llm_wire/message

The values a conversation is made of: messages, assistant turns, tool calls, streamed progress and token usage, with JSON codecs for storing them.

The caller owns the conversation. Build the next request from the messages you keep, appending each assistant turn and its tool results:

import llm_wire
import llm_wire/message

case llm_wire.run(client, prepared) {
  Ok(llm_wire.NeedsTools(turn:, ..)) -> {
    let results =
      list.map(turn.calls, fn(call) { llm_wire.tool_result(call, "42") })
    [message.Assistant(turn), ..results]
  }
  _ -> []
}

to_json and decoder store a message; turn_to_json and turn_decoder store an assistant turn with its provider data, which a later request must replay unchanged. A store that keeps a turn’s text and calls apart from the rest uses turn_replay_to_json and turn_replay_decoder for the provider-owned part; it is the format Fabric stores as llm_wire.turn.v1.

Records here are returned by the library; read their fields by label. Message, Content and Progress may gain variants in a minor release, so match them with a _ arm.

Types

One assistant response. provider is None for a turn the application wrote itself. provider_data is opaque replay data that a later request to the same provider must carry unchanged, such as Gemini’s signed parts.

pub type AssistantTurn {
  AssistantTurn(
    provider: option.Option(Provider),
    text: String,
    calls: List(ToolCall),
    response_id: option.Option(String),
    provider_data: option.Option(String),
  )
}

Constructors

One part of a multimodal message.

pub type Content {
  TextPart(text: String)
  ImageUrlPart(url: String)
  InlineImagePart(mime_type: String, base64_data: String)
}

Constructors

  • TextPart(text: String)
  • ImageUrlPart(url: String)

    A remote image. OpenAI admits it; Anthropic and Google refuse it during preparation.

  • InlineImagePart(mime_type: String, base64_data: String)

One message of a conversation.

pub type Message {
  System(text: String)
  User(text: String)
  UserParts(parts: List(Content))
  Assistant(turn: AssistantTurn)
  AssistantParts(parts: List(Content))
  ToolResult(call_id: String, content: String)
}

Constructors

  • System(text: String)
  • User(text: String)
  • UserParts(parts: List(Content))

    A user message made of several parts, such as text and an image.

  • Assistant(turn: AssistantTurn)

    An assistant turn: a provider response, or text and calls the application wrote.

  • AssistantParts(parts: List(Content))

    An application-written assistant message made of several parts.

  • ToolResult(call_id: String, content: String)

    The result of the call with call_id. Results follow the assistant turn that made the calls, one per call.

One piece of a streamed response.

pub type Progress {
  TextDelta(block_id: String, text: String)
  RefusalDelta(block_id: String, text: String)
  ReasoningDelta(block_id: String, text: String)
  ToolArgumentsDelta(call_id: String, text: String)
  UsageUpdate(usage: Usage)
  ProviderExtension(provider: String, event_name: String)
}

Constructors

  • TextDelta(block_id: String, text: String)
  • RefusalDelta(block_id: String, text: String)
  • ReasoningDelta(block_id: String, text: String)
  • ToolArgumentsDelta(call_id: String, text: String)

    Argument text of a tool call still being generated.

  • UsageUpdate(usage: Usage)
  • ProviderExtension(provider: String, event_name: String)

    A provider event LLM Wire does not interpret, by name.

The provider a turn came from, or a custom adapter’s name.

pub type Provider {
  OpenAI
  Anthropic
  Google
  Custom(name: String)
}

Constructors

  • OpenAI
  • Anthropic
  • Google
  • Custom(name: String)

A tool call the model made. arguments_json is the argument text exactly as the model produced it. provider_id and provider_state carry provider replay data, such as Gemini’s call id and thought signature.

pub type ToolCall {
  ToolCall(
    id: String,
    name: String,
    arguments_json: String,
    provider_id: option.Option(String),
    provider_state: option.Option(String),
  )
}

Constructors

  • ToolCall(
      id: String,
      name: String,
      arguments_json: String,
      provider_id: option.Option(String),
      provider_state: option.Option(String),
    )

Token counts a provider reported.

pub type Usage {
  Usage(input_tokens: Int, output_tokens: Int, total_tokens: Int)
}

Constructors

  • Usage(input_tokens: Int, output_tokens: Int, total_tokens: Int)

Values

pub fn decoder() -> decode.Decoder(Message)

Decode a message written by to_json. A value with a different format tag fails; a value without one is read as version 1.

pub fn provider_name(provider: Provider) -> String

A provider’s stable name: "openai", "anthropic", "google", or the custom adapter’s name.

pub fn to_json(message: Message) -> json.Json

Encode a message as JSON tagged "format": "llm_wire.message.v1".

pub fn tool_call(
  id: String,
  name: String,
  arguments_json: String,
) -> ToolCall

A tool call without provider replay data, for application-written turns.

pub fn turn_decoder() -> decode.Decoder(AssistantTurn)

Decode a turn written by turn_to_json.

pub fn turn_replay_decoder(
  text: String,
  calls: List(ToolCall),
) -> decode.Decoder(AssistantTurn)

Decode the data turn_replay_to_json wrote and complete the turn with the text and calls the caller stored. It also reads Fabric’s earlier llm_wire.turn.v1 data, whose issues list it ignores.

pub fn turn_replay_to_json(turn: AssistantTurn) -> json.Json

Encode only the provider-owned part of a turn: provider, response_id and provider_data. The caller stores the turn’s text and calls itself. This is exactly the data Fabric stores under the llm_wire.turn.v1 tag, without its former issues list.

pub fn turn_to_json(turn: AssistantTurn) -> json.Json

Encode an assistant turn, provider data included, tagged "format": "llm_wire.turn.v1". Its fields are those of turn_replay_to_json plus text and calls.

✨ Search Document