@ai-matrx/agents 0.59.215 → 0.59.216
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 +1 -1
- package/dist/mandates/index.cjs +2 -2
- package/dist/mandates/index.d.cts +4 -4
- package/dist/mandates/index.d.ts +4 -4
- package/dist/mandates/index.js +2 -2
- package/dist/models/index.cjs +113 -14
- package/dist/models/index.d.cts +8 -0
- package/dist/models/index.d.ts +8 -0
- package/dist/models/index.js +113 -14
- package/dist/models/react/index.d.cts +8 -0
- package/dist/models/react/index.d.ts +8 -0
- package/package.json +3 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
-
## 0.59.
|
|
3
|
+
## 0.59.216
|
|
4
4
|
|
|
5
5
|
- **Glyph path data removed; the same exports now alias the one glyph home (one-canonical, glyph lane, 2026-10-21).** `context, models, settings and versions icon files` defines no SVG any more: each export is `@ai-matrx/design-system/icons`'s glyph with this package's historical size and stroke. Names, props and sizes are unchanged; catalog `FolderIcon`, `TagIcon` and `RotateCcwIcon` are re-exports of the glyph home, and the settings rows join classes with `cn` from `@ai-matrx/design-system/cn`. Consumer action: none.
|
|
6
6
|
|
package/dist/mandates/index.cjs
CHANGED
|
@@ -47,9 +47,9 @@ module.exports = __toCommonJS(mandates_exports);
|
|
|
47
47
|
|
|
48
48
|
// mandates/keys.generated.ts
|
|
49
49
|
var MANDATE_KEYS_META = {
|
|
50
|
-
aidreamRevision: "
|
|
50
|
+
aidreamRevision: "09a96cc8f8c2eb29399669e9343d1f566532c29f",
|
|
51
51
|
generatorVersion: "1.0.0",
|
|
52
|
-
packageVersion: "0.59.
|
|
52
|
+
packageVersion: "0.59.216",
|
|
53
53
|
retireWindow: 3
|
|
54
54
|
};
|
|
55
55
|
var MANDATE_KEYS = {
|
|
@@ -6,9 +6,9 @@
|
|
|
6
6
|
* from the IN-PROCESS mandate declarations — the same `declared_mandates()` the
|
|
7
7
|
* boot sync writes to the database from. There is no hand list anywhere.
|
|
8
8
|
*
|
|
9
|
-
* aidream revision:
|
|
9
|
+
* aidream revision: 09a96cc8f8c2eb29399669e9343d1f566532c29f
|
|
10
10
|
* generator version: 1.0.0
|
|
11
|
-
* package version: 0.59.
|
|
11
|
+
* package version: 0.59.216
|
|
12
12
|
* active keys: 612
|
|
13
13
|
* retiring keys: 5
|
|
14
14
|
*
|
|
@@ -19,9 +19,9 @@
|
|
|
19
19
|
*/
|
|
20
20
|
/** Where this module came from — surfaced so a report can name the exact build. */
|
|
21
21
|
declare const MANDATE_KEYS_META: {
|
|
22
|
-
readonly aidreamRevision: "
|
|
22
|
+
readonly aidreamRevision: "09a96cc8f8c2eb29399669e9343d1f566532c29f";
|
|
23
23
|
readonly generatorVersion: "1.0.0";
|
|
24
|
-
readonly packageVersion: "0.59.
|
|
24
|
+
readonly packageVersion: "0.59.216";
|
|
25
25
|
readonly retireWindow: 3;
|
|
26
26
|
};
|
|
27
27
|
/** Every declared mandate key, by THE IDENTIFIER RULE. */
|
package/dist/mandates/index.d.ts
CHANGED
|
@@ -6,9 +6,9 @@
|
|
|
6
6
|
* from the IN-PROCESS mandate declarations — the same `declared_mandates()` the
|
|
7
7
|
* boot sync writes to the database from. There is no hand list anywhere.
|
|
8
8
|
*
|
|
9
|
-
* aidream revision:
|
|
9
|
+
* aidream revision: 09a96cc8f8c2eb29399669e9343d1f566532c29f
|
|
10
10
|
* generator version: 1.0.0
|
|
11
|
-
* package version: 0.59.
|
|
11
|
+
* package version: 0.59.216
|
|
12
12
|
* active keys: 612
|
|
13
13
|
* retiring keys: 5
|
|
14
14
|
*
|
|
@@ -19,9 +19,9 @@
|
|
|
19
19
|
*/
|
|
20
20
|
/** Where this module came from — surfaced so a report can name the exact build. */
|
|
21
21
|
declare const MANDATE_KEYS_META: {
|
|
22
|
-
readonly aidreamRevision: "
|
|
22
|
+
readonly aidreamRevision: "09a96cc8f8c2eb29399669e9343d1f566532c29f";
|
|
23
23
|
readonly generatorVersion: "1.0.0";
|
|
24
|
-
readonly packageVersion: "0.59.
|
|
24
|
+
readonly packageVersion: "0.59.216";
|
|
25
25
|
readonly retireWindow: 3;
|
|
26
26
|
};
|
|
27
27
|
/** Every declared mandate key, by THE IDENTIFIER RULE. */
|
package/dist/mandates/index.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
// mandates/keys.generated.ts
|
|
2
2
|
var MANDATE_KEYS_META = {
|
|
3
|
-
aidreamRevision: "
|
|
3
|
+
aidreamRevision: "09a96cc8f8c2eb29399669e9343d1f566532c29f",
|
|
4
4
|
generatorVersion: "1.0.0",
|
|
5
|
-
packageVersion: "0.59.
|
|
5
|
+
packageVersion: "0.59.216",
|
|
6
6
|
retireWindow: 3
|
|
7
7
|
};
|
|
8
8
|
var MANDATE_KEYS = {
|
package/dist/models/index.cjs
CHANGED
|
@@ -1005,6 +1005,117 @@ function createModelRecords(config) {
|
|
|
1005
1005
|
inFlight.set(key, p);
|
|
1006
1006
|
return p;
|
|
1007
1007
|
};
|
|
1008
|
+
async function readFullModel(modelId) {
|
|
1009
|
+
const relation = await isSignedIn() ? "model_config" : "model_public";
|
|
1010
|
+
const { data, error } = await ai().from(relation).select(MODEL_CONFIG_COLUMNS).eq("id", modelId).maybeSingle();
|
|
1011
|
+
if (error) throw error;
|
|
1012
|
+
const row = data;
|
|
1013
|
+
if (!row) throw new Error(`AI model ${modelId} is not available (ai.${relation} has no such row)`);
|
|
1014
|
+
if (!row.id || !row.name) throw new Error(`ai.${relation} returned a row without id/name for model ${modelId}`);
|
|
1015
|
+
const read = {
|
|
1016
|
+
...row,
|
|
1017
|
+
id: row.id,
|
|
1018
|
+
name: row.name,
|
|
1019
|
+
controls: row.controls ?? null,
|
|
1020
|
+
capabilities: requireCanonicalCapabilities(row.capabilities, { modelId: row.id, modelName: row.name })
|
|
1021
|
+
};
|
|
1022
|
+
return normalizeModel(read);
|
|
1023
|
+
}
|
|
1024
|
+
async function readOfferings(modelId) {
|
|
1025
|
+
const q = ai().from("model_offering").select("model_id, offering_id, served_via, served_via_endpoint_id, priority");
|
|
1026
|
+
const { data, error } = await (modelId ? q.eq("model_id", modelId) : q);
|
|
1027
|
+
if (error) throw error;
|
|
1028
|
+
return data ?? [];
|
|
1029
|
+
}
|
|
1030
|
+
async function rereadKnown() {
|
|
1031
|
+
const known = state2;
|
|
1032
|
+
const jobs = [];
|
|
1033
|
+
const fail = (code, message, context) => errorSink({ code, message: `Catalog refresh: ${message}`, ...context ? { context } : {} });
|
|
1034
|
+
if (known.fetchScope === "active" || known.fetchScope === "all") {
|
|
1035
|
+
jobs.push(
|
|
1036
|
+
readOptions().then(
|
|
1037
|
+
(rows3) => update((s3) => {
|
|
1038
|
+
const entities = { ...s3.entities };
|
|
1039
|
+
for (const row of rows3) {
|
|
1040
|
+
const existing = entities[row.id];
|
|
1041
|
+
entities[row.id] = { ...emptyRecord(), ...existing, ...row, _fetchType: existing?._fetchType === "full" ? "full" : "options" };
|
|
1042
|
+
}
|
|
1043
|
+
return withIdLists({ ...s3, entities, lastFetched: Date.now(), error: null });
|
|
1044
|
+
}),
|
|
1045
|
+
(err) => fail("model-records-refresh-options-failed", messageOf(err))
|
|
1046
|
+
)
|
|
1047
|
+
);
|
|
1048
|
+
}
|
|
1049
|
+
for (const [id, record] of Object.entries(known.entities)) {
|
|
1050
|
+
if (record._fetchType !== "full") continue;
|
|
1051
|
+
jobs.push(
|
|
1052
|
+
readFullModel(id).then(
|
|
1053
|
+
(fresh) => update((s3) => {
|
|
1054
|
+
const existing = s3.entities[fresh.id];
|
|
1055
|
+
return withIdLists({ ...s3, entities: { ...s3.entities, [fresh.id]: { ...emptyRecord(), ...existing, ...fresh, maker: fresh.maker ?? existing?.maker ?? null, _fetchType: "full" } } });
|
|
1056
|
+
}),
|
|
1057
|
+
(err) => fail("model-records-refresh-model-failed", `${id}: ${messageOf(err)}`, { modelId: id })
|
|
1058
|
+
)
|
|
1059
|
+
);
|
|
1060
|
+
}
|
|
1061
|
+
for (const id of Object.keys(known.identityById)) {
|
|
1062
|
+
jobs.push(
|
|
1063
|
+
Promise.resolve(ai().from("model_definition").select("id, name, common_name, is_deprecated").eq("id", id).maybeSingle()).then(
|
|
1064
|
+
({ data, error }) => {
|
|
1065
|
+
if (error) throw error;
|
|
1066
|
+
if (data) update((s3) => ({ ...s3, identityById: { ...s3.identityById, [id]: data } }));
|
|
1067
|
+
}
|
|
1068
|
+
).catch((err) => fail("model-records-refresh-identity-failed", `${id}: ${messageOf(err)}`, { modelId: id }))
|
|
1069
|
+
);
|
|
1070
|
+
}
|
|
1071
|
+
if (known.modelClassStatus === "succeeded") {
|
|
1072
|
+
jobs.push(
|
|
1073
|
+
readOfferings().then(
|
|
1074
|
+
(rows3) => update((s3) => ({ ...s3, modelClassIndex: buildModelClassIndex(rows3) })),
|
|
1075
|
+
(err) => fail("model-records-refresh-classes-failed", messageOf(err))
|
|
1076
|
+
)
|
|
1077
|
+
);
|
|
1078
|
+
} else {
|
|
1079
|
+
for (const id of classesReadFor) {
|
|
1080
|
+
jobs.push(
|
|
1081
|
+
readOfferings(id).then(
|
|
1082
|
+
(rows3) => update((s3) => {
|
|
1083
|
+
if (s3.modelClassStatus === "succeeded") return s3;
|
|
1084
|
+
const slice = buildModelClassIndex(rows3);
|
|
1085
|
+
const base = s3.modelClassIndex ?? { classesByModelId: {}, classOfOffering: {} };
|
|
1086
|
+
return { ...s3, modelClassIndex: { classesByModelId: { ...base.classesByModelId, ...slice.classesByModelId }, classOfOffering: { ...base.classOfOffering, ...slice.classOfOffering } } };
|
|
1087
|
+
}),
|
|
1088
|
+
(err) => fail("model-records-refresh-classes-failed", `${id}: ${messageOf(err)}`, { modelId: id })
|
|
1089
|
+
)
|
|
1090
|
+
);
|
|
1091
|
+
}
|
|
1092
|
+
}
|
|
1093
|
+
for (const [key, cfg] of Object.entries(known.classConfigByOffering)) {
|
|
1094
|
+
const offeringId = key.slice(cfg.modelId.length + 1);
|
|
1095
|
+
jobs.push(
|
|
1096
|
+
Promise.resolve(ai().rpc("resolve_model_config", { p_model_id: cfg.modelId, p_offering_id: offeringId })).then(
|
|
1097
|
+
({ data, error }) => {
|
|
1098
|
+
if (error) throw error;
|
|
1099
|
+
const next = data && typeof data === "object" && !Array.isArray(data) ? data : null;
|
|
1100
|
+
update((s3) => ({ ...s3, classConfigByOffering: { ...s3.classConfigByOffering, [key]: { modelId: cfg.modelId, controls: next?.controls ?? null, constraints: next?.constraints ?? null } } }));
|
|
1101
|
+
}
|
|
1102
|
+
).catch((err) => fail("model-records-refresh-class-config-failed", `${key}: ${messageOf(err)}`))
|
|
1103
|
+
);
|
|
1104
|
+
}
|
|
1105
|
+
await Promise.all(jobs);
|
|
1106
|
+
}
|
|
1107
|
+
let refreshing = null;
|
|
1108
|
+
let refreshAgain = null;
|
|
1109
|
+
function refreshAll() {
|
|
1110
|
+
if (refreshing) return refreshAgain ??= refreshing.then(() => {
|
|
1111
|
+
refreshAgain = null;
|
|
1112
|
+
return refreshAll();
|
|
1113
|
+
});
|
|
1114
|
+
refreshing = rereadKnown().finally(() => {
|
|
1115
|
+
refreshing = null;
|
|
1116
|
+
});
|
|
1117
|
+
return refreshing;
|
|
1118
|
+
}
|
|
1008
1119
|
async function readOptions() {
|
|
1009
1120
|
const { data: offeringRows, error: offeringError } = await ai().from("model_offering").select("model_id");
|
|
1010
1121
|
if (offeringError) throw offeringError;
|
|
@@ -1070,20 +1181,7 @@ function createModelRecords(config) {
|
|
|
1070
1181
|
return { ...s3, detailStatusById: { ...s3.detailStatusById, [modelId]: "loading" }, detailErrorById };
|
|
1071
1182
|
});
|
|
1072
1183
|
try {
|
|
1073
|
-
const
|
|
1074
|
-
const { data, error } = await ai().from(relation).select(MODEL_CONFIG_COLUMNS).eq("id", modelId).maybeSingle();
|
|
1075
|
-
if (error) throw error;
|
|
1076
|
-
const row = data;
|
|
1077
|
-
if (!row) throw new Error(`AI model ${modelId} is not available (ai.${relation} has no such row)`);
|
|
1078
|
-
if (!row.id || !row.name) throw new Error(`ai.${relation} returned a row without id/name for model ${modelId}`);
|
|
1079
|
-
const read = {
|
|
1080
|
-
...row,
|
|
1081
|
-
id: row.id,
|
|
1082
|
-
name: row.name,
|
|
1083
|
-
controls: row.controls ?? null,
|
|
1084
|
-
capabilities: requireCanonicalCapabilities(row.capabilities, { modelId: row.id, modelName: row.name })
|
|
1085
|
-
};
|
|
1086
|
-
const record = normalizeModel(read);
|
|
1184
|
+
const record = await readFullModel(modelId);
|
|
1087
1185
|
update((s3) => {
|
|
1088
1186
|
const existing = s3.entities[record.id];
|
|
1089
1187
|
const detailErrorById = { ...s3.detailErrorById };
|
|
@@ -1207,6 +1305,7 @@ function createModelRecords(config) {
|
|
|
1207
1305
|
}
|
|
1208
1306
|
});
|
|
1209
1307
|
},
|
|
1308
|
+
refresh: () => refreshAll(),
|
|
1210
1309
|
seedModel({ modelId, config: config2, offerings }) {
|
|
1211
1310
|
if (!modelId) return;
|
|
1212
1311
|
if (!classesReadFor.has(modelId) && state2.modelClassStatus !== "succeeded") {
|
package/dist/models/index.d.cts
CHANGED
|
@@ -671,6 +671,14 @@ interface ModelRecords {
|
|
|
671
671
|
loadModelClasses(modelId: string): Promise<void>;
|
|
672
672
|
/** The durable label of a model outside the options list. Never throws. */
|
|
673
673
|
loadIdentity(modelId: string): Promise<void>;
|
|
674
|
+
/**
|
|
675
|
+
* The catalog changed upstream (a `catalog_changed` notice: an admin renamed, offered or retired a model):
|
|
676
|
+
* re-read everything this instance already read — the options list, every full record, every identity,
|
|
677
|
+
* the class index and slices, every pinned class's controls — and swap each in when it answers. The old
|
|
678
|
+
* rows stay on screen until then (no blank pill, no flicker); a failed re-read keeps them and reports
|
|
679
|
+
* through the error sink. Reads nothing that was never read. Never throws.
|
|
680
|
+
*/
|
|
681
|
+
refresh(): Promise<void>;
|
|
674
682
|
/**
|
|
675
683
|
* Answer `loadModel` + `loadModelClasses` for one model from rows a batched
|
|
676
684
|
* route read already returned (`chat.route_seed`): its `ai.model_config` row
|
package/dist/models/index.d.ts
CHANGED
|
@@ -671,6 +671,14 @@ interface ModelRecords {
|
|
|
671
671
|
loadModelClasses(modelId: string): Promise<void>;
|
|
672
672
|
/** The durable label of a model outside the options list. Never throws. */
|
|
673
673
|
loadIdentity(modelId: string): Promise<void>;
|
|
674
|
+
/**
|
|
675
|
+
* The catalog changed upstream (a `catalog_changed` notice: an admin renamed, offered or retired a model):
|
|
676
|
+
* re-read everything this instance already read — the options list, every full record, every identity,
|
|
677
|
+
* the class index and slices, every pinned class's controls — and swap each in when it answers. The old
|
|
678
|
+
* rows stay on screen until then (no blank pill, no flicker); a failed re-read keeps them and reports
|
|
679
|
+
* through the error sink. Reads nothing that was never read. Never throws.
|
|
680
|
+
*/
|
|
681
|
+
refresh(): Promise<void>;
|
|
674
682
|
/**
|
|
675
683
|
* Answer `loadModel` + `loadModelClasses` for one model from rows a batched
|
|
676
684
|
* route read already returned (`chat.route_seed`): its `ai.model_config` row
|
package/dist/models/index.js
CHANGED
|
@@ -847,6 +847,117 @@ function createModelRecords(config) {
|
|
|
847
847
|
inFlight.set(key, p);
|
|
848
848
|
return p;
|
|
849
849
|
};
|
|
850
|
+
async function readFullModel(modelId) {
|
|
851
|
+
const relation = await isSignedIn() ? "model_config" : "model_public";
|
|
852
|
+
const { data, error } = await ai().from(relation).select(MODEL_CONFIG_COLUMNS).eq("id", modelId).maybeSingle();
|
|
853
|
+
if (error) throw error;
|
|
854
|
+
const row = data;
|
|
855
|
+
if (!row) throw new Error(`AI model ${modelId} is not available (ai.${relation} has no such row)`);
|
|
856
|
+
if (!row.id || !row.name) throw new Error(`ai.${relation} returned a row without id/name for model ${modelId}`);
|
|
857
|
+
const read = {
|
|
858
|
+
...row,
|
|
859
|
+
id: row.id,
|
|
860
|
+
name: row.name,
|
|
861
|
+
controls: row.controls ?? null,
|
|
862
|
+
capabilities: requireCanonicalCapabilities(row.capabilities, { modelId: row.id, modelName: row.name })
|
|
863
|
+
};
|
|
864
|
+
return normalizeModel(read);
|
|
865
|
+
}
|
|
866
|
+
async function readOfferings(modelId) {
|
|
867
|
+
const q = ai().from("model_offering").select("model_id, offering_id, served_via, served_via_endpoint_id, priority");
|
|
868
|
+
const { data, error } = await (modelId ? q.eq("model_id", modelId) : q);
|
|
869
|
+
if (error) throw error;
|
|
870
|
+
return data ?? [];
|
|
871
|
+
}
|
|
872
|
+
async function rereadKnown() {
|
|
873
|
+
const known = state2;
|
|
874
|
+
const jobs = [];
|
|
875
|
+
const fail = (code, message, context) => errorSink({ code, message: `Catalog refresh: ${message}`, ...context ? { context } : {} });
|
|
876
|
+
if (known.fetchScope === "active" || known.fetchScope === "all") {
|
|
877
|
+
jobs.push(
|
|
878
|
+
readOptions().then(
|
|
879
|
+
(rows3) => update((s3) => {
|
|
880
|
+
const entities = { ...s3.entities };
|
|
881
|
+
for (const row of rows3) {
|
|
882
|
+
const existing = entities[row.id];
|
|
883
|
+
entities[row.id] = { ...emptyRecord(), ...existing, ...row, _fetchType: existing?._fetchType === "full" ? "full" : "options" };
|
|
884
|
+
}
|
|
885
|
+
return withIdLists({ ...s3, entities, lastFetched: Date.now(), error: null });
|
|
886
|
+
}),
|
|
887
|
+
(err) => fail("model-records-refresh-options-failed", messageOf(err))
|
|
888
|
+
)
|
|
889
|
+
);
|
|
890
|
+
}
|
|
891
|
+
for (const [id, record] of Object.entries(known.entities)) {
|
|
892
|
+
if (record._fetchType !== "full") continue;
|
|
893
|
+
jobs.push(
|
|
894
|
+
readFullModel(id).then(
|
|
895
|
+
(fresh) => update((s3) => {
|
|
896
|
+
const existing = s3.entities[fresh.id];
|
|
897
|
+
return withIdLists({ ...s3, entities: { ...s3.entities, [fresh.id]: { ...emptyRecord(), ...existing, ...fresh, maker: fresh.maker ?? existing?.maker ?? null, _fetchType: "full" } } });
|
|
898
|
+
}),
|
|
899
|
+
(err) => fail("model-records-refresh-model-failed", `${id}: ${messageOf(err)}`, { modelId: id })
|
|
900
|
+
)
|
|
901
|
+
);
|
|
902
|
+
}
|
|
903
|
+
for (const id of Object.keys(known.identityById)) {
|
|
904
|
+
jobs.push(
|
|
905
|
+
Promise.resolve(ai().from("model_definition").select("id, name, common_name, is_deprecated").eq("id", id).maybeSingle()).then(
|
|
906
|
+
({ data, error }) => {
|
|
907
|
+
if (error) throw error;
|
|
908
|
+
if (data) update((s3) => ({ ...s3, identityById: { ...s3.identityById, [id]: data } }));
|
|
909
|
+
}
|
|
910
|
+
).catch((err) => fail("model-records-refresh-identity-failed", `${id}: ${messageOf(err)}`, { modelId: id }))
|
|
911
|
+
);
|
|
912
|
+
}
|
|
913
|
+
if (known.modelClassStatus === "succeeded") {
|
|
914
|
+
jobs.push(
|
|
915
|
+
readOfferings().then(
|
|
916
|
+
(rows3) => update((s3) => ({ ...s3, modelClassIndex: buildModelClassIndex(rows3) })),
|
|
917
|
+
(err) => fail("model-records-refresh-classes-failed", messageOf(err))
|
|
918
|
+
)
|
|
919
|
+
);
|
|
920
|
+
} else {
|
|
921
|
+
for (const id of classesReadFor) {
|
|
922
|
+
jobs.push(
|
|
923
|
+
readOfferings(id).then(
|
|
924
|
+
(rows3) => update((s3) => {
|
|
925
|
+
if (s3.modelClassStatus === "succeeded") return s3;
|
|
926
|
+
const slice = buildModelClassIndex(rows3);
|
|
927
|
+
const base = s3.modelClassIndex ?? { classesByModelId: {}, classOfOffering: {} };
|
|
928
|
+
return { ...s3, modelClassIndex: { classesByModelId: { ...base.classesByModelId, ...slice.classesByModelId }, classOfOffering: { ...base.classOfOffering, ...slice.classOfOffering } } };
|
|
929
|
+
}),
|
|
930
|
+
(err) => fail("model-records-refresh-classes-failed", `${id}: ${messageOf(err)}`, { modelId: id })
|
|
931
|
+
)
|
|
932
|
+
);
|
|
933
|
+
}
|
|
934
|
+
}
|
|
935
|
+
for (const [key, cfg] of Object.entries(known.classConfigByOffering)) {
|
|
936
|
+
const offeringId = key.slice(cfg.modelId.length + 1);
|
|
937
|
+
jobs.push(
|
|
938
|
+
Promise.resolve(ai().rpc("resolve_model_config", { p_model_id: cfg.modelId, p_offering_id: offeringId })).then(
|
|
939
|
+
({ data, error }) => {
|
|
940
|
+
if (error) throw error;
|
|
941
|
+
const next = data && typeof data === "object" && !Array.isArray(data) ? data : null;
|
|
942
|
+
update((s3) => ({ ...s3, classConfigByOffering: { ...s3.classConfigByOffering, [key]: { modelId: cfg.modelId, controls: next?.controls ?? null, constraints: next?.constraints ?? null } } }));
|
|
943
|
+
}
|
|
944
|
+
).catch((err) => fail("model-records-refresh-class-config-failed", `${key}: ${messageOf(err)}`))
|
|
945
|
+
);
|
|
946
|
+
}
|
|
947
|
+
await Promise.all(jobs);
|
|
948
|
+
}
|
|
949
|
+
let refreshing = null;
|
|
950
|
+
let refreshAgain = null;
|
|
951
|
+
function refreshAll() {
|
|
952
|
+
if (refreshing) return refreshAgain ??= refreshing.then(() => {
|
|
953
|
+
refreshAgain = null;
|
|
954
|
+
return refreshAll();
|
|
955
|
+
});
|
|
956
|
+
refreshing = rereadKnown().finally(() => {
|
|
957
|
+
refreshing = null;
|
|
958
|
+
});
|
|
959
|
+
return refreshing;
|
|
960
|
+
}
|
|
850
961
|
async function readOptions() {
|
|
851
962
|
const { data: offeringRows, error: offeringError } = await ai().from("model_offering").select("model_id");
|
|
852
963
|
if (offeringError) throw offeringError;
|
|
@@ -912,20 +1023,7 @@ function createModelRecords(config) {
|
|
|
912
1023
|
return { ...s3, detailStatusById: { ...s3.detailStatusById, [modelId]: "loading" }, detailErrorById };
|
|
913
1024
|
});
|
|
914
1025
|
try {
|
|
915
|
-
const
|
|
916
|
-
const { data, error } = await ai().from(relation).select(MODEL_CONFIG_COLUMNS).eq("id", modelId).maybeSingle();
|
|
917
|
-
if (error) throw error;
|
|
918
|
-
const row = data;
|
|
919
|
-
if (!row) throw new Error(`AI model ${modelId} is not available (ai.${relation} has no such row)`);
|
|
920
|
-
if (!row.id || !row.name) throw new Error(`ai.${relation} returned a row without id/name for model ${modelId}`);
|
|
921
|
-
const read = {
|
|
922
|
-
...row,
|
|
923
|
-
id: row.id,
|
|
924
|
-
name: row.name,
|
|
925
|
-
controls: row.controls ?? null,
|
|
926
|
-
capabilities: requireCanonicalCapabilities(row.capabilities, { modelId: row.id, modelName: row.name })
|
|
927
|
-
};
|
|
928
|
-
const record = normalizeModel(read);
|
|
1026
|
+
const record = await readFullModel(modelId);
|
|
929
1027
|
update((s3) => {
|
|
930
1028
|
const existing = s3.entities[record.id];
|
|
931
1029
|
const detailErrorById = { ...s3.detailErrorById };
|
|
@@ -1049,6 +1147,7 @@ function createModelRecords(config) {
|
|
|
1049
1147
|
}
|
|
1050
1148
|
});
|
|
1051
1149
|
},
|
|
1150
|
+
refresh: () => refreshAll(),
|
|
1052
1151
|
seedModel({ modelId, config: config2, offerings }) {
|
|
1053
1152
|
if (!modelId) return;
|
|
1054
1153
|
if (!classesReadFor.has(modelId) && state2.modelClassStatus !== "succeeded") {
|
|
@@ -331,6 +331,14 @@ interface ModelRecords {
|
|
|
331
331
|
loadModelClasses(modelId: string): Promise<void>;
|
|
332
332
|
/** The durable label of a model outside the options list. Never throws. */
|
|
333
333
|
loadIdentity(modelId: string): Promise<void>;
|
|
334
|
+
/**
|
|
335
|
+
* The catalog changed upstream (a `catalog_changed` notice: an admin renamed, offered or retired a model):
|
|
336
|
+
* re-read everything this instance already read — the options list, every full record, every identity,
|
|
337
|
+
* the class index and slices, every pinned class's controls — and swap each in when it answers. The old
|
|
338
|
+
* rows stay on screen until then (no blank pill, no flicker); a failed re-read keeps them and reports
|
|
339
|
+
* through the error sink. Reads nothing that was never read. Never throws.
|
|
340
|
+
*/
|
|
341
|
+
refresh(): Promise<void>;
|
|
334
342
|
/**
|
|
335
343
|
* Answer `loadModel` + `loadModelClasses` for one model from rows a batched
|
|
336
344
|
* route read already returned (`chat.route_seed`): its `ai.model_config` row
|
|
@@ -331,6 +331,14 @@ interface ModelRecords {
|
|
|
331
331
|
loadModelClasses(modelId: string): Promise<void>;
|
|
332
332
|
/** The durable label of a model outside the options list. Never throws. */
|
|
333
333
|
loadIdentity(modelId: string): Promise<void>;
|
|
334
|
+
/**
|
|
335
|
+
* The catalog changed upstream (a `catalog_changed` notice: an admin renamed, offered or retired a model):
|
|
336
|
+
* re-read everything this instance already read — the options list, every full record, every identity,
|
|
337
|
+
* the class index and slices, every pinned class's controls — and swap each in when it answers. The old
|
|
338
|
+
* rows stay on screen until then (no blank pill, no flicker); a failed re-read keeps them and reports
|
|
339
|
+
* through the error sink. Reads nothing that was never read. Never throws.
|
|
340
|
+
*/
|
|
341
|
+
refresh(): Promise<void>;
|
|
334
342
|
/**
|
|
335
343
|
* Answer `loadModel` + `loadModelClasses` for one model from rows a batched
|
|
336
344
|
* route read already returned (`chat.route_seed`): its `ai.model_config` row
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ai-matrx/agents",
|
|
3
|
-
"version": "0.59.
|
|
3
|
+
"version": "0.59.216",
|
|
4
4
|
"description": "Portable AI Matrx agent stream protocol, event projection, and safe result-presentation primitives.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.cjs",
|
|
@@ -510,10 +510,10 @@
|
|
|
510
510
|
"dependencies": {
|
|
511
511
|
"@ai-matrx/alchemy": "latest",
|
|
512
512
|
"@ai-matrx/api": "latest",
|
|
513
|
-
"@ai-matrx/associations": "latest",
|
|
514
513
|
"@ai-matrx/content-ir": "latest",
|
|
515
514
|
"@ai-matrx/data": "latest",
|
|
516
515
|
"@ai-matrx/design-system": "latest",
|
|
516
|
+
"@ai-matrx/associations": "latest",
|
|
517
517
|
"@ai-matrx/diff": "latest",
|
|
518
518
|
"@ai-matrx/icons": "latest",
|
|
519
519
|
"@ai-matrx/kit": "latest"
|
|
@@ -561,5 +561,5 @@
|
|
|
561
561
|
"verify:tarball": "node ./scripts/verify-tarball.mjs",
|
|
562
562
|
"typegen:self-test": "node scripts/typegen/drop-guard.self-test.mjs && node scripts/typegen/check-api-types-fresh.mjs --self-test"
|
|
563
563
|
},
|
|
564
|
-
"gitHead": "
|
|
564
|
+
"gitHead": "09a96cc8f8c2eb29399669e9343d1f566532c29f"
|
|
565
565
|
}
|