@myscheme/voice-navigation-sdk 0.1.5 → 0.1.7

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.
Files changed (38) hide show
  1. package/README.md +13 -5
  2. package/dist/actions.d.ts.map +1 -1
  3. package/dist/actions.js +184 -44
  4. package/dist/microphone-handler.d.ts +8 -0
  5. package/dist/microphone-handler.d.ts.map +1 -1
  6. package/dist/microphone-handler.js +98 -24
  7. package/dist/navigation-controller.d.ts +4 -0
  8. package/dist/navigation-controller.d.ts.map +1 -1
  9. package/dist/navigation-controller.js +201 -7
  10. package/dist/server/azure-speech-handler.d.ts +13 -0
  11. package/dist/server/azure-speech-handler.d.ts.map +1 -0
  12. package/dist/server/azure-speech-handler.js +79 -0
  13. package/dist/server/bedrock-embedding-handler.d.ts +16 -0
  14. package/dist/server/bedrock-embedding-handler.d.ts.map +1 -0
  15. package/dist/server/bedrock-embedding-handler.js +183 -0
  16. package/dist/server/bedrock-handler.d.ts +15 -0
  17. package/dist/server/bedrock-handler.d.ts.map +1 -0
  18. package/dist/server/bedrock-handler.js +171 -0
  19. package/dist/server/index.d.ts +7 -0
  20. package/dist/server/index.d.ts.map +1 -1
  21. package/dist/server/index.js +7 -0
  22. package/dist/server/opensearch-env-handler.d.ts +22 -0
  23. package/dist/server/opensearch-env-handler.d.ts.map +1 -0
  24. package/dist/server/opensearch-env-handler.js +221 -0
  25. package/dist/services/azure-speech.d.ts +10 -2
  26. package/dist/services/azure-speech.d.ts.map +1 -1
  27. package/dist/services/azure-speech.js +66 -3
  28. package/dist/services/bedrock.d.ts +16 -4
  29. package/dist/services/bedrock.d.ts.map +1 -1
  30. package/dist/services/bedrock.js +293 -17
  31. package/dist/services/vector-search.d.ts.map +1 -1
  32. package/dist/services/vector-search.js +15 -2
  33. package/dist/services/voice-feedback.d.ts +46 -0
  34. package/dist/services/voice-feedback.d.ts.map +1 -0
  35. package/dist/services/voice-feedback.js +332 -0
  36. package/dist/types.d.ts +17 -9
  37. package/dist/types.d.ts.map +1 -1
  38. package/package.json +3 -3
