///|
/// Generated types that the facade uses in its own signatures, re-exported so
/// callers can name them as `@anthropic.X`. Everything else generated from the
/// spec is reachable through `gaato/anthropic/gen`.
pub using @gen {
type StopReason,
type Usage,
type ModelInfo,
type ListResponseModelInfo,
type InputContentBlock,
type ToolChoice,
type ThinkingConfigParam,
type OutputConfig,
type Metadata,
type MessageDelta,
type MessageDeltaUsage,
type CreateMessageParams,
type MessageStreamEvent,
}
///|
/// Selects the credential header used by the API.
pub(all) enum AuthHeader {
XApiKey
Bearer
} derive(Eq, Debug)
///|
/// Compares authentication-header choices.
pub extend AuthHeader with Eq::{equal, not_equal}
///|
/// Debug representation of an authentication-header choice.
pub extend AuthHeader with @debug.Debug::{to_repr}
///|
/// The error body returned by the Anthropic API.
///
/// ```mbt check
/// test {
/// let error : @anthropic.ApiErrorBody = {
/// type_: "invalid_request_error",
/// message: "invalid request",
/// }
/// assert_eq(error.message, "invalid request")
/// }
/// ```
pub(all) struct ApiErrorBody {
type_ : String
message : String
} derive(Eq, Debug)
///|
/// Compares API error bodies field by field.
pub extend ApiErrorBody with Eq::{equal, not_equal}
///|
/// Debug representation of an API error body.
pub extend ApiErrorBody with @debug.Debug::{to_repr}
///|
/// A participant in a Messages API conversation.
pub(all) enum Role {
User
Assistant
} derive(Eq, Debug)
///|
/// Compares message roles.
pub extend Role with Eq::{equal, not_equal}
///|
/// Debug representation of a message role.
pub extend Role with @debug.Debug::{to_repr}
///|
/// Input content as plain text or typed content blocks. A block the generated
/// vocabulary does not know is carried losslessly as `@gen.InputContentBlock::Unknown`.
pub(all) enum InputContent {
Text(String)
Blocks(Array[InputContentBlock])
} derive(Eq, Debug)
///|
/// Compares input content, including typed blocks.
pub extend InputContent with Eq::{equal, not_equal}
///|
/// Debug representation of input content.
pub extend InputContent with @debug.Debug::{to_repr}
///|
/// A client tool definition for the Messages API.
///
/// ```mbt check
/// test {
/// let tool = @anthropic.ToolDef::new(name="lookup", input_schema={
/// "type": "object",
/// })
/// assert_eq(tool.name, "lookup")
/// }
/// ```
pub(all) struct ToolDef {
name : String
description : String?
input_schema : Json
strict : Bool?
} derive(Eq, Debug)
///|
/// Compares tool definitions field by field.
pub extend ToolDef with Eq::{equal, not_equal}
///|
/// Debug representation of a tool definition.
pub extend ToolDef with @debug.Debug::{to_repr}
///|
/// Creates a client tool definition with a JSON Schema input object.
pub fn ToolDef::new(
name~ : String,
input_schema~ : Json,
description? : String,
strict? : Bool,
) -> ToolDef {
{ name, description, input_schema, strict, }
}
///|
/// One user or assistant turn sent to the Messages API.
pub(all) struct Message {
role : Role
content : InputContent
} derive(Eq, Debug)
///|
/// Compares messages field by field.
pub extend Message with Eq::{equal, not_equal}
///|
/// Debug representation of a message.
pub extend Message with @debug.Debug::{to_repr}
///|
/// Creates a user message containing plain text.
///
/// ```mbt check
/// test {
/// assert_eq(@anthropic.Message::user("hello"), {
/// role: @anthropic.User,
/// content: @anthropic.Text("hello"),
/// })
/// }
/// ```
pub fn Message::user(text : String) -> Message {
{ role: User, content: Text(text), }
}
///|
/// Creates an assistant message containing plain text.
///
/// ```mbt check
/// test {
/// assert_eq(@anthropic.Message::assistant("hello"), {
/// role: @anthropic.Assistant,
/// content: @anthropic.Text("hello"),
/// })
/// }
/// ```
pub fn Message::assistant(text : String) -> Message {
{ role: Assistant, content: Text(text), }
}
///|
/// Creates a user message from typed content blocks (images, documents, tool results, ...).
pub fn Message::user_blocks(blocks : Array[InputContentBlock]) -> Message {
{ role: User, content: Blocks(blocks.copy()), }
}
///|
/// Creates an assistant message from typed content blocks.
pub fn Message::assistant_blocks(blocks : Array[InputContentBlock]) -> Message {
{ role: Assistant, content: Blocks(blocks.copy()), }
}
///|
/// Creates a user message containing one tool result block.
///
/// ```mbt check
/// test {
/// let message = @anthropic.Message::tool_result(
/// tool_use_id="toolu_1",
/// content="done",
/// )
/// assert_eq(message.role, @anthropic.User)
/// }
/// ```
pub fn Message::tool_result(
tool_use_id~ : String,
content~ : String,
is_error? : Bool,
) -> Message {
{
role: User,
content: Blocks([
@gen.InputContentBlock::ToolResult(
@gen.RequestToolResultBlock::new(
tool_use_id~,
type_="tool_result",
content=@gen.RequestToolResultBlockContent::Text(content),
is_error?,
),
),
]),
}
}
///|
/// Turns a response into the assistant turn to send back, block for block:
/// text, thinking (with its signature), tool use and every other block the
/// API returned are replayed as input blocks. A block the request vocabulary
/// cannot represent is passed through as raw JSON.
pub fn Message::from_response(response : MessageResponse) -> Message {
let blocks = response.message.content.map(block => {
let json = block.to_json()
let converted : InputContentBlock = @json.from_json(json) catch {
_ => {
let kind = match json {
Object(fields) =>
match fields.get("type") {
Some(String(kind)) => kind
_ => ""
}
_ => ""
}
@gen.InputContentBlock::Unknown(kind, json)
}
}
converted
})
{ role: Assistant, content: Blocks(blocks), }
}
///|
/// Input accepted by buffered and streaming message creation and by token counting.
///
/// The typed fields cover the common surface; `extra` is merged into the JSON
/// body after the typed fields and validated against the generated schema, so
/// any other documented parameter (`top_p`, `service_tier`, ...) can be passed
/// without a facade change. For full control build a `@gen.CreateMessageParams`
/// and use `Anthropic::create_message_params`.
pub(all) struct MessageRequest {
model : String
max_tokens : Int
messages : Array[Message]
system : String?
temperature : Double?
stop_sequences : Array[String]?
tools : Array[ToolDef]?
tool_choice : ToolChoice?
thinking : ThinkingConfigParam?
output_config : OutputConfig?
metadata : Metadata?
extra : Map[String, Json]
} derive(Eq, Debug)
///|
/// Compares message requests field by field.
pub extend MessageRequest with Eq::{equal, not_equal}
///|
/// Debug representation of a message request.
pub extend MessageRequest with @debug.Debug::{to_repr}
///|
/// Creates a message request and snapshots its mutable inputs.
///
/// ```mbt check
/// test {
/// let request = @anthropic.MessageRequest::new(
/// model="claude-opus-5",
/// max_tokens=64,
/// messages=[@anthropic.Message::user("hello")],
/// )
/// assert_eq(request.messages.length(), 1)
/// }
/// ```
pub fn MessageRequest::new(
model~ : String,
max_tokens~ : Int,
messages~ : Array[Message],
system? : String,
temperature? : Double,
stop_sequences? : Array[String],
tools? : Array[ToolDef],
tool_choice? : ToolChoice,
thinking? : ThinkingConfigParam,
output_config? : OutputConfig,
metadata? : Metadata,
extra? : Map[String, Json],
) -> MessageRequest {
{
model,
max_tokens,
messages: messages.map(copy_message),
system,
temperature,
stop_sequences: stop_sequences.map(Array::copy),
tools: tools.map(Array::copy),
tool_choice,
thinking,
output_config,
metadata,
extra: extra.map(Map::copy).unwrap_or({}),
}
}
///|
fn copy_message(message : Message) -> Message {
match message.content {
Text(text) => { ..message, content: Text(text), }
Blocks(blocks) => { ..message, content: Blocks(blocks.copy()), }
}
}
///|
/// One output content block. Blocks beyond text, thinking and tool use keep
/// their JSON; the typed form is on `MessageResponse::message`.
pub(all) enum ContentBlock {
Text(String)
Thinking(thinking~ : String, signature~ : String)
RedactedThinking(String)
ToolUse(id~ : String, name~ : String, input~ : Json)
Other(String, Json)
} derive(Eq, Debug)
///|
/// Compares output content blocks.
pub extend ContentBlock with Eq::{equal, not_equal}
///|
/// Debug representation of an output content block.
pub extend ContentBlock with @debug.Debug::{to_repr}
///|
/// A decoded message: the facade view (`content`), the generated view
/// (`message`) and the original JSON (`raw`).
pub(all) struct MessageResponse {
id : String
model : String
role : Role
content : Array[ContentBlock]
stop_reason : StopReason?
usage : Usage
message : @gen.Message
raw : Json
} derive(Eq, Debug)
///|
/// Compares decoded messages field by field.
pub extend MessageResponse with Eq::{equal, not_equal}
///|
/// Debug representation of a decoded message.
pub extend MessageResponse with @debug.Debug::{to_repr}
///|
/// Concatenates text blocks in response order and ignores other block kinds.
pub fn MessageResponse::text(self : MessageResponse) -> String {
let result = StringBuilder()
for block in self.content {
if block is Text(text) {
result.write_string(text)
}
}
result.to_string()
}
///|
/// The tool uses requested by the response, in content order.
pub fn MessageResponse::tool_uses(
self : MessageResponse,
) -> Array[(String, String, Json)] {
let result = []
for block in self.content {
if block is ToolUse(id~, name~, input~) {
result.push((id, name, input))
}
}
result
}
///|
/// One event from a streaming message. Event and delta kinds outside the
/// generated vocabulary retain their raw JSON.
pub(all) enum MessageEvent {
MessageStart(MessageResponse)
ContentBlockStart(index~ : Int, block~ : ContentBlock)
TextDelta(index~ : Int, text~ : String)
ThinkingDelta(index~ : Int, thinking~ : String)
SignatureDelta(index~ : Int, signature~ : String)
InputJsonDelta(index~ : Int, partial_json~ : String)
ContentBlockStop(index~ : Int)
MessageDelta(delta~ : MessageDelta, usage~ : MessageDeltaUsage)
MessageStop
Ping
Error(ApiErrorBody)
Other(String, Json)
} derive(Eq, Debug)
///|
/// Compares message events, including retained unknown JSON.
pub extend MessageEvent with Eq::{equal, not_equal}
///|
/// Debug representation of a message event.
pub extend MessageEvent with @debug.Debug::{to_repr}