@ai-matrx/agents 0.59.194 → 0.59.196

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.
@@ -1,6 +1,6 @@
1
1
  import { components } from '@ai-matrx/api/types';
2
2
  import * as React from 'react';
3
- import { JSX, ReactNode } from 'react';
3
+ import { ReactNode } from 'react';
4
4
 
5
5
  /**
6
6
  * Agent Settings — Type Definitions
@@ -166,16 +166,48 @@ interface SettingsStore {
166
166
  cancelModelSwitch(agentId: string): void;
167
167
  }
168
168
 
169
- interface SettingControlInputProps {
170
- /** Setting key (snake_case) — used for ids and response_format handling. */
171
- settingKey: string;
172
- control: ControlDefinition;
173
- value: unknown;
174
- onChange: (value: unknown) => void;
175
- disabled?: boolean;
176
- id?: string;
169
+ /**
170
+ * Model Settings Catalog — the single source of truth for the STANDARD
171
+ * settings list, and the one chokepoint that decides which keys it contains.
172
+ *
173
+ * ── The model (two distinct surfaces) ────────────────────────────────────────
174
+ * 1. STANDARD list — ONLY the keys the selected model explicitly declares in
175
+ * its `controls` config (i.e. the parameters this model actually supports).
176
+ * `buildSettingsRows()` returns exactly these, grouped + ordered. Catalog
177
+ * keys the model does not declare are NOT shown here.
178
+ * 2. CAUTION surface — settings the agent has SET that the model does NOT
179
+ * support. These are never hidden: they are flagged as "not valid for this
180
+ * model" and made repairable by the validation layer (the IssueTable, fed
181
+ * by the `unsupported_by_model` rule). They do NOT belong in the standard
182
+ * list — that is exactly the "showing all possible keys" bug.
183
+ *
184
+ * The catalog exists so the standard list's labels, grouping and order live
185
+ * in ONE place (previously copy-pasted as `textModelSettings` /
186
+ * `booleanSettings` / ... into three components, each filtering by
187
+ * `getControl(key)` inline — which drifted and regressed). Components map over
188
+ * `buildSettingsRows()`; they must not filter by model themselves (ESLint
189
+ * enforces). The original recurring bug — set values silently dropped when a
190
+ * model didn't support them — is fixed by the CAUTION surface, not by dumping
191
+ * every key into the standard list.
192
+ *
193
+ * Guardrail: `settings-catalogue.test.ts` asserts the standard list contains
194
+ * ONLY supported keys (never the full catalog), and `unsupported-by-model.
195
+ * test.ts` asserts set-but-unsupported keys surface in the caution layer.
196
+ */
197
+
198
+ type SettingsGroupId = "text" | "featureFlags" | "imageVideo" | "audio" | "other";
199
+ interface SettingsRow {
200
+ key: string;
201
+ label: string;
202
+ group: SettingsGroupId;
203
+ /** The model's control definition for this key. Standard rows are always
204
+ * supported, so this is present; typed nullable for consumer convenience. */
205
+ control: ControlDefinition | null;
206
+ /** Always true for rows returned by buildSettingsRows (standard = supported). */
207
+ supported: boolean;
208
+ /** True when the current settings hold a non-null value for this key. */
209
+ hasValue: boolean;
177
210
  }
178
- declare function SettingControlInput({ settingKey, control, value, onChange, disabled, id, }: SettingControlInputProps): React.JSX.Element;
179
211
 
