@ai-matrx/agents 0.59.189 → 0.59.191

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 } from 'react';
3
+ import { JSX, ReactNode } from 'react';
4
4
 
5
5
  /**
6
6
  * Agent Settings — Type Definitions
@@ -166,25 +166,16 @@ interface SettingsStore {
166
166
  cancelModelSwitch(agentId: string): void;
167
167
  }
168
168
 
169
- /** The enum value that means "off" when a control declares it. */
170
- declare const ENUM_OFF_VALUE = "none";
171
169
  interface SettingControlInputProps {
172
170
  /** Setting key (snake_case) — used for ids and response_format handling. */
173
171
  settingKey: string;
174
- explicitState?: boolean;
175
172
  control: ControlDefinition;
176
173
  value: unknown;
177
174
  onChange: (value: unknown) => void;
178
175
  disabled?: boolean;
179
176
  id?: string;
180
- /**
181
- * "dense" (default) = the builder's in-row controls. "comfortable" = menu
182
- * sizing for the composer's Model panel and the Chat Options window: 36px
183
- * controls (44px on touch), text-sm, and a Switch for booleans.
184
- */
185
- size?: "dense" | "comfortable";
186
177
  }
187
- declare function SettingControlInput({ settingKey, explicitState, control, value, onChange, disabled, id, size, }: SettingControlInputProps): React.JSX.Element;
178
+ declare function SettingControlInput({ settingKey, control, value, onChange, disabled, id, }: SettingControlInputProps): React.JSX.Element;
188
179
 
189
180
  /**
190
181
  * UI Gates — canonical model-gated UI flags.
@@ -229,26 +220,221 @@ declare const UI_GATE_EDITABLE_KEYS: readonly ["image_urls", "file_urls", "youtu
229
220
  type UiGateEditableKey = (typeof UI_GATE_EDITABLE_KEYS)[number];
230
221
 
231
222
  /**
232
- * THE input-capabilities editor (agent core B4): the per-agent / per-run UI gates (image URLs,
233
- * file URLs, YouTube). Controlled — the caller owns `values` and decides what a change means.
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).
234
228
  */
235
229
 
