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

Eval Run 聚合报告 + JSONL 输出。

## 字段

- `:suite_name` —— Suite 名（如 `"internal"` / `"bfcl"`）
- `:model` —— 评测使用的 model 字符串
- `:runs` —— `[Run.t()]` 全部 case 结果（按 case_id 排序）
- `:summary` —— 汇总指标 map
- `:started_at` / `:completed_at` —— ISO8601 时间戳
- `:report_path` —— JSONL 文件路径（nil 表示未写文件）

## JSONL 输出格式

每行 1 个 Run 的 JSON。下游可被 LangSmith / Langfuse / Datadog 直接消费:

    $ head -1 report.jsonl
    {"suite":"internal","case_id":"basic","model":"...","pass":true,...}

# `summary`

```elixir
@type summary() :: %{
  total: non_neg_integer(),
  pass: non_neg_integer(),
  fail: non_neg_integer(),
  pass_rate: float(),
  total_latency_ms: non_neg_integer(),
  avg_latency_ms: float(),
  total_tokens_in: non_neg_integer(),
  total_tokens_out: non_neg_integer(),
  total_cost_usd: float()
}
```

# `t`

```elixir
@type t() :: %CMDCEval.Report{
  completed_at: String.t(),
  model: String.t(),
  report_path: String.t() | nil,
  runs: [CMDCEval.Run.t()],
  started_at: String.t(),
  suite_name: String.t(),
  summary: summary()
}
```

# `build`

```elixir
@spec build(String.t(), String.t(), [CMDCEval.Run.t()], String.t(), String.t()) :: t()
```

根据已收集的 `[Run.t()]` 构造完整 Report 含 summary。

# `write_jsonl`

```elixir
@spec write_jsonl(t(), String.t()) :: {:ok, map()} | {:error, term()}
```

把 Report 的 `:runs` 序列化为 JSONL 写入 `path`。

写入成功返回 `{:ok, %{path | bytes_written | runs_written}}`,
失败返回 `{:error, reason}`。

---

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