PtcRunner.Tool (PtcRunner v0.4.1)

View Source

Normalized tool definition for PTC-Lisp and SubAgent.

Tools can be defined in multiple formats and are normalized to this struct. Supports function references, explicit signatures, and introspection.

Tool Type

Tools can be one of three types:

  • :native - Elixir function
  • :llm - LLM-powered tool (SubAgent only)
  • :subagent - SubAgent wrapped as tool (SubAgent only)

Tool Formats

All tool formats are accepted and normalized internally. Common patterns:

1. Function reference (extracts @spec and @doc)

"get_user" => &MyApp.get_user/1

2. Function with explicit signature

"search" => {&MyApp.search/2, "(query :string, limit :int) -> [{id :int}]"}

3. Function with signature and description

"analyze" => {&MyApp.analyze/1,
  signature: "(data :map) -> {score :float}",
  description: "Analyze data and return anomaly score"
}

4. Anonymous function

"get_time" => fn _args -> DateTime.utc_now() end

5. Skip validation explicitly

"dynamic" => {&MyApp.dynamic/1, :skip}

Type Definition

%PtcRunner.Tool{
  name: "get_user",
  function: &MyApp.get_user/1,
  signature: "(id :int) -> {id :int, name :string}",
  description: "Get user by ID",
  type: :native
}

Field Reference

  • name - Tool name as string (required)
  • function - Callable (required for native tools)
  • signature - Optional signature for validation: "(inputs) -> outputs"
  • description - Optional description for LLM visibility
  • type - Tool type: :native, :llm, :subagent

Summary

Functions

Creates a normalized Tool struct from a name and format.

Types

t()

@type t() :: %PtcRunner.Tool{
  description: String.t() | nil,
  function: (map() -> term()) | nil,
  name: String.t(),
  signature: String.t() | nil,
  type: :native | :llm | :subagent
}

tool_format()

@type tool_format() ::
  (map() -> term())
  | {(map() -> term()), String.t()}
  | {(map() -> term()), keyword()}
  | {(map() -> term()), :skip}

Functions

new(name, format)

@spec new(String.t(), tool_format()) :: {:ok, t()} | {:error, term()}

Creates a normalized Tool struct from a name and format.

Handles multiple input formats and normalizes to a consistent structure. Attempts to extract @spec and @doc from bare function references.

Parameters

  • name - Tool name as string
  • format - One of: function, {function, signature}, {function, options}, :skip

Returns

{:ok, tool} on success, {:error, reason} on failure.

Examples

Simple function reference (auto-extracts @doc and @spec if available):

iex> {:ok, tool} = PtcRunner.Tool.new("get_time", fn _args -> DateTime.utc_now() end)
iex> tool.name
"get_time"
iex> tool.type
:native

Function with explicit signature:

iex> {:ok, tool} = PtcRunner.Tool.new("search", {fn _args -> [] end, "(query :string, limit :int) -> [{id :int}]"})
iex> tool.signature
"(query :string, limit :int) -> [{id :int}]"

Function with signature and description:

iex> {:ok, tool} = PtcRunner.Tool.new("analyze", {fn _args -> %{} end,
...>   signature: "(data :map) -> {score :float}",
...>   description: "Analyze data and return anomaly score"
...> })
iex> tool.description
"Analyze data and return anomaly score"

Skip validation:

iex> {:ok, tool} = PtcRunner.Tool.new("dynamic", {fn _args -> nil end, :skip})
iex> tool.signature
nil