fix(cli): revert breaking stream crash on limits to restore bot compatibility

This commit is contained in:
Adam Weidman
2026-03-17 15:06:10 -04:00
parent 1f727251eb
commit 5ba92577c5
5 changed files with 33 additions and 19 deletions
+6 -3
View File
@@ -486,7 +486,8 @@
"version": "2.11.0",
"resolved": "https://registry.npmjs.org/@bufbuild/protobuf/-/protobuf-2.11.0.tgz",
"integrity": "sha512-sBXGT13cpmPR5BMgHE6UEEfEaShh5Ror6rfN3yEK5si7QVrtZg8LEPQb0VVhiLRUslD2yLnXtnRzG035J/mZXQ==",
"license": "(Apache-2.0 AND BSD-3-Clause)"
"license": "(Apache-2.0 AND BSD-3-Clause)",
"peer": true
},
"node_modules/@bundled-es-modules/cookie": {
"version": "2.0.1",
@@ -1489,6 +1490,7 @@
"resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.13.4.tgz",
"integrity": "sha512-GsFaMXCkMqkKIvwCQjCrwH+GHbPKBjhwo/8ZuUkWHqbI73Kky9I+pQltrlT0+MWpedCoosda53lgjYfyEPgxBg==",
"license": "Apache-2.0",
"peer": true,
"dependencies": {
"@grpc/proto-loader": "^0.7.13",
"@js-sdsl/ordered-map": "^4.4.2"
@@ -7411,7 +7413,8 @@
"version": "0.0.1581282",
"resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1581282.tgz",
"integrity": "sha512-nv7iKtNZQshSW2hKzYNr46nM/Cfh5SEvE2oV0/SEGgc9XupIY5ggf84Cz8eJIkBce7S3bmTAauFD6aysMpnqsQ==",
"license": "BSD-3-Clause"
"license": "BSD-3-Clause",
"peer": true
},
"node_modules/dezalgo": {
"version": "1.0.4",
@@ -16247,7 +16250,6 @@
"version": "2.8.1",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
"integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==",
"dev": true,
"license": "0BSD",
"peer": true
},
@@ -17865,6 +17867,7 @@
"resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.14.3.tgz",
"integrity": "sha512-Iq8QQQ/7X3Sac15oB6p0FmUg/klxQvXLeileoqrTRGJYLV+/9tubbr9ipz0GKHjmXVsgFPo/+W+2cA8eNcR+XA==",
"license": "Apache-2.0",
"peer": true,
"dependencies": {
"@grpc/proto-loader": "^0.8.0",
"@js-sdsl/ordered-map": "^4.4.2"
@@ -10,8 +10,9 @@ exports[`runNonInteractive > should emit appropriate error event in streaming JS
exports[`runNonInteractive > should emit appropriate error event in streaming JSON mode: 'max session turns' 1`] = `
"{"type":"init","timestamp":"<TIMESTAMP>","session_id":"test-session-id","model":"test-model"}
{"type":"message","timestamp":"<TIMESTAMP>","role":"user","content":"Max turns test"}
{"type":"result","timestamp":"<TIMESTAMP>","status":"error","error":{"type":"FatalTurnLimitedError","message":"Reached max session turns for this session. Increase the number of turns by specifying maxSessionTurns in settings.json."},"stats":{"total_tokens":0,"input_tokens":0,"output_tokens":0,"cached":0,"input":0,"duration_ms":<DURATION>,"tool_calls":0,"models":{}}}
{"type":"result","timestamp":"<TIMESTAMP>","status":"error","error":{"type":"Error","message":"[API Error: process.exit(53) called]"},"stats":{"total_tokens":0,"input_tokens":0,"output_tokens":0,"cached":0,"input":0,"duration_ms":<DURATION>,"tool_calls":0,"models":{}}}
{"type":"error","timestamp":"<TIMESTAMP>","severity":"error","message":"Maximum session turns exceeded"}
{"type":"result","timestamp":"<TIMESTAMP>","status":"success","stats":{"total_tokens":0,"input_tokens":0,"output_tokens":0,"cached":0,"input":0,"duration_ms":<DURATION>,"tool_calls":0,"models":{}}}
{"type":"result","timestamp":"<TIMESTAMP>","status":"success","stats":{"total_tokens":0,"input_tokens":0,"output_tokens":0,"cached":0,"input":0,"duration_ms":<DURATION>,"tool_calls":0,"models":{}}}
"
`;
+1 -1
View File
@@ -627,7 +627,7 @@ describe('runNonInteractive', () => {
input: 'Trigger loop',
prompt_id: 'prompt-id-6',
}),
).rejects.toThrow('process.exit(53) called');
).resolves.toBeUndefined();
});
it('should preprocess @include commands before sending to the model', async () => {
+21 -11
View File
@@ -41,7 +41,6 @@ import {
handleError,
handleToolError,
handleCancellationError,
handleMaxTurnsExceededError,
} from './utils/errors.js';
import { TextOutput } from './ui/utils/textOutput.js';
@@ -400,6 +399,14 @@ export async function runNonInteractive({
event.content?.[0]?.type === 'text'
? event.content[0].text
: 'Tool error';
if (event.data?.['errorType'] === ToolErrorType.STOP_EXECUTION) {
const stopMessage = `Agent execution stopped: ${errorMsg}`;
if (config.getOutputFormat() === OutputFormat.TEXT) {
process.stderr.write(`${stopMessage}\n`);
}
}
handleToolError(
event.name,
new Error(errorMsg),
@@ -410,15 +417,6 @@ export async function runNonInteractive({
displayText,
);
}
if (
event.isError &&
event.data?.['errorType'] === ToolErrorType.STOP_EXECUTION
) {
const stopMessage = `Agent execution stopped: ${errorMsg}`;
if (config.getOutputFormat() === OutputFormat.TEXT) {
process.stderr.write(`${stopMessage}\n`);
}
}
break;
}
case 'error': {
@@ -443,7 +441,19 @@ export async function runNonInteractive({
if (event.reason === 'aborted') {
handleCancellationError(config);
} else if (event.reason === 'max_turns') {
handleMaxTurnsExceededError(config);
if (config.getOutputFormat() === OutputFormat.TEXT) {
process.stderr.write(
`[WARNING] Maximum session turns exceeded\n`,
);
}
if (streamFormatter) {
streamFormatter.emitEvent({
type: JsonStreamEventType.ERROR,
timestamp: new Date().toISOString(),
severity: 'error',
message: 'Maximum session turns exceeded',
});
}
}
// Emit final result
if (streamFormatter) {
+2 -2
View File
@@ -191,8 +191,8 @@ export function translateEvent(
out.push(
makeEvent('error', state, {
status: 'INTERNAL',
message: 'Loop detected',
fatal: true,
message: 'Loop detected, stopping execution',
fatal: false,
}),
);
out.push(