@useago/sdk 1.4.2 → 1.4.4

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 (41) hide show
  1. package/README.md +4 -1
  2. package/dist/AgoClient-CLmtYTJx.cjs +8 -0
  3. package/dist/{AgoClient-BdtuHX7k.js → AgoClient-Ozz2b1dQ.js} +301 -161
  4. package/dist/angular.cjs +1 -1
  5. package/dist/angular.d.cts +151 -6
  6. package/dist/angular.d.ts +151 -6
  7. package/dist/angular.js +1 -1
  8. package/dist/{createConversationSession-B8zfTL78.cjs → createConversationSession-CUkNp6mZ.cjs} +1 -1
  9. package/dist/{createConversationSession-CWpf4u6I.js → createConversationSession-QIBN0gLx.js} +1 -1
  10. package/dist/{createFormCollector-BB_l0Sia.cjs → createFormCollector-DHT1ObOb.cjs} +1 -1
  11. package/dist/{createFormCollector-B4n0_diV.js → createFormCollector-F3YJfsbg.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 +149 -4
  15. package/dist/devtools.d.ts +149 -4
  16. package/dist/helpers.d.cts +6 -0
  17. package/dist/helpers.d.ts +6 -0
  18. package/dist/index.cjs +1 -1
  19. package/dist/index.d.cts +181 -5
  20. package/dist/index.d.ts +181 -5
  21. package/dist/index.js +4 -4
  22. package/dist/react.cjs +3 -3
  23. package/dist/react.d.cts +169 -10
  24. package/dist/react.d.ts +169 -10
  25. package/dist/react.js +441 -428
  26. package/dist/testing.cjs +1 -1
  27. package/dist/testing.d.cts +149 -4
  28. package/dist/testing.d.ts +149 -4
  29. package/dist/testing.js +1 -1
  30. package/dist/vue.cjs +1 -1
  31. package/dist/vue.d.cts +162 -5
  32. package/dist/vue.d.ts +162 -5
  33. package/dist/vue.js +22 -21
  34. package/dist/widget.cjs +3 -3
  35. package/dist/widget.d.cts +149 -4
  36. package/dist/widget.d.ts +149 -4
  37. package/dist/widget.js +120 -120
  38. package/llms-full.txt +1910 -0
  39. package/package.json +5 -3
  40. package/dist/AgoClient-CRAnT4qE.cjs +0 -8
  41. 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 k 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 k(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
+ }, I = 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 I(), R = "ago_widget_id";
48
+ function F() {
49
49
  if (typeof localStorage < "u") {
50
- const t = localStorage.getItem(w);
50
+ const t = localStorage.getItem(R);
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(R, 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,42 @@ 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 {
133
- constructor() {
134
- this.functions = /* @__PURE__ */ new Map();
132
+ }, T = 5e4, N = 2e4, D = 2e3, P = class {
133
+ constructor(e) {
134
+ this.functions = /* @__PURE__ */ new Map(), this.defaultMaxResultBytes = e?.maxResultBytes ?? T;
135
+ }
136
+ setDefaultMaxResultBytes(e) {
137
+ this.defaultMaxResultBytes = e;
135
138
  }
136
139
  register(e, t, s) {
137
140
  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
141
+ const { name: a, handler: r, description: c, parameters: u, maxResultBytes: h } = e;
142
+ return this.register(a, r, {
143
+ description: c,
144
+ parameters: u,
145
+ maxResultBytes: h
142
146
  });
143
147
  }
144
148
  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, {
149
+ 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");
150
+ this.functions.has(i) && l.warn(`Function "${i}" is being overwritten`);
151
+ const { maxResultBytes: n, ...o } = s;
152
+ this.functions.set(i, {
147
153
  schema: {
148
- ...s,
154
+ ...o,
149
155
  name: i
150
156
  },
151
- handler: t
152
- }), a.log(`Registered function: ${i}`);
157
+ handler: t,
158
+ maxResultBytes: n
159
+ }), l.log(`Registered function: ${i}`);
153
160
  }
154
161
  unregister(e) {
155
162
  const t = this.functions.delete(e);
156
- return t && a.log(`Unregistered function: ${e}`), t;
163
+ return t && l.log(`Unregistered function: ${e}`), t;
157
164
  }
158
165
  get(e) {
159
166
  return this.functions.get(e);
@@ -166,38 +173,55 @@ var k = class {
166
173
  }
167
174
  async execute(e, t) {
168
175
  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);
176
+ if (!s) throw new E(`Function "${e}" is not registered`, e);
177
+ l.log(`Executing function: ${e}`, t);
171
178
  try {
172
179
  const i = await s.handler(t);
173
- return a.log(`Function ${e} completed:`, i), i;
180
+ return l.log(`Function ${e} completed:`, i), this.guardResultSize(e, i, s.maxResultBytes);
174
181
  } 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);
182
+ 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
183
  }
177
184
  }
185
+ guardResultSize(e, t, s) {
186
+ let i;
187
+ try {
188
+ i = JSON.stringify(t);
189
+ } catch {
190
+ return t;
191
+ }
192
+ if (i === void 0) return t;
193
+ const n = new TextEncoder().encode(i).length, o = s ?? this.defaultMaxResultBytes;
194
+ return n > o ? (l.warn(`Function "${e}" result is ${n} bytes, over the ${o}-byte limit; a truncated preview was sent to the agent instead. Return fewer fields, paginate, or raise maxResultBytes for this function.`), {
195
+ truncated: !0,
196
+ originalBytes: n,
197
+ maxBytes: o,
198
+ preview: i.slice(0, D),
199
+ hint: `The result of "${e}" exceeded the ${o}-byte limit and was truncated. Request less data (use limit or filter parameters if available), or tell the user the result is too large to process.`
200
+ }) : (n > N && l.warn(`Function "${e}" returned a large result (${Math.round(n / 1024)} KB). Large results consume LLM context: return fewer fields, paginate, or push the data to the UI and return a summary.`), t);
201
+ }
178
202
  clear() {
179
- this.functions.clear(), a.log("Cleared all registered functions");
203
+ this.functions.clear(), l.log("Cleared all registered functions");
180
204
  }
181
205
  get size() {
182
206
  return this.functions.size;
183
207
  }
184
- }, A = class {
208
+ }, M = class {
185
209
  constructor() {
186
210
  this.entries = /* @__PURE__ */ new Map(), this.dynamicProviders = /* @__PURE__ */ new Map();
187
211
  }
188
212
  set(e, t) {
189
- this.entries.set(e, t), a.log(`ClientContext set: ${e}`);
213
+ this.entries.set(e, t), l.log(`ClientContext set: ${e}`);
190
214
  }
191
215
  remove(e) {
192
216
  const t = this.entries.delete(e);
193
- return t && a.log(`ClientContext removed: ${e}`), t;
217
+ return t && l.log(`ClientContext removed: ${e}`), t;
194
218
  }
195
219
  addDynamicProvider(e, t) {
196
- this.dynamicProviders.set(e, t), a.log(`DynamicContext provider added: ${e}`);
220
+ this.dynamicProviders.set(e, t), l.log(`DynamicContext provider added: ${e}`);
197
221
  }
198
222
  removeDynamicProvider(e) {
199
223
  const t = this.dynamicProviders.delete(e);
200
- return t && a.log(`DynamicContext provider removed: ${e}`), t;
224
+ return t && l.log(`DynamicContext provider removed: ${e}`), t;
201
225
  }
202
226
  getSnapshot() {
203
227
  if (this.entries.size === 0 && this.dynamicProviders.size === 0) return null;
@@ -207,34 +231,34 @@ var k = class {
207
231
  const i = s();
208
232
  i && (e[t] = i);
209
233
  } catch (i) {
210
- a.error(`DynamicContext provider "${t}" threw:`, i);
234
+ l.error(`DynamicContext provider "${t}" threw:`, i);
211
235
  }
212
236
  return Object.keys(e).length === 0 ? null : { entries: e };
213
237
  }
214
238
  clear() {
215
- this.entries.clear(), this.dynamicProviders.clear(), a.log("ClientContext cleared");
239
+ this.entries.clear(), this.dynamicProviders.clear(), l.log("ClientContext cleared");
216
240
  }
217
241
  };
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(",")}}`;
242
+ function v(e) {
243
+ 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
244
  }
221
- var R = class {
245
+ var O = class {
222
246
  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();
247
+ 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
248
  }
225
249
  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");
250
+ 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
251
  const t = e.body.getReader(), s = new TextDecoder();
228
252
  try {
229
253
  for (; ; ) {
230
254
  const { done: i, value: n } = await t.read();
231
255
  if (i) break;
232
- const r = s.decode(n, { stream: !0 });
233
- this.buffer += r, this.processBuffer();
256
+ const o = s.decode(n, { stream: !0 });
257
+ this.buffer += o, this.processBuffer();
234
258
  }
235
259
  return this.buffer.trim() && this.processBuffer(), this.buildFinalMessage();
236
260
  } catch (i) {
237
- const n = i instanceof Error ? i : new p("Stream processing failed mid-flight. The connection may have dropped; retry the message.");
261
+ const n = i instanceof Error ? i : new _("Stream processing failed mid-flight. The connection may have dropped; retry the message.");
238
262
  throw this.callbacks.onError?.(n), n;
239
263
  } finally {
240
264
  t.releaseLock();
@@ -253,10 +277,10 @@ var R = class {
253
277
  if (!i.startsWith(": ") && i.startsWith("data: ")) {
254
278
  const n = i.slice(6);
255
279
  try {
256
- const r = JSON.parse(n);
257
- this.handleChunk(r);
258
- } catch (r) {
259
- a.warn("Failed to parse SSE data:", n, r);
280
+ const o = JSON.parse(n);
281
+ this.handleChunk(o);
282
+ } catch (o) {
283
+ l.warn("Failed to parse SSE data:", n, o);
260
284
  }
261
285
  }
262
286
  }
@@ -281,7 +305,7 @@ var R = class {
281
305
  url: s.use_external_link ? s.external_link_url : s.internal_link_url
282
306
  };
283
307
  })), e.type === "client_function" && e.function_name) {
284
- const t = `${e.function_name}::${f(e.arguments ?? {})}`;
308
+ const t = `${e.function_name}::${v(e.arguments ?? {})}`;
285
309
  this.firedClientFunctions.has(t) || (this.firedClientFunctions.add(t), this.callbacks.onClientFunction?.({
286
310
  invocationId: e.id || "",
287
311
  functionName: e.function_name,
@@ -295,7 +319,11 @@ var R = class {
295
319
  const s = this.toolCalls.findIndex((i) => i.id === t.id);
296
320
  s >= 0 ? this.toolCalls[s] = t : this.toolCalls.push(t);
297
321
  }
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()));
322
+ 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?.({
323
+ conversationId: this.message.conversationId || "",
324
+ messageId: this.message.id,
325
+ waitingToolCallIds: e.waiting_tool_call_ids ?? []
326
+ }));
299
327
  }
300
328
  parseToolCall(e) {
301
329
  return {
@@ -327,14 +355,14 @@ var R = class {
327
355
  }
328
356
  buildFinalMessage() {
329
357
  const e = this.buildMessage();
330
- return this.callbacks.onComplete?.(e), e;
358
+ return e.status !== "WAITING_CLIENT" && this.callbacks.onComplete?.(e), e;
331
359
  }
332
360
  };
333
- function O(e) {
361
+ function H(e) {
334
362
  const t = e.message.toLowerCase();
335
363
  return t.includes("load failed") || t.includes("failed to fetch") || t.includes("network") || t.includes("abort");
336
364
  }
337
- var F = /* @__PURE__ */ new Set([
365
+ var j = /* @__PURE__ */ new Set([
338
366
  "image/jpeg",
339
367
  "image/png",
340
368
  "image/gif",
@@ -342,7 +370,7 @@ var F = /* @__PURE__ */ new Set([
342
370
  "image/bmp",
343
371
  "image/tiff"
344
372
  ]);
345
- function I(e) {
373
+ function B(e) {
346
374
  if (!e) return;
347
375
  const t = typeof window < "u" && window.location ? window.location.href : "https://ago.local/";
348
376
  try {
@@ -351,16 +379,16 @@ function I(e) {
351
379
  } catch {
352
380
  }
353
381
  }
354
- function j(e) {
355
- return e.isSafeImage === !0 && typeof e.contentType == "string" && e.contentType.startsWith("image/") && I(e.url) !== void 0;
382
+ function K(e) {
383
+ return e.isSafeImage === !0 && typeof e.contentType == "string" && e.contentType.startsWith("image/") && B(e.url) !== void 0;
356
384
  }
357
- function M(e) {
385
+ function X(e) {
358
386
  if (e == null || e < 0) return "";
359
387
  if (e < 1024) return `${e} B`;
360
388
  const t = e / 1024;
361
389
  return t < 1024 ? `${t.toFixed(1)} KB` : `${(t / 1024).toFixed(1)} MB`;
362
390
  }
363
- function U(e) {
391
+ function L(e) {
364
392
  return {
365
393
  id: String(e.id ?? ""),
366
394
  name: typeof e.name == "string" && e.name ? e.name : "file",
@@ -370,17 +398,17 @@ function U(e) {
370
398
  isSafeImage: e.is_safe_image === !0
371
399
  };
372
400
  }
373
- function L(e) {
401
+ function Y(e) {
374
402
  return e.map((t, s) => ({
375
403
  id: `local-${s}-${t.name}`,
376
404
  name: t.name,
377
405
  contentType: t.type || void 0,
378
406
  fileSize: t.size,
379
407
  url: typeof URL < "u" && URL.createObjectURL ? URL.createObjectURL(t) : void 0,
380
- isSafeImage: F.has(t.type)
408
+ isSafeImage: j.has(t.type)
381
409
  }));
382
410
  }
383
- var T = class {
411
+ var G = class {
384
412
  constructor() {
385
413
  this.handlers = /* @__PURE__ */ new Map();
386
414
  }
@@ -410,60 +438,74 @@ var T = class {
410
438
  waitFor(e, t) {
411
439
  return new Promise((s, i) => {
412
440
  let n;
413
- const r = ((o) => {
414
- n && clearTimeout(n), s(o);
441
+ const o = ((a) => {
442
+ n && clearTimeout(n), s(a);
415
443
  });
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`));
444
+ this.once(e, o), t?.timeout && (n = setTimeout(() => {
445
+ this.off(e, o), i(/* @__PURE__ */ new Error(`waitFor("${String(e)}") timed out after ${t.timeout}ms`));
418
446
  }, t.timeout));
