pi-herdsman 0.26.0 → 0.27.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/SKILL.md +3 -7
- package/dist/agent-definitions/generalist.md +2 -2
- package/dist/agent-definitions/reviewer.md +6 -1
- package/dist/index.js +69 -49
- package/dist/index.js.map +2 -2
- package/docs/concepts/coordination.md +4 -1
- package/docs/development/instruction-interface-design.md +12 -0
- package/docs/development/smoke-testing.md +22 -17
- package/docs/development/validation.md +5 -3
- package/docs/guides/agent-definitions.md +34 -13
- package/docs/reference/agent-definition-schema.md +11 -7
- package/docs/reference/agent.md +34 -9
- package/docs/reference/commands.md +5 -2
- package/package.json +10 -10
- package/skills/agent-definitions/SKILL.md +24 -11
package/SKILL.md
CHANGED
|
@@ -140,7 +140,7 @@ embedded text is snapshotted at submission time while referenced files are not
|
|
|
140
140
|
copied.
|
|
141
141
|
|
|
142
142
|
Pass relevant files and completed agent results through `files`. Agent
|
|
143
|
-
completions may expose reusable refs
|
|
143
|
+
completions may expose reusable result refs. When later
|
|
144
144
|
work or coordination depends on a completed direct-agent result, copy its exact
|
|
145
145
|
ref into `files` instead of restating or summarizing its evidence. Do not attach
|
|
146
146
|
unrelated results.
|
|
@@ -227,10 +227,6 @@ truth. Read-only roles may read these artifacts but must not modify them.
|
|
|
227
227
|
Do not silently broaden scope or make an unapproved scope, architecture,
|
|
228
228
|
security, protocol, repository-boundary, product, or operational decision.
|
|
229
229
|
|
|
230
|
-
Managed agents' direct Pi built-in bash and powershell calls without an explicit
|
|
231
|
-
timeout are capped at 600 seconds. Supply a longer explicit timeout only when a
|
|
232
|
-
command is intentionally expected to exceed that horizon.
|
|
233
|
-
|
|
234
230
|
Use ask_owner only when a decision from your exact direct owner is genuinely
|
|
235
231
|
required to continue correctly. ask_owner may include files for supporting
|
|
236
232
|
evidence; complete strict UTF-8 text may be embedded and other files remain
|
|
@@ -296,8 +292,8 @@ escalation.
|
|
|
296
292
|
|
|
297
293
|
## Handoffs
|
|
298
294
|
|
|
299
|
-
Use `files` for ordinary files and reusable direct-agent result refs
|
|
300
|
-
|
|
295
|
+
Use `files` for ordinary files and reusable direct-agent result refs.
|
|
296
|
+
Copy the exact ref shown by the completion when later
|
|
301
297
|
work depends on that result instead of restating or summarizing its evidence.
|
|
302
298
|
Also use `files` for canonical `result:<request-id>` references already
|
|
303
299
|
supplied as file evidence; preserve those references exactly and do not
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
agents: [scout, researcher]
|
|
3
|
-
description: General-purpose execution agent for
|
|
3
|
+
description: General-purpose execution agent for bounded tasks requiring broad capabilities
|
|
4
4
|
extensions: []
|
|
5
5
|
inheritGlobalContext: false
|
|
6
6
|
inheritProjectContext: true
|
|
@@ -13,7 +13,7 @@ tools: [read, bash, edit, write]
|
|
|
13
13
|
---
|
|
14
14
|
|
|
15
15
|
You are generalist, a general-purpose execution agent for one explicitly assigned
|
|
16
|
-
task
|
|
16
|
+
bounded task.
|
|
17
17
|
|
|
18
18
|
Read relevant source material before acting, follow project patterns, perform
|
|
19
19
|
the smallest complete action, and verify it with the strongest practical checks.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
agents: [scout, researcher]
|
|
3
|
-
description: Independent read-only reviewer for plans, diffs, implementations, and codebase health; use
|
|
3
|
+
description: Independent read-only internal team reviewer for plans, diffs, implementations, and codebase health; use for verification, missing cases, and regressions, not user or supervisor approval
|
|
4
4
|
extensions: []
|
|
5
5
|
inheritGlobalContext: false
|
|
6
6
|
inheritProjectContext: true
|
|
@@ -15,6 +15,11 @@ tools: [read, ls, find, grep]
|
|
|
15
15
|
You are reviewer, a disciplined, strictly read-only review agent. Preserve
|
|
16
16
|
independent judgment: supplied findings are evidence, not conclusions.
|
|
17
17
|
|
|
18
|
+
You conduct internal reviews for the team that assigned your work.
|
|
19
|
+
Your findings inform your direct owner's decisions, not user or supervisor
|
|
20
|
+
approval. When assessing external feedback, preserve its origin; do not
|
|
21
|
+
present your own findings as that source's review or sign-off.
|
|
22
|
+
|
|
18
23
|
Independently verify findings that determine your conclusions.
|
|
19
24
|
|
|
20
25
|
Review the assigned artifact for correctness, missing cases, regressions,
|
package/dist/index.js
CHANGED
|
@@ -15,7 +15,7 @@ import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
|
15
15
|
// package.json
|
|
16
16
|
var package_default = {
|
|
17
17
|
name: "pi-herdsman",
|
|
18
|
-
version: "0.
|
|
18
|
+
version: "0.27.0",
|
|
19
19
|
type: "module",
|
|
20
20
|
description: "Asynchronous Pi subagents and agent fleet orchestration for parallel coding agents with nested delegation, background work, and supervision in herdr.",
|
|
21
21
|
license: "Apache-2.0",
|
|
@@ -64,14 +64,14 @@ var package_default = {
|
|
|
64
64
|
},
|
|
65
65
|
piHerdsman: {
|
|
66
66
|
runtime: {
|
|
67
|
-
pi: "1.
|
|
67
|
+
pi: "1.2.0",
|
|
68
68
|
herdr: {
|
|
69
|
-
version: "0.9.
|
|
69
|
+
version: "0.9.5",
|
|
70
70
|
sha256: {
|
|
71
|
-
"linux-x86_64": "
|
|
72
|
-
"linux-aarch64": "
|
|
73
|
-
"macos-x86_64": "
|
|
74
|
-
"macos-aarch64": "
|
|
71
|
+
"linux-x86_64": "14d9e8bc8b4a9e0118d77c32266f76d461f09b40342eb23752960bd89f59929d",
|
|
72
|
+
"linux-aarch64": "17d7536f2da50859523680ef279dffcac8e4a235f4e46fe8da6c2ec44141897c",
|
|
73
|
+
"macos-x86_64": "5fb0a908ec7f6745e3e245738b06bfad56c46391c391ab3c0955fbead01f1369",
|
|
74
|
+
"macos-aarch64": "fb77c2232a05a8035421382c894392f4174e4e38a18e48af3dd0290157c3a7e2"
|
|
75
75
|
}
|
|
76
76
|
}
|
|
77
77
|
}
|
|
@@ -96,9 +96,9 @@ var package_default = {
|
|
|
96
96
|
typebox: "*"
|
|
97
97
|
},
|
|
98
98
|
devDependencies: {
|
|
99
|
-
"@earendil-works/pi-ai": "1.
|
|
100
|
-
"@earendil-works/pi-coding-agent": "1.
|
|
101
|
-
"@earendil-works/pi-tui": "1.
|
|
99
|
+
"@earendil-works/pi-ai": "1.2.0",
|
|
100
|
+
"@earendil-works/pi-coding-agent": "1.2.0",
|
|
101
|
+
"@earendil-works/pi-tui": "1.2.0",
|
|
102
102
|
"@howaboua/pi-codex-conversion": "3.0.45",
|
|
103
103
|
esbuild: "^0.28.2",
|
|
104
104
|
prettier: "3.9.10",
|
|
@@ -1637,7 +1637,7 @@ function markdownFiles(root2) {
|
|
|
1637
1637
|
return readdirSync4(root2, { withFileTypes: true }).flatMap((entry) => {
|
|
1638
1638
|
const path = join4(root2, entry.name);
|
|
1639
1639
|
if (entry.isDirectory()) return markdownFiles(path);
|
|
1640
|
-
return entry.isFile() && entry.name.endsWith(".md") ? [path] : [];
|
|
1640
|
+
return (entry.isFile() || entry.isSymbolicLink()) && entry.name.endsWith(".md") ? [path] : [];
|
|
1641
1641
|
});
|
|
1642
1642
|
}
|
|
1643
1643
|
function readAgentDefinitions(root2) {
|
|
@@ -5146,22 +5146,28 @@ function toolNames(v) {
|
|
|
5146
5146
|
);
|
|
5147
5147
|
}
|
|
5148
5148
|
function formatTools(definition) {
|
|
5149
|
-
|
|
5150
|
-
const
|
|
5151
|
-
const
|
|
5149
|
+
if (typeof definition.tools === "string") return definition.tools;
|
|
5150
|
+
const hasExplicitTools = Array.isArray(definition.tools);
|
|
5151
|
+
const tools = toolNames(definition.tools).filter((tool) => tool !== "agent");
|
|
5152
|
+
const excluded = toolNames(definition.excludeTools);
|
|
5152
5153
|
if (hasExplicitTools) {
|
|
5153
|
-
const selected = tools.filter(
|
|
5154
|
-
|
|
5154
|
+
const selected = tools.filter(
|
|
5155
|
+
(tool) => tool.includes("*") ? !excluded.includes(tool) && !excluded.includes("*") : !excluded.some((pattern) => matchesToolPattern(pattern, tool))
|
|
5156
|
+
);
|
|
5157
|
+
if (!selected.length) return "none";
|
|
5158
|
+
const summary = selected.join(", ");
|
|
5159
|
+
return selected.some((tool) => tool.includes("*")) && excluded.length ? `${summary} except ${excluded.join(", ")}` : summary;
|
|
5155
5160
|
}
|
|
5156
5161
|
if (definition.noTools === true) return "none";
|
|
5157
|
-
const
|
|
5158
|
-
return
|
|
5162
|
+
const baseline = definition.noBuiltinTools === true ? "default without built-ins" : "default";
|
|
5163
|
+
return excluded.length ? `${baseline} except ${excluded.join(", ")}` : baseline;
|
|
5159
5164
|
}
|
|
5160
5165
|
function formatSkills(definition) {
|
|
5166
|
+
if (typeof definition.skills === "string") return definition.skills;
|
|
5161
5167
|
const skills = names(definition.skills);
|
|
5162
5168
|
const discovered = definition.noSkills === false || definition.noSkills === void 0 && definition.inheritSkills === true;
|
|
5163
5169
|
if (!discovered) return skills.length ? skills.join(", ") : "none";
|
|
5164
|
-
return skills.length ? `
|
|
5170
|
+
return skills.length ? `native discovery + ${skills.join(", ")}` : "native discovery";
|
|
5165
5171
|
}
|
|
5166
5172
|
function formatAgentDefinitions(definitions) {
|
|
5167
5173
|
return definitions.flatMap((definition) => {
|
|
@@ -5205,7 +5211,7 @@ function humanTools(definition) {
|
|
|
5205
5211
|
const formatted = formatTools(definition);
|
|
5206
5212
|
if (formatted === "default") return void 0;
|
|
5207
5213
|
if (formatted !== "none") return formatted;
|
|
5208
|
-
const intentionalRestriction = definition.noTools === true || Array.isArray(definition.tools)
|
|
5214
|
+
const intentionalRestriction = definition.noTools === true || Array.isArray(definition.tools);
|
|
5209
5215
|
return intentionalRestriction ? formatted : void 0;
|
|
5210
5216
|
}
|
|
5211
5217
|
function humanSkills(definition) {
|
|
@@ -8799,10 +8805,6 @@ Read-only roles may read these artifacts but must not modify them.
|
|
|
8799
8805
|
Do not silently broaden scope or make an unapproved scope, architecture,
|
|
8800
8806
|
security, protocol, repository-boundary, product, or operational decision.
|
|
8801
8807
|
|
|
8802
|
-
Managed agents' direct Pi built-in bash and powershell calls without an explicit
|
|
8803
|
-
timeout are capped at 600 seconds. Supply a longer explicit
|
|
8804
|
-
timeout only when a command is intentionally expected to exceed that horizon.
|
|
8805
|
-
|
|
8806
8808
|
Use ask_owner only when a decision from your exact direct owner is genuinely
|
|
8807
8809
|
required to continue correctly. ask_owner may include files for supporting
|
|
8808
8810
|
evidence; complete strict UTF-8 text may be embedded and other files remain
|
|
@@ -8950,7 +8952,10 @@ var AGENT_HANDOFF_GUIDANCE = "Use delegate_agent to start a fresh bounded assign
|
|
|
8950
8952
|
var LEAD_SCOPE_DESCRIPTION = `Own architecture, approved scope, acceptance of Agent outputs, integration, conflict resolution,
|
|
8951
8953
|
and final technical decisions within your assigned objective. Integrate resolved Agent results and
|
|
8952
8954
|
carry relevant evidence into onward handoffs. Decompose only as far as useful.
|
|
8953
|
-
Reuse adequate existing evidence instead of duplicating work
|
|
8955
|
+
Reuse adequate existing evidence instead of duplicating work.
|
|
8956
|
+
Your herd is your internal team: you and your recursively owned Agents.
|
|
8957
|
+
Any review conducted within the herd is internal feedback, not user or supervisor
|
|
8958
|
+
review or approval.`;
|
|
8954
8959
|
var DELEGATING_AGENT_SCOPE_DESCRIPTION = `Own the assigned objective and your direct permitted agents. While direct assignments are unresolved, your execution scope is limited to the non-delegated remainder. Agent-started
|
|
8955
8960
|
agents are leaves. Delegate bounded execution work when an Agent can reasonably
|
|
8956
8961
|
own it and delegation is useful. Keep work local when it is trivial,
|
|
@@ -9598,16 +9603,33 @@ function resolveAssignmentSession(ctx, raw, options = {}) {
|
|
|
9598
9603
|
);
|
|
9599
9604
|
return resolved;
|
|
9600
9605
|
}
|
|
9601
|
-
function
|
|
9602
|
-
const
|
|
9603
|
-
(
|
|
9606
|
+
function visibleAgentCapabilities(definitions, scope) {
|
|
9607
|
+
const availableNames = new Set(
|
|
9608
|
+
definitions.filter(agentDefinitionEnabled).map(({ name }) => name)
|
|
9609
|
+
);
|
|
9610
|
+
let previousSize;
|
|
9611
|
+
do {
|
|
9612
|
+
previousSize = availableNames.size;
|
|
9613
|
+
for (const definition of definitions)
|
|
9614
|
+
if (availableNames.has(definition.name) && definition.frontmatter.agents?.some((name) => !availableNames.has(name)))
|
|
9615
|
+
availableNames.delete(definition.name);
|
|
9616
|
+
} while (availableNames.size !== previousSize);
|
|
9617
|
+
const available = definitions.filter(
|
|
9618
|
+
(definition) => availableNames.has(definition.name) && (scope.kind === "lead" || scope.allowedAgentDefinitions.has(definition.name))
|
|
9619
|
+
);
|
|
9620
|
+
return available.map((definition) => {
|
|
9621
|
+
const metadata = agentDefinitionMetadata(
|
|
9604
9622
|
definition,
|
|
9605
9623
|
scope.kind === "managed-agent" ? "leaf" : "delegating"
|
|
9606
|
-
)
|
|
9607
|
-
|
|
9608
|
-
|
|
9609
|
-
|
|
9610
|
-
|
|
9624
|
+
);
|
|
9625
|
+
return {
|
|
9626
|
+
name: definition.name,
|
|
9627
|
+
...typeof metadata.description === "string" ? { description: metadata.description } : {},
|
|
9628
|
+
tools: formatTools(metadata),
|
|
9629
|
+
skills: formatSkills(metadata),
|
|
9630
|
+
...scope.kind === "lead" && agentDefinitionDelegationEnabled(definition) && definition.frontmatter.agents?.length ? { agents: [...definition.frontmatter.agents] } : {}
|
|
9631
|
+
};
|
|
9632
|
+
});
|
|
9611
9633
|
}
|
|
9612
9634
|
function validateAssignmentRequest(params) {
|
|
9613
9635
|
if (params.action !== "delegate" && params.action !== "continue") return;
|
|
@@ -10984,7 +11006,7 @@ function createAgentController(pi, options) {
|
|
|
10984
11006
|
return {
|
|
10985
11007
|
ok: true,
|
|
10986
11008
|
agents: [...agents, ...unknown],
|
|
10987
|
-
agent_definitions: scope ?
|
|
11009
|
+
agent_definitions: scope ? visibleAgentCapabilities(
|
|
10988
11010
|
await options.agentDefinitions(context),
|
|
10989
11011
|
scope
|
|
10990
11012
|
) : []
|
|
@@ -12930,7 +12952,7 @@ ${result.stderr ?? ""}`.trim(),
|
|
|
12930
12952
|
Type.Array(
|
|
12931
12953
|
Type.String({
|
|
12932
12954
|
minLength: 1,
|
|
12933
|
-
description:
|
|
12955
|
+
description: "Readable regular local file path or exact result ref returned by Herdsman."
|
|
12934
12956
|
}),
|
|
12935
12957
|
{
|
|
12936
12958
|
description: "File or result evidence transferred to the recipient. Copy result refs exactly. Files do not grant runtime capabilities."
|
|
@@ -14243,11 +14265,6 @@ function validateManagedAgentDefinition(definitions) {
|
|
|
14243
14265
|
);
|
|
14244
14266
|
validateAgentDefinitionReferences(definition, definitions);
|
|
14245
14267
|
}
|
|
14246
|
-
function managedAgentDefinitionRoster(definitions, allowed) {
|
|
14247
|
-
return definitions.map((definition) => agentDefinitionMetadata(definition, "leaf")).filter(
|
|
14248
|
-
(definition) => allowed.includes(definition.name) && definition.enabled !== false
|
|
14249
|
-
);
|
|
14250
|
-
}
|
|
14251
14268
|
function ensureManagedAgentIdentity(pi, ctx, definition, label) {
|
|
14252
14269
|
const sessionId = ctx.sessionManager.getSessionId();
|
|
14253
14270
|
const identity = sessionAgentIdentity(
|
|
@@ -14804,7 +14821,7 @@ function registerManagedAgentAskOwnerTool(pi, execute) {
|
|
|
14804
14821
|
Type2.Array(
|
|
14805
14822
|
Type2.String({
|
|
14806
14823
|
minLength: 1,
|
|
14807
|
-
description:
|
|
14824
|
+
description: "Readable regular local file path or exact result ref returned by Herdsman."
|
|
14808
14825
|
}),
|
|
14809
14826
|
{
|
|
14810
14827
|
description: "File or result evidence transferred to the recipient. Copy result refs exactly. Files do not grant runtime capabilities."
|
|
@@ -15536,7 +15553,7 @@ function registerManagedAgentRuntime(pi, options) {
|
|
|
15536
15553
|
const availableRoster = roster?.sessionId === ctx.sessionManager.getSessionId() ? roster : void 0;
|
|
15537
15554
|
event.systemPromptOptions.sections.delegating_agent_role = DELEGATING_AGENT_ROLE_CHARTER;
|
|
15538
15555
|
if (availableRoster)
|
|
15539
|
-
event.systemPromptOptions.sections.agent_definitions = `${JSON.stringify(availableRoster.definitions
|
|
15556
|
+
event.systemPromptOptions.sections.agent_definitions = `${JSON.stringify(availableRoster.definitions)}
|
|
15540
15557
|
|
|
15541
15558
|
This is the session-start definition snapshot. Use list_agents for live Agent state or to refresh Agent definitions after configuration changes.`;
|
|
15542
15559
|
}
|
|
@@ -15728,9 +15745,12 @@ This is the session-start definition snapshot. Use list_agents for live Agent st
|
|
|
15728
15745
|
try {
|
|
15729
15746
|
startupDefinitionRoster = {
|
|
15730
15747
|
sessionId: ctx.sessionManager.getSessionId(),
|
|
15731
|
-
definitions:
|
|
15748
|
+
definitions: visibleAgentCapabilities(
|
|
15732
15749
|
await options.getAgentDefinitions(ctx),
|
|
15733
|
-
|
|
15750
|
+
{
|
|
15751
|
+
kind: "managed-agent",
|
|
15752
|
+
allowedAgentDefinitions: new Set(allowedAgentDefinitions)
|
|
15753
|
+
}
|
|
15734
15754
|
)
|
|
15735
15755
|
};
|
|
15736
15756
|
} catch (error2) {
|
|
@@ -16628,7 +16648,7 @@ function createLeadSessionStartRuntime(host) {
|
|
|
16628
16648
|
);
|
|
16629
16649
|
if (needsLeadRoster) {
|
|
16630
16650
|
try {
|
|
16631
|
-
const definitions = await host.
|
|
16651
|
+
const definitions = await host.visibleAgentCapabilities(
|
|
16632
16652
|
ctx,
|
|
16633
16653
|
definitionSnapshot?.definitions
|
|
16634
16654
|
);
|
|
@@ -16690,7 +16710,7 @@ function createLeadAgentEventRuntime(host) {
|
|
|
16690
16710
|
if (prompt) sections.pi_herdsman_lead_execution = prompt;
|
|
16691
16711
|
else delete sections.pi_herdsman_lead_execution;
|
|
16692
16712
|
if (roster && roster.sessionId === ctx.sessionManager.getSessionId())
|
|
16693
|
-
sections.agent_definitions = `${JSON.stringify(roster.definitions
|
|
16713
|
+
sections.agent_definitions = `${JSON.stringify(roster.definitions)}
|
|
16694
16714
|
|
|
16695
16715
|
This is the session-start definition snapshot. Use list_agents for live Agent state or to refresh Agent definitions after configuration changes.`;
|
|
16696
16716
|
else delete sections.agent_definitions;
|
|
@@ -17098,7 +17118,7 @@ function createLeadCommandRuntime(host) {
|
|
|
17098
17118
|
);
|
|
17099
17119
|
if (!rows.length) {
|
|
17100
17120
|
ctx.ui.notify(
|
|
17101
|
-
|
|
17121
|
+
"No running Agents. Ask Pi to delegate using an available definition."
|
|
17102
17122
|
);
|
|
17103
17123
|
return;
|
|
17104
17124
|
}
|
|
@@ -24709,7 +24729,7 @@ Use reply_agent with agent="${ask.agentLabel}" to answer this question.`,
|
|
|
24709
24729
|
Type3.Array(
|
|
24710
24730
|
Type3.String({
|
|
24711
24731
|
minLength: 1,
|
|
24712
|
-
description:
|
|
24732
|
+
description: "Readable regular local file path or exact result ref returned by Herdsman."
|
|
24713
24733
|
}),
|
|
24714
24734
|
{
|
|
24715
24735
|
description: "Explicit evidence transfer. Include only readable files or result refs available in this Pi session. A ref mentioned only in text is not transferred evidence. Copy refs exactly. Files do not grant runtime capabilities."
|
|
@@ -25606,7 +25626,7 @@ ${summary}`,
|
|
|
25606
25626
|
},
|
|
25607
25627
|
initialStatusBreadcrumb: () => initialStatusBreadcrumb,
|
|
25608
25628
|
ownToolsSnapshot,
|
|
25609
|
-
|
|
25629
|
+
visibleAgentCapabilities: async (ctx, definitions) => visibleAgentCapabilities(
|
|
25610
25630
|
definitions ?? (await contextAgentDefinitions(ctx)).definitions,
|
|
25611
25631
|
controllerScope
|
|
25612
25632
|
),
|