Functions
ReplyDelta
Alias of ::ai-chat/ReplyDelta
StreamStop
Alias of ::ai-chat/StreamStop
TextDelta
Alias of ::ai-chat/TextDelta
ToolUseEnd
Alias of ::ai-chat/ToolUseEnd
ToolUseInputDelta
Alias of ::ai-chat/ToolUseInputDelta
ToolUseStart
Alias of ::ai-chat/ToolUseStart
block-text
fn (b: Map): Str
Text from a single content block, or empty string.
block-tool-call
fn (b: Map): ::ai::tool/ToolCall?
Convert a tool_use content block into a ::ai::tool/ToolCall, or null otherwise.
chat-with-tools
fn (model: Str, messages: Vec<::ai::chat/Message>, system: Str?, tools: Vec<::ai::tool/Tool>?): ::ai::chat/ChatReply
Tools-aware chat function compatible with ::ai::chat/run-loop.
Parameters
model— Anthropic model id (e.g."claude-sonnet-4-5").messages— conversation history asVec<::ai::chat/Message>.system— optional system prompt.tools— optionalVec<::ai::tool/Tool>. When non-null, tools are advertised to the model andtool_useresponses becomeChatReply.tool-calls.
Returns a normalized ::ai::chat/ChatReply regardless of the
underlying response shape.
Example
::tool ::ai::tool
add fn (x: Int, y: Int): Int { add(x, y) }
opts ::ai::chat/ChatOptions({
chat-fn: ::anthropic::chat-tools/chat-with-tools,
model: "claude-sonnet-4-5",
tools: [::tool/from-fn(add)]
})
answer ::ai::chat/run-loop(opts, "What is 17 + 25?")
chat-with-tools-stream
fn (model: Str, messages: Vec<::ai::chat/Message>, system: Str?, tools: Vec<::ai::tool/Tool>?, on-delta: Fn): ::ai::chat/ChatReply
Streaming counterpart to chat-with-tools, compatible with
::ai::chat/run-loop-stream. Translates Anthropic SSE events
into provider-agnostic ::ai::chat/ReplyDelta events delivered
via on-delta, and returns a fully-aggregated ChatReply once
the stream terminates.
Parameters
model— Anthropic model id.messages— conversation history asVec<::ai::chat/Message>.system— optional system prompt.tools— optionalVec<::ai::tool/Tool>.on-delta— callback(delta: ReplyDelta): Nullinvoked for every event during streaming. Use::ai::chat/noop-on-deltaif you only care about the finalChatReply.
Example
on-text (delta) {
match delta {
::ai::chat/TextDelta => { print(delta.text) }
=> { null }
}
}
reply chat-with-tools-stream(
"claude-sonnet-4-5",
[::ai-chat/user-message("Hi")],
null,
null,
on-text
)
Then reply.text holds the full assistant text, reply.tool-calls
holds any parsed tool calls (with their input maps reconstructed
from streamed JSON fragments), and reply.usage carries the
provider-reported token totals.
count-tokens
fn (messages: Vec<::ai::chat/Message>, model: Str): Int
Count the input tokens a Vec<::ai::chat/Message> would consume
against model, using Anthropic's stable
/v1/messages/count_tokens endpoint. Returns the exact count
Anthropic would charge.
Compatible with the count-tokens-fn slot on
::ai::chat/ChatOptions:
(messages: Vec<Message>, model: Str): Int
System prompt and tools are not currently included by this helper — pass them via a custom wrapper if you need to model their cost. The caller's pre-call budget check should add the model's reserved overhead separately.
Network calls cost nothing in API credits but they are not free in latency; cache the result when checking budget repeatedly against an unchanged history.
drain-stream
fn (iter: Any, on-delta: Fn, state: Map): Map
Internal: tail-recursively consume iter, accumulating ReplyDelta events into state.
finalize-state
fn (state: Map): ::ai::chat/ChatReply
Internal: convert accumulated stream state into a ChatReply.
Concatenates text blocks in index order, parses the buffered
tool-input JSON for each tool block, and assembles the final
usage map.
handle-content-block-delta
fn (state: Map, idx: Int, delta: Map, on-delta: Fn): Map
Internal: dispatch a content_block_delta SSE event into ReplyDelta + state.
handle-content-block-start
fn (state: Map, idx: Int, block: Map, on-delta: Fn): Map
Internal: dispatch a content_block_start SSE event into ReplyDelta + state.
handle-content-block-stop
fn (state: Map, idx: Int, on-delta: Fn): Map
Internal: dispatch a content_block_stop SSE event into ReplyDelta + state.
handle-event
fn (state: Map, event: Map, on-delta: Fn): Map
Internal: dispatch a single SSE event from Anthropic's
post-stream into the appropriate ReplyDelta emissions and a
new accumulator state.
handle-message-delta
fn (state: Map, data: Map): Map
Internal: capture stop_reason and output token usage from a message_delta event.
handle-message-start
fn (state: Map, data: Map): Map
Internal: capture initial input usage from a message_start event.
ns
Alias of ::anthropic::chat-tools/
Anthropic adapter that satisfies the ::ai::chat/run-loop contract:
chat-with-tools(
model: Str,
messages: Vec<::ai::chat/Message>,
system: Str?,
tools: Vec<::ai::tool/Tool>?
): ::ai::chat/ChatReply
The function translates ::ai::chat/Message records into
Anthropic's content-block shape, calls
::anthropic::messages/post, and normalizes the response into a
::ai::chat/ChatReply so that run-loop does not need to know
about Anthropic's wire format.
response-text
fn (blocks: Vec): Str
Concatenate text content blocks from an Anthropic response.
response-tool-calls
fn (blocks: Vec): Vec<::ai::tool/ToolCall>
Extract ::ai::tool/ToolCall entries from a list of Anthropic content blocks.
response-usage
fn (u: Any): Map?
Normalize Anthropic's usage shape into {input-tokens, output-tokens}.
to-anthropic-message
fn (m: ::ai::chat/Message): Map
Convert a single normalized ::ai::chat/Message into Anthropic's
InputMessage shape. Tool results are emitted as user turns
with a tool_result content block (Anthropic's wire convention).
to-anthropic-tool
fn (t: ::ai::tool/Tool): Map
Convert a ::ai::tool/Tool into Anthropic's Tool shape (rename
input-schema to input_schema, keep name and description).
to-tool-use-block
fn (call: ::ai::tool/ToolCall): Map
Convert a ::ai::tool/ToolCall into an Anthropic tool_use content block.