fix(web): ai prompt editor update
This commit is contained in:
@@ -1144,6 +1144,8 @@ export const en = {
|
|||||||
merge: 'Complete Aggregation',
|
merge: 'Complete Aggregation',
|
||||||
vote: 'Key Information Extraction',
|
vote: 'Key Information Extraction',
|
||||||
priority: 'Structured Integration',
|
priority: 'Structured Integration',
|
||||||
|
addTool: 'Add Tool',
|
||||||
|
tool: 'Tool',
|
||||||
},
|
},
|
||||||
userMemory: {
|
userMemory: {
|
||||||
userMemory: 'User Memory',
|
userMemory: 'User Memory',
|
||||||
@@ -1201,6 +1203,7 @@ export const en = {
|
|||||||
IMPLICIT_MEMORY: 'Implicit Memory',
|
IMPLICIT_MEMORY: 'Implicit Memory',
|
||||||
EMOTIONAL_MEMORY: 'Emotional Memory',
|
EMOTIONAL_MEMORY: 'Emotional Memory',
|
||||||
EPISODIC_MEMORY: 'Episodic Memory',
|
EPISODIC_MEMORY: 'Episodic Memory',
|
||||||
|
FORGETTING_MANAGEMENT: 'Forgetting Management',
|
||||||
|
|
||||||
endUserProfile: 'Core Profile',
|
endUserProfile: 'Core Profile',
|
||||||
editEndUserProfile: 'Edit',
|
editEndUserProfile: 'Edit',
|
||||||
@@ -1833,6 +1836,7 @@ Memory Bear: After the rebellion, regional warlordism intensified for several re
|
|||||||
status_code: 'Status Code',
|
status_code: 'Status Code',
|
||||||
max_attempts: 'Max Retry Attempts',
|
max_attempts: 'Max Retry Attempts',
|
||||||
retry_interval: 'Retry Interval',
|
retry_interval: 'Retry Interval',
|
||||||
|
errorBranch: 'Error Branch',
|
||||||
},
|
},
|
||||||
'jinja-render': {
|
'jinja-render': {
|
||||||
template: 'Code',
|
template: 'Code',
|
||||||
|
|||||||
@@ -633,6 +633,8 @@ export const zh = {
|
|||||||
merge: '完整汇总',
|
merge: '完整汇总',
|
||||||
vote: '关键信息提取',
|
vote: '关键信息提取',
|
||||||
priority: '结构化整合',
|
priority: '结构化整合',
|
||||||
|
addTool: '添加工具',
|
||||||
|
tool: '工具',
|
||||||
},
|
},
|
||||||
// 角色管理相关翻译
|
// 角色管理相关翻译
|
||||||
role: {
|
role: {
|
||||||
@@ -1280,6 +1282,7 @@ export const zh = {
|
|||||||
IMPLICIT_MEMORY: '隐性记忆',
|
IMPLICIT_MEMORY: '隐性记忆',
|
||||||
EMOTIONAL_MEMORY: '情绪记忆',
|
EMOTIONAL_MEMORY: '情绪记忆',
|
||||||
EPISODIC_MEMORY: '情景记忆',
|
EPISODIC_MEMORY: '情景记忆',
|
||||||
|
FORGETTING_MANAGEMENT: '遗忘',
|
||||||
|
|
||||||
endUserProfile: '核心档案',
|
endUserProfile: '核心档案',
|
||||||
editEndUserProfile: '编辑',
|
editEndUserProfile: '编辑',
|
||||||
@@ -1933,6 +1936,7 @@ export const zh = {
|
|||||||
status_code: '状态码',
|
status_code: '状态码',
|
||||||
max_attempts: '最大重试次数',
|
max_attempts: '最大重试次数',
|
||||||
retry_interval: '重试间隔',
|
retry_interval: '重试间隔',
|
||||||
|
errorBranch: '异常分支',
|
||||||
},
|
},
|
||||||
'jinja-render': {
|
'jinja-render': {
|
||||||
template: '代码',
|
template: '代码',
|
||||||
@@ -2246,5 +2250,12 @@ export const zh = {
|
|||||||
orderPayInfo: '支付信息',
|
orderPayInfo: '支付信息',
|
||||||
create_time: '创建时间',
|
create_time: '创建时间',
|
||||||
},
|
},
|
||||||
|
forgetDetail: {
|
||||||
|
title: '遗忘管理系统帮助AI智能管理记忆生命周期,通过自动识别低价值记忆、设置遗忘策略和执行定期清理,优化记忆库存储空间,提升检索效率。',
|
||||||
|
overviewTitle: '核心指标概览',
|
||||||
|
totalMemory: '记忆总量',
|
||||||
|
MemoryHealth: '记忆健康度',
|
||||||
|
riskOfForgetting: '遗忘风险',
|
||||||
|
}
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@@ -19,7 +19,6 @@ import type {
|
|||||||
MemoryConfig,
|
MemoryConfig,
|
||||||
AiPromptModalRef,
|
AiPromptModalRef,
|
||||||
Source,
|
Source,
|
||||||
ToolModalRef,
|
|
||||||
ToolOption
|
ToolOption
|
||||||
} from './types'
|
} from './types'
|
||||||
import type { Model } from '@/views/ModelManagement/types'
|
import type { Model } from '@/views/ModelManagement/types'
|
||||||
@@ -33,7 +32,6 @@ import { memoryConfigListUrl } from '@/api/memory'
|
|||||||
import CustomSelect from '@/components/CustomSelect'
|
import CustomSelect from '@/components/CustomSelect'
|
||||||
import aiPrompt from '@/assets/images/application/aiPrompt.png'
|
import aiPrompt from '@/assets/images/application/aiPrompt.png'
|
||||||
import AiPromptModal from './components/AiPromptModal'
|
import AiPromptModal from './components/AiPromptModal'
|
||||||
import ToolModal from './components/ToolModal'
|
|
||||||
import ToolList from './components/ToolList'
|
import ToolList from './components/ToolList'
|
||||||
|
|
||||||
const DescWrapper: FC<{desc: string, className?: string}> = ({desc, className}) => {
|
const DescWrapper: FC<{desc: string, className?: string}> = ({desc, className}) => {
|
||||||
@@ -115,6 +113,7 @@ const Agent = forwardRef<AgentRef>((_props, ref) => {
|
|||||||
const [variableList, setVariableList] = useState<Variable[]>([])
|
const [variableList, setVariableList] = useState<Variable[]>([])
|
||||||
const [isSave, setIsSave] = useState(false)
|
const [isSave, setIsSave] = useState(false)
|
||||||
const initialized = useRef(false)
|
const initialized = useRef(false)
|
||||||
|
const [toolList, setToolList] = useState<ToolOption[]>([])
|
||||||
|
|
||||||
// 初始化完成标记
|
// 初始化完成标记
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@@ -143,6 +142,11 @@ const Agent = forwardRef<AgentRef>((_props, ref) => {
|
|||||||
if (isSave) return
|
if (isSave) return
|
||||||
setIsSave(true)
|
setIsSave(true)
|
||||||
}, [values])
|
}, [values])
|
||||||
|
useEffect(() => {
|
||||||
|
if (!initialized.current) return
|
||||||
|
if (isSave) return
|
||||||
|
setIsSave(true)
|
||||||
|
}, [toolList])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
getModels()
|
getModels()
|
||||||
@@ -294,7 +298,11 @@ const Agent = forwardRef<AgentRef>((_props, ref) => {
|
|||||||
...(item.config || {})
|
...(item.config || {})
|
||||||
}))
|
}))
|
||||||
} as KnowledgeConfig : null,
|
} as KnowledgeConfig : null,
|
||||||
tools: toolList
|
tools: toolList.map(vo => ({
|
||||||
|
tool_id: vo.tool_id,
|
||||||
|
operation: vo.operation,
|
||||||
|
enabled: vo.enabled
|
||||||
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log('params', rest, params)
|
console.log('params', rest, params)
|
||||||
@@ -347,18 +355,6 @@ const Agent = forwardRef<AgentRef>((_props, ref) => {
|
|||||||
form.setFieldValue('system_prompt', value)
|
form.setFieldValue('system_prompt', value)
|
||||||
}
|
}
|
||||||
|
|
||||||
const toolModalRef = useRef<ToolModalRef>(null)
|
|
||||||
const [toolList, setToolList] = useState<ToolOption[]>([])
|
|
||||||
const handleAddTool = () => {
|
|
||||||
toolModalRef.current?.handleOpen()
|
|
||||||
}
|
|
||||||
const updateTools = (tool: ToolOption) => {
|
|
||||||
const tools = [...toolList, tool]
|
|
||||||
setToolList(tools)
|
|
||||||
form.setFieldValue('tools', tools)
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log('toolList', toolList)
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{loading && <Spin fullscreen></Spin>}
|
{loading && <Spin fullscreen></Spin>}
|
||||||
@@ -469,10 +465,6 @@ const Agent = forwardRef<AgentRef>((_props, ref) => {
|
|||||||
defaultModel={defaultModel}
|
defaultModel={defaultModel}
|
||||||
refresh={updatePrompt}
|
refresh={updatePrompt}
|
||||||
/>
|
/>
|
||||||
<ToolModal
|
|
||||||
ref={toolModalRef}
|
|
||||||
refresh={updateTools}
|
|
||||||
/>
|
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -90,11 +90,19 @@ const AiPromptModal = forwardRef<AiPromptModalRef, AiPromptModalProps>(({
|
|||||||
switch (item.event) {
|
switch (item.event) {
|
||||||
case 'start':
|
case 'start':
|
||||||
currentPromptValueRef.current = ''
|
currentPromptValueRef.current = ''
|
||||||
|
if (editorRef.current?.clear) {
|
||||||
|
editorRef.current.clear();
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case 'message':
|
case 'message':
|
||||||
if (content) {
|
if (content) {
|
||||||
currentPromptValueRef.current += content;
|
currentPromptValueRef.current += content;
|
||||||
form.setFieldsValue({ current_prompt: currentPromptValueRef.current })
|
if (editorRef.current?.appendText) {
|
||||||
|
editorRef.current.appendText(content);
|
||||||
|
editorRef.current.scrollToBottom();
|
||||||
|
} else {
|
||||||
|
form.setFieldsValue({ current_prompt: currentPromptValueRef.current })
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (desc) {
|
if (desc) {
|
||||||
setChatList(prev => {
|
setChatList(prev => {
|
||||||
@@ -107,6 +115,8 @@ const AiPromptModal = forwardRef<AiPromptModalRef, AiPromptModalProps>(({
|
|||||||
break;
|
break;
|
||||||
case 'end':
|
case 'end':
|
||||||
setLoading(false)
|
setLoading(false)
|
||||||
|
// 流结束时同步表单值
|
||||||
|
form.setFieldsValue({ current_prompt: currentPromptValueRef.current })
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import { LexicalComposer } from '@lexical/react/LexicalComposer';
|
|||||||
import { RichTextPlugin } from '@lexical/react/LexicalRichTextPlugin';
|
import { RichTextPlugin } from '@lexical/react/LexicalRichTextPlugin';
|
||||||
import { ContentEditable } from '@lexical/react/LexicalContentEditable';
|
import { ContentEditable } from '@lexical/react/LexicalContentEditable';
|
||||||
import { LexicalErrorBoundary } from '@lexical/react/LexicalErrorBoundary';
|
import { LexicalErrorBoundary } from '@lexical/react/LexicalErrorBoundary';
|
||||||
import { $getSelection } from 'lexical';
|
import { $getSelection, $getRoot, $createParagraphNode, $createTextNode, $isParagraphNode, $isTextNode } from 'lexical';
|
||||||
import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext';
|
import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext';
|
||||||
import InitialValuePlugin from './plugin/InitialValuePlugin'
|
import InitialValuePlugin from './plugin/InitialValuePlugin'
|
||||||
import LineBreakPlugin from './plugin/LineBreakPlugin';
|
import LineBreakPlugin from './plugin/LineBreakPlugin';
|
||||||
@@ -12,6 +12,9 @@ import InsertTextPlugin from './plugin/InsertTextPlugin';
|
|||||||
|
|
||||||
export interface EditorRef {
|
export interface EditorRef {
|
||||||
insertText: (text: string) => void;
|
insertText: (text: string) => void;
|
||||||
|
appendText: (text: string) => void;
|
||||||
|
clear: () => void;
|
||||||
|
scrollToBottom: () => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface LexicalEditorProps {
|
interface LexicalEditorProps {
|
||||||
@@ -46,6 +49,41 @@ const EditorContent = forwardRef<EditorRef, LexicalEditorProps>(({
|
|||||||
selection.insertText(text);
|
selection.insertText(text);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
},
|
||||||
|
appendText: (text: string) => {
|
||||||
|
editor.update(() => {
|
||||||
|
const root = $getRoot();
|
||||||
|
const lastChild = root.getLastChild();
|
||||||
|
if (lastChild && $isParagraphNode(lastChild)) {
|
||||||
|
const lastTextNode = lastChild.getLastChild();
|
||||||
|
if (lastTextNode && $isTextNode(lastTextNode)) {
|
||||||
|
const currentText = lastTextNode.getTextContent();
|
||||||
|
lastTextNode.setTextContent(currentText + text);
|
||||||
|
} else {
|
||||||
|
const textNode = $createTextNode(text);
|
||||||
|
lastChild.append(textNode);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
const paragraph = $createParagraphNode();
|
||||||
|
const textNode = $createTextNode(text);
|
||||||
|
paragraph.append(textNode);
|
||||||
|
root.append(paragraph);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
clear: () => {
|
||||||
|
editor.update(() => {
|
||||||
|
const root = $getRoot();
|
||||||
|
root.clear();
|
||||||
|
const paragraph = $createParagraphNode();
|
||||||
|
root.append(paragraph);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
scrollToBottom: () => {
|
||||||
|
const editorElement = editor.getRootElement();
|
||||||
|
if (editorElement) {
|
||||||
|
editorElement.scrollTop = editorElement.scrollHeight;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}), [editor]);
|
}), [editor]);
|
||||||
|
|
||||||
|
|||||||
@@ -1,21 +1,37 @@
|
|||||||
import { type FC, useEffect } from 'react';
|
import { type FC, useEffect, useRef } from 'react';
|
||||||
import { $getRoot, $createParagraphNode, $createTextNode } from 'lexical';
|
import { $getRoot, $createParagraphNode, $createTextNode } from 'lexical';
|
||||||
import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext';
|
import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext';
|
||||||
|
|
||||||
// 设置初始值的插件
|
// 设置初始值的插件
|
||||||
const InitialValuePlugin: FC<{ value?: string }> = ({ value }) => {
|
const InitialValuePlugin: FC<{ value?: string }> = ({ value }) => {
|
||||||
const [editor] = useLexicalComposerContext();
|
const [editor] = useLexicalComposerContext();
|
||||||
|
const lastValueRef = useRef<string | undefined>(undefined);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (value) {
|
// 只有当value真正发生变化时才更新
|
||||||
|
if (lastValueRef.current !== value) {
|
||||||
editor.update(() => {
|
editor.update(() => {
|
||||||
const root = $getRoot();
|
const root = $getRoot();
|
||||||
|
const currentText = root.getTextContent();
|
||||||
|
|
||||||
|
// 如果当前内容和新值相同,则不更新
|
||||||
|
if (currentText === (value || '')) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
root.clear();
|
root.clear();
|
||||||
const paragraph = $createParagraphNode();
|
if (value) {
|
||||||
const textNode = $createTextNode(value);
|
const paragraph = $createParagraphNode();
|
||||||
paragraph.append(textNode);
|
const textNode = $createTextNode(value);
|
||||||
root.append(paragraph);
|
paragraph.append(textNode);
|
||||||
|
root.append(paragraph);
|
||||||
|
} else {
|
||||||
|
// 当value为undefined或空时,创建一个空段落
|
||||||
|
const paragraph = $createParagraphNode();
|
||||||
|
root.append(paragraph);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
lastValueRef.current = value;
|
||||||
}
|
}
|
||||||
}, [editor, value]);
|
}, [editor, value]);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user