pi-extensible-workflows 3.2.0 → 3.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 (47) hide show
  1. package/README.md +2 -31
  2. package/dist/src/agent-execution.d.ts +67 -9
  3. package/dist/src/agent-execution.js +385 -141
  4. package/dist/src/bundles.d.ts +53 -0
  5. package/dist/src/bundles.js +457 -0
  6. package/dist/src/cli.d.ts +3 -1
  7. package/dist/src/cli.js +156 -22
  8. package/dist/src/doctor-cleanup.js +68 -31
  9. package/dist/src/eval-capture-extension.js +16 -1
  10. package/dist/src/execution.d.ts +1 -1
  11. package/dist/src/execution.js +29 -13
  12. package/dist/src/host.d.ts +12 -9
  13. package/dist/src/host.js +525 -195
  14. package/dist/src/index.d.ts +5 -4
  15. package/dist/src/index.js +3 -2
  16. package/dist/src/persistence.d.ts +43 -8
  17. package/dist/src/persistence.js +54 -0
  18. package/dist/src/registry.d.ts +3 -2
  19. package/dist/src/registry.js +16 -4
  20. package/dist/src/session-inspector.d.ts +12 -2
  21. package/dist/src/session-inspector.js +50 -24
  22. package/dist/src/types.d.ts +141 -60
  23. package/dist/src/types.js +1 -0
  24. package/dist/src/validation.js +28 -7
  25. package/dist/src/workflow-artifacts.d.ts +1 -0
  26. package/dist/src/workflow-artifacts.js +1 -0
  27. package/dist/src/workflow-evals.d.ts +7 -1
  28. package/dist/src/workflow-evals.js +23 -3
  29. package/evals/cases/recovery-completed-worktree.yaml +17 -0
  30. package/evals/cases/recovery-failed-run.yaml +14 -0
  31. package/package.json +1 -1
  32. package/skills/pi-extensible-workflows/SKILL.md +13 -5
  33. package/src/agent-execution.ts +302 -107
  34. package/src/bundles.ts +471 -0
  35. package/src/cli.ts +130 -22
  36. package/src/doctor-cleanup.ts +38 -4
  37. package/src/eval-capture-extension.ts +15 -1
  38. package/src/execution.ts +27 -15
  39. package/src/host.ts +454 -175
  40. package/src/index.ts +5 -4
  41. package/src/persistence.ts +58 -4
  42. package/src/registry.ts +14 -5
  43. package/src/session-inspector.ts +49 -26
  44. package/src/types.ts +55 -30
  45. package/src/validation.ts +19 -6
  46. package/src/workflow-artifacts.ts +1 -0
  47. package/src/workflow-evals.ts +24 -3
