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.
- package/README.md +72 -0
- package/dist/src/agent-execution.d.ts +213 -0
- package/dist/src/agent-execution.js +537 -0
- package/dist/src/ambient-workflow-evals.d.ts +112 -0
- package/dist/src/ambient-workflow-evals.js +375 -0
- package/dist/src/cli.d.ts +6 -0
- package/dist/src/cli.js +26 -0
- package/dist/src/doctor.d.ts +59 -0
- package/dist/src/doctor.js +269 -0
- package/dist/src/eval-capture-extension.d.ts +5 -0
- package/dist/src/eval-capture-extension.js +48 -0
- package/dist/src/index.d.ts +362 -0
- package/dist/src/index.js +2839 -0
- package/dist/src/persistence.d.ts +90 -0
- package/dist/src/persistence.js +530 -0
- package/dist/src/session-inspector.d.ts +59 -0
- package/dist/src/session-inspector.js +396 -0
- package/dist/src/workflow-evals-child.d.ts +1 -0
- package/dist/src/workflow-evals-child.js +13 -0
- package/dist/src/workflow-evals.d.ts +290 -0
- package/dist/src/workflow-evals.js +1221 -0
- package/evals/cases/custom-model-read.yaml +15 -0
- package/evals/cases/direct-answer.yaml +6 -0
- package/evals/cases/mixed-parallel-pipeline.yaml +18 -0
- package/evals/cases/output-schema.yaml +22 -0
- package/evals/cases/parallel.yaml +15 -0
- package/evals/cases/pipeline.yaml +10 -0
- package/evals/cases/ready-for-agent-parallel-merge.yaml +32 -0
- package/evals/cases/required-role.yaml +14 -0
- package/evals/cases/role-model-mixed.yaml +18 -0
- package/evals/cases/two-agents.yaml +10 -0
- package/package.json +65 -0
- package/skills/pi-extensible-workflows/SKILL.md +109 -0
- package/src/agent-execution.ts +529 -0
- package/src/ambient-workflow-evals.ts +452 -0
- package/src/cli.ts +23 -0
- package/src/doctor.ts +285 -0
- package/src/eval-capture-extension.ts +54 -0
- package/src/index.ts +2519 -0
- package/src/persistence.ts +470 -0
- package/src/session-inspector.ts +370 -0
- package/src/workflow-evals-child.ts +15 -0
- package/src/workflow-evals.ts +876 -0
- package/test/fixtures/ready-for-agent-tasks.md +9 -0
- package/test/fixtures/workflow-eval-roles/developer.md +18 -0
- package/test/fixtures/workflow-eval-roles/reviewer.md +18 -0
- 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,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.
|