niceeval 0.4.4 → 0.4.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (177) hide show
  1. package/README.md +21 -12
  2. package/README.zh.md +8 -9
  3. package/docs-site/.mintignore +13 -0
  4. package/docs-site/AGENTS.md +46 -0
  5. package/docs-site/concepts/adapter.mdx +287 -0
  6. package/docs-site/concepts/assert.mdx +243 -0
  7. package/docs-site/concepts/drive.mdx +118 -0
  8. package/docs-site/concepts/evals.mdx +108 -0
  9. package/docs-site/concepts/experiment.mdx +37 -0
  10. package/docs-site/concepts/hitl.mdx +83 -0
  11. package/docs-site/concepts/judge.mdx +129 -0
  12. package/docs-site/concepts/overview.mdx +98 -0
  13. package/docs-site/concepts/tier.mdx +42 -0
  14. package/docs-site/docs-ref/00-index.md +23 -0
  15. package/docs-site/docs-ref/01-page-types.md +43 -0
  16. package/docs-site/docs-ref/03-style-rules.md +45 -0
  17. package/docs-site/docs-ref/04-code-examples.md +37 -0
  18. package/docs-site/docs-ref/05-dx-failure-paths.md +45 -0
  19. package/docs-site/docs-ref/06-checklists.md +53 -0
  20. package/docs-site/docs.json +256 -0
  21. package/docs-site/example/ai-agent-application.mdx +148 -0
  22. package/docs-site/example/claude-code-codex-plugin.mdx +162 -0
  23. package/docs-site/example/claude-code-codex-skill.mdx +147 -0
  24. package/docs-site/example/showcase.mdx +39 -0
  25. package/docs-site/example/tier1-ai-sdk-v7.mdx +136 -0
  26. package/docs-site/example/tier1-claude-sdk.mdx +119 -0
  27. package/docs-site/example/tier1-codex-sdk.mdx +111 -0
  28. package/docs-site/example/tier1-langgraph.mdx +119 -0
  29. package/docs-site/example/tier1-pi-sdk.mdx +119 -0
  30. package/docs-site/favicon.svg +5 -0
  31. package/docs-site/github-diff.css +135 -0
  32. package/docs-site/github-diff.js +11 -0
  33. package/docs-site/guides/authoring.mdx +129 -0
  34. package/docs-site/guides/ci-integration.mdx +97 -0
  35. package/docs-site/guides/connect-otel.mdx +209 -0
  36. package/docs-site/guides/connect-your-agent.mdx +221 -0
  37. package/docs-site/guides/dataset-fanout.mdx +98 -0
  38. package/docs-site/guides/experiments.mdx +71 -0
  39. package/docs-site/guides/fixtures.mdx +147 -0
  40. package/docs-site/guides/reporters.mdx +113 -0
  41. package/docs-site/guides/runner.mdx +79 -0
  42. package/docs-site/guides/sandbox-agent.mdx +138 -0
  43. package/docs-site/guides/sandbox-backends.mdx +64 -0
  44. package/docs-site/guides/scoring-guide.mdx +92 -0
  45. package/docs-site/guides/viewing-results.mdx +195 -0
  46. package/docs-site/guides/write-experiment.mdx +81 -0
  47. package/docs-site/guides/write-send.mdx +347 -0
  48. package/docs-site/images/adapter-tiers-zh.svg +60 -0
  49. package/docs-site/images/agent-turn-roundtrip-en.svg +62 -0
  50. package/docs-site/images/agent-turn-roundtrip-zh.svg +77 -0
  51. package/docs-site/images/hitl-handshake-zh.svg +89 -0
  52. package/docs-site/images/logo.svg +6 -0
  53. package/docs-site/index.mdx +181 -0
  54. package/docs-site/introduction.mdx +141 -0
  55. package/docs-site/quickstart.mdx +136 -0
  56. package/docs-site/reference/builtin-agents.mdx +161 -0
  57. package/docs-site/reference/capabilities.mdx +76 -0
  58. package/docs-site/reference/cli.mdx +120 -0
  59. package/docs-site/reference/define-agent.mdx +168 -0
  60. package/docs-site/reference/define-config.mdx +41 -0
  61. package/docs-site/reference/define-eval.mdx +160 -0
  62. package/docs-site/reference/events.mdx +131 -0
  63. package/docs-site/reference/expect.mdx +112 -0
  64. package/docs-site/tracker.js +8 -0
  65. package/docs-site/zh/concepts/adapter.mdx +286 -0
  66. package/docs-site/zh/concepts/assert.mdx +243 -0
  67. package/docs-site/zh/concepts/drive.mdx +118 -0
  68. package/docs-site/zh/concepts/evals.mdx +124 -0
  69. package/docs-site/zh/concepts/experiment.mdx +37 -0
  70. package/docs-site/zh/concepts/hitl.mdx +83 -0
  71. package/docs-site/zh/concepts/judge.mdx +130 -0
  72. package/docs-site/zh/concepts/overview.mdx +109 -0
  73. package/docs-site/zh/concepts/tier.mdx +44 -0
  74. package/docs-site/zh/example/ai-agent-application.mdx +152 -0
  75. package/docs-site/zh/example/claude-code-codex-plugin.mdx +163 -0
  76. package/docs-site/zh/example/claude-code-codex-skill.mdx +147 -0
  77. package/docs-site/zh/example/showcase.mdx +39 -0
  78. package/docs-site/zh/example/tier1-ai-sdk-v7.mdx +140 -0
  79. package/docs-site/zh/example/tier1-claude-sdk.mdx +122 -0
  80. package/docs-site/zh/example/tier1-codex-sdk.mdx +117 -0
  81. package/docs-site/zh/example/tier1-langgraph.mdx +123 -0
  82. package/docs-site/zh/example/tier1-pi-sdk.mdx +122 -0
  83. package/docs-site/zh/guides/agent-feedback-loop.mdx +79 -0
  84. package/docs-site/zh/guides/authoring.mdx +129 -0
  85. package/docs-site/zh/guides/ci-integration.mdx +97 -0
  86. package/docs-site/zh/guides/connect-otel.mdx +208 -0
  87. package/docs-site/zh/guides/connect-your-agent.mdx +226 -0
  88. package/docs-site/zh/guides/dataset-fanout.mdx +83 -0
  89. package/docs-site/zh/guides/experiments.mdx +72 -0
  90. package/docs-site/zh/guides/fixtures.mdx +147 -0
  91. package/docs-site/zh/guides/official-adapters.mdx +132 -0
  92. package/docs-site/zh/guides/reporters.mdx +113 -0
  93. package/docs-site/zh/guides/runner.mdx +82 -0
  94. package/docs-site/zh/guides/sandbox-agent.mdx +139 -0
  95. package/docs-site/zh/guides/sandbox-backends.mdx +75 -0
  96. package/docs-site/zh/guides/scoring-guide.mdx +92 -0
  97. package/docs-site/zh/guides/viewing-results.mdx +195 -0
  98. package/docs-site/zh/guides/write-experiment.mdx +101 -0
  99. package/docs-site/zh/guides/write-send.mdx +353 -0
  100. package/docs-site/zh/index.mdx +180 -0
  101. package/docs-site/zh/introduction.mdx +140 -0
  102. package/docs-site/zh/quickstart.mdx +137 -0
  103. package/docs-site/zh/reference/builtin-agents.mdx +364 -0
  104. package/docs-site/zh/reference/capabilities.mdx +76 -0
  105. package/docs-site/zh/reference/cli.mdx +140 -0
  106. package/docs-site/zh/reference/define-agent.mdx +461 -0
  107. package/docs-site/zh/reference/define-config.mdx +107 -0
  108. package/docs-site/zh/reference/define-eval.mdx +674 -0
  109. package/docs-site/zh/reference/events.mdx +252 -0
  110. package/docs-site/zh/reference/expect.mdx +208 -0
  111. package/package.json +3 -2
  112. package/src/agents/bub.ts +1 -1
  113. package/src/agents/claude-code.ts +8 -5
  114. package/src/agents/codex.ts +9 -5
  115. package/src/agents/sdk-streams.test.ts +4 -4
  116. package/src/agents/sdk-streams.ts +14 -9
  117. package/src/agents/types.ts +40 -1
  118. package/src/agents/ui-message-stream.ts +1 -0
  119. package/src/cli.ts +36 -7
  120. package/src/context/types.ts +140 -0
  121. package/src/expect/index.ts +15 -8
  122. package/src/i18n/en.ts +19 -6
  123. package/src/i18n/zh-CN.ts +19 -6
  124. package/src/o11y/parsers/bub.test.ts +71 -0
  125. package/src/o11y/parsers/bub.ts +5 -0
  126. package/src/o11y/types.ts +27 -2
  127. package/src/runner/reporters/artifacts.ts +11 -3
  128. package/src/runner/reporters/live.ts +45 -8
  129. package/src/runner/run.ts +71 -21
  130. package/src/runner/types.ts +45 -2
  131. package/src/sandbox/types.ts +18 -0
  132. package/src/scoring/types.ts +5 -0
  133. package/src/shared/types.ts +3 -0
  134. package/src/util.test.ts +26 -1
  135. package/src/util.ts +16 -0
  136. package/src/view/app/App.tsx +2 -2
  137. package/src/view/app/components/AttemptModal.tsx +2 -0
  138. package/src/view/app/components/CopyControls.tsx +87 -28
  139. package/src/view/app/i18n.ts +3 -3
  140. package/src/view/client-dist/app.css +1 -1
  141. package/src/view/client-dist/app.js +18 -18
  142. package/docs/README.md +0 -120
  143. package/docs/adapters/README.md +0 -60
  144. package/docs/adapters/authoring.md +0 -179
  145. package/docs/adapters/coding-agent-skills-plugins.md +0 -324
  146. package/docs/adapters/collection.md +0 -128
  147. package/docs/adapters/contract.md +0 -264
  148. package/docs/adapters/reference/agent-eval.md +0 -215
  149. package/docs/adapters/reference/agent-loop-apis.md +0 -69
  150. package/docs/adapters/reference/claude-code-otel-telemetry.md +0 -100
  151. package/docs/adapters/reference/eve-protocol.md +0 -127
  152. package/docs/adapters/reference/otel-genai.md +0 -107
  153. package/docs/adapters/reference/otel-instrumentation.md +0 -65
  154. package/docs/adapters/targets.md +0 -99
  155. package/docs/architecture.md +0 -140
  156. package/docs/assertions.md +0 -387
  157. package/docs/capabilities-by-construction.md +0 -48
  158. package/docs/cli.md +0 -173
  159. package/docs/concepts.md +0 -106
  160. package/docs/e2e-ci.md +0 -332
  161. package/docs/eval-authoring.md +0 -319
  162. package/docs/experiments.md +0 -157
  163. package/docs/getting-started.md +0 -224
  164. package/docs/multi-agent.md +0 -145
  165. package/docs/observability.md +0 -337
  166. package/docs/origin-integration.md +0 -195
  167. package/docs/references.md +0 -35
  168. package/docs/reports.md +0 -551
  169. package/docs/results-format.md +0 -228
  170. package/docs/results-lib.md +0 -191
  171. package/docs/runner.md +0 -104
  172. package/docs/sandbox.md +0 -276
  173. package/docs/scoring.md +0 -119
  174. package/docs/source-map.md +0 -126
  175. package/docs/tier-sync.md +0 -193
  176. package/docs/view.md +0 -194
  177. package/docs/vision.md +0 -88
