@ai-matrx/agents 0.59.268 → 0.59.270

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.
@@ -804,7 +804,15 @@ interface LocalModel {
804
804
  /** At least one variant is offered (Matrx 2 lists it). */
805
805
  offered?: boolean;
806
806
  /** The later of the model's and its presentation's updated_at: what an admin edit sends as expected_updated_at. */
807
- updated_at?: string | null;
807
+ updated_at?: string | null; /**
808
+ * Set only when `readModelCatalog(client, { devices })` asked: the computers that hold every required file of
809
+ * one of this model's listed variants (models/device-models.ts `availableOnDevices`). Absent otherwise.
810
+ */
811
+ available_on?: Array<{
812
+ app_instance_id: string;
813
+ variant_id: string;
814
+ device_model_file_ids: string[];
815
+ }>;
808
816
  }
809
817
  interface LocalCompatRow {
810
818
  hardware_class: HardwareClass;
@@ -804,7 +804,15 @@ interface LocalModel {
804
804
  /** At least one variant is offered (Matrx 2 lists it). */
805
805
  offered?: boolean;
806
806
  /** The later of the model's and its presentation's updated_at: what an admin edit sends as expected_updated_at. */
807
- updated_at?: string | null;
807
+ updated_at?: string | null; /**
808
+ * Set only when `readModelCatalog(client, { devices })` asked: the computers that hold every required file of
809
+ * one of this model's listed variants (models/device-models.ts `availableOnDevices`). Absent otherwise.
810
+ */
811
+ available_on?: Array<{
812
+ app_instance_id: string;
813
+ variant_id: string;
814
+ device_model_file_ids: string[];
815
+ }>;
808
816
  }
809
817
  interface LocalCompatRow {
810
818
  hardware_class: HardwareClass;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ai-matrx/agents",
3
- "version": "0.59.268",
3
+ "version": "0.59.270",
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",
@@ -518,23 +518,5 @@
518
518
  "optional": true
519
519
  }
520
520
  },
521
- "matrx": {
522
- "charter": "The headless agent core and the server API contract.",
523
- "owns": [
524
- "transport",
525
- "stream protocol",
526
- "mandates",
527
- "agent catalog and picker",
528
- "models",
529
- "skills",
530
- "generated server types"
531
- ],
532
- "mustNotOwn": [
533
- "chat UI",
534
- "Redux",
535
- "the agent builder"
536
- ],
537
- "layer": 5
538
- },
539
- "gitHead": "5b7c48a99c8d209284a96f989c5fdbc74187940c"
521
+ "gitHead": "8a4ed656ea91ae1934870745a5c95f91f24da863"
540
522
  }
@@ -8,7 +8,10 @@
8
8
  * Fails when a file outside apps/shared/matrx-agents/models/:
9
9
  * R1 reads ai.model_definition / model_public / model_offering / model_config / model_variant /
10
10
  * model_presentation (`.from("…")`) or the catalog RPCs (`admin_model_catalog`, `resolve_model_config`);
11
- * R2 computes a model label by hand (`x.common_name || x.name`, `?? …name`) instead of `modelDisplayLabel`.
11
+ * R2 computes a model label by hand (`x.common_name || x.name`, `?? …name`) instead of `modelDisplayLabel`;
12
+ * R3 reads ai.device_model_file (`.from("device_model_file").select(`) to decide which computer holds a
13
+ * model, instead of readModelCatalog({ devices }) / resolveDeviceModel. Writes (the computer publishing
14
+ * its own files) are not reads and pass.
12
15
  * ALLOWED lists the few readers that keep their own read on purpose, each with why and how it follows the
13
16
  * event. Test files are fixtures and are not scanned.
14
17
  *
