@aiwayds/dsh-tui-pi 1.3.1 → 2.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,122 @@
1
+ /**
2
+ * /model-sync (singular) — discover models for CUSTOM provider routes and
3
+ * merge them back into the llm-pi-ai settings section.
4
+ *
5
+ * A custom route is a hand-declared `llm-pi-ai.providers.<id>` profile that
6
+ * carries a `baseURL` and is NOT one of the built-in catalog routes
7
+ * (provider-catalog.ts): discovery against a catalog route would short-circuit
8
+ * back to the installed pi-ai catalog. This command interrogates
9
+ * each route's `GET ${baseURL}/models` through the official seam
10
+ * (`LlmRuntime.discoverModels`, registered for the `llm-pi-ai` namespace by
11
+ * dsh-llm-pi-ai with catalog short-circuit + stored-credential resolution),
12
+ * then merges the answer into the profile's `models` array.
13
+ *
14
+ * The merge is additive-only: existing entries are preserved verbatim (local
15
+ * overrides such as reasoningEfforts survive), discovered ids already present
16
+ * are skipped, new ids are appended with sanitized metadata. The write goes
17
+ * through `settings.mutate` at the revision read at execution time, with one
18
+ * retry after SettingsConflictError (the persistDefaultModel pattern in
19
+ * session.ts). Pure logic lives here as exported functions; src/index.ts only
20
+ * wires the command.
21
+ *
22
+ * @module dsh-tui-pi/model-sync
23
+ */
24
+ import type { SettingsProvider } from '@deepseek-ai/dsh-settings';
25
+ import type { LlmRuntime } from '@deepseek-ai/dsh-llm';
26
+ /**
27
+ * The services /model-sync needs, narrowed to the exact surface it touches so
28
+ * tests can supply fakes without a live tree.
29
+ */
30
+ export interface ModelSyncDeps {
31
+ /** The settings provider (describe for revisions, mutate for the write). */
32
+ settings: Pick<SettingsProvider, 'describe' | 'mutate'>;
33
+ /** The LLM runtime whose discoverModels serves the `llm-pi-ai` namespace. */
34
+ llm: Pick<LlmRuntime, 'discoverModels'>;
35
+ }
36
+ /** One models entry as stored in a profile — passed through untouched. */
37
+ type StoredModel = Record<string, unknown>;
38
+ /**
39
+ * A custom route selected for sync: the dict key plus the endpoint facts
40
+ * discovery needs. `api` is optional — discovery defaults the protocol.
41
+ */
42
+ export interface CustomProviderRoute {
43
+ id: string;
44
+ baseURL: string;
45
+ api?: string;
46
+ }
47
+ /**
48
+ * A sanitized discovered model — the writable shape of one endpoint row:
49
+ * always an id; name/capacities carried only when present and valid.
50
+ */
51
+ export interface SanitizedModel {
52
+ id: string;
53
+ name?: string;
54
+ contextWindow?: number;
55
+ maxTokens?: number;
56
+ }
57
+ /** Outcome of merging one route's discovery into its stored models. */
58
+ export interface ModelSyncMergeResult {
59
+ /**
60
+ * The merged models array to store: existing entries first in their stored
61
+ * order, newly discovered ids appended at the end in discovery order.
62
+ */
63
+ models: StoredModel[];
64
+ /** Discovered rows appended as new entries. */
65
+ added: number;
66
+ /** Existing entries preserved verbatim. */
67
+ kept: number;
68
+ /**
69
+ * Discovered rows dropped entirely: unusable id, or an id already covered
70
+ * by an existing entry (local state wins) or by an earlier row of this batch.
71
+ */
72
+ skipped: number;
73
+ }
74
+ /**
75
+ * Select the custom (hand-declared) routes worth syncing from a providers
76
+ * dict: profiles carrying a non-empty `baseURL` whose key is not a built-in
77
+ * catalog route — a catalog key would short-circuit discovery back to the
78
+ * installed catalog. Sorted by route key so the
79
+ * report order is stable regardless of document order.
80
+ */
81
+ export declare function selectCustomProviders(providers: Record<string, unknown> | undefined): CustomProviderRoute[];
82
+ /**
83
+ * Clean one discovered row into a writable models entry. The id is mandatory
84
+ * (blank/absent → undefined); name must be a non-blank string; capacities
85
+ * must be integers ≥ 1 — the llm-pi-ai schema rejects anything else at write
86
+ * time (`contextWindow >= 1`, integer step), and a field that fails stays
87
+ * behind rather than sinking the whole row (verified against the shipped
88
+ * schema: absent name/contextWindow/maxTokens validate fine).
89
+ */
90
+ export declare function sanitizeDiscoveredModel(raw: unknown): SanitizedModel | undefined;
91
+ /**
92
+ * Merge one route's discovery into its stored models — additive-only:
93
+ *
94
+ * - existing entries are the base and are preserved VERBATIM (local overrides
95
+ * like reasoningEfforts/input/compat survive; nothing is overwritten or
96
+ * deleted);
97
+ * - discovered rows join by id: an id already present (or repeated within the
98
+ * batch) counts as skipped, local state wins;
99
+ * - new ids are appended with `sanitizeDiscoveredModel`'s cleaned fields;
100
+ * - the stored order is never touched: existing entries keep their positions
101
+ * (id-less rows included) and new ids join at the end in discovery order.
102
+ */
103
+ export declare function mergeModels(existing: ReadonlyArray<object>, discovered: ReadonlyArray<unknown>): ModelSyncMergeResult;
104
+ /**
105
+ * Run one /model-sync round: select the target routes (the rawInput-named one,
106
+ * or every custom route), discover each endpoint's models, merge, and write
107
+ * back. One route's failure never aborts the rest — its line reports the
108
+ * reason instead. Agentless by design: nothing here touches a session.
109
+ *
110
+ * @returns the command result — per-provider `<id>: added N · kept M ·
111
+ * skipped K` lines on success, `<id>: <reason>` for failed routes; `kind:
112
+ * 'error'` only for preconditions (missing namespace, unknown/non-custom
113
+ * named route) or when EVERY route failed.
114
+ */
115
+ export declare function runModelSync(deps: ModelSyncDeps, options?: {
116
+ rawInput?: string;
117
+ signal?: AbortSignal;
118
+ }): Promise<{
119
+ kind: 'success' | 'error';
120
+ text: string;
121
+ }>;
122
+ export {};
@@ -0,0 +1,256 @@
1
+ /**
2
+ * /model-sync (singular) — discover models for CUSTOM provider routes and
3
+ * merge them back into the llm-pi-ai settings section.
4
+ *
5
+ * A custom route is a hand-declared `llm-pi-ai.providers.<id>` profile that
6
+ * carries a `baseURL` and is NOT one of the built-in catalog routes
7
+ * (provider-catalog.ts): discovery against a catalog route would short-circuit
8
+ * back to the installed pi-ai catalog. This command interrogates
9
+ * each route's `GET ${baseURL}/models` through the official seam
10
+ * (`LlmRuntime.discoverModels`, registered for the `llm-pi-ai` namespace by
11
+ * dsh-llm-pi-ai with catalog short-circuit + stored-credential resolution),
12
+ * then merges the answer into the profile's `models` array.
13
+ *
14
+ * The merge is additive-only: existing entries are preserved verbatim (local
15
+ * overrides such as reasoningEfforts survive), discovered ids already present
16
+ * are skipped, new ids are appended with sanitized metadata. The write goes
17
+ * through `settings.mutate` at the revision read at execution time, with one
18
+ * retry after SettingsConflictError (the persistDefaultModel pattern in
19
+ * session.ts). Pure logic lives here as exported functions; src/index.ts only
20
+ * wires the command.
21
+ *
22
+ * @module dsh-tui-pi/model-sync
23
+ */
24
+ import { settingsNamespace, SettingsConflictError } from '@deepseek-ai/dsh-settings';
25
+ import { catalogEntry } from "./provider-catalog.js";
26
+ /** The settings namespace dsh-llm-pi-ai owns its provider routes under. */
27
+ const NS_LLM_PI_AI = settingsNamespace('llm-pi-ai');
28
+ /**
29
+ * Read the providers dict out of an llm-pi-ai descriptor value. Tolerant of
30
+ * every malformed shape — a section that is not an object yields no routes.
31
+ */
32
+ function readProviders(value) {
33
+ if (typeof value !== 'object' || value === null)
34
+ return {};
35
+ const providers = value.providers;
36
+ if (typeof providers !== 'object' || providers === null)
37
+ return {};
38
+ return providers;
39
+ }
40
+ function readProfile(raw) {
41
+ const source = typeof raw === 'object' && raw !== null ? raw : {};
42
+ const baseURL = typeof source.baseURL === 'string' && source.baseURL !== '' ? source.baseURL : undefined;
43
+ const api = typeof source.api === 'string' && source.api !== '' ? source.api : undefined;
44
+ const rawModels = Array.isArray(source.models) ? source.models : [];
45
+ // Only well-formed entries are merged against; a malformed stored row is
46
+ // left alone rather than deleted (additive-only merge).
47
+ const models = rawModels.filter((entry) => typeof entry === 'object' && entry !== null);
48
+ return { ...(baseURL !== undefined ? { baseURL } : {}), ...(api !== undefined ? { api } : {}), models };
49
+ }
50
+ /** The stored entry's id, when it is a non-empty string. */
51
+ function storedModelId(entry) {
52
+ const id = entry.id;
53
+ return typeof id === 'string' && id !== '' ? id : undefined;
54
+ }
55
+ /**
56
+ * Select the custom (hand-declared) routes worth syncing from a providers
57
+ * dict: profiles carrying a non-empty `baseURL` whose key is not a built-in
58
+ * catalog route — a catalog key would short-circuit discovery back to the
59
+ * installed catalog. Sorted by route key so the
60
+ * report order is stable regardless of document order.
61
+ */
62
+ export function selectCustomProviders(providers) {
63
+ const selected = [];
64
+ for (const [id, raw] of Object.entries(providers ?? {})) {
65
+ if (catalogEntry(id) !== undefined)
66
+ continue;
67
+ const profile = readProfile(raw);
68
+ if (profile.baseURL === undefined)
69
+ continue;
70
+ selected.push({
71
+ id,
72
+ baseURL: profile.baseURL,
73
+ ...(profile.api !== undefined ? { api: profile.api } : {}),
74
+ });
75
+ }
76
+ selected.sort((a, b) => (a.id < b.id ? -1 : a.id > b.id ? 1 : 0));
77
+ return selected;
78
+ }
79
+ /**
80
+ * Clean one discovered row into a writable models entry. The id is mandatory
81
+ * (blank/absent → undefined); name must be a non-blank string; capacities
82
+ * must be integers ≥ 1 — the llm-pi-ai schema rejects anything else at write
83
+ * time (`contextWindow >= 1`, integer step), and a field that fails stays
84
+ * behind rather than sinking the whole row (verified against the shipped
85
+ * schema: absent name/contextWindow/maxTokens validate fine).
86
+ */
87
+ export function sanitizeDiscoveredModel(raw) {
88
+ if (typeof raw !== 'object' || raw === null)
89
+ return undefined;
90
+ const row = raw;
91
+ if (typeof row.id !== 'string')
92
+ return undefined;
93
+ const id = row.id.trim();
94
+ if (id === '')
95
+ return undefined;
96
+ const name = typeof row.name === 'string' && row.name.trim() !== '' ? row.name.trim() : undefined;
97
+ const capacity = (value) => typeof value === 'number' && Number.isInteger(value) && value >= 1 ? value : undefined;
98
+ const contextWindow = capacity(row.contextWindow);
99
+ const maxTokens = capacity(row.maxTokens);
100
+ return {
101
+ id,
102
+ ...(name !== undefined ? { name } : {}),
103
+ ...(contextWindow !== undefined ? { contextWindow } : {}),
104
+ ...(maxTokens !== undefined ? { maxTokens } : {}),
105
+ };
106
+ }
107
+ /**
108
+ * Merge one route's discovery into its stored models — additive-only:
109
+ *
110
+ * - existing entries are the base and are preserved VERBATIM (local overrides
111
+ * like reasoningEfforts/input/compat survive; nothing is overwritten or
112
+ * deleted);
113
+ * - discovered rows join by id: an id already present (or repeated within the
114
+ * batch) counts as skipped, local state wins;
115
+ * - new ids are appended with `sanitizeDiscoveredModel`'s cleaned fields;
116
+ * - the stored order is never touched: existing entries keep their positions
117
+ * (id-less rows included) and new ids join at the end in discovery order.
118
+ */
119
+ export function mergeModels(existing, discovered) {
120
+ const models = existing.map(entry => entry);
121
+ const ids = new Set();
122
+ for (const entry of models) {
123
+ const id = storedModelId(entry);
124
+ if (id !== undefined)
125
+ ids.add(id);
126
+ }
127
+ let added = 0;
128
+ let skipped = 0;
129
+ for (const raw of discovered) {
130
+ const clean = sanitizeDiscoveredModel(raw);
131
+ if (clean === undefined || ids.has(clean.id)) {
132
+ skipped += 1;
133
+ continue;
134
+ }
135
+ ids.add(clean.id);
136
+ // A fresh literal (not a cast): interfaces carry no implicit index
137
+ // signature, so the entry must be rebuilt as a plain record.
138
+ models.push({ ...clean });
139
+ added += 1;
140
+ }
141
+ // No reordering: existing entries stay exactly where the user stored them
142
+ // and new ids are appended at the end in discovery order — a no-op sync
143
+ // therefore leaves the stored array byte-identical.
144
+ return { models, added, kept: existing.length, skipped };
145
+ }
146
+ /**
147
+ * Write one route's merged models with optimistic concurrency: mutate at the
148
+ * revision read NOW (not at command start), one retry after
149
+ * SettingsConflictError with a freshly read revision — the same bottom pattern
150
+ * as persistDefaultModel in session.ts. A second conflict surfaces.
151
+ */
152
+ async function writeModels(settings, providerId, models) {
153
+ const ops = [
154
+ { op: 'set', path: ['providers', providerId, 'models'], value: models },
155
+ ];
156
+ const ns = NS_LLM_PI_AI;
157
+ for (let attempt = 0;; attempt++) {
158
+ const descriptor = currentDescriptor(settings);
159
+ try {
160
+ await settings.mutate(ns, ops, descriptor?.revision);
161
+ return;
162
+ }
163
+ catch (error) {
164
+ if (attempt === 0 && error instanceof SettingsConflictError)
165
+ continue;
166
+ throw error;
167
+ }
168
+ }
169
+ }
170
+ /** The live llm-pi-ai descriptor, re-read on demand (revision freshness). */
171
+ function currentDescriptor(settings) {
172
+ return settings.describe().find(d => d.ns === NS_LLM_PI_AI);
173
+ }
174
+ function errorText(error) {
175
+ return error instanceof Error ? error.message : String(error);
176
+ }
177
+ /**
178
+ * Run one /model-sync round: select the target routes (the rawInput-named one,
179
+ * or every custom route), discover each endpoint's models, merge, and write
180
+ * back. One route's failure never aborts the rest — its line reports the
181
+ * reason instead. Agentless by design: nothing here touches a session.
182
+ *
183
+ * @returns the command result — per-provider `<id>: added N · kept M ·
184
+ * skipped K` lines on success, `<id>: <reason>` for failed routes; `kind:
185
+ * 'error'` only for preconditions (missing namespace, unknown/non-custom
186
+ * named route) or when EVERY route failed.
187
+ */
188
+ export async function runModelSync(deps, options = {}) {
189
+ const descriptor = currentDescriptor(deps.settings);
190
+ if (descriptor === undefined) {
191
+ return { kind: 'error', text: 'The llm-pi-ai settings namespace is not registered — nothing to sync.' };
192
+ }
193
+ const wanted = options.rawInput?.trim() ?? '';
194
+ let targets;
195
+ if (wanted !== '') {
196
+ const providers = readProviders(descriptor.value);
197
+ if (!(wanted in providers)) {
198
+ return { kind: 'error', text: `Provider "${wanted}" is not configured under llm-pi-ai providers.` };
199
+ }
200
+ targets = selectCustomProviders({ [wanted]: providers[wanted] });
201
+ if (targets.length === 0) {
202
+ // Two distinct shapes land here: a built-in catalog key (excluded by
203
+ // selection even when the profile carries a baseURL) and a genuinely
204
+ // non-custom route without a baseURL. Name each accurately.
205
+ if (catalogEntry(wanted) !== undefined) {
206
+ return {
207
+ kind: 'error',
208
+ text: `Provider "${wanted}" is a built-in catalog route — /model-sync syncs hand-declared (baseURL) routes only.`,
209
+ };
210
+ }
211
+ return {
212
+ kind: 'error',
213
+ text: `Provider "${wanted}" has no baseURL — /model-sync syncs hand-declared routes only.`,
214
+ };
215
+ }
216
+ }
217
+ else {
218
+ targets = selectCustomProviders(readProviders(descriptor.value));
219
+ if (targets.length === 0) {
220
+ return { kind: 'success', text: 'No hand-declared (baseURL) providers configured — nothing to sync.' };
221
+ }
222
+ }
223
+ const lines = [];
224
+ let failures = 0;
225
+ for (const target of targets) {
226
+ try {
227
+ // Re-read the live section per route: an api added/removed between the
228
+ // selection and this write still reaches discovery (and a vanished
229
+ // namespace degrades into that route's failure line, not a crash).
230
+ const liveValue = currentDescriptor(deps.settings)?.value;
231
+ const profile = readProfile(readProviders(liveValue)[target.id]);
232
+ const discovered = await deps.llm.discoverModels(NS_LLM_PI_AI, {
233
+ provider: target.id,
234
+ baseURL: target.baseURL,
235
+ ...(profile.api !== undefined ? { api: profile.api } : {}),
236
+ ...(options.signal !== undefined ? { signal: options.signal } : {}),
237
+ });
238
+ const merged = mergeModels(profile.models, discovered);
239
+ // A no-op sync must produce zero settings mutations: write only when
240
+ // discovery actually contributed new ids.
241
+ if (merged.added > 0) {
242
+ await writeModels(deps.settings, target.id, merged.models);
243
+ }
244
+ lines.push(`${target.id}: added ${merged.added} · kept ${merged.kept} · skipped ${merged.skipped}`);
245
+ }
246
+ catch (error) {
247
+ failures += 1;
248
+ lines.push(`${target.id}: ${errorText(error)}`);
249
+ }
250
+ }
251
+ if (failures === targets.length && failures > 0) {
252
+ return { kind: 'error', text: lines.join('\n') };
253
+ }
254
+ return { kind: 'success', text: lines.join('\n') };
255
+ }
256
+ //# sourceMappingURL=model-sync.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"model-sync.js","sourceRoot":"","sources":["../src/model-sync.ts"],"names":[],"mappings":"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"}
package/lib/preset.d.ts CHANGED
@@ -35,17 +35,18 @@ export interface PresetRoot {
35
35
  }
