@ai-matrx/chat 0.3.33 → 0.4.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 +20 -0
- package/dist/agents/components/ambient-assistant/intelligence-places.js +2 -2
- package/dist/agents/components/chat/intelligence-places.js +7 -7
- package/dist/agents/components/inputs/smart-input/RunToolPicker.js +7 -13
- package/dist/agents/components/inputs/smart-input/composer/ComposerAgentPill.js +3 -2
- package/dist/agents/components/inputs/smart-input/composer/useComposerAgent.js +5 -5
- package/dist/agents/components/inputs/smart-input/composer/useComposerAgentFilter.js +3 -2
- package/dist/agents/components/run-controls/RunConfigOverrides.js +10 -16
- package/dist/agents/components/run-controls/panels/shared.d.ts +0 -1
- package/dist/agents/hooks/useAgentModelLabel.js +4 -3
- package/dist/agents/hooks/useDiffEnrichment.js +3 -5
- package/dist/agents/hooks/useModelControls.d.ts +5 -161
- package/dist/agents/identity/model-catalog.d.ts +37 -0
- package/dist/agents/identity/model-catalog.js +103 -0
- package/dist/agents/redux/agent-definition/selectors.d.ts +0 -237
- package/dist/agents/redux/agent-definition/thunks.d.ts +1 -1
- package/dist/agents/redux/agent-settings/agentSettingsSlice.d.ts +1 -1
- package/dist/agents/redux/agent-settings/agentSettingsSlice.js +4 -6
- package/dist/agents/redux/agent-settings/selectors.d.ts +1 -152
- package/dist/agents/redux/agent-settings/selectors.js +0 -39
- package/dist/agents/redux/agent-settings/useNormalizedControls.d.ts +8 -0
- package/dist/agents/redux/agent-settings/useNormalizedControls.js +24 -0
- package/dist/agents/redux/agent-shortcut-categories/selectors.d.ts +0 -50
- package/dist/agents/redux/agent-shortcuts/selectors.d.ts +0 -147
- package/dist/agents/redux/conversation-history/selectors.d.ts +0 -16
- package/dist/agents/redux/conversation-list/conversation-list.selectors.d.ts +0 -2
- package/dist/agents/redux/execution-system/active-requests/active-requests.selectors.d.ts +0 -54
- package/dist/agents/redux/execution-system/context-state/context-state.selectors.d.ts +0 -14
- package/dist/agents/redux/execution-system/conversations/conversations.selectors.d.ts +0 -5
- package/dist/agents/redux/execution-system/instance-context/instance-context.selectors.d.ts +0 -3
- package/dist/agents/redux/execution-system/instance-resources/instance-resources.selectors.d.ts +0 -8
- package/dist/agents/redux/execution-system/instance-ui-state/instance-ui-state.selectors.d.ts +0 -5
- package/dist/agents/redux/execution-system/instance-variable-values/instance-variable-values.selectors.d.ts +0 -7
- package/dist/agents/redux/execution-system/messages/messages.selectors.d.ts +0 -1
- package/dist/agents/redux/execution-system/observability/observability.selectors.d.ts +0 -7
- package/dist/agents/redux/execution-system/observational-memory/observational-memory.selectors.d.ts +0 -1
- package/dist/agents/redux/execution-system/selectors/aggregate.selectors.d.ts +0 -14
- package/dist/agents/redux/execution-system/thunks/execute-manual-instance.thunk.js +2 -2
- package/dist/agents/redux/model-registry.d.ts +6 -4
- package/dist/agents/redux/model-registry.js +23 -5
- package/dist/agents/redux/proposed-directives/proposedDirectivesSlice.d.ts +0 -1
- package/dist/agents/redux/tools/tools.selectors.d.ts +0 -1
- package/dist/agents/runtime/generation-job.js +4 -7
- package/dist/agents/runtime/get-model-capabilities.js +3 -3
- package/dist/agents/ui-first-tools/redux/agent-lists.selectors.d.ts +0 -2
- package/dist/host/db-types.d.ts +276 -9
- package/dist/store/create-chat-store.d.ts +0 -2
- package/dist/store/middlewares.d.ts +0 -5
- package/dist/store/slices.d.ts +0 -1
- package/dist/store/slices.js +0 -2
- package/dist/surfaces/redux/selectors.d.ts +0 -2
- package/dist/tool-call-visualization/intelligence-places.js +1 -1
- package/dist/tool-call-visualization/redux/selectors.d.ts +0 -1
- package/dist/voice-agent/intelligence-places.js +6 -6
- package/package.json +5 -5
- package/dist/agents/model-registry/modelRegistrySlice.d.ts +0 -691
- package/dist/agents/model-registry/modelRegistrySlice.js +0 -574
- package/dist/host/model-class.d.ts +0 -33
- package/dist/host/model-class.js +0 -21
|
@@ -1,574 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
createSlice,
|
|
3
|
-
createAsyncThunk,
|
|
4
|
-
createSelector
|
|
5
|
-
} from "@reduxjs/toolkit";
|
|
6
|
-
import { createClient } from "../../host/db.js";
|
|
7
|
-
import { extractErrorMessage } from "@ai-matrx/data/net";
|
|
8
|
-
import { recordUnavailable } from "../../host/diagnostics.js";
|
|
9
|
-
import { normalizeModel } from "@ai-matrx/agents/models";
|
|
10
|
-
import { requireCanonicalCapabilities } from "./parse.js";
|
|
11
|
-
import {
|
|
12
|
-
buildModelClassIndex,
|
|
13
|
-
modelClassName,
|
|
14
|
-
withModelClass
|
|
15
|
-
} from "./model-classes.js";
|
|
16
|
-
const classConfigKey = (modelId, offeringId) => `${modelId}:${offeringId}`;
|
|
17
|
-
const initialState = {
|
|
18
|
-
entities: {},
|
|
19
|
-
activeIds: [],
|
|
20
|
-
deprecatedIds: [],
|
|
21
|
-
fetchScope: null,
|
|
22
|
-
isLoading: false,
|
|
23
|
-
error: null,
|
|
24
|
-
lastFetched: null,
|
|
25
|
-
detailStatusById: {},
|
|
26
|
-
detailErrorById: {},
|
|
27
|
-
identityById: {},
|
|
28
|
-
identityStatusById: {},
|
|
29
|
-
classConfigByOffering: {},
|
|
30
|
-
classConfigStatusByOffering: {},
|
|
31
|
-
modelClassIndex: null
|
|
32
|
-
};
|
|
33
|
-
const fetchModelOptions = createAsyncThunk(
|
|
34
|
-
"modelRegistry/fetchModelOptions",
|
|
35
|
-
async (_, { rejectWithValue }) => {
|
|
36
|
-
try {
|
|
37
|
-
const supabase = createClient();
|
|
38
|
-
const { data: offeringRows, error: offeringError } = await supabase.schema("ai").from("model_offering").select("model_id");
|
|
39
|
-
if (offeringError) throw offeringError;
|
|
40
|
-
const routableIds = [
|
|
41
|
-
...new Set(
|
|
42
|
-
(offeringRows ?? []).map((r) => r.model_id).filter(
|
|
43
|
-
(id) => typeof id === "string" && id.length > 0
|
|
44
|
-
)
|
|
45
|
-
)
|
|
46
|
-
];
|
|
47
|
-
if (routableIds.length === 0) {
|
|
48
|
-
return [];
|
|
49
|
-
}
|
|
50
|
-
const { data, error } = await supabase.schema("ai").from("model_public").select(
|
|
51
|
-
"id, name, common_name, maker, cost_rating, speed_rating, is_primary, capabilities, is_deprecated, retired_at, successor_id"
|
|
52
|
-
).in("id", routableIds).order("common_name", { ascending: true, nullsFirst: false });
|
|
53
|
-
if (error) throw error;
|
|
54
|
-
return (data ?? []).filter(
|
|
55
|
-
(r) => typeof r.id === "string" && typeof r.name === "string"
|
|
56
|
-
).map((r) => ({
|
|
57
|
-
id: r.id,
|
|
58
|
-
name: r.name,
|
|
59
|
-
common_name: r.common_name,
|
|
60
|
-
maker: r.maker,
|
|
61
|
-
cost_rating: r.cost_rating,
|
|
62
|
-
speed_rating: r.speed_rating,
|
|
63
|
-
is_primary: r.is_primary,
|
|
64
|
-
capabilities: requireCanonicalCapabilities(r.capabilities, {
|
|
65
|
-
modelId: r.id,
|
|
66
|
-
modelName: r.name
|
|
67
|
-
}),
|
|
68
|
-
is_deprecated: r.is_deprecated,
|
|
69
|
-
retired_at: r.retired_at,
|
|
70
|
-
successor_id: r.successor_id
|
|
71
|
-
}));
|
|
72
|
-
} catch (err) {
|
|
73
|
-
return rejectWithValue(
|
|
74
|
-
extractErrorMessage(err, "Unknown error")
|
|
75
|
-
);
|
|
76
|
-
}
|
|
77
|
-
},
|
|
78
|
-
{
|
|
79
|
-
condition: (_, { getState }) => {
|
|
80
|
-
const { fetchScope, isLoading } = getState().modelRegistry;
|
|
81
|
-
const shouldFetch = fetchScope !== "active" && fetchScope !== "all" && !isLoading;
|
|
82
|
-
if (!shouldFetch) {
|
|
83
|
-
}
|
|
84
|
-
return shouldFetch;
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
);
|
|
88
|
-
const fetchModelClassConfig = createAsyncThunk(
|
|
89
|
-
"modelRegistry/fetchModelClassConfig",
|
|
90
|
-
async ({ modelId, offeringId }, { rejectWithValue }) => {
|
|
91
|
-
try {
|
|
92
|
-
const supabase = createClient();
|
|
93
|
-
const { data, error } = await supabase.schema("ai").rpc("resolve_model_config", {
|
|
94
|
-
p_model_id: modelId,
|
|
95
|
-
p_offering_id: offeringId
|
|
96
|
-
});
|
|
97
|
-
if (error) throw error;
|
|
98
|
-
const cfg = data && typeof data === "object" && !Array.isArray(data) ? data : null;
|
|
99
|
-
return {
|
|
100
|
-
key: classConfigKey(modelId, offeringId),
|
|
101
|
-
config: {
|
|
102
|
-
modelId,
|
|
103
|
-
controls: cfg?.controls ?? null,
|
|
104
|
-
constraints: cfg?.constraints ?? null
|
|
105
|
-
}
|
|
106
|
-
};
|
|
107
|
-
} catch (err) {
|
|
108
|
-
return rejectWithValue(
|
|
109
|
-
`Model class configuration ${modelId} / ${offeringId}: ${extractErrorMessage(err)}`
|
|
110
|
-
);
|
|
111
|
-
}
|
|
112
|
-
},
|
|
113
|
-
{
|
|
114
|
-
// A failed load (refused pin, network) is retried the next time a surface
|
|
115
|
-
// asks — never cached as a permanent "not available".
|
|
116
|
-
condition: ({ modelId, offeringId }, { getState }) => {
|
|
117
|
-
const status = getState().modelRegistry?.classConfigStatusByOffering?.[classConfigKey(modelId, offeringId)];
|
|
118
|
-
return status !== "loading" && status !== "succeeded";
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
);
|
|
122
|
-
const fetchModelClasses = createAsyncThunk(
|
|
123
|
-
"modelRegistry/fetchModelClasses",
|
|
124
|
-
async (_, { rejectWithValue }) => {
|
|
125
|
-
try {
|
|
126
|
-
const supabase = createClient();
|
|
127
|
-
const { data, error } = await supabase.schema("ai").from("model_offering").select("model_id, offering_id, served_via, served_via_endpoint_id, priority");
|
|
128
|
-
if (error) throw error;
|
|
129
|
-
return buildModelClassIndex(data ?? []);
|
|
130
|
-
} catch (err) {
|
|
131
|
-
return rejectWithValue(`Model classes: ${extractErrorMessage(err)}`);
|
|
132
|
-
}
|
|
133
|
-
},
|
|
134
|
-
{
|
|
135
|
-
condition: (_, { getState }) => {
|
|
136
|
-
const status = getState().modelRegistry?.modelClassStatus;
|
|
137
|
-
return status !== "loading" && status !== "succeeded";
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
);
|
|
141
|
-
const fetchModelIdentityById = createAsyncThunk(
|
|
142
|
-
"modelRegistry/fetchIdentityById",
|
|
143
|
-
async (modelId) => {
|
|
144
|
-
const supabase = createClient();
|
|
145
|
-
const { data, error } = await supabase.schema("ai").from("model_definition").select("id, name, common_name, is_deprecated").eq("id", modelId).maybeSingle();
|
|
146
|
-
if (error) throw error;
|
|
147
|
-
if (!data)
|
|
148
|
-
throw recordUnavailable({
|
|
149
|
-
entity: "AI model",
|
|
150
|
-
reason: "unknown",
|
|
151
|
-
recordId: modelId,
|
|
152
|
-
token: "ai_model",
|
|
153
|
-
relation: "model_definition"
|
|
154
|
-
});
|
|
155
|
-
return data;
|
|
156
|
-
},
|
|
157
|
-
{
|
|
158
|
-
condition: (modelId, { getState }) => {
|
|
159
|
-
const state = getState().modelRegistry;
|
|
160
|
-
if (state.entities[modelId]) return false;
|
|
161
|
-
if (state.identityById[modelId]) return false;
|
|
162
|
-
const status = state.identityStatusById[modelId];
|
|
163
|
-
return status !== "loading" && status !== "succeeded" && status !== "failed";
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
|
-
);
|
|
167
|
-
const MODEL_CONFIG_COLUMNS = "id, name, common_name, maker, cost_rating, speed_rating, is_premium, is_primary, context_window, max_tokens, capabilities, controls, constraints, is_deprecated, retired_at, successor_id";
|
|
168
|
-
const fetchModelById = createAsyncThunk(
|
|
169
|
-
"modelRegistry/fetchModelById",
|
|
170
|
-
async (modelId, { rejectWithValue, getState }) => {
|
|
171
|
-
console.log(
|
|
172
|
-
"[modelRegistry] fetchModelById \u2014 fetching full record for",
|
|
173
|
-
modelId
|
|
174
|
-
);
|
|
175
|
-
const auth = getState();
|
|
176
|
-
const relation = auth.userAuth?.accessToken ? "model_config" : "model_public";
|
|
177
|
-
try {
|
|
178
|
-
const supabase = createClient();
|
|
179
|
-
const { data, error } = await supabase.schema("ai").from(relation).select(MODEL_CONFIG_COLUMNS).eq("id", modelId).maybeSingle();
|
|
180
|
-
if (error) throw error;
|
|
181
|
-
if (!data) {
|
|
182
|
-
throw recordUnavailable({
|
|
183
|
-
entity: "AI model",
|
|
184
|
-
reason: "unknown",
|
|
185
|
-
recordId: modelId,
|
|
186
|
-
token: "ai_model",
|
|
187
|
-
relation
|
|
188
|
-
});
|
|
189
|
-
}
|
|
190
|
-
if (!data.id || !data.name) {
|
|
191
|
-
throw new Error(
|
|
192
|
-
`ai.${relation} returned a row without id/name for model ${modelId}`
|
|
193
|
-
);
|
|
194
|
-
}
|
|
195
|
-
return normalizeModel({
|
|
196
|
-
id: data.id,
|
|
197
|
-
name: data.name,
|
|
198
|
-
common_name: data.common_name,
|
|
199
|
-
maker: data.maker,
|
|
200
|
-
cost_rating: data.cost_rating,
|
|
201
|
-
speed_rating: data.speed_rating,
|
|
202
|
-
is_premium: data.is_premium,
|
|
203
|
-
is_primary: data.is_primary,
|
|
204
|
-
context_window: data.context_window,
|
|
205
|
-
max_tokens: data.max_tokens,
|
|
206
|
-
capabilities: requireCanonicalCapabilities(data.capabilities, {
|
|
207
|
-
modelId: data.id,
|
|
208
|
-
modelName: data.name
|
|
209
|
-
}),
|
|
210
|
-
controls: data.controls,
|
|
211
|
-
constraints: data.constraints,
|
|
212
|
-
is_deprecated: data.is_deprecated,
|
|
213
|
-
retired_at: data.retired_at,
|
|
214
|
-
successor_id: data.successor_id
|
|
215
|
-
});
|
|
216
|
-
} catch (err) {
|
|
217
|
-
return rejectWithValue(
|
|
218
|
-
`Model configuration ${modelId}: ${extractErrorMessage(err)}`
|
|
219
|
-
);
|
|
220
|
-
}
|
|
221
|
-
},
|
|
222
|
-
{
|
|
223
|
-
condition: (modelId, { getState }) => {
|
|
224
|
-
const { entities, detailStatusById } = getState().modelRegistry;
|
|
225
|
-
const existing = entities[modelId];
|
|
226
|
-
if (detailStatusById?.[modelId] === "loading" || detailStatusById?.[modelId] === "failed")
|
|
227
|
-
return false;
|
|
228
|
-
if (existing?._fetchType === "full") {
|
|
229
|
-
console.log(
|
|
230
|
-
"[modelRegistry] fetchModelById skipped \u2014 already full for",
|
|
231
|
-
modelId
|
|
232
|
-
);
|
|
233
|
-
return false;
|
|
234
|
-
}
|
|
235
|
-
return true;
|
|
236
|
-
}
|
|
237
|
-
}
|
|
238
|
-
);
|
|
239
|
-
const modelRegistrySlice = createSlice({
|
|
240
|
-
name: "modelRegistry",
|
|
241
|
-
initialState,
|
|
242
|
-
reducers: {
|
|
243
|
-
retryModelDetail(state, action) {
|
|
244
|
-
delete state.detailStatusById[action.payload];
|
|
245
|
-
delete state.detailErrorById[action.payload];
|
|
246
|
-
},
|
|
247
|
-
/**
|
|
248
|
-
* SSR hydration path.
|
|
249
|
-
* Supply options-level or full records from the server shell.
|
|
250
|
-
* fetchType tells the slice how much data each record carries.
|
|
251
|
-
*/
|
|
252
|
-
hydrateModels(state, action) {
|
|
253
|
-
const { models, fetchType, fetchScope, lastFetched } = action.payload;
|
|
254
|
-
for (const raw of models) {
|
|
255
|
-
const id = raw.id;
|
|
256
|
-
const existing = state.entities[id];
|
|
257
|
-
if (existing?._fetchType === "full" && fetchType === "options")
|
|
258
|
-
continue;
|
|
259
|
-
state.entities[id] = {
|
|
260
|
-
...emptyModelRecord(),
|
|
261
|
-
...normalizeModel(raw),
|
|
262
|
-
_fetchType: fetchType
|
|
263
|
-
};
|
|
264
|
-
}
|
|
265
|
-
rebuildIdLists(state);
|
|
266
|
-
state.fetchScope = fetchScope;
|
|
267
|
-
state.lastFetched = lastFetched;
|
|
268
|
-
state.isLoading = false;
|
|
269
|
-
state.error = null;
|
|
270
|
-
}
|
|
271
|
-
},
|
|
272
|
-
extraReducers: (builder) => {
|
|
273
|
-
builder.addCase(fetchModelOptions.pending, (state) => {
|
|
274
|
-
state.isLoading = true;
|
|
275
|
-
state.error = null;
|
|
276
|
-
}).addCase(fetchModelOptions.fulfilled, (state, action) => {
|
|
277
|
-
state.isLoading = false;
|
|
278
|
-
state.error = null;
|
|
279
|
-
for (const row of action.payload) {
|
|
280
|
-
const existing = state.entities[row.id];
|
|
281
|
-
if (existing?._fetchType === "full") continue;
|
|
282
|
-
state.entities[row.id] = {
|
|
283
|
-
// Spread a skeleton so all AIModelRow fields exist (null for unfetched ones)
|
|
284
|
-
...emptyModelRecord(),
|
|
285
|
-
...existing,
|
|
286
|
-
...row,
|
|
287
|
-
_fetchType: "options"
|
|
288
|
-
};
|
|
289
|
-
}
|
|
290
|
-
rebuildIdLists(state);
|
|
291
|
-
if (state.fetchScope !== "all" && state.fetchScope !== "deprecated") {
|
|
292
|
-
state.fetchScope = "active";
|
|
293
|
-
}
|
|
294
|
-
state.lastFetched = Date.now();
|
|
295
|
-
}).addCase(fetchModelOptions.rejected, (state, action) => {
|
|
296
|
-
state.isLoading = false;
|
|
297
|
-
state.error = action.payload;
|
|
298
|
-
});
|
|
299
|
-
builder.addCase(fetchModelById.pending, (state, action) => {
|
|
300
|
-
state.detailStatusById[action.meta.arg] = "loading";
|
|
301
|
-
delete state.detailErrorById[action.meta.arg];
|
|
302
|
-
}).addCase(fetchModelById.fulfilled, (state, action) => {
|
|
303
|
-
state.detailStatusById[action.meta.arg] = "succeeded";
|
|
304
|
-
delete state.detailErrorById[action.meta.arg];
|
|
305
|
-
const record = action.payload;
|
|
306
|
-
const existing = state.entities[record.id];
|
|
307
|
-
state.entities[record.id] = {
|
|
308
|
-
...emptyModelRecord(),
|
|
309
|
-
...existing,
|
|
310
|
-
...record,
|
|
311
|
-
maker: record.maker ?? existing?.maker ?? null,
|
|
312
|
-
_fetchType: "full"
|
|
313
|
-
};
|
|
314
|
-
rebuildIdLists(state);
|
|
315
|
-
}).addCase(fetchModelById.rejected, (state, action) => {
|
|
316
|
-
state.detailStatusById[action.meta.arg] = "failed";
|
|
317
|
-
state.detailErrorById[action.meta.arg] = typeof action.payload === "string" ? action.payload : action.error.message ?? "Model configuration request failed";
|
|
318
|
-
});
|
|
319
|
-
builder.addCase(fetchModelClassConfig.pending, (state, action) => {
|
|
320
|
-
state.classConfigStatusByOffering[classConfigKey(action.meta.arg.modelId, action.meta.arg.offeringId)] = "loading";
|
|
321
|
-
}).addCase(fetchModelClassConfig.fulfilled, (state, action) => {
|
|
322
|
-
state.classConfigStatusByOffering[action.payload.key] = "succeeded";
|
|
323
|
-
state.classConfigByOffering[action.payload.key] = action.payload.config;
|
|
324
|
-
}).addCase(fetchModelClassConfig.rejected, (state, action) => {
|
|
325
|
-
state.classConfigStatusByOffering[classConfigKey(action.meta.arg.modelId, action.meta.arg.offeringId)] = "failed";
|
|
326
|
-
});
|
|
327
|
-
builder.addCase(fetchModelClasses.pending, (state) => {
|
|
328
|
-
state.modelClassStatus = "loading";
|
|
329
|
-
}).addCase(fetchModelClasses.fulfilled, (state, action) => {
|
|
330
|
-
state.modelClassStatus = "succeeded";
|
|
331
|
-
state.modelClassIndex = action.payload;
|
|
332
|
-
}).addCase(fetchModelClasses.rejected, (state, action) => {
|
|
333
|
-
state.modelClassStatus = "failed";
|
|
334
|
-
console.error("[modelRegistry]", action.payload ?? action.error.message);
|
|
335
|
-
});
|
|
336
|
-
builder.addCase(fetchModelIdentityById.pending, (state, action) => {
|
|
337
|
-
state.identityStatusById[action.meta.arg] = "loading";
|
|
338
|
-
}).addCase(fetchModelIdentityById.fulfilled, (state, action) => {
|
|
339
|
-
const row = action.payload;
|
|
340
|
-
state.identityById[row.id] = row;
|
|
341
|
-
state.identityStatusById[row.id] = "succeeded";
|
|
342
|
-
}).addCase(fetchModelIdentityById.rejected, (state, action) => {
|
|
343
|
-
state.identityStatusById[action.meta.arg] = "failed";
|
|
344
|
-
});
|
|
345
|
-
}
|
|
346
|
-
});
|
|
347
|
-
function emptyModelRecord() {
|
|
348
|
-
return {
|
|
349
|
-
id: "",
|
|
350
|
-
name: "",
|
|
351
|
-
common_name: null,
|
|
352
|
-
maker: null,
|
|
353
|
-
capabilities: null,
|
|
354
|
-
constraints: [],
|
|
355
|
-
context_window: null,
|
|
356
|
-
controls: null,
|
|
357
|
-
is_deprecated: null,
|
|
358
|
-
is_premium: null,
|
|
359
|
-
is_primary: null,
|
|
360
|
-
max_tokens: null,
|
|
361
|
-
provider_id: null,
|
|
362
|
-
guest_fallback_id: null,
|
|
363
|
-
mid_fallback_id: null,
|
|
364
|
-
// 2026-07-10 ai-schema reshape additions
|
|
365
|
-
cost_rating: null,
|
|
366
|
-
speed_rating: null,
|
|
367
|
-
retry_fallback_id: null,
|
|
368
|
-
retry_max_attempts: 0,
|
|
369
|
-
organization_id: "",
|
|
370
|
-
created_by: null,
|
|
371
|
-
deleted_at: null,
|
|
372
|
-
retired_at: null,
|
|
373
|
-
successor_id: null,
|
|
374
|
-
visibility: "personal",
|
|
375
|
-
shown_to: null,
|
|
376
|
-
published_to_web: false,
|
|
377
|
-
published_to_web_at: null,
|
|
378
|
-
published_to_web_by: null,
|
|
379
|
-
// Canonical base columns (2026-07-02 AI-catalog reshape)
|
|
380
|
-
is_system: false,
|
|
381
|
-
created_at: "",
|
|
382
|
-
updated_at: "",
|
|
383
|
-
updated_by: null,
|
|
384
|
-
version: 0,
|
|
385
|
-
metadata: {},
|
|
386
|
-
description: null,
|
|
387
|
-
release_date: null
|
|
388
|
-
};
|
|
389
|
-
}
|
|
390
|
-
function rebuildIdLists(state) {
|
|
391
|
-
const active = [];
|
|
392
|
-
const deprecated = [];
|
|
393
|
-
for (const [id, record] of Object.entries(state.entities)) {
|
|
394
|
-
if (record.is_deprecated === true) {
|
|
395
|
-
deprecated.push(id);
|
|
396
|
-
} else {
|
|
397
|
-
active.push(id);
|
|
398
|
-
}
|
|
399
|
-
}
|
|
400
|
-
const sort = (ids) => ids.sort(
|
|
401
|
-
(a, b) => (state.entities[a].common_name ?? state.entities[a].name ?? "").localeCompare(
|
|
402
|
-
state.entities[b].common_name ?? state.entities[b].name ?? ""
|
|
403
|
-
)
|
|
404
|
-
);
|
|
405
|
-
state.activeIds = sort(active);
|
|
406
|
-
state.deprecatedIds = sort(deprecated);
|
|
407
|
-
}
|
|
408
|
-
const { hydrateModels, retryModelDetail } = modelRegistrySlice.actions;
|
|
409
|
-
var modelRegistrySlice_default = modelRegistrySlice.reducer;
|
|
410
|
-
const selectRegistrySlice = (state) => state.modelRegistry;
|
|
411
|
-
const selectEntities = (state) => state.modelRegistry.entities;
|
|
412
|
-
const selectActiveIds = (state) => state.modelRegistry.activeIds;
|
|
413
|
-
const selectDeprecatedIds = (state) => state.modelRegistry.deprecatedIds;
|
|
414
|
-
const selectModelFetchScope = (state) => state.modelRegistry.fetchScope;
|
|
415
|
-
const selectModelRegistryLoading = (state) => state.modelRegistry.isLoading;
|
|
416
|
-
const selectModelRegistryError = (state) => state.modelRegistry.error;
|
|
417
|
-
const selectModelRegistryLastFetched = (state) => state.modelRegistry.lastFetched;
|
|
418
|
-
const selectModelIdentityLookupStatus = (state, modelId) => state.modelRegistry.identityStatusById[modelId] ?? "idle";
|
|
419
|
-
const selectModelIdentityById = (state, modelId) => state.modelRegistry.identityById[modelId];
|
|
420
|
-
const selectModelIdentityMap = (state) => state.modelRegistry.identityById;
|
|
421
|
-
const selectActiveModels = createSelector(
|
|
422
|
-
[selectEntities, selectActiveIds],
|
|
423
|
-
(entities, ids) => ids.map((id) => entities[id]).filter(Boolean)
|
|
424
|
-
);
|
|
425
|
-
const selectDeprecatedModels = createSelector(
|
|
426
|
-
[selectEntities, selectDeprecatedIds],
|
|
427
|
-
(entities, ids) => ids.map((id) => entities[id]).filter(Boolean)
|
|
428
|
-
);
|
|
429
|
-
const selectAllModels = createSelector(
|
|
430
|
-
[selectEntities],
|
|
431
|
-
(entities) => Object.values(entities)
|
|
432
|
-
);
|
|
433
|
-
const selectModelOptions = createSelector(
|
|
434
|
-
[selectActiveModels],
|
|
435
|
-
(models) => models.map((m) => ({
|
|
436
|
-
value: m.id,
|
|
437
|
-
label: m.common_name || m.name || m.id,
|
|
438
|
-
maker: m.maker,
|
|
439
|
-
costRating: m.cost_rating,
|
|
440
|
-
speedRating: m.speed_rating
|
|
441
|
-
}))
|
|
442
|
-
);
|
|
443
|
-
const selectAllModelOptions = createSelector(
|
|
444
|
-
[selectEntities],
|
|
445
|
-
(entities) => Object.values(entities).map((m) => ({
|
|
446
|
-
value: m.id,
|
|
447
|
-
label: m.common_name || m.name || m.id,
|
|
448
|
-
maker: m.maker,
|
|
449
|
-
isDeprecated: m.is_deprecated ?? false,
|
|
450
|
-
isRetired: m.retired_at != null,
|
|
451
|
-
successorId: m.successor_id ?? null
|
|
452
|
-
}))
|
|
453
|
-
);
|
|
454
|
-
const selectModelLabelById = createSelector(
|
|
455
|
-
[
|
|
456
|
-
selectEntities,
|
|
457
|
-
selectModelIdentityMap,
|
|
458
|
-
(_state, modelId) => modelId
|
|
459
|
-
],
|
|
460
|
-
(entities, identities, modelId) => {
|
|
461
|
-
if (!modelId) return void 0;
|
|
462
|
-
const m = entities[modelId];
|
|
463
|
-
const identity = identities[modelId];
|
|
464
|
-
return m?.common_name || m?.name || identity?.common_name || identity?.name || void 0;
|
|
465
|
-
}
|
|
466
|
-
);
|
|
467
|
-
const selectModelClassName = (state, modelId, offeringId) => modelClassName(state.modelRegistry?.modelClassIndex, modelId, offeringId);
|
|
468
|
-
const selectModelLabelWithClass = (state, modelId, offeringId) => {
|
|
469
|
-
const label = selectModelLabelById(state, modelId);
|
|
470
|
-
return label ? withModelClass(label, selectModelClassName(state, modelId, offeringId)) : void 0;
|
|
471
|
-
};
|
|
472
|
-
const selectModelNameById = createSelector(
|
|
473
|
-
[
|
|
474
|
-
selectEntities,
|
|
475
|
-
(_state, modelId) => modelId
|
|
476
|
-
],
|
|
477
|
-
(entities, modelId) => {
|
|
478
|
-
if (!modelId) return void 0;
|
|
479
|
-
return entities[modelId]?.name;
|
|
480
|
-
}
|
|
481
|
-
);
|
|
482
|
-
const selectModelById = createSelector(
|
|
483
|
-
[
|
|
484
|
-
selectEntities,
|
|
485
|
-
(_state, modelId) => modelId
|
|
486
|
-
],
|
|
487
|
-
(entities, modelId) => entities[modelId]
|
|
488
|
-
);
|
|
489
|
-
const makeSelectModelById = () => createSelector(
|
|
490
|
-
[
|
|
491
|
-
selectEntities,
|
|
492
|
-
(_state, modelId) => modelId
|
|
493
|
-
],
|
|
494
|
-
(entities, modelId) => entities[modelId]
|
|
495
|
-
);
|
|
496
|
-
const selectModelControls = createSelector(
|
|
497
|
-
[
|
|
498
|
-
selectEntities,
|
|
499
|
-
(_state, modelId) => modelId
|
|
500
|
-
],
|
|
501
|
-
(entities, modelId) => entities[modelId]?.controls
|
|
502
|
-
);
|
|
503
|
-
const selectModelFetchType = createSelector(
|
|
504
|
-
[
|
|
505
|
-
selectEntities,
|
|
506
|
-
(_state, modelId) => modelId
|
|
507
|
-
],
|
|
508
|
-
(entities, modelId) => entities[modelId]?._fetchType
|
|
509
|
-
);
|
|
510
|
-
const selectActiveModelsReady = createSelector(
|
|
511
|
-
[selectRegistrySlice],
|
|
512
|
-
({ fetchScope, activeIds }) => (fetchScope === "active" || fetchScope === "all") && activeIds.length > 0
|
|
513
|
-
);
|
|
514
|
-
const selectDeprecatedModelsReady = createSelector(
|
|
515
|
-
[selectRegistrySlice],
|
|
516
|
-
({ fetchScope, deprecatedIds }) => (fetchScope === "deprecated" || fetchScope === "all") && deprecatedIds.length > 0
|
|
517
|
-
);
|
|
518
|
-
const selectAllModelsReady = createSelector(
|
|
519
|
-
[selectRegistrySlice],
|
|
520
|
-
({ fetchScope }) => fetchScope === "all"
|
|
521
|
-
);
|
|
522
|
-
const selectModelFullyLoaded = createSelector(
|
|
523
|
-
[
|
|
524
|
-
selectEntities,
|
|
525
|
-
(_state, modelId) => modelId
|
|
526
|
-
],
|
|
527
|
-
(entities, modelId) => {
|
|
528
|
-
if (!modelId) return false;
|
|
529
|
-
return entities[modelId]?._fetchType === "full";
|
|
530
|
-
}
|
|
531
|
-
);
|
|
532
|
-
const selectModelDetailError = createSelector(
|
|
533
|
-
[
|
|
534
|
-
(state) => state.modelRegistry.detailErrorById,
|
|
535
|
-
(_state, modelId) => modelId
|
|
536
|
-
],
|
|
537
|
-
(errors, modelId) => errors?.[modelId] ?? null
|
|
538
|
-
);
|
|
539
|
-
export {
|
|
540
|
-
classConfigKey,
|
|
541
|
-
modelRegistrySlice_default as default,
|
|
542
|
-
fetchModelById,
|
|
543
|
-
fetchModelClassConfig,
|
|
544
|
-
fetchModelClasses,
|
|
545
|
-
fetchModelIdentityById,
|
|
546
|
-
fetchModelOptions,
|
|
547
|
-
hydrateModels,
|
|
548
|
-
makeSelectModelById,
|
|
549
|
-
retryModelDetail,
|
|
550
|
-
selectActiveModels,
|
|
551
|
-
selectActiveModelsReady,
|
|
552
|
-
selectAllModelOptions,
|
|
553
|
-
selectAllModels,
|
|
554
|
-
selectAllModelsReady,
|
|
555
|
-
selectDeprecatedModels,
|
|
556
|
-
selectDeprecatedModelsReady,
|
|
557
|
-
selectModelById,
|
|
558
|
-
selectModelClassName,
|
|
559
|
-
selectModelControls,
|
|
560
|
-
selectModelDetailError,
|
|
561
|
-
selectModelFetchScope,
|
|
562
|
-
selectModelFetchType,
|
|
563
|
-
selectModelFullyLoaded,
|
|
564
|
-
selectModelIdentityById,
|
|
565
|
-
selectModelIdentityLookupStatus,
|
|
566
|
-
selectModelIdentityMap,
|
|
567
|
-
selectModelLabelById,
|
|
568
|
-
selectModelLabelWithClass,
|
|
569
|
-
selectModelNameById,
|
|
570
|
-
selectModelOptions,
|
|
571
|
-
selectModelRegistryError,
|
|
572
|
-
selectModelRegistryLastFetched,
|
|
573
|
-
selectModelRegistryLoading
|
|
574
|
-
};
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* host/model-class — the model "class" (offering) a run is pinned to, read through the host.
|
|
3
|
-
*
|
|
4
|
-
* The host loads a pinned class's controls and its display labels from its model registry.
|
|
5
|
-
* A host with no registry answers `undefined` (callers keep the model's own controls) and
|
|
6
|
-
* labels nothing. matrx-frontend registers its hooks (`providers/chatUiRegistration.ts`).
|
|
7
|
-
*/
|
|
8
|
-
import type { Json } from "./db-types.js";
|
|
9
|
-
export type ModelClassControls = undefined | {
|
|
10
|
-
pending: true;
|
|
11
|
-
failed?: false;
|
|
12
|
-
config?: undefined;
|
|
13
|
-
} | {
|
|
14
|
-
pending?: false;
|
|
15
|
-
failed: true;
|
|
16
|
-
config?: undefined;
|
|
17
|
-
} | {
|
|
18
|
-
pending?: false;
|
|
19
|
-
failed?: false;
|
|
20
|
-
config: {
|
|
21
|
-
modelId: string;
|
|
22
|
-
controls: Json | null;
|
|
23
|
-
constraints: Json | null;
|
|
24
|
-
};
|
|
25
|
-
};
|
|
26
|
-
export interface ChatModelClassHooks {
|
|
27
|
-
useModelClassControls(modelId: string | null | undefined, offeringId: string | null | undefined): ModelClassControls;
|
|
28
|
-
/** Loads the class labels the model pickers read (a side-effect hook). */
|
|
29
|
-
useModelClassLabels(): void;
|
|
30
|
-
}
|
|
31
|
-
export declare function registerChatModelClassHooks(next: ChatModelClassHooks | null): void;
|
|
32
|
-
export declare const useModelClassControls: ChatModelClassHooks["useModelClassControls"];
|
|
33
|
-
export declare const useModelClassLabels: ChatModelClassHooks["useModelClassLabels"];
|
package/dist/host/model-class.js
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
import { reportUnregisteredHostSlot } from "./diagnostics.js";
|
|
2
|
-
const NO_REGISTRY = {
|
|
3
|
-
useModelClassControls: () => void 0,
|
|
4
|
-
useModelClassLabels: () => void 0
|
|
5
|
-
};
|
|
6
|
-
let hooks = NO_REGISTRY;
|
|
7
|
-
function registerChatModelClassHooks(next) {
|
|
8
|
-
hooks = next ?? NO_REGISTRY;
|
|
9
|
-
}
|
|
10
|
-
function current() {
|
|
11
|
-
if (hooks === NO_REGISTRY)
|
|
12
|
-
reportUnregisteredHostSlot("modelClassHooks", "pinned model classes keep the model's own controls and show no class labels");
|
|
13
|
-
return hooks;
|
|
14
|
-
}
|
|
15
|
-
const useModelClassControls = (modelId, offeringId) => current().useModelClassControls(modelId, offeringId);
|
|
16
|
-
const useModelClassLabels = () => current().useModelClassLabels();
|
|
17
|
-
export {
|
|
18
|
-
registerChatModelClassHooks,
|
|
19
|
-
useModelClassControls,
|
|
20
|
-
useModelClassLabels
|
|
21
|
-
};
|