# `CMDC.Tool`
[🔗](https://github.com/tupleyun/cmdc/blob/v0.5.3/lib/cmdc/tool.ex#L1)

Agent 工具 behaviour 接口定义。

任何实现此 behaviour 的模块均可注册为 Agent 可调用的工具。
工具由 Agent 的 tool_call 消息触发，结果回传给 LLM。

## 实现示例

    defmodule MyApp.SearchTool do
      @behaviour CMDC.Tool

      @impl true
      def name, do: "search"

      @impl true
      def description, do: "在代码库中搜索内容"

      @impl true
      def parameters do
        %{
          "type" => "object",
          "properties" => %{
            "query" => %{"type" => "string", "description" => "搜索关键词"}
          },
          "required" => ["query"]
        }
      end

      @impl true
      def execute(%{"query" => query}, _context) do
        {:ok, "搜索结果：#{query}"}
      end
    end

## 可选回调

- `description/1` — 接收 `t:tool_context/0`，返回上下文感知描述；未实现时退回到 `description/0`
- `meta/1` — 接收已解析参数，返回简短人类可读摘要（如 `"读取 lib/cmdc.ex"`）；
  未实现时退回到 `name/0`

## 结果类型

- `{:ok, String.t()}` — 成功，字符串内容回传给 LLM 作为 tool_result
- `{:error, String.t()}` — 失败，错误描述字符串作为 tool_result 回传
- `{:effect, term()}` — 副作用类工具（如 SubAgent）返回结构化产物，由 ToolRunner 特殊处理

# `result`

```elixir
@type result() :: {:ok, String.t()} | {:error, String.t()} | {:effect, term()}
```

工具执行结果类型。

- `{:ok, String.t()}` — 成功，内容回传 LLM
- `{:error, String.t()}` — 失败，错误信息回传 LLM
- `{:effect, term()}` — 副作用结果，由 ToolRunner 处理（如子代理产物）

# `tool_context`

```elixir
@type tool_context() :: %{
  optional(:working_dir) =&gt; String.t(),
  optional(:shell) =&gt; atom()
}
```

传递给工具的轻量级上下文。

供 `description/1` 在生成 schema 时获取运行时信息（如工作目录、shell 类型）。
与传递给 `execute/2` 的完整 `CMDC.Context.t()` 不同。

# `description`

```elixir
@callback description() :: String.t()
```

返回工具的人类可读描述。

# `description`
*optional* 

```elixir
@callback description(context :: tool_context()) :: String.t()
```

返回上下文感知的工具描述（可选）。

接收 `t:tool_context/0`，可据此在描述中嵌入运行时信息。
未实现时，`CMDC.Tool.description/2` 自动退回到 `description/0`。

# `execute`

```elixir
@callback execute(args :: map(), context :: CMDC.Context.t()) :: result()
```

使用给定参数和会话上下文执行工具。

- `args` — LLM 传入的参数 map（JSON 解析后）
- `context` — `CMDC.Context.t()` 完整执行上下文（含 sandbox/working_dir/session_id 等）

# `meta`
*optional* 

```elixir
@callback meta(args :: map()) :: String.t()
```

返回特定工具调用的简短人类可读摘要（可选）。

供 UI 展示当前工具正在做什么，如 `"读取 lib/cmdc/tool.ex"`。
接收已解析的参数 map；未实现时退回到 `name/0`。

# `name`

```elixir
@callback name() :: String.t()
```

返回工具名称（对应 LLM tool_call 中的 name 字段）。

# `parameters`

```elixir
@callback parameters() :: map()
```

返回描述工具参数的 JSON Schema map（JSON Schema Draft 7 格式）。

# `description`

```elixir
@spec description(module(), tool_context()) :: String.t()
```

返回工具描述，优先调用上下文感知的 `description/1`，否则退回 `description/0`。

# `find`

```elixir
@spec find([module()], String.t()) :: {:ok, module()} | {:error, :not_found}
```

按名称查找工具模块，未找到返回 `{:error, :not_found}`。

# `meta`

```elixir
@spec meta(module(), map()) :: String.t()
```

返回工具调用摘要，有 `meta/1` 时调用，否则返回工具名称。

# `to_schema`

```elixir
@spec to_schema([module()], tool_context()) :: [map()]
```

将工具模块列表转换为 LLM 所需的 tools schema 格式。

每个工具对应一个 `%{"type" => "function", "function" => ...}` 条目。

---

*Consult [api-reference.md](api-reference.md) for complete listing*
