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