dsh-eval-pack 0.1.0-alpha.7 → 0.1.0-alpha.8

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/CHANGELOG.md CHANGED
@@ -1,5 +1,14 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.1.0-alpha.8] — 2026-11-01
4
+
5
+ ### Added
6
+
7
+ - `eval.summary`: aggregate pass count, pass rate and failing task ids for a graded run, using the same grader as `eval.grade`.
8
+ - Canonical-JSON grading: object key order no longer changes the verdict; array order still matters.
9
+
10
+ Verified by `node --test test/*.test.mjs` (7/7).
11
+
3
12
  ## [0.1.0-alpha.7] — 2026-11-01
4
13
 
5
14
  ### Changed
package/README-zh.md CHANGED
@@ -132,7 +132,6 @@ pnpm build && pnpm lint && pnpm typecheck && pnpm test
132
132
  - 本地运行;不联网、不调用模型、不上传。
133
133
  - 只使用公开/合成 fixture;不含客户数据或客户证据。
134
134
  - alpha/partial;not counted,不作 GA 或生产可用声明。
135
- - 冻结包仍可安装;不再加新功能,只修真实故障。
136
135
 
137
136
  ## 相关项目
138
137
 
package/README.md CHANGED
@@ -132,7 +132,6 @@ pnpm build && pnpm lint && pnpm typecheck && pnpm test
132
132
  - Runs locally; no network, no model call, no upload.
133
133
  - Public/synthetic fixtures only; no customer data, no customer evidence.
134
134
  - Alpha/partial; not counted, no GA or production-readiness claim.
135
- - Frozen packages stay installable; no new features, only genuine breakage fixes.
136
135
 
137
136
  ## Related work
138
137
 
@@ -8,4 +8,19 @@ export interface EvalPack {
8
8
  tasks: EvalTask[];
9
9
  }
10
10
  export declare function lintPack(input: unknown): string[];
11
+ /** Stable serialisation: object keys sorted at every level, arrays kept in order. */
12
+ export declare function canonical(value: unknown): string;
11
13
  export declare function grade(actual: unknown, expected: unknown): boolean;
14
+ export interface EvalResult {
15
+ id: string;
16
+ actual: unknown;
17
+ expected: unknown;
18
+ }
19
+ export interface EvalSummary {
20
+ total: number;
21
+ passed: number;
22
+ failed: number;
23
+ pass_rate: number;
24
+ failures: string[];
25
+ }
26
+ export declare function summarize(results: EvalResult[]): EvalSummary;
@@ -23,6 +23,33 @@ export function lintPack(input) {
23
23
  }
24
24
  return errors;
25
25
  }
26
+ /** Stable serialisation: object keys sorted at every level, arrays kept in order. */
27
+ export function canonical(value) {
28
+ const walk = (input) => {
29
+ if (Array.isArray(input))
30
+ return input.map(walk);
31
+ if (input && typeof input === 'object') {
32
+ const out = {};
33
+ for (const key of Object.keys(input).sort())
34
+ out[key] = walk(input[key]);
35
+ return out;
36
+ }
37
+ return input;
38
+ };
39
+ return JSON.stringify(walk(value));
40
+ }
26
41
  export function grade(actual, expected) {
27
- return JSON.stringify(actual) === JSON.stringify(expected);
42
+ return canonical(actual) === canonical(expected);
43
+ }
44
+ export function summarize(results) {
45
+ const failures = [];
46
+ let passed = 0;
47
+ for (const r of results) {
48
+ if (grade(r.actual, r.expected))
49
+ passed += 1;
50
+ else
51
+ failures.push(r.id);
52
+ }
53
+ const total = results.length;
54
+ return { total, passed, failed: total - passed, pass_rate: total ? Math.round((passed / total) * 1e6) / 1e6 : 0, failures };
28
55
  }
@@ -1,5 +1,5 @@
1
1
  import { defineTool } from '@deepseek-ai/dsh-tools';
2
- import { grade, lintPack } from '../core/harness.js';
2
+ import { grade, lintPack, summarize } from '../core/harness.js';
3
3
  const text = (t) => [{ type: 'text', text: t }];
4
4
  export function createTools() {
5
5
  const lint = defineTool({
@@ -16,5 +16,12 @@ export function createTools() {
16
16
  output: { schema: { type: 'object', additionalProperties: false, properties: { pass: { type: 'boolean', required: true } } }, render: (_a, v) => text(`grade ${v.pass ? 'pass' : 'fail'}`) },
17
17
  async execute(args) { return { pass: grade(args.actual, args.expected) }; },
18
18
  });
19
- return [lint, gradeTool];
19
+ const summary = defineTool({
20
+ name: 'eval.summary',
21
+ description: 'Aggregate graded results for a public/synthetic run: pass count, pass rate and the failing task ids, using the same canonical-JSON grader. Read-only; no runner.',
22
+ parameters: { results: { type: 'array', required: true, items: { type: 'object', additionalProperties: false, properties: { id: { type: 'string', required: true }, actual: { type: 'json', required: true }, expected: { type: 'json', required: true } } } } },
23
+ output: { schema: { type: 'object', additionalProperties: false, properties: { total: { type: 'number', required: true }, passed: { type: 'number', required: true }, failed: { type: 'number', required: true }, pass_rate: { type: 'number', required: true }, failures: { type: 'array', items: { type: 'string' }, required: true } } }, render: (_a, v) => text(`summary ${v.passed}/${v.total}`) },
24
+ async execute(args) { return summarize(args.results); },
25
+ });
26
+ return [lint, gradeTool, summary];
20
27
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-eval-pack",
3
- "version": "0.1.0-alpha.7",
3
+ "version": "0.1.0-alpha.8",
4
4
  "description": "Public/synthetic eval-pack lint and deterministic JSON grader; not a validated benchmark.",
5
5
  "type": "module",
6
6
  "main": "./lib/plugin/index.js",
package/screenshots.json CHANGED
@@ -10,5 +10,11 @@
10
10
  "kind": "demo",
11
11
  "alt": "Animated dsh-eval-pack terminal session",
12
12
  "caption": "The same run, assembled line by line."
13
+ },
14
+ {
15
+ "path": "docs/assets/dsh-eval-pack-capability.png",
16
+ "kind": "capability",
17
+ "alt": "dsh-eval-pack real test run",
18
+ "caption": "Real command: node --test test/summary.test.mjs — 4 tests passed, 0 failed (canonical grading and run summary). Run 2026-11-01; the image is rendered from the captured terminal output."
13
19
  }
14
20
  ]