lody 0.92.0 → 0.92.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.
|
@@ -80,7 +80,7 @@ let __tla = Promise.all([
|
|
|
80
80
|
}
|
|
81
81
|
})()
|
|
82
82
|
]).then(async () => {
|
|
83
|
-
const reviewViewerVersion = "0.92.
|
|
83
|
+
const reviewViewerVersion = "0.92.1";
|
|
84
84
|
const reviewViewerSha256 = "dc9c7fc1dde49bb39c5fe86392d69219b469c0cab4fd492d8b562045e7f676e4";
|
|
85
85
|
const reviewViewerFileName = "standalone.html";
|
|
86
86
|
const DEFAULT_CDN_BASES = [
|
package/dist/index.js
CHANGED
|
@@ -4325,7 +4325,7 @@ Upgrade Node, then re-run: npx lody@latest`;
|
|
|
4325
4325
|
}
|
|
4326
4326
|
const name$2 = "lody";
|
|
4327
4327
|
const name$1 = "@lody/cli-cloud";
|
|
4328
|
-
const version$9 = "0.92.
|
|
4328
|
+
const version$9 = "0.92.1";
|
|
4329
4329
|
const type$2 = "module";
|
|
4330
4330
|
const scripts = {
|
|
4331
4331
|
"dev": "node dev.mjs",
|
|
@@ -14381,9 +14381,16 @@ Requirements:
|
|
|
14381
14381
|
progressMessageId: string$1().trim().min(1).optional(),
|
|
14382
14382
|
completion: unknown(),
|
|
14383
14383
|
continuation: object$1({
|
|
14384
|
-
status:
|
|
14384
|
+
status: _enum$1([
|
|
14385
|
+
"not_started",
|
|
14386
|
+
"uncertain"
|
|
14387
|
+
]),
|
|
14385
14388
|
reason: object$1({
|
|
14386
|
-
code:
|
|
14389
|
+
code: _enum$1([
|
|
14390
|
+
"CONFIGURATION_UNAVAILABLE",
|
|
14391
|
+
"DELIVERY_ATTEMPTS_EXHAUSTED",
|
|
14392
|
+
"DELIVERY_EXECUTION_UNCERTAIN"
|
|
14393
|
+
]),
|
|
14387
14394
|
message: string$1()
|
|
14388
14395
|
}).strict()
|
|
14389
14396
|
}).strict().optional()
|
|
@@ -105122,6 +105129,7 @@ ${value}`;
|
|
|
105122
105129
|
this.mirror = new Mirror({
|
|
105123
105130
|
doc: handle.doc,
|
|
105124
105131
|
schema: sessionDocSchema,
|
|
105132
|
+
validateUpdates: false,
|
|
105125
105133
|
ignoreUnknownProperties: true,
|
|
105126
105134
|
initialState: merged
|
|
105127
105135
|
});
|
|
@@ -135090,12 +135098,22 @@ The postId is ${normalizedFeedbackPostId}. Use the feedback-progress-reporter sk
|
|
|
135090
135098
|
}
|
|
135091
135099
|
class SessionTurnHalted extends TaggedError("SessionTurnHalted") {
|
|
135092
135100
|
}
|
|
135101
|
+
class SessionTurnClaimContended extends TaggedError("SessionTurnClaimContended") {
|
|
135102
|
+
}
|
|
135103
|
+
class SessionTurnStartFenceFailed extends TaggedError("SessionTurnStartFenceFailed") {
|
|
135104
|
+
}
|
|
135093
135105
|
const isSessionTurnCancelled = (error2) => {
|
|
135094
135106
|
return typeof error2 === "object" && error2 !== null && "_tag" in error2 && error2._tag === "SessionTurnCancelled";
|
|
135095
135107
|
};
|
|
135096
135108
|
const isSessionTurnHalted = (error2) => {
|
|
135097
135109
|
return typeof error2 === "object" && error2 !== null && "_tag" in error2 && error2._tag === "SessionTurnHalted";
|
|
135098
135110
|
};
|
|
135111
|
+
const isSessionTurnClaimContended = (error2) => {
|
|
135112
|
+
return typeof error2 === "object" && error2 !== null && "_tag" in error2 && error2._tag === "SessionTurnClaimContended";
|
|
135113
|
+
};
|
|
135114
|
+
const isSessionTurnStartFenceFailed = (error2) => {
|
|
135115
|
+
return typeof error2 === "object" && error2 !== null && "_tag" in error2 && error2._tag === "SessionTurnStartFenceFailed";
|
|
135116
|
+
};
|
|
135099
135117
|
function truncateAnalyticsString$1(value, maxLength = 1e3) {
|
|
135100
135118
|
return value.length > maxLength ? `${value.slice(0, maxLength)}...` : value;
|
|
135101
135119
|
}
|
|
@@ -135636,6 +135654,9 @@ The postId is ${normalizedFeedbackPostId}. Use the feedback-progress-reporter sk
|
|
|
135636
135654
|
requesterUserId: options.userId,
|
|
135637
135655
|
inputConfig: options.inputConfig
|
|
135638
135656
|
};
|
|
135657
|
+
await this.settleVisibleTurn(runtime, "handled", {
|
|
135658
|
+
force: true
|
|
135659
|
+
});
|
|
135639
135660
|
try {
|
|
135640
135661
|
await this.finalizeYieldedTurnOutput(runtime, options.sessionId, previousTurnId);
|
|
135641
135662
|
} catch (error2) {
|
|
@@ -135827,9 +135848,27 @@ The postId is ${normalizedFeedbackPostId}. Use the feedback-progress-reporter sk
|
|
|
135827
135848
|
cancelFinalized: false,
|
|
135828
135849
|
interruptRequested: false,
|
|
135829
135850
|
terminateSessionOnCancel: false,
|
|
135851
|
+
...options.onTurnSettled ? {
|
|
135852
|
+
settlement: {
|
|
135853
|
+
callback: options.onTurnSettled,
|
|
135854
|
+
completed: false
|
|
135855
|
+
}
|
|
135856
|
+
} : {},
|
|
135830
135857
|
yieldedFinalization: Promise.resolve()
|
|
135831
135858
|
};
|
|
135832
135859
|
}
|
|
135860
|
+
async settleVisibleTurn(runtime, outcome, options = {}) {
|
|
135861
|
+
const settlement = runtime.settlement;
|
|
135862
|
+
if (!settlement || settlement.completed) return;
|
|
135863
|
+
if (options.force) settlement.forcedOutcome = outcome;
|
|
135864
|
+
const effectiveOutcome = settlement.forcedOutcome ?? outcome;
|
|
135865
|
+
try {
|
|
135866
|
+
await settlement.callback(effectiveOutcome);
|
|
135867
|
+
settlement.completed = true;
|
|
135868
|
+
} catch (error2) {
|
|
135869
|
+
this.deps.logger.error(`[${runtime.sessionId}] Failed to persist ${effectiveOutcome} turn settlement: ${formatErrorMessage(error2)}`);
|
|
135870
|
+
}
|
|
135871
|
+
}
|
|
135833
135872
|
getTurnRuntime(sessionId, turnId) {
|
|
135834
135873
|
const runtime = this.turnRuntimeBySession.get(sessionId);
|
|
135835
135874
|
return runtime?.turnId === turnId ? runtime : void 0;
|
|
@@ -136351,6 +136390,7 @@ The postId is ${normalizedFeedbackPostId}. Use the feedback-progress-reporter sk
|
|
|
136351
136390
|
}
|
|
136352
136391
|
async runVisibleSessionTurn(options, body2) {
|
|
136353
136392
|
const { sessionId, sessionDoc, userTurnId } = options;
|
|
136393
|
+
const assistantEntryParentTurnId = options.assistantEntryParentTurnId ?? userTurnId;
|
|
136354
136394
|
const span2 = startTraceSpan(this.deps.logger, "execution.visible_turn", {
|
|
136355
136395
|
sessionId,
|
|
136356
136396
|
...userTurnId ? {
|
|
@@ -136383,7 +136423,7 @@ The postId is ${normalizedFeedbackPostId}. Use the feedback-progress-reporter sk
|
|
|
136383
136423
|
let turnId;
|
|
136384
136424
|
let runtime;
|
|
136385
136425
|
try {
|
|
136386
|
-
turnId = this.deps.beginConversationTurn(sessionId,
|
|
136426
|
+
turnId = this.deps.beginConversationTurn(sessionId, assistantEntryParentTurnId, {
|
|
136387
136427
|
...options.dispatchSource ? {
|
|
136388
136428
|
dispatchSource: options.dispatchSource
|
|
136389
136429
|
} : {},
|
|
@@ -136484,7 +136524,7 @@ The postId is ${normalizedFeedbackPostId}. Use the feedback-progress-reporter sk
|
|
|
136484
136524
|
userTurnId
|
|
136485
136525
|
} : {},
|
|
136486
136526
|
alreadyOpened: wasOpened
|
|
136487
|
-
}, async () => await self2.deps.createAssistantEntryForTurn(sessionId, sessionDoc, runtime.turnId, runtime.session?.agentClient?.currentModel,
|
|
136527
|
+
}, async () => await self2.deps.createAssistantEntryForTurn(sessionId, sessionDoc, runtime.turnId, runtime.session?.agentClient?.currentModel, assistantEntryParentTurnId)));
|
|
136488
136528
|
if (wasOpened) {
|
|
136489
136529
|
return void 0;
|
|
136490
136530
|
}
|
|
@@ -136523,6 +136563,20 @@ The postId is ${normalizedFeedbackPostId}. Use the feedback-progress-reporter sk
|
|
|
136523
136563
|
yield* fail(new Error("Agent session was not ready"));
|
|
136524
136564
|
return void 0;
|
|
136525
136565
|
}
|
|
136566
|
+
if (!runtime.promptStarted && options.onTurnStarted) {
|
|
136567
|
+
const started = yield* self2.tryPromise(options.onTurnStarted).pipe(mapError$1((cause) => new SessionTurnStartFenceFailed({
|
|
136568
|
+
sessionId,
|
|
136569
|
+
turnId: runtime.turnId,
|
|
136570
|
+
cause
|
|
136571
|
+
})), tapError(() => self2.ignoreWithWarning(sessionId, "Failed to finalize a rejected Delivery start fence", self2.tryPromise(() => self2.handleTurnError(sessionId, sessionDoc)))));
|
|
136572
|
+
if (!started) {
|
|
136573
|
+
yield* fail(new SessionTurnClaimContended({
|
|
136574
|
+
sessionId,
|
|
136575
|
+
turnId: runtime.turnId
|
|
136576
|
+
}));
|
|
136577
|
+
return void 0;
|
|
136578
|
+
}
|
|
136579
|
+
}
|
|
136526
136580
|
runtime.terminateSessionOnCancel = false;
|
|
136527
136581
|
self2.deps.activateConversationTurnForACPUpdates(sessionId, runtime.turnId);
|
|
136528
136582
|
runtime.promptStarted = true;
|
|
@@ -136564,13 +136618,21 @@ The postId is ${normalizedFeedbackPostId}. Use the feedback-progress-reporter sk
|
|
|
136564
136618
|
}))));
|
|
136565
136619
|
const fiber = runFork(program2);
|
|
136566
136620
|
runtime.fiber = fiber;
|
|
136621
|
+
let settlement;
|
|
136567
136622
|
try {
|
|
136568
136623
|
await this.awaitTurnFiber(fiber, sessionId, turnId);
|
|
136569
136624
|
if (outcome === "unknown") {
|
|
136570
136625
|
outcome = "completed";
|
|
136571
136626
|
}
|
|
136627
|
+
settlement = "handled";
|
|
136572
136628
|
} catch (error2) {
|
|
136573
|
-
if (
|
|
136629
|
+
if (isSessionTurnClaimContended(error2)) {
|
|
136630
|
+
outcome = "claim-contended";
|
|
136631
|
+
} else if (isSessionTurnStartFenceFailed(error2)) {
|
|
136632
|
+
outcome = "start-fence-failed";
|
|
136633
|
+
this.deps.logger.warn(`[${sessionId}] Delivery start fence failed before provider execution: ${formatErrorMessage(error2.cause)}`);
|
|
136634
|
+
settlement = "not_started";
|
|
136635
|
+
} else if (isSessionTurnHalted(error2)) {
|
|
136574
136636
|
outcome = `halted-${error2.reason}`;
|
|
136575
136637
|
await this.finalizeHaltedTurn({
|
|
136576
136638
|
sessionId,
|
|
@@ -136578,23 +136640,25 @@ The postId is ${normalizedFeedbackPostId}. Use the feedback-progress-reporter sk
|
|
|
136578
136640
|
turnId: runtime.turnId,
|
|
136579
136641
|
reason: error2.reason
|
|
136580
136642
|
});
|
|
136581
|
-
|
|
136582
|
-
}
|
|
136583
|
-
if (isSessionTurnCancelled(error2) || runtime.cancelFinalized || runtime.cancelRequested || this.isTurnCancelled(sessionId, runtime.turnId) || await this.isUserTurnCancelled(sessionDoc, runtime.userTurnId)) {
|
|
136643
|
+
settlement = "handled";
|
|
136644
|
+
} else if (isSessionTurnCancelled(error2) || runtime.cancelFinalized || runtime.cancelRequested || this.isTurnCancelled(sessionId, runtime.turnId) || await this.isUserTurnCancelled(sessionDoc, runtime.userTurnId)) {
|
|
136584
136645
|
outcome = "cancelled";
|
|
136585
|
-
|
|
136646
|
+
const explicitlyCancelled = runtime.cancelRequested || this.isTurnCancelled(sessionId, runtime.turnId) || await this.isUserTurnCancelled(sessionDoc, runtime.userTurnId);
|
|
136647
|
+
settlement = explicitlyCancelled ? "cancelled" : runtime.promptStarted ? "uncertain" : "not_started";
|
|
136648
|
+
} else {
|
|
136649
|
+
await this.handleVisibleTurnUnhandledError({
|
|
136650
|
+
sessionId,
|
|
136651
|
+
sessionDoc,
|
|
136652
|
+
userTurnId: runtime.userTurnId,
|
|
136653
|
+
runtime,
|
|
136654
|
+
error: error2,
|
|
136655
|
+
code: effectiveErrorContext.code,
|
|
136656
|
+
describe: effectiveErrorContext.describe,
|
|
136657
|
+
onUnhandledError: effectiveErrorContext.onUnhandledError
|
|
136658
|
+
});
|
|
136659
|
+
outcome = "unhandled-error-recorded";
|
|
136660
|
+
settlement = "handled";
|
|
136586
136661
|
}
|
|
136587
|
-
await this.handleVisibleTurnUnhandledError({
|
|
136588
|
-
sessionId,
|
|
136589
|
-
sessionDoc,
|
|
136590
|
-
userTurnId: runtime.userTurnId,
|
|
136591
|
-
runtime,
|
|
136592
|
-
error: error2,
|
|
136593
|
-
code: effectiveErrorContext.code,
|
|
136594
|
-
describe: effectiveErrorContext.describe,
|
|
136595
|
-
onUnhandledError: effectiveErrorContext.onUnhandledError
|
|
136596
|
-
});
|
|
136597
|
-
outcome = "unhandled-error-recorded";
|
|
136598
136662
|
} finally {
|
|
136599
136663
|
if (!runtime.promptStarted) {
|
|
136600
136664
|
this.deps.clearConversationTurn(sessionId, runtime.turnId);
|
|
@@ -136604,6 +136668,9 @@ The postId is ${normalizedFeedbackPostId}. Use the feedback-progress-reporter sk
|
|
|
136604
136668
|
turnId
|
|
136605
136669
|
});
|
|
136606
136670
|
}
|
|
136671
|
+
if (settlement) {
|
|
136672
|
+
await this.settleVisibleTurn(runtime, settlement);
|
|
136673
|
+
}
|
|
136607
136674
|
return outcome;
|
|
136608
136675
|
}
|
|
136609
136676
|
markCurrentTurn(sessionId, turnId) {
|
|
@@ -136866,7 +136933,10 @@ The postId is ${normalizedFeedbackPostId}. Use the feedback-progress-reporter sk
|
|
|
136866
136933
|
})) {
|
|
136867
136934
|
return;
|
|
136868
136935
|
}
|
|
136869
|
-
const body2 = dispatchOptions?.onTurnClaimed ? (ctx) => promise$1(dispatchOptions.onTurnClaimed).pipe(flatMap$2(() => turn.body(ctx)
|
|
136936
|
+
const body2 = dispatchOptions?.onTurnClaimed ? (ctx) => promise$1(dispatchOptions.onTurnClaimed).pipe(flatMap$2((claimed) => claimed ? turn.body(ctx) : fail(new SessionTurnClaimContended({
|
|
136937
|
+
sessionId: message.sessionId,
|
|
136938
|
+
turnId: ctx.turnId
|
|
136939
|
+
})))) : turn.body;
|
|
136870
136940
|
await this.runVisibleSessionTurn(turn.options, body2);
|
|
136871
136941
|
}
|
|
136872
136942
|
async prepareContinueSessionTurn(message, dispatchOptions, prepareOptions) {
|
|
@@ -137330,6 +137400,15 @@ The postId is ${normalizedFeedbackPostId}. Use the feedback-progress-reporter sk
|
|
|
137330
137400
|
requesterUserId: userId,
|
|
137331
137401
|
inputConfig: acpSessionConfig
|
|
137332
137402
|
},
|
|
137403
|
+
...dispatchOptions?.dispatchSource === "delivery" ? {
|
|
137404
|
+
assistantEntryParentTurnId: userTurnId
|
|
137405
|
+
} : {},
|
|
137406
|
+
...dispatchOptions?.onTurnStarted ? {
|
|
137407
|
+
onTurnStarted: dispatchOptions.onTurnStarted
|
|
137408
|
+
} : {},
|
|
137409
|
+
...dispatchOptions?.onTurnSettled ? {
|
|
137410
|
+
onTurnSettled: dispatchOptions.onTurnSettled
|
|
137411
|
+
} : {},
|
|
137333
137412
|
...dispatchOptions?.dispatchSource ? {
|
|
137334
137413
|
dispatchSource: dispatchOptions.dispatchSource
|
|
137335
137414
|
} : {},
|
|
@@ -141616,6 +141695,7 @@ The postId is ${normalizedFeedbackPostId}. Use the feedback-progress-reporter sk
|
|
|
141616
141695
|
const DAY_MS = 24 * 60 * 60 * 1e3;
|
|
141617
141696
|
const TERMINAL_RETENTION_MS = 7 * DAY_MS;
|
|
141618
141697
|
const MATERIALIZATION_CLAIM_MS = 6e4;
|
|
141698
|
+
const DELIVERY_MAX_ATTEMPTS = 2;
|
|
141619
141699
|
const OperationKindSchema = _enum$1([
|
|
141620
141700
|
"session_create",
|
|
141621
141701
|
"session_create_many",
|
|
@@ -141732,6 +141812,33 @@ The postId is ${normalizedFeedbackPostId}. Use the feedback-progress-reporter sk
|
|
|
141732
141812
|
completion_json: string$1(),
|
|
141733
141813
|
consumed_at: string$1().nullable()
|
|
141734
141814
|
}).strict();
|
|
141815
|
+
const DeliveryReadRowSchema = DeliveryRowSchema.extend({
|
|
141816
|
+
execution_phase: _enum$1([
|
|
141817
|
+
"ready",
|
|
141818
|
+
"claimed",
|
|
141819
|
+
"prepared",
|
|
141820
|
+
"started",
|
|
141821
|
+
"uncertain"
|
|
141822
|
+
]),
|
|
141823
|
+
attempt_count: number$4().int().nonnegative(),
|
|
141824
|
+
active_claim_id: string$1().nullable(),
|
|
141825
|
+
active_claim_worker_boot_id: string$1().nullable()
|
|
141826
|
+
}).strict();
|
|
141827
|
+
const DELIVERY_READ_COLUMNS = `
|
|
141828
|
+
deliveries.sequence,
|
|
141829
|
+
deliveries.workspace_id,
|
|
141830
|
+
deliveries.requester_session_id,
|
|
141831
|
+
deliveries.operation_id,
|
|
141832
|
+
deliveries.delivery_id,
|
|
141833
|
+
deliveries.system_turn_id,
|
|
141834
|
+
deliveries.state,
|
|
141835
|
+
deliveries.initiator_chain_depth,
|
|
141836
|
+
deliveries.completion_json,
|
|
141837
|
+
deliveries.consumed_at,
|
|
141838
|
+
delivery_execution_state.execution_phase,
|
|
141839
|
+
delivery_execution_state.attempt_count,
|
|
141840
|
+
delivery_execution_state.active_claim_id,
|
|
141841
|
+
delivery_execution_state.active_claim_worker_boot_id`;
|
|
141735
141842
|
class LodyOperationStoreError extends Error {
|
|
141736
141843
|
constructor(code2, message, retryable) {
|
|
141737
141844
|
super(message);
|
|
@@ -142134,16 +142241,320 @@ The postId is ${normalizedFeedbackPostId}. Use the feedback-progress-reporter sk
|
|
|
142134
142241
|
return transaction.immediate();
|
|
142135
142242
|
}
|
|
142136
142243
|
listPendingDeliveries(workspaceId, requesterSessionId) {
|
|
142137
|
-
const rows = requesterSessionId ? this.db.prepare(`SELECT
|
|
142138
|
-
|
|
142139
|
-
|
|
142140
|
-
WHERE workspace_id = ?
|
|
142141
|
-
|
|
142244
|
+
const rows = requesterSessionId ? this.db.prepare(`SELECT ${DELIVERY_READ_COLUMNS}
|
|
142245
|
+
FROM deliveries
|
|
142246
|
+
JOIN delivery_execution_state USING (requester_session_id, operation_id)
|
|
142247
|
+
WHERE deliveries.workspace_id = ?
|
|
142248
|
+
AND deliveries.requester_session_id = ?
|
|
142249
|
+
AND deliveries.state = 'pending'
|
|
142250
|
+
ORDER BY deliveries.sequence ASC`).all(workspaceId, requesterSessionId) : this.db.prepare(`SELECT ${DELIVERY_READ_COLUMNS}
|
|
142251
|
+
FROM deliveries
|
|
142252
|
+
JOIN delivery_execution_state USING (requester_session_id, operation_id)
|
|
142253
|
+
WHERE deliveries.workspace_id = ? AND deliveries.state = 'pending'
|
|
142254
|
+
ORDER BY deliveries.sequence ASC`).all(workspaceId);
|
|
142142
142255
|
return rows.map((row) => this.decodeDelivery(row));
|
|
142143
142256
|
}
|
|
142144
|
-
|
|
142145
|
-
this.db.prepare(`
|
|
142146
|
-
|
|
142257
|
+
getDelivery(requesterSessionId, operationId) {
|
|
142258
|
+
const row = this.db.prepare(`SELECT ${DELIVERY_READ_COLUMNS}
|
|
142259
|
+
FROM deliveries
|
|
142260
|
+
JOIN delivery_execution_state USING (requester_session_id, operation_id)
|
|
142261
|
+
WHERE deliveries.requester_session_id = ? AND deliveries.operation_id = ?`).get(requesterSessionId, operationId);
|
|
142262
|
+
if (row === void 0) {
|
|
142263
|
+
throw new LodyOperationStoreError("DELIVERY_NOT_FOUND", `Delivery not found for Operation: ${operationId}`, false);
|
|
142264
|
+
}
|
|
142265
|
+
return this.decodeDelivery(row);
|
|
142266
|
+
}
|
|
142267
|
+
recoverOrphanedDeliveryClaims(workspaceId, workerBootId) {
|
|
142268
|
+
const result = this.db.prepare(`UPDATE delivery_execution_state
|
|
142269
|
+
SET execution_phase = CASE
|
|
142270
|
+
WHEN execution_phase = 'started' THEN 'uncertain'
|
|
142271
|
+
WHEN execution_phase IN ('claimed', 'prepared') THEN 'ready'
|
|
142272
|
+
ELSE execution_phase
|
|
142273
|
+
END,
|
|
142274
|
+
active_claim_id = NULL,
|
|
142275
|
+
active_claim_worker_boot_id = NULL
|
|
142276
|
+
WHERE (active_claim_id IS NOT NULL OR active_claim_worker_boot_id IS NOT NULL)
|
|
142277
|
+
AND (
|
|
142278
|
+
active_claim_id IS NULL
|
|
142279
|
+
OR active_claim_worker_boot_id IS NULL
|
|
142280
|
+
OR active_claim_worker_boot_id <> ?
|
|
142281
|
+
)
|
|
142282
|
+
AND EXISTS (
|
|
142283
|
+
SELECT 1 FROM deliveries
|
|
142284
|
+
WHERE deliveries.requester_session_id = delivery_execution_state.requester_session_id
|
|
142285
|
+
AND deliveries.operation_id = delivery_execution_state.operation_id
|
|
142286
|
+
AND deliveries.workspace_id = ? AND deliveries.state = 'pending'
|
|
142287
|
+
)`).run(workerBootId, workspaceId);
|
|
142288
|
+
return result.changes;
|
|
142289
|
+
}
|
|
142290
|
+
abandonDeliveryClaimsOwnedBy(workspaceId, workerBootId) {
|
|
142291
|
+
const result = this.db.prepare(`UPDATE delivery_execution_state
|
|
142292
|
+
SET execution_phase = CASE
|
|
142293
|
+
WHEN execution_phase = 'started' THEN 'uncertain'
|
|
142294
|
+
WHEN execution_phase IN ('claimed', 'prepared') THEN 'ready'
|
|
142295
|
+
ELSE execution_phase
|
|
142296
|
+
END,
|
|
142297
|
+
active_claim_id = NULL,
|
|
142298
|
+
active_claim_worker_boot_id = NULL
|
|
142299
|
+
WHERE active_claim_worker_boot_id = ?
|
|
142300
|
+
AND EXISTS (
|
|
142301
|
+
SELECT 1 FROM deliveries
|
|
142302
|
+
WHERE deliveries.requester_session_id = delivery_execution_state.requester_session_id
|
|
142303
|
+
AND deliveries.operation_id = delivery_execution_state.operation_id
|
|
142304
|
+
AND deliveries.workspace_id = ? AND deliveries.state = 'pending'
|
|
142305
|
+
)`).run(workerBootId, workspaceId);
|
|
142306
|
+
return result.changes;
|
|
142307
|
+
}
|
|
142308
|
+
claimDeliveryExecution(requesterSessionId, operationId, claim) {
|
|
142309
|
+
const transaction = this.db.transaction(() => {
|
|
142310
|
+
const current2 = this.getDelivery(requesterSessionId, operationId);
|
|
142311
|
+
if (current2.state === "consumed") return {
|
|
142312
|
+
status: "consumed",
|
|
142313
|
+
delivery: current2
|
|
142314
|
+
};
|
|
142315
|
+
if (current2.activeClaimId === claim.claimId && current2.activeClaimWorkerBootId === claim.workerBootId) {
|
|
142316
|
+
return {
|
|
142317
|
+
status: "claimed",
|
|
142318
|
+
delivery: current2
|
|
142319
|
+
};
|
|
142320
|
+
}
|
|
142321
|
+
if (current2.activeClaimId !== void 0 || current2.activeClaimWorkerBootId !== void 0) {
|
|
142322
|
+
return {
|
|
142323
|
+
status: "in_flight",
|
|
142324
|
+
delivery: current2
|
|
142325
|
+
};
|
|
142326
|
+
}
|
|
142327
|
+
if (current2.executionPhase !== "ready") {
|
|
142328
|
+
return {
|
|
142329
|
+
status: "in_flight",
|
|
142330
|
+
delivery: current2
|
|
142331
|
+
};
|
|
142332
|
+
}
|
|
142333
|
+
if (current2.attemptCount >= DELIVERY_MAX_ATTEMPTS) {
|
|
142334
|
+
return {
|
|
142335
|
+
status: "exhausted",
|
|
142336
|
+
delivery: current2
|
|
142337
|
+
};
|
|
142338
|
+
}
|
|
142339
|
+
const result = this.db.prepare(`UPDATE delivery_execution_state
|
|
142340
|
+
SET execution_phase = 'claimed', active_claim_id = ?, active_claim_worker_boot_id = ?
|
|
142341
|
+
WHERE requester_session_id = ? AND operation_id = ?
|
|
142342
|
+
AND attempt_count < ?
|
|
142343
|
+
AND execution_phase = 'ready'
|
|
142344
|
+
AND active_claim_id IS NULL AND active_claim_worker_boot_id IS NULL
|
|
142345
|
+
AND EXISTS (
|
|
142346
|
+
SELECT 1 FROM deliveries
|
|
142347
|
+
WHERE deliveries.requester_session_id = delivery_execution_state.requester_session_id
|
|
142348
|
+
AND deliveries.operation_id = delivery_execution_state.operation_id
|
|
142349
|
+
AND deliveries.state = 'pending'
|
|
142350
|
+
)`).run(claim.claimId, claim.workerBootId, requesterSessionId, operationId, DELIVERY_MAX_ATTEMPTS);
|
|
142351
|
+
if (result.changes !== 1) {
|
|
142352
|
+
const latest2 = this.getDelivery(requesterSessionId, operationId);
|
|
142353
|
+
if (latest2.state === "consumed") return {
|
|
142354
|
+
status: "consumed",
|
|
142355
|
+
delivery: latest2
|
|
142356
|
+
};
|
|
142357
|
+
if (latest2.activeClaimId !== void 0 || latest2.activeClaimWorkerBootId !== void 0) {
|
|
142358
|
+
return {
|
|
142359
|
+
status: "in_flight",
|
|
142360
|
+
delivery: latest2
|
|
142361
|
+
};
|
|
142362
|
+
}
|
|
142363
|
+
return {
|
|
142364
|
+
status: "exhausted",
|
|
142365
|
+
delivery: latest2
|
|
142366
|
+
};
|
|
142367
|
+
}
|
|
142368
|
+
return {
|
|
142369
|
+
status: "claimed",
|
|
142370
|
+
delivery: this.getDelivery(requesterSessionId, operationId)
|
|
142371
|
+
};
|
|
142372
|
+
});
|
|
142373
|
+
return transaction.immediate();
|
|
142374
|
+
}
|
|
142375
|
+
prepareClaimedDeliveryExecution(requesterSessionId, operationId, workerBootId, claimId) {
|
|
142376
|
+
const transaction = this.db.transaction(() => {
|
|
142377
|
+
const current2 = this.getDelivery(requesterSessionId, operationId);
|
|
142378
|
+
if (current2.activeClaimWorkerBootId === workerBootId && current2.activeClaimId === claimId && (current2.executionPhase === "prepared" || current2.executionPhase === "started")) {
|
|
142379
|
+
return {
|
|
142380
|
+
prepared: true,
|
|
142381
|
+
delivery: current2
|
|
142382
|
+
};
|
|
142383
|
+
}
|
|
142384
|
+
const result = this.db.prepare(`UPDATE delivery_execution_state
|
|
142385
|
+
SET execution_phase = 'prepared', attempt_count = attempt_count + 1
|
|
142386
|
+
WHERE requester_session_id = ? AND operation_id = ?
|
|
142387
|
+
AND attempt_count < ?
|
|
142388
|
+
AND execution_phase = 'claimed'
|
|
142389
|
+
AND active_claim_worker_boot_id = ? AND active_claim_id = ?
|
|
142390
|
+
AND EXISTS (
|
|
142391
|
+
SELECT 1 FROM deliveries
|
|
142392
|
+
WHERE deliveries.requester_session_id = delivery_execution_state.requester_session_id
|
|
142393
|
+
AND deliveries.operation_id = delivery_execution_state.operation_id
|
|
142394
|
+
AND deliveries.state = 'pending'
|
|
142395
|
+
)`).run(requesterSessionId, operationId, DELIVERY_MAX_ATTEMPTS, workerBootId, claimId);
|
|
142396
|
+
return {
|
|
142397
|
+
prepared: result.changes === 1,
|
|
142398
|
+
delivery: this.getDelivery(requesterSessionId, operationId)
|
|
142399
|
+
};
|
|
142400
|
+
});
|
|
142401
|
+
return transaction.immediate();
|
|
142402
|
+
}
|
|
142403
|
+
markClaimedDeliveryExecutionStarted(requesterSessionId, operationId, workerBootId, claimId) {
|
|
142404
|
+
const result = this.db.prepare(`UPDATE delivery_execution_state
|
|
142405
|
+
SET execution_phase = 'started'
|
|
142406
|
+
WHERE requester_session_id = ? AND operation_id = ?
|
|
142407
|
+
AND execution_phase = 'prepared'
|
|
142408
|
+
AND active_claim_worker_boot_id = ? AND active_claim_id = ?
|
|
142409
|
+
AND EXISTS (
|
|
142410
|
+
SELECT 1 FROM deliveries
|
|
142411
|
+
WHERE deliveries.requester_session_id = delivery_execution_state.requester_session_id
|
|
142412
|
+
AND deliveries.operation_id = delivery_execution_state.operation_id
|
|
142413
|
+
AND deliveries.state = 'pending'
|
|
142414
|
+
)`).run(requesterSessionId, operationId, workerBootId, claimId);
|
|
142415
|
+
if (result.changes === 1) return true;
|
|
142416
|
+
const current2 = this.getDelivery(requesterSessionId, operationId);
|
|
142417
|
+
return current2.executionPhase === "started" && current2.activeClaimWorkerBootId === workerBootId && current2.activeClaimId === claimId;
|
|
142418
|
+
}
|
|
142419
|
+
markClaimedDeliveryExecutionUncertain(requesterSessionId, operationId, workerBootId, claimId) {
|
|
142420
|
+
const result = this.db.prepare(`UPDATE delivery_execution_state
|
|
142421
|
+
SET execution_phase = 'uncertain',
|
|
142422
|
+
active_claim_id = NULL,
|
|
142423
|
+
active_claim_worker_boot_id = NULL
|
|
142424
|
+
WHERE requester_session_id = ? AND operation_id = ?
|
|
142425
|
+
AND execution_phase = 'started'
|
|
142426
|
+
AND active_claim_worker_boot_id = ? AND active_claim_id = ?
|
|
142427
|
+
AND EXISTS (
|
|
142428
|
+
SELECT 1 FROM deliveries
|
|
142429
|
+
WHERE deliveries.requester_session_id = delivery_execution_state.requester_session_id
|
|
142430
|
+
AND deliveries.operation_id = delivery_execution_state.operation_id
|
|
142431
|
+
AND deliveries.state = 'pending'
|
|
142432
|
+
)`).run(requesterSessionId, operationId, workerBootId, claimId);
|
|
142433
|
+
return result.changes === 1;
|
|
142434
|
+
}
|
|
142435
|
+
claimDeliveryFinalization(requesterSessionId, operationId, claim) {
|
|
142436
|
+
const transaction = this.db.transaction(() => {
|
|
142437
|
+
const current2 = this.getDelivery(requesterSessionId, operationId);
|
|
142438
|
+
if (current2.state === "consumed") return {
|
|
142439
|
+
status: "consumed",
|
|
142440
|
+
delivery: current2
|
|
142441
|
+
};
|
|
142442
|
+
if (current2.activeClaimId === claim.claimId && current2.activeClaimWorkerBootId === claim.workerBootId) {
|
|
142443
|
+
return {
|
|
142444
|
+
status: "claimed",
|
|
142445
|
+
delivery: current2
|
|
142446
|
+
};
|
|
142447
|
+
}
|
|
142448
|
+
if (current2.activeClaimId !== void 0 || current2.activeClaimWorkerBootId !== void 0) {
|
|
142449
|
+
return {
|
|
142450
|
+
status: "in_flight",
|
|
142451
|
+
delivery: current2
|
|
142452
|
+
};
|
|
142453
|
+
}
|
|
142454
|
+
const minimumAttemptCount = claim.requireAttemptsExhausted ? DELIVERY_MAX_ATTEMPTS : 0;
|
|
142455
|
+
const requiredExecutionPhase = claim.requiredExecutionPhase ?? "ready";
|
|
142456
|
+
if (current2.attemptCount < minimumAttemptCount) {
|
|
142457
|
+
return {
|
|
142458
|
+
status: "not_ready",
|
|
142459
|
+
delivery: current2
|
|
142460
|
+
};
|
|
142461
|
+
}
|
|
142462
|
+
if (current2.executionPhase !== requiredExecutionPhase) {
|
|
142463
|
+
return {
|
|
142464
|
+
status: "not_ready",
|
|
142465
|
+
delivery: current2
|
|
142466
|
+
};
|
|
142467
|
+
}
|
|
142468
|
+
const result = this.db.prepare(`UPDATE delivery_execution_state
|
|
142469
|
+
SET active_claim_id = ?, active_claim_worker_boot_id = ?
|
|
142470
|
+
WHERE requester_session_id = ? AND operation_id = ?
|
|
142471
|
+
AND attempt_count >= ?
|
|
142472
|
+
AND execution_phase = ?
|
|
142473
|
+
AND active_claim_id IS NULL AND active_claim_worker_boot_id IS NULL
|
|
142474
|
+
AND EXISTS (
|
|
142475
|
+
SELECT 1 FROM deliveries
|
|
142476
|
+
WHERE deliveries.requester_session_id = delivery_execution_state.requester_session_id
|
|
142477
|
+
AND deliveries.operation_id = delivery_execution_state.operation_id
|
|
142478
|
+
AND deliveries.state = 'pending'
|
|
142479
|
+
)`).run(claim.claimId, claim.workerBootId, requesterSessionId, operationId, minimumAttemptCount, requiredExecutionPhase);
|
|
142480
|
+
if (result.changes !== 1) {
|
|
142481
|
+
const latest2 = this.getDelivery(requesterSessionId, operationId);
|
|
142482
|
+
if (latest2.state === "consumed") return {
|
|
142483
|
+
status: "consumed",
|
|
142484
|
+
delivery: latest2
|
|
142485
|
+
};
|
|
142486
|
+
if (latest2.activeClaimId !== void 0 || latest2.activeClaimWorkerBootId !== void 0) {
|
|
142487
|
+
return {
|
|
142488
|
+
status: "in_flight",
|
|
142489
|
+
delivery: latest2
|
|
142490
|
+
};
|
|
142491
|
+
}
|
|
142492
|
+
return {
|
|
142493
|
+
status: "not_ready",
|
|
142494
|
+
delivery: latest2
|
|
142495
|
+
};
|
|
142496
|
+
}
|
|
142497
|
+
return {
|
|
142498
|
+
status: "claimed",
|
|
142499
|
+
delivery: this.getDelivery(requesterSessionId, operationId)
|
|
142500
|
+
};
|
|
142501
|
+
});
|
|
142502
|
+
return transaction.immediate();
|
|
142503
|
+
}
|
|
142504
|
+
releaseDeliveryClaim(requesterSessionId, operationId, workerBootId, claimId) {
|
|
142505
|
+
const result = this.db.prepare(`UPDATE delivery_execution_state
|
|
142506
|
+
SET execution_phase = CASE
|
|
142507
|
+
WHEN execution_phase IN ('claimed', 'prepared') THEN 'ready'
|
|
142508
|
+
ELSE execution_phase
|
|
142509
|
+
END,
|
|
142510
|
+
active_claim_id = NULL,
|
|
142511
|
+
active_claim_worker_boot_id = NULL
|
|
142512
|
+
WHERE requester_session_id = ? AND operation_id = ?
|
|
142513
|
+
AND active_claim_worker_boot_id = ? AND active_claim_id = ?
|
|
142514
|
+
AND execution_phase <> 'started'
|
|
142515
|
+
AND EXISTS (
|
|
142516
|
+
SELECT 1 FROM deliveries
|
|
142517
|
+
WHERE deliveries.requester_session_id = delivery_execution_state.requester_session_id
|
|
142518
|
+
AND deliveries.operation_id = delivery_execution_state.operation_id
|
|
142519
|
+
AND deliveries.state = 'pending'
|
|
142520
|
+
)`).run(requesterSessionId, operationId, workerBootId, claimId);
|
|
142521
|
+
return result.changes === 1;
|
|
142522
|
+
}
|
|
142523
|
+
consumeClaimedDelivery(requesterSessionId, operationId, workerBootId, claimId, consumedAt = new Date(this.now()).toISOString()) {
|
|
142524
|
+
const transaction = this.db.transaction(() => {
|
|
142525
|
+
const current2 = this.getDelivery(requesterSessionId, operationId);
|
|
142526
|
+
if (current2.state === "consumed" || current2.activeClaimWorkerBootId !== workerBootId || current2.activeClaimId !== claimId) {
|
|
142527
|
+
return {
|
|
142528
|
+
consumed: false,
|
|
142529
|
+
delivery: current2
|
|
142530
|
+
};
|
|
142531
|
+
}
|
|
142532
|
+
const result = this.db.prepare(`UPDATE deliveries
|
|
142533
|
+
SET state = 'consumed', consumed_at = ?
|
|
142534
|
+
WHERE requester_session_id = ? AND operation_id = ? AND state = 'pending'
|
|
142535
|
+
AND EXISTS (
|
|
142536
|
+
SELECT 1 FROM delivery_execution_state
|
|
142537
|
+
WHERE delivery_execution_state.requester_session_id = deliveries.requester_session_id
|
|
142538
|
+
AND delivery_execution_state.operation_id = deliveries.operation_id
|
|
142539
|
+
AND delivery_execution_state.active_claim_worker_boot_id = ?
|
|
142540
|
+
AND delivery_execution_state.active_claim_id = ?
|
|
142541
|
+
)`).run(consumedAt, requesterSessionId, operationId, workerBootId, claimId);
|
|
142542
|
+
if (result.changes === 1) {
|
|
142543
|
+
const released = this.db.prepare(`UPDATE delivery_execution_state
|
|
142544
|
+
SET active_claim_id = NULL, active_claim_worker_boot_id = NULL
|
|
142545
|
+
WHERE requester_session_id = ? AND operation_id = ?
|
|
142546
|
+
AND active_claim_worker_boot_id = ? AND active_claim_id = ?`).run(requesterSessionId, operationId, workerBootId, claimId);
|
|
142547
|
+
if (released.changes !== 1) {
|
|
142548
|
+
throw new Error("Consumed Delivery lost its active claim during transaction.");
|
|
142549
|
+
}
|
|
142550
|
+
}
|
|
142551
|
+
const latest2 = this.getDelivery(requesterSessionId, operationId);
|
|
142552
|
+
return {
|
|
142553
|
+
consumed: result.changes === 1,
|
|
142554
|
+
delivery: latest2
|
|
142555
|
+
};
|
|
142556
|
+
});
|
|
142557
|
+
return transaction.immediate();
|
|
142147
142558
|
}
|
|
142148
142559
|
deleteRequesterSession(requesterSessionId) {
|
|
142149
142560
|
this.db.prepare("DELETE FROM operations WHERE requester_session_id = ?").run(requesterSessionId);
|
|
@@ -142220,7 +142631,7 @@ The postId is ${normalizedFeedbackPostId}. Use the feedback-progress-reporter sk
|
|
|
142220
142631
|
};
|
|
142221
142632
|
}
|
|
142222
142633
|
decodeDelivery(row) {
|
|
142223
|
-
const parsed =
|
|
142634
|
+
const parsed = DeliveryReadRowSchema.parse(row);
|
|
142224
142635
|
return {
|
|
142225
142636
|
sequence: parsed.sequence,
|
|
142226
142637
|
workspaceId: parsed.workspace_id,
|
|
@@ -142229,6 +142640,14 @@ The postId is ${normalizedFeedbackPostId}. Use the feedback-progress-reporter sk
|
|
|
142229
142640
|
deliveryId: parsed.delivery_id,
|
|
142230
142641
|
systemTurnId: parsed.system_turn_id,
|
|
142231
142642
|
state: parsed.state,
|
|
142643
|
+
executionPhase: parsed.execution_phase,
|
|
142644
|
+
attemptCount: parsed.attempt_count,
|
|
142645
|
+
...parsed.active_claim_id ? {
|
|
142646
|
+
activeClaimId: parsed.active_claim_id
|
|
142647
|
+
} : {},
|
|
142648
|
+
...parsed.active_claim_worker_boot_id ? {
|
|
142649
|
+
activeClaimWorkerBootId: parsed.active_claim_worker_boot_id
|
|
142650
|
+
} : {},
|
|
142232
142651
|
initiatorChainDepth: parsed.initiator_chain_depth,
|
|
142233
142652
|
completion: parseJson$1(parsed.completion_json, OperationCompletionSchema, "Delivery completion"),
|
|
142234
142653
|
...parsed.consumed_at ? {
|
|
@@ -142287,7 +142706,11 @@ The postId is ${normalizedFeedbackPostId}. Use the feedback-progress-reporter sk
|
|
|
142287
142706
|
}).immediate();
|
|
142288
142707
|
}
|
|
142289
142708
|
migrate() {
|
|
142290
|
-
this.
|
|
142709
|
+
if (!this.isMigrationRequired()) return;
|
|
142710
|
+
this.db.transaction(() => {
|
|
142711
|
+
const hadDeliveryExecutionState = this.db.prepare("SELECT 1 FROM sqlite_master WHERE type = 'table' AND name = 'delivery_execution_state'").get() !== void 0;
|
|
142712
|
+
const hadDeliveryExecutionPhase = hadDeliveryExecutionState && this.db.prepare(`PRAGMA table_info(delivery_execution_state)`).all().some((column) => column.name === "execution_phase");
|
|
142713
|
+
this.db.exec(`
|
|
142291
142714
|
CREATE TABLE IF NOT EXISTS operations (
|
|
142292
142715
|
workspace_id TEXT NOT NULL,
|
|
142293
142716
|
owner_machine_id TEXT NOT NULL,
|
|
@@ -142330,6 +142753,28 @@ The postId is ${normalizedFeedbackPostId}. Use the feedback-progress-reporter sk
|
|
|
142330
142753
|
CREATE INDEX IF NOT EXISTS deliveries_pending_session
|
|
142331
142754
|
ON deliveries (workspace_id, requester_session_id, state, sequence);
|
|
142332
142755
|
|
|
142756
|
+
CREATE TABLE IF NOT EXISTS delivery_execution_state (
|
|
142757
|
+
requester_session_id TEXT NOT NULL,
|
|
142758
|
+
operation_id TEXT NOT NULL,
|
|
142759
|
+
execution_phase TEXT NOT NULL DEFAULT 'ready'
|
|
142760
|
+
CHECK (execution_phase IN ('ready', 'claimed', 'prepared', 'started', 'uncertain')),
|
|
142761
|
+
attempt_count INTEGER NOT NULL DEFAULT 0,
|
|
142762
|
+
active_claim_id TEXT,
|
|
142763
|
+
active_claim_worker_boot_id TEXT,
|
|
142764
|
+
PRIMARY KEY (requester_session_id, operation_id),
|
|
142765
|
+
FOREIGN KEY (requester_session_id, operation_id)
|
|
142766
|
+
REFERENCES operations (requester_session_id, operation_id)
|
|
142767
|
+
ON DELETE CASCADE
|
|
142768
|
+
);
|
|
142769
|
+
|
|
142770
|
+
CREATE TRIGGER IF NOT EXISTS deliveries_insert_execution_state
|
|
142771
|
+
AFTER INSERT ON deliveries
|
|
142772
|
+
BEGIN
|
|
142773
|
+
INSERT OR IGNORE INTO delivery_execution_state (
|
|
142774
|
+
requester_session_id, operation_id, execution_phase, attempt_count
|
|
142775
|
+
) VALUES (NEW.requester_session_id, NEW.operation_id, 'ready', 0);
|
|
142776
|
+
END;
|
|
142777
|
+
|
|
142333
142778
|
CREATE TABLE IF NOT EXISTS operation_item_materializations (
|
|
142334
142779
|
requester_session_id TEXT NOT NULL,
|
|
142335
142780
|
operation_id TEXT NOT NULL,
|
|
@@ -142355,6 +142800,47 @@ The postId is ${normalizedFeedbackPostId}. Use the feedback-progress-reporter sk
|
|
|
142355
142800
|
value TEXT NOT NULL
|
|
142356
142801
|
);
|
|
142357
142802
|
`);
|
|
142803
|
+
if (hadDeliveryExecutionState && !hadDeliveryExecutionPhase) {
|
|
142804
|
+
this.db.exec(`ALTER TABLE delivery_execution_state
|
|
142805
|
+
ADD COLUMN execution_phase TEXT NOT NULL DEFAULT 'ready'`);
|
|
142806
|
+
this.db.exec(`UPDATE delivery_execution_state
|
|
142807
|
+
SET execution_phase = CASE
|
|
142808
|
+
WHEN attempt_count > 0
|
|
142809
|
+
OR active_claim_id IS NOT NULL
|
|
142810
|
+
OR active_claim_worker_boot_id IS NOT NULL
|
|
142811
|
+
THEN 'uncertain'
|
|
142812
|
+
ELSE 'ready'
|
|
142813
|
+
END`);
|
|
142814
|
+
}
|
|
142815
|
+
this.db.prepare(`INSERT OR IGNORE INTO delivery_execution_state (
|
|
142816
|
+
requester_session_id, operation_id, execution_phase, attempt_count
|
|
142817
|
+
)
|
|
142818
|
+
SELECT requester_session_id, operation_id,
|
|
142819
|
+
CASE WHEN state = 'pending' THEN ? ELSE 'ready' END,
|
|
142820
|
+
0
|
|
142821
|
+
FROM deliveries`).run(hadDeliveryExecutionState ? "ready" : "uncertain");
|
|
142822
|
+
}).immediate();
|
|
142823
|
+
}
|
|
142824
|
+
isMigrationRequired() {
|
|
142825
|
+
const requiredObjects = /* @__PURE__ */ new Set([
|
|
142826
|
+
"table:operations",
|
|
142827
|
+
"index:operations_active_owner",
|
|
142828
|
+
"table:deliveries",
|
|
142829
|
+
"index:deliveries_pending_session",
|
|
142830
|
+
"table:delivery_execution_state",
|
|
142831
|
+
"trigger:deliveries_insert_execution_state",
|
|
142832
|
+
"table:operation_item_materializations",
|
|
142833
|
+
"table:operation_progress_settlements",
|
|
142834
|
+
"table:orchestration_meta"
|
|
142835
|
+
]);
|
|
142836
|
+
const existingObjects = this.db.prepare(`SELECT type, name FROM sqlite_master
|
|
142837
|
+
WHERE type IN ('table', 'index', 'trigger')`).all();
|
|
142838
|
+
for (const { type: type2, name: name2 } of existingObjects) {
|
|
142839
|
+
requiredObjects.delete(`${type2}:${name2}`);
|
|
142840
|
+
}
|
|
142841
|
+
if (requiredObjects.size > 0) return true;
|
|
142842
|
+
const executionStateColumns = this.db.prepare(`PRAGMA table_info(delivery_execution_state)`).all();
|
|
142843
|
+
return !executionStateColumns.some((column) => column.name === "execution_phase");
|
|
142358
142844
|
}
|
|
142359
142845
|
repairTerminalDeliveries() {
|
|
142360
142846
|
this.db.transaction(() => {
|
|
@@ -142463,20 +142949,20 @@ The postId is ${normalizedFeedbackPostId}. Use the feedback-progress-reporter sk
|
|
|
142463
142949
|
}
|
|
142464
142950
|
const isProgressRow = (entry) => entry.role === "system" && (entry.id === id2 || entry.id.startsWith(duplicatePrefix));
|
|
142465
142951
|
const timestamp2 = new Date(now2()).toISOString();
|
|
142466
|
-
|
|
142467
|
-
const existingIndex =
|
|
142468
|
-
const duplicates =
|
|
142952
|
+
const updateHistory = (history2) => {
|
|
142953
|
+
const existingIndex = history2.findIndex((entry2) => entry2.id === id2 && entry2.role === "system");
|
|
142954
|
+
const duplicates = history2.filter(isProgressRow);
|
|
142469
142955
|
const existing = duplicates[0];
|
|
142470
142956
|
const existingProgress = duplicates.flatMap((entry2) => entry2.items ?? []).filter((item) => item.type === "operation_progress").reduce((merged2, item) => mergeOperationProgressContent(merged2, item), void 0);
|
|
142471
142957
|
const materializedTargets = new Set((existingProgress?.items ?? []).map((item) => getOperationProgressTargetKey(item.target)));
|
|
142472
142958
|
const content = buildOperationProgressContent(operation, statusByTarget, materializedTargets);
|
|
142473
|
-
if (!content) return
|
|
142959
|
+
if (!content) return history2;
|
|
142474
142960
|
const merged = mergeOperationProgressContent(existingProgress, content);
|
|
142475
142961
|
const nextItems = [
|
|
142476
142962
|
merged
|
|
142477
142963
|
];
|
|
142478
142964
|
if (duplicates.length === 1 && existing && JSON.stringify(existing.items ?? []) === JSON.stringify(nextItems)) {
|
|
142479
|
-
return
|
|
142965
|
+
return history2;
|
|
142480
142966
|
}
|
|
142481
142967
|
const entry = {
|
|
142482
142968
|
...existing ?? {},
|
|
@@ -142489,20 +142975,24 @@ The postId is ${normalizedFeedbackPostId}. Use the feedback-progress-reporter sk
|
|
|
142489
142975
|
finished: true
|
|
142490
142976
|
};
|
|
142491
142977
|
if (existingIndex < 0) return [
|
|
142492
|
-
...
|
|
142978
|
+
...history2,
|
|
142493
142979
|
entry
|
|
142494
142980
|
];
|
|
142495
|
-
return
|
|
142981
|
+
return history2.flatMap((candidate, index) => index === existingIndex ? [
|
|
142496
142982
|
entry
|
|
142497
142983
|
] : isProgressRow(candidate) ? [] : [
|
|
142498
142984
|
candidate
|
|
142499
142985
|
]);
|
|
142500
|
-
}
|
|
142986
|
+
};
|
|
142987
|
+
const history = await sessionDoc.getHistory();
|
|
142988
|
+
if (updateHistory(history) === history) return;
|
|
142989
|
+
await sessionDoc.updateHistory(updateHistory);
|
|
142501
142990
|
};
|
|
142502
142991
|
const TARGET_OUTPUT_PREVIEW_MAX_BYTES = 8 * 1024;
|
|
142503
142992
|
const MATERIALIZATION_RETRY_MIN_MS = 1e3;
|
|
142504
142993
|
const MATERIALIZATION_RETRY_MAX_MS = 3e4;
|
|
142505
142994
|
const DELIVERY_EXPIRY_GRACE_MS = 8 * 60 * 60 * 1e3;
|
|
142995
|
+
const WORKER_BOOT_ID = randomUUID();
|
|
142506
142996
|
const truncateTargetOutput = (text) => {
|
|
142507
142997
|
const originalBytes = Buffer.byteLength(text, "utf8");
|
|
142508
142998
|
if (originalBytes <= TARGET_OUTPUT_PREVIEW_MAX_BYTES) return {
|
|
@@ -142540,7 +143030,8 @@ The postId is ${normalizedFeedbackPostId}. Use the feedback-progress-reporter sk
|
|
|
142540
143030
|
const text = (assistant.items ?? []).filter((item) => item.type === "text").map((item) => item.text).filter((item) => item.length > 0).join("\n\n");
|
|
142541
143031
|
return text.length > 0 ? truncateTargetOutput(text) : void 0;
|
|
142542
143032
|
};
|
|
142543
|
-
const
|
|
143033
|
+
const isTerminalAssistantEntry = (entry) => entry.role === "assistant" && (entry.finished === true || typeof entry.endedAt === "number");
|
|
143034
|
+
const terminalAssistantFor = (history, userTurnId) => history.find((entry) => entry.userTurnId === userTurnId && isTerminalAssistantEntry(entry));
|
|
142544
143035
|
const completionText = (operation) => [
|
|
142545
143036
|
`Lody Operation ${operation.operationId} (${operation.kind}) finished.`,
|
|
142546
143037
|
"Use the structured completion below to continue the user task. Do not restart completed targets.",
|
|
@@ -142552,6 +143043,7 @@ The postId is ${normalizedFeedbackPostId}. Use the feedback-progress-reporter sk
|
|
|
142552
143043
|
const storePath = options.storePath ?? getLodyOperationStorePath(options.machineId);
|
|
142553
143044
|
this.storeFactory = options.storeFactory ?? (() => new LodyOperationStore(storePath));
|
|
142554
143045
|
this.now = options.now ?? getServerNow;
|
|
143046
|
+
this.workerBootId = options.workerBootId ?? WORKER_BOOT_ID;
|
|
142555
143047
|
}
|
|
142556
143048
|
storeFactory;
|
|
142557
143049
|
now;
|
|
@@ -142563,7 +143055,8 @@ The postId is ${normalizedFeedbackPostId}. Use the feedback-progress-reporter sk
|
|
|
142563
143055
|
reconcileChains = /* @__PURE__ */ new Map();
|
|
142564
143056
|
deliveryChains = /* @__PURE__ */ new Map();
|
|
142565
143057
|
queuedDeliveryIds = /* @__PURE__ */ new Set();
|
|
142566
|
-
|
|
143058
|
+
dirtyDeliveryIds = /* @__PURE__ */ new Set();
|
|
143059
|
+
observedDeliverySettlements = /* @__PURE__ */ new Map();
|
|
142567
143060
|
operationAbortControllers = /* @__PURE__ */ new Map();
|
|
142568
143061
|
metaWatch = null;
|
|
142569
143062
|
store = null;
|
|
@@ -142572,6 +143065,7 @@ The postId is ${normalizedFeedbackPostId}. Use the feedback-progress-reporter sk
|
|
|
142572
143065
|
storeWakeTimer = null;
|
|
142573
143066
|
started = false;
|
|
142574
143067
|
materializationClaimToken = randomUUID();
|
|
143068
|
+
workerBootId;
|
|
142575
143069
|
start() {
|
|
142576
143070
|
if (this.started) return;
|
|
142577
143071
|
this.started = true;
|
|
@@ -142584,6 +143078,10 @@ The postId is ${normalizedFeedbackPostId}. Use the feedback-progress-reporter sk
|
|
|
142584
143078
|
]
|
|
142585
143079
|
});
|
|
142586
143080
|
this.store = this.storeFactory();
|
|
143081
|
+
const recoveredClaims = this.store.recoverOrphanedDeliveryClaims(this.options.workspaceId, this.workerBootId);
|
|
143082
|
+
if (recoveredClaims > 0) {
|
|
143083
|
+
this.options.logger.warn(`[orchestration] Recovered ${recoveredClaims} orphaned Delivery claim(s) from an exited Worker`);
|
|
143084
|
+
}
|
|
142587
143085
|
const storePath = this.options.storePath ?? getLodyOperationStorePath(this.options.machineId);
|
|
142588
143086
|
const storeBasename = path__default.basename(storePath);
|
|
142589
143087
|
const watchOperationStore = this.options.operationStoreWatchFactory ?? ((directory, onChange) => watch(directory, (_event, filename) => onChange(filename)));
|
|
@@ -142609,6 +143107,16 @@ The postId is ${normalizedFeedbackPostId}. Use the feedback-progress-reporter sk
|
|
|
142609
143107
|
this.storeWakeTimer = null;
|
|
142610
143108
|
if (this.progressRetryTimer) clearTimeout(this.progressRetryTimer);
|
|
142611
143109
|
this.progressRetryTimer = null;
|
|
143110
|
+
if (this.store) {
|
|
143111
|
+
try {
|
|
143112
|
+
const abandonedClaims = this.store.abandonDeliveryClaimsOwnedBy(this.options.workspaceId, this.workerBootId);
|
|
143113
|
+
if (abandonedClaims > 0) {
|
|
143114
|
+
this.options.logger.warn(`[orchestration] Abandoned ${abandonedClaims} Delivery claim(s) while stopping the workspace coordinator`);
|
|
143115
|
+
}
|
|
143116
|
+
} catch (error2) {
|
|
143117
|
+
this.options.logger.warn(`[orchestration] Could not abandon Delivery claims during coordinator stop: ${error2 instanceof Error ? error2.message : String(error2)}`);
|
|
143118
|
+
}
|
|
143119
|
+
}
|
|
142612
143120
|
this.store?.close();
|
|
142613
143121
|
this.store = null;
|
|
142614
143122
|
for (const subscription of this.targetSubscriptions.values()) {
|
|
@@ -142627,7 +143135,8 @@ The postId is ${normalizedFeedbackPostId}. Use the feedback-progress-reporter sk
|
|
|
142627
143135
|
this.reconcileChains.clear();
|
|
142628
143136
|
this.deliveryChains.clear();
|
|
142629
143137
|
this.queuedDeliveryIds.clear();
|
|
142630
|
-
this.
|
|
143138
|
+
this.dirtyDeliveryIds.clear();
|
|
143139
|
+
this.observedDeliverySettlements.clear();
|
|
142631
143140
|
for (const controller of this.operationAbortControllers.values()) controller.abort();
|
|
142632
143141
|
this.operationAbortControllers.clear();
|
|
142633
143142
|
}
|
|
@@ -143074,7 +143583,7 @@ The postId is ${normalizedFeedbackPostId}. Use the feedback-progress-reporter sk
|
|
|
143074
143583
|
}
|
|
143075
143584
|
enqueueDelivery(delivery, reason) {
|
|
143076
143585
|
if (this.queuedDeliveryIds.has(delivery.deliveryId)) {
|
|
143077
|
-
this.
|
|
143586
|
+
this.dirtyDeliveryIds.add(delivery.deliveryId);
|
|
143078
143587
|
return;
|
|
143079
143588
|
}
|
|
143080
143589
|
this.queuedDeliveryIds.add(delivery.deliveryId);
|
|
@@ -143083,29 +143592,28 @@ The postId is ${normalizedFeedbackPostId}. Use the feedback-progress-reporter sk
|
|
|
143083
143592
|
const next2 = previous.catch(() => void 0).then(async () => {
|
|
143084
143593
|
let attemptReason = reason;
|
|
143085
143594
|
for (; ; ) {
|
|
143086
|
-
this.
|
|
143595
|
+
this.dirtyDeliveryIds.delete(delivery.deliveryId);
|
|
143087
143596
|
try {
|
|
143088
143597
|
await this.deliverIfRunnable(delivery, attemptReason);
|
|
143089
143598
|
} catch (error2) {
|
|
143090
143599
|
this.options.logger.warn(`[orchestration] Delivery ${delivery.deliveryId} failed: ${error2 instanceof Error ? error2.message : String(error2)}`);
|
|
143091
143600
|
}
|
|
143092
|
-
const
|
|
143093
|
-
if (!this.started || !
|
|
143601
|
+
const retry2 = this.dirtyDeliveryIds.delete(delivery.deliveryId);
|
|
143602
|
+
if (!this.started || !retry2 || !this.isDeliveryPending(delivery)) {
|
|
143094
143603
|
return;
|
|
143095
143604
|
}
|
|
143096
|
-
attemptReason =
|
|
143605
|
+
attemptReason = "coalesced";
|
|
143097
143606
|
}
|
|
143098
143607
|
}).catch((error2) => {
|
|
143099
143608
|
this.options.logger.warn(`[orchestration] Delivery ${delivery.deliveryId} coalesced retry failed: ${error2 instanceof Error ? error2.message : String(error2)}`);
|
|
143100
143609
|
}).finally(() => {
|
|
143101
|
-
const
|
|
143610
|
+
const lateRetry = this.dirtyDeliveryIds.delete(delivery.deliveryId);
|
|
143102
143611
|
this.queuedDeliveryIds.delete(delivery.deliveryId);
|
|
143103
|
-
this.dirtyDeliveryReasons.delete(delivery.deliveryId);
|
|
143104
143612
|
if (this.deliveryChains.get(sessionId) === next2) {
|
|
143105
143613
|
this.deliveryChains.delete(sessionId);
|
|
143106
143614
|
}
|
|
143107
|
-
if (this.started &&
|
|
143108
|
-
this.enqueueDelivery(delivery,
|
|
143615
|
+
if (this.started && lateRetry && this.isDeliveryPending(delivery)) {
|
|
143616
|
+
this.enqueueDelivery(delivery, "coalesced");
|
|
143109
143617
|
}
|
|
143110
143618
|
});
|
|
143111
143619
|
this.deliveryChains.set(sessionId, next2);
|
|
@@ -143113,8 +143621,62 @@ The postId is ${normalizedFeedbackPostId}. Use the feedback-progress-reporter sk
|
|
|
143113
143621
|
isDeliveryPending(delivery) {
|
|
143114
143622
|
return this.withStore((store) => store.listPendingDeliveries(this.options.workspaceId, delivery.requesterSessionId).some((candidate) => candidate.deliveryId === delivery.deliveryId));
|
|
143115
143623
|
}
|
|
143624
|
+
async settleObservedDeliveryClaim(delivery, settlement) {
|
|
143625
|
+
const previous = this.observedDeliverySettlements.get(delivery.deliveryId);
|
|
143626
|
+
if (!previous || previous.claimId === settlement.claimId) {
|
|
143627
|
+
this.observedDeliverySettlements.set(delivery.deliveryId, settlement);
|
|
143628
|
+
}
|
|
143629
|
+
if (settlement.outcome === "finalize" && settlement.pendingHistoryWrite) {
|
|
143630
|
+
const current22 = this.withStore((store) => store.getDelivery(delivery.requesterSessionId, delivery.operationId));
|
|
143631
|
+
if (current22.activeClaimWorkerBootId !== this.workerBootId || current22.activeClaimId !== settlement.claimId) {
|
|
143632
|
+
if (this.observedDeliverySettlements.get(delivery.deliveryId) === settlement) {
|
|
143633
|
+
this.observedDeliverySettlements.delete(delivery.deliveryId);
|
|
143634
|
+
}
|
|
143635
|
+
return current22;
|
|
143636
|
+
}
|
|
143637
|
+
await settlement.pendingHistoryWrite();
|
|
143638
|
+
delete settlement.pendingHistoryWrite;
|
|
143639
|
+
}
|
|
143640
|
+
const current2 = this.withStore((store) => {
|
|
143641
|
+
let latest2 = store.getDelivery(delivery.requesterSessionId, delivery.operationId);
|
|
143642
|
+
if (latest2.activeClaimWorkerBootId !== this.workerBootId || latest2.activeClaimId !== settlement.claimId) {
|
|
143643
|
+
return latest2;
|
|
143644
|
+
}
|
|
143645
|
+
if (settlement.outcome === "handled" || settlement.outcome === "cancelled" || settlement.outcome === "finalize") {
|
|
143646
|
+
return store.consumeClaimedDelivery(delivery.requesterSessionId, delivery.operationId, this.workerBootId, settlement.claimId).delivery;
|
|
143647
|
+
}
|
|
143648
|
+
if (settlement.outcome === "uncertain") {
|
|
143649
|
+
store.markClaimedDeliveryExecutionUncertain(delivery.requesterSessionId, delivery.operationId, this.workerBootId, settlement.claimId);
|
|
143650
|
+
} else {
|
|
143651
|
+
store.releaseDeliveryClaim(delivery.requesterSessionId, delivery.operationId, this.workerBootId, settlement.claimId);
|
|
143652
|
+
}
|
|
143653
|
+
latest2 = store.getDelivery(delivery.requesterSessionId, delivery.operationId);
|
|
143654
|
+
return latest2;
|
|
143655
|
+
});
|
|
143656
|
+
if (current2.activeClaimWorkerBootId !== this.workerBootId || current2.activeClaimId !== settlement.claimId) {
|
|
143657
|
+
if (this.observedDeliverySettlements.get(delivery.deliveryId) === settlement) {
|
|
143658
|
+
this.observedDeliverySettlements.delete(delivery.deliveryId);
|
|
143659
|
+
}
|
|
143660
|
+
}
|
|
143661
|
+
return current2;
|
|
143662
|
+
}
|
|
143116
143663
|
async deliverIfRunnable(delivery, reason) {
|
|
143117
143664
|
if (!this.started) return;
|
|
143665
|
+
delivery = this.withStore((store) => store.getDelivery(delivery.requesterSessionId, delivery.operationId));
|
|
143666
|
+
if (delivery.state === "consumed") {
|
|
143667
|
+
this.observedDeliverySettlements.delete(delivery.deliveryId);
|
|
143668
|
+
return;
|
|
143669
|
+
}
|
|
143670
|
+
if (delivery.activeClaimId || delivery.activeClaimWorkerBootId) {
|
|
143671
|
+
const settlement = this.observedDeliverySettlements.get(delivery.deliveryId);
|
|
143672
|
+
if (settlement && delivery.activeClaimWorkerBootId === this.workerBootId && delivery.activeClaimId === settlement.claimId) {
|
|
143673
|
+
await this.settleObservedDeliveryClaim(delivery, settlement);
|
|
143674
|
+
} else if (settlement) {
|
|
143675
|
+
this.observedDeliverySettlements.delete(delivery.deliveryId);
|
|
143676
|
+
}
|
|
143677
|
+
return;
|
|
143678
|
+
}
|
|
143679
|
+
this.observedDeliverySettlements.delete(delivery.deliveryId);
|
|
143118
143680
|
const metaRecord = await this.options.workspaceDocument.repo.getDocMeta(getSessionRoomId(delivery.requesterSessionId));
|
|
143119
143681
|
if (!metaRecord?.meta || isLoroRepoDocDeleted(metaRecord)) return;
|
|
143120
143682
|
const meta = metaRecord.meta;
|
|
@@ -143122,32 +143684,54 @@ The postId is ${normalizedFeedbackPostId}. Use the feedback-progress-reporter sk
|
|
|
143122
143684
|
const sessionDoc = await this.options.workspaceDocument.getOrCreateSessionDoc(delivery.requesterSessionId);
|
|
143123
143685
|
this.subscribeTarget(delivery.requesterSessionId, sessionDoc);
|
|
143124
143686
|
const execution = this.options.executionService.getExecutionSnapshot(delivery.requesterSessionId);
|
|
143125
|
-
const historyBeforeDispatch = await sessionDoc.getHistory();
|
|
143126
|
-
const continuationEvidence = this.getContinuationEvidence(historyBeforeDispatch, delivery.systemTurnId);
|
|
143127
|
-
if (continuationEvidence) {
|
|
143128
|
-
this.consumeDelivery(delivery, reason, continuationEvidence);
|
|
143129
|
-
return;
|
|
143130
|
-
}
|
|
143131
143687
|
const operation = this.withStore((store) => store.get(delivery.requesterSessionId, delivery.operationId));
|
|
143132
143688
|
if (this.now() >= Date.parse(operation.deadlineAt) + DELIVERY_EXPIRY_GRACE_MS) {
|
|
143133
|
-
this.
|
|
143689
|
+
await this.finalizeDeliveryWithoutExecution(sessionDoc, operation, delivery, reason, "expired_stale", void 0, false, delivery.executionPhase === "uncertain" ? "uncertain" : "ready");
|
|
143690
|
+
return;
|
|
143691
|
+
}
|
|
143692
|
+
if (delivery.executionPhase === "uncertain") {
|
|
143693
|
+
await this.failUncertainDelivery(sessionDoc, operation, delivery, reason);
|
|
143134
143694
|
return;
|
|
143135
143695
|
}
|
|
143136
143696
|
if (execution.hasActiveTurn) return;
|
|
143137
143697
|
if (this.options.dispatchWatcher.hasPendingDispatch(delivery.requesterSessionId)) return;
|
|
143698
|
+
if (delivery.attemptCount >= DELIVERY_MAX_ATTEMPTS) {
|
|
143699
|
+
await this.failExhaustedDelivery(sessionDoc, operation, delivery, reason);
|
|
143700
|
+
return;
|
|
143701
|
+
}
|
|
143138
143702
|
const configuration = await this.resolveFrozenConfiguration(operation, delivery, reason);
|
|
143139
143703
|
if (configuration === "unknown") {
|
|
143140
143704
|
this.armConfigurationRetry(delivery.requesterSessionId);
|
|
143141
143705
|
return;
|
|
143142
143706
|
}
|
|
143143
143707
|
if (configuration === "unavailable") {
|
|
143144
|
-
await this.
|
|
143145
|
-
|
|
143708
|
+
await this.finalizeDeliveryWithoutExecution(sessionDoc, operation, delivery, reason, "configuration_unavailable", {
|
|
143709
|
+
code: "CONFIGURATION_UNAVAILABLE",
|
|
143710
|
+
message: "The frozen continuation agent configuration is no longer available."
|
|
143711
|
+
});
|
|
143146
143712
|
return;
|
|
143147
143713
|
}
|
|
143148
143714
|
const frozen = operation.frozenContinuationConfig.inputConfig;
|
|
143149
143715
|
const requester = await this.resolveRequesterIdentity(operation.requesterUserId);
|
|
143150
|
-
|
|
143716
|
+
const attemptId = randomUUID();
|
|
143717
|
+
let observedSettlement;
|
|
143718
|
+
const settleResidualClaim = () => observedSettlement ? this.settleObservedDeliveryClaim(delivery, {
|
|
143719
|
+
claimId: attemptId,
|
|
143720
|
+
outcome: observedSettlement
|
|
143721
|
+
}) : this.withStore((store) => {
|
|
143722
|
+
let current2 = store.getDelivery(delivery.requesterSessionId, delivery.operationId);
|
|
143723
|
+
if (current2.activeClaimWorkerBootId !== this.workerBootId || current2.activeClaimId !== attemptId) {
|
|
143724
|
+
return current2;
|
|
143725
|
+
}
|
|
143726
|
+
if (current2.executionPhase === "started") {
|
|
143727
|
+
store.markClaimedDeliveryExecutionUncertain(delivery.requesterSessionId, delivery.operationId, this.workerBootId, attemptId);
|
|
143728
|
+
} else {
|
|
143729
|
+
store.releaseDeliveryClaim(delivery.requesterSessionId, delivery.operationId, this.workerBootId, attemptId);
|
|
143730
|
+
}
|
|
143731
|
+
current2 = store.getDelivery(delivery.requesterSessionId, delivery.operationId);
|
|
143732
|
+
return current2;
|
|
143733
|
+
});
|
|
143734
|
+
const continuation = this.options.executionService.continueSession({
|
|
143151
143735
|
type: "session/chat",
|
|
143152
143736
|
sessionId: delivery.requesterSessionId,
|
|
143153
143737
|
machineId: this.options.machineId,
|
|
@@ -143183,18 +143767,97 @@ The postId is ${normalizedFeedbackPostId}. Use the feedback-progress-reporter sk
|
|
|
143183
143767
|
}, {
|
|
143184
143768
|
dispatchSource: "delivery",
|
|
143185
143769
|
onTurnClaimed: async () => {
|
|
143186
|
-
|
|
143770
|
+
if (!this.started) return false;
|
|
143771
|
+
const claim = this.withStore((store) => store.claimDeliveryExecution(delivery.requesterSessionId, delivery.operationId, {
|
|
143772
|
+
claimId: attemptId,
|
|
143773
|
+
workerBootId: this.workerBootId
|
|
143774
|
+
}));
|
|
143775
|
+
if (claim.status !== "claimed") {
|
|
143776
|
+
this.options.logger.debug(`[orchestration] Delivery ${delivery.deliveryId} claim lost status=${claim.status}`);
|
|
143777
|
+
return false;
|
|
143778
|
+
}
|
|
143779
|
+
try {
|
|
143780
|
+
await this.writeCompletionTurn(sessionDoc, operation, delivery);
|
|
143781
|
+
const prepared = this.withStore((store) => store.prepareClaimedDeliveryExecution(delivery.requesterSessionId, delivery.operationId, this.workerBootId, attemptId));
|
|
143782
|
+
if (!prepared.prepared) {
|
|
143783
|
+
this.withStore((store) => store.releaseDeliveryClaim(delivery.requesterSessionId, delivery.operationId, this.workerBootId, attemptId));
|
|
143784
|
+
this.options.logger.debug(`[orchestration] Delivery ${delivery.deliveryId} execution start lost its claim`);
|
|
143785
|
+
return false;
|
|
143786
|
+
}
|
|
143787
|
+
} catch (error2) {
|
|
143788
|
+
this.withStore((store) => store.releaseDeliveryClaim(delivery.requesterSessionId, delivery.operationId, this.workerBootId, attemptId));
|
|
143789
|
+
throw error2;
|
|
143790
|
+
}
|
|
143791
|
+
return true;
|
|
143792
|
+
},
|
|
143793
|
+
onTurnStarted: async () => this.withStore((store) => store.markClaimedDeliveryExecutionStarted(delivery.requesterSessionId, delivery.operationId, this.workerBootId, attemptId)),
|
|
143794
|
+
onTurnSettled: async (outcome) => {
|
|
143795
|
+
observedSettlement = outcome;
|
|
143796
|
+
const settled = await this.settleObservedDeliveryClaim(delivery, {
|
|
143797
|
+
claimId: attemptId,
|
|
143798
|
+
outcome
|
|
143799
|
+
});
|
|
143800
|
+
if (outcome === "handled" || outcome === "cancelled") {
|
|
143801
|
+
this.options.logger.debug(`[orchestration] Delivery ${delivery.deliveryId} consumed=${String(settled.state === "consumed")}`);
|
|
143802
|
+
}
|
|
143187
143803
|
}
|
|
143188
143804
|
});
|
|
143189
|
-
|
|
143190
|
-
|
|
143191
|
-
|
|
143192
|
-
|
|
143805
|
+
try {
|
|
143806
|
+
await continuation;
|
|
143807
|
+
} catch (error2) {
|
|
143808
|
+
const afterInterruption = await settleResidualClaim();
|
|
143809
|
+
if (afterInterruption.executionPhase === "uncertain") {
|
|
143810
|
+
await this.failUncertainDelivery(sessionDoc, operation, afterInterruption, reason);
|
|
143811
|
+
}
|
|
143812
|
+
if (afterInterruption.state === "pending" && !afterInterruption.activeClaimId && afterInterruption.attemptCount >= DELIVERY_MAX_ATTEMPTS) {
|
|
143813
|
+
await this.failExhaustedDelivery(sessionDoc, operation, afterInterruption, reason);
|
|
143814
|
+
}
|
|
143815
|
+
throw error2;
|
|
143816
|
+
}
|
|
143817
|
+
const afterExecution = await settleResidualClaim();
|
|
143818
|
+
if (afterExecution.executionPhase === "uncertain") {
|
|
143819
|
+
await this.failUncertainDelivery(sessionDoc, operation, afterExecution, reason);
|
|
143820
|
+
return;
|
|
143193
143821
|
}
|
|
143822
|
+
if (afterExecution.state === "pending" && !afterExecution.activeClaimId && afterExecution.attemptCount >= DELIVERY_MAX_ATTEMPTS) {
|
|
143823
|
+
await this.failExhaustedDelivery(sessionDoc, operation, afterExecution, reason);
|
|
143824
|
+
}
|
|
143825
|
+
}
|
|
143826
|
+
async failExhaustedDelivery(sessionDoc, operation, delivery, wakeReason) {
|
|
143827
|
+
await this.finalizeDeliveryWithoutExecution(sessionDoc, operation, delivery, wakeReason, "attempts_exhausted", {
|
|
143828
|
+
code: "DELIVERY_ATTEMPTS_EXHAUSTED",
|
|
143829
|
+
message: "The completion continuation did not settle after two delivery attempts."
|
|
143830
|
+
}, true);
|
|
143831
|
+
}
|
|
143832
|
+
async failUncertainDelivery(sessionDoc, operation, delivery, wakeReason) {
|
|
143833
|
+
await this.finalizeDeliveryWithoutExecution(sessionDoc, operation, delivery, wakeReason, "execution_uncertain", {
|
|
143834
|
+
status: "uncertain",
|
|
143835
|
+
code: "DELIVERY_EXECUTION_UNCERTAIN",
|
|
143836
|
+
message: "The completion continuation may have started before execution was interrupted. It was not replayed; review the session output and continue manually if needed."
|
|
143837
|
+
}, false, "uncertain");
|
|
143194
143838
|
}
|
|
143195
|
-
|
|
143839
|
+
async finalizeDeliveryWithoutExecution(sessionDoc, operation, delivery, wakeReason, evidence, continuationFailure, requireAttemptsExhausted = false, requiredExecutionPhase = "ready") {
|
|
143840
|
+
if (!this.started) return;
|
|
143196
143841
|
const startedAt = performance$2.now();
|
|
143197
|
-
|
|
143842
|
+
const claimId = randomUUID();
|
|
143843
|
+
const claim = this.withStore((store) => store.claimDeliveryFinalization(delivery.requesterSessionId, delivery.operationId, {
|
|
143844
|
+
claimId,
|
|
143845
|
+
workerBootId: this.workerBootId,
|
|
143846
|
+
requireAttemptsExhausted,
|
|
143847
|
+
requiredExecutionPhase
|
|
143848
|
+
}));
|
|
143849
|
+
if (claim.status !== "claimed") {
|
|
143850
|
+
this.options.logger.debug(`[orchestration] Delivery ${delivery.deliveryId} finalization skipped status=${claim.status} reason=${evidence} wake=${wakeReason}`);
|
|
143851
|
+
return;
|
|
143852
|
+
}
|
|
143853
|
+
const settled = await this.settleObservedDeliveryClaim(delivery, {
|
|
143854
|
+
claimId,
|
|
143855
|
+
outcome: "finalize",
|
|
143856
|
+
...continuationFailure ? {
|
|
143857
|
+
pendingHistoryWrite: () => this.writeCompletionTurn(sessionDoc, operation, delivery, continuationFailure)
|
|
143858
|
+
} : {}
|
|
143859
|
+
});
|
|
143860
|
+
if (settled.state !== "consumed") return;
|
|
143198
143861
|
const timer2 = this.configurationTimers.get(delivery.requesterSessionId);
|
|
143199
143862
|
if (timer2) clearTimeout(timer2);
|
|
143200
143863
|
this.configurationTimers.delete(delivery.requesterSessionId);
|
|
@@ -143248,50 +143911,83 @@ The postId is ${normalizedFeedbackPostId}. Use the feedback-progress-reporter sk
|
|
|
143248
143911
|
timer2.unref?.();
|
|
143249
143912
|
this.configurationTimers.set(sessionId, timer2);
|
|
143250
143913
|
}
|
|
143251
|
-
async writeCompletionTurn(sessionDoc, operation, delivery,
|
|
143914
|
+
async writeCompletionTurn(sessionDoc, operation, delivery, continuationFailure) {
|
|
143252
143915
|
if (!operation.completion) {
|
|
143253
143916
|
throw new Error(`Finished Operation ${operation.operationId} has no completion.`);
|
|
143254
143917
|
}
|
|
143255
|
-
const
|
|
143256
|
-
const
|
|
143257
|
-
|
|
143258
|
-
|
|
143259
|
-
|
|
143260
|
-
|
|
143261
|
-
|
|
143262
|
-
progressMessageId
|
|
143263
|
-
|
|
143264
|
-
|
|
143265
|
-
|
|
143266
|
-
|
|
143267
|
-
|
|
143268
|
-
|
|
143269
|
-
|
|
143270
|
-
|
|
143918
|
+
const completion = operation.completion;
|
|
143919
|
+
const buildTurn = (progressMessageId) => {
|
|
143920
|
+
const item = {
|
|
143921
|
+
type: "operation_completion",
|
|
143922
|
+
deliveryId: delivery.deliveryId,
|
|
143923
|
+
operationId: operation.operationId,
|
|
143924
|
+
operationKind: operation.kind,
|
|
143925
|
+
...progressMessageId ? {
|
|
143926
|
+
progressMessageId
|
|
143927
|
+
} : {},
|
|
143928
|
+
completion,
|
|
143929
|
+
...continuationFailure ? {
|
|
143930
|
+
continuation: {
|
|
143931
|
+
status: continuationFailure.status ?? "not_started",
|
|
143932
|
+
reason: {
|
|
143933
|
+
code: continuationFailure.code,
|
|
143934
|
+
message: continuationFailure.message
|
|
143935
|
+
}
|
|
143271
143936
|
}
|
|
143937
|
+
} : {}
|
|
143938
|
+
};
|
|
143939
|
+
return {
|
|
143940
|
+
id: delivery.systemTurnId,
|
|
143941
|
+
role: "system",
|
|
143942
|
+
userId: operation.requesterUserId,
|
|
143943
|
+
timestamp: new Date(this.now()).toISOString(),
|
|
143944
|
+
items: [
|
|
143945
|
+
item
|
|
143946
|
+
],
|
|
143947
|
+
fileDiff: [],
|
|
143948
|
+
finished: true,
|
|
143949
|
+
inputConfig: {
|
|
143950
|
+
...operation.frozenContinuationConfig.inputConfig,
|
|
143951
|
+
prompt: completionText(operation),
|
|
143952
|
+
chainDepth: operation.initiatorChainDepth + 1
|
|
143272
143953
|
}
|
|
143273
|
-
}
|
|
143274
|
-
};
|
|
143275
|
-
const turn = {
|
|
143276
|
-
id: delivery.systemTurnId,
|
|
143277
|
-
role: "system",
|
|
143278
|
-
userId: operation.requesterUserId,
|
|
143279
|
-
timestamp: new Date(this.now()).toISOString(),
|
|
143280
|
-
items: [
|
|
143281
|
-
item
|
|
143282
|
-
],
|
|
143283
|
-
fileDiff: [],
|
|
143284
|
-
finished: true,
|
|
143285
|
-
inputConfig: {
|
|
143286
|
-
...operation.frozenContinuationConfig.inputConfig,
|
|
143287
|
-
prompt: completionText(operation),
|
|
143288
|
-
chainDepth: operation.initiatorChainDepth + 1
|
|
143289
|
-
}
|
|
143954
|
+
};
|
|
143290
143955
|
};
|
|
143291
|
-
await sessionDoc.updateHistory((history) =>
|
|
143292
|
-
|
|
143293
|
-
|
|
143294
|
-
|
|
143956
|
+
await sessionDoc.updateHistory((history) => {
|
|
143957
|
+
const progressMessageId = this.findProgressMessageId(history, operation);
|
|
143958
|
+
const existing = history.find((entry) => entry.id === delivery.systemTurnId);
|
|
143959
|
+
if (!existing) return [
|
|
143960
|
+
...history,
|
|
143961
|
+
buildTurn(progressMessageId)
|
|
143962
|
+
];
|
|
143963
|
+
if (existing.role !== "system") return history;
|
|
143964
|
+
return history.map((entry) => entry.id !== delivery.systemTurnId ? entry : {
|
|
143965
|
+
...entry,
|
|
143966
|
+
items: entry.items?.map((existingItem) => {
|
|
143967
|
+
if (existingItem.type !== "operation_completion" || existingItem.deliveryId !== delivery.deliveryId) {
|
|
143968
|
+
return existingItem;
|
|
143969
|
+
}
|
|
143970
|
+
const linkedItem = progressMessageId ? {
|
|
143971
|
+
...existingItem,
|
|
143972
|
+
progressMessageId
|
|
143973
|
+
} : existingItem;
|
|
143974
|
+
if (continuationFailure) {
|
|
143975
|
+
return {
|
|
143976
|
+
...linkedItem,
|
|
143977
|
+
continuation: {
|
|
143978
|
+
status: continuationFailure.status ?? "not_started",
|
|
143979
|
+
reason: {
|
|
143980
|
+
code: continuationFailure.code,
|
|
143981
|
+
message: continuationFailure.message
|
|
143982
|
+
}
|
|
143983
|
+
}
|
|
143984
|
+
};
|
|
143985
|
+
}
|
|
143986
|
+
const { continuation: _continuation, ...withoutContinuation } = linkedItem;
|
|
143987
|
+
return withoutContinuation;
|
|
143988
|
+
})
|
|
143989
|
+
});
|
|
143990
|
+
});
|
|
143295
143991
|
}
|
|
143296
143992
|
findProgressMessageId(history, operation) {
|
|
143297
143993
|
if (operation.kind !== "session_create" && operation.kind !== "session_create_many") {
|
|
@@ -143312,20 +144008,6 @@ The postId is ${normalizedFeedbackPostId}. Use the feedback-progress-reporter sk
|
|
|
143312
144008
|
].every((item) => item.status === "succeeded" ? covered.get(getOperationProgressTargetKey(item.target)) === "succeeded" : item.status === "active" && item.inputDurable ? covered.has(getOperationProgressTargetKey(item.target)) : true);
|
|
143313
144009
|
return complete2 ? progressMessageId : void 0;
|
|
143314
144010
|
}
|
|
143315
|
-
getContinuationEvidence(history, systemTurnId) {
|
|
143316
|
-
const index = history.findIndex((entry) => entry.id === systemTurnId && entry.role === "system");
|
|
143317
|
-
if (index < 0) return null;
|
|
143318
|
-
const completionWasUnavailable = history[index]?.items?.some((item) => item.type === "operation_completion" && item.continuation?.status === "not_started" && item.continuation.reason.code === "CONFIGURATION_UNAVAILABLE");
|
|
143319
|
-
if (completionWasUnavailable) return "configuration_unavailable";
|
|
143320
|
-
for (const entry of history.slice(index + 1)) {
|
|
143321
|
-
if (entry.role === "assistant") return "assistant_history";
|
|
143322
|
-
if (entry.role === "user") return null;
|
|
143323
|
-
if (entry.role === "system" && entry.items?.some((item) => item.type === "system_notice" && item.name === "chat_failed")) {
|
|
143324
|
-
return "chat_failed";
|
|
143325
|
-
}
|
|
143326
|
-
}
|
|
143327
|
-
return null;
|
|
143328
|
-
}
|
|
143329
144011
|
}
|
|
143330
144012
|
const version = "1.33.0";
|
|
143331
144013
|
var lookup = [];
|
|
@@ -222954,7 +223636,7 @@ ${page}${helpTipBottom}${choiceDescription}${ansiEscapes.cursorHide}`;
|
|
|
222954
223636
|
data = createReviewBundleSnapshot(bundle);
|
|
222955
223637
|
}
|
|
222956
223638
|
const { injectReviewSnapshot } = await import("./chunks/index-VoI6Ds2-.js");
|
|
222957
|
-
const { resolveReviewViewerTemplate } = await import("./chunks/review-viewer-
|
|
223639
|
+
const { resolveReviewViewerTemplate } = await import("./chunks/review-viewer-DqtXyKjy.js").then(async (m) => {
|
|
222958
223640
|
await m.__tla;
|
|
222959
223641
|
return m;
|
|
222960
223642
|
});
|