@langchain/langgraph-sdk 0.0.1-rc.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License
2
+
3
+ Copyright (c) 2024 LangChain
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
package/client.cjs ADDED
@@ -0,0 +1 @@
1
+ module.exports = require('./dist/client.cjs');
package/client.d.cts ADDED
@@ -0,0 +1 @@
1
+ export * from './dist/client.cjs'
package/client.d.ts ADDED
@@ -0,0 +1 @@
1
+ export * from './dist/client.mjs'
package/client.js ADDED
@@ -0,0 +1 @@
1
+ export * from './dist/client.mjs'
@@ -0,0 +1,111 @@
1
+ import { Assistant, AssistantGraph, Config, GraphSchema, Metadata, Run, RunEvent, Thread, ThreadState } from "./schema.js";
2
+ import { AsyncCaller, AsyncCallerParams } from "./utils/async_caller.mjs";
3
+ import { IterableReadableStreamInterface } from "./utils/stream.mjs";
4
+ interface ClientConfig {
5
+ apiUrl?: string;
6
+ callerOptions?: AsyncCallerParams;
7
+ timeoutMs?: number;
8
+ }
9
+ declare class BaseClient {
10
+ protected asyncCaller: AsyncCaller;
11
+ protected timeoutMs: number;
12
+ protected apiUrl: string;
13
+ constructor(config?: ClientConfig);
14
+ protected prepareFetchOptions(path: string, options?: RequestInit & {
15
+ json?: unknown;
16
+ params?: Record<string, unknown>;
17
+ }): [url: URL, init: RequestInit];
18
+ protected fetch<T>(path: string, options?: RequestInit & {
19
+ json?: unknown;
20
+ params?: Record<string, unknown>;
21
+ }): Promise<T>;
22
+ }
23
+ declare class AssistantsClient extends BaseClient {
24
+ get(assistantId: string): Promise<Assistant>;
25
+ getGraph(assistantId: string): Promise<AssistantGraph>;
26
+ getSchemas(assistantId: string): Promise<GraphSchema>;
27
+ create(payload: {
28
+ graphId?: string;
29
+ config?: Config;
30
+ metadata?: Metadata;
31
+ }): Promise<Assistant>;
32
+ upsert(assistantId: string, payload: {
33
+ graphId?: string;
34
+ config?: Config;
35
+ metadata?: Metadata;
36
+ }): Promise<Assistant>;
37
+ search(query: {
38
+ metadata?: Metadata;
39
+ limit?: number;
40
+ offset?: number;
41
+ }): Promise<Assistant[]>;
42
+ }
43
+ declare class ThreadsClient extends BaseClient {
44
+ get(threadId: string): Promise<Thread>;
45
+ create(payload: {
46
+ metadata?: Metadata;
47
+ }): Promise<Thread>;
48
+ upsert(threadId: string, payload: {
49
+ metadata?: Metadata;
50
+ }): Promise<Thread>;
51
+ delete(threadId: string): Promise<void>;
52
+ search(query: {
53
+ metadata?: Metadata;
54
+ limit?: number;
55
+ offset?: number;
56
+ }): Promise<Thread[]>;
57
+ getState(threadId: string): Promise<ThreadState>;
58
+ updateState(threadIdOrConfig: string | Config, values: Record<string, unknown>, options?: {
59
+ asNode?: string;
60
+ }): Promise<void>;
61
+ patchState(threadIdOrConfig: string | Config, metadata: Record<string, unknown>): Promise<void>;
62
+ getHistory(threadId: string, options?: {
63
+ limit?: number;
64
+ before?: Config;
65
+ }): Promise<ThreadState[]>;
66
+ }
67
+ declare class RunsClient extends BaseClient {
68
+ stream(threadId: string, assistantId: string, options?: {
69
+ input?: Record<string, unknown>;
70
+ streamMode?: "values" | "messages" | "updates" | "events" | "debug";
71
+ metadata?: Metadata;
72
+ config?: Config;
73
+ interruptBefore?: string[];
74
+ interruptAfter?: string[];
75
+ }): Promise<IterableReadableStreamInterface<{
76
+ event: string;
77
+ data: unknown;
78
+ }>>;
79
+ create(threadId: string, assistantId: string, options?: {
80
+ input?: Record<string, unknown>;
81
+ metadata?: Metadata;
82
+ config?: Config;
83
+ interruptBefore?: string[];
84
+ interruptAfter?: string[];
85
+ webhook?: string;
86
+ }): Promise<Run>;
87
+ wait(threadId: string, assistantId: string, options?: {
88
+ input?: Record<string, unknown>;
89
+ streamMode?: "values" | "messages" | "updates" | "events" | "debug";
90
+ metadata?: Metadata;
91
+ config?: Config;
92
+ interruptBefore?: string[];
93
+ interruptAfter?: string[];
94
+ }): Promise<ThreadState["values"]>;
95
+ list(threadId: string, options?: {
96
+ limit?: number;
97
+ offset?: number;
98
+ }): Promise<Run[]>;
99
+ get(threadId: string, runId: string): Promise<Run>;
100
+ listEvents(threadId: string, runId: string, options?: {
101
+ limit?: number;
102
+ offset?: number;
103
+ }): Promise<RunEvent[]>;
104
+ }
105
+ export declare class Client {
106
+ assistants: AssistantsClient;
107
+ threads: ThreadsClient;
108
+ runs: RunsClient;
109
+ constructor(config?: ClientConfig);
110
+ }
111
+ export {};
@@ -0,0 +1,289 @@
1
+ import { AsyncCaller } from "./utils/async_caller.mjs";
2
+ import { createParser } from "eventsource-parser";
3
+ import { IterableReadableStream, } from "./utils/stream.mjs";
4
+ class BaseClient {
5
+ constructor(config) {
6
+ Object.defineProperty(this, "asyncCaller", {
7
+ enumerable: true,
8
+ configurable: true,
9
+ writable: true,
10
+ value: void 0
11
+ });
12
+ Object.defineProperty(this, "timeoutMs", {
13
+ enumerable: true,
14
+ configurable: true,
15
+ writable: true,
16
+ value: void 0
17
+ });
18
+ Object.defineProperty(this, "apiUrl", {
19
+ enumerable: true,
20
+ configurable: true,
21
+ writable: true,
22
+ value: void 0
23
+ });
24
+ this.asyncCaller = new AsyncCaller({
25
+ maxRetries: 5,
26
+ maxConcurrency: 5,
27
+ ...config?.callerOptions,
28
+ });
29
+ this.timeoutMs = config?.timeoutMs || 12_000;
30
+ this.apiUrl = config?.apiUrl || "http://localhost:8123";
31
+ }
32
+ prepareFetchOptions(path, options) {
33
+ const mutatedOptions = { ...options };
34
+ if (mutatedOptions.json) {
35
+ mutatedOptions.body = JSON.stringify(mutatedOptions.json);
36
+ mutatedOptions.headers = {
37
+ ...mutatedOptions.headers,
38
+ "Content-Type": "application/json",
39
+ };
40
+ delete mutatedOptions.json;
41
+ }
42
+ const targetUrl = new URL(`${this.apiUrl}${path}`);
43
+ if (mutatedOptions.params) {
44
+ for (const [key, value] of Object.entries(mutatedOptions.params)) {
45
+ if (value == null)
46
+ continue;
47
+ let strValue = typeof value === "string" || typeof value === "number"
48
+ ? value.toString()
49
+ : JSON.stringify(value);
50
+ targetUrl.searchParams.append(key, strValue);
51
+ }
52
+ delete mutatedOptions.params;
53
+ }
54
+ return [targetUrl, mutatedOptions];
55
+ }
56
+ async fetch(path, options) {
57
+ const response = await this.asyncCaller.fetch(...this.prepareFetchOptions(path, options));
58
+ return response.json();
59
+ }
60
+ }
61
+ class AssistantsClient extends BaseClient {
62
+ async get(assistantId) {
63
+ return this.fetch(`/assistants/${assistantId}`);
64
+ }
65
+ async getGraph(assistantId) {
66
+ return this.fetch(`/assistants/${assistantId}/graph`);
67
+ }
68
+ async getSchemas(assistantId) {
69
+ return this.fetch(`/assistants/${assistantId}/schemas`);
70
+ }
71
+ async create(payload) {
72
+ return this.fetch("/assistants", {
73
+ method: "POST",
74
+ body: JSON.stringify({
75
+ graph_id: payload.graphId,
76
+ config: payload.config,
77
+ metadata: payload.metadata,
78
+ }),
79
+ headers: { "Content-Type": "application/json" },
80
+ });
81
+ }
82
+ async upsert(assistantId, payload) {
83
+ return this.fetch(`/assistants/${assistantId}`, {
84
+ method: "PUT",
85
+ json: {
86
+ graph_id: payload.graphId,
87
+ config: payload.config,
88
+ metadata: payload.metadata,
89
+ },
90
+ });
91
+ }
92
+ async search(query) {
93
+ return this.fetch("/assistants/search", {
94
+ method: "POST",
95
+ json: {
96
+ metadata: query.metadata ?? undefined,
97
+ limit: query.limit ?? 10,
98
+ offset: query.offset ?? 0,
99
+ },
100
+ });
101
+ }
102
+ }
103
+ class ThreadsClient extends BaseClient {
104
+ async get(threadId) {
105
+ return this.fetch(`/threads/${threadId}`);
106
+ }
107
+ async create(payload) {
108
+ return this.fetch(`/threads`, {
109
+ method: "POST",
110
+ json: { metadata: payload },
111
+ });
112
+ }
113
+ async upsert(threadId, payload) {
114
+ return this.fetch(`/threads/${threadId}`, {
115
+ method: "PUT",
116
+ json: { metadata: payload },
117
+ });
118
+ }
119
+ async delete(threadId) {
120
+ return this.fetch(`/threads/${threadId}`, {
121
+ method: "DELETE",
122
+ });
123
+ }
124
+ async search(query) {
125
+ return this.fetch("/threads/search", {
126
+ method: "POST",
127
+ json: {
128
+ metadata: query.metadata ?? undefined,
129
+ limit: query.limit ?? 10,
130
+ offset: query.offset ?? 0,
131
+ },
132
+ });
133
+ }
134
+ async getState(threadId) {
135
+ return this.fetch(`/threads/${threadId}/state`);
136
+ }
137
+ async updateState(threadIdOrConfig, values, options) {
138
+ let config = undefined;
139
+ let threadId;
140
+ if (typeof threadIdOrConfig !== "string") {
141
+ config = threadIdOrConfig;
142
+ if (typeof config.configurable.thread_id !== "string") {
143
+ throw new Error("Thread ID is required when updating state with a config.");
144
+ }
145
+ threadId = config.configurable.thread_id;
146
+ }
147
+ else {
148
+ config = undefined;
149
+ threadId = threadIdOrConfig;
150
+ }
151
+ return this.fetch(`/threads/${threadId}/state`, {
152
+ method: "POST",
153
+ json: { values, config, as_node: options?.asNode },
154
+ });
155
+ }
156
+ async patchState(threadIdOrConfig, metadata) {
157
+ let threadId;
158
+ if (typeof threadIdOrConfig !== "string") {
159
+ if (typeof threadIdOrConfig.configurable.thread_id !== "string") {
160
+ throw new Error("Thread ID is required when updating state with a config.");
161
+ }
162
+ threadId = threadIdOrConfig.configurable.thread_id;
163
+ }
164
+ else {
165
+ threadId = threadIdOrConfig;
166
+ }
167
+ return this.fetch(`/threads/${threadId}/state`, {
168
+ method: "PATCH",
169
+ json: { metadata: metadata },
170
+ });
171
+ }
172
+ async getHistory(threadId, options) {
173
+ return this.fetch(`/threads/${threadId}/history`, {
174
+ params: {
175
+ limit: options?.limit ?? 10,
176
+ before: options?.before,
177
+ },
178
+ });
179
+ }
180
+ }
181
+ class RunsClient extends BaseClient {
182
+ async stream(threadId, assistantId, options) {
183
+ const response = await this.asyncCaller.fetch(...this.prepareFetchOptions(`/threads/${threadId}/runs/stream`, {
184
+ method: "POST",
185
+ json: {
186
+ input: options?.input,
187
+ config: options?.config,
188
+ metadata: options?.metadata,
189
+ stream_mode: options?.streamMode,
190
+ assistant_id: assistantId,
191
+ interrupt_before: options?.interruptBefore,
192
+ interrupt_after: options?.interruptAfter,
193
+ },
194
+ }));
195
+ let parser;
196
+ const textDecoder = new TextDecoder();
197
+ const stream = (response.body || new ReadableStream({ start: (ctrl) => ctrl.close() })).pipeThrough(new TransformStream({
198
+ async start(ctrl) {
199
+ parser = createParser((event) => {
200
+ if (event.type === "event" && event.data === "[DONE]") {
201
+ ctrl.terminate();
202
+ return;
203
+ }
204
+ if ("data" in event) {
205
+ ctrl.enqueue({
206
+ event: event.event ?? "event",
207
+ data: JSON.parse(event.data),
208
+ });
209
+ }
210
+ });
211
+ },
212
+ async transform(chunk) {
213
+ parser.feed(textDecoder.decode(chunk));
214
+ },
215
+ }));
216
+ return IterableReadableStream.fromReadableStream(stream);
217
+ }
218
+ async create(threadId, assistantId, options) {
219
+ return this.fetch(`/threads/${threadId}/runs`, {
220
+ method: "POST",
221
+ json: {
222
+ input: options?.input,
223
+ config: options?.config,
224
+ metadata: options?.metadata,
225
+ assistant_id: assistantId,
226
+ interrupt_before: options?.interruptBefore,
227
+ interrupt_after: options?.interruptAfter,
228
+ webhook: options?.webhook,
229
+ },
230
+ });
231
+ }
232
+ async wait(threadId, assistantId, options) {
233
+ return this.fetch(`/threads/${threadId}/runs/wait`, {
234
+ method: "POST",
235
+ json: {
236
+ input: options?.input,
237
+ config: options?.config,
238
+ metadata: options?.metadata,
239
+ assistant_id: assistantId,
240
+ interrupt_before: options?.interruptBefore,
241
+ interrupt_after: options?.interruptAfter,
242
+ },
243
+ });
244
+ }
245
+ async list(threadId, options) {
246
+ return this.fetch(`/threads/${threadId}/runs`, {
247
+ params: {
248
+ limit: options?.limit ?? 10,
249
+ offset: options?.offset ?? 0,
250
+ },
251
+ });
252
+ }
253
+ async get(threadId, runId) {
254
+ return this.fetch(`/threads/${threadId}/runs/${runId}`);
255
+ }
256
+ async listEvents(threadId, runId, options) {
257
+ return this.fetch(`/threads/${threadId}/runs/${runId}/events`, {
258
+ params: {
259
+ limit: options?.limit ?? 10,
260
+ offset: options?.offset ?? 0,
261
+ },
262
+ });
263
+ }
264
+ }
265
+ export class Client {
266
+ constructor(config) {
267
+ Object.defineProperty(this, "assistants", {
268
+ enumerable: true,
269
+ configurable: true,
270
+ writable: true,
271
+ value: void 0
272
+ });
273
+ Object.defineProperty(this, "threads", {
274
+ enumerable: true,
275
+ configurable: true,
276
+ writable: true,
277
+ value: void 0
278
+ });
279
+ Object.defineProperty(this, "runs", {
280
+ enumerable: true,
281
+ configurable: true,
282
+ writable: true,
283
+ value: void 0
284
+ });
285
+ this.assistants = new AssistantsClient(config);
286
+ this.threads = new ThreadsClient(config);
287
+ this.runs = new RunsClient(config);
288
+ }
289
+ }
@@ -0,0 +1 @@
1
+ export { Client } from "./client.mjs";
package/dist/index.mjs ADDED
@@ -0,0 +1 @@
1
+ export { Client } from "./client.mjs";
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,67 @@
1
+ type Optional<T> = T | null | undefined;
2
+ export interface Config {
3
+ /**
4
+ * Tags for this call and any sub-calls (eg. a Chain calling an LLM).
5
+ * You can use these to filter calls.
6
+ */
7
+ tags: string[];
8
+ /**
9
+ * Maximum number of times a call can recurse.
10
+ * If not provided, defaults to 25.
11
+ */
12
+ recursion_limit: number;
13
+ /**
14
+ * Runtime values for attributes previously made configurable on this Runnable.
15
+ */
16
+ configurable: Record<string, unknown>;
17
+ }
18
+ export interface GraphSchema {
19
+ graph_id: string;
20
+ state_schema: Record<string, unknown>;
21
+ config_schema: Record<string, unknown>;
22
+ }
23
+ export type Metadata = Optional<Record<string, unknown>>;
24
+ export interface Assistant {
25
+ assistant_id: string;
26
+ graph_id: string;
27
+ config: Config;
28
+ created_at: string;
29
+ updated_at: string;
30
+ metadata: Metadata;
31
+ }
32
+ export type AssistantGraph = Record<string, Array<Record<string, unknown>>>;
33
+ export interface Thread {
34
+ thread_id: string;
35
+ created_at: string;
36
+ updated_at: string;
37
+ metadata: Metadata;
38
+ }
39
+ export interface ThreadState {
40
+ values: Record<string, unknown>[] | Record<string, unknown>;
41
+ next: string[];
42
+ config: Config;
43
+ metadata: Metadata;
44
+ created_at: Optional<string>;
45
+ parent_config: Optional<Config>;
46
+ }
47
+ export interface Run {
48
+ run_id: string;
49
+ thread_id: string;
50
+ assistant_id: string;
51
+ created_at: string;
52
+ updated_at: string;
53
+ status: "pending" | "running" | "error" | "success" | "timeout" | "interrupted";
54
+ metadata: Metadata;
55
+ }
56
+ export interface RunEvent {
57
+ event_id: string;
58
+ run_id: string;
59
+ received_at: string;
60
+ span_id: string;
61
+ event: string;
62
+ name: string;
63
+ data: Record<string, unknown>;
64
+ metadata: Record<string, unknown>;
65
+ tags: string[];
66
+ }
67
+ export {};
package/dist/schema.js ADDED
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,41 @@
1
+ type ResponseCallback = (response?: Response) => Promise<boolean>;
2
+ export interface AsyncCallerParams {
3
+ /**
4
+ * The maximum number of concurrent calls that can be made.
5
+ * Defaults to `Infinity`, which means no limit.
6
+ */
7
+ maxConcurrency?: number;
8
+ /**
9
+ * The maximum number of retries that can be made for a single call,
10
+ * with an exponential backoff between each attempt. Defaults to 6.
11
+ */
12
+ maxRetries?: number;
13
+ onFailedResponseHook?: ResponseCallback;
14
+ }
15
+ export interface AsyncCallerCallOptions {
16
+ signal?: AbortSignal;
17
+ }
18
+ /**
19
+ * A class that can be used to make async calls with concurrency and retry logic.
20
+ *
21
+ * This is useful for making calls to any kind of "expensive" external resource,
22
+ * be it because it's rate-limited, subject to network issues, etc.
23
+ *
24
+ * Concurrent calls are limited by the `maxConcurrency` parameter, which defaults
25
+ * to `Infinity`. This means that by default, all calls will be made in parallel.
26
+ *
27
+ * Retries are limited by the `maxRetries` parameter, which defaults to 6. This
28
+ * means that by default, each call will be retried up to 6 times, with an
29
+ * exponential backoff between each attempt.
30
+ */
31
+ export declare class AsyncCaller {
32
+ protected maxConcurrency: AsyncCallerParams["maxConcurrency"];
33
+ protected maxRetries: AsyncCallerParams["maxRetries"];
34
+ private queue;
35
+ private onFailedResponseHook?;
36
+ constructor(params: AsyncCallerParams);
37
+ call<A extends any[], T extends (...args: A) => Promise<any>>(callable: T, ...args: Parameters<T>): Promise<Awaited<ReturnType<T>>>;
38
+ callWithOptions<A extends any[], T extends (...args: A) => Promise<any>>(options: AsyncCallerCallOptions, callable: T, ...args: Parameters<T>): Promise<Awaited<ReturnType<T>>>;
39
+ fetch(...args: Parameters<typeof fetch>): ReturnType<typeof fetch>;
40
+ }
41
+ export {};
@@ -0,0 +1,136 @@
1
+ import pRetry from "p-retry";
2
+ import PQueueMod from "p-queue";
3
+ const STATUS_NO_RETRY = [
4
+ 400, // Bad Request
5
+ 401, // Unauthorized
6
+ 403, // Forbidden
7
+ 404, // Not Found
8
+ 405, // Method Not Allowed
9
+ 406, // Not Acceptable
10
+ 407, // Proxy Authentication Required
11
+ 408, // Request Timeout
12
+ ];
13
+ const STATUS_IGNORE = [
14
+ 409, // Conflict
15
+ ];
16
+ /**
17
+ * A class that can be used to make async calls with concurrency and retry logic.
18
+ *
19
+ * This is useful for making calls to any kind of "expensive" external resource,
20
+ * be it because it's rate-limited, subject to network issues, etc.
21
+ *
22
+ * Concurrent calls are limited by the `maxConcurrency` parameter, which defaults
23
+ * to `Infinity`. This means that by default, all calls will be made in parallel.
24
+ *
25
+ * Retries are limited by the `maxRetries` parameter, which defaults to 6. This
26
+ * means that by default, each call will be retried up to 6 times, with an
27
+ * exponential backoff between each attempt.
28
+ */
29
+ export class AsyncCaller {
30
+ constructor(params) {
31
+ Object.defineProperty(this, "maxConcurrency", {
32
+ enumerable: true,
33
+ configurable: true,
34
+ writable: true,
35
+ value: void 0
36
+ });
37
+ Object.defineProperty(this, "maxRetries", {
38
+ enumerable: true,
39
+ configurable: true,
40
+ writable: true,
41
+ value: void 0
42
+ });
43
+ Object.defineProperty(this, "queue", {
44
+ enumerable: true,
45
+ configurable: true,
46
+ writable: true,
47
+ value: void 0
48
+ });
49
+ Object.defineProperty(this, "onFailedResponseHook", {
50
+ enumerable: true,
51
+ configurable: true,
52
+ writable: true,
53
+ value: void 0
54
+ });
55
+ this.maxConcurrency = params.maxConcurrency ?? Infinity;
56
+ this.maxRetries = params.maxRetries ?? 6;
57
+ if ("default" in PQueueMod) {
58
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
59
+ this.queue = new PQueueMod.default({
60
+ concurrency: this.maxConcurrency,
61
+ });
62
+ }
63
+ else {
64
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
65
+ this.queue = new PQueueMod({ concurrency: this.maxConcurrency });
66
+ }
67
+ this.onFailedResponseHook = params?.onFailedResponseHook;
68
+ }
69
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
70
+ call(callable, ...args) {
71
+ const onFailedResponseHook = this.onFailedResponseHook;
72
+ return this.queue.add(() => pRetry(() => callable(...args).catch((error) => {
73
+ // eslint-disable-next-line no-instanceof/no-instanceof
74
+ console.error;
75
+ if (error instanceof Error) {
76
+ throw error;
77
+ }
78
+ else if (error instanceof Response) {
79
+ // TODO: try to parse the response body and throw a more informative error
80
+ throw new Error(`HTTP ${error.status}: ${error.statusText}`);
81
+ }
82
+ else {
83
+ throw new Error(error);
84
+ }
85
+ }), {
86
+ async onFailedAttempt(error) {
87
+ if (error.message.startsWith("Cancel") ||
88
+ error.message.startsWith("TimeoutError") ||
89
+ error.message.startsWith("AbortError")) {
90
+ throw error;
91
+ }
92
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
93
+ if (error?.code === "ECONNABORTED") {
94
+ throw error;
95
+ }
96
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
97
+ const response = error?.response;
98
+ const status = response?.status;
99
+ if (status) {
100
+ if (STATUS_NO_RETRY.includes(+status)) {
101
+ throw error;
102
+ }
103
+ else if (STATUS_IGNORE.includes(+status)) {
104
+ return;
105
+ }
106
+ if (onFailedResponseHook) {
107
+ await onFailedResponseHook(response);
108
+ }
109
+ }
110
+ },
111
+ // If needed we can change some of the defaults here,
112
+ // but they're quite sensible.
113
+ retries: this.maxRetries,
114
+ randomize: true,
115
+ }), { throwOnTimeout: true });
116
+ }
117
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
118
+ callWithOptions(options, callable, ...args) {
119
+ // Note this doesn't cancel the underlying request,
120
+ // when available prefer to use the signal option of the underlying call
121
+ if (options.signal) {
122
+ return Promise.race([
123
+ this.call(callable, ...args),
124
+ new Promise((_, reject) => {
125
+ options.signal?.addEventListener("abort", () => {
126
+ reject(new Error("AbortError"));
127
+ });
128
+ }),
129
+ ]);
130
+ }
131
+ return this.call(callable, ...args);
132
+ }
133
+ fetch(...args) {
134
+ return this.call(() => fetch(...args).then((res) => (res.ok ? res : Promise.reject(res))));
135
+ }
136
+ }
@@ -0,0 +1,11 @@
1
+ export type IterableReadableStreamInterface<T> = ReadableStream<T> & AsyncIterable<T>;
2
+ export declare class IterableReadableStream<T> extends ReadableStream<T> implements IterableReadableStreamInterface<T> {
3
+ reader: ReadableStreamDefaultReader<T>;
4
+ ensureReader(): void;
5
+ next(): Promise<IteratorResult<T>>;
6
+ return(): Promise<IteratorResult<T>>;
7
+ throw(e: any): Promise<IteratorResult<T>>;
8
+ [Symbol.asyncIterator](): this;
9
+ static fromReadableStream<T>(stream: ReadableStream<T>): IterableReadableStream<T>;
10
+ static fromAsyncGenerator<T>(generator: AsyncGenerator<T>): IterableReadableStream<T>;
11
+ }
@@ -0,0 +1,106 @@
1
+ /*
2
+ * Support async iterator syntax for ReadableStreams in all environments.
3
+ * Source: https://github.com/MattiasBuelens/web-streams-polyfill/pull/122#issuecomment-1627354490
4
+ */
5
+ export class IterableReadableStream extends ReadableStream {
6
+ constructor() {
7
+ super(...arguments);
8
+ Object.defineProperty(this, "reader", {
9
+ enumerable: true,
10
+ configurable: true,
11
+ writable: true,
12
+ value: void 0
13
+ });
14
+ }
15
+ ensureReader() {
16
+ if (!this.reader) {
17
+ this.reader = this.getReader();
18
+ }
19
+ }
20
+ async next() {
21
+ this.ensureReader();
22
+ try {
23
+ const result = await this.reader.read();
24
+ if (result.done) {
25
+ this.reader.releaseLock(); // release lock when stream becomes closed
26
+ return {
27
+ done: true,
28
+ value: undefined,
29
+ };
30
+ }
31
+ else {
32
+ return {
33
+ done: false,
34
+ value: result.value,
35
+ };
36
+ }
37
+ }
38
+ catch (e) {
39
+ this.reader.releaseLock(); // release lock when stream becomes errored
40
+ throw e;
41
+ }
42
+ }
43
+ async return() {
44
+ this.ensureReader();
45
+ // If wrapped in a Node stream, cancel is already called.
46
+ if (this.locked) {
47
+ const cancelPromise = this.reader.cancel(); // cancel first, but don't await yet
48
+ this.reader.releaseLock(); // release lock first
49
+ await cancelPromise; // now await it
50
+ }
51
+ return { done: true, value: undefined };
52
+ }
53
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
54
+ async throw(e) {
55
+ this.ensureReader();
56
+ if (this.locked) {
57
+ const cancelPromise = this.reader.cancel(); // cancel first, but don't await yet
58
+ this.reader.releaseLock(); // release lock first
59
+ await cancelPromise; // now await it
60
+ }
61
+ throw e;
62
+ }
63
+ [Symbol.asyncIterator]() {
64
+ return this;
65
+ }
66
+ static fromReadableStream(stream) {
67
+ // From https://developer.mozilla.org/en-US/docs/Web/API/Streams_API/Using_readable_streams#reading_the_stream
68
+ const reader = stream.getReader();
69
+ return new IterableReadableStream({
70
+ start(controller) {
71
+ return pump();
72
+ function pump() {
73
+ return reader.read().then(({ done, value }) => {
74
+ // When no more data needs to be consumed, close the stream
75
+ if (done) {
76
+ controller.close();
77
+ return;
78
+ }
79
+ // Enqueue the next data chunk into our target stream
80
+ controller.enqueue(value);
81
+ return pump();
82
+ });
83
+ }
84
+ },
85
+ cancel() {
86
+ reader.releaseLock();
87
+ },
88
+ });
89
+ }
90
+ static fromAsyncGenerator(generator) {
91
+ return new IterableReadableStream({
92
+ async pull(controller) {
93
+ const { value, done } = await generator.next();
94
+ // When no more data needs to be consumed, close the stream
95
+ if (done) {
96
+ controller.close();
97
+ }
98
+ // Fix: `else if (value)` will hang the streaming when nullish value (e.g. empty string) is pulled
99
+ controller.enqueue(value);
100
+ },
101
+ async cancel(reason) {
102
+ await generator.return(reason);
103
+ },
104
+ });
105
+ }
106
+ }
package/index.cjs ADDED
@@ -0,0 +1 @@
1
+ module.exports = require('./dist/index.cjs');
package/index.d.cts ADDED
@@ -0,0 +1 @@
1
+ export * from './dist/index.cjs'
package/index.d.ts ADDED
@@ -0,0 +1 @@
1
+ export * from './dist/index.mjs'
package/index.js ADDED
@@ -0,0 +1 @@
1
+ export * from './dist/index.mjs'
package/package.json ADDED
@@ -0,0 +1,60 @@
1
+ {
2
+ "name": "@langchain/langgraph-sdk",
3
+ "version": "0.0.1-rc.0",
4
+ "description": "Client library for interacting with the LangGraph API",
5
+ "type": "module",
6
+ "packageManager": "yarn@1.22.19",
7
+ "scripts": {
8
+ "clean": "rm -rf dist/ && node scripts/create-entrypoints.js clean",
9
+ "build": "yarn clean && yarn build:esm && yarn build:cjs && node scripts/create-entrypoints.js",
10
+ "build:esm": "rm -f src/package.json && tsc --outDir dist/ && rm -rf dist/tests dist/**/tests",
11
+ "build:cjs": "echo '{}' > src/package.json && tsc --outDir dist-cjs/ -p tsconfig.cjs.json && node scripts/move-cjs-to-dist.js && rm -r dist-cjs src/package.json",
12
+ "prepublish": "yarn run build"
13
+ },
14
+ "main": "index.js",
15
+ "license": "MIT",
16
+ "dependencies": {
17
+ "eventsource-parser": "^1.1.2",
18
+ "p-queue": "^6.6.2",
19
+ "p-retry": "4",
20
+ "uuid": "^9.0.0"
21
+ },
22
+ "devDependencies": {
23
+ "@tsconfig/recommended": "^1.0.2",
24
+ "@types/node": "^20.12.12",
25
+ "@types/uuid": "^9.0.1",
26
+ "typescript": "^5.4.5"
27
+ },
28
+ "exports": {
29
+ ".": {
30
+ "types": {
31
+ "import": "./index.d.ts",
32
+ "require": "./index.d.cts",
33
+ "default": "./index.d.ts"
34
+ },
35
+ "import": "./index.js",
36
+ "require": "./index.cjs"
37
+ },
38
+ "./client": {
39
+ "types": {
40
+ "import": "./client.d.ts",
41
+ "require": "./client.d.cts",
42
+ "default": "./client.d.ts"
43
+ },
44
+ "import": "./client.js",
45
+ "require": "./client.cjs"
46
+ },
47
+ "./package.json": "./package.json"
48
+ },
49
+ "files": [
50
+ "dist/",
51
+ "client.cjs",
52
+ "client.js",
53
+ "client.d.ts",
54
+ "client.d.cts",
55
+ "index.cjs",
56
+ "index.js",
57
+ "index.d.ts",
58
+ "index.d.cts"
59
+ ]
60
+ }