236
230
  interface InputCapabilitiesEditorProps {
237
231
  values: UiGates;
238
232
  onChange: (key: UiGateEditableKey, value: boolean) => void;
239
- overriddenKeys?: ReadonlySet<UiGateEditableKey>;
240
- onReset?: (key: UiGateEditableKey) => 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;
241
240
  idPrefix: string;
242
241
  title?: string;
242
+ disabled?: boolean;
243
+ }
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
+ /**
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.
274
+ */
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;
288
+ }
289
+
290
+ /**
291
+ * THE SETTINGS WRITE TARGET — the one seam between THE model-settings panel
292
+ * (`./react/ModelSettingsPanel`) and whatever a change is written to.
293
+ *
294
+ * Owner ruling, 2026-10-21: one settings experience. The agent builder and the
295
+ * chat's "Model and overrides" render the SAME rows, controls, labels and
296
+ * order; they differ ONLY in where a change lands. The builder's target writes
297
+ * the agent; a conversation's (or a binding's, a mandate's, a shortcut's)
298
+ * target writes that record's overrides and adds a per-row reset back to what
299
+ * it inherits. The panel never knows which.
300
+ *
301
+ * Every method is the person's intent in the panel's words — never a store
302
+ * action. Optional methods are optional ACTIONS: a target that cannot bind a
303
+ * control to a run input simply has no `bind`, and the panel draws no button.
304
+ */
305
+
306
+ /** What one row shows. Off is a `set` value the panel recognizes (setting-state). */
307
+ type SettingRowView =
308
+ /** Key absent: the model's own default applies. */
309
+ {
310
+ state: "unset";
311
+ modelDefault?: unknown;
312
+ }
313
+ /** A saved / effective value. */
314
+ | {
315
+ state: "set";
316
+ value: unknown;
317
+ }
318
+ /** The setting is a run input: its value comes from `{{variableName}}`. */
319
+ | {
320
+ state: "bound";
321
+ variableName: string;
322
+ value: unknown;
323
+ };
324
+ /** What the target knows about a row beyond its value. */
325
+ interface SettingRowFacts {
326
+ /** True when THIS target changed the row (a conversation override). */
327
+ changedHere?: boolean;
328
+ /** Where the shown value comes from, in the host's words ("Agent", "Organization"). */
329
+ source?: string;
330
+ /** The row's first validation issue, when the target validates. */
331
+ issue?: {
332
+ message: string;
333
+ fixable: boolean;
334
+ };
335
+ }
336
+ type SettingRowRead = SettingRowView & SettingRowFacts;
337
+ interface SettingsWriteTarget {
338
+ read(key: string, control: ControlDefinition | null): SettingRowRead;
339
+ /** The person edited the control. */
340
+ change(key: string, value: unknown, control: ControlDefinition | null): void;
341
+ /** The person ticked an unset row (store `startingValueFor`). */
342
+ turnOn(key: string, control: ControlDefinition): void;
343
+ /** The person cleared the row back to "not set". */
344
+ clear(key: string): void;
345
+ /** One-click repair of the row's issue. */
346
+ fix?(key: string): void;
347
+ /** May this row become a run input? (Builder only.) */
348
+ canBind?(key: string): boolean;
349
+ bind?(key: string, control: ControlDefinition): void;
350
+ unbind?(key: string, control: ControlDefinition | null): void;
351
+ /** Drop THIS target's change and show what it inherits again. */
352
+ resetToInherited?(key: string): void;
353
+ /** The reset button's words, in the host's noun. Default "Reset to agent". */
354
+ resetLabel?: string;
355
+ }
356
+ /** The frontend input capabilities (ui gates) shown under the settings groups. */
357
+ interface CapabilitiesWriteTarget {
358
+ values: UiGates;
359
+ change(key: UiGateEditableKey, value: boolean): void;
360
+ /** Keys THIS target changed; each gets its own reset. */
361
+ changedKeys?: ReadonlySet<UiGateEditableKey>;
362
+ resetToInherited?(key: UiGateEditableKey): void;
363
+ /** Said under the rows when saving the capabilities failed. */
364
+ error?: string | null;
365
+ }
366
+
367
+ interface ExtraSettingRowProps {
368
+ rowKey: string;
369
+ label: string;
370
+ value: unknown;
243
371
  /**
244
- * "settings" (default) = the agent builder's rows with a one-line
245
- * description. "menu" = the composer/Chat Options sizing: label + switch
246
- * only, 36px rows (44px on touch), text-sm, 28px Reset when overridden.
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.
247
374
  */
248
- variant?: "settings" | "menu";
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;
249
381
  }
250
- /** Shared builder/runtime editor for frontend-only run capabilities. */
251
- declare function InputCapabilitiesEditor({ values, onChange, overriddenKeys, onReset, idPrefix, title, variant, }: InputCapabilitiesEditorProps): JSX.Element;
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
+ interface ModelSettingsPanelProps {
385
+ /** The effective model's normalized controls (`null` until a model's controls are known). */
386
+ controls: Record<string, unknown> | null;
387
+ /** The effective settings (marks `hasValue` on each catalog row). */
388
+ values: Record<string, unknown> | null;
389
+ /** Where every change lands. */
390
+ target: SettingsWriteTarget;
391
+ /** Unique per mount (ids for labels and controls). */
392
+ 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. */
396
+ notices?: ReactNode;
397
+ /** A row the host draws itself (the multi-speaker voice editor); `undefined` = the standard row. */
398
+ renderRow?: (row: SettingsRow) => ReactNode | undefined;
399
+ /** The input capabilities group, under the settings groups. */
400
+ capabilities?: CapabilitiesWriteTarget | undefined;
401
+ /** Said where the rows would be when the model declares none (or no model is chosen). */
402
+ emptyNote?: ReactNode;
403
+ disabled?: boolean;
404
+ }
405
+ declare function ModelSettingsPanel({ controls, values, target, idPrefix, model, notices, renderRow, capabilities, emptyNote, disabled, }: ModelSettingsPanelProps): React.JSX.Element;
406
+
407
+ /** A catalog value as the person reads it ("On", "auto", "1024"). */
408
+ declare function formatSettingValue(value: unknown): string;
409
+ interface SettingRowFrameProps {
410
+ /** `data-setting-row` — the setting key (or a host row name such as "model"). */
411
+ rowKey: string;
412
+ /** `data-setting-state` — unset | set | off | bound | translated | … */
413
+ state?: string;
414
+ /** The 16px leading column: the row's checkbox, or an icon. */
415
+ leading?: ReactNode;
416
+ label: ReactNode;
417
+ /** The control, or the row's value text. */
418
+ children?: ReactNode;
419
+ /** Fixed-width icons on the right: status, then actions. */
420
+ actions?: ReactNode;
421
+ }
422
+ /**
423
+ * The one row geometry every line of the panel uses — setting rows, the model row, the
424
+ * translated rows, the voice row and the input capabilities — so their edges line up.
425
+ */
426
+ declare function SettingRowFrame({ rowKey, state, leading, label, children, actions }: SettingRowFrameProps): React.JSX.Element;
427
+ declare function RowLabel({ htmlFor, muted, children }: {
428
+ htmlFor?: string;
429
+ muted?: boolean;
430
+ children: ReactNode;
431
+ }): 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;
252
438
 
