@zq-silk/yui 0.13.8 → 0.13.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +9 -8
- package/dist/cli/commandCatalog.js +21 -2
- package/dist/cli.js +42 -13
- package/dist/commands/agentCommands.js +1 -1
- package/dist/commands/configCommands.js +1 -86
- package/dist/commands/executionAuditCommands.js +17 -16
- package/dist/commands/globalRoleCommands.js +4 -4
- package/dist/commands/sessionCommands.js +2 -6
- package/dist/commands/taskActor.js +1 -2
- package/dist/commands/taskCommands.js +92 -9
- package/dist/commands/taskRoleRuntimeStatus.js +3 -3
- package/dist/config/configCatalog.js +1 -6
- package/dist/config/yuiConfig.js +0 -79
- package/dist/controller/clientRuntime.js +40 -3
- package/dist/controller/controller.js +29 -52
- package/dist/controller/fileSchedulerStoreAdapter.js +305 -1056
- package/dist/controller/runtime.js +12 -5
- package/dist/controller/runtimeHookRunFence.js +3 -9
- package/dist/controller/runtimeLaunchCoordinator.js +44 -67
- package/dist/controller/structuredProviderObservation.js +18 -5
- package/dist/coordination/workMailbox.js +4 -4
- package/dist/execution/executionHealth.js +1 -1
- package/dist/executor/agentExecutor.js +92 -68
- package/dist/executor/executorRegistry.js +8 -20
- package/dist/executor/fileRoleLaunchPlanner.js +24 -90
- package/dist/executor/turnCompletion.js +5 -5
- package/dist/lifecycle/exactRunTerminalization.js +1 -1
- package/dist/observability/executionAudit.js +40 -94
- package/dist/operator/operatorSessionHistory.js +7 -5
- package/dist/role/role.js +1 -1
- package/dist/run/agentRun.js +4 -54
- package/dist/runtime/agentDriver.js +2 -0
- package/dist/runtime/agentError.js +114 -0
- package/dist/runtime/agentHost.js +55 -82
- package/dist/runtime/builtinAgentDrivers.js +21 -9
- package/dist/runtime/builtinAgentErrorMappers.js +150 -0
- package/dist/runtime/exactControlPlane.js +6 -12
- package/dist/runtime/index.js +0 -1
- package/dist/runtime/launchBroker.js +5 -19
- package/dist/runtime/lifecycleReservation.js +20 -4
- package/dist/runtime/providerRuntimeIdentity.js +3 -2
- package/dist/runtime/runtimeBinding.js +0 -27
- package/dist/runtime/runtimeObservation.js +7 -16
- package/dist/runtime/runtimeSessionCandidate.js +3 -10
- package/dist/runtime/sessionLaunchRequest.js +1 -2
- package/dist/runtime/sessionReconciliation.js +2 -2
- package/dist/runtime/structuredProviderHost.js +44 -79
- package/dist/runtime/taskRuntimeIsolation.js +0 -7
- package/dist/runtime/tmuxAdapters.js +6 -49
- package/dist/scheduler/activeRoleRunDelivery.js +218 -168
- package/dist/scheduler/leaderWakeupProcessor.js +126 -86
- package/dist/scheduler/roleRunLiveness.js +4 -1
- package/dist/scheduler/roleRunStall.js +7 -11
- package/dist/scheduler/wakeReason.js +4 -0
- package/dist/storage/migration/productionRegistry.js +332 -0
- package/dist/storage/sqliteSchema.js +54 -2
- package/dist/storage/sqliteStore.js +11 -44
- package/dist/storage/taskStore.js +7 -35
- package/package.json +1 -1
- package/skills/yui-leader/SKILL.md +30 -8
- package/skills/yui-operator/SKILL.md +14 -6
- package/skills/yui-runtime/SKILL.md +6 -4
- package/dist/lifecycle/providerErrorClass.js +0 -152
- package/dist/run/providerRetry.js +0 -226
- package/dist/run/providerRetryConfig.js +0 -27
- package/dist/runtime/providerErrorCodes.js +0 -278
- package/dist/runtime/providerRecoveryDecision.js +0 -55
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { createAgentRun } from "../run/agentRun.js";
|
|
2
|
-
import { createRunAssignment } from "../context/runContextContract.js";
|
|
2
|
+
import { createRunAssignment, serializeRunBootstrapEnvelope } from "../context/runContextContract.js";
|
|
3
3
|
import { formatAgentRunReceiptId } from "../task/taskRecordReference.js";
|
|
4
4
|
import { effectiveLaunchSnapshotsCompatible, effectiveLaunchSnapshotsCompatibleForTaskSession } from "../executor/effectiveLaunch.js";
|
|
5
5
|
import { roleAgentSessionResumeMode } from "../executor/agentExecutor.js";
|
|
6
6
|
import { RuntimeLifecycleBusyError } from "../runtime/lifecycleReservation.js";
|
|
7
|
-
import { recordLeaderFailure } from "./leaderFailure.js";
|
|
8
7
|
import { isSchedulerTaskWorkspaceReady } from "./ports.js";
|
|
9
8
|
import { RuntimeLaunchError } from "../runtime/ports.js";
|
|
9
|
+
import { serializeAgentErrorRaw } from "../runtime/agentError.js";
|
|
10
10
|
export async function processLeaderWakeups(store, delivery, now, selection) {
|
|
11
11
|
const results = [];
|
|
12
12
|
const wakeups = selection === undefined || selection.full
|
|
@@ -42,6 +42,13 @@ export async function processLeaderWakeups(store, delivery, now, selection) {
|
|
|
42
42
|
results.push({ taskId: task.id, status: "skipped", reason: "busy" });
|
|
43
43
|
continue;
|
|
44
44
|
}
|
|
45
|
+
// A durable wake is already the complete next intent. Do not materialize
|
|
46
|
+
// another Run while the Provider still owns the previous Turn: doing so
|
|
47
|
+
// would make its late terminal compete with a newer Run generation.
|
|
48
|
+
if (providerTurnIsUnsettled(store, task.id, role.name)) {
|
|
49
|
+
results.push({ taskId: task.id, status: "skipped", reason: "busy" });
|
|
50
|
+
continue;
|
|
51
|
+
}
|
|
45
52
|
const reopening = wakeup.reasons.includes("task-reopened");
|
|
46
53
|
let existingSession = store.getRoleSession(task.id, role.name, reopening ? undefined : role.effective.agentId);
|
|
47
54
|
let effectiveSession = existingSession;
|
|
@@ -50,6 +57,7 @@ export async function processLeaderWakeups(store, delivery, now, selection) {
|
|
|
50
57
|
let run = null;
|
|
51
58
|
let prepared;
|
|
52
59
|
let preStartFencePersisted = false;
|
|
60
|
+
let mode = "new";
|
|
53
61
|
try {
|
|
54
62
|
const compatibleSession = existingSession !== null
|
|
55
63
|
&& (reopening
|
|
@@ -60,16 +68,15 @@ export async function processLeaderWakeups(store, delivery, now, selection) {
|
|
|
60
68
|
&& !compatibleSession;
|
|
61
69
|
if (hasNativeSession(existingSession) && !compatibleSession
|
|
62
70
|
&& !reopenIdentityDrift
|
|
63
|
-
&& existingSession.status
|
|
71
|
+
&& existingSession.status === "active") {
|
|
64
72
|
throw new Error(`Leader Session is incompatible with desired effective launch: ${task.id}/${role.name}.`);
|
|
65
73
|
}
|
|
66
74
|
const resumableSession = hasNativeSession(existingSession)
|
|
67
|
-
&& existingSession.status
|
|
68
|
-
&& existingSession.status !== "broken";
|
|
75
|
+
&& existingSession.status === "active";
|
|
69
76
|
// Reuse a healthy Session. A terminal Session is disposable and the next
|
|
70
77
|
// Run starts fresh without consulting historical recovery records.
|
|
71
78
|
const sessionSet = store.getTaskRoleSessionSet?.(task.id, role.name) ?? null;
|
|
72
|
-
|
|
79
|
+
mode = reopenIdentityDrift
|
|
73
80
|
? "new"
|
|
74
81
|
: sessionSet === null
|
|
75
82
|
? resumableSession && compatibleSession ? "resume" : "new"
|
|
@@ -130,25 +137,17 @@ export async function processLeaderWakeups(store, delivery, now, selection) {
|
|
|
130
137
|
mode,
|
|
131
138
|
runId: run.id,
|
|
132
139
|
...(mode === "resume" ? { nativeSessionId: existingSession.nativeSessionId } : {}),
|
|
140
|
+
...(mode !== "resume" || existingSession?.launchId === undefined
|
|
141
|
+
? {}
|
|
142
|
+
: { hostActivationId: existingSession.launchId }),
|
|
133
143
|
beforeHostStart: (preflight) => {
|
|
134
144
|
persistPreStartFence(store, task, role, run, existingSession, mode, preflight, now);
|
|
135
145
|
effectiveSession = preflightSession(role, run.effective, existingSession, mode, preflight);
|
|
136
146
|
preStartFencePersisted = true;
|
|
137
147
|
}
|
|
138
148
|
});
|
|
139
|
-
//
|
|
140
|
-
//
|
|
141
|
-
// fact, any
|
|
142
|
-
// later readiness or aggregate-write failure is delivery uncertainty,
|
|
143
|
-
// not a launch failure: preserve the Run and its reservation for the
|
|
144
|
-
// matching provider Hook instead of terminalizing it.
|
|
145
|
-
deliveryAttempted = prepared.turnAcceptedDuringLaunch === true
|
|
146
|
-
|| prepared.turnDeliveryUnknownDuringLaunch === true;
|
|
147
|
-
// Persist the exact preparation fence before waiting on provider
|
|
148
|
-
// readiness. A pre-input lifecycle Hook may fire during that wait; it
|
|
149
|
-
// must be able to resolve this Run/Session/launch generation from durable
|
|
150
|
-
// state rather than an in-memory delivery object. Fresh providers that
|
|
151
|
-
// discover their native Session later intentionally persist `null`.
|
|
149
|
+
// Persist the Session identity before submitting the Leader Turn.
|
|
150
|
+
// Starting/restoring a Session is independent from sending Run input.
|
|
152
151
|
if (!preStartFencePersisted) {
|
|
153
152
|
const preparedFenceSession = prepared.session === undefined
|
|
154
153
|
? existingSession
|
|
@@ -164,9 +163,6 @@ export async function processLeaderWakeups(store, delivery, now, selection) {
|
|
|
164
163
|
});
|
|
165
164
|
}
|
|
166
165
|
const ready = await delivery.waitUntilReady(prepared);
|
|
167
|
-
deliveryAttempted = deliveryAttempted
|
|
168
|
-
|| ready.prepared.turnAcceptedDuringLaunch === true
|
|
169
|
-
|| ready.prepared.turnDeliveryUnknownDuringLaunch === true;
|
|
170
166
|
const latestTask = store.getTask(task.id);
|
|
171
167
|
if (latestTask === null
|
|
172
168
|
|| latestTask.status !== "active"
|
|
@@ -193,10 +189,13 @@ export async function processLeaderWakeups(store, delivery, now, selection) {
|
|
|
193
189
|
: { launchId: ready.prepared.launchId }),
|
|
194
190
|
now
|
|
195
191
|
});
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
192
|
+
deliveryAttempted = true;
|
|
193
|
+
const outcome = await delivery.sendOnce({
|
|
194
|
+
delivery: ready,
|
|
195
|
+
receiptId: formatAgentRunReceiptId(task.id, run.id),
|
|
196
|
+
text: serializeRunBootstrapEnvelope(run.bootstrapEnvelope)
|
|
197
|
+
});
|
|
198
|
+
if (outcome === "busy" || outcome === "unavailable") {
|
|
200
199
|
delivery.forgetPrepared?.({
|
|
201
200
|
taskId: task.id,
|
|
202
201
|
roleName: role.name,
|
|
@@ -209,12 +208,12 @@ export async function processLeaderWakeups(store, delivery, now, selection) {
|
|
|
209
208
|
taskId: task.id,
|
|
210
209
|
runId: run.id,
|
|
211
210
|
status: "skipped",
|
|
212
|
-
reason: "busy"
|
|
211
|
+
reason: outcome === "busy" ? "busy" : "not-ready"
|
|
213
212
|
});
|
|
214
213
|
continue;
|
|
215
214
|
}
|
|
216
|
-
if (
|
|
217
|
-
const
|
|
215
|
+
if (outcome === "rejected") {
|
|
216
|
+
const terminal = store.saveRoleRunDeliveryFailure({
|
|
218
217
|
taskId: task.id,
|
|
219
218
|
roleName: role.name,
|
|
220
219
|
agentId: run.effective.agentId,
|
|
@@ -227,43 +226,10 @@ export async function processLeaderWakeups(store, delivery, now, selection) {
|
|
|
227
226
|
...(ready.prepared.launchId === undefined
|
|
228
227
|
? {}
|
|
229
228
|
: { launchId: ready.prepared.launchId }),
|
|
230
|
-
summary:
|
|
229
|
+
summary: "Provider rejected the Leader Turn before acceptance; Operator recovery is required.",
|
|
231
230
|
cleanupRequired: false,
|
|
232
231
|
now
|
|
233
232
|
});
|
|
234
|
-
if (persisted === "failed") {
|
|
235
|
-
delivery.forgetPrepared?.({
|
|
236
|
-
taskId: task.id,
|
|
237
|
-
roleName: role.name,
|
|
238
|
-
runId: run.id,
|
|
239
|
-
...(ready.prepared.launchId === undefined
|
|
240
|
-
? {}
|
|
241
|
-
: { launchId: ready.prepared.launchId })
|
|
242
|
-
});
|
|
243
|
-
}
|
|
244
|
-
results.push({
|
|
245
|
-
taskId: task.id,
|
|
246
|
-
runId: run.id,
|
|
247
|
-
status: persisted === "failed" ? "failed" : "skipped",
|
|
248
|
-
reason: "provider-rejected",
|
|
249
|
-
terminalized: persisted === "failed",
|
|
250
|
-
...(persisted === "failed"
|
|
251
|
-
? {}
|
|
252
|
-
: { error: "Run state changed while recording exact Provider rejection." })
|
|
253
|
-
});
|
|
254
|
-
continue;
|
|
255
|
-
}
|
|
256
|
-
if (ready.prepared.turnDeliveryUnknownDuringLaunch === true) {
|
|
257
|
-
store.saveRoleRunDelivery({
|
|
258
|
-
task,
|
|
259
|
-
role,
|
|
260
|
-
run,
|
|
261
|
-
session: effectiveSession,
|
|
262
|
-
...(ready.prepared.launchId === undefined
|
|
263
|
-
? {}
|
|
264
|
-
: { launchId: ready.prepared.launchId }),
|
|
265
|
-
now
|
|
266
|
-
});
|
|
267
233
|
delivery.forgetPrepared?.({
|
|
268
234
|
taskId: task.id,
|
|
269
235
|
roleName: role.name,
|
|
@@ -275,15 +241,13 @@ export async function processLeaderWakeups(store, delivery, now, selection) {
|
|
|
275
241
|
results.push({
|
|
276
242
|
taskId: task.id,
|
|
277
243
|
runId: run.id,
|
|
278
|
-
status: "skipped",
|
|
279
|
-
reason: "
|
|
244
|
+
status: terminal === "failed" ? "failed" : "skipped",
|
|
245
|
+
reason: "provider-rejected",
|
|
246
|
+
...(terminal === "failed" ? { terminalized: true } : {})
|
|
280
247
|
});
|
|
281
248
|
continue;
|
|
282
249
|
}
|
|
283
|
-
if (
|
|
284
|
-
// The Agent Host submitted the exact first Turn through structured
|
|
285
|
-
// Provider control. Persist the transport fence without a second write;
|
|
286
|
-
// the matching structured acknowledgement owns Run acceptance.
|
|
250
|
+
if (outcome === "delivery-unknown") {
|
|
287
251
|
store.saveRoleRunDelivery({
|
|
288
252
|
task,
|
|
289
253
|
role,
|
|
@@ -302,10 +266,34 @@ export async function processLeaderWakeups(store, delivery, now, selection) {
|
|
|
302
266
|
? {}
|
|
303
267
|
: { launchId: ready.prepared.launchId })
|
|
304
268
|
});
|
|
305
|
-
results.push({
|
|
269
|
+
results.push({
|
|
270
|
+
taskId: task.id,
|
|
271
|
+
runId: run.id,
|
|
272
|
+
status: "skipped",
|
|
273
|
+
reason: "delivery-uncertain"
|
|
274
|
+
});
|
|
306
275
|
continue;
|
|
307
276
|
}
|
|
308
|
-
|
|
277
|
+
store.saveRoleRunDelivery({
|
|
278
|
+
task,
|
|
279
|
+
role,
|
|
280
|
+
run,
|
|
281
|
+
session: effectiveSession,
|
|
282
|
+
...(ready.prepared.launchId === undefined
|
|
283
|
+
? {}
|
|
284
|
+
: { launchId: ready.prepared.launchId }),
|
|
285
|
+
now
|
|
286
|
+
});
|
|
287
|
+
delivery.forgetPrepared?.({
|
|
288
|
+
taskId: task.id,
|
|
289
|
+
roleName: role.name,
|
|
290
|
+
runId: run.id,
|
|
291
|
+
...(ready.prepared.launchId === undefined
|
|
292
|
+
? {}
|
|
293
|
+
: { launchId: ready.prepared.launchId })
|
|
294
|
+
});
|
|
295
|
+
results.push({ taskId: task.id, runId: run.id, status: "dispatched" });
|
|
296
|
+
continue;
|
|
309
297
|
}
|
|
310
298
|
catch (error) {
|
|
311
299
|
const detail = error instanceof Error ? error.message : String(error);
|
|
@@ -331,6 +319,57 @@ export async function processLeaderWakeups(store, delivery, now, selection) {
|
|
|
331
319
|
});
|
|
332
320
|
continue;
|
|
333
321
|
}
|
|
322
|
+
store.recordAgentError?.({
|
|
323
|
+
taskId: task.id,
|
|
324
|
+
roleName: role.name,
|
|
325
|
+
runId: run.id,
|
|
326
|
+
source: error instanceof RuntimeLaunchError ? "host" : "yui",
|
|
327
|
+
phase: deliveryAttempted
|
|
328
|
+
? "turn-submit"
|
|
329
|
+
: mode === "new" ? "session-start" : "session-restore",
|
|
330
|
+
message: detail,
|
|
331
|
+
raw: serializeAgentErrorRaw(error),
|
|
332
|
+
inputDisposition: deliveryAttempted ? "unknown" : "not-accepted"
|
|
333
|
+
}, now);
|
|
334
|
+
if (!deliveryAttempted) {
|
|
335
|
+
const failedSession = store.getRoleSession(task.id, role.name, run.effective.agentId);
|
|
336
|
+
const terminal = store.saveRoleRunDeliveryFailure({
|
|
337
|
+
taskId: task.id,
|
|
338
|
+
roleName: role.name,
|
|
339
|
+
agentId: run.effective.agentId,
|
|
340
|
+
adapterId: run.effective.adapterId,
|
|
341
|
+
runId: run.id,
|
|
342
|
+
mailboxBatchId: formatAgentRunReceiptId(task.id, run.id),
|
|
343
|
+
...(failedSession?.nativeSessionId === undefined
|
|
344
|
+
? {}
|
|
345
|
+
: { nativeSessionId: failedSession.nativeSessionId }),
|
|
346
|
+
...(prepared?.launchId === undefined && failedSession?.launchId === undefined
|
|
347
|
+
? {}
|
|
348
|
+
: { launchId: prepared?.launchId ?? failedSession.launchId }),
|
|
349
|
+
summary: `Leader Session preparation failed before Turn acceptance: ${message}`,
|
|
350
|
+
cleanupRequired: false,
|
|
351
|
+
now
|
|
352
|
+
});
|
|
353
|
+
if (terminal === "failed") {
|
|
354
|
+
delivery.forgetPrepared?.({
|
|
355
|
+
taskId: task.id,
|
|
356
|
+
roleName: role.name,
|
|
357
|
+
runId: run.id,
|
|
358
|
+
...(prepared?.launchId === undefined
|
|
359
|
+
? {}
|
|
360
|
+
: { launchId: prepared.launchId })
|
|
361
|
+
});
|
|
362
|
+
results.push({
|
|
363
|
+
taskId: task.id,
|
|
364
|
+
runId: run.id,
|
|
365
|
+
status: "failed",
|
|
366
|
+
reason: "unavailable",
|
|
367
|
+
error: message,
|
|
368
|
+
terminalized: true
|
|
369
|
+
});
|
|
370
|
+
continue;
|
|
371
|
+
}
|
|
372
|
+
}
|
|
334
373
|
// A managed Provider lifecycle operation may still be settling. Keep
|
|
335
374
|
// this newly-claimed Run as the sole mailbox owner; active-Run delivery
|
|
336
375
|
// retries after the lifecycle lane clears.
|
|
@@ -367,20 +406,13 @@ export async function processLeaderWakeups(store, delivery, now, selection) {
|
|
|
367
406
|
? {}
|
|
368
407
|
: { launchId: prepared.launchId })
|
|
369
408
|
});
|
|
370
|
-
|
|
371
|
-
task,
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
now
|
|
409
|
+
results.push({
|
|
410
|
+
taskId: task.id,
|
|
411
|
+
runId: run.id,
|
|
412
|
+
status: "skipped",
|
|
413
|
+
reason: "not-ready",
|
|
414
|
+
error: message
|
|
377
415
|
});
|
|
378
|
-
if (failureResult === "state-changed") {
|
|
379
|
-
results.push({ taskId: task.id, status: "skipped", reason: "state-changed" });
|
|
380
|
-
}
|
|
381
|
-
else {
|
|
382
|
-
results.push({ taskId: task.id, runId: run.id, status: "failed", error: message });
|
|
383
|
-
}
|
|
384
416
|
continue;
|
|
385
417
|
}
|
|
386
418
|
results.push({
|
|
@@ -394,6 +426,14 @@ export async function processLeaderWakeups(store, delivery, now, selection) {
|
|
|
394
426
|
}
|
|
395
427
|
return results;
|
|
396
428
|
}
|
|
429
|
+
function providerTurnIsUnsettled(store, taskId, roleName) {
|
|
430
|
+
if (store.getRoleSession(taskId, roleName)?.status !== "active")
|
|
431
|
+
return false;
|
|
432
|
+
const status = store.getTaskRoleSessionSet?.(taskId, roleName)
|
|
433
|
+
?.providerBinding?.turn?.status;
|
|
434
|
+
return status !== undefined
|
|
435
|
+
&& ["submitting", "accepted", "running", "delivery-unknown"].includes(status);
|
|
436
|
+
}
|
|
397
437
|
function validateReadySession(role, effective, existing, mode, session) {
|
|
398
438
|
if (mode === "new" && session === null)
|
|
399
439
|
return null;
|
|
@@ -416,7 +456,7 @@ function validateReadySession(role, effective, existing, mode, session) {
|
|
|
416
456
|
}
|
|
417
457
|
return {
|
|
418
458
|
...session,
|
|
419
|
-
status: "
|
|
459
|
+
status: "active",
|
|
420
460
|
...(mode === "resume" && existing !== null
|
|
421
461
|
? { effective: existing.effective }
|
|
422
462
|
: {})
|
|
@@ -449,7 +489,7 @@ function preflightSession(role, effective, existing, mode, preflight) {
|
|
|
449
489
|
nativeSessionId: preflight.nativeSessionId,
|
|
450
490
|
launchId: preflight.launchId,
|
|
451
491
|
...(preflight.sessionTitle === undefined ? {} : { title: preflight.sessionTitle }),
|
|
452
|
-
status: "
|
|
492
|
+
status: "active",
|
|
453
493
|
effective: preflight.effective
|
|
454
494
|
};
|
|
455
495
|
return validateReadySession(role, effective, existing, mode, session);
|
|
@@ -125,7 +125,10 @@ export async function reconcileExitedRoleRuns(store, delivery, now, selection, e
|
|
|
125
125
|
...(run.workspace === undefined ? {} : { managedWorkspace: run.workspace }),
|
|
126
126
|
mode: "resume",
|
|
127
127
|
runId: run.id,
|
|
128
|
-
nativeSessionId: session.nativeSessionId
|
|
128
|
+
nativeSessionId: session.nativeSessionId,
|
|
129
|
+
...(session.launchId === undefined
|
|
130
|
+
? {}
|
|
131
|
+
: { hostActivationId: session.launchId })
|
|
129
132
|
});
|
|
130
133
|
store.saveRoleRunPrepared({
|
|
131
134
|
task,
|
|
@@ -56,16 +56,12 @@ export function projectRoleRunHealth(input) {
|
|
|
56
56
|
const session = input.nativeSession;
|
|
57
57
|
const nativeSession = session === null || session === undefined
|
|
58
58
|
? "missing"
|
|
59
|
-
: session.status === "
|
|
60
|
-
? "stopped"
|
|
61
|
-
: session.
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
: !hasResourceIdentityText(session.nativeSessionId)
|
|
66
|
-
&& !hasResourceIdentityText(session.launchId)
|
|
67
|
-
? "unknown"
|
|
68
|
-
: "matching";
|
|
59
|
+
: session.status === "ended"
|
|
60
|
+
? session.endReason === "failed" ? "broken" : "stopped"
|
|
61
|
+
: !hasResourceIdentityText(session.nativeSessionId)
|
|
62
|
+
&& !hasResourceIdentityText(session.launchId)
|
|
63
|
+
? "unknown"
|
|
64
|
+
: "matching";
|
|
69
65
|
const resourceActivity = hostLiveness === "present"
|
|
70
66
|
&& nativeSession === "matching"
|
|
71
67
|
&& resourceEvidenceIsFresh(input.resource, input.now, windowMs, diagnosticAfterMs)
|
|
@@ -689,7 +685,7 @@ export async function reconcileStalledRoleRuns(store, delivery, now, selection,
|
|
|
689
685
|
|| (candidate.session.agentId === runAgentId
|
|
690
686
|
&& candidate.session.adapterId === runAdapterId);
|
|
691
687
|
const sessionUsable = candidate.session === null
|
|
692
|
-
||
|
|
688
|
+
|| candidate.session.status === "active";
|
|
693
689
|
const expectedResourceIdentity = candidate.session === null
|
|
694
690
|
? undefined
|
|
695
691
|
: {
|
|
@@ -17,8 +17,12 @@ export const WAKE_REASON_KINDS = Object.freeze([
|
|
|
17
17
|
"task-orphaned",
|
|
18
18
|
"input-timeout",
|
|
19
19
|
"role-run-stalled",
|
|
20
|
+
"agent-error",
|
|
21
|
+
"agent-session-recovery",
|
|
20
22
|
"review-failed",
|
|
21
23
|
"task-reopened",
|
|
24
|
+
"agent-error",
|
|
25
|
+
"agent-session-recovery",
|
|
22
26
|
"leader-run-failed",
|
|
23
27
|
"role-run-failed",
|
|
24
28
|
"job-finished",
|