@ai-matrx/agents 0.59.272 → 0.59.274

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 CHANGED
@@ -1,5 +1,19 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.59.274
4
+
5
+ - `./models`: a burst of `catalog_changed` is ONE re-read. New `coalesceModelCatalogChanges(deliver, options?)`:
6
+ a `requestId` already delivered (60 s) is dropped; the first envelope of a burst is delivered at once; copies
7
+ with the same payload inside 1.5 s are dropped; a different payload inside the window is delivered once when
8
+ it closes. `followModelCatalogChanges(subscribe, options?)` uses it, and the subscribe handler may pass a
9
+ second `meta` argument (`{ requestId }`). Live 2026-10-24: one edit reached every open app as 8 + 8
10
+ envelopes. Consumer action: none for the web; Matrx 2's main-process follower adopts the coalescer.
11
+
12
+ ## 0.59.273
13
+
14
+ Automatic changed-only republish (docs/metadata drift since the last published version; verified: `git diff 467bc8f112 757401d3d2 -- apps/shared/matrx-agents/src`
15
+ has no shipped-source changes outside tests, fixtures and docs). No consumer action required.
16
+
3
17
  ## 0.59.272
4
18
 
5
19
  - New export `./context/rules-corpus.json` (shipped in `files`): the context-rules parity corpus, so a consumer test (chat) reads it through the dependency instead of a path into this package. Additive; no consumer action required.
@@ -62,6 +62,7 @@ __export(models_exports, {
62
62
  catalogKindVerdict: () => catalogKindVerdict,
63
63
  cheapestAdequateModel: () => cheapestAdequateModel,
64
64
  classConfigKey: () => classConfigKey,
65
+ coalesceModelCatalogChanges: () => coalesceModelCatalogChanges,
65
66
  collapseTiersByClass: () => collapseTiersByClass,
66
67
  costRatingTier: () => costRatingTier,
67
68
  costRatingWord: () => costRatingWord,
@@ -1574,8 +1575,64 @@ function announceModelCatalogChanged(payload = {}) {
1574
1575
  }
1575
1576
  }
1576
1577
  }
