niceeval 0.5.1 → 0.5.3
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.
- package/docs-site/zh/concepts/adapter.mdx +6 -6
- package/docs-site/zh/concepts/experiment.mdx +6 -6
- package/docs-site/zh/concepts/overview.mdx +1 -1
- package/docs-site/zh/concepts/tier.mdx +6 -6
- package/docs-site/zh/guides/ci-integration.mdx +2 -0
- package/docs-site/zh/guides/connect-your-agent.mdx +7 -7
- package/docs-site/zh/guides/custom-reports.mdx +7 -7
- package/docs-site/zh/guides/experiments.mdx +3 -3
- package/docs-site/zh/guides/publish-report.mdx +91 -0
- package/docs-site/zh/guides/report-components.mdx +4 -4
- package/docs-site/zh/guides/reporters.mdx +1 -1
- package/docs-site/zh/guides/results-data.mdx +1 -1
- package/docs-site/zh/guides/runner.mdx +1 -1
- package/docs-site/zh/guides/sandbox-agent.mdx +2 -2
- package/docs-site/zh/guides/viewing-results.mdx +3 -19
- package/docs-site/zh/guides/write-experiment.mdx +9 -9
- package/docs-site/zh/guides/write-send.mdx +6 -6
- package/docs-site/zh/index.mdx +1 -1
- package/docs-site/zh/introduction.mdx +1 -1
- package/docs-site/zh/reference/builtin-agents.mdx +4 -0
- package/docs-site/zh/reference/cli.mdx +10 -6
- package/docs-site/zh/reference/define-agent.mdx +7 -3
- package/docs-site/zh/reference/define-config.mdx +3 -1
- package/docs-site/zh/reference/define-eval.mdx +9 -3
- package/docs-site/zh/reference/events.mdx +4 -0
- package/docs-site/zh/reference/expect.mdx +4 -0
- package/package.json +3 -2
- package/src/agents/ai-sdk.test.ts +1 -1
- package/src/agents/ai-sdk.ts +2 -2
- package/src/agents/claude-code.ts +1 -1
- package/src/agents/codex.ts +2 -2
- package/src/agents/streaming.test.ts +1 -1
- package/src/agents/types.ts +2 -2
- package/src/agents/ui-message-stream.test.ts +1 -1
- package/src/cli.ts +53 -15
- package/src/context/context.test.ts +1 -1
- package/src/context/context.ts +3 -3
- package/src/context/session.ts +2 -2
- package/src/context/types.ts +2 -2
- package/src/i18n/en.ts +2 -2
- package/src/i18n/zh-CN.ts +2 -2
- package/src/report/aggregate.ts +16 -16
- package/src/report/components.tsx +1 -1
- package/src/report/compute.ts +7 -7
- package/src/report/dual-face.test.tsx +1 -1
- package/src/report/{param.ts → flag.ts} +6 -6
- package/src/report/index.ts +3 -3
- package/src/report/react/MetricLine.tsx +1 -1
- package/src/report/react/fixtures.ts +1 -1
- package/src/report/report.test.ts +17 -17
- package/src/report/types.ts +11 -11
- package/src/results/results.test.ts +2 -2
- package/src/runner/attempt.ts +3 -3
- package/src/runner/fingerprint.ts +1 -1
- package/src/runner/reporters/braintrust.test.ts +2 -2
- package/src/runner/reporters/braintrust.ts +3 -3
- package/src/runner/run.ts +1 -1
- package/src/runner/types.ts +8 -8
- package/src/view/app/css.d.ts +3 -0
- package/src/view/app/i18n.ts +3 -3
- package/src/view/app/lib/rows.ts +4 -4
- package/src/view/client-dist/app.js +2 -2
- package/src/view/data.test.ts +25 -1
- package/src/view/data.ts +27 -3
|
@@ -56,6 +56,8 @@ description: "NiceEval 内置的 claude-code、codex、bub 适配器分别做到
|
|
|
56
56
|
|
|
57
57
|
{/* GENERATED:BEGIN builtin-agent-config */}
|
|
58
58
|
|
|
59
|
+
{/* 本区块由 pnpm docs:reference 从源码注释生成,勿手改;要改文案,改对应源码的 TSDoc/JSDoc(映射见 scripts/generate-reference.ts) */}
|
|
60
|
+
|
|
59
61
|
### `ClaudeCodeConfig`
|
|
60
62
|
|
|
61
63
|
#### `apiKey`
|
|
@@ -196,6 +198,8 @@ export default uiMessageStreamAgent({
|
|
|
196
198
|
|
|
197
199
|
{/* GENERATED:BEGIN ui-message-stream-options */}
|
|
198
200
|
|
|
201
|
+
{/* 本区块由 pnpm docs:reference 从源码注释生成,勿手改;要改文案,改对应源码的 TSDoc/JSDoc(映射见 scripts/generate-reference.ts) */}
|
|
202
|
+
|
|
199
203
|
#### `name`
|
|
200
204
|
|
|
201
205
|
```ts
|
|
@@ -4,7 +4,7 @@ sidebarTitle: "命令行"
|
|
|
4
4
|
description: "NiceEval CLI 参考:exp、init、list、clean 和 view 命令,以及 experiment、eval 过滤、sandbox、并发、预算和 JUnit CI 输出。"
|
|
5
5
|
---
|
|
6
6
|
|
|
7
|
-
[NiceEval](https://niceeval.com/) CLI 是发现、运行和查看 eval 的入口。实际执行 eval 时采用 experiment-first 模型:**`exp` 选择可签入的运行配置**,experiment 后的位置参数才按 eval ID 前缀过滤。agent、model 和
|
|
7
|
+
[NiceEval](https://niceeval.com/) CLI 是发现、运行和查看 eval 的入口。实际执行 eval 时采用 experiment-first 模型:**`exp` 选择可签入的运行配置**,experiment 后的位置参数才按 eval ID 前缀过滤。agent、model 和 flags 写在 `experiments/`,不靠临时 CLI 参数。
|
|
8
8
|
|
|
9
9
|
## 命令
|
|
10
10
|
|
|
@@ -56,10 +56,12 @@ npx niceeval exp compare-models weather
|
|
|
56
56
|
|
|
57
57
|
## 常用 flags
|
|
58
58
|
|
|
59
|
-
下表由 CLI 的 flag
|
|
59
|
+
下表由 CLI 的 flag 解析表生成,表外的 flag 一律按未知 flag 报错并以非零状态退出。**没有**用于选择 sandbox 后端的 CLI flag:sandbox 后端只能写在代码里——在 experiment(`defineExperiment`)里设置 `sandbox`,或者在 `niceeval.config.ts`(`defineConfig`)里设置作为项目级兜底,值来自 `niceeval/sandbox` 的 `dockerSandbox()` / `vercelSandbox()` / `e2bSandbox()`。
|
|
60
60
|
|
|
61
61
|
{/* GENERATED:BEGIN cli-flags */}
|
|
62
62
|
|
|
63
|
+
{/* 本区块由 pnpm docs:reference 从源码注释生成,勿手改;要改文案,改对应源码的 TSDoc/JSDoc(映射见 scripts/generate-reference.ts) */}
|
|
64
|
+
|
|
63
65
|
| Flag | 类型 | 说明 |
|
|
64
66
|
|---|---|---|
|
|
65
67
|
| `--agent` | string | experiment 运行不支持该 flag。要换 agent,请在 `experiments/` 下新增或复制一个配置文件。 |
|
|
@@ -70,16 +72,17 @@ npx niceeval exp compare-models weather
|
|
|
70
72
|
| `--budget` | number | 整次运行的预算上限(美元)。 |
|
|
71
73
|
| `--tag` | string | 只运行带有该 tag 的 eval(见 `defineEval` 的 `tags`)。 |
|
|
72
74
|
| `--junit` | string | 额外写一份 JUnit XML 报告到指定路径,供 CI 消费。 |
|
|
75
|
+
| `--json` | string | 额外写一份 JSON 结果(`RunSummary` 原样序列化)到指定路径,供 CI 或下游脚本消费。 |
|
|
73
76
|
| `--out` | string | `view` 命令专用:把结果查看器静态导出到指定目录。 |
|
|
74
77
|
| `--port` | number | `view` 命令专用:指定本地服务器监听端口。 |
|
|
75
78
|
| `--transcript` | boolean | `show` 命令专用:渲染单个 eval 的完整对话与工具调用(证据切面)。 |
|
|
76
79
|
| `--trace` | boolean | `show` 命令专用:渲染单个 eval 的 trace 瀑布文本版(证据切面)。 |
|
|
77
80
|
| `--diff` | boolean | `show` 命令专用:sandbox 里的文件改动摘要;`--diff=<文件路径>` 看单个文件的完整改动(路径必须 `=` 连写)。 |
|
|
78
81
|
| `--history` | boolean | `show` 命令专用:跨 run 时间轴,只列真实执行;与 `--report` 互斥。 |
|
|
79
|
-
| `--experiment` | string | `show` 命令专用:选集只留该实验。 |
|
|
82
|
+
| `--experiment` | string | `show` / `view` 命令专用:选集只留该实验。 |
|
|
80
83
|
| `--attempt` | number | `show` 命令专用:指定详情 / 证据切面看第几次 attempt(与展示一致的 1 计序号)。 |
|
|
81
|
-
| `--run` | string | `show` 命令专用:钉死看某一个结果目录(历史 run 或 `copySnapshots` 产物)。 |
|
|
82
|
-
| `--report` | string | `show` 命令专用:把默认榜单整槽换成你的报告文件(默认导出 `defineReport(...)`)。 |
|
|
84
|
+
| `--run` | string | `show` / `view` 命令专用:钉死看某一个结果目录(历史 run 或 `copySnapshots` 产物)。 |
|
|
85
|
+
| `--report` | string | `show` / `view` 命令专用:把默认榜单整槽换成你的报告文件(默认导出 `defineReport(...)`)。 |
|
|
83
86
|
| `--dry` | boolean | 只打印本次会匹配到的 eval × 运行配置,不实际执行。 |
|
|
84
87
|
| `--quiet` | boolean | 关闭控制台 / live 进度输出(reporter 仍会写 artifacts)。 |
|
|
85
88
|
| `--force` | boolean | 忽略上次运行结果,不跳过已通过的 (experiment, eval) 组合,强制全部重跑。 |
|
|
@@ -87,6 +90,7 @@ npx niceeval exp compare-models weather
|
|
|
87
90
|
| `--early-exit` / `--no-early-exit` | boolean | 某个 eval 的一次 attempt 通过后,停止该 eval 剩余的 attempts。 |
|
|
88
91
|
| `--open` / `--no-open` | boolean | `view` 命令专用:启动后自动打开浏览器(默认行为)。 |
|
|
89
92
|
| `--help` | boolean | 打印用法说明并退出。 |
|
|
93
|
+
| `--version` | boolean | 打印 niceeval 的版本号并退出。 |
|
|
90
94
|
|
|
91
95
|
{/* GENERATED:END cli-flags */}
|
|
92
96
|
|
|
@@ -105,7 +109,7 @@ npx niceeval exp compare-models
|
|
|
105
109
|
npx niceeval exp compare-models weather-tool
|
|
106
110
|
```
|
|
107
111
|
|
|
108
|
-
运行命名 experiment,用矩阵比较 agents、models 或
|
|
112
|
+
运行命名 experiment,用矩阵比较 agents、models 或 flags。第二个参数开始是 eval ID 前缀过滤。
|
|
109
113
|
|
|
110
114
|
## `view`
|
|
111
115
|
|
|
@@ -80,6 +80,8 @@ export default defineExperiment({
|
|
|
80
80
|
|
|
81
81
|
{/* GENERATED:BEGIN agent-def */}
|
|
82
82
|
|
|
83
|
+
{/* 本区块由 pnpm docs:reference 从源码注释生成,勿手改;要改文案,改对应源码的 TSDoc/JSDoc(映射见 scripts/generate-reference.ts) */}
|
|
84
|
+
|
|
83
85
|
### `RemoteAgentDef`
|
|
84
86
|
|
|
85
87
|
#### `name`
|
|
@@ -214,13 +216,13 @@ readonly reasoningEffort?: string;
|
|
|
214
216
|
|
|
215
217
|
模型推理努力程度;归属同 model——实验决定,省略时不覆盖 agent 原生默认。
|
|
216
218
|
|
|
217
|
-
#### `
|
|
219
|
+
#### `flags`
|
|
218
220
|
|
|
219
221
|
```ts
|
|
220
|
-
readonly
|
|
222
|
+
readonly flags: Readonly<Record<string, unknown>>;
|
|
221
223
|
```
|
|
222
224
|
|
|
223
|
-
experiment 的 `
|
|
225
|
+
experiment 的 `flags` 字段原样透传,内容和结构完全由 experiment 作者自定义
|
|
224
226
|
(如 `{ webResearch: true }`、`{ systemPrompt: "..." }`)。adapter 按自己的约定
|
|
225
227
|
读取其中的字段;框架本身不解释、不校验它的内容。命名特意避开 CLI 解析出的
|
|
226
228
|
`flag`(跑法层面的 --timeout/--budget 等),两者是不相关的概念。
|
|
@@ -280,6 +282,8 @@ log(msg: string): void;
|
|
|
280
282
|
|
|
281
283
|
{/* GENERATED:BEGIN sandbox-methods */}
|
|
282
284
|
|
|
285
|
+
{/* 本区块由 pnpm docs:reference 从源码注释生成,勿手改;要改文案,改对应源码的 TSDoc/JSDoc(映射见 scripts/generate-reference.ts) */}
|
|
286
|
+
|
|
283
287
|
### `Sandbox`
|
|
284
288
|
|
|
285
289
|
#### `workdir`
|
|
@@ -4,7 +4,7 @@ sidebarTitle: "defineConfig"
|
|
|
4
4
|
description: "defineConfig 参考:judge、reporters、并发、超时和 sandbox 默认值。"
|
|
5
5
|
---
|
|
6
6
|
|
|
7
|
-
`defineConfig` 从根目录的 `niceeval.config.ts` 默认导出,只放项目级默认值。agent、model、
|
|
7
|
+
`defineConfig` 从根目录的 `niceeval.config.ts` 默认导出,只放项目级默认值。agent、model、flags、runs 和实验预算写在 `experiments/` 下的 `defineExperiment` 文件里。
|
|
8
8
|
|
|
9
9
|
```ts
|
|
10
10
|
import { defineConfig } from "niceeval";
|
|
@@ -20,6 +20,8 @@ export default defineConfig({
|
|
|
20
20
|
|
|
21
21
|
{/* GENERATED:BEGIN config-fields */}
|
|
22
22
|
|
|
23
|
+
{/* 本区块由 pnpm docs:reference 从源码注释生成,勿手改;要改文案,改对应源码的 TSDoc/JSDoc(映射见 scripts/generate-reference.ts) */}
|
|
24
|
+
|
|
23
25
|
#### `name`
|
|
24
26
|
|
|
25
27
|
```ts
|
|
@@ -26,6 +26,8 @@ export default defineEval({
|
|
|
26
26
|
|
|
27
27
|
{/* GENERATED:BEGIN defineeval-options */}
|
|
28
28
|
|
|
29
|
+
{/* 本区块由 pnpm docs:reference 从源码注释生成,勿手改;要改文案,改对应源码的 TSDoc/JSDoc(映射见 scripts/generate-reference.ts) */}
|
|
30
|
+
|
|
29
31
|
#### `id`
|
|
30
32
|
|
|
31
33
|
```ts
|
|
@@ -108,6 +110,8 @@ eval 主体:拿到 TestContext,驱动对话 / 沙箱操作并就地断言。
|
|
|
108
110
|
|
|
109
111
|
{/* GENERATED:BEGIN test-context */}
|
|
110
112
|
|
|
113
|
+
{/* 本区块由 pnpm docs:reference 从源码注释生成,勿手改;要改文案,改对应源码的 TSDoc/JSDoc(映射见 scripts/generate-reference.ts) */}
|
|
114
|
+
|
|
111
115
|
#### `send`
|
|
112
116
|
|
|
113
117
|
```ts
|
|
@@ -207,13 +211,13 @@ readonly reasoningEffort?: string;
|
|
|
207
211
|
|
|
208
212
|
本次 attempt 的推理努力程度(如 "low"/"medium"/"high",取值由 adapter/模型决定)。
|
|
209
213
|
|
|
210
|
-
#### `
|
|
214
|
+
#### `flags`
|
|
211
215
|
|
|
212
216
|
```ts
|
|
213
|
-
readonly
|
|
217
|
+
readonly flags: Readonly<Record<string, unknown>>;
|
|
214
218
|
```
|
|
215
219
|
|
|
216
|
-
本次 attempt
|
|
220
|
+
本次 attempt 生效的实验 flags(experiment.flags 的只读视图;实验条件,非命令行开关)。
|
|
217
221
|
|
|
218
222
|
#### `log`
|
|
219
223
|
|
|
@@ -440,6 +444,8 @@ t.judge.autoevals.summarizes(sourceText, { on: t.reply }).atLeast(0.7);
|
|
|
440
444
|
|
|
441
445
|
{/* GENERATED:BEGIN turn-handle */}
|
|
442
446
|
|
|
447
|
+
{/* 本区块由 pnpm docs:reference 从源码注释生成,勿手改;要改文案,改对应源码的 TSDoc/JSDoc(映射见 scripts/generate-reference.ts) */}
|
|
448
|
+
|
|
443
449
|
#### `events`
|
|
444
450
|
|
|
445
451
|
```ts
|
|
@@ -23,6 +23,8 @@ interface Turn {
|
|
|
23
23
|
|
|
24
24
|
{/* GENERATED:BEGIN usage-fields */}
|
|
25
25
|
|
|
26
|
+
{/* 本区块由 pnpm docs:reference 从源码注释生成,勿手改;要改文案,改对应源码的 TSDoc/JSDoc(映射见 scripts/generate-reference.ts) */}
|
|
27
|
+
|
|
26
28
|
#### `inputTokens`
|
|
27
29
|
|
|
28
30
|
```ts
|
|
@@ -81,6 +83,8 @@ token 用量或 OTel span 反推得到)。存在时优先于按价格表(`define
|
|
|
81
83
|
|
|
82
84
|
{/* GENERATED:BEGIN stream-events */}
|
|
83
85
|
|
|
86
|
+
{/* 本区块由 pnpm docs:reference 从源码注释生成,勿手改;要改文案,改对应源码的 TSDoc/JSDoc(映射见 scripts/generate-reference.ts) */}
|
|
87
|
+
|
|
84
88
|
#### `message`
|
|
85
89
|
|
|
86
90
|
```ts
|
|
@@ -29,6 +29,8 @@ t.require(turn.status, equals("completed"));
|
|
|
29
29
|
|
|
30
30
|
{/* GENERATED:BEGIN expect-matchers */}
|
|
31
31
|
|
|
32
|
+
{/* 本区块由 pnpm docs:reference 从源码注释生成,勿手改;要改文案,改对应源码的 TSDoc/JSDoc(映射见 scripts/generate-reference.ts) */}
|
|
33
|
+
|
|
32
34
|
#### `includes`
|
|
33
35
|
|
|
34
36
|
```ts
|
|
@@ -150,6 +152,8 @@ t.check(t.reply, includes("nice to have").atLeast(0.7));
|
|
|
150
152
|
|
|
151
153
|
{/* GENERATED:BEGIN value-assertion */}
|
|
152
154
|
|
|
155
|
+
{/* 本区块由 pnpm docs:reference 从源码注释生成,勿手改;要改文案,改对应源码的 TSDoc/JSDoc(映射见 scripts/generate-reference.ts) */}
|
|
156
|
+
|
|
153
157
|
#### `name`
|
|
154
158
|
|
|
155
159
|
```ts
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "niceeval",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.3",
|
|
4
4
|
"description": "Agent-native eval tool — eval agents, services, functions, and coding-agent fixtures",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -100,7 +100,8 @@
|
|
|
100
100
|
"shiki": "^4.3.0",
|
|
101
101
|
"tailwind-merge": "^3.6.0",
|
|
102
102
|
"tailwindcss": "^4.3.1",
|
|
103
|
-
"typescript": "
|
|
103
|
+
"typescript": "npm:@typescript/typescript6@^6.0.2",
|
|
104
|
+
"@typescript/native": "npm:typescript@^7.0.2",
|
|
104
105
|
"vite": "^8.1.0",
|
|
105
106
|
"vitest": "^4.1.9"
|
|
106
107
|
},
|
|
@@ -454,7 +454,7 @@ function fakeCtx(opts: { id?: string } = {}): AgentContext {
|
|
|
454
454
|
return {
|
|
455
455
|
signal: new AbortController().signal,
|
|
456
456
|
model: undefined,
|
|
457
|
-
|
|
457
|
+
flags: {},
|
|
458
458
|
sandbox: undefined as unknown as AgentContext["sandbox"],
|
|
459
459
|
session,
|
|
460
460
|
log: () => {},
|
package/src/agents/ai-sdk.ts
CHANGED
|
@@ -367,7 +367,7 @@ export interface AiSdkGenerateContext<M = unknown> {
|
|
|
367
367
|
/** 实验钉的推理努力程度(ctx.reasoningEffort);省略 → 用应用自己的默认。应用自己决定怎么塞进 providerOptions(如 OpenAI 的 reasoningEffort)。 */
|
|
368
368
|
readonly reasoningEffort?: string;
|
|
369
369
|
readonly signal: AbortSignal;
|
|
370
|
-
readonly
|
|
370
|
+
readonly flags: Readonly<Record<string, unknown>>;
|
|
371
371
|
/**
|
|
372
372
|
* 配了 `tracing`(如 `aiSdkOtel()`)才有:直接放进 generateText / streamText 的
|
|
373
373
|
* `telemetry` 选项。OTel provider、per-attempt 端点绑定和轮末 flush 都由工厂做,
|
|
@@ -505,7 +505,7 @@ export function aiSdkAgent<M = unknown>(options: AiSdkAgentOptions<M>): Agent {
|
|
|
505
505
|
model: ctx.model,
|
|
506
506
|
reasoningEffort: ctx.reasoningEffort,
|
|
507
507
|
signal: ctx.signal,
|
|
508
|
-
|
|
508
|
+
flags: ctx.flags,
|
|
509
509
|
telemetry: otel?.settings,
|
|
510
510
|
});
|
|
511
511
|
} catch (error) {
|
|
@@ -94,7 +94,7 @@ export function claudeCodeAgent(config?: ClaudeCodeConfig): Agent {
|
|
|
94
94
|
const args = ["--print", "--dangerously-skip-permissions"];
|
|
95
95
|
if (ctx.model) args.push("--model", ctx.model);
|
|
96
96
|
if (config?.maxTurns != null) args.push("--max-turns", String(config.maxTurns));
|
|
97
|
-
if (ctx.
|
|
97
|
+
if (ctx.flags.webResearch) args.push("--allowedTools", "WebSearch,WebFetch");
|
|
98
98
|
if (ctx.session.id) args.push("--resume", ctx.session.id);
|
|
99
99
|
args.push(input.text);
|
|
100
100
|
|
package/src/agents/codex.ts
CHANGED
|
@@ -9,7 +9,7 @@ import type { Agent, McpServer } from "../types.ts";
|
|
|
9
9
|
//
|
|
10
10
|
// 连接方式:在沙箱里 spawn `codex exec --json`,stdout JSONL → parseCodex → 标准事件流。
|
|
11
11
|
// 配置:鉴权本地(config / env),模型交给实验(ctx.model),推理努力程度经 ctx.reasoningEffort
|
|
12
|
-
// (兼容旧的 ctx.
|
|
12
|
+
// (兼容旧的 ctx.flags.effort),其余参数经 ctx.flags。
|
|
13
13
|
// ───────────────────────────────────────────────────────────────────────────
|
|
14
14
|
|
|
15
15
|
export interface CodexConfig {
|
|
@@ -44,7 +44,7 @@ export function codexAgent(config?: CodexConfig): Agent {
|
|
|
44
44
|
// model 归属:实验决定(ctx.model);省略时不写 model 行,交给 codex CLI 原生默认,
|
|
45
45
|
// 不在 adapter 里硬编码一个会过期的模型名。
|
|
46
46
|
const modelLine = ctx.model ? `model = "${ctx.model}"\n` : "";
|
|
47
|
-
const effort = ctx.reasoningEffort ?? (ctx.
|
|
47
|
+
const effort = ctx.reasoningEffort ?? (ctx.flags.effort as string | undefined) ?? "medium";
|
|
48
48
|
const base = getBaseUrl();
|
|
49
49
|
|
|
50
50
|
if (base) {
|
package/src/agents/types.ts
CHANGED
|
@@ -155,12 +155,12 @@ export interface AgentContext {
|
|
|
155
155
|
/** 模型推理努力程度;归属同 model——实验决定,省略时不覆盖 agent 原生默认。 */
|
|
156
156
|
readonly reasoningEffort?: string;
|
|
157
157
|
/**
|
|
158
|
-
* experiment 的 `
|
|
158
|
+
* experiment 的 `flags` 字段原样透传,内容和结构完全由 experiment 作者自定义
|
|
159
159
|
* (如 `{ webResearch: true }`、`{ systemPrompt: "..." }`)。adapter 按自己的约定
|
|
160
160
|
* 读取其中的字段;框架本身不解释、不校验它的内容。命名特意避开 CLI 解析出的
|
|
161
161
|
* `flag`(跑法层面的 --timeout/--budget 等),两者是不相关的概念。
|
|
162
162
|
*/
|
|
163
|
-
readonly
|
|
163
|
+
readonly flags: Readonly<Record<string, unknown>>;
|
|
164
164
|
/** 仅沙箱型 agent 有(运行器按 --sandbox 备好)。 */
|
|
165
165
|
readonly sandbox: Sandbox;
|
|
166
166
|
readonly session: AgentSession;
|
|
@@ -73,7 +73,7 @@ function ctx(overrides: Partial<{ model: string }> = {}): AgentContext {
|
|
|
73
73
|
return {
|
|
74
74
|
signal: new AbortController().signal,
|
|
75
75
|
model: overrides.model,
|
|
76
|
-
|
|
76
|
+
flags: {},
|
|
77
77
|
sandbox: undefined as never,
|
|
78
78
|
// 同一个 ctx 重复用 = 同一条会话线(续接,同一个 ctx.session);新造 = 新线。
|
|
79
79
|
session: createAgentSession(),
|
package/src/cli.ts
CHANGED
|
@@ -17,7 +17,7 @@ import { stopAllSandboxes, liveSandboxCount } from "./sandbox/registry.ts";
|
|
|
17
17
|
import { evalLevelStats } from "./shared/outcome.ts";
|
|
18
18
|
import { sandboxRecommendedConcurrency } from "./sandbox/resolve.ts";
|
|
19
19
|
import { Console as ConsoleReporter } from "./runner/reporters/console.ts";
|
|
20
|
-
import { JUnit } from "./runner/reporters/json.ts";
|
|
20
|
+
import { Json, JUnit } from "./runner/reporters/json.ts";
|
|
21
21
|
import { Live as LiveReporter, type LiveRow } from "./runner/reporters/live.ts";
|
|
22
22
|
import { Artifacts as ArtifactsReporter } from "./runner/reporters/artifacts.ts";
|
|
23
23
|
import {
|
|
@@ -60,10 +60,12 @@ interface Flags {
|
|
|
60
60
|
budget?: number;
|
|
61
61
|
tag?: string;
|
|
62
62
|
junit?: string;
|
|
63
|
+
json?: string;
|
|
63
64
|
open?: boolean;
|
|
64
65
|
out?: string;
|
|
65
66
|
port?: number;
|
|
66
67
|
help: boolean;
|
|
68
|
+
version: boolean;
|
|
67
69
|
// ── show 专属(位置参数仍是 eval id 前缀;这些 flag 选「怎么看」)──
|
|
68
70
|
transcript: boolean;
|
|
69
71
|
trace: boolean;
|
|
@@ -79,43 +81,70 @@ interface Flags {
|
|
|
79
81
|
|
|
80
82
|
// 表驱动的 flag 定义(node:util parseArgs)。--no-x 显式声明,不依赖 allowNegative(需 Node 20.14+,
|
|
81
83
|
// engines 是 >=18)。未知 flag 由 strict 模式报清晰错误,不再静默吞掉后面的位置参数。
|
|
84
|
+
//
|
|
85
|
+
// 每个 flag 的 JSDoc 就是它在 docs-site/zh/reference/cli.mdx flag 表里的说明,由
|
|
86
|
+
// scripts/generate-reference.ts 提取渲染——改 flag 语义时改这里的注释即可,不用碰生成脚本。
|
|
87
|
+
// 负向 flag(no-x)与正向 flag 合并成一行展示,不需要单独写 JSDoc。
|
|
82
88
|
const FLAG_OPTIONS = {
|
|
89
|
+
/** experiment 运行不支持该 flag。要换 agent,请在 `experiments/` 下新增或复制一个配置文件。 */
|
|
83
90
|
agent: { type: "string" },
|
|
91
|
+
/** experiment 运行不支持该 flag。要换模型,请新增或复制一个 experiment 文件并修改 `model`。 */
|
|
84
92
|
model: { type: "string" },
|
|
93
|
+
/** 每个 eval 运行多少次,常用于 pass@N。 */
|
|
85
94
|
runs: { type: "string" },
|
|
95
|
+
/** 设置同时运行的 eval 数量。 */
|
|
86
96
|
"max-concurrency": { type: "string" },
|
|
97
|
+
/** 单个 attempt 的超时时间,单位毫秒。 */
|
|
87
98
|
timeout: { type: "string" },
|
|
99
|
+
/** 整次运行的预算上限(美元)。 */
|
|
88
100
|
budget: { type: "string" },
|
|
101
|
+
/** 只运行带有该 tag 的 eval(见 `defineEval` 的 `tags`)。 */
|
|
89
102
|
tag: { type: "string" },
|
|
103
|
+
/** 额外写一份 JUnit XML 报告到指定路径,供 CI 消费。 */
|
|
90
104
|
junit: { type: "string" },
|
|
105
|
+
/** 额外写一份 JSON 结果(`RunSummary` 原样序列化)到指定路径,供 CI 或下游脚本消费。 */
|
|
106
|
+
json: { type: "string" },
|
|
107
|
+
/** `view` 命令专用:把结果查看器静态导出到指定目录。 */
|
|
91
108
|
out: { type: "string" },
|
|
109
|
+
/** `view` 命令专用:指定本地服务器监听端口。 */
|
|
92
110
|
port: { type: "string" },
|
|
93
|
-
// --sandbox 已移除(sandbox 归 config/experiment);留着解析是为了给出迁移提示而非「未知 flag」。
|
|
94
|
-
sandbox: { type: "string" },
|
|
95
|
-
// --watch / --json:文档曾接受、尚未实现的 flag。容忍(no-op)而不是硬报「未知 flag」,
|
|
96
|
-
// 免得照旧文档写的脚本直接崩;真正实现前不接任何行为。
|
|
97
|
-
watch: { type: "boolean" },
|
|
98
|
-
json: { type: "boolean" },
|
|
99
111
|
// show 的证据切面 / 时间轴 / 报告装载(docs-site/zh/guides/viewing-results.mdx)。
|
|
112
|
+
/** `show` 命令专用:渲染单个 eval 的完整对话与工具调用(证据切面)。 */
|
|
100
113
|
transcript: { type: "boolean" },
|
|
114
|
+
/** `show` 命令专用:渲染单个 eval 的 trace 瀑布文本版(证据切面)。 */
|
|
101
115
|
trace: { type: "boolean" },
|
|
102
116
|
// --diff 是布尔;--diff=<路径> 在 parseArgs 前预扫成 diffPath(路径必须 = 连写,
|
|
103
117
|
// 空格形式的下一个 token 仍是位置参数 = eval id 前缀,与文档一致)。
|
|
118
|
+
/** `show` 命令专用:sandbox 里的文件改动摘要;`--diff=<文件路径>` 看单个文件的完整改动(路径必须 `=` 连写)。 */
|
|
104
119
|
diff: { type: "boolean" },
|
|
120
|
+
/** `show` 命令专用:跨 run 时间轴,只列真实执行;与 `--report` 互斥。 */
|
|
105
121
|
history: { type: "boolean" },
|
|
122
|
+
/** `show` / `view` 命令专用:选集只留该实验。 */
|
|
106
123
|
experiment: { type: "string" },
|
|
124
|
+
/** `show` 命令专用:指定详情 / 证据切面看第几次 attempt(与展示一致的 1 计序号)。 */
|
|
107
125
|
attempt: { type: "string" },
|
|
126
|
+
/** `show` / `view` 命令专用:钉死看某一个结果目录(历史 run 或 `copySnapshots` 产物)。 */
|
|
108
127
|
run: { type: "string" },
|
|
128
|
+
/** `show` / `view` 命令专用:把默认榜单整槽换成你的报告文件(默认导出 `defineReport(...)`)。 */
|
|
109
129
|
report: { type: "string" },
|
|
130
|
+
/** 只打印本次会匹配到的 eval × 运行配置,不实际执行。 */
|
|
110
131
|
dry: { type: "boolean" },
|
|
132
|
+
/** 关闭控制台 / live 进度输出(reporter 仍会写 artifacts)。 */
|
|
111
133
|
quiet: { type: "boolean" },
|
|
134
|
+
/** 忽略上次运行结果,不跳过已通过的 (experiment, eval) 组合,强制全部重跑。 */
|
|
112
135
|
force: { type: "boolean" },
|
|
136
|
+
/** CI 中推荐使用:让软阈值(`soft`)失败也计入整条 eval 的 outcome。 */
|
|
113
137
|
strict: { type: "boolean" },
|
|
138
|
+
/** 某个 eval 的一次 attempt 通过后,停止该 eval 剩余的 attempts。 */
|
|
114
139
|
"early-exit": { type: "boolean" },
|
|
115
140
|
"no-early-exit": { type: "boolean" },
|
|
141
|
+
/** `view` 命令专用:启动后自动打开浏览器(默认行为)。 */
|
|
116
142
|
open: { type: "boolean" },
|
|
117
143
|
"no-open": { type: "boolean" },
|
|
144
|
+
/** 打印用法说明并退出。 */
|
|
118
145
|
help: { type: "boolean", short: "h" },
|
|
146
|
+
/** 打印 niceeval 的版本号并退出。 */
|
|
147
|
+
version: { type: "boolean", short: "v" },
|
|
119
148
|
} as const;
|
|
120
149
|
|
|
121
150
|
function numberFlag(name: string, raw: string | undefined): number | undefined {
|
|
@@ -153,11 +182,6 @@ function parseArgs(argv: string[]): { command: string; positionals: string[]; fl
|
|
|
153
182
|
process.exit(1);
|
|
154
183
|
}
|
|
155
184
|
|
|
156
|
-
if (values.sandbox !== undefined) {
|
|
157
|
-
process.stderr.write(t("cli.sandboxFlagRemoved"));
|
|
158
|
-
process.exit(1);
|
|
159
|
-
}
|
|
160
|
-
|
|
161
185
|
// 第一个位置参数若是已知命令,则为命令;其余是 eval id 前缀 / view 输入。
|
|
162
186
|
const commands = new Set(["exp", "show", "list", "view", "clean", "init", "watch", "run"]);
|
|
163
187
|
let command = "run";
|
|
@@ -176,6 +200,7 @@ function parseArgs(argv: string[]): { command: string; positionals: string[]; fl
|
|
|
176
200
|
budget: numberFlag("budget", values.budget as string | undefined),
|
|
177
201
|
tag: values.tag as string | undefined,
|
|
178
202
|
junit: values.junit as string | undefined,
|
|
203
|
+
json: values.json as string | undefined,
|
|
179
204
|
out: values.out as string | undefined,
|
|
180
205
|
port: numberFlag("port", values.port as string | undefined),
|
|
181
206
|
dry: values.dry === true,
|
|
@@ -185,6 +210,7 @@ function parseArgs(argv: string[]): { command: string; positionals: string[]; fl
|
|
|
185
210
|
earlyExit: values["no-early-exit"] === true ? false : values["early-exit"] === true ? true : undefined,
|
|
186
211
|
open: values["no-open"] === true ? false : values.open === true ? true : undefined,
|
|
187
212
|
help: values.help === true,
|
|
213
|
+
version: values.version === true,
|
|
188
214
|
transcript: values.transcript === true,
|
|
189
215
|
trace: values.trace === true,
|
|
190
216
|
diff: values.diff === true && diffPath === undefined,
|
|
@@ -324,17 +350,28 @@ function evalsFilterFromExperiment(
|
|
|
324
350
|
return (id) => expFilter(id) && patternFilter(id);
|
|
325
351
|
}
|
|
326
352
|
|
|
353
|
+
/** package.json 的 version 字段;-v/--version 直接回显这个号。 */
|
|
354
|
+
async function packageVersion(): Promise<string> {
|
|
355
|
+
const raw = await readFile(new URL("../package.json", import.meta.url), "utf-8");
|
|
356
|
+
return (JSON.parse(raw) as { version: string }).version;
|
|
357
|
+
}
|
|
358
|
+
|
|
327
359
|
async function main(): Promise<void> {
|
|
328
360
|
const cwd = process.cwd();
|
|
329
361
|
await loadDotenv(cwd);
|
|
330
362
|
const { command, positionals, flags } = parseArgs(process.argv.slice(2));
|
|
331
363
|
|
|
332
|
-
// --help 不需要 config,先于一切命令处理。
|
|
364
|
+
// --help / --version 不需要 config,先于一切命令处理。
|
|
333
365
|
if (flags.help) {
|
|
334
366
|
process.stdout.write(t("cli.help"));
|
|
335
367
|
process.exit(0);
|
|
336
368
|
}
|
|
337
369
|
|
|
370
|
+
if (flags.version) {
|
|
371
|
+
process.stdout.write(`${await packageVersion()}\n`);
|
|
372
|
+
process.exit(0);
|
|
373
|
+
}
|
|
374
|
+
|
|
338
375
|
if (command === "view") {
|
|
339
376
|
// 位置参数 = eval id 前缀(收窄报告槽选集);存在的文件路径 = 单文件模式;
|
|
340
377
|
// 结果目录经 --run 递入;--report 整槽替换报告槽(与 show --report 吃同一个文件)。
|
|
@@ -435,7 +472,7 @@ async function main(): Promise<void> {
|
|
|
435
472
|
agent: exp.agent,
|
|
436
473
|
model: exp.model,
|
|
437
474
|
reasoningEffort: exp.reasoningEffort,
|
|
438
|
-
|
|
475
|
+
flags: exp.flags ?? {},
|
|
439
476
|
runs: flags.runs ?? envNumber("NICEEVAL_RUNS") ?? exp.runs ?? 1,
|
|
440
477
|
earlyExit: flags.earlyExit ?? exp.earlyExit ?? true,
|
|
441
478
|
sandbox: exp.sandbox ?? config.sandbox,
|
|
@@ -451,7 +488,7 @@ async function main(): Promise<void> {
|
|
|
451
488
|
}
|
|
452
489
|
} else {
|
|
453
490
|
// 裸 run / `niceeval <eval>` 不再执行。运行配置必须来自 experiments/,
|
|
454
|
-
// 这样 agent/model/
|
|
491
|
+
// 这样 agent/model/flags/runs/budget 与结果聚合都有可签入的身份。
|
|
455
492
|
const experiments = await discoverExperiments(cwd);
|
|
456
493
|
const asExp = experiments.filter((e) =>
|
|
457
494
|
positionals.some((p) => e.group === p || e.id === p || e.id.startsWith(p + "/")),
|
|
@@ -512,6 +549,7 @@ async function main(): Promise<void> {
|
|
|
512
549
|
const artifacts = ArtifactsReporter();
|
|
513
550
|
reporters.push(artifacts);
|
|
514
551
|
if (flags.junit) reporters.push(JUnit(flags.junit));
|
|
552
|
+
if (flags.json) reporters.push(Json(flags.json));
|
|
515
553
|
reporters.push(...(config.reporters ?? []));
|
|
516
554
|
|
|
517
555
|
// Ctrl+C / kill 的三级响应,核心目标:任何情况下都不留下孤儿沙箱。
|
package/src/context/context.ts
CHANGED
|
@@ -61,7 +61,7 @@ export interface ContextDeps {
|
|
|
61
61
|
sandbox: Sandbox;
|
|
62
62
|
model?: string;
|
|
63
63
|
reasoningEffort?: string;
|
|
64
|
-
|
|
64
|
+
flags: Record<string, unknown>;
|
|
65
65
|
signal: AbortSignal;
|
|
66
66
|
log(msg: string): void;
|
|
67
67
|
judge: JudgeConfig | undefined;
|
|
@@ -92,7 +92,7 @@ export function createEvalContext(deps: ContextDeps): { context: TestContext; st
|
|
|
92
92
|
sandbox: deps.sandbox,
|
|
93
93
|
model: deps.model,
|
|
94
94
|
reasoningEffort: deps.reasoningEffort,
|
|
95
|
-
|
|
95
|
+
flags: deps.flags,
|
|
96
96
|
signal: deps.signal,
|
|
97
97
|
log: deps.log,
|
|
98
98
|
telemetry: deps.telemetry,
|
|
@@ -284,7 +284,7 @@ export function createEvalContext(deps: ContextDeps): { context: TestContext; st
|
|
|
284
284
|
signal: deps.signal,
|
|
285
285
|
model: deps.model,
|
|
286
286
|
reasoningEffort: deps.reasoningEffort,
|
|
287
|
-
|
|
287
|
+
flags: deps.flags,
|
|
288
288
|
log: deps.log,
|
|
289
289
|
skip: (reason: string) => {
|
|
290
290
|
if (reason.trim().length === 0) throw new Error(t("context.skipEmpty"));
|
package/src/context/session.ts
CHANGED
|
@@ -88,7 +88,7 @@ export interface SessionDeps {
|
|
|
88
88
|
sandbox: Sandbox;
|
|
89
89
|
model?: string;
|
|
90
90
|
reasoningEffort?: string;
|
|
91
|
-
|
|
91
|
+
flags: Record<string, unknown>;
|
|
92
92
|
signal: AbortSignal;
|
|
93
93
|
log(msg: string): void;
|
|
94
94
|
/** tracing agent 的 OTLP 端点(经 send ctx 透给 adapter,用于注入导出 env)。 */
|
|
@@ -138,7 +138,7 @@ export class SessionManager {
|
|
|
138
138
|
signal: this.deps.signal,
|
|
139
139
|
model: this.deps.model,
|
|
140
140
|
reasoningEffort: this.deps.reasoningEffort,
|
|
141
|
-
|
|
141
|
+
flags: this.deps.flags,
|
|
142
142
|
sandbox: this.deps.sandbox,
|
|
143
143
|
session,
|
|
144
144
|
telemetry: this.deps.telemetry,
|
package/src/context/types.ts
CHANGED
|
@@ -274,8 +274,8 @@ export interface TestContext {
|
|
|
274
274
|
readonly model?: string;
|
|
275
275
|
/** 本次 attempt 的推理努力程度(如 "low"/"medium"/"high",取值由 adapter/模型决定)。 */
|
|
276
276
|
readonly reasoningEffort?: string;
|
|
277
|
-
/** 本次 attempt
|
|
278
|
-
readonly
|
|
277
|
+
/** 本次 attempt 生效的实验 flags(experiment.flags 的只读视图;实验条件,非命令行开关)。 */
|
|
278
|
+
readonly flags: Readonly<Record<string, unknown>>;
|
|
279
279
|
/** 打一行调试日志;有 live 进度回调时走该回调,否则落到 stderr,不出现在最终结果里。 */
|
|
280
280
|
log(msg: string): void;
|
|
281
281
|
/** 立即中止本 eval 并标记为 skipped(outcome / EvalResult.skipReason),reason 不能为空。 */
|
package/src/i18n/en.ts
CHANGED
|
@@ -59,7 +59,7 @@ export const en = {
|
|
|
59
59
|
"Flags:\n" +
|
|
60
60
|
" --runs n --max-concurrency n --timeout ms --budget usd --tag t\n" +
|
|
61
61
|
" --early-exit / --no-early-exit --strict --force --dry --quiet\n" +
|
|
62
|
-
" --junit path --out dir --port n --open / --no-open -h, --help\n\n" +
|
|
62
|
+
" --junit path --json path --out dir --port n --open / --no-open -h, --help -v, --version\n\n" +
|
|
63
63
|
"Positional args only select which evals to run (id prefixes); which agent and\n" +
|
|
64
64
|
"how to run come from experiments/ + flags. Env overrides (flag > env > config):\n" +
|
|
65
65
|
" NICEEVAL_RUNS NICEEVAL_MAX_CONCURRENCY NICEEVAL_TIMEOUT NICEEVAL_BUDGET\n",
|
|
@@ -94,10 +94,10 @@ export const en = {
|
|
|
94
94
|
" Docs: node_modules/niceeval/docs-site/zh/guides/write-experiment.mdx\n",
|
|
95
95
|
"cli.run.experimentRequiredHint": "Hint: \"{{pattern}}\" is an experiment{{kind}}; you probably meant: niceeval exp {{pattern}}\n",
|
|
96
96
|
"cli.run.experimentRequiredKnown": "Discovered experiments: {{experiments}}\n",
|
|
97
|
-
"cli.sandboxFlagRemoved": "`--sandbox` is not a CLI flag. Set `sandbox` in the experiment (or `niceeval.config.ts` as a project-wide fallback) to dockerSandbox() / vercelSandbox() / e2bSandbox() (import from \"niceeval/sandbox\").\n",
|
|
98
97
|
"cli.unimplemented": "Command \"{{command}}\" is not implemented yet (MVP).\n",
|
|
99
98
|
"cli.view.exportedDir": "Exported static report site: {{out}} (serve the whole directory with any static host; opening index.html via file:// cannot fetch artifacts)\n",
|
|
100
99
|
"cli.view.incompatible": "{{dir}}: written by niceeval {{producer}} (schemaVersion {{schemaVersion}}); this CLI reads schemaVersion {{supported}}.\nRun `{{command}}` to view it.\n",
|
|
100
|
+
"cli.view.noResults": "No results found under {{root}}. Run `niceeval exp` first, then `niceeval view`.\n",
|
|
101
101
|
"cli.view.incompatibleForeign": "{{dir}}: written by {{name}} {{version}} (schemaVersion {{schemaVersion}}); this CLI reads schemaVersion {{supported}}.\nOpen this report with the tool that produced it.\n",
|
|
102
102
|
"cli.view.url": "niceeval view: {{url}}\n",
|
|
103
103
|
"context.capabilityMissing":
|
package/src/i18n/zh-CN.ts
CHANGED
|
@@ -55,7 +55,7 @@ export const zhCN = {
|
|
|
55
55
|
"标志:\n" +
|
|
56
56
|
" --runs n --max-concurrency n --timeout ms --budget usd --tag t\n" +
|
|
57
57
|
" --early-exit / --no-early-exit --strict --force --dry --quiet\n" +
|
|
58
|
-
" --junit path --out dir --port n --open / --no-open -h, --help\n\n" +
|
|
58
|
+
" --junit path --json path --out dir --port n --open / --no-open -h, --help -v, --version\n\n" +
|
|
59
59
|
"位置参数只选「跑哪些 eval」(id 前缀);对着哪个 agent、怎么跑来自 experiments/ 与\n" +
|
|
60
60
|
"标志。环境变量覆盖(标志 > 环境变量 > config):\n" +
|
|
61
61
|
" NICEEVAL_RUNS NICEEVAL_MAX_CONCURRENCY NICEEVAL_TIMEOUT NICEEVAL_BUDGET\n",
|
|
@@ -91,10 +91,10 @@ export const zhCN = {
|
|
|
91
91
|
" 文档:node_modules/niceeval/docs-site/zh/guides/write-experiment.mdx\n",
|
|
92
92
|
"cli.run.experimentRequiredHint": "提示:\"{{pattern}}\" 是实验{{kind}},你大概想跑:niceeval exp {{pattern}}\n",
|
|
93
93
|
"cli.run.experimentRequiredKnown": "已发现实验:{{experiments}}\n",
|
|
94
|
-
"cli.sandboxFlagRemoved": "`--sandbox` 不是 CLI flag。请在 experiment(或 niceeval.config.ts 做全项目兜底)里把 sandbox 设成 dockerSandbox() / vercelSandbox() / e2bSandbox()(从 \"niceeval/sandbox\" 导入)。\n",
|
|
95
94
|
"cli.unimplemented": "命令 \"{{command}}\" 暂未实现(MVP)。\n",
|
|
96
95
|
"cli.view.exportedDir": "已导出静态查看站:{{out}}(整个目录可直接静态托管;本地打开 {{out}}/index.html 需经 http 服务,file:// 下工件 fetch 不可用)\n",
|
|
97
96
|
"cli.view.incompatible": "{{dir}}: 由 niceeval {{producer}} 写入(schemaVersion {{schemaVersion}}),当前 CLI 只读 schemaVersion {{supported}}。\n运行 `{{command}}` 查看这份报告。\n",
|
|
97
|
+
"cli.view.noResults": "{{root}} 下没有结果。先 `niceeval exp` 跑一轮,再 `niceeval view`。\n",
|
|
98
98
|
"cli.view.incompatibleForeign": "{{dir}}: 由 {{name}} {{version}} 写入(schemaVersion {{schemaVersion}}),当前 CLI 只读 schemaVersion {{supported}}。\n请用写出它的那个工具查看这份报告。\n",
|
|
99
99
|
"cli.view.url": "niceeval view: {{url}}\n",
|
|
100
100
|
"context.capabilityMissing":
|