253
439
  /** Subscribe to a slice of a settings store. `select` must return a stable value for unchanged state. */
254
440
  declare function useSettingsSelector<T>(store: SettingsStore, select: (state: AgentSettingsState) => T): T;
@@ -257,4 +443,4 @@ declare function useSettingsEntry(store: SettingsStore, agentId: string | null |
257
443
  /** Defaults merged with overrides for one agent; recomputed only when the entry changes. */
258
444
  declare function useEffectiveSettings(store: SettingsStore, agentId: string | null | undefined): Partial<AgentSettings>;
259
445
 
260
- export { ENUM_OFF_VALUE, InputCapabilitiesEditor, type InputCapabilitiesEditorProps, SettingControlInput, type SettingControlInputProps, useEffectiveSettings, useSettingsEntry, useSettingsSelector };
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 };
@@ -1,6 +1,6 @@
1
1
  import { components } from '@ai-matrx/api/types';
2
2
  import * as React from 'react';
3
- import { JSX } from 'react';
3
+ import { JSX, ReactNode } from 'react';
4
4
 
5
5
  /**
6
6
  * Agent Settings — Type Definitions
@@ -166,25 +166,16 @@ interface SettingsStore {
166
166
  cancelModelSwitch(agentId: string): void;
167
167
  }
168
168
 
169
- /** The enum value that means "off" when a control declares it. */
170
- declare const ENUM_OFF_VALUE = "none";
171
169
  interface SettingControlInputProps {
172
170
  /** Setting key (snake_case) — used for ids and response_format handling. */
173
171
  settingKey: string;
174
- explicitState?: boolean;
175
172
  control: ControlDefinition;
176
173
  value: unknown;
177
174
  onChange: (value: unknown) => void;
178
175
  disabled?: boolean;
179
176
  id?: string;
180
- /**
181
- * "dense" (default) = the builder's in-row controls. "comfortable" = menu
182
- * sizing for the composer's Model panel and the Chat Options window: 36px
183
- * controls (44px on touch), text-sm, and a Switch for booleans.
184
- */
185
- size?: "dense" | "comfortable";
186
177
  }
187
- declare function SettingControlInput({ settingKey, explicitState, control, value, onChange, disabled, id, size, }: SettingControlInputProps): React.JSX.Element;
178
+ declare function SettingControlInput({ settingKey, control, value, onChange, disabled, id, }: SettingControlInputProps): React.JSX.Element;
188
179
 
189
180
  /**
190
181
  * UI Gates — canonical model-gated UI flags.
@@ -229,26 +220,221 @@ declare const UI_GATE_EDITABLE_KEYS: readonly ["image_urls", "file_urls", "youtu
229
220
  type UiGateEditableKey = (typeof UI_GATE_EDITABLE_KEYS)[number];
230
221
 
231
222
  /**
232
- * THE input-capabilities editor (agent core B4): the per-agent / per-run UI gates (image URLs,
233
- * file URLs, YouTube). Controlled — the caller owns `values` and decides what a change means.
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).
234
228
  */
