pi-subagents 0.81.0 → 0.82.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 +38 -0
- package/bundle/agents.js +3 -3
- package/bundle/child-tool-plan.js +2 -2
- package/bundle/{chunk-LSRUTHT7.js → chunk-43SCHIMD.js} +1 -1
- package/bundle/{chunk-G5DKFLLI.js → chunk-4SDU2BZX.js} +15 -10
- package/bundle/{chunk-V2JWDB5U.js → chunk-52UBALJL.js} +2 -2
- package/bundle/{chunk-3DC5KBVP.js → chunk-5TYMSZX3.js} +1 -1
- package/bundle/{chunk-CEKS3TFO.js → chunk-7IVSUMQQ.js} +6 -6
- package/bundle/{chunk-KSWQVGDW.js → chunk-7PCKZHR5.js} +225 -18
- package/bundle/{chunk-563BHAZ5.js → chunk-7YMXOYEU.js} +33 -25
- package/bundle/{chunk-XMFLCKMQ.js → chunk-B5EKXDHE.js} +336 -130
- package/bundle/{chunk-ZBC44JJ3.js → chunk-CIZQXJ5Q.js} +22 -9
- package/bundle/{chunk-L5ZHE4L4.js → chunk-GC4DSPMH.js} +4 -4
- package/bundle/{chunk-ARRKBB2B.js → chunk-GJECHSAR.js} +2 -2
- package/bundle/{chunk-2ZSNH26H.js → chunk-M2CTFYT3.js} +7 -7
- package/bundle/{chunk-TUWLXTAM.js → chunk-MHZ4G23A.js} +681 -320
- package/bundle/{chunk-WSBNENFS.js → chunk-NGGAFDL6.js} +14 -4
- package/bundle/{chunk-VJHOELQP.js → chunk-NRQ75MGH.js} +160 -78
- package/bundle/{chunk-BJN5LUQY.js → chunk-OYF6AFDY.js} +1 -1
- package/bundle/{chunk-EYNJ6VL6.js → chunk-PLCCBLPY.js} +2 -2
- package/bundle/{chunk-74RT5YQE.js → chunk-RMQFMMAT.js} +123 -33
- package/bundle/{chunk-V6MR5TOQ.js → chunk-SIJ4S3EN.js} +25 -19
- package/bundle/{chunk-NNLASTQE.js → chunk-VH5OAWVG.js} +19 -5
- package/bundle/{chunk-BPS2AGBZ.js → chunk-W2SZ22EM.js} +93 -52
- package/bundle/{chunk-V3BIUPLU.js → chunk-WVD4UEL4.js} +256 -52
- package/bundle/{chunk-ZP3HODFH.js → chunk-XSWOTIA3.js} +1 -1
- package/bundle/{chunk-3IF2PGW7.js → chunk-YKEWIB4M.js} +1 -1
- package/bundle/{chunk-26C3WLYQ.js → chunk-ZLINIYTP.js} +497 -272
- package/bundle/{chunk-2XYWN7QJ.js → chunk-ZQGSDHL6.js} +2 -2
- package/bundle/control-channel.js +2 -2
- package/bundle/index.js +1 -1
- package/bundle/intercom-bridge.js +2 -2
- package/bundle/preflight.js +8 -8
- package/bundle/project-panes.js +3 -3
- package/docs/agents.md +31 -0
- package/docs/configuration.md +9 -1
- package/docs/tool-reference.md +3 -1
- package/docs/workflows.md +16 -0
- package/package.json +2 -2
- package/skills/pi-subagents/references/execution-controls.md +5 -4
- package/src/agents/agent-management.js +3 -3
- package/src/agents/agent-memory.js +3 -1
- package/src/agents/agents.js +6 -6
- package/src/agents/frontmatter.d.ts +2 -0
- package/src/agents/frontmatter.js +15 -1
- package/src/agents/skills.js +2 -1
- package/src/extension/config.js +3 -0
- package/src/extension/herdr-pi-bridge.js +17 -10
- package/src/extension/index.js +82 -2
- package/src/extension/schemas.js +3 -3
- package/src/intercom/native-supervisor-channel.js +20 -0
- package/src/missions/lifecycle.js +7 -1
- package/src/runs/background/active-async-capacity.d.ts +1 -0
- package/src/runs/background/active-async-capacity.js +9 -3
- package/src/runs/background/async-execution.js +20 -10
- package/src/runs/background/async-job-tracker.d.ts +6 -1
- package/src/runs/background/async-job-tracker.js +9 -4
- package/src/runs/background/async-status.d.ts +2 -0
- package/src/runs/background/async-status.js +21 -2
- package/src/runs/background/await-async-run.js +3 -7
- package/src/runs/background/boot-id.d.ts +12 -0
- package/src/runs/background/boot-id.js +47 -0
- package/src/runs/background/interrupted-elsewhere.d.ts +22 -0
- package/src/runs/background/interrupted-elsewhere.js +68 -0
- package/src/runs/background/notify.d.ts +2 -0
- package/src/runs/background/notify.js +13 -0
- package/src/runs/background/result-delivery-ownership.d.ts +6 -0
- package/src/runs/background/result-delivery-ownership.js +19 -1
- package/src/runs/background/result-watcher.d.ts +3 -1
- package/src/runs/background/result-watcher.js +24 -8
- package/src/runs/background/run-child-session.d.ts +1 -6
- package/src/runs/background/run-child-session.js +1 -1
- package/src/runs/background/run-status.js +2 -1
- package/src/runs/background/stale-run-reconciler.d.ts +25 -0
- package/src/runs/background/stale-run-reconciler.js +52 -13
- package/src/runs/background/subagent-runner-bootstrap.js +3 -0
- package/src/runs/background/subagent-runner.d.ts +4 -0
- package/src/runs/background/subagent-runner.js +13 -5
- package/src/runs/background/subagent-wait.d.ts +1 -1
- package/src/runs/background/subagent-wait.js +6 -1
- package/src/runs/background/terminal-run-index.d.ts +1 -0
- package/src/runs/background/terminal-run-index.js +4 -2
- package/src/runs/foreground/async-stop-action.js +3 -1
- package/src/runs/foreground/execution.js +6 -3
- package/src/runs/foreground/foreground-history.d.ts +16 -2
- package/src/runs/foreground/foreground-history.js +133 -31
- package/src/runs/foreground/subagent-executor.d.ts +11 -0
- package/src/runs/foreground/subagent-executor.js +277 -74
- package/src/runs/shared/child-launch.d.ts +2 -2
- package/src/runs/shared/child-session.d.ts +3 -2
- package/src/runs/shared/child-session.js +51 -8
- package/src/runs/shared/child-tool-plan.d.ts +7 -0
- package/src/runs/shared/child-tool-plan.js +21 -6
- package/src/runs/shared/herdr-connection.d.ts +17 -8
- package/src/runs/shared/herdr-connection.js +19 -7
- package/src/runs/shared/herdr-external-adapters.d.ts +3 -2
- package/src/runs/shared/herdr-external-adapters.js +1 -1
- package/src/runs/shared/herdr-machine.d.ts +12 -2
- package/src/runs/shared/herdr-machine.js +55 -9
- package/src/runs/shared/herdr-pane-host.d.ts +88 -0
- package/src/runs/shared/herdr-pane-host.js +155 -0
- package/src/runs/shared/herdr-placed-run.d.ts +27 -150
- package/src/runs/shared/herdr-placed-run.js +48 -395
- package/src/runs/shared/local-machine-access.d.ts +5 -0
- package/src/runs/shared/local-machine-access.js +28 -0
- package/src/runs/shared/orca-progress-tabs.d.ts +0 -1
- package/src/runs/shared/orca-progress-tabs.js +1 -24
- package/src/runs/shared/parallel-utils.d.ts +1 -1
- package/src/runs/shared/placed-run-owner.d.ts +49 -0
- package/src/runs/shared/placed-run-owner.js +93 -0
- package/src/runs/shared/placement-host.d.ts +99 -0
- package/src/runs/shared/placement-host.js +157 -0
- package/src/runs/shared/rex-machine.d.ts +25 -0
- package/src/runs/shared/rex-machine.js +83 -0
- package/src/runs/shared/rex-pane-host.d.ts +62 -0
- package/src/runs/shared/rex-pane-host.js +327 -0
- package/src/shared/completion-owner.d.ts +5 -0
- package/src/shared/completion-owner.js +5 -0
- package/src/shared/session-identity.d.ts +2 -0
- package/src/shared/session-identity.js +26 -0
- package/src/shared/types.d.ts +45 -6
- package/src/tui/fleet.d.ts +1 -0
- package/src/tui/fleet.js +24 -15
- package/src/tui/render.d.ts +6 -0
- package/src/tui/render.js +3 -3
- package/src/tui/subagent-messages.js +1 -0
- package/src/workflows/scripted-workflow.d.ts +1 -1
- package/src/workflows/workflow-auto-resume.d.ts +32 -0
- package/src/workflows/workflow-auto-resume.js +102 -0
- package/src/workflows/workflow-launch-record.d.ts +27 -0
- package/src/workflows/workflow-launch-record.js +48 -0
- package/src/workflows/workflow-resume-claim.d.ts +82 -0
- package/src/workflows/workflow-resume-claim.js +210 -0
- package/src/workflows/workflow-resume.d.ts +56 -0
- package/src/workflows/workflow-resume.js +106 -0
- package/src/workflows/workflow-reuse.d.ts +15 -9
- package/src/workflows/workflow-reuse.js +77 -14
- package/src/workflows/workflow-revival.d.ts +2 -0
- package/src/workflows/workflow-revival.js +2 -1
- package/src/workflows/workflow-stop-cause.d.ts +6 -0
- package/src/workflows/workflow-stop-cause.js +8 -0
|
@@ -10,10 +10,10 @@ import {
|
|
|
10
10
|
setInlineWorkflowCoverage,
|
|
11
11
|
setMainThinkingLevelSource,
|
|
12
12
|
widgetRenderKey
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-M2CTFYT3.js";
|
|
14
14
|
import {
|
|
15
15
|
package_default
|
|
16
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-ZQGSDHL6.js";
|
|
17
17
|
import {
|
|
18
18
|
EXTERNAL_JOB_BRIDGE_REQUEST_DIR,
|
|
19
19
|
REVIVAL_ORIGIN_FILE,
|
|
@@ -36,25 +36,32 @@ import {
|
|
|
36
36
|
formatControlNoticeMessage,
|
|
37
37
|
getInspectorPlugins,
|
|
38
38
|
hasLiveSubagentWork,
|
|
39
|
+
hasWorkflowResumeRefusal,
|
|
39
40
|
listRetainedChildren,
|
|
40
41
|
listScheduledRunSummaries,
|
|
41
42
|
markSeenWithTtl,
|
|
42
43
|
normalizePublicSubagentExecution,
|
|
43
44
|
parseSubagentNotifyContent,
|
|
45
|
+
prepareWorkflowResume,
|
|
44
46
|
preservedAgentFrontmatterFields,
|
|
45
47
|
readWorkflowReceipt,
|
|
48
|
+
recordWorkflowResumeRefusal,
|
|
49
|
+
refusalSentence,
|
|
46
50
|
registerHerdrStatusBridge,
|
|
47
51
|
registerInspectorEventListener,
|
|
48
52
|
registerMainWatchdog,
|
|
49
53
|
registerPiWebSessionLiveness,
|
|
50
54
|
registerSubagentNotify,
|
|
55
|
+
releaseWorkflowResumeClaim,
|
|
51
56
|
resolveSubagentResultStatus,
|
|
52
|
-
|
|
57
|
+
resumedRunStarted,
|
|
53
58
|
runtimeReplacedAbortReason,
|
|
54
59
|
sameProviderDiagnostics,
|
|
55
60
|
serviceExternalJobBridgeRequests,
|
|
56
|
-
snapshotProviderDiagnostics
|
|
57
|
-
|
|
61
|
+
snapshotProviderDiagnostics,
|
|
62
|
+
workflowResumeClaimState,
|
|
63
|
+
workflowResumeRefusal
|
|
64
|
+
} from "./chunk-ZLINIYTP.js";
|
|
58
65
|
import {
|
|
59
66
|
CONTACT_SUPERVISOR_TOOL_NAME,
|
|
60
67
|
NATIVE_SUPERVISOR_TOOL_NAME,
|
|
@@ -78,16 +85,18 @@ import {
|
|
|
78
85
|
registerPinnedTool,
|
|
79
86
|
registerWaitTool,
|
|
80
87
|
resolveCurrentSessionId,
|
|
88
|
+
resolvePiSessionId,
|
|
81
89
|
resolveWaitToolConfig,
|
|
82
90
|
setDeclarationPinning,
|
|
83
91
|
topLevelSupervisorTool
|
|
84
|
-
} from "./chunk-
|
|
92
|
+
} from "./chunk-W2SZ22EM.js";
|
|
85
93
|
import {
|
|
86
|
-
currentCompletionOwnerId,
|
|
87
94
|
deliverAsyncRunStop,
|
|
95
|
+
ownerConfirmedDead,
|
|
88
96
|
readSessionMessagesTail,
|
|
89
|
-
resolveSubagentRunId
|
|
90
|
-
|
|
97
|
+
resolveSubagentRunId,
|
|
98
|
+
restoreForegroundRunHistory
|
|
99
|
+
} from "./chunk-7PCKZHR5.js";
|
|
91
100
|
import {
|
|
92
101
|
ASYNC_STATUS_SNAPSHOT_KIND,
|
|
93
102
|
ASYNC_STATUS_SNAPSHOT_VERSION,
|
|
@@ -109,7 +118,7 @@ import {
|
|
|
109
118
|
resolveAsyncStatusChild,
|
|
110
119
|
stopStoppableAsyncStatusChildren,
|
|
111
120
|
withCachedUiContext
|
|
112
|
-
} from "./chunk-
|
|
121
|
+
} from "./chunk-VH5OAWVG.js";
|
|
113
122
|
import "./chunk-NF7IEKBH.js";
|
|
114
123
|
import {
|
|
115
124
|
disabledFeatureUseError,
|
|
@@ -120,15 +129,21 @@ import {
|
|
|
120
129
|
resolveDisabledFeatureSurface,
|
|
121
130
|
resolveMaxActiveAsyncRunsPerSession,
|
|
122
131
|
resolveScheduledStoreRoot
|
|
123
|
-
} from "./chunk-
|
|
132
|
+
} from "./chunk-NGGAFDL6.js";
|
|
124
133
|
import {
|
|
125
134
|
ACTIVE_RUN_INDEX_DIR,
|
|
126
135
|
MissionNotFoundError,
|
|
136
|
+
OWNING_SESSION_COMPLETION_OWNER,
|
|
137
|
+
WORKFLOW_STOP_CAUSE_OWNER_EXITED,
|
|
127
138
|
acknowledgeMissionObserverSnapshot,
|
|
139
|
+
checkRecordedPidLiveness,
|
|
128
140
|
cleanupResultIndexes,
|
|
141
|
+
currentCompletionOwnerId,
|
|
129
142
|
encodeIndexSegment,
|
|
130
143
|
findNestedRouteForRootId,
|
|
131
144
|
hasLiveNestedDescendants,
|
|
145
|
+
isRecordedPid,
|
|
146
|
+
isReusableWorkflowStopCause,
|
|
132
147
|
listMissions,
|
|
133
148
|
missionObserverIndexPath,
|
|
134
149
|
missionObserverResultCandidateFiles,
|
|
@@ -141,6 +156,7 @@ import {
|
|
|
141
156
|
readMission,
|
|
142
157
|
readMissionBinding,
|
|
143
158
|
readProcessTerminal,
|
|
159
|
+
readRecentTerminalRunIndex,
|
|
144
160
|
readResultPayload,
|
|
145
161
|
reconcileAsyncRun,
|
|
146
162
|
reconcileNestedAsyncDescendants,
|
|
@@ -162,28 +178,28 @@ import {
|
|
|
162
178
|
withWorkflowChildRunModel,
|
|
163
179
|
writeAsyncResultFile,
|
|
164
180
|
writeResultIndexForData
|
|
165
|
-
} from "./chunk-
|
|
166
|
-
import "./chunk-
|
|
181
|
+
} from "./chunk-NRQ75MGH.js";
|
|
182
|
+
import "./chunk-OYF6AFDY.js";
|
|
167
183
|
import {
|
|
168
184
|
shouldUseNativeFsWatch
|
|
169
185
|
} from "./chunk-NIXWDZZV.js";
|
|
170
186
|
import {
|
|
171
187
|
validateIntercomBridgeConfig
|
|
172
|
-
} from "./chunk-
|
|
188
|
+
} from "./chunk-XSWOTIA3.js";
|
|
173
189
|
import "./chunk-7F6RKT6W.js";
|
|
174
|
-
import "./chunk-
|
|
190
|
+
import "./chunk-4SDU2BZX.js";
|
|
175
191
|
import "./chunk-CTPAE36Y.js";
|
|
176
192
|
import {
|
|
177
193
|
listHerdrProjectPaneRoots,
|
|
178
194
|
restoreHerdrProjectPaneSnapshots
|
|
179
|
-
} from "./chunk-
|
|
195
|
+
} from "./chunk-52UBALJL.js";
|
|
180
196
|
import "./chunk-7J4ZXMY7.js";
|
|
181
197
|
import {
|
|
182
198
|
cleanupAllArtifactDirs,
|
|
183
199
|
cleanupOldArtifacts,
|
|
184
200
|
getArtifactPaths,
|
|
185
201
|
getArtifactsDir
|
|
186
|
-
} from "./chunk-
|
|
202
|
+
} from "./chunk-5TYMSZX3.js";
|
|
187
203
|
import {
|
|
188
204
|
listBackgroundWorkProviders
|
|
189
205
|
} from "./chunk-N2BN7BF5.js";
|
|
@@ -191,12 +207,12 @@ import "./chunk-YYREO77V.js";
|
|
|
191
207
|
import "./chunk-UKG4V45O.js";
|
|
192
208
|
import {
|
|
193
209
|
registerRuntimeAgentEventListener
|
|
194
|
-
} from "./chunk-
|
|
210
|
+
} from "./chunk-43SCHIMD.js";
|
|
195
211
|
import {
|
|
196
212
|
clearRuntimeAgentsForPi,
|
|
197
213
|
listRuntimeAgentConfigs,
|
|
198
214
|
mergeRuntimeAgents
|
|
199
|
-
} from "./chunk-
|
|
215
|
+
} from "./chunk-YKEWIB4M.js";
|
|
200
216
|
import {
|
|
201
217
|
DEFAULT_FILE_SYSTEM_RETRY_DELAYS_MS,
|
|
202
218
|
EXTRA_AGENT_DIRS_ENV,
|
|
@@ -236,7 +252,7 @@ import {
|
|
|
236
252
|
waitForFileSystemRetry,
|
|
237
253
|
withSettingsFileLease,
|
|
238
254
|
writeAtomicJson
|
|
239
|
-
} from "./chunk-
|
|
255
|
+
} from "./chunk-CIZQXJ5Q.js";
|
|
240
256
|
import {
|
|
241
257
|
DEFAULT_ARTIFACT_CONFIG,
|
|
242
258
|
DIRS,
|
|
@@ -282,7 +298,7 @@ import {
|
|
|
282
298
|
import { randomUUID as randomUUID3 } from "node:crypto";
|
|
283
299
|
import * as fs16 from "node:fs";
|
|
284
300
|
import * as os3 from "node:os";
|
|
285
|
-
import * as
|
|
301
|
+
import * as path16 from "node:path";
|
|
286
302
|
import { Box as Box2, Container as Container3, Spacer as Spacer3, Text as Text2 } from "@earendil-works/pi-tui";
|
|
287
303
|
|
|
288
304
|
// src/agents/global-npm-root.ts
|
|
@@ -884,7 +900,7 @@ function createAsyncJobTracker(pi, state, asyncDirRoot, options = {}) {
|
|
|
884
900
|
job.sessionFile = status.sessionFile ?? job.sessionFile;
|
|
885
901
|
if (isTerminalJobStatus(job.status)) {
|
|
886
902
|
let publication = terminalPublications.get(job.asyncId);
|
|
887
|
-
if (!publication && status.mode !== "workflow" && status.processTerminal?.state === "pending" && status.runId === job.asyncId && status.sessionId === state.currentSessionId && status.completionOwnerId && status.completionOwnerId
|
|
903
|
+
if (!publication && status.mode !== "workflow" && status.processTerminal?.state === "pending" && status.runId === job.asyncId && status.completionOwnerId && (status.sessionId === state.currentSessionId && status.completionOwnerId === state.completionOwnerId || typeof status.sessionId === "string" && options.deliveryOwnerId?.(status.sessionId, status.completionOwnerId, status.completionOwnerProcess, status.parentWorkflowRunId) === OWNING_SESSION_COMPLETION_OWNER)) {
|
|
888
904
|
publication = { instanceId: status.processTerminal.runnerProcessInstanceId, pending: true };
|
|
889
905
|
terminalPublications.set(job.asyncId, publication);
|
|
890
906
|
}
|
|
@@ -1160,13 +1176,13 @@ function createAsyncJobTracker(pi, state, asyncDirRoot, options = {}) {
|
|
|
1160
1176
|
rerenderWidget(ctx, []);
|
|
1161
1177
|
}
|
|
1162
1178
|
};
|
|
1163
|
-
const restoreActiveJobs = (ctx) => {
|
|
1179
|
+
const restoreActiveJobs = (ctx, observeStatus) => {
|
|
1164
1180
|
if (ctx?.hasUI) state.lastUiContext = ctx;
|
|
1165
1181
|
state.statusProjectionSessionId = null;
|
|
1166
1182
|
if (!state.currentSessionId) return;
|
|
1167
1183
|
let runs;
|
|
1168
1184
|
try {
|
|
1169
|
-
runs = listAsyncRuns(asyncDirRoot, { states: ["queued", "running"], sessionId: state.currentSessionId, resultsDir, kill: options.kill, now: options.now });
|
|
1185
|
+
runs = listAsyncRuns(asyncDirRoot, { states: ["queued", "running"], sessionId: state.currentSessionId, resultsDir, kill: options.kill, now: options.now, adoptCompletionOwnerId: state.completionOwnerId }, observeStatus);
|
|
1170
1186
|
} catch (error) {
|
|
1171
1187
|
console.error(`Failed to restore active async jobs from '${asyncDirRoot}':`, error);
|
|
1172
1188
|
return;
|
|
@@ -1975,22 +1991,27 @@ var HEALTHY_SCAN_INTERVAL_MS = 6e4;
|
|
|
1975
1991
|
var RETRY_DELAY_MS = 100;
|
|
1976
1992
|
var CLEANUP_LEASE_WAIT_MS = 0;
|
|
1977
1993
|
var SLOW_RESULT_SCAN_MS = 500;
|
|
1978
|
-
function
|
|
1979
|
-
const matches = raw.matchAll(new RegExp(`"${property}"\\s*:\\s*("(?:\\\\.|[^"\\\\])*")`, "g"));
|
|
1994
|
+
function jsonPropertyValue(raw, property, valuePattern) {
|
|
1980
1995
|
let encoded;
|
|
1981
|
-
for (const match of
|
|
1996
|
+
for (const match of raw.matchAll(new RegExp(`"${property}"\\s*:\\s*(${valuePattern})`, "g"))) encoded = match[1];
|
|
1982
1997
|
if (!encoded) return void 0;
|
|
1983
1998
|
try {
|
|
1984
|
-
|
|
1985
|
-
return typeof value === "string" && value ? value : void 0;
|
|
1999
|
+
return JSON.parse(encoded);
|
|
1986
2000
|
} catch {
|
|
1987
2001
|
return void 0;
|
|
1988
2002
|
}
|
|
1989
2003
|
}
|
|
2004
|
+
function jsonStringProperty(raw, property) {
|
|
2005
|
+
const value = jsonPropertyValue(raw, property, `"(?:\\\\.|[^"\\\\])*"`);
|
|
2006
|
+
return typeof value === "string" && value ? value : void 0;
|
|
2007
|
+
}
|
|
1990
2008
|
function resultFileIdentity(raw, file) {
|
|
1991
2009
|
return {
|
|
1992
2010
|
sessionId: jsonStringProperty(raw, "sessionId"),
|
|
1993
2011
|
completionOwnerId: jsonStringProperty(raw, "completionOwnerId"),
|
|
2012
|
+
// Recorded as a flat object, so a brace-free match is the whole value.
|
|
2013
|
+
completionOwnerProcess: jsonPropertyValue(raw, "completionOwnerProcess", `\\{[^{}]*\\}`),
|
|
2014
|
+
parentWorkflowRunId: jsonStringProperty(raw, "parentWorkflowRunId"),
|
|
1994
2015
|
runId: file.replace(/\.json$/i, "")
|
|
1995
2016
|
};
|
|
1996
2017
|
}
|
|
@@ -2047,12 +2068,14 @@ function createResultWatcher(pi, state, resultsDir, completionTtlMs, deps = {})
|
|
|
2047
2068
|
const handling = /* @__PURE__ */ new Set();
|
|
2048
2069
|
let deliveringPending = 0;
|
|
2049
2070
|
const identityCache = /* @__PURE__ */ new Map();
|
|
2071
|
+
const reportedMissionSyncFailures = /* @__PURE__ */ new Map();
|
|
2050
2072
|
let deliveryActive = true;
|
|
2051
2073
|
let deliveryEpoch = 0;
|
|
2052
2074
|
let resultScanTimer = null;
|
|
2053
2075
|
let activeSessionId = null;
|
|
2054
2076
|
const ownsResult = deps.ownership?.owns ?? ((sessionId, completionOwnerId) => sessionId === state.currentSessionId && typeof completionOwnerId === "string" && completionOwnerId === state.completionOwnerId);
|
|
2055
2077
|
const claimedSessionIds = () => deps.ownership?.claimedSessionIds() ?? [];
|
|
2078
|
+
const deliveryOwnerId = deps.ownership?.deliveryOwnerId ?? ((_sessionId, completionOwnerId) => completionOwnerId);
|
|
2056
2079
|
const ownsCompletion = (sessionId, completionOwnerId, epoch) => {
|
|
2057
2080
|
if (!deliveryActive || epoch !== deliveryEpoch) return false;
|
|
2058
2081
|
if (!activeSessionId && state.currentSessionId) activeSessionId = state.currentSessionId;
|
|
@@ -2136,7 +2159,7 @@ function createResultWatcher(pi, state, resultsDir, completionTtlMs, deps = {})
|
|
|
2136
2159
|
if (!inspected) return false;
|
|
2137
2160
|
const { identity } = inspected;
|
|
2138
2161
|
if (!identity.sessionId) return true;
|
|
2139
|
-
if (ownsResult(identity.sessionId, identity.completionOwnerId)) return true;
|
|
2162
|
+
if (ownsResult(identity.sessionId, deliveryOwnerId(identity.sessionId, identity.completionOwnerId, identity.completionOwnerProcess, identity.parentWorkflowRunId))) return true;
|
|
2140
2163
|
if (identity.runId && fsApi.existsSync(missionObserverIndexPath(resultsDir, identity.runId))) return true;
|
|
2141
2164
|
if (identity.runId && (observed ?? observedRunIds()).has(identity.runId)) return true;
|
|
2142
2165
|
return Boolean(deps.observeCompletion && !deps.observedCompletionRunIds);
|
|
@@ -2201,7 +2224,7 @@ function createResultWatcher(pi, state, resultsDir, completionTtlMs, deps = {})
|
|
|
2201
2224
|
let data = parseResult(raw);
|
|
2202
2225
|
if (typeof data.sessionId !== "string" || !data.sessionId) return;
|
|
2203
2226
|
const sessionId = data.sessionId;
|
|
2204
|
-
const completionOwnerId = data.completionOwnerId;
|
|
2227
|
+
const completionOwnerId = deliveryOwnerId(sessionId, data.completionOwnerId, data.completionOwnerProcess, data.parentWorkflowRunId);
|
|
2205
2228
|
const runId = typeof data.runId === "string" && data.runId ? data.runId : typeof data.id === "string" && data.id ? data.id : file.replace(/\.json$/i, "");
|
|
2206
2229
|
const toolCallId = typeof data.toolCallId === "string" ? data.toolCallId : void 0;
|
|
2207
2230
|
let read = { runId, sessionId, toolCallId, snapshot: raw, ...publicAtRead !== void 0 && publicAtRead !== raw ? { stalePublic: publicAtRead } : {} };
|
|
@@ -2219,9 +2242,14 @@ function createResultWatcher(pi, state, resultsDir, completionTtlMs, deps = {})
|
|
|
2219
2242
|
let observerSucceeded = true;
|
|
2220
2243
|
try {
|
|
2221
2244
|
syncMissionFromAsyncCompletion({ ...data, runId });
|
|
2245
|
+
reportedMissionSyncFailures.delete(file);
|
|
2222
2246
|
} catch (error) {
|
|
2223
2247
|
observerSucceeded = false;
|
|
2224
|
-
|
|
2248
|
+
const message2 = error instanceof Error ? error.message : String(error);
|
|
2249
|
+
if (reportedMissionSyncFailures.get(file) !== message2) {
|
|
2250
|
+
reportedMissionSyncFailures.set(file, message2);
|
|
2251
|
+
console.error(`Mission completion sync failed for '${resultPath}':`, error);
|
|
2252
|
+
}
|
|
2225
2253
|
}
|
|
2226
2254
|
try {
|
|
2227
2255
|
deps.observeCompletion?.({ ...data, runId });
|
|
@@ -2348,6 +2376,7 @@ ${baseOutput}` : ""}` : output;
|
|
|
2348
2376
|
...data,
|
|
2349
2377
|
id: data.id ?? runId,
|
|
2350
2378
|
runId,
|
|
2379
|
+
completionOwnerId,
|
|
2351
2380
|
triggerTurn,
|
|
2352
2381
|
intercomDelivered,
|
|
2353
2382
|
...nestedChildren?.length ? { nestedChildren } : {},
|
|
@@ -2622,14 +2651,24 @@ ${baseOutput}` : ""}` : output;
|
|
|
2622
2651
|
}
|
|
2623
2652
|
|
|
2624
2653
|
// src/runs/background/result-delivery-ownership.ts
|
|
2654
|
+
var deadCompletionOwnerIds = /* @__PURE__ */ new Set();
|
|
2625
2655
|
function createResultDeliveryOwnership(state) {
|
|
2626
2656
|
const currentOwner = () => typeof state.completionOwnerId === "string" && state.completionOwnerId ? state.completionOwnerId : void 0;
|
|
2627
2657
|
return {
|
|
2628
2658
|
owns(sessionId, completionOwnerId) {
|
|
2629
2659
|
const owner = currentOwner();
|
|
2630
|
-
if (!owner || completionOwnerId !== owner) return false;
|
|
2660
|
+
if (!owner || completionOwnerId !== owner && completionOwnerId !== OWNING_SESSION_COMPLETION_OWNER) return false;
|
|
2631
2661
|
return ownsRun(state.currentSessionId, sessionId);
|
|
2632
2662
|
},
|
|
2663
|
+
deliveryOwnerId(sessionId, completionOwnerId, ownerProcess, parentWorkflowRunId) {
|
|
2664
|
+
const owner = currentOwner();
|
|
2665
|
+
if (!owner || typeof completionOwnerId !== "string" || completionOwnerId === owner || completionOwnerId === OWNING_SESSION_COMPLETION_OWNER || parentWorkflowRunId || !ownsRun(state.currentSessionId, sessionId)) return completionOwnerId;
|
|
2666
|
+
if (!deadCompletionOwnerIds.has(completionOwnerId)) {
|
|
2667
|
+
if (!isRecordedPid(ownerProcess) || checkRecordedPidLiveness(ownerProcess) !== "dead") return completionOwnerId;
|
|
2668
|
+
deadCompletionOwnerIds.add(completionOwnerId);
|
|
2669
|
+
}
|
|
2670
|
+
return OWNING_SESSION_COMPLETION_OWNER;
|
|
2671
|
+
},
|
|
2633
2672
|
claimedSessionIds() {
|
|
2634
2673
|
if (!currentOwner() || !state.currentSessionId) return [];
|
|
2635
2674
|
return inheritedSessionIds(state.currentSessionId);
|
|
@@ -5141,7 +5180,7 @@ function registerSlashCommands(pi, state, options = {}) {
|
|
|
5141
5180
|
}
|
|
5142
5181
|
fleetOpen = true;
|
|
5143
5182
|
try {
|
|
5144
|
-
const { openSubagentFleet } = await import("./chunk-
|
|
5183
|
+
const { openSubagentFleet } = await import("./chunk-7YMXOYEU.js");
|
|
5145
5184
|
await openSubagentFleet(ctx, state, { asyncDirRoot: DIRS.async, inspectorPlugins: () => getInspectorPlugins(pi), resultsDir: DIRS.results, fleetKeybindings: options.fleetKeybindings });
|
|
5146
5185
|
} finally {
|
|
5147
5186
|
fleetOpen = false;
|
|
@@ -6773,6 +6812,7 @@ var MESSAGE_VIEWS = /* @__PURE__ */ new Map([
|
|
|
6773
6812
|
["subagent-wait-subscription", readsContent("result", (message2) => waitSubscriptionHeadline(message2.details))],
|
|
6774
6813
|
["subagent-incremental-child-notify", readsContent("result", workflowChildHeadline)],
|
|
6775
6814
|
["subagent-workflow-result-write-failed", readsContent("result", () => ["workflow result ", { status: "save failed" }])],
|
|
6815
|
+
["subagent-auto-resume", readsContent("result", () => ["workflow auto-resume ", { status: "failed" }])],
|
|
6776
6816
|
[SUBAGENT_CONTROL_MESSAGE_TYPE, readsContent("attention", (message2) => controlNoticeHeadline(message2.details))],
|
|
6777
6817
|
[SUBAGENT_STEERING_MESSAGE_TYPE, readsContent("attention", (message2) => steeringNoticeHeadline(message2.details))],
|
|
6778
6818
|
[SUBAGENT_WATCHDOG_WARNING_TYPE, (message2) => watchdogWarningView(message2.details, contentText(message2.content))],
|
|
@@ -8039,9 +8079,79 @@ function buildSubagentToolDescription(config = {}, options) {
|
|
|
8039
8079
|
return fullDescription(on);
|
|
8040
8080
|
}
|
|
8041
8081
|
|
|
8082
|
+
// src/workflows/workflow-auto-resume.ts
|
|
8083
|
+
import * as path13 from "node:path";
|
|
8084
|
+
var WORKFLOW_AUTO_RESUME_MESSAGE_TYPE = "subagent-auto-resume";
|
|
8085
|
+
var AUTO_RESUME_MAX_AGE_MS = 24 * 60 * 60 * 1e3;
|
|
8086
|
+
var AUTO_RESUME_SCAN_LIMIT = 50;
|
|
8087
|
+
function interruptedAt(status) {
|
|
8088
|
+
return status.workflow?.stopCause === WORKFLOW_STOP_CAUSE_OWNER_EXITED ? status.workflow.ownerExitedAt : status.endedAt;
|
|
8089
|
+
}
|
|
8090
|
+
var registryKey = /* @__PURE__ */ Symbol.for("pi-subagents.workflow-auto-resume.v1");
|
|
8091
|
+
var registryGlobal = globalThis;
|
|
8092
|
+
var pendingAutoResumes = registryGlobal[registryKey] ?? (registryGlobal[registryKey] = /* @__PURE__ */ new Set());
|
|
8093
|
+
function cancelPendingWorkflowAutoResumes(match) {
|
|
8094
|
+
for (const entry of pendingAutoResumes) {
|
|
8095
|
+
if (entry.state !== "pending" || !match(entry)) continue;
|
|
8096
|
+
entry.state = "cancelled";
|
|
8097
|
+
try {
|
|
8098
|
+
releaseWorkflowResumeClaim(entry.prepared.sourceAsyncDir, entry.prepared.newRunId);
|
|
8099
|
+
} catch (error) {
|
|
8100
|
+
console.error(`Failed to give back the auto-resume claim of workflow ${entry.prepared.sourceRunId}:`, error);
|
|
8101
|
+
}
|
|
8102
|
+
}
|
|
8103
|
+
}
|
|
8104
|
+
function finishWorkflowAutoResume(entry) {
|
|
8105
|
+
if (entry.state !== "cancelled") pendingAutoResumes.delete(entry);
|
|
8106
|
+
}
|
|
8107
|
+
function planWorkflowAutoResumes(input) {
|
|
8108
|
+
const { asyncDirRoot, currentSessionId, now } = input;
|
|
8109
|
+
cancelPendingWorkflowAutoResumes((entry) => entry.sessionId === currentSessionId);
|
|
8110
|
+
const reusableRunIds = /* @__PURE__ */ new Map();
|
|
8111
|
+
for (const entry of pendingAutoResumes) {
|
|
8112
|
+
if (entry.sessionId !== currentSessionId || entry.state !== "cancelled") continue;
|
|
8113
|
+
reusableRunIds.set(entry.prepared.sourceRunId, entry.prepared.newRunId);
|
|
8114
|
+
pendingAutoResumes.delete(entry);
|
|
8115
|
+
}
|
|
8116
|
+
let runIds;
|
|
8117
|
+
try {
|
|
8118
|
+
runIds = readRecentTerminalRunIndex(asyncDirRoot, { sessionId: currentSessionId, limit: AUTO_RESUME_SCAN_LIMIT, endedAfter: now - AUTO_RESUME_MAX_AGE_MS });
|
|
8119
|
+
} catch (error) {
|
|
8120
|
+
console.error("Failed to read interrupted workflows for auto-resume:", error);
|
|
8121
|
+
return [];
|
|
8122
|
+
}
|
|
8123
|
+
const planned = [];
|
|
8124
|
+
for (const runId of runIds) {
|
|
8125
|
+
const asyncDir = path13.join(asyncDirRoot, runId);
|
|
8126
|
+
try {
|
|
8127
|
+
const status = readStatus(asyncDir);
|
|
8128
|
+
if (!status || status.mode !== "workflow" || status.parentWorkflowRunId !== void 0 || status.sessionId !== currentSessionId) continue;
|
|
8129
|
+
if (!isReusableWorkflowStopCause(status.workflow?.stopCause)) continue;
|
|
8130
|
+
const at = interruptedAt(status);
|
|
8131
|
+
if (at === void 0 || now - at > AUTO_RESUME_MAX_AGE_MS) continue;
|
|
8132
|
+
if (workflowResumeClaimState(asyncDir).kind !== "none" || hasWorkflowResumeRefusal(asyncDir)) continue;
|
|
8133
|
+
const preparation = prepareWorkflowResume({ asyncDirRoot, sourceRunId: runId, trigger: "auto", now, currentSessionId, newRunId: reusableRunIds.get(runId) });
|
|
8134
|
+
if (preparation.ok) {
|
|
8135
|
+
const entry = { sessionId: currentSessionId, owner: input.owner, prepared: preparation.prepared, state: "pending" };
|
|
8136
|
+
pendingAutoResumes.add(entry);
|
|
8137
|
+
planned.push(entry);
|
|
8138
|
+
continue;
|
|
8139
|
+
}
|
|
8140
|
+
if (preparation.code === "claim-busy" || preparation.code === "claim-resumed") continue;
|
|
8141
|
+
recordWorkflowResumeRefusal(asyncDir, { reason: preparation.reason, byHand: preparation.byHand }, now);
|
|
8142
|
+
} catch (error) {
|
|
8143
|
+
console.error(`Failed to prepare auto-resume of workflow ${runId}:`, error);
|
|
8144
|
+
}
|
|
8145
|
+
}
|
|
8146
|
+
return planned;
|
|
8147
|
+
}
|
|
8148
|
+
function autoResumeFailureText(sourceRunId, refusal) {
|
|
8149
|
+
return `Workflow ${sourceRunId} was not auto-resumed: ${refusalSentence(refusal.reason, refusal.byHand)}`;
|
|
8150
|
+
}
|
|
8151
|
+
|
|
8042
8152
|
// src/missions/goal-driver.ts
|
|
8043
8153
|
import * as fs14 from "node:fs";
|
|
8044
|
-
import * as
|
|
8154
|
+
import * as path14 from "node:path";
|
|
8045
8155
|
var TERMINAL_MISSION_STATUSES2 = /* @__PURE__ */ new Set(["completed", "failed", "cancelled"]);
|
|
8046
8156
|
var ACTIVE_RUN_STATUSES = /* @__PURE__ */ new Set(["queued", "running", "active"]);
|
|
8047
8157
|
var MAX_ACTION_LENGTH = 180;
|
|
@@ -8056,7 +8166,7 @@ function tokenUsage(value) {
|
|
|
8056
8166
|
}
|
|
8057
8167
|
function readLinkedRun(run) {
|
|
8058
8168
|
if (!run.asyncDir) return run;
|
|
8059
|
-
const statusPath =
|
|
8169
|
+
const statusPath = path14.join(run.asyncDir, "status.json");
|
|
8060
8170
|
if (!fs14.existsSync(statusPath)) return run;
|
|
8061
8171
|
let parsed;
|
|
8062
8172
|
try {
|
|
@@ -8182,14 +8292,57 @@ function collectGoalContinuationNotices(input) {
|
|
|
8182
8292
|
return notices;
|
|
8183
8293
|
}
|
|
8184
8294
|
|
|
8295
|
+
// src/runs/background/interrupted-elsewhere.ts
|
|
8296
|
+
var INTERRUPTED_ELSEWHERE_MAX_AGE_MS = 24 * 60 * 60 * 1e3;
|
|
8297
|
+
function interruptedElsewhereLine(reopenId, count) {
|
|
8298
|
+
const command = `\`pi --session ${reopenId}\``;
|
|
8299
|
+
return count === 1 ? `1 subagent run was interrupted in another session. Reopen it to resume it: ${command}` : `${count} subagent runs were interrupted in another session. Reopen it to resume them: ${command}`;
|
|
8300
|
+
}
|
|
8301
|
+
function createInterruptedElsewhereCollector(input) {
|
|
8302
|
+
const ownSessions = ownerSessionIds(input.currentSessionId);
|
|
8303
|
+
const candidates = /* @__PURE__ */ new Map();
|
|
8304
|
+
const recent = (at) => typeof at === "number" && input.now - at <= INTERRUPTED_ELSEWHERE_MAX_AGE_MS;
|
|
8305
|
+
const add = (sessionId, runId, ownerDead) => {
|
|
8306
|
+
if (ownSessions.has(sessionId)) return;
|
|
8307
|
+
const runs = candidates.get(sessionId) ?? /* @__PURE__ */ new Map();
|
|
8308
|
+
if (!runs.has(runId)) runs.set(runId, ownerDead);
|
|
8309
|
+
candidates.set(sessionId, runs);
|
|
8310
|
+
};
|
|
8311
|
+
return {
|
|
8312
|
+
observeStatus(observed) {
|
|
8313
|
+
const status = observed;
|
|
8314
|
+
if (!status || typeof status.sessionId !== "string" || typeof status.runId !== "string" || status.state !== "running" && status.state !== "queued") return;
|
|
8315
|
+
if (status.parentWorkflowRunId !== void 0 || status.cwd !== input.cwd || !recent(status.lastUpdate ?? status.startedAt)) return;
|
|
8316
|
+
const { pid, pidNamespaceScope, bootId } = status;
|
|
8317
|
+
if (typeof pid !== "number") return;
|
|
8318
|
+
add(status.sessionId, status.runId, () => checkRecordedPidLiveness({ pid, pidNamespaceScope, bootId }) === "dead");
|
|
8319
|
+
},
|
|
8320
|
+
observeForegroundRun(run) {
|
|
8321
|
+
if (!run.sessionId || run.parentWorkflowRunId !== void 0 || run.cwd !== input.cwd || !recent(run.updatedAt)) return;
|
|
8322
|
+
add(run.sessionId, run.runId, () => ownerConfirmedDead(run));
|
|
8323
|
+
},
|
|
8324
|
+
lines() {
|
|
8325
|
+
const lines = [];
|
|
8326
|
+
for (const [sessionId, runs] of candidates) {
|
|
8327
|
+
const reopenId = resolvePiSessionId(sessionId);
|
|
8328
|
+
if (!reopenId) continue;
|
|
8329
|
+
let interrupted = 0;
|
|
8330
|
+
for (const ownerDead of runs.values()) if (ownerDead()) interrupted += 1;
|
|
8331
|
+
if (interrupted > 0) lines.push(interruptedElsewhereLine(reopenId, interrupted));
|
|
8332
|
+
}
|
|
8333
|
+
return lines;
|
|
8334
|
+
}
|
|
8335
|
+
};
|
|
8336
|
+
}
|
|
8337
|
+
|
|
8185
8338
|
// src/extension/upgrade-notice.ts
|
|
8186
8339
|
import * as fs15 from "node:fs";
|
|
8187
|
-
import * as
|
|
8340
|
+
import * as path15 from "node:path";
|
|
8188
8341
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
8189
8342
|
var versionNumber = (version) => typeof version === "string" && /^\d+\.\d+\.\d+$/.test(version) ? version.split(".").reduce((total, part) => total * 1e6 + Number(part), 0) : void 0;
|
|
8190
|
-
async function showUpgradeNotice(ctx, stateDir =
|
|
8343
|
+
async function showUpgradeNotice(ctx, stateDir = path15.join(getAgentDir(), "pi-subagents"), changelogPath = fileURLToPath2(new URL("../../CHANGELOG.md", new URL("../src/extension/upgrade-notice.js", import.meta.url).href)), version = package_default.version) {
|
|
8191
8344
|
if (!ctx.hasUI) return;
|
|
8192
|
-
const statePath =
|
|
8345
|
+
const statePath = path15.join(stateDir, "last-seen-version.json");
|
|
8193
8346
|
const lastSeen = await fs15.promises.readFile(statePath, "utf-8").then((raw) => JSON.parse(raw).version).catch(() => void 0);
|
|
8194
8347
|
const previous = versionNumber(lastSeen);
|
|
8195
8348
|
const current = versionNumber(version);
|
|
@@ -8251,14 +8404,14 @@ function formatWorkflowPreflightCall(input) {
|
|
|
8251
8404
|
}
|
|
8252
8405
|
function getSubagentSessionRoot(parentSessionFile) {
|
|
8253
8406
|
if (parentSessionFile) {
|
|
8254
|
-
const baseName =
|
|
8255
|
-
const sessionsDir =
|
|
8256
|
-
return
|
|
8407
|
+
const baseName = path16.basename(parentSessionFile, ".jsonl");
|
|
8408
|
+
const sessionsDir = path16.dirname(parentSessionFile);
|
|
8409
|
+
return path16.join(sessionsDir, baseName);
|
|
8257
8410
|
}
|
|
8258
|
-
return fs16.mkdtempSync(
|
|
8411
|
+
return fs16.mkdtempSync(path16.join(os3.tmpdir(), "pi-subagent-session-"));
|
|
8259
8412
|
}
|
|
8260
8413
|
function expandTilde(p) {
|
|
8261
|
-
return p.startsWith("~/") ?
|
|
8414
|
+
return p.startsWith("~/") ? path16.join(os3.homedir(), p.slice(2)) : p;
|
|
8262
8415
|
}
|
|
8263
8416
|
function isSlashResultRunning(result) {
|
|
8264
8417
|
return result.details?.progress?.some((entry) => entry.status === "running") || result.details?.results.some((entry) => entry.progress?.status === "running") || false;
|
|
@@ -8414,7 +8567,7 @@ function registerSubagentExtension(pi) {
|
|
|
8414
8567
|
const ctx = withLastUiContext((current) => current);
|
|
8415
8568
|
if (!ctx) return;
|
|
8416
8569
|
try {
|
|
8417
|
-
const { openSubagentFleet } = await import("./chunk-
|
|
8570
|
+
const { openSubagentFleet } = await import("./chunk-7YMXOYEU.js");
|
|
8418
8571
|
await openSubagentFleet(ctx, state, { initialKey: itemKey, asyncDirRoot: DIRS.async, resultsDir: DIRS.results, fleetKeybindings: config.fleetKeybindings, inspectorPlugins: () => getInspectorPlugins(pi) });
|
|
8419
8572
|
} catch (error) {
|
|
8420
8573
|
if (isStaleExtensionContextError(error)) {
|
|
@@ -8521,6 +8674,7 @@ function registerSubagentExtension(pi) {
|
|
|
8521
8674
|
refreshResultDelivery();
|
|
8522
8675
|
},
|
|
8523
8676
|
onJobCleanup: (asyncId) => deliveredRunIds.delete(asyncId),
|
|
8677
|
+
deliveryOwnerId: resultDeliveryOwnership.deliveryOwnerId,
|
|
8524
8678
|
supervisorRequestState: supervisorChannel.getSupervisorRequestState,
|
|
8525
8679
|
onJobsChanged: programStatus.sync
|
|
8526
8680
|
});
|
|
@@ -8609,7 +8763,7 @@ function registerSubagentExtension(pi) {
|
|
|
8609
8763
|
let executor;
|
|
8610
8764
|
let executorPromise;
|
|
8611
8765
|
let executorModulePromise;
|
|
8612
|
-
const loadExecutorModule = () => executorModulePromise ??= import("./chunk-
|
|
8766
|
+
const loadExecutorModule = () => executorModulePromise ??= import("./chunk-B5EKXDHE.js");
|
|
8613
8767
|
const getExecutor = () => {
|
|
8614
8768
|
executorPromise ??= loadExecutorModule().then(({ createSubagentExecutor }) => {
|
|
8615
8769
|
executor = createSubagentExecutor(executorDeps);
|
|
@@ -8623,7 +8777,7 @@ function registerSubagentExtension(pi) {
|
|
|
8623
8777
|
modulePreloadTimer = setTimeout(() => {
|
|
8624
8778
|
loadExecutorModule().catch(() => {
|
|
8625
8779
|
});
|
|
8626
|
-
if (fleetViewEnabled) import("./chunk-
|
|
8780
|
+
if (fleetViewEnabled) import("./chunk-7YMXOYEU.js").catch(() => {
|
|
8627
8781
|
});
|
|
8628
8782
|
}, MODULE_PRELOAD_DELAY_MS);
|
|
8629
8783
|
modulePreloadTimer.unref?.();
|
|
@@ -8675,6 +8829,43 @@ ${close}` }]
|
|
|
8675
8829
|
await waitForAdvertisement();
|
|
8676
8830
|
return (await getExecutor()).executePublic(id, params, signal, onUpdate, ctx);
|
|
8677
8831
|
};
|
|
8832
|
+
const autoResumeOwner = {};
|
|
8833
|
+
const postAutoResumeFailure = (sourceRunId, refusal) => {
|
|
8834
|
+
pi.sendMessage({ customType: WORKFLOW_AUTO_RESUME_MESSAGE_TYPE, content: autoResumeFailureText(sourceRunId, refusal), display: true }, { triggerTurn: false });
|
|
8835
|
+
};
|
|
8836
|
+
const launchWorkflowAutoResume = async (entry, ctx) => {
|
|
8837
|
+
const { prepared } = entry;
|
|
8838
|
+
try {
|
|
8839
|
+
await new Promise((resolve6) => setImmediate(resolve6));
|
|
8840
|
+
await waitForAdvertisement();
|
|
8841
|
+
const executor2 = await getExecutor();
|
|
8842
|
+
if (entry.state !== "pending") return;
|
|
8843
|
+
entry.state = "started";
|
|
8844
|
+
const outcome = await executor2.executeWorkflowResume(randomUUID3(), prepared, new AbortController().signal, ctx);
|
|
8845
|
+
if (outcome.launched && runtimeCleaned) state.workflowControllers?.get(prepared.newRunId)?.abort(runtimeReplacedAbortReason());
|
|
8846
|
+
if (outcome.launched || runtimeCleaned) return;
|
|
8847
|
+
try {
|
|
8848
|
+
postAutoResumeFailure(prepared.sourceRunId, outcome.refusal);
|
|
8849
|
+
} catch (error) {
|
|
8850
|
+
console.error(`Failed to post the auto-resume failure of workflow ${prepared.sourceRunId}:`, error);
|
|
8851
|
+
}
|
|
8852
|
+
} catch (error) {
|
|
8853
|
+
if (entry.state === "cancelled") return;
|
|
8854
|
+
const message2 = error instanceof Error ? error.message : String(error);
|
|
8855
|
+
console.error(`Failed to auto-resume workflow ${prepared.sourceRunId}:`, error);
|
|
8856
|
+
try {
|
|
8857
|
+
if (resumedRunStarted(prepared.sourceAsyncDir, prepared.newRunId)) return;
|
|
8858
|
+
releaseWorkflowResumeClaim(prepared.sourceAsyncDir, prepared.newRunId);
|
|
8859
|
+
const refusal = workflowResumeRefusal("launch-failed", `launch failed: ${message2}`, prepared.sourceRunId);
|
|
8860
|
+
recordWorkflowResumeRefusal(prepared.sourceAsyncDir, { reason: refusal.reason, byHand: refusal.byHand, newRunId: prepared.newRunId });
|
|
8861
|
+
postAutoResumeFailure(prepared.sourceRunId, refusal);
|
|
8862
|
+
} catch (cleanupError) {
|
|
8863
|
+
console.error(`Failed to give back the auto-resume claim of workflow ${prepared.sourceRunId}:`, cleanupError);
|
|
8864
|
+
}
|
|
8865
|
+
} finally {
|
|
8866
|
+
finishWorkflowAutoResume(entry);
|
|
8867
|
+
}
|
|
8868
|
+
};
|
|
8678
8869
|
const executeSubagentCollapsed = (id, params, signal, onUpdate, ctx) => {
|
|
8679
8870
|
if (ctx.hasUI) ctx.ui.setToolsExpanded(false);
|
|
8680
8871
|
return executeSubagentReady(id, params, signal, onUpdate, ctx);
|
|
@@ -8898,9 +9089,9 @@ ${close}` }]
|
|
|
8898
9089
|
owedResultRunIds.clear();
|
|
8899
9090
|
deliveredRunIds.clear();
|
|
8900
9091
|
state.parentSessionFile = ctx.sessionManager.getSessionFile();
|
|
8901
|
-
state.trustedSessionFileRoot = state.parentSessionFile ?
|
|
9092
|
+
state.trustedSessionFileRoot = state.parentSessionFile ? path16.join(getAgentDir(), "sessions") : void 0;
|
|
8902
9093
|
state.trustedSessionRoots = [.../* @__PURE__ */ new Set([
|
|
8903
|
-
...config.defaultSessionDir ? [
|
|
9094
|
+
...config.defaultSessionDir ? [path16.resolve(expandTilde(config.defaultSessionDir))] : [],
|
|
8904
9095
|
...state.parentSessionFile ? [getSubagentSessionRoot(state.parentSessionFile)] : []
|
|
8905
9096
|
])];
|
|
8906
9097
|
state.subagentSpawns = {
|
|
@@ -8910,7 +9101,7 @@ ${close}` }]
|
|
|
8910
9101
|
granted: 0,
|
|
8911
9102
|
grantHistory: []
|
|
8912
9103
|
};
|
|
8913
|
-
const projectPaneOwnerRoot =
|
|
9104
|
+
const projectPaneOwnerRoot = path16.resolve(ctx.cwd);
|
|
8914
9105
|
restoreHerdrProjectPaneSnapshots(state, [.../* @__PURE__ */ new Set([...state.herdrProjectPanes?.keys() ?? [], ...listHerdrProjectPaneRoots(projectPaneOwnerRoot), projectPaneOwnerRoot])]);
|
|
8915
9106
|
if (!process.env[SUBAGENT_CHILD_ENV]) {
|
|
8916
9107
|
delete process.env[SUBAGENT_PARENT_SESSION_ENV];
|
|
@@ -8931,12 +9122,24 @@ ${close}` }]
|
|
|
8931
9122
|
resetJobs(ctx);
|
|
8932
9123
|
logSlowPhase("reset-jobs", phaseStartedAt);
|
|
8933
9124
|
phaseStartedAt = Date.now();
|
|
8934
|
-
|
|
9125
|
+
const interruptedElsewhere = ctx.hasUI ? createInterruptedElsewhereCollector({ currentSessionId: state.currentSessionId, cwd: ctx.cwd, now: Date.now() }) : void 0;
|
|
9126
|
+
restoreForegroundRunHistory(state, { resultsDir: DIRS.results, observeForeign: interruptedElsewhere?.observeForegroundRun });
|
|
8935
9127
|
logSlowPhase("foreground-history", phaseStartedAt);
|
|
8936
9128
|
phaseStartedAt = Date.now();
|
|
8937
|
-
restoreActiveJobs(ctx);
|
|
9129
|
+
restoreActiveJobs(ctx, interruptedElsewhere?.observeStatus);
|
|
8938
9130
|
logSlowPhase("active-job-restore", phaseStartedAt);
|
|
8939
9131
|
phaseStartedAt = Date.now();
|
|
9132
|
+
if (interruptedElsewhere) for (const line of interruptedElsewhere.lines()) ctx.ui.notify(line, "info");
|
|
9133
|
+
logSlowPhase("cross-session-notice", phaseStartedAt);
|
|
9134
|
+
phaseStartedAt = Date.now();
|
|
9135
|
+
cancelPendingWorkflowAutoResumes((entry) => entry.owner === autoResumeOwner);
|
|
9136
|
+
if (recovering && ctx.hasUI && config.autoResume !== false) {
|
|
9137
|
+
for (const entry of planWorkflowAutoResumes({ asyncDirRoot: DIRS.async, currentSessionId: state.currentSessionId, now: Date.now(), owner: autoResumeOwner })) {
|
|
9138
|
+
void launchWorkflowAutoResume(entry, ctx);
|
|
9139
|
+
}
|
|
9140
|
+
}
|
|
9141
|
+
logSlowPhase("workflow-auto-resume", phaseStartedAt);
|
|
9142
|
+
phaseStartedAt = Date.now();
|
|
8940
9143
|
scheduledRunManager.bindSession(ctx);
|
|
8941
9144
|
logSlowPhase("scheduled-runs", phaseStartedAt);
|
|
8942
9145
|
phaseStartedAt = Date.now();
|
|
@@ -8960,6 +9163,7 @@ ${close}` }]
|
|
|
8960
9163
|
cleanup(shutdownReason) {
|
|
8961
9164
|
if (runtimeCleaned) return;
|
|
8962
9165
|
runtimeCleaned = true;
|
|
9166
|
+
cancelPendingWorkflowAutoResumes((entry) => entry.owner === autoResumeOwner);
|
|
8963
9167
|
programStatus.dispose(shutdownReason);
|
|
8964
9168
|
releaseHostSessionLiveness();
|
|
8965
9169
|
releaseHostSessionLiveness = () => {
|
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
validateCodeOwnedProfileRunner,
|
|
9
9
|
validatePermissionRules,
|
|
10
10
|
validateToolBudgetConfig
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-CIZQXJ5Q.js";
|
|
12
12
|
|
|
13
13
|
// src/agents/runtime-agent-registry.ts
|
|
14
14
|
var RUNTIME_AGENT_REGISTRY_KEY = "pi-subagents.runtime-agents.v1";
|