Skip to content

Commit 1ed08d8

Browse files
authored
fix(providers): remove default agent tool-call iteration cap (#8829)
* fix(providers): remove default agent tool-call iteration cap * docs(providers): note no execution timeout when billing is disabled
1 parent 900afc3 commit 1ed08d8

12 files changed

Lines changed: 25 additions & 30 deletions

File tree

‎apps/docs/content/docs/platform/self-hosting/environment-variables.mdx‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ import { Callout } from 'fumadocs-ui/components/callout'
6969
</Callout>
7070

7171
<Callout type="info">
72-
**Agent tool-call depth.** An Agent block ends its run after 20 model round trips of tool calling. Raise the ceiling with `MAX_TOOL_ITERATIONS` (for example `MAX_TOOL_ITERATIONS=50`). Every extra iteration is another model call, so raise it deliberately.
72+
**Agent tool-call depth.** An Agent block keeps calling tools until the model answers, with no round-trip limit by default. With billing disabled there is also no execution timeout unless `EXECUTION_TIMEOUT_FREE` (sync) or `EXECUTION_TIMEOUT_ASYNC_FREE` (async) is set, so a looping agent keeps making paid model calls. Set `MAX_TOOL_ITERATIONS` (for example `MAX_TOOL_ITERATIONS=50`) to cap the model round trips per block, or set those timeouts to bound the whole run.
7373
</Callout>
7474

7575
### Catalog visibility

‎apps/sim/.env.example‎

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -244,9 +244,10 @@ CRON_SECRET=your_cron_secret # Use `openssl rand -hex 32` to generate. Authentic
244244
# TABLE_DISPATCH_CONCURRENCY_PAID=50 # Rows one table run executes in parallel on paid tiers (billing disabled uses this)
245245
# FREE_STORAGE_LIMIT_GB=5 # File storage quota in GB
246246

247-
# Agent tool-call loop (Optional). Model round trips one Agent block takes before it
248-
# must answer. Defaults to 20; raise it for agents that chain many tool calls.
249-
# MAX_TOOL_ITERATIONS=20
247+
# Agent tool-call loop (Optional). Caps the model round trips one Agent block takes
248+
# before it must answer. Unbounded when unset. With billing disabled, runs also have no
249+
# execution timeout unless EXECUTION_TIMEOUT_FREE / EXECUTION_TIMEOUT_ASYNC_FREE are set.
250+
# MAX_TOOL_ITERATIONS=50
250251

251252
# Mistral OCR capacity (regular KBs, Sim Search and Mistral tools share these limits)
252253
# Use operating ceilings below the organization's actual quota, allowing for other clients.

‎apps/sim/executor/handlers/pi/search/normalize.ts‎

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,10 +37,9 @@ export const PI_SEARCH_TRUNCATED_MESSAGE =
3737
* Searches one Pi block execution may make. Pi's agent loop has no turn ceiling of its own, so
3838
* without this a model that starts looping — or is talked into it by an injected instruction in a
3939
* diff or a result — keeps spending the workspace's own provider quota until Sim's execution
40-
* timeout. The neighbouring ceilings are the precedent: `MAX_TOOL_CALLS` in `cloud-review-tools.ts`
41-
* and `MAX_TOOL_ITERATIONS` in `providers/index.ts`. Sized well above what genuine research needs,
42-
* since exceeding it fails the tool call. Stated as a number in the Pi block docs
43-
* (`workflows/blocks/pi.mdx`), so change both.
40+
* timeout. The neighbouring ceiling is the precedent: `MAX_TOOL_CALLS` in `cloud-review-tools.ts`.
41+
* Sized well above what genuine research needs, since exceeding it fails the tool call. Stated as a
42+
* number in the Pi block docs (`workflows/blocks/pi.mdx`), so change both.
4443
*
4544
* Scope is one **block execution**, not one workflow run: the counter lives in the tool spec, and
4645
* both adapters build a fresh spec per execution (`buildPiSearchToolSpec` from `pi-handler.ts`, and

‎apps/sim/lib/core/config/env.ts‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -424,7 +424,7 @@ export const env = createEnv({
424424
EXECUTION_TIMEOUT_ASYNC_ENTERPRISE: z.string().optional().default('5400'), // 90 minutes
425425

426426
// Agent Tool-Call Loop
427-
MAX_TOOL_ITERATIONS: z.string().optional(), // Max model round trips per Agent block tool-call loop (default 20)
427+
MAX_TOOL_ITERATIONS: z.string().optional(), // Max model round trips per Agent block tool-call loop (unbounded when unset)
428428

429429
// Isolated-VM Worker Pool Configuration
430430
IVM_POOL_SIZE: z.string().optional().default('4'), // Max worker processes in pool

‎apps/sim/providers/azure-openai/index.ts‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -338,7 +338,7 @@ async function executeChatCompletionsRequest(
338338
}
339339

340340
logger.info(
341-
`Processing ${toolCallsInResponse.length} tool calls (iteration ${iterationCount + 1}/${MAX_TOOL_ITERATIONS})`
341+
`Processing ${toolCallsInResponse.length} tool calls (iteration ${iterationCount + 1})`
342342
)
343343

344344
const toolsStartTime = Date.now()

‎apps/sim/providers/index.ts‎

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -131,18 +131,14 @@ async function prepareProviderFileAttachments(request: ProviderRequest): Promise
131131
}
132132
}
133133

134-
/** Round trips an Agent block's tool loop takes before it is forced to answer. */
135-
const DEFAULT_MAX_TOOL_ITERATIONS = 20
136-
137134
/**
138-
* Maximum number of iterations for tool call loops to prevent infinite loops.
139-
* Used across all providers that support tool/function calling.
140-
*
141-
* Self-hosted deployments that need longer agent runs raise it with the
142-
* `MAX_TOOL_ITERATIONS` env var; a value that is not a positive integer falls
143-
* back to {@link DEFAULT_MAX_TOOL_ITERATIONS}.
135+
* Maximum model round trips in an Agent block's tool-call loop. Unbounded by
136+
* default: the loop runs until the model stops calling tools, bounded only by
137+
* the execution timeout (none when billing is disabled and no timeout env var is
138+
* set) and usage limits. Set the `MAX_TOOL_ITERATIONS` env var to a positive
139+
* integer to impose a ceiling; any other value leaves it unbounded.
144140
*/
145-
export const MAX_TOOL_ITERATIONS = envNumber(env.MAX_TOOL_ITERATIONS, DEFAULT_MAX_TOOL_ITERATIONS, {
141+
export const MAX_TOOL_ITERATIONS = envNumber(env.MAX_TOOL_ITERATIONS, Number.POSITIVE_INFINITY, {
146142
min: 1,
147143
integer: true,
148144
})

‎apps/sim/providers/litellm/index.ts‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -371,7 +371,7 @@ export const litellmProvider: ProviderConfig = {
371371
}
372372

373373
logger.info(
374-
`Processing ${toolCallsInResponse.length} tool calls (iteration ${iterationCount + 1}/${MAX_TOOL_ITERATIONS})`
374+
`Processing ${toolCallsInResponse.length} tool calls (iteration ${iterationCount + 1})`
375375
)
376376

377377
const toolsStartTime = Date.now()

‎apps/sim/providers/mistral/index.ts‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -290,7 +290,7 @@ export const mistralProvider: ProviderConfig = {
290290
}
291291

292292
logger.info(
293-
`Processing ${toolCallsInResponse.length} tool calls (iteration ${iterationCount + 1}/${MAX_TOOL_ITERATIONS})`
293+
`Processing ${toolCallsInResponse.length} tool calls (iteration ${iterationCount + 1})`
294294
)
295295

296296
const toolsStartTime = Date.now()

‎apps/sim/providers/ollama/core.ts‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -297,7 +297,7 @@ export async function executeOllamaProviderRequest(
297297
}
298298

299299
logger.info(
300-
`Processing ${toolCallsInResponse.length} tool calls (iteration ${iterationCount + 1}/${MAX_TOOL_ITERATIONS})`
300+
`Processing ${toolCallsInResponse.length} tool calls (iteration ${iterationCount + 1})`
301301
)
302302

303303
const toolsStartTime = Date.now()

‎apps/sim/providers/openai/core.ts‎

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -729,9 +729,7 @@ export async function executeResponsesProviderRequest(
729729
}
730730

731731
logger.info(
732-
`Processing ${toolCallsInResponse.length} tool calls in parallel (iteration ${
733-
iterationCount + 1
734-
}/${MAX_TOOL_ITERATIONS})`
732+
`Processing ${toolCallsInResponse.length} tool calls in parallel (iteration ${iterationCount + 1})`
735733
)
736734

737735
const toolsStartTime = Date.now()

0 commit comments

Comments
 (0)