36
36
  export declare function __setPresetRootOverride(roots: PresetRoot[] | undefined): void;
37
37
  /**
38
- * Resolve the preset roots — same discovery families as dsh-agent-presets:
39
- * 1. shipped root: `<dsh install>/config/agent-presets/` (rc-era hosts) or
40
- * the `presets/` dir inside the `@deepseek-ai/dsh-agent-presets` package
41
- * (alpha-era hosts)
38
+ * Resolve the preset roots — same discovery families as dsh-agent-presets
39
+ * (alpha.3: shipped presets are bundled inside the `@deepseek-ai/dsh-agent-presets`
40
+ * package; locally authored presets live under the Harness home):
41
+ * 1. shipped root: the `presets/` dir inside the `@deepseek-ai/dsh-agent-presets`
42
+ * package
42
43
  * 2. user root: `~/.dsh/.agent-presets/`
43
44
  * The shipped root is located by probing the known install layouts; the user
44
45
  * root is the conventional `~/.dsh/.agent-presets/`.
45
46
  *
46
47
  * Nonexistent roots scan to an empty roster, so every candidate is probed
47
- * in order — rc-era layouts first, then the dsh-agent-presets package nested
48
- * under the dsh install, then the flat global-root variant (npm hoisting).
48
+ * in order — the dsh-agent-presets package nested under the dsh install
49
+ * first, then the flat global-root variant (npm hoisting).
49
50
  */
