Light Dark

Functions

ReplyDelta alias

Alias of ::ai-chat/ReplyDelta

StreamStop alias

Alias of ::ai-chat/StreamStop

TextDelta alias

Alias of ::ai-chat/TextDelta

ToolUseEnd alias

Alias of ::ai-chat/ToolUseEnd

ToolUseInputDelta alias

Alias of ::ai-chat/ToolUseInputDelta

ToolUseStart alias

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 as Vec<::ai::chat/Message>.
  • system — optional system prompt.
  • tools — optional Vec<::ai::tool/Tool>. When non-null, tools are advertised to the model and tool_use responses become ChatReply.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 as Vec<::ai::chat/Message>.
  • system — optional system prompt.
  • tools — optional Vec<::ai::tool/Tool>.
  • on-delta — callback (delta: ReplyDelta): Null invoked for every event during streaming. Use ::ai::chat/noop-on-delta if you only care about the final ChatReply.

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

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.