Opt-in argument DSL for tools with straightforward object input schemas.
Snodo.Tool.Simple builds the same raw JSON Schema returned by Snodo.Tool and
leaves call/2 untouched. Argument maps therefore retain protocol-native
string keys, and simple tools register in Snodo.Router exactly like raw tools.
defmodule Search do
use Snodo.Tool.Simple,
name: "search",
description: "Search packages",
additional_properties: false
argument("query", :string, required: true, min_length: 1)
argument("page", :integer, minimum: 1)
argument("sort", :string, enum: ["name", "downloads"])
argument("tags", {:array, :string}, unique_items: true)
@impl true
def call(%{"query" => query} = arguments, _context) do
{:ok, Snodo.Result.text("searching for #{query} on page #{arguments["page"] || 1}")}
end
endAn argument type may be one of the JSON primitive atoms, {:array, type}, or
a raw property-schema map. The :schema option merges arbitrary JSON Schema
keywords into a generated property, providing a local escape hatch without
abandoning the concise form. The raw Snodo.Tool DSL remains available when
the input root itself needs complete hand-authored control.
An :object or {:array, :object} argument may take a do block of
further argument declarations, which become the properties of that object
or of each array item. output_schema/1 with a do block builds the output
schema from the same declarations:
defmodule Order do
use Snodo.Tool.Simple, name: "order", description: "Place an order"
argument "customer", :object, required: true do
argument "id", :string, required: true
argument "email", :string
end
argument "lines", {:array, :object}, required: true, min_items: 1 do
argument "sku", :string, required: true
argument "quantity", :integer, required: true, minimum: 1
end
output_schema do
argument "order_id", :string, required: true
argument "total", :number, required: true
end
@impl true
def call(_arguments, _context) do
{:ok, Snodo.Result.structured(%{"order_id" => "o-1", "total" => 12.5})}
end
endBoth compile to plain JSON Schema maps, the same ones Snodo.Tool.input_schema/1
and Snodo.Tool.output_schema/1 accept.
The :title, :icons, and :metadata options set the corresponding
Snodo.Tool definition fields. They are validated when the module compiles.
Summary
Functions
Declares one property of the tool's input schema.
Sets the tool's output schema, either from a JSON Schema map or from a
do block of argument declarations.
Functions
Declares one property of the tool's input schema.
name is the property name as a string. type is a JSON type atom
(:string, :integer, :number, :boolean, :array, :object, or
:null), {:array, type} for an array whose "items" has that type, or a
raw property-schema map.
Options:
:required- whentrue, addsnameto the schema's"required"list. Defaults tofalse.:description,:default,:enum,:pattern- set the JSON Schema keyword of the same name.:min_length,:max_length,:min_items,:max_items,:minimum,:maximum,:exclusive_minimum,:exclusive_maximum,:unique_items- set the camel-case JSON Schema keyword, such as"minLength".:schema- a map of other JSON Schema keywords, merged into the property last, so it overrides the generated keys.
Nested objects
When type is :object or {:array, :object}, a do block may follow.
Each argument inside it declares a property of that object, or of the
object in "items" for an array, and may itself take a block. :required
inside the block adds the name to the nested object's "required" list.
A block argument also accepts :additional_properties, a boolean or schema
map set as the nested object's "additionalProperties". The other options,
including :schema, apply to the property itself, so for an array they sit
beside "items".
argument "filters", {:array, :object}, min_items: 1, additional_properties: false do
argument "field", :string, required: true
argument "value", :string
endA block argument's :schema cannot set the keys the block generates:
"properties" and "required" for :object, and "items" for
{:array, :object}.
An empty or repeated name, an unknown or repeated option, an option value of the wrong type, or a block on any other type is a compile error.
Sets the tool's output schema, either from a JSON Schema map or from a
do block of argument declarations.
With a map, this is Snodo.Tool.output_schema/1:
output_schema(%{"type" => "object", "properties" => %{"version" => %{"type" => "string"}}})With a block, the declarations take the same forms as the input schema, including nested blocks, and produce an object schema:
output_schema do
argument "version", :string, required: true
argument "published_at", :string
end:additional_properties and :schema apply to the output root as the
matching use Snodo.Tool.Simple options apply to the input root. They go in
the same keyword list as the block:
output_schema(
additional_properties: false,
do:
(
argument("version", :string, required: true)
argument("published_at", :string)
)
)With an output schema, call/2 must return structured content; see
Snodo.Tool.output_schema/1. Declaring the output schema a second time
when either declaration is a block, or declaring it inside an argument
block, is a compile error.