feat(consultation): unify server-distributed agents without fixed roles

This commit is contained in:
brother7 committed 2026-09-24 11:56:42 +08:00
1 parent 248776d855
commit 8a157be4f6
35 files changed
+625 -668

No files matched your search

+9 -10
View File
@@ -1,9 +1,8 @@
// @vitest-environment node
import { describe, expect, it } from 'vitest';
import examples from '../fixtures/teacher-guidance-examples.json';
import { TEACHER_BEHAVIOR_PROMPT } from '../../electron/coding-teacher/behavior-prompt';
const TEACHER_BEHAVIOR_PROMPT = '你是麦洛的创作老师';
import { compileTeacherContext, estimateTeacherTokens, teacherHistoryMessages } from '../../electron/coding-teacher/context';
import { consultationDefinition } from '../../electron/coding-teacher/consultation-role';
import { applyDiscussionReply, discussionInstructions, editDiscussion, validateDiscussionContext } from '../../electron/coding-teacher/discussion';
import { parseTeacherDiscussionReply } from '../../shared/teacher-discussion';
import type { TeacherDefinition, TeacherDiscussionAction, TeacherDiscussionContext, TeacherRequest, TeacherSourceContext, TeacherTopic } from '../../shared/coding-teacher';
@@ -31,7 +30,7 @@ function turn(owner: TeacherTopic, text: string, response: unknown, extra: Parti
const context = owner.discussion?.status === 'active'
? validateDiscussionContext(owner, { toolId: owner.discussion.id, revision: owner.discussion.revision, ...extra }) : undefined;
const compiled = compileTeacherContext(definition, source, owner.requests, text, [], undefined, 'question', discussionInstructions(owner, context));
expect(compiled.messages[0].content).toContain(TEACHER_BEHAVIOR_PROMPT);
expect(compiled.messages[0].content).not.toContain(TEACHER_BEHAVIOR_PROMPT);
expect(compiled.includedSourceMessageIds).toEqual(['source']);
expect(estimateTeacherTokens(compiled.messages)).toBeLessThanOrEqual(definition.limits.max_input_tokens);
const request: TeacherRequest = { id: `turn-${owner.requests.length}`, text, references: [], createdAt: 'now',
@@ -53,11 +52,11 @@ describe('teacher behavior wiring and per-request formats', () => {
expect(configured.system_prompt).toBe(`\n${TEACHER_BEHAVIOR_PROMPT}\n`);
});
it.each(['question', 'suggestions', 'guided-help', 'check-in'] as const)('applies teacher guidance to %s without mutating the cloud definition', intent => {
it.each(['question', 'suggestions', 'guided-help', 'check-in'] as const)('preserves the published persona for %s without mutating the cloud definition', intent => {
const before = structuredClone(definition);
const compiled = compileTeacherContext(definition, source, [], '帮我想一想', [], undefined, intent);
const system = compiled.messages[0].content;
expect(system.split(TEACHER_BEHAVIOR_PROMPT)).toHaveLength(2);
expect(system).not.toContain(TEACHER_BEHAVIOR_PROMPT);
expect(system).toContain(definition.system_prompt);
expect(system).toContain('启用的教学补充');
expect(system).not.toContain('不应加载的资料');
@@ -67,19 +66,19 @@ describe('teacher behavior wiring and per-request formats', () => {
expect(compiled.messages.some(message => message.content.includes('本轮界面协议'))).toBe(false);
});
it('leaves the friend persona and enabled teaching material isolated', () => {
const friend = consultationDefinition(definition, 'friend');
it('uses a server-defined friend persona with its own skills and the same project tools', () => {
const friend = { ...definition, teacher_id: 'published-friend', name: '朋友', system_prompt: '我是运营发布的朋友,只聊作品体验。' };
const compiled = compileTeacherContext(friend, source, [], '你觉得呢', [], undefined, 'question', undefined, true);
expect(compiled.messages[0].content).toContain(friend.system_prompt);
expect(compiled.messages[0].content).not.toContain(TEACHER_BEHAVIOR_PROMPT);
expect(compiled.messages[0].content).not.toContain('启用的教学补充');
expect(compiled.messages[0].content).not.toContain('你可以通过只读工具');
expect(compiled.messages[0].content).toContain('启用的教学补充');
expect(compiled.messages[0].content).toContain('你可以通过只读工具');
});
it('keeps the structured guided-help format alongside project read access and teaching guidance', () => {
const instructions = discussionInstructions(topic());
const compiled = compileTeacherContext(definition, source, [], '我说不清', [], undefined, 'guided-help', instructions, true);
expect(compiled.messages[0].content).toContain(TEACHER_BEHAVIOR_PROMPT);
expect(compiled.messages[0].content).not.toContain(TEACHER_BEHAVIOR_PROMPT);
expect(compiled.messages[0].content).toContain('你可以通过只读工具');
expect(compiled.messages[0].content).not.toContain('没有项目读取工具');
expect(compiled.messages.at(-2)).toEqual({ role: 'system', content: instructions });