pi-subagents 0.82.1 → 0.83.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/CHANGELOG.md +49 -0
- package/bundle/agents.js +5 -5
- package/bundle/background-work.js +1 -1
- package/bundle/capability-ceiling.js +1 -1
- package/bundle/child-tool-plan.js +4 -4
- package/bundle/{chunk-RMQFMMAT.js → chunk-2D52JFLF.js} +231 -10
- package/bundle/{chunk-52UBALJL.js → chunk-2DHZTCOL.js} +2 -2
- package/bundle/{chunk-43SCHIMD.js → chunk-2S4K53MV.js} +1 -1
- package/bundle/{chunk-IVAE5Z6Q.js → chunk-5YIITCPD.js} +31 -27
- package/bundle/{chunk-JYUKW2SY.js → chunk-AHIFYGR3.js} +13 -13
- package/bundle/{chunk-XSWOTIA3.js → chunk-C5P5CHYK.js} +1 -1
- package/bundle/{chunk-PDZWJCHD.js → chunk-C7JMPU5F.js} +10 -7
- package/bundle/{chunk-5TYMSZX3.js → chunk-D3JAFGMO.js} +2 -2
- package/bundle/{chunk-OYF6AFDY.js → chunk-F4ASL6OV.js} +2 -2
- package/bundle/{chunk-ZIV4J4HG.js → chunk-F5DBXJ2G.js} +51 -34
- package/bundle/{chunk-YKEWIB4M.js → chunk-G2Z6ZH26.js} +1 -1
- package/bundle/{chunk-G4GZD3OJ.js → chunk-IPGZMQXV.js} +11 -11
- package/bundle/{chunk-5LFLVSTM.js → chunk-JEZOSEWG.js} +2 -0
- package/bundle/{chunk-PLCCBLPY.js → chunk-LFDBD4PW.js} +2 -2
- package/bundle/{chunk-CIZQXJ5Q.js → chunk-LNRJCP2Y.js} +56 -20
- package/bundle/{chunk-UTT254JE.js → chunk-MABL3FUM.js} +8 -4
- package/bundle/{chunk-3JCDWF4V.js → chunk-NPIYWVOD.js} +12 -18
- package/bundle/{chunk-UCPP4GNU.js → chunk-QP5ZWNIS.js} +12 -5
- package/bundle/{chunk-Z7KVHQHL.js → chunk-QXASAHIA.js} +2 -2
- package/bundle/{chunk-46XKCPJR.js → chunk-RNIZLSEA.js} +2221 -3260
- package/bundle/{chunk-GJECHSAR.js → chunk-SSG7IEP5.js} +2 -2
- package/bundle/{chunk-VSUSLDNW.js → chunk-UFL7IYCW.js} +10 -8
- package/bundle/{chunk-QE4AGIMG.js → chunk-UUP372DR.js} +482 -705
- package/bundle/{chunk-6XJB7PIX.js → chunk-UYK5MZWE.js} +16 -12
- package/bundle/{chunk-4SDU2BZX.js → chunk-V2BZYLEP.js} +3 -3
- package/bundle/{chunk-FXUXCX2K.js → chunk-VLFZIN6D.js} +6 -6
- package/bundle/{chunk-N2BN7BF5.js → chunk-XA3DY6UG.js} +7 -5
- package/bundle/{chunk-PBK2I7WY.js → chunk-YXFJVCOL.js} +6 -6
- package/bundle/{chunk-4Y2ROR7L.js → chunk-ZVOAMTUQ.js} +5 -5
- package/bundle/control-channel.js +4 -4
- package/bundle/index.js +1 -1
- package/bundle/intercom-bridge.js +4 -4
- package/bundle/preflight.js +10 -10
- package/bundle/project-panes.js +5 -5
- package/bundle/shared-types.js +1 -1
- package/docs/configuration.md +13 -2
- package/docs/extension-api.md +21 -4
- package/docs/missions.md +2 -0
- package/docs/observability.md +1 -0
- package/docs/tool-reference.md +2 -2
- package/package.json +1 -1
- package/skills/pi-subagents/SKILL.md +6 -6
- package/src/agents/agent-management.d.ts +1 -1
- package/src/agents/agent-management.js +10 -16
- package/src/agents/agent-serializer.js +1 -2
- package/src/agents/agents.js +20 -5
- package/src/agents/frontmatter.js +22 -18
- package/src/api/background-work.d.ts +9 -6
- package/src/api/background-work.js +14 -7
- package/src/extension/index.js +6 -3
- package/src/extension/public-execution.d.ts +2 -2
- package/src/extension/public-execution.js +3 -3
- package/src/extension/reply-workflow-script.js +4 -5
- package/src/extension/rpc.js +3 -1
- package/src/extension/subagent-options.js +17 -4
- package/src/missions/actions.js +7 -2
- package/src/missions/lifecycle.d.ts +11 -0
- package/src/missions/lifecycle.js +37 -6
- package/src/missions/store.js +1 -0
- package/src/missions/types.d.ts +2 -0
- package/src/runs/background/async-execution.d.ts +1 -1
- package/src/runs/background/async-execution.js +7 -4
- package/src/runs/background/async-job-tracker.js +2 -1
- package/src/runs/background/async-resume.js +3 -2
- package/src/runs/background/auto-drain.js +2 -3
- package/src/runs/background/fleet-view.js +1 -1
- package/src/runs/background/retained-children.js +1 -1
- package/src/runs/background/run-child-session.js +22 -6
- package/src/runs/background/subagent-wait.d.ts +2 -1
- package/src/runs/background/subagent-wait.js +5 -2
- package/src/runs/foreground/execution.js +22 -6
- package/src/runs/foreground/subagent-executor.js +26 -56
- package/src/runs/shared/capability-ceiling.d.ts +2 -1
- package/src/runs/shared/capability-ceiling.js +3 -2
- package/src/runs/shared/child-launch.js +5 -2
- package/src/runs/shared/child-session.d.ts +6 -0
- package/src/runs/shared/child-session.js +20 -4
- package/src/runs/shared/herdr-machine.d.ts +2 -0
- package/src/runs/shared/herdr-machine.js +2 -0
- package/src/runs/shared/herdr-placed-run.js +11 -4
- package/src/runs/shared/parallel-handoff.d.ts +1 -1
- package/src/runs/shared/parallel-handoff.js +10 -6
- package/src/runs/shared/subagent-prompt-runtime.js +11 -17
- package/src/shared/disabled-features.d.ts +3 -1
- package/src/shared/disabled-features.js +11 -3
- package/src/shared/types.d.ts +4 -2
- package/src/shared/types.js +2 -0
- package/src/workflows/scripted-workflow.js +13 -1071
- package/workflow-script-worker.cjs +1068 -0
|
@@ -153,15 +153,18 @@ function resetExtensionCacheOnReload(loader) {
|
|
|
153
153
|
loader.loaded = true;
|
|
154
154
|
return true;
|
|
155
155
|
}
|
|
156
|
+
/** Applies `values` to `process.env` and returns a function that puts back the values they replaced. */
|
|
156
157
|
function applyProcessEnv(values) {
|
|
157
158
|
if (!values)
|
|
158
|
-
return;
|
|
159
|
+
return () => { };
|
|
160
|
+
const previous = Object.fromEntries(Object.keys(values).map((name) => [name, process.env[name]]));
|
|
159
161
|
for (const [name, value] of Object.entries(values)) {
|
|
160
162
|
if (value === undefined)
|
|
161
163
|
delete process.env[name];
|
|
162
164
|
else
|
|
163
165
|
process.env[name] = value;
|
|
164
166
|
}
|
|
167
|
+
return () => applyProcessEnv(previous);
|
|
165
168
|
}
|
|
166
169
|
/**
|
|
167
170
|
* Pi's built-in MCP extension registers server tools with the configured exposure, `codemode` by
|
|
@@ -458,7 +461,11 @@ export function createDefaultChildSessionFactory(options = {}) {
|
|
|
458
461
|
await commands?.shutdown();
|
|
459
462
|
const runner = session.extensionRunner;
|
|
460
463
|
if (runner.hasHandlers("session_shutdown")) {
|
|
461
|
-
|
|
464
|
+
// Ref'd so a detached runner with nothing else pending stays alive until the bound
|
|
465
|
+
// ends and still publishes its result; cleared as soon as the handlers finish.
|
|
466
|
+
let bound;
|
|
467
|
+
await Promise.race([runner.emit({ type: "session_shutdown", reason: "quit" }), new Promise((resolve) => { bound = setTimeout(resolve, shutdownTimeoutMs); })])
|
|
468
|
+
.finally(() => clearTimeout(bound));
|
|
462
469
|
}
|
|
463
470
|
}
|
|
464
471
|
catch (error) {
|
|
@@ -469,8 +476,7 @@ export function createDefaultChildSessionFactory(options = {}) {
|
|
|
469
476
|
}
|
|
470
477
|
};
|
|
471
478
|
let inheritedProviders = new Set();
|
|
472
|
-
const
|
|
473
|
-
applyProcessEnv(launch.processEnv);
|
|
479
|
+
const openSession = async () => {
|
|
474
480
|
if (!resetExtensionCacheOnReload(loader) && (launch.ambientExtensions || launch.extensionPaths.length))
|
|
475
481
|
launch.onExtensionError?.({ extensionPath: "<loader>", event: "load", error: new Error("pi's extension cache reset is unavailable; extensions loaded into this child share module state with other sessions in this process.") });
|
|
476
482
|
await loader.reload();
|
|
@@ -559,6 +565,16 @@ export function createDefaultChildSessionFactory(options = {}) {
|
|
|
559
565
|
}
|
|
560
566
|
return session;
|
|
561
567
|
};
|
|
568
|
+
const open = async () => {
|
|
569
|
+
const restoreEnv = applyProcessEnv(launch.processEnv);
|
|
570
|
+
try {
|
|
571
|
+
return await openSession();
|
|
572
|
+
}
|
|
573
|
+
finally {
|
|
574
|
+
if (launch.restoreProcessEnv)
|
|
575
|
+
restoreEnv();
|
|
576
|
+
}
|
|
577
|
+
};
|
|
562
578
|
const opened = loading.catch(() => { }).then(open);
|
|
563
579
|
loading = opened;
|
|
564
580
|
const session = await opened;
|
|
@@ -42,6 +42,8 @@ export interface PreparedHerdrMachineExternalCliRun {
|
|
|
42
42
|
export declare function resolveHerdrMachinePlacement(input: ResolveHerdrMachinePlacementInput): HerdrMachinePlacement;
|
|
43
43
|
/** `local` resolves to a Rex pane on this machine; a name with a `rex` entry in user settings to a Rex pane on that SSH host; any other value to a Herdr saved machine. */
|
|
44
44
|
export declare function resolveMachinePlacement(input: ResolveHerdrMachinePlacementInput): MachinePlacement;
|
|
45
|
+
/** A placed Pi keeps its transcript on the pane's machine, so it can't start from a local one. */
|
|
46
|
+
export declare const PLACED_RESTORE_UNSUPPORTED = "Pane-native remote Pi does not support fork, resume, or revival; use fresh context.";
|
|
45
47
|
export declare function formatHerdrMachineRunnerUnsupported(input: {
|
|
46
48
|
machine?: string;
|
|
47
49
|
agentName: string;
|
|
@@ -233,6 +233,8 @@ export function resolveMachinePlacement(input) {
|
|
|
233
233
|
return { machine: { provider: "rex", id: requested, target: settings.rex.ssh, cwd: validateRemoteCwd(remoteMachineCwd(input.stepCwd, settings.cwd, requested), requested) } };
|
|
234
234
|
return resolveHerdrMachinePlacement(input);
|
|
235
235
|
}
|
|
236
|
+
/** A placed Pi keeps its transcript on the pane's machine, so it can't start from a local one. */
|
|
237
|
+
export const PLACED_RESTORE_UNSUPPORTED = "Pane-native remote Pi does not support fork, resume, or revival; use fresh context.";
|
|
236
238
|
export function formatHerdrMachineRunnerUnsupported(input) {
|
|
237
239
|
if (input.machine === undefined)
|
|
238
240
|
return undefined;
|
|
@@ -8,6 +8,7 @@ import { encodeHerdrPiFrame, HERDR_PI_MODE_ENV, HERDR_PI_PROTOCOL, HERDR_PI_RUN_
|
|
|
8
8
|
import { discoverPlacedBridgeManifest } from "./placed-run-owner.js";
|
|
9
9
|
import { RexPlacedRunOwner } from "./rex-pane-host.js";
|
|
10
10
|
import { isRexLocalMachine } from "./rex-machine.js";
|
|
11
|
+
import { PLACED_RESTORE_UNSUPPORTED } from "./herdr-machine.js";
|
|
11
12
|
/** The pane half comes from the host; the bridge half (run, package, protocol, native session, evidence cursor) is host-neutral. */
|
|
12
13
|
export function reconcileHerdrReconnect(identity, candidate, lastEvidenceCursor, host = herdrPaneHost) {
|
|
13
14
|
return host.reconcile(identity, candidate, () => { const bridge = candidate.bridge; if (bridge.runId !== identity.runId || bridge.nativeSessionId !== identity.nativeSessionId || bridge.packageVersion !== packageJson.version || bridge.protocol !== HERDR_PI_PROTOCOL)
|
|
@@ -35,16 +36,18 @@ export async function boundedHerdrReconnect(identity, lastEvidenceCursor, attemp
|
|
|
35
36
|
}
|
|
36
37
|
function safeRunId(value) { const prefix = value?.replace(/[^A-Za-z0-9_-]/gu, "_").slice(0, 48) ?? "run"; return validateHerdrPiRunId(`${prefix}_${randomBytes(8).toString("hex")}`); }
|
|
37
38
|
export function serializeHerdrPiLaunch(launch) {
|
|
38
|
-
|
|
39
|
-
|
|
39
|
+
// Every child is handed a local session file path; only one that already exists (a fork or a
|
|
40
|
+
// resumed transcript) asks the pane to restore history. A fresh child's path is never written.
|
|
41
|
+
if (launch.storage.kind === "file" && fs.existsSync(launch.storage.sessionFile))
|
|
42
|
+
throw new Error(PLACED_RESTORE_UNSUPPORTED);
|
|
40
43
|
if (launch.extensionPaths.length || launch.requiredExtensions?.length)
|
|
41
44
|
throw new Error("Pane-native remote Pi cannot transfer local extension paths; install/configure pi-subagents on the remote machine.");
|
|
42
45
|
if (launch.processEnv && Object.values(launch.processEnv).some((value) => value !== undefined && value !== "__none__"))
|
|
43
46
|
throw new Error("Pane-native remote Pi cannot transfer local bindings, MCP selections, or process environment.");
|
|
44
47
|
if (launch.runtime.nestedRoute || launch.runtime.fanoutChild || launch.runtime.depth > 1)
|
|
45
48
|
throw new Error("Nested delegation from a pane-native remote Pi is not supported.");
|
|
46
|
-
if (launch.excludeTools?.length || launch.runtime.permissions || launch.runtime.toolBudget || launch.runtime.requiredExtensions || launch.runtime.
|
|
47
|
-
throw new Error("Pane-native remote Pi cannot yet represent exclusions, permission rules, tool budgets, MCP direct tools, or required-
|
|
49
|
+
if (launch.excludeTools?.length || launch.runtime.permissions || launch.runtime.toolBudget || launch.runtime.requiredExtensions || launch.runtime.mcpDirectTools?.length)
|
|
50
|
+
throw new Error("Pane-native remote Pi cannot yet represent exclusions, permission rules, tool budgets, MCP direct tools, or required-extension contracts; remove machine placement.");
|
|
48
51
|
const resources = launch.remoteResources;
|
|
49
52
|
if (!resources || !/^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$/u.test(resources.agent) || resources.skills?.some((name) => !/^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$/u.test(name)) || resources.toolCeiling?.some((name) => !/^[A-Za-z0-9_-]{1,64}$/u.test(name)) || (resources.reads !== undefined && resources.reads !== false && resources.reads.some((read) => typeof read !== "string" || Buffer.byteLength(read) > 4096)))
|
|
50
53
|
throw new Error("Pane-native remote resources require bounded logical agent, skill, tool, and read names.");
|
|
@@ -350,6 +353,10 @@ async function startPlacedPiSession(launch, owner, policy) {
|
|
|
350
353
|
throw new Error("Remote Pi resource resolution identity mismatch.");
|
|
351
354
|
if (!Array.isArray(configured.tools) || (policy.resources.toolCeiling && configured.tools.some((tool) => !policy.resources.toolCeiling.includes(String(tool)))))
|
|
352
355
|
throw new Error("Remote Pi active-tool ceiling acknowledgement mismatch.");
|
|
356
|
+
// The remote Pi never receives the runtime contract, so required tools are checked here, against what it activated.
|
|
357
|
+
const missingRequired = (launch.runtime.requiredTools ?? []).filter((tool) => !configured.tools.includes(tool));
|
|
358
|
+
if (missingRequired.length)
|
|
359
|
+
throw new Error(`Remote Pi agent '${policy.resources.agent}' did not activate required tools: ${missingRequired.join(", ")}.`);
|
|
353
360
|
if (launch.model && configured.model !== launch.model.split(":")[0])
|
|
354
361
|
throw new Error(`Remote Pi model '${launch.model}' did not resolve to the requested provider/model.`);
|
|
355
362
|
const identity = { runId, machineId: machine.id, target: isRexLocalMachine(machine) ? machine.id : machine.target, session: owner.host.sessionOf(connection), workspaceId: owned.workspaceId, tabId: owned.tabId, paneId: owned.paneId, terminalId, agentName, nativeSessionId: manifest.nativeSessionId, cwd: machine.cwd, runtimeDir };
|
|
@@ -23,7 +23,7 @@ export declare function resolveParallelHandoffChild(input: {
|
|
|
23
23
|
child: ParallelHandoffGroup["children"][number];
|
|
24
24
|
} | undefined;
|
|
25
25
|
export declare function protectRetainedWorktreeForResume(manifestPath: string, runId: string, childIndex: number, signal?: AbortSignal): Promise<string>;
|
|
26
|
-
export declare function resolveRetainedWorktreeCwd(manifestPath: string, runId: string, childIndex: number): string | undefined;
|
|
26
|
+
export declare function resolveRetainedWorktreeCwd(manifestPath: string, runId: string, childIndex: number, recordedWorktreePath?: string): string | undefined;
|
|
27
27
|
export declare function isTerminalParallelHandoffChildStatus(status: unknown): boolean;
|
|
28
28
|
export declare function formatStoredParallelHandoffCleanup(manifestPath: string, manifest?: ParallelHandoffManifest): string;
|
|
29
29
|
export interface ParallelHandoffEvidenceResult {
|
|
@@ -165,17 +165,18 @@ export async function protectRetainedWorktreeForResume(manifestPath, runId, chil
|
|
|
165
165
|
return cwd;
|
|
166
166
|
}), { signal }));
|
|
167
167
|
}
|
|
168
|
-
export function resolveRetainedWorktreeCwd(manifestPath, runId, childIndex) {
|
|
168
|
+
export function resolveRetainedWorktreeCwd(manifestPath, runId, childIndex, recordedWorktreePath) {
|
|
169
169
|
const manifest = readParallelHandoffManifest(manifestPath);
|
|
170
|
-
if (
|
|
171
|
-
return undefined;
|
|
172
|
-
if (manifest.runId !== runId)
|
|
170
|
+
if (manifest && manifest.runId !== runId)
|
|
173
171
|
throw new Error(`Managed worktree handoff belongs to run '${manifest.runId}', not '${runId}'.`);
|
|
174
|
-
const match = manifest
|
|
172
|
+
const match = manifest?.groups
|
|
175
173
|
.flatMap((group) => group.children.map((child) => ({ group, child })))
|
|
176
174
|
.find(({ child }) => child.index === childIndex);
|
|
177
|
-
if (!match)
|
|
175
|
+
if (!manifest || !match) {
|
|
176
|
+
if (recordedWorktreePath)
|
|
177
|
+
throw new Error(`Async run '${runId}' child ${childIndex} ran in managed worktree ${recordedWorktreePath}, but its handoff has no resumable record yet. Retry after the run settles; if it already ended, inspect ${manifestPath}.`);
|
|
178
178
|
return undefined;
|
|
179
|
+
}
|
|
179
180
|
const cleanup = match.group.cleanup.tasks.find((task) => task.index === match.child.taskIndex);
|
|
180
181
|
if (!cleanup)
|
|
181
182
|
throw new Error(`Async run '${runId}' child ${childIndex} has no managed worktree cleanup record.`);
|
|
@@ -185,6 +186,9 @@ export function resolveRetainedWorktreeCwd(manifestPath, runId, childIndex) {
|
|
|
185
186
|
const requiredCwd = path.join(cleanup.path, relativeCwd);
|
|
186
187
|
if (cleanup.worktreeRemoved || cleanup.branchRemoved)
|
|
187
188
|
throw new Error(`Async run '${runId}' required managed worktree was removed: ${requiredCwd}`);
|
|
189
|
+
// The runner removes the worktree right after this marker, without the locks that guard resume admission.
|
|
190
|
+
if (cleanup.reason?.includes("pending durable handoff capture"))
|
|
191
|
+
throw new Error(`Async run '${runId}' child ${childIndex} is still finalizing its managed worktree: ${requiredCwd}. Retry after the run settles; if it already ended, inspect ${manifestPath}.`);
|
|
188
192
|
let worktreeRoot = "";
|
|
189
193
|
let resolvedRequiredCwd = "";
|
|
190
194
|
try {
|
|
@@ -669,6 +669,7 @@ export default function registerSubagentPromptRuntime(pi, config, drainObservati
|
|
|
669
669
|
onRuntimeEvent("session_start", (_event, ctx) => {
|
|
670
670
|
const sessionManager = ctx?.sessionManager;
|
|
671
671
|
waitState.currentSessionId = sessionManager ? resolveCurrentSessionId(sessionManager) : null;
|
|
672
|
+
waitState.supervisorOwnerSessionId = sessionManager?.getSessionId() || null;
|
|
672
673
|
registerNativeSupervisorClientOnce();
|
|
673
674
|
});
|
|
674
675
|
onRuntimeEvent("agent_start", () => {
|
|
@@ -724,30 +725,23 @@ export default function registerSubagentPromptRuntime(pi, config, drainObservati
|
|
|
724
725
|
onRuntimeEvent("before_provider_headers", (event, ctx) => {
|
|
725
726
|
applyForkSessionAffinity(event?.headers, ctx?.model, config.parentSessionId, readInherited(ctx)?.model);
|
|
726
727
|
});
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
if (!fork)
|
|
733
|
-
return undefined;
|
|
734
|
-
const messages = projectForkRequest(event.messages, fork.system, fork.forkedAt, { boundary });
|
|
735
|
-
return messages === event.messages ? undefined : { messages };
|
|
736
|
-
});
|
|
737
|
-
onRuntimeEvent("context", (event, ctx) => {
|
|
728
|
+
// The strip runs on context_with_system, not context: Pi treats any change a context handler
|
|
729
|
+
// makes to the message list as a rewritten conversation and folds every mid-conversation system
|
|
730
|
+
// message into the leading one, so every later request would miss the prompt cache. The strip
|
|
731
|
+
// passes system messages through unchanged.
|
|
732
|
+
onRuntimeEvent("context_with_system", (event, ctx) => {
|
|
738
733
|
if (!event || typeof event !== "object" || !("messages" in event) || !Array.isArray(event.messages))
|
|
739
734
|
return undefined;
|
|
740
|
-
const
|
|
741
|
-
const
|
|
735
|
+
const fork = config.forkCacheKey ? readInherited(ctx) : undefined;
|
|
736
|
+
const stripped = stripParentOnlySubagentMessages(event.messages, {
|
|
742
737
|
sanitizeToolIds: !COMPOSITE_TOOL_ID_APIS.has(ctx?.model?.api ?? ""),
|
|
743
738
|
// Providers that reuse the Codex Responses wire under their own api id (e.g. cliproxyapi-codex-responses) split call_id|item_id the same way.
|
|
744
739
|
preserveBoundedCompositeToolIds: ctx?.model?.api?.endsWith("-codex-responses") === true,
|
|
745
740
|
preserveFanoutToolHistory: config.fanoutChild,
|
|
746
|
-
...(
|
|
741
|
+
...(fork ? { inheritedBefore: fork.forkedAt } : {}),
|
|
747
742
|
});
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
return { messages };
|
|
743
|
+
const messages = fork ? projectForkRequest(stripped, fork.system, fork.forkedAt, { boundary }) : stripped;
|
|
744
|
+
return messages === event.messages ? undefined : { messages };
|
|
751
745
|
});
|
|
752
746
|
// pi-intercom asks at session start for this session's intercom ID. Claiming
|
|
753
747
|
// the route there frees the session name for the readable label. An older
|
|
@@ -86,6 +86,8 @@ interface FeatureConfig {
|
|
|
86
86
|
export declare function resolveDisabledFeatureSurface(config: FeatureConfig): DisabledFeatureSurface;
|
|
87
87
|
/** Returns why a request uses a disabled feature, or undefined when every requested field is enabled. */
|
|
88
88
|
export declare function disabledFeatureUseError(request: object, surface: DisabledFeatureSurface, label?: string): string | undefined;
|
|
89
|
-
/** Lists what config disabled, for prepending to static
|
|
89
|
+
/** Lists what config disabled, for prepending to static guide docs that describe the full tool. */
|
|
90
90
|
export declare function disabledFeatureNotice(surface: DisabledFeatureSurface): string | undefined;
|
|
91
|
+
/** One-line form for guide sections, which are capped at 8,000 chars. */
|
|
92
|
+
export declare function disabledFeatureSectionNotice(surface: DisabledFeatureSurface): string | undefined;
|
|
91
93
|
export {};
|
|
@@ -99,14 +99,22 @@ export function disabledFeatureUseError(request, surface, label = "subagent") {
|
|
|
99
99
|
}
|
|
100
100
|
return undefined;
|
|
101
101
|
}
|
|
102
|
-
|
|
102
|
+
const WORKFLOW_SCRIPTS_REPLACEMENT = "Instead of workflow scripts, use the top-level tasks or chain fields.";
|
|
103
|
+
/** Lists what config disabled, for prepending to static guide docs that describe the full tool. */
|
|
103
104
|
export function disabledFeatureNotice(surface) {
|
|
104
105
|
if (surface.features.size === 0)
|
|
105
106
|
return undefined;
|
|
106
107
|
const lines = [...surface.features].map((feature) => {
|
|
107
108
|
const { actions, params, disabledBy } = featureSurface(feature);
|
|
108
109
|
const parts = [`options ${params.join(", ")}`, ...(actions.length > 0 ? [`actions ${actions.join(", ")}`] : [])];
|
|
109
|
-
return `- ${disabledBy}: ${parts.join("; ")}`;
|
|
110
|
+
return `- ${disabledBy}: ${parts.join("; ")}${feature === "workflow-scripts" ? `. ${WORKFLOW_SCRIPTS_REPLACEMENT}` : ""}`;
|
|
110
111
|
});
|
|
111
|
-
return `Disabled by config in this session. The
|
|
112
|
+
return `Disabled by config in this session. The guide below may still describe these, but calls that use them are rejected:\n${lines.join("\n")}`;
|
|
113
|
+
}
|
|
114
|
+
/** One-line form for guide sections, which are capped at 8,000 chars. */
|
|
115
|
+
export function disabledFeatureSectionNotice(surface) {
|
|
116
|
+
if (surface.features.size === 0)
|
|
117
|
+
return undefined;
|
|
118
|
+
const replacement = surface.features.has("workflow-scripts") ? ` ${WORKFLOW_SCRIPTS_REPLACEMENT}` : "";
|
|
119
|
+
return `Some options and actions are disabled by config in this session; guide topic tool-reference lists them.${replacement}`;
|
|
112
120
|
}
|
package/src/shared/types.d.ts
CHANGED
|
@@ -1936,7 +1936,7 @@ export interface AsyncStatus {
|
|
|
1936
1936
|
label?: string;
|
|
1937
1937
|
workflowKey?: string;
|
|
1938
1938
|
lane?: WorkflowLaneMetadata;
|
|
1939
|
-
/**
|
|
1939
|
+
/** Worktree path copied at setup; the handoff stays authoritative for the cwd. */
|
|
1940
1940
|
worktreePath?: string;
|
|
1941
1941
|
/** Display-only branch copied at launch; handoff remains authoritative. */
|
|
1942
1942
|
branch?: string;
|
|
@@ -2278,7 +2278,7 @@ export interface ActiveAsyncCapacitySnapshot {
|
|
|
2278
2278
|
export interface SubagentState {
|
|
2279
2279
|
baseCwd: string;
|
|
2280
2280
|
currentSessionId: string | null;
|
|
2281
|
-
/** Exact SDK runtime session ID for supervisor ownership; never a session file path. */
|
|
2281
|
+
/** Exact SDK runtime session ID (`getSessionId()`) for supervisor ownership and background-work matching; never a session file path. */
|
|
2282
2282
|
supervisorOwnerSessionId?: string | null;
|
|
2283
2283
|
/** Session for which active status projections were restored successfully. */
|
|
2284
2284
|
statusProjectionSessionId?: string | null;
|
|
@@ -2410,6 +2410,8 @@ export declare const SUBAGENT_CONTROL_EVENT = "subagent:control-event";
|
|
|
2410
2410
|
export declare const SUBAGENT_CONTROL_INTERCOM_EVENT = "subagent:control-intercom";
|
|
2411
2411
|
export declare const SUBAGENT_STEERING_NOTICE_EVENT = "subagent:steering-notice";
|
|
2412
2412
|
export declare const SUBAGENT_CHILD_STATUS_EVENT = "subagent:child-status";
|
|
2413
|
+
/** Payload is only `{ version: 1 }`: a hint for hosts to read `status` again, not a description of the change. */
|
|
2414
|
+
export declare const SUBAGENT_JOBS_CHANGED_EVENT = "subagent:jobs-changed";
|
|
2413
2415
|
export declare const SUBAGENT_RESULT_INTERCOM_EVENT = "subagent:result-intercom";
|
|
2414
2416
|
export declare const SUBAGENT_RESULT_INTERCOM_DELIVERY_EVENT = "subagent:result-intercom-delivery";
|
|
2415
2417
|
export interface SubagentChildStatusEvent {
|
package/src/shared/types.js
CHANGED
|
@@ -19,6 +19,8 @@ export const SUBAGENT_CONTROL_EVENT = "subagent:control-event";
|
|
|
19
19
|
export const SUBAGENT_CONTROL_INTERCOM_EVENT = "subagent:control-intercom";
|
|
20
20
|
export const SUBAGENT_STEERING_NOTICE_EVENT = "subagent:steering-notice";
|
|
21
21
|
export const SUBAGENT_CHILD_STATUS_EVENT = "subagent:child-status";
|
|
22
|
+
/** Payload is only `{ version: 1 }`: a hint for hosts to read `status` again, not a description of the change. */
|
|
23
|
+
export const SUBAGENT_JOBS_CHANGED_EVENT = "subagent:jobs-changed";
|
|
22
24
|
export const SUBAGENT_RESULT_INTERCOM_EVENT = "subagent:result-intercom";
|
|
23
25
|
export const SUBAGENT_RESULT_INTERCOM_DELIVERY_EVENT = "subagent:result-intercom-delivery";
|
|
24
26
|
export const FLEET_KEYBINDING_ACTIONS = [
|