feat(teacher): stream Yuxi reasoning and answer previews

This commit is contained in:
2026-09-29 18:18:56 +08:00
parent f443f3bc66
commit 8ccc4650a2
12 changed files with 364 additions and 42 deletions

View File

@@ -36,6 +36,7 @@ import { prepareTeacherModel } from './model-runner';
import { prepareCloudTeacher } from './cloud-runner';
import { readTeacherSource } from './source-reader';
import { applyTeacherReply, teacherReplyInstructions } from './reply';
import { previewTeacherReply } from '../../shared/teacher-reply';
import { subscribeWorksSquareSession } from '../services/works-square-session';
export interface TeacherScope {
@@ -560,6 +561,7 @@ export class CodingTeacherService {
...(store instanceof TeacherConversationStore ? { archive: await store.history() } : {}),
assertCurrent: () => this.assertAccount(account),
};
let streamedResponse = '';
const model = isCloud && access
? (this.options.prepareCloud ?? prepareCloudTeacher)(account, topic, input.requestId, access,
(progress) => {
@@ -578,6 +580,16 @@ export class CodingTeacherService {
else activities[index] = activity;
topic.revision++;
this.events.emit(key, structuredClone(topic));
}, update => {
this.assertAccount(account);
const current = topic.requests.find(request => request.id === input.requestId)!;
if (update.reasoning) current.reasoning = (current.reasoning ?? '') + update.reasoning;
if (update.response !== undefined) {
streamedResponse = update.response;
current.response = previewTeacherReply(streamedResponse);
}
topic.revision++;
this.events.emit(key, structuredClone(topic));
})
: await (this.options.prepareModel ?? prepareTeacherModel)(account, topic.definition,
access,
@@ -671,10 +683,9 @@ export class CodingTeacherService {
: '智能体回复失败,已保留本次问题与收到的内容。';
} finally {
// Keep received bytes inert even when an aborted runner resolves normally.
if (structuredReply && current.status !== 'completed' && structuredText)
current.unparsedResponse = structuredText;
if (structuredReply && current.status !== 'completed' && (structuredText || streamedResponse))
current.unparsedResponse = structuredText || streamedResponse;
if (intent === 'suggestions' && current.status !== 'completed') {
current.response = '';
delete current.suggestedQuestions;
}
topic.updatedAt = new Date().toISOString();