@llblab/pi-kit 0.1.5 → 0.1.7
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/CHANGELOG.md +9 -0
- package/README.md +3 -3
- package/node_modules/@llblab/pi-actors/BACKLOG.md +1 -1
- package/node_modules/@llblab/pi-actors/CHANGELOG.md +14 -1
- package/node_modules/@llblab/pi-actors/README.md +19 -3
- package/node_modules/@llblab/pi-actors/dist/lib/extension-runtime.js +29 -10
- package/node_modules/@llblab/pi-actors/dist/lib/inspector-overlay.d.ts +3 -0
- package/node_modules/@llblab/pi-actors/dist/lib/inspector-overlay.js +120 -38
- package/node_modules/@llblab/pi-actors/dist/lib/limits.d.ts +1 -0
- package/node_modules/@llblab/pi-actors/dist/lib/limits.js +1 -0
- package/node_modules/@llblab/pi-actors/dist/lib/observability.js +6 -1
- package/node_modules/@llblab/pi-actors/dist/lib/run-ui-runtime.d.ts +10 -3
- package/node_modules/@llblab/pi-actors/dist/lib/run-ui-runtime.js +109 -52
- package/node_modules/@llblab/pi-actors/dist/lib/runs-artifacts.js +24 -4
- package/node_modules/@llblab/pi-actors/dist/lib/runtime.d.ts +2 -0
- package/node_modules/@llblab/pi-actors/dist/lib/runtime.js +24 -4
- package/node_modules/@llblab/pi-actors/dist/lib/session-evidence.d.ts +1 -0
- package/node_modules/@llblab/pi-actors/dist/lib/session-evidence.js +3 -2
- package/node_modules/@llblab/pi-actors/dist/lib/state-readers.d.ts +5 -1
- package/node_modules/@llblab/pi-actors/dist/lib/state-readers.js +30 -3
- package/node_modules/@llblab/pi-actors/dist/lib/tools-access.d.ts +1 -0
- package/node_modules/@llblab/pi-actors/dist/lib/tools-access.js +13 -11
- package/node_modules/@llblab/pi-actors/dist/lib/tools-inspect.js +5 -5
- package/node_modules/@llblab/pi-actors/dist/lib/tools-message.d.ts +1 -0
- package/node_modules/@llblab/pi-actors/dist/lib/tools-message.js +3 -1
- package/node_modules/@llblab/pi-actors/docs/README.md +1 -0
- package/node_modules/@llblab/pi-actors/docs/actor-inspector.md +21 -5
- package/node_modules/@llblab/pi-actors/docs/async-runs.md +16 -4
- package/node_modules/@llblab/pi-actors/docs/command-templates.md +5 -4
- package/node_modules/@llblab/pi-actors/docs/inspection.md +83 -0
- package/node_modules/@llblab/pi-actors/docs/recipe-library.md +1 -1
- package/node_modules/@llblab/pi-actors/docs/template-recipes.md +225 -66
- package/node_modules/@llblab/pi-actors/docs/tool-registry.md +24 -3
- package/node_modules/@llblab/pi-actors/lib/extension-runtime.ts +26 -10
- package/node_modules/@llblab/pi-actors/lib/inspector-overlay.ts +161 -33
- package/node_modules/@llblab/pi-actors/lib/limits.ts +1 -0
- package/node_modules/@llblab/pi-actors/lib/observability.ts +5 -1
- package/node_modules/@llblab/pi-actors/lib/run-ui-runtime.ts +128 -50
- package/node_modules/@llblab/pi-actors/lib/runs-artifacts.ts +34 -4
- package/node_modules/@llblab/pi-actors/lib/runtime.ts +26 -7
- package/node_modules/@llblab/pi-actors/lib/session-evidence.ts +7 -2
- package/node_modules/@llblab/pi-actors/lib/state-readers.ts +45 -3
- package/node_modules/@llblab/pi-actors/lib/tools-access.ts +26 -12
- package/node_modules/@llblab/pi-actors/lib/tools-inspect.ts +9 -5
- package/node_modules/@llblab/pi-actors/lib/tools-message.ts +8 -1
- package/node_modules/@llblab/pi-actors/package.json +1 -1
- package/node_modules/@llblab/pi-telegram/AGENTS.md +1 -1
- package/node_modules/@llblab/pi-telegram/CHANGELOG.md +17 -0
- package/node_modules/@llblab/pi-telegram/README.md +1 -1
- package/node_modules/@llblab/pi-telegram/docs/architecture.md +5 -5
- package/node_modules/@llblab/pi-telegram/index.ts +25 -0
- package/node_modules/@llblab/pi-telegram/lib/bindings.ts +11 -0
- package/node_modules/@llblab/pi-telegram/lib/journal.ts +192 -9
- package/node_modules/@llblab/pi-telegram/lib/queue.ts +14 -0
- package/node_modules/@llblab/pi-telegram/lib/runtime.ts +52 -2
- package/node_modules/@llblab/pi-telegram/lib/status.ts +3 -3
- package/node_modules/@llblab/pi-telegram/lib/telegram-api.ts +5 -1
- package/node_modules/@llblab/pi-telegram/package.json +1 -1
- package/node_modules/@llblab/pi-telegram/skills/generated-control-surface/SKILL.md +14 -6
- package/package.json +4 -4
|
@@ -25,7 +25,7 @@ Each Run persists:
|
|
|
25
25
|
- captured Recipe/template/values;
|
|
26
26
|
- model and thinking policy provenance.
|
|
27
27
|
|
|
28
|
-
Inspection, Control, cancellation, kill, retirement, and teardown filter by owner. Lifecycle mutations revalidate generation, state, and process identity under the canonical lock.
|
|
28
|
+
Inspection, Control, cancellation, kill, retirement, and teardown filter by owner. Public Run-specific `inspect` and `message` also require a current coordinator session whose id exactly matches the persisted non-empty owner; possession of `run:<id>` alone grants no access. Missing coordinator identity, ownerless state, and cross-owner state fail closed. `inspect target=runtime view=runs` returns only the current session's exact-owner inventory and is the supported diagnostic when a remembered Run is inaccessible. Lifecycle mutations additionally revalidate generation, state, and process identity under the canonical lock.
|
|
29
29
|
|
|
30
30
|
## State Files
|
|
31
31
|
|
|
@@ -86,11 +86,19 @@ Unix services may publish a FIFO; native Windows services publish a Windows name
|
|
|
86
86
|
|
|
87
87
|
A service exact-id claims queued or transport-delivered Controls and records handled/failed outcomes through the canonical Control journal authority. Admission performs one locked read, integrity/generation check, terminal-tail compaction, capacity decision, and atomic write. The 65th pending Control and a rewrite exceeding 1 MiB fail as bounded `control_backpressure` before admission; malformed, unreadable, oversized, or stale-generation journals fail with an integrity reason and no rejected record. `inspect view=control` reports pending capacity, saturation, stale work, journal bytes, and diagnostics. Every transition uses the same lock, expected-state fence, 128-terminal compaction, and atomic bounded rewrite; persisted errors truncate inside the string at 4 KiB. Admitted nonterminal Controls never expire automatically. Delivery failure evidence cannot regress a Control already claimed or completed by a fast consumer. Services capture their startup generation, so stale-generation Controls never execute.
|
|
88
88
|
|
|
89
|
-
Runtime lifecycle `kill`, retention actions, and review retry/reset remain runtime-owned rather than Recipe-declared.
|
|
89
|
+
Runtime lifecycle `kill`, retention actions, and review retry/reset remain runtime-owned rather than Recipe-declared. Invoke Run actions through the public tool exactly as follows:
|
|
90
|
+
|
|
91
|
+
```text
|
|
92
|
+
message target=run:<id> action=kill
|
|
93
|
+
message target=run:<id> action=archive
|
|
94
|
+
message target=run:<id> action=prune input={"preserve_artifacts":true}
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
Kill accepts only a running owned generation and is the recovery path for a stuck saturated Run: it bypasses actor-local Control capacity and creates no synthetic Control. Archive and prune accept only terminal owned Runs. Archive moves the entire Run state directory and leaves a tombstone at the original path. Prune removes kernel state and preserves declared existing artifacts only when `preserve_artifacts` is explicitly true, copying them to retained artifact storage first. Same-directory restart clears all generation-local evidence before the new `run_instance_id`.
|
|
90
98
|
|
|
91
99
|
## Execution Evidence
|
|
92
100
|
|
|
93
|
-
`execution.json` stores general command/session provenance. The async runner keeps bounded stdout/stderr logs plus complete capture artifacts when semantic validation requires untruncated evidence. Pi command execution also records owned session provenance for later Trace projection and review checks. Trace and Control quotas do not constrain declared user artifacts, repositories or media sources, complete execution captures, or actor-owned queue/workload state; each remains governed by its own lifecycle and policy.
|
|
101
|
+
`execution.json` stores general command/session provenance. The async runner keeps bounded stdout/stderr logs plus complete capture artifacts when semantic validation requires untruncated evidence. Pi command execution also records owned session provenance for later Trace projection and review checks. Session evidence files larger than 4 MiB are rejected before JSONL materialization and surface explicit truncation diagnostics instead of being loaded unboundedly. Artifact manifests compute size and SHA-256 incrementally in 64 KiB chunks. Trace and Control quotas do not constrain declared user artifacts, repositories or media sources, complete execution captures, or actor-owned queue/workload state; each remains governed by its own lifecycle and policy.
|
|
94
102
|
|
|
95
103
|
Review acceptance remains a command-stage concern. General execution evidence does not imply review approval.
|
|
96
104
|
|
|
@@ -126,7 +134,7 @@ Packaged controlled services demonstrate the endpoint protocol:
|
|
|
126
134
|
- `music-player/playback` consumes playback Controls and emits playback Trace;
|
|
127
135
|
- `actors/resource-locker` consumes queue/lease actions, emits lock Trace, and atomically retains at most 512 valid journal records within 1 MiB.
|
|
128
136
|
|
|
129
|
-
Shared archive/prune evidence similarly retains at most 256 valid records within 1 MiB under its canonical lock.
|
|
137
|
+
Shared archive/prune evidence similarly retains at most 256 valid records within 1 MiB under its canonical lock. Filesystem watchers and bounded reconciliation observe authoritative state directly.
|
|
130
138
|
|
|
131
139
|
One-shot pipelines omit Control and terminate through their command graph.
|
|
132
140
|
|
|
@@ -136,6 +144,10 @@ One-shot pipelines omit Control and terminate through their command graph.
|
|
|
136
144
|
inspect target=run:<id> view=recipe
|
|
137
145
|
inspect target=run:<id> view=trace source=lifecycle lines=40
|
|
138
146
|
inspect target=run:<id> view=control
|
|
147
|
+
inspect target=runtime view=runs
|
|
148
|
+
inspect target=runtime view=triage
|
|
139
149
|
```
|
|
140
150
|
|
|
151
|
+
Runtime `runs` is the exact-owner inventory; `triage` aggregates failed Runs, Control pressure, incomplete Trace evidence, and attention for that inventory. See [Management Inspection](./inspection.md) for every target/view combination and applicable inputs.
|
|
152
|
+
|
|
141
153
|
Use `/actor-inspector` to inspect Runs as concrete actor instances in the live TUI. Runtime, Recipe registry, and tool definitions remain separate management targets. No public noun, tool, target, or view is added by bounded retention.
|
|
@@ -30,7 +30,7 @@ Command-template standard does not own:
|
|
|
30
30
|
|
|
31
31
|
## Shape
|
|
32
32
|
|
|
33
|
-
A command template is
|
|
33
|
+
A command template is a command-line string, an ordered array of command-template nodes, or an object that applies execution fields to a nested `template`:
|
|
34
34
|
|
|
35
35
|
```json
|
|
36
36
|
{
|
|
@@ -62,7 +62,8 @@ Common object fields:
|
|
|
62
62
|
- `retry`: Optional max attempts including the first. Default is `1`.
|
|
63
63
|
- `failure`: Optional failure propagation scope: `continue`, `branch`, or `root`. Default is `continue`.
|
|
64
64
|
- `recover`: Optional command template run between failed retry attempts. Recovery output is ignored; recovery failure stops retries.
|
|
65
|
-
- `
|
|
65
|
+
- `repeat`: Optional non-negative expansion count or supported length expression. Repeated nodes receive generated zero-based index placeholders.
|
|
66
|
+
- `template`: Required nested command string, ordered composition array, or command-template object.
|
|
66
67
|
|
|
67
68
|
For object form, write `template` last. Read the node flags first, then the executable content. Storage paths, labels, selectors, descriptions, and registry-specific metadata belong to each extension's local schema.
|
|
68
69
|
|
|
@@ -83,7 +84,7 @@ Implementations may expand `~` in command position and may resolve relative comm
|
|
|
83
84
|
Supported forms:
|
|
84
85
|
|
|
85
86
|
| Form | Meaning |
|
|
86
|
-
|
|
|
87
|
+
| --- | --- |
|
|
87
88
|
| `{name}` | Required value from runtime values or `defaults` |
|
|
88
89
|
| `{name=default}` | Inline default when no value is provided |
|
|
89
90
|
| `{name??fallback}` | Fallback when value is missing, null, or empty |
|
|
@@ -206,7 +207,7 @@ Repeat expressions support only integers, `index`, `prev`, `next`, `repeat`, par
|
|
|
206
207
|
|
|
207
208
|
Repeat placeholders are local generated values. Call-time args should not use these reserved names to override the repeat index.
|
|
208
209
|
|
|
209
|
-
Parallel children use the same object shape: flags come first and `template` stays last. A join remains usable when at least one branch succeeds and reports each branch label/status.
|
|
210
|
+
Parallel children use the same object shape: flags come first and `template` stays last. A join remains usable when at least one branch succeeds and reports each branch label/status. The portable composition field is always `template`.
|
|
210
211
|
|
|
211
212
|
## Failure Propagation
|
|
212
213
|
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
# Management Inspection
|
|
2
|
+
|
|
3
|
+
The public `inspect` tool exposes four exact target families. Targets are management projections, not interchangeable aliases.
|
|
4
|
+
|
|
5
|
+
## Target and View Matrix
|
|
6
|
+
|
|
7
|
+
| Target | Views | Purpose |
|
|
8
|
+
| --- | --- | --- |
|
|
9
|
+
| `run:<id>` | `recipe`, `trace`, `control` | Inspect one accessible Run generation |
|
|
10
|
+
| `runtime` | `status`, `runs`, `triage` | Inspect package policy, owned Run inventory, or aggregate operational pressure |
|
|
11
|
+
| `recipes` | `status`, `summary`, `doctor`, `imports`, `reviews` | Inspect user Recipe discovery, active Skill components, exact resolution, imports, and automatic-review recovery |
|
|
12
|
+
| `tool:<name>` | `status`, `schema` | Inspect persistent-tool activation/usage or its current callable schema |
|
|
13
|
+
|
|
14
|
+
`verbose=false` normally returns compact text and `verbose=true` returns structured details. `tool:<name> view=schema` is always structured because its callable parameter schema has no useful compact equivalent.
|
|
15
|
+
|
|
16
|
+
## Run Targets
|
|
17
|
+
|
|
18
|
+
```text
|
|
19
|
+
inspect target=run:demo view=recipe
|
|
20
|
+
inspect target=run:demo view=trace source=lifecycle lines=40
|
|
21
|
+
inspect target=run:demo view=control lines=20
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
Run views require a current coordinator session and an exact, non-empty match between that session id and the Run's persisted owner. Possessing a `run:<id>` is not authorization. Missing coordinator identity, ownerless state, and cross-owner state fail closed.
|
|
25
|
+
|
|
26
|
+
- `recipe` returns captured generation-local Recipe, launch, policy, and artifact declarations.
|
|
27
|
+
- `trace` returns the bounded unified projection plus retained-history completeness. `source` accepts `all`, `lifecycle`, `control`, `process`, `agent`, `artifact`, or `runtime`; `lines` bounds returned rows.
|
|
28
|
+
- `control` returns endpoint readiness, declared and runtime-owned actions, pending capacity, saturation, stale work, diagnostics, and recent redacted records; `lines` bounds recent records.
|
|
29
|
+
|
|
30
|
+
Use the runtime inventory when a remembered Run id is inaccessible from the current session:
|
|
31
|
+
|
|
32
|
+
```text
|
|
33
|
+
inspect target=runtime view=runs
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## Runtime Targets
|
|
37
|
+
|
|
38
|
+
```text
|
|
39
|
+
inspect target=runtime view=status
|
|
40
|
+
inspect target=runtime view=runs
|
|
41
|
+
inspect target=runtime view=runs status=failed
|
|
42
|
+
inspect target=runtime view=triage
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
- `status` reports immutable package/runtime identity, state schema, and current automatic-review policy.
|
|
46
|
+
- `runs` returns the complete inventory owned by the current coordinator session; it is not paginated or capped by `lines`. Optional `status` filters that exact-owner inventory.
|
|
47
|
+
- `triage` aggregates the same exact-owner inventory into failed Runs, pending/stale Controls, backpressure, incomplete Trace diagnostics, and retained attention evidence.
|
|
48
|
+
|
|
49
|
+
Runtime inventory never broadens authorization and never returns ownerless or foreign Run state.
|
|
50
|
+
|
|
51
|
+
## Recipe Targets
|
|
52
|
+
|
|
53
|
+
```text
|
|
54
|
+
inspect target=recipes view=status
|
|
55
|
+
inspect target=recipes view=summary
|
|
56
|
+
inspect target=recipes view=doctor identity=music-player/playback
|
|
57
|
+
inspect target=recipes view=imports verbose=true
|
|
58
|
+
inspect target=recipes view=reviews verbose=true
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
- `status` reports registry/watch state, active/shadowed/invalid/disabled user Recipes, active Skill components, drafts, usage, and diagnostics.
|
|
62
|
+
- `summary` returns the compact discovery-oriented projection of the same current context.
|
|
63
|
+
- `doctor` diagnoses one canonical `<skill>/<recipe>` identity when `identity` is provided; without an identity it reports registry remediation evidence.
|
|
64
|
+
- `imports` exposes active Skill namespaces and component import inventory for resolution diagnosis.
|
|
65
|
+
- `reviews` exposes bounded automatic draft/tool review state and recovery guidance.
|
|
66
|
+
|
|
67
|
+
`identity` is accepted only with `view=doctor`. Skill inventory is fail-soft diagnostic evidence; exact launch and registration still resolve against the immutable active-session context.
|
|
68
|
+
|
|
69
|
+
## Tool Targets
|
|
70
|
+
|
|
71
|
+
```text
|
|
72
|
+
inspect target=tool:music_player view=status
|
|
73
|
+
inspect target=tool:music_player view=schema
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
- `status` separates persistence, registry admission, host registration, `callable_now`, activation boundary, source identity, and `tool_calls` versus `spawn_calls`.
|
|
77
|
+
- `schema` returns the currently callable description, parameter schema, and prompt snippet. It fails clearly when a definition is persisted but its live callable schema is unavailable.
|
|
78
|
+
|
|
79
|
+
A registered tool is a capability definition, not a Run. Tool status cannot substitute for Run inspection, and Recipe spawning cannot prove registered-tool invocation.
|
|
80
|
+
|
|
81
|
+
## Boundaries
|
|
82
|
+
|
|
83
|
+
Inspection is read-only, owner-filtered where Run state is involved, and redacted. Evidence-heavy Run, review, diagnostic, and text projections apply their documented bounds; `runtime view=runs` deliberately returns the complete matching exact-owner inventory. Inspection does not mutate journals, infer authority from displayed data, expose private active-Skill installation paths, or turn retained Trace into an audit archive. Use `message` for admitted runtime or actor-local actions.
|
|
@@ -80,7 +80,7 @@ Do not bulk-copy bundled Recipes into the user Recipe root. Internal `recipe-mem
|
|
|
80
80
|
npm run recipes:qa
|
|
81
81
|
```
|
|
82
82
|
|
|
83
|
-
Recipe QA recursively inventories direct Skill components and validates filesystem identity, syntax, imports, Control declarations, origin ownership, portable artifact paths, and `{skill_dir}` helper references. Nested files and JSON/Markdown stem collisions fail precisely. Recipe descriptions remain optional; QA requires zero capability diagnostics and zero warnings without enforcing style, documentation quotas, or architecture policy.
|
|
83
|
+
Recipe QA recursively inventories direct Skill components and validates filesystem identity, syntax, imports, Control declarations, origin ownership, portable artifact paths, and `{skill_dir}` helper references. Nested files and JSON/Markdown stem collisions fail precisely. Recipe descriptions remain optional; QA requires zero capability diagnostics and zero warnings without enforcing style, documentation quotas, or architecture policy. `mailbox` is not part of the current Recipe contract and fails validation.
|
|
84
84
|
|
|
85
85
|
## Related
|
|
86
86
|
|
|
@@ -1,27 +1,45 @@
|
|
|
1
|
-
# Template
|
|
1
|
+
# Template Recipe Standard
|
|
2
2
|
|
|
3
|
-
A Recipe
|
|
3
|
+
A Template Recipe is a file-backed, reusable command-template graph. It adds stable identity, typed inputs, composition, optional detached execution, artifacts, Control, and provenance around the portable [Command Template Standard](./command-templates.md).
|
|
4
4
|
|
|
5
|
-
##
|
|
5
|
+
## Mental Model
|
|
6
|
+
|
|
7
|
+
A Recipe has three layers:
|
|
8
|
+
|
|
9
|
+
1. **Recipe contract**: identity, description, arguments, defaults, imports, lifecycle, artifacts, and Control.
|
|
10
|
+
2. **Command-template graph**: the executable string, sequence, parallel fanout, conditions, retry, and output behavior stored in `template`.
|
|
11
|
+
3. **Run projection**: detached process state, Trace, Control delivery, artifacts, and inspection when `async: true`.
|
|
12
|
+
|
|
13
|
+
Use a Recipe when a command graph should be named, validated, reused, imported, registered as a tool, or launched as a Run. Use an inline command template when file identity and Recipe metadata add no value.
|
|
14
|
+
|
|
15
|
+
## File Formats
|
|
16
|
+
|
|
17
|
+
Recipes may be authored as JSON or Markdown. Both formats compile to the same Recipe contract.
|
|
18
|
+
|
|
19
|
+
### JSON
|
|
20
|
+
|
|
21
|
+
JSON is the most direct form for structured composition:
|
|
6
22
|
|
|
7
23
|
```json
|
|
8
24
|
{
|
|
9
|
-
"
|
|
10
|
-
"description": "Create a repository health artifact",
|
|
25
|
+
"description": "Create a repository health report",
|
|
11
26
|
"args": ["repo:path", "artifact_path:path", "model:string"],
|
|
12
|
-
"defaults": {
|
|
13
|
-
|
|
14
|
-
|
|
27
|
+
"defaults": {
|
|
28
|
+
"artifact_path": "{state_dir}/health.md"
|
|
29
|
+
},
|
|
30
|
+
"async": true,
|
|
31
|
+
"artifacts": {
|
|
32
|
+
"report": "{artifact_path}"
|
|
33
|
+
},
|
|
15
34
|
"template": {
|
|
16
|
-
"
|
|
17
|
-
"values": { "input": "Inspect {repo}", "model": "{model}" }
|
|
35
|
+
"template": "pi -p {repo} --model {model}"
|
|
18
36
|
}
|
|
19
37
|
}
|
|
20
38
|
```
|
|
21
39
|
|
|
22
|
-
|
|
40
|
+
### Markdown
|
|
23
41
|
|
|
24
|
-
Markdown
|
|
42
|
+
Markdown uses YAML frontmatter for the Recipe contract and one executable fence for `template`:
|
|
25
43
|
|
|
26
44
|
````markdown
|
|
27
45
|
---
|
|
@@ -30,142 +48,283 @@ args:
|
|
|
30
48
|
- file:path
|
|
31
49
|
---
|
|
32
50
|
|
|
33
|
-
Human notes
|
|
51
|
+
Human-facing notes may explain intent and usage.
|
|
34
52
|
|
|
35
53
|
```template
|
|
36
54
|
summarize {file}
|
|
37
55
|
```
|
|
38
56
|
````
|
|
39
57
|
|
|
40
|
-
|
|
58
|
+
Executable fences may be marked `template`, `command-template`, `json`, or `recipe`. Narrative Markdown outside the executable fence is advisory and is not executed.
|
|
59
|
+
|
|
60
|
+
Choose JSON for dense machine-oriented graphs. Choose Markdown when a short executable definition benefits from nearby human guidance.
|
|
61
|
+
|
|
62
|
+
## Identity and Placement
|
|
63
|
+
|
|
64
|
+
Recipe identity comes from its location and filename, never from a top-level `name` field.
|
|
65
|
+
|
|
66
|
+
| Placement | Identity | Typical use |
|
|
67
|
+
| --- | --- | --- |
|
|
68
|
+
| Direct file under an active Skill's `recipes/` directory | `<skill>/<filename-stem>` | Maintained Skill capability |
|
|
69
|
+
| Explicit `.json` or `.md` path | Resolved file path with filename-stem evidence | Local or project-specific composition |
|
|
70
|
+
| File under `~/.pi/agent/recipes` | Registered user tool identity | User-maintained reusable tool |
|
|
41
71
|
|
|
42
|
-
Skill Recipe
|
|
72
|
+
A Skill Recipe is one direct file under `<skill>/recipes/`. Nested files are not Skill components. The Skill name comes from its active `SKILL.md`; the Recipe stem comes from the direct filename.
|
|
43
73
|
|
|
44
|
-
|
|
74
|
+
A Recipe file must not declare top-level `name`. Within a command-template graph, a node-level `name` has a different purpose: it invokes an alias declared in `imports`.
|
|
45
75
|
|
|
46
|
-
|
|
76
|
+
## Recipe Field Reference
|
|
47
77
|
|
|
48
|
-
-
|
|
49
|
-
- `args`, typed arg declarations, inline defaults, `defaults`, and composition `values`;
|
|
50
|
-
- `imports` with optional binding defaults/values;
|
|
51
|
-
- `template`;
|
|
52
|
-
- `async`;
|
|
53
|
-
- `singleton: true` for one explicit Skill-owned async service slot;
|
|
54
|
-
- `artifacts`;
|
|
55
|
-
- `control` for actual controlled services;
|
|
56
|
-
- command-template flags such as `parallel`, `concurrency`, `min_successful`, `when`, `timeout`, `delay`, `retry`, `failure`, `recover`, `repeat`, `accept_output`, and `output`;
|
|
57
|
-
- `retire_when: "children_terminal"` for opt-in supervisor retirement.
|
|
78
|
+
The following fields belong to the file-level Recipe contract. Unless noted otherwise, each field is optional.
|
|
58
79
|
|
|
59
|
-
|
|
80
|
+
| Field | Type | Default | Contract |
|
|
81
|
+
| --- | --- | --- | --- |
|
|
82
|
+
| `description` | string | none | Human-facing purpose used by discovery and tool surfaces. Describe the outcome, not implementation history. |
|
|
83
|
+
| `disabled` | boolean | `false` | Prevents launch and import when `true`. Use it to make an authored Recipe intentionally unavailable without deleting the file. |
|
|
84
|
+
| `args` | string[] | inferred/untyped placeholders | Declares public inputs. Entries may be untyped (`input`), typed (`file:path`), enum-constrained (`mode:enum(check,fix)`), or include an inline default (`limit:int=10`). Names must be unique and agree with placeholder types. |
|
|
85
|
+
| `defaults` | object | `{}` | Supplies fallback values for declared inputs. A default may reference another placeholder and is resolved recursively with a depth bound. Every authored default must correspond to a declared argument. |
|
|
86
|
+
| `values` | object | `{}` | Binds composition values before executing the Recipe graph. Use for authored wiring between wrapper/import context and template nodes, not for caller-owned configuration. |
|
|
87
|
+
| `imports` | object | `{}` | Maps local aliases to other Recipes. Each value is a canonical Skill reference, explicit file path, or binding object with `from`, `defaults`, and/or `values`. Imports are resolved and validated before launch. |
|
|
88
|
+
| `template` | string, array, or command-template object | required | Defines the executable command-template graph. It may directly execute commands, compose nodes, invoke import aliases, or delegate to another Recipe. |
|
|
89
|
+
| `async` | boolean | `false` | Launches the Recipe as a detached Run when `true`. Detached execution owns durable state, Trace, terminal reconciliation, and optional Control/artifacts. |
|
|
90
|
+
| `singleton` | boolean | `false` | Gives one async Skill Recipe a stable `run:<skill>` service slot. Valid only with `async: true`; at most one singleton Recipe may belong to a Skill. |
|
|
91
|
+
| `artifacts` | object of string paths | `{}` | Declares named files produced by the Run. Paths support placeholders, resolve under containment policy, and appear in Run inspection. |
|
|
92
|
+
| `control` | string[] | `[]` | Declares actions consumed by an actual controlled service. Actions must be unique lowercase ASCII names, non-reserved, and at most 64 characters. |
|
|
93
|
+
| `retire_when` | `"children_terminal"` | none | Opts an async supervisor into retirement after all owned child Runs become terminal. Omit it for ordinary Run lifecycle. |
|
|
94
|
+
| `actor_context` | boolean or `"off"` | enabled | Controls injection of Recipe composition context into compatible child-agent prompts. Use `false` or `"off"` only when a deliberately minimal child prompt is required. |
|
|
95
|
+
|
|
96
|
+
### Value Resolution
|
|
97
|
+
|
|
98
|
+
For a declared name, effective values resolve in this order:
|
|
99
|
+
|
|
100
|
+
```text
|
|
101
|
+
caller values
|
|
102
|
+
→ node/import/Recipe values
|
|
103
|
+
→ defaults
|
|
104
|
+
→ inline argument default
|
|
105
|
+
→ missing-value error
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
The selected value is then validated against its declared type or enum. Runtime-provided origin values such as `{recipe_dir}` and `{skill_dir}` are immutable and cannot be declared or overridden through `args`, `defaults`, or `values`.
|
|
109
|
+
|
|
110
|
+
## Command-Template Fields
|
|
111
|
+
|
|
112
|
+
A Recipe may place command-template execution fields beside `template`, and any object node inside the graph may use the same fields. Their execution semantics are defined by the [Command Template Standard](./command-templates.md).
|
|
113
|
+
|
|
114
|
+
| Field | Type | Default | Purpose |
|
|
115
|
+
| --- | --- | --- | --- |
|
|
116
|
+
| `label` | string | none | Human-readable node label for diagnostics and branch reports. |
|
|
117
|
+
| `parallel` | boolean | `false` | Runs an array node concurrently instead of sequentially. |
|
|
118
|
+
| `concurrency` | positive integer or placeholder | unlimited | Caps simultaneous children of a parallel node. |
|
|
119
|
+
| `min_successful` | non-negative integer or placeholder | none | Requires a minimum count of successful branches with non-empty stdout. |
|
|
120
|
+
| `when` | boolean or expression | `true` | Skips the node when its guard resolves false. |
|
|
121
|
+
| `timeout` | milliseconds or placeholder | `0` / unbounded | Terminates an execution attempt after a positive duration. |
|
|
122
|
+
| `delay` | milliseconds or placeholder | `0` | Waits before starting the node. |
|
|
123
|
+
| `retry` | positive integer or placeholder | `1` | Sets total attempts, including the first attempt. |
|
|
124
|
+
| `failure` | `continue`, `branch`, or `root` | `continue` | Selects how a node failure propagates through composition. |
|
|
125
|
+
| `recover` | command template | none | Runs cleanup between failed attempts; a recovery failure ends retry. |
|
|
126
|
+
| `repeat` | non-negative integer or expression | none | Repeats a node, exposing the current index to placeholders. |
|
|
127
|
+
| `accept_output` | supported semantic contract | none | Applies fail-closed semantic validation to otherwise successful stdout. |
|
|
128
|
+
| `output` | string selector | `stdout` | Selects the result channel returned by the graph. |
|
|
129
|
+
|
|
130
|
+
Keep Recipe metadata at the file level and execution behavior near the node it controls. For object form, place `template` last so readers encounter contract and execution flags before executable content.
|
|
131
|
+
|
|
132
|
+
## Imports and Composition
|
|
133
|
+
|
|
134
|
+
Imports are local aliases within one resolved execution graph:
|
|
60
135
|
|
|
61
136
|
```json
|
|
62
137
|
{
|
|
138
|
+
"description": "Review and format one report",
|
|
139
|
+
"args": ["input:string", "thinking:string=medium"],
|
|
63
140
|
"imports": {
|
|
64
141
|
"review": "swarm/quorum-review",
|
|
65
|
-
"
|
|
142
|
+
"format": {
|
|
66
143
|
"from": "../shared/report.md",
|
|
67
|
-
"defaults": {
|
|
144
|
+
"defaults": {
|
|
145
|
+
"thinking": "{thinking}"
|
|
146
|
+
}
|
|
68
147
|
}
|
|
69
148
|
},
|
|
70
149
|
"template": [
|
|
71
|
-
{
|
|
72
|
-
|
|
150
|
+
{
|
|
151
|
+
"name": "review",
|
|
152
|
+
"values": {
|
|
153
|
+
"input": "{input}"
|
|
154
|
+
}
|
|
155
|
+
},
|
|
156
|
+
{
|
|
157
|
+
"name": "format",
|
|
158
|
+
"values": {
|
|
159
|
+
"input": "Use prior output"
|
|
160
|
+
}
|
|
161
|
+
}
|
|
73
162
|
]
|
|
74
163
|
}
|
|
75
164
|
```
|
|
76
165
|
|
|
77
|
-
|
|
166
|
+
### Accepted References
|
|
78
167
|
|
|
79
|
-
|
|
168
|
+
An import `from` value accepts exactly one of these forms:
|
|
80
169
|
|
|
81
|
-
|
|
170
|
+
| Form | Resolution |
|
|
171
|
+
| --- | --- |
|
|
172
|
+
| `<skill>/<recipe>` | One direct filename stem under the exact active Skill |
|
|
173
|
+
| `./file.json` or `../file.md` | Relative to the importing Recipe's directory |
|
|
174
|
+
| `/absolute/path/to/file.json` | Exact absolute file |
|
|
82
175
|
|
|
83
|
-
|
|
176
|
+
An entry Recipe path resolves from invocation `cwd`. A relative import resolves from the importing Recipe, not from invocation `cwd`. Bare ambient names and implicit fallback search are not part of the contract.
|
|
84
177
|
|
|
85
|
-
|
|
178
|
+
Duplicate active Skill names, duplicate JSON/Markdown stems, missing references, disabled targets, import cycles, and excessive import depth fail closed. A launched Run captures the resolved graph; later catalog changes affect future launches only.
|
|
86
179
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
180
|
+
### Import Bindings
|
|
181
|
+
|
|
182
|
+
A string import uses the target as authored:
|
|
183
|
+
|
|
184
|
+
```json
|
|
185
|
+
{ "review": "swarm/quorum-review" }
|
|
93
186
|
```
|
|
94
187
|
|
|
95
|
-
|
|
188
|
+
An object binding can supply alias-local defaults or values:
|
|
96
189
|
|
|
97
|
-
|
|
190
|
+
```json
|
|
191
|
+
{
|
|
192
|
+
"review": {
|
|
193
|
+
"from": "swarm/quorum-review",
|
|
194
|
+
"defaults": { "thinking": "medium" },
|
|
195
|
+
"values": { "mode": "strict" }
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
Use `defaults` when callers may override the value. Use `values` for authored composition wiring subject to the normal resolution order.
|
|
201
|
+
|
|
202
|
+
### Direct Delegation
|
|
203
|
+
|
|
204
|
+
A Recipe may use another Recipe as its entire template. The delegated Recipe remains authoritative while the wrapper may narrow public arguments, defaults, or selected lifecycle metadata. Singleton Run and Recipe identities remain owned by the delegated singleton; wrappers cannot create alternate service identities.
|
|
205
|
+
|
|
206
|
+
## Async Runs and Singleton Services
|
|
98
207
|
|
|
99
|
-
`
|
|
208
|
+
`async: true` changes execution from an inline result to a detached Run. The Run receives durable state, stdout/stderr evidence, Trace, generation identity, and terminal reconciliation.
|
|
100
209
|
|
|
101
|
-
|
|
210
|
+
A singleton Recipe additionally follows these rules:
|
|
211
|
+
|
|
212
|
+
- it must be a direct Recipe owned by one active Skill;
|
|
213
|
+
- it must declare `async: true`;
|
|
214
|
+
- one Skill may declare at most one singleton Recipe;
|
|
215
|
+
- its logical address is `run:<skill>`;
|
|
216
|
+
- a compatible repeated launch reuses the healthy active generation;
|
|
217
|
+
- conflicting Recipe identity, owner, startup values, or Control contract fails closed;
|
|
218
|
+
- terminal generations are never reused;
|
|
219
|
+
- singleton identity alone does not restore workload state after restart.
|
|
220
|
+
|
|
221
|
+
Use singleton only for a genuine long-lived Skill service. Ordinary jobs should remain non-singleton Runs.
|
|
102
222
|
|
|
103
223
|
## Control
|
|
104
224
|
|
|
105
|
-
|
|
225
|
+
Declare Control only when the launched process consumes actor-local input:
|
|
106
226
|
|
|
107
227
|
```json
|
|
108
228
|
{
|
|
229
|
+
"description": "Run a controllable service",
|
|
109
230
|
"async": true,
|
|
110
231
|
"control": ["pause", "resume", "stop"],
|
|
111
232
|
"template": "{skill_dir}/scripts/service.mjs --state-dir {state_dir}"
|
|
112
233
|
}
|
|
113
234
|
```
|
|
114
235
|
|
|
115
|
-
|
|
236
|
+
Control action names are lowercase ASCII, unique, non-reserved, and at most 64 characters. Serialized Control input is limited to 380 bytes so admitted wire records remain within 512 bytes on FIFO and named pipe transports.
|
|
237
|
+
|
|
238
|
+
Do not use Control as a general data channel. Large inputs belong in declared files or artifacts; outputs belong in Trace, artifacts, execution evidence, or the command result.
|
|
116
239
|
|
|
117
240
|
## Artifacts
|
|
118
241
|
|
|
242
|
+
Declare deterministic outputs by stable name:
|
|
243
|
+
|
|
119
244
|
```json
|
|
120
245
|
{
|
|
121
246
|
"artifacts": {
|
|
122
247
|
"report": "{state_dir}/report.md",
|
|
123
248
|
"manifest": "{state_dir}/manifest.json"
|
|
124
|
-
}
|
|
249
|
+
},
|
|
250
|
+
"template": "generate-report --output {state_dir}/report.md"
|
|
125
251
|
}
|
|
126
252
|
```
|
|
127
253
|
|
|
128
|
-
Artifact
|
|
129
|
-
|
|
130
|
-
## File Origins
|
|
131
|
-
|
|
132
|
-
Every file-backed Recipe receives immutable `{recipe_dir}`. A Recipe under an active Skill also receives `{skill_dir}`, resolved to the directory containing that Skill's `SKILL.md`; using `{skill_dir}` elsewhere fails clearly. These runtime values cannot be declared in `args`, `defaults`, or `values`, and caller input cannot override them. They expand in templates, recursive defaults/values, imports, and artifacts while existing `./` executable behavior remains relative to invocation `cwd`.
|
|
254
|
+
Artifact declarations do not create files. The Recipe must write them and fail when its write policy cannot be honored. Inspection reports declaration, availability, size, and digest evidence without treating undeclared arbitrary paths as public artifacts.
|
|
133
255
|
|
|
134
|
-
##
|
|
256
|
+
## Runtime Origins
|
|
135
257
|
|
|
136
|
-
|
|
258
|
+
Every file-backed Recipe receives immutable `{recipe_dir}`, the directory containing the Recipe file. A Recipe directly owned by an active Skill also receives `{skill_dir}`, the directory containing that Skill's `SKILL.md`.
|
|
137
259
|
|
|
138
|
-
|
|
260
|
+
| Placeholder | Availability | Meaning |
|
|
261
|
+
| --- | --- | --- |
|
|
262
|
+
| `{recipe_dir}` | every file-backed Recipe | Stable origin for Recipe-relative helpers and assets |
|
|
263
|
+
| `{skill_dir}` | active Skill-owned Recipe only | Stable origin for Skill-owned helpers and assets |
|
|
264
|
+
| `{state_dir}` | async Run context | Generation-local durable Run state directory |
|
|
265
|
+
| `{current_model}` | when current Pi policy is available | Current model inherited as an explicit resolved value |
|
|
266
|
+
| `{current_thinking}` | when current Pi policy is available | Current thinking policy inherited as an explicit resolved value |
|
|
139
267
|
|
|
140
|
-
|
|
268
|
+
Origin and policy placeholders expand through templates, recursive defaults/values, imports, and artifacts where applicable. Resolution fails before launch when a required runtime value is unavailable.
|
|
141
269
|
|
|
142
|
-
|
|
270
|
+
Example policy inheritance:
|
|
143
271
|
|
|
144
272
|
```json
|
|
145
273
|
{
|
|
274
|
+
"args": ["model:string", "thinking:string"],
|
|
146
275
|
"defaults": {
|
|
147
276
|
"model": "{current_model}",
|
|
148
277
|
"thinking": "{current_thinking}"
|
|
149
|
-
}
|
|
278
|
+
},
|
|
279
|
+
"template": "pi -p inspect --model {model} --thinking {thinking}"
|
|
150
280
|
}
|
|
151
281
|
```
|
|
152
282
|
|
|
153
|
-
|
|
283
|
+
## Context and Provenance
|
|
284
|
+
|
|
285
|
+
A file-backed launch captures generation-local records for the entry Recipe and every resolved import. Records include role, filename stem, logical reference, Skill identity when applicable, and import alias ancestry.
|
|
154
286
|
|
|
155
|
-
|
|
287
|
+
Logical identities are exposed to Inspector and child-agent context. Machine-local physical paths remain local execution provenance and are not promoted into model-facing launch values.
|
|
156
288
|
|
|
157
|
-
|
|
289
|
+
`actor_context` controls only compatible child-prompt injection:
|
|
158
290
|
|
|
159
|
-
|
|
291
|
+
```json
|
|
292
|
+
{
|
|
293
|
+
"actor_context": false,
|
|
294
|
+
"template": "pi -p minimal-task"
|
|
295
|
+
}
|
|
296
|
+
```
|
|
297
|
+
|
|
298
|
+
Disabling injected context does not remove Run provenance or change the authored task prompt.
|
|
299
|
+
|
|
300
|
+
## Authoring Checklist
|
|
301
|
+
|
|
302
|
+
1. Choose a direct Skill identity or explicit file location.
|
|
303
|
+
2. When useful, add one outcome-oriented `description`; descriptions are optional.
|
|
304
|
+
3. Declare every public input in `args`, including types where useful.
|
|
305
|
+
4. Put overridable fallback configuration in `defaults`.
|
|
306
|
+
5. Add imports only when composition earns a stable local alias.
|
|
307
|
+
6. Keep execution flags on the node they govern.
|
|
308
|
+
7. Use `async` only when detached lifecycle or durable evidence is required.
|
|
309
|
+
8. Declare `control` only for actions the process actually consumes.
|
|
310
|
+
9. Declare deterministic artifact paths before writing them.
|
|
311
|
+
10. Validate exact references, portable paths, and platform assumptions.
|
|
160
312
|
|
|
161
313
|
## Validation
|
|
162
314
|
|
|
315
|
+
Validate one Recipe:
|
|
316
|
+
|
|
163
317
|
```bash
|
|
164
318
|
node skills/actors/scripts/validate-recipe.mjs path/to/recipe.json --qa
|
|
319
|
+
```
|
|
320
|
+
|
|
321
|
+
Validate all maintained Skill Recipes:
|
|
322
|
+
|
|
323
|
+
```bash
|
|
165
324
|
node skills/actors/scripts/validate-recipe.mjs skills --skills --qa --summary
|
|
166
325
|
```
|
|
167
326
|
|
|
168
|
-
|
|
327
|
+
Validation checks file size, filename identity, JSON/Markdown compilation, argument contracts, imports, cycles and depth, runtime origins, Control, artifacts, portable paths, helper targets, and platform notes. Recipe files larger than 1 MiB and import graphs deeper than 32 levels fail closed.
|
|
169
328
|
|
|
170
329
|
## Related
|
|
171
330
|
|