@x12i/catalox 3.7.1 → 3.8.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 (31) hide show
  1. package/README.md +39 -0
  2. package/dist/src/catalox/catalog-discovery.d.ts +1 -24
  3. package/dist/src/catalox/catalog-discovery.d.ts.map +1 -1
  4. package/dist/src/catalox/catalog-discovery.js +0 -82
  5. package/dist/src/catalox/catalog-discovery.js.map +1 -1
  6. package/dist/src/catalox/catalox-bound.d.ts +1 -5
  7. package/dist/src/catalox/catalox-bound.d.ts.map +1 -1
  8. package/dist/src/catalox/catalox-bound.js +0 -12
  9. package/dist/src/catalox/catalox-bound.js.map +1 -1
  10. package/dist/src/catalox/catalox.d.ts +1 -5
  11. package/dist/src/catalox/catalox.d.ts.map +1 -1
  12. package/dist/src/catalox/catalox.js +1 -170
  13. package/dist/src/catalox/catalox.js.map +1 -1
  14. package/dist/src/contracts/descriptor-rules.d.ts +5 -5
  15. package/dist/src/contracts/descriptor-rules.d.ts.map +1 -1
  16. package/dist/src/contracts/discovery.d.ts +0 -30
  17. package/dist/src/contracts/discovery.d.ts.map +1 -1
  18. package/dist/src/contracts/index.d.ts +2 -2
  19. package/dist/src/contracts/index.d.ts.map +1 -1
  20. package/dist/src/contracts/index.js.map +1 -1
  21. package/dist/src/contracts/search.d.ts +1 -108
  22. package/dist/src/contracts/search.d.ts.map +1 -1
  23. package/dist/src/firebase/bootstrap.d.ts +62 -0
  24. package/dist/src/firebase/bootstrap.d.ts.map +1 -1
  25. package/dist/src/firebase/bootstrap.js +91 -1
  26. package/dist/src/firebase/bootstrap.js.map +1 -1
  27. package/package.json +1 -2
  28. package/dist/src/catalox/ai-functions-loader.d.ts +0 -6
  29. package/dist/src/catalox/ai-functions-loader.d.ts.map +0 -1
  30. package/dist/src/catalox/ai-functions-loader.js +0 -19
  31. package/dist/src/catalox/ai-functions-loader.js.map +0 -1
@@ -34,8 +34,7 @@ import { SnapshotStore } from "../firebase/snapshot-store.js";
34
34
  import { StoreAppBindingStore } from "../firebase/store-app-binding-store.js";
35
35
  import { IdentityBindingStore } from "../firebase/identity-binding-store.js";
36
36
  import { nativeItemsCollectionId } from "../firebase/catalog-data-paths.js";
37
- import { applyCatalogVisibilityFilter, filterCatalogsByText, findCatalogsByAi as findCatalogsByAiHelper, summarizeCatalog, } from "./catalog-discovery.js";
38
- import { loadAiFunctions } from "./ai-functions-loader.js";
37
+ import { applyCatalogVisibilityFilter, filterCatalogsByText, summarizeCatalog, } from "./catalog-discovery.js";
39
38
  import { runBackupData, pruneGcsBackupRuns } from "./backup-data.js";
40
39
  import { runUndoFirestoreRestore } from "./restore-firestore-backup.js";
41
40
  import { runRestoreFirestoreBackupFromGcs, runDeleteCataloxGcsBackupRun } from "./restore-firestore-backup-from-gcs.js";
@@ -840,13 +839,6 @@ export class Catalox {
840
839
  });
841
840
  return filterCatalogsByText(all, input);
842
841
  }
843
- async findCatalogsByAi(context, input) {
844
- const all = await this.listAllCatalogs(context, {
845
- ...(input.includeDisabled != null ? { includeDisabled: input.includeDisabled } : {}),
846
- ...(input.includeHidden != null ? { includeHidden: input.includeHidden } : {}),
847
- });
848
- return findCatalogsByAiHelper({ query: input.query, catalogs: all, input });
849
- }
850
842
  async getCatalogDescriptor(context, catalogId) {
851
843
  const appId = await this.resolveAppIdForCatalogAccess({ context, catalogId, required: "read" });
852
844
  await this.deps.authz.requireBindingAccess(context, appId, catalogId, "read");
@@ -1370,167 +1362,6 @@ export class Catalox {
1370
1362
  });
1371
1363
  return { ...base, items: filtered.slice(0, limit) };
1372
1364
  }
