@myscheme/voice-navigation-sdk 0.1.0 → 0.1.2
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 +587 -134
- package/dist/actions.d.ts +3 -0
- package/dist/actions.d.ts.map +1 -1
- package/dist/actions.js +37 -97
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -1
- package/dist/navigation-controller.d.ts +3 -0
- package/dist/navigation-controller.d.ts.map +1 -1
- package/dist/navigation-controller.js +57 -8
- package/dist/services/bedrock.d.ts +4 -0
- package/dist/services/bedrock.d.ts.map +1 -1
- package/dist/services/bedrock.js +52 -15
- package/dist/services/page-registry.d.ts +25 -0
- package/dist/services/page-registry.d.ts.map +1 -0
- package/dist/services/page-registry.js +82 -0
- package/dist/services/xml-parser.d.ts +9 -0
- package/dist/services/xml-parser.d.ts.map +1 -0
- package/dist/services/xml-parser.js +60 -0
- package/dist/types.d.ts +14 -1
- package/dist/types.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/actions.d.ts
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
import type { NavigationAction, ActionContext, ActionResult, AgentActionResponse } from "./types.js";
|
|
2
|
+
import type { PageRegistry } from "./services/page-registry.js";
|
|
3
|
+
export declare const setPageRegistry: (registry: PageRegistry) => void;
|
|
4
|
+
export declare const getPageRegistry: () => PageRegistry | null;
|
|
2
5
|
export declare const setZoomScale: (scale: number) => number;
|
|
3
6
|
export declare const adjustZoom: (delta: number) => number;
|
|
4
7
|
export declare const formatActionLabel: (action: string) => string;
|
package/dist/actions.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"actions.d.ts","sourceRoot":"","sources":["../src/actions.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EACV,gBAAgB,
|
|
1
|
+
{"version":3,"file":"actions.d.ts","sourceRoot":"","sources":["../src/actions.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EACV,gBAAgB,EAEhB,aAAa,EACb,YAAY,EACZ,mBAAmB,EACpB,MAAM,YAAY,CAAC;AACpB,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAsChE,eAAO,MAAM,eAAe,GAAI,UAAU,YAAY,KAAG,IAOxD,CAAC;AAKF,eAAO,MAAM,eAAe,QAAO,YAAY,GAAG,IAEjD,CAAC;AAkCF,eAAO,MAAM,YAAY,GAAI,OAAO,MAAM,KAAG,MAS5C,CAAC;AAKF,eAAO,MAAM,UAAU,GAAI,OAAO,MAAM,KAAG,MAM1C,CAAC;AAKF,eAAO,MAAM,iBAAiB,GAAI,QAAQ,MAAM,KAAG,MAElD,CAAC;AAKF,eAAO,MAAM,kBAAkB,GAC7B,QAAQ,gBAAgB,EACxB,UAAS,aAAkB,KAC1B,YA4VF,CAAC;AAKF,eAAO,MAAM,kBAAkB,GAAI,QAAQ,GAAG,KAAG,mBAAmB,GAAG,IAiCtE,CAAC;AAKF,eAAO,MAAM,eAAe,GAAI,QAAQ,MAAM,KAAG,MAAM,IAAI,gBAY1D,CAAC"}
|
package/dist/actions.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const
|
|
1
|
+
const CORE_ACTIONS = new Set([
|
|
2
2
|
"zoom_in",
|
|
3
3
|
"zoom_out",
|
|
4
4
|
"scroll_up",
|
|
@@ -23,20 +23,20 @@ const ALLOWED_ACTIONS = new Set([
|
|
|
23
23
|
"pause_media",
|
|
24
24
|
"mute_media",
|
|
25
25
|
"unmute_media",
|
|
26
|
-
"navigate_home",
|
|
27
26
|
"search_content",
|
|
28
|
-
"navigate_search",
|
|
29
|
-
"navigate_faqs",
|
|
30
|
-
"navigate_help",
|
|
31
|
-
"navigate_contact",
|
|
32
|
-
"navigate_about",
|
|
33
|
-
"navigate_screen_reader",
|
|
34
|
-
"navigate_accessibility",
|
|
35
|
-
"navigate_disclaimer",
|
|
36
|
-
"navigate_terms_conditions",
|
|
37
27
|
"stop",
|
|
38
28
|
"unknown",
|
|
39
29
|
]);
|
|
30
|
+
let globalPageRegistry = null;
|
|
31
|
+
export const setPageRegistry = (registry) => {
|
|
32
|
+
globalPageRegistry = registry;
|
|
33
|
+
if (typeof window !== "undefined") {
|
|
34
|
+
window.__navigatePageRegistry = registry;
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
export const getPageRegistry = () => {
|
|
38
|
+
return globalPageRegistry;
|
|
39
|
+
};
|
|
40
40
|
const ZOOM_STEP = 0.1;
|
|
41
41
|
const MIN_ZOOM = 0.5;
|
|
42
42
|
const MAX_ZOOM = 2.0;
|
|
@@ -337,92 +337,12 @@ export const performAgentAction = (action, context = {}) => {
|
|
|
337
337
|
}
|
|
338
338
|
break;
|
|
339
339
|
}
|
|
340
|
-
case "navigate_home": {
|
|
341
|
-
notifyNavigationIntent(context, "/");
|
|
342
|
-
window.location.href = "/";
|
|
343
|
-
console.log("Navigating to home");
|
|
344
|
-
info.navigated = true;
|
|
345
|
-
performed = true;
|
|
346
|
-
break;
|
|
347
|
-
}
|
|
348
340
|
case "search_content": {
|
|
349
341
|
console.log("Vector search action delegated to controller");
|
|
350
342
|
info.searchPending = true;
|
|
351
343
|
performed = false;
|
|
352
344
|
break;
|
|
353
345
|
}
|
|
354
|
-
case "navigate_search": {
|
|
355
|
-
notifyNavigationIntent(context, "/search");
|
|
356
|
-
window.location.href = "/search";
|
|
357
|
-
console.log("Navigating to search");
|
|
358
|
-
info.navigated = true;
|
|
359
|
-
performed = true;
|
|
360
|
-
break;
|
|
361
|
-
}
|
|
362
|
-
case "navigate_faqs": {
|
|
363
|
-
notifyNavigationIntent(context, "/faqs");
|
|
364
|
-
window.location.href = "/faqs";
|
|
365
|
-
console.log("Navigating to FAQs");
|
|
366
|
-
info.navigated = true;
|
|
367
|
-
performed = true;
|
|
368
|
-
break;
|
|
369
|
-
}
|
|
370
|
-
case "navigate_help": {
|
|
371
|
-
notifyNavigationIntent(context, "/help");
|
|
372
|
-
window.location.href = "/help";
|
|
373
|
-
console.log("Navigating to help");
|
|
374
|
-
info.navigated = true;
|
|
375
|
-
performed = true;
|
|
376
|
-
break;
|
|
377
|
-
}
|
|
378
|
-
case "navigate_contact": {
|
|
379
|
-
notifyNavigationIntent(context, "/contact");
|
|
380
|
-
window.location.href = "/contact";
|
|
381
|
-
console.log("Navigating to contact");
|
|
382
|
-
info.navigated = true;
|
|
383
|
-
performed = true;
|
|
384
|
-
break;
|
|
385
|
-
}
|
|
386
|
-
case "navigate_about": {
|
|
387
|
-
notifyNavigationIntent(context, "/about");
|
|
388
|
-
window.location.href = "/about";
|
|
389
|
-
console.log("Navigating to about");
|
|
390
|
-
info.navigated = true;
|
|
391
|
-
performed = true;
|
|
392
|
-
break;
|
|
393
|
-
}
|
|
394
|
-
case "navigate_screen_reader": {
|
|
395
|
-
notifyNavigationIntent(context, "/screen-reader-access");
|
|
396
|
-
window.location.href = "/screen-reader-access";
|
|
397
|
-
console.log("Navigating to screen reader");
|
|
398
|
-
info.navigated = true;
|
|
399
|
-
performed = true;
|
|
400
|
-
break;
|
|
401
|
-
}
|
|
402
|
-
case "navigate_accessibility": {
|
|
403
|
-
notifyNavigationIntent(context, "/accessibility");
|
|
404
|
-
window.location.href = "/accessibility";
|
|
405
|
-
console.log("Navigating to accessibility");
|
|
406
|
-
info.navigated = true;
|
|
407
|
-
performed = true;
|
|
408
|
-
break;
|
|
409
|
-
}
|
|
410
|
-
case "navigate_disclaimer": {
|
|
411
|
-
notifyNavigationIntent(context, "/disclaimer");
|
|
412
|
-
window.location.href = "/disclaimer";
|
|
413
|
-
console.log("Navigating to disclaimer");
|
|
414
|
-
info.navigated = true;
|
|
415
|
-
performed = true;
|
|
416
|
-
break;
|
|
417
|
-
}
|
|
418
|
-
case "navigate_terms_conditions": {
|
|
419
|
-
notifyNavigationIntent(context, "/terms-and-conditions");
|
|
420
|
-
window.location.href = "/terms-and-conditions";
|
|
421
|
-
console.log("Navigating to terms and conditions");
|
|
422
|
-
info.navigated = true;
|
|
423
|
-
performed = true;
|
|
424
|
-
break;
|
|
425
|
-
}
|
|
426
346
|
case "stop": {
|
|
427
347
|
console.log("Stop command received");
|
|
428
348
|
if (onStop) {
|
|
@@ -432,6 +352,22 @@ export const performAgentAction = (action, context = {}) => {
|
|
|
432
352
|
break;
|
|
433
353
|
}
|
|
434
354
|
default: {
|
|
355
|
+
if (action.startsWith("navigate_") && globalPageRegistry) {
|
|
356
|
+
const pageId = globalPageRegistry.getPageIdFromAction(action);
|
|
357
|
+
if (pageId) {
|
|
358
|
+
const page = globalPageRegistry.getPageById(pageId);
|
|
359
|
+
if (page) {
|
|
360
|
+
notifyNavigationIntent(context, page.path);
|
|
361
|
+
window.location.href = page.path;
|
|
362
|
+
console.log(`Navigating to ${page.name} (${page.path})`);
|
|
363
|
+
info.navigated = true;
|
|
364
|
+
info.pageName = page.name;
|
|
365
|
+
info.pagePath = page.path;
|
|
366
|
+
performed = true;
|
|
367
|
+
break;
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
}
|
|
435
371
|
console.log(`Unknown action: ${action}`);
|
|
436
372
|
performed = false;
|
|
437
373
|
break;
|
|
@@ -446,8 +382,10 @@ export const extractAgentAction = (result) => {
|
|
|
446
382
|
if (!result) {
|
|
447
383
|
return null;
|
|
448
384
|
}
|
|
385
|
+
if (typeof result === "object" && !Array.isArray(result) && result.action) {
|
|
386
|
+
return result;
|
|
387
|
+
}
|
|
449
388
|
let raw = "";
|
|
450
|
-
console.log("Extracting action from result:", result, typeof result);
|
|
451
389
|
if (typeof result === "string") {
|
|
452
390
|
raw = result;
|
|
453
391
|
}
|
|
@@ -457,10 +395,6 @@ export const extractAgentAction = (result) => {
|
|
|
457
395
|
else if (result.text) {
|
|
458
396
|
raw = result.text;
|
|
459
397
|
}
|
|
460
|
-
else if (typeof result === "object" && result?.action) {
|
|
461
|
-
raw = result?.action;
|
|
462
|
-
}
|
|
463
|
-
console.log("raw reslt", raw, result);
|
|
464
398
|
if (!raw) {
|
|
465
399
|
return null;
|
|
466
400
|
}
|
|
@@ -474,5 +408,11 @@ export const extractAgentAction = (result) => {
|
|
|
474
408
|
}
|
|
475
409
|
};
|
|
476
410
|
export const isAllowedAction = (action) => {
|
|
477
|
-
|
|
411
|
+
if (CORE_ACTIONS.has(action)) {
|
|
412
|
+
return true;
|
|
413
|
+
}
|
|
414
|
+
if (action.startsWith("navigate_") && globalPageRegistry) {
|
|
415
|
+
return globalPageRegistry.isPageNavigationAction(action);
|
|
416
|
+
}
|
|
417
|
+
return false;
|
|
478
418
|
};
|
package/dist/index.d.ts
CHANGED
|
@@ -2,6 +2,10 @@ export { VoiceNavigationController } from "./navigation-controller.js";
|
|
|
2
2
|
export { MicrophoneHandler } from "./microphone-handler.js";
|
|
3
3
|
export { AzureSpeechService } from "./services/azure-speech.js";
|
|
4
4
|
export { BedrockService } from "./services/bedrock.js";
|
|
5
|
+
export { PageRegistry } from "./services/page-registry.js";
|
|
6
|
+
export type { NavigablePage } from "./services/page-registry.js";
|
|
7
|
+
export { parseNavigationXML, fetchNavigationXML, loadNavigationPages, } from "./services/xml-parser.js";
|
|
8
|
+
export type { PageXMLConfig } from "./services/xml-parser.js";
|
|
5
9
|
export * from "./types.js";
|
|
6
10
|
export * from "./actions.js";
|
|
7
11
|
export * from "./ui.js";
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,yBAAyB,EAAE,MAAM,4BAA4B,CAAC;AACvE,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAChE,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,cAAc,YAAY,CAAC;AAC3B,cAAc,cAAc,CAAC;AAC7B,cAAc,SAAS,CAAC;AAExB,OAAO,EAAE,yBAAyB,EAAE,MAAM,4BAA4B,CAAC;AACvE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,yBAAyB,EAAE,MAAM,4BAA4B,CAAC;AACvE,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAChE,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAC3D,YAAY,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AACjE,OAAO,EACL,kBAAkB,EAClB,kBAAkB,EAClB,mBAAmB,GACpB,MAAM,0BAA0B,CAAC;AAClC,YAAY,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAC9D,cAAc,YAAY,CAAC;AAC3B,cAAc,cAAc,CAAC;AAC7B,cAAc,SAAS,CAAC;AAExB,OAAO,EAAE,yBAAyB,EAAE,MAAM,4BAA4B,CAAC;AACvE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AA8JnD,wBAAgB,0BAA0B,CACxC,MAAM,EAAE,gBAAgB,GACvB,yBAAyB,CAuE3B"}
|
package/dist/index.js
CHANGED
|
@@ -2,6 +2,8 @@ export { VoiceNavigationController } from "./navigation-controller.js";
|
|
|
2
2
|
export { MicrophoneHandler } from "./microphone-handler.js";
|
|
3
3
|
export { AzureSpeechService } from "./services/azure-speech.js";
|
|
4
4
|
export { BedrockService } from "./services/bedrock.js";
|
|
5
|
+
export { PageRegistry } from "./services/page-registry.js";
|
|
6
|
+
export { parseNavigationXML, fetchNavigationXML, loadNavigationPages, } from "./services/xml-parser.js";
|
|
5
7
|
export * from "./types.js";
|
|
6
8
|
export * from "./actions.js";
|
|
7
9
|
export * from "./ui.js";
|
|
@@ -32,6 +34,7 @@ const buildPersistableConfig = (config) => {
|
|
|
32
34
|
opensearch: normalizedConfig.opensearch
|
|
33
35
|
? { ...normalizedConfig.opensearch }
|
|
34
36
|
: undefined,
|
|
37
|
+
pages: normalizedConfig.pages ? { ...normalizedConfig.pages } : undefined,
|
|
35
38
|
language: normalizedConfig.language,
|
|
36
39
|
autoStart: normalizedConfig.autoStart,
|
|
37
40
|
};
|
|
@@ -109,7 +112,8 @@ export function initNavigationOnMicrophone(config) {
|
|
|
109
112
|
const currentOpenSearchConfig = resolveOpenSearchConfig(normalizedConfig);
|
|
110
113
|
const hadVectorSearch = Boolean(previousOpenSearchConfig);
|
|
111
114
|
const wantsVectorSearch = Boolean(currentOpenSearchConfig);
|
|
112
|
-
const existingHasVectorSearch = Boolean(existingController
|
|
115
|
+
const existingHasVectorSearch = Boolean(existingController
|
|
116
|
+
?.vectorSearchService);
|
|
113
117
|
const vectorConfigChanged = hadVectorSearch &&
|
|
114
118
|
wantsVectorSearch &&
|
|
115
119
|
describeOpenSearchConfig(previousOpenSearchConfig) !==
|
|
@@ -4,6 +4,7 @@ export declare class VoiceNavigationController {
|
|
|
4
4
|
private microphoneHandler;
|
|
5
5
|
private azureSpeechService;
|
|
6
6
|
private bedrockService;
|
|
7
|
+
private pageRegistry;
|
|
7
8
|
private ui;
|
|
8
9
|
private lastTranscript;
|
|
9
10
|
private isProcessing;
|
|
@@ -12,12 +13,14 @@ export declare class VoiceNavigationController {
|
|
|
12
13
|
private autoStartPendingUserInteraction;
|
|
13
14
|
private removeAutoStartListeners;
|
|
14
15
|
private vectorSearchService;
|
|
16
|
+
private pagesInitialized;
|
|
15
17
|
constructor(config: NavigationConfig);
|
|
16
18
|
private shouldAutoStart;
|
|
17
19
|
setAutoStart(enabled: boolean): void;
|
|
18
20
|
prepareForNavigation(options?: {
|
|
19
21
|
target?: string;
|
|
20
22
|
}): void;
|
|
23
|
+
private initializePages;
|
|
21
24
|
private setupEventHandlers;
|
|
22
25
|
private toggleRecording;
|
|
23
26
|
start(options?: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"navigation-controller.d.ts","sourceRoot":"","sources":["../src/navigation-controller.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EACV,gBAAgB,EAKjB,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"navigation-controller.d.ts","sourceRoot":"","sources":["../src/navigation-controller.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EACV,gBAAgB,EAKjB,MAAM,YAAY,CAAC;AA0DpB,qBAAa,yBAAyB;IACpC,OAAO,CAAC,MAAM,CAAmB;IACjC,OAAO,CAAC,iBAAiB,CAAoB;IAC7C,OAAO,CAAC,kBAAkB,CAAqB;IAC/C,OAAO,CAAC,cAAc,CAAiB;IACvC,OAAO,CAAC,YAAY,CAAe;IACnC,OAAO,CAAC,EAAE,CAAa;IACvB,OAAO,CAAC,cAAc,CAAc;IACpC,OAAO,CAAC,YAAY,CAAkB;IACtC,OAAO,CAAC,qBAAqB,CAAkB;IAC/C,OAAO,CAAC,eAAe,CAA2B;IAClD,OAAO,CAAC,+BAA+B,CAAkB;IACzD,OAAO,CAAC,wBAAwB,CAA6B;IAC7D,OAAO,CAAC,mBAAmB,CAAoC;IAC/D,OAAO,CAAC,gBAAgB,CAAgB;gBAE5B,MAAM,EAAE,gBAAgB;IAgFpC,OAAO,CAAC,eAAe;IAoBhB,YAAY,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI;IAepC,oBAAoB,CAAC,OAAO,GAAE;QAAE,MAAM,CAAC,EAAE,MAAM,CAAA;KAAO,GAAG,IAAI;YAOtD,eAAe;IAmE7B,OAAO,CAAC,kBAAkB;YASZ,eAAe;IAkBhB,KAAK,CAChB,OAAO,GAAE;QAAE,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;KAAO,GACzC,OAAO,CAAC,IAAI,CAAC;IA0EH,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IA2BlC,OAAO,CAAC,aAAa;IAUrB,OAAO,CAAC,aAAa;YAWP,aAAa;YAOb,wBAAwB;IAuCtC,OAAO,CAAC,WAAW;YAoBL,iBAAiB;YAwBjB,iBAAiB;IA0HxB,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI;YAI5B,yBAAyB;IAgMvC,OAAO,CAAC,oBAAoB;IAqD5B,OAAO,CAAC,yBAAyB;IAoCjC,OAAO,CAAC,UAAU;IAQlB,OAAO,CAAC,YAAY;IAUpB,OAAO,CAAC,YAAY;IASpB,OAAO,CAAC,4BAA4B;IAiB7B,OAAO,IAAI,IAAI;IAgBtB,OAAO,CAAC,kBAAkB;IA8B1B,OAAO,CAAC,kBAAkB;IAwD1B,OAAO,CAAC,aAAa;IAYrB,OAAO,CAAC,uBAAuB;IAkD/B,OAAO,CAAC,sBAAsB;IAW9B,OAAO,CAAC,wBAAwB;CAmBjC"}
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import { MicrophoneHandler } from "./microphone-handler.js";
|
|
2
2
|
import { AzureSpeechService } from "./services/azure-speech.js";
|
|
3
3
|
import { BedrockService } from "./services/bedrock.js";
|
|
4
|
+
import { PageRegistry } from "./services/page-registry.js";
|
|
5
|
+
import { loadNavigationPages } from "./services/xml-parser.js";
|
|
4
6
|
import { VectorSearchService, } from "./services/vector-search.js";
|
|
5
|
-
import { performAgentAction, formatActionLabel, extractAgentAction, } from "./actions.js";
|
|
7
|
+
import { performAgentAction, formatActionLabel, extractAgentAction, setPageRegistry, } from "./actions.js";
|
|
6
8
|
import { createFloatingControl, setState, updateStatus, updateTranscript, updateActionIndicator, showError, emitEvent, } from "./ui.js";
|
|
7
9
|
const AUTO_START_STORAGE_KEY = "__navigate_auto_start";
|
|
8
10
|
const RESUME_STATE_STORAGE_KEY = "__navigate_resume_state";
|
|
@@ -61,6 +63,8 @@ export class VoiceNavigationController {
|
|
|
61
63
|
? undefined
|
|
62
64
|
: this.config.aws.embeddingModelId,
|
|
63
65
|
});
|
|
66
|
+
this.pageRegistry = new PageRegistry([]);
|
|
67
|
+
this.pagesInitialized = this.initializePages();
|
|
64
68
|
this.microphoneHandler = new MicrophoneHandler({
|
|
65
69
|
azureSpeechService: this.azureSpeechService,
|
|
66
70
|
bedrockService: this.bedrockService,
|
|
@@ -114,6 +118,46 @@ export class VoiceNavigationController {
|
|
|
114
118
|
prepareForNavigation(options = {}) {
|
|
115
119
|
this.persistResumeState(options.target);
|
|
116
120
|
}
|
|
121
|
+
async initializePages() {
|
|
122
|
+
try {
|
|
123
|
+
const pagesConfig = this.config.pages;
|
|
124
|
+
if (!pagesConfig) {
|
|
125
|
+
flowLog("No pages configuration provided, using empty page registry");
|
|
126
|
+
setPageRegistry(this.pageRegistry);
|
|
127
|
+
this.bedrockService.setPageRegistry(this.pageRegistry);
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
130
|
+
if (pagesConfig.pages && Array.isArray(pagesConfig.pages)) {
|
|
131
|
+
flowLog(`Loading ${pagesConfig.pages.length} pages from configuration`);
|
|
132
|
+
this.pageRegistry.loadPages(pagesConfig.pages);
|
|
133
|
+
}
|
|
134
|
+
else if (pagesConfig.xml) {
|
|
135
|
+
const xmlType = pagesConfig.xmlType || "url";
|
|
136
|
+
flowLog(`Loading pages from XML (${xmlType}): ${clipText(pagesConfig.xml, 60)}`);
|
|
137
|
+
const pages = await loadNavigationPages({
|
|
138
|
+
source: pagesConfig.xml,
|
|
139
|
+
type: xmlType,
|
|
140
|
+
});
|
|
141
|
+
flowLog(`✓ Loaded ${pages.length} pages from XML`);
|
|
142
|
+
this.pageRegistry.loadPages(pages);
|
|
143
|
+
}
|
|
144
|
+
setPageRegistry(this.pageRegistry);
|
|
145
|
+
this.bedrockService.setPageRegistry(this.pageRegistry);
|
|
146
|
+
flowLog(`✓ Page registry initialized with ${this.pageRegistry.size} pages`);
|
|
147
|
+
if (this.pageRegistry.size > 0) {
|
|
148
|
+
const actions = this.pageRegistry.getNavigationActions();
|
|
149
|
+
flowLog(`✓ Available page navigation actions: ${actions
|
|
150
|
+
.slice(0, 5)
|
|
151
|
+
.join(", ")}${actions.length > 5 ? `, ... (${actions.length} total)` : ""}`);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
catch (error) {
|
|
155
|
+
console.error("Failed to load navigation pages:", error);
|
|
156
|
+
flowLog("⚠ Continuing without dynamic page navigation");
|
|
157
|
+
setPageRegistry(this.pageRegistry);
|
|
158
|
+
this.bedrockService.setPageRegistry(this.pageRegistry);
|
|
159
|
+
}
|
|
160
|
+
}
|
|
117
161
|
setupEventHandlers() {
|
|
118
162
|
this.ui.button.addEventListener("click", () => {
|
|
119
163
|
this.toggleRecording();
|
|
@@ -133,6 +177,12 @@ export class VoiceNavigationController {
|
|
|
133
177
|
async start(options = {}) {
|
|
134
178
|
const reason = options.reason ?? "user";
|
|
135
179
|
this.lastStartReason = reason;
|
|
180
|
+
try {
|
|
181
|
+
await this.pagesInitialized;
|
|
182
|
+
}
|
|
183
|
+
catch (error) {
|
|
184
|
+
console.error("Failed to initialize pages:", error);
|
|
185
|
+
}
|
|
136
186
|
if (this.ui.root.dataset.state === "listening") {
|
|
137
187
|
return;
|
|
138
188
|
}
|
|
@@ -258,7 +308,8 @@ export class VoiceNavigationController {
|
|
|
258
308
|
}
|
|
259
309
|
handleError(error) {
|
|
260
310
|
console.error("Microphone error:", error);
|
|
261
|
-
if (this.lastStartReason === "auto" &&
|
|
311
|
+
if (this.lastStartReason === "auto" &&
|
|
312
|
+
this.isPermissionRelatedError(error)) {
|
|
262
313
|
setState(this.ui, "idle");
|
|
263
314
|
this.handleAutoStartFallback("auto");
|
|
264
315
|
updateStatus(this.ui, "Tap to start voice control");
|
|
@@ -670,8 +721,7 @@ export class VoiceNavigationController {
|
|
|
670
721
|
};
|
|
671
722
|
sessionStorage.setItem(RESUME_STATE_STORAGE_KEY, JSON.stringify(payload));
|
|
672
723
|
}
|
|
673
|
-
catch (error) {
|
|
674
|
-
}
|
|
724
|
+
catch (error) { }
|
|
675
725
|
}
|
|
676
726
|
consumeResumeState() {
|
|
677
727
|
if (typeof window === "undefined") {
|
|
@@ -737,9 +787,7 @@ export class VoiceNavigationController {
|
|
|
737
787
|
setState(this.ui, "idle");
|
|
738
788
|
const resume = () => {
|
|
739
789
|
this.clearAutoStartFallback();
|
|
740
|
-
void this.microphoneHandler
|
|
741
|
-
.unlockAudioContext(true)
|
|
742
|
-
.finally(() => {
|
|
790
|
+
void this.microphoneHandler.unlockAudioContext(true).finally(() => {
|
|
743
791
|
void this.start({ reason: "user" });
|
|
744
792
|
});
|
|
745
793
|
};
|
|
@@ -774,7 +822,8 @@ export class VoiceNavigationController {
|
|
|
774
822
|
if (message.includes("audiocontext") && message.includes("not allowed")) {
|
|
775
823
|
return true;
|
|
776
824
|
}
|
|
777
|
-
if (message.includes("must be resumed") &&
|
|
825
|
+
if (message.includes("must be resumed") &&
|
|
826
|
+
message.includes("user gesture")) {
|
|
778
827
|
return true;
|
|
779
828
|
}
|
|
780
829
|
return false;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { AgentActionResponse } from "../types.js";
|
|
2
|
+
import type { PageRegistry } from "./page-registry.js";
|
|
2
3
|
export interface BedrockConfig {
|
|
3
4
|
region: string;
|
|
4
5
|
accessKeyId: string;
|
|
@@ -10,7 +11,10 @@ export declare class BedrockService {
|
|
|
10
11
|
private client;
|
|
11
12
|
private actionModelId;
|
|
12
13
|
private embeddingModelId;
|
|
14
|
+
private pageRegistry;
|
|
13
15
|
constructor(config: BedrockConfig);
|
|
16
|
+
setPageRegistry(registry: PageRegistry): void;
|
|
17
|
+
private buildSystemPrompt;
|
|
14
18
|
extractAction(userInput: string): Promise<AgentActionResponse>;
|
|
15
19
|
static create(config: BedrockConfig): BedrockService;
|
|
16
20
|
embedText(text: string): Promise<number[]>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bedrock.d.ts","sourceRoot":"","sources":["../../src/services/bedrock.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,mBAAmB,EAAmB,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"bedrock.d.ts","sourceRoot":"","sources":["../../src/services/bedrock.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,mBAAmB,EAAmB,MAAM,aAAa,CAAC;AACxE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAEvD,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,eAAe,EAAE,MAAM,CAAC;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,gBAAgB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAClC;AAiCD,qBAAa,cAAc;IACzB,OAAO,CAAC,MAAM,CAAuB;IACrC,OAAO,CAAC,aAAa,CAAS;IAC9B,OAAO,CAAC,gBAAgB,CAAgB;IACxC,OAAO,CAAC,YAAY,CAA6B;gBAErC,MAAM,EAAE,aAAa;IAwBjC,eAAe,CAAC,QAAQ,EAAE,YAAY,GAAG,IAAI;IAO7C,OAAO,CAAC,iBAAiB;IA+BnB,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,mBAAmB,CAAC;IAmEpE,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,aAAa,GAAG,cAAc;IAO9C,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;CAwDjD"}
|
package/dist/services/bedrock.js
CHANGED
|
@@ -1,21 +1,35 @@
|
|
|
1
1
|
import { BedrockRuntimeClient, InvokeModelCommand, } from "@aws-sdk/client-bedrock-runtime";
|
|
2
|
-
const
|
|
2
|
+
const CORE_ACTIONS_LIST = `"zoom_in", "zoom_out", "scroll_up", "scroll_down", "scroll_left", "scroll_right", "page_up", "page_down", "scroll_top", "scroll_bottom", "go_back", "go_forward", "reload_page", "print_page", "copy_url", "open_menu", "close_menu", "focus_search", "toggle_fullscreen", "exit_fullscreen", "play_media", "pause_media", "mute_media", "unmute_media", "search_content", "stop"`;
|
|
3
|
+
const BASE_SYSTEM_PROMPT = `You are an action extraction assistant.
|
|
3
4
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
- WHEN YOU RETURN THE "search_content" ACTION, THE "query" FIELD MUST BE A SHORT PHRASE CAPTURING THE USER'S INTENT WITHOUT FILLER WORDS.
|
|
5
|
+
CRITICAL RULES:
|
|
6
|
+
1. RESPOND ONLY WITH A SINGLE JSON OBJECT
|
|
7
|
+
2. THE JSON MUST HAVE AN "action" FIELD
|
|
8
|
+
3. THE ACTION MUST BE EXACTLY ONE OF THE ACTIONS LISTED BELOW
|
|
9
|
+
4. DO NOT CREATE NEW ACTION NAMES - USE ONLY THE EXACT ACTION NAMES PROVIDED
|
|
10
|
+
5. DO NOT USE GENERIC ACTIONS LIKE "go_to_page" OR "navigate_to_page"
|
|
11
|
+
6. FOR PAGE NAVIGATION, USE THE EXACT "navigate_<id>" ACTION PROVIDED FOR THAT PAGE
|
|
12
|
+
7. IF UNCERTAIN, RESPOND WITH {"action": "unknown"}
|
|
13
13
|
|
|
14
|
-
|
|
15
|
-
|
|
14
|
+
RESPONSE FORMAT:
|
|
15
|
+
- Core actions: {"action": "action_name"}
|
|
16
|
+
- Search: {"action": "search_content", "query": "keywords"}
|
|
17
|
+
- Page navigation: {"action": "navigate_<page_id>"}
|
|
18
|
+
|
|
19
|
+
EXAMPLES:
|
|
20
|
+
- User says "go to dashboard" → {"action": "navigate_dashboard"}
|
|
21
|
+
- User says "show me the team page" → {"action": "navigate_team"}
|
|
22
|
+
- User says "scroll down" → {"action": "scroll_down"}
|
|
23
|
+
- User says "find schemes" → {"action": "search_content", "query": "schemes"}
|
|
24
|
+
|
|
25
|
+
MATCHING RULES FOR PAGE NAVIGATION:
|
|
26
|
+
- Match user's words to page names and keywords
|
|
27
|
+
- Choose the navigate_ action that best matches
|
|
28
|
+
- If user says "go to X" or "open X" or "show me X", find the page with that name or keyword`;
|
|
16
29
|
const DEFAULT_EMBEDDING_MODEL_ID = "cohere.embed-multilingual-v3";
|
|
17
30
|
export class BedrockService {
|
|
18
31
|
constructor(config) {
|
|
32
|
+
this.pageRegistry = null;
|
|
19
33
|
this.client = new BedrockRuntimeClient({
|
|
20
34
|
region: config.region,
|
|
21
35
|
credentials: {
|
|
@@ -29,17 +43,39 @@ export class BedrockService {
|
|
|
29
43
|
}
|
|
30
44
|
else if (typeof config.embeddingModelId === "string") {
|
|
31
45
|
const trimmed = config.embeddingModelId.trim();
|
|
32
|
-
this.embeddingModelId =
|
|
46
|
+
this.embeddingModelId =
|
|
47
|
+
trimmed.length > 0 ? trimmed : DEFAULT_EMBEDDING_MODEL_ID;
|
|
33
48
|
}
|
|
34
49
|
else {
|
|
35
50
|
this.embeddingModelId = DEFAULT_EMBEDDING_MODEL_ID;
|
|
36
51
|
}
|
|
37
52
|
}
|
|
53
|
+
setPageRegistry(registry) {
|
|
54
|
+
this.pageRegistry = registry;
|
|
55
|
+
}
|
|
56
|
+
buildSystemPrompt() {
|
|
57
|
+
let prompt = BASE_SYSTEM_PROMPT;
|
|
58
|
+
prompt += `\n\n=== CORE ACTIONS ===\n${CORE_ACTIONS_LIST}`;
|
|
59
|
+
if (this.pageRegistry && this.pageRegistry.size > 0) {
|
|
60
|
+
const pages = this.pageRegistry.getAllPages();
|
|
61
|
+
const pageActions = pages.map((page) => {
|
|
62
|
+
const keywords = page.keywords?.length
|
|
63
|
+
? ` [matches: ${page.keywords.join(", ")}]`
|
|
64
|
+
: "";
|
|
65
|
+
return `"navigate_${page.id}" for "${page.name}"${keywords}`;
|
|
66
|
+
});
|
|
67
|
+
prompt += `\n\n=== PAGE NAVIGATION ACTIONS ===\n${pageActions.join("\n")}`;
|
|
68
|
+
prompt += `\n\nWhen user wants to navigate to a page, use the EXACT "navigate_<id>" action shown above.`;
|
|
69
|
+
}
|
|
70
|
+
prompt += `\n\n=== FINAL REMINDER ===\nYou MUST use one of the actions listed above. DO NOT create new action names. DO NOT use "go_to_page" or similar generic actions.`;
|
|
71
|
+
return prompt;
|
|
72
|
+
}
|
|
38
73
|
async extractAction(userInput) {
|
|
74
|
+
const systemPrompt = this.buildSystemPrompt();
|
|
39
75
|
const body = {
|
|
40
76
|
anthropic_version: "bedrock-2023-05-31",
|
|
41
77
|
max_tokens: 70,
|
|
42
|
-
system:
|
|
78
|
+
system: systemPrompt,
|
|
43
79
|
messages: [
|
|
44
80
|
{
|
|
45
81
|
role: "user",
|
|
@@ -118,7 +154,8 @@ export class BedrockService {
|
|
|
118
154
|
(Array.isArray(decoded.embeddings)
|
|
119
155
|
? decoded.embeddings
|
|
120
156
|
: decoded.embeddings?.values) ||
|
|
121
|
-
decoded.results?.find((item) => Array.isArray(item.embedding))
|
|
157
|
+
decoded.results?.find((item) => Array.isArray(item.embedding))
|
|
158
|
+
?.embedding;
|
|
122
159
|
if (!Array.isArray(embedding)) {
|
|
123
160
|
throw new Error("Unexpected embedding response structure");
|
|
124
161
|
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
export interface NavigablePage {
|
|
2
|
+
id: string;
|
|
3
|
+
name: string;
|
|
4
|
+
path: string;
|
|
5
|
+
keywords?: string[];
|
|
6
|
+
description?: string;
|
|
7
|
+
}
|
|
8
|
+
export declare class PageRegistry {
|
|
9
|
+
private pages;
|
|
10
|
+
private pathToId;
|
|
11
|
+
private keywordIndex;
|
|
12
|
+
constructor(pages?: NavigablePage[]);
|
|
13
|
+
loadPages(pages: NavigablePage[]): void;
|
|
14
|
+
addPage(page: NavigablePage): void;
|
|
15
|
+
getPageById(id: string): NavigablePage | undefined;
|
|
16
|
+
getPageByPath(path: string): NavigablePage | undefined;
|
|
17
|
+
findPageByKeyword(keyword: string): NavigablePage | undefined;
|
|
18
|
+
getAllPages(): NavigablePage[];
|
|
19
|
+
getNavigationActions(): string[];
|
|
20
|
+
isPageNavigationAction(action: string): boolean;
|
|
21
|
+
getPageIdFromAction(action: string): string | null;
|
|
22
|
+
clear(): void;
|
|
23
|
+
get size(): number;
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=page-registry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"page-registry.d.ts","sourceRoot":"","sources":["../../src/services/page-registry.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,qBAAa,YAAY;IACvB,OAAO,CAAC,KAAK,CAAyC;IACtD,OAAO,CAAC,QAAQ,CAAkC;IAClD,OAAO,CAAC,YAAY,CAAuC;gBAE/C,KAAK,GAAE,aAAa,EAAO;IAOvC,SAAS,CAAC,KAAK,EAAE,aAAa,EAAE,GAAG,IAAI;IAavC,OAAO,CAAC,IAAI,EAAE,aAAa,GAAG,IAAI;IAuBlC,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG,aAAa,GAAG,SAAS;IAOlD,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,aAAa,GAAG,SAAS;IAQtD,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,aAAa,GAAG,SAAS;IAwB7D,WAAW,IAAI,aAAa,EAAE;IAO9B,oBAAoB,IAAI,MAAM,EAAE;IAOhC,sBAAsB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO;IAW/C,mBAAmB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAWlD,KAAK,IAAI,IAAI;IASb,IAAI,IAAI,IAAI,MAAM,CAEjB;CACF"}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
export class PageRegistry {
|
|
2
|
+
constructor(pages = []) {
|
|
3
|
+
this.pages = new Map();
|
|
4
|
+
this.pathToId = new Map();
|
|
5
|
+
this.keywordIndex = new Map();
|
|
6
|
+
this.loadPages(pages);
|
|
7
|
+
}
|
|
8
|
+
loadPages(pages) {
|
|
9
|
+
this.pages.clear();
|
|
10
|
+
this.pathToId.clear();
|
|
11
|
+
this.keywordIndex.clear();
|
|
12
|
+
for (const page of pages) {
|
|
13
|
+
this.addPage(page);
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
addPage(page) {
|
|
17
|
+
this.pages.set(page.id, page);
|
|
18
|
+
this.pathToId.set(page.path, page.id);
|
|
19
|
+
const keywords = page.keywords || [];
|
|
20
|
+
const allKeywords = [
|
|
21
|
+
page.name.toLowerCase(),
|
|
22
|
+
page.id.toLowerCase(),
|
|
23
|
+
...keywords.map((k) => k.toLowerCase()),
|
|
24
|
+
];
|
|
25
|
+
for (const keyword of allKeywords) {
|
|
26
|
+
if (!this.keywordIndex.has(keyword)) {
|
|
27
|
+
this.keywordIndex.set(keyword, new Set());
|
|
28
|
+
}
|
|
29
|
+
this.keywordIndex.get(keyword).add(page.id);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
getPageById(id) {
|
|
33
|
+
return this.pages.get(id);
|
|
34
|
+
}
|
|
35
|
+
getPageByPath(path) {
|
|
36
|
+
const id = this.pathToId.get(path);
|
|
37
|
+
return id ? this.pages.get(id) : undefined;
|
|
38
|
+
}
|
|
39
|
+
findPageByKeyword(keyword) {
|
|
40
|
+
const normalized = keyword.toLowerCase().trim();
|
|
41
|
+
const pageIds = this.keywordIndex.get(normalized);
|
|
42
|
+
if (pageIds && pageIds.size > 0) {
|
|
43
|
+
const firstId = Array.from(pageIds)[0];
|
|
44
|
+
return this.pages.get(firstId);
|
|
45
|
+
}
|
|
46
|
+
for (const [key, ids] of this.keywordIndex.entries()) {
|
|
47
|
+
if (key.includes(normalized) || normalized.includes(key)) {
|
|
48
|
+
const firstId = Array.from(ids)[0];
|
|
49
|
+
return this.pages.get(firstId);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
return undefined;
|
|
53
|
+
}
|
|
54
|
+
getAllPages() {
|
|
55
|
+
return Array.from(this.pages.values());
|
|
56
|
+
}
|
|
57
|
+
getNavigationActions() {
|
|
58
|
+
return Array.from(this.pages.keys()).map((id) => `navigate_${id}`);
|
|
59
|
+
}
|
|
60
|
+
isPageNavigationAction(action) {
|
|
61
|
+
if (!action.startsWith("navigate_")) {
|
|
62
|
+
return false;
|
|
63
|
+
}
|
|
64
|
+
const pageId = action.replace(/^navigate_/, "");
|
|
65
|
+
return this.pages.has(pageId);
|
|
66
|
+
}
|
|
67
|
+
getPageIdFromAction(action) {
|
|
68
|
+
if (!action.startsWith("navigate_")) {
|
|
69
|
+
return null;
|
|
70
|
+
}
|
|
71
|
+
const pageId = action.replace(/^navigate_/, "");
|
|
72
|
+
return this.pages.has(pageId) ? pageId : null;
|
|
73
|
+
}
|
|
74
|
+
clear() {
|
|
75
|
+
this.pages.clear();
|
|
76
|
+
this.pathToId.clear();
|
|
77
|
+
this.keywordIndex.clear();
|
|
78
|
+
}
|
|
79
|
+
get size() {
|
|
80
|
+
return this.pages.size;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { NavigablePage } from "./page-registry.js";
|
|
2
|
+
export interface PageXMLConfig {
|
|
3
|
+
source: string | URL;
|
|
4
|
+
type: "url" | "string";
|
|
5
|
+
}
|
|
6
|
+
export declare function parseNavigationXML(xmlString: string): NavigablePage[];
|
|
7
|
+
export declare function fetchNavigationXML(url: string): Promise<NavigablePage[]>;
|
|
8
|
+
export declare function loadNavigationPages(config: PageXMLConfig): Promise<NavigablePage[]>;
|
|
9
|
+
//# sourceMappingURL=xml-parser.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"xml-parser.d.ts","sourceRoot":"","sources":["../../src/services/xml-parser.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAExD,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,MAAM,GAAG,GAAG,CAAC;IACrB,IAAI,EAAE,KAAK,GAAG,QAAQ,CAAC;CACxB;AAKD,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,MAAM,GAAG,aAAa,EAAE,CAsDrE;AAKD,wBAAsB,kBAAkB,CACtC,GAAG,EAAE,MAAM,GACV,OAAO,CAAC,aAAa,EAAE,CAAC,CAgB1B;AAKD,wBAAsB,mBAAmB,CACvC,MAAM,EAAE,aAAa,GACpB,OAAO,CAAC,aAAa,EAAE,CAAC,CAM1B"}
|