235
229
 
236
230
  interface InputCapabilitiesEditorProps {
237
231
  values: UiGates;
238
232
  onChange: (key: UiGateEditableKey, value: boolean) => void;
239
- overriddenKeys?: ReadonlySet<UiGateEditableKey>;
240
- onReset?: (key: UiGateEditableKey) => 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;
241
240
  idPrefix: string;
242
241
  title?: string;
242
+ disabled?: boolean;
243
+ }
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
+ /**
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.
274
+ */
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;
288
+ }
289
+
290
+ /**
291
+ * THE SETTINGS WRITE TARGET — the one seam between THE model-settings panel
292
+ * (`./react/ModelSettingsPanel`) and whatever a change is written to.
293
+ *
294
+ * Owner ruling, 2026-10-21: one settings experience. The agent builder and the
295
+ * chat's "Model and overrides" render the SAME rows, controls, labels and
296
+ * order; they differ ONLY in where a change lands. The builder's target writes
297
+ * the agent; a conversation's (or a binding's, a mandate's, a shortcut's)
298
+ * target writes that record's overrides and adds a per-row reset back to what
299
+ * it inherits. The panel never knows which.
300
+ *
301
+ * Every method is the person's intent in the panel's words — never a store
302
+ * action. Optional methods are optional ACTIONS: a target that cannot bind a
303
+ * control to a run input simply has no `bind`, and the panel draws no button.
304
+ */
305
+
306
+ /** What one row shows. Off is a `set` value the panel recognizes (setting-state). */
307
+ type SettingRowView =
308
+ /** Key absent: the model's own default applies. */
309
+ {
310
+ state: "unset";
311
+ modelDefault?: unknown;
312
+ }
313
+ /** A saved / effective value. */
314
+ | {
315
+ state: "set";
316
+ value: unknown;
317
+ }
318
+ /** The setting is a run input: its value comes from `{{variableName}}`. */
319
+ | {
320
+ state: "bound";
321
+ variableName: string;
322
+ value: unknown;
323
+ };
324
+ /** What the target knows about a row beyond its value. */
325
+ interface SettingRowFacts {
326
+ /** True when THIS target changed the row (a conversation override). */
327
+ changedHere?: boolean;
328
+ /** Where the shown value comes from, in the host's words ("Agent", "Organization"). */
329
+ source?: string;
330
+ /** The row's first validation issue, when the target validates. */
331
+ issue?: {
332
+ message: string;
333
+ fixable: boolean;
334
+ };
335
+ }
336
+ type SettingRowRead = SettingRowView & SettingRowFacts;
337
+ interface SettingsWriteTarget {
338
+ read(key: string, control: ControlDefinition | null): SettingRowRead;
339
+ /** The person edited the control. */
340
+ change(key: string, value: unknown, control: ControlDefinition | null): void;
341
+ /** The person ticked an unset row (store `startingValueFor`). */
342
+ turnOn(key: string, control: ControlDefinition): void;
343
+ /** The person cleared the row back to "not set". */
344
+ clear(key: string): void;
345
+ /** One-click repair of the row's issue. */
346
+ fix?(key: string): void;
347
+ /** May this row become a run input? (Builder only.) */
348
+ canBind?(key: string): boolean;
349
+ bind?(key: string, control: ControlDefinition): void;
350
+ unbind?(key: string, control: ControlDefinition | null): void;
351
+ /** Drop THIS target's change and show what it inherits again. */
352
+ resetToInherited?(key: string): void;
353
+ /** The reset button's words, in the host's noun. Default "Reset to agent". */
354
+ resetLabel?: string;
355
+ }
356
+ /** The frontend input capabilities (ui gates) shown under the settings groups. */
357
+ interface CapabilitiesWriteTarget {
358
+ values: UiGates;
359
+ change(key: UiGateEditableKey, value: boolean): void;
360
+ /** Keys THIS target changed; each gets its own reset. */
361
+ changedKeys?: ReadonlySet<UiGateEditableKey>;
362
+ resetToInherited?(key: UiGateEditableKey): void;
363
+ /** Said under the rows when saving the capabilities failed. */
364
+ error?: string | null;
365
+ }
366
+
367
+ interface ExtraSettingRowProps {
368
+ rowKey: string;
369
+ label: string;
370
+ value: unknown;
243
371
  /**
244
- * "settings" (default) = the agent builder's rows with a one-line
245
- * description. "menu" = the composer/Chat Options sizing: label + switch
246
- * only, 36px rows (44px on touch), text-sm, 28px Reset when overridden.
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.
247
374
  */
248
- variant?: "settings" | "menu";
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;
249
381
  }