package/README.md CHANGED
@@ -20,7 +20,7 @@ For source installs and local development, see the [installation guide](https://
20
20
 
21
21
  ## Capabilities
22
22
 
23
- The default path is a named inline workflow: write a `script` that fans out independent work with `parallel(...)`, awaits the keyed results, passes them into one summarizing `agent(...)`, and returns. Inline launches require a non-empty `name`; registered function launches reject `name` and use their registered function name as the run name. Runs are backgrounded by default; set `foreground: true` when the final value must be returned in the same tool call.
23
+ The default path is a named inline workflow: write a `script` that fans out independent work with `parallel(...)`, awaits the keyed results, passes them into one summarizing `agent(...)`, and returns. Inline and file-backed launches require a non-empty `name`; a reviewed JavaScript file can use `scriptPath` instead of `script`, and its contents are captured in the run at launch. Registered function launches may use `name` as an optional run label and otherwise use their registered function name. Runs are backgrounded by default; set `foreground: true` when the final value must be returned in the same tool call. If a foreground tool call detaches before its result is accepted by the next event-loop turn, the terminal success or failure is promoted to exactly one follow-up message.
24
24
 
25
25
  ```js
26
26
  const reviews = await parallel("review", {
@@ -36,7 +36,7 @@ return await agent(
36
36
 
37
37
  **Advanced capabilities:** Use registered functions, `outputSchema`, budgets, checkpoints, worktrees, retry/resume, CLI export, and `pipeline(...)` when the task requires them. They remain available without complicating the basic inline path. Workflow worktree scopes always use the explicit `withWorktree(name, callback)` form.
38
38
 
39
- The main Pi agent writes these scripts on the fly for each task; extensions can add reusable functions and variables, and completed workflows can resume without rerunning completed work.
39
+ The main Pi agent writes these scripts on the fly for each task; an external review or approval flow can write one to a JavaScript file and launch it with `scriptPath`. Extensions can add reusable functions and variables, and completed workflows can resume without rerunning completed work.
40
40
 
41
41
  Learn more about roles, workflow contracts, and extension APIs in the documentation:
42
42
 
@@ -51,35 +51,6 @@ Learn more about roles, workflow contracts, and extension APIs in the documentat
51
51
  - [Agent patterns and model selection](https://vekexasia.github.io/pi-extensible-workflows/agents.html#patterns)
52
52
  - [Checkpoints](https://vekexasia.github.io/pi-extensible-workflows/agents.html#checkpoints)
53
53
 
54
- ## Configuration
55
-
56
- Global workflow settings live at `~/.pi/agent/pi-extensible-workflows/settings.json` by default. Trusted projects can add partial overrides at `<project>/.pi/pi-extensible-workflows/settings.json`; precedence is defaults < global < trusted project < per-run options. Project collections replace global collections, so `{}` and empty arrays clear inherited aliases or resource exclusions. Untrusted project settings are ignored. See [global and project settings](https://vekexasia.github.io/pi-extensible-workflows/developers.html#settings) for the schema, trust gate, source reporting, and merge rules.
57
-
58
- ## CLI
59
-
60
- ```sh
61
- npx pi-extensible-workflows doctor
62
- npx pi-extensible-workflows doctor cleanup [--older-than-days <days>] [--yes]
63
- npx pi-extensible-workflows inspect [session-id]
64
- npx pi-extensible-workflows transcript <session-file>
65
- npx pi-extensible-workflows run <workflow-name> [workflow arguments]
66
- npx pi-extensible-workflows export <workflow-name> [--name <command>] [--output <path>] [--force]
67
- ```
68
-
69
- `doctor` validates the installation and active Pi resources and remains read-only. `doctor cleanup` is an explicit, dry-run-first maintenance command: it previews terminal workflow runs older than 90 days across the current project's stored sessions and deletes them only with `--yes`; use `--older-than-days` to change the positive age threshold. It protects active, corrupt, leased, and dependency-linked runs. `inspect` opens a read-only terminal view of persisted workflow runs. `transcript` renders a session transcript to stdout. `run` derives flat CLI arguments and help from a registered function's input schema. Use `--input '<json>'` for nested or otherwise complex inputs. It executes in the current working directory, writes the final JSON result to stdout, and writes progress and errors to stderr. `export` creates an executable POSIX launcher in `~/.local/bin` by default.
70
- `run` and `export` accept the trust overrides `--approve` and `--no-approve`; the generated launcher forwards its arguments to `run`. `--` ends launcher option parsing, and later tokens are passed to workflow input instead of being interpreted as launcher options. Headless `run` and generated `export` launchers cannot execute workflows containing checkpoints; use the Pi workflow tool/UI path for checkpointed workflows.
71
- Launch snapshots use identity version 5. Cold resume rejects older snapshots, including v4 snapshots created with the previous worktree or registered-function naming contracts, with `RESUME_INCOMPATIBLE`; relaunch the workflow instead.
72
-
73
- ## Development
74
-
75
- ```sh
76
- npm ci
77
- npm run check
78
- npm run acceptance
79
- npm pack --dry-run --json
80
- ```
81
-
82
- Model-backed evaluations are optional. See the [evaluation guide](https://vekexasia.github.io/pi-extensible-workflows/developers.html#evaluation).
83
54
 
84
55
  ## License
85
56
 
@@ -1,8 +1,56 @@
1
1
  import { type ToolDefinition } from "@earendil-works/pi-coding-agent";
2
2
  type ThinkingLevel = "off" | "minimal" | "low" | "medium" | "high" | "xhigh" | "max";
3
- import type { AgentIdentity, AgentResourceExclusions, AgentResourcePolicy, AgentSetupSummary, JsonSchema, JsonValue, ModelSpec, NativeSession, RegisteredAgentSetupHook, SessionFactory, SessionInput, WorkflowRunContext } from "./types.js";
3
+ type AgentMessage = {
4
+ role: string;
5
+ content?: unknown;
6
+ stopReason?: string;
7
+ errorMessage?: string;
8
+ usage?: {
9
+ input: number;
10
+ output: number;
11
+ cacheRead: number;
12
+ cacheWrite: number;
13
+ cost: {
14
+ total: number;
15
+ };
16
+ };
17
+ };
18
+ type PiSession = {
19
+ readonly sessionId: string;
20
+ readonly sessionFile: string | undefined;
21
+ readonly messages: readonly AgentMessage[];
22
+ getSessionStats(): {
23
+ tokens: {
24
+ input: number;
25
+ output: number;
26
+ cacheRead: number;
27
+ cacheWrite: number;
28
+ total: number;
29
+ };
30
+ cost: number;
31
+ };
32
+ readonly systemPrompt?: string;
33
+ readonly model?: {
34
+ provider: string;
35
+ model?: string;
36
+ id?: string;
37
+ };
38
+ readonly agent?: {
39
+ state: {
40
+ tools: readonly {
41
+ name: string;
42
+ }[];
43
+ };
44
+ };
45
+ subscribe?(listener: (event: unknown) => void): () => void;
46
+ prompt(text: string): Promise<void>;
47
+ steer?(text: string): Promise<void>;
48
+ abort?(): Promise<void>;
49
+ dispose(): void;
50
+ };
51
+ import type { AgentIdentity, AgentResourceExclusions, AgentResourcePolicy, AgentSetupSummary, AgentTransport, AgentTransportContext, JsonSchema, JsonValue, ModelSpec, PreparedAgentSession, RegisteredAgentSetupHook, SessionInput, WorkflowAgentSession, WorkflowAgentSessionReference, WorkflowAgentSessionState, WorkflowRunContext } from "./types.js";
4
52
  import type { RunStore } from "./persistence.js";
5
- export type { AgentSetup, AgentSetupContext, AgentSetupHook, NativeSession, RegisteredAgentSetupHook, SessionFactory, SessionInput } from "./types.js";
53
+ export type { AgentSetup, AgentSetupContext, AgentSetupHook, AgentTransport, AgentTransportContext, PreparedAgentSession, RegisteredAgentSetupHook, SessionInput, WorkflowAgentMessage, WorkflowAgentSession, WorkflowAgentSessionEvent, WorkflowAgentSessionReference, WorkflowAgentSessionState, WorkflowAgentSessionStats, WorkflowAgentTurnResult } from "./types.js";
6
54
  export interface AgentBudgetHooks {
7
55
  beforeAttempt(): void;
8
56
  beforeTurn(): void;
@@ -15,6 +63,7 @@ export interface AgentDefinition {
15
63
  model?: string;
16
64
  thinking?: ThinkingLevel;
17
65
  tools?: readonly string[];
66
+ overrideSystemPrompt?: boolean;
18
67
  disabledAgentResources?: AgentResourceExclusions;
19
68
  }
20
69
  export interface AgentProviderFailure {
@@ -34,7 +83,7 @@ export interface AgentExecutionOptions {
34
83
  model?: string;
35
84
  thinking?: ThinkingLevel;
36
85
  onProgress?: (progress: AgentProgress) => void | Promise<void>;
37
- onAttempt?: (attempt: Pick<AgentAttempt, "attempt" | "sessionId" | "sessionFile" | "setup">) => void | Promise<void>;
86
+ onAttempt?: (attempt: AgentAttempt) => void | Promise<void>;
38
87
  providerErrorRecovery?: (failure: AgentProviderFailure) => Promise<AgentProviderRecovery>;
39
88
  modelOverride?: ModelSpec;
40
89
  tools?: readonly string[];
@@ -56,6 +105,7 @@ export interface AgentExecutionRoot {
56
105
  tools: ReadonlySet<string>;
57
106
  agentDefinitions?: Readonly<Record<string, AgentDefinition>>;
58
107
  agentDir?: string;
108
+ additionalSkillPaths?: readonly string[];
59
109
  availableModels?: ReadonlySet<string>;
60
110
  knownModels?: ReadonlySet<string>;
61
111
  modelAliases?: Readonly<Record<string, string>>;
@@ -87,36 +137,42 @@ export interface AgentActivity {
87
137
  export interface AgentProgress {
88
138
  accounting: AgentAccounting;
89
139
  toolCalls: readonly AgentToolCallProgress[];
140
+ state?: WorkflowAgentSessionState;
90
141
  activity?: AgentActivity;
142
+ lastEventAt?: number;
91
143
  persist: boolean;
92
144
  }
93
145
  export interface AgentAttempt {
94
146
  attempt: number;
95
- sessionId: string;
96
- sessionFile: string;
147
+ transport: string;
148
+ session?: WorkflowAgentSessionReference;
149
+ liveSession?: WorkflowAgentSession;
97
150
  result?: JsonValue;
98
151
  error?: {
99
152
  code: string;
100
153
  message: string;
101
154
  };
102
155
  accounting: AgentAccounting;
103
- setup?: AgentSetupSummary;
156
+ setup: AgentSetupSummary;
104
157
  }
105
158
  export interface AgentExecutionResult {
106
159
  value: JsonValue;
107
160
  attempts: readonly AgentAttempt[];
108
161
  cwd: string;
109
162
  }
110
- export declare function createNativeAgentSession(input: SessionInput): Promise<NativeSession>;
163
+ export declare function createLocalPiSession(input: SessionInput): Promise<PiSession>;
164
+ export declare function createLocalWorkflowAgentSession(prepared: Readonly<PreparedAgentSession>, context: Readonly<AgentTransportContext>): Promise<WorkflowAgentSession>;
165
+ export declare const localAgentTransport: AgentTransport;
111
166
  export declare class WorkflowAgentExecutor {
112
167
  private readonly root;
113
- private readonly createSession;
114
- constructor(root: AgentExecutionRoot, createSession?: SessionFactory);
168
+ private readonly transport;
169
+ constructor(root: AgentExecutionRoot, transport?: AgentTransport);
115
170
  setRunContext(runContext: Readonly<WorkflowRunContext>): void;
116
171
  resolve(options: AgentExecutionOptions, inheritedTools?: readonly string[]): {
117
172
  model: ModelSpec;
118
173
  requestedModel?: string;
119
174
  tools: readonly string[];
175
+ systemPrompt?: string;
120
176
  systemPromptAppend: string;
121
177
  };
122
178
  execute(task: string, options: AgentExecutionOptions, signal?: AbortSignal, customTools?: readonly ToolDefinition[], setSteer?: (handler: (message: string) => void | Promise<void>) => void, beforeRetry?: () => void): Promise<AgentExecutionResult>;
@@ -163,6 +219,7 @@ type ScheduledNode = {
163
219
  id: string;
164
220
  runId: string;
165
221
  parentId?: string;
222
+ prompt?: string;
166
223
  options: Readonly<ScheduledAgentOptions>;
167
224
  children: Set<string>;
168
225
  collected: boolean;
@@ -177,6 +234,7 @@ type ScheduledNode = {
177
234
  export type OwnershipRecord = {
178
235
  id: string;
179
236
  parentId?: string;
237
+ prompt?: string;
180
238
  label: string;
181
239
  state: ScheduledNode["state"];
182
240
  options: Readonly<ScheduledAgentOptions>;