@clemrig/flow 0.2.0 → 0.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.
Files changed (44) hide show
  1. package/README.md +6 -4
  2. package/dist/app/run.js +5 -1
  3. package/dist/app/run.js.map +1 -1
  4. package/dist/app/runs.d.ts +1 -1
  5. package/dist/app/runs.js +4 -5
  6. package/dist/app/runs.js.map +1 -1
  7. package/dist/engine/metrics.d.ts +17 -10
  8. package/dist/engine/metrics.js +29 -15
  9. package/dist/engine/metrics.js.map +1 -1
  10. package/dist/engine/profiles.d.ts +44 -11
  11. package/dist/engine/profiles.js +78 -78
  12. package/dist/engine/profiles.js.map +1 -1
  13. package/dist/engine/types.d.ts +10 -1
  14. package/dist/engine/workflow.d.ts +8 -3
  15. package/dist/engine/workflow.js +58 -3
  16. package/dist/engine/workflow.js.map +1 -1
  17. package/dist/index.d.ts +3 -3
  18. package/dist/index.js +2 -2
  19. package/dist/index.js.map +1 -1
  20. package/dist/system/process.d.ts +28 -6
  21. package/dist/system/process.js +24 -5
  22. package/dist/system/process.js.map +1 -1
  23. package/dist/system/runtimes/adapter.d.ts +21 -11
  24. package/dist/system/runtimes/adapter.js.map +1 -1
  25. package/dist/system/runtimes/agent-runtime.d.ts +3 -1
  26. package/dist/system/runtimes/agent-runtime.js +76 -87
  27. package/dist/system/runtimes/agent-runtime.js.map +1 -1
  28. package/dist/system/runtimes/claude-code.d.ts +5 -4
  29. package/dist/system/runtimes/claude-code.js +39 -84
  30. package/dist/system/runtimes/claude-code.js.map +1 -1
  31. package/dist/system/runtimes/codex.d.ts +11 -0
  32. package/dist/system/runtimes/codex.js +253 -0
  33. package/dist/system/runtimes/codex.js.map +1 -0
  34. package/dist/system/runtimes/inspect.js +7 -5
  35. package/dist/system/runtimes/inspect.js.map +1 -1
  36. package/dist/system/runtimes/pi.d.ts +3 -1
  37. package/dist/system/runtimes/pi.js +22 -10
  38. package/dist/system/runtimes/pi.js.map +1 -1
  39. package/dist/system/runtimes/registry.d.ts +3 -2
  40. package/dist/system/runtimes/registry.js +6 -1
  41. package/dist/system/runtimes/registry.js.map +1 -1
  42. package/dist/system/store.js +6 -2
  43. package/dist/system/store.js.map +1 -1
  44. package/package.json +2 -2
package/README.md CHANGED
@@ -1,12 +1,12 @@
1
1
  # @clemrig/flow
2
2
 
