@useago/sdk 0.3.3 → 0.3.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.
package/dist/widget.js CHANGED
@@ -0,0 +1,398 @@
1
+ import { t as X } from "./AgoClient-DF7M2WAz.js";
2
+ import { t as Z } from "./createFormCollector-ClzHfaBd.js";
3
+ var G = '"IBM Plex Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif';
4
+ function m(l, o) {
5
+ Object.assign(l.style, o);
6
+ }
7
+ function c(l = {}) {
8
+ const o = document.createElement("div");
9
+ return m(o, l), o;
10
+ }
11
+ var P = "ago-chat-widget-keyframes";
12
+ function ee() {
13
+ if (typeof document > "u" || document.getElementById(P)) return;
14
+ const l = document.createElement("style");
15
+ l.id = P, l.textContent = "@keyframes ago-pulse { 0%, 80%, 100% { opacity: 0.3; transform: scale(0.8); } 40% { opacity: 1; transform: scale(1); } }", document.head.appendChild(l);
16
+ }
17
+ function te(l) {
18
+ const o = typeof l == "string" ? document.querySelector(l) : l;
19
+ if (!o) throw new Error(`mountChatWidget: target "${String(l)}" not found.`);
20
+ return o;
21
+ }
22
+ function ae(l, o) {
23
+ const { title: w = "Chat", welcomeMessage: I = "Hello! How can I help you today?", placeholder: R = "Type a message...", allowFiles: u = !1, height: x = 500, logoUrl: f, showAgentName: b = !1, forms: _, onFollowUpClick: k, onMessageSent: D, onMessageReceived: s } = o;
24
+ if (!o.client && !o.config?.baseUrl) throw new Error("mountChatWidget requires either `client` or `config` (with a baseUrl).");
25
+ const i = o.client ?? new X(o.config), z = te(l);
26
+ let g = o.conversationId, n = [], y = !1, v = null;
27
+ const N = c({
28
+ display: "flex",
29
+ flexDirection: "column",
30
+ height: typeof x == "number" ? `${x}px` : x,
31
+ border: "1px solid #dee3e8",
32
+ borderRadius: "16px",
33
+ overflow: "hidden",
34
+ backgroundColor: "#fff",
35
+ fontFamily: G,
36
+ boxShadow: "rgba(15, 15, 15, 0.08) 0px 2px 16px 0px"
37
+ });
38
+ N.className = "ago-chat-widget";
39
+ const W = c({
40
+ padding: "14px 16px",
41
+ borderBottom: "1px solid #dee3e8",
42
+ backgroundColor: "#03182f",
43
+ color: "#e8f0fe",
44
+ display: "flex",
45
+ alignItems: "center",
46
+ gap: "10px"
47
+ });
48
+ if (W.className = "ago-chat-widget__header", f) {
49
+ const e = document.createElement("img");
50
+ e.src = f, e.alt = "Logo", m(e, {
51
+ height: "24px",
52
+ width: "auto"
53
+ }), W.appendChild(e);
54
+ }
55
+ const F = document.createElement("h3");
56
+ F.textContent = w, m(F, {
57
+ margin: "0",
58
+ fontSize: "15px",
59
+ fontWeight: "600"
60
+ }), W.appendChild(F);
61
+ const E = c({
62
+ flex: "1",
63
+ overflow: "auto",
64
+ padding: "16px",
65
+ backgroundColor: "#fbfbfb"
66
+ });
67
+ E.className = "ago-chat-widget__messages";
68
+ const { inputRow: K, setDisabled: j, focus: q } = ne({
69
+ placeholder: R,
70
+ allowFiles: u,
71
+ onSend: (e, t) => {
72
+ L(e, t);
73
+ }
74
+ });
75
+ ee(), N.append(W, E, K), z.appendChild(N);
76
+ const U = k !== !1, A = k === !1 ? void 0 : k ?? ((e) => {
77
+ L(e);
78
+ });
79
+ function V(e) {
80
+ const t = e.role === "user", d = c({
81
+ display: "flex",
82
+ flexDirection: "column",
83
+ alignItems: t ? "flex-end" : "flex-start",
84
+ marginBottom: "16px"
85
+ });
86
+ if (d.className = `ago-message ago-message--${e.role}`, !t && b && e.agent) {
87
+ const a = c({
88
+ fontSize: "13px",
89
+ fontWeight: "500",
90
+ color: "#30373e",
91
+ marginBottom: "6px",
92
+ padding: "0 4px"
93
+ });
94
+ a.className = "ago-message__agent", a.textContent = e.agent.displayName || e.agent.name, d.appendChild(a);
95
+ }
96
+ if (!t && e.sources && e.sources.length > 0) {
97
+ const a = c({
98
+ display: "grid",
99
+ gridTemplateColumns: "1fr 1fr",
100
+ gap: "6px",
101
+ marginBottom: "10px",
102
+ width: "100%",
103
+ maxWidth: "85%"
104
+ });
105
+ a.className = "ago-message__sources", e.sources.forEach((p, r) => {
106
+ const C = p.url ? document.createElement("a") : document.createElement("div");
107
+ p.url && C instanceof HTMLAnchorElement && (C.href = p.url, C.target = "_blank", C.rel = "noopener noreferrer"), m(C, {
108
+ display: "flex",
109
+ alignItems: "center",
110
+ gap: "8px",
111
+ padding: "8px 10px",
112
+ border: "1px solid #dee3e8",
113
+ borderRadius: "8px",
114
+ backgroundColor: "#fff",
115
+ textDecoration: "none",
116
+ color: "#30373e",
117
+ fontSize: "12px",
118
+ overflow: "hidden"
119
+ });
120
+ const $ = c({
121
+ flexShrink: "0",
122
+ width: "18px",
123
+ height: "18px",
124
+ borderRadius: "3px",
125
+ border: "1px solid #1b5fc4",
126
+ color: "#1b5fc4",
127
+ fontSize: "11px",
128
+ fontWeight: "500",
129
+ display: "flex",
130
+ alignItems: "center",
131
+ justifyContent: "center",
132
+ backgroundColor: "#f0f4ff"
133
+ });
134
+ $.textContent = String(r + 1);
135
+ const M = c({
136
+ overflow: "hidden",
137
+ textOverflow: "ellipsis",
138
+ whiteSpace: "nowrap"
139
+ });
140
+ M.textContent = p.title, M.title = p.title, C.append($, M), a.appendChild(C);
141
+ }), d.appendChild(a);
142
+ }
143
+ const h = c({
144
+ maxWidth: t ? "75%" : "100%",
145
+ padding: t ? "10px 14px" : "2px 8px",
146
+ borderRadius: t ? "16px" : "0",
147
+ backgroundColor: t ? "#03182f" : "transparent",
148
+ color: t ? "#fff" : "#30373e",
149
+ wordBreak: "break-word",
150
+ fontSize: "14px",
151
+ lineHeight: "1.6",
152
+ whiteSpace: "pre-wrap"
153
+ });
154
+ if (h.className = "ago-message__content", e.content ? h.textContent = e.content : e.status === "IN_PROGRESS" && h.appendChild(Q()), d.appendChild(h), e.followUpReplies && e.followUpReplies.length > 0) {
155
+ const a = c({
156
+ display: "flex",
157
+ flexWrap: "wrap",
158
+ gap: "8px",
159
+ marginTop: "10px"
160
+ });
161
+ a.className = "ago-message__followups";
162
+ for (const p of e.followUpReplies) {
163
+ const r = document.createElement("button");
164
+ r.type = "button", r.className = "ago-message__followup-btn", r.textContent = p, r.disabled = !U, m(r, {
165
+ padding: "6px 14px",
166
+ fontSize: "13px",
167
+ borderRadius: "16px",
168
+ border: "1px solid #dee3e8",
169
+ backgroundColor: "#fff",
170
+ color: "#30373e",
171
+ cursor: U ? "pointer" : "default",
172
+ transition: "border-color 0.15s"
173
+ }), A && r.addEventListener("click", () => A(p)), r.addEventListener("mouseenter", () => {
174
+ r.style.borderColor = "#1b5fc4";
175
+ }), r.addEventListener("mouseleave", () => {
176
+ r.style.borderColor = "#dee3e8";
177
+ }), a.appendChild(r);
178
+ }
179
+ d.appendChild(a);
180
+ }
181
+ return d;
182
+ }
183
+ function S() {
184
+ if (E.replaceChildren(), n.length === 0) {
185
+ const e = c({
186
+ textAlign: "center",
187
+ color: "#6b6d6f",
188
+ padding: "24px 16px",
189
+ fontSize: "14px",
190
+ lineHeight: "1.5"
191
+ });
192
+ e.textContent = I, E.appendChild(e);
193
+ } else for (const e of n) E.appendChild(V(e));
194
+ if (v) {
195
+ const e = c({
196
+ padding: "10px 14px",
197
+ backgroundColor: "#fef2f2",
198
+ color: "#dc2626",
199
+ borderRadius: "12px",
200
+ marginTop: "8px",
201
+ fontSize: "13px",
202
+ border: "1px solid #fecaca"
203
+ });
204
+ e.textContent = v, E.appendChild(e);
205
+ }
206
+ E.scrollTop = E.scrollHeight, j(y);
207
+ }
208
+ function Y() {
209
+ for (let e = n.length - 1; e >= 0; e--) {
210
+ const t = n[e];
211
+ if (t.role === "assistant" && t.status === "IN_PROGRESS") return t;
212
+ }
213
+ }
214
+ const B = (e) => {
215
+ g || (g = e.conversationId);
216
+ }, H = (e) => {
217
+ const t = Y();
218
+ t && (t.content += e.content, S());
219
+ }, O = (e) => {
220
+ const t = n.findIndex((d) => d.id === e.id || d.role === "assistant" && d.status === "IN_PROGRESS");
221
+ t >= 0 ? n[t] = e : n.push(e), y = !1, S(), e.status === "DONE" && s?.({
222
+ id: e.id,
223
+ content: e.content
224
+ });
225
+ }, T = (e) => {
226
+ v = e.error, y = !1, n = n.filter((t) => !t.id.startsWith("temp-")), S();
227
+ };
228
+ i.on("message:start", B), i.on("message:chunk", H), i.on("message:complete", O), i.on("message:error", T);
229
+ const J = (_ ?? []).map((e) => Z(e).install(i));
230
+ async function L(e, t) {
231
+ const d = e.trim();
232
+ if (!d && !t?.length || y) return;
233
+ D?.(d), y = !0, v = null;
234
+ const h = Date.now();
235
+ n.push({
236
+ id: `temp-user-${h}`,
237
+ conversationId: g || "",
238
+ content: d,
239
+ role: "user",
240
+ status: "DONE",
241
+ createdAt: /* @__PURE__ */ new Date()
242
+ }), n.push({
243
+ id: `temp-assistant-${h}`,
244
+ conversationId: g || "",
245
+ content: "",
246
+ role: "assistant",
247
+ status: "IN_PROGRESS",
248
+ createdAt: /* @__PURE__ */ new Date()
249
+ }), S();
250
+ try {
251
+ const a = await i.sendMessage(d, {
252
+ conversationId: g,
253
+ files: t
254
+ });
255
+ a.conversationId && !g && (g = a.conversationId);
256
+ const p = n.find((r) => r.id === `temp-user-${h}`);
257
+ if (p && (p.id = `user-${h}`, p.conversationId = a.conversationId), !n.some((r) => r.id === a.id)) {
258
+ const r = n.findIndex((C) => C.id === `temp-assistant-${h}`);
259
+ r >= 0 ? n[r] = a : n.push(a);
260
+ }
261
+ n = n.filter((r) => !r.id.startsWith("temp-")), y = !1, S();
262
+ } catch (a) {
263
+ v = a instanceof Error ? a.message : "Failed to send message", y = !1, n = n.filter((p) => !p.id.startsWith("temp-")), S();
264
+ }
265
+ }
266
+ return S(), q(), {
267
+ client: i,
268
+ element: N,
269
+ sendMessage: L,
270
+ destroy() {
271
+ i.off("message:start", B), i.off("message:chunk", H), i.off("message:complete", O), i.off("message:error", T), J.forEach((e) => e()), N.remove(), o.client || i.destroy();
272
+ }
273
+ };
274
+ function Q() {
275
+ const e = c({
276
+ display: "flex",
277
+ gap: "4px",
278
+ padding: "4px 0"
279
+ });
280
+ for (let t = 0; t < 3; t++) {
281
+ const d = c({
282
+ width: "6px",
283
+ height: "6px",
284
+ borderRadius: "50%",
285
+ backgroundColor: "#b5bfc8",
286
+ animation: "ago-pulse 1.2s ease-in-out infinite",
287
+ animationDelay: `${t * 0.2}s`
288
+ });
289
+ e.appendChild(d);
290
+ }
291
+ return e;
292
+ }
293
+ }
294
+ function ne(l) {
295
+ let o = [];
296
+ const w = document.createElement("form");
297
+ m(w, {
298
+ display: "flex",
299
+ flexDirection: "column",
300
+ gap: "8px",
301
+ padding: "12px",
302
+ borderTop: "1px solid #dee3e8",
303
+ backgroundColor: "#fff"
304
+ }), w.className = "ago-chat-input";
305
+ const I = c({
306
+ display: "flex",
307
+ flexWrap: "wrap",
308
+ gap: "6px"
309
+ }), R = c({
310
+ display: "flex",
311
+ gap: "8px",
312
+ alignItems: "flex-end"
313
+ }), u = document.createElement("textarea");
314
+ u.placeholder = l.placeholder, u.rows = 1, m(u, {
315
+ flex: "1",
316
+ resize: "none",
317
+ padding: "10px 12px",
318
+ border: "1px solid #dee3e8",
319
+ borderRadius: "12px",
320
+ fontSize: "14px",
321
+ fontFamily: G,
322
+ lineHeight: "1.4",
323
+ maxHeight: "120px",
324
+ outline: "none"
325
+ });
326
+ const x = document.createElement("button");
327
+ x.type = "submit", x.textContent = "Send", m(x, {
328
+ padding: "10px 16px",
329
+ border: "none",
330
+ borderRadius: "12px",
331
+ backgroundColor: "#03182f",
332
+ color: "#fff",
333
+ fontSize: "14px",
334
+ fontWeight: "500",
335
+ cursor: "pointer"
336
+ });
337
+ let f = null, b = null;
338
+ l.allowFiles && (f = document.createElement("input"), f.type = "file", f.multiple = !0, m(f, { display: "none" }), b = document.createElement("button"), b.type = "button", b.textContent = "📎", m(b, {
339
+ padding: "10px 12px",
340
+ border: "1px solid #dee3e8",
341
+ borderRadius: "12px",
342
+ backgroundColor: "#fff",
343
+ cursor: "pointer",
344
+ fontSize: "14px"
345
+ }), b.addEventListener("click", () => f?.click()), f.addEventListener("change", () => {
346
+ o = [...o, ...Array.from(f?.files ?? [])], _();
347
+ }));
348
+ function _() {
349
+ I.replaceChildren(), o.forEach((s, i) => {
350
+ const z = c({
351
+ display: "flex",
352
+ alignItems: "center",
353
+ gap: "4px",
354
+ padding: "4px 8px",
355
+ backgroundColor: "#f0f4ff",
356
+ border: "1px solid #dee3e8",
357
+ borderRadius: "8px",
358
+ fontSize: "12px"
359
+ }), g = document.createElement("span");
360
+ g.textContent = s.name;
361
+ const n = document.createElement("button");
362
+ n.type = "button", n.textContent = "×", m(n, {
363
+ border: "none",
364
+ background: "transparent",
365
+ cursor: "pointer",
366
+ fontSize: "14px",
367
+ lineHeight: "1"
368
+ }), n.addEventListener("click", () => {
369
+ o = o.filter((y, v) => v !== i), _();
370
+ }), z.append(g, n), I.appendChild(z);
371
+ });
372
+ }
373
+ const k = () => {
374
+ const s = u.value, i = o;
375
+ return u.value = "", o = [], _(), {
376
+ content: s,
377
+ files: i
378
+ };
379
+ }, D = () => {
380
+ const { content: s, files: i } = k();
381
+ (s.trim() || i.length > 0) && l.onSend(s.trim(), i.length > 0 ? i : void 0);
382
+ };
383
+ return w.addEventListener("submit", (s) => {
384
+ s.preventDefault(), D();
385
+ }), u.addEventListener("keydown", (s) => {
386
+ s.key === "Enter" && !s.shiftKey && (s.preventDefault(), D());
387
+ }), b && R.appendChild(b), R.append(u, x), f && w.appendChild(f), w.append(I, R), {
388
+ inputRow: w,
389
+ getValueAndClear: k,
390
+ setDisabled: (s) => {
391
+ u.disabled = s, x.disabled = s, x.style.opacity = s ? "0.6" : "1", x.style.cursor = s ? "not-allowed" : "pointer";
392
+ },
393
+ focus: () => u.focus()
394
+ };
395
+ }
396
+ export {
397
+ ae as mountChatWidget
398
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@useago/sdk",
3
- "version": "0.3.3",
3
+ "version": "0.3.4",
4
4
  "description": "JavaScript SDK for AGO Chat integration",
5
5
  "type": "module",
6
6
  "sideEffects": false,
@@ -1,254 +0,0 @@
1
- import { s as _ } from "./AgoClient-DF7M2WAz.js";
2
- function N(d, n) {
3
- const f = n ? n.storage ?? (typeof localStorage < "u" ? localStorage : void 0) : void 0;
4
- let m = d;
5
- if (n && f) try {
6
- const a = f.getItem(n.key);
7
- a != null && (m = JSON.parse(a));
8
- } catch {
9
- }
10
- const t = /* @__PURE__ */ new Set(), h = () => t.forEach((a) => a(m));
11
- function v() {
12
- if (n && f) try {
13
- f.setItem(n.key, JSON.stringify(m));
14
- } catch {
15
- }
16
- }
17
- return {
18
- get: () => m,
19
- set: (a) => {
20
- m = a, v(), h();
21
- },
22
- subscribe: (a) => (t.add(a), () => {
23
- t.delete(a);
24
- })
25
- };
26
- }
27
- var S = /^[a-zA-Z0-9_-]{1,40}$/;
28
- function E(d) {
29
- const { name: n, description: f, schema: m } = d;
30
- if (!S.test(n)) throw new Error(`Invalid form collector name "${n}": must match ${S} (it becomes the update_/submit_ function names).`);
31
- const t = typeof d.submit == "string" ? d.submit ? {
32
- via: "client",
33
- url: d.submit
34
- } : !1 : d.submit ?? !1, h = m.properties ?? {}, v = m.required ?? [], a = (e) => e == null || e === "", s = (e) => v.filter((o) => a(e[o])), i = (e) => {
35
- const o = {};
36
- for (const [l, r] of Object.entries(e)) {
37
- const b = h[l];
38
- if (b)
39
- if (r == null) o[l] = r;
40
- else if (b.type === "number" || b.type === "integer") {
41
- const F = typeof r == "number" ? r : Number(r);
42
- o[l] = Number.isNaN(F) ? r : F;
43
- } else b.type === "boolean" ? o[l] = typeof r == "boolean" ? r : r === "true" ? !0 : r === "false" ? !1 : !!r : o[l] = r;
44
- }
45
- return o;
46
- }, c = d.initialValues ?? {}, g = s(c), u = N({
47
- values: c,
48
- missing: g,
49
- complete: g.length === 0,
50
- submitted: !1
51
- }), y = (e) => {
52
- const o = u.get(), l = {
53
- ...o.values,
54
- ...e
55
- }, r = s(l), b = {
56
- ...o,
57
- values: l,
58
- missing: r,
59
- complete: r.length === 0
60
- };
61
- return u.set(b), b;
62
- };
63
- let p = null;
64
- const C = async () => {
65
- const e = u.get();
66
- if (!e.complete) return {
67
- ok: !1,
68
- missing: e.missing
69
- };
70
- if (!t) return {
71
- ok: !1,
72
- error: "No submit target configured for this form collector."
73
- };
74
- const o = e.values;
75
- try {
76
- let l;
77
- if (t.via === "client") if ("handler" in t) l = await t.handler(o);
78
- else {
79
- const r = await fetch(t.url, {
80
- method: "POST",
81
- headers: { "Content-Type": "application/json" },
82
- credentials: "include",
83
- body: JSON.stringify(o)
84
- });
85
- if (!r.ok) return {
86
- ok: !1,
87
- error: `Submit failed: HTTP ${r.status}`
88
- };
89
- l = await r.json().catch(() => {
90
- });
91
- }
92
- else {
93
- if (!p) return {
94
- ok: !1,
95
- error: "Backend submit requires install(client) (or useFormCollector) first."
96
- };
97
- l = await p.submitFormCollector(t.destination, o);
98
- }
99
- return u.set({
100
- ...u.get(),
101
- submitted: !0
102
- }), {
103
- ok: !0,
104
- result: l
105
- };
106
- } catch (l) {
107
- const r = l instanceof Error ? l.message : "Submit failed";
108
- return _.error(`FormCollector "${n}" submit failed:`, l), {
109
- ok: !1,
110
- error: r
111
- };
112
- }
113
- }, k = [{
114
- name: `update_${n}`,
115
- description: `Fill or update fields of the "${n}" form. ${f} 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.`,
116
- parameters: {
117
- ...m,
118
- required: []
119
- },
120
- handler: (e) => {
121
- const o = y(i(e));
122
- return {
123
- ok: !0,
124
- values: o.values,
125
- missing: o.missing,
126
- complete: o.complete
127
- };
128
- }
129
- }];
130
- t && k.push({
131
- name: `submit_${n}`,
132
- description: `Submit the completed "${n}" 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.`,
133
- parameters: {
134
- type: "object",
135
- properties: {}
136
- },
137
- handler: () => C()
138
- });
139
- const w = `form:${n}`, $ = () => {
140
- const e = u.get(), o = t ? ` When all required fields are present and the user confirms, call submit_${n}.` : "";
141
- return {
142
- name: `Form: ${n}`,
143
- description: `Conversational form the assistant is helping fill. ${f} Use update_${n} to record fields; ask the user only for what is still missing.${o}`,
144
- data: {
145
- values: e.values,
146
- missing: e.missing,
147
- complete: e.complete,
148
- submitted: e.submitted
149
- }
150
- };
151
- };
152
- return {
153
- name: n,
154
- store: u,
155
- functions: k,
156
- contextKey: w,
157
- contextProvider: $,
158
- install: (e) => {
159
- p = e;
160
- for (const o of k) e.register(o);
161
- return e.addDynamicContext(w, $), () => {
162
- for (const o of k) e.unregisterFunction(o.name);
163
- e.removeDynamicContext(w), p === e && (p = null);
164
- };
165
- },
166
- submit: C,
167
- getValues: () => u.get().values,
168
- setValues: (e) => {
169
- y(i(e));
170
- },
171
- reset: () => {
172
- const e = s(c);
173
- u.set({
174
- values: c,
175
- missing: e,
176
- complete: e.length === 0,
177
- submitted: !1
178
- });
179
- }
180
- };
181
- }
182
- function O(d = {}) {
183
- const { overrides: n = {} } = d, f = {
184
- id: "mock-msg-1",
185
- conversationId: "mock-conv-1",
186
- content: "Mock response",
187
- role: "assistant",
188
- status: "DONE",
189
- createdAt: /* @__PURE__ */ new Date()
190
- }, m = {
191
- id: "mock-conv-1",
192
- title: "Mock Conversation",
193
- lastMessageDate: /* @__PURE__ */ new Date()
194
- }, t = /* @__PURE__ */ new Map(), h = [], v = {
195
- sendMessage: async () => f,
196
- getConversations: async () => [m],
197
- getConversation: async () => m,
198
- getMessages: async () => [f],
199
- submitToolCallForm: async () => {
200
- },
201
- confirmToolCall: async () => {
202
- },
203
- rejectToolCall: async () => {
204
- },
205
- submitFeedback: async () => {
206
- },
207
- registerFunction: () => {
208
- },
209
- unregisterFunction: () => !0,
210
- getRegisteredFunctions: () => [],
211
- registerNavigationFunction: () => {
212
- },
213
- on: (s, i) => {
214
- t.has(s) || t.set(s, /* @__PURE__ */ new Set()), t.get(s).add(i);
215
- },
216
- off: (s, i) => {
217
- t.get(s)?.delete(i);
218
- },
219
- once: (s, i) => {
220
- const c = (...g) => {
221
- t.get(s)?.delete(c), i(...g);
222
- };
223
- t.has(s) || t.set(s, /* @__PURE__ */ new Set()), t.get(s).add(c);
224
- },
225
- waitFor: (s, i) => new Promise((c, g) => {
226
- let u;
227
- const y = (p) => {
228
- u && clearTimeout(u), t.get(s)?.delete(y), c(p);
229
- };
230
- t.has(s) || t.set(s, /* @__PURE__ */ new Set()), t.get(s).add(y), i?.timeout && (u = setTimeout(() => {
231
- t.get(s)?.delete(y), g(/* @__PURE__ */ new Error(`waitFor("${s}") timed out after ${i.timeout}ms`));
232
- }, i.timeout));
233
- }),
234
- updateConfig: () => {
235
- },
236
- destroy: () => {
237
- t.clear();
238
- },
239
- ...n
240
- }, a = {};
241
- for (const [s, i] of Object.entries(v)) a[s] = (...c) => (h.push({
242
- method: s,
243
- args: c
244
- }), i(...c));
245
- return a.__calls = h, a.__callsFor = (s) => h.filter((i) => i.method === s), a.__emitEvent = (s, i) => {
246
- const c = t.get(s);
247
- c && [...c].forEach((g) => g(i));
248
- }, a;
249
- }
250
- export {
251
- E as n,
252
- N as r,
253
- O as t
254
- };
@@ -1 +0,0 @@
1
- const M=require("./AgoClient-bjN-z2ZQ.cjs");function _(f,n){const d=n?n.storage??(typeof localStorage<"u"?localStorage:void 0):void 0;let m=f;if(n&&d)try{const a=d.getItem(n.key);a!=null&&(m=JSON.parse(a))}catch{}const t=new Set,b=()=>t.forEach(a=>a(m));function v(){if(n&&d)try{d.setItem(n.key,JSON.stringify(m))}catch{}}return{get:()=>m,set:a=>{m=a,v(),b()},subscribe:a=>(t.add(a),()=>{t.delete(a)})}}var S=/^[a-zA-Z0-9_-]{1,40}$/;function N(f){const{name:n,description:d,schema:m}=f;if(!S.test(n))throw new Error(`Invalid form collector name "${n}": must match ${S} (it becomes the update_/submit_ function names).`);const t=typeof f.submit=="string"?f.submit?{via:"client",url:f.submit}:!1:f.submit??!1,b=m.properties??{},v=m.required??[],a=e=>e==null||e==="",s=e=>v.filter(r=>a(e[r])),i=e=>{const r={};for(const[c,o]of Object.entries(e)){const p=b[c];if(p)if(o==null)r[c]=o;else if(p.type==="number"||p.type==="integer"){const F=typeof o=="number"?o:Number(o);r[c]=Number.isNaN(F)?o:F}else p.type==="boolean"?r[c]=typeof o=="boolean"?o:o==="true"?!0:o==="false"?!1:!!o:r[c]=o}return r},l=f.initialValues??{},g=s(l),u=_({values:l,missing:g,complete:g.length===0,submitted:!1}),y=e=>{const r=u.get(),c={...r.values,...e},o=s(c),p={...r,values:c,missing:o,complete:o.length===0};return u.set(p),p};let h=null;const C=async()=>{const e=u.get();if(!e.complete)return{ok:!1,missing:e.missing};if(!t)return{ok:!1,error:"No submit target configured for this form collector."};const r=e.values;try{let c;if(t.via==="client")if("handler"in t)c=await t.handler(r);else{const o=await fetch(t.url,{method:"POST",headers:{"Content-Type":"application/json"},credentials:"include",body:JSON.stringify(r)});if(!o.ok)return{ok:!1,error:`Submit failed: HTTP ${o.status}`};c=await o.json().catch(()=>{})}else{if(!h)return{ok:!1,error:"Backend submit requires install(client) (or useFormCollector) first."};c=await h.submitFormCollector(t.destination,r)}return u.set({...u.get(),submitted:!0}),{ok:!0,result:c}}catch(c){const o=c instanceof Error?c.message:"Submit failed";return M.logger.error(`FormCollector "${n}" submit failed:`,c),{ok:!1,error:o}}},k=[{name:`update_${n}`,description:`Fill or update fields of the "${n}" form. ${d} 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.`,parameters:{...m,required:[]},handler:e=>{const r=y(i(e));return{ok:!0,values:r.values,missing:r.missing,complete:r.complete}}}];t&&k.push({name:`submit_${n}`,description:`Submit the completed "${n}" 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.`,parameters:{type:"object",properties:{}},handler:()=>C()});const w=`form:${n}`,$=()=>{const e=u.get(),r=t?` When all required fields are present and the user confirms, call submit_${n}.`:"";return{name:`Form: ${n}`,description:`Conversational form the assistant is helping fill. ${d} Use update_${n} to record fields; ask the user only for what is still missing.${r}`,data:{values:e.values,missing:e.missing,complete:e.complete,submitted:e.submitted}}};return{name:n,store:u,functions:k,contextKey:w,contextProvider:$,install:e=>{h=e;for(const r of k)e.register(r);return e.addDynamicContext(w,$),()=>{for(const r of k)e.unregisterFunction(r.name);e.removeDynamicContext(w),h===e&&(h=null)}},submit:C,getValues:()=>u.get().values,setValues:e=>{y(i(e))},reset:()=>{const e=s(l);u.set({values:l,missing:e,complete:e.length===0,submitted:!1})}}}function O(f={}){const{overrides:n={}}=f,d={id:"mock-msg-1",conversationId:"mock-conv-1",content:"Mock response",role:"assistant",status:"DONE",createdAt:new Date},m={id:"mock-conv-1",title:"Mock Conversation",lastMessageDate:new Date},t=new Map,b=[],v={sendMessage:async()=>d,getConversations:async()=>[m],getConversation:async()=>m,getMessages:async()=>[d],submitToolCallForm:async()=>{},confirmToolCall:async()=>{},rejectToolCall:async()=>{},submitFeedback:async()=>{},registerFunction:()=>{},unregisterFunction:()=>!0,getRegisteredFunctions:()=>[],registerNavigationFunction:()=>{},on:(s,i)=>{t.has(s)||t.set(s,new Set),t.get(s).add(i)},off:(s,i)=>{t.get(s)?.delete(i)},once:(s,i)=>{const l=(...g)=>{t.get(s)?.delete(l),i(...g)};t.has(s)||t.set(s,new Set),t.get(s).add(l)},waitFor:(s,i)=>new Promise((l,g)=>{let u;const y=h=>{u&&clearTimeout(u),t.get(s)?.delete(y),l(h)};t.has(s)||t.set(s,new Set),t.get(s).add(y),i?.timeout&&(u=setTimeout(()=>{t.get(s)?.delete(y),g(new Error(`waitFor("${s}") timed out after ${i.timeout}ms`))},i.timeout))}),updateConfig:()=>{},destroy:()=>{t.clear()},...n},a={};for(const[s,i]of Object.entries(v))a[s]=(...l)=>(b.push({method:s,args:l}),i(...l));return a.__calls=b,a.__callsFor=s=>b.filter(i=>i.method===s),a.__emitEvent=(s,i)=>{const l=t.get(s);l&&[...l].forEach(g=>g(i))},a}Object.defineProperty(exports,"createFormCollector",{enumerable:!0,get:function(){return N}});Object.defineProperty(exports,"createMockClient",{enumerable:!0,get:function(){return O}});Object.defineProperty(exports,"createStore",{enumerable:!0,get:function(){return _}});