Current section
Files
Jump to
Current section
Files
lib/codex/tool.ex
defmodule Codex.Tool do
@moduledoc """
Behaviour and helper macros for Codex tool modules.
Tools must implement `c:invoke/2`, returning either `{:ok, map()}` or `{:error, term()}`.
Optional metadata is surfaced via `metadata/0` and merged with registry attributes on
registration.
"""
@callback invoke(map(), map()) :: {:ok, map()} | {:error, term()}
@callback metadata() :: map()
@optional_callbacks metadata: 0
@doc """
Returns metadata for a tool module, normalising to a map.
"""
@spec metadata(module()) :: map()
def metadata(module) when is_atom(module) do
_ = Code.ensure_loaded(module)
if function_exported?(module, :metadata, 0) do
module.metadata() |> normalise_metadata()
else
%{}
end
end
@doc """
Normalizes metadata options to a map.
"""
@spec normalize_metadata(term()) :: map()
def normalize_metadata(metadata) when is_map(metadata), do: metadata
def normalize_metadata(metadata) when is_list(metadata), do: Map.new(metadata)
def normalize_metadata(_other), do: %{}
@doc false
defmacro __using__(opts) do
quote do
@behaviour Codex.Tool
@impl true
def metadata do
unquote(opts)
|> Codex.Tool.normalize_metadata()
end
defoverridable metadata: 0
end
end
defp normalise_metadata(metadata), do: normalize_metadata(metadata)
end