@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.
- package/README.md +3 -1
- package/README.zh-CN.md +1 -1
- package/bin/dsh-tui-pi +2 -0
- package/bin/preflight-projcache.mjs +134 -0
- package/lib/ask-user.d.ts +9 -19
- package/lib/ask-user.js +20 -50
- package/lib/ask-user.js.map +1 -1
- package/lib/index.js +18 -15
- package/lib/index.js.map +1 -1
- package/lib/login.js +8 -3
- package/lib/login.js.map +1 -1
- package/lib/messages.js.map +1 -1
- package/lib/model-sync.d.ts +122 -0
- package/lib/model-sync.js +256 -0
- package/lib/model-sync.js.map +1 -0
- package/lib/preset.d.ts +7 -6
- package/lib/preset.js +24 -29
- package/lib/preset.js.map +1 -1
- package/lib/session.d.ts +1 -1
- package/lib/session.js +8 -5
- package/lib/session.js.map +1 -1
- package/lib/settings.js +10 -5
- package/lib/settings.js.map +1 -1
- package/lib/subagent-viewer.js.map +1 -1
- package/lib/theme-settings.d.ts +14 -8
- package/lib/theme-settings.js +15 -8
- package/lib/theme-settings.js.map +1 -1
- package/package.json +5 -4
- package/scripts/link-dsh-closure.mjs +9 -0
- package/scripts/smoke-boot.mjs +117 -0
|
@@ -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":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,EAAE,iBAAiB,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAA;AAGpF,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAA;AAEpD,2EAA2E;AAC3E,MAAM,YAAY,GAAG,iBAAiB,CAAC,WAAW,CAAC,CAAA;AAuDnD;;;GAGG;AACH,SAAS,aAAa,CAAC,KAAc;IACnC,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI;QAAE,OAAO,EAAE,CAAA;IAC1D,MAAM,SAAS,GAAI,KAAiC,CAAC,SAAS,CAAA;IAC9D,IAAI,OAAO,SAAS,KAAK,QAAQ,IAAI,SAAS,KAAK,IAAI;QAAE,OAAO,EAAE,CAAA;IAClE,OAAO,SAAoC,CAAA;AAC7C,CAAC;AASD,SAAS,WAAW,CAAC,GAAY;IAC/B,MAAM,MAAM,GAAG,OAAO,GAAG,KAAK,QAAQ,IAAI,GAAG,KAAK,IAAI,CAAC,CAAC,CAAC,GAA8B,CAAC,CAAC,CAAC,EAAE,CAAA;IAC5F,MAAM,OAAO,GAAG,OAAO,MAAM,CAAC,OAAO,KAAK,QAAQ,IAAI,MAAM,CAAC,OAAO,KAAK,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAA;IACxG,MAAM,GAAG,GAAG,OAAO,MAAM,CAAC,GAAG,KAAK,QAAQ,IAAI,MAAM,CAAC,GAAG,KAAK,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,CAAA;IACxF,MAAM,SAAS,GAAG,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAA;IACnE,yEAAyE;IACzE,wDAAwD;IACxD,MAAM,MAAM,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC,KAAK,EAAwB,EAAE,CAAC,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,CAAC,CAAA;IAC7G,OAAO,EAAE,GAAG,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,CAAC,GAAG,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,MAAM,EAAE,CAAA;AACzG,CAAC;AAED,4DAA4D;AAC5D,SAAS,aAAa,CAAC,KAAkB;IACvC,MAAM,EAAE,GAAG,KAAK,CAAC,EAAE,CAAA;IACnB,OAAO,OAAO,EAAE,KAAK,QAAQ,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,CAAA;AAC7D,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,qBAAqB,CACnC,SAA8C;IAE9C,MAAM,QAAQ,GAA0B,EAAE,CAAA;IAC1C,KAAK,MAAM,CAAC,EAAE,EAAE,GAAG,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,SAAS,IAAI,EAAE,CAAC,EAAE,CAAC;QACxD,IAAI,YAAY,CAAC,EAAE,CAAC,KAAK,SAAS;YAAE,SAAQ;QAC5C,MAAM,OAAO,GAAG,WAAW,CAAC,GAAG,CAAC,CAAA;QAChC,IAAI,OAAO,CAAC,OAAO,KAAK,SAAS;YAAE,SAAQ;QAC3C,QAAQ,CAAC,IAAI,CAAC;YACZ,EAAE;YACF,OAAO,EAAE,OAAO,CAAC,OAAO;YACxB,GAAG,CAAC,OAAO,CAAC,GAAG,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SAC3D,CAAC,CAAA;IACJ,CAAC;IACD,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;IACjE,OAAO,QAAQ,CAAA;AACjB,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,uBAAuB,CAAC,GAAY;IAClD,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,GAAG,KAAK,IAAI;QAAE,OAAO,SAAS,CAAA;IAC7D,MAAM,GAAG,GAAG,GAAqF,CAAA;IACjG,IAAI,OAAO,GAAG,CAAC,EAAE,KAAK,QAAQ;QAAE,OAAO,SAAS,CAAA;IAChD,MAAM,EAAE,GAAG,GAAG,CAAC,EAAE,CAAC,IAAI,EAAE,CAAA;IACxB,IAAI,EAAE,KAAK,EAAE;QAAE,OAAO,SAAS,CAAA;IAC/B,MAAM,IAAI,GAAG,OAAO,GAAG,CAAC,IAAI,KAAK,QAAQ,IAAI,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,SAAS,CAAA;IACjG,MAAM,QAAQ,GAAG,CAAC,KAAc,EAAsB,EAAE,CACtD,OAAO,KAAK,KAAK,QAAQ,IAAI,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAA;IACxF,MAAM,aAAa,GAAG,QAAQ,CAAC,GAAG,CAAC,aAAa,CAAC,CAAA;IACjD,MAAM,SAAS,GAAG,QAAQ,CAAC,GAAG,CAAC,SAAS,CAAC,CAAA;IACzC,OAAO;QACL,EAAE;QACF,GAAG,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACvC,GAAG,CAAC,aAAa,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACzD,GAAG,CAAC,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAClD,CAAA;AACH,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,WAAW,CACzB,QAA+B,EAC/B,UAAkC;IAElC,MAAM,MAAM,GAAkB,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,KAAoB,CAAC,CAAA;IACzE,MAAM,GAAG,GAAG,IAAI,GAAG,EAAU,CAAA;IAC7B,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,MAAM,EAAE,GAAG,aAAa,CAAC,KAAK,CAAC,CAAA;QAC/B,IAAI,EAAE,KAAK,SAAS;YAAE,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;IACnC,CAAC;IACD,IAAI,KAAK,GAAG,CAAC,CAAA;IACb,IAAI,OAAO,GAAG,CAAC,CAAA;IACf,KAAK,MAAM,GAAG,IAAI,UAAU,EAAE,CAAC;QAC7B,MAAM,KAAK,GAAG,uBAAuB,CAAC,GAAG,CAAC,CAAA;QAC1C,IAAI,KAAK,KAAK,SAAS,IAAI,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,CAAC;YAC7C,OAAO,IAAI,CAAC,CAAA;YACZ,SAAQ;QACV,CAAC;QACD,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,CAAA;QACjB,mEAAmE;QACnE,6DAA6D;QAC7D,MAAM,CAAC,IAAI,CAAC,EAAE,GAAG,KAAK,EAAE,CAAC,CAAA;QACzB,KAAK,IAAI,CAAC,CAAA;IACZ,CAAC;IACD,0EAA0E;IAC1E,wEAAwE;IACxE,oDAAoD;IACpD,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,QAAQ,CAAC,MAAM,EAAE,OAAO,EAAE,CAAA;AAC1D,CAAC;AAED;;;;;GAKG;AACH,KAAK,UAAU,WAAW,CACxB,QAAmC,EACnC,UAAkB,EAClB,MAAqB;IAErB,MAAM,GAAG,GAAqB;QAC5B,EAAE,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,WAAW,EAAE,UAAU,EAAE,QAAQ,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE;KACxE,CAAA;IACD,MAAM,EAAE,GAAsB,YAAY,CAAA;IAC1C,KAAK,IAAI,OAAO,GAAG,CAAC,GAAI,OAAO,EAAE,EAAE,CAAC;QAClC,MAAM,UAAU,GAAG,iBAAiB,CAAC,QAAQ,CAAC,CAAA;QAC9C,IAAI,CAAC;YACH,MAAM,QAAQ,CAAC,MAAM,CAAC,EAAE,EAAE,GAAG,EAAE,UAAU,EAAE,QAAQ,CAAC,CAAA;YACpD,OAAM;QACR,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,OAAO,KAAK,CAAC,IAAI,KAAK,YAAY,qBAAqB;gBAAE,SAAQ;YACrE,MAAM,KAAK,CAAA;QACb,CAAC;IACH,CAAC;AACH,CAAC;AAED,6EAA6E;AAC7E,SAAS,iBAAiB,CAAC,QAAmC;IAC5D,OAAO,QAAQ,CAAC,QAAQ,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,YAAY,CAAC,CAAA;AAC7D,CAAC;AAED,SAAS,SAAS,CAAC,KAAc;IAC/B,OAAO,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;AAC/D,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,IAAmB,EACnB,UAAuD,EAAE;IAEzD,MAAM,UAAU,GAAG,iBAAiB,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAA;IACnD,IAAI,UAAU,KAAK,SAAS,EAAE,CAAC;QAC7B,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,uEAAuE,EAAE,CAAA;IACzG,CAAC;IAED,MAAM,MAAM,GAAG,OAAO,CAAC,QAAQ,EAAE,IAAI,EAAE,IAAI,EAAE,CAAA;IAC7C,IAAI,OAA8B,CAAA;IAClC,IAAI,MAAM,KAAK,EAAE,EAAE,CAAC;QAClB,MAAM,SAAS,GAAG,aAAa,CAAC,UAAU,CAAC,KAAK,CAAC,CAAA;QACjD,IAAI,CAAC,CAAC,MAAM,IAAI,SAAS,CAAC,EAAE,CAAC;YAC3B,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,aAAa,MAAM,gDAAgD,EAAE,CAAA;QACrG,CAAC;QACD,OAAO,GAAG,qBAAqB,CAAC,EAAE,CAAC,MAAM,CAAC,EAAE,SAAS,CAAC,MAAM,CAAC,EAAE,CAAC,CAAA;QAChE,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACzB,qEAAqE;YACrE,qEAAqE;YACrE,4DAA4D;YAC5D,IAAI,YAAY,CAAC,MAAM,CAAC,KAAK,SAAS,EAAE,CAAC;gBACvC,OAAO;oBACL,IAAI,EAAE,OAAO;oBACb,IAAI,EAAE,aAAa,MAAM,wFAAwF;iBAClH,CAAA;YACH,CAAC;YACD,OAAO;gBACL,IAAI,EAAE,OAAO;gBACb,IAAI,EAAE,aAAa,MAAM,iEAAiE;aAC3F,CAAA;QACH,CAAC;IACH,CAAC;SAAM,CAAC;QACN,OAAO,GAAG,qBAAqB,CAAC,aAAa,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,CAAA;QAChE,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACzB,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,oEAAoE,EAAE,CAAA;QACxG,CAAC;IACH,CAAC;IAED,MAAM,KAAK,GAAa,EAAE,CAAA;IAC1B,IAAI,QAAQ,GAAG,CAAC,CAAA;IAChB,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;QAC7B,IAAI,CAAC;YACH,uEAAuE;YACvE,mEAAmE;YACnE,mEAAmE;YACnE,MAAM,SAAS,GAAG,iBAAiB,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,KAAK,CAAA;YACzD,MAAM,OAAO,GAAG,WAAW,CAAC,aAAa,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAA;YAChE,MAAM,UAAU,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,cAAc,CAAC,YAAY,EAAE;gBAC7D,QAAQ,EAAE,MAAM,CAAC,EAAE;gBACnB,OAAO,EAAE,MAAM,CAAC,OAAO;gBACvB,GAAG,CAAC,OAAO,CAAC,GAAG,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;gBAC1D,GAAG,CAAC,OAAO,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;aACpE,CAAC,CAAA;YACF,MAAM,MAAM,GAAG,WAAW,CAAC,OAAO,CAAC,MAAM,EAAE,UAAU,CAAC,CAAA;YACtD,qEAAqE;YACrE,0CAA0C;YAC1C,IAAI,MAAM,CAAC,KAAK,GAAG,CAAC,EAAE,CAAC;gBACrB,MAAM,WAAW,CAAC,IAAI,CAAC,QAAQ,EAAE,MAAM,CAAC,EAAE,EAAE,MAAM,CAAC,MAAM,CAAC,CAAA;YAC5D,CAAC;YACD,KAAK,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,EAAE,WAAW,MAAM,CAAC,KAAK,WAAW,MAAM,CAAC,IAAI,cAAc,MAAM,CAAC,OAAO,EAAE,CAAC,CAAA;QACrG,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,QAAQ,IAAI,CAAC,CAAA;YACb,KAAK,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,EAAE,KAAK,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC,CAAA;QACjD,CAAC;IACH,CAAC;IACD,IAAI,QAAQ,KAAK,OAAO,CAAC,MAAM,IAAI,QAAQ,GAAG,CAAC,EAAE,CAAC;QAChD,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAA;IAClD,CAAC;IACD,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAA;AACpD,CAAC"}
|
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
|
-
*
|
|
40
|
-
*
|
|
41
|
-
*
|
|
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 —
|
|
48
|
-
*
|
|
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
|
-
*
|
|
26
|
-
*
|
|
27
|
-
*
|
|
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 —
|
|
34
|
-
*
|
|
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`;
|
|
40
|
-
//
|
|
41
|
-
//
|
|
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.
|
|
65
|
-
*
|
|
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
|
|
104
|
-
//
|
|
105
|
-
//
|
|
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
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
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":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAA;AAC5D,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AACzC,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAA;AA0BjC,sEAAsE;AACtE,IAAI,kBAA4C,CAAA;AAChD,MAAM,UAAU,uBAAuB,CAAC,KAA+B;IACrE,kBAAkB,GAAG,KAAK,CAAA;AAC5B,CAAC;AAED
|
|
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.
|
|
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 {
|
|
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.
|
|
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.
|
|
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.
|
|
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
|
-
|
|
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
|