@schmitech/chatbot-api 2.1.6 → 2.2.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/dist/api.mjs CHANGED
@@ -1,53 +1,88 @@
1
- var q = Object.defineProperty;
2
- var D = (l, t, e) => t in l ? q(l, t, { enumerable: !0, configurable: !0, writable: !0, value: e }) : l[t] = e;
3
- var g = (l, t, e) => D(l, typeof t != "symbol" ? t + "" : t, e);
4
- let $ = null, F = null;
1
+ var x = Object.defineProperty;
2
+ var M = (o, e, t) => e in o ? x(o, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : o[e] = t;
3
+ var g = (o, e, t) => M(o, typeof e != "symbol" ? e + "" : e, t);
4
+ let b = null, $ = null;
5
5
  typeof window > "u" && Promise.all([
6
6
  // @ts-expect-error - Dynamic import of Node.js built-in module (only available in Node.js runtime)
7
7
  import("http").catch(() => null),
8
8
  // @ts-expect-error - Dynamic import of Node.js built-in module (only available in Node.js runtime)
9
9
  import("https").catch(() => null)
10
- ]).then(([l, t]) => {
11
- var e, r;
12
- (e = l == null ? void 0 : l.default) != null && e.Agent ? $ = new l.default.Agent({ keepAlive: !0 }) : l != null && l.Agent && ($ = new l.Agent({ keepAlive: !0 })), (r = t == null ? void 0 : t.default) != null && r.Agent ? F = new t.default.Agent({ keepAlive: !0 }) : t != null && t.Agent && (F = new t.Agent({ keepAlive: !0 }));
13
- }).catch((l) => {
14
- console.warn("Failed to initialize HTTP agents:", l.message);
10
+ ]).then(([o, e]) => {
11
+ var t, s;
12
+ (t = o == null ? void 0 : o.default) != null && t.Agent ? b = new o.default.Agent({ keepAlive: !0 }) : o != null && o.Agent && (b = new o.Agent({ keepAlive: !0 })), (s = e == null ? void 0 : e.default) != null && s.Agent ? $ = new e.default.Agent({ keepAlive: !0 }) : e != null && e.Agent && ($ = new e.Agent({ keepAlive: !0 }));
13
+ }).catch((o) => {
14
+ console.warn("Failed to initialize HTTP agents:", o.message);
15
15
  });
16
- class j {
16
+ const T = "Could not connect to the server. Please check if the server is running.", J = 6e4, D = 1e6, H = 5e5;
17
+ class B {
17
18
  // Session ID can be mutable
18
- constructor(t) {
19
+ constructor(e) {
19
20
  g(this, "apiUrl");
20
21
  g(this, "apiKey");
21
22
  g(this, "adapterName");
22
23
  g(this, "middlewareBaseUrl");
23
24
  g(this, "middlewareMode");
24
25
  g(this, "sessionId");
25
- if (!t.apiUrl || typeof t.apiUrl != "string")
26
+ if (!e.apiUrl || typeof e.apiUrl != "string")
26
27
  throw new Error("API URL must be a valid string");
27
- if (t.apiKey !== void 0 && t.apiKey !== null && typeof t.apiKey != "string")
28
+ if (e.apiKey !== void 0 && e.apiKey !== null && typeof e.apiKey != "string")
28
29
  throw new Error("API key must be a valid string or null");
29
- if (t.sessionId !== void 0 && t.sessionId !== null && typeof t.sessionId != "string")
30
+ if (e.sessionId !== void 0 && e.sessionId !== null && typeof e.sessionId != "string")
30
31
  throw new Error("Session ID must be a valid string or null");
31
- if (t.adapterName !== void 0 && t.adapterName !== null && typeof t.adapterName != "string")
32
+ if (e.adapterName !== void 0 && e.adapterName !== null && typeof e.adapterName != "string")
32
33
  throw new Error("Adapter name must be a valid string or null");
33
- if (t.middlewareBaseUrl !== void 0 && t.middlewareBaseUrl !== null && typeof t.middlewareBaseUrl != "string")
34
+ if (e.middlewareBaseUrl !== void 0 && e.middlewareBaseUrl !== null && typeof e.middlewareBaseUrl != "string")
34
35
  throw new Error("Middleware base URL must be a valid string or null");
35
- this.apiUrl = t.apiUrl, this.apiKey = t.apiKey ?? null, this.sessionId = t.sessionId ?? null;
36
- const e = typeof t.adapterName == "string" ? t.adapterName.trim() : "";
37
- this.adapterName = e && e.length > 0 ? e : null;
38
- const r = typeof t.middlewareBaseUrl == "string" ? t.middlewareBaseUrl.trim() : "";
39
- this.middlewareBaseUrl = r.endsWith("/") ? r.slice(0, -1) : r;
40
- const s = t.useMiddleware ?? (!this.apiKey && !!this.adapterName);
41
- this.middlewareMode = !!(this.adapterName && s);
36
+ this.apiUrl = e.apiUrl, this.apiKey = e.apiKey ?? null, this.sessionId = e.sessionId ?? null;
37
+ const t = typeof e.adapterName == "string" ? e.adapterName.trim() : "";
38
+ this.adapterName = t && t.length > 0 ? t : null;
39
+ const s = typeof e.middlewareBaseUrl == "string" ? e.middlewareBaseUrl.trim() : "";
40
+ this.middlewareBaseUrl = s.endsWith("/") ? s.slice(0, -1) : s;
41
+ const i = e.useMiddleware ?? (!this.apiKey && !!this.adapterName);
42
+ this.middlewareMode = !!(this.adapterName && i);
42
43
  }
43
- setSessionId(t) {
44
- if (t !== null && typeof t != "string")
44
+ setSessionId(e) {
45
+ if (e !== null && typeof e != "string")
45
46
  throw new Error("Session ID must be a valid string or null");
46
- this.sessionId = t;
47
+ this.sessionId = e;
47
48
  }
48
49
  getSessionId() {
49
50
  return this.sessionId;
50
51
  }
52
+ hasFailedToFetch(e) {
53
+ var t;
54
+ return (e == null ? void 0 : e.name) === "TypeError" && ((t = e == null ? void 0 : e.message) == null ? void 0 : t.includes("Failed to fetch"));
55
+ }
56
+ rethrowNetworkError(e) {
57
+ if (this.hasFailedToFetch(e))
58
+ throw new Error(T);
59
+ }
60
+ async fetchWithNetworkErrorHandling(e, t) {
61
+ try {
62
+ return await fetch(e, t);
63
+ } catch (s) {
64
+ throw this.rethrowNetworkError(s), s;
65
+ }
66
+ }
67
+ async requestJsonOrThrow(e, t, s) {
68
+ try {
69
+ const i = await fetch(e, {
70
+ ...this.getFetchOptions(t)
71
+ });
72
+ if (!i.ok) {
73
+ const r = await i.text();
74
+ throw new Error(`${s}: ${i.status} ${r}`);
75
+ }
76
+ return await i.json();
77
+ } catch (i) {
78
+ throw this.rethrowNetworkError(i), i;
79
+ }
80
+ }
81
+ getRequiredApiKey(e) {
82
+ if (!this.apiKey)
83
+ throw new Error(e);
84
+ return this.apiKey;
85
+ }
51
86
  /**
52
87
  * Validate that the API key exists and is active.
53
88
  *
@@ -55,63 +90,59 @@ class j {
55
90
  * @throws Error if API key is not provided, invalid, inactive, or validation fails
56
91
  */
57
92
  async validateApiKey() {
58
- var t;
59
- if (!this.apiKey)
60
- throw new Error("API key is required for validation");
93
+ const e = this.getRequiredApiKey("API key is required for validation");
61
94
  try {
62
- const e = await fetch(`${this.apiUrl}/admin/api-keys/${this.apiKey}/status`, {
95
+ const t = await this.fetchWithNetworkErrorHandling(`${this.apiUrl}/admin/api-keys/${e}/status`, {
63
96
  ...this.getFetchOptions({
64
97
  method: "GET"
65
98
  })
66
- }).catch((s) => {
67
- throw s.name === "TypeError" && s.message.includes("Failed to fetch") ? new Error("Could not connect to the server. Please check if the server is running.") : s;
68
99
  });
69
- if (!e.ok) {
70
- let s = "";
100
+ if (!t.ok) {
101
+ let i = "";
71
102
  try {
72
- s = await e.text();
103
+ i = await t.text();
73
104
  } catch {
74
- s = `HTTP ${e.status}`;
105
+ i = `HTTP ${t.status}`;
75
106
  }
76
- let i, n;
107
+ let r, a;
77
108
  try {
78
- const o = JSON.parse(s);
79
- i = o.detail || o.message || s;
109
+ const d = JSON.parse(i);
110
+ r = d.detail || d.message || i;
80
111
  } catch {
81
- i = s || `HTTP ${e.status}`;
112
+ r = i || `HTTP ${t.status}`;
82
113
  }
83
- switch (e.status) {
114
+ switch (t.status) {
84
115
  case 401:
85
- n = "API key is invalid or expired";
116
+ a = "API key is invalid or expired";
86
117
  break;
87
118
  case 403:
88
- n = "Access denied: API key does not have required permissions";
119
+ a = "Access denied: API key does not have required permissions";
89
120
  break;
90
121
  case 404:
91
- n = "API key not found";
122
+ a = "API key not found";
92
123
  break;
93
124
  case 503:
94
- n = "API key management is not available in inference-only mode";
125
+ a = "API key management is not available in inference-only mode";
95
126
  break;
96
127
  default:
97
- n = `Failed to validate API key: ${i}`;
128
+ a = `Failed to validate API key: ${r}`;
98
129
  break;
99
130
  }
100
- throw new Error(n);
131
+ throw new Error(a);
101
132
  }
102
- const r = await e.json();
103
- if (!r.exists) {
104
- const s = "API key does not exist";
105
- throw new Error(s);
133
+ const s = await t.json();
134
+ if (!s.exists) {
135
+ const i = "API key does not exist";
136
+ throw new Error(i);
106
137
  }
107
- if (!r.active) {
108
- const s = "API key is inactive";
109
- throw new Error(s);
138
+ if (!s.active) {
139
+ const i = "API key is inactive";
140
+ throw new Error(i);
110
141
  }
111
- return r;
112
- } catch (e) {
113
- let r;
114
- throw e instanceof Error && e.message ? e.message.includes("API key") || e.message.includes("Access denied") || e.message.includes("invalid") || e.message.includes("expired") || e.message.includes("inactive") || e.message.includes("not found") || e.message.includes("Could not connect") ? r = e.message : r = `API key validation failed: ${e.message}` : e.name === "TypeError" && ((t = e.message) != null && t.includes("Failed to fetch")) ? r = "Could not connect to the server. Please check if the server is running." : r = "API key validation failed. Please check your API key and try again.", console.warn(`[ApiClient] ${r}`), new Error(r);
142
+ return s;
143
+ } catch (t) {
144
+ let s;
145
+ throw t instanceof Error && t.message ? t.message.includes("API key") || t.message.includes("Access denied") || t.message.includes("invalid") || t.message.includes("expired") || t.message.includes("inactive") || t.message.includes("not found") || t.message.includes("Could not connect") ? s = t.message : s = `API key validation failed: ${t.message}` : this.hasFailedToFetch(t) ? s = T : s = "API key validation failed. Please check your API key and try again.", console.warn(`[ApiClient] ${s}`), new Error(s);
115
146
  }
116
147
  }
117
148
  /**
@@ -124,16 +155,12 @@ class j {
124
155
  * @throws Error if API key is not provided, invalid, disabled, or request fails
125
156
  */
126
157
  async getAdapterInfo() {
127
- var t;
128
- if (!this.apiKey)
129
- throw new Error("API key is required to get adapter information");
158
+ this.getRequiredApiKey("API key is required to get adapter information");
130
159
  try {
131
- const e = await fetch(`${this.apiUrl}/admin/adapters/info`, {
160
+ const e = await this.fetchWithNetworkErrorHandling(`${this.apiUrl}/admin/adapters/info`, {
132
161
  ...this.getFetchOptions({
133
162
  method: "GET"
134
163
  })
135
- }).catch((s) => {
136
- throw s.name === "TypeError" && s.message.includes("Failed to fetch") ? new Error("Could not connect to the server. Please check if the server is running.") : s;
137
164
  });
138
165
  if (!e.ok) {
139
166
  let s = "";
@@ -142,33 +169,33 @@ class j {
142
169
  } catch {
143
170
  s = `HTTP ${e.status}`;
144
171
  }
145
- let i, n;
172
+ let i, r;
146
173
  try {
147
- const o = JSON.parse(s);
148
- i = o.detail || o.message || s;
174
+ const a = JSON.parse(s);
175
+ i = a.detail || a.message || s;
149
176
  } catch {
150
177
  i = s || `HTTP ${e.status}`;
151
178
  }
152
179
  switch (e.status) {
153
180
  case 401:
154
- n = "API key is invalid, disabled, or has no associated adapter";
181
+ r = "API key is invalid, disabled, or has no associated adapter";
155
182
  break;
156
183
  case 404:
157
- n = "Adapter configuration not found";
184
+ r = "Adapter configuration not found";
158
185
  break;
159
186
  case 503:
160
- n = "Service is not available";
187
+ r = "Service is not available";
161
188
  break;
162
189
  default:
163
- n = `Failed to get adapter info: ${i}`;
190
+ r = `Failed to get adapter info: ${i}`;
164
191
  break;
165
192
  }
166
- throw new Error(n);
193
+ throw new Error(r);
167
194
  }
168
195
  return await e.json();
169
196
  } catch (e) {
170
- let r;
171
- throw e instanceof Error && e.message ? e.message.includes("API key") || e.message.includes("Adapter") || e.message.includes("invalid") || e.message.includes("disabled") || e.message.includes("not found") || e.message.includes("Could not connect") ? r = e.message : r = `Failed to get adapter info: ${e.message}` : e.name === "TypeError" && ((t = e.message) != null && t.includes("Failed to fetch")) ? r = "Could not connect to the server. Please check if the server is running." : r = "Failed to get adapter information. Please try again.", console.warn(`[ApiClient] ${r}`), new Error(r);
197
+ let t;
198
+ throw e instanceof Error && e.message ? e.message.includes("API key") || e.message.includes("Adapter") || e.message.includes("invalid") || e.message.includes("disabled") || e.message.includes("not found") || e.message.includes("Could not connect") ? t = e.message : t = `Failed to get adapter info: ${e.message}` : this.hasFailedToFetch(e) ? t = T : t = "Failed to get adapter information. Please try again.", console.warn(`[ApiClient] ${t}`), new Error(t);
172
199
  }
173
200
  }
174
201
  /**
@@ -181,192 +208,192 @@ class j {
181
208
  * @param limit - Maximum number of suggestions (default: 5)
182
209
  * @returns Promise resolving to autocomplete suggestions
183
210
  */
184
- async getAutocompleteSuggestions(t, e = 5) {
185
- if (t.length < 3)
186
- return { suggestions: [], query: t };
187
- const r = this.middlewareMode && !!this.adapterName;
188
- if (!r && !this.apiKey)
189
- return { suggestions: [], query: t };
211
+ async getAutocompleteSuggestions(e, t = 5) {
212
+ if (e.length < 3)
213
+ return { suggestions: [], query: e };
214
+ const s = this.middlewareMode && !!this.adapterName;
215
+ if (!s && !this.apiKey)
216
+ return { suggestions: [], query: e };
190
217
  try {
191
- const s = new URLSearchParams();
192
- s.set("q", t), s.set("limit", String(e));
193
- let i, n;
194
- if (r) {
218
+ const i = new URLSearchParams();
219
+ i.set("q", e), i.set("limit", String(t));
220
+ let r, a;
221
+ if (s) {
195
222
  if (!this.middlewareBaseUrl && typeof window > "u")
196
223
  throw new Error("middlewareBaseUrl must be set when using middleware outside the browser environment.");
197
- i = `${this.middlewareBaseUrl ? this.middlewareBaseUrl : ""}/api/v1/autocomplete?${s.toString()}`;
198
- const f = {
224
+ r = `${this.middlewareBaseUrl ? this.middlewareBaseUrl : ""}/api/v1/autocomplete?${i.toString()}`;
225
+ const u = {
199
226
  "X-Adapter-Name": this.adapterName,
200
227
  "X-Request-ID": Date.now().toString(36) + Math.random().toString(36).substring(2)
201
228
  };
202
- this.sessionId && (f["X-Session-ID"] = this.sessionId), n = {
229
+ this.sessionId && (u["X-Session-ID"] = this.sessionId), a = {
203
230
  method: "GET",
204
- headers: f
231
+ headers: u
205
232
  };
206
233
  } else {
207
- const d = new URL(`${this.apiUrl}/v1/autocomplete`);
208
- d.searchParams.set("q", t), d.searchParams.set("limit", String(e)), i = d.toString(), n = {
234
+ const l = new URL(`${this.apiUrl}/v1/autocomplete`);
235
+ l.searchParams.set("q", e), l.searchParams.set("limit", String(t)), r = l.toString(), a = {
209
236
  ...this.getFetchOptions({
210
237
  method: "GET"
211
238
  })
212
239
  };
213
240
  }
214
- const o = await fetch(i, n);
215
- return o.ok ? await o.json() : (console.warn("[ApiClient] Autocomplete request failed:", o.status), { suggestions: [], query: t });
216
- } catch (s) {
217
- return console.warn("[ApiClient] Autocomplete error:", s.message), { suggestions: [], query: t };
241
+ const d = await fetch(r, a);
242
+ return d.ok ? await d.json() : (console.warn("[ApiClient] Autocomplete request failed:", d.status), { suggestions: [], query: e });
243
+ } catch (i) {
244
+ return console.warn("[ApiClient] Autocomplete error:", i.message), { suggestions: [], query: e };
218
245
  }
219
246
  }
220
247
  // Helper to get fetch options with connection pooling if available
221
- getFetchOptions(t = {}) {
222
- const e = {};
248
+ getFetchOptions(e = {}) {
249
+ const t = {};
223
250
  if (typeof window > "u") {
224
- const i = this.apiUrl.startsWith("https:") ? F : $;
225
- i && (e.agent = i);
251
+ const r = this.apiUrl.startsWith("https:") ? $ : b;
252
+ r && (t.agent = r);
226
253
  } else
227
- e.headers = { Connection: "keep-alive" };
228
- const r = {
254
+ t.headers = { Connection: "keep-alive" };
255
+ const s = {
229
256
  "X-Request-ID": Date.now().toString(36) + Math.random().toString(36).substring(2)
230
257
  };
231
- if (e.headers && Object.assign(r, e.headers), t.headers) {
232
- const s = t.headers;
233
- for (const [i, n] of Object.entries(s))
234
- (i.toLowerCase() !== "x-api-key" || !this.apiKey) && (r[i] = n);
258
+ if (t.headers && Object.assign(s, t.headers), e.headers) {
259
+ const i = e.headers;
260
+ for (const [r, a] of Object.entries(i))
261
+ (r.toLowerCase() !== "x-api-key" || !this.apiKey) && (s[r] = a);
235
262
  }
236
- return this.apiKey && (r["X-API-Key"] = this.apiKey), this.sessionId && (r["X-Session-ID"] = this.sessionId), {
237
- ...t,
263
+ return this.apiKey && (s["X-API-Key"] = this.apiKey), this.sessionId && (s["X-Session-ID"] = this.sessionId), {
238
264
  ...e,
239
- headers: r
265
+ ...t,
266
+ headers: s
240
267
  };
241
268
  }
242
269
  // Create Chat request
243
- createChatRequest(t, e = !0, r, s, i, n, o, d, u, f, m) {
270
+ createChatRequest(e, t = !0, s, i, r, a, d, l, w, u, m) {
244
271
  const c = {
245
272
  messages: [
246
- { role: "user", content: t }
273
+ { role: "user", content: e }
247
274
  ],
248
- stream: e
275
+ stream: t
249
276
  };
250
- return r && r.length > 0 && (c.file_ids = r), s && (c.thread_id = s), i && (c.audio_input = i), n && (c.audio_format = n), o && (c.language = o), d !== void 0 && (c.return_audio = d), u && (c.tts_voice = u), f && (c.source_language = f), m && (c.target_language = m), c;
277
+ return s && s.length > 0 && (c.file_ids = s), i && (c.thread_id = i), r && (c.audio_input = r), a && (c.audio_format = a), d && (c.language = d), l !== void 0 && (c.return_audio = l), w && (c.tts_voice = w), u && (c.source_language = u), m && (c.target_language = m), c;
251
278
  }
252
- async *streamChat(t, e = !0, r, s, i, n, o, d, u, f, m, c) {
253
- var C, b, x;
279
+ async *streamChat(e, t = !0, s, i, r, a, d, l, w, u, m, c) {
280
+ var q, U, K;
254
281
  try {
255
- const w = new AbortController(), K = setTimeout(() => w.abort(), 6e4);
256
- c && c.addEventListener("abort", () => w.abort());
257
- const v = await fetch(`${this.apiUrl}/v1/chat`, {
282
+ const y = new AbortController(), S = setTimeout(() => y.abort(), J);
283
+ c && c.addEventListener("abort", () => y.abort());
284
+ const A = await fetch(`${this.apiUrl}/v1/chat`, {
258
285
  ...this.getFetchOptions({
259
286
  method: "POST",
260
287
  headers: {
261
288
  "Content-Type": "application/json",
262
- Accept: e ? "text/event-stream" : "application/json"
289
+ Accept: t ? "text/event-stream" : "application/json"
263
290
  },
264
291
  body: JSON.stringify(this.createChatRequest(
265
- t,
266
292
  e,
267
- r,
293
+ t,
268
294
  s,
269
295
  i,
270
- n,
271
- o,
296
+ r,
297
+ a,
272
298
  d,
299
+ l,
300
+ w,
273
301
  u,
274
- f,
275
302
  m
276
303
  ))
277
304
  }),
278
- signal: w.signal
305
+ signal: y.signal
279
306
  });
280
- if (clearTimeout(K), !v.ok) {
281
- const y = await v.text();
282
- throw new Error(`Network response was not ok: ${v.status} ${y}`);
307
+ if (clearTimeout(S), !A.ok) {
308
+ const f = await A.text();
309
+ throw new Error(`Network response was not ok: ${A.status} ${f}`);
283
310
  }
284
- if (!e) {
285
- const y = await v.json();
286
- y.response && (yield {
287
- text: y.response,
311
+ if (!t) {
312
+ const f = await A.json();
313
+ f.response && (yield {
314
+ text: f.response,
288
315
  done: !0,
289
- audio: y.audio,
290
- audioFormat: y.audio_format
316
+ audio: f.audio,
317
+ audioFormat: f.audio_format
291
318
  });
292
319
  return;
293
320
  }
294
- const I = (C = v.body) == null ? void 0 : C.getReader();
295
- if (!I) throw new Error("No reader available");
296
- const S = new TextDecoder();
297
- let p = "", A = !1;
321
+ const P = (q = A.body) == null ? void 0 : q.getReader();
322
+ if (!P) throw new Error("No reader available");
323
+ const N = new TextDecoder();
324
+ let p = "", E = !1;
298
325
  try {
299
326
  for (; ; ) {
300
- const { done: y, value: N } = await I.read();
301
- if (y)
327
+ const { done: f, value: _ } = await P.read();
328
+ if (f)
302
329
  break;
303
- const _ = S.decode(N, { stream: !0 });
304
- p += _;
305
- let P = 0, T;
306
- for (; (T = p.indexOf(`
307
- `, P)) !== -1; ) {
308
- const E = p.slice(P, T).trim();
309
- if (P = T + 1, E && E.startsWith("data: ")) {
310
- const h = E.slice(6).trim();
330
+ const R = N.decode(_, { stream: !0 });
331
+ p += R;
332
+ let k = 0, F;
333
+ for (; (F = p.indexOf(`
334
+ `, k)) !== -1; ) {
335
+ const I = p.slice(k, F).trim();
336
+ if (k = F + 1, I && I.startsWith("data: ")) {
337
+ const h = I.slice(6).trim();
311
338
  if (!h || h === "[DONE]") {
312
339
  yield { text: "", done: !0 };
313
340
  return;
314
341
  }
315
342
  try {
316
- const a = JSON.parse(h);
317
- if (a.error) {
318
- const O = `Server error: ${((b = a.error) == null ? void 0 : b.message) || a.error || "Unknown server error"}`;
319
- throw console.warn(`[ApiClient] ${O}`), new Error(O);
343
+ const n = JSON.parse(h);
344
+ if (n.error) {
345
+ const C = `Server error: ${((U = n.error) == null ? void 0 : U.message) || n.error || "Unknown server error"}`;
346
+ throw console.warn(`[ApiClient] ${C}`), new Error(C);
320
347
  }
321
- if (a.request_id && !a.response && !a.done) {
348
+ if (n.request_id && !n.response && !n.done) {
322
349
  yield {
323
350
  text: "",
324
351
  done: !1,
325
- request_id: a.request_id
352
+ request_id: n.request_id
326
353
  };
327
354
  continue;
328
355
  }
329
- if (a.done === !0) {
330
- A = !0, yield {
356
+ if (n.done === !0) {
357
+ E = !0, yield {
331
358
  text: "",
332
359
  done: !0,
333
- audio: a.audio,
334
- audioFormat: a.audio_format || a.audioFormat,
335
- threading: a.threading
360
+ audio: n.audio,
361
+ audioFormat: n.audio_format || n.audioFormat,
362
+ threading: n.threading
336
363
  // Pass through threading metadata
337
364
  };
338
365
  return;
339
366
  }
340
- const U = a.response || "";
341
- a.audio_chunk !== void 0 && (yield {
367
+ const O = n.response || "";
368
+ n.audio_chunk !== void 0 && (yield {
342
369
  text: "",
343
370
  done: !1,
344
- audio_chunk: a.audio_chunk,
345
- audioFormat: a.audioFormat || a.audio_format || "opus",
346
- chunk_index: a.chunk_index ?? 0
347
- }), (U || a.audio) && (A = !0, yield {
348
- text: U,
349
- done: a.done || !1,
350
- audio: a.audio,
351
- audioFormat: a.audio_format || a.audioFormat,
352
- threading: a.threading
371
+ audio_chunk: n.audio_chunk,
372
+ audioFormat: n.audioFormat || n.audio_format || "opus",
373
+ chunk_index: n.chunk_index ?? 0
374
+ }), (O || n.audio) && (E = !0, yield {
375
+ text: O,
376
+ done: n.done || !1,
377
+ audio: n.audio,
378
+ audioFormat: n.audio_format || n.audioFormat,
379
+ threading: n.threading
353
380
  // Include threading if present
354
381
  });
355
- } catch (a) {
356
- if ((x = a == null ? void 0 : a.message) != null && x.startsWith("Server error:"))
357
- throw a;
358
- console.warn("[ApiClient] Unable to parse server response. This may be a temporary issue."), console.warn("[ApiClient] Parse error details:", a == null ? void 0 : a.message), console.warn("[ApiClient] JSON text length:", h == null ? void 0 : h.length), console.warn("[ApiClient] JSON text preview (first 200 chars):", h == null ? void 0 : h.substring(0, 200)), console.warn("[ApiClient] JSON text preview (last 200 chars):", h == null ? void 0 : h.substring(h.length - 200));
382
+ } catch (n) {
383
+ if ((K = n == null ? void 0 : n.message) != null && K.startsWith("Server error:"))
384
+ throw n;
385
+ console.warn("[ApiClient] Unable to parse server response. This may be a temporary issue."), console.warn("[ApiClient] Parse error details:", n == null ? void 0 : n.message), console.warn("[ApiClient] JSON text length:", h == null ? void 0 : h.length), console.warn("[ApiClient] JSON text preview (first 200 chars):", h == null ? void 0 : h.substring(0, 200)), console.warn("[ApiClient] JSON text preview (last 200 chars):", h == null ? void 0 : h.substring(h.length - 200));
359
386
  }
360
- } else E && (A = !0, yield { text: E, done: !1 });
387
+ } else I && (E = !0, yield { text: I, done: !1 });
361
388
  }
362
- p = p.slice(P), p.length > 1e6 && (console.warn("[ApiClient] Buffer too large, truncating..."), p = p.slice(-5e5));
389
+ p = p.slice(k), p.length > D && (console.warn("[ApiClient] Buffer too large, truncating..."), p = p.slice(-H));
363
390
  }
364
- A && (yield { text: "", done: !0 });
391
+ E && (yield { text: "", done: !0 });
365
392
  } finally {
366
- I.releaseLock();
393
+ P.releaseLock();
367
394
  }
368
- } catch (w) {
369
- throw w.name === "AbortError" ? c != null && c.aborted ? new Error("Stream cancelled by user") : new Error("Connection timed out. Please check if the server is running.") : w.name === "TypeError" && w.message.includes("Failed to fetch") ? new Error("Could not connect to the server. Please check if the server is running.") : w;
395
+ } catch (y) {
396
+ throw y.name === "AbortError" ? c != null && c.aborted ? new Error("Stream cancelled by user") : new Error("Connection timed out. Please check if the server is running.") : this.hasFailedToFetch(y) ? new Error(T) : y;
370
397
  }
371
398
  }
372
399
  /**
@@ -376,107 +403,82 @@ class j {
376
403
  * @param requestId - The request identifier (from first stream chunk)
377
404
  * @returns Promise resolving to true if stream was cancelled, false otherwise
378
405
  */
379
- async stopChat(t, e) {
406
+ async stopChat(e, t) {
380
407
  try {
381
- const r = await fetch(`${this.apiUrl}/v1/chat/stop`, {
408
+ const s = await fetch(`${this.apiUrl}/v1/chat/stop`, {
382
409
  ...this.getFetchOptions({
383
410
  method: "POST",
384
411
  headers: {
385
412
  "Content-Type": "application/json"
386
413
  },
387
414
  body: JSON.stringify({
388
- session_id: t,
389
- request_id: e
415
+ session_id: e,
416
+ request_id: t
390
417
  })
391
418
  })
392
419
  });
393
- return r.ok ? (await r.json()).status === "cancelled" : (console.warn("[ApiClient] Failed to stop stream:", r.status), !1);
394
- } catch (r) {
395
- return console.error("[ApiClient] Error stopping stream:", r), !1;
420
+ return s.ok ? (await s.json()).status === "cancelled" : (console.warn("[ApiClient] Failed to stop stream:", s.status), !1);
421
+ } catch (s) {
422
+ return console.error("[ApiClient] Error stopping stream:", s), !1;
396
423
  }
397
424
  }
398
- async getConversationHistory(t, e) {
399
- const r = t || this.sessionId;
400
- if (!r)
425
+ async getConversationHistory(e, t) {
426
+ const s = e || this.sessionId;
427
+ if (!s)
401
428
  throw new Error("No session ID provided and no current session available");
402
- const s = {};
403
- this.apiKey && (s["X-API-Key"] = this.apiKey);
404
- try {
405
- const i = new URL(`${this.apiUrl}/admin/chat-history/${r}`);
406
- typeof e == "number" && Number.isFinite(e) && e > 0 && i.searchParams.set("limit", String(Math.floor(e)));
407
- const n = await fetch(i.toString(), {
408
- ...this.getFetchOptions({
409
- method: "GET",
410
- headers: s
411
- })
412
- });
413
- if (!n.ok) {
414
- const f = await n.text();
415
- throw new Error(`Failed to fetch conversation history: ${n.status} ${f}`);
416
- }
417
- const o = await n.json(), d = Array.isArray(o == null ? void 0 : o.messages) ? o.messages : [], u = typeof (o == null ? void 0 : o.count) == "number" ? o.count : d.length;
418
- return {
419
- session_id: (o == null ? void 0 : o.session_id) || r,
420
- messages: d,
421
- count: u
422
- };
423
- } catch (i) {
424
- throw i.name === "TypeError" && i.message.includes("Failed to fetch") ? new Error("Could not connect to the server. Please check if the server is running.") : i;
425
- }
429
+ const i = {};
430
+ this.apiKey && (i["X-API-Key"] = this.apiKey);
431
+ const r = new URL(`${this.apiUrl}/admin/chat-history/${s}`);
432
+ typeof t == "number" && Number.isFinite(t) && t > 0 && r.searchParams.set("limit", String(Math.floor(t)));
433
+ const a = await this.requestJsonOrThrow(
434
+ r.toString(),
435
+ {
436
+ method: "GET",
437
+ headers: i
438
+ },
439
+ "Failed to fetch conversation history"
440
+ ), d = Array.isArray(a == null ? void 0 : a.messages) ? a.messages : [], l = typeof (a == null ? void 0 : a.count) == "number" ? a.count : d.length;
441
+ return {
442
+ session_id: (a == null ? void 0 : a.session_id) || s,
443
+ messages: d,
444
+ count: l
445
+ };
426
446
  }
427
- async clearConversationHistory(t) {
428
- const e = t || this.sessionId;
429
- if (!e)
447
+ async clearConversationHistory(e) {
448
+ const t = e || this.sessionId;
449
+ if (!t)
430
450
  throw new Error("No session ID provided and no current session available");
431
- if (!this.apiKey)
432
- throw new Error("API key is required for clearing conversation history");
433
- const r = {
451
+ const s = this.getRequiredApiKey("API key is required for clearing conversation history"), i = {
434
452
  "Content-Type": "application/json",
435
- "X-Session-ID": e,
436
- "X-API-Key": this.apiKey
453
+ "X-Session-ID": t,
454
+ "X-API-Key": s
437
455
  };
438
- try {
439
- const s = await fetch(`${this.apiUrl}/admin/chat-history/${e}`, {
440
- ...this.getFetchOptions({
441
- method: "DELETE",
442
- headers: r
443
- })
444
- });
445
- if (!s.ok) {
446
- const n = await s.text();
447
- throw new Error(`Failed to clear conversation history: ${s.status} ${n}`);
448
- }
449
- return await s.json();
450
- } catch (s) {
451
- throw s.name === "TypeError" && s.message.includes("Failed to fetch") ? new Error("Could not connect to the server. Please check if the server is running.") : s;
452
- }
456
+ return await this.requestJsonOrThrow(
457
+ `${this.apiUrl}/admin/chat-history/${t}`,
458
+ {
459
+ method: "DELETE",
460
+ headers: i
461
+ },
462
+ "Failed to clear conversation history"
463
+ );
453
464
  }
454
- async deleteConversationWithFiles(t, e) {
455
- const r = t || this.sessionId;
456
- if (!r)
465
+ async deleteConversationWithFiles(e, t) {
466
+ const s = e || this.sessionId;
467
+ if (!s)
457
468
  throw new Error("No session ID provided and no current session available");
458
- if (!this.apiKey)
459
- throw new Error("API key is required for deleting conversation");
460
- const s = {
469
+ const i = this.getRequiredApiKey("API key is required for deleting conversation"), r = {
461
470
  "Content-Type": "application/json",
462
- "X-Session-ID": r,
463
- "X-API-Key": this.apiKey
464
- }, i = e && e.length > 0 ? `?file_ids=${e.join(",")}` : "", n = `${this.apiUrl}/admin/conversations/${r}${i}`;
465
- try {
466
- const o = await fetch(n, {
467
- ...this.getFetchOptions({
468
- method: "DELETE",
469
- headers: s
470
- })
471
- });
472
- if (!o.ok) {
473
- const u = await o.text();
474
- throw new Error(`Failed to delete conversation: ${o.status} ${u}`);
475
- }
476
- return await o.json();
477
- } catch (o) {
478
- throw o.name === "TypeError" && o.message.includes("Failed to fetch") ? new Error("Could not connect to the server. Please check if the server is running.") : o;
479
- }
471
+ "X-Session-ID": s,
472
+ "X-API-Key": i
473
+ }, a = t && t.length > 0 ? `?file_ids=${t.join(",")}` : "", d = `${this.apiUrl}/admin/conversations/${s}${a}`;
474
+ return await this.requestJsonOrThrow(
475
+ d,
476
+ {
477
+ method: "DELETE",
478
+ headers: r
479
+ },
480
+ "Failed to delete conversation"
481
+ );
480
482
  }
481
483
  /**
482
484
  * Create a conversation thread from a parent message.
@@ -486,32 +488,23 @@ class j {
486
488
  * @returns Promise resolving to thread information
487
489
  * @throws Error if the operation fails
488
490
  */
489
- async createThread(t, e) {
490
- if (!this.apiKey)
491
- throw new Error("API key is required for creating threads");
492
- const r = {
491
+ async createThread(e, t) {
492
+ const i = {
493
493
  "Content-Type": "application/json",
494
- "X-API-Key": this.apiKey
494
+ "X-API-Key": this.getRequiredApiKey("API key is required for creating threads")
495
495
  };
496
- try {
497
- const s = await fetch(`${this.apiUrl}/api/threads`, {
498
- ...this.getFetchOptions({
499
- method: "POST",
500
- headers: r,
501
- body: JSON.stringify({
502
- message_id: t,
503
- session_id: e
504
- })
496
+ return await this.requestJsonOrThrow(
497
+ `${this.apiUrl}/api/threads`,
498
+ {
499
+ method: "POST",
500
+ headers: i,
501
+ body: JSON.stringify({
502
+ message_id: e,
503
+ session_id: t
505
504
  })
506
- });
507
- if (!s.ok) {
508
- const n = await s.text();
509
- throw new Error(`Failed to create thread: ${s.status} ${n}`);
510
- }
511
- return await s.json();
512
- } catch (s) {
513
- throw s.name === "TypeError" && s.message.includes("Failed to fetch") ? new Error("Could not connect to the server. Please check if the server is running.") : s;
514
- }
505
+ },
506
+ "Failed to create thread"
507
+ );
515
508
  }
516
509
  /**
517
510
  * Get thread information by thread ID.
@@ -520,27 +513,18 @@ class j {
520
513
  * @returns Promise resolving to thread information
521
514
  * @throws Error if the operation fails
522
515
  */
523
- async getThreadInfo(t) {
524
- if (!this.apiKey)
525
- throw new Error("API key is required for getting thread info");
526
- const e = {
527
- "X-API-Key": this.apiKey
516
+ async getThreadInfo(e) {
517
+ const s = {
518
+ "X-API-Key": this.getRequiredApiKey("API key is required for getting thread info")
528
519
  };
529
- try {
530
- const r = await fetch(`${this.apiUrl}/api/threads/${t}`, {
531
- ...this.getFetchOptions({
532
- method: "GET",
533
- headers: e
534
- })
535
- });
536
- if (!r.ok) {
537
- const i = await r.text();
538
- throw new Error(`Failed to get thread info: ${r.status} ${i}`);
539
- }
540
- return await r.json();
541
- } catch (r) {
542
- throw r.name === "TypeError" && r.message.includes("Failed to fetch") ? new Error("Could not connect to the server. Please check if the server is running.") : r;
543
- }
520
+ return await this.requestJsonOrThrow(
521
+ `${this.apiUrl}/api/threads/${e}`,
522
+ {
523
+ method: "GET",
524
+ headers: s
525
+ },
526
+ "Failed to get thread info"
527
+ );
544
528
  }
545
529
  /**
546
530
  * Delete a thread and its associated dataset.
@@ -549,27 +533,18 @@ class j {
549
533
  * @returns Promise resolving to deletion result
550
534
  * @throws Error if the operation fails
551
535
  */
552
- async deleteThread(t) {
553
- if (!this.apiKey)
554
- throw new Error("API key is required for deleting threads");
555
- const e = {
556
- "X-API-Key": this.apiKey
536
+ async deleteThread(e) {
537
+ const s = {
538
+ "X-API-Key": this.getRequiredApiKey("API key is required for deleting threads")
557
539
  };
558
- try {
559
- const r = await fetch(`${this.apiUrl}/api/threads/${t}`, {
560
- ...this.getFetchOptions({
561
- method: "DELETE",
562
- headers: e
563
- })
564
- });
565
- if (!r.ok) {
566
- const i = await r.text();
567
- throw new Error(`Failed to delete thread: ${r.status} ${i}`);
568
- }
569
- return await r.json();
570
- } catch (r) {
571
- throw r.name === "TypeError" && r.message.includes("Failed to fetch") ? new Error("Could not connect to the server. Please check if the server is running.") : r;
572
- }
540
+ return await this.requestJsonOrThrow(
541
+ `${this.apiUrl}/api/threads/${e}`,
542
+ {
543
+ method: "DELETE",
544
+ headers: s
545
+ },
546
+ "Failed to delete thread"
547
+ );
573
548
  }
574
549
  /**
575
550
  * Upload a file for processing and indexing.
@@ -578,26 +553,17 @@ class j {
578
553
  * @returns Promise resolving to upload response with file_id
579
554
  * @throws Error if upload fails
580
555
  */
581
- async uploadFile(t) {
582
- if (!this.apiKey)
583
- throw new Error("API key is required for file upload");
584
- const e = new FormData();
585
- e.append("file", t);
586
- try {
587
- const r = await fetch(`${this.apiUrl}/api/files/upload`, {
588
- ...this.getFetchOptions({
589
- method: "POST",
590
- body: e
591
- })
592
- });
593
- if (!r.ok) {
594
- const s = await r.text();
595
- throw new Error(`Failed to upload file: ${r.status} ${s}`);
596
- }
597
- return await r.json();
598
- } catch (r) {
599
- throw r.name === "TypeError" && r.message.includes("Failed to fetch") ? new Error("Could not connect to the server. Please check if the server is running.") : r;
600
- }
556
+ async uploadFile(e) {
557
+ this.getRequiredApiKey("API key is required for file upload");
558
+ const t = new FormData();
559
+ return t.append("file", e), await this.requestJsonOrThrow(
560
+ `${this.apiUrl}/api/files/upload`,
561
+ {
562
+ method: "POST",
563
+ body: t
564
+ },
565
+ "Failed to upload file"
566
+ );
601
567
  }
602
568
  /**
603
569
  * List all files for the current API key.
@@ -606,22 +572,13 @@ class j {
606
572
  * @throws Error if request fails
607
573
  */
608
574
  async listFiles() {
609
- if (!this.apiKey)
610
- throw new Error("API key is required for listing files");
611
- try {
612
- const t = await fetch(`${this.apiUrl}/api/files`, {
613
- ...this.getFetchOptions({
614
- method: "GET"
615
- })
616
- });
617
- if (!t.ok) {
618
- const e = await t.text();
619
- throw new Error(`Failed to list files: ${t.status} ${e}`);
620
- }
621
- return await t.json();
622
- } catch (t) {
623
- throw t.name === "TypeError" && t.message.includes("Failed to fetch") ? new Error("Could not connect to the server. Please check if the server is running.") : t;
624
- }
575
+ return this.getRequiredApiKey("API key is required for listing files"), await this.requestJsonOrThrow(
576
+ `${this.apiUrl}/api/files`,
577
+ {
578
+ method: "GET"
579
+ },
580
+ "Failed to list files"
581
+ );
625
582
  }
626
583
  /**
627
584
  * Get information about a specific file.
@@ -630,23 +587,14 @@ class j {
630
587
  * @returns Promise resolving to file information
631
588
  * @throws Error if file not found or request fails
632
589
  */
633
- async getFileInfo(t) {
634
- if (!this.apiKey)
635
- throw new Error("API key is required for getting file info");
636
- try {
637
- const e = await fetch(`${this.apiUrl}/api/files/${t}`, {
638
- ...this.getFetchOptions({
639
- method: "GET"
640
- })
641
- });
642
- if (!e.ok) {
643
- const r = await e.text();
644
- throw new Error(`Failed to get file info: ${e.status} ${r}`);
645
- }
646
- return await e.json();
647
- } catch (e) {
648
- throw e.name === "TypeError" && e.message.includes("Failed to fetch") ? new Error("Could not connect to the server. Please check if the server is running.") : e;
649
- }
590
+ async getFileInfo(e) {
591
+ return this.getRequiredApiKey("API key is required for getting file info"), await this.requestJsonOrThrow(
592
+ `${this.apiUrl}/api/files/${e}`,
593
+ {
594
+ method: "GET"
595
+ },
596
+ "Failed to get file info"
597
+ );
650
598
  }
651
599
  /**
652
600
  * Query a specific file using semantic search.
@@ -657,27 +605,18 @@ class j {
657
605
  * @returns Promise resolving to query results
658
606
  * @throws Error if query fails
659
607
  */
660
- async queryFile(t, e, r = 10) {
661
- if (!this.apiKey)
662
- throw new Error("API key is required for querying files");
663
- try {
664
- const s = await fetch(`${this.apiUrl}/api/files/${t}/query`, {
665
- ...this.getFetchOptions({
666
- method: "POST",
667
- headers: {
668
- "Content-Type": "application/json"
669
- },
670
- body: JSON.stringify({ query: e, max_results: r })
671
- })
672
- });
673
- if (!s.ok) {
674
- const i = await s.text();
675
- throw new Error(`Failed to query file: ${s.status} ${i}`);
676
- }
677
- return await s.json();
678
- } catch (s) {
679
- throw s.name === "TypeError" && s.message.includes("Failed to fetch") ? new Error("Could not connect to the server. Please check if the server is running.") : s;
680
- }
608
+ async queryFile(e, t, s = 10) {
609
+ return this.getRequiredApiKey("API key is required for querying files"), await this.requestJsonOrThrow(
610
+ `${this.apiUrl}/api/files/${e}/query`,
611
+ {
612
+ method: "POST",
613
+ headers: {
614
+ "Content-Type": "application/json"
615
+ },
616
+ body: JSON.stringify({ query: t, max_results: s })
617
+ },
618
+ "Failed to query file"
619
+ );
681
620
  }
682
621
  /**
683
622
  * Delete a specific file.
@@ -686,63 +625,62 @@ class j {
686
625
  * @returns Promise resolving to deletion result
687
626
  * @throws Error if deletion fails
688
627
  */
689
- async deleteFile(t) {
690
- if (!this.apiKey)
691
- throw new Error("API key is required for deleting files");
692
- const e = `${this.apiUrl}/api/files/${t}`, r = this.getFetchOptions({
628
+ async deleteFile(e) {
629
+ this.getRequiredApiKey("API key is required for deleting files");
630
+ const t = `${this.apiUrl}/api/files/${e}`, s = this.getFetchOptions({
693
631
  method: "DELETE"
694
632
  });
695
633
  try {
696
- const s = await fetch(e, r);
697
- if (!s.ok) {
698
- const n = await s.text();
699
- let o;
634
+ const i = await fetch(t, s);
635
+ if (!i.ok) {
636
+ const a = await i.text();
637
+ let d;
700
638
  try {
701
- const d = JSON.parse(n);
702
- o = d.detail || d.message || `Failed to delete file (HTTP ${s.status})`;
639
+ const l = JSON.parse(a);
640
+ d = l.detail || l.message || `Failed to delete file (HTTP ${i.status})`;
703
641
  } catch {
704
- o = `Failed to delete file (HTTP ${s.status})`;
642
+ d = `Failed to delete file (HTTP ${i.status})`;
705
643
  }
706
- throw console.warn(`[ApiClient] ${o}`), new Error(o);
644
+ throw console.warn(`[ApiClient] ${d}`), new Error(d);
707
645
  }
708
- return await s.json();
709
- } catch (s) {
710
- let i;
711
- throw s.name === "TypeError" && s.message.includes("Failed to fetch") ? i = "Could not connect to the server. Please check if the server is running." : s.message && !s.message.includes("Failed to delete file") ? i = s.message : i = "Failed to delete file. Please try again.", console.warn(`[ApiClient] ${i}`), new Error(i);
646
+ return await i.json();
647
+ } catch (i) {
648
+ let r;
649
+ throw this.hasFailedToFetch(i) ? r = T : i.message && !i.message.includes("Failed to delete file") ? r = i.message : r = "Failed to delete file. Please try again.", console.warn(`[ApiClient] ${r}`), new Error(r);
712
650
  }
713
651
  }
714
652
  }
715
- let k = null;
716
- const R = (l, t = null, e = null) => {
717
- k = new j({ apiUrl: l, apiKey: t, sessionId: e });
653
+ let v = null;
654
+ const j = (o, e = null, t = null) => {
655
+ v = new B({ apiUrl: o, apiKey: e, sessionId: t });
718
656
  };
719
- async function* X(l, t = !0, e, r, s, i, n, o, d, u, f, m) {
720
- if (!k)
657
+ async function* G(o, e = !0, t, s, i, r, a, d, l, w, u, m) {
658
+ if (!v)
721
659
  throw new Error("API not configured. Please call configureApi() with your server URL before using any API functions.");
722
- yield* k.streamChat(
723
- l,
724
- t,
660
+ yield* v.streamChat(
661
+ o,
725
662
  e,
726
- r,
663
+ t,
727
664
  s,
728
665
  i,
729
- n,
730
- o,
666
+ r,
667
+ a,
731
668
  d,
669
+ l,
670
+ w,
732
671
  u,
733
- f,
734
672
  m
735
673
  );
736
674
  }
737
- async function B(l, t) {
738
- if (!k)
675
+ async function W(o, e) {
676
+ if (!v)
739
677
  throw new Error("API not configured. Please call configureApi() with your server URL before using any API functions.");
740
- return k.stopChat(l, t);
678
+ return v.stopChat(o, e);
741
679
  }
742
680
  export {
743
- j as ApiClient,
744
- R as configureApi,
745
- B as stopChat,
746
- X as streamChat
681
+ B as ApiClient,
682
+ j as configureApi,
683
+ W as stopChat,
684
+ G as streamChat
747
685
  };
748
686
  //# sourceMappingURL=api.mjs.map