agents 0.26.0 → 0.28.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +8 -9
- package/dist/abortable-C1SpfVoi.js +21 -0
- package/dist/abortable-C1SpfVoi.js.map +1 -0
- package/dist/{agent-routing-0DR0Tk2v.d.ts → agent-routing-QDcchcQP.d.ts} +16 -16
- package/dist/agent-routing.d.ts +1 -1
- package/dist/agent-tool-types.d.ts +1 -1
- package/dist/{agent-tools-YrATZJu2.d.ts → agent-tools-DHL2XI7u.d.ts} +2 -2
- package/dist/agent-tools.d.ts +1 -1
- package/dist/ai-ahruGw7e.d.ts +239 -0
- package/dist/ai-sdk-Bdsf6mSA.js +2444 -0
- package/dist/ai-sdk-Bdsf6mSA.js.map +1 -0
- package/dist/apply-chunks-1FheRb9W.js +99 -0
- package/dist/apply-chunks-1FheRb9W.js.map +1 -0
- package/dist/broadcast-state-CEyI4uAK.js +69 -0
- package/dist/broadcast-state-CEyI4uAK.js.map +1 -0
- package/dist/browser/ai.d.ts +8 -227
- package/dist/browser/ai.js +259 -1
- package/dist/browser/ai.js.map +1 -0
- package/dist/browser/index.d.ts +56 -46
- package/dist/browser/index.js +4 -361
- package/dist/browser/{ai-sdk.d.ts → tools/ai-sdk.d.ts} +7 -7
- package/dist/browser/{ai-sdk.js → tools/ai-sdk.js} +6 -5
- package/dist/browser/tools/ai-sdk.js.map +1 -0
- package/dist/browser/tools/pi.d.ts +111 -0
- package/dist/browser/tools/pi.js +119 -0
- package/dist/browser/tools/pi.js.map +1 -0
- package/dist/browser/{tanstack-ai.d.ts → tools/tanstack-ai.d.ts} +39 -37
- package/dist/browser/{tanstack-ai.js → tools/tanstack-ai.js} +73 -59
- package/dist/browser/tools/tanstack-ai.js.map +1 -0
- package/dist/browser-CEdNlsaD.js +481 -0
- package/dist/browser-CEdNlsaD.js.map +1 -0
- package/dist/{browser-DE3d-RLk.d.ts → browser-D30VlpcA.d.ts} +63 -37
- package/dist/{browser-tool-CQ10e6Kj.js → browser-tool-4iomavs_.js} +198 -62
- package/dist/browser-tool-4iomavs_.js.map +1 -0
- package/dist/{browser-tool-DuNdlwZ9.d.ts → browser-tool-vtrPOV8e.d.ts} +25 -6
- package/dist/{capability-B4WbF81e.js → capability-DBAKc6UZ.js} +1 -3
- package/dist/capability-DBAKc6UZ.js.map +1 -0
- package/dist/{capability-runner-DBAnGr6L.d.ts → capability-runner-BiVUtjqC.d.ts} +9 -7
- package/dist/channel-Bak_6zDP.d.ts +333 -0
- package/dist/chat/index.d.ts +11 -9
- package/dist/chat/index.js +5 -194
- package/dist/chat/index.js.map +1 -1
- package/dist/chat/react.d.ts +2 -4
- package/dist/chat/react.js +3 -1
- package/dist/chat/react.js.map +1 -1
- package/dist/chat-sdk/index.d.ts +1 -1
- package/dist/chat-sdk/index.js +1 -1
- package/dist/cli.js +144 -0
- package/dist/{client-je3koD9Z.d.ts → client-BGIQKJhX.d.ts} +2 -2
- package/dist/{client-fyQrLGkD.js → client-BnYbNT3z.js} +29 -5
- package/dist/client-BnYbNT3z.js.map +1 -0
- package/dist/client-tools-aIBO0Fk7.d.ts +53 -0
- package/dist/client.d.ts +1 -1
- package/dist/{connector-58XDGvc3.js → connector-CtZylXdk.js} +3 -603
- package/dist/connector-CtZylXdk.js.map +1 -0
- package/dist/{connector-Cl-VqPmA.d.ts → connector-DEXzVoaY.d.ts} +9 -374
- package/dist/conversations-FjHDRZyD.d.ts +192 -0
- package/dist/{current-agent-vAk_5JMt.d.ts → current-agent-CKgT5d1O.d.ts} +3 -5
- package/dist/current-agent-DhoDkSnH.js.map +1 -1
- package/dist/daemon-core-Buubj-y1.js +481 -0
- package/dist/daemon-core-Buubj-y1.js.map +1 -0
- package/dist/daemon-core-CbohVPAu.d.ts +132 -0
- package/dist/{do-oauth-client-provider-Tmf1vgKz.d.ts → do-oauth-client-provider-DfsUcpc3.d.ts} +7 -1
- package/dist/{durable-object-lifecycle-HhgOMWq9.d.ts → durable-object-lifecycle-DOI_bzCH.d.ts} +2 -2
- package/dist/{channels/email.d.ts → experimental/channels/email/index.d.ts} +25 -12
- package/dist/{channels/email.js → experimental/channels/email/index.js} +13 -35
- package/dist/experimental/channels/email/index.js.map +1 -0
- package/dist/experimental/channels/index.d.ts +270 -0
- package/dist/experimental/channels/index.js +1186 -0
- package/dist/experimental/channels/index.js.map +1 -0
- package/dist/{channels/slack.d.ts → experimental/channels/slack/index.d.ts} +19 -9
- package/dist/experimental/channels/slack/index.js +267 -0
- package/dist/experimental/channels/slack/index.js.map +1 -0
- package/dist/{channels/telegram.d.ts → experimental/channels/telegram/index.d.ts} +19 -9
- package/dist/experimental/channels/telegram/index.js +198 -0
- package/dist/experimental/channels/telegram/index.js.map +1 -0
- package/dist/experimental/channels/web/ai-sdk.d.ts +55 -0
- package/dist/experimental/channels/web/ai-sdk.js +266 -0
- package/dist/experimental/channels/web/ai-sdk.js.map +1 -0
- package/dist/experimental/channels/web/client.d.ts +97 -0
- package/dist/experimental/channels/web/client.js +349 -0
- package/dist/experimental/channels/web/client.js.map +1 -0
- package/dist/experimental/channels/web/index.d.ts +189 -0
- package/dist/experimental/channels/web/index.js +332 -0
- package/dist/experimental/channels/web/index.js.map +1 -0
- package/dist/gateway-BFO6vRDn.d.ts +100 -0
- package/dist/handle-zAzh0UW2.d.ts +460 -0
- package/dist/harness/ai-sdk/index.d.ts +175 -0
- package/dist/harness/ai-sdk/index.js +605 -0
- package/dist/harness/ai-sdk/index.js.map +1 -0
- package/dist/harness/container/daemon/index.d.ts +76 -0
- package/dist/harness/container/daemon/index.js +3 -0
- package/dist/harness/container/index.d.ts +740 -0
- package/dist/harness/container/index.js +2152 -0
- package/dist/harness/container/index.js.map +1 -0
- package/dist/harness/container/runtime/index.d.ts +144 -0
- package/dist/harness/container/runtime/index.js +1082 -0
- package/dist/harness/container/runtime/index.js.map +1 -0
- package/dist/harness/opencode/index.d.ts +369 -0
- package/dist/harness/opencode/index.js +1072 -0
- package/dist/harness/opencode/index.js.map +1 -0
- package/dist/harness/pi/index.d.ts +3 -2
- package/dist/harness/pi/index.js +3 -3
- package/dist/harness/store/index.d.ts +24 -0
- package/dist/harness/store/index.js +2 -0
- package/dist/harness/think/index.d.ts +821 -0
- package/dist/harness/think/index.js +2721 -0
- package/dist/harness/think/index.js.map +1 -0
- package/dist/harness-B6B9S3rb.d.ts +203 -0
- package/dist/{images-iiTDSyRu.js → images-Ce9SCu3X.js} +2 -248
- package/dist/images-Ce9SCu3X.js.map +1 -0
- package/dist/{index-BreL0YrQ.d.ts → index-BEL3ZV-s.d.ts} +2 -6
- package/dist/index-CBt8oRJt.d.ts +198 -0
- package/dist/index.d.ts +5 -5
- package/dist/index.js +2 -2
- package/dist/ingress-EFbrS547.js +9 -0
- package/dist/ingress-EFbrS547.js.map +1 -0
- package/dist/input-schema-BQykTEp_.js +20 -0
- package/dist/input-schema-BQykTEp_.js.map +1 -0
- package/dist/input-schema-D2QAtHZH.js +23 -0
- package/dist/input-schema-D2QAtHZH.js.map +1 -0
- package/dist/internal-kmw70xwR.js +46 -0
- package/dist/internal-kmw70xwR.js.map +1 -0
- package/dist/internal_context.d.ts +1 -1
- package/dist/lifecycle/index.d.ts +3 -3
- package/dist/lifecycle/index.js +2 -2
- package/dist/{lifecycle-CFu6OV03.js → lifecycle-DGorpAmA.js} +2 -4
- package/dist/lifecycle-DGorpAmA.js.map +1 -0
- package/dist/mcp/client/do-oauth-client-provider.d.ts +1 -1
- package/dist/mcp/client/do-oauth-client-provider.js +9 -0
- package/dist/mcp/client/do-oauth-client-provider.js.map +1 -1
- package/dist/mcp/client/index.d.ts +1 -1
- package/dist/mcp/client/index.js +1 -1
- package/dist/mcp/client/x402.d.ts +35 -4
- package/dist/mcp/client/x402.js +24 -3
- package/dist/mcp/client/x402.js.map +1 -1
- package/dist/mcp/index.d.ts +1 -1
- package/dist/mcp/index.js +2 -2
- package/dist/models/ai-sdk/index.d.ts +16 -14
- package/dist/models/ai-sdk/index.js +1 -2442
- package/dist/models/opencode/index.d.ts +65 -0
- package/dist/models/opencode/index.js +285 -0
- package/dist/models/opencode/index.js.map +1 -0
- package/dist/models/pi-ai/index.d.ts +9 -7
- package/dist/models/pi-ai/index.js +2 -1
- package/dist/models/pi-ai/index.js.map +1 -1
- package/dist/options-CiIsJHXR.d.ts +130 -0
- package/dist/protocol-BEgrJYC5.d.ts +331 -0
- package/dist/protocol-CukuI73M.d.ts +386 -0
- package/dist/protocol-cOklVBBD.js +227 -0
- package/dist/protocol-cOklVBBD.js.map +1 -0
- package/dist/{protocol-kHsr-f0X.js → protocol-eXeJxhgu.js} +2 -67
- package/dist/protocol-eXeJxhgu.js.map +1 -0
- package/dist/protocol-y2sSY584.js +148 -0
- package/dist/protocol-y2sSY584.js.map +1 -0
- package/dist/queue/index.d.ts +1 -1
- package/dist/queue/index.js +1 -1
- package/dist/{queue-BB-zfIYF.js → queue-CcIjVYTE.js} +2 -2
- package/dist/{queue-BB-zfIYF.js.map → queue-CcIjVYTE.js.map} +1 -1
- package/dist/react.d.ts +2 -2
- package/dist/routing/index.d.ts +2 -2
- package/dist/routing/index.js +1 -1
- package/dist/{scheduler-RdACNXDP.d.ts → scheduler-BCLESHSC.d.ts} +2 -12
- package/dist/{scheduler-DZ3xQfeK.js → scheduler-FIHv2-kJ.js} +2 -4
- package/dist/scheduler-FIHv2-kJ.js.map +1 -0
- package/dist/schedules/index.d.ts +1 -1
- package/dist/schedules/index.js +1 -1
- package/dist/serializable.d.ts +1 -1
- package/dist/session-store-Do4xkDcf.js +606 -0
- package/dist/session-store-Do4xkDcf.js.map +1 -0
- package/dist/session-store-DoPY12xM.d.ts +383 -0
- package/dist/sessions/index.d.ts +11 -434
- package/dist/sessions/index.js +1 -2271
- package/dist/sessions-_vN5BEZX.js +2272 -0
- package/dist/sessions-_vN5BEZX.js.map +1 -0
- package/dist/settings-C45hDliX.js +253 -0
- package/dist/settings-C45hDliX.js.map +1 -0
- package/dist/{transport-PfFnt-Ld.d.ts → settings-NgGwF7Qt.d.ts} +14 -208
- package/dist/{src-BZeu-SCD.js → src-CQxJFv4l.js} +8 -8
- package/dist/src-CQxJFv4l.js.map +1 -0
- package/dist/stall-watchdog-BpRF2uwG.js +195 -0
- package/dist/stall-watchdog-BpRF2uwG.js.map +1 -0
- package/dist/state/index.d.ts +1 -1
- package/dist/state/index.js +1 -3
- package/dist/state/index.js.map +1 -1
- package/dist/store-BKM4Xm9M.d.ts +332 -0
- package/dist/store-CslVzfN7.js +458 -0
- package/dist/store-CslVzfN7.js.map +1 -0
- package/dist/streams/index.d.ts +1 -1
- package/dist/streams/index.js +1 -1
- package/dist/{streams-DW-UCOUc.js → streams-lsHMJhRW.js} +17 -4
- package/dist/streams-lsHMJhRW.js.map +1 -0
- package/dist/{streams-Cmkj9QfW.d.ts → streams-vrCtbUIn.d.ts} +2 -2
- package/dist/sub-routing.d.ts +1 -1
- package/dist/tasks/index.d.ts +1 -1
- package/dist/tasks/index.js +1 -1
- package/dist/{tasks-68DESxf0.js → tasks-BN_5AWqI.js} +3 -2
- package/dist/tasks-BN_5AWqI.js.map +1 -0
- package/dist/{tasks-9YxYtByh.d.ts → tasks-E89KdwkS.d.ts} +2 -2
- package/dist/tool-CTp72Jb_.d.ts +278 -0
- package/dist/tool-CxKsvxjm.js +1126 -0
- package/dist/tool-CxKsvxjm.js.map +1 -0
- package/dist/tool-DoVberpN.d.ts +301 -0
- package/dist/tool-cQRkwSZZ.js +410 -0
- package/dist/tool-cQRkwSZZ.js.map +1 -0
- package/dist/tool-helpers-O5BDVEAY.js +58 -0
- package/dist/tool-helpers-O5BDVEAY.js.map +1 -0
- package/dist/transport-k2mFrtL8.d.ts +200 -0
- package/dist/turns-DCV3ycDl.js +317 -0
- package/dist/turns-DCV3ycDl.js.map +1 -0
- package/dist/voice/client.js +1 -1
- package/dist/voice/index.d.ts +2 -2
- package/dist/voice/index.js +1 -1
- package/dist/web/fetch/index.d.ts +89 -0
- package/dist/web/fetch/index.js +20 -0
- package/dist/web/fetch/index.js.map +1 -0
- package/dist/web/fetch/tools/ai-sdk.d.ts +80 -0
- package/dist/web/fetch/tools/ai-sdk.js +47 -0
- package/dist/web/fetch/tools/ai-sdk.js.map +1 -0
- package/dist/web/fetch/tools/pi.d.ts +84 -0
- package/dist/web/fetch/tools/pi.js +88 -0
- package/dist/web/fetch/tools/pi.js.map +1 -0
- package/dist/web/fetch/tools/tanstack-ai.d.ts +78 -0
- package/dist/web/fetch/tools/tanstack-ai.js +45 -0
- package/dist/web/fetch/tools/tanstack-ai.js.map +1 -0
- package/dist/web/search/index.d.ts +58 -0
- package/dist/web/search/index.js +2 -0
- package/dist/web/search/tools/ai-sdk.d.ts +77 -0
- package/dist/web/search/tools/ai-sdk.js +46 -0
- package/dist/web/search/tools/ai-sdk.js.map +1 -0
- package/dist/web/search/tools/pi.d.ts +82 -0
- package/dist/web/search/tools/pi.js +89 -0
- package/dist/web/search/tools/pi.js.map +1 -0
- package/dist/web/search/tools/tanstack-ai.d.ts +71 -0
- package/dist/web/search/tools/tanstack-ai.js +46 -0
- package/dist/web/search/tools/tanstack-ai.js.map +1 -0
- package/dist/websockets/index.d.ts +12 -296
- package/dist/websockets/index.js +1 -1
- package/dist/{websockets-Ci-LZFHH.js → websockets-C3zy8YR0.js} +20 -8
- package/dist/websockets-C3zy8YR0.js.map +1 -0
- package/dist/{wire-types-CrjKvDyi.d.ts → wire-types-Cv0iwjk5.d.ts} +3 -51
- package/dist/workflow-types.d.ts +1 -1
- package/dist/workflows.d.ts +1 -1
- package/dist/workflows.js +1 -1
- package/docs/browse-the-web.md +29 -1
- package/docs/fetch-the-web.md +276 -0
- package/docs/harnesses/pi.md +25 -0
- package/docs/harnesses/think.md +215 -0
- package/docs/index.md +99 -75
- package/docs/lifecycle.md +42 -3
- package/docs/queue.md +2 -3
- package/docs/scheduling.md +2 -6
- package/docs/search-the-web.md +135 -0
- package/package.json +148 -44
- package/dist/ai-fm7xx1BK.js +0 -312
- package/dist/ai-fm7xx1BK.js.map +0 -1
- package/dist/browser/ai-sdk.js.map +0 -1
- package/dist/browser/index.js.map +0 -1
- package/dist/browser/tanstack-ai.js.map +0 -1
- package/dist/browser-tool-CQ10e6Kj.js.map +0 -1
- package/dist/capability-B4WbF81e.js.map +0 -1
- package/dist/channel-Bnm4S7T2.d.ts +0 -491
- package/dist/channels/ai-sdk.d.ts +0 -46
- package/dist/channels/ai-sdk.js +0 -120
- package/dist/channels/ai-sdk.js.map +0 -1
- package/dist/channels/email.js.map +0 -1
- package/dist/channels/index.d.ts +0 -233
- package/dist/channels/index.js +0 -608
- package/dist/channels/index.js.map +0 -1
- package/dist/channels/slack.js +0 -614
- package/dist/channels/slack.js.map +0 -1
- package/dist/channels/tanstack-ai.d.ts +0 -39
- package/dist/channels/tanstack-ai.js +0 -17
- package/dist/channels/tanstack-ai.js.map +0 -1
- package/dist/channels/telegram.js +0 -427
- package/dist/channels/telegram.js.map +0 -1
- package/dist/channels/voice.d.ts +0 -45
- package/dist/channels/voice.js +0 -122
- package/dist/channels/voice.js.map +0 -1
- package/dist/client-fyQrLGkD.js.map +0 -1
- package/dist/connector-58XDGvc3.js.map +0 -1
- package/dist/images-iiTDSyRu.js.map +0 -1
- package/dist/index-BB0kqhIz.d.ts +0 -101
- package/dist/ingress-BfetZbMO.js +0 -83
- package/dist/ingress-BfetZbMO.js.map +0 -1
- package/dist/internal-CYlgHl1l.js +0 -59
- package/dist/internal-CYlgHl1l.js.map +0 -1
- package/dist/lifecycle-CFu6OV03.js.map +0 -1
- package/dist/models/ai-sdk/index.js.map +0 -1
- package/dist/protocol-kHsr-f0X.js.map +0 -1
- package/dist/scheduler-DZ3xQfeK.js.map +0 -1
- package/dist/sessions/index.js.map +0 -1
- package/dist/src-BZeu-SCD.js.map +0 -1
- package/dist/streams-DW-UCOUc.js.map +0 -1
- package/dist/surface-bZZJqBka.js +0 -17
- package/dist/surface-bZZJqBka.js.map +0 -1
- package/dist/tasks-68DESxf0.js.map +0 -1
- package/dist/tool-schema-CBjGPrsQ.js +0 -31
- package/dist/tool-schema-CBjGPrsQ.js.map +0 -1
- package/dist/websockets-Ci-LZFHH.js.map +0 -1
- package/docs/channels.md +0 -323
|
@@ -138,71 +138,6 @@ var StreamAccumulator = class {
|
|
|
138
138
|
}
|
|
139
139
|
};
|
|
140
140
|
//#endregion
|
|
141
|
-
//#region src/chat/broadcast-state.ts
|
|
142
|
-
function textOf(parts) {
|
|
143
|
-
let text = "";
|
|
144
|
-
for (const part of parts) if (part.type === "text") text += part.text;
|
|
145
|
-
return text;
|
|
146
|
-
}
|
|
147
|
-
/**
|
|
148
|
-
* Whether `messages` already holds a copy of the observed message whose text
|
|
149
|
-
* the accumulator does not extend. A healthy live accumulator is always the
|
|
150
|
-
* stored copy plus more; one that diverges holds interleaved or duplicated
|
|
151
|
-
* chunks (#2166), so the stored copy must win or the corruption never heals.
|
|
152
|
-
*/
|
|
153
|
-
function observedDivergesFrom(accumulator, messages) {
|
|
154
|
-
const existing = messages.find((m) => m.id === accumulator.messageId);
|
|
155
|
-
if (!existing) return false;
|
|
156
|
-
return !textOf(accumulator.parts).startsWith(textOf(existing.parts));
|
|
157
|
-
}
|
|
158
|
-
function transition(state, event) {
|
|
159
|
-
switch (event.type) {
|
|
160
|
-
case "clear": return {
|
|
161
|
-
state: { status: "idle" },
|
|
162
|
-
isStreaming: false
|
|
163
|
-
};
|
|
164
|
-
case "resume-fallback": {
|
|
165
|
-
const accumulator = new StreamAccumulator({ messageId: event.messageId });
|
|
166
|
-
return {
|
|
167
|
-
state: {
|
|
168
|
-
status: "observing",
|
|
169
|
-
streamId: event.streamId,
|
|
170
|
-
accumulator
|
|
171
|
-
},
|
|
172
|
-
isStreaming: true
|
|
173
|
-
};
|
|
174
|
-
}
|
|
175
|
-
case "response": {
|
|
176
|
-
let accumulator;
|
|
177
|
-
const isReplayedStart = event.replay === true && event.chunkData?.type === "start";
|
|
178
|
-
if (state.status === "idle" || state.streamId !== event.streamId || isReplayedStart) accumulator = new StreamAccumulator({
|
|
179
|
-
messageId: event.messageId,
|
|
180
|
-
continuation: event.continuation
|
|
181
|
-
});
|
|
182
|
-
else accumulator = state.accumulator;
|
|
183
|
-
if (event.chunkData) accumulator.applyChunk(event.chunkData);
|
|
184
|
-
let messagesUpdate;
|
|
185
|
-
const mergeUnlessDiverged = (prev) => observedDivergesFrom(accumulator, prev) ? prev : accumulator.mergeInto(prev);
|
|
186
|
-
if (event.done) return {
|
|
187
|
-
state: { status: "idle" },
|
|
188
|
-
messagesUpdate: mergeUnlessDiverged,
|
|
189
|
-
isStreaming: false
|
|
190
|
-
};
|
|
191
|
-
if (event.chunkData && !event.replay) messagesUpdate = mergeUnlessDiverged;
|
|
192
|
-
else if (event.replayComplete) messagesUpdate = (prev) => accumulator.mergeInto(prev);
|
|
193
|
-
return {
|
|
194
|
-
state: {
|
|
195
|
-
status: "observing",
|
|
196
|
-
streamId: event.streamId,
|
|
197
|
-
accumulator
|
|
198
|
-
},
|
|
199
|
-
messagesUpdate,
|
|
200
|
-
isStreaming: true
|
|
201
|
-
};
|
|
202
|
-
}
|
|
203
|
-
}
|
|
204
|
-
}
|
|
205
|
-
//#endregion
|
|
206
141
|
//#region src/chat/protocol.ts
|
|
207
142
|
/**
|
|
208
143
|
* Wire protocol message type constants for the cf_agent_chat_* protocol.
|
|
@@ -234,6 +169,6 @@ const CHAT_MESSAGE_TYPES = {
|
|
|
234
169
|
CHAT_RECOVERING: "cf_agent_chat_recovering"
|
|
235
170
|
};
|
|
236
171
|
//#endregion
|
|
237
|
-
export {
|
|
172
|
+
export { STREAM_RESUME_NONE_REASONS as n, StreamAccumulator as r, CHAT_MESSAGE_TYPES as t };
|
|
238
173
|
|
|
239
|
-
//# sourceMappingURL=protocol-
|
|
174
|
+
//# sourceMappingURL=protocol-eXeJxhgu.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"protocol-eXeJxhgu.js","names":[],"sources":["../src/chat/stream-accumulator.ts","../src/chat/protocol.ts"],"sourcesContent":["/**\n * StreamAccumulator — unified chunk-to-message builder.\n *\n * Used by @cloudflare/ai-chat (server + client) and @cloudflare/think\n * to incrementally build a UIMessage from stream chunks. Wraps\n * applyChunkToParts and handles the metadata chunk types (start, finish,\n * message-metadata, error) that applyChunkToParts does not cover.\n *\n * The accumulator signals domain-specific concerns (early persistence,\n * cross-message tool updates) via ChunkAction returns — callers handle\n * these according to their context.\n */\n\nimport type { UIMessage } from \"ai\";\nimport { applyChunkToParts, type StreamChunkData } from \"./message-builder\";\n\nfunction asMetadata(value: unknown): Record<string, unknown> | undefined {\n if (value != null && typeof value === \"object\" && !Array.isArray(value)) {\n return value as Record<string, unknown>;\n }\n return undefined;\n}\n\nexport interface StreamAccumulatorOptions {\n messageId: string;\n /** Whether chunks continue the current assistant message when merged. */\n continuation?: boolean;\n /** Eager seed; omitted continuations seed from the messages passed to `mergeInto`. */\n existingParts?: UIMessage[\"parts\"];\n existingMetadata?: Record<string, unknown>;\n}\n\nexport type ChunkAction =\n | {\n type: \"start\";\n messageId?: string;\n metadata?: Record<string, unknown>;\n }\n | {\n type: \"finish\";\n finishReason?: string;\n metadata?: Record<string, unknown>;\n }\n | { type: \"message-metadata\"; metadata: Record<string, unknown> }\n | { type: \"tool-approval-request\"; toolCallId: string }\n | {\n type: \"cross-message-tool-update\";\n updateType: \"output-available\" | \"output-error\";\n toolCallId: string;\n output?: unknown;\n errorText?: string;\n preliminary?: boolean;\n }\n | { type: \"error\"; error: string };\n\nexport interface ChunkResult {\n handled: boolean;\n action?: ChunkAction;\n}\n\nexport class StreamAccumulator {\n messageId: string;\n readonly parts: UIMessage[\"parts\"];\n metadata?: Record<string, unknown>;\n private _isContinuation: boolean;\n // Continuation chunks wait here until mergeInto can seed from current state.\n private _pendingContinuationChunks: StreamChunkData[] | null;\n\n constructor(options: StreamAccumulatorOptions) {\n this.messageId = options.messageId;\n this._isContinuation = options.continuation ?? false;\n this.parts = options.existingParts ? [...options.existingParts] : [];\n this.metadata = options.existingMetadata\n ? { ...options.existingMetadata }\n : undefined;\n this._pendingContinuationChunks =\n this._isContinuation &&\n options.existingParts === undefined &&\n options.existingMetadata === undefined\n ? []\n : null;\n }\n\n applyChunk(chunk: StreamChunkData): ChunkResult {\n this._pendingContinuationChunks?.push(chunk);\n const handled = applyChunkToParts(this.parts, chunk);\n\n // Detect tool-approval-request for early persistence signaling\n if (chunk.type === \"tool-approval-request\" && chunk.toolCallId) {\n return {\n handled,\n action: { type: \"tool-approval-request\", toolCallId: chunk.toolCallId }\n };\n }\n\n // Detect cross-message tool output/error: applyChunkToParts returns true\n // for recognized types but silently does nothing when the toolCallId\n // doesn't exist in the current parts array.\n if (\n (chunk.type === \"tool-output-available\" ||\n chunk.type === \"tool-output-error\") &&\n chunk.toolCallId\n ) {\n const foundInParts = this.parts.some(\n (p) => \"toolCallId\" in p && p.toolCallId === chunk.toolCallId\n );\n if (!foundInParts) {\n return {\n handled,\n action: {\n type: \"cross-message-tool-update\",\n updateType:\n chunk.type === \"tool-output-available\"\n ? \"output-available\"\n : \"output-error\",\n toolCallId: chunk.toolCallId,\n output: chunk.output,\n errorText: chunk.errorText,\n preliminary: chunk.preliminary\n }\n };\n }\n }\n\n if (!handled) {\n switch (chunk.type) {\n case \"start\": {\n if (chunk.messageId != null && !this._isContinuation) {\n this.messageId = chunk.messageId;\n }\n const startMeta = asMetadata(chunk.messageMetadata);\n if (startMeta) {\n this.metadata = this.metadata\n ? { ...this.metadata, ...startMeta }\n : { ...startMeta };\n }\n return {\n handled: true,\n action: {\n type: \"start\",\n messageId: chunk.messageId,\n metadata: startMeta\n }\n };\n }\n case \"finish\": {\n const finishMeta = asMetadata(chunk.messageMetadata);\n if (finishMeta) {\n this.metadata = this.metadata\n ? { ...this.metadata, ...finishMeta }\n : { ...finishMeta };\n }\n const finishReason =\n \"finishReason\" in chunk\n ? (chunk.finishReason as string)\n : undefined;\n return {\n handled: true,\n action: {\n type: \"finish\",\n finishReason,\n metadata: finishMeta\n }\n };\n }\n case \"message-metadata\": {\n const msgMeta = asMetadata(chunk.messageMetadata);\n if (msgMeta) {\n this.metadata = this.metadata\n ? { ...this.metadata, ...msgMeta }\n : { ...msgMeta };\n }\n return {\n handled: true,\n action: {\n type: \"message-metadata\",\n metadata: msgMeta ?? {}\n }\n };\n }\n case \"finish-step\": {\n return { handled: true };\n }\n case \"error\": {\n return {\n handled: true,\n action: {\n type: \"error\",\n error: chunk.errorText ?? JSON.stringify(chunk)\n }\n };\n }\n }\n }\n\n return { handled };\n }\n\n /** Snapshot the current state as a UIMessage. */\n toMessage(): UIMessage {\n return {\n id: this.messageId,\n role: \"assistant\",\n parts: [...this.parts],\n ...(this.metadata != null && { metadata: this.metadata })\n } as UIMessage;\n }\n\n /**\n * Merge this accumulator's message into an existing message array.\n * Handles continuation (walk backward for last assistant), replacement\n * (update existing by messageId), or append (new message). An unseeded\n * continuation adopts current parts here before applying its queued chunks.\n */\n mergeInto(messages: UIMessage[]): UIMessage[] {\n let existingIdx = messages.findIndex((m) => m.id === this.messageId);\n\n if (existingIdx < 0 && this._isContinuation) {\n for (let i = messages.length - 1; i >= 0; i--) {\n if (messages[i].role === \"assistant\") {\n existingIdx = i;\n break;\n }\n }\n }\n\n if (this._pendingContinuationChunks !== null) {\n const pendingChunks = this._pendingContinuationChunks;\n this._pendingContinuationChunks = null;\n this.parts.splice(\n 0,\n this.parts.length,\n ...(existingIdx >= 0 ? messages[existingIdx].parts : [])\n );\n const currentMetadata =\n existingIdx >= 0\n ? asMetadata(messages[existingIdx].metadata)\n : undefined;\n this.metadata = currentMetadata ? { ...currentMetadata } : undefined;\n if (existingIdx >= 0) {\n this.messageId = messages[existingIdx].id;\n }\n for (const chunk of pendingChunks) {\n this.applyChunk(chunk);\n }\n }\n\n const messageId =\n existingIdx >= 0 ? messages[existingIdx].id : this.messageId;\n\n const partialMessage: UIMessage = {\n id: messageId,\n role: \"assistant\",\n parts: [...this.parts],\n ...(this.metadata != null && { metadata: this.metadata })\n } as UIMessage;\n\n if (existingIdx >= 0) {\n const updated = [...messages];\n updated[existingIdx] = partialMessage;\n return updated;\n }\n return [...messages, partialMessage];\n }\n}\n","/**\n * Wire protocol message type constants for the cf_agent_chat_* protocol.\n *\n * These are the string values used on the wire between agent servers and\n * clients. Both @cloudflare/ai-chat (via its MessageType enum) and\n * @cloudflare/think use these values.\n */\nexport const STREAM_RESUME_NONE_REASONS = {\n /** No active, pending, or terminal stream exists for this agent. */\n IDLE: \"idle\",\n /** An active tool continuation is owned by another live connection. */\n CONTINUATION_OWNED: \"continuation-owned\"\n} as const;\n\nexport type StreamResumeNoneReason =\n (typeof STREAM_RESUME_NONE_REASONS)[keyof typeof STREAM_RESUME_NONE_REASONS];\n\nexport const CHAT_MESSAGE_TYPES = {\n CHAT_MESSAGES: \"cf_agent_chat_messages\",\n USE_CHAT_REQUEST: \"cf_agent_use_chat_request\",\n USE_CHAT_RESPONSE: \"cf_agent_use_chat_response\",\n CHAT_CLEAR: \"cf_agent_chat_clear\",\n CHAT_REQUEST_CANCEL: \"cf_agent_chat_request_cancel\",\n STREAM_RESUMING: \"cf_agent_stream_resuming\",\n STREAM_RESUME_ACK: \"cf_agent_stream_resume_ack\",\n STREAM_RESUME_REQUEST: \"cf_agent_stream_resume_request\",\n STREAM_RESUME_NONE: \"cf_agent_stream_resume_none\",\n // Server→client: a turn has been accepted but its resumable stream has not\n // started yet (queued, debouncing, waiting on MCP setup, or running async\n // work in `onChatMessage`). Sent in response to a resume request (or on\n // connect) so a reconnecting/re-mounting client keeps its expectation instead\n // of resolving its resume probe to \"no stream\" and then false-timing-out the\n // turn. Resolved by a later `STREAM_RESUMING` (stream started) or\n // `STREAM_RESUME_NONE` (turn settled without streaming). Backward-compatible —\n // clients that don't understand it ignore it. See issue #1784.\n STREAM_PENDING: \"cf_agent_stream_pending\",\n TOOL_RESULT: \"cf_agent_tool_result\",\n TOOL_APPROVAL: \"cf_agent_tool_approval\",\n MESSAGE_UPDATED: \"cf_agent_message_updated\",\n // Server→client: a durable chat turn is being recovered (interrupted by a\n // deploy/eviction or a stream-stall watchdog abort and now resuming). Sent\n // when a recovery continuation is scheduled and cleared on every terminal\n // outcome; `@cloudflare/think` also replays it on connect so a client that\n // joins mid-recovery learns it. Purely a progress hint — backward-compatible\n // (clients that don't understand it ignore it). See issue #1620.\n CHAT_RECOVERING: \"cf_agent_chat_recovering\"\n} as const;\n"],"mappings":"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"}
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
//#region src/experimental/channels/web/protocol.ts
|
|
2
|
+
/**
|
|
3
|
+
* The header carrying a connection's WebIdentity from the gateway to the
|
|
4
|
+
* agent. The gateway always sets it, so a client cannot supply its own; an
|
|
5
|
+
* agent must not take WebSocket upgrades from any other route.
|
|
6
|
+
*/
|
|
7
|
+
const WEB_IDENTITY_HEADER = "x-channels-identity";
|
|
8
|
+
/**
|
|
9
|
+
* Parse a text frame. Returns undefined for anything that is not a Channels
|
|
10
|
+
* frame, so the socket's other protocols keep working.
|
|
11
|
+
*/
|
|
12
|
+
function parseClientFrame(text) {
|
|
13
|
+
let frame;
|
|
14
|
+
try {
|
|
15
|
+
frame = JSON.parse(text);
|
|
16
|
+
} catch {
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
if (!isObject(frame) || typeof frame.type !== "string") return void 0;
|
|
20
|
+
if (frame.type === "channels:subscribe") {
|
|
21
|
+
const { responseId, from } = frame;
|
|
22
|
+
if (typeof responseId !== "string") return { invalid: "responseId" };
|
|
23
|
+
if (from !== void 0 && !Number.isInteger(from)) return { invalid: "from" };
|
|
24
|
+
return {
|
|
25
|
+
type: "channels:subscribe",
|
|
26
|
+
responseId,
|
|
27
|
+
...typeof from === "number" && { from }
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
if (frame.type === "channels:list-conversations") return isId(frame.requestId) ? {
|
|
31
|
+
type: "channels:list-conversations",
|
|
32
|
+
requestId: frame.requestId
|
|
33
|
+
} : { invalid: "requestId" };
|
|
34
|
+
if (frame.type !== "channels:event") return void 0;
|
|
35
|
+
const event = frame.event;
|
|
36
|
+
const eventId = isObject(event) ? event.eventId : void 0;
|
|
37
|
+
if (!isObject(event) || !isId(eventId)) return { invalid: "eventId" };
|
|
38
|
+
const parsed = parseEvent(event, eventId);
|
|
39
|
+
return typeof parsed === "string" ? {
|
|
40
|
+
invalid: parsed,
|
|
41
|
+
eventId
|
|
42
|
+
} : {
|
|
43
|
+
type: "channels:event",
|
|
44
|
+
event: parsed
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
function isObject(value) {
|
|
48
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
49
|
+
}
|
|
50
|
+
function isId(value) {
|
|
51
|
+
return typeof value === "string" && value.length > 0;
|
|
52
|
+
}
|
|
53
|
+
/** The event, or the name of the first invalid field. */
|
|
54
|
+
function parseEvent(event, eventId) {
|
|
55
|
+
switch (event.type) {
|
|
56
|
+
case "message": {
|
|
57
|
+
const message = event.message;
|
|
58
|
+
if (!isObject(message) || !isId(message.id)) return "message.id";
|
|
59
|
+
if (message.role !== "user") return "message.role";
|
|
60
|
+
const parts = message.parts;
|
|
61
|
+
if (!Array.isArray(parts) || !parts.every(isPart)) return "message.parts";
|
|
62
|
+
return {
|
|
63
|
+
type: "message",
|
|
64
|
+
eventId,
|
|
65
|
+
message: {
|
|
66
|
+
id: message.id,
|
|
67
|
+
role: "user",
|
|
68
|
+
parts,
|
|
69
|
+
...isObject(message.metadata) && { metadata: message.metadata }
|
|
70
|
+
},
|
|
71
|
+
...clientTools(event.clientTools)
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
case "tool-result": {
|
|
75
|
+
const { turnId, toolCallId, result } = event;
|
|
76
|
+
if (!isId(turnId)) return "turnId";
|
|
77
|
+
if (!isId(toolCallId)) return "toolCallId";
|
|
78
|
+
if (!isObject(result) || typeof result.ok !== "boolean") return "result";
|
|
79
|
+
return {
|
|
80
|
+
type: "tool-result",
|
|
81
|
+
eventId,
|
|
82
|
+
turnId,
|
|
83
|
+
toolCallId,
|
|
84
|
+
result: result.ok ? {
|
|
85
|
+
ok: true,
|
|
86
|
+
output: result.output ?? null
|
|
87
|
+
} : {
|
|
88
|
+
ok: false,
|
|
89
|
+
...typeof result.errorText === "string" && { errorText: result.errorText }
|
|
90
|
+
},
|
|
91
|
+
...clientTools(event.clientTools)
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
case "approval-response": {
|
|
95
|
+
const { turnId, approvalId, approved, reason } = event;
|
|
96
|
+
if (!isId(turnId)) return "turnId";
|
|
97
|
+
if (!isId(approvalId)) return "approvalId";
|
|
98
|
+
if (typeof approved !== "boolean") return "approved";
|
|
99
|
+
return {
|
|
100
|
+
type: "approval-response",
|
|
101
|
+
eventId,
|
|
102
|
+
turnId,
|
|
103
|
+
approvalId,
|
|
104
|
+
approved,
|
|
105
|
+
...typeof reason === "string" && { reason }
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
case "cancel": return isId(event.turnId) ? {
|
|
109
|
+
type: "cancel",
|
|
110
|
+
eventId,
|
|
111
|
+
turnId: event.turnId
|
|
112
|
+
} : "turnId";
|
|
113
|
+
case "conversation-create":
|
|
114
|
+
case "conversation-fork": return {
|
|
115
|
+
type: event.type,
|
|
116
|
+
eventId
|
|
117
|
+
};
|
|
118
|
+
case "conversation-reset":
|
|
119
|
+
if (event.handoff !== void 0 && typeof event.handoff !== "string") return "handoff";
|
|
120
|
+
return {
|
|
121
|
+
type: "conversation-reset",
|
|
122
|
+
eventId,
|
|
123
|
+
...event.handoff && { handoff: event.handoff }
|
|
124
|
+
};
|
|
125
|
+
default: return "type";
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
function isPart(part) {
|
|
129
|
+
return isObject(part) && typeof part.type === "string";
|
|
130
|
+
}
|
|
131
|
+
/** Keeps tools with a name, dropping a schema that is not an object. */
|
|
132
|
+
function clientTools(value) {
|
|
133
|
+
if (!Array.isArray(value)) return {};
|
|
134
|
+
const tools = [];
|
|
135
|
+
for (const tool of value) {
|
|
136
|
+
if (!isObject(tool) || !isId(tool.name)) continue;
|
|
137
|
+
tools.push({
|
|
138
|
+
name: tool.name,
|
|
139
|
+
...typeof tool.description === "string" && { description: tool.description },
|
|
140
|
+
...isObject(tool.inputSchema) && { inputSchema: tool.inputSchema }
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
return { clientTools: tools };
|
|
144
|
+
}
|
|
145
|
+
//#endregion
|
|
146
|
+
export { parseClientFrame as n, WEB_IDENTITY_HEADER as t };
|
|
147
|
+
|
|
148
|
+
//# sourceMappingURL=protocol-y2sSY584.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"protocol-y2sSY584.js","names":[],"sources":["../src/experimental/channels/web/protocol.ts"],"sourcesContent":["import type {\n ClientTool,\n ConversationInfo,\n ConversationOperation,\n ConversationSnapshot,\n InboundEvent,\n Json,\n JsonObject,\n Participant,\n ResponseChunk,\n TranscriptMessage,\n TurnStatus\n} from \"../protocol\";\n\n/** Who a connection is: set by the gateway, read by the Web Channel. */\nexport type WebIdentity = {\n /** The route that picked the agent. */\n route: string;\n /** The conversation to follow. Default: the agent's default for the route. */\n conversationId?: string;\n participant: Participant;\n};\n\n/**\n * The header carrying a connection's WebIdentity from the gateway to the\n * agent. The gateway always sets it, so a client cannot supply its own; an\n * agent must not take WebSocket upgrades from any other route.\n */\nexport const WEB_IDENTITY_HEADER = \"x-channels-identity\";\n\n// Frames between Channels and a connected client. Each connection follows\n// one conversation at a time, and every server frame names it, so a client\n// can drop frames for a conversation it no longer follows. Payloads are the\n// shared protocol types, unchanged.\n\nexport type ClientFrame =\n | { type: \"channels:event\"; event: InboundEvent }\n | { type: \"channels:subscribe\"; responseId: string; from?: number }\n /** Ask for the agent's conversations; answered by `channels:conversations`. */\n | { type: \"channels:list-conversations\"; requestId: string };\n\nexport type ServerFrame = { conversationId: string } &\n /**\n * On connect, after a reset (empty), and when the connection follows\n * another conversation. `you` is this connection's participant;\n * `operations` are the conversation operations it may send.\n */\n (\n | ({\n type: \"channels:snapshot\";\n you: Participant;\n operations: ConversationOperation[];\n } & ConversationSnapshot)\n | { type: \"channels:turn\"; turn: TurnStatus }\n /** Upserts by id; an unknown id appends. */\n | { type: \"channels:messages\"; messages: TranscriptMessage[] }\n | {\n type: \"channels:chunks\";\n responseId: string;\n /** Seq of the first chunk. */\n from: number;\n chunks: ResponseChunk[];\n }\n /** Everything before this was replay; what follows is live. */\n | { type: \"channels:caught-up\"; responseId: string; cursor: number }\n | {\n type: \"channels:end\";\n responseId: string;\n state: \"ended\" | \"interrupted\" | \"not-found\";\n }\n /**\n * The agent's conversations: the answer to a list request, carrying its\n * `requestId`, or pushed when one is created or forked.\n */\n | {\n type: \"channels:conversations\";\n requestId?: string;\n conversations?: ConversationInfo[];\n error?: string;\n }\n /** `conversationId` is the one a create or fork started, when it did. */\n | { type: \"channels:ack\"; eventId: string; error?: string }\n );\n\n/** A frame that names a Channels type but is malformed. */\nexport type InvalidClientFrame = { invalid: string; eventId?: string };\n\n/**\n * Parse a text frame. Returns undefined for anything that is not a Channels\n * frame, so the socket's other protocols keep working.\n */\nexport function parseClientFrame(\n text: string\n): ClientFrame | InvalidClientFrame | undefined {\n let frame: unknown;\n try {\n frame = JSON.parse(text);\n } catch {\n return undefined;\n }\n if (!isObject(frame) || typeof frame.type !== \"string\") return undefined;\n if (frame.type === \"channels:subscribe\") {\n const { responseId, from } = frame;\n if (typeof responseId !== \"string\") return { invalid: \"responseId\" };\n if (from !== undefined && !Number.isInteger(from)) {\n return { invalid: \"from\" };\n }\n return {\n type: \"channels:subscribe\",\n responseId,\n ...(typeof from === \"number\" && { from })\n };\n }\n if (frame.type === \"channels:list-conversations\") {\n return isId(frame.requestId)\n ? { type: \"channels:list-conversations\", requestId: frame.requestId }\n : { invalid: \"requestId\" };\n }\n if (frame.type !== \"channels:event\") return undefined;\n const event = frame.event;\n const eventId = isObject(event) ? event.eventId : undefined;\n if (!isObject(event) || !isId(eventId)) return { invalid: \"eventId\" };\n const parsed = parseEvent(event, eventId);\n return typeof parsed === \"string\"\n ? { invalid: parsed, eventId }\n : { type: \"channels:event\", event: parsed };\n}\n\ntype JsonRecord = { readonly [key: string]: Json | undefined };\n\n// Parsed JSON is JSON, so narrowing to an object is enough to read it.\nfunction isObject(value: unknown): value is JsonRecord {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction isId(value: unknown): value is string {\n return typeof value === \"string\" && value.length > 0;\n}\n\n/** The event, or the name of the first invalid field. */\nfunction parseEvent(event: JsonRecord, eventId: string): InboundEvent | string {\n switch (event.type) {\n case \"message\": {\n const message = event.message;\n if (!isObject(message) || !isId(message.id)) return \"message.id\";\n if (message.role !== \"user\") return \"message.role\";\n const parts = message.parts;\n if (!Array.isArray(parts) || !parts.every(isPart)) return \"message.parts\";\n return {\n type: \"message\",\n eventId,\n message: {\n id: message.id,\n role: \"user\",\n // SAFETY: each part is an object with a string type; the agent\n // decides which part types it accepts.\n parts: parts as unknown as TranscriptMessage[\"parts\"],\n ...(isObject(message.metadata) && {\n metadata: message.metadata as JsonObject\n })\n },\n ...clientTools(event.clientTools)\n };\n }\n case \"tool-result\": {\n const { turnId, toolCallId, result } = event;\n if (!isId(turnId)) return \"turnId\";\n if (!isId(toolCallId)) return \"toolCallId\";\n if (!isObject(result) || typeof result.ok !== \"boolean\") return \"result\";\n return {\n type: \"tool-result\",\n eventId,\n turnId,\n toolCallId,\n result: result.ok\n ? { ok: true, output: result.output ?? null }\n : {\n ok: false,\n ...(typeof result.errorText === \"string\" && {\n errorText: result.errorText\n })\n },\n ...clientTools(event.clientTools)\n };\n }\n case \"approval-response\": {\n const { turnId, approvalId, approved, reason } = event;\n if (!isId(turnId)) return \"turnId\";\n if (!isId(approvalId)) return \"approvalId\";\n if (typeof approved !== \"boolean\") return \"approved\";\n return {\n type: \"approval-response\",\n eventId,\n turnId,\n approvalId,\n approved,\n ...(typeof reason === \"string\" && { reason })\n };\n }\n case \"cancel\":\n return isId(event.turnId)\n ? { type: \"cancel\", eventId, turnId: event.turnId }\n : \"turnId\";\n case \"conversation-create\":\n case \"conversation-fork\":\n return { type: event.type, eventId };\n case \"conversation-reset\":\n if (event.handoff !== undefined && typeof event.handoff !== \"string\") {\n return \"handoff\";\n }\n return {\n type: \"conversation-reset\",\n eventId,\n ...(event.handoff && { handoff: event.handoff })\n };\n default:\n return \"type\";\n }\n}\n\nfunction isPart(part: Json): boolean {\n return isObject(part) && typeof part.type === \"string\";\n}\n\n/** Keeps tools with a name, dropping a schema that is not an object. */\nfunction clientTools(value: Json | undefined): { clientTools?: ClientTool[] } {\n if (!Array.isArray(value)) return {};\n const tools: ClientTool[] = [];\n for (const tool of value) {\n if (!isObject(tool) || !isId(tool.name)) continue;\n tools.push({\n name: tool.name,\n ...(typeof tool.description === \"string\" && {\n description: tool.description\n }),\n ...(isObject(tool.inputSchema) && {\n inputSchema: tool.inputSchema as JsonObject\n })\n });\n }\n return { clientTools: tools };\n}\n"],"mappings":"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"}
|
package/dist/queue/index.d.ts
CHANGED
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
d as LifecycleRouteContext,
|
|
4
4
|
s as LifecycleCapability,
|
|
5
5
|
v as LifecycleJobOutcome
|
|
6
|
-
} from "../capability-runner-
|
|
6
|
+
} from "../capability-runner-BiVUtjqC.js";
|
|
7
7
|
import { t as RetryOptions } from "../retries-CV6AkXmQ.js";
|
|
8
8
|
import {
|
|
9
9
|
a as QueuePayload,
|
package/dist/queue/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { t as Queue } from "../queue-
|
|
1
|
+
import { t as Queue } from "../queue-CcIjVYTE.js";
|
|
2
2
|
export { Queue };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { i as _classPrivateFieldInitSpec, n as _classPrivateFieldSet2, r as _assertClassBrand, t as _classPrivateFieldGet2 } from "./classPrivateFieldGet2-DZBYAB34.js";
|
|
2
2
|
import { t as _classPrivateMethodInitSpec } from "./classPrivateMethodInitSpec-qMjJ6sHQ.js";
|
|
3
|
-
import { t as LifecycleCapability } from "./capability-
|
|
3
|
+
import { t as LifecycleCapability } from "./capability-DBAKc6UZ.js";
|
|
4
4
|
import { isDurableObjectCodeUpdateReset, isPlatformFailure, resolveRetryConfig, tryN, validateRetryOptions } from "./retries.js";
|
|
5
5
|
//#region src/queue/queue.ts
|
|
6
6
|
/**
|
|
@@ -403,4 +403,4 @@ function _emit(type, payload) {
|
|
|
403
403
|
//#endregion
|
|
404
404
|
export { setQueueCallbackResolver as n, Queue as t };
|
|
405
405
|
|
|
406
|
-
//# sourceMappingURL=queue-
|
|
406
|
+
//# sourceMappingURL=queue-CcIjVYTE.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"queue-BB-zfIYF.js","names":[],"sources":["../src/queue/queue.ts"],"sourcesContent":["/**\n * Lifecycle background-work vocabulary. Queue validates items, resolves\n * named callbacks, and pushes jobs due immediately into the Lifecycle-owned\n * job queue; Lifecycle runs the alarm event loop, retry policy, and physical\n * alarm arming. Queue owns no storage of its own — each item is one job\n * whose `fn` is the callback name and whose payload carries the item's\n * payload and owner.\n */\n\nimport {\n LifecycleCapability,\n type LifecycleRouteAddress,\n type LifecycleRouteContext\n} from \"../lifecycle/capability\";\nimport type {\n LifecycleJob,\n LifecycleJobContext,\n LifecycleJobOutcome\n} from \"../lifecycle/job-queue\";\nimport {\n isDurableObjectCodeUpdateReset,\n isPlatformFailure,\n resolveRetryConfig,\n tryN,\n validateRetryOptions\n} from \"../retries\";\nimport type { RetryOptions } from \"../retries\";\nimport type { QueueEventType, QueueOptions } from \"./options\";\nimport type {\n QueueCallbacks,\n QueueCriteria,\n QueueHandlers,\n QueueItem,\n QueuePayload,\n QueuePushOptions,\n QueueStorageRow\n} from \"./types\";\n\n/** A resolved fallback handler for a callback name outside the registered map. */\ntype ResolvedQueueCallback = (\n payload: unknown,\n item: QueueItem<unknown>\n) => unknown;\n\nconst queueCallbackResolvers = new WeakMap<\n object,\n (name: string) => ResolvedQueueCallback | undefined\n>();\n\n/**\n * @internal Supply a composition-root fallback for callback names outside the\n * registered map. Agent uses this to keep its historical name-based queue\n * API (`this.queue(\"methodName\", payload)`) working: the resolver looks the\n * method up on the Agent, and the resolved handler still runs inside the\n * Lifecycle host boundary.\n */\nexport function setQueueCallbackResolver(\n queue: Queue<never>,\n resolver: (name: string) => ResolvedQueueCallback | undefined\n): void {\n queueCallbackResolvers.set(queue, resolver);\n}\n\nconst QUEUE_SCHEMA_VERSION_KEY = \"cf_agents:queue_schema_version\";\n/** Version 1: queue items live in the Lifecycle job queue. */\nconst CURRENT_QUEUE_SCHEMA_VERSION = 1;\n\nconst DEFAULT_RETRY: Required<RetryOptions> = {\n maxAttempts: 3,\n baseDelayMs: 100,\n maxDelayMs: 3000\n};\n\n/** What a Queue job's payload carries: the item payload and its owner. */\ntype QueueJobPayload = {\n readonly payload: unknown;\n readonly owner_path: string | null;\n readonly owner_path_key: string | null;\n};\n\ntype QueueRouteMessage =\n | {\n readonly type: \"push\";\n readonly callback: string;\n readonly payload: unknown;\n readonly options?: QueuePushOptions;\n }\n | { readonly type: \"get\" | \"cancel\"; readonly id: string }\n | { readonly type: \"list\"; readonly criteria?: QueueCriteria }\n | { readonly type: \"cancelAll\"; readonly callback?: string }\n | {\n readonly type: \"dispatch\";\n readonly item: QueueItem<unknown>;\n };\n\nfunction isQueueJobPayload(value: unknown): value is QueueJobPayload {\n // `payload` is absent after a JSON round trip when the item carried none.\n return typeof value === \"object\" && value !== null && \"owner_path\" in value;\n}\n\n/**\n * Durable background work for a Lifecycle Object.\n *\n * Register callbacks in the constructor and install the instance with\n * `Lifecycle.use()`. Each pushed item becomes a job due immediately in the\n * Lifecycle job queue; Lifecycle owns the physical alarm and the alarm event\n * loop, drives items one at a time in push order, retries a throwing\n * callback per its retry policy, and Queue runs registered callbacks through\n * Lifecycle's host invocation boundary. An item that still fails after its\n * last attempt is dropped after `queue:error` and the `onError` hook.\n *\n * Items survive the Durable Object leaving memory: an isolate that dies mid\n * callback wakes again on the Lifecycle deadman alarm and resumes the queue.\n * Callbacks should therefore be idempotent.\n *\n * @experimental The API surface may change before stabilizing.\n */\nexport class Queue<\n Handlers extends QueueHandlers = QueueCallbacks\n> extends LifecycleCapability {\n readonly #handlers: QueueHandlers;\n readonly #retryDefaults: Required<RetryOptions>;\n readonly #onError: ((error: unknown) => void | Promise<void>) | undefined;\n /**\n * Last due time handed to a job. The Lifecycle driver dispatches due jobs\n * in due-time order, so pushes get strictly increasing times to keep push\n * order (FIFO) even within one millisecond. Seeded from the persisted\n * queue tail on first use so a fresh instance never sorts a new item ahead\n * of items an earlier instance already queued.\n */\n #lastTime: number | null = null;\n\n /**\n * Create a durable Queue.\n *\n * @param options - Registered callbacks plus optional retry and error\n * policy. Registering `callbacks` types {@link push} against the map —\n * names and payloads are checked where the handlers are declared and where\n * they are pushed. Names outside the map are rejected unless a\n * composition-root resolver supplies them — the internal aperture behind\n * `Agent`'s name-based queue API.\n */\n constructor(options: QueueOptions<Handlers> = {}) {\n super(\"queue\");\n this.#handlers = options.callbacks ?? {};\n // Retry defaults are resolved, not validated, here: invalid defaults\n // surface per execution as queue:error instead of bricking the object at\n // construction. Per-item retry overrides are validated when pushed.\n this.#retryDefaults = resolveRetryConfig(options.retry, DEFAULT_RETRY);\n this.#onError = options.onError;\n }\n\n // ── Lifecycle capability hooks ───────────────────────────────────────────\n\n /** Migrate legacy `cf_agents_queues` rows into the Lifecycle job queue. */\n async onStart(): Promise<void> {\n const storage = this.lifecycle.storage;\n const version = (await storage.get<number>(QUEUE_SCHEMA_VERSION_KEY)) ?? 0;\n if (version >= CURRENT_QUEUE_SCHEMA_VERSION) return;\n\n await this.#migrateLegacyQueueTable(storage);\n await storage.put(QUEUE_SCHEMA_VERSION_KEY, CURRENT_QUEUE_SCHEMA_VERSION);\n }\n\n /**\n * Move every `cf_agents_queues` row into the job queue and drop the\n * table. Idempotent: a missing table means a fresh object or a completed\n * migration. Rows keep their insertion order.\n *\n * TEMPORARY: one-shot upgrade path for objects that had queued items when\n * this release landed. Remove in the next minor release (with the schema\n * version bump that gates it), once every deployed object has migrated.\n */\n async #migrateLegacyQueueTable(storage: DurableObjectStorage): Promise<void> {\n const tables = storage.sql\n .exec(\n \"SELECT name FROM sqlite_master WHERE type='table' AND name='cf_agents_queues'\"\n )\n .toArray();\n if (tables.length === 0) return;\n\n const rows = storage.sql\n .exec(\"SELECT * FROM cf_agents_queues ORDER BY created_at ASC, rowid ASC\")\n .toArray() as unknown as QueueStorageRow[];\n for (const row of rows) {\n let payload: unknown;\n try {\n payload =\n typeof row.payload === \"string\" ? JSON.parse(row.payload) : undefined;\n } catch (error) {\n console.error(\n `Skipping queue item \"${row.id}\" during job-queue migration: ` +\n \"its payload is not valid JSON\",\n error\n );\n continue;\n }\n let retry: RetryOptions | undefined;\n try {\n retry =\n typeof row.retry_options === \"string\"\n ? (JSON.parse(row.retry_options) as RetryOptions)\n : undefined;\n } catch {\n retry = undefined;\n }\n await this.lifecycle.jobs.push({\n id: row.id,\n fn: row.callback,\n time: this.#nextTime(),\n payload: {\n payload,\n owner_path: null,\n owner_path_key: null\n } satisfies QueueJobPayload,\n retry: resolveRetryConfig(retry, this.#retryDefaults)\n });\n }\n storage.sql.exec(\"DROP TABLE cf_agents_queues\");\n }\n\n /** Drive one due item dispatched by the Lifecycle event loop. */\n async onJob(\n context: LifecycleJobContext\n ): Promise<LifecycleJobOutcome | void> {\n const { job, attempt } = context;\n if (!isQueueJobPayload(job.payload)) {\n console.error(`Malformed queue item ${job.id}; dropping it`);\n return undefined;\n }\n const item = this.#jobToItem(job, job.payload);\n\n if (attempt > 1) {\n this.#emit(\"queue:retry\", {\n callback: job.fn,\n id: job.id,\n attempt,\n maxAttempts: resolveRetryConfig(job.retry, this.#retryDefaults)\n .maxAttempts\n });\n }\n\n if (job.payload.owner_path) {\n // A routed item executes inside its owning Lifecycle; retries run\n // there too, so this dispatch is a single routed attempt.\n try {\n await this.lifecycle.routes.to(\n {\n key: job.payload.owner_path_key ?? job.payload.owner_path,\n data: job.payload.owner_path\n },\n { type: \"dispatch\", item } satisfies QueueRouteMessage\n );\n } catch (error) {\n if (isPlatformFailure(error)) {\n // Preserve the item; Lifecycle defers platform-class failures to\n // a fresh invocation or the memory-limit breaker.\n throw error;\n }\n console.error(`error dispatching queue callback \"${job.fn}\"`, error);\n this.#emit(\"queue:error\", {\n callback: job.fn,\n id: job.id,\n error: error instanceof Error ? error.message : String(error),\n attempts: 0\n });\n try {\n await this.#onError?.(error);\n } catch {\n // swallow onError errors\n }\n // Leave the item due so a later alarm cycle can retry dispatch, for\n // example once a transport can resolve its owner again.\n return \"yield\";\n }\n return undefined;\n }\n\n const handler = this.#resolveCallback(job.fn);\n if (!handler) {\n console.error(`callback ${job.fn} not found`);\n return undefined;\n }\n await this.lifecycle.runInHostContext(() => handler(item.payload, item));\n return undefined;\n }\n\n /** Observe one item's terminal application failure; the item is dropped. */\n async onJobError(\n context: LifecycleJobContext,\n error: unknown\n ): Promise<LifecycleJobOutcome | void> {\n const { job } = context;\n const { maxAttempts } = resolveRetryConfig(job.retry, this.#retryDefaults);\n console.error(\n `queue callback \"${job.fn}\" failed after ${maxAttempts} attempts`,\n error\n );\n this.#emit(\"queue:error\", {\n callback: job.fn,\n id: job.id,\n error: error instanceof Error ? error.message : String(error),\n attempts: maxAttempts\n });\n try {\n await this.#onError?.(error);\n } catch {\n // swallow onError errors\n }\n return undefined;\n }\n\n /** Handle Queue protocol messages routed by another Lifecycle. */\n async onRoute(context: LifecycleRouteContext): Promise<unknown> {\n const message = context.payload as QueueRouteMessage;\n const owner = context.source ?? null;\n switch (message.type) {\n case \"push\":\n return this.#insert(\n owner,\n message.callback,\n message.payload,\n message.options\n );\n case \"get\":\n return this.#getForOwner(owner, message.id);\n case \"list\":\n return this.#listForOwner(owner, message.criteria);\n case \"cancel\":\n return this.#cancelForOwner(owner, message.id);\n case \"cancelAll\":\n return this.#cancelAllForOwner(owner, message.callback);\n case \"dispatch\":\n await this.#executeRouted(message.item);\n return true;\n default:\n throw new Error(\"Unknown routed Queue message\");\n }\n }\n\n /**\n * Execute a routed item locally with the historical retry handling. Runs\n * on the owning (facet) Queue, outside the root's event loop, so it applies\n * its own in-process retry budget. Platform-class failures re-throw so the\n * root preserves the item and the durable alarm retries on a fresh\n * invocation.\n */\n async #executeRouted(item: QueueItem<unknown>): Promise<void> {\n const handler = this.#resolveCallback(item.callback);\n if (!handler) {\n console.error(`callback ${item.callback} not found`);\n return;\n }\n const { maxAttempts, baseDelayMs, maxDelayMs } = resolveRetryConfig(\n item.retry,\n this.#retryDefaults\n );\n try {\n await tryN(\n maxAttempts,\n async (attempt) => {\n if (attempt > 1) {\n this.#emit(\"queue:retry\", {\n callback: item.callback,\n id: item.id,\n attempt,\n maxAttempts\n });\n }\n await this.lifecycle.runInHostContext(() =>\n handler(item.payload, item)\n );\n },\n {\n baseDelayMs,\n maxDelayMs,\n shouldRetry: (error) => !isDurableObjectCodeUpdateReset(error)\n }\n );\n } catch (error) {\n if (isPlatformFailure(error)) {\n throw error;\n }\n console.error(\n `queue callback \"${item.callback}\" failed after ${maxAttempts} attempts`,\n error\n );\n this.#emit(\"queue:error\", {\n callback: item.callback,\n id: item.id,\n error: error instanceof Error ? error.message : String(error),\n attempts: maxAttempts\n });\n try {\n await this.#onError?.(error);\n } catch {\n // swallow onError errors\n }\n }\n }\n\n // ── Queue API ────────────────────────────────────────────────────────────\n\n /**\n * Push one item for a registered callback. The item is due immediately;\n * the Lifecycle alarm event loop runs it in push order after this call\n * returns.\n *\n * Once the Lifecycle has started (and this Queue is not routed through\n * another Lifecycle), the item row is written synchronously before this\n * method's promise is even returned, so a caller may pair a push with its\n * own writes in one synchronous block — the item then commits atomically\n * with them.\n */\n async push<Name extends keyof Handlers & string>(\n callback: Name,\n payload?: QueuePayload<Handlers[Name]>,\n options?: QueuePushOptions\n ): Promise<QueueItem<QueuePayload<Handlers[Name]>>> {\n if (this.lifecycle.status() !== \"started\") await this.lifecycle.ready();\n this.#validatePush(callback, options);\n const item = this.lifecycle.routes.source\n ? ((await this.lifecycle.routes.toRoot({\n type: \"push\",\n callback,\n payload,\n options\n } satisfies QueueRouteMessage)) as QueueItem<\n QueuePayload<Handlers[Name]>\n >)\n : await this.#insert<QueuePayload<Handlers[Name]>>(\n null,\n callback,\n payload,\n options\n );\n this.#emit(\"queue:create\", { callback, id: item.id });\n return item;\n }\n\n /** Cancel one pending item. Returns false when no item matched. */\n async cancel(id: string): Promise<boolean> {\n await this.lifecycle.ready();\n if (this.lifecycle.routes.source) {\n return (await this.lifecycle.routes.toRoot({\n type: \"cancel\",\n id\n } satisfies QueueRouteMessage)) as boolean;\n }\n return this.#cancelForOwner(null, id);\n }\n\n /** Cancel every pending item, or every item for one callback. Returns the count. */\n async cancelAll(callback?: string): Promise<number> {\n await this.lifecycle.ready();\n if (this.lifecycle.routes.source) {\n return (await this.lifecycle.routes.toRoot({\n type: \"cancelAll\",\n callback\n } satisfies QueueRouteMessage)) as number;\n }\n return this.#cancelAllForOwner(null, callback);\n }\n\n /** Read one pending item. */\n async get<T = unknown>(id: string): Promise<QueueItem<T> | undefined> {\n await this.lifecycle.ready();\n if (this.lifecycle.routes.source) {\n return (await this.lifecycle.routes.toRoot({\n type: \"get\",\n id\n } satisfies QueueRouteMessage)) as QueueItem<T> | undefined;\n }\n return this.#getForOwner<T>(null, id);\n }\n\n /** List pending items in push order, optionally filtered by callback. */\n async list<T = unknown>(criteria?: QueueCriteria): Promise<QueueItem<T>[]> {\n await this.lifecycle.ready();\n if (this.lifecycle.routes.source) {\n return (await this.lifecycle.routes.toRoot({\n type: \"list\",\n criteria\n } satisfies QueueRouteMessage)) as QueueItem<T>[];\n }\n return this.#listForOwner<T>(null, criteria);\n }\n\n // ── Internals ────────────────────────────────────────────────────────────\n\n #validatePush(callback: string, options?: QueuePushOptions): void {\n if (typeof callback !== \"string\") {\n throw new Error(\"Callback must be a string\");\n }\n if (!this.#hasCallback(callback)) {\n throw new Error(\n `Unknown queue callback \"${callback}\": not registered on this Queue`\n );\n }\n if (options?.retry)\n validateRetryOptions(options.retry, this.#retryDefaults);\n if (options?.id !== undefined && options.id.trim() === \"\") {\n throw new Error(\"Queue item ids must be non-empty\");\n }\n }\n\n /** Resolve a name to its registered or composition-root-supplied handler. */\n #resolveCallback(name: string): ResolvedQueueCallback | undefined {\n const handler = this.#handlers[name];\n if (handler) {\n // SAFETY: registered handlers are constrained with `never` parameters\n // so concrete handler types satisfy the map under contravariance; the\n // payload passed at dispatch was persisted with this handler's name.\n return handler as ResolvedQueueCallback;\n }\n return queueCallbackResolvers.get(this)?.(name);\n }\n\n #hasCallback(name: string): boolean {\n return this.#resolveCallback(name) !== undefined;\n }\n\n /** The next strictly increasing due time, never before now. */\n #nextTime(): number {\n if (this.#lastTime === null) {\n this.#lastTime = this.#ownedJobs().reduce(\n (lastTime, { job }) => Math.max(lastTime, job.time),\n 0\n );\n }\n const time = Math.max(Date.now(), this.#lastTime + 1);\n this.#lastTime = time;\n return time;\n }\n\n async #insert<T>(\n owner: LifecycleRouteAddress | null,\n callback: string,\n payload: unknown,\n options?: QueuePushOptions\n ): Promise<QueueItem<T>> {\n // A stable-id push replaces the item in place: it keeps the existing\n // item's due time, and so its position in the queue.\n const existing =\n options?.id !== undefined\n ? this.lifecycle.jobs.get(options.id)\n : undefined;\n const keepTime =\n existing !== undefined &&\n this.#getForOwner(owner, existing.id) !== undefined;\n const job = await this.lifecycle.jobs.push({\n id: options?.id,\n fn: callback,\n time: keepTime ? existing.time : this.#nextTime(),\n payload: {\n payload,\n owner_path: owner?.data ?? null,\n owner_path_key: owner?.key ?? null\n } satisfies QueueJobPayload,\n retry: resolveRetryConfig(options?.retry, this.#retryDefaults)\n });\n return this.#jobToItem<T>(job, job.payload as QueueJobPayload);\n }\n\n #jobToItem<T>(job: LifecycleJob, envelope: QueueJobPayload): QueueItem<T> {\n return {\n id: job.id,\n callback: job.fn,\n payload: envelope.payload as T,\n createdAt: job.createdAt,\n retry: job.retry\n };\n }\n\n /** Every queue job this Queue owns, in push order. */\n #ownedJobs(): Array<{ job: LifecycleJob; envelope: QueueJobPayload }> {\n const owned: Array<{ job: LifecycleJob; envelope: QueueJobPayload }> = [];\n for (const job of this.lifecycle.jobs.list()) {\n if (isQueueJobPayload(job.payload)) {\n owned.push({ job, envelope: job.payload });\n }\n }\n return owned;\n }\n\n #getForOwner<T>(\n owner: LifecycleRouteAddress | null,\n id: string\n ): QueueItem<T> | undefined {\n const ownerKey = owner?.key ?? null;\n const job = this.lifecycle.jobs.get(id);\n if (!job || !isQueueJobPayload(job.payload)) return undefined;\n if ((job.payload.owner_path_key ?? null) !== ownerKey) return undefined;\n return this.#jobToItem<T>(job, job.payload);\n }\n\n #listForOwner<T>(\n owner: LifecycleRouteAddress | null,\n criteria: QueueCriteria = {}\n ): QueueItem<T>[] {\n const ownerKey = owner?.key ?? null;\n const items: QueueItem<T>[] = [];\n for (const { job, envelope } of this.#ownedJobs()) {\n if ((envelope.owner_path_key ?? null) !== ownerKey) continue;\n if (criteria.callback && job.fn !== criteria.callback) continue;\n items.push(this.#jobToItem<T>(job, envelope));\n }\n return items;\n }\n\n async #cancelForOwner(\n owner: LifecycleRouteAddress | null,\n id: string\n ): Promise<boolean> {\n if (!this.#getForOwner(owner, id)) return false;\n return this.lifecycle.jobs.cancel(id);\n }\n\n async #cancelAllForOwner(\n owner: LifecycleRouteAddress | null,\n callback?: string\n ): Promise<number> {\n let cancelled = 0;\n for (const item of this.#listForOwner(owner, { callback })) {\n if (await this.lifecycle.jobs.cancel(item.id)) cancelled++;\n }\n return cancelled;\n }\n\n /** @internal Remove items owned by one routed Lifecycle subtree. */\n async __DO_NOT_USE_WILL_BREAK__cleanupRoutePrefix(\n prefix: string\n ): Promise<void> {\n for (const { job, envelope } of this.#ownedJobs()) {\n const ownerKey = envelope.owner_path_key ?? envelope.owner_path;\n if (!envelope.owner_path || ownerKey === null) continue;\n if (ownerKey !== prefix && !ownerKey.startsWith(`${prefix}/`)) continue;\n await this.lifecycle.jobs.cancel(job.id);\n }\n }\n\n // ── Events ───────────────────────────────────────────────────────────────\n\n #emit(type: QueueEventType, payload: Record<string, unknown>): void {\n this.lifecycle.events.emit(type, payload);\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"queue-CcIjVYTE.js","names":[],"sources":["../src/queue/queue.ts"],"sourcesContent":["/**\n * Lifecycle background-work vocabulary. Queue validates items, resolves\n * named callbacks, and pushes jobs due immediately into the Lifecycle-owned\n * job queue; Lifecycle runs the alarm event loop, retry policy, and physical\n * alarm arming. Queue owns no storage of its own — each item is one job\n * whose `fn` is the callback name and whose payload carries the item's\n * payload and owner.\n */\n\nimport {\n LifecycleCapability,\n type LifecycleRouteAddress,\n type LifecycleRouteContext\n} from \"../lifecycle/capability\";\nimport type {\n LifecycleJob,\n LifecycleJobContext,\n LifecycleJobOutcome\n} from \"../lifecycle/job-queue\";\nimport {\n isDurableObjectCodeUpdateReset,\n isPlatformFailure,\n resolveRetryConfig,\n tryN,\n validateRetryOptions\n} from \"../retries\";\nimport type { RetryOptions } from \"../retries\";\nimport type { QueueEventType, QueueOptions } from \"./options\";\nimport type {\n QueueCallbacks,\n QueueCriteria,\n QueueHandlers,\n QueueItem,\n QueuePayload,\n QueuePushOptions,\n QueueStorageRow\n} from \"./types\";\n\n/** A resolved fallback handler for a callback name outside the registered map. */\ntype ResolvedQueueCallback = (\n payload: unknown,\n item: QueueItem<unknown>\n) => unknown;\n\nconst queueCallbackResolvers = new WeakMap<\n object,\n (name: string) => ResolvedQueueCallback | undefined\n>();\n\n/**\n * @internal Supply a composition-root fallback for callback names outside the\n * registered map. Agent uses this to keep its historical name-based queue\n * API (`this.queue(\"methodName\", payload)`) working: the resolver looks the\n * method up on the Agent, and the resolved handler still runs inside the\n * Lifecycle host boundary.\n */\nexport function setQueueCallbackResolver(\n queue: Queue<never>,\n resolver: (name: string) => ResolvedQueueCallback | undefined\n): void {\n queueCallbackResolvers.set(queue, resolver);\n}\n\nconst QUEUE_SCHEMA_VERSION_KEY = \"cf_agents:queue_schema_version\";\n/** Version 1: queue items live in the Lifecycle job queue. */\nconst CURRENT_QUEUE_SCHEMA_VERSION = 1;\n\nconst DEFAULT_RETRY: Required<RetryOptions> = {\n maxAttempts: 3,\n baseDelayMs: 100,\n maxDelayMs: 3000\n};\n\n/** What a Queue job's payload carries: the item payload and its owner. */\ntype QueueJobPayload = {\n readonly payload: unknown;\n readonly owner_path: string | null;\n readonly owner_path_key: string | null;\n};\n\ntype QueueRouteMessage =\n | {\n readonly type: \"push\";\n readonly callback: string;\n readonly payload: unknown;\n readonly options?: QueuePushOptions;\n }\n | { readonly type: \"get\" | \"cancel\"; readonly id: string }\n | { readonly type: \"list\"; readonly criteria?: QueueCriteria }\n | { readonly type: \"cancelAll\"; readonly callback?: string }\n | {\n readonly type: \"dispatch\";\n readonly item: QueueItem<unknown>;\n };\n\nfunction isQueueJobPayload(value: unknown): value is QueueJobPayload {\n // `payload` is absent after a JSON round trip when the item carried none.\n return typeof value === \"object\" && value !== null && \"owner_path\" in value;\n}\n\n/**\n * Durable background work for a Lifecycle Object.\n *\n * Register callbacks in the constructor and install the instance with\n * `Lifecycle.use()`. Each pushed item becomes a job due immediately in the\n * Lifecycle job queue; Lifecycle owns the physical alarm and the alarm event\n * loop, drives items one at a time in push order, retries a throwing\n * callback per its retry policy, and Queue runs registered callbacks through\n * Lifecycle's host invocation boundary. An item that still fails after its\n * last attempt is dropped after `queue:error` and the `onError` hook.\n *\n * Items survive the Durable Object leaving memory: an isolate that dies mid\n * callback wakes again on the Lifecycle deadman alarm and resumes the queue.\n * Callbacks should therefore be idempotent.\n *\n * @experimental The API surface may change before stabilizing.\n */\nexport class Queue<\n Handlers extends QueueHandlers = QueueCallbacks\n> extends LifecycleCapability {\n readonly #handlers: QueueHandlers;\n readonly #retryDefaults: Required<RetryOptions>;\n readonly #onError: ((error: unknown) => void | Promise<void>) | undefined;\n /**\n * Last due time handed to a job. The Lifecycle driver dispatches due jobs\n * in due-time order, so pushes get strictly increasing times to keep push\n * order (FIFO) even within one millisecond. Seeded from the persisted\n * queue tail on first use so a fresh instance never sorts a new item ahead\n * of items an earlier instance already queued.\n */\n #lastTime: number | null = null;\n\n /**\n * Create a durable Queue.\n *\n * @param options - Registered callbacks plus optional retry and error\n * policy. Registering `callbacks` types {@link push} against the map —\n * names and payloads are checked where the handlers are declared and where\n * they are pushed. Names outside the map are rejected unless a\n * composition-root resolver supplies them — the internal aperture behind\n * `Agent`'s name-based queue API.\n */\n constructor(options: QueueOptions<Handlers> = {}) {\n super(\"queue\");\n this.#handlers = options.callbacks ?? {};\n // Retry defaults are resolved, not validated, here: invalid defaults\n // surface per execution as queue:error instead of bricking the object at\n // construction. Per-item retry overrides are validated when pushed.\n this.#retryDefaults = resolveRetryConfig(options.retry, DEFAULT_RETRY);\n this.#onError = options.onError;\n }\n\n // ── Lifecycle capability hooks ───────────────────────────────────────────\n\n /** Migrate legacy `cf_agents_queues` rows into the Lifecycle job queue. */\n async onStart(): Promise<void> {\n const storage = this.lifecycle.storage;\n const version = (await storage.get<number>(QUEUE_SCHEMA_VERSION_KEY)) ?? 0;\n if (version >= CURRENT_QUEUE_SCHEMA_VERSION) return;\n\n await this.#migrateLegacyQueueTable(storage);\n await storage.put(QUEUE_SCHEMA_VERSION_KEY, CURRENT_QUEUE_SCHEMA_VERSION);\n }\n\n /**\n * Move every `cf_agents_queues` row into the job queue and drop the\n * table. Idempotent: a missing table means a fresh object or a completed\n * migration. Rows keep their insertion order.\n *\n * TEMPORARY: one-shot upgrade path for objects that had queued items when\n * this release landed. Remove in the next minor release (with the schema\n * version bump that gates it), once every deployed object has migrated.\n */\n async #migrateLegacyQueueTable(storage: DurableObjectStorage): Promise<void> {\n const tables = storage.sql\n .exec(\n \"SELECT name FROM sqlite_master WHERE type='table' AND name='cf_agents_queues'\"\n )\n .toArray();\n if (tables.length === 0) return;\n\n const rows = storage.sql\n .exec(\"SELECT * FROM cf_agents_queues ORDER BY created_at ASC, rowid ASC\")\n .toArray() as unknown as QueueStorageRow[];\n for (const row of rows) {\n let payload: unknown;\n try {\n payload =\n typeof row.payload === \"string\" ? JSON.parse(row.payload) : undefined;\n } catch (error) {\n console.error(\n `Skipping queue item \"${row.id}\" during job-queue migration: ` +\n \"its payload is not valid JSON\",\n error\n );\n continue;\n }\n let retry: RetryOptions | undefined;\n try {\n retry =\n typeof row.retry_options === \"string\"\n ? (JSON.parse(row.retry_options) as RetryOptions)\n : undefined;\n } catch {\n retry = undefined;\n }\n await this.lifecycle.jobs.push({\n id: row.id,\n fn: row.callback,\n time: this.#nextTime(),\n payload: {\n payload,\n owner_path: null,\n owner_path_key: null\n } satisfies QueueJobPayload,\n retry: resolveRetryConfig(retry, this.#retryDefaults)\n });\n }\n storage.sql.exec(\"DROP TABLE cf_agents_queues\");\n }\n\n /** Drive one due item dispatched by the Lifecycle event loop. */\n async onJob(\n context: LifecycleJobContext\n ): Promise<LifecycleJobOutcome | void> {\n const { job, attempt } = context;\n if (!isQueueJobPayload(job.payload)) {\n console.error(`Malformed queue item ${job.id}; dropping it`);\n return undefined;\n }\n const item = this.#jobToItem(job, job.payload);\n\n if (attempt > 1) {\n this.#emit(\"queue:retry\", {\n callback: job.fn,\n id: job.id,\n attempt,\n maxAttempts: resolveRetryConfig(job.retry, this.#retryDefaults)\n .maxAttempts\n });\n }\n\n if (job.payload.owner_path) {\n // A routed item executes inside its owning Lifecycle; retries run\n // there too, so this dispatch is a single routed attempt.\n try {\n await this.lifecycle.routes.to(\n {\n key: job.payload.owner_path_key ?? job.payload.owner_path,\n data: job.payload.owner_path\n },\n { type: \"dispatch\", item } satisfies QueueRouteMessage\n );\n } catch (error) {\n if (isPlatformFailure(error)) {\n // Preserve the item; Lifecycle defers platform-class failures to\n // a fresh invocation or the memory-limit breaker.\n throw error;\n }\n console.error(`error dispatching queue callback \"${job.fn}\"`, error);\n this.#emit(\"queue:error\", {\n callback: job.fn,\n id: job.id,\n error: error instanceof Error ? error.message : String(error),\n attempts: 0\n });\n try {\n await this.#onError?.(error);\n } catch {\n // swallow onError errors\n }\n // Leave the item due so a later alarm cycle can retry dispatch, for\n // example once a transport can resolve its owner again.\n return \"yield\";\n }\n return undefined;\n }\n\n const handler = this.#resolveCallback(job.fn);\n if (!handler) {\n console.error(`callback ${job.fn} not found`);\n return undefined;\n }\n await this.lifecycle.runInHostContext(() => handler(item.payload, item));\n return undefined;\n }\n\n /** Observe one item's terminal application failure; the item is dropped. */\n async onJobError(\n context: LifecycleJobContext,\n error: unknown\n ): Promise<LifecycleJobOutcome | void> {\n const { job } = context;\n const { maxAttempts } = resolveRetryConfig(job.retry, this.#retryDefaults);\n console.error(\n `queue callback \"${job.fn}\" failed after ${maxAttempts} attempts`,\n error\n );\n this.#emit(\"queue:error\", {\n callback: job.fn,\n id: job.id,\n error: error instanceof Error ? error.message : String(error),\n attempts: maxAttempts\n });\n try {\n await this.#onError?.(error);\n } catch {\n // swallow onError errors\n }\n return undefined;\n }\n\n /** Handle Queue protocol messages routed by another Lifecycle. */\n async onRoute(context: LifecycleRouteContext): Promise<unknown> {\n const message = context.payload as QueueRouteMessage;\n const owner = context.source ?? null;\n switch (message.type) {\n case \"push\":\n return this.#insert(\n owner,\n message.callback,\n message.payload,\n message.options\n );\n case \"get\":\n return this.#getForOwner(owner, message.id);\n case \"list\":\n return this.#listForOwner(owner, message.criteria);\n case \"cancel\":\n return this.#cancelForOwner(owner, message.id);\n case \"cancelAll\":\n return this.#cancelAllForOwner(owner, message.callback);\n case \"dispatch\":\n await this.#executeRouted(message.item);\n return true;\n default:\n throw new Error(\"Unknown routed Queue message\");\n }\n }\n\n /**\n * Execute a routed item locally with the historical retry handling. Runs\n * on the owning (facet) Queue, outside the root's event loop, so it applies\n * its own in-process retry budget. Platform-class failures re-throw so the\n * root preserves the item and the durable alarm retries on a fresh\n * invocation.\n */\n async #executeRouted(item: QueueItem<unknown>): Promise<void> {\n const handler = this.#resolveCallback(item.callback);\n if (!handler) {\n console.error(`callback ${item.callback} not found`);\n return;\n }\n const { maxAttempts, baseDelayMs, maxDelayMs } = resolveRetryConfig(\n item.retry,\n this.#retryDefaults\n );\n try {\n await tryN(\n maxAttempts,\n async (attempt) => {\n if (attempt > 1) {\n this.#emit(\"queue:retry\", {\n callback: item.callback,\n id: item.id,\n attempt,\n maxAttempts\n });\n }\n await this.lifecycle.runInHostContext(() =>\n handler(item.payload, item)\n );\n },\n {\n baseDelayMs,\n maxDelayMs,\n shouldRetry: (error) => !isDurableObjectCodeUpdateReset(error)\n }\n );\n } catch (error) {\n if (isPlatformFailure(error)) {\n throw error;\n }\n console.error(\n `queue callback \"${item.callback}\" failed after ${maxAttempts} attempts`,\n error\n );\n this.#emit(\"queue:error\", {\n callback: item.callback,\n id: item.id,\n error: error instanceof Error ? error.message : String(error),\n attempts: maxAttempts\n });\n try {\n await this.#onError?.(error);\n } catch {\n // swallow onError errors\n }\n }\n }\n\n // ── Queue API ────────────────────────────────────────────────────────────\n\n /**\n * Push one item for a registered callback. The item is due immediately;\n * the Lifecycle alarm event loop runs it in push order after this call\n * returns.\n *\n * Once the Lifecycle has started (and this Queue is not routed through\n * another Lifecycle), the item row is written synchronously before this\n * method's promise is even returned, so a caller may pair a push with its\n * own writes in one synchronous block — the item then commits atomically\n * with them.\n */\n async push<Name extends keyof Handlers & string>(\n callback: Name,\n payload?: QueuePayload<Handlers[Name]>,\n options?: QueuePushOptions\n ): Promise<QueueItem<QueuePayload<Handlers[Name]>>> {\n if (this.lifecycle.status() !== \"started\") await this.lifecycle.ready();\n this.#validatePush(callback, options);\n const item = this.lifecycle.routes.source\n ? ((await this.lifecycle.routes.toRoot({\n type: \"push\",\n callback,\n payload,\n options\n } satisfies QueueRouteMessage)) as QueueItem<\n QueuePayload<Handlers[Name]>\n >)\n : await this.#insert<QueuePayload<Handlers[Name]>>(\n null,\n callback,\n payload,\n options\n );\n this.#emit(\"queue:create\", { callback, id: item.id });\n return item;\n }\n\n /** Cancel one pending item. Returns false when no item matched. */\n async cancel(id: string): Promise<boolean> {\n await this.lifecycle.ready();\n if (this.lifecycle.routes.source) {\n return (await this.lifecycle.routes.toRoot({\n type: \"cancel\",\n id\n } satisfies QueueRouteMessage)) as boolean;\n }\n return this.#cancelForOwner(null, id);\n }\n\n /** Cancel every pending item, or every item for one callback. Returns the count. */\n async cancelAll(callback?: string): Promise<number> {\n await this.lifecycle.ready();\n if (this.lifecycle.routes.source) {\n return (await this.lifecycle.routes.toRoot({\n type: \"cancelAll\",\n callback\n } satisfies QueueRouteMessage)) as number;\n }\n return this.#cancelAllForOwner(null, callback);\n }\n\n /** Read one pending item. */\n async get<T = unknown>(id: string): Promise<QueueItem<T> | undefined> {\n await this.lifecycle.ready();\n if (this.lifecycle.routes.source) {\n return (await this.lifecycle.routes.toRoot({\n type: \"get\",\n id\n } satisfies QueueRouteMessage)) as QueueItem<T> | undefined;\n }\n return this.#getForOwner<T>(null, id);\n }\n\n /** List pending items in push order, optionally filtered by callback. */\n async list<T = unknown>(criteria?: QueueCriteria): Promise<QueueItem<T>[]> {\n await this.lifecycle.ready();\n if (this.lifecycle.routes.source) {\n return (await this.lifecycle.routes.toRoot({\n type: \"list\",\n criteria\n } satisfies QueueRouteMessage)) as QueueItem<T>[];\n }\n return this.#listForOwner<T>(null, criteria);\n }\n\n // ── Internals ────────────────────────────────────────────────────────────\n\n #validatePush(callback: string, options?: QueuePushOptions): void {\n if (typeof callback !== \"string\") {\n throw new Error(\"Callback must be a string\");\n }\n if (!this.#hasCallback(callback)) {\n throw new Error(\n `Unknown queue callback \"${callback}\": not registered on this Queue`\n );\n }\n if (options?.retry)\n validateRetryOptions(options.retry, this.#retryDefaults);\n if (options?.id !== undefined && options.id.trim() === \"\") {\n throw new Error(\"Queue item ids must be non-empty\");\n }\n }\n\n /** Resolve a name to its registered or composition-root-supplied handler. */\n #resolveCallback(name: string): ResolvedQueueCallback | undefined {\n const handler = this.#handlers[name];\n if (handler) {\n // SAFETY: registered handlers are constrained with `never` parameters\n // so concrete handler types satisfy the map under contravariance; the\n // payload passed at dispatch was persisted with this handler's name.\n return handler as ResolvedQueueCallback;\n }\n return queueCallbackResolvers.get(this)?.(name);\n }\n\n #hasCallback(name: string): boolean {\n return this.#resolveCallback(name) !== undefined;\n }\n\n /** The next strictly increasing due time, never before now. */\n #nextTime(): number {\n if (this.#lastTime === null) {\n this.#lastTime = this.#ownedJobs().reduce(\n (lastTime, { job }) => Math.max(lastTime, job.time),\n 0\n );\n }\n const time = Math.max(Date.now(), this.#lastTime + 1);\n this.#lastTime = time;\n return time;\n }\n\n async #insert<T>(\n owner: LifecycleRouteAddress | null,\n callback: string,\n payload: unknown,\n options?: QueuePushOptions\n ): Promise<QueueItem<T>> {\n // A stable-id push replaces the item in place: it keeps the existing\n // item's due time, and so its position in the queue.\n const existing =\n options?.id !== undefined\n ? this.lifecycle.jobs.get(options.id)\n : undefined;\n const keepTime =\n existing !== undefined &&\n this.#getForOwner(owner, existing.id) !== undefined;\n const job = await this.lifecycle.jobs.push({\n id: options?.id,\n fn: callback,\n time: keepTime ? existing.time : this.#nextTime(),\n payload: {\n payload,\n owner_path: owner?.data ?? null,\n owner_path_key: owner?.key ?? null\n } satisfies QueueJobPayload,\n retry: resolveRetryConfig(options?.retry, this.#retryDefaults)\n });\n return this.#jobToItem<T>(job, job.payload as QueueJobPayload);\n }\n\n #jobToItem<T>(job: LifecycleJob, envelope: QueueJobPayload): QueueItem<T> {\n return {\n id: job.id,\n callback: job.fn,\n payload: envelope.payload as T,\n createdAt: job.createdAt,\n retry: job.retry\n };\n }\n\n /** Every queue job this Queue owns, in push order. */\n #ownedJobs(): Array<{ job: LifecycleJob; envelope: QueueJobPayload }> {\n const owned: Array<{ job: LifecycleJob; envelope: QueueJobPayload }> = [];\n for (const job of this.lifecycle.jobs.list()) {\n if (isQueueJobPayload(job.payload)) {\n owned.push({ job, envelope: job.payload });\n }\n }\n return owned;\n }\n\n #getForOwner<T>(\n owner: LifecycleRouteAddress | null,\n id: string\n ): QueueItem<T> | undefined {\n const ownerKey = owner?.key ?? null;\n const job = this.lifecycle.jobs.get(id);\n if (!job || !isQueueJobPayload(job.payload)) return undefined;\n if ((job.payload.owner_path_key ?? null) !== ownerKey) return undefined;\n return this.#jobToItem<T>(job, job.payload);\n }\n\n #listForOwner<T>(\n owner: LifecycleRouteAddress | null,\n criteria: QueueCriteria = {}\n ): QueueItem<T>[] {\n const ownerKey = owner?.key ?? null;\n const items: QueueItem<T>[] = [];\n for (const { job, envelope } of this.#ownedJobs()) {\n if ((envelope.owner_path_key ?? null) !== ownerKey) continue;\n if (criteria.callback && job.fn !== criteria.callback) continue;\n items.push(this.#jobToItem<T>(job, envelope));\n }\n return items;\n }\n\n async #cancelForOwner(\n owner: LifecycleRouteAddress | null,\n id: string\n ): Promise<boolean> {\n if (!this.#getForOwner(owner, id)) return false;\n return this.lifecycle.jobs.cancel(id);\n }\n\n async #cancelAllForOwner(\n owner: LifecycleRouteAddress | null,\n callback?: string\n ): Promise<number> {\n let cancelled = 0;\n for (const item of this.#listForOwner(owner, { callback })) {\n if (await this.lifecycle.jobs.cancel(item.id)) cancelled++;\n }\n return cancelled;\n }\n\n /** @internal Remove items owned by one routed Lifecycle subtree. */\n async __DO_NOT_USE_WILL_BREAK__cleanupRoutePrefix(\n prefix: string\n ): Promise<void> {\n for (const { job, envelope } of this.#ownedJobs()) {\n const ownerKey = envelope.owner_path_key ?? envelope.owner_path;\n if (!envelope.owner_path || ownerKey === null) continue;\n if (ownerKey !== prefix && !ownerKey.startsWith(`${prefix}/`)) continue;\n await this.lifecycle.jobs.cancel(job.id);\n }\n }\n\n // ── Events ───────────────────────────────────────────────────────────────\n\n #emit(type: QueueEventType, payload: Record<string, unknown>): void {\n this.lifecycle.events.emit(type, payload);\n }\n}\n"],"mappings":"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"}
|
package/dist/react.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ import {
|
|
|
2
2
|
C as MCPServersState,
|
|
3
3
|
J as AgentToolRunPart,
|
|
4
4
|
Y as AgentToolRunState
|
|
5
|
-
} from "./agent-routing-
|
|
5
|
+
} from "./agent-routing-QDcchcQP.js";
|
|
6
6
|
import { ClientParameters } from "./serializable.js";
|
|
7
7
|
import { t as AgentTransport } from "./transport-protocol-ZTew5Wso.js";
|
|
8
8
|
import {
|
|
@@ -15,7 +15,7 @@ import {
|
|
|
15
15
|
p as RequiredAgentMethods,
|
|
16
16
|
s as AgentStub,
|
|
17
17
|
v as createStubProxy
|
|
18
|
-
} from "./client-
|
|
18
|
+
} from "./client-BGIQKJhX.js";
|
|
19
19
|
import { PartySocket } from "partysocket";
|
|
20
20
|
import { usePartySocket } from "partysocket/react";
|
|
21
21
|
|
package/dist/routing/index.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ import {
|
|
|
2
2
|
r as CapabilityWebSocketUpgradeContext,
|
|
3
3
|
s as LifecycleCapability,
|
|
4
4
|
t as CapabilityRequestContext
|
|
5
|
-
} from "../capability-runner-
|
|
5
|
+
} from "../capability-runner-BiVUtjqC.js";
|
|
6
6
|
import {
|
|
7
7
|
a as routeAgentRequest,
|
|
8
8
|
c as Agent,
|
|
@@ -10,7 +10,7 @@ import {
|
|
|
10
10
|
n as AgentOptions,
|
|
11
11
|
r as RoutingRetryOptions,
|
|
12
12
|
t as AgentGetOptions
|
|
13
|
-
} from "../agent-routing-
|
|
13
|
+
} from "../agent-routing-QDcchcQP.js";
|
|
14
14
|
|
|
15
15
|
//#region src/routing/routed-agents.d.ts
|
|
16
16
|
/** A public entry in an {@link RoutedAgents}. */
|
package/dist/routing/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { getAgentByName, routeAgentRequest } from "../agent-routing.js";
|
|
2
2
|
import { i as _classPrivateFieldInitSpec, n as _classPrivateFieldSet2, r as _assertClassBrand, t as _classPrivateFieldGet2 } from "../classPrivateFieldGet2-DZBYAB34.js";
|
|
3
3
|
import { t as _classPrivateMethodInitSpec } from "../classPrivateMethodInitSpec-qMjJ6sHQ.js";
|
|
4
|
-
import { t as LifecycleCapability } from "../capability-
|
|
4
|
+
import { t as LifecycleCapability } from "../capability-DBAKc6UZ.js";
|
|
5
5
|
//#region src/routing/routed-agents.ts
|
|
6
6
|
/**
|
|
7
7
|
* Catalog of the entries an owning Durable Object has created, keyed by
|
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
d as LifecycleRouteContext,
|
|
4
4
|
s as LifecycleCapability,
|
|
5
5
|
v as LifecycleJobOutcome
|
|
6
|
-
} from "./capability-runner-
|
|
6
|
+
} from "./capability-runner-BiVUtjqC.js";
|
|
7
7
|
import { t as RetryOptions } from "./retries-CV6AkXmQ.js";
|
|
8
8
|
|
|
9
9
|
//#region src/schedules/types.d.ts
|
|
@@ -41,8 +41,6 @@ type Schedule<T = string> = {
|
|
|
41
41
|
/**
|
|
42
42
|
* Constraint for a Scheduler's registered callback map: named handlers
|
|
43
43
|
* receiving the parsed payload and the schedule that fired.
|
|
44
|
-
*
|
|
45
|
-
* @experimental The API surface may change before stabilizing.
|
|
46
44
|
*/
|
|
47
45
|
type SchedulerHandlers = Record<
|
|
48
46
|
string,
|
|
@@ -54,8 +52,6 @@ type SchedulerHandlers = Record<
|
|
|
54
52
|
* must be registered or supplied by a composition-root resolver (the
|
|
55
53
|
* aperture behind Agent's name-based scheduling API); a bare Scheduler
|
|
56
54
|
* rejects it otherwise.
|
|
57
|
-
*
|
|
58
|
-
* @experimental The API surface may change before stabilizing.
|
|
59
55
|
*/
|
|
60
56
|
type SchedulerCallbacks = Record<
|
|
61
57
|
string,
|
|
@@ -63,8 +59,6 @@ type SchedulerCallbacks = Record<
|
|
|
63
59
|
>;
|
|
64
60
|
/**
|
|
65
61
|
* The payload type a registered scheduler callback accepts.
|
|
66
|
-
*
|
|
67
|
-
* @experimental The API surface may change before stabilizing.
|
|
68
62
|
*/
|
|
69
63
|
type SchedulerPayload<Handler> = Handler extends (
|
|
70
64
|
payload: infer Payload,
|
|
@@ -103,8 +97,6 @@ type SchedulerEventType =
|
|
|
103
97
|
| "schedule:duplicate_warning";
|
|
104
98
|
/**
|
|
105
99
|
* Optional callbacks and policy for a Scheduler capability.
|
|
106
|
-
*
|
|
107
|
-
* @experimental The API surface may change before stabilizing.
|
|
108
100
|
*/
|
|
109
101
|
interface SchedulerOptions<
|
|
110
102
|
Handlers extends SchedulerHandlers = SchedulerCallbacks
|
|
@@ -134,8 +126,6 @@ interface SchedulerOptions<
|
|
|
134
126
|
* Lifecycle job queue; Lifecycle owns the physical alarm and the alarm
|
|
135
127
|
* event loop, and Scheduler runs registered callbacks through Lifecycle's
|
|
136
128
|
* host invocation boundary when its jobs come due.
|
|
137
|
-
*
|
|
138
|
-
* @experimental The API surface may change before stabilizing.
|
|
139
129
|
*/
|
|
140
130
|
declare class Scheduler<
|
|
141
131
|
Handlers extends SchedulerHandlers = SchedulerCallbacks
|
|
@@ -220,4 +210,4 @@ export {
|
|
|
220
210
|
SchedulerCallbacks as s,
|
|
221
211
|
Scheduler as t
|
|
222
212
|
};
|
|
223
|
-
//# sourceMappingURL=scheduler-
|
|
213
|
+
//# sourceMappingURL=scheduler-BCLESHSC.d.ts.map
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { i as _classPrivateFieldInitSpec, n as _classPrivateFieldSet2, r as _assertClassBrand, t as _classPrivateFieldGet2 } from "./classPrivateFieldGet2-DZBYAB34.js";
|
|
2
2
|
import { t as _classPrivateMethodInitSpec } from "./classPrivateMethodInitSpec-qMjJ6sHQ.js";
|
|
3
|
-
import { t as LifecycleCapability } from "./capability-
|
|
3
|
+
import { t as LifecycleCapability } from "./capability-DBAKc6UZ.js";
|
|
4
4
|
import { isDurableObjectCodeUpdateReset, isPlatformFailure, resolveRetryConfig, tryN, validateRetryOptions } from "./retries.js";
|
|
5
5
|
import { parseCronExpression } from "cron-schedule";
|
|
6
6
|
//#region src/schedules/schedule-timing.ts
|
|
@@ -138,8 +138,6 @@ var _Scheduler_brand = /* @__PURE__ */ new WeakSet();
|
|
|
138
138
|
* Lifecycle job queue; Lifecycle owns the physical alarm and the alarm
|
|
139
139
|
* event loop, and Scheduler runs registered callbacks through Lifecycle's
|
|
140
140
|
* host invocation boundary when its jobs come due.
|
|
141
|
-
*
|
|
142
|
-
* @experimental The API surface may change before stabilizing.
|
|
143
141
|
*/
|
|
144
142
|
var Scheduler = class extends LifecycleCapability {
|
|
145
143
|
/**
|
|
@@ -655,4 +653,4 @@ function _emitCreated(result) {
|
|
|
655
653
|
//#endregion
|
|
656
654
|
export { setSchedulerCallbackResolver as n, Scheduler as t };
|
|
657
655
|
|
|
658
|
-
//# sourceMappingURL=scheduler-
|
|
656
|
+
//# sourceMappingURL=scheduler-FIHv2-kJ.js.map
|