100 lines
3.3 KiB
JavaScript
100 lines
3.3 KiB
JavaScript
import assert from 'node:assert/strict';
|
|
import test from 'node:test';
|
|
import {
|
|
reconcileSessionEventRequestContext,
|
|
resolvePostAgentRunChatState,
|
|
shouldKeepStreamingAfterRunError,
|
|
shouldPromoteSessionIdToStreaming,
|
|
} from './chat-agent-run-gate.mjs';
|
|
|
|
test('resolvePostAgentRunChatState keeps idle when Finish beat agent-run gate', () => {
|
|
assert.equal(
|
|
resolvePostAgentRunChatState({ chatState: 'idle', finishedViaPortalDirectChat: false }),
|
|
'idle',
|
|
);
|
|
});
|
|
|
|
test('resolvePostAgentRunChatState returns streaming while still waiting for session Finish', () => {
|
|
assert.equal(resolvePostAgentRunChatState({ chatState: 'waiting' }), 'streaming');
|
|
assert.equal(resolvePostAgentRunChatState({ chatState: 'streaming' }), 'streaming');
|
|
});
|
|
|
|
test('resolvePostAgentRunChatState prefers portal direct chat completion', () => {
|
|
assert.equal(
|
|
resolvePostAgentRunChatState({ chatState: 'streaming', finishedViaPortalDirectChat: true }),
|
|
'idle',
|
|
);
|
|
});
|
|
|
|
test('resolvePostAgentRunChatState idles after worker-side agent run success', () => {
|
|
assert.equal(
|
|
resolvePostAgentRunChatState({ chatState: 'waiting', agentRunSucceeded: true }),
|
|
'idle',
|
|
);
|
|
assert.equal(
|
|
resolvePostAgentRunChatState({ chatState: 'streaming', agentRunSucceeded: true }),
|
|
'idle',
|
|
);
|
|
});
|
|
|
|
test('completed run wins when the direct-chat snapshot is not ready', () => {
|
|
assert.equal(
|
|
resolvePostAgentRunChatState({
|
|
chatState: 'streaming',
|
|
finishedViaPortalDirectChat: false,
|
|
agentRunSucceeded: true,
|
|
}),
|
|
'idle',
|
|
);
|
|
});
|
|
|
|
test('only ambiguous transport failures keep the chat streaming', () => {
|
|
assert.equal(shouldKeepStreamingAfterRunError(0), true);
|
|
assert.equal(shouldKeepStreamingAfterRunError(409), false);
|
|
assert.equal(shouldKeepStreamingAfterRunError(503), true);
|
|
assert.equal(shouldKeepStreamingAfterRunError(400), false);
|
|
assert.equal(shouldKeepStreamingAfterRunError(undefined), false);
|
|
assert.equal(
|
|
shouldKeepStreamingAfterRunError(
|
|
409,
|
|
'Session already has an active request. Cancel it first.',
|
|
),
|
|
true,
|
|
);
|
|
assert.equal(
|
|
shouldKeepStreamingAfterRunError(
|
|
undefined,
|
|
'Session already has an active request. Cancel it first.',
|
|
),
|
|
true,
|
|
);
|
|
assert.equal(shouldKeepStreamingAfterRunError(undefined, '后台任务失败'), false);
|
|
});
|
|
|
|
test('shouldPromoteSessionIdToStreaming skips re-streaming after Finish', () => {
|
|
assert.equal(shouldPromoteSessionIdToStreaming('idle'), false);
|
|
assert.equal(shouldPromoteSessionIdToStreaming('waiting'), true);
|
|
assert.equal(shouldPromoteSessionIdToStreaming('streaming'), true);
|
|
});
|
|
|
|
test('reconcileSessionEventRequestContext adopts Goose request id while agent-run gate waits', () => {
|
|
assert.deepEqual(
|
|
reconcileSessionEventRequestContext({
|
|
activeRequestId: 'portal-req',
|
|
chatState: 'waiting',
|
|
eventType: 'ActiveRequests',
|
|
activeRequestIds: ['goose-req'],
|
|
}),
|
|
{ activeRequestId: 'goose-req', promoteStreaming: true, allowMissingGrace: false },
|
|
);
|
|
assert.deepEqual(
|
|
reconcileSessionEventRequestContext({
|
|
activeRequestId: 'portal-req',
|
|
chatState: 'waiting',
|
|
eventType: 'Message',
|
|
eventRequestId: 'goose-req',
|
|
}),
|
|
{ activeRequestId: 'goose-req', promoteStreaming: true, allowMissingGrace: false },
|
|
);
|
|
});
|