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