fix: report AgentExecutionBlocked in non-interactive programmatic modes (#26262)

This commit is contained in:
Coco Sheng
2026-04-30 16:41:35 -04:00
committed by GitHub
parent a03ec92436
commit 2f0c7518ad
11 changed files with 488 additions and 24 deletions
@@ -378,7 +378,7 @@ describe('translateEvent', () => {
expect(err.type).toBe('error');
expect(err.fatal).toBe(false);
expect(err._meta?.['code']).toBe('AGENT_EXECUTION_BLOCKED');
expect(err.message).toBe('Agent execution blocked: Policy violation');
expect(err.message).toBe('Policy violation');
});
it('uses systemMessage in the final error message when available', () => {
@@ -393,9 +393,7 @@ describe('translateEvent', () => {
};
const result = translateEvent(event, state);
const err = result[0] as AgentEvent<'error'>;
expect(err.message).toBe(
'Agent execution blocked: Blocked by policy hook',
);
expect(err.message).toBe('Blocked by policy hook');
});
});
+1 -1
View File
@@ -210,7 +210,7 @@ export function translateEvent(
out.push(
makeEvent('error', state, {
status: 'PERMISSION_DENIED',
message: `Agent execution blocked: ${event.value.systemMessage?.trim() || event.value.reason}`,
message: event.value.systemMessage?.trim() || event.value.reason,
fatal: false,
_meta: { code: 'AGENT_EXECUTION_BLOCKED' },
}),
@@ -647,7 +647,7 @@ describe('LegacyAgentSession', () => {
e.type === 'error' && e._meta?.['code'] === 'AGENT_EXECUTION_BLOCKED',
);
expect(blocked?.fatal).toBe(false);
expect(blocked?.message).toBe('Agent execution blocked: Blocked by hook');
expect(blocked?.message).toBe('Blocked by hook');
const messages = events.filter(
(e): e is AgentEvent<'message'> =>
@@ -331,4 +331,19 @@ describe('JsonFormatter', () => {
expect(parsed.error.message).toBe('Error\x07 with\x08 control\x0B chars');
expect(() => JSON.parse(formatted)).not.toThrow();
});
it('should format warnings as JSON', () => {
const formatter = new JsonFormatter();
const warnings = ['Warning 1', '\x1B[33mWarning 2 with ANSI\x1B[0m'];
const formatted = formatter.format(
undefined,
undefined,
undefined,
undefined,
warnings,
);
const parsed = JSON.parse(formatted);
expect(parsed.warnings).toEqual(['Warning 1', 'Warning 2 with ANSI']);
});
});
@@ -15,6 +15,7 @@ export class JsonFormatter {
response?: string,
stats?: SessionMetrics,
error?: JsonError,
warnings?: string[],
): string {
const output: JsonOutput = {};
@@ -34,6 +35,10 @@ export class JsonFormatter {
output.error = error;
}
if (warnings && warnings.length > 0) {
output.warnings = warnings.map((w) => stripAnsi(w));
}
return JSON.stringify(output, null, 2);
}
+1
View File
@@ -23,6 +23,7 @@ export interface JsonOutput {
response?: string;
stats?: SessionMetrics;
error?: JsonError;
warnings?: string[];
}
// Streaming JSON event types