@threadplane/langgraph 0.0.46
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
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@threadplane/langgraph",
|
|
3
|
+
"version": "0.0.46",
|
|
4
|
+
"peerDependencies": {
|
|
5
|
+
"@threadplane/chat": "*",
|
|
6
|
+
"@angular/core": "^20.0.0 || ^21.0.0",
|
|
7
|
+
"@langchain/core": "^1.1.33",
|
|
8
|
+
"@langchain/langgraph-sdk": "^1.7.4",
|
|
9
|
+
"rxjs": "~7.8.0"
|
|
10
|
+
},
|
|
11
|
+
"license": "MIT",
|
|
12
|
+
"repository": {
|
|
13
|
+
"type": "git",
|
|
14
|
+
"url": "https://github.com/cacheplane/angular-agent-framework.git",
|
|
15
|
+
"directory": "libs/langgraph"
|
|
16
|
+
},
|
|
17
|
+
"homepage": "https://github.com/cacheplane/angular-agent-framework#readme",
|
|
18
|
+
"bugs": {
|
|
19
|
+
"url": "https://github.com/cacheplane/angular-agent-framework/issues"
|
|
20
|
+
},
|
|
21
|
+
"sideEffects": false,
|
|
22
|
+
"module": "fesm2022/threadplane-langgraph.mjs",
|
|
23
|
+
"typings": "types/threadplane-langgraph.d.ts",
|
|
24
|
+
"exports": {
|
|
25
|
+
"./package.json": {
|
|
26
|
+
"default": "./package.json"
|
|
27
|
+
},
|
|
28
|
+
".": {
|
|
29
|
+
"types": "./types/threadplane-langgraph.d.ts",
|
|
30
|
+
"default": "./fesm2022/threadplane-langgraph.mjs"
|
|
31
|
+
}
|
|
32
|
+
},
|
|
33
|
+
"dependencies": {
|
|
34
|
+
"tslib": "^2.3.0",
|
|
35
|
+
"@threadplane/telemetry": "*"
|
|
36
|
+
},
|
|
37
|
+
"scripts": {
|
|
38
|
+
"postinstall": "threadplane-telemetry-postinstall || true"
|
|
39
|
+
}
|
|
40
|
+
}
|
|
@@ -0,0 +1,629 @@
|
|
|
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
|
+
import * as i0 from '@angular/core';
|
|
5
|
+
import { InjectionToken, Signal, ResourceStatus as ResourceStatus$1, Provider, WritableSignal } from '@angular/core';
|
|
6
|
+
import { MessageMetadata } from '@langchain/langgraph-sdk/ui';
|
|
7
|
+
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
|
+
|
|
11
|
+
interface AgentLifecycle {
|
|
12
|
+
/** Epoch ms of the first stream chunk arrival. Resets on switchThread(). */
|
|
13
|
+
readonly streamStartedAt: Signal<number | null>;
|
|
14
|
+
/** Epoch ms + classification of the most recent stream error. Resets on switchThread(). */
|
|
15
|
+
readonly streamErrorAt: Signal<{
|
|
16
|
+
at: number;
|
|
17
|
+
classification: string;
|
|
18
|
+
} | null>;
|
|
19
|
+
/** Epoch ms of the first interrupt$ non-null in this stream. Resets on switchThread(). */
|
|
20
|
+
readonly interruptReceivedAt: Signal<number | null>;
|
|
21
|
+
/** Epoch ms of the most recent submit({ resume }) call. Resets on switchThread(). */
|
|
22
|
+
readonly interruptResolvedAt: Signal<number | null>;
|
|
23
|
+
/** Epoch ms when the agent's "create new thread" branch fired. Resets on switchThread(). */
|
|
24
|
+
readonly threadCreatedAt: Signal<number | null>;
|
|
25
|
+
/** Epoch ms when an existing thread was restored from server (proves persistence). Resets on switchThread(). */
|
|
26
|
+
readonly threadPersistedAt: Signal<number | null>;
|
|
27
|
+
/** Epoch ms of the first tool call append. Resets on switchThread(). */
|
|
28
|
+
readonly toolCallStartedAt: Signal<number | null>;
|
|
29
|
+
/** Epoch ms of the first tool call result transition. Resets on switchThread(). */
|
|
30
|
+
readonly toolCallCompletedAt: Signal<number | null>;
|
|
31
|
+
}
|
|
32
|
+
declare const AGENT_LIFECYCLE: InjectionToken<AgentLifecycle>;
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Runtime constant mirroring Angular's ResourceStatus string-union type.
|
|
36
|
+
* Angular 21 ships ResourceStatus as a pure string-union type (no runtime value),
|
|
37
|
+
* so we provide a const-object shim for code that needs runtime comparisons.
|
|
38
|
+
*/
|
|
39
|
+
declare const ResourceStatus: {
|
|
40
|
+
readonly Idle: "idle";
|
|
41
|
+
readonly Loading: "loading";
|
|
42
|
+
readonly Reloading: "reloading";
|
|
43
|
+
readonly Resolved: "resolved";
|
|
44
|
+
readonly Error: "error";
|
|
45
|
+
readonly Local: "local";
|
|
46
|
+
};
|
|
47
|
+
type ResourceStatus = ResourceStatus$1;
|
|
48
|
+
/** An event emitted by a LangGraph stream. */
|
|
49
|
+
interface StreamEvent {
|
|
50
|
+
/** Event type identifier (e.g., 'values', 'messages', 'error', 'interrupt'). */
|
|
51
|
+
type: 'values' | `values|${string}` | 'messages' | `messages|${string}` | `messages/${string}` | `messages/${string}|${string}` | 'updates' | `updates|${string}` | 'tools' | `tools|${string}` | 'custom' | `custom|${string}` | 'error' | `error|${string}` | 'metadata' | 'checkpoints' | `checkpoints|${string}` | 'tasks' | `tasks|${string}` | 'debug' | `debug|${string}` | 'events' | `events|${string}` | 'interrupt' | 'interrupts';
|
|
52
|
+
namespace?: string[];
|
|
53
|
+
messages?: unknown[];
|
|
54
|
+
messageMetadata?: Record<string, unknown>;
|
|
55
|
+
[key: string]: unknown;
|
|
56
|
+
}
|
|
57
|
+
/** Strategy for handling concurrent LangGraph runs on the same thread. */
|
|
58
|
+
type LangGraphMultitaskStrategy = 'reject' | 'interrupt' | 'rollback' | 'enqueue';
|
|
59
|
+
type LangGraphDurability = 'exit' | 'async' | 'sync';
|
|
60
|
+
type LangGraphOnCompletion = 'complete' | 'continue';
|
|
61
|
+
type LangGraphOnDisconnect = 'cancel' | 'continue';
|
|
62
|
+
/** Options accepted by LangGraph-backed submit calls. */
|
|
63
|
+
interface LangGraphSubmitOptions {
|
|
64
|
+
signal?: AbortSignal;
|
|
65
|
+
config?: Config;
|
|
66
|
+
context?: unknown;
|
|
67
|
+
checkpoint?: Omit<Checkpoint, 'thread_id'> | null;
|
|
68
|
+
checkpointId?: string;
|
|
69
|
+
command?: Command;
|
|
70
|
+
metadata?: Metadata;
|
|
71
|
+
checkpointDuring?: boolean;
|
|
72
|
+
durability?: LangGraphDurability;
|
|
73
|
+
interruptBefore?: '*' | string[];
|
|
74
|
+
interruptAfter?: '*' | string[];
|
|
75
|
+
onCompletion?: LangGraphOnCompletion;
|
|
76
|
+
webhook?: string;
|
|
77
|
+
onDisconnect?: LangGraphOnDisconnect;
|
|
78
|
+
afterSeconds?: number;
|
|
79
|
+
ifNotExists?: 'create' | 'reject';
|
|
80
|
+
onRunCreated?: (params: {
|
|
81
|
+
run_id: string;
|
|
82
|
+
thread_id?: string;
|
|
83
|
+
}) => void;
|
|
84
|
+
streamMode?: StreamMode[];
|
|
85
|
+
streamSubgraphs?: boolean;
|
|
86
|
+
streamResumable?: boolean;
|
|
87
|
+
feedbackKeys?: string[];
|
|
88
|
+
/** Convenience alias normalized to `command.resume` before invoking LangGraph. */
|
|
89
|
+
resume?: unknown;
|
|
90
|
+
/** Strategy for handling concurrent runs on the same thread. */
|
|
91
|
+
multitaskStrategy?: LangGraphMultitaskStrategy;
|
|
92
|
+
}
|
|
93
|
+
/** A queued server-side LangGraph run. */
|
|
94
|
+
interface AgentQueueEntry<T = unknown> {
|
|
95
|
+
/** Server-side run ID. */
|
|
96
|
+
id: string;
|
|
97
|
+
/** Thread that owns the queued run. */
|
|
98
|
+
threadId: string;
|
|
99
|
+
/** Values submitted for the queued run. */
|
|
100
|
+
values: T | null | undefined;
|
|
101
|
+
/** Submit options used when the queued run was created. */
|
|
102
|
+
options?: LangGraphSubmitOptions;
|
|
103
|
+
/** Timestamp when the queued run was registered locally. */
|
|
104
|
+
createdAt: Date;
|
|
105
|
+
}
|
|
106
|
+
/** Public queue surface for pending server-side LangGraph runs. */
|
|
107
|
+
interface AgentQueue<T = unknown> {
|
|
108
|
+
/** Read-only pending queue entries. */
|
|
109
|
+
readonly entries: ReadonlyArray<AgentQueueEntry<T>>;
|
|
110
|
+
/** Number of pending queue entries. */
|
|
111
|
+
readonly size: number;
|
|
112
|
+
/** Cancel a specific pending run by server run ID. */
|
|
113
|
+
cancel: (id: string) => Promise<boolean>;
|
|
114
|
+
/** Cancel all pending runs and clear the queue. */
|
|
115
|
+
clear: () => Promise<void>;
|
|
116
|
+
}
|
|
117
|
+
/** A checkpoint entry in the experimental branch tree. */
|
|
118
|
+
interface AgentBranchTreeNode<T = unknown> {
|
|
119
|
+
type: 'node';
|
|
120
|
+
value: ThreadState<T>;
|
|
121
|
+
path: string[];
|
|
122
|
+
}
|
|
123
|
+
/** A branch fork where each item is an alternate checkpoint sequence. */
|
|
124
|
+
interface AgentBranchTreeFork<T = unknown> {
|
|
125
|
+
type: 'fork';
|
|
126
|
+
items: AgentBranchTree<T>[];
|
|
127
|
+
}
|
|
128
|
+
/** Tree representation of LangGraph checkpoint history for time-travel UIs. */
|
|
129
|
+
interface AgentBranchTree<T = unknown> {
|
|
130
|
+
type: 'sequence';
|
|
131
|
+
items: Array<AgentBranchTreeNode<T> | AgentBranchTreeFork<T>>;
|
|
132
|
+
}
|
|
133
|
+
/** A custom event emitted by the LangGraph backend via adispatch_custom_event(). */
|
|
134
|
+
interface CustomStreamEvent {
|
|
135
|
+
/** Event name set by the backend (e.g., 'state_update'). */
|
|
136
|
+
name: string;
|
|
137
|
+
/** Arbitrary payload from the backend. */
|
|
138
|
+
data: unknown;
|
|
139
|
+
}
|
|
140
|
+
/** Transport interface for connecting to a LangGraph agent. */
|
|
141
|
+
interface AgentTransport {
|
|
142
|
+
/** Open a streaming connection to an agent and yield events. */
|
|
143
|
+
stream(assistantId: string, threadId: string | null, payload: unknown, signal: AbortSignal, options?: LangGraphSubmitOptions): AsyncIterable<StreamEvent>;
|
|
144
|
+
/** Optional: join an already-started run without creating a new one. */
|
|
145
|
+
joinStream?(threadId: string, runId: string, lastEventId: string | undefined, signal: AbortSignal): AsyncIterable<StreamEvent>;
|
|
146
|
+
/** Optional: create a server-side queued run without joining it immediately. */
|
|
147
|
+
createQueuedRun?(assistantId: string, threadId: string, payload: unknown, signal: AbortSignal, options?: LangGraphSubmitOptions): Promise<AgentQueueEntry>;
|
|
148
|
+
/** Optional: cancel a server-side run. */
|
|
149
|
+
cancelRun?(threadId: string, runId: string, signal: AbortSignal): Promise<void>;
|
|
150
|
+
/** Optional: load persisted checkpoint history for a thread. */
|
|
151
|
+
getHistory?(threadId: string, signal: AbortSignal): Promise<ThreadState[]>;
|
|
152
|
+
/**
|
|
153
|
+
* Optional: update server-side thread state (e.g. to emit RemoveMessage
|
|
154
|
+
* entries for regenerate rollback). Forwards to the LangGraph
|
|
155
|
+
* `threads.updateState` API.
|
|
156
|
+
*
|
|
157
|
+
* `options.asNode` corresponds to LangGraph's `as_node` parameter — the
|
|
158
|
+
* server treats the update as if that node had just produced the values,
|
|
159
|
+
* which determines what the next pull resumes. `regenerate()` passes
|
|
160
|
+
* `asNode: '__start__'` so the next `submit(null)` resumes at the entry
|
|
161
|
+
* node and re-runs `generate` against the rolled-back state.
|
|
162
|
+
*/
|
|
163
|
+
updateState?(threadId: string, values: Record<string, unknown>, signal: AbortSignal, options?: {
|
|
164
|
+
asNode?: string;
|
|
165
|
+
}): Promise<void>;
|
|
166
|
+
}
|
|
167
|
+
/** Options for creating a LangGraph-backed agent via {@link agent}. */
|
|
168
|
+
interface AgentOptions<T, _ResolvedBag extends BagTemplate> {
|
|
169
|
+
/** Base URL of the LangGraph Platform API. Defaults to `provideAgent({ apiUrl })` when omitted. */
|
|
170
|
+
apiUrl?: string;
|
|
171
|
+
/** Agent or graph identifier on the LangGraph platform. */
|
|
172
|
+
assistantId: string;
|
|
173
|
+
/** Thread ID to connect to. Pass a Signal for reactive thread switching. */
|
|
174
|
+
threadId?: Signal<string | null> | string | null;
|
|
175
|
+
/** Called when a new thread is auto-created by the transport. */
|
|
176
|
+
onThreadId?: (id: string) => void;
|
|
177
|
+
/** Initial state values before the first stream response arrives. */
|
|
178
|
+
initialValues?: Partial<T>;
|
|
179
|
+
/** Throttle signal updates in milliseconds. `false` to disable. */
|
|
180
|
+
throttle?: number | false;
|
|
181
|
+
/** Custom message deserializer for non-standard message formats. */
|
|
182
|
+
toMessage?: (msg: unknown) => BaseMessage;
|
|
183
|
+
/** Custom transport. Defaults to FetchStreamTransport. */
|
|
184
|
+
transport?: AgentTransport;
|
|
185
|
+
/** Optional app-owned telemetry sink. No telemetry is emitted unless this is provided. */
|
|
186
|
+
telemetry?: AgentRuntimeTelemetrySink | false;
|
|
187
|
+
/** When true, subagent messages are filtered from the main messages signal. */
|
|
188
|
+
filterSubagentMessages?: boolean;
|
|
189
|
+
/** Tool names that indicate a subagent invocation. */
|
|
190
|
+
subagentToolNames?: string[];
|
|
191
|
+
}
|
|
192
|
+
/** Reference to a subagent's streaming state. */
|
|
193
|
+
interface SubagentStreamRef {
|
|
194
|
+
/** The tool call ID that spawned this subagent. */
|
|
195
|
+
toolCallId: string;
|
|
196
|
+
/** Optional human-readable subagent type/name. */
|
|
197
|
+
name?: string;
|
|
198
|
+
/** Current execution status of the subagent. */
|
|
199
|
+
status: Signal<'pending' | 'running' | 'complete' | 'error'>;
|
|
200
|
+
/** Current state values from the subagent. */
|
|
201
|
+
values: Signal<Record<string, unknown>>;
|
|
202
|
+
/** Messages from the subagent conversation. */
|
|
203
|
+
messages: Signal<BaseMessage[]>;
|
|
204
|
+
}
|
|
205
|
+
/**
|
|
206
|
+
* Unified LangGraph agent surface returned by `agent({...})`.
|
|
207
|
+
*
|
|
208
|
+
* Extends the runtime-neutral `AgentWithHistory` contract (chat-consumable)
|
|
209
|
+
* with the full LangGraph-specific API. One object drives both `<chat>` and
|
|
210
|
+
* any LangGraph-specific demo. Raw LangGraph signals are prefixed with
|
|
211
|
+
* `langGraph` to avoid collision with the runtime-neutral names.
|
|
212
|
+
*/
|
|
213
|
+
interface LangGraphAgent<T = unknown, ResolvedBag extends BagTemplate = BagTemplate> extends AgentWithHistory {
|
|
214
|
+
/** Raw LangChain BaseMessage list. Use `messages` for chat rendering. */
|
|
215
|
+
langGraphMessages: Signal<BaseMessage[]>;
|
|
216
|
+
/** All interrupts received during the current run (raw LangGraph shape). */
|
|
217
|
+
langGraphInterrupts: Signal<Interrupt<ResolvedBag['InterruptType']>[]>;
|
|
218
|
+
/** Raw LangGraph tool calls (with run-state). Use `toolCalls` for chat rendering. */
|
|
219
|
+
langGraphToolCalls: Signal<ToolCallWithResult[]>;
|
|
220
|
+
/** Raw LangGraph history (ThreadState[]). Use `history` for AgentCheckpoint[]. */
|
|
221
|
+
langGraphHistory: Signal<ThreadState<T>[]>;
|
|
222
|
+
/** Experimental branch tree derived from LangGraph checkpoint history. */
|
|
223
|
+
experimentalBranchTree: Signal<AgentBranchTree<T>>;
|
|
224
|
+
/** Submit input, resume commands, checkpoint forks, or other LangGraph run options. */
|
|
225
|
+
submit: (input: AgentSubmitInput | null | undefined, opts?: AgentSubmitOptions & LangGraphSubmitOptions) => Promise<void>;
|
|
226
|
+
/** Current agent state values (raw, typed per the type parameter T). */
|
|
227
|
+
value: Signal<T>;
|
|
228
|
+
/** True once at least one value or message has been received. */
|
|
229
|
+
hasValue: Signal<boolean>;
|
|
230
|
+
/** Re-submit the last input to restart the stream. */
|
|
231
|
+
reload: () => void;
|
|
232
|
+
/**
|
|
233
|
+
* Discards the assistant message at the given index AND all messages after
|
|
234
|
+
* it, then re-runs the agent against the trimmed conversation tail. The
|
|
235
|
+
* preceding user message (at index - 1) is preserved and re-submitted as
|
|
236
|
+
* the agent's input. No new user message is added to the history.
|
|
237
|
+
*
|
|
238
|
+
* Throws if the message at `index` is not 'assistant' role, or if the
|
|
239
|
+
* agent is currently loading another response.
|
|
240
|
+
*/
|
|
241
|
+
regenerate: (assistantMessageIndex: number) => Promise<void>;
|
|
242
|
+
/** Progress updates for currently executing tools. */
|
|
243
|
+
toolProgress: Signal<ToolProgress[]>;
|
|
244
|
+
/** Pending server-side runs created via `multitaskStrategy: 'enqueue'`. */
|
|
245
|
+
queue: Signal<AgentQueue>;
|
|
246
|
+
/** Filtered list of subagents with status 'running'. */
|
|
247
|
+
activeSubagents: Signal<SubagentStreamRef[]>;
|
|
248
|
+
/** Get a subagent stream by the tool call ID that spawned it. */
|
|
249
|
+
getSubagent: (toolCallId: string) => SubagentStreamRef | undefined;
|
|
250
|
+
/** Get subagent streams by their configured subagent type/name. */
|
|
251
|
+
getSubagentsByType: (type: string) => SubagentStreamRef[];
|
|
252
|
+
/** Get subagent streams spawned by the tool calls on a specific AI message. */
|
|
253
|
+
getSubagentsByMessage: (msg: AIMessage) => SubagentStreamRef[];
|
|
254
|
+
/** Raw custom events stream (signal of array). The runtime-neutral
|
|
255
|
+
* `events$` Observable is derived from this. */
|
|
256
|
+
customEvents: Signal<CustomStreamEvent[]>;
|
|
257
|
+
/** Current branch identifier for time-travel navigation. */
|
|
258
|
+
branch: Signal<string>;
|
|
259
|
+
/** Set the active branch for time-travel navigation. */
|
|
260
|
+
setBranch: (branch: string) => void;
|
|
261
|
+
/** True while a thread switch is loading state from the server. */
|
|
262
|
+
isThreadLoading: Signal<boolean>;
|
|
263
|
+
/** Switch to a different thread, resetting derived state. */
|
|
264
|
+
switchThread: (threadId: string | null) => void;
|
|
265
|
+
/** Join an already-running stream by run ID. */
|
|
266
|
+
joinStream: (runId: string, lastEventId?: string) => Promise<void>;
|
|
267
|
+
/** Get metadata for a specific message by index. */
|
|
268
|
+
getMessagesMetadata: (msg: BaseMessage, idx?: number) => MessageMetadata<Record<string, unknown>> | undefined;
|
|
269
|
+
/** Get tool call results associated with an AI message (LangGraph types). */
|
|
270
|
+
getToolCalls: (msg: AIMessage) => ToolCallWithResult[];
|
|
271
|
+
/**
|
|
272
|
+
* Lifecycle signals for observability/telemetry. Eight read-only signals
|
|
273
|
+
* capture key transitions (first stream chunk, first interrupt, tool
|
|
274
|
+
* call start/complete, thread create/persist, errors). All reset on
|
|
275
|
+
* `switchThread()`. See {@link AgentLifecycle}.
|
|
276
|
+
*/
|
|
277
|
+
lifecycle: AgentLifecycle;
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
/**
|
|
281
|
+
* Creates a LangGraph-backed Angular agent.
|
|
282
|
+
*
|
|
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.
|
|
288
|
+
*
|
|
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
|
|
293
|
+
*
|
|
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
|
+
* });
|
|
303
|
+
*
|
|
304
|
+
* // Access signals in template
|
|
305
|
+
* // chat.messages(), chat.status(), chat.error()
|
|
306
|
+
* ```
|
|
307
|
+
*/
|
|
308
|
+
declare function agent<T = Record<string, unknown>, Bag extends BagTemplate = BagTemplate>(options: AgentOptions<T, InferBag<T, Bag>>): LangGraphAgent<T, InferBag<T, Bag>>;
|
|
309
|
+
|
|
310
|
+
/**
|
|
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.
|
|
324
|
+
*/
|
|
325
|
+
declare function provideAgent(config: AgentConfig): Provider;
|
|
326
|
+
|
|
327
|
+
/**
|
|
328
|
+
* Optional registry that collects per-instance agent lifecycles within
|
|
329
|
+
* an Angular injection context. External instrumentation packages
|
|
330
|
+
* (e.g. cockpit-telemetry) provide this token and read from it.
|
|
331
|
+
*
|
|
332
|
+
* `@threadplane/langgraph` does NOT provide this itself — `agent()` writes to
|
|
333
|
+
* the registry only when an external consumer has provided it.
|
|
334
|
+
*/
|
|
335
|
+
declare class AgentLifecycleRegistry {
|
|
336
|
+
private readonly _lifecycles;
|
|
337
|
+
/** Reactive list of registered lifecycles. */
|
|
338
|
+
readonly lifecycles: Signal<readonly AgentLifecycle[]>;
|
|
339
|
+
register(lifecycle: AgentLifecycle): void;
|
|
340
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<AgentLifecycleRegistry, never>;
|
|
341
|
+
static ɵprov: i0.ɵɵInjectableDeclaration<AgentLifecycleRegistry>;
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
/**
|
|
345
|
+
* Test transport for deterministic agent testing without a real LangGraph server.
|
|
346
|
+
*
|
|
347
|
+
* Script event batches upfront, then emit them manually or step through them
|
|
348
|
+
* in your test specs. Supports error injection and close control.
|
|
349
|
+
*
|
|
350
|
+
* @example
|
|
351
|
+
* ```typescript
|
|
352
|
+
* const transport = new MockAgentTransport([
|
|
353
|
+
* [{ type: 'values', messages: [aiMsg('Hello')] }],
|
|
354
|
+
* [{ type: 'values', messages: [aiMsg('Done')] }],
|
|
355
|
+
* ]);
|
|
356
|
+
* ```
|
|
357
|
+
*/
|
|
358
|
+
declare class MockAgentTransport implements AgentTransport {
|
|
359
|
+
history: ThreadState[];
|
|
360
|
+
readonly historyCalls: string[];
|
|
361
|
+
readonly streams: Array<{
|
|
362
|
+
threadId: string | null;
|
|
363
|
+
payload: unknown;
|
|
364
|
+
options?: LangGraphSubmitOptions;
|
|
365
|
+
}>;
|
|
366
|
+
readonly createdQueuedRuns: AgentQueueEntry[];
|
|
367
|
+
readonly cancelledRuns: Array<{
|
|
368
|
+
threadId: string;
|
|
369
|
+
runId: string;
|
|
370
|
+
}>;
|
|
371
|
+
readonly joinedRuns: Array<{
|
|
372
|
+
threadId: string;
|
|
373
|
+
runId: string;
|
|
374
|
+
}>;
|
|
375
|
+
private script;
|
|
376
|
+
private scriptIndex;
|
|
377
|
+
private streaming;
|
|
378
|
+
private eventQueue;
|
|
379
|
+
private resolvers;
|
|
380
|
+
private closed;
|
|
381
|
+
private pendingError;
|
|
382
|
+
/** @param script - Array of event batches. Each batch is emitted as a group. */
|
|
383
|
+
constructor(script?: StreamEvent[][]);
|
|
384
|
+
/** Advance to the next scripted batch. Pass the returned events to `emit()`. */
|
|
385
|
+
nextBatch(): StreamEvent[];
|
|
386
|
+
/** Manually emit events into the stream. */
|
|
387
|
+
emit(events: StreamEvent[]): void;
|
|
388
|
+
/** Inject an error into the stream. */
|
|
389
|
+
emitError(err: Error): void;
|
|
390
|
+
/** Close the stream. Remaining queued events are drained before completion. */
|
|
391
|
+
close(): void;
|
|
392
|
+
/** Returns true if a stream is currently active. */
|
|
393
|
+
isStreaming(): boolean;
|
|
394
|
+
stream(_assistantId: string, _threadId: string | null, _payload: unknown, signal: AbortSignal, options?: LangGraphSubmitOptions): AsyncIterable<StreamEvent>;
|
|
395
|
+
createQueuedRun(_assistantId: string, threadId: string, payload: unknown, signal: AbortSignal, options?: LangGraphSubmitOptions): Promise<AgentQueueEntry>;
|
|
396
|
+
cancelRun(threadId: string, runId: string, signal: AbortSignal): Promise<void>;
|
|
397
|
+
getHistory(threadId: string, signal: AbortSignal): Promise<ThreadState[]>;
|
|
398
|
+
joinStream(threadId: string, runId: string, lastEventId: string | undefined, signal: AbortSignal): AsyncIterable<StreamEvent>;
|
|
399
|
+
private flush;
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
/**
|
|
403
|
+
* Production transport that connects to a LangGraph Platform API via HTTP and SSE.
|
|
404
|
+
*
|
|
405
|
+
* Creates threads automatically if no threadId is provided, and streams events
|
|
406
|
+
* using the LangGraph SDK client.
|
|
407
|
+
*
|
|
408
|
+
* @example
|
|
409
|
+
* ```typescript
|
|
410
|
+
* const transport = new FetchStreamTransport(
|
|
411
|
+
* 'http://localhost:2024',
|
|
412
|
+
* (id) => console.log('New thread:', id),
|
|
413
|
+
* );
|
|
414
|
+
* ```
|
|
415
|
+
*/
|
|
416
|
+
declare class FetchStreamTransport implements AgentTransport {
|
|
417
|
+
private client;
|
|
418
|
+
private onThreadId?;
|
|
419
|
+
/**
|
|
420
|
+
* @param apiUrl - Base URL of the LangGraph Platform API
|
|
421
|
+
* @param onThreadId - Optional callback invoked when a new thread is created
|
|
422
|
+
*/
|
|
423
|
+
constructor(apiUrl: string, onThreadId?: (id: string) => void);
|
|
424
|
+
/** Open a streaming connection, creating a thread if needed. */
|
|
425
|
+
stream(assistantId: string, threadId: string | null, payload: unknown, signal: AbortSignal, options?: LangGraphSubmitOptions): AsyncIterable<StreamEvent>;
|
|
426
|
+
/** Join an already-started run without creating a new thread. */
|
|
427
|
+
joinStream(threadId: string, runId: string, lastEventId: string | undefined, signal: AbortSignal): AsyncIterable<StreamEvent>;
|
|
428
|
+
/** Create a pending server-side run using LangGraph's enqueue strategy. */
|
|
429
|
+
createQueuedRun(assistantId: string, threadId: string, payload: unknown, signal: AbortSignal, options?: LangGraphSubmitOptions): Promise<AgentQueueEntry>;
|
|
430
|
+
/** Cancel a server-side run. */
|
|
431
|
+
cancelRun(threadId: string, runId: string, signal: AbortSignal): Promise<void>;
|
|
432
|
+
/** Load persisted checkpoint history for a thread. */
|
|
433
|
+
getHistory(threadId: string, signal: AbortSignal): Promise<ThreadState[]>;
|
|
434
|
+
/** Update server-side thread state, e.g. to remove messages for regenerate rollback. */
|
|
435
|
+
updateState(threadId: string, values: Record<string, unknown>, _signal: AbortSignal, options?: {
|
|
436
|
+
asNode?: string;
|
|
437
|
+
}): Promise<void>;
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
/**
|
|
441
|
+
* A LangGraphAgent mock with writable signals for easy test control.
|
|
442
|
+
*
|
|
443
|
+
* Cast the result of `mockLangGraphAgent()` to this type to access
|
|
444
|
+
* writable signals without unsafe casts in test files.
|
|
445
|
+
*/
|
|
446
|
+
interface MockLangGraphAgent extends LangGraphAgent<any, any> {
|
|
447
|
+
messages: WritableSignal<Message[]>;
|
|
448
|
+
langGraphMessages: WritableSignal<BaseMessage[]>;
|
|
449
|
+
status: WritableSignal<AgentStatus>;
|
|
450
|
+
isLoading: WritableSignal<boolean>;
|
|
451
|
+
error: WritableSignal<unknown>;
|
|
452
|
+
hasValue: WritableSignal<boolean>;
|
|
453
|
+
value: WritableSignal<any>;
|
|
454
|
+
interrupt: WritableSignal<AgentInterrupt | undefined>;
|
|
455
|
+
langGraphInterrupts: WritableSignal<Interrupt<any>[]>;
|
|
456
|
+
toolCalls: WritableSignal<ToolCall[]>;
|
|
457
|
+
langGraphToolCalls: WritableSignal<ToolCallWithResult[]>;
|
|
458
|
+
toolProgress: WritableSignal<ToolProgress[]>;
|
|
459
|
+
queue: WritableSignal<AgentQueue>;
|
|
460
|
+
branch: WritableSignal<string>;
|
|
461
|
+
history: WritableSignal<AgentCheckpoint[]>;
|
|
462
|
+
langGraphHistory: WritableSignal<ThreadState<any>[]>;
|
|
463
|
+
experimentalBranchTree: WritableSignal<AgentBranchTree<any>>;
|
|
464
|
+
isThreadLoading: WritableSignal<boolean>;
|
|
465
|
+
subagents: WritableSignal<Map<string, Subagent>>;
|
|
466
|
+
activeSubagents: WritableSignal<SubagentStreamRef[]>;
|
|
467
|
+
customEvents: WritableSignal<CustomStreamEvent[]>;
|
|
468
|
+
}
|
|
469
|
+
/**
|
|
470
|
+
* Creates a mock LangGraphAgent with writable signals for testing.
|
|
471
|
+
* Control state by writing to the returned writable signals directly.
|
|
472
|
+
*/
|
|
473
|
+
declare function mockLangGraphAgent(initial?: {
|
|
474
|
+
messages?: Message[];
|
|
475
|
+
langGraphMessages?: BaseMessage[];
|
|
476
|
+
status?: AgentStatus;
|
|
477
|
+
isLoading?: boolean;
|
|
478
|
+
error?: unknown;
|
|
479
|
+
hasValue?: boolean;
|
|
480
|
+
isThreadLoading?: boolean;
|
|
481
|
+
}): MockLangGraphAgent;
|
|
482
|
+
|
|
483
|
+
interface KwargsLike {
|
|
484
|
+
additional_kwargs?: Record<string, unknown> | undefined;
|
|
485
|
+
}
|
|
486
|
+
declare function extractCitations(msg: KwargsLike): Citation[] | undefined;
|
|
487
|
+
|
|
488
|
+
/**
|
|
489
|
+
* Construct a LangGraph SDK Client that accepts both absolute URLs
|
|
490
|
+
* (`http://localhost:2024`) and relative `/api`-style paths that get
|
|
491
|
+
* proxied by middleware in production. The SDK itself rejects
|
|
492
|
+
* relative URLs, so this helper rewrites them against
|
|
493
|
+
* `window.location.origin` when running in the browser.
|
|
494
|
+
*
|
|
495
|
+
* Single source of truth for the absolute-URL rewrite — the streaming
|
|
496
|
+
* transport (`fetch-stream.transport.ts`) and the threads adapter
|
|
497
|
+
* (`LangGraphThreadsAdapter`) both go through here.
|
|
498
|
+
*
|
|
499
|
+
* @example
|
|
500
|
+
* ```ts
|
|
501
|
+
* const client = createLangGraphClient(environment.langGraphApiUrl);
|
|
502
|
+
* const threads = await client.threads.search({ limit: 50 });
|
|
503
|
+
* ```
|
|
504
|
+
*/
|
|
505
|
+
declare function createLangGraphClient(apiUrl: string): Client;
|
|
506
|
+
/** Exported separately so non-Client callers (e.g. raw fetch) can
|
|
507
|
+
* share the same normalization logic. */
|
|
508
|
+
declare function toAbsoluteApiUrl(apiUrl: string): string;
|
|
509
|
+
|
|
510
|
+
/**
|
|
511
|
+
* Configuration consumed by {@link LangGraphThreadsAdapter}. Provide
|
|
512
|
+
* via {@link LANGGRAPH_THREADS_CONFIG} (typically in app.config.ts):
|
|
513
|
+
*
|
|
514
|
+
* ```ts
|
|
515
|
+
* providers: [
|
|
516
|
+
* { provide: LANGGRAPH_THREADS_CONFIG, useValue: {
|
|
517
|
+
* apiUrl: environment.langGraphApiUrl,
|
|
518
|
+
* }},
|
|
519
|
+
* ],
|
|
520
|
+
* ```
|
|
521
|
+
*
|
|
522
|
+
* The adapter expects backends to write the thread title to
|
|
523
|
+
* `metadata.title`. Spec 2026-05-19-llm-generated-labels-design.md
|
|
524
|
+
* originally proposed `metadata.thread_title` for cockpit caps but
|
|
525
|
+
* we converged on `title` to match the canonical demo and avoid a
|
|
526
|
+
* per-cap configuration knob.
|
|
527
|
+
*/
|
|
528
|
+
interface LangGraphThreadsConfig {
|
|
529
|
+
/** Base URL for the LangGraph Platform API. Accepts both absolute
|
|
530
|
+
* URLs and relative `/api`-style paths. */
|
|
531
|
+
apiUrl: string;
|
|
532
|
+
/** Fallback label for threads whose title hasn't been written yet
|
|
533
|
+
* (e.g. created but never sent). Defaults to `'Untitled'`. */
|
|
534
|
+
titleFallback?: string;
|
|
535
|
+
}
|
|
536
|
+
declare const LANGGRAPH_THREADS_CONFIG: InjectionToken<LangGraphThreadsConfig>;
|
|
537
|
+
/** Optional adapter clients can pass an explicit Client (e.g. for
|
|
538
|
+
* testing). When omitted, the adapter constructs one via
|
|
539
|
+
* {@link createLangGraphClient}. */
|
|
540
|
+
declare const LANGGRAPH_CLIENT: InjectionToken<Client<_langchain_langgraph_sdk.DefaultValues, _langchain_langgraph_sdk.DefaultValues, unknown>>;
|
|
541
|
+
/**
|
|
542
|
+
* SDK-backed thread store. Wraps `client.threads.*` and maps SDK
|
|
543
|
+
* threads to the framework's {@link Thread} type for direct use with
|
|
544
|
+
* `<chat-thread-list>` / `<chat-sidenav>`.
|
|
545
|
+
*
|
|
546
|
+
* Consumers wire the framework's `ThreadActionAdapter` to instance
|
|
547
|
+
* methods (rename/delete/archive/pin/...) so the right-click menu
|
|
548
|
+
* round-trips through the LangGraph SDK without per-app boilerplate.
|
|
549
|
+
*
|
|
550
|
+
* @example
|
|
551
|
+
* ```ts
|
|
552
|
+
* const svc = inject(LangGraphThreadsAdapter);
|
|
553
|
+
* const actions: ThreadActionAdapter = {
|
|
554
|
+
* rename: (id, t) => svc.rename(id, t),
|
|
555
|
+
* delete: (id) => svc.delete(id),
|
|
556
|
+
* };
|
|
557
|
+
* ```
|
|
558
|
+
*/
|
|
559
|
+
declare class LangGraphThreadsAdapter {
|
|
560
|
+
private readonly config;
|
|
561
|
+
private readonly client;
|
|
562
|
+
private readonly fallback;
|
|
563
|
+
private readonly _threads;
|
|
564
|
+
private readonly _archived;
|
|
565
|
+
/** Active (non-archived) threads, sorted with pinned first. */
|
|
566
|
+
readonly threads: Signal<Thread[]>;
|
|
567
|
+
/** Threads whose `metadata.archived === true`. */
|
|
568
|
+
readonly archivedThreads: Signal<Thread[]>;
|
|
569
|
+
/** Fetch the latest thread list from the server. Failures are
|
|
570
|
+
* logged via `console.error` (not swallowed silently — silent
|
|
571
|
+
* catches have masked prod issues in the past).
|
|
572
|
+
*
|
|
573
|
+
* Invocation and resolution are logged at `console.debug` so prod
|
|
574
|
+
* inspection can distinguish "never called" from "called but
|
|
575
|
+
* resolved empty" from "called and threw." This was prompted by a
|
|
576
|
+
* demo.threadplane.ai cold-load bug where the sidenav stayed empty
|
|
577
|
+
* with no visible signal. Tighten the log volume if it becomes
|
|
578
|
+
* noisy. */
|
|
579
|
+
refresh(): Promise<void>;
|
|
580
|
+
/** Fetch a single thread by id. Returns `null` when the server
|
|
581
|
+
* returns 404 (thread doesn't exist) so callers can distinguish
|
|
582
|
+
* "missing" from "couldn't reach the server" — genuine network
|
|
583
|
+
* errors rethrow. Used by URL-based thread routing to validate a
|
|
584
|
+
* pasted/shared thread id before activating it. */
|
|
585
|
+
getThread(threadId: string): Promise<Thread | null>;
|
|
586
|
+
create(metadata?: Record<string, unknown>): Promise<string | null>;
|
|
587
|
+
delete(threadId: string): Promise<void>;
|
|
588
|
+
rename(threadId: string, newTitle: string): Promise<void>;
|
|
589
|
+
archive(threadId: string): Promise<void>;
|
|
590
|
+
unarchive(threadId: string): Promise<void>;
|
|
591
|
+
pin(threadId: string): Promise<void>;
|
|
592
|
+
unpin(threadId: string): Promise<void>;
|
|
593
|
+
moveToProject(threadId: string, projectId: string | null): Promise<void>;
|
|
594
|
+
/** Re-stamp `metadata.pinnedOrder = 0,1,2,...` for the pinned slice
|
|
595
|
+
* to reflect the new ordering. */
|
|
596
|
+
reorderPinned(threadId: string, beforeId: string | null): Promise<void>;
|
|
597
|
+
private toThread;
|
|
598
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<LangGraphThreadsAdapter, never>;
|
|
599
|
+
static ɵprov: i0.ɵɵInjectableDeclaration<LangGraphThreadsAdapter>;
|
|
600
|
+
}
|
|
601
|
+
|
|
602
|
+
/**
|
|
603
|
+
* Call `fn` whenever the agent's status transitions out of `'running'`
|
|
604
|
+
* (i.e. when a run completes — success, error, or interrupt). Useful
|
|
605
|
+
* for refreshing thread lists, telemetry, or any other state that
|
|
606
|
+
* lags the agent.
|
|
607
|
+
*
|
|
608
|
+
* Must be called within an injection context (constructor or
|
|
609
|
+
* `runInInjectionContext`) — uses Angular's `effect` under the hood.
|
|
610
|
+
*
|
|
611
|
+
* @example
|
|
612
|
+
* ```ts
|
|
613
|
+
* constructor() {
|
|
614
|
+
* refreshOnRunEnd(this.agent, () => this.threads.refresh());
|
|
615
|
+
* }
|
|
616
|
+
* ```
|
|
617
|
+
*/
|
|
618
|
+
declare function refreshOnRunEnd(agent: LangGraphAgent, fn: () => void | Promise<void>): void;
|
|
619
|
+
/**
|
|
620
|
+
* Call `fn` whenever any of the watched signals transitions from a
|
|
621
|
+
* truthy "active" value to a non-active value. Generic version of
|
|
622
|
+
* {@link refreshOnRunEnd} for callers tracking custom state machines.
|
|
623
|
+
*
|
|
624
|
+
* Must be called within an injection context.
|
|
625
|
+
*/
|
|
626
|
+
declare function refreshOnTransition<T>(watch: Signal<T>, isActive: (v: T) => boolean, fn: () => void | Promise<void>): void;
|
|
627
|
+
|
|
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 };
|