@ai-matrx/agents 0.59.215 → 0.59.217
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/context/index.cjs +5 -1
- package/dist/context/index.d.cts +6 -0
- package/dist/context/index.d.ts +6 -0
- package/dist/context/index.js +5 -1
- package/dist/context/react/index.cjs +7 -1
- package/dist/context/react/index.d.cts +6 -0
- package/dist/context/react/index.d.ts +6 -0
- package/dist/context/react/index.js +7 -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 +5 -5
package/CHANGELOG.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
-
## 0.59.
|
|
3
|
+
## 0.59.217
|
|
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/context/index.cjs
CHANGED
|
@@ -160,7 +160,11 @@ function resolveContextRule(input) {
|
|
|
160
160
|
include = false;
|
|
161
161
|
includeBy = "agent";
|
|
162
162
|
}
|
|
163
|
-
|
|
163
|
+
const ownLocked = !identity && surface?.own === true;
|
|
164
|
+
if (ownLocked) {
|
|
165
|
+
include = false;
|
|
166
|
+
includeBy = "page";
|
|
167
|
+
} else if (user && typeof user.include === "boolean") {
|
|
164
168
|
include = user.include;
|
|
165
169
|
includeBy = "you";
|
|
166
170
|
}
|
package/dist/context/index.d.cts
CHANGED
|
@@ -113,6 +113,12 @@ interface ContextSurfaceLayer {
|
|
|
113
113
|
auto_context?: boolean | null;
|
|
114
114
|
/** `inlineUpTo` / envelope `max_inline_chars` / DB column. */
|
|
115
115
|
max_inline_chars?: number | null;
|
|
116
|
+
/**
|
|
117
|
+
* The value is withheld because this conversation IS the page (`page_context` mode `own`):
|
|
118
|
+
* nothing re-opens it — not the agent's Context Policy, not the person's rule. A page's own
|
|
119
|
+
* chat never receives itself (Arman, 2026-10-01 / 2026-10-21).
|
|
120
|
+
*/
|
|
121
|
+
own?: boolean;
|
|
116
122
|
}
|
|
117
123
|
/** The non-person layers for one value — what the table's layer breakdown shows. */
|
|
118
124
|
interface ContextRuleLayers {
|
package/dist/context/index.d.ts
CHANGED
|
@@ -113,6 +113,12 @@ interface ContextSurfaceLayer {
|
|
|
113
113
|
auto_context?: boolean | null;
|
|
114
114
|
/** `inlineUpTo` / envelope `max_inline_chars` / DB column. */
|
|
115
115
|
max_inline_chars?: number | null;
|
|
116
|
+
/**
|
|
117
|
+
* The value is withheld because this conversation IS the page (`page_context` mode `own`):
|
|
118
|
+
* nothing re-opens it — not the agent's Context Policy, not the person's rule. A page's own
|
|
119
|
+
* chat never receives itself (Arman, 2026-10-01 / 2026-10-21).
|
|
120
|
+
*/
|
|
121
|
+
own?: boolean;
|
|
116
122
|
}
|
|
117
123
|
/** The non-person layers for one value — what the table's layer breakdown shows. */
|
|
118
124
|
interface ContextRuleLayers {
|
package/dist/context/index.js
CHANGED
|
@@ -97,7 +97,11 @@ function resolveContextRule(input) {
|
|
|
97
97
|
include = false;
|
|
98
98
|
includeBy = "agent";
|
|
99
99
|
}
|
|
100
|
-
|
|
100
|
+
const ownLocked = !identity && surface?.own === true;
|
|
101
|
+
if (ownLocked) {
|
|
102
|
+
include = false;
|
|
103
|
+
includeBy = "page";
|
|
104
|
+
} else if (user && typeof user.include === "boolean") {
|
|
101
105
|
include = user.include;
|
|
102
106
|
includeBy = "you";
|
|
103
107
|
}
|
|
@@ -103,7 +103,11 @@ function resolveContextRule(input) {
|
|
|
103
103
|
include = false;
|
|
104
104
|
includeBy = "agent";
|
|
105
105
|
}
|
|
106
|
-
|
|
106
|
+
const ownLocked = !identity && surface?.own === true;
|
|
107
|
+
if (ownLocked) {
|
|
108
|
+
include = false;
|
|
109
|
+
includeBy = "page";
|
|
110
|
+
} else if (user && typeof user.include === "boolean") {
|
|
107
111
|
include = user.include;
|
|
108
112
|
includeBy = "you";
|
|
109
113
|
}
|
|
@@ -218,6 +222,7 @@ function includeChanges(rows, include, cap) {
|
|
|
218
222
|
const changes = [];
|
|
219
223
|
for (const row of rows) {
|
|
220
224
|
if (row.include === include) continue;
|
|
225
|
+
if (row.layers?.surface?.own === true) continue;
|
|
221
226
|
const next = { ...row.userRule ?? {} };
|
|
222
227
|
if (inheritedInclude(row, cap) === include) delete next.include;
|
|
223
228
|
else next.include = include;
|
|
@@ -763,6 +768,7 @@ function ContextRuleRow({
|
|
|
763
768
|
size: "sm",
|
|
764
769
|
"aria-label": `Include ${row.label}`,
|
|
765
770
|
checked: row.include,
|
|
771
|
+
disabled: row.layers?.surface?.own === true,
|
|
766
772
|
onCheckedChange: (next) => onChange(row.key, row.surfaceKey, withInclude(row, next))
|
|
767
773
|
}
|
|
768
774
|
) }),
|
|
@@ -31,6 +31,12 @@ interface ContextSurfaceLayer {
|
|
|
31
31
|
auto_context?: boolean | null;
|
|
32
32
|
/** `inlineUpTo` / envelope `max_inline_chars` / DB column. */
|
|
33
33
|
max_inline_chars?: number | null;
|
|
34
|
+
/**
|
|
35
|
+
* The value is withheld because this conversation IS the page (`page_context` mode `own`):
|
|
36
|
+
* nothing re-opens it — not the agent's Context Policy, not the person's rule. A page's own
|
|
37
|
+
* chat never receives itself (Arman, 2026-10-01 / 2026-10-21).
|
|
38
|
+
*/
|
|
39
|
+
own?: boolean;
|
|
34
40
|
}
|
|
35
41
|
/** The non-person layers for one value — what the table's layer breakdown shows. */
|
|
36
42
|
interface ContextRuleLayers {
|
|
@@ -31,6 +31,12 @@ interface ContextSurfaceLayer {
|
|
|
31
31
|
auto_context?: boolean | null;
|
|
32
32
|
/** `inlineUpTo` / envelope `max_inline_chars` / DB column. */
|
|
33
33
|
max_inline_chars?: number | null;
|
|
34
|
+
/**
|
|
35
|
+
* The value is withheld because this conversation IS the page (`page_context` mode `own`):
|
|
36
|
+
* nothing re-opens it — not the agent's Context Policy, not the person's rule. A page's own
|
|
37
|
+
* chat never receives itself (Arman, 2026-10-01 / 2026-10-21).
|
|
38
|
+
*/
|
|
39
|
+
own?: boolean;
|
|
34
40
|
}
|
|
35
41
|
/** The non-person layers for one value — what the table's layer breakdown shows. */
|
|
36
42
|
interface ContextRuleLayers {
|
|
@@ -62,7 +62,11 @@ function resolveContextRule(input) {
|
|
|
62
62
|
include = false;
|
|
63
63
|
includeBy = "agent";
|
|
64
64
|
}
|
|
65
|
-
|
|
65
|
+
const ownLocked = !identity && surface?.own === true;
|
|
66
|
+
if (ownLocked) {
|
|
67
|
+
include = false;
|
|
68
|
+
includeBy = "page";
|
|
69
|
+
} else if (user && typeof user.include === "boolean") {
|
|
66
70
|
include = user.include;
|
|
67
71
|
includeBy = "you";
|
|
68
72
|
}
|
|
@@ -182,6 +186,7 @@ function includeChanges(rows, include, cap) {
|
|
|
182
186
|
const changes = [];
|
|
183
187
|
for (const row of rows) {
|
|
184
188
|
if (row.include === include) continue;
|
|
189
|
+
if (row.layers?.surface?.own === true) continue;
|
|
185
190
|
const next = { ...row.userRule ?? {} };
|
|
186
191
|
if (inheritedInclude(row, cap) === include) delete next.include;
|
|
187
192
|
else next.include = include;
|
|
@@ -733,6 +738,7 @@ function ContextRuleRow({
|
|
|
733
738
|
size: "sm",
|
|
734
739
|
"aria-label": `Include ${row.label}`,
|
|
735
740
|
checked: row.include,
|
|
741
|
+
disabled: row.layers?.surface?.own === true,
|
|
736
742
|
onCheckedChange: (next) => onChange(row.key, row.surfaceKey, withInclude(row, next))
|
|
737
743
|
}
|
|
738
744
|
) }),
|
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: "268d0c2f1f0b2ea129ee132098cb3e7b9184a2ab",
|
|
51
51
|
generatorVersion: "1.0.0",
|
|
52
|
-
packageVersion: "0.59.
|
|
52
|
+
packageVersion: "0.59.217",
|
|
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: 268d0c2f1f0b2ea129ee132098cb3e7b9184a2ab
|
|
10
10
|
* generator version: 1.0.0
|
|
11
|
-
* package version: 0.59.
|
|
11
|
+
* package version: 0.59.217
|
|
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: "268d0c2f1f0b2ea129ee132098cb3e7b9184a2ab";
|
|
23
23
|
readonly generatorVersion: "1.0.0";
|
|
24
|
-
readonly packageVersion: "0.59.
|
|
24
|
+
readonly packageVersion: "0.59.217";
|
|
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: 268d0c2f1f0b2ea129ee132098cb3e7b9184a2ab
|
|
10
10
|
* generator version: 1.0.0
|
|
11
|
-
* package version: 0.59.
|
|
11
|
+
* package version: 0.59.217
|
|
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: "268d0c2f1f0b2ea129ee132098cb3e7b9184a2ab";
|
|
23
23
|
readonly generatorVersion: "1.0.0";
|
|
24
|
-
readonly packageVersion: "0.59.
|
|
24
|
+
readonly packageVersion: "0.59.217";
|
|
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: "268d0c2f1f0b2ea129ee132098cb3e7b9184a2ab",
|
|
4
4
|
generatorVersion: "1.0.0",
|
|
5
|
-
packageVersion: "0.59.
|
|
5
|
+
packageVersion: "0.59.217",
|
|
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.217",
|
|
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,13 +510,13 @@
|
|
|
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",
|
|
514
|
+
"@ai-matrx/associations": "latest",
|
|
515
515
|
"@ai-matrx/data": "latest",
|
|
516
516
|
"@ai-matrx/design-system": "latest",
|
|
517
517
|
"@ai-matrx/diff": "latest",
|
|
518
|
-
"@ai-matrx/
|
|
519
|
-
"@ai-matrx/
|
|
518
|
+
"@ai-matrx/kit": "latest",
|
|
519
|
+
"@ai-matrx/icons": "latest"
|
|
520
520
|
},
|
|
521
521
|
"peerDependencies": {
|
|
522
522
|
"react": ">=18.0.0",
|
|
@@ -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": "268d0c2f1f0b2ea129ee132098cb3e7b9184a2ab"
|
|
565
565
|
}
|