feat: align teacher guidance with persistent discussion tools

This commit is contained in:
鲨鱼辣椒
2026-09-23 22:44:23 +08:00
parent 404cfcde46
commit 847a752dba
8 changed files with 362 additions and 10 deletions

View File

@@ -6,6 +6,7 @@ import { afterEach, describe, expect, it, vi } from 'vitest';
import { CodingTeacherService, type TeacherScope } from '../../electron/coding-teacher/service';
import { TeacherTopicStore } from '../../electron/coding-teacher/store';
import { compileTeacherContext, estimateTeacherTokens, sourceContext } from '../../electron/coding-teacher/context';
import { TEACHER_BEHAVIOR_PROMPT } from '../../electron/coding-teacher/behavior-prompt';
import { streamTeacherReply } from '../../electron/coding-teacher/model-runner';
import { TeacherError } from '../../electron/coding-teacher/config-client';
import { consultationDefinition } from '../../electron/coding-teacher/consultation-role';
@@ -985,6 +986,10 @@ describe('teacher context and wire contract', () => {
expect(selected.cursor).toEqual(snapshot.cursor);
});
it('trims old source messages but retains instructions, Skill, explicit quote and question', () => {
const references = [{ kind: 'code' as const, text: 'count += 1' }];
const budget = estimateTeacherTokens(compileTeacherContext(
definition, context, [], '为什么这样?', references
).messages);
const compiled = compileTeacherContext(
definition,
{
@@ -993,13 +998,15 @@ describe('teacher context and wire contract', () => {
},
[],
'为什么这样?',
[{ kind: 'code', text: 'count += 1' }],
1200
references,
budget
);
const text = JSON.stringify(compiled.messages);
expect(text).toContain('通过问题引导思考');
expect(text).toContain('使用具体的小例子');
expect(text).toContain('count += 1');
expect(compiled.messages[0].content).toContain(TEACHER_BEHAVIOR_PROMPT);
expect(compiled.includedSourceMessageIds).toEqual(['source-user']);
expect(compiled.omittedMessages).toBe(1);
expect(() => compileTeacherContext(definition, context, [], 'x'.repeat(9000), [])).toThrow(
'超过上下文预算'
@@ -1169,6 +1176,9 @@ describe('structured teacher service integration', () => {
requestId: crypto.randomUUID(), text, presentation: 'discussion-v1', sourceConversationId: f.scope.sourceId, discussion,
});
const pending = await send('想养只小狗');
const modelMessages = f.run.mock.calls[0][0] as Array<{ role: string; content: string }>;
expect(modelMessages[0].content).toContain(TEACHER_BEHAVIOR_PROMPT);
expect(modelMessages.some(message => message.role === 'system' && message.content.includes('本轮界面协议'))).toBe(true);
expect(pending.requests[0].response).toBe('');
expect(pending.discussion).toBeUndefined();
f.finish();