Skip to content

Add a per-run limit for tool calls #1202

Open

Description

@Yut0Miura

I noticed Go has an iteration limit for the tool loop, but I couldn't find a way to cap the total number of tool calls in a single run.

Those aren't quite the same thing when the model returns several tool calls in one turn. A run can stay within the iteration limit and still make a lot of external calls.

Would be nice to have something similar to Python's max_function_calls on the Go side.

This would be especially useful for tools hitting paid APIs or other external services, where having a simple call budget is a useful safety net.

I don't think it needs to interrupt a batch that's already running - matching the Python behavior and applying the limit between iterations seems reasonable.

Activity

  1. Lokesh118 commented on Oct 24, 2026

    @Lokesh118

    Hi team!

    I'd like to take this up if nobody is currently working on it.

    Proposed Approach:

    1. Config Option: Add a new pointer field in agent/harness/toolautocall/autocall.go under Config:

      // MaximumToolCallsPerRequest (or MaximumFunctionCallsPerRequest) is the maximum
      // number of cumulative tool invocations allowed in a single run.
      // When nil (the default), no call-count limit is enforced.
      MaximumToolCallsPerRequest *int

      (Since providers like openaiprovider, anthropicprovider, etc. accept config.ToolAutoCall *toolautocall.Config, this immediately becomes configurable across all adapters).

    2. Accounting: Track cumulative tool invocations across turns within autocall.run().

    3. Budget Exhaustion Behavior: As suggested in the issue, allow an in-progress batch from the current iteration to finish. Between iterations, if cumulative invocations meet or exceed the limit, strip schema tools for the next round via prepareOptionsForLastIteration(opts) so the model gracefully wraps up with a final text response.

    4. Validation & Unit Tests: In autocall_test.go:

      • Validate negative values (returns configuration error).
      • Behavior when set to 0 vs nil (unlimited).
      • Cap triggered within a multi-call turn (allowing current batch to complete, then wrapping up).
      • Exact limit match vs overshoot across multiple iterations.

    Do you have any preference between MaximumToolCallsPerRequest vs MaximumFunctionCallsPerRequest? If this approach looks good to you, I'll go ahead and submit a PR!

  2. Yut0Miura commented on Oct 26, 2026

    @Yut0Miura
    Author

    Sounds good. I'd go with MaximumFunctionCallsPerRequest to stay consistent with Python's max_function_calls.

    A few things worth covering:

    • nil means unlimited, 0 means no automatic function calls, but the model can still return a final response.
    • Count actual execution attempts, including failures, not just tool calls requested by the model. Provider-handled calls shouldn't count.
    • Include approved tool calls in the count, since they use a separate execution path.

    Letting the current batch finish even if it goes over the limit is fine, as long as no new batch starts afterward.

    The rest of the approach looks good. Go ahead with the PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions