Skip to content

Commit

Permalink
✨ feat: 优化 Agent 实现,支持自动补全
Browse files Browse the repository at this point in the history
  • Loading branch information
arvinxx committed Jul 17, 2023
1 parent a3653a4 commit 455a1f7
Show file tree
Hide file tree
Showing 7 changed files with 138 additions and 99 deletions.
3 changes: 2 additions & 1 deletion src/locales/zh_CN/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ export default {
'agentTagPlaceholder': '请输入标签',
'archive': '归档',
'autoGenerate': '自动补全',
'autoGenerateTooltip': '基于提示词自动补全助手描述',
'cancel': '取消',
'close': '关闭',
'confirmRemoveSessionItemAlert': '即将删除该助手,删除后该将无法找回,请确认你的操作',
Expand All @@ -29,7 +30,7 @@ export default {
'newAgent': '新建助手',
'noDescription': '暂无描述',
'ok': '确定',
'profile': '身份卡',
'profile': '助手身份',
'reset': '重置',
'searchAgentPlaceholder': '搜索助手和对话...',
'sessionSetting': '会话设置',
Expand Down
129 changes: 81 additions & 48 deletions src/pages/chat/[id]/edit/AgentMeta.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { ActionIcon, Avatar, Input } from '@lobehub/ui';
import { Button } from 'antd';
import { ActionIcon, Avatar, Input, Tooltip } from '@lobehub/ui';
import { Button, Collapse } from 'antd';
import isEqual from 'fast-deep-equal';
import { LucideSparkles } from 'lucide-react';
import { useTranslation } from 'react-i18next';
Expand All @@ -18,8 +18,22 @@ const AgentMeta = () => {

const metaData = useSessionStore(agentSelectors.currentAgentMeta, isEqual);

const [autocompleteMeta, loading] = useSessionStore(
(s) => [s.autocompleteMeta, s.autocompleteLoading],
const [
autocompleteMeta,
autocompleteSessionAgentMeta,
loading,
updateAgentMeta,
id,
hasSystemRole,
] = useSessionStore(
(s) => [
s.autocompleteMeta,
s.autocompleteSessionAgentMeta,
s.autocompleteLoading,
s.updateAgentMeta,
s.activeId,
agentSelectors.hasSystemRole(s),
],
shallow,
);

Expand All @@ -34,50 +48,69 @@ const AgentMeta = () => {
];

return (
<>
<Flexbox
align={'center'}
distribution={'space-between'}
horizontal
paddingBlock={12}
style={{
borderBottom: `1px solid ${theme.colorBorder}`,
}}
>
<Flexbox className={styles.profile}> {t('profile')}</Flexbox>
<Button size={'large'}>{t('autoGenerate')}</Button>
</Flexbox>
<Flexbox gap={80} horizontal style={{ marginTop: 16 }}>
<Flexbox flex={1} gap={24}>
{basic.map((item) => (
<FormItem key={item.key} label={item.label}>
<Input
placeholder={item.placeholder}
suffix={
<ActionIcon
icon={LucideSparkles}
loading={loading[item.key as keyof typeof loading]}
onClick={() => {
autocompleteMeta(item.key as keyof typeof metaData);
}}
size={'small'}
style={{
color: theme.purple,
}}
title={t('autoGenerate')}
/>
}
type={'block'}
value={metaData[item.key as keyof typeof metaData]}
/>
</FormItem>
))}
</Flexbox>
<FormItem label={t('agentAvatar')}>
<Avatar avatar={metaData.avatar} size={200} />
</FormItem>
</Flexbox>
</>
<Collapse
defaultActiveKey={hasSystemRole ? ['meta'] : []}
items={[
{
children: (
<Flexbox gap={80} horizontal style={{ marginTop: 16 }}>
<Flexbox flex={1} gap={24}>
{basic.map((item) => (
<FormItem key={item.key} label={item.label}>
<Input
onChange={(e) => {
updateAgentMeta({ [item.key]: e.target.value });
}}
placeholder={item.placeholder}
suffix={
<ActionIcon
icon={LucideSparkles}
loading={loading[item.key as keyof typeof loading]}
onClick={() => {
autocompleteMeta(item.key as keyof typeof metaData);
}}
size={'small'}
style={{
color: theme.purple,
}}
title={t('autoGenerate')}
/>
}
type={'block'}
value={metaData[item.key as keyof typeof metaData]}
/>
</FormItem>
))}
</Flexbox>
<FormItem label={t('agentAvatar')}>
<Avatar avatar={metaData.avatar} size={200} />
</FormItem>
</Flexbox>
),
className: styles.collapseHeader,
extra: (
<Tooltip title={t('autoGenerateTooltip')}>
<Button
disabled={!hasSystemRole}
loading={Object.values(loading).some((i) => !!i)}
onClick={(e) => {
e.stopPropagation();
console.log(id);
if (!id) return;

autocompleteSessionAgentMeta(id, true);
}}
size={'large'}
>
{t('autoGenerate')}
</Button>
</Tooltip>
),
key: 'meta',
label: <Flexbox className={styles.profile}>{t('profile')}</Flexbox>,
},
]}
/>
);
};

Expand Down
5 changes: 5 additions & 0 deletions src/pages/chat/[id]/edit/style.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
import { createStyles } from 'antd-style';

export const useStyles = createStyles(({ css, token }) => ({
collapseHeader: css`
.ant-collapse-header {
align-items: center !important;
}
`,
footer: css`
position: sticky;
bottom: 0;
Expand Down
13 changes: 13 additions & 0 deletions src/prompts/agent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,3 +50,16 @@ export const promptPickEmoji = (content: string): Partial<OpenAIStreamPayload> =
},
],
});

export const promptSummaryDescription = (content: string): Partial<OpenAIStreamPayload> => ({
messages: [
{
content: '你是一名擅长会话的助理,你需要将用户的提示词做一个3句话以内的总结。',
role: 'system',
},
{
content: `输入:${content}`,
role: 'user',
},
],
});
36 changes: 0 additions & 36 deletions src/prompts/chat.ts

This file was deleted.

45 changes: 31 additions & 14 deletions src/store/session/slices/agentConfig/action.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import { StateCreator } from 'zustand/vanilla';

import { promptPickEmoji } from '@/prompts/agent';
import { promptSummaryDescription, promptSummaryTitle } from '@/prompts/chat';
import { SessionStore, chatSelectors, sessionSelectors } from '@/store/session';
import { promptPickEmoji, promptSummaryAgentName, promptSummaryDescription } from '@/prompts/agent';
import { SessionStore, sessionSelectors } from '@/store/session';
import { MetaData } from '@/types/meta';
import { LobeAgentConfig } from '@/types/session';
import { fetchPresetTaskResult } from '@/utils/fetch';
Expand Down Expand Up @@ -36,7 +35,7 @@ export interface AgentAction {
* 自动完成会话代理元数据
* @param id - 代理的 ID
*/
autocompleteSessionAgentMeta: (id: string) => void;
autocompleteSessionAgentMeta: (id: string, replace?: boolean) => void;

/**
* 内部更新代理元数据
Expand All @@ -55,6 +54,7 @@ export interface AgentAction {
* @param config - 部分 LobeAgentConfig 的配置
*/
updateAgentConfig: (config: Partial<LobeAgentConfig>) => void;
updateAgentMeta: (meta: Partial<MetaData>) => void;
/**
* 更新加载状态
* @param key - SessionLoadingState 的键
Expand Down Expand Up @@ -93,9 +93,9 @@ export const createAgentSlice: StateCreator<
const session = sessionSelectors.getSessionById(id)(get());
if (!session) return;

const chats = chatSelectors.currentChats(get());
const systemRole = session.config.systemRole;

if (chats.length <= 0) return;
if (!systemRole) return;

const preValue = session.meta.description;

Expand All @@ -115,7 +115,7 @@ export const createAgentSlice: StateCreator<
updateLoadingState('description', loading);
},
onMessageHandle: internalUpdateAgentMeta(id)('description'),
params: promptSummaryDescription(chats),
params: promptSummaryDescription(systemRole),
});
},

Expand All @@ -124,9 +124,9 @@ export const createAgentSlice: StateCreator<
const session = sessionSelectors.getSessionById(id)(get());
if (!session) return;

const chats = chatSelectors.currentChats(get());
const systemRole = session.config.systemRole;

if (chats.length <= 0) return;
if (!systemRole) return;

const previousTitle = session.meta.title;

Expand All @@ -141,7 +141,7 @@ export const createAgentSlice: StateCreator<
updateLoadingState('title', loading);
},
onMessageHandle: internalUpdateAgentMeta(id)('title'),
params: promptSummaryTitle(chats),
params: promptSummaryAgentName(systemRole),
});
},

Expand All @@ -166,19 +166,20 @@ export const createAgentSlice: StateCreator<
}
},

autocompleteSessionAgentMeta: (id) => {
autocompleteSessionAgentMeta: (id, replace) => {
const session = sessionSelectors.getSessionById(id)(get());

if (!session) return;
if (!session.meta.title) {

if (!session.meta.title || replace) {
get().autocompleteAgentTitle(id);
}

if (!session.meta.description) {
if (!session.meta.description || replace) {
get().autocompleteAgentDescription(id);
}

if (!session.meta.avatar) {
if (!session.meta.avatar || replace) {
get().autoPickEmoji(id);
}
},
Expand All @@ -203,6 +204,22 @@ export const createAgentSlice: StateCreator<

get().dispatchSession({ config, id: activeId, type: 'updateSessionConfig' });
},
updateAgentMeta: (meta) => {
const { activeId } = get();
const session = sessionSelectors.currentSession(get());
if (!activeId || !session) return;

for (const [key, value] of Object.entries(meta)) {
if (value !== undefined) {
get().dispatchSession({
id: activeId,
key: key as keyof MetaData,
type: 'updateSessionMeta',
value,
});
}
}
},
updateLoadingState: (key, value) => {
set({ autocompleteLoading: { ...get().autocompleteLoading, [key]: value } });
},
Expand Down
6 changes: 6 additions & 0 deletions src/store/session/slices/agentConfig/selectors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,17 @@ const currentAgentModel = (s: SessionStore): LanguageModel => {
return config?.model || LanguageModel.GPT3_5;
};

const hasSystemRole = (s: SessionStore) => {
const config = currentAgentConfigSafe(s);

return !!config.systemRole;
};
export const agentSelectors = {
currentAgentAvatar,
currentAgentConfig,
currentAgentConfigSafe,
currentAgentMeta,
currentAgentModel,
currentAgentTitle,
hasSystemRole,
};

0 comments on commit 455a1f7

Please sign in to comment.