1373
- async findCatalogItemsByAi(context, catalogId, input) {
1374
- const poolLimit = input.poolLimit ?? 300;
1375
- const base = await this.listCatalogItems(context, catalogId, {
1376
- limit: poolLimit,
1377
- ...(input.scope ? { scope: input.scope } : {}),
1378
- ...(input.filter ? { filter: input.filter } : {}),
1379
- ...(input.sort ? { sort: input.sort } : {}),
1380
- });
1381
- if (base.listOutcome !== "ok")
1382
- return { query: input.query, hits: [], noMatch: true };
1383
- const items = base.items;
1384
- const candidates = items.map((it) => {
1385
- const title = it.title ? String(it.title) : "";
1386
- const subtitle = it.subtitle ? String(it.subtitle) : "";
1387
- const label = [title, subtitle].filter(Boolean).join(" — ") || String(it.itemId);
1388
- return {
1389
- id: String(it.itemId),
1390
- label,
1391
- metadata: { catalogId: String(catalogId) },
1392
- };
1393
- });
1394
- const { match } = await loadAiFunctions();
1395
- const res = await match({
1396
- query: input.query,
1397
- candidates,
1398
- ...(input.guidance ? { guidance: input.guidance } : {}),
1399
- ...(input.maxResults != null ? { maxResults: input.maxResults } : {}),
1400
- ...(input.minScore != null ? { minScore: input.minScore } : {}),
1401
- ...(input.allowNoMatch != null ? { allowNoMatch: input.allowNoMatch } : {}),
1402
- ...(input.returnReasons != null ? { returnReasons: input.returnReasons } : {}),
1403
- ...(input.additionalInstructions ? { additionalInstructions: input.additionalInstructions } : {}),
1404
- ...(input.maxCandidates != null ? { maxCandidates: input.maxCandidates } : {}),
1405
- ...(input.mode ? { mode: input.mode } : {}),
1406
- ...(input.client ? { client: input.client } : {}),
1407
- ...(input.model ? { model: input.model } : {}),
1408
- ...(input.temperature != null ? { temperature: input.temperature } : {}),
1409
- ...(input.maxTokens != null ? { maxTokens: input.maxTokens } : {}),
1410
- ...(input.timeoutMs != null ? { timeoutMs: input.timeoutMs } : {}),
1411
- ...(input.vendor != null ? { vendor: input.vendor } : {}),
1412
- });
1413
- const byId = new Map(items.map((it) => [String(it.itemId), it]));
1414
- const hits = res.matches
1415
- .map((m) => {
1416
- const it = byId.get(String(m.id));
1417
- if (!it)
1418
- return null;
1419
- return { itemId: it.itemId, score: m.score, ...(m.reason ? { reason: m.reason } : {}), item: it };
1420
- })
1421
- .filter(Boolean);
1422
- return { query: input.query, hits, noMatch: Boolean(res.noMatch) };
1423
- }
1424
- async createCatalogItemByAi(context, catalogId, input) {
1425
- const appId = await this.resolveAppIdForCatalogAccess({ context, catalogId, required: "write" });
1426
- await this.deps.authz.requireBindingAccess(context, appId, catalogId, "write");
1427
- const descRec = await this.deps.descriptors.get(catalogId);
1428
- if (!descRec)
1429
- throw new CatalogAdapterError({ catalogId, reason: "missing_descriptor" });
1430
- const rules = descRec.descriptor.creationRules;
1431
- if (!rules)
1432
- throw new CatalogAdapterError({ catalogId, reason: "creation_rules_missing" });
1433
- if (rules.enabled === false)
1434
- throw new CatalogAdapterError({ catalogId, reason: "creation_rules_disabled" });
1435
- const catalog = await this.deps.catalogs.get(catalogId);
1436
- if (!catalog)
1437
- throw new CatalogNotFoundError({ catalogId });
1438
- const existingLimit = input.existingItemsSampleLimit ?? 0;
1439
- const existingItemsSample = existingLimit > 0
1440
- ? (await this.listCatalogItems(context, catalogId, { limit: existingLimit })).items.map((i) => i.data)
1441
- : undefined;
1442
- const { createItem } = await loadAiFunctions();
1443
- const result = await createItem({
1444
- ...(descRec.descriptor.itemLabel ? { itemLabel: descRec.descriptor.itemLabel } : {}),
1445
- creationRules: rules,
1446
- provided: input.provided,
1447
- fieldSchema: (descRec.descriptor.queryableFields ?? []),
1448
- ...(existingItemsSample ? { existingItemsSample } : {}),
1449
- ...(input.additionalInstructions ? { additionalInstructions: input.additionalInstructions } : {}),
1450
- ...(input.mode ? { mode: input.mode } : {}),
1451
- ...(input.model ? { model: input.model } : {}),
1452
- ...(input.client ? { client: input.client } : {}),
1453
- ...(input.temperature != null ? { temperature: input.temperature } : {}),
1454
- ...(input.maxTokens != null ? { maxTokens: input.maxTokens } : {}),
1455
- ...(input.timeoutMs != null ? { timeoutMs: input.timeoutMs } : {}),
1456
- ...(input.vendor != null ? { vendor: input.vendor } : {}),
1457
- }, undefined);
1458
- const out = {
1459
- catalogId,
1460
- proposed: result.item ?? {},
1461
- issues: (result.issues ?? []),
1462
- ...(result.missingInputs ? { missingInputs: result.missingInputs } : {}),
1463
- noCreate: Boolean(result.noCreate),
1464
- ...(result.reason ? { reason: result.reason } : {}),
1465
- };
1466
- const autoPersist = input.autoPersist === true;
1467
- const hasErrors = (result.issues ?? []).some((i) => i?.severity === "error");
1468
- if (autoPersist && !out.noCreate && !hasErrors) {
1469
- if (catalog.sourceMode !== "native") {
1470
- throw new CatalogAdapterError({ catalogId, reason: "autopersist_mapped_unsupported" });
1471
- }
1472
- const writePayload = input.scope != null ? { ...out.proposed, scope: input.scope } : out.proposed;
1473
- out.item = await this.upsertNativeCatalogItem(context, catalogId, writePayload);
1474
- }
1475
- return out;
1476
- }
1477
- async modifyCatalogItemByAi(context, catalogId, itemId, input) {
1478
- const appId = await this.resolveAppIdForCatalogAccess({ context, catalogId, required: "write" });
1479
- await this.deps.authz.requireBindingAccess(context, appId, catalogId, "write");
1480
- const descRec = await this.deps.descriptors.get(catalogId);
1481
- if (!descRec)
1482
- throw new CatalogAdapterError({ catalogId, reason: "missing_descriptor" });
1483
- const rules = descRec.descriptor.modificationRules;
1484
- if (!rules)
1485
- throw new CatalogAdapterError({ catalogId, reason: "modification_rules_missing" });
1486
- if (rules.enabled === false)
1487
- throw new CatalogAdapterError({ catalogId, reason: "modification_rules_disabled" });
1488
- const catalog = await this.deps.catalogs.get(catalogId);
1489
- if (!catalog)
1490
- throw new CatalogNotFoundError({ catalogId });
1491
- const got = await this.getCatalogItem(context, catalogId, itemId, input.nativeItemOptions);
1492
- if (got.outcome === "mapping_blocked") {
1493
- throw new CatalogAdapterError({ catalogId, reason: "mapping_validation_failed", issues: got.issues });
1494
- }
1495
- if (got.outcome === "not_found")
1496
- throw new CatalogNotFoundError({ catalogId, itemId });
1497
- const currentItem = (got.item.data ?? {});
1498
- const { modifyItem } = await loadAiFunctions();
1499
- const result = await modifyItem({
1500
- ...(descRec.descriptor.itemLabel ? { itemLabel: descRec.descriptor.itemLabel } : {}),
1501
- currentItem: currentItem,
1502
- modificationRules: rules,
1503
- patch: input.patch,
1504
- fieldSchema: (descRec.descriptor.queryableFields ?? []),
1505
- ...(input.additionalInstructions ? { additionalInstructions: input.additionalInstructions } : {}),
1506
- ...(input.mode ? { mode: input.mode } : {}),
1507
- ...(input.model ? { model: input.model } : {}),
1508
- ...(input.client ? { client: input.client } : {}),
1509
- ...(input.temperature != null ? { temperature: input.temperature } : {}),
1510
- ...(input.maxTokens != null ? { maxTokens: input.maxTokens } : {}),
1511
- ...(input.timeoutMs != null ? { timeoutMs: input.timeoutMs } : {}),
1512
- ...(input.vendor != null ? { vendor: input.vendor } : {}),
1513
- }, undefined);
1514
- const out = {
1515
- catalogId,
1516
- itemId,
1517
- proposed: result.item ?? {},
1518
- diff: (result.diff ?? []),
1519
- issues: (result.issues ?? []),
1520
- ...(result.violatedRules ? { violatedRules: result.violatedRules } : {}),
1521
- noChange: Boolean(result.noChange),
1522
- ...(result.reason ? { reason: result.reason } : {}),
1523
- };
1524
- const autoPersist = input.autoPersist === true;
1525
- const hasErrors = (result.issues ?? []).some((i) => i?.severity === "error");
1526
- if (autoPersist && !out.noChange && !hasErrors) {
1527
- if (catalog.sourceMode !== "native") {
1528
- throw new CatalogAdapterError({ catalogId, reason: "autopersist_mapped_unsupported" });
1529
- }
1530
- out.item = await this.updateNativeCatalogItem(context, catalogId, itemId, out.proposed, input.nativeItemOptions);
1531
- }
1532
- return out;
1533
- }
1534
1365
  async bindCatalogToApp(_context, _input) {
1535
1366
  const existing = await this.deps.bindings.findByAppCatalog(_input.appId, _input.catalogId);
1536
1367
  if (existing)