@useago/sdk 1.4.2 → 1.4.3

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.
Files changed (38) hide show
  1. package/README.md +4 -1
  2. package/dist/AgoClient-CMDVqNaH.cjs +8 -0
  3. package/dist/{AgoClient-BdtuHX7k.js → AgoClient-S8oeNnAE.js} +273 -157
  4. package/dist/angular.cjs +1 -1
  5. package/dist/angular.d.cts +121 -4
  6. package/dist/angular.d.ts +121 -4
  7. package/dist/angular.js +1 -1
  8. package/dist/{createConversationSession-B8zfTL78.cjs → createConversationSession-CmBq7uGi.cjs} +1 -1
  9. package/dist/{createConversationSession-CWpf4u6I.js → createConversationSession-DoUHdVNR.js} +1 -1
  10. package/dist/{createFormCollector-BB_l0Sia.cjs → createFormCollector-Bz_0IJ0Q.cjs} +1 -1
  11. package/dist/{createFormCollector-B4n0_diV.js → createFormCollector-vy-QvFja.js} +1 -1
  12. package/dist/createMockClient-BSr-UV8R.cjs +1 -0
  13. package/dist/{createMockClient-d-arlmCq.js → createMockClient-bAZ9KBHC.js} +18 -15
  14. package/dist/devtools.d.cts +120 -3
  15. package/dist/devtools.d.ts +120 -3
  16. package/dist/index.cjs +1 -1
  17. package/dist/index.d.cts +132 -3
  18. package/dist/index.d.ts +132 -3
  19. package/dist/index.js +4 -4
  20. package/dist/react.cjs +3 -3
  21. package/dist/react.d.cts +134 -9
  22. package/dist/react.d.ts +134 -9
  23. package/dist/react.js +440 -429
  24. package/dist/testing.cjs +1 -1
  25. package/dist/testing.d.cts +120 -3
  26. package/dist/testing.d.ts +120 -3
  27. package/dist/testing.js +1 -1
  28. package/dist/vue.cjs +1 -1
  29. package/dist/vue.d.cts +127 -4
  30. package/dist/vue.d.ts +127 -4
  31. package/dist/vue.js +1 -1
  32. package/dist/widget.cjs +3 -3
  33. package/dist/widget.d.cts +120 -3
  34. package/dist/widget.d.ts +120 -3
  35. package/dist/widget.js +120 -120
  36. package/package.json +1 -1
  37. package/dist/AgoClient-CRAnT4qE.cjs +0 -8
  38. package/dist/createMockClient-ucPENDzz.cjs +0 -1