@@ -55,6 +58,7 @@ const SKIP_DIR = new Set(["node_modules", "dist", ".next", ".next-preview", ".tu
55
58
  const isTest = (p) => /\.(test|spec)\.[cm]?[jt]sx?$/.test(p) || /\.d\.ts$/.test(p) || /\.generated\./.test(p);
56
59
 
57
60
  const R1 = /\.from\(\s*["'`](model_definition|model_public|model_offering|model_config|model_variant|model_presentation)["'`]|\.rpc\(\s*["'`](admin_model_catalog|resolve_model_config)["'`]/g;
61
+ const R3 = /\.from\(\s*["'`]device_model_file["'`]\s*\)\s*\.select\(/g;
58
62
  const R2 = /\bcommon_name\s*(\|\||\?\?)\s*[\w$?.]*\bname\b/g;
59
63
 
60
64
  function* walk(dir) {
@@ -85,6 +89,7 @@ function scan(roots) {
85
89
  for (const [rule, re, what] of [
86
90
  ["R1", R1, "reads the model catalog directly — use @ai-matrx/agents/models (records / chat's useModelLabel / readModelIdentities)"],
87
91
  ["R2", R2, "computes a model label by hand — use modelDisplayLabel(row) from @ai-matrx/agents/models"],
92
+ ["R3", R3, "reads device model placement directly — use readModelCatalog(client, { devices }) / resolveDeviceModel from @ai-matrx/agents/models"],
88
93
  ]) {
89
94
  re.lastIndex = 0;
90
95
  for (let m; (m = re.exec(src)); ) findings.push(`${rel}:${lineOf(src, m.index)} ${rule} ${what} [${m[0].replace(/\s+/g, " ")}]`);
@@ -98,15 +103,15 @@ if (args.includes("--self-test")) {
98
103
  // Falsifiability: a planted direct read and a hand-made label must each fail; the lawful form must pass.
99
104
  const dir = mkdtempSync(join(tmpdir(), "model-catalog-reads-"));
100
105
  try {
101
- writeFileSync(join(dir, "bad.ts"), 'export const r = (db: any) => db.schema("ai").from("model_definition").select("id");\nexport const l = (m: any) =>\n m?.common_name ??\n m?.name;\n');
102
- writeFileSync(join(dir, "good.ts"), 'import { modelDisplayLabel } from "@ai-matrx/agents/models";\nexport const l = (m: any) => modelDisplayLabel(m) ?? m.common_name ?? null;\n');
106
+ writeFileSync(join(dir, "bad.ts"), 'export const r = (db: any) => db.schema("ai").from("model_definition").select("id");\nexport const l = (m: any) =>\n m?.common_name ??\n m?.name;\nexport const d = (db: any) => db.schema("ai").from("device_model_file").select("*");\n');
107
+ writeFileSync(join(dir, "good.ts"), 'import { modelDisplayLabel } from "@ai-matrx/agents/models";\nexport const l = (m: any) => modelDisplayLabel(m) ?? m.common_name ?? null;\nexport const w = (db: any, rows: any[]) => db.schema("ai").from("device_model_file").upsert(rows);\n');
103
108
  const got = scan([dir]);
104
- const ok = got.length === 2 && got.some((f) => f.includes("bad.ts:1 R1")) && got.some((f) => f.includes("bad.ts:3 R2"));
109
+ const ok = got.length === 3 && got.some((f) => f.includes("bad.ts:1 R1")) && got.some((f) => f.includes("bad.ts:3 R2")) && got.some((f) => f.includes("bad.ts:5 R3"));
105
110
  if (!ok) {
106
- console.error(`check-model-catalog-reads --self-test: FAILED — expected R1+R2 on bad.ts only, got:\n ${got.join("\n ") || "(nothing)"}`);
111
+ console.error(`check-model-catalog-reads --self-test: FAILED — expected R1+R2+R3 on bad.ts only, got:\n ${got.join("\n ") || "(nothing)"}`);
107
112
  process.exit(1);
108
113
  }
109
- console.log("check-model-catalog-reads --self-test: OK — a planted read and a hand-made label both go red; modelDisplayLabel passes.");
114
+ console.log("check-model-catalog-reads --self-test: OK — a planted catalog read, a hand-made label and a device placement read all go red; modelDisplayLabel and a device file write pass.");
110
115
  process.exit(0);
111
116
  } finally {
112
117
  rmSync(dir, { recursive: true, force: true });