@anuma/sdk 6.39.2 → 6.40.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.
@@ -2592,12 +2592,10 @@ type StreamingTransportOptions = {
2592
2592
  inferenceId: string;
2593
2593
  }) => void;
2594
2594
  /**
2595
- * Fires whenever bytes arrive on the wire — data frames AND the keep-alive
2596
- * comment lines (`: ...`) the SSE parser otherwise discards. A pure liveness
2597
- * signal: a consumer running an idle watchdog uses it to tell a slow-but-alive
2598
- * stream (the server still heart-beating through a long reasoning silence)
2599
- * apart from a dead connection (no bytes at all). Not every transport emits it
2600
- * — the xhr transport does; treat its absence as "no extra liveness info".
2595
+ * Fires when the transport receives bytes, including SSE keep-alive comments.
2596
+ * Consumers can use this callback to reset the idle timeout.
2597
+ * The fetch and XHR transports emit it.
2598
+ * Custom transports can omit it if they cannot report byte activity.
2601
2599
  */
2602
2600
  onActivity?: () => void;
2603
2601
  };
@@ -6502,13 +6500,33 @@ interface MemorySubscribeOptions {
6502
6500
  * from the main interface.
6503
6501
  * @public
6504
6502
  */
6505
- interface MemoryMaintenance {
6503
+ interface MemoryMaintenance extends MemoryTopicMaintenance {
6506
6504
  /** Decay sweeper bound to this store's vault (see `createDecaySweeper`). */
6507
6505
  createDecaySweeper(options?: Omit<CreateDecaySweeperOptions, "vaultCtx">): DecaySweeper;
6508
6506
  /** One page of the topic-extraction backlog (see `getMemoriesNeedingTopicExtractionOp`). */
6509
6507
  getTopicBacklog(options?: {
6510
6508
  limit?: number;
6511
6509
  }): Promise<MemoriesNeedingTopicExtraction>;
6510
+ }
6511
+ /** @public */
6512
+ interface MemoryTopicBacklog {
6513
+ pending: readonly {
6514
+ uniqueId: string;
6515
+ }[];
6516
+ linkedUnstamped: readonly string[];
6517
+ topicsToRelink: readonly string[];
6518
+ topicsBackfill: readonly string[];
6519
+ }
6520
+ /**
6521
+ * Topic-extraction upkeep for either backend. On a remote store `pending` carries ids only, the
6522
+ * other backlog lists are always empty, and `relinkTopics` / `backfillTopics` do nothing.
6523
+ * @public
6524
+ */
6525
+ interface MemoryTopicMaintenance {
6526
+ /** One page of the topic-extraction backlog, edited or outdated rows first. */
6527
+ getTopicBacklog(options?: {
6528
+ limit?: number;
6529
+ }): Promise<MemoryTopicBacklog>;
6512
6530
  /** LLM topic extraction + link + stamp for these memories. */
6513
6531
  extractTopics(memoryIds: readonly string[], options: TopicExtractOptions & {
6514
6532
  now?: number;
@@ -6585,6 +6603,8 @@ interface MemoryStore {
6585
6603
  subscribe(onChange: () => void, options?: MemorySubscribeOptions): () => void;
6586
6604
  /** TRANSITIONAL — see {@link MemoryMaintenance}. Absent on a remote backend. */
6587
6605
  maintenance?: MemoryMaintenance;
6606
+ /** Topic-extraction upkeep, available on every backend. */
6607
+ readonly topicMaintenance: MemoryTopicMaintenance;
6588
6608
  }
6589
6609
 
6590
6610
  /**
@@ -11278,4 +11298,4 @@ interface UseChatStorageResult extends BaseUseChatStorageResult {
11278
11298
  */
11279
11299
  declare function useChatStorage(options: UseChatStorageOptions): UseChatStorageResult;
11280
11300
 
11281
- export { type AutoExtractMessage, type AutoExtractor, type Budget, CHUNKS_DISCARDED_ORIGIN, type CachedChunkVectors, type CachedServerTools, Conversation as ChatConversation, Message as ChatMessage, type ChatRole, type ChunkVectorCache, type ChunkingOptions, type ConsolidationAction, type ConsolidationFallbackReason, type ConversationMemoryInput, ConversationMemory as ConversationMemoryModel, type ConversationMemoryOperationsContext, type CreateAutoExtractorOptions, type CreateConversationOptions, type CreateDecaySweeperOptions, type CreateMessageOptions, type CreateVaultFolderOptions, type CreateVaultMemoryOptions, type CryptoPriceClassification, type CryptoPricePreProcessorOptions, DEFAULT_CACHE_EXPIRATION_MS, DEFAULT_CHUNK_CACHE_SIZE, DEFAULT_CHUNK_OVERLAP, DEFAULT_CHUNK_SIZE, DEFAULT_DECAY_POLICY, DEFAULT_MAX_CLASSIFIER_CALLS_PER_SWEEP, DEFAULT_MIN_CHUNK_SIZE, DEFAULT_PROFILE_FACETS, DEFAULT_PROFILE_FACT_TYPE_WEIGHTS, DEFAULT_PROFILE_PROOF_ALPHA, DEFAULT_PROFILE_TREND_MULTIPLIERS, DEFAULT_VAULT_CACHE_SIZE, DatabaseManager, type DatabaseManagerLogger, type DatabaseManagerOptions, type DecayCandidateRaw, type DecayClassifier, type DecayInput, type DecayPolicy, type DecaySweepResult, type DecaySweeper, type DecayVerdict, type DurableAutoExtractorOptions, ENTITY_FANOUT, type EmbeddedWalletSignerFn, EncryptionKeyMissingError, type ExtractFactsOptions, type ExtractOutcome, type ExtractedCandidate, type ExtractedEntity, type ExtractionCursorStore, type ExtractionFunnel, type ExtractionTimings, type FactType, type FileMetadata, type FileProcessingReason, type FileProcessingStatus, type FlushResult, type GetConversationsPageOptions, type GetMessagesPageOptions, type GraphTraversalOptions, HARD_DELETE_WINDOW_MS, INFERENCE_ID_HEADER, type InjectionClassifierOptions, type InjectionReason, type LazyStoredConversation, type LlmDecayClassifierOptions, type LlmNeighborRefinerOptions, type LocalMemoryStoreOptions, type Logger, LoggerProvider, type LoggerProviderProps, MAX_HOPS, MEDIUM_TTL_MS, MEMORY_KINDS, MEMORY_LEVELS, type ManualFactType, type MemoriesNeedingTopicExtraction, type MemoryContextItem, type MemoryContextLane, type MemoryContextOptions, type MemoryContextResult, type MemoryCreate, type EmbeddingOptions as MemoryEngineEmbeddingOptions, type MemoryEngineResult, type MemoryEngineSearchOptions, type MemoryExtractedEvent, MemoryKeyError, type MemoryKeyRing, type MemoryKind, type MemoryLevel, MemoryLevelError, type MemoryListOptions, type MemoryMaintenance, type MemoryQuarantinedEvent, type MemoryRecallOptions, type MemoryRetainOptions, type MemoryStore, type MemorySubscribeOptions, type MemoryToVerify, type MemoryTopic, type MemoryUpdate, type MemoryVaultSearchOptions, type MemoryVaultToolOptions, type MemoryVerification, type MessageRedactionResult, type MessageSkeleton, NEVER_TTL_MS, NODE_BUDGET, NOTION_OAUTH_CONFIG, type NeighborRefiner, type NotionAuthUrlParams, type NotionClientRegistration, type NotionExchangeCodeParams, type NotionMcpCaller, type NotionOAuthEndpoints, type NotionPKCEChallenge, type NotionRefreshTokenParams, type NotionTokenResponse, type NowSource, type ObservationTrend, type ObservationTrendInput, PAST_EVENT_GRACE_MS, PII_PATTERNS, PROFILE_DOC_VERSION, type PhotoIngestResult, type PhotoMediaRef, type PiiCategory, type PiiMatch, type PiiPattern, PiiRedactor, type PiiRedactorOptions, type PlatformStorage, type PortalLlmAuth, type PortalLlmFailure, type PortalLlmFailureReason, type ProfileConfigFingerprint, type ProfileDoc, type ProfileFacet, type ProfileFacetKey, type ProfileSalienceInput, type ProfileSection, type PromptPreProcessor, type PromptPreProcessorContext, type PublishedPhotoMemory, type QuantizedEmbedding, type QuarantinedMemoryInfo, QueueManager, type QueueStatus, RECALL_MAX_LIMIT, RECALL_TOOL_NAME, type RankableVaultMemory, type RankedMemory, type RankedProfileCandidate, type RecallContext, type RecallDegradation, type RecallDiagnostics, type RecallEmptyReason, type RecallOptions, type RecallResult, type RecallToolCallbacks, type RecallToolOptions, type RecencyOptions, type RedactionResult, type ReflectOptions, type ReflectResult, type RemoteMemoryCandidateOptions, type RemoteMemoryDecodeFailure, RemoteMemoryError, type RemoteMemoryListOptions, type RemoteMemoryMetadataPage, type RemoteMemoryMetadataRecord, type RemoteMemoryPage, RemoteMemoryPartialCreateError, type RemoteMemoryPersistence, type RemoteMemoryPersistenceOptions, type RemoteMemoryPipeline, type RemoteMemoryPipelineOptions, type RemoteMemoryQueryOptions, type RemoteMemoryQueryPage, type RemoteMemoryReadFilters, type RemoteMemoryRecord, type RemoteMemoryRow, type RemoteMemoryStoreOptions, type RequestEncryptionKeyOptions, RerankerUnavailableError, type ReservationReceipt, type ResumeStreamOptions, type ResumeStreamResult, type ResumeStreamWithStorageResult, type RetainAction, type RetainContext, type RetainOptions, type RetainResult, type RetainSource, SDK_SCHEMA_VERSION, SHORT_TTL_MS, STREAM_RESUMABLE_HEADER, type ScoreBreakdown, type ScoreProfileSalienceOptions, type ScreenResult, type ScreenedCandidate, type SearchSource, type SendMessageWithStorageArgs, type SendMessageWithStorageDetachedResult, type SendMessageWithStorageResult, type ServerToolsOptions, type ServerToolsResponse, type SignMessageFn, type StockPriceClassification, type StockPricePreProcessorOptions, type ChatCompletionUsage as StoredChatCompletionUsage, type StoredConversation, type StoredConversationMemory, type StoredMessage, type StoredMessageWithSimilarity, type StoredVaultFolder, VaultFolder as StoredVaultFolderModel, type StoredVaultMemory, VaultMemory as StoredVaultMemoryModel, StreamExpiredError, type StreamMetaEvent, type StreamResumeHandle, type StreamSmoothingConfig, type SynthesizeProfileOptions, TOOL_RESULT_ORIGIN, TOPICS_EXTRACTION_VERSION, TOPIC_EXTRACTION_BATCH_SIZE, TREND_RECENT_WINDOW_DAYS, TREND_STALE_WINDOW_DAYS, type TextChunk, type TopicExtractOptions, type TopicExtractionInput, type TopicExtractionRunResult, type TopicSkipReason, type TurnCompleteEvent, type TurnSkippedEvent, type UncheckedReason, type UnverifiableReason, type UpdateVaultFolderOptions, type UpdateVaultMemoryOptions, type UseChatStorageOptions, type UseChatStorageResult, type UseCreditsOptions, type UseCreditsResult, type UseModelsOptions, type UseModelsResult, VAULT_SIZE_HOP_CAP, type VaultEmbeddingCache, type VaultEmbeddingExpectation, type VaultFolderOperationsContext, type VaultMemoryKind, type VaultMemoryOperationsContext, type VaultMemoryProjection, type VaultMemoryVisibility, type VaultMemoryWriter, type VaultSaveOperation, type VaultSearchResult, type VaultWriteAction, type VaultWriteInput, type VaultWriteOutcome, type VerificationSources, type VerifyMemoriesForPublishOptions, WalletPoller, type WeatherClassification, type WeatherPreProcessorOptions, type WebSearchClassification, type WebSearchPreProcessorOptions, addConversationMemoriesOp, archiveVaultMemoryOp, assembleMemoryContext, attachFileContextToLastUserMessage, backfillMemoryTopicsOp, buildAttachedFilesText, buildNotionAuthUrl, capHopsForDensity, chatStorageMigrations, chatStorageSchema, chunkAndEmbedAllMessages, chunkAndEmbedMessage, chunkText, classifyCryptoPrice, classifyCryptoPriceBatch, classifyDecay, classifyInjectionCandidates, classifyObservationTrend, classifyStockPrice, classifyStockPriceBatch, classifyWeather, classifyWeatherBatch, classifyWebSearch, classifyWebSearchBatch, clearAllEncryptionKeys, clearAllEncryptionState, clearConversationMemoriesOp, clearEncryptionKey, clearLazyTitleCache, clearModelsCache, clearServerToolsCache, consoleLogger, conversationMemoryToStored, cosineInt8, createAutoExtractor, createChunkVectorCache, createCryptoPricePreProcessor, createDecaySweeper, createDurableAutoExtractor, createLlmDecayClassifier, createLlmNeighborRefiner, createLocalMemoryStore, createMemoryEngineTool, createMemoryVaultSearchTool, createMemoryVaultTool, createMessageSourceResolver, createNotionProxyTools, createNotionTools, createPlatformCursorStore, createRecallTool, createRemoteMemoryPersistence, createRemoteMemoryPipeline, createRemoteMemoryStore, createStockPricePreProcessor, createStreamingDeAnonymizer, createVaultEmbeddingCache, createVaultFolderOp, createVaultMemoriesBatchOp, createVaultMemoryOp, createWeatherPreProcessor, createWebSearchPreProcessor, decodeChunkVector, decryptConversationTitle, deleteAllVaultMemoriesForUserOp, deleteMessageOp, deleteVaultFolderOp, deleteVaultMemoryOp, dequantizeEmbedding, deriveKeyFromSignatureBytes, deriveMemoryKeyRing, discoverNotionOAuthEndpoints, eagerEmbedContent, embedAllMessages, embedMessage, encodeChunkVector, ensureDefaultFoldersOp, exchangeNotionCode, extractAndLinkEntitiesForMemoriesOp, extractAndRetain, extractEntitiesForMemories, extractFacts, extractReservationReceipts, formatFileProcessingNotes, generateConversationId, generateEmbedding, generateEmbeddings, generateNotionPKCE, getAllVaultFoldersOp, getAllVaultMemoriesOp, getAllVaultMemoryContentsOp, getCachedServerTools, getConversationMemoriesOp, getConversationsByProjectLazyOp, getConversationsLazyOp, getConversationsPageOp, getDecayCandidatesRawOp, getLogger, getMemoriesNeedingTopicExtractionOp, getServerTools, getUnfiledVaultMemoriesOp, getVaultFolderMemoryCountOp, getVaultMemoriesByIdsOp, getVaultMemoryOp, getVaultRankingProjectionsOp, hardDeleteDecayedOp, hasEncryptionKey, ingestPublishedPhotoMemoriesOp, injectionSignatureCatalog, isAttachedFilesText, isDegradedTopicSkip, isEncrypted, isPiiRedactor, isRerankerAvailable, maskScopedEmbeddingCache, memoryCipher, moveMemoriesToFolderOp, noopLogger, onKeyAvailable, parseMedia, preEmbedVaultMemories, quantizeEmbedding, queueManager, rankProfileCandidates, recall, reencryptMemoryField, reflect, refreshEncryptionKeyIfMatches, refreshNotionAccessToken, registerNotionClient, relinkMemoryTopicsOp, requestEncryptionKey, resolvePiiRedactor, restoreVaultMemoryOp, resumeStream, retain, scoreProfileSalience, screenCandidatesForInjection, sdkMigrations, sdkModelClasses, sdkSchema, searchVaultMemories, seedEncryptionKeys, setLogger, setMemoryVisibilityOp, shouldChunkMessage, shouldRecallMemory, stampTopicsExtractedAtOp, streamCancelPath, streamReplayPath, stripLegacyChunkTextOp, summarizeObservationTrends, supersedeVaultMemoryOp, synthesizeProfile, traverseGraphLane, ttlForType, updateVaultFolderContextOp, updateVaultFolderOp, updateVaultMemoryEmbeddingOp, updateVaultMemoryOp, upsertMessageOp, useChat, useChatStorage, useCredits, useEncryption, useModels, verifyMemoriesForPublish, xhrTransport };
11301
+ export { type AutoExtractMessage, type AutoExtractor, type Budget, CHUNKS_DISCARDED_ORIGIN, type CachedChunkVectors, type CachedServerTools, Conversation as ChatConversation, Message as ChatMessage, type ChatRole, type ChunkVectorCache, type ChunkingOptions, type ConsolidationAction, type ConsolidationFallbackReason, type ConversationMemoryInput, ConversationMemory as ConversationMemoryModel, type ConversationMemoryOperationsContext, type CreateAutoExtractorOptions, type CreateConversationOptions, type CreateDecaySweeperOptions, type CreateMessageOptions, type CreateVaultFolderOptions, type CreateVaultMemoryOptions, type CryptoPriceClassification, type CryptoPricePreProcessorOptions, DEFAULT_CACHE_EXPIRATION_MS, DEFAULT_CHUNK_CACHE_SIZE, DEFAULT_CHUNK_OVERLAP, DEFAULT_CHUNK_SIZE, DEFAULT_DECAY_POLICY, DEFAULT_MAX_CLASSIFIER_CALLS_PER_SWEEP, DEFAULT_MIN_CHUNK_SIZE, DEFAULT_PROFILE_FACETS, DEFAULT_PROFILE_FACT_TYPE_WEIGHTS, DEFAULT_PROFILE_PROOF_ALPHA, DEFAULT_PROFILE_TREND_MULTIPLIERS, DEFAULT_VAULT_CACHE_SIZE, DatabaseManager, type DatabaseManagerLogger, type DatabaseManagerOptions, type DecayCandidateRaw, type DecayClassifier, type DecayInput, type DecayPolicy, type DecaySweepResult, type DecaySweeper, type DecayVerdict, type DurableAutoExtractorOptions, ENTITY_FANOUT, type EmbeddedWalletSignerFn, EncryptionKeyMissingError, type ExtractFactsOptions, type ExtractOutcome, type ExtractedCandidate, type ExtractedEntity, type ExtractionCursorStore, type ExtractionFunnel, type ExtractionTimings, type FactType, type FileMetadata, type FileProcessingReason, type FileProcessingStatus, type FlushResult, type GetConversationsPageOptions, type GetMessagesPageOptions, type GraphTraversalOptions, HARD_DELETE_WINDOW_MS, INFERENCE_ID_HEADER, type InjectionClassifierOptions, type InjectionReason, type LazyStoredConversation, type LlmDecayClassifierOptions, type LlmNeighborRefinerOptions, type LocalMemoryStoreOptions, type Logger, LoggerProvider, type LoggerProviderProps, MAX_HOPS, MEDIUM_TTL_MS, MEMORY_KINDS, MEMORY_LEVELS, type ManualFactType, type MemoriesNeedingTopicExtraction, type MemoryContextItem, type MemoryContextLane, type MemoryContextOptions, type MemoryContextResult, type MemoryCreate, type EmbeddingOptions as MemoryEngineEmbeddingOptions, type MemoryEngineResult, type MemoryEngineSearchOptions, type MemoryExtractedEvent, MemoryKeyError, type MemoryKeyRing, type MemoryKind, type MemoryLevel, MemoryLevelError, type MemoryListOptions, type MemoryMaintenance, type MemoryQuarantinedEvent, type MemoryRecallOptions, type MemoryRetainOptions, type MemoryStore, type MemorySubscribeOptions, type MemoryToVerify, type MemoryTopic, type MemoryTopicBacklog, type MemoryTopicMaintenance, type MemoryUpdate, type MemoryVaultSearchOptions, type MemoryVaultToolOptions, type MemoryVerification, type MessageRedactionResult, type MessageSkeleton, NEVER_TTL_MS, NODE_BUDGET, NOTION_OAUTH_CONFIG, type NeighborRefiner, type NotionAuthUrlParams, type NotionClientRegistration, type NotionExchangeCodeParams, type NotionMcpCaller, type NotionOAuthEndpoints, type NotionPKCEChallenge, type NotionRefreshTokenParams, type NotionTokenResponse, type NowSource, type ObservationTrend, type ObservationTrendInput, PAST_EVENT_GRACE_MS, PII_PATTERNS, PROFILE_DOC_VERSION, type PhotoIngestResult, type PhotoMediaRef, type PiiCategory, type PiiMatch, type PiiPattern, PiiRedactor, type PiiRedactorOptions, type PlatformStorage, type PortalLlmAuth, type PortalLlmFailure, type PortalLlmFailureReason, type ProfileConfigFingerprint, type ProfileDoc, type ProfileFacet, type ProfileFacetKey, type ProfileSalienceInput, type ProfileSection, type PromptPreProcessor, type PromptPreProcessorContext, type PublishedPhotoMemory, type QuantizedEmbedding, type QuarantinedMemoryInfo, QueueManager, type QueueStatus, RECALL_MAX_LIMIT, RECALL_TOOL_NAME, type RankableVaultMemory, type RankedMemory, type RankedProfileCandidate, type RecallContext, type RecallDegradation, type RecallDiagnostics, type RecallEmptyReason, type RecallOptions, type RecallResult, type RecallToolCallbacks, type RecallToolOptions, type RecencyOptions, type RedactionResult, type ReflectOptions, type ReflectResult, type RemoteMemoryCandidateOptions, type RemoteMemoryDecodeFailure, RemoteMemoryError, type RemoteMemoryListOptions, type RemoteMemoryMetadataPage, type RemoteMemoryMetadataRecord, type RemoteMemoryPage, RemoteMemoryPartialCreateError, type RemoteMemoryPersistence, type RemoteMemoryPersistenceOptions, type RemoteMemoryPipeline, type RemoteMemoryPipelineOptions, type RemoteMemoryQueryOptions, type RemoteMemoryQueryPage, type RemoteMemoryReadFilters, type RemoteMemoryRecord, type RemoteMemoryRow, type RemoteMemoryStoreOptions, type RequestEncryptionKeyOptions, RerankerUnavailableError, type ReservationReceipt, type ResumeStreamOptions, type ResumeStreamResult, type ResumeStreamWithStorageResult, type RetainAction, type RetainContext, type RetainOptions, type RetainResult, type RetainSource, SDK_SCHEMA_VERSION, SHORT_TTL_MS, STREAM_RESUMABLE_HEADER, type ScoreBreakdown, type ScoreProfileSalienceOptions, type ScreenResult, type ScreenedCandidate, type SearchSource, type SendMessageWithStorageArgs, type SendMessageWithStorageDetachedResult, type SendMessageWithStorageResult, type ServerToolsOptions, type ServerToolsResponse, type SignMessageFn, type StockPriceClassification, type StockPricePreProcessorOptions, type ChatCompletionUsage as StoredChatCompletionUsage, type StoredConversation, type StoredConversationMemory, type StoredMessage, type StoredMessageWithSimilarity, type StoredVaultFolder, VaultFolder as StoredVaultFolderModel, type StoredVaultMemory, VaultMemory as StoredVaultMemoryModel, StreamExpiredError, type StreamMetaEvent, type StreamResumeHandle, type StreamSmoothingConfig, type SynthesizeProfileOptions, TOOL_RESULT_ORIGIN, TOPICS_EXTRACTION_VERSION, TOPIC_EXTRACTION_BATCH_SIZE, TREND_RECENT_WINDOW_DAYS, TREND_STALE_WINDOW_DAYS, type TextChunk, type TopicExtractOptions, type TopicExtractionInput, type TopicExtractionRunResult, type TopicSkipReason, type TurnCompleteEvent, type TurnSkippedEvent, type UncheckedReason, type UnverifiableReason, type UpdateVaultFolderOptions, type UpdateVaultMemoryOptions, type UseChatStorageOptions, type UseChatStorageResult, type UseCreditsOptions, type UseCreditsResult, type UseModelsOptions, type UseModelsResult, VAULT_SIZE_HOP_CAP, type VaultEmbeddingCache, type VaultEmbeddingExpectation, type VaultFolderOperationsContext, type VaultMemoryKind, type VaultMemoryOperationsContext, type VaultMemoryProjection, type VaultMemoryVisibility, type VaultMemoryWriter, type VaultSaveOperation, type VaultSearchResult, type VaultWriteAction, type VaultWriteInput, type VaultWriteOutcome, type VerificationSources, type VerifyMemoriesForPublishOptions, WalletPoller, type WeatherClassification, type WeatherPreProcessorOptions, type WebSearchClassification, type WebSearchPreProcessorOptions, addConversationMemoriesOp, archiveVaultMemoryOp, assembleMemoryContext, attachFileContextToLastUserMessage, backfillMemoryTopicsOp, buildAttachedFilesText, buildNotionAuthUrl, capHopsForDensity, chatStorageMigrations, chatStorageSchema, chunkAndEmbedAllMessages, chunkAndEmbedMessage, chunkText, classifyCryptoPrice, classifyCryptoPriceBatch, classifyDecay, classifyInjectionCandidates, classifyObservationTrend, classifyStockPrice, classifyStockPriceBatch, classifyWeather, classifyWeatherBatch, classifyWebSearch, classifyWebSearchBatch, clearAllEncryptionKeys, clearAllEncryptionState, clearConversationMemoriesOp, clearEncryptionKey, clearLazyTitleCache, clearModelsCache, clearServerToolsCache, consoleLogger, conversationMemoryToStored, cosineInt8, createAutoExtractor, createChunkVectorCache, createCryptoPricePreProcessor, createDecaySweeper, createDurableAutoExtractor, createLlmDecayClassifier, createLlmNeighborRefiner, createLocalMemoryStore, createMemoryEngineTool, createMemoryVaultSearchTool, createMemoryVaultTool, createMessageSourceResolver, createNotionProxyTools, createNotionTools, createPlatformCursorStore, createRecallTool, createRemoteMemoryPersistence, createRemoteMemoryPipeline, createRemoteMemoryStore, createStockPricePreProcessor, createStreamingDeAnonymizer, createVaultEmbeddingCache, createVaultFolderOp, createVaultMemoriesBatchOp, createVaultMemoryOp, createWeatherPreProcessor, createWebSearchPreProcessor, decodeChunkVector, decryptConversationTitle, deleteAllVaultMemoriesForUserOp, deleteMessageOp, deleteVaultFolderOp, deleteVaultMemoryOp, dequantizeEmbedding, deriveKeyFromSignatureBytes, deriveMemoryKeyRing, discoverNotionOAuthEndpoints, eagerEmbedContent, embedAllMessages, embedMessage, encodeChunkVector, ensureDefaultFoldersOp, exchangeNotionCode, extractAndLinkEntitiesForMemoriesOp, extractAndRetain, extractEntitiesForMemories, extractFacts, extractReservationReceipts, formatFileProcessingNotes, generateConversationId, generateEmbedding, generateEmbeddings, generateNotionPKCE, getAllVaultFoldersOp, getAllVaultMemoriesOp, getAllVaultMemoryContentsOp, getCachedServerTools, getConversationMemoriesOp, getConversationsByProjectLazyOp, getConversationsLazyOp, getConversationsPageOp, getDecayCandidatesRawOp, getLogger, getMemoriesNeedingTopicExtractionOp, getServerTools, getUnfiledVaultMemoriesOp, getVaultFolderMemoryCountOp, getVaultMemoriesByIdsOp, getVaultMemoryOp, getVaultRankingProjectionsOp, hardDeleteDecayedOp, hasEncryptionKey, ingestPublishedPhotoMemoriesOp, injectionSignatureCatalog, isAttachedFilesText, isDegradedTopicSkip, isEncrypted, isPiiRedactor, isRerankerAvailable, maskScopedEmbeddingCache, memoryCipher, moveMemoriesToFolderOp, noopLogger, onKeyAvailable, parseMedia, preEmbedVaultMemories, quantizeEmbedding, queueManager, rankProfileCandidates, recall, reencryptMemoryField, reflect, refreshEncryptionKeyIfMatches, refreshNotionAccessToken, registerNotionClient, relinkMemoryTopicsOp, requestEncryptionKey, resolvePiiRedactor, restoreVaultMemoryOp, resumeStream, retain, scoreProfileSalience, screenCandidatesForInjection, sdkMigrations, sdkModelClasses, sdkSchema, searchVaultMemories, seedEncryptionKeys, setLogger, setMemoryVisibilityOp, shouldChunkMessage, shouldRecallMemory, stampTopicsExtractedAtOp, streamCancelPath, streamReplayPath, stripLegacyChunkTextOp, summarizeObservationTrends, supersedeVaultMemoryOp, synthesizeProfile, traverseGraphLane, ttlForType, updateVaultFolderContextOp, updateVaultFolderOp, updateVaultMemoryEmbeddingOp, updateVaultMemoryOp, upsertMessageOp, useChat, useChatStorage, useCredits, useEncryption, useModels, verifyMemoriesForPublish, xhrTransport };
@@ -5115,6 +5115,93 @@ function composeHooks(hooks) {
5115
5115
  };
5116
5116
  }
5117
5117
 
5118
+ // src/lib/chat/streamIdleTimeout.ts
5119
+ var StreamIdleTimeoutError = class extends Error {
5120
+ constructor(idleTimeoutMs) {
5121
+ super(`Stream timed out after ${idleTimeoutMs} ms without activity.`);
5122
+ this.name = "StreamIdleTimeoutError";
5123
+ this.idleTimeoutMs = idleTimeoutMs;
5124
+ }
5125
+ };
5126
+ function withStreamIdleTimeout(transport, idleTimeoutMs) {
5127
+ if (!(idleTimeoutMs > 0) || idleTimeoutMs === Infinity) return transport;
5128
+ return (options) => ({
5129
+ stream: (async function* () {
5130
+ const controller = new AbortController();
5131
+ let timer;
5132
+ let settled = false;
5133
+ let completed = false;
5134
+ let iterator;
5135
+ let interruption;
5136
+ let rejectPending;
5137
+ const disarm = () => {
5138
+ if (timer !== void 0) clearTimeout(timer);
5139
+ timer = void 0;
5140
+ };
5141
+ const interrupt = (error) => {
5142
+ if (interruption) return;
5143
+ interruption = error;
5144
+ rejectPending?.(error);
5145
+ controller.abort();
5146
+ };
5147
+ const arm = () => {
5148
+ if (settled || controller.signal.aborted) return;
5149
+ disarm();
5150
+ timer = setTimeout(() => {
5151
+ interrupt(new StreamIdleTimeoutError(idleTimeoutMs));
5152
+ }, idleTimeoutMs);
5153
+ };
5154
+ const onAbort = () => {
5155
+ controller.abort();
5156
+ };
5157
+ options.signal?.addEventListener("abort", onAbort, { once: true });
5158
+ try {
5159
+ if (options.signal?.aborted) {
5160
+ const error = new Error("Request aborted");
5161
+ error.name = "AbortError";
5162
+ throw error;
5163
+ }
5164
+ arm();
5165
+ iterator = transport({
5166
+ ...options,
5167
+ signal: controller.signal,
5168
+ onActivity: () => {
5169
+ arm();
5170
+ options.onActivity?.();
5171
+ }
5172
+ }).stream[Symbol.asyncIterator]();
5173
+ while (true) {
5174
+ if (interruption) throw interruption;
5175
+ const next = await new Promise((resolve, reject) => {
5176
+ rejectPending = reject;
5177
+ Promise.resolve(iterator.next()).then(resolve, reject);
5178
+ });
5179
+ rejectPending = void 0;
5180
+ if (next.done) {
5181
+ completed = true;
5182
+ break;
5183
+ }
5184
+ arm();
5185
+ yield next.value;
5186
+ }
5187
+ } finally {
5188
+ settled = true;
5189
+ rejectPending = void 0;
5190
+ disarm();
5191
+ options.signal?.removeEventListener("abort", onAbort);
5192
+ if (!completed) {
5193
+ controller.abort();
5194
+ try {
5195
+ void iterator?.return?.().catch(() => {
5196
+ });
5197
+ } catch {
5198
+ }
5199
+ }
5200
+ }
5201
+ })()
5202
+ });
5203
+ }
5204
+
5118
5205
  // src/lib/chat/useChat/utils.ts
5119
5206
  import { jsonrepair } from "jsonrepair";
5120
5207
  function parseToolArguments(raw) {
@@ -7304,7 +7391,20 @@ var defaultTransport = (options) => {
7304
7391
  } catch {
7305
7392
  }
7306
7393
  }
7307
- return response;
7394
+ if (!response.body || !options.onActivity) return response;
7395
+ const body = response.body.pipeThrough(
7396
+ new TransformStream({
7397
+ transform(chunk, controller) {
7398
+ if (chunk.byteLength > 0) options.onActivity?.();
7399
+ controller.enqueue(chunk);
7400
+ }
7401
+ })
7402
+ );
7403
+ return new Response(body, {
7404
+ status: response.status,
7405
+ statusText: response.statusText,
7406
+ headers: response.headers
7407
+ });
7308
7408
  };
7309
7409
  return createSseClient({
7310
7410
  method: options.method ?? "POST",
@@ -7361,6 +7461,7 @@ async function runToolLoop(options) {
7361
7461
  conversationId,
7362
7462
  smoothing,
7363
7463
  signal,
7464
+ idleTimeoutMs = 12e4,
7364
7465
  resumable,
7365
7466
  detachSignal,
7366
7467
  onStreamMeta,
@@ -7374,13 +7475,14 @@ async function runToolLoop(options) {
7374
7475
  onStepFinish,
7375
7476
  onRequest,
7376
7477
  onStreamRetry,
7377
- transport: makeStreamingRequest = defaultTransport,
7478
+ transport = defaultTransport,
7378
7479
  preProcessors,
7379
7480
  maxConnectorCalls = 2,
7380
7481
  hooks: hooksOption,
7381
7482
  piiRedaction,
7382
7483
  onPiiRedacted
7383
7484
  } = options;
7485
+ const makeStreamingRequest = withStreamIdleTimeout(transport, idleTimeoutMs);
7384
7486
  const hooks = Array.isArray(hooksOption) ? composeHooks(hooksOption) : hooksOption;
7385
7487
  const runId = generateRunId();
7386
7488
  let messages = options.messages;
@@ -18144,6 +18246,14 @@ function createLocalMemoryStore(options) {
18144
18246
  getLogger().warn("[memory/store] Failed to embed memory:", err);
18145
18247
  });
18146
18248
  };
18249
+ const maintenance = {
18250
+ createDecaySweeper: (sweeperOptions) => createDecaySweeper({ ...sweeperOptions, vaultCtx }),
18251
+ getTopicBacklog: (backlogOptions) => getMemoriesNeedingTopicExtractionOp(vaultCtx, backlogOptions),
18252
+ extractTopics: (memoryIds, extractOptions) => extractAndLinkEntitiesForMemoriesOp(vaultCtx, memoryIds, extractOptions),
18253
+ stampTopicsExtracted: (memoryIds, extractedAt, version) => stampTopicsExtractedAtOp(vaultCtx, memoryIds, extractedAt, version),
18254
+ relinkTopics: (memoryIds) => relinkMemoryTopicsOp(vaultCtx, memoryIds),
18255
+ backfillTopics: (memoryIds) => backfillMemoryTopicsOp(vaultCtx, memoryIds)
18256
+ };
18147
18257
  return {
18148
18258
  masksEmbeddingInput: options.embeddingOptions.maskInput !== void 0,
18149
18259
  list: (listOptions) => getAllVaultMemoriesOp(vaultCtx, listOptions),
@@ -18157,21 +18267,22 @@ function createLocalMemoryStore(options) {
18157
18267
  memoriesByTopics: (names) => getMemoriesByEntityNamesOp(entityCtx, names),
18158
18268
  topicsByMemories: (memoryIds) => getEntitiesByMemoryIdsOp(entityCtx, memoryIds),
18159
18269
  listTopics: async () => {
18160
- const links = await entityCtx.memoryEntityCollection.query(...linksOwnedBy).fetch();
18270
+ const links = await entityCtx.memoryEntityCollection.query(...linksOwnedBy).unsafeFetchRaw();
18161
18271
  const members = /* @__PURE__ */ new Map();
18162
18272
  for (const link of links) {
18163
- const entityId = String(link.entityId);
18273
+ const entityId = String(link.entity_id);
18164
18274
  const set = members.get(entityId) ?? /* @__PURE__ */ new Set();
18165
- set.add(String(link.memoryId));
18275
+ set.add(String(link.memory_id));
18166
18276
  members.set(entityId, set);
18167
18277
  }
18168
- const entities = userId === void 0 ? await entityCtx.entityCollection.query().fetch() : members.size ? await entityCtx.entityCollection.query(Q8.where("id", Q8.oneOf([...members.keys()]))).fetch() : [];
18278
+ const entities = userId === void 0 ? await entityCtx.entityCollection.query().unsafeFetchRaw() : members.size ? await entityCtx.entityCollection.query(Q8.where("id", Q8.oneOf([...members.keys()]))).unsafeFetchRaw() : [];
18169
18279
  const byName = /* @__PURE__ */ new Map();
18170
18280
  for (const entity of entities) {
18171
- const count2 = members.get(entity.id)?.size ?? 0;
18172
- const existing = byName.get(entity.canonicalName);
18173
- byName.set(entity.canonicalName, {
18174
- name: entity.canonicalName,
18281
+ const name = String(entity.canonical_name);
18282
+ const count2 = members.get(String(entity.id))?.size ?? 0;
18283
+ const existing = byName.get(name);
18284
+ byName.set(name, {
18285
+ name,
18175
18286
  kind: existing?.kind ?? entity.kind ?? null,
18176
18287
  memoryCount: (existing?.memoryCount ?? 0) + count2
18177
18288
  });
@@ -18262,14 +18373,8 @@ function createLocalMemoryStore(options) {
18262
18373
  }
18263
18374
  return () => subscriptions.forEach((s) => s.unsubscribe());
18264
18375
  },
18265
- maintenance: {
18266
- createDecaySweeper: (sweeperOptions) => createDecaySweeper({ ...sweeperOptions, vaultCtx }),
18267
- getTopicBacklog: (backlogOptions) => getMemoriesNeedingTopicExtractionOp(vaultCtx, backlogOptions),
18268
- extractTopics: (memoryIds, extractOptions) => extractAndLinkEntitiesForMemoriesOp(vaultCtx, memoryIds, extractOptions),
18269
- stampTopicsExtracted: (memoryIds, extractedAt, version) => stampTopicsExtractedAtOp(vaultCtx, memoryIds, extractedAt, version),
18270
- relinkTopics: (memoryIds) => relinkMemoryTopicsOp(vaultCtx, memoryIds),
18271
- backfillTopics: (memoryIds) => backfillMemoryTopicsOp(vaultCtx, memoryIds)
18272
- }
18376
+ maintenance,
18377
+ topicMaintenance: maintenance
18273
18378
  };
18274
18379
  }
18275
18380
 
@@ -19053,7 +19158,7 @@ function createRemoteMemoryPipeline(options) {
19053
19158
  const memory = {
19054
19159
  ...snapshot.memory,
19055
19160
  content: patch.content,
19056
- updated_at: patch.preserveUpdatedAt ? snapshot.memory.updated_at : Date.now()
19161
+ updated_at: patch.preserveUpdatedAt ? snapshot.memory.updated_at : Math.max(Date.now(), (snapshot.memory.topics_extracted_at ?? 0) + 1)
19057
19162
  };
19058
19163
  if (patch.scope !== void 0) memory.scope = patch.scope;
19059
19164
  if (patch.embedding === void 0 && patch.content !== snapshot.memory.content) {
@@ -19186,6 +19291,7 @@ function projection({ memory }) {
19186
19291
  };
19187
19292
  }
19188
19293
  function relevant(change, options) {
19294
+ if (change === "metadata") return false;
19189
19295
  return options.includeDeleted ? change === "membership" : change !== "embedding" || !!options.embeddings;
19190
19296
  }
19191
19297
  function safely(onChange) {
@@ -19277,6 +19383,17 @@ function mergeTopics(existing, added) {
19277
19383
  }
19278
19384
  return [...byName.values()];
19279
19385
  }
19386
+ function sameTopics(stored2, next) {
19387
+ const key = (t) => JSON.stringify([t.name, t.kind ?? null, t.source]);
19388
+ if (stored2 === null || stored2.length !== next.length) return false;
19389
+ const keys = new Set(stored2.map(key));
19390
+ return next.every((t) => keys.has(key(t)));
19391
+ }
19392
+ function extractionDue(memory) {
19393
+ const stamp = memory.topics_extracted_at;
19394
+ if (stamp === void 0 || stamp === null) return "fresh";
19395
+ return memory.updated_at > stamp || (memory.topics_extracted_version ?? 0) < TOPICS_EXTRACTION_VERSION ? "stale" : null;
19396
+ }
19280
19397
  function canonicalTopics(row) {
19281
19398
  return new Set((parseTopics(row.topics) ?? []).map((topic) => normalizeEntityName(topic.name)));
19282
19399
  }
@@ -19289,7 +19406,12 @@ function createRemoteMemoryStore(options) {
19289
19406
  const seen = /* @__PURE__ */ new Map();
19290
19407
  let timer;
19291
19408
  const notify = (change, records = []) => {
19292
- if (timer) for (const record2 of records) seen.set(record2.memory.memory_id, record2);
19409
+ if (timer)
19410
+ for (const record2 of records) {
19411
+ const previous = seen.get(record2.memory.memory_id);
19412
+ if ((previous?.version ?? 0) + 1 === record2.version)
19413
+ seen.set(record2.memory.memory_id, record2);
19414
+ }
19293
19415
  for (const subscriber of [...subscribers])
19294
19416
  if (relevant(change, subscriber.options)) safely(subscriber.onChange);
19295
19417
  };
@@ -19350,15 +19472,72 @@ function createRemoteMemoryStore(options) {
19350
19472
  const record2 = await persistence.get(id);
19351
19473
  return record2 && !record2.memory.is_deleted ? record2 : null;
19352
19474
  };
19353
- const mutate = async (id, change, edit) => serialized(id, async () => {
19475
+ const mutateLocked = async (id, change, edit) => {
19354
19476
  const record2 = await live(id);
19355
19477
  if (!record2) return null;
19356
19478
  const next = edit(structuredClone(record2.memory));
19357
19479
  if (!next) return null;
19358
19480
  const saved = await persistence.put(next, record2);
19359
- notify(change, [saved]);
19481
+ notify(typeof change === "function" ? change(record2.memory) : change, [saved]);
19360
19482
  return saved;
19361
- });
19483
+ };
19484
+ const mutate = (id, change, edit) => serialized(id, () => mutateLocked(id, change, edit));
19485
+ const serializedAll = (ids, task) => [...new Set(ids)].sort().reduceRight((inner, id) => () => serialized(id, inner), task)();
19486
+ const mutateMany = async (ids, change, edit) => {
19487
+ const saved = /* @__PURE__ */ new Map();
19488
+ const failed = /* @__PURE__ */ new Map();
19489
+ for (const slice of chunks([...new Set(ids)], MAX_BATCH)) {
19490
+ await serializedAll(slice, async () => {
19491
+ const writes = [];
19492
+ let read;
19493
+ try {
19494
+ read = await readEveryState(slice);
19495
+ } catch (error) {
19496
+ for (const id of slice) failed.set(id, error);
19497
+ return;
19498
+ }
19499
+ const { records, unreadable } = read;
19500
+ for (const id of slice) {
19501
+ const record2 = records.get(id);
19502
+ if (unreadable.has(id)) failed.set(id, new Error(`Memory ${id} could not be decrypted`));
19503
+ else if (!record2) failed.set(id, new Error(`Memory ${id} was not found`));
19504
+ else if (!record2.memory.is_deleted) {
19505
+ const memory = edit(structuredClone(record2.memory));
19506
+ if (memory) writes.push({ before: record2, memory });
19507
+ }
19508
+ }
19509
+ if (writes.length === 0) return;
19510
+ try {
19511
+ const written = await persistence.putMany(
19512
+ writes.map(({ before, memory }) => ({ memory, expectedVersion: before }))
19513
+ );
19514
+ const byChange = /* @__PURE__ */ new Map();
19515
+ written.forEach((record2, i) => {
19516
+ saved.set(record2.memory.memory_id, record2);
19517
+ const kind = change(writes[i].before.memory);
19518
+ byChange.set(kind, [...byChange.get(kind) ?? [], record2]);
19519
+ });
19520
+ for (const [kind, changed] of byChange) notify(kind, changed);
19521
+ } catch (error) {
19522
+ const perRow = error instanceof RemoteMemoryError && (error.code === "version_conflict" || error.status === 429);
19523
+ for (const { before } of writes) {
19524
+ const id = before.memory.memory_id;
19525
+ if (!perRow) {
19526
+ failed.set(id, error);
19527
+ continue;
19528
+ }
19529
+ try {
19530
+ const record2 = await mutateLocked(id, change, edit);
19531
+ if (record2) saved.set(id, record2);
19532
+ } catch (rowError) {
19533
+ failed.set(id, rowError);
19534
+ }
19535
+ }
19536
+ }
19537
+ });
19538
+ }
19539
+ return { saved, failed };
19540
+ };
19362
19541
  const embedInBackground = ({ memory: { memory_id: id, content } }) => {
19363
19542
  generateEmbedding(content, embeddingOptions).then(
19364
19543
  (vector) => serialized(id, async () => {
@@ -19414,11 +19593,10 @@ function createRemoteMemoryStore(options) {
19414
19593
  return records.map((record2) => stored(record2.memory));
19415
19594
  };
19416
19595
  const asStored = (record2) => record2 ? stored(record2.memory) : null;
19417
- const withKnownKinds = async (topics) => {
19596
+ const knownKinds = async (topics) => {
19418
19597
  const unkinded = [
19419
19598
  ...new Set(topics.filter((t) => !t.kind).map((t) => normalizeEntityName(t.name)))
19420
19599
  ];
19421
- if (unkinded.length === 0) return topics;
19422
19600
  const kinds = /* @__PURE__ */ new Map();
19423
19601
  for (const names of chunks(unkinded, MAX_QUERY_TOPICS)) {
19424
19602
  for (const { memory } of await pages(metadata, {
@@ -19433,10 +19611,136 @@ function createRemoteMemoryStore(options) {
19433
19611
  }
19434
19612
  }
19435
19613
  }
19436
- return topics.map((topic) => {
19614
+ return (topic) => {
19437
19615
  const kind = topic.kind ?? kinds.get(normalizeEntityName(topic.name));
19438
19616
  return kind ? { ...topic, kind } : topic;
19439
- });
19617
+ };
19618
+ };
19619
+ const withKnownKinds = async (topics) => topics.map(await knownKinds(topics));
19620
+ const readEveryState = async (ids) => {
19621
+ const records = /* @__PURE__ */ new Map();
19622
+ const unreadable = /* @__PURE__ */ new Set();
19623
+ for (const memory_ids of chunks(ids, MAX_QUERY_IDS)) {
19624
+ let cursor2;
19625
+ do {
19626
+ const page = await persistence.query({
19627
+ memory_ids,
19628
+ include_deleted: true,
19629
+ include_archived: true,
19630
+ include_quarantined: true,
19631
+ include_superseded: true,
19632
+ limit: 200,
19633
+ ...cursor2 && { cursor: cursor2 }
19634
+ });
19635
+ warnFailed(page.failed);
19636
+ for (const record2 of page.items) records.set(record2.memory.memory_id, record2);
19637
+ for (const failure of page.failed) unreadable.add(failure.memory_id);
19638
+ cursor2 = page.next_cursor;
19639
+ } while (cursor2);
19640
+ }
19641
+ return { records, unreadable };
19642
+ };
19643
+ const topicMaintenance = {
19644
+ getTopicBacklog: async (backlogOptions = {}) => {
19645
+ const stale = [];
19646
+ const fresh = [];
19647
+ for (const { memory } of await pages(metadata, { order: "created" })) {
19648
+ if (memory.topics_user_managed) continue;
19649
+ const due = extractionDue(memory);
19650
+ if (due === "stale") stale.push(memory.memory_id);
19651
+ else if (due === "fresh") fresh.push(memory.memory_id);
19652
+ }
19653
+ const limit = backlogOptions.limit !== void 0 && backlogOptions.limit > 0 ? backlogOptions.limit : Infinity;
19654
+ return {
19655
+ pending: [...stale, ...fresh].slice(0, limit).map((uniqueId) => ({ uniqueId })),
19656
+ linkedUnstamped: [],
19657
+ topicsToRelink: [],
19658
+ topicsBackfill: []
19659
+ };
19660
+ },
19661
+ extractTopics: async (memoryIds, extractOptions) => {
19662
+ const extractedAt = extractOptions.now ?? Date.now();
19663
+ const skippedIds = [];
19664
+ const skippedReasons = /* @__PURE__ */ new Map();
19665
+ const skip = (id, reason) => {
19666
+ if (skippedReasons.has(id)) return;
19667
+ skippedIds.push(id);
19668
+ skippedReasons.set(id, reason);
19669
+ };
19670
+ const ids = [...new Set(memoryIds)];
19671
+ const { records, unreadable } = await readEveryState(ids);
19672
+ const inputs = [];
19673
+ for (const id of ids) {
19674
+ const memory = records.get(id)?.memory;
19675
+ if (unreadable.has(id)) skip(id, "unreadable");
19676
+ else if (!memory) skip(id, "not-found");
19677
+ else if (memory.is_deleted || memory.topics_user_managed) skip(id, "excluded");
19678
+ else inputs.push({ id, content: memory.content });
19679
+ }
19680
+ const entitiesByMemory = await extractEntitiesForMemories(inputs, extractOptions);
19681
+ const answered = /* @__PURE__ */ new Map();
19682
+ for (const input of inputs) {
19683
+ const entities = entitiesByMemory.get(input.id);
19684
+ if (entities === void 0) skip(input.id, "llm-unanswered");
19685
+ else
19686
+ answered.set(input.id, { content: input.content, topics: topicInputs(entities, "auto") });
19687
+ }
19688
+ const stampedIds = [];
19689
+ const fail = (id, reason) => {
19690
+ skip(id, reason);
19691
+ entitiesByMemory.delete(id);
19692
+ };
19693
+ try {
19694
+ const kinded = await knownKinds([...answered.values()].flatMap((a) => a.topics));
19695
+ const topics = new Map(
19696
+ [...answered].map(([id, a]) => [id, mergeTopics([], a.topics.map(kinded))])
19697
+ );
19698
+ const unchanged = (memory) => sameTopics(parseTopics(memory.topics), topics.get(memory.memory_id));
19699
+ const { saved, failed } = await mutateMany(
19700
+ [...answered.keys()],
19701
+ (before) => sameTopics(parseTopics(before.topics) ?? [], topics.get(before.memory_id)) ? "metadata" : "edit",
19702
+ (memory) => {
19703
+ if (memory.topics_user_managed || memory.content !== answered.get(memory.memory_id).content)
19704
+ return null;
19705
+ return {
19706
+ ...memory,
19707
+ ...!unchanged(memory) && {
19708
+ topics: serializeTopics(topics.get(memory.memory_id)),
19709
+ topics_updated_at: Date.now()
19710
+ },
19711
+ topics_extracted_at: Math.max(extractedAt, memory.updated_at),
19712
+ topics_extracted_version: TOPICS_EXTRACTION_VERSION
19713
+ };
19714
+ }
19715
+ );
19716
+ for (const id of answered.keys()) {
19717
+ if (saved.has(id)) stampedIds.push(id);
19718
+ else fail(id, failed.has(id) ? "link-failed" : "link-declined");
19719
+ }
19720
+ if (failed.size)
19721
+ getLogger().warn(
19722
+ "[memory/remote-store] Failed to write extracted topics:",
19723
+ failed.values().next().value
19724
+ );
19725
+ } catch (error) {
19726
+ getLogger().warn("[memory/remote-store] Failed to write extracted topics:", error);
19727
+ for (const id of answered.keys()) fail(id, "link-failed");
19728
+ }
19729
+ return { entitiesByMemory, stampedIds, skippedIds, skippedReasons };
19730
+ },
19731
+ stampTopicsExtracted: async (memoryIds, extractedAt, version = TOPICS_EXTRACTION_VERSION) => {
19732
+ const ids = [...new Set(memoryIds)];
19733
+ const { saved, failed } = await mutateMany(
19734
+ ids,
19735
+ () => "metadata",
19736
+ (memory) => memory.topics_user_managed ? null : { ...memory, topics_extracted_at: extractedAt, topics_extracted_version: version }
19737
+ );
19738
+ if (failed.size)
19739
+ getLogger().warn("[memory/remote-store] Failed to stamp topics:", [...failed.values()]);
19740
+ return ids.filter((id) => saved.has(id));
19741
+ },
19742
+ relinkTopics: () => Promise.resolve([]),
19743
+ backfillTopics: () => Promise.resolve([])
19440
19744
  };
19441
19745
  const everyState = {
19442
19746
  include_deleted: true,
@@ -19515,6 +19819,7 @@ function createRemoteMemoryStore(options) {
19515
19819
  };
19516
19820
  return {
19517
19821
  masksEmbeddingInput: embeddingOptions.maskInput !== void 0,
19822
+ topicMaintenance,
19518
19823
  list: async (listOptions = {}) => (await listRows(decrypted, listOptions, listFilters(listOptions), maxOf(listOptions))).map(
19519
19824
  (r) => stored(r.memory)
19520
19825
  ),
@@ -19599,7 +19904,7 @@ function createRemoteMemoryStore(options) {
19599
19904
  const kind = patch.kind !== void 0 ? patch.kind : memory.kind;
19600
19905
  assertValidKindLevel(kind, level);
19601
19906
  memory.content = patch.content;
19602
- memory.updated_at = Date.now();
19907
+ memory.updated_at = Math.max(Date.now(), (memory.topics_extracted_at ?? 0) + 1);
19603
19908
  if (patch.level !== void 0) {
19604
19909
  memory.level = level;
19605
19910
  memory.scope = scopeForLevel(level);