@@ -1,28 +1,28 @@
1
- var h = class extends Error {
1
+ var d = class extends Error {
2
2
  constructor(e, t, s) {
3
3
  super(e), this.code = t, this.statusCode = s, this.name = "AgoError";
4
4
  }
5
- }, u = class E extends h {
6
- constructor(t, s, i, n, r, o) {
7
- super(t, s, i), this.type = n, this.param = r, this.docUrl = o, this.name = "AgoApiError";
5
+ }, f = class I extends d {
6
+ constructor(t, s, i, n, o, a) {
7
+ super(t, s, i), this.type = n, this.param = o, this.docUrl = a, this.name = "AgoApiError";
8
8
  }
9
9
  static fromResponse(t, s) {
10
10
  const i = t.error;
11
- return new E(i.doc_url ? `${i.message} See ${i.doc_url}` : i.message, i.code, s, i.type, i.param, i.doc_url);
11
+ return new I(i.doc_url ? `${i.message} See ${i.doc_url}` : i.message, i.code, s, i.type, i.param, i.doc_url);
12
12
  }
13
- }, m = class extends h {
13
+ }, y = class extends d {
14
14
  constructor(e, t) {
15
15
  super(e, "network_error"), this.originalError = t, this.name = "AgoNetworkError";
16
16
  }
17
- }, p = class extends h {
17
+ }, _ = class extends d {
18
18
  constructor(e, t = "stream_error") {
19
19
  super(e, t), this.name = "AgoStreamError";
20
20
  }
21
- }, y = class extends h {
21
+ }, E = class extends d {
22
22
  constructor(e, t, s) {
23
23
  super(e, "function_error"), this.functionName = t, this.originalError = s, this.name = "AgoFunctionError";
24
24
  }
25
- }, S = class {
25
+ }, A = class {
26
26
  constructor(e = !1) {
27
27
  this.enabled = e;
28
28
  }
@@ -44,22 +44,22 @@ var h = class extends Error {
44
44
  debug(...e) {
45
45
  this.enabled && console.debug("[AGO SDK]", ...e);
46
46
  }
47
- }, a = new S(), w = "ago_widget_id";
48
- function $() {
47
+ }, l = new A(), S = "ago_widget_id";
48
+ function F() {
49
49
  if (typeof localStorage < "u") {
50
- const t = localStorage.getItem(w);
50
+ const t = localStorage.getItem(S);
51
51
  if (t) return t;
52
52
  }
53
53
  const e = typeof crypto < "u" && typeof crypto.randomUUID == "function" ? crypto.randomUUID() : `ago-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 12)}`;
54
54
  if (typeof localStorage < "u") try {
55
- localStorage.setItem(w, e);
55
+ localStorage.setItem(S, e);
56
56
  } catch {
57
57
  }
58
58
  return e;
59
59
  }
60
- var k = class {
60
+ var U = class {
61
61
  constructor(e) {
62
- this.baseUrl = e.baseUrl.replace(/\/$/, ""), this.headers = { "X-User-Anon-Id": e.widgetId || $() }, e.userEmail && (this.headers["X-User-Email"] = e.userEmail), e.userJwt && (this.headers.Authorization = `Bearer ${e.userJwt}`), e.permission && (this.headers["X-Widget-Permission"] = e.permission);
62
+ this.baseUrl = e.baseUrl.replace(/\/$/, ""), this.headers = { "X-User-Anon-Id": e.widgetId || F() }, e.userEmail && (this.headers["X-User-Email"] = e.userEmail), e.userJwt && (this.headers.Authorization = `Bearer ${e.userJwt}`), e.permission && (this.headers["X-Widget-Permission"] = e.permission);
63
63
  }
64
64
  updateConfig(e) {
65
65
  e.baseUrl && (this.baseUrl = e.baseUrl.replace(/\/$/, "")), e.widgetId && (this.headers["X-User-Anon-Id"] = e.widgetId), e.userEmail && (this.headers["X-User-Email"] = e.userEmail), e.userJwt && (this.headers.Authorization = `Bearer ${e.userJwt}`), e.permission !== void 0 && (e.permission ? this.headers["X-Widget-Permission"] = e.permission : delete this.headers["X-Widget-Permission"]);
@@ -72,7 +72,7 @@ var k = class {
72
72
  }
73
73
  async postStream(e, t) {
74
74
  const s = `${this.baseUrl}${e}`;
75
- a.debug("POST (stream)", s, t);
75
+ l.debug("POST (stream)", s, t);
76
76
  try {
77
77
  const i = await fetch(s, {
78
78
  method: "POST",
@@ -84,12 +84,12 @@ var k = class {
84
84
  });
85
85
  return i.ok || await this.handleErrorResponse(i), i;
86
86
  } catch (i) {
87
- throw i instanceof u ? i : new m(`Network error: ${i instanceof Error ? i.message : "Unknown error"}. Check that \`baseUrl\` is reachable and includes the protocol (https://).`, i instanceof Error ? i : void 0);
87
+ throw i instanceof f ? i : new y(`Network error: ${i instanceof Error ? i.message : "Unknown error"}. Check that \`baseUrl\` is reachable and includes the protocol (https://).`, i instanceof Error ? i : void 0);
88
88
  }
89
89
  }
90
90
  async postFormData(e, t) {
91
91
  const s = `${this.baseUrl}${e}`;
92
- a.debug("POST (formData)", s);
92
+ l.debug("POST (formData)", s);
93
93
  const i = { ...this.headers };
94
94
  try {
95
95
  const n = await fetch(s, {
@@ -99,12 +99,12 @@ var k = class {
99
99
  });
100
100
  return n.ok || await this.handleErrorResponse(n), n;
101
101
  } catch (n) {
102
- throw n instanceof u ? n : new m(`Network error: ${n instanceof Error ? n.message : "Unknown error"}. Check that \`baseUrl\` is reachable and includes the protocol (https://).`, n instanceof Error ? n : void 0);
102
+ throw n instanceof f ? n : new y(`Network error: ${n instanceof Error ? n.message : "Unknown error"}. Check that \`baseUrl\` is reachable and includes the protocol (https://).`, n instanceof Error ? n : void 0);
103
103
  }
104
104
  }
105
105
  async request(e, t, s) {
106
106
  const i = `${this.baseUrl}${t}`;
107
- a.debug(e, i, s);
107
+ l.debug(e, i, s);
108
108
  try {
109
109
  const n = await fetch(i, {
110
110
  method: e,
@@ -116,7 +116,7 @@ var k = class {
116
116
  });
117
117
  return n.ok || await this.handleErrorResponse(n), n.status === 204 ? void 0 : n.json();
118
118
  } catch (n) {
119
- throw n instanceof u ? n : new m(`Network error: ${n instanceof Error ? n.message : "Unknown error"}. Check that \`baseUrl\` is reachable and includes the protocol (https://).`, n instanceof Error ? n : void 0);
119
+ throw n instanceof f ? n : new y(`Network error: ${n instanceof Error ? n.message : "Unknown error"}. Check that \`baseUrl\` is reachable and includes the protocol (https://).`, n instanceof Error ? n : void 0);
120
120
  }
121
121
  }
122
122
  async handleErrorResponse(e) {
@@ -125,35 +125,35 @@ var k = class {
125
125
  t = await e.json();
126
126
  } catch {
127
127
  }
128
- if (t?.error) throw u.fromResponse(t, e.status);
128
+ if (t?.error) throw f.fromResponse(t, e.status);
129
129
  let s = "";
130
- throw e.status === 401 || e.status === 403 ? s = " Check `userJwt` (and that it has not expired)." : e.status === 404 && (s = " Check that `baseUrl` points at your AGO API root."), new u(`HTTP ${e.status}: ${e.statusText}.${s}`, "http_error", e.status, "api_error");
130
+ throw e.status === 401 || e.status === 403 ? s = " Check `userJwt` (and that it has not expired)." : e.status === 404 && (s = " Check that `baseUrl` points at your AGO API root."), new f(`HTTP ${e.status}: ${e.statusText}.${s}`, "http_error", e.status, "api_error");
131
131
  }
132
- }, x = class {
132
+ }, N = class {
133
133
  constructor() {
134
134
  this.functions = /* @__PURE__ */ new Map();
135
135
  }
136
136
  register(e, t, s) {
137
137
  if (typeof e == "object") {
138
- const { name: n, handler: r, description: o, parameters: l } = e;
139
- return this.register(n, r, {
140
- description: o,
141
- parameters: l
138
+ const { name: n, handler: o, description: a, parameters: r } = e;
139
+ return this.register(n, o, {
140
+ description: a,
141
+ parameters: r
142
142
  });
143
143
  }
144
144
  const i = e;
145
- if (!t || !s) throw new h(`registerFunction("${i}"): both a handler and a schema are required. Pass them as arguments or use the single-object form: registerFunction({ name, parameters, handler }).`, "function_invalid_registration");
146
- this.functions.has(i) && a.warn(`Function "${i}" is being overwritten`), this.functions.set(i, {
145
+ if (!t || !s) throw new d(`registerFunction("${i}"): both a handler and a schema are required. Pass them as arguments or use the single-object form: registerFunction({ name, parameters, handler }).`, "function_invalid_registration");
146
+ this.functions.has(i) && l.warn(`Function "${i}" is being overwritten`), this.functions.set(i, {
147
147
  schema: {
148
148
  ...s,
149
149
  name: i
150
150
  },
151
151
  handler: t
152
- }), a.log(`Registered function: ${i}`);
152
+ }), l.log(`Registered function: ${i}`);
153
153
  }
154
154
  unregister(e) {
155
155
  const t = this.functions.delete(e);
156
- return t && a.log(`Unregistered function: ${e}`), t;
156
+ return t && l.log(`Unregistered function: ${e}`), t;
157
157
  }
158
158
  get(e) {
159
159
  return this.functions.get(e);
@@ -166,38 +166,38 @@ var k = class {
166
166
  }
167
167
  async execute(e, t) {
168
168
  const s = this.functions.get(e);
169
- if (!s) throw new y(`Function "${e}" is not registered`, e);
170
- a.log(`Executing function: ${e}`, t);
169
+ if (!s) throw new E(`Function "${e}" is not registered`, e);
170
+ l.log(`Executing function: ${e}`, t);
171
171
  try {
172
172
  const i = await s.handler(t);
173
- return a.log(`Function ${e} completed:`, i), i;
173
+ return l.log(`Function ${e} completed:`, i), i;
174
174
  } catch (i) {
175
- throw a.error(`Function ${e} failed:`, i), new y(`Function "${e}" execution failed: ${i instanceof Error ? i.message : "Unknown error"}`, e, i instanceof Error ? i : void 0);
175
+ throw l.error(`Function ${e} failed:`, i), new E(`Function "${e}" execution failed: ${i instanceof Error ? i.message : "Unknown error"}`, e, i instanceof Error ? i : void 0);
176
176
  }
177
177
  }
178
178
  clear() {
179
- this.functions.clear(), a.log("Cleared all registered functions");
179
+ this.functions.clear(), l.log("Cleared all registered functions");
180
180
  }
181
181
  get size() {
182
182
  return this.functions.size;
183
183
  }
184
- }, A = class {
184
+ }, T = class {
185
185
  constructor() {
186
186
  this.entries = /* @__PURE__ */ new Map(), this.dynamicProviders = /* @__PURE__ */ new Map();
187
187
  }
188
188
  set(e, t) {
189
- this.entries.set(e, t), a.log(`ClientContext set: ${e}`);
189
+ this.entries.set(e, t), l.log(`ClientContext set: ${e}`);
190
190
  }
191
191
  remove(e) {
192
192
  const t = this.entries.delete(e);
193
- return t && a.log(`ClientContext removed: ${e}`), t;
193
+ return t && l.log(`ClientContext removed: ${e}`), t;
194
194
  }
195
195
  addDynamicProvider(e, t) {
196
- this.dynamicProviders.set(e, t), a.log(`DynamicContext provider added: ${e}`);
196
+ this.dynamicProviders.set(e, t), l.log(`DynamicContext provider added: ${e}`);
197
197
  }
198
198
  removeDynamicProvider(e) {
199
199
  const t = this.dynamicProviders.delete(e);
200
- return t && a.log(`DynamicContext provider removed: ${e}`), t;
200
+ return t && l.log(`DynamicContext provider removed: ${e}`), t;
201
201
  }
202
202
  getSnapshot() {
203
203
  if (this.entries.size === 0 && this.dynamicProviders.size === 0) return null;
@@ -207,34 +207,34 @@ var k = class {
207
207
  const i = s();
208
208
  i && (e[t] = i);
209
209
  } catch (i) {
210
- a.error(`DynamicContext provider "${t}" threw:`, i);
210
+ l.error(`DynamicContext provider "${t}" threw:`, i);
211
211
  }
212
212
  return Object.keys(e).length === 0 ? null : { entries: e };
213
213
  }
214
214
  clear() {
215
- this.entries.clear(), this.dynamicProviders.clear(), a.log("ClientContext cleared");
215
+ this.entries.clear(), this.dynamicProviders.clear(), l.log("ClientContext cleared");
216
216
  }
217
217
  };
218
- function f(e) {
219
- return e === null || typeof e != "object" ? JSON.stringify(e) ?? "null" : Array.isArray(e) ? `[${e.map(f).join(",")}]` : `{${Object.keys(e).sort().map((t) => `${JSON.stringify(t)}:${f(e[t])}`).join(",")}}`;
218
+ function v(e) {
219
+ return e === null || typeof e != "object" ? JSON.stringify(e) ?? "null" : Array.isArray(e) ? `[${e.map(v).join(",")}]` : `{${Object.keys(e).sort().map((t) => `${JSON.stringify(t)}:${v(e[t])}`).join(",")}}`;
220
220
  }
221
- var R = class {
221
+ var D = class {
222
222
  constructor(e) {
223
- this.callbacks = e, this.buffer = "", this.message = {}, this.toolCalls = [], this.sources = [], this.followUpReplies = [], this.isFirstChunk = !0, this.answerCompleteEmitted = !1, this.firedClientFunctions = /* @__PURE__ */ new Set();
223
+ this.callbacks = e, this.buffer = "", this.message = {}, this.toolCalls = [], this.sources = [], this.followUpReplies = [], this.isFirstChunk = !0, this.answerCompleteEmitted = !1, this.waitingClientEmitted = !1, this.firedClientFunctions = /* @__PURE__ */ new Set();
224
224
  }
225
225
  async processStream(e) {
226
- if (!e.body) throw new p("Response has no body. The endpoint did not return a stream: check that `baseUrl` points at an AGO API and nothing (proxy, mock) strips the SSE body.", "stream_no_body");
226
+ if (!e.body) throw new _("Response has no body. The endpoint did not return a stream: check that `baseUrl` points at an AGO API and nothing (proxy, mock) strips the SSE body.", "stream_no_body");
227
227
  const t = e.body.getReader(), s = new TextDecoder();
228
228
  try {
229
229
  for (; ; ) {
230
230
  const { done: i, value: n } = await t.read();
231
231
  if (i) break;
232
- const r = s.decode(n, { stream: !0 });
233
- this.buffer += r, this.processBuffer();
232
+ const o = s.decode(n, { stream: !0 });
233
+ this.buffer += o, this.processBuffer();
234
234
  }
235
235
  return this.buffer.trim() && this.processBuffer(), this.buildFinalMessage();
236
236
  } catch (i) {
237
- const n = i instanceof Error ? i : new p("Stream processing failed mid-flight. The connection may have dropped; retry the message.");
237
+ const n = i instanceof Error ? i : new _("Stream processing failed mid-flight. The connection may have dropped; retry the message.");
238
238
  throw this.callbacks.onError?.(n), n;
239
239
  } finally {
240
240
  t.releaseLock();
@@ -253,10 +253,10 @@ var R = class {
253
253
  if (!i.startsWith(": ") && i.startsWith("data: ")) {
254
254
  const n = i.slice(6);
255
255
  try {
256
- const r = JSON.parse(n);
257
- this.handleChunk(r);
258
- } catch (r) {
259
- a.warn("Failed to parse SSE data:", n, r);
256
+ const o = JSON.parse(n);
257
+ this.handleChunk(o);
258
+ } catch (o) {
259
+ l.warn("Failed to parse SSE data:", n, o);
260
260
  }
261
261
  }
262
262
  }
@@ -281,7 +281,7 @@ var R = class {
281
281
  url: s.use_external_link ? s.external_link_url : s.internal_link_url
282
282
  };
283
283
  })), e.type === "client_function" && e.function_name) {
284
- const t = `${e.function_name}::${f(e.arguments ?? {})}`;
284
+ const t = `${e.function_name}::${v(e.arguments ?? {})}`;
285
285
  this.firedClientFunctions.has(t) || (this.firedClientFunctions.add(t), this.callbacks.onClientFunction?.({
286
286
  invocationId: e.id || "",
287
287
  functionName: e.function_name,
@@ -295,7 +295,11 @@ var R = class {
295
295
  const s = this.toolCalls.findIndex((i) => i.id === t.id);
296
296
  s >= 0 ? this.toolCalls[s] = t : this.toolCalls.push(t);
297
297
  }
298
- e.follow_up_replies && (this.followUpReplies = e.follow_up_replies), this.message.status === "DONE" && !this.answerCompleteEmitted && this.message.id && (this.answerCompleteEmitted = !0, this.callbacks.onAnswerComplete?.(this.buildMessage()));
298
+ e.follow_up_replies && (this.followUpReplies = e.follow_up_replies), this.message.status === "DONE" && !this.answerCompleteEmitted && this.message.id && (this.answerCompleteEmitted = !0, this.callbacks.onAnswerComplete?.(this.buildMessage())), this.message.status === "WAITING_CLIENT" && !this.waitingClientEmitted && this.message.id && (this.waitingClientEmitted = !0, this.callbacks.onWaitingClient?.({
299
+ conversationId: this.message.conversationId || "",
300
+ messageId: this.message.id,
301
+ waitingToolCallIds: e.waiting_tool_call_ids ?? []
302
+ }));
299
303
  }
300
304
  parseToolCall(e) {
301
305
  return {
@@ -327,14 +331,14 @@ var R = class {
327
331
  }
328
332
  buildFinalMessage() {
329
333
  const e = this.buildMessage();
330
- return this.callbacks.onComplete?.(e), e;
334
+ return e.status !== "WAITING_CLIENT" && this.callbacks.onComplete?.(e), e;
331
335
  }
332
336
  };
333
- function O(e) {
337
+ function J(e) {
334
338
  const t = e.message.toLowerCase();
335
339
  return t.includes("load failed") || t.includes("failed to fetch") || t.includes("network") || t.includes("abort");
336
340
  }
337
- var F = /* @__PURE__ */ new Set([
341
+ var P = /* @__PURE__ */ new Set([
338
342
  "image/jpeg",
339
343
  "image/png",
340
344
  "image/gif",
@@ -342,7 +346,7 @@ var F = /* @__PURE__ */ new Set([
342
346
  "image/bmp",
343
347
  "image/tiff"
344
348
  ]);
345
- function I(e) {
349
+ function O(e) {
346
350
  if (!e) return;
347
351
  const t = typeof window < "u" && window.location ? window.location.href : "https://ago.local/";
348
352
  try {
@@ -351,16 +355,16 @@ function I(e) {
351
355
  } catch {
352
356
  }
353
357
  }
354
- function j(e) {
355
- return e.isSafeImage === !0 && typeof e.contentType == "string" && e.contentType.startsWith("image/") && I(e.url) !== void 0;
358
+ function B(e) {
359
+ return e.isSafeImage === !0 && typeof e.contentType == "string" && e.contentType.startsWith("image/") && O(e.url) !== void 0;
356
360
  }
357
- function M(e) {
361
+ function q(e) {
358
362
  if (e == null || e < 0) return "";
359
363
  if (e < 1024) return `${e} B`;
360
364
  const t = e / 1024;
361
365
  return t < 1024 ? `${t.toFixed(1)} KB` : `${(t / 1024).toFixed(1)} MB`;
362
366
  }
363
- function U(e) {
367
+ function j(e) {
364
368
  return {
365
369
  id: String(e.id ?? ""),
366
370
  name: typeof e.name == "string" && e.name ? e.name : "file",
@@ -370,17 +374,17 @@ function U(e) {
370
374
  isSafeImage: e.is_safe_image === !0
371
375
  };
372
376
  }
373
- function L(e) {
377
+ function H(e) {
374
378
  return e.map((t, s) => ({
375
379
  id: `local-${s}-${t.name}`,
376
380
  name: t.name,
377
381
  contentType: t.type || void 0,
378
382
  fileSize: t.size,
379
383
  url: typeof URL < "u" && URL.createObjectURL ? URL.createObjectURL(t) : void 0,
380
- isSafeImage: F.has(t.type)
384
+ isSafeImage: P.has(t.type)
381
385
  }));
382
386
  }
383
- var T = class {
387
+ var M = class {
384
388
  constructor() {
385
389
  this.handlers = /* @__PURE__ */ new Map();
386
390
  }
@@ -410,60 +414,74 @@ var T = class {
410
414
  waitFor(e, t) {
411
415
  return new Promise((s, i) => {
412
416
  let n;
413
- const r = ((o) => {
414
- n && clearTimeout(n), s(o);
417
+ const o = ((a) => {
418
+ n && clearTimeout(n), s(a);
415
419
  });
416
- this.once(e, r), t?.timeout && (n = setTimeout(() => {
417
- this.off(e, r), i(/* @__PURE__ */ new Error(`waitFor("${String(e)}") timed out after ${t.timeout}ms`));
420
+ this.once(e, o), t?.timeout && (n = setTimeout(() => {
421
+ this.off(e, o), i(/* @__PURE__ */ new Error(`waitFor("${String(e)}") timed out after ${t.timeout}ms`));
418
422
  }, t.timeout));
419
423
  });
420
424
  }
421
425
  removeAllListeners(e) {
422
426
  e ? this.handlers.delete(e) : this.handlers.clear();
423
427
  }
424
- }, v = '`baseUrl` is required, e.g. new AgoClient({ baseUrl: "https://YOUR-DOMAIN.api.useago.com" }). Try the live demo endpoint https://playground.api.useago.com. See docs/general/configuration.md#error-codes (config_missing_base_url).', D = /^[a-z][a-z0-9+.-]*:\/\//i, C = !1;
425
- function b(e, t = "AgoClient") {
426
- if (typeof e != "object" || e === null) throw new h(`${t}: ${v}`, "config_missing_base_url");
428
+ }, R = '`baseUrl` is required, e.g. new AgoClient({ baseUrl: "https://YOUR-DOMAIN.api.useago.com" }). Try the live demo endpoint https://playground.api.useago.com. See docs/general/configuration.md#error-codes (config_missing_base_url).', G = /^[a-z][a-z0-9+.-]*:\/\//i, $ = !1;
429
+ function k(e, t = "AgoClient") {
430
+ if (typeof e != "object" || e === null) throw new d(`${t}: ${R}`, "config_missing_base_url");
427
431
  const s = e.baseUrl;
428
- if (typeof s != "string" || s.trim() === "") throw new h(`${t}: ${v}`, "config_missing_base_url");
429
- !s.startsWith("/") && !D.test(s) && (C || (C = !0, console.warn(`[AGO] ${t}: \`baseUrl\` has no protocol and is not a relative path (config_suspect_base_url). Requests will fail: Node throws a URL parse error, browsers fetch it as a relative path. Use "https://..." (or a "/path" for a same-origin proxy).`)));
432
+ if (typeof s != "string" || s.trim() === "") throw new d(`${t}: ${R}`, "config_missing_base_url");
433
+ !s.startsWith("/") && !G.test(s) && ($ || ($ = !0, console.warn(`[AGO] ${t}: \`baseUrl\` has no protocol and is not a relative path (config_suspect_base_url). Requests will fail: Node throws a URL parse error, browsers fetch it as a relative path. Use "https://..." (or a "/path" for a same-origin proxy).`)));
430
434
  }
431
- function N(e) {
435
+ function L(e) {
432
436
  return e.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
433
437
  }
434
- function P(e, t) {
438
+ function w(e) {
439
+ return e.split("/").filter((t) => t.startsWith(":")).map((t) => t.slice(1));
440
+ }
441
+ function W(e, t) {
442
+ const s = [];
443
+ return {
444
+ path: e.split("/").map((i) => {
445
+ if (!i.startsWith(":")) return i;
446
+ const n = i.slice(1), o = t[n];
447
+ return o == null || o === "" ? (s.push(n), i) : encodeURIComponent(String(o));
448
+ }).join("/"),
449
+ missing: s
450
+ };
451
+ }
452
+ function z(e, t) {
435
453
  const s = t.find((n) => n.path === e);
436
454
  if (s) return s;
437
455
  const i = t.find((n) => {
438
456
  if (!n.path.includes(":")) return !1;
439
- const r = "^" + n.path.split("/").map((o) => o.startsWith(":") ? "[^/]+" : N(o)).join("/") + "/?$";
440
- return new RegExp(r).test(e);
457
+ const o = "^" + n.path.split("/").map((a) => a.startsWith(":") ? "[^/]+" : L(a)).join("/") + "/?$";
458
+ return new RegExp(o).test(e);
441
459
  });
442
- return i || t.filter((n) => n.path !== "/" && e.startsWith(n.path)).sort((n, r) => r.path.length - n.path.length)[0];
460
+ return i || t.filter((n) => n.path !== "/" && e.startsWith(n.path)).sort((n, o) => o.path.length - n.path.length)[0];
443
461
  }
444
- var z = class _ {
462
+ var K = class x {
445
463
  constructor(t) {
446
- this.warnedEmptyConversations = /* @__PURE__ */ new Set(), b(t, "AgoClient"), this.config = t, this.httpClient = new k(t), this.functionRegistry = new x(), this.contextRegistry = new A(), this.eventEmitter = new T(), t.debug && a.enable(), a.log("AgoClient initialized");
464
+ this.warnedEmptyConversations = /* @__PURE__ */ new Set(), this.pendingResumes = /* @__PURE__ */ new Map(), this.resumeGate = null, k(t, "AgoClient"), this.config = t, this.httpClient = new U(t), this.functionRegistry = new N(), this.contextRegistry = new T(), this.eventEmitter = new M(), t.debug && l.enable(), l.log("AgoClient initialized");
447
465
  }
448
466
  async sendMessage(t, s) {
449
- const i = this.functionRegistry.getSchemas(), n = this.contextRegistry.getSnapshot(), r = this.config.agent || this.config.defaultAgentId, o = {
467
+ const i = this.functionRegistry.getSchemas(), n = this.contextRegistry.getSnapshot(), o = this.config.agent || this.config.defaultAgentId, a = this.resolveClientFunctionsMode(s), r = {
450
468
  content: t,
451
469
  conversation_id: s?.conversationId,
452
- agent_id: s?.agentId || r
470
+ agent_id: s?.agentId || o
453
471
  };
454
- i.length > 0 && (o.client_functions = i), n && (o.client_context = n), s?.hidden && (o.hidden = !0);
455
- let l;
472
+ i.length > 0 && (r.client_functions = i, a === "pause" && (r.client_functions_mode = a)), n && (r.client_context = n), s?.hidden && (r.hidden = !0);
473
+ let c;
456
474
  if (s?.files && s.files.length > 0) {
457
- const c = new FormData();
458
- c.append("content", t), s.conversationId && c.append("conversation_id", s.conversationId), (s.agentId || r) && c.append("agent_id", s.agentId || r || ""), i.length > 0 && c.append("client_functions", JSON.stringify(i)), n && c.append("client_context", JSON.stringify(n)), s.hidden && c.append("hidden", "true");
459
- for (const d of s.files) c.append("files", d);
460
- l = await this.httpClient.postFormData("/api/sdk/v1/messages", c);
461
- } else l = await this.httpClient.postStream("/api/sdk/v1/messages", o);
462
- return this.processSSEResponse(l);
475
+ const h = new FormData();
476
+ h.append("content", t), s.conversationId && h.append("conversation_id", s.conversationId), (s.agentId || o) && h.append("agent_id", s.agentId || o || ""), i.length > 0 && (h.append("client_functions", JSON.stringify(i)), a === "pause" && h.append("client_functions_mode", a)), n && h.append("client_context", JSON.stringify(n)), s.hidden && h.append("hidden", "true");
477
+ for (const u of s.files) h.append("files", u);
478
+ c = await this.httpClient.postFormData("/api/sdk/v1/messages", h);
479
+ } else c = await this.httpClient.postStream("/api/sdk/v1/messages", r);
480
+ return this.processSSEResponse(c);
463
481
  }
464
482
  async processSSEResponse(t) {
465
483
  let s = !1;
466
- const i = await new R({
484
+ const i = await new D({
467
485
  onRawChunk: (n) => {
468
486
  this.eventEmitter.emit("stream:message", n);
469
487
  },
@@ -482,17 +500,60 @@ var z = class _ {
482
500
  onAnswerComplete: (n) => {
483
501
  this.eventEmitter.emit("message:answer-complete", n);
484
502
  },
503
+ onWaitingClient: (n) => {
504
+ this.eventEmitter.emit("message:waiting-client", n), this.markResumeSignal(n.messageId, n.conversationId, "waitingConfirmed");
505
+ },
485
506
  onComplete: (n) => {
486
507
  this.eventEmitter.emit("message:complete", n);
487
508
  },
488
509
  onError: (n) => {
489
510
  this.eventEmitter.emit("message:error", {
490
511
  error: n.message,
491
- code: n instanceof h ? n.code : void 0
512
+ code: n instanceof d ? n.code : void 0
492
513
  });
493
514
  }
494
515
  }).processStream(t);
495
- return this.maybeFlagEmptyReply(i, s), i;
516
+ return i.status !== "WAITING_CLIENT" && this.maybeFlagEmptyReply(i, s), i;
517
+ }
518
+ resolveClientFunctionsMode(t) {
519
+ return t?.clientFunctionsMode ?? this.config.clientFunctionsMode ?? "placeholder";
520
+ }
521
+ registerResumeGate(t) {
522
+ return this.resumeGate = t, () => {
523
+ this.resumeGate === t && (this.resumeGate = null);
524
+ };
525
+ }
526
+ async continueMessage(t) {
527
+ const s = this.functionRegistry.getSchemas(), i = this.contextRegistry.getSnapshot(), n = {};
528
+ s.length > 0 && (n.client_functions = s), i && (n.client_context = i);
529
+ const o = await this.httpClient.postStream(`/api/sdk/v1/messages/${t}/continue`, n);
530
+ return this.processSSEResponse(o);
531
+ }
532
+ markResumeSignal(t, s, i) {
533
+ if (!t) return;
534
+ const n = this.pendingResumes.get(t) ?? {
535
+ conversationId: s,
536
+ waitingConfirmed: !1,
537
+ resultsReady: !1,
538
+ started: !1
539
+ };
540
+ n[i] = !0, s && (n.conversationId = s), this.pendingResumes.set(t, n), !(!n.waitingConfirmed || !n.resultsReady || n.started) && (n.started = !0, this.runAutoResume(t, n.conversationId));
541
+ }
542
+ async runAutoResume(t, s) {
543
+ try {
544
+ this.resumeGate && await this.resumeGate({
545
+ conversationId: s,
546
+ messageId: t
547
+ });
548
+ } catch (i) {
549
+ l.warn("Resume gate threw; resuming anyway:", i);
550
+ }
551
+ this.pendingResumes.delete(t);
552
+ try {
553
+ await this.continueMessage(t);
554
+ } catch (i) {
555
+ l.warn("Auto-resume of paused turn failed:", i);
556
+ }
496
557
  }
497
558
  maybeFlagEmptyReply(t, s) {
498
559
  t.status === "DONE" && (t.content ?? "").trim() === "" && !s && !(t.toolCalls && t.toolCalls.length > 0) && !(t.followUpReplies && t.followUpReplies.length > 0) && setTimeout(() => {
@@ -512,16 +573,17 @@ var z = class _ {
512
573
  try {
513
574
  s = await this.functionRegistry.execute(t.functionName, t.arguments);
514
575
  } catch (n) {
515
- i = n instanceof Error ? n.message : "Unknown error", a.error("Client function execution failed:", n);
576
+ i = n instanceof Error ? n.message : "Unknown error", l.error("Client function execution failed:", n);
516
577
  }
517
578
  if (t.invocationId) try {
518
- await this.submitToolCallForm(t.invocationId, {
579
+ const n = await this.submitToolCallForm(t.invocationId, {
519
580
  result: s,
520
581
  error: i,
521
582
  _type: "client_function_result"
522
583
  });
584
+ n?.resume?.ready && this.markResumeSignal(n.resume.message_id, t.conversationId, "resultsReady");
523
585
  } catch (n) {
524
- a.error("Failed to submit function result:", n);
586
+ l.error("Failed to submit function result:", n);
525
587
  }
526
588
  this.eventEmitter.emit("function:result", {
527
589
  invocationId: t.invocationId,
@@ -549,8 +611,8 @@ var z = class _ {
549
611
  status: n.status,
550
612
  createdAt: new Date(n.created_at),
551
613
  hidden: n.hidden,
552
- toolCalls: _.mapPersistedToolCalls(n.tool_call_data),
553
- attachments: n.attachments && n.attachments.length > 0 ? n.attachments.map(U) : void 0
614
+ toolCalls: x.mapPersistedToolCalls(n.tool_call_data),
615
+ attachments: n.attachments && n.attachments.length > 0 ? n.attachments.map(j) : void 0
554
616
  }))
555
617
  };
556
618
  return this.eventEmitter.emit("conversation:loaded", i), i;
@@ -573,8 +635,30 @@ var z = class _ {
573
635
  async getMessages(t) {
574
636
  return (await this.getConversation(t)).messages || [];
575
637
  }
638
+ async resumePendingClientFunctions(t) {
639
+ const s = [...t.messages ?? []].reverse().find((r) => r.role === "assistant" && r.status === "WAITING_CLIENT");
640
+ if (!s) return null;
641
+ const i = (s.toolCalls ?? []).filter((r) => r.type === "client_function" && r.status === "waiting_input" && r.functionName), n = new Set(this.functionRegistry.getSchemas().map((r) => r.name)), o = i.filter((r) => !n.has(r.functionName));
642
+ if (o.length > 0)
643
+ return l.warn("Cannot resume paused turn: function(s) not registered on this page:", o.map((r) => r.functionName)), null;
644
+ let a = i.length === 0;
645
+ for (const r of i) {
646
+ let c, h;
647
+ try {
648
+ c = await this.functionRegistry.execute(r.functionName, r.arguments ?? {});
649
+ } catch (u) {
650
+ h = u instanceof Error ? u.message : "Unknown error", l.error("Client function execution failed:", u);
651
+ }
652
+ a = (await this.submitToolCallForm(r.id, {
653
+ result: c,
654
+ error: h,
655
+ _type: "client_function_result"
656
+ }))?.resume?.ready ?? a;
657
+ }
658
+ return a ? this.continueMessage(s.id) : null;
659
+ }
576
660
  async submitToolCallForm(t, s) {
577
- await this.httpClient.post(`/api/sdk/v1/tool-calls/${t}/submit`, { formData: s });
661
+ return this.httpClient.post(`/api/sdk/v1/tool-calls/${t}/submit`, { formData: s });
578
662
  }
579
663
  async confirmToolCall(t) {
580
664
  await this.httpClient.post(`/api/tool-calls/${t}/confirm/`);
@@ -614,36 +698,68 @@ var z = class _ {
614
698
  return this.functionRegistry.getSchemas();
615
699
  }
616
700
  registerNavigationFunction(t, s) {
617
- const i = s.map((r) => r.name), n = s.map((r) => `- "${r.name}": ${r.description}`).join(`
618
- `);
701
+ const i = s.map((r) => r.name), n = s.map((r) => {
702
+ const c = w(r.path), h = c.length > 0 ? ` (requires ${c.map((u) => `"${u}"`).join(", ")})` : "";
703
+ return `- "${r.name}"${h}: ${r.description}`;
704
+ }).join(`
705
+ `), o = /* @__PURE__ */ new Map();
706
+ for (const r of s) for (const c of w(r.path)) o.set(c, [...o.get(c) ?? [], r.name]);
707
+ const a = { page: {
708
+ type: "string",
709
+ description: "The page to navigate to",
710
+ enum: i
711
+ } };
712
+ for (const [r, c] of o) {
713
+ if (r === "page") {
714
+ l.error('registerNavigationFunction: a ":page" placeholder collides with the "page" argument and is ignored. Rename the placeholder.');
715
+ continue;
716
+ }
717
+ a[r] = {
718
+ type: "string",
719
+ description: `Value for ":${r}" in the page path. Required when page is ${c.map((h) => `"${h}"`).join(" or ")}.`
720
+ };
721
+ }
619
722
  this.registerFunction("navigateToPage", async (r) => {
620
- const o = r.page, l = s.find((c) => c.name === o);
621
- return l ? (t(l.path), {
622
- success: !0,
623
- navigatedTo: l.path
624
- }) : {
723
+ const c = r.page, h = s.find((m) => m.name === c);
724
+ if (!h) return {
625
725
  success: !1,
626
- error: `Unknown page: ${o}`
726
+ error: `Unknown page: ${c}`
727
+ };
728
+ let u = {};
729
+ if (typeof r.params == "string") try {
730
+ u = JSON.parse(r.params);
731
+ } catch {
732
+ }
733
+ else r.params && typeof r.params == "object" && (u = r.params);
734
+ const C = {};
735
+ for (const m of w(h.path)) C[m] = r[m] ?? u[m];
736
+ const { path: b, missing: g } = W(h.path, C);
737
+ if (g.length > 0) {
738
+ const m = g.map((p) => `"${p}": "..."`).join(", ");
739
+ return {
740
+ success: !1,
741
+ error: `Page "${c}" needs ${g.map((p) => `"${p}"`).join(", ")}. Retry with { "page": "${c}", ${m} }.`
742
+ };
743
+ }
744
+ return t(b), {
745
+ success: !0,
746
+ navigatedTo: b
627
747
  };
628
748
  }, {
629
749
  description: `Navigate the user to a page in the application. Available pages:
630
750
  ${n}`,
631
751
  parameters: {
632
752
  type: "object",
633
- properties: { page: {
634
- type: "string",
635
- description: "The page to navigate to",
636
- enum: i
637
- } },
753
+ properties: a,
638
754
  required: ["page"]
639
755
  }
640
756
  }), this.addDynamicContext("current-page", () => {
641
757
  if (typeof window > "u" || !window.location) return null;
642
- const r = window.location.href, o = typeof document < "u" ? document.title : void 0, l = P(window.location.pathname, s), c = { url: r };
643
- return l && (c.page = l.name), o && (c.title = o), {
758
+ const r = window.location.href, c = typeof document < "u" ? document.title : void 0, h = z(window.location.pathname, s), u = { url: r };
759
+ return h && (u.page = h.name), c && (u.title = c), {
644
760
  name: "Current page",
645
761
  description: "The page the user is currently viewing.",
646
- data: c
762
+ data: u
647
763
  };
648
764
  });
649
765
  }
@@ -651,38 +767,38 @@ ${n}`,
651
767
  this.unregisterFunction("navigateToPage"), this.removeDynamicContext("current-page");
652
768
  }
653
769
  registerPageStateFunction(t, s) {
654
- const i = s?.functionName ?? "setPageState", n = new Map(t.map((o) => [o.name, o])), r = t.map((o) => `- "${o.name}": ${o.description}`).join(`
770
+ const i = s?.functionName ?? "setPageState", n = new Map(t.map((a) => [a.name, a])), o = t.map((a) => `- "${a.name}": ${a.description}`).join(`
655
771
  `);
656
- this.registerFunction(i, async (o) => {
657
- const l = {};
658
- for (const [c, d] of Object.entries(o)) {
659
- if (d === void 0) continue;
660
- const g = n.get(c);
661
- g && (await g.set(d), l[c] = d);
772
+ this.registerFunction(i, async (a) => {
773
+ const r = {};
774
+ for (const [c, h] of Object.entries(a)) {
775
+ if (h === void 0) continue;
776
+ const u = n.get(c);
777
+ u && (await u.set(h), r[c] = h);
662
778
  }
663
779
  return {
664
780
  success: !0,
665
- applied: l
781
+ applied: r
666
782
  };
667
783
  }, {
668
784
  description: `Change the state of the current page. Set ONLY the controls the user explicitly asked for; leave the others unset. Available controls:
669
- ${r}`,
785
+ ${o}`,
670
786
  parameters: {
671
787
  type: "object",
672
- properties: Object.fromEntries(t.map((o) => [o.name, {
673
- ...o.schema,
674
- description: o.description
788
+ properties: Object.fromEntries(t.map((a) => [a.name, {
789
+ ...a.schema,
790
+ description: a.description
675
791
  }]))
676
792
  }
677
793
  }), this.addDynamicContext(`page-state:${i}`, () => {
678
- const o = t.filter((c) => typeof c.get == "function");
679
- if (o.length === 0) return null;
680
- const l = {};
681
- for (const c of o) l[c.name] = c.get();
794
+ const a = t.filter((c) => typeof c.get == "function");
795
+ if (a.length === 0) return null;
796
+ const r = {};
797
+ for (const c of a) r[c.name] = c.get();
682
798
  return {
683
799
  name: "Page state",
684
800
  description: "Current, editable state of the page the user is viewing.",
685
- data: l
801
+ data: r
686
802
  };
687
803
  });
688
804
  }
@@ -740,33 +856,33 @@ ${r}`,
740
856
  }
741
857
  updateConfig(t) {
742
858
  const s = {};
743
- for (const [n, r] of Object.entries(t)) r !== void 0 && (s[n] = r);
859
+ for (const [n, o] of Object.entries(t)) o !== void 0 && (s[n] = o);
744
860
  const i = {
745
861
  ...this.config,
746
862
  ...s
747
863
  };
748
- b(i, "AgoClient.updateConfig"), this.config = i, this.httpClient.updateConfig(s), s.debug !== void 0 && (s.debug ? a.enable() : a.disable());
864
+ k(i, "AgoClient.updateConfig"), this.config = i, this.httpClient.updateConfig(s), s.debug !== void 0 && (s.debug ? l.enable() : l.disable());
749
865
  }
750
866
  destroy() {
751
- this.eventEmitter.removeAllListeners(), this.functionRegistry.clear(), this.contextRegistry.clear(), a.log("AgoClient destroyed");
867
+ this.eventEmitter.removeAllListeners(), this.functionRegistry.clear(), this.contextRegistry.clear(), this.pendingResumes.clear(), this.resumeGate = null, l.log("AgoClient destroyed");
752
868
  }
753
869
  };
754
870
  export {
755
- p as _,
756
- j as a,
757
- R as c,
758
- x as d,
759
- a as f,
760
- m as g,
761
- y as h,
762
- L as i,
763
- O as l,
764
- h as m,
765
- b as n,
766
- M as o,
767
- u as p,
768
- T as r,
769
- I as s,
770
- z as t,
771
- A as u
871
+ _,
872
+ B as a,
873
+ D as c,
874
+ N as d,
875
+ l as f,
876
+ y as g,
877
+ E as h,
878
+ H as i,
879
+ J as l,
880
+ d as m,
881
+ k as n,
882
+ q as o,
883
+ f as p,
884
+ M as r,
885
+ O as s,
886
+ K as t,
887
+ T as u
772
888
  };