dsh-advisor 0.4.1 → 0.5.0

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/gateway.js CHANGED
@@ -11,23 +11,24 @@
11
11
  * exactly one plain-object `args` field whose keys are the method parameter
12
12
  * names (`get()` → `{ args: {} }`; `set(patch)` → `{ args: { patch } }`).
13
13
  *
14
- * Data: `get` reads the `AdvisorSettingsBridge` source — the same live
15
- * composed config the runtime reads (schema defaults → plugin-row base →
16
- * settings user layer), resolved through the `resolveAdvisorConfig` hard gate
17
- * (the SSOT for enabled-without-pair disabled-with-reason). `set` validates
18
- * the patch against the `Config` schema first (unknown-key rejection
19
- * unchanged — the settings service itself is non-strict and would accept the
20
- * unknown key), then writes the USER layer in-process via
21
- * `ctx.settings.update` (no exposed-namespace gate on the in-process write —
22
- * the wire-level `exposedNamespaces()` check only guards the apiproxy path),
23
- * and returns the new composed value.
14
+ * Data: `get` reads the `AdvisorSettingsBridge` source — the same live entry
15
+ * config the runtime reads (volatile references unwrapped), resolved through
16
+ * the `resolveAdvisorConfig` hard gate (the SSOT for enabled-without-pair
17
+ * disabled-with-reason). `set` validates the patch against the `Config`
18
+ * schema first (unknown-key rejection unchanged — the settings service itself
19
+ * is non-strict and would accept the unknown key), then writes the advisor
20
+ * ENTRY config in-process via `settings.update(ADVISOR_SETTINGS_NAMESPACE, ...)`
21
+ * (dsh 0.1.7-rc.1: the namespace key IS the profile entry id — the bundle row
22
+ * id `advisor` — and the write lands through the config editor into the
23
+ * Loader, which commits the volatile fields and emits `loader/volatile-update`,
24
+ * re-applying the runtime through the bridge with no restart), and returns
25
+ * the new composed value.
24
26
  *
25
27
  * The settings service is OPTIONAL (no settings service → the bridge source
26
28
  * stays the entry, `get` still works; `set` fails with a clear error — KD-G5
27
29
  * fallback). The gateway captures the service through a conditional
28
- * `ctx.inject(['settings'], ...)` child (the same activation pattern as
29
- * `installAdvisorSettings`), because `ctx.settings` is only resolvable from a
30
- * fiber that declares it.
30
+ * `ctx.inject(['settings'], ...)` child, because `ctx.settings` is only
31
+ * resolvable from a fiber that declares it.
31
32
  *
32
33
  * The returned config is normalized to the typertGateway JSON wire boundary:
33
34
  * absent keys (provider/model/disabledReason) are OMITTED, never
@@ -38,7 +39,12 @@
38
39
  */
39
40
  import { RemoteError, TypertRemoteService } from '@deepseek-ai/dsh-typert-protocol';
40
41
  import { ADVISOR_SETTINGS_NAMESPACE } from './settings.js';
42
+ import { parseModelPair } from './commands.js';
41
43
  import { resolveAdvisorConfig } from './config.js';
44
+ /** Build one tagged data error (keeps every call site's shape identical). */
45
+ export function advisorSessionError(tag, message) {
46
+ return { error: { tag, message } };
47
+ }
42
48
  /**
43
49
  * The host-side `advisor` config gateway (`/api/advisor/get` +
44
50
  * `/api/advisor/set`). Registered as the cordis service key `'advisor'`
@@ -60,14 +66,27 @@ export class AdvisorConfigGateway extends TypertRemoteService {
60
66
  bridge;
61
67
  /** The live settings service once the optional inject child activates. */
62
68
  settings;
69
+ /**
70
+ * The elected owner's session face, resolved LAZILY per request. The
71
+ * reviewer-claiming fiber assigns it after its controller exists (the
72
+ * gateway is constructed before the single-reviewer claim); a `undefined`
73
+ * answer means this fiber owns the service key but not the reviewer role —
74
+ * the session endpoints answer `advisor/unavailable` in data and stay
75
+ * inert (no second controller, no surviving-fiber promotion).
76
+ */
77
+ sessionControl;
63
78
  /**
64
79
  * @param ctx - owning context (the plugin fiber's ctx inside `apply`).
65
80
  * @param bridge - the same `AdvisorSettingsBridge` the runtime reads, so
66
81
  * get/set always operate on the live composed config.
82
+ * @param sessionControl - lazy access to the elected owner's session face
83
+ * (B2); defaults to "absent" so a direct construction without the wiring
84
+ * keeps the session endpoints cleanly unavailable.
67
85
  */
68
- constructor(ctx, bridge) {
86
+ constructor(ctx, bridge, sessionControl = () => undefined) {
69
87
  super(ctx, 'advisor');
70
88
  this.bridge = bridge;
89
+ this.sessionControl = sessionControl;
71
90
  // The settings service is optional (no settings → entry fallback). The
72
91
  // inject child activates only when a settings service is composed, mirroring
73
92
  // installAdvisorSettings' conditional child; the returned disposer mirrors
@@ -90,8 +109,66 @@ export class AdvisorConfigGateway extends TypertRemoteService {
90
109
  return { config: this.readConfig() };
91
110
  }
92
111
  /**
93
- * Validate a config patch and write it to the settings USER layer (live —
94
- * the runtime re-applies through the bridge `onChange`; no restart needed).
112
+ * B2 — the authoritative snapshot for one live session
113
+ * (`/api/advisor/getSession`, args `{ sessionId }`). Read-only: never
114
+ * allocates override state (the snapshot rides the wiring's `sessionStatus`
115
+ * readback). Unknown/disposed targets answer `advisor/session-unknown`
116
+ * without touching the controller; a gateway without an elected owner
117
+ * answers `advisor/unavailable`. Business outcomes live in the returned
118
+ * data (plugin-domain tags) — nothing here throws coded failures and the
119
+ * dsh failure vocabulary stays frozen.
120
+ */
121
+ getSession(sessionId) {
122
+ if (typeof sessionId !== 'string' || sessionId.length === 0) {
123
+ return advisorSessionError('advisor/rejected', 'advisor: getSession requires a non-empty sessionId');
124
+ }
125
+ const face = this.sessionControl();
126
+ if (face === undefined) {
127
+ return advisorSessionError('advisor/unavailable', 'advisor: the session control surface is not owned by this gateway — no elected owner on this fiber');
128
+ }
129
+ return face.getSession(sessionId);
130
+ }
131
+ /**
132
+ * B2 — set (or reset) the per-session reviewer route for one live session
133
+ * (`/api/advisor/setSessionModel`, args `{ sessionId, selection }`).
134
+ * `selection: null` = reset (re-inherit the CURRENT global defaults; never
135
+ * touches the enable override). A non-null selection must be the atomic
136
+ * `{ provider, model }` pair and passes the SAME validation as the command
137
+ * face (`parseModelPair` — spec §5.3); the write itself routes through the
138
+ * elected owner's `AdvisorCommandController` (`setModel`/`resetModel`), so
139
+ * pre-commit `resolveModelInfo` validation (60 s, cancellable, no retry),
140
+ * per-session generation fencing, and the route-change semantics are
141
+ * INHERITED, not reimplemented. Unknown/disposed targets are rejected
142
+ * BEFORE the controller runs — no generation is allocated for a dead
143
+ * session. Returns the post-commit snapshot on success.
144
+ */
145
+ async setSessionModel(sessionId, selection) {
146
+ if (typeof sessionId !== 'string' || sessionId.length === 0) {
147
+ return advisorSessionError('advisor/rejected', 'advisor: setSessionModel requires a non-empty sessionId');
148
+ }
149
+ const face = this.sessionControl();
150
+ if (face === undefined) {
151
+ return advisorSessionError('advisor/unavailable', 'advisor: the session control surface is not owned by this gateway — no elected owner on this fiber');
152
+ }
153
+ // Reset arm: the wire selection is null (JSON has no undefined).
154
+ if (selection === null)
155
+ return face.resetSessionModel(sessionId);
156
+ // Set arm: validate the atomic pair shape BEFORE touching the controller
157
+ // (a malformed selection must not allocate a generation). Non-object and
158
+ // extra-field shapes read as absent keys → the same incomplete-pair
159
+ // rejection the command face reports.
160
+ const pair = typeof selection === 'object' && selection !== null
161
+ ? selection
162
+ : {};
163
+ const validated = parseModelPair(pair.provider, pair.model);
164
+ if (!validated.ok)
165
+ return advisorSessionError('advisor/rejected', `advisor: ${validated.reason}`);
166
+ return face.setSessionModel(sessionId, validated.provider, validated.model);
167
+ }
168
+ /**
169
+ * Validate a config patch and write it to the advisor ENTRY config (live —
170
+ * the Loader commits the volatile fields and the runtime re-applies through
171
+ * the bridge `onChange`; no restart needed).
95
172
  * @param patch - any subset of the config keys; unknown keys are rejected
96
173
  * by the `Config` schema before anything is written.
97
174
  * @returns the NEW composed config after the write.
@@ -116,24 +193,30 @@ export class AdvisorConfigGateway extends TypertRemoteService {
116
193
  }
117
194
  // Wire normalization (QC tri M-2): JSON cannot carry undefined, so a
118
195
  // null-valued key is a third-party client's way of saying "absent" — the
119
- // resolver already treats null as missing on read, but the raw user layer
120
- // must not store it. Drop null values before the write (an all-null patch
121
- // is a no-op, like the empty patch above).
196
+ // resolver already treats null as missing on read, but the raw entry
197
+ // config must not store it. Drop null values before the write (an
198
+ // all-null patch is a no-op, like the empty patch above).
122
199
  const normalized = Object.fromEntries(Object.entries(patch).filter(([, value]) => value !== null));
123
200
  if (Object.keys(normalized).length === 0)
124
201
  return { config: this.readConfig() };
202
+ // The `ns` argument is the PROFILE ENTRY id — the advisor bundle row id
203
+ // (`cordis.patch.yml`), not a registered namespace (0.1.7-rc.1 has no
204
+ // registration; entries with volatile fields surface automatically). The
205
+ // write goes through the config editor into the Loader, which commits the
206
+ // volatile references and emits `loader/volatile-update` — the bridge
207
+ // onChange re-apply closes the loop before this promise settles.
125
208
  await settings.update(ADVISOR_SETTINGS_NAMESPACE, normalized);
126
209
  return { config: this.readConfig() };
127
210
  }
128
211
  /**
129
- * Resolve the live composed config through the hard gate. Containment
130
- * (qc2 W-1): a user layer the resolver rejects (e.g. an unknown key that
131
- * survived the non-strict settings schema) resolves to disabled-with-reason
132
- * carrying the message — the gateway never fails the RPC on a bad user
133
- * layer, and gate semantics hold (no model call can start). S1: when the
134
- * raw source is still readable, the fallback seeds its scalar latches
135
- * (systemPrompt / immuneTurns / maxDeltaMessages) instead of hardcoded
136
- * defaults, so an invalid layer only drops the offending keys.
212
+ * Resolve the live entry config through the hard gate. Containment
213
+ * (qc2 W-1): an entry config the resolver rejects (e.g. an unknown key
214
+ * that survived the non-strict schemastery object merge) resolves to
215
+ * disabled-with-reason carrying the message — the gateway never fails the
216
+ * RPC on a bad config, and gate semantics hold (no model call can start).
217
+ * S1: when the raw source is still readable, the fallback seeds its scalar
218
+ * latches (systemPrompt / immuneTurns / maxDeltaMessages) instead of
219
+ * hardcoded defaults, so an invalid config only drops the offending keys.
137
220
  */
138
221
  readConfig() {
139
222
  let config;
@@ -211,6 +294,34 @@ export function advisorTypertContribution() {
211
294
  ],
212
295
  result: { mode: 'src-json' },
213
296
  },
297
+ // B2 — the per-session model surface (issue #88). Same explicit
298
+ // registration, same direct/src-json dispatch shape; the payload
299
+ // contract stays one plain-object `args` keyed by parameter name
300
+ // (`getSession` → `{ args: { sessionId } }`; `setSessionModel` →
301
+ // `{ args: { sessionId, selection } }`).
302
+ {
303
+ id: 'dsh-advisor#advisor/getSession',
304
+ service: 'advisor',
305
+ namespace: 'advisor',
306
+ method: 'getSession',
307
+ invocation: { kind: 'direct' },
308
+ parameters: [
309
+ { name: 'sessionId', wire: 'sessionId', source: 'json', codec: { mode: 'src-json' } },
310
+ ],
311
+ result: { mode: 'src-json' },
312
+ },
313
+ {
314
+ id: 'dsh-advisor#advisor/setSessionModel',
315
+ service: 'advisor',
316
+ namespace: 'advisor',
317
+ method: 'setSessionModel',
318
+ invocation: { kind: 'direct' },
319
+ parameters: [
320
+ { name: 'sessionId', wire: 'sessionId', source: 'json', codec: { mode: 'src-json' } },
321
+ { name: 'selection', wire: 'selection', source: 'json', codec: { mode: 'src-json' } },
322
+ ],
323
+ result: { mode: 'src-json' },
324
+ },
214
325
  ],
215
326
  };