180
212
  /**
181
213
  * UI Gates — canonical model-gated UI flags.
@@ -219,72 +251,35 @@ interface UiGates {
219
251
  declare const UI_GATE_EDITABLE_KEYS: readonly ["image_urls", "file_urls", "youtube_videos"];
220
252
  type UiGateEditableKey = (typeof UI_GATE_EDITABLE_KEYS)[number];
221
253
 
222
- /**
223
- * THE input-capabilities group (agent core B4): the per-agent / per-run UI gates (image URLs,
224
- * file URLs, YouTube), drawn on THE model-settings panel's row frame so it lines up with the
225
- * settings above it — in the builder and in every override screen alike. Controlled: the
226
- * caller owns `values` and decides what a change means (the builder writes the agent's
227
- * ui_gates; a conversation writes its own capability overrides, each with a reset).
228
- */
229
-
230
- interface InputCapabilitiesEditorProps {
231
- values: UiGates;
232
- onChange: (key: UiGateEditableKey, value: boolean) => void;
233
- /** Keys the caller changed itself; each gets a reset to what it inherits. */
234
- changedKeys?: ReadonlySet<UiGateEditableKey> | undefined;
235
- onReset?: ((key: UiGateEditableKey) => void) | undefined;
236
- /** The reset button's words. Default "Reset to agent". */
237
- resetLabel?: string | undefined;
238
- /** Said under the rows when saving failed. */
239
- error?: string | null | undefined;
240
- idPrefix: string;
241
- title?: string;
242
- disabled?: boolean;
254
+ /** One model a host runs on the person's own computer. */
255
+ interface LocalModelEntry {
256
+ /** The value `onValueChange` receives (the conversation's model override). */
257
+ id: string;
258
+ name: string;
259
+ /** Brand glyph key (e.g. "Meta"); absent draws the neutral glyph. */
260
+ maker?: string | null;
261
+ contextWindow?: number | null;
262
+ /** The computer cannot hold it today: the row is dimmed and says why, but stays pickable. */
263
+ needsMoreMemory?: boolean;
243
264
  }
244
- /** Shared builder/runtime editor for frontend-only run capabilities. */
245
- declare function InputCapabilitiesEditor({ values, onChange, changedKeys, onReset, resetLabel, error, idPrefix, title, disabled, }: InputCapabilitiesEditorProps): JSX.Element;
246
-
247
265
  /**
248
- * Model Settings Catalog — the single source of truth for the STANDARD
249
- * settings list, and the one chokepoint that decides which keys it contains.
250
- *
251
- * ── The model (two distinct surfaces) ────────────────────────────────────────
252
- * 1. STANDARD list — ONLY the keys the selected model explicitly declares in
253
- * its `controls` config (i.e. the parameters this model actually supports).
254
- * `buildSettingsRows()` returns exactly these, grouped + ordered. Catalog
255
- * keys the model does not declare are NOT shown here.
256
- * 2. CAUTION surface — settings the agent has SET that the model does NOT
257
- * support. These are never hidden: they are flagged as "not valid for this
258
- * model" and made repairable by the validation layer (the IssueTable, fed
259
- * by the `unsupported_by_model` rule). They do NOT belong in the standard
260
- * list — that is exactly the "showing all possible keys" bug.
261
- *
262
- * The catalog exists so the standard list's labels, grouping and order live
263
- * in ONE place (previously copy-pasted as `textModelSettings` /
264
- * `booleanSettings` / ... into three components, each filtering by
265
- * `getControl(key)` inline — which drifted and regressed). Components map over
266
- * `buildSettingsRows()`; they must not filter by model themselves (ESLint
267
- * enforces). The original recurring bug — set values silently dropped when a
268
- * model didn't support them — is fixed by the CAUTION surface, not by dumping
269
- * every key into the standard list.
270
- *
271
- * Guardrail: `settings-catalogue.test.ts` asserts the standard list contains
272
- * ONLY supported keys (never the full catalog), and `unsupported-by-model.
273
- * test.ts` asserts set-but-unsupported keys surface in the caution layer.
266
+ * The host's local-model source (a store: `getModels` + `subscribe`, like the catalog). The picker
267
+ * draws its models as one "On this computer" group marked local. Start/Stop and getting more
268
+ * models stay the host's own screens.
274
269
  */
275
-
276
- type SettingsGroupId = "text" | "featureFlags" | "imageVideo" | "audio" | "other";
277
- interface SettingsRow {
278
- key: string;
279
- label: string;
280
- group: SettingsGroupId;
281
- /** The model's control definition for this key. Standard rows are always
282
- * supported, so this is present; typed nullable for consumer convenience. */
283
- control: ControlDefinition | null;
284
- /** Always true for rows returned by buildSettingsRows (standard = supported). */
285
- supported: boolean;
286
- /** True when the current settings hold a non-null value for this key. */
287
- hasValue: boolean;
270
+ interface LocalModelsPort {
271
+ /** Must return the SAME array until the list changes (it is a store snapshot). */
272
+ getModels(): readonly LocalModelEntry[];
273
+ subscribe(listener: () => void): () => void;
274
+ /** Group heading. Default "On this computer". */
275
+ groupLabel?: string;
276
+ /**
277
+ * Open the local model in its own private conversation (the host's Confidential Chat), instead
278
+ * of switching this conversation to it. Present = a local pick calls ONLY this: the cloud value
279
+ * and the class pin stay untouched, and no draft or context is carried. Absent = the pick reports
280
+ * the id through `onValueChange` (the override path).
281
+ */
282
+ open?(id: string): void;
288
283
  }
289
284
 
290
285
  /**
@@ -350,9 +345,48 @@ interface SettingsWriteTarget {
350
345
  unbind?(key: string, control: ControlDefinition | null): void;
351
346
  /** Drop THIS target's change and show what it inherits again. */
352
347
  resetToInherited?(key: string): void;
348
+ /**
349
+ * The keys THIS target changed. The panel keeps a changed key it has no row for (the model
350
+ * does not declare it, and the change removed its value) on screen, so its reset stays
351
+ * reachable.
352
+ */
353
+ changedKeys?: readonly string[];
353
354
  /** The reset button's words, in the host's noun. Default "Reset to agent". */
354
355
  resetLabel?: string;
355
356
  }
357
+ /**
358
+ * THE model row — the panel's first line, drawn by the panel with THE model picker
359
+ * (`ModelListDropdown`) in every host. Where a pick lands is the host's; the options below are
360
+ * capabilities a target has or lacks, exactly like `bind` / `resetToInherited` on the rows.
361
+ */
362
+ interface ModelRowTarget {
363
+ /** The model shown (the effective one; a one-message pick while that is on). */
364
+ value: string | null;
365
+ change(modelId: string): void;
366
+ /** The pinned class (offering) of the shown model. */
367
+ pinnedOfferingId: string | null | undefined;
368
+ /** A class pick (the picker reports the class before the model). */
369
+ changePin(offeringId: string | undefined): void;
370
+ /** True when THIS target changed the model or its class. */
371
+ changedHere?: boolean;
372
+ /** Drop this target's model choice (model and class together). */
373
+ resetToInherited?(): void;
374
+ /** An explicit "no override" choice at the top of the list, in the host's words. */
375
+ emptyChoice?: {
376
+ label: string;
377
+ choose(): void;
378
+ };
379
+ /** The person's local models (a chat host's port). */
380
+ localModels?: LocalModelsPort | undefined;
381
+ disabled?: boolean;
382
+ /** Said on the read-only picker when `disabled`. */
383
+ disabledTitle?: string;
384
+ /** "This message only": while on, a pick applies to the next message, then goes back. */
385
+ oneMessage?: {
386
+ on: boolean;
387
+ change(next: boolean): void;
388
+ };
389
+ }
356
390
  /** The frontend input capabilities (ui gates) shown under the settings groups. */
357
391
  interface CapabilitiesWriteTarget {
358
392
  values: UiGates;
@@ -364,35 +398,18 @@ interface CapabilitiesWriteTarget {
364
398
  error?: string | null;
365
399
  }
366
400
 
367
- interface ExtraSettingRowProps {
368
- rowKey: string;
369
- label: string;
370
- value: unknown;
371
- /**
372
- * `translated`: kept as set and sent as this model's closest equivalent (the server
373
- * converts it — never a warning). `unsupported`: this model has no such setting.
374
- */
375
- kind: "translated" | "unsupported";
376
- onClear: () => void;
377
- /** The conversation targets' reset (drop this target's change). */
378
- onReset?: (() => void) | undefined;
379
- resetLabel?: string | undefined;
380
- disabled?: boolean | undefined;
381
- }
382
- /** A set value outside the model's own rows — the builder's "Translated" line, shared. */
383
- declare function ExtraSettingRow({ rowKey, label, value, kind, onClear, onReset, resetLabel, disabled }: ExtraSettingRowProps): React.JSX.Element;
384
401
  interface ModelSettingsPanelProps {
385
402
  /** The effective model's normalized controls (`null` until a model's controls are known). */
386
403
  controls: Record<string, unknown> | null;
387
- /** The effective settings (marks `hasValue` on each catalog row). */
404
+ /** The effective settings (marks `hasValue` on each catalog row; the extra rows read them). */
388
405
  values: Record<string, unknown> | null;
389
406
  /** Where every change lands. */
390
407
  target: SettingsWriteTarget;
391
408
  /** Unique per mount (ids for labels and controls). */
392
409
  idPrefix: string;
393
- /** The model picker, drawn as the panel's first row. */
394
- model?: ReactNode;
395
- /** Drawn between the model row and the groups: notices, the issue list, extra rows. */
410
+ /** THE model row, drawn as the panel's first line. */
411
+ model?: ModelRowTarget | undefined;
412
+ /** Drawn between the model row and the groups: notices, the issue list. */
396
413
  notices?: ReactNode;
397
414
  /** A row the host draws itself (the multi-speaker voice editor); `undefined` = the standard row. */
398
415
  renderRow?: (row: SettingsRow) => ReactNode | undefined;
@@ -429,12 +446,6 @@ declare function RowLabel({ htmlFor, muted, children }: {
429
446
  muted?: boolean;
430
447
  children: ReactNode;
431
448
  }): React.JSX.Element;
432
- /** One titled group of rows, drawn the same way for catalog groups and host groups. */
433
- declare function SettingsGroupSection({ id, title, children }: {
434
- id: string;
435
- title?: string | undefined;
436
- children: ReactNode;
437
- }): React.JSX.Element;
438
449
 
439
450
  /** Subscribe to a slice of a settings store. `select` must return a stable value for unchanged state. */
440
451
  declare function useSettingsSelector<T>(store: SettingsStore, select: (state: AgentSettingsState) => T): T;
@@ -443,4 +454,4 @@ declare function useSettingsEntry(store: SettingsStore, agentId: string | null |
443
454
  /** Defaults merged with overrides for one agent; recomputed only when the entry changes. */
444
455
  declare function useEffectiveSettings(store: SettingsStore, agentId: string | null | undefined): Partial<AgentSettings>;
445
456
 
446
- export { ExtraSettingRow, type ExtraSettingRowProps, InputCapabilitiesEditor, type InputCapabilitiesEditorProps, ModelSettingsPanel, type ModelSettingsPanelProps, SettingControlInput, type SettingControlInputProps, SettingRowFrame, type SettingRowFrameProps, RowLabel as SettingRowLabel, SettingsGroupSection, formatSettingValue, useEffectiveSettings, useSettingsEntry, useSettingsSelector };
457
+ export { ModelSettingsPanel, type ModelSettingsPanelProps, SettingRowFrame, type SettingRowFrameProps, RowLabel as SettingRowLabel, formatSettingValue, useEffectiveSettings, useSettingsEntry, useSettingsSelector };
@@ -1,6 +1,6 @@
1
1
  import { components } from '@ai-matrx/api/types';
2
2
  import * as React from 'react';
3
- import { JSX, ReactNode } from 'react';
3
+ import { ReactNode } from 'react';
4
4
 
5
5
  /**
6
6
  * Agent Settings — Type Definitions
@@ -166,16 +166,48 @@ interface SettingsStore {
166
166
  cancelModelSwitch(agentId: string): void;
167
167
  }
168
168
 
169
- interface SettingControlInputProps {
170
- /** Setting key (snake_case) — used for ids and response_format handling. */
171
- settingKey: string;
172
- control: ControlDefinition;
173
- value: unknown;
174
- onChange: (value: unknown) => void;
175
- disabled?: boolean;
176
- id?: string;
169
+ /**
170
+ * Model Settings Catalog — the single source of truth for the STANDARD
171
+ * settings list, and the one chokepoint that decides which keys it contains.
172
+ *
173
+ * ── The model (two distinct surfaces) ────────────────────────────────────────
174
+ * 1. STANDARD list — ONLY the keys the selected model explicitly declares in
175
+ * its `controls` config (i.e. the parameters this model actually supports).
176
+ * `buildSettingsRows()` returns exactly these, grouped + ordered. Catalog
177
+ * keys the model does not declare are NOT shown here.
178
+ * 2. CAUTION surface — settings the agent has SET that the model does NOT
179
+ * support. These are never hidden: they are flagged as "not valid for this
180
+ * model" and made repairable by the validation layer (the IssueTable, fed
181
+ * by the `unsupported_by_model` rule). They do NOT belong in the standard
182
+ * list — that is exactly the "showing all possible keys" bug.
183
+ *
184
+ * The catalog exists so the standard list's labels, grouping and order live
185
+ * in ONE place (previously copy-pasted as `textModelSettings` /
186
+ * `booleanSettings` / ... into three components, each filtering by
187
+ * `getControl(key)` inline — which drifted and regressed). Components map over
188
+ * `buildSettingsRows()`; they must not filter by model themselves (ESLint
189
+ * enforces). The original recurring bug — set values silently dropped when a
190
+ * model didn't support them — is fixed by the CAUTION surface, not by dumping
191
+ * every key into the standard list.
192
+ *
193
+ * Guardrail: `settings-catalogue.test.ts` asserts the standard list contains
194
+ * ONLY supported keys (never the full catalog), and `unsupported-by-model.
195
+ * test.ts` asserts set-but-unsupported keys surface in the caution layer.
196
+ */
197
+
198
+ type SettingsGroupId = "text" | "featureFlags" | "imageVideo" | "audio" | "other";
199
+ interface SettingsRow {
200
+ key: string;
201
+ label: string;
202
+ group: SettingsGroupId;
203
+ /** The model's control definition for this key. Standard rows are always
204
+ * supported, so this is present; typed nullable for consumer convenience. */
205
+ control: ControlDefinition | null;
206
+ /** Always true for rows returned by buildSettingsRows (standard = supported). */
207
+ supported: boolean;
208
+ /** True when the current settings hold a non-null value for this key. */
209
+ hasValue: boolean;
177
210
  }
178
- declare function SettingControlInput({ settingKey, control, value, onChange, disabled, id, }: SettingControlInputProps): React.JSX.Element;
179
211
 
180
212
  /**
181
213
  * UI Gates — canonical model-gated UI flags.
@@ -219,72 +251,35 @@ interface UiGates {
219
251
  declare const UI_GATE_EDITABLE_KEYS: readonly ["image_urls", "file_urls", "youtube_videos"];
220
252
  type UiGateEditableKey = (typeof UI_GATE_EDITABLE_KEYS)[number];
221
253
 
222
- /**
223
- * THE input-capabilities group (agent core B4): the per-agent / per-run UI gates (image URLs,
224
- * file URLs, YouTube), drawn on THE model-settings panel's row frame so it lines up with the
225
- * settings above it — in the builder and in every override screen alike. Controlled: the
226
- * caller owns `values` and decides what a change means (the builder writes the agent's
227
- * ui_gates; a conversation writes its own capability overrides, each with a reset).
228
- */
229
-
230
- interface InputCapabilitiesEditorProps {
231
- values: UiGates;
232
- onChange: (key: UiGateEditableKey, value: boolean) => void;
233
- /** Keys the caller changed itself; each gets a reset to what it inherits. */
234
- changedKeys?: ReadonlySet<UiGateEditableKey> | undefined;
235
- onReset?: ((key: UiGateEditableKey) => void) | undefined;
236
- /** The reset button's words. Default "Reset to agent". */
237
- resetLabel?: string | undefined;
238
- /** Said under the rows when saving failed. */
239
- error?: string | null | undefined;
240
- idPrefix: string;
241
- title?: string;
242
- disabled?: boolean;
254
+ /** One model a host runs on the person's own computer. */
255
+ interface LocalModelEntry {
256
+ /** The value `onValueChange` receives (the conversation's model override). */
257
+ id: string;
258
+ name: string;
259
+ /** Brand glyph key (e.g. "Meta"); absent draws the neutral glyph. */
260
+ maker?: string | null;
261
+ contextWindow?: number | null;
262
+ /** The computer cannot hold it today: the row is dimmed and says why, but stays pickable. */
263
+ needsMoreMemory?: boolean;
243
264
  }
244
- /** Shared builder/runtime editor for frontend-only run capabilities. */
245
- declare function InputCapabilitiesEditor({ values, onChange, changedKeys, onReset, resetLabel, error, idPrefix, title, disabled, }: InputCapabilitiesEditorProps): JSX.Element;
246
-
247
265
  /**
248
- * Model Settings Catalog — the single source of truth for the STANDARD
249
- * settings list, and the one chokepoint that decides which keys it contains.
250
- *
251
- * ── The model (two distinct surfaces) ────────────────────────────────────────
252
- * 1. STANDARD list — ONLY the keys the selected model explicitly declares in
253
- * its `controls` config (i.e. the parameters this model actually supports).
254
- * `buildSettingsRows()` returns exactly these, grouped + ordered. Catalog
255
- * keys the model does not declare are NOT shown here.
256
- * 2. CAUTION surface — settings the agent has SET that the model does NOT
257
- * support. These are never hidden: they are flagged as "not valid for this
258
- * model" and made repairable by the validation layer (the IssueTable, fed
259
- * by the `unsupported_by_model` rule). They do NOT belong in the standard
260
- * list — that is exactly the "showing all possible keys" bug.
261
- *
262
- * The catalog exists so the standard list's labels, grouping and order live
263
- * in ONE place (previously copy-pasted as `textModelSettings` /
264
- * `booleanSettings` / ... into three components, each filtering by
265
- * `getControl(key)` inline — which drifted and regressed). Components map over
266
- * `buildSettingsRows()`; they must not filter by model themselves (ESLint
267
- * enforces). The original recurring bug — set values silently dropped when a
268
- * model didn't support them — is fixed by the CAUTION surface, not by dumping
269
- * every key into the standard list.
270
- *
271
- * Guardrail: `settings-catalogue.test.ts` asserts the standard list contains
272
- * ONLY supported keys (never the full catalog), and `unsupported-by-model.
273
- * test.ts` asserts set-but-unsupported keys surface in the caution layer.
266
+ * The host's local-model source (a store: `getModels` + `subscribe`, like the catalog). The picker
267
+ * draws its models as one "On this computer" group marked local. Start/Stop and getting more
268
+ * models stay the host's own screens.
274
269
  */
275
-
276
- type SettingsGroupId = "text" | "featureFlags" | "imageVideo" | "audio" | "other";
277
- interface SettingsRow {
278
- key: string;
279
- label: string;
280
- group: SettingsGroupId;
281
- /** The model's control definition for this key. Standard rows are always
282
- * supported, so this is present; typed nullable for consumer convenience. */
283
- control: ControlDefinition | null;
284
- /** Always true for rows returned by buildSettingsRows (standard = supported). */
285
- supported: boolean;
286
- /** True when the current settings hold a non-null value for this key. */
287
- hasValue: boolean;
270
+ interface LocalModelsPort {
271
+ /** Must return the SAME array until the list changes (it is a store snapshot). */
272
+ getModels(): readonly LocalModelEntry[];
273
+ subscribe(listener: () => void): () => void;
274
+ /** Group heading. Default "On this computer". */
275
+ groupLabel?: string;
276
+ /**
277
+ * Open the local model in its own private conversation (the host's Confidential Chat), instead
278
+ * of switching this conversation to it. Present = a local pick calls ONLY this: the cloud value
279
+ * and the class pin stay untouched, and no draft or context is carried. Absent = the pick reports
280
+ * the id through `onValueChange` (the override path).
281
+ */
282
+ open?(id: string): void;
288
283
  }
289
284
 
290
285
  /**
@@ -350,9 +345,48 @@ interface SettingsWriteTarget {
350
345
  unbind?(key: string, control: ControlDefinition | null): void;
351
346
  /** Drop THIS target's change and show what it inherits again. */
352
347
  resetToInherited?(key: string): void;
348
+ /**
349
+ * The keys THIS target changed. The panel keeps a changed key it has no row for (the model
350
+ * does not declare it, and the change removed its value) on screen, so its reset stays
351
+ * reachable.
352
+ */
353
+ changedKeys?: readonly string[];
353
354
  /** The reset button's words, in the host's noun. Default "Reset to agent". */
354
355
  resetLabel?: string;
355
356
  }
357
+ /**
358
+ * THE model row — the panel's first line, drawn by the panel with THE model picker
359
+ * (`ModelListDropdown`) in every host. Where a pick lands is the host's; the options below are
360
+ * capabilities a target has or lacks, exactly like `bind` / `resetToInherited` on the rows.
361
+ */
362
+ interface ModelRowTarget {
363
+ /** The model shown (the effective one; a one-message pick while that is on). */
364
+ value: string | null;
365
+ change(modelId: string): void;
366
+ /** The pinned class (offering) of the shown model. */
367
+ pinnedOfferingId: string | null | undefined;
368
+ /** A class pick (the picker reports the class before the model). */
369
+ changePin(offeringId: string | undefined): void;
370
+ /** True when THIS target changed the model or its class. */
371
+ changedHere?: boolean;
372
+ /** Drop this target's model choice (model and class together). */
373
+ resetToInherited?(): void;
374
+ /** An explicit "no override" choice at the top of the list, in the host's words. */
375
+ emptyChoice?: {
376
+ label: string;
377
+ choose(): void;
378
+ };
379
+ /** The person's local models (a chat host's port). */
380
+ localModels?: LocalModelsPort | undefined;
381
+ disabled?: boolean;
382
+ /** Said on the read-only picker when `disabled`. */
383
+ disabledTitle?: string;
384
+ /** "This message only": while on, a pick applies to the next message, then goes back. */
385
+ oneMessage?: {
386
+ on: boolean;
387
+ change(next: boolean): void;
388
+ };
389
+ }
356
390
  /** The frontend input capabilities (ui gates) shown under the settings groups. */
357
391
  interface CapabilitiesWriteTarget {
358
392
  values: UiGates;
@@ -364,35 +398,18 @@ interface CapabilitiesWriteTarget {
364
398
  error?: string | null;
365
399
  }
366
400
 
367
- interface ExtraSettingRowProps {
368
- rowKey: string;
369
- label: string;
370
- value: unknown;
371
- /**
372
- * `translated`: kept as set and sent as this model's closest equivalent (the server
373
- * converts it — never a warning). `unsupported`: this model has no such setting.
374
- */
375
- kind: "translated" | "unsupported";
376
- onClear: () => void;
377
- /** The conversation targets' reset (drop this target's change). */
378
- onReset?: (() => void) | undefined;
379
- resetLabel?: string | undefined;
380
- disabled?: boolean | undefined;
381
- }
382
- /** A set value outside the model's own rows — the builder's "Translated" line, shared. */
383
- declare function ExtraSettingRow({ rowKey, label, value, kind, onClear, onReset, resetLabel, disabled }: ExtraSettingRowProps): React.JSX.Element;
384
401
  interface ModelSettingsPanelProps {
385
402
  /** The effective model's normalized controls (`null` until a model's controls are known). */
386
403
  controls: Record<string, unknown> | null;
387
- /** The effective settings (marks `hasValue` on each catalog row). */
404
+ /** The effective settings (marks `hasValue` on each catalog row; the extra rows read them). */
388
405
  values: Record<string, unknown> | null;
389
406
  /** Where every change lands. */
390
407
  target: SettingsWriteTarget;
391
408
  /** Unique per mount (ids for labels and controls). */
392
409
  idPrefix: string;
393
- /** The model picker, drawn as the panel's first row. */
394
- model?: ReactNode;
395
- /** Drawn between the model row and the groups: notices, the issue list, extra rows. */
410
+ /** THE model row, drawn as the panel's first line. */
411
+ model?: ModelRowTarget | undefined;
412
+ /** Drawn between the model row and the groups: notices, the issue list. */
396
413
  notices?: ReactNode;
397
414
  /** A row the host draws itself (the multi-speaker voice editor); `undefined` = the standard row. */
398
415
  renderRow?: (row: SettingsRow) => ReactNode | undefined;
@@ -429,12 +446,6 @@ declare function RowLabel({ htmlFor, muted, children }: {
429
446
  muted?: boolean;
430
447
  children: ReactNode;
431
448
  }): React.JSX.Element;
432
- /** One titled group of rows, drawn the same way for catalog groups and host groups. */
433
- declare function SettingsGroupSection({ id, title, children }: {
434
- id: string;
435
- title?: string | undefined;
436
- children: ReactNode;
437
- }): React.JSX.Element;
438
449
 
439
450
  /** Subscribe to a slice of a settings store. `select` must return a stable value for unchanged state. */
440
451
  declare function useSettingsSelector<T>(store: SettingsStore, select: (state: AgentSettingsState) => T): T;
@@ -443,4 +454,4 @@ declare function useSettingsEntry(store: SettingsStore, agentId: string | null |
443
454
  /** Defaults merged with overrides for one agent; recomputed only when the entry changes. */
444
455
  declare function useEffectiveSettings(store: SettingsStore, agentId: string | null | undefined): Partial<AgentSettings>;
445
456
 
446
- export { ExtraSettingRow, type ExtraSettingRowProps, InputCapabilitiesEditor, type InputCapabilitiesEditorProps, ModelSettingsPanel, type ModelSettingsPanelProps, SettingControlInput, type SettingControlInputProps, SettingRowFrame, type SettingRowFrameProps, RowLabel as SettingRowLabel, SettingsGroupSection, formatSettingValue, useEffectiveSettings, useSettingsEntry, useSettingsSelector };
457
+ export { ModelSettingsPanel, type ModelSettingsPanelProps, SettingRowFrame, type SettingRowFrameProps, RowLabel as SettingRowLabel, formatSettingValue, useEffectiveSettings, useSettingsEntry, useSettingsSelector };