dsh-theone 0.3.9 → 0.3.13
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 +77 -53
- package/README.zh.md +82 -58
- package/cordis.patch.yml +0 -0
- package/dist/catalog-types.d.ts +0 -0
- package/dist/catalog-types.js +0 -0
- package/dist/client-locales.d.ts +20 -0
- package/dist/client-locales.js +40 -0
- package/dist/client-navigation.d.ts +0 -0
- package/dist/client-navigation.js +0 -0
- package/dist/client.d.ts +0 -0
- package/dist/client.js +375 -11
- package/dist/gateway-compaction.d.ts +0 -0
- package/dist/gateway-compaction.js +0 -0
- package/dist/history-catalog.d.ts +0 -0
- package/dist/history-catalog.js +0 -0
- package/dist/index.d.ts +17 -3
- package/dist/index.js +107 -23
- package/dist/linkage.d.ts +0 -0
- package/dist/linkage.js +0 -0
- package/dist/llm-router.d.ts +0 -0
- package/dist/llm-router.js +0 -0
- package/dist/model-json.d.ts +0 -0
- package/dist/model-json.js +0 -0
- package/dist/router.d.ts +0 -0
- package/dist/router.js +0 -0
- package/dist/routing-policy.d.ts +0 -0
- package/dist/routing-policy.js +0 -0
- package/dist/run.d.ts +0 -0
- package/dist/run.js +0 -0
- package/dist/settings-types.d.ts +0 -0
- package/dist/settings-types.js +0 -0
- package/dist/settings.d.ts +0 -0
- package/dist/settings.js +0 -0
- package/dist/store.d.ts +0 -0
- package/dist/store.js +0 -0
- package/dist/types.d.ts +0 -0
- package/dist/types.js +0 -0
- package/dist/update.d.ts +55 -0
- package/dist/update.js +121 -0
- package/docs/plugin-v0.1.md +0 -0
- package/docs/plugin-v0.1.zh.md +0 -0
- package/docs/plugin-v0.2.md +0 -0
- package/docs/plugin-v0.2.zh.md +0 -0
- package/package.json +1 -1
package/dist/client.js
CHANGED
|
@@ -88,6 +88,26 @@ var zh = {
|
|
|
88
88
|
"gateway.opening": "\u6B63\u5728\u6253\u5F00 TheOne \u4E3B\u804A\u5929\u2026",
|
|
89
89
|
"gateway.error": "\u4E3B\u804A\u5929\u6682\u65F6\u65E0\u6CD5\u6253\u5F00\uFF0C\u8BF7\u68C0\u67E5 DSH \u8FDE\u63A5\u548C TheOne \u63D2\u4EF6\u72B6\u6001\u3002",
|
|
90
90
|
"retry": "\u91CD\u8BD5",
|
|
91
|
+
"bg.label": "\u540E\u53F0",
|
|
92
|
+
"bg.follow": "\u9ED8\u8BA4",
|
|
93
|
+
"bg.title": "\u540E\u53F0\u6A21\u578B\uFF1A\u5206\u914D\u8BDD\u9898\u548C\u5E72\u6D3B\u90FD\u7528\u5B83",
|
|
94
|
+
"bg.followItem": "\u8DDF\u968F DSH \u9ED8\u8BA4\u6A21\u578B",
|
|
95
|
+
"bg.hint": "\u540E\u53F0\u6A21\u578B\uFF1A{model}\u3002TheOne \u5206\u914D\u8BDD\u9898\u548C\u540E\u53F0\u5E72\u6D3B\u90FD\u7528\u8FD9\u4E2A\u6A21\u578B\u3002",
|
|
96
|
+
"bg.hintFollow": "\u540E\u53F0\u6A21\u578B\uFF1A{model}\uFF08\u8DDF\u968F DSH \u9ED8\u8BA4\u6A21\u578B\uFF09\u3002\u70B9\u51FB\u53EF\u4EE5\u56FA\u5B9A\u4E3A\u5176\u4ED6\u6A21\u578B\u3002",
|
|
97
|
+
"bg.search": "\u641C\u7D22\u6A21\u578B",
|
|
98
|
+
"bg.none": "\u6CA1\u6709\u5339\u914D\u7684\u6A21\u578B",
|
|
99
|
+
"bg.error": "\u540E\u53F0\u6A21\u578B\u6CA1\u6709\u5207\u6362\u6210\u529F\uFF0C\u8BF7\u91CD\u8BD5\u3002",
|
|
100
|
+
"update.available": "\u66F4\u65B0",
|
|
101
|
+
"update.installing": "\u66F4\u65B0\u4E2D\u2026",
|
|
102
|
+
"update.restart": "\u91CD\u542F\u751F\u6548",
|
|
103
|
+
"update.reloading": "\u6B63\u5728\u91CD\u65B0\u52A0\u8F7D\u2026",
|
|
104
|
+
"update.reloadingHint": "TheOne \u6B63\u5728\u7528\u65B0\u7248\u672C\u91CD\u65B0\u52A0\u8F7D\uFF0CDSH \u4E0D\u9700\u8981\u91CD\u542F\uFF1B\u5B8C\u6210\u540E\u9875\u9762\u4F1A\u81EA\u52A8\u5237\u65B0\u3002",
|
|
105
|
+
"update.busy": "\u6709\u56DE\u590D\u6B63\u5728\u8FDB\u884C\uFF0C\u7B49\u5B83\u7ED3\u675F\u540E\u518D\u70B9\u66F4\u65B0\u3002",
|
|
106
|
+
"update.failed": "\u66F4\u65B0\u5931\u8D25",
|
|
107
|
+
"update.hint": "\u5F53\u524D {current}\uFF0C\u53EF\u66F4\u65B0\u5230 {latest}\u3002\u70B9\u51FB\u4E00\u952E\u66F4\u65B0\uFF0C\u4E0D\u7528\u91CD\u542F DSH\u3002",
|
|
108
|
+
"update.manualHint": "\u5F53\u524D {current}\uFF0C\u6700\u65B0 {latest}\u3002\u8FD9\u4EFD\u63D2\u4EF6\u4E0D\u662F\u4ECE GitHub \u6216 npm \u5B89\u88C5\u7684\uFF0C\u8BF7\u5728\u300C\u63D2\u4EF6\u300D\u9875\u9762\u91CD\u65B0\u5B89\u88C5\u3002",
|
|
109
|
+
"update.restartHint": "\u5DF2\u66F4\u65B0\uFF0C\u91CD\u542F DSH \u540E\u751F\u6548\u3002",
|
|
110
|
+
"update.failedHint": "\u66F4\u65B0\u6CA1\u6709\u5B8C\u6210\uFF08{error}\uFF09\u3002\u70B9\u51FB\u91CD\u8BD5\uFF0C\u6216\u5728\u300C\u63D2\u4EF6\u300D\u9875\u9762\u91CD\u65B0\u5B89\u88C5\u3002",
|
|
91
111
|
"settings.title": "TheOne \u8BBE\u7F6E",
|
|
92
112
|
"settings.menu": "\u8BBE\u7F6E",
|
|
93
113
|
"settings.subtitle": "\u67E5\u770B\u5F53\u524D\u751F\u6548\u7684\u914D\u7F6E\u548C\u5404\u9879\u7528\u9014\u3002",
|
|
@@ -257,6 +277,26 @@ var en = {
|
|
|
257
277
|
"gateway.opening": "Opening TheOne main chat\u2026",
|
|
258
278
|
"gateway.error": "Main chat could not open. Check your DSH connection and TheOne plugin status.",
|
|
259
279
|
"retry": "Retry",
|
|
280
|
+
"bg.label": "Background",
|
|
281
|
+
"bg.follow": "Default",
|
|
282
|
+
"bg.title": "Background model: routes and does the work",
|
|
283
|
+
"bg.followItem": "Follow DSH's default model",
|
|
284
|
+
"bg.hint": "Background model: {model}. TheOne routes and does the background work with it.",
|
|
285
|
+
"bg.hintFollow": "Background model: {model} (following DSH's default). Click to pin another model.",
|
|
286
|
+
"bg.search": "Search models",
|
|
287
|
+
"bg.none": "No matching models",
|
|
288
|
+
"bg.error": "The background model was not switched. Try again.",
|
|
289
|
+
"update.available": "Update",
|
|
290
|
+
"update.installing": "Updating\u2026",
|
|
291
|
+
"update.restart": "Restart to apply",
|
|
292
|
+
"update.reloading": "Reloading\u2026",
|
|
293
|
+
"update.reloadingHint": "TheOne is reloading with the new version; DSH keeps running, and the page refreshes when it is done.",
|
|
294
|
+
"update.busy": "A reply is in progress. Update once it finishes.",
|
|
295
|
+
"update.failed": "Update failed",
|
|
296
|
+
"update.hint": "You have {current}; {latest} is available. Click to update without restarting DSH.",
|
|
297
|
+
"update.manualHint": "You have {current}; {latest} is available. This copy was not installed from GitHub or npm, so reinstall it from the Plugins page.",
|
|
298
|
+
"update.restartHint": "Updated. Restart DSH to apply it.",
|
|
299
|
+
"update.failedHint": "The update did not finish ({error}). Click to retry, or reinstall from the Plugins page.",
|
|
260
300
|
"settings.title": "TheOne settings",
|
|
261
301
|
"settings.menu": "Settings",
|
|
262
302
|
"settings.subtitle": "Review active configuration and what each option does.",
|
|
@@ -497,9 +537,94 @@ function apply(ctx) {
|
|
|
497
537
|
});
|
|
498
538
|
});
|
|
499
539
|
});
|
|
540
|
+
let update;
|
|
541
|
+
const updateListeners = /* @__PURE__ */ new Set();
|
|
542
|
+
const setUpdate = (value) => {
|
|
543
|
+
update = value;
|
|
544
|
+
for (const listener of updateListeners) listener();
|
|
545
|
+
};
|
|
546
|
+
const subscribeUpdate = (listener) => {
|
|
547
|
+
updateListeners.add(listener);
|
|
548
|
+
return () => {
|
|
549
|
+
updateListeners.delete(listener);
|
|
550
|
+
};
|
|
551
|
+
};
|
|
552
|
+
const readUpdate = async (method = "GET") => {
|
|
553
|
+
try {
|
|
554
|
+
const response = await fetch("/api/theone/update", { method, signal: lifetime.signal, cache: "no-store" });
|
|
555
|
+
if (response.ok || response.status === 409) setUpdate(await response.json());
|
|
556
|
+
if (update?.state === "reloading") void awaitReload(update.current);
|
|
557
|
+
} catch {
|
|
558
|
+
}
|
|
559
|
+
};
|
|
560
|
+
async function awaitReload(previous) {
|
|
561
|
+
for (const started = Date.now(); Date.now() - started < 12e4; ) {
|
|
562
|
+
await new Promise((resolve) => setTimeout(resolve, 1500));
|
|
563
|
+
try {
|
|
564
|
+
const response = await fetch("/api/theone/update", { cache: "no-store" });
|
|
565
|
+
if (response.ok && (await response.json()).current !== previous) {
|
|
566
|
+
window.location.reload();
|
|
567
|
+
return;
|
|
568
|
+
}
|
|
569
|
+
} catch {
|
|
570
|
+
}
|
|
571
|
+
}
|
|
572
|
+
if (update) setUpdate({ ...update, state: "restart" });
|
|
573
|
+
}
|
|
574
|
+
ctx.effect(() => {
|
|
575
|
+
void readUpdate();
|
|
576
|
+
const timer = setInterval(() => {
|
|
577
|
+
void readUpdate();
|
|
578
|
+
}, 6 * 36e5);
|
|
579
|
+
return () => clearInterval(timer);
|
|
580
|
+
});
|
|
581
|
+
function UpdateButton() {
|
|
582
|
+
const t2 = useText();
|
|
583
|
+
const status = (0, import_react.useSyncExternalStore)(subscribeUpdate, () => update);
|
|
584
|
+
if (!status || !status.available && !status.state) return null;
|
|
585
|
+
const label = status.state === "installing" ? t2("update.installing") : status.state === "reloading" ? t2("update.reloading") : status.state === "restart" ? t2("update.restart") : status.state === "failed" ? t2("update.failed") : t2("update.available");
|
|
586
|
+
const title = status.error === "GATEWAY_BUSY" ? t2("update.busy") : status.state === "reloading" ? t2("update.reloadingHint") : status.state === "restart" ? t2("update.restartHint") : status.state === "failed" ? t2("update.failedHint", { error: status.error ?? "" }) : status.installable ? t2("update.hint", { current: status.current, latest: status.latest ?? "" }) : t2("update.manualHint", { current: status.current, latest: status.latest ?? "" });
|
|
587
|
+
const act = (event) => {
|
|
588
|
+
event.preventDefault();
|
|
589
|
+
event.stopPropagation();
|
|
590
|
+
if (status.state === "installing" || status.state === "reloading" || status.state === "restart") return;
|
|
591
|
+
if (!status.installable) {
|
|
592
|
+
window.open("https://github.com/YunongDai2005/dsh-theone#readme", "_blank", "noopener");
|
|
593
|
+
return;
|
|
594
|
+
}
|
|
595
|
+
setUpdate({ ...status, state: "installing" });
|
|
596
|
+
void readUpdate("POST");
|
|
597
|
+
};
|
|
598
|
+
return (0, import_react.createElement)(
|
|
599
|
+
"span",
|
|
600
|
+
{
|
|
601
|
+
className: "theone-update",
|
|
602
|
+
role: "button",
|
|
603
|
+
tabIndex: 0,
|
|
604
|
+
title,
|
|
605
|
+
"aria-label": title,
|
|
606
|
+
"data-state": status.state ?? "available",
|
|
607
|
+
onClick: act,
|
|
608
|
+
onPointerDown: (event) => event.stopPropagation(),
|
|
609
|
+
onKeyDown: (event) => {
|
|
610
|
+
if (event.key === "Enter" || event.key === " ") act(event);
|
|
611
|
+
}
|
|
612
|
+
},
|
|
613
|
+
status.state === "installing" || status.state === "reloading" ? (0, import_react.createElement)("span", { className: "theone-update-spin", "aria-hidden": true }) : null,
|
|
614
|
+
label,
|
|
615
|
+
!status.state && status.latest ? (0, import_react.createElement)("small", null, `v${status.latest}`) : null
|
|
616
|
+
);
|
|
617
|
+
}
|
|
618
|
+
const symbol = () => (0, import_react.createElement)(
|
|
619
|
+
"svg",
|
|
620
|
+
{ className: "theone-symbol", viewBox: "0 0 20 20", width: 20, height: 20, "aria-hidden": true, focusable: false },
|
|
621
|
+
(0, import_react.createElement)("circle", { cx: 10, cy: 10, r: 8.6, fill: "none", stroke: "currentColor", strokeWidth: 1.4 }),
|
|
622
|
+
(0, import_react.createElement)("circle", { cx: 10, cy: 10, r: 2.4, fill: "currentColor" })
|
|
623
|
+
);
|
|
500
624
|
function SidebarEntry({ size }) {
|
|
501
625
|
const t2 = useText();
|
|
502
626
|
const marker = (0, import_react.useRef)(null);
|
|
627
|
+
const pending = (0, import_react.useSyncExternalStore)(subscribeUpdate, () => !!update?.available && !update.state);
|
|
503
628
|
const id = (0, import_react.useSyncExternalStore)(navigation.subscribe, navigation.getSnapshot);
|
|
504
629
|
const sessions = (0, import_react.useSyncExternalStore)(ctx.sessions.list.subscribe, ctx.sessions.list.getSnapshot);
|
|
505
630
|
const panel = (0, import_react.useSyncExternalStore)(ctx.layout.panelInfo.subscribe, ctx.layout.panelInfo.getSnapshot);
|
|
@@ -606,7 +731,7 @@ function apply(ctx) {
|
|
|
606
731
|
return (0, import_react.createElement)(
|
|
607
732
|
"span",
|
|
608
733
|
{ ref: marker, className: "theone-nav", translate: "no", "data-wide": size === 16, "data-active": active },
|
|
609
|
-
(0, import_react.createElement)("span", { className: "theone-symbol" }),
|
|
734
|
+
(0, import_react.createElement)("span", { className: "theone-symbol-wrap" }, symbol(), size !== 16 && pending ? (0, import_react.createElement)("span", { className: "theone-update-dot", "aria-hidden": true }) : null),
|
|
610
735
|
size === 16 && (0, import_react.createElement)(
|
|
611
736
|
"span",
|
|
612
737
|
{ className: "theone-entry-copy" },
|
|
@@ -622,9 +747,214 @@ function apply(ctx) {
|
|
|
622
747
|
(0, import_react.createElement)("span", { className: "theone-entry-label" }, t2("gateway.label"))
|
|
623
748
|
),
|
|
624
749
|
(0, import_react.createElement)("span", { className: "theone-entry-sub" }, t2("gateway.subtitle"))
|
|
625
|
-
)
|
|
750
|
+
),
|
|
751
|
+
size === 16 && (0, import_react.createElement)(UpdateButton)
|
|
626
752
|
);
|
|
627
753
|
}
|
|
754
|
+
const readSettings = async () => {
|
|
755
|
+
const response = await fetch("/api/theone/settings", { signal: lifetime.signal, cache: "no-store" });
|
|
756
|
+
if (!response.ok) throw new Error("Settings unavailable");
|
|
757
|
+
return await response.json();
|
|
758
|
+
};
|
|
759
|
+
const saveBackgroundModel = async (choice) => {
|
|
760
|
+
for (let attempt = 0; attempt < 2; attempt++) {
|
|
761
|
+
const current = await readSettings();
|
|
762
|
+
const response = await fetch("/api/theone/settings", {
|
|
763
|
+
method: "PUT",
|
|
764
|
+
signal: lifetime.signal,
|
|
765
|
+
cache: "no-store",
|
|
766
|
+
headers: { "content-type": "application/json" },
|
|
767
|
+
body: JSON.stringify({ revision: current.revision, values: { ...current.savedValues, workerProvider: choice?.provider ?? null, workerModel: choice?.model ?? null } })
|
|
768
|
+
});
|
|
769
|
+
if (response.ok) return await response.json();
|
|
770
|
+
if (response.status !== 409) break;
|
|
771
|
+
}
|
|
772
|
+
throw new Error("Background model not saved");
|
|
773
|
+
};
|
|
774
|
+
function BackgroundModel({ directory }) {
|
|
775
|
+
const t2 = useText();
|
|
776
|
+
const state = (0, import_react.useSyncExternalStore)((listener) => directory.subscribe(listener), () => directory.getSnapshot());
|
|
777
|
+
const selection = state.pending ?? state.current;
|
|
778
|
+
const theone = selection?.provider === "theone";
|
|
779
|
+
const [settings, setSettings] = (0, import_react.useState)();
|
|
780
|
+
const [failed, setFailed] = (0, import_react.useState)(false);
|
|
781
|
+
const [saving, setSaving] = (0, import_react.useState)(false);
|
|
782
|
+
const button = (0, import_react.useRef)(null);
|
|
783
|
+
const closeMenu = (0, import_react.useRef)();
|
|
784
|
+
(0, import_react.useEffect)(() => {
|
|
785
|
+
if (!theone) return;
|
|
786
|
+
let alive = true;
|
|
787
|
+
readSettings().then((value) => {
|
|
788
|
+
if (alive) setSettings(value);
|
|
789
|
+
}, () => {
|
|
790
|
+
});
|
|
791
|
+
return () => {
|
|
792
|
+
alive = false;
|
|
793
|
+
closeMenu.current?.();
|
|
794
|
+
};
|
|
795
|
+
}, [theone]);
|
|
796
|
+
if (!theone) return null;
|
|
797
|
+
const pinned = settings?.values.workerProvider && settings.values.workerModel ? { provider: settings.values.workerProvider, model: settings.values.workerModel } : null;
|
|
798
|
+
const nameOf = (provider, model) => settings?.models.find((item) => item.provider === provider && item.id === model)?.name ?? model;
|
|
799
|
+
const effective = settings?.model ? nameOf(settings.model.provider, settings.model.model) : void 0;
|
|
800
|
+
const label = pinned ? nameOf(pinned.provider, pinned.model) : effective ?? t2("bg.follow");
|
|
801
|
+
const choose = async (choice) => {
|
|
802
|
+
closeMenu.current?.();
|
|
803
|
+
setSaving(true);
|
|
804
|
+
setFailed(false);
|
|
805
|
+
try {
|
|
806
|
+
setSettings(await saveBackgroundModel(choice));
|
|
807
|
+
} catch {
|
|
808
|
+
setFailed(true);
|
|
809
|
+
} finally {
|
|
810
|
+
setSaving(false);
|
|
811
|
+
}
|
|
812
|
+
};
|
|
813
|
+
const open = () => {
|
|
814
|
+
const anchor = button.current;
|
|
815
|
+
if (!anchor || closeMenu.current) {
|
|
816
|
+
closeMenu.current?.();
|
|
817
|
+
return;
|
|
818
|
+
}
|
|
819
|
+
const menu = document.createElement("div");
|
|
820
|
+
menu.className = "theone-bg-menu";
|
|
821
|
+
menu.setAttribute("role", "menu");
|
|
822
|
+
menu.setAttribute("translate", "no");
|
|
823
|
+
menu.setAttribute("aria-label", t2("bg.title"));
|
|
824
|
+
const heading = document.createElement("div");
|
|
825
|
+
heading.className = "theone-bg-heading";
|
|
826
|
+
heading.textContent = t2("bg.title");
|
|
827
|
+
const list = document.createElement("div");
|
|
828
|
+
list.className = "theone-bg-list";
|
|
829
|
+
const models = (settings?.models ?? []).filter((item2) => item2.provider !== "theone");
|
|
830
|
+
const item = (text, sub, checked, pick) => {
|
|
831
|
+
const row = document.createElement("button");
|
|
832
|
+
row.type = "button";
|
|
833
|
+
row.setAttribute("role", "menuitemradio");
|
|
834
|
+
row.setAttribute("aria-checked", String(checked));
|
|
835
|
+
row.className = "theone-bg-item";
|
|
836
|
+
const name = document.createElement("span");
|
|
837
|
+
name.textContent = text;
|
|
838
|
+
row.append(name);
|
|
839
|
+
if (sub) {
|
|
840
|
+
const small = document.createElement("small");
|
|
841
|
+
small.textContent = sub;
|
|
842
|
+
row.append(small);
|
|
843
|
+
}
|
|
844
|
+
const mark = document.createElement("span");
|
|
845
|
+
mark.className = "theone-bg-check";
|
|
846
|
+
mark.textContent = checked ? "\u2713" : "";
|
|
847
|
+
row.append(mark);
|
|
848
|
+
row.addEventListener("click", pick);
|
|
849
|
+
return row;
|
|
850
|
+
};
|
|
851
|
+
const render = (query) => {
|
|
852
|
+
list.replaceChildren(item(t2("bg.followItem"), !pinned && effective ? effective : void 0, !pinned, () => {
|
|
853
|
+
void choose(null);
|
|
854
|
+
}));
|
|
855
|
+
const needle = query.trim().toLowerCase();
|
|
856
|
+
const matched = models.filter((model) => !needle || `${model.name} ${model.id} ${model.provider}`.toLowerCase().includes(needle));
|
|
857
|
+
for (const provider of [...new Set(matched.map((model) => model.provider))]) {
|
|
858
|
+
const group = document.createElement("div");
|
|
859
|
+
group.className = "theone-bg-group";
|
|
860
|
+
group.textContent = provider;
|
|
861
|
+
list.append(group);
|
|
862
|
+
for (const model of matched.filter((entry) => entry.provider === provider))
|
|
863
|
+
list.append(item(model.name, model.name !== model.id ? model.id : void 0, pinned?.provider === model.provider && pinned.model === model.id, () => {
|
|
864
|
+
void choose({ provider: model.provider, model: model.id });
|
|
865
|
+
}));
|
|
866
|
+
}
|
|
867
|
+
if (!matched.length && needle) {
|
|
868
|
+
const empty = document.createElement("p");
|
|
869
|
+
empty.className = "theone-bg-empty";
|
|
870
|
+
empty.textContent = t2("bg.none");
|
|
871
|
+
list.append(empty);
|
|
872
|
+
}
|
|
873
|
+
};
|
|
874
|
+
menu.append(heading);
|
|
875
|
+
let search;
|
|
876
|
+
if (models.length > 8) {
|
|
877
|
+
search = document.createElement("input");
|
|
878
|
+
search.type = "search";
|
|
879
|
+
search.className = "theone-bg-search";
|
|
880
|
+
search.placeholder = t2("bg.search");
|
|
881
|
+
search.addEventListener("input", () => render(search.value));
|
|
882
|
+
menu.append(search);
|
|
883
|
+
}
|
|
884
|
+
menu.append(list);
|
|
885
|
+
render("");
|
|
886
|
+
document.body.append(menu);
|
|
887
|
+
anchor.setAttribute("aria-expanded", "true");
|
|
888
|
+
const place = () => {
|
|
889
|
+
const bounds = anchor.getBoundingClientRect(), size = menu.getBoundingClientRect();
|
|
890
|
+
menu.style.left = `${Math.max(8, Math.min(bounds.right - size.width, window.innerWidth - size.width - 8))}px`;
|
|
891
|
+
menu.style.top = `${Math.max(8, bounds.top - size.height - 8)}px`;
|
|
892
|
+
};
|
|
893
|
+
place();
|
|
894
|
+
const rows = () => [...menu.querySelectorAll(".theone-bg-item")];
|
|
895
|
+
const outside = (event) => {
|
|
896
|
+
if (!menu.contains(event.target) && !anchor.contains(event.target)) close();
|
|
897
|
+
};
|
|
898
|
+
const keydown = (event) => {
|
|
899
|
+
if (event.key === "Escape") {
|
|
900
|
+
event.preventDefault();
|
|
901
|
+
close();
|
|
902
|
+
anchor.focus();
|
|
903
|
+
} else if (event.key === "ArrowDown" || event.key === "ArrowUp") {
|
|
904
|
+
event.preventDefault();
|
|
905
|
+
const all = rows(), index = all.indexOf(document.activeElement);
|
|
906
|
+
all[(index + (event.key === "ArrowDown" ? 1 : all.length - 1) + (index < 0 && event.key === "ArrowUp" ? 1 : 0)) % all.length]?.focus();
|
|
907
|
+
}
|
|
908
|
+
};
|
|
909
|
+
const close = () => {
|
|
910
|
+
menu.remove();
|
|
911
|
+
closeMenu.current = void 0;
|
|
912
|
+
anchor.setAttribute("aria-expanded", "false");
|
|
913
|
+
document.removeEventListener("pointerdown", outside, true);
|
|
914
|
+
document.removeEventListener("keydown", keydown, true);
|
|
915
|
+
window.removeEventListener("resize", close);
|
|
916
|
+
window.removeEventListener("blur", close);
|
|
917
|
+
};
|
|
918
|
+
closeMenu.current = close;
|
|
919
|
+
document.addEventListener("pointerdown", outside, true);
|
|
920
|
+
document.addEventListener("keydown", keydown, true);
|
|
921
|
+
window.addEventListener("resize", close);
|
|
922
|
+
window.addEventListener("blur", close);
|
|
923
|
+
(search ?? rows().find((row) => row.getAttribute("aria-checked") === "true") ?? rows()[0])?.focus();
|
|
924
|
+
};
|
|
925
|
+
const title = failed ? t2("bg.error") : t2(pinned ? "bg.hint" : "bg.hintFollow", { model: label });
|
|
926
|
+
return (0, import_react.createElement)(
|
|
927
|
+
"button",
|
|
928
|
+
{
|
|
929
|
+
ref: button,
|
|
930
|
+
type: "button",
|
|
931
|
+
className: "theone-bg",
|
|
932
|
+
title,
|
|
933
|
+
"aria-label": title,
|
|
934
|
+
"aria-haspopup": "menu",
|
|
935
|
+
"data-failed": failed,
|
|
936
|
+
disabled: saving,
|
|
937
|
+
onClick: () => {
|
|
938
|
+
if (settings) open();
|
|
939
|
+
else readSettings().then((value) => {
|
|
940
|
+
setSettings(value);
|
|
941
|
+
}, () => setFailed(true));
|
|
942
|
+
}
|
|
943
|
+
},
|
|
944
|
+
(0, import_react.createElement)("span", { className: "theone-bg-caption" }, t2("bg.label")),
|
|
945
|
+
(0, import_react.createElement)("span", { className: "theone-bg-text" }, label),
|
|
946
|
+
(0, import_react.createElement)("span", { className: "theone-bg-chevron", "aria-hidden": true }, saving ? "\u2026" : "\u2303")
|
|
947
|
+
);
|
|
948
|
+
}
|
|
949
|
+
ctx.inject(["slots", "modelDirectories"], (scope) => {
|
|
950
|
+
const slots = scope.slots;
|
|
951
|
+
slots.inject("conversation.input.right", () => slots.register({
|
|
952
|
+
name: "conversation.input.right",
|
|
953
|
+
id: "theone.background-model",
|
|
954
|
+
order: 100,
|
|
955
|
+
inject: (sessionId) => ({ directory: scope.modelDirectories.directoryFor(sessionId).store })
|
|
956
|
+
}, BackgroundModel));
|
|
957
|
+
});
|
|
628
958
|
function GatewayPanel() {
|
|
629
959
|
const t2 = useText();
|
|
630
960
|
const [error, setError] = (0, import_react.useState)();
|
|
@@ -1307,7 +1637,7 @@ function apply(ctx) {
|
|
|
1307
1637
|
ctx.effect(() => {
|
|
1308
1638
|
const style = document.createElement("style");
|
|
1309
1639
|
style.dataset.plugin = "dsh-theone";
|
|
1310
|
-
style.textContent = sidebarCss + catalogCss + settingsCss;
|
|
1640
|
+
style.textContent = sidebarCss + catalogCss + settingsCss + composerCss;
|
|
1311
1641
|
document.head.append(style);
|
|
1312
1642
|
return () => {
|
|
1313
1643
|
lifetime.abort();
|
|
@@ -1317,17 +1647,17 @@ function apply(ctx) {
|
|
|
1317
1647
|
ctx.effect(() => {
|
|
1318
1648
|
const style = document.createElement("style");
|
|
1319
1649
|
style.dataset.plugin = "dsh-theone-gateway-row";
|
|
1320
|
-
const
|
|
1650
|
+
const update2 = () => {
|
|
1321
1651
|
const id = navigation.getSnapshot();
|
|
1322
1652
|
style.textContent = id ? `[role="treeitem"][data-row-key="${CSS.escape(`session:${id}`)}"]{display:none!important}` : "";
|
|
1323
1653
|
};
|
|
1324
|
-
|
|
1325
|
-
const unsubscribe = navigation.subscribe(
|
|
1326
|
-
window.addEventListener("storage",
|
|
1654
|
+
update2();
|
|
1655
|
+
const unsubscribe = navigation.subscribe(update2);
|
|
1656
|
+
window.addEventListener("storage", update2);
|
|
1327
1657
|
document.head.append(style);
|
|
1328
1658
|
return () => {
|
|
1329
1659
|
unsubscribe();
|
|
1330
|
-
window.removeEventListener("storage",
|
|
1660
|
+
window.removeEventListener("storage", update2);
|
|
1331
1661
|
style.remove();
|
|
1332
1662
|
};
|
|
1333
1663
|
});
|
|
@@ -1355,9 +1685,21 @@ button:has(.theone-nav[data-wide=true])>span:not(:has(.theone-nav)){display:none
|
|
|
1355
1685
|
button:has(.theone-nav):hover{background:var(--one-tint);border-color:color-mix(in srgb,var(--one-accent) 40%,var(--one-line))}
|
|
1356
1686
|
button:has(.theone-nav[data-active=true]){border-color:color-mix(in srgb,var(--one-accent) 40%,var(--one-line))}
|
|
1357
1687
|
.theone-nav{display:flex;align-items:center;gap:10px;color:var(--one-accent);font-family:inherit;position:relative;z-index:1}
|
|
1358
|
-
.theone-symbol{
|
|
1359
|
-
.theone-symbol
|
|
1360
|
-
.theone-nav[data-wide=true] .theone-symbol{margin:0
|
|
1688
|
+
.theone-symbol-wrap{position:relative;display:inline-flex;flex:none;width:20px;height:20px}
|
|
1689
|
+
.theone-nav .theone-symbol{display:block;width:20px;height:20px;flex:none;overflow:visible;border:0;border-radius:0;background:none}
|
|
1690
|
+
.theone-nav[data-wide=true] .theone-symbol-wrap{margin:0 2px}
|
|
1691
|
+
.theone-update-dot{position:absolute;top:-2px;right:-2px;width:7px;height:7px;border-radius:50%;background:#e8590c;box-shadow:0 0 0 2px var(--one-tint)}
|
|
1692
|
+
button:has(.theone-nav[data-wide=true])>span:has(.theone-nav){flex:1;min-width:0}
|
|
1693
|
+
.theone-nav[data-wide=true]{width:100%}
|
|
1694
|
+
.theone-update{margin-left:auto;align-self:center;display:inline-flex;align-items:center;gap:5px;padding:5px 10px;border-radius:999px;border:1px solid color-mix(in srgb,var(--one-accent) 45%,transparent);background:color-mix(in srgb,var(--one-accent) 12%,transparent);color:var(--one-accent);font-size:12px;line-height:16px;white-space:nowrap;cursor:pointer;transition:background 150ms ease}
|
|
1695
|
+
.theone-update:hover{background:color-mix(in srgb,var(--one-accent) 22%,transparent)}
|
|
1696
|
+
.theone-update:focus-visible{outline:2px solid var(--one-accent);outline-offset:2px}
|
|
1697
|
+
.theone-update small{font-size:11px;opacity:.75}
|
|
1698
|
+
.theone-update[data-state=installing],.theone-update[data-state=reloading],.theone-update[data-state=restart]{cursor:default}
|
|
1699
|
+
.theone-update[data-state=failed]{color:#d9480f;border-color:#d9480f66;background:#d9480f14}
|
|
1700
|
+
.theone-update-spin{width:10px;height:10px;border-radius:50%;border:1.5px solid currentColor;border-right-color:transparent;animation:theone-spin 800ms linear infinite}
|
|
1701
|
+
@keyframes theone-spin{to{transform:rotate(360deg)}}
|
|
1702
|
+
@media(prefers-reduced-motion:reduce){.theone-update-spin{animation:none}}
|
|
1361
1703
|
.theone-entry-copy{display:flex;flex-direction:column;align-items:flex-start;gap:2px}
|
|
1362
1704
|
.theone-entry-title{display:flex;align-items:center;gap:9px;line-height:22px}
|
|
1363
1705
|
.theone-wordmark{display:inline-flex;align-items:baseline;gap:1px;white-space:nowrap}
|
|
@@ -1374,6 +1716,28 @@ button:has(.theone-catalog-entry)>span:not(:has(.theone-catalog-entry)){display:
|
|
|
1374
1716
|
.theone-catalog{padding:32px;max-width:1180px;margin:auto;box-sizing:border-box;height:100%;overflow:auto;color:var(--dsw-alias-label-primary)}
|
|
1375
1717
|
.theone-catalog-header{display:flex;justify-content:space-between;align-items:center;gap:16px}.theone-catalog h1{font-size:24px;margin:0 0 8px}.theone-catalog-header p,.theone-catalog-status,.theone-group-summary{opacity:.65;margin:0 0 18px;line-height:1.6}.theone-catalog button{border:1px solid #8883;border-radius:9px;padding:8px 13px;background:transparent;color:inherit;cursor:pointer;font:inherit;white-space:nowrap}.theone-catalog button:disabled{opacity:.5;cursor:default}.theone-catalog-groups{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(100%,310px),1fr));gap:20px}.theone-topic-group{border:1px solid #8882;border-radius:16px;padding:20px;background:#88805}.theone-topic-group h2{font-size:18px;margin:0 0 8px}.theone-topic-group h2 span{font-size:13px;opacity:.5}.theone-topic-card{border-top:1px solid #8882;padding:16px 0}.theone-topic-card:last-child{padding-bottom:0}.theone-topic-card h3{font-size:15px;line-height:1.5;margin:0 0 7px}.theone-topic-card p{font-size:13px;line-height:1.7;opacity:.75;margin:0 0 12px;display:-webkit-box;-webkit-line-clamp:4;-webkit-box-orient:vertical;overflow:hidden}.theone-topic-actions{display:flex;gap:8px;flex-wrap:wrap}.theone-topic-actions button{font-size:12px}.theone-topic-actions .theone-source-link{border-color:transparent;opacity:.6}.theone-catalog-warning{background:#ff900011;padding:12px;border-radius:10px;font-size:13px}.theone-catalog-entry{display:flex;align-items:center;gap:10px;font-size:14px}.theone-catalog-empty{padding:40px 0;opacity:.65;line-height:1.8}.theone-catalog-tools{display:flex;gap:8px;flex-wrap:wrap;justify-content:flex-end}.theone-topic-links{display:flex;flex-wrap:wrap;align-items:center;gap:6px;margin:0 0 12px;font-size:12px}.theone-links-label,.theone-links-empty{opacity:.6}.theone-link-chip{display:inline-flex;align-items:center;gap:2px;border:1px solid #8883;border-radius:999px;padding:2px 4px 2px 9px}.theone-catalog .theone-link-chip button{border:0;padding:0 5px;opacity:.6;font-size:13px;line-height:1}.theone-topic-links select{font:inherit;font-size:12px;color:inherit;background:transparent;border:1px solid #8883;border-radius:8px;padding:2px 6px}.theone-link-private{display:inline-flex;align-items:center;gap:4px;opacity:.75;cursor:pointer}.theone-topic-card .theone-topic-state{font-size:12px;opacity:.8;-webkit-line-clamp:3}.theone-topic-state span{opacity:.6;margin-right:4px}.theone-manage{display:flex;flex-direction:column;gap:10px;margin-top:12px;padding:14px;border:1px solid #8883;border-radius:12px;font-size:12px}.theone-create{flex-direction:row;flex-wrap:wrap;align-items:center;margin:0 0 18px}.theone-create input{flex:1;min-width:180px}.theone-manage-field{display:flex;flex-direction:column;gap:5px}.theone-manage-field>span{opacity:.65}.theone-manage input,.theone-manage textarea,.theone-manage select,.theone-routes select{font:inherit;font-size:12px;color:inherit;background:transparent;border:1px solid #8883;border-radius:8px;padding:6px 8px;box-sizing:border-box;min-width:0}.theone-manage textarea{resize:vertical;width:100%}.theone-manage-row{display:flex;flex-wrap:wrap;gap:8px;align-items:center}.theone-manage-row select,.theone-manage-row input{flex:1;min-width:140px}.theone-manage-hint{opacity:.6;font-size:12px;line-height:1.6;margin:0}.theone-catalog .theone-danger{color:#c4402f;border-color:#c4402f55}.theone-routes{border:1px solid #8882;border-radius:16px;padding:14px 20px;margin:0 0 20px}.theone-routes summary{cursor:pointer;font-weight:500}.theone-routes summary span{opacity:.5;font-size:13px}.theone-routes ol{list-style:none;margin:12px 0 0;padding:0;display:flex;flex-direction:column;gap:10px}.theone-routes li{border-top:1px solid #8882;padding-top:10px;font-size:12px;display:flex;flex-direction:column;gap:5px}.theone-route-head{display:flex;gap:10px;min-width:0}.theone-route-head time{opacity:.55;flex:none}.theone-route-head q{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.theone-route-body{display:flex;flex-wrap:wrap;gap:8px;align-items:center}.theone-route-body small{opacity:.6}.theone-route-fixed{opacity:.75}@media(max-width:640px){.theone-catalog{padding:20px}.theone-catalog-header{align-items:flex-start}.theone-catalog-header h1{font-size:21px}}
|
|
1376
1718
|
`;
|
|
1719
|
+
var composerCss = `
|
|
1720
|
+
.theone-bg{display:inline-flex;align-items:center;gap:5px;height:32px;padding:0 10px;border:0;border-radius:10px;background:transparent;color:var(--dsw-alias-label-primary);font:inherit;font-size:14px;white-space:nowrap;cursor:pointer;max-width:220px}
|
|
1721
|
+
.theone-bg:hover,.theone-bg[aria-expanded=true]{background:var(--dsw-alias-interactive-bg-hover)}
|
|
1722
|
+
.theone-bg:focus-visible{outline:2px solid var(--dsw-focus-ring-color,#4a7fb5);outline-offset:1px}
|
|
1723
|
+
.theone-bg:disabled{opacity:.6;cursor:default}
|
|
1724
|
+
.theone-bg-caption,.theone-bg-chevron{color:var(--dsw-alias-label-secondary)}
|
|
1725
|
+
.theone-bg-text{overflow:hidden;text-overflow:ellipsis;display:var(--dsh-composer-model-text-display,inline)}
|
|
1726
|
+
.theone-bg-chevron{font-size:11px}
|
|
1727
|
+
.theone-bg[data-failed=true] .theone-bg-caption{color:#d9480f}
|
|
1728
|
+
.theone-bg-menu{position:fixed;z-index:10000;width:280px;max-height:min(420px,70vh);display:flex;flex-direction:column;padding:6px;border:1px solid var(--dsw-alias-border-l2);border-radius:14px;background:var(--dsw-specific-sidebar-fill);color:var(--dsw-alias-label-primary);box-shadow:0 10px 32px #0003;font:inherit;font-size:14px;box-sizing:border-box}
|
|
1729
|
+
.theone-bg-heading{padding:8px 10px 6px;font-size:12px;color:var(--dsw-alias-label-secondary)}
|
|
1730
|
+
.theone-bg-search{margin:0 4px 6px;padding:7px 10px;border:1px solid var(--dsw-alias-border-l2);border-radius:8px;background:transparent;color:inherit;font:inherit;font-size:13px;outline:none}
|
|
1731
|
+
.theone-bg-search:focus{border-color:var(--dsw-focus-ring-color,#4a7fb5)}
|
|
1732
|
+
.theone-bg-list{overflow:auto;min-height:0}
|
|
1733
|
+
.theone-bg-group{padding:8px 10px 4px;font-size:12px;color:var(--dsw-alias-label-secondary)}
|
|
1734
|
+
.theone-bg-item{display:flex;align-items:center;gap:8px;width:100%;padding:9px 10px;border:0;border-radius:8px;background:transparent;color:inherit;font:inherit;text-align:left;cursor:pointer}
|
|
1735
|
+
.theone-bg-item:hover,.theone-bg-item:focus-visible{outline:none;background:var(--dsw-alias-interactive-bg-hover)}
|
|
1736
|
+
.theone-bg-item span:first-child{flex:0 1 auto;min-width:40px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
|
|
1737
|
+
.theone-bg-item small{flex:0 100 auto;color:var(--dsw-alias-label-secondary);font-size:12px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:0}
|
|
1738
|
+
.theone-bg-check{margin-left:auto;flex:none;width:14px;text-align:center;color:var(--dsw-alias-label-primary)}
|
|
1739
|
+
.theone-bg-empty{margin:8px 10px;font-size:13px;color:var(--dsw-alias-label-secondary)}
|
|
1740
|
+
`;
|
|
1377
1741
|
var settingsCss = `
|
|
1378
1742
|
.theone-settings{--one-settings-accent:#a75b1e}[data-ds-dark-theme] .theone-settings{--one-settings-accent:#93c8f3}
|
|
1379
1743
|
.theone-settings input,.theone-settings select{width:100%;box-sizing:border-box;min-height:38px;padding:8px 11px;border:1px solid var(--dsw-alias-border-l2);border-radius:8px;font:inherit;color:inherit;background:var(--dsw-specific-sidebar-fill)}.theone-settings input:focus-visible,.theone-settings select:focus-visible{outline:2px solid var(--one-settings-accent);outline-offset:2px}.theone-settings input:disabled,.theone-settings select:disabled,.theone-settings button:disabled{opacity:.5;cursor:default}.theone-settings small{display:block;margin-top:5px;color:var(--dsw-alias-label-secondary);font-size:12px}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
package/dist/history-catalog.js
CHANGED
|
File without changes
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Context, Service } from '@deepseek-ai/cordis';
|
|
2
2
|
import z from '@deepseek-ai/schemastery';
|
|
3
|
-
import type { GenerateOptions, LlmResolvedModelInfo, StreamChunk } from '@deepseek-ai/dsh-llm';
|
|
3
|
+
import type { GenerateOptions, LlmModelInfo, LlmResolvedModelInfo, StreamChunk } from '@deepseek-ai/dsh-llm';
|
|
4
|
+
import type { ModelSelection } from '@deepseek-ai/dsh-agent';
|
|
4
5
|
import type { SessionEventWindow } from '@deepseek-ai/dsh-session-query';
|
|
5
6
|
import { HistoryCatalog } from './history-catalog.ts';
|
|
6
7
|
import { ContextStore } from './store.ts';
|
|
@@ -8,6 +9,7 @@ import type { RouterReceipt } from './llm-router.ts';
|
|
|
8
9
|
import type { LinkageSnapshot } from './catalog-types.ts';
|
|
9
10
|
import { type SettingsSnapshot } from './settings-types.ts';
|
|
10
11
|
import { type LinkScope } from './linkage.ts';
|
|
12
|
+
import { Updater } from './update.ts';
|
|
11
13
|
export interface Config {
|
|
12
14
|
databasePath?: string;
|
|
13
15
|
contextsPath?: string;
|
|
@@ -54,6 +56,8 @@ declare module '@deepseek-ai/dsh-llm' {
|
|
|
54
56
|
};
|
|
55
57
|
}
|
|
56
58
|
}
|
|
59
|
+
export declare function viaModel(selection: ModelSelection): string;
|
|
60
|
+
export declare function parseVia(id: string | undefined): ModelSelection | undefined;
|
|
57
61
|
export default class TheOne extends Service {
|
|
58
62
|
private config;
|
|
59
63
|
static inject: string[];
|
|
@@ -72,6 +76,9 @@ export default class TheOne extends Service {
|
|
|
72
76
|
private readonly closing;
|
|
73
77
|
/** A model the user picked in main chat's own model selector; it answers through the Workers. */
|
|
74
78
|
private pickedModel?;
|
|
79
|
+
private adapter?;
|
|
80
|
+
/** Update checks and one-click install through DSH's plugin manager. */
|
|
81
|
+
readonly updater: Updater;
|
|
75
82
|
/** Sessions whose current step answers through TheOne; only these refuse to run tools themselves. */
|
|
76
83
|
private readonly throughTheOne;
|
|
77
84
|
constructor(ctx: Context, config: Config);
|
|
@@ -89,8 +96,15 @@ export default class TheOne extends Service {
|
|
|
89
96
|
/** Capture before Web saves the gateway itself as DSH's new default. */
|
|
90
97
|
captureDefaultModel(): void;
|
|
91
98
|
private backingModel;
|
|
92
|
-
/**
|
|
93
|
-
|
|
99
|
+
/** Every model DSH offers besides TheOne; a provider that cannot list its models in time offers none. */
|
|
100
|
+
private offeredModels;
|
|
101
|
+
/**
|
|
102
|
+
* Main chat's model menu has one TheOne entry; the background model is chosen with the button
|
|
103
|
+
* beside it. Selections of the older "TheOne · <model>" entries still resolve.
|
|
104
|
+
*/
|
|
105
|
+
gatewayModels(provider: string): Promise<LlmModelInfo[]>;
|
|
106
|
+
/** The entry has exactly the backing model's capacity, including DSH overrides. */
|
|
107
|
+
gatewayModelInfo(provider?: string, signal?: AbortSignal, model?: string): Promise<LlmResolvedModelInfo>;
|
|
94
108
|
/** This main chat's recent text turns, each attributed to the topic it was routed to. */
|
|
95
109
|
private recentMainChat;
|
|
96
110
|
/** Recover bounded routing context from DSH references after the Gateway is rebuilt. */
|