@wix/pathgrade 1.0.27 → 1.0.29
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/README.md +12 -19
- package/dist/adapters/jest/invocation-adapter.js +5 -1
- package/dist/adapters/jest/reporter.js +4 -1
- package/dist/adapters/jest/results.js +8 -0
- package/dist/adapters/node-test/index.d.ts +5 -0
- package/dist/adapters/node-test/index.js +35 -7
- package/dist/adapters/node-test/invocation-adapter.js +3 -1
- package/dist/adapters/node-test/runner-adapter.js +22 -15
- package/dist/adapters/vitest/reporter.js +4 -1
- package/dist/agents/claude.js +5 -4
- package/dist/agents/codex-app-server/agent.js +1 -51
- package/dist/agents/codex-app-server/turn-notifications.d.ts +6 -0
- package/dist/agents/codex-app-server/turn-notifications.js +51 -0
- package/dist/agents/codex-app-server/turn-state.d.ts +19 -0
- package/dist/agents/codex-app-server/turn-state.js +1 -0
- package/dist/agents/opencode/protocol.d.ts +7 -0
- package/dist/agents/opencode/protocol.js +47 -0
- package/dist/agents/opencode.js +1 -47
- package/dist/analytics/engine.js +5 -2
- package/dist/commands/report.js +16 -2
- package/dist/commands/run-args.d.ts +1 -0
- package/dist/commands/run-args.js +13 -0
- package/dist/commands/run-changed.js +5 -15
- package/dist/config/pathgrade.d.ts +3 -0
- package/dist/config/pathgrade.js +33 -1
- package/dist/internal/direct-mcp-v2/claude-direct-mcp.d.ts +2 -1
- package/dist/internal/direct-mcp-v2/claude-direct-mcp.js +35 -17
- package/dist/internal/direct-mcp-v2/claude-profile.d.ts +33 -7
- package/dist/internal/direct-mcp-v2/claude-profile.js +104 -72
- package/dist/internal/direct-mcp-v2/public-scenario-runtime.js +13 -16
- package/dist/pathgrade.js +10 -2
- package/dist/reporters/cli.js +13 -6
- package/dist/reporters/github-comment.js +12 -9
- package/dist/reporters/loader.d.ts +1 -0
- package/dist/reporters/loader.js +27 -2
- package/dist/reporters/report-summary.js +13 -5
- package/dist/reporting/core.d.ts +1 -0
- package/dist/reporting/core.js +183 -105
- package/dist/reporting/types.d.ts +19 -3
- package/dist/runners/adapter-loader.js +17 -12
- package/dist/runners/direct-reporter-attempts.d.ts +1 -0
- package/dist/runners/direct-reporter-attempts.js +7 -0
- package/dist/runners/invocation.d.ts +2 -0
- package/dist/runners/model-builders.js +1 -0
- package/dist/runners/model-validation.js +31 -0
- package/dist/runners/model.d.ts +4 -0
- package/dist/runners/orchestrator.d.ts +2 -0
- package/dist/runners/orchestrator.js +11 -1
- package/dist/runners/repeated-attempts.d.ts +7 -0
- package/dist/runners/repeated-attempts.js +149 -0
- package/dist/runners/repeated-invocation.d.ts +7 -0
- package/dist/runners/repeated-invocation.js +129 -0
- package/dist/runners/report-projection.js +16 -6
- package/dist/runners/vitest-adapter.js +10 -0
- package/dist/runners/vitest-invocation.js +2 -0
- package/dist/sdk/agent-runtime-options.d.ts +12 -0
- package/dist/sdk/agent-runtime-options.js +67 -0
- package/dist/sdk/agent.js +4 -57
- package/dist/sdk/case-context.js +7 -2
- package/dist/sdk/lifecycle.js +8 -3
- package/dist/sdk/result-capture.js +4 -1
- package/dist/types.d.ts +34 -5
- package/dist/viewer.html +19 -19
- package/package.json +2 -2
package/dist/types.d.ts
CHANGED
|
@@ -150,6 +150,14 @@ export interface LogEntry {
|
|
|
150
150
|
}
|
|
151
151
|
export interface TrialResult {
|
|
152
152
|
trial_id: number;
|
|
153
|
+
/** Stable semantic case identity in schema-v2 reports. */
|
|
154
|
+
case_id?: string;
|
|
155
|
+
/** Unique identity for one runner-owned execution of the case. */
|
|
156
|
+
attempt_id?: string;
|
|
157
|
+
/** One-based invocation index. */
|
|
158
|
+
attempt_index?: number;
|
|
159
|
+
/** Display-safe runner outcome for this specific attempt. */
|
|
160
|
+
runner_outcome?: import('./runners/model.js').AttemptOutcome['kind'];
|
|
153
161
|
name?: string;
|
|
154
162
|
reward?: number;
|
|
155
163
|
scorer_results: ScorerResult[];
|
|
@@ -192,9 +200,22 @@ export interface TrialResult {
|
|
|
192
200
|
}
|
|
193
201
|
export interface EvalReport {
|
|
194
202
|
task: string;
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
203
|
+
/** Canonical status for this report or consolidated group when available. */
|
|
204
|
+
status?: 'pass' | 'fail';
|
|
205
|
+
/** Schema-v2 canonical average score. */
|
|
206
|
+
mean_reward?: number;
|
|
207
|
+
/** Binary success frequency, absent when attempts are ineligible. */
|
|
208
|
+
success_rate?: number;
|
|
209
|
+
/** Finite-sample pass@k values keyed by k in schema v2; number only for v1 reads. */
|
|
210
|
+
pass_at_k?: Record<string, number> | number;
|
|
211
|
+
pass_at_k_method?: 'finite_sample_unbiased';
|
|
212
|
+
pass_at_k_unavailable_reason?: PassAtKUnavailableReason;
|
|
213
|
+
eligible_case_count?: number;
|
|
214
|
+
attempts_per_case?: number;
|
|
215
|
+
/** @deprecated Version-1 artifact compatibility only. */
|
|
216
|
+
pass_rate?: number;
|
|
217
|
+
/** @deprecated Version-1 artifact compatibility only. New writers omit it. */
|
|
218
|
+
pass_pow_k?: number;
|
|
198
219
|
trials: TrialResult[];
|
|
199
220
|
skills_used: string[];
|
|
200
221
|
}
|
|
@@ -208,7 +229,8 @@ export type StrippedTrialResult = Omit<TrialResult, 'session_log' | 'conversatio
|
|
|
208
229
|
/**
|
|
209
230
|
* Per-group entry in the consolidated `.pathgrade/results.json` report.
|
|
210
231
|
*/
|
|
211
|
-
export type PathgradeGroupReport = Omit<EvalReport, 'trials'> & {
|
|
232
|
+
export type PathgradeGroupReport = Omit<EvalReport, 'trials' | 'status'> & {
|
|
233
|
+
status?: 'pass' | 'fail';
|
|
212
234
|
trials: StrippedTrialResult[];
|
|
213
235
|
/** Relative path from `.pathgrade/` to the trace file for this group. */
|
|
214
236
|
trace_file: string;
|
|
@@ -239,12 +261,16 @@ export interface PathgradeSelectionReport {
|
|
|
239
261
|
* external consumers can gate on schema revisions.
|
|
240
262
|
*/
|
|
241
263
|
export interface PathgradeReport {
|
|
242
|
-
version: 1;
|
|
264
|
+
version: 1 | 2;
|
|
243
265
|
timestamp: string;
|
|
244
266
|
/** `ci.threshold` from Pathgrade config or legacy plugin config, if configured. */
|
|
245
267
|
threshold?: number;
|
|
246
268
|
/** Weighted average of every individual trial score across all groups. */
|
|
247
269
|
overall_pass_rate: number;
|
|
270
|
+
/** Canonical schema-v2 average reward. */
|
|
271
|
+
overall_mean_reward?: number;
|
|
272
|
+
attempts_requested?: number;
|
|
273
|
+
attempts_completed?: number;
|
|
248
274
|
/**
|
|
249
275
|
* Threshold check result. When `threshold` is set: `'pass'` iff
|
|
250
276
|
* `overall_pass_rate >= threshold`. Otherwise: `'pass'` iff every trial
|
|
@@ -259,6 +285,7 @@ export interface PathgradeReport {
|
|
|
259
285
|
*/
|
|
260
286
|
selection?: PathgradeSelectionReport;
|
|
261
287
|
}
|
|
288
|
+
export type PassAtKUnavailableReason = 'non_binary_reward' | 'incomplete_attempts' | 'case_identity_mismatch';
|
|
262
289
|
export interface TrialPaths {
|
|
263
290
|
root: string;
|
|
264
291
|
workspace: string;
|
|
@@ -396,6 +423,8 @@ export interface AgentSessionOptions {
|
|
|
396
423
|
scriptedMcpHost?: import('./providers/scripted-mcp-mock-host.js').ScriptedMcpMockHost;
|
|
397
424
|
/** Parent-owned public ScenarioMachineV2 bridge; never serialized into child config. */
|
|
398
425
|
scenarioMcpServers?: Record<string, import('@anthropic-ai/claude-agent-sdk').McpSdkServerConfigWithInstance>;
|
|
426
|
+
/** RuntimeLock-admitted Claude executable; wins over developer overrides for ScenarioMachineV2 sessions. */
|
|
427
|
+
admittedClaudeCodeExecutable?: string;
|
|
399
428
|
/** Parent-owned admitted Codex app-server mount; projected only into thread/start memory. */
|
|
400
429
|
codexScenarioMount?: import('./agents/codex-app-server/scenario-mount.js').CodexScenarioMount;
|
|
401
430
|
/** Runtime-only values inherited by drivers and persistence sinks for redaction. */
|
package/dist/viewer.html
CHANGED
|
@@ -838,12 +838,13 @@
|
|
|
838
838
|
applyTheme(getTheme());
|
|
839
839
|
|
|
840
840
|
// ─── State ─────────────────────────────────────────────────
|
|
841
|
-
let reports = [];
|
|
842
|
-
let sortKey = 'date';
|
|
843
|
-
let sortDir = 'desc';
|
|
841
|
+
let reports = [], sortKey = 'date', sortDir = 'desc';
|
|
844
842
|
const $ = id => document.getElementById(id);
|
|
845
843
|
const esc = s => s ? String(s).replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>') : '';
|
|
846
|
-
|
|
844
|
+
const meanReward = r => r.mean_reward ?? r.pass_rate ?? 0;
|
|
845
|
+
const reportStatus = r => r.status === 'pass' || r.status === 'fail' ? r.status : (meanReward(r) >= 0.5 ? 'pass' : 'fail');
|
|
846
|
+
const passAtKSortValue = r => typeof r.pass_at_k === 'number' ? r.pass_at_k : (r.pass_at_k ? Math.max(...Object.values(r.pass_at_k)) : -1);
|
|
847
|
+
const passAtKDisplay = r => typeof r.pass_at_k === 'number' ? (r.pass_at_k * 100).toFixed(0) + '% v1' : r.pass_at_k ? Object.entries(r.pass_at_k).map(([k, value]) => '@' + k + ' ' + (value * 100).toFixed(0) + '%').join(' · ') : r.pass_at_k_unavailable_reason ? '— ' + r.pass_at_k_unavailable_reason.replaceAll('_', ' ') : '—';
|
|
847
848
|
function parseDate(file) {
|
|
848
849
|
// filename format: 2026-04-08T14-25-03-134Z → 2026-04-08T14:25:03.134
|
|
849
850
|
const m = file.match(/(\d{4}-\d{2}-\d{2})T(\d{2})-(\d{2})-(\d{2})-(\d+)/);
|
|
@@ -877,10 +878,10 @@
|
|
|
877
878
|
switch (sortKey) {
|
|
878
879
|
case 'task': va = (a.task || '').toLowerCase(); vb = (b.task || '').toLowerCase(); break;
|
|
879
880
|
case 'date': va = parseDate(a.file); vb = parseDate(b.file); break;
|
|
880
|
-
case '
|
|
881
|
-
case '
|
|
882
|
-
case '
|
|
883
|
-
case 'status': va = a
|
|
881
|
+
case 'mean_reward': va = meanReward(a); vb = meanReward(b); break;
|
|
882
|
+
case 'success_rate': va = a.success_rate ?? -1; vb = b.success_rate ?? -1; break;
|
|
883
|
+
case 'pass_at_k': va = passAtKSortValue(a); vb = passAtKSortValue(b); break;
|
|
884
|
+
case 'status': va = reportStatus(a) === 'pass' ? 1 : 0; vb = reportStatus(b) === 'pass' ? 1 : 0; break;
|
|
884
885
|
default: return 0;
|
|
885
886
|
}
|
|
886
887
|
if (va < vb) return sortDir === 'asc' ? -1 : 1;
|
|
@@ -936,24 +937,23 @@
|
|
|
936
937
|
const header = `<div class="reports-header">
|
|
937
938
|
${colHeader('task', 'Task')}
|
|
938
939
|
${colHeader('date', 'Date')}
|
|
939
|
-
${colHeader('
|
|
940
|
+
${colHeader('mean_reward', 'Mean Reward', 'center')}
|
|
941
|
+
${colHeader('success_rate', 'Success Rate', 'center')}
|
|
940
942
|
${colHeader('pass_at_k', 'pass@k', 'center')}
|
|
941
|
-
${colHeader('pass_pow_k', 'pass^k', 'center')}
|
|
942
943
|
${colHeader('status', 'Status', 'center')}
|
|
943
944
|
<div></div>
|
|
944
945
|
</div>`;
|
|
945
946
|
|
|
946
947
|
const rows = sorted.map(r => {
|
|
947
|
-
const
|
|
948
|
-
const isPass = r.pass_rate >= 0.5;
|
|
948
|
+
const reward = (meanReward(r) * 100).toFixed(0), isPass = reportStatus(r) === 'pass';
|
|
949
949
|
const ts = r.timestamp || parseDate(r.file);
|
|
950
950
|
|
|
951
951
|
return `<a class="report-row" onclick="navigate('detail','${esc(r.file)}')" href="javascript:void(0)">
|
|
952
952
|
<div class="report-task">${esc(r.task)}</div>
|
|
953
953
|
<div class="report-date">${formatDate(ts)}</div>
|
|
954
|
-
<div class="report-metric"><div class="val">${
|
|
955
|
-
<div class="report-metric"><div class="val">${r.
|
|
956
|
-
<div class="report-metric"><div class="val">${
|
|
954
|
+
<div class="report-metric"><div class="val">${reward}%</div></div>
|
|
955
|
+
<div class="report-metric"><div class="val">${r.success_rate != null ? (r.success_rate * 100).toFixed(0) + '%' : '—'}</div></div>
|
|
956
|
+
<div class="report-metric"><div class="val">${esc(passAtKDisplay(r))}</div></div>
|
|
957
957
|
<div style="text-align:center"><span class="badge ${isPass ? 'badge-pass' : 'badge-fail'}">${isPass ? 'PASS' : 'FAIL'}</span></div>
|
|
958
958
|
<button class="delete-btn" onclick="event.preventDefault();event.stopPropagation();deleteReport('${esc(r.file)}')" title="Delete report">✕</button>
|
|
959
959
|
</a>`;
|
|
@@ -975,9 +975,9 @@
|
|
|
975
975
|
const totalTokens = r.trials.reduce((s, t) => s + (t.input_tokens || 0) + (t.output_tokens || 0) + (t.conversation_input_tokens || 0) + (t.conversation_output_tokens || 0), 0);
|
|
976
976
|
|
|
977
977
|
const stats = `
|
|
978
|
-
<div class="stat-pill"><div class="val">${(r
|
|
979
|
-
<div class="stat-pill"><div class="val">${r.
|
|
980
|
-
<div class="stat-pill"><div class="val">${
|
|
978
|
+
<div class="stat-pill"><div class="val">${(meanReward(r) * 100).toFixed(1)}%</div><div class="lbl">Mean Reward</div></div>
|
|
979
|
+
<div class="stat-pill"><div class="val">${r.success_rate != null ? (r.success_rate * 100).toFixed(1) + '%' : '—'}</div><div class="lbl">Success Rate</div></div>
|
|
980
|
+
<div class="stat-pill"><div class="val">${esc(passAtKDisplay(r))}</div><div class="lbl">pass@k</div></div>
|
|
981
981
|
<div class="stat-pill"><div class="val">${(avgDur / 1000).toFixed(1)}s</div><div class="lbl">Avg Duration</div></div>
|
|
982
982
|
<div class="stat-pill"><div class="val">~${totalTokens}</div><div class="lbl">Total Tokens</div></div>
|
|
983
983
|
<div class="stat-pill"><div class="val">${r.skills_used?.join(', ') || 'none'}</div><div class="lbl">Skills</div></div>
|
|
@@ -999,7 +999,7 @@
|
|
|
999
999
|
}
|
|
1000
1000
|
function renderTrial(t, idx) {
|
|
1001
1001
|
const evaluated = t.reward !== undefined;
|
|
1002
|
-
const pass = evaluated && t.reward >= 0.5;
|
|
1002
|
+
const pass = evaluated && (t.runner_outcome === undefined ? t.reward >= 0.5 : t.runner_outcome === 'passed' && t.reward === 1);
|
|
1003
1003
|
const dur = ((t.duration_ms || 0) / 1000).toFixed(1);
|
|
1004
1004
|
const tokens = (t.input_tokens || 0) + (t.output_tokens || 0);
|
|
1005
1005
|
const convTokens = (t.conversation_input_tokens || 0) + (t.conversation_output_tokens || 0);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wix/pathgrade",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.29",
|
|
4
4
|
"packageManager": "yarn@4.12.0",
|
|
5
5
|
"description": "Evaluate whether AI agents discover and use your skills correctly",
|
|
6
6
|
"exports": {
|
|
@@ -140,5 +140,5 @@
|
|
|
140
140
|
"typescript": "^5.9.3",
|
|
141
141
|
"zod": "4.3.6"
|
|
142
142
|
},
|
|
143
|
-
"falconPackageHash": "
|
|
143
|
+
"falconPackageHash": "126198d020df14b3e6fceef3b0325ac5e84411c5e1b544a0167de604"
|
|
144
144
|
}
|