@ai-matrx/chat 0.5.17 → 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.
- package/CHANGELOG.md +12 -0
- package/dist/agents/components/identity-refs/AiIdentityRef.d.ts +33 -0
- package/dist/agents/components/identity-refs/AiIdentityRef.js +138 -0
- package/dist/agents/components/inputs/smart-input/QuicksetPanel.js +5 -9
- package/dist/agents/components/inputs/smart-input/RunSkillPicker.js +1 -1
- package/dist/agents/components/inputs/smart-input/RunToolPicker.js +6 -11
- package/dist/agents/components/inputs/smart-input/ShapeChipsRow.js +1 -1
- package/dist/agents/components/inputs/smart-input/composer/ComposerEffortPill.js +1 -1
- package/dist/agents/components/inputs/smart-input/composer/ComposerOutput.js +1 -1
- package/dist/agents/components/inputs/smart-input/composer/ComposerPlusMenu.js +1 -1
- package/dist/agents/components/inputs/smart-input/composer/useComposerAgent.js +1 -1
- package/dist/agents/components/inputs/smart-input/composer/useRunControlCounts.d.ts +3 -0
- package/dist/agents/components/inputs/smart-input/composer/useRunControlCounts.js +54 -0
- package/dist/agents/components/model-tiers/ModelTierIdentityList.js +1 -1
- package/dist/agents/components/run-controls/RunConfigOverrides.js +1 -1
- package/dist/agents/components/run-controls/RunInputCapabilities.js +1 -1
- package/dist/agents/components/run-controls/panels/shared.d.ts +0 -2
- package/dist/agents/hooks/useDiffEnrichment.js +3 -6
- package/dist/agents/identity/agent-catalog-lists.js +2 -1
- package/dist/agents/identity/agent-identity.js +2 -1
- package/dist/agents/identity/model-catalog.d.ts +9 -0
- package/dist/agents/identity/model-catalog.js +25 -0
- package/dist/agents/identity/preferred-chat-model.d.ts +9 -0
- package/dist/agents/identity/preferred-chat-model.js +33 -0
- package/dist/agents/identity/settings-store.d.ts +10 -0
- package/dist/agents/identity/settings-store.js +49 -0
- package/dist/agents/identity/skill-catalog.d.ts +27 -0
- package/dist/agents/identity/skill-catalog.js +100 -0
- package/dist/agents/identity/tool-catalog.d.ts +15 -0
- package/dist/agents/identity/tool-catalog.js +67 -0
- package/dist/agents/redux/agent-definition/cache-bust-middleware.d.ts +0 -1
- package/dist/agents/redux/agent-definition/cache-bust-middleware.js +1 -13
- package/dist/agents/redux/agent-definition/selectors.d.ts +12 -546
- package/dist/agents/redux/agent-settings/internal-utils.d.ts +2 -123
- package/dist/agents/redux/agent-settings/internal-utils.js +1 -315
- package/dist/agents/redux/agent-settings/settings-catalogue.d.ts +2 -78
- package/dist/agents/redux/agent-settings/settings-catalogue.js +1 -176
- package/dist/agents/redux/agent-settings/types.d.ts +2 -148
- package/dist/agents/redux/agent-settings/types.js +1 -0
- package/dist/agents/redux/agent-settings/ui-gates.d.ts +2 -54
- package/dist/agents/redux/agent-settings/ui-gates.js +1 -38
- package/dist/agents/redux/agent-shortcut-categories/selectors.d.ts +0 -100
- package/dist/agents/redux/agent-shortcuts/selectors.d.ts +0 -294
- package/dist/agents/redux/conversation-history/selectors.d.ts +0 -32
- package/dist/agents/redux/conversation-list/conversation-list.selectors.d.ts +0 -4
- package/dist/agents/redux/execution-system/active-requests/active-requests.selectors.d.ts +0 -108
- package/dist/agents/redux/execution-system/context-state/context-state.selectors.d.ts +0 -28
- package/dist/agents/redux/execution-system/conversations/conversations.selectors.d.ts +0 -10
- package/dist/agents/redux/execution-system/instance-context/instance-context.selectors.d.ts +0 -6
- package/dist/agents/redux/execution-system/instance-model-overrides/launch-model-overrides.js +1 -1
- package/dist/agents/redux/execution-system/instance-resources/instance-resources.selectors.d.ts +0 -16
- package/dist/agents/redux/execution-system/instance-ui-state/instance-ui-state.selectors.d.ts +0 -10
- package/dist/agents/redux/execution-system/instance-variable-values/instance-variable-values.selectors.d.ts +0 -14
- package/dist/agents/redux/execution-system/messages/messages.selectors.d.ts +0 -2
- package/dist/agents/redux/execution-system/observability/observability.selectors.d.ts +0 -14
- package/dist/agents/redux/execution-system/observational-memory/observational-memory.selectors.d.ts +0 -2
- package/dist/agents/redux/execution-system/selectors/aggregate.selectors.d.ts +0 -28
- package/dist/agents/redux/execution-system/thunks/execute-instance.thunk.js +1 -1
- package/dist/agents/redux/execution-system/thunks/load-conversation.thunk.js +13 -2
- package/dist/agents/redux/execution-system/thunks/process-stream.js +2 -5
- package/dist/agents/redux/execution-system/thunks/resolve-base-url.js +2 -1
- package/dist/agents/redux/execution-system/utils/loaded-skill-sources.d.ts +1 -1
- package/dist/agents/redux/execution-system/utils/loaded-skill-sources.js +3 -3
- package/dist/agents/redux/execution-system/utils/required-organization.d.ts +10 -0
- package/dist/agents/redux/execution-system/utils/required-organization.js +6 -1
- package/dist/agents/redux/proposed-directives/proposedDirectivesSlice.d.ts +0 -2
- package/dist/agents/types/instance.types.d.ts +9 -0
- package/dist/agents/ui-first-tools/redux/agent-lists.selectors.d.ts +0 -4
- package/dist/host/ui-slots.d.ts +0 -46
- package/dist/host/ui-slots.js +0 -33
- package/dist/store/create-chat-store.d.ts +0 -4
- package/dist/store/middlewares.d.ts +0 -10
- package/dist/store/slices.d.ts +0 -2
- package/dist/store/slices.js +0 -4
- package/dist/surfaces/redux/selectors.d.ts +0 -4
- package/dist/tool-call-visualization/redux/selectors.d.ts +0 -2
- package/dist/ui/chat-default-model-knob.d.ts +1 -1
- package/dist/ui/chat-default-model-knob.js +1 -1
- package/package.json +9 -9
- package/dist/agents/components/model/AgentModelPanel.d.ts +0 -4
- package/dist/agents/components/model/AgentModelPanel.js +0 -9
- package/dist/agents/redux/agent-settings/agentSettingsSlice.d.ts +0 -1015
- package/dist/agents/redux/agent-settings/agentSettingsSlice.js +0 -659
- package/dist/agents/redux/agent-settings/selectors.d.ts +0 -10057
- package/dist/agents/redux/agent-settings/selectors.js +0 -234
- package/dist/agents/redux/agent-settings/useNormalizedControls.d.ts +0 -8
- package/dist/agents/redux/agent-settings/useNormalizedControls.js +0 -24
- package/dist/agents/redux/tools/tools.selectors.d.ts +0 -529
- package/dist/agents/redux/tools/tools.selectors.js +0 -24
- package/dist/agents/redux/tools/tools.slice.d.ts +0 -12
- package/dist/agents/redux/tools/tools.slice.js +0 -37
- package/dist/agents/redux/tools/tools.thunks.d.ts +0 -125
- package/dist/agents/redux/tools/tools.thunks.js +0 -45
- package/dist/host/defaults/setting-control-input.d.ts +0 -11
- package/dist/host/defaults/setting-control-input.js +0 -91
|
@@ -1,123 +1,2 @@
|
|
|
1
|
-
/**
|
|
2
|
-
*
|
|
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
|
-
|
|
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
|
-
*
|
|
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";
|