# `CMDC.Context`
[🔗](https://github.com/tuplehq/cmdc/blob/v0.3.0/lib/cmdc/context.ex#L1)

工具和插件的执行上下文，typed struct 杜绝 map 黑洞。

在 Agent Loop 执行过程中作为**只读上下文**传递给 Tool 的 `execute/2`
和 Plugin 的 `handle_event/3`。不应在 Plugin 内修改 Context，
而是通过返回 action 元组影响 Agent 行为。

## 字段分组

- **身份** — `session_id`、`working_dir`、`model`
- **运行时配置** — `sandbox`、`tools`、`subagents`、`config`
- **会话数据** — `todos`、`memory_contents`
- **业务上下文** — `user_data`（来自 `Options.user_data`，SubAgent 自动继承）
- **统计** — `turn`、`total_tokens`、`cost_usd`

## 用于 Tool 实现示例

    def execute(args, %CMDC.Context{sandbox: sandbox} = ctx) when not is_nil(sandbox) do
      sandbox.read_file(args["path"], working_dir: ctx.working_dir)
    end
    def execute(args, ctx) do
      CMDC.Sandbox.Local.read_file(args["path"], working_dir: ctx.working_dir)
    end

## 读取业务上下文（user_data）

    def execute(args, %CMDC.Context{user_data: %{tenant_id: t}}) do
      {:ok, "fetched for tenant=#{t}"}
    end

# `t`

```elixir
@type t() :: %CMDC.Context{
  config: CMDC.Config.t() | nil,
  cost_usd: float(),
  last_assistant_reply: String.t() | nil,
  memory_contents: %{required(String.t()) =&gt; String.t()},
  model: String.t(),
  prompt_mode: CMDC.Options.prompt_mode(),
  sandbox: module() | nil,
  session_id: String.t(),
  subagents: [map()],
  todos: [map()],
  tools: [module()],
  total_tokens: non_neg_integer(),
  turn: non_neg_integer(),
  user_data: map(),
  working_dir: String.t()
}
```

# `from_options`

```elixir
@spec from_options(CMDC.Options.t(), String.t(), CMDC.Config.t() | nil) :: t()
```

从 `CMDC.Options.t()` 和 session_id 构建初始 Context。

用于 Agent 启动时创建第一个 Context 快照。

# `from_state`

```elixir
@spec from_state(map()) :: t()
```

从 Agent.State map 构建 Context 快照，供 Plugin Pipeline 和 Tool 使用。

Agent.State 保证包含 `session_id`、`working_dir`、`model` 字段。

# `total_tokens`

```elixir
@spec total_tokens(t()) :: non_neg_integer()
```

返回当前已使用的 token 总量。

---

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