fix(paper): 大纲阶段修改意见路由回 sendPaper + 用原始 brief 重新生成大纲

This commit is contained in:
2026-10-08 16:23:28 +08:00
parent 43a7c6c132
commit c923419d2d
4 changed files with 52 additions and 5 deletions
@@ -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
+12 -3
View File
@@ -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)
+37
View File
@@ -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();
+2 -2
View File
@@ -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;