Skip to content

Add stopAfterToolCalls option for OpenAI-compatible workflows#107

Closed
ajason wants to merge 9 commits intomattt:mainfrom
ajason:feature/stop-after-tool-calls
Closed

Add stopAfterToolCalls option for OpenAI-compatible workflows#107
ajason wants to merge 9 commits intomattt:mainfrom
ajason:feature/stop-after-tool-calls

Conversation

@ajason
Copy link
Contributor

@ajason ajason commented Feb 5, 2026

  • Introduce a provider-specific stopAfterToolCalls toggle in OpenAILanguageModel.CustomGenerationOptions.
  • Document the new option and add tests to validate encoding behavior.

Motivation
In production environments, tool execution is often managed by an "external orchestrator" (e.g., dispatching calls to independent workers, invoking internal services, or implementing permission and auditing logic). The current default behavior automatically executes tools immediately after the model generates tool calls. This is unsuitable for systems that require:

  • Permission, auditing, or routing checks prior to execution.
  • Distribution of tool calls to different executors via an external system.
  • Persistence of tool calls for asynchronous execution.

The stopAfterToolCalls flag allows the client to receive the tool calls without triggering automatic execution, handing control over the execution timing to the upper-level orchestrator.

Use Cases / Scenarios

  • Sending tool calls to a queue or workflow system for processing.
  • Implementing security audits (e.g., for sensitive APIs or enterprise resource access).
  • Facilitating multi-agent or multi-service collaboration where execution is coordinated by external logic.
  • Persisting tool calls for retry or playback mechanisms.

Behavior

  • When stopAfterToolCalls == true and the model generates tool calls: the generation process halts, returning the tool calls to the caller without execution.

Testing

  • swift test --filter OpenAICustomOptionsTests

DeepSeek API expects tool message content to be a string, not an array.
Changed from .blocks() to .text() for tool messages in:
- respondWithChatCompletions method
- respondWithResponses method
- toOpenAIMessages method (for transcript injection)
1. 在 OpenAILanguageModel 的配置选项中新增 stopAfterToolCalls 属性
2. 实现生成工具调用后立即停止响应的逻辑,支持直接返回工具调用信息而不触发后续执行
DeepSeek API expects tool message content to be a string, not an array.
Changed from .blocks() to .text() for tool messages.

Also ensures structured tool outputs (JSON) are correctly serialized to JSON strings
instead of using debug descriptions.
@ajason ajason closed this Feb 5, 2026
@mattt mattt mentioned this pull request Feb 5, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant