@yanglaofish/dsh-proxy-pro 1.1.0 → 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/lib/proxy-core.js CHANGED
@@ -21,42 +21,67 @@ export const DEFAULT_ENTRY_ID = 'dsh-proxy-pro'
21
21
 
22
22
  /**
23
23
  * Resolve this plugin's composition entry id — the settings namespace on
24
- * dsh >= 0.2 (LESSONS §33). Prefers the row whose fiber IS this context, then
25
- * the known bundle id; undefined when the editor cannot be read.
24
+ * dsh >= 0.2 (LESSONS §33). Core plugins read it straight off the fiber
25
+ * (`ctx.fiber.entry?.options.id`, e.g. dsh-experimental-speech-to-text); the
26
+ * config-editor row match is the fallback, then the known bundle id.
26
27
  */
27
- export function discoverEntryId(configEditor, ctx) {
28
+ export function resolveEntryId(ctx, configEditor, fallback = DEFAULT_ENTRY_ID) {
29
+ const direct = ctx?.fiber?.entry?.options?.id
30
+ if (typeof direct === 'string' && direct.length > 0) return direct
28
31
  try {
29
32
  const rows = configEditor?.configuration?.() ?? []
30
33
  const own = rows.find((row) => row?.entry?.fiber === ctx?.fiber)
31
- ?? rows.find((row) => row?.entry?.options?.id === DEFAULT_ENTRY_ID)
34
+ ?? rows.find((row) => row?.entry?.options?.id === fallback)
32
35
  const id = own?.entry?.options?.id
33
- return typeof id === 'string' && id.length > 0 ? id : undefined
36
+ return typeof id === 'string' && id.length > 0 ? id : fallback
34
37
  } catch {
35
- return undefined
38
+ return fallback
36
39
  }
37
40
  }
38
41
 
39
42
  /**
40
- * Effective config of one entry: the composed layers, then the profile patch.
41
- * Every Config field is a scalar, so a shallow merge is exact.
43
+ * Read one resolved Config field.
44
+ *
45
+ * Cordis' documented volatile contract (vendor loader README, LESSONS §36):
46
+ * a field declared `.volatile()` resolves to a `Volatile<T>` **reference**
47
+ * whose live value is read with `.get()`; Loader commits volatile-only edits
48
+ * into that same reference. Older cores (and our `.volatile()` guard on old
49
+ * schemastery) hand back a plain value, so both shapes are accepted.
42
50
  */
43
- export function readEntryConfig(configEditor, entryId, fallback) {
44
- try {
45
- const rows = configEditor?.configuration?.() ?? []
46
- const own = rows.find((row) => row?.entry?.options?.id === entryId)
47
- if (own !== undefined) return { ...fallback, ...(own.inherited ?? {}), ...(own.override ?? {}) }
48
- } catch {
49
- /* fall through to the apply-time config */
51
+ export function readConfigField(config, field, fallback) {
52
+ const value = config?.[field]
53
+ if (value !== null && typeof value === 'object' && typeof value.get === 'function') {
54
+ try {
55
+ const live = value.get()
56
+ return live === undefined ? fallback : live
57
+ } catch {
58
+ return fallback
59
+ }
60
+ }
61
+ return value === undefined ? fallback : value
62
+ }
63
+
64
+ /** The plain, serializable configuration the tools/client/API consume. */
65
+ export function readProxyConfig(config) {
66
+ return {
67
+ enabled: readConfigField(config, 'enabled', false) === true,
68
+ mode: readConfigField(config, 'mode', 'none'),
69
+ customUrl: readConfigField(config, 'customUrl', ''),
70
+ noProxy: readConfigField(config, 'noProxy', ''),
71
+ systemPollMs: readConfigField(config, 'systemPollMs', 0),
50
72
  }
51
- return fallback
52
73
  }
53
74
 
54
75
  /**
55
76
  * Editable configuration payload for the client panel (`/config` API). The
56
77
  * browser cannot reach the settings transport on dsh >= 0.2, so the host hands
57
78
  * the panel exactly the fields it edits (LESSONS §33).
79
+ *
80
+ * @param resolved - the live configuration (see {@link readProxyConfig}).
81
+ * @param writable - whether this composition can persist a write at all; a
82
+ * read-only composition must not offer enabled controls (review fix).
58
83
  */
59
- export function configPayload(resolved) {
84
+ export function configPayload(resolved, writable = true) {
60
85
  return {
61
86
  config: {
62
87
  enabled: resolved?.enabled === true,
@@ -65,7 +90,7 @@ export function configPayload(resolved) {
65
90
  noProxy: resolved?.noProxy ?? '',
66
91
  systemPollMs: resolved?.systemPollMs ?? 0,
67
92
  },
68
- writable: true,
93
+ writable: writable === true,
69
94
  }
70
95
  }
71
96
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yanglaofish/dsh-proxy-pro",
3
- "version": "1.1.0",
3
+ "version": "2.0.1",
4
4
  "description": "DSH proxy manager: route model requests, web fetches and spawned tools through the Windows system proxy or a custom address; per-URL route diagnosis, one-click toggle from the conversation header, a dedicated Settings page, and keepalive-aware 407 hints.",
5
5
  "type": "module",
6
6
  "main": "./lib/index.js",
@@ -40,10 +40,10 @@
40
40
  },
41
41
  "peerDependencies": {
42
42
  "@deepseek-ai/cordis": "^4.0.0",
43
- "@deepseek-ai/dsh-http-proxy": ">=0.1.5-rc.2 <0.3.0",
44
- "@deepseek-ai/dsh-settings": ">=0.1.5-rc.2 <0.3.0",
45
- "@deepseek-ai/dsh-system-prompt": ">=0.1.5-rc.2 <0.3.0",
46
- "@deepseek-ai/dsh-tools": ">=0.1.5-rc.2 <0.3.0",
43
+ "@deepseek-ai/dsh-http-proxy": ">=0.2.0-rc.2 <0.3.0",
44
+ "@deepseek-ai/dsh-settings": ">=0.2.0-rc.2 <0.3.0",
45
+ "@deepseek-ai/dsh-system-prompt": ">=0.2.0-rc.2 <0.3.0",
46
+ "@deepseek-ai/dsh-tools": ">=0.2.0-rc.2 <0.3.0",
47
47
  "@deepseek-ai/schemastery": "^3.18.0"
48
48
  },
49
49
  "dsh": {