Packages
claude_gleam
1.0.0
Gleam SDK for the Anthropic Claude API with agentic tool-use loop and BEAM concurrency
Current section
Files
Jump to
Current section
Files
src/claude@json@encode.erl
-module(claude@json@encode).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/claude/json/encode.gleam").
-export([tool_choice/1, content_block_param/1, message_param/1, create_params/8]).
-if(?OTP_RELEASE >= 27).
-define(MODULEDOC(Str), -moduledoc(Str)).
-define(DOC(Str), -doc(Str)).
-else.
-define(MODULEDOC(Str), -compile([])).
-define(DOC(Str), -compile([])).
-endif.
-file("src/claude/json/encode.gleam", 25).
?DOC(" Encode a Role to its API string representation.\n").
-spec role(claude@types@message:role()) -> gleam@json:json().
role(R) ->
case R of
user ->
gleam@json:string(<<"user"/utf8>>);
assistant ->
gleam@json:string(<<"assistant"/utf8>>)
end.
-file("src/claude/json/encode.gleam", 117).
?DOC(" Encode an image source.\n").
-spec image_source(claude@types@content:image_source()) -> gleam@json:json().
image_source(Src) ->
case Src of
{base64_image, Mt, D} ->
gleam@json:object(
[{<<"type"/utf8>>, gleam@json:string(<<"base64"/utf8>>)},
{<<"media_type"/utf8>>, gleam@json:string(Mt)},
{<<"data"/utf8>>, gleam@json:string(D)}]
);
{url_image, U} ->
gleam@json:object(
[{<<"type"/utf8>>, gleam@json:string(<<"url"/utf8>>)},
{<<"url"/utf8>>, gleam@json:string(U)}]
)
end.
-file("src/claude/json/encode.gleam", 131).
?DOC(" Encode a document source.\n").
-spec document_source(claude@types@content:document_source()) -> gleam@json:json().
document_source(Src) ->
case Src of
{base64_document, Mt, D} ->
gleam@json:object(
[{<<"type"/utf8>>, gleam@json:string(<<"base64"/utf8>>)},
{<<"media_type"/utf8>>, gleam@json:string(Mt)},
{<<"data"/utf8>>, gleam@json:string(D)}]
);
{url_document, U} ->
gleam@json:object(
[{<<"type"/utf8>>, gleam@json:string(<<"url"/utf8>>)},
{<<"url"/utf8>>, gleam@json:string(U)}]
)
end.
-file("src/claude/json/encode.gleam", 145).
?DOC(" Encode a ToolChoice for the API request.\n").
-spec tool_choice(claude@types@tool:tool_choice()) -> gleam@json:json().
tool_choice(Choice) ->
case Choice of
{auto, Dp} ->
gleam@json:object(
[{<<"type"/utf8>>, gleam@json:string(<<"auto"/utf8>>)},
{<<"disable_parallel_tool_use"/utf8>>, gleam@json:bool(Dp)}]
);
{any, Dp@1} ->
gleam@json:object(
[{<<"type"/utf8>>, gleam@json:string(<<"any"/utf8>>)},
{<<"disable_parallel_tool_use"/utf8>>,
gleam@json:bool(Dp@1)}]
);
{specific_tool, N, Dp@2} ->
gleam@json:object(
[{<<"type"/utf8>>, gleam@json:string(<<"tool"/utf8>>)},
{<<"name"/utf8>>, gleam@json:string(N)},
{<<"disable_parallel_tool_use"/utf8>>,
gleam@json:bool(Dp@2)}]
);
no_tools ->
gleam@json:object(
[{<<"type"/utf8>>, gleam@json:string(<<"none"/utf8>>)}]
)
end.
-file("src/claude/json/encode.gleam", 109).
?DOC(" Encode tool result content.\n").
-spec tool_result_content(claude@types@content:tool_result_content()) -> gleam@json:json().
tool_result_content(C) ->
case C of
{string_result, S} ->
gleam@json:string(S);
{blocks_result, Blocks} ->
gleam@json:array(Blocks, fun content_block_param/1)
end.
-file("src/claude/json/encode.gleam", 47).
?DOC(" Encode a ContentBlockParam for the API request.\n").
-spec content_block_param(claude@types@content:content_block_param()) -> gleam@json:json().
content_block_param(Block) ->
case Block of
{text_param, T} ->
gleam@json:object(
[{<<"type"/utf8>>, gleam@json:string(<<"text"/utf8>>)},
{<<"text"/utf8>>, gleam@json:string(T)}]
);
{image_param, Src} ->
gleam@json:object(
[{<<"type"/utf8>>, gleam@json:string(<<"image"/utf8>>)},
{<<"source"/utf8>>, image_source(Src)}]
);
{document_param, Src@1} ->
gleam@json:object(
[{<<"type"/utf8>>, gleam@json:string(<<"document"/utf8>>)},
{<<"source"/utf8>>, document_source(Src@1)}]
);
{tool_use_param, 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>>,
claude_json_ffi:json_string_to_raw(Input)}]
);
{tool_result_param, Id@1, C, Err} ->
Base = [{<<"type"/utf8>>, gleam@json:string(<<"tool_result"/utf8>>)},
{<<"tool_use_id"/utf8>>, gleam@json:string(Id@1)},
{<<"content"/utf8>>, tool_result_content(C)}],
Fields = case Err of
true ->
lists:append(
Base,
[{<<"is_error"/utf8>>, gleam@json:bool(true)}]
);
false ->
Base
end,
gleam@json:object(Fields);
{thinking_param, T@1, S} ->
gleam@json:object(
[{<<"type"/utf8>>, gleam@json:string(<<"thinking"/utf8>>)},
{<<"thinking"/utf8>>, gleam@json:string(T@1)},
{<<"signature"/utf8>>, gleam@json:string(S)}]
);
{redacted_thinking_param, D} ->
gleam@json:object(
[{<<"type"/utf8>>,
gleam@json:string(<<"redacted_thinking"/utf8>>)},
{<<"data"/utf8>>, gleam@json:string(D)}]
);
{server_tool_use_param, Id@2, Name@1, Input@1} ->
gleam@json:object(
[{<<"type"/utf8>>,
gleam@json:string(<<"server_tool_use"/utf8>>)},
{<<"id"/utf8>>, gleam@json:string(Id@2)},
{<<"name"/utf8>>, gleam@json:string(Name@1)},
{<<"input"/utf8>>,
claude_json_ffi:json_string_to_raw(Input@1)}]
)
end.
-file("src/claude/json/encode.gleam", 39).
?DOC(" Encode message content — either a plain string or a list of content blocks.\n").
-spec message_content(claude@types@message:message_content()) -> gleam@json:json().
message_content(C) ->
case C of
{string_content, S} ->
gleam@json:string(S);
{block_content, Blocks} ->
gleam@json:array(Blocks, fun content_block_param/1)
end.
-file("src/claude/json/encode.gleam", 33).
?DOC(" Encode a MessageParam for the API request.\n").
-spec message_param(claude@types@message:message_param()) -> gleam@json:json().
message_param(Msg) ->
{message_param, R, C} = Msg,
gleam@json:object(
[{<<"role"/utf8>>, role(R)}, {<<"content"/utf8>>, message_content(C)}]
).
-file("src/claude/json/encode.gleam", 173).
?DOC(
" Encode the full Messages API request body.\n"
"\n"
" Only includes optional fields when they have values.\n"
" Does not include an empty tools array.\n"
" Includes stream: true only when stream is True.\n"
).
-spec create_params(
binary(),
integer(),
list(claude@types@message:message_param()),
claude@types@tool:registry(),
gleam@option:option(binary()),
gleam@option:option(claude@types@tool:tool_choice()),
gleam@option:option(integer()),
boolean()
) -> gleam@json:json().
create_params(Model, Max_tokens, Messages, Tools, System, Tc, Thinking, Stream) ->
Fields = [{<<"model"/utf8>>, gleam@json:string(Model)},
{<<"max_tokens"/utf8>>, gleam@json:int(Max_tokens)},
{<<"messages"/utf8>>, gleam@json:array(Messages, fun message_param/1)}],
Fields@1 = case claude@types@tool:is_empty(Tools) of
true ->
Fields;
false ->
lists:append(
Fields,
[{<<"tools"/utf8>>, claude@types@tool:to_json(Tools)}]
)
end,
Fields@2 = case System of
{some, S} ->
lists:append(Fields@1, [{<<"system"/utf8>>, gleam@json:string(S)}]);
none ->
Fields@1
end,
Fields@3 = case Tc of
{some, C} ->
lists:append(Fields@2, [{<<"tool_choice"/utf8>>, tool_choice(C)}]);
none ->
Fields@2
end,
Fields@4 = case Thinking of
{some, Budget} ->
lists:append(
Fields@3,
[{<<"thinking"/utf8>>,
gleam@json:object(
[{<<"type"/utf8>>,
gleam@json:string(<<"enabled"/utf8>>)},
{<<"budget_tokens"/utf8>>,
gleam@json:int(Budget)}]
)}]
);
none ->
Fields@3
end,
Fields@5 = case Stream of
true ->
lists:append(Fields@4, [{<<"stream"/utf8>>, gleam@json:bool(true)}]);
false ->
Fields@4
end,
gleam@json:object(Fields@5).