Skip to content

Commit

Permalink
feat: enable to generate a random avatar for the bot (#153)
Browse files Browse the repository at this point in the history
![image](https://github.com/ant-xuexiao/petercat/assets/10885578/05b52ae8-3ba4-4efc-9070-69a87249b909)

* 根据repo name 自动生成bot配置
* 随机生成猫猫头像
  • Loading branch information
xingwanying authored Jun 12, 2024
2 parents a03df5d + 2f97ecb commit ec6b866
Show file tree
Hide file tree
Showing 19 changed files with 54 additions and 25 deletions.
34 changes: 25 additions & 9 deletions client/app/factory/edit/[id]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ export default function Edit({ params }: { params: { id: string } }) {
const [botProfile, setBotProfile] = useImmer<BotProfile>({
id: '',
avatar: '',
gitAvatar: '',
name: 'Untitled',
description: '',
prompt: '',
Expand Down Expand Up @@ -49,8 +50,8 @@ export default function Edit({ params }: { params: { id: string } }) {
} = useBotCreate();

const isEdit = useMemo(
() => !!params?.id && params?.id !== 'new',
[params?.id],
() => (!!params?.id && params?.id !== 'new') || !!botProfile?.id,
[params?.id, botProfile?.id],
);

const { data: config, isLoading } = useBotConfig(params?.id, isEdit);
Expand Down Expand Up @@ -89,9 +90,19 @@ export default function Edit({ params }: { params: { id: string } }) {
}, [createError]);

useEffect(() => {
if (createResponseData) {
const botInfo = createResponseData?.[0];
if (!isEmpty(botInfo)) {
setBotProfile?.((draft) => {
draft.id = createResponseData;
draft.repoName = botProfile.repoName;
draft.id = botInfo.id;
draft.name = botInfo.name;
draft.avatar = botInfo.avatar;
draft.gitAvatar = botInfo.gitAvatar;
draft.prompt = botInfo.prompt;
draft.description = botInfo.description;
draft.starters = botInfo.starters;
draft.public = botInfo.public;
draft.helloMessage = botInfo.hello_message;
});
}
}, [createResponseData]);
Expand Down Expand Up @@ -141,9 +152,9 @@ export default function Edit({ params }: { params: { id: string } }) {
variant="bordered"
name="repo_name"
label="Github 项目名"
value={botProfile?.repoName}
placeholder="请输入 GitHub 项目名称 (ORG_NAME/REPO_NAME)"
labelPlacement="outside"
value={botProfile?.description}
onChange={(e) => {
const repoName = e.target.value;
setBotProfile?.((draft) => {
Expand All @@ -153,12 +164,13 @@ export default function Edit({ params }: { params: { id: string } }) {
required
className="mt-1 mb-6 block w-full border-gray-300 rounded-md shadow-sm focus:border-indigo-300 focus:ring focus:ring-indigo-200 focus:ring-opacity-50"
/>
{isEdit ? (
{!isEdit ? (
<div className="w-full text-center">
<Button
radius="full"
className="bg-gray-700 text-white"
startContent={<AIBtnIcon />}
isLoading={createBotLoading}
onClick={() => {
onCreateBot(botProfile?.repoName!);
}}
Expand All @@ -171,6 +183,7 @@ export default function Edit({ params }: { params: { id: string } }) {
radius="full"
className="bg-[#F1F1F1] text-gray-500"
startContent={<AIBtnIcon />}
isLoading={createBotLoading}
onClick={() => {
onCreateBot(botProfile?.repoName!);
}}
Expand All @@ -180,7 +193,7 @@ export default function Edit({ params }: { params: { id: string } }) {
)}
</div>

{!isEdit && (
{isEdit && (
<BotCreateFrom setBotProfile={setBotProfile} botProfile={botProfile} />
)}
</div>
Expand Down Expand Up @@ -216,7 +229,7 @@ export default function Edit({ params }: { params: { id: string } }) {
aria-label="Options"
onSelectionChange={(key) => setActiveTab(`${key}`)}
classNames={{
base: 'w-[216px] h-[36px]',
base: 'w-[230px] h-[36px]',
tab: 'shadow-none w-[108px] h-[36px] px-0 py-0',
tabContent:
'group-data-[selected=true]:bg-[#FAE4CB] rounded-full px-3 py-2 w-[108px] h-[36px]',
Expand Down Expand Up @@ -291,7 +304,10 @@ export default function Edit({ params }: { params: { id: string } }) {
'https://mdn.alipayobjects.com/huamei_j8gzmo/afts/img/A*YAP3SI7MMHQAAAAAAAAAAAAADrPSAQ/original',
title: botProfile?.name || 'PeterCat',
}}
apiUrl={`${API_HOST}/api/chat/stream_chat`}
apiDomain={API_HOST}
apiUrl="/api/chat/stream_qa"
prompt={botProfile?.prompt}
starters={botProfile?.starters}
helloMessage={botProfile?.helloMessage}
/>
)}
Expand Down
10 changes: 8 additions & 2 deletions client/app/factory/edit/components/BotCreateFrom.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import type { Updater } from 'use-immer';
import InputList from './InputList';
import BulbIcon from '@/public/icons/BulbIcon';
import GitHubIcon from '@/public/icons/GitHubIcon';
import { random } from 'lodash';

interface BotFormProps {
botProfile?: BotProfile;
Expand Down Expand Up @@ -38,6 +39,11 @@ const BotCreateFrom = (props: BotFormProps) => {
<Tooltip content="随机头像">
<Button
isIconOnly
onClick={() => {
setBotProfile?.((draft: BotProfile) => {
draft.avatar = `/images/avatar${random(0, 9)}.png`;
});
}}
className="rounded-full bg-gray-700 mr-2 w-[32px] h-[32px]"
aria-label="随机头像"
>
Expand All @@ -57,7 +63,7 @@ const BotCreateFrom = (props: BotFormProps) => {
</div>
</div>
<div className="flex-1">
<div className="mb-[50px]">
<div className="mb-[42px]">
<Input
name="name"
label="机器人名称*"
Expand All @@ -69,7 +75,7 @@ const BotCreateFrom = (props: BotFormProps) => {
required
/>
</div>
<div className="mt-[50px]">
<div className="mt-[42px]">
<Input
name="description"
label="机器人描述*"
Expand Down
2 changes: 1 addition & 1 deletion client/app/hooks/useBot.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ export function useBotCreate() {
});

return {
data: mutation.data?.data?.data?.id,
data: mutation?.data?.data?.data,
createBot: mutation.mutate,
isLoading: mutation.isPending,
error: mutation.error,
Expand Down
1 change: 1 addition & 0 deletions client/app/interface/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,5 @@ export interface BotProfile {
public?: boolean;
helloMessage?: string;
repoName?: string;
gitAvatar?: string;
}
18 changes: 13 additions & 5 deletions client/app/services/BotsController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { BotProfile } from '@/app/interface';

declare type Bot = Tables<'bots'>;

axios.defaults.withCredentials = true
axios.defaults.withCredentials = true;

const apiDomain = process.env.NEXT_PUBLIC_API_DOMAIN;
// Get the public bot profile by id
Expand All @@ -21,8 +21,13 @@ export async function getBotConfig(id: string): Promise<Bot[]> {
}

// Get the bot list
export async function getBotList(personal: boolean, name: string): Promise<Bot[]> {
const response = await axios.get(`${apiDomain}/api/bot/list?personal=${personal}&name=${name ?? ''}`);
export async function getBotList(
personal: boolean,
name: string,
): Promise<Bot[]> {
const response = await axios.get(
`${apiDomain}/api/bot/list?personal=${personal}&name=${name ?? ''}`,
);
return response.data.data;
}

Expand All @@ -32,8 +37,11 @@ export async function deleteBot(id: string) {
}

// Create Bot
export async function createBot(repo_name: string) {
return axios.post(`${apiDomain}/api/bot/create`, repo_name);
export async function createBot(repo_name: string, starters?: string[]) {
return axios.post(`${apiDomain}/api/bot/create`, {
repo_name,
starters,
});
}

// Update Bot
Expand Down
Binary file added client/public/images/avatar0.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added client/public/images/avatar1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added client/public/images/avatar2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added client/public/images/avatar3.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added client/public/images/avatar4.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added client/public/images/avatar5.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added client/public/images/avatar6.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added client/public/images/avatar7.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added client/public/images/avatar8.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added client/public/images/avatar9.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
8 changes: 4 additions & 4 deletions server/bot/builder.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from typing import Optional
from typing import List, Optional
from github import Github
from db.supabase.client import get_client
from prompts.bot_template import generate_prompt_by_repo_name
Expand All @@ -9,7 +9,8 @@
async def bot_builder(
uid: str,
repo_name: str,
starters: Optional[list[str]] = ["介绍一下项目", "快速上手", "贡献指南"],
starters: Optional[List[str]] = None,
hello_message: Optional[str] = None
):
"""
create a bot based on the given github repository.
Expand All @@ -31,11 +32,10 @@ async def bot_builder(
"avatar": repo.organization.avatar_url if repo.organization else None,
"prompt": prompt,
"uid": uid,
"enable_img_generation": False,
"label": "Assistant",
"starters": starters,
"enable_img_generation": False,
"public": False,
"hello_message": hello_message
}

supabase = get_client()
Expand Down
1 change: 0 additions & 1 deletion server/routers/bot.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,6 @@ def get_bot_config(id: Optional[str] = Query(None, description="Filter bots by p

@router.post("/create", status_code=200)
async def create_bot(bot_data: BotCreateRequest, user_id: str = Cookie(None)):
print('user_id', user_id)
if not user_id:
raise HTTPException(status_code=status.HTTP_403_FORBIDDEN, detail="Must Login")
return await bot_builder(user_id, **bot_data.model_dump())
Expand Down
2 changes: 0 additions & 2 deletions server/tools/bot_builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,10 +55,8 @@ def edit_bot(
"avatar": bot["avatar"],
"prompt": prompt if prompt else bot["prompt"],
"uid": uid,
"enable_img_generation": False,
"label": "Assistant",
"starters": starters if isinstance(starters, list) and starters else bot["starters"],
"enable_img_generation": False,
"public": False,
}

Expand Down
3 changes: 2 additions & 1 deletion server/type_class/bot.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@

class BotCreateRequest(BaseModel):
repo_name: str
starters: Optional[list[str]]
starters: Optional[List[str]] = ["介绍一下项目", "快速上手", "贡献指南"],
hello_message: Optional[str] = "我是答疑机器人,答疑机器人能够快速响应用户需求,并解决实际问题。"
class BotUpdateRequest(BaseModel):
avatar: Optional[str] = None
description: Optional[str] = None
Expand Down

0 comments on commit ec6b866

Please sign in to comment.