From c923419d2d36cb3db921cea082c6343e0f48a819 Mon Sep 17 00:00:00 2001 From: admin Date: Thu, 8 Oct 2026 16:23:28 +0800 Subject: [PATCH] =?UTF-8?q?fix(paper):=20=E5=A4=A7=E7=BA=B2=E9=98=B6?= =?UTF-8?q?=E6=AE=B5=E4=BF=AE=E6=94=B9=E6=84=8F=E8=A7=81=E8=B7=AF=E7=94=B1?= =?UTF-8?q?=E5=9B=9E=20sendPaper=20+=20=E7=94=A8=E5=8E=9F=E5=A7=8B=20brief?= =?UTF-8?q?=20=E9=87=8D=E6=96=B0=E7=94=9F=E6=88=90=E5=A4=A7=E7=BA=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../app/services/paper/complete.py | 1 + sdk/app/services/paper/agent.py | 15 ++++++-- ui/src/components/chat/Composer.vue | 37 +++++++++++++++++++ ui/src/stores/chat.js | 4 +- 4 files changed, 52 insertions(+), 5 deletions(-) diff --git a/paper_writer_service/app/services/paper/complete.py b/paper_writer_service/app/services/paper/complete.py index ca002a1..466f58f 100644 --- a/paper_writer_service/app/services/paper/complete.py +++ b/paper_writer_service/app/services/paper/complete.py @@ -39,6 +39,7 @@ async def get_paper(paper_id: str, format: str = "md") -> dict[str, Any]: return { "ok": True, "paper_id": paper_id, "title": paper["title"], "status": paper["status"], "template_key": brief.get("template_key") or "document", + "brief": brief, "sections": [ {"section_id": s["section_id"], "title": s["title"], "status": s["status"], "word_count": s["word_count"]} for s in sections diff --git a/sdk/app/services/paper/agent.py b/sdk/app/services/paper/agent.py index 5842a81..316012c 100644 --- a/sdk/app/services/paper/agent.py +++ b/sdk/app/services/paper/agent.py @@ -170,9 +170,18 @@ async def _followup(db, session_id: str, text: str, paper_id: str, client: Paper await _write_message(db, session_id, blocks=blocks, text=blocks[0]["html"]) return blocks if status in ("outline", "writing"): - # 大纲/撰写阶段:把 text 视为补充要求,重新生成大纲(原大纲作废) - brief = await extract_brief(text) - outline = await client.call_tool("propose_paper_outline", {**brief, "topic": brief.get("topic") or text, "template_key": template_key}) + # 大纲/撰写阶段:修改意见 → 用原始 brief + 修改意见重新生成大纲(原大纲作废) + paper = await client.call_tool("get_paper", {"paper_id": paper_id}) + ob = (paper.get("brief") or {}) if paper.get("ok") else {} + outline = await client.call_tool("propose_paper_outline", { + "topic": ob.get("topic") or paper.get("title") or text, + "requirements": ";".join(x for x in [ob.get("requirements"), text] if x), + "paper_type": ob.get("paper_type") or "", + "language": ob.get("language") or "", + "length": ob.get("length") or "", + "format_req": ob.get("format_req") or "", + "template_key": template_key, + }) if outline.get("ok"): await client.call_tool("cancel_paper", {"paper_id": paper_id}) return await _outline_message(db, session_id, outline) diff --git a/ui/src/components/chat/Composer.vue b/ui/src/components/chat/Composer.vue index 3abf9a6..3cb2c02 100644 --- a/ui/src/components/chat/Composer.vue +++ b/ui/src/components/chat/Composer.vue @@ -128,6 +128,36 @@ const hasBioflowContext = computed(() => { } }); +/** 论文上下文(当前会话消息含 paper 块;用于把修改意见路由回 sendPaper) */ +const hasPaperContext = computed(() => { + try { + const chat = useChatStore(); + const list = chat.messages || []; + return list.some((m) => m && m.role === 'assistant' && Array.isArray(m.blocks) + && m.blocks.some((b) => b && ['paper_brief', 'paper_outline', 'paper_progress'].includes(b.type))); + } catch { + return false; + } +}); + +/** 当前活跃论文 id(从最近的 paper_outline/paper_progress 块取) */ +const activePaperId = computed(() => { + try { + const chat = useChatStore(); + const list = chat.messages || []; + for (let i = list.length - 1; i >= 0; i--) { + const m = list[i]; + if (!m || m.role !== 'assistant' || !Array.isArray(m.blocks)) continue; + for (const b of m.blocks) { + if (b && (b.type === 'paper_outline' || b.type === 'paper_progress') && b.paper_id) return b.paper_id; + } + } + return null; + } catch { + return null; + } +}); + /** 生信可用(探活显隐 FR-BIO-025;未探活视为可用不阻断分流——后端不注册时由请求失败兜底) */ const bioflowEnabled = computed(() => { try { @@ -344,6 +374,13 @@ const submit = () => { const dg = useDocgenStore(); dg.requestExport(); dg.switchToDocTab(); + } else if (hasPaperContext.value && paperEnabled.value) { + // 活跃论文(outline/writing/complete 阶段)的修改意见 → sendPaper(带 paper_id) + try { + useChatStore().sendPaper(text, { paperId: activePaperId.value || '' }).catch(() => {}); + } catch { + emit('send', text); + } } else { // QA 原路径:附件注记进消息文本 const note = attachmentNoteText(); diff --git a/ui/src/stores/chat.js b/ui/src/stores/chat.js index b35a2d0..3a2815c 100644 --- a/ui/src/stores/chat.js +++ b/ui/src/stores/chat.js @@ -1580,7 +1580,7 @@ export const useChatStore = defineStore('chat', { // 写稿期由 confirmPaper 触发后台循环,前端 2s 轮询 paperProgress 更新进度卡, // complete 后重载会话取 agent 直写的 artifact 块并接管到文档 TAB。 // =============================================================== - async sendPaper(description, { userMsg, templateId } = {}) { + async sendPaper(description, { userMsg, templateId, paperId } = {}) { const q = String(description == null ? '' : description).trim(); if (!q || this.busy) return; const sessions = useSessionsStore(); @@ -1628,7 +1628,7 @@ export const useChatStore = defineStore('chat', { // 2. POST turns(短同步) let payload; try { - payload = await paperTurn({ session_id: sessionId, text: q, template_key: templateId || '' }); + payload = await paperTurn({ session_id: sessionId, text: q, paper_id: paperId || null, template_key: templateId || '' }); } catch (err) { const marker = this._errorMarker(err.code); const text = err.message || (marker && marker.text) || T.upstreamError;