fix: preserve complete consultation replies and recover retained history

This commit is contained in:
鲨鱼辣椒
2026-09-28 17:38:31 +08:00
parent dda2f0a3be
commit d530abe580
14 changed files with 643 additions and 38 deletions

View File

@@ -1,5 +1,6 @@
// Deterministic responses for layout/interaction tests only; never imported by the app.
import type { TeacherDefinition, TeacherTopic, TeacherSend } from '../../../shared/coding-teacher';
import { parseTeacherReply } from '../../../shared/teacher-reply';
const definition: TeacherDefinition = { schema_version: 1, teacher_id: 'coding-teacher', name: '麦洛智能体', description: '', avatar_id: 'avatar-01', welcome_message: '', suggested_questions: [], system_prompt: '测试', skills: [], model: { model_id: 'fixture', reasoning_choice: { mode: 'default' } }, limits: { max_input_tokens: 8000, max_output_tokens: 1500 } };
const samples: Record<string, unknown> = {
ideas: { kind: 'ideas', title: '我的小狗世界', items: [{ id: 'dog', text: '养一只自己的小狗', state: 'kept' }, { id: 'breed', parentId: 'dog', text: '是一只柯基', state: 'kept' }, { id: 'garden', text: '有一片可以种东西的花园', state: 'kept' }, { id: 'food', parentId: 'garden', text: '种出来的东西可以喂小狗', state: 'suggested' }] },
@@ -10,6 +11,17 @@ const samples: Record<string, unknown> = {
const scenario = new URLSearchParams(location.search).get('kind') ?? 'ideas';
let current: TeacherTopic = { schemaVersion: 1, revision: 1, id: 'discussion-fixture', accountId: 'fixture', projectId: 'fixture', sourceConversationId: 'project', definition, version: 1, createdAt: 'now', updatedAt: 'now', requests: Array.from({ length: 8 }, (_, i) => ({ id: `r${i}`, text: i === 7 ? '我还没想好,我们边聊边想。' : '我希望这个游戏更有意思。', references: [], createdAt: 'now', sourceCursor: { workerGeneration: 0, seq: i }, sourceCapturedAt: 'now', includedSourceMessageIds: [], omittedMessages: 0, status: 'completed', response: i === 7 ? '可以,我们先把已经想到的放在一起。哪里还不确定,就留着继续聊。' : '先从你最在意的一个小地方开始想。', ...(i === 7 ? { suggestedQuestions: ['有什么好玩的想法?'] } : {}) })), ...(samples[scenario] ? { discussion: { id: 'tool', revision: 1, status: 'active', content: structuredClone(samples[scenario]) } } : {}) };
const stream = Object.assign(new EventTarget(), { close() {}, onerror: null, onopen: null });
if (scenario === 'recovered' || scenario === 'incomplete') {
const raw = '{"reply":"它早就不是"刚搭好架子"那种阶段了——骨架、玩法、成长线都在跑。\n现在的阶段是「能玩,正在调手感」。'
+ (scenario === 'recovered' ? '","quickReplies":[],"tool":{"kind":"structure","nodes":[]}}' : '');
const parsed = parseTeacherReply(raw);
current.requests = [{
...current.requests[0], text: '现在项目是什么阶段?', sourceConversationId: 'original-source',
references: [{ messageId: 'original-message', text: '原来的项目记录', role: 'assistant' }],
response: parsed.reply, replyIncomplete: parsed.incomplete, replyParseError: parsed.parseError,
suggestedQuestions: parsed.quickReplies, unparsedResponse: raw,
}];
}
if (scenario === 'retry') {
const status = new URLSearchParams(location.search).get('status') === 'cancelled' ? 'cancelled' : 'failed';
current.requests = [{