@useago/sdk 1.0.7 → 1.0.9

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.
@@ -0,0 +1,299 @@
1
+ import { c as $ } from "./AgoClient-QcTtrN7u.js";
2
+ function A(s, e) {
3
+ const a = e ? e.storage ?? (typeof localStorage < "u" ? localStorage : void 0) : void 0;
4
+ let n = s;
5
+ if (e && a) try {
6
+ const m = a.getItem(e.key);
7
+ m != null && (n = JSON.parse(m));
8
+ } catch {
9
+ }
10
+ const o = /* @__PURE__ */ new Set(), c = () => o.forEach((m) => m(n));
11
+ function b() {
12
+ if (e && a) try {
13
+ a.setItem(e.key, JSON.stringify(n));
14
+ } catch {
15
+ }
16
+ }
17
+ return {
18
+ get: () => n,
19
+ set: (m) => {
20
+ n = m, b(), c();
21
+ },
22
+ subscribe: (m) => (o.add(m), () => {
23
+ o.delete(m);
24
+ })
25
+ };
26
+ }
27
+ var P = /^[a-zA-Z0-9_-]{1,40}$/, W = (s) => s == null || s === "";
28
+ function v(s, e) {
29
+ if ("anyOf" in s) return s.anyOf.some((c) => v(c, e));
30
+ if ("allOf" in s) return s.allOf.every((c) => v(c, e));
31
+ const a = e[s.property];
32
+ if (W(a)) return !1;
33
+ if (Array.isArray(s.value)) return s.value.some((c) => String(a) === String(c));
34
+ if (!s.op) return String(a) === String(s.value);
35
+ const n = Number(a), o = Number(s.value);
36
+ if (Number.isNaN(n) || Number.isNaN(o)) return !1;
37
+ switch (s.op) {
38
+ case ">=":
39
+ return n >= o;
40
+ case "<=":
41
+ return n <= o;
42
+ case ">":
43
+ return n > o;
44
+ case "<":
45
+ return n < o;
46
+ default:
47
+ return $.warn(`Unknown requiredWhen op "${s.op}"; treating as not required.`), !1;
48
+ }
49
+ }
50
+ function y(s, e) {
51
+ const a = s.properties ?? {}, n = /* @__PURE__ */ new Set();
52
+ for (const c of s.required ?? []) {
53
+ const b = a[c]?.requiredWhen;
54
+ (!b || v(b, e)) && n.add(c);
55
+ }
56
+ for (const [c, b] of Object.entries(a)) b.requiredWhen && v(b.requiredWhen, e) && n.add(c);
57
+ const o = [...n].filter((c) => W(e[c]));
58
+ return {
59
+ missing: o,
60
+ complete: o.length === 0
61
+ };
62
+ }
63
+ function J(s) {
64
+ const e = {};
65
+ for (const [a, n] of Object.entries(s.properties ?? {})) e[a] = {
66
+ type: n.type,
67
+ ...n.description != null && { description: n.description },
68
+ ...n.enum && { enum: n.enum },
69
+ ...n.default !== void 0 && { default: n.default }
70
+ };
71
+ return {
72
+ type: "object",
73
+ properties: e,
74
+ required: []
75
+ };
76
+ }
77
+ function R(s) {
78
+ const { name: e, description: a, schema: n } = s;
79
+ if (!P.test(e)) throw new Error(`Invalid form collector name "${e}": must match ${P} (it becomes the update_/submit_ function names).`);
80
+ const o = typeof s.submit == "string" ? s.submit ? {
81
+ via: "client",
82
+ url: s.submit
83
+ } : !1 : s.submit ?? !1;
84
+ s.autoSubmit === !0 && !o && $.warn(`FormCollector "${e}": autoSubmit is ignored because no submit target is configured.`);
85
+ const c = (s.autoSubmit ?? !0) && !!o, b = n.properties ?? {}, m = (t) => {
86
+ const r = {};
87
+ for (const [u, i] of Object.entries(t)) {
88
+ const l = b[u];
89
+ if (l)
90
+ if (i == null) r[u] = i;
91
+ else if (l.type === "number" || l.type === "integer") {
92
+ const d = typeof i == "number" ? i : Number(i);
93
+ r[u] = Number.isNaN(d) ? i : d;
94
+ } else l.type === "boolean" ? r[u] = typeof i == "boolean" ? i : i === "true" ? !0 : i === "false" ? !1 : !!i : r[u] = i;
95
+ }
96
+ return r;
97
+ }, S = s.initialValues ?? {}, f = A({
98
+ values: S,
99
+ submitted: !1
100
+ }), C = (t) => {
101
+ const r = f.get(), u = {
102
+ ...r,
103
+ values: {
104
+ ...r.values,
105
+ ...t
106
+ }
107
+ };
108
+ return f.set(u), u;
109
+ };
110
+ let h = null;
111
+ const k = (t, r) => {
112
+ h?.emitFormEvent("form:error", {
113
+ name: e,
114
+ values: t,
115
+ error: r
116
+ });
117
+ };
118
+ let p = null;
119
+ const j = async () => {
120
+ const { values: t } = f.get(), { complete: r, missing: u } = y(n, t);
121
+ if (!r) return {
122
+ ok: !1,
123
+ missing: u
124
+ };
125
+ if (!o) return {
126
+ ok: !1,
127
+ error: "No submit target configured for this form collector."
128
+ };
129
+ const i = t;
130
+ try {
131
+ let l;
132
+ if (o.via === "client") if ("handler" in o) l = await o.handler(i);
133
+ else {
134
+ const d = await fetch(o.url, {
135
+ method: "POST",
136
+ headers: { "Content-Type": "application/json" },
137
+ credentials: "include",
138
+ body: JSON.stringify(i)
139
+ });
140
+ if (!d.ok) {
141
+ const x = `Submit failed: HTTP ${d.status}`;
142
+ return k(i, x), {
143
+ ok: !1,
144
+ error: x
145
+ };
146
+ }
147
+ l = await d.json().catch(() => {
148
+ });
149
+ }
150
+ else {
151
+ if (!h) return {
152
+ ok: !1,
153
+ error: "Backend submit requires install(client) (or useFormCollector) first."
154
+ };
155
+ l = await h.submitFormCollector(e, i);
156
+ }
157
+ return f.set({
158
+ ...f.get(),
159
+ submitted: !0,
160
+ submitResult: l
161
+ }), h?.emitFormEvent("form:submitted", {
162
+ name: e,
163
+ values: i,
164
+ result: l
165
+ }), {
166
+ ok: !0,
167
+ result: l
168
+ };
169
+ } catch (l) {
170
+ const d = l instanceof Error ? l.message : "Submit failed";
171
+ return $.error(`FormCollector "${e}" submit failed:`, l), k(i, d), {
172
+ ok: !1,
173
+ error: d
174
+ };
175
+ }
176
+ }, N = () => p || (p = (async () => {
177
+ try {
178
+ return await j();
179
+ } finally {
180
+ p = null;
181
+ }
182
+ })(), p), F = async () => {
183
+ if (!c || !o) return null;
184
+ const { values: t, submitted: r } = f.get();
185
+ return r || !y(n, t).complete ? null : N();
186
+ }, q = {
187
+ name: `update_${e}`,
188
+ description: `Fill or update fields of the "${e}" form. ${a} Pass any subset of fields; call it repeatedly to fill the form as the user provides information. Returns the current values and which required fields are still missing.`,
189
+ parameters: J(n),
190
+ handler: async (t) => {
191
+ const r = C(m(t)), { missing: u } = y(n, r.values), i = await F();
192
+ return i ? i.ok ? {
193
+ ok: !0,
194
+ values: r.values,
195
+ missing: u,
196
+ submitted: !0
197
+ } : {
198
+ ok: !0,
199
+ values: r.values,
200
+ missing: u,
201
+ submitted: !1,
202
+ submitError: i.error
203
+ } : {
204
+ ok: !0,
205
+ values: r.values,
206
+ missing: u
207
+ };
208
+ }
209
+ }, g = [q];
210
+ o && !c && g.push({
211
+ name: `submit_${e}`,
212
+ description: `Submit the completed "${e}" form. Only call this once every required field is collected and the user has confirmed. If fields are missing it returns them instead of submitting.`,
213
+ parameters: {
214
+ type: "object",
215
+ properties: {}
216
+ },
217
+ handler: () => N()
218
+ });
219
+ const I = "client__", O = o ? `submit_${e}` : null, V = (t) => {
220
+ const r = t.functionName ?? t.toolName;
221
+ if (r)
222
+ return r.startsWith(I) ? r.slice(8) : r;
223
+ }, _ = (t) => {
224
+ let r = { ...S }, u = !1;
225
+ for (const i of t) {
226
+ const l = V(i);
227
+ l === q.name ? i.arguments && (r = {
228
+ ...r,
229
+ ...m(i.arguments)
230
+ }) : O && l === O && i.status?.toLowerCase() === "done" && (u = !0);
231
+ }
232
+ f.set({
233
+ values: r,
234
+ submitted: u
235
+ });
236
+ }, w = `form:${e}`, E = () => {
237
+ const { values: t, submitted: r } = f.get(), { missing: u, complete: i } = y(n, t), l = o ? c ? " The form is submitted automatically as soon as every required field is filled, so there is no submit function to call." : ` When nothing is missing and the user confirms, call submit_${e}.` : "", d = r ? `The "${e}" form has been submitted.` : `You are currently collecting information from the user to fill the "${e}" form.`;
238
+ return {
239
+ name: `Form: ${e}`,
240
+ description: `${d} ${a} Some fields are conditionally required; the requiredWhen field in the schema tells you when each becomes required. The form schema is the following: ${JSON.stringify(n)}. Data collected so far: ${JSON.stringify(t)}. Call update_${e} with any fields the user provides; ask only for what is still missing.${l}`,
241
+ data: {
242
+ values: t,
243
+ missing: u,
244
+ complete: i,
245
+ submitted: r
246
+ }
247
+ };
248
+ }, T = (t) => {
249
+ _((t.messages ?? []).flatMap((r) => r.toolCalls ?? []));
250
+ };
251
+ return {
252
+ name: e,
253
+ store: f,
254
+ functions: g,
255
+ contextKey: w,
256
+ contextProvider: E,
257
+ install: (t) => {
258
+ h = t;
259
+ for (const u of g) t.register(u);
260
+ t.addDynamicContext(w, E);
261
+ const r = f.subscribe(() => t.notifyContextChanged());
262
+ return t.on("conversation:loaded", T), () => {
263
+ r();
264
+ for (const u of g) t.unregisterFunction(u.name);
265
+ t.removeDynamicContext(w), t.off("conversation:loaded", T), h === t && (h = null);
266
+ };
267
+ },
268
+ hydrate: _,
269
+ submit: N,
270
+ getValues: () => f.get().values,
271
+ setValues: (t) => {
272
+ C(m(t)), F();
273
+ },
274
+ reset: () => {
275
+ f.set({
276
+ values: S,
277
+ submitted: !1
278
+ });
279
+ },
280
+ getStatus: () => y(n, f.get().values)
281
+ };
282
+ }
283
+ async function L(s, e) {
284
+ const a = await s.getFormCollector(e.name);
285
+ return R({
286
+ name: a.name,
287
+ description: e.description ?? a.description,
288
+ schema: e.schema ?? a.schema,
289
+ submit: e.submit ?? a.submit,
290
+ initialValues: e.initialValues,
291
+ autoSubmit: e.autoSubmit ?? a.autoSubmit
292
+ });
293
+ }
294
+ export {
295
+ A as i,
296
+ y as n,
297
+ L as r,
298
+ R as t
299
+ };
@@ -176,6 +176,7 @@ declare class AgoClient {
176
176
  * call it when their store updates so observers like the dev panel stay live.
177
177
  */
178
178
  notifyContextChanged(): void;
179
+ /* Excluded from this release type: emitFormEvent */
179
180
  /**
180
181
  * Enable automatic capture of the current browser page (URL + title).
181
182
  * Injected as a dynamic context entry named `browser-page`.
@@ -290,6 +291,27 @@ declare interface AgoClientEvents {
290
291
  result: unknown;
291
292
  error?: string;
292
293
  };
294
+ /**
295
+ * A form collector submitted successfully. `result` is the raw submit response
296
+ * (POST body / handler return value / backend relay result) — the third-party
297
+ * API's answer. `values` is the submitted field set, `name` the collector name.
298
+ */
299
+ "form:submitted": {
300
+ name: string;
301
+ values: Record<string, unknown>;
302
+ result: unknown;
303
+ };
304
+ /**
305
+ * A form collector submit was attempted and failed at the network/server level
306
+ * (HTTP non-2xx, or a thrown handler/fetch). `error` is the message. Validation
307
+ * pre-checks (missing required fields, no submit target) are NOT errors and do
308
+ * not fire this — they are returned to the caller as `{ ok: false }`.
309
+ */
310
+ "form:error": {
311
+ name: string;
312
+ values: Record<string, unknown>;
313
+ error: string;
314
+ };
293
315
  "connection:status": {
294
316
  connected: boolean;
295
317
  };
@@ -473,7 +495,7 @@ declare interface FormCollectorDefinition<V = Record<string, unknown>> {
473
495
 
474
496
  /**
475
497
  * Shape of a form's fields. Mirrors a client function's `parameters` (so the same
476
- * object feeds the store, the update function, and the dynamic context). Additionally allows the SDK-only per-field `requiredWhen`, which {@link toWireParameters} removes before the schema reaches the LLM.
498
+ * object feeds the store, the update function, and the dynamic context). Additionally allows the SDK-only per-field `requiredWhen`, which {@link toWireParameters} removes from the LLM tool's `parameters` (the full schema still reaches the agent via dynamic context).
477
499
  */
478
500
  declare interface FormCollectorSchema {
479
501
  type: "object";
@@ -490,17 +512,32 @@ declare interface FormField {
490
512
  }
491
513
 
492
514
  /**
493
- * A field's conditional-requiredness rule. The field becomes required exactly
494
- * when the controlling `property` matches `value` against the answers collected
495
- * so far:
515
+ * A field's conditional-requiredness rule: either a single {@link FormFieldLeafCondition}
516
+ * or a boolean combination of rules. `anyOf` is OR (true when any nested rule
517
+ * holds); `allOf` is AND (true when every nested rule holds). Both nest
518
+ * arbitrarily, so you can mix them, e.g.
519
+ * `{ anyOf: [{ property: "a", op: ">=", value: 1 }, { property: "b", value: "1" }] }`.
520
+ * An empty `anyOf` is never required; an empty `allOf` is always required.
521
+ *
522
+ * Stripped from the LLM tool's `parameters` (see {@link toWireParameters}), but the
523
+ * full schema, `requiredWhen` included, still reaches the agent via the dynamic
524
+ * context so it knows when each field becomes required.
525
+ */
526
+ declare type FormFieldCondition = FormFieldLeafCondition | {
527
+ anyOf: FormFieldCondition[];
528
+ } | {
529
+ allOf: FormFieldCondition[];
530
+ };
531
+
532
+ /**
533
+ * A single leaf comparison. The field it guards becomes required exactly when the
534
+ * controlling `property` matches `value` against the answers collected so far:
496
535
  * - a single `value`, no `op` — equality (compared as strings);
497
536
  * - a single `value` with `op` — numeric comparison (both sides coerced to numbers);
498
537
  * - an array `value`, no `op` — "one of": matches when the property equals any
499
538
  * listed value.
500
- *
501
- * SDK-only — it is stripped from the schema before it reaches the LLM tool
502
539
  */
503
- declare interface FormFieldCondition {
540
+ declare interface FormFieldLeafCondition {
504
541
  /** The controlling field whose value the rule tests. */
505
542
  property: string;
506
543
  /** Comparison operator; omitted means equality. Ignored when `value` is an array. */
@@ -521,7 +558,8 @@ declare interface FormFieldSchema {
521
558
  default?: unknown;
522
559
  /**
523
560
  * Makes the field required only while this condition holds. Drives the dynamic
524
- * `missing` list; stripped before the LLM tool — see {@link toWireParameters}.
561
+ * `missing` list; stripped from the LLM tool's `parameters` (still sent to the
562
+ * agent via dynamic context). See {@link toWireParameters}.
525
563
  */
526
564
  requiredWhen?: FormFieldCondition;
527
565
  }
@@ -176,6 +176,7 @@ declare class AgoClient {
176
176
  * call it when their store updates so observers like the dev panel stay live.
177
177
  */
178
178
  notifyContextChanged(): void;
179
+ /* Excluded from this release type: emitFormEvent */
179
180
  /**
180
181
  * Enable automatic capture of the current browser page (URL + title).
181
182
  * Injected as a dynamic context entry named `browser-page`.
@@ -290,6 +291,27 @@ declare interface AgoClientEvents {
290
291
  result: unknown;
291
292
  error?: string;
292
293
  };
294
+ /**
295
+ * A form collector submitted successfully. `result` is the raw submit response
296
+ * (POST body / handler return value / backend relay result) — the third-party
297
+ * API's answer. `values` is the submitted field set, `name` the collector name.
298
+ */
299
+ "form:submitted": {
300
+ name: string;
301
+ values: Record<string, unknown>;
302
+ result: unknown;
303
+ };
304
+ /**
305
+ * A form collector submit was attempted and failed at the network/server level
306
+ * (HTTP non-2xx, or a thrown handler/fetch). `error` is the message. Validation
307
+ * pre-checks (missing required fields, no submit target) are NOT errors and do
308
+ * not fire this — they are returned to the caller as `{ ok: false }`.
309
+ */
310
+ "form:error": {
311
+ name: string;
312
+ values: Record<string, unknown>;
313
+ error: string;
314
+ };
293
315
  "connection:status": {
294
316
  connected: boolean;
295
317
  };
@@ -473,7 +495,7 @@ declare interface FormCollectorDefinition<V = Record<string, unknown>> {
473
495
 
474
496
  /**
475
497
  * Shape of a form's fields. Mirrors a client function's `parameters` (so the same
476
- * object feeds the store, the update function, and the dynamic context). Additionally allows the SDK-only per-field `requiredWhen`, which {@link toWireParameters} removes before the schema reaches the LLM.
498
+ * object feeds the store, the update function, and the dynamic context). Additionally allows the SDK-only per-field `requiredWhen`, which {@link toWireParameters} removes from the LLM tool's `parameters` (the full schema still reaches the agent via dynamic context).
477
499
  */
478
500
  declare interface FormCollectorSchema {
479
501
  type: "object";
@@ -490,17 +512,32 @@ declare interface FormField {
490
512
  }
491
513
 
492
514
  /**
493
- * A field's conditional-requiredness rule. The field becomes required exactly
494
- * when the controlling `property` matches `value` against the answers collected
495
- * so far:
515
+ * A field's conditional-requiredness rule: either a single {@link FormFieldLeafCondition}
516
+ * or a boolean combination of rules. `anyOf` is OR (true when any nested rule
517
+ * holds); `allOf` is AND (true when every nested rule holds). Both nest
518
+ * arbitrarily, so you can mix them, e.g.
519
+ * `{ anyOf: [{ property: "a", op: ">=", value: 1 }, { property: "b", value: "1" }] }`.
520
+ * An empty `anyOf` is never required; an empty `allOf` is always required.
521
+ *
522
+ * Stripped from the LLM tool's `parameters` (see {@link toWireParameters}), but the
523
+ * full schema, `requiredWhen` included, still reaches the agent via the dynamic
524
+ * context so it knows when each field becomes required.
525
+ */
526
+ declare type FormFieldCondition = FormFieldLeafCondition | {
527
+ anyOf: FormFieldCondition[];
528
+ } | {
529
+ allOf: FormFieldCondition[];
530
+ };
531
+
532
+ /**
533
+ * A single leaf comparison. The field it guards becomes required exactly when the
534
+ * controlling `property` matches `value` against the answers collected so far:
496
535
  * - a single `value`, no `op` — equality (compared as strings);
497
536
  * - a single `value` with `op` — numeric comparison (both sides coerced to numbers);
498
537
  * - an array `value`, no `op` — "one of": matches when the property equals any
499
538
  * listed value.
500
- *
501
- * SDK-only — it is stripped from the schema before it reaches the LLM tool
502
539
  */
503
- declare interface FormFieldCondition {
540
+ declare interface FormFieldLeafCondition {
504
541
  /** The controlling field whose value the rule tests. */
505
542
  property: string;
506
543
  /** Comparison operator; omitted means equality. Ignored when `value` is an array. */
@@ -521,7 +558,8 @@ declare interface FormFieldSchema {
521
558
  default?: unknown;
522
559
  /**
523
560
  * Makes the field required only while this condition holds. Drives the dynamic
524
- * `missing` list; stripped before the LLM tool — see {@link toWireParameters}.
561
+ * `missing` list; stripped from the LLM tool's `parameters` (still sent to the
562
+ * agent via dynamic context). See {@link toWireParameters}.
525
563
  */
526
564
  requiredWhen?: FormFieldCondition;
527
565
  }
package/dist/index.cjs CHANGED
@@ -1 +1 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const n=require("./AgoClient--y10UXUV.cjs"),m=require("./createFormCollector-DWzGKDwO.cjs"),p=require("./createConversationSession-BuMXp0Ia.cjs"),w=require("./createMockClient-zHQ0cjUH.cjs");require("./testing.cjs");const g=require("./functions-Djnq-JAo.cjs");function h(e){return e}function E(e,o){return e.on("message:complete",o),()=>e.off("message:complete",o)}function S(e,o){return e.on("message:chunk",o),()=>e.off("message:chunk",o)}function y(e,o){return e.on("message:start",o),()=>e.off("message:start",o)}function v(e,o){return e.on("message:error",o),()=>e.off("message:error",o)}function b(e,o){return e.on("toolCall:received",o),()=>e.off("toolCall:received",o)}function F(e,o){return e.on("function:invoke",o),()=>e.off("function:invoke",o)}async function*M(e,o,l){const a=[];let r=null,s=!1;const c=i=>{a.push(i),r?.()},f=i=>c({type:"start",data:i}),t=i=>c({type:"chunk",data:i}),u=i=>{c({type:"complete",data:i}),s=!0,r?.()},d=i=>{c({type:"error",data:i}),s=!0,r?.()},C=i=>c({type:"toolCall",data:i});e.on("message:start",f),e.on("message:chunk",t),e.on("message:complete",u),e.on("message:error",d),e.on("toolCall:received",C),e.sendMessage(o,l).catch(()=>{s=!0,r?.()});try{for(;!s||a.length>0;)a.length>0?yield a.shift():(await new Promise(i=>{r=i}),r=null)}finally{e.off("message:start",f),e.off("message:chunk",t),e.off("message:complete",u),e.off("message:error",d),e.off("toolCall:received",C)}}function A(e){let o,l,a,r,s,c;if(typeof window<"u"&&window.AGO){const t=window.AGO;o=t.basepath,l=t.widgetId,a=t.agent||t.defaultAgent,r=t.permission,s=t.email,c=t.jwt}if(typeof document<"u"){const t=u=>document.querySelector(`meta[name="${u}"]`)?.getAttribute("content")||void 0;o=o||t("ago-base-url"),l=l||t("ago-widget-id"),a=a||t("ago-agent")||t("ago-agent-id"),r=r||t("ago-permission"),s=s||t("ago-user-email")}if(typeof document<"u"){const t=[document.body,...Array.from(document.querySelectorAll("script[data-ago-base-url]"))].filter(Boolean);for(const u of t)u&&(o=o||u.getAttribute("data-ago-base-url")||void 0,l=l||u.getAttribute("data-ago-widget-id")||void 0,a=a||u.getAttribute("data-ago-agent")||u.getAttribute("data-ago-agent-id")||void 0,r=r||u.getAttribute("data-ago-permission")||void 0,s=s||u.getAttribute("data-ago-user-email")||void 0)}o=e?.baseUrl||o,l=e?.widgetId||l,a=e?.agent||e?.defaultAgentId||a,r=e?.permission||r,s=e?.userEmail||s,c=e?.userJwt||c;const f=e?.debug;return o?{baseUrl:o,widgetId:l,agent:a,permission:r,userEmail:s,userJwt:c,debug:f}:null}function k(e){const o=A(e);if(!o)throw new n.AgoError('createAgo(): could not detect AGO configuration. Set window.AGO, add <meta name="ago-base-url">, or pass { baseUrl } explicitly.',"config_missing_base_url");return new n.AgoClient(o)}function q(e,o){return{...e,handler:o}}exports.AgoApiError=n.AgoApiError;exports.AgoClient=n.AgoClient;exports.AgoError=n.AgoError;exports.AgoFunctionError=n.AgoFunctionError;exports.AgoNetworkError=n.AgoNetworkError;exports.AgoStreamError=n.AgoStreamError;exports.ClientContextRegistry=n.ClientContextRegistry;exports.EventEmitter=n.EventEmitter;exports.FunctionRegistry=n.FunctionRegistry;exports.SSEHandler=n.SSEHandler;exports.autoDetectConfig=A;exports.copyToClipboard=g.copyToClipboard;exports.createAgo=k;exports.createConversationSession=p.createConversationSession;exports.createFormCollector=m.createFormCollector;exports.createMessageStream=M;exports.createMockClient=w.createMockClient;exports.createStore=m.createStore;exports.defineFunction=h;exports.deriveFormStatus=m.deriveFormStatus;exports.getLocalStorage=g.getLocalStorage;exports.getUserLocation=g.getUserLocation;exports.highlightElement=g.highlightElement;exports.isStreamNetworkError=n.isStreamNetworkError;exports.loadFormCollector=m.loadFormCollector;exports.logger=n.logger;exports.onFunctionInvoke=F;exports.onMessage=E;exports.onMessageChunk=S;exports.onMessageError=v;exports.onMessageStart=y;exports.onToolCall=b;exports.openUrl=g.openUrl;exports.scrollToElement=g.scrollToElement;exports.setLocalStorage=g.setLocalStorage;exports.setTheme=g.setTheme;exports.showConfirmDialog=g.showConfirmDialog;exports.showNotification=g.showNotification;exports.showToast=g.showToast;exports.submitForm=g.submitForm;exports.trackEvent=g.trackEvent;exports.validateConfig=n.validateConfig;exports.withHandler=q;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const n=require("./AgoClient-B3-WGVne.cjs"),f=require("./createFormCollector-BI3DXaew.cjs"),p=require("./createConversationSession-C0diFTUk.cjs"),w=require("./createMockClient-zHQ0cjUH.cjs");require("./testing.cjs");const g=require("./functions-Djnq-JAo.cjs");function h(e){return e}function E(e,o){return e.on("message:complete",o),()=>e.off("message:complete",o)}function S(e,o){return e.on("message:chunk",o),()=>e.off("message:chunk",o)}function y(e,o){return e.on("message:start",o),()=>e.off("message:start",o)}function b(e,o){return e.on("message:error",o),()=>e.off("message:error",o)}function F(e,o){return e.on("toolCall:received",o),()=>e.off("toolCall:received",o)}function v(e,o){return e.on("form:submitted",o),()=>e.off("form:submitted",o)}function M(e,o){return e.on("form:error",o),()=>e.off("form:error",o)}function q(e,o){return e.on("function:invoke",o),()=>e.off("function:invoke",o)}async function*k(e,o,l){const a=[];let r=null,s=!1;const m=i=>{a.push(i),r?.()},c=i=>m({type:"start",data:i}),t=i=>m({type:"chunk",data:i}),u=i=>{m({type:"complete",data:i}),s=!0,r?.()},d=i=>{m({type:"error",data:i}),s=!0,r?.()},C=i=>m({type:"toolCall",data:i});e.on("message:start",c),e.on("message:chunk",t),e.on("message:complete",u),e.on("message:error",d),e.on("toolCall:received",C),e.sendMessage(o,l).catch(()=>{s=!0,r?.()});try{for(;!s||a.length>0;)a.length>0?yield a.shift():(await new Promise(i=>{r=i}),r=null)}finally{e.off("message:start",c),e.off("message:chunk",t),e.off("message:complete",u),e.off("message:error",d),e.off("toolCall:received",C)}}function A(e){let o,l,a,r,s,m;if(typeof window<"u"&&window.AGO){const t=window.AGO;o=t.basepath,l=t.widgetId,a=t.agent||t.defaultAgent,r=t.permission,s=t.email,m=t.jwt}if(typeof document<"u"){const t=u=>document.querySelector(`meta[name="${u}"]`)?.getAttribute("content")||void 0;o=o||t("ago-base-url"),l=l||t("ago-widget-id"),a=a||t("ago-agent")||t("ago-agent-id"),r=r||t("ago-permission"),s=s||t("ago-user-email")}if(typeof document<"u"){const t=[document.body,...Array.from(document.querySelectorAll("script[data-ago-base-url]"))].filter(Boolean);for(const u of t)u&&(o=o||u.getAttribute("data-ago-base-url")||void 0,l=l||u.getAttribute("data-ago-widget-id")||void 0,a=a||u.getAttribute("data-ago-agent")||u.getAttribute("data-ago-agent-id")||void 0,r=r||u.getAttribute("data-ago-permission")||void 0,s=s||u.getAttribute("data-ago-user-email")||void 0)}o=e?.baseUrl||o,l=e?.widgetId||l,a=e?.agent||e?.defaultAgentId||a,r=e?.permission||r,s=e?.userEmail||s,m=e?.userJwt||m;const c=e?.debug;return o?{baseUrl:o,widgetId:l,agent:a,permission:r,userEmail:s,userJwt:m,debug:c}:null}function T(e){const o=A(e);if(!o)throw new n.AgoError('createAgo(): could not detect AGO configuration. Set window.AGO, add <meta name="ago-base-url">, or pass { baseUrl } explicitly.',"config_missing_base_url");return new n.AgoClient(o)}function _(e,o){return{...e,handler:o}}exports.AgoApiError=n.AgoApiError;exports.AgoClient=n.AgoClient;exports.AgoError=n.AgoError;exports.AgoFunctionError=n.AgoFunctionError;exports.AgoNetworkError=n.AgoNetworkError;exports.AgoStreamError=n.AgoStreamError;exports.ClientContextRegistry=n.ClientContextRegistry;exports.EventEmitter=n.EventEmitter;exports.FunctionRegistry=n.FunctionRegistry;exports.SSEHandler=n.SSEHandler;exports.autoDetectConfig=A;exports.copyToClipboard=g.copyToClipboard;exports.createAgo=T;exports.createConversationSession=p.createConversationSession;exports.createFormCollector=f.createFormCollector;exports.createMessageStream=k;exports.createMockClient=w.createMockClient;exports.createStore=f.createStore;exports.defineFunction=h;exports.deriveFormStatus=f.deriveFormStatus;exports.getLocalStorage=g.getLocalStorage;exports.getUserLocation=g.getUserLocation;exports.highlightElement=g.highlightElement;exports.isStreamNetworkError=n.isStreamNetworkError;exports.loadFormCollector=f.loadFormCollector;exports.logger=n.logger;exports.onFormError=M;exports.onFormSubmitted=v;exports.onFunctionInvoke=q;exports.onMessage=E;exports.onMessageChunk=S;exports.onMessageError=b;exports.onMessageStart=y;exports.onToolCall=F;exports.openUrl=g.openUrl;exports.scrollToElement=g.scrollToElement;exports.setLocalStorage=g.setLocalStorage;exports.setTheme=g.setTheme;exports.showConfirmDialog=g.showConfirmDialog;exports.showNotification=g.showNotification;exports.showToast=g.showToast;exports.submitForm=g.submitForm;exports.trackEvent=g.trackEvent;exports.validateConfig=n.validateConfig;exports.withHandler=_;
package/dist/index.d.cts CHANGED
@@ -187,6 +187,7 @@ export declare class AgoClient {
187
187
  * call it when their store updates so observers like the dev panel stay live.
188
188
  */
189
189
  notifyContextChanged(): void;
190
+ /* Excluded from this release type: emitFormEvent */
190
191
  /**
191
192
  * Enable automatic capture of the current browser page (URL + title).
192
193
  * Injected as a dynamic context entry named `browser-page`.
@@ -301,6 +302,27 @@ export declare interface AgoClientEvents {
301
302
  result: unknown;
302
303
  error?: string;
303
304
  };
305
+ /**
306
+ * A form collector submitted successfully. `result` is the raw submit response
307
+ * (POST body / handler return value / backend relay result) — the third-party
308
+ * API's answer. `values` is the submitted field set, `name` the collector name.
309
+ */
310
+ "form:submitted": {
311
+ name: string;
312
+ values: Record<string, unknown>;
313
+ result: unknown;
314
+ };
315
+ /**
316
+ * A form collector submit was attempted and failed at the network/server level
317
+ * (HTTP non-2xx, or a thrown handler/fetch). `error` is the message. Validation
318
+ * pre-checks (missing required fields, no submit target) are NOT errors and do
319
+ * not fire this — they are returned to the caller as `{ ok: false }`.
320
+ */
321
+ "form:error": {
322
+ name: string;
323
+ values: Record<string, unknown>;
324
+ error: string;
325
+ };
304
326
  "connection:status": {
305
327
  connected: boolean;
306
328
  };
@@ -913,7 +935,7 @@ export declare interface FormCollectorDefinition<V = Record<string, unknown>> {
913
935
 
914
936
  /**
915
937
  * Shape of a form's fields. Mirrors a client function's `parameters` (so the same
916
- * object feeds the store, the update function, and the dynamic context). Additionally allows the SDK-only per-field `requiredWhen`, which {@link toWireParameters} removes before the schema reaches the LLM.
938
+ * object feeds the store, the update function, and the dynamic context). Additionally allows the SDK-only per-field `requiredWhen`, which {@link toWireParameters} removes from the LLM tool's `parameters` (the full schema still reaches the agent via dynamic context).
917
939
  */
918
940
  export declare interface FormCollectorSchema {
919
941
  type: "object";
@@ -953,17 +975,32 @@ export declare interface FormField {
953
975
  }
954
976
 
955
977
  /**
956
- * A field's conditional-requiredness rule. The field becomes required exactly
957
- * when the controlling `property` matches `value` against the answers collected
958
- * so far:
978
+ * A field's conditional-requiredness rule: either a single {@link FormFieldLeafCondition}
979
+ * or a boolean combination of rules. `anyOf` is OR (true when any nested rule
980
+ * holds); `allOf` is AND (true when every nested rule holds). Both nest
981
+ * arbitrarily, so you can mix them, e.g.
982
+ * `{ anyOf: [{ property: "a", op: ">=", value: 1 }, { property: "b", value: "1" }] }`.
983
+ * An empty `anyOf` is never required; an empty `allOf` is always required.
984
+ *
985
+ * Stripped from the LLM tool's `parameters` (see {@link toWireParameters}), but the
986
+ * full schema, `requiredWhen` included, still reaches the agent via the dynamic
987
+ * context so it knows when each field becomes required.
988
+ */
989
+ export declare type FormFieldCondition = FormFieldLeafCondition | {
990
+ anyOf: FormFieldCondition[];
991
+ } | {
992
+ allOf: FormFieldCondition[];
993
+ };
994
+
995
+ /**
996
+ * A single leaf comparison. The field it guards becomes required exactly when the
997
+ * controlling `property` matches `value` against the answers collected so far:
959
998
  * - a single `value`, no `op` — equality (compared as strings);
960
999
  * - a single `value` with `op` — numeric comparison (both sides coerced to numbers);
961
1000
  * - an array `value`, no `op` — "one of": matches when the property equals any
962
1001
  * listed value.
963
- *
964
- * SDK-only — it is stripped from the schema before it reaches the LLM tool
965
1002
  */
966
- declare interface FormFieldCondition {
1003
+ export declare interface FormFieldLeafCondition {
967
1004
  /** The controlling field whose value the rule tests. */
968
1005
  property: string;
969
1006
  /** Comparison operator; omitted means equality. Ignored when `value` is an array. */
@@ -977,14 +1014,15 @@ declare interface FormFieldCondition {
977
1014
  }
978
1015
 
979
1016
  /** A single field's schema: the wire-legal keys plus the SDK-only `requiredWhen`. */
980
- declare interface FormFieldSchema {
1017
+ export declare interface FormFieldSchema {
981
1018
  type: string;
982
1019
  description?: string;
983
1020
  enum?: string[];
984
1021
  default?: unknown;
985
1022
  /**
986
1023
  * Makes the field required only while this condition holds. Drives the dynamic
987
- * `missing` list; stripped before the LLM tool — see {@link toWireParameters}.
1024
+ * `missing` list; stripped from the LLM tool's `parameters` (still sent to the
1025
+ * agent via dynamic context). See {@link toWireParameters}.
988
1026
  */
989
1027
  requiredWhen?: FormFieldCondition;
990
1028
  }
@@ -1162,6 +1200,23 @@ export declare interface MockAgoClientOptions {
1162
1200
 
1163
1201
  declare type MockFn = (...args: any[]) => any;
1164
1202
 
1203
+ /**
1204
+ * Subscribe to failed form collector submissions (network/server failures).
1205
+ */
1206
+ export declare function onFormError(client: AgoClient, callback: (data: AgoClientEvents["form:error"]) => void): () => void;
1207
+
1208
+ /**
1209
+ * Subscribe to successful form collector submissions. `result` is the submit
1210
+ * response (the third-party API's answer). Returns an unsubscribe function.
1211
+ *
1212
+ * ```ts
1213
+ * const unsub = onFormSubmitted(client, ({ name, result }) => {
1214
+ * console.log(name, "submitted", result);
1215
+ * });
1216
+ * ```
1217
+ */
1218
+ export declare function onFormSubmitted(client: AgoClient, callback: (data: AgoClientEvents["form:submitted"]) => void): () => void;
1219
+
1165
1220
  /**
1166
1221
  * Subscribe to client function invocations.
1167
1222
  */