-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, builder_error_to_string/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@tool:property_schema()}), list(binary())}. -type tool_builder_error() :: {invalid_tool_name, anthropic@tool:tool_name_error()} | {duplicate_property, binary()}. -file("src/anthropic/tools/builder.gleam", 55). ?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", 60). ?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", 77). ?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", 247). ?DOC(" Add a custom property schema\n"). -spec add_property( tool_builder(), binary(), anthropic@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", 85). ?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", 105). ?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", 125). ?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", 145). ?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", 165). ?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", 186). ?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", 217). ?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", 263). ?DOC(" Add an object parameter with nested properties\n"). -spec add_object_param( tool_builder(), binary(), binary(), list({binary(), anthropic@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", 292). ?DOC( " Build the tool from the builder state without validation.\n" "\n" " Use this when you trust the tool name is valid (e.g., hardcoded constants).\n" " For untrusted input, use `build_validated()` instead.\n" ). -spec build(tool_builder()) -> anthropic@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, anthropic@tool:tool_name_unchecked(erlang:element(2, Builder)), erlang:element(3, Builder), Input_schema}. -file("src/anthropic/tools/builder.gleam", 317). ?DOC( " Build a simple tool with no parameters without validation.\n" "\n" " Use this when you trust the tool name is valid (e.g., hardcoded constants).\n" " For untrusted input, use `build_validated()` instead.\n" ). -spec build_simple(tool_builder()) -> anthropic@tool:tool(). build_simple(Builder) -> {tool, anthropic@tool:tool_name_unchecked(erlang:element(2, Builder)), erlang:element(3, Builder), {input_schema, <<"object"/utf8>>, none, none}}. -file("src/anthropic/tools/builder.gleam", 342). ?DOC(" Convert a ToolBuilderError to a human-readable string\n"). -spec builder_error_to_string(tool_builder_error()) -> binary(). builder_error_to_string(Error) -> case Error of {invalid_tool_name, Name_error} -> anthropic@tool:tool_name_error_to_string(Name_error); {duplicate_property, Name} -> <<"Duplicate property name: "/utf8, Name/binary>> end. -file("src/anthropic/tools/builder.gleam", 354). ?DOC( " Validate a tool name according to Anthropic's requirements.\n" "\n" " Must match regex: ^[a-zA-Z0-9_-]{1,64}$\n" "\n" " Returns the validated ToolName on success.\n" ). -spec validate_name(binary()) -> {ok, anthropic@tool:tool_name()} | {error, tool_builder_error()}. validate_name(Name) -> _pipe = anthropic@tool:tool_name(Name), gleam@result:map_error( _pipe, fun(Field@0) -> {invalid_tool_name, Field@0} end ). -file("src/anthropic/tools/builder.gleam", 410). -spec has_duplicates(list(binary())) -> boolean(). has_duplicates(Items) -> erlang:length(Items) /= erlang:length(gleam@list:unique(Items)). -file("src/anthropic/tools/builder.gleam", 418). -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", 414). -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", 366). ?DOC( " Build and validate the tool.\n" "\n" " This validates that:\n" " - The tool name matches Anthropic's requirements (alphanumeric, _, -, 1-64 chars)\n" " - No duplicate property names exist\n" "\n" " Use this for user-provided or untrusted tool names.\n" ). -spec build_validated(tool_builder()) -> {ok, anthropic@tool:tool()} | {error, tool_builder_error()}. build_validated(Builder) -> case validate_name(erlang:element(2, Builder)) of {error, Err} -> {error, Err}; {ok, Validated_name} -> 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 -> 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, {ok, {tool, Validated_name, erlang:element(3, Builder), Input_schema}} end end.