@ran-sh/dsh-crew 1.5.1 → 1.6.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.
@@ -4,7 +4,7 @@ import { PanelHeader, PanelStyles } from './panel-chrome';
4
4
  // DSH Crew QUICK CONTROLS panel for the official 3080 surface.
5
5
  //
6
6
  // Narrow by design: only the user-facing master switch, flash/pro model
7
- // priority lists and vision/imagegen toggles — all other operations belong
7
+ // priority lists — all other operations belong
8
8
  // to the native 3210 full control plane. Talks only to the quick endpoints
9
9
  // (/_dsh/dsh-crew/quick-config, /quick-status). Runtime maintenance stays on 3210.
10
10
 
@@ -17,17 +17,9 @@ type QuickConfig = {
17
17
  subagents_enabled?: boolean;
18
18
  flash_model_priority?: ModelEntry[];
19
19
  pro_model_priority?: ModelEntry[];
20
- vision_enabled?: boolean;
21
- imagegen_enabled?: boolean;
22
- vision_provider?: string;
23
- imagegen_provider?: string;
24
20
  };
25
21
 
26
22
  const RESTART_KEYS = new Set([
27
- 'vision_enabled',
28
- 'imagegen_enabled',
29
- 'vision_provider',
30
- 'imagegen_provider',
31
23
  ]);
32
24
 
