feat(h5): web 联网能力、实时查询路由与 session Finish 对齐
- 新增 web 能力并挂载 platform/web(web_search/fetch_url) - 实时查询强制 web skill,router fallback 与 await session Finish - Session Broker 覆盖率/指标、stream replay 与相关单测/E2E 脚本 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,35 @@
|
||||
import assert from 'node:assert/strict';
|
||||
import test from 'node:test';
|
||||
import { ReadableStream } from 'node:stream/web';
|
||||
import {
|
||||
consumeSessionEventsUntilFinish,
|
||||
eventMatchesRequest,
|
||||
parseSessionStreamEvent,
|
||||
} from './session-reply-wait.mjs';
|
||||
|
||||
test('parseSessionStreamEvent parses SSE data payload', () => {
|
||||
const event = parseSessionStreamEvent('id: 1\ndata: {"type":"Finish","token_state":null}\n');
|
||||
assert.equal(event?.type, 'Finish');
|
||||
});
|
||||
|
||||
test('eventMatchesRequest scopes by request id when present', () => {
|
||||
assert.equal(eventMatchesRequest({ request_id: 'req-1' }, 'req-1'), true);
|
||||
assert.equal(eventMatchesRequest({ request_id: 'req-2' }, 'req-1'), false);
|
||||
assert.equal(eventMatchesRequest({ type: 'Finish' }, 'req-1'), true);
|
||||
});
|
||||
|
||||
test('consumeSessionEventsUntilFinish resolves on Finish', async () => {
|
||||
const frames = [
|
||||
'data: {"type":"Message","request_id":"req-1","message":{"role":"assistant"}}\n\n',
|
||||
'data: {"type":"Finish","request_id":"req-1","token_state":{"totalTokens":12}}\n\n',
|
||||
];
|
||||
const stream = new ReadableStream({
|
||||
start(controller) {
|
||||
for (const frame of frames) controller.enqueue(new TextEncoder().encode(frame));
|
||||
controller.close();
|
||||
},
|
||||
});
|
||||
const result = await consumeSessionEventsUntilFinish(stream, { requestId: 'req-1', timeoutMs: 5000 });
|
||||
assert.equal(result.finishEvent.type, 'Finish');
|
||||
assert.equal(result.tokenState.totalTokens, 12);
|
||||
});
|
||||
Reference in New Issue
Block a user