@ai-matrx/chat 0.5.18 → 0.6.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.
Files changed (89) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/dist/agents/components/identity-refs/AiIdentityRef.d.ts +33 -0
  3. package/dist/agents/components/identity-refs/AiIdentityRef.js +138 -0
  4. package/dist/agents/components/inputs/smart-input/QuicksetPanel.js +5 -9
  5. package/dist/agents/components/inputs/smart-input/RunSkillPicker.js +1 -1
  6. package/dist/agents/components/inputs/smart-input/RunToolPicker.js +6 -11
  7. package/dist/agents/components/inputs/smart-input/ShapeChipsRow.js +1 -1
  8. package/dist/agents/components/inputs/smart-input/composer/ComposerEffortPill.js +1 -1
  9. package/dist/agents/components/inputs/smart-input/composer/ComposerOutput.js +1 -1
  10. package/dist/agents/components/inputs/smart-input/composer/ComposerPlusMenu.js +1 -1
  11. package/dist/agents/components/inputs/smart-input/composer/useComposerAgent.js +1 -1
  12. package/dist/agents/components/inputs/smart-input/composer/useRunControlCounts.d.ts +3 -0
  13. package/dist/agents/components/inputs/smart-input/composer/useRunControlCounts.js +54 -0
  14. package/dist/agents/components/model-tiers/ModelTierIdentityList.js +1 -1
  15. package/dist/agents/components/run-controls/RunConfigOverrides.js +1 -1
  16. package/dist/agents/components/run-controls/RunInputCapabilities.js +1 -1
  17. package/dist/agents/components/run-controls/panels/shared.d.ts +0 -2
  18. package/dist/agents/hooks/useDiffEnrichment.js +3 -6
  19. package/dist/agents/identity/agent-catalog-lists.js +2 -1
  20. package/dist/agents/identity/agent-identity.js +2 -1
  21. package/dist/agents/identity/model-catalog.d.ts +9 -0
  22. package/dist/agents/identity/model-catalog.js +25 -0
  23. package/dist/agents/identity/preferred-chat-model.d.ts +9 -0
  24. package/dist/agents/identity/preferred-chat-model.js +33 -0
  25. package/dist/agents/identity/settings-store.d.ts +10 -0
  26. package/dist/agents/identity/settings-store.js +49 -0
  27. package/dist/agents/identity/skill-catalog.d.ts +27 -0
  28. package/dist/agents/identity/skill-catalog.js +100 -0
  29. package/dist/agents/identity/tool-catalog.d.ts +15 -0
  30. package/dist/agents/identity/tool-catalog.js +67 -0
  31. package/dist/agents/redux/agent-definition/cache-bust-middleware.d.ts +0 -1
  32. package/dist/agents/redux/agent-definition/cache-bust-middleware.js +1 -13
  33. package/dist/agents/redux/agent-definition/selectors.d.ts +12 -546
  34. package/dist/agents/redux/agent-settings/internal-utils.d.ts +2 -123
  35. package/dist/agents/redux/agent-settings/internal-utils.js +1 -315
  36. package/dist/agents/redux/agent-settings/settings-catalogue.d.ts +2 -78
  37. package/dist/agents/redux/agent-settings/settings-catalogue.js +1 -176
  38. package/dist/agents/redux/agent-settings/types.d.ts +2 -148
  39. package/dist/agents/redux/agent-settings/types.js +1 -0
  40. package/dist/agents/redux/agent-settings/ui-gates.d.ts +2 -54
  41. package/dist/agents/redux/agent-settings/ui-gates.js +1 -38
  42. package/dist/agents/redux/agent-shortcut-categories/selectors.d.ts +0 -100
  43. package/dist/agents/redux/agent-shortcuts/selectors.d.ts +0 -294
  44. package/dist/agents/redux/conversation-history/selectors.d.ts +0 -32
  45. package/dist/agents/redux/conversation-list/conversation-list.selectors.d.ts +0 -4
  46. package/dist/agents/redux/execution-system/active-requests/active-requests.selectors.d.ts +0 -108
  47. package/dist/agents/redux/execution-system/context-state/context-state.selectors.d.ts +0 -28
  48. package/dist/agents/redux/execution-system/conversations/conversations.selectors.d.ts +0 -10
  49. package/dist/agents/redux/execution-system/instance-context/instance-context.selectors.d.ts +0 -6
  50. package/dist/agents/redux/execution-system/instance-model-overrides/launch-model-overrides.js +1 -1
  51. package/dist/agents/redux/execution-system/instance-resources/instance-resources.selectors.d.ts +0 -16
  52. package/dist/agents/redux/execution-system/instance-ui-state/instance-ui-state.selectors.d.ts +0 -10
  53. package/dist/agents/redux/execution-system/instance-variable-values/instance-variable-values.selectors.d.ts +0 -14
  54. package/dist/agents/redux/execution-system/messages/messages.selectors.d.ts +0 -2
  55. package/dist/agents/redux/execution-system/observability/observability.selectors.d.ts +0 -14
  56. package/dist/agents/redux/execution-system/observational-memory/observational-memory.selectors.d.ts +0 -2
  57. package/dist/agents/redux/execution-system/selectors/aggregate.selectors.d.ts +0 -28
  58. package/dist/agents/redux/execution-system/thunks/process-stream.js +2 -5
  59. package/dist/agents/redux/execution-system/utils/loaded-skill-sources.d.ts +1 -1
  60. package/dist/agents/redux/execution-system/utils/loaded-skill-sources.js +3 -3
  61. package/dist/agents/redux/proposed-directives/proposedDirectivesSlice.d.ts +0 -2
  62. package/dist/agents/ui-first-tools/redux/agent-lists.selectors.d.ts +0 -4
  63. package/dist/host/ui-slots.d.ts +0 -46
  64. package/dist/host/ui-slots.js +0 -33
  65. package/dist/store/create-chat-store.d.ts +0 -4
  66. package/dist/store/middlewares.d.ts +0 -10
  67. package/dist/store/slices.d.ts +0 -2
  68. package/dist/store/slices.js +0 -4
  69. package/dist/surfaces/redux/selectors.d.ts +0 -4
  70. package/dist/tool-call-visualization/redux/selectors.d.ts +0 -2
  71. package/dist/ui/chat-default-model-knob.d.ts +1 -1
  72. package/dist/ui/chat-default-model-knob.js +1 -1
  73. package/package.json +4 -4
  74. package/dist/agents/components/model/AgentModelPanel.d.ts +0 -4
  75. package/dist/agents/components/model/AgentModelPanel.js +0 -9
  76. package/dist/agents/redux/agent-settings/agentSettingsSlice.d.ts +0 -1015
  77. package/dist/agents/redux/agent-settings/agentSettingsSlice.js +0 -659
  78. package/dist/agents/redux/agent-settings/selectors.d.ts +0 -10057
  79. package/dist/agents/redux/agent-settings/selectors.js +0 -234
  80. package/dist/agents/redux/agent-settings/useNormalizedControls.d.ts +0 -8
  81. package/dist/agents/redux/agent-settings/useNormalizedControls.js +0 -24
  82. package/dist/agents/redux/tools/tools.selectors.d.ts +0 -529
  83. package/dist/agents/redux/tools/tools.selectors.js +0 -24
  84. package/dist/agents/redux/tools/tools.slice.d.ts +0 -12
  85. package/dist/agents/redux/tools/tools.slice.js +0 -37
  86. package/dist/agents/redux/tools/tools.thunks.d.ts +0 -125
  87. package/dist/agents/redux/tools/tools.thunks.js +0 -45
  88. package/dist/host/defaults/setting-control-input.d.ts +0 -11
  89. package/dist/host/defaults/setting-control-input.js +0 -91
