specrails-core 5.2.3 → 5.4.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/README.md +3 -0
- package/bin/specrails-core.mjs +5 -0
- package/dist/agent-runtime/capabilities.d.ts +27 -0
- package/dist/agent-runtime/capabilities.js +73 -0
- package/dist/agent-runtime/capabilities.js.map +1 -0
- package/dist/agent-runtime/cli-executor.d.ts +43 -0
- package/dist/agent-runtime/cli-executor.js +405 -0
- package/dist/agent-runtime/cli-executor.js.map +1 -0
- package/dist/agent-runtime/cli-process.d.ts +32 -0
- package/dist/agent-runtime/cli-process.js +159 -0
- package/dist/agent-runtime/cli-process.js.map +1 -0
- package/dist/agent-runtime/cli.d.ts +39 -0
- package/dist/agent-runtime/cli.js +216 -0
- package/dist/agent-runtime/cli.js.map +1 -0
- package/dist/agent-runtime/codex-schema.d.ts +4 -0
- package/dist/agent-runtime/codex-schema.js +31 -0
- package/dist/agent-runtime/codex-schema.js.map +1 -0
- package/dist/agent-runtime/config.d.ts +11 -0
- package/dist/agent-runtime/config.js +263 -0
- package/dist/agent-runtime/config.js.map +1 -0
- package/dist/agent-runtime/core-host.d.ts +41 -0
- package/dist/agent-runtime/core-host.js +132 -0
- package/dist/agent-runtime/core-host.js.map +1 -0
- package/dist/agent-runtime/durable-store.d.ts +22 -0
- package/dist/agent-runtime/durable-store.js +205 -0
- package/dist/agent-runtime/durable-store.js.map +1 -0
- package/dist/agent-runtime/efficiency-summary.d.ts +67 -0
- package/dist/agent-runtime/efficiency-summary.js +52 -0
- package/dist/agent-runtime/efficiency-summary.js.map +1 -0
- package/dist/agent-runtime/efficiency-types.d.ts +60 -0
- package/dist/agent-runtime/efficiency-types.js +8 -0
- package/dist/agent-runtime/efficiency-types.js.map +1 -0
- package/dist/agent-runtime/efficiency.d.ts +5 -0
- package/dist/agent-runtime/efficiency.js +35 -0
- package/dist/agent-runtime/efficiency.js.map +1 -0
- package/dist/agent-runtime/evaluation-corpus.d.ts +13 -0
- package/dist/agent-runtime/evaluation-corpus.js +8 -0
- package/dist/agent-runtime/evaluation-corpus.js.map +1 -0
- package/dist/agent-runtime/evaluation.d.ts +43 -0
- package/dist/agent-runtime/evaluation.js +171 -0
- package/dist/agent-runtime/evaluation.js.map +1 -0
- package/dist/agent-runtime/executor-types.d.ts +125 -0
- package/dist/agent-runtime/executor-types.js +29 -0
- package/dist/agent-runtime/executor-types.js.map +1 -0
- package/dist/agent-runtime/executors.d.ts +23 -0
- package/dist/agent-runtime/executors.js +48 -0
- package/dist/agent-runtime/executors.js.map +1 -0
- package/dist/agent-runtime/gemini-policy.d.ts +8 -0
- package/dist/agent-runtime/gemini-policy.js +36 -0
- package/dist/agent-runtime/gemini-policy.js.map +1 -0
- package/dist/agent-runtime/graph/artifacts.d.ts +26 -0
- package/dist/agent-runtime/graph/artifacts.js +205 -0
- package/dist/agent-runtime/graph/artifacts.js.map +1 -0
- package/dist/agent-runtime/graph/nodes.d.ts +39 -0
- package/dist/agent-runtime/graph/nodes.js +321 -0
- package/dist/agent-runtime/graph/nodes.js.map +1 -0
- package/dist/agent-runtime/graph/review-policy.d.ts +18 -0
- package/dist/agent-runtime/graph/review-policy.js +32 -0
- package/dist/agent-runtime/graph/review-policy.js.map +1 -0
- package/dist/agent-runtime/graph/roles.d.ts +47 -0
- package/dist/agent-runtime/graph/roles.js +190 -0
- package/dist/agent-runtime/graph/roles.js.map +1 -0
- package/dist/agent-runtime/graph/state.d.ts +83 -0
- package/dist/agent-runtime/graph/state.js +23 -0
- package/dist/agent-runtime/graph/state.js.map +1 -0
- package/dist/agent-runtime/graph-checkpointer.d.ts +61 -0
- package/dist/agent-runtime/graph-checkpointer.js +137 -0
- package/dist/agent-runtime/graph-checkpointer.js.map +1 -0
- package/dist/agent-runtime/index.d.ts +20 -0
- package/dist/agent-runtime/index.js +21 -0
- package/dist/agent-runtime/index.js.map +1 -0
- package/dist/agent-runtime/kimi-acp.d.ts +11 -0
- package/dist/agent-runtime/kimi-acp.js +190 -0
- package/dist/agent-runtime/kimi-acp.js.map +1 -0
- package/dist/agent-runtime/openai-executor.d.ts +26 -0
- package/dist/agent-runtime/openai-executor.js +192 -0
- package/dist/agent-runtime/openai-executor.js.map +1 -0
- package/dist/agent-runtime/openspec-tool-server.d.ts +1 -0
- package/dist/agent-runtime/openspec-tool-server.js +37 -0
- package/dist/agent-runtime/openspec-tool-server.js.map +1 -0
- package/dist/agent-runtime/openspec.d.ts +123 -0
- package/dist/agent-runtime/openspec.js +263 -0
- package/dist/agent-runtime/openspec.js.map +1 -0
- package/dist/agent-runtime/prompts.d.ts +44 -0
- package/dist/agent-runtime/prompts.js +310 -0
- package/dist/agent-runtime/prompts.js.map +1 -0
- package/dist/agent-runtime/provider-diagnostic.d.ts +2 -0
- package/dist/agent-runtime/provider-diagnostic.js +25 -0
- package/dist/agent-runtime/provider-diagnostic.js.map +1 -0
- package/dist/agent-runtime/repository-context.d.ts +25 -0
- package/dist/agent-runtime/repository-context.js +100 -0
- package/dist/agent-runtime/repository-context.js.map +1 -0
- package/dist/agent-runtime/review-context.d.ts +14 -0
- package/dist/agent-runtime/review-context.js +41 -0
- package/dist/agent-runtime/review-context.js.map +1 -0
- package/dist/agent-runtime/role-routing.d.ts +10 -0
- package/dist/agent-runtime/role-routing.js +29 -0
- package/dist/agent-runtime/role-routing.js.map +1 -0
- package/dist/agent-runtime/role-state.d.ts +19 -0
- package/dist/agent-runtime/role-state.js +24 -0
- package/dist/agent-runtime/role-state.js.map +1 -0
- package/dist/agent-runtime/runtime-identity.d.ts +11 -0
- package/dist/agent-runtime/runtime-identity.js +33 -0
- package/dist/agent-runtime/runtime-identity.js.map +1 -0
- package/dist/agent-runtime/tool-event.d.ts +3 -0
- package/dist/agent-runtime/tool-event.js +24 -0
- package/dist/agent-runtime/tool-event.js.map +1 -0
- package/dist/agent-runtime/verification-plan.d.ts +55 -0
- package/dist/agent-runtime/verification-plan.js +206 -0
- package/dist/agent-runtime/verification-plan.js.map +1 -0
- package/dist/agent-runtime/workflow-types.d.ts +226 -0
- package/dist/agent-runtime/workflow-types.js +2 -0
- package/dist/agent-runtime/workflow-types.js.map +1 -0
- package/dist/agent-runtime/workflow.d.ts +17 -0
- package/dist/agent-runtime/workflow.js +636 -0
- package/dist/agent-runtime/workflow.js.map +1 -0
- package/dist/agent-runtime/workspace-tools.d.ts +29 -0
- package/dist/agent-runtime/workspace-tools.js +282 -0
- package/dist/agent-runtime/workspace-tools.js.map +1 -0
- package/dist/installer/cli.d.ts +35 -0
- package/dist/installer/cli.js +3 -0
- package/dist/installer/cli.js.map +1 -1
- package/dist/installer/commands/doctor.d.ts +27 -0
- package/dist/installer/commands/framework.d.ts +85 -0
- package/dist/installer/commands/init.d.ts +147 -0
- package/dist/installer/commands/update.d.ts +56 -0
- package/dist/installer/commands/v5-migration.d.ts +32 -0
- package/dist/installer/phases/framework-lifecycle.d.ts +53 -0
- package/dist/installer/phases/install-config.d.ts +64 -0
- package/dist/installer/phases/manifest.d.ts +45 -0
- package/dist/installer/phases/prereqs.d.ts +51 -0
- package/dist/installer/phases/provider-detect.d.ts +89 -0
- package/dist/installer/phases/scaffold.d.ts +211 -0
- package/dist/installer/phases/scaffold.js +39 -109
- package/dist/installer/phases/scaffold.js.map +1 -1
- package/dist/installer/runtime/kimi.d.ts +84 -0
- package/dist/installer/runtime/pipeline-state.d.ts +351 -0
- package/dist/installer/runtime/pipeline-state.js +514 -41
- package/dist/installer/runtime/pipeline-state.js.map +1 -1
- package/dist/installer/util/errors.d.ts +46 -0
- package/dist/installer/util/exec.d.ts +41 -0
- package/dist/installer/util/fs.d.ts +153 -0
- package/dist/installer/util/git.d.ts +44 -0
- package/dist/installer/util/install-transaction.d.ts +29 -0
- package/dist/installer/util/logger.d.ts +31 -0
- package/dist/installer/util/paths.d.ts +34 -0
- package/dist/installer/util/prompts.d.ts +23 -0
- package/dist/installer/util/registry.d.ts +174 -0
- package/dist/installer/util/template.d.ts +23 -0
- package/docs/README.md +1 -0
- package/docs/agent-runtime-efficiency.md +65 -0
- package/docs/agent-runtime.md +339 -0
- package/integration-contract.json +80 -7
- package/package.json +20 -2
- package/schemas/agent-runtime.schema.json +77 -0
- package/schemas/fixtures/runtime-efficiency-summary.v1.json +790 -0
- package/templates/codex-skills/batch-implement/SKILL.md +33 -58
- package/templates/codex-skills/implement/SKILL.md +21 -124
- package/templates/codex-skills/retry/SKILL.md +8 -34
- package/templates/commands/specrails/batch-implement.md +21 -16
- package/templates/commands/specrails/implement.md +17 -276
- package/templates/commands/specrails/retry.md +6 -34
- package/templates/gemini-commands/batch-implement.toml +34 -28
- package/templates/gemini-commands/implement.toml +34 -55
- package/templates/gemini-commands/retry.toml +10 -16
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
import { createHash, randomUUID } from 'node:crypto';
|
|
2
|
+
import { mkdir, open, readFile, rename, rm } from 'node:fs/promises';
|
|
3
|
+
import { hostname } from 'node:os';
|
|
4
|
+
import { join, resolve } from 'node:path';
|
|
5
|
+
export class WorkflowStoreError extends Error {
|
|
6
|
+
code;
|
|
7
|
+
constructor(code, message) {
|
|
8
|
+
super(message);
|
|
9
|
+
this.code = code;
|
|
10
|
+
this.name = 'WorkflowStoreError';
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
export const ENVELOPE_FORMAT = 2;
|
|
14
|
+
function errorCode(error) {
|
|
15
|
+
return typeof error === 'object' && error !== null && 'code' in error ? String(error.code) : undefined;
|
|
16
|
+
}
|
|
17
|
+
/** Reject non-JSON data instead of silently changing the fingerprint on serialization. */
|
|
18
|
+
export function fingerprint(value) {
|
|
19
|
+
const seen = new Set();
|
|
20
|
+
const canonical = (item) => {
|
|
21
|
+
if (item === null || typeof item === 'string' || typeof item === 'boolean')
|
|
22
|
+
return item;
|
|
23
|
+
if (typeof item === 'number' && Number.isFinite(item))
|
|
24
|
+
return item;
|
|
25
|
+
if (typeof item !== 'object' || item === null || seen.has(item))
|
|
26
|
+
throw new TypeError('Checkpoint values must be finite, acyclic JSON data');
|
|
27
|
+
if (!Array.isArray(item) && Object.getPrototypeOf(item) !== Object.prototype && Object.getPrototypeOf(item) !== null) {
|
|
28
|
+
throw new TypeError('Checkpoint values must be plain JSON objects');
|
|
29
|
+
}
|
|
30
|
+
seen.add(item);
|
|
31
|
+
const result = Array.isArray(item)
|
|
32
|
+
? item.map(canonical)
|
|
33
|
+
: Object.fromEntries(Object.keys(item).sort().map(key => [key, canonical(item[key])]));
|
|
34
|
+
seen.delete(item);
|
|
35
|
+
return result;
|
|
36
|
+
};
|
|
37
|
+
return createHash('sha256').update(JSON.stringify(canonical(value))).digest('hex');
|
|
38
|
+
}
|
|
39
|
+
function runDirectory(directory, runId) {
|
|
40
|
+
if (!/^[a-zA-Z0-9][a-zA-Z0-9_.-]{0,127}$/.test(runId) || runId.endsWith('.') || /^(?:con|prn|aux|nul|com[1-9]|lpt[1-9])(?:\.|$)/i.test(runId)) {
|
|
41
|
+
throw new WorkflowStoreError('INVALID_ID', 'Run ID must contain 1–128 letters, numbers, dots, underscores or dashes, start with a letter or number, and be a portable filename');
|
|
42
|
+
}
|
|
43
|
+
return join(resolve(directory), runId);
|
|
44
|
+
}
|
|
45
|
+
export async function readWorkflowEnvelope(directory, runId) {
|
|
46
|
+
let raw;
|
|
47
|
+
try {
|
|
48
|
+
raw = await readFile(join(runDirectory(directory, runId), 'checkpoint.json'), 'utf8');
|
|
49
|
+
}
|
|
50
|
+
catch (error) {
|
|
51
|
+
if (errorCode(error) === 'ENOENT')
|
|
52
|
+
return null;
|
|
53
|
+
throw error;
|
|
54
|
+
}
|
|
55
|
+
try {
|
|
56
|
+
const envelope = JSON.parse(raw);
|
|
57
|
+
const state = envelope.state;
|
|
58
|
+
if (envelope.format !== ENVELOPE_FORMAT || !state || state.schemaVersion !== 2 || state.runId !== runId || typeof state.traceId !== 'string' ||
|
|
59
|
+
!Array.isArray(state.events) || !Array.isArray(state.history) || !state.steps ||
|
|
60
|
+
envelope.checksum !== fingerprint({ state, graph: envelope.graph ?? null }))
|
|
61
|
+
throw new Error('Invalid envelope or checksum');
|
|
62
|
+
return { state, ...(envelope.graph ? { graph: envelope.graph } : {}) };
|
|
63
|
+
}
|
|
64
|
+
catch (error) {
|
|
65
|
+
throw new WorkflowStoreError('CORRUPT_STATE', `Cannot read checkpoint for ${runId}: ${error instanceof Error ? error.message : String(error)}`);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
/** Read-only view of the host ledger. */
|
|
69
|
+
export async function readWorkflowState(directory, runId) {
|
|
70
|
+
return (await readWorkflowEnvelope(directory, runId))?.state ?? null;
|
|
71
|
+
}
|
|
72
|
+
/** Publish a complete checkpoint, receipt, usage, event ledger and graph history in one atomic rename. */
|
|
73
|
+
export async function writeWorkflowEnvelope(directory, envelope) {
|
|
74
|
+
const root = runDirectory(directory, envelope.state.runId);
|
|
75
|
+
await mkdir(root, { recursive: true, mode: 0o700 });
|
|
76
|
+
// JSON removes absent optional fields; validate the actual stored representation.
|
|
77
|
+
const normalized = JSON.parse(JSON.stringify({ state: envelope.state, graph: envelope.graph ?? null }));
|
|
78
|
+
const payload = JSON.stringify({ format: ENVELOPE_FORMAT, checksum: fingerprint(normalized), state: normalized.state, ...(normalized.graph ? { graph: normalized.graph } : {}) });
|
|
79
|
+
const temporary = join(root, `.checkpoint-${randomUUID()}.tmp`);
|
|
80
|
+
const handle = await open(temporary, 'wx', 0o600);
|
|
81
|
+
try {
|
|
82
|
+
await handle.writeFile(payload, 'utf8');
|
|
83
|
+
await handle.sync();
|
|
84
|
+
}
|
|
85
|
+
finally {
|
|
86
|
+
await handle.close();
|
|
87
|
+
}
|
|
88
|
+
try {
|
|
89
|
+
// Node's rename replaces an existing file on supported macOS and Windows filesystems.
|
|
90
|
+
await renameReplacing(temporary, join(root, 'checkpoint.json'));
|
|
91
|
+
// POSIX directory sync makes the rename durable; Windows cannot open directories this way.
|
|
92
|
+
if (process.platform !== 'win32') {
|
|
93
|
+
const directoryHandle = await open(root, 'r');
|
|
94
|
+
try {
|
|
95
|
+
await directoryHandle.sync();
|
|
96
|
+
}
|
|
97
|
+
finally {
|
|
98
|
+
await directoryHandle.close();
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
finally {
|
|
103
|
+
await rm(temporary, { force: true });
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
// Windows reports EPERM/EBUSY when a scanner or reader briefly holds the target;
|
|
107
|
+
// the rename is retried before it is reported as a persistence failure.
|
|
108
|
+
async function renameReplacing(from, to) {
|
|
109
|
+
for (let attempt = 0;; attempt++) {
|
|
110
|
+
try {
|
|
111
|
+
await rename(from, to);
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
catch (error) {
|
|
115
|
+
const code = errorCode(error);
|
|
116
|
+
if (process.platform !== 'win32' || attempt >= 10 || (code !== 'EPERM' && code !== 'EBUSY' && code !== 'EACCES'))
|
|
117
|
+
throw error;
|
|
118
|
+
await new Promise(resolve => setTimeout(resolve, 10 * (attempt + 1)));
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
export async function writeWorkflowState(directory, state, graph) {
|
|
123
|
+
await writeWorkflowEnvelope(directory, { state, ...(graph ? { graph } : {}) });
|
|
124
|
+
}
|
|
125
|
+
async function ownerAt(path) {
|
|
126
|
+
try {
|
|
127
|
+
const owner = JSON.parse(await readFile(join(path, 'owner.json'), 'utf8'));
|
|
128
|
+
return Number.isInteger(owner.pid) && owner.pid > 0 && typeof owner.hostname === 'string' && typeof owner.token === 'string' ? owner : null;
|
|
129
|
+
}
|
|
130
|
+
catch (error) {
|
|
131
|
+
if (error instanceof SyntaxError || errorCode(error) === 'ENOENT')
|
|
132
|
+
return null;
|
|
133
|
+
throw error;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
function alive(owner) {
|
|
137
|
+
if (owner.hostname !== hostname())
|
|
138
|
+
return true; // Never steal leases from another machine.
|
|
139
|
+
try {
|
|
140
|
+
process.kill(owner.pid, 0);
|
|
141
|
+
return true;
|
|
142
|
+
}
|
|
143
|
+
catch (error) {
|
|
144
|
+
return errorCode(error) !== 'ESRCH';
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
/** Atomic directory leases avoid platform-specific flock and native dependencies. */
|
|
148
|
+
export async function acquireWorkflowLease(directory, runId) {
|
|
149
|
+
const root = runDirectory(directory, runId);
|
|
150
|
+
const lease = join(root, '.lease');
|
|
151
|
+
const recovery = join(root, '.lease-recovery');
|
|
152
|
+
await mkdir(root, { recursive: true, mode: 0o700 });
|
|
153
|
+
const locked = () => new WorkflowStoreError('LOCKED', `Workflow ${runId} has an active or unverifiable lease`);
|
|
154
|
+
let created = false;
|
|
155
|
+
try {
|
|
156
|
+
await mkdir(lease);
|
|
157
|
+
created = true;
|
|
158
|
+
}
|
|
159
|
+
catch (error) {
|
|
160
|
+
if (errorCode(error) !== 'EEXIST')
|
|
161
|
+
throw error;
|
|
162
|
+
}
|
|
163
|
+
if (!created) {
|
|
164
|
+
// A separate election prevents two contenders from deleting each other's new lease.
|
|
165
|
+
try {
|
|
166
|
+
await mkdir(recovery);
|
|
167
|
+
}
|
|
168
|
+
catch (error) {
|
|
169
|
+
if (errorCode(error) === 'EEXIST')
|
|
170
|
+
throw locked();
|
|
171
|
+
throw error;
|
|
172
|
+
}
|
|
173
|
+
try {
|
|
174
|
+
const oldOwner = await ownerAt(lease);
|
|
175
|
+
if (!oldOwner || alive(oldOwner))
|
|
176
|
+
throw locked();
|
|
177
|
+
await rm(lease, { recursive: true, force: true });
|
|
178
|
+
await mkdir(lease);
|
|
179
|
+
}
|
|
180
|
+
finally {
|
|
181
|
+
await rm(recovery, { recursive: true, force: true });
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
const owner = { pid: process.pid, hostname: hostname(), token: randomUUID() };
|
|
185
|
+
try {
|
|
186
|
+
const handle = await open(join(lease, 'owner.json'), 'wx', 0o600);
|
|
187
|
+
try {
|
|
188
|
+
await handle.writeFile(JSON.stringify(owner));
|
|
189
|
+
await handle.sync();
|
|
190
|
+
}
|
|
191
|
+
finally {
|
|
192
|
+
await handle.close();
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
catch (error) {
|
|
196
|
+
await rm(lease, { recursive: true, force: true });
|
|
197
|
+
throw error;
|
|
198
|
+
}
|
|
199
|
+
return async () => {
|
|
200
|
+
const current = await ownerAt(lease);
|
|
201
|
+
if (current?.token === owner.token)
|
|
202
|
+
await rm(lease, { recursive: true, force: true });
|
|
203
|
+
};
|
|
204
|
+
}
|
|
205
|
+
//# sourceMappingURL=durable-store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"durable-store.js","sourceRoot":"","sources":["../../src/agent-runtime/durable-store.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { type PipelineContext, type PipelineCompletion } from '../installer/runtime/pipeline-state.js';
|
|
2
|
+
import type { RuntimeConfig } from './executor-types.js';
|
|
3
|
+
import type { WorkflowState } from './workflow-types.js';
|
|
4
|
+
/** Compact derived view. Durable invocation/evidence IDs remain the accounting authority. */
|
|
5
|
+
export declare function efficiencySummary(state: WorkflowState, context: PipelineContext, config: RuntimeConfig | undefined, completion?: PipelineCompletion, identity?: {
|
|
6
|
+
planHash?: string;
|
|
7
|
+
candidateHash: string;
|
|
8
|
+
verification?: {
|
|
9
|
+
receipt?: {
|
|
10
|
+
commands: Array<{
|
|
11
|
+
evidenceId?: string;
|
|
12
|
+
}>;
|
|
13
|
+
notRunEvidenceIds?: string[];
|
|
14
|
+
};
|
|
15
|
+
};
|
|
16
|
+
}): {
|
|
17
|
+
schemaVersion: 1;
|
|
18
|
+
currentEvidenceIds: string[];
|
|
19
|
+
planHash: string | null;
|
|
20
|
+
candidateHash: string | null;
|
|
21
|
+
runId: string;
|
|
22
|
+
workflowVersion: string;
|
|
23
|
+
technicalAcceptance: string;
|
|
24
|
+
archive: import("../installer/runtime/pipeline-state.js").PhaseStatus;
|
|
25
|
+
delivery: "pending" | "complete" | "pending-host";
|
|
26
|
+
roles: {
|
|
27
|
+
role: "architect" | "developer" | "reviewer";
|
|
28
|
+
provider: string | null;
|
|
29
|
+
model: string | null;
|
|
30
|
+
effort: string | null;
|
|
31
|
+
observedModel: null;
|
|
32
|
+
observedEffort: null;
|
|
33
|
+
origin: string;
|
|
34
|
+
tier: "base" | "escalation";
|
|
35
|
+
}[];
|
|
36
|
+
invocations: {
|
|
37
|
+
byKind: {
|
|
38
|
+
[k: string]: number;
|
|
39
|
+
};
|
|
40
|
+
total: number;
|
|
41
|
+
complete: boolean;
|
|
42
|
+
promptBytes: number | null;
|
|
43
|
+
contextBytes: number | null;
|
|
44
|
+
handoffBytes: number | null;
|
|
45
|
+
fullContexts: number;
|
|
46
|
+
incrementalContexts: number;
|
|
47
|
+
};
|
|
48
|
+
escalations: {
|
|
49
|
+
role: string;
|
|
50
|
+
attemptId: string;
|
|
51
|
+
provider: string;
|
|
52
|
+
model: string | null;
|
|
53
|
+
effort: string | null;
|
|
54
|
+
reason: string | null;
|
|
55
|
+
}[];
|
|
56
|
+
escalationsTruncated: boolean;
|
|
57
|
+
checks: {
|
|
58
|
+
invalidated: number | null;
|
|
59
|
+
available: boolean;
|
|
60
|
+
complete: boolean;
|
|
61
|
+
executed: number | null;
|
|
62
|
+
reused: number | null;
|
|
63
|
+
notRun: number | null;
|
|
64
|
+
durationMs: number | null;
|
|
65
|
+
};
|
|
66
|
+
metrics: import("./efficiency-types.js").RuntimeEfficiency;
|
|
67
|
+
};
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { readVerificationEvidence } from '../installer/runtime/pipeline-state.js';
|
|
2
|
+
import { runtimeEfficiency } from './efficiency.js';
|
|
3
|
+
/** Compact derived view. Durable invocation/evidence IDs remain the accounting authority. */
|
|
4
|
+
export function efficiencySummary(state, context, config, completion, identity) {
|
|
5
|
+
const invocations = state.history.flatMap(attempt => [...(attempt.invocations ?? []), ...(attempt.pendingInvocations ?? [])].map(call => ({ ...call, role: attempt.stepId, attemptId: attempt.id })));
|
|
6
|
+
const kinds = ['initial', 'correction', 'repair', 'deepen', 'session-fallback'];
|
|
7
|
+
const byKind = Object.fromEntries(kinds.map(kind => [kind, invocations.filter(call => call.kind === kind).length]));
|
|
8
|
+
const measured = state.history.every(attempt => !attempt.pendingInvocations?.length) && state.history.every(attempt => !['architect', 'developer', 'reviewer'].includes(attempt.stepId) || attempt.invocations !== undefined) && invocations.every(call => call.kind !== undefined && call.promptBytes !== undefined);
|
|
9
|
+
const bytes = (key) => invocations.every(call => call[key] !== undefined) ? invocations.reduce((sum, call) => sum + call[key], 0) : null;
|
|
10
|
+
const checkIds = new Set();
|
|
11
|
+
let checks = [], evidenceAvailable = true;
|
|
12
|
+
try {
|
|
13
|
+
let cursor;
|
|
14
|
+
do {
|
|
15
|
+
const page = readVerificationEvidence(context, { limit: 100, ...(cursor ? { cursor } : {}) });
|
|
16
|
+
if (!page.available) {
|
|
17
|
+
evidenceAvailable = false;
|
|
18
|
+
break;
|
|
19
|
+
}
|
|
20
|
+
for (const row of page.items ?? [])
|
|
21
|
+
if (typeof row.id === 'string' && !checkIds.has(row.id)) {
|
|
22
|
+
checkIds.add(row.id);
|
|
23
|
+
checks.push(row);
|
|
24
|
+
}
|
|
25
|
+
if (checkIds.size > 10000)
|
|
26
|
+
throw new Error('Evidence summary limit');
|
|
27
|
+
cursor = 'nextCursor' in page ? page.nextCursor : undefined;
|
|
28
|
+
} while (cursor);
|
|
29
|
+
}
|
|
30
|
+
catch {
|
|
31
|
+
checks = [];
|
|
32
|
+
evidenceAvailable = false;
|
|
33
|
+
}
|
|
34
|
+
const checksComplete = evidenceAvailable && checks.every(check => check.status !== 'interrupted' && typeof check.durationMs === 'number');
|
|
35
|
+
const escalatedRoles = new Set();
|
|
36
|
+
const escalations = invocations.filter(call => { if (call.tier !== 'escalation' || escalatedRoles.has(call.role))
|
|
37
|
+
return false; escalatedRoles.add(call.role); return true; }).map(call => ({ role: call.role, attemptId: call.attemptId, provider: call.provider, model: call.model ?? null, effort: call.requestedEffort ?? null, reason: call.routeReason ?? null }));
|
|
38
|
+
return {
|
|
39
|
+
schemaVersion: 1, currentEvidenceIds: [...(identity?.verification?.receipt?.commands.flatMap(command => command.evidenceId ? [command.evidenceId] : []) ?? []), ...(identity?.verification?.receipt?.notRunEvidenceIds ?? [])].slice(0, 100), planHash: identity?.planHash ?? null, candidateHash: identity?.candidateHash ?? null, runId: state.runId, workflowVersion: state.workflowVersion,
|
|
40
|
+
technicalAcceptance: completion?.validation === 'verified' ? 'validated' : completion?.validation === 'with-exceptions' ? 'with-exceptions' : completion?.validation === 'blocked' ? 'blocked' : 'pending',
|
|
41
|
+
archive: completion?.archive ?? 'pending', delivery: completion?.delivery ?? 'pending',
|
|
42
|
+
roles: ['architect', 'developer', 'reviewer'].map(role => {
|
|
43
|
+
const selected = config?.agents[role], latest = invocations.filter(call => call.role === role).at(-1);
|
|
44
|
+
return { role, provider: latest?.provider ?? selected?.provider ?? null, model: latest?.model ?? selected?.model ?? null, effort: latest ? latest.requestedEffort ?? null : selected?.effort ?? null, observedModel: null, observedEffort: null, origin: 'frozen-runtime-config', tier: latest?.tier ?? 'base' };
|
|
45
|
+
}),
|
|
46
|
+
invocations: { byKind, total: invocations.length, complete: measured, promptBytes: bytes('promptBytes'), contextBytes: bytes('contextBytes'), handoffBytes: bytes('handoffBytes'), fullContexts: invocations.filter(call => call.contextMode === 'full').length, incrementalContexts: invocations.filter(call => call.contextMode === 'incremental').length },
|
|
47
|
+
escalations: escalations.slice(-16), escalationsTruncated: escalations.length > 16,
|
|
48
|
+
checks: { invalidated: identity && evidenceAvailable ? checks.filter(check => check.planHash !== identity.planHash || check.candidateHash !== identity.candidateHash || check.reuseReason === 'snapshot-inputs-changed-during-verification').length : null, available: evidenceAvailable, complete: checksComplete, executed: checksComplete ? checks.filter(check => check.disposition === 'executed').length : null, reused: evidenceAvailable ? checks.filter(check => check.disposition === 'reused').length : null, notRun: evidenceAvailable ? checks.filter(check => check.disposition === 'not-run').length : null, durationMs: checksComplete ? checks.reduce((sum, check) => sum + (typeof check.durationMs === 'number' ? check.durationMs : 0), 0) : null },
|
|
49
|
+
metrics: runtimeEfficiency(state),
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=efficiency-summary.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"efficiency-summary.js","sourceRoot":"","sources":["../../src/agent-runtime/efficiency-summary.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/** Subsets of inputTokens, never added again to the existing token total. */
|
|
2
|
+
export interface CacheTokenUsage {
|
|
3
|
+
uncachedInputTokens?: number | null;
|
|
4
|
+
cacheReadInputTokens?: number | null;
|
|
5
|
+
cacheWriteInputTokens?: number | null;
|
|
6
|
+
}
|
|
7
|
+
export interface ProviderInvocation {
|
|
8
|
+
invocationId?: string;
|
|
9
|
+
ordinal?: number;
|
|
10
|
+
kind?: import('./role-routing.js').InvocationKind;
|
|
11
|
+
tier?: 'base' | 'escalation';
|
|
12
|
+
routeReason?: string;
|
|
13
|
+
contextMode?: 'full' | 'incremental';
|
|
14
|
+
promptBytes?: number;
|
|
15
|
+
contextBytes?: number;
|
|
16
|
+
handoffBytes?: number;
|
|
17
|
+
requestedEffort?: string | null;
|
|
18
|
+
provider: string;
|
|
19
|
+
/** Requested model; absent means the provider selected its default. */
|
|
20
|
+
model?: string;
|
|
21
|
+
status: 'succeeded' | 'failed';
|
|
22
|
+
/** Entire executor wall time, including its native tools and process startup. */
|
|
23
|
+
durationMs: number;
|
|
24
|
+
toolCalls: number;
|
|
25
|
+
usage: CacheTokenUsage & {
|
|
26
|
+
inputTokens: number | null;
|
|
27
|
+
outputTokens: number | null;
|
|
28
|
+
costUsd: number | null;
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
export declare const CACHE_TOKEN_KEYS: readonly ["uncachedInputTokens", "cacheReadInputTokens", "cacheWriteInputTokens"];
|
|
32
|
+
export declare function sumCacheUsage(values: CacheTokenUsage[]): CacheTokenUsage;
|
|
33
|
+
export interface EfficiencyTotals {
|
|
34
|
+
attempts: number;
|
|
35
|
+
measuredAttempts: number;
|
|
36
|
+
/** Completed phase wall time; null while an attempt has no end timestamp. */
|
|
37
|
+
durationMs: number | null;
|
|
38
|
+
agentDurationMs: number | null;
|
|
39
|
+
providerCalls: number | null;
|
|
40
|
+
toolCalls: number | null;
|
|
41
|
+
inputTokens: number | null;
|
|
42
|
+
outputTokens: number | null;
|
|
43
|
+
costUsd: number | null;
|
|
44
|
+
uncachedInputTokens: number | null;
|
|
45
|
+
cacheReadInputTokens: number | null;
|
|
46
|
+
cacheWriteInputTokens: number | null;
|
|
47
|
+
}
|
|
48
|
+
export interface RuntimeEfficiency {
|
|
49
|
+
schemaVersion: 1;
|
|
50
|
+
total: EfficiencyTotals;
|
|
51
|
+
phases: Array<EfficiencyTotals & {
|
|
52
|
+
stepId: string;
|
|
53
|
+
providers: string[];
|
|
54
|
+
models: string[];
|
|
55
|
+
}>;
|
|
56
|
+
}
|
|
57
|
+
export type PendingProviderInvocation = Pick<ProviderInvocation, 'provider' | 'model' | 'kind' | 'tier' | 'routeReason' | 'contextMode' | 'promptBytes' | 'contextBytes' | 'handoffBytes' | 'requestedEffort'> & {
|
|
58
|
+
invocationId: string;
|
|
59
|
+
ordinal: number;
|
|
60
|
+
};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export const CACHE_TOKEN_KEYS = ['uncachedInputTokens', 'cacheReadInputTokens', 'cacheWriteInputTokens'];
|
|
2
|
+
export function sumCacheUsage(values) {
|
|
3
|
+
if (!values.some(value => CACHE_TOKEN_KEYS.some(key => value[key] !== undefined)))
|
|
4
|
+
return {};
|
|
5
|
+
return Object.fromEntries(CACHE_TOKEN_KEYS.map(key => [key, values.some(value => value[key] == null)
|
|
6
|
+
? null : values.reduce((sum, value) => sum + (value[key] ?? 0), 0)]));
|
|
7
|
+
}
|
|
8
|
+
//# sourceMappingURL=efficiency-types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"efficiency-types.js","sourceRoot":"","sources":["../../src/agent-runtime/efficiency-types.ts"],"names":[],"mappings":"AA0BA,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,qBAAqB,EAAE,sBAAsB,EAAE,uBAAuB,CAAU,CAAA;AAEjH,MAAM,UAAU,aAAa,CAAC,MAAyB;IACrD,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,gBAAgB,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,SAAS,CAAC,CAAC;QAAE,OAAO,EAAE,CAAA;IAC5F,OAAO,MAAM,CAAC,WAAW,CAAC,gBAAgB,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,GAAG,EAAE,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC;YAClG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,KAAK,EAAE,EAAE,CAAC,GAAG,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;AACzE,CAAC"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { WorkflowState } from './workflow-types.js';
|
|
2
|
+
import { type RuntimeEfficiency } from './efficiency-types.js';
|
|
3
|
+
export * from './efficiency-types.js';
|
|
4
|
+
/** Read-only projection: failed/superseded attempts remain spend, polling never changes it. */
|
|
5
|
+
export declare function runtimeEfficiency(state: WorkflowState): RuntimeEfficiency;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { CACHE_TOKEN_KEYS } from './efficiency-types.js';
|
|
2
|
+
export * from './efficiency-types.js';
|
|
3
|
+
function sum(values) {
|
|
4
|
+
return values.some(value => value == null || !Number.isFinite(value) || value < 0) ? null : values.reduce((total, value) => total + (value ?? 0), 0);
|
|
5
|
+
}
|
|
6
|
+
const AGENT_PHASES = new Set(['architect', 'developer', 'reviewer']);
|
|
7
|
+
function totals(attempts) {
|
|
8
|
+
const invocations = attempts.flatMap(attempt => attempt.invocations ?? []);
|
|
9
|
+
const measured = attempts.filter(attempt => !AGENT_PHASES.has(attempt.stepId) || attempt.invocations !== undefined);
|
|
10
|
+
const complete = measured.length === attempts.length && attempts.every(attempt => !attempt.pendingInvocations?.length);
|
|
11
|
+
const duration = (attempt) => attempt.completedAt ? Math.max(0, Date.parse(attempt.completedAt) - Date.parse(attempt.startedAt)) : null;
|
|
12
|
+
const cache = Object.fromEntries(CACHE_TOKEN_KEYS.map(key => [key, complete ? sum(invocations.map(call => call.usage[key])) : null]));
|
|
13
|
+
return {
|
|
14
|
+
attempts: attempts.length, measuredAttempts: measured.length,
|
|
15
|
+
durationMs: sum(attempts.map(duration)),
|
|
16
|
+
agentDurationMs: complete ? sum(invocations.map(call => call.durationMs)) : null,
|
|
17
|
+
providerCalls: complete ? invocations.length : null,
|
|
18
|
+
toolCalls: complete ? sum(invocations.map(call => call.toolCalls)) : null,
|
|
19
|
+
inputTokens: sum(attempts.map(attempt => attempt.usage?.inputTokens)),
|
|
20
|
+
outputTokens: sum(attempts.map(attempt => attempt.usage?.outputTokens)),
|
|
21
|
+
costUsd: sum(attempts.map(attempt => attempt.usage?.costUsd)),
|
|
22
|
+
...cache,
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
/** Read-only projection: failed/superseded attempts remain spend, polling never changes it. */
|
|
26
|
+
export function runtimeEfficiency(state) {
|
|
27
|
+
const phases = [...new Set(state.history.map(attempt => attempt.stepId))].map(stepId => {
|
|
28
|
+
const attempts = state.history.filter(attempt => attempt.stepId === stepId);
|
|
29
|
+
const calls = attempts.flatMap(attempt => attempt.invocations ?? []);
|
|
30
|
+
return { stepId, ...totals(attempts), providers: [...new Set(calls.map(call => call.provider))], models: [...new Set(calls.map(call => call.model).filter((model) => model !== undefined))] };
|
|
31
|
+
});
|
|
32
|
+
const pending = state.history.some(attempt => attempt.pendingInvocations?.length);
|
|
33
|
+
return { schemaVersion: 1, total: { ...totals(state.history), durationMs: state.usage.durationMs, inputTokens: pending ? null : state.usage.inputTokens, outputTokens: pending ? null : state.usage.outputTokens, costUsd: pending ? null : state.usage.costUsd }, phases };
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=efficiency.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"efficiency.js","sourceRoot":"","sources":["../../src/agent-runtime/efficiency.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/** Frozen fixture definitions and independent assertions; no model call or install. */
|
|
2
|
+
export interface EvaluationCase {
|
|
3
|
+
id: string;
|
|
4
|
+
description: string;
|
|
5
|
+
repositories: string[];
|
|
6
|
+
source: string;
|
|
7
|
+
solution: string;
|
|
8
|
+
defects: string[];
|
|
9
|
+
oracle: string;
|
|
10
|
+
verification?: string;
|
|
11
|
+
correction?: 'verification' | 'review';
|
|
12
|
+
}
|
|
13
|
+
export declare const EVALUATION_CORPUS: EvaluationCase[];
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export const EVALUATION_CORPUS = [
|
|
2
|
+
{ id: 'static-tetris', verification: 'assert.deepStrictEqual(api.clearRows([[1,1]]), [[0,0]])', description: 'Clear complete rows in a static browser game without removing partial rows.', repositories: ['game'], source: 'exports.clearRows = board => board', solution: 'exports.clearRows = board => { const remaining = board.filter(row => row.some(cell => !cell)); return [...Array.from({length: board.length - remaining.length}, () => Array(board[0].length).fill(0)), ...remaining.map(row => [...row])]; }', defects: ['exports.clearRows = board => board', 'exports.clearRows = board => board.filter(row => row.every(Boolean))'], oracle: 'assert.deepStrictEqual(api.clearRows([[1,1],[1,0],[1,1]]), [[0,0],[0,0],[1,0]]); assert.deepStrictEqual(api.clearRows([[0,1],[1,0]]), [[0,1],[1,0]]);' },
|
|
3
|
+
{ id: 'local-tested-feature', verification: 'assert.strictEqual(api.subtotal([]), 0)', description: 'Calculate an integer-cent subtotal including repeated quantities and empty baskets.', repositories: ['shop'], source: 'exports.subtotal = items => 0', solution: 'exports.subtotal = items => items.reduce((sum, item) => sum + item.cents * item.quantity, 0)', defects: ['exports.subtotal = items => items.length', 'exports.subtotal = items => items.reduce((sum, item) => sum + item.cents, 0)'], oracle: 'assert.strictEqual(api.subtotal([]), 0); assert.strictEqual(api.subtotal([{cents: 125, quantity: 3}, {cents: 20, quantity: 2}]), 415);' },
|
|
4
|
+
{ id: 'cross-repository-contract', verification: 'assert.strictEqual(api.alert().active, true)', description: 'Keep both repositories on the same alert contract: an active severity and its informational flag.', repositories: ['front', 'back'], source: 'exports.alert = () => ({active: false})', solution: 'exports.alert = () => ({active: true, severity: "warning", informational: true})', defects: ['exports.alert = () => ({active: true, severity: "warning"})', 'exports.alert = () => ({active: true, severity: "error", informational: false})'], oracle: 'assert.deepStrictEqual(api.alert(), {active: true, severity: "warning", informational: true});' },
|
|
5
|
+
{ id: 'verification-correction', verification: 'assert.strictEqual(api.clamp(11, 0, 10), 10)', description: 'Clamp values to both boundaries, including an already valid value.', repositories: ['math'], source: 'exports.clamp = value => value', solution: 'exports.clamp = (value, min, max) => Math.min(max, Math.max(min, value))', defects: ['exports.clamp = (value, min, max) => Math.max(min, value)', 'exports.clamp = (value, min, max) => Math.min(max, value)'], oracle: 'assert.strictEqual(api.clamp(-1, 0, 10), 0); assert.strictEqual(api.clamp(11, 0, 10), 10); assert.strictEqual(api.clamp(5, 0, 10), 5);', correction: 'verification' },
|
|
6
|
+
{ id: 'review-correction', verification: 'assert.strictEqual(typeof api.unique, "function")', description: 'Deduplicate stable values while preserving the first occurrence order.', repositories: ['collections'], source: 'exports.unique = values => values', solution: 'exports.unique = values => [...new Set(values)]', defects: ['exports.unique = values => [...new Set(values)].sort()', 'exports.unique = values => values'], oracle: 'assert.deepStrictEqual(api.unique([3, 1, 3, 2, 1]), [3, 1, 2]); assert.deepStrictEqual(api.unique([]), []);', correction: 'review' },
|
|
7
|
+
];
|
|
8
|
+
//# sourceMappingURL=evaluation-corpus.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"evaluation-corpus.js","sourceRoot":"","sources":["../../src/agent-runtime/evaluation-corpus.ts"],"names":[],"mappings":"AAYA,MAAM,CAAC,MAAM,iBAAiB,GAAqB;IACjD,EAAE,EAAE,EAAE,eAAe,EAAE,YAAY,EAAE,yDAAyD,EAAE,WAAW,EAAE,6EAA6E,EAAE,YAAY,EAAE,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,oCAAoC,EAAE,QAAQ,EAAE,8OAA8O,EAAE,OAAO,EAAE,CAAC,oCAAoC,EAAE,sEAAsE,CAAC,EAAE,MAAM,EAAE,uJAAuJ,EAAE;IACtxB,EAAE,EAAE,EAAE,sBAAsB,EAAE,YAAY,EAAE,yCAAyC,EAAE,WAAW,EAAE,qFAAqF,EAAE,YAAY,EAAE,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,+BAA+B,EAAE,QAAQ,EAAE,8FAA8F,EAAE,OAAO,EAAE,CAAC,0CAA0C,EAAE,8EAA8E,CAAC,EAAE,MAAM,EAAE,wIAAwI,EAAE;IAC/nB,EAAE,EAAE,EAAE,2BAA2B,EAAE,YAAY,EAAE,8CAA8C,EAAE,WAAW,EAAE,mGAAmG,EAAE,YAAY,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC,EAAE,MAAM,EAAE,yCAAyC,EAAE,QAAQ,EAAE,kFAAkF,EAAE,OAAO,EAAE,CAAC,6DAA6D,EAAE,iFAAiF,CAAC,EAAE,MAAM,EAAE,gGAAgG,EAAE;IAC5oB,EAAE,EAAE,EAAE,yBAAyB,EAAE,YAAY,EAAE,8CAA8C,EAAE,WAAW,EAAE,oEAAoE,EAAE,YAAY,EAAE,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,gCAAgC,EAAE,QAAQ,EAAE,0EAA0E,EAAE,OAAO,EAAE,CAAC,2DAA2D,EAAE,2DAA2D,CAAC,EAAE,MAAM,EAAE,wIAAwI,EAAE,UAAU,EAAE,cAAc,EAAE;IAC7nB,EAAE,EAAE,EAAE,mBAAmB,EAAE,YAAY,EAAE,mDAAmD,EAAE,WAAW,EAAE,wEAAwE,EAAE,YAAY,EAAE,CAAC,aAAa,CAAC,EAAE,MAAM,EAAE,mCAAmC,EAAE,QAAQ,EAAE,iDAAiD,EAAE,OAAO,EAAE,CAAC,wDAAwD,EAAE,mCAAmC,CAAC,EAAE,MAAM,EAAE,6GAA6G,EAAE,UAAU,EAAE,QAAQ,EAAE;CACtjB,CAAA"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import type { RuntimeConfig } from './executor-types.js';
|
|
2
|
+
export interface EvaluationOptions {
|
|
3
|
+
output: string;
|
|
4
|
+
config?: RuntimeConfig;
|
|
5
|
+
maxCostUsd?: number;
|
|
6
|
+
real?: boolean;
|
|
7
|
+
repetitions?: number;
|
|
8
|
+
}
|
|
9
|
+
export declare function runEvaluation(options: EvaluationOptions): Promise<{
|
|
10
|
+
schemaVersion: number;
|
|
11
|
+
experiment: string;
|
|
12
|
+
noExtraInvocations: boolean;
|
|
13
|
+
mode: string;
|
|
14
|
+
runtimeIdentity: import("./runtime-identity.js").RuntimeIdentity;
|
|
15
|
+
corpusHash: string;
|
|
16
|
+
measurement: string;
|
|
17
|
+
monetaryTarget: number;
|
|
18
|
+
monetaryConclusion: string;
|
|
19
|
+
groups: {
|
|
20
|
+
[k: string]: {
|
|
21
|
+
samples: number;
|
|
22
|
+
independentlyAccepted: number;
|
|
23
|
+
costPerAcceptedUsd: number | null;
|
|
24
|
+
medianActiveDurationMs: number | null;
|
|
25
|
+
minActiveDurationMs: number | null;
|
|
26
|
+
maxActiveDurationMs: number | null;
|
|
27
|
+
standardDeviationMs: number | null;
|
|
28
|
+
};
|
|
29
|
+
};
|
|
30
|
+
noObservedQualityDrop: boolean;
|
|
31
|
+
promptPairs: {
|
|
32
|
+
caseId: unknown;
|
|
33
|
+
repeat: unknown;
|
|
34
|
+
fullBytes: number | null;
|
|
35
|
+
optimizedBytes: number | null;
|
|
36
|
+
reduction: number | null;
|
|
37
|
+
}[];
|
|
38
|
+
correctionPromptTargetMet: boolean;
|
|
39
|
+
sampleLimitations: string;
|
|
40
|
+
stopReason: string | null;
|
|
41
|
+
reportedSpendUsd: number;
|
|
42
|
+
observations: Record<string, unknown>[];
|
|
43
|
+
}>;
|