@@ -1,9 +1,66 @@
1
1
  export class AzureSpeechService {
2
2
  constructor(config) {
3
- this.subscriptionKey = config.subscriptionKey;
4
- this.region = config.region;
3
+ this.tokenEndpoint = null;
4
+ this.subscriptionKey = null;
5
+ this.region = null;
6
+ this.useProxy = false;
7
+ this.cachedToken = null;
8
+ this.tokenExpiration = 0;
9
+ this.useProxy = !!config.tokenEndpoint;
10
+ if (this.useProxy) {
11
+ this.tokenEndpoint = config.tokenEndpoint || null;
12
+ }
13
+ else {
14
+ if (!config.subscriptionKey || !config.region) {
15
+ throw new Error("Azure subscription key and region required for direct mode");
16
+ }
17
+ this.subscriptionKey = config.subscriptionKey;
18
+ this.region = config.region;
19
+ }
5
20
  }
6
21
  async fetchToken() {
22
+ if (this.cachedToken && Date.now() < this.tokenExpiration) {
23
+ return {
24
+ token: this.cachedToken,
25
+ region: this.region || "centralindia",
26
+ };
27
+ }
28
+ if (this.useProxy) {
29
+ return this.fetchTokenViaProxy();
30
+ }
31
+ else {
32
+ return this.fetchTokenDirect();
33
+ }
34
+ }
35
+ async fetchTokenViaProxy() {
36
+ if (!this.tokenEndpoint) {
37
+ throw new Error("Token endpoint not configured");
38
+ }
39
+ try {
40
+ const response = await fetch(this.tokenEndpoint, {
41
+ method: "POST",
42
+ headers: {
43
+ "Content-Type": "application/json",
44
+ },
45
+ });
46
+ if (!response.ok) {
47
+ throw new Error(`Failed to fetch token: ${response.status} ${response.statusText}`);
48
+ }
49
+ const data = (await response.json());
50
+ this.cachedToken = data.token;
51
+ this.tokenExpiration = Date.now() + 9 * 60 * 1000;
52
+ this.region = data.region;
53
+ return data;
54
+ }
55
+ catch (error) {
56
+ console.error("Failed to fetch Azure speech token via proxy:", error);
57
+ throw error;
58
+ }
59
+ }
60
+ async fetchTokenDirect() {
61
+ if (!this.subscriptionKey || !this.region) {
62
+ throw new Error("Azure subscription key and region not configured");
63
+ }
7
64
  const url = `https://${this.region}.api.cognitive.microsoft.com/sts/v1.0/issueToken`;
8
65
  try {
9
66
  const response = await fetch(url, {
@@ -17,9 +74,11 @@ export class AzureSpeechService {
17
74
  throw new Error(`Failed to fetch token: ${response.status} ${response.statusText}`);
18
75
  }
19
76
  const token = await response.text();
77
+ this.cachedToken = token;
78
+ this.tokenExpiration = Date.now() + 9 * 60 * 1000;
20
79
  return {
21
80
  token,
22
- region: this.region,
81
+ region: this.region || "centralindia",
23
82
  };
24
83
  }
25
84
  catch (error) {
@@ -27,6 +86,10 @@ export class AzureSpeechService {
27
86
  throw error;
28
87
  }
29
88
  }
89
+ clearTokenCache() {
90
+ this.cachedToken = null;
91
+ this.tokenExpiration = 0;
92
+ }
30
93
  static create(config) {
31
94
  return new AzureSpeechService(config);
32
95
  }
@@ -1,10 +1,12 @@
1
1
  import type { AgentActionResponse } from "../types.js";
2
2
  import type { PageRegistry } from "./page-registry.js";
3
3
  export interface BedrockConfig {
4
- region: string;
5
- accessKeyId: string;
6
- secretAccessKey: string;
7
- modelId: string;
4
+ bedrockEndpoint?: string;
5
+ embeddingEndpoint?: string;
6
+ region?: string;
7
+ accessKeyId?: string;
8
+ secretAccessKey?: string;
9
+ modelId?: string;
8
10
  embeddingModelId?: string | null;
9
11
  }
10
12
  export declare class BedrockService {
@@ -12,11 +14,21 @@ export declare class BedrockService {
12
14
  private actionModelId;
13
15
  private embeddingModelId;
14
16
  private pageRegistry;
17
+ private bedrockEndpoint;
18
+ private embeddingEndpointUrl;
19
+ private useProxy;
15
20
  constructor(config: BedrockConfig);
16
21
  setPageRegistry(registry: PageRegistry): void;
17
22
  private buildSystemPrompt;
18
23
  extractAction(userInput: string): Promise<AgentActionResponse>;
24
+ private extractActionViaProxy;
25
+ private extractActionDirect;
19
26
  static create(config: BedrockConfig): BedrockService;
20
27
  embedText(text: string): Promise<number[]>;
28
+ private embedTextViaProxy;
29
+ private embedTextDirect;
30
+ generateFeedbackMessage(prompt: string, language: string): Promise<string>;
31
+ private generateFeedbackViaProxy;
32
+ private generateFeedbackDirect;
21
33
  }
22
34
  //# sourceMappingURL=bedrock.d.ts.map
@@ -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;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;CAoFjD"}
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;IAE5B,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAG3B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,gBAAgB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAClC;AAyCD,qBAAa,cAAc;IACzB,OAAO,CAAC,MAAM,CAAqC;IACnD,OAAO,CAAC,aAAa,CAAuB;IAC5C,OAAO,CAAC,gBAAgB,CAAgB;IACxC,OAAO,CAAC,YAAY,CAA6B;IACjD,OAAO,CAAC,eAAe,CAAuB;IAC9C,OAAO,CAAC,oBAAoB,CAAuB;IACnD,OAAO,CAAC,QAAQ,CAAkB;gBAEtB,MAAM,EAAE,aAAa;IA6CjC,eAAe,CAAC,QAAQ,EAAE,YAAY,GAAG,IAAI;IAO7C,OAAO,CAAC,iBAAiB;IA+BnB,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,mBAAmB,CAAC;YAWtD,qBAAqB;YA2ErB,mBAAmB;IAyEjC,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,aAAa,GAAG,cAAc;IAO9C,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;YAWlC,iBAAiB;YAkFjB,eAAe;IAwFvB,uBAAuB,CAC3B,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,MAAM,CAAC;YA0BJ,wBAAwB;YAwExB,sBAAsB;CA+DrC"}
@@ -1,5 +1,5 @@
1
1
  import { BedrockRuntimeClient, InvokeModelCommand, } from "@aws-sdk/client-bedrock-runtime";
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"`;
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", "quit", "tab_next", "tab_back", "click", "enter", "submit", "move_left", "move_right", "move_up", "move_down", "move_beginning", "move_end", "select_all", "select_line", "type_text", "cut", "copy", "paste", "clear"`;
3
3
  const BASE_SYSTEM_PROMPT = `You are an action extraction assistant.
4
4
 
5
5
  CRITICAL RULES:
@@ -14,6 +14,7 @@ CRITICAL RULES:
14
14
  RESPONSE FORMAT:
15
15
  - Core actions: {"action": "action_name"}
16
16
  - Search: {"action": "search_content", "query": "keywords"}
17
+ - Type text: {"action": "type_text", "text": "text to type"}
17
18
  - Page navigation: {"action": "navigate_<page_id>"}
18
19
 
19
20
  EXAMPLES:
@@ -21,6 +22,13 @@ EXAMPLES:
21
22
  - User says "show me the team page" → {"action": "navigate_team"}
22
23
  - User says "scroll down" → {"action": "scroll_down"}
23
24
  - User says "find schemes" → {"action": "search_content", "query": "schemes"}
25
+ - User says "type hello world" → {"action": "type_text", "text": "hello world"}
26
+ - User says "tab" or "tab next" → {"action": "tab_next"}
27
+ - User says "tab previous" or "tab back" → {"action": "tab_back"}
28
+ - User says "focus next" → {"action": "focus_next"}
29
+ - User says "focus previous" → {"action": "focus_previous"}
30
+ - User says "go back" or "back" (browser history) → {"action": "go_back"}
31
+ - User says "click" → {"action": "click"}
24
32
 
25
33
  MATCHING RULES FOR PAGE NAVIGATION:
26
34
  - Match user's words to page names and keywords
@@ -29,25 +37,45 @@ MATCHING RULES FOR PAGE NAVIGATION:
29
37
  const DEFAULT_EMBEDDING_MODEL_ID = "cohere.embed-multilingual-v3";
30
38
  export class BedrockService {
31
39
  constructor(config) {
40
+ this.client = null;
41
+ this.actionModelId = null;
32
42
  this.pageRegistry = null;
33
- this.client = new BedrockRuntimeClient({
34
- region: config.region,
35
- credentials: {
36
- accessKeyId: config.accessKeyId,
37
- secretAccessKey: config.secretAccessKey,
38
- },
39
- });
40
- this.actionModelId = config.modelId;
41
- if (config.embeddingModelId === null) {
43
+ this.bedrockEndpoint = null;
44
+ this.embeddingEndpointUrl = null;
45
+ this.useProxy = false;
46
+ this.useProxy = !!(config.bedrockEndpoint || config.embeddingEndpoint);
47
+ if (this.useProxy) {
48
+ this.bedrockEndpoint = config.bedrockEndpoint || null;
49
+ this.embeddingEndpointUrl = config.embeddingEndpoint || null;
50
+ this.actionModelId = null;
42
51
  this.embeddingModelId = null;
43
52
  }
44
- else if (typeof config.embeddingModelId === "string") {
45
- const trimmed = config.embeddingModelId.trim();
46
- this.embeddingModelId =
47
- trimmed.length > 0 ? trimmed : DEFAULT_EMBEDDING_MODEL_ID;
48
- }
49
53
  else {
50
- this.embeddingModelId = DEFAULT_EMBEDDING_MODEL_ID;
54
+ if (!config.region ||
55
+ !config.accessKeyId ||
56
+ !config.secretAccessKey ||
57
+ !config.modelId) {
58
+ throw new Error("AWS credentials required for direct mode");
59
+ }
60
+ this.client = new BedrockRuntimeClient({
61
+ region: config.region,
62
+ credentials: {
63
+ accessKeyId: config.accessKeyId,
64
+ secretAccessKey: config.secretAccessKey,
65
+ },
66
+ });
67
+ this.actionModelId = config.modelId;
68
+ if (config.embeddingModelId === null) {
69
+ this.embeddingModelId = null;
70
+ }
71
+ else if (typeof config.embeddingModelId === "string") {
72
+ const trimmed = config.embeddingModelId.trim();
73
+ this.embeddingModelId =
74
+ trimmed.length > 0 ? trimmed : DEFAULT_EMBEDDING_MODEL_ID;
75
+ }
76
+ else {
77
+ this.embeddingModelId = DEFAULT_EMBEDDING_MODEL_ID;
78
+ }
51
79
  }
52
80
  }
53
81
  setPageRegistry(registry) {
@@ -71,6 +99,73 @@ export class BedrockService {
71
99
  return prompt;
72
100
  }
73
101
  async extractAction(userInput) {
102
+ if (this.useProxy) {
103
+ return this.extractActionViaProxy(userInput);
104
+ }
105
+ else {
106
+ return this.extractActionDirect(userInput);
107
+ }
108
+ }
109
+ async extractActionViaProxy(userInput) {
110
+ if (!this.bedrockEndpoint) {
111
+ throw new Error("Bedrock endpoint not configured");
112
+ }
113
+ try {
114
+ const systemPrompt = this.buildSystemPrompt();
115
+ const requestBody = {
116
+ anthropic_version: "bedrock-2023-05-31",
117
+ max_tokens: 70,
118
+ system: systemPrompt,
119
+ messages: [
120
+ {
121
+ role: "user",
122
+ content: [
123
+ {
124
+ type: "text",
125
+ text: `User input: "${userInput}". Identify the intended action from the allowed list and respond ONLY with a JSON object. If the user input is unclear, respond with {"action": "unknown"}. Include no additional text.`,
126
+ },
127
+ ],
128
+ },
129
+ ],
130
+ };
131
+ const response = await fetch(this.bedrockEndpoint, {
132
+ method: "POST",
133
+ headers: {
134
+ "Content-Type": "application/json",
135
+ },
136
+ body: JSON.stringify({
137
+ body: requestBody,
138
+ }),
139
+ });
140
+ if (!response.ok) {
141
+ throw new Error(`Bedrock proxy error: ${response.status} ${response.statusText}`);
142
+ }
143
+ const data = (await response.json());
144
+ let rawText = "";
145
+ if (data.content && data.content.length > 0) {
146
+ rawText = data.content[0].text || "";
147
+ }
148
+ if (!rawText) {
149
+ return { action: "unknown" };
150
+ }
151
+ try {
152
+ const parsed = JSON.parse(rawText);
153
+ return parsed;
154
+ }
155
+ catch (parseError) {
156
+ console.error("Failed to parse Bedrock response:", rawText, parseError);
157
+ return { action: "unknown" };
158
+ }
159
+ }
160
+ catch (error) {
161
+ console.error("Bedrock proxy API error:", error);
162
+ throw error;
163
+ }
164
+ }
165
+ async extractActionDirect(userInput) {
166
+ if (!this.client || !this.actionModelId) {
167
+ throw new Error("AWS Bedrock client not initialized");
168
+ }
74
169
  const systemPrompt = this.buildSystemPrompt();
75
170
  const body = {
76
171
  anthropic_version: "bedrock-2023-05-31",
@@ -126,11 +221,76 @@ export class BedrockService {
126
221
  return new BedrockService(config);
127
222
  }
128
223
  async embedText(text) {
224
+ if (this.useProxy) {
225
+ return this.embedTextViaProxy(text);
226
+ }
227
+ else {
228
+ return this.embedTextDirect(text);
229
+ }
230
+ }
231
+ async embedTextViaProxy(text) {
129
232
  const prompt = text.trim();
130
233
  if (!prompt) {
131
234
  return [];
132
235
  }
133
- if (!this.embeddingModelId) {
236
+ if (!this.embeddingEndpointUrl) {
237
+ throw new Error("Embedding endpoint not configured");
238
+ }
239
+ try {
240
+ const response = await fetch(this.embeddingEndpointUrl, {
241
+ method: "POST",
242
+ headers: {
243
+ "Content-Type": "application/json",
244
+ },
245
+ body: JSON.stringify({
246
+ text: prompt,
247
+ inputType: "search_query",
248
+ }),
249
+ });
250
+ if (!response.ok) {
251
+ throw new Error(`Embedding proxy error: ${response.status} ${response.statusText}`);
252
+ }
253
+ const decoded = (await response.json());
254
+ let embedding;
255
+ if (decoded.embeddings) {
256
+ if (Array.isArray(decoded.embeddings)) {
257
+ if (decoded.embeddings.length > 0 &&
258
+ Array.isArray(decoded.embeddings[0])) {
259
+ embedding = decoded.embeddings[0];
260
+ }
261
+ else if (decoded.embeddings.length > 0 &&
262
+ typeof decoded.embeddings[0] === "number") {
263
+ embedding = decoded.embeddings;
264
+ }
265
+ }
266
+ else if (typeof decoded.embeddings === "object" &&
267
+ "values" in decoded.embeddings) {
268
+ embedding = decoded.embeddings.values;
269
+ }
270
+ }
271
+ if (!embedding) {
272
+ embedding =
273
+ decoded.embedding ||
274
+ decoded.vector ||
275
+ decoded.results?.find((item) => Array.isArray(item.embedding))
276
+ ?.embedding;
277
+ }
278
+ if (!Array.isArray(embedding)) {
279
+ throw new Error("Unexpected embedding response structure");
280
+ }
281
+ return embedding.map((value) => Number(value));
282
+ }
283
+ catch (error) {
284
+ console.error("Embedding proxy error:", error);
285
+ throw error;
286
+ }
287
+ }
288
+ async embedTextDirect(text) {
289
+ const prompt = text.trim();
290
+ if (!prompt) {
291
+ return [];
292
+ }
293
+ if (!this.client || !this.embeddingModelId) {
134
294
  throw new Error("Bedrock embedding model is not configured");
135
295
  }
136
296
  const payload = {
@@ -184,4 +344,120 @@ export class BedrockService {
184
344
  throw error;
185
345
  }
186
346
  }
347
+ async generateFeedbackMessage(prompt, language) {
348
+ console.log("[Bedrock] generateFeedbackMessage called for language:", language);
349
+ const systemPrompt = `You are a voice navigation assistant providing spoken feedback.
350
+ Generate brief, natural, conversational feedback messages (maximum 10 words).
351
+ Be specific and clear about what action was performed.
352
+ Use the language: ${language}
353
+ Respond with ONLY the feedback message text, no JSON, no explanations.`;
354
+ const userPrompt = prompt;
355
+ console.log("[Bedrock] Using proxy mode:", this.useProxy);
356
+ if (this.useProxy) {
357
+ return this.generateFeedbackViaProxy(systemPrompt, userPrompt);
358
+ }
359
+ else {
360
+ return this.generateFeedbackDirect(systemPrompt, userPrompt);
361
+ }
362
+ }
363
+ async generateFeedbackViaProxy(systemPrompt, userPrompt) {
364
+ if (!this.bedrockEndpoint) {
365
+ throw new Error("Bedrock endpoint not configured");
366
+ }
367
+ console.log("[Bedrock] Calling proxy endpoint:", this.bedrockEndpoint);
368
+ try {
369
+ const requestBody = {
370
+ anthropic_version: "bedrock-2023-05-31",
371
+ max_tokens: 50,
372
+ system: systemPrompt,
373
+ messages: [
374
+ {
375
+ role: "user",
376
+ content: [
377
+ {
378
+ type: "text",
379
+ text: userPrompt,
380
+ },
381
+ ],
382
+ },
383
+ ],
384
+ };
385
+ const response = await fetch(this.bedrockEndpoint, {
386
+ method: "POST",
387
+ headers: {
388
+ "Content-Type": "application/json",
389
+ },
390
+ body: JSON.stringify({
391
+ body: requestBody,
392
+ }),
393
+ });
394
+ if (!response.ok) {
395
+ throw new Error(`Bedrock proxy error: ${response.status}`);
396
+ }
397
+ const result = (await response.json());
398
+ console.log("[Bedrock] Proxy response received:", result);
399
+ if (result.content &&
400
+ Array.isArray(result.content) &&
401
+ result.content[0]?.text) {
402
+ const message = result.content[0].text.trim();
403
+ console.log("[Bedrock] Extracted message from proxy:", message);
404
+ return message;
405
+ }
406
+ if (typeof result === "object" && result !== null && "text" in result) {
407
+ const message = String(result.text).trim();
408
+ console.log("[Bedrock] Extracted text from proxy:", message);
409
+ return message;
410
+ }
411
+ throw new Error("Unexpected feedback response format");
412
+ }
413
+ catch (error) {
414
+ console.error("[Bedrock] Proxy generation error:", error);
415
+ throw error;
416
+ }
417
+ }
418
+ async generateFeedbackDirect(systemPrompt, userPrompt) {
419
+ if (!this.client || !this.actionModelId) {
420
+ throw new Error("Bedrock client not configured");
421
+ }
422
+ console.log("[Bedrock] Using direct AWS SDK with model:", this.actionModelId);
423
+ const payload = {
424
+ anthropic_version: "bedrock-2023-05-31",
425
+ max_tokens: 50,
426
+ temperature: 0.7,
427
+ system: systemPrompt,
428
+ messages: [
429
+ {
430
+ role: "user",
431
+ content: userPrompt,
432
+ },
433
+ ],
434
+ };
435
+ const input = {
436
+ modelId: this.actionModelId,
437
+ contentType: "application/json",
438
+ accept: "application/json",
439
+ body: JSON.stringify(payload),
440
+ };
441
+ try {
442
+ const command = new InvokeModelCommand(input);
443
+ const response = await this.client.send(command);
444
+ if (!response.body) {
445
+ throw new Error("No response from Bedrock");
446
+ }
447
+ const decoded = JSON.parse(new TextDecoder().decode(response.body));
448
+ console.log("[Bedrock] Direct SDK response received");
449
+ if (decoded.content &&
450
+ Array.isArray(decoded.content) &&
451
+ decoded.content[0]?.text) {
452
+ const message = decoded.content[0].text.trim();
453
+ console.log("[Bedrock] Extracted message from direct:", message);
454
+ return message;
455
+ }
456
+ throw new Error("Unexpected feedback response format");
457
+ }
458
+ catch (error) {
459
+ console.error("[Bedrock] Direct generation error:", error);
460
+ throw error;
461
+ }
462
+ }
187
463
  }
@@ -1 +1 @@
1
- {"version":3,"file":"vector-search.d.ts","sourceRoot":"","sources":["../../src/services/vector-search.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAEpD,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACjC;AAwCD,qBAAa,mBAAmB;IAC9B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAA6B;IACpD,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;gBAEtB,MAAM,EAAE,gBAAgB;IA6B9B,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,EAAE,CAAC;IAyF9E,YAAY,CAAC,GAAG,EAAE,eAAe,GAAG,MAAM,GAAG,IAAI;IAoCjD,oBAAoB,CAAC,IAAI,EAAE,eAAe,EAAE,GAAG;QAC7C,GAAG,EAAE,eAAe,CAAC;QACrB,GAAG,EAAE,MAAM,CAAC;KACb,GAAG,IAAI;IAaR,OAAO,CAAC,mBAAmB;IAsB3B,OAAO,CAAC,eAAe;YAkBT,YAAY;CAQ3B"}
1
+ {"version":3,"file":"vector-search.d.ts","sourceRoot":"","sources":["../../src/services/vector-search.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAEpD,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACjC;AAyCD,qBAAa,mBAAmB;IAC9B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAA6B;IACpD,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;gBAEtB,MAAM,EAAE,gBAAgB;IAuC9B,MAAM,CACV,MAAM,EAAE,MAAM,EAAE,EAChB,SAAS,CAAC,EAAE,MAAM,GACjB,OAAO,CAAC,eAAe,EAAE,CAAC;IA6F7B,YAAY,CAAC,GAAG,EAAE,eAAe,GAAG,MAAM,GAAG,IAAI;IAoCjD,oBAAoB,CAAC,IAAI,EAAE,eAAe,EAAE,GAAG;QAC7C,GAAG,EAAE,eAAe,CAAC;QACrB,GAAG,EAAE,MAAM,CAAC;KACb,GAAG,IAAI;IAaR,OAAO,CAAC,mBAAmB;IAqC3B,OAAO,CAAC,eAAe;YAqBT,YAAY;CAQ3B"}
@@ -11,6 +11,7 @@ export class VectorSearchService {
11
11
  const requestTimeoutMs = typeof config.requestTimeoutMs === "number" && config.requestTimeoutMs > 0
12
12
  ? Math.floor(config.requestTimeoutMs)
13
13
  : 15000;
14
+ const isEndpointOnlyMode = !!(config.searchEndpoint && !config.node);
14
15
  this.config = {
15
16
  ...config,
16
17
  vectorField: config.vectorField || "embedding",
@@ -19,9 +20,12 @@ export class VectorSearchService {
19
20
  numCandidates,
20
21
  requestTimeoutMs,
21
22
  sourceFields: config.sourceFields,
22
- apiPath: config.apiPath || DEFAULT_VECTOR_SEARCH_API_PATH,
23
+ apiPath: config.apiPath ||
24
+ config.searchEndpoint ||
25
+ DEFAULT_VECTOR_SEARCH_API_PATH,
26
+ isEndpointOnlyMode,
23
27
  };
24
- this.endpoint = this.resolveEndpoint(this.config.apiPath);
28
+ this.endpoint = this.resolveEndpoint(config.searchEndpoint || config.apiPath || DEFAULT_VECTOR_SEARCH_API_PATH);
25
29
  }
26
30
  async search(vector, queryText) {
27
31
  if (!Array.isArray(vector) || vector.length === 0) {
@@ -133,6 +137,15 @@ export class VectorSearchService {
133
137
  return null;
134
138
  }
135
139
  buildRequestPayload(vector, queryText) {
140
+ if (this.config.isEndpointOnlyMode) {
141
+ return {
142
+ vector,
143
+ query: queryText,
144
+ size: this.config.size,
145
+ minScore: this.config.minScore,
146
+ sourceFields: this.config.sourceFields,
147
+ };
148
+ }
136
149
  return {
137
150
  vector,
138
151
  queryText,
@@ -0,0 +1,46 @@
1
+ import type { NavigationAction, ActionResult } from "../types.js";
2
+ import type { AzureSpeechService } from "./azure-speech.js";
3
+ import type { BedrockService } from "./bedrock.js";
4
+ interface VoiceFeedbackConfig {
5
+ enabled?: boolean;
6
+ language?: string;
7
+ azureSpeechService: AzureSpeechService;
8
+ bedrockService: BedrockService;
9
+ }
10
+ interface FeedbackContext {
11
+ action: NavigationAction;
12
+ actionResult?: ActionResult;
13
+ transcript?: string;
14
+ elementInfo?: {
15
+ tag?: string;
16
+ label?: string;
17
+ text?: string;
18
+ type?: string;
19
+ };
20
+ }
21
+ export declare class VoiceFeedbackService {
22
+ private enabled;
23
+ private language;
24
+ private azureSpeechService;
25
+ private bedrockService;
26
+ private synthesizer;
27
+ private isSpeaking;
28
+ constructor(config: VoiceFeedbackConfig);
29
+ setEnabled(enabled: boolean): void;
30
+ isEnabled(): boolean;
31
+ setLanguage(language: string): void;
32
+ private initializeSynthesizer;
33
+ private getVoiceForLanguage;
34
+ private generateFeedbackMessage;
35
+ private buildPromptForAction;
36
+ private getFallbackMessage;
37
+ private speak;
38
+ private stopSpeaking;
39
+ provideFeedback(context: FeedbackContext): Promise<void>;
40
+ provideImmediateFeedback(message: string): Promise<void>;
41
+ announceFocusChange(element: HTMLElement, direction: "next" | "previous"): Promise<void>;
42
+ private extractElementInfo;
43
+ dispose(): void;
44
+ }
45
+ export {};
46
+ //# sourceMappingURL=voice-feedback.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"voice-feedback.d.ts","sourceRoot":"","sources":["../../src/services/voice-feedback.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAClE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAC5D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAEnD,UAAU,mBAAmB;IAC3B,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,kBAAkB,EAAE,kBAAkB,CAAC;IACvC,cAAc,EAAE,cAAc,CAAC;CAChC;AAED,UAAU,eAAe;IACvB,MAAM,EAAE,gBAAgB,CAAC;IACzB,YAAY,CAAC,EAAE,YAAY,CAAC;IAC5B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE;QACZ,GAAG,CAAC,EAAE,MAAM,CAAC;QACb,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,IAAI,CAAC,EAAE,MAAM,CAAC;KACf,CAAC;CACH;AAED,qBAAa,oBAAoB;IAC/B,OAAO,CAAC,OAAO,CAAU;IACzB,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,kBAAkB,CAAqB;IAC/C,OAAO,CAAC,cAAc,CAAiB;IACvC,OAAO,CAAC,WAAW,CAAsC;IACzD,OAAO,CAAC,UAAU,CAAkB;gBAExB,MAAM,EAAE,mBAAmB;IAiBvC,UAAU,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI;IAclC,SAAS,IAAI,OAAO;IAOpB,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI;YAQrB,qBAAqB;IAmCnC,OAAO,CAAC,mBAAmB;YAsBb,uBAAuB;IAsCrC,OAAO,CAAC,oBAAoB;IA4C5B,OAAO,CAAC,kBAAkB;YAgCZ,KAAK;IA0EnB,OAAO,CAAC,YAAY;IAkBd,eAAe,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC;IAoFxD,wBAAwB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAkBxD,mBAAmB,CACvB,OAAO,EAAE,WAAW,EACpB,SAAS,EAAE,MAAM,GAAG,UAAU,GAC7B,OAAO,CAAC,IAAI,CAAC;IAwBhB,OAAO,CAAC,kBAAkB;IAwF1B,OAAO,IAAI,IAAI;CAOhB"}