250
- /** Shared builder/runtime editor for frontend-only run capabilities. */
251
- declare function InputCapabilitiesEditor({ values, onChange, overriddenKeys, onReset, idPrefix, title, variant, }: InputCapabilitiesEditorProps): JSX.Element;
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
+ interface ModelSettingsPanelProps {
385
+ /** The effective model's normalized controls (`null` until a model's controls are known). */
386
+ controls: Record<string, unknown> | null;
387
+ /** The effective settings (marks `hasValue` on each catalog row). */
388
+ values: Record<string, unknown> | null;
389
+ /** Where every change lands. */
390
+ target: SettingsWriteTarget;
391
+ /** Unique per mount (ids for labels and controls). */
392
+ 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. */
396
+ notices?: ReactNode;
397
+ /** A row the host draws itself (the multi-speaker voice editor); `undefined` = the standard row. */
398
+ renderRow?: (row: SettingsRow) => ReactNode | undefined;
399
+ /** The input capabilities group, under the settings groups. */
400
+ capabilities?: CapabilitiesWriteTarget | undefined;
401
+ /** Said where the rows would be when the model declares none (or no model is chosen). */
402
+ emptyNote?: ReactNode;
403
+ disabled?: boolean;
404
+ }
405
+ declare function ModelSettingsPanel({ controls, values, target, idPrefix, model, notices, renderRow, capabilities, emptyNote, disabled, }: ModelSettingsPanelProps): React.JSX.Element;
406
+
407
+ /** A catalog value as the person reads it ("On", "auto", "1024"). */
408
+ declare function formatSettingValue(value: unknown): string;
409
+ interface SettingRowFrameProps {
410
+ /** `data-setting-row` — the setting key (or a host row name such as "model"). */
411
+ rowKey: string;
412
+ /** `data-setting-state` — unset | set | off | bound | translated | … */
413
+ state?: string;
414
+ /** The 16px leading column: the row's checkbox, or an icon. */
415
+ leading?: ReactNode;
416
+ label: ReactNode;
417
+ /** The control, or the row's value text. */
418
+ children?: ReactNode;
419
+ /** Fixed-width icons on the right: status, then actions. */
420
+ actions?: ReactNode;
421
+ }
422
+ /**
423
+ * The one row geometry every line of the panel uses — setting rows, the model row, the
424
+ * translated rows, the voice row and the input capabilities — so their edges line up.
425
+ */
426
+ declare function SettingRowFrame({ rowKey, state, leading, label, children, actions }: SettingRowFrameProps): React.JSX.Element;
427
+ declare function RowLabel({ htmlFor, muted, children }: {
428
+ htmlFor?: string;
429
+ muted?: boolean;
430
+ children: ReactNode;
431
+ }): 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;
252
438
 
253
439
  /** Subscribe to a slice of a settings store. `select` must return a stable value for unchanged state. */
254
440
  declare function useSettingsSelector<T>(store: SettingsStore, select: (state: AgentSettingsState) => T): T;
@@ -257,4 +443,4 @@ declare function useSettingsEntry(store: SettingsStore, agentId: string | null |
257
443
  /** Defaults merged with overrides for one agent; recomputed only when the entry changes. */
258
444
  declare function useEffectiveSettings(store: SettingsStore, agentId: string | null | undefined): Partial<AgentSettings>;
259
445
 
260
- export { ENUM_OFF_VALUE, InputCapabilitiesEditor, type InputCapabilitiesEditorProps, SettingControlInput, type SettingControlInputProps, useEffectiveSettings, useSettingsEntry, useSettingsSelector };
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 };