Skip to main content

Choice policies and protocol shapes

Fields require target model and channel support. Chat uses an optional boolean pointer, so explicit false is distinct from omission. Current Chat ↔ Responses conversions map the boolean and selected-function shape. Chat → Claude maps required to any, a selected function to tool, and disabling parallel calls to disable_parallel_tool_use. This does not guarantee every model accepts every combination. parallel_tool_calls controls a model turn, not application scheduling, concurrent HTTP requests, or gateway execution of local functions. Check actual call counts, names, arguments, and IDs. If a single-call request returns several calls, reject before executing any of them. Built-in server tools such as search have separate limits.

Strict mode and conversion

Native Chat function declarations can carry function.strict; native Responses uses sibling strict. Current Chat / Responses function-tool converters in both directions copy name, description, and parameters without copying strict. Native requests, converted requests, and upstream strict defaults are therefore not equivalent. A preserved parameter schema does not prove strict mode took effect. This limitation concerns function declarations, not final-text response_format.json_schema.strict / text.format.strict. Validate business arguments in the application regardless. These fields do not establish OpenRouter’s require_parameters routing preferences, allowed_tools, tool search, or hosted execution as general project capabilities.

A bounded read-only example

The script supports API_TOOL_POLICY=forced|required|auto|none, defaulting to forced. It requests local demonstration stock using that policy and always sends parallel_tool_calls=false. After a valid call, it returns the matching tool_call_id and switches to none for the final answer. At most two model requests and one local read-only calculation; no automatic retry. Missing calls under forced / required fail this example. Auto can answer directly; none rejects any call. All arguments must pass validation before the fixed demonstration lookup runs. There is no dynamic dispatch or real inventory connection. The original assistant message is replayed, without printing private reasoning. Second-turn failures do not repeat the lookup. Production tools that mutate data still need independent permissions, deduplication, and recovery. Output includes the answer and observed tool-call count. Correct use of the stock value needs separate acceptance. Model support is required; HTTP 200 alone does not prove policy enforcement. Source: relaykit/dto/openai_request.go, relaykit/relayconvert/internal/oai_chat/to_oai_responses_req.go, relaykit/relayconvert/internal/oai_responses/to_oai_chat_req.go, and relaykit/relayconvert/internal/shared/claude/tool_choice.go. See tool calling, OpenRouter client tools, and OpenAI function calling.

Runnable example

Run from the documentation directory; keep http-client.mjs when copying. See the REST runtime.
阅读中文