@appilots/web-sdk 0.2.0 → 0.3.0
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 +19 -0
- package/dist/{chunk-T5TUFZ6T.js → chunk-H4ITA2QP.js} +255 -16
- package/dist/{chunk-VHRE4RUO.mjs → chunk-RR3T5CPP.mjs} +250 -17
- package/dist/index.d.mts +3 -3
- package/dist/index.d.ts +3 -3
- package/dist/index.js +70 -58
- package/dist/index.mjs +1 -1
- package/dist/react/index.d.mts +19 -5
- package/dist/react/index.d.ts +19 -5
- package/dist/react/index.js +516 -101
- package/dist/react/index.mjs +505 -98
- package/dist/{AppilotsWebRuntime-DZF26UyU.d.mts → webSpeechHost-CrTKADeb.d.mts} +127 -1
- package/dist/{AppilotsWebRuntime-DZF26UyU.d.ts → webSpeechHost-CrTKADeb.d.ts} +127 -1
- package/package.json +1 -1
|
@@ -4509,18 +4509,27 @@ var WRITE_SUCCESS = {
|
|
|
4509
4509
|
"a\\s+[e\xE9]t[e\xE9]\\s+(?:enregistr|cr[e\xE9]|ajout|sauvegard)[e\xE9]e?"
|
|
4510
4510
|
]
|
|
4511
4511
|
};
|
|
4512
|
+
var SENTENCE_START = "(?:^|[.!?:;*\\n]\\s*)";
|
|
4512
4513
|
var COMPLETION_CLAIM = {
|
|
4513
4514
|
pt: [
|
|
4514
4515
|
"j[a\xE1]\\s+(?:cadastrei|registrei|salvei|criei)",
|
|
4515
4516
|
"conclu[i\xED]\\s+o\\s+cadastro",
|
|
4516
|
-
"cadastro\\s+(?:foi\\s+)?(?:conclu[i\xED]do|realizado|feito)"
|
|
4517
|
+
"cadastro\\s+(?:foi\\s+)?(?:conclu[i\xED]do|realizado|feito)",
|
|
4518
|
+
`${SENTENCE_START}(?:eu\\s+)?(?:cadastrei|registrei|salvei|criei|adicionei|enviei)\\b`
|
|
4517
4519
|
],
|
|
4518
4520
|
en: [
|
|
4519
4521
|
"i(?:'|\u2019)?ve\\s+(?:registered|saved|created|added)",
|
|
4520
|
-
"i\\s+have\\s+(?:registered|saved|created|added)"
|
|
4522
|
+
"i\\s+have\\s+(?:registered|saved|created|added)",
|
|
4523
|
+
`${SENTENCE_START}i\\s+(?:registered|saved|created|added|submitted)\\b`
|
|
4521
4524
|
],
|
|
4522
|
-
es: [
|
|
4523
|
-
|
|
4525
|
+
es: [
|
|
4526
|
+
"ya\\s+(?:lo\\s+|la\\s+)?(?:registr[e\xE9]|guard[e\xE9]|cre[e\xE9])",
|
|
4527
|
+
`${SENTENCE_START}(?:ya\\s+)?he\\s+(?:registrado|guardado|creado|enviado|a[\xF1n]adido)\\b`
|
|
4528
|
+
],
|
|
4529
|
+
fr: [
|
|
4530
|
+
"j(?:e\\s+l(?:'|\u2019)ai|(?:'|\u2019)ai)\\s+(?:enregistr|cr[e\xE9]|ajout|sauvegard)[e\xE9]",
|
|
4531
|
+
`${SENTENCE_START}c(?:'|\u2019)est\\s+(?:enregistr|cr[e\xE9]|ajout|sauvegard)[e\xE9]`
|
|
4532
|
+
]
|
|
4524
4533
|
};
|
|
4525
4534
|
var SUBMIT_CONTROL = {
|
|
4526
4535
|
pt: ["cadastrar", "registrar", "salvar", "enviar", "confirmar"],
|
|
@@ -4638,6 +4647,7 @@ var AppilotsClient = class {
|
|
|
4638
4647
|
mcpVersion;
|
|
4639
4648
|
introspectionReporter;
|
|
4640
4649
|
user;
|
|
4650
|
+
plainLanguage;
|
|
4641
4651
|
sessionId = null;
|
|
4642
4652
|
mission = null;
|
|
4643
4653
|
missionDispatchPaused = false;
|
|
@@ -4656,6 +4666,7 @@ var AppilotsClient = class {
|
|
|
4656
4666
|
this.mcpVersion = options.mcpVersion;
|
|
4657
4667
|
this.introspectionReporter = options.introspectionReporter;
|
|
4658
4668
|
this.user = options.user;
|
|
4669
|
+
this.plainLanguage = options.plainLanguage;
|
|
4659
4670
|
this.headers = {
|
|
4660
4671
|
"Content-Type": "application/json",
|
|
4661
4672
|
// Version telemetry: lets the server correlate behavior per SDK
|
|
@@ -4805,6 +4816,19 @@ var AppilotsClient = class {
|
|
|
4805
4816
|
return {};
|
|
4806
4817
|
}
|
|
4807
4818
|
}
|
|
4819
|
+
/**
|
|
4820
|
+
* Per-session plain-language override — e.g. from the signed-in user's
|
|
4821
|
+
* accessibility profile. `undefined` hands the decision back to the
|
|
4822
|
+
* project setting. Applies from the next request on.
|
|
4823
|
+
*/
|
|
4824
|
+
setPlainLanguage(value) {
|
|
4825
|
+
this.plainLanguage = value;
|
|
4826
|
+
}
|
|
4827
|
+
/** Every relay-bound context carries the reply-style preference. */
|
|
4828
|
+
withPreferences(context) {
|
|
4829
|
+
if (this.plainLanguage === void 0) return context;
|
|
4830
|
+
return { ...context ?? {}, plainLanguage: this.plainLanguage };
|
|
4831
|
+
}
|
|
4808
4832
|
// ── Messages ──────────────────────────────────────────────────
|
|
4809
4833
|
async sendMessage(content, context) {
|
|
4810
4834
|
if (this.sessionStorage && !this.sessionId) await this.loadStoredSession();
|
|
@@ -4818,7 +4842,7 @@ var AppilotsClient = class {
|
|
|
4818
4842
|
body: JSON.stringify({
|
|
4819
4843
|
content,
|
|
4820
4844
|
sessionId: this.sessionId,
|
|
4821
|
-
context,
|
|
4845
|
+
context: this.withPreferences(context),
|
|
4822
4846
|
// Optional MCP version bundled with this app build. Server
|
|
4823
4847
|
// compares vs the active MCP doc to detect stale uploads.
|
|
4824
4848
|
...this.mcpVersion ? { mcpVersion: this.mcpVersion } : {},
|
|
@@ -5083,7 +5107,7 @@ var AppilotsClient = class {
|
|
|
5083
5107
|
JSON.stringify({
|
|
5084
5108
|
content,
|
|
5085
5109
|
sessionId: this.sessionId,
|
|
5086
|
-
context,
|
|
5110
|
+
context: this.withPreferences(context),
|
|
5087
5111
|
...this.mcpVersion ? { mcpVersion: this.mcpVersion } : {},
|
|
5088
5112
|
...this.introspectionFragment()
|
|
5089
5113
|
})
|
|
@@ -5102,7 +5126,9 @@ var AppilotsClient = class {
|
|
|
5102
5126
|
body: JSON.stringify({
|
|
5103
5127
|
sessionId: this.sessionId,
|
|
5104
5128
|
results,
|
|
5105
|
-
context: this.
|
|
5129
|
+
context: this.withPreferences(
|
|
5130
|
+
this.mission ? { ...context, missionProtocol: 1, missionId: this.mission.scope.id } : context
|
|
5131
|
+
),
|
|
5106
5132
|
hop
|
|
5107
5133
|
})
|
|
5108
5134
|
},
|
|
@@ -5190,7 +5216,7 @@ var AppilotsClient = class {
|
|
|
5190
5216
|
body: JSON.stringify({
|
|
5191
5217
|
command,
|
|
5192
5218
|
missionId: this.mission.scope.id,
|
|
5193
|
-
context
|
|
5219
|
+
context: this.withPreferences(context)
|
|
5194
5220
|
})
|
|
5195
5221
|
});
|
|
5196
5222
|
if (command === "resume") this.missionDispatchPaused = false;
|
|
@@ -5577,6 +5603,11 @@ var AppilotsClient = class {
|
|
|
5577
5603
|
};
|
|
5578
5604
|
}
|
|
5579
5605
|
};
|
|
5606
|
+
function isSpeechHost(value) {
|
|
5607
|
+
if (!value || typeof value !== "object") return false;
|
|
5608
|
+
const candidate = value;
|
|
5609
|
+
return typeof candidate.start === "function" && typeof candidate.stop === "function" && typeof candidate.cancel === "function";
|
|
5610
|
+
}
|
|
5580
5611
|
var DESTRUCTIVE_LABEL_RE = /\b(cancelar?\w*|cancel(?:ar|led|ation|amento)?|delete\w*|exclu\w*|delet\w*|remov\w*|remove|apag\w*|destroy\w*|unsubscribe\w*)\b/i;
|
|
5581
5612
|
function looksDestructiveActionLabel(value) {
|
|
5582
5613
|
if (typeof value !== "string" || !value.trim()) return false;
|
|
@@ -6718,6 +6749,10 @@ function actionHasCompletedConfirmGate(action, actions) {
|
|
|
6718
6749
|
return payload.destructive === true || payload.severity === "danger";
|
|
6719
6750
|
});
|
|
6720
6751
|
}
|
|
6752
|
+
function confirmExpiresAt(confirm) {
|
|
6753
|
+
const scope = readPayload(confirm).missionApproval;
|
|
6754
|
+
return typeof scope?.expiresAt === "number" ? scope.expiresAt : void 0;
|
|
6755
|
+
}
|
|
6721
6756
|
var ActionQueueMachine = class {
|
|
6722
6757
|
deps;
|
|
6723
6758
|
options;
|
|
@@ -7223,6 +7258,20 @@ var ActionQueueMachine = class {
|
|
|
7223
7258
|
return this.state.actions.filter((a) => a.status === "completed" || a.status === "failed");
|
|
7224
7259
|
}
|
|
7225
7260
|
};
|
|
7261
|
+
var STILL_WORKING_FIRST_MS = 1e4;
|
|
7262
|
+
var STILL_WORKING_EVERY_MS = 2e4;
|
|
7263
|
+
function startStillWorkingTimer(onTick) {
|
|
7264
|
+
let elapsedMs = STILL_WORKING_FIRST_MS;
|
|
7265
|
+
let timer = setTimeout(function tick() {
|
|
7266
|
+
onTick(Math.round(elapsedMs / 1e3));
|
|
7267
|
+
elapsedMs += STILL_WORKING_EVERY_MS;
|
|
7268
|
+
timer = setTimeout(tick, STILL_WORKING_EVERY_MS);
|
|
7269
|
+
}, STILL_WORKING_FIRST_MS);
|
|
7270
|
+
return () => clearTimeout(timer);
|
|
7271
|
+
}
|
|
7272
|
+
function normalize3(s) {
|
|
7273
|
+
return s.toLowerCase().normalize("NFD").replace(/[\u0300-\u036f]/g, "").replace(/[^a-z0-9]/g, "");
|
|
7274
|
+
}
|
|
7226
7275
|
function matchScore(needle, hay) {
|
|
7227
7276
|
if (!needle || !hay) return 0;
|
|
7228
7277
|
if (needle === hay) return 100;
|
|
@@ -7923,7 +7972,7 @@ function parseInlineMarkdown(text) {
|
|
|
7923
7972
|
}
|
|
7924
7973
|
|
|
7925
7974
|
// src/version.ts
|
|
7926
|
-
var SDK_VERSION2 = "0.
|
|
7975
|
+
var SDK_VERSION2 = "0.3.0";
|
|
7927
7976
|
|
|
7928
7977
|
// src/introspection/locators.ts
|
|
7929
7978
|
var APPILOTS_ID_ATTR = "data-appilots-id";
|
|
@@ -9318,7 +9367,9 @@ function stripComponentPrefix(componentId) {
|
|
|
9318
9367
|
/^(?:button|btn|switch|toggle|slider|input|field|link)[-_](.+)$/i
|
|
9319
9368
|
);
|
|
9320
9369
|
if (kebab?.[1]) return kebab[1];
|
|
9321
|
-
const camel = componentId.match(
|
|
9370
|
+
const camel = componentId.match(
|
|
9371
|
+
/^(?:button|btn|switch|toggle|slider|input|field|link)([A-Z].*)$/
|
|
9372
|
+
);
|
|
9322
9373
|
if (camel?.[1]) return camel[1].charAt(0).toLowerCase() + camel[1].slice(1);
|
|
9323
9374
|
return null;
|
|
9324
9375
|
}
|
|
@@ -9346,7 +9397,8 @@ function matchesKind(el, kind) {
|
|
|
9346
9397
|
return !["checkbox", "radio", "button", "submit", "reset", "image"].includes(type);
|
|
9347
9398
|
}
|
|
9348
9399
|
if (kind === "toggle") {
|
|
9349
|
-
if (tag === "input" && (el.getAttribute("type") ?? "").toLowerCase() === "checkbox")
|
|
9400
|
+
if (tag === "input" && (el.getAttribute("type") ?? "").toLowerCase() === "checkbox")
|
|
9401
|
+
return true;
|
|
9350
9402
|
const role2 = (el.getAttribute("role") ?? "").toLowerCase();
|
|
9351
9403
|
return role2 === "switch" || role2 === "checkbox";
|
|
9352
9404
|
}
|
|
@@ -9365,7 +9417,9 @@ function findListItemElements(listIndex, options = {}) {
|
|
|
9365
9417
|
const root = rootOf(options);
|
|
9366
9418
|
if (typeof root.querySelectorAll !== "function") return void 0;
|
|
9367
9419
|
const containers = Array.from(
|
|
9368
|
-
root.querySelectorAll(
|
|
9420
|
+
root.querySelectorAll(
|
|
9421
|
+
`[${APPILOTS_LIST_ID_ATTR}], ul, ol, table, [role="list"], [role="listbox"], [role="grid"]`
|
|
9422
|
+
)
|
|
9369
9423
|
).filter((el) => !hidesSubtree(el));
|
|
9370
9424
|
const container = containers[listIndex];
|
|
9371
9425
|
if (!container) return void 0;
|
|
@@ -9460,6 +9514,14 @@ function resolveTargetElement(rawId, options = {}) {
|
|
|
9460
9514
|
return { element: el, via: "exact-id" };
|
|
9461
9515
|
}
|
|
9462
9516
|
}
|
|
9517
|
+
const folded = normalize3(id);
|
|
9518
|
+
if (folded) {
|
|
9519
|
+
for (const el of candidates) {
|
|
9520
|
+
if (idCandidatesFor(el).some((candidate) => normalize3(candidate) === folded)) {
|
|
9521
|
+
return { element: el, via: "exact-id" };
|
|
9522
|
+
}
|
|
9523
|
+
}
|
|
9524
|
+
}
|
|
9463
9525
|
const stripped = stripComponentPrefix(id);
|
|
9464
9526
|
if (stripped) {
|
|
9465
9527
|
const strippedLower = stripped.toLowerCase();
|
|
@@ -9474,9 +9536,10 @@ function resolveTargetElement(rawId, options = {}) {
|
|
|
9474
9536
|
let best;
|
|
9475
9537
|
let tied = false;
|
|
9476
9538
|
for (const el of candidates) {
|
|
9539
|
+
if (isSensitiveField(el, bestId(el), accessibleName(el))) continue;
|
|
9477
9540
|
let score = 0;
|
|
9478
9541
|
for (const candidate of idCandidatesFor(el)) {
|
|
9479
|
-
score = Math.max(score, matchScore(
|
|
9542
|
+
score = Math.max(score, matchScore(folded, normalize3(candidate)));
|
|
9480
9543
|
}
|
|
9481
9544
|
if (score < MIN_FUZZY_SCORE) continue;
|
|
9482
9545
|
if (!best || score > best.score) {
|
|
@@ -9506,7 +9569,9 @@ function isOccludedByModal(el, options = {}) {
|
|
|
9506
9569
|
const root = rootOf(options);
|
|
9507
9570
|
if (typeof root.querySelectorAll !== "function") return false;
|
|
9508
9571
|
const modals = Array.from(
|
|
9509
|
-
root.querySelectorAll(
|
|
9572
|
+
root.querySelectorAll(
|
|
9573
|
+
'[aria-modal="true"], [role="dialog"], [role="alertdialog"], dialog[open]'
|
|
9574
|
+
)
|
|
9510
9575
|
).filter((modal) => !hidesSubtree(modal) && isVisible(modal));
|
|
9511
9576
|
if (modals.length === 0) return false;
|
|
9512
9577
|
return !modals.some((modal) => modal === el || modal.contains(el));
|
|
@@ -9515,7 +9580,9 @@ function modalCandidateLabels(options = {}, limit = 8) {
|
|
|
9515
9580
|
const root = rootOf(options);
|
|
9516
9581
|
if (typeof root.querySelectorAll !== "function") return [];
|
|
9517
9582
|
const modal = Array.from(
|
|
9518
|
-
root.querySelectorAll(
|
|
9583
|
+
root.querySelectorAll(
|
|
9584
|
+
'[aria-modal="true"], [role="dialog"], [role="alertdialog"], dialog[open]'
|
|
9585
|
+
)
|
|
9519
9586
|
).find((candidate) => !hidesSubtree(candidate));
|
|
9520
9587
|
if (!modal) return [];
|
|
9521
9588
|
const out = [];
|
|
@@ -9550,6 +9617,21 @@ function readVisibleValidation(context) {
|
|
|
9550
9617
|
const snapshot = captureSnapshot({ root: rootElement(context) });
|
|
9551
9618
|
return snapshot.texts.find((text) => FORM_VALIDATION_TEXT_RE2.test(text));
|
|
9552
9619
|
}
|
|
9620
|
+
var SUBMIT_SETTLE_MAX_MS = 6e3;
|
|
9621
|
+
function readAlertTexts(context) {
|
|
9622
|
+
const root = rootElement(context) ?? (typeof document !== "undefined" ? document.body : void 0);
|
|
9623
|
+
if (!root) return [];
|
|
9624
|
+
return Array.from(root.querySelectorAll('[role="alert"], [aria-live="assertive"]')).filter((el) => !hidesSubtree(el)).map((el) => (el.textContent ?? "").trim()).filter(Boolean);
|
|
9625
|
+
}
|
|
9626
|
+
async function waitForSubmitSettle(submit, context) {
|
|
9627
|
+
const busy = () => submit.isConnected && (submit.disabled || submit.getAttribute("aria-disabled") === "true") || captureSnapshot({ root: rootElement(context) }).loading;
|
|
9628
|
+
const started = Date.now();
|
|
9629
|
+
while (busy()) {
|
|
9630
|
+
if (context.signal?.aborted || Date.now() - started >= SUBMIT_SETTLE_MAX_MS) return !busy();
|
|
9631
|
+
await sleep2(100);
|
|
9632
|
+
}
|
|
9633
|
+
return true;
|
|
9634
|
+
}
|
|
9553
9635
|
function rootElement(context) {
|
|
9554
9636
|
const root = context.root;
|
|
9555
9637
|
if (!root) return void 0;
|
|
@@ -9755,6 +9837,18 @@ async function formFillHandler(payload, context, permissions) {
|
|
|
9755
9837
|
setToggleValue(el, value2);
|
|
9756
9838
|
continue;
|
|
9757
9839
|
}
|
|
9840
|
+
if (el.tagName.toLowerCase() === "input" && el.type === "file") {
|
|
9841
|
+
failures.push({
|
|
9842
|
+
fieldId: field.fieldId,
|
|
9843
|
+
error: `Field "${field.fieldId}" is a file picker; only the user can attach a file`,
|
|
9844
|
+
diagnose: diagnose(context, "validation", {
|
|
9845
|
+
fieldId: field.fieldId,
|
|
9846
|
+
recoverable: false,
|
|
9847
|
+
requiresUserInput: true
|
|
9848
|
+
})
|
|
9849
|
+
});
|
|
9850
|
+
continue;
|
|
9851
|
+
}
|
|
9758
9852
|
const value = field.value == null ? "" : String(field.value);
|
|
9759
9853
|
const written = setControlValue(el, value);
|
|
9760
9854
|
if (!written) {
|
|
@@ -9822,6 +9916,7 @@ async function formFillHandler(payload, context, permissions) {
|
|
|
9822
9916
|
context
|
|
9823
9917
|
);
|
|
9824
9918
|
if (blocked) return { success: false, ...blocked };
|
|
9919
|
+
const alertsBefore = new Set(readAlertTexts(context));
|
|
9825
9920
|
clickElement(submit);
|
|
9826
9921
|
await sleep2(120);
|
|
9827
9922
|
if (context.signal?.aborted) return { success: false, error: "Session ended" };
|
|
@@ -9834,6 +9929,30 @@ async function formFillHandler(payload, context, permissions) {
|
|
|
9834
9929
|
effect: "partial"
|
|
9835
9930
|
};
|
|
9836
9931
|
}
|
|
9932
|
+
const settled = await waitForSubmitSettle(submit, context);
|
|
9933
|
+
if (context.signal?.aborted) return { success: false, error: "Session ended" };
|
|
9934
|
+
if (!settled) {
|
|
9935
|
+
return {
|
|
9936
|
+
success: false,
|
|
9937
|
+
error: `Submit still in progress after ${SUBMIT_SETTLE_MAX_MS / 1e3}s \u2014 outcome unknown, do not report it as saved`,
|
|
9938
|
+
diagnose: diagnose(context, "screen-timeout", { recoverable: false }),
|
|
9939
|
+
effect: "unknown"
|
|
9940
|
+
};
|
|
9941
|
+
}
|
|
9942
|
+
const lateValidation = readVisibleValidation(context);
|
|
9943
|
+
const rejection = lateValidation ?? readAlertTexts(context).find((text) => !alertsBefore.has(text));
|
|
9944
|
+
if (rejection) {
|
|
9945
|
+
return {
|
|
9946
|
+
success: false,
|
|
9947
|
+
error: `Submit was rejected: ${rejection}`,
|
|
9948
|
+
diagnose: lateValidation ? diagnose(context, "validation", { visibleMessage: rejection, recoverable: true }) : (
|
|
9949
|
+
// Server-side failure (5xx, expired session, timeout): retrying
|
|
9950
|
+
// blindly can double-submit or loop, so hand it to the user.
|
|
9951
|
+
diagnose(context, "unknown", { visibleMessage: rejection, recoverable: false })
|
|
9952
|
+
),
|
|
9953
|
+
effect: "partial"
|
|
9954
|
+
};
|
|
9955
|
+
}
|
|
9837
9956
|
return { success: true, effect: "completed" };
|
|
9838
9957
|
}
|
|
9839
9958
|
return { success: true, effect: "changed" };
|
|
@@ -10152,6 +10271,14 @@ async function withSuppressedConfirm(context, fn) {
|
|
|
10152
10271
|
}
|
|
10153
10272
|
|
|
10154
10273
|
// src/runtime/AppilotsWebRuntime.ts
|
|
10274
|
+
function browserLocale() {
|
|
10275
|
+
if (typeof navigator === "undefined") return void 0;
|
|
10276
|
+
for (const language of navigator.languages ?? [navigator.language]) {
|
|
10277
|
+
const locale = normalizeAppilotsLocale(language);
|
|
10278
|
+
if (locale) return locale;
|
|
10279
|
+
}
|
|
10280
|
+
return void 0;
|
|
10281
|
+
}
|
|
10155
10282
|
var POST_ACTION_LOADING_MAX_MS = 6e3;
|
|
10156
10283
|
var AppilotsWebRuntime = class {
|
|
10157
10284
|
client;
|
|
@@ -10177,13 +10304,15 @@ var AppilotsWebRuntime = class {
|
|
|
10177
10304
|
apiKey: options.apiKey,
|
|
10178
10305
|
apiBaseUrl: options.apiBaseUrl,
|
|
10179
10306
|
debug: options.debug,
|
|
10307
|
+
timeout: options.timeout,
|
|
10180
10308
|
appVersion: options.appVersion,
|
|
10181
10309
|
mcpVersion: options.mcpVersion,
|
|
10182
10310
|
// This package's own version, so the server can tell a web
|
|
10183
10311
|
// client apart from an RN one by more than the platform field
|
|
10184
10312
|
// (issue #312).
|
|
10185
10313
|
sdkVersion: SDK_VERSION2,
|
|
10186
|
-
user: options.user
|
|
10314
|
+
user: options.user,
|
|
10315
|
+
plainLanguage: options.plainLanguage
|
|
10187
10316
|
});
|
|
10188
10317
|
this.navigation = new WebNavigationAdapter({
|
|
10189
10318
|
routes: options.routes,
|
|
@@ -10249,6 +10378,8 @@ var AppilotsWebRuntime = class {
|
|
|
10249
10378
|
buildContext(extras = {}) {
|
|
10250
10379
|
if (extras.newMission === true) this.deltaTracker.reset();
|
|
10251
10380
|
const context = { platform: "web" };
|
|
10381
|
+
const deviceLocale = browserLocale();
|
|
10382
|
+
if (deviceLocale) context.deviceLocale = deviceLocale;
|
|
10252
10383
|
const screen = this.navigation.getCurrentScreen();
|
|
10253
10384
|
if (screen) context.currentScreen = screen;
|
|
10254
10385
|
const navigationState = this.navigation.getNavigationState();
|
|
@@ -10379,4 +10510,106 @@ var AppilotsWebRuntime = class {
|
|
|
10379
10510
|
}
|
|
10380
10511
|
};
|
|
10381
10512
|
|
|
10382
|
-
|
|
10513
|
+
// src/speech/webSpeechHost.ts
|
|
10514
|
+
var MAX_SILENT_RESTARTS = 5;
|
|
10515
|
+
function recognitionCtor() {
|
|
10516
|
+
const g = globalThis;
|
|
10517
|
+
return g.SpeechRecognition ?? g.webkitSpeechRecognition ?? null;
|
|
10518
|
+
}
|
|
10519
|
+
function isWebSpeechSupported() {
|
|
10520
|
+
return recognitionCtor() !== null;
|
|
10521
|
+
}
|
|
10522
|
+
function createWebSpeechHost() {
|
|
10523
|
+
const Ctor = recognitionCtor();
|
|
10524
|
+
if (!Ctor) return null;
|
|
10525
|
+
let live = null;
|
|
10526
|
+
let committed = "";
|
|
10527
|
+
let current = "";
|
|
10528
|
+
let silentRestarts = 0;
|
|
10529
|
+
let pendingStop = null;
|
|
10530
|
+
const partialListeners = /* @__PURE__ */ new Set();
|
|
10531
|
+
const endListeners = /* @__PURE__ */ new Set();
|
|
10532
|
+
const text = () => `${committed} ${current}`.replace(/\s+/g, " ").trim();
|
|
10533
|
+
const ended = (error) => endListeners.forEach((l) => l(error));
|
|
10534
|
+
const open = (locale) => new Promise((resolve, reject) => {
|
|
10535
|
+
const r = new Ctor();
|
|
10536
|
+
live = r;
|
|
10537
|
+
r.lang = locale;
|
|
10538
|
+
r.continuous = true;
|
|
10539
|
+
r.interimResults = true;
|
|
10540
|
+
let started = false;
|
|
10541
|
+
let failure;
|
|
10542
|
+
r.onstart = () => {
|
|
10543
|
+
started = true;
|
|
10544
|
+
resolve();
|
|
10545
|
+
};
|
|
10546
|
+
r.onresult = ({ results }) => {
|
|
10547
|
+
if (live !== r) return;
|
|
10548
|
+
let next = "";
|
|
10549
|
+
for (let i = 0; i < results.length; i++) next += results[i]?.[0]?.transcript ?? "";
|
|
10550
|
+
current = next;
|
|
10551
|
+
silentRestarts = 0;
|
|
10552
|
+
const t = text();
|
|
10553
|
+
partialListeners.forEach((l) => l(t));
|
|
10554
|
+
};
|
|
10555
|
+
r.onerror = ({ error }) => {
|
|
10556
|
+
if (error !== "no-speech") failure = error;
|
|
10557
|
+
};
|
|
10558
|
+
r.onend = () => {
|
|
10559
|
+
if (live !== r) return;
|
|
10560
|
+
if (pendingStop) {
|
|
10561
|
+
const done = pendingStop;
|
|
10562
|
+
pendingStop = null;
|
|
10563
|
+
live = null;
|
|
10564
|
+
done(text());
|
|
10565
|
+
return;
|
|
10566
|
+
}
|
|
10567
|
+
live = null;
|
|
10568
|
+
if (!started) {
|
|
10569
|
+
reject(new Error(failure ?? "speech recognition did not start"));
|
|
10570
|
+
return;
|
|
10571
|
+
}
|
|
10572
|
+
if (failure) return ended(new Error(failure));
|
|
10573
|
+
if (silentRestarts >= MAX_SILENT_RESTARTS) return ended();
|
|
10574
|
+
silentRestarts++;
|
|
10575
|
+
committed = text();
|
|
10576
|
+
current = "";
|
|
10577
|
+
open(locale).catch(ended);
|
|
10578
|
+
};
|
|
10579
|
+
r.start();
|
|
10580
|
+
});
|
|
10581
|
+
return {
|
|
10582
|
+
start({ locale }) {
|
|
10583
|
+
live?.abort();
|
|
10584
|
+
committed = "";
|
|
10585
|
+
current = "";
|
|
10586
|
+
silentRestarts = 0;
|
|
10587
|
+
pendingStop = null;
|
|
10588
|
+
return open(locale);
|
|
10589
|
+
},
|
|
10590
|
+
stop() {
|
|
10591
|
+
const r = live;
|
|
10592
|
+
if (!r) return Promise.resolve(text());
|
|
10593
|
+
return new Promise((resolve) => {
|
|
10594
|
+
pendingStop = resolve;
|
|
10595
|
+
r.stop();
|
|
10596
|
+
});
|
|
10597
|
+
},
|
|
10598
|
+
async cancel() {
|
|
10599
|
+
const r = live;
|
|
10600
|
+
live = null;
|
|
10601
|
+
pendingStop = null;
|
|
10602
|
+
r?.abort();
|
|
10603
|
+
},
|
|
10604
|
+
onPartial(listener) {
|
|
10605
|
+
partialListeners.add(listener);
|
|
10606
|
+
return () => partialListeners.delete(listener);
|
|
10607
|
+
},
|
|
10608
|
+
onEnd(listener) {
|
|
10609
|
+
endListeners.add(listener);
|
|
10610
|
+
return () => endListeners.delete(listener);
|
|
10611
|
+
}
|
|
10612
|
+
};
|
|
10613
|
+
}
|
|
10614
|
+
|
|
10615
|
+
export { APPILOTS_CHAT_ATTR, APPILOTS_ID_ATTR, APPILOTS_ITEM_COUNT_ATTR, APPILOTS_ITEM_INDEX_ATTR, APPILOTS_ITEM_KEY_ATTR, APPILOTS_LIST_ID_ATTR, APPILOTS_LIST_ITEM_ATTR, APPILOTS_SENSITIVE_ATTR, APPILOTS_SKIP_ATTR, ActionQueueMachine, AppilotsClient, AppilotsWebRuntime, ChatSessionMachine, RateLimitedError, SDK_VERSION2 as SDK_VERSION, WebNavigationAdapter, accessibleName, appilotsDebugWarn, bestId, buildPath, candidateIds, captureSnapshot, clickElement, confirmExpiresAt, createWebSpeechHost, describeAction, elementRole, executeAction, findListItemElements, findScrollContainer, focusElement, getRegisteredElement, hidesSubtree, humanizeError, isOccludedByModal, isSpeechHost, isVisible, isWebSpeechSupported, longPressElement, matchRoute, modalCandidateLabels, normalizeLabelToId, parseInlineMarkdown, parseMarkdownBlocks, parseSyntheticListItemId, primaryControlOf, probeLoadingState, readControlValue, readOwnText, readScrollMetrics, readToggleValue, registeredElements, resolveListItem, resolveTargetElement, routesBelongToSameFeature2 as routesBelongToSameFeature, screenDepartedBaseline, scrollIntoView, scrollToOffset, setControlValue, setToggleValue, startStillWorkingTimer, stripComponentPrefix, waitForLoadingSettle, waitForScreenSettle, walkDom };
|
package/dist/index.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { C as ControlEvidence, A as AgentAction, a as AppilotsLocale, b as AgentPermissions, c as AppilotsEvent, W as WebNavigationAdapter, S as ScreenActionMetadataLike, d as ActionExecutionResult } from './
|
|
2
|
-
export { e as ActionDiagnose, f as ActionQueueMachine, g as AgentActionType, h as AppilotsClient, i as AppilotsEventHandler, j as AppilotsWebRuntime, k as AppilotsWebRuntimeOptions, l as ChatMessage, m as ChatSessionMachine, n as ChatSessionOptions, o as ChatSessionState, E as EscalationState, p as EscalationStrings, R as RateLimitedError, q as
|
|
1
|
+
import { C as ControlEvidence, A as AgentAction, a as AppilotsLocale, b as AgentPermissions, c as AppilotsEvent, W as WebNavigationAdapter, S as ScreenActionMetadataLike, d as ActionExecutionResult } from './webSpeechHost-CrTKADeb.mjs';
|
|
2
|
+
export { e as ActionDiagnose, f as ActionQueueMachine, g as AgentActionType, h as AppilotsClient, i as AppilotsEventHandler, j as AppilotsWebRuntime, k as AppilotsWebRuntimeOptions, l as ChatMessage, m as ChatSessionMachine, n as ChatSessionOptions, o as ChatSessionState, E as EscalationState, p as EscalationStrings, R as RateLimitedError, q as SpeechHost, r as SpeechStartOptions, s as SpeechState, t as WebNavigationAdapterOptions, u as WebNavigationState, v as WebRoute, w as WebScreenMetadata, x as buildPath, y as createWebSpeechHost, z as isSpeechHost, B as isWebSpeechSupported, D as matchRoute } from './webSpeechHost-CrTKADeb.mjs';
|
|
3
3
|
|
|
4
4
|
type ActionPresentationState = 'pending' | 'running' | 'success' | 'failed';
|
|
5
5
|
|
|
@@ -1005,6 +1005,6 @@ declare function scrollToOffset(container: Element, offset: number): boolean;
|
|
|
1005
1005
|
* (`X-Appilots-Sdk-Version`). Kept identical to package.json by the
|
|
1006
1006
|
* release flow; `version.test.ts` fails if the two ever disagree.
|
|
1007
1007
|
*/
|
|
1008
|
-
declare const SDK_VERSION = "0.
|
|
1008
|
+
declare const SDK_VERSION = "0.3.0";
|
|
1009
1009
|
|
|
1010
1010
|
export { APPILOTS_CHAT_ATTR, APPILOTS_ID_ATTR, APPILOTS_ITEM_COUNT_ATTR, APPILOTS_ITEM_INDEX_ATTR, APPILOTS_ITEM_KEY_ATTR, APPILOTS_LIST_ID_ATTR, APPILOTS_LIST_ITEM_ATTR, APPILOTS_SENSITIVE_ATTR, APPILOTS_SKIP_ATTR, ActionExecutionResult, AgentAction, AgentPermissions, AppilotsEvent, type LoadingProbeResult, type LoadingSettleOptions, type LoadingSettleResult, type ResolveOptions, type ResolvedTarget, SDK_VERSION, type ScreenSettleOptions, type ScreenSettleResult, type ScreenSnapshot, type ScrollMetrics, type SettleProbes, type WalkDomOptions, type WebExecutorContext, WebNavigationAdapter, accessibleName, bestId, candidateIds, captureSnapshot, clickElement, describeAction, elementRole, executeAction, findListItemElements, findScrollContainer, focusElement, getRegisteredElement, hidesSubtree, humanizeError, isOccludedByModal, isVisible, longPressElement, modalCandidateLabels, normalizeLabelToId, parseSyntheticListItemId, primaryControlOf, probeLoadingState, readControlValue, readOwnText, readScrollMetrics, readToggleValue, registeredElements, resolveListItem, resolveTargetElement, routesBelongToSameFeature, screenDepartedBaseline, scrollIntoView, scrollToOffset, setControlValue, setToggleValue, stripComponentPrefix, waitForLoadingSettle, waitForScreenSettle, walkDom };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { C as ControlEvidence, A as AgentAction, a as AppilotsLocale, b as AgentPermissions, c as AppilotsEvent, W as WebNavigationAdapter, S as ScreenActionMetadataLike, d as ActionExecutionResult } from './
|
|
2
|
-
export { e as ActionDiagnose, f as ActionQueueMachine, g as AgentActionType, h as AppilotsClient, i as AppilotsEventHandler, j as AppilotsWebRuntime, k as AppilotsWebRuntimeOptions, l as ChatMessage, m as ChatSessionMachine, n as ChatSessionOptions, o as ChatSessionState, E as EscalationState, p as EscalationStrings, R as RateLimitedError, q as
|
|
1
|
+
import { C as ControlEvidence, A as AgentAction, a as AppilotsLocale, b as AgentPermissions, c as AppilotsEvent, W as WebNavigationAdapter, S as ScreenActionMetadataLike, d as ActionExecutionResult } from './webSpeechHost-CrTKADeb.js';
|
|
2
|
+
export { e as ActionDiagnose, f as ActionQueueMachine, g as AgentActionType, h as AppilotsClient, i as AppilotsEventHandler, j as AppilotsWebRuntime, k as AppilotsWebRuntimeOptions, l as ChatMessage, m as ChatSessionMachine, n as ChatSessionOptions, o as ChatSessionState, E as EscalationState, p as EscalationStrings, R as RateLimitedError, q as SpeechHost, r as SpeechStartOptions, s as SpeechState, t as WebNavigationAdapterOptions, u as WebNavigationState, v as WebRoute, w as WebScreenMetadata, x as buildPath, y as createWebSpeechHost, z as isSpeechHost, B as isWebSpeechSupported, D as matchRoute } from './webSpeechHost-CrTKADeb.js';
|
|
3
3
|
|
|
4
4
|
type ActionPresentationState = 'pending' | 'running' | 'success' | 'failed';
|
|
5
5
|
|
|
@@ -1005,6 +1005,6 @@ declare function scrollToOffset(container: Element, offset: number): boolean;
|
|
|
1005
1005
|
* (`X-Appilots-Sdk-Version`). Kept identical to package.json by the
|
|
1006
1006
|
* release flow; `version.test.ts` fails if the two ever disagree.
|
|
1007
1007
|
*/
|
|
1008
|
-
declare const SDK_VERSION = "0.
|
|
1008
|
+
declare const SDK_VERSION = "0.3.0";
|
|
1009
1009
|
|
|
1010
1010
|
export { APPILOTS_CHAT_ATTR, APPILOTS_ID_ATTR, APPILOTS_ITEM_COUNT_ATTR, APPILOTS_ITEM_INDEX_ATTR, APPILOTS_ITEM_KEY_ATTR, APPILOTS_LIST_ID_ATTR, APPILOTS_LIST_ITEM_ATTR, APPILOTS_SENSITIVE_ATTR, APPILOTS_SKIP_ATTR, ActionExecutionResult, AgentAction, AgentPermissions, AppilotsEvent, type LoadingProbeResult, type LoadingSettleOptions, type LoadingSettleResult, type ResolveOptions, type ResolvedTarget, SDK_VERSION, type ScreenSettleOptions, type ScreenSettleResult, type ScreenSnapshot, type ScrollMetrics, type SettleProbes, type WalkDomOptions, type WebExecutorContext, WebNavigationAdapter, accessibleName, bestId, candidateIds, captureSnapshot, clickElement, describeAction, elementRole, executeAction, findListItemElements, findScrollContainer, focusElement, getRegisteredElement, hidesSubtree, humanizeError, isOccludedByModal, isVisible, longPressElement, modalCandidateLabels, normalizeLabelToId, parseSyntheticListItemId, primaryControlOf, probeLoadingState, readControlValue, readOwnText, readScrollMetrics, readToggleValue, registeredElements, resolveListItem, resolveTargetElement, routesBelongToSameFeature, screenDepartedBaseline, scrollIntoView, scrollToOffset, setControlValue, setToggleValue, stripComponentPrefix, waitForLoadingSettle, waitForScreenSettle, walkDom };
|