@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 +21 -0
- package/client.cjs +1 -0
- package/client.d.cts +1 -0
- package/client.d.ts +1 -0
- package/client.js +1 -0
- package/dist/client.d.mts +111 -0
- package/dist/client.mjs +289 -0
- package/dist/index.d.mts +1 -0
- package/dist/index.mjs +1 -0
- package/dist/schema.cjs +2 -0
- package/dist/schema.d.ts +67 -0
- package/dist/schema.js +1 -0
- package/dist/utils/async_caller.d.mts +41 -0
- package/dist/utils/async_caller.mjs +136 -0
- package/dist/utils/stream.d.mts +11 -0
- package/dist/utils/stream.mjs +106 -0
- package/index.cjs +1 -0
- package/index.d.cts +1 -0
- package/index.d.ts +1 -0
- package/index.js +1 -0
- package/package.json +60 -0
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 {};
|
package/dist/client.mjs
ADDED
|
@@ -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
|
+
}
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { Client } from "./client.mjs";
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { Client } from "./client.mjs";
|
package/dist/schema.cjs
ADDED
package/dist/schema.d.ts
ADDED
|
@@ -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
|
+
}
|