-module(anthropic@api). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]). -define(FILEPATH, "src/anthropic/api.gleam"). -export([create_message/2]). -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( " API functions for Anthropic Messages API\n" "\n" " This module provides the core functions for interacting with Claude's\n" " Messages API, including message creation and response parsing.\n" ). -file("src/anthropic/api.gleam", 69). ?DOC(" Validate a CreateMessageRequest before sending\n"). -spec validate_request(anthropic@types@request:create_message_request()) -> {ok, nil} | {error, anthropic@types@error:anthropic_error()}. validate_request(Request) -> _pipe = case gleam@list:is_empty(erlang:element(3, Request)) of true -> {error, anthropic@types@error:invalid_request_error( <<"messages list cannot be empty"/utf8>> )}; false -> {ok, nil} end, _pipe@1 = gleam@result:'try'( _pipe, fun(_) -> case gleam@string:is_empty( gleam@string:trim(erlang:element(2, Request)) ) of true -> {error, anthropic@types@error:invalid_request_error( <<"model name cannot be empty"/utf8>> )}; false -> {ok, nil} end end ), gleam@result:'try'(_pipe@1, fun(_) -> case erlang:element(4, Request) > 0 of true -> {ok, nil}; false -> {error, anthropic@types@error:invalid_request_error( <<"max_tokens must be greater than 0"/utf8>> )} end end). -file("src/anthropic/api.gleam", 125). ?DOC(" Convert decode errors to a string\n"). -spec decode_errors_to_string(list(gleam@dynamic@decode:decode_error())) -> binary(). decode_errors_to_string(Errors) -> _pipe = Errors, _pipe@1 = gleam@list:map( _pipe, fun(E) -> <<<<<<"expected "/utf8, (erlang:element(2, E))/binary>>/binary, ", got "/utf8>>/binary, (erlang:element(3, E))/binary>> end ), gleam@string:join(_pipe@1, <<"; "/utf8>>). -file("src/anthropic/api.gleam", 184). ?DOC(" Decoder for text blocks\n"). -spec text_block_decoder() -> gleam@dynamic@decode:decoder(anthropic@types@message:content_block()). text_block_decoder() -> gleam@dynamic@decode:field( <<"text"/utf8>>, {decoder, fun gleam@dynamic@decode:decode_string/1}, fun(Text) -> gleam@dynamic@decode:success({text_block, Text}) end ). -file("src/anthropic/api.gleam", 209). ?DOC(" Convert a dynamic value to a JSON string using Erlang's built-in json module\n"). -spec dynamic_to_json_string(gleam@dynamic:dynamic_()) -> binary(). dynamic_to_json_string(Value) -> Iodata = json:encode(Value), erlang:iolist_to_binary(Iodata). -file("src/anthropic/api.gleam", 200). ?DOC(" Decoder for tool input (converts dynamic to JSON string)\n"). -spec input_decoder() -> gleam@dynamic@decode:decoder(binary()). input_decoder() -> gleam@dynamic@decode:new_primitive_decoder( <<"Object"/utf8>>, fun(Data) -> Json_str = dynamic_to_json_string(Data), {ok, Json_str} end ). -file("src/anthropic/api.gleam", 190). ?DOC(" Decoder for tool use blocks\n"). -spec tool_use_block_decoder() -> gleam@dynamic@decode:decoder(anthropic@types@message:content_block()). tool_use_block_decoder() -> gleam@dynamic@decode:field( <<"id"/utf8>>, {decoder, fun gleam@dynamic@decode:decode_string/1}, fun(Id) -> gleam@dynamic@decode:field( <<"name"/utf8>>, {decoder, fun gleam@dynamic@decode:decode_string/1}, fun(Name) -> gleam@dynamic@decode:field( <<"input"/utf8>>, input_decoder(), fun(Input) -> gleam@dynamic@decode:success( {tool_use_block, Id, Name, Input} ) end ) end ) end ). -file("src/anthropic/api.gleam", 169). ?DOC(" Decoder for ContentBlock\n"). -spec content_block_decoder() -> gleam@dynamic@decode:decoder(anthropic@types@message:content_block()). content_block_decoder() -> gleam@dynamic@decode:field( <<"type"/utf8>>, {decoder, fun gleam@dynamic@decode:decode_string/1}, fun(Block_type) -> case Block_type of <<"text"/utf8>> -> text_block_decoder(); <<"tool_use"/utf8>> -> tool_use_block_decoder(); _ -> gleam@dynamic@decode:success( {text_block, <<<<"[Unknown content type: "/utf8, Block_type/binary>>/binary, "]"/utf8>>} ) end end ). -file("src/anthropic/api.gleam", 224). ?DOC(" Decoder for Usage\n"). -spec usage_decoder() -> gleam@dynamic@decode:decoder(anthropic@types@request:usage()). usage_decoder() -> gleam@dynamic@decode:field( <<"input_tokens"/utf8>>, {decoder, fun gleam@dynamic@decode:decode_int/1}, fun(Input_tokens) -> gleam@dynamic@decode:field( <<"output_tokens"/utf8>>, {decoder, fun gleam@dynamic@decode:decode_int/1}, fun(Output_tokens) -> gleam@dynamic@decode:success( {usage, Input_tokens, Output_tokens} ) end ) end ). -file("src/anthropic/api.gleam", 235). ?DOC(" Parse a role string\n"). -spec parse_role(binary()) -> anthropic@types@message:role(). parse_role(Str) -> case Str of <<"user"/utf8>> -> user; <<"assistant"/utf8>> -> assistant; _ -> assistant end. -file("src/anthropic/api.gleam", 244). ?DOC(" Parse a stop reason string\n"). -spec parse_stop_reason(binary()) -> gleam@option:option(anthropic@types@request:stop_reason()). parse_stop_reason(Str) -> case Str of <<"end_turn"/utf8>> -> {some, end_turn}; <<"max_tokens"/utf8>> -> {some, max_tokens}; <<"stop_sequence"/utf8>> -> {some, stop_sequence}; <<"tool_use"/utf8>> -> {some, tool_use}; _ -> none end. -file("src/anthropic/api.gleam", 132). ?DOC(" Decoder for CreateMessageResponse\n"). -spec response_decoder() -> gleam@dynamic@decode:decoder(anthropic@types@request:create_message_response()). response_decoder() -> gleam@dynamic@decode:field( <<"id"/utf8>>, {decoder, fun gleam@dynamic@decode:decode_string/1}, fun(Id) -> gleam@dynamic@decode:field( <<"type"/utf8>>, {decoder, fun gleam@dynamic@decode:decode_string/1}, fun(Response_type) -> gleam@dynamic@decode:field( <<"role"/utf8>>, {decoder, fun gleam@dynamic@decode:decode_string/1}, fun(Role_str) -> gleam@dynamic@decode:field( <<"content"/utf8>>, gleam@dynamic@decode:list( content_block_decoder() ), fun(Content) -> gleam@dynamic@decode:field( <<"model"/utf8>>, {decoder, fun gleam@dynamic@decode:decode_string/1}, fun(Model) -> gleam@dynamic@decode:field( <<"usage"/utf8>>, usage_decoder(), fun(Usage) -> gleam@dynamic@decode:field( <<"stop_reason"/utf8>>, begin _pipe = gleam@dynamic@decode:optional( {decoder, fun gleam@dynamic@decode:decode_string/1} ), gleam@dynamic@decode:map( _pipe, fun(Opt) -> case Opt of {some, S} -> parse_stop_reason( S ); none -> none end end ) end, fun(Stop_reason) -> gleam@dynamic@decode:field( <<"stop_sequence"/utf8>>, gleam@dynamic@decode:optional( {decoder, fun gleam@dynamic@decode:decode_string/1} ), fun( Stop_sequence ) -> Role = parse_role( Role_str ), gleam@dynamic@decode:success( {create_message_response, Id, Response_type, Role, Content, Model, Stop_reason, Stop_sequence, Usage} ) end ) end ) end ) end ) end ) end ) end ) end ). -file("src/anthropic/api.gleam", 111). ?DOC(" Decode a dynamic value into CreateMessageResponse\n"). -spec decode_response(gleam@dynamic:dynamic_()) -> {ok, anthropic@types@request:create_message_response()} | {error, anthropic@types@error:anthropic_error()}. decode_response(Value) -> Decoder = response_decoder(), case gleam@dynamic@decode:run(Value, Decoder) of {ok, Response} -> {ok, Response}; {error, Errors} -> {error, anthropic@types@error:json_error( <<"Failed to decode response: "/utf8, (decode_errors_to_string(Errors))/binary>> )} end. -file("src/anthropic/api.gleam", 99). ?DOC(" Parse a response body into CreateMessageResponse\n"). -spec parse_response(binary()) -> {ok, anthropic@types@request:create_message_response()} | {error, anthropic@types@error:anthropic_error()}. parse_response(Body) -> case gleam_json_ffi:decode(Body) of {ok, Dyn} -> decode_response(Dyn); {error, _} -> {error, anthropic@types@error:json_error( <<"Failed to parse response JSON"/utf8>> )} end. -file("src/anthropic/api.gleam", 43). ?DOC( " Create a message using the Anthropic Messages API\n" "\n" " This function sends a request to Claude and returns the response.\n" "\n" " ## Example\n" "\n" " ```gleam\n" " let request = create_request(\n" " \"claude-sonnet-4-20250514\",\n" " [user_message(\"Hello, Claude!\")],\n" " 1024,\n" " )\n" " case create_message(client, request) {\n" " Ok(response) -> io.println(response_text(response))\n" " Error(err) -> io.println(error_to_string(err))\n" " }\n" " ```\n" ). -spec create_message( anthropic@client:client(), anthropic@types@request:create_message_request() ) -> {ok, anthropic@types@request:create_message_response()} | {error, anthropic@types@error:anthropic_error()}. create_message(Client, Request) -> gleam@result:'try'( validate_request(Request), fun(_) -> Body = anthropic@types@request:request_to_json_string(Request), gleam@result:'try'( anthropic@client:post_and_handle( Client, <<"/v1/messages"/utf8>>, Body ), fun(Response_body) -> parse_response(Response_body) end ) end ).