@henryqw/pi-subagent 26.2.3 → 26.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -2
- package/dist/ephemeral.js +12 -1
- package/dist/index.d.ts +8 -6
- package/package.json +7 -7
package/README.md
CHANGED
|
@@ -6,7 +6,7 @@ Delegate work to configured Pi Roles with [Herdr](https://herdr.dev/). Authorize
|
|
|
6
6
|
|
|
7
7
|
## Install
|
|
8
8
|
|
|
9
|
-
Requires Pi 1.
|
|
9
|
+
Requires Pi 1.1.0 or later. Development and automated checks use Pi 1.1.0. Older Pi releases are no longer supported.
|
|
10
10
|
|
|
11
11
|
```bash
|
|
12
12
|
pi install npm:@henryqw/pi-task-models
|
|
@@ -246,7 +246,9 @@ The servers named in `mcps` come from the global `~/.pi/agent/mcp.json` only. In
|
|
|
246
246
|
| `RoleLaunchRuntime`, `HerdrHostRuntime`, `CheckedGitRuntime` | classes | Supply launch, host, and Git behavior to the runner. |
|
|
247
247
|
| `ExecutionPolicySnapshot`, `RunState`, `CoordinatorRuntime` | types | Describe persisted policy, state, and runner integration. |
|
|
248
248
|
|
|
249
|
-
|
|
249
|
+
Role route and launch helpers require only model routing fields and `isProjectTrusted()` from the context, plus `cwd` for configured package resources. They do not require UI methods.
|
|
250
|
+
|
|
251
|
+
`createEphemeralSubagentExecutor` accepts global concurrency, turn/token, idle, and hard-runtime policy. Queued time consumes no child timeout. A run resolves resources only after receiving its permit and accepts abort, output, token, and activity callbacks. Output and diagnostics are bounded. A child that reports `agent_settled.aborted: true` returns a failure result with `stopReason: "aborted"`, even if its process exits with code 0. Collected output, usage, and child error text are kept. `aborted: false` does not prove provider success. A parent abort or timeout still rejects with `EphemeralSubagentError`.
|
|
250
252
|
|
|
251
253
|
See [Orchestration and package-author API](./docs/orchestration.md) for the detailed contracts and recovery model.
|
|
252
254
|
|
package/dist/ephemeral.js
CHANGED
|
@@ -38,7 +38,7 @@ const PI_JSON_EVENTS = {
|
|
|
38
38
|
summarization_retry_finished: true,
|
|
39
39
|
bash_execution_update: true,
|
|
40
40
|
};
|
|
41
|
-
const CONSUMED_JSON_EVENTS = new Set(["message_start", "message_update", "message_end"]);
|
|
41
|
+
const CONSUMED_JSON_EVENTS = new Set(["message_start", "message_update", "message_end", "agent_settled"]);
|
|
42
42
|
const JSON_EVENT_TYPE = /^\s*\{\s*"type"\s*:\s*"([^"\\]+)"/;
|
|
43
43
|
const JSON_STRING = `"(?:[^"\\\\\u0000-\u001f]|\\\\(?:["\\\\/bfnrt]|u[0-9a-fA-F]{4}))*"`;
|
|
44
44
|
const JSON_OVERSIZED_TOOL_START = new RegExp(`^\\s*\\{\\s*"type"\\s*:\\s*"tool_execution_start"\\s*,\\s*"toolCallId"\\s*:\\s*(${JSON_STRING})\\s*,\\s*"toolName"\\s*:\\s*(${JSON_STRING})(?=\\s*,)`);
|
|
@@ -429,6 +429,7 @@ async function runPi(prepared, input, budget, invocation) {
|
|
|
429
429
|
let spawnError;
|
|
430
430
|
let protocolError;
|
|
431
431
|
let aborted = false;
|
|
432
|
+
let settlementAborted = false;
|
|
432
433
|
let limit;
|
|
433
434
|
let tokenBudget = "within";
|
|
434
435
|
let startedTurns = 0;
|
|
@@ -528,6 +529,8 @@ async function runPi(prepared, input, budget, invocation) {
|
|
|
528
529
|
}
|
|
529
530
|
else {
|
|
530
531
|
const exitCode = code ?? 1;
|
|
532
|
+
if (settlementAborted)
|
|
533
|
+
stopReason = "aborted";
|
|
531
534
|
const outcome = exitCode !== 0 || stopReason === "error" || stopReason === "aborted" ? "failure" : "success";
|
|
532
535
|
resolve({
|
|
533
536
|
outcome,
|
|
@@ -627,6 +630,14 @@ async function runPi(prepared, input, budget, invocation) {
|
|
|
627
630
|
const record = event;
|
|
628
631
|
if (typeof record.type !== "string" || !Object.hasOwn(PI_JSON_EVENTS, record.type))
|
|
629
632
|
return;
|
|
633
|
+
if (record.type === "agent_settled") {
|
|
634
|
+
if (typeof record.aborted !== "boolean") {
|
|
635
|
+
protocolError = new Error("Subagent agent_settled.aborted must be a boolean.");
|
|
636
|
+
stop(true);
|
|
637
|
+
return;
|
|
638
|
+
}
|
|
639
|
+
settlementAborted ||= record.aborted;
|
|
640
|
+
}
|
|
630
641
|
observeEvent();
|
|
631
642
|
if (record.type === "turn_start") {
|
|
632
643
|
if (++startedTurns > budget.maxTurns) {
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type ExtensionAPI, type ExtensionContext } from "@earendil-works/pi-coding-agent";
|
|
2
|
-
import { type AvailableModel, type ModelTask, type ProfileName, type ResolvedTaskRoute, type ThinkingLevel } from "@henryqw/pi-task-models";
|
|
2
|
+
import { resolveTaskModelRoute, type AvailableModel, type ModelTask, type ProfileName, type ResolvedTaskRoute, type ThinkingLevel } from "@henryqw/pi-task-models";
|
|
3
3
|
export { DISPLAY_TEXT_CONTRACT, hasDisplayControlCharacters } from "./display-text.ts";
|
|
4
4
|
export { loadRoleMcpConfig, parseRoleMcpAllowlist } from "./mcp-role.ts";
|
|
5
5
|
export { addUsage, capEphemeralSubagentOutput, createEphemeralSubagentExecutor, DEFAULT_MAX_TURNS, EphemeralSubagentError, EXECUTION_BUDGET_ENV, formatDuration, type EphemeralSubagentActivityEvent, type EphemeralSubagentErrorCode, type EphemeralSubagentExecutionBudget, type EphemeralSubagentExecutor, type EphemeralSubagentExecutorOptions, type EphemeralSubagentResult, type EphemeralSubagentRunInput, type EphemeralSubagentTimeout, } from "./ephemeral.ts";
|
|
@@ -83,7 +83,9 @@ export declare function loadBuiltinRole(name: BuiltinRoleName): Role;
|
|
|
83
83
|
* user files are an error. Missing user directory returns the built-ins.
|
|
84
84
|
*/
|
|
85
85
|
export declare function loadRoles(agentDir?: string): Role[];
|
|
86
|
-
|
|
86
|
+
type TaskRouteContext = Parameters<typeof resolveTaskModelRoute>[0];
|
|
87
|
+
type RoleLaunchContext = TaskRouteContext & Pick<ExtensionContext, "isProjectTrusted">;
|
|
88
|
+
export declare function resolveTaskRoute(ctx: TaskRouteContext, profileName: ProfileName, agentDir?: string): ResolvedTaskRoute;
|
|
87
89
|
export declare function resolveRoleSkills(pi: Pick<ExtensionAPI, "getCommands">, role: Role): ResolvedRoleSkills;
|
|
88
90
|
/** Resolve all enabled package resources selected by one Role's extension sources. */
|
|
89
91
|
export declare function resolveRolePackageResources(role: Role, ctx: Pick<ExtensionContext, "cwd" | "isProjectTrusted">): Promise<{
|
|
@@ -93,12 +95,12 @@ export declare function resolveRolePackageResources(role: Role, ctx: Pick<Extens
|
|
|
93
95
|
themes: string[];
|
|
94
96
|
}>;
|
|
95
97
|
export declare function createRoleLaunch(pi: Pick<ExtensionAPI, "getCommands">, ctx: Pick<ExtensionContext, "isProjectTrusted">, input: CreateRoleLaunchInput): ResolvedRoleLaunch;
|
|
96
|
-
export declare function resolveRoleLaunch(pi: Pick<ExtensionAPI, "getCommands">, ctx:
|
|
98
|
+
export declare function resolveRoleLaunch(pi: Pick<ExtensionAPI, "getCommands">, ctx: RoleLaunchContext, input: ResolveRoleLaunchInput): ResolvedRoleLaunch;
|
|
97
99
|
/** Prepare a resolved or resolvable Role launch while keeping its system prompt out of argv. */
|
|
98
|
-
export declare function prepareRoleLaunch(pi: Pick<ExtensionAPI, "getCommands">, ctx:
|
|
99
|
-
export declare function prepareRoleLaunch(pi: Pick<ExtensionAPI, "getCommands">, ctx:
|
|
100
|
+
export declare function prepareRoleLaunch(pi: Pick<ExtensionAPI, "getCommands">, ctx: RoleLaunchContext, input: ResolveRoleLaunchInput): PreparedRoleLaunch;
|
|
101
|
+
export declare function prepareRoleLaunch(pi: Pick<ExtensionAPI, "getCommands">, ctx: RoleLaunchContext, input: CreateRoleLaunchInput): PreparedRoleLaunch;
|
|
100
102
|
/** Resolve and prepare a configured Role with its package-owned resources. */
|
|
101
|
-
export declare function resolveConfiguredRoleLaunch(pi: Pick<ExtensionAPI, "getCommands">, ctx: ExtensionContext, input: ResolveConfiguredRoleLaunchInput): Promise<PreparedRoleLaunch>;
|
|
103
|
+
export declare function resolveConfiguredRoleLaunch(pi: Pick<ExtensionAPI, "getCommands">, ctx: RoleLaunchContext & Pick<ExtensionContext, "cwd">, input: ResolveConfiguredRoleLaunchInput): Promise<PreparedRoleLaunch>;
|
|
102
104
|
/** Insert the system prompt pair after a caller has prepared its launch argv. */
|
|
103
105
|
export declare function finalizeRoleLaunch(prepared: PreparedRoleLaunch): ResolvedRoleLaunch;
|
|
104
106
|
export * from "./composition.ts";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@henryqw/pi-subagent",
|
|
3
|
-
"version": "26.
|
|
3
|
+
"version": "26.3.0",
|
|
4
4
|
"description": "Delegate bounded direct work or durable checked isolated task graphs to Pi roles.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"pi-package",
|
|
@@ -40,9 +40,9 @@
|
|
|
40
40
|
"pack:check": "npm pack --dry-run"
|
|
41
41
|
},
|
|
42
42
|
"peerDependencies": {
|
|
43
|
-
"@earendil-works/pi-ai": "^1.
|
|
44
|
-
"@earendil-works/pi-coding-agent": "^1.
|
|
45
|
-
"@earendil-works/pi-tui": "^1.
|
|
43
|
+
"@earendil-works/pi-ai": "^1.1.0",
|
|
44
|
+
"@earendil-works/pi-coding-agent": "^1.1.0",
|
|
45
|
+
"@earendil-works/pi-tui": "^1.1.0",
|
|
46
46
|
"typebox": "^1.3.15"
|
|
47
47
|
},
|
|
48
48
|
"repository": {
|
|
@@ -74,9 +74,9 @@
|
|
|
74
74
|
"proper-lockfile": "^4.1.2"
|
|
75
75
|
},
|
|
76
76
|
"devDependencies": {
|
|
77
|
-
"@earendil-works/pi-ai": "1.
|
|
78
|
-
"@earendil-works/pi-coding-agent": "1.
|
|
79
|
-
"@earendil-works/pi-tui": "1.
|
|
77
|
+
"@earendil-works/pi-ai": "1.1.0",
|
|
78
|
+
"@earendil-works/pi-coding-agent": "1.1.0",
|
|
79
|
+
"@earendil-works/pi-tui": "1.1.0",
|
|
80
80
|
"@types/proper-lockfile": "^4.1.4"
|
|
81
81
|
}
|
|
82
82
|
}
|