@threadplane/langgraph 0.0.47 → 0.0.50

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/package.json CHANGED
@@ -1,6 +1,15 @@
1
1
  {
2
2
  "name": "@threadplane/langgraph",
3
- "version": "0.0.47",
3
+ "version": "0.0.50",
4
+ "description": "LangGraph adapter for @threadplane/chat — Angular bindings for LangGraph Platform.",
5
+ "keywords": [
6
+ "angular",
7
+ "langgraph",
8
+ "langchain",
9
+ "agent",
10
+ "adapter",
11
+ "threadplane"
12
+ ],
4
13
  "peerDependencies": {
5
14
  "@threadplane/chat": "*",
6
15
  "@angular/core": "^20.0.0 || ^21.0.0",
@@ -1,12 +1,13 @@
1
- import * as _langchain_langgraph_sdk from '@langchain/langgraph-sdk';
2
- import { Config, Checkpoint, Command, Metadata, StreamMode, ThreadState, BagTemplate, Interrupt, ToolCallWithResult, ToolProgress, InferBag, Client } from '@langchain/langgraph-sdk';
3
- export { BagTemplate, InferBag, Interrupt, ThreadState } from '@langchain/langgraph-sdk';
4
1
  import * as i0 from '@angular/core';
5
2
  import { InjectionToken, Signal, ResourceStatus as ResourceStatus$1, Provider, WritableSignal } from '@angular/core';
3
+ import { BaseMessage, AIMessage } from '@langchain/core/messages';
4
+ import * as _langchain_langgraph_sdk from '@langchain/langgraph-sdk';
5
+ import { ThreadState, Config, Checkpoint, Command, Metadata, StreamMode, BagTemplate, Interrupt, ToolCallWithResult, ToolProgress, Client } from '@langchain/langgraph-sdk';
6
+ export { BagTemplate, InferBag, Interrupt, ThreadState } from '@langchain/langgraph-sdk';
7
+ import { AgentRuntimeTelemetrySink, AgentWithHistory, AgentSubmitInput, AgentSubmitOptions, ClientToolsCapability, Message, AgentStatus, ToolCall, AgentInterrupt, Subagent, AgentCheckpoint, MockAgent, MockAgentOptions, Citation, Thread } from '@threadplane/chat';
6
8
  import { MessageMetadata } from '@langchain/langgraph-sdk/ui';
7
9
  export { SubmitOptions } from '@langchain/langgraph-sdk/ui';
8
- import { BaseMessage, AIMessage } from '@langchain/core/messages';
9
- import { AgentRuntimeTelemetrySink, AgentWithHistory, AgentSubmitInput, AgentSubmitOptions, Message, AgentStatus, AgentInterrupt, ToolCall, AgentCheckpoint, Subagent, Citation, Thread } from '@threadplane/chat';
10
+ import { FakeAgentConfig } from '@threadplane/chat/testing';
10
11
 
11
12
  interface AgentLifecycle {
12
13
  /** Epoch ms of the first stream chunk arrival. Resets on switchThread(). */
@@ -165,6 +166,23 @@ interface AgentTransport {
165
166
  }): Promise<void>;
166
167
  }
167
168
  /** Options for creating a LangGraph-backed agent via {@link agent}. */
169
+ /**
170
+ * Tuning options for the underlying LangGraph SDK `Client` constructed by the
171
+ * default {@link FetchStreamTransport}. Ignored when a custom `transport` is
172
+ * supplied (the transport owns its own client).
173
+ */
174
+ interface LangGraphClientOptions {
175
+ /**
176
+ * How many times a failed request — including the initial stream connect —
177
+ * is retried with exponential backoff before the error surfaces. Maps to the
178
+ * SDK's `callerOptions.maxRetries`. Omitted → the SDK default (currently 4).
179
+ *
180
+ * Set `0` to fail fast: useful for e2e tests that force a connection failure
181
+ * and assert the error surfaces promptly, rather than after the full
182
+ * multi-second backoff window.
183
+ */
184
+ maxRetries?: number;
185
+ }
168
186
  interface AgentOptions<T, _ResolvedBag extends BagTemplate> {
169
187
  /** Base URL of the LangGraph Platform API. Defaults to `provideAgent({ apiUrl })` when omitted. */
170
188
  apiUrl?: string;
@@ -182,6 +200,8 @@ interface AgentOptions<T, _ResolvedBag extends BagTemplate> {
182
200
  toMessage?: (msg: unknown) => BaseMessage;
183
201
  /** Custom transport. Defaults to FetchStreamTransport. */
184
202
  transport?: AgentTransport;
203
+ /** Tuning options for the default transport's LangGraph SDK client (e.g. retry budget). */
204
+ clientOptions?: LangGraphClientOptions;
185
205
  /** Optional app-owned telemetry sink. No telemetry is emitted unless this is provided. */
186
206
  telemetry?: AgentRuntimeTelemetrySink | false;
187
207
  /** When true, subagent messages are filtered from the main messages signal. */
@@ -203,7 +223,7 @@ interface SubagentStreamRef {
203
223
  messages: Signal<BaseMessage[]>;
204
224
  }
205
225
  /**
206
- * Unified LangGraph agent surface returned by `agent({...})`.
226
+ * Unified LangGraph agent surface returned by `injectAgent()`.
207
227
  *
208
228
  * Extends the runtime-neutral `AgentWithHistory` contract (chat-consumable)
209
229
  * with the full LangGraph-specific API. One object drives both `<chat>` and
@@ -223,6 +243,13 @@ interface LangGraphAgent<T = unknown, ResolvedBag extends BagTemplate = BagTempl
223
243
  experimentalBranchTree: Signal<AgentBranchTree<T>>;
224
244
  /** Submit input, resume commands, checkpoint forks, or other LangGraph run options. */
225
245
  submit: (input: AgentSubmitInput | null | undefined, opts?: AgentSubmitOptions & LangGraphSubmitOptions) => Promise<void>;
246
+ /**
247
+ * Client-declared, client-executed tools. Call setCatalog() to register
248
+ * tool specs; the catalog is automatically shipped with every run via
249
+ * `input.client_tools`. Pending tool calls appear in pending() after
250
+ * the run ends; resolve() returns a result and continues the run.
251
+ */
252
+ clientTools: ClientToolsCapability;
226
253
  /** Current agent state values (raw, typed per the type parameter T). */
227
254
  value: Signal<T>;
228
255
  /** True once at least one value or message has been received. */
@@ -278,51 +305,75 @@ interface LangGraphAgent<T = unknown, ResolvedBag extends BagTemplate = BagTempl
278
305
  }
279
306
 
280
307
  /**
281
- * Creates a LangGraph-backed Angular agent.
308
+ * Configuration for an agent instance.
309
+ * Combines connection defaults with per-component options so the
310
+ * agent can be constructed once at provider time and injected
311
+ * everywhere it is needed.
312
+ */
313
+ interface AgentConfig<T = Record<string, unknown>, _Bag extends BagTemplate = BagTemplate> {
314
+ /** Base URL of the LangGraph Platform API (e.g., `'http://localhost:2024'`). */
315
+ apiUrl?: string;
316
+ /** Agent or graph identifier on the LangGraph platform. */
317
+ assistantId?: string;
318
+ /** Thread ID to connect to. Pass a Signal for reactive thread switching. */
319
+ threadId?: Signal<string | null> | string | null;
320
+ /** Called when a new thread is auto-created by the transport. */
321
+ onThreadId?: (id: string) => void;
322
+ /** Initial state values before the first stream response arrives. */
323
+ initialValues?: Partial<T>;
324
+ /** Throttle signal updates in milliseconds. `false` to disable. */
325
+ throttle?: number | false;
326
+ /** Custom message deserializer for non-standard message formats. */
327
+ toMessage?: (msg: unknown) => BaseMessage;
328
+ /** Custom transport. Defaults to {@link FetchStreamTransport}. */
329
+ transport?: AgentTransport;
330
+ /** Tuning options for the default transport's LangGraph SDK client (e.g. retry budget). */
331
+ clientOptions?: LangGraphClientOptions;
332
+ /** Optional app-owned telemetry sink. No telemetry is emitted unless this is provided. */
333
+ telemetry?: AgentRuntimeTelemetrySink | false;
334
+ /** When true, subagent messages are filtered from the main messages signal. */
335
+ filterSubagentMessages?: boolean;
336
+ /** Tool names that indicate a subagent invocation. */
337
+ subagentToolNames?: string[];
338
+ }
339
+ /**
340
+ * Wire the LangGraph adapter into Angular's dependency injection.
282
341
  *
283
- * Must be called within an Angular injection context (component constructor,
284
- * field initializer, or `runInInjectionContext`). Returns a unified
285
- * {@link LangGraphAgent} whose properties are Angular Signals that update
286
- * in real time as LangGraph streams messages, values, tool calls, interrupts,
287
- * subagent state, and checkpoint history.
342
+ * Registers a singleton `LangGraphAgent` constructed from `config`. Retrieve it
343
+ * in any component with `injectAgent()`. Provide this at the application root
344
+ * (`app.config.ts`) for an app-wide agent.
288
345
  *
289
- * @typeParam T - The state shape returned by the agent
290
- * @typeParam Bag - Optional bag template for typed interrupts and submit payloads
291
- * @param options - Configuration for the LangGraph agent
292
- * @returns A {@link LangGraphAgent} with reactive signals and action methods
346
+ * To use a different agent in a component subtree, re-provide
347
+ * `provideAgent({...})` in that component's `providers: []` array
348
+ * Angular's hierarchical DI scopes the singleton accordingly.
293
349
  *
294
- * @example
295
- * ```typescript
296
- * // In a component field initializer
297
- * const chat = agent({
298
- * assistantId: 'chat_agent',
299
- * apiUrl: 'http://localhost:2024',
300
- * threadId: signal(this.savedThreadId),
301
- * onThreadId: (id) => localStorage.setItem('threadId', id),
302
- * });
350
+ * **Static vs factory config.** Pass a plain `AgentConfig` object when the
351
+ * config is known up front. Pass a `() => AgentConfig` factory when the config
352
+ * depends on runtime/DI state the factory runs inside an Angular injection
353
+ * context, so it may call `inject()` to read services, route params, or
354
+ * component-scoped signals:
303
355
  *
304
- * // Access signals in template
305
- * // chat.messages(), chat.status(), chat.error()
356
+ * ```ts
357
+ * providers: [
358
+ * provideAgent(() => {
359
+ * const route = inject(ActivatedRoute);
360
+ * return { assistantId: 'chat', threadId: toSignal(route.paramMap) };
361
+ * }),
362
+ * ];
306
363
  * ```
307
364
  */
308
- declare function agent<T = Record<string, unknown>, Bag extends BagTemplate = BagTemplate>(options: AgentOptions<T, InferBag<T, Bag>>): LangGraphAgent<T, InferBag<T, Bag>>;
365
+ declare function provideAgent<T = Record<string, unknown>>(configOrFactory: AgentConfig<T> | (() => AgentConfig<T>)): Provider[];
309
366
 
310
367
  /**
311
- * Global configuration for agent instances.
312
- * Properties set here serve as defaults that can be overridden per-call.
313
- */
314
- interface AgentConfig {
315
- /** Base URL of the LangGraph Platform API (e.g., `'http://localhost:2024'`). */
316
- apiUrl?: string;
317
- /** Custom transport implementation. Defaults to {@link FetchStreamTransport}. */
318
- transport?: AgentTransport;
319
- }
320
- declare const AGENT_CONFIG: InjectionToken<AgentConfig>;
321
- /**
322
- * Angular provider factory that registers global defaults for all
323
- * agent instances in the application.
368
+ * Retrieve the LangGraph-backed Agent from the current Angular injection context.
369
+ *
370
+ * Mirrors `@threadplane/ag-ui`'s `injectAgent()` so consumer code is identical
371
+ * regardless of which adapter is wired in `app.config.ts`. The agent is a
372
+ * singleton scoped to the injector that called `provideAgent()` — re-provide
373
+ * in a child component's `providers: []` to scope a different agent to that
374
+ * subtree (Angular's hierarchical DI handles the rest).
324
375
  */
325
- declare function provideAgent(config: AgentConfig): Provider;
376
+ declare function injectAgent<T = Record<string, unknown>, ResolvedBag extends BagTemplate = BagTemplate>(): LangGraphAgent<T, ResolvedBag>;
326
377
 
327
378
  /**
328
379
  * Optional registry that collects per-instance agent lifecycles within
@@ -419,8 +470,9 @@ declare class FetchStreamTransport implements AgentTransport {
419
470
  /**
420
471
  * @param apiUrl - Base URL of the LangGraph Platform API
421
472
  * @param onThreadId - Optional callback invoked when a new thread is created
473
+ * @param clientOptions - Optional SDK client tuning (e.g. `maxRetries`)
422
474
  */
423
- constructor(apiUrl: string, onThreadId?: (id: string) => void);
475
+ constructor(apiUrl: string, onThreadId?: (id: string) => void, clientOptions?: LangGraphClientOptions);
424
476
  /** Open a streaming connection, creating a thread if needed. */
425
477
  stream(assistantId: string, threadId: string | null, payload: unknown, signal: AbortSignal, options?: LangGraphSubmitOptions): AsyncIterable<StreamEvent>;
426
478
  /** Join an already-started run without creating a new thread. */
@@ -440,46 +492,85 @@ declare class FetchStreamTransport implements AgentTransport {
440
492
  /**
441
493
  * A LangGraphAgent mock with writable signals for easy test control.
442
494
  *
495
+ * Builds on the runtime-neutral {@link MockAgent} from `@threadplane/chat`
496
+ * (which supplies the neutral `Agent`-contract writable signals plus
497
+ * `submit`/`stop`/`regenerate` call tracking) and layers the LangGraph-specific
498
+ * writable signals on top.
499
+ *
443
500
  * Cast the result of `mockLangGraphAgent()` to this type to access
444
501
  * writable signals without unsafe casts in test files.
445
502
  */
446
503
  interface MockLangGraphAgent extends LangGraphAgent<any, any> {
447
504
  messages: WritableSignal<Message[]>;
448
- langGraphMessages: WritableSignal<BaseMessage[]>;
449
505
  status: WritableSignal<AgentStatus>;
450
506
  isLoading: WritableSignal<boolean>;
451
507
  error: WritableSignal<unknown>;
508
+ toolCalls: WritableSignal<ToolCall[]>;
509
+ interrupt: WritableSignal<AgentInterrupt | undefined>;
510
+ subagents: WritableSignal<Map<string, Subagent>>;
511
+ history: WritableSignal<AgentCheckpoint[]>;
512
+ submitCalls: MockAgent['submitCalls'];
513
+ stopCount: MockAgent['stopCount'];
514
+ _internal: MockAgent['_internal'];
515
+ langGraphMessages: WritableSignal<BaseMessage[]>;
452
516
  hasValue: WritableSignal<boolean>;
453
517
  value: WritableSignal<any>;
454
- interrupt: WritableSignal<AgentInterrupt | undefined>;
455
518
  langGraphInterrupts: WritableSignal<Interrupt<any>[]>;
456
- toolCalls: WritableSignal<ToolCall[]>;
457
519
  langGraphToolCalls: WritableSignal<ToolCallWithResult[]>;
458
520
  toolProgress: WritableSignal<ToolProgress[]>;
459
521
  queue: WritableSignal<AgentQueue>;
460
522
  branch: WritableSignal<string>;
461
- history: WritableSignal<AgentCheckpoint[]>;
462
523
  langGraphHistory: WritableSignal<ThreadState<any>[]>;
463
524
  experimentalBranchTree: WritableSignal<AgentBranchTree<any>>;
464
525
  isThreadLoading: WritableSignal<boolean>;
465
- subagents: WritableSignal<Map<string, Subagent>>;
466
526
  activeSubagents: WritableSignal<SubagentStreamRef[]>;
467
527
  customEvents: WritableSignal<CustomStreamEvent[]>;
468
528
  }
469
529
  /**
470
530
  * Creates a mock LangGraphAgent with writable signals for testing.
471
531
  * Control state by writing to the returned writable signals directly.
532
+ *
533
+ * Neutral `Agent`-contract signals come from {@link mockAgent}; LangGraph-specific
534
+ * signals are declared here and layered on top.
472
535
  */
473
- declare function mockLangGraphAgent(initial?: {
474
- messages?: Message[];
536
+ declare function mockLangGraphAgent(initial?: MockAgentOptions & {
475
537
  langGraphMessages?: BaseMessage[];
476
- status?: AgentStatus;
477
- isLoading?: boolean;
478
- error?: unknown;
479
538
  hasValue?: boolean;
480
539
  isThreadLoading?: boolean;
481
540
  }): MockLangGraphAgent;
482
541
 
542
+ /**
543
+ * Wire an in-process fake LangGraph agent into Angular DI.
544
+ *
545
+ * Streams a canned assistant reply (see FakeAgentConfig) with no backend —
546
+ * the symmetric counterpart to @threadplane/ag-ui's provideFakeAgent(). For
547
+ * advanced manual scripting (tool calls, interrupts, multi-batch), provide
548
+ * the agent yourself with
549
+ * `provideAgent({ assistantId, transport: new MockAgentTransport(...) })`.
550
+ */
551
+ declare function provideFakeAgent(config?: FakeAgentConfig): Provider[];
552
+
553
+ /**
554
+ * In-process AgentTransport that auto-streams a canned assistant reply.
555
+ *
556
+ * Backs `provideFakeAgent()`. Unlike `MockAgentTransport` (passive, driven
557
+ * manually from specs), this transport emits its tokens automatically on
558
+ * `stream()`, then completes — suitable for offline demos and integration tests.
559
+ *
560
+ * NOT for production use.
561
+ */
562
+ declare class FakeStreamTransport implements AgentTransport {
563
+ private readonly tokens;
564
+ private readonly reasoningTokens;
565
+ private readonly delayMs;
566
+ constructor(config?: FakeAgentConfig);
567
+ stream(_assistantId: string, _threadId: string | null, _payload: unknown, signal: AbortSignal, _options?: LangGraphSubmitOptions): AsyncIterable<StreamEvent>;
568
+ createQueuedRun(_assistantId: string, threadId: string, payload: unknown, _signal: AbortSignal, options?: LangGraphSubmitOptions): Promise<AgentQueueEntry>;
569
+ cancelRun(_threadId: string, _runId: string, _signal: AbortSignal): Promise<void>;
570
+ getHistory(_threadId: string, _signal: AbortSignal): Promise<ThreadState[]>;
571
+ joinStream(): AsyncIterable<StreamEvent>;
572
+ }
573
+
483
574
  interface KwargsLike {
484
575
  additional_kwargs?: Record<string, unknown> | undefined;
485
576
  }
@@ -496,17 +587,34 @@ declare function extractCitations(msg: KwargsLike): Citation[] | undefined;
496
587
  * transport (`fetch-stream.transport.ts`) and the threads adapter
497
588
  * (`LangGraphThreadsAdapter`) both go through here.
498
589
  *
590
+ * `clientOptions.maxRetries` maps to the SDK's `callerOptions.maxRetries`,
591
+ * which governs how many times a failed request (including the initial
592
+ * stream connect) is retried with exponential backoff before the error
593
+ * surfaces. Omitted → the SDK default (currently 4). Apps under test set
594
+ * `0` so a forced connection failure surfaces immediately instead of after
595
+ * the full backoff window.
596
+ *
499
597
  * @example
500
598
  * ```ts
501
599
  * const client = createLangGraphClient(environment.langGraphApiUrl);
502
600
  * const threads = await client.threads.search({ limit: 50 });
503
601
  * ```
504
602
  */
505
- declare function createLangGraphClient(apiUrl: string): Client;
603
+ declare function createLangGraphClient(apiUrl: string, clientOptions?: LangGraphClientOptions): Client;
506
604
  /** Exported separately so non-Client callers (e.g. raw fetch) can
507
605
  * share the same normalization logic. */
508
606
  declare function toAbsoluteApiUrl(apiUrl: string): string;
509
607
 
608
+ /**
609
+ * App-wide LangGraph SDK client tuning (e.g. `maxRetries`). Provide once at the
610
+ * app root; both the agent's default {@link FetchStreamTransport} and the
611
+ * {@link LangGraphThreadsAdapter} read it so the retry budget is configured in
612
+ * one place. A call-site `agent({ clientOptions })` or per-agent
613
+ * `provideAgent({ clientOptions })` overrides it for that agent.
614
+ * Absent → the SDK default.
615
+ */
616
+ declare const LANGGRAPH_CLIENT_OPTIONS: InjectionToken<LangGraphClientOptions>;
617
+
510
618
  /**
511
619
  * Configuration consumed by {@link LangGraphThreadsAdapter}. Provide
512
620
  * via {@link LANGGRAPH_THREADS_CONFIG} (typically in app.config.ts):
@@ -558,6 +666,7 @@ declare const LANGGRAPH_CLIENT: InjectionToken<Client<_langchain_langgraph_sdk.D
558
666
  */
559
667
  declare class LangGraphThreadsAdapter {
560
668
  private readonly config;
669
+ private readonly sharedClientOptions;
561
670
  private readonly client;
562
671
  private readonly fallback;
563
672
  private readonly _threads;
@@ -625,5 +734,5 @@ declare function refreshOnRunEnd(agent: LangGraphAgent, fn: () => void | Promise
625
734
  */
626
735
  declare function refreshOnTransition<T>(watch: Signal<T>, isActive: (v: T) => boolean, fn: () => void | Promise<void>): void;
627
736
 
628
- export { AGENT_CONFIG, AGENT_LIFECYCLE, AgentLifecycleRegistry, FetchStreamTransport, LANGGRAPH_CLIENT, LANGGRAPH_THREADS_CONFIG, LangGraphThreadsAdapter, MockAgentTransport, ResourceStatus, agent, createLangGraphClient, extractCitations, mockLangGraphAgent, provideAgent, refreshOnRunEnd, refreshOnTransition, toAbsoluteApiUrl };
629
- export type { AgentBranchTree, AgentBranchTreeFork, AgentBranchTreeNode, AgentConfig, AgentLifecycle, AgentOptions, AgentQueue, AgentQueueEntry, AgentTransport, CustomStreamEvent, LangGraphAgent, LangGraphMultitaskStrategy, LangGraphSubmitOptions, LangGraphThreadsConfig, MockLangGraphAgent, StreamEvent, SubagentStreamRef };
737
+ export { AGENT_LIFECYCLE, AgentLifecycleRegistry, FakeStreamTransport, FetchStreamTransport, LANGGRAPH_CLIENT, LANGGRAPH_CLIENT_OPTIONS, LANGGRAPH_THREADS_CONFIG, LangGraphThreadsAdapter, MockAgentTransport, ResourceStatus, createLangGraphClient, extractCitations, injectAgent, mockLangGraphAgent, provideAgent, provideFakeAgent, refreshOnRunEnd, refreshOnTransition, toAbsoluteApiUrl };
738
+ export type { AgentBranchTree, AgentBranchTreeFork, AgentBranchTreeNode, AgentConfig, AgentLifecycle, AgentOptions, AgentQueue, AgentQueueEntry, AgentTransport, CustomStreamEvent, LangGraphAgent, LangGraphClientOptions, LangGraphMultitaskStrategy, LangGraphSubmitOptions, LangGraphThreadsConfig, MockLangGraphAgent, StreamEvent, SubagentStreamRef };