Normandy.Tools.Examples.EnhancedCalculator behaviour
(normandy v0.6.2)
View Source
Schema-based calculator tool demonstrating the new SchemaBaseTool approach.
This is an enhanced version of the Calculator tool that uses Normandy schemas for input definition, providing automatic validation and better error messages.
Comparison with Original Calculator
Original Approach (manual schema definition):
- Manually define struct fields
- Manually write JSON schema in
input_schema/1 - No automatic validation
- Duplication between struct and schema
Schema-Based Approach (this module):
- Define schema once with
tool_schema - Automatic JSON schema generation
- Built-in validation with detailed errors
- Type coercion and default values
- Format validation support
Examples
# Create and validate
iex> {:ok, calc} = EnhancedCalculator.validate(%{operation: "add", a: 5, b: 3})
iex> EnhancedCalculator.execute(calc)
{:ok, 8}
# Validation catches errors
iex> EnhancedCalculator.validate(%{operation: "invalid", a: 5, b: 3})
{:error, [%{path: [:operation], constraint: :enum, ...}]}
# Automatic through BaseTool protocol
iex> tool = %EnhancedCalculator{operation: "multiply", a: 4, b: 7}
iex> Normandy.Tools.BaseTool.run(tool)
{:ok, 28}
Summary
Callbacks
Executes the tool with validated inputs.
Callbacks
Executes the tool with validated inputs.
This function must be implemented by the tool. It receives a validated struct with all fields populated according to the schema.
Returns {:ok, result} on success or {:error, reason} on failure.
Examples
@impl Normandy.Tools.SchemaBaseTool
def execute(%__MODULE__{operation: "add", a: a, b: b}) do
{:ok, a + b}
end
def execute(%__MODULE__{operation: "divide", a: _a, b: 0}) do
{:error, "Division by zero"}
end
Functions
Validates input parameters against the tool's schema.
Returns {:ok, struct} on success or {:error, errors} on validation failure.
Examples
iex> Elixir.Normandy.Tools.Examples.EnhancedCalculator.validate(%{operation: "add", a: 5, b: 3})
{:ok, %Elixir.Normandy.Tools.Examples.EnhancedCalculator{operation: "add", a: 5, b: 3}}
iex> Elixir.Normandy.Tools.Examples.EnhancedCalculator.validate(%{operation: "invalid"})
{:error, [%{path: [:a], message: "is required", constraint: :required}]}
Validates and raises on error.
Returns the validated struct or raises Normandy.Schema.ValidationError.