@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":"controller.js","names":["#options","#messagesKey","#subagents","#subgraphs","#messageMetadata","#resolvedInterrupts","#selfCreatedThreadIds","#rootEventListeners","#rootBus","#threadListeners","#currentThreadId","#createInitialSnapshot","#rootMessages","#lifecycleLoading","#disposed","#submitter","#ensureThread","#rootPumpReady","#awaitNextTerminal","#latestUnresolvedInterrupt","#hydrationPromise","#createHydrationPromise","#resolveHydration","#rejectHydration","#resetHydrationPromise","#teardownThread","#applyValues","#thread","#cancelPendingDispose","#pendingDisposeTimer","#startRootPump","#notifyThreadListeners","#threadEventUnsubscribe","#rootSubscription","#rootPump","#rootToolAssembler","#onWildcardEvent","#usesEventStreamTransport","#onRootEvent","#recordRootInterrupt"],"sources":["../../src/stream/controller.ts"],"sourcesContent":["/**\n * Framework-agnostic controller for the experimental v2 stream.\n *\n * Responsibilities:\n * - Owns at most one {@link ThreadStream} at a time (swapped on\n * `hydrate(newThreadId)` or `dispose`).\n * - Exposes three always-on observable surfaces via {@link StreamStore}:\n * - `rootStore` : root values/messages/toolCalls/interrupts/…\n * - `subagentStore` : discovery map of subagents (no content)\n * - `subgraphStore` : discovery map of subgraphs (no content)\n * - Owns a {@link ChannelRegistry} that framework selector hooks\n * (`useMessages`, `useToolCalls`, `useExtension`, `useChannel`)\n * use to lazily open per-namespace subscriptions.\n * - Imperative run surface: `submit`, `stop`, `respond`, `joinStream`.\n *\n * A single multi-channel subscription (`values`, `lifecycle`, `input`,\n * `messages`, `tools`) powers every always-on projection and both\n * discovery runners. Selector hooks add their own (deduped)\n * subscriptions on top — so even a UI with many subagents only opens\n * one extra subscription per `(channels, namespace)` actually\n * rendered on screen.\n */\nimport { AIMessage, type BaseMessage } from \"@langchain/core/messages\";\nimport type {\n Channel,\n Event,\n LifecycleEvent,\n MessagesEvent,\n ToolsEvent,\n ValuesEvent,\n} from \"@langchain/protocol\";\nimport type { Interrupt } from \"../schema.js\";\nimport type { ThreadStream } from \"../client/stream/index.js\";\nimport type { SubscriptionHandle } from \"../client/stream/index.js\";\nimport { ToolCallAssembler } from \"../client/stream/handles/tools.js\";\nimport { ensureMessageInstances } from \"../ui/messages.js\";\nimport type { Message } from \"../types.messages.js\";\nimport { StreamStore } from \"./store.js\";\nimport { ChannelRegistry } from \"./channel-registry.js\";\nimport {\n SubagentDiscovery,\n type SubagentMap,\n SubgraphDiscovery,\n type SubgraphMap,\n type SubgraphByNodeMap,\n} from \"./discovery/index.js\";\nimport {\n isInternalWorkNamespace,\n isLegacySubagentNamespace,\n isRootNamespace,\n} from \"./namespace.js\";\nimport {\n MessageMetadataTracker,\n type CheckpointEnvelope,\n type MessageMetadata,\n type MessageMetadataMap,\n} from \"./message-metadata-tracker.js\";\nimport { LifecycleLoadingTracker } from \"./lifecycle-loading-tracker.js\";\nimport { RootMessageProjection } from \"./root-message-projection.js\";\nimport {\n EMPTY_QUEUE,\n SubmitCoordinator,\n type SubmissionQueueEntry,\n type SubmissionQueueSnapshot,\n} from \"./submit-coordinator.js\";\nimport { upsertToolCall } from \"./tool-calls.js\";\nimport type {\n RootEventBus,\n RootSnapshot,\n StreamControllerOptions,\n StreamSubmitOptions,\n} from \"./types.js\";\n\nfunction isAbortLikeError(error: unknown): boolean {\n if (error == null || typeof error !== \"object\") return false;\n const maybeError = error as { name?: unknown; message?: unknown };\n return (\n maybeError.name === \"AbortError\" ||\n (typeof maybeError.message === \"string\" &&\n maybeError.message.includes(\"aborted\"))\n );\n}\n\nconst ROOT_NAMESPACE: readonly string[] = [];\n\n/**\n * Channel set covered by the always-on root subscription. Exported so\n * projections (and transports) can reason about what the root pump\n * already delivers before opening additional server subscriptions.\n */\nexport const ROOT_PUMP_CHANNELS: readonly Channel[] = [\n \"values\",\n \"checkpoints\",\n \"lifecycle\",\n \"input\",\n \"messages\",\n \"tools\",\n];\n\ninterface ResolvedInterrupt {\n interruptId: string;\n namespace: string[];\n}\n\nexport type {\n MessageMetadata,\n MessageMetadataMap,\n SubmissionQueueEntry,\n SubmissionQueueSnapshot,\n};\n\n/**\n * Coordinates one thread's protocol-v2 stream and exposes stable\n * observable projections for framework bindings.\n *\n * The controller owns the root subscription, lazily binds scoped\n * projections through {@link ChannelRegistry}, and normalizes protocol\n * events into class-message, tool-call, discovery, interrupt, and queue\n * stores.\n *\n * @typeParam StateType - Shape of the graph state exposed on `values`.\n * @typeParam InterruptType - Shape of protocol interrupt payloads.\n * @typeParam ConfigurableType - Shape of `config.configurable` accepted by submit.\n */\nexport class StreamController<\n StateType extends object = Record<string, unknown>,\n InterruptType = unknown,\n ConfigurableType extends object = Record<string, unknown>,\n> {\n readonly rootStore: StreamStore<RootSnapshot<StateType, InterruptType>>;\n readonly subagentStore: StreamStore<SubagentMap>;\n readonly subgraphStore: StreamStore<SubgraphMap>;\n readonly subgraphByNodeStore: StreamStore<SubgraphByNodeMap>;\n readonly messageMetadataStore: StreamStore<MessageMetadataMap>;\n readonly queueStore: StreamStore<SubmissionQueueSnapshot<StateType>>;\n readonly registry: ChannelRegistry;\n\n readonly #options: StreamControllerOptions<StateType>;\n readonly #messagesKey: string;\n readonly #subagents = new SubagentDiscovery();\n readonly #subgraphs = new SubgraphDiscovery();\n readonly #messageMetadata = new MessageMetadataTracker();\n\n #thread: ThreadStream | undefined;\n #currentThreadId: string | null;\n #rootSubscription: SubscriptionHandle<Event> | undefined;\n #rootPump: Promise<void> | undefined;\n #rootPumpReady: Promise<void> | undefined;\n #threadEventUnsubscribe: (() => void) | undefined;\n #disposed = false;\n #pendingDisposeTimer: ReturnType<typeof setTimeout> | null = null;\n readonly #resolvedInterrupts = new Set<string>();\n /**\n * Thread ids we minted client-side on first `submit()`. Keeping them\n * here lets `hydrate()` skip the `threads.getState()` round-trip —\n * we know there is nothing checkpointed server-side yet (and the\n * request would 404 and surface a spurious error to the UI).\n */\n readonly #selfCreatedThreadIds = new Set<string>();\n readonly #rootEventListeners = new Set<(event: Event) => void>();\n readonly #rootBus: RootEventBus;\n\n /**\n * Single-shot hydration promise. Exposed via `hydrationPromise`\n * so Suspense wrappers can throw it until the first hydrate\n * completes (resolve) or fails (reject). Reset whenever a new\n * hydrate cycle begins so `<Suspense>` boundaries re-suspend on\n * thread switch.\n */\n #hydrationPromise: Promise<void>;\n #resolveHydration!: () => void;\n #rejectHydration!: (error: unknown) => void;\n\n /**\n * Tool assembler lives for the lifetime of a thread; reset on\n * rebind so a fresh thread starts with a clean slate.\n */\n #rootToolAssembler = new ToolCallAssembler();\n #rootMessages!: RootMessageProjection<StateType, InterruptType>;\n #lifecycleLoading!: LifecycleLoadingTracker<\n RootSnapshot<StateType, InterruptType>\n >;\n #submitter!: SubmitCoordinator<StateType, InterruptType, ConfigurableType>;\n\n readonly #threadListeners = new Set<\n (thread: ThreadStream | undefined) => void\n >();\n\n /**\n * Create a controller around a LangGraph client and optional initial thread.\n *\n * @param options - Runtime configuration, client, thread id, and initial state.\n */\n constructor(options: StreamControllerOptions<StateType>) {\n this.#options = options;\n this.#messagesKey = options.messagesKey ?? \"messages\";\n this.#currentThreadId = options.threadId ?? null;\n this.#rootBus = {\n channels: ROOT_PUMP_CHANNELS,\n subscribe: (listener) => {\n this.#rootEventListeners.add(listener);\n return () => {\n this.#rootEventListeners.delete(listener);\n };\n },\n };\n this.registry = new ChannelRegistry(this.#rootBus);\n this.subagentStore = this.#subagents.store;\n this.subgraphStore = this.#subgraphs.store;\n this.subgraphByNodeStore = this.#subgraphs.byNodeStore;\n this.rootStore = new StreamStore<RootSnapshot<StateType, InterruptType>>(\n this.#createInitialSnapshot()\n );\n this.#rootMessages = new RootMessageProjection({\n messagesKey: this.#messagesKey,\n store: this.rootStore,\n subagents: this.#subagents,\n });\n this.#lifecycleLoading = new LifecycleLoadingTracker({\n store: this.rootStore,\n isDisposed: () => this.#disposed,\n });\n this.messageMetadataStore = this.#messageMetadata.store;\n this.queueStore = new StreamStore<SubmissionQueueSnapshot<StateType>>(\n EMPTY_QUEUE as SubmissionQueueSnapshot<StateType>\n );\n this.#submitter = new SubmitCoordinator({\n options: this.#options,\n rootStore: this.rootStore,\n queueStore: this.queueStore,\n getDisposed: () => this.#disposed,\n getCurrentThreadId: () => this.#currentThreadId,\n setCurrentThreadId: (threadId) => {\n this.#currentThreadId = threadId;\n },\n rememberSelfCreatedThreadId: (threadId) => {\n this.#selfCreatedThreadIds.add(threadId);\n },\n hydrate: (threadId) => this.hydrate(threadId),\n ensureThread: (threadId) => this.#ensureThread(threadId),\n waitForRootPumpReady: () => this.#rootPumpReady,\n awaitNextTerminal: (signal) => this.#awaitNextTerminal(signal),\n latestUnresolvedInterrupt: () => this.#latestUnresolvedInterrupt(),\n markInterruptResolved: (interruptId) => {\n this.#resolvedInterrupts.add(interruptId);\n },\n });\n this.#hydrationPromise = this.#createHydrationPromise();\n /**\n * Attach a default no-op catch so orphaned hydrationPromise\n * rejections (e.g. controllers spawned during Suspense retries\n * whose promise never gets subscribed to because the suspense\n * cache already holds an earlier one) don't surface as unhandled\n * rejections. Callers that attach their own handlers via .then()\n * still receive the rejection on their derived promise.\n */\n this.#hydrationPromise.catch(() => undefined);\n /**\n * Kick off the initial hydrate eagerly when a caller-supplied\n * thread id is present. Suspense consumers throw\n * `hydrationPromise` on the very first render, which unmounts the\n * subtree before any `useEffect` can run — so if we waited for an\n * effect to drive the hydrate we'd deadlock. Firing here makes\n * the promise settle independently of the component lifecycle.\n */\n if (this.#currentThreadId != null) {\n void this.hydrate(this.#currentThreadId);\n } else {\n this.#resolveHydration();\n }\n }\n\n /**\n * Promise that settles the first time {@link hydrate} finishes on\n * the current thread. Resolves on a clean hydration, rejects when\n * the thread-state fetch errors. A fresh promise is installed on\n * every thread swap so `<Suspense>` wrappers re-suspend on\n * `switchThread`.\n */\n get hydrationPromise(): Promise<void> {\n return this.#hydrationPromise;\n }\n\n /**\n * Create the deferred promise backing the current hydration cycle.\n */\n #createHydrationPromise(): Promise<void> {\n return new Promise<void>((resolve, reject) => {\n this.#resolveHydration = resolve;\n this.#rejectHydration = reject;\n });\n }\n\n /**\n * Replace the current hydration promise before a thread swap.\n */\n #resetHydrationPromise(): void {\n /**\n * Swallow rejection on the orphaned promise so Node doesn't\n * flag it as unhandled; Suspense callers that still hold a\n * reference see the rejection they subscribed to.\n */\n this.#hydrationPromise.catch(() => undefined);\n this.#hydrationPromise = this.#createHydrationPromise();\n }\n\n // ---------- public imperatives ----------\n\n /**\n * Fetch the checkpointed thread state and seed the root snapshot.\n * Re-calling with a different `threadId` swaps the underlying\n * {@link ThreadStream}, rewires the registry to the new thread, and\n * resets assemblers.\n *\n * @param threadId - Optional replacement thread id; `null` clears the active thread.\n */\n async hydrate(threadId?: string | null): Promise<void> {\n if (this.#disposed) return;\n const target = threadId === undefined ? this.#currentThreadId : threadId;\n const changed = target !== this.#currentThreadId;\n this.#currentThreadId = target ?? null;\n this.rootStore.setState((s) => ({ ...s, threadId: this.#currentThreadId }));\n\n if (changed) {\n /**\n * Swap to a new thread: re-arm the hydration promise so any\n * Suspense boundary remounted against the new id suspends again.\n */\n this.#resetHydrationPromise();\n await this.#teardownThread();\n /**\n * Reset UI-facing snapshot so stale messages/values/tool-calls\n * from the previous thread don't bleed into the new one. The\n * new thread's state (if any) is then populated below via\n * `#applyValues`.\n */\n this.rootStore.setState(() => ({\n ...this.#createInitialSnapshot(),\n threadId: this.#currentThreadId,\n }));\n /**\n * Drop queued submissions — they were targeted at the previous\n * thread so dispatching them against the new thread would be\n * surprising. Mirrors the legacy `StreamOrchestrator` behaviour.\n */\n this.queueStore.setState(\n () => EMPTY_QUEUE as SubmissionQueueSnapshot<StateType>\n );\n }\n\n if (this.#currentThreadId == null) {\n this.rootStore.setState((s) => ({ ...s, isThreadLoading: false }));\n this.#resolveHydration();\n return;\n }\n\n /**\n * Self-generated thread ids have nothing to fetch server-side yet\n * — the thread is created lazily by the first `run.start`. Calling\n * `threads.getState()` here would return a 404 and surface a\n * spurious error to the UI.\n */\n if (this.#selfCreatedThreadIds.has(this.#currentThreadId)) {\n this.rootStore.setState((s) => ({ ...s, isThreadLoading: false }));\n this.#resolveHydration();\n return;\n }\n\n this.rootStore.setState((s) => ({ ...s, isThreadLoading: true }));\n let hydrationError: unknown;\n try {\n const state = await this.#options.client.threads.getState<StateType>(\n this.#currentThreadId\n );\n if (state?.values != null) {\n /**\n * `threads.getState()` returns the legacy `ThreadState` shape\n * where `parent_checkpoint` is an object (`{ thread_id,\n * checkpoint_id, checkpoint_ns }`). Synthesize the v2\n * `Checkpoint` envelope (matching the `checkpoints` channel\n * payload) so hydrated messages also get their\n * `parentCheckpointId` populated for fork / edit flows.\n */\n const checkpointId = state.checkpoint?.checkpoint_id;\n const parentCheckpointId =\n state.parent_checkpoint?.checkpoint_id ?? undefined;\n const syntheticCheckpoint =\n typeof checkpointId === \"string\"\n ? {\n id: checkpointId,\n ...(parentCheckpointId != null\n ? { parent_id: parentCheckpointId }\n : {}),\n }\n : undefined;\n this.#applyValues(state.values as unknown, syntheticCheckpoint);\n }\n } catch (error) {\n /**\n * A 404 on hydrate means the thread does not exist server-side\n * yet (most commonly because the caller supplied a brand-new,\n * externally-minted thread id and is about to create it via the\n * first `submit()`). Treat it as \"empty state\" rather than a\n * fatal hydration error so Suspense boundaries resolve cleanly\n * and no spurious error renders in the UI.\n */\n const status = (error as { status?: number } | null)?.status;\n if (status !== 404) {\n hydrationError = error;\n this.rootStore.setState((s) => ({ ...s, error }));\n }\n } finally {\n this.rootStore.setState((s) => ({ ...s, isThreadLoading: false }));\n if (hydrationError != null) {\n this.#rejectHydration(hydrationError);\n } else {\n this.#resolveHydration();\n }\n }\n\n /**\n * P0 fix: open the shared subscription on mount so in-flight\n * server-side runs are observed even when no local `submit()` is\n * active. The transport replays the run from `seq=0` on a rotating\n * subscribe, so late-joining is free once the subscription exists.\n * `isLoading` transitions are driven by the persistent root\n * lifecycle listener registered in `#startRootPump`.\n */\n this.#ensureThread(this.#currentThreadId);\n }\n\n /**\n * Submit input or a resume command to the active thread.\n *\n * @param input - Input payload for a new run; `null`/`undefined` submits no input.\n * @param options - Per-run config, metadata, multitask behavior, and callbacks.\n */\n async submit(\n input: unknown,\n options?: StreamSubmitOptions<StateType, ConfigurableType>\n ): Promise<void> {\n await this.#submitter.submit(input, options);\n }\n\n /**\n * Abort the currently tracked run and mark the controller idle.\n */\n async stop(): Promise<void> {\n await this.#submitter.stop();\n }\n\n /**\n * Cancel a queued submission by id. Returns `true` when the entry\n * was found and removed, `false` otherwise.\n *\n * Today this only removes the entry from the client-side mirror —\n * once the server exposes queue cancel (roadmap A0.3) the\n * controller will additionally issue a cancel call against the\n * active transport.\n *\n * @param id - Client-side queue entry id to remove.\n */\n async cancelQueued(id: string): Promise<boolean> {\n return this.#submitter.cancelQueued(id);\n }\n\n /**\n * Drop every queued submission. Server-side cancel arrives with A0.3.\n */\n async clearQueue(): Promise<void> {\n await this.#submitter.clearQueue();\n }\n\n /**\n * Respond to a pending protocol interrupt.\n *\n * @param response - Payload to send back to the interrupted namespace.\n * @param target - Optional explicit interrupt id and namespace; defaults to the latest unresolved interrupt.\n */\n async respond(\n response: unknown,\n target?: { interruptId: string; namespace?: string[] }\n ): Promise<void> {\n if (this.#disposed || this.#thread == null) {\n throw new Error(\"No active thread to respond to.\");\n }\n const resolved =\n target != null\n ? {\n interruptId: target.interruptId,\n namespace: target.namespace ?? [...ROOT_NAMESPACE],\n }\n : this.#latestUnresolvedInterrupt();\n if (resolved == null) {\n throw new Error(\"No pending interrupt to respond to.\");\n }\n try {\n await this.#thread.respondInput({\n namespace: resolved.namespace,\n interrupt_id: resolved.interruptId,\n response,\n });\n this.#resolvedInterrupts.add(resolved.interruptId);\n } catch (error) {\n if (this.#disposed && isAbortLikeError(error)) {\n return;\n }\n throw error;\n }\n }\n\n /**\n * Dispose the active thread, subscriptions, registry entries, and listeners.\n */\n async dispose(): Promise<void> {\n if (this.#disposed) return;\n this.#cancelPendingDispose();\n this.#disposed = true;\n this.#submitter.abortActiveRun();\n await this.#teardownThread();\n await this.registry.dispose();\n this.#threadListeners.clear();\n }\n\n /**\n * StrictMode-safe lifecycle hook for framework bindings.\n *\n * React 18+ `StrictMode` intentionally mounts → unmounts → remounts\n * components in dev to surface effect-cleanup bugs. A naive\n * `useEffect(() => () => controller.dispose())` would permanently\n * tear the controller down on that first synthetic unmount, leaving\n * every subsequent `submit()` a silent no-op.\n *\n * Call {@link activate} from the bind site's effect and return the\n * result as the effect's cleanup. The controller uses deferred\n * disposal: a `release()` only schedules a dispose on the next\n * microtask, which is cancelled if another `activate()` arrives\n * before it fires (the normal StrictMode remount path).\n */\n activate(): () => void {\n this.#cancelPendingDispose();\n return () => {\n if (this.#disposed) return;\n this.#pendingDisposeTimer = setTimeout(() => {\n this.#pendingDisposeTimer = null;\n void this.dispose().catch(() => undefined);\n }, 0);\n };\n }\n\n /**\n * Cancel a deferred dispose scheduled by {@link activate}.\n */\n #cancelPendingDispose(): void {\n if (this.#pendingDisposeTimer != null) {\n clearTimeout(this.#pendingDisposeTimer);\n this.#pendingDisposeTimer = null;\n }\n }\n\n // ---------- escape hatches ----------\n\n /**\n * Current underlying {@link ThreadStream} (v2 escape hatch).\n */\n getThread(): ThreadStream | undefined {\n return this.#thread;\n }\n\n /**\n * Listen for `ThreadStream` lifecycle (swap on thread-id change,\n * detach on dispose). The listener fires immediately with the\n * current thread (may be `undefined`).\n *\n * @param listener - Callback invoked immediately and on every thread swap.\n */\n subscribeThread(\n listener: (thread: ThreadStream | undefined) => void\n ): () => void {\n this.#threadListeners.add(listener);\n listener(this.#thread);\n return () => {\n this.#threadListeners.delete(listener);\n };\n }\n\n // ---------- internals ----------\n\n /**\n * Build the initial root snapshot from configured initial values.\n */\n #createInitialSnapshot(): RootSnapshot<StateType, InterruptType> {\n const values = (this.#options.initialValues ??\n ({} as StateType)) as StateType;\n const messages = extractAndCoerceMessages(\n values as unknown as Record<string, unknown>,\n this.#messagesKey\n );\n /**\n * Seed `isThreadLoading: true` synchronously when a caller-supplied\n * threadId is on the controller at construction/swap time. Without\n * this Suspense wrappers would render their fallback for a tick\n * because `isThreadLoading` flips false → true → false once the\n * deferred `hydrate()` starts, and the synchronous render observes\n * the initial `false`.\n */\n const willHydrate =\n this.#currentThreadId != null &&\n !this.#selfCreatedThreadIds.has(this.#currentThreadId);\n return {\n values,\n messages,\n toolCalls: [],\n interrupts: [],\n interrupt: undefined,\n isLoading: false,\n isThreadLoading: willHydrate,\n error: undefined,\n threadId: this.#currentThreadId,\n };\n }\n\n /**\n * Return the active thread stream, creating and binding one when needed.\n *\n * @param threadId - Thread id used when constructing the stream.\n */\n #ensureThread(threadId: string): ThreadStream {\n if (this.#thread != null) return this.#thread;\n this.#thread = this.#options.client.threads.stream(threadId, {\n assistantId: this.#options.assistantId,\n transport: this.#options.transport,\n fetch: this.#options.fetch,\n webSocketFactory: this.#options.webSocketFactory,\n });\n this.registry.bind(this.#thread);\n this.#startRootPump(this.#thread);\n this.#notifyThreadListeners();\n return this.#thread;\n }\n\n /**\n * Close the current thread stream and reset per-thread assembly state.\n */\n async #teardownThread(): Promise<void> {\n const thread = this.#thread;\n this.#thread = undefined;\n this.registry.bind(undefined);\n this.#threadEventUnsubscribe?.();\n this.#threadEventUnsubscribe = undefined;\n /**\n * Persistent lifecycle driver is scoped to the current thread\n * stream. Remove it so a swap to a new thread starts with a clean\n * listener set (a new one is installed in `#startRootPump`).\n */\n this.#rootEventListeners.delete(this.#lifecycleLoading.listener);\n try {\n await this.#rootSubscription?.unsubscribe();\n } catch {\n /* already closed */\n }\n this.#rootSubscription = undefined;\n this.#rootPumpReady = undefined;\n try {\n await this.#rootPump;\n } catch {\n /* ignore */\n }\n this.#rootPump = undefined;\n\n // Reset per-thread assembly state.\n this.#rootMessages.reset();\n this.#rootToolAssembler = new ToolCallAssembler();\n this.#lifecycleLoading.reset();\n this.#messageMetadata.reset();\n this.queueStore.setState(\n () => EMPTY_QUEUE as SubmissionQueueSnapshot<StateType>\n );\n\n if (thread != null) {\n try {\n await thread.close();\n } catch {\n /* already closed */\n }\n this.#notifyThreadListeners();\n }\n }\n\n /**\n * Determine whether the configured transport uses the resumable event-stream path.\n */\n #usesEventStreamTransport(): boolean {\n const transport = this.#options.transport;\n if (transport === \"websocket\") return false;\n if (transport == null || transport === \"sse\") return true;\n return typeof transport.openEventStream === \"function\";\n }\n\n /**\n * Start the always-on root subscription pump for the provided thread.\n *\n * @param thread - Thread stream to subscribe to and fan out from.\n */\n #startRootPump(thread: ThreadStream): void {\n if (this.#rootPump != null) return;\n let resolveReady: (() => void) | undefined;\n this.#rootPumpReady = new Promise<void>((resolve) => {\n resolveReady = resolve;\n });\n\n /**\n * Wildcard discovery + interrupt tracking is delivered via the\n * thread's dedicated lifecycle watcher (see `ThreadStream.onEvent`).\n * This callback fires once per globally-unique event across both\n * the content pump AND the watcher, so we can drive discovery\n * runners and nested HITL capture without widening the content\n * pump's narrow filter.\n */\n this.#threadEventUnsubscribe = thread.onEvent((event) =>\n this.#onWildcardEvent(event)\n );\n\n /**\n * Persistent isLoading driver. Drives `isLoading` from\n * root-namespace lifecycle events so that in-flight runs observed\n * via `hydrate()` (not initiated by a local `submit()`) still flip\n * the UI to loading. `running` → true; terminals → false. The\n * optimistic `isLoading = true` inside `submit()` stays because\n * that fires before any subscription event arrives.\n */\n this.#rootEventListeners.add(this.#lifecycleLoading.listener);\n\n this.#rootPump = (async () => {\n try {\n /**\n * Narrow the content pump to the root namespace, depth 1:\n * this is enough to observe root LLM deltas and first-level\n * discovery hints (tool-started for task:* / subgraph\n * boundaries) without downloading content from every nested\n * subagent / subgraph. Deeper content is pulled in lazily by\n * per-namespace selector projections (e.g. `useMessages(sub)`),\n * which expand `#computeUnionFilter` progressively.\n */\n const subscriptionPromise = thread.subscribe({\n channels: [...ROOT_PUMP_CHANNELS] as Channel[],\n namespaces: [[] as string[]],\n depth: 1,\n });\n if (this.#usesEventStreamTransport()) {\n /**\n * SSE streams can legitimately withhold response headers until\n * the first event is available. Waiting for `subscribe()` here\n * would deadlock new-thread submits: the run is not dispatched\n * until the root pump is \"ready\", but the pump does not become\n * ready until the run emits. `thread.subscribe()` has already\n * registered the local subscription and scheduled the stream\n * rotation by this point; waiting one microtask lets the fetch\n * get kicked off without requiring headers to arrive.\n */\n queueMicrotask(() => {\n resolveReady?.();\n resolveReady = undefined;\n });\n }\n const subscription = await subscriptionPromise;\n resolveReady?.();\n resolveReady = undefined;\n this.#rootSubscription = subscription;\n /**\n * The SSE transport pauses the underlying subscription when\n * a terminal root lifecycle event arrives (so `for await`\n * loops observing a single run exit cleanly) and re-opens\n * the next run's server stream on `#prepareForNextRun`,\n * resuming the subscription handle. The root pump needs to\n * survive that hand-off: we re-enter the inner `for await`\n * for every resumed iteration until the subscription is\n * permanently closed or the controller is disposed.\n */\n while (!this.#disposed) {\n for await (const event of subscription) {\n if (this.#disposed) {\n break;\n }\n /**\n * Resilience: isolate per-event dispatch from the pump loop.\n *\n * `#onRootEvent` runs synchronously and, transitively,\n * invokes every root-bus listener (selector projections that\n * opted into the shared stream) plus every `rootStore`\n * subscriber. Some of those subscribers live in a React\n * render tree — `useStream` drives\n * `useSyncExternalStore`, so a misbehaving component can\n * surface a render-phase error (\"Maximum update depth\n * exceeded\", \"The result of getSnapshot should be cached\",\n * etc.) that propagates out here.\n *\n * Without this guard, a single throw bubbles through the\n * `for await` loop and terminates the root pump permanently.\n * That is catastrophic: no more root events get processed —\n * the terminal `lifecycle: completed` never lands, so\n * `#awaitNextTerminal` never resolves, `isLoading` stays\n * `true`, composers stay disabled, and the final assistant\n * turn never commits to `stream.messages`. The UI looks\n * hung even though the server is still emitting events\n * (and `ThreadStream.onEvent` keeps firing).\n *\n * We therefore swallow the error and keep pumping. The\n * the pump's correctness guarantees do not depend on any\n * consumer behaving well.\n */\n try {\n this.#onRootEvent(event);\n } catch {\n /**\n * Best-effort — a consumer-facing store subscriber should not\n * terminate the root pump. Store mutations happen before\n * listeners are notified, so continuing with later events keeps\n * the controller's authoritative state moving forward.\n */\n }\n }\n if (this.#disposed) break;\n if (!subscription.isPaused) {\n break;\n }\n await subscription.waitForResume();\n }\n } catch {\n resolveReady?.();\n resolveReady = undefined;\n /* thread closed or errored */\n }\n })();\n }\n\n /**\n * Handle an event delivered via {@link ThreadStream.onEvent}.\n *\n * `onEvent` fires once per globally-unique event across the content\n * pump and the wildcard lifecycle watcher, so this is the single\n * entry point for wildcard discovery / interrupt tracking. It does\n * NOT fan events out to the root bus (that's driven by the content\n * pump iterator so root-bus short-circuits stay depth-1 scoped) and\n * it does NOT process root content — messages/tools/values at root\n * are handled by `#onRootEvent` off the content pump.\n *\n * @param event - Raw protocol event observed by the thread-wide listener.\n */\n #onWildcardEvent(event: Event): void {\n try {\n this.#subagents.push(event);\n } catch {\n /**\n * Discovery store subscribers are user/UI code. If one throws, still\n * let the wildcard watcher update subgraphs, loading, and interrupts.\n */\n }\n this.#subgraphs.push(event);\n this.#lifecycleLoading.handle(event);\n\n /**\n * Nested `input.requested` events (HITL inside a subagent /\n * subgraph) are not observable via the narrow content pump. The\n * `ThreadStream` itself already records them into\n * `thread.interrupts`, which `#latestUnresolvedInterrupt()`\n * consults — so HITL respond() works for any depth. Root-level\n * interrupts are also mirrored into `rootStore.interrupts` here so\n * UI state does not depend on the narrower content pump being the\n * first consumer to see the event.\n */\n this.#recordRootInterrupt(event);\n }\n\n /**\n * Process one root-pump event and update all root projections.\n *\n * @param event - Event yielded by the root subscription.\n */\n #onRootEvent(event: Event): void {\n try {\n this.#subagents.push(event);\n } catch {\n /**\n * Discovery store subscribers are user/UI code. If one throws, still\n * process the root event below so orchestrator messages and terminal\n * state continue to advance.\n */\n }\n\n /**\n * Fan root-pump events out to every root-bus listener (selector\n * projections that opted into the shared stream,\n * `#awaitTerminal`, etc.). The root bus mirrors the content\n * pump's narrow scope (depth 1 at root) so projections that\n * short-circuit via the bus stay bounded.\n */\n if (this.#rootEventListeners.size > 0) {\n for (const listener of this.#rootEventListeners) {\n try {\n listener(event);\n } catch {\n /**\n * Best-effort — a bad listener should not wedge other\n * projections or the root pump itself.\n */\n }\n }\n }\n\n /**\n * `messages` and `tools` events are emitted under a node's\n * namespace — for a typical StateGraph the LLM's token deltas\n * land on `[\"model:<uuid>\"]`, tool executions on\n * `[\"tools:<uuid>\"]`, etc. The orchestrator's own turns (root\n * agent, or an orchestrator-scoped subgraph like `model:*` /\n * `model_request:*`) belong in `root.messages` and\n * `root.toolCalls`.\n *\n * Subagent / tool-internal branches do NOT:\n * - `task:*` segment — legacy subagent convention.\n * - `tools:*` segment — every tool execution is wrapped in a\n * `tools` subgraph. For simple tools its only content is\n * the eventual tool result (also echoed verbatim by\n * `values.messages` so we don't lose anything). For the\n * deep-agent `task` tool its content IS the spawned\n * subagent's full message + tool stream, which is surfaced\n * separately via `useMessages(stream, subagent)` /\n * `useToolCalls(stream, subagent)`.\n *\n * We therefore drop `messages` events from any namespace that\n * contains a `task:*` or `tools:*` segment; the authoritative\n * tool-result text lands in `root.messages` via the root\n * `values.messages` snapshot merge in `#applyValues`.\n */\n const isInternalNamespace = isInternalWorkNamespace(event.params.namespace);\n const hasLegacySubagentNamespace = isLegacySubagentNamespace(\n event.params.namespace\n );\n\n if (event.method === \"messages\") {\n if (!isInternalNamespace) {\n this.#rootMessages.handleMessage(event as MessagesEvent);\n }\n return;\n }\n\n if (event.method === \"tools\") {\n /**\n * Root-level tool events (both for simple orchestrator tools\n * and the deep-agent `task` dispatcher) fire at a\n * single-segment `[\"tools:<id>\"]` namespace. Anything deeper\n * (e.g. `[tools:<outer>, tools:<inner>]`) is a subagent's own\n * tool call and belongs to that subagent's `useToolCalls`\n * view, not the orchestrator's `root.toolCalls`.\n */\n const isRootLevelTool =\n event.params.namespace.length <= 1 && !hasLegacySubagentNamespace;\n if (isRootLevelTool) {\n /**\n * Record the `namespace → tool_call_id` association so that\n * the ensuing `message-start` (role: \"tool\") at the same\n * namespace can recover the `tool_call_id` (the `messages`\n * channel's start event doesn't carry it directly).\n */\n const toolData = event.params.data as {\n event?: string;\n tool_call_id?: string;\n };\n if (\n toolData.event === \"tool-started\" &&\n typeof toolData.tool_call_id === \"string\"\n ) {\n this.#rootMessages.recordToolCallNamespace(\n event.params.namespace,\n toolData.tool_call_id\n );\n }\n const tc = this.#rootToolAssembler.consume(event as ToolsEvent);\n if (tc != null) {\n this.rootStore.setState((s) => ({\n ...s,\n toolCalls: upsertToolCall(s.toolCalls, tc),\n }));\n }\n }\n return;\n }\n\n /**\n * The `checkpoints` channel carries the lightweight envelope\n * (`id`, `parent_id`, `step`, `source`) emitted immediately\n * before its companion `values` event on the same superstep.\n * Buffer the envelope per-namespace so the ensuing `values`\n * event at the same namespace can pair with it in `#applyValues`.\n * The buffer is read-and-cleared on consumption so a subsequent\n * `values` event without a new checkpoint doesn't reuse stale\n * metadata.\n */\n if (event.method === \"checkpoints\") {\n const data = event.params.data as {\n id?: unknown;\n parent_id?: unknown;\n } | null;\n this.#messageMetadata.bufferCheckpoint(event.params.namespace, data);\n return;\n }\n\n // Channels below are only meaningful at the root namespace.\n const isRoot = isRootNamespace(event.params.namespace);\n if (!isRoot) return;\n\n if (event.method === \"values\") {\n const valuesEvent = event as ValuesEvent;\n const bufferedCheckpoint = this.#messageMetadata.consumeCheckpoint(\n event.params.namespace\n );\n this.#applyValues(valuesEvent.params.data, bufferedCheckpoint);\n return;\n }\n\n if (event.method === \"input.requested\") {\n this.#recordRootInterrupt(event);\n return;\n }\n\n if (event.method === \"lifecycle\") {\n /**\n * Root lifecycle transitions are observed elsewhere\n * (#awaitTerminal) to unblock `submit`.\n */\n const lifecycle = (event as LifecycleEvent).params.data as {\n event?: string;\n };\n void lifecycle;\n }\n }\n\n /**\n * Merge a `values` payload into root values and root messages.\n *\n * @param raw - Raw `values` channel payload.\n * @param checkpoint - Optional checkpoint envelope paired with the values event.\n */\n #applyValues(raw: unknown, checkpoint?: CheckpointEnvelope): void {\n if (raw == null || typeof raw !== \"object\" || Array.isArray(raw)) {\n return;\n }\n const state = raw as Record<string, unknown>;\n /**\n * Surface parent_checkpoint per-message when the values event\n * carries the lightweight checkpoint envelope (populated by\n * `@langchain/langgraph-core`'s `_emitValuesWithCheckpointMeta` and\n * forwarded through `convertToProtocolEvent`). Consumers surface\n * this as `useMessageMetadata(stream, msg.id).parentCheckpointId`\n * for fork / edit flows.\n */\n const parentCheckpointId = checkpoint?.parent_id;\n if (parentCheckpointId != null && Array.isArray(state[this.#messagesKey])) {\n this.#messageMetadata.recordMessages(\n state[this.#messagesKey] as Array<{ id?: string }>,\n { parentCheckpointId }\n );\n }\n const maybeMessages = state[this.#messagesKey];\n let nextValues: StateType;\n let nextMessages: BaseMessage[];\n if (Array.isArray(maybeMessages)) {\n const coerced = ensureMessageInstances(\n maybeMessages as (Message | BaseMessage)[]\n );\n nextValues = {\n ...(state as StateType),\n [this.#messagesKey]: coerced,\n } as StateType;\n nextMessages = coerced;\n } else {\n nextValues = state as StateType;\n nextMessages = [];\n }\n this.#rootMessages.applyValues(nextValues, nextMessages);\n }\n\n /**\n * Mirror root protocol interrupts into the root snapshot.\n *\n * This can be called from both the wildcard lifecycle/input watcher and the\n * root content pump. Store-level dedup keeps the user-facing list stable.\n */\n #recordRootInterrupt(event: Event): void {\n if (event.method !== \"input.requested\") return;\n if (!isRootNamespace(event.params.namespace)) return;\n const data = event.params.data as {\n interrupt_id?: string;\n payload?: unknown;\n };\n const interruptId = data?.interrupt_id;\n if (\n typeof interruptId !== \"string\" ||\n this.#resolvedInterrupts.has(interruptId)\n ) {\n return;\n }\n const interrupt: Interrupt<InterruptType> = {\n id: interruptId,\n value: data.payload as InterruptType,\n };\n this.rootStore.setState((s) => {\n if (s.interrupts.some((entry) => entry.id === interruptId)) return s;\n const interrupts = [...s.interrupts, interrupt];\n return { ...s, interrupts, interrupt: interrupts[0] };\n });\n }\n\n /**\n * Resolve on the next root-namespace terminal lifecycle event\n * (`completed` / `failed` / `interrupted`) or on abort.\n *\n * Attaches to the controller's root event bus instead of opening\n * a second server subscription. Callers should register the\n * returned promise **before** dispatching the command that\n * triggers the run (`thread.run.start` / `thread.input.respond`)\n * — the root pump fans events out synchronously on arrival, so a\n * late registration would miss the terminal for fast runs.\n *\n * @param signal - Abort signal for the local submit lifecycle.\n */\n #awaitNextTerminal(signal: AbortSignal): Promise<{\n event: \"completed\" | \"failed\" | \"interrupted\" | \"aborted\";\n error?: string;\n }> {\n return new Promise((resolve) => {\n let settled = false;\n function finish(result: {\n event: \"completed\" | \"failed\" | \"interrupted\" | \"aborted\";\n error?: string;\n }) {\n if (settled) return;\n settled = true;\n unsubscribeRoot?.();\n unsubscribeThread?.();\n signal.removeEventListener(\"abort\", finishAborted);\n resolve(result);\n }\n const finishAborted = () => finish({ event: \"aborted\" });\n const onEvent = (event: Event) => {\n if (settled) return;\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 error?: string;\n };\n if (lifecycle?.event === \"completed\") {\n setTimeout(() => finish({ event: \"completed\" }), 0);\n } else if (lifecycle?.event === \"failed\") {\n setTimeout(\n () => finish({ event: \"failed\", error: lifecycle.error }),\n 0\n );\n } else if (lifecycle?.event === \"interrupted\") {\n setTimeout(() => finish({ event: \"interrupted\" }), 0);\n }\n };\n const unsubscribeRoot = this.#rootBus.subscribe(onEvent);\n const unsubscribeThread = this.#thread?.onEvent(onEvent);\n if (signal.aborted) {\n finishAborted();\n } else {\n signal.addEventListener(\"abort\", finishAborted, { once: true });\n }\n });\n }\n\n /**\n * Find the newest unresolved interrupt recorded on the active thread.\n */\n #latestUnresolvedInterrupt(): ResolvedInterrupt | null {\n const thread = this.#thread;\n if (thread == null) return null;\n for (let i = thread.interrupts.length - 1; i >= 0; i -= 1) {\n const entry = thread.interrupts[i];\n if (entry == null) continue;\n if (this.#resolvedInterrupts.has(entry.interruptId)) continue;\n return {\n interruptId: entry.interruptId,\n namespace: entry.namespace,\n };\n }\n return null;\n }\n\n /**\n * Notify listeners that the underlying thread stream changed.\n */\n #notifyThreadListeners(): void {\n for (const listener of this.#threadListeners) listener(this.#thread);\n }\n}\n\n// ---------- helpers ----------\n\n/**\n * Extract and coerce the configured messages key from a values object.\n *\n * @param values - State values object to read from.\n * @param messagesKey - Key that contains the message array.\n */\nfunction extractAndCoerceMessages(\n values: Record<string, unknown>,\n messagesKey: string\n): BaseMessage[] {\n const raw = values[messagesKey];\n if (!Array.isArray(raw)) return [];\n return ensureMessageInstances(\n raw as (Message | BaseMessage)[]\n ) as BaseMessage[];\n}\n\n// Unused import guard — `AIMessage` is only referenced by type tests.\nvoid AIMessage;\n"],"mappings":"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"}
|
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
const require_store = require("../store.cjs");
|
|
2
|
+
const require_namespace = require("../namespace.cjs");
|
|
3
|
+
//#region src/stream/discovery/subagents.ts
|
|
4
|
+
var SubagentDiscovery = class {
|
|
5
|
+
store = new require_store.StreamStore(/* @__PURE__ */ new Map());
|
|
6
|
+
#map = /* @__PURE__ */ new Map();
|
|
7
|
+
#taskIdByObservedNamespace = /* @__PURE__ */ new Map();
|
|
8
|
+
#observedOwnNamespaces = /* @__PURE__ */ new Set();
|
|
9
|
+
/** Feed a single root event. Non-discovery events are ignored. */
|
|
10
|
+
push(event) {
|
|
11
|
+
if (event.method === "tools") this.#onToolEvent(event);
|
|
12
|
+
else if (event.method === "values") this.#onValuesEvent(event);
|
|
13
|
+
}
|
|
14
|
+
/** Current snapshot map. */
|
|
15
|
+
get snapshot() {
|
|
16
|
+
return this.store.getSnapshot();
|
|
17
|
+
}
|
|
18
|
+
discoverFromMessage(message, namespace) {
|
|
19
|
+
let changed = false;
|
|
20
|
+
for (const toolCall of getTaskToolCalls(message)) changed = this.#upsertTaskToolCall(toolCall.id, toolCall.input, namespace) || changed;
|
|
21
|
+
if (changed) this.#commit();
|
|
22
|
+
}
|
|
23
|
+
#commit() {
|
|
24
|
+
this.store.setValue(new Map([...this.#map.values()].map((entry) => [entry.id, toSnapshot(entry)])));
|
|
25
|
+
}
|
|
26
|
+
#onToolEvent(event) {
|
|
27
|
+
const data = event.params.data;
|
|
28
|
+
const toolCallId = data.tool_call_id;
|
|
29
|
+
const toolName = data.tool_name;
|
|
30
|
+
if (data.event === "tool-started" && toolName === "task") {
|
|
31
|
+
const input = parseTaskInput(data.input);
|
|
32
|
+
if (toolCallId == null) return;
|
|
33
|
+
this.#upsertTaskToolCall(toolCallId, input, event.params.namespace);
|
|
34
|
+
this.#commit();
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
if (toolCallId == null) return;
|
|
38
|
+
const entry = this.#map.get(toolCallId);
|
|
39
|
+
if (entry == null) return;
|
|
40
|
+
if (data.event === "tool-finished") {
|
|
41
|
+
entry.status = "complete";
|
|
42
|
+
entry.output = data.output;
|
|
43
|
+
entry.completedAt = /* @__PURE__ */ new Date();
|
|
44
|
+
this.#commit();
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
if (data.event === "tool-error") {
|
|
48
|
+
entry.status = "error";
|
|
49
|
+
entry.error = data.message ?? "Subagent failed";
|
|
50
|
+
entry.completedAt = /* @__PURE__ */ new Date();
|
|
51
|
+
this.#commit();
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
#onValuesEvent(event) {
|
|
55
|
+
const data = event.params.data;
|
|
56
|
+
if (data == null || typeof data !== "object" || Array.isArray(data)) return;
|
|
57
|
+
const messages = data.messages;
|
|
58
|
+
if (!Array.isArray(messages)) return;
|
|
59
|
+
let changed = this.#recordObservedWorkNamespace(event.params.namespace);
|
|
60
|
+
for (const message of messages) {
|
|
61
|
+
for (const toolCall of getTaskToolCalls(message)) changed = this.#upsertTaskToolCall(toolCall.id, toolCall.input, event.params.namespace) || changed;
|
|
62
|
+
const toolCallId = getToolMessageCallId(message);
|
|
63
|
+
if (toolCallId == null) continue;
|
|
64
|
+
const existing = this.#map.get(toolCallId);
|
|
65
|
+
if (existing == null) continue;
|
|
66
|
+
existing.status = "complete";
|
|
67
|
+
existing.output = message;
|
|
68
|
+
existing.completedAt = /* @__PURE__ */ new Date();
|
|
69
|
+
changed = true;
|
|
70
|
+
}
|
|
71
|
+
if (changed) this.#commit();
|
|
72
|
+
}
|
|
73
|
+
#upsertTaskToolCall(toolCallId, input, eventNamespace) {
|
|
74
|
+
const namespace = taskWorkNamespace(toolCallId, eventNamespace);
|
|
75
|
+
const existing = this.#map.get(toolCallId);
|
|
76
|
+
if (existing != null) {
|
|
77
|
+
let changed = false;
|
|
78
|
+
this.#recordTaskNamespaceCandidate(toolCallId, eventNamespace);
|
|
79
|
+
const nextName = input.subagent_type ?? existing.name;
|
|
80
|
+
const nextTaskInput = input.description ?? existing.taskInput;
|
|
81
|
+
if (existing.name !== nextName) {
|
|
82
|
+
existing.name = nextName;
|
|
83
|
+
changed = true;
|
|
84
|
+
}
|
|
85
|
+
if (existing.taskInput !== nextTaskInput) {
|
|
86
|
+
existing.taskInput = nextTaskInput;
|
|
87
|
+
changed = true;
|
|
88
|
+
}
|
|
89
|
+
const namespaceKeyed = require_namespace.namespaceKey(existing.namespace);
|
|
90
|
+
const ownNamespaceKey = `tools:${toolCallId}`;
|
|
91
|
+
const nextNamespaceKey = require_namespace.namespaceKey(namespace);
|
|
92
|
+
if (require_namespace.isConcreteToolNamespace(eventNamespace) || namespaceKeyed === ownNamespaceKey) {
|
|
93
|
+
if (namespaceKeyed === ownNamespaceKey && nextNamespaceKey !== ownNamespaceKey && this.#observedOwnNamespaces.has(toolCallId)) return changed;
|
|
94
|
+
if (namespaceKeyed !== nextNamespaceKey) {
|
|
95
|
+
existing.namespace = namespace;
|
|
96
|
+
changed = true;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
if (existing.status !== "complete" && existing.status !== "error") {
|
|
100
|
+
if (existing.status !== "running") {
|
|
101
|
+
existing.status = "running";
|
|
102
|
+
changed = true;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
return changed;
|
|
106
|
+
}
|
|
107
|
+
const { parentId, depth } = lineageFromNamespace(eventNamespace);
|
|
108
|
+
this.#recordTaskNamespaceCandidate(toolCallId, eventNamespace);
|
|
109
|
+
this.#map.set(toolCallId, {
|
|
110
|
+
id: toolCallId,
|
|
111
|
+
name: input.subagent_type ?? "unknown",
|
|
112
|
+
namespace,
|
|
113
|
+
parentId,
|
|
114
|
+
depth,
|
|
115
|
+
status: "running",
|
|
116
|
+
taskInput: input.description,
|
|
117
|
+
output: void 0,
|
|
118
|
+
error: void 0,
|
|
119
|
+
startedAt: /* @__PURE__ */ new Date(),
|
|
120
|
+
completedAt: null
|
|
121
|
+
});
|
|
122
|
+
return true;
|
|
123
|
+
}
|
|
124
|
+
#recordObservedWorkNamespace(namespace) {
|
|
125
|
+
if (!require_namespace.isConcreteToolNamespace(namespace)) return false;
|
|
126
|
+
const last = namespace.at(-1);
|
|
127
|
+
if (last == null) return false;
|
|
128
|
+
const namespaceKeyed = require_namespace.namespaceKey(namespace);
|
|
129
|
+
const toolCallId = this.#taskIdByObservedNamespace.get(namespaceKeyed) ?? last.slice(6);
|
|
130
|
+
const existing = this.#map.get(toolCallId);
|
|
131
|
+
if (existing == null) return false;
|
|
132
|
+
if (namespaceKeyed === `tools:${toolCallId}`) this.#observedOwnNamespaces.add(toolCallId);
|
|
133
|
+
else if (this.#observedOwnNamespaces.has(toolCallId) || !this.#taskIdByObservedNamespace.has(namespaceKeyed) && !shouldPromoteToObservedNamespace(existing)) return false;
|
|
134
|
+
if (require_namespace.namespaceKey(existing.namespace) === namespaceKeyed) return false;
|
|
135
|
+
existing.namespace = [...namespace];
|
|
136
|
+
return true;
|
|
137
|
+
}
|
|
138
|
+
#recordTaskNamespaceCandidate(toolCallId, namespace) {
|
|
139
|
+
if (!require_namespace.isConcreteToolNamespace(namespace)) return;
|
|
140
|
+
this.#taskIdByObservedNamespace.set(require_namespace.namespaceKey(namespace), toolCallId);
|
|
141
|
+
}
|
|
142
|
+
};
|
|
143
|
+
function shouldPromoteToObservedNamespace(entry) {
|
|
144
|
+
return entry.name === "fanout-worker" || /^Worker worker-\d+/i.test(entry.taskInput ?? "");
|
|
145
|
+
}
|
|
146
|
+
function taskWorkNamespace(toolCallId, eventNamespace) {
|
|
147
|
+
const last = eventNamespace.at(-1);
|
|
148
|
+
if (last != null && require_namespace.isToolNamespaceSegment(last)) return [...eventNamespace];
|
|
149
|
+
return [`tools:${toolCallId}`];
|
|
150
|
+
}
|
|
151
|
+
function toSnapshot(entry) {
|
|
152
|
+
return {
|
|
153
|
+
id: entry.id,
|
|
154
|
+
name: entry.name,
|
|
155
|
+
namespace: entry.namespace,
|
|
156
|
+
parentId: entry.parentId,
|
|
157
|
+
depth: entry.depth,
|
|
158
|
+
status: entry.status,
|
|
159
|
+
taskInput: entry.taskInput,
|
|
160
|
+
output: entry.output,
|
|
161
|
+
error: entry.error,
|
|
162
|
+
startedAt: entry.startedAt,
|
|
163
|
+
completedAt: entry.completedAt
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
function parseTaskInput(raw) {
|
|
167
|
+
if (raw == null) return {};
|
|
168
|
+
if (typeof raw === "string") try {
|
|
169
|
+
const parsed = JSON.parse(raw);
|
|
170
|
+
return {
|
|
171
|
+
description: typeof parsed.description === "string" ? parsed.description : void 0,
|
|
172
|
+
subagent_type: typeof parsed.subagent_type === "string" ? parsed.subagent_type : void 0
|
|
173
|
+
};
|
|
174
|
+
} catch {
|
|
175
|
+
return {};
|
|
176
|
+
}
|
|
177
|
+
if (typeof raw === "object" && !Array.isArray(raw)) {
|
|
178
|
+
const obj = raw;
|
|
179
|
+
return {
|
|
180
|
+
description: typeof obj.description === "string" ? obj.description : void 0,
|
|
181
|
+
subagent_type: typeof obj.subagent_type === "string" ? obj.subagent_type : void 0
|
|
182
|
+
};
|
|
183
|
+
}
|
|
184
|
+
return {};
|
|
185
|
+
}
|
|
186
|
+
function getTaskToolCalls(message) {
|
|
187
|
+
if (message == null || typeof message !== "object" || Array.isArray(message)) return [];
|
|
188
|
+
const record = message;
|
|
189
|
+
const toolCalls = record.tool_calls ?? record.kwargs?.tool_calls ?? record.lc_kwargs?.tool_calls;
|
|
190
|
+
if (!Array.isArray(toolCalls)) return [];
|
|
191
|
+
const result = [];
|
|
192
|
+
for (const toolCall of toolCalls) {
|
|
193
|
+
if (toolCall == null || typeof toolCall !== "object" || Array.isArray(toolCall)) continue;
|
|
194
|
+
const record = toolCall;
|
|
195
|
+
if (typeof record.id !== "string" || record.name !== "task") continue;
|
|
196
|
+
result.push({
|
|
197
|
+
id: record.id,
|
|
198
|
+
input: parseTaskInput(record.args)
|
|
199
|
+
});
|
|
200
|
+
}
|
|
201
|
+
return result;
|
|
202
|
+
}
|
|
203
|
+
function getToolMessageCallId(message) {
|
|
204
|
+
if (message == null || typeof message !== "object" || Array.isArray(message)) return;
|
|
205
|
+
const record = message;
|
|
206
|
+
const id = record.tool_call_id ?? record.kwargs?.tool_call_id ?? record.lc_kwargs?.tool_call_id;
|
|
207
|
+
return typeof id === "string" && id.length > 0 ? id : void 0;
|
|
208
|
+
}
|
|
209
|
+
/**
|
|
210
|
+
* Derive (parentId, depth) from a namespace like
|
|
211
|
+
* `["subagents:abc:def"]`. Namespaces form a rooted tree; the last
|
|
212
|
+
* `:` segment of the deepest namespace element is the current node's
|
|
213
|
+
* call-id and the one before it is the parent.
|
|
214
|
+
*/
|
|
215
|
+
function lineageFromNamespace(namespace) {
|
|
216
|
+
if (require_namespace.isRootNamespace(namespace)) return {
|
|
217
|
+
parentId: null,
|
|
218
|
+
depth: 1
|
|
219
|
+
};
|
|
220
|
+
const last = namespace[namespace.length - 1];
|
|
221
|
+
if (last == null) return {
|
|
222
|
+
parentId: null,
|
|
223
|
+
depth: 1
|
|
224
|
+
};
|
|
225
|
+
const trimmed = last.split(":").filter((part) => part.length > 0).slice(1);
|
|
226
|
+
const depth = Math.max(1, trimmed.length);
|
|
227
|
+
return {
|
|
228
|
+
parentId: (trimmed.length >= 2 ? trimmed[trimmed.length - 2] : null) ?? null,
|
|
229
|
+
depth
|
|
230
|
+
};
|
|
231
|
+
}
|
|
232
|
+
//#endregion
|
|
233
|
+
exports.SubagentDiscovery = SubagentDiscovery;
|
|
234
|
+
|
|
235
|
+
//# sourceMappingURL=subagents.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"subagents.cjs","names":["StreamStore","#onToolEvent","#onValuesEvent","#upsertTaskToolCall","#commit","#map","#recordObservedWorkNamespace","#recordTaskNamespaceCandidate","namespaceKey","isConcreteToolNamespace","#observedOwnNamespaces","#taskIdByObservedNamespace","isToolNamespaceSegment","isRootNamespace"],"sources":["../../../src/stream/discovery/subagents.ts"],"sourcesContent":["/**\n * Root-scoped subagent discovery.\n *\n * Populates a `Map<callId, SubagentDiscoverySnapshot>` by watching\n * `task` tool calls on the root subscription. No content channels\n * (subagent messages, tool calls, extensions) are opened here — that\n * layer is driven by selector hooks via the\n * {@link ChannelRegistry}, keyed on `SubagentDiscoverySnapshot.namespace`.\n *\n * Discovery data this runner populates per subagent:\n * - id, name, namespace, parentId, depth\n * - status (`running` | `complete` | `error`)\n * - taskInput / output / error / startedAt / completedAt\n *\n * The runner is fed events by the {@link StreamController}'s root\n * subscription; it does not open subscriptions of its own.\n */\nimport type { Event, ToolsEvent, ValuesEvent } from \"@langchain/protocol\";\nimport { StreamStore } from \"../store.js\";\nimport type { SubagentDiscoverySnapshot } from \"../types.js\";\nimport {\n isConcreteToolNamespace,\n isRootNamespace,\n isToolNamespaceSegment,\n namespaceKey,\n} from \"../namespace.js\";\n\nexport type SubagentMap = ReadonlyMap<string, SubagentDiscoverySnapshot>;\n\ninterface MutableSubagent {\n id: string;\n name: string;\n namespace: readonly string[];\n parentId: string | null;\n depth: number;\n status: \"running\" | \"complete\" | \"error\";\n taskInput: string | undefined;\n output: unknown;\n error: string | undefined;\n startedAt: Date;\n completedAt: Date | null;\n}\n\nexport class SubagentDiscovery {\n readonly store = new StreamStore<SubagentMap>(new Map());\n #map = new Map<string, MutableSubagent>();\n #taskIdByObservedNamespace = new Map<string, string>();\n #observedOwnNamespaces = new Set<string>();\n\n /** Feed a single root event. Non-discovery events are ignored. */\n push(event: Event): void {\n if (event.method === \"tools\") {\n this.#onToolEvent(event as ToolsEvent);\n } else if (event.method === \"values\") {\n this.#onValuesEvent(event as ValuesEvent);\n }\n }\n\n /** Current snapshot map. */\n get snapshot(): SubagentMap {\n return this.store.getSnapshot();\n }\n\n discoverFromMessage(message: unknown, namespace: readonly string[]): void {\n let changed = false;\n for (const toolCall of getTaskToolCalls(message)) {\n changed =\n this.#upsertTaskToolCall(toolCall.id, toolCall.input, namespace) ||\n changed;\n }\n if (changed) this.#commit();\n }\n\n #commit(): void {\n // Rebuild as a fresh Map so React / useSyncExternalStore sees a\n // new reference on every change.\n this.store.setValue(\n new Map(\n [...this.#map.values()].map((entry) => [entry.id, toSnapshot(entry)])\n )\n );\n }\n\n #onToolEvent(event: ToolsEvent): void {\n const data = event.params.data;\n const toolCallId = (data as { tool_call_id?: string }).tool_call_id;\n const toolName = (data as { tool_name?: string }).tool_name;\n\n if (data.event === \"tool-started\" && toolName === \"task\") {\n const input = parseTaskInput((data as { input?: unknown }).input);\n if (toolCallId == null) return;\n this.#upsertTaskToolCall(toolCallId, input, event.params.namespace);\n this.#commit();\n return;\n }\n\n if (toolCallId == null) return;\n const entry = this.#map.get(toolCallId);\n if (entry == null) return;\n\n if (data.event === \"tool-finished\") {\n entry.status = \"complete\";\n entry.output = (data as { output?: unknown }).output;\n entry.completedAt = new Date();\n this.#commit();\n return;\n }\n\n if (data.event === \"tool-error\") {\n entry.status = \"error\";\n entry.error = (data as { message?: string }).message ?? \"Subagent failed\";\n entry.completedAt = new Date();\n this.#commit();\n }\n }\n\n #onValuesEvent(event: ValuesEvent): void {\n const data = event.params.data;\n if (data == null || typeof data !== \"object\" || Array.isArray(data)) return;\n const messages = (data as { messages?: unknown }).messages;\n if (!Array.isArray(messages)) return;\n\n let changed = this.#recordObservedWorkNamespace(event.params.namespace);\n for (const message of messages) {\n for (const toolCall of getTaskToolCalls(message)) {\n changed =\n this.#upsertTaskToolCall(\n toolCall.id,\n toolCall.input,\n event.params.namespace\n ) || changed;\n }\n\n const toolCallId = getToolMessageCallId(message);\n if (toolCallId == null) continue;\n const existing = this.#map.get(toolCallId);\n if (existing == null) continue;\n existing.status = \"complete\";\n existing.output = message;\n existing.completedAt = new Date();\n changed = true;\n }\n if (changed) this.#commit();\n }\n\n #upsertTaskToolCall(\n toolCallId: string,\n input: { description?: string; subagent_type?: string },\n eventNamespace: readonly string[]\n ): boolean {\n const namespace = taskWorkNamespace(toolCallId, eventNamespace);\n const existing = this.#map.get(toolCallId);\n if (existing != null) {\n let changed = false;\n this.#recordTaskNamespaceCandidate(toolCallId, eventNamespace);\n const nextName = input.subagent_type ?? existing.name;\n const nextTaskInput = input.description ?? existing.taskInput;\n if (existing.name !== nextName) {\n existing.name = nextName;\n changed = true;\n }\n if (existing.taskInput !== nextTaskInput) {\n existing.taskInput = nextTaskInput;\n changed = true;\n }\n const namespaceKeyed = namespaceKey(existing.namespace);\n const ownNamespaceKey = `tools:${toolCallId}`;\n const nextNamespaceKey = namespaceKey(namespace);\n if (\n isConcreteToolNamespace(eventNamespace) ||\n namespaceKeyed === ownNamespaceKey\n ) {\n // A wrapper task tool event can arrive under an execution namespace\n // like `tools:<uuid>`, while the subagent's actual message state is\n // under `tools:<tool_call_id>`. Once discovery has observed the own\n // namespace carrying state, do not demote it back to the wrapper\n // namespace.\n if (\n namespaceKeyed === ownNamespaceKey &&\n nextNamespaceKey !== ownNamespaceKey &&\n this.#observedOwnNamespaces.has(toolCallId)\n ) {\n return changed;\n }\n if (namespaceKeyed !== nextNamespaceKey) {\n existing.namespace = namespace;\n changed = true;\n }\n }\n if (existing.status !== \"complete\" && existing.status !== \"error\") {\n if (existing.status !== \"running\") {\n existing.status = \"running\";\n changed = true;\n }\n }\n return changed;\n }\n\n // Prefer the namespace where the task is first observed. Later\n // observations may move it between wrapper execution namespaces\n // and `[\"tools:<toolCallId>\"]`, depending on where the stream proves\n // the worker's scoped message/tool state exists.\n const { parentId, depth } = lineageFromNamespace(eventNamespace);\n this.#recordTaskNamespaceCandidate(toolCallId, eventNamespace);\n this.#map.set(toolCallId, {\n id: toolCallId,\n name: input.subagent_type ?? \"unknown\",\n namespace,\n parentId,\n depth,\n status: \"running\",\n taskInput: input.description,\n output: undefined,\n error: undefined,\n startedAt: new Date(),\n completedAt: null,\n });\n return true;\n }\n\n #recordObservedWorkNamespace(namespace: readonly string[]): boolean {\n if (!isConcreteToolNamespace(namespace)) return false;\n const last = namespace.at(-1);\n if (last == null) return false;\n const namespaceKeyed = namespaceKey(namespace);\n const toolCallId =\n this.#taskIdByObservedNamespace.get(namespaceKeyed) ??\n last.slice(\"tools:\".length);\n const existing = this.#map.get(toolCallId);\n if (existing == null) return false;\n\n const ownNamespaceKey = `tools:${toolCallId}`;\n if (namespaceKeyed === ownNamespaceKey) {\n this.#observedOwnNamespaces.add(toolCallId);\n } else if (\n this.#observedOwnNamespaces.has(toolCallId) ||\n (!this.#taskIdByObservedNamespace.has(namespaceKeyed) &&\n !shouldPromoteToObservedNamespace(existing))\n ) {\n return false;\n }\n\n if (namespaceKey(existing.namespace) === namespaceKeyed) return false;\n existing.namespace = [...namespace];\n return true;\n }\n\n #recordTaskNamespaceCandidate(\n toolCallId: string,\n namespace: readonly string[]\n ): void {\n if (!isConcreteToolNamespace(namespace)) return;\n this.#taskIdByObservedNamespace.set(namespaceKey(namespace), toolCallId);\n }\n}\n\nfunction shouldPromoteToObservedNamespace(entry: MutableSubagent): boolean {\n return (\n entry.name === \"fanout-worker\" ||\n /^Worker worker-\\d+/i.test(entry.taskInput ?? \"\")\n );\n}\n\nfunction taskWorkNamespace(\n toolCallId: string,\n eventNamespace: readonly string[]\n): readonly string[] {\n const last = eventNamespace.at(-1);\n if (last != null && isToolNamespaceSegment(last)) return [...eventNamespace];\n return [`tools:${toolCallId}`];\n}\n\nfunction toSnapshot(entry: MutableSubagent): SubagentDiscoverySnapshot {\n return {\n id: entry.id,\n name: entry.name,\n namespace: entry.namespace,\n parentId: entry.parentId,\n depth: entry.depth,\n status: entry.status,\n taskInput: entry.taskInput,\n output: entry.output,\n error: entry.error,\n startedAt: entry.startedAt,\n completedAt: entry.completedAt,\n };\n}\n\nfunction parseTaskInput(raw: unknown): {\n description?: string;\n subagent_type?: string;\n} {\n if (raw == null) return {};\n if (typeof raw === \"string\") {\n try {\n const parsed = JSON.parse(raw) as Record<string, unknown>;\n return {\n description:\n typeof parsed.description === \"string\"\n ? parsed.description\n : undefined,\n subagent_type:\n typeof parsed.subagent_type === \"string\"\n ? parsed.subagent_type\n : undefined,\n };\n } catch {\n return {};\n }\n }\n if (typeof raw === \"object\" && !Array.isArray(raw)) {\n const obj = raw as Record<string, unknown>;\n return {\n description:\n typeof obj.description === \"string\" ? obj.description : undefined,\n subagent_type:\n typeof obj.subagent_type === \"string\" ? obj.subagent_type : undefined,\n };\n }\n return {};\n}\n\nfunction getTaskToolCalls(message: unknown): Array<{\n id: string;\n input: { description?: string; subagent_type?: string };\n}> {\n if (\n message == null ||\n typeof message !== \"object\" ||\n Array.isArray(message)\n ) {\n return [];\n }\n const record = message as {\n tool_calls?: unknown;\n kwargs?: { tool_calls?: unknown };\n lc_kwargs?: { tool_calls?: unknown };\n };\n const toolCalls =\n record.tool_calls ??\n record.kwargs?.tool_calls ??\n record.lc_kwargs?.tool_calls;\n if (!Array.isArray(toolCalls)) return [];\n\n const result: Array<{\n id: string;\n input: { description?: string; subagent_type?: string };\n }> = [];\n for (const toolCall of toolCalls) {\n if (\n toolCall == null ||\n typeof toolCall !== \"object\" ||\n Array.isArray(toolCall)\n ) {\n continue;\n }\n const record = toolCall as {\n id?: unknown;\n name?: unknown;\n args?: unknown;\n };\n if (typeof record.id !== \"string\" || record.name !== \"task\") continue;\n result.push({ id: record.id, input: parseTaskInput(record.args) });\n }\n return result;\n}\n\nfunction getToolMessageCallId(message: unknown): string | undefined {\n if (\n message == null ||\n typeof message !== \"object\" ||\n Array.isArray(message)\n ) {\n return undefined;\n }\n const record = message as {\n tool_call_id?: unknown;\n kwargs?: { tool_call_id?: unknown };\n lc_kwargs?: { tool_call_id?: unknown };\n };\n const id =\n record.tool_call_id ??\n record.kwargs?.tool_call_id ??\n record.lc_kwargs?.tool_call_id;\n return typeof id === \"string\" && id.length > 0 ? id : undefined;\n}\n\n/**\n * Derive (parentId, depth) from a namespace like\n * `[\"subagents:abc:def\"]`. Namespaces form a rooted tree; the last\n * `:` segment of the deepest namespace element is the current node's\n * call-id and the one before it is the parent.\n */\nfunction lineageFromNamespace(namespace: readonly string[]): {\n parentId: string | null;\n depth: number;\n} {\n if (isRootNamespace(namespace)) return { parentId: null, depth: 1 };\n const last = namespace[namespace.length - 1];\n if (last == null) return { parentId: null, depth: 1 };\n // Namespace segments typically look like\n // subagents:<parentCallId>:<thisCallId>\n // but the protocol doesn't mandate that shape; we best-effort.\n const parts = last.split(\":\").filter((part) => part.length > 0);\n const trimmed = parts.slice(1); // drop the leading \"subagents\" prefix\n const depth = Math.max(1, trimmed.length);\n const parentId = trimmed.length >= 2 ? trimmed[trimmed.length - 2] : null;\n return { parentId: parentId ?? null, depth };\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { StreamStore } from "../store.cjs";
|
|
2
|
+
import { SubagentDiscoverySnapshot } from "../types.cjs";
|
|
3
|
+
import { Event } from "@langchain/protocol";
|
|
4
|
+
|
|
5
|
+
//#region src/stream/discovery/subagents.d.ts
|
|
6
|
+
type SubagentMap = ReadonlyMap<string, SubagentDiscoverySnapshot>;
|
|
7
|
+
declare class SubagentDiscovery {
|
|
8
|
+
#private;
|
|
9
|
+
readonly store: StreamStore<SubagentMap>;
|
|
10
|
+
/** Feed a single root event. Non-discovery events are ignored. */
|
|
11
|
+
push(event: Event): void;
|
|
12
|
+
/** Current snapshot map. */
|
|
13
|
+
get snapshot(): SubagentMap;
|
|
14
|
+
discoverFromMessage(message: unknown, namespace: readonly string[]): void;
|
|
15
|
+
}
|
|
16
|
+
//#endregion
|
|
17
|
+
export { SubagentDiscovery, SubagentMap };
|
|
18
|
+
//# sourceMappingURL=subagents.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"subagents.d.cts","names":[],"sources":["../../../src/stream/discovery/subagents.ts"],"mappings":";;;;;KA2BY,WAAA,GAAc,WAAA,SAAoB,yBAAA;AAAA,cAgBjC,iBAAA;EAAA;WACF,KAAA,EAAK,WAAA,CAAA,WAAA;EAMF;EAAZ,IAAA,CAAK,KAAA,EAAO,KAAA;EASR;EAAA,IAAA,QAAA,CAAA,GAAY,WAAA;EAIhB,mBAAA,CAAoB,OAAA,WAAkB,SAAA;AAAA"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { StreamStore } from "../store.js";
|
|
2
|
+
import { SubagentDiscoverySnapshot } from "../types.js";
|
|
3
|
+
import { Event } from "@langchain/protocol";
|
|
4
|
+
|
|
5
|
+
//#region src/stream/discovery/subagents.d.ts
|
|
6
|
+
type SubagentMap = ReadonlyMap<string, SubagentDiscoverySnapshot>;
|
|
7
|
+
declare class SubagentDiscovery {
|
|
8
|
+
#private;
|
|
9
|
+
readonly store: StreamStore<SubagentMap>;
|
|
10
|
+
/** Feed a single root event. Non-discovery events are ignored. */
|
|
11
|
+
push(event: Event): void;
|
|
12
|
+
/** Current snapshot map. */
|
|
13
|
+
get snapshot(): SubagentMap;
|
|
14
|
+
discoverFromMessage(message: unknown, namespace: readonly string[]): void;
|
|
15
|
+
}
|
|
16
|
+
//#endregion
|
|
17
|
+
export { SubagentDiscovery, SubagentMap };
|
|
18
|
+
//# sourceMappingURL=subagents.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"subagents.d.ts","names":[],"sources":["../../../src/stream/discovery/subagents.ts"],"mappings":";;;;;KA2BY,WAAA,GAAc,WAAA,SAAoB,yBAAA;AAAA,cAgBjC,iBAAA;EAAA;WACF,KAAA,EAAK,WAAA,CAAA,WAAA;EAMF;EAAZ,IAAA,CAAK,KAAA,EAAO,KAAA;EASR;EAAA,IAAA,QAAA,CAAA,GAAY,WAAA;EAIhB,mBAAA,CAAoB,OAAA,WAAkB,SAAA;AAAA"}
|