@@ -1,123 +1,2 @@
1
- /**
2
- * Agent Settings — Internal Utilities
3
- *
4
- * Pure functions with NO Redux imports. No React hooks.
5
- * All logic that was previously scattered across:
6
- * - useModelControls hook
7
- * - switchModel thunk
8
- * - ModelChangeConflictModal component
9
- * - ConversationInput.handleSettingsChange
10
- *
11
- * is consolidated here and consumed by the slice's reducers/thunks.
12
- */
13
- import type { AgentSettings, AgentVariable, ConflictAction, ConflictItem, NormalizedControls, PendingModelSwitch, ResolutionMode } from "./types.js";
14
- import { AgentContext } from "./types.js";
15
- export type { AgentContext };
16
- /**
17
- * Cross-provider parameter name synonyms.
18
- * When a setting key is unsupported by a new model, we check aliases
19
- * to suggest the equivalent parameter name the new model may use instead.
20
- */
21
- export declare const PARAM_ALIASES: Readonly<Record<string, string[]>>;
22
- /**
23
- * Parse raw JSONB controls from `ai_model.controls` into a typed NormalizedControls map.
24
- *
25
- * Absorbs the logic from `useModelControls` hook.
26
- *
27
- * Control JSONB shape per field:
28
- * { type?, min?, max?, default?, enum?, required?, allowed? }
29
- *
30
- * Special cases:
31
- * - `output_format` → `response_format` only for text response formats
32
- * (outputFormatControlKey); an image file format keeps its own key
33
- * - `allowed: true/false` → boolean feature flag
34
- * - enum values that are `{ type: "json_object" }` objects → flattened to string
35
- */
36
- export declare function parseModelControls(rawControls: Record<string, unknown> | null | undefined): NormalizedControls;
37
- /**
38
- * Extract submission-ready default values from a model's raw controls JSONB.
39
- *
40
- * Absorbs the logic from `getModelDefaults` in `useModelControls`.
41
- *
42
- * Rules:
43
- * - Controls with `default: null` are SKIPPED (opt-in only controls)
44
- * - `tools: { allowed: true }` → `tools: []` (empty list, not a boolean)
45
- * - `response_format: "text"` → SKIP (backend treats absence as text)
46
- * - `response_format: "json_object"` → `{ type: "json_object" }` (dict form)
47
- * - UI-only capability flags (image_urls, file_urls, etc.) → kept as booleans
48
- */
49
- export declare function extractModelDefaults(rawControls: Record<string, unknown> | null | undefined): Partial<AgentSettings>;
50
- /**
51
- * Detect which keys in `currentSettings` are incompatible with `newControls`.
52
- *
53
- * Returns:
54
- * - `conflicts`: settings that have problems (unsupported, out-of-range, wrong enum)
55
- * - `supportedKeys`: settings that carry over cleanly
56
- *
57
- * This is the NEW detection logic that was missing from the existing system
58
- * (the old ModelChangeConflictModal received conflicts pre-built from above).
59
- */
60
- export declare function detectConflicts(currentSettings: Partial<AgentSettings>, newControls: NormalizedControls, newDefaults: Partial<AgentSettings>): {
61
- conflicts: ConflictItem[];
62
- supportedKeys: Array<keyof AgentSettings>;
63
- };
64
- /**
65
- * Apply a pending switch's resolution mode + custom actions to produce
66
- * the final settings after the model change is confirmed.
67
- *
68
- * Absorbs `computeResolvedSettings` from ModelChangeConflictModal.
69
- */
70
- export declare function resolveConflicts(currentSettings: Partial<AgentSettings>, pending: PendingModelSwitch): Partial<AgentSettings>;
71
- /**
72
- * Determine the action ('keep' | 'reset') for a conflict given the current mode.
73
- * Absorbs `getActionForMode` from ModelChangeConflictModal.
74
- */
75
- export declare function getActionForMode(mode: ResolutionMode, conflict: ConflictItem, customActions: Partial<Record<keyof AgentSettings, ConflictAction>>): ConflictAction;
76
- /**
77
- * Compare `proposed` settings against `defaults` and return only the keys
78
- * that genuinely differ. Uses JSON-stringify for deep comparison.
79
- *
80
- * Absorbs the diff logic from ConversationInput.handleSettingsChange.
81
- * In chat/test contexts, only true overrides are stored — not redundant defaults.
82
- *
83
- * REMOVAL IS A DIFF TOO: a key the defaults carry that `proposed` dropped (or
84
- * set to null) is stored as an explicit `null` override. Without it a removal
85
- * was inexpressible — the default (e.g. the agent's class pin `offering_id`)
86
- * silently came back on the next merge and on the wire. `null` = "the API must
87
- * not use this key"; `mergeEffectiveSettings` deletes it, `buildApiPayload`
88
- * sends it (the server honours `offering_id: null`).
89
- */
90
- export declare function computeOverrideDiff(defaults: Partial<AgentSettings>, proposed: Partial<AgentSettings>): Partial<AgentSettings>;
91
- /**
92
- * The class pin (`offering_id`) an entry runs on: an override — including an
93
- * explicit `null` removal — wins over the defaults. Never `overrides ?? defaults`
94
- * (a removal is `null`, which `??` would fall through to the default's pin).
95
- */
96
- export declare function effectiveOfferingPinOf(entry: {
97
- defaults?: Partial<AgentSettings>;
98
- overrides?: Partial<AgentSettings>;
99
- } | null | undefined): string | undefined;
100
- /**
101
- * Build the payload to send to the Python backend for a given context.
102
- *
103
- * - 'builder': full effective settings minus UI-only flags
104
- * - 'chat': only the overrides delta minus UI-only flags
105
- * (backend already has the agent's defaults — only send what changed)
106
- * - 'test': same as builder (full effective settings)
107
- */
108
- export declare function buildApiPayload(effectiveSettings: Partial<AgentSettings>, overrides: Partial<AgentSettings>, context: AgentContext): Partial<AgentSettings>;
109
- /**
110
- * Merge defaults + overrides into the effective settings the UI should display.
111
- * Overrides take precedence field-by-field.
112
- */
113
- export declare function mergeEffectiveSettings(defaults: Partial<AgentSettings>, overrides: Partial<AgentSettings>): Partial<AgentSettings>;
114
- /**
115
- * Produce a flat name→value map from variable_defaults merged with variable_overrides.
116
- * Used by variable input components to read current values without prop drilling.
117
- */
118
- export declare function mergeVariableValues(variableDefaults: AgentVariable[], variableOverrides: Record<string, string>): Record<string, string>;
119
- /**
120
- * Strip null/undefined fields from a settings object.
121
- * Used when loading from DB to ensure the state is clean.
122
- */
123
- export declare function sanitizeSettings(raw: Record<string, unknown> | null | undefined): Partial<AgentSettings>;
1
+ /** Agent settings live in the agent core (B4): `@ai-matrx/agents/settings`. */
2
+ export * from "@ai-matrx/agents/settings";
@@ -1,315 +1 @@
1
- import { LLM_PARAMS_KEYS } from "@ai-matrx/agents/generated/llm-enums";
2
- import { outputFormatControlKey } from "@ai-matrx/agents/models";
3
- import { isUiGateKey, UI_GATE_KEYS } from "./ui-gates.js";
4
- const PARAM_ALIASES = {
5
- max_tokens: ["max_output_tokens", "max_completion_tokens", "max_new_tokens"],
6
- max_output_tokens: ["max_tokens", "max_completion_tokens", "max_new_tokens"],
7
- max_completion_tokens: ["max_tokens", "max_output_tokens"],
8
- max_new_tokens: ["max_tokens", "max_output_tokens"],
9
- stop: ["stop_sequences"],
10
- stop_sequences: ["stop"],
11
- top_k: ["top_k_tokens"],
12
- top_k_tokens: ["top_k"],
13
- presence_penalty: ["repetition_penalty"],
14
- repetition_penalty: ["presence_penalty"],
15
- reasoning_budget: ["thinking_budget"],
16
- thinking_budget: ["reasoning_budget"]
17
- };
18
- const ALL_KNOWN_KEYS = /* @__PURE__ */ new Set([
19
- ...LLM_PARAMS_KEYS,
20
- // Legacy DB keys — normalizer converts at Redux boundary, but we still recognize them
21
- "max_tokens",
22
- "output_format",
23
- "n",
24
- // Frontend-only capability flags (never sent to the API)
25
- "tools",
26
- "file_urls",
27
- "image_urls",
28
- "youtube_videos",
29
- "multi_speaker",
30
- "internal_web_search",
31
- "internal_url_context",
32
- // Backend param not yet in generated types
33
- "image_loras",
34
- // Stop sequences
35
- "stop_sequences"
36
- ]);
37
- function parseModelControls(rawControls) {
38
- if (!rawControls || typeof rawControls !== "object" || Array.isArray(rawControls)) {
39
- return { rawControls: {}, unmappedControls: {} };
40
- }
41
- let controls = rawControls;
42
- const normalized = {
43
- rawControls: controls,
44
- unmappedControls: {}
45
- };
46
- for (const [key, value] of Object.entries(controls)) {
47
- if (!ALL_KNOWN_KEYS.has(key)) {
48
- normalized.unmappedControls[key] = value;
49
- continue;
50
- }
51
- const normalizedKey = outputFormatControlKey(key, value);
52
- if (typeof value !== "object" || value === null || Array.isArray(value)) {
53
- continue;
54
- }
55
- const rawControl = value;
56
- const rawDefault = rawControl.default;
57
- const flatDefault = rawDefault !== null && typeof rawDefault === "object" && !Array.isArray(rawDefault) && "type" in rawDefault ? String(rawDefault.type) : rawDefault;
58
- const controlDef = {
59
- type: rawControl.type || "string",
60
- min: rawControl.min,
61
- max: rawControl.max,
62
- default: flatDefault,
63
- required: rawControl.required
64
- };
65
- if (Array.isArray(rawControl.enum)) {
66
- controlDef.enum = rawControl.enum.map((option) => {
67
- if (option !== null && typeof option === "object" && "type" in option) {
68
- return String(option.type);
69
- }
70
- return String(option);
71
- });
72
- controlDef.type = "enum";
73
- } else if ("allowed" in rawControl) {
74
- controlDef.type = "boolean";
75
- controlDef.default = rawControl.allowed;
76
- controlDef.isFeatureFlag = true;
77
- } else if (typeof rawControl.default === "boolean") {
78
- controlDef.type = "boolean";
79
- } else if (rawControl.type === void 0 && (rawControl.min !== void 0 || rawControl.max !== void 0)) {
80
- controlDef.type = rawControl.default !== void 0 && Number.isInteger(rawControl.default) ? "integer" : "number";
81
- }
82
- normalized[normalizedKey] = controlDef;
83
- }
84
- return normalized;
85
- }
86
- function extractModelDefaults(rawControls) {
87
- if (!rawControls || typeof rawControls !== "object" || Array.isArray(rawControls)) {
88
- return {};
89
- }
90
- const defaults = {};
91
- for (const [key, value] of Object.entries(rawControls)) {
92
- if (typeof value !== "object" || value === null || Array.isArray(value)) {
93
- continue;
94
- }
95
- const rawControl = value;
96
- const normalizedKey = outputFormatControlKey(key, value);
97
- if (isUiGateKey(normalizedKey)) {
98
- if (normalizedKey === "tools") {
99
- if (rawControl.allowed === true) {
100
- defaults.tools = [];
101
- }
102
- } else {
103
- const flagValue = "allowed" in rawControl ? rawControl.allowed : rawControl.default;
104
- if (flagValue !== null && flagValue !== void 0) {
105
- defaults[normalizedKey] = Boolean(flagValue);
106
- }
107
- }
108
- continue;
109
- }
110
- let defaultValue;
111
- if (rawControl.default !== void 0 && rawControl.default !== null) {
112
- defaultValue = rawControl.default;
113
- } else if ("allowed" in rawControl) {
114
- defaultValue = rawControl.allowed;
115
- } else if (Array.isArray(rawControl.enum) && rawControl.enum.length > 0 && rawControl.default === void 0) {
116
- defaultValue = void 0;
117
- }
118
- if (defaultValue === void 0 || defaultValue === null) continue;
119
- if (typeof defaultValue === "object" && !Array.isArray(defaultValue) && "type" in defaultValue) {
120
- defaultValue = String(defaultValue.type);
121
- }
122
- if (normalizedKey === "response_format") {
123
- if (typeof defaultValue === "string") {
124
- if (defaultValue === "text" || defaultValue === "") continue;
125
- defaults[normalizedKey] = { type: defaultValue };
126
- } else {
127
- defaults[normalizedKey] = defaultValue;
128
- }
129
- continue;
130
- }
131
- defaults[normalizedKey] = defaultValue;
132
- }
133
- return defaults;
134
- }
135
- function detectConflicts(currentSettings, newControls, newDefaults) {
136
- const conflicts = [];
137
- const supportedKeys = [];
138
- const skipKeys = /* @__PURE__ */ new Set(["model", "offering_id"]);
139
- for (const [rawKey, currentValue] of Object.entries(currentSettings)) {
140
- const key = rawKey;
141
- if (skipKeys.has(key)) continue;
142
- if (currentValue === void 0 || currentValue === null) continue;
143
- const controlDef = newControls[key];
144
- if (!controlDef) {
145
- const aliasHint = findAliasHint(key, newControls);
146
- conflicts.push({
147
- key,
148
- currentValue,
149
- newModelDefault: newDefaults[key] ?? null,
150
- reason: "unsupported_key",
151
- // Kept by default (keep_all): the server translates it for this model.
152
- description: aliasHint ? `Translated for this model. Its own setting is "${aliasHint}".` : "Translated for this model.",
153
- aliasHint: aliasHint ?? void 0
154
- });
155
- continue;
156
- }
157
- if ((controlDef.type === "number" || controlDef.type === "integer") && typeof currentValue === "number") {
158
- const tooLow = controlDef.min !== void 0 && currentValue < controlDef.min;
159
- const tooHigh = controlDef.max !== void 0 && currentValue > controlDef.max;
160
- if (tooLow || tooHigh) {
161
- const rangeStr = formatRange(controlDef);
162
- conflicts.push({
163
- key,
164
- currentValue,
165
- newModelDefault: newDefaults[key] ?? controlDef.default ?? null,
166
- reason: "value_out_of_range",
167
- description: `Value ${currentValue} is outside the supported range ${rangeStr}.`
168
- });
169
- continue;
170
- }
171
- }
172
- if (controlDef.type === "enum" && Array.isArray(controlDef.enum) && typeof currentValue === "string") {
173
- if (!controlDef.enum.includes(currentValue)) {
174
- conflicts.push({
175
- key,
176
- currentValue,
177
- newModelDefault: newDefaults[key] ?? controlDef.default ?? null,
178
- reason: "invalid_enum_value",
179
- description: `"${currentValue}" is not valid for this model. Supported: ${controlDef.enum.join(", ")}.`
180
- });
181
- continue;
182
- }
183
- }
184
- supportedKeys.push(key);
185
- }
186
- return { conflicts, supportedKeys };
187
- }
188
- function findAliasHint(key, controls) {
189
- const aliases = PARAM_ALIASES[key];
190
- if (!aliases) return null;
191
- return aliases.find(
192
- (alias) => controls[alias] !== void 0
193
- ) ?? null;
194
- }
195
- function formatRange(def) {
196
- if (def.min !== void 0 && def.max !== void 0) {
197
- return `[${def.min}, ${def.max}]`;
198
- }
199
- if (def.min !== void 0) return `[${def.min}, \u221E)`;
200
- if (def.max !== void 0) return `(-\u221E, ${def.max}]`;
201
- return "(unbounded)";
202
- }
203
- function resolveConflicts(currentSettings, pending) {
204
- const resolved = { ...currentSettings };
205
- for (const conflict of pending.conflicts) {
206
- const action = getActionForMode(
207
- pending.mode,
208
- conflict,
209
- pending.customActions
210
- );
211
- if (action === "reset") {
212
- if (conflict.reason !== "unsupported_key" && conflict.newModelDefault !== void 0 && conflict.newModelDefault !== null) {
213
- resolved[conflict.key] = conflict.newModelDefault;
214
- } else {
215
- delete resolved[conflict.key];
216
- }
217
- }
218
- }
219
- return resolved;
220
- }
221
- function getActionForMode(mode, conflict, customActions) {
222
- switch (mode) {
223
- case "keep_all":
224
- return "keep";
225
- case "auto_resolve":
226
- return "reset";
227
- case "remove_only":
228
- return conflict.reason === "unsupported_key" ? "reset" : "keep";
229
- case "custom":
230
- return customActions[conflict.key] ?? "keep";
231
- }
232
- }
233
- function computeOverrideDiff(defaults, proposed) {
234
- const diff = {};
235
- const defaultsRecord = defaults;
236
- const proposedRecord = proposed;
237
- for (const [key, proposedValue] of Object.entries(proposedRecord)) {
238
- if (proposedValue === void 0 || proposedValue === null) continue;
239
- const defaultValue = defaultsRecord[key];
240
- if (JSON.stringify(proposedValue) !== JSON.stringify(defaultValue)) {
241
- diff[key] = proposedValue;
242
- }
243
- }
244
- for (const [key, defaultValue] of Object.entries(defaultsRecord)) {
245
- if (defaultValue === void 0 || defaultValue === null) continue;
246
- const proposedValue = proposedRecord[key];
247
- if (proposedValue === void 0 || proposedValue === null) {
248
- diff[key] = null;
249
- }
250
- }
251
- return diff;
252
- }
253
- function effectiveOfferingPinOf(entry) {
254
- if (!entry) return void 0;
255
- const overrides = entry.overrides ?? {};
256
- const raw = "offering_id" in overrides ? overrides.offering_id : entry.defaults?.offering_id;
257
- return typeof raw === "string" && raw !== "" ? raw : void 0;
258
- }
259
- const UI_ONLY_SET = new Set(UI_GATE_KEYS);
260
- function buildApiPayload(effectiveSettings, overrides, context) {
261
- const source = context === "chat" ? overrides : effectiveSettings;
262
- const payload = {};
263
- for (const [key, value] of Object.entries(source)) {
264
- if (UI_ONLY_SET.has(key)) continue;
265
- if (value === void 0 || value === null) continue;
266
- payload[key] = value;
267
- }
268
- for (const [key, value] of Object.entries(overrides)) {
269
- if (UI_ONLY_SET.has(key)) continue;
270
- if (value === null) payload[key] = null;
271
- }
272
- return payload;
273
- }
274
- function mergeEffectiveSettings(defaults, overrides) {
275
- const merged = { ...defaults };
276
- for (const [key, value] of Object.entries(overrides)) {
277
- if (value === null) delete merged[key];
278
- else if (value !== void 0) merged[key] = value;
279
- }
280
- return merged;
281
- }
282
- function mergeVariableValues(variableDefaults, variableOverrides) {
283
- const result = {};
284
- for (const variable of variableDefaults) {
285
- result[variable.name] = String(variable.defaultValue ?? "");
286
- }
287
- for (const [name, value] of Object.entries(variableOverrides)) {
288
- result[name] = value;
289
- }
290
- return result;
291
- }
292
- function sanitizeSettings(raw) {
293
- if (!raw || typeof raw !== "object") return {};
294
- const clean = {};
295
- for (const [key, value] of Object.entries(raw)) {
296
- if (value !== null && value !== void 0) {
297
- clean[key] = value;
298
- }
299
- }
300
- return clean;
301
- }
302
- export {
303
- PARAM_ALIASES,
304
- buildApiPayload,
305
- computeOverrideDiff,
306
- detectConflicts,
307
- effectiveOfferingPinOf,
308
- extractModelDefaults,
309
- getActionForMode,
310
- mergeEffectiveSettings,
311
- mergeVariableValues,
312
- parseModelControls,
313
- resolveConflicts,
314
- sanitizeSettings
315
- };
1
+ export * from "@ai-matrx/agents/settings";
@@ -1,78 +1,2 @@
1
- /**
2
- * Model Settings Catalogue — the single source of truth for the STANDARD
3
- * settings list, and the one chokepoint that decides which keys it contains.
4
- *
5
- * ── The model (two distinct surfaces) ────────────────────────────────────────
6
- * 1. STANDARD list — ONLY the keys the selected model explicitly declares in
7
- * its `controls` config (i.e. the parameters this model actually supports).
8
- * `buildSettingsRows()` returns exactly these, grouped + ordered. Catalogue
9
- * keys the model does not declare are NOT shown here.
10
- * 2. CAUTION surface — settings the agent has SET that the model does NOT
11
- * support. These are never hidden: they are flagged as "not valid for this
12
- * model" and made repairable by the validation layer (the IssueTable, fed
13
- * by the `unsupported_by_model` rule). They do NOT belong in the standard
14
- * list — that is exactly the "showing all possible keys" bug.
15
- *
16
- * The catalogue exists so the standard list's labels, grouping and order live
17
- * in ONE place (previously copy-pasted as `textModelSettings` /
18
- * `booleanSettings` / ... into three components, each filtering by
19
- * `getControl(key)` inline — which drifted and regressed). Components map over
20
- * `buildSettingsRows()`; they must not filter by model themselves (ESLint
21
- * enforces). The original recurring bug — set values silently dropped when a
22
- * model didn't support them — is fixed by the CAUTION surface, not by dumping
23
- * every key into the standard list.
24
- *
25
- * Guardrail: `settings-catalogue.test.ts` asserts the standard list contains
26
- * ONLY supported keys (never the full catalogue), and `unsupported-by-model.
27
- * test.ts` asserts set-but-unsupported keys surface in the caution layer.
28
- */
29
- import type { ControlDefinition } from "./types.js";
30
- export type SettingsGroupId = "text" | "featureFlags" | "imageVideo" | "audio" | "other";
31
- export interface CatalogueEntry {
32
- key: string;
33
- label: string;
34
- }
35
- export interface CatalogueGroup {
36
- id: SettingsGroupId;
37
- /** Section header shown above the group. Empty string = no header (lead group). */
38
- label: string;
39
- entries: CatalogueEntry[];
40
- }
41
- export declare const SETTINGS_CATALOGUE: CatalogueGroup[];
42
- /** Flat set of every key the catalogue declares. */
43
- export declare const CATALOGUE_KEYS: ReadonlySet<string>;
44
- export interface SettingsRow {
45
- key: string;
46
- label: string;
47
- group: SettingsGroupId;
48
- /** The model's control definition for this key. Standard rows are always
49
- * supported, so this is present; typed nullable for consumer convenience. */
50
- control: ControlDefinition | null;
51
- /** Always true for rows returned by buildSettingsRows (standard = supported). */
52
- supported: boolean;
53
- /** True when the current settings hold a non-null value for this key. */
54
- hasValue: boolean;
55
- }
56
- export interface RenderGroup {
57
- id: SettingsGroupId;
58
- label: string;
59
- rows: SettingsRow[];
60
- }
61
- /** A minimal structural view of a model's normalized controls. Accepts either
62
- * NormalizedControls variant in the codebase (both are a key→ControlDefinition
63
- * map plus rawControls/unmappedControls). */
64
- type ControlsLike = Record<string, unknown> | null | undefined;
65
- /**
66
- * Build the STANDARD settings list for the selected model.
67
- *
68
- * CONTRACT: returns ONLY keys the model declares a control for (supported).
69
- * Catalogue keys the model does not declare are omitted — they are not "shown"
70
- * in the standard list. Set-but-unsupported keys are NOT returned here either;
71
- * the caution layer (validation IssueTable) surfaces and repairs those.
72
- *
73
- * The catch-all "Other" group carries supported keys the model declares that
74
- * the catalogue doesn't name yet — so a brand-new model control still appears
75
- * without a code change. Empty groups are returned (consumers skip them).
76
- */
77
- export declare function buildSettingsRows(controls: ControlsLike, settings: Record<string, unknown> | null | undefined): RenderGroup[];
78
- export {};
1
+ /** Agent settings live in the agent core (B4): `@ai-matrx/agents/settings`. */
2
+ export * from "@ai-matrx/agents/settings";