Skip to content

Commit 8a6b404

Browse files
committed
Handle case of tool error to add to user message
1 parent 5a697a1 commit 8a6b404

File tree

2 files changed

+27
-3
lines changed

2 files changed

+27
-3
lines changed

packages/agent-runtime/src/__tests__/tool-validation-error.test.ts

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ describe('tool validation error handling', () => {
5959

6060
const responseChunks: (string | PrintModeEvent)[] = []
6161

62-
await processStream({
62+
const result = await processStream({
6363
...agentRuntimeImpl,
6464
agentContext: {},
6565
agentState,
@@ -96,6 +96,9 @@ describe('tool validation error handling', () => {
9696
expect(errorEvents.length).toBe(1)
9797
expect(errorEvents[0].message).toContain('Invalid parameters for spawn_agents')
9898

99+
// Verify hadToolCallError is true so the agent loop continues
100+
expect(result.hadToolCallError).toBe(true)
101+
99102
// Verify NO tool_call event was emitted (since validation failed before that point)
100103
const toolCallEvents = responseChunks.filter(
101104
(chunk): chunk is Extract<PrintModeEvent, { type: 'tool_call' }> =>
@@ -125,6 +128,18 @@ describe('tool validation error handling', () => {
125128
expect(toolMessages.length).toBe(0)
126129
// And no assistant tool calls either
127130
expect(assistantToolCalls.length).toBe(0)
131+
132+
// Verify error message was added to message history for the LLM to see
133+
const userMessages = agentState.messageHistory.filter(
134+
(m) => m.role === 'user',
135+
)
136+
const errorUserMessage = userMessages.find((m) => {
137+
const contentStr = Array.isArray(m.content)
138+
? m.content.map((p) => ('text' in p ? p.text : '')).join('')
139+
: typeof m.content === 'string' ? m.content : ''
140+
return contentStr.includes('Error during tool call') && contentStr.includes('Invalid parameters for spawn_agents')
141+
})
142+
expect(errorUserMessage).toBeDefined()
128143
})
129144

130145
it('should still emit tool_call and tool_result for valid tool calls', async () => {

packages/agent-runtime/src/tools/stream-parser.ts

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,8 @@ export async function processStream(
9090
const toolResultsToAddAfterStream: ToolMessage[] = []
9191
const toolCalls: (CodebuffToolCall | CustomToolCall)[] = []
9292
const assistantMessages: Message[] = []
93+
let hadToolCallError = false
94+
const errorMessages: Message[] = []
9395
const { promise: streamDonePromise, resolve: resolveStreamDonePromise } =
9496
Promise.withResolvers<void>()
9597
let previousToolCallFinished = streamDonePromise
@@ -120,6 +122,15 @@ export async function processStream(
120122
content: chunk.output,
121123
}
122124
assistantMessages.push(toolResultMessage)
125+
} else if (chunk.type === 'error') {
126+
hadToolCallError = true
127+
errorMessages.push(
128+
userMessage(
129+
withSystemTags(
130+
`Error during tool call: ${chunk.message}. Please check the tool name and arguments and try again.`,
131+
),
132+
),
133+
)
123134
}
124135
}
125136
return onResponseChunk(chunk)
@@ -267,8 +278,6 @@ export async function processStream(
267278

268279
// === STREAM CONSUMPTION LOOP ===
269280
let messageId: string | null = null
270-
let hadToolCallError = false
271-
const errorMessages: Message[] = []
272281

273282
while (true) {
274283
if (signal.aborted) {

0 commit comments

Comments
 (0)