import { useMemo } from "react"; import { useConsole } from "../../context"; import { ChatList, ChatInput } from "../../components/chat/Chat"; import { traceEntryToChatMessage, type ChatMessage } from "../../components/chat/mapTrace"; import { TRACE_TERMINAL } from "../../api/types"; // Continue chat: same ChatList/ChatBubble/ChatInput as the trace timeline. // 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(() => { 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.chatHistory, ctx.traceEntries, ctx.followups]); if (!t) return
点任务行查看详情后,这里显示继续会话
; const terminal = TRACE_TERMINAL.includes(t.status); const running = ["queued", "running"].includes(t.status); const canSend = terminal || running; const hint = terminal ? "终态任务:发送走继续接口(同一会话再跑一轮)" : running ? "运行中/排队中:发送走后续消息直接发送(跑完当前轮后优先执行)" : "merged/merge-failed 任务不可继续,也不可发后续消息"; const legacy = ctx.chatHistory ? (ctx.chatHistory.legacy_continue_count ?? null) : null; return (
{legacy !== null && legacy > 0 ? (
此前有 {legacy} 条继续消息发生在持久化之前,未入库,上面历史不完整;部署后新发的继续消息会正常显示。
) : null} {ctx.chatHistory && ctx.chatHistory.trace_note ? (
{ctx.chatHistory.trace_note}
) : null} void ctx.sendChatMessage(text)} />
{hint}。{ctx.chatMsg}
); }