From d9b4c6a21b0b0656e928173985c782755b69f67b Mon Sep 17 00:00:00 2001 From: Syngnat Date: Thu, 23 Apr 2026 13:40:29 +0800 Subject: [PATCH] =?UTF-8?q?=F0=9F=90=9B=20fix(jvm):=20=E5=9B=BA=E5=AE=9A?= =?UTF-8?q?=20AI=20=E9=87=8D=E8=AF=95=E9=93=BE=E8=B7=AF=E7=9A=84=20JVM=20?= =?UTF-8?q?=E4=B8=8A=E4=B8=8B=E6=96=87?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 为 JVM AI 回复的重新生成流程继承原始页签上下文并透传到新消息 - 让重试、催促重发和工具回合续跑都按原 JVM 上下文构建 system prompt - 避免切换页签后重试 JVM 计划时出现上下文错位或定向能力丢失 - 重新通过前端全量测试、前端构建与 wails 生产构建验证 --- frontend/src/components/AIChatPanel.tsx | 40 +++++++++++++++++++------ frontend/wailsjs/go/models.ts | 1 - 2 files changed, 31 insertions(+), 10 deletions(-) diff --git a/frontend/src/components/AIChatPanel.tsx b/frontend/src/components/AIChatPanel.tsx index 5602f18..0fa7d3e 100644 --- a/frontend/src/components/AIChatPanel.tsx +++ b/frontend/src/components/AIChatPanel.tsx @@ -649,7 +649,7 @@ export const AIChatPanel: React.FC = ({ if (m.tool_call_id) mapped.tool_call_id = m.tool_call_id; return mapped; }); - const sysMessages = await buildSystemContextMessages(); + const sysMessages = await buildSystemContextMessages(existing.jvmPlanContext); // 追加催促消息 messagesPayload.push({ role: 'user', content: '请直接使用 function call 调用工具执行操作,不要只用文字描述计划。' }); const allMsg = [...sysMessages, ...messagesPayload]; @@ -750,13 +750,16 @@ export const AIChatPanel: React.FC = ({ toolCallRoundRef.current = 0; totalToolRoundRef.current = 0; nudgeCountRef.current = 0; + const retryJVMPlanContext = msg.jvmPlanContext || getCurrentJVMPlanContext(); + pendingJVMPlanContextRef.current = retryJVMPlanContext; setSending(true); // 插入 connecting 过渡消息(波纹动画),与 handleSend 保持一致 const connectingMsg: AIChatMessage = { id: genId(), role: 'assistant', phase: 'connecting', content: '', - timestamp: Date.now(), loading: true + timestamp: Date.now(), loading: true, + jvmPlanContext: retryJVMPlanContext, }; addAIChatMessage(sid, connectingMsg); @@ -764,7 +767,7 @@ export const AIChatPanel: React.FC = ({ const messagesPayload = truncatedHistory.map(m => ({ role: m.role, content: m.content, images: m.images })); try { - const sysMessages = await buildSystemContextMessages(); + const sysMessages = await buildSystemContextMessages(retryJVMPlanContext); const allMessages = [...sysMessages, ...messagesPayload]; const Service = (window as any).go?.aiservice?.Service; @@ -778,7 +781,8 @@ export const AIChatPanel: React.FC = ({ id: genId(), role: 'assistant', content: result?.success ? result.content : `❌ ${errClean}`, rawError: (!result?.success && errClean !== errRaw) ? errRaw : undefined, - timestamp: Date.now() + timestamp: Date.now(), + jvmPlanContext: retryJVMPlanContext, }); setSending(false); } else { @@ -787,20 +791,38 @@ export const AIChatPanel: React.FC = ({ } catch(e: any) { const rawE = e?.message || String(e); const cleanE = sanitizeErrorMsg(rawE); - addAIChatMessage(sid, { id: genId(), role: 'assistant', content: `❌ 发送失败: ${cleanE}`, rawError: cleanE !== rawE ? rawE : undefined, timestamp: Date.now() }); + addAIChatMessage(sid, { + id: genId(), + role: 'assistant', + content: `❌ 发送失败: ${cleanE}`, + rawError: cleanE !== rawE ? rawE : undefined, + timestamp: Date.now(), + jvmPlanContext: retryJVMPlanContext, + }); setSending(false); } } - }, [sid, truncateAIChatMessages, addAIChatMessage]); + }, [sid, truncateAIChatMessages, addAIChatMessage, getCurrentJVMPlanContext]); - const buildSystemContextMessages = useCallback(async () => { + const buildSystemContextMessages = useCallback(async (overrideJVMPlanContext?: JVMAIPlanContext) => { // 🔧 性能优化:从 store 实时读取,避免闭包捕获导致的依赖链式重建 const { activeContext: ctx, aiContexts: ctxMap, connections: conns, tabs: allTabs, activeTabId: tabId } = useStore.getState(); const connectionKey = ctx?.connectionId ? `${ctx.connectionId}:${ctx.dbName || ''}` : 'default'; const activeContextItems = ctxMap[connectionKey] || []; const systemMessages: { role: string; content: string; images?: string[] }[] = []; - const activeTab = allTabs.find(t => t.id === tabId); + const activeTab = overrideJVMPlanContext + ? ( + allTabs.find(t => t.id === overrideJVMPlanContext.tabId) || + allTabs.find( + t => + t.type === 'jvm-resource' && + t.connectionId === overrideJVMPlanContext.connectionId && + t.providerMode === overrideJVMPlanContext.providerMode && + String(t.resourcePath || '').trim() === overrideJVMPlanContext.resourcePath, + ) + ) + : allTabs.find(t => t.id === tabId); const activeConnection = activeTab?.connectionId ? conns.find(c => c.id === activeTab.connectionId) : undefined; @@ -1147,7 +1169,7 @@ SELECT * FROM users WHERE status = 1; if (m.tool_call_id) mapped.tool_call_id = m.tool_call_id; return mapped; }); - const sysMessages = await buildSystemContextMessages(); + const sysMessages = await buildSystemContextMessages(inheritedJVMPlanContext); let finalMessagesPayload = messagesPayload; // 在这里加入长度检查和自动摘要(带上动态限额) diff --git a/frontend/wailsjs/go/models.ts b/frontend/wailsjs/go/models.ts index 01e9816..0ec2e59 100755 --- a/frontend/wailsjs/go/models.ts +++ b/frontend/wailsjs/go/models.ts @@ -913,7 +913,6 @@ export namespace jvm { } } - export namespace redis { export class ZSetMember {