pi-extensible-workflows 0.3.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 +72 -0
  2. package/dist/src/agent-execution.d.ts +213 -0
  3. package/dist/src/agent-execution.js +537 -0
  4. package/dist/src/ambient-workflow-evals.d.ts +112 -0
  5. package/dist/src/ambient-workflow-evals.js +375 -0
  6. package/dist/src/cli.d.ts +6 -0
  7. package/dist/src/cli.js +26 -0
  8. package/dist/src/doctor.d.ts +59 -0
  9. package/dist/src/doctor.js +269 -0
  10. package/dist/src/eval-capture-extension.d.ts +5 -0
  11. package/dist/src/eval-capture-extension.js +48 -0
  12. package/dist/src/index.d.ts +362 -0
  13. package/dist/src/index.js +2839 -0
  14. package/dist/src/persistence.d.ts +90 -0
  15. package/dist/src/persistence.js +530 -0
  16. package/dist/src/session-inspector.d.ts +59 -0
  17. package/dist/src/session-inspector.js +396 -0
  18. package/dist/src/workflow-evals-child.d.ts +1 -0
  19. package/dist/src/workflow-evals-child.js +13 -0
  20. package/dist/src/workflow-evals.d.ts +290 -0
  21. package/dist/src/workflow-evals.js +1221 -0
  22. package/evals/cases/custom-model-read.yaml +15 -0
  23. package/evals/cases/direct-answer.yaml +6 -0
  24. package/evals/cases/mixed-parallel-pipeline.yaml +18 -0
  25. package/evals/cases/output-schema.yaml +22 -0
  26. package/evals/cases/parallel.yaml +15 -0
  27. package/evals/cases/pipeline.yaml +10 -0
  28. package/evals/cases/ready-for-agent-parallel-merge.yaml +32 -0
  29. package/evals/cases/required-role.yaml +14 -0
  30. package/evals/cases/role-model-mixed.yaml +18 -0
  31. package/evals/cases/two-agents.yaml +10 -0
  32. package/package.json +65 -0
  33. package/skills/pi-extensible-workflows/SKILL.md +109 -0
  34. package/src/agent-execution.ts +529 -0
  35. package/src/ambient-workflow-evals.ts +452 -0
  36. package/src/cli.ts +23 -0
  37. package/src/doctor.ts +285 -0
  38. package/src/eval-capture-extension.ts +54 -0
  39. package/src/index.ts +2519 -0
  40. package/src/persistence.ts +470 -0
  41. package/src/session-inspector.ts +370 -0
  42. package/src/workflow-evals-child.ts +15 -0
  43. package/src/workflow-evals.ts +876 -0
  44. package/test/fixtures/ready-for-agent-tasks.md +9 -0
  45. package/test/fixtures/workflow-eval-roles/developer.md +18 -0
  46. package/test/fixtures/workflow-eval-roles/reviewer.md +18 -0
  47. package/test/fixtures/workflow-eval-roles/scout.md +17 -0
