niceeval 0.6.0 → 0.6.1

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 (87) hide show
  1. package/dist/agents/types.d.ts +5 -1
  2. package/dist/report/built-ins/experiment-comparison.d.ts +1 -0
  3. package/dist/report/built-ins/experiment-comparison.js +13 -0
  4. package/dist/report/built-ins/index.d.ts +1 -1
  5. package/dist/report/built-ins/index.js +1 -1
  6. package/dist/report/components.d.ts +3 -1
  7. package/dist/report/components.js +1 -1
  8. package/dist/report/compute.js +15 -33
  9. package/dist/report/format.d.ts +0 -6
  10. package/dist/report/format.js +1 -18
  11. package/dist/report/index.d.ts +2 -2
  12. package/dist/report/index.js +1 -1
  13. package/dist/report/locale.d.ts +13 -2
  14. package/dist/report/locale.js +26 -3
  15. package/dist/report/metrics.js +1 -1
  16. package/dist/report/react/AttemptList.d.ts +2 -2
  17. package/dist/report/react/AttemptList.js +3 -4
  18. package/dist/report/react/ExperimentList.d.ts +3 -2
  19. package/dist/report/react/ExperimentList.js +59 -7
  20. package/dist/report/react/MetricScatter.js +1 -5
  21. package/dist/report/react/fixtures.js +9 -4
  22. package/dist/report/react/format.d.ts +1 -1
  23. package/dist/report/react/format.js +1 -1
  24. package/dist/report/react/index.d.ts +1 -1
  25. package/dist/report/text/faces.js +71 -33
  26. package/dist/report/types.d.ts +3 -15
  27. package/docs-site/zh/concepts/adapter.mdx +2 -2
  28. package/docs-site/zh/concepts/assert.mdx +11 -10
  29. package/docs-site/zh/concepts/evals.mdx +7 -6
  30. package/docs-site/zh/concepts/overview.mdx +1 -1
  31. package/docs-site/zh/guides/agent-feedback-loop.mdx +9 -7
  32. package/docs-site/zh/guides/fixtures.mdx +3 -1
  33. package/docs-site/zh/guides/official-adapters.mdx +1 -1
  34. package/docs-site/zh/guides/publish-report.mdx +1 -1
  35. package/docs-site/zh/guides/report-components.mdx +13 -13
  36. package/docs-site/zh/guides/results-data.mdx +28 -2
  37. package/docs-site/zh/guides/sandbox-agent.mdx +1 -0
  38. package/docs-site/zh/guides/sandbox-providers.mdx +1 -1
  39. package/docs-site/zh/guides/viewing-results.mdx +6 -5
  40. package/docs-site/zh/guides/write-send.mdx +2 -1
  41. package/docs-site/zh/reference/cli.mdx +3 -3
  42. package/docs-site/zh/reference/define-agent.mdx +3 -1
  43. package/docs-site/zh/reference/events.mdx +2 -2
  44. package/docs-site/zh/reference/expect.mdx +10 -5
  45. package/package.json +1 -1
  46. package/src/agents/types.ts +5 -1
  47. package/src/i18n/en.ts +1 -2
  48. package/src/i18n/zh-CN.ts +1 -1
  49. package/src/report/built-in-user-parity.test.tsx +44 -47
  50. package/src/report/built-ins/experiment-comparison.tsx +19 -0
  51. package/src/report/built-ins/index.ts +1 -1
  52. package/src/report/components.tsx +3 -1
  53. package/src/report/compute.ts +12 -36
  54. package/src/report/dual-render.test.tsx +33 -29
  55. package/src/report/format.ts +1 -16
  56. package/src/report/index.ts +1 -2
  57. package/src/report/locale.ts +26 -3
  58. package/src/report/metrics.ts +1 -1
  59. package/src/report/react/AttemptList.tsx +4 -6
  60. package/src/report/react/ExperimentList.tsx +167 -55
  61. package/src/report/react/MetricScatter.tsx +1 -11
  62. package/src/report/react/enhance.js +39 -0
  63. package/src/report/react/fixtures.ts +10 -4
  64. package/src/report/react/format.ts +1 -1
  65. package/src/report/react/index.tsx +0 -1
  66. package/src/report/react/render.test.tsx +24 -8
  67. package/src/report/react/styles.css +40 -13
  68. package/src/report/report.test.ts +2 -7
  69. package/src/report/text/faces.ts +76 -36
  70. package/src/report/types.ts +3 -15
  71. package/src/results/host-equivalence.test.ts +3 -3
  72. package/src/show/index.ts +8 -15
  73. package/src/show/render.ts +7 -204
  74. package/src/show/show.test.ts +22 -23
  75. package/src/view/data.test.ts +1 -1
  76. package/src/view/data.ts +6 -6
  77. package/src/view/index.ts +1 -1
  78. package/src/view/shared/types.ts +1 -1
  79. package/src/view/view-report.test.ts +5 -5
  80. package/dist/o11y/execution-tree.d.ts +0 -103
  81. package/dist/o11y/otlp/select.d.ts +0 -22
  82. package/dist/report/built-ins/cost-pass-rate-comparison.d.ts +0 -1
  83. package/dist/report/built-ins/cost-pass-rate-comparison.js +0 -17
  84. package/dist/results/annotated-source.d.ts +0 -61
  85. package/dist/results/attempt-evidence.d.ts +0 -69
  86. package/dist/results/attempt-source.d.ts +0 -15
  87. package/src/report/built-ins/cost-pass-rate-comparison.tsx +0 -23
