-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.