@foisit/react-wrapper 2.4.2 → 2.4.5
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/README.md +63 -8
- package/index.js +88 -3
- package/index.mjs +442 -215
- package/lib/services/AssistantService.d.ts +10 -0
- package/package.json +22 -2
package/index.mjs
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { jsx as k } from "react/jsx-runtime";
|
|
2
|
-
import { createContext as F, useState as
|
|
3
|
-
const
|
|
2
|
+
import { createContext as F, useState as I, useEffect as $, useContext as N } from "react";
|
|
3
|
+
const O = {};
|
|
4
4
|
function Q() {
|
|
5
|
-
return /* @__PURE__ */ k("div", { className:
|
|
5
|
+
return /* @__PURE__ */ k("div", { className: O.container, children: /* @__PURE__ */ k("h1", { children: "Welcome to ReactWrapper!" }) });
|
|
6
6
|
}
|
|
7
|
-
class
|
|
7
|
+
class T {
|
|
8
8
|
constructor(t) {
|
|
9
9
|
this.endpoint = t || "https://foisit-ninja.netlify.app/.netlify/functions/intent";
|
|
10
10
|
}
|
|
@@ -12,11 +12,11 @@ class M {
|
|
|
12
12
|
try {
|
|
13
13
|
const s = {
|
|
14
14
|
userInput: t,
|
|
15
|
-
commands: e.map((
|
|
16
|
-
id:
|
|
17
|
-
command:
|
|
18
|
-
description:
|
|
19
|
-
parameters:
|
|
15
|
+
commands: e.map((o) => ({
|
|
16
|
+
id: o.id,
|
|
17
|
+
command: o.command,
|
|
18
|
+
description: o.description,
|
|
19
|
+
parameters: o.parameters
|
|
20
20
|
// Send param schemas to AI
|
|
21
21
|
})),
|
|
22
22
|
context: i
|
|
@@ -35,13 +35,13 @@ class M {
|
|
|
35
35
|
}
|
|
36
36
|
}
|
|
37
37
|
}
|
|
38
|
-
class
|
|
38
|
+
class z {
|
|
39
39
|
constructor(t = !0) {
|
|
40
40
|
if (this.commands = /* @__PURE__ */ new Map(), this.openAIService = null, this.context = null, this.pendingConfirmation = null, this.enableSmartIntent = !0, this.selectOptionsCache = /* @__PURE__ */ new Map(), typeof t == "boolean") {
|
|
41
|
-
this.enableSmartIntent = t, this.enableSmartIntent && (this.openAIService = new
|
|
41
|
+
this.enableSmartIntent = t, this.enableSmartIntent && (this.openAIService = new T());
|
|
42
42
|
return;
|
|
43
43
|
}
|
|
44
|
-
this.enableSmartIntent = t.enableSmartIntent ?? !0, this.enableSmartIntent && (this.openAIService = new
|
|
44
|
+
this.enableSmartIntent = t.enableSmartIntent ?? !0, this.enableSmartIntent && (this.openAIService = new T(t.intentEndpoint));
|
|
45
45
|
}
|
|
46
46
|
/** Add a new command (string or object) */
|
|
47
47
|
addCommand(t, e) {
|
|
@@ -66,14 +66,14 @@ class B {
|
|
|
66
66
|
async executeCommand(t) {
|
|
67
67
|
if (typeof t == "object" && t !== null) {
|
|
68
68
|
if (this.isStructured(t)) {
|
|
69
|
-
const c = String(t.commandId), f = t.params ?? {},
|
|
70
|
-
if (!
|
|
71
|
-
const p = this.sanitizeParamsForCommand(
|
|
72
|
-
return m.length > 0 ? (this.context = { commandId: this.getCommandIdentifier(
|
|
73
|
-
message: `Please provide the required details for "${
|
|
69
|
+
const c = String(t.commandId), f = t.params ?? {}, r = this.getCommandById(c);
|
|
70
|
+
if (!r) return { message: "That command is not available.", type: "error" };
|
|
71
|
+
const p = this.sanitizeParamsForCommand(r, f), m = (r.parameters ?? []).filter((C) => C.required).filter((C) => p[C.name] == null || p[C.name] === "");
|
|
72
|
+
return m.length > 0 ? (this.context = { commandId: this.getCommandIdentifier(r), params: p }, {
|
|
73
|
+
message: `Please provide the required details for "${r.command}".`,
|
|
74
74
|
type: "form",
|
|
75
75
|
fields: m
|
|
76
|
-
}) :
|
|
76
|
+
}) : r.critical ? (this.pendingConfirmation = { commandId: this.getCommandIdentifier(r), params: p }, this.buildConfirmResponse(r)) : this.safeRunAction(r, p);
|
|
77
77
|
}
|
|
78
78
|
if (!this.context)
|
|
79
79
|
return { message: "Session expired or invalid context.", type: "error" };
|
|
@@ -82,28 +82,28 @@ class B {
|
|
|
82
82
|
return this.context = null, { message: "Session expired or invalid context.", type: "error" };
|
|
83
83
|
if (Array.isArray(t))
|
|
84
84
|
return { message: "Invalid form payload.", type: "error" };
|
|
85
|
-
const
|
|
85
|
+
const a = {
|
|
86
86
|
...this.context.params,
|
|
87
87
|
...t
|
|
88
88
|
};
|
|
89
89
|
if (n.critical)
|
|
90
90
|
return this.context = null, this.pendingConfirmation = {
|
|
91
91
|
commandId: this.getCommandIdentifier(n),
|
|
92
|
-
params:
|
|
92
|
+
params: a
|
|
93
93
|
}, this.buildConfirmResponse(n);
|
|
94
|
-
const
|
|
95
|
-
return this.context = null, this.normalizeResponse(
|
|
94
|
+
const o = await this.safeRunAction(n, a);
|
|
95
|
+
return this.context = null, this.normalizeResponse(o);
|
|
96
96
|
}
|
|
97
97
|
const e = t.trim().toLowerCase();
|
|
98
98
|
if (this.pendingConfirmation) {
|
|
99
99
|
const n = e;
|
|
100
100
|
if (["yes", "y", "confirm", "ok", "okay"].includes(n)) {
|
|
101
|
-
const { commandId:
|
|
101
|
+
const { commandId: a, params: o } = this.pendingConfirmation;
|
|
102
102
|
this.pendingConfirmation = null;
|
|
103
|
-
const c = this.getCommandById(
|
|
104
|
-
return c ? this.safeRunAction(c,
|
|
103
|
+
const c = this.getCommandById(a);
|
|
104
|
+
return c ? this.safeRunAction(c, o) : { message: "That action is no longer available.", type: "error" };
|
|
105
105
|
}
|
|
106
|
-
return ["no", "n", "cancel", "stop"].includes(n) ? (this.pendingConfirmation = null, { message: "
|
|
106
|
+
return ["no", "n", "cancel", "stop"].includes(n) ? (this.pendingConfirmation = null, { message: "Cancelled.", type: "success" }) : {
|
|
107
107
|
message: "Please confirm: Yes or No.",
|
|
108
108
|
type: "confirm",
|
|
109
109
|
options: [
|
|
@@ -114,22 +114,25 @@ class B {
|
|
|
114
114
|
}
|
|
115
115
|
const i = this.commands.get(e);
|
|
116
116
|
if (i) {
|
|
117
|
-
const n = i
|
|
118
|
-
|
|
117
|
+
const n = i;
|
|
118
|
+
if (n.macro)
|
|
119
|
+
return this.safeRunAction(n, {});
|
|
120
|
+
const a = (n.parameters ?? []).filter((o) => o.required);
|
|
121
|
+
return a.length > 0 ? (this.context = { commandId: this.getCommandIdentifier(n), params: {} }, {
|
|
119
122
|
message: `Please provide the required details for "${n.command}".`,
|
|
120
123
|
type: "form",
|
|
121
|
-
fields:
|
|
124
|
+
fields: a
|
|
122
125
|
}) : n.critical ? (this.pendingConfirmation = { commandId: this.getCommandIdentifier(n), params: {} }, this.buildConfirmResponse(n)) : this.safeRunAction(n, {});
|
|
123
126
|
}
|
|
124
127
|
const s = await this.tryDeterministicMatch(e);
|
|
125
128
|
if (s) return s;
|
|
126
129
|
if (this.enableSmartIntent && this.openAIService) {
|
|
127
|
-
const n = await this.getCommandsForAI(),
|
|
130
|
+
const n = await this.getCommandsForAI(), a = await this.openAIService.determineIntent(
|
|
128
131
|
e,
|
|
129
132
|
n,
|
|
130
133
|
this.context
|
|
131
134
|
);
|
|
132
|
-
return this.handleAIResult(
|
|
135
|
+
return this.handleAIResult(a);
|
|
133
136
|
}
|
|
134
137
|
return this.enableSmartIntent ? this.listAllCommands() : { message: "I'm not sure what you mean.", type: "error" };
|
|
135
138
|
}
|
|
@@ -138,10 +141,12 @@ class B {
|
|
|
138
141
|
const e = this.getCommandById(t.match);
|
|
139
142
|
if (!e)
|
|
140
143
|
return { message: "I'm not sure what you mean.", type: "error" };
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
144
|
+
if (e.macro)
|
|
145
|
+
return this.safeRunAction(e, {});
|
|
146
|
+
const i = t.params ?? {}, s = this.sanitizeParamsForCommand(e, i), n = e.allowAiParamExtraction === !1 ? {} : s, o = (e.parameters ?? []).filter((f) => f.required).filter((f) => n[f.name] == null || n[f.name] === "");
|
|
147
|
+
if (t.incomplete || o.length > 0) {
|
|
148
|
+
if (this.context = { commandId: this.getCommandIdentifier(e), params: n }, !(e.collectRequiredViaForm !== !1) && this.shouldAskSingleQuestion(o)) {
|
|
149
|
+
const p = o.map((g) => g.name).join(" and ");
|
|
145
150
|
return {
|
|
146
151
|
message: t.message || `Please provide ${p}.`,
|
|
147
152
|
type: "question"
|
|
@@ -150,7 +155,7 @@ class B {
|
|
|
150
155
|
return {
|
|
151
156
|
message: t.message || `Please fill in the missing details for "${e.command}".`,
|
|
152
157
|
type: "form",
|
|
153
|
-
fields:
|
|
158
|
+
fields: o
|
|
154
159
|
};
|
|
155
160
|
}
|
|
156
161
|
if (e.critical)
|
|
@@ -180,52 +185,52 @@ class B {
|
|
|
180
185
|
delete i[s.name];
|
|
181
186
|
continue;
|
|
182
187
|
}
|
|
183
|
-
const
|
|
184
|
-
if (!
|
|
188
|
+
const a = n.trim();
|
|
189
|
+
if (!a) {
|
|
185
190
|
delete i[s.name];
|
|
186
191
|
continue;
|
|
187
192
|
}
|
|
188
|
-
i[s.name] =
|
|
193
|
+
i[s.name] = a;
|
|
189
194
|
}
|
|
190
195
|
if (s.type === "number") {
|
|
191
|
-
const
|
|
192
|
-
if (Number.isNaN(
|
|
196
|
+
const a = typeof n == "number" ? n : Number(n == null ? void 0 : n.toString().trim());
|
|
197
|
+
if (Number.isNaN(a)) {
|
|
193
198
|
delete i[s.name];
|
|
194
199
|
continue;
|
|
195
200
|
}
|
|
196
|
-
if (typeof s.min == "number" &&
|
|
201
|
+
if (typeof s.min == "number" && a < s.min) {
|
|
197
202
|
delete i[s.name];
|
|
198
203
|
continue;
|
|
199
204
|
}
|
|
200
|
-
if (typeof s.max == "number" &&
|
|
205
|
+
if (typeof s.max == "number" && a > s.max) {
|
|
201
206
|
delete i[s.name];
|
|
202
207
|
continue;
|
|
203
208
|
}
|
|
204
|
-
i[s.name] =
|
|
209
|
+
i[s.name] = a;
|
|
205
210
|
}
|
|
206
211
|
if (s.type === "date") {
|
|
207
|
-
const
|
|
208
|
-
if (typeof
|
|
209
|
-
const
|
|
210
|
-
this.isIsoDateString(
|
|
212
|
+
const a = i[s.name];
|
|
213
|
+
if (typeof a == "string") {
|
|
214
|
+
const o = a.trim();
|
|
215
|
+
this.isIsoDateString(o) ? i[s.name] = o : delete i[s.name];
|
|
211
216
|
} else
|
|
212
217
|
delete i[s.name];
|
|
213
218
|
}
|
|
214
219
|
if (s.type === "select") {
|
|
215
|
-
const
|
|
216
|
-
if (!
|
|
220
|
+
const a = typeof n == "string" ? n : n == null ? void 0 : n.toString();
|
|
221
|
+
if (!a) {
|
|
217
222
|
delete i[s.name];
|
|
218
223
|
continue;
|
|
219
224
|
}
|
|
220
|
-
if (Array.isArray(s.options) && s.options.length > 0 && !s.options.some((c) => String(c.value) === String(
|
|
225
|
+
if (Array.isArray(s.options) && s.options.length > 0 && !s.options.some((c) => String(c.value) === String(a))) {
|
|
221
226
|
delete i[s.name];
|
|
222
227
|
continue;
|
|
223
228
|
}
|
|
224
|
-
i[s.name] =
|
|
229
|
+
i[s.name] = a;
|
|
225
230
|
}
|
|
226
231
|
if (s.type === "file") {
|
|
227
|
-
const
|
|
228
|
-
(s.delivery ?? "file") === "base64" ? !c && !
|
|
232
|
+
const a = i[s.name], o = a && typeof a == "object" && typeof a.name == "string" && typeof a.size == "number", c = typeof a == "string" && /^data:[^;]+;base64,/.test(a);
|
|
233
|
+
(s.delivery ?? "file") === "base64" ? !c && !o && delete i[s.name] : o || delete i[s.name];
|
|
229
234
|
}
|
|
230
235
|
}
|
|
231
236
|
return i;
|
|
@@ -242,7 +247,7 @@ class B {
|
|
|
242
247
|
}
|
|
243
248
|
buildConfirmResponse(t) {
|
|
244
249
|
return {
|
|
245
|
-
message:
|
|
250
|
+
message: `Are you sure you want to run "${t.command}"?`,
|
|
246
251
|
type: "confirm",
|
|
247
252
|
options: [
|
|
248
253
|
{ label: "Yes", value: "yes" },
|
|
@@ -252,35 +257,35 @@ class B {
|
|
|
252
257
|
}
|
|
253
258
|
async tryDeterministicMatch(t) {
|
|
254
259
|
const e = [];
|
|
255
|
-
for (const
|
|
260
|
+
for (const o of this.commands.values()) {
|
|
256
261
|
let c = 0;
|
|
257
|
-
const f =
|
|
262
|
+
const f = o.command.toLowerCase();
|
|
258
263
|
t.includes(f) && (c += 5);
|
|
259
|
-
const
|
|
260
|
-
for (const p of
|
|
264
|
+
const r = o.keywords ?? [];
|
|
265
|
+
for (const p of r) {
|
|
261
266
|
const g = p.toLowerCase().trim();
|
|
262
267
|
g && (t === g ? c += 4 : t.includes(g) && (c += 3));
|
|
263
268
|
}
|
|
264
|
-
c > 0 && e.push({ cmd:
|
|
269
|
+
c > 0 && e.push({ cmd: o, score: c });
|
|
265
270
|
}
|
|
266
271
|
if (e.length === 0) return null;
|
|
267
|
-
e.sort((
|
|
268
|
-
const i = e[0].score, s = e.filter((
|
|
272
|
+
e.sort((o, c) => c.score - o.score);
|
|
273
|
+
const i = e[0].score, s = e.filter((o) => o.score === i).slice(0, 3);
|
|
269
274
|
if (s.length > 1)
|
|
270
275
|
return {
|
|
271
276
|
message: "I think you mean one of these. Which one should I run?",
|
|
272
277
|
type: "ambiguous",
|
|
273
|
-
options: s.map((
|
|
274
|
-
label:
|
|
275
|
-
value:
|
|
276
|
-
commandId:
|
|
278
|
+
options: s.map((o) => ({
|
|
279
|
+
label: o.cmd.command,
|
|
280
|
+
value: o.cmd.command,
|
|
281
|
+
commandId: o.cmd.id
|
|
277
282
|
}))
|
|
278
283
|
};
|
|
279
|
-
const n = s[0].cmd,
|
|
280
|
-
return
|
|
284
|
+
const n = s[0].cmd, a = (n.parameters ?? []).filter((o) => o.required);
|
|
285
|
+
return a.length > 0 ? (this.context = { commandId: this.getCommandIdentifier(n), params: {} }, {
|
|
281
286
|
message: `Please provide the required details for "${n.command}".`,
|
|
282
287
|
type: "form",
|
|
283
|
-
fields:
|
|
288
|
+
fields: a
|
|
284
289
|
}) : n.critical ? (this.pendingConfirmation = { commandId: this.getCommandIdentifier(n), params: {} }, this.buildConfirmResponse(n)) : this.safeRunAction(n, {});
|
|
285
290
|
}
|
|
286
291
|
async safeRunAction(t, e) {
|
|
@@ -301,14 +306,14 @@ class B {
|
|
|
301
306
|
e.parameters && await Promise.all(
|
|
302
307
|
e.parameters.map(async (i) => {
|
|
303
308
|
if (i.type !== "select" || !i.getOptions || i.options && i.options.length) return;
|
|
304
|
-
const s = `${e.id ?? e.command}:${i.name}`, n = this.selectOptionsCache.get(s),
|
|
305
|
-
if (n &&
|
|
309
|
+
const s = `${e.id ?? e.command}:${i.name}`, n = this.selectOptionsCache.get(s), a = Date.now();
|
|
310
|
+
if (n && a - n.ts < 6e4) {
|
|
306
311
|
i.options = n.options;
|
|
307
312
|
return;
|
|
308
313
|
}
|
|
309
314
|
try {
|
|
310
|
-
const
|
|
311
|
-
this.selectOptionsCache.set(s, { options:
|
|
315
|
+
const o = await i.getOptions();
|
|
316
|
+
this.selectOptionsCache.set(s, { options: o, ts: a }), i.options = o;
|
|
312
317
|
} catch {
|
|
313
318
|
}
|
|
314
319
|
})
|
|
@@ -345,21 +350,21 @@ class B {
|
|
|
345
350
|
return Array.from(this.commands.keys());
|
|
346
351
|
}
|
|
347
352
|
}
|
|
348
|
-
class
|
|
353
|
+
class P {
|
|
349
354
|
constructor() {
|
|
350
|
-
this.synth = window.speechSynthesis;
|
|
355
|
+
this.synth = typeof window < "u" ? window.speechSynthesis : null;
|
|
351
356
|
}
|
|
352
357
|
speak(t, e) {
|
|
353
358
|
if (!this.synth) {
|
|
354
|
-
console.error("SpeechSynthesis API is not supported in this
|
|
359
|
+
console.error("SpeechSynthesis API is not supported in this environment.");
|
|
355
360
|
return;
|
|
356
361
|
}
|
|
357
362
|
const i = new SpeechSynthesisUtterance(t);
|
|
358
|
-
e && (i.pitch = e.pitch || 1, i.rate = e.rate || 1, i.volume = e.volume || 1), i.onstart = () => {
|
|
363
|
+
e && (i.pitch = e.pitch || 1, i.rate = e.rate || 1, i.volume = e.volume || 1), typeof window < "u" && (i.onstart = () => {
|
|
359
364
|
window.dispatchEvent(new CustomEvent("foisit:tts-start"));
|
|
360
365
|
}, i.onend = () => {
|
|
361
366
|
console.log("Speech finished."), window.dispatchEvent(new CustomEvent("foisit:tts-end"));
|
|
362
|
-
}, i.onerror = (s) => {
|
|
367
|
+
}), i.onerror = (s) => {
|
|
363
368
|
console.error("Error during speech synthesis:", s.error);
|
|
364
369
|
}, this.synth.speak(i);
|
|
365
370
|
}
|
|
@@ -367,7 +372,7 @@ class q {
|
|
|
367
372
|
this.synth && this.synth.cancel();
|
|
368
373
|
}
|
|
369
374
|
}
|
|
370
|
-
class
|
|
375
|
+
class W {
|
|
371
376
|
constructor() {
|
|
372
377
|
this.fallbackMessage = "Sorry, I didn’t understand that.";
|
|
373
378
|
}
|
|
@@ -375,17 +380,18 @@ class z {
|
|
|
375
380
|
this.fallbackMessage = t;
|
|
376
381
|
}
|
|
377
382
|
handleFallback(t) {
|
|
378
|
-
t && console.log(`Fallback triggered for: "${t}"`), console.log(this.fallbackMessage), new
|
|
383
|
+
t && console.log(`Fallback triggered for: "${t}"`), console.log(this.fallbackMessage), new P().speak(this.fallbackMessage);
|
|
379
384
|
}
|
|
380
385
|
getFallbackMessage() {
|
|
381
386
|
return this.fallbackMessage;
|
|
382
387
|
}
|
|
383
388
|
}
|
|
384
|
-
const
|
|
389
|
+
const H = () => {
|
|
390
|
+
if (typeof window > "u") return null;
|
|
385
391
|
const d = window;
|
|
386
392
|
return d.SpeechRecognition ?? d.webkitSpeechRecognition ?? null;
|
|
387
393
|
};
|
|
388
|
-
class
|
|
394
|
+
class B {
|
|
389
395
|
constructor(t = "en-US", e = {}) {
|
|
390
396
|
this.recognition = null, this.isListening = !1, this.engineActive = !1, this.intentionallyStopped = !1, this.restartAllowed = !0, this.lastStart = 0, this.backoffMs = 250, this.destroyed = !1, this.resultCallback = null, this.ttsSpeaking = !1, this.debugEnabled = !0, this.restartTimer = null, this.prewarmed = !1, this.hadResultThisSession = !1, this.onTTSStart = () => {
|
|
391
397
|
var s;
|
|
@@ -398,7 +404,7 @@ class O {
|
|
|
398
404
|
}, this.onTTSEnd = () => {
|
|
399
405
|
this.ttsSpeaking = !1, this.isListening && this.restartAllowed ? this.safeRestart() : this.emitStatus(this.isListening ? "listening" : "idle");
|
|
400
406
|
};
|
|
401
|
-
const i =
|
|
407
|
+
const i = H();
|
|
402
408
|
if (i) {
|
|
403
409
|
this.recognition = new i(), this.recognition.lang = t, this.recognition.interimResults = e.interimResults ?? !0, this.recognition.continuous = e.continuous ?? !0, this.recognition.onresult = (n) => this.handleResult(n, e), this.recognition.onend = () => this.handleEnd(), this.recognition.onstart = () => {
|
|
404
410
|
this.log("recognition onstart"), this.engineActive = !0, this.hadResultThisSession = !1, this.restartTimer && (clearTimeout(this.restartTimer), this.restartTimer = null), this.backoffMs = 250, this.isListening && !this.ttsSpeaking && this.emitStatus("listening");
|
|
@@ -407,16 +413,16 @@ class O {
|
|
|
407
413
|
s.onaudiostart = () => this.log("onaudiostart"), s.onsoundstart = () => this.log("onsoundstart"), s.onspeechstart = () => this.log("onspeechstart"), s.onspeechend = () => this.log("onspeechend"), s.onsoundend = () => this.log("onsoundend"), s.onaudioend = () => this.log("onaudioend"), this.recognition.onerror = (n) => this.handleError(n);
|
|
408
414
|
} else
|
|
409
415
|
this.recognition = null, this.emitStatus("unsupported");
|
|
410
|
-
window.addEventListener("foisit:tts-start", this.onTTSStart), window.addEventListener("foisit:tts-end", this.onTTSEnd), this.visibilityHandler = () => {
|
|
416
|
+
typeof window < "u" ? (window.addEventListener("foisit:tts-start", this.onTTSStart), window.addEventListener("foisit:tts-end", this.onTTSEnd), this.visibilityHandler = () => {
|
|
411
417
|
var s;
|
|
412
|
-
if (document.hidden) {
|
|
418
|
+
if (typeof document < "u" && document.hidden) {
|
|
413
419
|
try {
|
|
414
420
|
(s = this.recognition) == null || s.stop();
|
|
415
421
|
} catch {
|
|
416
422
|
}
|
|
417
423
|
this.emitStatus(this.ttsSpeaking ? "speaking" : "idle");
|
|
418
424
|
} else this.isListening && !this.ttsSpeaking && this.safeRestart();
|
|
419
|
-
}, document.addEventListener("visibilitychange", this.visibilityHandler);
|
|
425
|
+
}, typeof document < "u" && document.addEventListener("visibilitychange", this.visibilityHandler)) : this.visibilityHandler = void 0;
|
|
420
426
|
}
|
|
421
427
|
// Debug logger helpers
|
|
422
428
|
log(t) {
|
|
@@ -430,7 +436,7 @@ class O {
|
|
|
430
436
|
}
|
|
431
437
|
/** Check if SpeechRecognition is available */
|
|
432
438
|
isSupported() {
|
|
433
|
-
return
|
|
439
|
+
return H() !== null;
|
|
434
440
|
}
|
|
435
441
|
/** Allow consumers (wrappers) to observe status changes */
|
|
436
442
|
onStatusChange(t) {
|
|
@@ -468,11 +474,11 @@ class O {
|
|
|
468
474
|
var s, n;
|
|
469
475
|
if (!this.resultCallback) return;
|
|
470
476
|
const i = e.confidenceThreshold ?? 0.6;
|
|
471
|
-
for (let
|
|
472
|
-
const
|
|
473
|
-
if (f && !(!
|
|
477
|
+
for (let a = t.resultIndex; a < t.results.length; a++) {
|
|
478
|
+
const o = t.results[a], c = o && o[0], f = ((n = (s = c == null ? void 0 : c.transcript) == null ? void 0 : s.trim) == null ? void 0 : n.call(s)) || "", r = (c == null ? void 0 : c.confidence) ?? 0;
|
|
479
|
+
if (f && !(!o.isFinal && e.interimResults === !1) && !(o.isFinal && r < i))
|
|
474
480
|
try {
|
|
475
|
-
this.hadResultThisSession = !0, this.resultCallback(f, !!
|
|
481
|
+
this.hadResultThisSession = !0, this.resultCallback(f, !!o.isFinal);
|
|
476
482
|
} catch {
|
|
477
483
|
this.error("VoiceProcessor: result callback error");
|
|
478
484
|
}
|
|
@@ -551,27 +557,29 @@ class O {
|
|
|
551
557
|
}
|
|
552
558
|
}
|
|
553
559
|
}
|
|
554
|
-
class
|
|
560
|
+
class R {
|
|
555
561
|
constructor() {
|
|
556
|
-
this.lastTap = 0;
|
|
562
|
+
this.lastTap = 0, this.tapCount = 0;
|
|
557
563
|
}
|
|
558
564
|
/**
|
|
559
|
-
* Sets up
|
|
560
|
-
* @param
|
|
565
|
+
* Sets up triple-click and triple-tap listeners
|
|
566
|
+
* @param onTripleClickOrTap Callback to execute when a triple-click or triple-tap is detected
|
|
561
567
|
*/
|
|
562
|
-
|
|
563
|
-
this.destroy(), this.
|
|
564
|
-
|
|
565
|
-
|
|
568
|
+
setupTripleTapListener(t) {
|
|
569
|
+
this.destroy(), this.clickListener = () => {
|
|
570
|
+
this.tapCount++, this.tapCount === 1 ? this.tapTimeout = window.setTimeout(() => {
|
|
571
|
+
this.tapCount = 0;
|
|
572
|
+
}, 500) : this.tapCount === 3 && (clearTimeout(this.tapTimeout), this.tapCount = 0, t());
|
|
573
|
+
}, document.addEventListener("click", this.clickListener), this.touchEndListener = () => {
|
|
566
574
|
const e = (/* @__PURE__ */ new Date()).getTime(), i = e - this.lastTap;
|
|
567
|
-
i <
|
|
575
|
+
i < 500 && i > 0 ? (this.tapCount++, this.tapCount === 3 && (this.tapCount = 0, t())) : this.tapCount = 1, this.lastTap = e;
|
|
568
576
|
}, document.addEventListener("touchend", this.touchEndListener);
|
|
569
577
|
}
|
|
570
578
|
destroy() {
|
|
571
|
-
this.dblClickListener && document.removeEventListener("dblclick", this.dblClickListener), this.touchEndListener && document.removeEventListener("touchend", this.touchEndListener), this.dblClickListener = void 0, this.touchEndListener = void 0;
|
|
579
|
+
this.dblClickListener && document.removeEventListener("dblclick", this.dblClickListener), this.touchEndListener && document.removeEventListener("touchend", this.touchEndListener), this.clickListener && document.removeEventListener("click", this.clickListener), this.tapTimeout && clearTimeout(this.tapTimeout), this.dblClickListener = void 0, this.touchEndListener = void 0, this.clickListener = void 0, this.tapTimeout = void 0, this.tapCount = 0;
|
|
572
580
|
}
|
|
573
581
|
}
|
|
574
|
-
function
|
|
582
|
+
function j() {
|
|
575
583
|
if (document.querySelector("#assistant-styles")) {
|
|
576
584
|
console.log("Styles already injected");
|
|
577
585
|
return;
|
|
@@ -612,17 +620,20 @@ function D() {
|
|
|
612
620
|
}
|
|
613
621
|
`, document.head.appendChild(t), console.log("Gradient styles injected");
|
|
614
622
|
}
|
|
615
|
-
function
|
|
623
|
+
function U() {
|
|
616
624
|
if (document.querySelector("#gradient-indicator"))
|
|
617
625
|
return;
|
|
618
626
|
const d = document.createElement("div");
|
|
619
|
-
d.id = "gradient-indicator",
|
|
627
|
+
d.id = "gradient-indicator", j(), d.classList.add("gradient-indicator"), document.body.appendChild(d), console.log("Gradient indicator added to the DOM");
|
|
620
628
|
}
|
|
621
|
-
function
|
|
629
|
+
function D() {
|
|
622
630
|
const d = document.querySelector("#gradient-indicator");
|
|
623
631
|
d && (d.remove(), console.log("Gradient indicator removed from the DOM"));
|
|
624
632
|
}
|
|
625
|
-
|
|
633
|
+
function V() {
|
|
634
|
+
return typeof window < "u" && typeof document < "u";
|
|
635
|
+
}
|
|
636
|
+
class _ {
|
|
626
637
|
constructor() {
|
|
627
638
|
this.state = "idle", this.subscribers = [];
|
|
628
639
|
}
|
|
@@ -630,7 +641,7 @@ class V {
|
|
|
630
641
|
return this.state;
|
|
631
642
|
}
|
|
632
643
|
setState(t) {
|
|
633
|
-
this.state = t, this.notifySubscribers(), console.log("State updated:", t), t === "listening" ?
|
|
644
|
+
this.state = t, this.notifySubscribers(), console.log("State updated:", t), t === "listening" ? U() : D();
|
|
634
645
|
}
|
|
635
646
|
// eslint-disable-next-line no-unused-vars
|
|
636
647
|
subscribe(t) {
|
|
@@ -642,7 +653,64 @@ class V {
|
|
|
642
653
|
}
|
|
643
654
|
class G {
|
|
644
655
|
constructor(t) {
|
|
645
|
-
this.container = null, this.chatWindow = null, this.messagesContainer = null, this.input = null, this.isOpen = !1, this.loadingEl = null, this.
|
|
656
|
+
this.container = null, this.chatWindow = null, this.messagesContainer = null, this.input = null, this.isOpen = !1, this.loadingEl = null, this.commandHandlers = /* @__PURE__ */ new Map(), this.active = V(), this.handleClickOutside = (e) => {
|
|
657
|
+
const i = e.target;
|
|
658
|
+
this.chatWindow && this.chatWindow.contains(i) || i.closest(".foisit-floating-btn") || this.toggle();
|
|
659
|
+
}, this.config = t, this.active && this.init();
|
|
660
|
+
}
|
|
661
|
+
/** Register a command handler that can be invoked programmatically via `runCommand` */
|
|
662
|
+
registerCommandHandler(t, e) {
|
|
663
|
+
!t || typeof e != "function" || this.commandHandlers.set(t, e);
|
|
664
|
+
}
|
|
665
|
+
/** Check whether a programmatic handler is registered locally */
|
|
666
|
+
hasCommandHandler(t) {
|
|
667
|
+
return this.commandHandlers.has(t);
|
|
668
|
+
}
|
|
669
|
+
/** Set an external executor (used to run commands registered via CommandHandler) */
|
|
670
|
+
setExternalCommandExecutor(t) {
|
|
671
|
+
this.externalCommandExecutor = t;
|
|
672
|
+
}
|
|
673
|
+
/** Unregister a previously registered command handler */
|
|
674
|
+
unregisterCommandHandler(t) {
|
|
675
|
+
t && this.commandHandlers.delete(t);
|
|
676
|
+
}
|
|
677
|
+
/**
|
|
678
|
+
* Run a registered command by id. Options:
|
|
679
|
+
* - `params`: passed to the handler
|
|
680
|
+
* - `openOverlay`: if true, open the overlay before running
|
|
681
|
+
* - `showInvocation`: if true, show the invocation as a user message
|
|
682
|
+
*/
|
|
683
|
+
async runCommand(t) {
|
|
684
|
+
if (!t || !t.commandId) throw new Error("runCommand requires a commandId");
|
|
685
|
+
const { commandId: e, params: i, openOverlay: s = !0, showInvocation: n = !0 } = t;
|
|
686
|
+
s && !this.isOpen && this.toggle();
|
|
687
|
+
const a = this.commandHandlers.get(e);
|
|
688
|
+
if (a && n && this.messagesContainer && this.addMessage(`Command: ${e}`, "user"), a)
|
|
689
|
+
try {
|
|
690
|
+
this.showLoading();
|
|
691
|
+
const o = await a(i);
|
|
692
|
+
if (this.hideLoading(), typeof o == "string")
|
|
693
|
+
this.addMessage(o, "system");
|
|
694
|
+
else if (o && typeof o == "object")
|
|
695
|
+
try {
|
|
696
|
+
this.addMessage(JSON.stringify(o, null, 2), "system");
|
|
697
|
+
} catch {
|
|
698
|
+
this.addMessage(String(o), "system");
|
|
699
|
+
}
|
|
700
|
+
else o == null || this.addMessage(String(o), "system");
|
|
701
|
+
return o;
|
|
702
|
+
} catch (o) {
|
|
703
|
+
throw this.hideLoading(), this.addMessage(`Command "${e}" failed: ${String(o)}`, "system"), o;
|
|
704
|
+
}
|
|
705
|
+
if (this.externalCommandExecutor)
|
|
706
|
+
try {
|
|
707
|
+
this.showLoading();
|
|
708
|
+
const o = await this.externalCommandExecutor({ commandId: e, params: i });
|
|
709
|
+
return this.hideLoading(), o;
|
|
710
|
+
} catch (o) {
|
|
711
|
+
throw this.hideLoading(), this.addMessage(`Command "${e}" failed: ${String(o)}`, "system"), o;
|
|
712
|
+
}
|
|
713
|
+
this.addMessage(`No handler registered for command "${e}".`, "system");
|
|
646
714
|
}
|
|
647
715
|
init() {
|
|
648
716
|
var e, i;
|
|
@@ -650,16 +718,16 @@ class G {
|
|
|
650
718
|
this.injectOverlayStyles();
|
|
651
719
|
const t = document.getElementById("foisit-overlay-container");
|
|
652
720
|
if (t && t instanceof HTMLElement) {
|
|
653
|
-
this.container = t, this.chatWindow = t.querySelector(".foisit-chat"), this.messagesContainer = t.querySelector(".foisit-messages"), this.input = t.querySelector("input.foisit-input"), ((e = this.config.floatingButton) == null ? void 0 : e.visible) !== !1 && !t.querySelector(".foisit-floating-btn") && this.renderFloatingButton(), this.chatWindow || this.renderChatWindow();
|
|
721
|
+
this.container = t, this.chatWindow = t.querySelector(".foisit-chat"), this.messagesContainer = t.querySelector(".foisit-messages"), this.input = t.querySelector("input.foisit-input"), ((e = this.config.floatingButton) == null ? void 0 : e.visible) !== !1 && !t.querySelector(".foisit-floating-btn") && this.renderFloatingButton(), this.chatWindow || this.renderChatWindow(), this.config.enableGestureActivation && (this.gestureHandler = new R(), this.gestureHandler.setupTripleTapListener(() => this.toggle()));
|
|
654
722
|
return;
|
|
655
723
|
}
|
|
656
|
-
this.container = document.createElement("div"), this.container.id = "foisit-overlay-container", this.container.className = "foisit-overlay-container", document.body.appendChild(this.container), ((i = this.config.floatingButton) == null ? void 0 : i.visible) !== !1 && this.renderFloatingButton(), this.renderChatWindow();
|
|
724
|
+
this.container = document.createElement("div"), this.container.id = "foisit-overlay-container", this.container.className = "foisit-overlay-container", document.body.appendChild(this.container), ((i = this.config.floatingButton) == null ? void 0 : i.visible) !== !1 && this.renderFloatingButton(), this.renderChatWindow(), this.config.enableGestureActivation && (this.gestureHandler = new R(), this.gestureHandler.setupTripleTapListener(() => this.toggle()));
|
|
657
725
|
}
|
|
658
726
|
renderFloatingButton() {
|
|
659
|
-
var s, n,
|
|
727
|
+
var s, n, a, o, c, f;
|
|
660
728
|
const t = document.createElement("button");
|
|
661
729
|
t.innerHTML = ((s = this.config.floatingButton) == null ? void 0 : s.customHtml) || "🎙️";
|
|
662
|
-
const e = ((
|
|
730
|
+
const e = ((a = (n = this.config.floatingButton) == null ? void 0 : n.position) == null ? void 0 : a.bottom) || "20px", i = ((c = (o = this.config.floatingButton) == null ? void 0 : o.position) == null ? void 0 : c.right) || "20px";
|
|
663
731
|
t.className = "foisit-floating-btn", t.style.bottom = e, t.style.right = i, t.onclick = () => this.toggle(), t.onmouseenter = () => t.style.transform = "scale(1.05)", t.onmouseleave = () => t.style.transform = "scale(1)", (f = this.container) == null || f.appendChild(t);
|
|
664
732
|
}
|
|
665
733
|
renderChatWindow() {
|
|
@@ -673,31 +741,39 @@ class G {
|
|
|
673
741
|
const i = document.createElement("button");
|
|
674
742
|
i.type = "button", i.className = "foisit-close", i.setAttribute("aria-label", "Close"), i.innerHTML = "×", i.addEventListener("click", () => this.toggle()), t.appendChild(e), t.appendChild(i), this.messagesContainer = document.createElement("div"), this.messagesContainer.className = "foisit-messages";
|
|
675
743
|
const s = document.createElement("div");
|
|
676
|
-
s.className = "foisit-input-area", this.input = document.createElement("input"), this.input.placeholder = this.config.inputPlaceholder || "Type a command...", this.input.className = "foisit-input", this.input.addEventListener("keydown", (
|
|
677
|
-
var
|
|
678
|
-
if (
|
|
744
|
+
s.className = "foisit-input-area", this.input = document.createElement("input"), this.input.placeholder = this.config.inputPlaceholder || "Type a command...", this.input.className = "foisit-input", this.input.addEventListener("keydown", (a) => {
|
|
745
|
+
var o;
|
|
746
|
+
if (a.key === "Enter" && ((o = this.input) != null && o.value.trim())) {
|
|
679
747
|
const c = this.input.value.trim();
|
|
680
748
|
this.input.value = "", this.onSubmit && this.onSubmit(c);
|
|
681
749
|
}
|
|
682
750
|
}), s.appendChild(this.input), this.chatWindow.appendChild(t), this.chatWindow.appendChild(this.messagesContainer), this.chatWindow.appendChild(s), (n = this.container) == null || n.appendChild(this.chatWindow);
|
|
683
751
|
}
|
|
684
752
|
registerCallbacks(t, e) {
|
|
685
|
-
this.onSubmit = t, this.onClose = e;
|
|
753
|
+
this.active && (this.onSubmit = t, this.onClose = e);
|
|
686
754
|
}
|
|
687
755
|
toggle(t, e) {
|
|
688
|
-
t && (this.onSubmit = t), e && (this.onClose = e), this.isOpen = !this.isOpen, this.chatWindow && (this.isOpen ? (this.chatWindow.style.display = "flex", requestAnimationFrame(() => {
|
|
756
|
+
this.active && (t && (this.onSubmit = t), e && (this.onClose = e), this.isOpen = !this.isOpen, this.chatWindow && (this.isOpen ? (this.container && (this.container.style.pointerEvents = "auto"), this.chatWindow.style.display = "flex", requestAnimationFrame(() => {
|
|
689
757
|
this.chatWindow && (this.chatWindow.style.opacity = "1", this.chatWindow.style.transform = "translateY(0) scale(1)");
|
|
690
758
|
}), setTimeout(() => {
|
|
691
759
|
var i;
|
|
692
760
|
return (i = this.input) == null ? void 0 : i.focus();
|
|
693
|
-
}, 100)) : (this.chatWindow.style.opacity = "0", this.chatWindow.style.transform = "translateY(20px) scale(0.95)", setTimeout(() => {
|
|
761
|
+
}, 100), this.addClickOutsideListener()) : (this.chatWindow.style.opacity = "0", this.chatWindow.style.transform = "translateY(20px) scale(0.95)", setTimeout(() => {
|
|
694
762
|
this.chatWindow && !this.isOpen && (this.chatWindow.style.display = "none");
|
|
695
|
-
}, 200), this.onClose && this.onClose()));
|
|
763
|
+
}, 200), this.onClose && this.onClose(), this.removeClickOutsideListener(), this.container && (this.container.style.pointerEvents = "none"))));
|
|
764
|
+
}
|
|
765
|
+
addClickOutsideListener() {
|
|
766
|
+
this.container && (this.removeClickOutsideListener(), this.container.addEventListener("click", this.handleClickOutside));
|
|
767
|
+
}
|
|
768
|
+
removeClickOutsideListener() {
|
|
769
|
+
this.container && this.container.removeEventListener("click", this.handleClickOutside);
|
|
696
770
|
}
|
|
697
771
|
addMessage(t, e) {
|
|
698
772
|
if (!this.messagesContainer) return;
|
|
699
773
|
const i = document.createElement("div");
|
|
700
|
-
i.textContent = t, i.className = e === "user" ? "foisit-bubble user" : "foisit-bubble system"
|
|
774
|
+
e === "system" ? i.innerHTML = this.renderMarkdown(t) : i.textContent = t, i.className = e === "user" ? "foisit-bubble user" : "foisit-bubble system";
|
|
775
|
+
const s = (t || "").length || 0, n = Math.max(120, 700 - Math.min(600, Math.floor(s * 6)));
|
|
776
|
+
i.style.opacity = "0", i.style.transform = "translateY(8px)", i.style.transition = "none", this.messagesContainer.appendChild(i), this.animateMessageEntrance(i, n), this.scrollToBottom();
|
|
701
777
|
}
|
|
702
778
|
addOptions(t) {
|
|
703
779
|
if (!this.messagesContainer) return;
|
|
@@ -710,11 +786,11 @@ class G {
|
|
|
710
786
|
this.onSubmit && this.onSubmit({ commandId: i.commandId });
|
|
711
787
|
return;
|
|
712
788
|
}
|
|
713
|
-
const
|
|
714
|
-
this.onSubmit && this.onSubmit(
|
|
789
|
+
const a = i && typeof i.value == "string" && i.value.trim() ? i.value : i.label;
|
|
790
|
+
this.onSubmit && this.onSubmit(a);
|
|
715
791
|
};
|
|
716
|
-
s.onclick = n, s.onkeydown = (
|
|
717
|
-
(
|
|
792
|
+
s.onclick = n, s.onkeydown = (a) => {
|
|
793
|
+
(a.key === "Enter" || a.key === " ") && (a.preventDefault(), n());
|
|
718
794
|
}, e.appendChild(s);
|
|
719
795
|
}), this.messagesContainer.appendChild(e), this.scrollToBottom();
|
|
720
796
|
}
|
|
@@ -723,57 +799,57 @@ class G {
|
|
|
723
799
|
this.addMessage(t, "system");
|
|
724
800
|
const s = document.createElement("form");
|
|
725
801
|
s.className = "foisit-form";
|
|
726
|
-
const n = [],
|
|
802
|
+
const n = [], a = (r, p) => {
|
|
727
803
|
const g = document.createElement("div");
|
|
728
|
-
return g.className = "foisit-form-label", g.innerHTML =
|
|
729
|
-
},
|
|
730
|
-
const
|
|
731
|
-
return
|
|
804
|
+
return g.className = "foisit-form-label", g.innerHTML = r + (p ? ' <span class="foisit-req-star">*</span>' : ""), g;
|
|
805
|
+
}, o = () => {
|
|
806
|
+
const r = document.createElement("div");
|
|
807
|
+
return r.className = "foisit-form-error", r.style.display = "none", r;
|
|
732
808
|
};
|
|
733
|
-
(e ?? []).forEach((
|
|
809
|
+
(e ?? []).forEach((r) => {
|
|
734
810
|
const p = document.createElement("div");
|
|
735
811
|
p.className = "foisit-form-group";
|
|
736
|
-
const g =
|
|
737
|
-
p.appendChild(
|
|
812
|
+
const g = r.description || r.name;
|
|
813
|
+
p.appendChild(a(g, r.required));
|
|
738
814
|
let m;
|
|
739
|
-
if (
|
|
815
|
+
if (r.type === "select") {
|
|
740
816
|
const l = document.createElement("select");
|
|
741
817
|
l.className = "foisit-form-input";
|
|
742
|
-
const
|
|
743
|
-
|
|
744
|
-
const
|
|
745
|
-
(h ?? []).forEach((
|
|
746
|
-
const
|
|
747
|
-
|
|
818
|
+
const y = document.createElement("option");
|
|
819
|
+
y.value = "", y.textContent = "Select...", l.appendChild(y);
|
|
820
|
+
const w = (h) => {
|
|
821
|
+
(h ?? []).forEach((x) => {
|
|
822
|
+
const b = document.createElement("option");
|
|
823
|
+
b.value = String(x.value ?? x.label ?? ""), b.textContent = String(x.label ?? x.value ?? ""), l.appendChild(b);
|
|
748
824
|
});
|
|
749
825
|
};
|
|
750
|
-
if (Array.isArray(
|
|
751
|
-
|
|
752
|
-
else if (typeof
|
|
753
|
-
const h =
|
|
754
|
-
|
|
826
|
+
if (Array.isArray(r.options) && r.options.length)
|
|
827
|
+
w(r.options);
|
|
828
|
+
else if (typeof r.getOptions == "function") {
|
|
829
|
+
const h = r.getOptions, x = document.createElement("option");
|
|
830
|
+
x.value = "", x.textContent = "Loading...", l.appendChild(x), Promise.resolve().then(() => h()).then((b) => {
|
|
755
831
|
for (; l.options.length > 1; ) l.remove(1);
|
|
756
|
-
|
|
832
|
+
w(b);
|
|
757
833
|
}).catch(() => {
|
|
758
834
|
for (; l.options.length > 1; ) l.remove(1);
|
|
759
|
-
const
|
|
760
|
-
|
|
835
|
+
const b = document.createElement("option");
|
|
836
|
+
b.value = "", b.textContent = "Error loading options", l.appendChild(b);
|
|
761
837
|
});
|
|
762
838
|
}
|
|
763
|
-
|
|
764
|
-
} else if (
|
|
765
|
-
const l =
|
|
766
|
-
|
|
767
|
-
const
|
|
768
|
-
if (h.style.display = "none", h.textContent = "",
|
|
769
|
-
const
|
|
770
|
-
if (
|
|
771
|
-
h.textContent = `Please select at most ${
|
|
839
|
+
r.defaultValue != null && (l.value = String(r.defaultValue)), m = l;
|
|
840
|
+
} else if (r.type === "file") {
|
|
841
|
+
const l = r, y = document.createElement("input");
|
|
842
|
+
y.className = "foisit-form-input", y.type = "file", l.accept && Array.isArray(l.accept) && (y.accept = l.accept.join(",")), l.multiple && (y.multiple = !0), l.capture && (l.capture === !0 ? y.setAttribute("capture", "") : y.setAttribute("capture", String(l.capture))), y.addEventListener("change", async () => {
|
|
843
|
+
const w = Array.from(y.files || []), h = C;
|
|
844
|
+
if (h.style.display = "none", h.textContent = "", w.length === 0) return;
|
|
845
|
+
const x = l.maxFiles ?? (l.multiple ? 10 : 1);
|
|
846
|
+
if (w.length > x) {
|
|
847
|
+
h.textContent = `Please select at most ${x} file(s).`, h.style.display = "block";
|
|
772
848
|
return;
|
|
773
849
|
}
|
|
774
|
-
const
|
|
775
|
-
if (
|
|
776
|
-
h.textContent = `One or more files exceed the maximum size of ${Math.round(
|
|
850
|
+
const b = l.maxSizeBytes ?? 1 / 0, u = w.reduce((v, E) => v + E.size, 0);
|
|
851
|
+
if (w.some((v) => v.size > b)) {
|
|
852
|
+
h.textContent = `One or more files exceed the maximum size of ${Math.round(b / 1024)} KB.`, h.style.display = "block";
|
|
777
853
|
return;
|
|
778
854
|
}
|
|
779
855
|
const S = l.maxTotalBytes ?? 1 / 0;
|
|
@@ -783,29 +859,29 @@ class G {
|
|
|
783
859
|
}
|
|
784
860
|
if (l.accept && Array.isArray(l.accept)) {
|
|
785
861
|
const v = l.accept;
|
|
786
|
-
if (!
|
|
862
|
+
if (!w.every((L) => L.type ? v.some((A) => A.startsWith(".") ? L.name.toLowerCase().endsWith(A.toLowerCase()) : L.type === A || L.type.startsWith(A.split("/")[0] + "/")) : !0)) {
|
|
787
863
|
h.textContent = "One or more files have an unsupported type.", h.style.display = "block";
|
|
788
864
|
return;
|
|
789
865
|
}
|
|
790
866
|
}
|
|
791
|
-
}), m =
|
|
867
|
+
}), m = y;
|
|
792
868
|
} else {
|
|
793
869
|
const l = document.createElement("input");
|
|
794
|
-
l.className = "foisit-form-input",
|
|
870
|
+
l.className = "foisit-form-input", r.type === "string" && (l.placeholder = r.placeholder || "Type here..."), r.type === "number" ? (l.type = "number", typeof r.min == "number" && (l.min = String(r.min)), typeof r.max == "number" && (l.max = String(r.max)), typeof r.step == "number" && (l.step = String(r.step)), r.defaultValue != null && (l.value = String(r.defaultValue))) : r.type === "date" ? (l.type = "date", typeof r.min == "string" && (l.min = r.min), typeof r.max == "string" && (l.max = r.max), r.defaultValue != null && (l.value = String(r.defaultValue))) : (l.type = "text", r.defaultValue != null && (l.value = String(r.defaultValue))), m = l;
|
|
795
871
|
}
|
|
796
|
-
const C =
|
|
872
|
+
const C = o();
|
|
797
873
|
p.appendChild(m), p.appendChild(C), n.push({
|
|
798
|
-
name:
|
|
799
|
-
type:
|
|
874
|
+
name: r.name,
|
|
875
|
+
type: r.type,
|
|
800
876
|
el: m,
|
|
801
|
-
required:
|
|
877
|
+
required: r.required
|
|
802
878
|
}), s.appendChild(p);
|
|
803
879
|
});
|
|
804
880
|
const c = document.createElement("div");
|
|
805
881
|
c.className = "foisit-form-actions";
|
|
806
882
|
const f = document.createElement("button");
|
|
807
|
-
f.type = "submit", f.textContent = "Submit", f.className = "foisit-option-chip", f.style.fontWeight = "600", c.appendChild(f), s.appendChild(c), s.onsubmit = async (
|
|
808
|
-
|
|
883
|
+
f.type = "submit", f.textContent = "Submit", f.className = "foisit-option-chip", f.style.fontWeight = "600", c.appendChild(f), s.appendChild(c), s.onsubmit = async (r) => {
|
|
884
|
+
r.preventDefault();
|
|
809
885
|
const p = {};
|
|
810
886
|
let g = !1;
|
|
811
887
|
s.querySelectorAll(".foisit-form-error").forEach((m) => {
|
|
@@ -815,16 +891,16 @@ class G {
|
|
|
815
891
|
});
|
|
816
892
|
for (const m of n) {
|
|
817
893
|
if (m.type === "file") {
|
|
818
|
-
const
|
|
819
|
-
if (m.required &&
|
|
820
|
-
g = !0,
|
|
894
|
+
const w = m.el.parentElement, h = w == null ? void 0 : w.querySelector(".foisit-form-error"), x = m.el, b = Array.from(x.files || []);
|
|
895
|
+
if (m.required && b.length === 0) {
|
|
896
|
+
g = !0, x.classList.add("foisit-error-border"), h && (h.textContent = "This file is required", h.style.display = "block");
|
|
821
897
|
continue;
|
|
822
898
|
}
|
|
823
|
-
if (
|
|
899
|
+
if (b.length === 0) continue;
|
|
824
900
|
const u = (e ?? []).find((v) => v.name === m.name), S = (u == null ? void 0 : u.delivery) ?? "file";
|
|
825
901
|
if (u != null && u.maxWidth || u != null && u.maxHeight)
|
|
826
902
|
try {
|
|
827
|
-
const v = await this.getImageDimensions(
|
|
903
|
+
const v = await this.getImageDimensions(b[0]);
|
|
828
904
|
if (u.maxWidth && v.width > u.maxWidth) {
|
|
829
905
|
g = !0, h && (h.textContent = `Image width must be ≤ ${u.maxWidth}px`, h.style.display = "block");
|
|
830
906
|
continue;
|
|
@@ -837,7 +913,7 @@ class G {
|
|
|
837
913
|
}
|
|
838
914
|
if (u != null && u.maxDurationSec)
|
|
839
915
|
try {
|
|
840
|
-
const v = await this.getMediaDuration(
|
|
916
|
+
const v = await this.getMediaDuration(b[0]);
|
|
841
917
|
if (v && v > u.maxDurationSec) {
|
|
842
918
|
g = !0, h && (h.textContent = `Media duration must be ≤ ${u.maxDurationSec}s`, h.style.display = "block");
|
|
843
919
|
continue;
|
|
@@ -845,10 +921,10 @@ class G {
|
|
|
845
921
|
} catch {
|
|
846
922
|
}
|
|
847
923
|
if (S === "file")
|
|
848
|
-
p[m.name] = u != null && u.multiple ?
|
|
924
|
+
p[m.name] = u != null && u.multiple ? b : b[0];
|
|
849
925
|
else if (S === "base64")
|
|
850
926
|
try {
|
|
851
|
-
const v = await Promise.all(
|
|
927
|
+
const v = await Promise.all(b.map((E) => this.readFileAsDataURL(E)));
|
|
852
928
|
p[m.name] = u != null && u.multiple ? v : v[0];
|
|
853
929
|
} catch {
|
|
854
930
|
g = !0, h && (h.textContent = "Failed to encode file(s) to base64.", h.style.display = "block");
|
|
@@ -856,15 +932,15 @@ class G {
|
|
|
856
932
|
}
|
|
857
933
|
continue;
|
|
858
934
|
}
|
|
859
|
-
const C = (m.el.value ?? "").toString().trim(), l = m.el.parentElement,
|
|
935
|
+
const C = (m.el.value ?? "").toString().trim(), l = m.el.parentElement, y = l == null ? void 0 : l.querySelector(".foisit-form-error");
|
|
860
936
|
if (m.required && (C == null || C === "")) {
|
|
861
|
-
g = !0, m.el.classList.add("foisit-error-border"),
|
|
937
|
+
g = !0, m.el.classList.add("foisit-error-border"), y && (y.textContent = "This field is required", y.style.display = "block");
|
|
862
938
|
continue;
|
|
863
939
|
}
|
|
864
940
|
if (C !== "")
|
|
865
941
|
if (m.type === "number") {
|
|
866
|
-
const
|
|
867
|
-
Number.isNaN(
|
|
942
|
+
const w = Number(C);
|
|
943
|
+
Number.isNaN(w) || (p[m.name] = w);
|
|
868
944
|
} else
|
|
869
945
|
p[m.name] = C;
|
|
870
946
|
}
|
|
@@ -894,9 +970,54 @@ class G {
|
|
|
894
970
|
scrollToBottom() {
|
|
895
971
|
this.messagesContainer && (this.messagesContainer.scrollTop = this.messagesContainer.scrollHeight);
|
|
896
972
|
}
|
|
973
|
+
/** Subtle entrance animation for new messages */
|
|
974
|
+
animateMessageEntrance(t, e) {
|
|
975
|
+
if (!t) return;
|
|
976
|
+
t.style.transition = `opacity ${e}ms cubic-bezier(0.22, 0.9, 0.32, 1), transform ${Math.max(120, e)}ms cubic-bezier(0.22, 0.9, 0.32, 1)`, requestAnimationFrame(() => {
|
|
977
|
+
t.style.opacity = "1", t.style.transform = "translateY(0)";
|
|
978
|
+
});
|
|
979
|
+
const i = () => {
|
|
980
|
+
try {
|
|
981
|
+
t.style.transition = "";
|
|
982
|
+
} catch {
|
|
983
|
+
}
|
|
984
|
+
t.removeEventListener("transitionend", i);
|
|
985
|
+
};
|
|
986
|
+
t.addEventListener("transitionend", i);
|
|
987
|
+
}
|
|
988
|
+
/** Smoothly scroll messages container to bottom over duration (ms) */
|
|
989
|
+
animateScrollToBottom(t) {
|
|
990
|
+
if (!this.messagesContainer) return;
|
|
991
|
+
const e = this.messagesContainer, i = e.scrollTop, s = e.scrollHeight - e.clientHeight;
|
|
992
|
+
if (s <= i || t <= 0) {
|
|
993
|
+
e.scrollTop = s;
|
|
994
|
+
return;
|
|
995
|
+
}
|
|
996
|
+
const n = s - i, a = performance.now(), o = (c) => {
|
|
997
|
+
const f = Math.min(1, (c - a) / t), r = 1 - Math.pow(1 - f, 3);
|
|
998
|
+
e.scrollTop = Math.round(i + n * r), f < 1 && requestAnimationFrame(o);
|
|
999
|
+
};
|
|
1000
|
+
requestAnimationFrame(o);
|
|
1001
|
+
}
|
|
897
1002
|
destroy() {
|
|
898
1003
|
var t;
|
|
899
|
-
(t = this.container) == null || t.remove(), this.container = null, this.chatWindow = null, this.messagesContainer = null, this.input = null, this.isOpen = !1;
|
|
1004
|
+
this.removeClickOutsideListener(), (t = this.container) == null || t.remove(), this.container = null, this.chatWindow = null, this.messagesContainer = null, this.input = null, this.isOpen = !1;
|
|
1005
|
+
}
|
|
1006
|
+
/** Escape HTML special characters to prevent XSS */
|
|
1007
|
+
escapeHtml(t) {
|
|
1008
|
+
const e = {
|
|
1009
|
+
"&": "&",
|
|
1010
|
+
"<": "<",
|
|
1011
|
+
">": ">",
|
|
1012
|
+
'"': """,
|
|
1013
|
+
"'": "'"
|
|
1014
|
+
};
|
|
1015
|
+
return t.replace(/[&<>"']/g, (i) => e[i]);
|
|
1016
|
+
}
|
|
1017
|
+
/** Simple markdown renderer for AI responses */
|
|
1018
|
+
renderMarkdown(t) {
|
|
1019
|
+
let e = this.escapeHtml(t);
|
|
1020
|
+
return e = e.replace(/```(\w*)\n([\s\S]*?)```/g, (i, s, n) => `<pre class="foisit-code-block"><code${s ? ` class="language-${s}"` : ""}>${n.trim()}</code></pre>`), e = e.replace(/`([^`]+)`/g, '<code class="foisit-inline-code">$1</code>'), e = e.replace(/^###### (.+)$/gm, '<h6 class="foisit-md-h6">$1</h6>'), e = e.replace(/^##### (.+)$/gm, '<h5 class="foisit-md-h5">$1</h5>'), e = e.replace(/^#### (.+)$/gm, '<h4 class="foisit-md-h4">$1</h4>'), e = e.replace(/^### (.+)$/gm, '<h3 class="foisit-md-h3">$1</h3>'), e = e.replace(/^## (.+)$/gm, '<h2 class="foisit-md-h2">$1</h2>'), e = e.replace(/^# (.+)$/gm, '<h1 class="foisit-md-h1">$1</h1>'), e = e.replace(/\*\*([^*]+)\*\*/g, "<strong>$1</strong>"), e = e.replace(/__([^_]+)__/g, "<strong>$1</strong>"), e = e.replace(/\*([^*]+)\*/g, "<em>$1</em>"), e = e.replace(new RegExp("(?<!_)_([^_]+)_(?!_)", "g"), "<em>$1</em>"), e = e.replace(/~~([^~]+)~~/g, "<del>$1</del>"), e = e.replace(/\[([^\]]+)\]\(([^)]+)\)/g, '<a href="$2" target="_blank" rel="noopener noreferrer" class="foisit-md-link">$1</a>'), e = e.replace(/^[\-\*] (.+)$/gm, '<li class="foisit-md-li">$1</li>'), e = e.replace(/(<li class="foisit-md-li">.*<\/li>\n?)+/g, (i) => `<ul class="foisit-md-ul">${i}</ul>`), e = e.replace(/^\d+\. (.+)$/gm, '<li class="foisit-md-li">$1</li>'), e = e.replace(new RegExp('(?<!<\\/ul>)(<li class="foisit-md-li">.*<\\/li>\\n?)+', "g"), (i) => i.includes("<ul") ? i : `<ol class="foisit-md-ol">${i}</ol>`), e = e.replace(/^> (.+)$/gm, '<blockquote class="foisit-md-blockquote">$1</blockquote>'), e = e.replace(/^(---|___|\*\*\*)$/gm, '<hr class="foisit-md-hr">'), e = e.replace(/\n\n+/g, '</p><p class="foisit-md-p">'), e = e.replace(/\n/g, "<br>"), e.match(/^<(h[1-6]|ul|ol|pre|blockquote|hr|p)/) || (e = `<p class="foisit-md-p">${e}</p>`), e;
|
|
900
1021
|
}
|
|
901
1022
|
readFileAsDataURL(t) {
|
|
902
1023
|
return new Promise((e, i) => {
|
|
@@ -924,16 +1045,16 @@ class G {
|
|
|
924
1045
|
try {
|
|
925
1046
|
const i = URL.createObjectURL(t), s = t.type.startsWith("audio") ? document.createElement("audio") : document.createElement("video");
|
|
926
1047
|
let n = !1;
|
|
927
|
-
const
|
|
1048
|
+
const a = setTimeout(() => {
|
|
928
1049
|
n || (n = !0, URL.revokeObjectURL(i), e(0));
|
|
929
1050
|
}, 5e3);
|
|
930
1051
|
s.preload = "metadata", s.onloadedmetadata = () => {
|
|
931
1052
|
if (n) return;
|
|
932
|
-
n = !0, clearTimeout(
|
|
1053
|
+
n = !0, clearTimeout(a);
|
|
933
1054
|
const c = s.duration || 0;
|
|
934
1055
|
URL.revokeObjectURL(i), e(c);
|
|
935
1056
|
}, s.onerror = () => {
|
|
936
|
-
n || (n = !0, clearTimeout(
|
|
1057
|
+
n || (n = !0, clearTimeout(a), URL.revokeObjectURL(i), e(0));
|
|
937
1058
|
}, s.src = i;
|
|
938
1059
|
} catch {
|
|
939
1060
|
e(0);
|
|
@@ -1264,18 +1385,104 @@ class G {
|
|
|
1264
1385
|
transition: transform 0.2s;
|
|
1265
1386
|
}
|
|
1266
1387
|
.foisit-floating-btn:hover { transform: scale(1.05); }
|
|
1388
|
+
|
|
1389
|
+
/* Markdown Styles */
|
|
1390
|
+
.foisit-bubble.system .foisit-md-p { margin: 0 0 0.5em 0; }
|
|
1391
|
+
.foisit-bubble.system .foisit-md-p:last-child { margin-bottom: 0; }
|
|
1392
|
+
|
|
1393
|
+
.foisit-bubble.system .foisit-md-h1,
|
|
1394
|
+
.foisit-bubble.system .foisit-md-h2,
|
|
1395
|
+
.foisit-bubble.system .foisit-md-h3,
|
|
1396
|
+
.foisit-bubble.system .foisit-md-h4,
|
|
1397
|
+
.foisit-bubble.system .foisit-md-h5,
|
|
1398
|
+
.foisit-bubble.system .foisit-md-h6 {
|
|
1399
|
+
margin: 0.8em 0 0.4em 0;
|
|
1400
|
+
font-weight: 600;
|
|
1401
|
+
line-height: 1.3;
|
|
1402
|
+
}
|
|
1403
|
+
.foisit-bubble.system .foisit-md-h1:first-child,
|
|
1404
|
+
.foisit-bubble.system .foisit-md-h2:first-child,
|
|
1405
|
+
.foisit-bubble.system .foisit-md-h3:first-child { margin-top: 0; }
|
|
1406
|
+
|
|
1407
|
+
.foisit-bubble.system .foisit-md-h1 { font-size: 1.4em; }
|
|
1408
|
+
.foisit-bubble.system .foisit-md-h2 { font-size: 1.25em; }
|
|
1409
|
+
.foisit-bubble.system .foisit-md-h3 { font-size: 1.1em; }
|
|
1410
|
+
.foisit-bubble.system .foisit-md-h4 { font-size: 1em; }
|
|
1411
|
+
.foisit-bubble.system .foisit-md-h5 { font-size: 0.95em; }
|
|
1412
|
+
.foisit-bubble.system .foisit-md-h6 { font-size: 0.9em; opacity: 0.85; }
|
|
1413
|
+
|
|
1414
|
+
.foisit-bubble.system .foisit-md-ul,
|
|
1415
|
+
.foisit-bubble.system .foisit-md-ol {
|
|
1416
|
+
margin: 0.5em 0;
|
|
1417
|
+
padding-left: 1.5em;
|
|
1418
|
+
}
|
|
1419
|
+
.foisit-bubble.system .foisit-md-li { margin: 0.25em 0; }
|
|
1420
|
+
|
|
1421
|
+
.foisit-bubble.system .foisit-code-block {
|
|
1422
|
+
background: rgba(0,0,0,0.15);
|
|
1423
|
+
border-radius: 6px;
|
|
1424
|
+
padding: 10px 12px;
|
|
1425
|
+
margin: 0.5em 0;
|
|
1426
|
+
overflow-x: auto;
|
|
1427
|
+
font-family: 'SF Mono', Monaco, Consolas, 'Liberation Mono', 'Courier New', monospace;
|
|
1428
|
+
font-size: 0.85em;
|
|
1429
|
+
line-height: 1.4;
|
|
1430
|
+
}
|
|
1431
|
+
.foisit-bubble.system .foisit-code-block code {
|
|
1432
|
+
background: transparent;
|
|
1433
|
+
padding: 0;
|
|
1434
|
+
}
|
|
1435
|
+
|
|
1436
|
+
.foisit-bubble.system .foisit-inline-code {
|
|
1437
|
+
background: rgba(0,0,0,0.1);
|
|
1438
|
+
padding: 2px 6px;
|
|
1439
|
+
border-radius: 4px;
|
|
1440
|
+
font-family: 'SF Mono', Monaco, Consolas, 'Liberation Mono', 'Courier New', monospace;
|
|
1441
|
+
font-size: 0.9em;
|
|
1442
|
+
}
|
|
1443
|
+
|
|
1444
|
+
.foisit-bubble.system .foisit-md-blockquote {
|
|
1445
|
+
border-left: 3px solid rgba(127,127,127,0.4);
|
|
1446
|
+
margin: 0.5em 0;
|
|
1447
|
+
padding-left: 12px;
|
|
1448
|
+
opacity: 0.9;
|
|
1449
|
+
font-style: italic;
|
|
1450
|
+
}
|
|
1451
|
+
|
|
1452
|
+
.foisit-bubble.system .foisit-md-link {
|
|
1453
|
+
color: inherit;
|
|
1454
|
+
text-decoration: underline;
|
|
1455
|
+
opacity: 0.9;
|
|
1456
|
+
}
|
|
1457
|
+
.foisit-bubble.system .foisit-md-link:hover { opacity: 1; }
|
|
1458
|
+
|
|
1459
|
+
.foisit-bubble.system .foisit-md-hr {
|
|
1460
|
+
border: none;
|
|
1461
|
+
border-top: 1px solid rgba(127,127,127,0.3);
|
|
1462
|
+
margin: 0.8em 0;
|
|
1463
|
+
}
|
|
1464
|
+
|
|
1465
|
+
.foisit-bubble.system strong { font-weight: 600; }
|
|
1466
|
+
.foisit-bubble.system em { font-style: italic; }
|
|
1467
|
+
.foisit-bubble.system del { text-decoration: line-through; opacity: 0.7; }
|
|
1468
|
+
|
|
1469
|
+
@media (prefers-color-scheme: dark) {
|
|
1470
|
+
.foisit-bubble.system .foisit-code-block { background: rgba(255,255,255,0.08); }
|
|
1471
|
+
.foisit-bubble.system .foisit-inline-code { background: rgba(255,255,255,0.1); }
|
|
1472
|
+
}
|
|
1267
1473
|
`, document.head.appendChild(t);
|
|
1268
1474
|
}
|
|
1269
1475
|
}
|
|
1270
1476
|
class Y {
|
|
1271
1477
|
constructor(t) {
|
|
1272
|
-
this.config = t, this.isActivated = !1, this.lastProcessedInput = "", this.processingLock = !1, this.defaultIntroMessage = "How can I help you?", this.commandHandler = new
|
|
1478
|
+
this.config = t, this.isActivated = !1, this.lastProcessedInput = "", this.processingLock = !1, this.defaultIntroMessage = "How can I help you?", this.commandHandler = new z({
|
|
1273
1479
|
enableSmartIntent: this.config.enableSmartIntent !== !1,
|
|
1274
1480
|
intentEndpoint: this.config.intentEndpoint
|
|
1275
|
-
}), this.fallbackHandler = new
|
|
1481
|
+
}), this.fallbackHandler = new W(), typeof window < "u" && typeof document < "u" ? (this.voiceProcessor = new B(), this.textToSpeech = new P(), this.stateManager = new _(), this.gestureHandler = new R(), this.overlayManager = new G({
|
|
1276
1482
|
floatingButton: this.config.floatingButton,
|
|
1277
|
-
inputPlaceholder: this.config.inputPlaceholder
|
|
1278
|
-
|
|
1483
|
+
inputPlaceholder: this.config.inputPlaceholder,
|
|
1484
|
+
enableGestureActivation: this.config.enableGestureActivation
|
|
1485
|
+
}), this.overlayManager.setExternalCommandExecutor(async (e) => this.commandHandler.executeCommand(e)), this.config.commands.forEach((e) => this.commandHandler.addCommand(e)), this.config.fallbackResponse && this.fallbackHandler.setFallbackMessage(this.config.fallbackResponse), this.overlayManager.registerCallbacks(
|
|
1279
1486
|
async (e) => {
|
|
1280
1487
|
if (typeof e == "string") {
|
|
1281
1488
|
this.overlayManager.addMessage(e, "user"), await this.handleCommand(e);
|
|
@@ -1289,15 +1496,22 @@ class Y {
|
|
|
1289
1496
|
}
|
|
1290
1497
|
},
|
|
1291
1498
|
() => console.log("AssistantService: Overlay closed.")
|
|
1292
|
-
);
|
|
1499
|
+
)) : (this.voiceProcessor = void 0, this.textToSpeech = void 0, this.stateManager = void 0, this.gestureHandler = void 0, this.overlayManager = void 0, this.config.commands.forEach((e) => this.commandHandler.addCommand(e)), this.config.fallbackResponse && this.fallbackHandler.setFallbackMessage(this.config.fallbackResponse));
|
|
1293
1500
|
}
|
|
1294
1501
|
/** Start listening for activation and commands */
|
|
1295
1502
|
startListening() {
|
|
1296
|
-
|
|
1503
|
+
if (typeof window > "u" || !this.voiceProcessor) {
|
|
1504
|
+
console.log("AssistantService: Voice is disabled or unavailable; startListening() is a no-op.");
|
|
1505
|
+
return;
|
|
1506
|
+
}
|
|
1297
1507
|
}
|
|
1298
1508
|
/** Stop listening */
|
|
1299
1509
|
stopListening() {
|
|
1300
|
-
|
|
1510
|
+
if (typeof window > "u" || !this.voiceProcessor) {
|
|
1511
|
+
console.log("AssistantService: Voice unavailable; stopListening() is a no-op."), this.isActivated = !1;
|
|
1512
|
+
return;
|
|
1513
|
+
}
|
|
1514
|
+
this.voiceProcessor.stopListening(), this.isActivated = !1;
|
|
1301
1515
|
}
|
|
1302
1516
|
/**
|
|
1303
1517
|
* Reset activation state so the next activation flow can occur.
|
|
@@ -1395,6 +1609,19 @@ class Y {
|
|
|
1395
1609
|
removeCommand(t) {
|
|
1396
1610
|
console.log(`AssistantService: Removing command "${t}".`), this.commandHandler.removeCommand(t);
|
|
1397
1611
|
}
|
|
1612
|
+
/** Expose programmatic command handler registration to host apps */
|
|
1613
|
+
registerCommandHandler(t, e) {
|
|
1614
|
+
this.overlayManager && this.overlayManager.registerCommandHandler(t, e);
|
|
1615
|
+
}
|
|
1616
|
+
unregisterCommandHandler(t) {
|
|
1617
|
+
this.overlayManager && this.overlayManager.unregisterCommandHandler(t);
|
|
1618
|
+
}
|
|
1619
|
+
/** Programmatically run a registered command (proxies to OverlayManager) */
|
|
1620
|
+
async runCommand(t) {
|
|
1621
|
+
if (!this.overlayManager) throw new Error("Overlay manager not available.");
|
|
1622
|
+
const e = await this.overlayManager.runCommand(t);
|
|
1623
|
+
return e && typeof e == "object" && "type" in e && this.processResponse(e), e;
|
|
1624
|
+
}
|
|
1398
1625
|
/** Get all registered commands */
|
|
1399
1626
|
getCommands() {
|
|
1400
1627
|
return this.commandHandler.getCommands();
|
|
@@ -1410,13 +1637,13 @@ class Y {
|
|
|
1410
1637
|
if (i && typeof i == "object") {
|
|
1411
1638
|
const s = i, n = s.label ?? s.commandId ?? "Selection";
|
|
1412
1639
|
this.overlayManager.addMessage(String(n), "user"), this.overlayManager.showLoading();
|
|
1413
|
-
let
|
|
1640
|
+
let a;
|
|
1414
1641
|
try {
|
|
1415
|
-
|
|
1642
|
+
a = await this.commandHandler.executeCommand(s);
|
|
1416
1643
|
} finally {
|
|
1417
1644
|
this.overlayManager.hideLoading();
|
|
1418
1645
|
}
|
|
1419
|
-
this.processResponse(
|
|
1646
|
+
this.processResponse(a);
|
|
1420
1647
|
}
|
|
1421
1648
|
},
|
|
1422
1649
|
() => {
|
|
@@ -1425,26 +1652,26 @@ class Y {
|
|
|
1425
1652
|
);
|
|
1426
1653
|
}
|
|
1427
1654
|
}
|
|
1428
|
-
const
|
|
1429
|
-
let
|
|
1430
|
-
const
|
|
1431
|
-
const [e, i] =
|
|
1432
|
-
return
|
|
1433
|
-
|
|
1655
|
+
const q = F(null);
|
|
1656
|
+
let M = null;
|
|
1657
|
+
const Z = ({ config: d, children: t }) => {
|
|
1658
|
+
const [e, i] = I(null), [s, n] = I(!1);
|
|
1659
|
+
return $(() => {
|
|
1660
|
+
M ? console.warn(
|
|
1434
1661
|
"Multiple AssistantProvider instances detected. Reusing global AssistantService."
|
|
1435
|
-
) : (console.log("Initializing global AssistantService..."),
|
|
1436
|
-
const
|
|
1437
|
-
return i(
|
|
1438
|
-
var
|
|
1439
|
-
console.log("Cleaning up AssistantService..."), (
|
|
1662
|
+
) : (console.log("Initializing global AssistantService..."), M = new Y(d));
|
|
1663
|
+
const a = M;
|
|
1664
|
+
return i(a), n(!0), () => {
|
|
1665
|
+
var o;
|
|
1666
|
+
console.log("Cleaning up AssistantService..."), (o = a.destroy) == null || o.call(a), M = null;
|
|
1440
1667
|
};
|
|
1441
|
-
}, [d]), !s || !e ? /* @__PURE__ */ k("div", { children: "Loading Assistant..." }) : /* @__PURE__ */ k(
|
|
1668
|
+
}, [d]), !s || !e ? /* @__PURE__ */ k("div", { children: "Loading Assistant..." }) : /* @__PURE__ */ k(q.Provider, { value: e, children: t });
|
|
1442
1669
|
}, K = () => {
|
|
1443
|
-
const d = N(
|
|
1670
|
+
const d = N(q);
|
|
1444
1671
|
if (console.log("assistant", d), !d)
|
|
1445
1672
|
throw new Error("useAssistant must be used within an AssistantProvider");
|
|
1446
1673
|
return d;
|
|
1447
|
-
},
|
|
1674
|
+
}, tt = ({
|
|
1448
1675
|
label: d = "Activate Assistant",
|
|
1449
1676
|
onActivate: t
|
|
1450
1677
|
}) => {
|
|
@@ -1452,9 +1679,9 @@ const J = ({ config: d, children: t }) => {
|
|
|
1452
1679
|
return /* @__PURE__ */ k("button", { onClick: () => {
|
|
1453
1680
|
t && t(), e.reactivate();
|
|
1454
1681
|
}, className: "assistant-activator", children: d });
|
|
1455
|
-
},
|
|
1456
|
-
const [t, e] =
|
|
1457
|
-
return
|
|
1682
|
+
}, et = (d) => {
|
|
1683
|
+
const [t, e] = I(d.getState());
|
|
1684
|
+
return $(() => {
|
|
1458
1685
|
const i = (s) => {
|
|
1459
1686
|
e(s);
|
|
1460
1687
|
};
|
|
@@ -1465,11 +1692,11 @@ const J = ({ config: d, children: t }) => {
|
|
|
1465
1692
|
}, [d]), t;
|
|
1466
1693
|
};
|
|
1467
1694
|
export {
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
|
|
1695
|
+
tt as AssistantActivator,
|
|
1696
|
+
q as AssistantContext,
|
|
1697
|
+
Z as AssistantProvider,
|
|
1471
1698
|
Y as AssistantService,
|
|
1472
1699
|
Q as ReactWrapper,
|
|
1473
1700
|
K as useAssistant,
|
|
1474
|
-
|
|
1701
|
+
et as useAssistantState
|
|
1475
1702
|
};
|