50
51
  export declare function resolvePresetRoots(): PresetRoot[];
51
52
  /**
package/lib/preset.js CHANGED
@@ -21,28 +21,26 @@ export function __setPresetRootOverride(roots) {
21
21
  presetRootOverride = roots;
22
22
  }
23
23
  /**
24
- * Resolve the preset roots — same discovery families as dsh-agent-presets:
25
- * 1. shipped root: `<dsh install>/config/agent-presets/` (rc-era hosts) or
26
- * the `presets/` dir inside the `@deepseek-ai/dsh-agent-presets` package
27
- * (alpha-era hosts)
24
+ * Resolve the preset roots — same discovery families as dsh-agent-presets
25
+ * (alpha.3: shipped presets are bundled inside the `@deepseek-ai/dsh-agent-presets`
26
+ * package; locally authored presets live under the Harness home):
27
+ * 1. shipped root: the `presets/` dir inside the `@deepseek-ai/dsh-agent-presets`
28
+ * package
28
29
  * 2. user root: `~/.dsh/.agent-presets/`
29
30
  * The shipped root is located by probing the known install layouts; the user
30
31
  * root is the conventional `~/.dsh/.agent-presets/`.
31
32
  *
32
33
  * Nonexistent roots scan to an empty roster, so every candidate is probed
33
- * in order — rc-era layouts first, then the dsh-agent-presets package nested
34
- * under the dsh install, then the flat global-root variant (npm hoisting).
34
+ * in order — the dsh-agent-presets package nested under the dsh install
35
+ * first, then the flat global-root variant (npm hoisting).
35
36
  */
