@olares/lares-mobile 0.15.0 → 0.15.1

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 CHANGED
@@ -4,16 +4,20 @@ LarePass 只依赖这一个包。对话、Host、设置都在内部走 `@olares/
4
4
 
5
5
  ```vue
6
6
  <template>
7
- <LaresApp :locale="locale" :env="env" />
7
+ <LaresApp :locale="locale" v-bind="ports" />
8
8
  </template>
9
9
  <script setup>
10
- import { LaresApp } from "@olares/lares-mobile";
10
+ import { LaresApp, laresPortsFromAccount, findLaresEntrance } from "@olares/lares-mobile";
11
11
  </script>
12
12
  ```
13
13
 
14
14
  设置页同样只挂 `LaresAgentSettings`。
15
15
 
16
- `env` 由宿主注入(`PROTOCOL` / `LARES_SUB_DOMAIN` / `ACCOUNT_DOMAIN` / `IS_PC_TEST`)。PC 预览走 `/laresHost` 代理时设 `IS_PC_TEST`。需要自定义鉴权请求时再传 `request`。
16
+ 正式 App:把当前登录账号的 `myApps` 交给 `laresPortsFromAccount`(或自己调 `findLaresEntrance` 得到 `baseUrl`)。入口前缀是安装时随机的,不要拼 `lares.<用户>.olares.com`,也不要把 webpack `.env` 里的调试子域带进生产。
17
+
18
+ PC 预览:`IS_PC_TEST` 时走 `/laresHost` 代理,`laresPortsFromAccount` 会继续用 `PROTOCOL` / `LARES_SUB_DOMAIN` / `ACCOUNT_DOMAIN`。自定义鉴权请求再传 `request`。
19
+
20
+ 切账号时更新 `baseUrl` / `env` 即可,客户端会丢掉上一台的 runtime 和设置缓存,改连新 Host。
17
21
 
18
22
  本地联调(包未上 registry 时):
19
23
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@olares/lares-mobile",
3
- "version": "0.15.0",
3
+ "version": "0.15.1",
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.0",
31
+ "@olares/lares-core": "0.15.1",
32
32
  "markdown-it": "^14.3.0"
33
33
  }
34
34
  }
package/src/App.vue CHANGED
@@ -141,6 +141,7 @@ export default {
141
141
  return {
142
142
  sending: false,
143
143
  starting: false,
144
+ hostGen: 0,
144
145
  running: false,
145
146
  sessionId: "",
146
147
  draft: "",
@@ -183,6 +184,9 @@ export default {
183
184
  runtime() {
184
185
  return connectChat(this.ports);
185
186
  },
187
+ hostKey() {
188
+ return this.runtime.key;
189
+ },
186
190
  t() {
187
191
  return createT(this.locale);
188
192
  },
@@ -274,6 +278,9 @@ export default {
274
278
  sessionId(id) {
275
279
  this.bindIntake(id);
276
280
  },
281
+ hostKey() {
282
+ this.switchHost();
283
+ },
277
284
  },
278
285
  created() {
279
286
  this.intake = new FileIntake((file, sessionId, options) => this.runtime.upload(file, options, sessionId));
@@ -290,7 +297,7 @@ export default {
290
297
  },
291
298
  });
292
299
  this.bindIntake(this.sessionId);
293
- this.unsub = this.runtime.subscribe((snap) => this.applySnap(snap));
300
+ this.bindRuntime();
294
301
  try {
295
302
  const raw = JSON.parse(localStorage.getItem("lares.mobile.effort") || "{}");
296
303
  if (raw && typeof raw === "object") this.effortByModel = raw;
@@ -404,17 +411,47 @@ export default {
404
411
  this.preview = { path: "", status: "idle", data: null, error: "" };
405
412
  },
406
413
  async retry() {
414
+ const gen = ++this.hostGen;
407
415
  this.starting = true;
408
416
  try {
409
417
  await this.runtime.start();
418
+ if (gen !== this.hostGen) return;
410
419
  await this.loadComposerMeta();
411
420
  } finally {
412
- this.starting = false;
421
+ if (gen === this.hostGen) this.starting = false;
413
422
  }
414
423
  },
415
424
  modelKey(model) {
416
425
  return selectionKey({ provider: model.provider, model: model.id });
417
426
  },
427
+ bindRuntime() {
428
+ this.unsub?.();
429
+ this.unsub = this.runtime.subscribe((snap) => this.applySnap(snap));
430
+ },
431
+ switchHost() {
432
+ this.voiceCap?.stop?.(true);
433
+ this.intakeUnsub?.();
434
+ if (this.sessionId) this.intake?.cancelSession(this.sessionId);
435
+ this.sessionId = "";
436
+ this.items = [];
437
+ this.sessions = [];
438
+ this.sessionsReady = false;
439
+ this.previews = {};
440
+ this.preview = { path: "", status: "idle", data: null, error: "" };
441
+ this.pendingUser = "";
442
+ this.failed = "";
443
+ this.error = "";
444
+ this.models = null;
445
+ this.modelError = "";
446
+ this.modelPending = "";
447
+ this.modelSheet = false;
448
+ this.panel = "";
449
+ this.question = null;
450
+ this.questionBusy = false;
451
+ this.bindIntake("");
452
+ this.bindRuntime();
453
+ this.retry();
454
+ },
418
455
  bindIntake(sessionId) {
419
456
  this.intakeUnsub?.();
420
457
  this.intakeUnsub = null;
package/src/host.js CHANGED
@@ -1,4 +1,4 @@
1
- import { hostConfigFromEnv, hostUrl, MODELS_PATH, probeHost } from "@olares/lares-core/larepass/host";
1
+ import { hostTarget, hostUrl, MODELS_PATH, probeHost } from "@olares/lares-core/larepass/host";
2
2
  import { callRpc, consumeMux, ensureSession, loadTranscript, MUX_PATH, sendPrompt } from "@olares/lares-core/larepass/chat";
3
3
  import { muxWsUrl } from "@olares/lares-core/larepass/mux";
4
4
  import { RESPOND_PATH } from "@olares/lares-core/larepass/rpc";
@@ -92,9 +92,7 @@ export async function defaultRequest(url, init = {}) {
92
92
  }
93
93
 
94
94
  export function createHostClient(ports = {}) {
95
- const fromEnv = hostConfigFromEnv(ports.env);
96
- const baseUrl = ports.baseUrl ?? fromEnv.baseUrl;
97
- const proxyPrefix = ports.proxyPrefix ?? fromEnv.proxyPrefix;
95
+ const { baseUrl, proxyPrefix } = hostTarget(ports);
98
96
  const send = ports.request ?? defaultRequest;
99
97
  const urlFor = (path) => hostUrl({ baseUrl, proxyPrefix, path });
100
98
  const request = (path, init) => send(urlFor(path), init);
package/src/index.d.ts CHANGED
@@ -29,11 +29,24 @@ export type HostPorts = {
29
29
 
30
30
  export const PC_TEST_PROXY: string;
31
31
 
32
+ export function findLaresEntrance(apps?: unknown[]): string;
33
+
32
34
  export function hostConfigFromEnv(env?: HostEnv): {
33
35
  baseUrl: string;
34
36
  proxyPrefix: string;
35
37
  };
36
38
 
39
+ export function hostKey(ports?: HostPorts): string;
40
+
41
+ export function laresPortsFromAccount(input?: {
42
+ env?: HostEnv;
43
+ apps?: unknown[];
44
+ }): {
45
+ baseUrl?: string;
46
+ env?: HostEnv;
47
+ proxyPrefix?: string;
48
+ };
49
+
37
50
  export function defaultRequest(url: string, init?: HostRequestInit): Promise<HostResponse>;
38
51
 
39
52
  export function createHostClient(ports?: HostPorts): {
package/src/index.js CHANGED
@@ -1,4 +1,10 @@
1
1
  export { default as LaresApp } from "./App.vue";
2
2
  export { default as LaresAgentSettings } from "./settings/AgentSettings.vue";
3
3
  export { createHostClient, defaultRequest } from "./host.js";
4
- export { hostConfigFromEnv, PC_TEST_PROXY } from "@olares/lares-core/larepass/host";
4
+ export {
5
+ findLaresEntrance,
6
+ hostConfigFromEnv,
7
+ hostKey,
8
+ laresPortsFromAccount,
9
+ PC_TEST_PROXY,
10
+ } from "@olares/lares-core/larepass/host";
package/src/runtime.js CHANGED
@@ -1,12 +1,32 @@
1
+ import { hostKey } from "@olares/lares-core/larepass/host";
2
+ import { resetHostSettingsCache } from "@olares/lares-core/larepass/settings";
1
3
  import { createChatRuntime } from "@olares/lares-core/larepass/runtime";
2
4
  import { createHostClient } from "./host.js";
3
5
 
4
6
  let current = null;
7
+ let liveKey = "";
8
+
9
+ export function adoptHost(ports) {
10
+ const key = hostKey(ports);
11
+ if (key === liveKey) return key;
12
+ liveKey = key;
13
+ current?.dispose?.();
14
+ current = null;
15
+ resetHostSettingsCache();
16
+ return key;
17
+ }
5
18
 
6
19
  export function connectChat(ports) {
7
20
  const client = createHostClient(ports);
8
- const key = client.urlFor("/api");
21
+ const key = adoptHost(ports);
9
22
  if (current?.key === key) return current;
10
23
  current = Object.assign(createChatRuntime(client), { key });
11
24
  return current;
12
25
  }
26
+
27
+ export function resetChatHost() {
28
+ liveKey = "";
29
+ current?.dispose?.();
30
+ current = null;
31
+ resetHostSettingsCache();
32
+ }
@@ -94,7 +94,9 @@ import {
94
94
  searchValueFromMenu,
95
95
  } from "@olares/lares-core/search/menu";
96
96
  import { rememberedSettings } from "@olares/lares-core/larepass/settings";
97
+ import { hostKey as hostSessionKey } from "@olares/lares-core/larepass/host";
97
98
  import { createHostClient } from "../host.js";
99
+ import { adoptHost } from "../runtime.js";
98
100
  import { createT } from "../i18n.js";
99
101
  import LaresSettingRow from "./SettingRow.vue";
100
102
  import LaresSheet from "./Sheet.vue";
@@ -138,13 +140,19 @@ export default {
138
140
  t() {
139
141
  return createT(this.locale);
140
142
  },
141
- settings() {
142
- return createHostClient({
143
+ ports() {
144
+ return {
143
145
  baseUrl: this.baseUrl,
144
146
  proxyPrefix: this.proxyPrefix,
145
147
  request: this.request,
146
148
  env: this.env,
147
- }).settings;
149
+ };
150
+ },
151
+ hostKey() {
152
+ return hostSessionKey(this.ports);
153
+ },
154
+ settings() {
155
+ return createHostClient(this.ports).settings;
148
156
  },
149
157
  busy() {
150
158
  return this.loading || Boolean(this.pending);
@@ -238,6 +246,19 @@ export default {
238
246
  return "";
239
247
  },
240
248
  },
249
+ watch: {
250
+ hostKey() {
251
+ adoptHost(this.ports);
252
+ this.panel = "";
253
+ this.models = null;
254
+ this.voice = null;
255
+ this.search = null;
256
+ this.modelError = "";
257
+ this.voiceError = "";
258
+ this.searchError = "";
259
+ this.load(true);
260
+ },
261
+ },
241
262
  mounted() {
242
263
  this.load(false);
243
264
  },