{"version":3,"sources":["../src/memory/types.ts","../src/agent/state-signals.ts"],"names":["isPlainObject","mastraDBMessageToSignal","createSignal","signal"],"mappings":"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","file":"chunk-UC46OXET.cjs","sourcesContent":["import type { AssistantContent, CoreMessage, ToolContent, UserContent } from '@internal/ai-sdk-v4';\n\nimport type { AgentExecutionOptions } from '../agent/agent.types';\nimport type { AgentConfig } from '../agent/types';\nexport type { MastraDBMessage } from '../agent';\nimport type { EmbeddingModelId } from '../llm/model/index.js';\nimport type { ModelRouterModelId } from '../llm/model/provider-registry.js';\nimport type { MastraLanguageModel, MastraModelConfig } from '../llm/model/shared.types';\nimport type { RequestContext } from '../request-context';\nimport type { PublicSchema } from '../schema';\nimport type { MastraCompositeStore } from '../storage';\nimport type { DynamicArgument } from '../types';\nimport type { MastraEmbeddingModel, MastraEmbeddingOptions, MastraVector } from '../vector';\nimport type { VectorFilter } from '../vector/filter/base';\nimport type { MemoryProcessor } from '.';\n\nexport type { Message as AiMessageType } from '@internal/ai-sdk-v4';\nexport type { MastraLanguageModel };\n\n// Types for the memory system\nexport type MastraMessageV1 = {\n id: string;\n content: string | UserContent | AssistantContent | ToolContent;\n role: 'system' | 'user' | 'assistant' | 'tool' | 'signal';\n createdAt: Date;\n threadId?: string;\n resourceId?: string;\n toolCallIds?: string[];\n toolCallArgs?: Record[];\n toolNames?: string[];\n type: 'text' | 'tool-call' | 'tool-result';\n};\n\n/**\n * @deprecated use MastraMessageV1 or MastraDBMessage\n */\nexport type MessageType = MastraMessageV1;\n\nexport type StorageThreadType = {\n id: string;\n title?: string;\n resourceId: string;\n createdAt: Date;\n updatedAt: Date;\n metadata?: Record;\n};\n\n/**\n * Thread-specific Observational Memory metadata.\n * Stored on thread.metadata.mastra.om to keep thread-specific data\n * separate from the shared resource-level OM record.\n */\nexport type ThreadOMMetadata = {\n /** The current task being worked on in this thread */\n currentTask?: string;\n /** Suggested response for continuing this thread's conversation */\n suggestedResponse?: string;\n /** Observer-generated thread title */\n threadTitle?: string;\n /** Timestamp of the last observed message in this thread (ISO string for JSON serialization) */\n lastObservedAt?: string;\n /** Cursor pointing at the last observed message (for replay pruning fallback) */\n lastObservedMessageCursor?: { createdAt: string; id: string };\n // Note: Patterns are stored on the ObservationalMemoryRecord (resource-level), not thread metadata\n};\n\n/**\n * Structure for Mastra-specific thread metadata.\n * Stored on thread.metadata.mastra\n */\nexport type ThreadMastraMetadata = {\n om?: ThreadOMMetadata;\n};\n\nfunction isPlainObject(value: unknown): value is Record {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\n/**\n * Helper to get OM metadata from a thread's metadata object.\n * Returns undefined if not present or if the structure is invalid.\n */\nexport function getThreadOMMetadata(threadMetadata?: Record): ThreadOMMetadata | undefined {\n if (!threadMetadata) return undefined;\n const mastra = threadMetadata.mastra;\n if (!isPlainObject(mastra)) return undefined;\n const om = mastra.om;\n if (!isPlainObject(om)) return undefined;\n return om as ThreadOMMetadata;\n}\n\n/**\n * Helper to set OM metadata on a thread's metadata object.\n * Creates the nested structure if it doesn't exist.\n * Returns a new metadata object (does not mutate the original).\n * Safely handles cases where existing mastra/om values are not objects.\n */\nexport function setThreadOMMetadata(\n threadMetadata: Record | undefined,\n omMetadata: ThreadOMMetadata,\n): Record {\n const existing = threadMetadata ?? {};\n const existingMastra = isPlainObject(existing.mastra) ? existing.mastra : {};\n const existingOM = isPlainObject(existingMastra.om) ? existingMastra.om : {};\n\n return {\n ...existing,\n mastra: {\n ...existingMastra,\n om: {\n ...existingOM,\n ...omMetadata,\n },\n },\n };\n}\n\n/**\n * Memory-specific context passed via RequestContext under the 'MastraMemory' key\n * This provides processors with access to memory-related execution context\n */\nexport type MemoryRequestContext = {\n thread?: Partial & { id: string };\n resourceId?: string;\n memoryConfig?: MemoryConfigInternal;\n};\n\n/**\n * Parse and validate memory runtime context from RequestContext\n * @param requestContext - The RequestContext to extract memory context from\n * @returns The validated MemoryRequestContext or null if not available\n * @throws Error if the context exists but is malformed\n */\nexport function parseMemoryRequestContext(requestContext?: RequestContext): MemoryRequestContext | null {\n if (!requestContext) {\n return null;\n }\n\n const memoryContext = requestContext.get('MastraMemory');\n if (!memoryContext) {\n return null;\n }\n\n // Validate the structure\n if (typeof memoryContext !== 'object' || memoryContext === null) {\n throw new Error(`Invalid MemoryRequestContext: expected object, got ${typeof memoryContext}`);\n }\n\n const ctx = memoryContext as Record;\n\n // Validate thread if present\n if (ctx.thread !== undefined) {\n if (typeof ctx.thread !== 'object' || ctx.thread === null) {\n throw new Error(`Invalid MemoryRequestContext.thread: expected object, got ${typeof ctx.thread}`);\n }\n const thread = ctx.thread as Record;\n if (typeof thread.id !== 'string') {\n throw new Error(`Invalid MemoryRequestContext.thread.id: expected string, got ${typeof thread.id}`);\n }\n }\n\n // Validate resourceId if present\n if (ctx.resourceId !== undefined && typeof ctx.resourceId !== 'string') {\n throw new Error(`Invalid MemoryRequestContext.resourceId: expected string, got ${typeof ctx.resourceId}`);\n }\n\n return memoryContext as MemoryRequestContext;\n}\n\nexport type MessageResponse = {\n raw: MastraMessageV1[];\n core_message: CoreMessage[];\n}[T];\n\ntype BaseWorkingMemory = {\n enabled: boolean;\n /**\n * Scope for working memory storage.\n * - 'resource': Memory persists across all threads for the same resource/user (default)\n * - 'thread': Memory is isolated per conversation thread\n *\n * @default 'resource'\n */\n scope?: 'thread' | 'resource';\n /**\n * Experimental: deliver working memory to the model as a state signal instead of folding\n * it into the system message. Storage is unchanged. When `true`, `Memory` auto-attaches\n * a state-signal processor that emits snapshots or deltas with dedup via `cacheKey`, and\n * registers the working-memory tool as `setWorkingMemory` instead of `updateWorkingMemory`.\n *\n * Not supported with template working memory `version: 'vnext'`.\n *\n * @default false\n * @see docs/src/content/en/docs/agents/signals.mdx\n */\n useStateSignals?: boolean;\n /** @deprecated The `use` option has been removed. Working memory always uses tool-call mode. */\n use?: never;\n};\n\ntype TemplateWorkingMemory =\n | (BaseWorkingMemory & {\n template: string;\n schema?: never;\n version?: 'stable';\n })\n | (Omit & {\n template: string;\n schema?: never;\n version: 'vnext';\n useStateSignals?: false;\n });\n\ntype SchemaWorkingMemory = BaseWorkingMemory & {\n schema: PublicSchema;\n template?: never;\n};\n\ntype WorkingMemoryNone = BaseWorkingMemory & {\n template?: never;\n schema?: never;\n};\n\nexport type WorkingMemory = TemplateWorkingMemory | SchemaWorkingMemory | WorkingMemoryNone;\n\n/**\n * Vector index configuration for optimizing semantic recall performance.\n *\n * These settings are primarily supported by PostgreSQL with pgvector extension.\n * Other vector stores (Pinecone, Qdrant, Chroma, etc.) will use their default\n * configurations and ignore these settings.\n *\n * @see https://mastra.ai/docs/memory/semantic-recall#postgresql-index-optimization\n */\nexport type VectorIndexConfig = {\n /**\n * Type of vector index to create (PostgreSQL/pgvector only).\n * - 'ivfflat': Inverted file index, good balance of speed and recall\n * - 'hnsw': Hierarchical Navigable Small World, best performance for most cases\n * - 'flat': Exact nearest neighbor search, slow but 100% recall\n *\n * @default 'ivfflat'\n * @example\n * ```typescript\n * type: 'hnsw' // Recommended for production\n * ```\n */\n type?: 'ivfflat' | 'hnsw' | 'flat';\n\n /**\n * Distance metric for similarity calculations.\n * - 'cosine': Normalized dot product, good for text similarity\n * - 'euclidean': L2 distance, geometric distance in vector space\n * - 'dotproduct': Inner product, best for OpenAI embeddings\n *\n * Note: While defined here, most vector stores have their own metric configuration.\n *\n * @default 'cosine'\n * @example\n * ```typescript\n * metric: 'dotproduct' // Optimal for OpenAI embeddings\n * ```\n */\n metric?: 'cosine' | 'euclidean' | 'dotproduct';\n\n /**\n * Configuration for IVFFlat index (PostgreSQL only).\n * Controls the number of inverted lists for clustering vectors.\n */\n ivf?: {\n /**\n * Number of inverted lists (clusters) to create.\n * Higher values mean better recall but slower build time.\n * Recommended: rows/1000 for tables with > 1M rows.\n *\n * @default 100\n */\n lists?: number;\n };\n\n /**\n * Configuration for HNSW index (PostgreSQL only).\n * Hierarchical graph-based index with superior query performance.\n */\n hnsw?: {\n /**\n * Maximum number of bi-directional links per node.\n * Higher values increase recall and index size.\n *\n * @default 16\n * @example\n * ```typescript\n * m: 32 // Higher recall, larger index\n * ```\n */\n m?: number;\n\n /**\n * Size of dynamic candidate list during index construction.\n * Higher values mean better recall but slower index creation.\n *\n * @default 64\n * @example\n * ```typescript\n * efConstruction: 128 // Better quality, slower build\n * ```\n */\n efConstruction?: number;\n };\n};\n\n/**\n * Configuration for semantic recall using RAG-based retrieval.\n *\n * Enables agents to retrieve relevant messages from past conversations using vector similarity search.\n * Retrieved messages provide context from beyond the recent conversation history, helping agents\n * maintain continuity across longer interactions.\n *\n * @see https://mastra.ai/docs/memory/semantic-recall\n */\nexport type SemanticRecall = {\n /**\n * Number of semantically similar messages to retrieve from the vector database.\n * Higher values provide more context but increase token usage.\n *\n * @example\n * ```typescript\n * topK: 3 // Retrieve 3 most similar messages\n * ```\n */\n topK: number;\n\n /**\n * Amount of surrounding context to include with each retrieved message.\n * Can be a single number (same before/after) or an object with separate values.\n * Helps provide conversational flow around the matched message.\n *\n * @example\n * ```typescript\n * messageRange: 2 // Include 2 messages before and after\n * messageRange: { before: 1, after: 3 } // 1 before, 3 after\n * ```\n */\n messageRange: number | { before: number; after: number };\n\n /**\n * Scope for semantic search queries.\n * - 'resource': Search across all threads owned by the same resource/user (default)\n * - 'thread': Search only within the current conversation thread\n *\n * @default 'resource'\n * @example\n * ```typescript\n * scope: 'thread' // Limit recall to current thread only\n * ```\n */\n scope?: 'thread' | 'resource';\n\n /**\n * Vector index configuration (PostgreSQL/pgvector specific).\n * Other vector stores will use their default index configurations.\n * HNSW indexes typically provide better performance than IVFFlat.\n *\n * @example\n * ```typescript\n * indexConfig: {\n * type: 'hnsw',\n * metric: 'dotproduct', // Best for OpenAI embeddings\n * hnsw: { m: 16, efConstruction: 64 }\n * }\n * ```\n */\n indexConfig?: VectorIndexConfig;\n\n /**\n * Metadata filter for semantic search queries.\n * Allows filtering results by metadata fields using MongoDB-style query syntax.\n * Works in combination with scope-based filtering (resource_id/thread_id).\n *\n * @example\n * ```typescript\n * filter: {\n * projectId: { $eq: 'project-a' },\n * category: { $in: ['work', 'personal'] }\n * }\n * ```\n */\n filter?: VectorFilter;\n\n /**\n * Minimum similarity score threshold (0-1).\n * Messages below this threshold will be filtered out from semantic search results.\n *\n * @example\n * ```typescript\n * threshold: 0.7 // Only include messages with 70%+ similarity\n * ```\n */\n threshold?: number;\n\n /**\n * Index name for the vector store.\n * If not provided, will be auto-generated based on embedder model.\n *\n * @example\n * ```typescript\n * indexName: 'my-custom-index'\n * ```\n */\n indexName?: string;\n};\n\n/**\n * Model settings for Observer/Reflector agents in Observational Memory.\n * Uses the same settings as Agent.generate() modelSettings (temperature, maxOutputTokens, topP, etc.).\n */\nexport type ObservationalMemoryModelSettings = AgentExecutionOptions['modelSettings'];\n\nexport type ObservationalMemoryActivationTTL = number | string | 'auto' | false;\n\n/**\n * Configuration for the observation step in Observational Memory.\n */\nexport interface ObservationalMemoryObservationConfig {\n /**\n * Model for the Observer agent.\n * Can be a model ID string (e.g., 'openai/gpt-4o'), a LanguageModel instance,\n * a function that returns either (for dynamic model selection),\n * or an array of ModelWithRetries for fallback support.\n *\n * Cannot be set if a top-level `model` is also provided.\n *\n * @default 'google/gemini-2.5-flash'\n */\n model?: AgentConfig['model'];\n\n /**\n * Token count of unobserved messages that triggers observation.\n * When unobserved message tokens exceed this, the Observer is called.\n *\n * @default 30000\n */\n messageTokens?: number;\n\n /**\n * Model settings for the Observer agent.\n * @default { temperature: 0.3, maxOutputTokens: 100_000 }\n */\n modelSettings?: ObservationalMemoryModelSettings;\n\n /**\n * Provider-specific options passed to the Observer model.\n * Use this for provider features like thinking budgets, safety settings, etc.\n *\n * @example\n * ```ts\n * providerOptions: {\n * google: { thinkingConfig: { thinkingBudget: 215 } }\n * }\n * ```\n *\n * @default { google: { thinkingConfig: { thinkingBudget: 215 } } }\n */\n providerOptions?: Record | undefined>;\n\n /**\n * Maximum tokens per batch when observing multiple threads.\n * Threads are chunked into batches of this size and processed in parallel.\n * Lower values = more parallelism but more API calls.\n * Higher values = fewer API calls but less parallelism.\n *\n * @default 10000\n */\n maxTokensPerBatch?: number;\n\n /**\n * Token interval for async background observation buffering.\n * Observations run asynchronously in the background at this interval,\n * storing results in a buffer. When the main `messageTokens` threshold is reached,\n * buffered observations are activated instantly (no blocking LLM call).\n *\n * Can be an absolute token count (e.g. `5_000`) or a fraction of `messageTokens`\n * (e.g. `0.25` means buffer every 25% of the threshold).\n *\n * Set to `false` to explicitly disable async buffering.\n *\n * Must resolve to less than `messageTokens`.\n *\n * @default 0.2 (buffer every 20% of messageTokens)\n * @example\n * ```ts\n * // Buffer every 5k tokens, activate at 20k\n * observation: {\n * messageTokens: 20_000,\n * bufferTokens: 5_000,\n * }\n * // Or equivalently, using a fraction:\n * observation: {\n * messageTokens: 20_000,\n * bufferTokens: 0.25,\n * }\n * // Disable async buffering (use synchronous observation)\n * observation: {\n * bufferTokens: false,\n * }\n * ```\n */\n bufferTokens?: number | false;\n\n /**\n * Ratio (0-1) of buffered observations to activate when threshold is reached.\n * Setting this below 1 keeps some observations in reserve, which helps maintain\n * conversation continuity and provides a buffer for the next activation cycle.\n *\n * Requires `bufferTokens` to also be set.\n *\n * @default 0.8 (activate 80% of buffered observations, keeping 20% in reserve)\n * @example\n * ```ts\n * // Activate 70% of buffered observations, keep 30% in reserve\n * observation: {\n * messageTokens: 20_000,\n * bufferTokens: 0.25,\n * bufferActivation: 0.7,\n * }\n * ```\n */\n bufferActivation?: number;\n\n /**\n * Time before buffered observations are force-activated after inactivity.\n * Accepts milliseconds as a number, a duration string like `\"5m\"` or `\"1hr\"`,\n * `\"auto\"` to choose a provider-aware TTL from the actor model's prompt-cache behavior,\n * or `false` to disable top-level `activateAfterIdle` for observations.\n * If unset, top-level `activateAfterIdle` is used for observations.\n */\n activateAfterIdle?: ObservationalMemoryActivationTTL;\n\n /**\n * Force-activate buffered observations when the actor provider/model changes.\n * If unset, top-level `activateOnProviderChange` is used for observations.\n */\n activateOnProviderChange?: boolean;\n\n /**\n * Token threshold above which synchronous (blocking) observation is forced.\n * When set, the system will never block for observation between `messageTokens`\n * and `blockAfter` — only async buffering and activation are used in that range.\n * Once unobserved tokens exceed `blockAfter`, a synchronous observation runs as a\n * last resort to prevent context window overflow.\n *\n * Accepts either:\n * - A **multiplier** (1 < value < 2): multiplied by `messageTokens`.\n * e.g. `blockAfter: 1.5` with `messageTokens: 20_000` → blocks at 30,000 tokens.\n * - An **absolute token count** (≥ 2): must be greater than `messageTokens`.\n * e.g. `blockAfter: 80_000` → blocks at 80,000 tokens.\n *\n * Only relevant when `bufferTokens` is set. When `bufferTokens` is not set,\n * synchronous observation is used directly at `messageTokens` and this setting has no effect.\n *\n * @default 1.2 (120% of `messageTokens`) when `bufferTokens` is set.\n *\n * @example\n * ```ts\n * // Multiplier: 1.5x messageTokens\n * observation: {\n * messageTokens: 20_000,\n * bufferTokens: 0.25,\n * blockAfter: 1.5, // resolves to 30,000\n * }\n * // Absolute: explicit token count\n * observation: {\n * messageTokens: 20_000,\n * bufferTokens: 5_000,\n * blockAfter: 80_000,\n * }\n * ```\n */\n blockAfter?: number;\n\n /**\n * Optional token budget for observer context.\n * When set, the \"Previous Observations\" section is truncated from the end\n * to keep the most recent observations within this budget, and pending\n * buffered reflections replace the raw observations they summarized.\n * Set to `0` for full truncation (omit previous observations entirely), or `false` to disable.\n *\n * @default undefined (disabled)\n */\n previousObserverTokens?: number | false;\n\n /**\n * Custom instructions appended to the Observer agent's system prompt.\n * Use this to customize what the Observer focuses on or how it formats observations.\n *\n * @example\n * ```ts\n * observation: {\n * instruction: 'Focus on user dietary preferences and allergies.',\n * }\n * ```\n */\n instruction?: string;\n\n /**\n * When enabled, the Observer suggests a short thread title based on the conversation.\n * The title is updated on the thread whenever the Observer runs.\n *\n * @default false\n */\n threadTitle?: boolean;\n\n /**\n * Whether image/file attachment parts are forwarded to the Observer LLM.\n * - `true` forwards attachments\n * - `false` drops attachments and leaves placeholder text\n * - `'auto'` checks model capabilities to decide\n *\n * @default true\n */\n observeAttachments?: 'auto' | boolean;\n}\n\n/**\n * Configuration for the reflection step in Observational Memory.\n */\nexport interface ObservationalMemoryReflectionConfig {\n /**\n * Model for the Reflector agent.\n * Can be a model ID string (e.g., 'openai/gpt-4o'), a LanguageModel instance,\n * a function that returns either (for dynamic model selection),\n * or an array of ModelWithRetries for fallback support.\n *\n * Cannot be set if a top-level `model` is also provided.\n *\n * @default 'google/gemini-2.5-flash'\n */\n model?: AgentConfig['model'];\n\n /**\n * Token count of observations that triggers reflection.\n * When observation tokens exceed this, the Reflector is called to condense them.\n *\n * @default 40000\n */\n observationTokens?: number;\n\n /**\n * Model settings for the Reflector agent.\n * @default { temperature: 0, maxOutputTokens: 100_000 }\n */\n modelSettings?: ObservationalMemoryModelSettings;\n\n /**\n * Provider-specific options passed to the Reflector model.\n * Use this for provider features like thinking budgets, safety settings, etc.\n *\n * @example\n * ```ts\n * providerOptions: {\n * google: { thinkingConfig: { thinkingBudget: 1024 } }\n * }\n * ```\n *\n * @default { google: { thinkingConfig: { thinkingBudget: 1024 } } }\n */\n providerOptions?: Record | undefined>;\n\n /**\n * Token threshold above which synchronous (blocking) reflection is forced.\n * When set with async reflection enabled, the system will not block for\n * reflection between `observationTokens` and `blockAfter` — only async\n * buffering and activation are used in that range. Once observation tokens\n * exceed `blockAfter`, a synchronous reflection runs as a last resort.\n *\n * Accepts either:\n * - A **multiplier** (1 < value < 2): multiplied by `observationTokens`.\n * e.g. `blockAfter: 1.5` with `observationTokens: 30_000` → blocks at 45,000 tokens.\n * - An **absolute token count** (≥ 2): must be greater than `observationTokens`.\n * e.g. `blockAfter: 50_000` → blocks at 50,000 tokens.\n *\n * Only relevant when `bufferActivation` is set. When `bufferActivation` is not set,\n * synchronous reflection is used directly at `observationTokens` and this setting has no effect.\n *\n * @default 1.2 (120% of `observationTokens`) when `bufferActivation` is set.\n */\n blockAfter?: number;\n\n /**\n * Time before buffered reflections are force-activated after inactivity.\n * Accepts milliseconds as a number, a duration string like `\"5m\"` or `\"1hr\"`,\n * `\"auto\"` to choose a provider-aware TTL from the actor model's prompt-cache behavior,\n * or `false` to disable idle activation for reflections.\n * Reflections do not inherit top-level `activateAfterIdle`; set this explicitly to enable.\n */\n activateAfterIdle?: ObservationalMemoryActivationTTL;\n\n /**\n * Force-activate buffered reflections when the actor provider/model changes.\n * Reflections do not inherit top-level `activateOnProviderChange`; set this explicitly to enable.\n */\n activateOnProviderChange?: boolean;\n\n /**\n * Ratio (0-1) controlling when async reflection buffering starts.\n * When observation tokens reach `observationTokens * bufferActivation`,\n * reflection runs asynchronously in the background. When the full\n * `observationTokens` threshold is reached, the buffered reflection\n * is spliced into the observation content instantly (no blocking LLM call).\n *\n * Only one buffered reflection is maintained at a time. On activation,\n * the buffered reflection replaces the line range it was generated from,\n * and any new observations appended after that range are preserved.\n *\n * Requires `observation.bufferTokens` to also be set (async observation).\n *\n * @example\n * ```ts\n * reflection: {\n * observationTokens: 30_000,\n * bufferActivation: 0.5, // Start buffering at 15k tokens\n * }\n * ```\n */\n bufferActivation?: number;\n\n /**\n * Custom instructions appended to the Reflector agent's system prompt.\n * Use this to customize how the Reflector consolidates observations.\n *\n * @example\n * ```ts\n * reflection: {\n * instruction: 'Consolidate observations and remove duplicates.',\n * }\n * ```\n */\n instruction?: string;\n}\n\n/**\n * Configuration for Observational Memory.\n *\n * Observational Memory is a three-tier memory system that uses an Observer agent\n * to extract observations from conversations and a Reflector agent to compress them.\n * This enables efficient long-term memory with minimal context usage.\n *\n * Can be set to `true` to enable with defaults, or an object to customize.\n *\n * @example\n * ```typescript\n * // Enable with defaults\n * observationalMemory: true\n *\n * // Custom configuration\n * observationalMemory: {\n * scope: 'resource',\n * model: 'google/gemini-2.5-flash',\n * observation: {\n * messageTokens: 20_000,\n * },\n * reflection: {\n * observationTokens: 90_000,\n * },\n * }\n * ```\n */\nexport interface ObservationalMemoryOptions {\n /**\n * Enable or disable Observational Memory.\n * When omitted, defaults to `true` (enabled).\n * Only `enabled: false` explicitly disables it.\n *\n * @default true\n */\n enabled?: boolean;\n\n /**\n * Model for both Observer and Reflector agents.\n * Sets the model for both agents at once. Cannot be used together with\n * `observation.model` or `reflection.model` — an error will be thrown.\n *\n * @default 'google/gemini-2.5-flash'\n */\n model?: AgentConfig['model'];\n\n /**\n * Observation step configuration for extracting observations from conversations.\n */\n observation?: ObservationalMemoryObservationConfig;\n\n /**\n * Reflection step configuration for compressing observations.\n */\n reflection?: ObservationalMemoryReflectionConfig;\n\n /**\n * Memory scope for observations.\n * - 'resource': Observations span all threads for a resource (cross-thread memory)\n * - 'thread': Observations are per-thread (default)\n *\n * @default 'thread'\n */\n scope?: 'resource' | 'thread';\n\n /**\n * Time before buffered observations are force-activated after inactivity.\n * Accepts milliseconds as a number, a duration string like `\"5m\"` or `\"1hr\"`,\n * or `\"auto\"` to choose a provider-aware TTL from the actor model's prompt-cache behavior.\n * When the gap between the current time and the last assistant message part's `createdAt`\n * exceeds this value, buffered observations activate regardless of whether the\n * token threshold has been reached. Useful to align with prompt cache TTLs.\n *\n * Reflections do not inherit this setting. Use `reflection.activateAfterIdle` to\n * opt reflections into idle activation.\n *\n * @example 300_000\n * @example \"5m\"\n * @example \"1hr\"\n * @example \"auto\"\n */\n activateAfterIdle?: ObservationalMemoryActivationTTL;\n\n /**\n * Force-activate buffered observations when the actor provider/model changes.\n * Useful when switching between models that do not share prompt caches.\n *\n * Reflections do not inherit this setting. Use `reflection.activateOnProviderChange`\n * to opt reflections into provider-change activation.\n */\n activateOnProviderChange?: boolean;\n\n /**\n * Share the token budget between messages and observations.\n * When true, the total budget = observation.messageTokens + reflection.observationTokens.\n * - Messages can use more space when observations are small\n * - Observations can use more space when messages are small\n *\n * This helps maximize context usage by allowing flexible allocation.\n *\n * @default false\n */\n shareTokenBudget?: boolean;\n\n /**\n * When true, inserts temporal-gap reminder markers before new user messages after\n * significant inactivity. These markers are persisted in memory and also emitted\n * as inline reminder events for clients that want to render them specially.\n *\n * @default false\n */\n temporalMarkers?: boolean;\n\n /**\n * **Experimental.** Enable retrieval-mode observation groups as durable pointers\n * to raw message history. When enabled, observation groups keep `_range`\n * metadata visible in context and a `recall` tool is registered so the actor\n * can inspect raw messages behind a stored observation summary.\n *\n * - `true` — recall tool with cross-thread browsing by default\n * - `{ vector: true }` — also enables semantic search using Memory-level vector/embedder\n * - `{ scope: 'thread' }` — restricts the recall tool to the current thread only\n * - `{ vector: true, scope: 'thread' }` — current-thread browsing + semantic search\n *\n * `scope` defaults to `'resource'` (cross-thread browsing, thread listing, and search).\n * Set to `'thread'` to restrict to the current thread only.\n *\n * @experimental\n * @default false\n */\n retrieval?: boolean | { vector?: boolean; scope?: 'thread' | 'resource' };\n}\n\n/**\n * Check if observational memory is enabled from a `boolean | ObservationalMemoryOptions` value.\n *\n * - `true` → enabled\n * - `false` → disabled\n * - `{ enabled: false }` → disabled\n * - `{ ... }` (without `enabled: false`) → enabled\n * - `undefined` → disabled\n */\nexport function isObservationalMemoryEnabled(\n config: boolean | ObservationalMemoryOptions | undefined,\n): config is true | ObservationalMemoryOptions {\n if (config === true) return true;\n if (config === false || config === undefined) return false;\n return config.enabled !== false;\n}\n\n/**\n * Configuration for memory behaviors and retrieval strategies.\n *\n * Controls three types of memory: conversation history (recent messages), semantic recall\n * (RAG-based retrieval of relevant past messages), and working memory (persistent user data).\n * All memory types are combined into a single context window for the LLM.\n *\n * @see https://mastra.ai/docs/memory/overview\n */\ntype BaseMemoryConfig = {\n /**\n * When true, prevents memory from saving new messages.\n * Useful for internal agents (like routing agents) that should read memory but not modify it.\n *\n * @default false\n * @example\n * ```typescript\n * readOnly: true // Agent can read memory but won't save new messages\n * ```\n */\n readOnly?: boolean;\n\n /**\n * Number of recent messages from the current thread to include in context.\n * Provides short-term conversational continuity.\n * Set to false to disable conversation history entirely.\n *\n * @default 10\n * @example\n * ```typescript\n * lastMessages: 5 // Include last 5 messages\n * lastMessages: false // Disable conversation history\n * ```\n */\n lastMessages?: number | false;\n\n /**\n * Semantic recall configuration for RAG-based retrieval of relevant past messages.\n * Uses vector embeddings for similarity search across conversation history.\n * Can be a boolean to enable/disable with defaults, or an object for detailed configuration.\n *\n * @default false (disabled by default)\n * @example\n * ```typescript\n * semanticRecall: false // Disable semantic recall\n * semanticRecall: {\n * topK: 5,\n * messageRange: 2,\n * scope: 'resource' // Search across all resource (user) threads\n * }\n * ```\n */\n semanticRecall?: boolean | SemanticRecall;\n\n /**\n * Working memory configuration for persistent user data and preferences.\n * Maintains a structured record (Markdown or schema-based) that agents update over time.\n * Can be thread-scoped (per conversation) or resource-scoped (across all user threads).\n *\n * @example\n * ```typescript\n * workingMemory: {\n * enabled: true,\n * scope: 'resource', // Persist across all resource (user) conversations\n * template: '# User Profile\\n- **Name**:\\n- **Preferences**:',\n * schema: z.object({\n * name: z.string(),\n * preferences: z.object({\n * communicationStyle: z.string(),\n * projectGoal: z.string(),\n * deadlines: z.array(z.string()),\n * }),\n * }),\n * }\n * ```\n */\n workingMemory?: WorkingMemory;\n\n /**\n * Observational Memory configuration for long-term memory with automatic observation and reflection.\n *\n * Uses an Observer agent to extract observations from conversations and a Reflector agent\n * to compress them when they grow too large. This enables efficient long-term memory\n * that maintains context across many conversations.\n *\n * Set to `true` to enable with defaults, `false` to disable, or an object to customize.\n *\n * @example\n * ```typescript\n * // Enable with defaults\n * observationalMemory: true\n *\n * // Custom configuration\n * observationalMemory: {\n * scope: 'resource',\n * model: 'google/gemini-2.5-flash',\n * observation: {\n * messageTokens: 20_000,\n * },\n * reflection: {\n * observationTokens: 90_000,\n * },\n * }\n * ```\n */\n observationalMemory?: boolean | ObservationalMemoryOptions;\n\n /**\n * Automatically generate descriptive thread titles based on the first user message.\n * Can be a boolean to enable with defaults, or an object to customize the model and instructions.\n * Title generation runs asynchronously and doesn't affect response time.\n *\n * @default false\n * @example\n * ```typescript\n * generateTitle: true // Use agent's model for title generation\n * generateTitle: {\n * model: openai(\"gpt-4o-mini\"),\n * instructions: \"Generate a concise title (max 5 words)\"\n * }\n * ```\n */\n generateTitle?:\n | boolean\n | {\n /**\n * Language model to use for title generation.\n * Can be static or a function that receives request context for dynamic selection.\n * Accepts both Mastra models and standard AI SDK LanguageModelV1/V2.\n */\n model: DynamicArgument;\n /**\n * Custom instructions for title generation.\n * Can be static or a function that receives request context for dynamic customization.\n */\n instructions?: DynamicArgument;\n };\n\n /**\n * Whether to filter out incomplete (suspended) tool calls when sending messages to the LLM.\n * When true, tool calls in `input-available` state are stripped from the prompt,\n * preventing the agent from seeing its own suspended tool calls in thread history.\n *\n * Set to false to allow the agent to see suspended tool calls in context.\n * This is useful for suspend/resume patterns where the agent should be aware of pending interactions.\n *\n * Note: Some providers (e.g. OpenAI) may return errors when incomplete tool calls are included.\n * Anthropic handles incomplete tool calls without issues.\n *\n * @default true\n * @example\n * ```typescript\n * filterIncompleteToolCalls: false // Keep suspended tool calls visible in context\n * ```\n */\n filterIncompleteToolCalls?: boolean;\n\n /**\n * Thread management configuration.\n * @deprecated The `threads` object is deprecated. Use top-level `generateTitle` instead of `threads.generateTitle`.\n */\n threads?: {\n /**\n * @deprecated Moved to top-level `generateTitle`. Using `threads.generateTitle` will throw an error.\n */\n generateTitle?:\n | boolean\n | {\n model: DynamicArgument;\n instructions?: DynamicArgument;\n };\n };\n};\n\nexport type MemoryConfigInternal = BaseMemoryConfig & {\n /**\n * Working memory configuration for persistent user data and preferences.\n * Maintains a structured record (Markdown or schema-based) that agents update over time.\n * Can be thread-scoped (per conversation) or resource-scoped (across all user threads).\n *\n * @example\n * ```typescript\n * workingMemory: {\n * enabled: true,\n * scope: 'resource', // Persist across all resource (user) conversations\n * template: '# User Profile\\n- **Name**:\\n- **Preferences**:',\n * schema: z.object({\n * name: z.string(),\n * preferences: z.object({\n * communicationStyle: z.string(),\n * projectGoal: z.string(),\n * deadlines: z.array(z.string()),\n * }),\n * }),\n * }\n * ```\n */\n workingMemory?: WorkingMemory;\n};\n\nexport type MemoryConfig = BaseMemoryConfig & {\n /**\n * Working memory configuration for persistent user data and preferences.\n * Maintains a structured record (Markdown or schema-based) that agents update over time.\n * Can be thread-scoped (per conversation) or resource-scoped (across all user threads).\n *\n * @example\n * ```typescript\n * workingMemory: {\n * enabled: true,\n * scope: 'resource', // Persist across all resource (user) conversations\n * template: '# User Profile\\n- **Name**:\\n- **Preferences**:',\n * schema: z.object({\n * name: z.string(),\n * preferences: z.object({\n * communicationStyle: z.string(),\n * projectGoal: z.string(),\n * deadlines: z.array(z.string()),\n * }),\n * }),\n * }\n * ```\n */\n workingMemory?: TemplateWorkingMemory | SchemaWorkingMemory | WorkingMemoryNone;\n};\n\n/**\n * Configuration for Mastra's memory system.\n *\n * Enables agents to persist and recall information across conversations using storage providers,\n * vector databases for semantic search, and processors for context management. Memory can be\n * scoped to individual threads or shared across all conversations for a resource (user).\n *\n * @see https://mastra.ai/docs/memory/overview\n */\nexport type SharedMemoryConfig = {\n /**\n * Storage adapter for persisting conversation threads, messages, and working memory.\n *\n * @example\n * ```typescript\n * storage: new LibSQLStore({ id: 'agent-memory-storage', url: \"file:./agent-memory.db\" })\n * ```\n */\n storage?: MastraCompositeStore;\n\n /**\n * Configuration for memory behaviors including conversation history, semantic recall,\n * working memory, and thread management. Controls how messages are retrieved and\n * what context is included in the LLM's prompt.\n */\n options?: MemoryConfigInternal;\n\n /**\n * Vector database for semantic recall capabilities using RAG-based search.\n * Enables retrieval of relevant messages from past conversations based on semantic similarity.\n * Set to false to disable vector search entirely.\n *\n * @example\n * ```typescript\n * vector: new PgVector({ connectionString: process.env.DATABASE_URL })\n * ```\n */\n vector?: MastraVector | false;\n\n /**\n * Embedding model for converting messages into vector representations for semantic search.\n * Compatible with any AI SDK embedding model. FastEmbed provides local embeddings,\n * while providers like OpenAI offer cloud-based models.\n *\n * Can be specified as:\n * - A string in the format \"provider/model\" (e.g., \"openai/text-embedding-3-small\")\n * - An EmbeddingModel or EmbeddingModelV2 instance\n *\n * @example\n * ```typescript\n * // Using a string (model router format)\n * embedder: \"openai/text-embedding-3-small\"\n *\n * // Using an AI SDK model directly\n * embedder: openai.embedding(\"text-embedding-3-small\")\n * ```\n */\n embedder?: EmbeddingModelId | MastraEmbeddingModel | string;\n\n /**\n * Options to pass to the embedder when generating embeddings.\n * Use this to pass provider-specific options like outputDimensionality for Google models.\n *\n * @example\n * ```typescript\n * // Control embedding dimensions for Google models\n * embedderOptions: {\n * providerOptions: {\n * google: {\n * outputDimensionality: 768,\n * taskType: 'RETRIEVAL_DOCUMENT'\n * }\n * }\n * }\n * ```\n */\n embedderOptions?: MastraEmbeddingOptions;\n\n /**\n * @deprecated This option is deprecated and will throw an error if used.\n * Use the new Input/Output processor system instead.\n *\n * See: https://mastra.ai/en/docs/memory/processors\n *\n * @example\n * ```typescript\n * // OLD (throws error):\n * new Memory({\n * processors: [new TokenLimiter(100000)]\n * })\n *\n * // NEW (use this):\n * new Agent({\n * memory,\n * outputProcessors: [new TokenLimiterProcessor(100000)]\n * })\n * ```\n */\n processors?: MemoryProcessor[];\n};\n\n/** @deprecated Use the `format` field on `WorkingMemoryTemplate` discriminated union instead. */\nexport type WorkingMemoryFormat = 'json' | 'markdown';\n\nexport type WorkingMemoryTemplate =\n | { format: 'markdown'; content: string }\n | { format: 'json'; content: string | Record };\n\n// Type for flexible message deletion input\nexport type MessageDeleteInput = string[] | { id: string }[];\n\n/**\n * Serialized memory configuration that can be stored in the database\n * This is a subset of SharedMemoryConfig with serializable types only\n */\nexport type SerializedMemoryConfig = {\n /**\n * Vector database identifier. The vector instance should be registered\n * with the Mastra instance to resolve from this ID.\n * Set to false to disable vector search entirely.\n */\n vector?: string | false;\n\n /**\n * Configuration for memory behaviors, omitting WorkingMemory and threads\n */\n options?: {\n /** Treat memory as read-only (no new messages stored) */\n readOnly?: boolean;\n\n /** Number of recent messages to include, or false to disable */\n lastMessages?: number | false;\n\n /** Semantic recall configuration */\n semanticRecall?: boolean | SemanticRecall;\n\n /** Title generation configuration (serialized form) */\n generateTitle?:\n | boolean\n | {\n /** Model ID in format provider/model-name */\n model: ModelRouterModelId;\n /** Custom instructions for title generation */\n instructions?: string;\n };\n };\n\n /**\n * Embedding model ID in the format \"provider/model\"\n * (e.g., \"openai/text-embedding-3-small\")\n * Can be a predefined EmbeddingModelId or a custom string\n */\n embedder?: EmbeddingModelId | string;\n\n /**\n * Options to pass to the embedder, omitting telemetry\n */\n embedderOptions?: Omit;\n\n /**\n * Serialized observational memory configuration.\n * `true` to enable with defaults, or a config object for customization.\n * Only JSON-safe fields are included (model IDs as strings, numeric/boolean settings).\n */\n observationalMemory?: boolean | SerializedObservationalMemoryConfig;\n};\n\n/**\n * JSON-serializable subset of ObservationalMemoryOptions for storage.\n * Model references are stored as string IDs (e.g., \"google/gemini-2.5-flash\").\n */\nexport type SerializedObservationalMemoryConfig = {\n /** Model ID for both Observer and Reflector (e.g., \"google/gemini-2.5-flash\") */\n model?: string;\n\n /** Memory scope: 'resource' or 'thread' */\n scope?: 'resource' | 'thread';\n\n /** Inactivity TTL before forcing buffered observation activation */\n activateAfterIdle?: ObservationalMemoryActivationTTL;\n\n /** Force-activate buffered observation activation when the actor model changes */\n activateOnProviderChange?: boolean;\n\n /** Share the token budget between messages and observations */\n shareTokenBudget?: boolean;\n\n /** Persist inline temporal gap markers for long pauses between messages */\n temporalMarkers?: boolean;\n\n /**\n * **Experimental.** Enable retrieval-mode observation groups as durable pointers to raw message history.\n * @experimental\n */\n retrieval?: boolean | { vector?: boolean; scope?: 'thread' | 'resource' };\n\n /** Observation step configuration */\n observation?: SerializedObservationalMemoryObservationConfig;\n\n /** Reflection step configuration */\n reflection?: SerializedObservationalMemoryReflectionConfig;\n};\n\n/** Serializable subset of ObservationalMemoryObservationConfig */\nexport type SerializedObservationalMemoryObservationConfig = {\n /** Observer model ID */\n model?: string;\n /** Token count threshold that triggers observation */\n messageTokens?: number;\n /** Model settings (temperature, maxOutputTokens, etc.) */\n modelSettings?: Record;\n /** Provider-specific options */\n providerOptions?: Record | undefined>;\n /** Maximum tokens per batch */\n maxTokensPerBatch?: number;\n /** Token interval for async buffering, or false to disable */\n bufferTokens?: number | false;\n /** Ratio of buffered observations to activate */\n bufferActivation?: number;\n /** Inactivity TTL before forcing buffered observation activation */\n activateAfterIdle?: ObservationalMemoryActivationTTL;\n /** Force-activate buffered observation activation when the actor model changes */\n activateOnProviderChange?: boolean;\n /** Token threshold for synchronous blocking */\n blockAfter?: number;\n /** Optional token budget for observer context (0 = full truncation, false = disabled) */\n previousObserverTokens?: number | false;\n /** Whether the Observer should suggest thread titles */\n threadTitle?: boolean;\n /** Whether image/file attachment parts are forwarded to the Observer LLM */\n observeAttachments?: 'auto' | boolean;\n};\n\n/** Serializable subset of ObservationalMemoryReflectionConfig */\nexport type SerializedObservationalMemoryReflectionConfig = {\n /** Reflector model ID */\n model?: string;\n /** Token count threshold that triggers reflection */\n observationTokens?: number;\n /** Model settings (temperature, maxOutputTokens, etc.) */\n modelSettings?: Record;\n /** Provider-specific options */\n providerOptions?: Record | undefined>;\n /** Token threshold for synchronous blocking */\n blockAfter?: number;\n /** Inactivity TTL before forcing buffered reflection activation */\n activateAfterIdle?: ObservationalMemoryActivationTTL;\n /** Force-activate buffered reflection activation when the actor model changes */\n activateOnProviderChange?: boolean;\n /** Ratio for async reflection buffering */\n bufferActivation?: number;\n};\n","import type { MastraMemory } from '../memory/memory';\nimport type { MemoryConfigInternal, StorageThreadType } from '../memory/types';\nimport type { MessageList } from './message-list';\nimport type { MastraDBMessage } from './message-list/state/types';\nimport { createSignal, mastraDBMessageToSignal } from './signals';\nimport type { AgentStateSignalInput, CreatedAgentSignal } from './signals';\n\nfunction isPlainObject(value: unknown): value is Record {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nexport type StateSignalTracking = {\n currentCacheKey?: string;\n currentMode?: 'snapshot' | 'delta';\n version?: number;\n lastSignalId?: string;\n lastSnapshotSignalId?: string;\n updatedAt?: string;\n activeCopies?: Array<{ id: string; cacheKey?: string; mode?: 'snapshot' | 'delta'; version?: number }>;\n};\n\nexport type ActiveStateSignal = CreatedAgentSignal & {\n type: 'state';\n metadata?: Record & {\n state?: {\n id?: string;\n threadId?: string;\n cacheKey?: string;\n version?: number;\n mode?: 'snapshot' | 'delta';\n };\n };\n};\n\nexport type StateSignalHistory = {\n activeStateSignals: ActiveStateSignal[];\n contextWindow: {\n hasSnapshot: boolean;\n };\n lastSnapshot?: ActiveStateSignal;\n deltasSinceSnapshot: ActiveStateSignal[];\n};\n\nexport type ApplyStateSignalResult =\n | { skipped: true; reason: 'unchanged'; stateId: string; tracking?: StateSignalTracking }\n | { skipped: false; signal: CreatedAgentSignal; stateId: string; version: number; tracking: StateSignalTracking };\n\nexport function getStateSignalsMetadata(threadMetadata?: Record): Record {\n if (!threadMetadata) return {};\n const mastra = threadMetadata.mastra;\n if (!isPlainObject(mastra)) return {};\n const stateSignals = mastra.stateSignals;\n return isPlainObject(stateSignals) ? (stateSignals as Record) : {};\n}\n\nexport function setStateSignalMetadata(\n threadMetadata: Record | undefined,\n stateId: string,\n tracking: StateSignalTracking,\n): Record {\n const existing = threadMetadata ?? {};\n const existingMastra = isPlainObject(existing.mastra) ? existing.mastra : {};\n const existingStateSignals = isPlainObject(existingMastra.stateSignals) ? existingMastra.stateSignals : {};\n\n return {\n ...existing,\n mastra: {\n ...existingMastra,\n stateSignals: {\n ...existingStateSignals,\n [stateId]: tracking,\n },\n },\n };\n}\n\nfunction signalCreatedAt(signal: ActiveStateSignal): number {\n const createdAt = signal.createdAt instanceof Date ? signal.createdAt : new Date(signal.createdAt);\n const timestamp = createdAt.getTime();\n return Number.isNaN(timestamp) ? 0 : timestamp;\n}\n\nexport function sortStateSignals(signals: ActiveStateSignal[]): ActiveStateSignal[] {\n return signals\n .map((signal, index) => ({ signal, index }))\n .sort((left, right) => signalCreatedAt(left.signal) - signalCreatedAt(right.signal) || left.index - right.index)\n .map(({ signal }) => signal);\n}\n\nexport function dbMessagesToStateSignals(\n messages: MastraDBMessage[],\n stateId: string | undefined,\n threadId: string,\n): ActiveStateSignal[] {\n return sortStateSignals(\n messages\n .filter(message => message.role === 'signal')\n .map(message => {\n try {\n return mastraDBMessageToSignal(message);\n } catch {\n return undefined;\n }\n })\n .filter(\n (signal): signal is ActiveStateSignal =>\n signal?.type === 'state' &&\n isPlainObject(signal.metadata?.state) &&\n (!stateId || signal.metadata.state.id === stateId) &&\n signal.metadata.state.threadId === threadId,\n ),\n );\n}\n\nexport function getActiveStateSignals(\n messageList: MessageList,\n stateId: string | undefined,\n threadId: string,\n): ActiveStateSignal[] {\n return dbMessagesToStateSignals(messageList.get.all.db(), stateId, threadId);\n}\n\nexport function mergeStateSignals(...signalGroups: ActiveStateSignal[][]): ActiveStateSignal[] {\n const signalsById = new Map();\n for (const signal of signalGroups.flat()) {\n signalsById.set(signal.id, signal);\n }\n return sortStateSignals([...signalsById.values()]);\n}\n\nexport function deriveStateSignalHistory(activeStateSignals: ActiveStateSignal[]): StateSignalHistory {\n const sortedStateSignals = sortStateSignals(activeStateSignals);\n const lastSnapshotIndex = sortedStateSignals.findLastIndex(signal => signal.metadata?.state?.mode === 'snapshot');\n const lastSnapshot = lastSnapshotIndex >= 0 ? sortedStateSignals[lastSnapshotIndex] : undefined;\n const deltasSinceSnapshot = sortedStateSignals\n .slice(lastSnapshotIndex + 1)\n .filter(signal => signal.metadata?.state?.mode === 'delta');\n\n return {\n activeStateSignals: sortedStateSignals,\n contextWindow: {\n hasSnapshot: Boolean(lastSnapshot),\n },\n lastSnapshot,\n deltasSinceSnapshot,\n };\n}\n\nexport async function resolveStateSignalHistory({\n messageList,\n memory,\n threadId,\n stateId,\n tracking,\n}: {\n messageList: MessageList;\n memory: MastraMemory;\n threadId: string;\n stateId: string;\n tracking?: StateSignalTracking;\n}): Promise {\n const localStateSignals = getActiveStateSignals(messageList, stateId, threadId);\n const localHistory = deriveStateSignalHistory(localStateSignals);\n const contextWindow = localHistory.contextWindow;\n\n if (localHistory.contextWindow.hasSnapshot || !tracking?.lastSnapshotSignalId) {\n return { ...localHistory, contextWindow };\n }\n\n const memoryStore = await memory.storage.getStore('memory');\n if (!memoryStore) return { ...localHistory, contextWindow };\n\n const trackedSignalIds = new Set();\n for (const activeCopy of tracking.activeCopies ?? []) {\n trackedSignalIds.add(activeCopy.id);\n }\n trackedSignalIds.add(tracking.lastSnapshotSignalId);\n\n if (trackedSignalIds.size === 0 || typeof memoryStore.listMessagesById !== 'function') {\n return { ...localHistory, contextWindow };\n }\n\n const storedMessages = await memoryStore.listMessagesById({ messageIds: [...trackedSignalIds] });\n const storedStateSignals = dbMessagesToStateSignals(storedMessages.messages, stateId, threadId);\n const resolvedStateSignals = mergeStateSignals(storedStateSignals, localStateSignals);\n\n return {\n ...deriveStateSignalHistory(resolvedStateSignals.length > 0 ? resolvedStateSignals : localStateSignals),\n contextWindow,\n };\n}\n\nexport function createStateSignalInput(\n input: AgentStateSignalInput | (Omit & { id?: string }),\n options?: { defaultId?: string; acceptedAt?: Date },\n): { stateId: string; signal: CreatedAgentSignal; mode: 'snapshot' | 'delta'; cacheKey: string } {\n const stateId = input.id ?? options?.defaultId;\n if (!stateId) {\n throw new Error('state signal id is required');\n }\n if (!input.cacheKey) {\n throw new Error('state signal cacheKey is required');\n }\n\n const mode = input.mode ?? 'snapshot';\n const { id: _stateId, cacheKey, mode: _mode, value, delta, metadata, ...signalInput } = input;\n const signal = createSignal({\n ...signalInput,\n type: 'state',\n tagName: signalInput.tagName ?? 'state',\n acceptedAt: options?.acceptedAt,\n metadata: {\n ...metadata,\n state: {\n ...(isPlainObject(metadata?.state) ? metadata.state : {}),\n id: stateId,\n cacheKey,\n mode,\n },\n ...(value !== undefined ? { value } : {}),\n ...(delta !== undefined ? { delta } : {}),\n },\n });\n\n return { stateId, signal, mode, cacheKey };\n}\n\nexport async function applyStateSignal({\n input,\n memory,\n thread,\n resourceId,\n threadId,\n memoryConfig,\n messageList,\n activeStateSignals,\n defaultId,\n acceptedAt,\n beforeAddSignal,\n writeSignal,\n}: {\n input: AgentStateSignalInput | (Omit & { id?: string });\n memory: MastraMemory;\n thread: StorageThreadType;\n resourceId: string;\n threadId: string;\n memoryConfig?: MemoryConfigInternal;\n messageList?: MessageList;\n activeStateSignals?: ActiveStateSignal[];\n defaultId?: string;\n acceptedAt?: Date;\n beforeAddSignal?: () => void;\n writeSignal?: (signal: CreatedAgentSignal) => Promise | void;\n}): Promise {\n const { stateId, signal, cacheKey, mode } = createStateSignalInput(input, { defaultId, acceptedAt });\n const activeSignals =\n activeStateSignals ?? (messageList ? getActiveStateSignals(messageList, stateId, threadId) : []);\n const tracking = getStateSignalsMetadata(thread.metadata)[stateId];\n\n const usesActiveWindow = Boolean(messageList || activeStateSignals);\n const hasActiveCopy = activeSignals.some(\n signal => signal.metadata?.state?.cacheKey === cacheKey && signal.metadata?.state?.mode === mode,\n );\n const matchesCurrentState =\n tracking?.currentCacheKey === cacheKey &&\n (tracking.currentMode === mode || (!tracking.currentMode && hasActiveCopy));\n if (matchesCurrentState && (!usesActiveWindow || hasActiveCopy)) {\n return { skipped: true, reason: 'unchanged', stateId, tracking };\n }\n\n const previousVersion = typeof tracking?.version === 'number' ? tracking.version : 0;\n const version = matchesCurrentState ? previousVersion || 1 : previousVersion + 1;\n const updatedSignal = createSignal({\n ...signal,\n metadata: {\n ...signal.metadata,\n state: {\n ...(isPlainObject(signal.metadata?.state) ? signal.metadata.state : {}),\n id: stateId,\n threadId,\n cacheKey,\n version,\n mode,\n },\n },\n });\n\n beforeAddSignal?.();\n if (messageList) {\n messageList.addSignal(updatedSignal);\n }\n await writeSignal?.(updatedSignal);\n\n const updatedAt = new Date().toISOString();\n const updatedActiveSignals = [...activeSignals, updatedSignal];\n const nextTracking: StateSignalTracking = {\n currentCacheKey: cacheKey,\n currentMode: mode,\n version,\n lastSignalId: updatedSignal.id,\n lastSnapshotSignalId: mode === 'snapshot' ? updatedSignal.id : tracking?.lastSnapshotSignalId,\n updatedAt,\n activeCopies: updatedActiveSignals.map(activeSignal => {\n const activeStateMetadata = isPlainObject(activeSignal.metadata?.state) ? activeSignal.metadata.state : {};\n return {\n id: activeSignal.id,\n ...(typeof activeStateMetadata.cacheKey === 'string' ? { cacheKey: activeStateMetadata.cacheKey } : {}),\n ...(activeStateMetadata.mode === 'snapshot' || activeStateMetadata.mode === 'delta'\n ? { mode: activeStateMetadata.mode }\n : {}),\n ...(typeof activeStateMetadata.version === 'number' ? { version: activeStateMetadata.version } : {}),\n };\n }),\n };\n\n await memory.saveThread({\n thread: {\n ...thread,\n id: threadId,\n resourceId: thread.resourceId ?? resourceId,\n createdAt: thread.createdAt ?? new Date(),\n updatedAt: new Date(updatedAt),\n metadata: setStateSignalMetadata(thread.metadata, stateId, nextTracking),\n },\n memoryConfig,\n });\n\n return { skipped: false, signal: updatedSignal, stateId, version, tracking: nextTracking };\n}\n"]}