216
327
  }
@@ -1 +1 @@
1
- {"version":3,"file":"gateway.js","sourceRoot":"","sources":["../src/gateway.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AAKH,OAAO,EAAE,WAAW,EAAE,mBAAmB,EAAE,MAAM,kCAAkC,CAAA;AACnF,OAAO,EAAE,0BAA0B,EAAE,MAAM,eAAe,CAAA;AAE1D,OAAO,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAA;AAMlD;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,OAAO,oBAAqB,SAAQ,mBAAmB;IAC1C,MAAM,CAAuB;IAC9C,0EAA0E;IAClE,QAAQ,CAA8B;IAE9C;;;;OAIG;IACH,YAAY,GAAY,EAAE,MAA6B;QACrD,KAAK,CAAC,GAAG,EAAE,SAAS,CAAC,CAAA;QACrB,IAAI,CAAC,MAAM,GAAG,MAAM,CAAA;QACpB,uEAAuE;QACvE,6EAA6E;QAC7E,2EAA2E;QAC3E,2EAA2E;QAC3E,4EAA4E;QAC5E,2BAA2B;QAC3B,GAAG,CAAC,MAAM,CAAC,CAAC,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,EAAE;YAChC,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAA;YAC7B,OAAO,GAAG,EAAE;gBACV,IAAI,CAAC,QAAQ,GAAG,SAAS,CAAA;YAC3B,CAAC,CAAA;QACH,CAAC,CAAC,CAAA;IACJ,CAAC;IAED;;;;OAIG;IACH,GAAG;QACD,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,UAAU,EAAE,EAAE,CAAA;IACtC,CAAC;IAED;;;;;;;;OAQG;IACH,KAAK,CAAC,GAAG,CAAC,KAAyB;QACjC,uEAAuE;QACvE,qEAAqE;QACrE,yEAAyE;QACzE,oBAAoB,CAAC,KAAK,CAAC,CAAA;QAC3B,oEAAoE;QACpE,2CAA2C;QAC3C,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,UAAU,EAAE,EAAE,CAAA;QACzE,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAA;QAC9B,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;YAC3B,sEAAsE;YACtE,kEAAkE;YAClE,mEAAmE;YACnE,MAAM,IAAI,WAAW,CAAC,kBAAkB,EAAE,4EAA4E,EAAE,EAAE,CAAC,CAAA;QAC7H,CAAC;QACD,qEAAqE;QACrE,yEAAyE;QACzE,0EAA0E;QAC1E,0EAA0E;QAC1E,2CAA2C;QAC3C,MAAM,UAAU,GAAG,MAAM,CAAC,WAAW,CACnC,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,KAAK,KAAK,IAAI,CAAC,CAC5D,CAAA;QACD,IAAI,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,UAAU,EAAE,EAAE,CAAA;QAC9E,MAAM,QAAQ,CAAC,MAAM,CAAC,0BAA0B,EAAE,UAAU,CAAC,CAAA;QAC7D,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,UAAU,EAAE,EAAE,CAAA;IACtC,CAAC;IAED;;;;;;;;;OASG;IACK,UAAU;QAChB,IAAI,MAA6B,CAAA;QACjC,IAAI,CAAC;YACH,MAAM,GAAG,oBAAoB,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,CAAA;QACrD,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,GAA8B,CAAA;YAClC,IAAI,CAAC;gBACH,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAA;YAC5B,CAAC;YAAC,MAAM,CAAC;gBACP,6DAA6D;YAC/D,CAAC;YACD,MAAM,GAAG;gBACP,OAAO,EAAE,KAAK;gBACd,YAAY,EAAE,GAAG,EAAE,YAAY,IAAI,EAAE;gBACrC,WAAW,EAAE,GAAG,EAAE,WAAW,IAAI,CAAC;gBAClC,gBAAgB,EAAE,GAAG,EAAE,gBAAgB,IAAI,EAAE;gBAC7C,cAAc,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;aACvE,CAAA;QACH,CAAC;QACD,8DAA8D;QAC9D,wEAAwE;QACxE,MAAM,IAAI,GAA4B;YACpC,OAAO,EAAE,MAAM,CAAC,OAAO;YACvB,YAAY,EAAE,MAAM,CAAC,YAAY;YACjC,WAAW,EAAE,MAAM,CAAC,WAAW;YAC/B,gBAAgB,EAAE,MAAM,CAAC,gBAAgB;SAC1C,CAAA;QACD,IAAI,MAAM,CAAC,QAAQ,KAAK,SAAS;YAAE,IAAI,CAAC,QAAQ,GAAG,MAAM,CAAC,QAAQ,CAAA;QAClE,IAAI,MAAM,CAAC,KAAK,KAAK,SAAS;YAAE,IAAI,CAAC,KAAK,GAAG,MAAM,CAAC,KAAK,CAAA;QACzD,IAAI,MAAM,CAAC,cAAc,KAAK,SAAS;YAAE,IAAI,CAAC,cAAc,GAAG,MAAM,CAAC,cAAc,CAAA;QACpF,OAAO,IAAwC,CAAA;IACjD,CAAC;CACF;AAED;;;;;;;;;;GAUG;AACH,MAAM,UAAU,yBAAyB;IACvC,OAAO;QACL,OAAO,EAAE,aAAa;QACtB,IAAI,EAAE,MAAM;QACZ,OAAO,EAAE,EAAE;QACX,KAAK,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE;QAChD,WAAW,EAAE;YACX;gBACE,EAAE,EAAE,yBAAyB;gBAC7B,OAAO,EAAE,SAAS;gBAClB,SAAS,EAAE,SAAS;gBACpB,MAAM,EAAE,KAAK;gBACb,UAAU,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;gBAC9B,UAAU,EAAE,EAAE;gBACd,MAAM,EAAE,EAAE,IAAI,EAAE,UAAU,EAAE;aAC7B;YACD;gBACE,EAAE,EAAE,yBAAyB;gBAC7B,OAAO,EAAE,SAAS;gBAClB,SAAS,EAAE,SAAS;gBACpB,MAAM,EAAE,KAAK;gBACb,UAAU,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;gBAC9B,UAAU,EAAE;oBACV,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,UAAU,EAAE,EAAE;iBAC9E;gBACD,MAAM,EAAE,EAAE,IAAI,EAAE,UAAU,EAAE;aAC7B;SACF;KACF,CAAA;AACH,CAAC"}
1
+ {"version":3,"file":"gateway.js","sourceRoot":"","sources":["../src/gateway.ts"],"names":[],"mappings":"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"}
package/lib/index.d.ts CHANGED
@@ -31,11 +31,11 @@
31
31
  * (`ctx.get('tuiSettingsSections') !== undefined`), so the hint names the TUI
32
32
  * `/settings` Advisor section as a write path exactly while the seam is
33
33
  * mounted; the readback itself stays session-less and read-only.
34
- * Settings (plan dsh-advisor-settings-n2): the plugin-row config is the
35
- * composition base of the `advisor` settings namespace (`src/settings.ts`),
36
- * read live through the bridge source; committed settings edits re-apply
37
- * derived state (immuneTurns / maxDeltaMessages / per-session runtimes)
38
- * without a restart.
34
+ * Settings (plan dsh-advisor-settings-n2): the plugin-row entry config's six
35
+ * live fields are schema-volatile (`src/config.ts`), read live through the
36
+ * bridge source (`src/settings.ts`); committed volatile edits (Loader
37
+ * `loader/volatile-update`) re-apply derived state (immuneTurns /
38
+ * maxDeltaMessages / per-session runtimes) without a restart.
39
39
  * Config gateway (plan dsh-advisor-settings-gateway-n5): `apply` also
40
40
  * registers the host-side `AdvisorConfigGateway` (`src/gateway.ts`) — the
41
41
  * `/api/advisor/get` + `/api/advisor/set` endpoints (explicit