Packages
A well-typed, idiomatic Gleam client for Anthropic's Claude API with streaming support and tool use
Current section
Files
Jump to
Current section
Files
src/anthropic@tools@builder.erl
-module(anthropic@tools@builder).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/anthropic/tools/builder.gleam").
-export([tool_builder/1, tool_builder_with_description/2, with_description/2, add_property/4, add_string_param/4, add_number_param/4, add_integer_param/4, add_boolean_param/4, add_enum_param/5, add_string_array_param/5, add_number_array_param/4, add_object_param/6, build/1, build_simple/1, validate_name/1, build_validated/1]).
-export_type([tool_builder/0, tool_builder_error/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(
" Fluent builder for tool definitions\n"
"\n"
" This module provides an ergonomic builder API for creating tool definitions.\n"
" The builder pattern allows for type-safe, readable tool construction.\n"
"\n"
" ## Example\n"
"\n"
" ```gleam\n"
" let weather_tool =\n"
" tool_builder(\"get_weather\")\n"
" |> with_description(\"Get the current weather for a location\")\n"
" |> add_string_param(\"location\", \"City and state, e.g. 'San Francisco, CA'\", True)\n"
" |> add_enum_param(\"unit\", \"Temperature unit\", [\"celsius\", \"fahrenheit\"], False)\n"
" |> build()\n"
"\n"
" // For tools with no parameters\n"
" let time_tool =\n"
" tool_builder(\"get_time\")\n"
" |> with_description(\"Get the current time\")\n"
" |> build_simple()\n"
" ```\n"
).
-type tool_builder() :: {tool_builder,
binary(),
gleam@option:option(binary()),
list({binary(), anthropic@types@tool:property_schema()}),
list(binary())}.
-type tool_builder_error() :: empty_name |
{invalid_name_characters, binary()} |
{name_too_long, binary(), integer()} |
{duplicate_property, binary()}.
-file("src/anthropic/tools/builder.gleam", 52).
?DOC(" Start building a new tool with the given name\n").
-spec tool_builder(binary()) -> tool_builder().
tool_builder(Name) ->
{tool_builder, Name, none, [], []}.
-file("src/anthropic/tools/builder.gleam", 57).
?DOC(" Start building a new tool with name and description\n").
-spec tool_builder_with_description(binary(), binary()) -> tool_builder().
tool_builder_with_description(Name, Description) ->
{tool_builder, Name, {some, Description}, [], []}.
-file("src/anthropic/tools/builder.gleam", 74).
?DOC(" Set the description for the tool\n").
-spec with_description(tool_builder(), binary()) -> tool_builder().
with_description(Builder, Description) ->
{tool_builder,
erlang:element(2, Builder),
{some, Description},
erlang:element(4, Builder),
erlang:element(5, Builder)}.
-file("src/anthropic/tools/builder.gleam", 244).
?DOC(" Add a custom property schema\n").
-spec add_property(
tool_builder(),
binary(),
anthropic@types@tool:property_schema(),
boolean()
) -> tool_builder().
add_property(Builder, Name, Property, Is_required) ->
New_properties = lists:append(
erlang:element(4, Builder),
[{Name, Property}]
),
New_required = case Is_required of
true ->
lists:append(erlang:element(5, Builder), [Name]);
false ->
erlang:element(5, Builder)
end,
{tool_builder,
erlang:element(2, Builder),
erlang:element(3, Builder),
New_properties,
New_required}.
-file("src/anthropic/tools/builder.gleam", 82).
?DOC(" Add a string parameter\n").
-spec add_string_param(tool_builder(), binary(), binary(), boolean()) -> tool_builder().
add_string_param(Builder, Name, Description, Is_required) ->
Prop = {property_schema,
<<"string"/utf8>>,
{some, Description},
none,
none,
none,
none},
add_property(Builder, Name, Prop, Is_required).
-file("src/anthropic/tools/builder.gleam", 102).
?DOC(" Add a number parameter\n").
-spec add_number_param(tool_builder(), binary(), binary(), boolean()) -> tool_builder().
add_number_param(Builder, Name, Description, Is_required) ->
Prop = {property_schema,
<<"number"/utf8>>,
{some, Description},
none,
none,
none,
none},
add_property(Builder, Name, Prop, Is_required).
-file("src/anthropic/tools/builder.gleam", 122).
?DOC(" Add an integer parameter\n").
-spec add_integer_param(tool_builder(), binary(), binary(), boolean()) -> tool_builder().
add_integer_param(Builder, Name, Description, Is_required) ->
Prop = {property_schema,
<<"integer"/utf8>>,
{some, Description},
none,
none,
none,
none},
add_property(Builder, Name, Prop, Is_required).
-file("src/anthropic/tools/builder.gleam", 142).
?DOC(" Add a boolean parameter\n").
-spec add_boolean_param(tool_builder(), binary(), binary(), boolean()) -> tool_builder().
add_boolean_param(Builder, Name, Description, Is_required) ->
Prop = {property_schema,
<<"boolean"/utf8>>,
{some, Description},
none,
none,
none,
none},
add_property(Builder, Name, Prop, Is_required).
-file("src/anthropic/tools/builder.gleam", 162).
?DOC(" Add an enum parameter (string with allowed values)\n").
-spec add_enum_param(
tool_builder(),
binary(),
binary(),
list(binary()),
boolean()
) -> tool_builder().
add_enum_param(Builder, Name, Description, Values, Is_required) ->
Prop = {property_schema,
<<"string"/utf8>>,
{some, Description},
{some, Values},
none,
none,
none},
add_property(Builder, Name, Prop, Is_required).
-file("src/anthropic/tools/builder.gleam", 183).
?DOC(" Add an array parameter with string items\n").
-spec add_string_array_param(
tool_builder(),
binary(),
binary(),
binary(),
boolean()
) -> tool_builder().
add_string_array_param(
Builder,
Name,
Description,
Item_description,
Is_required
) ->
Item_schema = {property_schema,
<<"string"/utf8>>,
{some, Item_description},
none,
none,
none,
none},
Prop = {property_schema,
<<"array"/utf8>>,
{some, Description},
none,
{some, Item_schema},
none,
none},
add_property(Builder, Name, Prop, Is_required).
-file("src/anthropic/tools/builder.gleam", 214).
?DOC(" Add an array parameter with number items\n").
-spec add_number_array_param(tool_builder(), binary(), binary(), boolean()) -> tool_builder().
add_number_array_param(Builder, Name, Description, Is_required) ->
Item_schema = {property_schema,
<<"number"/utf8>>,
none,
none,
none,
none,
none},
Prop = {property_schema,
<<"array"/utf8>>,
{some, Description},
none,
{some, Item_schema},
none,
none},
add_property(Builder, Name, Prop, Is_required).
-file("src/anthropic/tools/builder.gleam", 260).
?DOC(" Add an object parameter with nested properties\n").
-spec add_object_param(
tool_builder(),
binary(),
binary(),
list({binary(), anthropic@types@tool:property_schema()}),
list(binary()),
boolean()
) -> tool_builder().
add_object_param(
Builder,
Name,
Description,
Nested_properties,
Nested_required,
Is_required
) ->
Prop = {property_schema,
<<"object"/utf8>>,
{some, Description},
none,
none,
{some, Nested_properties},
{some, Nested_required}},
add_property(Builder, Name, Prop, Is_required).
-file("src/anthropic/tools/builder.gleam", 286).
?DOC(" Build the tool from the builder state\n").
-spec build(tool_builder()) -> anthropic@types@tool:tool().
build(Builder) ->
Input_schema = case erlang:element(4, Builder) of
[] ->
{input_schema, <<"object"/utf8>>, none, none};
Props ->
{input_schema,
<<"object"/utf8>>,
{some, Props},
case erlang:element(5, Builder) of
[] ->
none;
Reqs ->
{some, Reqs}
end}
end,
{tool, erlang:element(2, Builder), erlang:element(3, Builder), Input_schema}.
-file("src/anthropic/tools/builder.gleam", 308).
?DOC(" Build a simple tool with no parameters\n").
-spec build_simple(tool_builder()) -> anthropic@types@tool:tool().
build_simple(Builder) ->
{tool,
erlang:element(2, Builder),
erlang:element(3, Builder),
{input_schema, <<"object"/utf8>>, none, none}}.
-file("src/anthropic/tools/builder.gleam", 385).
-spec is_alphanumeric(binary()) -> boolean().
is_alphanumeric(Char) ->
Lower = (((((((((((((((((((((((((Char =:= <<"a"/utf8>>) orelse (Char =:= <<"b"/utf8>>))
orelse (Char =:= <<"c"/utf8>>))
orelse (Char =:= <<"d"/utf8>>))
orelse (Char =:= <<"e"/utf8>>))
orelse (Char =:= <<"f"/utf8>>))
orelse (Char =:= <<"g"/utf8>>))
orelse (Char =:= <<"h"/utf8>>))
orelse (Char =:= <<"i"/utf8>>))
orelse (Char =:= <<"j"/utf8>>))
orelse (Char =:= <<"k"/utf8>>))
orelse (Char =:= <<"l"/utf8>>))
orelse (Char =:= <<"m"/utf8>>))
orelse (Char =:= <<"n"/utf8>>))
orelse (Char =:= <<"o"/utf8>>))
orelse (Char =:= <<"p"/utf8>>))
orelse (Char =:= <<"q"/utf8>>))
orelse (Char =:= <<"r"/utf8>>))
orelse (Char =:= <<"s"/utf8>>))
orelse (Char =:= <<"t"/utf8>>))
orelse (Char =:= <<"u"/utf8>>))
orelse (Char =:= <<"v"/utf8>>))
orelse (Char =:= <<"w"/utf8>>))
orelse (Char =:= <<"x"/utf8>>))
orelse (Char =:= <<"y"/utf8>>))
orelse (Char =:= <<"z"/utf8>>),
Upper = (((((((((((((((((((((((((Char =:= <<"A"/utf8>>) orelse (Char =:= <<"B"/utf8>>))
orelse (Char =:= <<"C"/utf8>>))
orelse (Char =:= <<"D"/utf8>>))
orelse (Char =:= <<"E"/utf8>>))
orelse (Char =:= <<"F"/utf8>>))
orelse (Char =:= <<"G"/utf8>>))
orelse (Char =:= <<"H"/utf8>>))
orelse (Char =:= <<"I"/utf8>>))
orelse (Char =:= <<"J"/utf8>>))
orelse (Char =:= <<"K"/utf8>>))
orelse (Char =:= <<"L"/utf8>>))
orelse (Char =:= <<"M"/utf8>>))
orelse (Char =:= <<"N"/utf8>>))
orelse (Char =:= <<"O"/utf8>>))
orelse (Char =:= <<"P"/utf8>>))
orelse (Char =:= <<"Q"/utf8>>))
orelse (Char =:= <<"R"/utf8>>))
orelse (Char =:= <<"S"/utf8>>))
orelse (Char =:= <<"T"/utf8>>))
orelse (Char =:= <<"U"/utf8>>))
orelse (Char =:= <<"V"/utf8>>))
orelse (Char =:= <<"W"/utf8>>))
orelse (Char =:= <<"X"/utf8>>))
orelse (Char =:= <<"Y"/utf8>>))
orelse (Char =:= <<"Z"/utf8>>),
Digit = (((((((((Char =:= <<"0"/utf8>>) orelse (Char =:= <<"1"/utf8>>))
orelse (Char =:= <<"2"/utf8>>))
orelse (Char =:= <<"3"/utf8>>))
orelse (Char =:= <<"4"/utf8>>))
orelse (Char =:= <<"5"/utf8>>))
orelse (Char =:= <<"6"/utf8>>))
orelse (Char =:= <<"7"/utf8>>))
orelse (Char =:= <<"8"/utf8>>))
orelse (Char =:= <<"9"/utf8>>),
(Lower orelse Upper) orelse Digit.
-file("src/anthropic/tools/builder.gleam", 457).
-spec has_duplicates(list(binary())) -> boolean().
has_duplicates(Items) ->
erlang:length(Items) /= erlang:length(gleam@list:unique(Items)).
-file("src/anthropic/tools/builder.gleam", 465).
-spec find_first_duplicate_helper(list(binary()), list(binary())) -> gleam@option:option(binary()).
find_first_duplicate_helper(Remaining, Seen) ->
case Remaining of
[] ->
none;
[First | Rest] ->
case gleam@list:contains(Seen, First) of
true ->
{some, First};
false ->
find_first_duplicate_helper(Rest, [First | Seen])
end
end.
-file("src/anthropic/tools/builder.gleam", 461).
-spec find_first_duplicate(list(binary())) -> gleam@option:option(binary()).
find_first_duplicate(Items) ->
find_first_duplicate_helper(Items, []).
-file("src/anthropic/tools/builder.gleam", 482).
-spec string_length(binary()) -> integer().
string_length(S) ->
string:length(S).
-file("src/anthropic/tools/builder.gleam", 486).
-spec string_to_graphemes(binary()) -> list(binary()).
string_to_graphemes(S) ->
gleam@string:to_graphemes(S).
-file("src/anthropic/tools/builder.gleam", 379).
?DOC(" Check if a string only contains valid tool name characters\n").
-spec is_valid_tool_name(binary()) -> boolean().
is_valid_tool_name(Name) ->
_pipe = Name,
_pipe@1 = string_to_graphemes(_pipe),
gleam@list:all(
_pipe@1,
fun(Char) ->
(is_alphanumeric(Char) orelse (Char =:= <<"_"/utf8>>)) orelse (Char
=:= <<"-"/utf8>>)
end
).
-file("src/anthropic/tools/builder.gleam", 338).
?DOC(
" Validate a tool name according to Anthropic's requirements\n"
" Must match regex: ^[a-zA-Z0-9_-]{1,64}$\n"
).
-spec validate_name(binary()) -> {ok, binary()} | {error, tool_builder_error()}.
validate_name(Name) ->
case Name of
<<""/utf8>> ->
{error, empty_name};
_ ->
Length = string_length(Name),
case Length > 64 of
true ->
{error, {name_too_long, Name, Length}};
false ->
case is_valid_tool_name(Name) of
true ->
{ok, Name};
false ->
{error, {invalid_name_characters, Name}}
end
end
end.
-file("src/anthropic/tools/builder.gleam", 357).
?DOC(" Build and validate the tool\n").
-spec build_validated(tool_builder()) -> {ok, anthropic@types@tool:tool()} |
{error, tool_builder_error()}.
build_validated(Builder) ->
case validate_name(erlang:element(2, Builder)) of
{error, Err} ->
{error, Err};
{ok, _} ->
Prop_names = gleam@list:map(
erlang:element(4, Builder),
fun(P) -> erlang:element(1, P) end
),
case has_duplicates(Prop_names) of
true ->
Dup = find_first_duplicate(Prop_names),
{error,
{duplicate_property,
gleam@option:unwrap(Dup, <<""/utf8>>)}};
false ->
{ok, build(Builder)}
end
end.