dsh-model-switch 0.4.35 → 0.4.37
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/CHANGELOG.md +21 -0
- package/lib/auto-review-CMHNfRuV.js +1015 -0
- package/lib/auto-review-CvmQaRVf.js +1022 -0
- package/lib/auto-review-oan7iXY7.js +987 -0
- package/lib/auto-review.js +1 -1
- package/lib/client.js +103 -4
- package/lib/index.js +1 -1
- package/lib/types/auto-sessions-state.d.ts +45 -0
- package/lib/types/client/locales.d.ts +2 -0
- package/lib/types/session-route.d.ts +22 -0
- package/package.json +1 -1
package/lib/auto-review.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as bindAutoReviewSessionCorrelation, c as installToolCallSafetyNet, d as resolveSessionAutoReviewRoute, f as reviewLlm, i as autoReviewStatus, l as isReviewerInfrastructureFailure, n as autoReviewGate, o as defensivePermissionPresets, p as reviewScope, r as autoReviewRouteOf, s as inject, t as apply, u as name } from "./auto-review-
|
|
1
|
+
import { a as bindAutoReviewSessionCorrelation, c as installToolCallSafetyNet, d as resolveSessionAutoReviewRoute, f as reviewLlm, i as autoReviewStatus, l as isReviewerInfrastructureFailure, n as autoReviewGate, o as defensivePermissionPresets, p as reviewScope, r as autoReviewRouteOf, s as inject, t as apply, u as name } from "./auto-review-CvmQaRVf.js";
|
|
2
2
|
export { apply, autoReviewGate, autoReviewRouteOf, autoReviewStatus, bindAutoReviewSessionCorrelation, defensivePermissionPresets, inject, installToolCallSafetyNet, isReviewerInfrastructureFailure, name, resolveSessionAutoReviewRoute, reviewLlm, reviewScope };
|
package/lib/client.js
CHANGED
|
@@ -268,7 +268,7 @@ window.__ModuleLoader__.load({
|
|
|
268
268
|
});
|
|
269
269
|
}
|
|
270
270
|
/** A non-blank string. Blank values behave exactly like an absent field. */
|
|
271
|
-
function present(value) {
|
|
271
|
+
function present$1(value) {
|
|
272
272
|
return typeof value === "string" && value.trim() !== "";
|
|
273
273
|
}
|
|
274
274
|
/** Normalize one raw entry to its owning provider and route view; undefined for non-object junk. */
|
|
@@ -278,10 +278,10 @@ window.__ModuleLoader__.load({
|
|
|
278
278
|
const group = {};
|
|
279
279
|
for (const field of ROUTE_FIELDS) {
|
|
280
280
|
const item = source[field];
|
|
281
|
-
if (present(item)) group[field] = item;
|
|
281
|
+
if (present$1(item)) group[field] = item;
|
|
282
282
|
}
|
|
283
283
|
return {
|
|
284
|
-
provider: present(source.provider) ? source.provider : "",
|
|
284
|
+
provider: present$1(source.provider) ? source.provider : "",
|
|
285
285
|
group
|
|
286
286
|
};
|
|
287
287
|
}
|
|
@@ -349,6 +349,72 @@ window.__ModuleLoader__.load({
|
|
|
349
349
|
return Object.entries(groups).map(([key, value]) => entryOf(key, value));
|
|
350
350
|
}
|
|
351
351
|
//#endregion
|
|
352
|
+
//#region src/session-route.ts
|
|
353
|
+
/** Flat deployment-default fields per capability, in group-storage field names. */
|
|
354
|
+
const CAPABILITY_FIELDS = Object.freeze({
|
|
355
|
+
compaction: {
|
|
356
|
+
provider: "compactProvider",
|
|
357
|
+
model: "compactModel"
|
|
358
|
+
},
|
|
359
|
+
autoReview: {
|
|
360
|
+
provider: "autoReviewProvider",
|
|
361
|
+
model: "autoReviewModel"
|
|
362
|
+
},
|
|
363
|
+
title: {
|
|
364
|
+
provider: "titleProvider",
|
|
365
|
+
model: "titleModel"
|
|
366
|
+
},
|
|
367
|
+
subagent: {
|
|
368
|
+
provider: "subagentProvider",
|
|
369
|
+
model: "subagentModel"
|
|
370
|
+
}
|
|
371
|
+
});
|
|
372
|
+
/** A non-blank string; blank values behave exactly like an absent field. */
|
|
373
|
+
function present(value) {
|
|
374
|
+
return typeof value === "string" && value.trim() !== "";
|
|
375
|
+
}
|
|
376
|
+
/** Read one capability's pair from a flat route record; undefined unless both halves are present. */
|
|
377
|
+
function pairOf(source, fields) {
|
|
378
|
+
if (source === void 0) return void 0;
|
|
379
|
+
const record = source;
|
|
380
|
+
const provider = record[fields.provider];
|
|
381
|
+
const model = record[fields.model];
|
|
382
|
+
if (!present(provider) || !present(model)) return void 0;
|
|
383
|
+
return {
|
|
384
|
+
provider,
|
|
385
|
+
model
|
|
386
|
+
};
|
|
387
|
+
}
|
|
388
|
+
/**
|
|
389
|
+
* Every provider group that overrides one capability, provider-sorted.
|
|
390
|
+
*
|
|
391
|
+
* Reads the stored table only and never attributes a session, so a caller can
|
|
392
|
+
* describe the layering ("this is the default; these groups override it")
|
|
393
|
+
* without claiming which layer a given session receives.
|
|
394
|
+
* @param groups - the normalized provider → group map.
|
|
395
|
+
* @param capability - capability whose group pins are collected.
|
|
396
|
+
* @returns The complete pins, ordered by provider id; empty when no group pins it.
|
|
397
|
+
*/
|
|
398
|
+
function capabilityGroupPins(groups, capability) {
|
|
399
|
+
const pins = [];
|
|
400
|
+
if (groups === void 0) return pins;
|
|
401
|
+
for (const provider of Object.keys(groups).sort()) {
|
|
402
|
+
const group = groups[provider];
|
|
403
|
+
const route = pairOf(group, CAPABILITY_FIELDS[capability]);
|
|
404
|
+
if (route === void 0) continue;
|
|
405
|
+
const effort = capability === "subagent" ? group?.subagentReasoningEffort : void 0;
|
|
406
|
+
pins.push(present(effort) ? {
|
|
407
|
+
provider,
|
|
408
|
+
route,
|
|
409
|
+
reasoningEffort: effort
|
|
410
|
+
} : {
|
|
411
|
+
provider,
|
|
412
|
+
route
|
|
413
|
+
});
|
|
414
|
+
}
|
|
415
|
+
return pins;
|
|
416
|
+
}
|
|
417
|
+
//#endregion
|
|
352
418
|
//#region src/client/plugin-rpc.ts
|
|
353
419
|
function callPluginRpc(rpc, method, endpoint, payload, signal) {
|
|
354
420
|
return rpc.call("/api", method, {
|
|
@@ -657,6 +723,21 @@ window.__ModuleLoader__.load({
|
|
|
657
723
|
function compact(...values) {
|
|
658
724
|
return values.filter((value) => value !== void 0 && value !== "").join(" · ");
|
|
659
725
|
}
|
|
726
|
+
/**
|
|
727
|
+
* The layering line under a capability card.
|
|
728
|
+
*
|
|
729
|
+
* The card's own summary is the deployment-wide default ("默认(无组时)"); a
|
|
730
|
+
* provider group overrides it for that provider's sessions, so name the pins
|
|
731
|
+
* instead of letting the default look like the effective route.
|
|
732
|
+
* @param t - settings locale lookup.
|
|
733
|
+
* @param pins - the capability's provider-group pins.
|
|
734
|
+
* @returns The line, or undefined when no group pins this capability.
|
|
735
|
+
*/
|
|
736
|
+
function groupNote(t, pins) {
|
|
737
|
+
if (pins.length === 0) return void 0;
|
|
738
|
+
const listed = pins.slice(0, 3).map((pin) => `${pin.provider} → ${pin.route.provider} · ${pin.route.model}${pin.reasoningEffort === void 0 ? "" : ` · ${pin.reasoningEffort}`}`).join(";");
|
|
739
|
+
return pins.length > 3 ? t("groupOverridesMore").replace("{listed}", listed).replace("{count}", String(pins.length)) : t("groupOverridesLabel").replace("{pins}", listed);
|
|
740
|
+
}
|
|
660
741
|
/** A complete pinned pair; either half blank leaves the capability at its default. */
|
|
661
742
|
function draftPair(provider, model) {
|
|
662
743
|
return provider !== void 0 && provider.trim() !== "" && model !== void 0 && model.trim() !== "" ? {
|
|
@@ -811,7 +892,7 @@ window.__ModuleLoader__.load({
|
|
|
811
892
|
});
|
|
812
893
|
return null;
|
|
813
894
|
}
|
|
814
|
-
function RouteCard({ title, summary, hint, icon, open, onToggle, disabled = false, badge, badgeWarn = false, trailing, expandable = true, children }) {
|
|
895
|
+
function RouteCard({ title, summary, hint, note, icon, open, onToggle, disabled = false, badge, badgeWarn = false, trailing, expandable = true, children }) {
|
|
815
896
|
const header = /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
|
|
816
897
|
type: "button",
|
|
817
898
|
className: ModelSwitchSettings_module_css_default.routeHeader,
|
|
@@ -837,6 +918,10 @@ window.__ModuleLoader__.load({
|
|
|
837
918
|
className: ModelSwitchSettings_module_css_default.routeSummary,
|
|
838
919
|
children: summary
|
|
839
920
|
}),
|
|
921
|
+
note === void 0 ? null : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
922
|
+
className: ModelSwitchSettings_module_css_default.hint,
|
|
923
|
+
children: note
|
|
924
|
+
}),
|
|
840
925
|
hint === void 0 ? null : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
841
926
|
className: ModelSwitchSettings_module_css_default.hint,
|
|
842
927
|
children: hint
|
|
@@ -1068,6 +1153,12 @@ window.__ModuleLoader__.load({
|
|
|
1068
1153
|
};
|
|
1069
1154
|
}, [loadSearchCapabilities]);
|
|
1070
1155
|
const providerGroups = normalizeProviderGroups(switchSettings.value?.providerGroups);
|
|
1156
|
+
const groupPins = {
|
|
1157
|
+
autoReview: capabilityGroupPins(providerGroups, "autoReview"),
|
|
1158
|
+
compaction: capabilityGroupPins(providerGroups, "compaction"),
|
|
1159
|
+
title: capabilityGroupPins(providerGroups, "title"),
|
|
1160
|
+
subagent: capabilityGroupPins(providerGroups, "subagent")
|
|
1161
|
+
};
|
|
1071
1162
|
/**
|
|
1072
1163
|
* Seed an unsaved group from the live routes.
|
|
1073
1164
|
*
|
|
@@ -1556,6 +1647,7 @@ window.__ModuleLoader__.load({
|
|
|
1556
1647
|
title: props.t("subagent"),
|
|
1557
1648
|
summary: subagentSummary,
|
|
1558
1649
|
hint: props.t("subagentHelp"),
|
|
1650
|
+
note: groupNote(props.t, groupPins.subagent),
|
|
1559
1651
|
icon: "subagent",
|
|
1560
1652
|
open: open === "subagent" && subagentOn,
|
|
1561
1653
|
onToggle: () => {
|
|
@@ -1785,6 +1877,7 @@ window.__ModuleLoader__.load({
|
|
|
1785
1877
|
title: props.t("autoReview"),
|
|
1786
1878
|
summary: autoReviewDraft === void 0 ? props.t("loading") : autoReviewOn ? routeName(groups, autoReviewDraft) : props.t("autoReviewFollow"),
|
|
1787
1879
|
hint: props.t("autoReviewHelp"),
|
|
1880
|
+
note: groupNote(props.t, groupPins.autoReview),
|
|
1788
1881
|
icon: "autoReview",
|
|
1789
1882
|
open: open === "autoReview" && autoReviewOn,
|
|
1790
1883
|
onToggle: () => {
|
|
@@ -1853,6 +1946,7 @@ window.__ModuleLoader__.load({
|
|
|
1853
1946
|
title: props.t("compaction"),
|
|
1854
1947
|
summary: compactionDraft === void 0 ? props.t("loading") : compactionOn ? routeName(groups, compactionDraft) : props.t("compactionFollow"),
|
|
1855
1948
|
hint: props.t("compactionHelp"),
|
|
1949
|
+
note: groupNote(props.t, groupPins.compaction),
|
|
1856
1950
|
icon: "compaction",
|
|
1857
1951
|
open: open === "compaction" && compactionOn,
|
|
1858
1952
|
onToggle: () => {
|
|
@@ -1917,6 +2011,7 @@ window.__ModuleLoader__.load({
|
|
|
1917
2011
|
title: props.t("sessionTitle"),
|
|
1918
2012
|
summary: titleDraft === void 0 ? props.t("loading") : titleOn ? routeName(groups, titleDraft) : props.t("titleFollow"),
|
|
1919
2013
|
hint: props.t("titleHelp"),
|
|
2014
|
+
note: groupNote(props.t, groupPins.title),
|
|
1920
2015
|
icon: "sessionTitle",
|
|
1921
2016
|
open: open === "sessionTitle" && titleOn,
|
|
1922
2017
|
onToggle: () => {
|
|
@@ -2307,6 +2402,8 @@ window.__ModuleLoader__.load({
|
|
|
2307
2402
|
providerGroupsBodyHelp: "每个供应商保存一组压缩、自动审查、会话命名与子代理路由。会话自身的供应商与该组一致时,这四项能力按组实时解析,未固定项回落到上方卡片里的全局设置。切换某个会话的模型不会写入任何全局设置,因此不同供应商的多个会话并行时互不影响,会话中切换供应商后下一次调用也会立即跟随新供应商的配置组。",
|
|
2308
2403
|
providerGroupPick: "选择供应商以编辑其配置组。",
|
|
2309
2404
|
providerGroupDelete: "删除该组",
|
|
2405
|
+
groupOverridesLabel: "组覆盖:{pins};无组时用上方默认值",
|
|
2406
|
+
groupOverridesMore: "组覆盖:{listed} 等 {count} 个组;无组时用上方默认值",
|
|
2310
2407
|
saveTimeout: "保存超时,请重试",
|
|
2311
2408
|
saveRejected: "保存被拒绝,请重试",
|
|
2312
2409
|
"reason.central-subagent-routing": "Alpha.4 没有全局子代理启动路由接口。",
|
|
@@ -2367,6 +2464,8 @@ window.__ModuleLoader__.load({
|
|
|
2367
2464
|
providerGroupsBodyHelp: "Each provider stores one route group for compaction, auto review, session naming, and subagents. A session running on that provider resolves all four capabilities from the group and falls back to the cards above when a row is off. Switching a session’s model writes no global setting, so parallel sessions on different providers never affect each other, and mid-session provider switches take effect on the very next call.",
|
|
2368
2465
|
providerGroupPick: "Pick a provider to edit its group.",
|
|
2369
2466
|
providerGroupDelete: "Delete group",
|
|
2467
|
+
groupOverridesLabel: "Group overrides: {pins}; without a group the default above applies",
|
|
2468
|
+
groupOverridesMore: "Group overrides: {listed} and {count} groups; without a group the default above applies",
|
|
2370
2469
|
saveTimeout: "The save timed out; try again",
|
|
2371
2470
|
saveRejected: "The save was rejected; try again",
|
|
2372
2471
|
"reason.central-subagent-routing": "Alpha.4 exposes no global Subagent start-routing seam.",
|
package/lib/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { o as normalizeProviderGroups } from "./session-route-D1zoZgf3.js";
|
|
2
|
-
import { i as autoReviewStatus } from "./auto-review-
|
|
2
|
+
import { i as autoReviewStatus } from "./auto-review-CvmQaRVf.js";
|
|
3
3
|
import { ModelSwitchAdapterRegistry } from "./adapter-registry.js";
|
|
4
4
|
import { createRequire } from "node:module";
|
|
5
5
|
import z from "@deepseek-ai/schemastery";
|
|
@@ -15,8 +15,35 @@
|
|
|
15
15
|
* and must not resurrect a preset the user may have chosen since.
|
|
16
16
|
*/
|
|
17
17
|
export declare const AUTO_SESSION_STATE_MAX_AGE_MS: number;
|
|
18
|
+
/** A decoded snapshot: the ids recorded at `savedAt`. */
|
|
19
|
+
export interface AutoSessionState {
|
|
20
|
+
savedAt: number;
|
|
21
|
+
ids: string[];
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* What one replay can do right now.
|
|
25
|
+
*
|
|
26
|
+
* `restore` holds the recorded ids that exist in the live session list and can
|
|
27
|
+
* be moved back onto Auto; `remaining` holds the ones no live session claims
|
|
28
|
+
* yet. The remaining ids stay in the file (with their original `savedAt`) so a
|
|
29
|
+
* later claim — or the next start — can still replay them, instead of the
|
|
30
|
+
* replay consuming the whole snapshot and dropping what it could not restore.
|
|
31
|
+
*/
|
|
32
|
+
export interface AutoSnapshotReplay {
|
|
33
|
+
restore: string[];
|
|
34
|
+
remaining: string[];
|
|
35
|
+
}
|
|
18
36
|
/** Serialize the session ids that were on Auto at `savedAt`. */
|
|
19
37
|
export declare function encodeAutoSessionState(ids: readonly string[], savedAt: number): string;
|
|
38
|
+
/**
|
|
39
|
+
* Decode a snapshot written by {@link encodeAutoSessionState}, keeping the
|
|
40
|
+
* timestamp so a partial replay can write the rest back with the original
|
|
41
|
+
* expiry instead of restarting the replay window.
|
|
42
|
+
*
|
|
43
|
+
* Every malformed or stale shape degrades to `undefined`: an unreadable state
|
|
44
|
+
* file must never stop the Auto registration from being released or re-claimed.
|
|
45
|
+
*/
|
|
46
|
+
export declare function decodeAutoSessionStatePayload(raw: string | undefined, now: number, maxAgeMs?: number): AutoSessionState | undefined;
|
|
20
47
|
/**
|
|
21
48
|
* Decode a snapshot written by {@link encodeAutoSessionState}.
|
|
22
49
|
*
|
|
@@ -24,3 +51,21 @@ export declare function encodeAutoSessionState(ids: readonly string[], savedAt:
|
|
|
24
51
|
* must never stop the Auto registration from being released or re-claimed.
|
|
25
52
|
*/
|
|
26
53
|
export declare function decodeAutoSessionState(raw: string | undefined, now: number, maxAgeMs?: number): string[];
|
|
54
|
+
/**
|
|
55
|
+
* Union of two id lists, order-preserving and de-duplicated.
|
|
56
|
+
*
|
|
57
|
+
* A release-time snapshot merges what the live read sees with what the
|
|
58
|
+
* continuous record saw earlier, because the live read can run after the
|
|
59
|
+
* official teardown already moved the sessions off Auto — or fail outright.
|
|
60
|
+
*/
|
|
61
|
+
export declare function mergeAutoSessionIds(primary: readonly string[], secondary: readonly string[]): string[];
|
|
62
|
+
/**
|
|
63
|
+
* Split a recorded id list into what one replay can restore now and what has
|
|
64
|
+
* to stay recorded.
|
|
65
|
+
*
|
|
66
|
+
* A recorded id counts as restorable as soon as a live session carries it; ids
|
|
67
|
+
* without a live session (not loaded yet, or already gone) remain in the file.
|
|
68
|
+
*/
|
|
69
|
+
export declare function planAutoSnapshotReplay(ids: readonly string[], live: readonly {
|
|
70
|
+
id: string;
|
|
71
|
+
}[]): AutoSnapshotReplay;
|
|
@@ -49,6 +49,8 @@ export declare const zh: {
|
|
|
49
49
|
readonly providerGroupsBodyHelp: "每个供应商保存一组压缩、自动审查、会话命名与子代理路由。会话自身的供应商与该组一致时,这四项能力按组实时解析,未固定项回落到上方卡片里的全局设置。切换某个会话的模型不会写入任何全局设置,因此不同供应商的多个会话并行时互不影响,会话中切换供应商后下一次调用也会立即跟随新供应商的配置组。";
|
|
50
50
|
readonly providerGroupPick: "选择供应商以编辑其配置组。";
|
|
51
51
|
readonly providerGroupDelete: "删除该组";
|
|
52
|
+
readonly groupOverridesLabel: "组覆盖:{pins};无组时用上方默认值";
|
|
53
|
+
readonly groupOverridesMore: "组覆盖:{listed} 等 {count} 个组;无组时用上方默认值";
|
|
52
54
|
readonly saveTimeout: "保存超时,请重试";
|
|
53
55
|
readonly saveRejected: "保存被拒绝,请重试";
|
|
54
56
|
readonly 'reason.central-subagent-routing': "Alpha.4 没有全局子代理启动路由接口。";
|
|
@@ -77,6 +77,28 @@ export declare function subagentRouteOf(settings: RouteBearingSettings | undefin
|
|
|
77
77
|
* @returns The complete group pair, or undefined when the group pins nothing here.
|
|
78
78
|
*/
|
|
79
79
|
export declare function groupRoute(settings: RouteBearingSettings | undefined, provider: string | undefined, capability: CapabilityId): CapabilityRoute | undefined;
|
|
80
|
+
/**
|
|
81
|
+
* One provider group's pin for one capability, as the settings page shows it.
|
|
82
|
+
*/
|
|
83
|
+
export interface CapabilityGroupPin {
|
|
84
|
+
/** The provider whose sessions this group applies to. */
|
|
85
|
+
readonly provider: string;
|
|
86
|
+
/** The pinned route. */
|
|
87
|
+
readonly route: CapabilityRoute;
|
|
88
|
+
/** A subagent spawn's effort; only meaningful for `subagent`. */
|
|
89
|
+
readonly reasoningEffort?: string;
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Every provider group that overrides one capability, provider-sorted.
|
|
93
|
+
*
|
|
94
|
+
* Reads the stored table only and never attributes a session, so a caller can
|
|
95
|
+
* describe the layering ("this is the default; these groups override it")
|
|
96
|
+
* without claiming which layer a given session receives.
|
|
97
|
+
* @param groups - the normalized provider → group map.
|
|
98
|
+
* @param capability - capability whose group pins are collected.
|
|
99
|
+
* @returns The complete pins, ordered by provider id; empty when no group pins it.
|
|
100
|
+
*/
|
|
101
|
+
export declare function capabilityGroupPins(groups: ProviderGroups | undefined, capability: CapabilityId): readonly CapabilityGroupPin[];
|
|
80
102
|
/**
|
|
81
103
|
* The route one capability should use for one session.
|
|
82
104
|
*
|