feat(h5): inject direct-chat history on agent escalation and defer ambiguous routing.

Phase B appends snapshot context when leaving h5direct sessions so Goose no longer starts blind. Phase C lets the 0.72 fallback return null on gated chat text so the existing LLM router can run, flags default off.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
john
2026-08-28 20:45:34 +08:00
parent 6f48cad4c2
commit 5f3980e0df
9 changed files with 654 additions and 3 deletions
+61
View File
@@ -2737,6 +2737,67 @@ test('agent run persists direct session transcript before escalating to goosed',
assert.equal(removed[0], 'deep-session-1');
});
test('agent run injects direct escalation context when feature flag is enabled', async () => {
const pool = createFakePool({
sessionDeliverables: {
'user-1:deep-session-1': [{
page_id: 'page-deep-context',
title: '深度页面',
publication_id: 'pub-deep-context',
publication_status: 'online',
public_url: 'http://127.0.0.1:5173/MindSpace/user-1/public/a.html',
}],
},
});
const submitted = [];
const gateway = createAgentRunGateway({
pool,
tkmindProxy: {
async startSessionForUser(userId) {
assert.equal(userId, 'user-1');
return { id: 'deep-session-1' };
},
async submitSessionReplyForUser(userId, sessionId, requestId, userMessage, options = {}) {
submitted.push({ userId, sessionId, requestId, userMessage, options });
},
},
sessionSnapshotService: {
async get(sessionId) {
if (sessionId !== 'h5direct_existing') return null;
return {
messages: [
{ role: 'user', content: [{ type: 'text', text: '中考政策' }] },
{ role: 'assistant', content: [{ type: 'text', text: '政策摘要' }] },
],
};
},
async remove() {},
},
conversationMemoryService: {
async saveConversationMessages(_sessionId, _userId, messages) {
return messages;
},
},
directEscalationContextPolicy: {
enabled: true,
canaryUserIds: new Set(),
},
retryDelaysMs: [],
});
const run = await gateway.createRun('user-1', {
sessionId: 'h5direct_existing',
requestId: 'req-force-deep-context',
userMessage: { role: 'user', content: [{ type: 'text', text: '帮我生成页面 public/a.html' }] },
forceDeepReasoning: true,
});
await waitFor(() => pool.runs.get(run.id)?.status === 'succeeded');
assert.ok(pool.events.some((event) => event.eventType === 'direct_escalation_context_injected'));
assert.match(submitted[0].userMessage.content[0].text, /会话恢复上下文/);
assert.match(submitted[0].userMessage.content[0].text, /中考政策/);
});
test('agent run rejects reused goosed session when broker ownership check fails', async () => {
const pool = createFakePool();
const gateway = createAgentRunGateway({