419
447
  });
420
448
  }
421
449
  removeAllListeners(e) {
422
450
  e ? this.handlers.delete(e) : this.handlers.clear();
423
451
  }
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");
452
+ }, S = '`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).', W = /^[a-z][a-z0-9+.-]*:\/\//i, $ = !1;
453
+ function x(e, t = "AgoClient") {
454
+ if (typeof e != "object" || e === null) throw new d(`${t}: ${S}`, "config_missing_base_url");
427
455
  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).`)));
456
+ if (typeof s != "string" || s.trim() === "") throw new d(`${t}: ${S}`, "config_missing_base_url");
457
+ !s.startsWith("/") && !W.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
458
  }
431
- function N(e) {
459
+ function z(e) {
432
460
  return e.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
433
461
  }
434
- function P(e, t) {
462
+ function w(e) {
463
+ return e.split("/").filter((t) => t.startsWith(":")).map((t) => t.slice(1));
464
+ }
465
+ function J(e, t) {
466
+ const s = [];
467
+ return {
468
+ path: e.split("/").map((i) => {
469
+ if (!i.startsWith(":")) return i;
470
+ const n = i.slice(1), o = t[n];
471
+ return o == null || o === "" ? (s.push(n), i) : encodeURIComponent(String(o));
472
+ }).join("/"),
473
+ missing: s
474
+ };
475
+ }
476
+ function q(e, t) {
435
477
  const s = t.find((n) => n.path === e);
436
478
  if (s) return s;
437
479
  const i = t.find((n) => {
438
480
  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);
481
+ const o = "^" + n.path.split("/").map((a) => a.startsWith(":") ? "[^/]+" : z(a)).join("/") + "/?$";
482
+ return new RegExp(o).test(e);
441
483
  });
442
- return i || t.filter((n) => n.path !== "/" && e.startsWith(n.path)).sort((n, r) => r.path.length - n.path.length)[0];
484
+ return i || t.filter((n) => n.path !== "/" && e.startsWith(n.path)).sort((n, o) => o.path.length - n.path.length)[0];
443
485
  }
444
- var z = class _ {
486
+ var V = class A {
445
487
  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");
488
+ this.warnedEmptyConversations = /* @__PURE__ */ new Set(), this.pendingResumes = /* @__PURE__ */ new Map(), this.resumeGate = null, x(t, "AgoClient"), this.config = t, this.httpClient = new U(t), this.functionRegistry = new P({ maxResultBytes: t.maxFunctionResultBytes }), this.contextRegistry = new M(), this.eventEmitter = new G(), t.debug && l.enable(), l.log("AgoClient initialized");
447
489
  }
448
490
  async sendMessage(t, s) {
449
- const i = this.functionRegistry.getSchemas(), n = this.contextRegistry.getSnapshot(), r = this.config.agent || this.config.defaultAgentId, o = {
491
+ const i = this.functionRegistry.getSchemas(), n = this.contextRegistry.getSnapshot(), o = this.config.agent || this.config.defaultAgentId, a = this.resolveClientFunctionsMode(s), r = {
450
492
  content: t,
451
493
  conversation_id: s?.conversationId,
452
- agent_id: s?.agentId || r
494
+ agent_id: s?.agentId || o
453
495
  };
454
- i.length > 0 && (o.client_functions = i), n && (o.client_context = n), s?.hidden && (o.hidden = !0);
455
- let l;
496
+ i.length > 0 && (r.client_functions = i, a === "pause" && (r.client_functions_mode = a)), n && (r.client_context = n), s?.hidden && (r.hidden = !0);
497
+ let c;
456
498
  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);
499
+ const u = new FormData();
500
+ u.append("content", t), s.conversationId && u.append("conversation_id", s.conversationId), (s.agentId || o) && u.append("agent_id", s.agentId || o || ""), i.length > 0 && (u.append("client_functions", JSON.stringify(i)), a === "pause" && u.append("client_functions_mode", a)), n && u.append("client_context", JSON.stringify(n)), s.hidden && u.append("hidden", "true");
501
+ for (const h of s.files) u.append("files", h);
502
+ c = await this.httpClient.postFormData("/api/sdk/v1/messages", u);
503
+ } else c = await this.httpClient.postStream("/api/sdk/v1/messages", r);
504
+ return this.processSSEResponse(c);
463
505
  }
464
506
  async processSSEResponse(t) {
465
507
  let s = !1;
466
- const i = await new R({
508
+ const i = await new O({
467
509
  onRawChunk: (n) => {
468
510
  this.eventEmitter.emit("stream:message", n);
469
511
  },
@@ -482,17 +524,60 @@ var z = class _ {
482
524
  onAnswerComplete: (n) => {
483
525
  this.eventEmitter.emit("message:answer-complete", n);
484
526
  },
527
+ onWaitingClient: (n) => {
528
+ this.eventEmitter.emit("message:waiting-client", n), this.markResumeSignal(n.messageId, n.conversationId, "waitingConfirmed");
529
+ },
485
530
  onComplete: (n) => {
486
531
  this.eventEmitter.emit("message:complete", n);
487
532
  },
488
533
  onError: (n) => {
489
534
  this.eventEmitter.emit("message:error", {
490
535
  error: n.message,
491
- code: n instanceof h ? n.code : void 0
536
+ code: n instanceof d ? n.code : void 0
492
537
  });
493
538
  }
494
539
  }).processStream(t);
495
- return this.maybeFlagEmptyReply(i, s), i;
540
+ return i.status !== "WAITING_CLIENT" && this.maybeFlagEmptyReply(i, s), i;
541
+ }
542
+ resolveClientFunctionsMode(t) {
543
+ return t?.clientFunctionsMode ?? this.config.clientFunctionsMode ?? "placeholder";
544
+ }
545
+ registerResumeGate(t) {
546
+ return this.resumeGate = t, () => {
547
+ this.resumeGate === t && (this.resumeGate = null);
548
+ };
549
+ }
550
+ async continueMessage(t) {
551
+ const s = this.functionRegistry.getSchemas(), i = this.contextRegistry.getSnapshot(), n = {};
552
+ s.length > 0 && (n.client_functions = s), i && (n.client_context = i);
553
+ const o = await this.httpClient.postStream(`/api/sdk/v1/messages/${t}/continue`, n);
554
+ return this.processSSEResponse(o);
555
+ }
556
+ markResumeSignal(t, s, i) {
557
+ if (!t) return;
558
+ const n = this.pendingResumes.get(t) ?? {
559
+ conversationId: s,
560
+ waitingConfirmed: !1,
561
+ resultsReady: !1,
562
+ started: !1
563
+ };
564
+ 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));
565
+ }
566
+ async runAutoResume(t, s) {
567
+ try {
568
+ this.resumeGate && await this.resumeGate({
569
+ conversationId: s,
570
+ messageId: t
571
+ });
572
+ } catch (i) {
573
+ l.warn("Resume gate threw; resuming anyway:", i);
574
+ }
575
+ this.pendingResumes.delete(t);
576
+ try {
577
+ await this.continueMessage(t);
578
+ } catch (i) {
579
+ l.warn("Auto-resume of paused turn failed:", i);
580
+ }
496
581
  }
497
582
  maybeFlagEmptyReply(t, s) {
498
583
  t.status === "DONE" && (t.content ?? "").trim() === "" && !s && !(t.toolCalls && t.toolCalls.length > 0) && !(t.followUpReplies && t.followUpReplies.length > 0) && setTimeout(() => {
@@ -512,16 +597,17 @@ var z = class _ {
512
597
  try {
513
598
  s = await this.functionRegistry.execute(t.functionName, t.arguments);
514
599
  } catch (n) {
515
- i = n instanceof Error ? n.message : "Unknown error", a.error("Client function execution failed:", n);
600
+ i = n instanceof Error ? n.message : "Unknown error", l.error("Client function execution failed:", n);
516
601
  }
517
602
  if (t.invocationId) try {
518
- await this.submitToolCallForm(t.invocationId, {
603
+ const n = await this.submitToolCallForm(t.invocationId, {
519
604
  result: s,
520
605
  error: i,
521
606
  _type: "client_function_result"
522
607
  });
608
+ n?.resume?.ready && this.markResumeSignal(n.resume.message_id, t.conversationId, "resultsReady");
523
609
  } catch (n) {
524
- a.error("Failed to submit function result:", n);
610
+ l.error("Failed to submit function result:", n);
525
611
  }
526
612
  this.eventEmitter.emit("function:result", {
527
613
  invocationId: t.invocationId,
@@ -549,8 +635,8 @@ var z = class _ {
549
635
  status: n.status,
550
636
  createdAt: new Date(n.created_at),
551
637
  hidden: n.hidden,
552
- toolCalls: _.mapPersistedToolCalls(n.tool_call_data),
553
- attachments: n.attachments && n.attachments.length > 0 ? n.attachments.map(U) : void 0
638
+ toolCalls: A.mapPersistedToolCalls(n.tool_call_data),
639
+ attachments: n.attachments && n.attachments.length > 0 ? n.attachments.map(L) : void 0
554
640
  }))
555
641
  };
556
642
  return this.eventEmitter.emit("conversation:loaded", i), i;
@@ -573,8 +659,30 @@ var z = class _ {
573
659
  async getMessages(t) {
574
660
  return (await this.getConversation(t)).messages || [];
575
661
  }
662
+ async resumePendingClientFunctions(t) {
663
+ const s = [...t.messages ?? []].reverse().find((r) => r.role === "assistant" && r.status === "WAITING_CLIENT");
664
+ if (!s) return null;
665
+ 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));
666
+ if (o.length > 0)
667
+ return l.warn("Cannot resume paused turn: function(s) not registered on this page:", o.map((r) => r.functionName)), null;
668
+ let a = i.length === 0;
669
+ for (const r of i) {
670
+ let c, u;
671
+ try {
672
+ c = await this.functionRegistry.execute(r.functionName, r.arguments ?? {});
673
+ } catch (h) {
674
+ u = h instanceof Error ? h.message : "Unknown error", l.error("Client function execution failed:", h);
675
+ }
676
+ a = (await this.submitToolCallForm(r.id, {
677
+ result: c,
678
+ error: u,
679
+ _type: "client_function_result"
680
+ }))?.resume?.ready ?? a;
681
+ }
682
+ return a ? this.continueMessage(s.id) : null;
683
+ }
576
684
  async submitToolCallForm(t, s) {
577
- await this.httpClient.post(`/api/sdk/v1/tool-calls/${t}/submit`, { formData: s });
685
+ return this.httpClient.post(`/api/sdk/v1/tool-calls/${t}/submit`, { formData: s });
578
686
  }
579
687
  async confirmToolCall(t) {
580
688
  await this.httpClient.post(`/api/tool-calls/${t}/confirm/`);
@@ -614,36 +722,68 @@ var z = class _ {
614
722
  return this.functionRegistry.getSchemas();
615
723
  }
616
724
  registerNavigationFunction(t, s) {
617
- const i = s.map((r) => r.name), n = s.map((r) => `- "${r.name}": ${r.description}`).join(`
618
- `);
725
+ const i = s.map((r) => r.name), n = s.map((r) => {
726
+ const c = w(r.path), u = c.length > 0 ? ` (requires ${c.map((h) => `"${h}"`).join(", ")})` : "";
727
+ return `- "${r.name}"${u}: ${r.description}`;
728
+ }).join(`
729
+ `), o = /* @__PURE__ */ new Map();
730
+ for (const r of s) for (const c of w(r.path)) o.set(c, [...o.get(c) ?? [], r.name]);
731
+ const a = { page: {
732
+ type: "string",
733
+ description: "The page to navigate to",
734
+ enum: i
735
+ } };
736
+ for (const [r, c] of o) {
737
+ if (r === "page") {
738
+ l.error('registerNavigationFunction: a ":page" placeholder collides with the "page" argument and is ignored. Rename the placeholder.');
739
+ continue;
740
+ }
741
+ a[r] = {
742
+ type: "string",
743
+ description: `Value for ":${r}" in the page path. Required when page is ${c.map((u) => `"${u}"`).join(" or ")}.`
744
+ };
745
+ }
619
746
  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
- }) : {
747
+ const c = r.page, u = s.find((m) => m.name === c);
748
+ if (!u) return {
625
749
  success: !1,
626
- error: `Unknown page: ${o}`
750
+ error: `Unknown page: ${c}`
751
+ };
752
+ let h = {};
753
+ if (typeof r.params == "string") try {
754
+ h = JSON.parse(r.params);
755
+ } catch {
756
+ }
757
+ else r.params && typeof r.params == "object" && (h = r.params);
758
+ const C = {};
759
+ for (const m of w(u.path)) C[m] = r[m] ?? h[m];
760
+ const { path: b, missing: g } = J(u.path, C);
761
+ if (g.length > 0) {
762
+ const m = g.map((p) => `"${p}": "..."`).join(", ");
763
+ return {
764
+ success: !1,
765
+ error: `Page "${c}" needs ${g.map((p) => `"${p}"`).join(", ")}. Retry with { "page": "${c}", ${m} }.`
766
+ };
767
+ }
768
+ return t(b), {
769
+ success: !0,
770
+ navigatedTo: b
627
771
  };
628
772
  }, {
629
773
  description: `Navigate the user to a page in the application. Available pages:
630
774
  ${n}`,
631
775
  parameters: {
632
776
  type: "object",
633
- properties: { page: {
634
- type: "string",
635
- description: "The page to navigate to",
636
- enum: i
637
- } },
777
+ properties: a,
638
778
  required: ["page"]
639
779
  }
640
780
  }), this.addDynamicContext("current-page", () => {
641
781
  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), {
782
+ const r = window.location.href, c = typeof document < "u" ? document.title : void 0, u = q(window.location.pathname, s), h = { url: r };
783
+ return u && (h.page = u.name), c && (h.title = c), {
644
784
  name: "Current page",
645
785
  description: "The page the user is currently viewing.",
646
- data: c
786
+ data: h
647
787
  };
648
788
  });
649
789
  }
@@ -651,38 +791,38 @@ ${n}`,
651
791
  this.unregisterFunction("navigateToPage"), this.removeDynamicContext("current-page");
652
792
  }
653
793
  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(`
794
+ const i = s?.functionName ?? "setPageState", n = new Map(t.map((a) => [a.name, a])), o = t.map((a) => `- "${a.name}": ${a.description}`).join(`
655
795
  `);
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);
796
+ this.registerFunction(i, async (a) => {
797
+ const r = {};
798
+ for (const [c, u] of Object.entries(a)) {
799
+ if (u === void 0) continue;
800
+ const h = n.get(c);
801
+ h && (await h.set(u), r[c] = u);
662
802
  }
663
803
  return {
664
804
  success: !0,
665
- applied: l
805
+ applied: r
666
806
  };
667
807
  }, {
668
808
  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}`,
809
+ ${o}`,
670
810
  parameters: {
671
811
  type: "object",
672
- properties: Object.fromEntries(t.map((o) => [o.name, {
673
- ...o.schema,
674
- description: o.description
812
+ properties: Object.fromEntries(t.map((a) => [a.name, {
813
+ ...a.schema,
814
+ description: a.description
675
815
  }]))
676
816
  }
677
817
  }), 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();
818
+ const a = t.filter((c) => typeof c.get == "function");
819
+ if (a.length === 0) return null;
820
+ const r = {};
821
+ for (const c of a) r[c.name] = c.get();
682
822
  return {
683
823
  name: "Page state",
684
824
  description: "Current, editable state of the page the user is viewing.",
685
- data: l
825
+ data: r
686
826
  };
687
827
  });
688
828
  }
@@ -740,33 +880,33 @@ ${r}`,
740
880
  }
