@langchain/langgraph-sdk 1.8.10 → 1.9.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +90 -43
- package/dist/client/assistants/index.cjs +180 -0
- package/dist/client/assistants/index.cjs.map +1 -0
- package/dist/client/assistants/index.d.cts +155 -0
- package/dist/client/assistants/index.d.cts.map +1 -0
- package/dist/client/assistants/index.d.ts +155 -0
- package/dist/client/assistants/index.d.ts.map +1 -0
- package/dist/client/assistants/index.js +180 -0
- package/dist/client/assistants/index.js.map +1 -0
- package/dist/client/base.cjs +190 -0
- package/dist/client/base.cjs.map +1 -0
- package/dist/client/base.d.cts +84 -0
- package/dist/client/base.d.cts.map +1 -0
- package/dist/client/base.d.ts +84 -0
- package/dist/client/base.d.ts.map +1 -0
- package/dist/client/base.js +188 -0
- package/dist/client/base.js.map +1 -0
- package/dist/client/crons/index.cjs +159 -0
- package/dist/client/crons/index.cjs.map +1 -0
- package/dist/client/crons/index.d.cts +71 -0
- package/dist/client/crons/index.d.cts.map +1 -0
- package/dist/client/crons/index.d.ts +71 -0
- package/dist/client/crons/index.d.ts.map +1 -0
- package/dist/client/crons/index.js +159 -0
- package/dist/client/crons/index.js.map +1 -0
- package/dist/client/index.cjs +84 -0
- package/dist/client/index.cjs.map +1 -0
- package/dist/client/index.d.cts +63 -0
- package/dist/client/index.d.cts.map +1 -0
- package/dist/client/index.d.ts +63 -0
- package/dist/client/index.d.ts.map +1 -0
- package/dist/client/index.js +83 -0
- package/dist/client/index.js.map +1 -0
- package/dist/client/runs/index.cjs +275 -0
- package/dist/client/runs/index.cjs.map +1 -0
- package/dist/client/runs/index.d.cts +123 -0
- package/dist/client/runs/index.d.cts.map +1 -0
- package/dist/client/runs/index.d.ts +123 -0
- package/dist/client/runs/index.d.ts.map +1 -0
- package/dist/client/runs/index.js +275 -0
- package/dist/client/runs/index.js.map +1 -0
- package/dist/client/store/index.cjs +128 -0
- package/dist/client/store/index.cjs.map +1 -0
- package/dist/client/store/index.d.cts +75 -0
- package/dist/client/store/index.d.cts.map +1 -0
- package/dist/client/store/index.d.ts +75 -0
- package/dist/client/store/index.d.ts.map +1 -0
- package/dist/client/store/index.js +128 -0
- package/dist/client/store/index.js.map +1 -0
- package/dist/client/stream/error.cjs +18 -0
- package/dist/client/stream/error.cjs.map +1 -0
- package/dist/client/stream/error.d.cts +14 -0
- package/dist/client/stream/error.d.cts.map +1 -0
- package/dist/client/stream/error.d.ts +14 -0
- package/dist/client/stream/error.d.ts.map +1 -0
- package/dist/client/stream/error.js +18 -0
- package/dist/client/stream/error.js.map +1 -0
- package/dist/client/stream/handles/index.cjs +3 -0
- package/dist/client/stream/handles/index.d.ts +3 -0
- package/dist/client/stream/handles/index.js +4 -0
- package/dist/client/stream/handles/subagents.cjs +263 -0
- package/dist/client/stream/handles/subagents.cjs.map +1 -0
- package/dist/client/stream/handles/subagents.d.cts +45 -0
- package/dist/client/stream/handles/subagents.d.cts.map +1 -0
- package/dist/client/stream/handles/subagents.d.ts +45 -0
- package/dist/client/stream/handles/subagents.d.ts.map +1 -0
- package/dist/client/stream/handles/subagents.js +262 -0
- package/dist/client/stream/handles/subagents.js.map +1 -0
- package/dist/client/stream/handles/subgraphs.cjs +352 -0
- package/dist/client/stream/handles/subgraphs.cjs.map +1 -0
- package/dist/client/stream/handles/subgraphs.d.cts +82 -0
- package/dist/client/stream/handles/subgraphs.d.cts.map +1 -0
- package/dist/client/stream/handles/subgraphs.d.ts +82 -0
- package/dist/client/stream/handles/subgraphs.d.ts.map +1 -0
- package/dist/client/stream/handles/subgraphs.js +351 -0
- package/dist/client/stream/handles/subgraphs.js.map +1 -0
- package/dist/client/stream/handles/tools.cjs +92 -0
- package/dist/client/stream/handles/tools.cjs.map +1 -0
- package/dist/client/stream/handles/tools.d.cts +26 -0
- package/dist/client/stream/handles/tools.d.cts.map +1 -0
- package/dist/client/stream/handles/tools.d.ts +26 -0
- package/dist/client/stream/handles/tools.d.ts.map +1 -0
- package/dist/client/stream/handles/tools.js +92 -0
- package/dist/client/stream/handles/tools.js.map +1 -0
- package/dist/client/stream/index.cjs +1368 -0
- package/dist/client/stream/index.cjs.map +1 -0
- package/dist/client/stream/index.d.cts +238 -0
- package/dist/client/stream/index.d.cts.map +1 -0
- package/dist/client/stream/index.d.ts +238 -0
- package/dist/client/stream/index.d.ts.map +1 -0
- package/dist/client/stream/index.js +1367 -0
- package/dist/client/stream/index.js.map +1 -0
- package/dist/client/stream/media.cjs +506 -0
- package/dist/client/stream/media.cjs.map +1 -0
- package/dist/client/stream/media.d.cts +164 -0
- package/dist/client/stream/media.d.cts.map +1 -0
- package/dist/client/stream/media.d.ts +164 -0
- package/dist/client/stream/media.d.ts.map +1 -0
- package/dist/client/stream/media.js +505 -0
- package/dist/client/stream/media.js.map +1 -0
- package/dist/client/stream/messages.cjs +635 -0
- package/dist/client/stream/messages.cjs.map +1 -0
- package/dist/client/stream/messages.d.cts +139 -0
- package/dist/client/stream/messages.d.cts.map +1 -0
- package/dist/client/stream/messages.d.ts +139 -0
- package/dist/client/stream/messages.d.ts.map +1 -0
- package/dist/client/stream/messages.js +631 -0
- package/dist/client/stream/messages.js.map +1 -0
- package/dist/client/stream/multi-cursor-buffer.cjs +55 -0
- package/dist/client/stream/multi-cursor-buffer.cjs.map +1 -0
- package/dist/client/stream/multi-cursor-buffer.js +55 -0
- package/dist/client/stream/multi-cursor-buffer.js.map +1 -0
- package/dist/client/stream/subscription.cjs +85 -0
- package/dist/client/stream/subscription.cjs.map +1 -0
- package/dist/client/stream/subscription.d.cts +22 -0
- package/dist/client/stream/subscription.d.cts.map +1 -0
- package/dist/client/stream/subscription.d.ts +22 -0
- package/dist/client/stream/subscription.d.ts.map +1 -0
- package/dist/client/stream/subscription.js +84 -0
- package/dist/client/stream/subscription.js.map +1 -0
- package/dist/client/stream/transport/agent-server.cjs +45 -0
- package/dist/client/stream/transport/agent-server.cjs.map +1 -0
- package/dist/client/stream/transport/agent-server.d.cts +39 -0
- package/dist/client/stream/transport/agent-server.d.cts.map +1 -0
- package/dist/client/stream/transport/agent-server.d.ts +39 -0
- package/dist/client/stream/transport/agent-server.d.ts.map +1 -0
- package/dist/client/stream/transport/agent-server.js +45 -0
- package/dist/client/stream/transport/agent-server.js.map +1 -0
- package/dist/client/stream/transport/constants.cjs +10 -0
- package/dist/client/stream/transport/constants.cjs.map +1 -0
- package/dist/client/stream/transport/constants.js +10 -0
- package/dist/client/stream/transport/constants.js.map +1 -0
- package/dist/client/stream/transport/decoder.cjs +115 -0
- package/dist/client/stream/transport/decoder.cjs.map +1 -0
- package/dist/client/stream/transport/decoder.js +114 -0
- package/dist/client/stream/transport/decoder.js.map +1 -0
- package/dist/client/stream/transport/http.cjs +183 -0
- package/dist/client/stream/transport/http.cjs.map +1 -0
- package/dist/client/stream/transport/http.d.cts +45 -0
- package/dist/client/stream/transport/http.d.cts.map +1 -0
- package/dist/client/stream/transport/http.d.ts +45 -0
- package/dist/client/stream/transport/http.d.ts.map +1 -0
- package/dist/client/stream/transport/http.js +183 -0
- package/dist/client/stream/transport/http.js.map +1 -0
- package/dist/client/stream/transport/index.cjs +3 -0
- package/dist/client/stream/transport/index.js +4 -0
- package/dist/client/stream/transport/queue.cjs +55 -0
- package/dist/client/stream/transport/queue.cjs.map +1 -0
- package/dist/client/stream/transport/queue.js +55 -0
- package/dist/client/stream/transport/queue.js.map +1 -0
- package/dist/client/stream/transport/stream.cjs +79 -0
- package/dist/client/stream/transport/stream.cjs.map +1 -0
- package/dist/client/stream/transport/stream.js +79 -0
- package/dist/client/stream/transport/stream.js.map +1 -0
- package/dist/client/stream/transport/types.d.cts +29 -0
- package/dist/client/stream/transport/types.d.cts.map +1 -0
- package/dist/client/stream/transport/types.d.ts +29 -0
- package/dist/client/stream/transport/types.d.ts.map +1 -0
- package/dist/client/stream/transport/utils.cjs +45 -0
- package/dist/client/stream/transport/utils.cjs.map +1 -0
- package/dist/client/stream/transport/utils.js +39 -0
- package/dist/client/stream/transport/utils.js.map +1 -0
- package/dist/client/stream/transport/websocket.cjs +155 -0
- package/dist/client/stream/transport/websocket.cjs.map +1 -0
- package/dist/client/stream/transport/websocket.d.cts +36 -0
- package/dist/client/stream/transport/websocket.d.cts.map +1 -0
- package/dist/client/stream/transport/websocket.d.ts +36 -0
- package/dist/client/stream/transport/websocket.d.ts.map +1 -0
- package/dist/client/stream/transport/websocket.js +155 -0
- package/dist/client/stream/transport/websocket.js.map +1 -0
- package/dist/client/stream/transport.d.cts +104 -0
- package/dist/client/stream/transport.d.cts.map +1 -0
- package/dist/client/stream/transport.d.ts +104 -0
- package/dist/client/stream/transport.d.ts.map +1 -0
- package/dist/client/stream/types.d.cts +208 -0
- package/dist/client/stream/types.d.cts.map +1 -0
- package/dist/client/stream/types.d.ts +208 -0
- package/dist/client/stream/types.d.ts.map +1 -0
- package/dist/client/threads/index.cjs +271 -0
- package/dist/client/threads/index.cjs.map +1 -0
- package/dist/client/threads/index.d.cts +235 -0
- package/dist/client/threads/index.d.cts.map +1 -0
- package/dist/client/threads/index.d.ts +235 -0
- package/dist/client/threads/index.d.ts.map +1 -0
- package/dist/client/threads/index.js +270 -0
- package/dist/client/threads/index.js.map +1 -0
- package/dist/client/ui-internal/index.cjs +29 -0
- package/dist/client/ui-internal/index.cjs.map +1 -0
- package/dist/client/ui-internal/index.d.cts +11 -0
- package/dist/client/ui-internal/index.d.cts.map +1 -0
- package/dist/client/ui-internal/index.d.ts +11 -0
- package/dist/client/ui-internal/index.d.ts.map +1 -0
- package/dist/client/ui-internal/index.js +29 -0
- package/dist/client/ui-internal/index.js.map +1 -0
- package/dist/client.cjs +35 -1308
- package/dist/client.d.cts +19 -857
- package/dist/client.d.ts +19 -857
- package/dist/client.js +16 -1301
- package/dist/index.cjs +25 -4
- package/dist/index.d.cts +15 -3
- package/dist/index.d.ts +15 -3
- package/dist/index.js +14 -3
- package/dist/react/stream.cjs.map +1 -1
- package/dist/react/stream.custom.cjs +1 -1
- package/dist/react/stream.custom.js +1 -1
- package/dist/react/stream.d.cts +2 -1
- package/dist/react/stream.d.cts.map +1 -1
- package/dist/react/stream.d.ts +2 -1
- package/dist/react/stream.d.ts.map +1 -1
- package/dist/react/stream.js.map +1 -1
- package/dist/react/stream.lgp.cjs +6 -5
- package/dist/react/stream.lgp.cjs.map +1 -1
- package/dist/react/stream.lgp.js +4 -3
- package/dist/react/stream.lgp.js.map +1 -1
- package/dist/react/types.d.cts +1 -1
- package/dist/react/types.d.ts +1 -1
- package/dist/react/types.d.ts.map +1 -1
- package/dist/react-ui/server/server.cjs +1 -1
- package/dist/react-ui/server/server.cjs.map +1 -1
- package/dist/react-ui/server/server.js +1 -1
- package/dist/react-ui/server/server.js.map +1 -1
- package/dist/react-ui/types.cjs.map +1 -1
- package/dist/react-ui/types.d.cts +1 -1
- package/dist/react-ui/types.d.cts.map +1 -1
- package/dist/react-ui/types.d.ts +1 -1
- package/dist/react-ui/types.d.ts.map +1 -1
- package/dist/react-ui/types.js.map +1 -1
- package/dist/stream/assembled-to-message.cjs +121 -0
- package/dist/stream/assembled-to-message.cjs.map +1 -0
- package/dist/stream/assembled-to-message.d.cts +35 -0
- package/dist/stream/assembled-to-message.d.cts.map +1 -0
- package/dist/stream/assembled-to-message.d.ts +35 -0
- package/dist/stream/assembled-to-message.d.ts.map +1 -0
- package/dist/stream/assembled-to-message.js +119 -0
- package/dist/stream/assembled-to-message.js.map +1 -0
- package/dist/stream/channel-registry.cjs +224 -0
- package/dist/stream/channel-registry.cjs.map +1 -0
- package/dist/stream/channel-registry.d.cts +102 -0
- package/dist/stream/channel-registry.d.cts.map +1 -0
- package/dist/stream/channel-registry.d.ts +102 -0
- package/dist/stream/channel-registry.d.ts.map +1 -0
- package/dist/stream/channel-registry.js +224 -0
- package/dist/stream/channel-registry.js.map +1 -0
- package/dist/stream/constants.cjs +11 -0
- package/dist/stream/constants.cjs.map +1 -0
- package/dist/stream/constants.d.cts +10 -0
- package/dist/stream/constants.d.cts.map +1 -0
- package/dist/stream/constants.d.ts +10 -0
- package/dist/stream/constants.d.ts.map +1 -0
- package/dist/stream/constants.js +11 -0
- package/dist/stream/constants.js.map +1 -0
- package/dist/stream/controller.cjs +933 -0
- package/dist/stream/controller.cjs.map +1 -0
- package/dist/stream/controller.d.cts +135 -0
- package/dist/stream/controller.d.cts.map +1 -0
- package/dist/stream/controller.d.ts +135 -0
- package/dist/stream/controller.d.ts.map +1 -0
- package/dist/stream/controller.js +910 -0
- package/dist/stream/controller.js.map +1 -0
- package/dist/stream/discovery/index.d.ts +2 -0
- package/dist/stream/discovery/subagents.cjs +235 -0
- package/dist/stream/discovery/subagents.cjs.map +1 -0
- package/dist/stream/discovery/subagents.d.cts +18 -0
- package/dist/stream/discovery/subagents.d.cts.map +1 -0
- package/dist/stream/discovery/subagents.d.ts +18 -0
- package/dist/stream/discovery/subagents.d.ts.map +1 -0
- package/dist/stream/discovery/subagents.js +235 -0
- package/dist/stream/discovery/subagents.js.map +1 -0
- package/dist/stream/discovery/subgraphs.cjs +153 -0
- package/dist/stream/discovery/subgraphs.cjs.map +1 -0
- package/dist/stream/discovery/subgraphs.d.cts +19 -0
- package/dist/stream/discovery/subgraphs.d.cts.map +1 -0
- package/dist/stream/discovery/subgraphs.d.ts +19 -0
- package/dist/stream/discovery/subgraphs.d.ts.map +1 -0
- package/dist/stream/discovery/subgraphs.js +153 -0
- package/dist/stream/discovery/subgraphs.js.map +1 -0
- package/dist/stream/index.cjs +36 -0
- package/dist/stream/index.d.cts +25 -0
- package/dist/stream/index.d.ts +25 -0
- package/dist/stream/index.js +16 -0
- package/dist/stream/lifecycle-loading-tracker.cjs +83 -0
- package/dist/stream/lifecycle-loading-tracker.cjs.map +1 -0
- package/dist/stream/lifecycle-loading-tracker.js +83 -0
- package/dist/stream/lifecycle-loading-tracker.js.map +1 -0
- package/dist/stream/message-metadata-tracker.cjs +165 -0
- package/dist/stream/message-metadata-tracker.cjs.map +1 -0
- package/dist/stream/message-metadata-tracker.d.cts +24 -0
- package/dist/stream/message-metadata-tracker.d.cts.map +1 -0
- package/dist/stream/message-metadata-tracker.d.ts +24 -0
- package/dist/stream/message-metadata-tracker.d.ts.map +1 -0
- package/dist/stream/message-metadata-tracker.js +165 -0
- package/dist/stream/message-metadata-tracker.js.map +1 -0
- package/dist/stream/message-reconciliation.cjs +118 -0
- package/dist/stream/message-reconciliation.cjs.map +1 -0
- package/dist/stream/message-reconciliation.js +115 -0
- package/dist/stream/message-reconciliation.js.map +1 -0
- package/dist/stream/namespace.cjs +54 -0
- package/dist/stream/namespace.cjs.map +1 -0
- package/dist/stream/namespace.js +49 -0
- package/dist/stream/namespace.js.map +1 -0
- package/dist/stream/projections/channel.cjs +53 -0
- package/dist/stream/projections/channel.cjs.map +1 -0
- package/dist/stream/projections/channel.d.cts +22 -0
- package/dist/stream/projections/channel.d.cts.map +1 -0
- package/dist/stream/projections/channel.d.ts +22 -0
- package/dist/stream/projections/channel.d.ts.map +1 -0
- package/dist/stream/projections/channel.js +53 -0
- package/dist/stream/projections/channel.js.map +1 -0
- package/dist/stream/projections/extension.cjs +29 -0
- package/dist/stream/projections/extension.cjs.map +1 -0
- package/dist/stream/projections/extension.d.cts +7 -0
- package/dist/stream/projections/extension.d.cts.map +1 -0
- package/dist/stream/projections/extension.d.ts +7 -0
- package/dist/stream/projections/extension.d.ts.map +1 -0
- package/dist/stream/projections/extension.js +29 -0
- package/dist/stream/projections/extension.js.map +1 -0
- package/dist/stream/projections/index.cjs +6 -0
- package/dist/stream/projections/index.d.ts +6 -0
- package/dist/stream/projections/index.js +7 -0
- package/dist/stream/projections/media.cjs +81 -0
- package/dist/stream/projections/media.cjs.map +1 -0
- package/dist/stream/projections/media.d.cts +18 -0
- package/dist/stream/projections/media.d.cts.map +1 -0
- package/dist/stream/projections/media.d.ts +18 -0
- package/dist/stream/projections/media.d.ts.map +1 -0
- package/dist/stream/projections/media.js +78 -0
- package/dist/stream/projections/media.js.map +1 -0
- package/dist/stream/projections/messages.cjs +121 -0
- package/dist/stream/projections/messages.cjs.map +1 -0
- package/dist/stream/projections/messages.d.cts +8 -0
- package/dist/stream/projections/messages.d.cts.map +1 -0
- package/dist/stream/projections/messages.d.ts +8 -0
- package/dist/stream/projections/messages.d.ts.map +1 -0
- package/dist/stream/projections/messages.js +121 -0
- package/dist/stream/projections/messages.js.map +1 -0
- package/dist/stream/projections/runtime.cjs +44 -0
- package/dist/stream/projections/runtime.cjs.map +1 -0
- package/dist/stream/projections/runtime.js +44 -0
- package/dist/stream/projections/runtime.js.map +1 -0
- package/dist/stream/projections/tool-calls.cjs +50 -0
- package/dist/stream/projections/tool-calls.cjs.map +1 -0
- package/dist/stream/projections/tool-calls.d.cts +8 -0
- package/dist/stream/projections/tool-calls.d.cts.map +1 -0
- package/dist/stream/projections/tool-calls.d.ts +8 -0
- package/dist/stream/projections/tool-calls.d.ts.map +1 -0
- package/dist/stream/projections/tool-calls.js +50 -0
- package/dist/stream/projections/tool-calls.js.map +1 -0
- package/dist/stream/projections/values.cjs +52 -0
- package/dist/stream/projections/values.cjs.map +1 -0
- package/dist/stream/projections/values.d.cts +7 -0
- package/dist/stream/projections/values.d.cts.map +1 -0
- package/dist/stream/projections/values.d.ts +6 -0
- package/dist/stream/projections/values.d.ts.map +1 -0
- package/dist/stream/projections/values.js +52 -0
- package/dist/stream/projections/values.js.map +1 -0
- package/dist/stream/root-message-projection.cjs +256 -0
- package/dist/stream/root-message-projection.cjs.map +1 -0
- package/dist/stream/root-message-projection.js +256 -0
- package/dist/stream/root-message-projection.js.map +1 -0
- package/dist/stream/store.cjs +32 -0
- package/dist/stream/store.cjs.map +1 -0
- package/dist/stream/store.d.cts +37 -0
- package/dist/stream/store.d.cts.map +1 -0
- package/dist/stream/store.d.ts +37 -0
- package/dist/stream/store.d.ts.map +1 -0
- package/dist/stream/store.js +32 -0
- package/dist/stream/store.js.map +1 -0
- package/dist/stream/submit-coordinator.cjs +399 -0
- package/dist/stream/submit-coordinator.cjs.map +1 -0
- package/dist/stream/submit-coordinator.d.cts +27 -0
- package/dist/stream/submit-coordinator.d.cts.map +1 -0
- package/dist/stream/submit-coordinator.d.ts +27 -0
- package/dist/stream/submit-coordinator.d.ts.map +1 -0
- package/dist/stream/submit-coordinator.js +397 -0
- package/dist/stream/submit-coordinator.js.map +1 -0
- package/dist/stream/tool-calls.cjs +15 -0
- package/dist/stream/tool-calls.cjs.map +1 -0
- package/dist/stream/tool-calls.js +15 -0
- package/dist/stream/tool-calls.js.map +1 -0
- package/dist/stream/types-inference.d.cts +43 -0
- package/dist/stream/types-inference.d.cts.map +1 -0
- package/dist/stream/types-inference.d.ts +43 -0
- package/dist/stream/types-inference.d.ts.map +1 -0
- package/dist/stream/types.d.cts +354 -0
- package/dist/stream/types.d.cts.map +1 -0
- package/dist/stream/types.d.ts +354 -0
- package/dist/stream/types.d.ts.map +1 -0
- package/dist/types.d.cts +2 -1
- package/dist/types.d.cts.map +1 -1
- package/dist/types.d.ts +2 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/ui/index.cjs +1 -1
- package/dist/ui/index.d.cts +3 -3
- package/dist/ui/index.d.ts +3 -3
- package/dist/ui/index.js +1 -1
- package/dist/ui/manager.cjs +1 -1
- package/dist/ui/manager.js +1 -1
- package/dist/ui/messages.cjs +50 -7
- package/dist/ui/messages.cjs.map +1 -1
- package/dist/ui/messages.d.cts.map +1 -1
- package/dist/ui/messages.d.ts.map +1 -1
- package/dist/ui/messages.js +51 -9
- package/dist/ui/messages.js.map +1 -1
- package/dist/ui/orchestrator-custom.cjs +1 -1
- package/dist/ui/orchestrator-custom.js +1 -1
- package/dist/ui/orchestrator.cjs +2 -2
- package/dist/ui/orchestrator.d.cts +1 -1
- package/dist/ui/orchestrator.d.ts +1 -1
- package/dist/ui/orchestrator.d.ts.map +1 -1
- package/dist/ui/orchestrator.js +2 -2
- package/dist/ui/stream/agent.d.cts +1 -1
- package/dist/ui/stream/agent.d.cts.map +1 -1
- package/dist/ui/stream/agent.d.ts +1 -1
- package/dist/ui/stream/agent.d.ts.map +1 -1
- package/dist/ui/stream/base.d.cts +7 -6
- package/dist/ui/stream/base.d.cts.map +1 -1
- package/dist/ui/stream/base.d.ts +7 -6
- package/dist/ui/stream/base.d.ts.map +1 -1
- package/dist/ui/stream/deep-agent.d.cts +1 -1
- package/dist/ui/stream/deep-agent.d.cts.map +1 -1
- package/dist/ui/stream/deep-agent.d.ts +1 -1
- package/dist/ui/stream/deep-agent.d.ts.map +1 -1
- package/dist/ui/stream/index.d.cts +4 -4
- package/dist/ui/stream/index.d.cts.map +1 -1
- package/dist/ui/stream/index.d.ts +4 -4
- package/dist/ui/stream/index.d.ts.map +1 -1
- package/dist/ui/types.d.cts +3 -2
- package/dist/ui/types.d.cts.map +1 -1
- package/dist/ui/types.d.ts +2 -1
- package/dist/ui/types.d.ts.map +1 -1
- package/package.json +18 -8
- package/dist/client.cjs.map +0 -1
- package/dist/client.d.cts.map +0 -1
- package/dist/client.d.ts.map +0 -1
- package/dist/client.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.cjs","names":["ensureMessageInstances","#transportAdapter","#pending","#subscriptions","#seenEventIds","#headlessInterruptsAwaitingTerminal","#pendingSubResolves","#onEventListeners","#extensionsCache","#extensionsEvents","#extensionsEventListeners","#extensionsEndListeners","#mediaHandles","#audioBuffer","MultiCursorBuffer","#imagesBuffer","#videoBuffer","#filesBuffer","#fetchOption","#nextCommandId","#prepareForNextRun","#ensureLifecycleTracking","#send","#consumeEvents","#ensureOpen","#opened","#openPromise","#lifecycleStartPromise","#lifecycleSubId","#subscribeRaw","#lifecycleChannels","#terminalPauseTimer","#terminalPauseSeq","#messagesIterable","StreamingMessageAssembler","#startProjection","toStreamingMessageHandle","#valuesProjection","#outputPromise","#toolCallsIterable","ToolCallAssembler","#subgraphsIterable","SubgraphDiscoveryHandle","#subagentsIterable","SubagentDiscoveryHandle","#ensureMediaDispatcher","#extensionsProxy","#createExtension","#extensionsDispatcherStarted","#extensionsEnded","#mediaDispatcherStarted","MediaAssembler","#mediaAssembler","#ensureExtensionsDispatcher","#startLifecycleWatcher","#lifecycleWatcherStartPromise","#startLifecycleWatcherSse","#startLifecycleWatcherWebSocket","#closed","#lifecycleWatcherHandle","#handleLifecycleWatcherMessage","#applyThreadLevelEffects","#fireOnEvent","isHeadlessToolInterrupt","#sharedStream","#sharedStreamFilter","#subscribeViaSharedStream","#subscribeViaCommand","#scheduleReconcile","#rotationState","#reconcileStream","#computeUnionFilter","#resolvePending","#rejectUncoveredPending","#pumpStream","#handleIncoming","#failThreadWithError","ProtocolError","matchesSubscription","#scheduleTerminalPause"],"sources":["../../../src/client/stream/index.ts"],"sourcesContent":["import type {\n Channel,\n Command,\n CommandResponse,\n Event,\n LifecycleEvent,\n ListCheckpointsResult,\n Message,\n MessagesEvent,\n Namespace,\n RunResult,\n StateForkResult,\n StateGetResult,\n SubscribeParams,\n SubscribeResult,\n ToolsEvent,\n ValuesEvent,\n} from \"@langchain/protocol\";\nimport { matchesSubscription } from \"./subscription.js\";\nimport { MultiCursorBuffer } from \"./multi-cursor-buffer.js\";\nimport { ensureMessageInstances } from \"../../ui/messages.js\";\nimport {\n ToolCallAssembler,\n SubgraphDiscoveryHandle,\n SubgraphHandle,\n SubagentDiscoveryHandle,\n SubagentHandle,\n} from \"./handles/index.js\";\nimport {\n StreamingMessageAssembler,\n toStreamingMessageHandle,\n} from \"./messages.js\";\nimport type { StreamingMessageHandle } from \"./messages.js\";\nimport type { AssembledToolCall } from \"./handles/tools.js\";\nimport { MediaAssembler } from \"./media.js\";\nimport type {\n AnyMediaHandle,\n AudioMedia,\n FileMedia,\n ImageMedia,\n VideoMedia,\n} from \"./media.js\";\nimport type {\n EventSubscription,\n EventForChannel,\n EventForChannels,\n InterruptPayload,\n ThreadExtension,\n ThreadExtensions,\n ThreadModules,\n ThreadStreamOptions,\n SessionOrderingState,\n SubscribeOptions,\n YieldForChannel,\n YieldForChannels,\n} from \"./types.js\";\nimport type { EventStreamHandle, TransportAdapter } from \"./transport.js\";\nimport { ProtocolError } from \"./error.js\";\nimport { NAMESPACE_SEPARATOR } from \"../../stream/constants.js\";\nimport { isHeadlessToolInterrupt } from \"../../headless-tools.js\";\n\ntype PendingCommand = {\n resolve: (response: CommandResponse) => void;\n reject: (error: Error) => void;\n};\n\ntype CommandResultMap = {\n \"run.start\": RunResult;\n \"subscription.subscribe\": SubscribeResult;\n \"subscription.unsubscribe\": Record<string, unknown>;\n \"agent.getTree\": Record<string, unknown>;\n \"input.respond\": Record<string, unknown>;\n \"input.inject\": Record<string, unknown>;\n \"state.get\": StateGetResult;\n \"state.listCheckpoints\": ListCheckpointsResult;\n \"state.fork\": StateForkResult;\n};\n\ntype CommandParamsMap = {\n \"run.start\": Record<string, unknown>;\n \"subscription.subscribe\": SubscribeParams;\n \"subscription.unsubscribe\": { subscription_id: string };\n \"agent.getTree\": { run_id?: string };\n \"input.respond\": Record<string, unknown>;\n \"input.inject\": Record<string, unknown>;\n \"state.get\": Record<string, unknown>;\n \"state.listCheckpoints\": Record<string, unknown>;\n \"state.fork\": Record<string, unknown>;\n};\n\ntype InternalEventSubscription = EventSubscription<unknown> & {\n filter: SubscribeParams;\n push(event: Event): void;\n close(): void;\n pause(): void;\n resume(): void;\n /**\n * Highest sequence observed by the thread before this subscription was\n * registered. Replayed terminal events at or before this point belong to a\n * run that already ended before the subscription existed, so they must not\n * pause the subscription before it can drain server replay.\n */\n registeredAfterSeq: number | undefined;\n /**\n * Per-subscription dedup window. Guards against redelivery during\n * shared-stream rotation overlap and from WebSocket server-side\n * fan-out, while still letting newly-registered subs receive the\n * replayed events that existing subs already consumed. Event IDs\n * are session-local but stable across sessions for the same run\n * (the session's monotonic `_next_seq` processes events in order),\n * so a set-per-sub is sufficient.\n */\n seenEventIds: Set<string>;\n};\n\ntype PendingSubResolve = {\n filter: SubscribeParams;\n resolve: () => void;\n reject: (err: unknown) => void;\n};\n\nconst MESSAGE_LIKE_TYPES = new Set([\n \"human\",\n \"user\",\n \"ai\",\n \"assistant\",\n \"tool\",\n \"system\",\n \"function\",\n \"remove\",\n]);\n\n/**\n * When the state payload has a `messages` array containing plain\n * serialized messages (objects with a recognized `type` field), coerce\n * them into `@langchain/core/messages` class instances so remote runs\n * expose the same shape as in-process runs.\n *\n * Returns the input unchanged when the payload is not an object, does\n * not include a `messages` key, or contains entries that are already\n * class instances / not message-like.\n */\nfunction coerceStateMessages(value: unknown): unknown {\n if (value == null || typeof value !== \"object\" || Array.isArray(value)) {\n return value;\n }\n const state = value as Record<string, unknown>;\n const messages = state.messages;\n if (!Array.isArray(messages) || messages.length === 0) return value;\n\n const needsCoercion = messages.some((msg) => {\n if (msg == null || typeof msg !== \"object\") return false;\n if (typeof (msg as { getType?: () => string }).getType === \"function\") {\n return false;\n }\n const type = (msg as { type?: unknown }).type;\n return typeof type === \"string\" && MESSAGE_LIKE_TYPES.has(type);\n });\n if (!needsCoercion) return value;\n\n return {\n ...state,\n messages: ensureMessageInstances(\n messages as Parameters<typeof ensureMessageInstances>[0]\n ),\n };\n}\n\nfunction namespaceKey(ns: Namespace): string {\n return ns.join(NAMESPACE_SEPARATOR);\n}\n\nfunction maxSeq(\n current: number | undefined,\n next: number | undefined\n): number | undefined {\n if (next == null) return current;\n if (current == null) return next;\n return Math.max(current, next);\n}\n\nconst ROOT_TERMINAL_LIFECYCLE_EVENTS = new Set([\n \"completed\",\n \"failed\",\n \"interrupted\",\n]);\n\n/**\n * Detect a root-namespace terminal lifecycle event. Used by\n * `#startProjection`'s `endOnRootTerminal` guard to settle per-run\n * dispatchers regardless of whether the shared-stream pause logic\n * applies to their underlying subscription.\n */\nfunction isRootTerminalLifecycle(event: Event): boolean {\n if (event.method !== \"lifecycle\") return false;\n if (event.params.namespace.length !== 0) return false;\n const data = event.params.data as { event?: string } | undefined;\n return data?.event != null && ROOT_TERMINAL_LIFECYCLE_EVENTS.has(data.event);\n}\n\nfunction namespaceListsEqual(\n a: readonly Namespace[] | undefined,\n b: readonly Namespace[] | undefined\n): boolean {\n if (a === b) return true;\n if (a === undefined || b === undefined) return false;\n if (a.length !== b.length) return false;\n const aKeys = new Set<string>();\n for (const ns of a) aKeys.add(namespaceKey(ns));\n for (const ns of b) {\n if (!aKeys.has(namespaceKey(ns))) return false;\n }\n return true;\n}\n\n/**\n * Structural equality on filters. Two filters are equal iff they\n * request the same channel set, the same namespace prefix set\n * (with `undefined` meaning wildcard), and the same depth\n * (with `undefined` meaning unbounded).\n */\nfunction filterEqual(\n a: SubscribeParams | null,\n b: SubscribeParams | null\n): boolean {\n if (a === b) return true;\n if (a == null || b == null) return false;\n if (a.channels.length !== b.channels.length) return false;\n const aChannels = new Set(a.channels as Channel[]);\n for (const ch of b.channels as Channel[]) {\n if (!aChannels.has(ch)) return false;\n }\n if (!namespaceListsEqual(a.namespaces, b.namespaces)) return false;\n const aDepth = a.depth ?? null;\n const bDepth = b.depth ?? null;\n if (aDepth !== bDepth) return false;\n return true;\n}\n\nfunction isPrefix(prefix: Namespace, candidate: Namespace): boolean {\n if (prefix.length > candidate.length) return false;\n for (let i = 0; i < prefix.length; i += 1) {\n if (prefix[i] !== candidate[i]) return false;\n }\n return true;\n}\n\n/**\n * Whether the `coverer` filter delivers every event a subscription\n * opened with `target` could want.\n *\n * Rules:\n * - Channels: target.channels must be a subset of coverer.channels.\n * - Namespaces:\n * - coverer wildcard (`undefined`) → coverer covers all prefixes.\n * - coverer explicit + target wildcard → not covered.\n * - both explicit → every target prefix must have some coverer\n * prefix that is its ancestor (coverer's prefix delivers events\n * for all descendants, modulo depth).\n * - Depth:\n * - coverer unbounded (`undefined`) → depth is covered.\n * - otherwise, for each target prefix `tp` covered by coverer\n * prefix `cp`, the maximum event depth target wants\n * (`tp.length + (target.depth ?? ∞) - cp.length`) must be\n * `<= coverer.depth`. For a wildcard target with bounded depth,\n * target's max absolute depth is `target.depth` (prefix is `[]`).\n */\nfunction filterCovers(\n coverer: SubscribeParams,\n target: SubscribeParams\n): boolean {\n const covererChannels = new Set(coverer.channels as Channel[]);\n for (const ch of target.channels as Channel[]) {\n if (!covererChannels.has(ch)) return false;\n }\n\n const covererDepth = coverer.depth;\n const targetDepth = target.depth;\n\n if (coverer.namespaces == null) {\n if (covererDepth == null) return true;\n if (targetDepth == null) return false;\n return targetDepth <= covererDepth;\n }\n\n if (target.namespaces == null) return false;\n\n for (const tp of target.namespaces) {\n const covered = coverer.namespaces.some((cp) => {\n if (!isPrefix(cp, tp)) return false;\n if (covererDepth == null) return true;\n if (targetDepth == null) return false;\n return tp.length - cp.length + targetDepth <= covererDepth;\n });\n if (!covered) return false;\n }\n return true;\n}\n\nfunction normalizeSubscribeParams(\n paramsOrChannels: SubscribeParams | Channel | readonly Channel[],\n options: SubscribeOptions = {}\n): SubscribeParams {\n if (\n typeof paramsOrChannels === \"object\" &&\n !Array.isArray(paramsOrChannels) &&\n \"channels\" in paramsOrChannels\n ) {\n return paramsOrChannels;\n }\n\n const channels = Array.isArray(paramsOrChannels)\n ? ([...paramsOrChannels] as Channel[])\n : ([paramsOrChannels] as Channel[]);\n return {\n ...options,\n channels,\n };\n}\n\n/**\n * Async iterable handle for raw event subscriptions.\n *\n * An optional `transform` maps each incoming event before it is queued\n * or delivered to a waiting consumer. This is used by named custom\n * channel subscriptions (e.g. `\"custom:a2a\"`) to unwrap the payload\n * so callers receive the raw emitted data instead of the protocol\n * event envelope.\n */\nexport class SubscriptionHandle<TEvent extends Event = Event, TYield = TEvent>\n implements AsyncIterable<TYield>, EventSubscription<TYield>\n{\n readonly subscriptionId: string;\n readonly params: SubscribeParams;\n private readonly queue: TYield[] = [];\n private readonly waiters: Array<(value: IteratorResult<TYield>) => void> = [];\n private closed = false;\n private paused = false;\n private resumeResolve?: () => void;\n private readonly onUnsubscribe: (id: string) => Promise<void>;\n private readonly transform: (event: TEvent) => TYield;\n\n constructor(\n subscriptionId: string,\n params: SubscribeParams,\n onUnsubscribe: (id: string) => Promise<void>,\n transform?: (event: TEvent) => TYield\n ) {\n this.subscriptionId = subscriptionId;\n this.params = params;\n this.onUnsubscribe = onUnsubscribe;\n this.transform = transform ?? ((event) => event as unknown as TYield);\n }\n\n push(event: TEvent): void {\n if (this.closed) {\n return;\n }\n const value = this.transform(event);\n const waiter = this.waiters.shift();\n if (waiter) {\n waiter({ done: false, value });\n return;\n }\n this.queue.push(value);\n }\n\n /**\n * Pause the subscription: resolve all waiting iterators with `done: true`\n * so `for await` loops exit, but keep the subscription alive. New events\n * arriving while paused are still buffered. Call `resume()` to allow\n * iterators to consume again.\n */\n pause(): void {\n if (this.closed) return;\n this.paused = true;\n while (this.waiters.length > 0) {\n this.waiters.shift()?.({ done: true, value: undefined });\n }\n }\n\n /**\n * Resume a paused subscription so new `for await` loops can consume\n * buffered and future events.\n */\n resume(): void {\n this.paused = false;\n this.resumeResolve?.();\n this.resumeResolve = undefined;\n }\n\n /**\n * Returns a promise that resolves when `resume()` is called. Resolves\n * immediately if not currently paused.\n */\n waitForResume(): Promise<void> {\n if (!this.paused) return Promise.resolve();\n return new Promise<void>((resolve) => {\n this.resumeResolve = resolve;\n });\n }\n\n get isPaused(): boolean {\n return this.paused;\n }\n\n close(): void {\n this.closed = true;\n this.paused = false;\n while (this.waiters.length > 0) {\n this.waiters.shift()?.({ done: true, value: undefined });\n }\n // A paused iterator may be parked on `waitForResume()` instead of\n // on a regular iterator waiter. Resolving here prevents closed\n // subscriptions from stranding pumps that observe `isPaused` and\n // block on `waitForResume()` (e.g. the root pump in\n // `StreamController`).\n this.resumeResolve?.();\n this.resumeResolve = undefined;\n }\n\n async unsubscribe(): Promise<void> {\n if (this.closed) {\n return;\n }\n this.close();\n await this.onUnsubscribe(this.subscriptionId);\n }\n\n [Symbol.asyncIterator](): AsyncIterator<TYield> {\n return {\n next: async () => {\n if (this.queue.length > 0) {\n const value = this.queue.shift()!;\n return { done: false, value };\n }\n if (this.closed || this.paused) {\n return { done: true, value: undefined };\n }\n return await new Promise<IteratorResult<TYield>>((resolve) => {\n this.waiters.push(resolve);\n });\n },\n return: async () => {\n this.close();\n return { done: true, value: undefined };\n },\n };\n }\n}\n\n/**\n * High-level wrapper around a protocol connection to a specific thread.\n *\n * In the thread-centric protocol, threads are durable (backed by\n * checkpoints) and connections are ephemeral. A `ThreadStream` is the\n * client-side handle for interacting with a thread: starting runs,\n * subscribing to events, consuming assembled projections (`messages`,\n * `values`, `toolCalls`, etc.), and responding to interrupts.\n *\n * Construct via `client.threads.stream(threadId?, { assistantId? })`.\n *\n * @typeParam TExtensions - Optional map of `{ name: payload }` pairs\n * describing the transformer projections the bound assistant exposes\n * on `custom:<name>` channels. Narrows `thread.extensions.<name>` to\n * `ThreadExtension<payload>`. Defaults to `Record<string, unknown>`.\n */\nexport class ThreadStream<\n TExtensions extends Record<string, unknown> = Record<string, unknown>,\n> {\n readonly threadId: string;\n readonly ordering: SessionOrderingState = {};\n readonly run: ThreadModules[\"run\"];\n readonly agent: ThreadModules[\"agent\"];\n readonly input: ThreadModules[\"input\"];\n readonly state: ThreadModules[\"state\"];\n\n /**\n * Whether the run was interrupted (a lifecycle \"interrupted\" event\n * was received). Mirrors the in-process `run.interrupted`.\n */\n interrupted = false;\n\n /**\n * Interrupt payloads collected during the run, if any.\n * Mirrors the in-process `run.interrupts`.\n */\n readonly interrupts: InterruptPayload[] = [];\n\n readonly assistantId: string;\n\n #nextCommandId: number;\n readonly #transportAdapter: TransportAdapter;\n readonly #pending = new Map<number, PendingCommand>();\n readonly #subscriptions = new Map<string, InternalEventSubscription>();\n // Tracks `event_id`s that have already been processed for thread-level\n // side effects (interrupt tracking, `input.requested` capture) AND to\n // drop duplicate fan-outs during the overlap window of SSE stream\n // rotation (see `#reconcileStream`): the old stream and the new stream\n // are both pumping briefly, and the server replays buffered events on\n // new streams, so the same `event_id` can arrive twice.\n //\n // The set grows at the rate of unique events per thread, but its\n // lifetime is bounded by `ThreadStream` (it's GC'd when the run\n // completes and the stream is disposed), and each entry is a short\n // numeric string. A bounded sliding-window alternative was considered\n // and rejected: any cap smaller than the server's replay buffer\n // (`maxBufferSize` in `protocol/session`) would risk evicting still-\n // live ids and re-processing real events, which trades a hypothetical\n // memory win for a real correctness failure mode and cross-repo\n // coupling. Revisit only if a concrete long-run memory profile\n // justifies the added complexity.\n readonly #seenEventIds = new Set<string>();\n /**\n * Headless tool interrupts can be auto-resumed by the React hook before\n * the shared SSE content pump has processed the root `interrupted`\n * lifecycle event. `respondInput()` clears `interrupts`, so keep a\n * short-lived marker here until that stale terminal passes through the\n * content pump and we can avoid pausing it.\n */\n readonly #headlessInterruptsAwaitingTerminal = new Set<string>();\n #closed = false;\n #opened = false;\n #openPromise?: Promise<void>;\n\n // ---------- Shared SSE stream state ----------\n // Under the SSE transport a single connection is shared across all\n // subscriptions. Its filter is the union of every active subscription's\n // filter (`#computeUnionFilter`); the client fans out incoming events\n // to matching subscriptions via `matchesSubscription` in\n // `#handleIncoming`. The stream rotates (open-before-close) whenever\n // `subscribe`/`unsubscribe` changes the channel union.\n #sharedStream: EventStreamHandle | null = null;\n #sharedStreamFilter: SubscribeParams | null = null;\n #rotationState: \"idle\" | \"scheduled\" | \"rotating\" = \"idle\";\n /** Pending `subscribe()` promises waiting for a covering rotation. */\n readonly #pendingSubResolves: PendingSubResolve[] = [];\n #terminalPauseTimer: ReturnType<typeof setTimeout> | undefined;\n #terminalPauseSeq: number | null | undefined;\n\n #lifecycleSubId: string | null = null;\n #lifecycleStartPromise?: Promise<void>;\n\n // ---------- v2 lifecycle watcher ----------\n // Dedicated wildcard `{channels: [\"lifecycle\", \"input\"]}` stream\n // opened by `submitRun` / `respondInput` (v2 entry points). Carries\n // every interrupt and lifecycle event at any depth so consumers of\n // `onEvent` (discovery runners, nested HITL capture) don't depend\n // on the content pump's narrow filter.\n //\n // - SSE: opened via `openEventStream` as an independent stream\n // that sits outside `#computeUnionFilter`, so the shared SSE\n // content pump stays narrow. Tracked in `#lifecycleWatcherHandle`\n // so `close()` can tear it down.\n // - WebSocket: opened via `#subscribeRaw` on the shared command\n // connection. The resulting `SubscriptionHandle` is managed by\n // the normal `#subscriptions` lifecycle, so no separate handle\n // reference is needed — `close()` fans `SubscriptionHandle.close`\n // across all registered subs.\n #lifecycleWatcherHandle: EventStreamHandle | null = null;\n #lifecycleWatcherStartPromise?: Promise<void>;\n\n // ---------- v2 unified event fan-out ----------\n // Listeners invoked once per globally-unique event across BOTH the\n // content pump and the lifecycle watcher. Used by `StreamController`\n // to consume discovery and interrupt events without opening extra\n // server subscriptions.\n readonly #onEventListeners = new Set<(event: Event) => void>();\n\n #messagesIterable?: AsyncIterable<StreamingMessageHandle>;\n #valuesProjection?: AsyncIterable<unknown> & PromiseLike<unknown>;\n #toolCallsIterable?: AsyncIterable<AssembledToolCall>;\n #subgraphsIterable?: AsyncIterable<SubgraphHandle>;\n #subagentsIterable?: AsyncIterable<SubagentHandle>;\n #outputPromise?: Promise<unknown>;\n #extensionsProxy?: ThreadExtensions<TExtensions>;\n readonly #extensionsCache = new Map<string, ThreadExtension<unknown>>();\n\n /**\n * Shared state for the single `\"custom\"` channel subscription that\n * backs every `thread.extensions.<name>` handle.\n *\n * One subscription is opened eagerly from {@link run.start} (mirroring\n * the {@link values} eager-start pattern) so that per-name handles\n * created before, during, or after the run can all resolve correctly.\n *\n * - `events` retains every custom event for backfill into\n * late-constructed handles.\n * - `eventListeners` fan new events out to live per-name handlers.\n * - `endListeners` fire when the dispatcher's run terminates, so each\n * handle can resolve its `PromiseLike` side with its last-seen\n * payload.\n */\n #extensionsDispatcherStarted = false;\n #extensionsEnded = false;\n readonly #extensionsEvents: Event[] = [];\n readonly #extensionsEventListeners: Array<(event: Event) => void> = [];\n readonly #extensionsEndListeners: Array<() => void> = [];\n\n /**\n * Shared state for the single `messages`-channel subscription that\n * backs every media handle iterable (`thread.audio`, `thread.images`,\n * `thread.video`, `thread.files`). One subscription serves all four\n * iterables; per-type buffers track the handles already emitted so\n * late attachers replay through {@link MultiCursorBuffer}.\n */\n #mediaDispatcherStarted = false;\n #mediaAssembler: MediaAssembler | undefined;\n /** Object URLs minted by media handles, tracked for {@link close} cleanup. */\n readonly #mediaHandles = new Set<AnyMediaHandle>();\n readonly #audioBuffer = new MultiCursorBuffer<AudioMedia>();\n readonly #imagesBuffer = new MultiCursorBuffer<ImageMedia>();\n readonly #videoBuffer = new MultiCursorBuffer<VideoMedia>();\n readonly #filesBuffer = new MultiCursorBuffer<FileMedia>();\n readonly #fetchOption: typeof fetch | undefined;\n\n constructor(\n transportAdapter: TransportAdapter,\n options: ThreadStreamOptions\n ) {\n if (!options?.assistantId) {\n throw new Error(\"ThreadStream requires an assistantId option.\");\n }\n this.#transportAdapter = transportAdapter;\n this.threadId = transportAdapter.threadId;\n this.assistantId = options.assistantId;\n this.#nextCommandId = options.startingCommandId ?? 1;\n this.#fetchOption = options.fetch;\n this.run = {\n start: async (params) => {\n this.#prepareForNextRun();\n this.#ensureLifecycleTracking();\n // Eagerly start the values projection so `thread.output` /\n // `thread.values` resolve with the final state regardless of\n // whether they are accessed before or after the run completes.\n // Without this, late access would open a fresh subscription\n // that misses every `values` event from the run.\n void this.values;\n // NOTE: `thread.extensions.<name>` is NOT eagerly subscribed.\n // The shared custom dispatcher is opened lazily on first\n // extension access and relies on the server's event buffer to\n // replay any custom events that were emitted before the\n // subscription landed. This keeps the zero-extensions hot path\n // free of an unused `custom` subscription per run.\n return await this.#send(\"run.start\", {\n ...params,\n assistant_id: this.assistantId,\n });\n },\n };\n this.agent = {\n getTree: async (params = {}) =>\n (await this.#send(\"agent.getTree\", params)) as {\n tree: unknown;\n } as never,\n };\n this.input = {\n respond: async (params) => {\n this.#prepareForNextRun();\n this.#ensureLifecycleTracking();\n // See note in `run.start` — keep `thread.output` working\n // across resumes regardless of access order.\n void this.values;\n await this.#send(\n \"input.respond\",\n params as unknown as CommandParamsMap[\"input.respond\"]\n );\n },\n inject: async (params) => {\n await this.#send(\n \"input.inject\",\n params as unknown as CommandParamsMap[\"input.inject\"]\n );\n },\n };\n this.state = {\n get: async (params) =>\n await this.#send(\n \"state.get\",\n params as unknown as CommandParamsMap[\"state.get\"]\n ),\n listCheckpoints: async (params) =>\n await this.#send(\n \"state.listCheckpoints\",\n params as unknown as CommandParamsMap[\"state.listCheckpoints\"]\n ),\n fork: async (params) =>\n await this.#send(\n \"state.fork\",\n params as unknown as CommandParamsMap[\"state.fork\"]\n ),\n };\n // SSE transports deliver events via openEventStream — the events()\n // iterable is inert. Skip the consumer loop in that case.\n if (this.#transportAdapter.openEventStream == null) {\n void this.#consumeEvents();\n }\n }\n\n /**\n * Ensure the underlying transport is connected.\n *\n * For HTTP/SSE this is a no-op. For WebSocket this performs the\n * handshake. Called lazily on first command; safe to call multiple times.\n */\n async #ensureOpen(): Promise<void> {\n if (this.#opened) return;\n if (this.#openPromise == null) {\n this.#openPromise = this.#transportAdapter.open().then(() => {\n this.#opened = true;\n });\n }\n await this.#openPromise;\n }\n\n /**\n * Channels bundled into every lazy getter's SSE filter so that\n * interrupt tracking works without a separate lifecycle subscription.\n */\n #lifecycleChannels(): Channel[] {\n return [\"lifecycle\", \"input\"];\n }\n\n /**\n * Lazily start a dedicated lifecycle+input subscription so that\n * `thread.interrupted` / `thread.interrupts` work even when the\n * caller never accesses a lazy getter (e.g. they only call\n * `run.start` and `subscribe({ channels: [\"custom:...\"] })`).\n *\n * Idempotent and fire-and-forget — invoked from `run.start` and\n * `input.respond`.\n */\n #ensureLifecycleTracking(): void {\n if (this.#lifecycleStartPromise != null) return;\n this.#lifecycleStartPromise = (async () => {\n const sub = await this.#subscribeRaw({\n channels: this.#lifecycleChannels(),\n });\n this.#lifecycleSubId = sub.subscriptionId;\n })().catch(() => undefined);\n }\n\n /**\n * Reset interrupt state and resume all paused user subscriptions.\n * Called before `run.start()` and `input.respond()` so that\n * iterators on the same handle pick up the next run's events.\n */\n #prepareForNextRun(): void {\n this.interrupted = false;\n this.interrupts.length = 0;\n if (this.#terminalPauseTimer != null) {\n clearTimeout(this.#terminalPauseTimer);\n this.#terminalPauseTimer = undefined;\n }\n this.#terminalPauseSeq = undefined;\n for (const [id, subscription] of this.#subscriptions) {\n if (id !== this.#lifecycleSubId) {\n subscription.resume();\n }\n }\n }\n\n // ---------- Lazy getters mirroring in-process GraphRunStream ----------\n\n /**\n * Streaming messages. Each `for await` loop gets an independent cursor\n * over the shared buffer; late consumers see all previously emitted\n * messages. Mirrors the in-process `run.messages`.\n */\n get messages(): AsyncIterable<StreamingMessageHandle> {\n if (this.#messagesIterable) return this.#messagesIterable;\n const buffer = new MultiCursorBuffer<StreamingMessageHandle>();\n this.#messagesIterable = buffer;\n const assembler = new StreamingMessageAssembler();\n void this.#startProjection(\n [\"messages\", ...this.#lifecycleChannels()],\n (event) => {\n if (event.method !== \"messages\") return;\n const msg = assembler.consume(event as MessagesEvent);\n if (msg) buffer.push(toStreamingMessageHandle(msg));\n },\n () => buffer.close()\n );\n return buffer;\n }\n\n /**\n * State values. Iterable for intermediate snapshots; also\n * `PromiseLike` — `await thread.values` resolves with the final\n * state. Mirrors the in-process `run.values`.\n */\n get values(): AsyncIterable<unknown> & PromiseLike<unknown> {\n if (this.#valuesProjection) return this.#valuesProjection;\n const buffer = new MultiCursorBuffer<unknown>();\n let lastValue: unknown;\n let resolveOutput!: (value: unknown) => void;\n const outputPromise = new Promise<unknown>((resolve) => {\n resolveOutput = resolve;\n });\n this.#outputPromise = outputPromise;\n const projection = Object.assign(buffer, {\n then: <TResult1 = unknown, TResult2 = never>(\n onfulfilled?:\n | ((value: unknown) => TResult1 | PromiseLike<TResult1>)\n | null,\n onrejected?:\n | ((reason: unknown) => TResult2 | PromiseLike<TResult2>)\n | null\n ): Promise<TResult1 | TResult2> =>\n outputPromise.then(onfulfilled, onrejected),\n }) as AsyncIterable<unknown> & PromiseLike<unknown>;\n this.#valuesProjection = projection;\n void this.#startProjection(\n [\"values\", ...this.#lifecycleChannels()],\n (event) => {\n if (event.method !== \"values\") return;\n const data = coerceStateMessages((event as ValuesEvent).params.data);\n lastValue = data;\n buffer.push(data);\n },\n () => {\n resolveOutput(lastValue);\n buffer.close();\n }\n );\n return projection;\n }\n\n /**\n * Tool calls with promise-based output/status/error.\n * Mirrors the in-process `run.toolCalls`.\n */\n get toolCalls(): AsyncIterable<AssembledToolCall> {\n if (this.#toolCallsIterable) return this.#toolCallsIterable;\n const buffer = new MultiCursorBuffer<AssembledToolCall>();\n this.#toolCallsIterable = buffer;\n const assembler = new ToolCallAssembler();\n void this.#startProjection(\n [\"tools\", ...this.#lifecycleChannels()],\n (event) => {\n if (event.method !== \"tools\") return;\n const tc = assembler.consume(event as ToolsEvent);\n if (tc) buffer.push(tc);\n },\n () => buffer.close()\n );\n return buffer;\n }\n\n /**\n * Discovered subgraphs. Mirrors the in-process `run.subgraphs`.\n */\n get subgraphs(): AsyncIterable<SubgraphHandle> {\n if (this.#subgraphsIterable) return this.#subgraphsIterable;\n const buffer = new MultiCursorBuffer<SubgraphHandle>();\n this.#subgraphsIterable = buffer;\n void (async () => {\n const rawHandle = await this.#subscribeRaw({\n channels: [\"tools\", ...this.#lifecycleChannels()],\n });\n const discovery = new SubgraphDiscoveryHandle(rawHandle, this, []);\n for await (const sub of discovery) {\n buffer.push(sub);\n }\n buffer.close();\n })();\n return buffer;\n }\n\n /**\n * Discovered subagents.\n */\n get subagents(): AsyncIterable<SubagentHandle> {\n if (this.#subagentsIterable) return this.#subagentsIterable;\n const buffer = new MultiCursorBuffer<SubagentHandle>();\n this.#subagentsIterable = buffer;\n void (async () => {\n const rawHandle = await this.#subscribeRaw({\n channels: [\"tools\", ...this.#lifecycleChannels()],\n });\n const discovery = new SubagentDiscoveryHandle(rawHandle, this);\n for await (const sub of discovery) {\n buffer.push(sub);\n }\n buffer.close();\n })();\n return buffer;\n }\n\n /**\n * Audio media handles, one per message containing at least one\n * `AudioBlock`. Each `for await` opens an independent cursor over\n * the shared buffer; late consumers replay every previously emitted\n * audio handle.\n *\n * Yields one item per message on the first matching\n * `content-block-start` — messages with no audio blocks are skipped.\n */\n get audio(): AsyncIterable<AudioMedia> {\n this.#ensureMediaDispatcher();\n return this.#audioBuffer;\n }\n\n /**\n * Image media handles, one per message containing at least one\n * `ImageBlock`. See {@link audio} for shared semantics.\n */\n get images(): AsyncIterable<ImageMedia> {\n this.#ensureMediaDispatcher();\n return this.#imagesBuffer;\n }\n\n /**\n * Video media handles, one per message containing at least one\n * `VideoBlock`. See {@link audio} for shared semantics.\n */\n get video(): AsyncIterable<VideoMedia> {\n this.#ensureMediaDispatcher();\n return this.#videoBuffer;\n }\n\n /**\n * File media handles, one per message containing at least one\n * `FileBlock`. See {@link audio} for shared semantics.\n */\n get files(): AsyncIterable<FileMedia> {\n this.#ensureMediaDispatcher();\n return this.#filesBuffer;\n }\n\n /**\n * Promise that resolves with the final state value when the run\n * completes. Shares the `values` getter's SSE connection.\n * Mirrors the in-process `run.output`.\n */\n get output(): Promise<unknown> {\n // Accessing `this.values` ensures the projection is started.\n void this.values;\n return this.#outputPromise!;\n }\n\n /**\n * Proxy over compile-time {@link StreamTransformer} projections\n * exposed by the bound assistant on `custom:<name>` channels.\n *\n * Each access (e.g. `thread.extensions.toolActivity`) lazily opens a\n * dedicated `custom:<name>` subscription, returns a cached\n * {@link ThreadExtension} handle that is both `AsyncIterable<T>`\n * (streaming items as they arrive) and `PromiseLike<T>` (resolves\n * with the final value when the run terminates), and reuses the same\n * handle on subsequent access.\n *\n * Mirrors the in-process `run.extensions.<name>` shape.\n */\n get extensions(): ThreadExtensions<TExtensions> {\n if (this.#extensionsProxy) return this.#extensionsProxy;\n const cache = this.#extensionsCache;\n const createExtension = (name: string) => this.#createExtension(name);\n this.#extensionsProxy = new Proxy(\n Object.create(null) as ThreadExtensions<TExtensions>,\n {\n get: (_target, prop) => {\n if (typeof prop !== \"string\") return undefined;\n const cached = cache.get(prop);\n if (cached) return cached;\n const extension = createExtension(prop);\n cache.set(prop, extension);\n return extension;\n },\n has: (_target, prop) => typeof prop === \"string\",\n }\n );\n return this.#extensionsProxy;\n }\n\n /**\n * Lazily open one shared subscription on the `custom` channel that\n * buffers every custom event for this run and fans it out to any\n * per-name extension handles.\n *\n * Deliberately **lazy**: the dispatcher only starts on first access\n * to `thread.extensions.<name>`. Runs that never touch extensions\n * pay no subscription cost. Runs that touch extensions after events\n * have already fired rely on the server's per-session event buffer,\n * which replays matching events to new subscriptions.\n *\n * Each handle retains a PromiseLike that resolves with the\n * transformer's last-observed payload, independent of when the\n * caller grabs the handle (before, during, or after the run), as\n * long as the server still has the events buffered.\n *\n * Idempotent. Invoked only from {@link #createExtension}.\n */\n #ensureExtensionsDispatcher(): void {\n if (this.#extensionsDispatcherStarted) return;\n this.#extensionsDispatcherStarted = true;\n void this.#startProjection(\n [\"custom\", ...this.#lifecycleChannels()],\n (event) => {\n if (event.method !== \"custom\") return;\n this.#extensionsEvents.push(event);\n for (const listener of this.#extensionsEventListeners) {\n listener(event);\n }\n },\n () => {\n this.#extensionsEnded = true;\n const listeners = this.#extensionsEndListeners.splice(0);\n for (const listener of listeners) listener();\n },\n // Late-bound dispatchers (created after the run already terminated)\n // are skipped by the shared-stream pause logic — their\n // `registeredAfterSeq` is already past the terminal seq, which is\n // intended to keep nested replays draining for raw `subscribe()`\n // callers. The dispatcher needs the OPPOSITE: once the run's\n // terminal lifecycle replays through, settle the per-name\n // `PromiseLike`s with their last-observed payload. Detect the\n // terminal explicitly here so a late `thread.extensions.<name>`\n // access still resolves.\n { endOnRootTerminal: true }\n );\n }\n\n /**\n * Open the single shared `messages`-channel subscription that backs\n * every media iterable (audio/images/video/files). Idempotent.\n *\n * The {@link MediaAssembler} fans out to four per-type\n * {@link MultiCursorBuffer}s; each buffer feeds its corresponding\n * lazy getter. One handle is yielded per `(messageId, blockType)` on\n * the first matching `content-block-start`, so messages without any\n * media blocks of a given type never appear on that iterable.\n */\n #ensureMediaDispatcher(): void {\n if (this.#mediaDispatcherStarted) return;\n this.#mediaDispatcherStarted = true;\n const assembler = new MediaAssembler({\n fetch: this.#fetchOption,\n onAudio: (m) => {\n this.#mediaHandles.add(m);\n this.#audioBuffer.push(m);\n },\n onImage: (m) => {\n this.#mediaHandles.add(m);\n this.#imagesBuffer.push(m);\n },\n onVideo: (m) => {\n this.#mediaHandles.add(m);\n this.#videoBuffer.push(m);\n },\n onFile: (m) => {\n this.#mediaHandles.add(m);\n this.#filesBuffer.push(m);\n },\n });\n this.#mediaAssembler = assembler;\n void this.#startProjection(\n [\"messages\", ...this.#lifecycleChannels()],\n (event) => {\n if (event.method !== \"messages\") return;\n assembler.consume(event as MessagesEvent);\n },\n () => {\n assembler.close();\n this.#audioBuffer.close();\n this.#imagesBuffer.close();\n this.#videoBuffer.close();\n this.#filesBuffer.close();\n }\n );\n }\n\n /**\n * Build a single {@link ThreadExtension} handle for a named\n * `custom:<name>` projection.\n *\n * The handle reads from the shared extensions dispatcher: past events\n * matching {@link name} are backfilled on construction, future events\n * arrive via a registered listener, and the handle's `PromiseLike`\n * side resolves with its last-seen payload once the run terminates\n * (which may already have happened, in which case it resolves on the\n * next microtask).\n */\n #createExtension(name: string): ThreadExtension<unknown> {\n this.#ensureExtensionsDispatcher();\n\n const buffer = new MultiCursorBuffer<unknown>();\n let lastValue: unknown;\n let resolveFinal!: (value: unknown) => void;\n const finalPromise = new Promise<unknown>((resolve) => {\n resolveFinal = resolve;\n });\n\n const handleEvent = (event: Event) => {\n const data = event.params.data as\n | {\n name?: string;\n payload?: unknown;\n }\n | undefined;\n if (data?.name !== name) return;\n lastValue = data.payload;\n buffer.push(data.payload);\n };\n\n // Backfill from events already seen by the dispatcher so handles\n // constructed mid-run or post-run still observe their payload.\n for (const event of this.#extensionsEvents) handleEvent(event);\n\n // Live events — routed through the shared dispatcher.\n this.#extensionsEventListeners.push(handleEvent);\n\n const settle = () => {\n resolveFinal(lastValue);\n buffer.close();\n };\n if (this.#extensionsEnded) {\n settle();\n } else {\n this.#extensionsEndListeners.push(settle);\n }\n\n return Object.assign(buffer, {\n then: <TResult1 = unknown, TResult2 = never>(\n onfulfilled?:\n | ((value: unknown) => TResult1 | PromiseLike<TResult1>)\n | null,\n onrejected?:\n | ((reason: unknown) => TResult2 | PromiseLike<TResult2>)\n | null\n ): Promise<TResult1 | TResult2> =>\n finalPromise.then(onfulfilled, onrejected),\n }) as ThreadExtension<unknown>;\n }\n\n /**\n * Generic projection starter: opens a raw subscription with the given\n * channels, feeds events through the consumer, and calls onDone when\n * the stream ends.\n *\n * When `endOnRootTerminal` is set, the projection unsubscribes its\n * own handle one macrotask after observing a root-namespace terminal\n * lifecycle event. This is needed by projections that may be opened\n * AFTER a run already terminated: the shared-stream pause logic\n * skips subscriptions whose `registeredAfterSeq` is past the\n * terminal so raw `subscribe()` callers can keep draining replayed\n * descendants — but a per-run dispatcher (e.g. the extensions\n * pipeline) needs the projection to settle so its `PromiseLike`\n * surface resolves. The macrotask deferral mirrors the deferred\n * pause in `#handleIncoming`, giving trailing same-tick custom\n * events (transformer `finalize()` flushes) a chance to drain.\n */\n async #startProjection(\n channels: Channel[],\n onEvent: (event: Event) => void,\n onDone: () => void,\n options: { endOnRootTerminal?: boolean } = {}\n ): Promise<void> {\n let endTimer: ReturnType<typeof setTimeout> | undefined;\n let rawHandle: SubscriptionHandle<Event> | undefined;\n try {\n rawHandle = await this.#subscribeRaw({ channels });\n const handle = rawHandle;\n for await (const event of handle) {\n onEvent(event);\n if (\n options.endOnRootTerminal &&\n endTimer == null &&\n isRootTerminalLifecycle(event)\n ) {\n endTimer = setTimeout(() => {\n endTimer = undefined;\n void handle.unsubscribe().catch(() => undefined);\n }, 0);\n }\n }\n } catch {\n // Projection streams are best-effort views over the shared thread\n // stream. Surface-level errors are reflected through the controller\n // state; this background task only needs to settle cleanly.\n } finally {\n if (endTimer != null) clearTimeout(endTimer);\n onDone();\n }\n }\n\n // ---------- v2 entry points ----------\n\n /**\n * Start a run without the v1 eager lazy-getter shims.\n *\n * `run.start` (the v1 entry point) eagerly opens a wildcard `values`\n * projection so `thread.output` / `thread.values` resolve regardless\n * of access order, and calls `#ensureLifecycleTracking` which opens\n * another wildcard `[\"lifecycle\", \"input\"]` subscription. Both\n * subscriptions widen `#computeUnionFilter` to wildcard, defeating\n * the progressive-expansion rotation strategy.\n *\n * `submitRun` skips those shims — callers that manage their own\n * content subscriptions (such as `StreamController`) get the narrow\n * union filter they asked for. Lifecycle / interrupt tracking is\n * instead served by the dedicated `#startLifecycleWatcher`, which\n * opens a wildcard `[\"lifecycle\", \"input\"]` stream alongside the\n * narrow content pump on both SSE and WebSocket transports.\n */\n async submitRun(params: {\n input?: unknown;\n config?: unknown;\n metadata?: Record<string, unknown>;\n /**\n * Fork the new run from an explicit checkpoint instead of the\n * thread's latest. Forwarded verbatim on the `/run.start` protocol\n * message; the API layer picks it up and routes it to\n * `graph.streamEvents(input, { version: \"v3\", forkFrom })`\n * (see plan-roadmap.md R2.4 / A0.1).\n */\n forkFrom?: { checkpointId: string };\n /**\n * Controls how concurrent submissions on the same thread are\n * handled by the server (`reject` | `rollback` | `interrupt` |\n * `enqueue`). Forwarded to the server; the SDK does not interpret\n * it locally (see plan-roadmap.md S1.3 / A0.3).\n */\n multitaskStrategy?: \"reject\" | \"rollback\" | \"interrupt\" | \"enqueue\";\n }): Promise<RunResult> {\n this.#prepareForNextRun();\n this.#startLifecycleWatcher();\n return await this.#send(\"run.start\", {\n ...(params as Record<string, unknown>),\n assistant_id: this.assistantId,\n });\n }\n\n /**\n * Respond to an interrupt without the v1 eager lazy-getter shims.\n * See {@link submitRun} for why this exists alongside\n * {@link input.respond}.\n */\n async respondInput(params: {\n namespace: readonly string[];\n interrupt_id: string;\n response: unknown;\n }): Promise<void> {\n this.#prepareForNextRun();\n this.#startLifecycleWatcher();\n await this.#send(\n \"input.respond\",\n params as unknown as CommandParamsMap[\"input.respond\"]\n );\n }\n\n /**\n * Register a listener for every globally-unique event on the thread.\n *\n * Fires exactly once per `event_id` across both the content pump\n * (user `subscribe()` calls) and the lifecycle watcher. Events\n * without an `event_id` always fire through (dedup is best-effort).\n *\n * Returns an unsubscribe function. Primary consumer is\n * `StreamController`, which uses the listener to feed discovery\n * runners and pick up deeply-nested interrupts that the narrow\n * content pump wouldn't deliver.\n */\n onEvent(listener: (event: Event) => void): () => void {\n this.#onEventListeners.add(listener);\n return () => {\n this.#onEventListeners.delete(listener);\n };\n }\n\n /**\n * Lazily open the wildcard discovery watcher stream.\n *\n * Idempotent. Used by both transports, but through different\n * mechanisms:\n *\n * - **SSE**: opens a dedicated event stream via\n * {@link TransportAdapter.openEventStream}. The stream runs\n * outside `#computeUnionFilter`, so the shared SSE stream's\n * content pump can stay narrow (e.g. `depth: 1`) while we still\n * capture every lifecycle/input event at any depth.\n * - **WebSocket**: opens a wildcard watcher subscription\n * subscription via the normal command path. The WS server\n * delivers matching events on the shared command connection and\n * `#handleIncoming` dispatches them through `#fireOnEvent` and\n * the thread-level effects — same downstream semantics as the\n * SSE watcher, just reusing the transport that's already open.\n *\n * Why this matters: consumers of {@link onEvent} (notably\n * `StreamController`'s subgraph/subagent discovery runners and\n * nested interrupt capture) depend on observing namespaced\n * lifecycle events at any depth. Without this watcher, WS clients\n * would only ever receive events matching the content pump's\n * narrow filter (depth 1 from the root), breaking inference rules\n * that require deeper descendants (e.g. the \"has-descendants\"\n * signal used to promote a subgraph host).\n */\n #startLifecycleWatcher(): void {\n if (this.#lifecycleWatcherStartPromise != null) return;\n\n if (this.#transportAdapter.openEventStream != null) {\n this.#lifecycleWatcherStartPromise = this.#startLifecycleWatcherSse();\n return;\n }\n\n this.#lifecycleWatcherStartPromise = this.#startLifecycleWatcherWebSocket();\n }\n\n async #startLifecycleWatcherSse(): Promise<void> {\n const filter: SubscribeParams = {\n channels: [\"lifecycle\", \"input\"],\n };\n let handle: EventStreamHandle;\n try {\n handle = this.#transportAdapter.openEventStream!(filter);\n } catch {\n return;\n }\n try {\n await handle.ready;\n } catch {\n try {\n handle.close();\n } catch {\n // best-effort\n }\n return;\n }\n if (this.#closed) {\n try {\n handle.close();\n } catch {\n // best-effort\n }\n return;\n }\n this.#lifecycleWatcherHandle = handle;\n try {\n for await (const message of handle.events) {\n if (this.#closed) break;\n this.#handleLifecycleWatcherMessage(message);\n }\n } catch {\n // Best-effort; the content pump handles surface-level errors.\n }\n }\n\n async #startLifecycleWatcherWebSocket(): Promise<void> {\n // `#subscribeRaw` on WS registers the subscription with the\n // server and buffers incoming events on a `SubscriptionHandle`.\n // All the side effects we care about (global dedup,\n // `#fireOnEvent` fan-out to `onEvent` listeners, interrupt\n // capture) already run in `#handleIncoming` regardless of which\n // subscription matched, so we don't need to process events on\n // the handle itself — we just drain it so its buffer doesn't\n // accumulate.\n let handle: SubscriptionHandle<Event>;\n try {\n handle = await this.#subscribeRaw({\n channels: [\"lifecycle\", \"input\"],\n });\n } catch {\n return;\n }\n if (this.#closed) {\n try {\n handle.close();\n } catch {\n // best-effort\n }\n return;\n }\n try {\n for await (const _event of handle) {\n if (this.#closed) break;\n }\n } catch {\n // Best-effort; surface-level errors are reported by the\n // content pump.\n }\n }\n\n /**\n * Process an event from the dedicated lifecycle watcher stream.\n *\n * Unlike `#handleIncoming`, this does NOT fan out to user\n * subscriptions — user subs with namespace wildcards already widen\n * `#computeUnionFilter` and therefore receive the event on the\n * content pump. Delivering via both streams would only add per-sub\n * dedup churn without expanding what the user can observe.\n *\n * We still run global-dedup thread-level side effects (interrupt\n * capture, `onEvent` fan-out) so deeply-nested interrupts outside\n * the content pump's narrow scope are recorded.\n */\n #handleLifecycleWatcherMessage(message: Message): void {\n if (message.type !== \"event\") return;\n if (typeof message.seq === \"number\") {\n this.ordering.lastSeenSeq = maxSeq(\n this.ordering.lastSeenSeq,\n message.seq\n );\n }\n if (message.event_id) {\n this.ordering.lastEventId = message.event_id;\n }\n const eventId = message.event_id ?? undefined;\n const globallyProcessed =\n eventId != null && this.#seenEventIds.has(eventId);\n if (eventId != null) this.#seenEventIds.add(eventId);\n if (globallyProcessed) return;\n this.#applyThreadLevelEffects(message);\n this.#fireOnEvent(message);\n }\n\n #applyThreadLevelEffects(event: Event): void {\n if (event.method === \"lifecycle\") {\n const lifecycle = event as LifecycleEvent;\n if (lifecycle.params.data.event === \"interrupted\") {\n this.interrupted = true;\n }\n }\n if (event.method === \"input.requested\") {\n const data = event.params.data;\n const interruptId =\n data.interrupt_id ?? `interrupt_${this.interrupts.length}`;\n this.interrupts.push({\n interruptId,\n payload: data.payload,\n namespace: [...event.params.namespace],\n });\n if (isHeadlessToolInterrupt(data.payload)) {\n this.#headlessInterruptsAwaitingTerminal.add(interruptId);\n }\n }\n }\n\n #fireOnEvent(event: Event): void {\n if (this.#onEventListeners.size === 0) return;\n for (const listener of this.#onEventListeners) {\n try {\n listener(event);\n } catch {\n // Best-effort — a bad listener should not wedge event delivery.\n }\n }\n }\n\n async close(): Promise<void> {\n if (this.#closed) {\n return;\n }\n this.#closed = true;\n if (this.#terminalPauseTimer != null) {\n clearTimeout(this.#terminalPauseTimer);\n this.#terminalPauseTimer = undefined;\n }\n this.#terminalPauseSeq = undefined;\n // Reject any `subscribe()` promises still waiting for a covering\n // rotation, and tear down the shared SSE stream. A rotation in\n // flight will observe `#closed` after its `await ready` and bail.\n for (const pending of this.#pendingSubResolves) {\n pending.reject(new Error(\"ThreadStream closed\"));\n }\n this.#pendingSubResolves.length = 0;\n if (this.#sharedStream != null) {\n try {\n this.#sharedStream.close();\n } catch {\n // best-effort\n }\n this.#sharedStream = null;\n this.#sharedStreamFilter = null;\n }\n if (this.#lifecycleWatcherHandle != null) {\n try {\n this.#lifecycleWatcherHandle.close();\n } catch {\n // best-effort\n }\n this.#lifecycleWatcherHandle = null;\n }\n const lifecycleWatcherStartPromise = this.#lifecycleWatcherStartPromise;\n this.#lifecycleWatcherStartPromise = undefined;\n this.#onEventListeners.clear();\n for (const subscription of this.#subscriptions.values()) {\n subscription.close();\n }\n this.#subscriptions.clear();\n try {\n await lifecycleWatcherStartPromise;\n } catch {\n // best-effort\n }\n // Safety net: revoke any object URLs minted by media handles so\n // long-lived consumers don't leak after thread teardown.\n for (const handle of this.#mediaHandles) {\n try {\n handle.revoke();\n } catch {\n // best-effort\n }\n }\n this.#mediaHandles.clear();\n this.#mediaAssembler?.close();\n this.#audioBuffer.close();\n this.#imagesBuffer.close();\n this.#videoBuffer.close();\n this.#filesBuffer.close();\n await this.#transportAdapter.close();\n }\n\n /**\n * Subscribe to raw wire channels and receive protocol events.\n *\n * For assembled projections, use the lazy getters instead:\n * `thread.messages`, `thread.values`, `thread.toolCalls`,\n * `thread.subgraphs`, `thread.subagents`, `thread.output`.\n */\n async subscribe<TChannel extends Channel>(\n channel: TChannel,\n options?: SubscribeOptions\n ): Promise<\n SubscriptionHandle<EventForChannel<TChannel>, YieldForChannel<TChannel>>\n >;\n async subscribe<const TChannels extends readonly Channel[]>(\n channels: TChannels,\n options?: SubscribeOptions\n ): Promise<\n SubscriptionHandle<EventForChannels<TChannels>, YieldForChannels<TChannels>>\n >;\n async subscribe(params: SubscribeParams): Promise<SubscriptionHandle<Event>>;\n async subscribe(\n paramsOrChannels: SubscribeParams | Channel | readonly Channel[],\n options: SubscribeOptions = {}\n ): Promise<unknown> {\n // The string / string-array overloads are typed to unwrap\n // `custom:<name>` payloads for ergonomic single-extension\n // subscriptions (`thread.subscribe(\"custom:a2a\")` yields the\n // raw payload). The `SubscribeParams` object overload, however,\n // is typed as `SubscriptionHandle<Event>` — it must deliver the\n // full event envelope so callers like `channelProjection` (which\n // backs `useChannel`) can see the `method`, `namespace`, and\n // `data.name` fields needed for filtering and rendering.\n const isParamsObject =\n typeof paramsOrChannels === \"object\" &&\n !Array.isArray(paramsOrChannels) &&\n \"channels\" in paramsOrChannels;\n const params = normalizeSubscribeParams(\n paramsOrChannels as SubscribeParams | Channel | readonly Channel[],\n options\n );\n return await this.#subscribeRaw(params, {\n unwrapNamedCustom: !isParamsObject,\n });\n }\n\n async #subscribeRaw(\n params: SubscribeParams,\n options: { unwrapNamedCustom?: boolean } = {}\n ): Promise<SubscriptionHandle<Event>> {\n await this.#ensureOpen();\n const { unwrapNamedCustom = true } = options;\n const hasOnlyNamedCustom =\n params.channels.length > 0 &&\n params.channels.every((ch) => ch.startsWith(\"custom:\"));\n const transform =\n unwrapNamedCustom && hasOnlyNamedCustom\n ? (event: Event) =>\n (\n (event.params as Record<string, unknown>).data as {\n payload?: unknown;\n }\n )?.payload ?? event\n : undefined;\n\n if (this.#transportAdapter.openEventStream != null) {\n return this.#subscribeViaSharedStream(params, transform);\n }\n\n return this.#subscribeViaCommand(params, transform);\n }\n\n /**\n * Subscribe via the single shared SSE connection.\n *\n * The subscription is registered immediately in `#subscriptions` so\n * fan-out can reach it the moment events begin flowing. The returned\n * promise resolves after a stream rotation completes whose union\n * filter covers this subscription's channels — mirroring the per-sub\n * `await streamHandle.ready` semantics callers depended on.\n *\n * Every subscribe schedules a stream rotation, even when the current\n * stream's filter already covers `params`. Rotating opens a fresh\n * server-side session that replays the run's full history from\n * `seq=0`; without it a late-joining sub would only see events that\n * arrive after it registered, because the shared pump's dedup drops\n * events the existing sub already consumed. Per-sub dedup\n * (`seenEventIds`) protects existing subs from receiving the\n * replay as duplicates. Rapid subscribes in the same microtask are\n * coalesced by `#scheduleReconcile` into a single rotation.\n */\n async #subscribeViaSharedStream(\n params: SubscribeParams,\n transform?: (event: Event) => unknown\n ): Promise<SubscriptionHandle<Event>> {\n const subscriptionId = `sse-${this.#nextCommandId++}`;\n const handle = new SubscriptionHandle<Event, unknown>(\n subscriptionId,\n params,\n async (id) => {\n this.#subscriptions.delete(id);\n this.#scheduleReconcile();\n },\n transform\n );\n const subscription = Object.assign(handle, {\n filter: params,\n registeredAfterSeq: this.ordering.lastSeenSeq,\n seenEventIds: new Set<string>(),\n });\n this.#subscriptions.set(subscriptionId, subscription);\n\n const covered = new Promise<void>((resolve, reject) => {\n this.#pendingSubResolves.push({ filter: params, resolve, reject });\n });\n this.#scheduleReconcile();\n\n try {\n await covered;\n } catch (err) {\n this.#subscriptions.delete(subscriptionId);\n throw err;\n }\n return handle as SubscriptionHandle<Event>;\n }\n\n /**\n * Progressive-expansion union of every currently-registered\n * subscription's filter. The server receives the narrowest filter\n * that still covers every active sub so deeply-namespaced or\n * selectively-opened projections don't pull down the entire thread's\n * event firehose.\n *\n * Unioning rules (matching the server's matching semantics in\n * `matchesSinkFilter`):\n * - Channels: set union.\n * - Namespaces: if any subscription requests a wildcard\n * (`namespaces === undefined`) the union is wildcard; otherwise\n * the union is the deduplicated list of every explicit prefix.\n * - Depth: if any subscription is unbounded (`depth === undefined`)\n * the union is unbounded; otherwise the union is the maximum\n * depth across all subscriptions (matching the per-sub \"max\n * reach below the prefix\" semantics).\n *\n * Returns `null` when there are no subscriptions.\n */\n #computeUnionFilter(): SubscribeParams | null {\n if (this.#subscriptions.size === 0) return null;\n\n const channels = new Set<Channel>();\n let wildcardNamespaces = false;\n const namespaceMap = new Map<string, Namespace>();\n let unboundedDepth = false;\n let maxDepth = 0;\n\n for (const sub of this.#subscriptions.values()) {\n for (const ch of sub.filter.channels) channels.add(ch);\n\n if (sub.filter.namespaces == null) {\n wildcardNamespaces = true;\n } else if (!wildcardNamespaces) {\n for (const ns of sub.filter.namespaces) {\n namespaceMap.set(namespaceKey(ns), ns);\n }\n }\n\n if (sub.filter.depth == null) {\n unboundedDepth = true;\n } else if (!unboundedDepth && sub.filter.depth > maxDepth) {\n maxDepth = sub.filter.depth;\n }\n }\n\n const result: SubscribeParams = {\n channels: [...channels] as Channel[],\n };\n if (!wildcardNamespaces) {\n result.namespaces = [...namespaceMap.values()];\n }\n if (!unboundedDepth) {\n result.depth = maxDepth;\n }\n return result;\n }\n\n /**\n * Schedule a stream reconciliation for the next microtask.\n *\n * Coalesces multiple subscribe/unsubscribe calls in the same tick\n * into a single rotation, and serializes across ticks (no two\n * rotations ever run concurrently).\n */\n #scheduleReconcile(): void {\n if (this.#closed) return;\n if (this.#rotationState !== \"idle\") return;\n this.#rotationState = \"scheduled\";\n queueMicrotask(() => {\n if (this.#closed) {\n this.#rotationState = \"idle\";\n return;\n }\n this.#rotationState = \"idle\";\n void this.#reconcileStream().catch(() => {\n this.#rotationState = \"idle\";\n });\n });\n }\n\n /**\n * Reconcile the shared SSE stream to match the desired union filter.\n *\n * Rotation strategy: open the new stream first, await its `ready`,\n * then close the old one. Overlap is absorbed by `#seenEventIds`\n * dedup in `#handleIncoming`.\n *\n * Error handling:\n * - Failure before `ready` resolves: reject all pending `subscribe`\n * promises whose filter isn't covered by the existing stream,\n * and keep the existing stream running for other subscriptions.\n * - Failure mid-pump on the active stream: close the thread via\n * {@link #failThreadWithError} so higher layers can rebind.\n */\n async #reconcileStream(): Promise<void> {\n if (this.#closed) return;\n if (this.#rotationState === \"rotating\") return;\n\n const desired = this.#computeUnionFilter();\n if (desired == null) return;\n\n // Bail only when nothing structurally changed AND nobody is\n // waiting on a fresh replay. A pending sub always needs a\n // rotation even when the filter is unchanged, because the server\n // replays buffered events only at the moment the SSE connection\n // is opened.\n if (\n this.#sharedStreamFilter != null &&\n filterEqual(desired, this.#sharedStreamFilter) &&\n this.#pendingSubResolves.length === 0\n ) {\n this.#resolvePending();\n return;\n }\n\n this.#rotationState = \"rotating\";\n let newHandle: EventStreamHandle;\n try {\n newHandle = this.#transportAdapter.openEventStream!(desired);\n } catch (err) {\n this.#rotationState = \"idle\";\n this.#rejectUncoveredPending(err);\n return;\n }\n\n try {\n await newHandle.ready;\n } catch (err) {\n this.#rotationState = \"idle\";\n try {\n newHandle.close();\n } catch {\n // best-effort\n }\n this.#rejectUncoveredPending(err);\n return;\n }\n\n if (this.#closed) {\n try {\n newHandle.close();\n } catch {\n // best-effort\n }\n this.#rotationState = \"idle\";\n return;\n }\n\n void this.#pumpStream(newHandle);\n\n const oldHandle = this.#sharedStream;\n this.#sharedStream = newHandle;\n this.#sharedStreamFilter = desired;\n if (oldHandle != null) {\n try {\n oldHandle.close();\n } catch {\n // best-effort\n }\n }\n\n this.#rotationState = \"idle\";\n this.#resolvePending();\n\n const next = this.#computeUnionFilter();\n if (next != null && !filterEqual(next, this.#sharedStreamFilter)) {\n this.#scheduleReconcile();\n }\n }\n\n /**\n * Pump events from a shared-stream handle into `#handleIncoming`.\n * One pump task runs per open stream; during rotation overlap two\n * pumps may be active briefly, with `#seenEventIds` deduping.\n */\n async #pumpStream(handle: EventStreamHandle): Promise<void> {\n try {\n for await (const message of handle.events) {\n if (this.#closed) {\n break;\n }\n this.#handleIncoming(message);\n }\n } catch (err) {\n if (handle === this.#sharedStream && !this.#closed) {\n this.#failThreadWithError(err);\n }\n // Errors on an old (being-rotated-out) stream are ignored —\n // the new stream is already pumping and holds authoritative state.\n }\n }\n\n /**\n * Resolve any pending `subscribe()` promises whose filter is now\n * covered by the active shared stream. Called after every successful\n * rotation (and after no-op reconciliations).\n */\n #resolvePending(): void {\n if (this.#sharedStreamFilter == null) return;\n const current = this.#sharedStreamFilter;\n if (this.#pendingSubResolves.length === 0) return;\n const stillPending: PendingSubResolve[] = [];\n for (const pending of this.#pendingSubResolves) {\n if (filterCovers(current, pending.filter)) {\n pending.resolve();\n } else {\n stillPending.push(pending);\n }\n }\n this.#pendingSubResolves.length = 0;\n this.#pendingSubResolves.push(...stillPending);\n }\n\n /**\n * Reject pending `subscribe()` promises whose filter isn't covered\n * by the existing stream (they're the ones that triggered the\n * failed rotation). Covered pending subs are resolved normally —\n * they didn't need the new stream.\n */\n #rejectUncoveredPending(err: unknown): void {\n if (this.#pendingSubResolves.length === 0) return;\n const current = this.#sharedStreamFilter;\n const stillPending: PendingSubResolve[] = [];\n for (const pending of this.#pendingSubResolves) {\n if (current != null && filterCovers(current, pending.filter)) {\n pending.resolve();\n } else {\n stillPending.push(pending);\n }\n }\n this.#pendingSubResolves.length = 0;\n for (const pending of stillPending) pending.reject(err);\n }\n\n /**\n * Terminate the thread due to an unrecoverable shared-stream error.\n * Rejects pending commands, closes subscriptions, and marks the\n * thread closed so no further rotations occur.\n */\n #failThreadWithError(err: unknown): void {\n const normalized =\n // oxlint-disable-next-line no-instanceof/no-instanceof\n err instanceof Error ? err : new Error(String(err));\n for (const pending of this.#pending.values()) {\n pending.reject(normalized);\n }\n this.#pending.clear();\n for (const pending of this.#pendingSubResolves) {\n pending.reject(normalized);\n }\n this.#pendingSubResolves.length = 0;\n for (const subscription of this.#subscriptions.values()) {\n subscription.close();\n }\n }\n\n /**\n * Command-based subscription (WebSocket fallback). The server replays\n * matching buffered events on subscribe via the same WebSocket stream.\n */\n async #subscribeViaCommand(\n params: SubscribeParams,\n transform?: (event: Event) => unknown\n ): Promise<SubscriptionHandle<Event>> {\n const result = await this.#send(\"subscription.subscribe\", params);\n const handle = new SubscriptionHandle<Event, unknown>(\n result.subscription_id,\n params,\n async (id) => {\n this.#subscriptions.delete(id);\n if (!this.#closed) {\n await this.#send(\"subscription.unsubscribe\", {\n subscription_id: id,\n }).catch((err: unknown) => {\n if (\n // oxlint-disable-next-line no-instanceof/no-instanceof\n err instanceof ProtocolError &&\n err.code === \"no_such_subscription\"\n ) {\n return;\n }\n throw err;\n });\n }\n },\n transform\n );\n const subscription = Object.assign(handle, {\n filter: params,\n registeredAfterSeq: this.ordering.lastSeenSeq,\n seenEventIds: new Set<string>(),\n });\n this.#subscriptions.set(result.subscription_id, subscription);\n return handle as SubscriptionHandle<Event>;\n }\n\n async #consumeEvents(): Promise<void> {\n try {\n for await (const message of this.#transportAdapter.events()) {\n this.#handleIncoming(message);\n }\n for (const subscription of this.#subscriptions.values()) {\n subscription.close();\n }\n } catch (error) {\n const normalized =\n // oxlint-disable-next-line no-instanceof/no-instanceof\n error instanceof Error ? error : new Error(String(error));\n for (const pending of this.#pending.values()) {\n pending.reject(normalized);\n }\n for (const subscription of this.#subscriptions.values()) {\n subscription.close();\n }\n this.#pending.clear();\n }\n }\n\n /**\n * Pause non-lifecycle subscriptions after a root terminal lifecycle.\n *\n * The pause is deferred one macrotask so same-run trailing events\n * emitted immediately after terminal (for example final `values`)\n * can still drain. `terminalSeq` lets replay attachers skip terminals\n * that happened before they registered, so late subscribers can keep\n * consuming the replayed history they joined for.\n */\n #scheduleTerminalPause(terminalSeq: number | undefined): void {\n if (this.#terminalPauseTimer != null) {\n clearTimeout(this.#terminalPauseTimer);\n }\n this.#terminalPauseSeq = terminalSeq ?? null;\n this.#terminalPauseTimer = setTimeout(() => {\n this.#terminalPauseTimer = undefined;\n if (this.#closed) return;\n for (const [id, subscription] of this.#subscriptions) {\n if (id === this.#lifecycleSubId) continue;\n if (\n terminalSeq != null &&\n subscription.registeredAfterSeq != null &&\n subscription.registeredAfterSeq >= terminalSeq\n ) {\n continue;\n }\n subscription.pause();\n }\n }, 0);\n }\n\n #handleIncoming(message: Message): void {\n if (message.type === \"event\") {\n if (typeof message.seq === \"number\") {\n this.ordering.lastSeenSeq = maxSeq(\n this.ordering.lastSeenSeq,\n message.seq\n );\n }\n if (message.event_id) {\n this.ordering.lastEventId = message.event_id;\n }\n\n // Two flavors of dedup live here:\n // 1. Thread-level side effects (interrupt state, interrupt\n // capture) — must run AT MOST ONCE per unique event_id\n // regardless of how many times the event is redelivered\n // (rotation overlap, WebSocket fan-out). Gated by the\n // global `#seenEventIds`.\n // 2. Per-subscription fan-out — gated by each sub's own\n // `seenEventIds`. This is what lets a rotation-triggered\n // replay (the server opens a fresh session that replays\n // from seq=0) reach newly-registered subs while NOT\n // redelivering events to subs that have already consumed\n // them. Event IDs are stable across sessions for the same\n // run, so per-sub set membership is the correct predicate.\n const eventId = message.event_id ?? undefined;\n const globallyProcessed =\n eventId != null && this.#seenEventIds.has(eventId);\n if (eventId != null) {\n this.#seenEventIds.add(eventId);\n }\n\n const TERMINAL_LIFECYCLE_EVENTS = new Set([\n \"interrupted\",\n \"completed\",\n \"failed\",\n ]);\n\n if (!globallyProcessed) {\n this.#applyThreadLevelEffects(message);\n this.#fireOnEvent(message);\n }\n\n // Unified fan-out: both SSE (shared stream) and WebSocket paths\n // deliver every event through a single connection; the client\n // dispatches to matching subscriptions based on each sub's\n // advertised filter, with per-sub dedup.\n let fannedToAny = false;\n for (const subscription of this.#subscriptions.values()) {\n if (!matchesSubscription(message, subscription.filter)) continue;\n if (eventId != null) {\n if (subscription.seenEventIds.has(eventId)) {\n continue;\n }\n subscription.seenEventIds.add(eventId);\n }\n subscription.push(message);\n fannedToAny = true;\n }\n\n // A root terminal schedules subscription pause on a macrotask,\n // but reconnect/replay can still deliver same-run trailing state\n // afterward (for example the final `values` snapshot). Drain that\n // event, briefly resume any paused consumers, then re-arm the\n // terminal pause so idle subscriptions still settle.\n if (\n fannedToAny &&\n this.#terminalPauseSeq !== undefined &&\n !(\n message.method === \"lifecycle\" &&\n message.params.namespace.length === 0\n )\n ) {\n const eventSeq =\n typeof message.seq === \"number\" ? message.seq : undefined;\n const terminalSeq = this.#terminalPauseSeq;\n if (\n terminalSeq === null ||\n eventSeq == null ||\n eventSeq > terminalSeq\n ) {\n if (this.#terminalPauseTimer != null) {\n clearTimeout(this.#terminalPauseTimer);\n this.#terminalPauseTimer = undefined;\n }\n for (const [id, subscription] of this.#subscriptions) {\n if (id !== this.#lifecycleSubId) {\n subscription.resume();\n }\n }\n this.#scheduleTerminalPause(\n terminalSeq === null ? undefined : terminalSeq\n );\n }\n }\n\n if (\n fannedToAny &&\n message.method === \"lifecycle\" &&\n message.params.namespace.length === 0 &&\n TERMINAL_LIFECYCLE_EVENTS.has(message.params.data.event)\n ) {\n const shouldSkipPause =\n message.params.data.event === \"interrupted\" &&\n this.#headlessInterruptsAwaitingTerminal.size > 0;\n if (shouldSkipPause) {\n this.#headlessInterruptsAwaitingTerminal.clear();\n return;\n }\n // A single shared stream delivers every subscription's events,\n // so a terminal event applies to all currently active\n // non-lifecycle subscriptions. Defer the pause one macrotask:\n // transformer `finalize()` hooks can emit trailing custom events\n // immediately after root lifecycle completion, and pausing\n // synchronously would buffer those same-run events until the\n // next submit resumes subscriptions.\n this.#scheduleTerminalPause(\n typeof message.seq === \"number\" ? message.seq : undefined\n );\n }\n return;\n }\n\n const messageId = typeof message.id === \"number\" ? message.id : undefined;\n const pending =\n messageId === undefined ? undefined : this.#pending.get(messageId);\n if (!pending) {\n return;\n }\n if (messageId !== undefined) {\n this.#pending.delete(messageId);\n }\n if (message.type === \"error\") {\n pending.reject(new ProtocolError(message));\n return;\n }\n if (typeof message.meta?.applied_through_seq === \"number\") {\n this.ordering.lastAppliedThroughSeq = message.meta.applied_through_seq;\n }\n pending.resolve(message);\n }\n\n async #send<TMethod extends keyof CommandResultMap>(\n method: TMethod,\n params: CommandParamsMap[TMethod]\n ): Promise<CommandResultMap[TMethod]> {\n await this.#ensureOpen();\n const id = this.#nextCommandId++;\n const command = {\n id,\n method,\n params,\n } as Command;\n const responsePromise = new Promise<CommandResponse>((resolve, reject) => {\n this.#pending.set(id, { resolve, reject });\n });\n const immediate = await this.#transportAdapter.send(command);\n if (immediate) {\n this.#pending.delete(id);\n if (immediate.type === \"error\") {\n throw new ProtocolError(immediate);\n }\n if (typeof immediate.meta?.applied_through_seq === \"number\") {\n this.ordering.lastAppliedThroughSeq =\n immediate.meta.applied_through_seq;\n }\n return immediate.result as CommandResultMap[TMethod];\n }\n const response = await responsePromise;\n return response.result as CommandResultMap[TMethod];\n }\n}\n\nexport {\n MessageAssembler,\n StreamingMessageAssembler,\n StreamingMessage,\n} from \"./messages.js\";\nexport type { AssembledMessage, MessageAssemblyUpdate } from \"./messages.js\";\nexport {\n ToolCallAssembler,\n SubgraphDiscoveryHandle,\n SubgraphHandle,\n SubagentHandle,\n SubagentDiscoveryHandle,\n} from \"./handles/index.js\";\nexport type {\n AssembledToolCall,\n ToolCallStatus,\n Subscribable,\n} from \"./handles/index.js\";\nexport { inferChannel, matchesSubscription } from \"./subscription.js\";\nexport type { TransportAdapter, AgentServerAdapter } from \"./transport.js\";\nexport type * from \"./types.js\";\nexport { ProtocolError } from \"./error.js\";\nexport { MediaAssembler, MediaAssemblyError } from \"./media.js\";\nexport type {\n AnyMediaHandle,\n AudioMedia,\n FileMedia,\n ImageMedia,\n MediaAssemblerCallbacks,\n MediaAssemblerOptions,\n MediaAssemblyErrorKind,\n MediaBase,\n MediaBlockType,\n VideoMedia,\n} from \"./media.js\";\n"],"mappings":";;;;;;;;;;;;;AAyHA,MAAM,qBAAqB,IAAI,IAAI;CACjC;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACD,CAAC;;;;;;;;;;;AAYF,SAAS,oBAAoB,OAAyB;AACpD,KAAI,SAAS,QAAQ,OAAO,UAAU,YAAY,MAAM,QAAQ,MAAM,CACpE,QAAO;CAET,MAAM,QAAQ;CACd,MAAM,WAAW,MAAM;AACvB,KAAI,CAAC,MAAM,QAAQ,SAAS,IAAI,SAAS,WAAW,EAAG,QAAO;AAU9D,KAAI,CARkB,SAAS,MAAM,QAAQ;AAC3C,MAAI,OAAO,QAAQ,OAAO,QAAQ,SAAU,QAAO;AACnD,MAAI,OAAQ,IAAmC,YAAY,WACzD,QAAO;EAET,MAAM,OAAQ,IAA2B;AACzC,SAAO,OAAO,SAAS,YAAY,mBAAmB,IAAI,KAAK;GAC/D,CACkB,QAAO;AAE3B,QAAO;EACL,GAAG;EACH,UAAUA,iBAAAA,uBACR,SACD;EACF;;AAGH,SAAS,aAAa,IAAuB;AAC3C,QAAO,GAAG,KAAA,KAAyB;;AAGrC,SAAS,OACP,SACA,MACoB;AACpB,KAAI,QAAQ,KAAM,QAAO;AACzB,KAAI,WAAW,KAAM,QAAO;AAC5B,QAAO,KAAK,IAAI,SAAS,KAAK;;AAGhC,MAAM,iCAAiC,IAAI,IAAI;CAC7C;CACA;CACA;CACD,CAAC;;;;;;;AAQF,SAAS,wBAAwB,OAAuB;AACtD,KAAI,MAAM,WAAW,YAAa,QAAO;AACzC,KAAI,MAAM,OAAO,UAAU,WAAW,EAAG,QAAO;CAChD,MAAM,OAAO,MAAM,OAAO;AAC1B,QAAO,MAAM,SAAS,QAAQ,+BAA+B,IAAI,KAAK,MAAM;;AAG9E,SAAS,oBACP,GACA,GACS;AACT,KAAI,MAAM,EAAG,QAAO;AACpB,KAAI,MAAM,KAAA,KAAa,MAAM,KAAA,EAAW,QAAO;AAC/C,KAAI,EAAE,WAAW,EAAE,OAAQ,QAAO;CAClC,MAAM,wBAAQ,IAAI,KAAa;AAC/B,MAAK,MAAM,MAAM,EAAG,OAAM,IAAI,aAAa,GAAG,CAAC;AAC/C,MAAK,MAAM,MAAM,EACf,KAAI,CAAC,MAAM,IAAI,aAAa,GAAG,CAAC,CAAE,QAAO;AAE3C,QAAO;;;;;;;;AAST,SAAS,YACP,GACA,GACS;AACT,KAAI,MAAM,EAAG,QAAO;AACpB,KAAI,KAAK,QAAQ,KAAK,KAAM,QAAO;AACnC,KAAI,EAAE,SAAS,WAAW,EAAE,SAAS,OAAQ,QAAO;CACpD,MAAM,YAAY,IAAI,IAAI,EAAE,SAAsB;AAClD,MAAK,MAAM,MAAM,EAAE,SACjB,KAAI,CAAC,UAAU,IAAI,GAAG,CAAE,QAAO;AAEjC,KAAI,CAAC,oBAAoB,EAAE,YAAY,EAAE,WAAW,CAAE,QAAO;AAG7D,MAFe,EAAE,SAAS,WACX,EAAE,SAAS,MACH,QAAO;AAC9B,QAAO;;AAGT,SAAS,SAAS,QAAmB,WAA+B;AAClE,KAAI,OAAO,SAAS,UAAU,OAAQ,QAAO;AAC7C,MAAK,IAAI,IAAI,GAAG,IAAI,OAAO,QAAQ,KAAK,EACtC,KAAI,OAAO,OAAO,UAAU,GAAI,QAAO;AAEzC,QAAO;;;;;;;;;;;;;;;;;;;;;;AAuBT,SAAS,aACP,SACA,QACS;CACT,MAAM,kBAAkB,IAAI,IAAI,QAAQ,SAAsB;AAC9D,MAAK,MAAM,MAAM,OAAO,SACtB,KAAI,CAAC,gBAAgB,IAAI,GAAG,CAAE,QAAO;CAGvC,MAAM,eAAe,QAAQ;CAC7B,MAAM,cAAc,OAAO;AAE3B,KAAI,QAAQ,cAAc,MAAM;AAC9B,MAAI,gBAAgB,KAAM,QAAO;AACjC,MAAI,eAAe,KAAM,QAAO;AAChC,SAAO,eAAe;;AAGxB,KAAI,OAAO,cAAc,KAAM,QAAO;AAEtC,MAAK,MAAM,MAAM,OAAO,WAOtB,KAAI,CANY,QAAQ,WAAW,MAAM,OAAO;AAC9C,MAAI,CAAC,SAAS,IAAI,GAAG,CAAE,QAAO;AAC9B,MAAI,gBAAgB,KAAM,QAAO;AACjC,MAAI,eAAe,KAAM,QAAO;AAChC,SAAO,GAAG,SAAS,GAAG,SAAS,eAAe;GAC9C,CACY,QAAO;AAEvB,QAAO;;AAGT,SAAS,yBACP,kBACA,UAA4B,EAAE,EACb;AACjB,KACE,OAAO,qBAAqB,YAC5B,CAAC,MAAM,QAAQ,iBAAiB,IAChC,cAAc,iBAEd,QAAO;CAGT,MAAM,WAAW,MAAM,QAAQ,iBAAiB,GAC3C,CAAC,GAAG,iBAAiB,GACrB,CAAC,iBAAiB;AACvB,QAAO;EACL,GAAG;EACH;EACD;;;;;;;;;;;AAYH,IAAa,qBAAb,MAEA;CACE;CACA;CACA,QAAmC,EAAE;CACrC,UAA2E,EAAE;CAC7E,SAAiB;CACjB,SAAiB;CACjB;CACA;CACA;CAEA,YACE,gBACA,QACA,eACA,WACA;AACA,OAAK,iBAAiB;AACtB,OAAK,SAAS;AACd,OAAK,gBAAgB;AACrB,OAAK,YAAY,eAAe,UAAU;;CAG5C,KAAK,OAAqB;AACxB,MAAI,KAAK,OACP;EAEF,MAAM,QAAQ,KAAK,UAAU,MAAM;EACnC,MAAM,SAAS,KAAK,QAAQ,OAAO;AACnC,MAAI,QAAQ;AACV,UAAO;IAAE,MAAM;IAAO;IAAO,CAAC;AAC9B;;AAEF,OAAK,MAAM,KAAK,MAAM;;;;;;;;CASxB,QAAc;AACZ,MAAI,KAAK,OAAQ;AACjB,OAAK,SAAS;AACd,SAAO,KAAK,QAAQ,SAAS,EAC3B,MAAK,QAAQ,OAAO,GAAG;GAAE,MAAM;GAAM,OAAO,KAAA;GAAW,CAAC;;;;;;CAQ5D,SAAe;AACb,OAAK,SAAS;AACd,OAAK,iBAAiB;AACtB,OAAK,gBAAgB,KAAA;;;;;;CAOvB,gBAA+B;AAC7B,MAAI,CAAC,KAAK,OAAQ,QAAO,QAAQ,SAAS;AAC1C,SAAO,IAAI,SAAe,YAAY;AACpC,QAAK,gBAAgB;IACrB;;CAGJ,IAAI,WAAoB;AACtB,SAAO,KAAK;;CAGd,QAAc;AACZ,OAAK,SAAS;AACd,OAAK,SAAS;AACd,SAAO,KAAK,QAAQ,SAAS,EAC3B,MAAK,QAAQ,OAAO,GAAG;GAAE,MAAM;GAAM,OAAO,KAAA;GAAW,CAAC;AAO1D,OAAK,iBAAiB;AACtB,OAAK,gBAAgB,KAAA;;CAGvB,MAAM,cAA6B;AACjC,MAAI,KAAK,OACP;AAEF,OAAK,OAAO;AACZ,QAAM,KAAK,cAAc,KAAK,eAAe;;CAG/C,CAAC,OAAO,iBAAwC;AAC9C,SAAO;GACL,MAAM,YAAY;AAChB,QAAI,KAAK,MAAM,SAAS,EAEtB,QAAO;KAAE,MAAM;KAAO,OADR,KAAK,MAAM,OAAO;KACH;AAE/B,QAAI,KAAK,UAAU,KAAK,OACtB,QAAO;KAAE,MAAM;KAAM,OAAO,KAAA;KAAW;AAEzC,WAAO,MAAM,IAAI,SAAiC,YAAY;AAC5D,UAAK,QAAQ,KAAK,QAAQ;MAC1B;;GAEJ,QAAQ,YAAY;AAClB,SAAK,OAAO;AACZ,WAAO;KAAE,MAAM;KAAM,OAAO,KAAA;KAAW;;GAE1C;;;;;;;;;;;;;;;;;;;AAoBL,IAAa,eAAb,MAEE;CACA;CACA,WAA0C,EAAE;CAC5C;CACA;CACA;CACA;;;;;CAMA,cAAc;;;;;CAMd,aAA0C,EAAE;CAE5C;CAEA;CACA;CACA,2BAAoB,IAAI,KAA6B;CACrD,iCAA0B,IAAI,KAAwC;CAkBtE,gCAAyB,IAAI,KAAa;;;;;;;;CAQ1C,sDAA+C,IAAI,KAAa;CAChE,UAAU;CACV,UAAU;CACV;CASA,gBAA0C;CAC1C,sBAA8C;CAC9C,iBAAoD;;CAEpD,sBAAoD,EAAE;CACtD;CACA;CAEA,kBAAiC;CACjC;CAkBA,0BAAoD;CACpD;CAOA,oCAA6B,IAAI,KAA6B;CAE9D;CACA;CACA;CACA;CACA;CACA;CACA;CACA,mCAA4B,IAAI,KAAuC;;;;;;;;;;;;;;;;CAiBvE,+BAA+B;CAC/B,mBAAmB;CACnB,oBAAsC,EAAE;CACxC,4BAAoE,EAAE;CACtE,0BAAsD,EAAE;;;;;;;;CASxD,0BAA0B;CAC1B;;CAEA,gCAAyB,IAAI,KAAqB;CAClD,eAAwB,IAAIc,4BAAAA,mBAA+B;CAC3D,gBAAyB,IAAIA,4BAAAA,mBAA+B;CAC5D,eAAwB,IAAIA,4BAAAA,mBAA+B;CAC3D,eAAwB,IAAIA,4BAAAA,mBAA8B;CAC1D;CAEA,YACE,kBACA,SACA;AACA,MAAI,CAAC,SAAS,YACZ,OAAM,IAAI,MAAM,+CAA+C;AAEjE,QAAA,mBAAyB;AACzB,OAAK,WAAW,iBAAiB;AACjC,OAAK,cAAc,QAAQ;AAC3B,QAAA,gBAAsB,QAAQ,qBAAqB;AACnD,QAAA,cAAoB,QAAQ;AAC5B,OAAK,MAAM,EACT,OAAO,OAAO,WAAW;AACvB,SAAA,mBAAyB;AACzB,SAAA,yBAA+B;AAM1B,QAAK;AAOV,UAAO,MAAM,MAAA,KAAW,aAAa;IACnC,GAAG;IACH,cAAc,KAAK;IACpB,CAAC;KAEL;AACD,OAAK,QAAQ,EACX,SAAS,OAAO,SAAS,EAAE,KACxB,MAAM,MAAA,KAAW,iBAAiB,OAAO,EAG7C;AACD,OAAK,QAAQ;GACX,SAAS,OAAO,WAAW;AACzB,UAAA,mBAAyB;AACzB,UAAA,yBAA+B;AAG1B,SAAK;AACV,UAAM,MAAA,KACJ,iBACA,OACD;;GAEH,QAAQ,OAAO,WAAW;AACxB,UAAM,MAAA,KACJ,gBACA,OACD;;GAEJ;AACD,OAAK,QAAQ;GACX,KAAK,OAAO,WACV,MAAM,MAAA,KACJ,aACA,OACD;GACH,iBAAiB,OAAO,WACtB,MAAM,MAAA,KACJ,yBACA,OACD;GACH,MAAM,OAAO,WACX,MAAM,MAAA,KACJ,cACA,OACD;GACJ;AAGD,MAAI,MAAA,iBAAuB,mBAAmB,KACvC,OAAA,eAAqB;;;;;;;;CAU9B,OAAA,aAAmC;AACjC,MAAI,MAAA,OAAc;AAClB,MAAI,MAAA,eAAqB,KACvB,OAAA,cAAoB,MAAA,iBAAuB,MAAM,CAAC,WAAW;AAC3D,SAAA,SAAe;IACf;AAEJ,QAAM,MAAA;;;;;;CAOR,qBAAgC;AAC9B,SAAO,CAAC,aAAa,QAAQ;;;;;;;;;;;CAY/B,2BAAiC;AAC/B,MAAI,MAAA,yBAA+B,KAAM;AACzC,QAAA,yBAA+B,YAAY;AAIzC,SAAA,kBAHY,MAAM,MAAA,aAAmB,EACnC,UAAU,MAAA,mBAAyB,EACpC,CAAC,EACyB;MACzB,CAAC,YAAY,KAAA,EAAU;;;;;;;CAQ7B,qBAA2B;AACzB,OAAK,cAAc;AACnB,OAAK,WAAW,SAAS;AACzB,MAAI,MAAA,sBAA4B,MAAM;AACpC,gBAAa,MAAA,mBAAyB;AACtC,SAAA,qBAA2B,KAAA;;AAE7B,QAAA,mBAAyB,KAAA;AACzB,OAAK,MAAM,CAAC,IAAI,iBAAiB,MAAA,cAC/B,KAAI,OAAO,MAAA,eACT,cAAa,QAAQ;;;;;;;CAY3B,IAAI,WAAkD;AACpD,MAAI,MAAA,iBAAwB,QAAO,MAAA;EACnC,MAAM,SAAS,IAAIA,4BAAAA,mBAA2C;AAC9D,QAAA,mBAAyB;EACzB,MAAM,YAAY,IAAIoB,mBAAAA,2BAA2B;AAC5C,QAAA,gBACH,CAAC,YAAY,GAAG,MAAA,mBAAyB,CAAC,GACzC,UAAU;AACT,OAAI,MAAM,WAAW,WAAY;GACjC,MAAM,MAAM,UAAU,QAAQ,MAAuB;AACrD,OAAI,IAAK,QAAO,KAAKE,mBAAAA,yBAAyB,IAAI,CAAC;WAE/C,OAAO,OAAO,CACrB;AACD,SAAO;;;;;;;CAQT,IAAI,SAAwD;AAC1D,MAAI,MAAA,iBAAwB,QAAO,MAAA;EACnC,MAAM,SAAS,IAAItB,4BAAAA,mBAA4B;EAC/C,IAAI;EACJ,IAAI;EACJ,MAAM,gBAAgB,IAAI,SAAkB,YAAY;AACtD,mBAAgB;IAChB;AACF,QAAA,gBAAsB;EACtB,MAAM,aAAa,OAAO,OAAO,QAAQ,EACvC,OACE,aAGA,eAIA,cAAc,KAAK,aAAa,WAAW,EAC9C,CAAC;AACF,QAAA,mBAAyB;AACpB,QAAA,gBACH,CAAC,UAAU,GAAG,MAAA,mBAAyB,CAAC,GACvC,UAAU;AACT,OAAI,MAAM,WAAW,SAAU;GAC/B,MAAM,OAAO,oBAAqB,MAAsB,OAAO,KAAK;AACpE,eAAY;AACZ,UAAO,KAAK,KAAK;WAEb;AACJ,iBAAc,UAAU;AACxB,UAAO,OAAO;IAEjB;AACD,SAAO;;;;;;CAOT,IAAI,YAA8C;AAChD,MAAI,MAAA,kBAAyB,QAAO,MAAA;EACpC,MAAM,SAAS,IAAIA,4BAAAA,mBAAsC;AACzD,QAAA,oBAA0B;EAC1B,MAAM,YAAY,IAAI0B,cAAAA,mBAAmB;AACpC,QAAA,gBACH,CAAC,SAAS,GAAG,MAAA,mBAAyB,CAAC,GACtC,UAAU;AACT,OAAI,MAAM,WAAW,QAAS;GAC9B,MAAM,KAAK,UAAU,QAAQ,MAAoB;AACjD,OAAI,GAAI,QAAO,KAAK,GAAG;WAEnB,OAAO,OAAO,CACrB;AACD,SAAO;;;;;CAMT,IAAI,YAA2C;AAC7C,MAAI,MAAA,kBAAyB,QAAO,MAAA;EACpC,MAAM,SAAS,IAAI1B,4BAAAA,mBAAmC;AACtD,QAAA,oBAA0B;AAC1B,GAAM,YAAY;GAIhB,MAAM,YAAY,IAAI4B,kBAAAA,wBAHJ,MAAM,MAAA,aAAmB,EACzC,UAAU,CAAC,SAAS,GAAG,MAAA,mBAAyB,CAAC,EAClD,CAAC,EACuD,MAAM,EAAE,CAAC;AAClE,cAAW,MAAM,OAAO,UACtB,QAAO,KAAK,IAAI;AAElB,UAAO,OAAO;MACZ;AACJ,SAAO;;;;;CAMT,IAAI,YAA2C;AAC7C,MAAI,MAAA,kBAAyB,QAAO,MAAA;EACpC,MAAM,SAAS,IAAI5B,4BAAAA,mBAAmC;AACtD,QAAA,oBAA0B;AAC1B,GAAM,YAAY;GAIhB,MAAM,YAAY,IAAI8B,kBAAAA,wBAHJ,MAAM,MAAA,aAAmB,EACzC,UAAU,CAAC,SAAS,GAAG,MAAA,mBAAyB,CAAC,EAClD,CAAC,EACuD,KAAK;AAC9D,cAAW,MAAM,OAAO,UACtB,QAAO,KAAK,IAAI;AAElB,UAAO,OAAO;MACZ;AACJ,SAAO;;;;;;;;;;;CAYT,IAAI,QAAmC;AACrC,QAAA,uBAA6B;AAC7B,SAAO,MAAA;;;;;;CAOT,IAAI,SAAoC;AACtC,QAAA,uBAA6B;AAC7B,SAAO,MAAA;;;;;;CAOT,IAAI,QAAmC;AACrC,QAAA,uBAA6B;AAC7B,SAAO,MAAA;;;;;;CAOT,IAAI,QAAkC;AACpC,QAAA,uBAA6B;AAC7B,SAAO,MAAA;;;;;;;CAQT,IAAI,SAA2B;AAExB,OAAK;AACV,SAAO,MAAA;;;;;;;;;;;;;;;CAgBT,IAAI,aAA4C;AAC9C,MAAI,MAAA,gBAAuB,QAAO,MAAA;EAClC,MAAM,QAAQ,MAAA;EACd,MAAM,mBAAmB,SAAiB,MAAA,gBAAsB,KAAK;AACrE,QAAA,kBAAwB,IAAI,MAC1B,OAAO,OAAO,KAAK,EACnB;GACE,MAAM,SAAS,SAAS;AACtB,QAAI,OAAO,SAAS,SAAU,QAAO,KAAA;IACrC,MAAM,SAAS,MAAM,IAAI,KAAK;AAC9B,QAAI,OAAQ,QAAO;IACnB,MAAM,YAAY,gBAAgB,KAAK;AACvC,UAAM,IAAI,MAAM,UAAU;AAC1B,WAAO;;GAET,MAAM,SAAS,SAAS,OAAO,SAAS;GACzC,CACF;AACD,SAAO,MAAA;;;;;;;;;;;;;;;;;;;;CAqBT,8BAAoC;AAClC,MAAI,MAAA,4BAAmC;AACvC,QAAA,8BAAoC;AAC/B,QAAA,gBACH,CAAC,UAAU,GAAG,MAAA,mBAAyB,CAAC,GACvC,UAAU;AACT,OAAI,MAAM,WAAW,SAAU;AAC/B,SAAA,iBAAuB,KAAK,MAAM;AAClC,QAAK,MAAM,YAAY,MAAA,yBACrB,UAAS,MAAM;WAGb;AACJ,SAAA,kBAAwB;GACxB,MAAM,YAAY,MAAA,uBAA6B,OAAO,EAAE;AACxD,QAAK,MAAM,YAAY,UAAW,WAAU;KAW9C,EAAE,mBAAmB,MAAM,CAC5B;;;;;;;;;;;;CAaH,yBAA+B;AAC7B,MAAI,MAAA,uBAA8B;AAClC,QAAA,yBAA+B;EAC/B,MAAM,YAAY,IAAIO,cAAAA,eAAe;GACnC,OAAO,MAAA;GACP,UAAU,MAAM;AACd,UAAA,aAAmB,IAAI,EAAE;AACzB,UAAA,YAAkB,KAAK,EAAE;;GAE3B,UAAU,MAAM;AACd,UAAA,aAAmB,IAAI,EAAE;AACzB,UAAA,aAAmB,KAAK,EAAE;;GAE5B,UAAU,MAAM;AACd,UAAA,aAAmB,IAAI,EAAE;AACzB,UAAA,YAAkB,KAAK,EAAE;;GAE3B,SAAS,MAAM;AACb,UAAA,aAAmB,IAAI,EAAE;AACzB,UAAA,YAAkB,KAAK,EAAE;;GAE5B,CAAC;AACF,QAAA,iBAAuB;AAClB,QAAA,gBACH,CAAC,YAAY,GAAG,MAAA,mBAAyB,CAAC,GACzC,UAAU;AACT,OAAI,MAAM,WAAW,WAAY;AACjC,aAAU,QAAQ,MAAuB;WAErC;AACJ,aAAU,OAAO;AACjB,SAAA,YAAkB,OAAO;AACzB,SAAA,aAAmB,OAAO;AAC1B,SAAA,YAAkB,OAAO;AACzB,SAAA,YAAkB,OAAO;IAE5B;;;;;;;;;;;;;CAcH,iBAAiB,MAAwC;AACvD,QAAA,4BAAkC;EAElC,MAAM,SAAS,IAAIrC,4BAAAA,mBAA4B;EAC/C,IAAI;EACJ,IAAI;EACJ,MAAM,eAAe,IAAI,SAAkB,YAAY;AACrD,kBAAe;IACf;EAEF,MAAM,eAAe,UAAiB;GACpC,MAAM,OAAO,MAAM,OAAO;AAM1B,OAAI,MAAM,SAAS,KAAM;AACzB,eAAY,KAAK;AACjB,UAAO,KAAK,KAAK,QAAQ;;AAK3B,OAAK,MAAM,SAAS,MAAA,iBAAwB,aAAY,MAAM;AAG9D,QAAA,yBAA+B,KAAK,YAAY;EAEhD,MAAM,eAAe;AACnB,gBAAa,UAAU;AACvB,UAAO,OAAO;;AAEhB,MAAI,MAAA,gBACF,SAAQ;MAER,OAAA,uBAA6B,KAAK,OAAO;AAG3C,SAAO,OAAO,OAAO,QAAQ,EAC3B,OACE,aAGA,eAIA,aAAa,KAAK,aAAa,WAAW,EAC7C,CAAC;;;;;;;;;;;;;;;;;;;CAoBJ,OAAA,gBACE,UACA,SACA,QACA,UAA2C,EAAE,EAC9B;EACf,IAAI;EACJ,IAAI;AACJ,MAAI;AACF,eAAY,MAAM,MAAA,aAAmB,EAAE,UAAU,CAAC;GAClD,MAAM,SAAS;AACf,cAAW,MAAM,SAAS,QAAQ;AAChC,YAAQ,MAAM;AACd,QACE,QAAQ,qBACR,YAAY,QACZ,wBAAwB,MAAM,CAE9B,YAAW,iBAAiB;AAC1B,gBAAW,KAAA;AACN,YAAO,aAAa,CAAC,YAAY,KAAA,EAAU;OAC/C,EAAE;;UAGH,WAIE;AACR,OAAI,YAAY,KAAM,cAAa,SAAS;AAC5C,WAAQ;;;;;;;;;;;;;;;;;;;;CAuBZ,MAAM,UAAU,QAmBO;AACrB,QAAA,mBAAyB;AACzB,QAAA,uBAA6B;AAC7B,SAAO,MAAM,MAAA,KAAW,aAAa;GACnC,GAAI;GACJ,cAAc,KAAK;GACpB,CAAC;;;;;;;CAQJ,MAAM,aAAa,QAID;AAChB,QAAA,mBAAyB;AACzB,QAAA,uBAA6B;AAC7B,QAAM,MAAA,KACJ,iBACA,OACD;;;;;;;;;;;;;;CAeH,QAAQ,UAA8C;AACpD,QAAA,iBAAuB,IAAI,SAAS;AACpC,eAAa;AACX,SAAA,iBAAuB,OAAO,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA+B3C,yBAA+B;AAC7B,MAAI,MAAA,gCAAsC,KAAM;AAEhD,MAAI,MAAA,iBAAuB,mBAAmB,MAAM;AAClD,SAAA,+BAAqC,MAAA,0BAAgC;AACrE;;AAGF,QAAA,+BAAqC,MAAA,gCAAsC;;CAG7E,OAAA,2BAAiD;EAC/C,MAAM,SAA0B,EAC9B,UAAU,CAAC,aAAa,QAAQ,EACjC;EACD,IAAI;AACJ,MAAI;AACF,YAAS,MAAA,iBAAuB,gBAAiB,OAAO;UAClD;AACN;;AAEF,MAAI;AACF,SAAM,OAAO;UACP;AACN,OAAI;AACF,WAAO,OAAO;WACR;AAGR;;AAEF,MAAI,MAAA,QAAc;AAChB,OAAI;AACF,WAAO,OAAO;WACR;AAGR;;AAEF,QAAA,yBAA+B;AAC/B,MAAI;AACF,cAAW,MAAM,WAAW,OAAO,QAAQ;AACzC,QAAI,MAAA,OAAc;AAClB,UAAA,8BAAoC,QAAQ;;UAExC;;CAKV,OAAA,iCAAuD;EASrD,IAAI;AACJ,MAAI;AACF,YAAS,MAAM,MAAA,aAAmB,EAChC,UAAU,CAAC,aAAa,QAAQ,EACjC,CAAC;UACI;AACN;;AAEF,MAAI,MAAA,QAAc;AAChB,OAAI;AACF,WAAO,OAAO;WACR;AAGR;;AAEF,MAAI;AACF,cAAW,MAAM,UAAU,OACzB,KAAI,MAAA,OAAc;UAEd;;;;;;;;;;;;;;;CAmBV,+BAA+B,SAAwB;AACrD,MAAI,QAAQ,SAAS,QAAS;AAC9B,MAAI,OAAO,QAAQ,QAAQ,SACzB,MAAK,SAAS,cAAc,OAC1B,KAAK,SAAS,aACd,QAAQ,IACT;AAEH,MAAI,QAAQ,SACV,MAAK,SAAS,cAAc,QAAQ;EAEtC,MAAM,UAAU,QAAQ,YAAY,KAAA;EACpC,MAAM,oBACJ,WAAW,QAAQ,MAAA,aAAmB,IAAI,QAAQ;AACpD,MAAI,WAAW,KAAM,OAAA,aAAmB,IAAI,QAAQ;AACpD,MAAI,kBAAmB;AACvB,QAAA,wBAA8B,QAAQ;AACtC,QAAA,YAAkB,QAAQ;;CAG5B,yBAAyB,OAAoB;AAC3C,MAAI,MAAM,WAAW;OACD,MACJ,OAAO,KAAK,UAAU,cAClC,MAAK,cAAc;;AAGvB,MAAI,MAAM,WAAW,mBAAmB;GACtC,MAAM,OAAO,MAAM,OAAO;GAC1B,MAAM,cACJ,KAAK,gBAAgB,aAAa,KAAK,WAAW;AACpD,QAAK,WAAW,KAAK;IACnB;IACA,SAAS,KAAK;IACd,WAAW,CAAC,GAAG,MAAM,OAAO,UAAU;IACvC,CAAC;AACF,OAAIiD,uBAAAA,wBAAwB,KAAK,QAAQ,CACvC,OAAA,mCAAyC,IAAI,YAAY;;;CAK/D,aAAa,OAAoB;AAC/B,MAAI,MAAA,iBAAuB,SAAS,EAAG;AACvC,OAAK,MAAM,YAAY,MAAA,iBACrB,KAAI;AACF,YAAS,MAAM;UACT;;CAMZ,MAAM,QAAuB;AAC3B,MAAI,MAAA,OACF;AAEF,QAAA,SAAe;AACf,MAAI,MAAA,sBAA4B,MAAM;AACpC,gBAAa,MAAA,mBAAyB;AACtC,SAAA,qBAA2B,KAAA;;AAE7B,QAAA,mBAAyB,KAAA;AAIzB,OAAK,MAAM,WAAW,MAAA,mBACpB,SAAQ,uBAAO,IAAI,MAAM,sBAAsB,CAAC;AAElD,QAAA,mBAAyB,SAAS;AAClC,MAAI,MAAA,gBAAsB,MAAM;AAC9B,OAAI;AACF,UAAA,aAAmB,OAAO;WACpB;AAGR,SAAA,eAAqB;AACrB,SAAA,qBAA2B;;AAE7B,MAAI,MAAA,0BAAgC,MAAM;AACxC,OAAI;AACF,UAAA,uBAA6B,OAAO;WAC9B;AAGR,SAAA,yBAA+B;;EAEjC,MAAM,+BAA+B,MAAA;AACrC,QAAA,+BAAqC,KAAA;AACrC,QAAA,iBAAuB,OAAO;AAC9B,OAAK,MAAM,gBAAgB,MAAA,cAAoB,QAAQ,CACrD,cAAa,OAAO;AAEtB,QAAA,cAAoB,OAAO;AAC3B,MAAI;AACF,SAAM;UACA;AAKR,OAAK,MAAM,UAAU,MAAA,aACnB,KAAI;AACF,UAAO,QAAQ;UACT;AAIV,QAAA,aAAmB,OAAO;AAC1B,QAAA,gBAAsB,OAAO;AAC7B,QAAA,YAAkB,OAAO;AACzB,QAAA,aAAmB,OAAO;AAC1B,QAAA,YAAkB,OAAO;AACzB,QAAA,YAAkB,OAAO;AACzB,QAAM,MAAA,iBAAuB,OAAO;;CAuBtC,MAAM,UACJ,kBACA,UAA4B,EAAE,EACZ;EASlB,MAAM,iBACJ,OAAO,qBAAqB,YAC5B,CAAC,MAAM,QAAQ,iBAAiB,IAChC,cAAc;EAChB,MAAM,SAAS,yBACb,kBACA,QACD;AACD,SAAO,MAAM,MAAA,aAAmB,QAAQ,EACtC,mBAAmB,CAAC,gBACrB,CAAC;;CAGJ,OAAA,aACE,QACA,UAA2C,EAAE,EACT;AACpC,QAAM,MAAA,YAAkB;EACxB,MAAM,EAAE,oBAAoB,SAAS;EACrC,MAAM,qBACJ,OAAO,SAAS,SAAS,KACzB,OAAO,SAAS,OAAO,OAAO,GAAG,WAAW,UAAU,CAAC;EACzD,MAAM,YACJ,qBAAqB,sBAChB,UAEI,MAAM,OAAmC,MAGzC,WAAW,QAChB,KAAA;AAEN,MAAI,MAAA,iBAAuB,mBAAmB,KAC5C,QAAO,MAAA,yBAA+B,QAAQ,UAAU;AAG1D,SAAO,MAAA,oBAA0B,QAAQ,UAAU;;;;;;;;;;;;;;;;;;;;;CAsBrD,OAAA,yBACE,QACA,WACoC;EACpC,MAAM,iBAAiB,OAAO,MAAA;EAC9B,MAAM,SAAS,IAAI,mBACjB,gBACA,QACA,OAAO,OAAO;AACZ,SAAA,cAAoB,OAAO,GAAG;AAC9B,SAAA,mBAAyB;KAE3B,UACD;EACD,MAAM,eAAe,OAAO,OAAO,QAAQ;GACzC,QAAQ;GACR,oBAAoB,KAAK,SAAS;GAClC,8BAAc,IAAI,KAAa;GAChC,CAAC;AACF,QAAA,cAAoB,IAAI,gBAAgB,aAAa;EAErD,MAAM,UAAU,IAAI,SAAe,SAAS,WAAW;AACrD,SAAA,mBAAyB,KAAK;IAAE,QAAQ;IAAQ;IAAS;IAAQ,CAAC;IAClE;AACF,QAAA,mBAAyB;AAEzB,MAAI;AACF,SAAM;WACC,KAAK;AACZ,SAAA,cAAoB,OAAO,eAAe;AAC1C,SAAM;;AAER,SAAO;;;;;;;;;;;;;;;;;;;;;;CAuBT,sBAA8C;AAC5C,MAAI,MAAA,cAAoB,SAAS,EAAG,QAAO;EAE3C,MAAM,2BAAW,IAAI,KAAc;EACnC,IAAI,qBAAqB;EACzB,MAAM,+BAAe,IAAI,KAAwB;EACjD,IAAI,iBAAiB;EACrB,IAAI,WAAW;AAEf,OAAK,MAAM,OAAO,MAAA,cAAoB,QAAQ,EAAE;AAC9C,QAAK,MAAM,MAAM,IAAI,OAAO,SAAU,UAAS,IAAI,GAAG;AAEtD,OAAI,IAAI,OAAO,cAAc,KAC3B,sBAAqB;YACZ,CAAC,mBACV,MAAK,MAAM,MAAM,IAAI,OAAO,WAC1B,cAAa,IAAI,aAAa,GAAG,EAAE,GAAG;AAI1C,OAAI,IAAI,OAAO,SAAS,KACtB,kBAAiB;YACR,CAAC,kBAAkB,IAAI,OAAO,QAAQ,SAC/C,YAAW,IAAI,OAAO;;EAI1B,MAAM,SAA0B,EAC9B,UAAU,CAAC,GAAG,SAAS,EACxB;AACD,MAAI,CAAC,mBACH,QAAO,aAAa,CAAC,GAAG,aAAa,QAAQ,CAAC;AAEhD,MAAI,CAAC,eACH,QAAO,QAAQ;AAEjB,SAAO;;;;;;;;;CAUT,qBAA2B;AACzB,MAAI,MAAA,OAAc;AAClB,MAAI,MAAA,kBAAwB,OAAQ;AACpC,QAAA,gBAAsB;AACtB,uBAAqB;AACnB,OAAI,MAAA,QAAc;AAChB,UAAA,gBAAsB;AACtB;;AAEF,SAAA,gBAAsB;AACjB,SAAA,iBAAuB,CAAC,YAAY;AACvC,UAAA,gBAAsB;KACtB;IACF;;;;;;;;;;;;;;;;CAiBJ,OAAA,kBAAwC;AACtC,MAAI,MAAA,OAAc;AAClB,MAAI,MAAA,kBAAwB,WAAY;EAExC,MAAM,UAAU,MAAA,oBAA0B;AAC1C,MAAI,WAAW,KAAM;AAOrB,MACE,MAAA,sBAA4B,QAC5B,YAAY,SAAS,MAAA,mBAAyB,IAC9C,MAAA,mBAAyB,WAAW,GACpC;AACA,SAAA,gBAAsB;AACtB;;AAGF,QAAA,gBAAsB;EACtB,IAAI;AACJ,MAAI;AACF,eAAY,MAAA,iBAAuB,gBAAiB,QAAQ;WACrD,KAAK;AACZ,SAAA,gBAAsB;AACtB,SAAA,uBAA6B,IAAI;AACjC;;AAGF,MAAI;AACF,SAAM,UAAU;WACT,KAAK;AACZ,SAAA,gBAAsB;AACtB,OAAI;AACF,cAAU,OAAO;WACX;AAGR,SAAA,uBAA6B,IAAI;AACjC;;AAGF,MAAI,MAAA,QAAc;AAChB,OAAI;AACF,cAAU,OAAO;WACX;AAGR,SAAA,gBAAsB;AACtB;;AAGG,QAAA,WAAiB,UAAU;EAEhC,MAAM,YAAY,MAAA;AAClB,QAAA,eAAqB;AACrB,QAAA,qBAA2B;AAC3B,MAAI,aAAa,KACf,KAAI;AACF,aAAU,OAAO;UACX;AAKV,QAAA,gBAAsB;AACtB,QAAA,gBAAsB;EAEtB,MAAM,OAAO,MAAA,oBAA0B;AACvC,MAAI,QAAQ,QAAQ,CAAC,YAAY,MAAM,MAAA,mBAAyB,CAC9D,OAAA,mBAAyB;;;;;;;CAS7B,OAAA,WAAkB,QAA0C;AAC1D,MAAI;AACF,cAAW,MAAM,WAAW,OAAO,QAAQ;AACzC,QAAI,MAAA,OACF;AAEF,UAAA,eAAqB,QAAQ;;WAExB,KAAK;AACZ,OAAI,WAAW,MAAA,gBAAsB,CAAC,MAAA,OACpC,OAAA,oBAA0B,IAAI;;;;;;;;CAYpC,kBAAwB;AACtB,MAAI,MAAA,sBAA4B,KAAM;EACtC,MAAM,UAAU,MAAA;AAChB,MAAI,MAAA,mBAAyB,WAAW,EAAG;EAC3C,MAAM,eAAoC,EAAE;AAC5C,OAAK,MAAM,WAAW,MAAA,mBACpB,KAAI,aAAa,SAAS,QAAQ,OAAO,CACvC,SAAQ,SAAS;MAEjB,cAAa,KAAK,QAAQ;AAG9B,QAAA,mBAAyB,SAAS;AAClC,QAAA,mBAAyB,KAAK,GAAG,aAAa;;;;;;;;CAShD,wBAAwB,KAAoB;AAC1C,MAAI,MAAA,mBAAyB,WAAW,EAAG;EAC3C,MAAM,UAAU,MAAA;EAChB,MAAM,eAAoC,EAAE;AAC5C,OAAK,MAAM,WAAW,MAAA,mBACpB,KAAI,WAAW,QAAQ,aAAa,SAAS,QAAQ,OAAO,CAC1D,SAAQ,SAAS;MAEjB,cAAa,KAAK,QAAQ;AAG9B,QAAA,mBAAyB,SAAS;AAClC,OAAK,MAAM,WAAW,aAAc,SAAQ,OAAO,IAAI;;;;;;;CAQzD,qBAAqB,KAAoB;EACvC,MAAM,aAEJ,eAAe,QAAQ,MAAM,IAAI,MAAM,OAAO,IAAI,CAAC;AACrD,OAAK,MAAM,WAAW,MAAA,QAAc,QAAQ,CAC1C,SAAQ,OAAO,WAAW;AAE5B,QAAA,QAAc,OAAO;AACrB,OAAK,MAAM,WAAW,MAAA,mBACpB,SAAQ,OAAO,WAAW;AAE5B,QAAA,mBAAyB,SAAS;AAClC,OAAK,MAAM,gBAAgB,MAAA,cAAoB,QAAQ,CACrD,cAAa,OAAO;;;;;;CAQxB,OAAA,oBACE,QACA,WACoC;EACpC,MAAM,SAAS,MAAM,MAAA,KAAW,0BAA0B,OAAO;EACjE,MAAM,SAAS,IAAI,mBACjB,OAAO,iBACP,QACA,OAAO,OAAO;AACZ,SAAA,cAAoB,OAAO,GAAG;AAC9B,OAAI,CAAC,MAAA,OACH,OAAM,MAAA,KAAW,4BAA4B,EAC3C,iBAAiB,IAClB,CAAC,CAAC,OAAO,QAAiB;AACzB,QAEE,eAAec,cAAAA,iBACf,IAAI,SAAS,uBAEb;AAEF,UAAM;KACN;KAGN,UACD;EACD,MAAM,eAAe,OAAO,OAAO,QAAQ;GACzC,QAAQ;GACR,oBAAoB,KAAK,SAAS;GAClC,8BAAc,IAAI,KAAa;GAChC,CAAC;AACF,QAAA,cAAoB,IAAI,OAAO,iBAAiB,aAAa;AAC7D,SAAO;;CAGT,OAAA,gBAAsC;AACpC,MAAI;AACF,cAAW,MAAM,WAAW,MAAA,iBAAuB,QAAQ,CACzD,OAAA,eAAqB,QAAQ;AAE/B,QAAK,MAAM,gBAAgB,MAAA,cAAoB,QAAQ,CACrD,cAAa,OAAO;WAEf,OAAO;GACd,MAAM,aAEJ,iBAAiB,QAAQ,QAAQ,IAAI,MAAM,OAAO,MAAM,CAAC;AAC3D,QAAK,MAAM,WAAW,MAAA,QAAc,QAAQ,CAC1C,SAAQ,OAAO,WAAW;AAE5B,QAAK,MAAM,gBAAgB,MAAA,cAAoB,QAAQ,CACrD,cAAa,OAAO;AAEtB,SAAA,QAAc,OAAO;;;;;;;;;;;;CAazB,uBAAuB,aAAuC;AAC5D,MAAI,MAAA,sBAA4B,KAC9B,cAAa,MAAA,mBAAyB;AAExC,QAAA,mBAAyB,eAAe;AACxC,QAAA,qBAA2B,iBAAiB;AAC1C,SAAA,qBAA2B,KAAA;AAC3B,OAAI,MAAA,OAAc;AAClB,QAAK,MAAM,CAAC,IAAI,iBAAiB,MAAA,eAAqB;AACpD,QAAI,OAAO,MAAA,eAAsB;AACjC,QACE,eAAe,QACf,aAAa,sBAAsB,QACnC,aAAa,sBAAsB,YAEnC;AAEF,iBAAa,OAAO;;KAErB,EAAE;;CAGP,gBAAgB,SAAwB;AACtC,MAAI,QAAQ,SAAS,SAAS;AAC5B,OAAI,OAAO,QAAQ,QAAQ,SACzB,MAAK,SAAS,cAAc,OAC1B,KAAK,SAAS,aACd,QAAQ,IACT;AAEH,OAAI,QAAQ,SACV,MAAK,SAAS,cAAc,QAAQ;GAgBtC,MAAM,UAAU,QAAQ,YAAY,KAAA;GACpC,MAAM,oBACJ,WAAW,QAAQ,MAAA,aAAmB,IAAI,QAAQ;AACpD,OAAI,WAAW,KACb,OAAA,aAAmB,IAAI,QAAQ;GAGjC,MAAM,4BAA4B,IAAI,IAAI;IACxC;IACA;IACA;IACD,CAAC;AAEF,OAAI,CAAC,mBAAmB;AACtB,UAAA,wBAA8B,QAAQ;AACtC,UAAA,YAAkB,QAAQ;;GAO5B,IAAI,cAAc;AAClB,QAAK,MAAM,gBAAgB,MAAA,cAAoB,QAAQ,EAAE;AACvD,QAAI,CAACC,qBAAAA,oBAAoB,SAAS,aAAa,OAAO,CAAE;AACxD,QAAI,WAAW,MAAM;AACnB,SAAI,aAAa,aAAa,IAAI,QAAQ,CACxC;AAEF,kBAAa,aAAa,IAAI,QAAQ;;AAExC,iBAAa,KAAK,QAAQ;AAC1B,kBAAc;;AAQhB,OACE,eACA,MAAA,qBAA2B,KAAA,KAC3B,EACE,QAAQ,WAAW,eACnB,QAAQ,OAAO,UAAU,WAAW,IAEtC;IACA,MAAM,WACJ,OAAO,QAAQ,QAAQ,WAAW,QAAQ,MAAM,KAAA;IAClD,MAAM,cAAc,MAAA;AACpB,QACE,gBAAgB,QAChB,YAAY,QACZ,WAAW,aACX;AACA,SAAI,MAAA,sBAA4B,MAAM;AACpC,mBAAa,MAAA,mBAAyB;AACtC,YAAA,qBAA2B,KAAA;;AAE7B,UAAK,MAAM,CAAC,IAAI,iBAAiB,MAAA,cAC/B,KAAI,OAAO,MAAA,eACT,cAAa,QAAQ;AAGzB,WAAA,sBACE,gBAAgB,OAAO,KAAA,IAAY,YACpC;;;AAIL,OACE,eACA,QAAQ,WAAW,eACnB,QAAQ,OAAO,UAAU,WAAW,KACpC,0BAA0B,IAAI,QAAQ,OAAO,KAAK,MAAM,EACxD;AAIA,QAFE,QAAQ,OAAO,KAAK,UAAU,iBAC9B,MAAA,mCAAyC,OAAO,GAC7B;AACnB,WAAA,mCAAyC,OAAO;AAChD;;AASF,UAAA,sBACE,OAAO,QAAQ,QAAQ,WAAW,QAAQ,MAAM,KAAA,EACjD;;AAEH;;EAGF,MAAM,YAAY,OAAO,QAAQ,OAAO,WAAW,QAAQ,KAAK,KAAA;EAChE,MAAM,UACJ,cAAc,KAAA,IAAY,KAAA,IAAY,MAAA,QAAc,IAAI,UAAU;AACpE,MAAI,CAAC,QACH;AAEF,MAAI,cAAc,KAAA,EAChB,OAAA,QAAc,OAAO,UAAU;AAEjC,MAAI,QAAQ,SAAS,SAAS;AAC5B,WAAQ,OAAO,IAAID,cAAAA,cAAc,QAAQ,CAAC;AAC1C;;AAEF,MAAI,OAAO,QAAQ,MAAM,wBAAwB,SAC/C,MAAK,SAAS,wBAAwB,QAAQ,KAAK;AAErD,UAAQ,QAAQ,QAAQ;;CAG1B,OAAA,KACE,QACA,QACoC;AACpC,QAAM,MAAA,YAAkB;EACxB,MAAM,KAAK,MAAA;EACX,MAAM,UAAU;GACd;GACA;GACA;GACD;EACD,MAAM,kBAAkB,IAAI,SAA0B,SAAS,WAAW;AACxE,SAAA,QAAc,IAAI,IAAI;IAAE;IAAS;IAAQ,CAAC;IAC1C;EACF,MAAM,YAAY,MAAM,MAAA,iBAAuB,KAAK,QAAQ;AAC5D,MAAI,WAAW;AACb,SAAA,QAAc,OAAO,GAAG;AACxB,OAAI,UAAU,SAAS,QACrB,OAAM,IAAIA,cAAAA,cAAc,UAAU;AAEpC,OAAI,OAAO,UAAU,MAAM,wBAAwB,SACjD,MAAK,SAAS,wBACZ,UAAU,KAAK;AAEnB,UAAO,UAAU;;AAGnB,UADiB,MAAM,iBACP"}
|
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
import { AssembledToolCall, ToolCallStatus } from "./handles/tools.cjs";
|
|
2
|
+
import { AssembledMessage, MessageAssembler, MessageAssemblyUpdate, StreamingMessage, StreamingMessageHandle } from "./messages.cjs";
|
|
3
|
+
import { AnyMediaHandle, AudioMedia, FileMedia, ImageMedia, MediaAssembler, MediaAssemblerCallbacks, MediaAssemblerOptions, MediaAssemblyError, MediaAssemblyErrorKind, MediaBase, MediaBlockType, VideoMedia } from "./media.cjs";
|
|
4
|
+
import { AgentServerAdapter, TransportAdapter } from "./transport.cjs";
|
|
5
|
+
import { EventForChannel, EventForChannels, EventMethodByChannel, EventSubscription, ExtendedRunStartParams, InputModule, InterruptPayload, MessageSubscription, SessionOrderingState, StateModule, SubscribeOptions, ThreadExtension, ThreadExtensions, ThreadModules, ThreadStreamOptions, ThreadStreamTransport, ThreadStreamTransportKind, UnwrapExtension, YieldForChannel, YieldForChannels } from "./types.cjs";
|
|
6
|
+
import { SubagentHandle } from "./handles/subagents.cjs";
|
|
7
|
+
import { SubgraphHandle, Subscribable } from "./handles/subgraphs.cjs";
|
|
8
|
+
import { inferChannel, matchesSubscription } from "./subscription.cjs";
|
|
9
|
+
import { ProtocolError } from "./error.cjs";
|
|
10
|
+
import { Channel, Event, RunResult, SubscribeParams } from "@langchain/protocol";
|
|
11
|
+
|
|
12
|
+
//#region src/client/stream/index.d.ts
|
|
13
|
+
/**
|
|
14
|
+
* Async iterable handle for raw event subscriptions.
|
|
15
|
+
*
|
|
16
|
+
* An optional `transform` maps each incoming event before it is queued
|
|
17
|
+
* or delivered to a waiting consumer. This is used by named custom
|
|
18
|
+
* channel subscriptions (e.g. `"custom:a2a"`) to unwrap the payload
|
|
19
|
+
* so callers receive the raw emitted data instead of the protocol
|
|
20
|
+
* event envelope.
|
|
21
|
+
*/
|
|
22
|
+
declare class SubscriptionHandle<TEvent extends Event = Event, TYield = TEvent> implements AsyncIterable<TYield>, EventSubscription<TYield> {
|
|
23
|
+
readonly subscriptionId: string;
|
|
24
|
+
readonly params: SubscribeParams;
|
|
25
|
+
private readonly queue;
|
|
26
|
+
private readonly waiters;
|
|
27
|
+
private closed;
|
|
28
|
+
private paused;
|
|
29
|
+
private resumeResolve?;
|
|
30
|
+
private readonly onUnsubscribe;
|
|
31
|
+
private readonly transform;
|
|
32
|
+
constructor(subscriptionId: string, params: SubscribeParams, onUnsubscribe: (id: string) => Promise<void>, transform?: (event: TEvent) => TYield);
|
|
33
|
+
push(event: TEvent): void;
|
|
34
|
+
/**
|
|
35
|
+
* Pause the subscription: resolve all waiting iterators with `done: true`
|
|
36
|
+
* so `for await` loops exit, but keep the subscription alive. New events
|
|
37
|
+
* arriving while paused are still buffered. Call `resume()` to allow
|
|
38
|
+
* iterators to consume again.
|
|
39
|
+
*/
|
|
40
|
+
pause(): void;
|
|
41
|
+
/**
|
|
42
|
+
* Resume a paused subscription so new `for await` loops can consume
|
|
43
|
+
* buffered and future events.
|
|
44
|
+
*/
|
|
45
|
+
resume(): void;
|
|
46
|
+
/**
|
|
47
|
+
* Returns a promise that resolves when `resume()` is called. Resolves
|
|
48
|
+
* immediately if not currently paused.
|
|
49
|
+
*/
|
|
50
|
+
waitForResume(): Promise<void>;
|
|
51
|
+
get isPaused(): boolean;
|
|
52
|
+
close(): void;
|
|
53
|
+
unsubscribe(): Promise<void>;
|
|
54
|
+
[Symbol.asyncIterator](): AsyncIterator<TYield>;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* High-level wrapper around a protocol connection to a specific thread.
|
|
58
|
+
*
|
|
59
|
+
* In the thread-centric protocol, threads are durable (backed by
|
|
60
|
+
* checkpoints) and connections are ephemeral. A `ThreadStream` is the
|
|
61
|
+
* client-side handle for interacting with a thread: starting runs,
|
|
62
|
+
* subscribing to events, consuming assembled projections (`messages`,
|
|
63
|
+
* `values`, `toolCalls`, etc.), and responding to interrupts.
|
|
64
|
+
*
|
|
65
|
+
* Construct via `client.threads.stream(threadId?, { assistantId? })`.
|
|
66
|
+
*
|
|
67
|
+
* @typeParam TExtensions - Optional map of `{ name: payload }` pairs
|
|
68
|
+
* describing the transformer projections the bound assistant exposes
|
|
69
|
+
* on `custom:<name>` channels. Narrows `thread.extensions.<name>` to
|
|
70
|
+
* `ThreadExtension<payload>`. Defaults to `Record<string, unknown>`.
|
|
71
|
+
*/
|
|
72
|
+
declare class ThreadStream<TExtensions extends Record<string, unknown> = Record<string, unknown>> {
|
|
73
|
+
#private;
|
|
74
|
+
readonly threadId: string;
|
|
75
|
+
readonly ordering: SessionOrderingState;
|
|
76
|
+
readonly run: ThreadModules["run"];
|
|
77
|
+
readonly agent: ThreadModules["agent"];
|
|
78
|
+
readonly input: ThreadModules["input"];
|
|
79
|
+
readonly state: ThreadModules["state"];
|
|
80
|
+
/**
|
|
81
|
+
* Whether the run was interrupted (a lifecycle "interrupted" event
|
|
82
|
+
* was received). Mirrors the in-process `run.interrupted`.
|
|
83
|
+
*/
|
|
84
|
+
interrupted: boolean;
|
|
85
|
+
/**
|
|
86
|
+
* Interrupt payloads collected during the run, if any.
|
|
87
|
+
* Mirrors the in-process `run.interrupts`.
|
|
88
|
+
*/
|
|
89
|
+
readonly interrupts: InterruptPayload[];
|
|
90
|
+
readonly assistantId: string;
|
|
91
|
+
constructor(transportAdapter: TransportAdapter, options: ThreadStreamOptions);
|
|
92
|
+
/**
|
|
93
|
+
* Streaming messages. Each `for await` loop gets an independent cursor
|
|
94
|
+
* over the shared buffer; late consumers see all previously emitted
|
|
95
|
+
* messages. Mirrors the in-process `run.messages`.
|
|
96
|
+
*/
|
|
97
|
+
get messages(): AsyncIterable<StreamingMessageHandle>;
|
|
98
|
+
/**
|
|
99
|
+
* State values. Iterable for intermediate snapshots; also
|
|
100
|
+
* `PromiseLike` — `await thread.values` resolves with the final
|
|
101
|
+
* state. Mirrors the in-process `run.values`.
|
|
102
|
+
*/
|
|
103
|
+
get values(): AsyncIterable<unknown> & PromiseLike<unknown>;
|
|
104
|
+
/**
|
|
105
|
+
* Tool calls with promise-based output/status/error.
|
|
106
|
+
* Mirrors the in-process `run.toolCalls`.
|
|
107
|
+
*/
|
|
108
|
+
get toolCalls(): AsyncIterable<AssembledToolCall>;
|
|
109
|
+
/**
|
|
110
|
+
* Discovered subgraphs. Mirrors the in-process `run.subgraphs`.
|
|
111
|
+
*/
|
|
112
|
+
get subgraphs(): AsyncIterable<SubgraphHandle>;
|
|
113
|
+
/**
|
|
114
|
+
* Discovered subagents.
|
|
115
|
+
*/
|
|
116
|
+
get subagents(): AsyncIterable<SubagentHandle>;
|
|
117
|
+
/**
|
|
118
|
+
* Audio media handles, one per message containing at least one
|
|
119
|
+
* `AudioBlock`. Each `for await` opens an independent cursor over
|
|
120
|
+
* the shared buffer; late consumers replay every previously emitted
|
|
121
|
+
* audio handle.
|
|
122
|
+
*
|
|
123
|
+
* Yields one item per message on the first matching
|
|
124
|
+
* `content-block-start` — messages with no audio blocks are skipped.
|
|
125
|
+
*/
|
|
126
|
+
get audio(): AsyncIterable<AudioMedia>;
|
|
127
|
+
/**
|
|
128
|
+
* Image media handles, one per message containing at least one
|
|
129
|
+
* `ImageBlock`. See {@link audio} for shared semantics.
|
|
130
|
+
*/
|
|
131
|
+
get images(): AsyncIterable<ImageMedia>;
|
|
132
|
+
/**
|
|
133
|
+
* Video media handles, one per message containing at least one
|
|
134
|
+
* `VideoBlock`. See {@link audio} for shared semantics.
|
|
135
|
+
*/
|
|
136
|
+
get video(): AsyncIterable<VideoMedia>;
|
|
137
|
+
/**
|
|
138
|
+
* File media handles, one per message containing at least one
|
|
139
|
+
* `FileBlock`. See {@link audio} for shared semantics.
|
|
140
|
+
*/
|
|
141
|
+
get files(): AsyncIterable<FileMedia>;
|
|
142
|
+
/**
|
|
143
|
+
* Promise that resolves with the final state value when the run
|
|
144
|
+
* completes. Shares the `values` getter's SSE connection.
|
|
145
|
+
* Mirrors the in-process `run.output`.
|
|
146
|
+
*/
|
|
147
|
+
get output(): Promise<unknown>;
|
|
148
|
+
/**
|
|
149
|
+
* Proxy over compile-time {@link StreamTransformer} projections
|
|
150
|
+
* exposed by the bound assistant on `custom:<name>` channels.
|
|
151
|
+
*
|
|
152
|
+
* Each access (e.g. `thread.extensions.toolActivity`) lazily opens a
|
|
153
|
+
* dedicated `custom:<name>` subscription, returns a cached
|
|
154
|
+
* {@link ThreadExtension} handle that is both `AsyncIterable<T>`
|
|
155
|
+
* (streaming items as they arrive) and `PromiseLike<T>` (resolves
|
|
156
|
+
* with the final value when the run terminates), and reuses the same
|
|
157
|
+
* handle on subsequent access.
|
|
158
|
+
*
|
|
159
|
+
* Mirrors the in-process `run.extensions.<name>` shape.
|
|
160
|
+
*/
|
|
161
|
+
get extensions(): ThreadExtensions<TExtensions>;
|
|
162
|
+
/**
|
|
163
|
+
* Start a run without the v1 eager lazy-getter shims.
|
|
164
|
+
*
|
|
165
|
+
* `run.start` (the v1 entry point) eagerly opens a wildcard `values`
|
|
166
|
+
* projection so `thread.output` / `thread.values` resolve regardless
|
|
167
|
+
* of access order, and calls `#ensureLifecycleTracking` which opens
|
|
168
|
+
* another wildcard `["lifecycle", "input"]` subscription. Both
|
|
169
|
+
* subscriptions widen `#computeUnionFilter` to wildcard, defeating
|
|
170
|
+
* the progressive-expansion rotation strategy.
|
|
171
|
+
*
|
|
172
|
+
* `submitRun` skips those shims — callers that manage their own
|
|
173
|
+
* content subscriptions (such as `StreamController`) get the narrow
|
|
174
|
+
* union filter they asked for. Lifecycle / interrupt tracking is
|
|
175
|
+
* instead served by the dedicated `#startLifecycleWatcher`, which
|
|
176
|
+
* opens a wildcard `["lifecycle", "input"]` stream alongside the
|
|
177
|
+
* narrow content pump on both SSE and WebSocket transports.
|
|
178
|
+
*/
|
|
179
|
+
submitRun(params: {
|
|
180
|
+
input?: unknown;
|
|
181
|
+
config?: unknown;
|
|
182
|
+
metadata?: Record<string, unknown>;
|
|
183
|
+
/**
|
|
184
|
+
* Fork the new run from an explicit checkpoint instead of the
|
|
185
|
+
* thread's latest. Forwarded verbatim on the `/run.start` protocol
|
|
186
|
+
* message; the API layer picks it up and routes it to
|
|
187
|
+
* `graph.streamEvents(input, { version: "v3", forkFrom })`
|
|
188
|
+
* (see plan-roadmap.md R2.4 / A0.1).
|
|
189
|
+
*/
|
|
190
|
+
forkFrom?: {
|
|
191
|
+
checkpointId: string;
|
|
192
|
+
};
|
|
193
|
+
/**
|
|
194
|
+
* Controls how concurrent submissions on the same thread are
|
|
195
|
+
* handled by the server (`reject` | `rollback` | `interrupt` |
|
|
196
|
+
* `enqueue`). Forwarded to the server; the SDK does not interpret
|
|
197
|
+
* it locally (see plan-roadmap.md S1.3 / A0.3).
|
|
198
|
+
*/
|
|
199
|
+
multitaskStrategy?: "reject" | "rollback" | "interrupt" | "enqueue";
|
|
200
|
+
}): Promise<RunResult>;
|
|
201
|
+
/**
|
|
202
|
+
* Respond to an interrupt without the v1 eager lazy-getter shims.
|
|
203
|
+
* See {@link submitRun} for why this exists alongside
|
|
204
|
+
* {@link input.respond}.
|
|
205
|
+
*/
|
|
206
|
+
respondInput(params: {
|
|
207
|
+
namespace: readonly string[];
|
|
208
|
+
interrupt_id: string;
|
|
209
|
+
response: unknown;
|
|
210
|
+
}): Promise<void>;
|
|
211
|
+
/**
|
|
212
|
+
* Register a listener for every globally-unique event on the thread.
|
|
213
|
+
*
|
|
214
|
+
* Fires exactly once per `event_id` across both the content pump
|
|
215
|
+
* (user `subscribe()` calls) and the lifecycle watcher. Events
|
|
216
|
+
* without an `event_id` always fire through (dedup is best-effort).
|
|
217
|
+
*
|
|
218
|
+
* Returns an unsubscribe function. Primary consumer is
|
|
219
|
+
* `StreamController`, which uses the listener to feed discovery
|
|
220
|
+
* runners and pick up deeply-nested interrupts that the narrow
|
|
221
|
+
* content pump wouldn't deliver.
|
|
222
|
+
*/
|
|
223
|
+
onEvent(listener: (event: Event) => void): () => void;
|
|
224
|
+
close(): Promise<void>;
|
|
225
|
+
/**
|
|
226
|
+
* Subscribe to raw wire channels and receive protocol events.
|
|
227
|
+
*
|
|
228
|
+
* For assembled projections, use the lazy getters instead:
|
|
229
|
+
* `thread.messages`, `thread.values`, `thread.toolCalls`,
|
|
230
|
+
* `thread.subgraphs`, `thread.subagents`, `thread.output`.
|
|
231
|
+
*/
|
|
232
|
+
subscribe<TChannel extends Channel>(channel: TChannel, options?: SubscribeOptions): Promise<SubscriptionHandle<EventForChannel<TChannel>, YieldForChannel<TChannel>>>;
|
|
233
|
+
subscribe<const TChannels extends readonly Channel[]>(channels: TChannels, options?: SubscribeOptions): Promise<SubscriptionHandle<EventForChannels<TChannels>, YieldForChannels<TChannels>>>;
|
|
234
|
+
subscribe(params: SubscribeParams): Promise<SubscriptionHandle<Event>>;
|
|
235
|
+
}
|
|
236
|
+
//#endregion
|
|
237
|
+
export { SubscriptionHandle, ThreadStream };
|
|
238
|
+
//# sourceMappingURL=index.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.cts","names":[],"sources":["../../../src/client/stream/index.ts"],"mappings":";;;;;;;;;;;;;;;;;AAyUA;;;;cAAa,kBAAA,gBAAkC,KAAA,GAAQ,KAAA,WAAgB,MAAA,aAC1D,aAAA,CAAc,MAAA,GAAS,iBAAA,CAAkB,MAAA;EAAA,SAE3C,cAAA;EAAA,SACA,MAAA,EAAQ,eAAA;EAAA,iBACA,KAAA;EAAA,iBACA,OAAA;EAAA,QACT,MAAA;EAAA,QACA,MAAA;EAAA,QACA,aAAA;EAAA,iBACS,aAAA;EAAA,iBACA,SAAA;EAEjB,WAAA,CACE,cAAA,UACA,MAAA,EAAQ,eAAA,EACR,aAAA,GAAgB,EAAA,aAAe,OAAA,QAC/B,SAAA,IAAa,KAAA,EAAO,MAAA,KAAW,MAAA;EAQjC,IAAA,CAAK,KAAA,EAAO,MAAA;EA2E4B;;;;;;EAxDxC,KAAA,CAAA;EA5C8B;;;;EAwD9B,MAAA,CAAA;EAvDW;;;;EAiEX,aAAA,CAAA,GAAiB,OAAA;EAAA,IAOb,QAAA,CAAA;EAIJ,KAAA,CAAA;EAeM,WAAA,CAAA,GAAe,OAAA;EAAA,CAQpB,MAAA,CAAO,aAAA,KAAkB,aAAA,CAAc,MAAA;AAAA;;;;;;;;;;;;;;;;;cAsC7B,YAAA,qBACS,MAAA,oBAA0B,MAAA;EAAA;WAErC,QAAA;EAAA,SACA,QAAA,EAAU,oBAAA;EAAA,SACV,GAAA,EAAK,aAAA;EAAA,SACL,KAAA,EAAO,aAAA;EAAA,SACP,KAAA,EAAO,aAAA;EAAA,SACP,KAAA,EAAO,aAAA;EAtDV;;;;EA4DN,WAAA;EApDwC;;;AAsC1C;EAtC0C,SA0D/B,UAAA,EAAY,gBAAA;EAAA,SAEZ,WAAA;EA+HT,WAAA,CACE,gBAAA,EAAkB,gBAAA,EAClB,OAAA,EAAS,mBAAA;EAtJmC;;;;;EAAA,IA6S1C,QAAA,CAAA,GAAY,aAAA,CAAc,sBAAA;EA1RT;;;;;EAAA,IAgTjB,MAAA,CAAA,GAAU,aAAA,YAAyB,WAAA;EAAA;;;;EAAA,IAyCnC,SAAA,CAAA,GAAa,aAAA,CAAc,iBAAA;EAwCA;;;EAAA,IApB3B,SAAA,CAAA,GAAa,aAAA,CAAc,cAAA;EAuDH;;;EAAA,IAnCxB,SAAA,CAAA,GAAa,aAAA,CAAc,cAAA;EAqDJ;;;;;;;;;EAAA,IA3BvB,KAAA,CAAA,GAAS,aAAA,CAAc,UAAA;EAsiBZ;;;;EAAA,IA7hBX,MAAA,CAAA,GAAU,aAAA,CAAc,UAAA;EAwmBP;;;;EAAA,IA/lBjB,KAAA,CAAA,GAAS,aAAA,CAAc,UAAA;EAimBsB;;;;EAAA,IAxlB7C,KAAA,CAAA,GAAS,aAAA,CAAc,SAAA;EA4lBwC;;;;;EAAA,IAllB/D,MAAA,CAAA,GAAU,OAAA;EAolBoC;;;;;;;;;;;;;EAAA,IAjkB9C,UAAA,CAAA,GAAc,gBAAA,CAAiB,WAAA;EAjenB;;;;;;;;;;;;;;;;;EA4tBV,SAAA,CAAU,MAAA;IACd,KAAA;IACA,MAAA;IACA,QAAA,GAAW,MAAA;IAxXI;;;;;;;IAgYf,QAAA;MAAa,YAAA;IAAA;IA9TY;;;;;;IAqUzB,iBAAA;EAAA,IACE,OAAA,CAAQ,SAAA;EA3SC;;;;;EAyTP,YAAA,CAAa,MAAA;IACjB,SAAA;IACA,YAAA;IACA,QAAA;EAAA,IACE,OAAA;EAlCF;;;;;;;;;;;;EAuDF,OAAA,CAAQ,QAAA,GAAW,KAAA,EAAO,KAAA;EAyLpB,KAAA,CAAA,GAAS,OAAA;EAzLf;;;;;;;EAgQM,SAAA,kBAA2B,OAAA,CAAA,CAC/B,OAAA,EAAS,QAAA,EACT,OAAA,GAAU,gBAAA,GACT,OAAA,CACD,kBAAA,CAAmB,eAAA,CAAgB,QAAA,GAAW,eAAA,CAAgB,QAAA;EAE1D,SAAA,kCAA2C,OAAA,GAAA,CAC/C,QAAA,EAAU,SAAA,EACV,OAAA,GAAU,gBAAA,GACT,OAAA,CACD,kBAAA,CAAmB,gBAAA,CAAiB,SAAA,GAAY,gBAAA,CAAiB,SAAA;EAE7D,SAAA,CAAU,MAAA,EAAQ,eAAA,GAAkB,OAAA,CAAQ,kBAAA,CAAmB,KAAA;AAAA"}
|