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

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,6 +1,12 @@
1
1
  # Changelog
2
2
 
3
- ## [0.1.0-alpha.8] — 2026-11-01
3
+ ## [0.1.0-alpha.9] — 2026-11-01
4
+
5
+ ### Added
6
+
7
+ - `eval.pass_at_k`: unbiased pass@k estimator `1 - C(n-c,k)/C(n,k)` with exact binomials, plus the per-task and mean values. Verified by `node --test test/*.test.mjs` (12/12).
8
+
9
+ ## [Unreleased]
4
10
 
5
11
  ### Added
6
12
 
@@ -24,3 +24,25 @@ export interface EvalSummary {
24
24
  failures: string[];
25
25
  }
26
26
  export declare function summarize(results: EvalResult[]): EvalSummary;
27
+ export interface PassAtKInput {
28
+ task_id: string;
29
+ samples: number;
30
+ correct: number;
31
+ }
32
+ export interface PassAtKResult {
33
+ task_id: string;
34
+ k: number;
35
+ n: number;
36
+ c: number;
37
+ pass_at_k: number;
38
+ }
39
+ /**
40
+ * Unbiased pass@k estimator: 1 - C(n-c, k) / C(n, k).
41
+ * Clean-room from the published estimator definition; exact binomials via BigInt.
42
+ */
43
+ export declare function passAtK(task: PassAtKInput, k: number): PassAtKResult;
44
+ export declare function passAtKMean(tasks: PassAtKInput[], k: number): {
45
+ k: number;
46
+ tasks: PassAtKResult[];
47
+ mean: number;
48
+ };
@@ -53,3 +53,33 @@ export function summarize(results) {
53
53
  const total = results.length;
54
54
  return { total, passed, failed: total - passed, pass_rate: total ? Math.round((passed / total) * 1e6) / 1e6 : 0, failures };
55
55
  }
56
+ function comb(n, k) {
57
+ if (k < 0 || k > n)
58
+ return 0n;
59
+ let result = 1n;
60
+ for (let i = 1n; i <= BigInt(k); i += 1n)
61
+ result = (result * (BigInt(n) - BigInt(k) + i)) / i;
62
+ return result;
63
+ }
64
+ /**
65
+ * Unbiased pass@k estimator: 1 - C(n-c, k) / C(n, k).
66
+ * Clean-room from the published estimator definition; exact binomials via BigInt.
67
+ */
68
+ export function passAtK(task, k) {
69
+ const { samples, correct } = task;
70
+ if (!Number.isInteger(samples) || samples < 1)
71
+ throw new Error('E_EVAL_SAMPLES: samples must be a positive integer');
72
+ if (!Number.isInteger(correct) || correct < 0 || correct > samples)
73
+ throw new Error('E_EVAL_CORRECT: correct must be between 0 and samples');
74
+ if (!Number.isInteger(k) || k < 1 || k > samples)
75
+ throw new Error('E_EVAL_K: k must be between 1 and samples');
76
+ const denominator = comb(samples, k);
77
+ const numerator = comb(samples - correct, k);
78
+ const value = 1 - Number(numerator) / Number(denominator);
79
+ return { task_id: task.task_id, k, n: samples, c: correct, pass_at_k: Math.round(value * 1e6) / 1e6 };
80
+ }
81
+ export function passAtKMean(tasks, k) {
82
+ const results = tasks.map((t) => passAtK(t, k));
83
+ const mean = results.length ? Math.round((results.reduce((sum, r) => sum + r.pass_at_k, 0) / results.length) * 1e6) / 1e6 : 0;
84
+ return { k, tasks: results, mean };
85
+ }
@@ -1,5 +1,5 @@
1
1
  import { defineTool } from '@deepseek-ai/dsh-tools';
2
- import { grade, lintPack, summarize } from '../core/harness.js';
2
+ import { grade, lintPack, passAtKMean, summarize } from '../core/harness.js';
3
3
  const text = (t) => [{ type: 'text', text: t }];
4
4
  export function createTools() {
5
5
  const lint = defineTool({
@@ -23,5 +23,12 @@ export function createTools() {
23
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
24
  async execute(args) { return summarize(args.results); },
25
25
  });
26
- return [lint, gradeTool, summary];
26
+ const passAtKTool = defineTool({
27
+ name: 'eval.pass_at_k',
28
+ description: 'Unbiased pass@k for sampled tasks: 1 - C(n-c, k)/C(n, k), exact binomials. Read-only; no runner.',
29
+ parameters: { k: { type: 'number', required: true }, tasks: { type: 'array', required: true, items: { type: 'object', additionalProperties: false, properties: { task_id: { type: 'string', required: true }, samples: { type: 'number', required: true }, correct: { type: 'number', required: true } } } } },
30
+ output: { schema: { type: 'object', additionalProperties: false, properties: { k: { type: 'number', required: true }, mean: { type: 'number', required: true }, tasks: { type: 'array', required: true, items: { type: 'object', additionalProperties: false, properties: { task_id: { type: 'string', required: true }, pass_at_k: { type: 'number', required: true } } } } } }, render: (_a, v) => text(`pass@${v.k} mean ${v.mean}`) },
31
+ async execute(args) { const r = passAtKMean(args.tasks, args.k); return { k: r.k, mean: r.mean, tasks: r.tasks.map((t) => ({ task_id: t.task_id, pass_at_k: t.pass_at_k })) }; },
32
+ });
33
+ return [lint, gradeTool, summary, passAtKTool];
27
34
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-eval-pack",
3
- "version": "0.1.0-alpha.8",
3
+ "version": "0.1.0-alpha.9",
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
@@ -16,5 +16,11 @@
16
16
  "kind": "capability",
17
17
  "alt": "dsh-eval-pack real test run",
18
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."
19
+ },
20
+ {
21
+ "path": "docs/assets/dsh-eval-pack-capability2.png",
22
+ "kind": "capability",
23
+ "alt": "dsh-eval-pack second capability run",
24
+ "caption": "Real command: node --test test/pass-at-k.test.mjs — 5 tests passed, 0 failed (Unbiased pass@k estimator with exact binomials.) Run 2026-11-01; rendered from the captured terminal output."
19
25
  }
20
26
  ]