niceeval 0.6.0 → 0.6.2
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/dist/agents/types.d.ts +72 -6
- package/dist/context/types.d.ts +32 -12
- package/dist/i18n/en.d.ts +54 -0
- package/dist/i18n/zh-CN.d.ts +55 -1
- package/dist/o11y/types.d.ts +16 -2
- package/dist/report/aggregate.d.ts +5 -3
- package/dist/report/aggregate.js +32 -5
- package/dist/report/built-ins/experiment-comparison.d.ts +39 -0
- package/dist/report/built-ins/experiment-comparison.js +119 -0
- package/dist/report/built-ins/index.d.ts +2 -1
- package/dist/report/built-ins/index.js +2 -2
- package/dist/report/components.d.ts +10 -2
- package/dist/report/components.js +3 -3
- package/dist/report/compute.d.ts +11 -18
- package/dist/report/compute.js +68 -66
- package/dist/report/flag.d.ts +16 -1
- package/dist/report/flag.js +19 -1
- package/dist/report/format.d.ts +16 -14
- package/dist/report/format.js +28 -30
- package/dist/report/index.d.ts +5 -4
- package/dist/report/index.js +6 -5
- package/dist/report/locale.d.ts +23 -3
- package/dist/report/locale.js +47 -6
- package/dist/report/metrics.d.ts +13 -1
- package/dist/report/metrics.js +66 -15
- package/dist/report/primitives.d.ts +6 -0
- package/dist/report/react/AttemptList.d.ts +4 -4
- package/dist/report/react/AttemptList.js +8 -10
- package/dist/report/react/EvalList.d.ts +1 -1
- package/dist/report/react/EvalList.js +0 -0
- package/dist/report/react/ExperimentComparison.d.ts +8 -0
- package/dist/report/react/ExperimentComparison.js +11 -0
- package/dist/report/react/ExperimentList.d.ts +4 -2
- package/dist/report/react/ExperimentList.js +57 -7
- package/dist/report/react/MetricScatter.js +6 -16
- package/dist/report/react/chart-math.d.ts +23 -6
- package/dist/report/react/chart-math.js +71 -19
- package/dist/report/react/fixtures.d.ts +3 -3
- package/dist/report/react/fixtures.js +30 -18
- package/dist/report/react/format.d.ts +1 -1
- package/dist/report/react/format.js +1 -1
- package/dist/report/react/index.d.ts +1 -1
- package/dist/report/report.d.ts +5 -1
- package/dist/report/report.js +6 -2
- package/dist/report/text/faces.d.ts +1 -1
- package/dist/report/text/faces.js +100 -61
- package/dist/report/text/table.js +36 -5
- package/dist/report/types.d.ts +40 -34
- package/dist/results/types.d.ts +11 -0
- package/dist/runner/feedback/sink.d.ts +110 -0
- package/dist/runner/types.d.ts +513 -22
- package/dist/sandbox/docker.d.ts +23 -2
- package/dist/sandbox/e2b.d.ts +15 -1
- package/dist/sandbox/errors.d.ts +30 -3
- package/dist/sandbox/io-retry.d.ts +17 -0
- package/dist/sandbox/registry.d.ts +2 -0
- package/dist/sandbox/resolve.d.ts +18 -5
- package/dist/sandbox/retry.d.ts +11 -1
- package/dist/sandbox/types.d.ts +39 -5
- package/dist/sandbox/vercel.d.ts +7 -1
- package/dist/scoring/coverage.d.ts +30 -0
- package/dist/scoring/display.d.ts +21 -0
- package/dist/scoring/display.js +120 -0
- package/dist/scoring/types.d.ts +103 -20
- package/dist/shared/aggregate.d.ts +1 -0
- package/dist/shared/aggregate.js +3 -3
- package/dist/shared/types.d.ts +28 -0
- package/dist/tty-line.d.ts +0 -4
- package/dist/util.d.ts +23 -0
- package/docs-site/zh/concepts/adapter.mdx +24 -6
- package/docs-site/zh/concepts/assert.mdx +11 -10
- package/docs-site/zh/concepts/evals.mdx +7 -6
- package/docs-site/zh/concepts/experiment.mdx +1 -1
- package/docs-site/zh/concepts/overview.mdx +7 -7
- package/docs-site/zh/guides/agent-feedback-loop.mdx +35 -31
- package/docs-site/zh/guides/authoring.mdx +33 -0
- package/docs-site/zh/guides/ci-integration.mdx +23 -12
- package/docs-site/zh/guides/connect-your-agent.mdx +29 -3
- package/docs-site/zh/guides/custom-reports.mdx +29 -34
- package/docs-site/zh/guides/dataset-fanout.mdx +25 -3
- package/docs-site/zh/guides/debug-sandbox.mdx +57 -0
- package/docs-site/zh/guides/debugging.mdx +210 -0
- package/docs-site/zh/guides/experiments.mdx +10 -3
- package/docs-site/zh/guides/fixtures.mdx +3 -1
- package/docs-site/zh/guides/official-adapters.mdx +27 -3
- package/docs-site/zh/guides/publish-report.mdx +30 -16
- package/docs-site/zh/guides/report-components.mdx +49 -37
- package/docs-site/zh/guides/reporters.mdx +2 -2
- package/docs-site/zh/guides/results-data.mdx +42 -8
- package/docs-site/zh/guides/runner.mdx +17 -7
- package/docs-site/zh/guides/sandbox-agent.mdx +57 -7
- package/docs-site/zh/guides/sandbox-providers.mdx +258 -10
- package/docs-site/zh/guides/scoring-guide.mdx +4 -4
- package/docs-site/zh/guides/viewing-results.mdx +85 -41
- package/docs-site/zh/guides/write-experiment.mdx +5 -3
- package/docs-site/zh/guides/write-send.mdx +19 -2
- package/docs-site/zh/index.mdx +1 -1
- package/docs-site/zh/reference/builtin-agents.mdx +27 -0
- package/docs-site/zh/reference/capabilities.mdx +2 -2
- package/docs-site/zh/reference/cli.mdx +35 -9
- package/docs-site/zh/reference/define-agent.mdx +60 -5
- package/docs-site/zh/reference/define-config.mdx +1 -1
- package/docs-site/zh/reference/define-eval.mdx +42 -9
- package/docs-site/zh/reference/events.mdx +2 -2
- package/docs-site/zh/reference/expect.mdx +36 -6
- package/package.json +5 -1
- package/src/agents/ai-sdk-otel.test.ts +1 -0
- package/src/agents/ai-sdk.test.ts +3 -0
- package/src/agents/ai-sdk.ts +3 -0
- package/src/agents/bub-install-spec.test.ts +34 -0
- package/src/agents/bub-install-spec.ts +32 -0
- package/src/agents/bub.ts +31 -32
- package/src/agents/claude-code.test.ts +130 -9
- package/src/agents/claude-code.ts +76 -4
- package/src/agents/codex.test.ts +189 -40
- package/src/agents/codex.ts +155 -14
- package/src/agents/coding-cli-versions.test.ts +15 -0
- package/src/agents/coding-cli-versions.ts +3 -0
- package/src/agents/index.ts +11 -0
- package/src/agents/langgraph.test.ts +204 -0
- package/src/agents/langgraph.ts +495 -0
- package/src/agents/marketplace.ts +85 -0
- package/src/agents/native-config.test.ts +179 -0
- package/src/agents/native-config.ts +267 -0
- package/src/agents/openai-compat.test.ts +1 -0
- package/src/agents/openclaw.test.ts +31 -0
- package/src/agents/openclaw.ts +171 -0
- package/src/agents/plugin-config.test.ts +1 -0
- package/src/agents/sdk-streams.test.ts +79 -0
- package/src/agents/sdk-streams.ts +55 -10
- package/src/agents/skills.test.ts +1 -0
- package/src/agents/streaming.test.ts +3 -9
- package/src/agents/types.ts +73 -6
- package/src/agents/ui-message-stream.test.ts +3 -0
- package/src/cli.ts +411 -108
- package/src/context/context.test.ts +51 -12
- package/src/context/context.ts +161 -29
- package/src/context/session.test.ts +1 -0
- package/src/context/session.ts +114 -6
- package/src/context/types.ts +30 -12
- package/src/define.test.ts +13 -8
- package/src/define.ts +25 -4
- package/src/expect/index.ts +53 -23
- package/src/i18n/en.ts +65 -4
- package/src/i18n/zh-CN.ts +66 -4
- package/src/o11y/cost.test.ts +1 -0
- package/src/o11y/execution-tree.test.ts +1 -20
- package/src/o11y/otlp/mappers/claude-code.test.ts +1 -0
- package/src/o11y/otlp/parse.test.ts +1 -0
- package/src/o11y/otlp/turn-otel.test.ts +1 -0
- package/src/o11y/parsers/bub.test.ts +1 -0
- package/src/o11y/parsers/claude-code.test.ts +1 -34
- package/src/o11y/parsers/openclaw.test.ts +154 -0
- package/src/o11y/parsers/openclaw.ts +310 -0
- package/src/o11y/prices.json +746 -311
- package/src/o11y/tool-names.test.ts +1 -0
- package/src/o11y/types.ts +16 -2
- package/src/report/aggregate.ts +34 -5
- package/src/report/built-in-user-parity.test.tsx +127 -173
- package/src/report/built-ins/experiment-comparison.tsx +179 -0
- package/src/report/built-ins/index.ts +7 -2
- package/src/report/components.tsx +11 -3
- package/src/report/compute.ts +80 -74
- package/src/report/dual-render.test.tsx +222 -91
- package/src/report/flag.ts +30 -2
- package/src/report/format.ts +36 -27
- package/src/report/index.ts +23 -6
- package/src/report/locale.ts +49 -6
- package/src/report/metrics.ts +68 -15
- package/src/report/primitives.tsx +6 -0
- package/src/report/react/AttemptList.tsx +9 -36
- package/src/report/react/EvalList.tsx +0 -0
- package/src/report/react/ExperimentComparison.tsx +68 -0
- package/src/report/react/ExperimentList.tsx +173 -55
- package/src/report/react/MetricScatter.tsx +13 -25
- package/src/report/react/chart-math.test.ts +85 -0
- package/src/report/react/chart-math.ts +101 -22
- package/src/report/react/enhance.js +72 -1
- package/src/report/react/fixtures.ts +34 -21
- package/src/report/react/format.ts +1 -1
- package/src/report/react/index.tsx +0 -1
- package/src/report/react/render.test.tsx +30 -69
- package/src/report/react/styles.css +112 -14
- package/src/report/report.test.ts +308 -105
- package/src/report/report.ts +6 -2
- package/src/report/text/faces.ts +111 -67
- package/src/report/text/table.ts +42 -5
- package/src/report/types.ts +42 -34
- package/src/results/annotated-source.test.ts +62 -9
- package/src/results/annotated-source.ts +64 -6
- package/src/results/attempt-evidence.test.ts +9 -7
- package/src/results/attempt-evidence.ts +15 -8
- package/src/results/attempt-source.ts +6 -3
- package/src/results/copy.ts +145 -55
- package/src/results/host-equivalence.test.ts +11 -9
- package/src/results/index.ts +2 -0
- package/src/results/locator.test.ts +1 -22
- package/src/results/open.ts +7 -1
- package/src/results/publish.ts +149 -0
- package/src/results/results.test.ts +85 -51
- package/src/results/truncate.ts +90 -0
- package/src/results/types.ts +7 -0
- package/src/results/writer.ts +31 -13
- package/src/runner/attempt.test.ts +138 -7
- package/src/runner/attempt.ts +603 -104
- package/src/runner/discover.test.ts +47 -0
- package/src/runner/discover.ts +36 -2
- package/src/runner/eval-source.test.ts +1 -27
- package/src/runner/feedback/agent.test.ts +504 -0
- package/src/runner/feedback/agent.ts +409 -0
- package/src/runner/feedback/ci.test.ts +562 -0
- package/src/runner/feedback/ci.ts +401 -0
- package/src/runner/feedback/coordinator.test.ts +317 -0
- package/src/runner/feedback/coordinator.ts +397 -0
- package/src/runner/feedback/failure.ts +40 -0
- package/src/runner/feedback/human.test.ts +616 -0
- package/src/runner/feedback/human.ts +535 -0
- package/src/runner/feedback/index.ts +66 -0
- package/src/runner/feedback/io.ts +78 -0
- package/src/runner/feedback/profile.test.ts +50 -0
- package/src/runner/feedback/profile.ts +58 -0
- package/src/runner/feedback/reducer.test.ts +395 -0
- package/src/runner/feedback/reducer.ts +260 -0
- package/src/runner/feedback/renderer.ts +82 -0
- package/src/runner/feedback/sink.ts +203 -0
- package/src/runner/feedback/testing.ts +106 -0
- package/src/runner/ledger.test.ts +230 -0
- package/src/runner/ledger.ts +329 -0
- package/src/runner/report.test.ts +128 -3
- package/src/runner/report.ts +33 -9
- package/src/runner/reporters/artifacts.ts +8 -2
- package/src/runner/reporters/braintrust.test.ts +8 -7
- package/src/runner/reporters/braintrust.ts +9 -2
- package/src/runner/reporters/index.ts +2 -2
- package/src/runner/reporters/json.test.ts +162 -0
- package/src/runner/reporters/json.ts +35 -8
- package/src/runner/reporters/shared.ts +1 -5
- package/src/runner/run.test.ts +760 -3
- package/src/runner/run.ts +242 -36
- package/src/runner/sandbox-prep.ts +3 -42
- package/src/runner/timing.ts +158 -0
- package/src/runner/types.ts +518 -22
- package/src/sandbox/checkpoint.test.ts +55 -0
- package/src/sandbox/checkpoint.ts +29 -8
- package/src/sandbox/cli-commands.ts +407 -0
- package/src/sandbox/docker.ts +115 -16
- package/src/sandbox/e2b-agent-template.test.ts +56 -0
- package/src/sandbox/e2b-agent-template.ts +94 -0
- package/src/sandbox/e2b.ts +74 -9
- package/src/sandbox/errors.ts +111 -4
- package/src/sandbox/index.ts +2 -0
- package/src/sandbox/io-retry.test.ts +58 -0
- package/src/sandbox/io-retry.ts +45 -0
- package/src/sandbox/keep-registry.test.ts +86 -0
- package/src/sandbox/keep-registry.ts +142 -0
- package/src/sandbox/keep.ts +178 -0
- package/src/sandbox/paths.test.ts +1 -0
- package/src/sandbox/paths.ts +19 -8
- package/src/sandbox/registry.ts +20 -3
- package/src/sandbox/resolve.ts +76 -11
- package/src/sandbox/retry.test.ts +70 -0
- package/src/sandbox/retry.ts +46 -4
- package/src/sandbox/types.ts +44 -6
- package/src/sandbox/vercel.ts +43 -20
- package/src/scoring/collector.ts +60 -17
- package/src/scoring/coverage.ts +95 -0
- package/src/scoring/diff.ts +81 -0
- package/src/scoring/display.test.ts +121 -0
- package/src/scoring/display.ts +133 -0
- package/src/scoring/evidence.test.ts +189 -0
- package/src/scoring/judge.test.ts +142 -0
- package/src/scoring/judge.ts +15 -18
- package/src/scoring/scoped.ts +217 -50
- package/src/scoring/types.ts +117 -20
- package/src/scoring/verdict.ts +16 -4
- package/src/shared/aggregate.ts +3 -2
- package/src/shared/types.ts +31 -0
- package/src/show/compose.ts +2 -2
- package/src/show/index.ts +29 -16
- package/src/show/render.ts +626 -308
- package/src/show/show.test.ts +251 -36
- package/src/tty-line.ts +8 -26
- package/src/util.test.ts +1 -0
- package/src/util.ts +41 -0
- package/src/view/app/components/AttemptModal.tsx +153 -2
- package/src/view/app/components/CodeView.tsx +32 -11
- package/src/view/app/components/CopyControls.tsx +2 -2
- package/src/view/app/i18n.ts +6 -0
- package/src/view/app/lib/attempt-route.test.ts +1 -0
- package/src/view/app/lib/verdict.ts +7 -9
- package/src/view/artifact-serving.test.ts +2 -1
- package/src/view/client-dist/app.css +1 -1
- package/src/view/client-dist/app.js +17 -17
- package/src/view/data.test.ts +2 -1
- package/src/view/data.ts +17 -7
- package/src/view/index.ts +12 -1
- package/src/view/server.ts +2 -0
- package/src/view/shared/types.ts +1 -1
- package/src/view/styles.css +3 -0
- package/src/view/view-report.test.ts +11 -10
- package/dist/o11y/execution-tree.d.ts +0 -103
- package/dist/o11y/otlp/select.d.ts +0 -22
- package/dist/report/built-ins/cost-pass-rate-comparison.d.ts +0 -1
- package/dist/report/built-ins/cost-pass-rate-comparison.js +0 -17
- package/dist/results/annotated-source.d.ts +0 -61
- package/dist/results/attempt-evidence.d.ts +0 -69
- package/dist/results/attempt-source.d.ts +0 -15
- package/src/report/built-ins/cost-pass-rate-comparison.tsx +0 -23
- package/src/runner/reporters/console.ts +0 -70
- package/src/runner/reporters/live.test.ts +0 -56
- package/src/runner/reporters/live.ts +0 -247
- package/src/runner/reporters/quiet.test.ts +0 -66
- package/src/runner/reporters/quiet.ts +0 -49
- package/src/runner/reporters/table.ts +0 -277
package/src/scoring/types.ts
CHANGED
|
@@ -2,12 +2,25 @@
|
|
|
2
2
|
|
|
3
3
|
import type { Severity, SourceLoc } from "../shared/types.ts";
|
|
4
4
|
import type { DerivedFacts, StreamEvent, Usage } from "../o11y/types.ts";
|
|
5
|
+
import type { ResolvedCoverage } from "./coverage.ts";
|
|
5
6
|
|
|
6
|
-
|
|
7
|
+
// 覆盖代数(解析 / 降级 / 聚合)住在 coverage.ts;类型经这里进聚合 facade(src/types.ts)。
|
|
8
|
+
export type {
|
|
9
|
+
CoverageChannel,
|
|
10
|
+
ResolvedCoverage,
|
|
11
|
+
ResolvedCoverageChannel,
|
|
12
|
+
ResolvedCoverageStatus,
|
|
13
|
+
} from "./coverage.ts";
|
|
14
|
+
|
|
15
|
+
/** 值断言(expect 匹配器)。纯函数 score + 可链式改严重度 / 阈值 / optional。 */
|
|
7
16
|
export interface ValueAssertion {
|
|
8
17
|
readonly name: string;
|
|
9
18
|
readonly severity: Severity;
|
|
10
19
|
readonly threshold?: number;
|
|
20
|
+
/** `.optional()` 链过的标记:评不了只记 unavailable,不把 attempt 拖成 errored。 */
|
|
21
|
+
readonly isOptional?: boolean;
|
|
22
|
+
/** 期望条件的有界文本描述(如 `contains "Brooklyn"`),失败时进 AssertionResult.expected。 */
|
|
23
|
+
readonly expected?: string;
|
|
11
24
|
score(value: unknown): number | Promise<number>;
|
|
12
25
|
/** 转成硬门槛断言:未达阈值(省略 threshold 则按 score > 0 判定)整条 eval 判为 failed。返回新实例,不改原对象。 */
|
|
13
26
|
gate(threshold?: number): ValueAssertion;
|
|
@@ -16,37 +29,82 @@ export interface ValueAssertion {
|
|
|
16
29
|
* `--strict` 运行下,软阈值失败也会把整条 eval 的 verdict 计为 failed。返回新实例,不改原对象。
|
|
17
30
|
*/
|
|
18
31
|
atLeast(threshold: number): ValueAssertion;
|
|
32
|
+
/**
|
|
33
|
+
* 允许这条断言证据缺席:评不了时只记录 `outcome: "unavailable"`,不影响判定。
|
|
34
|
+
* 与 severity 正交(severity 说影不影响质量判定,optional 说证据允不允许缺席)。返回新实例,不改原对象。
|
|
35
|
+
*/
|
|
36
|
+
optional(): ValueAssertion;
|
|
19
37
|
}
|
|
20
38
|
|
|
21
|
-
/**
|
|
22
|
-
|
|
39
|
+
/**
|
|
40
|
+
* 断言记录的公共字段(见 docs/feature/scoring/architecture.md「断言记录」——字段契约的单点定义)。
|
|
41
|
+
*/
|
|
42
|
+
export interface AssertionBase {
|
|
43
|
+
/** 断言标题:t.group 内是该断言自己的摘要,组外是 matcher 摘要或 judge 问题;show/view 失败行的标题。 */
|
|
23
44
|
name: string;
|
|
45
|
+
/** 所属分组路径:外层在前的 t.group 标题数组;无分组省略。纯报告用,不影响判定。 */
|
|
46
|
+
groupPath?: string[];
|
|
24
47
|
severity: Severity;
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
48
|
+
/** 作者用 .optional() 显式允许该断言缺席;只改变 unavailable 的折叠方式(见 Severity 与 Verdict),不改变 severity 语义。 */
|
|
49
|
+
optional?: true;
|
|
50
|
+
/** matcher / judge 摘要,如 `equals(4)`、`closedQA("…")`;与 name 分开,供 show/view 同时展示分组标题与检查方式。 */
|
|
51
|
+
detail?: string;
|
|
52
|
+
/** 断言在 eval 源码中的调用点,`--eval` 把结果标回源码行的锚。 */
|
|
53
|
+
loc?: SourceLoc;
|
|
28
54
|
}
|
|
29
55
|
|
|
30
|
-
/**
|
|
31
|
-
|
|
32
|
-
|
|
56
|
+
/**
|
|
57
|
+
* 断言评估完的结果(进判定 / 报告)。判别键是 `outcome`——`unavailable` 是没有分数的独立态,
|
|
58
|
+
* 普通聚合代码按 `outcome` 分支就不可能把证据缺口算成零分。判定只消费
|
|
59
|
+
* `severity` / `outcome` / `optional` / `score` / `threshold`。
|
|
60
|
+
*/
|
|
61
|
+
export type AssertionResult =
|
|
62
|
+
| (AssertionBase & {
|
|
63
|
+
outcome: "passed" | "failed";
|
|
64
|
+
/** 归一化得分:值断言 0/1,judge 等打分断言 0..1。 */
|
|
65
|
+
score: number;
|
|
66
|
+
/** soft 断言的 .atLeast(x) 阈值;没有设阈值则省略。 */
|
|
67
|
+
threshold?: number;
|
|
68
|
+
/** 失败证据摘要:期望值的有界文本预览,供 show/view 直接展示。 */
|
|
69
|
+
expected?: string;
|
|
70
|
+
/** 失败证据摘要:实际值的有界文本预览。 */
|
|
71
|
+
received?: string;
|
|
72
|
+
/** 这条分数看着什么材料算出(judge 输入或被检查值预览);view 展开排查用,默认不展示。 */
|
|
73
|
+
evidence?: string;
|
|
74
|
+
})
|
|
75
|
+
| (AssertionBase & {
|
|
76
|
+
outcome: "unavailable";
|
|
77
|
+
/** 机器可读原因,如 "judge-model-unresolved"、"coverage:actions=partial"。 */
|
|
78
|
+
reason: string;
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* 摘要面从完整 `AssertionResult[]` 选出的一条主失败断言。它只负责展示,不参与 verdict;
|
|
83
|
+
* `show @locator` / view Attempt 详情仍读取完整断言数组。字段保持结构化,使 CI 不必解析
|
|
84
|
+
* Human 的 `gate: …` 文案。
|
|
85
|
+
*/
|
|
86
|
+
export interface PrimaryAssertionSummary {
|
|
33
87
|
severity: Severity;
|
|
88
|
+
/** `groupPath.join(" > ")`,无 group 时回退到断言 name。 */
|
|
89
|
+
assertion: string;
|
|
90
|
+
/** `detail ?? name`;与 assertion 相同时省略,避免重复。 */
|
|
91
|
+
matcher?: string;
|
|
92
|
+
expected?: string;
|
|
93
|
+
received?: string;
|
|
94
|
+
score?: number;
|
|
34
95
|
threshold?: number;
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
evidence?: string;
|
|
40
|
-
/** 所属分组(t.group 标题)。纯报告用,不影响 passed/score。 */
|
|
41
|
-
group?: string;
|
|
42
|
-
/** 断言在 eval 源码里的调用点(栈回溯抠出);view 把判定叠回这一行。 */
|
|
43
|
-
loc?: SourceLoc;
|
|
96
|
+
/** unavailable 断言的结构化原因。 */
|
|
97
|
+
reason?: string;
|
|
98
|
+
/** 同类因果失败中除主失败外的条数。 */
|
|
99
|
+
additionalFailures: number;
|
|
44
100
|
}
|
|
45
101
|
|
|
46
102
|
/** eval 作者拿到的可链式句柄(t.judge.autoevals.closedQA(...).atLeast(0.7))。 */
|
|
47
103
|
export interface AssertionHandle {
|
|
48
104
|
atLeast(threshold: number): AssertionHandle;
|
|
49
105
|
gate(threshold?: number): AssertionHandle;
|
|
106
|
+
/** 允许这条断言证据缺席:unavailable 只保留在记录里,不影响判定(见 Severity 与 Verdict)。 */
|
|
107
|
+
optional(): AssertionHandle;
|
|
50
108
|
}
|
|
51
109
|
|
|
52
110
|
/** scoped / judge 断言在 final 评估时拿到的运行结果。 */
|
|
@@ -57,6 +115,8 @@ export interface ScoringContext {
|
|
|
57
115
|
readonly scripts: Record<string, ScriptResult>;
|
|
58
116
|
readonly usage: Usage;
|
|
59
117
|
readonly status: "completed" | "failed" | "waiting";
|
|
118
|
+
/** 当前作用域(turn / session / attempt)解析后的证据覆盖;断言按它做三值折叠(见 scoped.ts)。 */
|
|
119
|
+
readonly coverage: ResolvedCoverage;
|
|
60
120
|
/** 读沙箱里某文件的最终内容(judge / file 断言用)。 */
|
|
61
121
|
readFile(path: string): Promise<string | undefined>;
|
|
62
122
|
}
|
|
@@ -66,9 +126,46 @@ export interface ScriptResult {
|
|
|
66
126
|
output: string;
|
|
67
127
|
}
|
|
68
128
|
|
|
129
|
+
// ── agent 归因增量(见 docs/feature/results/architecture.md「diff.json」与
|
|
130
|
+
// docs/feature/sandbox/architecture.md「变更归因:send 窗口与分类账」)──
|
|
131
|
+
|
|
132
|
+
/** diff.json 的落盘形状:按时序的窗口数组(逐窗口 delta 序列,不做跨窗口压缩)。 */
|
|
133
|
+
export type DiffArtifact = DiffWindow[];
|
|
134
|
+
|
|
135
|
+
export interface DiffWindow {
|
|
136
|
+
/** send 窗口标签,与时间树 turn 节点、--execution 轮次同源(如 "s1/t2")。 */
|
|
137
|
+
window: string;
|
|
138
|
+
/** 该窗口内 agent 改动的文件;窗口内没有 workspace 变化时窗口仍落一条、changes 为空对象。 */
|
|
139
|
+
changes: Record<string, WindowChange>;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
export interface WindowChange {
|
|
143
|
+
status: "added" | "modified" | "deleted";
|
|
144
|
+
/** 窗口开始时的内容;added 无此字段。 */
|
|
145
|
+
before?: string;
|
|
146
|
+
/** 窗口结束时的内容;deleted 无此字段。 */
|
|
147
|
+
after?: string;
|
|
148
|
+
/** 二进制文件不内联内容,只记字节数。 */
|
|
149
|
+
binary?: { beforeBytes?: number; afterBytes?: number };
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
/** 读取面在窗口序列之上派生的文件级视图(派生物可随时重算,不落盘)。 */
|
|
153
|
+
export interface DiffFileSummary {
|
|
154
|
+
/** 净效果:首个触及窗口的起点 vs 最后触及窗口的终点;"none" = 动过但净无变化(创建又删除、改回原样)。 */
|
|
155
|
+
net: "added" | "modified" | "deleted" | "none";
|
|
156
|
+
/** 触及该文件的窗口标签,按时序。 */
|
|
157
|
+
windows: string[];
|
|
158
|
+
binary?: true;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
/** agent 归因 diff 的消费视图:窗口序列(落盘事实)+ 派生的文件级摘要与终态读取。 */
|
|
69
162
|
export interface DiffData {
|
|
70
|
-
|
|
71
|
-
|
|
163
|
+
/** 落盘事实,原样。 */
|
|
164
|
+
windows: DiffWindow[];
|
|
165
|
+
/** 派生:每个被 agent 触及的文件一条。 */
|
|
166
|
+
files: Record<string, DiffFileSummary>;
|
|
167
|
+
/** 该文件最后一个触及窗口结束时的内容;净删除或从未触及返回 undefined。t.sandbox.diff.get 同一语义。 */
|
|
168
|
+
get(path: string): string | undefined;
|
|
72
169
|
}
|
|
73
170
|
|
|
74
171
|
export type Verdict = "passed" | "failed" | "errored" | "skipped";
|
package/src/scoring/verdict.ts
CHANGED
|
@@ -1,17 +1,29 @@
|
|
|
1
|
-
// 判定:把执行结果 + 断言 + 跳过原因折叠成一个 Verdict
|
|
1
|
+
// 判定:把执行结果 + 断言 + 跳过原因折叠成一个 Verdict
|
|
2
|
+
// (见 docs/feature/scoring/architecture/severity-and-verdict.md)。固定优先级取第一个成立项:
|
|
3
|
+
// 执行异常 / 任一非 optional 断言 unavailable → errored
|
|
4
|
+
// 任一 gate 不通过,或 strict 下 soft 低于阈值 → failed
|
|
5
|
+
// 显式 t.skip(reason) → skipped
|
|
6
|
+
// 否则 → passed
|
|
7
|
+
// errored 压过一切(执行证据已不可信);failed 压过 skipped(t.skip 不掩盖已记录的硬失败)。
|
|
2
8
|
|
|
3
|
-
import type { AssertionResult, Verdict } from "../types.ts";
|
|
9
|
+
import type { AssertionResult, AttemptError, Verdict } from "../types.ts";
|
|
4
10
|
|
|
5
11
|
export function computeVerdict(input: {
|
|
6
|
-
error?:
|
|
12
|
+
error?: AttemptError;
|
|
7
13
|
assertions: readonly AssertionResult[];
|
|
8
14
|
skipReason?: string;
|
|
9
15
|
strict?: boolean;
|
|
10
16
|
}): Verdict {
|
|
11
17
|
if (input.error !== undefined) return "errored";
|
|
12
18
|
|
|
19
|
+
// 作者写下的每条断言默认都要求可评估:非 optional 的 unavailable 使 attempt errored,
|
|
20
|
+
// 不分 gate / soft——「soft 全部评不了但 attempt 还绿着」是没有测量的绿,不允许出现。
|
|
13
21
|
for (const a of input.assertions) {
|
|
14
|
-
if (a.
|
|
22
|
+
if (a.outcome === "unavailable" && !a.optional) return "errored";
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
for (const a of input.assertions) {
|
|
26
|
+
if (a.outcome !== "failed") continue;
|
|
15
27
|
if (a.severity === "gate" || input.strict) return "failed";
|
|
16
28
|
}
|
|
17
29
|
|
package/src/shared/aggregate.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
//
|
|
1
|
+
// report 聚合(report/aggregate.ts)与 view 榜单(view/app/lib/rows.ts)共用的聚合小工具。
|
|
2
2
|
// 实验标签推导、token/成本求和、verdict 排序各只有一份 —— 否则同一个实验在终端和网页上
|
|
3
3
|
// 会显示成两个名字 / 两组数。保持环境无关(纯函数,只 type import)。
|
|
4
4
|
|
|
@@ -56,11 +56,12 @@ export function evalPrefixPredicate(evals?: string | string[]): (id: string) =>
|
|
|
56
56
|
|
|
57
57
|
/** 无 experimentId 时的兜底标签。 */
|
|
58
58
|
export function fallbackExperimentLabel(result: {
|
|
59
|
+
experimentId?: string;
|
|
59
60
|
experiment?: ExperimentRunInfo;
|
|
60
61
|
agent: string;
|
|
61
62
|
model?: string;
|
|
62
63
|
}): string {
|
|
63
|
-
if (result.
|
|
64
|
+
if (result.experimentId) return displayExperimentName(result.experimentId) ?? result.experimentId;
|
|
64
65
|
if (result.model) return `${result.agent}/${result.model}`;
|
|
65
66
|
return result.agent || "ad hoc run";
|
|
66
67
|
}
|
package/src/shared/types.ts
CHANGED
|
@@ -33,6 +33,37 @@ export interface SourceArtifact {
|
|
|
33
33
|
/** 通用清理闭包(setup 返回值 / teardown 的形状),异步同步皆可,统一在 finally 里执行。 */
|
|
34
34
|
export type Cleanup = () => Promise<void> | void;
|
|
35
35
|
|
|
36
|
+
/** `ScopedFeedback.progress` 的入参:此刻正在做什么(短命状态,可被后续更新覆盖)。 */
|
|
37
|
+
export interface ProgressUpdate {
|
|
38
|
+
message: string;
|
|
39
|
+
current?: number;
|
|
40
|
+
total?: number;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/** `ScopedFeedback.diagnostic` 的入参:运行结束后仍应保留的问题(永久事件)。 */
|
|
44
|
+
export interface DiagnosticInput {
|
|
45
|
+
code: string;
|
|
46
|
+
level: "warning" | "error";
|
|
47
|
+
message: string;
|
|
48
|
+
data?: Readonly<Record<string, JsonValue>>;
|
|
49
|
+
/** 并发 attempt 产生同一问题时的去重键;相同 key 折叠成一条并累计次数。 */
|
|
50
|
+
dedupeKey?: string;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* 作用域反馈 API(见 docs/feature/experiments/library.md「生命周期代码怎样向这次运行反馈」):
|
|
55
|
+
* sandbox provider、sandbox hook、eval 与 Agent Adapter 从 runner 注入的上下文获得同一套入口。
|
|
56
|
+
* - `progress` 是短命状态:Human profile 更新 active 行,Agent/CI 不逐条打印,不进最终结果;
|
|
57
|
+
* - `diagnostic` 是永久事件:进 Human/Agent/CI 的永久输出流并落进 attempt 的 diagnostics;
|
|
58
|
+
* 即使 level 为 "error" 也不自动改变 verdict(要 errored 抛异常,要 failed 用断言)。
|
|
59
|
+
* 两个方法都不接受 phase / scope / 颜色 / 输出流——runner 知道当前回调属于哪个生命周期阶段,
|
|
60
|
+
* 调用方不能冒充其它阶段。
|
|
61
|
+
*/
|
|
62
|
+
export interface ScopedFeedback {
|
|
63
|
+
progress(update: ProgressUpdate): void;
|
|
64
|
+
diagnostic(input: DiagnosticInput): void;
|
|
65
|
+
}
|
|
66
|
+
|
|
36
67
|
/**
|
|
37
68
|
* 可本地化文案:纯字符串,或按 locale 代码(如 "en"、"zh-CN")映射多语言。
|
|
38
69
|
* view 按当前界面语言挑一条,挑不到回退到 en / 第一条。
|
package/src/show/compose.ts
CHANGED
|
@@ -58,14 +58,14 @@ export function evalHistory(exp: Experiment, evalId: string): EvalHistoryRow[] {
|
|
|
58
58
|
if (c !== null) cost = (cost ?? 0) + c;
|
|
59
59
|
}
|
|
60
60
|
const latest = fresh[fresh.length - 1];
|
|
61
|
-
const failed = latest.result.assertions.find((a) =>
|
|
61
|
+
const failed = latest.result.assertions.find((a) => a.outcome !== "passed");
|
|
62
62
|
rows.push({
|
|
63
63
|
startedAt: snapshot.startedAt,
|
|
64
64
|
verdict: foldEvalVerdict(fresh.map((a) => a.result)),
|
|
65
65
|
attempts: fresh.length,
|
|
66
66
|
costUSD: cost,
|
|
67
67
|
...(failed ? { failedAssertion: `${failed.severity} ${failed.name}` } : {}),
|
|
68
|
-
...(latest.result.error !== undefined ? { error: latest.result.error } : {}),
|
|
68
|
+
...(latest.result.error !== undefined ? { error: latest.result.error.message } : {}),
|
|
69
69
|
});
|
|
70
70
|
}
|
|
71
71
|
return rows.reverse();
|
package/src/show/index.ts
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// 宿主组合语义:docs/feature/reports/architecture.md「Selection 是计算入口」)。
|
|
3
3
|
//
|
|
4
4
|
// 位置参数 = eval id 前缀,或 `@<locator>`(精确指名单个 attempt,见 results/locator.ts):
|
|
5
|
-
// 裸跑 / 前缀
|
|
5
|
+
// 裸跑 / 多 eval 前缀 默认 ExperimentComparison 的 text 面(单 eval 前缀仍进入详情)
|
|
6
6
|
// 恰好一个 eval 单 eval 详情(attempt / 断言明细,宿主本体)
|
|
7
7
|
// @<locator> 精确 attempt:无证据 flag → 紧凑全景;带 flag → 对应证据切面
|
|
8
8
|
// --eval / --execution / --diff[=路径] 证据切面(宿主本体):出现即走证据室,不渲染报告槽
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
// --run <目录> 结果根换成该目录;--experiment Selection 只留该实验
|
|
12
12
|
//
|
|
13
13
|
// 数据全部走 niceeval/results 的读取面(openResults + 合成 Selection + loadAttemptEvidence),
|
|
14
|
-
//
|
|
14
|
+
// 不自己爬目录;证据可用性只由 loadAttemptEvidence 在单 Attempt 页面计算。
|
|
15
15
|
|
|
16
16
|
import { existsSync } from "node:fs";
|
|
17
17
|
import { join, resolve } from "node:path";
|
|
@@ -24,7 +24,7 @@ import {
|
|
|
24
24
|
MalformedLocatorError,
|
|
25
25
|
} from "../results/index.ts";
|
|
26
26
|
// report.ts / load.ts have no JSX of their own, but ReportDefinition / ReportLoadError must
|
|
27
|
-
// come from the SAME module instance
|
|
27
|
+
// come from the SAME module instance ExperimentComparison (built-ins, .tsx) is built
|
|
28
28
|
// against — `unique symbol` branding and `instanceof` are keyed by declaration site, so a raw
|
|
29
29
|
// src copy and the compiled dist copy of "the same" ReportDefinition are, to TypeScript and to
|
|
30
30
|
// `instanceof`, two different types. The package-owned report runtime ships as precompiled
|
|
@@ -32,6 +32,7 @@ import {
|
|
|
32
32
|
// when niceeval is linked in — see tsconfig.report-build.json); show pulls all of it from
|
|
33
33
|
// there, not just the .tsx-touching pieces.
|
|
34
34
|
import { renderReportToText } from "../../dist/report/report.js";
|
|
35
|
+
import { ExperimentComparison } from "../../dist/report/built-ins/index.js";
|
|
35
36
|
import { ReportLoadError, loadReportFile } from "../../dist/report/load.js";
|
|
36
37
|
import { detectLocale, t } from "../i18n/index.ts";
|
|
37
38
|
import { foldEvalVerdict } from "../shared/verdict.ts";
|
|
@@ -43,16 +44,15 @@ import {
|
|
|
43
44
|
attemptIndexLine,
|
|
44
45
|
attemptOverviewText,
|
|
45
46
|
attemptsOfEval,
|
|
46
|
-
cheapCapabilities,
|
|
47
47
|
diffText,
|
|
48
48
|
evalDetailText,
|
|
49
49
|
evalHistoryText,
|
|
50
50
|
evalSourceText,
|
|
51
51
|
executionText,
|
|
52
52
|
experimentHistoryText,
|
|
53
|
+
timingText,
|
|
53
54
|
pickDetailAttempt,
|
|
54
55
|
skippedRunsText,
|
|
55
|
-
showIndexText,
|
|
56
56
|
verdictReasonLine,
|
|
57
57
|
} from "./render.ts";
|
|
58
58
|
|
|
@@ -61,6 +61,8 @@ export interface ShowFlags {
|
|
|
61
61
|
eval?: boolean;
|
|
62
62
|
/** 该 attempt 的标准执行事件流 + OTel enrichment(证据切面)。 */
|
|
63
63
|
execution?: boolean;
|
|
64
|
+
/** --timing:默认有界诊断投影;full 逐节点展开。boolean 仅供库调用兼容,等价 summary。 */
|
|
65
|
+
timing?: boolean | "summary" | "full";
|
|
64
66
|
/** --diff(文件级摘要)。 */
|
|
65
67
|
diff?: boolean;
|
|
66
68
|
/** --diff=<路径>(单个文件的完整改动;路径必须 = 连写,位置参数永远留给 eval id 前缀)。 */
|
|
@@ -121,7 +123,12 @@ async function show(
|
|
|
121
123
|
flags: ShowFlags,
|
|
122
124
|
io: { out: (s: string) => void; err: (s: string) => void; width: number; now: number },
|
|
123
125
|
): Promise<void> {
|
|
124
|
-
const evidence =
|
|
126
|
+
const evidence =
|
|
127
|
+
flags.eval === true ||
|
|
128
|
+
flags.execution === true ||
|
|
129
|
+
(flags.timing !== undefined && flags.timing !== false) ||
|
|
130
|
+
flags.diff === true ||
|
|
131
|
+
flags.diffPath !== undefined;
|
|
125
132
|
|
|
126
133
|
// 组合语义矩阵(docs/feature/reports/show.md「选择结果范围」):--history 与 --report 互斥,先于任何 IO 报出来。
|
|
127
134
|
if (flags.history && flags.report !== undefined) {
|
|
@@ -166,6 +173,12 @@ async function show(
|
|
|
166
173
|
const blocks: string[] = [];
|
|
167
174
|
if (flags.eval) blocks.push(evalSourceText(attemptEvidence, { header, artifactPath, width: io.width }));
|
|
168
175
|
if (flags.execution) blocks.push(executionText(attemptEvidence, { header, artifactPath, width: io.width }));
|
|
176
|
+
if (flags.timing) blocks.push(timingText(attemptEvidence, {
|
|
177
|
+
header,
|
|
178
|
+
artifactPath,
|
|
179
|
+
width: io.width,
|
|
180
|
+
mode: flags.timing === "full" ? "full" : "summary",
|
|
181
|
+
}));
|
|
169
182
|
if (flags.diff || flags.diffPath !== undefined) {
|
|
170
183
|
blocks.push(diffText({ header, diff: attemptEvidence.diff, artifactPath, file: flags.diffPath }));
|
|
171
184
|
}
|
|
@@ -202,7 +215,7 @@ async function show(
|
|
|
202
215
|
// 证据切面是宿主本体:出现即走证据室,不渲染报告槽(与默认报告同规则)。
|
|
203
216
|
if (evidence) {
|
|
204
217
|
if (matchedEvalIds.length !== 1) {
|
|
205
|
-
// 撞多个 eval 时不止说「有几个」,直接给紧凑索引(locator +
|
|
218
|
+
// 撞多个 eval 时不止说「有几个」,直接给紧凑索引(locator + 失败原因)
|
|
206
219
|
// 让 agent 一步摘到 `@<locator>`,不必再跑一轮 `show <eval id>` 才知道选谁。
|
|
207
220
|
const index = matchedEvalIds
|
|
208
221
|
.map((evalId) => {
|
|
@@ -213,7 +226,6 @@ async function show(
|
|
|
213
226
|
evalId,
|
|
214
227
|
verdict,
|
|
215
228
|
locator: rep?.locator,
|
|
216
|
-
capabilities: rep ? cheapCapabilities(rep.result) : { eval: false, execution: false, timing: false, diff: false },
|
|
217
229
|
reason: rep ? verdictReasonLine(rep.result) : undefined,
|
|
218
230
|
});
|
|
219
231
|
})
|
|
@@ -230,6 +242,12 @@ async function show(
|
|
|
230
242
|
const blocks: string[] = [];
|
|
231
243
|
if (flags.eval) blocks.push(evalSourceText(attemptEvidence, { header, artifactPath, width: io.width }));
|
|
232
244
|
if (flags.execution) blocks.push(executionText(attemptEvidence, { header, artifactPath, width: io.width }));
|
|
245
|
+
if (flags.timing) blocks.push(timingText(attemptEvidence, {
|
|
246
|
+
header,
|
|
247
|
+
artifactPath,
|
|
248
|
+
width: io.width,
|
|
249
|
+
mode: flags.timing === "full" ? "full" : "summary",
|
|
250
|
+
}));
|
|
233
251
|
if (flags.diff || flags.diffPath !== undefined) {
|
|
234
252
|
blocks.push(diffText({ header, diff: attemptEvidence.diff, artifactPath, file: flags.diffPath }));
|
|
235
253
|
}
|
|
@@ -277,16 +295,11 @@ async function show(
|
|
|
277
295
|
return;
|
|
278
296
|
}
|
|
279
297
|
|
|
280
|
-
// 裸 show
|
|
281
|
-
// --report
|
|
282
|
-
// locale = CLI 界面语言(NICEEVAL_LANG / LC_* / LANG 检测):报告 chrome 文案跟随
|
|
298
|
+
// 裸 show 与裸 view 选择同一个普通默认 definition,这里只是渲染 text 面。
|
|
299
|
+
// --report 替换同一个报告槽。locale = CLI 界面语言(NICEEVAL_LANG / LC_* / LANG 检测):报告 chrome 文案跟随
|
|
283
300
|
// 终端语言(docs/feature/reports/library.md「locale:渲染面的语言」);Locale 与 ReportLocale 同为
|
|
284
301
|
// "en" | "zh-CN",直接传递。
|
|
285
|
-
|
|
286
|
-
io.out(showIndexText(selection, io.width) + "\n");
|
|
287
|
-
return;
|
|
288
|
-
}
|
|
289
|
-
const definition = await loadReportFile(cwd, flags.report);
|
|
302
|
+
const definition = flags.report === undefined ? ExperimentComparison : await loadReportFile(cwd, flags.report);
|
|
290
303
|
// attemptCommand 留给 renderReportToText 的默认值:AttemptLocator 已经是可直接 `niceeval show
|
|
291
304
|
// @<locator>` 的真实 CLI 语法,不需要再反查 eval id 拼一条近似命令(见 tree.ts 的默认实现)。
|
|
292
305
|
const text = await renderReportToText(definition, { selection, results }, { width: io.width, locale: detectLocale() });
|