dsh-plan-completion 0.1.6 → 0.1.7
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 +13 -0
- package/client.js +148 -174
- package/docs/publish-assessment.md +4 -1
- package/index.js +15 -4
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,18 @@
|
|
|
3
3
|
All notable changes to this project are documented here.
|
|
4
4
|
Format: [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), versioning: SemVer.
|
|
5
5
|
|
|
6
|
+
## [0.1.7] - 2026-11-02
|
|
7
|
+
|
|
8
|
+
### Fixed
|
|
9
|
+
- Settings page model lists now load per provider (`GET /settings?provider=…`), so third-party
|
|
10
|
+
providers' models appear after switching Provider; fixed an internal error caused by a
|
|
11
|
+
provider-scope bug in the settings snapshot.
|
|
12
|
+
|
|
13
|
+
### Changed
|
|
14
|
+
- Settings page redesign matched to DSH General Settings: flat 66px rows (title + description left,
|
|
15
|
+
control right), filled controls without borders, DSH-sized toggle, right-aligned save button,
|
|
16
|
+
unified typography/theme tokens for light and dark themes.
|
|
17
|
+
|
|
6
18
|
## [0.1.6] - 2026-11-02
|
|
7
19
|
|
|
8
20
|
### Added
|
|
@@ -152,3 +164,4 @@ Format: [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), versioning: Se
|
|
|
152
164
|
`enableDebugRoutes: true`; production endpoints are `state`, `debug`, `diag`, `replan`, `warm`.
|
|
153
165
|
- No credentials are stored in the plugin; model calls use the host `llm` service.
|
|
154
166
|
|
|
167
|
+
|
package/client.js
CHANGED
|
@@ -113,7 +113,10 @@ window.__ModuleLoader__.load({
|
|
|
113
113
|
'settings.policy.auto': '自动(优先非推理)',
|
|
114
114
|
'settings.provider': 'Provider',
|
|
115
115
|
'settings.modelId': 'Model ID',
|
|
116
|
-
'settings.modelCalls': '允许本插件调用模型',
|
|
116
|
+
'settings.modelCalls': '允许本插件调用模型',
|
|
117
|
+
'settings.modelDesc': '选择插件生成计划与建议时使用的模型来源',
|
|
118
|
+
'settings.providerDesc': '固定使用的 provider',
|
|
119
|
+
'settings.callsDesc': '关闭后插件只使用启发式,不向模型发送内容',
|
|
117
120
|
'settings.defaultRoute': '宿主默认:{value}',
|
|
118
121
|
'settings.save': '保存',
|
|
119
122
|
'settings.saving': '保存中…',
|
|
@@ -171,7 +174,10 @@ window.__ModuleLoader__.load({
|
|
|
171
174
|
'settings.policy.auto': 'Auto (prefer non-reasoning)',
|
|
172
175
|
'settings.provider': 'Provider',
|
|
173
176
|
'settings.modelId': 'Model ID',
|
|
174
|
-
'settings.modelCalls': 'Allow this plugin to call models',
|
|
177
|
+
'settings.modelCalls': 'Allow this plugin to call models',
|
|
178
|
+
'settings.modelDesc': 'Model source used for plan and suggestion generation',
|
|
179
|
+
'settings.providerDesc': 'Provider used by the fixed policy',
|
|
180
|
+
'settings.callsDesc': 'When off, the plugin only uses heuristics and sends nothing',
|
|
175
181
|
'settings.defaultRoute': 'Host default: {value}',
|
|
176
182
|
'settings.save': 'Save',
|
|
177
183
|
'settings.saving': 'Saving…',
|
|
@@ -820,9 +826,10 @@ window.__ModuleLoader__.load({
|
|
|
820
826
|
/**
|
|
821
827
|
* Host settings used by the settings page (model policy + modelCalls).
|
|
822
828
|
*/
|
|
823
|
-
function fetchSettings() {
|
|
829
|
+
function fetchSettings(provider) {
|
|
824
830
|
try {
|
|
825
|
-
|
|
831
|
+
const query = typeof provider === 'string' && provider ? '?provider=' + encodeURIComponent(provider) : '';
|
|
832
|
+
return Promise.resolve(fetch('/plan-completion/settings' + query, {
|
|
826
833
|
method: 'GET',
|
|
827
834
|
credentials: 'same-origin',
|
|
828
835
|
headers: { accept: 'application/json' }
|
|
@@ -2138,176 +2145,138 @@ window.__ModuleLoader__.load({
|
|
|
2138
2145
|
const SETTINGS_ID = 'plan-completion-settings';
|
|
2139
2146
|
const SETTINGS_ORDER = 60;
|
|
2140
2147
|
|
|
2141
|
-
function settingsCss() {
|
|
2142
|
-
return [
|
|
2143
|
-
'.dpc-settings-
|
|
2144
|
-
'.dpc-settings-
|
|
2145
|
-
'.dpc-settings-
|
|
2146
|
-
'.dpc-settings-
|
|
2147
|
-
'.dpc-settings-
|
|
2148
|
-
'.dpc-settings-
|
|
2149
|
-
'.dpc-settings-
|
|
2150
|
-
'.dpc-settings-
|
|
2151
|
-
'.dpc-settings-
|
|
2152
|
-
'.dpc-settings-
|
|
2153
|
-
'.dpc-settings-
|
|
2154
|
-
'.dpc-settings-
|
|
2155
|
-
'.dpc-settings-
|
|
2156
|
-
|
|
2157
|
-
|
|
2158
|
-
|
|
2159
|
-
|
|
2160
|
-
|
|
2161
|
-
|
|
2162
|
-
|
|
2163
|
-
|
|
2164
|
-
|
|
2165
|
-
|
|
2166
|
-
|
|
2167
|
-
|
|
2168
|
-
|
|
2169
|
-
|
|
2170
|
-
|
|
2171
|
-
|
|
2172
|
-
|
|
2173
|
-
|
|
2174
|
-
|
|
2175
|
-
|
|
2176
|
-
|
|
2177
|
-
|
|
2178
|
-
|
|
2179
|
-
|
|
2180
|
-
|
|
2181
|
-
|
|
2182
|
-
|
|
2183
|
-
|
|
2184
|
-
|
|
2185
|
-
|
|
2186
|
-
|
|
2187
|
-
|
|
2188
|
-
|
|
2189
|
-
|
|
2190
|
-
|
|
2191
|
-
|
|
2192
|
-
|
|
2193
|
-
|
|
2194
|
-
|
|
2195
|
-
|
|
2196
|
-
|
|
2197
|
-
|
|
2198
|
-
|
|
2199
|
-
|
|
2200
|
-
|
|
2201
|
-
|
|
2202
|
-
|
|
2203
|
-
|
|
2204
|
-
|
|
2205
|
-
|
|
2206
|
-
|
|
2207
|
-
|
|
2208
|
-
|
|
2209
|
-
|
|
2210
|
-
|
|
2211
|
-
|
|
2212
|
-
|
|
2213
|
-
|
|
2214
|
-
|
|
2215
|
-
|
|
2216
|
-
|
|
2217
|
-
|
|
2218
|
-
|
|
2219
|
-
|
|
2220
|
-
|
|
2221
|
-
|
|
2222
|
-
|
|
2223
|
-
|
|
2224
|
-
|
|
2225
|
-
|
|
2226
|
-
const
|
|
2227
|
-
{
|
|
2228
|
-
|
|
2229
|
-
|
|
2230
|
-
|
|
2231
|
-
|
|
2232
|
-
|
|
2233
|
-
|
|
2234
|
-
|
|
2235
|
-
|
|
2236
|
-
|
|
2237
|
-
|
|
2238
|
-
|
|
2239
|
-
|
|
2240
|
-
|
|
2241
|
-
|
|
2242
|
-
|
|
2243
|
-
|
|
2244
|
-
|
|
2245
|
-
|
|
2246
|
-
|
|
2247
|
-
|
|
2248
|
-
|
|
2249
|
-
|
|
2250
|
-
|
|
2251
|
-
|
|
2252
|
-
|
|
2253
|
-
|
|
2254
|
-
|
|
2255
|
-
|
|
2256
|
-
onChange: function
|
|
2257
|
-
|
|
2258
|
-
|
|
2259
|
-
|
|
2260
|
-
|
|
2261
|
-
|
|
2262
|
-
|
|
2263
|
-
|
|
2264
|
-
|
|
2265
|
-
|
|
2266
|
-
|
|
2267
|
-
|
|
2268
|
-
|
|
2269
|
-
|
|
2270
|
-
|
|
2271
|
-
|
|
2272
|
-
|
|
2273
|
-
onChange: function onProvider(event) {
|
|
2274
|
-
patch({ fixedProvider: event.target.value });
|
|
2275
|
-
}
|
|
2276
|
-
}),
|
|
2277
|
-
h('input', {
|
|
2278
|
-
key: 'model',
|
|
2279
|
-
className: 'dpc-settings-input',
|
|
2280
|
-
placeholder: t('settings.modelId'),
|
|
2281
|
-
value: settings.fixedModel || '',
|
|
2282
|
-
onChange: function onModel(event) {
|
|
2283
|
-
patch({ fixedModel: event.target.value });
|
|
2284
|
-
}
|
|
2285
|
-
})
|
|
2286
|
-
)
|
|
2287
|
-
: null
|
|
2288
|
-
),
|
|
2289
|
-
h(
|
|
2290
|
-
'label',
|
|
2291
|
-
{ key: 'calls', className: 'dpc-settings-check' },
|
|
2292
|
-
h('input', {
|
|
2293
|
-
type: 'checkbox',
|
|
2294
|
-
checked: settings.modelCalls === true,
|
|
2295
|
-
onChange: function onCalls(event) {
|
|
2296
|
-
patch({ modelCalls: event.target.checked });
|
|
2297
|
-
}
|
|
2298
|
-
}),
|
|
2299
|
-
h('span', null, t('settings.modelCalls'))
|
|
2300
|
-
),
|
|
2301
|
-
error ? h('div', { key: 'error', className: 'dpc-settings-error' }, error) : null,
|
|
2302
|
-
saved && !error ? h('div', { key: 'saved', className: 'dpc-settings-hint' }, t('settings.saved')) : null,
|
|
2303
|
-
h(
|
|
2304
|
-
'button',
|
|
2305
|
-
{ key: 'save', type: 'button', className: 'dpc-settings-save', disabled: saving, onClick: save },
|
|
2306
|
-
saving ? t('settings.saving') : t('settings.save')
|
|
2307
|
-
)
|
|
2308
|
-
)
|
|
2309
|
-
);
|
|
2310
|
-
}
|
|
2148
|
+
function settingsCss() {
|
|
2149
|
+
return [
|
|
2150
|
+
'.dpc-settings-page{display:flex;flex-direction:column;padding:8px 24px 20px;max-width:720px;box-sizing:border-box;font-size:13px;line-height:20px;color:var(--dsw-alias-label-primary)}',
|
|
2151
|
+
'.dpc-settings-head{display:flex;flex-direction:column;gap:4px;padding:6px 0 10px}',
|
|
2152
|
+
'.dpc-settings-title{font-size:16px;font-weight:600;line-height:26px}',
|
|
2153
|
+
'.dpc-settings-sub{font-size:12px;line-height:18px;color:var(--dsw-alias-label-tertiary)}',
|
|
2154
|
+
'.dpc-settings-row{display:flex;align-items:center;justify-content:space-between;gap:24px;min-height:66px;padding:12px 0;box-sizing:border-box;border-bottom:1px solid var(--dsw-alias-border-l1)}',
|
|
2155
|
+
'.dpc-settings-row:last-of-type{border-bottom:0}',
|
|
2156
|
+
'.dpc-settings-row-main{display:flex;flex-direction:column;gap:3px;min-width:0}',
|
|
2157
|
+
'.dpc-settings-row-label{font-size:14px;line-height:22px;color:var(--dsw-alias-label-primary)}',
|
|
2158
|
+
'.dpc-settings-row-desc{font-size:12px;line-height:18px;color:var(--dsw-alias-label-tertiary)}',
|
|
2159
|
+
'.dpc-settings-control{flex:none;display:flex;justify-content:flex-end;align-items:center;min-width:132px;max-width:240px}',
|
|
2160
|
+
'.dpc-settings-select{width:100%;border:1px solid transparent;border-radius:8px;padding:7px 12px;font-size:13px;line-height:20px;background:var(--dsw-alias-bg-layer-2,var(--dsw-alias-bg-layer-1));color:var(--dsw-alias-label-primary);cursor:pointer;appearance:auto}',
|
|
2161
|
+
'.dpc-settings-select:hover{background:var(--dsw-alias-bg-layer-1)}',
|
|
2162
|
+
'.dpc-settings-select:focus{outline:none;border-color:var(--dsw-alias-brand-primary,var(--dsw-alias-state-business-primary))}',
|
|
2163
|
+
'.dpc-settings-toggle{width:40px;height:24px;border-radius:999px;border:0;background:var(--dsw-alias-bg-layer-2,var(--dsw-alias-bg-layer-1));position:relative;cursor:pointer;padding:0;flex:none}',
|
|
2164
|
+
'.dpc-settings-toggle[data-on="true"]{background:var(--dsw-alias-brand-primary,var(--dsw-alias-state-business-primary))}',
|
|
2165
|
+
'.dpc-settings-toggle span{position:absolute;top:2px;left:2px;width:20px;height:20px;border-radius:999px;background:#fff;transition:left .12s ease;box-shadow:0 1px 2px rgba(0,0,0,.18)}',
|
|
2166
|
+
'.dpc-settings-toggle[data-on="true"] span{left:18px}',
|
|
2167
|
+
'.dpc-settings-footer{display:flex;align-items:center;justify-content:flex-end;gap:12px;padding-top:18px}',
|
|
2168
|
+
'.dpc-settings-status{font-size:12px;line-height:18px;color:var(--dsw-alias-state-success-primary,var(--dsw-alias-label-secondary));margin-right:auto}',
|
|
2169
|
+
'.dpc-settings-error{font-size:12px;line-height:18px;color:var(--dsw-alias-state-error-primary,var(--dsw-alias-label-secondary));margin-right:auto}',
|
|
2170
|
+
'.dpc-settings-save{border:0;border-radius:8px;padding:7px 16px;font-size:13px;line-height:20px;cursor:pointer;background:var(--dsw-alias-bg-layer-2,var(--dsw-alias-bg-layer-1));color:var(--dsw-alias-label-primary);flex:none}',
|
|
2171
|
+
'.dpc-settings-save:hover{background:var(--dsw-alias-bg-layer-1)}',
|
|
2172
|
+
'.dpc-settings-save:disabled{opacity:.5;cursor:default}',
|
|
2173
|
+
'.dpc-settings-loading{padding:18px 24px;font-size:13px;color:var(--dsw-alias-label-secondary)}'
|
|
2174
|
+
].join('\n');
|
|
2175
|
+
}
|
|
2176
|
+
|
|
2177
|
+
function PlanSettingsPage(props) {
|
|
2178
|
+
const t = makeT(props);
|
|
2179
|
+
const [settings, setSettings] = React.useState(null);
|
|
2180
|
+
const [status, setStatus] = React.useState('loading');
|
|
2181
|
+
const [saving, setSaving] = React.useState(false);
|
|
2182
|
+
const [error, setError] = React.useState('');
|
|
2183
|
+
const [saved, setSaved] = React.useState(false);
|
|
2184
|
+
|
|
2185
|
+
React.useEffect(function load() {
|
|
2186
|
+
let alive = true;
|
|
2187
|
+
fetchSettings().then(function applied(result) {
|
|
2188
|
+
if (!alive) return;
|
|
2189
|
+
if (!result || result.ok !== true || !result.settings) { setStatus('error'); return; }
|
|
2190
|
+
setSettings(result.settings);
|
|
2191
|
+
setStatus('ready');
|
|
2192
|
+
});
|
|
2193
|
+
return function cleanup() { alive = false; };
|
|
2194
|
+
}, []);
|
|
2195
|
+
|
|
2196
|
+
function patch(next) {
|
|
2197
|
+
setSaved(false);
|
|
2198
|
+
setSettings(function keep(previous) { return previous ? { ...previous, ...next } : previous; });
|
|
2199
|
+
}
|
|
2200
|
+
function chooseProvider(provider) {
|
|
2201
|
+
patch({ fixedProvider: provider, fixedModel: '', models: [] });
|
|
2202
|
+
fetchSettings(provider).then(function applied(result) {
|
|
2203
|
+
if (result && result.ok === true && result.settings) patch({ models: result.settings.models || [] });
|
|
2204
|
+
});
|
|
2205
|
+
}
|
|
2206
|
+
function save() {
|
|
2207
|
+
if (!settings || saving) return;
|
|
2208
|
+
setSaving(true); setError('');
|
|
2209
|
+
saveSettings({
|
|
2210
|
+
modelPolicy: settings.modelPolicy,
|
|
2211
|
+
fixedProvider: settings.fixedProvider || '',
|
|
2212
|
+
fixedModel: settings.fixedModel || '',
|
|
2213
|
+
modelCalls: settings.modelCalls === true
|
|
2214
|
+
}).then(function applied(result) {
|
|
2215
|
+
setSaving(false);
|
|
2216
|
+
if (!result || result.ok !== true) {
|
|
2217
|
+
const detail = result && typeof result.error === 'string' ? result.error : '';
|
|
2218
|
+
setError(detail ? t('settings.saveError') + ': ' + detail : t('settings.saveError'));
|
|
2219
|
+
return;
|
|
2220
|
+
}
|
|
2221
|
+
setSettings(result.settings || settings);
|
|
2222
|
+
setSaved(true); setError('');
|
|
2223
|
+
});
|
|
2224
|
+
}
|
|
2225
|
+
|
|
2226
|
+
const styleTag = h('style', { key: 'style', 'data-plan-completion-style': 'settings' }, settingsCss());
|
|
2227
|
+
if (status === 'loading') return h(React.Fragment, null, styleTag, h('div', { key: 'loading', className: 'dpc-settings-loading' }, t('settings.loading')));
|
|
2228
|
+
if (status === 'error' || !settings) return h(React.Fragment, null, styleTag, h('div', { key: 'error', className: 'dpc-settings-loading dpc-settings-error' }, t('settings.error')));
|
|
2229
|
+
|
|
2230
|
+
const defaultRoute = settings.defaultSelection ? settings.defaultSelection.provider + '/' + settings.defaultSelection.model : '-';
|
|
2231
|
+
const providers = settings.providers || [];
|
|
2232
|
+
const models = settings.models || [];
|
|
2233
|
+
const row = function row(key, label, desc, control) {
|
|
2234
|
+
return h('div', { key: key, className: 'dpc-settings-row' },
|
|
2235
|
+
h('div', { key: 'main', className: 'dpc-settings-row-main' },
|
|
2236
|
+
h('div', { key: 'label', className: 'dpc-settings-row-label' }, label),
|
|
2237
|
+
desc ? h('div', { key: 'desc', className: 'dpc-settings-row-desc' }, desc) : null),
|
|
2238
|
+
h('div', { key: 'control', className: 'dpc-settings-control' }, control));
|
|
2239
|
+
};
|
|
2240
|
+
|
|
2241
|
+
return h(React.Fragment, null, styleTag,
|
|
2242
|
+
h('div', { key: 'page', className: 'dpc-settings-page' },
|
|
2243
|
+
h('div', { key: 'head', className: 'dpc-settings-head' },
|
|
2244
|
+
h('div', { key: 'title', className: 'dpc-settings-title' }, t('settings.title')),
|
|
2245
|
+
h('div', { key: 'sub', className: 'dpc-settings-sub' }, t('settings.defaultRoute', { value: defaultRoute }))),
|
|
2246
|
+
row('policy', t('settings.model'), t('settings.modelDesc'),
|
|
2247
|
+
h('select', { className: 'dpc-settings-select', value: settings.modelPolicy,
|
|
2248
|
+
onChange: function onPolicy(event) { patch({ modelPolicy: event.target.value }); } },
|
|
2249
|
+
[h('option', { key: 'default', value: 'default' }, t('settings.policy.default')),
|
|
2250
|
+
h('option', { key: 'fixed', value: 'fixed' }, t('settings.policy.fixed')),
|
|
2251
|
+
h('option', { key: 'auto', value: 'auto' }, t('settings.policy.auto'))])),
|
|
2252
|
+
settings.modelPolicy === 'fixed'
|
|
2253
|
+
? row('provider', t('settings.provider'), t('settings.providerDesc'),
|
|
2254
|
+
h('select', { className: 'dpc-settings-select', value: settings.fixedProvider || '',
|
|
2255
|
+
onChange: function onProvider(event) { chooseProvider(event.target.value); } },
|
|
2256
|
+
[h('option', { key: 'empty', value: '' }, '—')].concat(providers.map(function option(p) {
|
|
2257
|
+
return h('option', { key: p.id, value: p.id }, p.name || p.id);
|
|
2258
|
+
}))))
|
|
2259
|
+
: null,
|
|
2260
|
+
settings.modelPolicy === 'fixed'
|
|
2261
|
+
? row('model', t('settings.modelId'), t('settings.modelDesc'),
|
|
2262
|
+
h('select', { className: 'dpc-settings-select', value: settings.fixedModel || '',
|
|
2263
|
+
onChange: function onModel(event) { patch({ fixedModel: event.target.value }); } },
|
|
2264
|
+
[h('option', { key: 'empty', value: '' }, '—')].concat(models.map(function option(m) {
|
|
2265
|
+
return h('option', { key: m.id, value: m.id }, m.name || m.id);
|
|
2266
|
+
}))))
|
|
2267
|
+
: null,
|
|
2268
|
+
row('calls', t('settings.modelCalls'), t('settings.callsDesc'),
|
|
2269
|
+
h('button', { type: 'button', className: 'dpc-settings-toggle', 'data-on': settings.modelCalls === true ? 'true' : 'false',
|
|
2270
|
+
'aria-pressed': settings.modelCalls === true ? 'true' : 'false',
|
|
2271
|
+
onClick: function onCalls() { patch({ modelCalls: settings.modelCalls !== true }); } },
|
|
2272
|
+
h('span', { key: 'knob' }))),
|
|
2273
|
+
h('div', { key: 'footer', className: 'dpc-settings-footer' },
|
|
2274
|
+
error ? h('div', { key: 'e', className: 'dpc-settings-error' }, error)
|
|
2275
|
+
: saved ? h('div', { key: 's', className: 'dpc-settings-status' }, t('settings.saved')) : null,
|
|
2276
|
+
h('button', { key: 'save', type: 'button', className: 'dpc-settings-save', disabled: saving, onClick: save },
|
|
2277
|
+
saving ? t('settings.saving') : t('settings.save')))));
|
|
2278
|
+
}
|
|
2279
|
+
|
|
2311
2280
|
|
|
2312
2281
|
// =====================================================================
|
|
2313
2282
|
// Plugin entry
|
|
@@ -2442,3 +2411,8 @@ window.__ModuleLoader__.load({
|
|
|
2442
2411
|
// hot-reload marker 2026-11-01T13:57Z
|
|
2443
2412
|
|
|
2444
2413
|
|
|
2414
|
+
|
|
2415
|
+
|
|
2416
|
+
|
|
2417
|
+
|
|
2418
|
+
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
# GitHub 发布评估 · 会话计划补全插件(2026-11-02)
|
|
2
2
|
|
|
3
|
-
> 历史文档:以下保留 v0.1.0 的交付/评估/计划记录。**当前最新为 v0.1.
|
|
3
|
+
> 历史文档:以下保留 v0.1.0 的交付/评估/计划记录。**当前最新为 v0.1.6**(计划停更检测 + 建议文本保真 + 核对进度 + 本地计划持久化 + 鉴权/状态一致性/隐私边界修复),详见 [security.md](security.md) 与 [CHANGELOG](../CHANGELOG.md);旧记录中的“无鉴权”、原始诊断字段与独立评审不代表当前实现。
|
|
4
4
|
>
|
|
5
|
+
> v0.1.6 发布记录(2026-11-02):模型设置页(settings.plugins.tab)+ settings 持久化;Tab 建议日志仅本地不发布。tag `v0.1.6`;npm `dsh-plan-completion@0.1.6`;138/138 tests;CI run 41393937067。
|
|
6
|
+
>
|
|
5
7
|
> v0.1.5 发布记录(2026-11-02):计划停更检测——连续 2 次 op=none 后建议变为 `/replan …` 并标记 stale。tag `v0.1.5` + [Release](https://github.com/Xumi0920/dsh-plan-completion/releases/tag/v0.1.5);Actions [run 41391402601](https://github.com/Xumi0920/dsh-plan-completion/actions/runs/41391402601)(四 job 全绿,133/133 tests);npm `dsh-plan-completion@0.1.5`(shasum `c53c6d7ef79d8634913054db79fa9e5b1e86b182`)。
|
|
6
8
|
>
|
|
7
9
|
> v0.1.4 发布记录(2026-11-02):建议文本保真修复(标识符/路径/命令保留 + 语义化截断)。tag `v0.1.4` + [Release](https://github.com/Xumi0920/dsh-plan-completion/releases/tag/v0.1.4);GitHub Actions [run 41389845733](https://github.com/Xumi0920/dsh-plan-completion/actions/runs/41389845733)(四 job 全绿,132/132 tests);npm `dsh-plan-completion@0.1.4`(31 files,shasum `a6f8953445e330081243f9f9d6b429fd4402b341`)。
|
|
@@ -111,3 +113,4 @@ git tag v0.1.0 && git push --tags
|
|
|
111
113
|
|
|
112
114
|
|
|
113
115
|
|
|
116
|
+
|
package/index.js
CHANGED
|
@@ -419,7 +419,7 @@ export function apply(ctx, config = {}) {
|
|
|
419
419
|
}
|
|
420
420
|
}
|
|
421
421
|
|
|
422
|
-
function settingsSnapshot() {
|
|
422
|
+
async function settingsSnapshot(providerHint = '') {
|
|
423
423
|
const selection = services.agentDefaultModel?.currentSelection?.() ?? null
|
|
424
424
|
let providers = []
|
|
425
425
|
try {
|
|
@@ -427,6 +427,14 @@ export function apply(ctx, config = {}) {
|
|
|
427
427
|
} catch {
|
|
428
428
|
providers = []
|
|
429
429
|
}
|
|
430
|
+
let models = []
|
|
431
|
+
let modelsProvider = ''
|
|
432
|
+
try {
|
|
433
|
+
modelsProvider = providerHint || selection?.provider || (Array.isArray(providers) ? providers[0]?.id : '')
|
|
434
|
+
if (modelsProvider && typeof services.llm?.listModels === 'function') {
|
|
435
|
+
models = (await services.llm.listModels(modelsProvider))?.map(m => ({ provider: modelsProvider, id: m?.id ?? '', name: m?.name ?? m?.id ?? '' })) ?? []
|
|
436
|
+
}
|
|
437
|
+
} catch { models = [] }
|
|
430
438
|
return {
|
|
431
439
|
modelPolicy: settings.modelPolicy,
|
|
432
440
|
fixedProvider: settings.fixedProvider,
|
|
@@ -435,6 +443,8 @@ export function apply(ctx, config = {}) {
|
|
|
435
443
|
defaultSelection: selection && selection.provider && selection.model
|
|
436
444
|
? { provider: selection.provider, model: selection.model }
|
|
437
445
|
: null,
|
|
446
|
+
models,
|
|
447
|
+
modelsProvider,
|
|
438
448
|
providers: Array.isArray(providers)
|
|
439
449
|
? providers.map(provider => ({ id: provider?.id ?? '', name: provider?.name ?? provider?.id ?? '' }))
|
|
440
450
|
: [],
|
|
@@ -1182,12 +1192,12 @@ export function apply(ctx, config = {}) {
|
|
|
1182
1192
|
return
|
|
1183
1193
|
}
|
|
1184
1194
|
if (pathname === `${ROUTE_PREFIX}settings` && method === 'GET') {
|
|
1185
|
-
jsonResponse(res, 200, { ok: true, settings: settingsSnapshot() })
|
|
1195
|
+
jsonResponse(res, 200, { ok: true, settings: await settingsSnapshot(url?.searchParams?.get('provider') ?? '') })
|
|
1186
1196
|
return
|
|
1187
1197
|
}
|
|
1188
1198
|
if (pathname === `${ROUTE_PREFIX}settings` && method === 'POST') {
|
|
1189
1199
|
const body = (await readJsonBody(req)) ?? {}
|
|
1190
|
-
const next = { ...settingsSnapshot() }
|
|
1200
|
+
const next = { ...(await settingsSnapshot()) }
|
|
1191
1201
|
if (body.modelPolicy !== undefined) {
|
|
1192
1202
|
const policy = normalizeModelPolicy(body.modelPolicy)
|
|
1193
1203
|
if (policy !== String(body.modelPolicy).trim()) {
|
|
@@ -1226,7 +1236,7 @@ export function apply(ctx, config = {}) {
|
|
|
1226
1236
|
modelCalls: settings.modelCalls,
|
|
1227
1237
|
})
|
|
1228
1238
|
debugLog({ phase: 'settings-updated', modelPolicy: settings.modelPolicy, saved })
|
|
1229
|
-
jsonResponse(res, 200, { ok: true, saved, settings: settingsSnapshot() })
|
|
1239
|
+
jsonResponse(res, 200, { ok: true, saved, settings: await settingsSnapshot() })
|
|
1230
1240
|
return
|
|
1231
1241
|
}
|
|
1232
1242
|
if (pathname === `${ROUTE_PREFIX}state` && method === 'GET') {
|
|
@@ -1649,3 +1659,4 @@ export function apply(ctx, config = {}) {
|
|
|
1649
1659
|
|
|
1650
1660
|
|
|
1651
1661
|
|
|
1662
|
+
|