36
37
  export function resolvePresetRoots() {
37
38
  const roots = [];
38
39
  // Shipped root probes. The dsh binary is at `/usr/local/bin/dsh` or
39
- // `/opt/homebrew/bin/dsh`; rc-era hosts keep the config dir at
40
- // `<global>/lib/node_modules/@deepseek-ai/dsh/config/agent-presets/`, while
41
- // alpha-era hosts bundle the shipped presets inside `@deepseek-ai/dsh-agent-presets`
42
- // (observed nested under the dsh package; flat at the global root when npm hoists).
40
+ // `/opt/homebrew/bin/dsh`; the shipped presets are bundled inside
41
+ // `@deepseek-ai/dsh-agent-presets` (observed nested under the dsh package;
42
+ // flat at the global root when npm hoists).
43
43
  const shippedPaths = [
44
- '/opt/homebrew/lib/node_modules/@deepseek-ai/dsh/config/agent-presets',
45
- '/usr/local/lib/node_modules/@deepseek-ai/dsh/config/agent-presets',
46
44
  '/opt/homebrew/lib/node_modules/@deepseek-ai/dsh/node_modules/@deepseek-ai/dsh-agent-presets/presets',
47
45
  '/usr/local/lib/node_modules/@deepseek-ai/dsh/node_modules/@deepseek-ai/dsh-agent-presets/presets',
48
46
  '/opt/homebrew/lib/node_modules/@deepseek-ai/dsh-agent-presets/presets',
@@ -61,14 +59,14 @@ export function resolvePresetRoots() {
61
59
  * publishes display metadata in Chinese only (e.g. `标准模式`) with no i18n
62
60
  * mechanism, which would put Chinese in front of every user — so the roster
63
61
  * overrides the ids we know. Anything unmapped (a renamed or newly shipped
64
- * preset) keeps its official string until mapped here. `code` (rc) and `ptc`
65
- * (alpha) are the same preset across the upstream rename.
62
+ * preset) keeps its official string until mapped here. The shipped alpha.3
63
+ * roster is standard / minimal / cordis / ptc (the pre-alpha `code` id was
64
+ * renamed upstream and no longer exists).
66
65
  */
67
66
  const PRESET_ENGLISH_NAMES = {
68
67
  standard: 'Standard',
69
68
  minimal: 'Minimal',
70
69
  cordis: 'Cordis',
71
- code: 'PTC',
72
70
  ptc: 'PTC',
73
71
  };
74
72
  /**
@@ -100,28 +98,25 @@ async function scanRoot(root) {
100
98
  catch {
101
99
  continue; // no composition file → skip
102
100
  }
103
- // Read optional display metadata: `preset.yml` is the canonical file on
104
- // current rc and alpha hosts alike (`METADATA_FILE` in
105
- // @deepseek-ai/dsh-agent-presets); `metadata.yml` stays as a legacy
106
- // fallback. First file that reads wins; absent metadata keeps the
107
- // directory id as the name.
101
+ // Read the display metadata: `preset.yml` is the canonical file
102
+ // (`METADATA_FILE` in @deepseek-ai/dsh-agent-presets); absent metadata
103
+ // keeps the directory id as the name.
108
104
  let name = entry.name;
109
105
  let description;
110
- for (const metaName of ['preset.yml', 'metadata.yml']) {
111
- let meta;
112
- try {
113
- meta = await readFile(join(dir, metaName), 'utf8');
114
- }
115
- catch {
116
- continue;
117
- }
106
+ let meta;
107
+ try {
108
+ meta = await readFile(join(dir, 'preset.yml'), 'utf8');
109
+ }
110
+ catch {
111
+ meta = '';
112
+ }
113
+ if (meta !== '') {
118
114
  const nameMatch = meta.match(/^name:\s*(.+)$/m);
119
115
  if (nameMatch)
120
116
  name = nameMatch[1].trim();
121
117
  const descMatch = meta.match(/^description:\s*(.+)$/m);
122
118
  if (descMatch)
123
119
  description = descMatch[1].trim();
124
- break;
125
120
  }
126
121
  // English override for the known shipped ids; unmapped presets keep the
127
122
  // official string (metadata name ?? id).
package/lib/preset.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"preset.js","sourceRoot":"","sources":["../src/preset.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"preset.js","sourceRoot":"","sources":["../src/preset.ts"],"names":[],"mappings":"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"}
package/lib/session.d.ts CHANGED
@@ -337,7 +337,7 @@ export declare class DshSessionBridge {
337
337
  /**
338
338
  * Resume a persisted session: tear down the live agent (disposers are kept —
339
339
  * the session-id filter re-binds to the resumed id) and load the persisted
340
- * session in its place. The caller replays `handle.agent.session.events`
340
+ * session in its place. The caller replays `handle.agent.session.snapshotEvents()`
341
341
  * through `replay()` to rebuild stats/transcript — clear the transcript
342
342
  * BEFORE replaying (the renderer's echo dedupe must not see replayed user
343
343
  * messages next to a stale local echo). Serialized: concurrent calls share
package/lib/session.js CHANGED
@@ -11,7 +11,7 @@
11
11
  */
12
12
  import { installModelSelection } from '@deepseek-ai/dsh-agent';
13
13
  import { createUserMessage } from '@deepseek-ai/dsh-llm';
14
- import { settingsNamespace, SettingsConflictError } from '@deepseek-ai/dsh-settings';
14
+ import { SettingsConflictError } from '@deepseek-ai/dsh-settings';
15
15
  import { SessionId } from '@deepseek-ai/dsh-session';
16
16
  import { readAppendSystem } from "./append-system.js";
17
17
  import { join } from 'node:path';
@@ -418,7 +418,7 @@ export class DshSessionBridge {
418
418
  const session = sessions.get(SessionId(childId));
419
419
  if (session === undefined)
420
420
  continue;
421
- const events = session.events;
421
+ const events = session.snapshotEvents();
422
422
  const len = events.length;
423
423
  let from = this.reconciledLen.get(childId) ?? 0;
424
424
  // A torn-down / re-seeded child session restarts its log — recount it.
@@ -883,7 +883,7 @@ export class DshSessionBridge {
883
883
  /**
884
884
  * Resume a persisted session: tear down the live agent (disposers are kept —
885
885
  * the session-id filter re-binds to the resumed id) and load the persisted
886
- * session in its place. The caller replays `handle.agent.session.events`
886
+ * session in its place. The caller replays `handle.agent.session.snapshotEvents()`
887
887
  * through `replay()` to rebuild stats/transcript — clear the transcript
888
888
  * BEFORE replaying (the renderer's echo dedupe must not see replayed user
889
889
  * messages next to a stale local echo). Serialized: concurrent calls share
@@ -1532,7 +1532,7 @@ export class DshSessionBridge {
1532
1532
  if (this.sessionId === undefined)
1533
1533
  return true;
1534
1534
  const agent = this.getAgent();
1535
- return agent === undefined || agent.session.events.length === 0;
1535
+ return agent === undefined || agent.session.seq === 0;
1536
1536
  }
1537
1537
  }
1538
1538
  /**
@@ -1564,7 +1564,10 @@ export async function persistDefaultModel(ctx, selection) {
1564
1564
  const settings = ctx.get('settings');
1565
1565
  if (settings === undefined)
1566
1566
  return undefined;
1567
- const ns = settingsNamespace('agent-default-model');
1567
+ // dsh-settings 0.1.2-alpha.3 removed the runtime settingsNamespace() helper:
1568
+ // a plain literal is the supported spelling (type-level brand check plus the
1569
+ // host's runtime parseSettingsNamespace validation).
1570
+ const ns = 'agent-default-model';
1568
1571
  // The descriptor carries the namespace's revision (optimistic-concurrency
1569
1572
  // token for mutate) and proves the schema registration that validates the
1570
1573
  // field names below; the write itself rejects when the namespace is