741
881
  updateConfig(t) {
742
882
  const s = {};
743
- for (const [n, r] of Object.entries(t)) r !== void 0 && (s[n] = r);
883
+ for (const [n, o] of Object.entries(t)) o !== void 0 && (s[n] = o);
744
884
  const i = {
745
885
  ...this.config,
746
886
  ...s
747
887
  };
748
- b(i, "AgoClient.updateConfig"), this.config = i, this.httpClient.updateConfig(s), s.debug !== void 0 && (s.debug ? a.enable() : a.disable());
888
+ x(i, "AgoClient.updateConfig"), this.config = i, this.httpClient.updateConfig(s), s.debug !== void 0 && (s.debug ? l.enable() : l.disable()), s.maxFunctionResultBytes !== void 0 && this.functionRegistry.setDefaultMaxResultBytes(s.maxFunctionResultBytes);
749
889
  }
750
890
  destroy() {
751
- this.eventEmitter.removeAllListeners(), this.functionRegistry.clear(), this.contextRegistry.clear(), a.log("AgoClient destroyed");
891
+ this.eventEmitter.removeAllListeners(), this.functionRegistry.clear(), this.contextRegistry.clear(), this.pendingResumes.clear(), this.resumeGate = null, l.log("AgoClient destroyed");
752
892
  }
753
893
  };
754
894
  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
895
+ _,
896
+ K as a,
897
+ O as c,
898
+ P as d,
899
+ l as f,
900
+ y as g,
901
+ E as h,
902
+ Y as i,
903
+ H as l,
904
+ d as m,
905
+ x as n,
906
+ X as o,
907
+ f as p,
908
+ G as r,
909
+ B as s,
910
+ V as t,
911
+ M as u
772
912
  };