@langchain/angular 1.0.4 → 1.0.5
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/dist/context.cjs.map +1 -1
- package/dist/context.js.map +1 -1
- package/dist/index.d.cts +4 -4
- package/dist/index.d.ts +4 -4
- package/dist/selectors.cjs +0 -5
- package/dist/selectors.cjs.map +1 -1
- package/dist/selectors.d.cts +2 -1
- package/dist/selectors.d.cts.map +1 -1
- package/dist/selectors.d.ts +2 -1
- package/dist/selectors.d.ts.map +1 -1
- package/dist/selectors.js +0 -5
- package/dist/selectors.js.map +1 -1
- package/dist/use-stream.cjs +1 -0
- package/dist/use-stream.cjs.map +1 -1
- package/dist/use-stream.d.cts +3 -5
- package/dist/use-stream.d.cts.map +1 -1
- package/dist/use-stream.d.ts +3 -5
- package/dist/use-stream.d.ts.map +1 -1
- package/dist/use-stream.js +1 -0
- package/dist/use-stream.js.map +1 -1
- package/package.json +2 -2
package/dist/context.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"context.cjs","names":["InjectionToken","useStream"],"sources":["../src/context.ts"],"sourcesContent":["import {\n InjectionToken,\n inject as angularInject,\n type EnvironmentProviders,\n makeEnvironmentProviders,\n} from \"@angular/core\";\nimport { Client } from \"@langchain/langgraph-sdk\";\nimport type { InferStateType } from \"@langchain/langgraph-sdk/stream\";\nimport {\n useStream,\n type StreamApi,\n type UseStreamOptions,\n} from \"./use-stream.js\";\n\nexport type InferRecordState<T> =\n InferStateType<T> extends object\n ? { [K in keyof InferStateType<T>]: InferStateType<T>[K] }\n : Record<string, unknown>;\n\n/**\n * Configuration defaults for `useStream` and `injectStream` calls.\n */\nexport interface StreamDefaults {\n /** Base URL of the LangGraph API. */\n apiUrl?: string;\n /** API key for authenticating with the LangGraph API. */\n apiKey?: string;\n /** Pre-configured Client instance. */\n client?: Client;\n}\n\n/**\n * Injection token for stream default configuration.\n * Provide via `provideStreamDefaults()` in your application config.\n */\nexport const STREAM_DEFAULTS = new InjectionToken<StreamDefaults>(\n \"LANGCHAIN_STREAM_DEFAULTS\"\n);\n\n/**\n * Injection token for a shared stream instance.\n * Provide via `provideStream()` at the component level.\n */\nexport const STREAM_INSTANCE = new InjectionToken<StreamApi>(\n \"LANGCHAIN_STREAM_INSTANCE\"\n);\n\n/**\n * Provides default LangGraph configuration at the application level.\n *\n * Use this in your application's `providers` array to set defaults like\n * `apiUrl` that will be used by all `useStream` and `injectStream` calls.\n *\n * @example\n * ```typescript\n * // app.config.ts\n * import { ApplicationConfig } from \"@angular/core\";\n * import { provideStreamDefaults } from \"@langchain/angular\";\n *\n * export const appConfig: ApplicationConfig = {\n * providers: [\n * provideStreamDefaults({\n * apiUrl: \"http://localhost:2024\",\n * }),\n * ],\n * };\n * ```\n */\nexport function provideStreamDefaults(\n defaults: StreamDefaults\n): EnvironmentProviders {\n return makeEnvironmentProviders([\n { provide: STREAM_DEFAULTS, useValue: defaults },\n ]);\n}\n\n/**\n * Creates a provider for a shared `useStream` instance at the component level.\n *\n * Add the returned provider to a component's `providers` array so that all\n * child components can access the same stream via `injectStream()`.\n *\n * @example\n * ```typescript\n * import { Component } from \"@angular/core\";\n * import { provideStream, injectStream } from \"@langchain/angular\";\n *\n * @Component({\n * providers: [provideStream({ assistantId: \"agent\" })],\n * template: `\n * <app-message-list />\n * <app-message-input />\n * `,\n * })\n * export class ChatContainer {}\n *\n * // In child components:\n * @Component({\n * template: `\n * @for (msg of stream.messages(); track msg.id) {\n * <div>{{ msg.content }}</div>\n * }\n * `,\n * })\n * export class MessageListComponent {\n * stream = injectStream();\n * }\n * ```\n */\nexport function provideStream<T = Record<string, unknown>>(\n options: UseStreamOptions<InferStateType<T>>\n) {\n return {\n provide: STREAM_INSTANCE,\n useFactory: () => {\n const defaults = angularInject(STREAM_DEFAULTS, { optional: true });\n return useStream(mergeDefaults(options, defaults));\n },\n };\n}\n\nfunction mergeDefaults<S extends object>(\n options: UseStreamOptions<S>,\n defaults: StreamDefaults | null | undefined\n): UseStreamOptions<S> {\n if (defaults == null) return options;\n if (\n (options as { transport?: unknown }).transport != null &&\n typeof (options as { transport: unknown }).transport !== \"string\"\n ) {\n return options;\n }\n const bag = options as unknown as Record<string, unknown>;\n return {\n ...bag,\n apiUrl: bag.apiUrl ?? defaults.apiUrl,\n apiKey: bag.apiKey ?? defaults.apiKey,\n client: bag.client ?? defaults.client,\n } as unknown as UseStreamOptions<S>;\n}\n"],"mappings":";;;;;;;AAmCA,MAAa,kBAAkB,IAAIA,cAAAA,eACjC,4BACD;;;;;AAMD,MAAa,kBAAkB,IAAIA,cAAAA,eACjC,4BACD;;;;;;;;;;;;;;;;;;;;;;AAuBD,SAAgB,sBACd,UACsB;AACtB,SAAA,GAAA,cAAA,0BAAgC,CAC9B;EAAE,SAAS;EAAiB,UAAU;EAAU,CACjD,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAoCJ,SAAgB,cACd,SACA;AACA,QAAO;EACL,SAAS;EACT,kBAAkB;AAEhB,UAAOC,mBAAAA,
|
|
1
|
+
{"version":3,"file":"context.cjs","names":["InjectionToken","useStream"],"sources":["../src/context.ts"],"sourcesContent":["import {\n InjectionToken,\n inject as angularInject,\n type EnvironmentProviders,\n makeEnvironmentProviders,\n} from \"@angular/core\";\nimport { Client } from \"@langchain/langgraph-sdk\";\nimport type { InferStateType } from \"@langchain/langgraph-sdk/stream\";\nimport {\n useStream,\n type StreamApi,\n type UseStreamOptions,\n} from \"./use-stream.js\";\n\nexport type InferRecordState<T> =\n InferStateType<T> extends object\n ? { [K in keyof InferStateType<T>]: InferStateType<T>[K] }\n : Record<string, unknown>;\n\n/**\n * Configuration defaults for `useStream` and `injectStream` calls.\n */\nexport interface StreamDefaults {\n /** Base URL of the LangGraph API. */\n apiUrl?: string;\n /** API key for authenticating with the LangGraph API. */\n apiKey?: string;\n /** Pre-configured Client instance. */\n client?: Client;\n}\n\n/**\n * Injection token for stream default configuration.\n * Provide via `provideStreamDefaults()` in your application config.\n */\nexport const STREAM_DEFAULTS = new InjectionToken<StreamDefaults>(\n \"LANGCHAIN_STREAM_DEFAULTS\"\n);\n\n/**\n * Injection token for a shared stream instance.\n * Provide via `provideStream()` at the component level.\n */\nexport const STREAM_INSTANCE = new InjectionToken<StreamApi>(\n \"LANGCHAIN_STREAM_INSTANCE\"\n);\n\n/**\n * Provides default LangGraph configuration at the application level.\n *\n * Use this in your application's `providers` array to set defaults like\n * `apiUrl` that will be used by all `useStream` and `injectStream` calls.\n *\n * @example\n * ```typescript\n * // app.config.ts\n * import { ApplicationConfig } from \"@angular/core\";\n * import { provideStreamDefaults } from \"@langchain/angular\";\n *\n * export const appConfig: ApplicationConfig = {\n * providers: [\n * provideStreamDefaults({\n * apiUrl: \"http://localhost:2024\",\n * }),\n * ],\n * };\n * ```\n */\nexport function provideStreamDefaults(\n defaults: StreamDefaults\n): EnvironmentProviders {\n return makeEnvironmentProviders([\n { provide: STREAM_DEFAULTS, useValue: defaults },\n ]);\n}\n\n/**\n * Creates a provider for a shared `useStream` instance at the component level.\n *\n * Add the returned provider to a component's `providers` array so that all\n * child components can access the same stream via `injectStream()`.\n *\n * @example\n * ```typescript\n * import { Component } from \"@angular/core\";\n * import { provideStream, injectStream } from \"@langchain/angular\";\n *\n * @Component({\n * providers: [provideStream({ assistantId: \"agent\" })],\n * template: `\n * <app-message-list />\n * <app-message-input />\n * `,\n * })\n * export class ChatContainer {}\n *\n * // In child components:\n * @Component({\n * template: `\n * @for (msg of stream.messages(); track msg.id) {\n * <div>{{ msg.content }}</div>\n * }\n * `,\n * })\n * export class MessageListComponent {\n * stream = injectStream();\n * }\n * ```\n */\nexport function provideStream<T = Record<string, unknown>>(\n options: UseStreamOptions<InferStateType<T>>\n) {\n return {\n provide: STREAM_INSTANCE,\n useFactory: () => {\n const defaults = angularInject(STREAM_DEFAULTS, { optional: true });\n return useStream<T>(mergeDefaults(options, defaults));\n },\n };\n}\n\nfunction mergeDefaults<S extends object>(\n options: UseStreamOptions<S>,\n defaults: StreamDefaults | null | undefined\n): UseStreamOptions<S> {\n if (defaults == null) return options;\n if (\n (options as { transport?: unknown }).transport != null &&\n typeof (options as { transport: unknown }).transport !== \"string\"\n ) {\n return options;\n }\n const bag = options as unknown as Record<string, unknown>;\n return {\n ...bag,\n apiUrl: bag.apiUrl ?? defaults.apiUrl,\n apiKey: bag.apiKey ?? defaults.apiKey,\n client: bag.client ?? defaults.client,\n } as unknown as UseStreamOptions<S>;\n}\n"],"mappings":";;;;;;;AAmCA,MAAa,kBAAkB,IAAIA,cAAAA,eACjC,4BACD;;;;;AAMD,MAAa,kBAAkB,IAAIA,cAAAA,eACjC,4BACD;;;;;;;;;;;;;;;;;;;;;;AAuBD,SAAgB,sBACd,UACsB;AACtB,SAAA,GAAA,cAAA,0BAAgC,CAC9B;EAAE,SAAS;EAAiB,UAAU;EAAU,CACjD,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAoCJ,SAAgB,cACd,SACA;AACA,QAAO;EACL,SAAS;EACT,kBAAkB;AAEhB,UAAOC,mBAAAA,UAAa,cAAc,UAAA,GAAA,cAAA,QADH,iBAAiB,EAAE,UAAU,MAAM,CAAC,CACf,CAAC;;EAExD;;AAGH,SAAS,cACP,SACA,UACqB;AACrB,KAAI,YAAY,KAAM,QAAO;AAC7B,KACG,QAAoC,aAAa,QAClD,OAAQ,QAAmC,cAAc,SAEzD,QAAO;CAET,MAAM,MAAM;AACZ,QAAO;EACL,GAAG;EACH,QAAQ,IAAI,UAAU,SAAS;EAC/B,QAAQ,IAAI,UAAU,SAAS;EAC/B,QAAQ,IAAI,UAAU,SAAS;EAChC"}
|
package/dist/context.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"context.js","names":["angularInject"],"sources":["../src/context.ts"],"sourcesContent":["import {\n InjectionToken,\n inject as angularInject,\n type EnvironmentProviders,\n makeEnvironmentProviders,\n} from \"@angular/core\";\nimport { Client } from \"@langchain/langgraph-sdk\";\nimport type { InferStateType } from \"@langchain/langgraph-sdk/stream\";\nimport {\n useStream,\n type StreamApi,\n type UseStreamOptions,\n} from \"./use-stream.js\";\n\nexport type InferRecordState<T> =\n InferStateType<T> extends object\n ? { [K in keyof InferStateType<T>]: InferStateType<T>[K] }\n : Record<string, unknown>;\n\n/**\n * Configuration defaults for `useStream` and `injectStream` calls.\n */\nexport interface StreamDefaults {\n /** Base URL of the LangGraph API. */\n apiUrl?: string;\n /** API key for authenticating with the LangGraph API. */\n apiKey?: string;\n /** Pre-configured Client instance. */\n client?: Client;\n}\n\n/**\n * Injection token for stream default configuration.\n * Provide via `provideStreamDefaults()` in your application config.\n */\nexport const STREAM_DEFAULTS = new InjectionToken<StreamDefaults>(\n \"LANGCHAIN_STREAM_DEFAULTS\"\n);\n\n/**\n * Injection token for a shared stream instance.\n * Provide via `provideStream()` at the component level.\n */\nexport const STREAM_INSTANCE = new InjectionToken<StreamApi>(\n \"LANGCHAIN_STREAM_INSTANCE\"\n);\n\n/**\n * Provides default LangGraph configuration at the application level.\n *\n * Use this in your application's `providers` array to set defaults like\n * `apiUrl` that will be used by all `useStream` and `injectStream` calls.\n *\n * @example\n * ```typescript\n * // app.config.ts\n * import { ApplicationConfig } from \"@angular/core\";\n * import { provideStreamDefaults } from \"@langchain/angular\";\n *\n * export const appConfig: ApplicationConfig = {\n * providers: [\n * provideStreamDefaults({\n * apiUrl: \"http://localhost:2024\",\n * }),\n * ],\n * };\n * ```\n */\nexport function provideStreamDefaults(\n defaults: StreamDefaults\n): EnvironmentProviders {\n return makeEnvironmentProviders([\n { provide: STREAM_DEFAULTS, useValue: defaults },\n ]);\n}\n\n/**\n * Creates a provider for a shared `useStream` instance at the component level.\n *\n * Add the returned provider to a component's `providers` array so that all\n * child components can access the same stream via `injectStream()`.\n *\n * @example\n * ```typescript\n * import { Component } from \"@angular/core\";\n * import { provideStream, injectStream } from \"@langchain/angular\";\n *\n * @Component({\n * providers: [provideStream({ assistantId: \"agent\" })],\n * template: `\n * <app-message-list />\n * <app-message-input />\n * `,\n * })\n * export class ChatContainer {}\n *\n * // In child components:\n * @Component({\n * template: `\n * @for (msg of stream.messages(); track msg.id) {\n * <div>{{ msg.content }}</div>\n * }\n * `,\n * })\n * export class MessageListComponent {\n * stream = injectStream();\n * }\n * ```\n */\nexport function provideStream<T = Record<string, unknown>>(\n options: UseStreamOptions<InferStateType<T>>\n) {\n return {\n provide: STREAM_INSTANCE,\n useFactory: () => {\n const defaults = angularInject(STREAM_DEFAULTS, { optional: true });\n return useStream(mergeDefaults(options, defaults));\n },\n };\n}\n\nfunction mergeDefaults<S extends object>(\n options: UseStreamOptions<S>,\n defaults: StreamDefaults | null | undefined\n): UseStreamOptions<S> {\n if (defaults == null) return options;\n if (\n (options as { transport?: unknown }).transport != null &&\n typeof (options as { transport: unknown }).transport !== \"string\"\n ) {\n return options;\n }\n const bag = options as unknown as Record<string, unknown>;\n return {\n ...bag,\n apiUrl: bag.apiUrl ?? defaults.apiUrl,\n apiKey: bag.apiKey ?? defaults.apiKey,\n client: bag.client ?? defaults.client,\n } as unknown as UseStreamOptions<S>;\n}\n"],"mappings":";;;;;;;AAmCA,MAAa,kBAAkB,IAAI,eACjC,4BACD;;;;;AAMD,MAAa,kBAAkB,IAAI,eACjC,4BACD;;;;;;;;;;;;;;;;;;;;;;AAuBD,SAAgB,sBACd,UACsB;AACtB,QAAO,yBAAyB,CAC9B;EAAE,SAAS;EAAiB,UAAU;EAAU,CACjD,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAoCJ,SAAgB,cACd,SACA;AACA,QAAO;EACL,SAAS;EACT,kBAAkB;AAEhB,UAAO,
|
|
1
|
+
{"version":3,"file":"context.js","names":["angularInject"],"sources":["../src/context.ts"],"sourcesContent":["import {\n InjectionToken,\n inject as angularInject,\n type EnvironmentProviders,\n makeEnvironmentProviders,\n} from \"@angular/core\";\nimport { Client } from \"@langchain/langgraph-sdk\";\nimport type { InferStateType } from \"@langchain/langgraph-sdk/stream\";\nimport {\n useStream,\n type StreamApi,\n type UseStreamOptions,\n} from \"./use-stream.js\";\n\nexport type InferRecordState<T> =\n InferStateType<T> extends object\n ? { [K in keyof InferStateType<T>]: InferStateType<T>[K] }\n : Record<string, unknown>;\n\n/**\n * Configuration defaults for `useStream` and `injectStream` calls.\n */\nexport interface StreamDefaults {\n /** Base URL of the LangGraph API. */\n apiUrl?: string;\n /** API key for authenticating with the LangGraph API. */\n apiKey?: string;\n /** Pre-configured Client instance. */\n client?: Client;\n}\n\n/**\n * Injection token for stream default configuration.\n * Provide via `provideStreamDefaults()` in your application config.\n */\nexport const STREAM_DEFAULTS = new InjectionToken<StreamDefaults>(\n \"LANGCHAIN_STREAM_DEFAULTS\"\n);\n\n/**\n * Injection token for a shared stream instance.\n * Provide via `provideStream()` at the component level.\n */\nexport const STREAM_INSTANCE = new InjectionToken<StreamApi>(\n \"LANGCHAIN_STREAM_INSTANCE\"\n);\n\n/**\n * Provides default LangGraph configuration at the application level.\n *\n * Use this in your application's `providers` array to set defaults like\n * `apiUrl` that will be used by all `useStream` and `injectStream` calls.\n *\n * @example\n * ```typescript\n * // app.config.ts\n * import { ApplicationConfig } from \"@angular/core\";\n * import { provideStreamDefaults } from \"@langchain/angular\";\n *\n * export const appConfig: ApplicationConfig = {\n * providers: [\n * provideStreamDefaults({\n * apiUrl: \"http://localhost:2024\",\n * }),\n * ],\n * };\n * ```\n */\nexport function provideStreamDefaults(\n defaults: StreamDefaults\n): EnvironmentProviders {\n return makeEnvironmentProviders([\n { provide: STREAM_DEFAULTS, useValue: defaults },\n ]);\n}\n\n/**\n * Creates a provider for a shared `useStream` instance at the component level.\n *\n * Add the returned provider to a component's `providers` array so that all\n * child components can access the same stream via `injectStream()`.\n *\n * @example\n * ```typescript\n * import { Component } from \"@angular/core\";\n * import { provideStream, injectStream } from \"@langchain/angular\";\n *\n * @Component({\n * providers: [provideStream({ assistantId: \"agent\" })],\n * template: `\n * <app-message-list />\n * <app-message-input />\n * `,\n * })\n * export class ChatContainer {}\n *\n * // In child components:\n * @Component({\n * template: `\n * @for (msg of stream.messages(); track msg.id) {\n * <div>{{ msg.content }}</div>\n * }\n * `,\n * })\n * export class MessageListComponent {\n * stream = injectStream();\n * }\n * ```\n */\nexport function provideStream<T = Record<string, unknown>>(\n options: UseStreamOptions<InferStateType<T>>\n) {\n return {\n provide: STREAM_INSTANCE,\n useFactory: () => {\n const defaults = angularInject(STREAM_DEFAULTS, { optional: true });\n return useStream<T>(mergeDefaults(options, defaults));\n },\n };\n}\n\nfunction mergeDefaults<S extends object>(\n options: UseStreamOptions<S>,\n defaults: StreamDefaults | null | undefined\n): UseStreamOptions<S> {\n if (defaults == null) return options;\n if (\n (options as { transport?: unknown }).transport != null &&\n typeof (options as { transport: unknown }).transport !== \"string\"\n ) {\n return options;\n }\n const bag = options as unknown as Record<string, unknown>;\n return {\n ...bag,\n apiUrl: bag.apiUrl ?? defaults.apiUrl,\n apiKey: bag.apiKey ?? defaults.apiKey,\n client: bag.client ?? defaults.client,\n } as unknown as UseStreamOptions<S>;\n}\n"],"mappings":";;;;;;;AAmCA,MAAa,kBAAkB,IAAI,eACjC,4BACD;;;;;AAMD,MAAa,kBAAkB,IAAI,eACjC,4BACD;;;;;;;;;;;;;;;;;;;;;;AAuBD,SAAgB,sBACd,UACsB;AACtB,QAAO,yBAAyB,CAC9B;EAAE,SAAS;EAAiB,UAAU;EAAU,CACjD,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAoCJ,SAAgB,cACd,SACA;AACA,QAAO;EACL,SAAS;EACT,kBAAkB;AAEhB,UAAO,UAAa,cAAc,SADjBA,OAAc,iBAAiB,EAAE,UAAU,MAAM,CAAC,CACf,CAAC;;EAExD;;AAGH,SAAS,cACP,SACA,UACqB;AACrB,KAAI,YAAY,KAAM,QAAO;AAC7B,KACG,QAAoC,aAAa,QAClD,OAAQ,QAAmC,cAAc,SAEzD,QAAO;CAET,MAAM,MAAM;AACZ,QAAO;EACL,GAAG;EACH,QAAQ,IAAI,UAAU,SAAS;EAC/B,QAAQ,IAAI,UAAU,SAAS;EAC/B,QAAQ,IAAI,UAAU,SAAS;EAChC"}
|
package/dist/index.d.cts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { AgentServerOptions, AnyStream, CustomAdapterOptions, STREAM_CONTROLLER,
|
|
1
|
+
import { AgentServerOptions, AnyStream, CustomAdapterOptions, STREAM_CONTROLLER, StreamApi, ThreadStream, UseStreamOptions, UseStreamResult, UseStreamReturn, useStream } from "./use-stream.cjs";
|
|
2
2
|
import { injectStream } from "./inject-stream.cjs";
|
|
3
3
|
import { injectProjection } from "./inject-projection.cjs";
|
|
4
4
|
import { SelectorTarget, injectAudio, injectChannel, injectExtension, injectFiles, injectImages, injectMessages, injectToolCalls, injectValues, injectVideo } from "./selectors.cjs";
|
|
@@ -7,6 +7,6 @@ import { MessageMetadata, MessageMetadataMap, injectMessageMetadata } from "./se
|
|
|
7
7
|
import { injectMediaUrl } from "./inject-media-url.cjs";
|
|
8
8
|
import { STREAM_DEFAULTS, STREAM_INSTANCE, StreamDefaults, provideStream, provideStreamDefaults } from "./context.cjs";
|
|
9
9
|
import { StreamService } from "./stream-service.cjs";
|
|
10
|
-
import { AgentServerAdapter, AnyMediaHandle, AssembledToolCall, AudioMedia, Channel, Event, FileMedia, ImageMedia, InferStateType, InferSubagentStates, InferToolCalls, MediaAssemblyError, MediaAssemblyErrorKind, MediaBase, MediaBlockType, StreamSubmitOptions, SubagentDiscoverySnapshot, SubgraphDiscoverySnapshot, ToolCallStatus, VideoMedia, WidenUpdateMessages } from "@langchain/langgraph-sdk/stream";
|
|
11
|
-
import { AnyHeadlessToolImplementation, DefaultToolCall, FlushPendingHeadlessToolInterruptsOptions, HeadlessToolImplementation, HeadlessToolInterrupt, HttpAgentServerAdapter, HttpAgentServerAdapterOptions, OnToolCallback,
|
|
12
|
-
export { type AgentServerAdapter, type AgentServerOptions, type AnyHeadlessToolImplementation, type AnyMediaHandle, type AnyStream, type AssembledToolCall, type AudioMedia, type Channel, type CustomAdapterOptions, type DefaultToolCall, type Event, type FileMedia, type FlushPendingHeadlessToolInterruptsOptions, type HeadlessToolImplementation, type HeadlessToolInterrupt, HttpAgentServerAdapter, type HttpAgentServerAdapterOptions, type ImageMedia, type InferStateType, type InferSubagentStates, type InferToolCalls, type InjectSubmissionQueueReturn, MediaAssemblyError, type MediaAssemblyErrorKind, type MediaBase, type MediaBlockType, type MessageMetadata, type MessageMetadataMap, type OnToolCallback, STREAM_CONTROLLER, STREAM_DEFAULTS, STREAM_INSTANCE, type SelectorTarget, type
|
|
10
|
+
import { AgentServerAdapter, AnyMediaHandle, AssembledToolCall, AssembledToolCallFromTool as ToolCallFromTool, AudioMedia, Channel, Event, FileMedia, ImageMedia, InferStateType, InferSubagentStates, InferToolCalls, MediaAssemblyError, MediaAssemblyErrorKind, MediaBase, MediaBlockType, StreamSubmitOptions, SubagentDiscoverySnapshot, SubgraphDiscoverySnapshot, ToolCallStatus, VideoMedia, WidenUpdateMessages } from "@langchain/langgraph-sdk/stream";
|
|
11
|
+
import { AnyHeadlessToolImplementation, DefaultToolCall, FlushPendingHeadlessToolInterruptsOptions, HeadlessToolImplementation, HeadlessToolInterrupt, HttpAgentServerAdapter, HttpAgentServerAdapterOptions, OnToolCallback, ToolCallState, ToolCallsFromTools, ToolEvent, executeHeadlessTool, filterOutHeadlessToolInterrupts, findHeadlessTool, flushPendingHeadlessToolInterrupts, handleHeadlessToolInterrupt, headlessToolResumeCommand, isHeadlessToolInterrupt, parseHeadlessToolInterruptPayload } from "@langchain/langgraph-sdk";
|
|
12
|
+
export { type AgentServerAdapter, type AgentServerOptions, type AnyHeadlessToolImplementation, type AnyMediaHandle, type AnyStream, type AssembledToolCall, type AudioMedia, type Channel, type CustomAdapterOptions, type DefaultToolCall, type Event, type FileMedia, type FlushPendingHeadlessToolInterruptsOptions, type HeadlessToolImplementation, type HeadlessToolInterrupt, HttpAgentServerAdapter, type HttpAgentServerAdapterOptions, type ImageMedia, type InferStateType, type InferSubagentStates, type InferToolCalls, type InjectSubmissionQueueReturn, MediaAssemblyError, type MediaAssemblyErrorKind, type MediaBase, type MediaBlockType, type MessageMetadata, type MessageMetadataMap, type OnToolCallback, STREAM_CONTROLLER, STREAM_DEFAULTS, STREAM_INSTANCE, type SelectorTarget, type StreamApi, type StreamDefaults, StreamService, type StreamSubmitOptions, type SubagentDiscoverySnapshot, type SubgraphDiscoverySnapshot, type SubmissionQueueEntry, type SubmissionQueueSnapshot, type ThreadStream, type ToolCallFromTool, type ToolCallState, type ToolCallStatus, type ToolCallsFromTools, type ToolEvent, type UseStreamOptions, type UseStreamResult, type UseStreamReturn, type VideoMedia, type WidenUpdateMessages, executeHeadlessTool, filterOutHeadlessToolInterrupts, findHeadlessTool, flushPendingHeadlessToolInterrupts, handleHeadlessToolInterrupt, headlessToolResumeCommand, injectAudio, injectChannel, injectExtension, injectFiles, injectImages, injectMediaUrl, injectMessageMetadata, injectMessages, injectProjection, injectStream, injectSubmissionQueue, injectToolCalls, injectValues, injectVideo, isHeadlessToolInterrupt, parseHeadlessToolInterruptPayload, provideStream, provideStreamDefaults, useStream };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { AgentServerOptions, AnyStream, CustomAdapterOptions, STREAM_CONTROLLER,
|
|
1
|
+
import { AgentServerOptions, AnyStream, CustomAdapterOptions, STREAM_CONTROLLER, StreamApi, ThreadStream, UseStreamOptions, UseStreamResult, UseStreamReturn, useStream } from "./use-stream.js";
|
|
2
2
|
import { injectStream } from "./inject-stream.js";
|
|
3
3
|
import { injectProjection } from "./inject-projection.js";
|
|
4
4
|
import { SelectorTarget, injectAudio, injectChannel, injectExtension, injectFiles, injectImages, injectMessages, injectToolCalls, injectValues, injectVideo } from "./selectors.js";
|
|
@@ -7,6 +7,6 @@ import { MessageMetadata, MessageMetadataMap, injectMessageMetadata } from "./se
|
|
|
7
7
|
import { injectMediaUrl } from "./inject-media-url.js";
|
|
8
8
|
import { STREAM_DEFAULTS, STREAM_INSTANCE, StreamDefaults, provideStream, provideStreamDefaults } from "./context.js";
|
|
9
9
|
import { StreamService } from "./stream-service.js";
|
|
10
|
-
import { AnyHeadlessToolImplementation, DefaultToolCall, FlushPendingHeadlessToolInterruptsOptions, HeadlessToolImplementation, HeadlessToolInterrupt, HttpAgentServerAdapter, HttpAgentServerAdapterOptions, OnToolCallback,
|
|
11
|
-
import { AgentServerAdapter, AnyMediaHandle, AssembledToolCall, AudioMedia, Channel, Event, FileMedia, ImageMedia, InferStateType, InferSubagentStates, InferToolCalls, MediaAssemblyError, MediaAssemblyErrorKind, MediaBase, MediaBlockType, StreamSubmitOptions, SubagentDiscoverySnapshot, SubgraphDiscoverySnapshot, ToolCallStatus, VideoMedia, WidenUpdateMessages } from "@langchain/langgraph-sdk/stream";
|
|
12
|
-
export { type AgentServerAdapter, type AgentServerOptions, type AnyHeadlessToolImplementation, type AnyMediaHandle, type AnyStream, type AssembledToolCall, type AudioMedia, type Channel, type CustomAdapterOptions, type DefaultToolCall, type Event, type FileMedia, type FlushPendingHeadlessToolInterruptsOptions, type HeadlessToolImplementation, type HeadlessToolInterrupt, HttpAgentServerAdapter, type HttpAgentServerAdapterOptions, type ImageMedia, type InferStateType, type InferSubagentStates, type InferToolCalls, type InjectSubmissionQueueReturn, MediaAssemblyError, type MediaAssemblyErrorKind, type MediaBase, type MediaBlockType, type MessageMetadata, type MessageMetadataMap, type OnToolCallback, STREAM_CONTROLLER, STREAM_DEFAULTS, STREAM_INSTANCE, type SelectorTarget, type
|
|
10
|
+
import { AnyHeadlessToolImplementation, DefaultToolCall, FlushPendingHeadlessToolInterruptsOptions, HeadlessToolImplementation, HeadlessToolInterrupt, HttpAgentServerAdapter, HttpAgentServerAdapterOptions, OnToolCallback, ToolCallState, ToolCallsFromTools, ToolEvent, executeHeadlessTool, filterOutHeadlessToolInterrupts, findHeadlessTool, flushPendingHeadlessToolInterrupts, handleHeadlessToolInterrupt, headlessToolResumeCommand, isHeadlessToolInterrupt, parseHeadlessToolInterruptPayload } from "@langchain/langgraph-sdk";
|
|
11
|
+
import { AgentServerAdapter, AnyMediaHandle, AssembledToolCall, AssembledToolCallFromTool as ToolCallFromTool, AudioMedia, Channel, Event, FileMedia, ImageMedia, InferStateType, InferSubagentStates, InferToolCalls, MediaAssemblyError, MediaAssemblyErrorKind, MediaBase, MediaBlockType, StreamSubmitOptions, SubagentDiscoverySnapshot, SubgraphDiscoverySnapshot, ToolCallStatus, VideoMedia, WidenUpdateMessages } from "@langchain/langgraph-sdk/stream";
|
|
12
|
+
export { type AgentServerAdapter, type AgentServerOptions, type AnyHeadlessToolImplementation, type AnyMediaHandle, type AnyStream, type AssembledToolCall, type AudioMedia, type Channel, type CustomAdapterOptions, type DefaultToolCall, type Event, type FileMedia, type FlushPendingHeadlessToolInterruptsOptions, type HeadlessToolImplementation, type HeadlessToolInterrupt, HttpAgentServerAdapter, type HttpAgentServerAdapterOptions, type ImageMedia, type InferStateType, type InferSubagentStates, type InferToolCalls, type InjectSubmissionQueueReturn, MediaAssemblyError, type MediaAssemblyErrorKind, type MediaBase, type MediaBlockType, type MessageMetadata, type MessageMetadataMap, type OnToolCallback, STREAM_CONTROLLER, STREAM_DEFAULTS, STREAM_INSTANCE, type SelectorTarget, type StreamApi, type StreamDefaults, StreamService, type StreamSubmitOptions, type SubagentDiscoverySnapshot, type SubgraphDiscoverySnapshot, type SubmissionQueueEntry, type SubmissionQueueSnapshot, type ThreadStream, type ToolCallFromTool, type ToolCallState, type ToolCallStatus, type ToolCallsFromTools, type ToolEvent, type UseStreamOptions, type UseStreamResult, type UseStreamReturn, type VideoMedia, type WidenUpdateMessages, executeHeadlessTool, filterOutHeadlessToolInterrupts, findHeadlessTool, flushPendingHeadlessToolInterrupts, handleHeadlessToolInterrupt, headlessToolResumeCommand, injectAudio, injectChannel, injectExtension, injectFiles, injectImages, injectMediaUrl, injectMessageMetadata, injectMessages, injectProjection, injectStream, injectSubmissionQueue, injectToolCalls, injectValues, injectVideo, isHeadlessToolInterrupt, parseHeadlessToolInterruptPayload, provideStream, provideStreamDefaults, useStream };
|
package/dist/selectors.cjs
CHANGED
|
@@ -58,11 +58,6 @@ function injectMessages(stream, target) {
|
|
|
58
58
|
return (0, _angular_core.computed)(() => isRootSignal() ? stream.messages() : scoped());
|
|
59
59
|
}
|
|
60
60
|
const EMPTY_MESSAGES = [];
|
|
61
|
-
/**
|
|
62
|
-
* Subscribe to a scoped `tools` (tool-call) stream. Same target and
|
|
63
|
-
* lifecycle rules as {@link injectMessages}; at the root this returns
|
|
64
|
-
* `stream.toolCalls` directly.
|
|
65
|
-
*/
|
|
66
61
|
function injectToolCalls(stream, target) {
|
|
67
62
|
const { namespace, key, isRootSignal } = normalizeTarget(target, "toolCalls");
|
|
68
63
|
const scoped = require_inject_projection.injectProjection((0, _angular_core.computed)(() => isRootSignal() ? null : require_use_stream.getRegistry(stream)), () => (0, _langchain_langgraph_sdk_stream.toolCallsProjection)(namespace()), key, EMPTY_TOOLCALLS);
|
package/dist/selectors.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"selectors.cjs","names":["NAMESPACE_SEPARATOR","injectProjection","getRegistry"],"sources":["../src/selectors.ts"],"sourcesContent":["import { computed, isSignal, type Signal } from \"@angular/core\";\nimport type { BaseMessage } from \"@langchain/core/messages\";\nimport {\n NAMESPACE_SEPARATOR,\n audioProjection,\n channelProjection,\n extensionProjection,\n filesProjection,\n imagesProjection,\n messagesProjection,\n toolCallsProjection,\n valuesProjection,\n videoProjection,\n type AssembledToolCall,\n type AudioMedia,\n type Channel,\n type ChannelProjectionOptions,\n type Event,\n type FileMedia,\n type ImageMedia,\n type InferStateType,\n type SubagentDiscoverySnapshot,\n type SubgraphDiscoverySnapshot,\n type VideoMedia,\n} from \"@langchain/langgraph-sdk/stream\";\nimport {\n getRegistry,\n type AnyStream,\n type UseStreamReturn,\n} from \"./use-stream.js\";\nimport { injectProjection } from \"./inject-projection.js\";\n\n/**\n * Selector primitives don't need to carry `InterruptType` /\n * `ConfigurableType`. Parameterising on `StateType` alone lets\n * callers with a full `injectStream<S, I, C>()` handle pass it in\n * without redeclaring those generics at every call site.\n */\ntype StreamHandle<StateType extends object> = UseStreamReturn<\n StateType,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n any,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n any\n>;\n\n/**\n * What a selector primitive can be targeted at. Callers can pass:\n * - `undefined` / `null` — root namespace (served by the always-on\n * root store — no extra subscription);\n * - a {@link SubagentDiscoverySnapshot} (`stream.subagents().get(...)`);\n * - a {@link SubgraphDiscoverySnapshot} (`stream.subgraphs().get(...)`);\n * - an explicit `{ namespace: string[] }`;\n * - a raw `string[]` escape hatch.\n *\n * Selectors also accept a `Signal<SelectorTarget>` so callers can\n * feed a `computed(() => ...)` and have the projection rebind\n * automatically.\n */\nexport type SelectorTarget =\n | undefined\n | null\n | readonly string[]\n | { namespace: readonly string[] }\n | SubagentDiscoverySnapshot\n | SubgraphDiscoverySnapshot;\n\nconst EMPTY_NAMESPACE: readonly string[] = [];\n\nfunction resolveNamespace(target: SelectorTarget): readonly string[] {\n if (target == null) return EMPTY_NAMESPACE;\n if (Array.isArray(target)) return target as readonly string[];\n const obj = target as { namespace?: readonly string[] };\n return obj.namespace ?? EMPTY_NAMESPACE;\n}\n\nfunction isRoot(namespace: readonly string[]): boolean {\n return namespace.length === 0;\n}\n\nfunction namespaceKey(namespace: readonly string[]): string {\n return namespace.join(NAMESPACE_SEPARATOR);\n}\n\n/**\n * Resolve a target or target-signal into a reactive\n * `[namespace, key]` pair. The helper returns plain signals so\n * `injectProjection` can track them via its internal effect.\n */\nfunction normalizeTarget(\n target: SelectorTarget | Signal<SelectorTarget>,\n prefix: string\n): {\n namespace: Signal<readonly string[]>;\n key: Signal<string>;\n isRootSignal: Signal<boolean>;\n} {\n if (isSignal(target)) {\n const namespace = computed(() =>\n resolveNamespace((target as Signal<SelectorTarget>)())\n );\n const key = computed(() => `${prefix}|${namespaceKey(namespace())}`);\n const isRootSignal = computed(() => isRoot(namespace()));\n return { namespace, key, isRootSignal };\n }\n const ns = resolveNamespace(target as SelectorTarget);\n const staticKey = `${prefix}|${namespaceKey(ns)}`;\n return {\n namespace: computed(() => ns),\n key: computed(() => staticKey),\n isRootSignal: computed(() => isRoot(ns)),\n };\n}\n\n/**\n * Subscribe to a scoped `messages` stream.\n *\n * Contract:\n * - At the root (no `target`) this returns `stream.messages` — the\n * always-on root projection; no extra subscription is opened.\n * - For any non-root namespace, call-time triggers a ref-counted\n * `messages` subscription scoped to that namespace. The\n * subscription is released automatically when the calling\n * component / service is destroyed (and the registry closes the\n * underlying server subscription when the last consumer leaves).\n *\n * Messages are always `BaseMessage` class instances from\n * `@langchain/core/messages`.\n */\nexport function injectMessages(\n stream: AnyStream,\n target?: SelectorTarget | Signal<SelectorTarget>\n): Signal<BaseMessage[]> {\n const { namespace, key, isRootSignal } = normalizeTarget(\n target as SelectorTarget | Signal<SelectorTarget>,\n \"messages\"\n );\n const registry = computed(() =>\n isRootSignal() ? null : getRegistry(stream)\n );\n const scoped = injectProjection<BaseMessage[]>(\n registry,\n () => messagesProjection(namespace()),\n key,\n EMPTY_MESSAGES\n );\n return computed(() => (isRootSignal() ? stream.messages() : scoped()));\n}\n\nconst EMPTY_MESSAGES: BaseMessage[] = [];\n\n/**\n * Subscribe to a scoped `tools` (tool-call) stream. Same target and\n * lifecycle rules as {@link injectMessages}; at the root this returns\n * `stream.toolCalls` directly.\n */\nexport function injectToolCalls(\n stream: AnyStream,\n target?: SelectorTarget | Signal<SelectorTarget>\n): Signal<AssembledToolCall[]> {\n const { namespace, key, isRootSignal } = normalizeTarget(\n target as SelectorTarget | Signal<SelectorTarget>,\n \"toolCalls\"\n );\n const registry = computed(() =>\n isRootSignal() ? null : getRegistry(stream)\n );\n const scoped = injectProjection<AssembledToolCall[]>(\n registry,\n () => toolCallsProjection(namespace()),\n key,\n EMPTY_TOOLCALLS\n );\n return computed(() => (isRootSignal() ? stream.toolCalls() : scoped()));\n}\n\nconst EMPTY_TOOLCALLS: AssembledToolCall[] = [];\n\n/**\n * Subscribe to a scoped `values` stream — the most recent state\n * payload for a namespace. At the root returns `stream.values`.\n *\n * Typing:\n * - **Root** (`injectValues(stream)`): returns the `StateType`\n * declared on `injectStream<State>()` — non-nullable (the root\n * snapshot always has values, falling back to `initialValues ??\n * {}`).\n * - **Scoped** (`injectValues(stream, target)`): scoped payloads can\n * differ from the root state; callers should annotate the expected\n * shape explicitly (`injectValues<SubagentState>(stream, sub)`).\n * Defaults to `unknown` when not annotated.\n */\nexport function injectValues<StateType extends object>(\n stream: StreamHandle<StateType>\n): Signal<StateType>;\nexport function injectValues<T>(stream: AnyStream): Signal<InferStateType<T>>;\nexport function injectValues<T = unknown>(\n stream: AnyStream,\n target: SelectorTarget | Signal<SelectorTarget>,\n options?: { messagesKey?: string }\n): Signal<T | undefined>;\nexport function injectValues(\n stream: AnyStream,\n target?: SelectorTarget | Signal<SelectorTarget>,\n options?: { messagesKey?: string }\n): Signal<unknown> {\n const messagesKey = options?.messagesKey ?? \"messages\";\n const { namespace, key, isRootSignal } = normalizeTarget(\n target as SelectorTarget | Signal<SelectorTarget>,\n `values|${messagesKey}`\n );\n const registry = computed(() =>\n isRootSignal() ? null : getRegistry(stream)\n );\n const scoped = injectProjection<unknown>(\n registry,\n () => valuesProjection<unknown>(namespace(), messagesKey),\n key,\n undefined\n );\n return computed(() => (isRootSignal() ? stream.values() : scoped()));\n}\n\n/**\n * Subscribe to a `custom:<name>` stream extension — the most recent\n * payload emitted by the transformer, scoped to the target namespace.\n */\nexport function injectExtension<T = unknown>(\n stream: AnyStream,\n name: string,\n target?: SelectorTarget | Signal<SelectorTarget>\n): Signal<T | undefined> {\n const { namespace, key } = normalizeTarget(\n target as SelectorTarget | Signal<SelectorTarget>,\n `extension|${name}`\n );\n return injectProjection<T | undefined>(\n getRegistry(stream),\n () => extensionProjection<T>(name, namespace()),\n key,\n undefined\n );\n}\n\n/**\n * Raw-events escape hatch. Subscribes to one or more channels at a\n * namespace and returns a bounded buffer of raw protocol events.\n * Prefer {@link injectMessages} / {@link injectToolCalls} /\n * {@link injectValues} for the common cases.\n */\nexport type InjectChannelOptions = ChannelProjectionOptions;\n\nexport function injectChannel(\n stream: AnyStream,\n channels: readonly Channel[],\n target?: SelectorTarget | Signal<SelectorTarget>,\n options?: InjectChannelOptions\n): Signal<Event[]> {\n const sortedChannels = [...channels].sort().join(\",\");\n const prefix = `channel|${options?.bufferSize ?? \"default\"}|${(options?.replay ?? true) ? \"replay\" : \"live\"}|${sortedChannels}`;\n const { namespace, key } = normalizeTarget(\n target as SelectorTarget | Signal<SelectorTarget>,\n prefix\n );\n return injectProjection<Event[]>(\n getRegistry(stream),\n () => channelProjection(channels, namespace(), options),\n key,\n EMPTY_EVENTS\n );\n}\n\nconst EMPTY_EVENTS: Event[] = [];\n\n/**\n * Subscribe to a scoped audio-media stream. Each handle is yielded\n * on its first matching `content-block-start`, exposes\n * `.partialBytes` for live access, settles `.blob` / `.objectURL` /\n * `.transcript` on `message-finish`, and surfaces errors via\n * `.error`.\n *\n * Pair with `injectMediaUrl` to turn a handle into an `<audio src>`.\n */\nexport function injectAudio(\n stream: AnyStream,\n target?: SelectorTarget | Signal<SelectorTarget>\n): Signal<AudioMedia[]> {\n const { namespace, key } = normalizeTarget(\n target as SelectorTarget | Signal<SelectorTarget>,\n \"audio\"\n );\n return injectProjection<AudioMedia[]>(\n getRegistry(stream),\n () => audioProjection(namespace()),\n key,\n EMPTY_AUDIO\n );\n}\n\nconst EMPTY_AUDIO: AudioMedia[] = [];\n\n/**\n * Subscribe to a scoped image-media stream. Pair with\n * `injectMediaUrl` for `<img src>`.\n */\nexport function injectImages(\n stream: AnyStream,\n target?: SelectorTarget | Signal<SelectorTarget>\n): Signal<ImageMedia[]> {\n const { namespace, key } = normalizeTarget(\n target as SelectorTarget | Signal<SelectorTarget>,\n \"images\"\n );\n return injectProjection<ImageMedia[]>(\n getRegistry(stream),\n () => imagesProjection(namespace()),\n key,\n EMPTY_IMAGES\n );\n}\n\nconst EMPTY_IMAGES: ImageMedia[] = [];\n\n/**\n * Subscribe to a scoped video-media stream. Pair with\n * `injectMediaUrl` for `<video src>`.\n */\nexport function injectVideo(\n stream: AnyStream,\n target?: SelectorTarget | Signal<SelectorTarget>\n): Signal<VideoMedia[]> {\n const { namespace, key } = normalizeTarget(\n target as SelectorTarget | Signal<SelectorTarget>,\n \"video\"\n );\n return injectProjection<VideoMedia[]>(\n getRegistry(stream),\n () => videoProjection(namespace()),\n key,\n EMPTY_VIDEO\n );\n}\n\nconst EMPTY_VIDEO: VideoMedia[] = [];\n\n/**\n * Subscribe to a scoped file-media stream. Pair with\n * `injectMediaUrl` for an `<a download href>` target.\n */\nexport function injectFiles(\n stream: AnyStream,\n target?: SelectorTarget | Signal<SelectorTarget>\n): Signal<FileMedia[]> {\n const { namespace, key } = normalizeTarget(\n target as SelectorTarget | Signal<SelectorTarget>,\n \"files\"\n );\n return injectProjection<FileMedia[]>(\n getRegistry(stream),\n () => filesProjection(namespace()),\n key,\n EMPTY_FILES\n );\n}\n\nconst EMPTY_FILES: FileMedia[] = [];\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"selectors.cjs","names":["NAMESPACE_SEPARATOR","injectProjection","getRegistry"],"sources":["../src/selectors.ts"],"sourcesContent":["import { computed, isSignal, type Signal } from \"@angular/core\";\nimport type { BaseMessage } from \"@langchain/core/messages\";\nimport {\n NAMESPACE_SEPARATOR,\n audioProjection,\n channelProjection,\n extensionProjection,\n filesProjection,\n imagesProjection,\n messagesProjection,\n toolCallsProjection,\n valuesProjection,\n videoProjection,\n type AssembledToolCall,\n type AudioMedia,\n type Channel,\n type ChannelProjectionOptions,\n type Event,\n type FileMedia,\n type ImageMedia,\n type InferToolCalls,\n type InferStateType,\n type SubagentDiscoverySnapshot,\n type SubgraphDiscoverySnapshot,\n type VideoMedia,\n} from \"@langchain/langgraph-sdk/stream\";\nimport {\n getRegistry,\n type AnyStream,\n type UseStreamReturn,\n} from \"./use-stream.js\";\nimport { injectProjection } from \"./inject-projection.js\";\n\n/**\n * Selector primitives don't need to carry `InterruptType` /\n * `ConfigurableType`. Parameterising on `StateType` alone lets\n * callers with a full `injectStream<S, I, C>()` handle pass it in\n * without redeclaring those generics at every call site.\n */\ntype StreamHandle<StateType extends object> = UseStreamReturn<\n StateType,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n any,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n any\n>;\n\n/**\n * What a selector primitive can be targeted at. Callers can pass:\n * - `undefined` / `null` — root namespace (served by the always-on\n * root store — no extra subscription);\n * - a {@link SubagentDiscoverySnapshot} (`stream.subagents().get(...)`);\n * - a {@link SubgraphDiscoverySnapshot} (`stream.subgraphs().get(...)`);\n * - an explicit `{ namespace: string[] }`;\n * - a raw `string[]` escape hatch.\n *\n * Selectors also accept a `Signal<SelectorTarget>` so callers can\n * feed a `computed(() => ...)` and have the projection rebind\n * automatically.\n */\nexport type SelectorTarget =\n | undefined\n | null\n | readonly string[]\n | { namespace: readonly string[] }\n | SubagentDiscoverySnapshot\n | SubgraphDiscoverySnapshot;\n\nconst EMPTY_NAMESPACE: readonly string[] = [];\n\nfunction resolveNamespace(target: SelectorTarget): readonly string[] {\n if (target == null) return EMPTY_NAMESPACE;\n if (Array.isArray(target)) return target as readonly string[];\n const obj = target as { namespace?: readonly string[] };\n return obj.namespace ?? EMPTY_NAMESPACE;\n}\n\nfunction isRoot(namespace: readonly string[]): boolean {\n return namespace.length === 0;\n}\n\nfunction namespaceKey(namespace: readonly string[]): string {\n return namespace.join(NAMESPACE_SEPARATOR);\n}\n\n/**\n * Resolve a target or target-signal into a reactive\n * `[namespace, key]` pair. The helper returns plain signals so\n * `injectProjection` can track them via its internal effect.\n */\nfunction normalizeTarget(\n target: SelectorTarget | Signal<SelectorTarget>,\n prefix: string\n): {\n namespace: Signal<readonly string[]>;\n key: Signal<string>;\n isRootSignal: Signal<boolean>;\n} {\n if (isSignal(target)) {\n const namespace = computed(() =>\n resolveNamespace((target as Signal<SelectorTarget>)())\n );\n const key = computed(() => `${prefix}|${namespaceKey(namespace())}`);\n const isRootSignal = computed(() => isRoot(namespace()));\n return { namespace, key, isRootSignal };\n }\n const ns = resolveNamespace(target as SelectorTarget);\n const staticKey = `${prefix}|${namespaceKey(ns)}`;\n return {\n namespace: computed(() => ns),\n key: computed(() => staticKey),\n isRootSignal: computed(() => isRoot(ns)),\n };\n}\n\n/**\n * Subscribe to a scoped `messages` stream.\n *\n * Contract:\n * - At the root (no `target`) this returns `stream.messages` — the\n * always-on root projection; no extra subscription is opened.\n * - For any non-root namespace, call-time triggers a ref-counted\n * `messages` subscription scoped to that namespace. The\n * subscription is released automatically when the calling\n * component / service is destroyed (and the registry closes the\n * underlying server subscription when the last consumer leaves).\n *\n * Messages are always `BaseMessage` class instances from\n * `@langchain/core/messages`.\n */\nexport function injectMessages(\n stream: AnyStream,\n target?: SelectorTarget | Signal<SelectorTarget>\n): Signal<BaseMessage[]> {\n const { namespace, key, isRootSignal } = normalizeTarget(\n target as SelectorTarget | Signal<SelectorTarget>,\n \"messages\"\n );\n const registry = computed(() =>\n isRootSignal() ? null : getRegistry(stream)\n );\n const scoped = injectProjection<BaseMessage[]>(\n registry,\n () => messagesProjection(namespace()),\n key,\n EMPTY_MESSAGES\n );\n return computed(() => (isRootSignal() ? stream.messages() : scoped()));\n}\n\nconst EMPTY_MESSAGES: BaseMessage[] = [];\n\n/**\n * Subscribe to a scoped `tools` (tool-call) stream. Same target and\n * lifecycle rules as {@link injectMessages}; at the root this returns\n * `stream.toolCalls` directly.\n */\nexport function injectToolCalls(\n stream: AnyStream,\n target?: SelectorTarget | Signal<SelectorTarget>\n): Signal<AssembledToolCall[]>;\nexport function injectToolCalls<T>(\n stream: AnyStream,\n target?: SelectorTarget | Signal<SelectorTarget>\n): Signal<InferToolCalls<T>[]>;\nexport function injectToolCalls(\n stream: AnyStream,\n target?: SelectorTarget | Signal<SelectorTarget>\n): Signal<AssembledToolCall[]> {\n const { namespace, key, isRootSignal } = normalizeTarget(\n target as SelectorTarget | Signal<SelectorTarget>,\n \"toolCalls\"\n );\n const registry = computed(() =>\n isRootSignal() ? null : getRegistry(stream)\n );\n const scoped = injectProjection<AssembledToolCall[]>(\n registry,\n () => toolCallsProjection(namespace()),\n key,\n EMPTY_TOOLCALLS\n );\n return computed(() => (isRootSignal() ? stream.toolCalls() : scoped()));\n}\n\nconst EMPTY_TOOLCALLS: AssembledToolCall[] = [];\n\n/**\n * Subscribe to a scoped `values` stream — the most recent state\n * payload for a namespace. At the root returns `stream.values`.\n *\n * Typing:\n * - **Root** (`injectValues(stream)`): returns the `StateType`\n * declared on `injectStream<State>()` — non-nullable (the root\n * snapshot always has values, falling back to `initialValues ??\n * {}`).\n * - **Scoped** (`injectValues(stream, target)`): scoped payloads can\n * differ from the root state; callers should annotate the expected\n * shape explicitly (`injectValues<SubagentState>(stream, sub)`).\n * Defaults to `unknown` when not annotated.\n */\nexport function injectValues<StateType extends object>(\n stream: StreamHandle<StateType>\n): Signal<StateType>;\nexport function injectValues<T>(stream: AnyStream): Signal<InferStateType<T>>;\nexport function injectValues<T = unknown>(\n stream: AnyStream,\n target: SelectorTarget | Signal<SelectorTarget>,\n options?: { messagesKey?: string }\n): Signal<T | undefined>;\nexport function injectValues(\n stream: AnyStream,\n target?: SelectorTarget | Signal<SelectorTarget>,\n options?: { messagesKey?: string }\n): Signal<unknown> {\n const messagesKey = options?.messagesKey ?? \"messages\";\n const { namespace, key, isRootSignal } = normalizeTarget(\n target as SelectorTarget | Signal<SelectorTarget>,\n `values|${messagesKey}`\n );\n const registry = computed(() =>\n isRootSignal() ? null : getRegistry(stream)\n );\n const scoped = injectProjection<unknown>(\n registry,\n () => valuesProjection<unknown>(namespace(), messagesKey),\n key,\n undefined\n );\n return computed(() => (isRootSignal() ? stream.values() : scoped()));\n}\n\n/**\n * Subscribe to a `custom:<name>` stream extension — the most recent\n * payload emitted by the transformer, scoped to the target namespace.\n */\nexport function injectExtension<T = unknown>(\n stream: AnyStream,\n name: string,\n target?: SelectorTarget | Signal<SelectorTarget>\n): Signal<T | undefined> {\n const { namespace, key } = normalizeTarget(\n target as SelectorTarget | Signal<SelectorTarget>,\n `extension|${name}`\n );\n return injectProjection<T | undefined>(\n getRegistry(stream),\n () => extensionProjection<T>(name, namespace()),\n key,\n undefined\n );\n}\n\n/**\n * Raw-events escape hatch. Subscribes to one or more channels at a\n * namespace and returns a bounded buffer of raw protocol events.\n * Prefer {@link injectMessages} / {@link injectToolCalls} /\n * {@link injectValues} for the common cases.\n */\nexport type InjectChannelOptions = ChannelProjectionOptions;\n\nexport function injectChannel(\n stream: AnyStream,\n channels: readonly Channel[],\n target?: SelectorTarget | Signal<SelectorTarget>,\n options?: InjectChannelOptions\n): Signal<Event[]> {\n const sortedChannels = [...channels].sort().join(\",\");\n const prefix = `channel|${options?.bufferSize ?? \"default\"}|${(options?.replay ?? true) ? \"replay\" : \"live\"}|${sortedChannels}`;\n const { namespace, key } = normalizeTarget(\n target as SelectorTarget | Signal<SelectorTarget>,\n prefix\n );\n return injectProjection<Event[]>(\n getRegistry(stream),\n () => channelProjection(channels, namespace(), options),\n key,\n EMPTY_EVENTS\n );\n}\n\nconst EMPTY_EVENTS: Event[] = [];\n\n/**\n * Subscribe to a scoped audio-media stream. Each handle is yielded\n * on its first matching `content-block-start`, exposes\n * `.partialBytes` for live access, settles `.blob` / `.objectURL` /\n * `.transcript` on `message-finish`, and surfaces errors via\n * `.error`.\n *\n * Pair with `injectMediaUrl` to turn a handle into an `<audio src>`.\n */\nexport function injectAudio(\n stream: AnyStream,\n target?: SelectorTarget | Signal<SelectorTarget>\n): Signal<AudioMedia[]> {\n const { namespace, key } = normalizeTarget(\n target as SelectorTarget | Signal<SelectorTarget>,\n \"audio\"\n );\n return injectProjection<AudioMedia[]>(\n getRegistry(stream),\n () => audioProjection(namespace()),\n key,\n EMPTY_AUDIO\n );\n}\n\nconst EMPTY_AUDIO: AudioMedia[] = [];\n\n/**\n * Subscribe to a scoped image-media stream. Pair with\n * `injectMediaUrl` for `<img src>`.\n */\nexport function injectImages(\n stream: AnyStream,\n target?: SelectorTarget | Signal<SelectorTarget>\n): Signal<ImageMedia[]> {\n const { namespace, key } = normalizeTarget(\n target as SelectorTarget | Signal<SelectorTarget>,\n \"images\"\n );\n return injectProjection<ImageMedia[]>(\n getRegistry(stream),\n () => imagesProjection(namespace()),\n key,\n EMPTY_IMAGES\n );\n}\n\nconst EMPTY_IMAGES: ImageMedia[] = [];\n\n/**\n * Subscribe to a scoped video-media stream. Pair with\n * `injectMediaUrl` for `<video src>`.\n */\nexport function injectVideo(\n stream: AnyStream,\n target?: SelectorTarget | Signal<SelectorTarget>\n): Signal<VideoMedia[]> {\n const { namespace, key } = normalizeTarget(\n target as SelectorTarget | Signal<SelectorTarget>,\n \"video\"\n );\n return injectProjection<VideoMedia[]>(\n getRegistry(stream),\n () => videoProjection(namespace()),\n key,\n EMPTY_VIDEO\n );\n}\n\nconst EMPTY_VIDEO: VideoMedia[] = [];\n\n/**\n * Subscribe to a scoped file-media stream. Pair with\n * `injectMediaUrl` for an `<a download href>` target.\n */\nexport function injectFiles(\n stream: AnyStream,\n target?: SelectorTarget | Signal<SelectorTarget>\n): Signal<FileMedia[]> {\n const { namespace, key } = normalizeTarget(\n target as SelectorTarget | Signal<SelectorTarget>,\n \"files\"\n );\n return injectProjection<FileMedia[]>(\n getRegistry(stream),\n () => filesProjection(namespace()),\n key,\n EMPTY_FILES\n );\n}\n\nconst EMPTY_FILES: FileMedia[] = [];\n"],"mappings":"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"}
|
package/dist/selectors.d.cts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { AnyStream, UseStreamReturn } from "./use-stream.cjs";
|
|
2
|
-
import { AssembledToolCall, AudioMedia, Channel, ChannelProjectionOptions, Event, FileMedia, ImageMedia, InferStateType, SubagentDiscoverySnapshot, SubgraphDiscoverySnapshot, VideoMedia } from "@langchain/langgraph-sdk/stream";
|
|
2
|
+
import { AssembledToolCall, AudioMedia, Channel, ChannelProjectionOptions, Event, FileMedia, ImageMedia, InferStateType, InferToolCalls, SubagentDiscoverySnapshot, SubgraphDiscoverySnapshot, VideoMedia } from "@langchain/langgraph-sdk/stream";
|
|
3
3
|
import { Signal } from "@angular/core";
|
|
4
4
|
import { BaseMessage } from "@langchain/core/messages";
|
|
5
5
|
|
|
@@ -49,6 +49,7 @@ declare function injectMessages(stream: AnyStream, target?: SelectorTarget | Sig
|
|
|
49
49
|
* `stream.toolCalls` directly.
|
|
50
50
|
*/
|
|
51
51
|
declare function injectToolCalls(stream: AnyStream, target?: SelectorTarget | Signal<SelectorTarget>): Signal<AssembledToolCall[]>;
|
|
52
|
+
declare function injectToolCalls<T>(stream: AnyStream, target?: SelectorTarget | Signal<SelectorTarget>): Signal<InferToolCalls<T>[]>;
|
|
52
53
|
/**
|
|
53
54
|
* Subscribe to a scoped `values` stream — the most recent state
|
|
54
55
|
* payload for a namespace. At the root returns `stream.values`.
|
package/dist/selectors.d.cts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"selectors.d.cts","names":[],"sources":["../src/selectors.ts"],"mappings":";;;;;;;;
|
|
1
|
+
{"version":3,"file":"selectors.d.cts","names":[],"sources":["../src/selectors.ts"],"mappings":";;;;;;;;AA8ByB;;;;KASpB,YAAA,6BAAyC,eAAA,CAC5C,SAAA;;;;;AAoBF;;;;;;;;;KAAY,cAAA;EAIN,SAAA;AAAA,IACF,yBAAA,GACA,yBAAA;;;;;;;;;;;;;;;;iBAgEY,cAAA,CACd,MAAA,EAAQ,SAAA,EACR,MAAA,GAAS,cAAA,GAAiB,MAAA,CAAO,cAAA,IAChC,MAAA,CAAO,WAAA;;;AAwBV;;;iBAAgB,eAAA,CACd,MAAA,EAAQ,SAAA,EACR,MAAA,GAAS,cAAA,GAAiB,MAAA,CAAO,cAAA,IAChC,MAAA,CAAO,iBAAA;AAAA,iBACM,eAAA,GAAA,CACd,MAAA,EAAQ,SAAA,EACR,MAAA,GAAS,cAAA,GAAiB,MAAA,CAAO,cAAA,IAChC,MAAA,CAAO,cAAA,CAAe,CAAA;;;;;;;;;;;;;;;iBAqCT,YAAA,0BAAA,CACd,MAAA,EAAQ,YAAA,CAAa,SAAA,IACpB,MAAA,CAAO,SAAA;AAAA,iBACM,YAAA,GAAA,CAAgB,MAAA,EAAQ,SAAA,GAAY,MAAA,CAAO,cAAA,CAAe,CAAA;AAAA,iBAC1D,YAAA,aAAA,CACd,MAAA,EAAQ,SAAA,EACR,MAAA,EAAQ,cAAA,GAAiB,MAAA,CAAO,cAAA,GAChC,OAAA;EAAY,WAAA;AAAA,IACX,MAAA,CAAO,CAAA;;;;;iBA2BM,eAAA,aAAA,CACd,MAAA,EAAQ,SAAA,EACR,IAAA,UACA,MAAA,GAAS,cAAA,GAAiB,MAAA,CAAO,cAAA,IAChC,MAAA,CAAO,CAAA;;;;;;;KAmBE,oBAAA,GAAuB,wBAAA;AAAA,iBAEnB,aAAA,CACd,MAAA,EAAQ,SAAA,EACR,QAAA,WAAmB,OAAA,IACnB,MAAA,GAAS,cAAA,GAAiB,MAAA,CAAO,cAAA,GACjC,OAAA,GAAU,oBAAA,GACT,MAAA,CAAO,KAAA;;;;;;;;;AAjEV;iBA2FgB,WAAA,CACd,MAAA,EAAQ,SAAA,EACR,MAAA,GAAS,cAAA,GAAiB,MAAA,CAAO,cAAA,IAChC,MAAA,CAAO,UAAA;;;;;iBAmBM,YAAA,CACd,MAAA,EAAQ,SAAA,EACR,MAAA,GAAS,cAAA,GAAiB,MAAA,CAAO,cAAA,IAChC,MAAA,CAAO,UAAA;;;;;iBAmBM,WAAA,CACd,MAAA,EAAQ,SAAA,EACR,MAAA,GAAS,cAAA,GAAiB,MAAA,CAAO,cAAA,IAChC,MAAA,CAAO,UAAA;;;;;iBAmBM,WAAA,CACd,MAAA,EAAQ,SAAA,EACR,MAAA,GAAS,cAAA,GAAiB,MAAA,CAAO,cAAA,IAChC,MAAA,CAAO,SAAA"}
|
package/dist/selectors.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { AnyStream, UseStreamReturn } from "./use-stream.js";
|
|
2
2
|
import { Signal } from "@angular/core";
|
|
3
|
-
import { AssembledToolCall, AudioMedia, Channel, ChannelProjectionOptions, Event, FileMedia, ImageMedia, InferStateType, SubagentDiscoverySnapshot, SubgraphDiscoverySnapshot, VideoMedia } from "@langchain/langgraph-sdk/stream";
|
|
3
|
+
import { AssembledToolCall, AudioMedia, Channel, ChannelProjectionOptions, Event, FileMedia, ImageMedia, InferStateType, InferToolCalls, SubagentDiscoverySnapshot, SubgraphDiscoverySnapshot, VideoMedia } from "@langchain/langgraph-sdk/stream";
|
|
4
4
|
import { BaseMessage } from "@langchain/core/messages";
|
|
5
5
|
|
|
6
6
|
//#region src/selectors.d.ts
|
|
@@ -49,6 +49,7 @@ declare function injectMessages(stream: AnyStream, target?: SelectorTarget | Sig
|
|
|
49
49
|
* `stream.toolCalls` directly.
|
|
50
50
|
*/
|
|
51
51
|
declare function injectToolCalls(stream: AnyStream, target?: SelectorTarget | Signal<SelectorTarget>): Signal<AssembledToolCall[]>;
|
|
52
|
+
declare function injectToolCalls<T>(stream: AnyStream, target?: SelectorTarget | Signal<SelectorTarget>): Signal<InferToolCalls<T>[]>;
|
|
52
53
|
/**
|
|
53
54
|
* Subscribe to a scoped `values` stream — the most recent state
|
|
54
55
|
* payload for a namespace. At the root returns `stream.values`.
|
package/dist/selectors.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"selectors.d.ts","names":[],"sources":["../src/selectors.ts"],"mappings":";;;;;;;;
|
|
1
|
+
{"version":3,"file":"selectors.d.ts","names":[],"sources":["../src/selectors.ts"],"mappings":";;;;;;;;AA8ByB;;;;KASpB,YAAA,6BAAyC,eAAA,CAC5C,SAAA;;;;;AAoBF;;;;;;;;;KAAY,cAAA;EAIN,SAAA;AAAA,IACF,yBAAA,GACA,yBAAA;;;;;;;;;;;;;;;;iBAgEY,cAAA,CACd,MAAA,EAAQ,SAAA,EACR,MAAA,GAAS,cAAA,GAAiB,MAAA,CAAO,cAAA,IAChC,MAAA,CAAO,WAAA;;;AAwBV;;;iBAAgB,eAAA,CACd,MAAA,EAAQ,SAAA,EACR,MAAA,GAAS,cAAA,GAAiB,MAAA,CAAO,cAAA,IAChC,MAAA,CAAO,iBAAA;AAAA,iBACM,eAAA,GAAA,CACd,MAAA,EAAQ,SAAA,EACR,MAAA,GAAS,cAAA,GAAiB,MAAA,CAAO,cAAA,IAChC,MAAA,CAAO,cAAA,CAAe,CAAA;;;;;;;;;;;;;;;iBAqCT,YAAA,0BAAA,CACd,MAAA,EAAQ,YAAA,CAAa,SAAA,IACpB,MAAA,CAAO,SAAA;AAAA,iBACM,YAAA,GAAA,CAAgB,MAAA,EAAQ,SAAA,GAAY,MAAA,CAAO,cAAA,CAAe,CAAA;AAAA,iBAC1D,YAAA,aAAA,CACd,MAAA,EAAQ,SAAA,EACR,MAAA,EAAQ,cAAA,GAAiB,MAAA,CAAO,cAAA,GAChC,OAAA;EAAY,WAAA;AAAA,IACX,MAAA,CAAO,CAAA;;;;;iBA2BM,eAAA,aAAA,CACd,MAAA,EAAQ,SAAA,EACR,IAAA,UACA,MAAA,GAAS,cAAA,GAAiB,MAAA,CAAO,cAAA,IAChC,MAAA,CAAO,CAAA;;;;;;;KAmBE,oBAAA,GAAuB,wBAAA;AAAA,iBAEnB,aAAA,CACd,MAAA,EAAQ,SAAA,EACR,QAAA,WAAmB,OAAA,IACnB,MAAA,GAAS,cAAA,GAAiB,MAAA,CAAO,cAAA,GACjC,OAAA,GAAU,oBAAA,GACT,MAAA,CAAO,KAAA;;;;;;;;;AAjEV;iBA2FgB,WAAA,CACd,MAAA,EAAQ,SAAA,EACR,MAAA,GAAS,cAAA,GAAiB,MAAA,CAAO,cAAA,IAChC,MAAA,CAAO,UAAA;;;;;iBAmBM,YAAA,CACd,MAAA,EAAQ,SAAA,EACR,MAAA,GAAS,cAAA,GAAiB,MAAA,CAAO,cAAA,IAChC,MAAA,CAAO,UAAA;;;;;iBAmBM,WAAA,CACd,MAAA,EAAQ,SAAA,EACR,MAAA,GAAS,cAAA,GAAiB,MAAA,CAAO,cAAA,IAChC,MAAA,CAAO,UAAA;;;;;iBAmBM,WAAA,CACd,MAAA,EAAQ,SAAA,EACR,MAAA,GAAS,cAAA,GAAiB,MAAA,CAAO,cAAA,IAChC,MAAA,CAAO,SAAA"}
|
package/dist/selectors.js
CHANGED
|
@@ -58,11 +58,6 @@ function injectMessages(stream, target) {
|
|
|
58
58
|
return computed(() => isRootSignal() ? stream.messages() : scoped());
|
|
59
59
|
}
|
|
60
60
|
const EMPTY_MESSAGES = [];
|
|
61
|
-
/**
|
|
62
|
-
* Subscribe to a scoped `tools` (tool-call) stream. Same target and
|
|
63
|
-
* lifecycle rules as {@link injectMessages}; at the root this returns
|
|
64
|
-
* `stream.toolCalls` directly.
|
|
65
|
-
*/
|
|
66
61
|
function injectToolCalls(stream, target) {
|
|
67
62
|
const { namespace, key, isRootSignal } = normalizeTarget(target, "toolCalls");
|
|
68
63
|
const scoped = injectProjection(computed(() => isRootSignal() ? null : getRegistry(stream)), () => toolCallsProjection(namespace()), key, EMPTY_TOOLCALLS);
|
package/dist/selectors.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"selectors.js","names":[],"sources":["../src/selectors.ts"],"sourcesContent":["import { computed, isSignal, type Signal } from \"@angular/core\";\nimport type { BaseMessage } from \"@langchain/core/messages\";\nimport {\n NAMESPACE_SEPARATOR,\n audioProjection,\n channelProjection,\n extensionProjection,\n filesProjection,\n imagesProjection,\n messagesProjection,\n toolCallsProjection,\n valuesProjection,\n videoProjection,\n type AssembledToolCall,\n type AudioMedia,\n type Channel,\n type ChannelProjectionOptions,\n type Event,\n type FileMedia,\n type ImageMedia,\n type InferStateType,\n type SubagentDiscoverySnapshot,\n type SubgraphDiscoverySnapshot,\n type VideoMedia,\n} from \"@langchain/langgraph-sdk/stream\";\nimport {\n getRegistry,\n type AnyStream,\n type UseStreamReturn,\n} from \"./use-stream.js\";\nimport { injectProjection } from \"./inject-projection.js\";\n\n/**\n * Selector primitives don't need to carry `InterruptType` /\n * `ConfigurableType`. Parameterising on `StateType` alone lets\n * callers with a full `injectStream<S, I, C>()` handle pass it in\n * without redeclaring those generics at every call site.\n */\ntype StreamHandle<StateType extends object> = UseStreamReturn<\n StateType,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n any,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n any\n>;\n\n/**\n * What a selector primitive can be targeted at. Callers can pass:\n * - `undefined` / `null` — root namespace (served by the always-on\n * root store — no extra subscription);\n * - a {@link SubagentDiscoverySnapshot} (`stream.subagents().get(...)`);\n * - a {@link SubgraphDiscoverySnapshot} (`stream.subgraphs().get(...)`);\n * - an explicit `{ namespace: string[] }`;\n * - a raw `string[]` escape hatch.\n *\n * Selectors also accept a `Signal<SelectorTarget>` so callers can\n * feed a `computed(() => ...)` and have the projection rebind\n * automatically.\n */\nexport type SelectorTarget =\n | undefined\n | null\n | readonly string[]\n | { namespace: readonly string[] }\n | SubagentDiscoverySnapshot\n | SubgraphDiscoverySnapshot;\n\nconst EMPTY_NAMESPACE: readonly string[] = [];\n\nfunction resolveNamespace(target: SelectorTarget): readonly string[] {\n if (target == null) return EMPTY_NAMESPACE;\n if (Array.isArray(target)) return target as readonly string[];\n const obj = target as { namespace?: readonly string[] };\n return obj.namespace ?? EMPTY_NAMESPACE;\n}\n\nfunction isRoot(namespace: readonly string[]): boolean {\n return namespace.length === 0;\n}\n\nfunction namespaceKey(namespace: readonly string[]): string {\n return namespace.join(NAMESPACE_SEPARATOR);\n}\n\n/**\n * Resolve a target or target-signal into a reactive\n * `[namespace, key]` pair. The helper returns plain signals so\n * `injectProjection` can track them via its internal effect.\n */\nfunction normalizeTarget(\n target: SelectorTarget | Signal<SelectorTarget>,\n prefix: string\n): {\n namespace: Signal<readonly string[]>;\n key: Signal<string>;\n isRootSignal: Signal<boolean>;\n} {\n if (isSignal(target)) {\n const namespace = computed(() =>\n resolveNamespace((target as Signal<SelectorTarget>)())\n );\n const key = computed(() => `${prefix}|${namespaceKey(namespace())}`);\n const isRootSignal = computed(() => isRoot(namespace()));\n return { namespace, key, isRootSignal };\n }\n const ns = resolveNamespace(target as SelectorTarget);\n const staticKey = `${prefix}|${namespaceKey(ns)}`;\n return {\n namespace: computed(() => ns),\n key: computed(() => staticKey),\n isRootSignal: computed(() => isRoot(ns)),\n };\n}\n\n/**\n * Subscribe to a scoped `messages` stream.\n *\n * Contract:\n * - At the root (no `target`) this returns `stream.messages` — the\n * always-on root projection; no extra subscription is opened.\n * - For any non-root namespace, call-time triggers a ref-counted\n * `messages` subscription scoped to that namespace. The\n * subscription is released automatically when the calling\n * component / service is destroyed (and the registry closes the\n * underlying server subscription when the last consumer leaves).\n *\n * Messages are always `BaseMessage` class instances from\n * `@langchain/core/messages`.\n */\nexport function injectMessages(\n stream: AnyStream,\n target?: SelectorTarget | Signal<SelectorTarget>\n): Signal<BaseMessage[]> {\n const { namespace, key, isRootSignal } = normalizeTarget(\n target as SelectorTarget | Signal<SelectorTarget>,\n \"messages\"\n );\n const registry = computed(() =>\n isRootSignal() ? null : getRegistry(stream)\n );\n const scoped = injectProjection<BaseMessage[]>(\n registry,\n () => messagesProjection(namespace()),\n key,\n EMPTY_MESSAGES\n );\n return computed(() => (isRootSignal() ? stream.messages() : scoped()));\n}\n\nconst EMPTY_MESSAGES: BaseMessage[] = [];\n\n/**\n * Subscribe to a scoped `tools` (tool-call) stream. Same target and\n * lifecycle rules as {@link injectMessages}; at the root this returns\n * `stream.toolCalls` directly.\n */\nexport function injectToolCalls(\n stream: AnyStream,\n target?: SelectorTarget | Signal<SelectorTarget>\n): Signal<AssembledToolCall[]> {\n const { namespace, key, isRootSignal } = normalizeTarget(\n target as SelectorTarget | Signal<SelectorTarget>,\n \"toolCalls\"\n );\n const registry = computed(() =>\n isRootSignal() ? null : getRegistry(stream)\n );\n const scoped = injectProjection<AssembledToolCall[]>(\n registry,\n () => toolCallsProjection(namespace()),\n key,\n EMPTY_TOOLCALLS\n );\n return computed(() => (isRootSignal() ? stream.toolCalls() : scoped()));\n}\n\nconst EMPTY_TOOLCALLS: AssembledToolCall[] = [];\n\n/**\n * Subscribe to a scoped `values` stream — the most recent state\n * payload for a namespace. At the root returns `stream.values`.\n *\n * Typing:\n * - **Root** (`injectValues(stream)`): returns the `StateType`\n * declared on `injectStream<State>()` — non-nullable (the root\n * snapshot always has values, falling back to `initialValues ??\n * {}`).\n * - **Scoped** (`injectValues(stream, target)`): scoped payloads can\n * differ from the root state; callers should annotate the expected\n * shape explicitly (`injectValues<SubagentState>(stream, sub)`).\n * Defaults to `unknown` when not annotated.\n */\nexport function injectValues<StateType extends object>(\n stream: StreamHandle<StateType>\n): Signal<StateType>;\nexport function injectValues<T>(stream: AnyStream): Signal<InferStateType<T>>;\nexport function injectValues<T = unknown>(\n stream: AnyStream,\n target: SelectorTarget | Signal<SelectorTarget>,\n options?: { messagesKey?: string }\n): Signal<T | undefined>;\nexport function injectValues(\n stream: AnyStream,\n target?: SelectorTarget | Signal<SelectorTarget>,\n options?: { messagesKey?: string }\n): Signal<unknown> {\n const messagesKey = options?.messagesKey ?? \"messages\";\n const { namespace, key, isRootSignal } = normalizeTarget(\n target as SelectorTarget | Signal<SelectorTarget>,\n `values|${messagesKey}`\n );\n const registry = computed(() =>\n isRootSignal() ? null : getRegistry(stream)\n );\n const scoped = injectProjection<unknown>(\n registry,\n () => valuesProjection<unknown>(namespace(), messagesKey),\n key,\n undefined\n );\n return computed(() => (isRootSignal() ? stream.values() : scoped()));\n}\n\n/**\n * Subscribe to a `custom:<name>` stream extension — the most recent\n * payload emitted by the transformer, scoped to the target namespace.\n */\nexport function injectExtension<T = unknown>(\n stream: AnyStream,\n name: string,\n target?: SelectorTarget | Signal<SelectorTarget>\n): Signal<T | undefined> {\n const { namespace, key } = normalizeTarget(\n target as SelectorTarget | Signal<SelectorTarget>,\n `extension|${name}`\n );\n return injectProjection<T | undefined>(\n getRegistry(stream),\n () => extensionProjection<T>(name, namespace()),\n key,\n undefined\n );\n}\n\n/**\n * Raw-events escape hatch. Subscribes to one or more channels at a\n * namespace and returns a bounded buffer of raw protocol events.\n * Prefer {@link injectMessages} / {@link injectToolCalls} /\n * {@link injectValues} for the common cases.\n */\nexport type InjectChannelOptions = ChannelProjectionOptions;\n\nexport function injectChannel(\n stream: AnyStream,\n channels: readonly Channel[],\n target?: SelectorTarget | Signal<SelectorTarget>,\n options?: InjectChannelOptions\n): Signal<Event[]> {\n const sortedChannels = [...channels].sort().join(\",\");\n const prefix = `channel|${options?.bufferSize ?? \"default\"}|${(options?.replay ?? true) ? \"replay\" : \"live\"}|${sortedChannels}`;\n const { namespace, key } = normalizeTarget(\n target as SelectorTarget | Signal<SelectorTarget>,\n prefix\n );\n return injectProjection<Event[]>(\n getRegistry(stream),\n () => channelProjection(channels, namespace(), options),\n key,\n EMPTY_EVENTS\n );\n}\n\nconst EMPTY_EVENTS: Event[] = [];\n\n/**\n * Subscribe to a scoped audio-media stream. Each handle is yielded\n * on its first matching `content-block-start`, exposes\n * `.partialBytes` for live access, settles `.blob` / `.objectURL` /\n * `.transcript` on `message-finish`, and surfaces errors via\n * `.error`.\n *\n * Pair with `injectMediaUrl` to turn a handle into an `<audio src>`.\n */\nexport function injectAudio(\n stream: AnyStream,\n target?: SelectorTarget | Signal<SelectorTarget>\n): Signal<AudioMedia[]> {\n const { namespace, key } = normalizeTarget(\n target as SelectorTarget | Signal<SelectorTarget>,\n \"audio\"\n );\n return injectProjection<AudioMedia[]>(\n getRegistry(stream),\n () => audioProjection(namespace()),\n key,\n EMPTY_AUDIO\n );\n}\n\nconst EMPTY_AUDIO: AudioMedia[] = [];\n\n/**\n * Subscribe to a scoped image-media stream. Pair with\n * `injectMediaUrl` for `<img src>`.\n */\nexport function injectImages(\n stream: AnyStream,\n target?: SelectorTarget | Signal<SelectorTarget>\n): Signal<ImageMedia[]> {\n const { namespace, key } = normalizeTarget(\n target as SelectorTarget | Signal<SelectorTarget>,\n \"images\"\n );\n return injectProjection<ImageMedia[]>(\n getRegistry(stream),\n () => imagesProjection(namespace()),\n key,\n EMPTY_IMAGES\n );\n}\n\nconst EMPTY_IMAGES: ImageMedia[] = [];\n\n/**\n * Subscribe to a scoped video-media stream. Pair with\n * `injectMediaUrl` for `<video src>`.\n */\nexport function injectVideo(\n stream: AnyStream,\n target?: SelectorTarget | Signal<SelectorTarget>\n): Signal<VideoMedia[]> {\n const { namespace, key } = normalizeTarget(\n target as SelectorTarget | Signal<SelectorTarget>,\n \"video\"\n );\n return injectProjection<VideoMedia[]>(\n getRegistry(stream),\n () => videoProjection(namespace()),\n key,\n EMPTY_VIDEO\n );\n}\n\nconst EMPTY_VIDEO: VideoMedia[] = [];\n\n/**\n * Subscribe to a scoped file-media stream. Pair with\n * `injectMediaUrl` for an `<a download href>` target.\n */\nexport function injectFiles(\n stream: AnyStream,\n target?: SelectorTarget | Signal<SelectorTarget>\n): Signal<FileMedia[]> {\n const { namespace, key } = normalizeTarget(\n target as SelectorTarget | Signal<SelectorTarget>,\n \"files\"\n );\n return injectProjection<FileMedia[]>(\n getRegistry(stream),\n () => filesProjection(namespace()),\n key,\n EMPTY_FILES\n );\n}\n\nconst EMPTY_FILES: FileMedia[] = [];\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"selectors.js","names":[],"sources":["../src/selectors.ts"],"sourcesContent":["import { computed, isSignal, type Signal } from \"@angular/core\";\nimport type { BaseMessage } from \"@langchain/core/messages\";\nimport {\n NAMESPACE_SEPARATOR,\n audioProjection,\n channelProjection,\n extensionProjection,\n filesProjection,\n imagesProjection,\n messagesProjection,\n toolCallsProjection,\n valuesProjection,\n videoProjection,\n type AssembledToolCall,\n type AudioMedia,\n type Channel,\n type ChannelProjectionOptions,\n type Event,\n type FileMedia,\n type ImageMedia,\n type InferToolCalls,\n type InferStateType,\n type SubagentDiscoverySnapshot,\n type SubgraphDiscoverySnapshot,\n type VideoMedia,\n} from \"@langchain/langgraph-sdk/stream\";\nimport {\n getRegistry,\n type AnyStream,\n type UseStreamReturn,\n} from \"./use-stream.js\";\nimport { injectProjection } from \"./inject-projection.js\";\n\n/**\n * Selector primitives don't need to carry `InterruptType` /\n * `ConfigurableType`. Parameterising on `StateType` alone lets\n * callers with a full `injectStream<S, I, C>()` handle pass it in\n * without redeclaring those generics at every call site.\n */\ntype StreamHandle<StateType extends object> = UseStreamReturn<\n StateType,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n any,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n any\n>;\n\n/**\n * What a selector primitive can be targeted at. Callers can pass:\n * - `undefined` / `null` — root namespace (served by the always-on\n * root store — no extra subscription);\n * - a {@link SubagentDiscoverySnapshot} (`stream.subagents().get(...)`);\n * - a {@link SubgraphDiscoverySnapshot} (`stream.subgraphs().get(...)`);\n * - an explicit `{ namespace: string[] }`;\n * - a raw `string[]` escape hatch.\n *\n * Selectors also accept a `Signal<SelectorTarget>` so callers can\n * feed a `computed(() => ...)` and have the projection rebind\n * automatically.\n */\nexport type SelectorTarget =\n | undefined\n | null\n | readonly string[]\n | { namespace: readonly string[] }\n | SubagentDiscoverySnapshot\n | SubgraphDiscoverySnapshot;\n\nconst EMPTY_NAMESPACE: readonly string[] = [];\n\nfunction resolveNamespace(target: SelectorTarget): readonly string[] {\n if (target == null) return EMPTY_NAMESPACE;\n if (Array.isArray(target)) return target as readonly string[];\n const obj = target as { namespace?: readonly string[] };\n return obj.namespace ?? EMPTY_NAMESPACE;\n}\n\nfunction isRoot(namespace: readonly string[]): boolean {\n return namespace.length === 0;\n}\n\nfunction namespaceKey(namespace: readonly string[]): string {\n return namespace.join(NAMESPACE_SEPARATOR);\n}\n\n/**\n * Resolve a target or target-signal into a reactive\n * `[namespace, key]` pair. The helper returns plain signals so\n * `injectProjection` can track them via its internal effect.\n */\nfunction normalizeTarget(\n target: SelectorTarget | Signal<SelectorTarget>,\n prefix: string\n): {\n namespace: Signal<readonly string[]>;\n key: Signal<string>;\n isRootSignal: Signal<boolean>;\n} {\n if (isSignal(target)) {\n const namespace = computed(() =>\n resolveNamespace((target as Signal<SelectorTarget>)())\n );\n const key = computed(() => `${prefix}|${namespaceKey(namespace())}`);\n const isRootSignal = computed(() => isRoot(namespace()));\n return { namespace, key, isRootSignal };\n }\n const ns = resolveNamespace(target as SelectorTarget);\n const staticKey = `${prefix}|${namespaceKey(ns)}`;\n return {\n namespace: computed(() => ns),\n key: computed(() => staticKey),\n isRootSignal: computed(() => isRoot(ns)),\n };\n}\n\n/**\n * Subscribe to a scoped `messages` stream.\n *\n * Contract:\n * - At the root (no `target`) this returns `stream.messages` — the\n * always-on root projection; no extra subscription is opened.\n * - For any non-root namespace, call-time triggers a ref-counted\n * `messages` subscription scoped to that namespace. The\n * subscription is released automatically when the calling\n * component / service is destroyed (and the registry closes the\n * underlying server subscription when the last consumer leaves).\n *\n * Messages are always `BaseMessage` class instances from\n * `@langchain/core/messages`.\n */\nexport function injectMessages(\n stream: AnyStream,\n target?: SelectorTarget | Signal<SelectorTarget>\n): Signal<BaseMessage[]> {\n const { namespace, key, isRootSignal } = normalizeTarget(\n target as SelectorTarget | Signal<SelectorTarget>,\n \"messages\"\n );\n const registry = computed(() =>\n isRootSignal() ? null : getRegistry(stream)\n );\n const scoped = injectProjection<BaseMessage[]>(\n registry,\n () => messagesProjection(namespace()),\n key,\n EMPTY_MESSAGES\n );\n return computed(() => (isRootSignal() ? stream.messages() : scoped()));\n}\n\nconst EMPTY_MESSAGES: BaseMessage[] = [];\n\n/**\n * Subscribe to a scoped `tools` (tool-call) stream. Same target and\n * lifecycle rules as {@link injectMessages}; at the root this returns\n * `stream.toolCalls` directly.\n */\nexport function injectToolCalls(\n stream: AnyStream,\n target?: SelectorTarget | Signal<SelectorTarget>\n): Signal<AssembledToolCall[]>;\nexport function injectToolCalls<T>(\n stream: AnyStream,\n target?: SelectorTarget | Signal<SelectorTarget>\n): Signal<InferToolCalls<T>[]>;\nexport function injectToolCalls(\n stream: AnyStream,\n target?: SelectorTarget | Signal<SelectorTarget>\n): Signal<AssembledToolCall[]> {\n const { namespace, key, isRootSignal } = normalizeTarget(\n target as SelectorTarget | Signal<SelectorTarget>,\n \"toolCalls\"\n );\n const registry = computed(() =>\n isRootSignal() ? null : getRegistry(stream)\n );\n const scoped = injectProjection<AssembledToolCall[]>(\n registry,\n () => toolCallsProjection(namespace()),\n key,\n EMPTY_TOOLCALLS\n );\n return computed(() => (isRootSignal() ? stream.toolCalls() : scoped()));\n}\n\nconst EMPTY_TOOLCALLS: AssembledToolCall[] = [];\n\n/**\n * Subscribe to a scoped `values` stream — the most recent state\n * payload for a namespace. At the root returns `stream.values`.\n *\n * Typing:\n * - **Root** (`injectValues(stream)`): returns the `StateType`\n * declared on `injectStream<State>()` — non-nullable (the root\n * snapshot always has values, falling back to `initialValues ??\n * {}`).\n * - **Scoped** (`injectValues(stream, target)`): scoped payloads can\n * differ from the root state; callers should annotate the expected\n * shape explicitly (`injectValues<SubagentState>(stream, sub)`).\n * Defaults to `unknown` when not annotated.\n */\nexport function injectValues<StateType extends object>(\n stream: StreamHandle<StateType>\n): Signal<StateType>;\nexport function injectValues<T>(stream: AnyStream): Signal<InferStateType<T>>;\nexport function injectValues<T = unknown>(\n stream: AnyStream,\n target: SelectorTarget | Signal<SelectorTarget>,\n options?: { messagesKey?: string }\n): Signal<T | undefined>;\nexport function injectValues(\n stream: AnyStream,\n target?: SelectorTarget | Signal<SelectorTarget>,\n options?: { messagesKey?: string }\n): Signal<unknown> {\n const messagesKey = options?.messagesKey ?? \"messages\";\n const { namespace, key, isRootSignal } = normalizeTarget(\n target as SelectorTarget | Signal<SelectorTarget>,\n `values|${messagesKey}`\n );\n const registry = computed(() =>\n isRootSignal() ? null : getRegistry(stream)\n );\n const scoped = injectProjection<unknown>(\n registry,\n () => valuesProjection<unknown>(namespace(), messagesKey),\n key,\n undefined\n );\n return computed(() => (isRootSignal() ? stream.values() : scoped()));\n}\n\n/**\n * Subscribe to a `custom:<name>` stream extension — the most recent\n * payload emitted by the transformer, scoped to the target namespace.\n */\nexport function injectExtension<T = unknown>(\n stream: AnyStream,\n name: string,\n target?: SelectorTarget | Signal<SelectorTarget>\n): Signal<T | undefined> {\n const { namespace, key } = normalizeTarget(\n target as SelectorTarget | Signal<SelectorTarget>,\n `extension|${name}`\n );\n return injectProjection<T | undefined>(\n getRegistry(stream),\n () => extensionProjection<T>(name, namespace()),\n key,\n undefined\n );\n}\n\n/**\n * Raw-events escape hatch. Subscribes to one or more channels at a\n * namespace and returns a bounded buffer of raw protocol events.\n * Prefer {@link injectMessages} / {@link injectToolCalls} /\n * {@link injectValues} for the common cases.\n */\nexport type InjectChannelOptions = ChannelProjectionOptions;\n\nexport function injectChannel(\n stream: AnyStream,\n channels: readonly Channel[],\n target?: SelectorTarget | Signal<SelectorTarget>,\n options?: InjectChannelOptions\n): Signal<Event[]> {\n const sortedChannels = [...channels].sort().join(\",\");\n const prefix = `channel|${options?.bufferSize ?? \"default\"}|${(options?.replay ?? true) ? \"replay\" : \"live\"}|${sortedChannels}`;\n const { namespace, key } = normalizeTarget(\n target as SelectorTarget | Signal<SelectorTarget>,\n prefix\n );\n return injectProjection<Event[]>(\n getRegistry(stream),\n () => channelProjection(channels, namespace(), options),\n key,\n EMPTY_EVENTS\n );\n}\n\nconst EMPTY_EVENTS: Event[] = [];\n\n/**\n * Subscribe to a scoped audio-media stream. Each handle is yielded\n * on its first matching `content-block-start`, exposes\n * `.partialBytes` for live access, settles `.blob` / `.objectURL` /\n * `.transcript` on `message-finish`, and surfaces errors via\n * `.error`.\n *\n * Pair with `injectMediaUrl` to turn a handle into an `<audio src>`.\n */\nexport function injectAudio(\n stream: AnyStream,\n target?: SelectorTarget | Signal<SelectorTarget>\n): Signal<AudioMedia[]> {\n const { namespace, key } = normalizeTarget(\n target as SelectorTarget | Signal<SelectorTarget>,\n \"audio\"\n );\n return injectProjection<AudioMedia[]>(\n getRegistry(stream),\n () => audioProjection(namespace()),\n key,\n EMPTY_AUDIO\n );\n}\n\nconst EMPTY_AUDIO: AudioMedia[] = [];\n\n/**\n * Subscribe to a scoped image-media stream. Pair with\n * `injectMediaUrl` for `<img src>`.\n */\nexport function injectImages(\n stream: AnyStream,\n target?: SelectorTarget | Signal<SelectorTarget>\n): Signal<ImageMedia[]> {\n const { namespace, key } = normalizeTarget(\n target as SelectorTarget | Signal<SelectorTarget>,\n \"images\"\n );\n return injectProjection<ImageMedia[]>(\n getRegistry(stream),\n () => imagesProjection(namespace()),\n key,\n EMPTY_IMAGES\n );\n}\n\nconst EMPTY_IMAGES: ImageMedia[] = [];\n\n/**\n * Subscribe to a scoped video-media stream. Pair with\n * `injectMediaUrl` for `<video src>`.\n */\nexport function injectVideo(\n stream: AnyStream,\n target?: SelectorTarget | Signal<SelectorTarget>\n): Signal<VideoMedia[]> {\n const { namespace, key } = normalizeTarget(\n target as SelectorTarget | Signal<SelectorTarget>,\n \"video\"\n );\n return injectProjection<VideoMedia[]>(\n getRegistry(stream),\n () => videoProjection(namespace()),\n key,\n EMPTY_VIDEO\n );\n}\n\nconst EMPTY_VIDEO: VideoMedia[] = [];\n\n/**\n * Subscribe to a scoped file-media stream. Pair with\n * `injectMediaUrl` for an `<a download href>` target.\n */\nexport function injectFiles(\n stream: AnyStream,\n target?: SelectorTarget | Signal<SelectorTarget>\n): Signal<FileMedia[]> {\n const { namespace, key } = normalizeTarget(\n target as SelectorTarget | Signal<SelectorTarget>,\n \"files\"\n );\n return injectProjection<FileMedia[]>(\n getRegistry(stream),\n () => filesProjection(namespace()),\n key,\n EMPTY_FILES\n );\n}\n\nconst EMPTY_FILES: FileMedia[] = [];\n"],"mappings":"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"}
|
package/dist/use-stream.cjs
CHANGED
|
@@ -46,6 +46,7 @@ function useStream(options, destroyRef) {
|
|
|
46
46
|
webSocketFactory: hasCustomAdapter ? void 0 : asBag.webSocketFactory,
|
|
47
47
|
onThreadId: options.onThreadId,
|
|
48
48
|
onCreated: options.onCreated,
|
|
49
|
+
onCompleted: options.onCompleted,
|
|
49
50
|
initialValues: options.initialValues,
|
|
50
51
|
messagesKey: options.messagesKey
|
|
51
52
|
});
|
package/dist/use-stream.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-stream.cjs","names":["ClientCtor","StreamController","DestroyRef"],"sources":["../src/use-stream.ts"],"sourcesContent":["import {\n DestroyRef,\n computed,\n effect,\n inject,\n isSignal,\n signal,\n untracked,\n type Signal,\n} from \"@angular/core\";\nimport type { BaseMessage } from \"@langchain/core/messages\";\nimport type { Client, Interrupt } from \"@langchain/langgraph-sdk\";\nimport {\n filterOutHeadlessToolInterrupts,\n flushPendingHeadlessToolInterrupts,\n type AnyHeadlessToolImplementation,\n type OnToolCallback,\n} from \"@langchain/langgraph-sdk\";\nimport {\n Client as ClientCtor,\n type ClientConfig,\n type ThreadStream,\n} from \"@langchain/langgraph-sdk/client\";\nimport {\n StreamController,\n type AgentServerAdapter,\n type AgentServerOptions as StreamAgentServerOptions,\n type AssembledToolCall,\n type ChannelRegistry,\n type CustomAdapterOptions as StreamCustomAdapterOptions,\n type InferStateType,\n type InferSubagentStates,\n type RootSnapshot,\n type StateOf as StreamStateOf,\n type StreamSubmitOptions,\n type SubagentDiscoverySnapshot,\n type SubagentMap,\n type SubgraphByNodeMap,\n type SubgraphDiscoverySnapshot,\n type SubgraphMap,\n type UseStreamOptions as StreamUseStreamOptions,\n type WidenUpdateMessages,\n} from \"@langchain/langgraph-sdk/stream\";\n\n/** @deprecated Prefer {@link InferStateType}. */\nexport type StateOf<T> = StreamStateOf<T>;\n\ntype AngularThreadId = string | null | Signal<string | null | undefined>;\n\nexport type AgentServerOptions<StateType extends object> =\n StreamAgentServerOptions<StateType, AngularThreadId>;\n\nexport type CustomAdapterOptions<StateType extends object> =\n StreamCustomAdapterOptions<StateType, AngularThreadId, string>;\n\nexport type UseStreamOptions<\n StateType extends object = Record<string, unknown>,\n> = StreamUseStreamOptions<\n StateType,\n AngularThreadId,\n string | undefined,\n string | undefined,\n string\n>;\n\n/**\n * Private field on the handle that carries the\n * {@link StreamController} reference. Selector primitives read this\n * to reach the shared {@link ChannelRegistry}. Use the companion\n * `inject*` selectors (`injectMessages`, `injectToolCalls`,\n * `injectValues`, …) instead of reading this directly.\n */\nexport const STREAM_CONTROLLER: unique symbol = Symbol.for(\n \"@langchain/angular/controller\"\n);\n\n/**\n * Return shape of {@link useStream} — the Angular `StreamApi`.\n *\n * Reactivity primitives follow Angular conventions:\n *\n * - Data projections are `Signal<T>`; call them as functions in\n * templates (`stream.messages()`). They are snapshots — never\n * mutate the returned arrays / maps.\n * - Imperative methods (`submit` / `stop` / `respond`) are plain\n * functions. No `WritableSignal`s are exposed on the root handle.\n * - Identity values captured at construction time (`client`,\n * `assistantId`) are exposed as plain values; remount the\n * component to swap them.\n */\nexport interface UseStreamReturn<\n T = Record<string, unknown>,\n InterruptType = unknown,\n ConfigurableType extends object = Record<string, unknown>,\n StateType extends object = InferStateType<T>,\n SubagentStates = InferSubagentStates<T>,\n> {\n readonly values: Signal<StateType>;\n readonly messages: Signal<BaseMessage[]>;\n readonly toolCalls: Signal<AssembledToolCall[]>;\n readonly interrupts: Signal<Interrupt<InterruptType>[]>;\n readonly interrupt: Signal<Interrupt<InterruptType> | undefined>;\n readonly isLoading: Signal<boolean>;\n readonly isThreadLoading: Signal<boolean>;\n readonly error: Signal<unknown>;\n readonly threadId: Signal<string | null>;\n\n /**\n * Promise that settles when the active thread's initial hydration\n * completes. Exposed so SSR/render-before-flush pipelines can\n * `await stream.hydrationPromise` before serialising.\n */\n readonly hydrationPromise: Signal<Promise<void>>;\n\n readonly subagents: Signal<\n ReadonlyMap<\n keyof SubagentStates & string extends never\n ? string\n : keyof SubagentStates & string,\n SubagentDiscoverySnapshot\n >\n >;\n readonly subgraphs: Signal<ReadonlyMap<string, SubgraphDiscoverySnapshot>>;\n readonly subgraphsByNode: Signal<\n ReadonlyMap<string, readonly SubgraphDiscoverySnapshot[]>\n >;\n\n submit(\n input: WidenUpdateMessages<Partial<StateType>> | null | undefined,\n options?: StreamSubmitOptions<StateType, ConfigurableType>\n ): Promise<void>;\n stop(): Promise<void>;\n respond(\n response: unknown,\n target?: { interruptId: string; namespace?: string[] }\n ): Promise<void>;\n\n readonly client: Client;\n readonly assistantId: string;\n\n /** v2 escape hatch — returns the bound {@link ThreadStream}. */\n getThread(): ThreadStream | undefined;\n\n /** @internal Used by selector primitives. */\n readonly [STREAM_CONTROLLER]: StreamController<\n StateType,\n InterruptType,\n ConfigurableType\n >;\n}\n\n/**\n * Erased handle useful as a parameter type for helper components that\n * pass a `stream` through to selector primitives without reading\n * `values` directly. Mirrors the React/Vue `AnyStream` alias.\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport type AnyStream = UseStreamReturn<any, any, any>;\n\n/**\n * Convenience alias — the fully-resolved return type of\n * {@link useStream} for a given source type `T`.\n */\nexport type StreamApi<\n T = Record<string, unknown>,\n InterruptType = unknown,\n ConfigurableType extends object = Record<string, unknown>,\n> = UseStreamReturn<T, InterruptType, ConfigurableType>;\n\n/**\n * React-compatible alias for the fully-resolved stream handle type.\n * Angular docs prefer {@link StreamApi}, but shared libraries can use\n * this name across framework bindings.\n */\nexport type UseStreamResult<\n T = Record<string, unknown>,\n InterruptType = unknown,\n ConfigurableType extends object = Record<string, unknown>,\n> = UseStreamReturn<T, InterruptType, ConfigurableType>;\n\n/**\n * Framework-free factory that constructs a {@link StreamController}\n * and wraps its stores in Angular Signals. Callers must supply the\n * {@link DestroyRef} that owns the controller's lifetime — it's\n * already captured by the public `injectStream` helper.\n *\n * Exported for advanced callers (e.g. testing utilities, custom\n * factories) that prefer to manage injection scope themselves.\n */\nexport function useStream<\n T = Record<string, unknown>,\n InterruptType = unknown,\n ConfigurableType extends object = Record<string, unknown>,\n>(\n options: UseStreamOptions<InferStateType<T>>,\n destroyRef?: DestroyRef\n): UseStreamReturn<T, InterruptType, ConfigurableType> {\n type StateType = InferStateType<T>;\n\n interface OptionsBag {\n assistantId?: string;\n threadId?: string | null | Signal<string | null | undefined>;\n client?: Client;\n apiUrl?: string;\n apiKey?: string;\n callerOptions?: ClientConfig[\"callerOptions\"];\n defaultHeaders?: ClientConfig[\"defaultHeaders\"];\n transport?: \"sse\" | \"websocket\" | AgentServerAdapter;\n fetch?: typeof fetch;\n webSocketFactory?: (url: string) => WebSocket;\n onThreadId?: (threadId: string) => void;\n onCreated?: (meta: { run_id: string; thread_id: string }) => void;\n initialValues?: StateType;\n messagesKey?: string;\n tools?: AnyHeadlessToolImplementation[];\n onTool?: OnToolCallback;\n }\n const asBag = options as OptionsBag;\n\n const hasCustomAdapter =\n asBag.transport != null && typeof asBag.transport !== \"string\";\n const transport = asBag.transport;\n\n const client: Client =\n asBag.client ??\n (new ClientCtor({\n apiUrl: asBag.apiUrl,\n apiKey: asBag.apiKey,\n callerOptions: asBag.callerOptions,\n defaultHeaders: asBag.defaultHeaders,\n }) as unknown as Client);\n\n // Custom adapters may omit `assistantId`; the controller still\n // requires one so it has something to forward to `threads.stream`.\n const sentinel = \"_\";\n const assistantId =\n \"assistantId\" in options ? (options.assistantId ?? sentinel) : sentinel;\n\n // Normalize threadId input to a signal — callers may pass plain\n // values, nulls, or their own signals.\n const threadIdInput: Signal<string | null> = (() => {\n const raw = asBag.threadId;\n if (isSignal(raw)) {\n return computed(\n () => (raw as Signal<string | null | undefined>)() ?? null\n );\n }\n const initial: string | null = (raw as string | null | undefined) ?? null;\n return signal(initial) as unknown as Signal<string | null>;\n })();\n\n const controller = new StreamController<\n StateType,\n InterruptType,\n ConfigurableType\n >({\n assistantId,\n // Cast: the runtime `Client` is state-shape agnostic, but the\n // controller declares `client: Client<StateType>` for its own\n // typings. Same cast is applied in the React/Vue bindings.\n client: client as unknown as Client<StateType>,\n threadId: untracked(() => threadIdInput()),\n transport,\n fetch: hasCustomAdapter ? undefined : asBag.fetch,\n webSocketFactory: hasCustomAdapter ? undefined : asBag.webSocketFactory,\n onThreadId: options.onThreadId,\n onCreated: options.onCreated,\n initialValues: options.initialValues,\n messagesKey: options.messagesKey,\n });\n\n // Deferred dispose — matches the React `useEffect(() =>\n // controller.activate())` and Vue `onScopeDispose(deactivate)`\n // patterns. HMR / scope-reuse scenarios stay clean because\n // `activate()` cancels the pending dispose if the scope survives.\n const deactivate = controller.activate();\n const ref = destroyRef ?? inject(DestroyRef);\n ref.onDestroy(deactivate);\n\n // ─── Reactivity bridge: StreamStore → Signal ────────────────────────\n function bindStore<S>(\n subscribe: (listener: () => void) => () => void,\n getSnapshot: () => S\n ): Signal<S> {\n const s = signal<S>(getSnapshot());\n const unsubscribe = subscribe(() => {\n s.set(getSnapshot());\n });\n ref.onDestroy(unsubscribe);\n return computed(() => s());\n }\n\n const rootSignal = bindStore<RootSnapshot<StateType, InterruptType>>(\n controller.rootStore.subscribe,\n controller.rootStore.getSnapshot\n );\n const subagentSignal = bindStore<SubagentMap>(\n controller.subagentStore.subscribe,\n controller.subagentStore.getSnapshot\n );\n const subgraphSignal = bindStore<SubgraphMap>(\n controller.subgraphStore.subscribe,\n controller.subgraphStore.getSnapshot\n );\n const subgraphByNodeSignal = bindStore<SubgraphByNodeMap>(\n controller.subgraphByNodeStore.subscribe,\n controller.subgraphByNodeStore.getSnapshot\n );\n\n const values = computed(() => rootSignal().values);\n const messages = computed(() => rootSignal().messages);\n const toolCalls = computed(() => rootSignal().toolCalls);\n const interrupts = computed(() =>\n filterOutHeadlessToolInterrupts(rootSignal().interrupts)\n );\n const interrupt = computed(() => interrupts()[0]);\n const isLoading = computed(() => rootSignal().isLoading);\n const isThreadLoading = computed(() => rootSignal().isThreadLoading);\n const error = computed(() => rootSignal().error);\n const threadId = computed(() => rootSignal().threadId);\n\n // `hydrationPromise` is a property on the controller that gets\n // swapped on every `hydrate()` call. Exposing it as a signal lets\n // templates `await stream.hydrationPromise()` reactively; we\n // refresh the reference when the root store settles a new promise.\n const hydrationPromise = computed(() => {\n rootSignal();\n return controller.hydrationPromise;\n });\n\n // ─── threadId reactivity ────────────────────────────────────────────\n //\n // Re-hydrate whenever the caller's threadId input changes after\n // construction. The initial hydrate already fired synchronously in\n // the controller constructor, so we compare against the snapshot\n // captured at construction time rather than blindly skipping the\n // first run — in Angular, `@Input()` bindings apply *between*\n // construction and the first effect tick, so the first read can\n // legitimately be a different (updated) value that needs to\n // hydrate.\n const initialThreadId = untracked(() => threadIdInput()) ?? null;\n let lastAppliedThreadId: string | null = initialThreadId;\n effect(() => {\n const next = threadIdInput() ?? null;\n if (next === lastAppliedThreadId) return;\n lastAppliedThreadId = next;\n untracked(() => {\n void controller.hydrate(next);\n });\n });\n\n // ─── Headless-tool handling ─────────────────────────────────────────\n const tools = options.tools;\n const onTool = options.onTool;\n if (tools?.length) {\n const handledTools = new Set<string>();\n\n // Clear the dedup set whenever the thread id changes.\n effect(() => {\n threadIdInput();\n untracked(() => handledTools.clear());\n });\n\n effect(() => {\n const snapshot = rootSignal();\n const bag = snapshot.values as unknown as Record<string, unknown>;\n const existing = Array.isArray(bag?.__interrupt__)\n ? (bag.__interrupt__ as Interrupt[])\n : [];\n const combined: Interrupt[] = [\n ...existing,\n ...(snapshot.interrupts as unknown as Interrupt[]),\n ];\n if (combined.length === 0) return;\n untracked(() => {\n flushPendingHeadlessToolInterrupts(\n { ...bag, __interrupt__: combined },\n tools,\n handledTools,\n {\n onTool,\n defer: (run) => {\n void Promise.resolve().then(run);\n },\n resumeSubmit: (command) =>\n controller.submit(null, {\n command,\n } as StreamSubmitOptions<StateType, ConfigurableType>),\n }\n );\n });\n });\n }\n\n const handle: UseStreamReturn<T, InterruptType, ConfigurableType> = {\n values: values as UseStreamReturn<\n T,\n InterruptType,\n ConfigurableType\n >[\"values\"],\n messages,\n toolCalls,\n interrupts,\n interrupt,\n isLoading,\n isThreadLoading,\n error,\n threadId,\n hydrationPromise,\n subagents: subagentSignal as UseStreamReturn<\n T,\n InterruptType,\n ConfigurableType\n >[\"subagents\"],\n subgraphs: subgraphSignal,\n subgraphsByNode: subgraphByNodeSignal,\n submit: (input, submitOptions) => controller.submit(input, submitOptions),\n stop: () => controller.stop(),\n respond: (response, target) => controller.respond(response, target),\n getThread: () => controller.getThread(),\n client,\n assistantId,\n [STREAM_CONTROLLER]: controller,\n };\n\n return handle;\n}\n\n/**\n * Helper used by the selector primitives to reach the underlying\n * {@link ChannelRegistry} from a stream handle. Kept internal —\n * application code should call `injectMessages`, `injectToolCalls`,\n * etc. instead of reading this directly.\n *\n * @internal\n */\nexport function getRegistry(\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n stream: UseStreamReturn<any, any, any>\n): ChannelRegistry {\n return stream[STREAM_CONTROLLER].registry;\n}\n\nexport type { ThreadStream };\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"use-stream.cjs","names":["ClientCtor","StreamController","DestroyRef"],"sources":["../src/use-stream.ts"],"sourcesContent":["import {\n DestroyRef,\n computed,\n effect,\n inject,\n isSignal,\n signal,\n untracked,\n type Signal,\n} from \"@angular/core\";\nimport type { BaseMessage } from \"@langchain/core/messages\";\nimport type { Client, Interrupt } from \"@langchain/langgraph-sdk\";\nimport {\n filterOutHeadlessToolInterrupts,\n flushPendingHeadlessToolInterrupts,\n type AnyHeadlessToolImplementation,\n type OnToolCallback,\n} from \"@langchain/langgraph-sdk\";\nimport {\n Client as ClientCtor,\n type ClientConfig,\n type ThreadStream,\n} from \"@langchain/langgraph-sdk/client\";\nimport {\n StreamController,\n type AgentServerAdapter,\n type AgentServerOptions as StreamAgentServerOptions,\n type ChannelRegistry,\n type CustomAdapterOptions as StreamCustomAdapterOptions,\n type InferStateType,\n type InferToolCalls,\n type InferSubagentStates,\n type RootSnapshot,\n type RunCompletedInfo,\n type RunExecutionInfo,\n type StreamSubmitOptions,\n type SubagentDiscoverySnapshot,\n type SubagentMap,\n type SubgraphByNodeMap,\n type SubgraphDiscoverySnapshot,\n type SubgraphMap,\n type UseStreamOptions as StreamUseStreamOptions,\n type WidenUpdateMessages,\n} from \"@langchain/langgraph-sdk/stream\";\n\ntype AngularThreadId = string | null | Signal<string | null | undefined>;\n\nexport type AgentServerOptions<StateType extends object> =\n StreamAgentServerOptions<StateType, AngularThreadId>;\n\nexport type CustomAdapterOptions<StateType extends object> =\n StreamCustomAdapterOptions<StateType, AngularThreadId, string>;\n\nexport type UseStreamOptions<\n StateType extends object = Record<string, unknown>,\n> = StreamUseStreamOptions<\n StateType,\n AngularThreadId,\n string | undefined,\n string | undefined,\n string\n>;\n\n/**\n * Private field on the handle that carries the\n * {@link StreamController} reference. Selector primitives read this\n * to reach the shared {@link ChannelRegistry}. Use the companion\n * `inject*` selectors (`injectMessages`, `injectToolCalls`,\n * `injectValues`, …) instead of reading this directly.\n */\nexport const STREAM_CONTROLLER: unique symbol = Symbol.for(\n \"@langchain/angular/controller\"\n);\n\n/**\n * Return shape of {@link useStream} — the Angular `StreamApi`.\n *\n * Reactivity primitives follow Angular conventions:\n *\n * - Data projections are `Signal<T>`; call them as functions in\n * templates (`stream.messages()`). They are snapshots — never\n * mutate the returned arrays / maps.\n * - Imperative methods (`submit` / `stop` / `respond`) are plain\n * functions. No `WritableSignal`s are exposed on the root handle.\n * - Identity values captured at construction time (`client`,\n * `assistantId`) are exposed as plain values; remount the\n * component to swap them.\n */\nexport interface UseStreamReturn<\n T = Record<string, unknown>,\n InterruptType = unknown,\n ConfigurableType extends object = Record<string, unknown>,\n StateType extends object = InferStateType<T>,\n SubagentStates = InferSubagentStates<T>,\n> {\n readonly values: Signal<StateType>;\n readonly messages: Signal<BaseMessage[]>;\n readonly toolCalls: Signal<InferToolCalls<T>[]>;\n readonly interrupts: Signal<Interrupt<InterruptType>[]>;\n readonly interrupt: Signal<Interrupt<InterruptType> | undefined>;\n readonly isLoading: Signal<boolean>;\n readonly isThreadLoading: Signal<boolean>;\n readonly error: Signal<unknown>;\n readonly threadId: Signal<string | null>;\n\n /**\n * Promise that settles when the active thread's initial hydration\n * completes. Exposed so SSR/render-before-flush pipelines can\n * `await stream.hydrationPromise` before serialising.\n */\n readonly hydrationPromise: Signal<Promise<void>>;\n\n readonly subagents: Signal<\n ReadonlyMap<\n keyof SubagentStates & string extends never\n ? string\n : keyof SubagentStates & string,\n SubagentDiscoverySnapshot\n >\n >;\n readonly subgraphs: Signal<ReadonlyMap<string, SubgraphDiscoverySnapshot>>;\n readonly subgraphsByNode: Signal<\n ReadonlyMap<string, readonly SubgraphDiscoverySnapshot[]>\n >;\n\n submit(\n input: WidenUpdateMessages<Partial<StateType>> | null | undefined,\n options?: StreamSubmitOptions<StateType, ConfigurableType>\n ): Promise<void>;\n stop(): Promise<void>;\n respond(\n response: unknown,\n target?: { interruptId: string; namespace?: string[] }\n ): Promise<void>;\n\n readonly client: Client;\n readonly assistantId: string;\n\n /** v2 escape hatch — returns the bound {@link ThreadStream}. */\n getThread(): ThreadStream | undefined;\n\n /** @internal Used by selector primitives. */\n readonly [STREAM_CONTROLLER]: StreamController<\n StateType,\n InterruptType,\n ConfigurableType\n >;\n}\n\n/**\n * Erased handle useful as a parameter type for helper components that\n * pass a `stream` through to selector primitives without reading\n * `values` directly. Mirrors the React/Vue `AnyStream` alias.\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport type AnyStream = UseStreamReturn<any, any, any>;\n\n/**\n * Convenience alias — the fully-resolved return type of\n * {@link useStream} for a given source type `T`.\n */\nexport type StreamApi<\n T = Record<string, unknown>,\n InterruptType = unknown,\n ConfigurableType extends object = Record<string, unknown>,\n> = UseStreamReturn<T, InterruptType, ConfigurableType>;\n\n/**\n * React-compatible alias for the fully-resolved stream handle type.\n * Angular docs prefer {@link StreamApi}, but shared libraries can use\n * this name across framework bindings.\n */\nexport type UseStreamResult<\n T = Record<string, unknown>,\n InterruptType = unknown,\n ConfigurableType extends object = Record<string, unknown>,\n> = UseStreamReturn<T, InterruptType, ConfigurableType>;\n\n/**\n * Framework-free factory that constructs a {@link StreamController}\n * and wraps its stores in Angular Signals. Callers must supply the\n * {@link DestroyRef} that owns the controller's lifetime — it's\n * already captured by the public `injectStream` helper.\n *\n * Exported for advanced callers (e.g. testing utilities, custom\n * factories) that prefer to manage injection scope themselves.\n */\nexport function useStream<\n T = Record<string, unknown>,\n InterruptType = unknown,\n ConfigurableType extends object = Record<string, unknown>,\n>(\n options: UseStreamOptions<InferStateType<T>>,\n destroyRef?: DestroyRef\n): UseStreamReturn<T, InterruptType, ConfigurableType> {\n type StateType = InferStateType<T>;\n\n interface OptionsBag {\n assistantId?: string;\n threadId?: string | null | Signal<string | null | undefined>;\n client?: Client;\n apiUrl?: string;\n apiKey?: string;\n callerOptions?: ClientConfig[\"callerOptions\"];\n defaultHeaders?: ClientConfig[\"defaultHeaders\"];\n transport?: \"sse\" | \"websocket\" | AgentServerAdapter;\n fetch?: typeof fetch;\n webSocketFactory?: (url: string) => WebSocket;\n onThreadId?: (threadId: string) => void;\n onCreated?: (info: RunExecutionInfo) => void;\n onCompleted?: (info: RunCompletedInfo) => void;\n initialValues?: StateType;\n messagesKey?: string;\n tools?: AnyHeadlessToolImplementation[];\n onTool?: OnToolCallback;\n }\n const asBag = options as OptionsBag;\n\n const hasCustomAdapter =\n asBag.transport != null && typeof asBag.transport !== \"string\";\n const transport = asBag.transport;\n\n const client: Client =\n asBag.client ??\n (new ClientCtor({\n apiUrl: asBag.apiUrl,\n apiKey: asBag.apiKey,\n callerOptions: asBag.callerOptions,\n defaultHeaders: asBag.defaultHeaders,\n }) as unknown as Client);\n\n // Custom adapters may omit `assistantId`; the controller still\n // requires one so it has something to forward to `threads.stream`.\n const sentinel = \"_\";\n const assistantId =\n \"assistantId\" in options ? (options.assistantId ?? sentinel) : sentinel;\n\n // Normalize threadId input to a signal — callers may pass plain\n // values, nulls, or their own signals.\n const threadIdInput: Signal<string | null> = (() => {\n const raw = asBag.threadId;\n if (isSignal(raw)) {\n return computed(\n () => (raw as Signal<string | null | undefined>)() ?? null\n );\n }\n const initial: string | null = (raw as string | null | undefined) ?? null;\n return signal(initial) as unknown as Signal<string | null>;\n })();\n\n const controller = new StreamController<\n StateType,\n InterruptType,\n ConfigurableType\n >({\n assistantId,\n // Cast: the runtime `Client` is state-shape agnostic, but the\n // controller declares `client: Client<StateType>` for its own\n // typings. Same cast is applied in the React/Vue bindings.\n client: client as unknown as Client<StateType>,\n threadId: untracked(() => threadIdInput()),\n transport,\n fetch: hasCustomAdapter ? undefined : asBag.fetch,\n webSocketFactory: hasCustomAdapter ? undefined : asBag.webSocketFactory,\n onThreadId: options.onThreadId,\n onCreated: options.onCreated,\n onCompleted: options.onCompleted,\n initialValues: options.initialValues,\n messagesKey: options.messagesKey,\n });\n\n // Deferred dispose — matches the React `useEffect(() =>\n // controller.activate())` and Vue `onScopeDispose(deactivate)`\n // patterns. HMR / scope-reuse scenarios stay clean because\n // `activate()` cancels the pending dispose if the scope survives.\n const deactivate = controller.activate();\n const ref = destroyRef ?? inject(DestroyRef);\n ref.onDestroy(deactivate);\n\n // ─── Reactivity bridge: StreamStore → Signal ────────────────────────\n function bindStore<S>(\n subscribe: (listener: () => void) => () => void,\n getSnapshot: () => S\n ): Signal<S> {\n const s = signal<S>(getSnapshot());\n const unsubscribe = subscribe(() => {\n s.set(getSnapshot());\n });\n ref.onDestroy(unsubscribe);\n return computed(() => s());\n }\n\n const rootSignal = bindStore<RootSnapshot<StateType, InterruptType>>(\n controller.rootStore.subscribe,\n controller.rootStore.getSnapshot\n );\n const subagentSignal = bindStore<SubagentMap>(\n controller.subagentStore.subscribe,\n controller.subagentStore.getSnapshot\n );\n const subgraphSignal = bindStore<SubgraphMap>(\n controller.subgraphStore.subscribe,\n controller.subgraphStore.getSnapshot\n );\n const subgraphByNodeSignal = bindStore<SubgraphByNodeMap>(\n controller.subgraphByNodeStore.subscribe,\n controller.subgraphByNodeStore.getSnapshot\n );\n\n const values = computed(() => rootSignal().values);\n const messages = computed(() => rootSignal().messages);\n const toolCalls = computed(\n () => rootSignal().toolCalls as InferToolCalls<T>[]\n );\n const interrupts = computed(() =>\n filterOutHeadlessToolInterrupts(rootSignal().interrupts)\n );\n const interrupt = computed(() => interrupts()[0]);\n const isLoading = computed(() => rootSignal().isLoading);\n const isThreadLoading = computed(() => rootSignal().isThreadLoading);\n const error = computed(() => rootSignal().error);\n const threadId = computed(() => rootSignal().threadId);\n\n // `hydrationPromise` is a property on the controller that gets\n // swapped on every `hydrate()` call. Exposing it as a signal lets\n // templates `await stream.hydrationPromise()` reactively; we\n // refresh the reference when the root store settles a new promise.\n const hydrationPromise = computed(() => {\n rootSignal();\n return controller.hydrationPromise;\n });\n\n // ─── threadId reactivity ────────────────────────────────────────────\n //\n // Re-hydrate whenever the caller's threadId input changes after\n // construction. The initial hydrate already fired synchronously in\n // the controller constructor, so we compare against the snapshot\n // captured at construction time rather than blindly skipping the\n // first run — in Angular, `@Input()` bindings apply *between*\n // construction and the first effect tick, so the first read can\n // legitimately be a different (updated) value that needs to\n // hydrate.\n const initialThreadId = untracked(() => threadIdInput()) ?? null;\n let lastAppliedThreadId: string | null = initialThreadId;\n effect(() => {\n const next = threadIdInput() ?? null;\n if (next === lastAppliedThreadId) return;\n lastAppliedThreadId = next;\n untracked(() => {\n void controller.hydrate(next);\n });\n });\n\n // ─── Headless-tool handling ─────────────────────────────────────────\n const tools = options.tools;\n const onTool = options.onTool;\n if (tools?.length) {\n const handledTools = new Set<string>();\n\n // Clear the dedup set whenever the thread id changes.\n effect(() => {\n threadIdInput();\n untracked(() => handledTools.clear());\n });\n\n effect(() => {\n const snapshot = rootSignal();\n const bag = snapshot.values as unknown as Record<string, unknown>;\n const existing = Array.isArray(bag?.__interrupt__)\n ? (bag.__interrupt__ as Interrupt[])\n : [];\n const combined: Interrupt[] = [\n ...existing,\n ...(snapshot.interrupts as unknown as Interrupt[]),\n ];\n if (combined.length === 0) return;\n untracked(() => {\n flushPendingHeadlessToolInterrupts(\n { ...bag, __interrupt__: combined },\n tools,\n handledTools,\n {\n onTool,\n defer: (run) => {\n void Promise.resolve().then(run);\n },\n resumeSubmit: (command) =>\n controller.submit(null, {\n command,\n } as StreamSubmitOptions<StateType, ConfigurableType>),\n }\n );\n });\n });\n }\n\n const handle: UseStreamReturn<T, InterruptType, ConfigurableType> = {\n values: values as UseStreamReturn<\n T,\n InterruptType,\n ConfigurableType\n >[\"values\"],\n messages,\n toolCalls,\n interrupts,\n interrupt,\n isLoading,\n isThreadLoading,\n error,\n threadId,\n hydrationPromise,\n subagents: subagentSignal as UseStreamReturn<\n T,\n InterruptType,\n ConfigurableType\n >[\"subagents\"],\n subgraphs: subgraphSignal,\n subgraphsByNode: subgraphByNodeSignal,\n submit: (input, submitOptions) => controller.submit(input, submitOptions),\n stop: () => controller.stop(),\n respond: (response, target) => controller.respond(response, target),\n getThread: () => controller.getThread(),\n client,\n assistantId,\n [STREAM_CONTROLLER]: controller,\n };\n\n return handle;\n}\n\n/**\n * Helper used by the selector primitives to reach the underlying\n * {@link ChannelRegistry} from a stream handle. Kept internal —\n * application code should call `injectMessages`, `injectToolCalls`,\n * etc. instead of reading this directly.\n *\n * @internal\n */\nexport function getRegistry(\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n stream: UseStreamReturn<any, any, any>\n): ChannelRegistry {\n return stream[STREAM_CONTROLLER].registry;\n}\n\nexport type { ThreadStream };\n"],"mappings":"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"}
|
package/dist/use-stream.d.cts
CHANGED
|
@@ -1,12 +1,10 @@
|
|
|
1
|
-
import { AgentServerOptions,
|
|
1
|
+
import { AgentServerOptions, ChannelRegistry, CustomAdapterOptions, InferStateType, InferSubagentStates, InferToolCalls, StreamController, StreamSubmitOptions, SubagentDiscoverySnapshot, SubgraphDiscoverySnapshot, UseStreamOptions, WidenUpdateMessages } from "@langchain/langgraph-sdk/stream";
|
|
2
2
|
import { DestroyRef, Signal } from "@angular/core";
|
|
3
3
|
import { BaseMessage } from "@langchain/core/messages";
|
|
4
4
|
import { Client, Interrupt } from "@langchain/langgraph-sdk";
|
|
5
5
|
import { ThreadStream as ThreadStream$1 } from "@langchain/langgraph-sdk/client";
|
|
6
6
|
|
|
7
7
|
//#region src/use-stream.d.ts
|
|
8
|
-
/** @deprecated Prefer {@link InferStateType}. */
|
|
9
|
-
type StateOf$1<T> = StateOf<T>;
|
|
10
8
|
type AngularThreadId = string | null | Signal<string | null | undefined>;
|
|
11
9
|
type AgentServerOptions$1<StateType extends object> = AgentServerOptions<StateType, AngularThreadId>;
|
|
12
10
|
type CustomAdapterOptions$1<StateType extends object> = CustomAdapterOptions<StateType, AngularThreadId, string>;
|
|
@@ -36,7 +34,7 @@ declare const STREAM_CONTROLLER: unique symbol;
|
|
|
36
34
|
interface UseStreamReturn<T = Record<string, unknown>, InterruptType = unknown, ConfigurableType extends object = Record<string, unknown>, StateType extends object = InferStateType<T>, SubagentStates = InferSubagentStates<T>> {
|
|
37
35
|
readonly values: Signal<StateType>;
|
|
38
36
|
readonly messages: Signal<BaseMessage[]>;
|
|
39
|
-
readonly toolCalls: Signal<
|
|
37
|
+
readonly toolCalls: Signal<InferToolCalls<T>[]>;
|
|
40
38
|
readonly interrupts: Signal<Interrupt<InterruptType>[]>;
|
|
41
39
|
readonly interrupt: Signal<Interrupt<InterruptType> | undefined>;
|
|
42
40
|
readonly isLoading: Signal<boolean>;
|
|
@@ -93,5 +91,5 @@ type UseStreamResult<T = Record<string, unknown>, InterruptType = unknown, Confi
|
|
|
93
91
|
*/
|
|
94
92
|
declare function useStream<T = Record<string, unknown>, InterruptType = unknown, ConfigurableType extends object = Record<string, unknown>>(options: UseStreamOptions$1<InferStateType<T>>, destroyRef?: DestroyRef): UseStreamReturn<T, InterruptType, ConfigurableType>;
|
|
95
93
|
//#endregion
|
|
96
|
-
export { AgentServerOptions$1 as AgentServerOptions, AnyStream, CustomAdapterOptions$1 as CustomAdapterOptions, STREAM_CONTROLLER,
|
|
94
|
+
export { AgentServerOptions$1 as AgentServerOptions, AnyStream, CustomAdapterOptions$1 as CustomAdapterOptions, STREAM_CONTROLLER, StreamApi, type ThreadStream$1 as ThreadStream, UseStreamOptions$1 as UseStreamOptions, UseStreamResult, UseStreamReturn, useStream };
|
|
97
95
|
//# sourceMappingURL=use-stream.d.cts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-stream.d.cts","names":[],"sources":["../src/use-stream.ts"],"mappings":"
|
|
1
|
+
{"version":3,"file":"use-stream.d.cts","names":[],"sources":["../src/use-stream.ts"],"mappings":";;;;;;;KA6CK,eAAA,mBAAkC,MAAA;AAAA,KAE3B,oBAAA,6BACV,kBAAA,CAAyB,SAAA,EAAW,eAAA;AAAA,KAE1B,sBAAA,6BACV,oBAAA,CAA2B,SAAA,EAAW,eAAA;AAAA,KAE5B,kBAAA,4BACiB,MAAA,qBACzB,gBAAA,CACF,SAAA,EACA,eAAA;;;;AAVF;;;;cAuBa,iBAAA;;;;;;;;;;AApBb;;;;;UAsCiB,eAAA,KACX,MAAA,8EAE8B,MAAA,8CACP,cAAA,CAAe,CAAA,oBACzB,mBAAA,CAAoB,CAAA;EAAA,SAE5B,MAAA,EAAQ,MAAA,CAAO,SAAA;EAAA,SACf,QAAA,EAAU,MAAA,CAAO,WAAA;EAAA,SACjB,SAAA,EAAW,MAAA,CAAO,cAAA,CAAe,CAAA;EAAA,SACjC,UAAA,EAAY,MAAA,CAAO,SAAA,CAAU,aAAA;EAAA,SAC7B,SAAA,EAAW,MAAA,CAAO,SAAA,CAAU,aAAA;EAAA,SAC5B,SAAA,EAAW,MAAA;EAAA,SACX,eAAA,EAAiB,MAAA;EAAA,SACjB,KAAA,EAAO,MAAA;EAAA,SACP,QAAA,EAAU,MAAA;EAlDO;;;;;EAAA,SAyDjB,gBAAA,EAAkB,MAAA,CAAO,OAAA;EAAA,SAEzB,SAAA,EAAW,MAAA,CAClB,WAAA,OACQ,cAAA,yCAEI,cAAA,WACV,yBAAA;EAAA,SAGK,SAAA,EAAW,MAAA,CAAO,WAAA,SAAoB,yBAAA;EAAA,SACtC,eAAA,EAAiB,MAAA,CACxB,WAAA,kBAA6B,yBAAA;EAG/B,MAAA,CACE,KAAA,EAAO,mBAAA,CAAoB,OAAA,CAAQ,SAAA,uBACnC,OAAA,GAAU,mBAAA,CAAoB,SAAA,EAAW,gBAAA,IACxC,OAAA;EACH,IAAA,IAAQ,OAAA;EACR,OAAA,CACE,QAAA,WACA,MAAA;IAAW,WAAA;IAAqB,SAAA;EAAA,IAC/B,OAAA;EAAA,SAEM,MAAA,EAAQ,MAAA;EAAA,SACR,WAAA;;EAGT,SAAA,IAAa,cAAA;EAnEd;EAAA,UAsEW,iBAAA,GAAoB,gBAAA,CAC5B,SAAA,EACA,aAAA,EACA,gBAAA;AAAA;;;;;;KAUQ,SAAA,GAAY,eAAA;;;;;KAMZ,SAAA,KACN,MAAA,8EAE8B,MAAA,qBAChC,eAAA,CAAgB,CAAA,EAAG,aAAA,EAAe,gBAAA;;;;;;KAO1B,eAAA,KACN,MAAA,8EAE8B,MAAA,qBAChC,eAAA,CAAgB,CAAA,EAAG,aAAA,EAAe,gBAAA;;;;;;;;;;iBAWtB,SAAA,KACV,MAAA,8EAE8B,MAAA,kBAAA,CAElC,OAAA,EAAS,kBAAA,CAAiB,cAAA,CAAe,CAAA,IACzC,UAAA,GAAa,UAAA,GACZ,eAAA,CAAgB,CAAA,EAAG,aAAA,EAAe,gBAAA"}
|
package/dist/use-stream.d.ts
CHANGED
|
@@ -1,12 +1,10 @@
|
|
|
1
1
|
import { DestroyRef, Signal } from "@angular/core";
|
|
2
2
|
import { Client, Interrupt } from "@langchain/langgraph-sdk";
|
|
3
3
|
import { ThreadStream as ThreadStream$1 } from "@langchain/langgraph-sdk/client";
|
|
4
|
-
import { AgentServerOptions,
|
|
4
|
+
import { AgentServerOptions, ChannelRegistry, CustomAdapterOptions, InferStateType, InferSubagentStates, InferToolCalls, StreamController, StreamSubmitOptions, SubagentDiscoverySnapshot, SubgraphDiscoverySnapshot, UseStreamOptions, WidenUpdateMessages } from "@langchain/langgraph-sdk/stream";
|
|
5
5
|
import { BaseMessage } from "@langchain/core/messages";
|
|
6
6
|
|
|
7
7
|
//#region src/use-stream.d.ts
|
|
8
|
-
/** @deprecated Prefer {@link InferStateType}. */
|
|
9
|
-
type StateOf$1<T> = StateOf<T>;
|
|
10
8
|
type AngularThreadId = string | null | Signal<string | null | undefined>;
|
|
11
9
|
type AgentServerOptions$1<StateType extends object> = AgentServerOptions<StateType, AngularThreadId>;
|
|
12
10
|
type CustomAdapterOptions$1<StateType extends object> = CustomAdapterOptions<StateType, AngularThreadId, string>;
|
|
@@ -36,7 +34,7 @@ declare const STREAM_CONTROLLER: unique symbol;
|
|
|
36
34
|
interface UseStreamReturn<T = Record<string, unknown>, InterruptType = unknown, ConfigurableType extends object = Record<string, unknown>, StateType extends object = InferStateType<T>, SubagentStates = InferSubagentStates<T>> {
|
|
37
35
|
readonly values: Signal<StateType>;
|
|
38
36
|
readonly messages: Signal<BaseMessage[]>;
|
|
39
|
-
readonly toolCalls: Signal<
|
|
37
|
+
readonly toolCalls: Signal<InferToolCalls<T>[]>;
|
|
40
38
|
readonly interrupts: Signal<Interrupt<InterruptType>[]>;
|
|
41
39
|
readonly interrupt: Signal<Interrupt<InterruptType> | undefined>;
|
|
42
40
|
readonly isLoading: Signal<boolean>;
|
|
@@ -93,5 +91,5 @@ type UseStreamResult<T = Record<string, unknown>, InterruptType = unknown, Confi
|
|
|
93
91
|
*/
|
|
94
92
|
declare function useStream<T = Record<string, unknown>, InterruptType = unknown, ConfigurableType extends object = Record<string, unknown>>(options: UseStreamOptions$1<InferStateType<T>>, destroyRef?: DestroyRef): UseStreamReturn<T, InterruptType, ConfigurableType>;
|
|
95
93
|
//#endregion
|
|
96
|
-
export { AgentServerOptions$1 as AgentServerOptions, AnyStream, CustomAdapterOptions$1 as CustomAdapterOptions, STREAM_CONTROLLER,
|
|
94
|
+
export { AgentServerOptions$1 as AgentServerOptions, AnyStream, CustomAdapterOptions$1 as CustomAdapterOptions, STREAM_CONTROLLER, StreamApi, type ThreadStream$1 as ThreadStream, UseStreamOptions$1 as UseStreamOptions, UseStreamResult, UseStreamReturn, useStream };
|
|
97
95
|
//# sourceMappingURL=use-stream.d.ts.map
|
package/dist/use-stream.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-stream.d.ts","names":[],"sources":["../src/use-stream.ts"],"mappings":"
|
|
1
|
+
{"version":3,"file":"use-stream.d.ts","names":[],"sources":["../src/use-stream.ts"],"mappings":";;;;;;;KA6CK,eAAA,mBAAkC,MAAA;AAAA,KAE3B,oBAAA,6BACV,kBAAA,CAAyB,SAAA,EAAW,eAAA;AAAA,KAE1B,sBAAA,6BACV,oBAAA,CAA2B,SAAA,EAAW,eAAA;AAAA,KAE5B,kBAAA,4BACiB,MAAA,qBACzB,gBAAA,CACF,SAAA,EACA,eAAA;;;;AAVF;;;;cAuBa,iBAAA;;;;;;;;;;AApBb;;;;;UAsCiB,eAAA,KACX,MAAA,8EAE8B,MAAA,8CACP,cAAA,CAAe,CAAA,oBACzB,mBAAA,CAAoB,CAAA;EAAA,SAE5B,MAAA,EAAQ,MAAA,CAAO,SAAA;EAAA,SACf,QAAA,EAAU,MAAA,CAAO,WAAA;EAAA,SACjB,SAAA,EAAW,MAAA,CAAO,cAAA,CAAe,CAAA;EAAA,SACjC,UAAA,EAAY,MAAA,CAAO,SAAA,CAAU,aAAA;EAAA,SAC7B,SAAA,EAAW,MAAA,CAAO,SAAA,CAAU,aAAA;EAAA,SAC5B,SAAA,EAAW,MAAA;EAAA,SACX,eAAA,EAAiB,MAAA;EAAA,SACjB,KAAA,EAAO,MAAA;EAAA,SACP,QAAA,EAAU,MAAA;EAlDO;;;;;EAAA,SAyDjB,gBAAA,EAAkB,MAAA,CAAO,OAAA;EAAA,SAEzB,SAAA,EAAW,MAAA,CAClB,WAAA,OACQ,cAAA,yCAEI,cAAA,WACV,yBAAA;EAAA,SAGK,SAAA,EAAW,MAAA,CAAO,WAAA,SAAoB,yBAAA;EAAA,SACtC,eAAA,EAAiB,MAAA,CACxB,WAAA,kBAA6B,yBAAA;EAG/B,MAAA,CACE,KAAA,EAAO,mBAAA,CAAoB,OAAA,CAAQ,SAAA,uBACnC,OAAA,GAAU,mBAAA,CAAoB,SAAA,EAAW,gBAAA,IACxC,OAAA;EACH,IAAA,IAAQ,OAAA;EACR,OAAA,CACE,QAAA,WACA,MAAA;IAAW,WAAA;IAAqB,SAAA;EAAA,IAC/B,OAAA;EAAA,SAEM,MAAA,EAAQ,MAAA;EAAA,SACR,WAAA;;EAGT,SAAA,IAAa,cAAA;EAnEd;EAAA,UAsEW,iBAAA,GAAoB,gBAAA,CAC5B,SAAA,EACA,aAAA,EACA,gBAAA;AAAA;;;;;;KAUQ,SAAA,GAAY,eAAA;;;;;KAMZ,SAAA,KACN,MAAA,8EAE8B,MAAA,qBAChC,eAAA,CAAgB,CAAA,EAAG,aAAA,EAAe,gBAAA;;;;;;KAO1B,eAAA,KACN,MAAA,8EAE8B,MAAA,qBAChC,eAAA,CAAgB,CAAA,EAAG,aAAA,EAAe,gBAAA;;;;;;;;;;iBAWtB,SAAA,KACV,MAAA,8EAE8B,MAAA,kBAAA,CAElC,OAAA,EAAS,kBAAA,CAAiB,cAAA,CAAe,CAAA,IACzC,UAAA,GAAa,UAAA,GACZ,eAAA,CAAgB,CAAA,EAAG,aAAA,EAAe,gBAAA"}
|
package/dist/use-stream.js
CHANGED
|
@@ -46,6 +46,7 @@ function useStream(options, destroyRef) {
|
|
|
46
46
|
webSocketFactory: hasCustomAdapter ? void 0 : asBag.webSocketFactory,
|
|
47
47
|
onThreadId: options.onThreadId,
|
|
48
48
|
onCreated: options.onCreated,
|
|
49
|
+
onCompleted: options.onCompleted,
|
|
49
50
|
initialValues: options.initialValues,
|
|
50
51
|
messagesKey: options.messagesKey
|
|
51
52
|
});
|
package/dist/use-stream.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-stream.js","names":["ClientCtor"],"sources":["../src/use-stream.ts"],"sourcesContent":["import {\n DestroyRef,\n computed,\n effect,\n inject,\n isSignal,\n signal,\n untracked,\n type Signal,\n} from \"@angular/core\";\nimport type { BaseMessage } from \"@langchain/core/messages\";\nimport type { Client, Interrupt } from \"@langchain/langgraph-sdk\";\nimport {\n filterOutHeadlessToolInterrupts,\n flushPendingHeadlessToolInterrupts,\n type AnyHeadlessToolImplementation,\n type OnToolCallback,\n} from \"@langchain/langgraph-sdk\";\nimport {\n Client as ClientCtor,\n type ClientConfig,\n type ThreadStream,\n} from \"@langchain/langgraph-sdk/client\";\nimport {\n StreamController,\n type AgentServerAdapter,\n type AgentServerOptions as StreamAgentServerOptions,\n type AssembledToolCall,\n type ChannelRegistry,\n type CustomAdapterOptions as StreamCustomAdapterOptions,\n type InferStateType,\n type InferSubagentStates,\n type RootSnapshot,\n type StateOf as StreamStateOf,\n type StreamSubmitOptions,\n type SubagentDiscoverySnapshot,\n type SubagentMap,\n type SubgraphByNodeMap,\n type SubgraphDiscoverySnapshot,\n type SubgraphMap,\n type UseStreamOptions as StreamUseStreamOptions,\n type WidenUpdateMessages,\n} from \"@langchain/langgraph-sdk/stream\";\n\n/** @deprecated Prefer {@link InferStateType}. */\nexport type StateOf<T> = StreamStateOf<T>;\n\ntype AngularThreadId = string | null | Signal<string | null | undefined>;\n\nexport type AgentServerOptions<StateType extends object> =\n StreamAgentServerOptions<StateType, AngularThreadId>;\n\nexport type CustomAdapterOptions<StateType extends object> =\n StreamCustomAdapterOptions<StateType, AngularThreadId, string>;\n\nexport type UseStreamOptions<\n StateType extends object = Record<string, unknown>,\n> = StreamUseStreamOptions<\n StateType,\n AngularThreadId,\n string | undefined,\n string | undefined,\n string\n>;\n\n/**\n * Private field on the handle that carries the\n * {@link StreamController} reference. Selector primitives read this\n * to reach the shared {@link ChannelRegistry}. Use the companion\n * `inject*` selectors (`injectMessages`, `injectToolCalls`,\n * `injectValues`, …) instead of reading this directly.\n */\nexport const STREAM_CONTROLLER: unique symbol = Symbol.for(\n \"@langchain/angular/controller\"\n);\n\n/**\n * Return shape of {@link useStream} — the Angular `StreamApi`.\n *\n * Reactivity primitives follow Angular conventions:\n *\n * - Data projections are `Signal<T>`; call them as functions in\n * templates (`stream.messages()`). They are snapshots — never\n * mutate the returned arrays / maps.\n * - Imperative methods (`submit` / `stop` / `respond`) are plain\n * functions. No `WritableSignal`s are exposed on the root handle.\n * - Identity values captured at construction time (`client`,\n * `assistantId`) are exposed as plain values; remount the\n * component to swap them.\n */\nexport interface UseStreamReturn<\n T = Record<string, unknown>,\n InterruptType = unknown,\n ConfigurableType extends object = Record<string, unknown>,\n StateType extends object = InferStateType<T>,\n SubagentStates = InferSubagentStates<T>,\n> {\n readonly values: Signal<StateType>;\n readonly messages: Signal<BaseMessage[]>;\n readonly toolCalls: Signal<AssembledToolCall[]>;\n readonly interrupts: Signal<Interrupt<InterruptType>[]>;\n readonly interrupt: Signal<Interrupt<InterruptType> | undefined>;\n readonly isLoading: Signal<boolean>;\n readonly isThreadLoading: Signal<boolean>;\n readonly error: Signal<unknown>;\n readonly threadId: Signal<string | null>;\n\n /**\n * Promise that settles when the active thread's initial hydration\n * completes. Exposed so SSR/render-before-flush pipelines can\n * `await stream.hydrationPromise` before serialising.\n */\n readonly hydrationPromise: Signal<Promise<void>>;\n\n readonly subagents: Signal<\n ReadonlyMap<\n keyof SubagentStates & string extends never\n ? string\n : keyof SubagentStates & string,\n SubagentDiscoverySnapshot\n >\n >;\n readonly subgraphs: Signal<ReadonlyMap<string, SubgraphDiscoverySnapshot>>;\n readonly subgraphsByNode: Signal<\n ReadonlyMap<string, readonly SubgraphDiscoverySnapshot[]>\n >;\n\n submit(\n input: WidenUpdateMessages<Partial<StateType>> | null | undefined,\n options?: StreamSubmitOptions<StateType, ConfigurableType>\n ): Promise<void>;\n stop(): Promise<void>;\n respond(\n response: unknown,\n target?: { interruptId: string; namespace?: string[] }\n ): Promise<void>;\n\n readonly client: Client;\n readonly assistantId: string;\n\n /** v2 escape hatch — returns the bound {@link ThreadStream}. */\n getThread(): ThreadStream | undefined;\n\n /** @internal Used by selector primitives. */\n readonly [STREAM_CONTROLLER]: StreamController<\n StateType,\n InterruptType,\n ConfigurableType\n >;\n}\n\n/**\n * Erased handle useful as a parameter type for helper components that\n * pass a `stream` through to selector primitives without reading\n * `values` directly. Mirrors the React/Vue `AnyStream` alias.\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport type AnyStream = UseStreamReturn<any, any, any>;\n\n/**\n * Convenience alias — the fully-resolved return type of\n * {@link useStream} for a given source type `T`.\n */\nexport type StreamApi<\n T = Record<string, unknown>,\n InterruptType = unknown,\n ConfigurableType extends object = Record<string, unknown>,\n> = UseStreamReturn<T, InterruptType, ConfigurableType>;\n\n/**\n * React-compatible alias for the fully-resolved stream handle type.\n * Angular docs prefer {@link StreamApi}, but shared libraries can use\n * this name across framework bindings.\n */\nexport type UseStreamResult<\n T = Record<string, unknown>,\n InterruptType = unknown,\n ConfigurableType extends object = Record<string, unknown>,\n> = UseStreamReturn<T, InterruptType, ConfigurableType>;\n\n/**\n * Framework-free factory that constructs a {@link StreamController}\n * and wraps its stores in Angular Signals. Callers must supply the\n * {@link DestroyRef} that owns the controller's lifetime — it's\n * already captured by the public `injectStream` helper.\n *\n * Exported for advanced callers (e.g. testing utilities, custom\n * factories) that prefer to manage injection scope themselves.\n */\nexport function useStream<\n T = Record<string, unknown>,\n InterruptType = unknown,\n ConfigurableType extends object = Record<string, unknown>,\n>(\n options: UseStreamOptions<InferStateType<T>>,\n destroyRef?: DestroyRef\n): UseStreamReturn<T, InterruptType, ConfigurableType> {\n type StateType = InferStateType<T>;\n\n interface OptionsBag {\n assistantId?: string;\n threadId?: string | null | Signal<string | null | undefined>;\n client?: Client;\n apiUrl?: string;\n apiKey?: string;\n callerOptions?: ClientConfig[\"callerOptions\"];\n defaultHeaders?: ClientConfig[\"defaultHeaders\"];\n transport?: \"sse\" | \"websocket\" | AgentServerAdapter;\n fetch?: typeof fetch;\n webSocketFactory?: (url: string) => WebSocket;\n onThreadId?: (threadId: string) => void;\n onCreated?: (meta: { run_id: string; thread_id: string }) => void;\n initialValues?: StateType;\n messagesKey?: string;\n tools?: AnyHeadlessToolImplementation[];\n onTool?: OnToolCallback;\n }\n const asBag = options as OptionsBag;\n\n const hasCustomAdapter =\n asBag.transport != null && typeof asBag.transport !== \"string\";\n const transport = asBag.transport;\n\n const client: Client =\n asBag.client ??\n (new ClientCtor({\n apiUrl: asBag.apiUrl,\n apiKey: asBag.apiKey,\n callerOptions: asBag.callerOptions,\n defaultHeaders: asBag.defaultHeaders,\n }) as unknown as Client);\n\n // Custom adapters may omit `assistantId`; the controller still\n // requires one so it has something to forward to `threads.stream`.\n const sentinel = \"_\";\n const assistantId =\n \"assistantId\" in options ? (options.assistantId ?? sentinel) : sentinel;\n\n // Normalize threadId input to a signal — callers may pass plain\n // values, nulls, or their own signals.\n const threadIdInput: Signal<string | null> = (() => {\n const raw = asBag.threadId;\n if (isSignal(raw)) {\n return computed(\n () => (raw as Signal<string | null | undefined>)() ?? null\n );\n }\n const initial: string | null = (raw as string | null | undefined) ?? null;\n return signal(initial) as unknown as Signal<string | null>;\n })();\n\n const controller = new StreamController<\n StateType,\n InterruptType,\n ConfigurableType\n >({\n assistantId,\n // Cast: the runtime `Client` is state-shape agnostic, but the\n // controller declares `client: Client<StateType>` for its own\n // typings. Same cast is applied in the React/Vue bindings.\n client: client as unknown as Client<StateType>,\n threadId: untracked(() => threadIdInput()),\n transport,\n fetch: hasCustomAdapter ? undefined : asBag.fetch,\n webSocketFactory: hasCustomAdapter ? undefined : asBag.webSocketFactory,\n onThreadId: options.onThreadId,\n onCreated: options.onCreated,\n initialValues: options.initialValues,\n messagesKey: options.messagesKey,\n });\n\n // Deferred dispose — matches the React `useEffect(() =>\n // controller.activate())` and Vue `onScopeDispose(deactivate)`\n // patterns. HMR / scope-reuse scenarios stay clean because\n // `activate()` cancels the pending dispose if the scope survives.\n const deactivate = controller.activate();\n const ref = destroyRef ?? inject(DestroyRef);\n ref.onDestroy(deactivate);\n\n // ─── Reactivity bridge: StreamStore → Signal ────────────────────────\n function bindStore<S>(\n subscribe: (listener: () => void) => () => void,\n getSnapshot: () => S\n ): Signal<S> {\n const s = signal<S>(getSnapshot());\n const unsubscribe = subscribe(() => {\n s.set(getSnapshot());\n });\n ref.onDestroy(unsubscribe);\n return computed(() => s());\n }\n\n const rootSignal = bindStore<RootSnapshot<StateType, InterruptType>>(\n controller.rootStore.subscribe,\n controller.rootStore.getSnapshot\n );\n const subagentSignal = bindStore<SubagentMap>(\n controller.subagentStore.subscribe,\n controller.subagentStore.getSnapshot\n );\n const subgraphSignal = bindStore<SubgraphMap>(\n controller.subgraphStore.subscribe,\n controller.subgraphStore.getSnapshot\n );\n const subgraphByNodeSignal = bindStore<SubgraphByNodeMap>(\n controller.subgraphByNodeStore.subscribe,\n controller.subgraphByNodeStore.getSnapshot\n );\n\n const values = computed(() => rootSignal().values);\n const messages = computed(() => rootSignal().messages);\n const toolCalls = computed(() => rootSignal().toolCalls);\n const interrupts = computed(() =>\n filterOutHeadlessToolInterrupts(rootSignal().interrupts)\n );\n const interrupt = computed(() => interrupts()[0]);\n const isLoading = computed(() => rootSignal().isLoading);\n const isThreadLoading = computed(() => rootSignal().isThreadLoading);\n const error = computed(() => rootSignal().error);\n const threadId = computed(() => rootSignal().threadId);\n\n // `hydrationPromise` is a property on the controller that gets\n // swapped on every `hydrate()` call. Exposing it as a signal lets\n // templates `await stream.hydrationPromise()` reactively; we\n // refresh the reference when the root store settles a new promise.\n const hydrationPromise = computed(() => {\n rootSignal();\n return controller.hydrationPromise;\n });\n\n // ─── threadId reactivity ────────────────────────────────────────────\n //\n // Re-hydrate whenever the caller's threadId input changes after\n // construction. The initial hydrate already fired synchronously in\n // the controller constructor, so we compare against the snapshot\n // captured at construction time rather than blindly skipping the\n // first run — in Angular, `@Input()` bindings apply *between*\n // construction and the first effect tick, so the first read can\n // legitimately be a different (updated) value that needs to\n // hydrate.\n const initialThreadId = untracked(() => threadIdInput()) ?? null;\n let lastAppliedThreadId: string | null = initialThreadId;\n effect(() => {\n const next = threadIdInput() ?? null;\n if (next === lastAppliedThreadId) return;\n lastAppliedThreadId = next;\n untracked(() => {\n void controller.hydrate(next);\n });\n });\n\n // ─── Headless-tool handling ─────────────────────────────────────────\n const tools = options.tools;\n const onTool = options.onTool;\n if (tools?.length) {\n const handledTools = new Set<string>();\n\n // Clear the dedup set whenever the thread id changes.\n effect(() => {\n threadIdInput();\n untracked(() => handledTools.clear());\n });\n\n effect(() => {\n const snapshot = rootSignal();\n const bag = snapshot.values as unknown as Record<string, unknown>;\n const existing = Array.isArray(bag?.__interrupt__)\n ? (bag.__interrupt__ as Interrupt[])\n : [];\n const combined: Interrupt[] = [\n ...existing,\n ...(snapshot.interrupts as unknown as Interrupt[]),\n ];\n if (combined.length === 0) return;\n untracked(() => {\n flushPendingHeadlessToolInterrupts(\n { ...bag, __interrupt__: combined },\n tools,\n handledTools,\n {\n onTool,\n defer: (run) => {\n void Promise.resolve().then(run);\n },\n resumeSubmit: (command) =>\n controller.submit(null, {\n command,\n } as StreamSubmitOptions<StateType, ConfigurableType>),\n }\n );\n });\n });\n }\n\n const handle: UseStreamReturn<T, InterruptType, ConfigurableType> = {\n values: values as UseStreamReturn<\n T,\n InterruptType,\n ConfigurableType\n >[\"values\"],\n messages,\n toolCalls,\n interrupts,\n interrupt,\n isLoading,\n isThreadLoading,\n error,\n threadId,\n hydrationPromise,\n subagents: subagentSignal as UseStreamReturn<\n T,\n InterruptType,\n ConfigurableType\n >[\"subagents\"],\n subgraphs: subgraphSignal,\n subgraphsByNode: subgraphByNodeSignal,\n submit: (input, submitOptions) => controller.submit(input, submitOptions),\n stop: () => controller.stop(),\n respond: (response, target) => controller.respond(response, target),\n getThread: () => controller.getThread(),\n client,\n assistantId,\n [STREAM_CONTROLLER]: controller,\n };\n\n return handle;\n}\n\n/**\n * Helper used by the selector primitives to reach the underlying\n * {@link ChannelRegistry} from a stream handle. Kept internal —\n * application code should call `injectMessages`, `injectToolCalls`,\n * etc. instead of reading this directly.\n *\n * @internal\n */\nexport function getRegistry(\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n stream: UseStreamReturn<any, any, any>\n): ChannelRegistry {\n return stream[STREAM_CONTROLLER].registry;\n}\n\nexport type { ThreadStream };\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"use-stream.js","names":["ClientCtor"],"sources":["../src/use-stream.ts"],"sourcesContent":["import {\n DestroyRef,\n computed,\n effect,\n inject,\n isSignal,\n signal,\n untracked,\n type Signal,\n} from \"@angular/core\";\nimport type { BaseMessage } from \"@langchain/core/messages\";\nimport type { Client, Interrupt } from \"@langchain/langgraph-sdk\";\nimport {\n filterOutHeadlessToolInterrupts,\n flushPendingHeadlessToolInterrupts,\n type AnyHeadlessToolImplementation,\n type OnToolCallback,\n} from \"@langchain/langgraph-sdk\";\nimport {\n Client as ClientCtor,\n type ClientConfig,\n type ThreadStream,\n} from \"@langchain/langgraph-sdk/client\";\nimport {\n StreamController,\n type AgentServerAdapter,\n type AgentServerOptions as StreamAgentServerOptions,\n type ChannelRegistry,\n type CustomAdapterOptions as StreamCustomAdapterOptions,\n type InferStateType,\n type InferToolCalls,\n type InferSubagentStates,\n type RootSnapshot,\n type RunCompletedInfo,\n type RunExecutionInfo,\n type StreamSubmitOptions,\n type SubagentDiscoverySnapshot,\n type SubagentMap,\n type SubgraphByNodeMap,\n type SubgraphDiscoverySnapshot,\n type SubgraphMap,\n type UseStreamOptions as StreamUseStreamOptions,\n type WidenUpdateMessages,\n} from \"@langchain/langgraph-sdk/stream\";\n\ntype AngularThreadId = string | null | Signal<string | null | undefined>;\n\nexport type AgentServerOptions<StateType extends object> =\n StreamAgentServerOptions<StateType, AngularThreadId>;\n\nexport type CustomAdapterOptions<StateType extends object> =\n StreamCustomAdapterOptions<StateType, AngularThreadId, string>;\n\nexport type UseStreamOptions<\n StateType extends object = Record<string, unknown>,\n> = StreamUseStreamOptions<\n StateType,\n AngularThreadId,\n string | undefined,\n string | undefined,\n string\n>;\n\n/**\n * Private field on the handle that carries the\n * {@link StreamController} reference. Selector primitives read this\n * to reach the shared {@link ChannelRegistry}. Use the companion\n * `inject*` selectors (`injectMessages`, `injectToolCalls`,\n * `injectValues`, …) instead of reading this directly.\n */\nexport const STREAM_CONTROLLER: unique symbol = Symbol.for(\n \"@langchain/angular/controller\"\n);\n\n/**\n * Return shape of {@link useStream} — the Angular `StreamApi`.\n *\n * Reactivity primitives follow Angular conventions:\n *\n * - Data projections are `Signal<T>`; call them as functions in\n * templates (`stream.messages()`). They are snapshots — never\n * mutate the returned arrays / maps.\n * - Imperative methods (`submit` / `stop` / `respond`) are plain\n * functions. No `WritableSignal`s are exposed on the root handle.\n * - Identity values captured at construction time (`client`,\n * `assistantId`) are exposed as plain values; remount the\n * component to swap them.\n */\nexport interface UseStreamReturn<\n T = Record<string, unknown>,\n InterruptType = unknown,\n ConfigurableType extends object = Record<string, unknown>,\n StateType extends object = InferStateType<T>,\n SubagentStates = InferSubagentStates<T>,\n> {\n readonly values: Signal<StateType>;\n readonly messages: Signal<BaseMessage[]>;\n readonly toolCalls: Signal<InferToolCalls<T>[]>;\n readonly interrupts: Signal<Interrupt<InterruptType>[]>;\n readonly interrupt: Signal<Interrupt<InterruptType> | undefined>;\n readonly isLoading: Signal<boolean>;\n readonly isThreadLoading: Signal<boolean>;\n readonly error: Signal<unknown>;\n readonly threadId: Signal<string | null>;\n\n /**\n * Promise that settles when the active thread's initial hydration\n * completes. Exposed so SSR/render-before-flush pipelines can\n * `await stream.hydrationPromise` before serialising.\n */\n readonly hydrationPromise: Signal<Promise<void>>;\n\n readonly subagents: Signal<\n ReadonlyMap<\n keyof SubagentStates & string extends never\n ? string\n : keyof SubagentStates & string,\n SubagentDiscoverySnapshot\n >\n >;\n readonly subgraphs: Signal<ReadonlyMap<string, SubgraphDiscoverySnapshot>>;\n readonly subgraphsByNode: Signal<\n ReadonlyMap<string, readonly SubgraphDiscoverySnapshot[]>\n >;\n\n submit(\n input: WidenUpdateMessages<Partial<StateType>> | null | undefined,\n options?: StreamSubmitOptions<StateType, ConfigurableType>\n ): Promise<void>;\n stop(): Promise<void>;\n respond(\n response: unknown,\n target?: { interruptId: string; namespace?: string[] }\n ): Promise<void>;\n\n readonly client: Client;\n readonly assistantId: string;\n\n /** v2 escape hatch — returns the bound {@link ThreadStream}. */\n getThread(): ThreadStream | undefined;\n\n /** @internal Used by selector primitives. */\n readonly [STREAM_CONTROLLER]: StreamController<\n StateType,\n InterruptType,\n ConfigurableType\n >;\n}\n\n/**\n * Erased handle useful as a parameter type for helper components that\n * pass a `stream` through to selector primitives without reading\n * `values` directly. Mirrors the React/Vue `AnyStream` alias.\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport type AnyStream = UseStreamReturn<any, any, any>;\n\n/**\n * Convenience alias — the fully-resolved return type of\n * {@link useStream} for a given source type `T`.\n */\nexport type StreamApi<\n T = Record<string, unknown>,\n InterruptType = unknown,\n ConfigurableType extends object = Record<string, unknown>,\n> = UseStreamReturn<T, InterruptType, ConfigurableType>;\n\n/**\n * React-compatible alias for the fully-resolved stream handle type.\n * Angular docs prefer {@link StreamApi}, but shared libraries can use\n * this name across framework bindings.\n */\nexport type UseStreamResult<\n T = Record<string, unknown>,\n InterruptType = unknown,\n ConfigurableType extends object = Record<string, unknown>,\n> = UseStreamReturn<T, InterruptType, ConfigurableType>;\n\n/**\n * Framework-free factory that constructs a {@link StreamController}\n * and wraps its stores in Angular Signals. Callers must supply the\n * {@link DestroyRef} that owns the controller's lifetime — it's\n * already captured by the public `injectStream` helper.\n *\n * Exported for advanced callers (e.g. testing utilities, custom\n * factories) that prefer to manage injection scope themselves.\n */\nexport function useStream<\n T = Record<string, unknown>,\n InterruptType = unknown,\n ConfigurableType extends object = Record<string, unknown>,\n>(\n options: UseStreamOptions<InferStateType<T>>,\n destroyRef?: DestroyRef\n): UseStreamReturn<T, InterruptType, ConfigurableType> {\n type StateType = InferStateType<T>;\n\n interface OptionsBag {\n assistantId?: string;\n threadId?: string | null | Signal<string | null | undefined>;\n client?: Client;\n apiUrl?: string;\n apiKey?: string;\n callerOptions?: ClientConfig[\"callerOptions\"];\n defaultHeaders?: ClientConfig[\"defaultHeaders\"];\n transport?: \"sse\" | \"websocket\" | AgentServerAdapter;\n fetch?: typeof fetch;\n webSocketFactory?: (url: string) => WebSocket;\n onThreadId?: (threadId: string) => void;\n onCreated?: (info: RunExecutionInfo) => void;\n onCompleted?: (info: RunCompletedInfo) => void;\n initialValues?: StateType;\n messagesKey?: string;\n tools?: AnyHeadlessToolImplementation[];\n onTool?: OnToolCallback;\n }\n const asBag = options as OptionsBag;\n\n const hasCustomAdapter =\n asBag.transport != null && typeof asBag.transport !== \"string\";\n const transport = asBag.transport;\n\n const client: Client =\n asBag.client ??\n (new ClientCtor({\n apiUrl: asBag.apiUrl,\n apiKey: asBag.apiKey,\n callerOptions: asBag.callerOptions,\n defaultHeaders: asBag.defaultHeaders,\n }) as unknown as Client);\n\n // Custom adapters may omit `assistantId`; the controller still\n // requires one so it has something to forward to `threads.stream`.\n const sentinel = \"_\";\n const assistantId =\n \"assistantId\" in options ? (options.assistantId ?? sentinel) : sentinel;\n\n // Normalize threadId input to a signal — callers may pass plain\n // values, nulls, or their own signals.\n const threadIdInput: Signal<string | null> = (() => {\n const raw = asBag.threadId;\n if (isSignal(raw)) {\n return computed(\n () => (raw as Signal<string | null | undefined>)() ?? null\n );\n }\n const initial: string | null = (raw as string | null | undefined) ?? null;\n return signal(initial) as unknown as Signal<string | null>;\n })();\n\n const controller = new StreamController<\n StateType,\n InterruptType,\n ConfigurableType\n >({\n assistantId,\n // Cast: the runtime `Client` is state-shape agnostic, but the\n // controller declares `client: Client<StateType>` for its own\n // typings. Same cast is applied in the React/Vue bindings.\n client: client as unknown as Client<StateType>,\n threadId: untracked(() => threadIdInput()),\n transport,\n fetch: hasCustomAdapter ? undefined : asBag.fetch,\n webSocketFactory: hasCustomAdapter ? undefined : asBag.webSocketFactory,\n onThreadId: options.onThreadId,\n onCreated: options.onCreated,\n onCompleted: options.onCompleted,\n initialValues: options.initialValues,\n messagesKey: options.messagesKey,\n });\n\n // Deferred dispose — matches the React `useEffect(() =>\n // controller.activate())` and Vue `onScopeDispose(deactivate)`\n // patterns. HMR / scope-reuse scenarios stay clean because\n // `activate()` cancels the pending dispose if the scope survives.\n const deactivate = controller.activate();\n const ref = destroyRef ?? inject(DestroyRef);\n ref.onDestroy(deactivate);\n\n // ─── Reactivity bridge: StreamStore → Signal ────────────────────────\n function bindStore<S>(\n subscribe: (listener: () => void) => () => void,\n getSnapshot: () => S\n ): Signal<S> {\n const s = signal<S>(getSnapshot());\n const unsubscribe = subscribe(() => {\n s.set(getSnapshot());\n });\n ref.onDestroy(unsubscribe);\n return computed(() => s());\n }\n\n const rootSignal = bindStore<RootSnapshot<StateType, InterruptType>>(\n controller.rootStore.subscribe,\n controller.rootStore.getSnapshot\n );\n const subagentSignal = bindStore<SubagentMap>(\n controller.subagentStore.subscribe,\n controller.subagentStore.getSnapshot\n );\n const subgraphSignal = bindStore<SubgraphMap>(\n controller.subgraphStore.subscribe,\n controller.subgraphStore.getSnapshot\n );\n const subgraphByNodeSignal = bindStore<SubgraphByNodeMap>(\n controller.subgraphByNodeStore.subscribe,\n controller.subgraphByNodeStore.getSnapshot\n );\n\n const values = computed(() => rootSignal().values);\n const messages = computed(() => rootSignal().messages);\n const toolCalls = computed(\n () => rootSignal().toolCalls as InferToolCalls<T>[]\n );\n const interrupts = computed(() =>\n filterOutHeadlessToolInterrupts(rootSignal().interrupts)\n );\n const interrupt = computed(() => interrupts()[0]);\n const isLoading = computed(() => rootSignal().isLoading);\n const isThreadLoading = computed(() => rootSignal().isThreadLoading);\n const error = computed(() => rootSignal().error);\n const threadId = computed(() => rootSignal().threadId);\n\n // `hydrationPromise` is a property on the controller that gets\n // swapped on every `hydrate()` call. Exposing it as a signal lets\n // templates `await stream.hydrationPromise()` reactively; we\n // refresh the reference when the root store settles a new promise.\n const hydrationPromise = computed(() => {\n rootSignal();\n return controller.hydrationPromise;\n });\n\n // ─── threadId reactivity ────────────────────────────────────────────\n //\n // Re-hydrate whenever the caller's threadId input changes after\n // construction. The initial hydrate already fired synchronously in\n // the controller constructor, so we compare against the snapshot\n // captured at construction time rather than blindly skipping the\n // first run — in Angular, `@Input()` bindings apply *between*\n // construction and the first effect tick, so the first read can\n // legitimately be a different (updated) value that needs to\n // hydrate.\n const initialThreadId = untracked(() => threadIdInput()) ?? null;\n let lastAppliedThreadId: string | null = initialThreadId;\n effect(() => {\n const next = threadIdInput() ?? null;\n if (next === lastAppliedThreadId) return;\n lastAppliedThreadId = next;\n untracked(() => {\n void controller.hydrate(next);\n });\n });\n\n // ─── Headless-tool handling ─────────────────────────────────────────\n const tools = options.tools;\n const onTool = options.onTool;\n if (tools?.length) {\n const handledTools = new Set<string>();\n\n // Clear the dedup set whenever the thread id changes.\n effect(() => {\n threadIdInput();\n untracked(() => handledTools.clear());\n });\n\n effect(() => {\n const snapshot = rootSignal();\n const bag = snapshot.values as unknown as Record<string, unknown>;\n const existing = Array.isArray(bag?.__interrupt__)\n ? (bag.__interrupt__ as Interrupt[])\n : [];\n const combined: Interrupt[] = [\n ...existing,\n ...(snapshot.interrupts as unknown as Interrupt[]),\n ];\n if (combined.length === 0) return;\n untracked(() => {\n flushPendingHeadlessToolInterrupts(\n { ...bag, __interrupt__: combined },\n tools,\n handledTools,\n {\n onTool,\n defer: (run) => {\n void Promise.resolve().then(run);\n },\n resumeSubmit: (command) =>\n controller.submit(null, {\n command,\n } as StreamSubmitOptions<StateType, ConfigurableType>),\n }\n );\n });\n });\n }\n\n const handle: UseStreamReturn<T, InterruptType, ConfigurableType> = {\n values: values as UseStreamReturn<\n T,\n InterruptType,\n ConfigurableType\n >[\"values\"],\n messages,\n toolCalls,\n interrupts,\n interrupt,\n isLoading,\n isThreadLoading,\n error,\n threadId,\n hydrationPromise,\n subagents: subagentSignal as UseStreamReturn<\n T,\n InterruptType,\n ConfigurableType\n >[\"subagents\"],\n subgraphs: subgraphSignal,\n subgraphsByNode: subgraphByNodeSignal,\n submit: (input, submitOptions) => controller.submit(input, submitOptions),\n stop: () => controller.stop(),\n respond: (response, target) => controller.respond(response, target),\n getThread: () => controller.getThread(),\n client,\n assistantId,\n [STREAM_CONTROLLER]: controller,\n };\n\n return handle;\n}\n\n/**\n * Helper used by the selector primitives to reach the underlying\n * {@link ChannelRegistry} from a stream handle. Kept internal —\n * application code should call `injectMessages`, `injectToolCalls`,\n * etc. instead of reading this directly.\n *\n * @internal\n */\nexport function getRegistry(\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n stream: UseStreamReturn<any, any, any>\n): ChannelRegistry {\n return stream[STREAM_CONTROLLER].registry;\n}\n\nexport type { ThreadStream };\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@langchain/angular",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.5",
|
|
4
4
|
"description": "Angular integration for LangGraph & LangChain",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
"directory": "libs/sdk-angular"
|
|
11
11
|
},
|
|
12
12
|
"dependencies": {
|
|
13
|
-
"@langchain/langgraph-sdk": "1.9.
|
|
13
|
+
"@langchain/langgraph-sdk": "1.9.5"
|
|
14
14
|
},
|
|
15
15
|
"devDependencies": {
|
|
16
16
|
"@analogjs/vite-plugin-angular": "^2.5.0",
|