1577
- function followModelCatalogChanges(subscribe) {
1578
- return subscribe("catalog_changed", (payload) => announceModelCatalogChanged(payload ?? {}));
1578
+ var contentKey = (payload) => JSON.stringify(
1579
+ Object.keys({ catalog: "models", ...payload }).sort().map((k) => [k, k === "catalog" ? payload[k] ?? "models" : payload[k] ?? null]).filter(([, v]) => v !== null)
1580
+ );
1581
+ function coalesceModelCatalogChanges(deliver, options = {}) {
1582
+ const windowMs = options.windowMs ?? 1500;
1583
+ const rememberMs = options.rememberMs ?? 6e4;
1584
+ const now = options.now ?? (() => Date.now());
1585
+ const setTimer = options.setTimer ?? ((fn, ms) => setTimeout(fn, ms));
1586
+ const clearTimer = options.clearTimer ?? ((h) => clearTimeout(h));
1587
+ const seenIds = /* @__PURE__ */ new Map();
1588
+ let windowStart = -Infinity;
1589
+ let windowKeys = /* @__PURE__ */ new Set();
1590
+ let pending = null;
1591
+ let timer = null;
1592
+ const open = (payload, at) => {
1593
+ windowStart = at;
1594
+ windowKeys = /* @__PURE__ */ new Set([contentKey(payload)]);
1595
+ deliver(payload);
1596
+ };
1597
+ const feed = (payload, meta) => {
1598
+ const p = payload ?? {};
1599
+ const t = now();
1600
+ for (const [id2, at] of seenIds) if (t - at > rememberMs) seenIds.delete(id2);
1601
+ const id = typeof meta?.requestId === "string" && meta.requestId ? meta.requestId : null;
1602
+ if (id !== null) {
1603
+ if (seenIds.has(id)) return;
1604
+ seenIds.set(id, t);
1605
+ }
1606
+ if (t - windowStart >= windowMs) return open(p, t);
1607
+ const key = contentKey(p);
1608
+ if (windowKeys.has(key)) return;
1609
+ windowKeys.add(key);
1610
+ pending = p;
1611
+ timer ??= setTimer(() => {
1612
+ timer = null;
1613
+ const next = pending;
1614
+ pending = null;
1615
+ if (next) open(next, now());
1616
+ }, Math.max(0, windowStart + windowMs - t));
1617
+ };
1618
+ return Object.assign(feed, {
1619
+ stop() {
1620
+ if (timer !== null) clearTimer(timer);
1621
+ timer = null;
1622
+ pending = null;
1623
+ }
1624
+ });
1625
+ }
1626
+ function followModelCatalogChanges(subscribe, options) {
1627
+ const feed = coalesceModelCatalogChanges((payload) => announceModelCatalogChanged(payload), options);
1628
+ const off = subscribe("catalog_changed", (payload, meta) => {
1629
+ if (!isModelCatalogChange(payload ?? {})) return;
1630
+ feed(payload ?? {}, meta);
1631
+ });
1632
+ return () => {
1633
+ feed.stop();
1634
+ off();
1635
+ };
1579
1636
  }
1580
1637
  function followModelCatalogVisibility(options) {
1581
1638
  const page = options.page ?? (typeof document !== "undefined" && typeof window !== "undefined" ? { document, window } : null);
@@ -2831,7 +2888,8 @@ function toDeviceModelFile(r) {
2831
2888
  sha256: sn2(r.sha256),
2832
2889
  artifact_id: sn2(r.artifact_id),
2833
2890
  state: s2(r.state),
2834
- organization_id: sn2(r.organization_id)
2891
+ organization_id: sn2(r.organization_id),
2892
+ model_key: sn2(r.metadata?.model_key)
2835
2893
  };
2836
2894
  }
2837
2895
  async function readDeviceModelFiles(client, opts = {}) {
@@ -1764,6 +1764,11 @@ interface DeviceModelFile {
1764
1764
  artifact_id: string | null;
1765
1765
  state: string;
1766
1766
  organization_id: string | null;
1767
+ /**
1768
+ * The key the computer runs this file under (`metadata.model_key`, published by Matrx 2): for a person's own
1769
+ * file it is the run key the device's model service names it by. Null when not reported yet.
1770
+ */
1771
+ model_key: string | null;
1767
1772
  }
1768
1773
  declare function toDeviceModelFile(r: Row$1): DeviceModelFile;
1769
1774
  /**
@@ -2061,8 +2066,12 @@ declare function modelDisplayLabel(row: ModelLabelSource | null | undefined): st
2061
2066
 
2062
2067
  /** A `catalog_changed` payload: `{ catalog?: "models" | ..., change?, model_id? }`. */
2063
2068
  type ModelCatalogChangePayload = Record<string, unknown>;
2069
+ /** What the bus knew about one envelope besides its payload: its `requestId` (the server names one burst once). */
2070
+ type ModelCatalogChangeMeta = {
2071
+ requestId?: string | null;
2072
+ } | null | undefined;
2064
2073
  /** The bus client's subscribe call: `(action, handler) => unsubscribe` (the web's `registerDirectiveHandler`). */
2065
- type ModelCatalogDirectiveSubscribe = (action: "catalog_changed", handler: (payload: ModelCatalogChangePayload) => void) => () => void;
2074
+ type ModelCatalogDirectiveSubscribe = (action: "catalog_changed", handler: (payload: ModelCatalogChangePayload, meta?: ModelCatalogChangeMeta) => void) => () => void;
2066
2075
  /** Is this notice about the MODEL catalog? (`catalog` absent or `"models"`; the tool catalog shares the action.) */
2067
2076
  declare function isModelCatalogChange(payload: ModelCatalogChangePayload | null | undefined): boolean;
2068
2077
  /** Listen for model catalog changes. Returns the unsubscribe. */
@@ -2071,8 +2080,32 @@ declare function onModelCatalogChanged(listener: (payload: ModelCatalogChangePay
2071
2080
  declare function modelCatalogRevision(): number;
2072
2081
  /** Announce a model catalog change to every listener (a notice that is not about models is ignored). */
2073
2082
  declare function announceModelCatalogChanged(payload?: ModelCatalogChangePayload): void;
2074
- /** Bind the host's bus client: every `catalog_changed` it delivers reaches every model reader. Returns the unbind. */
2075
- declare function followModelCatalogChanges(subscribe: ModelCatalogDirectiveSubscribe): () => void;
2083
+ interface ModelCatalogCoalesceOptions {
2084
+ /** Envelopes within this many ms of the last delivery are the same burst. Default 1500. */
2085
+ windowMs?: number;
2086
+ /** How long a delivered `requestId` is remembered (a late replica's copy is dropped). Default 60 s. */
2087
+ rememberMs?: number;
2088
+ now?: () => number;
2089
+ setTimer?: (fn: () => void, ms: number) => unknown;
2090
+ clearTimer?: (handle: unknown) => void;
2091
+ }
2092
+ /**
2093
+ * Fold a burst of `catalog_changed` envelopes into ONE delivery. The server's replicas (and, before
2094
+ * 2026-10-24, a second relay ~4 s later) can put the same change on the bus several times; every copy used to
2095
+ * cost every open app a re-read. Rules: an envelope whose `requestId` was delivered within `rememberMs` is
2096
+ * dropped; the first envelope of a burst is delivered at once; within `windowMs` of that delivery a copy with
2097
+ * the same payload is dropped, and a DIFFERENT payload (another model, another kind of edit) is delivered
2098
+ * once when the window closes, so a real second change is never lost. Returns the feed; `feed.stop()` drops
2099
+ * a pending delivery.
2100
+ */
2101
+ declare function coalesceModelCatalogChanges(deliver: (payload: ModelCatalogChangePayload) => void, options?: ModelCatalogCoalesceOptions): ((payload: ModelCatalogChangePayload, meta?: ModelCatalogChangeMeta) => void) & {
2102
+ stop(): void;
2103
+ };
2104
+ /**
2105
+ * Bind the host's bus client: every `catalog_changed` it delivers reaches every model reader, a burst of
2106
+ * copies as ONE change (`coalesceModelCatalogChanges`). Returns the unbind.
2107
+ */
2108
+ declare function followModelCatalogChanges(subscribe: ModelCatalogDirectiveSubscribe, options?: ModelCatalogCoalesceOptions): () => void;
2076
2109
  interface ModelCatalogVisibilityOptions {
2077
2110
  /** The client the stamp is read with (supabase-js fits as is). */
2078
2111
  client: ModelRecordsClient;
@@ -2100,5 +2133,5 @@ interface ModelCatalogVisibilityOptions {
2100
2133
  */
2101
2134
  declare function followModelCatalogVisibility(options: ModelCatalogVisibilityOptions): () => void;
2102
2135
 
2103
- export { CHAT_DEFAULT_MODEL_KNOB, CONTENT_TYPES, DEFAULT_CAPABILITIES, DEVICE_FILE_USABLE_STATES, DEVICE_OWN_FILE_USABLE_STATES, DEVICE_RULE_TWIN_FIXTURE, DEVICE_SERVED_SETTINGS_KEY, DEVICE_SERVED_VIA, DeviceModelUnavailableError, EMPTY_MODEL_RECORDS, EXCLUDED_REVIEW_STATES, FEATURE_BUCKETS, FEATURE_BUCKET_ORDER, FEATURE_KEYS, FILE_TYPE_QUANT, GgufError, INPUT_MODALITIES, INTERACTION_MODES, LLM_INTERACTIONS, MAX_SUCCESSION_HOPS, MODEL_CATALOG_KINDS, MODEL_FAVORITE_ENTITY_TYPE, NEW_AGENT_DEFAULT_MODEL_KNOB, OUTPUT_MODALITIES, SERVICE_LABEL, SERVICE_LABEL_PLURAL, TOP_TIER_COST_RATING, TOP_TIER_LOCKED_TITLE, UNKNOWN_MODEL_KIND, acceptsTextInstructions, announceModelCatalogChanged, availableOnDevices, blendedPrice, buildModelClassIndex, buildSuccessionIndex, catalogFingerprint, catalogForApp, catalogKeyColumn, catalogKindOf, catalogKindVerdict, cheapestAdequateModel, classConfigKey, collapseTiersByClass, costRatingTier, costRatingWord, createModelCatalog, createModelFavorites, createModelRecords, curatedList, displayOrderOf, favoriteIdsEqual, fetchCuratedModels, findNonCanonicalCapabilityValues, fitsMemory, fitsNeed, fitsThisComputer, followModelCatalogChanges, followModelCatalogVisibility, formatMemoryBytes, fromDiscovery, ggufEngine, ggufFacts, groupFeatures, hardwareClassesOf, hasCompatibleDecisionInteraction, isChatModelCapability, isContentType, isConversationalModelCapability, isDecisionModelCapability, isFeatureKey, isHelperGguf, isInteractionMode, isListedVariant, isLocalModelCatalog, isManagedAgentModelCapability, isModelCatalogChange, isProjectorName, isSupersedable, isTopTierRating, judgeHeaderFacts, mergeAuditRecordIntoCapabilities, missingShards, modelCatalogRevision, modelClassKnobFor, modelClassName, modelClassPinOf, modelDisplayLabel, modelsForSelectionPurpose, normalizeArch, normalizeModel, normalizeModels, normalizeOs, normalizePromptSettings, onModelCatalogChanged, orderCatalogGroups, orderCatalogModels, outputFormatControlKey, parseCapabilities, pickProjector, priceTierRating, quantFromName, rankVariants, readCuratedRows, readDeviceModelFiles, readGgufHeader, readModelCatalog, readModelCatalogStamp, readModelIdentities, readPublicModel, reconcileModelFavoriteIds, reportModelDiagnostic, requireCanonicalCapabilities, requiredArtifactIds, requiredArtifacts, resetSuccessionLogForTests, resolveDeviceModel, resolveLiveModelId, resolveModelMapKnob, resolveNewAgentModelId, resolvePreferredModelChoice, resolveSuccessor, runtimesOnEngine, seesImages, selectActiveModels, selectActiveModelsReady, selectAllModelOptions, selectAllModels, selectAllModelsReady, selectDeprecatedModels, selectDeprecatedModelsReady, selectModelById, selectModelClassConfig, selectModelClassName, selectModelControls, selectModelDetailError, selectModelFetchType, selectModelFullyLoaded, selectModelIdentityById, selectModelIdentityLookupStatus, selectModelLabelById, selectModelLabelWithClass, selectModelNameById, selectModelOptions, selectVariant, serviceCountLabel, setModelDiagnosticsSink, shapeCuratedModels, shardFileName, shardName, speedRatingLabel, speedRatingWord, splitSetProblems, takesInput, toAuditRecord, toDeviceModelFile, validateModelSet, variantVerdict, withModelClass };
2104
- export type { AdminOffering, AdminPricingBand, ArtifactUse, AuditCapabilitiesRecord, AvailabilityVariant, CapabilitiesParseContext, CatalogKeyColumn, CatalogKindInput, CatalogKindVerdict, CatalogModel, CatalogTier, CheapestAdequateOptions, CompatStatus, ContentType, CuratedCatalogClient, CuratedModel, CuratedPresentation, CuratedRows, CuratedVariant, DecidedBy, DeviceAvailability, DeviceGraphics, DeviceHardware, DeviceModelFile, DeviceModelResolution, DeviceServedSettings, DiscoveryAmbiguity, DiscoveryArtifact, DiscoveryMedia, DiscoveryResult, DiscoveryRuntime, DiscoverySource, DiscoveryVariant, FeatureBucket, FeatureBucketMeta, FeatureKey, FitCapabilities, GgufHeader, GgufRead, GgufTensor, GroupedFeatures, HardwareClass, HardwareClasses, HeaderFlag, HeaderJudgement, HeaderRefusal, Interaction, InteractionMode, LocalArtifact, LocalCatalogClient, LocalCatalogQuery, LocalCompatRow, LocalModel, LocalModelCatalog, LocalPresentation, LocalRuntime, LocalRuntimeBuild, LocalVariant, Modality, ModelCapabilities, ModelCatalog, ModelCatalogChangePayload, ModelCatalogClient, ModelCatalogConfig, ModelCatalogDirectiveSubscribe, ModelCatalogErrorSink, ModelCatalogPgError, ModelCatalogPgResult, ModelCatalogQuery, ModelCatalogState, ModelCatalogVariant, ModelCatalogVariantState, ModelCatalogVisibilityOptions, ModelClassConfig, ModelClassEntry, ModelClassIndex, ModelDiagnosticEntry, ModelDiagnosticsSink, ModelFavorites, ModelFavoritesCache, ModelFavoritesClient, ModelFavoritesConfig, ModelFavoritesErrorSink, ModelFavoritesState, ModelFetchScope, ModelFileHandle, ModelFit, ModelIdentityRow, ModelJson, ModelLabelSource, ModelNeed, ModelOfferingRow, ModelOption, ModelOptionWithLifecycle, ModelRecord, ModelRecordFetchType, ModelRecords, ModelRecordsClient, ModelRecordsConfig, ModelRecordsState, ModelSelectionPurpose, ModelSetEnv, ModelSetFacts, ModelSetValidation, NewAgentModel, NoSelection, OrderedLike, PreferredModelChoice, PreferredModelChoicePorts, PriceTier, PricedCatalogModel, PublicModelClient, RankOptions, RankedVariant, ReadModelCatalogOptions, SelectDevice, Selection, ShardName, SuccessionClient, SuccessionIndex, SuccessionNode, VariantDiscovery, VariantVerdict, Want };
2136
+ export { CHAT_DEFAULT_MODEL_KNOB, CONTENT_TYPES, DEFAULT_CAPABILITIES, DEVICE_FILE_USABLE_STATES, DEVICE_OWN_FILE_USABLE_STATES, DEVICE_RULE_TWIN_FIXTURE, DEVICE_SERVED_SETTINGS_KEY, DEVICE_SERVED_VIA, DeviceModelUnavailableError, EMPTY_MODEL_RECORDS, EXCLUDED_REVIEW_STATES, FEATURE_BUCKETS, FEATURE_BUCKET_ORDER, FEATURE_KEYS, FILE_TYPE_QUANT, GgufError, INPUT_MODALITIES, INTERACTION_MODES, LLM_INTERACTIONS, MAX_SUCCESSION_HOPS, MODEL_CATALOG_KINDS, MODEL_FAVORITE_ENTITY_TYPE, NEW_AGENT_DEFAULT_MODEL_KNOB, OUTPUT_MODALITIES, SERVICE_LABEL, SERVICE_LABEL_PLURAL, TOP_TIER_COST_RATING, TOP_TIER_LOCKED_TITLE, UNKNOWN_MODEL_KIND, acceptsTextInstructions, announceModelCatalogChanged, availableOnDevices, blendedPrice, buildModelClassIndex, buildSuccessionIndex, catalogFingerprint, catalogForApp, catalogKeyColumn, catalogKindOf, catalogKindVerdict, cheapestAdequateModel, classConfigKey, coalesceModelCatalogChanges, collapseTiersByClass, costRatingTier, costRatingWord, createModelCatalog, createModelFavorites, createModelRecords, curatedList, displayOrderOf, favoriteIdsEqual, fetchCuratedModels, findNonCanonicalCapabilityValues, fitsMemory, fitsNeed, fitsThisComputer, followModelCatalogChanges, followModelCatalogVisibility, formatMemoryBytes, fromDiscovery, ggufEngine, ggufFacts, groupFeatures, hardwareClassesOf, hasCompatibleDecisionInteraction, isChatModelCapability, isContentType, isConversationalModelCapability, isDecisionModelCapability, isFeatureKey, isHelperGguf, isInteractionMode, isListedVariant, isLocalModelCatalog, isManagedAgentModelCapability, isModelCatalogChange, isProjectorName, isSupersedable, isTopTierRating, judgeHeaderFacts, mergeAuditRecordIntoCapabilities, missingShards, modelCatalogRevision, modelClassKnobFor, modelClassName, modelClassPinOf, modelDisplayLabel, modelsForSelectionPurpose, normalizeArch, normalizeModel, normalizeModels, normalizeOs, normalizePromptSettings, onModelCatalogChanged, orderCatalogGroups, orderCatalogModels, outputFormatControlKey, parseCapabilities, pickProjector, priceTierRating, quantFromName, rankVariants, readCuratedRows, readDeviceModelFiles, readGgufHeader, readModelCatalog, readModelCatalogStamp, readModelIdentities, readPublicModel, reconcileModelFavoriteIds, reportModelDiagnostic, requireCanonicalCapabilities, requiredArtifactIds, requiredArtifacts, resetSuccessionLogForTests, resolveDeviceModel, resolveLiveModelId, resolveModelMapKnob, resolveNewAgentModelId, resolvePreferredModelChoice, resolveSuccessor, runtimesOnEngine, seesImages, selectActiveModels, selectActiveModelsReady, selectAllModelOptions, selectAllModels, selectAllModelsReady, selectDeprecatedModels, selectDeprecatedModelsReady, selectModelById, selectModelClassConfig, selectModelClassName, selectModelControls, selectModelDetailError, selectModelFetchType, selectModelFullyLoaded, selectModelIdentityById, selectModelIdentityLookupStatus, selectModelLabelById, selectModelLabelWithClass, selectModelNameById, selectModelOptions, selectVariant, serviceCountLabel, setModelDiagnosticsSink, shapeCuratedModels, shardFileName, shardName, speedRatingLabel, speedRatingWord, splitSetProblems, takesInput, toAuditRecord, toDeviceModelFile, validateModelSet, variantVerdict, withModelClass };
2137
+ export type { AdminOffering, AdminPricingBand, ArtifactUse, AuditCapabilitiesRecord, AvailabilityVariant, CapabilitiesParseContext, CatalogKeyColumn, CatalogKindInput, CatalogKindVerdict, CatalogModel, CatalogTier, CheapestAdequateOptions, CompatStatus, ContentType, CuratedCatalogClient, CuratedModel, CuratedPresentation, CuratedRows, CuratedVariant, DecidedBy, DeviceAvailability, DeviceGraphics, DeviceHardware, DeviceModelFile, DeviceModelResolution, DeviceServedSettings, DiscoveryAmbiguity, DiscoveryArtifact, DiscoveryMedia, DiscoveryResult, DiscoveryRuntime, DiscoverySource, DiscoveryVariant, FeatureBucket, FeatureBucketMeta, FeatureKey, FitCapabilities, GgufHeader, GgufRead, GgufTensor, GroupedFeatures, HardwareClass, HardwareClasses, HeaderFlag, HeaderJudgement, HeaderRefusal, Interaction, InteractionMode, LocalArtifact, LocalCatalogClient, LocalCatalogQuery, LocalCompatRow, LocalModel, LocalModelCatalog, LocalPresentation, LocalRuntime, LocalRuntimeBuild, LocalVariant, Modality, ModelCapabilities, ModelCatalog, ModelCatalogChangeMeta, ModelCatalogChangePayload, ModelCatalogClient, ModelCatalogCoalesceOptions, ModelCatalogConfig, ModelCatalogDirectiveSubscribe, ModelCatalogErrorSink, ModelCatalogPgError, ModelCatalogPgResult, ModelCatalogQuery, ModelCatalogState, ModelCatalogVariant, ModelCatalogVariantState, ModelCatalogVisibilityOptions, ModelClassConfig, ModelClassEntry, ModelClassIndex, ModelDiagnosticEntry, ModelDiagnosticsSink, ModelFavorites, ModelFavoritesCache, ModelFavoritesClient, ModelFavoritesConfig, ModelFavoritesErrorSink, ModelFavoritesState, ModelFetchScope, ModelFileHandle, ModelFit, ModelIdentityRow, ModelJson, ModelLabelSource, ModelNeed, ModelOfferingRow, ModelOption, ModelOptionWithLifecycle, ModelRecord, ModelRecordFetchType, ModelRecords, ModelRecordsClient, ModelRecordsConfig, ModelRecordsState, ModelSelectionPurpose, ModelSetEnv, ModelSetFacts, ModelSetValidation, NewAgentModel, NoSelection, OrderedLike, PreferredModelChoice, PreferredModelChoicePorts, PriceTier, PricedCatalogModel, PublicModelClient, RankOptions, RankedVariant, ReadModelCatalogOptions, SelectDevice, Selection, ShardName, SuccessionClient, SuccessionIndex, SuccessionNode, VariantDiscovery, VariantVerdict, Want };
@@ -1764,6 +1764,11 @@ interface DeviceModelFile {
1764
1764
  artifact_id: string | null;
1765
1765
  state: string;
1766
1766
  organization_id: string | null;
1767
+ /**
1768
+ * The key the computer runs this file under (`metadata.model_key`, published by Matrx 2): for a person's own
1769
+ * file it is the run key the device's model service names it by. Null when not reported yet.
1770
+ */
1771
+ model_key: string | null;
1767
1772
  }
1768
1773
  declare function toDeviceModelFile(r: Row$1): DeviceModelFile;
1769
1774
  /**
@@ -2061,8 +2066,12 @@ declare function modelDisplayLabel(row: ModelLabelSource | null | undefined): st
2061
2066
 
2062
2067
  /** A `catalog_changed` payload: `{ catalog?: "models" | ..., change?, model_id? }`. */
2063
2068
  type ModelCatalogChangePayload = Record<string, unknown>;
2069
+ /** What the bus knew about one envelope besides its payload: its `requestId` (the server names one burst once). */
2070
+ type ModelCatalogChangeMeta = {
2071
+ requestId?: string | null;
2072
+ } | null | undefined;
2064
2073
  /** The bus client's subscribe call: `(action, handler) => unsubscribe` (the web's `registerDirectiveHandler`). */
2065
- type ModelCatalogDirectiveSubscribe = (action: "catalog_changed", handler: (payload: ModelCatalogChangePayload) => void) => () => void;
2074
+ type ModelCatalogDirectiveSubscribe = (action: "catalog_changed", handler: (payload: ModelCatalogChangePayload, meta?: ModelCatalogChangeMeta) => void) => () => void;
2066
2075
  /** Is this notice about the MODEL catalog? (`catalog` absent or `"models"`; the tool catalog shares the action.) */
2067
2076
  declare function isModelCatalogChange(payload: ModelCatalogChangePayload | null | undefined): boolean;
2068
2077
  /** Listen for model catalog changes. Returns the unsubscribe. */
@@ -2071,8 +2080,32 @@ declare function onModelCatalogChanged(listener: (payload: ModelCatalogChangePay
2071
2080
  declare function modelCatalogRevision(): number;
2072
2081
  /** Announce a model catalog change to every listener (a notice that is not about models is ignored). */
2073
2082
  declare function announceModelCatalogChanged(payload?: ModelCatalogChangePayload): void;
2074
- /** Bind the host's bus client: every `catalog_changed` it delivers reaches every model reader. Returns the unbind. */
2075
- declare function followModelCatalogChanges(subscribe: ModelCatalogDirectiveSubscribe): () => void;
2083
+ interface ModelCatalogCoalesceOptions {
2084
+ /** Envelopes within this many ms of the last delivery are the same burst. Default 1500. */
2085
+ windowMs?: number;
2086
+ /** How long a delivered `requestId` is remembered (a late replica's copy is dropped). Default 60 s. */
2087
+ rememberMs?: number;
2088
+ now?: () => number;
2089
+ setTimer?: (fn: () => void, ms: number) => unknown;
2090
+ clearTimer?: (handle: unknown) => void;
2091
+ }
2092
+ /**
2093
+ * Fold a burst of `catalog_changed` envelopes into ONE delivery. The server's replicas (and, before
2094
+ * 2026-10-24, a second relay ~4 s later) can put the same change on the bus several times; every copy used to
2095
+ * cost every open app a re-read. Rules: an envelope whose `requestId` was delivered within `rememberMs` is
2096
+ * dropped; the first envelope of a burst is delivered at once; within `windowMs` of that delivery a copy with
2097
+ * the same payload is dropped, and a DIFFERENT payload (another model, another kind of edit) is delivered
2098
+ * once when the window closes, so a real second change is never lost. Returns the feed; `feed.stop()` drops
2099
+ * a pending delivery.
2100
+ */
2101
+ declare function coalesceModelCatalogChanges(deliver: (payload: ModelCatalogChangePayload) => void, options?: ModelCatalogCoalesceOptions): ((payload: ModelCatalogChangePayload, meta?: ModelCatalogChangeMeta) => void) & {
2102
+ stop(): void;
2103
+ };
2104
+ /**
2105
+ * Bind the host's bus client: every `catalog_changed` it delivers reaches every model reader, a burst of
2106
+ * copies as ONE change (`coalesceModelCatalogChanges`). Returns the unbind.
2107
+ */
2108
+ declare function followModelCatalogChanges(subscribe: ModelCatalogDirectiveSubscribe, options?: ModelCatalogCoalesceOptions): () => void;
2076
2109
  interface ModelCatalogVisibilityOptions {
2077
2110
  /** The client the stamp is read with (supabase-js fits as is). */
2078
2111
  client: ModelRecordsClient;
@@ -2100,5 +2133,5 @@ interface ModelCatalogVisibilityOptions {
2100
2133
  */
2101
2134
  declare function followModelCatalogVisibility(options: ModelCatalogVisibilityOptions): () => void;
2102
2135
 
2103
- export { CHAT_DEFAULT_MODEL_KNOB, CONTENT_TYPES, DEFAULT_CAPABILITIES, DEVICE_FILE_USABLE_STATES, DEVICE_OWN_FILE_USABLE_STATES, DEVICE_RULE_TWIN_FIXTURE, DEVICE_SERVED_SETTINGS_KEY, DEVICE_SERVED_VIA, DeviceModelUnavailableError, EMPTY_MODEL_RECORDS, EXCLUDED_REVIEW_STATES, FEATURE_BUCKETS, FEATURE_BUCKET_ORDER, FEATURE_KEYS, FILE_TYPE_QUANT, GgufError, INPUT_MODALITIES, INTERACTION_MODES, LLM_INTERACTIONS, MAX_SUCCESSION_HOPS, MODEL_CATALOG_KINDS, MODEL_FAVORITE_ENTITY_TYPE, NEW_AGENT_DEFAULT_MODEL_KNOB, OUTPUT_MODALITIES, SERVICE_LABEL, SERVICE_LABEL_PLURAL, TOP_TIER_COST_RATING, TOP_TIER_LOCKED_TITLE, UNKNOWN_MODEL_KIND, acceptsTextInstructions, announceModelCatalogChanged, availableOnDevices, blendedPrice, buildModelClassIndex, buildSuccessionIndex, catalogFingerprint, catalogForApp, catalogKeyColumn, catalogKindOf, catalogKindVerdict, cheapestAdequateModel, classConfigKey, collapseTiersByClass, costRatingTier, costRatingWord, createModelCatalog, createModelFavorites, createModelRecords, curatedList, displayOrderOf, favoriteIdsEqual, fetchCuratedModels, findNonCanonicalCapabilityValues, fitsMemory, fitsNeed, fitsThisComputer, followModelCatalogChanges, followModelCatalogVisibility, formatMemoryBytes, fromDiscovery, ggufEngine, ggufFacts, groupFeatures, hardwareClassesOf, hasCompatibleDecisionInteraction, isChatModelCapability, isContentType, isConversationalModelCapability, isDecisionModelCapability, isFeatureKey, isHelperGguf, isInteractionMode, isListedVariant, isLocalModelCatalog, isManagedAgentModelCapability, isModelCatalogChange, isProjectorName, isSupersedable, isTopTierRating, judgeHeaderFacts, mergeAuditRecordIntoCapabilities, missingShards, modelCatalogRevision, modelClassKnobFor, modelClassName, modelClassPinOf, modelDisplayLabel, modelsForSelectionPurpose, normalizeArch, normalizeModel, normalizeModels, normalizeOs, normalizePromptSettings, onModelCatalogChanged, orderCatalogGroups, orderCatalogModels, outputFormatControlKey, parseCapabilities, pickProjector, priceTierRating, quantFromName, rankVariants, readCuratedRows, readDeviceModelFiles, readGgufHeader, readModelCatalog, readModelCatalogStamp, readModelIdentities, readPublicModel, reconcileModelFavoriteIds, reportModelDiagnostic, requireCanonicalCapabilities, requiredArtifactIds, requiredArtifacts, resetSuccessionLogForTests, resolveDeviceModel, resolveLiveModelId, resolveModelMapKnob, resolveNewAgentModelId, resolvePreferredModelChoice, resolveSuccessor, runtimesOnEngine, seesImages, selectActiveModels, selectActiveModelsReady, selectAllModelOptions, selectAllModels, selectAllModelsReady, selectDeprecatedModels, selectDeprecatedModelsReady, selectModelById, selectModelClassConfig, selectModelClassName, selectModelControls, selectModelDetailError, selectModelFetchType, selectModelFullyLoaded, selectModelIdentityById, selectModelIdentityLookupStatus, selectModelLabelById, selectModelLabelWithClass, selectModelNameById, selectModelOptions, selectVariant, serviceCountLabel, setModelDiagnosticsSink, shapeCuratedModels, shardFileName, shardName, speedRatingLabel, speedRatingWord, splitSetProblems, takesInput, toAuditRecord, toDeviceModelFile, validateModelSet, variantVerdict, withModelClass };
2104
- export type { AdminOffering, AdminPricingBand, ArtifactUse, AuditCapabilitiesRecord, AvailabilityVariant, CapabilitiesParseContext, CatalogKeyColumn, CatalogKindInput, CatalogKindVerdict, CatalogModel, CatalogTier, CheapestAdequateOptions, CompatStatus, ContentType, CuratedCatalogClient, CuratedModel, CuratedPresentation, CuratedRows, CuratedVariant, DecidedBy, DeviceAvailability, DeviceGraphics, DeviceHardware, DeviceModelFile, DeviceModelResolution, DeviceServedSettings, DiscoveryAmbiguity, DiscoveryArtifact, DiscoveryMedia, DiscoveryResult, DiscoveryRuntime, DiscoverySource, DiscoveryVariant, FeatureBucket, FeatureBucketMeta, FeatureKey, FitCapabilities, GgufHeader, GgufRead, GgufTensor, GroupedFeatures, HardwareClass, HardwareClasses, HeaderFlag, HeaderJudgement, HeaderRefusal, Interaction, InteractionMode, LocalArtifact, LocalCatalogClient, LocalCatalogQuery, LocalCompatRow, LocalModel, LocalModelCatalog, LocalPresentation, LocalRuntime, LocalRuntimeBuild, LocalVariant, Modality, ModelCapabilities, ModelCatalog, ModelCatalogChangePayload, ModelCatalogClient, ModelCatalogConfig, ModelCatalogDirectiveSubscribe, ModelCatalogErrorSink, ModelCatalogPgError, ModelCatalogPgResult, ModelCatalogQuery, ModelCatalogState, ModelCatalogVariant, ModelCatalogVariantState, ModelCatalogVisibilityOptions, ModelClassConfig, ModelClassEntry, ModelClassIndex, ModelDiagnosticEntry, ModelDiagnosticsSink, ModelFavorites, ModelFavoritesCache, ModelFavoritesClient, ModelFavoritesConfig, ModelFavoritesErrorSink, ModelFavoritesState, ModelFetchScope, ModelFileHandle, ModelFit, ModelIdentityRow, ModelJson, ModelLabelSource, ModelNeed, ModelOfferingRow, ModelOption, ModelOptionWithLifecycle, ModelRecord, ModelRecordFetchType, ModelRecords, ModelRecordsClient, ModelRecordsConfig, ModelRecordsState, ModelSelectionPurpose, ModelSetEnv, ModelSetFacts, ModelSetValidation, NewAgentModel, NoSelection, OrderedLike, PreferredModelChoice, PreferredModelChoicePorts, PriceTier, PricedCatalogModel, PublicModelClient, RankOptions, RankedVariant, ReadModelCatalogOptions, SelectDevice, Selection, ShardName, SuccessionClient, SuccessionIndex, SuccessionNode, VariantDiscovery, VariantVerdict, Want };
2136
+ export { CHAT_DEFAULT_MODEL_KNOB, CONTENT_TYPES, DEFAULT_CAPABILITIES, DEVICE_FILE_USABLE_STATES, DEVICE_OWN_FILE_USABLE_STATES, DEVICE_RULE_TWIN_FIXTURE, DEVICE_SERVED_SETTINGS_KEY, DEVICE_SERVED_VIA, DeviceModelUnavailableError, EMPTY_MODEL_RECORDS, EXCLUDED_REVIEW_STATES, FEATURE_BUCKETS, FEATURE_BUCKET_ORDER, FEATURE_KEYS, FILE_TYPE_QUANT, GgufError, INPUT_MODALITIES, INTERACTION_MODES, LLM_INTERACTIONS, MAX_SUCCESSION_HOPS, MODEL_CATALOG_KINDS, MODEL_FAVORITE_ENTITY_TYPE, NEW_AGENT_DEFAULT_MODEL_KNOB, OUTPUT_MODALITIES, SERVICE_LABEL, SERVICE_LABEL_PLURAL, TOP_TIER_COST_RATING, TOP_TIER_LOCKED_TITLE, UNKNOWN_MODEL_KIND, acceptsTextInstructions, announceModelCatalogChanged, availableOnDevices, blendedPrice, buildModelClassIndex, buildSuccessionIndex, catalogFingerprint, catalogForApp, catalogKeyColumn, catalogKindOf, catalogKindVerdict, cheapestAdequateModel, classConfigKey, coalesceModelCatalogChanges, collapseTiersByClass, costRatingTier, costRatingWord, createModelCatalog, createModelFavorites, createModelRecords, curatedList, displayOrderOf, favoriteIdsEqual, fetchCuratedModels, findNonCanonicalCapabilityValues, fitsMemory, fitsNeed, fitsThisComputer, followModelCatalogChanges, followModelCatalogVisibility, formatMemoryBytes, fromDiscovery, ggufEngine, ggufFacts, groupFeatures, hardwareClassesOf, hasCompatibleDecisionInteraction, isChatModelCapability, isContentType, isConversationalModelCapability, isDecisionModelCapability, isFeatureKey, isHelperGguf, isInteractionMode, isListedVariant, isLocalModelCatalog, isManagedAgentModelCapability, isModelCatalogChange, isProjectorName, isSupersedable, isTopTierRating, judgeHeaderFacts, mergeAuditRecordIntoCapabilities, missingShards, modelCatalogRevision, modelClassKnobFor, modelClassName, modelClassPinOf, modelDisplayLabel, modelsForSelectionPurpose, normalizeArch, normalizeModel, normalizeModels, normalizeOs, normalizePromptSettings, onModelCatalogChanged, orderCatalogGroups, orderCatalogModels, outputFormatControlKey, parseCapabilities, pickProjector, priceTierRating, quantFromName, rankVariants, readCuratedRows, readDeviceModelFiles, readGgufHeader, readModelCatalog, readModelCatalogStamp, readModelIdentities, readPublicModel, reconcileModelFavoriteIds, reportModelDiagnostic, requireCanonicalCapabilities, requiredArtifactIds, requiredArtifacts, resetSuccessionLogForTests, resolveDeviceModel, resolveLiveModelId, resolveModelMapKnob, resolveNewAgentModelId, resolvePreferredModelChoice, resolveSuccessor, runtimesOnEngine, seesImages, selectActiveModels, selectActiveModelsReady, selectAllModelOptions, selectAllModels, selectAllModelsReady, selectDeprecatedModels, selectDeprecatedModelsReady, selectModelById, selectModelClassConfig, selectModelClassName, selectModelControls, selectModelDetailError, selectModelFetchType, selectModelFullyLoaded, selectModelIdentityById, selectModelIdentityLookupStatus, selectModelLabelById, selectModelLabelWithClass, selectModelNameById, selectModelOptions, selectVariant, serviceCountLabel, setModelDiagnosticsSink, shapeCuratedModels, shardFileName, shardName, speedRatingLabel, speedRatingWord, splitSetProblems, takesInput, toAuditRecord, toDeviceModelFile, validateModelSet, variantVerdict, withModelClass };
2137
+ export type { AdminOffering, AdminPricingBand, ArtifactUse, AuditCapabilitiesRecord, AvailabilityVariant, CapabilitiesParseContext, CatalogKeyColumn, CatalogKindInput, CatalogKindVerdict, CatalogModel, CatalogTier, CheapestAdequateOptions, CompatStatus, ContentType, CuratedCatalogClient, CuratedModel, CuratedPresentation, CuratedRows, CuratedVariant, DecidedBy, DeviceAvailability, DeviceGraphics, DeviceHardware, DeviceModelFile, DeviceModelResolution, DeviceServedSettings, DiscoveryAmbiguity, DiscoveryArtifact, DiscoveryMedia, DiscoveryResult, DiscoveryRuntime, DiscoverySource, DiscoveryVariant, FeatureBucket, FeatureBucketMeta, FeatureKey, FitCapabilities, GgufHeader, GgufRead, GgufTensor, GroupedFeatures, HardwareClass, HardwareClasses, HeaderFlag, HeaderJudgement, HeaderRefusal, Interaction, InteractionMode, LocalArtifact, LocalCatalogClient, LocalCatalogQuery, LocalCompatRow, LocalModel, LocalModelCatalog, LocalPresentation, LocalRuntime, LocalRuntimeBuild, LocalVariant, Modality, ModelCapabilities, ModelCatalog, ModelCatalogChangeMeta, ModelCatalogChangePayload, ModelCatalogClient, ModelCatalogCoalesceOptions, ModelCatalogConfig, ModelCatalogDirectiveSubscribe, ModelCatalogErrorSink, ModelCatalogPgError, ModelCatalogPgResult, ModelCatalogQuery, ModelCatalogState, ModelCatalogVariant, ModelCatalogVariantState, ModelCatalogVisibilityOptions, ModelClassConfig, ModelClassEntry, ModelClassIndex, ModelDiagnosticEntry, ModelDiagnosticsSink, ModelFavorites, ModelFavoritesCache, ModelFavoritesClient, ModelFavoritesConfig, ModelFavoritesErrorSink, ModelFavoritesState, ModelFetchScope, ModelFileHandle, ModelFit, ModelIdentityRow, ModelJson, ModelLabelSource, ModelNeed, ModelOfferingRow, ModelOption, ModelOptionWithLifecycle, ModelRecord, ModelRecordFetchType, ModelRecords, ModelRecordsClient, ModelRecordsConfig, ModelRecordsState, ModelSelectionPurpose, ModelSetEnv, ModelSetFacts, ModelSetValidation, NewAgentModel, NoSelection, OrderedLike, PreferredModelChoice, PreferredModelChoicePorts, PriceTier, PricedCatalogModel, PublicModelClient, RankOptions, RankedVariant, ReadModelCatalogOptions, SelectDevice, Selection, ShardName, SuccessionClient, SuccessionIndex, SuccessionNode, VariantDiscovery, VariantVerdict, Want };
@@ -1391,8 +1391,64 @@ function announceModelCatalogChanged(payload = {}) {
1391
1391
  }
1392
1392
  }
1393
1393
  }
1394
- function followModelCatalogChanges(subscribe) {
1395
- return subscribe("catalog_changed", (payload) => announceModelCatalogChanged(payload ?? {}));
1394
+ var contentKey = (payload) => JSON.stringify(
1395
+ Object.keys({ catalog: "models", ...payload }).sort().map((k) => [k, k === "catalog" ? payload[k] ?? "models" : payload[k] ?? null]).filter(([, v]) => v !== null)
1396
+ );
1397
+ function coalesceModelCatalogChanges(deliver, options = {}) {
1398
+ const windowMs = options.windowMs ?? 1500;
1399
+ const rememberMs = options.rememberMs ?? 6e4;
1400
+ const now = options.now ?? (() => Date.now());
1401
+ const setTimer = options.setTimer ?? ((fn, ms) => setTimeout(fn, ms));
1402
+ const clearTimer = options.clearTimer ?? ((h) => clearTimeout(h));
1403
+ const seenIds = /* @__PURE__ */ new Map();
1404
+ let windowStart = -Infinity;
1405
+ let windowKeys = /* @__PURE__ */ new Set();
1406
+ let pending = null;
1407
+ let timer = null;
1408
+ const open = (payload, at) => {
1409
+ windowStart = at;
1410
+ windowKeys = /* @__PURE__ */ new Set([contentKey(payload)]);
1411
+ deliver(payload);
1412
+ };
1413
+ const feed = (payload, meta) => {
1414
+ const p = payload ?? {};
1415
+ const t = now();
1416
+ for (const [id2, at] of seenIds) if (t - at > rememberMs) seenIds.delete(id2);
1417
+ const id = typeof meta?.requestId === "string" && meta.requestId ? meta.requestId : null;
1418
+ if (id !== null) {
1419
+ if (seenIds.has(id)) return;
1420
+ seenIds.set(id, t);
1421
+ }
1422
+ if (t - windowStart >= windowMs) return open(p, t);
1423
+ const key = contentKey(p);
1424
+ if (windowKeys.has(key)) return;
1425
+ windowKeys.add(key);
1426
+ pending = p;
1427
+ timer ??= setTimer(() => {
1428
+ timer = null;
1429
+ const next = pending;
1430
+ pending = null;
1431
+ if (next) open(next, now());
1432
+ }, Math.max(0, windowStart + windowMs - t));
1433
+ };
1434
+ return Object.assign(feed, {
1435
+ stop() {
1436
+ if (timer !== null) clearTimer(timer);
1437
+ timer = null;
1438
+ pending = null;
1439
+ }
1440
+ });
1441
+ }
1442
+ function followModelCatalogChanges(subscribe, options) {
1443
+ const feed = coalesceModelCatalogChanges((payload) => announceModelCatalogChanged(payload), options);
1444
+ const off = subscribe("catalog_changed", (payload, meta) => {
1445
+ if (!isModelCatalogChange(payload ?? {})) return;
1446
+ feed(payload ?? {}, meta);
1447
+ });
1448
+ return () => {
1449
+ feed.stop();
1450
+ off();
1451
+ };
1396
1452
  }
1397
1453
  function followModelCatalogVisibility(options) {
1398
1454
  const page = options.page ?? (typeof document !== "undefined" && typeof window !== "undefined" ? { document, window } : null);
@@ -2648,7 +2704,8 @@ function toDeviceModelFile(r) {
2648
2704
  sha256: sn2(r.sha256),
2649
2705
  artifact_id: sn2(r.artifact_id),
2650
2706
  state: s2(r.state),
2651
- organization_id: sn2(r.organization_id)
2707
+ organization_id: sn2(r.organization_id),
2708
+ model_key: sn2(r.metadata?.model_key)
2652
2709
  };
2653
2710
  }
2654
2711
  async function readDeviceModelFiles(client, opts = {}) {
@@ -3094,6 +3151,7 @@ export {
3094
3151
  catalogKindVerdict,
3095
3152
  cheapestAdequateModel,
3096
3153
  classConfigKey,
3154
+ coalesceModelCatalogChanges,
3097
3155
  collapseTiersByClass,
3098
3156
  costRatingTier,
3099
3157
  costRatingWord,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ai-matrx/agents",
3
- "version": "0.59.272",
3
+ "version": "0.59.274",
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",
@@ -520,5 +520,5 @@
520
520
  "optional": true
521
521
  }
522
522
  },
523
- "gitHead": "467bc8f11239e00d4bcd8d27c85861b0165cd0bd"
523
+ "gitHead": "6393a0ff9a690870c61c5c757c4ffe0b066e73df"
524
524
  }