Skip to content

Commit ddc5164

Browse files
committed
Fix tool call
1 parent bd6a103 commit ddc5164

File tree

1 file changed

+37
-3
lines changed
  • apps/sim/lib/copilot/orchestrator/sse-handlers

1 file changed

+37
-3
lines changed

apps/sim/lib/copilot/orchestrator/sse-handlers/handlers.ts

Lines changed: 37 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -289,6 +289,23 @@ export const sseHandlers: Record<string, SSEHandler> = {
289289
markToolResultSeen(toolCall.id)
290290
return
291291
}
292+
293+
// Decision was null — timed out or aborted.
294+
// Do NOT fall through to auto-execute. Mark the tool as timed out
295+
// and notify Go so it can unblock waitForExternalTool.
296+
toolCall.status = 'rejected'
297+
toolCall.endTime = Date.now()
298+
markToolComplete(toolCall.id, toolCall.name, 408, 'Tool approval timed out', {
299+
skipped: true,
300+
reason: 'timeout',
301+
}).catch((err) => {
302+
logger.error('markToolComplete fire-and-forget failed (timeout)', {
303+
toolCallId: toolCall.id,
304+
error: err instanceof Error ? err.message : String(err),
305+
})
306+
})
307+
markToolResultSeen(toolCall.id)
308+
return
292309
}
293310

294311
if (options.autoExecuteTools !== false) {
@@ -431,9 +448,10 @@ export const subAgentHandlers: Record<string, SSEHandler> = {
431448
return
432449
}
433450

434-
// Integration tools (user-installed) require approval in interactive mode,
435-
// same as top-level interrupt tools.
436-
if (options.interactive === true && isIntegrationTool(toolName)) {
451+
// Interrupt tools and integration tools (user-installed) require approval
452+
// in interactive mode, same as top-level handler.
453+
const needsSubagentApproval = isInterruptToolName(toolName) || isIntegrationTool(toolName)
454+
if (options.interactive === true && needsSubagentApproval) {
437455
const decision = await waitForToolDecision(
438456
toolCallId,
439457
options.timeout || STREAM_TIMEOUT_MS,
@@ -481,6 +499,22 @@ export const subAgentHandlers: Record<string, SSEHandler> = {
481499
markToolResultSeen(toolCall.id)
482500
return
483501
}
502+
503+
// Decision was null — timed out or aborted.
504+
// Do NOT fall through to auto-execute.
505+
toolCall.status = 'rejected'
506+
toolCall.endTime = Date.now()
507+
markToolComplete(toolCall.id, toolCall.name, 408, 'Tool approval timed out', {
508+
skipped: true,
509+
reason: 'timeout',
510+
}).catch((err) => {
511+
logger.error('markToolComplete fire-and-forget failed (subagent timeout)', {
512+
toolCallId: toolCall.id,
513+
error: err instanceof Error ? err.message : String(err),
514+
})
515+
})
516+
markToolResultSeen(toolCall.id)
517+
return
484518
}
485519

486520
// Client-executable run tools in interactive mode: defer to client.

0 commit comments

Comments
 (0)