fix: isolate visual tool failures from agent runs

This commit is contained in:
john
2026-07-27 19:20:23 +08:00
parent 7002007128
commit 17c59fde71
10 changed files with 444 additions and 16 deletions
+43
View File
@@ -2,6 +2,7 @@ import assert from 'node:assert/strict';
import test from 'node:test';
import { ReadableStream } from 'node:stream/web';
import {
classifySessionProviderErrorMessage,
consumeSessionEventsUntilFinish,
eventMatchesRequest,
parseSessionStreamEvent,
@@ -139,3 +140,45 @@ test('consumeSessionEventsUntilFinish surfaces provider tool history errors befo
},
);
});
test('consumeSessionEventsUntilFinish classifies unsupported visual history as degradable', async () => {
const message =
'Request failed: Bad request (400): Failed to deserialize the JSON body into the target type: messages[8]: unknown variant `image_url`, expected `text`';
assert.equal(
classifySessionProviderErrorMessage(message),
'SESSION_VISUAL_CONTEXT_UNSUPPORTED',
);
const frames = [
`data: ${JSON.stringify({
type: 'Message',
request_id: 'req-visual',
message: {
role: 'assistant',
content: [{
type: 'text',
text: `Ran into this error: ${message}\n\nPlease retry if you think this is a transient or recoverable error.`,
}],
},
})}\n\n`,
'data: {"type":"Finish","request_id":"req-visual"}\n\n',
];
const stream = new ReadableStream({
start(controller) {
for (const frame of frames) controller.enqueue(new TextEncoder().encode(frame));
controller.close();
},
});
await assert.rejects(
consumeSessionEventsUntilFinish(stream, {
requestId: 'req-visual',
timeoutMs: 5000,
}),
(error) => {
assert.equal(error.code, 'SESSION_VISUAL_CONTEXT_UNSUPPORTED');
assert.equal(error.retryable, false);
return true;
},
);
});