dsh-model-switch 0.4.20 → 0.4.21

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.
@@ -1,45 +1,45 @@
1
- import type { SettingsPathOpView } from '@deepseek-ai/dsh-api-remotes/client';
2
- import type { SettingsScope, SettingsScopeSnapshot } from '@deepseek-ai/dsh-client-ui-settings/client';
3
- interface RemoteError {
4
- code: string;
5
- message: string;
6
- }
7
- interface RemoteResult<T> {
8
- ok: boolean;
9
- value?: T;
10
- error?: RemoteError;
11
- }
12
- interface NamespaceView {
13
- ns: string;
14
- value: unknown;
15
- base?: unknown;
16
- user?: unknown;
17
- revision: number;
18
- }
19
- interface DescribeValue {
20
- writable: boolean;
21
- namespaces: readonly NamespaceView[];
22
- }
23
- export interface RemoteSettingsFace {
24
- describe(): Promise<RemoteResult<DescribeValue>>;
25
- mutate(ns: string, ops: readonly unknown[], expectedRevision: number | undefined): Promise<RemoteResult<NamespaceView>>;
26
- }
27
- /** Host-backed settings scope used by this plugin on authenticated remote browsers. */
28
- export declare class RemoteSettingsScope<T> implements SettingsScope<T> {
29
- private readonly api;
30
- private readonly namespace;
31
- private readonly decode;
32
- private snapshot;
33
- private readonly listeners;
34
- constructor(api: RemoteSettingsFace, namespace: string, decode: (value: unknown) => T | undefined);
35
- getSnapshot: () => SettingsScopeSnapshot<T>;
36
- subscribe: (listener: () => void) => (() => void);
37
- reload(): Promise<void>;
38
- set(field: string, value: unknown): Promise<void>;
39
- unset(field: string): Promise<void>;
40
- mutate(ops: readonly SettingsPathOpView[], expectedRevision?: number): Promise<void>;
41
- private write;
42
- private accept;
43
- private publish;
44
- }
45
- export {};
1
+ import type { SettingsPathOpView } from '@deepseek-ai/dsh-api-remotes/client';
2
+ import type { SettingsScope, SettingsScopeSnapshot } from '@deepseek-ai/dsh-client-ui-settings/client';
3
+ interface RemoteError {
4
+ code: string;
5
+ message: string;
6
+ }
7
+ interface RemoteResult<T> {
8
+ ok: boolean;
9
+ value?: T;
10
+ error?: RemoteError;
11
+ }
12
+ interface NamespaceView {
13
+ ns: string;
14
+ value: unknown;
15
+ base?: unknown;
16
+ user?: unknown;
17
+ revision: number;
18
+ }
19
+ interface DescribeValue {
20
+ writable: boolean;
21
+ namespaces: readonly NamespaceView[];
22
+ }
23
+ export interface RemoteSettingsFace {
24
+ describe(): Promise<RemoteResult<DescribeValue>>;
25
+ mutate(ns: string, ops: readonly unknown[], expectedRevision: number | undefined): Promise<RemoteResult<NamespaceView>>;
26
+ }
27
+ /** Host-backed settings scope used by this plugin on authenticated remote browsers. */
28
+ export declare class RemoteSettingsScope<T> implements SettingsScope<T> {
29
+ private readonly api;
30
+ private readonly namespace;
31
+ private readonly decode;
32
+ private snapshot;
33
+ private readonly listeners;
34
+ constructor(api: RemoteSettingsFace, namespace: string, decode: (value: unknown) => T | undefined);
35
+ getSnapshot: () => SettingsScopeSnapshot<T>;
36
+ subscribe: (listener: () => void) => (() => void);
37
+ reload(): Promise<void>;
38
+ set(field: string, value: unknown): Promise<void>;
39
+ unset(field: string): Promise<void>;
40
+ mutate(ops: readonly SettingsPathOpView[], expectedRevision?: number): Promise<void>;
41
+ private write;
42
+ private accept;
43
+ private publish;
44
+ }
45
+ export {};
@@ -21,8 +21,8 @@ export interface ModelSwitchSettingsView {
21
21
  compactOnSwitch?: boolean;
22
22
  autoReviewProvider?: string;
23
23
  autoReviewModel?: string;
24
- /** Plan-exit compaction threshold in tokens; absent = the shipped default. */
25
- planCompactThreshold?: number;
24
+ compactProvider?: string;
25
+ compactModel?: string;
26
26
  }
