@relayflows/sdk 2.0.35 → 2.0.37
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/dist/adapters/base.d.ts +16 -0
- package/dist/adapters/base.d.ts.map +1 -1
- package/dist/adapters/claude.d.ts.map +1 -1
- package/dist/adapters/claude.js +15 -0
- package/dist/adapters/claude.js.map +1 -1
- package/dist/adapters/codex.d.ts.map +1 -1
- package/dist/adapters/codex.js +4 -0
- package/dist/adapters/codex.js.map +1 -1
- package/dist/adapters/usage-limit.d.ts +2 -0
- package/dist/adapters/usage-limit.d.ts.map +1 -0
- package/dist/adapters/usage-limit.js +17 -0
- package/dist/adapters/usage-limit.js.map +1 -0
- package/dist/authored-activity.d.ts +17 -0
- package/dist/authored-activity.d.ts.map +1 -0
- package/dist/authored-activity.js +218 -0
- package/dist/authored-activity.js.map +1 -0
- package/dist/authored-child-run.d.ts +34 -0
- package/dist/authored-child-run.d.ts.map +1 -0
- package/dist/authored-child-run.js +128 -0
- package/dist/authored-child-run.js.map +1 -0
- package/dist/authored-flow-error.d.ts +32 -3
- package/dist/authored-flow-error.d.ts.map +1 -1
- package/dist/authored-flow-error.js +3 -1
- package/dist/authored-flow-error.js.map +1 -1
- package/dist/authored-flow-executor.d.ts +11 -1
- package/dist/authored-flow-executor.d.ts.map +1 -1
- package/dist/authored-flow-executor.js +32 -1
- package/dist/authored-flow-executor.js.map +1 -1
- package/dist/authored-helper-effect.d.ts.map +1 -1
- package/dist/authored-helper-effect.js +3 -2
- package/dist/authored-helper-effect.js.map +1 -1
- package/dist/authored-mcp.d.ts.map +1 -1
- package/dist/authored-mcp.js +4 -2
- package/dist/authored-mcp.js.map +1 -1
- package/dist/authored-node-entry.js +9 -1
- package/dist/authored-node-entry.js.map +1 -1
- package/dist/authored-node-runner.d.ts.map +1 -1
- package/dist/authored-node-runner.js +42 -9
- package/dist/authored-node-runner.js.map +1 -1
- package/dist/authored-plugin-effect.d.ts.map +1 -1
- package/dist/authored-plugin-effect.js +4 -2
- package/dist/authored-plugin-effect.js.map +1 -1
- package/dist/authored-preflight.d.ts +1 -1
- package/dist/authored-preflight.d.ts.map +1 -1
- package/dist/authored-preflight.js +2 -2
- package/dist/authored-preflight.js.map +1 -1
- package/dist/authored-root.d.ts +12 -7
- package/dist/authored-root.d.ts.map +1 -1
- package/dist/authored-root.js +24 -0
- package/dist/authored-root.js.map +1 -1
- package/dist/authored-step-output.d.ts +24 -8
- package/dist/authored-step-output.d.ts.map +1 -1
- package/dist/authored-step-output.js +81 -15
- package/dist/authored-step-output.js.map +1 -1
- package/dist/authored-subscription-park.d.ts +5 -0
- package/dist/authored-subscription-park.d.ts.map +1 -0
- package/dist/authored-subscription-park.js +47 -0
- package/dist/authored-subscription-park.js.map +1 -0
- package/dist/authored-verdict.d.ts +2 -0
- package/dist/authored-verdict.d.ts.map +1 -1
- package/dist/authored-verdict.js +2 -1
- package/dist/authored-verdict.js.map +1 -1
- package/dist/authored-worker-step.d.ts +1 -1
- package/dist/authored-worker-step.d.ts.map +1 -1
- package/dist/authored-worker-step.js +9 -4
- package/dist/authored-worker-step.js.map +1 -1
- package/dist/cli/check-activities.d.ts +8 -0
- package/dist/cli/check-activities.d.ts.map +1 -0
- package/dist/cli/check-activities.js +155 -0
- package/dist/cli/check-activities.js.map +1 -0
- package/dist/cli/check.d.ts +2 -0
- package/dist/cli/check.d.ts.map +1 -1
- package/dist/cli/check.js +3 -3
- package/dist/cli/check.js.map +1 -1
- package/dist/cli/cli-probe.d.ts +2 -2
- package/dist/cli/cli-probe.d.ts.map +1 -1
- package/dist/cli/cli-probe.js +22 -9
- package/dist/cli/cli-probe.js.map +1 -1
- package/dist/cli/direct-run.d.ts.map +1 -1
- package/dist/cli/direct-run.js +17 -4
- package/dist/cli/direct-run.js.map +1 -1
- package/dist/cli/run.d.ts +18 -5
- package/dist/cli/run.d.ts.map +1 -1
- package/dist/cli/run.js +37 -12
- package/dist/cli/run.js.map +1 -1
- package/dist/cli/subscription-report.d.ts +5 -0
- package/dist/cli/subscription-report.d.ts.map +1 -0
- package/dist/cli/subscription-report.js +48 -0
- package/dist/cli/subscription-report.js.map +1 -0
- package/dist/cli-adapter.d.ts +4 -2
- package/dist/cli-adapter.d.ts.map +1 -1
- package/dist/cli-adapter.js +4 -0
- package/dist/cli-adapter.js.map +1 -1
- package/dist/cli.d.ts +1 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +13 -5
- package/dist/cli.js.map +1 -1
- package/dist/communication/local.d.ts +1 -1
- package/dist/communication/local.d.ts.map +1 -1
- package/dist/communication/local.js +2 -2
- package/dist/communication/local.js.map +1 -1
- package/dist/communication/worker.d.ts +1 -1
- package/dist/communication/worker.d.ts.map +1 -1
- package/dist/communication/worker.js +4 -4
- package/dist/communication/worker.js.map +1 -1
- package/dist/decimal-dollars.d.ts +12 -0
- package/dist/decimal-dollars.d.ts.map +1 -0
- package/dist/decimal-dollars.js +39 -0
- package/dist/decimal-dollars.js.map +1 -0
- package/dist/effect-channel.d.ts.map +1 -1
- package/dist/effect-channel.js +2 -0
- package/dist/effect-channel.js.map +1 -1
- package/dist/failure-kinds.d.ts +2 -2
- package/dist/failure-kinds.d.ts.map +1 -1
- package/dist/failure-kinds.js +2 -0
- package/dist/failure-kinds.js.map +1 -1
- package/dist/helper-instruction.d.ts +3 -0
- package/dist/helper-instruction.d.ts.map +1 -0
- package/dist/helper-instruction.js +3 -0
- package/dist/helper-instruction.js.map +1 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/journal-client.d.ts +21 -3
- package/dist/journal-client.d.ts.map +1 -1
- package/dist/journal-client.js +45 -6
- package/dist/journal-client.js.map +1 -1
- package/dist/journal-reader.d.ts.map +1 -1
- package/dist/journal-reader.js +2 -0
- package/dist/journal-reader.js.map +1 -1
- package/dist/llm-worker.d.ts +2 -1
- package/dist/llm-worker.d.ts.map +1 -1
- package/dist/llm-worker.js +7 -2
- package/dist/llm-worker.js.map +1 -1
- package/dist/local-agent-environment.d.ts +13 -0
- package/dist/local-agent-environment.d.ts.map +1 -0
- package/dist/local-agent-environment.js +104 -0
- package/dist/local-agent-environment.js.map +1 -0
- package/dist/local-agent.d.ts +4 -1
- package/dist/local-agent.d.ts.map +1 -1
- package/dist/local-agent.js +15 -5
- package/dist/local-agent.js.map +1 -1
- package/dist/preflight.d.ts +6 -0
- package/dist/preflight.d.ts.map +1 -1
- package/dist/preflight.js +36 -10
- package/dist/preflight.js.map +1 -1
- package/dist/protocol.d.ts +187 -1
- package/dist/protocol.d.ts.map +1 -1
- package/dist/reported-cost-total.d.ts +41 -0
- package/dist/reported-cost-total.d.ts.map +1 -0
- package/dist/reported-cost-total.js +63 -0
- package/dist/reported-cost-total.js.map +1 -0
- package/dist/reported-cost.d.ts +24 -0
- package/dist/reported-cost.d.ts.map +1 -0
- package/dist/reported-cost.js +49 -0
- package/dist/reported-cost.js.map +1 -0
- package/dist/run-state.d.ts +9 -11
- package/dist/run-state.d.ts.map +1 -1
- package/dist/run-state.js +15 -38
- package/dist/run-state.js.map +1 -1
- package/dist/step-settling.d.ts +11 -0
- package/dist/step-settling.d.ts.map +1 -0
- package/dist/step-settling.js +22 -0
- package/dist/step-settling.js.map +1 -0
- package/dist/worker-cli.d.ts +1 -1
- package/dist/worker-cli.d.ts.map +1 -1
- package/dist/worker-cli.js +3 -3
- package/dist/worker-cli.js.map +1 -1
- package/dist/worker.d.ts +2 -0
- package/dist/worker.d.ts.map +1 -1
- package/dist/worker.js +5 -2
- package/dist/worker.js.map +1 -1
- package/dist/yaml-helper-effect.d.ts.map +1 -1
- package/dist/yaml-helper-effect.js +2 -1
- package/dist/yaml-helper-effect.js.map +1 -1
- package/dist/yaml-helpers.d.ts.map +1 -1
- package/dist/yaml-helpers.js +2 -1
- package/dist/yaml-helpers.js.map +1 -1
- package/package.json +2 -2
- package/src/adapters/base.ts +19 -0
- package/src/adapters/claude.ts +15 -0
- package/src/adapters/codex.ts +6 -0
- package/src/adapters/usage-limit.ts +17 -0
- package/src/authored-activity.ts +251 -0
- package/src/authored-child-run.ts +138 -0
- package/src/authored-flow-error.ts +33 -0
- package/src/authored-flow-executor.ts +44 -1
- package/src/authored-helper-effect.ts +3 -2
- package/src/authored-mcp.ts +4 -2
- package/src/authored-node-entry.ts +11 -2
- package/src/authored-node-runner.ts +43 -9
- package/src/authored-plugin-effect.ts +4 -2
- package/src/authored-preflight.ts +2 -2
- package/src/authored-root.ts +34 -4
- package/src/authored-step-output.ts +88 -15
- package/src/authored-subscription-park.ts +46 -0
- package/src/authored-verdict.ts +2 -1
- package/src/authored-worker-step.ts +9 -3
- package/src/cli/check-activities.ts +144 -0
- package/src/cli/check.ts +6 -3
- package/src/cli/cli-probe.ts +23 -9
- package/src/cli/direct-run.ts +16 -1
- package/src/cli/run.ts +59 -14
- package/src/cli/subscription-report.ts +51 -0
- package/src/cli-adapter.ts +8 -2
- package/src/cli.ts +13 -6
- package/src/communication/local.ts +3 -2
- package/src/communication/worker.ts +7 -4
- package/src/decimal-dollars.ts +38 -0
- package/src/effect-channel.ts +2 -0
- package/src/failure-kinds.ts +2 -0
- package/src/helper-instruction.ts +2 -0
- package/src/index.ts +6 -0
- package/src/journal-client.ts +60 -7
- package/src/journal-reader.ts +2 -0
- package/src/llm-worker.ts +6 -1
- package/src/local-agent-environment.ts +92 -0
- package/src/local-agent.ts +19 -4
- package/src/preflight.ts +46 -10
- package/src/protocol.ts +151 -0
- package/src/reported-cost-total.ts +82 -0
- package/src/reported-cost.ts +51 -0
- package/src/run-state.ts +25 -37
- package/src/step-settling.ts +19 -0
- package/src/worker-cli.ts +3 -2
- package/src/worker.ts +9 -2
- package/src/yaml-helper-effect.ts +2 -1
- package/src/yaml-helpers.ts +2 -1
package/src/run-state.ts
CHANGED
|
@@ -10,8 +10,13 @@
|
|
|
10
10
|
// No I/O, no clock: the caller passes `now_ms`, so a test folds a hand-built
|
|
11
11
|
// journal against a fixed instant and asserts exact elapsed and overdue values.
|
|
12
12
|
|
|
13
|
+
import { addDollars } from './decimal-dollars.js';
|
|
14
|
+
import { addReportedCost, modelFreeSteps, NO_REPORTED_COST, type ReportedCostTotal } from './reported-cost-total.js';
|
|
13
15
|
import type { JournalEvent } from './journal-reader.js';
|
|
14
16
|
|
|
17
|
+
export { addDollars } from './decimal-dollars.js';
|
|
18
|
+
export type { ReportedCostTotal } from './reported-cost-total.js';
|
|
19
|
+
|
|
15
20
|
export type RunStatus = 'running' | 'parked' | 'completed' | 'failed' | 'cancelling' | 'cancelled';
|
|
16
21
|
|
|
17
22
|
/** `StepState` variant names from state.rs, snake_case. */
|
|
@@ -25,6 +30,7 @@ export interface Spend {
|
|
|
25
30
|
dollars_unmetered: boolean;
|
|
26
31
|
}
|
|
27
32
|
|
|
33
|
+
|
|
28
34
|
export interface StepCounts {
|
|
29
35
|
total: number;
|
|
30
36
|
done: number;
|
|
@@ -91,6 +97,10 @@ export interface StepView {
|
|
|
91
97
|
completion_reason: string | null;
|
|
92
98
|
/** Paths the worker journaled for the last attempt, when its output carried them. */
|
|
93
99
|
artifacts: { paths: string[]; journaled: boolean };
|
|
100
|
+
/** Metered charges of this step's attempts: what counted toward the budget. */
|
|
101
|
+
spend: Spend;
|
|
102
|
+
/** Actual cost of this step's attempts. Null until an attempt completes. */
|
|
103
|
+
reported_cost: ReportedCostTotal | null;
|
|
94
104
|
}
|
|
95
105
|
|
|
96
106
|
export interface RunView {
|
|
@@ -101,6 +111,8 @@ export interface RunView {
|
|
|
101
111
|
spawned_at_ms: number;
|
|
102
112
|
now_ms: number;
|
|
103
113
|
spend: Spend;
|
|
114
|
+
/** Actual cost of this run's own attempts; see {@link ReportedCostTotal}. */
|
|
115
|
+
reported_cost: ReportedCostTotal;
|
|
104
116
|
counts: StepCounts;
|
|
105
117
|
steps: StepView[];
|
|
106
118
|
}
|
|
@@ -127,42 +139,6 @@ function text(value: unknown, fallback = ''): string {
|
|
|
127
139
|
return typeof value === 'string' ? value : fallback;
|
|
128
140
|
}
|
|
129
141
|
|
|
130
|
-
/**
|
|
131
|
-
* Sum two decimal dollar strings exactly, at whatever scale they carry — the
|
|
132
|
-
* kernel's budget fold (`relayflowd-core/src/state/budget.rs`) aligns every
|
|
133
|
-
* fractional digit before adding, and it accepts arbitrary precision. Scaling
|
|
134
|
-
* to a fixed six fractional digits dropped a charge of `0.0000001` to zero, so
|
|
135
|
-
* `flows status` underreported spend the kernel had totalled exactly.
|
|
136
|
-
*
|
|
137
|
-
* A value that is not a decimal number is left out of the sum rather than
|
|
138
|
-
* counted as zero, and the caller is told by `malformed`.
|
|
139
|
-
*/
|
|
140
|
-
export function addDollars(left: string, right: string): string {
|
|
141
|
-
const parsed = [left, right].map((value) => /^\d+(?:\.\d+)?$/.test(value) ? value : null);
|
|
142
|
-
const usable = parsed.filter((value): value is string => value !== null);
|
|
143
|
-
if (usable.length === 0) return '0';
|
|
144
|
-
if (usable.length === 1) return normalizeDollars(usable[0]!);
|
|
145
|
-
const scale = Math.max(...usable.map((value) => (value.split('.')[1] ?? '').length));
|
|
146
|
-
const scaled = usable.map((value) => {
|
|
147
|
-
const [whole, fraction = ''] = value.split('.');
|
|
148
|
-
return BigInt(`${whole}${fraction.padEnd(scale, '0')}`);
|
|
149
|
-
});
|
|
150
|
-
return fromScaled(scaled[0]! + scaled[1]!, scale);
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
/** `12.3400` -> `12.34`, `0.000` -> `0`; the journal's own spelling otherwise. */
|
|
154
|
-
function normalizeDollars(value: string): string {
|
|
155
|
-
const [whole, fraction = ''] = value.split('.');
|
|
156
|
-
return fromScaled(BigInt(`${whole}${fraction}`), fraction.length);
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
function fromScaled(total: bigint, scale: number): string {
|
|
160
|
-
if (scale === 0) return String(total);
|
|
161
|
-
const digits = String(total).padStart(scale + 1, '0');
|
|
162
|
-
const whole = digits.slice(0, digits.length - scale);
|
|
163
|
-
const fraction = digits.slice(digits.length - scale).replace(/0+$/, '');
|
|
164
|
-
return fraction.length === 0 ? whole : `${whole}.${fraction}`;
|
|
165
|
-
}
|
|
166
142
|
|
|
167
143
|
/**
|
|
168
144
|
* Reduce `trajectory_tail.transcript` (the digest flows#491 journals) to the
|
|
@@ -209,6 +185,7 @@ function addSpend(total: Spend, charge: unknown): Spend {
|
|
|
209
185
|
|
|
210
186
|
const ZERO_SPEND: Spend = { tokens_in: 0, tokens_out: 0, dollars: '0', dollars_unmetered: false };
|
|
211
187
|
|
|
188
|
+
|
|
212
189
|
interface StepFold {
|
|
213
190
|
view: StepView;
|
|
214
191
|
depends_on: string[];
|
|
@@ -221,6 +198,7 @@ function freshStep(id: string, type: string, maxIterations: number | null, depen
|
|
|
221
198
|
id, type, state: 'pending', attempt: 0, max_iterations: maxIterations,
|
|
222
199
|
started_at_ms: null, elapsed_ms: null, lease: null, backoff_until_ms: null, wait: null,
|
|
223
200
|
last_attempt: null, completion_reason: null, artifacts: { paths: [], journaled: false },
|
|
201
|
+
spend: ZERO_SPEND, reported_cost: null,
|
|
224
202
|
},
|
|
225
203
|
};
|
|
226
204
|
}
|
|
@@ -268,6 +246,8 @@ export function foldRunState(events: readonly JournalEvent[], now_ms: number): R
|
|
|
268
246
|
// An authored child run carries its parent's totals so ceilings hold across
|
|
269
247
|
// the family (state.rs `prior_spend`); the view reports the same running total.
|
|
270
248
|
let spend = addSpend(ZERO_SPEND, budget['prior_spend']);
|
|
249
|
+
let reportedCost = NO_REPORTED_COST;
|
|
250
|
+
const modelFree = modelFreeSteps(first);
|
|
271
251
|
let completion: string | null = null;
|
|
272
252
|
let cancelRequested = false;
|
|
273
253
|
|
|
@@ -297,6 +277,9 @@ export function foldRunState(events: readonly JournalEvent[], now_ms: number): R
|
|
|
297
277
|
const attempt = event.attempt ?? view.attempt;
|
|
298
278
|
view.attempt = Math.max(view.attempt, attempt);
|
|
299
279
|
spend = addSpend(spend, payload['budget']);
|
|
280
|
+
view.spend = addSpend(view.spend, payload['budget']);
|
|
281
|
+
reportedCost = addReportedCost(reportedCost, payload, modelFree.has(view.id));
|
|
282
|
+
view.reported_cost = addReportedCost(view.reported_cost ?? NO_REPORTED_COST, payload, modelFree.has(view.id));
|
|
300
283
|
const verification = payload['verification'] !== null && typeof payload['verification'] === 'object'
|
|
301
284
|
? payload['verification'] as Payload : undefined;
|
|
302
285
|
view.last_attempt = {
|
|
@@ -362,8 +345,12 @@ export function foldRunState(events: readonly JournalEvent[], now_ms: number): R
|
|
|
362
345
|
// A new epoch restarts every step (state.rs `apply_epoch`); the
|
|
363
346
|
// summary then restores the ones it carries forward.
|
|
364
347
|
for (const step of steps.values()) {
|
|
365
|
-
const { id, type, max_iterations } = step.view;
|
|
348
|
+
const { id, type, max_iterations, spend: stepSpend, reported_cost: stepCost } = step.view;
|
|
366
349
|
step.view = freshStep(id, type, max_iterations, step.depends_on).view;
|
|
350
|
+
// Rollover keeps the earlier segments' completions in the journal,
|
|
351
|
+
// and this fold has already read them: what the step cost stays.
|
|
352
|
+
step.view.spend = stepSpend;
|
|
353
|
+
step.view.reported_cost = stepCost;
|
|
367
354
|
}
|
|
368
355
|
spend = addSpend(ZERO_SPEND, payload['budget_spent']);
|
|
369
356
|
const done = payload['steps_done'] !== null && typeof payload['steps_done'] === 'object' ? payload['steps_done'] as Payload : {};
|
|
@@ -462,6 +449,7 @@ export function foldRunState(events: readonly JournalEvent[], now_ms: number): R
|
|
|
462
449
|
spawned_at_ms: first.at_ms,
|
|
463
450
|
now_ms,
|
|
464
451
|
spend,
|
|
452
|
+
reported_cost: reportedCost,
|
|
465
453
|
counts,
|
|
466
454
|
steps: views,
|
|
467
455
|
};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A step's LAST settling `step.completed`: the verdict the kernel settled the
|
|
3
|
+
* step on. `retry` and `park` completions record an attempt the kernel did
|
|
4
|
+
* NOT settle it on (relayflowd-core `Disposition`) — crash recovery's
|
|
5
|
+
* `crashed`, a `worker_error` with iterations left — and precede the attempt
|
|
6
|
+
* that did, so neither the first completion nor a completion count is the
|
|
7
|
+
* step's verdict. Shared by the authored reader and the Bun result verifier,
|
|
8
|
+
* which must agree on which completion a claim is judged against.
|
|
9
|
+
*/
|
|
10
|
+
export function settlingCompletion<T>(entries: readonly T[], stepId: string): T | undefined {
|
|
11
|
+
return entries.filter(entry => {
|
|
12
|
+
if (typeof entry !== 'object' || entry === null) return false;
|
|
13
|
+
const { entry_type: type, step_id: step, payload } = entry as Record<string, unknown>;
|
|
14
|
+
if (type !== 'step.completed' || step !== stepId) return false;
|
|
15
|
+
const disposition = typeof payload === 'object' && payload !== null
|
|
16
|
+
? (payload as Record<string, unknown>)['disposition'] : undefined;
|
|
17
|
+
return disposition !== 'retry' && disposition !== 'park';
|
|
18
|
+
}).at(-1);
|
|
19
|
+
}
|
package/src/worker-cli.ts
CHANGED
|
@@ -91,6 +91,7 @@ export async function runAgentCli(
|
|
|
91
91
|
cwd?: string,
|
|
92
92
|
transport: AgentTransport = 'direct',
|
|
93
93
|
relayContext?: AgentRelayContext,
|
|
94
|
+
processEnvironment: NodeJS.ProcessEnv = process.env,
|
|
94
95
|
): Promise<WorkerCliResult> {
|
|
95
96
|
signal?.throwIfAborted();
|
|
96
97
|
if (signal !== undefined && process.platform === 'win32') {
|
|
@@ -134,7 +135,7 @@ export async function runAgentCli(
|
|
|
134
135
|
if (kind === 'relayflows-wrapper-v1') {
|
|
135
136
|
// The closed allowlist admits no ambient RELAYFLOW_* value; the four
|
|
136
137
|
// discovery names are set from this dispatch, exactly as for a direct spawn.
|
|
137
|
-
const wrapperEnv = wrapperEnvironment(
|
|
138
|
+
const wrapperEnv = wrapperEnvironment(processEnvironment);
|
|
138
139
|
applyStepEnvironment(wrapperEnv, sidechannel);
|
|
139
140
|
return requirePricedUsage(decodeWrapperResult(await runWrapperSession(
|
|
140
141
|
cli,
|
|
@@ -148,7 +149,7 @@ export async function runAgentCli(
|
|
|
148
149
|
)), effectiveModel);
|
|
149
150
|
}
|
|
150
151
|
|
|
151
|
-
const env: NodeJS.ProcessEnv = { ...
|
|
152
|
+
const env: NodeJS.ProcessEnv = { ...processEnvironment };
|
|
152
153
|
delete env[WAKE_CONTEXT_ENV];
|
|
153
154
|
delete env[MODEL_ENV];
|
|
154
155
|
// Where this attempt's journal is, so the agent can run `flows status` on
|
package/src/worker.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { communicationInstruction } from './communication/spec.js';
|
|
2
2
|
import { workerSpend } from './worker-spend.js';
|
|
3
|
+
import { reportedCost } from './reported-cost.js';
|
|
3
4
|
import type { WorkerCliResult } from './worker-cli.js';
|
|
4
5
|
import { EventEmitter } from 'node:events';
|
|
5
6
|
import type { JournalClient } from './journal-client.js';
|
|
@@ -31,6 +32,8 @@ export interface AgentWorkerOptions {
|
|
|
31
32
|
* the root a dispatch is measured against is a value, not an assumption.
|
|
32
33
|
*/
|
|
33
34
|
runRoot?: string;
|
|
35
|
+
/** Environment inherited by provider CLIs, including agent-only secrets. */
|
|
36
|
+
environment?: NodeJS.ProcessEnv;
|
|
34
37
|
}
|
|
35
38
|
|
|
36
39
|
/**
|
|
@@ -122,7 +125,8 @@ export class AgentWorker extends EventEmitter {
|
|
|
122
125
|
if (communication) {
|
|
123
126
|
if (!this.options.dataDir) throw new Error('Agent communication requires a worker data directory');
|
|
124
127
|
const { completeCommunicationDispatch } = await import('./communication/worker.js');
|
|
125
|
-
await completeCommunicationDispatch(this.client, dispatch, communication, this.options.dataDir,
|
|
128
|
+
await completeCommunicationDispatch(this.client, dispatch, communication, this.options.dataDir,
|
|
129
|
+
this.options.runRoot, this.options.environment);
|
|
126
130
|
return;
|
|
127
131
|
}
|
|
128
132
|
let humanIntervention = false;
|
|
@@ -142,9 +146,11 @@ export class AgentWorker extends EventEmitter {
|
|
|
142
146
|
}, cwd.directory ?? (spec.transport === 'relay' ? undefined : this.options.runRoot),
|
|
143
147
|
spec.transport === 'relay' ? 'relay' : 'direct',
|
|
144
148
|
{ runId: dispatch.run_id, stepId: dispatch.step_id, idempotencyKey: dispatch.idempotency_key,
|
|
145
|
-
dataDir: this.options.dataDir, resultSchema: spec.verification?.json_schema }
|
|
149
|
+
dataDir: this.options.dataDir, resultSchema: spec.verification?.json_schema },
|
|
150
|
+
this.options.environment)
|
|
146
151
|
: Promise.resolve({ exit_code: null, stdout_tail: '', stderr_tail: 'agent step has no declared CLI' }));
|
|
147
152
|
const { result, usage } = workerSpend(completed, effectiveModel);
|
|
153
|
+
const cost = reportedCost(completed, effectiveModel);
|
|
148
154
|
const completionReason = result.exit_code === 0 ? 'success' : 'worker_error';
|
|
149
155
|
|
|
150
156
|
// Output shape: if the CLI's stdout parses as JSON, promote THAT
|
|
@@ -195,6 +201,7 @@ export class AgentWorker extends EventEmitter {
|
|
|
195
201
|
...(Object.keys(trajectoryTail).length === 0 ? {} : { trajectory_tail: trajectoryTail }),
|
|
196
202
|
...(humanIntervention ? { human_intervention: true } : {}),
|
|
197
203
|
...(usage !== undefined ? { usage } : {}),
|
|
204
|
+
...(cost === undefined ? {} : { reported_cost: cost }),
|
|
198
205
|
started_pins: dispatch.pins,
|
|
199
206
|
end_pins: dispatch.pins,
|
|
200
207
|
},
|
|
@@ -8,6 +8,7 @@ import type { StepDispatchEvent } from './protocol.js';
|
|
|
8
8
|
import { atomicJson, readSlackReceipt, receiptPath, slackWriteback } from './slack-writeback.js';
|
|
9
9
|
import { invokeHelper, type HelperCall } from './yaml-helpers.js';
|
|
10
10
|
import { withWorkerLease } from './worker-lease.js';
|
|
11
|
+
import { NO_MODEL_COST } from './reported-cost.js';
|
|
11
12
|
|
|
12
13
|
export function helperMount(provider: string, env = process.env): string | undefined {
|
|
13
14
|
const root = [env.RELAYFILE_MOUNT_PATH, env.WORKSPACE_ROOT, env.WORKFORCE_SANDBOX_ROOT,
|
|
@@ -73,6 +74,6 @@ export async function completeHelperDispatch(
|
|
|
73
74
|
return { ...call, idempotencyKey: `${dispatch.run_id}:${dispatch.step_id}`, receipt };
|
|
74
75
|
});
|
|
75
76
|
await client.stepComplete(dispatch.run_id, dispatch.step_id, dispatch.attempt,
|
|
76
|
-
dispatch.idempotency_key, 'success', { output, started_pins: dispatch.pins, end_pins: dispatch.pins,
|
|
77
|
+
dispatch.idempotency_key, 'success', { output, started_pins: dispatch.pins, end_pins: dispatch.pins, reported_cost: NO_MODEL_COST,
|
|
77
78
|
effects: [{ surface_path: surfacePath, idempotency_key: dispatch.idempotency_key }] });
|
|
78
79
|
}
|
package/src/yaml-helpers.ts
CHANGED
|
@@ -3,6 +3,7 @@ import { githubClient, linearClient, slackClient, type RelayTransport } from '@r
|
|
|
3
3
|
import type { AgentStepSpec, KernelAgentStep, YamlHelperParams } from './spec.js';
|
|
4
4
|
import { canonicalize } from './canonical.js';
|
|
5
5
|
import { unknownKeyErrors } from './unknown-keys.js';
|
|
6
|
+
import { HELPER_INSTRUCTION_PREFIX } from './helper-instruction.js';
|
|
6
7
|
|
|
7
8
|
const string = { type: 'string', minLength: 1 };
|
|
8
9
|
const text = { type: 'string' };
|
|
@@ -61,7 +62,7 @@ export type HelperCall = { [P in keyof YamlHelperParams]: { [V in keyof YamlHelp
|
|
|
61
62
|
{ type: 'effect'; provider: P; verb: V; params: YamlHelperParams[P][V] }
|
|
62
63
|
}[keyof YamlHelperParams[P]] }[keyof YamlHelperParams];
|
|
63
64
|
|
|
64
|
-
const prefix =
|
|
65
|
+
const prefix = HELPER_INSTRUCTION_PREFIX;
|
|
65
66
|
const commonFields = ['id', 'dependsOn', 'maxIterations', 'verification', 'output'] as const;
|
|
66
67
|
const isObject = (value: unknown): value is Record<string, unknown> =>
|
|
67
68
|
value !== null && typeof value === 'object' && !Array.isArray(value);
|