fix: render consultation replies and typed tool activity

This commit is contained in:
2026-09-24 14:36:20 +08:00
parent a628860144
commit 97837cef90
19 changed files with 432 additions and 35 deletions

View File

@@ -198,6 +198,9 @@ describe('cloud coding teacher', () => {
await vi.waitFor(async () => expect((await f.service.read(f.scope, topic.id)).requests[0].status).toBe('completed'));
const saved = (await f.service.read(f.scope, topic.id)).requests[0];
expect(saved.response).toBe('计数器从 42 开始。');
expect(saved.toolActivity).toEqual([{ id: 'parent:read-counter', name: 'read_project_file', status: 'completed' }]);
const restarted = await f.restart();
expect((await restarted.read(f.scope, topic.id)).requests[0].toolActivity).toEqual(saved.toolActivity);
expect(saved.cloudRequestId).toBe('cloud-question');
expect(JSON.stringify(requests[0].body)).toContain('const title');
expect(saved.truncatedMessages).toBeGreaterThan(0);
@@ -1377,6 +1380,25 @@ describe('structured teacher service integration', () => {
describe('project consultations with selected cloud teachers', () => {
it('persists malformed discussion output without putting it into future model context', async () => {
const f = await fixture();
const scope = { ...f.scope, sourceId: 'project' };
const selected = await f.service.create(scope);
const raw = '{"reply":"这段正文完整。","tool":{"privateDiagnostic":"only-in-original"';
f.replyWith(raw);
await f.service.send(scope, selected.id, {
requestId: crypto.randomUUID(), text: '看看项目', presentation: 'discussion-v1', sourceConversationId: f.scope.sourceId,
});
f.finish();
await vi.waitFor(async () => expect((await f.service.read(scope, selected.id)).requests[0].status).toBe('completed'));
const restarted = await f.restart();
const saved = await restarted.read(scope, selected.id);
expect(saved.requests[0]).toMatchObject({ response: '这段正文完整。', unparsedResponse: raw });
const compiled = compileTeacherContext(saved.definition, context, saved.requests, '继续聊', []);
expect(JSON.stringify(compiled.messages)).not.toContain('only-in-original');
expect(JSON.stringify(compiled.messages)).toContain('这段正文完整。');
});
it.each(['local', 'yuxi'])('keeps the published identity and project tools on the %s runtime', async (runtime) => {
const f = await fixture({ cloudTeacher: runtime === 'yuxi', mockCloud: runtime === 'yuxi' });
const scope = { ...f.scope, sourceId: 'project' };