pi-subagents 0.40.0 → 0.42.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/CHANGELOG.md +97 -0
- package/README.md +54 -1879
- package/agents/oracle.md +1 -0
- package/inspector-runner.mjs +11 -0
- package/package.json +13 -5
- package/prompts/parallel-context-build.md +1 -1
- package/prompts/parallel-handoff-plan.md +1 -1
- package/prompts/review-loop.md +1 -1
- package/skills/pi-subagents/SKILL.md +9 -7
- package/skills/pi-subagents/references/constraints-and-recipes.md +24 -32
- package/skills/pi-subagents/references/execution-controls.md +99 -97
- package/skills/pi-subagents/references/management-authoring-rpc.md +2 -2
- package/skills/pi-subagents/references/prompting-and-roles.md +23 -30
- package/src/agents/agent-management.ts +155 -65
- package/src/agents/agent-serializer.ts +19 -0
- package/src/agents/agents.ts +154 -71
- package/src/agents/chain-serializer.ts +10 -7
- package/src/agents/frontmatter.ts +5 -3
- package/src/agents/identity.ts +1 -1
- package/src/agents/proactive-skills.ts +13 -10
- package/src/agents/skills.ts +23 -6
- package/src/api/control-channel.ts +4 -0
- package/src/api/delegation.ts +26 -194
- package/src/api/external-runs.ts +129 -0
- package/src/api/intercom-bridge.ts +3 -0
- package/src/api/pi-args.ts +5 -0
- package/src/api/preflight.ts +3 -3
- package/src/api/shared-types.ts +19 -0
- package/src/extension/config.ts +10 -0
- package/src/extension/control-notices.ts +5 -39
- package/src/extension/doctor.ts +10 -9
- package/src/extension/fanout-child.ts +7 -4
- package/src/extension/index.ts +232 -68
- package/src/extension/rpc.ts +18 -12
- package/src/extension/schemas.ts +48 -37
- package/src/extension/tool-description.ts +36 -86
- package/src/inspectors/herdr/actions.ts +229 -0
- package/src/inspectors/herdr/client.ts +130 -0
- package/src/inspectors/herdr/inspector-runner.ts +141 -0
- package/src/inspectors/herdr/project-panes.ts +154 -0
- package/src/integrations/herdr-status.ts +330 -0
- package/src/intercom/intercom-bridge.ts +3 -2
- package/src/intercom/result-intercom.ts +5 -1
- package/src/missions/actions.ts +374 -0
- package/src/missions/lifecycle.ts +314 -0
- package/src/missions/store.ts +442 -0
- package/src/missions/types.ts +135 -0
- package/src/policy/authority.ts +46 -0
- package/src/profiles/profiles.ts +29 -3
- package/src/runs/background/async-execution.ts +110 -50
- package/src/runs/background/async-job-tracker.ts +27 -4
- package/src/runs/background/async-resume.ts +6 -6
- package/src/runs/background/async-status.ts +29 -1
- package/src/runs/background/auto-drain.ts +3 -3
- package/src/runs/background/chain-append.ts +3 -2
- package/src/runs/background/control-channel.ts +9 -7
- package/src/runs/background/fleet-view.ts +3 -4
- package/src/runs/background/notify.ts +2 -1
- package/src/runs/background/process-terminal.ts +5 -5
- package/src/runs/background/result-watcher.ts +13 -5
- package/src/runs/background/run-id-resolver.ts +3 -3
- package/src/runs/background/run-status.ts +35 -8
- package/src/runs/background/scheduled-runs.ts +602 -375
- package/src/runs/background/stale-run-reconciler.ts +3 -3
- package/src/runs/background/subagent-runner.ts +608 -445
- package/src/runs/background/subagent-wait.ts +50 -9
- package/src/runs/background/wait-subscriptions.ts +253 -0
- package/src/runs/background/wait-tool.ts +12 -4
- package/src/runs/foreground/async-steering-action.ts +3 -3
- package/src/runs/foreground/chain-clarify.ts +8 -4
- package/src/runs/foreground/chain-execution.ts +56 -30
- package/src/runs/foreground/execution.ts +34 -9
- package/src/runs/foreground/subagent-executor.ts +1036 -274
- package/src/runs/shared/acceptance.ts +28 -6
- package/src/runs/shared/child-protocol.ts +302 -22
- package/src/runs/shared/dynamic-fanout.ts +1 -1
- package/src/runs/shared/external-cli-runner.ts +130 -0
- package/src/runs/shared/long-running-guard.ts +42 -1
- package/src/runs/shared/mcp-direct-tool-allowlist.ts +2 -0
- package/src/runs/shared/nested-events.ts +59 -5
- package/src/runs/shared/nested-render.ts +9 -4
- package/src/runs/shared/parallel-handoff.ts +86 -2
- package/src/runs/shared/parallel-utils.ts +11 -2
- package/src/runs/shared/permissions.ts +95 -0
- package/src/runs/shared/pi-args.ts +468 -109
- package/src/runs/shared/pi-spawn.ts +11 -1
- package/src/runs/shared/run-history.ts +1 -1
- package/src/runs/shared/subagent-prompt-runtime.ts +36 -5
- package/src/runs/shared/subagent-startup-retry.ts +5 -2
- package/src/runs/shared/turn-budget.ts +6 -6
- package/src/runs/shared/worktree.ts +122 -12
- package/src/shared/accessible-dir.ts +29 -7
- package/src/shared/artifacts.ts +143 -1
- package/src/shared/fork-context.ts +3 -2
- package/src/shared/launch-contract.ts +1 -0
- package/src/shared/settings.ts +10 -0
- package/src/shared/types.ts +156 -14
- package/src/shared/utils.ts +8 -6
- package/src/slash/delegation-adapters.ts +32 -194
- package/src/slash/delegation-request.ts +43 -126
- package/src/slash/prompt-template-bridge.ts +158 -205
- package/src/slash/prompt-workflows.ts +21 -57
- package/src/slash/slash-bridge.ts +14 -0
- package/src/slash/slash-commands.ts +31 -632
- package/src/slash/subagents-admin.ts +18 -14
- package/src/tui/fleet-status.ts +156 -21
- package/src/tui/fleet-transcript.ts +110 -5
- package/src/tui/fleet.ts +57 -25
- package/src/tui/render.ts +368 -152
- package/src/types/pi-runtime-compat.d.ts +8 -0
- package/src/watchdog/lsp-diagnostics.ts +12 -7
- package/src/watchdog/model-selection.ts +2 -2
- package/src/watchdog/permission-arbiter.ts +145 -0
- package/src/watchdog/register-child.ts +1 -1
- package/src/watchdog/register-main.ts +1 -1
- package/src/watchdog/review.ts +4 -1
- package/src/watchdog/runtime.ts +3 -2
- package/src/workflows/chat-progress.ts +140 -0
- package/src/workflows/scripted-workflow.ts +415 -0
- package/agents/advisor.md +0 -73
- package/src/extension/chain-validation.ts +0 -181
|
@@ -3,40 +3,99 @@ import * as fs from "node:fs";
|
|
|
3
3
|
import * as os from "node:os";
|
|
4
4
|
import * as path from "node:path";
|
|
5
5
|
import { fileURLToPath } from "node:url";
|
|
6
|
-
import {
|
|
7
|
-
|
|
6
|
+
import {
|
|
7
|
+
encodeNestedPathEnv,
|
|
8
|
+
parseNestedPathEnv,
|
|
9
|
+
type NestedPathEntry,
|
|
10
|
+
} from "./nested-path.ts";
|
|
11
|
+
import {
|
|
12
|
+
resolveMcpDirectToolSelections,
|
|
13
|
+
type ResolvedMcpDirectToolSelection,
|
|
14
|
+
} from "./mcp-direct-tool-allowlist.ts";
|
|
8
15
|
import { resolvePiPackageRoot } from "./pi-spawn.ts";
|
|
9
16
|
import { RUNTIME_EXTENSION_ACK_PATH_ENV } from "./runtime-acknowledged-extensions.ts";
|
|
10
|
-
import {
|
|
11
|
-
|
|
17
|
+
import {
|
|
18
|
+
STRUCTURED_OUTPUT_CAPTURE_ENV,
|
|
19
|
+
STRUCTURED_OUTPUT_SCHEMA_ENV,
|
|
20
|
+
} from "./structured-output.ts";
|
|
21
|
+
import {
|
|
22
|
+
TEMP_ROOT_DIR,
|
|
23
|
+
type JsonSchemaObject,
|
|
24
|
+
type LaunchResolvedChildExtensionsV1,
|
|
25
|
+
type ResolvedToolBudget,
|
|
26
|
+
} from "../../shared/types.ts";
|
|
12
27
|
import { THINKING_LEVELS } from "../../shared/model-info.ts";
|
|
13
|
-
import {
|
|
14
|
-
|
|
15
|
-
|
|
28
|
+
import {
|
|
29
|
+
TOOL_BUDGET_ENV,
|
|
30
|
+
TOOL_BUDGET_ZERO_AUTH_ENV,
|
|
31
|
+
encodeToolBudgetEnv,
|
|
32
|
+
} from "./tool-budget.ts";
|
|
33
|
+
import {
|
|
34
|
+
CHILD_TOOL_DIAGNOSTIC_PATH_ENV,
|
|
35
|
+
MCP_DIRECT_CHILD_TOOLS_ENV,
|
|
36
|
+
REQUIRED_CHILD_TOOLS_ENV,
|
|
37
|
+
} from "./tool-availability.ts";
|
|
38
|
+
import {
|
|
39
|
+
CHILD_WATCHDOG_CONFIG_ENV,
|
|
40
|
+
encodeChildWatchdogConfig,
|
|
41
|
+
type ChildWatchdogConfig,
|
|
42
|
+
} from "../../watchdog/child-status.ts";
|
|
16
43
|
import { WAIT_TOOL_ENABLED_ENV } from "../background/wait-config.ts";
|
|
17
|
-
import {
|
|
18
|
-
|
|
44
|
+
import {
|
|
45
|
+
PI_CODING_AGENT_PACKAGE_ROOT_ENV,
|
|
46
|
+
getAgentDir,
|
|
47
|
+
} from "../../shared/utils.ts";
|
|
48
|
+
import {
|
|
49
|
+
encodePermissionRules,
|
|
50
|
+
PERMISSION_AUDIT_PATH_ENV,
|
|
51
|
+
PERMISSION_POLICY_ENV,
|
|
52
|
+
type PermissionRules,
|
|
53
|
+
} from "./permissions.ts";
|
|
54
|
+
import {
|
|
55
|
+
SUBAGENT_CAPABILITY_CEILING_ENV,
|
|
56
|
+
capabilityCeilingAgentRestrictionSources,
|
|
57
|
+
decodeSubagentCapabilityCeiling,
|
|
58
|
+
encodeSubagentCapabilityCeiling,
|
|
59
|
+
intersectSubagentCapabilityCeilings,
|
|
60
|
+
isAgentAllowedByCapabilityCeiling,
|
|
61
|
+
type ResolvedSubagentCapabilityCeiling,
|
|
62
|
+
type SubagentCapabilityAudit,
|
|
63
|
+
} from "./capability-ceiling.ts";
|
|
19
64
|
|
|
20
65
|
const TASK_ARG_LIMIT = 8000;
|
|
21
66
|
const MAX_LAUNCH_RESOLVED_EXTENSION_IDS = 32;
|
|
22
|
-
const PROMPT_RUNTIME_EXTENSION_PATH = path.join(
|
|
23
|
-
|
|
67
|
+
const PROMPT_RUNTIME_EXTENSION_PATH = path.join(
|
|
68
|
+
path.dirname(fileURLToPath(import.meta.url)),
|
|
69
|
+
"subagent-prompt-runtime.ts",
|
|
70
|
+
);
|
|
71
|
+
const FANOUT_CHILD_EXTENSION_PATH = path.join(
|
|
72
|
+
path.dirname(fileURLToPath(import.meta.url)),
|
|
73
|
+
"..",
|
|
74
|
+
"..",
|
|
75
|
+
"extension",
|
|
76
|
+
"fanout-child.ts",
|
|
77
|
+
);
|
|
24
78
|
export const SUBAGENT_CHILD_ENV = "PI_SUBAGENT_CHILD";
|
|
25
|
-
export const SUBAGENT_ORCHESTRATOR_TARGET_ENV =
|
|
26
|
-
|
|
27
|
-
export const
|
|
79
|
+
export const SUBAGENT_ORCHESTRATOR_TARGET_ENV =
|
|
80
|
+
"PI_SUBAGENT_ORCHESTRATOR_TARGET";
|
|
81
|
+
export const SUBAGENT_ORCHESTRATOR_SESSION_ID_ENV =
|
|
82
|
+
"PI_SUBAGENT_ORCHESTRATOR_SESSION_ID";
|
|
83
|
+
export const SUBAGENT_SUPERVISOR_CHANNEL_DIR_ENV =
|
|
84
|
+
"PI_SUBAGENT_SUPERVISOR_CHANNEL_DIR";
|
|
28
85
|
export const SUBAGENT_RUN_ID_ENV = "PI_SUBAGENT_RUN_ID";
|
|
29
86
|
export const SUBAGENT_CHILD_AGENT_ENV = "PI_SUBAGENT_CHILD_AGENT";
|
|
30
87
|
export const SUBAGENT_CHILD_INDEX_ENV = "PI_SUBAGENT_CHILD_INDEX";
|
|
31
88
|
export const SUBAGENT_FANOUT_CHILD_ENV = "PI_SUBAGENT_FANOUT_CHILD";
|
|
32
89
|
export const SUBAGENT_PARENT_EVENT_SINK_ENV = "PI_SUBAGENT_PARENT_EVENT_SINK";
|
|
33
|
-
export const SUBAGENT_PARENT_CONTROL_INBOX_ENV =
|
|
90
|
+
export const SUBAGENT_PARENT_CONTROL_INBOX_ENV =
|
|
91
|
+
"PI_SUBAGENT_PARENT_CONTROL_INBOX";
|
|
34
92
|
export const SUBAGENT_PARENT_ROOT_RUN_ID_ENV = "PI_SUBAGENT_PARENT_ROOT_RUN_ID";
|
|
35
93
|
export const SUBAGENT_PARENT_RUN_ID_ENV = "PI_SUBAGENT_PARENT_RUN_ID";
|
|
36
94
|
export const SUBAGENT_PARENT_CHILD_INDEX_ENV = "PI_SUBAGENT_PARENT_CHILD_INDEX";
|
|
37
95
|
export const SUBAGENT_PARENT_DEPTH_ENV = "PI_SUBAGENT_PARENT_DEPTH";
|
|
38
96
|
export const SUBAGENT_PARENT_PATH_ENV = "PI_SUBAGENT_PARENT_PATH";
|
|
39
|
-
export const SUBAGENT_PARENT_CAPABILITY_TOKEN_ENV =
|
|
97
|
+
export const SUBAGENT_PARENT_CAPABILITY_TOKEN_ENV =
|
|
98
|
+
"PI_SUBAGENT_PARENT_CAPABILITY_TOKEN";
|
|
40
99
|
export const SUBAGENT_PARENT_SESSION_ENV = "PI_SUBAGENT_PARENT_SESSION";
|
|
41
100
|
export const SUBAGENT_STEER_INBOX_ENV = "PI_SUBAGENT_STEER_INBOX";
|
|
42
101
|
export const SUBAGENT_STEER_CAPABILITY_ENV = "PI_SUBAGENT_STEER_CAPABILITY";
|
|
@@ -87,6 +146,8 @@ export interface BuildPiArgsInput {
|
|
|
87
146
|
};
|
|
88
147
|
toolBudget?: ResolvedToolBudget;
|
|
89
148
|
allowZeroToolBudget?: boolean;
|
|
149
|
+
permissionRules?: PermissionRules;
|
|
150
|
+
permissionAuditPath?: string;
|
|
90
151
|
childWatchdog?: ChildWatchdogConfig;
|
|
91
152
|
waitToolEnabled?: boolean;
|
|
92
153
|
capabilityCeiling?: ResolvedSubagentCapabilityCeiling;
|
|
@@ -102,17 +163,37 @@ export interface BuildPiArgsResult {
|
|
|
102
163
|
}
|
|
103
164
|
|
|
104
165
|
function sanitizeSupervisorChannelSegment(value: string): string {
|
|
105
|
-
return
|
|
166
|
+
return (
|
|
167
|
+
value
|
|
168
|
+
.trim()
|
|
169
|
+
.replace(/[^A-Za-z0-9._-]+/g, "-")
|
|
170
|
+
.replace(/^-+|-+$/g, "") || "unknown"
|
|
171
|
+
);
|
|
106
172
|
}
|
|
107
173
|
|
|
108
|
-
function supervisorChannelDir(
|
|
109
|
-
|
|
174
|
+
function supervisorChannelDir(
|
|
175
|
+
runId: string,
|
|
176
|
+
agent: string,
|
|
177
|
+
childIndex: number,
|
|
178
|
+
): string {
|
|
179
|
+
return path.join(
|
|
180
|
+
TEMP_ROOT_DIR,
|
|
181
|
+
"supervisor-channels",
|
|
182
|
+
`${sanitizeSupervisorChannelSegment(runId)}-${sanitizeSupervisorChannelSegment(agent)}-${childIndex}`,
|
|
183
|
+
);
|
|
110
184
|
}
|
|
111
185
|
|
|
112
|
-
export function applyThinkingSuffix(
|
|
186
|
+
export function applyThinkingSuffix(
|
|
187
|
+
model: string | undefined,
|
|
188
|
+
thinking: string | false | undefined,
|
|
189
|
+
replaceExisting = false,
|
|
190
|
+
): string | undefined {
|
|
113
191
|
if (!model || !thinking) return model;
|
|
114
192
|
const colonIdx = model.lastIndexOf(":");
|
|
115
|
-
if (
|
|
193
|
+
if (
|
|
194
|
+
colonIdx !== -1 &&
|
|
195
|
+
THINKING_LEVELS.some((level) => level === model.substring(colonIdx + 1))
|
|
196
|
+
) {
|
|
116
197
|
return replaceExisting ? `${model.slice(0, colonIdx)}:${thinking}` : model;
|
|
117
198
|
}
|
|
118
199
|
return `${model}:${thinking}`;
|
|
@@ -125,7 +206,13 @@ export interface ResolvePiLaunchToolPlanInput {
|
|
|
125
206
|
mcpDirectTools?: string[];
|
|
126
207
|
cwd?: string;
|
|
127
208
|
requireReadTool?: boolean;
|
|
128
|
-
structuredOutput?:
|
|
209
|
+
structuredOutput?:
|
|
210
|
+
| boolean
|
|
211
|
+
| {
|
|
212
|
+
schema: JsonSchemaObject;
|
|
213
|
+
schemaPath: string;
|
|
214
|
+
outputPath: string;
|
|
215
|
+
};
|
|
129
216
|
capabilityCeiling?: ResolvedSubagentCapabilityCeiling;
|
|
130
217
|
inheritedCapabilityCeiling?: ResolvedSubagentCapabilityCeiling;
|
|
131
218
|
agentName?: string;
|
|
@@ -155,7 +242,10 @@ function extensionIdentifier(value: string): string {
|
|
|
155
242
|
return `sha256:${createHash("sha256").update(path.normalize(value.trim())).digest("hex").slice(0, 16)}`;
|
|
156
243
|
}
|
|
157
244
|
|
|
158
|
-
function boundedExtensionIdentifiers(values: string[]): {
|
|
245
|
+
function boundedExtensionIdentifiers(values: string[]): {
|
|
246
|
+
ids: string[];
|
|
247
|
+
omitted: number;
|
|
248
|
+
} {
|
|
159
249
|
const ids = [...new Set(values.map(extensionIdentifier))];
|
|
160
250
|
return {
|
|
161
251
|
ids: ids.slice(0, MAX_LAUNCH_RESOLVED_EXTENSION_IDS),
|
|
@@ -163,7 +253,15 @@ function boundedExtensionIdentifiers(values: string[]): { ids: string[]; omitted
|
|
|
163
253
|
};
|
|
164
254
|
}
|
|
165
255
|
|
|
166
|
-
export function projectLaunchResolvedChildExtensions(
|
|
256
|
+
export function projectLaunchResolvedChildExtensions(
|
|
257
|
+
toolPlan: Pick<
|
|
258
|
+
PiLaunchToolPlan,
|
|
259
|
+
| "runtimeExtensions"
|
|
260
|
+
| "configuredExtensions"
|
|
261
|
+
| "extensionArgs"
|
|
262
|
+
| "disableAmbientExtensions"
|
|
263
|
+
>,
|
|
264
|
+
): LaunchResolvedChildExtensionsV1 {
|
|
167
265
|
const runtime = boundedExtensionIdentifiers(toolPlan.runtimeExtensions);
|
|
168
266
|
const configured = boundedExtensionIdentifiers(toolPlan.configuredExtensions);
|
|
169
267
|
const effective = boundedExtensionIdentifiers(toolPlan.extensionArgs);
|
|
@@ -182,55 +280,207 @@ export function projectLaunchResolvedChildExtensions(toolPlan: Pick<PiLaunchTool
|
|
|
182
280
|
};
|
|
183
281
|
}
|
|
184
282
|
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
283
|
+
/**
|
|
284
|
+
* Resolve the permission-system extension entry point when installed.
|
|
285
|
+
* Returns the absolute path to the extension's main module, or undefined
|
|
286
|
+
* when the package is not installed. Callers can check `autoInject` config
|
|
287
|
+
* to decide whether to include it in child processes.
|
|
288
|
+
*/
|
|
289
|
+
export function resolvePermissionSystemExtension(): string | undefined {
|
|
290
|
+
const agentDir = getAgentDir();
|
|
291
|
+
const candidates = [
|
|
292
|
+
// npm-scoped package (most common)
|
|
293
|
+
path.join(
|
|
294
|
+
agentDir,
|
|
295
|
+
"npm",
|
|
296
|
+
"node_modules",
|
|
297
|
+
"@gotgenes",
|
|
298
|
+
"pi-permission-system",
|
|
299
|
+
),
|
|
300
|
+
// direct extension directory (some layouts)
|
|
301
|
+
path.join(agentDir, "extensions", "pi-permission-system"),
|
|
302
|
+
];
|
|
303
|
+
const errors: Error[] = [];
|
|
304
|
+
for (const extDir of candidates) {
|
|
305
|
+
if (!fs.existsSync(extDir)) continue;
|
|
306
|
+
const pkgPath = path.join(extDir, "package.json");
|
|
307
|
+
if (!fs.existsSync(pkgPath)) {
|
|
308
|
+
errors.push(new Error(`Permission-system package manifest is missing at ${pkgPath}.`));
|
|
309
|
+
continue;
|
|
310
|
+
}
|
|
311
|
+
try {
|
|
312
|
+
let pkg: { pi?: { extensions?: string[] } };
|
|
313
|
+
const parsed: unknown = JSON.parse(fs.readFileSync(pkgPath, "utf-8"));
|
|
314
|
+
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
315
|
+
throw new Error("manifest root must be an object");
|
|
316
|
+
}
|
|
317
|
+
pkg = parsed as typeof pkg;
|
|
318
|
+
const extensions = pkg.pi?.extensions;
|
|
319
|
+
const entry = Array.isArray(extensions) ? extensions[0] : undefined;
|
|
320
|
+
if (typeof entry !== "string" || !entry.trim()) {
|
|
321
|
+
throw new Error(
|
|
322
|
+
`Permission-system package manifest at ${pkgPath} must declare pi.extensions[0] as a non-empty string.`,
|
|
323
|
+
);
|
|
324
|
+
}
|
|
325
|
+
const resolved = path.resolve(extDir, entry);
|
|
326
|
+
if (fs.existsSync(resolved)) return resolved;
|
|
327
|
+
throw new Error(
|
|
328
|
+
`Permission-system extension entry ${JSON.stringify(entry)} in ${pkgPath} does not exist at ${resolved}.`,
|
|
329
|
+
);
|
|
330
|
+
} catch (error) {
|
|
331
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
332
|
+
errors.push(message.startsWith("Permission-system") ? new Error(message) : new Error(`Cannot read permission-system package manifest at ${pkgPath}: ${message}`));
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
if (errors.length > 0) throw errors[0]!;
|
|
336
|
+
return undefined;
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
export function resolvePiLaunchToolPlan(
|
|
340
|
+
input: ResolvePiLaunchToolPlanInput,
|
|
341
|
+
): PiLaunchToolPlan {
|
|
342
|
+
const capabilityCeiling = intersectSubagentCapabilityCeilings(
|
|
343
|
+
input.capabilityCeiling,
|
|
344
|
+
input.inheritedCapabilityCeiling,
|
|
345
|
+
);
|
|
346
|
+
const allowedToolSet =
|
|
347
|
+
capabilityCeiling?.allowedTools === undefined
|
|
348
|
+
? undefined
|
|
349
|
+
: new Set(capabilityCeiling.allowedTools);
|
|
350
|
+
const requestedBuiltinTools =
|
|
351
|
+
input.tools?.filter(
|
|
352
|
+
(tool) =>
|
|
353
|
+
!(tool.includes("/") || tool.endsWith(".ts") || tool.endsWith(".js")),
|
|
354
|
+
) ?? [];
|
|
189
355
|
if (input.requireReadTool && allowedToolSet && !allowedToolSet.has("read")) {
|
|
190
|
-
throw new Error(
|
|
356
|
+
throw new Error(
|
|
357
|
+
`Capability ceiling from ${capabilityCeiling?.sources.join(", ") || "unknown source"} excludes required tool 'read' for lazy skill loading.`,
|
|
358
|
+
);
|
|
191
359
|
}
|
|
192
|
-
const declaredBuiltinTools =
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
360
|
+
const declaredBuiltinTools =
|
|
361
|
+
input.tools === undefined
|
|
362
|
+
? allowedToolSet
|
|
363
|
+
? [...allowedToolSet]
|
|
364
|
+
: []
|
|
365
|
+
: (input.requireReadTool &&
|
|
366
|
+
requestedBuiltinTools.length > 0 &&
|
|
367
|
+
!requestedBuiltinTools.includes("read") &&
|
|
368
|
+
!allowedToolSet
|
|
369
|
+
? ["read", ...requestedBuiltinTools]
|
|
370
|
+
: requestedBuiltinTools
|
|
371
|
+
).filter((tool) => !allowedToolSet || allowedToolSet.has(tool));
|
|
197
372
|
const fanoutAuthorized = declaredBuiltinTools.includes("subagent");
|
|
198
|
-
const toolExtensionPaths: string[] = capabilityCeiling?.denyExtensions
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
373
|
+
const toolExtensionPaths: string[] = capabilityCeiling?.denyExtensions
|
|
374
|
+
? []
|
|
375
|
+
: (input.tools ?? []).filter(
|
|
376
|
+
(tool) =>
|
|
377
|
+
!requestedBuiltinTools.includes(tool) &&
|
|
378
|
+
(tool.includes("/") || tool.endsWith(".ts") || tool.endsWith(".js")),
|
|
379
|
+
);
|
|
380
|
+
const resolvedMcpSelections = capabilityCeiling?.denyExtensions
|
|
381
|
+
? []
|
|
382
|
+
: resolveMcpDirectToolSelections(input.mcpDirectTools, input.cwd);
|
|
383
|
+
const effectiveMcpSelections = resolvedMcpSelections.filter(
|
|
384
|
+
(selection) => !allowedToolSet || allowedToolSet.has(selection.name),
|
|
385
|
+
);
|
|
386
|
+
const effectiveMcpTools = effectiveMcpSelections.map(
|
|
387
|
+
(selection) => selection.name,
|
|
388
|
+
);
|
|
389
|
+
const explicitToolAllowlist =
|
|
390
|
+
input.tools !== undefined ||
|
|
391
|
+
(input.mcpDirectTools?.length ?? 0) > 0 ||
|
|
392
|
+
allowedToolSet !== undefined;
|
|
203
393
|
const internalTools = input.structuredOutput ? ["structured_output"] : [];
|
|
204
|
-
const effectiveToolAllowlist = [
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
394
|
+
const effectiveToolAllowlist = [
|
|
395
|
+
...new Set([
|
|
396
|
+
...declaredBuiltinTools,
|
|
397
|
+
...effectiveMcpTools,
|
|
398
|
+
...internalTools,
|
|
399
|
+
]),
|
|
400
|
+
];
|
|
401
|
+
const requiredChildTools = explicitToolAllowlist
|
|
402
|
+
? [
|
|
403
|
+
...new Set([
|
|
404
|
+
...(input.tools !== undefined ? declaredBuiltinTools : []),
|
|
405
|
+
...(input.mcpDirectTools?.length ? effectiveMcpTools : []),
|
|
406
|
+
...internalTools,
|
|
407
|
+
]),
|
|
408
|
+
]
|
|
409
|
+
: [];
|
|
410
|
+
const permSystemExt = capabilityCeiling?.denyExtensions
|
|
411
|
+
? undefined
|
|
412
|
+
: resolvePermissionSystemExtension();
|
|
413
|
+
const runtimeExtensions = [
|
|
414
|
+
PROMPT_RUNTIME_EXTENSION_PATH,
|
|
415
|
+
...(fanoutAuthorized ? [FANOUT_CHILD_EXTENSION_PATH] : []),
|
|
416
|
+
...(permSystemExt ? [permSystemExt] : []),
|
|
417
|
+
];
|
|
418
|
+
const disableAmbientExtensions =
|
|
419
|
+
capabilityCeiling?.denyExtensions === true ||
|
|
420
|
+
input.extensions !== undefined;
|
|
421
|
+
const configuredExtensions = capabilityCeiling?.denyExtensions
|
|
422
|
+
? []
|
|
423
|
+
: [
|
|
424
|
+
...toolExtensionPaths,
|
|
425
|
+
...(input.extensions ?? []),
|
|
426
|
+
...(input.subagentOnlyExtensions ?? []),
|
|
427
|
+
];
|
|
215
428
|
const extensionArgs = disableAmbientExtensions
|
|
216
429
|
? [...new Set([...runtimeExtensions, ...configuredExtensions])]
|
|
217
|
-
: [
|
|
218
|
-
|
|
219
|
-
|
|
430
|
+
: [
|
|
431
|
+
...new Set([
|
|
432
|
+
...runtimeExtensions,
|
|
433
|
+
...toolExtensionPaths,
|
|
434
|
+
...(input.subagentOnlyExtensions ?? []),
|
|
435
|
+
]),
|
|
436
|
+
];
|
|
437
|
+
const requestedToolNames =
|
|
438
|
+
input.tools !== undefined
|
|
439
|
+
? [
|
|
440
|
+
...new Set([
|
|
441
|
+
...requestedBuiltinTools,
|
|
442
|
+
...resolvedMcpSelections.map((selection) => selection.name),
|
|
443
|
+
]),
|
|
444
|
+
]
|
|
445
|
+
: undefined;
|
|
446
|
+
const capabilityAudit = capabilityCeiling
|
|
447
|
+
? ({
|
|
448
|
+
ceiling: capabilityCeiling,
|
|
449
|
+
...(requestedToolNames ? { requestedTools: requestedToolNames } : {}),
|
|
450
|
+
effectiveTools: effectiveToolAllowlist,
|
|
451
|
+
removedTools:
|
|
452
|
+
requestedToolNames?.filter(
|
|
453
|
+
(tool) => !effectiveToolAllowlist.includes(tool),
|
|
454
|
+
) ?? [],
|
|
455
|
+
internalTools,
|
|
456
|
+
extensionsDenied: capabilityCeiling.denyExtensions,
|
|
457
|
+
removedExtensionCount: capabilityCeiling.denyExtensions
|
|
458
|
+
? (input.extensions?.length ?? 0) +
|
|
459
|
+
(input.subagentOnlyExtensions?.length ?? 0) +
|
|
460
|
+
(input.tools ?? []).filter(
|
|
461
|
+
(tool) =>
|
|
462
|
+
tool.includes("/") ||
|
|
463
|
+
tool.endsWith(".ts") ||
|
|
464
|
+
tool.endsWith(".js"),
|
|
465
|
+
).length
|
|
466
|
+
: 0,
|
|
467
|
+
requestedMcpToolCount: input.mcpDirectTools?.length ?? 0,
|
|
468
|
+
effectiveMcpTools,
|
|
469
|
+
agentAllowed:
|
|
470
|
+
input.agentName === undefined
|
|
471
|
+
? true
|
|
472
|
+
: isAgentAllowedByCapabilityCeiling(
|
|
473
|
+
input.agentName,
|
|
474
|
+
capabilityCeiling,
|
|
475
|
+
),
|
|
476
|
+
...(capabilityCeilingAgentRestrictionSources(capabilityCeiling)
|
|
477
|
+
? {
|
|
478
|
+
agentRestrictionSources:
|
|
479
|
+
capabilityCeilingAgentRestrictionSources(capabilityCeiling),
|
|
480
|
+
}
|
|
481
|
+
: {}),
|
|
482
|
+
} satisfies SubagentCapabilityAudit)
|
|
220
483
|
: undefined;
|
|
221
|
-
const capabilityAudit = capabilityCeiling ? {
|
|
222
|
-
ceiling: capabilityCeiling,
|
|
223
|
-
...(requestedToolNames ? { requestedTools: requestedToolNames } : {}),
|
|
224
|
-
effectiveTools: effectiveToolAllowlist,
|
|
225
|
-
removedTools: requestedToolNames?.filter((tool) => !effectiveToolAllowlist.includes(tool)) ?? [],
|
|
226
|
-
internalTools,
|
|
227
|
-
extensionsDenied: capabilityCeiling.denyExtensions,
|
|
228
|
-
removedExtensionCount: capabilityCeiling.denyExtensions ? (input.extensions?.length ?? 0) + (input.subagentOnlyExtensions?.length ?? 0) + ((input.tools ?? []).filter((tool) => tool.includes("/") || tool.endsWith(".ts") || tool.endsWith(".js")).length) : 0,
|
|
229
|
-
requestedMcpToolCount: input.mcpDirectTools?.length ?? 0,
|
|
230
|
-
effectiveMcpTools,
|
|
231
|
-
agentAllowed: input.agentName === undefined ? true : isAgentAllowedByCapabilityCeiling(input.agentName, capabilityCeiling),
|
|
232
|
-
...(capabilityCeilingAgentRestrictionSources(capabilityCeiling) ? { agentRestrictionSources: capabilityCeilingAgentRestrictionSources(capabilityCeiling) } : {}),
|
|
233
|
-
} satisfies SubagentCapabilityAudit : undefined;
|
|
234
484
|
return {
|
|
235
485
|
...(capabilityCeiling ? { capabilityCeiling } : {}),
|
|
236
486
|
requestedBuiltinTools,
|
|
@@ -252,6 +502,15 @@ export function resolvePiLaunchToolPlan(input: ResolvePiLaunchToolPlanInput): Pi
|
|
|
252
502
|
};
|
|
253
503
|
}
|
|
254
504
|
|
|
505
|
+
/** Escape XML-significant characters in a string for safe attribute interpolation. */
|
|
506
|
+
function escapeXmlAttr(value: string): string {
|
|
507
|
+
return value
|
|
508
|
+
.replace(/&/g, "&")
|
|
509
|
+
.replace(/"/g, """)
|
|
510
|
+
.replace(/</g, "<")
|
|
511
|
+
.replace(/>/g, ">");
|
|
512
|
+
}
|
|
513
|
+
|
|
255
514
|
export function buildPiArgs(input: BuildPiArgsInput): BuildPiArgsResult {
|
|
256
515
|
const args = [...input.baseArgs];
|
|
257
516
|
|
|
@@ -282,17 +541,23 @@ export function buildPiArgs(input: BuildPiArgsInput): BuildPiArgsResult {
|
|
|
282
541
|
requireReadTool: input.requireReadTool,
|
|
283
542
|
structuredOutput: input.structuredOutput,
|
|
284
543
|
capabilityCeiling: input.capabilityCeiling,
|
|
285
|
-
inheritedCapabilityCeiling: decodeSubagentCapabilityCeiling(
|
|
544
|
+
inheritedCapabilityCeiling: decodeSubagentCapabilityCeiling(
|
|
545
|
+
process.env[SUBAGENT_CAPABILITY_CEILING_ENV],
|
|
546
|
+
),
|
|
286
547
|
agentName: input.childAgentName,
|
|
287
548
|
});
|
|
288
549
|
if (toolPlan.explicitToolAllowlist) {
|
|
289
|
-
args.push(
|
|
290
|
-
|
|
550
|
+
args.push(
|
|
551
|
+
toolPlan.effectiveToolAllowlist.length > 0 ? "--tools" : "--no-tools",
|
|
552
|
+
);
|
|
553
|
+
if (toolPlan.effectiveToolAllowlist.length > 0)
|
|
554
|
+
args.push(toolPlan.effectiveToolAllowlist.join(","));
|
|
291
555
|
}
|
|
292
556
|
if (toolPlan.disableAmbientExtensions) {
|
|
293
557
|
args.push("--no-extensions");
|
|
294
558
|
}
|
|
295
|
-
for (const extPath of toolPlan.extensionArgs)
|
|
559
|
+
for (const extPath of toolPlan.extensionArgs)
|
|
560
|
+
args.push("--extension", extPath);
|
|
296
561
|
|
|
297
562
|
if (!input.inheritProjectContext) {
|
|
298
563
|
args.push("--no-context-files");
|
|
@@ -306,8 +571,18 @@ export function buildPiArgs(input: BuildPiArgsInput): BuildPiArgsResult {
|
|
|
306
571
|
tempDir = fs.mkdtempSync(path.join(os.tmpdir(), "pi-subagent-"));
|
|
307
572
|
const stem = (input.promptFileStem ?? "prompt").replace(/[^\w.-]/g, "_");
|
|
308
573
|
const promptPath = path.join(tempDir, `${stem}.md`);
|
|
309
|
-
|
|
310
|
-
|
|
574
|
+
// Inject <active_agent> tag so @gotgenes/pi-permission-system can
|
|
575
|
+
// resolve per-agent policy inside the child session.
|
|
576
|
+
const taggedPrompt = input.childAgentName
|
|
577
|
+
? `<active_agent name="${escapeXmlAttr(input.childAgentName)}"/>\n\n${input.systemPrompt}`
|
|
578
|
+
: input.systemPrompt;
|
|
579
|
+
fs.writeFileSync(promptPath, taggedPrompt, { mode: 0o600 });
|
|
580
|
+
args.push(
|
|
581
|
+
input.systemPromptMode === "replace"
|
|
582
|
+
? "--system-prompt"
|
|
583
|
+
: "--append-system-prompt",
|
|
584
|
+
promptPath,
|
|
585
|
+
);
|
|
311
586
|
}
|
|
312
587
|
|
|
313
588
|
if (input.task.length > TASK_ARG_LIMIT) {
|
|
@@ -322,58 +597,106 @@ export function buildPiArgs(input: BuildPiArgsInput): BuildPiArgsResult {
|
|
|
322
597
|
}
|
|
323
598
|
|
|
324
599
|
const env: Record<string, string | undefined> = {};
|
|
325
|
-
const piPackageRoot =
|
|
600
|
+
const piPackageRoot =
|
|
601
|
+
process.env[PI_CODING_AGENT_PACKAGE_ROOT_ENV] ?? resolvePiPackageRoot();
|
|
326
602
|
if (piPackageRoot) env[PI_CODING_AGENT_PACKAGE_ROOT_ENV] = piPackageRoot;
|
|
327
|
-
if (!tempDir)
|
|
328
|
-
|
|
603
|
+
if (!tempDir)
|
|
604
|
+
tempDir = fs.mkdtempSync(path.join(os.tmpdir(), "pi-subagent-"));
|
|
605
|
+
const runtimeAcknowledgedExtensionsPath = path.join(
|
|
606
|
+
tempDir,
|
|
607
|
+
"runtime-acknowledged-extensions.json",
|
|
608
|
+
);
|
|
329
609
|
env[RUNTIME_EXTENSION_ACK_PATH_ENV] = runtimeAcknowledgedExtensionsPath;
|
|
330
610
|
let toolDiagnosticPath: string | undefined;
|
|
331
611
|
if (toolPlan.requiredChildTools.length > 0) {
|
|
332
|
-
if (!tempDir)
|
|
612
|
+
if (!tempDir)
|
|
613
|
+
tempDir = fs.mkdtempSync(path.join(os.tmpdir(), "pi-subagent-"));
|
|
333
614
|
toolDiagnosticPath = path.join(tempDir, "tool-diagnostic.json");
|
|
334
615
|
env[REQUIRED_CHILD_TOOLS_ENV] = JSON.stringify(toolPlan.requiredChildTools);
|
|
335
616
|
env[CHILD_TOOL_DIAGNOSTIC_PATH_ENV] = toolDiagnosticPath;
|
|
336
617
|
}
|
|
337
|
-
env[MCP_DIRECT_CHILD_TOOLS_ENV] =
|
|
618
|
+
env[MCP_DIRECT_CHILD_TOOLS_ENV] =
|
|
619
|
+
toolPlan.effectiveMcpTools.length > 0
|
|
620
|
+
? JSON.stringify(toolPlan.effectiveMcpTools)
|
|
621
|
+
: undefined;
|
|
338
622
|
env[SUBAGENT_CHILD_ENV] = "1";
|
|
339
623
|
env[SUBAGENT_FANOUT_CHILD_ENV] = toolPlan.fanoutAuthorized ? "1" : "0";
|
|
340
624
|
if (input.waitToolEnabled !== undefined) {
|
|
341
625
|
env[WAIT_TOOL_ENABLED_ENV] = input.waitToolEnabled ? "true" : "false";
|
|
342
626
|
}
|
|
343
|
-
const inheritedNestedRoute = Boolean(
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
627
|
+
const inheritedNestedRoute = Boolean(
|
|
628
|
+
process.env[SUBAGENT_PARENT_EVENT_SINK_ENV] &&
|
|
629
|
+
process.env[SUBAGENT_PARENT_ROOT_RUN_ID_ENV] &&
|
|
630
|
+
process.env[SUBAGENT_PARENT_CAPABILITY_TOKEN_ENV],
|
|
631
|
+
);
|
|
632
|
+
const parentRunId =
|
|
633
|
+
input.parentRunId ??
|
|
634
|
+
input.runId ??
|
|
635
|
+
(inheritedNestedRoute ? process.env[SUBAGENT_RUN_ID_ENV] : undefined) ??
|
|
636
|
+
process.env[SUBAGENT_PARENT_RUN_ID_ENV] ??
|
|
637
|
+
"";
|
|
638
|
+
const parentChildIndex =
|
|
639
|
+
input.parentChildIndex !== undefined
|
|
640
|
+
? String(input.parentChildIndex)
|
|
641
|
+
: input.childIndex !== undefined
|
|
642
|
+
? String(input.childIndex)
|
|
643
|
+
: (process.env[SUBAGENT_PARENT_CHILD_INDEX_ENV] ?? "");
|
|
350
644
|
const inheritedDepth = Number(process.env[SUBAGENT_PARENT_DEPTH_ENV]);
|
|
351
|
-
const parentDepth =
|
|
645
|
+
const parentDepth =
|
|
646
|
+
input.parentDepth ??
|
|
647
|
+
(inheritedNestedRoute && Number.isFinite(inheritedDepth)
|
|
648
|
+
? inheritedDepth + 1
|
|
649
|
+
: 1);
|
|
352
650
|
const parentPath = input.parentPath ?? [
|
|
353
651
|
...parseNestedPathEnv(process.env[SUBAGENT_PARENT_PATH_ENV]),
|
|
354
|
-
...(parentRunId
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
652
|
+
...(parentRunId
|
|
653
|
+
? [
|
|
654
|
+
{
|
|
655
|
+
runId: parentRunId,
|
|
656
|
+
...(parentChildIndex && /^\d+$/.test(parentChildIndex)
|
|
657
|
+
? { stepIndex: Number(parentChildIndex) }
|
|
658
|
+
: {}),
|
|
659
|
+
...(input.childAgentName ? { agent: input.childAgentName } : {}),
|
|
660
|
+
},
|
|
661
|
+
]
|
|
662
|
+
: []),
|
|
359
663
|
];
|
|
360
664
|
env[SUBAGENT_PARENT_EVENT_SINK_ENV] = toolPlan.fanoutAuthorized
|
|
361
|
-
? input.parentEventSink ??
|
|
665
|
+
? (input.parentEventSink ??
|
|
666
|
+
process.env[SUBAGENT_PARENT_EVENT_SINK_ENV] ??
|
|
667
|
+
"")
|
|
362
668
|
: "";
|
|
363
669
|
env[SUBAGENT_PARENT_CONTROL_INBOX_ENV] = toolPlan.fanoutAuthorized
|
|
364
|
-
? input.parentControlInbox ??
|
|
670
|
+
? (input.parentControlInbox ??
|
|
671
|
+
process.env[SUBAGENT_PARENT_CONTROL_INBOX_ENV] ??
|
|
672
|
+
"")
|
|
365
673
|
: "";
|
|
366
674
|
env[SUBAGENT_PARENT_ROOT_RUN_ID_ENV] = toolPlan.fanoutAuthorized
|
|
367
|
-
? input.parentRootRunId ??
|
|
675
|
+
? (input.parentRootRunId ??
|
|
676
|
+
process.env[SUBAGENT_PARENT_ROOT_RUN_ID_ENV] ??
|
|
677
|
+
input.runId ??
|
|
678
|
+
"")
|
|
679
|
+
: "";
|
|
680
|
+
env[SUBAGENT_PARENT_RUN_ID_ENV] = toolPlan.fanoutAuthorized
|
|
681
|
+
? parentRunId
|
|
682
|
+
: "";
|
|
683
|
+
env[SUBAGENT_PARENT_CHILD_INDEX_ENV] = toolPlan.fanoutAuthorized
|
|
684
|
+
? parentChildIndex
|
|
685
|
+
: "";
|
|
686
|
+
env[SUBAGENT_PARENT_DEPTH_ENV] = toolPlan.fanoutAuthorized
|
|
687
|
+
? String(parentDepth)
|
|
688
|
+
: "";
|
|
689
|
+
env[SUBAGENT_PARENT_PATH_ENV] = toolPlan.fanoutAuthorized
|
|
690
|
+
? encodeNestedPathEnv(parentPath)
|
|
368
691
|
: "";
|
|
369
|
-
env[SUBAGENT_PARENT_RUN_ID_ENV] = toolPlan.fanoutAuthorized ? parentRunId : "";
|
|
370
|
-
env[SUBAGENT_PARENT_CHILD_INDEX_ENV] = toolPlan.fanoutAuthorized ? parentChildIndex : "";
|
|
371
|
-
env[SUBAGENT_PARENT_DEPTH_ENV] = toolPlan.fanoutAuthorized ? String(parentDepth) : "";
|
|
372
|
-
env[SUBAGENT_PARENT_PATH_ENV] = toolPlan.fanoutAuthorized ? encodeNestedPathEnv(parentPath) : "";
|
|
373
692
|
env[SUBAGENT_PARENT_CAPABILITY_TOKEN_ENV] = toolPlan.fanoutAuthorized
|
|
374
|
-
? input.parentCapabilityToken ??
|
|
693
|
+
? (input.parentCapabilityToken ??
|
|
694
|
+
process.env[SUBAGENT_PARENT_CAPABILITY_TOKEN_ENV] ??
|
|
695
|
+
"")
|
|
375
696
|
: "";
|
|
376
|
-
env.PI_SUBAGENT_INHERIT_PROJECT_CONTEXT = input.inheritProjectContext
|
|
697
|
+
env.PI_SUBAGENT_INHERIT_PROJECT_CONTEXT = input.inheritProjectContext
|
|
698
|
+
? "1"
|
|
699
|
+
: "0";
|
|
377
700
|
env.PI_SUBAGENT_INHERIT_SKILLS = input.inheritSkills ? "1" : "0";
|
|
378
701
|
env[PI_INTERCOM_STABLE_ID_ENV] = input.intercomSessionName || undefined;
|
|
379
702
|
env[PI_INTERCOM_SESSION_ID_ENV] = undefined;
|
|
@@ -386,13 +709,26 @@ export function buildPiArgs(input: BuildPiArgsInput): BuildPiArgsResult {
|
|
|
386
709
|
if (input.parentSessionId) {
|
|
387
710
|
env[SUBAGENT_ORCHESTRATOR_SESSION_ID_ENV] = input.parentSessionId;
|
|
388
711
|
}
|
|
389
|
-
|
|
712
|
+
const encodedPermissionRules = encodePermissionRules(input.permissionRules);
|
|
713
|
+
if (
|
|
714
|
+
input.orchestratorIntercomTarget &&
|
|
715
|
+
input.parentSessionId &&
|
|
716
|
+
input.runId &&
|
|
717
|
+
input.childAgentName
|
|
718
|
+
) {
|
|
390
719
|
const childIndex = input.childIndex ?? 0;
|
|
391
|
-
const channelDir = supervisorChannelDir(
|
|
720
|
+
const channelDir = supervisorChannelDir(
|
|
721
|
+
input.runId,
|
|
722
|
+
input.childAgentName,
|
|
723
|
+
childIndex,
|
|
724
|
+
);
|
|
392
725
|
fs.mkdirSync(path.join(channelDir, "requests"), { recursive: true });
|
|
393
726
|
fs.mkdirSync(path.join(channelDir, "replies"), { recursive: true });
|
|
394
727
|
env[SUBAGENT_SUPERVISOR_CHANNEL_DIR_ENV] = channelDir;
|
|
395
728
|
}
|
|
729
|
+
if (encodedPermissionRules)
|
|
730
|
+
env[PERMISSION_AUDIT_PATH_ENV] =
|
|
731
|
+
input.permissionAuditPath ?? path.join(tempDir, "permission-audit.jsonl");
|
|
396
732
|
if (input.runId) {
|
|
397
733
|
env[SUBAGENT_RUN_ID_ENV] = input.runId;
|
|
398
734
|
}
|
|
@@ -402,11 +738,24 @@ export function buildPiArgs(input: BuildPiArgsInput): BuildPiArgsResult {
|
|
|
402
738
|
if (input.childIndex !== undefined) {
|
|
403
739
|
env[SUBAGENT_CHILD_INDEX_ENV] = String(input.childIndex);
|
|
404
740
|
}
|
|
405
|
-
if (!toolPlan.capabilityCeiling && input.mcpDirectTools?.length)
|
|
406
|
-
|
|
741
|
+
if (!toolPlan.capabilityCeiling && input.mcpDirectTools?.length)
|
|
742
|
+
env.MCP_DIRECT_TOOLS = input.mcpDirectTools.join(",");
|
|
743
|
+
else if (
|
|
744
|
+
toolPlan.capabilityCeiling &&
|
|
745
|
+
toolPlan.effectiveMcpSelections.length &&
|
|
746
|
+
!toolPlan.capabilityCeiling.denyExtensions
|
|
747
|
+
)
|
|
748
|
+
env.MCP_DIRECT_TOOLS = toolPlan.effectiveMcpSelections
|
|
749
|
+
.map((selection) => selection.selector)
|
|
750
|
+
.join(",");
|
|
407
751
|
else env.MCP_DIRECT_TOOLS = "__none__";
|
|
408
|
-
const encodedCapabilityCeiling = encodeSubagentCapabilityCeiling(
|
|
409
|
-
|
|
752
|
+
const encodedCapabilityCeiling = encodeSubagentCapabilityCeiling(
|
|
753
|
+
toolPlan.capabilityCeiling,
|
|
754
|
+
);
|
|
755
|
+
if (encodedCapabilityCeiling)
|
|
756
|
+
env[SUBAGENT_CAPABILITY_CEILING_ENV] = encodedCapabilityCeiling;
|
|
757
|
+
if (encodedPermissionRules)
|
|
758
|
+
env[PERMISSION_POLICY_ENV] = encodedPermissionRules;
|
|
410
759
|
if (input.structuredOutput) {
|
|
411
760
|
env[STRUCTURED_OUTPUT_CAPTURE_ENV] = input.structuredOutput.outputPath;
|
|
412
761
|
env[STRUCTURED_OUTPUT_SCHEMA_ENV] = input.structuredOutput.schemaPath;
|
|
@@ -414,17 +763,27 @@ export function buildPiArgs(input: BuildPiArgsInput): BuildPiArgsResult {
|
|
|
414
763
|
if (input.steerInboxDir) {
|
|
415
764
|
env[SUBAGENT_STEER_INBOX_ENV] = input.steerInboxDir;
|
|
416
765
|
}
|
|
417
|
-
if (input.steerCapabilityPath)
|
|
766
|
+
if (input.steerCapabilityPath)
|
|
767
|
+
env[SUBAGENT_STEER_CAPABILITY_ENV] = input.steerCapabilityPath;
|
|
418
768
|
if (input.steerAckDir) env[SUBAGENT_STEER_ACK_DIR_ENV] = input.steerAckDir;
|
|
419
769
|
const encodedToolBudget = encodeToolBudgetEnv(input.toolBudget);
|
|
420
770
|
if (encodedToolBudget) env[TOOL_BUDGET_ENV] = encodedToolBudget;
|
|
421
771
|
env[TOOL_BUDGET_ZERO_AUTH_ENV] = input.allowZeroToolBudget ? "1" : undefined;
|
|
422
772
|
const encodedChildWatchdog = encodeChildWatchdogConfig(input.childWatchdog);
|
|
423
|
-
if (encodedChildWatchdog)
|
|
773
|
+
if (encodedChildWatchdog)
|
|
774
|
+
env[CHILD_WATCHDOG_CONFIG_ENV] = encodedChildWatchdog;
|
|
424
775
|
|
|
425
|
-
env[SUBAGENT_PARENT_SESSION_ENV] =
|
|
776
|
+
env[SUBAGENT_PARENT_SESSION_ENV] =
|
|
777
|
+
input.parentSessionId ?? process.env[SUBAGENT_PARENT_SESSION_ENV] ?? "";
|
|
426
778
|
|
|
427
|
-
return {
|
|
779
|
+
return {
|
|
780
|
+
args,
|
|
781
|
+
env,
|
|
782
|
+
tempDir,
|
|
783
|
+
toolDiagnosticPath,
|
|
784
|
+
runtimeAcknowledgedExtensionsPath,
|
|
785
|
+
capabilityAudit: toolPlan.capabilityAudit,
|
|
786
|
+
};
|
|
428
787
|
}
|
|
429
788
|
|
|
430
789
|
export const parseParentPathEnv = parseNestedPathEnv;
|