@axiom-lattice/client-sdk 1.0.23 → 1.0.25
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/README.md +33 -0
- package/dist/index.d.ts +121 -20
- package/dist/index.js +538 -369
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +537 -359
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -5
package/dist/index.mjs
CHANGED
|
@@ -20,182 +20,6 @@ var AuthenticationError = class extends Error {
|
|
|
20
20
|
}
|
|
21
21
|
};
|
|
22
22
|
|
|
23
|
-
// src/client.ts
|
|
24
|
-
import axios from "axios";
|
|
25
|
-
|
|
26
|
-
// src/wechat-client.ts
|
|
27
|
-
import { promisify } from "miniprogram-api-promise";
|
|
28
|
-
function createWechatClient(config) {
|
|
29
|
-
let wxApi = null;
|
|
30
|
-
if (typeof global !== "undefined" && global.wx) {
|
|
31
|
-
wxApi = global.wx;
|
|
32
|
-
} else if (typeof globalThis !== "undefined" && globalThis.wx) {
|
|
33
|
-
wxApi = globalThis.wx;
|
|
34
|
-
} else {
|
|
35
|
-
try {
|
|
36
|
-
const win = globalThis;
|
|
37
|
-
if (win.wx) {
|
|
38
|
-
wxApi = win.wx;
|
|
39
|
-
}
|
|
40
|
-
} catch (e) {
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
if (!wxApi) {
|
|
44
|
-
throw new Error("WeChat Mini Program environment not detected");
|
|
45
|
-
}
|
|
46
|
-
const request = promisify(wxApi.request);
|
|
47
|
-
const defaultHeaders = {
|
|
48
|
-
"Content-Type": "application/json",
|
|
49
|
-
...config.headers
|
|
50
|
-
};
|
|
51
|
-
const interceptors = {
|
|
52
|
-
request: {
|
|
53
|
-
handlers: [],
|
|
54
|
-
use(fulfilled, rejected) {
|
|
55
|
-
const id = this.handlers.length;
|
|
56
|
-
this.handlers.push({ fulfilled, rejected });
|
|
57
|
-
return id;
|
|
58
|
-
},
|
|
59
|
-
eject(id) {
|
|
60
|
-
if (this.handlers[id]) {
|
|
61
|
-
this.handlers[id] = {};
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
},
|
|
65
|
-
response: {
|
|
66
|
-
handlers: [],
|
|
67
|
-
use(fulfilled, rejected) {
|
|
68
|
-
const id = this.handlers.length;
|
|
69
|
-
this.handlers.push({ fulfilled, rejected });
|
|
70
|
-
return id;
|
|
71
|
-
},
|
|
72
|
-
eject(id) {
|
|
73
|
-
if (this.handlers[id]) {
|
|
74
|
-
this.handlers[id] = {};
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
};
|
|
79
|
-
const processRequestInterceptors = (requestConfig) => {
|
|
80
|
-
let config2 = { ...requestConfig };
|
|
81
|
-
for (const handler of interceptors.request.handlers) {
|
|
82
|
-
if (handler.fulfilled) {
|
|
83
|
-
try {
|
|
84
|
-
config2 = handler.fulfilled(config2);
|
|
85
|
-
} catch (error) {
|
|
86
|
-
if (handler.rejected) {
|
|
87
|
-
handler.rejected(error);
|
|
88
|
-
}
|
|
89
|
-
throw error;
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
return config2;
|
|
94
|
-
};
|
|
95
|
-
const processResponseInterceptors = async (response) => {
|
|
96
|
-
let result = response;
|
|
97
|
-
for (const handler of interceptors.response.handlers) {
|
|
98
|
-
if (handler.fulfilled) {
|
|
99
|
-
try {
|
|
100
|
-
result = await handler.fulfilled(result);
|
|
101
|
-
} catch (error) {
|
|
102
|
-
if (handler.rejected) {
|
|
103
|
-
result = await handler.rejected(error);
|
|
104
|
-
} else {
|
|
105
|
-
throw error;
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
return result;
|
|
111
|
-
};
|
|
112
|
-
const processErrorInterceptors = async (error) => {
|
|
113
|
-
let result = error;
|
|
114
|
-
for (const handler of interceptors.response.handlers) {
|
|
115
|
-
if (handler.rejected) {
|
|
116
|
-
try {
|
|
117
|
-
result = await handler.rejected(result);
|
|
118
|
-
} catch (newError) {
|
|
119
|
-
result = newError;
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
return Promise.reject(result);
|
|
124
|
-
};
|
|
125
|
-
const CancelToken = {
|
|
126
|
-
source() {
|
|
127
|
-
let cancel = () => {
|
|
128
|
-
};
|
|
129
|
-
const token = {
|
|
130
|
-
promise: new Promise((resolve) => {
|
|
131
|
-
cancel = (message = "Request cancelled") => resolve(message);
|
|
132
|
-
}),
|
|
133
|
-
reason: void 0
|
|
134
|
-
};
|
|
135
|
-
return {
|
|
136
|
-
token,
|
|
137
|
-
cancel
|
|
138
|
-
};
|
|
139
|
-
}
|
|
140
|
-
};
|
|
141
|
-
const isCancel = (value) => {
|
|
142
|
-
return value && value.__CANCEL__;
|
|
143
|
-
};
|
|
144
|
-
const makeRequest = async (method, url, data, customConfig) => {
|
|
145
|
-
try {
|
|
146
|
-
const requestConfig = processRequestInterceptors({
|
|
147
|
-
url: `${config.baseURL}${url}`,
|
|
148
|
-
method,
|
|
149
|
-
data,
|
|
150
|
-
header: { ...defaultHeaders, ...customConfig?.headers },
|
|
151
|
-
timeout: config.timeout || 3e4,
|
|
152
|
-
...customConfig
|
|
153
|
-
});
|
|
154
|
-
if (customConfig?.cancelToken) {
|
|
155
|
-
customConfig.cancelToken.promise.then((reason) => {
|
|
156
|
-
throw Object.assign(new Error(reason), { __CANCEL__: true });
|
|
157
|
-
});
|
|
158
|
-
}
|
|
159
|
-
const response = await request(requestConfig);
|
|
160
|
-
const transformedResponse = {
|
|
161
|
-
data: response.data,
|
|
162
|
-
status: response.statusCode,
|
|
163
|
-
statusText: response.errMsg,
|
|
164
|
-
headers: response.header,
|
|
165
|
-
config: requestConfig
|
|
166
|
-
};
|
|
167
|
-
return await processResponseInterceptors(transformedResponse);
|
|
168
|
-
} catch (error) {
|
|
169
|
-
return processErrorInterceptors(error);
|
|
170
|
-
}
|
|
171
|
-
};
|
|
172
|
-
const client = {
|
|
173
|
-
get: (url, customConfig) => makeRequest("GET", url, null, customConfig),
|
|
174
|
-
post: (url, data, customConfig) => makeRequest("POST", url, data, customConfig),
|
|
175
|
-
delete: (url, customConfig) => makeRequest("DELETE", url, null, customConfig),
|
|
176
|
-
put: (url, data, customConfig) => makeRequest("PUT", url, data, customConfig),
|
|
177
|
-
patch: (url, data, customConfig) => makeRequest("PATCH", url, data, customConfig),
|
|
178
|
-
head: (url, customConfig) => makeRequest("HEAD", url, null, customConfig),
|
|
179
|
-
options: (url, customConfig) => makeRequest("OPTIONS", url, null, customConfig),
|
|
180
|
-
defaults: {
|
|
181
|
-
headers: defaultHeaders
|
|
182
|
-
},
|
|
183
|
-
interceptors: {
|
|
184
|
-
request: {
|
|
185
|
-
use: interceptors.request.use.bind(interceptors.request),
|
|
186
|
-
eject: interceptors.request.eject.bind(interceptors.request)
|
|
187
|
-
},
|
|
188
|
-
response: {
|
|
189
|
-
use: interceptors.response.use.bind(interceptors.response),
|
|
190
|
-
eject: interceptors.response.eject.bind(interceptors.response)
|
|
191
|
-
}
|
|
192
|
-
},
|
|
193
|
-
CancelToken,
|
|
194
|
-
isCancel
|
|
195
|
-
};
|
|
196
|
-
return client;
|
|
197
|
-
}
|
|
198
|
-
|
|
199
23
|
// src/client.ts
|
|
200
24
|
var Client = class {
|
|
201
25
|
/**
|
|
@@ -283,63 +107,70 @@ var Client = class {
|
|
|
283
107
|
}
|
|
284
108
|
};
|
|
285
109
|
this.config = {
|
|
286
|
-
timeout:
|
|
287
|
-
environment: "web",
|
|
288
|
-
// Default to web environment
|
|
110
|
+
timeout: 3e5,
|
|
289
111
|
...config
|
|
290
112
|
};
|
|
291
|
-
this.environment = this.config.environment || "web";
|
|
292
113
|
this.assistantId = config.assistantId;
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
114
|
+
this.headers = {
|
|
115
|
+
"Content-Type": "application/json",
|
|
116
|
+
Authorization: `Bearer ${this.config.apiKey}`,
|
|
117
|
+
...this.config.headers
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Helper method to handle fetch responses and errors
|
|
122
|
+
* @private
|
|
123
|
+
*/
|
|
124
|
+
async handleResponse(response) {
|
|
125
|
+
if (!response.ok) {
|
|
126
|
+
if (response.status === 401) {
|
|
127
|
+
throw new AuthenticationError("Authentication failed");
|
|
128
|
+
} else {
|
|
129
|
+
const errorData = await response.json().catch(() => ({}));
|
|
130
|
+
throw new ApiError(
|
|
131
|
+
errorData.message || "API Error",
|
|
132
|
+
response.status,
|
|
133
|
+
errorData
|
|
134
|
+
);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
if (response.status === 204) {
|
|
138
|
+
return {};
|
|
139
|
+
}
|
|
140
|
+
try {
|
|
141
|
+
return await response.json();
|
|
142
|
+
} catch (error) {
|
|
143
|
+
throw new Error(`Failed to parse response: ${error}`);
|
|
313
144
|
}
|
|
314
|
-
this.setupInterceptors();
|
|
315
145
|
}
|
|
316
146
|
/**
|
|
317
|
-
*
|
|
147
|
+
* Helper method to make fetch requests
|
|
318
148
|
* @private
|
|
319
149
|
*/
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
throw new Error(`Request error: ${error.message}`);
|
|
340
|
-
}
|
|
150
|
+
async fetchWithTimeout(url, options = {}) {
|
|
151
|
+
const controller = new AbortController();
|
|
152
|
+
const timeoutId = setTimeout(() => controller.abort(), this.config.timeout);
|
|
153
|
+
try {
|
|
154
|
+
const fullUrl = url.startsWith("http") ? url : `${this.config.baseURL}${url}`;
|
|
155
|
+
const response = await fetch(fullUrl, {
|
|
156
|
+
...options,
|
|
157
|
+
headers: {
|
|
158
|
+
...this.headers,
|
|
159
|
+
...options.headers || {}
|
|
160
|
+
},
|
|
161
|
+
signal: controller.signal
|
|
162
|
+
});
|
|
163
|
+
return await this.handleResponse(response);
|
|
164
|
+
} catch (error) {
|
|
165
|
+
if (error instanceof DOMException && error.name === "AbortError") {
|
|
166
|
+
throw new NetworkError("Request timed out");
|
|
167
|
+
} else if (error instanceof TypeError && error.message.includes("fetch")) {
|
|
168
|
+
throw new NetworkError("Network request failed");
|
|
341
169
|
}
|
|
342
|
-
|
|
170
|
+
throw error;
|
|
171
|
+
} finally {
|
|
172
|
+
clearTimeout(timeoutId);
|
|
173
|
+
}
|
|
343
174
|
}
|
|
344
175
|
/**
|
|
345
176
|
* Set tenant ID for multi-tenant environments
|
|
@@ -347,7 +178,7 @@ var Client = class {
|
|
|
347
178
|
*/
|
|
348
179
|
setTenantId(tenantId) {
|
|
349
180
|
this.tenantId = tenantId;
|
|
350
|
-
this.
|
|
181
|
+
this.headers["x-tenant-id"] = tenantId;
|
|
351
182
|
}
|
|
352
183
|
/**
|
|
353
184
|
* Creates a new thread
|
|
@@ -356,11 +187,14 @@ var Client = class {
|
|
|
356
187
|
*/
|
|
357
188
|
async createThread(options) {
|
|
358
189
|
try {
|
|
359
|
-
const
|
|
360
|
-
|
|
361
|
-
|
|
190
|
+
const data = await this.fetchWithTimeout("/threads", {
|
|
191
|
+
method: "POST",
|
|
192
|
+
body: JSON.stringify({
|
|
193
|
+
...options,
|
|
194
|
+
assistantId: this.assistantId
|
|
195
|
+
})
|
|
362
196
|
});
|
|
363
|
-
return
|
|
197
|
+
return data.id;
|
|
364
198
|
} catch (error) {
|
|
365
199
|
throw error;
|
|
366
200
|
}
|
|
@@ -372,12 +206,9 @@ var Client = class {
|
|
|
372
206
|
*/
|
|
373
207
|
async getThread(threadId) {
|
|
374
208
|
try {
|
|
375
|
-
const
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
}
|
|
379
|
-
});
|
|
380
|
-
return response.data;
|
|
209
|
+
const url = new URL(`${this.config.baseURL}/threads/${threadId}`);
|
|
210
|
+
url.searchParams.append("assistantId", this.assistantId);
|
|
211
|
+
return await this.fetchWithTimeout(url.toString());
|
|
381
212
|
} catch (error) {
|
|
382
213
|
throw error;
|
|
383
214
|
}
|
|
@@ -389,13 +220,18 @@ var Client = class {
|
|
|
389
220
|
*/
|
|
390
221
|
async listThreads(options) {
|
|
391
222
|
try {
|
|
392
|
-
const
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
223
|
+
const url = new URL(`${this.config.baseURL}/threads`);
|
|
224
|
+
url.searchParams.append("assistantId", this.assistantId);
|
|
225
|
+
if (options?.limit) {
|
|
226
|
+
url.searchParams.append("limit", options.limit.toString());
|
|
227
|
+
}
|
|
228
|
+
if (options?.offset !== void 0) {
|
|
229
|
+
url.searchParams.append("offset", options.offset.toString());
|
|
230
|
+
}
|
|
231
|
+
const data = await this.fetchWithTimeout(
|
|
232
|
+
url.toString()
|
|
233
|
+
);
|
|
234
|
+
return data.threads;
|
|
399
235
|
} catch (error) {
|
|
400
236
|
throw error;
|
|
401
237
|
}
|
|
@@ -407,10 +243,10 @@ var Client = class {
|
|
|
407
243
|
*/
|
|
408
244
|
async deleteThread(threadId) {
|
|
409
245
|
try {
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
246
|
+
const url = new URL(`${this.config.baseURL}/threads/${threadId}`);
|
|
247
|
+
url.searchParams.append("assistantId", this.assistantId);
|
|
248
|
+
await this.fetchWithTimeout(url.toString(), {
|
|
249
|
+
method: "DELETE"
|
|
414
250
|
});
|
|
415
251
|
} catch (error) {
|
|
416
252
|
throw error;
|
|
@@ -423,18 +259,20 @@ var Client = class {
|
|
|
423
259
|
*/
|
|
424
260
|
async getMessages(options) {
|
|
425
261
|
try {
|
|
426
|
-
const
|
|
427
|
-
|
|
428
|
-
{
|
|
429
|
-
params: {
|
|
430
|
-
limit: options.limit,
|
|
431
|
-
after: options.after,
|
|
432
|
-
reverse: options.reverse,
|
|
433
|
-
assistantId: this.assistantId
|
|
434
|
-
}
|
|
435
|
-
}
|
|
262
|
+
const url = new URL(
|
|
263
|
+
`${this.config.baseURL}/api/assistants/${this.assistantId}/${options.threadId}/memory`
|
|
436
264
|
);
|
|
437
|
-
|
|
265
|
+
if (options.limit) {
|
|
266
|
+
url.searchParams.append("limit", options.limit.toString());
|
|
267
|
+
}
|
|
268
|
+
if (options.after) {
|
|
269
|
+
url.searchParams.append("after", options.after);
|
|
270
|
+
}
|
|
271
|
+
if (options.reverse !== void 0) {
|
|
272
|
+
url.searchParams.append("reverse", options.reverse.toString());
|
|
273
|
+
}
|
|
274
|
+
url.searchParams.append("assistantId", this.assistantId);
|
|
275
|
+
return await this.fetchWithTimeout(url.toString());
|
|
438
276
|
} catch (error) {
|
|
439
277
|
throw error;
|
|
440
278
|
}
|
|
@@ -446,10 +284,9 @@ var Client = class {
|
|
|
446
284
|
*/
|
|
447
285
|
async getAgentState(threadId) {
|
|
448
286
|
try {
|
|
449
|
-
|
|
287
|
+
return await this.fetchWithTimeout(
|
|
450
288
|
`/api/assistants/${this.assistantId}/${threadId}/state`
|
|
451
289
|
);
|
|
452
|
-
return response.data;
|
|
453
290
|
} catch (error) {
|
|
454
291
|
throw error;
|
|
455
292
|
}
|
|
@@ -460,10 +297,10 @@ var Client = class {
|
|
|
460
297
|
*/
|
|
461
298
|
async getAgentGraph() {
|
|
462
299
|
try {
|
|
463
|
-
const
|
|
300
|
+
const data = await this.fetchWithTimeout(
|
|
464
301
|
`/api/assistants/${this.assistantId}/graph`
|
|
465
302
|
);
|
|
466
|
-
return
|
|
303
|
+
return data.image;
|
|
467
304
|
} catch (error) {
|
|
468
305
|
throw error;
|
|
469
306
|
}
|
|
@@ -471,7 +308,7 @@ var Client = class {
|
|
|
471
308
|
/**
|
|
472
309
|
* Run agent with options
|
|
473
310
|
* @param options - Options for running the agent
|
|
474
|
-
* @returns A promise that resolves to the run result
|
|
311
|
+
* @returns A promise that resolves to the run result
|
|
475
312
|
*/
|
|
476
313
|
async run(options) {
|
|
477
314
|
try {
|
|
@@ -484,9 +321,10 @@ var Client = class {
|
|
|
484
321
|
"Streaming without callbacks is not supported. Use chat.stream with callbacks instead."
|
|
485
322
|
);
|
|
486
323
|
} else {
|
|
487
|
-
|
|
488
|
-
"
|
|
489
|
-
|
|
324
|
+
return await this.fetchWithTimeout("/api/runs", {
|
|
325
|
+
method: "POST",
|
|
326
|
+
headers,
|
|
327
|
+
body: JSON.stringify({
|
|
490
328
|
assistant_id: this.assistantId,
|
|
491
329
|
thread_id: options.threadId,
|
|
492
330
|
message: options.message,
|
|
@@ -494,10 +332,8 @@ var Client = class {
|
|
|
494
332
|
command: options.command,
|
|
495
333
|
streaming: false,
|
|
496
334
|
background: options.background || false
|
|
497
|
-
}
|
|
498
|
-
|
|
499
|
-
);
|
|
500
|
-
return response.data;
|
|
335
|
+
})
|
|
336
|
+
});
|
|
501
337
|
}
|
|
502
338
|
} catch (error) {
|
|
503
339
|
throw error;
|
|
@@ -512,30 +348,22 @@ var Client = class {
|
|
|
512
348
|
* @returns A function that can be called to stop the stream
|
|
513
349
|
*/
|
|
514
350
|
streamRun(options, onEvent, onComplete, onError) {
|
|
515
|
-
if (this.environment === "wechat-miniprogram") {
|
|
516
|
-
return this.streamRunWechat(options, onEvent, onComplete, onError);
|
|
517
|
-
} else {
|
|
518
|
-
return this.streamRunWeb(options, onEvent, onComplete, onError);
|
|
519
|
-
}
|
|
520
|
-
}
|
|
521
|
-
/**
|
|
522
|
-
* Stream run results using axios for web environment
|
|
523
|
-
* @private
|
|
524
|
-
*/
|
|
525
|
-
streamRunWeb(options, onEvent, onComplete, onError) {
|
|
526
351
|
const headers = {
|
|
527
|
-
"Content-Type": "application/json"
|
|
352
|
+
"Content-Type": "application/json",
|
|
353
|
+
Accept: "text/event-stream",
|
|
354
|
+
...this.headers
|
|
528
355
|
};
|
|
529
356
|
if (this.tenantId) {
|
|
530
357
|
headers["x-tenant-id"] = this.tenantId;
|
|
531
358
|
}
|
|
532
|
-
const
|
|
359
|
+
const controller = new AbortController();
|
|
360
|
+
const { signal } = controller;
|
|
533
361
|
(async () => {
|
|
534
362
|
try {
|
|
535
|
-
const
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
{
|
|
363
|
+
const response = await fetch(`${this.config.baseURL}/api/runs`, {
|
|
364
|
+
method: "POST",
|
|
365
|
+
headers,
|
|
366
|
+
body: JSON.stringify({
|
|
539
367
|
assistant_id: this.assistantId,
|
|
540
368
|
thread_id: options.threadId,
|
|
541
369
|
message: options.message,
|
|
@@ -543,33 +371,50 @@ var Client = class {
|
|
|
543
371
|
command: options.command,
|
|
544
372
|
streaming: true,
|
|
545
373
|
background: options.background || false
|
|
546
|
-
},
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
374
|
+
}),
|
|
375
|
+
signal
|
|
376
|
+
});
|
|
377
|
+
if (!response.ok) {
|
|
378
|
+
throw new Error(`HTTP error! Status: ${response.status}`);
|
|
379
|
+
}
|
|
380
|
+
if (!response.body) {
|
|
381
|
+
throw new Error("Response body is null");
|
|
382
|
+
}
|
|
383
|
+
const reader = response.body.getReader();
|
|
384
|
+
const decoder = new TextDecoder();
|
|
385
|
+
let buffer = "";
|
|
386
|
+
while (true) {
|
|
387
|
+
const { done, value } = await reader.read();
|
|
388
|
+
if (done)
|
|
389
|
+
break;
|
|
390
|
+
const chunk = decoder.decode(value, { stream: true });
|
|
391
|
+
buffer += chunk;
|
|
392
|
+
const lines = buffer.split("\n");
|
|
393
|
+
buffer = lines.pop() || "";
|
|
394
|
+
for (const line of lines) {
|
|
395
|
+
if (line.trim().startsWith("data: ")) {
|
|
396
|
+
try {
|
|
397
|
+
const eventData = JSON.parse(line.trim().slice(6));
|
|
398
|
+
onEvent(eventData);
|
|
399
|
+
} catch (error) {
|
|
400
|
+
console.error("Error parsing SSE data:", line, error);
|
|
401
|
+
if (onError) {
|
|
402
|
+
onError(
|
|
403
|
+
error instanceof Error ? error : new Error(String(error))
|
|
404
|
+
);
|
|
567
405
|
}
|
|
568
406
|
}
|
|
569
|
-
return data;
|
|
570
407
|
}
|
|
571
408
|
}
|
|
572
|
-
|
|
409
|
+
}
|
|
410
|
+
if (buffer && buffer.trim().startsWith("data: ")) {
|
|
411
|
+
try {
|
|
412
|
+
const eventData = JSON.parse(buffer.trim().slice(6));
|
|
413
|
+
onEvent(eventData);
|
|
414
|
+
} catch (error) {
|
|
415
|
+
console.error("Error parsing SSE data:", buffer, error);
|
|
416
|
+
}
|
|
417
|
+
}
|
|
573
418
|
if (onComplete) {
|
|
574
419
|
if (options.enableReturnStateWhenSteamCompleted) {
|
|
575
420
|
try {
|
|
@@ -583,7 +428,7 @@ var Client = class {
|
|
|
583
428
|
}
|
|
584
429
|
}
|
|
585
430
|
} catch (error) {
|
|
586
|
-
if (
|
|
431
|
+
if (error instanceof DOMException && error.name === "AbortError") {
|
|
587
432
|
return;
|
|
588
433
|
}
|
|
589
434
|
if (onError) {
|
|
@@ -592,74 +437,406 @@ var Client = class {
|
|
|
592
437
|
}
|
|
593
438
|
})();
|
|
594
439
|
return () => {
|
|
595
|
-
|
|
440
|
+
controller.abort();
|
|
596
441
|
};
|
|
597
442
|
}
|
|
443
|
+
};
|
|
444
|
+
|
|
445
|
+
// src/wechat-client.ts
|
|
446
|
+
var WeChatClient = class {
|
|
598
447
|
/**
|
|
599
|
-
*
|
|
448
|
+
* Creates a new WeChatClient instance
|
|
449
|
+
* @param config - Configuration options for the client
|
|
450
|
+
*/
|
|
451
|
+
constructor(config) {
|
|
452
|
+
this.tenantId = "";
|
|
453
|
+
this.registeredTools = /* @__PURE__ */ new Map();
|
|
454
|
+
/**
|
|
455
|
+
* Chat namespace for sending messages and streaming responses
|
|
456
|
+
*/
|
|
457
|
+
this.chat = {
|
|
458
|
+
/**
|
|
459
|
+
* Sends a message to a thread and receives a response
|
|
460
|
+
* @param options - Options for sending a message
|
|
461
|
+
* @returns A promise that resolves to the chat response
|
|
462
|
+
*/
|
|
463
|
+
send: async (options) => {
|
|
464
|
+
try {
|
|
465
|
+
const message = options.messages[options.messages.length - 1];
|
|
466
|
+
const result = await this.run({
|
|
467
|
+
threadId: options.threadId,
|
|
468
|
+
message: typeof message.content === "string" ? message.content : JSON.stringify(message.content),
|
|
469
|
+
streaming: false
|
|
470
|
+
});
|
|
471
|
+
return {
|
|
472
|
+
message: {
|
|
473
|
+
role: "ai",
|
|
474
|
+
content: result.output || "",
|
|
475
|
+
id: result.id || ""
|
|
476
|
+
},
|
|
477
|
+
traceId: result.id || ""
|
|
478
|
+
};
|
|
479
|
+
} catch (error) {
|
|
480
|
+
throw error;
|
|
481
|
+
}
|
|
482
|
+
},
|
|
483
|
+
/**
|
|
484
|
+
* Sends a message to a thread and streams the response
|
|
485
|
+
* @param options - Options for streaming a message
|
|
486
|
+
* @param onEvent - Callback function that receives stream events
|
|
487
|
+
* @param onComplete - Optional callback function called when streaming completes
|
|
488
|
+
* @param onError - Optional callback function called when an error occurs
|
|
489
|
+
* @returns A function that can be called to stop the stream
|
|
490
|
+
*/
|
|
491
|
+
stream: (options, onEvent, onComplete, onError) => {
|
|
492
|
+
const message = options.messages[options.messages.length - 1];
|
|
493
|
+
return this.streamRun(
|
|
494
|
+
{
|
|
495
|
+
threadId: options.threadId,
|
|
496
|
+
message: typeof message.content === "string" ? message.content : JSON.stringify(message.content),
|
|
497
|
+
streaming: true,
|
|
498
|
+
background: options.background,
|
|
499
|
+
enableReturnStateWhenSteamCompleted: options.enableReturnStateWhenSteamCompleted
|
|
500
|
+
},
|
|
501
|
+
onEvent,
|
|
502
|
+
onComplete,
|
|
503
|
+
onError
|
|
504
|
+
);
|
|
505
|
+
}
|
|
506
|
+
};
|
|
507
|
+
/**
|
|
508
|
+
* Tools namespace for registering and unregistering client-side tools
|
|
509
|
+
*/
|
|
510
|
+
this.tools = {
|
|
511
|
+
/**
|
|
512
|
+
* Registers a client-side tool
|
|
513
|
+
* @param options - Options for registering a tool
|
|
514
|
+
*/
|
|
515
|
+
register: (options) => {
|
|
516
|
+
if (this.config.transport !== "ws") {
|
|
517
|
+
throw new Error(
|
|
518
|
+
"Client-side tools are only supported with WebSocket transport"
|
|
519
|
+
);
|
|
520
|
+
}
|
|
521
|
+
this.registeredTools.set(options.name, options);
|
|
522
|
+
},
|
|
523
|
+
/**
|
|
524
|
+
* Unregisters a client-side tool
|
|
525
|
+
* @param name - Tool name
|
|
526
|
+
*/
|
|
527
|
+
unregister: (name) => {
|
|
528
|
+
this.registeredTools.delete(name);
|
|
529
|
+
}
|
|
530
|
+
};
|
|
531
|
+
this.config = {
|
|
532
|
+
timeout: 3e4,
|
|
533
|
+
...config
|
|
534
|
+
};
|
|
535
|
+
this.assistantId = config.assistantId;
|
|
536
|
+
}
|
|
537
|
+
/**
|
|
538
|
+
* Set tenant ID for multi-tenant environments
|
|
539
|
+
* @param tenantId - Tenant identifier
|
|
540
|
+
*/
|
|
541
|
+
setTenantId(tenantId) {
|
|
542
|
+
this.tenantId = tenantId;
|
|
543
|
+
}
|
|
544
|
+
/**
|
|
545
|
+
* Helper method to make WeChat HTTP requests
|
|
600
546
|
* @private
|
|
601
547
|
*/
|
|
602
|
-
|
|
603
|
-
const
|
|
604
|
-
let
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
548
|
+
async request(options) {
|
|
549
|
+
const { url, method, data, params } = options;
|
|
550
|
+
let fullUrl = `${this.config.baseURL}${url}`;
|
|
551
|
+
if (params && Object.keys(params).length > 0) {
|
|
552
|
+
const queryParams = new URLSearchParams();
|
|
553
|
+
Object.entries(params).forEach(([key, value]) => {
|
|
554
|
+
if (value !== void 0) {
|
|
555
|
+
queryParams.append(key, String(value));
|
|
556
|
+
}
|
|
557
|
+
});
|
|
558
|
+
fullUrl += `?${queryParams.toString()}`;
|
|
559
|
+
}
|
|
560
|
+
const headers = {
|
|
561
|
+
"Content-Type": "application/json",
|
|
562
|
+
Authorization: `Bearer ${this.config.apiKey}`,
|
|
563
|
+
...this.config.headers
|
|
564
|
+
};
|
|
565
|
+
if (this.tenantId) {
|
|
566
|
+
headers["x-tenant-id"] = this.tenantId;
|
|
567
|
+
}
|
|
568
|
+
return new Promise((resolve, reject) => {
|
|
569
|
+
wx.request({
|
|
570
|
+
url: fullUrl,
|
|
571
|
+
method,
|
|
572
|
+
data,
|
|
573
|
+
header: headers,
|
|
574
|
+
timeout: this.config.timeout,
|
|
575
|
+
success: (res) => {
|
|
576
|
+
const statusCode = res.statusCode;
|
|
577
|
+
if (statusCode >= 200 && statusCode < 300) {
|
|
578
|
+
resolve(res.data);
|
|
579
|
+
} else if (statusCode === 401) {
|
|
580
|
+
reject(
|
|
581
|
+
new AuthenticationError(
|
|
582
|
+
res.data?.message || "Authentication failed"
|
|
583
|
+
)
|
|
584
|
+
);
|
|
585
|
+
} else {
|
|
586
|
+
reject(
|
|
587
|
+
new ApiError(
|
|
588
|
+
res.data?.message || "API Error",
|
|
589
|
+
statusCode,
|
|
590
|
+
res.data
|
|
591
|
+
)
|
|
592
|
+
);
|
|
593
|
+
}
|
|
594
|
+
},
|
|
595
|
+
fail: (err) => {
|
|
596
|
+
reject(new NetworkError(`Request failed: ${err.errMsg}`));
|
|
597
|
+
}
|
|
598
|
+
});
|
|
599
|
+
});
|
|
600
|
+
}
|
|
601
|
+
/**
|
|
602
|
+
* Creates a new thread
|
|
603
|
+
* @param options - Options for creating a thread
|
|
604
|
+
* @returns A promise that resolves to the thread ID
|
|
605
|
+
*/
|
|
606
|
+
async createThread(options) {
|
|
607
|
+
try {
|
|
608
|
+
const response = await this.request({
|
|
609
|
+
url: "/threads",
|
|
610
|
+
method: "POST",
|
|
611
|
+
data: {
|
|
612
|
+
...options,
|
|
613
|
+
assistantId: this.assistantId
|
|
614
|
+
}
|
|
615
|
+
});
|
|
616
|
+
return response.id;
|
|
617
|
+
} catch (error) {
|
|
618
|
+
throw error;
|
|
619
|
+
}
|
|
620
|
+
}
|
|
621
|
+
/**
|
|
622
|
+
* Retrieves thread information
|
|
623
|
+
* @param threadId - Thread identifier
|
|
624
|
+
* @returns A promise that resolves to the thread information
|
|
625
|
+
*/
|
|
626
|
+
async getThread(threadId) {
|
|
627
|
+
try {
|
|
628
|
+
return await this.request({
|
|
629
|
+
url: `/threads/${threadId}`,
|
|
630
|
+
method: "GET",
|
|
631
|
+
params: {
|
|
632
|
+
assistantId: this.assistantId
|
|
633
|
+
}
|
|
634
|
+
});
|
|
635
|
+
} catch (error) {
|
|
636
|
+
throw error;
|
|
637
|
+
}
|
|
638
|
+
}
|
|
639
|
+
/**
|
|
640
|
+
* Lists all threads
|
|
641
|
+
* @param options - Options for listing threads
|
|
642
|
+
* @returns A promise that resolves to an array of threads
|
|
643
|
+
*/
|
|
644
|
+
async listThreads(options) {
|
|
645
|
+
try {
|
|
646
|
+
const response = await this.request({
|
|
647
|
+
url: "/threads",
|
|
648
|
+
method: "GET",
|
|
649
|
+
params: {
|
|
650
|
+
...options,
|
|
651
|
+
assistantId: this.assistantId
|
|
652
|
+
}
|
|
653
|
+
});
|
|
654
|
+
return response.threads;
|
|
655
|
+
} catch (error) {
|
|
656
|
+
throw error;
|
|
657
|
+
}
|
|
658
|
+
}
|
|
659
|
+
/**
|
|
660
|
+
* Deletes a thread
|
|
661
|
+
* @param threadId - Thread identifier
|
|
662
|
+
* @returns A promise that resolves when the thread is deleted
|
|
663
|
+
*/
|
|
664
|
+
async deleteThread(threadId) {
|
|
665
|
+
try {
|
|
666
|
+
await this.request({
|
|
667
|
+
url: `/threads/${threadId}`,
|
|
668
|
+
method: "DELETE",
|
|
669
|
+
params: {
|
|
670
|
+
assistantId: this.assistantId
|
|
671
|
+
}
|
|
672
|
+
});
|
|
673
|
+
} catch (error) {
|
|
674
|
+
throw error;
|
|
675
|
+
}
|
|
676
|
+
}
|
|
677
|
+
/**
|
|
678
|
+
* Retrieves messages from a thread
|
|
679
|
+
* @param options - Options for retrieving messages
|
|
680
|
+
* @returns A promise that resolves to an array of messages
|
|
681
|
+
*/
|
|
682
|
+
async getMessages(options) {
|
|
683
|
+
try {
|
|
684
|
+
return await this.request({
|
|
685
|
+
url: `/api/assistants/${this.assistantId}/${options.threadId}/memory`,
|
|
686
|
+
method: "GET",
|
|
687
|
+
params: {
|
|
688
|
+
limit: options.limit,
|
|
689
|
+
after: options.after,
|
|
690
|
+
reverse: options.reverse,
|
|
691
|
+
assistantId: this.assistantId
|
|
692
|
+
}
|
|
693
|
+
});
|
|
694
|
+
} catch (error) {
|
|
695
|
+
throw error;
|
|
696
|
+
}
|
|
697
|
+
}
|
|
698
|
+
/**
|
|
699
|
+
* Retrieves agent state
|
|
700
|
+
* @param threadId - Thread identifier
|
|
701
|
+
* @returns A promise that resolves to the agent state
|
|
702
|
+
*/
|
|
703
|
+
async getAgentState(threadId) {
|
|
704
|
+
try {
|
|
705
|
+
return await this.request({
|
|
706
|
+
url: `/api/assistants/${this.assistantId}/${threadId}/state`,
|
|
707
|
+
method: "GET"
|
|
708
|
+
});
|
|
709
|
+
} catch (error) {
|
|
710
|
+
throw error;
|
|
711
|
+
}
|
|
712
|
+
}
|
|
713
|
+
/**
|
|
714
|
+
* Gets agent graph visualization
|
|
715
|
+
* @returns A promise that resolves to the graph visualization data
|
|
716
|
+
*/
|
|
717
|
+
async getAgentGraph() {
|
|
718
|
+
try {
|
|
719
|
+
const response = await this.request({
|
|
720
|
+
url: `/api/assistants/${this.assistantId}/graph`,
|
|
721
|
+
method: "GET"
|
|
722
|
+
});
|
|
723
|
+
return response.image;
|
|
724
|
+
} catch (error) {
|
|
725
|
+
throw error;
|
|
726
|
+
}
|
|
727
|
+
}
|
|
728
|
+
/**
|
|
729
|
+
* Run agent with options
|
|
730
|
+
* @param options - Options for running the agent
|
|
731
|
+
* @returns A promise that resolves to the run result
|
|
732
|
+
*/
|
|
733
|
+
async run(options) {
|
|
734
|
+
try {
|
|
735
|
+
if (options.streaming) {
|
|
736
|
+
throw new Error(
|
|
737
|
+
"Streaming without callbacks is not supported. Use chat.stream with callbacks instead."
|
|
738
|
+
);
|
|
739
|
+
} else {
|
|
740
|
+
return await this.request({
|
|
741
|
+
url: "/api/runs",
|
|
742
|
+
method: "POST",
|
|
743
|
+
data: {
|
|
612
744
|
assistant_id: this.assistantId,
|
|
613
745
|
thread_id: options.threadId,
|
|
614
746
|
message: options.message,
|
|
615
747
|
files: options.files,
|
|
616
748
|
command: options.command,
|
|
617
749
|
streaming: false,
|
|
618
|
-
// We can't do true streaming in WeChat
|
|
619
750
|
background: options.background || false
|
|
620
|
-
}
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
751
|
+
}
|
|
752
|
+
});
|
|
753
|
+
}
|
|
754
|
+
} catch (error) {
|
|
755
|
+
throw error;
|
|
756
|
+
}
|
|
757
|
+
}
|
|
758
|
+
/**
|
|
759
|
+
* Stream run results using WeChat's downloadFile API
|
|
760
|
+
* @param options - Options for streaming run results
|
|
761
|
+
* @param onEvent - Callback function that receives stream events
|
|
762
|
+
* @param onComplete - Optional callback function called when streaming completes
|
|
763
|
+
* @param onError - Optional callback function called when an error occurs
|
|
764
|
+
* @returns A function that can be called to stop the stream
|
|
765
|
+
*/
|
|
766
|
+
streamRun(options, onEvent, onComplete, onError) {
|
|
767
|
+
const headers = {
|
|
768
|
+
"Content-Type": "application/json",
|
|
769
|
+
Authorization: `Bearer ${this.config.apiKey}`,
|
|
770
|
+
...this.config.headers
|
|
771
|
+
};
|
|
772
|
+
if (this.tenantId) {
|
|
773
|
+
headers["x-tenant-id"] = this.tenantId;
|
|
774
|
+
}
|
|
775
|
+
const taskId = wx.request({
|
|
776
|
+
url: `${this.config.baseURL}/api/runs`,
|
|
777
|
+
method: "POST",
|
|
778
|
+
data: {
|
|
779
|
+
assistant_id: this.assistantId,
|
|
780
|
+
thread_id: options.threadId,
|
|
781
|
+
message: options.message,
|
|
782
|
+
files: options.files,
|
|
783
|
+
command: options.command,
|
|
784
|
+
streaming: true,
|
|
785
|
+
background: options.background || false
|
|
786
|
+
},
|
|
787
|
+
header: headers,
|
|
788
|
+
responseType: "text",
|
|
789
|
+
enableChunked: true,
|
|
790
|
+
success: async () => {
|
|
791
|
+
},
|
|
792
|
+
fail: (err) => {
|
|
793
|
+
if (onError) {
|
|
794
|
+
onError(new Error(`Stream request failed: ${err.errMsg}`));
|
|
795
|
+
}
|
|
796
|
+
},
|
|
797
|
+
complete: async () => {
|
|
798
|
+
if (onComplete) {
|
|
799
|
+
if (options.enableReturnStateWhenSteamCompleted) {
|
|
800
|
+
try {
|
|
801
|
+
const state = await this.getAgentState(options.threadId);
|
|
802
|
+
onComplete(state);
|
|
803
|
+
} catch (error) {
|
|
804
|
+
onComplete();
|
|
638
805
|
}
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
806
|
+
} else {
|
|
807
|
+
onComplete();
|
|
808
|
+
}
|
|
809
|
+
}
|
|
810
|
+
},
|
|
811
|
+
// Using WeChat's chunked data capability
|
|
812
|
+
dataReceived: (res) => {
|
|
813
|
+
if (!res.data)
|
|
814
|
+
return;
|
|
815
|
+
const textDecoder = new TextDecoder();
|
|
816
|
+
const text = textDecoder.decode(res.data);
|
|
817
|
+
const lines = text.split("\n");
|
|
818
|
+
for (const line of lines) {
|
|
819
|
+
if (line.trim().startsWith("data: ")) {
|
|
820
|
+
try {
|
|
821
|
+
const eventData = JSON.parse(line.trim().slice(6));
|
|
822
|
+
onEvent(eventData);
|
|
823
|
+
} catch (error) {
|
|
824
|
+
if (onError) {
|
|
825
|
+
onError(
|
|
826
|
+
error instanceof Error ? error : new Error(String(error))
|
|
827
|
+
);
|
|
649
828
|
}
|
|
650
829
|
}
|
|
651
830
|
}
|
|
652
831
|
}
|
|
653
|
-
} catch (error) {
|
|
654
|
-
if (onError) {
|
|
655
|
-
onError(error instanceof Error ? error : new Error(String(error)));
|
|
656
|
-
}
|
|
657
|
-
isRunning = false;
|
|
658
832
|
}
|
|
659
|
-
};
|
|
660
|
-
poll();
|
|
833
|
+
});
|
|
661
834
|
return () => {
|
|
662
|
-
|
|
835
|
+
wx.abortRequest({
|
|
836
|
+
requestId: taskId,
|
|
837
|
+
success: () => console.log("Stream request aborted"),
|
|
838
|
+
fail: (err) => console.error("Failed to abort stream request:", err.errMsg)
|
|
839
|
+
});
|
|
663
840
|
};
|
|
664
841
|
}
|
|
665
842
|
};
|
|
@@ -861,6 +1038,7 @@ export {
|
|
|
861
1038
|
AuthenticationError,
|
|
862
1039
|
Client,
|
|
863
1040
|
NetworkError,
|
|
1041
|
+
WeChatClient,
|
|
864
1042
|
createSimpleMessageMerger
|
|
865
1043
|
};
|
|
866
1044
|
//# sourceMappingURL=index.mjs.map
|