Single-turn translation — the translator path (SPEC.md §11, ADR-0011).
Toolnexus.Client.translate/2 is toolnexus used as a pure wire-format translator:
OpenAI shapes in, exactly ONE provider call, OpenAI shapes out. No agent loop, no tool
execution, no conversation state — so a caller can run it statelessly.
It is the INBOUND half of the §5 adapters: to_openai/1/to_anthropic/1/to_gemini/1
send declarations out, this reads the provider's tool calls back in.
Use it when the CALLER owns the conversation and executes tools itself (the standard OpenAI function-calling posture). When toolnexus owns the conversation, use the agent loop with relay tools instead (§10).
This module holds the pure translation functions; the entry point itself lives on
Toolnexus.Client.
Summary
Functions
Parses a tool-call arguments value into a map, tolerating both wire forms — some clients
send arguments as an object rather than a JSON string.
Renders a tool-call arguments value as the JSON string the OpenAI wire format uses.
Flattens an OpenAI content value to text: the string form and the parts-array form.
Non-text parts are ignored.
Maps a provider stop reason onto an OpenAI finish reason. Tool calls win: a turn that
emitted any tool call is always "tool_calls" to a conforming client.
True when the message list already carries a system-ish message.
Converts an OpenAI messages list into Anthropic-native messages plus the extracted
system prompt, preserving the tool structure a text flattening destroys (§11)
Maps OpenAI tool_choice onto Anthropic's shape. Returns nil for absent/"auto" (the
provider default) and for anything unrecognized.
Converts an OpenAI tools list into Anthropic tool declarations. Entries that are
already provider-native pass through; anything unrecognized is skipped.
Renders a result's tool calls as an OpenAI tool_calls array, ready to put on an
assistant message. Convenience for assembling a response envelope.
Reads an assistant message's OpenAI tool_calls.
Functions
Parses a tool-call arguments value into a map, tolerating both wire forms — some clients
send arguments as an object rather than a JSON string.
Renders a tool-call arguments value as the JSON string the OpenAI wire format uses.
Flattens an OpenAI content value to text: the string form and the parts-array form.
Non-text parts are ignored.
Maps a provider stop reason onto an OpenAI finish reason. Tool calls win: a turn that
emitted any tool call is always "tool_calls" to a conforming client.
True when the message list already carries a system-ish message.
Converts an OpenAI messages list into Anthropic-native messages plus the extracted
system prompt, preserving the tool structure a text flattening destroys (§11):
- an assistant turn's
tool_callsbecometool_useblocks, withargumentsparsed back from its JSON string into an object; - a
tool-role result becomes atool_resultblock keyed bytool_call_id, merged into a single user turn when consecutive (providers expect one result-bearing turn answering the preceding assistant turn); system/developermessages are hoisted out, since Anthropic takes system separately.
Returns {messages, system}.
Maps OpenAI tool_choice onto Anthropic's shape. Returns nil for absent/"auto" (the
provider default) and for anything unrecognized.
Converts an OpenAI tools list into Anthropic tool declarations. Entries that are
already provider-native pass through; anything unrecognized is skipped.
@spec tool_calls_json(Toolnexus.Translate.Result.t()) :: [map()]
Renders a result's tool calls as an OpenAI tool_calls array, ready to put on an
assistant message. Convenience for assembling a response envelope.
@spec tool_calls_of(map()) :: [Toolnexus.Translate.ToolCall.t()]
Reads an assistant message's OpenAI tool_calls.