@@ -0,0 +1,89 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1240 668" role="img" aria-labelledby="title desc">
2
+ <title id="title">HITL 一次完整握手</title>
3
+ <desc id="desc">eval 发送任务,应用停在审批上,本轮以 waiting 返回并带 input.requested;t.respond 作为又一次普通 send 把结构化裁决交回,同一轮继续执行到 completed。</desc>
4
+ <defs>
5
+ <marker id="headBlue" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="8" markerHeight="8" orient="auto-start-reverse">
6
+ <path d="M 0 0 L 10 5 L 0 10 z" fill="#8ab4f8" />
7
+ </marker>
8
+ <marker id="headPurple" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="8" markerHeight="8" orient="auto-start-reverse">
9
+ <path d="M 0 0 L 10 5 L 0 10 z" fill="#a78bfa" />
10
+ </marker>
11
+ <linearGradient id="card" x1="0" x2="1" y1="0" y2="1">
12
+ <stop offset="0" stop-color="#0d1117" />
13
+ <stop offset="1" stop-color="#111820" />
14
+ </linearGradient>
15
+ <style>
16
+ .label { fill: #e6edf3; font: 600 24px ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; }
17
+ .code { fill: #e6edf3; font: 20px ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; }
18
+ .codeSm { fill: #c9d1d9; font: 18px ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; }
19
+ .cjk { fill: #c9d1d9; font: 20px -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif; }
20
+ .muted { fill: #8b949e; font: 18px -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif; }
21
+ .waiting { fill: #f0b429; }
22
+ .done { fill: #7ee787; }
23
+ .pill { fill: #1f2937; stroke: #374151; stroke-width: 1; }
24
+ .head { fill: #161b22; stroke: #30363d; stroke-width: 1.5; }
25
+ .arrow { stroke: #8ab4f8; stroke-width: 3; fill: none; marker-end: url(#headBlue); }
26
+ .returnArrow { stroke: #a78bfa; stroke-width: 3; fill: none; marker-end: url(#headPurple); }
27
+ .lane { stroke: #30363d; stroke-width: 1; stroke-dasharray: 5 8; }
28
+ </style>
29
+ </defs>
30
+
31
+ <rect x="1" y="1" width="1238" height="666" rx="24" fill="url(#card)" stroke="#30363d" stroke-width="2" />
32
+
33
+ <!-- 生命线与头部 -->
34
+ <line x1="200" y1="76" x2="200" y2="628" class="lane" />
35
+ <line x1="680" y1="76" x2="680" y2="628" class="lane" />
36
+ <line x1="1060" y1="76" x2="1060" y2="628" class="lane" />
37
+
38
+ <rect x="110" y="30" width="180" height="38" rx="10" class="head" />
39
+ <text x="200" y="57" class="label" text-anchor="middle">test(t)</text>
40
+ <rect x="565" y="30" width="230" height="38" rx="10" class="head" />
41
+ <text x="680" y="57" class="label" text-anchor="middle">Adapter 的 send</text>
42
+ <rect x="970" y="30" width="180" height="38" rx="10" class="head" />
43
+ <text x="1060" y="57" class="label" text-anchor="middle">你的应用</text>
44
+
45
+ <!-- ① 发起任务 -->
46
+ <text x="220" y="112" class="code">await t.send("把服务部署到 prod")</text>
47
+ <path d="M 206 124 H 668" class="arrow" />
48
+ <text x="220" y="146" class="muted">第 1 次 send</text>
49
+
50
+ <text x="700" y="152" class="cjk">调应用</text>
51
+ <path d="M 686 164 H 1048" class="arrow" />
52
+ <text x="944" y="196" class="muted" text-anchor="middle">停在部署确认上,等人批准</text>
53
+
54
+ <!-- ② waiting 返回 -->
55
+ <text x="220" y="222" class="code">Turn{ status: <tspan class="waiting">"waiting"</tspan>,</text>
56
+ <text x="220" y="246" class="codeSm"> events: [..., input.requested(</text>
57
+ <text x="220" y="268" class="codeSm"> id: "req_1", options: approve | deny)] }</text>
58
+ <path d="M 674 282 H 206" class="returnArrow" />
59
+
60
+ <!-- ③ eval 侧检查(不触发 send) -->
61
+ <rect x="40" y="308" width="170" height="32" rx="8" class="pill" />
62
+ <text x="54" y="331" class="codeSm">t.parked()</text>
63
+ <text x="230" y="331" class="muted">断言这一轮确实停下了</text>
64
+
65
+ <rect x="40" y="350" width="500" height="32" rx="8" class="pill" />
66
+ <text x="54" y="373" class="codeSm">t.requireInputRequest({ action: "deploy" })</text>
67
+ <text x="560" y="373" class="muted">取出待答请求;只读结果,不触发 send</text>
68
+
69
+ <!-- ④ 替人回答 -->
70
+ <text x="220" y="420" class="code">await t.respond("approve")</text>
71
+ <path d="M 206 432 H 668" class="arrow" />
72
+ <text x="220" y="456" class="codeSm">input.responses = [{ requestId: "req_1",</text>
73
+ <text x="220" y="478" class="codeSm"> optionId: "approve" }]</text>
74
+ <text x="500" y="420" class="muted">第 2 次 send:又一次普通 send</text>
75
+
76
+ <text x="696" y="470" class="cjk">按 requestId 交回裁决</text>
77
+ <path d="M 686 482 H 1048" class="arrow" />
78
+ <text x="944" y="510" class="muted" text-anchor="middle">同一轮接着跑,不重发请求</text>
79
+
80
+ <!-- ⑤ completed 返回 -->
81
+ <path d="M 1054 530 H 686" class="returnArrow" />
82
+ <text x="220" y="562" class="code">Turn{ status: <tspan class="done">"completed"</tspan>, events: [...] }</text>
83
+ <path d="M 674 574 H 206" class="returnArrow" />
84
+
85
+ <!-- ⑥ 断言照常 -->
86
+ <rect x="40" y="600" width="300" height="32" rx="8" class="pill" />
87
+ <text x="54" y="623" class="codeSm">t.calledTool("deploy")</text>
88
+ <text x="360" y="623" class="muted">事件流照常累计,断言词汇不变</text>
89
+ </svg>
@@ -0,0 +1,6 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 220 56" role="img" aria-label="niceeval">
2
+ <rect width="56" height="56" rx="12" fill="#11161e"/>
3
+ <path d="M15 14h28v7H25v7h15v7H25v13H15z" fill="#f8fafc"/>
4
+ <path d="M31 35h14v7H31z" fill="#848c8e"/>
5
+ <text x="72" y="37" fill="#11161e" font-family="Inter, Arial, sans-serif" font-size="28" font-weight="700">niceeval</text>
6
+ </svg>
@@ -0,0 +1,181 @@
1
+ ---
2
+ title: "NiceEval"
3
+ sidebarTitle: "Home"
4
+ description: "NiceEval is a progressive, full-featured, developer-friendly, agent-native eval tool for AI agents."
5
+ ---
6
+
7
+ <div align="center">
8
+
9
+ # NiceEval
10
+
11
+ **A progressive, full-featured, developer-friendly, agent-native eval tool for AI agents**
12
+
13
+ </div>
14
+
15
+ [NiceEval](https://niceeval.com/) is an agent-native eval tool inspired by [eve](https://eve.dev). It aims for strong developer experience first: a project can usually integrate it in about 10 minutes, eval files stay readable, and results are easy to inspect.
16
+
17
+ It is also broad enough to evaluate coding-agent plugins, hooks, and Skills built for Claude Code / Codex, as well as your own AI agent application. Whether your app uses AI SDK, LangGraph, Pi, or a custom agent loop, you can connect it through an adapter.
18
+
19
+ After each run, [NiceEval](https://niceeval.com/) generates readable reports and structured artifacts so you can inspect agent behavior, debug failures, and keep improving pass rate, cost, and latency.
20
+
21
+ <CardGroup cols={3}>
22
+ <Card title="Claude Code / Codex plugin" icon="plug" href="/example/claude-code-codex-plugin">
23
+ Use sandbox workspaces to give a coding agent real tasks, then verify plugin behavior through tests, diffs, and tool-call records.
24
+ </Card>
25
+ <Card title="Claude Code / Codex Skill" icon="wand-magic-sparkles" href="/example/claude-code-codex-skill">
26
+ Inject the Skill through experiment setup, then compare pass rate, cost, and behavior against a no-Skill baseline.
27
+ </Card>
28
+ <Card title="AI agent application" icon="globe" href="/example/ai-agent-application">
29
+ Wrap your AI agent with `defineAgent` and bring replies, tool calls, and structured output into the same eval surface.
30
+ </Card>
31
+ </CardGroup>
32
+
33
+ ## Architecture
34
+
35
+ [NiceEval](https://niceeval.com/) supports two integration modes, depending on whether the subject under test needs an isolated workspace.
36
+
37
+ ### Mode 1: Sandbox
38
+
39
+ Run coding agents such as Codex and Claude Code that need a sandbox:
40
+
41
+ ```text
42
+ evals/*.eval.ts
43
+ |
44
+ v
45
+ ┌────────────┐
46
+ │ niceeval │
47
+ └────────────┘
48
+ |
49
+ | Agent adapter (official)
50
+ v
51
+ ┌───────────────────────────────┐
52
+ │ Docker Sandbox │
53
+ │ ┌───────────────────────┐ │
54
+ │ │ Codex / Claude Code / │ │
55
+ │ │ apps that need an │ │
56
+ │ │ isolated workspace │ │
57
+ │ └───────────────────────┘ │
58
+ └───────────────────────────────┘
59
+ ```
60
+
61
+ ### Mode 2: Direct
62
+
63
+ Connect directly to your own AI agent:
64
+
65
+ ```text
66
+ evals/*.eval.ts
67
+ |
68
+ v
69
+ ┌────────────┐
70
+ │ niceeval │
71
+ └────────────┘
72
+ |
73
+ | Agent adapter (official / custom)
74
+ v
75
+ ┌────────────────────────────┐
76
+ │ Your own AI agent app │
77
+ │ (AI SDK · LangGraph · Pi · │
78
+ │ custom agent loop, etc.) │
79
+ └────────────────────────────┘
80
+ ```
81
+
82
+ - **[NiceEval](https://niceeval.com/) core** handles eval discovery, scheduling, scoring, reporting, and artifacts.
83
+ - **Agent adapters** are the open boundary: you decide how to call the subject under test and how to map its output into the standard event stream.
84
+ - **Sandbox** handles file-system isolation: coding agents that need a real workspace use Docker or a cloud sandbox; direct web agents do not need Docker.
85
+
86
+ ## Core Concepts
87
+
88
+ | Concept | In one sentence |
89
+ |---|---|
90
+ | [Eval](/concepts/evals) | A test case: written in `evals/*.eval.ts`, describing what to verify. |
91
+ | [Experiment](/concepts/experiment) | A check-in-able run configuration: decides which adapter, model, and flags to use. |
92
+ | [Adapter](/concepts/adapter) | The connection layer for the subject under test: implements `send` and translates responses into the standard event stream. |
93
+ | [Sandbox](/guides/sandbox-backends) | Needed only for coding agents that require isolated workspaces; direct web agents do not need one. |
94
+ | [Tier](/concepts/tier) | Three investment levels for adapter integration: Tier 1 only connects `send`, Tier 2 adds OTel for call waterfalls, and Tier 3 makes invasive changes for feature A/B tests. |
95
+
96
+ See [Architecture Overview](/concepts/overview) for the full terminology map.
97
+
98
+ ## Examples
99
+
100
+ To run one eval you need two files: the eval itself (what to test) and an experiment (which agent to run). The CLI does not accept a bare eval ID. In `niceeval exp <experiment> <eval-prefix>`, the experiment decides which subject gets connected. Here is a real direct web-agent scenario from `examples/zh/ai-sdk/`: verify that the agent calls a tool for a live weather question and answers from the tool result instead of inventing one.
101
+
102
+ ```ts
103
+ // evals/weather-tool.eval.ts
104
+ import { defineEval } from "niceeval";
105
+
106
+ export default defineEval({
107
+ description: "Verify that the agent calls the weather tool and answers from the tool result",
108
+
109
+ async test(t) {
110
+ const turn = await t.send("What's the weather like in Beijing today?");
111
+ turn.succeeded();
112
+
113
+ await t.group("Calls get_weather with the right city", () => {
114
+ t.calledTool("get_weather", { input: { city: "Beijing" } });
115
+ t.messageIncludes(/°C|temperature|weather|sunny|cloudy|rain/i);
116
+ });
117
+
118
+ t.judge.autoevals
119
+ .closedQA("Does the assistant answer from the returned weather data instead of inventing a temperature?")
120
+ .atLeast(0.7);
121
+ },
122
+ });
123
+ ```
124
+
125
+ ```ts
126
+ // experiments/local.ts
127
+ import { defineExperiment } from "niceeval";
128
+ import { webAgent } from "./adapter"; // Your adapter for the web agent under test.
129
+
130
+ export default defineExperiment({
131
+ agent: webAgent({ baseUrl: "http://127.0.0.1:5188" }),
132
+ model: "gpt-5.4",
133
+ });
134
+ ```
135
+
136
+ ```sh
137
+ npx niceeval exp local weather-tool
138
+ npx niceeval view
139
+ ```
140
+
141
+ If the subject under test is a coding agent that needs an isolated workspace, such as Codex or a Claude Code plugin / Skill, use `t.sandbox.uploadDirectory()` to lay down the workspace, `t.sandbox.fileChanged()` / `t.sandbox.file()` to inspect changes, and `t.sandbox.runCommand()` to run tests. See `examples/zh/coding-agent-skill/` in the repository.
142
+
143
+ ## Quickstart
144
+
145
+ If you want a coding agent to integrate [NiceEval](https://niceeval.com/) into the project for you, hand it the matching scenario page:
146
+
147
+ ```text
148
+ READ https://raw.githubusercontent.com/CorrectRoadH/niceeval/refs/heads/main/docs-site/zh/example/claude-code-codex-plugin.mdx and install niceeval for this repo.
149
+ READ https://raw.githubusercontent.com/CorrectRoadH/niceeval/refs/heads/main/docs-site/zh/example/claude-code-codex-skill.mdx and install niceeval for this repo.
150
+ READ https://raw.githubusercontent.com/CorrectRoadH/niceeval/refs/heads/main/docs-site/zh/example/ai-agent-application.mdx and install niceeval for this repo.
151
+ ```
152
+
153
+ <CardGroup cols={3}>
154
+ <Card title="Eval your Claude Code / Codex plugin" icon="plug" href="/example/claude-code-codex-plugin">
155
+ Start from a real plugin task, upload a workspace, inject the plugin, and use pass rate to see whether it works reliably.
156
+ </Card>
157
+ <Card title="Eval your Claude Code / Codex Skill" icon="wand-magic-sparkles" href="/example/claude-code-codex-skill">
158
+ Verify that the Skill is loaded, uses tools as intended, and produces testable outcomes.
159
+ </Card>
160
+ <Card title="Eval your AI agent application" icon="globe" href="/example/ai-agent-application">
161
+ Wrap your app interface and write assertions over conversations, tool calls, structured outputs, and cost.
162
+ </Card>
163
+ </CardGroup>
164
+
165
+ ## FAQ
166
+
167
+ <AccordionGroup>
168
+ <Accordion title="Do I need to create an account?">
169
+ No. Running evals and inspecting reports with `niceeval view` happens locally. Docker or E2B-style sandbox backends are only needed when the subject under test is a coding agent that needs an isolated workspace.
170
+ </Accordion>
171
+ <Accordion title="Can I connect an agent that is not written in TypeScript or JavaScript?">
172
+ Yes. An adapter only sends to and receives from the interface your app already exposes, such as HTTP, gRPC, or WebSocket. [NiceEval](https://niceeval.com/) does not care which language your app is written in or where it is deployed. See [Adapter](/concepts/adapter).
173
+ </Accordion>
174
+ <Accordion title="Can this run in CI?">
175
+ Yes. See [CI Integration](/guides/ci-integration).
176
+ </Accordion>
177
+ </AccordionGroup>
178
+
179
+ <Tip>
180
+ For the shortest path, read [Quickstart](/quickstart). To understand the boundaries first, read [Architecture Overview](/concepts/overview).
181
+ </Tip>
@@ -0,0 +1,141 @@
1
+ ---
2
+ title: "NiceEval: an eval tool for agents"
3
+ sidebarTitle: "Introduction"
4
+ description: "NiceEval helps teams measure, evaluate, and improve AI in production: compare models, iterate on agents, catch regressions, and improve with real data."
5
+ ---
6
+
7
+ [NiceEval](https://niceeval.com/) is an agent eval tool that helps teams measure, evaluate, and improve AI in production. With NiceEval, teams can compare models, iterate on agents, catch regressions, and keep improving their AI applications using real user data. It aims for low-friction DX: most projects can integrate in about 10 minutes, write the first eval, and start checking agent behavior reliably.
8
+
9
+ NiceEval is local-first at its core: your evals run in your own environment, so you don't need to create an account or connect to a platform before running your first eval. When your team needs to share eval results or track regressions, you can push a Report to platforms like BrainTrust, or export a custom report.
10
+
11
+ It can evaluate coding-agent plugins, hooks, and Skills for Claude Code / Codex, and it can also evaluate your own AI agent application directly. Whether your agent is built on AI SDK, LangGraph, Pi, or a custom loop, you can connect it through an Adapter into the same eval surface.
12
+
13
+ ## 30 seconds of DX
14
+
15
+ An eval is just a TypeScript file: send the agent a message, assert on what it did.
16
+
17
+ ```ts
18
+ // evals/eval-tool-call.eval.ts
19
+ import { defineEval } from "niceeval";
20
+
21
+ export default defineEval({
22
+ description: "Verify the agent calls the weather tool and answers from its result",
23
+
24
+ async test(t) {
25
+ const turn = await t.send("What's the weather in Beijing today?");
26
+ t.succeeded();
27
+
28
+ await t.group("calls get_weather with the right city", () => {
29
+ t.calledTool("get_weather", { input: { city: "Beijing" } });
30
+ t.messageIncludes(/°C|sunny|cloudy|rain/);
31
+ });
32
+
33
+ const second = await t.send("What about Shanghai tomorrow?");
34
+ second.messageIncludes("Shanghai");
35
+
36
+ t.judge.autoevals
37
+ .closedQA("Does the reply use the tool's weather data instead of making up a temperature?")
38
+ .atLeast(0.7);
39
+ },
40
+ });
41
+ ```
42
+
43
+ ```sh
44
+ pnpm exec niceeval exp local eval-tool-call # run only eval-tool-call under the local experiment
45
+ pnpm exec niceeval view # view eval results
46
+ ```
47
+
48
+ ## Why NiceEval when DeepEval, LangFuse, and BrainTrust already exist
49
+
50
+ NiceEval is an Agent-Native eval tool. The Dataset / golden pattern of building an Input and an Expected Output doesn't fit real agent evaluation — agents today need to be checked at a finer grain: multi-turn conversations, multi-agent collaboration, tool calls, skill loading. NiceEval is designed for exactly that: assertions land directly on tool calls, message content, structured output, and usage, instead of requiring you to hand-build a golden dataset first.
51
+
52
+ Tools like Langfuse and Braintrust lean more toward tracing and observability. For the path of "write evals, run evals, inspect results", that is often heavier than necessary. NiceEval is designed around that path from the start, with a simpler developer experience. The two aren't mutually exclusive either: NiceEval coexists with LangFuse and BrainTrust — use them for tracing, or upload eval results to both.
53
+
54
+ ## What you can evaluate
55
+
56
+ <CardGroup cols={2}>
57
+ <Card title="Coding agents" icon="code">
58
+ Put Claude Code, Codex, or bub into a sandbox, give them a task, then verify the result with real tests and file assertions.
59
+ </Card>
60
+ <Card title="Your own AI agent application" icon="globe">
61
+ Connect to your app directly and assert on replies, tool calls, and structured outputs.
62
+ </Card>
63
+ </CardGroup>
64
+
65
+ ## Two integration modes
66
+
67
+ <Tabs>
68
+ <Tab title="Sandbox mode">
69
+ Fits coding agents such as Codex and Claude Code that need a real file system and command execution.
70
+
71
+ ```text
72
+ evals/*.eval.ts
73
+
74
+
75
+ ┌────────────┐
76
+ │ niceeval │
77
+ └────────────┘
78
+
79
+ │ Adapter (official)
80
+
81
+ ┌───────────────────────────────┐
82
+ │ Docker Sandbox │
83
+ │ ┌───────────────────────┐ │
84
+ │ │ Codex / Claude Code / │ │
85
+ │ │ apps that need an │ │
86
+ │ │ isolated workspace │ │
87
+ │ └───────────────────────┘ │
88
+ └───────────────────────────────┘
89
+ ```
90
+ </Tab>
91
+ <Tab title="Direct mode">
92
+ Fits your own AI agent app and does not require Docker.
93
+
94
+ ```text
95
+ evals/*.eval.ts
96
+
97
+
98
+ ┌────────────┐
99
+ │ niceeval │
100
+ └────────────┘
101
+
102
+ │ Adapter (official or custom)
103
+
104
+ ┌────────────────────────────┐
105
+ │ Your own AI agent app │
106
+ │ (AI SDK · LangGraph · Pi · │
107
+ │ custom agent loop, etc.) │
108
+ └────────────────────────────┘
109
+ ```
110
+ </Tab>
111
+ </Tabs>
112
+
113
+ ## Core concepts at a glance
114
+
115
+ | Concept | In one line |
116
+ |---|---|
117
+ | Eval | A test case: written in `evals/*.eval.ts`, describing what to check. |
118
+ | Experiment | A checked-in run configuration: which Adapter, which model, which flags. |
119
+ | Adapter | The layer that connects to the system under test: implement one `send`, get back a standard event stream. |
120
+ | Sandbox | Only needed for coding agents that require an isolated workspace; a direct web agent doesn't need one. |
121
+ | Tier | Three levels of Adapter integration effort: Tier 1 wires up `send` only, Tier 2 adds OTel for a call waterfall, Tier 3 makes invasive changes for feature A/B testing. |
122
+
123
+ See the full glossary in the [architecture overview](/concepts/overview).
124
+
125
+ ## Start from your scenario
126
+
127
+ <CardGroup cols={3}>
128
+ <Card title="Evaluate a Claude Code / Codex plugin" icon="puzzle-piece" href="/example/claude-code-codex-plugin">
129
+ Drop the plugin into a real workspace and compare pass rate, cost, latency, and behavior with and without it.
130
+ </Card>
131
+ <Card title="Evaluate a Claude Code / Codex Skill" icon="wand-magic-sparkles" href="/example/claude-code-codex-skill">
132
+ Compare coding-agent tasks with and without the Skill to measure whether it actually improves results.
133
+ </Card>
134
+ <Card title="Evaluate your own AI agent application" icon="robot" href="/example/ai-agent-application">
135
+ Connect directly to your app's API and assert on tool calls, image understanding, and multi-turn conversations.
136
+ </Card>
137
+ </CardGroup>
138
+
139
+ ## What to read next
140
+
141
+ [Quickstart](/quickstart) walks through installation, writing the first eval, and getting a report.
@@ -0,0 +1,136 @@
1
+ ---
2
+ title: "Set up evals for your agent project"
3
+ sidebarTitle: "Quickstart"
4
+ description: "Install NiceEval, write three files, and run the first eval against your own application in about 10 minutes."
5
+ ---
6
+
7
+ Connecting your own application takes three files: an **adapter** that calls your app, an **experiment** that chooses what to run, and an **eval** that declares what must be true. Below is the shortest complete path. Scenario-specific guides and the coding-agent handoff path come after it.
8
+
9
+ ## Let AI wire it up for you (recommended)
10
+
11
+ <Steps>
12
+ <Step title="Install">
13
+ ```text
14
+ READ https://niceeval.com/INIT.md and install niceeval for this repo.
15
+ ```
16
+ </Step>
17
+ <Step title="Run evals">
18
+ ```bash
19
+ pnpm exec niceeval exp <experiment-name>
20
+ ```
21
+ </Step>
22
+ <Step title="View results">
23
+ ```bash
24
+ pnpm exec niceeval view
25
+ ```
26
+ </Step>
27
+ </Steps>
28
+
29
+ ## Manual integration
30
+
31
+ ```bash
32
+ pnpm add -D niceeval
33
+ pnpm exec niceeval init
34
+ ```
35
+
36
+ ### Adapter
37
+
38
+ The adapter is the layer between your agent and NiceEval. There are multiple integration tiers, from non-invasive to partially instrumented, which unlock more useful eval features. See [Tier](/concepts/tier).
39
+
40
+ ```ts
41
+ // agents/my-bot.ts
42
+ import { defineAgent } from "niceeval/adapter";
43
+
44
+ export default defineAgent({
45
+ name: "my-bot",
46
+ async send(input, ctx) {
47
+ const r = await fetch("http://localhost:3000/chat", {
48
+ method: "POST",
49
+ headers: { "content-type": "application/json" },
50
+ body: JSON.stringify({ message: input.text, model: ctx.model }),
51
+ signal: ctx.signal,
52
+ });
53
+ const body = await r.json();
54
+ return {
55
+ status: r.ok ? "completed" : "failed",
56
+ events: [{ type: "message", role: "assistant", text: body.reply }],
57
+ };
58
+ },
59
+ });
60
+ ```
61
+
62
+ ### Experiment
63
+
64
+ ```ts
65
+ // experiments/my-bot.ts
66
+ import { defineExperiment } from "niceeval";
67
+ import myBot from "../agents/my-bot.ts";
68
+
69
+ export default defineExperiment({
70
+ description: "my-bot baseline",
71
+ model: "gpt-4o",
72
+ agent: myBot,
73
+ runs: 1,
74
+ });
75
+ ```
76
+
77
+ ### Eval
78
+
79
+ ```ts
80
+ // evals/refund-policy.eval.ts
81
+ import { defineEval } from "niceeval";
82
+ import { includes } from "niceeval/expect";
83
+
84
+ export default defineEval({
85
+ description: "Refund policy question",
86
+ async test(t) {
87
+ await t.send("What is your refund policy?");
88
+ t.succeeded();
89
+ t.check(t.reply, includes("30 days"));
90
+ },
91
+ });
92
+ ```
93
+
94
+ ```bash
95
+ pnpm exec niceeval exp my-bot
96
+ pnpm exec niceeval view
97
+ ```
98
+
99
+ At this point the first eval is running.
100
+
101
+ This minimal adapter is **single-turn**. The second turn will not remember the first until you teach the app how to continue conversation history. Multi-turn sessions, tool-call events that unlock `t.calledTool()`, HITL, and tracing are all optional increments you add later. Follow [Connect Your Agent](/guides/connect-your-agent) step by step. Existing evals do not need to be rewritten.
102
+
103
+ ## Start from a scenario
104
+
105
+ If you already know what you want to evaluate, jump straight into the matching path:
106
+
107
+ <CardGroup cols={3}>
108
+ <Card title="Eval your Claude Code / Codex plugin" icon="plug" href="/example/claude-code-codex-plugin">
109
+ For plugins, hooks, MCP servers, and project-level coding-agent extensions.
110
+ </Card>
111
+ <Card title="Eval your Claude Code / Codex Skill" icon="wand-magic-sparkles" href="/example/claude-code-codex-skill">
112
+ For verifying whether a Skill is triggered, follows the intended workflow, and genuinely improves task success.
113
+ </Card>
114
+ <Card title="Eval your AI agent application" icon="globe" href="/example/ai-agent-application">
115
+ For full examples built on AI SDK, LangGraph, Pi, or a custom agent app.
116
+ </Card>
117
+ </CardGroup>
118
+
119
+ ## Put it in CI
120
+
121
+ ```yaml
122
+ name: evals
123
+ on: [pull_request]
124
+ jobs:
125
+ evals:
126
+ runs-on: ubuntu-latest
127
+ steps:
128
+ - uses: actions/checkout@v4
129
+ - uses: actions/setup-node@v4
130
+ - run: npm ci
131
+ - run: npm exec niceeval exp my-bot
132
+ ```
133
+
134
+ <Tip>
135
+ Next, read [Authoring Evals](/guides/authoring) and [Scoring Guide](/guides/scoring-guide), then replace the example with your real behavior.
136
+ </Tip>