fix(teacher): 区分词元预算与传输字节避免短问题被拦截

This commit is contained in:
2026-09-24 11:09:29 +08:00
parent eb3dc85a2f
commit de72b1cd94
10 changed files with 187 additions and 35 deletions

View File

@@ -85,7 +85,7 @@ async function submitCompiledContext(
);
const compiled = compileTeacherContext(
f.topic.definition, f.access.source, [], intent === 'check-in' ? '' : '下一步怎么想?', [],
model.inputLimit, intent, presentationInstructions, true
model.inputLimit, intent, presentationInstructions, true, model.measureInput
);
await model.run(compiled.messages, new AbortController().signal, vi.fn());
const body = vi.mocked(transport.json).mock.calls.find(([url]) => url === '/questions')?.[1] as {
@@ -130,6 +130,32 @@ it('submits the active discussion protocol, current tool content and selected fo
expect(protocol).toContain('比较两种重力');
});
it('submits a short first question with the normal discussion protocol and published budget', async () => {
const f = await fixture();
const { body } = await submitCompiledContext(f, 'question', discussionInstructions(f.topic));
expect(body.query).toContain('下一步怎么想?');
});
it('excerpts long code context to fit the serialized cloud query', async () => {
const f = await fixture();
f.access.source.messages[0].text = 'const title = "game";\n'.repeat(500);
const { body, compiled } = await submitCompiledContext(f);
expect(compiled.truncatedMessages).toBeGreaterThan(0);
expect(body.query).toContain('下一步怎么想?');
});
it('fits code excerpts beside the unchanged discussion protocol in the original cloud budget', async () => {
const f = await fixture();
const original = 'const config = { "title": "小游戏" };\n'.repeat(500);
f.access.source.messages[0].text = original;
const protocol = discussionInstructions(f.topic);
const { body, compiled } = await submitCompiledContext(f, 'question', protocol);
expect(compiled.messages.at(-2)?.content).toBe(protocol);
expect(compiled.truncatedMessages).toBeGreaterThan(0);
expect(f.access.source.messages[0].text).toBe(original);
expect(JSON.parse(body.query).messages.at(-1).content).toContain('下一步怎么想?');
});
it('submits a nonempty proactive check-in without inventing a user message', async () => {
const f = await fixture();
f.access.source.messages = [];