@olares/lares-mobile 0.15.0 → 0.15.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 +9 -3
- package/package.json +2 -2
- package/src/App.vue +93 -49
- package/src/chat/Composer.vue +6 -3
- package/src/chat/Deliverables.vue +13 -1
- package/src/host.js +2 -4
- package/src/index.d.ts +16 -0
- package/src/index.js +7 -1
- package/src/layout.js +8 -0
- package/src/preview/Preview.vue +3 -0
- package/src/runtime.js +21 -1
- package/src/settings/AgentSettings.vue +26 -3
- package/src/styles.css +15 -0
package/README.md
CHANGED
|
@@ -4,16 +4,22 @@ LarePass 只依赖这一个包。对话、Host、设置都在内部走 `@olares/
|
|
|
4
4
|
|
|
5
5
|
```vue
|
|
6
6
|
<template>
|
|
7
|
-
<LaresApp :locale="locale" :
|
|
7
|
+
<LaresApp :locale="locale" :device="device" 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
|
+
`device` 为 `desktop` 时对话列居中、宽 748px;`mobile`(默认)保持全宽。
|
|
15
|
+
|
|
14
16
|
设置页同样只挂 `LaresAgentSettings`。
|
|
15
17
|
|
|
16
|
-
|
|
18
|
+
正式 App:把当前登录账号的 `myApps` 交给 `laresPortsFromAccount`(或自己调 `findLaresEntrance` 得到 `baseUrl`)。入口前缀是安装时随机的,不要拼 `lares.<用户>.olares.com`,也不要把 webpack `.env` 里的调试子域带进生产。
|
|
19
|
+
|
|
20
|
+
PC 预览:`IS_PC_TEST` 时走 `/laresHost` 代理,`laresPortsFromAccount` 会继续用 `PROTOCOL` / `LARES_SUB_DOMAIN` / `ACCOUNT_DOMAIN`。自定义鉴权请求再传 `request`。
|
|
21
|
+
|
|
22
|
+
切账号时更新 `baseUrl` / `env` 即可,客户端会丢掉上一台的 runtime 和设置缓存,改连新 Host。
|
|
17
23
|
|
|
18
24
|
本地联调(包未上 registry 时):
|
|
19
25
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@olares/lares-mobile",
|
|
3
|
-
"version": "0.15.
|
|
3
|
+
"version": "0.15.2",
|
|
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.
|
|
31
|
+
"@olares/lares-core": "0.15.2",
|
|
32
32
|
"markdown-it": "^14.3.0"
|
|
33
33
|
}
|
|
34
34
|
}
|
package/src/App.vue
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<div class="lares-shell">
|
|
2
|
+
<div class="lares-shell" :data-device="chatDevice">
|
|
3
3
|
<LaresChatBar
|
|
4
4
|
:t="t"
|
|
5
5
|
:title="sessionTitle"
|
|
@@ -16,52 +16,54 @@
|
|
|
16
16
|
@close="panel = ''"
|
|
17
17
|
@pick="pickSession"
|
|
18
18
|
/>
|
|
19
|
-
<
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
19
|
+
<div class="lares-shell__conversation">
|
|
20
|
+
<p v-if="failed" class="lares-shell__status">{{ failText }}</p>
|
|
21
|
+
<button v-if="failed" type="button" class="lares-shell__retry" :disabled="starting" @click="retry">
|
|
22
|
+
{{ t("probe.retry") }}
|
|
23
|
+
</button>
|
|
24
|
+
<LaresTranscript
|
|
25
|
+
ref="transcript"
|
|
26
|
+
:items="viewItems"
|
|
27
|
+
:running="running"
|
|
28
|
+
:loading="historyLoading || starting"
|
|
29
|
+
:previews="previews"
|
|
30
|
+
:media-url="mediaUrl"
|
|
31
|
+
:scroll-top="scrollTop"
|
|
32
|
+
:remember-scroll="rememberScroll"
|
|
33
|
+
:sticking="sticking"
|
|
34
|
+
:session-id="sessionId"
|
|
35
|
+
:question="question"
|
|
36
|
+
:question-busy="questionBusy"
|
|
37
|
+
:t="t"
|
|
38
|
+
@open="openFile"
|
|
39
|
+
@media="pinLog"
|
|
40
|
+
@answer="answerQuestion"
|
|
41
|
+
/>
|
|
42
|
+
<LaresComposer
|
|
43
|
+
:draft="draft"
|
|
44
|
+
:sending="sending"
|
|
45
|
+
:can-send="canSend"
|
|
46
|
+
:model-label="modelLabel"
|
|
47
|
+
:model-busy="modelBusy"
|
|
48
|
+
:effort-label="effortLabel"
|
|
49
|
+
:effort-disabled="effortDisabled"
|
|
50
|
+
:attach-pending="upload.pending > 0"
|
|
51
|
+
:attach-disabled="!sessionId || historyLoading || starting"
|
|
52
|
+
:voice-phase="voicePhase"
|
|
53
|
+
:voice-elapsed="voiceElapsed"
|
|
54
|
+
:voice-error="voiceErrorText"
|
|
55
|
+
:failures="upload.failures"
|
|
56
|
+
:t="t"
|
|
57
|
+
@update:draft="draft = $event"
|
|
58
|
+
@send="send"
|
|
59
|
+
@model="openModelSheet"
|
|
60
|
+
@effort="openEffortSheet"
|
|
61
|
+
@files="attachFiles"
|
|
62
|
+
@voice="toggleVoice"
|
|
63
|
+
@hold-start="onHoldStart"
|
|
64
|
+
@hold-end="onHoldEnd"
|
|
65
|
+
/>
|
|
66
|
+
</div>
|
|
65
67
|
<LaresSheet :open="modelSheet" :title="t('model.menuAria')" @close="modelSheet = false">
|
|
66
68
|
<p v-if="modelError" class="lares-shell__status">{{ modelError }}</p>
|
|
67
69
|
<p v-else-if="!models" class="lares-shell__hint">{{ t("agent.loading") }}</p>
|
|
@@ -118,6 +120,7 @@ import { DEFAULT_MAX_UPLOAD_BYTES } from "@olares/lares-core/files/limits";
|
|
|
118
120
|
import { groupModelsByProvider, effortMenuRows, reasoningOfModel, currentEffortId, selectionKey } from "@olares/lares-core/router/session-model";
|
|
119
121
|
import { messageFromCode } from "@olares/lares-core/i18n/t";
|
|
120
122
|
import { parseAskUserQuestions, singleSelectAnswer } from "@olares/lares-core/larepass/questions";
|
|
123
|
+
import { chatDevice as resolveChatDevice } from "./layout.js";
|
|
121
124
|
import LaresChatBar from "./chat/ChatBar.vue";
|
|
122
125
|
import LaresHistoryPanel from "./chat/HistoryPanel.vue";
|
|
123
126
|
import LaresTranscript from "./chat/Transcript.vue";
|
|
@@ -132,6 +135,7 @@ export default {
|
|
|
132
135
|
components: { LaresChatBar, LaresHistoryPanel, LaresTranscript, LaresComposer, LaresPreview, LaresSheet, LaresSettingRow },
|
|
133
136
|
props: {
|
|
134
137
|
locale: { type: String, default: "en" },
|
|
138
|
+
device: { type: String, default: "mobile" },
|
|
135
139
|
baseUrl: { type: String, default: undefined },
|
|
136
140
|
proxyPrefix: { type: String, default: undefined },
|
|
137
141
|
request: { type: Function, default: undefined },
|
|
@@ -141,6 +145,7 @@ export default {
|
|
|
141
145
|
return {
|
|
142
146
|
sending: false,
|
|
143
147
|
starting: false,
|
|
148
|
+
hostGen: 0,
|
|
144
149
|
running: false,
|
|
145
150
|
sessionId: "",
|
|
146
151
|
draft: "",
|
|
@@ -183,9 +188,15 @@ export default {
|
|
|
183
188
|
runtime() {
|
|
184
189
|
return connectChat(this.ports);
|
|
185
190
|
},
|
|
191
|
+
hostKey() {
|
|
192
|
+
return this.runtime.key;
|
|
193
|
+
},
|
|
186
194
|
t() {
|
|
187
195
|
return createT(this.locale);
|
|
188
196
|
},
|
|
197
|
+
chatDevice() {
|
|
198
|
+
return resolveChatDevice(this.device);
|
|
199
|
+
},
|
|
189
200
|
canSend() {
|
|
190
201
|
return Boolean(this.draft.trim()) && Boolean(this.sessionId) && !this.running && !this.historyLoading && this.upload.pending === 0;
|
|
191
202
|
},
|
|
@@ -274,6 +285,9 @@ export default {
|
|
|
274
285
|
sessionId(id) {
|
|
275
286
|
this.bindIntake(id);
|
|
276
287
|
},
|
|
288
|
+
hostKey() {
|
|
289
|
+
this.switchHost();
|
|
290
|
+
},
|
|
277
291
|
},
|
|
278
292
|
created() {
|
|
279
293
|
this.intake = new FileIntake((file, sessionId, options) => this.runtime.upload(file, options, sessionId));
|
|
@@ -290,7 +304,7 @@ export default {
|
|
|
290
304
|
},
|
|
291
305
|
});
|
|
292
306
|
this.bindIntake(this.sessionId);
|
|
293
|
-
this.
|
|
307
|
+
this.bindRuntime();
|
|
294
308
|
try {
|
|
295
309
|
const raw = JSON.parse(localStorage.getItem("lares.mobile.effort") || "{}");
|
|
296
310
|
if (raw && typeof raw === "object") this.effortByModel = raw;
|
|
@@ -404,17 +418,47 @@ export default {
|
|
|
404
418
|
this.preview = { path: "", status: "idle", data: null, error: "" };
|
|
405
419
|
},
|
|
406
420
|
async retry() {
|
|
421
|
+
const gen = ++this.hostGen;
|
|
407
422
|
this.starting = true;
|
|
408
423
|
try {
|
|
409
424
|
await this.runtime.start();
|
|
425
|
+
if (gen !== this.hostGen) return;
|
|
410
426
|
await this.loadComposerMeta();
|
|
411
427
|
} finally {
|
|
412
|
-
this.starting = false;
|
|
428
|
+
if (gen === this.hostGen) this.starting = false;
|
|
413
429
|
}
|
|
414
430
|
},
|
|
415
431
|
modelKey(model) {
|
|
416
432
|
return selectionKey({ provider: model.provider, model: model.id });
|
|
417
433
|
},
|
|
434
|
+
bindRuntime() {
|
|
435
|
+
this.unsub?.();
|
|
436
|
+
this.unsub = this.runtime.subscribe((snap) => this.applySnap(snap));
|
|
437
|
+
},
|
|
438
|
+
switchHost() {
|
|
439
|
+
this.voiceCap?.stop?.(true);
|
|
440
|
+
this.intakeUnsub?.();
|
|
441
|
+
if (this.sessionId) this.intake?.cancelSession(this.sessionId);
|
|
442
|
+
this.sessionId = "";
|
|
443
|
+
this.items = [];
|
|
444
|
+
this.sessions = [];
|
|
445
|
+
this.sessionsReady = false;
|
|
446
|
+
this.previews = {};
|
|
447
|
+
this.preview = { path: "", status: "idle", data: null, error: "" };
|
|
448
|
+
this.pendingUser = "";
|
|
449
|
+
this.failed = "";
|
|
450
|
+
this.error = "";
|
|
451
|
+
this.models = null;
|
|
452
|
+
this.modelError = "";
|
|
453
|
+
this.modelPending = "";
|
|
454
|
+
this.modelSheet = false;
|
|
455
|
+
this.panel = "";
|
|
456
|
+
this.question = null;
|
|
457
|
+
this.questionBusy = false;
|
|
458
|
+
this.bindIntake("");
|
|
459
|
+
this.bindRuntime();
|
|
460
|
+
this.retry();
|
|
461
|
+
},
|
|
418
462
|
bindIntake(sessionId) {
|
|
419
463
|
this.intakeUnsub?.();
|
|
420
464
|
this.intakeUnsub = null;
|
package/src/chat/Composer.vue
CHANGED
|
@@ -68,7 +68,6 @@
|
|
|
68
68
|
</svg>
|
|
69
69
|
</button>
|
|
70
70
|
<button
|
|
71
|
-
v-if="showSend"
|
|
72
71
|
type="submit"
|
|
73
72
|
class="lares-composer__icon"
|
|
74
73
|
data-kind="send"
|
|
@@ -79,8 +78,9 @@
|
|
|
79
78
|
<path d="M12 19V7M6.5 12.5 12 7l5.5 5.5" />
|
|
80
79
|
</svg>
|
|
81
80
|
</button>
|
|
81
|
+
<!-- Voice input parked.
|
|
82
82
|
<button
|
|
83
|
-
v-
|
|
83
|
+
v-if="!showSend"
|
|
84
84
|
type="button"
|
|
85
85
|
class="lares-composer__icon"
|
|
86
86
|
data-kind="voice"
|
|
@@ -99,10 +99,11 @@
|
|
|
99
99
|
<path d="M17.5 9v6" />
|
|
100
100
|
</svg>
|
|
101
101
|
</button>
|
|
102
|
+
-->
|
|
102
103
|
</div>
|
|
103
104
|
</div>
|
|
104
105
|
</div>
|
|
105
|
-
<p v-if="voiceError" class="lares-composer__hint" data-status="error">{{ voiceError }}</p>
|
|
106
|
+
<!-- <p v-if="voiceError" class="lares-composer__hint" data-status="error">{{ voiceError }}</p> -->
|
|
106
107
|
<p v-for="item in failures" :key="item.id" class="lares-composer__hint" data-status="error">
|
|
107
108
|
{{ t("upload.failed", { name: item.name, reason: t(`error.${item.code}`) }) }}
|
|
108
109
|
</p>
|
|
@@ -187,6 +188,8 @@ export default {
|
|
|
187
188
|
this.onSend();
|
|
188
189
|
},
|
|
189
190
|
canHold(event) {
|
|
191
|
+
// Voice input parked (hold-to-record).
|
|
192
|
+
return false;
|
|
190
193
|
if (this.draft.trim() || this.sending || this.voiceBlocked) return false;
|
|
191
194
|
if (event.pointerType === "mouse") return false;
|
|
192
195
|
return true;
|
|
@@ -23,11 +23,15 @@
|
|
|
23
23
|
playsinline
|
|
24
24
|
/>
|
|
25
25
|
<audio
|
|
26
|
-
v-else
|
|
26
|
+
v-else-if="item.kind === 'audio'"
|
|
27
27
|
class="lares-turn-media-audio"
|
|
28
28
|
:src="mediaUrl(item)"
|
|
29
29
|
controls
|
|
30
30
|
/>
|
|
31
|
+
<div
|
|
32
|
+
v-else-if="item.kind === 'model3d'"
|
|
33
|
+
class="lares-turn-media-model3d"
|
|
34
|
+
>{{ t("model3dHint") }}</div>
|
|
31
35
|
</figure>
|
|
32
36
|
</div>
|
|
33
37
|
<div v-if="group.files.length" class="lares-turn-files">
|
|
@@ -136,6 +140,14 @@ export default {
|
|
|
136
140
|
width: min(520px, 100%);
|
|
137
141
|
}
|
|
138
142
|
|
|
143
|
+
.lares-turn-media-model3d {
|
|
144
|
+
width: min(520px, 100%);
|
|
145
|
+
padding: 16px;
|
|
146
|
+
color: var(--q-ink-3);
|
|
147
|
+
font-size: 13px;
|
|
148
|
+
line-height: 20px;
|
|
149
|
+
}
|
|
150
|
+
|
|
139
151
|
.lares-turn-files {
|
|
140
152
|
display: grid;
|
|
141
153
|
grid-template-columns: max-content minmax(0, 1fr);
|
package/src/host.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
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
|
|
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): {
|
|
@@ -44,8 +57,11 @@ export function createHostClient(ports?: HostPorts): {
|
|
|
44
57
|
prompt: (sessionId: string, text: string) => Promise<{ ok: boolean }>;
|
|
45
58
|
};
|
|
46
59
|
|
|
60
|
+
export type ChatDevice = "desktop" | "mobile";
|
|
61
|
+
|
|
47
62
|
export const LaresApp: DefineComponent<{
|
|
48
63
|
locale?: string;
|
|
64
|
+
device?: ChatDevice;
|
|
49
65
|
baseUrl?: string;
|
|
50
66
|
proxyPrefix?: string;
|
|
51
67
|
env?: HostEnv;
|
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 {
|
|
4
|
+
export {
|
|
5
|
+
findLaresEntrance,
|
|
6
|
+
hostConfigFromEnv,
|
|
7
|
+
hostKey,
|
|
8
|
+
laresPortsFromAccount,
|
|
9
|
+
PC_TEST_PROXY,
|
|
10
|
+
} from "@olares/lares-core/larepass/host";
|
package/src/layout.js
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export const DEVICE_MOBILE = "mobile";
|
|
2
|
+
export const DEVICE_DESKTOP = "desktop";
|
|
3
|
+
export const DESKTOP_CHAT_WIDTH_PX = 748;
|
|
4
|
+
|
|
5
|
+
/** Host-facing layout. Unknown values stay on the phone column. */
|
|
6
|
+
export function chatDevice(value) {
|
|
7
|
+
return value === DEVICE_DESKTOP ? DEVICE_DESKTOP : DEVICE_MOBILE;
|
|
8
|
+
}
|
package/src/preview/Preview.vue
CHANGED
|
@@ -38,6 +38,9 @@
|
|
|
38
38
|
@click="onMarkdownClick"
|
|
39
39
|
/>
|
|
40
40
|
<pre v-else-if="data?.kind === 'text'" class="lares-preview__text">{{ data.text }}</pre>
|
|
41
|
+
<div v-else-if="data?.kind === 'model3d'" class="lares-preview__hint">
|
|
42
|
+
<p>{{ t("model3dHint") }}</p>
|
|
43
|
+
</div>
|
|
41
44
|
<div v-else class="lares-preview__hint">
|
|
42
45
|
<p>{{ t("unsupportedTitle") }}</p>
|
|
43
46
|
<p>{{ t("unsupported") }}</p>
|
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 =
|
|
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
|
+
}
|
|
@@ -22,6 +22,7 @@
|
|
|
22
22
|
</p>
|
|
23
23
|
<p v-if="modelError" class="lares-agent__hint" data-status="error">{{ modelError }}</p>
|
|
24
24
|
</section>
|
|
25
|
+
<!-- Voice input parked.
|
|
25
26
|
<section class="lares-agent__group">
|
|
26
27
|
<h2>{{ tVoice("settings.title") }}</h2>
|
|
27
28
|
<div class="lares-agent__list">
|
|
@@ -44,6 +45,7 @@
|
|
|
44
45
|
</div>
|
|
45
46
|
<p v-if="voiceError" class="lares-agent__hint" data-status="error">{{ voiceError }}</p>
|
|
46
47
|
</section>
|
|
48
|
+
-->
|
|
47
49
|
<section class="lares-agent__group">
|
|
48
50
|
<h2>{{ tSearch("settings.title") }}</h2>
|
|
49
51
|
<div class="lares-agent__list">
|
|
@@ -94,7 +96,9 @@ import {
|
|
|
94
96
|
searchValueFromMenu,
|
|
95
97
|
} from "@olares/lares-core/search/menu";
|
|
96
98
|
import { rememberedSettings } from "@olares/lares-core/larepass/settings";
|
|
99
|
+
import { hostKey as hostSessionKey } from "@olares/lares-core/larepass/host";
|
|
97
100
|
import { createHostClient } from "../host.js";
|
|
101
|
+
import { adoptHost } from "../runtime.js";
|
|
98
102
|
import { createT } from "../i18n.js";
|
|
99
103
|
import LaresSettingRow from "./SettingRow.vue";
|
|
100
104
|
import LaresSheet from "./Sheet.vue";
|
|
@@ -138,13 +142,19 @@ export default {
|
|
|
138
142
|
t() {
|
|
139
143
|
return createT(this.locale);
|
|
140
144
|
},
|
|
141
|
-
|
|
142
|
-
return
|
|
145
|
+
ports() {
|
|
146
|
+
return {
|
|
143
147
|
baseUrl: this.baseUrl,
|
|
144
148
|
proxyPrefix: this.proxyPrefix,
|
|
145
149
|
request: this.request,
|
|
146
150
|
env: this.env,
|
|
147
|
-
}
|
|
151
|
+
};
|
|
152
|
+
},
|
|
153
|
+
hostKey() {
|
|
154
|
+
return hostSessionKey(this.ports);
|
|
155
|
+
},
|
|
156
|
+
settings() {
|
|
157
|
+
return createHostClient(this.ports).settings;
|
|
148
158
|
},
|
|
149
159
|
busy() {
|
|
150
160
|
return this.loading || Boolean(this.pending);
|
|
@@ -238,6 +248,19 @@ export default {
|
|
|
238
248
|
return "";
|
|
239
249
|
},
|
|
240
250
|
},
|
|
251
|
+
watch: {
|
|
252
|
+
hostKey() {
|
|
253
|
+
adoptHost(this.ports);
|
|
254
|
+
this.panel = "";
|
|
255
|
+
this.models = null;
|
|
256
|
+
this.voice = null;
|
|
257
|
+
this.search = null;
|
|
258
|
+
this.modelError = "";
|
|
259
|
+
this.voiceError = "";
|
|
260
|
+
this.searchError = "";
|
|
261
|
+
this.load(true);
|
|
262
|
+
},
|
|
263
|
+
},
|
|
241
264
|
mounted() {
|
|
242
265
|
this.load(false);
|
|
243
266
|
},
|
package/src/styles.css
CHANGED
|
@@ -7,6 +7,21 @@
|
|
|
7
7
|
color: var(--q-ink-1);
|
|
8
8
|
}
|
|
9
9
|
|
|
10
|
+
.lares-shell__conversation {
|
|
11
|
+
display: flex;
|
|
12
|
+
flex-direction: column;
|
|
13
|
+
min-width: 0;
|
|
14
|
+
min-height: 0;
|
|
15
|
+
flex: 1;
|
|
16
|
+
width: 100%;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
.lares-shell[data-device="desktop"] .lares-shell__conversation {
|
|
20
|
+
width: 748px;
|
|
21
|
+
max-width: 100%;
|
|
22
|
+
margin-inline: auto;
|
|
23
|
+
}
|
|
24
|
+
|
|
10
25
|
.lares-shell button,
|
|
11
26
|
.lares-shell textarea,
|
|
12
27
|
.lares-shell select {
|