Merge teacher reply cleanup with continuous conversations

This commit is contained in:
鲨鱼辣椒
2026-09-28 18:29:04 +08:00
40 changed files with 1759 additions and 1988 deletions

View File

@@ -11,7 +11,8 @@ interface TurnIndex { id: string; createdAt: string; origin?: string; messages:
interface Manifest {
topic: Omit<TeacherTopic, 'requests'>;
turns: TurnIndex[];
importedDiscussions?: Record<string, string>;
/** Retained verbatim when present in older manifests; no longer imported or interpreted. */
importedDiscussions?: unknown;
}
const PAGE_SIZE = 50;
const isMissing = (error: unknown) => (error as NodeJS.ErrnoException)?.code === 'ENOENT';
@@ -86,7 +87,7 @@ export class TeacherConversationStore {
schemaVersion: 1, revision: 0, id: randomUUID(), accountId: this.accountId,
projectId: '', sourceConversationId: 'project', definition: structuredClone(definition), version,
createdAt: now, updatedAt: now, requests: [],
conversation: { agentId: this.agentId, segmentTurns: 0, discussions: {} },
conversation: { agentId: this.agentId, segmentTurns: 0 },
};
// The manifest is durable before any turn file, so orphan recovery knows its owner.
const manifest: Manifest = { topic: { ...topic }, turns: [] };
@@ -221,12 +222,8 @@ export class TeacherConversationStore {
await this.save(topic, turn.id);
topic.requests = topic.requests.slice(-PAGE_SIZE);
}
if (old.discussion && (!topic.conversation!.discussions[project.id]
|| old.updatedAt > (this.manifest!.importedDiscussions?.[project.id] ?? ''))) {
(this.manifest!.importedDiscussions ??= {})[project.id] = old.updatedAt;
topic.conversation!.discussions[project.id] = structuredClone(old.discussion);
await this.save(topic, '');
}
// Retired component state stays in the untouched legacy topic. Import
// its conversation turns without creating active per-project components.
}
}
if (this.manifest) await this.recent();