11import { ToolMessage } from "@langchain/core/messages" ;
2+ import { isGraphInterrupt } from "@langchain/langgraph" ;
23import { createMiddleware } from "langchain" ;
34import { logger , type AdminUser , type IAdminForth } from "adminforth" ;
45import {
@@ -13,6 +14,7 @@ import { ALWAYS_AVAILABLE_API_TOOL_NAMES } from "../tools/index.js";
1314import { createApiTool } from "../tools/apiTool.js" ;
1415import type { AgentEventEmitter } from "../../agentEvents.js" ;
1516import type { SequenceDebugCollector } from "./sequenceDebug.js" ;
17+ import { isAbortError } from "../../errors.js" ;
1618
1719function getEnabledApiToolNames ( messages : unknown [ ] ) {
1820 const enabledToolNames = new Set < string > ( ) ;
@@ -82,9 +84,14 @@ export function createApiBasedToolsMiddleware(
8284 async wrapToolCall ( request , handler ) {
8385 const startedAt = Date . now ( ) ;
8486 const toolInput = JSON . stringify ( request . toolCall . args ?? { } ) ;
85- const toolCallId = request . toolCall . id as string ;
86- const { adminUser, emit, sequenceDebugSink, userTimeZone } = request . runtime . context as {
87+ if ( ! request . toolCall . id ) {
88+ throw new Error ( `Tool call "${ request . toolCall . name } " has no id.` ) ;
89+ }
90+
91+ const toolCallId = request . toolCall . id ;
92+ const { adminUser, abortSignal, emit, sequenceDebugSink, userTimeZone } = request . runtime . context as {
8793 adminUser : AdminUser ;
94+ abortSignal ?: AbortSignal ;
8895 emit ?: AgentEventEmitter ;
8996 sequenceDebugSink : SequenceDebugCollector ;
9097 userTimeZone : string ;
@@ -137,17 +144,25 @@ export function createApiBasedToolsMiddleware(
137144 toolCallTracker . finishSuccess ( result ) ;
138145 return result ;
139146 } catch ( error ) {
147+ if (
148+ isGraphInterrupt ( error )
149+ || abortSignal ?. aborted
150+ || isAbortError ( error )
151+ ) {
152+ throw error ;
153+ }
154+
155+ const message = error instanceof Error ? error . message : String ( error ) ;
156+
140157 logger . error (
141158 `Error calling tool "${ request . toolCall . name } ": ${ error instanceof Error ? error . stack ?? error . message : String ( error ) } ` ,
142159 ) ;
143- toolCallTracker . finishError ( `Error: ${ error instanceof Error ? error . message : String ( error ) } ` ) ;
160+ toolCallTracker . finishError ( `Error: ${ message } ` ) ;
144161 return new ToolMessage ( {
145162 name : request . toolCall . name ,
146163 tool_call_id : toolCallId ,
147164 status : "error" ,
148- content : `Error: ${
149- error instanceof Error ? error . message : String ( error )
150- } `,
165+ content : `Error: ${ message } ` ,
151166 } )
152167 } finally {
153168 logger . info (
0 commit comments