@olares/lares-mobile 0.15.18 → 0.15.20

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@olares/lares-mobile",
3
- "version": "0.15.18",
3
+ "version": "0.15.20",
4
4
  "description": "Lares chat component for LarePass",
5
5
  "type": "module",
6
6
  "repository": {
@@ -28,7 +28,7 @@
28
28
  "vue": "^3.2.0"
29
29
  },
30
30
  "dependencies": {
31
- "@olares/lares-core": "0.15.18",
31
+ "@olares/lares-core": "0.15.20",
32
32
  "markdown-it": "^14.3.0"
33
33
  }
34
34
  }
package/src/App.vue CHANGED
@@ -115,6 +115,7 @@
115
115
  <script>
116
116
  import { modelState, modelStateLabel } from "@olares/lares-core/router/model-state";
117
117
  import { matchVoiceShortcut } from "@olares/lares-core/voice/shortcuts";
118
+ import { markRaw } from "vue";
118
119
  import { subscribeVoiceSettings } from "@olares/lares-core/larepass/settings";
119
120
  import { createVoicePanel } from "@olares/lares-core/voice/panel";
120
121
  import { mergeVoiceTranscript, subscribeVoiceHistory } from "@olares/lares-core/voice/projection";
@@ -578,7 +579,7 @@ export default {
578
579
  },
579
580
  });
580
581
  this.voiceSettingsUnsub = subscribeVoiceSettings((value) => {
581
- this.voiceDefaultMode = value.config.mobileMode; this.voiceSettings = value;
582
+ this.voiceDefaultMode = value.config.mobileMode; this.voiceSettings = markRaw(value);
582
583
  const next = value.config.speak === true;
583
584
  if (this.voiceSpeak && !next) this.reader?.stop();
584
585
  this.voiceSpeak = next;
@@ -603,7 +604,7 @@ export default {
603
604
  return this.player?.play(wavBlob(sentence.audio));
604
605
  },
605
606
  halt: () => this.player?.stop(),
606
- silence: () => void this.runtime.interruptSpeech?.(),
607
+ silence: (source) => void this.runtime.interruptSpeech?.(source),
607
608
  fail: (err) => this.showSpeakProblem(err),
608
609
  });
609
610
 
@@ -727,6 +728,7 @@ export default {
727
728
  this.items = snap.items;
728
729
  this.running = snap.running;
729
730
  this.runningSince = snap.runningSince || 0;
731
+ if (this.voiceCall) this.reader.stop();
730
732
  const target = this.voiceSpeak && !this.voiceCall && !document.hidden ? speakable(utterance, true) : null;
731
733
  if (target) this.reader.follow({ ...target, sessionId: snap.sessionId, source: { sessionId: snap.sessionId, turn: target.turn, step: target.step, attemptId: target.attemptId }, key: `${snap.sessionId}:${target.key}` });
732
734
  this.failed = snap.failed;
@@ -1008,7 +1010,7 @@ export default {
1008
1010
  try {
1009
1011
  await this.runtime.start({ workspaces: this.chatDevice === "desktop" });
1010
1012
  if (gen !== this.hostGen) return;
1011
- void this.runtime.settings.voice(false, { diagnostics: false }).then(value => { if (gen === this.hostGen) { this.voiceSettings = value; this.voiceDefaultMode = value.config.mobileMode; } }).catch(() => {});
1013
+ void this.runtime.settings.voice(false, { diagnostics: false }).then(value => { if (gen === this.hostGen) { this.voiceSettings = markRaw(value); this.voiceDefaultMode = value.config.mobileMode; } }).catch(() => {});
1012
1014
  if (this.chatDevice !== "desktop") await this.runtime.refreshWorkspaces();
1013
1015
  await this.loadComposerMeta();
1014
1016
  } finally {
@@ -1280,7 +1282,7 @@ export default {
1280
1282
  async openDictation(preset) {
1281
1283
  if (document.hidden || navigator.onLine === false) return;
1282
1284
  if (!this.voiceSettings) {
1283
- try { this.voiceSettings = await this.runtime.settings.voice(false, { diagnostics: false }); }
1285
+ try { this.voiceSettings = markRaw(await this.runtime.settings.voice(false, { diagnostics: false })); }
1284
1286
  catch { return; }
1285
1287
  }
1286
1288
  if (!laresVoiceAvailability(this.voiceSettings).dictation) return;
@@ -1317,7 +1319,7 @@ export default {
1317
1319
  this.reader.stop(); this.player?.stop(); this.player?.unlock();
1318
1320
  let conversation;
1319
1321
  const reader = createSentencePlayer({
1320
- stream: device === "device" ? (value) => playAudioStream({ ...value, request: (path, options) => this.runtime.voiceRequest(path, options), headers: conversation.headers, socket: (ticket) => this.runtime.voiceSocket(ticket, "/api/lares/voice/stream") }) : undefined,
1322
+ stream: (value) => playAudioStream({ ...value, request: (path, options) => this.runtime.voiceRequest(path, options), headers: conversation.headers, socket: (ticket) => this.runtime.voiceSocket(ticket, "/api/lares/voice/stream") }),
1321
1323
  send: (value) => conversation.speak(value),
1322
1324
  play: (sentence) => sentence.bluetooth === "played" ? Promise.resolve() : this.player.play(wavBlob(sentence.audio)),
1323
1325
  halt: () => this.player.stop(), silence: () => {},
package/src/host.js CHANGED
@@ -319,8 +319,9 @@ export function createHostClient(ports = {}) {
319
319
  const message = typeof error?.message === "string" && error.message ? error.message : code;
320
320
  throw Object.assign(new Error(message), { code });
321
321
  },
322
- async interruptSpeech() {
323
- const res = await request(`${VOICE_API}/playback/stop`, { method: "POST", headers: voiceHeaders("device") });
322
+ async interruptSpeech(source) {
323
+ const body = source && typeof source === "object" ? { sessionId: source.sessionId, turn: source.turn, step: source.step, attemptId: source.attemptId } : {};
324
+ const res = await request(`${VOICE_API}/playback/stop`, { method: "POST", headers: voiceHeaders("device"), body });
324
325
  return Boolean(res?.ok);
325
326
  },
326
327
  async openMux(signal) {