pi-herdsman 0.21.0 → 0.21.1
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/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.21.
|
|
18
|
+
version: "0.21.1",
|
|
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,7 +64,7 @@ var package_default = {
|
|
|
64
64
|
},
|
|
65
65
|
piHerdsman: {
|
|
66
66
|
runtime: {
|
|
67
|
-
pi: "1.0.
|
|
67
|
+
pi: "1.0.4",
|
|
68
68
|
herdr: {
|
|
69
69
|
version: "0.9.3",
|
|
70
70
|
sha256: {
|
|
@@ -93,9 +93,9 @@ var package_default = {
|
|
|
93
93
|
typebox: "*"
|
|
94
94
|
},
|
|
95
95
|
devDependencies: {
|
|
96
|
-
"@earendil-works/pi-ai": "1.0.
|
|
97
|
-
"@earendil-works/pi-coding-agent": "1.0.
|
|
98
|
-
"@earendil-works/pi-tui": "1.0.
|
|
96
|
+
"@earendil-works/pi-ai": "1.0.4",
|
|
97
|
+
"@earendil-works/pi-coding-agent": "1.0.4",
|
|
98
|
+
"@earendil-works/pi-tui": "1.0.4",
|
|
99
99
|
esbuild: "^0.28.2",
|
|
100
100
|
typebox: "^1.3.7"
|
|
101
101
|
},
|
|
@@ -1579,6 +1579,11 @@ function overrideBodyMode(definition) {
|
|
|
1579
1579
|
function normalizedToolNames(tools) {
|
|
1580
1580
|
return (tools ?? []).flatMap((tool) => tool.split(",")).map((tool) => tool.trim()).filter(Boolean);
|
|
1581
1581
|
}
|
|
1582
|
+
function matchesToolPattern(pattern, name) {
|
|
1583
|
+
if (!pattern.includes("*")) return pattern === name;
|
|
1584
|
+
const source = pattern.split("*").map((part) => part.replace(/[.+?^${}()|[\]\\]/gu, "\\$&")).join(".*");
|
|
1585
|
+
return new RegExp(`^${source}$`, "u").test(name);
|
|
1586
|
+
}
|
|
1582
1587
|
function readOptionalAgentDefinitions(root2) {
|
|
1583
1588
|
const stats = statSync3(root2, { throwIfNoEntry: false });
|
|
1584
1589
|
if (!stats) return [];
|
|
@@ -1954,33 +1959,41 @@ function agentLaunchArgs(agent, options) {
|
|
|
1954
1959
|
}
|
|
1955
1960
|
}
|
|
1956
1961
|
if (sharedPromptPath) args.push("--append-system-prompt", sharedPromptPath);
|
|
1957
|
-
if (managedAgent)
|
|
1958
|
-
args.push("--append-system-prompt", `<active_agent name="${agent.name}"/>`);
|
|
1959
1962
|
const explicitTools = frontmatter.tools !== void 0;
|
|
1960
|
-
const
|
|
1963
|
+
const configuredTools = normalizedToolNames(frontmatter.tools);
|
|
1964
|
+
const noTools = frontmatter.noTools === true || explicitTools && configuredTools.length === 0;
|
|
1961
1965
|
if (noTools) args.push("--no-tools");
|
|
1962
1966
|
if (frontmatter.noBuiltinTools) args.push("--no-builtin-tools");
|
|
1963
1967
|
const requiredTools = [
|
|
1964
1968
|
...managedAgent ? agentDefinitionDelegationEnabled(agent) ? [...AGENT_COORDINATION_TOOLS, "ask_owner"] : ["ask_owner"] : [],
|
|
1965
1969
|
...options.requiredTools ?? []
|
|
1966
1970
|
].filter((tool, index, all) => all.indexOf(tool) === index);
|
|
1967
|
-
|
|
1968
|
-
|
|
1969
|
-
|
|
1970
|
-
|
|
1971
|
+
const requiredToolSet = new Set(requiredTools);
|
|
1972
|
+
const excluded = normalizedToolNames(frontmatter.excludeTools).filter((pattern) => !requiredToolSet.has(pattern)).filter((pattern, index, all) => all.indexOf(pattern) === index);
|
|
1973
|
+
for (const pattern of excluded) {
|
|
1974
|
+
if (!pattern.includes("*")) continue;
|
|
1975
|
+
const required = requiredTools.find(
|
|
1976
|
+
(tool) => matchesToolPattern(pattern, tool)
|
|
1977
|
+
);
|
|
1978
|
+
if (required)
|
|
1979
|
+
throw new Error(
|
|
1980
|
+
`agent ${agent.name} excludeTools pattern ${JSON.stringify(pattern)} matches required tool ${JSON.stringify(required)}; required tools cannot be excluded by patterns`
|
|
1971
1981
|
);
|
|
1972
|
-
|
|
1973
|
-
|
|
1982
|
+
}
|
|
1983
|
+
if (noTools || explicitTools) {
|
|
1984
|
+
const configured = configuredTools.filter(
|
|
1985
|
+
(tool) => (!managedAgent || tool !== "agent") && !requiredToolSet.has(tool)
|
|
1986
|
+
);
|
|
1987
|
+
const selected = [.../* @__PURE__ */ new Set([...configured, ...requiredTools])];
|
|
1988
|
+
if (selected.length) {
|
|
1989
|
+
if (!selected.some((tool) => tool.startsWith("mcp__"))) {
|
|
1990
|
+
selected.push("mcp__");
|
|
1991
|
+
if (!excluded.includes("mcp__")) excluded.push("mcp__");
|
|
1992
|
+
}
|
|
1993
|
+
args.push("--tools", selected.join(","));
|
|
1974
1994
|
}
|
|
1975
|
-
const requiredToolSet = new Set(requiredTools);
|
|
1976
|
-
const excluded = normalizedToolNames(frontmatter.excludeTools).filter((tool) => !requiredToolSet.has(tool)).filter((tool, index, all) => all.indexOf(tool) === index);
|
|
1977
|
-
if (excluded.length) args.push("--exclude-tools", excluded.join(","));
|
|
1978
|
-
} else {
|
|
1979
|
-
if (frontmatter.tools?.length)
|
|
1980
|
-
args.push("--tools", frontmatter.tools.join(","));
|
|
1981
|
-
if (frontmatter.excludeTools?.length)
|
|
1982
|
-
args.push("--exclude-tools", frontmatter.excludeTools.join(","));
|
|
1983
1995
|
}
|
|
1996
|
+
if (excluded.length) args.push("--exclude-tools", excluded.join(","));
|
|
1984
1997
|
const noSkills = frontmatter.noSkills ?? frontmatter.inheritSkills !== true;
|
|
1985
1998
|
if (noSkills) args.push("--no-skills");
|
|
1986
1999
|
for (const skill of frontmatter.skills ?? []) args.push("--skill", skill);
|
|
@@ -1989,6 +2002,8 @@ function agentLaunchArgs(agent, options) {
|
|
|
1989
2002
|
args.push("--no-extensions");
|
|
1990
2003
|
for (const extension of frontmatter.extensions ?? [])
|
|
1991
2004
|
args.push("--extension", extension);
|
|
2005
|
+
if (managedAgent)
|
|
2006
|
+
args.push("--append-system-prompt", `<active_agent name="${agent.name}"/>`);
|
|
1992
2007
|
return args;
|
|
1993
2008
|
}
|
|
1994
2009
|
|
|
@@ -11889,10 +11904,21 @@ function createAgentController(pi, options) {
|
|
|
11889
11904
|
} finally {
|
|
11890
11905
|
resetRelease();
|
|
11891
11906
|
}
|
|
11907
|
+
let ownerDisplay = "lead";
|
|
11908
|
+
if (scope.kind === "managed-agent") {
|
|
11909
|
+
const definition2 = process.env.PI_HERDSMAN_AGENT_DEFINITION;
|
|
11910
|
+
const parentLabel = process.env.PI_HERDSMAN_LABEL;
|
|
11911
|
+
if (!definition2 || !parentLabel)
|
|
11912
|
+
throw new Error(
|
|
11913
|
+
"Managed-Agent launch is missing its definition or label"
|
|
11914
|
+
);
|
|
11915
|
+
ownerDisplay = displayIdentity(definition2, parentLabel);
|
|
11916
|
+
}
|
|
11892
11917
|
const env = [
|
|
11893
11918
|
`PI_HERDSMAN_MAILBOX=${mailbox}`,
|
|
11894
11919
|
`PI_HERDSMAN_RUN_ID=${runId}`,
|
|
11895
11920
|
`PI_HERDSMAN_OWNER_SESSION_ID=${owner}`,
|
|
11921
|
+
`PI_HERDSMAN_OWNER_DISPLAY=${ownerDisplay}`,
|
|
11896
11922
|
`PI_SUBAGENT_PARENT_SESSION=${forwardingSession}`,
|
|
11897
11923
|
`PI_HERDSMAN_LABEL=${label}`,
|
|
11898
11924
|
`PI_HERDSMAN_WORKSPACE_ID=${workspaceId}`,
|
|
@@ -13527,6 +13553,9 @@ function collectSessionUsage(ctx, ownedChildren, openOwnedSession, leadRoots = [
|
|
|
13527
13553
|
import { randomUUID as randomUUID9 } from "node:crypto";
|
|
13528
13554
|
import { Type as Type2 } from "typebox";
|
|
13529
13555
|
import { isDeepStrictEqual } from "node:util";
|
|
13556
|
+
var DELEGATING_AGENT_ROLE_CHARTER = `## Delegating agent role
|
|
13557
|
+
${DELEGATING_AGENT_SCOPE_DESCRIPTION}
|
|
13558
|
+
${FILE_HANDOFF_GUIDANCE}`;
|
|
13530
13559
|
function currentTurnIsSoleToolCall(message, name) {
|
|
13531
13560
|
const turn = message;
|
|
13532
13561
|
if (turn?.role !== "assistant" || !Array.isArray(turn.content)) return false;
|
|
@@ -14699,7 +14728,9 @@ function registerManagedAgentRuntime(pi, options) {
|
|
|
14699
14728
|
const view = await controller.agentSnapshotView(
|
|
14700
14729
|
ctx,
|
|
14701
14730
|
scope,
|
|
14702
|
-
controller.sessionSignal()
|
|
14731
|
+
controller.sessionSignal(),
|
|
14732
|
+
true,
|
|
14733
|
+
false
|
|
14703
14734
|
);
|
|
14704
14735
|
return buildAgentStatusSnapshot(view, ctx, {
|
|
14705
14736
|
scope,
|
|
@@ -14717,29 +14748,23 @@ function registerManagedAgentRuntime(pi, options) {
|
|
|
14717
14748
|
});
|
|
14718
14749
|
}
|
|
14719
14750
|
controller?.registerTools(/* @__PURE__ */ new Map());
|
|
14720
|
-
|
|
14721
|
-
|
|
14722
|
-
|
|
14723
|
-
|
|
14724
|
-
|
|
14725
|
-
|
|
14726
|
-
|
|
14751
|
+
pi.on("before_agent_start", (event, ctx) => {
|
|
14752
|
+
const definition = process.env.PI_HERDSMAN_AGENT_DEFINITION;
|
|
14753
|
+
const label = process.env.PI_HERDSMAN_LABEL;
|
|
14754
|
+
event.systemPromptOptions.sections.pi_herdsman_agent = [
|
|
14755
|
+
`identity: ${displayIdentity(definition, label)}`,
|
|
14756
|
+
`direct_owner: ${process.env.PI_HERDSMAN_OWNER_DISPLAY}`
|
|
14757
|
+
].join("\n");
|
|
14758
|
+
if (delegationEnabled) {
|
|
14727
14759
|
const roster = startupDefinitionRoster;
|
|
14728
14760
|
const availableRoster = roster?.sessionId === ctx.sessionManager.getSessionId() ? roster : void 0;
|
|
14729
|
-
|
|
14730
|
-
|
|
14731
|
-
|
|
14732
|
-
${projection.roleCharter}
|
|
14733
|
-
|
|
14734
|
-
` + (availableRoster ? `## Available agent definitions
|
|
14735
|
-
|
|
14736
|
-
<agent_definitions>
|
|
14737
|
-
${JSON.stringify(availableRoster.definitions, null, 2)}
|
|
14738
|
-
</agent_definitions>
|
|
14761
|
+
event.systemPromptOptions.sections.delegating_agent_role = DELEGATING_AGENT_ROLE_CHARTER;
|
|
14762
|
+
if (availableRoster)
|
|
14763
|
+
event.systemPromptOptions.sections.agent_definitions = `${JSON.stringify(availableRoster.definitions, null, 2)}
|
|
14739
14764
|
|
|
14740
|
-
This is the session-start definition snapshot. Use agent_list for live Agent state or to refresh Agent definitions after configuration changes
|
|
14741
|
-
|
|
14742
|
-
|
|
14765
|
+
This is the session-start definition snapshot. Use agent_list for live Agent state or to refresh Agent definitions after configuration changes.`;
|
|
14766
|
+
}
|
|
14767
|
+
});
|
|
14743
14768
|
const execution = createManagedAgentExecutionState();
|
|
14744
14769
|
const metadataPublisher = createManagedAgentMetadataPublisher(pi);
|
|
14745
14770
|
const leafStatus = createManagedAgentLeafStatus({
|
|
@@ -15149,6 +15174,8 @@ function managedAgentEnvironmentError() {
|
|
|
15149
15174
|
if (!validId(e.PI_HERDSMAN_RUN_ID)) return "PI_HERDSMAN_RUN_ID invalid";
|
|
15150
15175
|
if (!validId(e.PI_HERDSMAN_OWNER_SESSION_ID))
|
|
15151
15176
|
return "PI_HERDSMAN_OWNER_SESSION_ID invalid";
|
|
15177
|
+
if (!e.PI_HERDSMAN_OWNER_DISPLAY?.trim())
|
|
15178
|
+
return "PI_HERDSMAN_OWNER_DISPLAY missing";
|
|
15152
15179
|
if (!e.PI_HERDSMAN_LABEL || !AGENT_LABEL_PATTERN2.test(e.PI_HERDSMAN_LABEL))
|
|
15153
15180
|
return "PI_HERDSMAN_LABEL invalid";
|
|
15154
15181
|
if (!e.PI_HERDSMAN_WORKSPACE_ID?.trim())
|
|
@@ -21017,9 +21044,6 @@ var LEAD_ROLE_CHARTER = `## Lead role
|
|
|
21017
21044
|
${LEAD_SCOPE_DESCRIPTION}
|
|
21018
21045
|
${LEAD_SUPERVISOR_PEER_GUIDANCE}
|
|
21019
21046
|
${FILE_HANDOFF_GUIDANCE}`;
|
|
21020
|
-
var DELEGATING_AGENT_ROLE_CHARTER = `## Delegating agent role
|
|
21021
|
-
${DELEGATING_AGENT_SCOPE_DESCRIPTION}
|
|
21022
|
-
${FILE_HANDOFF_GUIDANCE}`;
|
|
21023
21047
|
var MANAGER_ROLE_CHARTER = `## Manager role
|
|
21024
21048
|
Manage project work by branch. Use staff_delegate with a task and optional branch
|
|
21025
21049
|
to start new project work. Use staff_resume with its branch to resume existing
|
|
@@ -21614,125 +21638,6 @@ ${globalInstructions}
|
|
|
21614
21638
|
const currentChief = (failOnVerificationError = false) => roleTransitions.currentChief(failOnVerificationError);
|
|
21615
21639
|
const managerForScope = (scope) => roleTransitions.managerForScope(scope);
|
|
21616
21640
|
const currentWorktreeScope = (ctx) => roleTransitions.currentWorktreeScope(ctx);
|
|
21617
|
-
const managedSupervisorWorktreeScope = async (ctx) => {
|
|
21618
|
-
const workspaceId = process.env.HERDR_WORKSPACE_ID;
|
|
21619
|
-
if (!workspaceId) return void 0;
|
|
21620
|
-
try {
|
|
21621
|
-
return await worktreeGroupScope(pi, ctx, workspaceId, ctx.signal);
|
|
21622
|
-
} catch (error2) {
|
|
21623
|
-
if (error2 instanceof OperationError && error2.detail.details?.herdrCode === "not_git_worktree")
|
|
21624
|
-
return void 0;
|
|
21625
|
-
throw error2;
|
|
21626
|
-
}
|
|
21627
|
-
};
|
|
21628
|
-
const managedSupervisorAgent = (ctx, descriptor) => verifiedHerdrAgent(descriptor, {
|
|
21629
|
-
listAgents: async () => (await listAllHerdrAgents(pi, ctx, ctx.signal)).agents,
|
|
21630
|
-
getAgent: async (paneId) => (await runHerdr(pi, ctx, ["agent", "get", paneId], {
|
|
21631
|
-
signal: ctx.signal
|
|
21632
|
-
}))?.agent,
|
|
21633
|
-
expectedSession: expectedSession2,
|
|
21634
|
-
isPiAgent,
|
|
21635
|
-
matchesExpectedSession
|
|
21636
|
-
});
|
|
21637
|
-
const managedCurrentManager = async (ctx, scope) => {
|
|
21638
|
-
const currentScope = scope === null || scope === void 0 ? await managedSupervisorWorktreeScope(ctx) : scope;
|
|
21639
|
-
if (!currentScope) return void 0;
|
|
21640
|
-
const status = readManagerDescriptorStatus(
|
|
21641
|
-
supervisionRuntime(),
|
|
21642
|
-
currentScope.primaryWorkspaceId
|
|
21643
|
-
);
|
|
21644
|
-
if (!status || !status.live) return void 0;
|
|
21645
|
-
if (status.descriptor.repoKey !== currentScope.repoKey)
|
|
21646
|
-
throw new Error("Manager authority does not match project");
|
|
21647
|
-
verifyManagerCoordinationAuthority(
|
|
21648
|
-
status.descriptor,
|
|
21649
|
-
readLeadCoordinationState(
|
|
21650
|
-
supervisionRuntime(),
|
|
21651
|
-
status.descriptor.piSessionId
|
|
21652
|
-
),
|
|
21653
|
-
HERDSMAN_BUILD,
|
|
21654
|
-
requireCompatibleBuild
|
|
21655
|
-
);
|
|
21656
|
-
if (!await managedSupervisorAgent(ctx, status.descriptor))
|
|
21657
|
-
throw new Error(
|
|
21658
|
-
"Manager authority exists but live discovery is inconclusive"
|
|
21659
|
-
);
|
|
21660
|
-
return status.descriptor;
|
|
21661
|
-
};
|
|
21662
|
-
const managedCurrentChief = async (ctx, failOnVerificationError = false) => {
|
|
21663
|
-
const runtime = supervisionRuntime();
|
|
21664
|
-
const leaseMayExist = () => {
|
|
21665
|
-
try {
|
|
21666
|
-
statSync7(runtime.lock);
|
|
21667
|
-
return true;
|
|
21668
|
-
} catch (error2) {
|
|
21669
|
-
if (error2.code === "ENOENT") return false;
|
|
21670
|
-
throw error2;
|
|
21671
|
-
}
|
|
21672
|
-
};
|
|
21673
|
-
let descriptor;
|
|
21674
|
-
try {
|
|
21675
|
-
descriptor = readChiefDescriptor(runtime.descriptor);
|
|
21676
|
-
} catch (error2) {
|
|
21677
|
-
if (failOnVerificationError && leaseMayExist()) throw error2;
|
|
21678
|
-
return void 0;
|
|
21679
|
-
}
|
|
21680
|
-
requireCompatibleBuild(
|
|
21681
|
-
HERDSMAN_BUILD,
|
|
21682
|
-
descriptor.build,
|
|
21683
|
-
"supervision",
|
|
21684
|
-
`Chief ${descriptor.piSessionId}`
|
|
21685
|
-
);
|
|
21686
|
-
if (!chiefLeaseIsHeld(runtime)) {
|
|
21687
|
-
if (failOnVerificationError && leaseMayExist())
|
|
21688
|
-
throw new Error("Unable to verify Chief supervision lease");
|
|
21689
|
-
return void 0;
|
|
21690
|
-
}
|
|
21691
|
-
try {
|
|
21692
|
-
const verified = await verifyRemoteChiefAuthority(descriptor, {
|
|
21693
|
-
remoteIdentity: () => managedSupervisorAgent(ctx, descriptor),
|
|
21694
|
-
requireCompatibleBuild,
|
|
21695
|
-
build: HERDSMAN_BUILD
|
|
21696
|
-
});
|
|
21697
|
-
if (!verified) return void 0;
|
|
21698
|
-
return descriptor;
|
|
21699
|
-
} catch (error2) {
|
|
21700
|
-
if (error2 instanceof OperationError && error2.detail.category === "incompatible_build")
|
|
21701
|
-
throw error2;
|
|
21702
|
-
if (failOnVerificationError) throw error2;
|
|
21703
|
-
return void 0;
|
|
21704
|
-
}
|
|
21705
|
-
};
|
|
21706
|
-
const prepareManagedSupervisorState = async (ctx) => {
|
|
21707
|
-
const content = await leadSupervisorState(ctx, {
|
|
21708
|
-
currentWorktreeScope: managedSupervisorWorktreeScope,
|
|
21709
|
-
projectAssignmentForScope: (scope, sessionId) => {
|
|
21710
|
-
const assignments = findProjectAssignmentBySession(
|
|
21711
|
-
supervisionRuntime(),
|
|
21712
|
-
scope.repoKey,
|
|
21713
|
-
sessionId
|
|
21714
|
-
);
|
|
21715
|
-
if (assignments.length > 1)
|
|
21716
|
-
throw new Error(
|
|
21717
|
-
"Multiple project assignments match the Lead session"
|
|
21718
|
-
);
|
|
21719
|
-
return assignments[0];
|
|
21720
|
-
},
|
|
21721
|
-
currentManager: managedCurrentManager,
|
|
21722
|
-
currentChiefAuthority: managedCurrentChief
|
|
21723
|
-
});
|
|
21724
|
-
const latest = [
|
|
21725
|
-
...buildSessionProjection2(ctx.sessionManager.getBranch()).entries
|
|
21726
|
-
].reverse().find(
|
|
21727
|
-
(candidate) => candidate.sourceEntry.type === "custom_message" && candidate.sourceEntry.customType === SUPERVISOR_STATE_TYPE && candidate.messages.length > 0
|
|
21728
|
-
);
|
|
21729
|
-
const latestMessage = latest?.messages[0];
|
|
21730
|
-
return supervisorStateMessage(
|
|
21731
|
-
SUPERVISOR_STATE_TYPE,
|
|
21732
|
-
content,
|
|
21733
|
-
latestMessage ? contentText5(latestMessage.content, "") : void 0
|
|
21734
|
-
);
|
|
21735
|
-
};
|
|
21736
21641
|
const currentManager = (ctx, scope = null) => roleTransitions.currentManager(ctx, scope);
|
|
21737
21642
|
const currentSupervisor = (ctx) => roleTransitions.currentSupervisor(ctx);
|
|
21738
21643
|
const liveAgent = (...args) => leadRuntimes.liveAgent(...args);
|
|
@@ -22546,10 +22451,6 @@ ${summary}`,
|
|
|
22546
22451
|
resolveMessageFiles,
|
|
22547
22452
|
currentTurnMessage,
|
|
22548
22453
|
getAgentDefinitions: async (ctx) => (await contextAgentDefinitions(ctx)).definitions,
|
|
22549
|
-
prepareDelegatingStart: async (ctx) => ({
|
|
22550
|
-
roleCharter: DELEGATING_AGENT_ROLE_CHARTER,
|
|
22551
|
-
supervisorStateMessage: await prepareManagedSupervisorState(ctx)
|
|
22552
|
-
}),
|
|
22553
22454
|
appendError: (ctx, kind, error2) => appendDurableError(pi, ctx, kind, error2)
|
|
22554
22455
|
});
|
|
22555
22456
|
}
|