@@ -0,0 +1,15 @@
1
+ id: custom-model-read
2
+ prompt: "Have one subagent using the model $EVAL_MODEL read README.md with a minimal toolset and report in one sentence what this package does."
3
+ maxCost: 0.1
4
+ expectations:
5
+ workflowCallCount:
6
+ min: 1
7
+ agentPolicies:
8
+ - callIndex: 0
9
+ model: "$EVAL_MODEL"
10
+ tools:
11
+ mode: exact
12
+ values: [read]
13
+ semanticCriteria:
14
+ - id: intent
15
+ description: "The script configures one agent with the requested model and only the read tool, instructs it to inspect README.md, and returns its one-sentence package description."
@@ -0,0 +1,6 @@
1
+ id: direct-answer
2
+ prompt: "How many lines are in README.md?"
3
+ maxCost: 0.1
4
+ expectations:
5
+ workflowCallCount: 0
6
+ expectedWorkflowCalls: 0
@@ -0,0 +1,18 @@
1
+ id: mixed-parallel-pipeline
2
+ prompt: "Gather API and UI evidence independently at the same time, then process each gathered result through the same ordered analysis and summary stages."
3
+ maxCost: 0.1
4
+ expectations:
5
+ workflowCallCount:
6
+ min: 1
7
+ requiredOperations: [parallel, pipeline]
8
+ minimumAgentCalls: 2
9
+ requiredAgentStructures:
10
+ - execution: parallel
11
+ operation: parallel
12
+ agents: [{}, {}]
13
+ - execution: sequential
14
+ operation: pipeline
15
+ agents: [{}, {}]
16
+ semanticCriteria:
17
+ - id: intent
18
+ description: "The script gathers API and UI evidence in parallel, then passes each result through ordered analysis and summary stages."
@@ -0,0 +1,22 @@
1
+ id: output-schema
2
+ prompt: "Use one scout subagent for a structured report containing a numeric count and a text summary."
3
+ maxCost: 0.1
4
+ expectations:
5
+ workflowCallCount:
6
+ min: 1
7
+ requiredRoles: [scout]
8
+ agentPolicies:
9
+ - callIndex: 0
10
+ role: scout
11
+ forbidOptions: [model, thinking, tools]
12
+ requireOutputSchema:
13
+ type: object
14
+ requiredKeys: [count, summary]
15
+ propertyTypes:
16
+ count: number
17
+ summary: string
18
+ forbiddenProperties: [extra]
19
+ count: 1
20
+ semanticCriteria:
21
+ - id: intent
22
+ description: "The script configures one scout agent with an output schema requiring a numeric count and text summary."
@@ -0,0 +1,15 @@
1
+ id: parallel
2
+ prompt: "Run the independent API and UI checks at the same time, then report both outcomes together."
3
+ maxCost: 0.1
4
+ expectations:
5
+ workflowCallCount:
6
+ min: 1
7
+ requiredOperations: [parallel]
8
+ minimumAgentCalls: 2
9
+ requiredAgentStructures:
10
+ - execution: parallel
11
+ operation: parallel
12
+ agents: [{}, {}]
13
+ semanticCriteria:
14
+ - id: intent
15
+ description: "Independent API and UI checks run in parallel and both outcomes are combined."
@@ -0,0 +1,10 @@
1
+ id: pipeline
2
+ prompt: "Process the API and UI artifacts through the same ordered normalization and finalization stages, preserving each item's result."
3
+ maxCost: 0.1
4
+ expectations:
5
+ workflowCallCount:
6
+ min: 1
7
+ requiredOperations: [pipeline]
8
+ semanticCriteria:
9
+ - id: intent
10
+ description: "API and UI items pass through the same ordered normalization and finalization stages."
@@ -0,0 +1,32 @@
1
+ id: ready-for-agent-parallel-merge
2
+ prompt: "Fix every ready-for-agent issue. GitHub access is unavailable, so read the two issue descriptions in test/fixtures/ready-for-agent-tasks.md. Do the issues in parallel, each in its own named withWorktree scope. After all work is done, merge their branches into main and leave main clean."
3
+ maxCost: 10
4
+ expectations:
5
+ workflowCallCount:
6
+ min: 1
7
+ requiredOperations: [withWorktree]
8
+ minimumAgentCalls: 3
9
+ requiredRoles: [developer]
10
+ agentPolicies:
11
+ - callIndex: 0
12
+ role: developer
13
+ - callIndex: 1
14
+ role: developer
15
+ - callIndex: 2
16
+ role: developer
17
+ requiredAgentOrder:
18
+ - role: developer
19
+ execution: parallel
20
+ - role: developer
21
+ execution: parallel
22
+ - role: developer
23
+ execution: sequential
24
+ requiredAgentStructures:
25
+ - execution: parallel
26
+ operation: parallel
27
+ agents:
28
+ - role: developer
29
+ - role: developer
30
+ semanticCriteria:
31
+ - id: intent
32
+ description: "Two developer agents fix the local issue tasks concurrently in separate named withWorktree scopes, then a final developer agent receives both results, merges both branches into main, verifies the merged work, and leaves main clean."
@@ -0,0 +1,14 @@
1
+ id: required-role
2
+ prompt: "Have a reviewer assess the change and return a short review."
3
+ maxCost: 0.1
4
+ expectations:
5
+ workflowCallCount:
6
+ min: 1
7
+ requiredRoles: [reviewer]
8
+ agentPolicies:
9
+ - callIndex: 0
10
+ role: reviewer
11
+ forbidOptions: [model, thinking, tools]
12
+ semanticCriteria:
13
+ - id: intent
14
+ description: "A reviewer-role agent assesses the change and its result is returned."
@@ -0,0 +1,18 @@
1
+ id: role-model-mixed
2
+ prompt: "Obtain a reviewer-role assessment first, then use a separate subagent with the explicit model $EVAL_MODEL and no tools to synthesize the final text."
3
+ maxCost: 0.1
4
+ expectations:
5
+ workflowCallCount:
6
+ min: 1
7
+ minimumAgentCalls: 2
8
+ agentPolicies:
9
+ - callIndex: 0
10
+ role: reviewer
11
+ forbidOptions: [model, thinking, tools]
12
+ - callIndex: 1
13
+ model: "$EVAL_MODEL"
14
+ tools:
15
+ mode: empty
16
+ semanticCriteria:
17
+ - id: intent
18
+ description: "The reviewer assessment is produced first and passed to a separate no-tools synthesis agent."
@@ -0,0 +1,10 @@
1
+ id: two-agents
2
+ prompt: "Investigate this repository from two independent angles: inspect the API surface and inspect the user-facing behavior. Combine both findings into one concise plain-text comparison."
3
+ maxCost: 0.1
4
+ expectations:
5
+ workflowCallCount:
6
+ min: 1
7
+ minimumAgentCalls: 2
8
+ semanticCriteria:
9
+ - id: intent
10
+ description: "The workflow independently inspects API and user-facing behavior, then combines both findings into one concise comparison."
package/package.json ADDED
@@ -0,0 +1,65 @@
1
+ {
2
+ "name": "pi-extensible-workflows",
3
+ "version": "0.3.0",
4
+ "description": "Deterministic multi-agent workflow orchestration for Pi",
5
+ "homepage": "https://vekexasia.github.io/pi-extensible-workflows/",
6
+ "repository": { "type": "git", "url": "git+https://github.com/vekexasia/pi-extensible-workflows.git" },
7
+ "type": "module",
8
+ "keywords": [
9
+ "pi-package",
10
+ "pi",
11
+ "workflow",
12
+ "multi-agent",
13
+ "orchestration",
14
+ "automation"
15
+ ],
16
+ "exports": "./dist/src/index.js",
17
+ "bin": {
18
+ "pi-extensible-workflows": "./dist/src/cli.js"
19
+ },
20
+ "files": [
21
+ "dist/src",
22
+ "src",
23
+ "skills",
24
+ "evals",
25
+ "test/fixtures"
26
+ ],
27
+ "scripts": {
28
+ "build": "rm -rf dist && tsc -p tsconfig.json && chmod +x dist/src/cli.js",
29
+ "inspect": "node dist/src/cli.js inspect",
30
+ "lint": "eslint .",
31
+ "test": "npm run build && node --test 'dist/test/*.test.js'",
32
+ "acceptance": "npm run build && node --test dist/test/runtime-acceptance.test.js",
33
+ "docs:check": "node scripts/check-docs.mjs",
34
+ "check": "npm run lint && npm test && npm run docs:check",
35
+ "evals": "npm run build && node dist/src/workflow-evals.js",
36
+ "evals:ambient": "node -e \"if (process.env.PI_WORKFLOW_EVAL_AMBIENT !== '1') { console.error('Ambient Tier D evals are opt-in. Set PI_WORKFLOW_EVAL_AMBIENT=1 to run them.'); process.exit(1); }\" && npm run build && node dist/src/ambient-workflow-evals.js",
37
+ "prepack": "npm run build"
38
+ },
39
+ "pi": {
40
+ "extensions": [
41
+ "./src/index.ts"
42
+ ]
43
+ },
44
+ "peerDependencies": {
45
+ "@earendil-works/pi-ai": "*",
46
+ "@earendil-works/pi-coding-agent": "*",
47
+ "typebox": "*"
48
+ },
49
+ "devDependencies": {
50
+ "@earendil-works/pi-ai": "0.80.9",
51
+ "@earendil-works/pi-coding-agent": "0.80.9",
52
+ "@eslint/js": "10.0.1",
53
+ "@types/node": "24.12.4",
54
+ "eslint": "10.0.3",
55
+ "typescript": "5.9.3",
56
+ "typescript-eslint": "8.63.0"
57
+ },
58
+ "engines": {
59
+ "node": ">=22.19.0"
60
+ },
61
+ "license": "MIT",
62
+ "dependencies": {
63
+ "acorn": "^8.17.0"
64
+ }
65
+ }
@@ -0,0 +1,109 @@
1
+ ---
2
+ name: pi-extensible-workflows
3
+ description: Use when the task is complex enough to require multiple subagents or when the user explicitly asks for a workflow.
4
+ ---
5
+
6
+ # pi-extensible-workflows
7
+
8
+ Use `workflow` exclusively for genuinely multi-agent orchestration. For one agent, use ordinary tools or `Agent` directly. Do not wrap a single agent in a workflow; define distinct responsibilities and keep the result flow explicit.
9
+
10
+ ## Pattern
11
+
12
+ ```js
13
+ const reportSchema = {
14
+ type: "object",
15
+ properties: {
16
+ summary: { type: "string" },
17
+ findings: { type: "array", items: { type: "string" } },
18
+ },
19
+ required: ["summary", "findings"],
20
+ additionalProperties: false,
21
+ };
22
+
23
+ const reports = await parallel("research", {
24
+ first: () => agent("Research the first target.", { role: "scout", outputSchema: reportSchema }),
25
+ second: () => agent("Research the second target.", { role: "scout", outputSchema: reportSchema }),
26
+ });
27
+
28
+ // Add a downstream agent only when synthesis or independent review is a real phase.
29
+ return agent(
30
+ prompt("Review these reports:\n\n{reports}", { reports }),
31
+ { role: "reviewer", outputSchema: reportSchema },
32
+ );
33
+ ```
34
+
35
+ To pass structured input from the main agent, include `args`:
36
+ ```json
37
+ { "workflow": "namespace.workflowName", "args": { "issue": 42 } }
38
+ ```
39
+ Inside the workflow, read `args.issue`; omitted `args` is `null`.
40
+ If `workflow_catalog` is available, call it once before creating the first workflow for a task. Use the returned global functions, variables, and registered workflows as needed for the rest of that task. Do not try to reinvent already exposed functions.
41
+
42
+ Pass downstream only needed results. Workflow JavaScript has no imports, filesystem, network, process, or timers; delegate such work to agents with the required tools.
43
+
44
+ ## `agent()` options
45
+
46
+ ```typescript
47
+ interface AgentOptions {
48
+ label?: string; // optional non-empty display name
49
+ model?: `${provider}/${model}` | `${provider}/${model}:${thinking}`;
50
+ thinking?: "off" | "minimal" | "low" | "medium" | "high" | "xhigh" | "max";
51
+ role?: string; // one of the available workflow roles
52
+ tools?: string[]; // [] = no tools; omitted uses role or launch tools
53
+ outputSchema?: JsonSchema;
54
+ retries?: number; // non-negative; use for safe, repeatable work
55
+ timeoutMs?: number | null; // positive milliseconds; null means unlimited
56
+ }
57
+ ```
58
+
59
+ Agent calls are unnamed. Direct `agent(...)` calls receive hidden source call-site identity; aliases are unsupported. Calls from one source call site must not race outside `parallel` or `pipeline`, whose structural keys keep replay deterministic.
60
+
61
+ ## Shared worktree scope
62
+
63
+ Use `withWorktree(callback)` or `withWorktree(name, callback)` when top-level agents should collaborate in one worktree:
64
+
65
+ ```js
66
+ const results = await withWorktree("implementation", async () => parallel("implementation", {
67
+ api: () => agent("Implement the API"),
68
+ tests: () => agent("Add integration tests"),
69
+ }));
70
+ ```
71
+
72
+ The callback result is returned unchanged and the worktree is created only when the first enclosed agent launches. Concurrent agents share mutable files, so give them non-conflicting work or coordinate explicitly.
73
+
74
+ `parallel()` tasks may call any workflow function, not only `agent()`:
75
+
76
+ ```js
77
+ const results = await parallel("checks", {
78
+ security: () => reviewRepository({ focus: "security" }),
79
+ release: () => reviewRepository({ focus: "release readiness" }),
80
+ });
81
+ ```
82
+
83
+ Use separate named scopes when each parallel branch needs its own worktree:
84
+
85
+ ```js
86
+ const results = await parallel("implementation", {
87
+ api: () => withWorktree("api", () => agent("Implement the API")),
88
+ ui: () => withWorktree("ui", () => agent("Implement the UI")),
89
+ });
90
+ ```
91
+
92
+ Registered extension functions receive `withWorktree` in their context, so they may create a shared scope internally. Their public inputs and outputs must remain JSON; callbacks cannot cross the extension-function boundary.
93
+
94
+ ## Rules
95
+
96
+ - Do not create a workflow for one agent. Phases must have distinct work.
97
+ - Use `log(messageString)` in the script to surface brief status messages to the operator.
98
+ - A role owns its execution policy. When `role` is present, do not also set `model`, `thinking`, or `tools`; only task-specific options such as `outputSchema`, retries, timeout, or a `withWorktree` scope may accompany it.
99
+ - Use `parallel()` for independent tasks with different flows. Use `pipeline()` when each keyed item passes through the same ordered stages; do not duplicate identical stage chains inside `parallel()` branches.
100
+ - Call shapes are `parallel(operationName, tasksRecord)` and `pipeline(operationName, itemsRecord, stagesRecord)`; object keys are stable task, item, and stage names.
101
+ - Preserve item metadata in workflow code between pipeline stages instead of requiring agents to echo it through `outputSchema`.
102
+ - Repeated work uses a JavaScript loop; each direct `agent(...)` call receives deterministic call-site and occurrence identity.
103
+ - Runs default to background; set tool-call `foreground: true` when asked to wait.
104
+ - Omit `maxAgentLaunches` unless an explicit total launch budget is required.
105
+ - `parallel()` and `pipeline()` return keyed bare values. Await results before use.
106
+ - Interpolate results with `prompt("...{value}", { value })`; placeholders in plain strings stay literal.
107
+ - Use `outputSchema` only when another phase must compare, aggregate, or validate the result. Never add it to a final agent whose prose is returned directly. Keep only fields the consumer needs, and avoid repeating the same evidence in multiple schemas.
108
+ - With `outputSchema`, agents must call `workflow_result`; one repair prompt is built in. Omit `retries` unless an additional retry is justified and the work is idempotent.
109
+ - Do not add "persona" specs to the prompt for agents. Just define the task.