Nous.Tool.Schema (nous v0.13.3)

View Source

Declarative DSL for defining tool schemas.

Provides a macro-based approach to defining tool metadata, parameters, and JSON Schema in a single, readable block. Automatically implements Nous.Tool.Behaviour callbacks.

Architecture

When you use Nous.Tool.Schema, the module:

  1. Adds @behaviour Nous.Tool.Behaviour
  2. Imports the tool and param macros
  3. Registers a @before_compile hook to generate metadata/0 and __tool_schema__/0

The tool macro captures the tool name, description, category, and tags. Inside its block, param declarations accumulate into @tool_params. At compile time, these are transformed into JSON Schema and behaviour callbacks.

Quick Start

defmodule MyApp.Tools.FileRead do
  use Nous.Tool.Schema

  tool "file_read",
    description: "Read a file from the filesystem",
    category: :read,
    tags: [:file] do
      param :path, :string, required: true, doc: "Absolute file path"
      param :offset, :integer, doc: "Line offset to start reading from"
      param :limit, :integer, doc: "Number of lines to read"
  end

  @impl Nous.Tool.Behaviour
  def execute(_ctx, %{"path" => path} = _args) do
    {:ok, File.read!(path)}
  end
end

Supported Param Types

Elixir typeJSON Schema type
:string"string"
:integer"integer"
:number"number"
:boolean"boolean"
:array"array"
:object"object"

Summary

Functions

Set up the Schema DSL in the calling module.

Build a JSON Schema map from a list of param definitions.

Declare a parameter within a tool block.

Define a tool with its name, options, and parameter block.

Convert an Elixir type atom to a JSON Schema type string.

Types

param_def()

@type param_def() :: %{
  name: atom(),
  type: atom(),
  required: boolean(),
  doc: String.t() | nil
}

Functions

__using__(opts)

(macro)

Set up the Schema DSL in the calling module.

Injects @behaviour Nous.Tool.Behaviour, imports macros, and registers a @before_compile hook to generate callbacks.

Example

defmodule MyTool do
  use Nous.Tool.Schema
  # ...
end

build_json_schema(params)

@spec build_json_schema([param_def()]) :: map()

Build a JSON Schema map from a list of param definitions.

Examples

iex> Nous.Tool.Schema.build_json_schema([
...>   %{name: :query, type: :string, required: true, doc: "Search query"},
...>   %{name: :limit, type: :integer, required: false, doc: nil}
...> ])
%{
  "type" => "object",
  "properties" => %{
    "query" => %{"type" => "string", "description" => "Search query"},
    "limit" => %{"type" => "integer"}
  },
  "required" => ["query"]
}

param(name, type, opts \\ [])

(macro)

Declare a parameter within a tool block.

Arguments

  • name - Parameter name as an atom
  • type - One of :string, :integer, :number, :boolean, :array, :object
  • opts - Keyword options

Options

  • :required - Whether the parameter is required (default: false)
  • :doc - Human-readable description of the parameter

Examples

param :query, :string, required: true, doc: "The search query"
param :limit, :integer, doc: "Maximum results to return"
param :verbose, :boolean

tool(name, opts, list)

(macro)

Define a tool with its name, options, and parameter block.

Options

  • :description - Human-readable description of the tool (required)
  • :category - Tool category: :read, :write, :execute, :communicate, :search
  • :tags - List of atom tags for filtering (default: [])

Example

tool "search_web",
  description: "Search the web for information",
  category: :search,
  tags: [:web, :research] do
    param :query, :string, required: true, doc: "Search query"
    param :limit, :integer, doc: "Maximum number of results"
end

type_to_json_type(atom)

@spec type_to_json_type(atom()) :: String.t()

Convert an Elixir type atom to a JSON Schema type string.

Examples

iex> Nous.Tool.Schema.type_to_json_type(:string)
"string"

iex> Nous.Tool.Schema.type_to_json_type(:integer)
"integer"