Packages

A well-typed, idiomatic Gleam client for Anthropic's Claude API with streaming support and tool use

Current section

Files

Jump to
anthropic_gleam src anthropic@message.erl
Raw

src/anthropic@message.erl

-module(anthropic@message).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/anthropic/message.gleam").
-export([role_to_json/1, role_from_string/1, role_to_string/1, image_source_to_json/1, image_source_from_dict/1, content_block_type/1, message_text/1, has_tool_use/1, get_tool_uses/1, user_message/1, assistant_message/1, content_block_to_json/1, message_to_json/1, messages_to_json/1, message_to_json_string/1, content_block_to_json_string/1]).
-export_type([role/0, image_source_type/0, image_source/0, content_block/0, message/0]).
-if(?OTP_RELEASE >= 27).
-define(MODULEDOC(Str), -moduledoc(Str)).
-define(DOC(Str), -doc(Str)).
-else.
-define(MODULEDOC(Str), -compile([])).
-define(DOC(Str), -compile([])).
-endif.
?MODULEDOC(
" Core message types for the Anthropic Messages API\n"
"\n"
" This module defines the fundamental types for working with Claude's API,\n"
" including messages, content blocks, and their JSON serialization.\n"
).
-type role() :: user | assistant.
-type image_source_type() :: base64.
-type image_source() :: {image_source, image_source_type(), binary(), binary()}.
-type content_block() :: {text_block, binary()} |
{image_block, image_source()} |
{tool_use_block, binary(), binary(), binary()} |
{tool_result_block, binary(), binary(), boolean()}.
-type message() :: {message, role(), list(content_block())}.
-file("src/anthropic/message.gleam", 25).
?DOC(" Encode a Role to JSON string value\n").
-spec role_to_json(role()) -> gleam@json:json().
role_to_json(Role) ->
case Role of
user ->
gleam@json:string(<<"user"/utf8>>);
assistant ->
gleam@json:string(<<"assistant"/utf8>>)
end.
-file("src/anthropic/message.gleam", 33).
?DOC(" Convert a string to Role\n").
-spec role_from_string(binary()) -> {ok, role()} | {error, binary()}.
role_from_string(Str) ->
case Str of
<<"user"/utf8>> ->
{ok, user};
<<"assistant"/utf8>> ->
{ok, assistant};
_ ->
{error, <<"Invalid role: "/utf8, Str/binary>>}
end.
-file("src/anthropic/message.gleam", 42).
?DOC(" Convert a Role to string\n").
-spec role_to_string(role()) -> binary().
role_to_string(Role) ->
case Role of
user ->
<<"user"/utf8>>;
assistant ->
<<"assistant"/utf8>>
end.
-file("src/anthropic/message.gleam", 72).
?DOC(" Encode an ImageSource to JSON\n").
-spec image_source_to_json(image_source()) -> gleam@json:json().
image_source_to_json(Source) ->
{image_source, _, Media_type, Data} = Source,
gleam@json:object(
[{<<"type"/utf8>>, gleam@json:string(<<"base64"/utf8>>)},
{<<"media_type"/utf8>>, gleam@json:string(Media_type)},
{<<"data"/utf8>>, gleam@json:string(Data)}]
).
-file("src/anthropic/message.gleam", 82).
?DOC(" Create an ImageSource from a dict (for JSON decoding)\n").
-spec image_source_from_dict(gleam@dict:dict(binary(), binary())) -> {ok,
image_source()} |
{error, binary()}.
image_source_from_dict(Dict) ->
gleam@result:'try'(
begin
_pipe = gleam_stdlib:map_get(Dict, <<"media_type"/utf8>>),
gleam@result:replace_error(
_pipe,
<<"Missing media_type field"/utf8>>
)
end,
fun(Media_type) ->
gleam@result:'try'(
begin
_pipe@1 = gleam_stdlib:map_get(Dict, <<"data"/utf8>>),
gleam@result:replace_error(
_pipe@1,
<<"Missing data field"/utf8>>
)
end,
fun(Data) -> {ok, {image_source, base64, Media_type, Data}} end
)
end
).
-file("src/anthropic/message.gleam", 161).
?DOC(" Get the type of a content block as a string\n").
-spec content_block_type(content_block()) -> binary().
content_block_type(Block) ->
case Block of
{text_block, _} ->
<<"text"/utf8>>;
{image_block, _} ->
<<"image"/utf8>>;
{tool_use_block, _, _, _} ->
<<"tool_use"/utf8>>;
{tool_result_block, _, _, _} ->
<<"tool_result"/utf8>>
end.
-file("src/anthropic/message.gleam", 199).
?DOC(" Get the text content from a message (concatenated)\n").
-spec message_text(message()) -> binary().
message_text(Message) ->
_pipe = erlang:element(3, Message),
_pipe@1 = gleam@list:filter_map(_pipe, fun(Block) -> case Block of
{text_block, Text} ->
{ok, Text};
_ ->
{error, nil}
end end),
gleam@string:join(_pipe@1, <<""/utf8>>).
-file("src/anthropic/message.gleam", 211).
?DOC(" Check if a message contains tool use blocks\n").
-spec has_tool_use(message()) -> boolean().
has_tool_use(Message) ->
gleam@list:any(erlang:element(3, Message), fun(Block) -> case Block of
{tool_use_block, _, _, _} ->
true;
_ ->
false
end end).
-file("src/anthropic/message.gleam", 221).
?DOC(" Get all tool use blocks from a message\n").
-spec get_tool_uses(message()) -> list(content_block()).
get_tool_uses(Message) ->
gleam@list:filter(erlang:element(3, Message), fun(Block) -> case Block of
{tool_use_block, _, _, _} ->
true;
_ ->
false
end end).
-file("src/anthropic/message.gleam", 245).
?DOC(
" Create a user message with text content\n"
"\n"
" This is a convenience function for the common case of creating a simple\n"
" text message from the user.\n"
"\n"
" ## Example\n"
"\n"
" ```gleam\n"
" let msg = user_message(\"Hello, Claude!\")\n"
" // Equivalent to: Message(role: User, content: [TextBlock(text: \"Hello, Claude!\")])\n"
" ```\n"
).
-spec user_message(binary()) -> message().
user_message(Text_content) ->
{message, user, [{text_block, Text_content}]}.
-file("src/anthropic/message.gleam", 260).
?DOC(
" Create an assistant message with text content\n"
"\n"
" This is a convenience function for the common case of creating a simple\n"
" text message from the assistant (useful for setting up conversation history).\n"
"\n"
" ## Example\n"
"\n"
" ```gleam\n"
" let msg = assistant_message(\"I'm here to help!\")\n"
" // Equivalent to: Message(role: Assistant, content: [TextBlock(text: \"I'm here to help!\")])\n"
" ```\n"
).
-spec assistant_message(binary()) -> message().
assistant_message(Text_content) ->
{message, assistant, [{text_block, Text_content}]}.
-file("src/anthropic/message.gleam", 270).
?DOC(
" Convert a JSON string to a raw JSON value (for embedding pre-encoded JSON)\n"
" Uses the FFI to parse JSON and convert Erlang terms to Gleam Json\n"
).
-spec json_string_to_raw_json(binary()) -> gleam@json:json().
json_string_to_raw_json(Json_string) ->
anthropic_ffi:json_string_to_gleam_json(Json_string).
-file("src/anthropic/message.gleam", 127).
?DOC(" Encode a ContentBlock to JSON\n").
-spec content_block_to_json(content_block()) -> gleam@json:json().
content_block_to_json(Block) ->
case Block of
{text_block, Text} ->
gleam@json:object(
[{<<"type"/utf8>>, gleam@json:string(<<"text"/utf8>>)},
{<<"text"/utf8>>, gleam@json:string(Text)}]
);
{image_block, Source} ->
gleam@json:object(
[{<<"type"/utf8>>, gleam@json:string(<<"image"/utf8>>)},
{<<"source"/utf8>>, image_source_to_json(Source)}]
);
{tool_use_block, Id, Name, Input} ->
gleam@json:object(
[{<<"type"/utf8>>, gleam@json:string(<<"tool_use"/utf8>>)},
{<<"id"/utf8>>, gleam@json:string(Id)},
{<<"name"/utf8>>, gleam@json:string(Name)},
{<<"input"/utf8>>, json_string_to_raw_json(Input)}]
);
{tool_result_block, Tool_use_id, Content, Is_error} ->
gleam@json:object(
[{<<"type"/utf8>>, gleam@json:string(<<"tool_result"/utf8>>)},
{<<"tool_use_id"/utf8>>, gleam@json:string(Tool_use_id)},
{<<"content"/utf8>>, gleam@json:string(Content)},
{<<"is_error"/utf8>>, gleam@json:bool(Is_error)}]
)
end.
-file("src/anthropic/message.gleam", 185).
?DOC(" Encode a Message to JSON\n").
-spec message_to_json(message()) -> gleam@json:json().
message_to_json(Message) ->
{message, Role, Content} = Message,
gleam@json:object(
[{<<"role"/utf8>>, role_to_json(Role)},
{<<"content"/utf8>>,
gleam@json:array(Content, fun content_block_to_json/1)}]
).
-file("src/anthropic/message.gleam", 194).
?DOC(" Encode a list of Messages to JSON\n").
-spec messages_to_json(list(message())) -> gleam@json:json().
messages_to_json(Messages) ->
gleam@json:array(Messages, fun message_to_json/1).
-file("src/anthropic/message.gleam", 283).
?DOC(" Convert a message to a JSON string\n").
-spec message_to_json_string(message()) -> binary().
message_to_json_string(Message) ->
_pipe = Message,
_pipe@1 = message_to_json(_pipe),
gleam@json:to_string(_pipe@1).
-file("src/anthropic/message.gleam", 290).
?DOC(" Convert a content block to a JSON string\n").
-spec content_block_to_json_string(content_block()) -> binary().
content_block_to_json_string(Block) ->
_pipe = Block,
_pipe@1 = content_block_to_json(_pipe),
gleam@json:to_string(_pipe@1).