@workos/quickstudy 0.6.1 → 0.7.0
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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@workos/quickstudy",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.7.0",
|
|
4
4
|
"description": "An open-source, company-agnostic eval harness for measuring whether coding agents can complete real integration tasks, across an agent x feature x framework x surface matrix.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -9,7 +9,7 @@ export const EMBEDDED_BUILD_INFO: {
|
|
|
9
9
|
// (the `x-release-please-version` marker anchors the replacement). It is
|
|
10
10
|
// restored as-is after a binary build (scripts/build-binary.ts), so the
|
|
11
11
|
// committed source `--version` stays in lockstep with package.json.
|
|
12
|
-
version: "0.
|
|
12
|
+
version: "0.7.0", // x-release-please-version
|
|
13
13
|
revision: null,
|
|
14
14
|
dirty: null,
|
|
15
15
|
sourceHash: null,
|
package/src/diagnose/render.ts
CHANGED
|
@@ -17,7 +17,7 @@ export function renderDiagnosisText(diagnosis: DiagnosisJson, resultsDir: string
|
|
|
17
17
|
lines.push(`diagnosis: run ${diagnosis.run_id}`);
|
|
18
18
|
lines.push(` model: ${diagnosis.model.requested}${diagnosis.model.resolved !== null ? ` (resolved: ${diagnosis.model.resolved})` : ""}`);
|
|
19
19
|
lines.push(
|
|
20
|
-
` pairs: ${diagnosis.pairs_diagnosed} diagnosed, ${diagnosis.pairs_skipped} skipped (
|
|
20
|
+
` pairs: ${diagnosis.pairs_diagnosed} diagnosed, ${diagnosis.pairs_skipped} skipped (passing or control)` +
|
|
21
21
|
(diagnosis.errors.length > 0 ? `, ${diagnosis.errors.length} errored` : ""),
|
|
22
22
|
);
|
|
23
23
|
|
package/src/diagnose/run.ts
CHANGED
|
@@ -30,6 +30,7 @@ import {
|
|
|
30
30
|
type PairBundle,
|
|
31
31
|
} from "./prompt.ts";
|
|
32
32
|
import { selectDiagnosablePairs, type DiagnosablePair } from "./select.ts";
|
|
33
|
+
import { controlExperiments } from "../report/report.ts";
|
|
33
34
|
import {
|
|
34
35
|
DIAGNOSIS_DISCLAIMER,
|
|
35
36
|
DIAGNOSIS_PROMPT_VERSION,
|
|
@@ -218,10 +219,13 @@ export async function runDiagnose(options: RunDiagnoseOptions): Promise<Diagnosi
|
|
|
218
219
|
|
|
219
220
|
const run = mustResolveRun(store, options.runId);
|
|
220
221
|
const attempts = store.listAttempts(run.id);
|
|
221
|
-
|
|
222
|
+
// Controls check the instrument, not an agent: the oracle passes and the
|
|
223
|
+
// no-op fails by construction, so their pairs carry no diagnosable cause.
|
|
224
|
+
const controls = controlExperiments(run);
|
|
225
|
+
const selection = selectDiagnosablePairs(attempts, { controls });
|
|
222
226
|
log(
|
|
223
227
|
`diagnose: run ${run.id} — ${selection.pairs.length} diagnosable pair(s), ` +
|
|
224
|
-
`${selection.skipped} passing pair(s) skipped`,
|
|
228
|
+
`${selection.skipped} passing pair(s) skipped, ${selection.controls} control pair(s) excluded`,
|
|
225
229
|
);
|
|
226
230
|
|
|
227
231
|
const findings: DiagnosisFinding[] = [];
|
|
@@ -281,7 +285,7 @@ export async function runDiagnose(options: RunDiagnoseOptions): Promise<Diagnosi
|
|
|
281
285
|
prompt_version: DIAGNOSIS_PROMPT_VERSION,
|
|
282
286
|
disclaimer: DIAGNOSIS_DISCLAIMER,
|
|
283
287
|
pairs_diagnosed: selection.pairs.length - errors.length,
|
|
284
|
-
pairs_skipped: selection.skipped,
|
|
288
|
+
pairs_skipped: selection.skipped + selection.controls,
|
|
285
289
|
findings,
|
|
286
290
|
errors,
|
|
287
291
|
};
|
package/src/diagnose/select.ts
CHANGED
|
@@ -47,6 +47,19 @@ export interface PairSelection {
|
|
|
47
47
|
pairs: DiagnosablePair[];
|
|
48
48
|
/** Passing-only pairs — skipped, never sent to the model. */
|
|
49
49
|
skipped: number;
|
|
50
|
+
/**
|
|
51
|
+
* Control pairs (the positive-control oracle, the negative-control no-op) —
|
|
52
|
+
* excluded before classification, never sent to the model. A control's
|
|
53
|
+
* outcome is fixed by construction: asked why the no-op "failed", a model
|
|
54
|
+
* confidently reports a broken harness. The report's scorer health watches
|
|
55
|
+
* the oracle instead.
|
|
56
|
+
*/
|
|
57
|
+
controls: number;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export interface SelectOptions {
|
|
61
|
+
/** Experiment ids the run recorded as controls (RunConfig.roles other than "agent"). */
|
|
62
|
+
controls?: ReadonlySet<string>;
|
|
50
63
|
}
|
|
51
64
|
|
|
52
65
|
/** Bundle ordering: failed first, then errors, then incomplete. */
|
|
@@ -58,10 +71,11 @@ const CLASS_ORDER: Record<Exclude<AttemptClass, "passed">, number> = {
|
|
|
58
71
|
|
|
59
72
|
/**
|
|
60
73
|
* Group attempts into pairs, classify, and select each diagnosable pair's
|
|
61
|
-
* bundle.
|
|
62
|
-
*
|
|
74
|
+
* bundle. Control experiments are excluded first (see PairSelection.controls).
|
|
75
|
+
* Deterministic: pairs sort by eval id then experiment id (the report's
|
|
76
|
+
* order); within a class, attempts sort by ULID (id) order.
|
|
63
77
|
*/
|
|
64
|
-
export function selectDiagnosablePairs(attempts: AttemptRecord[]): PairSelection {
|
|
78
|
+
export function selectDiagnosablePairs(attempts: AttemptRecord[], options: SelectOptions = {}): PairSelection {
|
|
65
79
|
const byPair = new Map<string, AttemptRecord[]>();
|
|
66
80
|
for (const attempt of attempts) {
|
|
67
81
|
const key = `${attempt.evalId}|${attempt.experimentId}`;
|
|
@@ -72,8 +86,13 @@ export function selectDiagnosablePairs(attempts: AttemptRecord[]): PairSelection
|
|
|
72
86
|
|
|
73
87
|
const pairs: DiagnosablePair[] = [];
|
|
74
88
|
let skipped = 0;
|
|
89
|
+
let controls = 0;
|
|
75
90
|
|
|
76
91
|
for (const group of byPair.values()) {
|
|
92
|
+
if (options.controls?.has(group[0]!.experimentId)) {
|
|
93
|
+
controls += 1;
|
|
94
|
+
continue;
|
|
95
|
+
}
|
|
77
96
|
const report = collectPairs(group)[0]!;
|
|
78
97
|
if (report.failed + report.errors + report.incomplete === 0) {
|
|
79
98
|
skipped += 1;
|
|
@@ -106,5 +125,5 @@ export function selectDiagnosablePairs(attempts: AttemptRecord[]): PairSelection
|
|
|
106
125
|
}
|
|
107
126
|
|
|
108
127
|
pairs.sort((a, b) => a.evalId.localeCompare(b.evalId) || a.experimentId.localeCompare(b.experimentId));
|
|
109
|
-
return { pairs, skipped };
|
|
128
|
+
return { pairs, skipped, controls };
|
|
110
129
|
}
|
package/src/diagnose/types.ts
CHANGED
|
@@ -85,6 +85,7 @@ export interface DiagnosisJson {
|
|
|
85
85
|
/** Fixed self-labeling: hypotheses with evidence links, not verdicts; single-sweep scope. */
|
|
86
86
|
disclaimer: string;
|
|
87
87
|
pairs_diagnosed: number;
|
|
88
|
+
/** Pairs never sent to the model: passing-only pairs and control (oracle / no-op) pairs. */
|
|
88
89
|
pairs_skipped: number;
|
|
89
90
|
findings: DiagnosisFinding[];
|
|
90
91
|
errors: PairDiagnosisError[];
|
package/src/report/report.ts
CHANGED
|
@@ -454,7 +454,7 @@ function roleOf(run: RunRecord, experimentId: string): ExperimentRole {
|
|
|
454
454
|
}
|
|
455
455
|
|
|
456
456
|
/** The run's control experiments, from the roles it recorded. */
|
|
457
|
-
function controlExperiments(run: RunRecord): Set<string> {
|
|
457
|
+
export function controlExperiments(run: RunRecord): Set<string> {
|
|
458
458
|
return new Set(run.config.experimentIds.filter((id) => roleOf(run, id) !== "agent"));
|
|
459
459
|
}
|
|
460
460
|
|