@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.
Files changed (59) hide show
  1. package/CHANGELOG.md +20 -0
  2. package/dist/agents/components/ambient-assistant/intelligence-places.js +2 -2
  3. package/dist/agents/components/chat/intelligence-places.js +7 -7
  4. package/dist/agents/components/inputs/smart-input/RunToolPicker.js +7 -13
  5. package/dist/agents/components/inputs/smart-input/composer/ComposerAgentPill.js +3 -2
  6. package/dist/agents/components/inputs/smart-input/composer/useComposerAgent.js +5 -5
  7. package/dist/agents/components/inputs/smart-input/composer/useComposerAgentFilter.js +3 -2
  8. package/dist/agents/components/run-controls/RunConfigOverrides.js +10 -16
  9. package/dist/agents/components/run-controls/panels/shared.d.ts +0 -1
  10. package/dist/agents/hooks/useAgentModelLabel.js +4 -3
  11. package/dist/agents/hooks/useDiffEnrichment.js +3 -5
  12. package/dist/agents/hooks/useModelControls.d.ts +5 -161
  13. package/dist/agents/identity/model-catalog.d.ts +37 -0
  14. package/dist/agents/identity/model-catalog.js +103 -0
  15. package/dist/agents/redux/agent-definition/selectors.d.ts +0 -237
  16. package/dist/agents/redux/agent-definition/thunks.d.ts +1 -1
  17. package/dist/agents/redux/agent-settings/agentSettingsSlice.d.ts +1 -1
  18. package/dist/agents/redux/agent-settings/agentSettingsSlice.js +4 -6
  19. package/dist/agents/redux/agent-settings/selectors.d.ts +1 -152
  20. package/dist/agents/redux/agent-settings/selectors.js +0 -39
  21. package/dist/agents/redux/agent-settings/useNormalizedControls.d.ts +8 -0
  22. package/dist/agents/redux/agent-settings/useNormalizedControls.js +24 -0
  23. package/dist/agents/redux/agent-shortcut-categories/selectors.d.ts +0 -50
  24. package/dist/agents/redux/agent-shortcuts/selectors.d.ts +0 -147
  25. package/dist/agents/redux/conversation-history/selectors.d.ts +0 -16
  26. package/dist/agents/redux/conversation-list/conversation-list.selectors.d.ts +0 -2
  27. package/dist/agents/redux/execution-system/active-requests/active-requests.selectors.d.ts +0 -54
  28. package/dist/agents/redux/execution-system/context-state/context-state.selectors.d.ts +0 -14
  29. package/dist/agents/redux/execution-system/conversations/conversations.selectors.d.ts +0 -5
  30. package/dist/agents/redux/execution-system/instance-context/instance-context.selectors.d.ts +0 -3
  31. package/dist/agents/redux/execution-system/instance-resources/instance-resources.selectors.d.ts +0 -8
  32. package/dist/agents/redux/execution-system/instance-ui-state/instance-ui-state.selectors.d.ts +0 -5
  33. package/dist/agents/redux/execution-system/instance-variable-values/instance-variable-values.selectors.d.ts +0 -7
  34. package/dist/agents/redux/execution-system/messages/messages.selectors.d.ts +0 -1
  35. package/dist/agents/redux/execution-system/observability/observability.selectors.d.ts +0 -7
  36. package/dist/agents/redux/execution-system/observational-memory/observational-memory.selectors.d.ts +0 -1
  37. package/dist/agents/redux/execution-system/selectors/aggregate.selectors.d.ts +0 -14
  38. package/dist/agents/redux/execution-system/thunks/execute-manual-instance.thunk.js +2 -2
  39. package/dist/agents/redux/model-registry.d.ts +6 -4
  40. package/dist/agents/redux/model-registry.js +23 -5
  41. package/dist/agents/redux/proposed-directives/proposedDirectivesSlice.d.ts +0 -1
  42. package/dist/agents/redux/tools/tools.selectors.d.ts +0 -1
  43. package/dist/agents/runtime/generation-job.js +4 -7
  44. package/dist/agents/runtime/get-model-capabilities.js +3 -3
  45. package/dist/agents/ui-first-tools/redux/agent-lists.selectors.d.ts +0 -2
  46. package/dist/host/db-types.d.ts +276 -9
  47. package/dist/store/create-chat-store.d.ts +0 -2
  48. package/dist/store/middlewares.d.ts +0 -5
  49. package/dist/store/slices.d.ts +0 -1
  50. package/dist/store/slices.js +0 -2
  51. package/dist/surfaces/redux/selectors.d.ts +0 -2
  52. package/dist/tool-call-visualization/intelligence-places.js +1 -1
  53. package/dist/tool-call-visualization/redux/selectors.d.ts +0 -1
  54. package/dist/voice-agent/intelligence-places.js +6 -6
  55. package/package.json +5 -5
  56. package/dist/agents/model-registry/modelRegistrySlice.d.ts +0 -691
  57. package/dist/agents/model-registry/modelRegistrySlice.js +0 -574
  58. package/dist/host/model-class.d.ts +0 -33
  59. 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"];
@@ -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
- };