@ai-matrx/agents 0.59.273 → 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,9 +1,18 @@
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
+
3
12
  ## 0.59.273
4
13
 
5
- UNVERIFIED: this release has no Unreleased entry and the source comparison could not be made (the caller supplied no source comparison). Whether source changed is unknown; consumer action is unknown.
6
- Check the package's gitHead on npm against this version's gitHead: `git diff <previous gitHead> <this gitHead> -- apps/shared/matrx-agents/src`.
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.
7
16
 
8
17
  ## 0.59.272
9
18
 
@@ -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);
@@ -2066,8 +2066,12 @@ declare function modelDisplayLabel(row: ModelLabelSource | null | undefined): st
2066
2066
 
2067
2067
  /** A `catalog_changed` payload: `{ catalog?: "models" | ..., change?, model_id? }`. */
2068
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;
2069
2073
  /** The bus client's subscribe call: `(action, handler) => unsubscribe` (the web's `registerDirectiveHandler`). */
2070
- type ModelCatalogDirectiveSubscribe = (action: "catalog_changed", handler: (payload: ModelCatalogChangePayload) => void) => () => void;
2074
+ type ModelCatalogDirectiveSubscribe = (action: "catalog_changed", handler: (payload: ModelCatalogChangePayload, meta?: ModelCatalogChangeMeta) => void) => () => void;
2071
2075
  /** Is this notice about the MODEL catalog? (`catalog` absent or `"models"`; the tool catalog shares the action.) */
2072
2076
  declare function isModelCatalogChange(payload: ModelCatalogChangePayload | null | undefined): boolean;
2073
2077
  /** Listen for model catalog changes. Returns the unsubscribe. */
@@ -2076,8 +2080,32 @@ declare function onModelCatalogChanged(listener: (payload: ModelCatalogChangePay
2076
2080
  declare function modelCatalogRevision(): number;
2077
2081
  /** Announce a model catalog change to every listener (a notice that is not about models is ignored). */
2078
2082
  declare function announceModelCatalogChanged(payload?: ModelCatalogChangePayload): void;
2079
- /** Bind the host's bus client: every `catalog_changed` it delivers reaches every model reader. Returns the unbind. */
2080
- 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;
2081
2109
  interface ModelCatalogVisibilityOptions {
2082
2110
  /** The client the stamp is read with (supabase-js fits as is). */
2083
2111
  client: ModelRecordsClient;
@@ -2105,5 +2133,5 @@ interface ModelCatalogVisibilityOptions {
2105
2133
  */
2106
2134
  declare function followModelCatalogVisibility(options: ModelCatalogVisibilityOptions): () => void;
2107
2135
 
2108
- 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 };
2109
- 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 };
@@ -2066,8 +2066,12 @@ declare function modelDisplayLabel(row: ModelLabelSource | null | undefined): st
2066
2066
 
2067
2067
  /** A `catalog_changed` payload: `{ catalog?: "models" | ..., change?, model_id? }`. */
2068
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;
2069
2073
  /** The bus client's subscribe call: `(action, handler) => unsubscribe` (the web's `registerDirectiveHandler`). */
2070
- type ModelCatalogDirectiveSubscribe = (action: "catalog_changed", handler: (payload: ModelCatalogChangePayload) => void) => () => void;
2074
+ type ModelCatalogDirectiveSubscribe = (action: "catalog_changed", handler: (payload: ModelCatalogChangePayload, meta?: ModelCatalogChangeMeta) => void) => () => void;
2071
2075
  /** Is this notice about the MODEL catalog? (`catalog` absent or `"models"`; the tool catalog shares the action.) */
2072
2076
  declare function isModelCatalogChange(payload: ModelCatalogChangePayload | null | undefined): boolean;
2073
2077
  /** Listen for model catalog changes. Returns the unsubscribe. */
@@ -2076,8 +2080,32 @@ declare function onModelCatalogChanged(listener: (payload: ModelCatalogChangePay
2076
2080
  declare function modelCatalogRevision(): number;
2077
2081
  /** Announce a model catalog change to every listener (a notice that is not about models is ignored). */
2078
2082
  declare function announceModelCatalogChanged(payload?: ModelCatalogChangePayload): void;
2079
- /** Bind the host's bus client: every `catalog_changed` it delivers reaches every model reader. Returns the unbind. */
2080
- 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;
2081
2109
  interface ModelCatalogVisibilityOptions {
2082
2110
  /** The client the stamp is read with (supabase-js fits as is). */
2083
2111
  client: ModelRecordsClient;
@@ -2105,5 +2133,5 @@ interface ModelCatalogVisibilityOptions {
2105
2133
  */
2106
2134
  declare function followModelCatalogVisibility(options: ModelCatalogVisibilityOptions): () => void;
2107
2135
 
2108
- 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 };
2109
- 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);
@@ -3095,6 +3151,7 @@ export {
3095
3151
  catalogKindVerdict,
3096
3152
  cheapestAdequateModel,
3097
3153
  classConfigKey,
3154
+ coalesceModelCatalogChanges,
3098
3155
  collapseTiersByClass,
3099
3156
  costRatingTier,
3100
3157
  costRatingWord,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ai-matrx/agents",
3
- "version": "0.59.273",
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": "757401d3d21eefd180f94f290b796b53904b8c15"
523
+ "gitHead": "6393a0ff9a690870c61c5c757c4ffe0b066e73df"
524
524
  }