diff --git a/package-lock.json b/package-lock.json index e815c073..b826cbb7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -16,6 +16,7 @@ "element-plus": "^2.9.3", "js-yaml": "^4.1.0", "langchain": "^0.3.12", + "uuid": "^11.0.5", "vue": "^3.5.13" }, "devDependencies": { @@ -830,6 +831,19 @@ "node": ">=18" } }, + "node_modules/@langchain/core/node_modules/uuid": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-10.0.0.tgz", + "integrity": "sha512-8XkAphELsDnEGrDxUOHB3RGvXz6TeuYSGEZBOjtTtPm2lwhGBjLgOzLHB63IUWfBpNucQjND6d3AOudO+H3RWQ==", + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], + "license": "MIT", + "bin": { + "uuid": "dist/bin/uuid" + } + }, "node_modules/@langchain/google-genai": { "version": "0.1.6", "resolved": "https://registry.npmjs.org/@langchain/google-genai/-/google-genai-0.1.6.tgz", @@ -3024,6 +3038,19 @@ } } }, + "node_modules/langchain/node_modules/uuid": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-10.0.0.tgz", + "integrity": "sha512-8XkAphELsDnEGrDxUOHB3RGvXz6TeuYSGEZBOjtTtPm2lwhGBjLgOzLHB63IUWfBpNucQjND6d3AOudO+H3RWQ==", + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], + "license": "MIT", + "bin": { + "uuid": "dist/bin/uuid" + } + }, "node_modules/langsmith": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/langsmith/-/langsmith-0.3.2.tgz", @@ -3047,6 +3074,19 @@ } } }, + "node_modules/langsmith/node_modules/uuid": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-10.0.0.tgz", + "integrity": "sha512-8XkAphELsDnEGrDxUOHB3RGvXz6TeuYSGEZBOjtTtPm2lwhGBjLgOzLHB63IUWfBpNucQjND6d3AOudO+H3RWQ==", + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], + "license": "MIT", + "bin": { + "uuid": "dist/bin/uuid" + } + }, "node_modules/lilconfig": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.3.tgz", @@ -4467,16 +4507,16 @@ "license": "MIT" }, "node_modules/uuid": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-10.0.0.tgz", - "integrity": "sha512-8XkAphELsDnEGrDxUOHB3RGvXz6TeuYSGEZBOjtTtPm2lwhGBjLgOzLHB63IUWfBpNucQjND6d3AOudO+H3RWQ==", + "version": "11.0.5", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-11.0.5.tgz", + "integrity": "sha512-508e6IcKLrhxKdBbcA2b4KQZlLVp2+J5UwQ6F7Drckkc5N9ZJwFa4TgWtsww9UG8fGHbm6gbV19TdM5pQ4GaIA==", "funding": [ "https://github.com/sponsors/broofa", "https://github.com/sponsors/ctavan" ], "license": "MIT", "bin": { - "uuid": "dist/bin/uuid" + "uuid": "dist/esm/bin/uuid" } }, "node_modules/vite": { diff --git a/package.json b/package.json index 77596f8a..72ff59e1 100644 --- a/package.json +++ b/package.json @@ -21,6 +21,7 @@ "element-plus": "^2.9.3", "js-yaml": "^4.1.0", "langchain": "^0.3.12", + "uuid": "^11.0.5", "vue": "^3.5.13" }, "devDependencies": { diff --git a/src/App.vue b/src/App.vue index 105b255e..43100ceb 100644 --- a/src/App.vue +++ b/src/App.vue @@ -72,8 +72,11 @@ v-model:optimized-prompt="optimizedPrompt" :is-iterating="isIterating" v-model:selected-iterate-template="selectedIterateTemplate" + :versions="currentVersions" + :current-version-id="currentVersionId" @iterate="handleIteratePrompt" @openTemplateManager="openTemplateManager" + @switchVersion="handleSwitchVersion" /> @@ -137,12 +140,13 @@ /> - - + @@ -159,12 +163,14 @@ import { templateManager } from './services/template/manager' import ModelManager from './components/ModelManager.vue' import TemplateManager from './components/TemplateManager.vue' import Toast from './components/Toast.vue' -import HistoryDrawer from './components/HistoryDrawer.vue' +import HistoryModal from './components/HistoryDrawer.vue' import PromptPanel from './components/PromptPanel.vue' import InputPanel from './components/InputPanel.vue' import OutputPanel from './components/OutputPanel.vue' import { useToast } from './composables/useToast' import TemplateSelect from './components/TemplateSelect.vue' +import { historyManager } from './services/history/manager' +import { v4 as uuidv4 } from 'uuid' // 初始化服务 const llmService = createLLMService(modelManager) @@ -196,6 +202,9 @@ const selectedIterateTemplate = ref(null) const history = ref([]) const models = ref([]) const outputPanelRef = ref(null) +const currentChainId = ref('') +const currentVersions = ref([]) +const currentVersionId = ref('') // 流式输出处理器 const streamHandler = { @@ -270,17 +279,42 @@ const handleOptimizePrompt = async () => { }) // 使用流式调用 - await promptService.optimizePromptStream( + const result = await promptService.optimizePromptStream( prompt.value, optimizeModel.value, - selectedOptimizeTemplate.value.content, // 直接使用当前选中的提示词内容 + selectedOptimizeTemplate.value.content, { onToken: (token) => { optimizedPrompt.value += token }, onComplete: () => { - // 更新历史记录 - history.value = promptService.getHistory() + // 创建新记录链 + console.log('创建新的历史记录链...') + const newRecord = historyManager.createNewChain({ + id: uuidv4(), + originalPrompt: prompt.value, + optimizedPrompt: optimizedPrompt.value, + type: 'optimize', + modelKey: optimizeModel.value, + templateId: selectedOptimizeTemplate.value.id, + timestamp: Date.now(), + metadata: {} + }); + + console.log('新记录链创建成功:', { + chainId: newRecord.chainId, + record: newRecord + }) + + currentChainId.value = newRecord.chainId; + // 更新版本信息 + currentVersions.value = newRecord.versions; + currentVersionId.value = newRecord.currentRecord.id; + history.value = historyManager.getAllChains(); + console.log('历史记录已更新:', { + totalChains: history.value?.length + }) + toast.success('优化成功') isOptimizing.value = false }, @@ -316,8 +350,7 @@ const handleIteratePrompt = async ({ originalPrompt, iterateInput }) => { try { // 使用流式调用 - const template = selectedIterateTemplate.value; - await promptService.iteratePromptStream( + const result = await promptService.iteratePromptStream( originalPrompt, iterateInput, optimizeModel.value, @@ -326,15 +359,41 @@ const handleIteratePrompt = async ({ originalPrompt, iterateInput }) => { optimizedPrompt.value += token; // 直接更新到 optimizedPrompt }, onComplete: () => { - // 更新历史记录 - history.value = promptService.getHistory() + // 添加迭代记录 + console.log('添加迭代记录...', { + chainId: currentChainId.value, + originalPrompt, + iterateInput + }) + + const updatedChain = historyManager.addIteration({ + chainId: currentChainId.value, + originalPrompt: originalPrompt, + optimizedPrompt: optimizedPrompt.value, + iterationNote: iterateInput, + modelKey: optimizeModel.value, + templateId: selectedIterateTemplate.value.id + }); + + console.log('迭代记录添加成功:', { + chain: updatedChain + }) + + // 更新版本信息 + currentVersions.value = updatedChain.versions; + currentVersionId.value = updatedChain.currentRecord.id; + history.value = historyManager.getAllChains(); + console.log('历史记录已更新:', { + totalChains: history.value?.length + }) + toast.success('迭代优化成功') }, onError: (error) => { toast.error(error.message || '迭代优化失败') } }, - template + selectedIterateTemplate.value ); } catch (error) { console.error('迭代优化失败:', error) @@ -392,9 +451,38 @@ const handleTest = async () => { }; const handleSelectHistory = (item) => { - prompt.value = item.prompt - optimizedPrompt.value = item.result - showHistory.value = false + // 如果是迭代记录,需要找到原始的提示词 + if (item.type === 'iterate') { + // 从历史记录中找到对应的链 + const chain = history.value.find(c => c.chainId === item.chainId); + if (chain) { + prompt.value = chain.rootRecord.originalPrompt; + currentVersions.value = chain.versions; + currentVersionId.value = item.id; + } + } else { + prompt.value = item.originalPrompt; + const chain = history.value.find(c => c.chainId === item.chainId); + if (chain) { + currentVersions.value = chain.versions; + currentVersionId.value = item.id; + } + } + optimizedPrompt.value = item.optimizedPrompt; + showHistory.value = false; +} + +// 添加清空历史记录的处理函数 +const handleClearHistory = async () => { + try { + await historyManager.clearHistory() + history.value = [] + console.log('历史记录已清空') + toast.success('历史记录已清空') + } catch (error) { + console.error('清空历史记录失败:', error) + toast.error('清空历史记录失败') + } } // 保存提示词选择到本地存储 @@ -424,14 +512,34 @@ const openTemplateManager = (type = 'optimize') => { showTemplates.value = true } +// 添加版本切换处理函数 +const handleSwitchVersion = (version) => { + optimizedPrompt.value = version.optimizedPrompt; + currentVersionId.value = version.id; +} + // 生命周期钩子 onMounted(async () => { await initServices() loadModels() - // 加载历史记录 - if (promptService) { - history.value = promptService.getHistory() + // 初始化历史记录管理器 + try { + console.log('初始化历史记录管理器...') + await historyManager.init() + history.value = historyManager.getAllChains() + console.log('历史记录加载完成:', { + recordCount: history.value?.length, + chains: history.value?.map(chain => ({ + chainId: chain.chainId, + versionsCount: chain.versions.length, + rootRecord: chain.rootRecord, + currentRecord: chain.currentRecord + })) + }) + } catch (error) { + console.error('加载历史记录失败:', error) + toast.error('加载历史记录失败') } // 初始化提示词选择 @@ -487,6 +595,14 @@ watch(showConfig, (newVal) => { loadModels() } }) + +// 添加历史记录显示状态监听 +watch(showHistory, (newVal) => { + console.log('历史记录显示状态变更:', { + show: newVal, + currentHistory: history.value?.length + }) +}) \ No newline at end of file diff --git a/src/components/PromptPanel.vue b/src/components/PromptPanel.vue index 4b4b1ecf..e58b6472 100644 --- a/src/components/PromptPanel.vue +++ b/src/components/PromptPanel.vue @@ -2,7 +2,24 @@
-

优化后的提示词

+
+

优化后的提示词

+
+ +
+