fix max tool call stack abort flow

This commit is contained in:
Timothy Carambat 2026-02-27 15:57:58 -08:00
parent a6ba5a4034
commit 1eae02e60f

View File

@ -660,27 +660,22 @@ ${this.getHistory({ to: route.to })
if (completionStream.functionCall) { if (completionStream.functionCall) {
if (depth >= this.maxToolCalls) { if (depth >= this.maxToolCalls) {
this.handlerProps?.log?.( this.handlerProps?.log?.(
`[warning]: Maximum tool call limit (${this.maxToolCalls}) reached. Stopping tool execution.` `[warning]: Maximum tool call limit (${this.maxToolCalls}) reached. Making final response without tools.`
); );
this?.introspect?.( this?.introspect?.(
`Maximum tool call limit (${this.maxToolCalls}) reached. Returning what I have so far.` `Maximum tool call limit (${this.maxToolCalls}) reached. Generating a final response from what I have so far.`
); );
const bailoutMessage =
completionStream.textResponse || const finalStream = await provider.stream(messages, [], eventHandler);
const finalResponse =
finalStream?.textResponse ||
"I reached the maximum number of tool calls allowed for a single response. Here is what I have so far based on the tools I was able to run."; "I reached the maximum number of tool calls allowed for a single response. Here is what I have so far based on the tools I was able to run.";
eventHandler?.("reportStreamEvent", { return finalResponse;
type: "fullTextResponse",
uuid: v4(),
content: bailoutMessage,
});
return bailoutMessage;
} }
const { name, arguments: args } = completionStream.functionCall; const { name, arguments: args } = completionStream.functionCall;
const fn = this.functions.get(name); const fn = this.functions.get(name);
// if provider hallucinated on the function name
// ask the provider to complete again
if (!fn) { if (!fn) {
return await this.handleAsyncExecution( return await this.handleAsyncExecution(
provider, provider,
@ -699,17 +694,14 @@ ${this.getHistory({ to: route.to })
); );
} }
// Execute the function and return the result to the provider
fn.caller = byAgent || "agent"; fn.caller = byAgent || "agent";
// If provider is verbose, log the tool call to the frontend
if (provider?.verbose) { if (provider?.verbose) {
this?.introspect?.( this?.introspect?.(
`${fn.caller} is executing \`${name}\` tool ${JSON.stringify(args, null, 2)}` `${fn.caller} is executing \`${name}\` tool ${JSON.stringify(args, null, 2)}`
); );
} }
// Always log the tool call to the console for debugging purposes
this.handlerProps?.log?.( this.handlerProps?.log?.(
`[debug]: ${fn.caller} is attempting to call \`${name}\` tool ${JSON.stringify(args, null, 2)}` `[debug]: ${fn.caller} is attempting to call \`${name}\` tool ${JSON.stringify(args, null, 2)}`
); );
@ -724,7 +716,7 @@ ${this.getHistory({ to: route.to })
* or else no response will be sent to the chat. * or else no response will be sent to the chat.
*/ */
if (this.skipHandleExecution) { if (this.skipHandleExecution) {
this.skipHandleExecution = false; // reset the flag to prevent next tool call from being skipped this.skipHandleExecution = false;
this?.introspect?.( this?.introspect?.(
`The tool call has direct output enabled! The result will be returned directly to the chat without any further processing and no further tool calls will be run.` `The tool call has direct output enabled! The result will be returned directly to the chat without any further processing and no further tool calls will be run.`
); );
@ -784,13 +776,15 @@ ${this.getHistory({ to: route.to })
if (completion.functionCall) { if (completion.functionCall) {
if (depth >= this.maxToolCalls) { if (depth >= this.maxToolCalls) {
this.handlerProps?.log?.( this.handlerProps?.log?.(
`[warning]: Maximum tool call limit (${this.maxToolCalls}) reached. Stopping tool execution.` `[warning]: Maximum tool call limit (${this.maxToolCalls}) reached. Making final response without tools.`
); );
this?.introspect?.( this?.introspect?.(
`Maximum tool call limit (${this.maxToolCalls}) reached. Returning what I have so far.` `Maximum tool call limit (${this.maxToolCalls}) reached. Generating a final response from what I have so far.`
); );
const finalCompletion = await provider.complete(messages, []);
return ( return (
completion.textResponse || finalCompletion?.textResponse ||
"I reached the maximum number of tool calls allowed for a single response. Here is what I have so far based on the tools I was able to run." "I reached the maximum number of tool calls allowed for a single response. Here is what I have so far based on the tools I was able to run."
); );
} }
@ -798,8 +792,6 @@ ${this.getHistory({ to: route.to })
const { name, arguments: args } = completion.functionCall; const { name, arguments: args } = completion.functionCall;
const fn = this.functions.get(name); const fn = this.functions.get(name);
// if provider hallucinated on the function name
// ask the provider to complete again
if (!fn) { if (!fn) {
return await this.handleExecution( return await this.handleExecution(
provider, provider,
@ -818,17 +810,14 @@ ${this.getHistory({ to: route.to })
); );
} }
// Execute the function and return the result to the provider
fn.caller = byAgent || "agent"; fn.caller = byAgent || "agent";
// If provider is verbose, log the tool call to the frontend
if (provider?.verbose) { if (provider?.verbose) {
this?.introspect?.( this?.introspect?.(
`[debug]: ${fn.caller} is attempting to call \`${name}\` tool` `[debug]: ${fn.caller} is attempting to call \`${name}\` tool`
); );
} }
// Always log the tool call to the console for debugging purposes
this.handlerProps?.log?.( this.handlerProps?.log?.(
`[debug]: ${fn.caller} is attempting to call \`${name}\` tool` `[debug]: ${fn.caller} is attempting to call \`${name}\` tool`
); );
@ -836,10 +825,8 @@ ${this.getHistory({ to: route.to })
const result = await fn.handler(args); const result = await fn.handler(args);
Telemetry.sendTelemetry("agent_tool_call", { tool: name }, null, true); Telemetry.sendTelemetry("agent_tool_call", { tool: name }, null, true);
// If the tool call has direct output enabled, return the result directly to the chat
// without any further processing and no further tool calls will be run.
if (this.skipHandleExecution) { if (this.skipHandleExecution) {
this.skipHandleExecution = false; // reset the flag to prevent next tool call from being skipped this.skipHandleExecution = false;
this?.introspect?.( this?.introspect?.(
`The tool call has direct output enabled! The result will be returned directly to the chat without any further processing and no further tool calls will be run.` `The tool call has direct output enabled! The result will be returned directly to the chat without any further processing and no further tool calls will be run.`
); );