33
25
  const T = {
@@ -48,10 +40,7 @@ const T = {
48
40
  flash: 'Worker / Flash',
49
41
  pro: 'Reviewer / Pro',
50
42
  addModel: '+ 添加模型',
51
- multimodal: '多模态',
52
- vision: '视觉',
53
- imagegen: '生图',
54
- provider: 'Provider',
43
+ provider: 'Provider',
55
44
  applyRestart: '应用并重启 Crew',
56
45
  savedNeedsRestart: '配置已保存 · 需要重启 Crew 才会生效',
57
46
  saved: '已保存',
@@ -76,9 +65,6 @@ const T = {
76
65
  flash: 'Worker / Flash',
77
66
  pro: 'Reviewer / Pro',
78
67
  addModel: '+ Add model',
79
- multimodal: 'Multimodal',
80
- vision: 'Vision',
81
- imagegen: 'Imagegen',
82
68
  provider: 'Provider',
83
69
  applyRestart: 'Apply & restart Crew',
84
70
  savedNeedsRestart: 'Saved · restart Crew to take effect',
@@ -167,15 +153,11 @@ export function QuickPanel({ ctx }: { ctx: any }) {
167
153
  } finally { setBusy(false); }
168
154
  }, [t]);
169
155
 
170
- const toggle = (key: 'subagents_enabled' | 'vision_enabled' | 'imagegen_enabled', value: boolean) => {
156
+ const toggle = (key: 'subagents_enabled', value: boolean) => {
171
157
  setConfig((c) => ({ ...(c ?? {}), [key]: value }));
172
158
  void patch({ [key]: value } as QuickConfig);
173
159
  };
174
160
 
175
- const setProvider = (key: 'vision_provider' | 'imagegen_provider', value: string) => {
176
- setConfig((c) => ({ ...(c ?? {}), [key]: value }));
177
- void patch({ [key]: value } as QuickConfig);
178
- };
179
161
 
180
162
  const moveModel = (listKey: 'flash_model_priority' | 'pro_model_priority', index: number, dir: -1 | 1) => {
181
163
  const list = [...((config?.[listKey] as ModelEntry[] | undefined) ?? [])];
@@ -268,23 +250,6 @@ export function QuickPanel({ ctx }: { ctx: any }) {
268
250
  </div>
269
251
  {modelList('flash_model_priority', t.flash)}
270
252
  {modelList('pro_model_priority', t.pro)}
271
- <details className="crew-quick-group">
272
- <summary><strong>{t.multimodal}</strong><span className="crew-quick-count">{t.vision} / {t.imagegen}</span></summary>
273
- <div className="crew-quick-content">
274
- <div className="crew-quick-media">
275
- <label><input type="checkbox" disabled={busy} checked={config.vision_enabled === true}
276
- onChange={(e) => toggle('vision_enabled', e.target.checked)} /> {t.vision}</label>
277
- <input className="crew-quick-input" aria-label={`${t.vision} Provider`} placeholder={t.provider} disabled={busy} defaultValue={config.vision_provider ?? ''} key={`vision-${config.vision_provider ?? ''}`}
278
- onBlur={(e) => setProvider('vision_provider', e.target.value)} />
279
- </div>
280
- <div className="crew-quick-media">
281
- <label><input type="checkbox" disabled={busy} checked={config.imagegen_enabled === true}
282
- onChange={(e) => toggle('imagegen_enabled', e.target.checked)} /> {t.imagegen}</label>
283
- <input className="crew-quick-input" aria-label={`${t.imagegen} Provider`} placeholder={t.provider} disabled={busy} defaultValue={config.imagegen_provider ?? ''}
284
- onBlur={(e) => setProvider('imagegen_provider', e.target.value)} />
285
- </div>
286
- </div>
287
- </details>
288
253
  {restartPending && (
289
254
  <div className="crew-quick-row">
290
255
  <a className="crew-quick-btn primary" href={FULL} target="_blank" rel="noopener noreferrer">{t.openFull}</a>
@@ -26,7 +26,7 @@ export function classifyCrewSurface({ bridgeStatus, runtime } = {}) {
26
26
  /**
27
27
  * Surface capability model. The NATIVE 3210 Crew harness is the single full
28
28
  * control plane; the OFFICIAL 3080 surface is a narrow quick-controls panel
29
- * (total switch, flash/pro model priority, vision/imagegen toggles) plus a
29
+ * (total switch and the flash/pro model priority lists) plus a
30
30
  * deep link back to 3210. Unknown surfaces get diagnostics only — never write
31
31
  * authority. This replaces the old binary full-vs-minimal assumption.
32
32
  */
package/src/hub/index.mjs CHANGED
@@ -12,7 +12,6 @@ import {
12
12
  normalizeGlobalConfig,
13
13
  chooseDefaultTier,
14
14
  normalizeWorkerProviderMode,
15
- getMultimodalRegistrationPlan,
16
15
  canDispatchRole,
17
16
  resolveModelPolicy,
18
17
  resolveRoleTierHint,
@@ -112,10 +111,6 @@ export const QUICK_CONFIG_KEYS = Object.freeze([
112
111
  'subagents_enabled',
113
112
  'flash_model_priority',
114
113
  'pro_model_priority',
115
- 'vision_enabled',
116
- 'imagegen_enabled',
117
- 'vision_provider',
118
- 'imagegen_provider',
119
114
  ]);
120
115
  const LEGACY_TIER_MODELS = { flash: 'deepseek-v4-flash', pro: 'deepseek-v4-pro' };
121
116
  // Local copy (the hub must not import jobs.mjs, which pulls the DSH SDK into
@@ -1366,39 +1361,6 @@ export async function apply(ctx) {
1366
1361
  while (credentialPurgePlans.size > 32) credentialPurgePlans.delete(credentialPurgePlans.keys().next().value);
1367
1362
  };
1368
1363
 
1369
- // Multimodal bridge: register describe_image / generate_image for the DS
1370
- // model. Config is read per call so settings-page edits apply live; the
1371
- // capability switches (vision_enabled / imagegen_enabled) decide which tools
1372
- // are registered at plugin boot, so toggling them takes effect on restart.
1373
- try {
1374
- const { createMultimodalTools } = await import('../multimodal.mjs');
1375
- const { readGlobalConfig } = await import('../install/install.mjs');
1376
- const plan = getMultimodalRegistrationPlan(normalizeGlobalConfig(readGlobalConfig()));
1377
- for (const tool of createMultimodalTools(() => readGlobalConfig())) {
1378
- if (!plan.tools[tool.name]) {
1379
- ctx.logger?.info?.(`dsh-crew: ${tool.name} not registered (disabled by capability switch)`);
1380
- continue;
1381
- }
1382
- disposers.push(ctx.effect(() => ctx.tools.register(tool), `dsh-crew: ${tool.name} tool`));
1383
- }
1384
- } catch (err) {
1385
- ctx.logger?.warn?.(`dsh-crew: multimodal tools unavailable: ${err?.message ?? err}`);
1386
- }
1387
-
1388
- // Vision route: image paste on the text-only DS models (admission adapter +
1389
- // pre-step transcription). Installed only while Crew Vision is enabled.
1390
- try {
1391
- const { installVisionRoute } = await import('../vision-route.mjs');
1392
- const { readGlobalConfig } = await import('../install/install.mjs');
1393
- if (getMultimodalRegistrationPlan(normalizeGlobalConfig(readGlobalConfig())).visionRoute) {
1394
- disposers.push(installVisionRoute(ctx, () => readGlobalConfig()));
1395
- } else {
1396
- ctx.logger?.info?.('dsh-crew: vision route not installed (Crew Vision disabled by capability switch)');
1397
- }
1398
- } catch (err) {
1399
- ctx.logger?.warn?.(`dsh-crew: vision route unavailable: ${err?.message ?? err}`);
1400
- }
1401
-
1402
1364
  ctx.inject(['webServer'], (webCtx) => {
1403
1365
  const webServer = webCtx.webServer;
1404
1366
  const disposers = [];
@@ -2676,43 +2638,6 @@ export async function apply(ctx) {
2676
2638
  },
2677
2639
  }));
2678
2640
 
2679
- disposers.push(webServer.register({
2680
- kind: 'exact', path: `${ROUTE_BASE}/vision-models`,
2681
- handler: async (req, res) => {
2682
- if (!isLoopbackRequest(req)) return sendJson(res, 403, { ok: false, error: 'loopback only' });
2683
- try {
2684
- const url = new URL(req.url, 'http://localhost');
2685
- const provider = url.searchParams.get('provider');
2686
- const force = url.searchParams.get('refresh') === '1';
2687
- const lang = url.searchParams.get('lang');
2688
- adoptLang(lang);
2689
- const { listVisionModels } = await import('../multimodal.mjs');
2690
- const { readGlobalConfig } = await import('../install/install.mjs');
2691
- return sendJson(res, 200, { ok: true, models: await listVisionModels(provider, force, () => readGlobalConfig(), lang) });
2692
- } catch (err) {
2693
- return sendJson(res, 500, { ok: false, error: err?.message ?? String(err) });
2694
- }
2695
- },
2696
- }));
2697
-
2698
- disposers.push(webServer.register({
2699
- kind: 'exact', path: `${ROUTE_BASE}/provider-test`,
2700
- handler: async (req, res) => {
2701
- if (!isLoopbackRequest(req)) return sendJson(res, 403, { ok: false, error: 'loopback only' });
2702
- if (req.method !== 'POST') return sendJson(res, 405, { ok: false, error: 'POST only' });
2703
- try {
2704
- // The entry comes from the panel form so unsaved edits can be probed.
2705
- const entry = await readBody(req);
2706
- adoptLang(entry?.lang);
2707
- const { testProvider } = await import('../multimodal.mjs');
2708
- const result = await testProvider(entry, entry?.lang);
2709
- return sendJson(res, 200, { ok: true, result });
2710
- } catch (err) {
2711
- return sendJson(res, 500, { ok: false, error: err?.message ?? String(err) });
2712
- }
2713
- },
2714
- }));
2715
-
2716
2641
  disposers.push(webServer.register({
2717
2642
  kind: 'exact', path: `${ROUTE_BASE}/install/status`,
2718
2643
  handler: async (req, res) => {
@@ -2761,7 +2686,7 @@ export async function apply(ctx) {
2761
2686
  return () => { for (const d of disposers.reverse()) d(); };
2762
2687
  });
2763
2688
 
2764
- ctx.logger?.info?.('dsh-crew hub mounted (jobs API + installer endpoints + multimodal tools)');
2689
+ ctx.logger?.info?.('dsh-crew hub mounted (jobs API + installer endpoints)');
2765
2690
  return async () => {
2766
2691
  for (const d of disposers.reverse()) { try { d(); } catch {} }
2767
2692
  await hub.dispose();
package/src/i18n.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  // Server-side locale for strings that reach the user: connectivity-test
2
- // reports, model-list labels, error messages and the vision transcription.
2
+ // reports, model-list labels and error messages.
3
3
  //
4
4
  // The panel owns the authoritative locale (DSH's setting may be absent, in
5
5
  // which case the browser decides), so it passes `lang` with every request and