Alloy.Tool.Inline (alloy v0.12.4)

Copy Markdown View Source

A tool defined as data instead of a module.

Module tools (Alloy.Tool) are the right shape for tools you own and test. Inline tools cover the cases modules can't: tools discovered at runtime (an MCP server's tool list, a database of user-defined actions) and one-off tools that don't warrant a file.

Build one with Alloy.Tool.inline/1:

weather =
  Alloy.Tool.inline(
    name: "get_weather",
    description: "Get current weather for a location",
    input_schema: %{
      type: "object",
      properties: %{location: %{type: "string"}},
      required: ["location"]
    },
    execute: fn %{"location" => loc}, _context ->
      {:ok, "22°C and clear in " <> loc}
    end
  )

Alloy.run("What's the weather in Sydney?",
  provider: provider,
  tools: [weather, Alloy.Tool.Core.Read]
)

tools: accepts inline tools and tool modules interchangeably.

Fields

Required:

  • :name - unique tool name (string, used in API calls)
  • :description - what the tool does, for the model
  • :input_schema - JSON Schema map for the input
  • :execute - 2-arity function (input, context) returning {:ok, text}, {:ok, text, structured_data}, or {:error, reason} — the same contract as Alloy.Tool.execute/2

Optional:

  • :concurrent? - safe to run in parallel with other tools (default true, matching module tools without a concurrent?/0)
  • :max_result_chars - cap on result text, or :unlimited (default nil, no cap)
  • :allowed_callers - as Alloy.Tool.allowed_callers/0 (default nil, omitted from the tool definition)
  • :result_type - as Alloy.Tool.result_type/0 (default nil, omitted from the tool definition)
  • :strict - request provider strict-mode schema enforcement (default false)
  • :input_examples - example input maps for providers that support them (default [])
  • :defer_loading - request provider-side deferred tool loading (default false)

Summary

Types

t()

@type t() :: %Alloy.Tool.Inline{
  allowed_callers: [atom()] | nil,
  concurrent?: boolean(),
  defer_loading: boolean(),
  description: String.t(),
  execute: (map(), map() ->
              {:ok, String.t()}
              | {:ok, String.t(), map()}
              | {:error, String.t()}),
  input_examples: [map()],
  input_schema: map(),
  max_result_chars: pos_integer() | :unlimited | nil,
  name: String.t(),
  result_type: :text | :structured | nil,
  strict: boolean()
}