# `CMDCEval.Runner`
[🔗](https://github.com/tupleyun/cmdc_eval/blob/v0.1.0/lib/cmdc_eval/runner.ex#L1)

Eval Runner —— 并发跑 case + 调 CMDC Agent + 收集 Run + 输出 Report。

## 流程

    [Suite.cases/0]
      └─▶ Task.async_stream/3 (并发跑 case)
            └─▶ for each case:
                  1. CMDC.create_agent(model, tools, provider_opts)
                  2. CMDC.prompt(session, case.input)
                  3. CMDC.collect_reply(session, timeout)
                  4. Suite.assert(case, reply) → boolean
                  5. CMDC.stop(session)
                  6. 收集 latency + token usage + cost → Run.success/failure
      └─▶ Report.build/5 聚合 + 可选 JSONL 写文件

## 错误处理

单 case crash / timeout 被捕获 → `Run.failure(reason)`，不影响其他 case。
整个 Runner 不会因为单 case 失败而中断。

## Mock Provider

当 `provider_opts` 含 `provider_fn: fn ... end` 时直接走该函数（用
`cmdc_test` 子库的 `CMDCTest.MockProvider`），避免真 LLM 调用。

# `run`

```elixir
@spec run(keyword()) :: {:ok, CMDCEval.Report.t()} | {:error, term()}
```

跑 Suite，返回 `{:ok, %Report{}}` 或 `{:error, reason}`。

见 `CMDCEval.run/1` 的选项说明。

---

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