@langchain/langgraph-sdk 1.8.10 → 1.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +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":"subgraphs.js","names":["#onValuesEvent","#promoted","#shadow","#ensureShadow","#commit"],"sources":["../../../src/stream/discovery/subgraphs.ts"],"sourcesContent":["/**\n * Root-scoped subgraph discovery.\n *\n * Watches namespaced `lifecycle` events on the root subscription and\n * assembles two views of the subgraph set:\n *\n * - {@link SubgraphMap}: `Map<namespaceKey, SubgraphDiscoverySnapshot>`,\n * the canonical identity-keyed view consumed by the channel\n * registry and selector hooks.\n * - {@link SubgraphByNodeMap}: `Map<nodeName, readonly\n * SubgraphDiscoverySnapshot[]>`, a convenience index so callers\n * can look up subgraphs by the graph node that produced them\n * (`addNode(\"visualizer_0\", …)`) without parsing namespaces.\n * Arrays preserve insertion order, which matters for parallel\n * fan-outs that share a node name.\n *\n * # What counts as a subgraph\n *\n * The server emits a namespaced `lifecycle` event for every node\n * invocation — a plain function node (`orchestrator`) and a subgraph\n * host (`research`) look identical on the wire. We classify a\n * namespace as a subgraph iff at least one strictly-deeper namespace\n * has been observed with it as a prefix. Concretely, given a stream\n * whose lifecycle events hit the namespaces\n *\n * `[\"orchestrator:u1\"]`\n * `[\"research:u2\"]`\n * `[\"research:u2\", \"researcher:u3\"]`\n * `[\"research:u2\", \"tools:u4\"]`\n * `[\"writer:u5\"]`\n *\n * only `[\"research:u2\"]` is promoted — it's the only namespace that\n * hosts deeper executions. `orchestrator` and `writer` are plain\n * function-node leaves; the `researcher` / `tools` entries are the\n * subgraph's internal nodes, not subgraphs in their own right.\n *\n * Promotion is monotonic (a namespace never loses subgraph status)\n * and retroactive: a namespace whose own `started` event arrived\n * before any descendant is promoted later when the first descendant\n * event lands. Latency is bounded by the gap between a parent node\n * entering and its first inner node materializing — typically tens\n * of milliseconds.\n */\nimport type { Event, LifecycleEvent, ValuesEvent } from \"@langchain/protocol\";\nimport { StreamStore } from \"../store.js\";\nimport type { SubgraphDiscoverySnapshot } from \"../types.js\";\nimport {\n isInternalWorkNamespace,\n isRootNamespace,\n namespaceKey,\n} from \"../namespace.js\";\n\nexport type SubgraphMap = ReadonlyMap<string, SubgraphDiscoverySnapshot>;\nexport type SubgraphByNodeMap = ReadonlyMap<\n string,\n readonly SubgraphDiscoverySnapshot[]\n>;\n\ninterface MutableSubgraph {\n id: string;\n namespace: readonly string[];\n nodeName: string;\n status: \"running\" | \"complete\" | \"error\";\n startedAt: Date;\n completedAt: Date | null;\n}\n\n/**\n * LangGraph namespaces a node invocation as `<node_name>:<uuid>`\n * (parallel fan-outs share `<node_name>` as a prefix but each get a\n * fresh uuid). Extract the node-name half so callers can key\n * discovery lookups on names they wrote in `addNode(...)`.\n */\nfunction parseNodeName(segment: string): string {\n const colon = segment.indexOf(\":\");\n return colon === -1 ? segment : segment.slice(0, colon);\n}\n\nexport class SubgraphDiscovery {\n readonly store = new StreamStore<SubgraphMap>(new Map());\n readonly byNodeStore = new StreamStore<SubgraphByNodeMap>(new Map());\n\n /**\n * Latest known status for every namespaced lifecycle event we have\n * ever observed. A shadow entry is NOT necessarily a subgraph —\n * it is only projected into the committed stores once the same\n * namespace also appears in {@link #promoted}.\n */\n #shadow = new Map<string, MutableSubgraph>();\n\n /**\n * Namespaces that have been observed as a strict prefix of a\n * deeper namespace and are therefore confirmed subgraph hosts.\n * Insertion order is preserved and becomes the iteration order\n * of the committed snapshot maps.\n */\n #promoted = new Set<string>();\n\n /** Feed a single root event. Non-discovery events are ignored. */\n push(event: Event): void {\n if (event.method === \"values\") {\n this.#onValuesEvent(event as ValuesEvent);\n return;\n }\n if (event.method !== \"lifecycle\") return;\n const lifecycle = event as LifecycleEvent;\n const namespace = lifecycle.params.namespace;\n // Root lifecycle events describe the main run; subgraph discovery\n // only cares about namespaced lifecycle events.\n if (isRootNamespace(namespace)) return;\n const id = namespaceKey(namespace);\n const data = lifecycle.params.data as { event?: string };\n const lastSegment = namespace[namespace.length - 1] ?? \"\";\n const nodeName = parseNodeName(lastSegment);\n\n let touched = false;\n\n // Promote every strict ancestor the first time we see it as a\n // prefix. The ancestor may or may not yet have a shadow entry;\n // #commit() tolerates either case.\n for (let depth = 1; depth < namespace.length; depth += 1) {\n const ancestorId = namespaceKey(namespace.slice(0, depth));\n if (!this.#promoted.has(ancestorId)) {\n this.#promoted.add(ancestorId);\n if (this.#shadow.has(ancestorId)) touched = true;\n }\n }\n\n // Update shadow status for this namespace itself.\n if (data.event === \"started\") {\n if (!this.#shadow.has(id)) {\n this.#shadow.set(id, {\n id,\n namespace: [...namespace],\n nodeName,\n status: \"running\",\n startedAt: new Date(),\n completedAt: null,\n });\n if (this.#promoted.has(id)) touched = true;\n }\n } else if (\n data.event === \"completed\" ||\n data.event === \"interrupted\" ||\n data.event === \"failed\"\n ) {\n // Synthesize a shadow entry if we missed the `started` event\n // (common when a late subscription attaches to a running run).\n const entry = this.#ensureShadow(id, namespace, nodeName);\n if (data.event === \"failed\") {\n entry.status = \"error\";\n } else {\n entry.status = \"complete\";\n }\n entry.completedAt = new Date();\n if (this.#promoted.has(id)) touched = true;\n }\n\n if (touched) this.#commit();\n }\n\n /**\n * Promote subgraph host namespaces from namespaced `values` snapshots.\n *\n * Older protocol streams exposed subgraph structure primarily through\n * nested `lifecycle` events: a host namespace such as\n * `[\"research:<uuid>\"]` was promoted once a deeper namespace like\n * `[\"research:<uuid>\", \"inner:<uuid>\"]` appeared. Some runtimes now\n * emit the useful subgraph signal as `values` snapshots scoped directly\n * to the host namespace instead, without forwarding inner lifecycle\n * events to the client. In that shape, the namespace on the `values`\n * event is already the selector target that `useMessages(stream,\n * subgraph)` should subscribe to, so we create/promote the shadow\n * subgraph entry from that namespace.\n *\n * Root `values` events are ignored because they represent the parent\n * thread state, not a subgraph. Tool/subagent namespaces are also\n * ignored because deep-agent task tools emit their own namespaced\n * `values` snapshots under `tools:*` / `task:*`; those are discovered\n * by `SubagentDiscovery` and must not be duplicated as subgraphs.\n *\n * A `values` event does not carry lifecycle terminal status, so the\n * entry remains marked `running` until a matching lifecycle terminal\n * event arrives. If no terminal arrives, the discovery map still\n * contains the host namespace, which is the important invariant for\n * scoped selectors.\n */\n #onValuesEvent(event: ValuesEvent): void {\n const namespace = event.params.namespace;\n if (isRootNamespace(namespace)) return;\n if (isInternalWorkNamespace(namespace)) return;\n const data = event.params.data;\n if (data == null || typeof data !== \"object\" || Array.isArray(data)) return;\n\n const id = namespaceKey(namespace);\n const lastSegment = namespace[namespace.length - 1] ?? \"\";\n const nodeName = parseNodeName(lastSegment);\n const entry = this.#ensureShadow(id, namespace, nodeName);\n entry.status = \"running\";\n\n if (!this.#promoted.has(id)) {\n this.#promoted.add(id);\n }\n this.#commit();\n }\n\n get snapshot(): SubgraphMap {\n return this.store.getSnapshot();\n }\n\n get byNodeSnapshot(): SubgraphByNodeMap {\n return this.byNodeStore.getSnapshot();\n }\n\n #ensureShadow(\n id: string,\n namespace: readonly string[],\n nodeName: string\n ): MutableSubgraph {\n let entry = this.#shadow.get(id);\n if (entry == null) {\n entry = {\n id,\n namespace: [...namespace],\n nodeName,\n status: \"running\",\n startedAt: new Date(),\n completedAt: null,\n };\n this.#shadow.set(id, entry);\n }\n return entry;\n }\n\n #commit(): void {\n const snapshots: SubgraphDiscoverySnapshot[] = [];\n for (const id of this.#promoted) {\n const entry = this.#shadow.get(id);\n // A namespace can be promoted before its own lifecycle event\n // arrives if descendant events outpace the prefix event. Skip\n // until the shadow entry lands; the next push() promoting or\n // updating this namespace will re-commit.\n if (entry == null) continue;\n snapshots.push({ ...entry });\n }\n\n this.store.setValue(new Map(snapshots.map((s) => [s.id, s])));\n\n const byNode = new Map<string, SubgraphDiscoverySnapshot[]>();\n for (const snap of snapshots) {\n const bucket = byNode.get(snap.nodeName);\n if (bucket == null) byNode.set(snap.nodeName, [snap]);\n else bucket.push(snap);\n }\n this.byNodeStore.setValue(byNode);\n }\n}\n"],"mappings":";;;;;;;;;AAyEA,SAAS,cAAc,SAAyB;CAC9C,MAAM,QAAQ,QAAQ,QAAQ,IAAI;AAClC,QAAO,UAAU,KAAK,UAAU,QAAQ,MAAM,GAAG,MAAM;;AAGzD,IAAa,oBAAb,MAA+B;CAC7B,QAAiB,IAAI,4BAAyB,IAAI,KAAK,CAAC;CACxD,cAAuB,IAAI,4BAA+B,IAAI,KAAK,CAAC;;;;;;;CAQpE,0BAAU,IAAI,KAA8B;;;;;;;CAQ5C,4BAAY,IAAI,KAAa;;CAG7B,KAAK,OAAoB;AACvB,MAAI,MAAM,WAAW,UAAU;AAC7B,SAAA,cAAoB,MAAqB;AACzC;;AAEF,MAAI,MAAM,WAAW,YAAa;EAClC,MAAM,YAAY;EAClB,MAAM,YAAY,UAAU,OAAO;AAGnC,MAAI,gBAAgB,UAAU,CAAE;EAChC,MAAM,KAAK,aAAa,UAAU;EAClC,MAAM,OAAO,UAAU,OAAO;EAE9B,MAAM,WAAW,cADG,UAAU,UAAU,SAAS,MAAM,GACZ;EAE3C,IAAI,UAAU;AAKd,OAAK,IAAI,QAAQ,GAAG,QAAQ,UAAU,QAAQ,SAAS,GAAG;GACxD,MAAM,aAAa,aAAa,UAAU,MAAM,GAAG,MAAM,CAAC;AAC1D,OAAI,CAAC,MAAA,SAAe,IAAI,WAAW,EAAE;AACnC,UAAA,SAAe,IAAI,WAAW;AAC9B,QAAI,MAAA,OAAa,IAAI,WAAW,CAAE,WAAU;;;AAKhD,MAAI,KAAK,UAAU;OACb,CAAC,MAAA,OAAa,IAAI,GAAG,EAAE;AACzB,UAAA,OAAa,IAAI,IAAI;KACnB;KACA,WAAW,CAAC,GAAG,UAAU;KACzB;KACA,QAAQ;KACR,2BAAW,IAAI,MAAM;KACrB,aAAa;KACd,CAAC;AACF,QAAI,MAAA,SAAe,IAAI,GAAG,CAAE,WAAU;;aAGxC,KAAK,UAAU,eACf,KAAK,UAAU,iBACf,KAAK,UAAU,UACf;GAGA,MAAM,QAAQ,MAAA,aAAmB,IAAI,WAAW,SAAS;AACzD,OAAI,KAAK,UAAU,SACjB,OAAM,SAAS;OAEf,OAAM,SAAS;AAEjB,SAAM,8BAAc,IAAI,MAAM;AAC9B,OAAI,MAAA,SAAe,IAAI,GAAG,CAAE,WAAU;;AAGxC,MAAI,QAAS,OAAA,QAAc;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA6B7B,eAAe,OAA0B;EACvC,MAAM,YAAY,MAAM,OAAO;AAC/B,MAAI,gBAAgB,UAAU,CAAE;AAChC,MAAI,wBAAwB,UAAU,CAAE;EACxC,MAAM,OAAO,MAAM,OAAO;AAC1B,MAAI,QAAQ,QAAQ,OAAO,SAAS,YAAY,MAAM,QAAQ,KAAK,CAAE;EAErE,MAAM,KAAK,aAAa,UAAU;EAElC,MAAM,WAAW,cADG,UAAU,UAAU,SAAS,MAAM,GACZ;EAC3C,MAAM,QAAQ,MAAA,aAAmB,IAAI,WAAW,SAAS;AACzD,QAAM,SAAS;AAEf,MAAI,CAAC,MAAA,SAAe,IAAI,GAAG,CACzB,OAAA,SAAe,IAAI,GAAG;AAExB,QAAA,QAAc;;CAGhB,IAAI,WAAwB;AAC1B,SAAO,KAAK,MAAM,aAAa;;CAGjC,IAAI,iBAAoC;AACtC,SAAO,KAAK,YAAY,aAAa;;CAGvC,cACE,IACA,WACA,UACiB;EACjB,IAAI,QAAQ,MAAA,OAAa,IAAI,GAAG;AAChC,MAAI,SAAS,MAAM;AACjB,WAAQ;IACN;IACA,WAAW,CAAC,GAAG,UAAU;IACzB;IACA,QAAQ;IACR,2BAAW,IAAI,MAAM;IACrB,aAAa;IACd;AACD,SAAA,OAAa,IAAI,IAAI,MAAM;;AAE7B,SAAO;;CAGT,UAAgB;EACd,MAAM,YAAyC,EAAE;AACjD,OAAK,MAAM,MAAM,MAAA,UAAgB;GAC/B,MAAM,QAAQ,MAAA,OAAa,IAAI,GAAG;AAKlC,OAAI,SAAS,KAAM;AACnB,aAAU,KAAK,EAAE,GAAG,OAAO,CAAC;;AAG9B,OAAK,MAAM,SAAS,IAAI,IAAI,UAAU,KAAK,MAAM,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;EAE7D,MAAM,yBAAS,IAAI,KAA0C;AAC7D,OAAK,MAAM,QAAQ,WAAW;GAC5B,MAAM,SAAS,OAAO,IAAI,KAAK,SAAS;AACxC,OAAI,UAAU,KAAM,QAAO,IAAI,KAAK,UAAU,CAAC,KAAK,CAAC;OAChD,QAAO,KAAK,KAAK;;AAExB,OAAK,YAAY,SAAS,OAAO"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
const require_media = require("../client/stream/media.cjs");
|
|
3
|
+
const require_constants = require("./constants.cjs");
|
|
4
|
+
const require_store = require("./store.cjs");
|
|
5
|
+
const require_channel_registry = require("./channel-registry.cjs");
|
|
6
|
+
const require_subagents = require("./discovery/subagents.cjs");
|
|
7
|
+
const require_subgraphs = require("./discovery/subgraphs.cjs");
|
|
8
|
+
const require_assembled_to_message = require("./assembled-to-message.cjs");
|
|
9
|
+
const require_controller = require("./controller.cjs");
|
|
10
|
+
const require_messages = require("./projections/messages.cjs");
|
|
11
|
+
const require_tool_calls = require("./projections/tool-calls.cjs");
|
|
12
|
+
const require_values = require("./projections/values.cjs");
|
|
13
|
+
const require_extension = require("./projections/extension.cjs");
|
|
14
|
+
const require_channel = require("./projections/channel.cjs");
|
|
15
|
+
const require_media$1 = require("./projections/media.cjs");
|
|
16
|
+
require("./projections/index.cjs");
|
|
17
|
+
exports.ChannelRegistry = require_channel_registry.ChannelRegistry;
|
|
18
|
+
exports.MediaAssembler = require_media.MediaAssembler;
|
|
19
|
+
exports.MediaAssemblyError = require_media.MediaAssemblyError;
|
|
20
|
+
exports.NAMESPACE_SEPARATOR = require_constants.NAMESPACE_SEPARATOR;
|
|
21
|
+
exports.ROOT_PUMP_CHANNELS = require_controller.ROOT_PUMP_CHANNELS;
|
|
22
|
+
exports.StreamController = require_controller.StreamController;
|
|
23
|
+
exports.StreamStore = require_store.StreamStore;
|
|
24
|
+
exports.SubagentDiscovery = require_subagents.SubagentDiscovery;
|
|
25
|
+
exports.SubgraphDiscovery = require_subgraphs.SubgraphDiscovery;
|
|
26
|
+
exports.assembledMessageToBaseMessage = require_assembled_to_message.assembledMessageToBaseMessage;
|
|
27
|
+
exports.assembledToBaseMessage = require_assembled_to_message.assembledToBaseMessage;
|
|
28
|
+
exports.audioProjection = require_media$1.audioProjection;
|
|
29
|
+
exports.channelProjection = require_channel.channelProjection;
|
|
30
|
+
exports.extensionProjection = require_extension.extensionProjection;
|
|
31
|
+
exports.filesProjection = require_media$1.filesProjection;
|
|
32
|
+
exports.imagesProjection = require_media$1.imagesProjection;
|
|
33
|
+
exports.messagesProjection = require_messages.messagesProjection;
|
|
34
|
+
exports.toolCallsProjection = require_tool_calls.toolCallsProjection;
|
|
35
|
+
exports.valuesProjection = require_values.valuesProjection;
|
|
36
|
+
exports.videoProjection = require_media$1.videoProjection;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { DefaultToolCall, ToolCallFromTool } from "../types.messages.cjs";
|
|
2
|
+
import { AssembledToolCall, ToolCallStatus } from "../client/stream/handles/tools.cjs";
|
|
3
|
+
import { AnyMediaHandle, AudioMedia, FileMedia, ImageMedia, MediaAssembler, MediaAssemblerCallbacks, MediaAssemblerOptions, MediaAssemblyError, MediaAssemblyErrorKind, MediaBase, MediaBlockType, VideoMedia } from "../client/stream/media.cjs";
|
|
4
|
+
import { AgentServerAdapter, TransportAdapter } from "../client/stream/transport.cjs";
|
|
5
|
+
import { AgentTypeConfigLike, CompiledSubAgentLike, DeepAgentTypeConfigLike, DefaultSubagentStates, ExtractAgentConfig, ExtractDeepAgentConfig, ExtractSubAgentMiddleware, InferAgentToolCalls, InferDeepAgentSubagents, InferSubagentByName, InferSubagentNames, InferSubagentState, IsAgentLike, IsDeepAgentLike, SubAgentLike, SubagentStateMap, SubagentToolCall } from "../ui/types.cjs";
|
|
6
|
+
import { InferBag, InferNodeNames } from "../ui/stream/index.cjs";
|
|
7
|
+
import { InferStateType, InferSubagentStates, InferToolCalls, WidenUpdateMessages } from "./types-inference.cjs";
|
|
8
|
+
import { StoreListener, StreamStore } from "./store.cjs";
|
|
9
|
+
import { AcquiredProjection, AgentServerOptions, CustomAdapterOptions, ProjectionRuntime, ProjectionSpec, RootEventBus, RootSnapshot, StateOf, StreamControllerOptions, StreamSubmitOptions, SubagentDiscoverySnapshot, SubgraphDiscoverySnapshot, Target, UseStreamCommonOptions, UseStreamOptions } from "./types.cjs";
|
|
10
|
+
import { ChannelRegistry } from "./channel-registry.cjs";
|
|
11
|
+
import { SubagentDiscovery, SubagentMap } from "./discovery/subagents.cjs";
|
|
12
|
+
import { SubgraphByNodeMap, SubgraphDiscovery, SubgraphMap } from "./discovery/subgraphs.cjs";
|
|
13
|
+
import { MessageMetadata, MessageMetadataMap } from "./message-metadata-tracker.cjs";
|
|
14
|
+
import { SubmissionQueueEntry, SubmissionQueueSnapshot } from "./submit-coordinator.cjs";
|
|
15
|
+
import { ROOT_PUMP_CHANNELS, StreamController } from "./controller.cjs";
|
|
16
|
+
import { messagesProjection } from "./projections/messages.cjs";
|
|
17
|
+
import { toolCallsProjection } from "./projections/tool-calls.cjs";
|
|
18
|
+
import { valuesProjection } from "./projections/values.cjs";
|
|
19
|
+
import { extensionProjection } from "./projections/extension.cjs";
|
|
20
|
+
import { ChannelProjectionOptions, channelProjection } from "./projections/channel.cjs";
|
|
21
|
+
import { MediaProjectionOptions, audioProjection, filesProjection, imagesProjection, videoProjection } from "./projections/media.cjs";
|
|
22
|
+
import { AssembledToMessageInput, ExtendedMessageRole, assembledMessageToBaseMessage, assembledToBaseMessage } from "./assembled-to-message.cjs";
|
|
23
|
+
import { NAMESPACE_SEPARATOR } from "./constants.cjs";
|
|
24
|
+
import { Channel, Event } from "@langchain/protocol";
|
|
25
|
+
export { type AcquiredProjection, type AgentServerAdapter, type AgentServerOptions, type AgentTypeConfigLike, type AnyMediaHandle, type AssembledToMessageInput, type AssembledToolCall, type AudioMedia, type Channel, type ChannelProjectionOptions, ChannelRegistry, type CompiledSubAgentLike, type CustomAdapterOptions, type DeepAgentTypeConfigLike, type DefaultSubagentStates, type DefaultToolCall, type Event, type ExtendedMessageRole, type ExtractAgentConfig, type ExtractDeepAgentConfig, type ExtractSubAgentMiddleware, type FileMedia, type ImageMedia, type InferAgentToolCalls, type InferBag, type InferDeepAgentSubagents, type InferNodeNames, type InferStateType, type InferSubagentByName, type InferSubagentNames, type InferSubagentState, type InferSubagentStates, type InferToolCalls, type IsAgentLike, type IsDeepAgentLike, MediaAssembler, type MediaAssemblerCallbacks, type MediaAssemblerOptions, MediaAssemblyError, type MediaAssemblyErrorKind, type MediaBase, type MediaBlockType, type MediaProjectionOptions, type MessageMetadata, type MessageMetadataMap, NAMESPACE_SEPARATOR, type ProjectionRuntime, type ProjectionSpec, ROOT_PUMP_CHANNELS, type RootEventBus, type RootSnapshot, type StateOf, type StoreListener, StreamController, type StreamControllerOptions, StreamStore, type StreamSubmitOptions, type SubAgentLike, SubagentDiscovery, type SubagentDiscoverySnapshot, type SubagentMap, type SubagentStateMap, type SubagentToolCall, type SubgraphByNodeMap, SubgraphDiscovery, type SubgraphDiscoverySnapshot, type SubgraphMap, type SubmissionQueueEntry, type SubmissionQueueSnapshot, type Target, type ToolCallFromTool, type ToolCallStatus, type TransportAdapter, type UseStreamCommonOptions, type UseStreamOptions, type VideoMedia, type WidenUpdateMessages, assembledMessageToBaseMessage, assembledToBaseMessage, audioProjection, channelProjection, extensionProjection, filesProjection, imagesProjection, messagesProjection, toolCallsProjection, valuesProjection, videoProjection };
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { DefaultToolCall, ToolCallFromTool } from "../types.messages.js";
|
|
2
|
+
import { AssembledToolCall, ToolCallStatus } from "../client/stream/handles/tools.js";
|
|
3
|
+
import { AnyMediaHandle, AudioMedia, FileMedia, ImageMedia, MediaAssembler, MediaAssemblerCallbacks, MediaAssemblerOptions, MediaAssemblyError, MediaAssemblyErrorKind, MediaBase, MediaBlockType, VideoMedia } from "../client/stream/media.js";
|
|
4
|
+
import { AgentServerAdapter, TransportAdapter } from "../client/stream/transport.js";
|
|
5
|
+
import { AgentTypeConfigLike, CompiledSubAgentLike, DeepAgentTypeConfigLike, DefaultSubagentStates, ExtractAgentConfig, ExtractDeepAgentConfig, ExtractSubAgentMiddleware, InferAgentToolCalls, InferDeepAgentSubagents, InferSubagentByName, InferSubagentNames, InferSubagentState, IsAgentLike, IsDeepAgentLike, SubAgentLike, SubagentStateMap, SubagentToolCall } from "../ui/types.js";
|
|
6
|
+
import { InferBag, InferNodeNames } from "../ui/stream/index.js";
|
|
7
|
+
import { InferStateType, InferSubagentStates, InferToolCalls, WidenUpdateMessages } from "./types-inference.js";
|
|
8
|
+
import { StoreListener, StreamStore } from "./store.js";
|
|
9
|
+
import { AcquiredProjection, AgentServerOptions, CustomAdapterOptions, ProjectionRuntime, ProjectionSpec, RootEventBus, RootSnapshot, StateOf, StreamControllerOptions, StreamSubmitOptions, SubagentDiscoverySnapshot, SubgraphDiscoverySnapshot, Target, UseStreamCommonOptions, UseStreamOptions } from "./types.js";
|
|
10
|
+
import { ChannelRegistry } from "./channel-registry.js";
|
|
11
|
+
import { SubagentDiscovery, SubagentMap } from "./discovery/subagents.js";
|
|
12
|
+
import { SubgraphByNodeMap, SubgraphDiscovery, SubgraphMap } from "./discovery/subgraphs.js";
|
|
13
|
+
import { MessageMetadata, MessageMetadataMap } from "./message-metadata-tracker.js";
|
|
14
|
+
import { SubmissionQueueEntry, SubmissionQueueSnapshot } from "./submit-coordinator.js";
|
|
15
|
+
import { ROOT_PUMP_CHANNELS, StreamController } from "./controller.js";
|
|
16
|
+
import { messagesProjection } from "./projections/messages.js";
|
|
17
|
+
import { toolCallsProjection } from "./projections/tool-calls.js";
|
|
18
|
+
import { valuesProjection } from "./projections/values.js";
|
|
19
|
+
import { extensionProjection } from "./projections/extension.js";
|
|
20
|
+
import { ChannelProjectionOptions, channelProjection } from "./projections/channel.js";
|
|
21
|
+
import { MediaProjectionOptions, audioProjection, filesProjection, imagesProjection, videoProjection } from "./projections/media.js";
|
|
22
|
+
import { AssembledToMessageInput, ExtendedMessageRole, assembledMessageToBaseMessage, assembledToBaseMessage } from "./assembled-to-message.js";
|
|
23
|
+
import { NAMESPACE_SEPARATOR } from "./constants.js";
|
|
24
|
+
import { Channel, Event } from "@langchain/protocol";
|
|
25
|
+
export { type AcquiredProjection, type AgentServerAdapter, type AgentServerOptions, type AgentTypeConfigLike, type AnyMediaHandle, type AssembledToMessageInput, type AssembledToolCall, type AudioMedia, type Channel, type ChannelProjectionOptions, ChannelRegistry, type CompiledSubAgentLike, type CustomAdapterOptions, type DeepAgentTypeConfigLike, type DefaultSubagentStates, type DefaultToolCall, type Event, type ExtendedMessageRole, type ExtractAgentConfig, type ExtractDeepAgentConfig, type ExtractSubAgentMiddleware, type FileMedia, type ImageMedia, type InferAgentToolCalls, type InferBag, type InferDeepAgentSubagents, type InferNodeNames, type InferStateType, type InferSubagentByName, type InferSubagentNames, type InferSubagentState, type InferSubagentStates, type InferToolCalls, type IsAgentLike, type IsDeepAgentLike, MediaAssembler, type MediaAssemblerCallbacks, type MediaAssemblerOptions, MediaAssemblyError, type MediaAssemblyErrorKind, type MediaBase, type MediaBlockType, type MediaProjectionOptions, type MessageMetadata, type MessageMetadataMap, NAMESPACE_SEPARATOR, type ProjectionRuntime, type ProjectionSpec, ROOT_PUMP_CHANNELS, type RootEventBus, type RootSnapshot, type StateOf, type StoreListener, StreamController, type StreamControllerOptions, StreamStore, type StreamSubmitOptions, type SubAgentLike, SubagentDiscovery, type SubagentDiscoverySnapshot, type SubagentMap, type SubagentStateMap, type SubagentToolCall, type SubgraphByNodeMap, SubgraphDiscovery, type SubgraphDiscoverySnapshot, type SubgraphMap, type SubmissionQueueEntry, type SubmissionQueueSnapshot, type Target, type ToolCallFromTool, type ToolCallStatus, type TransportAdapter, type UseStreamCommonOptions, type UseStreamOptions, type VideoMedia, type WidenUpdateMessages, assembledMessageToBaseMessage, assembledToBaseMessage, audioProjection, channelProjection, extensionProjection, filesProjection, imagesProjection, messagesProjection, toolCallsProjection, valuesProjection, videoProjection };
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { MediaAssembler, MediaAssemblyError } from "../client/stream/media.js";
|
|
2
|
+
import { NAMESPACE_SEPARATOR } from "./constants.js";
|
|
3
|
+
import { StreamStore } from "./store.js";
|
|
4
|
+
import { ChannelRegistry } from "./channel-registry.js";
|
|
5
|
+
import { SubagentDiscovery } from "./discovery/subagents.js";
|
|
6
|
+
import { SubgraphDiscovery } from "./discovery/subgraphs.js";
|
|
7
|
+
import { assembledMessageToBaseMessage, assembledToBaseMessage } from "./assembled-to-message.js";
|
|
8
|
+
import { ROOT_PUMP_CHANNELS, StreamController } from "./controller.js";
|
|
9
|
+
import { messagesProjection } from "./projections/messages.js";
|
|
10
|
+
import { toolCallsProjection } from "./projections/tool-calls.js";
|
|
11
|
+
import { valuesProjection } from "./projections/values.js";
|
|
12
|
+
import { extensionProjection } from "./projections/extension.js";
|
|
13
|
+
import { channelProjection } from "./projections/channel.js";
|
|
14
|
+
import { audioProjection, filesProjection, imagesProjection, videoProjection } from "./projections/media.js";
|
|
15
|
+
import "./projections/index.js";
|
|
16
|
+
export { ChannelRegistry, MediaAssembler, MediaAssemblyError, NAMESPACE_SEPARATOR, ROOT_PUMP_CHANNELS, StreamController, StreamStore, SubagentDiscovery, SubgraphDiscovery, assembledMessageToBaseMessage, assembledToBaseMessage, audioProjection, channelProjection, extensionProjection, filesProjection, imagesProjection, messagesProjection, toolCallsProjection, valuesProjection, videoProjection };
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
const require_namespace = require("./namespace.cjs");
|
|
2
|
+
//#region src/stream/lifecycle-loading-tracker.ts
|
|
3
|
+
/**
|
|
4
|
+
* Drives root-snapshot `isLoading` from root lifecycle events.
|
|
5
|
+
*/
|
|
6
|
+
var LifecycleLoadingTracker = class {
|
|
7
|
+
/** Snapshot store whose `isLoading` slot we manage. */
|
|
8
|
+
#store;
|
|
9
|
+
/**
|
|
10
|
+
* Disposal probe. Consulted from the deferred `setTimeout` so a
|
|
11
|
+
* controller torn down between scheduling and firing doesn't end
|
|
12
|
+
* up writing to a defunct store.
|
|
13
|
+
*/
|
|
14
|
+
#isDisposed;
|
|
15
|
+
/**
|
|
16
|
+
* Highest sequence number of a terminal lifecycle we've observed.
|
|
17
|
+
* `running` events at or below this seq are stale replays and
|
|
18
|
+
* are dropped to avoid flipping the loading flag back on after the
|
|
19
|
+
* run has already ended.
|
|
20
|
+
*/
|
|
21
|
+
#lastTerminalLifecycleSeq = -1;
|
|
22
|
+
/**
|
|
23
|
+
* @param params.store - Store whose `isLoading` slot we drive.
|
|
24
|
+
* @param params.isDisposed - Disposal probe consulted from deferred callbacks.
|
|
25
|
+
*/
|
|
26
|
+
constructor(params) {
|
|
27
|
+
this.#store = params.store;
|
|
28
|
+
this.#isDisposed = params.isDisposed;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Bound listener suitable for `EventBus.subscribe`. Re-exposed as a
|
|
32
|
+
* stable property so the controller can later remove the same
|
|
33
|
+
* function reference from the bus on teardown.
|
|
34
|
+
*/
|
|
35
|
+
listener = (event) => {
|
|
36
|
+
this.handle(event);
|
|
37
|
+
};
|
|
38
|
+
/**
|
|
39
|
+
* Reset internal state when rebinding to a new thread.
|
|
40
|
+
*
|
|
41
|
+
* The terminal-seq guard is per-thread: a new thread's `running`
|
|
42
|
+
* events are not stale relative to the old thread's terminals.
|
|
43
|
+
*/
|
|
44
|
+
reset() {
|
|
45
|
+
this.#lastTerminalLifecycleSeq = -1;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Process a single protocol event.
|
|
49
|
+
*
|
|
50
|
+
* Filters down to root-namespace lifecycle events, then mutates the
|
|
51
|
+
* store's `isLoading` slot. All other events are ignored.
|
|
52
|
+
*
|
|
53
|
+
* @param event - Any protocol event from the controller's root bus.
|
|
54
|
+
*/
|
|
55
|
+
handle(event) {
|
|
56
|
+
if (event.method !== "lifecycle") return;
|
|
57
|
+
if (!require_namespace.isRootNamespace(event.params.namespace)) return;
|
|
58
|
+
const lifecycle = event.params.data;
|
|
59
|
+
const seq = typeof event.seq === "number" ? event.seq : void 0;
|
|
60
|
+
if (lifecycle?.event === "running") {
|
|
61
|
+
if (seq != null && seq <= this.#lastTerminalLifecycleSeq) return;
|
|
62
|
+
this.#store.setState((s) => s.isLoading ? s : {
|
|
63
|
+
...s,
|
|
64
|
+
isLoading: true
|
|
65
|
+
});
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
if (lifecycle?.event === "completed" || lifecycle?.event === "failed" || lifecycle?.event === "interrupted" || lifecycle?.event === "cancelled") {
|
|
69
|
+
if (seq != null) this.#lastTerminalLifecycleSeq = Math.max(this.#lastTerminalLifecycleSeq, seq);
|
|
70
|
+
setTimeout(() => {
|
|
71
|
+
if (this.#isDisposed()) return;
|
|
72
|
+
this.#store.setState((s) => s.isLoading ? {
|
|
73
|
+
...s,
|
|
74
|
+
isLoading: false
|
|
75
|
+
} : s);
|
|
76
|
+
}, 0);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
};
|
|
80
|
+
//#endregion
|
|
81
|
+
exports.LifecycleLoadingTracker = LifecycleLoadingTracker;
|
|
82
|
+
|
|
83
|
+
//# sourceMappingURL=lifecycle-loading-tracker.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lifecycle-loading-tracker.cjs","names":["#store","#isDisposed","#lastTerminalLifecycleSeq","isRootNamespace"],"sources":["../../src/stream/lifecycle-loading-tracker.ts"],"sourcesContent":["/**\n * Drives the {@link RootSnapshot.isLoading} flag from root lifecycle\n * events.\n *\n * # What it does\n *\n * The tracker watches a stream of protocol events and flips the\n * `isLoading` slot of a {@link StreamStore} based on root-namespace\n * `lifecycle` payloads:\n *\n * - `running` → `isLoading = true`\n * - `completed` / `failed` / `interrupted` / `cancelled`\n * → `isLoading = false`\n *\n * Non-root, non-lifecycle, and unknown events are ignored.\n *\n * # Why it lives in its own class\n *\n * Lifecycle handling has two subtleties that we want to keep out of\n * the {@link StreamController}'s critical path:\n *\n * 1. **Stale `running` filtering.** SSE replays older events on\n * reconnect — including a `running` lifecycle that fired before\n * the run terminated. Without filtering, that replay would flip\n * `isLoading` back to `true` after a `completed` already brought\n * it down. We track the highest terminal `seq` we've seen and\n * drop any `running` whose `seq` is at or below it.\n * 2. **Deferred terminal flip.** The flip from `true → false` is\n * pushed to the next macrotask (`setTimeout(..., 0)`). This\n * gives synchronous consumers — most notably `for await`\n * iterators in framework bindings — one event-loop tick to\n * observe terminal-related state (e.g. the final assistant\n * message landing in `values`) before `isLoading` settles.\n *\n * # Why it's safe to register the listener as `controller.onEvent`\n *\n * The tracker subscribes to the controller's root event bus via the\n * exported {@link listener} arrow. Because the listener is bound at\n * construction time, removing it later (`bus.delete(tracker.listener)`)\n * works without `bind()` gymnastics in the controller.\n *\n * @typeParam T - The snapshot shape; must contain an `isLoading` flag.\n */\nimport type { Event, LifecycleEvent } from \"@langchain/protocol\";\nimport { StreamStore } from \"./store.js\";\nimport { isRootNamespace } from \"./namespace.js\";\n\n/**\n * Minimal contract the snapshot must satisfy. The tracker only\n * touches `isLoading`, leaving everything else for the controller.\n */\ntype LoadingSnapshot = { readonly isLoading: boolean };\n\n/**\n * Drives root-snapshot `isLoading` from root lifecycle events.\n */\nexport class LifecycleLoadingTracker<T extends LoadingSnapshot> {\n /** Snapshot store whose `isLoading` slot we manage. */\n readonly #store: StreamStore<T>;\n\n /**\n * Disposal probe. Consulted from the deferred `setTimeout` so a\n * controller torn down between scheduling and firing doesn't end\n * up writing to a defunct store.\n */\n readonly #isDisposed: () => boolean;\n\n /**\n * Highest sequence number of a terminal lifecycle we've observed.\n * `running` events at or below this seq are stale replays and\n * are dropped to avoid flipping the loading flag back on after the\n * run has already ended.\n */\n #lastTerminalLifecycleSeq = -1;\n\n /**\n * @param params.store - Store whose `isLoading` slot we drive.\n * @param params.isDisposed - Disposal probe consulted from deferred callbacks.\n */\n constructor(params: { store: StreamStore<T>; isDisposed: () => boolean }) {\n this.#store = params.store;\n this.#isDisposed = params.isDisposed;\n }\n\n /**\n * Bound listener suitable for `EventBus.subscribe`. Re-exposed as a\n * stable property so the controller can later remove the same\n * function reference from the bus on teardown.\n */\n readonly listener = (event: Event): void => {\n this.handle(event);\n };\n\n /**\n * Reset internal state when rebinding to a new thread.\n *\n * The terminal-seq guard is per-thread: a new thread's `running`\n * events are not stale relative to the old thread's terminals.\n */\n reset(): void {\n this.#lastTerminalLifecycleSeq = -1;\n }\n\n /**\n * Process a single protocol event.\n *\n * Filters down to root-namespace lifecycle events, then mutates the\n * store's `isLoading` slot. All other events are ignored.\n *\n * @param event - Any protocol event from the controller's root bus.\n */\n handle(event: Event): void {\n if (event.method !== \"lifecycle\") return;\n if (!isRootNamespace(event.params.namespace)) return;\n const lifecycle = (event as LifecycleEvent).params.data as {\n event?: string;\n };\n const seq = typeof event.seq === \"number\" ? event.seq : undefined;\n if (lifecycle?.event === \"running\") {\n // Drop stale `running` replays that arrive *after* a terminal\n // for the same run. SSE re-streams history on reconnect; without\n // this filter the loading flag would oscillate.\n if (seq != null && seq <= this.#lastTerminalLifecycleSeq) {\n return;\n }\n this.#store.setState((s) =>\n s.isLoading ? s : { ...s, isLoading: true }\n );\n return;\n }\n if (\n lifecycle?.event === \"completed\" ||\n lifecycle?.event === \"failed\" ||\n lifecycle?.event === \"interrupted\" ||\n lifecycle?.event === \"cancelled\"\n ) {\n if (seq != null) {\n this.#lastTerminalLifecycleSeq = Math.max(\n this.#lastTerminalLifecycleSeq,\n seq\n );\n }\n // Flip `isLoading=false` on the next macrotask so synchronous\n // consumers iterating events get one tick to observe terminal\n // state (the final values snapshot etc.) before the loading\n // indicator drops.\n setTimeout(() => {\n if (this.#isDisposed()) return;\n this.#store.setState((s) =>\n s.isLoading ? { ...s, isLoading: false } : s\n );\n }, 0);\n }\n }\n}\n"],"mappings":";;;;;AAwDA,IAAa,0BAAb,MAAgE;;CAE9D;;;;;;CAOA;;;;;;;CAQA,4BAA4B;;;;;CAM5B,YAAY,QAA8D;AACxE,QAAA,QAAc,OAAO;AACrB,QAAA,aAAmB,OAAO;;;;;;;CAQ5B,YAAqB,UAAuB;AAC1C,OAAK,OAAO,MAAM;;;;;;;;CASpB,QAAc;AACZ,QAAA,2BAAiC;;;;;;;;;;CAWnC,OAAO,OAAoB;AACzB,MAAI,MAAM,WAAW,YAAa;AAClC,MAAI,CAACG,kBAAAA,gBAAgB,MAAM,OAAO,UAAU,CAAE;EAC9C,MAAM,YAAa,MAAyB,OAAO;EAGnD,MAAM,MAAM,OAAO,MAAM,QAAQ,WAAW,MAAM,MAAM,KAAA;AACxD,MAAI,WAAW,UAAU,WAAW;AAIlC,OAAI,OAAO,QAAQ,OAAO,MAAA,yBACxB;AAEF,SAAA,MAAY,UAAU,MACpB,EAAE,YAAY,IAAI;IAAE,GAAG;IAAG,WAAW;IAAM,CAC5C;AACD;;AAEF,MACE,WAAW,UAAU,eACrB,WAAW,UAAU,YACrB,WAAW,UAAU,iBACrB,WAAW,UAAU,aACrB;AACA,OAAI,OAAO,KACT,OAAA,2BAAiC,KAAK,IACpC,MAAA,0BACA,IACD;AAMH,oBAAiB;AACf,QAAI,MAAA,YAAkB,CAAE;AACxB,UAAA,MAAY,UAAU,MACpB,EAAE,YAAY;KAAE,GAAG;KAAG,WAAW;KAAO,GAAG,EAC5C;MACA,EAAE"}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { isRootNamespace } from "./namespace.js";
|
|
2
|
+
//#region src/stream/lifecycle-loading-tracker.ts
|
|
3
|
+
/**
|
|
4
|
+
* Drives root-snapshot `isLoading` from root lifecycle events.
|
|
5
|
+
*/
|
|
6
|
+
var LifecycleLoadingTracker = class {
|
|
7
|
+
/** Snapshot store whose `isLoading` slot we manage. */
|
|
8
|
+
#store;
|
|
9
|
+
/**
|
|
10
|
+
* Disposal probe. Consulted from the deferred `setTimeout` so a
|
|
11
|
+
* controller torn down between scheduling and firing doesn't end
|
|
12
|
+
* up writing to a defunct store.
|
|
13
|
+
*/
|
|
14
|
+
#isDisposed;
|
|
15
|
+
/**
|
|
16
|
+
* Highest sequence number of a terminal lifecycle we've observed.
|
|
17
|
+
* `running` events at or below this seq are stale replays and
|
|
18
|
+
* are dropped to avoid flipping the loading flag back on after the
|
|
19
|
+
* run has already ended.
|
|
20
|
+
*/
|
|
21
|
+
#lastTerminalLifecycleSeq = -1;
|
|
22
|
+
/**
|
|
23
|
+
* @param params.store - Store whose `isLoading` slot we drive.
|
|
24
|
+
* @param params.isDisposed - Disposal probe consulted from deferred callbacks.
|
|
25
|
+
*/
|
|
26
|
+
constructor(params) {
|
|
27
|
+
this.#store = params.store;
|
|
28
|
+
this.#isDisposed = params.isDisposed;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Bound listener suitable for `EventBus.subscribe`. Re-exposed as a
|
|
32
|
+
* stable property so the controller can later remove the same
|
|
33
|
+
* function reference from the bus on teardown.
|
|
34
|
+
*/
|
|
35
|
+
listener = (event) => {
|
|
36
|
+
this.handle(event);
|
|
37
|
+
};
|
|
38
|
+
/**
|
|
39
|
+
* Reset internal state when rebinding to a new thread.
|
|
40
|
+
*
|
|
41
|
+
* The terminal-seq guard is per-thread: a new thread's `running`
|
|
42
|
+
* events are not stale relative to the old thread's terminals.
|
|
43
|
+
*/
|
|
44
|
+
reset() {
|
|
45
|
+
this.#lastTerminalLifecycleSeq = -1;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Process a single protocol event.
|
|
49
|
+
*
|
|
50
|
+
* Filters down to root-namespace lifecycle events, then mutates the
|
|
51
|
+
* store's `isLoading` slot. All other events are ignored.
|
|
52
|
+
*
|
|
53
|
+
* @param event - Any protocol event from the controller's root bus.
|
|
54
|
+
*/
|
|
55
|
+
handle(event) {
|
|
56
|
+
if (event.method !== "lifecycle") return;
|
|
57
|
+
if (!isRootNamespace(event.params.namespace)) return;
|
|
58
|
+
const lifecycle = event.params.data;
|
|
59
|
+
const seq = typeof event.seq === "number" ? event.seq : void 0;
|
|
60
|
+
if (lifecycle?.event === "running") {
|
|
61
|
+
if (seq != null && seq <= this.#lastTerminalLifecycleSeq) return;
|
|
62
|
+
this.#store.setState((s) => s.isLoading ? s : {
|
|
63
|
+
...s,
|
|
64
|
+
isLoading: true
|
|
65
|
+
});
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
if (lifecycle?.event === "completed" || lifecycle?.event === "failed" || lifecycle?.event === "interrupted" || lifecycle?.event === "cancelled") {
|
|
69
|
+
if (seq != null) this.#lastTerminalLifecycleSeq = Math.max(this.#lastTerminalLifecycleSeq, seq);
|
|
70
|
+
setTimeout(() => {
|
|
71
|
+
if (this.#isDisposed()) return;
|
|
72
|
+
this.#store.setState((s) => s.isLoading ? {
|
|
73
|
+
...s,
|
|
74
|
+
isLoading: false
|
|
75
|
+
} : s);
|
|
76
|
+
}, 0);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
};
|
|
80
|
+
//#endregion
|
|
81
|
+
export { LifecycleLoadingTracker };
|
|
82
|
+
|
|
83
|
+
//# sourceMappingURL=lifecycle-loading-tracker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lifecycle-loading-tracker.js","names":["#store","#isDisposed","#lastTerminalLifecycleSeq"],"sources":["../../src/stream/lifecycle-loading-tracker.ts"],"sourcesContent":["/**\n * Drives the {@link RootSnapshot.isLoading} flag from root lifecycle\n * events.\n *\n * # What it does\n *\n * The tracker watches a stream of protocol events and flips the\n * `isLoading` slot of a {@link StreamStore} based on root-namespace\n * `lifecycle` payloads:\n *\n * - `running` → `isLoading = true`\n * - `completed` / `failed` / `interrupted` / `cancelled`\n * → `isLoading = false`\n *\n * Non-root, non-lifecycle, and unknown events are ignored.\n *\n * # Why it lives in its own class\n *\n * Lifecycle handling has two subtleties that we want to keep out of\n * the {@link StreamController}'s critical path:\n *\n * 1. **Stale `running` filtering.** SSE replays older events on\n * reconnect — including a `running` lifecycle that fired before\n * the run terminated. Without filtering, that replay would flip\n * `isLoading` back to `true` after a `completed` already brought\n * it down. We track the highest terminal `seq` we've seen and\n * drop any `running` whose `seq` is at or below it.\n * 2. **Deferred terminal flip.** The flip from `true → false` is\n * pushed to the next macrotask (`setTimeout(..., 0)`). This\n * gives synchronous consumers — most notably `for await`\n * iterators in framework bindings — one event-loop tick to\n * observe terminal-related state (e.g. the final assistant\n * message landing in `values`) before `isLoading` settles.\n *\n * # Why it's safe to register the listener as `controller.onEvent`\n *\n * The tracker subscribes to the controller's root event bus via the\n * exported {@link listener} arrow. Because the listener is bound at\n * construction time, removing it later (`bus.delete(tracker.listener)`)\n * works without `bind()` gymnastics in the controller.\n *\n * @typeParam T - The snapshot shape; must contain an `isLoading` flag.\n */\nimport type { Event, LifecycleEvent } from \"@langchain/protocol\";\nimport { StreamStore } from \"./store.js\";\nimport { isRootNamespace } from \"./namespace.js\";\n\n/**\n * Minimal contract the snapshot must satisfy. The tracker only\n * touches `isLoading`, leaving everything else for the controller.\n */\ntype LoadingSnapshot = { readonly isLoading: boolean };\n\n/**\n * Drives root-snapshot `isLoading` from root lifecycle events.\n */\nexport class LifecycleLoadingTracker<T extends LoadingSnapshot> {\n /** Snapshot store whose `isLoading` slot we manage. */\n readonly #store: StreamStore<T>;\n\n /**\n * Disposal probe. Consulted from the deferred `setTimeout` so a\n * controller torn down between scheduling and firing doesn't end\n * up writing to a defunct store.\n */\n readonly #isDisposed: () => boolean;\n\n /**\n * Highest sequence number of a terminal lifecycle we've observed.\n * `running` events at or below this seq are stale replays and\n * are dropped to avoid flipping the loading flag back on after the\n * run has already ended.\n */\n #lastTerminalLifecycleSeq = -1;\n\n /**\n * @param params.store - Store whose `isLoading` slot we drive.\n * @param params.isDisposed - Disposal probe consulted from deferred callbacks.\n */\n constructor(params: { store: StreamStore<T>; isDisposed: () => boolean }) {\n this.#store = params.store;\n this.#isDisposed = params.isDisposed;\n }\n\n /**\n * Bound listener suitable for `EventBus.subscribe`. Re-exposed as a\n * stable property so the controller can later remove the same\n * function reference from the bus on teardown.\n */\n readonly listener = (event: Event): void => {\n this.handle(event);\n };\n\n /**\n * Reset internal state when rebinding to a new thread.\n *\n * The terminal-seq guard is per-thread: a new thread's `running`\n * events are not stale relative to the old thread's terminals.\n */\n reset(): void {\n this.#lastTerminalLifecycleSeq = -1;\n }\n\n /**\n * Process a single protocol event.\n *\n * Filters down to root-namespace lifecycle events, then mutates the\n * store's `isLoading` slot. All other events are ignored.\n *\n * @param event - Any protocol event from the controller's root bus.\n */\n handle(event: Event): void {\n if (event.method !== \"lifecycle\") return;\n if (!isRootNamespace(event.params.namespace)) return;\n const lifecycle = (event as LifecycleEvent).params.data as {\n event?: string;\n };\n const seq = typeof event.seq === \"number\" ? event.seq : undefined;\n if (lifecycle?.event === \"running\") {\n // Drop stale `running` replays that arrive *after* a terminal\n // for the same run. SSE re-streams history on reconnect; without\n // this filter the loading flag would oscillate.\n if (seq != null && seq <= this.#lastTerminalLifecycleSeq) {\n return;\n }\n this.#store.setState((s) =>\n s.isLoading ? s : { ...s, isLoading: true }\n );\n return;\n }\n if (\n lifecycle?.event === \"completed\" ||\n lifecycle?.event === \"failed\" ||\n lifecycle?.event === \"interrupted\" ||\n lifecycle?.event === \"cancelled\"\n ) {\n if (seq != null) {\n this.#lastTerminalLifecycleSeq = Math.max(\n this.#lastTerminalLifecycleSeq,\n seq\n );\n }\n // Flip `isLoading=false` on the next macrotask so synchronous\n // consumers iterating events get one tick to observe terminal\n // state (the final values snapshot etc.) before the loading\n // indicator drops.\n setTimeout(() => {\n if (this.#isDisposed()) return;\n this.#store.setState((s) =>\n s.isLoading ? { ...s, isLoading: false } : s\n );\n }, 0);\n }\n }\n}\n"],"mappings":";;;;;AAwDA,IAAa,0BAAb,MAAgE;;CAE9D;;;;;;CAOA;;;;;;;CAQA,4BAA4B;;;;;CAM5B,YAAY,QAA8D;AACxE,QAAA,QAAc,OAAO;AACrB,QAAA,aAAmB,OAAO;;;;;;;CAQ5B,YAAqB,UAAuB;AAC1C,OAAK,OAAO,MAAM;;;;;;;;CASpB,QAAc;AACZ,QAAA,2BAAiC;;;;;;;;;;CAWnC,OAAO,OAAoB;AACzB,MAAI,MAAM,WAAW,YAAa;AAClC,MAAI,CAAC,gBAAgB,MAAM,OAAO,UAAU,CAAE;EAC9C,MAAM,YAAa,MAAyB,OAAO;EAGnD,MAAM,MAAM,OAAO,MAAM,QAAQ,WAAW,MAAM,MAAM,KAAA;AACxD,MAAI,WAAW,UAAU,WAAW;AAIlC,OAAI,OAAO,QAAQ,OAAO,MAAA,yBACxB;AAEF,SAAA,MAAY,UAAU,MACpB,EAAE,YAAY,IAAI;IAAE,GAAG;IAAG,WAAW;IAAM,CAC5C;AACD;;AAEF,MACE,WAAW,UAAU,eACrB,WAAW,UAAU,YACrB,WAAW,UAAU,iBACrB,WAAW,UAAU,aACrB;AACA,OAAI,OAAO,KACT,OAAA,2BAAiC,KAAK,IACpC,MAAA,0BACA,IACD;AAMH,oBAAiB;AACf,QAAI,MAAA,YAAkB,CAAE;AACxB,UAAA,MAAY,UAAU,MACpB,EAAE,YAAY;KAAE,GAAG;KAAG,WAAW;KAAO,GAAG,EAC5C;MACA,EAAE"}
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
const require_store = require("./store.cjs");
|
|
2
|
+
const require_namespace = require("./namespace.cjs");
|
|
3
|
+
//#region src/stream/message-metadata-tracker.ts
|
|
4
|
+
/**
|
|
5
|
+
* Per-message checkpoint metadata projection.
|
|
6
|
+
*
|
|
7
|
+
* # What this module is
|
|
8
|
+
*
|
|
9
|
+
* The protocol emits a `checkpoints` event immediately *before* its
|
|
10
|
+
* companion `values` event for the same superstep:
|
|
11
|
+
*
|
|
12
|
+
* 1. `checkpoints` — `{ id, parent_id?, step?, source? }`
|
|
13
|
+
* 2. `values` — `{ messages, ... }` (same namespace)
|
|
14
|
+
*
|
|
15
|
+
* Both events carry the same `seq` ordering but live on different
|
|
16
|
+
* channels, so the controller can't atomically observe them. This
|
|
17
|
+
* tracker bridges the gap by buffering each `checkpoints` envelope
|
|
18
|
+
* keyed on its namespace, then consuming it when the matching values
|
|
19
|
+
* payload arrives. Once paired, the consumer (typically the
|
|
20
|
+
* controller) writes a {@link MessageMetadata} record under each
|
|
21
|
+
* message id.
|
|
22
|
+
*
|
|
23
|
+
* # Why fork / edit flows need this
|
|
24
|
+
*
|
|
25
|
+
* Surfacing `parentCheckpointId` per-message lets UI flows like
|
|
26
|
+
* "edit a message and re-run" call
|
|
27
|
+
* `submit(input, { forkFrom: { checkpointId } })` without making the
|
|
28
|
+
* caller juggle thread state. Each message remembers the checkpoint
|
|
29
|
+
* it was first observed at, so a "fork from this message" UI can read
|
|
30
|
+
* `useMessageMetadata(stream, msg.id)` directly.
|
|
31
|
+
*
|
|
32
|
+
* # Lifecycle
|
|
33
|
+
*
|
|
34
|
+
* - `bufferCheckpoint(ns, data)` — store the envelope until the
|
|
35
|
+
* companion values event arrives.
|
|
36
|
+
* - `consumeCheckpoint(ns)` — read-and-clear the envelope when
|
|
37
|
+
* the values event lands. Returning `undefined` signals "no
|
|
38
|
+
* metadata to attach" — older snapshots without a paired
|
|
39
|
+
* checkpoint are still applied to the store, just without
|
|
40
|
+
* `parentCheckpointId`.
|
|
41
|
+
* - `recordMessages(msgs, meta)` — write metadata for the supplied
|
|
42
|
+
* message ids if it differs from what's already stored.
|
|
43
|
+
* - `reset()` — clear everything (called on
|
|
44
|
+
* thread rebind / dispose).
|
|
45
|
+
*
|
|
46
|
+
* The buffer is read-and-cleared on consumption so a values event that
|
|
47
|
+
* arrives without a fresh checkpoint envelope doesn't reuse stale
|
|
48
|
+
* metadata from a previous superstep.
|
|
49
|
+
*/
|
|
50
|
+
/**
|
|
51
|
+
* Frozen empty map used as the store's initial value. Keeping the
|
|
52
|
+
* reference stable avoids spurious `setSnapshot` notifications on
|
|
53
|
+
* `reset()` for consumers that haven't observed any metadata yet.
|
|
54
|
+
*/
|
|
55
|
+
const EMPTY_METADATA_MAP = /* @__PURE__ */ new Map();
|
|
56
|
+
/**
|
|
57
|
+
* Tracks checkpoint-derived metadata for messages.
|
|
58
|
+
*
|
|
59
|
+
* Owns one {@link StreamStore} mapping `messageId → MessageMetadata`
|
|
60
|
+
* plus a per-namespace buffer of pending checkpoint envelopes. The
|
|
61
|
+
* controller wires it up via three call sites:
|
|
62
|
+
*
|
|
63
|
+
* 1. `controller.#onRootEvent("checkpoints")`
|
|
64
|
+
* → `bufferCheckpoint(namespace, data)`
|
|
65
|
+
* 2. `controller.#onRootEvent("values")`
|
|
66
|
+
* → `consumeCheckpoint(namespace)` then
|
|
67
|
+
* `recordMessages(values.messages, { parentCheckpointId })`
|
|
68
|
+
* 3. `controller.#teardownThread`
|
|
69
|
+
* → `reset()`
|
|
70
|
+
*
|
|
71
|
+
* @see useMessageMetadata - The framework hook that reads from
|
|
72
|
+
* {@link MessageMetadataTracker.store}.
|
|
73
|
+
*/
|
|
74
|
+
var MessageMetadataTracker = class {
|
|
75
|
+
/** Observable map of messageId → metadata for framework consumers. */
|
|
76
|
+
store = new require_store.StreamStore(EMPTY_METADATA_MAP);
|
|
77
|
+
/**
|
|
78
|
+
* Pending checkpoint envelopes awaiting their companion values
|
|
79
|
+
* event. Keyed by `namespaceKey(namespace)` so a deeply-nested
|
|
80
|
+
* checkpoint at one namespace doesn't collide with a root-level
|
|
81
|
+
* checkpoint emitted in the same tick.
|
|
82
|
+
*/
|
|
83
|
+
#pendingCheckpointByNamespace = /* @__PURE__ */ new Map();
|
|
84
|
+
/**
|
|
85
|
+
* Drop all buffered checkpoints and reset the metadata map to the
|
|
86
|
+
* shared empty instance. Called on thread rebind / dispose so a new
|
|
87
|
+
* thread's metadata can't bleed into the old one.
|
|
88
|
+
*/
|
|
89
|
+
reset() {
|
|
90
|
+
this.#pendingCheckpointByNamespace.clear();
|
|
91
|
+
this.store.setState(() => EMPTY_METADATA_MAP);
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Buffer a `checkpoints` event for later pairing with its values
|
|
95
|
+
* companion.
|
|
96
|
+
*
|
|
97
|
+
* Defensive against missing / malformed payloads:
|
|
98
|
+
*
|
|
99
|
+
* - `data == null` → no-op (some upstream nodes elide the
|
|
100
|
+
* payload entirely; we keep the previous buffered envelope so
|
|
101
|
+
* the next consume call still wins).
|
|
102
|
+
* - `id` not a string → no-op.
|
|
103
|
+
* - `parent_id` not a string → omitted from the envelope.
|
|
104
|
+
*
|
|
105
|
+
* @param namespace - Event namespace (used as the buffer key).
|
|
106
|
+
* @param data - Raw checkpoints payload.
|
|
107
|
+
*/
|
|
108
|
+
bufferCheckpoint(namespace, data) {
|
|
109
|
+
if (data == null || typeof data.id !== "string") return;
|
|
110
|
+
const envelope = { id: data.id };
|
|
111
|
+
if (typeof data.parent_id === "string") envelope.parent_id = data.parent_id;
|
|
112
|
+
this.#pendingCheckpointByNamespace.set(require_namespace.namespaceKey(namespace), envelope);
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Read-and-clear the buffered checkpoint envelope for `namespace`.
|
|
116
|
+
*
|
|
117
|
+
* Always pairs with a single {@link bufferCheckpoint} call: a values
|
|
118
|
+
* event without a matching buffered checkpoint returns `undefined`
|
|
119
|
+
* (meaning "no metadata to attach"), and the next checkpoint event
|
|
120
|
+
* starts fresh rather than reusing stale data.
|
|
121
|
+
*
|
|
122
|
+
* @param namespace - Event namespace to consume.
|
|
123
|
+
* @returns The buffered envelope, or `undefined` when none was buffered.
|
|
124
|
+
*/
|
|
125
|
+
consumeCheckpoint(namespace) {
|
|
126
|
+
const key = require_namespace.namespaceKey(namespace);
|
|
127
|
+
const checkpoint = this.#pendingCheckpointByNamespace.get(key);
|
|
128
|
+
if (checkpoint != null) this.#pendingCheckpointByNamespace.delete(key);
|
|
129
|
+
return checkpoint;
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Record metadata for a list of messages.
|
|
133
|
+
*
|
|
134
|
+
* Skips messages whose existing entry already matches `metadata`;
|
|
135
|
+
* those without an `id` (or with a non-string id) are silently
|
|
136
|
+
* ignored — there's nothing to key the metadata on. The store is
|
|
137
|
+
* only updated when at least one entry actually changed, so
|
|
138
|
+
* reapplying the same values snapshot is cheap.
|
|
139
|
+
*
|
|
140
|
+
* @param messages - Messages from the latest values payload.
|
|
141
|
+
* @param metadata - Metadata to attach (currently just
|
|
142
|
+
* `parentCheckpointId`).
|
|
143
|
+
*/
|
|
144
|
+
recordMessages(messages, metadata) {
|
|
145
|
+
const current = this.store.getSnapshot();
|
|
146
|
+
let changed = false;
|
|
147
|
+
const next = new Map(current);
|
|
148
|
+
for (const msg of messages) {
|
|
149
|
+
const id = msg?.id;
|
|
150
|
+
if (typeof id !== "string" || id.length === 0) continue;
|
|
151
|
+
const prev = next.get(id);
|
|
152
|
+
if (prev != null && prev.parentCheckpointId === metadata.parentCheckpointId) continue;
|
|
153
|
+
next.set(id, {
|
|
154
|
+
...prev,
|
|
155
|
+
...metadata
|
|
156
|
+
});
|
|
157
|
+
changed = true;
|
|
158
|
+
}
|
|
159
|
+
if (changed) this.store.setState(() => next);
|
|
160
|
+
}
|
|
161
|
+
};
|
|
162
|
+
//#endregion
|
|
163
|
+
exports.MessageMetadataTracker = MessageMetadataTracker;
|
|
164
|
+
|
|
165
|
+
//# sourceMappingURL=message-metadata-tracker.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"message-metadata-tracker.cjs","names":["StreamStore","#pendingCheckpointByNamespace","namespaceKey"],"sources":["../../src/stream/message-metadata-tracker.ts"],"sourcesContent":["/**\n * Per-message checkpoint metadata projection.\n *\n * # What this module is\n *\n * The protocol emits a `checkpoints` event immediately *before* its\n * companion `values` event for the same superstep:\n *\n * 1. `checkpoints` — `{ id, parent_id?, step?, source? }`\n * 2. `values` — `{ messages, ... }` (same namespace)\n *\n * Both events carry the same `seq` ordering but live on different\n * channels, so the controller can't atomically observe them. This\n * tracker bridges the gap by buffering each `checkpoints` envelope\n * keyed on its namespace, then consuming it when the matching values\n * payload arrives. Once paired, the consumer (typically the\n * controller) writes a {@link MessageMetadata} record under each\n * message id.\n *\n * # Why fork / edit flows need this\n *\n * Surfacing `parentCheckpointId` per-message lets UI flows like\n * \"edit a message and re-run\" call\n * `submit(input, { forkFrom: { checkpointId } })` without making the\n * caller juggle thread state. Each message remembers the checkpoint\n * it was first observed at, so a \"fork from this message\" UI can read\n * `useMessageMetadata(stream, msg.id)` directly.\n *\n * # Lifecycle\n *\n * - `bufferCheckpoint(ns, data)` — store the envelope until the\n * companion values event arrives.\n * - `consumeCheckpoint(ns)` — read-and-clear the envelope when\n * the values event lands. Returning `undefined` signals \"no\n * metadata to attach\" — older snapshots without a paired\n * checkpoint are still applied to the store, just without\n * `parentCheckpointId`.\n * - `recordMessages(msgs, meta)` — write metadata for the supplied\n * message ids if it differs from what's already stored.\n * - `reset()` — clear everything (called on\n * thread rebind / dispose).\n *\n * The buffer is read-and-cleared on consumption so a values event that\n * arrives without a fresh checkpoint envelope doesn't reuse stale\n * metadata from a previous superstep.\n */\nimport { StreamStore } from \"./store.js\";\nimport { namespaceKey } from \"./namespace.js\";\n\n/**\n * Metadata tracked per message id. Surfaced to applications via\n * `useMessageMetadata(stream, messageId)`.\n */\nexport interface MessageMetadata {\n /**\n * Checkpoint id the message's *parent* was at when this message was\n * observed. Drives fork / edit flows\n * (`submit(input, { forkFrom: { checkpointId } })`).\n *\n * `undefined` when the message was observed without a paired\n * checkpoint envelope (e.g. before checkpoints rolled out, or when\n * the caller stripped them upstream).\n */\n readonly parentCheckpointId: string | undefined;\n}\n\n/**\n * Read-only map exposed via {@link MessageMetadataTracker.store}.\n */\nexport type MessageMetadataMap = ReadonlyMap<string, MessageMetadata>;\n\n/**\n * Lightweight envelope mirroring the on-wire `checkpoints` event.\n *\n * The protocol payload may include additional fields (`step`,\n * `source`, etc.) — we only carry what the per-message metadata\n * actually needs.\n */\nexport interface CheckpointEnvelope {\n /** Checkpoint id this superstep wrote. */\n readonly id: string;\n /**\n * Parent checkpoint id, when present. Becomes\n * {@link MessageMetadata.parentCheckpointId} on the next values event.\n */\n readonly parent_id?: string;\n}\n\n/**\n * Frozen empty map used as the store's initial value. Keeping the\n * reference stable avoids spurious `setSnapshot` notifications on\n * `reset()` for consumers that haven't observed any metadata yet.\n */\nconst EMPTY_METADATA_MAP: MessageMetadataMap = new Map();\n\n/**\n * Tracks checkpoint-derived metadata for messages.\n *\n * Owns one {@link StreamStore} mapping `messageId → MessageMetadata`\n * plus a per-namespace buffer of pending checkpoint envelopes. The\n * controller wires it up via three call sites:\n *\n * 1. `controller.#onRootEvent(\"checkpoints\")`\n * → `bufferCheckpoint(namespace, data)`\n * 2. `controller.#onRootEvent(\"values\")`\n * → `consumeCheckpoint(namespace)` then\n * `recordMessages(values.messages, { parentCheckpointId })`\n * 3. `controller.#teardownThread`\n * → `reset()`\n *\n * @see useMessageMetadata - The framework hook that reads from\n * {@link MessageMetadataTracker.store}.\n */\nexport class MessageMetadataTracker {\n /** Observable map of messageId → metadata for framework consumers. */\n readonly store = new StreamStore<MessageMetadataMap>(EMPTY_METADATA_MAP);\n\n /**\n * Pending checkpoint envelopes awaiting their companion values\n * event. Keyed by `namespaceKey(namespace)` so a deeply-nested\n * checkpoint at one namespace doesn't collide with a root-level\n * checkpoint emitted in the same tick.\n */\n readonly #pendingCheckpointByNamespace = new Map<\n string,\n CheckpointEnvelope\n >();\n\n /**\n * Drop all buffered checkpoints and reset the metadata map to the\n * shared empty instance. Called on thread rebind / dispose so a new\n * thread's metadata can't bleed into the old one.\n */\n reset(): void {\n this.#pendingCheckpointByNamespace.clear();\n this.store.setState(() => EMPTY_METADATA_MAP);\n }\n\n /**\n * Buffer a `checkpoints` event for later pairing with its values\n * companion.\n *\n * Defensive against missing / malformed payloads:\n *\n * - `data == null` → no-op (some upstream nodes elide the\n * payload entirely; we keep the previous buffered envelope so\n * the next consume call still wins).\n * - `id` not a string → no-op.\n * - `parent_id` not a string → omitted from the envelope.\n *\n * @param namespace - Event namespace (used as the buffer key).\n * @param data - Raw checkpoints payload.\n */\n bufferCheckpoint(\n namespace: readonly string[],\n data: { id?: unknown; parent_id?: unknown } | null\n ): void {\n if (data == null || typeof data.id !== \"string\") return;\n const envelope: CheckpointEnvelope = { id: data.id };\n if (typeof data.parent_id === \"string\") {\n (envelope as { parent_id?: string }).parent_id = data.parent_id;\n }\n this.#pendingCheckpointByNamespace.set(namespaceKey(namespace), envelope);\n }\n\n /**\n * Read-and-clear the buffered checkpoint envelope for `namespace`.\n *\n * Always pairs with a single {@link bufferCheckpoint} call: a values\n * event without a matching buffered checkpoint returns `undefined`\n * (meaning \"no metadata to attach\"), and the next checkpoint event\n * starts fresh rather than reusing stale data.\n *\n * @param namespace - Event namespace to consume.\n * @returns The buffered envelope, or `undefined` when none was buffered.\n */\n consumeCheckpoint(\n namespace: readonly string[]\n ): CheckpointEnvelope | undefined {\n const key = namespaceKey(namespace);\n const checkpoint = this.#pendingCheckpointByNamespace.get(key);\n if (checkpoint != null) this.#pendingCheckpointByNamespace.delete(key);\n return checkpoint;\n }\n\n /**\n * Record metadata for a list of messages.\n *\n * Skips messages whose existing entry already matches `metadata`;\n * those without an `id` (or with a non-string id) are silently\n * ignored — there's nothing to key the metadata on. The store is\n * only updated when at least one entry actually changed, so\n * reapplying the same values snapshot is cheap.\n *\n * @param messages - Messages from the latest values payload.\n * @param metadata - Metadata to attach (currently just\n * `parentCheckpointId`).\n */\n recordMessages(\n messages: Array<{ id?: string }>,\n metadata: MessageMetadata\n ): void {\n const current = this.store.getSnapshot();\n let changed = false;\n const next = new Map(current);\n for (const msg of messages) {\n const id = msg?.id;\n if (typeof id !== \"string\" || id.length === 0) continue;\n const prev = next.get(id);\n if (\n prev != null &&\n prev.parentCheckpointId === metadata.parentCheckpointId\n ) {\n continue;\n }\n next.set(id, { ...prev, ...metadata });\n changed = true;\n }\n if (changed) this.store.setState(() => next);\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA6FA,MAAM,qCAAyC,IAAI,KAAK;;;;;;;;;;;;;;;;;;;AAoBxD,IAAa,yBAAb,MAAoC;;CAElC,QAAiB,IAAIA,cAAAA,YAAgC,mBAAmB;;;;;;;CAQxE,gDAAyC,IAAI,KAG1C;;;;;;CAOH,QAAc;AACZ,QAAA,6BAAmC,OAAO;AAC1C,OAAK,MAAM,eAAe,mBAAmB;;;;;;;;;;;;;;;;;CAkB/C,iBACE,WACA,MACM;AACN,MAAI,QAAQ,QAAQ,OAAO,KAAK,OAAO,SAAU;EACjD,MAAM,WAA+B,EAAE,IAAI,KAAK,IAAI;AACpD,MAAI,OAAO,KAAK,cAAc,SAC3B,UAAoC,YAAY,KAAK;AAExD,QAAA,6BAAmC,IAAIE,kBAAAA,aAAa,UAAU,EAAE,SAAS;;;;;;;;;;;;;CAc3E,kBACE,WACgC;EAChC,MAAM,MAAMA,kBAAAA,aAAa,UAAU;EACnC,MAAM,aAAa,MAAA,6BAAmC,IAAI,IAAI;AAC9D,MAAI,cAAc,KAAM,OAAA,6BAAmC,OAAO,IAAI;AACtE,SAAO;;;;;;;;;;;;;;;CAgBT,eACE,UACA,UACM;EACN,MAAM,UAAU,KAAK,MAAM,aAAa;EACxC,IAAI,UAAU;EACd,MAAM,OAAO,IAAI,IAAI,QAAQ;AAC7B,OAAK,MAAM,OAAO,UAAU;GAC1B,MAAM,KAAK,KAAK;AAChB,OAAI,OAAO,OAAO,YAAY,GAAG,WAAW,EAAG;GAC/C,MAAM,OAAO,KAAK,IAAI,GAAG;AACzB,OACE,QAAQ,QACR,KAAK,uBAAuB,SAAS,mBAErC;AAEF,QAAK,IAAI,IAAI;IAAE,GAAG;IAAM,GAAG;IAAU,CAAC;AACtC,aAAU;;AAEZ,MAAI,QAAS,MAAK,MAAM,eAAe,KAAK"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
//#region src/stream/message-metadata-tracker.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* Metadata tracked per message id. Surfaced to applications via
|
|
4
|
+
* `useMessageMetadata(stream, messageId)`.
|
|
5
|
+
*/
|
|
6
|
+
interface MessageMetadata {
|
|
7
|
+
/**
|
|
8
|
+
* Checkpoint id the message's *parent* was at when this message was
|
|
9
|
+
* observed. Drives fork / edit flows
|
|
10
|
+
* (`submit(input, { forkFrom: { checkpointId } })`).
|
|
11
|
+
*
|
|
12
|
+
* `undefined` when the message was observed without a paired
|
|
13
|
+
* checkpoint envelope (e.g. before checkpoints rolled out, or when
|
|
14
|
+
* the caller stripped them upstream).
|
|
15
|
+
*/
|
|
16
|
+
readonly parentCheckpointId: string | undefined;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Read-only map exposed via {@link MessageMetadataTracker.store}.
|
|
20
|
+
*/
|
|
21
|
+
type MessageMetadataMap = ReadonlyMap<string, MessageMetadata>;
|
|
22
|
+
//#endregion
|
|
23
|
+
export { MessageMetadata, MessageMetadataMap };
|
|
24
|
+
//# sourceMappingURL=message-metadata-tracker.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"message-metadata-tracker.d.cts","names":[],"sources":["../../src/stream/message-metadata-tracker.ts"],"mappings":";;;;;UAqDiB,eAAA;;;;;;;;;;WAUN,kBAAA;AAAA;;;;KAMC,kBAAA,GAAqB,WAAA,SAAoB,eAAA"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
//#region src/stream/message-metadata-tracker.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* Metadata tracked per message id. Surfaced to applications via
|
|
4
|
+
* `useMessageMetadata(stream, messageId)`.
|
|
5
|
+
*/
|
|
6
|
+
interface MessageMetadata {
|
|
7
|
+
/**
|
|
8
|
+
* Checkpoint id the message's *parent* was at when this message was
|
|
9
|
+
* observed. Drives fork / edit flows
|
|
10
|
+
* (`submit(input, { forkFrom: { checkpointId } })`).
|
|
11
|
+
*
|
|
12
|
+
* `undefined` when the message was observed without a paired
|
|
13
|
+
* checkpoint envelope (e.g. before checkpoints rolled out, or when
|
|
14
|
+
* the caller stripped them upstream).
|
|
15
|
+
*/
|
|
16
|
+
readonly parentCheckpointId: string | undefined;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Read-only map exposed via {@link MessageMetadataTracker.store}.
|
|
20
|
+
*/
|
|
21
|
+
type MessageMetadataMap = ReadonlyMap<string, MessageMetadata>;
|
|
22
|
+
//#endregion
|
|
23
|
+
export { MessageMetadata, MessageMetadataMap };
|
|
24
|
+
//# sourceMappingURL=message-metadata-tracker.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"message-metadata-tracker.d.ts","names":[],"sources":["../../src/stream/message-metadata-tracker.ts"],"mappings":";;;;;UAqDiB,eAAA;;;;;;;;;;WAUN,kBAAA;AAAA;;;;KAMC,kBAAA,GAAqB,WAAA,SAAoB,eAAA"}
|