{"version":3,"sources":["../src/memory/types.ts","../src/agent/state-signals.ts"],"names":["isPlainObject","mastraDBMessageToSignal","createSignal","signal"],"mappings":"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","file":"chunk-DGHXXCUH.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<string, unknown>[];\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<string, unknown>;\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<string, unknown> {\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<string, unknown>): 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<string, unknown> | undefined,\n  omMetadata: ThreadOMMetadata,\n): Record<string, unknown> {\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<StorageThreadType> & { 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<string, unknown>;\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<string, unknown>;\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<T extends 'raw' | 'core_message'> = {\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<BaseWorkingMemory, 'useStateSignals'> & {\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<string, Record<string, unknown> | 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<string, Record<string, unknown> | 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<MastraModelConfig>;\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<string>;\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<MastraModelConfig>;\n          instructions?: DynamicArgument<string>;\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> | 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<string, unknown> };\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<MastraEmbeddingOptions, 'telemetry'>;\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<string, unknown>;\n  /** Provider-specific options */\n  providerOptions?: Record<string, Record<string, unknown> | 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<string, unknown>;\n  /** Provider-specific options */\n  providerOptions?: Record<string, Record<string, unknown> | 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<string, unknown> {\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<string, unknown> & {\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<string, unknown>): Record<string, StateSignalTracking> {\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<string, StateSignalTracking>) : {};\n}\n\nexport function setStateSignalMetadata(\n  threadMetadata: Record<string, unknown> | undefined,\n  stateId: string,\n  tracking: StateSignalTracking,\n): Record<string, unknown> {\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<string, ActiveStateSignal>();\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  resourceId,\n  stateId,\n  tracking,\n}: {\n  messageList: MessageList;\n  memory: MastraMemory;\n  threadId: string;\n  resourceId: string;\n  stateId: string;\n  tracking?: StateSignalTracking;\n}): Promise<StateSignalHistory> {\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 storedMessages = await memoryStore.listMessages({\n    threadId,\n    resourceId,\n    perPage: false,\n    orderBy: { field: 'createdAt', direction: 'ASC' },\n  });\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<AgentStateSignalInput, 'id'> & { 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  writeSignal,\n}: {\n  input: AgentStateSignalInput | (Omit<AgentStateSignalInput, 'id'> & { 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  writeSignal?: (signal: CreatedAgentSignal) => Promise<void> | void;\n}): Promise<ApplyStateSignalResult> {\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  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"]}