chat: 持久化继续消息,chat-history 交替历史
基线 main 811912c(PR #125 Muse 风格之后):服务端与单测与 9538825 相同;React 侧在 Muse 风格 ContinuePanel 上重放 chat-history 集成(新版输入框占位文案保持 Muse 风格的“消息”), console.html 由新版 src 重新构建。 - 新表 task_continue_messages:POST /continue 的用户消息与状态改回 queued 同一事务落盘,409 被拒不留 phantom 消息 - GET /tasks/{id}/chat-history:prompt + 继续 + 后续消息 + 链路按 时间交错拼好返回;部署前继续以 legacy_continue_count 如实标注 - React ContinuePanel 优先用 chat-history,旧服务端自动回退
This commit is contained in:
1 parent
811912c841
commit
f02c513729
9 files changed
+524
-40
No files matched your search
@@ -5,25 +5,33 @@ import { traceEntryToChatMessage, type ChatMessage } from "../../components/chat
|
||||
import { TRACE_TERMINAL } from "../../api/types";
|
||||
|
||||
// Continue chat: same ChatList/ChatBubble/ChatInput as the trace timeline.
|
||||
// History is the task prompt (user) + message-kind trace entries
|
||||
// (assistant) + followups already sent (user). Live followups and trace
|
||||
// entries carry no timestamps, so they cannot be interleaved exactly:
|
||||
// followups are appended after trace messages and this is stated here
|
||||
// and in the final report, not hidden by a fabricated order.
|
||||
// Sending uses only live APIs: terminal tasks -> POST /tasks/:id/continue,
|
||||
// queued/running tasks -> POST /tasks/:id/followups (direct). No new API.
|
||||
// Preferred source is GET /chat-history (server-merged true alternating
|
||||
// history: prompt + persisted continues + followups + trace, in
|
||||
// timestamp order). Only when that endpoint is unavailable (old server)
|
||||
// fall back to the previous view: prompt + message-kind trace entries
|
||||
// + followups appended after — that fallback cannot interleave exactly
|
||||
// and cannot show pre-persistence continues, and it says so nowhere
|
||||
// else, so the fallback path is kept only as a compatibility shim.
|
||||
// Sending uses only live APIs: terminal tasks -> POST /tasks/:id/continue
|
||||
// (the server now persists that message in the same transaction),
|
||||
// queued/running tasks -> POST /tasks/:id/followups (direct).
|
||||
export default function ContinuePanel() {
|
||||
const ctx = useConsole();
|
||||
const t = ctx.currentTask;
|
||||
const messages = useMemo<ChatMessage[]>(() => {
|
||||
if (!t) return [];
|
||||
if (ctx.chatHistory) {
|
||||
return ctx.chatHistory.messages.map((m) => ({
|
||||
id: m.id, role: m.role, text: m.text, label: m.label,
|
||||
}));
|
||||
}
|
||||
const head: ChatMessage[] = t.prompt ? [{ id: "task-prompt", role: "user", text: t.prompt }] : [];
|
||||
const assistant = ctx.traceEntries.filter((e) => e.kind === "message").map((e, i) => traceEntryToChatMessage(e, i));
|
||||
const followups: ChatMessage[] = ctx.followups.map((f, i) => ({
|
||||
id: "followup-" + i, role: "user" as const, text: String(f.body || ""), label: "后续消息",
|
||||
}));
|
||||
return [...head, ...assistant, ...followups];
|
||||
}, [t, ctx.traceEntries, ctx.followups]);
|
||||
}, [t, ctx.chatHistory, ctx.traceEntries, ctx.followups]);
|
||||
if (!t) return <div className="muted">点任务行查看详情后,这里显示继续会话</div>;
|
||||
const terminal = TRACE_TERMINAL.includes(t.status);
|
||||
const running = ["queued", "running"].includes(t.status);
|
||||
@@ -33,8 +41,15 @@ export default function ContinuePanel() {
|
||||
: running
|
||||
? "运行中/排队中:发送走后续消息直接发送(跑完当前轮后优先执行)"
|
||||
: "merged/merge-failed 任务不可继续,也不可发后续消息";
|
||||
const legacy = ctx.chatHistory ? (ctx.chatHistory.legacy_continue_count ?? null) : null;
|
||||
return (
|
||||
<div className="chat-column">
|
||||
{legacy !== null && legacy > 0 ? (
|
||||
<div className="muted">此前有 {legacy} 条继续消息发生在持久化之前,未入库,上面历史不完整;部署后新发的继续消息会正常显示。</div>
|
||||
) : null}
|
||||
{ctx.chatHistory && ctx.chatHistory.trace_note ? (
|
||||
<div className="muted">{ctx.chatHistory.trace_note}</div>
|
||||
) : null}
|
||||
<ChatList messages={messages} empty="(暂无会话消息)" />
|
||||
<ChatInput
|
||||
disabled={!canSend}
|
||||
|
||||
Reference in new issue
Block a user