pi-herdsman 0.1.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/LICENSE +84 -0
- package/README.md +171 -0
- package/SKILL.md +369 -0
- package/dist/agent-definitions/implementer.md +32 -0
- package/dist/agent-definitions/researcher.md +27 -0
- package/dist/agent-definitions/reviewer.md +30 -0
- package/dist/agent-definitions/scout.md +27 -0
- package/dist/agent-definitions/worker.md +31 -0
- package/dist/index.js +255 -0
- package/docs/README.md +104 -0
- package/docs/agent-api.md +103 -0
- package/docs/concepts/delegation.md +100 -0
- package/docs/concepts/lifecycle.md +149 -0
- package/docs/concepts/supervision.md +77 -0
- package/docs/concepts/workers.md +124 -0
- package/docs/development/documentation.md +175 -0
- package/docs/development/smoke-testing.md +293 -0
- package/docs/development/validation.md +124 -0
- package/docs/getting-started.md +168 -0
- package/docs/guides/agent-definitions.md +234 -0
- package/docs/guides/customizing-agents.md +238 -0
- package/docs/guides/handoffs.md +224 -0
- package/docs/guides/recovery.md +156 -0
- package/docs/reference/agent-definition-schema.md +272 -0
- package/docs/reference/ask-owner.md +133 -0
- package/docs/reference/commands.md +121 -0
- package/docs/reference/configuration.md +130 -0
- package/docs/reference/errors.md +87 -0
- package/docs/reference/status-widget.md +148 -0
- package/docs/reference/supervision.md +203 -0
- package/docs/reference/worker-states.md +57 -0
- package/docs/reference/worker.md +201 -0
- package/package.json +62 -0
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
# Handoffs and files
|
|
2
|
+
|
|
3
|
+
[Documentation index](../README.md)
|
|
4
|
+
|
|
5
|
+
Pi Herdsman has two text-file mechanisms with different purposes:
|
|
6
|
+
|
|
7
|
+
- `files` supplies evidence to delegate (definition or session), steer, reply,
|
|
8
|
+
or ask_owner.
|
|
9
|
+
- whole-line body `@file` references put definition-owned text into the worker
|
|
10
|
+
system prompt when a new worker generation is built.
|
|
11
|
+
|
|
12
|
+
Strict UTF-8 text is embedded when it fits; non-text and non-fitting files are
|
|
13
|
+
canonical local references and are not copied or snapshotted.
|
|
14
|
+
|
|
15
|
+
## Message `files`
|
|
16
|
+
|
|
17
|
+
For `delegate` with `definition`, `delegate` with `session`, `steer`, and
|
|
18
|
+
`reply`, pass supporting artifacts, including
|
|
19
|
+
applicable instruction or skill files, through `files` instead of mentioning
|
|
20
|
+
only their paths in the task or message; explain each file's relevance in the
|
|
21
|
+
accompanying text, and do not reattach skills already supplied by the selected
|
|
22
|
+
agent definition.
|
|
23
|
+
|
|
24
|
+
Example:
|
|
25
|
+
|
|
26
|
+
```json
|
|
27
|
+
{
|
|
28
|
+
"action": "delegate",
|
|
29
|
+
"definition": "reviewer",
|
|
30
|
+
"task": "Review the implementation against the approved plan.",
|
|
31
|
+
"files": [".pi-herdsman/plan.md", "/tmp/implementation-result"]
|
|
32
|
+
}
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
`files` is supported by `delegate` with `definition`, `delegate` with `session`,
|
|
36
|
+
`steer`, `reply`, and `ask_owner`. For
|
|
37
|
+
controller actions, relative paths resolve from the calling controller's cwd;
|
|
38
|
+
for `ask_owner`, they resolve from the managed worker's cwd. Every accepted
|
|
39
|
+
path is displayed using its canonical absolute path.
|
|
40
|
+
|
|
41
|
+
Supplied paths must resolve to readable regular files. Missing, broken,
|
|
42
|
+
unreadable, and non-regular paths reject the whole operation. Canonical
|
|
43
|
+
duplicates are represented once, with the first occurrence winning.
|
|
44
|
+
|
|
45
|
+
For `delegate` with `definition`, deterministic validation and known-input sizing happen
|
|
46
|
+
before mutation. The final durable envelope can be sized only after herdr
|
|
47
|
+
returns the authoritative pane ID; if the configured `mailboxPayloadLimitBytes`
|
|
48
|
+
is then exceeded, `delegate` with `definition` returns `invalid_request` without delivering a task and
|
|
49
|
+
rolls back the exact startup attempt (`rollbackOccurred: true` when
|
|
50
|
+
applicable).
|
|
51
|
+
|
|
52
|
+
For each regular file:
|
|
53
|
+
|
|
54
|
+
- complete strict UTF-8 text without NUL bytes is embedded when the complete
|
|
55
|
+
message fits the effective configured `mailboxPayloadLimitBytes` boundary;
|
|
56
|
+
- invalid UTF-8, NUL-containing, binary, and non-fitting files are represented
|
|
57
|
+
only by a canonical local path and observed byte size.
|
|
58
|
+
|
|
59
|
+
The fixed 1 MiB mailbox protocol safety ceiling is a separate read limit for
|
|
60
|
+
mailbox records; it does not replace the configured admission limit for new
|
|
61
|
+
messages.
|
|
62
|
+
|
|
63
|
+
No file is partially embedded. Embedded text is a submission-time snapshot.
|
|
64
|
+
Reference-only files are not copied or snapshotted; their contents may change
|
|
65
|
+
or disappear after submission, and the recipient must already have local
|
|
66
|
+
filesystem/tool access to inspect them. `files` supplies evidence and does not
|
|
67
|
+
grant runtime capabilities.
|
|
68
|
+
|
|
69
|
+
Files are read through their canonical `realpath` target.
|
|
70
|
+
|
|
71
|
+
## Canonical deduplication
|
|
72
|
+
|
|
73
|
+
Within any message's `files`, the first canonical occurrence wins.
|
|
74
|
+
|
|
75
|
+
These can therefore represent one attachment:
|
|
76
|
+
|
|
77
|
+
```text
|
|
78
|
+
./notes.md
|
|
79
|
+
/project/notes.md
|
|
80
|
+
./symlink-to-notes.md
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
when they resolve to the same physical canonical path. The same canonical path
|
|
84
|
+
in caller-supplied `delegate.files` also takes precedence over a definition body
|
|
85
|
+
`@file` reference, including when the caller file is reference-only.
|
|
86
|
+
|
|
87
|
+
Later duplicates are omitted.
|
|
88
|
+
|
|
89
|
+
## Body `@file` references
|
|
90
|
+
|
|
91
|
+
Inside an agent body, a line is a file reference only when the trimmed complete
|
|
92
|
+
line has one of these shapes:
|
|
93
|
+
|
|
94
|
+
```text
|
|
95
|
+
@./relative.md
|
|
96
|
+
@../relative.md
|
|
97
|
+
@/absolute/path.md
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
These remain literal text:
|
|
101
|
+
|
|
102
|
+
```text
|
|
103
|
+
@alice
|
|
104
|
+
Use @./policy.md when needed
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
Relative body references are resolved from the Markdown definition that
|
|
108
|
+
declared them **before** bundled/global body composition.
|
|
109
|
+
|
|
110
|
+
Expansion then happens once, in body order, when a new worker generation is
|
|
111
|
+
constructed.
|
|
112
|
+
|
|
113
|
+
Included file contents are not recursively parsed for more `@file` references.
|
|
114
|
+
|
|
115
|
+
## Cross-mechanism precedence
|
|
116
|
+
|
|
117
|
+
Caller assignment files win overlap with definition body references.
|
|
118
|
+
|
|
119
|
+
If the same canonical file appears in both:
|
|
120
|
+
|
|
121
|
+
```text
|
|
122
|
+
delegate.files
|
|
123
|
+
body @file
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
the assignment keeps its user-message copy and the body reference is omitted.
|
|
127
|
+
|
|
128
|
+
The combined rule is:
|
|
129
|
+
|
|
130
|
+
```text
|
|
131
|
+
duplicates inside delegate.files
|
|
132
|
+
→ first caller occurrence wins
|
|
133
|
+
|
|
134
|
+
duplicates inside body @file references
|
|
135
|
+
→ first body occurrence wins
|
|
136
|
+
|
|
137
|
+
same canonical file in both
|
|
138
|
+
→ caller attachment wins
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
## Immutable prompt transport
|
|
142
|
+
|
|
143
|
+
A definition body is expanded into text before worker lifecycle mutation.
|
|
144
|
+
|
|
145
|
+
The final expanded body and shared herdr worker guidance are written to private
|
|
146
|
+
temporary snapshots (`0600` files under private `0700` directories), passed to
|
|
147
|
+
Pi, and removed after the delegation attempt.
|
|
148
|
+
|
|
149
|
+
Original body source paths are never handed to Pi as system-prompt paths.
|
|
150
|
+
|
|
151
|
+
Each worker generation builds its system prompt once for its single assignment.
|
|
152
|
+
Session continuation builds a new generation with the current effective
|
|
153
|
+
definition configuration while preserving the saved Pi session context.
|
|
154
|
+
|
|
155
|
+
## Result handoff
|
|
156
|
+
|
|
157
|
+
Successful worker completion may expose a private `resultPath`.
|
|
158
|
+
|
|
159
|
+
For dependent work, pass the exact result path through `files` rather than
|
|
160
|
+
copying a large result manually:
|
|
161
|
+
|
|
162
|
+
```json
|
|
163
|
+
{
|
|
164
|
+
"action": "delegate",
|
|
165
|
+
"definition": "reviewer",
|
|
166
|
+
"task": "Review the implementation described in the supplied result.",
|
|
167
|
+
"files": ["/exact/resultPath"]
|
|
168
|
+
}
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
Successful worker completions persist their complete output at the canonical
|
|
172
|
+
`resultPath`; they do not receive a separate completion overflow path.
|
|
173
|
+
Oversized non-completion registered-tool output may additionally expose
|
|
174
|
+
`full_output_path` when overflow persistence succeeds. Model-visible content
|
|
175
|
+
remains bounded in both cases.
|
|
176
|
+
|
|
177
|
+
## Project-local coordination workspace
|
|
178
|
+
|
|
179
|
+
Use the project-local `.pi-herdsman/` directory for temporary coordination artifacts
|
|
180
|
+
used by agents working on the repository.
|
|
181
|
+
|
|
182
|
+
Typical contents include implementation plans, scope and non-goals,
|
|
183
|
+
specifications, accepted decisions, investigation notes, review scope or
|
|
184
|
+
acceptance criteria, validation notes, and handoff state.
|
|
185
|
+
|
|
186
|
+
Prefer one current artifact per coordinated objective. Reuse and update an
|
|
187
|
+
adequate artifact rather than creating multiple competing descriptions of the
|
|
188
|
+
same work.
|
|
189
|
+
|
|
190
|
+
Keep the default structure flat:
|
|
191
|
+
|
|
192
|
+
```
|
|
193
|
+
.pi-herdsman/
|
|
194
|
+
task.md
|
|
195
|
+
runtime-contract.md
|
|
196
|
+
plugin-remapping-ui.md
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
Create subdirectories only when real artifact volume makes the flat layout
|
|
200
|
+
unwieldy.
|
|
201
|
+
|
|
202
|
+
These files are coordination state, not product state. Do not use `.pi-herdsman/`
|
|
203
|
+
for product source, permanent user documentation, application data, build
|
|
204
|
+
output, caches, or generated artifacts.
|
|
205
|
+
|
|
206
|
+
Read-only workers may consume existing coordination artifacts but do not gain
|
|
207
|
+
permission to modify them.
|
|
208
|
+
|
|
209
|
+
When dependent work uses an artifact, pass the same path through `files` on the
|
|
210
|
+
message that creates or updates the dependency: `delegate.files` for a new
|
|
211
|
+
worker, `steer.files` for an active worker, `ask_owner.files` for supporting
|
|
212
|
+
evidence in a question, or `reply.files` for the owner's answer. Update the
|
|
213
|
+
artifact before submission. Small text is embedded at submission time; a
|
|
214
|
+
reference-only artifact remains a live canonical local path.
|
|
215
|
+
|
|
216
|
+
Required textual instructions or evidence may be passed through `files`.
|
|
217
|
+
`files` does not add runtime capability; use a capable definition when an
|
|
218
|
+
actual runtime capability is required.
|
|
219
|
+
|
|
220
|
+
## See also
|
|
221
|
+
|
|
222
|
+
- [`worker` API](../reference/worker.md)
|
|
223
|
+
- [Agent-definition schema](../reference/agent-definition-schema.md)
|
|
224
|
+
- [Delegation](../concepts/delegation.md)
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
# Recovery
|
|
2
|
+
|
|
3
|
+
[Documentation index](../README.md)
|
|
4
|
+
|
|
5
|
+
Recovery is identity-safe and conservative. Use the public state and returned
|
|
6
|
+
structured error before attempting another mutation.
|
|
7
|
+
|
|
8
|
+
## Worker is `blocked`
|
|
9
|
+
|
|
10
|
+
A blocked worker still has an active assignment.
|
|
11
|
+
|
|
12
|
+
If the worker is waiting for an owner answer, use `reply` with its exact worker.
|
|
13
|
+
|
|
14
|
+
Otherwise resolve the reported external/attention condition. Do not delegate new
|
|
15
|
+
task to a blocked worker.
|
|
16
|
+
|
|
17
|
+
## Worker is `settling`
|
|
18
|
+
|
|
19
|
+
`settling` means assignment convergence is incomplete. Typical causes include:
|
|
20
|
+
|
|
21
|
+
- task handoff acknowledgement;
|
|
22
|
+
- result delivery;
|
|
23
|
+
- bounded result-persistence recovery;
|
|
24
|
+
- delegating-worker/worker completion gating;
|
|
25
|
+
- launch handoff;
|
|
26
|
+
- one-shot cleanup.
|
|
27
|
+
|
|
28
|
+
Do not delegate another task yet.
|
|
29
|
+
|
|
30
|
+
If nothing independent remains, end the turn normally and let result/attention
|
|
31
|
+
delivery returns attention to the owner. Refresh `list` only when there is a reason to take
|
|
32
|
+
another control action.
|
|
33
|
+
|
|
34
|
+
If `list` reports `result_error`, the worker's result could not be persisted
|
|
35
|
+
after bounded retries. The condition retains the run, request, owner, worker,
|
|
36
|
+
and failure category. Do not delegate over it: resolve the mailbox persistence
|
|
37
|
+
problem, then close the exact worker before delegating new work. The condition
|
|
38
|
+
marks retry as unsafe and exact-owner cleanup as safe.
|
|
39
|
+
|
|
40
|
+
## Worker is `unknown`
|
|
41
|
+
|
|
42
|
+
`unknown` means the system cannot prove a safe control state from current exact
|
|
43
|
+
evidence.
|
|
44
|
+
|
|
45
|
+
Do not guess from pane IDs, process appearance, elapsed time, or stale metadata.
|
|
46
|
+
|
|
47
|
+
Refresh `list` and resolve the identity/lifecycle condition. If a cleanup or
|
|
48
|
+
recovery error is present, inspect its exact details.
|
|
49
|
+
|
|
50
|
+
## Inactivity advisory
|
|
51
|
+
|
|
52
|
+
A `working` worker with an exact active assignment can become advisory `stale`
|
|
53
|
+
after ten minutes without observed Pi turn, message, or tool activity.
|
|
54
|
+
|
|
55
|
+
Possible list fields:
|
|
56
|
+
|
|
57
|
+
- `stale: true`
|
|
58
|
+
- `inactive_ms`
|
|
59
|
+
- `last_activity_at`
|
|
60
|
+
|
|
61
|
+
This is not proof that the worker is hung, dead, safe to terminate, or safe to
|
|
62
|
+
replace.
|
|
63
|
+
|
|
64
|
+
Do not close solely because of inactivity.
|
|
65
|
+
|
|
66
|
+
## Startup failure
|
|
67
|
+
|
|
68
|
+
Fresh and historical-session delegation startup is bounded.
|
|
69
|
+
|
|
70
|
+
When herdr returns a structured failure, Pi Herdsman preserves it. When startup
|
|
71
|
+
returns empty or malformed output and no better structured error is available,
|
|
72
|
+
the implementation can capture one bounded exact-pane diagnostic snapshot
|
|
73
|
+
within the startup budget.
|
|
74
|
+
|
|
75
|
+
Failures report the known stage and identities when available.
|
|
76
|
+
|
|
77
|
+
Ownership-safe rollback removes only resources whose identity can be proved.
|
|
78
|
+
If ownership cannot be proved, cleanup intentionally fails closed and preserves
|
|
79
|
+
evidence.
|
|
80
|
+
|
|
81
|
+
Do not "fix" this by manually deleting guessed panes or mailboxes.
|
|
82
|
+
|
|
83
|
+
## `pane_not_ready`
|
|
84
|
+
|
|
85
|
+
A pane-readiness failure means the managed worker did not reach the required
|
|
86
|
+
safe startup boundary.
|
|
87
|
+
|
|
88
|
+
The normal response is to inspect the returned stage/diagnostic and the current
|
|
89
|
+
herdr environment. Do not add client-side polling or arbitrary sleeps as an
|
|
90
|
+
operator workaround.
|
|
91
|
+
|
|
92
|
+
## Cleanup or rollback failure
|
|
93
|
+
|
|
94
|
+
A `rollback_failure` can contain both:
|
|
95
|
+
|
|
96
|
+
- the primary launch/control failure;
|
|
97
|
+
- the cleanup failure.
|
|
98
|
+
|
|
99
|
+
Preserve both. The `nextAction` field may direct you to inspect cleanup evidence
|
|
100
|
+
before retrying.
|
|
101
|
+
|
|
102
|
+
A later attempt should not reuse a label or resource whose ownership is still
|
|
103
|
+
uncertain.
|
|
104
|
+
|
|
105
|
+
## Close failure
|
|
106
|
+
|
|
107
|
+
Normal `worker close` targets one exact directly owned live worker.
|
|
108
|
+
|
|
109
|
+
Closing a delegating worker cascades through its owned workers first. If a
|
|
110
|
+
worker cannot be proved or closed safely, the delegating worker remains rather
|
|
111
|
+
than being destructively guessed away.
|
|
112
|
+
|
|
113
|
+
For lead-only human emergency cleanup, `/workers stop` operates on the proven
|
|
114
|
+
owned tree and reports discarded active work or durable pending results. It is
|
|
115
|
+
not the normal model orchestration interface.
|
|
116
|
+
|
|
117
|
+
## Historical session failure
|
|
118
|
+
|
|
119
|
+
A `delegate` with `session` requires an exact session path or full UUID.
|
|
120
|
+
|
|
121
|
+
The saved session header must contain a non-empty working directory. Session
|
|
122
|
+
delegation uses that saved cwd and does not accept a caller-supplied `cwd`.
|
|
123
|
+
|
|
124
|
+
The saved agent-definition name is resolved against the current effective
|
|
125
|
+
definition roster. If it no longer exists, session delegation fails instead of guessing a
|
|
126
|
+
replacement. The definition must also be enabled and authorized for the current
|
|
127
|
+
controller, and its current effective configuration is used for the new worker
|
|
128
|
+
generation.
|
|
129
|
+
|
|
130
|
+
An exact session that is already represented by active or unresolved managed
|
|
131
|
+
work cannot be activated concurrently. The session-start exclusion applies to
|
|
132
|
+
the canonical session path, so an exact UUID and its exact path identify the
|
|
133
|
+
same target. Wait for the existing assignment to finish and clean up, or close
|
|
134
|
+
its exact live worker when abandoning it, then retry. Do not delegate another
|
|
135
|
+
task through a worker label.
|
|
136
|
+
|
|
137
|
+
## Before retrying
|
|
138
|
+
|
|
139
|
+
Check:
|
|
140
|
+
|
|
141
|
+
1. exact error category;
|
|
142
|
+
2. operation;
|
|
143
|
+
3. worker identity;
|
|
144
|
+
4. known pane/session IDs;
|
|
145
|
+
5. startup stage when present;
|
|
146
|
+
6. primary cause;
|
|
147
|
+
7. cleanup cause;
|
|
148
|
+
8. `rollbackOccurred`;
|
|
149
|
+
9. `nextAction`;
|
|
150
|
+
10. current `worker list`.
|
|
151
|
+
|
|
152
|
+
## See also
|
|
153
|
+
|
|
154
|
+
- [Errors](../reference/errors.md)
|
|
155
|
+
- [Worker states](../reference/worker-states.md)
|
|
156
|
+
- [Workers and identity](../concepts/workers.md)
|
|
@@ -0,0 +1,272 @@
|
|
|
1
|
+
# Agent-definition schema
|
|
2
|
+
|
|
3
|
+
[Documentation index](../README.md)
|
|
4
|
+
|
|
5
|
+
This page is the canonical public schema for Markdown agent definitions.
|
|
6
|
+
|
|
7
|
+
## File format
|
|
8
|
+
|
|
9
|
+
A definition requires frontmatter beginning on the first line and a closing
|
|
10
|
+
frontmatter delimiter:
|
|
11
|
+
|
|
12
|
+
```markdown
|
|
13
|
+
---
|
|
14
|
+
name: scout
|
|
15
|
+
thinking: medium
|
|
16
|
+
tools: ["read", "bash"]
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
Prompt body.
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
Known string arrays use inline JSON arrays. YAML block sequences are not
|
|
23
|
+
supported.
|
|
24
|
+
|
|
25
|
+
Unknown frontmatter fields fail validation.
|
|
26
|
+
|
|
27
|
+
Malformed files fail discovery; Pi Herdsman does not silently drop one invalid
|
|
28
|
+
definition and return a partial roster.
|
|
29
|
+
|
|
30
|
+
## Sources and precedence
|
|
31
|
+
|
|
32
|
+
Bundled definitions:
|
|
33
|
+
|
|
34
|
+
```text
|
|
35
|
+
dist/agent-definitions/
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
Global definitions by default:
|
|
39
|
+
|
|
40
|
+
```text
|
|
41
|
+
~/.pi/agent/agents/
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
A matching project or global name overlays the lower-precedence definition.
|
|
45
|
+
|
|
46
|
+
An unmatched project or global definition is standalone. Project definitions
|
|
47
|
+
are loaded from `<cwd>/.pi/agents/` only when trusted project settings set
|
|
48
|
+
`piHerdsman.projectAgents` to `true`. Precedence is `bundled < project < global`.
|
|
49
|
+
|
|
50
|
+
All effective definitions are sorted and validated together, including every
|
|
51
|
+
`workers` reference.
|
|
52
|
+
|
|
53
|
+
`enabled` controls definition availability. A disabled definition remains in the
|
|
54
|
+
lead roster so it can be enabled again, but owner-visible definition lists omit
|
|
55
|
+
it. Definition and session delegations reject a disabled definition. An already
|
|
56
|
+
active worker may finish and remains controllable according to its current
|
|
57
|
+
available actions; disabling a definition does not mutate that assignment.
|
|
58
|
+
|
|
59
|
+
## Fields
|
|
60
|
+
|
|
61
|
+
| Field | Accepted value | Omitted/default behavior | Runtime/composition behavior |
|
|
62
|
+
| ----------------------- | --------------------------------------------------------------------- | ----------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------ |
|
|
63
|
+
| `name` | non-empty string | required | Effective definition identity. |
|
|
64
|
+
| `enabled` | boolean | `true` | `false` makes definition and session delegation unavailable; it does not mutate an active worker. |
|
|
65
|
+
| `description` | string | absent | Display/selection description. |
|
|
66
|
+
| `model` | non-empty string | Pi default/current launch behavior | Passed as Pi model selection. |
|
|
67
|
+
| `thinking` | `off`, `minimal`, `low`, `medium`, `high`, `xhigh`, `max`, or `false` | Pi default/current launch behavior | `false` launches as `off`. |
|
|
68
|
+
| `systemPromptMode` | `append` or `replace` | `append` only for definition name `delegate`; otherwise `replace` | Controls effective body versus Pi base system prompt. |
|
|
69
|
+
| `bodyMode` | `append` or `replace` | `replace` for non-empty matching overlay body | Valid only when overlaying an existing lower-precedence definition; consumed during body composition. |
|
|
70
|
+
| `noTools` | boolean | Pi normal tool policy | `true` emits `--no-tools`; managed `ask_owner` remains infrastructure. |
|
|
71
|
+
| `noBuiltinTools` | boolean | Pi normal built-in tool policy | `true` emits `--no-builtin-tools`. |
|
|
72
|
+
| `tools` | inline array of non-empty strings | no explicit allowlist | Passed to Pi as a source-agnostic tool-name allowlist; matching overlay replaces whole array. |
|
|
73
|
+
| `excludeTools` | inline array of non-empty strings | no explicit exclusions | Passed to Pi as source-agnostic tool-name exclusions; matching override replaces whole array. |
|
|
74
|
+
| `noSkills` | boolean | skills disabled unless `inheritSkills: true` | Controls Pi native skill discovery; explicit `skills` values are still passed separately. |
|
|
75
|
+
| `inheritSkills` | boolean | does not enable by itself unless `true` | `true` changes omitted `noSkills` default so native skills remain available. Explicit `noSkills` wins. |
|
|
76
|
+
| `skills` | inline array of non-empty strings | no explicit skill arguments | Each value is passed unchanged as a Pi skill path/resource. |
|
|
77
|
+
| `noExtensions` | boolean | Pi normal extension policy | `true` emits `--no-extensions`. Required herdr worker infrastructure remains injected by the launcher. |
|
|
78
|
+
| `extensions` | inline array of non-empty strings | no extra extension arguments | Each value is passed unchanged to Pi. |
|
|
79
|
+
| `workers` | inline array of unique non-empty definition names | no direct workers | Names direct definitions this worker may delegate to; every name must exist. |
|
|
80
|
+
| `inheritProjectContext` | boolean | `true` only for definition name `delegate`; otherwise `false` | Controls project context-file inheritance. |
|
|
81
|
+
| `inheritGlobalContext` | boolean | follows effective `inheritProjectContext` | Controls global context-file inheritance. |
|
|
82
|
+
|
|
83
|
+
Arrays supplied by an override replace the complete inherited array, including
|
|
84
|
+
an explicit `[]`.
|
|
85
|
+
|
|
86
|
+
When a delegating worker declares a worker in `workers`, that worker must be enabled.
|
|
87
|
+
A delegating worker referencing a disabled worker can remain discoverable, but is rejected
|
|
88
|
+
during assignment or fresh worker startup with an explicit disabled-worker error
|
|
89
|
+
rather than being silently removed from the delegating worker definition.
|
|
90
|
+
|
|
91
|
+
Skill and extension paths are passed to Pi unchanged. herdr does not resolve
|
|
92
|
+
them relative to the definition file.
|
|
93
|
+
|
|
94
|
+
Tool names are governed by Pi's native name-based policy, regardless of
|
|
95
|
+
whether a tool is built in, registered by an extension, or supplied as a
|
|
96
|
+
custom/SDK tool. When both fields apply, an exclusion wins over an allowlist.
|
|
97
|
+
Names do not need to exist when a definition is discovered: unknown names are
|
|
98
|
+
accepted and can match a tool registered later. Pi Herdsman does not provide
|
|
99
|
+
source-qualified permissions, such as an extension path plus tool name.
|
|
100
|
+
|
|
101
|
+
An explicit `tools` allowlist takes precedence over the default-selection
|
|
102
|
+
switches `noTools` and `noBuiltinTools`; `excludeTools` still removes matching
|
|
103
|
+
names. Thus a managed worker may receive both `--no-tools` and an explicit
|
|
104
|
+
`--tools ask_owner`. Pi Herdsman protects that mandatory `ask_owner` capability in
|
|
105
|
+
managed launches and removes it from explicit exclusions. Unmanaged Pi
|
|
106
|
+
launches do not receive this exception.
|
|
107
|
+
|
|
108
|
+
Loading extension code and exposing its tools are separate concerns. An
|
|
109
|
+
extension listed in `extensions` is loaded, while its registered tools still
|
|
110
|
+
must pass `tools` and `excludeTools` to be model-callable. Tool filtering is
|
|
111
|
+
not extension sandboxing: loaded extensions may still run handlers, commands,
|
|
112
|
+
shortcuts, providers, initialization, and other non-tool behavior.
|
|
113
|
+
|
|
114
|
+
Pi's native tool policy is the callable boundary verified for the documented
|
|
115
|
+
integration. A provider or conversion integration may add its own presentation
|
|
116
|
+
layer, so provider-visible tool descriptions should not be treated as a Pi
|
|
117
|
+
Herdsman permission registry or as proof that extension code is sandboxed. Pi Herdsman
|
|
118
|
+
passes the native policy through; it does not independently guarantee every
|
|
119
|
+
provider presentation boundary.
|
|
120
|
+
|
|
121
|
+
Tools with the same name are not independently permissionable by source, and
|
|
122
|
+
the winner for a name collision is not a supported ordering contract.
|
|
123
|
+
|
|
124
|
+
`noExtensions` disables ordinary extension discovery, but launcher-injected
|
|
125
|
+
Pi Herdsman worker and Herdr-state extensions remain mandatory infrastructure.
|
|
126
|
+
Explicit `extensions` entries remain separate launch inputs and are passed to
|
|
127
|
+
Pi normally. Launcher-injected infrastructure remains separate from the
|
|
128
|
+
definition's extension and tool policy.
|
|
129
|
+
|
|
130
|
+
## Tool inference for `workers`
|
|
131
|
+
|
|
132
|
+
A non-empty `workers` list declares potential worker definitions; effective
|
|
133
|
+
delegation also requires permitted `worker` capability and a controller depth
|
|
134
|
+
that allows delegation.
|
|
135
|
+
|
|
136
|
+
This capability is projected by controller depth. Lead-launched definitions
|
|
137
|
+
retain their declared worker allowlist and effective `worker` tool. A
|
|
138
|
+
worker-launched worker receives no worker allowlist and no effective `worker`,
|
|
139
|
+
even when its definition is delegation-enabled at the lead. Explicit tool
|
|
140
|
+
allowlists, empty arrays, `noTools`, and exclusions remain fail-closed.
|
|
141
|
+
|
|
142
|
+
When it has an explicit non-empty `tools` allowlist and does not already contain
|
|
143
|
+
`worker`, Pi Herdsman appends `worker` to the effective allowlist unless denied.
|
|
144
|
+
|
|
145
|
+
Rules:
|
|
146
|
+
|
|
147
|
+
| Configuration | Effective inference |
|
|
148
|
+
| ------------------------------------------------ | ------------------------------------------------------------------------- |
|
|
149
|
+
| `workers` omitted or `[]` | no inferred `worker` |
|
|
150
|
+
| non-empty `workers`, `tools` omitted | keep Pi default tool policy; do not materialize a `worker`-only allowlist |
|
|
151
|
+
| non-empty `workers`, explicit non-empty `tools` | append `worker` |
|
|
152
|
+
| `excludeTools` contains `worker` | explicit denial wins |
|
|
153
|
+
| `noTools: true`, no explicit `worker` in `tools` | no inferred `worker` |
|
|
154
|
+
| `noTools: true`, explicit `tools: ["worker"]` | explicit allow is preserved |
|
|
155
|
+
| explicit allow plus explicit exclusion | exclusion wins |
|
|
156
|
+
|
|
157
|
+
`ask_owner` is separate mandatory managed-worker infrastructure and is not this
|
|
158
|
+
inference rule.
|
|
159
|
+
|
|
160
|
+
## Body composition
|
|
161
|
+
|
|
162
|
+
The body is text after the closing `---`, trimmed at its outer boundaries.
|
|
163
|
+
|
|
164
|
+
For matching project and global overlays:
|
|
165
|
+
|
|
166
|
+
```text
|
|
167
|
+
empty overlay body
|
|
168
|
+
→ lower-layer body
|
|
169
|
+
|
|
170
|
+
non-empty overlay body, bodyMode omitted/replace
|
|
171
|
+
→ overlay body
|
|
172
|
+
|
|
173
|
+
non-empty overlay body, bodyMode append
|
|
174
|
+
→ lower-layer body + "\n\n" + overlay body
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
Standalone definitions cannot declare `bodyMode`.
|
|
178
|
+
|
|
179
|
+
## Body file references
|
|
180
|
+
|
|
181
|
+
A body line is a reference only when the complete trimmed line matches:
|
|
182
|
+
|
|
183
|
+
```text
|
|
184
|
+
@./relative/path
|
|
185
|
+
@../relative/path
|
|
186
|
+
@/absolute/path
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
Before bundled/global body composition, relative references are resolved from
|
|
190
|
+
the definition file that declared them.
|
|
191
|
+
|
|
192
|
+
When a new worker generation is constructed:
|
|
193
|
+
|
|
194
|
+
1. references are processed in body order;
|
|
195
|
+
2. targets are canonicalized with `realpath`;
|
|
196
|
+
3. each canonical file is included once;
|
|
197
|
+
4. a caller `delegate.files` canonical overlap wins and removes the body copy;
|
|
198
|
+
5. each accepted source must be a bounded readable regular UTF-8 file without
|
|
199
|
+
NUL bytes;
|
|
200
|
+
6. included text replaces that reference line;
|
|
201
|
+
7. included text is not recursively expanded.
|
|
202
|
+
|
|
203
|
+
Every new worker generation expands the effective body and its file references
|
|
204
|
+
once at launch. Session continuation preserves the Pi session history while
|
|
205
|
+
using the current effective definition configuration.
|
|
206
|
+
|
|
207
|
+
## Runtime prompt order
|
|
208
|
+
|
|
209
|
+
For a newly constructed managed worker, the effective launch composition is:
|
|
210
|
+
|
|
211
|
+
```text
|
|
212
|
+
Pi base system prompt
|
|
213
|
+
↓ effective body via systemPromptMode
|
|
214
|
+
selected project/global context-file additions
|
|
215
|
+
↓
|
|
216
|
+
shared herdr worker guidance
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
The final effective body and shared guidance are delivered through private
|
|
220
|
+
temporary prompt snapshots.
|
|
221
|
+
|
|
222
|
+
## Complete override example
|
|
223
|
+
|
|
224
|
+
```markdown
|
|
225
|
+
---
|
|
226
|
+
name: reviewer
|
|
227
|
+
description: Review implementation changes
|
|
228
|
+
model: openai-codex/gpt-5.6-luna
|
|
229
|
+
thinking: high
|
|
230
|
+
bodyMode: append
|
|
231
|
+
systemPromptMode: replace
|
|
232
|
+
noTools: false
|
|
233
|
+
noBuiltinTools: false
|
|
234
|
+
tools: ["read", "bash"]
|
|
235
|
+
excludeTools: []
|
|
236
|
+
noSkills: false
|
|
237
|
+
inheritSkills: true
|
|
238
|
+
skills: ["/absolute/path/to/code-review/SKILL.md"]
|
|
239
|
+
noExtensions: false
|
|
240
|
+
extensions: ["/absolute/path/to/local-extension.ts"]
|
|
241
|
+
workers: ["scout"]
|
|
242
|
+
inheritProjectContext: true
|
|
243
|
+
inheritGlobalContext: false
|
|
244
|
+
---
|
|
245
|
+
|
|
246
|
+
Additional local review instructions.
|
|
247
|
+
|
|
248
|
+
@./prompts/review-policy.md
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
Because `workers` is non-empty and the explicit `tools` list does not deny it,
|
|
252
|
+
the effective tools include `worker`.
|
|
253
|
+
|
|
254
|
+
To disable a bundled role without copying its definition, use a minimal global
|
|
255
|
+
override:
|
|
256
|
+
|
|
257
|
+
```markdown
|
|
258
|
+
---
|
|
259
|
+
name: reviewer
|
|
260
|
+
enabled: false
|
|
261
|
+
---
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
The `/workers agents` menu exposes the same enable and disable operations.
|
|
265
|
+
Removing the `enabled` line inherits the bundled value; when no source declares
|
|
266
|
+
the field, the effective value is `true`.
|
|
267
|
+
|
|
268
|
+
## See also
|
|
269
|
+
|
|
270
|
+
- [Customizing bundled agents](../guides/customizing-agents.md)
|
|
271
|
+
- [Handoffs and files](../guides/handoffs.md)
|
|
272
|
+
- [Delegation](../concepts/delegation.md)
|