@bastani/atomic 0.9.16-alpha.7 → 0.9.16-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 +19 -0
- package/dist/builtin/intercom/CHANGELOG.md +6 -0
- package/dist/builtin/intercom/README.md +4 -4
- package/dist/builtin/intercom/broker/broker.ts +617 -22
- package/dist/builtin/intercom/broker/client-message-validation.ts +9 -0
- package/dist/builtin/intercom/broker/client.ts +200 -10
- package/dist/builtin/intercom/broker/pending-send-registry.ts +4 -0
- package/dist/builtin/intercom/broker/send-handler.ts +90 -36
- package/dist/builtin/intercom/broker/send-signature.ts +20 -8
- package/dist/builtin/intercom/group.ts +85 -0
- package/dist/builtin/intercom/index.bundle.mjs +680 -53
- package/dist/builtin/intercom/package.json +1 -1
- package/dist/builtin/intercom/session-target.ts +54 -0
- package/dist/builtin/intercom/skills/intercom/SKILL.md +18 -3
- package/dist/builtin/intercom/source-ownership.ts +31 -0
- package/dist/builtin/intercom/types.ts +115 -0
- package/dist/builtin/mcp/index.bundle.mjs +109 -35
- package/dist/builtin/mcp/package.json +1 -1
- package/dist/builtin/subagents/package.json +1 -1
- package/dist/builtin/subagents/src/extension/index.bundle.mjs +173 -51
- package/dist/builtin/web-access/index.bundle.mjs +109 -35
- package/dist/builtin/web-access/package.json +1 -1
- package/dist/builtin/workflows/CHANGELOG.md +15 -0
- package/dist/builtin/workflows/README.md +40 -37
- package/dist/builtin/workflows/builtin/adversarial-verification.js +13 -0
- package/dist/builtin/workflows/builtin/{shared-prompts.ts → chunk-0x6e303p.js} +133 -154
- package/dist/builtin/workflows/builtin/chunk-29wrp38a.js +199 -0
- package/dist/builtin/workflows/builtin/chunk-2dqb5s2q.js +602 -0
- package/dist/builtin/workflows/builtin/chunk-4febxsv4.js +264 -0
- package/dist/builtin/workflows/builtin/chunk-5n10x7j2.js +69730 -0
- package/dist/builtin/workflows/builtin/chunk-5wgwscd0.js +4 -0
- package/dist/builtin/workflows/builtin/chunk-6fqs7c01.js +155 -0
- package/dist/builtin/workflows/builtin/chunk-7430zyas.js +126 -0
- package/dist/builtin/workflows/builtin/chunk-7at6dnkr.js +33 -0
- package/dist/builtin/workflows/builtin/chunk-82ha8p41.js +175 -0
- package/dist/builtin/workflows/builtin/chunk-bfkmzv9h.js +156 -0
- package/dist/builtin/workflows/builtin/chunk-c53y8bdh.js +345 -0
- package/dist/builtin/workflows/builtin/chunk-cdtd3m3w.js +529 -0
- package/dist/builtin/workflows/builtin/chunk-cg9tmks0.js +206 -0
- package/dist/builtin/workflows/builtin/chunk-hdpj1dkw.js +2447 -0
- package/dist/builtin/workflows/builtin/chunk-hzzn6adg.js +221 -0
- package/dist/builtin/workflows/builtin/chunk-nqr34qp3.js +1061 -0
- package/dist/builtin/workflows/builtin/chunk-qwzvgxnq.js +404 -0
- package/dist/builtin/workflows/builtin/chunk-qx2ptjs3.js +215 -0
- package/dist/builtin/workflows/builtin/chunk-v04c5qmd.js +1207 -0
- package/dist/builtin/workflows/builtin/chunk-wpckd35c.js +12 -0
- package/dist/builtin/workflows/builtin/chunk-x2ghn0je.js +4110 -0
- package/dist/builtin/workflows/builtin/chunk-zf28603f.js +1080 -0
- package/dist/builtin/workflows/builtin/classify-and-act.js +12 -0
- package/dist/builtin/workflows/builtin/fan-out-and-synthesize.js +10 -0
- package/dist/builtin/workflows/builtin/generate-and-filter.js +12 -0
- package/dist/builtin/workflows/builtin/goal.js +16 -0
- package/dist/builtin/workflows/builtin/index.js +49 -0
- package/dist/builtin/workflows/builtin/loop-until-done.js +12 -0
- package/dist/builtin/workflows/builtin/open-claude-design.js +11 -0
- package/dist/builtin/workflows/builtin/ralph.js +16 -0
- package/dist/builtin/workflows/builtin/steering-context.d.ts +6 -0
- package/dist/builtin/workflows/builtin/steering-context.js +7 -0
- package/dist/builtin/workflows/builtin/tournament.js +13 -0
- package/dist/builtin/workflows/package.json +10 -7
- package/dist/builtin/workflows/src/authoring/typebox-defaults.d.ts +41 -0
- package/dist/builtin/workflows/src/extension/index.bundle.mjs +1228 -428
- package/dist/builtin/workflows/src/{index.bundle.mjs → index.js} +956 -427
- package/dist/builtin/workflows/src/shared/authoring-contract-stage.d.ts +403 -0
- package/dist/builtin/workflows/src/shared/authoring-contract-ui.d.ts +327 -0
- package/dist/builtin/workflows/src/shared/budget.d.ts +67 -0
- package/dist/builtin/workflows/src/shared/workflow-authoring-types.d.ts +60 -0
- package/dist/builtin/workflows/src/shared/workflow-heartbeat-contract.d.ts +21 -0
- package/dist/core/agent-session-custom-message-commit.d.ts.map +1 -1
- package/dist/core/agent-session-custom-message-commit.js +12 -5
- package/dist/core/agent-session-custom-message-commit.js.map +1 -1
- package/dist/core/agent-session-persistent-custom-messages.d.ts.map +1 -1
- package/dist/core/agent-session-persistent-custom-messages.js +2 -0
- package/dist/core/agent-session-persistent-custom-messages.js.map +1 -1
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +2 -1
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/auth-storage.d.ts +2 -0
- package/dist/core/auth-storage.d.ts.map +1 -1
- package/dist/core/auth-storage.js +4 -0
- package/dist/core/auth-storage.js.map +1 -1
- package/dist/core/builtin-install-layout.d.ts +1 -1
- package/dist/core/builtin-install-layout.d.ts.map +1 -1
- package/dist/core/builtin-install-layout.js +1 -1
- package/dist/core/builtin-install-layout.js.map +1 -1
- package/dist/core/codex-fast-mode.d.ts +10 -7
- package/dist/core/codex-fast-mode.d.ts.map +1 -1
- package/dist/core/codex-fast-mode.js +31 -13
- package/dist/core/codex-fast-mode.js.map +1 -1
- package/dist/core/extensions/context-types.d.ts +35 -0
- package/dist/core/extensions/context-types.d.ts.map +1 -1
- package/dist/core/extensions/context-types.js.map +1 -1
- package/dist/core/extensions/index.d.ts +1 -1
- package/dist/core/extensions/index.d.ts.map +1 -1
- package/dist/core/extensions/index.js.map +1 -1
- package/dist/core/extensions/loader-virtual-modules.d.ts.map +1 -1
- package/dist/core/extensions/loader-virtual-modules.js +6 -1
- package/dist/core/extensions/loader-virtual-modules.js.map +1 -1
- package/dist/core/model-runtime.d.ts +2 -0
- package/dist/core/model-runtime.d.ts.map +1 -1
- package/dist/core/model-runtime.js +4 -0
- package/dist/core/model-runtime.js.map +1 -1
- package/dist/core/runtime-credentials.d.ts +1 -0
- package/dist/core/runtime-credentials.d.ts.map +1 -1
- package/dist/core/runtime-credentials.js +8 -0
- package/dist/core/runtime-credentials.js.map +1 -1
- package/dist/core/sdk.d.ts.map +1 -1
- package/dist/core/sdk.js +5 -5
- package/dist/core/sdk.js.map +1 -1
- package/dist/core/session-manager-storage.d.ts +2 -0
- package/dist/core/session-manager-storage.d.ts.map +1 -1
- package/dist/core/session-manager-storage.js +4 -2
- package/dist/core/session-manager-storage.js.map +1 -1
- package/dist/core/slash-commands.js +1 -1
- package/dist/core/slash-commands.js.map +1 -1
- package/dist/core/workflow-stage-admission.d.ts +6 -1
- package/dist/core/workflow-stage-admission.d.ts.map +1 -1
- package/dist/core/workflow-stage-admission.js +8 -9
- package/dist/core/workflow-stage-admission.js.map +1 -1
- package/dist/index.d.ts +0 -1
- package/dist/modes/interactive/components/footer.d.ts.map +1 -1
- package/dist/modes/interactive/components/footer.js +1 -1
- package/dist/modes/interactive/components/footer.js.map +1 -1
- package/dist/modes/interactive/interactive-autocomplete.js +1 -1
- package/dist/modes/interactive/interactive-autocomplete.js.map +1 -1
- package/dist/modes/interactive/interactive-startup.js +1 -1
- package/dist/modes/interactive/interactive-startup.js.map +1 -1
- package/dist/modes/interactive-engine/isolated-runtime.d.ts +4 -0
- package/dist/modes/interactive-engine/isolated-runtime.d.ts.map +1 -1
- package/dist/modes/interactive-engine/isolated-runtime.js +69 -10
- package/dist/modes/interactive-engine/isolated-runtime.js.map +1 -1
- package/dist/modes/rpc/rpc-client-api.d.ts +18 -2
- package/dist/modes/rpc/rpc-client-api.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-client-api.js +33 -5
- package/dist/modes/rpc/rpc-client-api.js.map +1 -1
- package/dist/modes/rpc/rpc-command-handler.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-command-handler.js +8 -4
- package/dist/modes/rpc/rpc-command-handler.js.map +1 -1
- package/dist/modes/rpc/rpc-types.d.ts +13 -0
- package/dist/modes/rpc/rpc-types.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-types.js.map +1 -1
- package/docs/intercom.md +15 -6
- package/docs/packages.md +2 -2
- package/docs/providers.md +8 -3
- package/docs/quickstart.md +2 -2
- package/docs/rpc.md +21 -4
- package/docs/settings.md +6 -4
- package/docs/subagents.md +1 -1
- package/docs/usage.md +1 -1
- package/docs/workflows.md +108 -239
- package/npm-shrinkwrap.json +32 -32
- package/package.json +9 -13
- package/dist/builtin/workflows/ambient.d.ts +0 -61
- package/dist/builtin/workflows/builtin/adversarial-verification-prompts.ts +0 -26
- package/dist/builtin/workflows/builtin/adversarial-verification-runner.ts +0 -391
- package/dist/builtin/workflows/builtin/adversarial-verification.ts +0 -34
- package/dist/builtin/workflows/builtin/classify-and-act-prompts.ts +0 -14
- package/dist/builtin/workflows/builtin/classify-and-act-runner.ts +0 -108
- package/dist/builtin/workflows/builtin/classify-and-act.ts +0 -40
- package/dist/builtin/workflows/builtin/fan-out-and-synthesize-prompts.ts +0 -14
- package/dist/builtin/workflows/builtin/fan-out-and-synthesize-runner.ts +0 -96
- package/dist/builtin/workflows/builtin/fan-out-and-synthesize.ts +0 -37
- package/dist/builtin/workflows/builtin/generate-and-filter-prompts.ts +0 -41
- package/dist/builtin/workflows/builtin/generate-and-filter-runner.ts +0 -90
- package/dist/builtin/workflows/builtin/generate-and-filter.ts +0 -31
- package/dist/builtin/workflows/builtin/goal-artifacts.ts +0 -64
- package/dist/builtin/workflows/builtin/goal-convergence.ts +0 -87
- package/dist/builtin/workflows/builtin/goal-ledger.ts +0 -139
- package/dist/builtin/workflows/builtin/goal-models.ts +0 -72
- package/dist/builtin/workflows/builtin/goal-orchestrator-prompts.ts +0 -94
- package/dist/builtin/workflows/builtin/goal-prompts.ts +0 -217
- package/dist/builtin/workflows/builtin/goal-reducer.ts +0 -176
- package/dist/builtin/workflows/builtin/goal-reports.ts +0 -76
- package/dist/builtin/workflows/builtin/goal-reverify.ts +0 -305
- package/dist/builtin/workflows/builtin/goal-review.ts +0 -139
- package/dist/builtin/workflows/builtin/goal-runner.ts +0 -504
- package/dist/builtin/workflows/builtin/goal-schemas.ts +0 -89
- package/dist/builtin/workflows/builtin/goal-types.ts +0 -164
- package/dist/builtin/workflows/builtin/goal.ts +0 -78
- package/dist/builtin/workflows/builtin/index.ts +0 -16
- package/dist/builtin/workflows/builtin/loop-until-done-prompts.ts +0 -87
- package/dist/builtin/workflows/builtin/loop-until-done-runner.ts +0 -282
- package/dist/builtin/workflows/builtin/loop-until-done.ts +0 -51
- package/dist/builtin/workflows/builtin/open-claude-design-live-protocol.ts +0 -305
- package/dist/builtin/workflows/builtin/open-claude-design-phases.ts +0 -337
- package/dist/builtin/workflows/builtin/open-claude-design-runner.ts +0 -347
- package/dist/builtin/workflows/builtin/open-claude-design-setup.ts +0 -313
- package/dist/builtin/workflows/builtin/open-claude-design-utils.ts +0 -311
- package/dist/builtin/workflows/builtin/open-claude-design.ts +0 -57
- package/dist/builtin/workflows/builtin/pattern-artifact-root.ts +0 -28
- package/dist/builtin/workflows/builtin/progress-scoring.ts +0 -230
- package/dist/builtin/workflows/builtin/ralph-core.ts +0 -449
- package/dist/builtin/workflows/builtin/ralph-forked-prompts.ts +0 -100
- package/dist/builtin/workflows/builtin/ralph-models.ts +0 -183
- package/dist/builtin/workflows/builtin/ralph-review-gate.ts +0 -103
- package/dist/builtin/workflows/builtin/ralph-reviewer-prompt.ts +0 -104
- package/dist/builtin/workflows/builtin/ralph-runner.ts +0 -459
- package/dist/builtin/workflows/builtin/ralph.ts +0 -82
- package/dist/builtin/workflows/builtin/review-convergence.ts +0 -229
- package/dist/builtin/workflows/builtin/selection-math.ts +0 -156
- package/dist/builtin/workflows/builtin/steering-context.ts +0 -51
- package/dist/builtin/workflows/builtin/tournament-prompts.ts +0 -70
- package/dist/builtin/workflows/builtin/tournament-runner.ts +0 -400
- package/dist/builtin/workflows/builtin/tournament.ts +0 -73
- package/dist/builtin/workflows/builtin/verification-criteria.ts +0 -330
- package/dist/builtin/workflows/builtin/verification-prompts.ts +0 -206
- package/dist/builtin/workflows/builtin/verification-usage.ts +0 -44
|
@@ -1,400 +0,0 @@
|
|
|
1
|
-
import { mkdir, readFile, writeFile } from "node:fs/promises";
|
|
2
|
-
import { join, isAbsolute, relative, resolve } from "node:path";
|
|
3
|
-
import { Type } from "typebox";
|
|
4
|
-
import type { WorkflowInputValues, WorkflowRunContext, WorkflowSerializableObject, WorkflowSerializableValue, WorkflowTaskResult, WorkflowTaskStep } from "../src/shared/types.js";
|
|
5
|
-
import { accumulate, plan_comparisons, rank_candidates, select_pivots, soft_win, type Preference, type ScoringJob } from "./selection-math.js";
|
|
6
|
-
import { build_scoring_prompt, scoring_prompt_reads, warm_first_fan_out, type ScoringCandidate, type SharedHead } from "./verification-prompts.js";
|
|
7
|
-
import { normalize_criteria, parse_rubric, VERIFICATION_SCALE, type Criterion, type CriterionInput } from "./verification-criteria.js";
|
|
8
|
-
import { DEFAULT_TOURNAMENT_CRITERIA, renderComparisonsReducerPrompt, renderTournamentAttemptPrompt } from "./tournament-prompts.js";
|
|
9
|
-
import { stableArtifactRoot } from "./pattern-artifact-root.js";
|
|
10
|
-
import { fold_usage, type UsageTotals } from "./verification-usage.js";
|
|
11
|
-
|
|
12
|
-
const judgeScoreSchema = Type.Object({
|
|
13
|
-
criterion_id: Type.String(),
|
|
14
|
-
score_a: Type.Integer({ minimum: VERIFICATION_SCALE.min, maximum: VERIFICATION_SCALE.max }),
|
|
15
|
-
score_b: Type.Integer({ minimum: VERIFICATION_SCALE.min, maximum: VERIFICATION_SCALE.max }),
|
|
16
|
-
evidence: Type.Array(Type.String()),
|
|
17
|
-
}, { additionalProperties: false });
|
|
18
|
-
|
|
19
|
-
const JUDGE_GROUND_TRUTH_NOTE = "No external ground truth is supplied; score each presented solution against the task and criterion.";
|
|
20
|
-
const JUDGE_OUTPUT_FORMAT =
|
|
21
|
-
"Return only JSON with criterion_id (string), score_a (integer 1–20 for presented slot 1), score_b (integer 1–20 for presented slot 2), and evidence (array of strings).";
|
|
22
|
-
|
|
23
|
-
type TournamentCriteriaInput = string | Record<string, string> | readonly string[] | readonly CriterionInput[];
|
|
24
|
-
type TournamentInputs = WorkflowInputValues & { readonly prompt: string; readonly num_attempts: number; readonly max_concurrency: number; readonly n_evaluations: number; readonly pivots: number; readonly seed: number; readonly criteria?: TournamentCriteriaInput; readonly models?: readonly string[] };
|
|
25
|
-
|
|
26
|
-
type Entrant = { readonly label: string; readonly path: string; readonly body: string };
|
|
27
|
-
type JudgeReport = { readonly criterion_id: string; readonly score_a: number; readonly score_b: number; readonly evidence: readonly string[] };
|
|
28
|
-
type ComparisonRecord = { a: number; b: number; phase: "ring" | "pivot"; criterion_id: string; rep: number; swapped: boolean; score_a?: number; score_b?: number; p_ab?: number; invalid?: true; judge_artifact_path: string };
|
|
29
|
-
type ScoredComparisonRecord = ComparisonRecord & { score_a: number; score_b: number };
|
|
30
|
-
type PairRecord = { a: number; b: number; phase: "ring" | "pivot"; valid_reports: number; mean_score_a?: number; mean_score_b?: number; p_ab: number; invalid?: true };
|
|
31
|
-
type JudgeStage = { readonly job: ScoringJob; readonly name: string; readonly path: string; readonly slot1: number; readonly slot2: number; readonly step: WorkflowTaskStep };
|
|
32
|
-
|
|
33
|
-
function serializableObject(
|
|
34
|
-
value: WorkflowSerializableValue | undefined,
|
|
35
|
-
): WorkflowSerializableObject | undefined {
|
|
36
|
-
if (value === null || Array.isArray(value) || typeof value !== "object") return undefined;
|
|
37
|
-
return value as WorkflowSerializableObject;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
function stringArray(value: WorkflowSerializableValue | undefined): value is readonly string[] {
|
|
41
|
-
return Array.isArray(value) && value.every((item) => typeof item === "string");
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
function judgeReport(value: WorkflowSerializableValue | undefined): JudgeReport | undefined {
|
|
45
|
-
const object = serializableObject(value);
|
|
46
|
-
if (object === undefined) return undefined;
|
|
47
|
-
const criterionId = object.criterion_id;
|
|
48
|
-
const scoreA = object.score_a;
|
|
49
|
-
const scoreB = object.score_b;
|
|
50
|
-
const evidence = object.evidence;
|
|
51
|
-
if (
|
|
52
|
-
typeof criterionId !== "string" ||
|
|
53
|
-
typeof scoreA !== "number" ||
|
|
54
|
-
!Number.isInteger(scoreA) ||
|
|
55
|
-
scoreA < VERIFICATION_SCALE.min ||
|
|
56
|
-
scoreA > VERIFICATION_SCALE.max ||
|
|
57
|
-
typeof scoreB !== "number" ||
|
|
58
|
-
!Number.isInteger(scoreB) ||
|
|
59
|
-
scoreB < VERIFICATION_SCALE.min ||
|
|
60
|
-
scoreB > VERIFICATION_SCALE.max ||
|
|
61
|
-
!stringArray(evidence)
|
|
62
|
-
) return undefined;
|
|
63
|
-
return { criterion_id: criterionId, score_a: scoreA, score_b: scoreB, evidence };
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
function resultFor(
|
|
67
|
-
results: readonly WorkflowTaskResult[],
|
|
68
|
-
stageName: string,
|
|
69
|
-
): WorkflowTaskResult | undefined {
|
|
70
|
-
return results.find((result) => result.stageName === stageName || result.name === stageName);
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
function scoredComparison(record: ComparisonRecord): record is ScoredComparisonRecord {
|
|
74
|
-
return typeof record.score_a === "number" && typeof record.score_b === "number" && record.invalid !== true;
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
function stageName(job: ScoringJob): string {
|
|
78
|
-
return `judge-${job.a}-${job.b}-${job.criterionId}-r${job.rep}`;
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
function criterionSlug(id: string): string {
|
|
82
|
-
const slug = id
|
|
83
|
-
.toLowerCase()
|
|
84
|
-
.replace(/[^a-z0-9]+/g, "_")
|
|
85
|
-
.replace(/^_+|_+$/g, "")
|
|
86
|
-
.slice(0, 40)
|
|
87
|
-
.replace(/_+$/g, "");
|
|
88
|
-
return slug || "criterion";
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
function judgeArtifactPath(judgesDir: string, job: ScoringJob, criterionIndex: number): string {
|
|
92
|
-
const filename = `judge-${job.a}-${job.b}-c${criterionIndex}-${criterionSlug(job.criterionId)}-r${job.rep}.json`;
|
|
93
|
-
const root = resolve(judgesDir);
|
|
94
|
-
const path = resolve(judgesDir, filename);
|
|
95
|
-
const fromRoot = relative(root, path);
|
|
96
|
-
if (fromRoot.startsWith("..") || isAbsolute(fromRoot)) {
|
|
97
|
-
throw new Error(`tournament: judge artifact escaped its directory: ${path}`);
|
|
98
|
-
}
|
|
99
|
-
return path;
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
function tournamentCriteria(input: TournamentCriteriaInput | undefined): readonly Criterion[] {
|
|
103
|
-
if (input === undefined) return normalize_criteria(DEFAULT_TOURNAMENT_CRITERIA);
|
|
104
|
-
if (typeof input === "string") return parse_rubric(input).criteria;
|
|
105
|
-
return normalize_criteria(input);
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
function modelAssignment(
|
|
109
|
-
entrants: readonly Entrant[],
|
|
110
|
-
models: readonly string[] | undefined,
|
|
111
|
-
): Record<string, string> | undefined {
|
|
112
|
-
if (models === undefined) return undefined;
|
|
113
|
-
const assignment: Record<string, string> = {};
|
|
114
|
-
if (models.length === 0) return assignment;
|
|
115
|
-
for (const [index, entrant] of entrants.entries()) assignment[entrant.label] = models[index % models.length]!;
|
|
116
|
-
return assignment;
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
function combineUsage(totals: readonly UsageTotals[]): UsageTotals {
|
|
120
|
-
const combined = {
|
|
121
|
-
calls: 0,
|
|
122
|
-
input: 0,
|
|
123
|
-
output: 0,
|
|
124
|
-
cacheRead: 0,
|
|
125
|
-
cacheWrite: 0,
|
|
126
|
-
cost: 0,
|
|
127
|
-
turns: 0,
|
|
128
|
-
};
|
|
129
|
-
for (const total of totals) {
|
|
130
|
-
combined.calls += total.calls;
|
|
131
|
-
combined.input += total.input;
|
|
132
|
-
combined.output += total.output;
|
|
133
|
-
combined.cacheRead += total.cacheRead;
|
|
134
|
-
combined.cacheWrite += total.cacheWrite;
|
|
135
|
-
combined.cost += total.cost;
|
|
136
|
-
combined.turns += total.turns;
|
|
137
|
-
}
|
|
138
|
-
const cacheDenominator = combined.input + combined.cacheRead;
|
|
139
|
-
return {
|
|
140
|
-
...combined,
|
|
141
|
-
cacheHitRate: cacheDenominator === 0 ? 0 : combined.cacheRead / cacheDenominator,
|
|
142
|
-
};
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
export async function runTournament(ctx: WorkflowRunContext<TournamentInputs>) {
|
|
146
|
-
const artifactDir = await stableArtifactRoot(ctx, "tournament");
|
|
147
|
-
const attemptsDir = join(artifactDir, "attempts");
|
|
148
|
-
const numAttempts = ctx.inputs.num_attempts ?? 4;
|
|
149
|
-
const maxConcurrency = ctx.inputs.max_concurrency ?? 4;
|
|
150
|
-
const nEvaluations = ctx.inputs.n_evaluations ?? 2;
|
|
151
|
-
const pivotCount = ctx.inputs.pivots ?? 1;
|
|
152
|
-
const seed = ctx.inputs.seed ?? 0;
|
|
153
|
-
const judgesDir = join(artifactDir, "judges");
|
|
154
|
-
await mkdir(attemptsDir, { recursive: true });
|
|
155
|
-
await mkdir(judgesDir, { recursive: true });
|
|
156
|
-
|
|
157
|
-
const attemptArtifactPaths = Array.from({ length: numAttempts }, (_, index) =>
|
|
158
|
-
join(attemptsDir, `attempt-${index + 1}.md`));
|
|
159
|
-
const models = ctx.inputs.models;
|
|
160
|
-
const attemptResults = await ctx.parallel(
|
|
161
|
-
attemptArtifactPaths.map((path, index) => ({
|
|
162
|
-
name: `attempt-${index + 1}`,
|
|
163
|
-
prompt: renderTournamentAttemptPrompt(ctx.inputs.prompt, index + 1),
|
|
164
|
-
context: "fresh" as const,
|
|
165
|
-
output: path,
|
|
166
|
-
outputMode: "file-only" as const,
|
|
167
|
-
...(models !== undefined && models.length > 0 ? { model: models[index % models.length] } : {}),
|
|
168
|
-
})),
|
|
169
|
-
{ concurrency: maxConcurrency, failFast: true },
|
|
170
|
-
);
|
|
171
|
-
|
|
172
|
-
const entrants: Entrant[] = await Promise.all(attemptArtifactPaths.map(async (path, index) => ({
|
|
173
|
-
label: `attempt-${index + 1}`,
|
|
174
|
-
path,
|
|
175
|
-
body: await readFile(path, "utf8"),
|
|
176
|
-
})));
|
|
177
|
-
const criteria = tournamentCriteria(ctx.inputs.criteria);
|
|
178
|
-
const criterionIds = criteria.map((criterion) => criterion.id);
|
|
179
|
-
const plan = plan_comparisons({
|
|
180
|
-
n: entrants.length,
|
|
181
|
-
pivots: pivotCount,
|
|
182
|
-
repeats: nEvaluations,
|
|
183
|
-
seed,
|
|
184
|
-
});
|
|
185
|
-
const weights = Array.from({ length: entrants.length }, () => 0);
|
|
186
|
-
const counts = Array.from({ length: entrants.length }, () => 0);
|
|
187
|
-
const comparisons: ComparisonRecord[] = [];
|
|
188
|
-
const pairs: PairRecord[] = [];
|
|
189
|
-
const judgeArtifactPaths: string[] = [];
|
|
190
|
-
let executed = 0;
|
|
191
|
-
|
|
192
|
-
const runPhase = async (
|
|
193
|
-
phase: "ring" | "pivot",
|
|
194
|
-
jobs: readonly ScoringJob[],
|
|
195
|
-
): Promise<{ readonly preferences: readonly Preference[]; readonly results: readonly WorkflowTaskResult[] }> => {
|
|
196
|
-
const stages: JudgeStage[] = jobs.map((job) => {
|
|
197
|
-
const slot1 = job.swapped ? job.b : job.a;
|
|
198
|
-
const slot2 = job.swapped ? job.a : job.b;
|
|
199
|
-
const first = entrants[slot1]!;
|
|
200
|
-
const second = entrants[slot2]!;
|
|
201
|
-
const head: SharedHead = {
|
|
202
|
-
task: ctx.inputs.prompt,
|
|
203
|
-
groundTruthNote: JUDGE_GROUND_TRUTH_NOTE,
|
|
204
|
-
candidates: [
|
|
205
|
-
{ path: first.path, body: first.body },
|
|
206
|
-
{ path: second.path, body: second.body },
|
|
207
|
-
] satisfies readonly ScoringCandidate[],
|
|
208
|
-
scaleAnchors: VERIFICATION_SCALE.anchors,
|
|
209
|
-
outputFormat: JUDGE_OUTPUT_FORMAT,
|
|
210
|
-
};
|
|
211
|
-
const name = stageName(job);
|
|
212
|
-
const criterionIndex = criterionIds.indexOf(job.criterionId);
|
|
213
|
-
const path = judgeArtifactPath(judgesDir, job, criterionIndex);
|
|
214
|
-
judgeArtifactPaths.push(path);
|
|
215
|
-
return {
|
|
216
|
-
job,
|
|
217
|
-
name,
|
|
218
|
-
path,
|
|
219
|
-
slot1,
|
|
220
|
-
slot2,
|
|
221
|
-
step: {
|
|
222
|
-
name,
|
|
223
|
-
prompt: build_scoring_prompt(head, criteria.find((criterion) => criterion.id === job.criterionId)!),
|
|
224
|
-
context: "fresh" as const,
|
|
225
|
-
reads: scoring_prompt_reads(head),
|
|
226
|
-
schema: judgeScoreSchema,
|
|
227
|
-
},
|
|
228
|
-
};
|
|
229
|
-
});
|
|
230
|
-
if (stages.length === 0) return { preferences: [], results: [] };
|
|
231
|
-
executed += stages.length;
|
|
232
|
-
const results = await warm_first_fan_out(
|
|
233
|
-
ctx,
|
|
234
|
-
stages.map((stage) => stage.step),
|
|
235
|
-
(_step, index) => `${stages[index]!.slot1}:${stages[index]!.slot2}`,
|
|
236
|
-
{ concurrency: maxConcurrency, failFast: false },
|
|
237
|
-
);
|
|
238
|
-
const phaseResults = [...results];
|
|
239
|
-
for (const stage of stages) {
|
|
240
|
-
let report = judgeReport(resultFor(results, stage.name)?.structured);
|
|
241
|
-
if (report === undefined) {
|
|
242
|
-
executed += 1;
|
|
243
|
-
const retried = await ctx.task(`${stage.name}-reask`, {
|
|
244
|
-
prompt: `${stage.step.prompt}\nThe previous report was invalid. Return the required JSON schema exactly once.`,
|
|
245
|
-
context: "fresh",
|
|
246
|
-
reads: stage.step.reads,
|
|
247
|
-
schema: judgeScoreSchema,
|
|
248
|
-
});
|
|
249
|
-
phaseResults.push(retried);
|
|
250
|
-
report = judgeReport(retried.structured);
|
|
251
|
-
}
|
|
252
|
-
if (report === undefined) {
|
|
253
|
-
await writeFile(stage.path, `${JSON.stringify({ invalid: true }, null, 2)}\n`);
|
|
254
|
-
comparisons.push({
|
|
255
|
-
a: stage.job.a,
|
|
256
|
-
b: stage.job.b,
|
|
257
|
-
phase,
|
|
258
|
-
criterion_id: stage.job.criterionId,
|
|
259
|
-
rep: stage.job.rep,
|
|
260
|
-
swapped: stage.job.swapped,
|
|
261
|
-
invalid: true,
|
|
262
|
-
judge_artifact_path: stage.path,
|
|
263
|
-
});
|
|
264
|
-
continue;
|
|
265
|
-
}
|
|
266
|
-
await writeFile(stage.path, `${JSON.stringify(report, null, 2)}\n`);
|
|
267
|
-
const scoreA = stage.job.swapped ? report.score_b : report.score_a;
|
|
268
|
-
const scoreB = stage.job.swapped ? report.score_a : report.score_b;
|
|
269
|
-
comparisons.push({
|
|
270
|
-
a: stage.job.a,
|
|
271
|
-
b: stage.job.b,
|
|
272
|
-
phase,
|
|
273
|
-
criterion_id: stage.job.criterionId,
|
|
274
|
-
rep: stage.job.rep,
|
|
275
|
-
swapped: stage.job.swapped,
|
|
276
|
-
score_a: scoreA,
|
|
277
|
-
score_b: scoreB,
|
|
278
|
-
p_ab: soft_win(scoreA, scoreB),
|
|
279
|
-
judge_artifact_path: stage.path,
|
|
280
|
-
});
|
|
281
|
-
}
|
|
282
|
-
|
|
283
|
-
const phaseRecords = comparisons.filter((record) => record.phase === phase);
|
|
284
|
-
const grouped = new Map<string, ComparisonRecord[]>();
|
|
285
|
-
for (const record of phaseRecords) {
|
|
286
|
-
const key = `${record.a}:${record.b}`;
|
|
287
|
-
const group = grouped.get(key);
|
|
288
|
-
if (group === undefined) grouped.set(key, [record]);
|
|
289
|
-
else group.push(record);
|
|
290
|
-
}
|
|
291
|
-
const preferences: Preference[] = [];
|
|
292
|
-
for (const records of grouped.values()) {
|
|
293
|
-
const first = records[0]!;
|
|
294
|
-
const valid = records.filter(scoredComparison);
|
|
295
|
-
if (valid.length === 0) {
|
|
296
|
-
pairs.push({ a: first.a, b: first.b, phase, valid_reports: 0, p_ab: 0.5, invalid: true });
|
|
297
|
-
preferences.push({ a: first.a, b: first.b, p: 0.5 });
|
|
298
|
-
continue;
|
|
299
|
-
}
|
|
300
|
-
const meanScoreA = valid.reduce((sum, record) => sum + record.score_a, 0) / valid.length;
|
|
301
|
-
const meanScoreB = valid.reduce((sum, record) => sum + record.score_b, 0) / valid.length;
|
|
302
|
-
const p = soft_win(meanScoreA, meanScoreB);
|
|
303
|
-
pairs.push({
|
|
304
|
-
a: first.a,
|
|
305
|
-
b: first.b,
|
|
306
|
-
phase,
|
|
307
|
-
valid_reports: valid.length,
|
|
308
|
-
mean_score_a: meanScoreA,
|
|
309
|
-
mean_score_b: meanScoreB,
|
|
310
|
-
p_ab: p,
|
|
311
|
-
});
|
|
312
|
-
preferences.push({ a: first.a, b: first.b, p });
|
|
313
|
-
}
|
|
314
|
-
return { preferences, results: phaseResults };
|
|
315
|
-
};
|
|
316
|
-
|
|
317
|
-
const ringJobs = plan.jobs(plan.ring, criterionIds);
|
|
318
|
-
const ringPhase = await runPhase("ring", ringJobs);
|
|
319
|
-
accumulate(ringPhase.preferences, weights, counts);
|
|
320
|
-
const pivotIndices = select_pivots(weights, counts, pivotCount);
|
|
321
|
-
const pivotJobs = plan.jobs(plan.pivotRounds(pivotIndices), criterionIds);
|
|
322
|
-
const pivotPhase = await runPhase("pivot", pivotJobs);
|
|
323
|
-
accumulate(pivotPhase.preferences, weights, counts);
|
|
324
|
-
const ranking = rank_candidates(weights, counts).map((entry) => ({
|
|
325
|
-
label: entrants[entry.index]!.label,
|
|
326
|
-
index: entry.index,
|
|
327
|
-
meanPreference: entry.meanPreference,
|
|
328
|
-
}));
|
|
329
|
-
const outputRanking = ranking.map(({ label, meanPreference }) => ({ label, meanPreference }));
|
|
330
|
-
const budgetPivots = Math.min(pivotCount, entrants.length);
|
|
331
|
-
// Planned units are judge jobs: scheduled directed pairs × criteria × evaluations.
|
|
332
|
-
const comparisonBudget =
|
|
333
|
-
(entrants.length + budgetPivots * (entrants.length - budgetPivots) + (budgetPivots * (budgetPivots - 1)) / 2) *
|
|
334
|
-
criteria.length * nEvaluations;
|
|
335
|
-
const comparisonPath = join(artifactDir, "comparisons.json");
|
|
336
|
-
const assignment = modelAssignment(entrants, models);
|
|
337
|
-
const phaseUsage = {
|
|
338
|
-
attempts: fold_usage(attemptResults),
|
|
339
|
-
ring: fold_usage(ringPhase.results),
|
|
340
|
-
pivots: fold_usage(pivotPhase.results),
|
|
341
|
-
};
|
|
342
|
-
const baseLedger = {
|
|
343
|
-
task: ctx.inputs.prompt,
|
|
344
|
-
seed,
|
|
345
|
-
params: {
|
|
346
|
-
n: entrants.length,
|
|
347
|
-
pivots: pivotCount,
|
|
348
|
-
n_evaluations: nEvaluations,
|
|
349
|
-
criteria,
|
|
350
|
-
},
|
|
351
|
-
comparisons,
|
|
352
|
-
pairs,
|
|
353
|
-
w: weights,
|
|
354
|
-
c: counts,
|
|
355
|
-
ranking,
|
|
356
|
-
// Budget units are judge stages: planned jobs versus dispatched jobs, including re-asks in executed.
|
|
357
|
-
budget: { planned: comparisonBudget, executed },
|
|
358
|
-
...(assignment === undefined ? {} : { model_assignment: assignment }),
|
|
359
|
-
};
|
|
360
|
-
const writeLedger = async (reducerUsage: UsageTotals): Promise<void> => {
|
|
361
|
-
const usage = {
|
|
362
|
-
...phaseUsage,
|
|
363
|
-
reducer: reducerUsage,
|
|
364
|
-
total: combineUsage([phaseUsage.attempts, phaseUsage.ring, phaseUsage.pivots, reducerUsage]),
|
|
365
|
-
};
|
|
366
|
-
await writeFile(comparisonPath, `${JSON.stringify({ ...baseLedger, usage }, null, 2)}\n`);
|
|
367
|
-
};
|
|
368
|
-
await writeLedger(fold_usage([]));
|
|
369
|
-
|
|
370
|
-
const winner = ranking[0]!;
|
|
371
|
-
const winnerEntrant = entrants[winner.index]!;
|
|
372
|
-
const resultPath = join(artifactDir, "winner.md");
|
|
373
|
-
const reducer = await ctx.task("comparisons-reducer", {
|
|
374
|
-
prompt: renderComparisonsReducerPrompt({
|
|
375
|
-
task: ctx.inputs.prompt,
|
|
376
|
-
comparisonsPath: comparisonPath,
|
|
377
|
-
ranking: outputRanking,
|
|
378
|
-
winnerLabel: winner.label,
|
|
379
|
-
winnerPath: winnerEntrant.path,
|
|
380
|
-
}),
|
|
381
|
-
context: "fresh",
|
|
382
|
-
reads: [comparisonPath, winnerEntrant.path, ...judgeArtifactPaths],
|
|
383
|
-
output: resultPath,
|
|
384
|
-
outputMode: "file-only",
|
|
385
|
-
});
|
|
386
|
-
await writeLedger(fold_usage([reducer]));
|
|
387
|
-
|
|
388
|
-
return {
|
|
389
|
-
result: reducer.text,
|
|
390
|
-
winner: winner.label,
|
|
391
|
-
winner_artifact_path: winnerEntrant.path,
|
|
392
|
-
result_path: resultPath,
|
|
393
|
-
attempt_artifact_paths: attemptArtifactPaths,
|
|
394
|
-
judge_artifact_paths: judgeArtifactPaths,
|
|
395
|
-
comparisons_path: comparisonPath,
|
|
396
|
-
ranking: outputRanking,
|
|
397
|
-
seed,
|
|
398
|
-
artifact_dir: artifactDir,
|
|
399
|
-
};
|
|
400
|
-
}
|
|
@@ -1,73 +0,0 @@
|
|
|
1
|
-
import { Type } from "typebox";
|
|
2
|
-
import { workflow } from "../src/authoring/workflow.js";
|
|
3
|
-
import { withSteeringPropagationContext } from "./steering-context.js";
|
|
4
|
-
import { runTournament } from "./tournament-runner.js";
|
|
5
|
-
|
|
6
|
-
export default workflow({
|
|
7
|
-
name: "tournament",
|
|
8
|
-
description: "Run independent whole-task attempts through a soft-scored pivot-pairing schedule and return an auditable ranking.",
|
|
9
|
-
// The 15-minute default, stated rather than inherited: this is a per-workflow
|
|
10
|
-
// product decision, so a future change to the global default must not silently
|
|
11
|
-
// re-cadence a long autonomous run.
|
|
12
|
-
heartbeatIntervalMinutes: 15,
|
|
13
|
-
inputs: {
|
|
14
|
-
prompt: Type.String({ description: "Task every competing agent must attempt independently." }),
|
|
15
|
-
num_attempts: Type.Integer({
|
|
16
|
-
minimum: 2,
|
|
17
|
-
maximum: 8,
|
|
18
|
-
default: 4,
|
|
19
|
-
description: "Number of independent whole-task attempts (2-8).",
|
|
20
|
-
}),
|
|
21
|
-
max_concurrency: Type.Integer({
|
|
22
|
-
minimum: 1,
|
|
23
|
-
maximum: 8,
|
|
24
|
-
default: 4,
|
|
25
|
-
description: "Maximum simultaneously active attempts or pairwise judges (1-8).",
|
|
26
|
-
}),
|
|
27
|
-
n_evaluations: Type.Integer({
|
|
28
|
-
minimum: 1,
|
|
29
|
-
default: 2,
|
|
30
|
-
description: "Number of repeated evaluations per criterion and directed pair.",
|
|
31
|
-
}),
|
|
32
|
-
pivots: Type.Integer({
|
|
33
|
-
minimum: 1,
|
|
34
|
-
default: 1,
|
|
35
|
-
description: "Number of pivot candidates used for the second comparison phase.",
|
|
36
|
-
}),
|
|
37
|
-
seed: Type.Integer({
|
|
38
|
-
default: 0,
|
|
39
|
-
description: "Seed for the deterministic comparison schedule.",
|
|
40
|
-
}),
|
|
41
|
-
criteria: Type.Optional(Type.Union([
|
|
42
|
-
Type.String(),
|
|
43
|
-
Type.Record(Type.String(), Type.String()),
|
|
44
|
-
Type.Array(Type.String()),
|
|
45
|
-
Type.Array(Type.Object({
|
|
46
|
-
id: Type.Optional(Type.String()),
|
|
47
|
-
name: Type.Optional(Type.String()),
|
|
48
|
-
description: Type.String(),
|
|
49
|
-
}, { additionalProperties: true })),
|
|
50
|
-
], {
|
|
51
|
-
description: "Optional V1 judge criteria; accepts a markdown rubric, record, string list, or CriterionInput list; omitted uses the default three-criterion rubric.",
|
|
52
|
-
})),
|
|
53
|
-
models: Type.Optional(Type.Array(Type.String(), {
|
|
54
|
-
description: "Optional ordered model ids assigned round-robin to attempt slots.",
|
|
55
|
-
})),
|
|
56
|
-
},
|
|
57
|
-
outputs: {
|
|
58
|
-
result: Type.String({ description: "Compact reference to the final reducer report; read `result_path` for the full report." }),
|
|
59
|
-
winner: Type.String({ description: "Stable attempt label selected as the top-ranked tournament winner." }),
|
|
60
|
-
winner_artifact_path: Type.String({ description: "Path to the original winning attempt artifact." }),
|
|
61
|
-
result_path: Type.String({ description: "Path to the final reducer report artifact." }),
|
|
62
|
-
attempt_artifact_paths: Type.Array(Type.String(), { description: "Paths to every independent attempt artifact." }),
|
|
63
|
-
judge_artifact_paths: Type.Array(Type.String(), { description: "Paths to all per-job structured judge artifacts." }),
|
|
64
|
-
comparisons_path: Type.String({ description: "Path to the durable JSON soft-scored comparisons ledger." }),
|
|
65
|
-
ranking: Type.Array(Type.Object({
|
|
66
|
-
label: Type.String(),
|
|
67
|
-
meanPreference: Type.Number(),
|
|
68
|
-
}, { additionalProperties: false }), { description: "All attempts ordered by mean preference." }),
|
|
69
|
-
seed: Type.Integer({ description: "Seed used for the deterministic comparison schedule." }),
|
|
70
|
-
artifact_dir: Type.String({ description: "Run-specific directory containing tournament artifacts." }),
|
|
71
|
-
},
|
|
72
|
-
run: async (ctx) => await runTournament(withSteeringPropagationContext(ctx)),
|
|
73
|
-
});
|