@bastani/atomic 0.9.44-alpha.4 → 0.9.44-alpha.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +26 -0
- package/dist/builtin/intercom/CHANGELOG.md +12 -0
- package/dist/builtin/intercom/broker/broker.ts +13 -1
- package/dist/builtin/intercom/index.bundle.mjs +9 -1
- package/dist/builtin/intercom/package.json +1 -1
- package/dist/builtin/intercom/types.ts +7 -0
- package/dist/builtin/intercom/workflow-delivery-states.ts +48 -0
- package/dist/builtin/mcp/package.json +1 -1
- package/dist/builtin/subagents/package.json +1 -1
- package/dist/builtin/web-access/package.json +1 -1
- package/dist/builtin/workflows/CHANGELOG.md +26 -0
- package/dist/builtin/workflows/builtin/{chunk-zjecnjxx.js → chunk-6901nsd6.js} +1 -1
- package/dist/builtin/workflows/builtin/{chunk-k8d7ehjx.js → chunk-jvna28mq.js} +381 -130
- package/dist/builtin/workflows/builtin/{chunk-qxpymnaf.js → chunk-vwx023ge.js} +1 -1
- package/dist/builtin/workflows/builtin/goal.js +2 -2
- package/dist/builtin/workflows/builtin/index.js +3 -3
- package/dist/builtin/workflows/builtin/ralph.js +2 -2
- package/dist/builtin/workflows/package.json +1 -1
- package/dist/builtin/workflows/src/durable/journal/internal.d.ts +15 -1
- package/dist/builtin/workflows/src/durable/journal/sql-run-journal.d.ts +11 -0
- package/dist/builtin/workflows/src/extension/index.bundle.mjs +2457 -736
- package/dist/builtin/workflows/src/extension/local-worker-entry.mjs +2329 -730
- package/dist/builtin/workflows/src/index.js +2328 -730
- package/dist/builtin/workflows/src/local-worker-entry.mjs +2329 -730
- package/dist/core/agent-session-custom-message-commit.d.ts.map +1 -1
- package/dist/core/agent-session-custom-message-commit.js +16 -0
- package/dist/core/agent-session-custom-message-commit.js.map +1 -1
- package/dist/core/storage/errors.d.ts +5 -1
- package/dist/core/storage/errors.d.ts.map +1 -1
- package/dist/core/storage/errors.js +8 -2
- package/dist/core/storage/errors.js.map +1 -1
- package/dist/core/storage/node-sqlite.d.ts +2 -1
- package/dist/core/storage/node-sqlite.d.ts.map +1 -1
- package/dist/core/storage/node-sqlite.js +213 -20
- package/dist/core/storage/node-sqlite.js.map +1 -1
- package/docs/intercom/reference.md +2 -0
- package/docs/workflows/operations.md +1 -1
- package/npm-shrinkwrap.json +32 -32
- package/package.json +3 -3
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent-session-custom-message-commit.d.ts","sourceRoot":"","sources":["../../src/core/agent-session-custom-message-commit.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,2BAA2B,IAAI,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAQ9F,OAAO,KAAK,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AACrF,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"agent-session-custom-message-commit.d.ts","sourceRoot":"","sources":["../../src/core/agent-session-custom-message-commit.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,2BAA2B,IAAI,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAQ9F,OAAO,KAAK,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AACrF,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAgFnD,6EAA6E;AAC7E,wBAAsB,2BAA2B,CAAC,CAAC,EAClD,OAAO,EAAE,YAAY,EACrB,UAAU,EAAE,aAAa,CAAC,CAAC,CAAC,EAC5B,OAAO,CAAC,EAAE,kBAAkB,GAC1B,OAAO,CAAC,IAAI,CAAC,CAgHf;AAED,wBAAgB,4BAA4B,CAAC,CAAC,EAC7C,IAAI,EAAE,YAAY,EAClB,UAAU,EAAE,aAAa,CAAC,CAAC,CAAC,EAC5B,OAAO,CAAC,EAAE,kBAAkB,GAC1B,OAAO,CAAC,IAAI,CAAC,CAEf;AAED,+EAA+E;AAC/E,wBAAsB,4BAA4B,CAAC,CAAC,EACnD,OAAO,EAAE,YAAY,EACrB,WAAW,EAAE,aAAa,CAAC,CAAC,CAAC,EAAE,EAC/B,OAAO,CAAC,EAAE,mBAAmB,GAC3B,OAAO,CAAC,IAAI,CAAC,CA4Df;AAED,wBAAgB,6BAA6B,CAAC,CAAC,EAC9C,IAAI,EAAE,YAAY,EAClB,WAAW,EAAE,aAAa,CAAC,CAAC,CAAC,EAAE,EAC/B,OAAO,CAAC,EAAE,mBAAmB,GAC3B,OAAO,CAAC,IAAI,CAAC,CAEf;AAED,eAAO,MAAM,sCAAsC;;;CAGlD,CAAC"}
|
|
@@ -52,6 +52,20 @@ function queuesBehindFirstStagePrompt(session, options) {
|
|
|
52
52
|
options.deliverAs !== "nextTurn" &&
|
|
53
53
|
options.deliverAs !== "interrupt");
|
|
54
54
|
}
|
|
55
|
+
/**
|
|
56
|
+
* A protected delivery accepted while queued input is paused writes its durable card before it queues the hidden
|
|
57
|
+
* turn. A resume during that write releases a hold that does not contain it yet and reports no released work, so
|
|
58
|
+
* nothing would ever start the turn. Start it here, as an idle delivery after the resume would have.
|
|
59
|
+
*/
|
|
60
|
+
function startTurnIfPauseReleasedDuringAdmission(session, starter) {
|
|
61
|
+
if (session._queuedMessagesPaused || session._subagentPolicy?.executionEnded !== undefined)
|
|
62
|
+
return;
|
|
63
|
+
if (session.isStreaming || session._isPreparingRun || session._activePromptCount > 0)
|
|
64
|
+
return;
|
|
65
|
+
const turn = session._runAgentPrompt([], undefined, undefined, false, starter);
|
|
66
|
+
session._workflowStageAdmission?.trackAdmittedWork(turn);
|
|
67
|
+
void turn.catch(() => { });
|
|
68
|
+
}
|
|
55
69
|
/** Commit one delivery whose source generation already granted admission. */
|
|
56
70
|
export async function commitAdmittedCustomMessage(session, appMessage, options) {
|
|
57
71
|
const owner = resolveWorkflowStageDeliveryTarget(session);
|
|
@@ -91,6 +105,7 @@ export async function commitAdmittedCustomMessage(session, appMessage, options)
|
|
|
91
105
|
const delivery = options.deliverAs === "followUp" ? "followUp" : "steer";
|
|
92
106
|
if (useProtectedReconciliation) {
|
|
93
107
|
await queueProtectedStreamingCustomMessage(self, appMessage, delivery);
|
|
108
|
+
startTurnIfPauseReleasedDuringAdmission(self, appMessage);
|
|
94
109
|
}
|
|
95
110
|
else {
|
|
96
111
|
self._queueAgentMessage(appMessage, delivery);
|
|
@@ -197,6 +212,7 @@ export async function commitAdmittedCustomMessages(session, appMessages, options
|
|
|
197
212
|
if (options?.triggerTurn === true) {
|
|
198
213
|
if (useProtectedReconciliation) {
|
|
199
214
|
await queueProtectedStreamingCustomMessages(self, appMessages, delivery);
|
|
215
|
+
startTurnIfPauseReleasedDuringAdmission(self, appMessages[0]);
|
|
200
216
|
}
|
|
201
217
|
else {
|
|
202
218
|
for (const item of appMessages)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent-session-custom-message-commit.js","sourceRoot":"","sources":["../../src/core/agent-session-custom-message-commit.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kCAAkC,EAAE,MAAM,wCAAwC,CAAC;AAE5F,OAAO,EACN,oCAAoC,EACpC,oCAAoC,EACpC,qCAAqC,EACrC,uCAAuC,GACvC,MAAM,+CAA+C,CAAC;AACvD,OAAO,EAAE,wBAAwB,EAAE,MAAM,2BAA2B,CAAC;AAGrE,OAAO,EAAE,4BAA4B,EAAE,MAAM,uBAAuB,CAAC;AAErE,KAAK,UAAU,2BAA2B,CAAI,OAAqB,EAAE,OAAyB;IAC7F,MAAM,OAAO,CAAC,oBAAoB,CAAC,OAAO,CAAC,CAAC;AAC7C,CAAC;AAED,0FAA0F;AAC1F,KAAK,UAAU,qBAAqB,CAAC,OAAqB,EAAE,OAAsB;IACjF,OAAO,CAAC,yBAAyB,GAAG,IAAI,CAAC;IACzC,OAAO,CAAC,+BAA+B,EAAE,CAAC;IAC1C,IAAI,CAAC,OAAO,CAAC,qBAAqB,EAAE,CAAC;QACpC,OAAO,CAAC,UAAU,EAAE,CAAC;QACrB,OAAO,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;IACvB,CAAC;IACD,MAAM,oCAAoC,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC;IAC5E,IACC,CAAC,OAAO,CAAC,WAAW;QACpB,OAAO,CAAC,kBAAkB,KAAK,CAAC;QAChC,CAAC,OAAO,CAAC,qBAAqB;QAC9B,CAAC,OAAO,CAAC,yBAAyB,EACjC,CAAC;QACF,yEAAyE;QACzE,6DAA6D;QAC7D,MAAM,IAAI,GAAG,OAAO,CAAC,eAAe,CAAC,EAAE,EAAE,SAAS,EAAE,SAAS,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC;QAC/E,OAAO,CAAC,uBAAuB,EAAE,iBAAiB,CAAC,IAAI,CAAC,CAAC;QACzD,KAAK,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;IAC3B,CAAC;AACF,CAAC;AAED;;;;GAIG;AACH,SAAS,wBAAwB,CAChC,OAAqB,EACrB,OAAyB,EACzB,OAAuC;IAEvC,OAAO,CACN,OAAO,CAAC,iCAAiC;QACzC,OAAO,CAAC,kBAAkB,KAAK,CAAC;QAChC,CAAC,OAAO,CAAC,qBAAqB;QAC9B,OAAO,CAAC,UAAU,KAAK,4BAA4B;QACnD,OAAO,EAAE,WAAW,KAAK,IAAI;QAC7B,OAAO,CAAC,kBAAkB,KAAK,IAAI;QACnC,OAAO,CAAC,SAAS,KAAK,UAAU,CAChC,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,SAAS,4BAA4B,CAAC,OAAqB,EAAE,OAAuC;IACnG,OAAO,CACN,OAAO,CAAC,iCAAiC;QACzC,OAAO,CAAC,kBAAkB,GAAG,CAAC;QAC9B,CAAC,OAAO,CAAC,qBAAqB;QAC9B,OAAO,EAAE,WAAW,KAAK,IAAI;QAC7B,OAAO,CAAC,kBAAkB,KAAK,IAAI;QACnC,OAAO,CAAC,SAAS,KAAK,UAAU;QAChC,OAAO,CAAC,SAAS,KAAK,WAAW,CACjC,CAAC;AACH,CAAC;AAED,6EAA6E;AAC7E,MAAM,CAAC,KAAK,UAAU,2BAA2B,CAChD,OAAqB,EACrB,UAA4B,EAC5B,OAA4B;IAE5B,MAAM,KAAK,GAAG,kCAAkC,CAAC,OAAO,CAAC,CAAC;IAC1D,IAAI,KAAK,KAAK,OAAO;QAAE,OAAO,2BAA2B,CAAC,KAAK,EAAE,UAAU,EAAE,OAAO,CAAC,CAAC;IACtF,MAAM,IAAI,GAAG,OAAO,CAAC;IACrB,IAAI,wBAAwB,CAAC,IAAI,EAAE,UAAU,EAAE,OAAO,CAAC,EAAE,CAAC;QACzD,MAAM,2BAA2B,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;QACpD,OAAO;IACR,CAAC;IACD,MAAM,0BAA0B,GAC/B,OAAO,EAAE,oBAAoB,KAAK,IAAI;QACtC,OAAO,CAAC,kBAAkB,KAAK,IAAI;QACnC,CAAC,OAAO,CAAC,WAAW,KAAK,IAAI,IAAI,OAAO,CAAC,iBAAiB,KAAK,SAAS,CAAC,CAAC;IAC3E,IAAI,4BAA4B,CAAC,IAAI,EAAE,OAAO,CAAC,EAAE,CAAC;QACjD,MAAM,QAAQ,GAAG,OAAO,EAAE,SAAS,KAAK,UAAU,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,OAAO,CAAC;QAC1E,IAAI,0BAA0B;YAAE,MAAM,oCAAoC,CAAC,IAAI,EAAE,UAAU,EAAE,QAAQ,CAAC,CAAC;;YAClG,IAAI,CAAC,kBAAkB,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;QACnD,OAAO;IACR,CAAC;IACD,IACC,0BAA0B;QAC1B,OAAO,EAAE,WAAW;QACpB,OAAO,CAAC,SAAS,KAAK,WAAW;QACjC,CAAC,IAAI,CAAC,yBAAyB,IAAI,IAAI,CAAC,uBAAuB,CAAC,EAC/D,CAAC;QACF,MAAM,qBAAqB,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;QAC9C,OAAO;IACR,CAAC;IACD,IAAI,OAAO,EAAE,SAAS,KAAK,UAAU,EAAE,CAAC;QACvC,IAAI,CAAC,wBAAwB,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IAChD,CAAC;SAAM,IACN,IAAI,CAAC,qBAAqB;QAC1B,gFAAgF;QAChF,2EAA2E;QAC3E,CAAC,IAAI,CAAC,eAAe,EAAE,cAAc,KAAK,SAAS,IAAI,OAAO,EAAE,WAAW,IAAI,OAAO,CAAC,SAAS,KAAK,WAAW,CAAC,EAChH,CAAC;QACF,IAAI,OAAO,EAAE,WAAW,KAAK,IAAI,EAAE,CAAC;YACnC,MAAM,QAAQ,GAAG,OAAO,CAAC,SAAS,KAAK,UAAU,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,OAAO,CAAC;YACzE,IAAI,0BAA0B,EAAE,CAAC;gBAChC,MAAM,oCAAoC,CAAC,IAAI,EAAE,UAAU,EAAE,QAAQ,CAAC,CAAC;YACxE,CAAC;iBAAM,CAAC;gBACP,IAAI,CAAC,kBAAkB,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;YAC/C,CAAC;QACF,CAAC;aAAM,IAAI,IAAI,CAAC,WAAW,IAAI,IAAI,CAAC,eAAe,EAAE,CAAC;YACrD,IAAI,CAAC,sBAAsB,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QAC9C,CAAC;aAAM,CAAC;YACP,MAAM,2BAA2B,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;QACrD,CAAC;IACF,CAAC;SAAM,IAAI,OAAO,EAAE,SAAS,KAAK,WAAW,IAAI,OAAO,CAAC,WAAW,EAAE,CAAC;QACtE,MAAM,SAAS,GAAG,IAAI,CAAC,8BAA8B,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;QAC3E,IAAI,CAAC,uBAAuB,EAAE,iBAAiB,CAAC,SAAS,CAAC,CAAC;QAC3D,KAAK,SAAS,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;IAChC,CAAC;SAAM,IACN,CAAC,IAAI,CAAC,WAAW,IAAI,IAAI,CAAC,eAAe,CAAC;QAC1C,OAAO,EAAE,kBAAkB,KAAK,IAAI;QACpC,OAAO,CAAC,WAAW,KAAK,IAAI;QAC5B,OAAO,CAAC,SAAS,KAAK,SAAS,EAC9B,CAAC;QACF,MAAM,2BAA2B,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;IACrD,CAAC;SAAM,IAAI,CAAC,IAAI,CAAC,WAAW,IAAI,IAAI,CAAC,eAAe,CAAC,IAAI,OAAO,EAAE,WAAW,KAAK,KAAK,EAAE,CAAC;QACzF,IAAI,CAAC,sBAAsB,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IAC9C,CAAC;SAAM,IAAI,CAAC,IAAI,CAAC,WAAW,IAAI,IAAI,CAAC,eAAe,CAAC,IAAI,0BAA0B,EAAE,CAAC;QACrF,MAAM,oCAAoC,CACzC,IAAI,EACJ,UAAU,EACV,OAAO,EAAE,SAAS,KAAK,UAAU,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,OAAO,CACxD,CAAC;QACF,qEAAqE;QACrE,IAAI,CAAC,IAAI,CAAC,WAAW;YAAE,wBAAwB,CAAC,IAAI,CAAC,CAAC;IACvD,CAAC;SAAM,IAAI,CAAC,IAAI,CAAC,WAAW,IAAI,IAAI,CAAC,eAAe,CAAC,IAAI,OAAO,EAAE,oBAAoB,KAAK,IAAI,EAAE,CAAC;QACjG,MAAM,2BAA2B,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;IACrD,CAAC;SAAM,IAAI,CAAC,IAAI,CAAC,WAAW,IAAI,IAAI,CAAC,eAAe,CAAC,IAAI,OAAO,EAAE,WAAW,KAAK,KAAK,EAAE,CAAC;QACzF,IAAI,CAAC,kBAAkB,CAAC,UAAU,EAAE,OAAO,EAAE,SAAS,KAAK,UAAU,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;IAC/F,CAAC;SAAM,IAAI,0BAA0B,IAAI,OAAO,EAAE,WAAW,KAAK,IAAI,IAAI,IAAI,CAAC,uBAAuB,EAAE,CAAC;QACxG,MAAM,oCAAoC,CACzC,IAAI,EACJ,UAAU,EACV,OAAO,EAAE,SAAS,KAAK,UAAU,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,OAAO,CACxD,CAAC;QACF,MAAM,IAAI,GAAG,IAAI,CAAC,eAAe,CAAC,EAAE,EAAE,SAAS,EAAE,SAAS,EAAE,KAAK,EAAE,UAAU,CAAC,CAAC;QAC/E,IAAI,CAAC,uBAAuB,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC;QACrD,KAAK,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;IAC3B,CAAC;SAAM,IAAI,OAAO,EAAE,WAAW,EAAE,CAAC;QACjC,MAAM,aAAa,GAAG,0BAA0B;YAC/C,CAAC,CAAC,MAAM,oCAAoC,CAC1C,IAAI,EACJ,UAAU,EACV,OAAO,EAAE,SAAS,KAAK,UAAU,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,OAAO,CACxD;YACF,CAAC,CAAC,UAAU,CAAC;QACd,kEAAkE;QAClE,IAAI,0BAA0B,IAAI,CAAC,IAAI,CAAC,WAAW,IAAI,IAAI,CAAC,eAAe,CAAC,EAAE,CAAC;YAC9E,IAAI,CAAC,kBAAkB,CAAC,aAAa,EAAE,OAAO,CAAC,SAAS,KAAK,UAAU,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;YAChG,OAAO;QACR,CAAC;QACD,IAAI,gBAA6B,CAAC;QAClC,MAAM,SAAS,GAAG,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE;YAC/C,gBAAgB,GAAG,OAAO,CAAC;QAC5B,CAAC,CAAC,CAAC;QACH,MAAM,IAAI,GAAG,IAAI,CAAC,eAAe,CAAC,aAAa,EAAE,gBAAgB,CAAC,CAAC;QACnE,IAAI,CAAC;YACJ,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC,CAAC;QACvC,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YAChB,IAAI,CAAC,0BAA0B;gBAAE,MAAM,KAAK,CAAC;YAC7C,qEAAqE;YACrE,sEAAsE;YACtE,IAAI,CAAC,kBAAkB,CAAC,aAAa,EAAE,OAAO,EAAE,SAAS,KAAK,UAAU,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;YACjG,KAAK,IAAI,CAAC,4BAA4B,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;QAC1D,CAAC;IACF,CAAC;SAAM,CAAC;QACP,MAAM,2BAA2B,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;IACrD,CAAC;AACF,CAAC;AAED,MAAM,UAAU,4BAA4B,CAE3C,UAA4B,EAC5B,OAA4B;IAE5B,OAAO,2BAA2B,CAAC,IAAI,EAAE,UAAU,EAAE,OAAO,CAAC,CAAC;AAC/D,CAAC;AAED,+EAA+E;AAC/E,MAAM,CAAC,KAAK,UAAU,4BAA4B,CACjD,OAAqB,EACrB,WAA+B,EAC/B,OAA6B;IAE7B,MAAM,KAAK,GAAG,kCAAkC,CAAC,OAAO,CAAC,CAAC;IAC1D,IAAI,KAAK,KAAK,OAAO;QAAE,OAAO,4BAA4B,CAAC,KAAK,EAAE,WAAW,EAAE,OAAO,CAAC,CAAC;IACxF,MAAM,IAAI,GAAG,OAAO,CAAC;IACrB,IAAI,WAAW,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,wBAAwB,CAAC,IAAI,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC,EAAE,CAAC;QAChF,KAAK,MAAM,IAAI,IAAI,WAAW;YAAE,MAAM,2BAA2B,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;QAC9E,OAAO;IACR,CAAC;IACD,MAAM,0BAA0B,GAC/B,OAAO,EAAE,oBAAoB,KAAK,IAAI,IAAI,OAAO,CAAC,WAAW,KAAK,IAAI,IAAI,OAAO,CAAC,kBAAkB,KAAK,IAAI,CAAC;IAC/G,MAAM,QAAQ,GAAG,OAAO,EAAE,SAAS,KAAK,UAAU,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,OAAO,CAAC;IAC1E,IAAI,4BAA4B,CAAC,IAAI,EAAE,OAAO,CAAC,EAAE,CAAC;QACjD,IAAI,0BAA0B;YAAE,MAAM,qCAAqC,CAAC,IAAI,EAAE,WAAW,EAAE,QAAQ,CAAC,CAAC;;YACpG,KAAK,MAAM,IAAI,IAAI,WAAW;gBAAE,IAAI,CAAC,kBAAkB,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;QAC7E,OAAO;IACR,CAAC;IACD,IAAI,OAAO,EAAE,SAAS,KAAK,UAAU,EAAE,CAAC;QACvC,IAAI,CAAC,wBAAwB,CAAC,IAAI,CAAC,GAAG,WAAW,CAAC,CAAC;IACpD,CAAC;SAAM,IACN,IAAI,CAAC,qBAAqB;QAC1B,CAAC,IAAI,CAAC,eAAe,EAAE,cAAc,KAAK,SAAS,IAAI,OAAO,EAAE,WAAW,CAAC,EAC3E,CAAC;QACF,IAAI,OAAO,EAAE,WAAW,KAAK,IAAI,EAAE,CAAC;YACnC,IAAI,0BAA0B,EAAE,CAAC;gBAChC,MAAM,qCAAqC,CAAC,IAAI,EAAE,WAAW,EAAE,QAAQ,CAAC,CAAC;YAC1E,CAAC;iBAAM,CAAC;gBACP,KAAK,MAAM,IAAI,IAAI,WAAW;oBAAE,IAAI,CAAC,kBAAkB,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;YACzE,CAAC;QACF,CAAC;aAAM,IAAI,IAAI,CAAC,WAAW,IAAI,IAAI,CAAC,eAAe,EAAE,CAAC;YACrD,IAAI,CAAC,sBAAsB,CAAC,IAAI,CAAC,GAAG,WAAW,CAAC,CAAC;QAClD,CAAC;aAAM,CAAC;YACP,KAAK,MAAM,IAAI,IAAI,WAAW;gBAAE,MAAM,IAAI,CAAC,oBAAoB,CAAC,IAAI,CAAC,CAAC;QACvE,CAAC;IACF,CAAC;SAAM,IACN,CAAC,IAAI,CAAC,WAAW,IAAI,IAAI,CAAC,eAAe,CAAC;QAC1C,OAAO,EAAE,kBAAkB,KAAK,IAAI;QACpC,OAAO,CAAC,WAAW,KAAK,IAAI;QAC5B,OAAO,CAAC,SAAS,KAAK,SAAS,EAC9B,CAAC;QACF,KAAK,MAAM,IAAI,IAAI,WAAW;YAAE,MAAM,IAAI,CAAC,oBAAoB,CAAC,IAAI,CAAC,CAAC;IACvE,CAAC;SAAM,IAAI,CAAC,IAAI,CAAC,WAAW,IAAI,IAAI,CAAC,eAAe,CAAC,IAAI,OAAO,EAAE,WAAW,KAAK,KAAK,EAAE,CAAC;QACzF,IAAI,CAAC,sBAAsB,CAAC,IAAI,CAAC,GAAG,WAAW,CAAC,CAAC;IAClD,CAAC;SAAM,IAAI,CAAC,IAAI,CAAC,WAAW,IAAI,IAAI,CAAC,eAAe,CAAC,IAAI,0BAA0B,EAAE,CAAC;QACrF,MAAM,qCAAqC,CAAC,IAAI,EAAE,WAAW,EAAE,QAAQ,CAAC,CAAC;QACzE,IAAI,CAAC,IAAI,CAAC,WAAW;YAAE,wBAAwB,CAAC,IAAI,CAAC,CAAC;IACvD,CAAC;SAAM,IAAI,CAAC,IAAI,CAAC,WAAW,IAAI,IAAI,CAAC,eAAe,CAAC,IAAI,OAAO,EAAE,oBAAoB,KAAK,IAAI,EAAE,CAAC;QACjG,KAAK,MAAM,IAAI,IAAI,WAAW;YAAE,MAAM,IAAI,CAAC,oBAAoB,CAAC,IAAI,CAAC,CAAC;IACvE,CAAC;SAAM,IAAI,CAAC,IAAI,CAAC,WAAW,IAAI,IAAI,CAAC,eAAe,CAAC,IAAI,OAAO,EAAE,WAAW,KAAK,KAAK,EAAE,CAAC;QACzF,KAAK,MAAM,IAAI,IAAI,WAAW;YAAE,IAAI,CAAC,kBAAkB,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;IACzE,CAAC;SAAM,IAAI,OAAO,EAAE,WAAW,EAAE,CAAC;QACjC,IAAI,0BAA0B,EAAE,CAAC;YAChC,MAAM,uCAAuC,CAAC,IAAI,EAAE,WAAW,EAAE,QAAQ,CAAC,CAAC;QAC5E,CAAC;aAAM,CAAC;YACP,MAAM,IAAI,GAAG,IAAI,CAAC,eAAe,CAAC,WAAW,CAAC,CAAC;YAC/C,KAAK,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;QAC3B,CAAC;IACF,CAAC;SAAM,CAAC;QACP,KAAK,MAAM,IAAI,IAAI,WAAW;YAAE,MAAM,IAAI,CAAC,oBAAoB,CAAC,IAAI,CAAC,CAAC;IACvE,CAAC;AACF,CAAC;AAED,MAAM,UAAU,6BAA6B,CAE5C,WAA+B,EAC/B,OAA6B;IAE7B,OAAO,4BAA4B,CAAC,IAAI,EAAE,WAAW,EAAE,OAAO,CAAC,CAAC;AACjE,CAAC;AAED,MAAM,CAAC,MAAM,sCAAsC,GAAG;IACrD,4BAA4B;IAC5B,6BAA6B;CAC7B,CAAC","sourcesContent":["import { resolveWorkflowStageDeliveryTarget } from \"./agent-session-delivery-forwarding.ts\";\nimport type { AgentSessionInternalSurface as AgentSession } from \"./agent-session-methods.ts\";\nimport {\n\tadmitProtectedStreamingCustomMessage,\n\tqueueProtectedStreamingCustomMessage,\n\tqueueProtectedStreamingCustomMessages,\n\ttriggerProtectedStreamingCustomMessages,\n} from \"./agent-session-persistent-custom-messages.ts\";\nimport { deliverQueuedInputIfIdle } from \"./agent-session-prompt.ts\";\nimport type { SendMessageOptions, SendMessagesOptions } from \"./extensions/index.js\";\nimport type { CustomMessage } from \"./messages.ts\";\nimport { TASK_COMPLETION_MESSAGE_TYPE } from \"./tasks/completion.js\";\n\nasync function appendDurableStageAdmission<T>(session: AgentSession, message: CustomMessage<T>): Promise<void> {\n\tawait session._appendCustomMessage(message);\n}\n\n/** Cancel only the receiver's native operation; its original prompt owns continuation. */\nasync function commitPriorityMessage(session: AgentSession, message: CustomMessage): Promise<void> {\n\tsession._priorityInterruptPending = true;\n\tsession._ensureActiveInterruptQueueHold();\n\tif (!session._queuedMessagesPaused) {\n\t\tsession.abortRetry();\n\t\tsession.agent.abort();\n\t}\n\tawait queueProtectedStreamingCustomMessage(session, message, \"steer\", true);\n\tif (\n\t\t!session.isStreaming &&\n\t\tsession._activePromptCount === 0 &&\n\t\t!session._queuedMessagesPaused &&\n\t\t!session._subagentMessageAdmission\n\t) {\n\t\t// Idle stage chat has no original prompt awaiter. Start one owned drain,\n\t\t// without replaying the stage task or a completed tool call.\n\t\tconst turn = session._runAgentPrompt([], undefined, undefined, false, message);\n\t\tsession._workflowStageAdmission?.trackAdmittedWork(turn);\n\t\tvoid turn.catch(() => {});\n\t}\n}\n\n/**\n * #3919: before a fresh stage's own prompt is submitted, turn-starting input is that prompt's startup context.\n * Once the prompt is in preflight, a run has started, or queued input is paused, the ordinary admission paths\n * own ordering. The stage's own task completions follow its own work, so they never precede its prompt.\n */\nfunction holdsForFirstStagePrompt<T>(\n\tsession: AgentSession,\n\tmessage: CustomMessage<T>,\n\toptions: SendMessageOptions | undefined,\n): boolean {\n\treturn (\n\t\tsession._workflowStageAwaitingFirstPrompt &&\n\t\tsession._activePromptCount === 0 &&\n\t\t!session._queuedMessagesPaused &&\n\t\tmessage.customType !== TASK_COMPLETION_MESSAGE_TYPE &&\n\t\toptions?.triggerTurn === true &&\n\t\toptions.excludeFromContext !== true &&\n\t\toptions.deliverAs !== \"nextTurn\"\n\t);\n}\n\n/**\n * #3919: once the stage prompt is submitted but before it owns a run (its input hooks), a turn-starting\n * message must not start a competing turn. It queues behind the pending prompt; interrupts keep their own path.\n */\nfunction queuesBehindFirstStagePrompt(session: AgentSession, options: SendMessageOptions | undefined): boolean {\n\treturn (\n\t\tsession._workflowStageAwaitingFirstPrompt &&\n\t\tsession._activePromptCount > 0 &&\n\t\t!session._queuedMessagesPaused &&\n\t\toptions?.triggerTurn === true &&\n\t\toptions.excludeFromContext !== true &&\n\t\toptions.deliverAs !== \"nextTurn\" &&\n\t\toptions.deliverAs !== \"interrupt\"\n\t);\n}\n\n/** Commit one delivery whose source generation already granted admission. */\nexport async function commitAdmittedCustomMessage<T>(\n\tsession: AgentSession,\n\tappMessage: CustomMessage<T>,\n\toptions?: SendMessageOptions,\n): Promise<void> {\n\tconst owner = resolveWorkflowStageDeliveryTarget(session);\n\tif (owner !== session) return commitAdmittedCustomMessage(owner, appMessage, options);\n\tconst self = session;\n\tif (holdsForFirstStagePrompt(self, appMessage, options)) {\n\t\tawait appendDurableStageAdmission(self, appMessage);\n\t\treturn;\n\t}\n\tconst useProtectedReconciliation =\n\t\toptions?.persistWhenStreaming === true &&\n\t\toptions.excludeFromContext !== true &&\n\t\t(options.triggerTurn === true || options.stageAdmissionKey !== undefined);\n\tif (queuesBehindFirstStagePrompt(self, options)) {\n\t\tconst delivery = options?.deliverAs === \"followUp\" ? \"followUp\" : \"steer\";\n\t\tif (useProtectedReconciliation) await queueProtectedStreamingCustomMessage(self, appMessage, delivery);\n\t\telse self._queueAgentMessage(appMessage, delivery);\n\t\treturn;\n\t}\n\tif (\n\t\tuseProtectedReconciliation &&\n\t\toptions?.triggerTurn &&\n\t\toptions.deliverAs === \"interrupt\" &&\n\t\t(self._subagentMessageAdmission || self._workflowStageAdmission)\n\t) {\n\t\tawait commitPriorityMessage(self, appMessage);\n\t\treturn;\n\t}\n\tif (options?.deliverAs === \"nextTurn\") {\n\t\tself._pendingNextTurnMessages.push(appMessage);\n\t} else if (\n\t\tself._queuedMessagesPaused ||\n\t\t// A child has one host-owned task prompt, including its asynchronous preflight.\n\t\t// Inbound context joins that execution; an idle SDK gap is not a new task.\n\t\t(self._subagentPolicy?.executionEnded !== undefined && options?.triggerTurn && options.deliverAs !== \"interrupt\")\n\t) {\n\t\tif (options?.triggerTurn === true) {\n\t\t\tconst delivery = options.deliverAs === \"followUp\" ? \"followUp\" : \"steer\";\n\t\t\tif (useProtectedReconciliation) {\n\t\t\t\tawait queueProtectedStreamingCustomMessage(self, appMessage, delivery);\n\t\t\t} else {\n\t\t\t\tself._queueAgentMessage(appMessage, delivery);\n\t\t\t}\n\t\t} else if (self.isStreaming || self._isPreparingRun) {\n\t\t\tself._pendingCustomMessages.push(appMessage);\n\t\t} else {\n\t\t\tawait appendDurableStageAdmission(self, appMessage);\n\t\t}\n\t} else if (options?.deliverAs === \"interrupt\" && options.triggerTurn) {\n\t\tconst interrupt = self._enqueueInterruptCustomMessage(appMessage, options);\n\t\tself._workflowStageAdmission?.trackAdmittedWork(interrupt);\n\t\tvoid interrupt.catch(() => {});\n\t} else if (\n\t\t(self.isStreaming || self._isPreparingRun) &&\n\t\toptions?.excludeFromContext === true &&\n\t\toptions.triggerTurn !== true &&\n\t\toptions.deliverAs === undefined\n\t) {\n\t\tawait appendDurableStageAdmission(self, appMessage);\n\t} else if ((self.isStreaming || self._isPreparingRun) && options?.triggerTurn === false) {\n\t\tself._pendingCustomMessages.push(appMessage);\n\t} else if ((self.isStreaming || self._isPreparingRun) && useProtectedReconciliation) {\n\t\tawait queueProtectedStreamingCustomMessage(\n\t\t\tself,\n\t\t\tappMessage,\n\t\t\toptions?.deliverAs === \"followUp\" ? \"followUp\" : \"steer\",\n\t\t);\n\t\t// The durable card append can yield past the run's last queue drain.\n\t\tif (!self.isStreaming) deliverQueuedInputIfIdle(self);\n\t} else if ((self.isStreaming || self._isPreparingRun) && options?.persistWhenStreaming === true) {\n\t\tawait appendDurableStageAdmission(self, appMessage);\n\t} else if ((self.isStreaming || self._isPreparingRun) && options?.triggerTurn !== false) {\n\t\tself._queueAgentMessage(appMessage, options?.deliverAs === \"followUp\" ? \"followUp\" : \"steer\");\n\t} else if (useProtectedReconciliation && options?.triggerTurn === true && self._workflowStageAdmission) {\n\t\tawait queueProtectedStreamingCustomMessage(\n\t\t\tself,\n\t\t\tappMessage,\n\t\t\toptions?.deliverAs === \"followUp\" ? \"followUp\" : \"steer\",\n\t\t);\n\t\tconst turn = self._runAgentPrompt([], undefined, undefined, false, appMessage);\n\t\tself._workflowStageAdmission.trackAdmittedWork(turn);\n\t\tvoid turn.catch(() => {});\n\t} else if (options?.triggerTurn) {\n\t\tconst promptMessage = useProtectedReconciliation\n\t\t\t? await admitProtectedStreamingCustomMessage(\n\t\t\t\t\tself,\n\t\t\t\t\tappMessage,\n\t\t\t\t\toptions?.deliverAs === \"followUp\" ? \"followUp\" : \"steer\",\n\t\t\t\t)\n\t\t\t: appMessage;\n\t\t// Durable admission may yield while another turn takes ownership.\n\t\tif (useProtectedReconciliation && (self.isStreaming || self._isPreparingRun)) {\n\t\t\tself._queueAgentMessage(promptMessage, options.deliverAs === \"followUp\" ? \"followUp\" : \"steer\");\n\t\t\treturn;\n\t\t}\n\t\tlet resolveAdmission!: () => void;\n\t\tconst admission = new Promise<void>((resolve) => {\n\t\t\tresolveAdmission = resolve;\n\t\t});\n\t\tconst turn = self._runAgentPrompt(promptMessage, resolveAdmission);\n\t\ttry {\n\t\t\tawait Promise.race([admission, turn]);\n\t\t} catch (error) {\n\t\t\tif (!useProtectedReconciliation) throw error;\n\t\t\t// The visible card is already durable. Retry only its hidden turn so\n\t\t\t// lifecycle delivery never appends a second card for this occurrence.\n\t\t\tself._queueAgentMessage(promptMessage, options?.deliverAs === \"followUp\" ? \"followUp\" : \"steer\");\n\t\t\tvoid self._continueQueuedAgentMessages().catch(() => {});\n\t\t}\n\t} else {\n\t\tawait appendDurableStageAdmission(self, appMessage);\n\t}\n}\n\nexport function _commitAdmittedCustomMessage<T>(\n\tthis: AgentSession,\n\tappMessage: CustomMessage<T>,\n\toptions?: SendMessageOptions,\n): Promise<void> {\n\treturn commitAdmittedCustomMessage(this, appMessage, options);\n}\n\n/** Commit a batch whose source generation already granted atomic admission. */\nexport async function commitAdmittedCustomMessages<T>(\n\tsession: AgentSession,\n\tappMessages: CustomMessage<T>[],\n\toptions?: SendMessagesOptions,\n): Promise<void> {\n\tconst owner = resolveWorkflowStageDeliveryTarget(session);\n\tif (owner !== session) return commitAdmittedCustomMessages(owner, appMessages, options);\n\tconst self = session;\n\tif (appMessages.every((item) => holdsForFirstStagePrompt(self, item, options))) {\n\t\tfor (const item of appMessages) await appendDurableStageAdmission(self, item);\n\t\treturn;\n\t}\n\tconst useProtectedReconciliation =\n\t\toptions?.persistWhenStreaming === true && options.triggerTurn === true && options.excludeFromContext !== true;\n\tconst delivery = options?.deliverAs === \"followUp\" ? \"followUp\" : \"steer\";\n\tif (queuesBehindFirstStagePrompt(self, options)) {\n\t\tif (useProtectedReconciliation) await queueProtectedStreamingCustomMessages(self, appMessages, delivery);\n\t\telse for (const item of appMessages) self._queueAgentMessage(item, delivery);\n\t\treturn;\n\t}\n\tif (options?.deliverAs === \"nextTurn\") {\n\t\tself._pendingNextTurnMessages.push(...appMessages);\n\t} else if (\n\t\tself._queuedMessagesPaused ||\n\t\t(self._subagentPolicy?.executionEnded !== undefined && options?.triggerTurn)\n\t) {\n\t\tif (options?.triggerTurn === true) {\n\t\t\tif (useProtectedReconciliation) {\n\t\t\t\tawait queueProtectedStreamingCustomMessages(self, appMessages, delivery);\n\t\t\t} else {\n\t\t\t\tfor (const item of appMessages) self._queueAgentMessage(item, delivery);\n\t\t\t}\n\t\t} else if (self.isStreaming || self._isPreparingRun) {\n\t\t\tself._pendingCustomMessages.push(...appMessages);\n\t\t} else {\n\t\t\tfor (const item of appMessages) await self._appendCustomMessage(item);\n\t\t}\n\t} else if (\n\t\t(self.isStreaming || self._isPreparingRun) &&\n\t\toptions?.excludeFromContext === true &&\n\t\toptions.triggerTurn !== true &&\n\t\toptions.deliverAs === undefined\n\t) {\n\t\tfor (const item of appMessages) await self._appendCustomMessage(item);\n\t} else if ((self.isStreaming || self._isPreparingRun) && options?.triggerTurn === false) {\n\t\tself._pendingCustomMessages.push(...appMessages);\n\t} else if ((self.isStreaming || self._isPreparingRun) && useProtectedReconciliation) {\n\t\tawait queueProtectedStreamingCustomMessages(self, appMessages, delivery);\n\t\tif (!self.isStreaming) deliverQueuedInputIfIdle(self);\n\t} else if ((self.isStreaming || self._isPreparingRun) && options?.persistWhenStreaming === true) {\n\t\tfor (const item of appMessages) await self._appendCustomMessage(item);\n\t} else if ((self.isStreaming || self._isPreparingRun) && options?.triggerTurn !== false) {\n\t\tfor (const item of appMessages) self._queueAgentMessage(item, delivery);\n\t} else if (options?.triggerTurn) {\n\t\tif (useProtectedReconciliation) {\n\t\t\tawait triggerProtectedStreamingCustomMessages(self, appMessages, delivery);\n\t\t} else {\n\t\t\tconst turn = self._runAgentPrompt(appMessages);\n\t\t\tvoid turn.catch(() => {});\n\t\t}\n\t} else {\n\t\tfor (const item of appMessages) await self._appendCustomMessage(item);\n\t}\n}\n\nexport function _commitAdmittedCustomMessages<T>(\n\tthis: AgentSession,\n\tappMessages: CustomMessage<T>[],\n\toptions?: SendMessagesOptions,\n): Promise<void> {\n\treturn commitAdmittedCustomMessages(this, appMessages, options);\n}\n\nexport const agentSessionCustomMessageCommitMethods = {\n\t_commitAdmittedCustomMessage,\n\t_commitAdmittedCustomMessages,\n};\n"]}
|
|
1
|
+
{"version":3,"file":"agent-session-custom-message-commit.js","sourceRoot":"","sources":["../../src/core/agent-session-custom-message-commit.ts"],"names":[],"mappings":"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","sourcesContent":["import { resolveWorkflowStageDeliveryTarget } from \"./agent-session-delivery-forwarding.ts\";\nimport type { AgentSessionInternalSurface as AgentSession } from \"./agent-session-methods.ts\";\nimport {\n\tadmitProtectedStreamingCustomMessage,\n\tqueueProtectedStreamingCustomMessage,\n\tqueueProtectedStreamingCustomMessages,\n\ttriggerProtectedStreamingCustomMessages,\n} from \"./agent-session-persistent-custom-messages.ts\";\nimport { deliverQueuedInputIfIdle } from \"./agent-session-prompt.ts\";\nimport type { SendMessageOptions, SendMessagesOptions } from \"./extensions/index.js\";\nimport type { CustomMessage } from \"./messages.ts\";\nimport { TASK_COMPLETION_MESSAGE_TYPE } from \"./tasks/completion.js\";\n\nasync function appendDurableStageAdmission<T>(session: AgentSession, message: CustomMessage<T>): Promise<void> {\n\tawait session._appendCustomMessage(message);\n}\n\n/** Cancel only the receiver's native operation; its original prompt owns continuation. */\nasync function commitPriorityMessage(session: AgentSession, message: CustomMessage): Promise<void> {\n\tsession._priorityInterruptPending = true;\n\tsession._ensureActiveInterruptQueueHold();\n\tif (!session._queuedMessagesPaused) {\n\t\tsession.abortRetry();\n\t\tsession.agent.abort();\n\t}\n\tawait queueProtectedStreamingCustomMessage(session, message, \"steer\", true);\n\tif (\n\t\t!session.isStreaming &&\n\t\tsession._activePromptCount === 0 &&\n\t\t!session._queuedMessagesPaused &&\n\t\t!session._subagentMessageAdmission\n\t) {\n\t\t// Idle stage chat has no original prompt awaiter. Start one owned drain,\n\t\t// without replaying the stage task or a completed tool call.\n\t\tconst turn = session._runAgentPrompt([], undefined, undefined, false, message);\n\t\tsession._workflowStageAdmission?.trackAdmittedWork(turn);\n\t\tvoid turn.catch(() => {});\n\t}\n}\n\n/**\n * #3919: before a fresh stage's own prompt is submitted, turn-starting input is that prompt's startup context.\n * Once the prompt is in preflight, a run has started, or queued input is paused, the ordinary admission paths\n * own ordering. The stage's own task completions follow its own work, so they never precede its prompt.\n */\nfunction holdsForFirstStagePrompt<T>(\n\tsession: AgentSession,\n\tmessage: CustomMessage<T>,\n\toptions: SendMessageOptions | undefined,\n): boolean {\n\treturn (\n\t\tsession._workflowStageAwaitingFirstPrompt &&\n\t\tsession._activePromptCount === 0 &&\n\t\t!session._queuedMessagesPaused &&\n\t\tmessage.customType !== TASK_COMPLETION_MESSAGE_TYPE &&\n\t\toptions?.triggerTurn === true &&\n\t\toptions.excludeFromContext !== true &&\n\t\toptions.deliverAs !== \"nextTurn\"\n\t);\n}\n\n/**\n * #3919: once the stage prompt is submitted but before it owns a run (its input hooks), a turn-starting\n * message must not start a competing turn. It queues behind the pending prompt; interrupts keep their own path.\n */\nfunction queuesBehindFirstStagePrompt(session: AgentSession, options: SendMessageOptions | undefined): boolean {\n\treturn (\n\t\tsession._workflowStageAwaitingFirstPrompt &&\n\t\tsession._activePromptCount > 0 &&\n\t\t!session._queuedMessagesPaused &&\n\t\toptions?.triggerTurn === true &&\n\t\toptions.excludeFromContext !== true &&\n\t\toptions.deliverAs !== \"nextTurn\" &&\n\t\toptions.deliverAs !== \"interrupt\"\n\t);\n}\n\n/**\n * A protected delivery accepted while queued input is paused writes its durable card before it queues the hidden\n * turn. A resume during that write releases a hold that does not contain it yet and reports no released work, so\n * nothing would ever start the turn. Start it here, as an idle delivery after the resume would have.\n */\nfunction startTurnIfPauseReleasedDuringAdmission(session: AgentSession, starter: CustomMessage): void {\n\tif (session._queuedMessagesPaused || session._subagentPolicy?.executionEnded !== undefined) return;\n\tif (session.isStreaming || session._isPreparingRun || session._activePromptCount > 0) return;\n\tconst turn = session._runAgentPrompt([], undefined, undefined, false, starter);\n\tsession._workflowStageAdmission?.trackAdmittedWork(turn);\n\tvoid turn.catch(() => {});\n}\n\n/** Commit one delivery whose source generation already granted admission. */\nexport async function commitAdmittedCustomMessage<T>(\n\tsession: AgentSession,\n\tappMessage: CustomMessage<T>,\n\toptions?: SendMessageOptions,\n): Promise<void> {\n\tconst owner = resolveWorkflowStageDeliveryTarget(session);\n\tif (owner !== session) return commitAdmittedCustomMessage(owner, appMessage, options);\n\tconst self = session;\n\tif (holdsForFirstStagePrompt(self, appMessage, options)) {\n\t\tawait appendDurableStageAdmission(self, appMessage);\n\t\treturn;\n\t}\n\tconst useProtectedReconciliation =\n\t\toptions?.persistWhenStreaming === true &&\n\t\toptions.excludeFromContext !== true &&\n\t\t(options.triggerTurn === true || options.stageAdmissionKey !== undefined);\n\tif (queuesBehindFirstStagePrompt(self, options)) {\n\t\tconst delivery = options?.deliverAs === \"followUp\" ? \"followUp\" : \"steer\";\n\t\tif (useProtectedReconciliation) await queueProtectedStreamingCustomMessage(self, appMessage, delivery);\n\t\telse self._queueAgentMessage(appMessage, delivery);\n\t\treturn;\n\t}\n\tif (\n\t\tuseProtectedReconciliation &&\n\t\toptions?.triggerTurn &&\n\t\toptions.deliverAs === \"interrupt\" &&\n\t\t(self._subagentMessageAdmission || self._workflowStageAdmission)\n\t) {\n\t\tawait commitPriorityMessage(self, appMessage);\n\t\treturn;\n\t}\n\tif (options?.deliverAs === \"nextTurn\") {\n\t\tself._pendingNextTurnMessages.push(appMessage);\n\t} else if (\n\t\tself._queuedMessagesPaused ||\n\t\t// A child has one host-owned task prompt, including its asynchronous preflight.\n\t\t// Inbound context joins that execution; an idle SDK gap is not a new task.\n\t\t(self._subagentPolicy?.executionEnded !== undefined && options?.triggerTurn && options.deliverAs !== \"interrupt\")\n\t) {\n\t\tif (options?.triggerTurn === true) {\n\t\t\tconst delivery = options.deliverAs === \"followUp\" ? \"followUp\" : \"steer\";\n\t\t\tif (useProtectedReconciliation) {\n\t\t\t\tawait queueProtectedStreamingCustomMessage(self, appMessage, delivery);\n\t\t\t\tstartTurnIfPauseReleasedDuringAdmission(self, appMessage);\n\t\t\t} else {\n\t\t\t\tself._queueAgentMessage(appMessage, delivery);\n\t\t\t}\n\t\t} else if (self.isStreaming || self._isPreparingRun) {\n\t\t\tself._pendingCustomMessages.push(appMessage);\n\t\t} else {\n\t\t\tawait appendDurableStageAdmission(self, appMessage);\n\t\t}\n\t} else if (options?.deliverAs === \"interrupt\" && options.triggerTurn) {\n\t\tconst interrupt = self._enqueueInterruptCustomMessage(appMessage, options);\n\t\tself._workflowStageAdmission?.trackAdmittedWork(interrupt);\n\t\tvoid interrupt.catch(() => {});\n\t} else if (\n\t\t(self.isStreaming || self._isPreparingRun) &&\n\t\toptions?.excludeFromContext === true &&\n\t\toptions.triggerTurn !== true &&\n\t\toptions.deliverAs === undefined\n\t) {\n\t\tawait appendDurableStageAdmission(self, appMessage);\n\t} else if ((self.isStreaming || self._isPreparingRun) && options?.triggerTurn === false) {\n\t\tself._pendingCustomMessages.push(appMessage);\n\t} else if ((self.isStreaming || self._isPreparingRun) && useProtectedReconciliation) {\n\t\tawait queueProtectedStreamingCustomMessage(\n\t\t\tself,\n\t\t\tappMessage,\n\t\t\toptions?.deliverAs === \"followUp\" ? \"followUp\" : \"steer\",\n\t\t);\n\t\t// The durable card append can yield past the run's last queue drain.\n\t\tif (!self.isStreaming) deliverQueuedInputIfIdle(self);\n\t} else if ((self.isStreaming || self._isPreparingRun) && options?.persistWhenStreaming === true) {\n\t\tawait appendDurableStageAdmission(self, appMessage);\n\t} else if ((self.isStreaming || self._isPreparingRun) && options?.triggerTurn !== false) {\n\t\tself._queueAgentMessage(appMessage, options?.deliverAs === \"followUp\" ? \"followUp\" : \"steer\");\n\t} else if (useProtectedReconciliation && options?.triggerTurn === true && self._workflowStageAdmission) {\n\t\tawait queueProtectedStreamingCustomMessage(\n\t\t\tself,\n\t\t\tappMessage,\n\t\t\toptions?.deliverAs === \"followUp\" ? \"followUp\" : \"steer\",\n\t\t);\n\t\tconst turn = self._runAgentPrompt([], undefined, undefined, false, appMessage);\n\t\tself._workflowStageAdmission.trackAdmittedWork(turn);\n\t\tvoid turn.catch(() => {});\n\t} else if (options?.triggerTurn) {\n\t\tconst promptMessage = useProtectedReconciliation\n\t\t\t? await admitProtectedStreamingCustomMessage(\n\t\t\t\t\tself,\n\t\t\t\t\tappMessage,\n\t\t\t\t\toptions?.deliverAs === \"followUp\" ? \"followUp\" : \"steer\",\n\t\t\t\t)\n\t\t\t: appMessage;\n\t\t// Durable admission may yield while another turn takes ownership.\n\t\tif (useProtectedReconciliation && (self.isStreaming || self._isPreparingRun)) {\n\t\t\tself._queueAgentMessage(promptMessage, options.deliverAs === \"followUp\" ? \"followUp\" : \"steer\");\n\t\t\treturn;\n\t\t}\n\t\tlet resolveAdmission!: () => void;\n\t\tconst admission = new Promise<void>((resolve) => {\n\t\t\tresolveAdmission = resolve;\n\t\t});\n\t\tconst turn = self._runAgentPrompt(promptMessage, resolveAdmission);\n\t\ttry {\n\t\t\tawait Promise.race([admission, turn]);\n\t\t} catch (error) {\n\t\t\tif (!useProtectedReconciliation) throw error;\n\t\t\t// The visible card is already durable. Retry only its hidden turn so\n\t\t\t// lifecycle delivery never appends a second card for this occurrence.\n\t\t\tself._queueAgentMessage(promptMessage, options?.deliverAs === \"followUp\" ? \"followUp\" : \"steer\");\n\t\t\tvoid self._continueQueuedAgentMessages().catch(() => {});\n\t\t}\n\t} else {\n\t\tawait appendDurableStageAdmission(self, appMessage);\n\t}\n}\n\nexport function _commitAdmittedCustomMessage<T>(\n\tthis: AgentSession,\n\tappMessage: CustomMessage<T>,\n\toptions?: SendMessageOptions,\n): Promise<void> {\n\treturn commitAdmittedCustomMessage(this, appMessage, options);\n}\n\n/** Commit a batch whose source generation already granted atomic admission. */\nexport async function commitAdmittedCustomMessages<T>(\n\tsession: AgentSession,\n\tappMessages: CustomMessage<T>[],\n\toptions?: SendMessagesOptions,\n): Promise<void> {\n\tconst owner = resolveWorkflowStageDeliveryTarget(session);\n\tif (owner !== session) return commitAdmittedCustomMessages(owner, appMessages, options);\n\tconst self = session;\n\tif (appMessages.every((item) => holdsForFirstStagePrompt(self, item, options))) {\n\t\tfor (const item of appMessages) await appendDurableStageAdmission(self, item);\n\t\treturn;\n\t}\n\tconst useProtectedReconciliation =\n\t\toptions?.persistWhenStreaming === true && options.triggerTurn === true && options.excludeFromContext !== true;\n\tconst delivery = options?.deliverAs === \"followUp\" ? \"followUp\" : \"steer\";\n\tif (queuesBehindFirstStagePrompt(self, options)) {\n\t\tif (useProtectedReconciliation) await queueProtectedStreamingCustomMessages(self, appMessages, delivery);\n\t\telse for (const item of appMessages) self._queueAgentMessage(item, delivery);\n\t\treturn;\n\t}\n\tif (options?.deliverAs === \"nextTurn\") {\n\t\tself._pendingNextTurnMessages.push(...appMessages);\n\t} else if (\n\t\tself._queuedMessagesPaused ||\n\t\t(self._subagentPolicy?.executionEnded !== undefined && options?.triggerTurn)\n\t) {\n\t\tif (options?.triggerTurn === true) {\n\t\t\tif (useProtectedReconciliation) {\n\t\t\t\tawait queueProtectedStreamingCustomMessages(self, appMessages, delivery);\n\t\t\t\tstartTurnIfPauseReleasedDuringAdmission(self, appMessages[0]!);\n\t\t\t} else {\n\t\t\t\tfor (const item of appMessages) self._queueAgentMessage(item, delivery);\n\t\t\t}\n\t\t} else if (self.isStreaming || self._isPreparingRun) {\n\t\t\tself._pendingCustomMessages.push(...appMessages);\n\t\t} else {\n\t\t\tfor (const item of appMessages) await self._appendCustomMessage(item);\n\t\t}\n\t} else if (\n\t\t(self.isStreaming || self._isPreparingRun) &&\n\t\toptions?.excludeFromContext === true &&\n\t\toptions.triggerTurn !== true &&\n\t\toptions.deliverAs === undefined\n\t) {\n\t\tfor (const item of appMessages) await self._appendCustomMessage(item);\n\t} else if ((self.isStreaming || self._isPreparingRun) && options?.triggerTurn === false) {\n\t\tself._pendingCustomMessages.push(...appMessages);\n\t} else if ((self.isStreaming || self._isPreparingRun) && useProtectedReconciliation) {\n\t\tawait queueProtectedStreamingCustomMessages(self, appMessages, delivery);\n\t\tif (!self.isStreaming) deliverQueuedInputIfIdle(self);\n\t} else if ((self.isStreaming || self._isPreparingRun) && options?.persistWhenStreaming === true) {\n\t\tfor (const item of appMessages) await self._appendCustomMessage(item);\n\t} else if ((self.isStreaming || self._isPreparingRun) && options?.triggerTurn !== false) {\n\t\tfor (const item of appMessages) self._queueAgentMessage(item, delivery);\n\t} else if (options?.triggerTurn) {\n\t\tif (useProtectedReconciliation) {\n\t\t\tawait triggerProtectedStreamingCustomMessages(self, appMessages, delivery);\n\t\t} else {\n\t\t\tconst turn = self._runAgentPrompt(appMessages);\n\t\t\tvoid turn.catch(() => {});\n\t\t}\n\t} else {\n\t\tfor (const item of appMessages) await self._appendCustomMessage(item);\n\t}\n}\n\nexport function _commitAdmittedCustomMessages<T>(\n\tthis: AgentSession,\n\tappMessages: CustomMessage<T>[],\n\toptions?: SendMessagesOptions,\n): Promise<void> {\n\treturn commitAdmittedCustomMessages(this, appMessages, options);\n}\n\nexport const agentSessionCustomMessageCommitMethods = {\n\t_commitAdmittedCustomMessage,\n\t_commitAdmittedCustomMessages,\n};\n"]}
|
|
@@ -8,7 +8,11 @@ export declare class StorageUnavailableError extends StorageError {
|
|
|
8
8
|
readonly adapter: string;
|
|
9
9
|
readonly location: string;
|
|
10
10
|
readonly cause: StorageFailureCause;
|
|
11
|
-
|
|
11
|
+
/**
|
|
12
|
+
* `detail` names the driver failure in the message: a worker or coordinator that relays only `message` across
|
|
13
|
+
* a process boundary keeps the reason. Adapters pass it only for causes that cannot carry credentials.
|
|
14
|
+
*/
|
|
15
|
+
constructor(descriptor: StorageDescriptor, cause: StorageFailureCause, detail?: string);
|
|
12
16
|
}
|
|
13
17
|
export declare class StoreClosedError extends StorageError {
|
|
14
18
|
readonly adapter: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../../src/core/storage/errors.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAEpE,MAAM,MAAM,mBAAmB,GAAG,MAAM,GAAG,WAAW,GAAG,OAAO,GAAG,MAAM,GAAG,SAAS,CAAC;AAEtF,qBAAa,YAAa,SAAQ,KAAK;IACtC,SAAiB,YAAY,CAAC,EAAE,mBAAmB,CAAC;IACpD,YAAY,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,YAAY,EAGlD;CACD;AAED,qBAAa,uBAAwB,SAAQ,YAAY;IACxD,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,SAAiB,KAAK,EAAE,mBAAmB,CAAC;IAC5C,YAAY,UAAU,EAAE,iBAAiB,EAAE,KAAK,EAAE,mBAAmB,
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../../src/core/storage/errors.ts"],"names":[],"mappings":"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"}
|
|
@@ -7,8 +7,14 @@ export class StorageError extends Error {
|
|
|
7
7
|
export class StorageUnavailableError extends StorageError {
|
|
8
8
|
adapter;
|
|
9
9
|
location;
|
|
10
|
-
|
|
11
|
-
|
|
10
|
+
/**
|
|
11
|
+
* `detail` names the driver failure in the message: a worker or coordinator that relays only `message` across
|
|
12
|
+
* a process boundary keeps the reason. Adapters pass it only for causes that cannot carry credentials.
|
|
13
|
+
*/
|
|
14
|
+
constructor(descriptor, cause, detail) {
|
|
15
|
+
super(`Storage unavailable: ${descriptor.adapter} at ${descriptor.location}${detail ? `: ${detail}` : ""}`, {
|
|
16
|
+
cause,
|
|
17
|
+
});
|
|
12
18
|
this.adapter = descriptor.adapter;
|
|
13
19
|
this.location = descriptor.location;
|
|
14
20
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../../src/core/storage/errors.ts"],"names":[],"mappings":"AAIA,MAAM,OAAO,YAAa,SAAQ,KAAK;IAEtC,YAAY,OAAe,EAAE,OAAsB;QAClD,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QACxB,IAAI,CAAC,IAAI,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC;IAC7B,CAAC;CACD;AAED,MAAM,OAAO,uBAAwB,SAAQ,YAAY;IAC/C,OAAO,CAAS;IAChB,QAAQ,CAAS;IAE1B,YAAY,UAA6B,EAAE,KAA0B;
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../../src/core/storage/errors.ts"],"names":[],"mappings":"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","sourcesContent":["import type { SqliteValue, StorageDescriptor } from \"./database.js\";\n\nexport type StorageFailureCause = object | SqliteValue | boolean | symbol | undefined;\n\nexport class StorageError extends Error {\n\tdeclare readonly cleanupCause?: StorageFailureCause;\n\tconstructor(message: string, options?: ErrorOptions) {\n\t\tsuper(message, options);\n\t\tthis.name = new.target.name;\n\t}\n}\n\nexport class StorageUnavailableError extends StorageError {\n\treadonly adapter: string;\n\treadonly location: string;\n\tdeclare readonly cause: StorageFailureCause;\n\t/**\n\t * `detail` names the driver failure in the message: a worker or coordinator that relays only `message` across\n\t * a process boundary keeps the reason. Adapters pass it only for causes that cannot carry credentials.\n\t */\n\tconstructor(descriptor: StorageDescriptor, cause: StorageFailureCause, detail?: string) {\n\t\tsuper(`Storage unavailable: ${descriptor.adapter} at ${descriptor.location}${detail ? `: ${detail}` : \"\"}`, {\n\t\t\tcause,\n\t\t});\n\t\tthis.adapter = descriptor.adapter;\n\t\tthis.location = descriptor.location;\n\t}\n}\n\nexport class StoreClosedError extends StorageError {\n\treadonly adapter: string;\n\treadonly location: string;\n\tconstructor(descriptor: StorageDescriptor) {\n\t\tsuper(`Storage closed: ${descriptor.adapter} at ${descriptor.location}`);\n\t\tthis.adapter = descriptor.adapter;\n\t\tthis.location = descriptor.location;\n\t}\n}\n\nexport class StorageTransactionClosedError extends StorageError {\n\tconstructor() {\n\t\tsuper(\"Storage transaction is closed\");\n\t}\n}\n\nexport class StorageRollbackError extends StorageError {\n\tdeclare readonly cause: StorageFailureCause;\n\treadonly rollbackCause: StorageFailureCause;\n\tconstructor(cause: StorageFailureCause, rollbackCause: StorageFailureCause) {\n\t\tsuper(\"Storage rollback failed\", { cause });\n\t\tthis.rollbackCause = rollbackCause;\n\t}\n}\n\nexport class StorageInvalidTextError extends StorageError {\n\treadonly parameterIndex: number;\n\treadonly reason = \"nul-character\";\n\tconstructor(parameterIndex: number) {\n\t\tsuper(`Storage parameter ${parameterIndex} contains a NUL character`);\n\t\tthis.parameterIndex = parameterIndex;\n\t}\n}\n\nexport class StorageSchemaVersionError extends StorageError {\n\treadonly domain: string;\n\treadonly found: SqliteValue;\n\treadonly supported: number;\n\tconstructor(domain: string, found: SqliteValue, supported: number) {\n\t\tsuper(`Unsupported ${domain} storage schema version`);\n\t\tthis.domain = domain;\n\t\tthis.found = found;\n\t\tthis.supported = supported;\n\t}\n}\n\nexport class StoragePrefixError extends StorageError {\n\treadonly prefix: string;\n\treadonly reason: \"pattern\" | \"reserved\";\n\tconstructor(prefix: string, reason: \"pattern\" | \"reserved\") {\n\t\tsuper(`Invalid storage prefix: ${reason}`);\n\t\tthis.prefix = prefix;\n\t\tthis.reason = reason;\n\t}\n}\n\nexport class StorageConfigError extends StorageError {\n\treadonly source: \"sdk\" | \"cli\" | \"env\" | \"settings\";\n\treadonly field: string;\n\treadonly reason: string;\n\tconstructor(source: \"sdk\" | \"cli\" | \"env\" | \"settings\", field: string, reason: string) {\n\t\tsuper(`Invalid storage configuration: ${field} (${reason})`);\n\t\tthis.source = source;\n\t\tthis.field = field;\n\t\tthis.reason = reason;\n\t}\n}\n\nexport class StorageAdapterLoadError extends StorageError {\n\treadonly module: string;\n\tdeclare readonly cause: StorageFailureCause;\n\tconstructor(module: string, cause: StorageFailureCause) {\n\t\tsuper(`Could not load storage adapter: ${module}`, { cause });\n\t\tthis.module = module;\n\t}\n}\n\nexport class StorageOutcomeUnknownError extends StorageError {\n\treadonly domain: string;\n\treadonly id: string;\n\treadonly key: string;\n\tconstructor(domain: string, id: string, key: string) {\n\t\tsuper(`Storage write outcome unknown: ${domain} ${id}`);\n\t\tthis.domain = domain;\n\t\tthis.id = id;\n\t\tthis.key = key;\n\t}\n}\n\nexport class StoragePayloadTooLargeError extends StorageError {\n\treadonly limitBytes: number;\n\treadonly actualBytes: number;\n\tconstructor(limitBytes: number, actualBytes: number) {\n\t\tsuper(\"Storage payload exceeds the backend limit\");\n\t\tthis.limitBytes = limitBytes;\n\t\tthis.actualBytes = actualBytes;\n\t}\n}\n"]}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import type { DatabaseSync } from "node:sqlite";
|
|
2
2
|
import type { SqliteDatabase } from "./database.js";
|
|
3
|
-
export declare function openNodeSqliteDatabase(path: string, { busyTimeoutMs, readOnly }?: {
|
|
3
|
+
export declare function openNodeSqliteDatabase(path: string, { busyTimeoutMs, lockWaitMs, readOnly, }?: {
|
|
4
4
|
busyTimeoutMs?: number;
|
|
5
|
+
lockWaitMs?: number;
|
|
5
6
|
readOnly?: boolean;
|
|
6
7
|
}): Promise<SqliteDatabase>;
|
|
7
8
|
export declare function wrapNodeSqliteDatabase(connection: DatabaseSync): SqliteDatabase;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"node-sqlite.d.ts","sourceRoot":"","sources":["../../../src/core/storage/node-sqlite.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,KAAK,EAAE,cAAc,EAA6D,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"node-sqlite.d.ts","sourceRoot":"","sources":["../../../src/core/storage/node-sqlite.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,KAAK,EAAE,cAAc,EAA6D,MAAM,eAAe,CAAC;AA2Z/G,wBAAsB,sBAAsB,CAC3C,IAAI,EAAE,MAAM,EACZ,EACC,aAAoB,EACpB,UAA6C,EAC7C,QAAgB,GAChB,GAAE;IAAE,aAAa,CAAC,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,OAAO,CAAA;CAAO,GACzE,OAAO,CAAC,cAAc,CAAC,CA2BzB;AAED,wBAAgB,sBAAsB,CAAC,UAAU,EAAE,YAAY,GAAG,cAAc,CAW/E"}
|
|
@@ -37,6 +37,27 @@ function snapshotParams(params) {
|
|
|
37
37
|
function finalizeReleasedStatements() {
|
|
38
38
|
globalThis.Bun?.gc(true);
|
|
39
39
|
}
|
|
40
|
+
/** Default for how long a transaction keeps retrying `BEGIN IMMEDIATE` while another connection holds the write lock. */
|
|
41
|
+
const DEFAULT_NODE_SQLITE_LOCK_WAIT_MS = 30_000;
|
|
42
|
+
const LOCK_RETRY_BASE_DELAY_MS = 5;
|
|
43
|
+
const LOCK_RETRY_MAX_DELAY_MS = 100;
|
|
44
|
+
/** Most transactions one group commit carries, so a batch cannot keep the write lock from other processes for long. */
|
|
45
|
+
const MAX_GROUP_COMMIT_TRANSACTIONS = 128;
|
|
46
|
+
/** SQLITE_BUSY, including its extended codes: another connection holds the lock this statement needs. */
|
|
47
|
+
function isSqliteBusy(cause) {
|
|
48
|
+
const code = cause?.errcode;
|
|
49
|
+
return typeof code === "number" && (code & 0xff) === 5;
|
|
50
|
+
}
|
|
51
|
+
/** The driver's own reason, kept in the error message so it survives relays that forward only `message`. */
|
|
52
|
+
function sqliteFailureDetail(cause) {
|
|
53
|
+
if (!(cause instanceof Error) || cause.message === "")
|
|
54
|
+
return undefined;
|
|
55
|
+
const code = cause.errcode;
|
|
56
|
+
return typeof code === "number" ? `${cause.message} (SQLite code ${code})` : cause.message;
|
|
57
|
+
}
|
|
58
|
+
function unavailable(descriptor, cause, detail = sqliteFailureDetail(cause)) {
|
|
59
|
+
return new StorageUnavailableError(descriptor, cause, detail);
|
|
60
|
+
}
|
|
40
61
|
function normalizeRow(row) {
|
|
41
62
|
return Object.fromEntries(Object.entries(row).map(([key, value]) => [
|
|
42
63
|
key,
|
|
@@ -53,12 +74,15 @@ class NodeSqliteDatabase {
|
|
|
53
74
|
descriptor;
|
|
54
75
|
connection;
|
|
55
76
|
tail = Promise.resolve();
|
|
77
|
+
openBatch;
|
|
56
78
|
closing = false;
|
|
57
79
|
closePromise;
|
|
58
80
|
executor;
|
|
59
81
|
ownsConnection;
|
|
60
82
|
transactionIdentity;
|
|
61
|
-
|
|
83
|
+
lockWaitMs;
|
|
84
|
+
constructor(connection, descriptor, ownsConnection = true, transactionIdentity = connection, lockWaitMs = DEFAULT_NODE_SQLITE_LOCK_WAIT_MS) {
|
|
85
|
+
this.lockWaitMs = lockWaitMs;
|
|
62
86
|
this.transactionIdentity = transactionIdentity;
|
|
63
87
|
this.ownsConnection = ownsConnection;
|
|
64
88
|
this.connection = connection;
|
|
@@ -70,7 +94,62 @@ class NodeSqliteDatabase {
|
|
|
70
94
|
return operation();
|
|
71
95
|
}
|
|
72
96
|
catch (cause) {
|
|
73
|
-
throw
|
|
97
|
+
throw unavailable(this.descriptor, cause);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* One non-blocking `BEGIN IMMEDIATE`. node:sqlite runs `busy_timeout` synchronously, so a lock held by another
|
|
102
|
+
* process would freeze this process's event loop for the whole timeout. The attempt runs with `busy_timeout=0`
|
|
103
|
+
* and the connection's own value is restored before returning or throwing, so single statements outside a
|
|
104
|
+
* transaction keep it. Callers reach this only through `enqueue` and the transaction gate, so nothing else runs
|
|
105
|
+
* on the connection in between.
|
|
106
|
+
*/
|
|
107
|
+
tryBegin() {
|
|
108
|
+
this.driver(() => {
|
|
109
|
+
const configured = Number(this.connection.prepare("PRAGMA busy_timeout").get()?.timeout ?? 0);
|
|
110
|
+
this.connection.exec("PRAGMA busy_timeout=0");
|
|
111
|
+
let began = false;
|
|
112
|
+
try {
|
|
113
|
+
this.connection.exec("BEGIN IMMEDIATE");
|
|
114
|
+
began = true;
|
|
115
|
+
}
|
|
116
|
+
finally {
|
|
117
|
+
try {
|
|
118
|
+
this.connection.exec(`PRAGMA busy_timeout=${configured}`);
|
|
119
|
+
}
|
|
120
|
+
catch (restoreFailure) {
|
|
121
|
+
// Never hand back a transaction on a connection whose lock wait is no longer the configured one.
|
|
122
|
+
if (began)
|
|
123
|
+
this.connection.exec("ROLLBACK");
|
|
124
|
+
// biome-ignore lint/correctness/noUnsafeFinally: a failed restore must replace the attempt's outcome.
|
|
125
|
+
throw restoreFailure;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Takes the write lock without blocking the event loop. Nothing has run yet when `BEGIN IMMEDIATE` reports
|
|
132
|
+
* SQLITE_BUSY, so the attempt is retried after a jittered timer until `lockWaitMs` has passed; every other
|
|
133
|
+
* failure, and a lock still held at the deadline, rejects at once with its cause.
|
|
134
|
+
*/
|
|
135
|
+
async begin() {
|
|
136
|
+
const started = Date.now();
|
|
137
|
+
for (let attempt = 0;; attempt += 1) {
|
|
138
|
+
try {
|
|
139
|
+
this.tryBegin();
|
|
140
|
+
return;
|
|
141
|
+
}
|
|
142
|
+
catch (error) {
|
|
143
|
+
const cause = error instanceof StorageUnavailableError ? error.cause : undefined;
|
|
144
|
+
if (!isSqliteBusy(cause))
|
|
145
|
+
throw error;
|
|
146
|
+
const remaining = started + this.lockWaitMs - Date.now();
|
|
147
|
+
if (remaining <= 0) {
|
|
148
|
+
throw unavailable(this.descriptor, cause, `${sqliteFailureDetail(cause)}; gave up after waiting ${Date.now() - started} ms for the write lock`);
|
|
149
|
+
}
|
|
150
|
+
const backoff = Math.min(LOCK_RETRY_MAX_DELAY_MS, LOCK_RETRY_BASE_DELAY_MS * 2 ** attempt);
|
|
151
|
+
await new Promise((resolve) => setTimeout(resolve, Math.min(remaining, backoff * (0.5 + Math.random() / 2))));
|
|
152
|
+
}
|
|
74
153
|
}
|
|
75
154
|
}
|
|
76
155
|
createExecutor(active) {
|
|
@@ -106,43 +185,157 @@ class NodeSqliteDatabase {
|
|
|
106
185
|
this.tail = result.then(() => { }, () => { });
|
|
107
186
|
return result;
|
|
108
187
|
}
|
|
188
|
+
/** A statement queued after open transactions runs after them, so later transactions start a new batch. */
|
|
189
|
+
enqueueStatement(operation) {
|
|
190
|
+
this.openBatch = undefined;
|
|
191
|
+
return this.enqueue(operation);
|
|
192
|
+
}
|
|
109
193
|
exec(sql) {
|
|
110
|
-
return this.
|
|
194
|
+
return this.enqueueStatement(() => this.executor.exec(sql));
|
|
111
195
|
}
|
|
112
196
|
run(sql, ...params) {
|
|
113
197
|
const bound = snapshotParams(params);
|
|
114
|
-
return this.
|
|
198
|
+
return this.enqueueStatement(() => this.executor.run(sql, ...bound));
|
|
115
199
|
}
|
|
116
200
|
get(sql, ...params) {
|
|
117
201
|
const bound = snapshotParams(params);
|
|
118
|
-
return this.
|
|
202
|
+
return this.enqueueStatement(() => this.executor.get(sql, ...bound));
|
|
119
203
|
}
|
|
120
204
|
all(sql, ...params) {
|
|
121
205
|
const bound = snapshotParams(params);
|
|
122
|
-
return this.
|
|
206
|
+
return this.enqueueStatement(() => this.executor.all(sql, ...bound));
|
|
123
207
|
}
|
|
208
|
+
/**
|
|
209
|
+
* Group commit: transactions queued while earlier work holds the connection join one `BEGIN IMMEDIATE … COMMIT`,
|
|
210
|
+
* each inside its own savepoint and in the order they were requested. A transaction that throws rolls back only
|
|
211
|
+
* its savepoint and rejects only its caller; every caller settles after the shared commit, so durability is the
|
|
212
|
+
* same as a transaction of its own. Under load one lock acquisition and one sync serve the whole batch.
|
|
213
|
+
*/
|
|
124
214
|
transaction(callback) {
|
|
125
|
-
|
|
126
|
-
|
|
215
|
+
if (this.closing)
|
|
216
|
+
return Promise.reject(new StoreClosedError(this.descriptor));
|
|
217
|
+
return new Promise((resolve, reject) => {
|
|
218
|
+
const queued = { callback, resolve: resolve, reject };
|
|
219
|
+
if (this.openBatch !== undefined && this.openBatch.length < MAX_GROUP_COMMIT_TRANSACTIONS) {
|
|
220
|
+
this.openBatch.push(queued);
|
|
221
|
+
return;
|
|
222
|
+
}
|
|
223
|
+
this.startBatch([queued]);
|
|
224
|
+
});
|
|
225
|
+
}
|
|
226
|
+
startBatch(batch) {
|
|
227
|
+
this.openBatch = batch;
|
|
228
|
+
void this.enqueue(() => this.commitBatch(batch));
|
|
229
|
+
}
|
|
230
|
+
commitBatch(batch) {
|
|
231
|
+
if (this.openBatch === batch)
|
|
232
|
+
this.openBatch = undefined;
|
|
233
|
+
return gateTransaction(this.transactionIdentity, () => batch.length === 1 ? this.commitAlone(batch[0]) : this.commitMembers(batch));
|
|
234
|
+
}
|
|
235
|
+
/** A transaction with nobody queued behind it commits on its own, without savepoints. */
|
|
236
|
+
async commitAlone(queued) {
|
|
237
|
+
try {
|
|
238
|
+
await this.begin();
|
|
239
|
+
}
|
|
240
|
+
catch (cause) {
|
|
241
|
+
queued.reject(cause);
|
|
242
|
+
return;
|
|
243
|
+
}
|
|
244
|
+
let active = true;
|
|
245
|
+
try {
|
|
246
|
+
const value = await queued.callback(this.createExecutor(() => active));
|
|
247
|
+
active = false;
|
|
248
|
+
await this.executor.exec("COMMIT");
|
|
249
|
+
queued.resolve(value);
|
|
250
|
+
}
|
|
251
|
+
catch (cause) {
|
|
252
|
+
active = false;
|
|
253
|
+
try {
|
|
254
|
+
await this.executor.exec("ROLLBACK");
|
|
255
|
+
}
|
|
256
|
+
catch (rollbackCause) {
|
|
257
|
+
queued.reject(new StorageRollbackError(cause, rollbackCause));
|
|
258
|
+
return;
|
|
259
|
+
}
|
|
260
|
+
queued.reject(cause);
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
async commitMembers(batch) {
|
|
264
|
+
try {
|
|
265
|
+
await this.begin();
|
|
266
|
+
}
|
|
267
|
+
catch (cause) {
|
|
268
|
+
for (const queued of batch)
|
|
269
|
+
queued.reject(cause);
|
|
270
|
+
return;
|
|
271
|
+
}
|
|
272
|
+
const outcomes = [];
|
|
273
|
+
for (const queued of batch) {
|
|
274
|
+
const savepoint = `atomic_group_${outcomes.length}`;
|
|
127
275
|
let active = true;
|
|
128
|
-
const transaction = this.createExecutor(() => active);
|
|
129
276
|
try {
|
|
130
|
-
|
|
277
|
+
await this.executor.exec(`SAVEPOINT ${savepoint}`);
|
|
278
|
+
const value = await queued.callback(this.createExecutor(() => active));
|
|
131
279
|
active = false;
|
|
132
|
-
await this.executor.exec(
|
|
133
|
-
|
|
280
|
+
await this.executor.exec(`RELEASE ${savepoint}`);
|
|
281
|
+
outcomes.push({ ok: true, value });
|
|
134
282
|
}
|
|
135
283
|
catch (cause) {
|
|
136
284
|
active = false;
|
|
137
285
|
try {
|
|
138
|
-
await this.executor.exec(
|
|
286
|
+
await this.executor.exec(`ROLLBACK TO ${savepoint}`);
|
|
287
|
+
await this.executor.exec(`RELEASE ${savepoint}`);
|
|
139
288
|
}
|
|
140
289
|
catch (rollbackCause) {
|
|
141
|
-
|
|
290
|
+
await this.abandonMembers(batch, outcomes, cause, rollbackCause);
|
|
291
|
+
return;
|
|
142
292
|
}
|
|
143
|
-
|
|
293
|
+
outcomes.push({ ok: false, error: cause });
|
|
144
294
|
}
|
|
145
|
-
}
|
|
295
|
+
}
|
|
296
|
+
try {
|
|
297
|
+
await this.executor.exec("COMMIT");
|
|
298
|
+
}
|
|
299
|
+
catch (commitCause) {
|
|
300
|
+
await this.rollbackQuietly();
|
|
301
|
+
batch.forEach((queued, index) => {
|
|
302
|
+
const outcome = outcomes[index];
|
|
303
|
+
queued.reject(outcome.ok ? commitCause : outcome.error);
|
|
304
|
+
});
|
|
305
|
+
return;
|
|
306
|
+
}
|
|
307
|
+
batch.forEach((queued, index) => {
|
|
308
|
+
const outcome = outcomes[index];
|
|
309
|
+
if (outcome.ok)
|
|
310
|
+
queued.resolve(outcome.value);
|
|
311
|
+
else
|
|
312
|
+
queued.reject(outcome.error);
|
|
313
|
+
});
|
|
314
|
+
}
|
|
315
|
+
/**
|
|
316
|
+
* A savepoint that cannot be rolled back leaves the whole transaction unusable: earlier members lose their
|
|
317
|
+
* uncommitted writes and fail, the failing member reports both causes, and members that have not run yet get a
|
|
318
|
+
* fresh transaction right away, still ahead of anything queued after them, because nothing of theirs has happened.
|
|
319
|
+
*/
|
|
320
|
+
async abandonMembers(batch, outcomes, cause, rollbackCause) {
|
|
321
|
+
await this.rollbackQuietly();
|
|
322
|
+
const failed = outcomes.length;
|
|
323
|
+
batch.slice(0, failed).forEach((queued, index) => {
|
|
324
|
+
const outcome = outcomes[index];
|
|
325
|
+
queued.reject(outcome.ok ? unavailable(this.descriptor, rollbackCause) : outcome.error);
|
|
326
|
+
});
|
|
327
|
+
batch[failed].reject(new StorageRollbackError(cause, rollbackCause));
|
|
328
|
+
const remaining = batch.slice(failed + 1);
|
|
329
|
+
if (remaining.length > 0)
|
|
330
|
+
await this.commitMembers(remaining);
|
|
331
|
+
}
|
|
332
|
+
async rollbackQuietly() {
|
|
333
|
+
try {
|
|
334
|
+
await this.executor.exec("ROLLBACK");
|
|
335
|
+
}
|
|
336
|
+
catch {
|
|
337
|
+
// SQLite already rolled the transaction back; there is nothing left to undo.
|
|
338
|
+
}
|
|
146
339
|
}
|
|
147
340
|
close() {
|
|
148
341
|
if (!this.closePromise) {
|
|
@@ -156,7 +349,7 @@ class NodeSqliteDatabase {
|
|
|
156
349
|
return this.closePromise;
|
|
157
350
|
}
|
|
158
351
|
}
|
|
159
|
-
export async function openNodeSqliteDatabase(path, { busyTimeoutMs = 5000, readOnly = false } = {}) {
|
|
352
|
+
export async function openNodeSqliteDatabase(path, { busyTimeoutMs = 5000, lockWaitMs = DEFAULT_NODE_SQLITE_LOCK_WAIT_MS, readOnly = false, } = {}) {
|
|
160
353
|
const descriptor = { adapter: "node-sqlite", location: path };
|
|
161
354
|
// Load node:sqlite on first open: importing it prints Node's experimental warning, which every importer of the
|
|
162
355
|
// package entry point would otherwise see.
|
|
@@ -177,7 +370,7 @@ export async function openNodeSqliteDatabase(path, { busyTimeoutMs = 5000, readO
|
|
|
177
370
|
connection.exec("PRAGMA journal_mode=WAL; PRAGMA synchronous=FULL; PRAGMA foreign_keys=ON");
|
|
178
371
|
const location = connection.location();
|
|
179
372
|
const identity = location === null ? connection : await realpath(location);
|
|
180
|
-
return new NodeSqliteDatabase(connection, descriptor, true, identity);
|
|
373
|
+
return new NodeSqliteDatabase(connection, descriptor, true, identity, lockWaitMs);
|
|
181
374
|
}
|
|
182
375
|
catch (cause) {
|
|
183
376
|
try {
|
|
@@ -186,7 +379,7 @@ export async function openNodeSqliteDatabase(path, { busyTimeoutMs = 5000, readO
|
|
|
186
379
|
catch {
|
|
187
380
|
// Preserve the opening failure if cleanup also fails.
|
|
188
381
|
}
|
|
189
|
-
throw
|
|
382
|
+
throw unavailable(descriptor, cause);
|
|
190
383
|
}
|
|
191
384
|
}
|
|
192
385
|
export function wrapNodeSqliteDatabase(connection) {
|
|
@@ -197,7 +390,7 @@ export function wrapNodeSqliteDatabase(connection) {
|
|
|
197
390
|
return new NodeSqliteDatabase(connection, descriptor, false);
|
|
198
391
|
}
|
|
199
392
|
catch (cause) {
|
|
200
|
-
throw
|
|
393
|
+
throw unavailable(descriptor, cause);
|
|
201
394
|
}
|
|
202
395
|
}
|
|
203
396
|
//# sourceMappingURL=node-sqlite.js.map
|