27
27
  export interface SubagentSettingsView {
28
28
  mode: 'follow-main' | 'fixed';
@@ -55,9 +55,15 @@ export declare const AUTO_REVIEW_SETTINGS_FIELDS: Readonly<{
55
55
  readonly provider: "autoReviewProvider";
56
56
  readonly model: "autoReviewModel";
57
57
  }>;
58
+ /** Compaction summarization route for `/compact` and automatic compaction; both unset means the official default (the conversation target). */
59
+ export declare const COMPACTION_SETTINGS_FIELDS: Readonly<{
60
+ readonly provider: "compactProvider";
61
+ readonly model: "compactModel";
62
+ }>;
58
63
  export declare function deriveSubagentSettings(settings: ModelSwitchSettingsView): SubagentSettingsView;
59
64
  export declare function deriveSearchSettings(settings: ModelSwitchSettingsView): CapabilityRouteView;
60
65
  export declare function deriveImageSettings(settings: ModelSwitchSettingsView): CapabilityRouteView;
61
66
  export declare function deriveAutoReviewSettings(settings: ModelSwitchSettingsView): CapabilityRouteView;
62
- /** Whether both reviewer fields form a complete route; an incomplete pair still follows the session model. */
63
- export declare function autoReviewRouteConfigured(route: CapabilityRouteView | undefined): boolean;
67
+ export declare function deriveCompactionSettings(settings: ModelSwitchSettingsView): CapabilityRouteView;
68
+ /** Whether both fields of a model route form a complete pair; an incomplete pair stays off. */
69
+ export declare function routePairConfigured(route: CapabilityRouteView | undefined): boolean;
@@ -0,0 +1,56 @@
1
+ import type { Context } from '@deepseek-ai/cordis';
2
+ import type { Entry, Loader } from '@deepseek-ai/cordis-plugin-loader';
3
+ import type { BasicCompactionConfig } from '@deepseek-ai/dsh-compaction-basic';
4
+ /** Cordis plugin identity; matches the cordis.patch.yml insert row id. */
5
+ export declare const name = "model-switch-compaction";
6
+ /** The loader is awaited at row activation; settings and the official row are still read structurally so stock compaction survives a disabled Model Switch row. */
7
+ export declare const inject: string[];
8
+ /** Both identifiers trimmed and non-empty; undefined means "official default". */
9
+ export interface CompactionRoute {
10
+ readonly provider: string;
11
+ readonly model: string;
12
+ }
13
+ /**
14
+ * Resolve the configurable summarization route from live settings.
15
+ * @param settings - Model Switch settings carrying the optional compaction pair.
16
+ * @returns Both identifiers trimmed and non-empty, or undefined (official default).
17
+ */
18
+ export declare function compactionRouteOf(settings: {
19
+ readonly compactProvider?: string;
20
+ readonly compactModel?: string;
21
+ } | undefined): CompactionRoute | undefined;
22
+ /**
23
+ * Merge the resolved route over the official row's own config.
24
+ * @param forwarded - config the official compaction-basic row was configured with.
25
+ * @param route - resolved summarization route; undefined keeps official behavior.
26
+ * @returns A detached config safe to hand to a fresh engine construction.
27
+ */
28
+ export declare function composeCompactionConfig(forwarded: BasicCompactionConfig, route: CompactionRoute | undefined): BasicCompactionConfig;
29
+ /**
30
+ * Locate the official compaction row in the loader tree.
31
+ * Disabled entries stay in the tree, so a name-matched disable still matches.
32
+ * @param loader - the host loader, when one is reachable.
33
+ * @returns The official entry, or undefined when this profile has no such row.
34
+ */
35
+ export declare function officialCompactionEntry(loader: Loader | undefined): Entry | undefined;
36
+ /**
37
+ * Copy the official row's stored config, ignoring non-object payloads.
38
+ * @param entry - the official compaction entry.
39
+ * @returns A plain object spread; missing or invalid configs become `{}`.
40
+ */
41
+ export declare function forwardedConfig(entry: Entry): BasicCompactionConfig;
42
+ /**
43
+ * Mount the Model Switch compaction engine for this profile.
44
+ *
45
+ * Installs a sibling row that replaces the official compaction-basic engine
46
+ * with the same package under the configurable summarization route. Host
47
+ * settings and the loader are read structurally so a disabled `model-switch`
48
+ * row leaves official compaction untouched. Reconciles run on
49
+ * `model-switch/settings-update` (emitted by the host on volatile commits and
50
+ * ordinary saves); the listener is global so instances of this row inside
51
+ * agent-preset realms still hear the host row's emission. The initial
52
+ * reconcile is awaited so `/compact` resolves the service as soon as this row
53
+ * completes.
54
+ * @param ctx - this row's context.
55
+ */
56
+ export declare function apply(ctx: Context): Promise<void>;
@@ -7,6 +7,10 @@ declare module '@deepseek-ai/cordis' {
7
7
  interface Context {
8
8
  modelSwitch: ModelSwitchRuntime;
9
9
  }
10
+ interface Events {
11
+ /** Model Switch settings changed; reread via `modelSwitch.currentSettings()`. */
12
+ 'model-switch/settings-update'(): void;
13
+ }
10
14
  }
11
15
  /** Host owner for Model Switch settings and the released Main-default adapter. */
12
16
  export declare class ModelSwitchRuntime extends Service {
@@ -23,7 +27,8 @@ export declare class ModelSwitchRuntime extends Service {
23
27
  compactOnSwitch: import("@deepseek-ai/schemastery").default<boolean, boolean, "volatile-defined">;
24
28
  autoReviewProvider: import("@deepseek-ai/schemastery").default<string, string, "volatile">;
25
29
  autoReviewModel: import("@deepseek-ai/schemastery").default<string, string, "volatile">;
26
- planCompactThreshold: import("@deepseek-ai/schemastery").default<number, number, "volatile-defined">;
30
+ compactProvider: import("@deepseek-ai/schemastery").default<string, string, "volatile">;
31
+ compactModel: import("@deepseek-ai/schemastery").default<string, string, "volatile">;
27
32
  }>>, Schemastery.ObjectT<NoInfer<{
28
33
  subagentMode: import("@deepseek-ai/schemastery").default<"follow-main" | "fixed", "follow-main" | "fixed", "volatile-defined">;
29
34
  subagentProvider: import("@deepseek-ai/schemastery").default<string, string, "volatile">;
@@ -36,7 +41,8 @@ export declare class ModelSwitchRuntime extends Service {
36
41
  compactOnSwitch: import("@deepseek-ai/schemastery").default<boolean, boolean, "volatile-defined">;
37
42
  autoReviewProvider: import("@deepseek-ai/schemastery").default<string, string, "volatile">;
38
43
  autoReviewModel: import("@deepseek-ai/schemastery").default<string, string, "volatile">;
39
- planCompactThreshold: import("@deepseek-ai/schemastery").default<number, number, "volatile-defined">;
44
+ compactProvider: import("@deepseek-ai/schemastery").default<string, string, "volatile">;
45
+ compactModel: import("@deepseek-ai/schemastery").default<string, string, "volatile">;
40
46
  }>>, "plain">;
41
47
  get capabilities(): {
42
48
  searchProviderAdapters: {
@@ -16,8 +16,10 @@ export interface ModelSwitchSettings {
16
16
  autoReviewProvider?: string;
17
17
  /** Reviewer model for the Auto preset; set together with `autoReviewProvider`. */
18
18
  autoReviewModel?: string;
19
- /** Plan-exit compaction threshold in tokens; 0 disables the mechanism. */
20
- planCompactThreshold: number;
19
+ /** Summarization provider for `/compact` and automatic compaction; both fields unset = official default (the conversation target). */
20
+ compactProvider?: string;
21
+ /** Summarization model for `/compact` and automatic compaction; set together with `compactProvider`. */
22
+ compactModel?: string;
21
23
  }
22
24
  /** Loader-owned references; every field is directly editable in the profile form. */
23
25
  export interface Config {
@@ -32,7 +34,8 @@ export interface Config {
32
34
  compactOnSwitch: Volatile<boolean>;
33
35
  autoReviewProvider: Volatile<string | undefined>;
34
36
  autoReviewModel: Volatile<string | undefined>;
35
- planCompactThreshold: Volatile<number>;
37
+ compactProvider: Volatile<string | undefined>;
38
+ compactModel: Volatile<string | undefined>;
36
39
  }
37
40
  export declare const Config: z<Schemastery.ObjectS<NoInfer<{
38
41
  subagentMode: z<"follow-main" | "fixed", "follow-main" | "fixed", "volatile-defined">;
@@ -46,7 +49,8 @@ export declare const Config: z<Schemastery.ObjectS<NoInfer<{
46
49
  compactOnSwitch: z<boolean, boolean, "volatile-defined">;
47
50
  autoReviewProvider: z<string, string, "volatile">;
48
51
  autoReviewModel: z<string, string, "volatile">;
49
- planCompactThreshold: z<number, number, "volatile-defined">;
52
+ compactProvider: z<string, string, "volatile">;
53
+ compactModel: z<string, string, "volatile">;
50
54
  }>>, Schemastery.ObjectT<NoInfer<{
51
55
  subagentMode: z<"follow-main" | "fixed", "follow-main" | "fixed", "volatile-defined">;
52
56
  subagentProvider: z<string, string, "volatile">;
@@ -59,6 +63,7 @@ export declare const Config: z<Schemastery.ObjectS<NoInfer<{
59
63
  compactOnSwitch: z<boolean, boolean, "volatile-defined">;
60
64
  autoReviewProvider: z<string, string, "volatile">;
61
65
  autoReviewModel: z<string, string, "volatile">;
62
- planCompactThreshold: z<number, number, "volatile-defined">;
66
+ compactProvider: z<string, string, "volatile">;
67
+ compactModel: z<string, string, "volatile">;
63
68
  }>>, "plain">;
64
69
  export declare function readConfig(config: Config): ModelSwitchSettings;
@@ -61,8 +61,33 @@ export type GoalHandoff = {
61
61
  readonly code?: string;
62
62
  readonly message: string;
63
63
  };
64
+ /** Identity of the plan document under review, for its durable address. */
65
+ export interface PlanDocumentRef {
66
+ /** Logged tool invocation that owns the plan; absent while only the review is pending. */
67
+ readonly callId?: string;
68
+ /** Browser-unique pending request identity (the review card's key). */
69
+ readonly requestKey: string;
70
+ }
71
+ /**
72
+ * Address the plan document exactly as the official opener does.
73
+ *
74
+ * A logged plan (`callId` present) resolves from `dsh-resource://plan/...`
75
+ * for as long as the session log holds the call; before that the pending
76
+ * review's own `dsh-resource://plan-review/...` address is the one that
77
+ * opens its preview.
78
+ *
79
+ * @param sessionId - the session that owns the review.
80
+ * @param ref - logged call identity plus the pending request key.
81
+ * @returns The plan resource address.
82
+ */
83
+ export declare function planDocumentAddress(sessionId: string, ref: PlanDocumentRef): string;
64
84
  /**
65
- * Make the plan text this session's armed goal, replacing any unfinished goal.
85
+ * Make this plan the session's armed goal, replacing any unfinished goal.
86
+ *
87
+ * The objective is a short instruction carrying the plan document's address,
88
+ * not the plan's raw markdown: goal objectives are injected into every round,
89
+ * and a full plan would be truncated by length limits mid-sentence. The round
90
+ * driver reads the plan from the address instead.
66
91
  *
67
92
  * Ordering mirrors the card's own commit-then-answer rule: a refusal here keeps
68
93
  * the Plan pending instead of approving work that no goal tracks. The replace
@@ -71,7 +96,8 @@ export type GoalHandoff = {
71
96
  *
72
97
  * @param remote - the released goal remote, absent when no goal package is mounted.
73
98
  * @param sessionId - the session that owns both the review and the goal.
74
- * @param plan - the plan markdown under review.
99
+ * @param plan - the plan markdown under review (validated non-empty).
100
+ * @param ref - the plan document identity used for its address.
75
101
  * @returns Whether the goal now tracks this plan, or why it does not.
76
102
  */
77
- export declare function setPlanAsGoal(remote: GoalRemote | undefined, sessionId: string, plan: string): Promise<GoalHandoff>;
103
+ export declare function setPlanAsGoal(remote: GoalRemote | undefined, sessionId: string, plan: string, ref: PlanDocumentRef): Promise<GoalHandoff>;