3
- Write agent workflows in TypeScript and run them with [Claude Code](https://code.claude.com) or [Pi](https://www.npmjs.com/package/@earendil-works/pi-coding-agent).
3
+ Write agent workflows in TypeScript and run them with [Claude Code](https://code.claude.com), [Codex](https://developers.openai.com/codex) or [Pi](https://www.npmjs.com/package/@earendil-works/pi-coding-agent).
4
4
 
5
- A workflow is an explicit graph of **CODE** stages (your code), **AGENT** stages (an agent run by Claude Code or Pi) and **GATE** stages that accept a result or send it back for correction, a bounded number of times. This package is the engine: the API to write workflows, their execution, the agent runtimes and the runs. [`@clemrig/factory`](https://www.npmjs.com/package/@clemrig/factory) builds a command and per-repository workflows on it; [`@clemrig/flow-ui`](https://www.npmjs.com/package/@clemrig/flow-ui) shows the runs in a local dashboard.
5
+ A workflow is an explicit graph of **CODE** stages (your code), **AGENT** stages (an agent run by Claude Code, Codex or Pi) and **GATE** stages that accept a result or send it back for correction, a bounded number of times. This package is the engine: the API to write workflows, their execution, the agent runtimes and the runs. [`@clemrig/factory`](https://www.npmjs.com/package/@clemrig/factory) builds on it a command that takes a repository's issues from spec to pull request, beside the repository's own workflows; [`@clemrig/flow-ui`](https://www.npmjs.com/package/@clemrig/flow-ui) shows the runs in a local dashboard.
6
6
 
7
7
  ## Requirements
8
8
 
9
- macOS or Linux, Node.js 24 or later. For agent stages, the `claude` CLI (2.1.296 or later) or the `pi` CLI (1.1.0 or later) in the `PATH`, connected to its provider. The engine never reads or stores credentials.
9
+ macOS or Linux, Node.js 24 or later. For agent stages, the `claude` CLI (2.1.296 or later), the `codex` CLI (0.160.1 or later, in a Git repository) or the `pi` CLI (1.1.0 or later) in the `PATH`, connected to its provider. Each agent runs with the machine's own configuration of its CLI, plus its profile's settings. The engine never reads or stores credentials.
10
10
 
11
11
  ## Run a workflow
12
12
 
@@ -43,7 +43,9 @@ const state = await run.done;
43
43
  console.log(state.status, state.data);
44
44
  ```
45
45
 
46
- Before it creates the run, `startRun` checks, in this order, `dir` (an existing directory), the budget (`maxCostUsd`, in USD, replaces the workflow's), the input against the workflow's `input` (an `InvalidInputError` lists every problem), the prompts (a non-empty text for each agent stage's prompt) and each runtime the workflow uses, its version and connection checked in `dir`; the first failing check rejects it with its reasons. It then returns the run, its end (`done`) and `stop(reason)`, which fails the run before its next stage. Runs are kept in `runsDir` when it is given. The engine never changes the process's current directory: stage code reaches the working directory through `dir`. While child processes run (agents, commands), a SIGINT or SIGTERM to the program interrupts them, so that none outlives it, and stops each run before its next stage, even if a stage catches the interruption. A program about to quit at once can call `killChildProcesses()`, which kills the child processes of every run.
46
+ A workflow may declare `steps`: ordered groups of its stages that show how far a run went, for instance `steps: [{ name: "greet", stages: ["greet"] }]`. `defineWorkflow` refuses steps unless they name each step once and hold each stage exactly once; the engine itself ignores them, and the factory's Kanban shows them.
47
+
48
+ Before it creates the run, `startRun` checks, in this order, `dir` (an existing directory), the budget (`maxCostUsd`, in USD, replaces the workflow's; refused when an agent stage uses Codex, which announces no cost), the input against the workflow's `input` (an `InvalidInputError` lists every problem), the prompts (a non-empty text for each agent stage's prompt) and each runtime the workflow uses, its version and connection checked in `dir`; the first failing check rejects it with its reasons. It then returns the run, its end (`done`) and `stop(reason)`, which fails the run before its next stage. Runs are kept in `runsDir` when it is given. The engine never changes the process's current directory: stage code reaches the working directory through `dir`. While child processes run (agents, commands), a SIGINT or SIGTERM to the program interrupts them, each agent with the signal on which it ends its own commands, so that none outlives it, and stops each run before its next stage, even if a stage catches the interruption. A program about to quit at once can call `killChildProcesses()`, which kills the child processes of every run, but not the commands Codex runs in their own process groups.
47
49
 
48
50
  The stages, gates, corrections, agent profiles, sessions and prompts are described in the "Write a workflow" section of [`@clemrig/factory`'s README](https://www.npmjs.com/package/@clemrig/factory); import them from `@clemrig/flow` here. What it says of `.factory/`, prompt files and `factory run` options belongs to the factory: with the engine alone, the program gives the input, the prompt texts and the directories to `startRun`.
49
51
 
package/dist/app/run.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { budgetProblem, emptyMetrics, recordUsage } from "../engine/metrics.js";
2
2
  import { executeWorkflow } from "../engine/runner.js";
3
- import { parseInput } from "../engine/workflow.js";
3
+ import { budgetRefusal, parseInput } from "../engine/workflow.js";
4
4
  import { whenInterrupted } from "../system/process.js";
5
5
  import { AgentRuntime } from "../system/runtimes/agent-runtime.js";
6
6
  import { inspectRuntimes, } from "../system/runtimes/inspect.js";
@@ -18,6 +18,10 @@ export async function startRun(setup, hooks) {
18
18
  if (setup.maxCostUsd !== undefined &&
19
19
  !(Number.isFinite(setup.maxCostUsd) && setup.maxCostUsd > 0))
20
20
  throw new Error(`maxCostUsd must be a positive number of USD, got ${typeof setup.maxCostUsd === "string" ? JSON.stringify(setup.maxCostUsd) : String(setup.maxCostUsd)}`);
21
+ // The budget in force, the run's or the workflow's, whoever built the workflow.
22
+ const unbudgetable = maxCostUsd === undefined ? undefined : budgetRefusal(workflow.agents);
23
+ if (unbudgetable)
24
+ throw new Error(unbudgetable);
21
25
  const input = parseInput(workflow, setup.input ?? {});
22
26
  const prompts = await setup.prompts();
23
27
  const unprompted = [
@@ -1 +1 @@
1
- {"version":3,"file":"run.js","sourceRoot":"","sources":["../../src/app/run.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"run.js","sourceRoot":"","sources":["../../src/app/run.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAChF,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAOtD,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAClE,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,EAAE,YAAY,EAAE,MAAM,qCAAqC,CAAC;AACnE,OAAO,EACL,eAAe,GAEhB,MAAM,+BAA+B,CAAC;AACvC,OAAO,EACL,mBAAmB,EACnB,cAAc,EACd,YAAY,EACZ,WAAW,EACX,QAAQ,GACT,MAAM,oBAAoB,CAAC;AAmC5B;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,QAAQ,CAC5B,KAAe,EACf,KAAe;IAEf,MAAM,EAAE,QAAQ,EAAE,GAAG,EAAE,SAAS,EAAE,GAAG,KAAK,CAAC;IAC3C,IAAI,CAAC,CAAC,MAAM,WAAW,CAAC,GAAG,CAAC,CAAC;QAC3B,MAAM,IAAI,KAAK,CAAC,qCAAqC,GAAG,EAAE,CAAC,CAAC;IAC9D,MAAM,UAAU,GAAG,KAAK,CAAC,UAAU,IAAI,QAAQ,CAAC,UAAU,CAAC;IAC3D,IACE,KAAK,CAAC,UAAU,KAAK,SAAS;QAC9B,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,UAAU,CAAC,IAAI,KAAK,CAAC,UAAU,GAAG,CAAC,CAAC;QAE5D,MAAM,IAAI,KAAK,CACb,oDAAoD,OAAO,KAAK,CAAC,UAAU,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,EAAE,CACzJ,CAAC;IACJ,gFAAgF;IAChF,MAAM,YAAY,GAChB,UAAU,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,aAAa,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;IACxE,IAAI,YAAY;QAAE,MAAM,IAAI,KAAK,CAAC,YAAY,CAAC,CAAC;IAChD,MAAM,KAAK,GAAG,UAAU,CAAC,QAAQ,EAAE,KAAK,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC;IACtD,MAAM,OAAO,GAAG,MAAM,KAAK,CAAC,OAAO,EAAE,CAAC;IACtC,MAAM,UAAU,GAAG;QACjB,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC;KACvE,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,IAAI,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;IAC7E,IAAI,UAAU,CAAC,MAAM;QACnB,MAAM,IAAI,KAAK,CACb,UAAU,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,4BAA4B,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CACxE,CAAC;IACJ,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,WAAW,EAAE,GAAG,MAAM,eAAe,CAC/D,QAAQ,CAAC,MAAM,EACf,GAAG,CACJ,CAAC;IACF,IAAI,QAAQ,CAAC,MAAM;QACjB,MAAM,IAAI,KAAK,CACb,0BAA0B,QAAQ,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,SAAS,KAAK,KAAK,OAAO,MAAM,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAC9H,CAAC;IACJ,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IACrC,MAAM,KAAK,GAAa;QACtB,OAAO,EAAE,CAAC;QACV,EAAE,EAAE,QAAQ,EAAE;QACd,QAAQ,EAAE,QAAQ,CAAC,IAAI;QACvB,KAAK;QACL,KAAK,EAAE,QAAQ,CAAC,OAAO;QACvB,MAAM,EAAE,SAAS;QACjB,IAAI,EAAE,EAAE;QACR,SAAS,EAAE,GAAG;QACd,SAAS,EAAE,GAAG;QACd,OAAO,EAAE,YAAY,EAAE;QACvB,QAAQ,EAAE,MAAM,CAAC,WAAW,CAC1B,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,EAAE,EAAE,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YACtD,OAAO;YACP,MAAM;SACP,CAAC,CACH;KACF,CAAC;IACF,IAAI,KAAK,CAAC,OAAO,KAAK,SAAS;QAAE,MAAM,mBAAmB,CAAC,GAAG,CAAC,CAAC;SAC3D,IAAI,CAAC,MAAM,WAAW,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,KAAK,KAAK;QACnD,MAAM,IAAI,KAAK,CAAC,+BAA+B,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;IAClE,MAAM,KAAK,GAAG,IAAI,YAAY,CAC5B,KAAK,CAAC,OAAO,IAAI,cAAc,CAAC,GAAG,CAAC,EACpC,KAAK,CAAC,EAAE,CACT,CAAC;IACF,MAAM,KAAK,GAAG,IAAI,YAAY,CAAC;QAC7B,GAAG;QACH,SAAS;QACT,OAAO;QACP,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE;YACxB,IAAI,KAAK,CAAC,OAAO;gBAAE,WAAW,CAAC,KAAK,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;YACtD,MAAM,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC1B,CAAC;QACD,GAAG,EAAE,EAAE,EAAE,EAAE,KAAK,CAAC,EAAE,EAAE,SAAS,EAAE,KAAK,CAAC,SAAS,EAAE;QACjD,WAAW;KACZ,CAAC,CAAC;IACH,MAAM,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACxB,MAAM,UAAU,GAAG,IAAI,eAAe,EAAE,CAAC;IACzC;;;OAGG;IACH,MAAM,UAAU,GAAG,GAAG,EAAE;QACtB,MAAM,OAAO,GACX,UAAU,KAAK,SAAS,IAAI,CAAC,KAAK,CAAC,OAAO;YACxC,CAAC,CAAC,SAAS;YACX,CAAC,CAAC,aAAa,CAAC,KAAK,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC;QAC/C,IAAI,OAAO;YAAE,UAAU,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC;QAClD,OAAO,OAAO,CAAC;IACjB,CAAC,CAAC;IACF,oGAAoG;IACpG,MAAM,QAAQ,GAAc;QAC1B,KAAK,CAAC,OAAO,CAAC,OAAO,EAAE,MAAM;YAC3B,MAAM,OAAO,GAAG,UAAU,EAAE,CAAC;YAC7B,IAAI,OAAO;gBAAE,MAAM,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC;YACtC,MAAM,KAAK,GAAG,MAAM,KAAK;iBACtB,OAAO,CAAC,OAAO,EAAE,MAAM,CAAC;iBACxB,OAAO,CAAC,GAAG,EAAE,CAAC,UAAU,EAAE,CAAC,CAAC;YAC/B,MAAM,QAAQ,GAAG,UAAU,EAAE,CAAC;YAC9B,IAAI,QAAQ;gBAAE,MAAM,IAAI,KAAK,CAAC,QAAQ,CAAC,CAAC;YACxC,OAAO,KAAK,CAAC;QACf,CAAC;KACF,CAAC;IACF,yGAAyG;IACzG,MAAM,OAAO,GAAG,eAAe,CAAC,CAAC,MAAM,EAAE,EAAE,CACzC,UAAU,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,sBAAsB,MAAM,EAAE,CAAC,CAAC,CAC5D,CAAC;IACF,MAAM,IAAI,GAAG,eAAe,CAC1B,QAAQ,EACR,KAAK,EACL,EAAE,KAAK,EAAE,QAAQ,EAAE,GAAG,EAAE,EACxB,KAAK,EACL,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,CAAC,MAAM,EAAE,CACtD,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;IACnB,OAAO;QACL,KAAK;QACL,QAAQ,EAAE,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC;QACjC,IAAI;QACJ,IAAI,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,UAAU,CAAC,KAAK,CAAC,MAAM,CAAC;KAC3C,CAAC;AACJ,CAAC"}
@@ -17,7 +17,7 @@ export declare function summarizeRun(state: RunState): {
17
17
  stage: string;
18
18
  durationMs: number | null;
19
19
  costUsd: number | null;
20
- /** Some agent call announced no usage. */
20
+ /** Some agent call announced no cost. */
21
21
  partial: boolean;
22
22
  updatedAt: string;
23
23
  };
package/dist/app/runs.js CHANGED
@@ -1,4 +1,4 @@
1
- import { elapsedMs } from "../engine/metrics.js";
1
+ import { knownCost, elapsedMs } from "../engine/metrics.js";
2
2
  import { presentData } from "../engine/workflow.js";
3
3
  import { FileRunStore } from "../system/store.js";
4
4
  const message = (error) => error instanceof Error ? error.message : String(error);
@@ -19,16 +19,15 @@ export async function listRuns(runsDir) {
19
19
  }
20
20
  /** A run as a list shows it; a cost no agent announced is unknown (`null`), not zero. */
21
21
  export function summarizeRun(state) {
22
- const usage = state.metrics?.usage;
23
22
  return {
24
23
  id: state.id,
25
24
  workflow: state.workflow,
26
25
  status: state.status,
27
26
  stage: state.stage,
28
27
  durationMs: elapsedMs(state),
29
- costUsd: usage?.responses ? usage.costUsd : null,
30
- /** Some agent call announced no usage. */
31
- partial: Boolean(usage?.missing),
28
+ costUsd: knownCost(state.metrics),
29
+ /** Some agent call announced no cost. */
30
+ partial: Boolean(state.metrics?.usage.missing),
32
31
  updatedAt: state.updatedAt,
33
32
  };
34
33
  }
@@ -1 +1 @@
1
- {"version":3,"file":"runs.js","sourceRoot":"","sources":["../../src/app/runs.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"runs.js","sourceRoot":"","sources":["../../src/app/runs.ts"],"names":[],"mappings":"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"}
@@ -1,44 +1,51 @@
1
1
  import type { RunState } from "./types.js";
2
- /** Tokens of a model response or of an agent call. */
2
+ /** Tokens of a model response or of an agent call; `input` counts those read without the cache. */
3
3
  export interface TokenCounts {
4
4
  input: number;
5
5
  output: number;
6
6
  cacheRead: number;
7
7
  cacheWrite: number;
8
8
  }
9
- /** Tokens and the runtime's estimated cost. */
9
+ /** Tokens and the runtime's estimated cost, absent when the runtime announces none (Codex). */
10
10
  export interface AgentUsage extends TokenCounts {
11
- costUsd: number;
11
+ costUsd?: number;
12
12
  }
13
13
  export interface RunMetrics {
14
- /** The run's total, the sum of its sessions; `responses` counts measured reports, `missing` unmeasured ones. */
15
- usage: AgentUsage & {
14
+ /**
15
+ * The run's total, the sum of its sessions, with the cost they announced;
16
+ * `responses` counts measured reports, `missing` those without a cost.
17
+ */
18
+ usage: TokenCounts & {
19
+ costUsd: number;
16
20
  responses: number;
17
21
  missing: number;
18
22
  };
19
23
  /**
20
24
  * Per agent session, `<runtime>:<session>`: the latest total its runtime
21
- * announced (Claude Code), or the sum of its responses (Pi). Absent from runs
22
- * recorded before it existed.
25
+ * announced (Claude Code, Codex), or the sum of its responses (Pi). Absent
26
+ * from runs recorded before it existed.
23
27
  */
24
28
  sessions?: Record<string, AgentUsage>;
25
29
  }
26
- /** A measure as the runtime reports it: one response (Pi), or its session's total so far (Claude Code). */
30
+ /** A measure as the runtime reports it: one response (Pi), or its session's total so far (Claude Code, Codex). */
27
31
  export interface UsageReport {
28
32
  session: string;
29
33
  scope: "response" | "session";
30
34
  /** `undefined` when the runtime reported nothing measurable. */
31
35
  usage: AgentUsage | undefined;
32
36
  }
33
- /** Tokens and cost of several measures together. */
37
+ /** Tokens of several measures together, and their cost when each announced one. */
34
38
  export declare function sumUsage(measures: AgentUsage[]): AgentUsage;
35
39
  export declare function emptyMetrics(): RunMetrics;
36
40
  /**
37
41
  * Records a measure as its runtime reports it: a session total replaces the
38
42
  * previous one, a response adds to its session. The run's total is the sum of
39
- * its sessions; nothing else is computed.
43
+ * its sessions, with the cost they announced; nothing else is computed. A
44
+ * measure without a cost leaves the run's cost partial.
40
45
  */
41
46
  export declare function recordUsage(metrics: RunMetrics, report: UsageReport): void;
47
+ /** The cost the run's agents announced; `null` while none announced any. */
48
+ export declare function knownCost(metrics: RunMetrics | undefined): number | null;
42
49
  /** Why a run past its budget must stop: its announced cost exceeds it, or a call announced none. */
43
50
  export declare function budgetProblem(metrics: RunMetrics, maxCostUsd: number): string | undefined;
44
51
  /** From creation to now while running, to the last update once completed or failed. */
@@ -1,32 +1,31 @@
1
- const fields = [
2
- "input",
3
- "output",
4
- "cacheRead",
5
- "cacheWrite",
6
- "costUsd",
7
- ];
8
- const noUsage = () => ({
1
+ const tokenFields = ["input", "output", "cacheRead", "cacheWrite"];
2
+ const noTokens = () => ({
9
3
  input: 0,
10
4
  output: 0,
11
5
  cacheRead: 0,
12
6
  cacheWrite: 0,
13
- costUsd: 0,
14
7
  });
15
- /** Tokens and cost of several measures together. */
8
+ /** Tokens of several measures together, and their cost when each announced one. */
16
9
  export function sumUsage(measures) {
17
- const total = noUsage();
10
+ const total = noTokens();
18
11
  for (const measure of measures)
19
- for (const field of fields)
12
+ for (const field of tokenFields)
20
13
  total[field] += measure[field];
14
+ if (measures.every(({ costUsd }) => costUsd !== undefined))
15
+ total.costUsd = measures.reduce((sum, { costUsd }) => sum + (costUsd ?? 0), 0);
21
16
  return total;
22
17
  }
23
18
  export function emptyMetrics() {
24
- return { usage: { ...noUsage(), responses: 0, missing: 0 }, sessions: {} };
19
+ return {
20
+ usage: { ...noTokens(), costUsd: 0, responses: 0, missing: 0 },
21
+ sessions: {},
22
+ };
25
23
  }
26
24
  /**
27
25
  * Records a measure as its runtime reports it: a session total replaces the
28
26
  * previous one, a response adds to its session. The run's total is the sum of
29
- * its sessions; nothing else is computed.
27
+ * its sessions, with the cost they announced; nothing else is computed. A
28
+ * measure without a cost leaves the run's cost partial.
30
29
  */
31
30
  export function recordUsage(metrics, report) {
32
31
  if (!report.usage) {
@@ -34,6 +33,8 @@ export function recordUsage(metrics, report) {
34
33
  return;
35
34
  }
36
35
  metrics.usage.responses++;
36
+ if (report.usage.costUsd === undefined)
37
+ metrics.usage.missing++;
37
38
  metrics.sessions ??= {};
38
39
  const { sessions } = metrics;
39
40
  const previous = sessions[report.session];
@@ -41,7 +42,20 @@ export function recordUsage(metrics, report) {
41
42
  report.scope === "session" || !previous
42
43
  ? report.usage
43
44
  : sumUsage([previous, report.usage]);
44
- Object.assign(metrics.usage, sumUsage(Object.values(sessions)));
45
+ const measures = Object.values(sessions);
46
+ for (const field of tokenFields)
47
+ metrics.usage[field] = measures.reduce((sum, measure) => sum + measure[field], 0);
48
+ metrics.usage.costUsd = measures.reduce((sum, { costUsd }) => sum + (costUsd ?? 0), 0);
49
+ }
50
+ /** The cost the run's agents announced; `null` while none announced any. */
51
+ export function knownCost(metrics) {
52
+ if (!metrics)
53
+ return null;
54
+ // Runs recorded before sessions were kept measured every response with its cost.
55
+ const priced = metrics.sessions
56
+ ? Object.values(metrics.sessions).some(({ costUsd }) => costUsd !== undefined)
57
+ : metrics.usage.responses > 0;
58
+ return priced ? metrics.usage.costUsd : null;
45
59
  }
46
60
  /** Why a run past its budget must stop: its announced cost exceeds it, or a call announced none. */
47
61
  export function budgetProblem(metrics, maxCostUsd) {
@@ -1 +1 @@
1
- {"version":3,"file":"metrics.js","sourceRoot":"","sources":["../../src/engine/metrics.ts"],"names":[],"mappings":"AAqCA,MAAM,MAAM,GAAG;IACb,OAAO;IACP,QAAQ;IACR,WAAW;IACX,YAAY;IACZ,SAAS;CACD,CAAC;AAEX,MAAM,OAAO,GAAG,GAAe,EAAE,CAAC,CAAC;IACjC,KAAK,EAAE,CAAC;IACR,MAAM,EAAE,CAAC;IACT,SAAS,EAAE,CAAC;IACZ,UAAU,EAAE,CAAC;IACb,OAAO,EAAE,CAAC;CACX,CAAC,CAAC;AAEH,oDAAoD;AACpD,MAAM,UAAU,QAAQ,CAAC,QAAsB;IAC7C,MAAM,KAAK,GAAG,OAAO,EAAE,CAAC;IACxB,KAAK,MAAM,OAAO,IAAI,QAAQ;QAC5B,KAAK,MAAM,KAAK,IAAI,MAAM;YAAE,KAAK,CAAC,KAAK,CAAC,IAAI,OAAO,CAAC,KAAK,CAAC,CAAC;IAC7D,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,UAAU,YAAY;IAC1B,OAAO,EAAE,KAAK,EAAE,EAAE,GAAG,OAAO,EAAE,EAAE,SAAS,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC;AAC7E,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,WAAW,CAAC,OAAmB,EAAE,MAAmB;IAClE,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;QAClB,OAAO,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC;QACxB,OAAO;IACT,CAAC;IACD,OAAO,CAAC,KAAK,CAAC,SAAS,EAAE,CAAC;IAC1B,OAAO,CAAC,QAAQ,KAAK,EAAE,CAAC;IACxB,MAAM,EAAE,QAAQ,EAAE,GAAG,OAAO,CAAC;IAC7B,MAAM,QAAQ,GAAG,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IAC1C,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC;QACtB,MAAM,CAAC,KAAK,KAAK,SAAS,IAAI,CAAC,QAAQ;YACrC,CAAC,CAAC,MAAM,CAAC,KAAK;YACd,CAAC,CAAC,QAAQ,CAAC,CAAC,QAAQ,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;IACzC,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;AAClE,CAAC;AAED,oGAAoG;AACpG,MAAM,UAAU,aAAa,CAC3B,OAAmB,EACnB,UAAkB;IAElB,IAAI,OAAO,CAAC,KAAK,CAAC,OAAO;QACvB,OAAO,aAAa,UAAU,yDAAyD,CAAC;IAC1F,IAAI,OAAO,CAAC,KAAK,CAAC,OAAO,GAAG,UAAU;QACpC,OAAO,oBAAoB,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,uBAAuB,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC;IAChH,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,uFAAuF;AACvF,MAAM,UAAU,SAAS,CAAC,KAAe,EAAE,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE;IACzD,MAAM,GAAG,GAAG,KAAK,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;IAC3E,MAAM,OAAO,GAAG,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;IAClD,OAAO,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,OAAO,IAAI,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC;AACnE,CAAC"}
1
+ {"version":3,"file":"metrics.js","sourceRoot":"","sources":["../../src/engine/metrics.ts"],"names":[],"mappings":"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"}
@@ -1,11 +1,7 @@
1
1
  import { z } from "zod";
2
- /** An agent stage's runtime, settings and access, declared in full by its workflow. */
2
+ /** An agent stage's runtime and settings, declared by its workflow. */
3
3
  export declare const profileSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
4
4
  runtime: z.ZodLiteral<"pi">;
5
- access: z.ZodDefault<z.ZodEnum<{
6
- read: "read";
7
- write: "write";
8
- }>>;
9
5
  provider: z.ZodString;
10
6
  model: z.ZodString;
11
7
  thinking: z.ZodEnum<{
@@ -17,16 +13,12 @@ export declare const profileSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
17
13
  off: "off";
18
14
  xhigh: "xhigh";
19
15
  }>;
20
- tools: z.ZodArray<z.ZodString>;
16
+ tools: z.ZodOptional<z.ZodArray<z.ZodString>>;
21
17
  skills: z.ZodDefault<z.ZodArray<z.ZodString>>;
22
18
  extensions: z.ZodDefault<z.ZodArray<z.ZodString>>;
23
19
  timeoutMs: z.ZodDefault<z.ZodNumber>;
24
20
  }, z.core.$strict>, z.ZodObject<{
25
21
  runtime: z.ZodLiteral<"claude-code">;
26
- access: z.ZodDefault<z.ZodEnum<{
27
- read: "read";
28
- write: "write";
29
- }>>;
30
22
  model: z.ZodString;
31
23
  thinking: z.ZodEnum<{
32
24
  high: "high";
@@ -35,19 +27,60 @@ export declare const profileSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
35
27
  medium: "medium";
36
28
  xhigh: "xhigh";
37
29
  }>;
38
- tools: z.ZodArray<z.ZodString>;
30
+ tools: z.ZodOptional<z.ZodArray<z.ZodString>>;
31
+ permissionMode: z.ZodOptional<z.ZodEnum<{
32
+ acceptEdits: "acceptEdits";
33
+ auto: "auto";
34
+ bypassPermissions: "bypassPermissions";
35
+ dontAsk: "dontAsk";
36
+ manual: "manual";
37
+ plan: "plan";
38
+ }>>;
39
39
  mcpServers: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodObject<{
40
40
  command: z.ZodString;
41
41
  args: z.ZodDefault<z.ZodArray<z.ZodString>>;
42
42
  }, z.core.$strict>>>;
43
43
  timeoutMs: z.ZodDefault<z.ZodNumber>;
44
+ }, z.core.$strict>, z.ZodObject<{
45
+ runtime: z.ZodLiteral<"codex">;
46
+ model: z.ZodString;
47
+ thinking: z.ZodString;
48
+ sandbox: z.ZodOptional<z.ZodEnum<{
49
+ "danger-full-access": "danger-full-access";
50
+ "read-only": "read-only";
51
+ "workspace-write": "workspace-write";
52
+ }>>;
53
+ timeoutMs: z.ZodDefault<z.ZodNumber>;
44
54
  }, z.core.$strict>], "runtime">;
45
55
  /** A profile as a workflow declares it. */
46
56
  export type AgentProfile = z.input<typeof profileSchema>;
47
57
  /** A profile with its defaults applied. */
48
58
  export type ResolvedProfile = z.output<typeof profileSchema>;
49
59
  export type Runtime = ResolvedProfile["runtime"];
60
+ /** A runtime's profile, with its defaults applied. */
61
+ export type ProfileOf<R extends Runtime> = Extract<ResolvedProfile, {
62
+ runtime: R;
63
+ }>;
50
64
  /** Each runtime's name as the operator reads it. */
51
65
  export declare const runtimeLabels: Record<Runtime, string>;
66
+ /** Whether a runtime announces the cost of its calls: Codex announces tokens only. */
67
+ export declare const announcesCost: Record<Runtime, boolean>;
68
+ /**
69
+ * Every problem of a profile, without defining a workflow: each with the path
70
+ * of its field (empty for the profile itself).
71
+ */
72
+ export declare function profileProblems(profile: unknown): {
73
+ path: string;
74
+ message: string;
75
+ }[];
52
76
  /** The profile with its defaults applied; an invalid profile is refused with its problems. */
53
77
  export declare function resolveProfile(profile: AgentProfile): ResolvedProfile;
78
+ /**
79
+ * What an agent call records of its profile besides its runtime and model, which
80
+ * names Pi's provider: MCP servers by name, so that their commands stay in the workflow.
81
+ */
82
+ export type AgentSettings = Omit<ProfileOf<"pi">, "runtime" | "provider" | "model"> | (Omit<ProfileOf<"claude-code">, "runtime" | "model" | "mcpServers"> & {
83
+ mcpServers: string[];
84
+ }) | Omit<ProfileOf<"codex">, "runtime" | "model">;
85
+ /** The settings a call records of its profile. */
86
+ export declare function agentSettings(profile: ResolvedProfile): AgentSettings;
@@ -1,77 +1,52 @@
1
1
  import { z } from "zod";
2
- /** Pi native tools; any other tool name must come from an explicitly trusted extension. */
3
- const piBuiltinTools = new Set([
4
- "read",
5
- "bash",
6
- "powershell",
7
- "edit",
8
- "write",
9
- "grep",
10
- "find",
11
- "ls",
12
- ]);
13
- /** Pi native tools that can change files or run commands. */
14
- const piWriteTools = new Set(["bash", "powershell", "edit", "write"]);
2
+ const timeoutMs = z.number().int().min(1000).max(7_200_000).default(900_000);
15
3
  /**
16
- * The only Claude Code tools a read-only profile may use. Its native set grows with
17
- * each version (worktrees, monitors, schedules…), so anything else is refused.
4
+ * Pi, with the provider whose connection it uses. Without `tools`, Pi keeps its
5
+ * default tools; extensions, skills and context files of the machine load as usual.
18
6
  */
19
- const claudeCodeReadTools = new Set([
20
- "Read",
21
- "Grep",
22
- "Glob",
23
- "WebFetch",
24
- "WebSearch",
25
- ]);
26
- const timeoutMs = z.number().int().min(1000).max(7_200_000).default(900_000);
27
- /** `read` by default; `write` allows tools that change files or run commands. */
28
- const access = z.enum(["read", "write"]).default("read");
29
- const piProfileSchema = z
30
- .strictObject({
7
+ const piProfileSchema = z.strictObject({
31
8
  runtime: z.literal("pi"),
32
- access,
33
9
  // No default: a profile names the provider whose connection it uses.
34
10
  provider: z.string().min(1),
35
11
  model: z.string().min(1),
36
- thinking: z.enum([
37
- "off",
38
- "minimal",
39
- "low",
40
- "medium",
41
- "high",
42
- "xhigh",
43
- "max",
44
- ]),
45
- // Exact names only: Pi allowlist patterns could accidentally grant mutation tools.
46
- tools: z.array(z.string().regex(/^[a-zA-Z][a-zA-Z0-9_-]*$/)),
12
+ thinking: z.enum(["off", "minimal", "low", "medium", "high", "xhigh", "max"]),
13
+ // Exact names only: Pi allowlist patterns would enable tools the profile does not name.
14
+ tools: z.array(z.string().regex(/^[a-zA-Z][a-zA-Z0-9_-]*$/)).optional(),
47
15
  skills: z.array(z.string().min(1)).default([]),
48
16
  extensions: z.array(z.string().min(1)).default([]),
49
17
  timeoutMs,
50
- })
51
- .refine((profile) => profile.extensions.length > 0 ||
52
- profile.tools.every((tool) => piBuiltinTools.has(tool)), {
53
- path: ["tools"],
54
- message: "Custom tools require explicitly trusted extensions",
55
18
  });
56
- const mcpTool = /^mcp__([a-zA-Z0-9][a-zA-Z0-9-]*)__[a-zA-Z0-9_-]+$/;
57
- /** The server a Claude Code MCP tool name (`mcp__<server>__<tool>`) belongs to. */
58
- function mcpToolServer(tool) {
59
- return mcpTool.exec(tool)?.[1];
60
- }
61
- const claudeCodeProfileSchema = z
62
- .strictObject({
19
+ /** A Claude Code MCP tool name: `mcp__<server>__<tool>`, the server's or the machine's. */
20
+ const mcpTool = /^mcp__[a-zA-Z0-9][a-zA-Z0-9_-]*__[a-zA-Z0-9_-]+$/;
21
+ /**
22
+ * Claude Code, with the machine's settings, plugins, MCP servers and memory as
23
+ * usual. `tools` limits its built-in tools and allows the listed ones to run;
24
+ * `mcpServers` adds servers to those of the machine.
25
+ */
26
+ const claudeCodeProfileSchema = z.strictObject({
63
27
  runtime: z.literal("claude-code"),
64
- access,
65
28
  model: z.string().min(1),
66
29
  /** Claude Code effort levels. */
67
30
  thinking: z.enum(["low", "medium", "high", "xhigh", "max"]),
68
31
  // Exact names only: rules such as Bash(git *) or "default" would change the tool set.
69
- tools: z.array(z
32
+ tools: z
33
+ .array(z
70
34
  .string()
71
- .refine((tool) => /^[A-Z][a-zA-Z0-9]*$/.test(tool) || mcpTool.test(tool))),
72
- // Without "_": `mcp__<server>__<tool>` names must split one way only.
35
+ .refine((tool) => /^[A-Z][a-zA-Z0-9]*$/.test(tool) || mcpTool.test(tool)))
36
+ .optional(),
37
+ /** The choices of `--permission-mode`; without it, the machine's settings decide. */
38
+ permissionMode: z
39
+ .enum([
40
+ "acceptEdits",
41
+ "auto",
42
+ "bypassPermissions",
43
+ "manual",
44
+ "dontAsk",
45
+ "plan",
46
+ ])
47
+ .optional(),
73
48
  mcpServers: z
74
- .record(z.string().regex(/^[a-zA-Z0-9][a-zA-Z0-9-]*$/),
49
+ .record(z.string().regex(/^[a-zA-Z0-9][a-zA-Z0-9_-]*$/),
75
50
  // No env: servers inherit the run's environment, so secrets stay out of workflows.
76
51
  z.strictObject({
77
52
  command: z.string().min(1),
@@ -79,34 +54,50 @@ const claudeCodeProfileSchema = z
79
54
  }))
80
55
  .default({}),
81
56
  timeoutMs,
82
- })
83
- .refine((profile) => profile.tools.every((tool) => {
84
- const server = mcpToolServer(tool);
85
- return (server === undefined || Object.hasOwn(profile.mcpServers, server));
86
- }), { path: ["tools"], message: "MCP tools require a declared server" });
87
- /** Tools a read-only profile must not have; tools of a declared MCP server are trusted like Pi extension tools. */
88
- function writeTools(profile) {
89
- return profile.tools.filter((tool) => profile.runtime === "pi"
90
- ? piWriteTools.has(tool)
91
- : !claudeCodeReadTools.has(tool) && mcpToolServer(tool) === undefined);
92
- }
93
- /** An agent stage's runtime, settings and access, declared in full by its workflow. */
94
- export const profileSchema = z
95
- .discriminatedUnion("runtime", [piProfileSchema, claudeCodeProfileSchema])
96
- .superRefine((profile, context) => {
97
- const refused = profile.access === "read" ? writeTools(profile) : [];
98
- if (refused.length)
99
- context.addIssue({
100
- code: "custom",
101
- path: ["tools"],
102
- message: `read-only profile must not include ${refused.join(", ")}; set access: "write" to allow it`,
103
- });
104
57
  });
58
+ /** Codex, with the machine's configuration, AGENTS.md files and skills as usual. */
59
+ const codexProfileSchema = z.strictObject({
60
+ runtime: z.literal("codex"),
61
+ model: z.string().min(1),
62
+ /** `model_reasoning_effort`: its values depend on the model (low, medium, high, xhigh…). */
63
+ thinking: z.string().regex(/^[a-z]+$/),
64
+ /** `sandbox_mode`; without it, the machine's configuration decides. */
65
+ sandbox: z
66
+ .enum(["read-only", "workspace-write", "danger-full-access"])
67
+ .optional(),
68
+ timeoutMs,
69
+ });
70
+ /** An agent stage's runtime and settings, declared by its workflow. */
71
+ export const profileSchema = z.discriminatedUnion("runtime", [
72
+ piProfileSchema,
73
+ claudeCodeProfileSchema,
74
+ codexProfileSchema,
75
+ ]);
105
76
  /** Each runtime's name as the operator reads it. */
106
77
  export const runtimeLabels = {
107
78
  "claude-code": "Claude Code",
79
+ codex: "Codex",
108
80
  pi: "Pi",
109
81
  };
82
+ /** Whether a runtime announces the cost of its calls: Codex announces tokens only. */
83
+ export const announcesCost = {
84
+ "claude-code": true,
85
+ codex: false,
86
+ pi: true,
87
+ };
88
+ /**
89
+ * Every problem of a profile, without defining a workflow: each with the path
90
+ * of its field (empty for the profile itself).
91
+ */
92
+ export function profileProblems(profile) {
93
+ const parsed = profileSchema.safeParse(profile);
94
+ return parsed.success
95
+ ? []
96
+ : parsed.error.issues.map(({ path, message }) => ({
97
+ path: path.map(String).join("."),
98
+ message,
99
+ }));
100
+ }
110
101
  /** The profile with its defaults applied; an invalid profile is refused with its problems. */
111
102
  export function resolveProfile(profile) {
112
103
  const parsed = profileSchema.safeParse(profile);
@@ -114,4 +105,13 @@ export function resolveProfile(profile) {
114
105
  throw new Error(`Invalid agent profile:\n${z.prettifyError(parsed.error)}`);
115
106
  return parsed.data;
116
107
  }
108
+ const settingsOf = {
109
+ pi: ({ runtime: _runtime, provider: _provider, model: _model, ...settings }) => settings,
110
+ "claude-code": ({ runtime: _runtime, model: _model, mcpServers, ...settings }) => ({ ...settings, mcpServers: Object.keys(mcpServers) }),
111
+ codex: ({ runtime: _runtime, model: _model, ...settings }) => settings,
112
+ };
113
+ /** The settings a call records of its profile. */
114
+ export function agentSettings(profile) {
115
+ return settingsOf[profile.runtime](profile);
116
+ }
117
117
  //# sourceMappingURL=profiles.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"profiles.js","sourceRoot":"","sources":["../../src/engine/profiles.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"profiles.js","sourceRoot":"","sources":["../../src/engine/profiles.ts"],"names":[],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  import type { z } from "zod";
2
2
  import type { AgentUsage, RunMetrics, TokenCounts } from "./metrics.js";
3
- import type { AgentProfile, ResolvedProfile, Runtime } from "./profiles.js";
3
+ import type { AgentProfile, AgentSettings, ResolvedProfile, Runtime } from "./profiles.js";
4
4
  export type StageKind = "AGENT" | "CODE" | "GATE";
5
5
  /** What an agent stage asks of the agent runtime. */
6
6
  export interface AgentRequest {
@@ -22,6 +22,8 @@ export type AgentActivity = {
22
22
  runtime: Runtime;
23
23
  model: string;
24
24
  session: string;
25
+ /** Absent from runs recorded before calls recorded their settings. */
26
+ settings?: AgentSettings;
25
27
  } | {
26
28
  kind: "call";
27
29
  status: "completed" | "failed";
@@ -141,9 +143,16 @@ export interface WorkflowDefinition {
141
143
  nodes: Record<string, WorkflowNode>;
142
144
  /** Fails a run once its agents' announced cost exceeds it, in USD; a run's own budget replaces it. */
143
145
  maxCostUsd?: number;
146
+ /** The run's progress as a reader sees it: ordered steps that together hold every stage once. */
147
+ steps?: WorkflowStep[];
144
148
  /** Result lines; by default the run's validated data as JSON. */
145
149
  presentResult?(state: Readonly<RunState>): string[];
146
150
  }
151
+ /** A named group of stages, shown as one step of a run's progress. */
152
+ export interface WorkflowStep {
153
+ name: string;
154
+ stages: string[];
155
+ }
147
156
  /** An agent stage as `defineWorkflow` resolves it. */
148
157
  export interface AgentStage {
149
158
  profile: ResolvedProfile;