@@ -1,61 +0,0 @@
1
- import type { AssertionResult } from "../types.ts";
2
- /** 一行源码 + 映射到这一行的全部断言(保持原始顺序;可以是空数组)。 */
3
- export interface AnnotatedSourceLine {
4
- /** 1-indexed 行号,与 SourceLoc.line 同一坐标系。 */
5
- line: number;
6
- /** 这一行的原始文本(已按 normalizeEvalSource 归一化,不含行尾换行符)。 */
7
- text: string;
8
- /**
9
- * 映射到这一行的断言,按输入顺序(通常即执行顺序)排列。每条断言自带 severity / score /
10
- * passed / detail / evidence —— 这就是"状态 / 严重度 / 分数 / detail / evidence"标回源码行
11
- * 的完整信息,不需要额外的行级折叠字段:折叠成单一显示态是 renderer 的展示决定,不是这份
12
- * 领域 model 的职责(与 indexAsserts() 的先例一致,它同样只分桶、不折叠)。
13
- */
14
- assertions: AssertionResult[];
15
- }
16
- export interface AnnotatedEvalSourceSummary {
17
- /** 参与统计的断言总数 = mappedAssertions + unmappedAssertions。 */
18
- totalAssertions: number;
19
- /** 成功映射到某一行源码的断言数。 */
20
- mappedAssertions: number;
21
- /** 落进 unmapped 桶的断言数。 */
22
- unmappedAssertions: number;
23
- /** 按 passed 计票(映射与未映射的断言都计入)。 */
24
- passed: number;
25
- failed: number;
26
- /** 按 severity 计票(映射与未映射的断言都计入)。 */
27
- gate: number;
28
- soft: number;
29
- /** 源码总行数,等于 lines.length。 */
30
- totalLines: number;
31
- /** 至少挂了一条断言的行数。 */
32
- annotatedLines: number;
33
- }
34
- export interface AnnotatedEvalSource {
35
- /** 项目相对路径,与 SourceArtifact.path / SourceLoc.file 同一约定。 */
36
- sourcePath: string;
37
- /** 归一化后源码文本的 SHA-256(与 captureEvalSource() 的算法一致,见 source-hash.ts)。 */
38
- sourceSha256: string;
39
- lines: AnnotatedSourceLine[];
40
- /**
41
- * 没有落到 lines 里任何一行的断言,原始顺序保留,永不丢弃。三种情况都进这里:
42
- * 没有 SourceLoc(如 skip 前就出错的 eval、或调用方尚未收集到位置)、SourceLoc 指向
43
- * 另一个文件(loc.file !== sourcePath —— 罕见,如断言写在共享 helper 里)、
44
- * SourceLoc 的行号落在这份源码的行范围之外(源码与断言记录不同步的边界情况)。
45
- * 后两种不是文档明确要求的场景,但"never silently dropped"的契约对它们同样成立 ——
46
- * 这份 model 是分桶断言的唯一出口,不属于任何一行就必须出现在这里。
47
- */
48
- unmapped: AssertionResult[];
49
- summary: AnnotatedEvalSourceSummary;
50
- }
51
- /**
52
- * 纯函数:给定一份源码文本(未归一化也可以,内部会 normalizeEvalSource)与一批断言,
53
- * 产出标注好的 AnnotatedEvalSource。幂等 / 无 IO —— 可以在渲染路径上安全调用。
54
- *
55
- * 断言 → 源码行的映射规则:`a.loc` 存在、`a.loc.file === source.path`、且
56
- * `1 <= a.loc.line <= lines.length` 三者同时成立才落到对应行;否则进 `unmapped`。
57
- */
58
- export declare function buildAnnotatedEvalSource(source: {
59
- path: string;
60
- content: string;
61
- }, assertions: readonly AssertionResult[]): AnnotatedEvalSource;
@@ -1,69 +0,0 @@
1
- import type { AttemptHandle } from "./types.ts";
2
- import { type AttemptIdentity, type AttemptLocator } from "./locator.ts";
3
- import type { AnnotatedEvalSource } from "./annotated-source.ts";
4
- import { type ExecutionTree } from "../o11y/execution-tree.ts";
5
- import type { DiffData, EvalResult } from "../types.ts";
6
- /**
7
- * 一个 Attempt 的 artifact 落盘位置。单一目录足够:一个 attempt 的全部 artifact
8
- * (events.json / trace.json / o11y.json / diff.json / sources.json,见 ARTIFACT_KINDS)
9
- * 要么全在它自己的 attempt 目录,要么(--resume 携带条目——本轮没写任何新数据,
10
- * 见 writer.ts 对携带分支的说明)全在 artifactBase 回退到的原快照 attempt 目录,
11
- * 从不出现"这个 kind 在自己目录、那个 kind 在 artifactBase"的拆分场景,不需要
12
- * 按 kind 逐个给路径。想要某一种 artifact 的具体文件,自己拼
13
- * `join(artifactPaths.dir, "<kind>.json")`(kind 见 `ArtifactKind`)。
14
- *
15
- * 与 show/render.ts 的 `attemptArtifactsPath(attempt, cwd)` 是同一份"这个 attempt 的证据在哪"
16
- * 知识的两种呈现:那边为 CLI 文本展示把它转成 cwd 相对的短路径,这里给 evidence 层的调用方
17
- * (view / 静态导出 / 报告列表,它们没有统一的"cwd"概念)一份绝对路径,不做相对化。
18
- */
19
- export interface EvidencePaths {
20
- /** 绝对路径。 */
21
- dir: string;
22
- }
23
- /**
24
- * 每一位只在数据真的存在且非空时为 true——从不因为对应的 artifact 文件"存在"就点亮,
25
- * 见本文件头注逐位的门槛说明。show/view/静态导出/报告列表读这四位来决定要不要显示
26
- * 对应的证据切面,不自己重新判断"这个 attempt 有没有 X"。
27
- */
28
- export interface AttemptEvidenceCapabilities {
29
- /** evalSource 非空且有内容(源码行或断言二选一非空)。 */
30
- eval: boolean;
31
- /** events 非空数组——有骨架可看。 */
32
- execution: boolean;
33
- /** execution 成立且这次运行接入过 OTel(ExecutionTree.timingAvailable)。 */
34
- timing: boolean;
35
- /** diff 非空且至少改动/删除了一个文件。 */
36
- diff: boolean;
37
- }
38
- /**
39
- * 一个 Attempt 的完整证据聚合。除 `locator` 外每个字段要么是别的模块已经产出的纯数据类型,
40
- * 要么是这四样拼出来的判定——本类型自己不发明新的证据形状。
41
- */
42
- export interface AttemptEvidence {
43
- locator: AttemptLocator;
44
- /** locator 派生自的不可变身份元组,与 `locator` 编码的是同一份数据,供不想解码 locator
45
- * 的调用方直接读结构化字段(如按 experimentId 分组、按时间排序)。 */
46
- identity: AttemptIdentity;
47
- result: EvalResult;
48
- /** 运行时保存的 Eval 源码标注(`--eval` 切面);没有 sources() 就是 null,不伪造空文档。 */
49
- evalSource: AnnotatedEvalSource | null;
50
- /** 标准事件流 + OTel enrichment(`--execution` 切面);没有非空 events 就是 null,
51
- * 不产出一棵只剩 telemetry-only 节点、没有真实骨架的误导性树(见头注 execution 门槛)。 */
52
- execution: ExecutionTree | null;
53
- /** 被测 Agent 对 Sandbox 工作区的文件变化(`--diff` 切面);原样透传 attempt.diff()。 */
54
- diff: DiffData | null;
55
- artifactPaths: EvidencePaths;
56
- capabilities: AttemptEvidenceCapabilities;
57
- }
58
- /**
59
- * 纯组合:一次性 await 好 attempt 的四类懒加载证据(events / trace / diff / 经
60
- * loadAnnotatedEvalSource 解引用的 eval 源码),拼成一份 AttemptEvidence。不重新实现
61
- * Eval 源码标注、ExecutionTree 合并或 diff 语义的任何一条规则——那些规则的家分别在
62
- * annotated-source.ts / execution-tree.ts / attempt.diff() 自身,这里只调用与判定"够不够
63
- * 亮起对应的证据切面"。
64
- *
65
- * `attempt.locator` 在真实读取路径(openResults() 产出的 handle)恒有值;缺失时按当前身份
66
- * 元组按 encodeAttemptLocator 兜底算一份,同 open.ts 给 record.locator 做的兜底同一口径——
67
- * 只服务手工构造 AttemptHandle 的测试场景,不改变真实读取路径的行为。
68
- */
69
- export declare function loadAttemptEvidence(attempt: AttemptHandle): Promise<AttemptEvidence>;
@@ -1,15 +0,0 @@
1
- import type { AttemptHandle } from "./types.ts";
2
- import { type AnnotatedEvalSource } from "./annotated-source.ts";
3
- /**
4
- * 给定一个 attempt,取回它的 eval 源码(经 sources() 解引用,可能来自本快照或
5
- * artifactBase 回退到的原快照)与它的断言,产出标注好的 AnnotatedEvalSource。
6
- *
7
- * 没有 sources()(eval 从没被 `loc` 引用到、或落盘里压根没有 sources.json/artifactBase
8
- * 已失效)时返回 null——没有源码就没有「标注源码」这回事,不伪造一份空文档。
9
- *
10
- * 一个 attempt 的 sources() 理论上可以有多份文件(主 eval 文件 + 罕见的跨文件 loc);
11
- * 这里按「哪份文件被最多断言的 loc 命中」选一份作为主文件喂给 buildAnnotatedEvalSource——
12
- * 只服务这条打通链路的验证目的,不是最终选择策略(后续阶段如需要为每份引用到的文件
13
- * 都出一份 AnnotatedEvalSource,在这基础上很容易扩成返回数组)。
14
- */
15
- export declare function loadAnnotatedEvalSource(attempt: AttemptHandle): Promise<AnnotatedEvalSource | null>;
@@ -1,23 +0,0 @@
1
- // CostPassRateComparison:show / view 裸跑时的出厂报告槽。
2
- //
3
- // 它是一份普通 ReportDefinition,零特权:只声明「摆什么」——成本 × 通过率的散点(比较
4
- // experiments)和实验列表。散点走 selection-form(`MetricScatter` 声明了 `resolve`,宿主
5
- // 渲染前的 resolveReportTree 会替它调 `.data`);`ExperimentList` 没有 selection-form,
6
- // 报告函数体里直接 `await ExperimentList.data(selection)` 拿到普通数组再传 `items`——
7
- // 这正是三个实体列表统一的用法,内置默认报告不搞一套特权写法。包外用户复制这段 TSX
8
- // (只改 import 路径与 export 形式)会走完全相同的解析与渲染管线。
9
-
10
- import { Col } from "../primitives.tsx";
11
- import { ExperimentList, MetricScatter } from "../components.tsx";
12
- import { costUSD, passRate } from "../metrics.ts";
13
- import { defineReport } from "../report.ts";
14
-
15
- export const CostPassRateComparison = defineReport(async ({ selection }) => {
16
- const experiments = await ExperimentList.data(selection);
17
- return (
18
- <Col>
19
- <MetricScatter selection={selection} points="experiment" series="agent" x={costUSD} y={passRate} />
20
- <ExperimentList items={experiments} />
21
- </Col>
22
- );
23
- });