@mastra/memory 1.5.1 → 1.5.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +28 -0
- package/dist/{chunk-6PKWQ3GH.js → chunk-HNPAIFCZ.js} +59 -16
- package/dist/chunk-HNPAIFCZ.js.map +1 -0
- package/dist/{chunk-6XVTMLW4.cjs → chunk-PVFLHAZX.cjs} +59 -16
- package/dist/chunk-PVFLHAZX.cjs.map +1 -0
- package/dist/docs/SKILL.md +55 -0
- package/dist/docs/assets/SOURCE_MAP.json +103 -0
- package/dist/docs/references/docs-agents-agent-approval.md +558 -0
- package/dist/docs/references/docs-agents-agent-memory.md +209 -0
- package/dist/docs/references/docs-agents-network-approval.md +275 -0
- package/dist/docs/references/docs-agents-networks.md +299 -0
- package/dist/docs/references/docs-agents-supervisor-agents.md +304 -0
- package/dist/docs/references/docs-memory-memory-processors.md +314 -0
- package/dist/docs/references/docs-memory-message-history.md +260 -0
- package/dist/docs/references/docs-memory-observational-memory.md +248 -0
- package/dist/docs/references/docs-memory-overview.md +45 -0
- package/dist/docs/references/docs-memory-semantic-recall.md +272 -0
- package/dist/docs/references/docs-memory-storage.md +261 -0
- package/dist/docs/references/docs-memory-working-memory.md +400 -0
- package/dist/docs/references/reference-core-getMemory.md +50 -0
- package/dist/docs/references/reference-core-listMemory.md +56 -0
- package/dist/docs/references/reference-memory-clone-utilities.md +199 -0
- package/dist/docs/references/reference-memory-cloneThread.md +130 -0
- package/dist/docs/references/reference-memory-createThread.md +68 -0
- package/dist/docs/references/reference-memory-getThreadById.md +24 -0
- package/dist/docs/references/reference-memory-listThreads.md +145 -0
- package/dist/docs/references/reference-memory-memory-class.md +147 -0
- package/dist/docs/references/reference-memory-observational-memory.md +565 -0
- package/dist/docs/references/reference-processors-token-limiter-processor.md +115 -0
- package/dist/docs/references/reference-storage-dynamodb.md +282 -0
- package/dist/docs/references/reference-storage-libsql.md +135 -0
- package/dist/docs/references/reference-storage-mongodb.md +262 -0
- package/dist/docs/references/reference-storage-postgresql.md +526 -0
- package/dist/docs/references/reference-storage-upstash.md +160 -0
- package/dist/docs/references/reference-vectors-libsql.md +305 -0
- package/dist/docs/references/reference-vectors-mongodb.md +295 -0
- package/dist/docs/references/reference-vectors-pg.md +408 -0
- package/dist/docs/references/reference-vectors-upstash.md +294 -0
- package/dist/index.cjs +1 -1
- package/dist/index.js +1 -1
- package/dist/{observational-memory-AJWSMZVP.js → observational-memory-KAFD4QZK.js} +3 -3
- package/dist/{observational-memory-AJWSMZVP.js.map → observational-memory-KAFD4QZK.js.map} +1 -1
- package/dist/{observational-memory-Q5TO525O.cjs → observational-memory-Q47HN5YL.cjs} +17 -17
- package/dist/{observational-memory-Q5TO525O.cjs.map → observational-memory-Q47HN5YL.cjs.map} +1 -1
- package/dist/processors/index.cjs +15 -15
- package/dist/processors/index.js +1 -1
- package/dist/processors/observational-memory/observational-memory.d.ts +2 -2
- package/dist/processors/observational-memory/observational-memory.d.ts.map +1 -1
- package/dist/processors/observational-memory/token-counter.d.ts.map +1 -1
- package/package.json +8 -8
- package/dist/chunk-6PKWQ3GH.js.map +0 -1
- package/dist/chunk-6XVTMLW4.cjs.map +0 -1
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/processors/observational-memory/observer-agent.ts","../src/processors/observational-memory/reflector-agent.ts","../src/processors/observational-memory/token-counter.ts","../src/processors/observational-memory/observational-memory.ts"],"names":["result"],"mappings":"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","file":"chunk-6PKWQ3GH.js","sourcesContent":["import type { MastraDBMessage } from '@mastra/core/agent';\n\n/**\n * The core extraction instructions for the Observer.\n * This is exported so the Reflector can understand how observations were created.\n */\nexport const OBSERVER_EXTRACTION_INSTRUCTIONS = `CRITICAL: DISTINGUISH USER ASSERTIONS FROM QUESTIONS\n\nWhen the user TELLS you something about themselves, mark it as an assertion:\n- \"I have two kids\" → 🔴 (14:30) User stated has two kids\n- \"I work at Acme Corp\" → 🔴 (14:31) User stated works at Acme Corp\n- \"I graduated in 2019\" → 🔴 (14:32) User stated graduated in 2019\n\nWhen the user ASKS about something, mark it as a question/request:\n- \"Can you help me with X?\" → 🔴 (15:00) User asked help with X\n- \"What's the best way to do Y?\" → 🔴 (15:01) User asked best way to do Y\n\nDistinguish between QUESTIONS and STATEMENTS OF INTENT:\n- \"Can you recommend...\" → Question (extract as \"User asked...\")\n- \"I'm looking forward to [doing X]\" → Statement of intent (extract as \"User stated they will [do X] (include estimated/actual date if mentioned)\")\n- \"I need to [do X]\" → Statement of intent (extract as \"User stated they need to [do X] (again, add date if mentioned)\")\n\nSTATE CHANGES AND UPDATES:\nWhen a user indicates they are changing something, frame it as a state change that supersedes previous information:\n- \"I'm going to start doing X instead of Y\" → \"User will start doing X (changing from Y)\"\n- \"I'm switching from A to B\" → \"User is switching from A to B\"\n- \"I moved my stuff to the new place\" → \"User moved their stuff to the new place (no longer at previous location)\"\n\nIf the new state contradicts or updates previous information, make that explicit:\n- BAD: \"User plans to use the new method\"\n- GOOD: \"User will use the new method (replacing the old approach)\"\n\nThis helps distinguish current state from outdated information.\n\nUSER ASSERTIONS ARE AUTHORITATIVE. The user is the source of truth about their own life.\nIf a user previously stated something and later asks a question about the same topic,\nthe assertion is the answer - the question doesn't invalidate what they already told you.\n\nTEMPORAL ANCHORING:\nEach observation has TWO potential timestamps:\n\n1. BEGINNING: The time the statement was made (from the message timestamp) - ALWAYS include this\n2. END: The time being REFERENCED, if different from when it was said - ONLY when there's a relative time reference\n\nONLY add \"(meaning DATE)\" or \"(estimated DATE)\" at the END when you can provide an ACTUAL DATE:\n- Past: \"last week\", \"yesterday\", \"a few days ago\", \"last month\", \"in March\"\n- Future: \"this weekend\", \"tomorrow\", \"next week\"\n\nDO NOT add end dates for:\n- Present-moment statements with no time reference\n- Vague references like \"recently\", \"a while ago\", \"lately\", \"soon\" - these cannot be converted to actual dates\n\nFORMAT:\n- With time reference: (TIME) [observation]. (meaning/estimated DATE)\n- Without time reference: (TIME) [observation].\n\nGOOD: (09:15) User's friend had a birthday party in March. (meaning March 20XX)\n ^ References a past event - add the referenced date at the end\n\nGOOD: (09:15) User will visit their parents this weekend. (meaning June 17-18, 20XX)\n ^ References a future event - add the referenced date at the end\n\nGOOD: (09:15) User prefers hiking in the mountains.\n ^ Present-moment preference, no time reference - NO end date needed\n\nGOOD: (09:15) User is considering adopting a dog.\n ^ Present-moment thought, no time reference - NO end date needed\n\nBAD: (09:15) User prefers hiking in the mountains. (meaning June 15, 20XX - today)\n ^ No time reference in the statement - don't repeat the message timestamp at the end\n\nIMPORTANT: If an observation contains MULTIPLE events, split them into SEPARATE observation lines.\nEACH split observation MUST have its own date at the end - even if they share the same time context.\n\nExamples (assume message is from June 15, 20XX):\n\nBAD: User will visit their parents this weekend (meaning June 17-18, 20XX) and go to the dentist tomorrow.\nGOOD (split into two observations, each with its date):\n User will visit their parents this weekend. (meaning June 17-18, 20XX)\n User will go to the dentist tomorrow. (meaning June 16, 20XX)\n\nBAD: User needs to clean the garage this weekend and is looking forward to setting up a new workbench.\nGOOD (split, BOTH get the same date since they're related):\n User needs to clean the garage this weekend. (meaning June 17-18, 20XX)\n User will set up a new workbench this weekend. (meaning June 17-18, 20XX)\n\nBAD: User was given a gift by their friend (estimated late May 20XX) last month.\nGOOD: (09:15) User was given a gift by their friend last month. (estimated late May 20XX)\n ^ Message time at START, relative date reference at END - never in the middle\n\nBAD: User started a new job recently and will move to a new apartment next week.\nGOOD (split):\n User started a new job recently.\n User will move to a new apartment next week. (meaning June 21-27, 20XX)\n ^ \"recently\" is too vague for a date - omit the end date. \"next week\" can be calculated.\n\nALWAYS put the date at the END in parentheses - this is critical for temporal reasoning.\nWhen splitting related events that share the same time context, EACH observation must have the date.\n\nPRESERVE UNUSUAL PHRASING:\nWhen the user uses unexpected or non-standard terminology, quote their exact words.\n\nBAD: User exercised.\nGOOD: User stated they did a \"movement session\" (their term for exercise).\n\nUSE PRECISE ACTION VERBS:\nReplace vague verbs like \"getting\", \"got\", \"have\" with specific action verbs that clarify the nature of the action.\nIf the assistant confirms or clarifies the user's action, use the assistant's more precise language.\n\nBAD: User is getting X.\nGOOD: User subscribed to X. (if context confirms recurring delivery)\nGOOD: User purchased X. (if context confirms one-time acquisition)\n\nBAD: User got something.\nGOOD: User purchased / received / was given something. (be specific)\n\nCommon clarifications:\n- \"getting\" something regularly → \"subscribed to\" or \"enrolled in\"\n- \"getting\" something once → \"purchased\" or \"acquired\"\n- \"got\" → \"purchased\", \"received as gift\", \"was given\", \"picked up\"\n- \"signed up\" → \"enrolled in\", \"registered for\", \"subscribed to\"\n- \"stopped getting\" → \"canceled\", \"unsubscribed from\", \"discontinued\"\n\nWhen the assistant interprets or confirms the user's vague language, prefer the assistant's precise terminology.\n\nPRESERVING DETAILS IN ASSISTANT-GENERATED CONTENT:\n\nWhen the assistant provides lists, recommendations, or creative content that the user explicitly requested,\npreserve the DISTINGUISHING DETAILS that make each item unique and queryable later.\n\n1. RECOMMENDATION LISTS - Preserve the key attribute that distinguishes each item:\n BAD: Assistant recommended 5 hotels in the city.\n GOOD: Assistant recommended hotels: Hotel A (near the train station), Hotel B (budget-friendly), \n Hotel C (has rooftop pool), Hotel D (pet-friendly), Hotel E (historic building).\n \n BAD: Assistant listed 3 online stores for craft supplies.\n GOOD: Assistant listed craft stores: Store A (based in Germany, ships worldwide), \n Store B (specializes in vintage fabrics), Store C (offers bulk discounts).\n\n2. NAMES, HANDLES, AND IDENTIFIERS - Always preserve specific identifiers:\n BAD: Assistant provided social media accounts for several photographers.\n GOOD: Assistant provided photographer accounts: @photographer_one (portraits), \n @photographer_two (landscapes), @photographer_three (nature).\n \n BAD: Assistant listed some authors to check out.\n GOOD: Assistant recommended authors: Jane Smith (mystery novels), \n Bob Johnson (science fiction), Maria Garcia (historical romance).\n\n3. CREATIVE CONTENT - Preserve structure and key sequences:\n BAD: Assistant wrote a poem with multiple verses.\n GOOD: Assistant wrote a 3-verse poem. Verse 1 theme: loss. Verse 2 theme: hope. \n Verse 3 theme: renewal. Refrain: \"The light returns.\"\n \n BAD: User shared their lucky numbers from a fortune cookie.\n GOOD: User's fortune cookie lucky numbers: 7, 14, 23, 38, 42, 49.\n\n4. TECHNICAL/NUMERICAL RESULTS - Preserve specific values:\n BAD: Assistant explained the performance improvements from the optimization.\n GOOD: Assistant explained the optimization achieved 43.7% faster load times \n and reduced memory usage from 2.8GB to 940MB.\n \n BAD: Assistant provided statistics about the dataset.\n GOOD: Assistant provided dataset stats: 7,342 samples, 89.6% accuracy, \n 23ms average inference time.\n\n5. QUANTITIES AND COUNTS - Always preserve how many of each item:\n BAD: Assistant listed items with details but no quantities.\n GOOD: Assistant listed items: Item A (4 units, size large), Item B (2 units, size small).\n \n When listing items with attributes, always include the COUNT first before other details.\n\n6. ROLE/PARTICIPATION STATEMENTS - When user mentions their role at an event:\n BAD: User attended the company event.\n GOOD: User was a presenter at the company event.\n \n BAD: User went to the fundraiser.\n GOOD: User volunteered at the fundraiser (helped with registration).\n \n Always capture specific roles: presenter, organizer, volunteer, team lead, \n coordinator, participant, contributor, helper, etc.\n\nCONVERSATION CONTEXT:\n- What the user is working on or asking about\n- Previous topics and their outcomes\n- What user understands or needs clarification on\n- Specific requirements or constraints mentioned\n- Contents of assistant learnings and summaries\n- Answers to users questions including full context to remember detailed summaries and explanations\n- Assistant explanations, especially complex ones. observe the fine details so that the assistant does not forget what they explained\n- Relevant code snippets\n- User preferences (like favourites, dislikes, preferences, etc)\n- Any specifically formatted text or ascii that would need to be reproduced or referenced in later interactions (preserve these verbatim in memory)\n- Sequences, units, measurements, and any kind of specific relevant data\n- Any blocks of any text which the user and assistant are iteratively collaborating back and forth on should be preserved verbatim\n- When who/what/where/when is mentioned, note that in the observation. Example: if the user received went on a trip with someone, observe who that someone was, where the trip was, when it happened, and what happened, not just that the user went on the trip.\n- For any described entity (like a person, place, thing, etc), preserve the attributes that would help identify or describe the specific entity later: location (\"near X\"), specialty (\"focuses on Y\"), unique feature (\"has Z\"), relationship (\"owned by W\"), or other details. The entity's name is important, but so are any additional details that distinguish it. If there are a list of entities, preserve these details for each of them.\n\nUSER MESSAGE CAPTURE:\n- Short and medium-length user messages should be captured nearly verbatim in your own words.\n- For very long user messages, summarize but quote key phrases that carry specific intent or meaning.\n- This is critical for continuity: when the conversation window shrinks, the observations are the only record of what the user said.\n\nAVOIDING REPETITIVE OBSERVATIONS:\n- Do NOT repeat the same observation across multiple turns if there is no new information.\n- When the agent performs repeated similar actions (e.g., browsing files, running the same tool type multiple times), group them into a single parent observation with sub-bullets for each new result.\n\nExample — BAD (repetitive):\n* 🟡 (14:30) Agent used view tool on src/auth.ts\n* 🟡 (14:31) Agent used view tool on src/users.ts\n* 🟡 (14:32) Agent used view tool on src/routes.ts\n\nExample — GOOD (grouped):\n* 🟡 (14:30) Agent browsed source files for auth flow\n * -> viewed src/auth.ts — found token validation logic\n * -> viewed src/users.ts — found user lookup by email\n * -> viewed src/routes.ts — found middleware chain\n\nOnly add a new observation for a repeated action if the NEW result changes the picture.\n\nACTIONABLE INSIGHTS:\n- What worked well in explanations\n- What needs follow-up or clarification\n- User's stated goals or next steps (note if the user tells you not to do a next step, or asks for something specific, other next steps besides the users request should be marked as \"waiting for user\", unless the user explicitly says to continue all next steps)`;\n\n/**\n * The output format instructions for the Observer.\n * This is exported so the Reflector can use the same format.\n */\n\n/**\n * Base output format for Observer (without patterns section)\n */\nexport const OBSERVER_OUTPUT_FORMAT_BASE = `Use priority levels:\n- 🔴 High: explicit user facts, preferences, goals achieved, critical context\n- 🟡 Medium: project details, learned information, tool results\n- 🟢 Low: minor details, uncertain observations\n\nGroup related observations (like tool sequences) by indenting:\n* 🔴 (14:33) Agent debugging auth issue\n * -> ran git status, found 3 modified files\n * -> viewed auth.ts:45-60, found missing null check\n * -> applied fix, tests now pass\n\nGroup observations by date, then list each with 24-hour time.\n\n<observations>\nDate: Dec 4, 2025\n* 🔴 (14:30) User prefers direct answers\n* 🔴 (14:31) Working on feature X\n* 🟡 (14:32) User might prefer dark mode\n\nDate: Dec 5, 2025\n* 🔴 (09:15) Continued work on feature X\n</observations>\n\n<current-task>\nState the current task(s) explicitly. Can be single or multiple:\n- Primary: What the agent is currently working on\n- Secondary: Other pending tasks (mark as \"waiting for user\" if appropriate)\n\nIf the agent started doing something without user approval, note that it's off-task.\n</current-task>\n\n<suggested-response>\nHint for the agent's immediate next message. Examples:\n- \"I've updated the navigation model. Let me walk you through the changes...\"\n- \"The assistant should wait for the user to respond before continuing.\"\n- Call the view tool on src/example.ts to continue debugging.\n</suggested-response>`;\n\n/**\n * The guidelines for the Observer.\n * This is exported so the Reflector can reference them.\n */\nexport const OBSERVER_GUIDELINES = `- Be specific enough for the assistant to act on\n- Good: \"User prefers short, direct answers without lengthy explanations\"\n- Bad: \"User stated a preference\" (too vague)\n- Add 1 to 5 observations per exchange\n- Use terse language to save tokens. Sentences should be dense without unnecessary words\n- Do not add repetitive observations that have already been observed. Group repeated similar actions (tool calls, file browsing) under a single parent with sub-bullets for new results\n- If the agent calls tools, observe what was called, why, and what was learned\n- When observing files with line numbers, include the line number if useful\n- If the agent provides a detailed response, observe the contents so it could be repeated\n- Make sure you start each observation with a priority emoji (🔴, 🟡, 🟢)\n- User messages are always 🔴 priority, so are the completions of tasks. Capture the user's words closely — short/medium messages near-verbatim, long messages summarized with key quotes\n- Observe WHAT the agent did and WHAT it means\n- If the user provides detailed messages or code snippets, observe all important details`;\n\n/**\n * Build the complete observer system prompt.\n * @param multiThread - Whether this is for multi-thread batched observation (default: false)\n * @param instruction - Optional custom instructions to append to the prompt\n */\nexport function buildObserverSystemPrompt(multiThread: boolean = false, instruction?: string): string {\n // Use condensed output format when condensed prompt is enabled\n // Otherwise, use the base output format\n const outputFormat = OBSERVER_OUTPUT_FORMAT_BASE;\n\n if (multiThread) {\n return `You are the memory consciousness of an AI assistant. Your observations will be the ONLY information the assistant has about past interactions with this user.\n\nExtract observations that will help the assistant remember:\n\n${OBSERVER_EXTRACTION_INSTRUCTIONS}\n\n=== MULTI-THREAD INPUT ===\n\nYou will receive messages from MULTIPLE conversation threads, each wrapped in <thread id=\"...\"> tags.\nProcess each thread separately and output observations for each thread.\n\n=== OUTPUT FORMAT ===\n\nYour output MUST use XML tags to structure the response. Each thread's observations, current-task, and suggested-response should be nested inside a <thread id=\"...\"> block within <observations>.\n\n<observations>\n<thread id=\"thread_id_1\">\nDate: Dec 4, 2025\n* 🔴 (14:30) User prefers direct answers\n* 🔴 (14:31) Working on feature X\n\n<current-task>\nWhat the agent is currently working on in this thread\n</current-task>\n\n<suggested-response>\nHint for the agent's next message in this thread\n</suggested-response>\n</thread>\n\n<thread id=\"thread_id_2\">\nDate: Dec 5, 2025\n* 🔴 (09:15) User asked about deployment\n\n<current-task>\nCurrent task for this thread\n</current-task>\n\n<suggested-response>\nSuggested response for this thread\n</suggested-response>\n</thread>\n</observations>\n\nUse priority levels:\n- 🔴 High: explicit user facts, preferences, goals achieved, critical context, user messages\n- 🟡 Medium: project details, learned information, tool results\n- 🟢 Low: minor details, uncertain observations\n\n=== GUIDELINES ===\n\n${OBSERVER_GUIDELINES}\n\nRemember: These observations are the assistant's ONLY memory. Make them count.\n\nUser messages are extremely important. If the user asks a question or gives a new task, make it clear in <current-task> that this is the priority.${instruction ? `\\n\\n=== CUSTOM INSTRUCTIONS ===\\n\\n${instruction}` : ''}`;\n }\n\n return `You are the memory consciousness of an AI assistant. Your observations will be the ONLY information the assistant has about past interactions with this user.\n\nExtract observations that will help the assistant remember:\n\n${OBSERVER_EXTRACTION_INSTRUCTIONS}\n\n=== OUTPUT FORMAT ===\n\nYour output MUST use XML tags to structure the response. This allows the system to properly parse and manage memory over time.\n\n${outputFormat}\n\n=== GUIDELINES ===\n\n${OBSERVER_GUIDELINES}\n\n=== IMPORTANT: THREAD ATTRIBUTION ===\n\nDo NOT add thread identifiers, thread IDs, or <thread> tags to your observations.\nThread attribution is handled externally by the system.\nSimply output your observations without any thread-related markup.\n\nRemember: These observations are the assistant's ONLY memory. Make them count.\n\nUser messages are extremely important. If the user asks a question or gives a new task, make it clear in <current-task> that this is the priority. If the assistant needs to respond to the user, indicate in <suggested-response> that it should pause for user reply before continuing other tasks.${instruction ? `\\n\\n=== CUSTOM INSTRUCTIONS ===\\n\\n${instruction}` : ''}`;\n}\n\n/**\n * Observer Agent System Prompt (default - for backwards compatibility)\n *\n * This prompt instructs the Observer to extract observations from message history.\n * The observations become the agent's \"subconscious memory\" - the ONLY information\n * the main agent will have about past interactions.\n */\nexport const OBSERVER_SYSTEM_PROMPT = buildObserverSystemPrompt();\n\n/**\n * Result from the Observer agent\n */\nexport interface ObserverResult {\n /** The extracted observations in markdown format */\n observations: string;\n\n /** The current task extracted from observations (for thread metadata) */\n currentTask?: string;\n\n /** Suggested continuation message for the Actor */\n suggestedContinuation?: string;\n\n /** Raw output from the model (for debugging) */\n rawOutput?: string;\n\n /** True if the output was detected as degenerate (repetition loop) and should be discarded/retried */\n degenerate?: boolean;\n}\n\n/**\n * Format messages for the Observer's input.\n * Includes timestamps for temporal context.\n */\nexport function formatMessagesForObserver(messages: MastraDBMessage[], options?: { maxPartLength?: number }): string {\n const maxLen = options?.maxPartLength;\n\n return messages\n .map(msg => {\n const timestamp = msg.createdAt\n ? new Date(msg.createdAt).toLocaleString('en-US', {\n year: 'numeric',\n month: 'short',\n day: 'numeric',\n hour: 'numeric',\n minute: '2-digit',\n hour12: true,\n })\n : '';\n\n const role = msg.role.charAt(0).toUpperCase() + msg.role.slice(1);\n const timestampStr = timestamp ? ` (${timestamp})` : '';\n\n // Extract text content from the message\n // IMPORTANT: Check parts FIRST since it contains the full message (including tool calls)\n // The content.content string is just the text portion\n let content = '';\n if (typeof msg.content === 'string') {\n content = maybeTruncate(msg.content, maxLen);\n } else if (msg.content?.parts && Array.isArray(msg.content.parts) && msg.content.parts.length > 0) {\n // Use parts array - this includes tool invocations and results\n content = msg.content.parts\n .map(part => {\n if (part.type === 'text') return maybeTruncate(part.text, maxLen);\n if (part.type === 'tool-invocation') {\n const inv = part.toolInvocation;\n if (inv.state === 'result') {\n const resultStr = JSON.stringify(inv.result, null, 2);\n return `[Tool Result: ${inv.toolName}]\\n${maybeTruncate(resultStr, maxLen)}`;\n }\n const argsStr = JSON.stringify(inv.args, null, 2);\n return `[Tool Call: ${inv.toolName}]\\n${maybeTruncate(argsStr, maxLen)}`;\n }\n // Skip all data-* parts (observation markers, activation markers, buffering markers, etc.)\n if (part.type?.startsWith('data-')) return '';\n return '';\n })\n .filter(Boolean)\n .join('\\n');\n } else if (msg.content?.content) {\n // Fallback to text string if no parts\n content = maybeTruncate(msg.content.content, maxLen);\n }\n\n return `**${role}${timestampStr}:**\\n${content}`;\n })\n .join('\\n\\n---\\n\\n');\n}\n\n/** Truncate a string to maxLen characters, appending a note if truncated. */\nfunction maybeTruncate(str: string, maxLen?: number): string {\n if (!maxLen || str.length <= maxLen) return str;\n const truncated = str.slice(0, maxLen);\n const remaining = str.length - maxLen;\n return `${truncated}\\n... [truncated ${remaining} characters]`;\n}\n\n/**\n * Format messages from multiple threads for batched observation.\n * Each thread's messages are wrapped in a <thread id=\"...\"> block.\n */\nexport function formatMultiThreadMessagesForObserver(\n messagesByThread: Map<string, MastraDBMessage[]>,\n threadOrder: string[],\n): string {\n const sections: string[] = [];\n\n for (const threadId of threadOrder) {\n const messages = messagesByThread.get(threadId);\n if (!messages || messages.length === 0) continue;\n\n const formattedMessages = formatMessagesForObserver(messages);\n sections.push(`<thread id=\"${threadId}\">\\n${formattedMessages}\\n</thread>`);\n }\n\n return sections.join('\\n\\n');\n}\n\n/**\n * Build the prompt for multi-thread batched observation.\n */\nexport function buildMultiThreadObserverPrompt(\n existingObservations: string | undefined,\n messagesByThread: Map<string, MastraDBMessage[]>,\n threadOrder: string[],\n): string {\n const formattedMessages = formatMultiThreadMessagesForObserver(messagesByThread, threadOrder);\n\n let prompt = '';\n\n if (existingObservations) {\n prompt += `## Previous Observations\\n\\n${existingObservations}\\n\\n---\\n\\n`;\n prompt +=\n 'Do not repeat these existing observations. Your new observations will be appended to the existing observations.\\n\\n';\n }\n\n prompt += `## New Message History to Observe\\n\\nThe following messages are from ${threadOrder.length} different conversation threads. Each thread is wrapped in a <thread id=\"...\"> tag.\\n\\n${formattedMessages}\\n\\n---\\n\\n`;\n\n prompt += `## Your Task\\n\\n`;\n prompt += `Extract new observations from each thread. Output your observations grouped by thread using <thread id=\"...\"> tags inside your <observations> block. Each thread block should contain that thread's observations, current-task, and suggested-response.\\n\\n`;\n prompt += `Example output format:\\n`;\n prompt += `<observations>\\n`;\n prompt += `<thread id=\"thread1\">\\n`;\n prompt += `Date: Dec 4, 2025\\n`;\n prompt += `* 🔴 (14:30) User prefers direct answers\\n`;\n prompt += `<current-task>Working on feature X</current-task>\\n`;\n prompt += `<suggested-response>Continue with the implementation</suggested-response>\\n`;\n prompt += `</thread>\\n`;\n prompt += `<thread id=\"thread2\">\\n`;\n prompt += `Date: Dec 5, 2025\\n`;\n prompt += `* 🔴 (09:15) User asked about deployment\\n`;\n prompt += `<current-task>Discussing deployment options</current-task>\\n`;\n prompt += `<suggested-response>Explain the deployment process</suggested-response>\\n`;\n prompt += `</thread>\\n`;\n prompt += `</observations>`;\n\n return prompt;\n}\n\n/**\n * Result from parsing multi-thread Observer output\n */\nexport interface MultiThreadObserverResult {\n /** Results per thread */\n threads: Map<string, ObserverResult>;\n /** Raw output from the model (for debugging) */\n rawOutput: string;\n /** True if the output was detected as degenerate (repetition loop) and should be discarded/retried */\n degenerate?: boolean;\n}\n\n/**\n * Parse multi-thread Observer output to extract per-thread results.\n */\nexport function parseMultiThreadObserverOutput(output: string): MultiThreadObserverResult {\n const threads = new Map<string, ObserverResult>();\n\n // Check for degenerate repetition on the whole output\n if (detectDegenerateRepetition(output)) {\n return { threads, rawOutput: output, degenerate: true };\n }\n\n // Extract the <observations> block first\n const observationsMatch = output.match(/^[ \\t]*<observations>([\\s\\S]*?)^[ \\t]*<\\/observations>/im);\n const observationsContent = observationsMatch?.[1] ?? output;\n\n // Find all <thread id=\"...\">...</thread> blocks within observations\n const threadRegex = /<thread\\s+id=\"([^\"]+)\">([\\s\\S]*?)<\\/thread>/gi;\n let match;\n\n while ((match = threadRegex.exec(observationsContent)) !== null) {\n const threadId = match[1];\n const threadContent = match[2];\n if (!threadId || !threadContent) continue;\n\n // Parse this thread's content for observations, current-task, suggested-response\n // Extract observations (everything except current-task and suggested-response)\n let observations = threadContent;\n\n // Extract and remove current-task\n let currentTask: string | undefined;\n const currentTaskMatch = threadContent.match(/<current-task>([\\s\\S]*?)<\\/current-task>/i);\n if (currentTaskMatch?.[1]) {\n currentTask = currentTaskMatch[1].trim();\n observations = observations.replace(/<current-task>[\\s\\S]*?<\\/current-task>/i, '');\n }\n\n // Extract and remove suggested-response\n let suggestedContinuation: string | undefined;\n const suggestedMatch = threadContent.match(/<suggested-response>([\\s\\S]*?)<\\/suggested-response>/i);\n if (suggestedMatch?.[1]) {\n suggestedContinuation = suggestedMatch[1].trim();\n observations = observations.replace(/<suggested-response>[\\s\\S]*?<\\/suggested-response>/i, '');\n }\n\n // Clean up observations and apply line truncation\n observations = sanitizeObservationLines(observations.trim());\n\n threads.set(threadId, {\n observations,\n currentTask,\n suggestedContinuation,\n rawOutput: threadContent,\n });\n }\n\n // If no thread blocks found, the caller will need to handle this case\n // (e.g., by falling back to single-thread parsing)\n\n return {\n threads,\n rawOutput: output,\n };\n}\n\n/**\n * Build the full prompt for the Observer agent.\n * Includes emphasis on the most recent user message for priority handling.\n */\nexport function buildObserverPrompt(\n existingObservations: string | undefined,\n messagesToObserve: MastraDBMessage[],\n options?: { skipContinuationHints?: boolean },\n): string {\n const formattedMessages = formatMessagesForObserver(messagesToObserve);\n\n let prompt = '';\n\n if (existingObservations) {\n prompt += `## Previous Observations\\n\\n${existingObservations}\\n\\n---\\n\\n`;\n prompt +=\n 'Do not repeat these existing observations. Your new observations will be appended to the existing observations.\\n\\n';\n }\n\n prompt += `## New Message History to Observe\\n\\n${formattedMessages}\\n\\n---\\n\\n`;\n\n prompt += `## Your Task\\n\\n`;\n prompt += `Extract new observations from the message history above. Do not repeat observations that are already in the previous observations. Add your new observations in the format specified in your instructions.`;\n\n if (options?.skipContinuationHints) {\n prompt += `\\n\\nIMPORTANT: Do NOT include <current-task> or <suggested-response> sections in your output. Only output <observations>.`;\n }\n\n return prompt;\n}\n\n/**\n * Parse the Observer's output to extract observations, current task, and suggested response.\n * Uses XML tag parsing for structured extraction.\n */\nexport function parseObserverOutput(output: string): ObserverResult {\n // Check for degenerate repetition before parsing (operates on raw output)\n if (detectDegenerateRepetition(output)) {\n return {\n observations: '',\n rawOutput: output,\n degenerate: true,\n };\n }\n\n const parsed = parseMemorySectionXml(output);\n\n // Return observations WITHOUT current-task/suggested-response tags\n // Those are stored separately in thread metadata and injected dynamically\n const observations = sanitizeObservationLines(parsed.observations || '');\n\n return {\n observations,\n currentTask: parsed.currentTask || undefined,\n suggestedContinuation: parsed.suggestedResponse || undefined,\n rawOutput: output,\n };\n}\n\n/**\n * Parsed result from XML memory section\n */\ninterface ParsedMemorySection {\n observations: string;\n currentTask: string;\n suggestedResponse: string;\n}\n\n/**\n * Parse XML tags from observer/reflector output.\n * Extracts content from <observations>, <current-task>, and <suggested-response> tags.\n */\nexport function parseMemorySectionXml(content: string): ParsedMemorySection {\n const result: ParsedMemorySection = {\n observations: '',\n currentTask: '',\n suggestedResponse: '',\n };\n\n // Extract <observations> content (supports multiple blocks)\n // Tags must be at the start of a line (with optional leading whitespace) to avoid\n // capturing inline mentions like \"User discussed <observations> tags\"\n const observationsRegex = /^[ \\t]*<observations>([\\s\\S]*?)^[ \\t]*<\\/observations>/gim;\n const observationsMatches = [...content.matchAll(observationsRegex)];\n if (observationsMatches.length > 0) {\n result.observations = observationsMatches\n .map(m => m[1]?.trim() ?? '')\n .filter(Boolean)\n .join('\\n');\n } else {\n // Fallback: if no XML tags, extract list items from raw content\n // This handles cases where the LLM doesn't follow the XML format exactly\n result.observations = extractListItemsOnly(content);\n }\n\n // Extract <current-task> content (first match only)\n // Tags must be at the start of a line to avoid capturing inline mentions\n const currentTaskMatch = content.match(/^[ \\t]*<current-task>([\\s\\S]*?)^[ \\t]*<\\/current-task>/im);\n if (currentTaskMatch?.[1]) {\n result.currentTask = currentTaskMatch[1].trim();\n }\n\n // Extract <suggested-response> content (first match only)\n // Tags must be at the start of a line to avoid capturing inline mentions\n const suggestedResponseMatch = content.match(/^[ \\t]*<suggested-response>([\\s\\S]*?)^[ \\t]*<\\/suggested-response>/im);\n if (suggestedResponseMatch?.[1]) {\n result.suggestedResponse = suggestedResponseMatch[1].trim();\n }\n\n return result;\n}\n\n/**\n * Fallback: Extract only list items from content when XML tags are missing.\n * Preserves nested list items (indented with spaces/tabs).\n */\nfunction extractListItemsOnly(content: string): string {\n const lines = content.split('\\n');\n const listLines: string[] = [];\n\n for (const line of lines) {\n // Match lines that start with list markers (-, *, or numbered)\n // Allow leading whitespace for nested items\n if (/^\\s*[-*]\\s/.test(line) || /^\\s*\\d+\\.\\s/.test(line)) {\n listLines.push(line);\n }\n }\n\n return listLines.join('\\n').trim();\n}\n\n/**\n * Maximum length (in characters) for a single observation line.\n * Lines exceeding this are truncated with an ellipsis marker.\n * This guards against LLM degeneration that produces enormous single-line outputs.\n */\nconst MAX_OBSERVATION_LINE_CHARS = 10_000;\n\n/**\n * Truncate individual observation lines that exceed the maximum length.\n */\nexport function sanitizeObservationLines(observations: string): string {\n if (!observations) return observations;\n const lines = observations.split('\\n');\n let changed = false;\n for (let i = 0; i < lines.length; i++) {\n if (lines[i]!.length > MAX_OBSERVATION_LINE_CHARS) {\n lines[i] = lines[i]!.slice(0, MAX_OBSERVATION_LINE_CHARS) + ' … [truncated]';\n changed = true;\n }\n }\n return changed ? lines.join('\\n') : observations;\n}\n\n/**\n * Detect degenerate repetition in observer/reflector output.\n * Returns true if the text contains suspicious levels of repeated content,\n * which indicates an LLM repeat-penalty bug (e.g., Gemini Flash looping).\n *\n * Strategy: sample sequential chunks of the text and check if a high\n * proportion are near-identical to previous chunks.\n */\nexport function detectDegenerateRepetition(text: string): boolean {\n if (!text || text.length < 2000) return false;\n\n // Strategy 1: Check for repeated long substrings by sampling fixed-size windows.\n // If the same ~200-char window appears many times, it's degenerate.\n const windowSize = 200;\n const step = Math.max(1, Math.floor(text.length / 50)); // sample ~50 windows\n const seen = new Map<string, number>();\n let duplicateWindows = 0;\n let totalWindows = 0;\n\n for (let i = 0; i + windowSize <= text.length; i += step) {\n const window = text.slice(i, i + windowSize);\n totalWindows++;\n const count = (seen.get(window) ?? 0) + 1;\n seen.set(window, count);\n if (count > 1) duplicateWindows++;\n }\n\n // If more than 40% of sampled windows are duplicates, it's degenerate\n if (totalWindows > 5 && duplicateWindows / totalWindows > 0.4) {\n return true;\n }\n\n // Strategy 2: Check for extremely long lines (a single line with 50k+ chars\n // is almost certainly degenerate enumeration)\n const lines = text.split('\\n');\n for (const line of lines) {\n if (line.length > 50_000) return true;\n }\n\n return false;\n}\n\n/**\n * Check if observations contain a Current Task section.\n * Supports both XML format and legacy markdown format.\n */\nexport function hasCurrentTaskSection(observations: string): boolean {\n // Check for XML format first\n if (/<current-task>/i.test(observations)) {\n return true;\n }\n\n // Legacy markdown patterns\n const currentTaskPatterns = [\n /\\*\\*Current Task:?\\*\\*/i,\n /^Current Task:/im,\n /\\*\\*Current Task\\*\\*:/i,\n /## Current Task/i,\n ];\n\n return currentTaskPatterns.some(pattern => pattern.test(observations));\n}\n\n/**\n * Extract the Current Task content from observations.\n */\nexport function extractCurrentTask(observations: string): string | null {\n const openTag = '<current-task>';\n const closeTag = '</current-task>';\n const startIdx = observations.toLowerCase().indexOf(openTag);\n if (startIdx === -1) return null;\n const contentStart = startIdx + openTag.length;\n const endIdx = observations.toLowerCase().indexOf(closeTag, contentStart);\n if (endIdx === -1) return null;\n const content = observations.slice(contentStart, endIdx).trim();\n return content || null;\n}\n\n/**\n * Optimize observations for token efficiency before presenting to the Actor.\n *\n * This removes:\n * - Non-critical emojis (🟡 and 🟢, keeping only 🔴)\n * - Semantic tags [label, label]\n * - Arrow indicators (->)\n * - Extra whitespace\n *\n * The full format is preserved in storage for analysis.\n */\nexport function optimizeObservationsForContext(observations: string): string {\n let optimized = observations;\n\n // Remove 🟡 and 🟢 emojis (keep 🔴 for critical items)\n optimized = optimized.replace(/🟡\\s*/g, '');\n optimized = optimized.replace(/🟢\\s*/g, '');\n\n // Remove semantic tags like [label, label] but keep collapsed markers like [72 items collapsed - ID: b1fa]\n optimized = optimized.replace(/\\[(?![\\d\\s]*items collapsed)[^\\]]+\\]/g, '');\n\n // Remove arrow indicators\n optimized = optimized.replace(/\\s*->\\s*/g, ' ');\n\n // Clean up multiple spaces\n optimized = optimized.replace(/ +/g, ' ');\n\n // Clean up multiple newlines\n optimized = optimized.replace(/\\n{3,}/g, '\\n\\n');\n\n return optimized.trim();\n}\n","import {\n OBSERVER_EXTRACTION_INSTRUCTIONS,\n OBSERVER_OUTPUT_FORMAT_BASE,\n OBSERVER_GUIDELINES,\n sanitizeObservationLines,\n detectDegenerateRepetition,\n} from './observer-agent';\nimport type { ReflectorResult as BaseReflectorResult } from './types';\n\n/**\n * Result from parsing Reflector output, extending the base type with\n * token count used for compression validation.\n */\nexport interface ReflectorResult extends BaseReflectorResult {\n /** Token count of output (for compression validation) */\n tokenCount?: number;\n}\n\n/**\n * Build the Reflector's system prompt.\n *\n * The Reflector handles meta-observation - when observations grow too large,\n * it reorganizes them into something more manageable by:\n * - Re-organizing and streamlining observations\n * - Drawing connections and conclusions between observations\n * - Identifying if the agent got off track and how to get back on track\n * - Preserving ALL important information (reflections become the ENTIRE memory)\n *\n * @param instruction - Optional custom instructions to append to the prompt\n */\nexport function buildReflectorSystemPrompt(instruction?: string): string {\n return `You are the memory consciousness of an AI assistant. Your memory observation reflections will be the ONLY information the assistant has about past interactions with this user.\n\nThe following instructions were given to another part of your psyche (the observer) to create memories.\nUse this to understand how your observational memories were created.\n\n<observational-memory-instruction>\n${OBSERVER_EXTRACTION_INSTRUCTIONS}\n\n=== OUTPUT FORMAT ===\n\n${OBSERVER_OUTPUT_FORMAT_BASE}\n\n=== GUIDELINES ===\n\n${OBSERVER_GUIDELINES}\n</observational-memory-instruction>\n\nYou are another part of the same psyche, the observation reflector.\nYour reason for existing is to reflect on all the observations, re-organize and streamline them, and draw connections and conclusions between observations about what you've learned, seen, heard, and done.\n\nYou are a much greater and broader aspect of the psyche. Understand that other parts of your mind may get off track in details or side quests, make sure you think hard about what the observed goal at hand is, and observe if we got off track, and why, and how to get back on track. If we're on track still that's great!\n\nTake the existing observations and rewrite them to make it easier to continue into the future with this knowledge, to achieve greater things and grow and learn!\n\nIMPORTANT: your reflections are THE ENTIRETY of the assistants memory. Any information you do not add to your reflections will be immediately forgotten. Make sure you do not leave out anything. Your reflections must assume the assistant knows nothing - your reflections are the ENTIRE memory system.\n\nWhen consolidating observations:\n- Preserve and include dates/times when present (temporal context is critical)\n- Retain the most relevant timestamps (start times, completion times, significant events)\n- Combine related items where it makes sense (e.g., \"agent called view tool 5 times on file x\")\n- Condense older observations more aggressively, retain more detail for recent ones\n\nCRITICAL: USER ASSERTIONS vs QUESTIONS\n- \"User stated: X\" = authoritative assertion (user told us something about themselves)\n- \"User asked: X\" = question/request (user seeking information)\n\nWhen consolidating, USER ASSERTIONS TAKE PRECEDENCE. The user is the authority on their own life.\nIf you see both \"User stated: has two kids\" and later \"User asked: how many kids do I have?\",\nkeep the assertion - the question doesn't invalidate what they told you. The answer is in the assertion.\n\n=== THREAD ATTRIBUTION (Resource Scope) ===\n\nWhen observations contain <thread id=\"...\"> sections:\n- MAINTAIN thread attribution where thread-specific context matters (e.g., ongoing tasks, thread-specific preferences)\n- CONSOLIDATE cross-thread facts that are stable/universal (e.g., user profile, general preferences)\n- PRESERVE thread attribution for recent or context-specific observations\n- When consolidating, you may merge observations from multiple threads if they represent the same universal fact\n\nExample input:\n<thread id=\"thread-1\">\nDate: Dec 4, 2025\n* 🔴 (14:30) User prefers TypeScript\n* 🟡 (14:35) Working on auth feature\n</thread>\n<thread id=\"thread-2\">\nDate: Dec 4, 2025\n* 🔴 (15:00) User prefers TypeScript\n* 🟡 (15:05) Debugging API endpoint\n</thread>\n\nExample output (consolidated):\nDate: Dec 4, 2025\n* 🔴 (14:30) User prefers TypeScript\n<thread id=\"thread-1\">\n* 🟡 (14:35) Working on auth feature\n</thread>\n<thread id=\"thread-2\">\n* 🟡 (15:05) Debugging API endpoint\n</thread>\n\n=== OUTPUT FORMAT ===\n\nYour output MUST use XML tags to structure the response:\n\n<observations>\nPut all consolidated observations here using the date-grouped format with priority emojis (🔴, 🟡, 🟢).\nGroup related observations with indentation.\n</observations>\n\n<current-task>\nState the current task(s) explicitly:\n- Primary: What the agent is currently working on\n- Secondary: Other pending tasks (mark as \"waiting for user\" if appropriate)\n</current-task>\n\n<suggested-response>\nHint for the agent's immediate next message. Examples:\n- \"I've updated the navigation model. Let me walk you through the changes...\"\n- \"The assistant should wait for the user to respond before continuing.\"\n- Call the view tool on src/example.ts to continue debugging.\n</suggested-response>\n\nUser messages are extremely important. If the user asks a question or gives a new task, make it clear in <current-task> that this is the priority. If the assistant needs to respond to the user, indicate in <suggested-response> that it should pause for user reply before continuing other tasks.${instruction ? `\\n\\n=== CUSTOM INSTRUCTIONS ===\\n\\n${instruction}` : ''}`;\n}\n\n/**\n * The Reflector's system prompt (default - for backwards compatibility)\n */\nexport const REFLECTOR_SYSTEM_PROMPT = buildReflectorSystemPrompt();\n\n/**\n * Compression guidance by level.\n * - Level 0: No compression guidance (used as first attempt for regular reflection)\n * - Level 1: Gentle compression guidance (original wording — \"slightly more\" goes a long way for LLMs)\n * - Level 2: Aggressive compression guidance (stronger push when level 1 didn't work)\n */\nexport const COMPRESSION_GUIDANCE: Record<0 | 1 | 2 | 3, string> = {\n 0: '',\n 1: `\n## COMPRESSION REQUIRED\n\nYour previous reflection was the same size or larger than the original observations.\n\nPlease re-process with slightly more compression:\n- Towards the beginning, condense more observations into higher-level reflections\n- Closer to the end, retain more fine details (recent context matters more)\n- Memory is getting long - use a more condensed style throughout\n- Combine related items more aggressively but do not lose important specific details of names, places, events, and people\n- For example if there is a long nested observation list about repeated tool calls, you can combine those into a single line and observe that the tool was called multiple times for x reason, and finally y outcome happened.\n\nYour current detail level was a 10/10, lets aim for a 8/10 detail level.\n`,\n 2: `\n## AGGRESSIVE COMPRESSION REQUIRED\n\nYour previous reflection was still too large after compression guidance.\n\nPlease re-process with much more aggressive compression:\n- Towards the beginning, heavily condense observations into high-level summaries\n- Closer to the end, retain fine details (recent context matters more)\n- Memory is getting very long - use a significantly more condensed style throughout\n- Combine related items aggressively but do not lose important specific details of names, places, events, and people\n- For example if there is a long nested observation list about repeated tool calls, you can combine those into a single line and observe that the tool was called multiple times for x reason, and finally y outcome happened.\n- Remove redundant information and merge overlapping observations\n\nYour current detail level was a 10/10, lets aim for a 6/10 detail level.\n`,\n 3: `\n## CRITICAL COMPRESSION REQUIRED\n\nYour previous reflections have failed to compress sufficiently after multiple attempts.\n\nPlease re-process with maximum compression:\n- Summarize the oldest observations (first 50-70%) into brief high-level paragraphs — only key facts, decisions, and outcomes\n- For the most recent observations (last 30-50%), retain important details but still use a condensed style\n- Ruthlessly merge related observations — if 10 observations are about the same topic, combine into 1-2 lines\n- Drop procedural details (tool calls, retries, intermediate steps) — keep only final outcomes\n- Drop observations that are no longer relevant or have been superseded by newer information\n- Preserve: names, dates, decisions, errors, user preferences, and architectural choices\n\nYour current detail level was a 10/10, lets aim for a 4/10 detail level.\n`,\n};\n\n/**\n * Compression retry prompt - backwards compat alias for level 1\n */\nexport const COMPRESSION_RETRY_PROMPT = COMPRESSION_GUIDANCE[1];\n\n/**\n * Build the prompt for the Reflector agent\n */\nexport function buildReflectorPrompt(\n observations: string,\n manualPrompt?: string,\n compressionLevel?: boolean | 0 | 1 | 2 | 3,\n skipContinuationHints?: boolean,\n): string {\n // Normalize: boolean `true` maps to level 1 for backwards compat\n const level: 0 | 1 | 2 | 3 = typeof compressionLevel === 'number' ? compressionLevel : compressionLevel ? 1 : 0;\n\n let prompt = `## OBSERVATIONS TO REFLECT ON\n\n${observations}\n\n---\n\nPlease analyze these observations and produce a refined, condensed version that will become the assistant's entire memory going forward.`;\n\n if (manualPrompt) {\n prompt += `\n\n## SPECIFIC GUIDANCE\n\n${manualPrompt}`;\n }\n\n const guidance = COMPRESSION_GUIDANCE[level];\n if (guidance) {\n prompt += `\n\n${guidance}`;\n }\n\n if (skipContinuationHints) {\n prompt += `\\n\\nIMPORTANT: Do NOT include <current-task> or <suggested-response> sections in your output. Only output <observations>.`;\n }\n\n return prompt;\n}\n\n/**\n * Parse the Reflector's output to extract observations, current task, and suggested response.\n * Uses XML tag parsing for structured extraction.\n */\nexport function parseReflectorOutput(output: string): ReflectorResult {\n // Check for degenerate repetition before parsing\n if (detectDegenerateRepetition(output)) {\n return {\n observations: '',\n degenerate: true,\n };\n }\n\n const parsed = parseReflectorSectionXml(output);\n\n // Return observations WITHOUT current-task/suggested-response tags\n // Those are stored separately in thread metadata and injected dynamically\n const observations = sanitizeObservationLines(parsed.observations || '');\n\n return {\n observations,\n suggestedContinuation: parsed.suggestedResponse || undefined,\n // Note: Reflector's currentTask is not used - thread metadata preserves per-thread tasks\n };\n}\n\n/**\n * Parsed result from XML reflector section\n */\ninterface ParsedReflectorSection {\n observations: string;\n currentTask: string;\n suggestedResponse: string;\n}\n\n/**\n * Parse XML tags from reflector output.\n * Extracts content from <observations>, <current-task>, and <suggested-response> tags.\n */\nfunction parseReflectorSectionXml(content: string): ParsedReflectorSection {\n const result: ParsedReflectorSection = {\n observations: '',\n currentTask: '',\n suggestedResponse: '',\n };\n\n // Extract <observations> content (supports multiple blocks)\n // Tags must be at the start of a line (with optional leading whitespace) to avoid\n // capturing inline mentions like \"User discussed <observations> tags\"\n const observationsRegex = /^[ \\t]*<observations>([\\s\\S]*?)^[ \\t]*<\\/observations>/gim;\n const observationsMatches = [...content.matchAll(observationsRegex)];\n if (observationsMatches.length > 0) {\n result.observations = observationsMatches\n .map(m => m[1]?.trim() ?? '')\n .filter(Boolean)\n .join('\\n');\n } else {\n // Fallback: if no XML tags, try extracting list items first, then fall back to full content\n const listItems = extractReflectorListItems(content);\n result.observations = listItems || content.trim();\n }\n\n // Extract <current-task> content (first match only)\n const currentTaskMatch = content.match(/<current-task>([\\s\\S]*?)<\\/current-task>/i);\n if (currentTaskMatch?.[1]) {\n result.currentTask = currentTaskMatch[1].trim();\n }\n\n // Extract <suggested-response> content (first match only)\n const suggestedResponseMatch = content.match(/<suggested-response>([\\s\\S]*?)<\\/suggested-response>/i);\n if (suggestedResponseMatch?.[1]) {\n result.suggestedResponse = suggestedResponseMatch[1].trim();\n }\n\n return result;\n}\n\n/**\n * Fallback: Extract only list items from content when XML tags are missing.\n */\nfunction extractReflectorListItems(content: string): string {\n const lines = content.split('\\n');\n const listLines: string[] = [];\n\n for (const line of lines) {\n // Match lines that start with list markers (-, *, or numbered)\n if (/^\\s*[-*]\\s/.test(line) || /^\\s*\\d+\\.\\s/.test(line)) {\n listLines.push(line);\n }\n }\n\n return listLines.join('\\n').trim();\n}\n\n/**\n * Validate that reflection actually compressed the observations below the target threshold\n *\n * @param reflectedTokens - Token count of reflected observations\n * @param targetThreshold - Target token count to compress below (the reflection threshold)\n * @returns true if compression was successful (reflected tokens are below target)\n */\nexport function validateCompression(reflectedTokens: number, targetThreshold: number): boolean {\n // Reflection should be below the target threshold\n return reflectedTokens < targetThreshold;\n}\n","import type { MastraDBMessage } from '@mastra/core/agent';\nimport { Tiktoken } from 'js-tiktoken/lite';\nimport type { TiktokenBPE } from 'js-tiktoken/lite';\nimport o200k_base from 'js-tiktoken/ranks/o200k_base';\n\n/**\n * Shared default encoder singleton.\n * Tiktoken(o200k_base) builds two internal Maps with ~200k entries each,\n * costing ~80-120 MB of heap per instance. Since ObservationalMemory creates\n * a TokenCounter for both input and output processors per request, sharing\n * the default encoder avoids duplicating this cost.\n */\nlet sharedDefaultEncoder: Tiktoken | undefined;\n\nfunction getDefaultEncoder(): Tiktoken {\n if (!sharedDefaultEncoder) {\n sharedDefaultEncoder = new Tiktoken(o200k_base);\n }\n return sharedDefaultEncoder;\n}\n\n/**\n * Token counting utility using tiktoken.\n * For POC we use o200k_base (GPT-4o encoding) as a reasonable default.\n * Production will add provider-aware counting.\n */\nexport class TokenCounter {\n private encoder: Tiktoken;\n\n // Per-message overhead: accounts for role tokens, message framing, and separators.\n // Empirically derived from OpenAI's token counting guide (3 tokens per message base +\n // fractional overhead from name/role encoding). 3.8 is a practical average across models.\n private static readonly TOKENS_PER_MESSAGE = 3.8;\n // Conversation-level overhead: system prompt framing, reply priming tokens, etc.\n private static readonly TOKENS_PER_CONVERSATION = 24;\n\n constructor(encoding?: TiktokenBPE) {\n this.encoder = encoding ? new Tiktoken(encoding) : getDefaultEncoder();\n }\n\n /**\n * Count tokens in a plain string\n */\n countString(text: string): number {\n if (!text) return 0;\n // Allow all special tokens to avoid errors with content containing tokens like <|endoftext|>\n return this.encoder.encode(text, 'all').length;\n }\n\n /**\n * Count tokens in a single message\n */\n countMessage(message: MastraDBMessage): number {\n let tokenString = message.role;\n let overhead = TokenCounter.TOKENS_PER_MESSAGE;\n let toolResultCount = 0;\n\n if (typeof message.content === 'string') {\n tokenString += message.content;\n } else if (message.content && typeof message.content === 'object') {\n if (message.content.content && !Array.isArray(message.content.parts)) {\n tokenString += message.content.content;\n } else if (Array.isArray(message.content.parts)) {\n for (const part of message.content.parts) {\n if (part.type === 'text') {\n tokenString += part.text;\n } else if (part.type === 'tool-invocation') {\n const invocation = part.toolInvocation;\n if (invocation.state === 'call' || invocation.state === 'partial-call') {\n if (invocation.toolName) {\n tokenString += invocation.toolName;\n }\n if (invocation.args) {\n if (typeof invocation.args === 'string') {\n tokenString += invocation.args;\n } else {\n tokenString += JSON.stringify(invocation.args);\n // JSON.stringify adds ~12 tokens of structural overhead (braces, quotes, colons)\n // that the model's native tool encoding doesn't use, so subtract to compensate.\n overhead -= 12;\n }\n }\n } else if (invocation.state === 'result') {\n toolResultCount++;\n if (invocation.result !== undefined) {\n if (typeof invocation.result === 'string') {\n tokenString += invocation.result;\n } else {\n tokenString += JSON.stringify(invocation.result);\n overhead -= 12;\n }\n }\n } else {\n throw new Error(\n `Unhandled tool-invocation state '${(part as any).toolInvocation?.state}' in token counting for part type '${part.type}'`,\n );\n }\n } else if (typeof part.type === 'string' && part.type.startsWith('data-')) {\n // Skip data-* parts (e.g. data-om-activation, data-om-buffering-start, etc.)\n // These are OM metadata parts that are never sent to the LLM.\n } else {\n tokenString += JSON.stringify(part);\n }\n }\n }\n }\n\n // Add overhead for tool results\n if (toolResultCount > 0) {\n overhead += toolResultCount * TokenCounter.TOKENS_PER_MESSAGE;\n }\n\n // Allow all special tokens to avoid errors with content containing tokens like <|endoftext|>\n return Math.round(this.encoder.encode(tokenString, 'all').length + overhead);\n }\n\n /**\n * Count tokens in an array of messages\n */\n countMessages(messages: MastraDBMessage[]): number {\n if (!messages || messages.length === 0) return 0;\n\n let total = TokenCounter.TOKENS_PER_CONVERSATION;\n for (const message of messages) {\n total += this.countMessage(message);\n }\n return total;\n }\n\n /**\n * Count tokens in observations string\n */\n countObservations(observations: string): number {\n return this.countString(observations);\n }\n}\n","import { appendFileSync } from 'node:fs';\nimport { join } from 'node:path';\nimport { Agent } from '@mastra/core/agent';\nimport type { AgentConfig, MastraDBMessage, MessageList } from '@mastra/core/agent';\nimport { resolveModelConfig } from '@mastra/core/llm';\nimport { getThreadOMMetadata, parseMemoryRequestContext, setThreadOMMetadata } from '@mastra/core/memory';\nimport type {\n Processor,\n ProcessInputArgs,\n ProcessInputStepArgs,\n ProcessOutputResultArgs,\n ProcessorStreamWriter,\n} from '@mastra/core/processors';\nimport { MessageHistory } from '@mastra/core/processors';\nimport type { RequestContext } from '@mastra/core/request-context';\nimport type { MemoryStorage, ObservationalMemoryRecord, BufferedObservationChunk } from '@mastra/core/storage';\nimport xxhash from 'xxhash-wasm';\n\nconst OM_DEBUG_LOG = process.env.OM_DEBUG ? join(process.cwd(), 'om-debug.log') : null;\nfunction omDebug(msg: string) {\n if (!OM_DEBUG_LOG) return;\n try {\n appendFileSync(OM_DEBUG_LOG, `[${new Date().toLocaleString()}] ${msg}\\n`);\n } catch {\n // ignore write errors\n }\n}\nfunction omError(msg: string, err?: unknown) {\n const errStr = err instanceof Error ? (err.stack ?? err.message) : err !== undefined ? String(err) : '';\n const full = errStr ? `${msg}: ${errStr}` : msg;\n omDebug(`[OM:ERROR] ${full}`);\n}\n\nomDebug(`[OM:process-start] OM module loaded, pid=${process.pid}`);\n\n// ════════════════════════════════════════════════════════════════════════════════\n// PROCESS-LEVEL OPERATION REGISTRY\n// Tracks which operations (reflecting, observing, buffering) are actively running\n// in THIS process. Used to detect stale DB flags left by crashed processes.\n// Key format: `${recordId}:${operationType}`\n// ════════════════════════════════════════════════════════════════════════════════\nconst activeOps = new Set<string>();\n\nfunction opKey(\n recordId: string,\n op: 'reflecting' | 'observing' | 'bufferingObservation' | 'bufferingReflection',\n): string {\n return `${recordId}:${op}`;\n}\n\nfunction registerOp(\n recordId: string,\n op: 'reflecting' | 'observing' | 'bufferingObservation' | 'bufferingReflection',\n): void {\n activeOps.add(opKey(recordId, op));\n}\n\nfunction unregisterOp(\n recordId: string,\n op: 'reflecting' | 'observing' | 'bufferingObservation' | 'bufferingReflection',\n): void {\n activeOps.delete(opKey(recordId, op));\n}\n\nfunction isOpActiveInProcess(\n recordId: string,\n op: 'reflecting' | 'observing' | 'bufferingObservation' | 'bufferingReflection',\n): boolean {\n return activeOps.has(opKey(recordId, op));\n}\n\n// Wrap console.error so any unexpected errors also land in the debug log\nif (OM_DEBUG_LOG) {\n const _origConsoleError = console.error;\n console.error = (...args: unknown[]) => {\n omDebug(\n `[console.error] ${args.map(a => (a instanceof Error ? (a.stack ?? a.message) : typeof a === 'object' && a !== null ? JSON.stringify(a) : String(a))).join(' ')}`,\n );\n _origConsoleError.apply(console, args);\n };\n}\n\nimport {\n buildObserverSystemPrompt,\n buildObserverPrompt,\n buildMultiThreadObserverPrompt,\n parseObserverOutput,\n parseMultiThreadObserverOutput,\n optimizeObservationsForContext,\n formatMessagesForObserver,\n} from './observer-agent';\nimport {\n buildReflectorSystemPrompt,\n buildReflectorPrompt,\n parseReflectorOutput,\n validateCompression,\n} from './reflector-agent';\nimport { TokenCounter } from './token-counter';\nimport type {\n ObservationConfig,\n ReflectionConfig,\n ThresholdRange,\n ModelSettings,\n ProviderOptions,\n DataOmObservationStartPart,\n DataOmObservationEndPart,\n DataOmObservationFailedPart,\n DataOmStatusPart,\n ObservationMarkerConfig,\n DataOmBufferingStartPart,\n DataOmBufferingEndPart,\n DataOmBufferingFailedPart,\n DataOmActivationPart,\n OmOperationType,\n} from './types';\n\n/**\n * Format a relative time string like \"5 days ago\", \"2 weeks ago\", \"today\", etc.\n */\nfunction formatRelativeTime(date: Date, currentDate: Date): string {\n const diffMs = currentDate.getTime() - date.getTime();\n const diffDays = Math.floor(diffMs / (1000 * 60 * 60 * 24));\n\n if (diffDays === 0) return 'today';\n if (diffDays === 1) return 'yesterday';\n if (diffDays < 7) return `${diffDays} days ago`;\n if (diffDays < 14) return '1 week ago';\n if (diffDays < 30) return `${Math.floor(diffDays / 7)} weeks ago`;\n if (diffDays < 60) return '1 month ago';\n if (diffDays < 365) return `${Math.floor(diffDays / 30)} months ago`;\n return `${Math.floor(diffDays / 365)} year${Math.floor(diffDays / 365) > 1 ? 's' : ''} ago`;\n}\n\n/**\n * Add relative time annotations to date headers in observations.\n * Transforms \"Date: May 15, 2023\" to \"Date: May 15, 2023 (5 days ago)\"\n */\nfunction formatGapBetweenDates(prevDate: Date, currDate: Date): string | null {\n const diffMs = currDate.getTime() - prevDate.getTime();\n const diffDays = Math.floor(diffMs / (1000 * 60 * 60 * 24));\n\n if (diffDays <= 1) {\n return null; // No gap marker for consecutive days\n } else if (diffDays < 7) {\n return `[${diffDays} days later]`;\n } else if (diffDays < 14) {\n return `[1 week later]`;\n } else if (diffDays < 30) {\n const weeks = Math.floor(diffDays / 7);\n return `[${weeks} weeks later]`;\n } else if (diffDays < 60) {\n return `[1 month later]`;\n } else {\n const months = Math.floor(diffDays / 30);\n return `[${months} months later]`;\n }\n}\n\n/**\n * Expand inline estimated dates with relative time.\n * Matches patterns like \"(estimated May 27-28, 2023)\" or \"(meaning May 30, 2023)\"\n * and expands them to \"(meaning May 30, 2023 - which was 3 weeks ago)\"\n */\n/**\n * Parses a date string like \"May 30, 2023\", \"May 27-28, 2023\", \"late April 2023\", etc.\n * Returns the parsed Date or null if unparseable.\n */\nfunction parseDateFromContent(dateContent: string): Date | null {\n let targetDate: Date | null = null;\n\n // Try simple date format first: \"May 30, 2023\"\n const simpleDateMatch = dateContent.match(/([A-Z][a-z]+)\\s+(\\d{1,2}),?\\s+(\\d{4})/);\n if (simpleDateMatch) {\n const parsed = new Date(`${simpleDateMatch[1]} ${simpleDateMatch[2]}, ${simpleDateMatch[3]}`);\n if (!isNaN(parsed.getTime())) {\n targetDate = parsed;\n }\n }\n\n // Try range format: \"May 27-28, 2023\" - use first date\n if (!targetDate) {\n const rangeMatch = dateContent.match(/([A-Z][a-z]+)\\s+(\\d{1,2})-\\d{1,2},?\\s+(\\d{4})/);\n if (rangeMatch) {\n const parsed = new Date(`${rangeMatch[1]} ${rangeMatch[2]}, ${rangeMatch[3]}`);\n if (!isNaN(parsed.getTime())) {\n targetDate = parsed;\n }\n }\n }\n\n // Try \"late/early/mid Month Year\" format\n if (!targetDate) {\n const vagueMatch = dateContent.match(\n /(late|early|mid)[- ]?(?:to[- ]?(?:late|early|mid)[- ]?)?([A-Z][a-z]+)\\s+(\\d{4})/i,\n );\n if (vagueMatch) {\n const month = vagueMatch[2];\n const year = vagueMatch[3];\n const modifier = vagueMatch[1]!.toLowerCase();\n let day = 15; // default to middle\n if (modifier === 'early') day = 7;\n if (modifier === 'late') day = 23;\n const parsed = new Date(`${month} ${day}, ${year}`);\n if (!isNaN(parsed.getTime())) {\n targetDate = parsed;\n }\n }\n }\n\n // Try \"Month to Month Year\" format (cross-month range)\n if (!targetDate) {\n const crossMonthMatch = dateContent.match(/([A-Z][a-z]+)\\s+to\\s+(?:early\\s+)?([A-Z][a-z]+)\\s+(\\d{4})/i);\n if (crossMonthMatch) {\n // Use the middle of the range - approximate with second month\n const parsed = new Date(`${crossMonthMatch[2]} 1, ${crossMonthMatch[3]}`);\n if (!isNaN(parsed.getTime())) {\n targetDate = parsed;\n }\n }\n }\n\n return targetDate;\n}\n\n/**\n * Detects if an observation line indicates future intent (will do, plans to, looking forward to, etc.)\n */\nfunction isFutureIntentObservation(line: string): boolean {\n const futureIntentPatterns = [\n /\\bwill\\s+(?:be\\s+)?(?:\\w+ing|\\w+)\\b/i,\n /\\bplans?\\s+to\\b/i,\n /\\bplanning\\s+to\\b/i,\n /\\blooking\\s+forward\\s+to\\b/i,\n /\\bgoing\\s+to\\b/i,\n /\\bintends?\\s+to\\b/i,\n /\\bwants?\\s+to\\b/i,\n /\\bneeds?\\s+to\\b/i,\n /\\babout\\s+to\\b/i,\n ];\n return futureIntentPatterns.some(pattern => pattern.test(line));\n}\n\nfunction expandInlineEstimatedDates(observations: string, currentDate: Date): string {\n // Match patterns like:\n // (estimated May 27-28, 2023)\n // (meaning May 30, 2023)\n // (estimated late April to early May 2023)\n // (estimated mid-to-late May 2023)\n // These should now be at the END of observation lines\n const inlineDateRegex = /\\((estimated|meaning)\\s+([^)]+\\d{4})\\)/gi;\n\n return observations.replace(inlineDateRegex, (match, prefix: string, dateContent: string) => {\n const targetDate = parseDateFromContent(dateContent);\n\n if (targetDate) {\n const relative = formatRelativeTime(targetDate, currentDate);\n\n // Check if this is a future-intent observation that's now in the past\n // We need to look at the text BEFORE this match to determine intent\n const matchIndex = observations.indexOf(match);\n const lineStart = observations.lastIndexOf('\\n', matchIndex) + 1;\n const lineBeforeDate = observations.substring(lineStart, matchIndex);\n\n const isPastDate = targetDate < currentDate;\n const isFutureIntent = isFutureIntentObservation(lineBeforeDate);\n\n if (isPastDate && isFutureIntent) {\n // This was a planned action that should have happened by now\n return `(${prefix} ${dateContent} - ${relative}, likely already happened)`;\n }\n\n return `(${prefix} ${dateContent} - ${relative})`;\n }\n\n // Couldn't parse, return original\n return match;\n });\n}\n\nfunction addRelativeTimeToObservations(observations: string, currentDate: Date): string {\n // First, expand inline estimated dates with relative time\n const withInlineDates = expandInlineEstimatedDates(observations, currentDate);\n\n // Match date headers like \"Date: May 15, 2023\" or \"Date: January 1, 2024\"\n const dateHeaderRegex = /^(Date:\\s*)([A-Z][a-z]+ \\d{1,2}, \\d{4})$/gm;\n\n // First pass: collect all dates in order\n const dates: { index: number; date: Date; match: string; prefix: string; dateStr: string }[] = [];\n let regexMatch: RegExpExecArray | null;\n while ((regexMatch = dateHeaderRegex.exec(withInlineDates)) !== null) {\n const dateStr = regexMatch[2]!;\n const parsed = new Date(dateStr);\n if (!isNaN(parsed.getTime())) {\n dates.push({\n index: regexMatch.index,\n date: parsed,\n match: regexMatch[0],\n prefix: regexMatch[1]!,\n dateStr,\n });\n }\n }\n\n // If no dates found, return the inline-expanded version\n if (dates.length === 0) {\n return withInlineDates;\n }\n\n // Second pass: build result with relative times and gap markers\n let result = '';\n let lastIndex = 0;\n\n for (let i = 0; i < dates.length; i++) {\n const curr = dates[i]!;\n const prev = i > 0 ? dates[i - 1]! : null;\n\n // Add text before this date header\n result += withInlineDates.slice(lastIndex, curr.index);\n\n // Add gap marker if there's a significant gap from previous date\n if (prev) {\n const gap = formatGapBetweenDates(prev.date, curr.date);\n if (gap) {\n result += `\\n${gap}\\n\\n`;\n }\n }\n\n // Add the date header with relative time\n const relative = formatRelativeTime(curr.date, currentDate);\n result += `${curr.prefix}${curr.dateStr} (${relative})`;\n\n lastIndex = curr.index + curr.match.length;\n }\n\n // Add remaining text after last date header\n result += withInlineDates.slice(lastIndex);\n\n return result;\n}\n/**\n * Debug event emitted when observation-related events occur.\n * Useful for understanding what the Observer is doing.\n */\nexport interface ObservationDebugEvent {\n type:\n | 'observation_triggered'\n | 'observation_complete'\n | 'reflection_triggered'\n | 'reflection_complete'\n | 'tokens_accumulated'\n | 'step_progress';\n timestamp: Date;\n threadId: string;\n resourceId: string;\n /** Messages that were sent to the Observer */\n messages?: Array<{ role: string; content: string }>;\n /** Token counts */\n pendingTokens?: number;\n sessionTokens?: number;\n totalPendingTokens?: number;\n threshold?: number;\n /** Input token count (for reflection events) */\n inputTokens?: number;\n /** Number of active observations (for reflection events) */\n activeObservationsLength?: number;\n /** Output token count after reflection */\n outputTokens?: number;\n /** The observations that were generated */\n observations?: string;\n /** Previous observations (before this event) */\n previousObservations?: string;\n /** Observer's raw output */\n rawObserverOutput?: string;\n /** LLM usage from Observer/Reflector calls */\n usage?: {\n inputTokens?: number;\n outputTokens?: number;\n totalTokens?: number;\n };\n /** Step progress fields (for step_progress events) */\n stepNumber?: number;\n finishReason?: string;\n thresholdPercent?: number;\n willSave?: boolean;\n willObserve?: boolean;\n}\n\n/**\n * Configuration for ObservationalMemory\n */\nexport interface ObservationalMemoryConfig {\n /**\n * Storage adapter for persisting observations.\n * Must be a MemoryStorage instance (from MastraStorage.stores.memory).\n */\n storage: MemoryStorage;\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.\n */\n observation?: ObservationConfig;\n\n /**\n * Reflection step configuration.\n */\n reflection?: ReflectionConfig;\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 scope?: 'resource' | 'thread';\n\n /**\n * Debug callback for observation events.\n * Called whenever observation-related events occur.\n * Useful for debugging and understanding the observation flow.\n */\n onDebugEvent?: (event: ObservationDebugEvent) => void;\n\n obscureThreadIds?: 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/**\n * Internal resolved config with all defaults applied.\n * Thresholds are stored as ThresholdRange internally for dynamic calculation,\n * even when user provides a simple number (converted based on shareTokenBudget).\n */\ninterface ResolvedObservationConfig {\n model: AgentConfig['model'];\n /** Internal threshold - always stored as ThresholdRange for dynamic calculation */\n messageTokens: number | ThresholdRange;\n /** Whether shared token budget is enabled */\n shareTokenBudget: boolean;\n /** Model settings - merged with user config and defaults */\n modelSettings: ModelSettings;\n providerOptions: ProviderOptions;\n maxTokensPerBatch: number;\n /** Token interval for async background observation buffering (resolved from config) */\n bufferTokens?: number;\n /** Ratio of buffered observations to activate (0-1 float) */\n bufferActivation?: number;\n /** Token threshold above which synchronous observation is forced */\n blockAfter?: number;\n /** Custom instructions to append to the Observer's system prompt */\n instruction?: string;\n}\n\ninterface ResolvedReflectionConfig {\n model: AgentConfig['model'];\n /** Internal threshold - always stored as ThresholdRange for dynamic calculation */\n observationTokens: number | ThresholdRange;\n /** Whether shared token budget is enabled */\n shareTokenBudget: boolean;\n /** Model settings - merged with user config and defaults */\n modelSettings: ModelSettings;\n providerOptions: ProviderOptions;\n /** Ratio (0-1) controlling when async reflection buffering starts */\n bufferActivation?: number;\n /** Token threshold above which synchronous reflection is forced */\n blockAfter?: number;\n /** Custom instructions to append to the Reflector's system prompt */\n instruction?: string;\n}\n\n/**\n * Default configuration values matching the spec\n */\nexport const OBSERVATIONAL_MEMORY_DEFAULTS = {\n observation: {\n model: 'google/gemini-2.5-flash',\n messageTokens: 30_000,\n modelSettings: {\n temperature: 0.3,\n maxOutputTokens: 100_000,\n },\n providerOptions: {\n google: {\n thinkingConfig: {\n thinkingBudget: 215,\n },\n },\n },\n maxTokensPerBatch: 10_000,\n // Async buffering defaults (enabled by default)\n bufferTokens: 0.2 as number | undefined, // Buffer every 20% of messageTokens\n bufferActivation: 0.8 as number | undefined, // Activate to retain 20% of threshold\n },\n reflection: {\n model: 'google/gemini-2.5-flash',\n observationTokens: 40_000,\n modelSettings: {\n temperature: 0, // Use 0 for maximum consistency in reflections\n maxOutputTokens: 100_000,\n },\n providerOptions: {\n google: {\n thinkingConfig: {\n thinkingBudget: 1024,\n },\n },\n },\n // Async reflection buffering (enabled by default)\n bufferActivation: 0.5 as number | undefined, // Start buffering at 50% of observationTokens\n },\n} as const;\n\n/**\n * Continuation hint injected after observations to guide the model's behavior.\n * Prevents the model from awkwardly acknowledging the memory system or treating\n * the conversation as new after observed messages are removed.\n */\nexport const OBSERVATION_CONTINUATION_HINT = `This message is not from the user, the conversation history grew too long and wouldn't fit in context! Thankfully the entire conversation is stored in your memory observations. Please continue from where the observations left off. Do not refer to your \"memory observations\" directly, the user doesn't know about them, they are your memories! Just respond naturally as if you're remembering the conversation (you are!). Do not say \"Hi there!\" or \"based on our previous conversation\" as if the conversation is just starting, this is not a new conversation. This is an ongoing conversation, keep continuity by responding based on your memory. For example do not say \"I understand. I've reviewed my memory observations\", or \"I remember [...]\". Answer naturally following the suggestion from your memory. Note that your memory may contain a suggested first response, which you should follow.\n\nIMPORTANT: this system reminder is NOT from the user. The system placed it here as part of your memory system. This message is part of you remembering your conversation with the user.\n\nNOTE: Any messages following this system reminder are newer than your memories.`;\n\n/**\n * Preamble that introduces the observations block.\n * Use before `<observations>`, with instructions after.\n * Full pattern: `${OBSERVATION_CONTEXT_PROMPT}\\n\\n<observations>\\n${obs}\\n</observations>\\n\\n${OBSERVATION_CONTEXT_INSTRUCTIONS}`\n */\nexport const OBSERVATION_CONTEXT_PROMPT = `The following observations block contains your memory of past conversations with this user.`;\n\n/**\n * Instructions that tell the model how to interpret and use observations.\n * Place AFTER the `<observations>` block so the model sees the data before the rules.\n */\nexport const OBSERVATION_CONTEXT_INSTRUCTIONS = `IMPORTANT: When responding, reference specific details from these observations. Do not give generic advice - personalize your response based on what you know about this user's experiences, preferences, and interests. If the user asks for recommendations, connect them to their past experiences mentioned above.\n\nKNOWLEDGE UPDATES: When asked about current state (e.g., \"where do I currently...\", \"what is my current...\"), always prefer the MOST RECENT information. Observations include dates - if you see conflicting information, the newer observation supersedes the older one. Look for phrases like \"will start\", \"is switching\", \"changed to\", \"moved to\" as indicators that previous information has been updated.\n\nPLANNED ACTIONS: If the user stated they planned to do something (e.g., \"I'm going to...\", \"I'm looking forward to...\", \"I will...\") and the date they planned to do it is now in the past (check the relative time like \"3 weeks ago\"), assume they completed the action unless there's evidence they didn't. For example, if someone said \"I'll start my new diet on Monday\" and that was 2 weeks ago, assume they started the diet.\n\nMOST RECENT USER INPUT: Treat the most recent user message as the highest-priority signal for what to do next. Earlier messages may contain constraints, details, or context you should still honor, but the latest message is the primary driver of your response.`;\n\n/**\n * ObservationalMemory - A three-agent memory system for long conversations.\n *\n * This processor:\n * 1. On input: Injects observations into context, filters out observed messages\n * 2. On output: Tracks new messages, triggers Observer/Reflector when thresholds hit\n *\n * The Actor (main agent) sees:\n * - Observations (compressed history)\n * - Suggested continuation message\n * - Recent unobserved messages\n *\n * @example\n * ```ts\n * import { ObservationalMemory } from '@mastra/memory/processors';\n *\n * // Minimal configuration\n * const om = new ObservationalMemory({ storage });\n *\n * // Full configuration\n * const om = new ObservationalMemory({\n * storage,\n * model: 'google/gemini-2.5-flash', // shared model for both agents\n * shareTokenBudget: true,\n * observation: {\n * messageTokens: 30_000,\n * modelSettings: { temperature: 0.3 },\n * },\n * reflection: {\n * observationTokens: 40_000,\n * },\n * });\n *\n * const agent = new Agent({\n * inputProcessors: [om],\n * outputProcessors: [om],\n * });\n * ```\n */\nexport interface ObserveHooks {\n onObservationStart?: () => void;\n onObservationEnd?: () => void;\n onReflectionStart?: () => void;\n onReflectionEnd?: () => void;\n}\n\nexport class ObservationalMemory implements Processor<'observational-memory'> {\n readonly id = 'observational-memory' as const;\n readonly name = 'Observational Memory';\n\n private storage: MemoryStorage;\n private tokenCounter: TokenCounter;\n private scope: 'resource' | 'thread';\n private observationConfig: ResolvedObservationConfig;\n private reflectionConfig: ResolvedReflectionConfig;\n private onDebugEvent?: (event: ObservationDebugEvent) => void;\n\n /** Internal Observer agent - created lazily */\n private observerAgent?: Agent;\n\n /** Internal Reflector agent - created lazily */\n private reflectorAgent?: Agent;\n\n private shouldObscureThreadIds = false;\n private hasher = xxhash();\n private threadIdCache = new Map<string, string>();\n\n /**\n * Track message IDs observed during this instance's lifetime.\n * Prevents re-observing messages when per-thread lastObservedAt cursors\n * haven't fully advanced past messages observed in a prior cycle.\n */\n private observedMessageIds = new Set<string>();\n\n /** Internal MessageHistory for message persistence */\n private messageHistory: MessageHistory;\n\n /**\n * In-memory mutex for serializing observation/reflection cycles per resource/thread.\n * Prevents race conditions where two concurrent cycles could both read isObserving=false\n * before either sets it to true, leading to lost work.\n *\n * Key format: \"resource:{resourceId}\" or \"thread:{threadId}\"\n * Value: Promise that resolves when the lock is released\n *\n * NOTE: This mutex only works within a single Node.js process. For distributed\n * deployments, external locking (Redis, database locks) would be needed, or\n * accept eventual consistency (acceptable for v1).\n */\n private locks = new Map<string, Promise<void>>();\n\n /**\n * Track in-flight async buffering operations per resource/thread.\n * STATIC: Shared across all ObservationalMemory instances in this process.\n * This is critical because multiple OM instances are created per agent loop step,\n * and we need them to share knowledge of in-flight operations.\n * Key format: \"obs:{lockKey}\" or \"refl:{lockKey}\"\n * Value: Promise that resolves when buffering completes\n */\n private static asyncBufferingOps = new Map<string, Promise<void>>();\n\n /**\n * Track the last token boundary at which we started buffering.\n * STATIC: Shared across all instances so boundary tracking persists across OM recreations.\n * Key format: \"obs:{lockKey}\" or \"refl:{lockKey}\"\n */\n private static lastBufferedBoundary = new Map<string, number>();\n\n /**\n * Track the timestamp cursor for buffered messages.\n * STATIC: Shared across all instances so each buffer only observes messages\n * newer than the previous buffer's boundary.\n * Key format: \"obs:{lockKey}\"\n */\n private static lastBufferedAtTime = new Map<string, Date>();\n\n /**\n * Tracks cycleId for in-flight buffered reflections.\n * STATIC: Shared across instances so we can match cycleId at activation time.\n * Key format: \"refl:{lockKey}\"\n */\n private static reflectionBufferCycleIds = new Map<string, string>();\n\n /**\n * Track message IDs that have been sealed during async buffering.\n * STATIC: Shared across all instances so saveMessagesWithSealedIdTracking\n * generates new IDs when re-saving messages that were sealed in a previous step.\n * Key format: threadId\n * Value: Set of sealed message IDs\n */\n private static sealedMessageIds = new Map<string, Set<string>>();\n\n /**\n * Check if async buffering is enabled for observations.\n */\n private isAsyncObservationEnabled(): boolean {\n const enabled = this.observationConfig.bufferTokens !== undefined && this.observationConfig.bufferTokens > 0;\n return enabled;\n }\n\n /**\n * Check if async buffering is enabled for reflections.\n * Reflection buffering is enabled when bufferActivation is set (triggers at threshold * bufferActivation).\n */\n private isAsyncReflectionEnabled(): boolean {\n return this.reflectionConfig.bufferActivation !== undefined && this.reflectionConfig.bufferActivation > 0;\n }\n\n /**\n * Get the buffer interval boundary key for observations.\n */\n private getObservationBufferKey(lockKey: string): string {\n return `obs:${lockKey}`;\n }\n\n /**\n * Get the buffer interval boundary key for reflections.\n */\n private getReflectionBufferKey(lockKey: string): string {\n return `refl:${lockKey}`;\n }\n\n /**\n * Clean up static maps for a thread/resource to prevent memory leaks.\n * Called after activation (to remove activated message IDs from sealedMessageIds)\n * and from clear() (to fully remove all static state for a thread).\n */\n private cleanupStaticMaps(threadId: string, resourceId?: string | null, activatedMessageIds?: string[]): void {\n const lockKey = this.getLockKey(threadId, resourceId);\n const obsBufKey = this.getObservationBufferKey(lockKey);\n const reflBufKey = this.getReflectionBufferKey(lockKey);\n\n if (activatedMessageIds) {\n // Partial cleanup: remove only activated IDs from sealedMessageIds\n const sealedSet = ObservationalMemory.sealedMessageIds.get(threadId);\n if (sealedSet) {\n for (const id of activatedMessageIds) {\n sealedSet.delete(id);\n }\n if (sealedSet.size === 0) {\n ObservationalMemory.sealedMessageIds.delete(threadId);\n }\n }\n } else {\n // Full cleanup: remove all static state for this thread\n ObservationalMemory.sealedMessageIds.delete(threadId);\n ObservationalMemory.lastBufferedAtTime.delete(obsBufKey);\n ObservationalMemory.lastBufferedBoundary.delete(obsBufKey);\n ObservationalMemory.lastBufferedBoundary.delete(reflBufKey);\n ObservationalMemory.asyncBufferingOps.delete(obsBufKey);\n ObservationalMemory.asyncBufferingOps.delete(reflBufKey);\n ObservationalMemory.reflectionBufferCycleIds.delete(reflBufKey);\n }\n }\n\n /**\n * Await any in-flight async buffering operations for a given thread/resource.\n * Returns once all buffering promises have settled (or after timeout).\n */\n static async awaitBuffering(\n threadId: string | null | undefined,\n resourceId: string | null | undefined,\n scope: 'thread' | 'resource',\n timeoutMs = 30000,\n ): Promise<void> {\n const lockKey = scope === 'resource' && resourceId ? `resource:${resourceId}` : `thread:${threadId ?? 'unknown'}`;\n const obsKey = `obs:${lockKey}`;\n const reflKey = `refl:${lockKey}`;\n\n const promises: Promise<void>[] = [];\n const obsOp = ObservationalMemory.asyncBufferingOps.get(obsKey);\n if (obsOp) promises.push(obsOp);\n const reflOp = ObservationalMemory.asyncBufferingOps.get(reflKey);\n if (reflOp) promises.push(reflOp);\n\n if (promises.length === 0) {\n return;\n }\n\n try {\n await Promise.race([\n Promise.all(promises),\n new Promise<never>((_, reject) => setTimeout(() => reject(new Error('Timeout')), timeoutMs)),\n ]);\n } catch {\n // Timeout or error - continue silently\n }\n }\n\n /**\n * Safely get bufferedObservationChunks as an array.\n * Handles cases where it might be a JSON string or undefined.\n */\n private getBufferedChunks(record: ObservationalMemoryRecord | null | undefined): BufferedObservationChunk[] {\n if (!record?.bufferedObservationChunks) return [];\n if (Array.isArray(record.bufferedObservationChunks)) return record.bufferedObservationChunks;\n if (typeof record.bufferedObservationChunks === 'string') {\n try {\n const parsed = JSON.parse(record.bufferedObservationChunks);\n return Array.isArray(parsed) ? parsed : [];\n } catch {\n return [];\n }\n }\n return [];\n }\n\n /**\n * Resolve bufferActivation config into an absolute retention floor (tokens to keep).\n * - Value in (0, 1]: ratio → retentionFloor = threshold * (1 - value)\n * - Value >= 1000: absolute token count → retentionFloor = value\n */\n private resolveRetentionFloor(bufferActivation: number, messageTokensThreshold: number): number {\n if (bufferActivation >= 1000) return bufferActivation;\n return messageTokensThreshold * (1 - bufferActivation);\n }\n\n /**\n * Convert bufferActivation to the equivalent ratio (0-1) for the storage layer.\n * When bufferActivation >= 1000, it's an absolute retention target, so we compute\n * the equivalent ratio: 1 - (bufferActivation / threshold).\n */\n private resolveActivationRatio(bufferActivation: number, messageTokensThreshold: number): number {\n if (bufferActivation >= 1000) {\n return Math.max(0, Math.min(1, 1 - bufferActivation / messageTokensThreshold));\n }\n return bufferActivation;\n }\n\n /**\n * Calculate the projected message tokens that would be removed if activation happened now.\n * This replicates the chunk boundary logic in swapBufferedToActive without actually activating.\n */\n private calculateProjectedMessageRemoval(\n chunks: BufferedObservationChunk[],\n bufferActivation: number,\n messageTokensThreshold: number,\n currentPendingTokens: number,\n ): number {\n if (chunks.length === 0) return 0;\n\n const retentionFloor = this.resolveRetentionFloor(bufferActivation, messageTokensThreshold);\n const targetMessageTokens = Math.max(0, currentPendingTokens - retentionFloor);\n\n // Find the closest chunk boundary to the target, biased over (prefer removing\n // slightly more than the target so remaining context lands at or below retentionFloor).\n // Track both best-over and best-under boundaries so we can fall back to under\n // if the over boundary would overshoot by too much.\n let cumulativeMessageTokens = 0;\n let bestOverBoundary = 0;\n let bestOverTokens = 0;\n let bestUnderBoundary = 0;\n let bestUnderTokens = 0;\n\n for (let i = 0; i < chunks.length; i++) {\n cumulativeMessageTokens += chunks[i]!.messageTokens ?? 0;\n const boundary = i + 1;\n\n if (cumulativeMessageTokens >= targetMessageTokens) {\n // Over or equal — track the closest (lowest) over boundary\n if (bestOverBoundary === 0 || cumulativeMessageTokens < bestOverTokens) {\n bestOverBoundary = boundary;\n bestOverTokens = cumulativeMessageTokens;\n }\n } else {\n // Under — track the closest (highest) under boundary\n if (cumulativeMessageTokens > bestUnderTokens) {\n bestUnderBoundary = boundary;\n bestUnderTokens = cumulativeMessageTokens;\n }\n }\n }\n\n // Safeguard: if the over boundary would eat into more than 95% of the\n // retention floor, fall back to the best under boundary instead.\n // This prevents edge cases where a large chunk overshoots dramatically.\n // Additionally, never bias over if it would leave fewer than 1000 tokens\n // remaining — at that level the agent may lose all meaningful context.\n const maxOvershoot = retentionFloor * 0.95;\n const overshoot = bestOverTokens - targetMessageTokens;\n const remainingAfterOver = currentPendingTokens - bestOverTokens;\n\n let bestBoundaryMessageTokens: number;\n\n if (bestOverBoundary > 0 && overshoot <= maxOvershoot && (remainingAfterOver >= 1000 || retentionFloor === 0)) {\n bestBoundaryMessageTokens = bestOverTokens;\n } else if (bestUnderBoundary > 0) {\n bestBoundaryMessageTokens = bestUnderTokens;\n } else if (bestOverBoundary > 0) {\n // All boundaries are over and exceed the safeguard — still activate\n // the closest over boundary (better than nothing)\n bestBoundaryMessageTokens = bestOverTokens;\n } else {\n return chunks[0]?.messageTokens ?? 0;\n }\n\n return bestBoundaryMessageTokens;\n }\n\n /**\n * Check if we've crossed a new bufferTokens interval boundary.\n * Returns true if async buffering should be triggered.\n *\n * When pending tokens are within ~1 bufferTokens of the observation threshold,\n * the buffer interval is halved to produce finer-grained chunks right before\n * activation. This improves chunk boundary selection, reducing overshoot.\n */\n private shouldTriggerAsyncObservation(\n currentTokens: number,\n lockKey: string,\n record: ObservationalMemoryRecord,\n messageTokensThreshold?: number,\n ): boolean {\n if (!this.isAsyncObservationEnabled()) return false;\n\n // Don't start a new buffer if one is already in progress\n if (record.isBufferingObservation) {\n if (isOpActiveInProcess(record.id, 'bufferingObservation')) return false;\n // Flag is stale (from a crashed process) — clear it and allow new buffering\n omDebug(`[OM:shouldTriggerAsyncObs] isBufferingObservation=true but stale, clearing`);\n this.storage.setBufferingObservationFlag(record.id, false).catch(() => {});\n }\n\n // Also check in-memory state for the current instance (protects within a single request)\n const bufferKey = this.getObservationBufferKey(lockKey);\n if (this.isAsyncBufferingInProgress(bufferKey)) return false;\n\n const bufferTokens = this.observationConfig.bufferTokens!;\n // Use the higher of persisted DB value or in-memory value.\n // DB value survives instance recreation; in-memory value is set immediately\n // when buffering starts (before the DB write completes).\n const dbBoundary = record.lastBufferedAtTokens ?? 0;\n const memBoundary = ObservationalMemory.lastBufferedBoundary.get(bufferKey) ?? 0;\n const lastBoundary = Math.max(dbBoundary, memBoundary);\n\n // Halve the buffer interval when within ~1 bufferTokens of the activation threshold.\n // This produces finer-grained chunks right before activation, improving boundary selection.\n const rampPoint = messageTokensThreshold ? messageTokensThreshold - bufferTokens * 1.1 : Infinity;\n const effectiveBufferTokens = currentTokens >= rampPoint ? bufferTokens / 2 : bufferTokens;\n\n // Calculate which interval we're in\n const currentInterval = Math.floor(currentTokens / effectiveBufferTokens);\n const lastInterval = Math.floor(lastBoundary / effectiveBufferTokens);\n\n const shouldTrigger = currentInterval > lastInterval;\n\n omDebug(\n `[OM:shouldTriggerAsyncObs] tokens=${currentTokens}, bufferTokens=${bufferTokens}, effectiveBufferTokens=${effectiveBufferTokens}, rampPoint=${rampPoint}, currentInterval=${currentInterval}, lastInterval=${lastInterval}, lastBoundary=${lastBoundary} (db=${dbBoundary}, mem=${memBoundary}), shouldTrigger=${shouldTrigger}`,\n );\n\n // Trigger if we've crossed into a new interval\n return shouldTrigger;\n }\n\n /**\n * Check if async reflection buffering should be triggered.\n * Triggers once when observation tokens reach `threshold * bufferActivation`.\n * Only allows one buffered reflection at a time.\n */\n private shouldTriggerAsyncReflection(\n currentObservationTokens: number,\n lockKey: string,\n record: ObservationalMemoryRecord,\n ): boolean {\n if (!this.isAsyncReflectionEnabled()) return false;\n\n // Don't re-trigger if buffering is already in progress\n if (record.isBufferingReflection) {\n if (isOpActiveInProcess(record.id, 'bufferingReflection')) return false;\n // Flag is stale (from a crashed process) — clear it and allow new buffering\n omDebug(`[OM:shouldTriggerAsyncRefl] isBufferingReflection=true but stale, clearing`);\n this.storage.setBufferingReflectionFlag(record.id, false).catch(() => {});\n }\n\n // Also check in-memory state for the current instance\n const bufferKey = this.getReflectionBufferKey(lockKey);\n if (this.isAsyncBufferingInProgress(bufferKey)) return false;\n if (ObservationalMemory.lastBufferedBoundary.has(bufferKey)) return false;\n\n // Don't re-trigger if the record already has a buffered reflection\n if (record.bufferedReflection) return false;\n\n // Check if we've crossed the activation threshold\n const reflectThreshold = this.getMaxThreshold(this.reflectionConfig.observationTokens);\n const activationPoint = reflectThreshold * this.reflectionConfig.bufferActivation!;\n\n const shouldTrigger = currentObservationTokens >= activationPoint;\n omDebug(\n `[OM:shouldTriggerAsyncRefl] obsTokens=${currentObservationTokens}, reflThreshold=${reflectThreshold}, activationPoint=${activationPoint}, bufferActivation=${this.reflectionConfig.bufferActivation}, shouldTrigger=${shouldTrigger}, isBufferingRefl=${record.isBufferingReflection}, hasBufferedReflection=${!!record.bufferedReflection}`,\n );\n\n return shouldTrigger;\n }\n\n /**\n * Check if an async buffering operation is already in progress.\n */\n private isAsyncBufferingInProgress(bufferKey: string): boolean {\n return ObservationalMemory.asyncBufferingOps.has(bufferKey);\n }\n\n /**\n * Acquire a lock for the given key, execute the callback, then release.\n * If a lock is already held, waits for it to be released before acquiring.\n */\n private async withLock<T>(key: string, fn: () => Promise<T>): Promise<T> {\n // Wait for any existing lock to be released\n const existingLock = this.locks.get(key);\n if (existingLock) {\n await existingLock;\n }\n\n // Create a new lock\n let releaseLock: () => void;\n const lockPromise = new Promise<void>(resolve => {\n releaseLock = resolve;\n });\n this.locks.set(key, lockPromise);\n\n try {\n return await fn();\n } finally {\n // Release the lock\n releaseLock!();\n // Clean up if this is still our lock\n if (this.locks.get(key) === lockPromise) {\n this.locks.delete(key);\n }\n }\n }\n\n /**\n * Get the lock key for the current scope\n */\n private getLockKey(threadId: string | null | undefined, resourceId: string | null | undefined): string {\n if (this.scope === 'resource' && resourceId) {\n return `resource:${resourceId}`;\n }\n return `thread:${threadId ?? 'unknown'}`;\n }\n\n constructor(config: ObservationalMemoryConfig) {\n // Validate that top-level model is not used together with sub-config models\n if (config.model && config.observation?.model) {\n throw new Error(\n 'Cannot set both `model` and `observation.model`. Use `model` to set both agents, or set each individually.',\n );\n }\n if (config.model && config.reflection?.model) {\n throw new Error(\n 'Cannot set both `model` and `reflection.model`. Use `model` to set both agents, or set each individually.',\n );\n }\n\n this.shouldObscureThreadIds = config.obscureThreadIds || false;\n this.storage = config.storage;\n this.scope = config.scope ?? 'thread';\n\n // Resolve \"default\" to the default model\n const resolveModel = (m: typeof config.model) =>\n m === 'default' ? OBSERVATIONAL_MEMORY_DEFAULTS.observation.model : m;\n\n // Require an explicit model — no silent default.\n // Resolution order: top-level model → sub-config model → the other sub-config model → error\n const observationModel =\n resolveModel(config.model) ?? resolveModel(config.observation?.model) ?? resolveModel(config.reflection?.model);\n const reflectionModel =\n resolveModel(config.model) ?? resolveModel(config.reflection?.model) ?? resolveModel(config.observation?.model);\n\n if (!observationModel || !reflectionModel) {\n throw new Error(\n `Observational Memory requires a model to be set. Use \\`observationalMemory: true\\` for the default (google/gemini-2.5-flash), or set a model explicitly:\\n\\n` +\n ` observationalMemory: {\\n` +\n ` model: \"$provider/$model\",\\n` +\n ` }\\n\\n` +\n `See https://mastra.ai/docs/memory/observational-memory#models for model recommendations and alternatives.`,\n );\n }\n\n // Get base thresholds first (needed for shared budget calculation)\n const messageTokens = config.observation?.messageTokens ?? OBSERVATIONAL_MEMORY_DEFAULTS.observation.messageTokens;\n const observationTokens =\n config.reflection?.observationTokens ?? OBSERVATIONAL_MEMORY_DEFAULTS.reflection.observationTokens;\n const isSharedBudget = config.shareTokenBudget ?? false;\n\n // Total context budget when shared budget is enabled\n const totalBudget = messageTokens + observationTokens;\n\n // Async buffering is disabled when:\n // - bufferTokens: false is explicitly set\n // - scope is 'resource' and the user did NOT explicitly configure async buffering\n // (if they did, validateBufferConfig will throw a helpful error)\n const userExplicitlyConfiguredAsync =\n config.observation?.bufferTokens !== undefined ||\n config.observation?.bufferActivation !== undefined ||\n config.reflection?.bufferActivation !== undefined;\n const asyncBufferingDisabled =\n config.observation?.bufferTokens === false || (config.scope === 'resource' && !userExplicitlyConfiguredAsync);\n\n // shareTokenBudget is not yet compatible with async buffering (temporary limitation).\n // To use shareTokenBudget, users must explicitly disable buffering.\n if (isSharedBudget && !asyncBufferingDisabled) {\n const common =\n `shareTokenBudget requires async buffering to be disabled (this is a temporary limitation). ` +\n `Add observation: { bufferTokens: false } to your config:\\n\\n` +\n ` observationalMemory: {\\n` +\n ` shareTokenBudget: true,\\n` +\n ` observation: { bufferTokens: false },\\n` +\n ` }\\n`;\n if (userExplicitlyConfiguredAsync) {\n throw new Error(\n common + `\\nRemove any other async buffering settings (bufferTokens, bufferActivation, blockAfter).`,\n );\n } else {\n throw new Error(\n common + `\\nAsync buffering is enabled by default — this opt-out is only needed when using shareTokenBudget.`,\n );\n }\n }\n\n // Resolve observation config with defaults\n this.observationConfig = {\n model: observationModel,\n // When shared budget, store as range: min = base threshold, max = total budget\n // This allows messages to expand into unused observation space\n messageTokens: isSharedBudget ? { min: messageTokens, max: totalBudget } : messageTokens,\n shareTokenBudget: isSharedBudget,\n modelSettings: {\n temperature:\n config.observation?.modelSettings?.temperature ??\n OBSERVATIONAL_MEMORY_DEFAULTS.observation.modelSettings.temperature,\n maxOutputTokens:\n config.observation?.modelSettings?.maxOutputTokens ??\n OBSERVATIONAL_MEMORY_DEFAULTS.observation.modelSettings.maxOutputTokens,\n },\n providerOptions: config.observation?.providerOptions ?? OBSERVATIONAL_MEMORY_DEFAULTS.observation.providerOptions,\n maxTokensPerBatch:\n config.observation?.maxTokensPerBatch ?? OBSERVATIONAL_MEMORY_DEFAULTS.observation.maxTokensPerBatch,\n bufferTokens: asyncBufferingDisabled\n ? undefined\n : this.resolveBufferTokens(\n config.observation?.bufferTokens ?? OBSERVATIONAL_MEMORY_DEFAULTS.observation.bufferTokens,\n config.observation?.messageTokens ?? OBSERVATIONAL_MEMORY_DEFAULTS.observation.messageTokens,\n ),\n bufferActivation: asyncBufferingDisabled\n ? undefined\n : (config.observation?.bufferActivation ?? OBSERVATIONAL_MEMORY_DEFAULTS.observation.bufferActivation),\n blockAfter: asyncBufferingDisabled\n ? undefined\n : this.resolveBlockAfter(\n config.observation?.blockAfter ??\n ((config.observation?.bufferTokens ?? OBSERVATIONAL_MEMORY_DEFAULTS.observation.bufferTokens)\n ? 1.2\n : undefined),\n config.observation?.messageTokens ?? OBSERVATIONAL_MEMORY_DEFAULTS.observation.messageTokens,\n ),\n instruction: config.observation?.instruction,\n };\n\n // Resolve reflection config with defaults\n this.reflectionConfig = {\n model: reflectionModel,\n observationTokens: observationTokens,\n shareTokenBudget: isSharedBudget,\n modelSettings: {\n temperature:\n config.reflection?.modelSettings?.temperature ??\n OBSERVATIONAL_MEMORY_DEFAULTS.reflection.modelSettings.temperature,\n maxOutputTokens:\n config.reflection?.modelSettings?.maxOutputTokens ??\n OBSERVATIONAL_MEMORY_DEFAULTS.reflection.modelSettings.maxOutputTokens,\n },\n providerOptions: config.reflection?.providerOptions ?? OBSERVATIONAL_MEMORY_DEFAULTS.reflection.providerOptions,\n bufferActivation: asyncBufferingDisabled\n ? undefined\n : (config?.reflection?.bufferActivation ?? OBSERVATIONAL_MEMORY_DEFAULTS.reflection.bufferActivation),\n blockAfter: asyncBufferingDisabled\n ? undefined\n : this.resolveBlockAfter(\n config.reflection?.blockAfter ??\n ((config.reflection?.bufferActivation ?? OBSERVATIONAL_MEMORY_DEFAULTS.reflection.bufferActivation)\n ? 1.2\n : undefined),\n config.reflection?.observationTokens ?? OBSERVATIONAL_MEMORY_DEFAULTS.reflection.observationTokens,\n ),\n instruction: config.reflection?.instruction,\n };\n\n this.tokenCounter = new TokenCounter();\n this.onDebugEvent = config.onDebugEvent;\n\n // Create internal MessageHistory for message persistence\n // OM handles message saving itself (in processOutputStep) instead of relying on\n // the Memory class's MessageHistory processor\n this.messageHistory = new MessageHistory({ storage: this.storage });\n\n // Validate buffer configuration\n this.validateBufferConfig();\n\n omDebug(\n `[OM:init] new ObservationalMemory instance created — scope=${this.scope}, messageTokens=${JSON.stringify(this.observationConfig.messageTokens)}, obsAsyncEnabled=${this.isAsyncObservationEnabled()}, bufferTokens=${this.observationConfig.bufferTokens}, bufferActivation=${this.observationConfig.bufferActivation}, blockAfter=${this.observationConfig.blockAfter}, reflectionTokens=${this.reflectionConfig.observationTokens}, refAsyncEnabled=${this.isAsyncReflectionEnabled()}, refAsyncActivation=${this.reflectionConfig.bufferActivation}, refBlockAfter=${this.reflectionConfig.blockAfter}`,\n );\n }\n\n /**\n * Get the current configuration for this OM instance.\n * Used by the server to expose config to the UI when OM is added via processors.\n */\n get config(): {\n scope: 'resource' | 'thread';\n observation: {\n messageTokens: number | ThresholdRange;\n };\n reflection: {\n observationTokens: number | ThresholdRange;\n };\n } {\n return {\n scope: this.scope,\n observation: {\n messageTokens: this.observationConfig.messageTokens,\n },\n reflection: {\n observationTokens: this.reflectionConfig.observationTokens,\n },\n };\n }\n\n /**\n * Wait for any in-flight async buffering operations for the given thread/resource.\n * Used by server endpoints to block until buffering completes so the UI can get final state.\n */\n async waitForBuffering(\n threadId: string | null | undefined,\n resourceId: string | null | undefined,\n timeoutMs = 30000,\n ): Promise<void> {\n return ObservationalMemory.awaitBuffering(threadId, resourceId, this.scope, timeoutMs);\n }\n\n /**\n * Get the full config including resolved model names.\n * This is async because it needs to resolve the model configs.\n */\n async getResolvedConfig(requestContext?: RequestContext): Promise<{\n scope: 'resource' | 'thread';\n observation: {\n messageTokens: number | ThresholdRange;\n model: string;\n };\n reflection: {\n observationTokens: number | ThresholdRange;\n model: string;\n };\n }> {\n // Helper to get the model config to resolve (handles ModelWithRetries[] by taking first)\n const getModelToResolve = (model: AgentConfig['model']) => {\n if (Array.isArray(model)) {\n return model[0]?.model ?? 'unknown';\n }\n return model;\n };\n\n // Format as provider/modelId (e.g., \"google/gemini-2.5-flash\")\n const formatModelName = (model: { provider?: string; modelId: string }) => {\n return model.provider ? `${model.provider}/${model.modelId}` : model.modelId;\n };\n\n // Helper to safely resolve a model config\n const safeResolveModel = async (modelConfig: AgentConfig['model']): Promise<string> => {\n const modelToResolve = getModelToResolve(modelConfig);\n\n try {\n // resolveModelConfig handles both static configs and functions\n const resolved = await resolveModelConfig(modelToResolve, requestContext);\n return formatModelName(resolved);\n } catch (error) {\n // If resolution fails, return a placeholder\n omError('[OM] Failed to resolve model config', error);\n return '(unknown)';\n }\n };\n\n const [observationModelName, reflectionModelName] = await Promise.all([\n safeResolveModel(this.observationConfig.model),\n safeResolveModel(this.reflectionConfig.model),\n ]);\n\n return {\n scope: this.scope,\n observation: {\n messageTokens: this.observationConfig.messageTokens,\n model: observationModelName,\n },\n reflection: {\n observationTokens: this.reflectionConfig.observationTokens,\n model: reflectionModelName,\n },\n };\n }\n\n /**\n * Emit a debug event if the callback is configured\n */\n private emitDebugEvent(event: ObservationDebugEvent): void {\n if (this.onDebugEvent) {\n this.onDebugEvent(event);\n }\n }\n\n /**\n * Validate buffer configuration on first use.\n * Ensures bufferTokens is less than the threshold and bufferActivation is valid.\n */\n private validateBufferConfig(): void {\n // Async buffering is not yet supported with resource scope\n const hasAsyncBuffering =\n this.observationConfig.bufferTokens !== undefined ||\n this.observationConfig.bufferActivation !== undefined ||\n this.reflectionConfig.bufferActivation !== undefined;\n if (hasAsyncBuffering && this.scope === 'resource') {\n throw new Error(\n `Async buffering is not yet supported with scope: 'resource'. ` +\n `Use scope: 'thread', or set observation: { bufferTokens: false } to disable async buffering.`,\n );\n }\n\n // Validate observation bufferTokens\n const observationThreshold = this.getMaxThreshold(this.observationConfig.messageTokens);\n if (this.observationConfig.bufferTokens !== undefined) {\n if (this.observationConfig.bufferTokens <= 0) {\n throw new Error(`observation.bufferTokens must be > 0, got ${this.observationConfig.bufferTokens}`);\n }\n if (this.observationConfig.bufferTokens >= observationThreshold) {\n throw new Error(\n `observation.bufferTokens (${this.observationConfig.bufferTokens}) must be less than messageTokens (${observationThreshold})`,\n );\n }\n }\n\n // Validate observation bufferActivation: (0, 1] for ratio, or >= 1000 for absolute retention tokens\n if (this.observationConfig.bufferActivation !== undefined) {\n if (this.observationConfig.bufferActivation <= 0) {\n throw new Error(`observation.bufferActivation must be > 0, got ${this.observationConfig.bufferActivation}`);\n }\n if (this.observationConfig.bufferActivation > 1 && this.observationConfig.bufferActivation < 1000) {\n throw new Error(\n `observation.bufferActivation must be <= 1 (ratio) or >= 1000 (absolute token retention), got ${this.observationConfig.bufferActivation}`,\n );\n }\n if (\n this.observationConfig.bufferActivation >= 1000 &&\n this.observationConfig.bufferActivation >= observationThreshold\n ) {\n throw new Error(\n `observation.bufferActivation as absolute retention (${this.observationConfig.bufferActivation}) must be less than messageTokens (${observationThreshold})`,\n );\n }\n }\n\n // Validate observation blockAfter\n if (this.observationConfig.blockAfter !== undefined) {\n if (this.observationConfig.blockAfter < observationThreshold) {\n throw new Error(\n `observation.blockAfter (${this.observationConfig.blockAfter}) must be >= messageTokens (${observationThreshold})`,\n );\n }\n if (!this.observationConfig.bufferTokens) {\n throw new Error(\n `observation.blockAfter requires observation.bufferTokens to be set (blockAfter only applies when async buffering is enabled)`,\n );\n }\n }\n\n // Validate reflection bufferActivation (0-1 float range)\n if (this.reflectionConfig.bufferActivation !== undefined) {\n if (this.reflectionConfig.bufferActivation <= 0 || this.reflectionConfig.bufferActivation > 1) {\n throw new Error(\n `reflection.bufferActivation must be in range (0, 1], got ${this.reflectionConfig.bufferActivation}`,\n );\n }\n }\n\n // Validate reflection blockAfter\n if (this.reflectionConfig.blockAfter !== undefined) {\n const reflectionThreshold = this.getMaxThreshold(this.reflectionConfig.observationTokens);\n if (this.reflectionConfig.blockAfter < reflectionThreshold) {\n throw new Error(\n `reflection.blockAfter (${this.reflectionConfig.blockAfter}) must be >= reflection.observationTokens (${reflectionThreshold})`,\n );\n }\n if (!this.reflectionConfig.bufferActivation) {\n throw new Error(\n `reflection.blockAfter requires reflection.bufferActivation to be set (blockAfter only applies when async reflection is enabled)`,\n );\n }\n }\n }\n\n /**\n * Resolve bufferTokens: if it's a fraction (0 < value < 1), multiply by messageTokens threshold.\n * Otherwise return the absolute token count.\n */\n private resolveBufferTokens(\n bufferTokens: number | false | undefined,\n messageTokens: number | ThresholdRange,\n ): number | undefined {\n if (bufferTokens === false) return undefined;\n if (bufferTokens === undefined) return undefined;\n if (bufferTokens > 0 && bufferTokens < 1) {\n const threshold = typeof messageTokens === 'number' ? messageTokens : messageTokens.max;\n return Math.round(threshold * bufferTokens);\n }\n return bufferTokens;\n }\n\n /**\n * Resolve blockAfter config value.\n * Values between 1 and 2 (exclusive) are treated as multipliers of the threshold.\n * e.g. blockAfter: 1.5 with messageTokens: 20_000 → 30_000\n * Values >= 2 are treated as absolute token counts.\n * Defaults to 1.2 (120% of threshold) when async buffering is enabled but blockAfter is omitted.\n */\n private resolveBlockAfter(\n blockAfter: number | undefined,\n messageTokens: number | ThresholdRange,\n ): number | undefined {\n if (blockAfter === undefined) return undefined;\n // Values between 1 (inclusive) and 2 (exclusive) are treated as multipliers of the threshold.\n // e.g. blockAfter: 1.5 means 1.5x the threshold. blockAfter: 1 means exactly at threshold.\n // Values >= 2 are treated as absolute token counts.\n if (blockAfter >= 1 && blockAfter < 2) {\n const threshold = typeof messageTokens === 'number' ? messageTokens : messageTokens.max;\n return Math.round(threshold * blockAfter);\n }\n return blockAfter;\n }\n\n /**\n * Get the maximum value from a threshold (simple number or range)\n */\n private getMaxThreshold(threshold: number | ThresholdRange): number {\n if (typeof threshold === 'number') {\n return threshold;\n }\n return threshold.max;\n }\n\n /**\n * Calculate dynamic threshold based on observation space.\n * When shareTokenBudget is enabled, the message threshold can expand\n * into unused observation space, up to the total context budget.\n *\n * Total budget = messageTokens + observationTokens\n * Effective threshold = totalBudget - currentObservationTokens\n *\n * Example with 30k:40k thresholds (70k total):\n * - 0 observations → messages can use ~70k\n * - 10k observations → messages can use ~60k\n * - 40k observations → messages back to ~30k\n */\n private calculateDynamicThreshold(threshold: number | ThresholdRange, currentObservationTokens: number): number {\n // If not using adaptive threshold (simple number), return as-is\n if (typeof threshold === 'number') {\n return threshold;\n }\n\n // Adaptive threshold: use remaining space in total budget\n // Total budget is stored as threshold.max (base + reflection threshold)\n // Base threshold is stored as threshold.min\n const totalBudget = threshold.max;\n const baseThreshold = threshold.min;\n\n // Effective threshold = total budget minus current observations\n // But never go below the base threshold\n const effectiveThreshold = Math.max(totalBudget - currentObservationTokens, baseThreshold);\n\n return Math.round(effectiveThreshold);\n }\n\n /**\n * Check whether the unobserved message tokens meet the observation threshold.\n */\n private meetsObservationThreshold(opts: {\n record: ObservationalMemoryRecord;\n unobservedTokens: number;\n extraTokens?: number;\n }): boolean {\n const { record, unobservedTokens, extraTokens = 0 } = opts;\n const pendingTokens = (record.pendingMessageTokens ?? 0) + unobservedTokens + extraTokens;\n const currentObservationTokens = record.observationTokenCount ?? 0;\n const threshold = this.calculateDynamicThreshold(this.observationConfig.messageTokens, currentObservationTokens);\n return pendingTokens >= threshold;\n }\n\n /**\n * Get or create the Observer agent\n */\n private getObserverAgent(): Agent {\n if (!this.observerAgent) {\n const systemPrompt = buildObserverSystemPrompt(false, this.observationConfig.instruction);\n\n this.observerAgent = new Agent({\n id: 'observational-memory-observer',\n name: 'Observer',\n instructions: systemPrompt,\n model: this.observationConfig.model,\n });\n }\n return this.observerAgent;\n }\n\n /**\n * Get or create the Reflector agent\n */\n private getReflectorAgent(): Agent {\n if (!this.reflectorAgent) {\n const systemPrompt = buildReflectorSystemPrompt(this.reflectionConfig.instruction);\n\n this.reflectorAgent = new Agent({\n id: 'observational-memory-reflector',\n name: 'Reflector',\n instructions: systemPrompt,\n model: this.reflectionConfig.model,\n });\n }\n return this.reflectorAgent;\n }\n\n /**\n * Get thread/resource IDs for storage lookup\n */\n private getStorageIds(threadId: string, resourceId?: string): { threadId: string | null; resourceId: string } {\n if (this.scope === 'resource') {\n return {\n threadId: null,\n resourceId: resourceId ?? threadId,\n };\n }\n if (!threadId) {\n throw new Error(\n `ObservationalMemory (scope: 'thread') requires a threadId, but received an empty value. ` +\n `This is a bug — getThreadContext should have caught this earlier.`,\n );\n }\n return {\n threadId,\n resourceId: resourceId ?? threadId,\n };\n }\n\n /**\n * Get or create the observational memory record.\n * Returns the existing record if one exists, otherwise initializes a new one.\n */\n async getOrCreateRecord(threadId: string, resourceId?: string): Promise<ObservationalMemoryRecord> {\n const ids = this.getStorageIds(threadId, resourceId);\n let record = await this.storage.getObservationalMemory(ids.threadId, ids.resourceId);\n\n if (!record) {\n // Capture the timezone used for Observer date formatting\n const observedTimezone = Intl.DateTimeFormat().resolvedOptions().timeZone;\n\n record = await this.storage.initializeObservationalMemory({\n threadId: ids.threadId,\n resourceId: ids.resourceId,\n scope: this.scope,\n config: {\n observation: this.observationConfig,\n reflection: this.reflectionConfig,\n scope: this.scope,\n },\n observedTimezone,\n });\n }\n\n return record;\n }\n\n /**\n * Check if we need to trigger reflection.\n */\n private shouldReflect(observationTokens: number): boolean {\n const threshold = this.getMaxThreshold(this.reflectionConfig.observationTokens);\n return observationTokens > threshold;\n }\n\n // ════════════════════════════════════════════════════════════════════════════\n // DATA-OM-OBSERVATION PART HELPERS (Start/End/Failed markers)\n // These helpers manage the observation boundary markers within messages.\n //\n // Flow:\n // 1. Before observation: [...messageParts]\n // 2. Insert start: [...messageParts, start] → stream to UI (loading state)\n // 3. After success: [...messageParts, start, end] → stream to UI (complete)\n // 4. After failure: [...messageParts, start, failed]\n //\n // For filtering, we look for the last completed observation (start + end pair).\n // A start without end means observation is in progress.\n // ════════════════════════════════════════════════════════════════════════════\n\n /**\n * Get current config snapshot for observation markers.\n */\n private getObservationMarkerConfig(): ObservationMarkerConfig {\n return {\n messageTokens: this.getMaxThreshold(this.observationConfig.messageTokens),\n observationTokens: this.getMaxThreshold(this.reflectionConfig.observationTokens),\n scope: this.scope,\n };\n }\n\n /**\n * Create a start marker for when observation begins.\n */\n private createObservationStartMarker(params: {\n cycleId: string;\n operationType: 'observation' | 'reflection';\n tokensToObserve: number;\n recordId: string;\n threadId: string;\n threadIds: string[];\n }): DataOmObservationStartPart {\n return {\n type: 'data-om-observation-start',\n data: {\n cycleId: params.cycleId,\n operationType: params.operationType,\n startedAt: new Date().toISOString(),\n tokensToObserve: params.tokensToObserve,\n recordId: params.recordId,\n threadId: params.threadId,\n threadIds: params.threadIds,\n config: this.getObservationMarkerConfig(),\n },\n };\n }\n\n /**\n * Create an end marker for when observation completes successfully.\n */\n private createObservationEndMarker(params: {\n cycleId: string;\n operationType: 'observation' | 'reflection';\n startedAt: string;\n tokensObserved: number;\n observationTokens: number;\n observations?: string;\n currentTask?: string;\n suggestedResponse?: string;\n recordId: string;\n threadId: string;\n }): DataOmObservationEndPart {\n const completedAt = new Date().toISOString();\n const durationMs = new Date(completedAt).getTime() - new Date(params.startedAt).getTime();\n\n return {\n type: 'data-om-observation-end',\n data: {\n cycleId: params.cycleId,\n operationType: params.operationType,\n completedAt,\n durationMs,\n tokensObserved: params.tokensObserved,\n observationTokens: params.observationTokens,\n observations: params.observations,\n currentTask: params.currentTask,\n suggestedResponse: params.suggestedResponse,\n recordId: params.recordId,\n threadId: params.threadId,\n },\n };\n }\n\n /**\n * Create a failed marker for when observation fails.\n */\n private createObservationFailedMarker(params: {\n cycleId: string;\n operationType: 'observation' | 'reflection';\n startedAt: string;\n tokensAttempted: number;\n error: string;\n recordId: string;\n threadId: string;\n }): DataOmObservationFailedPart {\n const failedAt = new Date().toISOString();\n const durationMs = new Date(failedAt).getTime() - new Date(params.startedAt).getTime();\n\n return {\n type: 'data-om-observation-failed',\n data: {\n cycleId: params.cycleId,\n operationType: params.operationType,\n failedAt,\n durationMs,\n tokensAttempted: params.tokensAttempted,\n error: params.error,\n recordId: params.recordId,\n threadId: params.threadId,\n },\n };\n }\n\n /**\n * Create a start marker for when async buffering begins.\n */\n private createBufferingStartMarker(params: {\n cycleId: string;\n operationType: OmOperationType;\n tokensToBuffer: number;\n recordId: string;\n threadId: string;\n threadIds: string[];\n }): DataOmBufferingStartPart {\n return {\n type: 'data-om-buffering-start',\n data: {\n cycleId: params.cycleId,\n operationType: params.operationType,\n startedAt: new Date().toISOString(),\n tokensToBuffer: params.tokensToBuffer,\n recordId: params.recordId,\n threadId: params.threadId,\n threadIds: params.threadIds,\n config: this.getObservationMarkerConfig(),\n },\n };\n }\n\n /**\n * Create an end marker for when async buffering completes successfully.\n */\n private createBufferingEndMarker(params: {\n cycleId: string;\n operationType: OmOperationType;\n startedAt: string;\n tokensBuffered: number;\n bufferedTokens: number;\n recordId: string;\n threadId: string;\n observations?: string;\n }): DataOmBufferingEndPart {\n const completedAt = new Date().toISOString();\n const durationMs = new Date(completedAt).getTime() - new Date(params.startedAt).getTime();\n\n return {\n type: 'data-om-buffering-end',\n data: {\n cycleId: params.cycleId,\n operationType: params.operationType,\n completedAt,\n durationMs,\n tokensBuffered: params.tokensBuffered,\n bufferedTokens: params.bufferedTokens,\n recordId: params.recordId,\n threadId: params.threadId,\n observations: params.observations,\n },\n };\n }\n\n /**\n * Create a failed marker for when async buffering fails.\n */\n private createBufferingFailedMarker(params: {\n cycleId: string;\n operationType: OmOperationType;\n startedAt: string;\n tokensAttempted: number;\n error: string;\n recordId: string;\n threadId: string;\n }): DataOmBufferingFailedPart {\n const failedAt = new Date().toISOString();\n const durationMs = new Date(failedAt).getTime() - new Date(params.startedAt).getTime();\n\n return {\n type: 'data-om-buffering-failed',\n data: {\n cycleId: params.cycleId,\n operationType: params.operationType,\n failedAt,\n durationMs,\n tokensAttempted: params.tokensAttempted,\n error: params.error,\n recordId: params.recordId,\n threadId: params.threadId,\n },\n };\n }\n\n /**\n * Create an activation marker for when buffered observations are activated.\n */\n private createActivationMarker(params: {\n cycleId: string;\n operationType: OmOperationType;\n chunksActivated: number;\n tokensActivated: number;\n observationTokens: number;\n messagesActivated: number;\n recordId: string;\n threadId: string;\n generationCount: number;\n observations?: string;\n }): DataOmActivationPart {\n return {\n type: 'data-om-activation',\n data: {\n cycleId: params.cycleId,\n operationType: params.operationType,\n activatedAt: new Date().toISOString(),\n chunksActivated: params.chunksActivated,\n tokensActivated: params.tokensActivated,\n observationTokens: params.observationTokens,\n messagesActivated: params.messagesActivated,\n recordId: params.recordId,\n threadId: params.threadId,\n generationCount: params.generationCount,\n config: this.getObservationMarkerConfig(),\n observations: params.observations,\n },\n };\n }\n\n /**\n * Persist a data-om-* marker part on the last assistant message in messageList\n * AND save the updated message to the DB so it survives page reload.\n * (data-* parts are filtered out before sending to the LLM, so they don't affect model calls.)\n */\n private async persistMarkerToMessage(\n marker: { type: string; data: unknown },\n messageList: MessageList | undefined,\n threadId: string,\n resourceId?: string,\n ): Promise<void> {\n if (!messageList) return;\n const allMsgs = messageList.get.all.db();\n // Find the last assistant message to attach the marker to\n for (let i = allMsgs.length - 1; i >= 0; i--) {\n const msg = allMsgs[i];\n if (msg?.role === 'assistant' && msg.content?.parts && Array.isArray(msg.content.parts)) {\n // Only push if the marker isn't already in the parts array.\n // writer.custom() adds the marker to the stream, and the AI SDK may have\n // already appended it to the message's parts before this runs.\n const markerData = marker.data as { cycleId?: string } | undefined;\n const alreadyPresent =\n markerData?.cycleId &&\n msg.content.parts.some((p: any) => p?.type === marker.type && p?.data?.cycleId === markerData.cycleId);\n if (!alreadyPresent) {\n msg.content.parts.push(marker as any);\n }\n // Upsert the modified message to DB so the marker part is persisted.\n // Non-critical — if this fails, the marker is still in the stream,\n // it just won't survive page reload.\n try {\n await this.messageHistory.persistMessages({\n messages: [msg],\n threadId,\n resourceId,\n });\n } catch (e) {\n omDebug(`[OM:persistMarker] failed to save marker to DB: ${e}`);\n }\n return;\n }\n }\n }\n\n /**\n * Persist a marker to the last assistant message in storage.\n * Unlike persistMarkerToMessage, this fetches messages directly from the DB\n * so it works even when no MessageList is available (e.g. async buffering ops).\n */\n private async persistMarkerToStorage(\n marker: { type: string; data: unknown },\n threadId: string,\n resourceId?: string,\n ): Promise<void> {\n try {\n const result = await this.storage.listMessages({\n threadId,\n perPage: 20,\n orderBy: { field: 'createdAt', direction: 'DESC' },\n });\n const messages = result?.messages ?? [];\n // Find the last assistant message\n for (const msg of messages) {\n if (msg?.role === 'assistant' && msg.content?.parts && Array.isArray(msg.content.parts)) {\n // Only push if the marker isn't already in the parts array.\n const markerData = marker.data as { cycleId?: string } | undefined;\n const alreadyPresent =\n markerData?.cycleId &&\n msg.content.parts.some((p: any) => p?.type === marker.type && p?.data?.cycleId === markerData.cycleId);\n if (!alreadyPresent) {\n msg.content.parts.push(marker as any);\n }\n await this.messageHistory.persistMessages({\n messages: [msg],\n threadId,\n resourceId,\n });\n return;\n }\n }\n } catch (e) {\n omDebug(`[OM:persistMarkerToStorage] failed to save marker to DB: ${e}`);\n }\n }\n\n /**\n * Find the last completed observation boundary in a message's parts.\n * A completed observation is a start marker followed by an end marker.\n *\n * Returns the index of the END marker (which is the observation boundary),\n * or -1 if no completed observation is found.\n */\n private findLastCompletedObservationBoundary(message: MastraDBMessage): number {\n const parts = message.content?.parts;\n if (!parts || !Array.isArray(parts)) return -1;\n\n // Search from the end to find the most recent end marker\n for (let i = parts.length - 1; i >= 0; i--) {\n const part = parts[i] as { type?: string };\n if (part?.type === 'data-om-observation-end') {\n // Found an end marker - this is the observation boundary\n return i;\n }\n }\n return -1;\n }\n\n /**\n * Check if a message has an in-progress observation (start without end).\n */\n private hasInProgressObservation(message: MastraDBMessage): boolean {\n const parts = message.content?.parts;\n if (!parts || !Array.isArray(parts)) return false;\n\n let lastStartIndex = -1;\n let lastEndOrFailedIndex = -1;\n\n for (let i = parts.length - 1; i >= 0; i--) {\n const part = parts[i] as { type?: string };\n if (part?.type === 'data-om-observation-start' && lastStartIndex === -1) {\n lastStartIndex = i;\n }\n if (\n (part?.type === 'data-om-observation-end' || part?.type === 'data-om-observation-failed') &&\n lastEndOrFailedIndex === -1\n ) {\n lastEndOrFailedIndex = i;\n }\n }\n\n // In progress if we have a start that comes after any end/failed\n return lastStartIndex !== -1 && lastStartIndex > lastEndOrFailedIndex;\n }\n\n /**\n * Seal messages to prevent new parts from being merged into them.\n * This is used when starting buffering to capture the current content state.\n *\n * Sealing works by:\n * 1. Setting `message.content.metadata.mastra.sealed = true` (message-level flag)\n * 2. Adding `metadata.mastra.sealedAt` to the last part (boundary marker)\n *\n * When MessageList.add() receives a message with the same ID as a sealed message,\n * it creates a new message with only the parts beyond the seal boundary.\n *\n * The messages are mutated in place - since they're references to the same objects\n * in the MessageList, the seal will be recognized immediately.\n *\n * @param messages - Messages to seal (mutated in place)\n */\n private sealMessagesForBuffering(messages: MastraDBMessage[]): void {\n const sealedAt = Date.now();\n\n for (const msg of messages) {\n if (!msg.content?.parts?.length) continue;\n\n // Set message-level sealed flag\n if (!msg.content.metadata) {\n msg.content.metadata = {};\n }\n const metadata = msg.content.metadata as { mastra?: { sealed?: boolean } };\n if (!metadata.mastra) {\n metadata.mastra = {};\n }\n metadata.mastra.sealed = true;\n\n // Add sealedAt to the last part\n const lastPart = msg.content.parts[msg.content.parts.length - 1] as {\n metadata?: { mastra?: { sealedAt?: number } };\n };\n if (!lastPart.metadata) {\n lastPart.metadata = {};\n }\n if (!lastPart.metadata.mastra) {\n lastPart.metadata.mastra = {};\n }\n lastPart.metadata.mastra.sealedAt = sealedAt;\n }\n }\n\n /**\n * Insert an observation marker into a message.\n * The marker is appended directly to the message's parts array (mutating in place).\n * Also persists the change to storage so markers survive page refresh.\n *\n * For end/failed markers, the message is also \"sealed\" to prevent future content\n * from being merged into it. This ensures observation markers are preserved.\n */\n /**\n * Insert an observation marker into a message.\n * For start markers, this pushes the part directly.\n * For end/failed markers, this should be called AFTER writer.custom() has added the part,\n * so we just find the part and add sealing metadata.\n */\n\n /**\n * Get unobserved parts from a message.\n * If the message has a completed observation (start + end), only return parts after the end.\n * If observation is in progress (start without end), include parts before the start.\n * Otherwise, return all parts.\n */\n private getUnobservedParts(message: MastraDBMessage): MastraDBMessage['content']['parts'] {\n const parts = message.content?.parts;\n if (!parts || !Array.isArray(parts)) return [];\n\n const endMarkerIndex = this.findLastCompletedObservationBoundary(message);\n if (endMarkerIndex === -1) {\n // No completed observation - all parts are unobserved\n // (This includes the case where observation is in progress)\n return parts.filter(p => {\n const part = p as { type?: string };\n // Exclude start markers that are in progress\n return part?.type !== 'data-om-observation-start';\n });\n }\n\n // Return only parts after the end marker (excluding start/end/failed markers)\n return parts.slice(endMarkerIndex + 1).filter(p => {\n const part = p as { type?: string };\n return !part?.type?.startsWith('data-om-observation-');\n });\n }\n\n /**\n * Check if a message has any unobserved parts.\n */\n private hasUnobservedParts(message: MastraDBMessage): boolean {\n return this.getUnobservedParts(message).length > 0;\n }\n\n /**\n * Create a virtual message containing only the unobserved parts.\n * This is used for token counting and observation.\n */\n private createUnobservedMessage(message: MastraDBMessage): MastraDBMessage | null {\n const unobservedParts = this.getUnobservedParts(message);\n if (unobservedParts.length === 0) return null;\n\n return {\n ...message,\n content: {\n ...message.content,\n parts: unobservedParts,\n },\n };\n }\n\n /**\n * Get unobserved messages with part-level filtering.\n *\n * This method uses data-om-observation-end markers to filter at the part level:\n * 1. For messages WITH a completed observation: only return parts AFTER the end marker\n * 2. For messages WITHOUT completed observation: check timestamp against lastObservedAt\n *\n * This handles the case where a single message accumulates many parts\n * (like tool calls) during an agentic loop - we only observe the new parts.\n */\n private getUnobservedMessages(\n allMessages: MastraDBMessage[],\n record: ObservationalMemoryRecord,\n opts?: { excludeBuffered?: boolean },\n ): MastraDBMessage[] {\n const lastObservedAt = record.lastObservedAt;\n // Safeguard: track message IDs that were already observed to prevent re-observation\n // This handles edge cases like process restarts where lastObservedAt might not capture all messages\n const observedMessageIds = new Set<string>(\n Array.isArray(record.observedMessageIds) ? record.observedMessageIds : [],\n );\n\n // Only exclude buffered chunk message IDs when called from the buffering path.\n // The main agent context should still see buffered messages until activation.\n if (opts?.excludeBuffered) {\n const bufferedChunks = this.getBufferedChunks(record);\n for (const chunk of bufferedChunks) {\n if (Array.isArray(chunk.messageIds)) {\n for (const id of chunk.messageIds) {\n observedMessageIds.add(id);\n }\n }\n }\n }\n\n if (!lastObservedAt && observedMessageIds.size === 0) {\n // No observations yet - all messages are unobserved\n return allMessages;\n }\n\n const result: MastraDBMessage[] = [];\n\n for (const msg of allMessages) {\n // First check: skip if this message ID was already observed (safeguard against re-observation)\n if (observedMessageIds?.has(msg.id)) {\n continue;\n }\n\n // Check if this message has a completed observation\n const endMarkerIndex = this.findLastCompletedObservationBoundary(msg);\n const inProgress = this.hasInProgressObservation(msg);\n\n if (inProgress) {\n // Include the full message for in-progress observations\n // The Observer is currently working on this\n result.push(msg);\n } else if (endMarkerIndex !== -1) {\n // Message has a completed observation - only include parts after it\n const virtualMsg = this.createUnobservedMessage(msg);\n if (virtualMsg) {\n result.push(virtualMsg);\n } else {\n }\n } else {\n // No observation markers - fall back to timestamp-based filtering\n if (!msg.createdAt || !lastObservedAt) {\n // Messages without timestamps are always included\n // Also include messages when there's no lastObservedAt timestamp\n result.push(msg);\n } else {\n const msgDate = new Date(msg.createdAt);\n if (msgDate > lastObservedAt) {\n result.push(msg);\n } else {\n }\n }\n }\n }\n\n return result;\n }\n\n /**\n * Wrapper for observer/reflector agent.generate() calls that checks for abort.\n * agent.generate() returns an empty result on abort instead of throwing,\n * so we must check the signal before and after the call.\n * Retries are handled by Mastra's built-in p-retry at the model execution layer.\n */\n private async withAbortCheck<T>(fn: () => Promise<T>, abortSignal?: AbortSignal): Promise<T> {\n if (abortSignal?.aborted) {\n throw new Error('The operation was aborted.');\n }\n\n const result = await fn();\n\n if (abortSignal?.aborted) {\n throw new Error('The operation was aborted.');\n }\n\n return result;\n }\n\n /**\n * Call the Observer agent to extract observations.\n */\n private async callObserver(\n existingObservations: string | undefined,\n messagesToObserve: MastraDBMessage[],\n abortSignal?: AbortSignal,\n options?: { skipContinuationHints?: boolean; requestContext?: RequestContext },\n ): Promise<{\n observations: string;\n currentTask?: string;\n suggestedContinuation?: string;\n usage?: { inputTokens?: number; outputTokens?: number; totalTokens?: number };\n }> {\n const agent = this.getObserverAgent();\n\n const prompt = buildObserverPrompt(existingObservations, messagesToObserve, options);\n\n const doGenerate = async () => {\n const result = await this.withAbortCheck(\n () =>\n agent.generate(prompt, {\n modelSettings: {\n ...this.observationConfig.modelSettings,\n },\n providerOptions: this.observationConfig.providerOptions as any,\n ...(abortSignal ? { abortSignal } : {}),\n ...(options?.requestContext ? { requestContext: options.requestContext } : {}),\n }),\n abortSignal,\n );\n return result;\n };\n\n let result = await doGenerate();\n let parsed = parseObserverOutput(result.text);\n\n // Retry once if degenerate repetition was detected\n if (parsed.degenerate) {\n omDebug(`[OM:callObserver] degenerate repetition detected, retrying once`);\n result = await doGenerate();\n parsed = parseObserverOutput(result.text);\n if (parsed.degenerate) {\n omDebug(`[OM:callObserver] degenerate repetition on retry, failing`);\n throw new Error('Observer produced degenerate output after retry');\n }\n }\n\n // Extract usage from result (totalUsage or usage)\n const usage = result.totalUsage ?? result.usage;\n\n return {\n observations: parsed.observations,\n currentTask: parsed.currentTask,\n suggestedContinuation: parsed.suggestedContinuation,\n usage: usage\n ? {\n inputTokens: usage.inputTokens,\n outputTokens: usage.outputTokens,\n totalTokens: usage.totalTokens,\n }\n : undefined,\n };\n }\n\n /**\n * Call the Observer agent for multiple threads in a single batched request.\n * This is more efficient than calling the Observer for each thread individually.\n * Returns per-thread results with observations, currentTask, and suggestedContinuation,\n * plus the total usage for the batch.\n */\n private async callMultiThreadObserver(\n existingObservations: string | undefined,\n messagesByThread: Map<string, MastraDBMessage[]>,\n threadOrder: string[],\n abortSignal?: AbortSignal,\n requestContext?: RequestContext,\n ): Promise<{\n results: Map<\n string,\n {\n observations: string;\n currentTask?: string;\n suggestedContinuation?: string;\n }\n >;\n usage?: { inputTokens?: number; outputTokens?: number; totalTokens?: number };\n }> {\n // Create a multi-thread observer agent with the special system prompt\n const agent = new Agent({\n id: 'multi-thread-observer',\n name: 'multi-thread-observer',\n model: this.observationConfig.model,\n instructions: buildObserverSystemPrompt(true, this.observationConfig.instruction),\n });\n\n const prompt = buildMultiThreadObserverPrompt(existingObservations, messagesByThread, threadOrder);\n\n // Flatten all messages for context dump\n const allMessages: MastraDBMessage[] = [];\n for (const msgs of messagesByThread.values()) {\n allMessages.push(...msgs);\n }\n\n // Mark all messages as observed (skip any already-observed)\n for (const msg of allMessages) {\n this.observedMessageIds.add(msg.id);\n }\n\n const doGenerate = async () => {\n return this.withAbortCheck(\n () =>\n agent.generate(prompt, {\n modelSettings: {\n ...this.observationConfig.modelSettings,\n },\n providerOptions: this.observationConfig.providerOptions as any,\n ...(abortSignal ? { abortSignal } : {}),\n ...(requestContext ? { requestContext } : {}),\n }),\n abortSignal,\n );\n };\n\n let result = await doGenerate();\n let parsed = parseMultiThreadObserverOutput(result.text);\n\n // Retry once if degenerate repetition was detected\n if (parsed.degenerate) {\n omDebug(`[OM:callMultiThreadObserver] degenerate repetition detected, retrying once`);\n result = await doGenerate();\n parsed = parseMultiThreadObserverOutput(result.text);\n if (parsed.degenerate) {\n omDebug(`[OM:callMultiThreadObserver] degenerate repetition on retry, failing`);\n throw new Error('Multi-thread observer produced degenerate output after retry');\n }\n }\n\n // Convert to the expected return format\n const results = new Map<\n string,\n {\n observations: string;\n currentTask?: string;\n suggestedContinuation?: string;\n }\n >();\n\n for (const [threadId, threadResult] of parsed.threads) {\n results.set(threadId, {\n observations: threadResult.observations,\n currentTask: threadResult.currentTask,\n suggestedContinuation: threadResult.suggestedContinuation,\n });\n }\n\n // If some threads didn't get results, log a warning\n for (const threadId of threadOrder) {\n if (!results.has(threadId)) {\n // Add empty result so we still update the cursor\n results.set(threadId, { observations: '' });\n }\n }\n\n // Extract usage from result\n const usage = result.totalUsage ?? result.usage;\n\n return {\n results,\n usage: usage\n ? {\n inputTokens: usage.inputTokens,\n outputTokens: usage.outputTokens,\n totalTokens: usage.totalTokens,\n }\n : undefined,\n };\n }\n\n /**\n * Call the Reflector agent to condense observations.\n * Includes compression validation and retry logic.\n */\n private async callReflector(\n observations: string,\n manualPrompt?: string,\n streamContext?: {\n writer?: ProcessorStreamWriter;\n cycleId: string;\n startedAt: string;\n recordId: string;\n threadId: string;\n },\n observationTokensThreshold?: number,\n abortSignal?: AbortSignal,\n skipContinuationHints?: boolean,\n compressionStartLevel?: 0 | 1 | 2 | 3,\n requestContext?: RequestContext,\n ): Promise<{\n observations: string;\n suggestedContinuation?: string;\n usage?: { inputTokens?: number; outputTokens?: number; totalTokens?: number };\n }> {\n const agent = this.getReflectorAgent();\n\n const originalTokens = this.tokenCounter.countObservations(observations);\n\n // Get the target threshold - use provided value or fall back to config\n const targetThreshold = observationTokensThreshold ?? this.getMaxThreshold(this.reflectionConfig.observationTokens);\n\n // Track total usage across attempts\n let totalUsage = { inputTokens: 0, outputTokens: 0, totalTokens: 0 };\n\n // Attempt reflection with escalating compression levels.\n // Start at the provided level and retry up to level 3 if compression fails.\n let currentLevel: 0 | 1 | 2 | 3 = compressionStartLevel ?? 0;\n const maxLevel: 0 | 1 | 2 | 3 = 3;\n let parsed: ReturnType<typeof parseReflectorOutput> = { observations: '', suggestedContinuation: undefined };\n let reflectedTokens = 0;\n let attemptNumber = 0;\n\n while (currentLevel <= maxLevel) {\n attemptNumber++;\n const isRetry = attemptNumber > 1;\n\n const prompt = buildReflectorPrompt(observations, manualPrompt, currentLevel, skipContinuationHints);\n omDebug(\n `[OM:callReflector] ${isRetry ? `retry #${attemptNumber - 1}` : 'first attempt'}: level=${currentLevel}, originalTokens=${originalTokens}, targetThreshold=${targetThreshold}, promptLen=${prompt.length}, skipContinuationHints=${skipContinuationHints}`,\n );\n\n let chunkCount = 0;\n const result = await this.withAbortCheck(\n () =>\n agent.generate(prompt, {\n modelSettings: {\n ...this.reflectionConfig.modelSettings,\n },\n providerOptions: this.reflectionConfig.providerOptions as any,\n ...(abortSignal ? { abortSignal } : {}),\n ...(requestContext ? { requestContext } : {}),\n ...(attemptNumber === 1\n ? {\n onChunk(chunk: any) {\n chunkCount++;\n if (chunkCount === 1 || chunkCount % 50 === 0) {\n const preview =\n chunk.type === 'text-delta'\n ? ` text=\"${chunk.textDelta?.slice(0, 80)}...\"`\n : chunk.type === 'tool-call'\n ? ` tool=${chunk.toolName}`\n : '';\n omDebug(`[OM:callReflector] chunk#${chunkCount}: type=${chunk.type}${preview}`);\n }\n },\n onFinish(event: any) {\n omDebug(\n `[OM:callReflector] onFinish: chunks=${chunkCount}, finishReason=${event.finishReason}, inputTokens=${event.usage?.inputTokens}, outputTokens=${event.usage?.outputTokens}, textLen=${event.text?.length}`,\n );\n },\n onAbort(event: any) {\n omDebug(`[OM:callReflector] onAbort: chunks=${chunkCount}, reason=${event?.reason ?? 'unknown'}`);\n },\n onError({ error }: { error: unknown }) {\n omError(`[OM:callReflector] onError after ${chunkCount} chunks`, error);\n },\n }\n : {}),\n }),\n abortSignal,\n );\n\n omDebug(\n `[OM:callReflector] attempt #${attemptNumber} returned: textLen=${result.text?.length}, textPreview=\"${result.text?.slice(0, 120)}...\", inputTokens=${result.usage?.inputTokens ?? result.totalUsage?.inputTokens}, outputTokens=${result.usage?.outputTokens ?? result.totalUsage?.outputTokens}`,\n );\n\n // Accumulate usage\n const usage = result.totalUsage ?? result.usage;\n if (usage) {\n totalUsage.inputTokens += usage.inputTokens ?? 0;\n totalUsage.outputTokens += usage.outputTokens ?? 0;\n totalUsage.totalTokens += usage.totalTokens ?? 0;\n }\n\n parsed = parseReflectorOutput(result.text);\n\n // If degenerate repetition detected, treat as compression failure\n if (parsed.degenerate) {\n omDebug(\n `[OM:callReflector] attempt #${attemptNumber}: degenerate repetition detected, treating as compression failure`,\n );\n reflectedTokens = originalTokens; // Force retry\n } else {\n reflectedTokens = this.tokenCounter.countObservations(parsed.observations);\n }\n omDebug(\n `[OM:callReflector] attempt #${attemptNumber} parsed: reflectedTokens=${reflectedTokens}, targetThreshold=${targetThreshold}, compressionValid=${validateCompression(reflectedTokens, targetThreshold)}, parsedObsLen=${parsed.observations?.length}, degenerate=${parsed.degenerate ?? false}`,\n );\n\n // If compression succeeded or we've exhausted all levels, stop\n if (!parsed.degenerate && (validateCompression(reflectedTokens, targetThreshold) || currentLevel >= maxLevel)) {\n break;\n }\n\n // Guard against infinite loop: if degenerate persists at maxLevel, stop\n if (parsed.degenerate && currentLevel >= maxLevel) {\n omDebug(`[OM:callReflector] degenerate output persists at maxLevel=${maxLevel}, breaking`);\n break;\n }\n\n // Emit failed marker and start marker for next retry\n if (streamContext?.writer) {\n const failedMarker = this.createObservationFailedMarker({\n cycleId: streamContext.cycleId,\n operationType: 'reflection',\n startedAt: streamContext.startedAt,\n tokensAttempted: originalTokens,\n error: `Did not compress below threshold (${originalTokens} → ${reflectedTokens}, target: ${targetThreshold}), retrying at level ${currentLevel + 1}`,\n recordId: streamContext.recordId,\n threadId: streamContext.threadId,\n });\n await streamContext.writer.custom(failedMarker).catch(() => {});\n\n const retryCycleId = crypto.randomUUID();\n streamContext.cycleId = retryCycleId;\n\n const startMarker = this.createObservationStartMarker({\n cycleId: retryCycleId,\n operationType: 'reflection',\n tokensToObserve: originalTokens,\n recordId: streamContext.recordId,\n threadId: streamContext.threadId,\n threadIds: [streamContext.threadId],\n });\n streamContext.startedAt = startMarker.data.startedAt;\n await streamContext.writer.custom(startMarker).catch(() => {});\n }\n\n // Escalate to next compression level\n currentLevel = Math.min(currentLevel + 1, maxLevel) as 0 | 1 | 2 | 3;\n }\n\n return {\n observations: parsed.observations,\n suggestedContinuation: parsed.suggestedContinuation,\n usage: totalUsage.totalTokens > 0 ? totalUsage : undefined,\n };\n }\n\n /**\n * Format observations for injection into context.\n * Applies token optimization before presenting to the Actor.\n *\n * In resource scope mode, filters continuity messages to only show\n * the message for the current thread.\n */\n /**\n * Format observations for injection into the Actor's context.\n * @param observations - The observations to inject\n * @param suggestedResponse - Thread-specific suggested response (from thread metadata)\n * @param unobservedContextBlocks - Formatted <unobserved-context> blocks from other threads\n */\n private formatObservationsForContext(\n observations: string,\n currentTask?: string,\n suggestedResponse?: string,\n unobservedContextBlocks?: string,\n currentDate?: Date,\n ): string {\n // Optimize observations to save tokens\n let optimized = optimizeObservationsForContext(observations);\n\n // Add relative time annotations to date headers if currentDate is provided\n if (currentDate) {\n optimized = addRelativeTimeToObservations(optimized, currentDate);\n }\n\n let content = `\n${OBSERVATION_CONTEXT_PROMPT}\n\n<observations>\n${optimized}\n</observations>\n\n${OBSERVATION_CONTEXT_INSTRUCTIONS}`;\n\n // Add unobserved context from other threads (resource scope only)\n if (unobservedContextBlocks) {\n content += `\\n\\nThe following content is from OTHER conversations different from the current conversation, they're here for reference, but they're not necessarily your focus:\\nSTART_OTHER_CONVERSATIONS_BLOCK\\n${unobservedContextBlocks}\\nEND_OTHER_CONVERSATIONS_BLOCK`;\n }\n\n // Dynamically inject current-task from thread metadata (not stored in observations)\n if (currentTask) {\n content += `\n\n<current-task>\n${currentTask}\n</current-task>`;\n }\n\n if (suggestedResponse) {\n content += `\n\n<suggested-response>\n${suggestedResponse}\n</suggested-response>\n`;\n }\n\n return content;\n }\n\n /**\n * Get threadId and resourceId from either RequestContext or MessageList\n */\n private getThreadContext(\n requestContext: ProcessInputArgs['requestContext'],\n messageList: MessageList,\n ): { threadId: string; resourceId?: string } | null {\n // First try RequestContext (set by Memory)\n const memoryContext = requestContext?.get('MastraMemory') as\n | { thread?: { id: string }; resourceId?: string }\n | undefined;\n\n if (memoryContext?.thread?.id) {\n return {\n threadId: memoryContext.thread.id,\n resourceId: memoryContext.resourceId,\n };\n }\n\n // Fallback to MessageList's memoryInfo\n const serialized = messageList.serialize();\n if (serialized.memoryInfo?.threadId) {\n return {\n threadId: serialized.memoryInfo.threadId,\n resourceId: serialized.memoryInfo.resourceId,\n };\n }\n\n // In thread scope, threadId is required — without it OM would silently\n // fall back to a resource-keyed record which causes deadlocks when\n // multiple threads share the same resourceId.\n if (this.scope === 'thread') {\n throw new Error(\n `ObservationalMemory (scope: 'thread') requires a threadId, but none was found in RequestContext or MessageList. ` +\n `Ensure the agent is configured with Memory and a valid threadId is provided.`,\n );\n }\n\n return null;\n }\n\n // ══════════════════════════════════════════════════════════════════════════\n // PROCESS INPUT STEP HELPERS\n // These helpers extract logical units from processInputStep for clarity.\n // ══════════════════════════════════════════════════════════════════════════\n\n /**\n * Load historical unobserved messages into the message list (step 0 only).\n * In resource scope, loads only current thread's messages.\n * In thread scope, loads all unobserved messages for the thread.\n */\n private async loadHistoricalMessagesIfNeeded(\n messageList: MessageList,\n state: Record<string, unknown>,\n threadId: string,\n resourceId: string | undefined,\n lastObservedAt: Date | undefined,\n ): Promise<void> {\n if (state.initialSetupDone) {\n return;\n }\n state.initialSetupDone = true;\n\n if (this.scope === 'resource' && resourceId) {\n // RESOURCE SCOPE: Load only the current thread's historical messages.\n // Other threads' unobserved context is loaded fresh each step\n // to reflect the latest lastObservedAt cursors after observations.\n const currentThreadMessages = await this.loadUnobservedMessages(threadId, undefined, lastObservedAt);\n\n for (const msg of currentThreadMessages) {\n if (msg.role !== 'system') {\n if (!this.hasUnobservedParts(msg) && this.findLastCompletedObservationBoundary(msg) !== -1) {\n continue;\n }\n messageList.add(msg, 'memory');\n }\n }\n } else {\n // THREAD SCOPE: Load unobserved messages using resource-level lastObservedAt\n const historicalMessages = await this.loadUnobservedMessages(threadId, resourceId, lastObservedAt);\n\n if (historicalMessages.length > 0) {\n for (const msg of historicalMessages) {\n if (msg.role !== 'system') {\n if (!this.hasUnobservedParts(msg) && this.findLastCompletedObservationBoundary(msg) !== -1) {\n continue;\n }\n messageList.add(msg, 'memory');\n }\n }\n }\n }\n }\n\n /**\n * Calculate all threshold-related values for observation decision making.\n */\n private calculateObservationThresholds(\n _allMessages: MastraDBMessage[],\n unobservedMessages: MastraDBMessage[],\n _pendingTokens: number,\n otherThreadTokens: number,\n currentObservationTokens: number,\n _record?: ObservationalMemoryRecord,\n ): {\n totalPendingTokens: number;\n threshold: number;\n effectiveObservationTokensThreshold: number;\n isSharedBudget: boolean;\n } {\n // Count only unobserved messages for threshold checking.\n // Already-observed messages may still be in the messageList (the AI SDK\n // repopulates it each step), but they shouldn't count toward the threshold\n // since they've already been captured in observations.\n const contextWindowTokens = this.tokenCounter.countMessages(unobservedMessages);\n\n // Total pending = unobserved in-context tokens + other threads\n const totalPendingTokens = Math.max(0, contextWindowTokens + otherThreadTokens);\n\n const threshold = this.calculateDynamicThreshold(this.observationConfig.messageTokens, currentObservationTokens);\n\n // Calculate effective reflection threshold for UI display\n // When adaptive threshold is enabled, both thresholds share a budget\n const baseReflectionThreshold = this.getMaxThreshold(this.reflectionConfig.observationTokens);\n const isSharedBudget = typeof this.observationConfig.messageTokens !== 'number';\n const totalBudget = isSharedBudget ? (this.observationConfig.messageTokens as { min: number; max: number }).max : 0;\n const effectiveObservationTokensThreshold = isSharedBudget\n ? Math.max(totalBudget - threshold, 1000)\n : baseReflectionThreshold;\n return {\n totalPendingTokens,\n threshold,\n effectiveObservationTokensThreshold,\n isSharedBudget,\n };\n }\n\n /**\n * Emit debug event and stream progress part for UI feedback.\n */\n private async emitStepProgress(\n writer: ProcessInputStepArgs['writer'],\n threadId: string,\n resourceId: string | undefined,\n stepNumber: number,\n record: ObservationalMemoryRecord,\n thresholds: {\n totalPendingTokens: number;\n threshold: number;\n effectiveObservationTokensThreshold: number;\n },\n currentObservationTokens: number,\n ): Promise<void> {\n const { totalPendingTokens, threshold, effectiveObservationTokensThreshold } = thresholds;\n\n this.emitDebugEvent({\n type: 'step_progress',\n timestamp: new Date(),\n threadId,\n resourceId: resourceId ?? '',\n stepNumber,\n finishReason: 'unknown',\n pendingTokens: totalPendingTokens,\n threshold,\n thresholdPercent: Math.round((totalPendingTokens / threshold) * 100),\n willSave: totalPendingTokens >= threshold,\n willObserve: totalPendingTokens >= threshold,\n });\n\n if (writer) {\n // Calculate buffered chunk totals for UI\n const bufferedChunks = this.getBufferedChunks(record);\n const bufferedObservationTokens = bufferedChunks.reduce((sum, chunk) => sum + (chunk.tokenCount ?? 0), 0);\n\n // chunk.messageTokens represents the token count of raw messages that will be\n // removed from the context window when the chunk activates (lastObservedAt advances).\n // Cap at totalPendingTokens so the UI never shows a reduction larger than the window.\n const rawBufferedMessageTokens = bufferedChunks.reduce((sum, chunk) => sum + (chunk.messageTokens ?? 0), 0);\n const bufferedMessageTokens = Math.min(rawBufferedMessageTokens, totalPendingTokens);\n\n // Calculate projected message removal based on activation ratio and chunk boundaries\n // This replicates the logic in swapBufferedToActive without actually activating\n const projectedMessageRemoval = this.calculateProjectedMessageRemoval(\n bufferedChunks,\n this.observationConfig.bufferActivation ?? 1,\n this.getMaxThreshold(this.observationConfig.messageTokens),\n totalPendingTokens,\n );\n\n // Determine observation buffering status\n let obsBufferStatus: 'idle' | 'running' | 'complete' = 'idle';\n if (record.isBufferingObservation) {\n obsBufferStatus = 'running';\n } else if (bufferedChunks.length > 0) {\n obsBufferStatus = 'complete';\n }\n\n // Determine reflection buffering status\n let refBufferStatus: 'idle' | 'running' | 'complete' = 'idle';\n if (record.isBufferingReflection) {\n refBufferStatus = 'running';\n } else if (record.bufferedReflection && record.bufferedReflection.length > 0) {\n refBufferStatus = 'complete';\n }\n\n const statusPart: DataOmStatusPart = {\n type: 'data-om-status',\n data: {\n windows: {\n active: {\n messages: {\n tokens: totalPendingTokens,\n threshold,\n },\n observations: {\n tokens: currentObservationTokens,\n threshold: effectiveObservationTokensThreshold,\n },\n },\n buffered: {\n observations: {\n chunks: bufferedChunks.length,\n messageTokens: bufferedMessageTokens,\n projectedMessageRemoval,\n observationTokens: bufferedObservationTokens,\n status: obsBufferStatus,\n },\n reflection: {\n inputObservationTokens: record.bufferedReflectionInputTokens ?? 0,\n observationTokens: record.bufferedReflectionTokens ?? 0,\n status: refBufferStatus,\n },\n },\n },\n recordId: record.id,\n threadId,\n stepNumber,\n generationCount: record.generationCount,\n },\n };\n omDebug(\n `[OM:status] step=${stepNumber} msgs=${totalPendingTokens}/${threshold} obs=${currentObservationTokens}/${effectiveObservationTokensThreshold} bufObs={chunks=${bufferedChunks.length},msgTok=${bufferedMessageTokens},obsTok=${bufferedObservationTokens},status=${obsBufferStatus}} bufRef={inTok=${record.bufferedReflectionInputTokens ?? 0},outTok=${record.bufferedReflectionTokens ?? 0},status=${refBufferStatus}} gen=${record.generationCount}`,\n );\n await writer.custom(statusPart).catch(() => {\n // Ignore errors if stream is closed\n });\n }\n }\n\n /**\n * Handle observation when threshold is reached.\n * Tries async activation first if enabled, then falls back to sync observation.\n * Returns whether observation succeeded.\n */\n private async handleThresholdReached(\n messageList: MessageList,\n record: ObservationalMemoryRecord,\n threadId: string,\n resourceId: string | undefined,\n threshold: number,\n lockKey: string,\n writer: ProcessInputStepArgs['writer'],\n abortSignal: ProcessInputStepArgs['abortSignal'],\n abort: ProcessInputStepArgs['abort'],\n requestContext?: RequestContext,\n ): Promise<{\n observationSucceeded: boolean;\n updatedRecord: ObservationalMemoryRecord;\n activatedMessageIds?: string[];\n }> {\n let observationSucceeded = false;\n let updatedRecord = record;\n let activatedMessageIds: string[] | undefined;\n\n await this.withLock(lockKey, async () => {\n let freshRecord = await this.getOrCreateRecord(threadId, resourceId);\n const freshAllMessages = messageList.get.all.db();\n let freshUnobservedMessages = this.getUnobservedMessages(freshAllMessages, freshRecord);\n\n // Re-check threshold inside the lock using only unobserved messages.\n // Already-observed messages may still be in the messageList but shouldn't\n // count toward the threshold since they've been captured in observations.\n const freshContextTokens = this.tokenCounter.countMessages(freshUnobservedMessages);\n let freshOtherThreadTokens = 0;\n if (this.scope === 'resource' && resourceId) {\n const freshOtherContext = await this.loadOtherThreadsContext(resourceId, threadId);\n freshOtherThreadTokens = freshOtherContext ? this.tokenCounter.countString(freshOtherContext) : 0;\n }\n const freshTotal = freshContextTokens + freshOtherThreadTokens;\n omDebug(\n `[OM:threshold] handleThresholdReached (inside lock): freshTotal=${freshTotal}, threshold=${threshold}, freshUnobserved=${freshUnobservedMessages.length}, freshOtherThreadTokens=${freshOtherThreadTokens}, freshCurrentTokens=${freshContextTokens}`,\n );\n if (freshTotal < threshold) {\n omDebug(`[OM:threshold] freshTotal < threshold, bailing out`);\n return;\n }\n\n // Snapshot lastObservedAt BEFORE observation runs.\n const preObservationTime = freshRecord.lastObservedAt?.getTime() ?? 0;\n\n // Try to activate buffered observations first (instant activation)\n let activationResult: {\n success: boolean;\n updatedRecord?: ObservationalMemoryRecord;\n messageTokensActivated?: number;\n activatedMessageIds?: string[];\n suggestedContinuation?: string;\n currentTask?: string;\n } = { success: false };\n if (this.isAsyncObservationEnabled()) {\n // Wait for any in-flight async buffering to complete first\n const bufferKey = this.getObservationBufferKey(lockKey);\n const asyncOp = ObservationalMemory.asyncBufferingOps.get(bufferKey);\n if (asyncOp) {\n try {\n // Wait for buffering to complete (with reasonable timeout)\n await Promise.race([\n asyncOp,\n new Promise((_, reject) => setTimeout(() => reject(new Error('Timeout')), 30000)),\n ]);\n } catch {\n // Timeout or error - proceed with what we have\n }\n }\n\n // Re-fetch record after waiting for async op\n const recordAfterWait = await this.getOrCreateRecord(threadId, resourceId);\n const chunksAfterWait = this.getBufferedChunks(recordAfterWait);\n omDebug(\n `[OM:threshold] tryActivation: chunksAvailable=${chunksAfterWait.length}, isBufferingObs=${recordAfterWait.isBufferingObservation}`,\n );\n\n activationResult = await this.tryActivateBufferedObservations(\n recordAfterWait,\n lockKey,\n freshTotal,\n writer,\n messageList,\n );\n omDebug(`[OM:threshold] activationResult: success=${activationResult.success}`);\n if (activationResult.success) {\n // Activation succeeded - the buffered observations are now active.\n // Trust the activation and return success immediately.\n // The activated chunks have already been moved to activeObservations.\n observationSucceeded = true;\n updatedRecord = activationResult.updatedRecord ?? recordAfterWait;\n activatedMessageIds = activationResult.activatedMessageIds;\n\n omDebug(\n `[OM:threshold] activation succeeded, obsTokens=${updatedRecord.observationTokenCount}, activeObsLen=${updatedRecord.activeObservations?.length}`,\n );\n\n // Propagate continuation hints from activation to thread metadata\n if (activationResult.suggestedContinuation || activationResult.currentTask) {\n const thread = await this.storage.getThreadById({ threadId });\n if (thread) {\n const newMetadata = setThreadOMMetadata(thread.metadata, {\n suggestedResponse: activationResult.suggestedContinuation,\n currentTask: activationResult.currentTask,\n });\n await this.storage.updateThread({\n id: threadId,\n title: thread.title ?? '',\n metadata: newMetadata,\n });\n }\n }\n\n // Note: lastBufferedBoundary is updated by the caller AFTER cleanupAfterObservation\n // removes the activated messages from messageList and recounts the actual context size.\n\n // Check if async reflection should be triggered or activated.\n // This only does async work (background buffering or instant activation) —\n // never blocking sync reflection that could overwrite freshly activated observations.\n await this.maybeAsyncReflect(\n updatedRecord,\n updatedRecord.observationTokenCount ?? 0,\n writer,\n messageList,\n requestContext,\n );\n return;\n }\n\n // When async observation is enabled, don't fall through to synchronous observation\n // unless blockAfter is set and we've exceeded it.\n if (this.observationConfig.blockAfter && freshTotal >= this.observationConfig.blockAfter) {\n omDebug(\n `[OM:threshold] blockAfter exceeded (${freshTotal} >= ${this.observationConfig.blockAfter}), falling through to sync observation`,\n );\n // blockAfter exceeded — fall through to synchronous observation as a last resort.\n // Re-fetch unobserved messages since activation may have changed things.\n freshRecord = await this.getOrCreateRecord(threadId, resourceId);\n const refreshedAll = messageList.get.all.db();\n freshUnobservedMessages = this.getUnobservedMessages(refreshedAll, freshRecord);\n } else {\n omDebug(`[OM:threshold] activation failed, no blockAfter or below it — letting async buffering catch up`);\n // Below blockAfter (or no blockAfter set) — let async buffering catch up.\n return;\n }\n }\n\n if (freshUnobservedMessages.length > 0) {\n try {\n if (this.scope === 'resource' && resourceId) {\n await this.doResourceScopedObservation({\n record: freshRecord,\n currentThreadId: threadId,\n resourceId,\n currentThreadMessages: freshUnobservedMessages,\n writer,\n abortSignal,\n requestContext,\n });\n } else {\n await this.doSynchronousObservation({\n record: freshRecord,\n threadId,\n unobservedMessages: freshUnobservedMessages,\n writer,\n abortSignal,\n requestContext,\n });\n }\n // Check if observation actually updated lastObservedAt\n updatedRecord = await this.getOrCreateRecord(threadId, resourceId);\n const updatedTime = updatedRecord.lastObservedAt?.getTime() ?? 0;\n observationSucceeded = updatedTime > preObservationTime;\n } catch (error) {\n if (abortSignal?.aborted) {\n abort('Agent execution was aborted');\n } else {\n abort(\n `Encountered error during memory observation ${error instanceof Error ? error.message : JSON.stringify(error, null, 2)}`,\n );\n }\n // abort() throws, so this line is only reached if abort doesn't throw\n }\n }\n });\n\n return { observationSucceeded, updatedRecord, activatedMessageIds };\n }\n\n /**\n * Remove observed messages from message list after successful observation.\n * Accepts optional observedMessageIds for activation-based cleanup (when no markers are present).\n */\n private async cleanupAfterObservation(\n messageList: MessageList,\n sealedIds: Set<string>,\n threadId: string,\n resourceId: string | undefined,\n state: Record<string, unknown>,\n observedMessageIds?: string[],\n ): Promise<void> {\n const allMsgs = messageList.get.all.db();\n let markerIdx = -1;\n let markerMsg: MastraDBMessage | null = null;\n\n // Find the last observation end marker\n for (let i = allMsgs.length - 1; i >= 0; i--) {\n const msg = allMsgs[i];\n if (!msg) continue;\n if (this.findLastCompletedObservationBoundary(msg) !== -1) {\n markerIdx = i;\n markerMsg = msg;\n break;\n }\n }\n\n omDebug(\n `[OM:cleanupBranch] allMsgs=${allMsgs.length}, markerFound=${markerIdx !== -1}, markerIdx=${markerIdx}, observedMessageIds=${observedMessageIds?.length ?? 'undefined'}, allIds=${allMsgs.map(m => m.id?.slice(0, 8)).join(',')}`,\n );\n\n if (markerMsg && markerIdx !== -1) {\n // Collect all messages before the marker (these are fully observed)\n const idsToRemove: string[] = [];\n const messagesToSave: MastraDBMessage[] = [];\n\n for (let i = 0; i < markerIdx; i++) {\n const msg = allMsgs[i];\n if (msg?.id && msg.id !== 'om-continuation') {\n idsToRemove.push(msg.id);\n messagesToSave.push(msg);\n }\n }\n\n // Also include the marker message itself in the save\n messagesToSave.push(markerMsg);\n\n // Filter marker message to only unobserved parts\n const unobservedParts = this.getUnobservedParts(markerMsg);\n if (unobservedParts.length === 0) {\n // Marker message is fully observed — remove it too\n if (markerMsg.id) {\n idsToRemove.push(markerMsg.id);\n }\n } else if (unobservedParts.length < (markerMsg.content?.parts?.length ?? 0)) {\n // Trim marker message to only unobserved parts (in-place)\n markerMsg.content.parts = unobservedParts;\n }\n\n // Remove observed messages from context FIRST, before saveMessagesWithSealedIdTracking\n // which may mutate msg.id for sealed messages (causing removeByIds to miss them).\n if (idsToRemove.length > 0) {\n messageList.removeByIds(idsToRemove);\n }\n\n // Save all observed messages (with their markers) to DB\n if (messagesToSave.length > 0) {\n await this.saveMessagesWithSealedIdTracking(messagesToSave, sealedIds, threadId, resourceId, state);\n }\n } else if (observedMessageIds && observedMessageIds.length > 0) {\n // Activation-based cleanup: remove observed messages from context.\n // Each LLM step is a fresh request — processInputStep prepares the context\n // window before each call. Removing observed messages here ensures the next\n // step sees a trimmed context with observations instead of raw messages.\n const observedSet = new Set(observedMessageIds);\n const messagesToSave: MastraDBMessage[] = [];\n const idsToRemove: string[] = [];\n\n for (const msg of allMsgs) {\n if (msg?.id && msg.id !== 'om-continuation' && observedSet.has(msg.id)) {\n messagesToSave.push(msg);\n idsToRemove.push(msg.id);\n }\n }\n\n omDebug(\n `[OM:cleanupActivation] observedSet=${[...observedSet].map(id => id.slice(0, 8)).join(',')}, matched=${idsToRemove.length}, idsToRemove=${idsToRemove.map(id => id.slice(0, 8)).join(',')}`,\n );\n\n // Remove activated messages from context. No need to re-save — these were\n // already persisted by handlePerStepSave or runAsyncBufferedObservation.\n if (idsToRemove.length > 0) {\n messageList.removeByIds(idsToRemove);\n omDebug(\n `[OM:cleanupActivation] removed ${idsToRemove.length} messages, remaining=${messageList.get.all.db().length}`,\n );\n }\n } else {\n // No marker found — fall back to source-based clearing\n const newInput = messageList.clear.input.db();\n const newOutput = messageList.clear.response.db();\n const messagesToSave = [...newInput, ...newOutput];\n if (messagesToSave.length > 0) {\n await this.saveMessagesWithSealedIdTracking(messagesToSave, sealedIds, threadId, resourceId, state);\n }\n }\n\n // Clear any remaining input/response tracking\n // (only reached for marker-based and fallback paths, NOT activation path)\n messageList.clear.input.db();\n messageList.clear.response.db();\n }\n\n /**\n * Handle per-step save when threshold is not reached.\n * Persists messages incrementally to prevent data loss on interruption.\n */\n private async handlePerStepSave(\n messageList: MessageList,\n sealedIds: Set<string>,\n threadId: string,\n resourceId: string | undefined,\n state: Record<string, unknown>,\n ): Promise<void> {\n const newInput = messageList.clear.input.db();\n const newOutput = messageList.clear.response.db();\n const messagesToSave = [...newInput, ...newOutput];\n\n omDebug(\n `[OM:handlePerStepSave] cleared input=${newInput.length}, response=${newOutput.length}, toSave=${messagesToSave.length}, ids=${messagesToSave.map(m => m.id?.slice(0, 8)).join(',')}`,\n );\n\n if (messagesToSave.length > 0) {\n await this.saveMessagesWithSealedIdTracking(messagesToSave, sealedIds, threadId, resourceId, state);\n\n // Re-add messages to context so the agent can still see them\n for (const msg of messagesToSave) {\n messageList.add(msg, 'memory');\n }\n }\n }\n\n /**\n * Inject observations as system message and add continuation reminder.\n */\n private async injectObservationsIntoContext(\n messageList: MessageList,\n record: ObservationalMemoryRecord,\n threadId: string,\n resourceId: string | undefined,\n unobservedContextBlocks: string | undefined,\n requestContext: ProcessInputStepArgs['requestContext'],\n ): Promise<void> {\n const thread = await this.storage.getThreadById({ threadId });\n const threadOMMetadata = getThreadOMMetadata(thread?.metadata);\n const currentTask = threadOMMetadata?.currentTask;\n const suggestedResponse = threadOMMetadata?.suggestedResponse;\n const rawCurrentDate = requestContext?.get('currentDate');\n const currentDate =\n rawCurrentDate instanceof Date\n ? rawCurrentDate\n : typeof rawCurrentDate === 'string'\n ? new Date(rawCurrentDate)\n : new Date();\n\n if (!record.activeObservations) {\n return;\n }\n\n const observationSystemMessage = this.formatObservationsForContext(\n record.activeObservations,\n currentTask,\n suggestedResponse,\n unobservedContextBlocks,\n currentDate,\n );\n\n // Clear any existing observation system message and add fresh one\n messageList.clearSystemMessages('observational-memory');\n messageList.addSystem(observationSystemMessage, 'observational-memory');\n\n // Add continuation reminder\n const continuationMessage: MastraDBMessage = {\n id: `om-continuation`,\n role: 'user',\n createdAt: new Date(0),\n content: {\n format: 2,\n parts: [\n {\n type: 'text',\n text: `<system-reminder>${OBSERVATION_CONTINUATION_HINT}</system-reminder>`,\n },\n ],\n },\n threadId,\n resourceId,\n };\n messageList.add(continuationMessage, 'memory');\n }\n\n /**\n * Filter out already-observed messages from message list (step 0 only).\n * Historical messages loaded from DB may contain observation markers from previous sessions.\n */\n private filterAlreadyObservedMessages(messageList: MessageList, record?: ObservationalMemoryRecord): void {\n const allMessages = messageList.get.all.db();\n\n // Find the message with the last observation end marker\n let markerMessageIndex = -1;\n let markerMessage: MastraDBMessage | null = null;\n\n for (let i = allMessages.length - 1; i >= 0; i--) {\n const msg = allMessages[i];\n if (!msg) continue;\n if (this.findLastCompletedObservationBoundary(msg) !== -1) {\n markerMessageIndex = i;\n markerMessage = msg;\n break;\n }\n }\n\n if (markerMessage && markerMessageIndex !== -1) {\n const messagesToRemove: string[] = [];\n for (let i = 0; i < markerMessageIndex; i++) {\n const msg = allMessages[i];\n if (msg?.id && msg.id !== 'om-continuation') {\n messagesToRemove.push(msg.id);\n }\n }\n\n if (messagesToRemove.length > 0) {\n messageList.removeByIds(messagesToRemove);\n }\n\n // Filter marker message to only unobserved parts\n const unobservedParts = this.getUnobservedParts(markerMessage);\n if (unobservedParts.length === 0) {\n if (markerMessage.id) {\n messageList.removeByIds([markerMessage.id]);\n }\n } else if (unobservedParts.length < (markerMessage.content?.parts?.length ?? 0)) {\n markerMessage.content.parts = unobservedParts;\n }\n } else if (record) {\n // No observation markers found (e.g., after buffered activation).\n // Fall back to record-based filtering: remove messages that are already\n // captured in observations (via lastObservedAt timestamp or observedMessageIds).\n // This prevents context overflow on session resume after buffered activation.\n const observedIds = new Set<string>(Array.isArray(record.observedMessageIds) ? record.observedMessageIds : []);\n // NOTE: Do NOT add buffered chunk messageIds here. Buffered messages are NOT yet\n // observed — they're staged for future activation. They must remain in context\n // for the LLM to see. Only observedMessageIds and lastObservedAt determine what's\n // been truly observed.\n\n const lastObservedAt = record.lastObservedAt;\n const messagesToRemove: string[] = [];\n\n for (const msg of allMessages) {\n if (!msg?.id || msg.id === 'om-continuation') continue;\n\n // Remove if explicitly tracked in observedMessageIds or buffered chunks\n if (observedIds.has(msg.id)) {\n messagesToRemove.push(msg.id);\n continue;\n }\n\n // Remove if created before lastObservedAt (these messages' content is\n // already captured in activeObservations via buffered activation)\n if (lastObservedAt && msg.createdAt) {\n const msgDate = new Date(msg.createdAt);\n if (msgDate <= lastObservedAt) {\n messagesToRemove.push(msg.id);\n }\n }\n }\n\n if (messagesToRemove.length > 0) {\n messageList.removeByIds(messagesToRemove);\n }\n }\n }\n\n /**\n * Process input at each step - check threshold, observe if needed, save, inject observations.\n * This is the ONLY processor method - all OM logic happens here.\n *\n * Flow:\n * 1. Load historical messages (step 0 only)\n * 2. Check if observation threshold is reached\n * 3. If threshold reached: observe, save messages with markers\n * 4. Inject observations into context\n * 5. Filter out already-observed messages\n */\n async processInputStep(args: ProcessInputStepArgs): Promise<MessageList | MastraDBMessage[]> {\n const { messageList, requestContext, stepNumber, state: _state, writer, abortSignal, abort } = args;\n const state = _state ?? ({} as Record<string, unknown>);\n\n const context = this.getThreadContext(requestContext, messageList);\n if (!context) {\n return messageList;\n }\n\n const { threadId, resourceId } = context;\n const memoryContext = parseMemoryRequestContext(requestContext);\n const readOnly = memoryContext?.memoryConfig?.readOnly;\n\n // Fetch fresh record\n let record = await this.getOrCreateRecord(threadId, resourceId);\n omDebug(\n `[OM:step] processInputStep step=${stepNumber}: recordId=${record.id}, genCount=${record.generationCount}, obsTokens=${record.observationTokenCount}, bufferedReflection=${record.bufferedReflection ? 'present (' + record.bufferedReflection.length + ' chars)' : 'empty'}, activeObsLen=${record.activeObservations?.length}`,\n );\n\n // ════════════════════════════════════════════════════════════════════════\n // STEP 1: LOAD HISTORICAL MESSAGES (step 0 only)\n // ════════════════════════════════════════════════════════════════════════\n await this.loadHistoricalMessagesIfNeeded(messageList, state, threadId, resourceId, record.lastObservedAt);\n\n // ════════════════════════════════════════════════════════════════════════\n // STEP 1b: LOAD OTHER THREADS' UNOBSERVED CONTEXT (resource scope, every step)\n // ════════════════════════════════════════════════════════════════════════\n let unobservedContextBlocks: string | undefined;\n if (this.scope === 'resource' && resourceId) {\n unobservedContextBlocks = await this.loadOtherThreadsContext(resourceId, threadId);\n }\n\n // ════════════════════════════════════════════════════════════════════════\n // STEP 1c: ACTIVATE BUFFERED OBSERVATIONS (step 0 only)\n // At the start of a new turn, check if buffered observations should be activated.\n // Only activates if message tokens have reached the observation threshold,\n // preventing premature activation of partially-buffered content.\n // ════════════════════════════════════════════════════════════════════════\n if (stepNumber === 0 && !readOnly && this.isAsyncObservationEnabled()) {\n const lockKey = this.getLockKey(threadId, resourceId);\n const bufferedChunks = this.getBufferedChunks(record);\n omDebug(\n `[OM:step0-activation] asyncObsEnabled=true, bufferedChunks=${bufferedChunks.length}, isBufferingObs=${record.isBufferingObservation}`,\n );\n\n // Reset stale lastBufferedBoundary at the start of a new turn.\n // After activation+reflection on a previous turn, the context may have shrunk\n // significantly (e.g., 51k → 3k) but the DB boundary stays at 51k. This makes\n // shouldTriggerAsyncObservation think we're still in interval 5, preventing any\n // new buffering triggers until tokens grow past 51k again.\n {\n const bufKey = this.getObservationBufferKey(lockKey);\n const dbBoundary = record.lastBufferedAtTokens ?? 0;\n const currentContextTokens = this.tokenCounter.countMessages(messageList.get.all.db());\n if (dbBoundary > currentContextTokens) {\n omDebug(\n `[OM:step0-boundary-reset] dbBoundary=${dbBoundary} > currentContext=${currentContextTokens}, resetting to current`,\n );\n ObservationalMemory.lastBufferedBoundary.set(bufKey, currentContextTokens);\n this.storage.setBufferingObservationFlag(record.id, false, currentContextTokens).catch(() => {});\n }\n }\n\n if (bufferedChunks.length > 0) {\n // Compute threshold to check if activation is warranted\n const allMsgsForCheck = messageList.get.all.db();\n const unobservedMsgsForCheck = this.getUnobservedMessages(allMsgsForCheck, record);\n const otherThreadTokensForCheck = unobservedContextBlocks\n ? this.tokenCounter.countString(unobservedContextBlocks)\n : 0;\n const currentObsTokensForCheck = record.observationTokenCount ?? 0;\n const { totalPendingTokens: step0PendingTokens, threshold: step0Threshold } =\n this.calculateObservationThresholds(\n allMsgsForCheck,\n unobservedMsgsForCheck,\n 0, // pendingTokens not needed — allMessages covers context\n otherThreadTokensForCheck,\n currentObsTokensForCheck,\n record,\n );\n\n // Activate buffered chunks at step 0 if:\n // - We're at or above the regular observation threshold (buffers are needed)\n // Use the regular threshold, not blockAfter — blockAfter gates synchronous observation,\n // but activating already-buffered chunks is cheap (no LLM call) and prevents chunks\n // from piling up in single-step turns that never reach step > 0.\n omDebug(\n `[OM:step0-activation] pendingTokens=${step0PendingTokens}, threshold=${step0Threshold}, blockAfter=${this.observationConfig.blockAfter}, shouldActivate=${step0PendingTokens >= step0Threshold}, allMsgs=${allMsgsForCheck.length}`,\n );\n\n if (step0PendingTokens >= step0Threshold) {\n const activationResult = await this.tryActivateBufferedObservations(\n record,\n lockKey,\n step0PendingTokens,\n writer,\n messageList,\n );\n\n if (activationResult.success && activationResult.updatedRecord) {\n record = activationResult.updatedRecord;\n\n // Remove activated messages from context using activatedMessageIds.\n // Note: swapBufferedToActive does NOT populate record.observedMessageIds\n // (intentionally — recycled IDs would block future content).\n // filterAlreadyObservedMessages runs later at step 0 and uses lastObservedAt\n // as a fallback, but we do explicit removal here for immediate effect.\n const activatedIds = activationResult.activatedMessageIds ?? [];\n if (activatedIds.length > 0) {\n const activatedSet = new Set(activatedIds);\n const allMsgs = messageList.get.all.db();\n const idsToRemove = allMsgs\n .filter(msg => msg?.id && msg.id !== 'om-continuation' && activatedSet.has(msg.id))\n .map(msg => msg.id);\n\n if (idsToRemove.length > 0) {\n messageList.removeByIds(idsToRemove);\n }\n }\n\n // Clean up sealed IDs for activated messages (prevents memory leak)\n this.cleanupStaticMaps(threadId, resourceId, activatedIds);\n\n // Reset lastBufferedBoundary to 0 after activation so that any\n // remaining unbuffered messages in context can trigger a new buffering\n // interval. The worst case is one no-op trigger if all remaining messages\n // are already in buffered chunks.\n const bufKey = this.getObservationBufferKey(lockKey);\n ObservationalMemory.lastBufferedBoundary.set(bufKey, 0);\n this.storage.setBufferingObservationFlag(record.id, false, 0).catch(() => {});\n\n // Propagate continuation hints from activation to thread metadata so\n // injectObservationsIntoContext can include them immediately.\n if (activationResult.suggestedContinuation || activationResult.currentTask) {\n const thread = await this.storage.getThreadById({ threadId });\n if (thread) {\n const newMetadata = setThreadOMMetadata(thread.metadata, {\n suggestedResponse: activationResult.suggestedContinuation,\n currentTask: activationResult.currentTask,\n });\n await this.storage.updateThread({\n id: threadId,\n title: thread.title ?? '',\n metadata: newMetadata,\n });\n }\n }\n\n // Check if reflection should be triggered or activated\n await this.maybeReflect({\n record,\n observationTokens: record.observationTokenCount ?? 0,\n threadId,\n writer,\n messageList,\n requestContext,\n });\n // Re-fetch record — reflection may have created a new generation with lower obsTokens\n record = await this.getOrCreateRecord(threadId, resourceId);\n }\n }\n }\n }\n\n // ════════════════════════════════════════════════════════════════════════\n // STEP 1d: REFLECTION CHECK (step 0 only)\n // If observation tokens are already over the reflection threshold when the\n // conversation starts (e.g. from a previous session), trigger reflection.\n // This covers the case where no buffered observation activation happened above.\n // Safe because reflection carries over lastObservedAt — unobserved messages won't be lost.\n // Also triggers async buffered reflection if above the activation point but\n // below the full threshold (e.g. after a crash lost a previous reflection attempt).\n // ════════════════════════════════════════════════════════════════════════\n if (stepNumber === 0 && !readOnly) {\n const obsTokens = record.observationTokenCount ?? 0;\n if (this.shouldReflect(obsTokens)) {\n omDebug(`[OM:step0-reflect] obsTokens=${obsTokens} over reflectThreshold, triggering reflection`);\n await this.maybeReflect({\n record,\n observationTokens: obsTokens,\n threadId,\n writer,\n messageList,\n requestContext,\n });\n // Re-fetch record after reflection may have created a new generation\n record = await this.getOrCreateRecord(threadId, resourceId);\n } else if (this.isAsyncReflectionEnabled()) {\n // Below full threshold but maybe above activation point — try async reflection\n const lockKey = this.getLockKey(threadId, resourceId);\n if (this.shouldTriggerAsyncReflection(obsTokens, lockKey, record)) {\n omDebug(`[OM:step0-reflect] obsTokens=${obsTokens} above activation point, triggering async reflection`);\n await this.maybeAsyncReflect(record, obsTokens, writer, messageList, requestContext);\n record = await this.getOrCreateRecord(threadId, resourceId);\n }\n }\n }\n\n // ════════════════════════════════════════════════════════════════════════\n // STEP 2: CHECK THRESHOLD AND OBSERVE IF NEEDED\n // ════════════════════════════════════════════════════════════════════════\n if (!readOnly) {\n const allMessages = messageList.get.all.db();\n const unobservedMessages = this.getUnobservedMessages(allMessages, record);\n const otherThreadTokens = unobservedContextBlocks ? this.tokenCounter.countString(unobservedContextBlocks) : 0;\n const currentObservationTokens = record.observationTokenCount ?? 0;\n\n const thresholds = this.calculateObservationThresholds(\n allMessages,\n unobservedMessages,\n 0, // pendingTokens not needed — allMessages covers context\n otherThreadTokens,\n currentObservationTokens,\n record,\n );\n const { totalPendingTokens, threshold } = thresholds;\n\n // Subtract already-buffered message tokens from the pending count for buffering decisions.\n // Buffered messages are \"unobserved\" (not yet in activeObservations) but have already been\n // sent to the observer — counting them would cause redundant buffering ops, especially\n // after activation resets lastBufferedBoundary to 0.\n const bufferedChunkTokens = this.getBufferedChunks(record).reduce((sum, c) => sum + (c.tokenCount ?? 0), 0);\n const unbufferedPendingTokens = Math.max(0, totalPendingTokens - bufferedChunkTokens);\n\n // Merge per-state sealedIds with static sealedMessageIds (survives across OM instances)\n const stateSealedIds: Set<string> = (state.sealedIds as Set<string>) ?? new Set<string>();\n const staticSealedIds = ObservationalMemory.sealedMessageIds.get(threadId) ?? new Set<string>();\n const sealedIds = new Set<string>([...stateSealedIds, ...staticSealedIds]);\n state.sealedIds = sealedIds;\n const lockKey = this.getLockKey(threadId, resourceId);\n\n // ════════════════════════════════════════════════════════════════════════\n // ASYNC BUFFERING: Trigger background observation at bufferTokens intervals\n // ════════════════════════════════════════════════════════════════════════\n\n if (this.isAsyncObservationEnabled() && totalPendingTokens < threshold) {\n const shouldTrigger = this.shouldTriggerAsyncObservation(unbufferedPendingTokens, lockKey, record, threshold);\n omDebug(\n `[OM:async-obs] belowThreshold: pending=${totalPendingTokens}, unbuffered=${unbufferedPendingTokens}, threshold=${threshold}, shouldTrigger=${shouldTrigger}, isBufferingObs=${record.isBufferingObservation}, lastBufferedAt=${record.lastBufferedAtTokens}`,\n );\n if (shouldTrigger) {\n this.startAsyncBufferedObservation(\n record,\n threadId,\n unobservedMessages,\n lockKey,\n writer,\n unbufferedPendingTokens,\n requestContext,\n );\n }\n } else if (this.isAsyncObservationEnabled()) {\n // Above threshold but we still need to check async buffering:\n // - At step 0, sync observation won't run, so we need chunks ready\n // - Below blockAfter, sync observation won't run, so we need chunks ready\n const shouldTrigger = this.shouldTriggerAsyncObservation(unbufferedPendingTokens, lockKey, record, threshold);\n omDebug(\n `[OM:async-obs] atOrAboveThreshold: pending=${totalPendingTokens}, unbuffered=${unbufferedPendingTokens}, threshold=${threshold}, step=${stepNumber}, shouldTrigger=${shouldTrigger}`,\n );\n if (shouldTrigger) {\n this.startAsyncBufferedObservation(\n record,\n threadId,\n unobservedMessages,\n lockKey,\n writer,\n unbufferedPendingTokens,\n requestContext,\n );\n }\n }\n\n // ════════════════════════════════════════════════════════════════════════\n // PER-STEP SAVE: Always persist messages incrementally (step > 0)\n // Must run BEFORE threshold handling so that:\n // 1. Sealed messages get new IDs (preventing observedMessageIds collisions)\n // 2. Messages are persisted even when activation runs\n // ════════════════════════════════════════════════════════════════════════\n if (stepNumber > 0) {\n await this.handlePerStepSave(messageList, sealedIds, threadId, resourceId, state);\n }\n\n // ════════════════════════════════════════════════════════════════════════\n // THRESHOLD REACHED: Observe and clean up\n // ════════════════════════════════════════════════════════════════════════\n if (stepNumber > 0 && totalPendingTokens >= threshold) {\n const { observationSucceeded, updatedRecord, activatedMessageIds } = await this.handleThresholdReached(\n messageList,\n record,\n threadId,\n resourceId,\n threshold,\n lockKey,\n writer,\n abortSignal,\n abort,\n requestContext,\n );\n\n if (observationSucceeded) {\n // Use activatedMessageIds from chunk activation if available,\n // otherwise fall back to observedMessageIds from sync observation.\n // swapBufferedToActive does NOT populate record.observedMessageIds\n // (intentionally — recycled IDs would block future content),\n // so we pass activatedMessageIds directly for cleanup.\n const observedIds = activatedMessageIds?.length\n ? activatedMessageIds\n : Array.isArray(updatedRecord.observedMessageIds)\n ? updatedRecord.observedMessageIds\n : undefined;\n omDebug(\n `[OM:cleanup] observedIds=${observedIds?.length ?? 'undefined'}, ids=${observedIds?.join(',') ?? 'none'}, updatedRecord.observedMessageIds=${JSON.stringify(updatedRecord.observedMessageIds)}`,\n );\n await this.cleanupAfterObservation(messageList, sealedIds, threadId, resourceId, state, observedIds);\n\n // Clean up sealed IDs for activated messages (prevents memory leak)\n if (activatedMessageIds?.length) {\n this.cleanupStaticMaps(threadId, resourceId, activatedMessageIds);\n }\n\n // Reset lastBufferedBoundary to 0 after activation so that any\n // remaining unbuffered messages in context can trigger a new buffering\n // interval on the next step.\n if (this.isAsyncObservationEnabled()) {\n const bufKey = this.getObservationBufferKey(lockKey);\n ObservationalMemory.lastBufferedBoundary.set(bufKey, 0);\n this.storage.setBufferingObservationFlag(updatedRecord.id, false, 0).catch(() => {});\n omDebug(`[OM:threshold] post-activation boundary reset to 0`);\n }\n }\n\n record = updatedRecord;\n }\n }\n\n // ════════════════════════════════════════════════════════════════════════\n // STEP 3: INJECT OBSERVATIONS INTO CONTEXT\n // ════════════════════════════════════════════════════════════════════════\n await this.injectObservationsIntoContext(\n messageList,\n record,\n threadId,\n resourceId,\n unobservedContextBlocks,\n requestContext,\n );\n\n // ════════════════════════════════════════════════════════════════════════\n // STEP 4: FILTER OUT ALREADY-OBSERVED MESSAGES (step 0 only)\n // ════════════════════════════════════════════════════════════════════════\n if (stepNumber === 0) {\n this.filterAlreadyObservedMessages(messageList, record);\n }\n\n // ════════════════════════════════════════════════════════════════════════\n // STEP 5: EMIT FINAL STATUS (after all observations/activations/reflections)\n // ════════════════════════════════════════════════════════════════════════\n {\n // Re-fetch record to capture any changes from observation/activation/reflection\n const freshRecord = await this.getOrCreateRecord(threadId, resourceId);\n\n // Count tokens from messages actually in the context window.\n // We use messageList directly rather than getUnobservedMessages because after\n // activation, lastObservedAt advances to the chunk's timestamp which incorrectly\n // filters out messages that weren't part of the chunk but predate it.\n // messageList already has activated messages removed (step 1c), so it accurately\n // represents what's still in context.\n const contextMessages = messageList.get.all.db();\n const freshUnobservedTokens = this.tokenCounter.countMessages(contextMessages);\n const otherThreadTokens = unobservedContextBlocks ? this.tokenCounter.countString(unobservedContextBlocks) : 0;\n const currentObservationTokens = freshRecord.observationTokenCount ?? 0;\n\n const threshold = this.calculateDynamicThreshold(this.observationConfig.messageTokens, currentObservationTokens);\n const baseReflectionThreshold = this.getMaxThreshold(this.reflectionConfig.observationTokens);\n const isSharedBudget = typeof this.observationConfig.messageTokens !== 'number';\n const totalBudget = isSharedBudget\n ? (this.observationConfig.messageTokens as { min: number; max: number }).max\n : 0;\n const effectiveObservationTokensThreshold = isSharedBudget\n ? Math.max(totalBudget - threshold, 1000)\n : baseReflectionThreshold;\n\n const totalPendingTokens = freshUnobservedTokens + otherThreadTokens;\n\n await this.emitStepProgress(\n writer,\n threadId,\n resourceId,\n stepNumber,\n freshRecord,\n {\n totalPendingTokens,\n threshold,\n effectiveObservationTokensThreshold,\n },\n currentObservationTokens,\n );\n\n // Persist the computed token count so the UI can display it on page load\n this.storage.setPendingMessageTokens(freshRecord.id, totalPendingTokens).catch(() => {});\n }\n\n return messageList;\n }\n\n /**\n * Save any unsaved messages at the end of the agent turn.\n *\n * This is the \"final save\" that catches messages that processInputStep didn't save\n * (e.g., when the observation threshold was never reached, or on single-step execution).\n * Without this, messages would be lost because MessageHistory is disabled when OM is active.\n */\n async processOutputResult(args: ProcessOutputResultArgs): Promise<MessageList | MastraDBMessage[]> {\n const { messageList, requestContext, state: _state } = args;\n // Default state to {} for backward compat with older @mastra/core that doesn't pass state\n const state = _state ?? ({} as Record<string, unknown>);\n\n const context = this.getThreadContext(requestContext, messageList);\n if (!context) {\n return messageList;\n }\n\n const { threadId, resourceId } = context;\n\n // Check if readOnly\n const memoryContext = parseMemoryRequestContext(requestContext);\n const readOnly = memoryContext?.memoryConfig?.readOnly;\n if (readOnly) {\n return messageList;\n }\n\n // Final save: persist any messages that weren't saved during per-step saves\n // (e.g., the final assistant response after the last processInputStep)\n const newInput = messageList.get.input.db();\n const newOutput = messageList.get.response.db();\n const messagesToSave = [...newInput, ...newOutput];\n\n omDebug(\n `[OM:processOutputResult] threadId=${threadId}, inputMsgs=${newInput.length}, responseMsgs=${newOutput.length}, totalToSave=${messagesToSave.length}, allMsgsInList=${messageList.get.all.db().length}`,\n );\n\n if (messagesToSave.length === 0) {\n omDebug(`[OM:processOutputResult] nothing to save — all messages were already saved during per-step saves`);\n return messageList;\n }\n\n const sealedIds: Set<string> = (state.sealedIds as Set<string>) ?? new Set<string>();\n\n omDebug(\n `[OM:processOutputResult] saving ${messagesToSave.length} messages, sealedIds=${sealedIds.size}, ids=${messagesToSave.map(m => m.id?.slice(0, 8)).join(',')}`,\n );\n await this.saveMessagesWithSealedIdTracking(messagesToSave, sealedIds, threadId, resourceId, state);\n omDebug(\n `[OM:processOutputResult] saved successfully, finalIds=${messagesToSave.map(m => m.id?.slice(0, 8)).join(',')}`,\n );\n\n return messageList;\n }\n\n /**\n * Save messages to storage, regenerating IDs for any messages that were\n * previously saved with observation markers (sealed).\n *\n * After saving, tracks which messages now have observation markers\n * so their IDs won't be reused in future save cycles.\n */\n private async saveMessagesWithSealedIdTracking(\n messagesToSave: MastraDBMessage[],\n sealedIds: Set<string>,\n threadId: string,\n resourceId: string | undefined,\n state: Record<string, unknown>,\n ): Promise<void> {\n // Regenerate IDs for messages that were already saved with observation markers\n // This prevents overwriting sealed messages in the DB\n for (const msg of messagesToSave) {\n if (sealedIds.has(msg.id)) {\n msg.id = crypto.randomUUID();\n }\n }\n\n await this.messageHistory.persistMessages({\n messages: messagesToSave,\n threadId,\n resourceId,\n });\n\n // After successful save, track IDs of messages that now have observation markers (sealed)\n // These IDs cannot be reused in future cycles\n for (const msg of messagesToSave) {\n if (this.findLastCompletedObservationBoundary(msg) !== -1) {\n sealedIds.add(msg.id);\n }\n }\n state.sealedIds = sealedIds;\n }\n\n /**\n * Load messages from storage that haven't been observed yet.\n * Uses cursor-based query with lastObservedAt timestamp for efficiency.\n *\n * In resource scope mode, loads messages for the entire resource (all threads).\n * In thread scope mode, loads messages for just the current thread.\n */\n private async loadUnobservedMessages(\n threadId: string,\n resourceId: string | undefined,\n lastObservedAt?: Date,\n ): Promise<MastraDBMessage[]> {\n // Add 1ms to lastObservedAt to make the filter exclusive (since dateRange.start is inclusive)\n // This prevents re-loading the same messages that were already observed\n const startDate = lastObservedAt ? new Date(lastObservedAt.getTime() + 1) : undefined;\n\n let result: { messages: MastraDBMessage[] };\n\n if (this.scope === 'resource' && resourceId) {\n // Resource scope: use the new listMessagesByResourceId method\n result = await this.storage.listMessagesByResourceId({\n resourceId,\n perPage: false, // Get all messages (no pagination limit)\n orderBy: { field: 'createdAt', direction: 'ASC' },\n filter: startDate\n ? {\n dateRange: {\n start: startDate,\n },\n }\n : undefined,\n });\n } else {\n // Thread scope: use listMessages with threadId\n result = await this.storage.listMessages({\n threadId,\n perPage: false, // Get all messages (no pagination limit)\n orderBy: { field: 'createdAt', direction: 'ASC' },\n filter: startDate\n ? {\n dateRange: {\n start: startDate,\n },\n }\n : undefined,\n });\n }\n\n return result.messages;\n }\n\n /**\n * Load unobserved messages from other threads (not the current thread) for a resource.\n * Called fresh each step so it reflects the latest lastObservedAt cursors\n * after observations complete.\n */\n private async loadOtherThreadsContext(resourceId: string, currentThreadId: string): Promise<string | undefined> {\n const { threads: allThreads } = await this.storage.listThreads({ filter: { resourceId } });\n\n const messagesByThread = new Map<string, MastraDBMessage[]>();\n\n for (const thread of allThreads) {\n // Skip current thread — its messages are already in messageList\n if (thread.id === currentThreadId) continue;\n\n const omMetadata = getThreadOMMetadata(thread.metadata);\n const threadLastObservedAt = omMetadata?.lastObservedAt;\n const startDate = threadLastObservedAt ? new Date(new Date(threadLastObservedAt).getTime() + 1) : undefined;\n\n const result = await this.storage.listMessages({\n threadId: thread.id,\n perPage: false,\n orderBy: { field: 'createdAt', direction: 'ASC' },\n filter: startDate ? { dateRange: { start: startDate } } : undefined,\n });\n\n // Filter out messages already observed in this instance's lifetime\n const filtered = result.messages.filter(m => !this.observedMessageIds.has(m.id));\n\n if (filtered.length > 0) {\n messagesByThread.set(thread.id, filtered);\n }\n }\n\n if (messagesByThread.size === 0) return undefined;\n\n const blocks = await this.formatUnobservedContextBlocks(messagesByThread, currentThreadId);\n return blocks || undefined;\n }\n\n /**\n * Format unobserved messages from other threads as <unobserved-context> blocks.\n * These are injected into the Actor's context so it has awareness of activity\n * in other threads for the same resource.\n */\n private async formatUnobservedContextBlocks(\n messagesByThread: Map<string, MastraDBMessage[]>,\n currentThreadId: string,\n ): Promise<string> {\n const blocks: string[] = [];\n\n for (const [threadId, messages] of messagesByThread) {\n // Skip current thread - those go in normal message history\n if (threadId === currentThreadId) continue;\n\n // Skip if no messages\n if (messages.length === 0) continue;\n\n // Format messages with timestamps, truncating large parts (e.g. tool results)\n // since this is injected as context for the actor, not sent to the observer\n const formattedMessages = formatMessagesForObserver(messages, { maxPartLength: 500 });\n\n if (formattedMessages) {\n const obscuredId = await this.representThreadIDInContext(threadId);\n blocks.push(`<other-conversation id=\"${obscuredId}\">\n${formattedMessages}\n</other-conversation>`);\n }\n }\n\n return blocks.join('\\n\\n');\n }\n\n private async representThreadIDInContext(threadId: string): Promise<string> {\n if (this.shouldObscureThreadIds) {\n // Check cache first\n const cached = this.threadIdCache.get(threadId);\n if (cached) return cached;\n\n // Use xxhash (32-bit) to create short, opaque, non-reversible identifiers\n // This prevents LLMs from recognizing patterns like \"answer_\" in base64\n const hasher = await this.hasher;\n const hashed = hasher.h32ToString(threadId);\n this.threadIdCache.set(threadId, hashed);\n return hashed;\n }\n return threadId;\n }\n\n /**\n * Strip any thread tags that the Observer might have added.\n * Thread attribution is handled externally by the system, not by the Observer.\n * This is a defense-in-depth measure.\n */\n private stripThreadTags(observations: string): string {\n // Remove any <thread...> or </thread> tags the Observer might add\n return observations.replace(/<thread[^>]*>|<\\/thread>/gi, '').trim();\n }\n\n /**\n * Get the maximum createdAt timestamp from a list of messages.\n * Used to set lastObservedAt to the most recent message timestamp instead of current time.\n * This ensures historical data (like LongMemEval fixtures) works correctly.\n */\n private getMaxMessageTimestamp(messages: MastraDBMessage[]): Date {\n let maxTime = 0;\n for (const msg of messages) {\n if (msg.createdAt) {\n const msgTime = new Date(msg.createdAt).getTime();\n if (msgTime > maxTime) {\n maxTime = msgTime;\n }\n }\n }\n // If no valid timestamps found, fall back to current time\n return maxTime > 0 ? new Date(maxTime) : new Date();\n }\n\n /**\n * Wrap observations in a thread attribution tag.\n * Used in resource scope to track which thread observations came from.\n */\n private async wrapWithThreadTag(threadId: string, observations: string): Promise<string> {\n // First strip any thread tags the Observer might have added\n const cleanObservations = this.stripThreadTags(observations);\n const obscuredId = await this.representThreadIDInContext(threadId);\n return `<thread id=\"${obscuredId}\">\\n${cleanObservations}\\n</thread>`;\n }\n\n /**\n * Append or merge new thread sections.\n * If the new section has the same thread ID and date as an existing section,\n * merge the observations into that section to reduce token usage.\n * Otherwise, append as a new section.\n */\n private replaceOrAppendThreadSection(\n existingObservations: string,\n _threadId: string,\n newThreadSection: string,\n ): string {\n if (!existingObservations) {\n return newThreadSection;\n }\n\n // Extract thread ID and date from new section\n const threadIdMatch = newThreadSection.match(/<thread id=\"([^\"]+)\">/);\n const dateMatch = newThreadSection.match(/Date:\\s*([A-Za-z]+\\s+\\d+,\\s+\\d+)/);\n\n if (!threadIdMatch || !dateMatch) {\n // Can't parse, just append\n return `${existingObservations}\\n\\n${newThreadSection}`;\n }\n\n const newThreadId = threadIdMatch[1]!;\n const newDate = dateMatch[1]!;\n\n // Look for existing section with same thread ID and date.\n // Use string search instead of regex to avoid polynomial backtracking (CodeQL).\n const threadOpen = `<thread id=\"${newThreadId}\">`;\n const threadClose = '</thread>';\n const startIdx = existingObservations.indexOf(threadOpen);\n let existingSection: string | null = null;\n let existingSectionStart = -1;\n let existingSectionEnd = -1;\n\n if (startIdx !== -1) {\n const closeIdx = existingObservations.indexOf(threadClose, startIdx);\n if (closeIdx !== -1) {\n existingSectionEnd = closeIdx + threadClose.length;\n existingSectionStart = startIdx;\n const section = existingObservations.slice(startIdx, existingSectionEnd);\n // Verify this section contains the matching date\n if (section.includes(`Date: ${newDate}`) || section.includes(`Date:${newDate}`)) {\n existingSection = section;\n }\n }\n }\n\n if (existingSection) {\n // Found existing section with same thread ID and date - merge observations\n // Extract observations from new section: everything after the Date: line, before </thread>\n const dateLineEnd = newThreadSection.indexOf('\\n', newThreadSection.indexOf('Date:'));\n const newCloseIdx = newThreadSection.lastIndexOf(threadClose);\n if (dateLineEnd !== -1 && newCloseIdx !== -1) {\n const newObsContent = newThreadSection.slice(dateLineEnd + 1, newCloseIdx).trim();\n if (newObsContent) {\n // Insert new observations at the end of the existing section (before </thread>)\n const withoutClose = existingSection.slice(0, existingSection.length - threadClose.length).trimEnd();\n const merged = `${withoutClose}\\n${newObsContent}\\n${threadClose}`;\n return (\n existingObservations.slice(0, existingSectionStart) +\n merged +\n existingObservations.slice(existingSectionEnd)\n );\n }\n }\n }\n\n // No existing section with same thread ID and date - append\n return `${existingObservations}\\n\\n${newThreadSection}`;\n }\n\n /**\n * Sort threads by their oldest unobserved message.\n * Returns thread IDs in order from oldest to most recent.\n * This ensures no thread's messages get \"stuck\" unobserved.\n */\n private sortThreadsByOldestMessage(messagesByThread: Map<string, MastraDBMessage[]>): string[] {\n const threadOrder = Array.from(messagesByThread.entries())\n .map(([threadId, messages]) => {\n // Find oldest message timestamp\n const oldestTimestamp = Math.min(\n ...messages.map(m => (m.createdAt ? new Date(m.createdAt).getTime() : Date.now())),\n );\n return { threadId, oldestTimestamp };\n })\n .sort((a, b) => a.oldestTimestamp - b.oldestTimestamp);\n\n return threadOrder.map(t => t.threadId);\n }\n\n /**\n * Do synchronous observation (fallback when no buffering)\n */\n private async doSynchronousObservation(opts: {\n record: ObservationalMemoryRecord;\n threadId: string;\n unobservedMessages: MastraDBMessage[];\n writer?: ProcessorStreamWriter;\n abortSignal?: AbortSignal;\n reflectionHooks?: Pick<ObserveHooks, 'onReflectionStart' | 'onReflectionEnd'>;\n requestContext?: RequestContext;\n }): Promise<void> {\n const { record, threadId, unobservedMessages, writer, abortSignal, reflectionHooks, requestContext } = opts;\n // Emit debug event for observation triggered\n this.emitDebugEvent({\n type: 'observation_triggered',\n timestamp: new Date(),\n threadId,\n resourceId: record.resourceId ?? '',\n previousObservations: record.activeObservations,\n messages: unobservedMessages.map(m => ({\n role: m.role,\n content: typeof m.content === 'string' ? m.content : JSON.stringify(m.content),\n })),\n });\n\n // ════════════════════════════════════════════════════════════\n // LOCKING: Acquire lock and re-check\n // ════════════════════════════════════════════════════════════\n await this.storage.setObservingFlag(record.id, true);\n registerOp(record.id, 'observing');\n\n // Generate unique cycle ID for this observation cycle\n // This ties together the start/end/failed markers\n const cycleId = crypto.randomUUID();\n\n // Insert START marker before observation (uses total unobserved as estimate;\n // actual observed count may be smaller with ratio-aware observation)\n const tokensToObserve = this.tokenCounter.countMessages(unobservedMessages);\n const lastMessage = unobservedMessages[unobservedMessages.length - 1];\n const startedAt = new Date().toISOString();\n\n if (lastMessage?.id) {\n const startMarker = this.createObservationStartMarker({\n cycleId,\n operationType: 'observation',\n tokensToObserve,\n recordId: record.id,\n threadId,\n threadIds: [threadId],\n });\n // Stream the start marker to the UI first - this adds the part via stream handler\n if (writer) {\n await writer.custom(startMarker).catch(() => {\n // Ignore errors from streaming - observation should continue\n });\n }\n\n // Then add to message (skipPush since writer.custom already added the part)\n }\n\n try {\n // Re-check: reload record to see if another request already observed\n const freshRecord = await this.storage.getObservationalMemory(record.threadId, record.resourceId);\n if (freshRecord && freshRecord.lastObservedAt && record.lastObservedAt) {\n if (freshRecord.lastObservedAt > record.lastObservedAt) {\n return;\n }\n }\n\n // ════════════════════════════════════════════════════════════\n // RATIO-AWARE MESSAGE SEALING\n // When bufferActivation is set and sync observation fires, seal the\n // most recent message so any future parts added by the LLM go into\n // a new message. This keeps the observation scope bounded — the sealed\n // content gets observed now, and new content accumulates separately\n // for the next observation cycle.\n // ════════════════════════════════════════════════════════════\n let messagesToObserve = unobservedMessages;\n const bufferActivation = this.observationConfig.bufferActivation;\n if (bufferActivation && bufferActivation < 1 && unobservedMessages.length >= 1) {\n const newestMsg = unobservedMessages[unobservedMessages.length - 1];\n if (newestMsg?.content?.parts?.length) {\n this.sealMessagesForBuffering([newestMsg]);\n omDebug(\n `[OM:sync-obs] sealed newest message (${newestMsg.role}, ${newestMsg.content.parts.length} parts) for ratio-aware observation`,\n );\n }\n }\n\n const result = await this.callObserver(\n freshRecord?.activeObservations ?? record.activeObservations,\n messagesToObserve,\n abortSignal,\n { requestContext },\n );\n\n // Build new observations (use freshRecord if available)\n const existingObservations = freshRecord?.activeObservations ?? record.activeObservations ?? '';\n let newObservations: string;\n if (this.scope === 'resource') {\n // In resource scope: wrap with thread tag and replace/append\n const threadSection = await this.wrapWithThreadTag(threadId, result.observations);\n newObservations = this.replaceOrAppendThreadSection(existingObservations, threadId, threadSection);\n } else {\n // In thread scope: simple append\n newObservations = existingObservations\n ? `${existingObservations}\\n\\n${result.observations}`\n : result.observations;\n }\n\n let totalTokenCount = this.tokenCounter.countObservations(newObservations);\n\n // Calculate tokens generated in THIS cycle only (for UI marker)\n const cycleObservationTokens = this.tokenCounter.countObservations(result.observations);\n\n // Use the max message timestamp as cursor — only for the messages we actually observed\n const lastObservedAt = this.getMaxMessageTimestamp(messagesToObserve);\n\n // Collect message IDs being observed for the safeguard\n // Only mark the messages we actually observed, not the ones we kept\n const newMessageIds = messagesToObserve.map(m => m.id);\n const existingIds = freshRecord?.observedMessageIds ?? record.observedMessageIds ?? [];\n const allObservedIds = [...new Set([...(Array.isArray(existingIds) ? existingIds : []), ...newMessageIds])];\n\n // Save thread-specific metadata BEFORE updating the OM record.\n // This ensures a consistent lock ordering (mastra_threads → mastra_observational_memory)\n // that matches the order used by saveMessages, preventing PostgreSQL deadlocks\n // when concurrent agents share a resourceId.\n if (result.suggestedContinuation || result.currentTask) {\n const thread = await this.storage.getThreadById({ threadId });\n if (thread) {\n const newMetadata = setThreadOMMetadata(thread.metadata, {\n suggestedResponse: result.suggestedContinuation,\n currentTask: result.currentTask,\n });\n await this.storage.updateThread({\n id: threadId,\n title: thread.title ?? '',\n metadata: newMetadata,\n });\n }\n }\n\n await this.storage.updateActiveObservations({\n id: record.id,\n observations: newObservations,\n tokenCount: totalTokenCount,\n lastObservedAt,\n observedMessageIds: allObservedIds,\n });\n\n // ════════════════════════════════════════════════════════════════════════\n // INSERT END MARKER after successful observation\n // This marks the boundary between observed and unobserved parts\n // ════════════════════════════════════════════════════════════════════════\n const actualTokensObserved = this.tokenCounter.countMessages(messagesToObserve);\n if (lastMessage?.id) {\n const endMarker = this.createObservationEndMarker({\n cycleId,\n operationType: 'observation',\n startedAt,\n tokensObserved: actualTokensObserved,\n observationTokens: cycleObservationTokens,\n observations: result.observations,\n currentTask: result.currentTask,\n suggestedResponse: result.suggestedContinuation,\n recordId: record.id,\n threadId,\n });\n\n // Stream the end marker to the UI first - this adds the part via stream handler\n if (writer) {\n await writer.custom(endMarker).catch(() => {\n // Ignore errors from streaming - observation should continue\n });\n }\n\n // Then seal the message (skipPush since writer.custom already added the part)\n }\n\n // Emit debug event for observation complete\n this.emitDebugEvent({\n type: 'observation_complete',\n timestamp: new Date(),\n threadId,\n resourceId: record.resourceId ?? '',\n observations: newObservations,\n rawObserverOutput: result.observations,\n previousObservations: record.activeObservations,\n messages: messagesToObserve.map(m => ({\n role: m.role,\n content: typeof m.content === 'string' ? m.content : JSON.stringify(m.content),\n })),\n usage: result.usage,\n });\n\n // Check for reflection\n await this.maybeReflect({\n record: { ...record, activeObservations: newObservations },\n observationTokens: totalTokenCount,\n threadId,\n writer,\n abortSignal,\n reflectionHooks,\n requestContext,\n });\n } catch (error) {\n // Insert FAILED marker on error\n if (lastMessage?.id) {\n const failedMarker = this.createObservationFailedMarker({\n cycleId,\n operationType: 'observation',\n startedAt,\n tokensAttempted: tokensToObserve,\n error: error instanceof Error ? error.message : String(error),\n recordId: record.id,\n threadId,\n });\n\n // Stream the failed marker to the UI first - this adds the part via stream handler\n if (writer) {\n await writer.custom(failedMarker).catch(() => {\n // Ignore errors from streaming - observation should continue\n });\n }\n\n // Then seal the message (skipPush since writer.custom already added the part)\n }\n // If aborted, re-throw so the main agent loop can handle cancellation\n if (abortSignal?.aborted) {\n throw error;\n }\n // Log the error but don't re-throw - observation failure should not crash the agent\n omError('[OM] Observation failed', error);\n } finally {\n await this.storage.setObservingFlag(record.id, false);\n unregisterOp(record.id, 'observing');\n }\n }\n\n /**\n * Start an async background observation that stores results to bufferedObservations.\n * This is a fire-and-forget operation that runs in the background.\n * The results will be swapped to active when the main threshold is reached.\n *\n * If another buffering operation is already in progress for this scope, this will\n * wait for it to complete before starting a new one (mutex behavior).\n *\n * @param record - Current OM record\n * @param threadId - Thread ID\n * @param unobservedMessages - All unobserved messages (will be filtered for already-buffered)\n * @param lockKey - Lock key for this scope\n * @param writer - Optional stream writer for emitting buffering markers\n */\n private startAsyncBufferedObservation(\n record: ObservationalMemoryRecord,\n threadId: string,\n unobservedMessages: MastraDBMessage[],\n lockKey: string,\n writer?: ProcessorStreamWriter,\n contextWindowTokens?: number,\n requestContext?: RequestContext,\n ): void {\n const bufferKey = this.getObservationBufferKey(lockKey);\n\n // Update the last buffered boundary (in-memory for current instance).\n // Use contextWindowTokens (all messages in context) to match the scale of\n // totalPendingTokens passed to shouldTriggerAsyncObservation.\n const currentTokens =\n contextWindowTokens ?? this.tokenCounter.countMessages(unobservedMessages) + (record.pendingMessageTokens ?? 0);\n ObservationalMemory.lastBufferedBoundary.set(bufferKey, currentTokens);\n\n // Set persistent flag so new instances (created per request) know buffering is in progress\n registerOp(record.id, 'bufferingObservation');\n this.storage.setBufferingObservationFlag(record.id, true, currentTokens).catch(err => {\n omError('[OM] Failed to set buffering observation flag', err);\n });\n\n // Start the async operation - waits for any existing op to complete first\n const asyncOp = this.runAsyncBufferedObservation(\n record,\n threadId,\n unobservedMessages,\n bufferKey,\n writer,\n requestContext,\n ).finally(() => {\n // Clean up the operation tracking\n ObservationalMemory.asyncBufferingOps.delete(bufferKey);\n // Clear persistent flag\n unregisterOp(record.id, 'bufferingObservation');\n this.storage.setBufferingObservationFlag(record.id, false).catch(err => {\n omError('[OM] Failed to clear buffering observation flag', err);\n });\n });\n\n ObservationalMemory.asyncBufferingOps.set(bufferKey, asyncOp);\n }\n\n /**\n * Internal method that waits for existing buffering operation and then runs new buffering.\n * This implements the mutex-wait behavior.\n */\n private async runAsyncBufferedObservation(\n record: ObservationalMemoryRecord,\n threadId: string,\n unobservedMessages: MastraDBMessage[],\n bufferKey: string,\n writer?: ProcessorStreamWriter,\n requestContext?: RequestContext,\n ): Promise<void> {\n // Wait for any existing buffering operation to complete first (mutex behavior)\n const existingOp = ObservationalMemory.asyncBufferingOps.get(bufferKey);\n if (existingOp) {\n try {\n await existingOp;\n } catch {\n // Previous op failed, continue with new one\n }\n }\n\n // Re-fetch record to get latest state after waiting\n const freshRecord = await this.storage.getObservationalMemory(record.threadId, record.resourceId);\n if (!freshRecord) {\n return;\n }\n\n // Determine the buffer cursor — the timestamp boundary beyond which we look for new messages.\n // Start from the static map (in-process), fall back to DB record (survives restarts).\n let bufferCursor = ObservationalMemory.lastBufferedAtTime.get(bufferKey) ?? freshRecord.lastBufferedAtTime ?? null;\n\n // Advance the cursor if lastObservedAt is newer (e.g. sync observation ran after the last buffer)\n if (freshRecord.lastObservedAt) {\n const lastObserved = new Date(freshRecord.lastObservedAt);\n if (!bufferCursor || lastObserved > bufferCursor) {\n bufferCursor = lastObserved;\n }\n }\n\n // Filter messages to only those newer than the buffer cursor.\n // This prevents re-buffering messages that were already included in a previous chunk,\n // even if their IDs were mutated by saveMessagesWithSealedIdTracking.\n let candidateMessages = this.getUnobservedMessages(unobservedMessages, freshRecord, {\n excludeBuffered: true,\n });\n const preFilterCount = candidateMessages.length;\n if (bufferCursor) {\n candidateMessages = candidateMessages.filter(msg => {\n if (!msg.createdAt) return true; // include messages without timestamps\n return new Date(msg.createdAt) > bufferCursor;\n });\n }\n\n omDebug(\n `[OM:bufferCursor] cursor=${bufferCursor?.toISOString() ?? 'null'}, unobserved=${unobservedMessages.length}, afterExcludeBuffered=${preFilterCount}, afterCursorFilter=${candidateMessages.length}`,\n );\n\n // Check if there's enough content to buffer\n const bufferTokens = this.observationConfig.bufferTokens ?? 5000;\n const minNewTokens = bufferTokens / 2;\n const newTokens = this.tokenCounter.countMessages(candidateMessages);\n\n if (newTokens < minNewTokens) {\n return; // Not enough new content to buffer\n }\n\n const messagesToBuffer = candidateMessages;\n\n // Seal the messages being buffered to prevent new parts from being added.\n // This ensures that any streaming content after this point goes to new messages,\n // preserving the boundary of what we're buffering.\n this.sealMessagesForBuffering(messagesToBuffer);\n\n // CRITICAL: Persist the sealed messages to storage immediately.\n // This ensures that:\n // 1. The seal metadata (sealedAt on last part) is saved to the database\n // 2. When MessageList creates new messages for streaming content after the seal,\n // those new messages have their own IDs and don't overwrite the sealed messages\n // 3. The sealed messages remain intact with their content at the time of buffering\n await this.messageHistory.persistMessages({\n messages: messagesToBuffer,\n threadId,\n resourceId: freshRecord.resourceId ?? undefined,\n });\n\n // Track sealed message IDs in the static map so saveMessagesWithSealedIdTracking\n // generates new IDs for any future saves of these messages.\n // Uses static map because async buffering runs in the background and the per-state\n // sealedIds set may belong to a different (already-finished) processInputStep call.\n let staticSealedIds = ObservationalMemory.sealedMessageIds.get(threadId);\n if (!staticSealedIds) {\n staticSealedIds = new Set<string>();\n ObservationalMemory.sealedMessageIds.set(threadId, staticSealedIds);\n }\n for (const msg of messagesToBuffer) {\n staticSealedIds.add(msg.id);\n }\n\n // Generate cycle ID and capture start time\n const cycleId = `buffer-obs-${Date.now()}-${Math.random().toString(36).slice(2, 11)}`;\n const startedAt = new Date().toISOString();\n const tokensToBuffer = this.tokenCounter.countMessages(messagesToBuffer);\n\n // Emit buffering start marker\n if (writer) {\n const startMarker = this.createBufferingStartMarker({\n cycleId,\n operationType: 'observation',\n tokensToBuffer,\n recordId: freshRecord.id,\n threadId,\n threadIds: [threadId],\n });\n void writer.custom(startMarker).catch(() => {});\n }\n\n try {\n omDebug(\n `[OM:bufferInput] cycleId=${cycleId}, msgCount=${messagesToBuffer.length}, msgTokens=${this.tokenCounter.countMessages(messagesToBuffer)}, ids=${messagesToBuffer.map(m => `${m.id?.slice(0, 8)}@${m.createdAt ? new Date(m.createdAt).toISOString() : 'none'}`).join(',')}`,\n );\n await this.doAsyncBufferedObservation(\n freshRecord,\n threadId,\n messagesToBuffer,\n cycleId,\n startedAt,\n writer,\n requestContext,\n );\n\n // Update the buffer cursor so the next buffer only sees messages newer than this one.\n // Uses the same timestamp logic as the chunk's lastObservedAt (max message timestamp + 1ms).\n const maxTs = this.getMaxMessageTimestamp(messagesToBuffer);\n const cursor = new Date(maxTs.getTime() + 1);\n ObservationalMemory.lastBufferedAtTime.set(bufferKey, cursor);\n } catch (error) {\n // Emit buffering failed marker\n if (writer) {\n const failedMarker = this.createBufferingFailedMarker({\n cycleId,\n operationType: 'observation',\n startedAt,\n tokensAttempted: tokensToBuffer,\n error: error instanceof Error ? error.message : String(error),\n recordId: freshRecord.id,\n threadId,\n });\n void writer.custom(failedMarker).catch(() => {});\n await this.persistMarkerToStorage(failedMarker, threadId, freshRecord.resourceId ?? undefined);\n }\n omError('[OM] Async buffered observation failed', error);\n }\n }\n\n /**\n * Perform async buffered observation - observes messages and stores to bufferedObservations.\n * Does NOT update activeObservations or trigger reflection.\n *\n * The observer sees: active observations + existing buffered observations + message history\n * (excluding already-buffered messages).\n */\n private async doAsyncBufferedObservation(\n record: ObservationalMemoryRecord,\n threadId: string,\n messagesToBuffer: MastraDBMessage[],\n cycleId: string,\n startedAt: string,\n writer?: ProcessorStreamWriter,\n requestContext?: RequestContext,\n ): Promise<void> {\n // Build combined context for the observer: active + buffered chunk observations\n const bufferedChunks = this.getBufferedChunks(record);\n const bufferedChunksText = bufferedChunks.map(c => c.observations).join('\\n\\n');\n const combinedObservations = this.combineObservationsForBuffering(record.activeObservations, bufferedChunksText);\n\n // Call observer with combined context\n // Allow the observer to produce suggestedResponse/currentTask so they survive\n // activation and maintain continuity when the context window shrinks\n const result = await this.callObserver(\n combinedObservations,\n messagesToBuffer,\n undefined, // No abort signal for background ops\n { requestContext },\n );\n\n // If the observer returned empty observations, skip buffering\n if (!result.observations) {\n omDebug(`[OM:doAsyncBufferedObservation] empty observations returned, skipping buffer storage`);\n return;\n }\n\n // Get the new observations to buffer (just the new content, not merged)\n // The storage adapter will handle appending to existing buffered content\n let newObservations: string;\n if (this.scope === 'resource') {\n newObservations = await this.wrapWithThreadTag(threadId, result.observations);\n } else {\n newObservations = result.observations;\n }\n\n const newTokenCount = this.tokenCounter.countObservations(newObservations);\n\n // Just pass the new message IDs - storage adapter will merge with existing\n const newMessageIds = messagesToBuffer.map(m => m.id);\n const messageTokens = this.tokenCounter.countMessages(messagesToBuffer);\n\n // lastObservedAt should be the timestamp of the latest message being buffered (+1ms for exclusive)\n // This ensures new messages created after buffering are still considered unobserved\n const maxMessageTimestamp = this.getMaxMessageTimestamp(messagesToBuffer);\n const lastObservedAt = new Date(maxMessageTimestamp.getTime() + 1);\n\n // Store as a new buffered chunk (storage adapter appends to existing chunks)\n await this.storage.updateBufferedObservations({\n id: record.id,\n chunk: {\n cycleId,\n observations: newObservations,\n tokenCount: newTokenCount,\n messageIds: newMessageIds,\n messageTokens,\n lastObservedAt,\n suggestedContinuation: result.suggestedContinuation,\n currentTask: result.currentTask,\n },\n lastBufferedAtTime: lastObservedAt,\n });\n\n // Emit buffering end marker\n if (writer) {\n const tokensBuffered = this.tokenCounter.countMessages(messagesToBuffer);\n // Re-fetch record to get total buffered tokens after storage update\n const updatedRecord = await this.storage.getObservationalMemory(record.threadId, record.resourceId);\n const updatedChunks = this.getBufferedChunks(updatedRecord);\n const totalBufferedTokens = updatedChunks.reduce((sum, c) => sum + (c.tokenCount ?? 0), 0) || newTokenCount;\n const endMarker = this.createBufferingEndMarker({\n cycleId,\n operationType: 'observation',\n startedAt,\n tokensBuffered,\n bufferedTokens: totalBufferedTokens,\n recordId: record.id,\n threadId,\n observations: newObservations,\n });\n void writer.custom(endMarker).catch(() => {});\n // Persist so the badge state survives page reload even if the stream is already closed\n await this.persistMarkerToStorage(endMarker, threadId, record.resourceId ?? undefined);\n }\n }\n\n /**\n * Combine active and buffered observations for the buffering observer context.\n * The buffering observer needs to see both so it doesn't duplicate content.\n */\n private combineObservationsForBuffering(\n activeObservations: string | undefined,\n bufferedObservations: string | undefined,\n ): string | undefined {\n if (!activeObservations && !bufferedObservations) {\n return undefined;\n }\n if (!activeObservations) {\n return bufferedObservations;\n }\n if (!bufferedObservations) {\n return activeObservations;\n }\n // Both exist - combine them with a clear separator\n return `${activeObservations}\\n\\n--- BUFFERED (pending activation) ---\\n\\n${bufferedObservations}`;\n }\n\n /**\n * Try to activate buffered observations when threshold is reached.\n * Returns true if activation succeeded, false if no buffered content or activation failed.\n *\n * @param record - Current OM record\n * @param lockKey - Lock key for this scope\n * @param writer - Optional writer for emitting UI markers\n */\n private async tryActivateBufferedObservations(\n record: ObservationalMemoryRecord,\n lockKey: string,\n currentPendingTokens: number,\n writer?: ProcessInputStepArgs['writer'],\n messageList?: MessageList,\n ): Promise<{\n success: boolean;\n updatedRecord?: ObservationalMemoryRecord;\n messageTokensActivated?: number;\n activatedMessageIds?: string[];\n suggestedContinuation?: string;\n currentTask?: string;\n }> {\n // Check if there's buffered content to activate\n const chunks = this.getBufferedChunks(record);\n omDebug(`[OM:tryActivate] chunks=${chunks.length}, recordId=${record.id}`);\n if (!chunks.length) {\n omDebug(`[OM:tryActivate] no chunks, returning false`);\n return { success: false };\n }\n\n const bufferKey = this.getObservationBufferKey(lockKey);\n\n // Wait for any in-progress async buffering to complete (with timeout)\n // Use 60s timeout - buffering can take a while for large message batches\n const asyncOp = ObservationalMemory.asyncBufferingOps.get(bufferKey);\n if (asyncOp) {\n try {\n await Promise.race([\n asyncOp,\n new Promise((_, reject) => setTimeout(() => reject(new Error('Timeout')), 60_000)),\n ]);\n } catch {\n // Timeout or error - proceed with what we have\n }\n }\n\n // Re-fetch record to get latest buffered content\n const freshRecord = await this.storage.getObservationalMemory(record.threadId, record.resourceId);\n if (!freshRecord) {\n return { success: false };\n }\n const freshChunks = this.getBufferedChunks(freshRecord);\n if (!freshChunks.length) {\n return { success: false };\n }\n\n // Re-check whether activation is still needed. A previous activation on this\n // turn (or an in-flight buffering op that just completed) may have already\n // brought us well below the threshold. Activating unnecessarily invalidates\n // the prompt cache, so we skip if we're already under the threshold.\n const messageTokensThreshold = this.getMaxThreshold(this.observationConfig.messageTokens);\n let effectivePendingTokens = currentPendingTokens;\n if (messageList) {\n effectivePendingTokens = this.tokenCounter.countMessages(messageList.get.all.db());\n if (effectivePendingTokens < messageTokensThreshold) {\n omDebug(\n `[OM:tryActivate] skipping activation: freshPendingTokens=${effectivePendingTokens} < threshold=${messageTokensThreshold}`,\n );\n return { success: false };\n }\n }\n\n // Perform partial swap with bufferActivation\n const bufferActivation = this.observationConfig.bufferActivation ?? 0.7;\n const activationRatio = this.resolveActivationRatio(bufferActivation, messageTokensThreshold);\n\n // When above blockAfter, bypass the overshoot safeguard to aggressively reduce context.\n // The system is about to do a synchronous observation anyway, so we should remove as much as possible.\n const forceMaxActivation = !!(\n this.observationConfig.blockAfter && effectivePendingTokens >= this.observationConfig.blockAfter\n );\n\n omDebug(\n `[OM:tryActivate] swapping: freshChunks=${freshChunks.length}, bufferActivation=${bufferActivation}, activationRatio=${activationRatio}, forceMax=${forceMaxActivation}, totalChunkTokens=${freshChunks.reduce((s, c) => s + (c.tokenCount ?? 0), 0)}`,\n );\n const activationResult = await this.storage.swapBufferedToActive({\n id: freshRecord.id,\n activationRatio,\n messageTokensThreshold,\n currentPendingTokens: effectivePendingTokens,\n forceMaxActivation,\n });\n omDebug(\n `[OM:tryActivate] swapResult: chunksActivated=${activationResult.chunksActivated}, tokensActivated=${activationResult.messageTokensActivated}, obsTokensActivated=${activationResult.observationTokensActivated}, activatedCycleIds=${activationResult.activatedCycleIds.join(',')}`,\n );\n\n // Clear the buffering flag but do NOT reset lastBufferedBoundary here.\n // The caller sets the boundary to the post-activation context size so that\n // interval tracking continues from the correct position. Deleting it here\n // would reset to 0 and cause the next step to immediately re-trigger buffering.\n await this.storage.setBufferingObservationFlag(freshRecord.id, false);\n unregisterOp(freshRecord.id, 'bufferingObservation');\n\n // Fetch updated record\n const updatedRecord = await this.storage.getObservationalMemory(record.threadId, record.resourceId);\n\n // Emit activation markers for UI feedback - one per activated cycleId\n // Each marker gets its own chunk's data so the UI shows per-chunk breakdowns\n if (writer && updatedRecord && activationResult.activatedCycleIds.length > 0) {\n const perChunkMap = new Map(activationResult.perChunk?.map(c => [c.cycleId, c]));\n for (const cycleId of activationResult.activatedCycleIds) {\n const chunkData = perChunkMap.get(cycleId);\n const activationMarker = this.createActivationMarker({\n cycleId, // Use the original buffering cycleId so UI can link them\n operationType: 'observation',\n chunksActivated: 1,\n tokensActivated: chunkData?.messageTokens ?? activationResult.messageTokensActivated,\n observationTokens: chunkData?.observationTokens ?? activationResult.observationTokensActivated,\n messagesActivated: chunkData?.messageCount ?? activationResult.messagesActivated,\n recordId: updatedRecord.id,\n threadId: updatedRecord.threadId ?? record.threadId ?? '',\n generationCount: updatedRecord.generationCount ?? 0,\n observations: chunkData?.observations ?? activationResult.observations,\n });\n void writer.custom(activationMarker).catch(() => {});\n await this.persistMarkerToMessage(\n activationMarker,\n messageList,\n record.threadId ?? '',\n record.resourceId ?? undefined,\n );\n }\n }\n\n return {\n success: true,\n updatedRecord: updatedRecord ?? undefined,\n messageTokensActivated: activationResult.messageTokensActivated,\n activatedMessageIds: activationResult.activatedMessageIds,\n suggestedContinuation: activationResult.suggestedContinuation,\n currentTask: activationResult.currentTask,\n };\n }\n\n /**\n * Start an async background reflection that stores results to bufferedReflection.\n * This is a fire-and-forget operation that runs in the background.\n * The results will be swapped to active when the main reflection threshold is reached.\n *\n * @param record - Current OM record\n * @param observationTokens - Current observation token count\n * @param lockKey - Lock key for this scope\n */\n private startAsyncBufferedReflection(\n record: ObservationalMemoryRecord,\n observationTokens: number,\n lockKey: string,\n writer?: ProcessorStreamWriter,\n requestContext?: RequestContext,\n ): void {\n const bufferKey = this.getReflectionBufferKey(lockKey);\n\n // Don't start if already in progress\n if (this.isAsyncBufferingInProgress(bufferKey)) {\n return;\n }\n\n // Update the last buffered boundary (in-memory for current instance)\n ObservationalMemory.lastBufferedBoundary.set(bufferKey, observationTokens);\n\n // Set persistent flag so new instances know buffering is in progress\n registerOp(record.id, 'bufferingReflection');\n this.storage.setBufferingReflectionFlag(record.id, true).catch(err => {\n omError('[OM] Failed to set buffering reflection flag', err);\n });\n\n // Start the async operation\n const asyncOp = this.doAsyncBufferedReflection(record, bufferKey, writer, requestContext)\n .catch(async error => {\n // Emit buffering failed marker\n if (writer) {\n const failedMarker = this.createBufferingFailedMarker({\n cycleId: `reflect-buf-${Date.now()}-${Math.random().toString(36).slice(2, 11)}`,\n operationType: 'reflection',\n startedAt: new Date().toISOString(),\n tokensAttempted: observationTokens,\n error: error instanceof Error ? error.message : String(error),\n recordId: record.id,\n threadId: record.threadId ?? '',\n });\n void writer.custom(failedMarker).catch(() => {});\n await this.persistMarkerToStorage(failedMarker, record.threadId ?? '', record.resourceId ?? undefined);\n }\n // Log but don't crash - async buffering failure is recoverable\n omError('[OM] Async buffered reflection failed', error);\n })\n .finally(() => {\n // Clean up the operation tracking\n ObservationalMemory.asyncBufferingOps.delete(bufferKey);\n // Clear persistent flag\n unregisterOp(record.id, 'bufferingReflection');\n this.storage.setBufferingReflectionFlag(record.id, false).catch(err => {\n omError('[OM] Failed to clear buffering reflection flag', err);\n });\n });\n\n ObservationalMemory.asyncBufferingOps.set(bufferKey, asyncOp);\n }\n\n /**\n * Perform async buffered reflection - reflects observations and stores to bufferedReflection.\n * Does NOT create a new generation or update activeObservations.\n */\n private async doAsyncBufferedReflection(\n record: ObservationalMemoryRecord,\n _bufferKey: string,\n writer?: ProcessorStreamWriter,\n requestContext?: RequestContext,\n ): Promise<void> {\n // Re-fetch the record to get the latest observation token count.\n // The record passed in may be stale if sync observation just ran.\n const freshRecord = await this.storage.getObservationalMemory(record.threadId, record.resourceId);\n const currentRecord = freshRecord ?? record;\n const observationTokens = currentRecord.observationTokenCount ?? 0;\n const reflectThreshold = this.getMaxThreshold(this.reflectionConfig.observationTokens);\n const bufferActivation = this.reflectionConfig.bufferActivation ?? 0.5;\n const startedAt = new Date().toISOString();\n const cycleId = `reflect-buf-${Date.now()}-${Math.random().toString(36).slice(2, 11)}`;\n\n // Store cycleId so tryActivateBufferedReflection can use it for UI markers\n ObservationalMemory.reflectionBufferCycleIds.set(_bufferKey, cycleId);\n\n // Slice activeObservations to only the first N lines that fit within the\n // activation-point token budget. This keeps the reflector prompt small\n // (avoiding LLM hangs on huge prompts) and matches the portion that will\n // be replaced at activation time.\n const fullObservations = currentRecord.activeObservations ?? '';\n const allLines = fullObservations.split('\\n');\n const totalLines = allLines.length;\n\n // Calculate how many lines fit within the activation point budget\n const avgTokensPerLine = totalLines > 0 ? observationTokens / totalLines : 0;\n const activationPointTokens = reflectThreshold * bufferActivation;\n const linesToReflect =\n avgTokensPerLine > 0 ? Math.min(Math.floor(activationPointTokens / avgTokensPerLine), totalLines) : totalLines;\n\n const activeObservations = allLines.slice(0, linesToReflect).join('\\n');\n const reflectedObservationLineCount = linesToReflect;\n const sliceTokenEstimate = Math.round(avgTokensPerLine * linesToReflect);\n // Compression target: ask for 75% of the slice size. This is a modest reduction\n // that LLMs can reliably achieve on dense observation text, unlike the more\n // aggressive bufferActivation ratio which often fails on already-compressed content.\n const compressionTarget = Math.round(sliceTokenEstimate * 0.75);\n\n omDebug(\n `[OM:reflect] doAsyncBufferedReflection: slicing observations for reflection — totalLines=${totalLines}, avgTokPerLine=${avgTokensPerLine.toFixed(1)}, activationPointTokens=${activationPointTokens}, linesToReflect=${linesToReflect}/${totalLines}, sliceTokenEstimate=${sliceTokenEstimate}, compressionTarget=${compressionTarget}`,\n );\n\n omDebug(\n `[OM:reflect] doAsyncBufferedReflection: starting reflector call, recordId=${currentRecord.id}, observationTokens=${sliceTokenEstimate}, compressionTarget=${compressionTarget} (inputTokens), activeObsLength=${activeObservations.length}, reflectedLineCount=${reflectedObservationLineCount}`,\n );\n\n // Emit buffering start marker (after slice so we report the actual token count)\n if (writer) {\n const startMarker = this.createBufferingStartMarker({\n cycleId,\n operationType: 'reflection',\n tokensToBuffer: sliceTokenEstimate,\n recordId: record.id,\n threadId: record.threadId ?? '',\n threadIds: record.threadId ? [record.threadId] : [],\n });\n void writer.custom(startMarker).catch(() => {});\n }\n\n // Call reflector with compression target.\n // Start at compression level 1 (standard guidance), retry at level 2 (aggressive).\n const reflectResult = await this.callReflector(\n activeObservations,\n undefined, // No manual prompt\n undefined, // No stream context for background ops\n compressionTarget,\n undefined, // No abort signal for background ops\n true, // Skip continuation hints for async buffering\n 1, // Start at compression level 1 for buffered reflection\n requestContext,\n );\n\n const reflectionTokenCount = this.tokenCounter.countObservations(reflectResult.observations);\n omDebug(\n `[OM:reflect] doAsyncBufferedReflection: reflector returned ${reflectionTokenCount} tokens (${reflectResult.observations?.length} chars), saving to recordId=${currentRecord.id}`,\n );\n\n // Store to bufferedReflection along with the line boundary\n await this.storage.updateBufferedReflection({\n id: currentRecord.id,\n reflection: reflectResult.observations,\n tokenCount: reflectionTokenCount,\n inputTokenCount: sliceTokenEstimate,\n reflectedObservationLineCount,\n });\n omDebug(\n `[OM:reflect] doAsyncBufferedReflection: bufferedReflection saved with lineCount=${reflectedObservationLineCount}`,\n );\n\n // Emit buffering end marker\n if (writer) {\n const endMarker = this.createBufferingEndMarker({\n cycleId,\n operationType: 'reflection',\n startedAt,\n tokensBuffered: sliceTokenEstimate,\n bufferedTokens: reflectionTokenCount,\n recordId: currentRecord.id,\n threadId: currentRecord.threadId ?? '',\n observations: reflectResult.observations,\n });\n void writer.custom(endMarker).catch(() => {});\n // Persist so the badge state survives page reload even if the stream is already closed\n await this.persistMarkerToStorage(endMarker, currentRecord.threadId ?? '', currentRecord.resourceId ?? undefined);\n }\n }\n\n /**\n * Try to activate buffered reflection when threshold is reached.\n * Returns true if activation succeeded, false if no buffered content or activation failed.\n *\n * @param record - Current OM record\n * @param lockKey - Lock key for this scope\n */\n private async tryActivateBufferedReflection(\n record: ObservationalMemoryRecord,\n lockKey: string,\n writer?: ProcessorStreamWriter,\n messageList?: MessageList,\n ): Promise<boolean> {\n const bufferKey = this.getReflectionBufferKey(lockKey);\n\n // Wait for any in-flight async reflection before checking DB state.\n // The passed-in record may be stale — the async reflector could have\n // saved results between when the record was fetched and now.\n const asyncOp = ObservationalMemory.asyncBufferingOps.get(bufferKey);\n if (asyncOp) {\n omDebug(`[OM:reflect] tryActivateBufferedReflection: waiting for in-progress op...`);\n try {\n await Promise.race([\n asyncOp,\n new Promise((_, reject) => setTimeout(() => reject(new Error('Timeout')), 60_000)),\n ]);\n } catch {\n // Timeout or error - proceed with what we have\n }\n }\n\n // Fetch the latest record — either the async op just completed, or we\n // need the freshest DB state to check for buffered reflection content.\n const freshRecord = await this.storage.getObservationalMemory(record.threadId, record.resourceId);\n\n omDebug(\n `[OM:reflect] tryActivateBufferedReflection: recordId=${record.id}, hasBufferedReflection=${!!freshRecord?.bufferedReflection}, bufferedReflectionLen=${freshRecord?.bufferedReflection?.length ?? 0}`,\n );\n omDebug(\n `[OM:reflect] tryActivateBufferedReflection: freshRecord.id=${freshRecord?.id}, freshBufferedReflection=${freshRecord?.bufferedReflection ? 'present (' + freshRecord.bufferedReflection.length + ' chars)' : 'empty'}, freshObsTokens=${freshRecord?.observationTokenCount}`,\n );\n\n if (!freshRecord?.bufferedReflection) {\n omDebug(`[OM:reflect] tryActivateBufferedReflection: no buffered reflection after re-fetch, returning false`);\n return false;\n }\n\n const beforeTokens = freshRecord.observationTokenCount ?? 0;\n\n // Compute the combined token count for the new activeObservations.\n // Replicate the merge logic: bufferedReflection + unreflected lines after the boundary.\n const reflectedLineCount = freshRecord.reflectedObservationLineCount ?? 0;\n const currentObservations = freshRecord.activeObservations ?? '';\n const allLines = currentObservations.split('\\n');\n const unreflectedLines = allLines.slice(reflectedLineCount);\n const unreflectedContent = unreflectedLines.join('\\n').trim();\n const combinedObservations = unreflectedContent\n ? `${freshRecord.bufferedReflection}\\n\\n${unreflectedContent}`\n : freshRecord.bufferedReflection!;\n const combinedTokenCount = this.tokenCounter.countObservations(combinedObservations);\n\n // Swap buffered reflection to active. The storage adapter uses the stored\n // reflectedObservationLineCount to split: reflected lines → replaced by bufferedReflection,\n // unreflected lines (added after reflection) → appended as-is.\n omDebug(\n `[OM:reflect] tryActivateBufferedReflection: activating, beforeTokens=${beforeTokens}, combinedTokenCount=${combinedTokenCount}, reflectedLineCount=${reflectedLineCount}, unreflectedLines=${unreflectedLines.length}`,\n );\n await this.storage.swapBufferedReflectionToActive({\n currentRecord: freshRecord,\n tokenCount: combinedTokenCount,\n });\n\n // Reset lastBufferedBoundary so new reflection buffering can start fresh\n ObservationalMemory.lastBufferedBoundary.delete(bufferKey);\n\n // Emit activation marker using the original buffering cycleId so the UI can match it\n const afterRecord = await this.storage.getObservationalMemory(record.threadId, record.resourceId);\n const afterTokens = afterRecord?.observationTokenCount ?? 0;\n omDebug(\n `[OM:reflect] tryActivateBufferedReflection: activation complete! beforeTokens=${beforeTokens}, afterTokens=${afterTokens}, newRecordId=${afterRecord?.id}, newGenCount=${afterRecord?.generationCount}`,\n );\n\n if (writer) {\n const originalCycleId = ObservationalMemory.reflectionBufferCycleIds.get(bufferKey);\n const activationMarker = this.createActivationMarker({\n cycleId: originalCycleId ?? `reflect-act-${Date.now()}-${Math.random().toString(36).slice(2, 11)}`,\n operationType: 'reflection',\n chunksActivated: 1,\n tokensActivated: beforeTokens,\n observationTokens: afterTokens,\n messagesActivated: 0,\n recordId: freshRecord.id,\n threadId: freshRecord.threadId ?? '',\n generationCount: afterRecord?.generationCount ?? freshRecord.generationCount ?? 0,\n observations: afterRecord?.activeObservations,\n });\n void writer.custom(activationMarker).catch(() => {});\n await this.persistMarkerToMessage(\n activationMarker,\n messageList,\n freshRecord.threadId ?? '',\n freshRecord.resourceId ?? undefined,\n );\n }\n\n // Clean up the stored cycleId\n ObservationalMemory.reflectionBufferCycleIds.delete(bufferKey);\n\n return true;\n }\n\n /**\n * Resource-scoped observation: observe ALL threads with unobserved messages.\n * Threads are observed in oldest-first order to ensure no thread's messages\n * get \"stuck\" unobserved forever.\n *\n * Key differences from thread-scoped observation:\n * 1. Loads messages from ALL threads for the resource\n * 2. Observes threads one-by-one in oldest-first order\n * 3. Only updates lastObservedAt AFTER all threads are observed\n * 4. Only triggers reflection AFTER all threads are observed\n */\n private async doResourceScopedObservation(opts: {\n record: ObservationalMemoryRecord;\n currentThreadId: string;\n resourceId: string;\n currentThreadMessages: MastraDBMessage[];\n writer?: ProcessorStreamWriter;\n abortSignal?: AbortSignal;\n reflectionHooks?: Pick<ObserveHooks, 'onReflectionStart' | 'onReflectionEnd'>;\n requestContext?: RequestContext;\n }): Promise<void> {\n const {\n record,\n currentThreadId,\n resourceId,\n currentThreadMessages,\n writer,\n abortSignal,\n reflectionHooks,\n requestContext,\n } = opts;\n // Clear debug entries at start of observation cycle\n\n // ════════════════════════════════════════════════════════════\n // PER-THREAD CURSORS: Load unobserved messages for each thread using its own lastObservedAt\n // This prevents message loss when threads have different observation progress\n // ════════════════════════════════════════════════════════════\n\n // First, get all threads for this resource to access their per-thread lastObservedAt\n const { threads: allThreads } = await this.storage.listThreads({ filter: { resourceId } });\n const threadMetadataMap = new Map<string, { lastObservedAt?: string }>();\n\n for (const thread of allThreads) {\n const omMetadata = getThreadOMMetadata(thread.metadata);\n threadMetadataMap.set(thread.id, { lastObservedAt: omMetadata?.lastObservedAt });\n }\n\n // Load messages per-thread using each thread's own cursor\n const messagesByThread = new Map<string, MastraDBMessage[]>();\n\n for (const thread of allThreads) {\n const threadLastObservedAt = threadMetadataMap.get(thread.id)?.lastObservedAt;\n\n // Query messages for this specific thread AFTER its lastObservedAt\n // Add 1ms to make the filter exclusive (since dateRange.start is inclusive)\n // This prevents re-observing the same messages\n const startDate = threadLastObservedAt ? new Date(new Date(threadLastObservedAt).getTime() + 1) : undefined;\n\n const result = await this.storage.listMessages({\n threadId: thread.id,\n perPage: false,\n orderBy: { field: 'createdAt', direction: 'ASC' },\n filter: startDate ? { dateRange: { start: startDate } } : undefined,\n });\n\n if (result.messages.length > 0) {\n messagesByThread.set(thread.id, result.messages);\n }\n }\n\n // Handle current thread messages (may not be in DB yet)\n // Merge with any DB messages for the current thread\n if (currentThreadMessages.length > 0) {\n const existingCurrentThreadMsgs = messagesByThread.get(currentThreadId) ?? [];\n const messageMap = new Map<string, MastraDBMessage>();\n\n // Add DB messages first\n for (const msg of existingCurrentThreadMsgs) {\n if (msg.id) messageMap.set(msg.id, msg);\n }\n\n // Add/override with current thread messages (they're more up-to-date)\n for (const msg of currentThreadMessages) {\n if (msg.id) messageMap.set(msg.id, msg);\n }\n\n messagesByThread.set(currentThreadId, Array.from(messageMap.values()));\n }\n\n // Filter out messages already observed in this instance's lifetime.\n // This can happen when doResourceScopedObservation re-queries the DB using per-thread\n // lastObservedAt cursors that haven't fully advanced past messages observed in a prior cycle.\n for (const [tid, msgs] of messagesByThread) {\n const filtered = msgs.filter(m => !this.observedMessageIds.has(m.id));\n if (filtered.length > 0) {\n messagesByThread.set(tid, filtered);\n } else {\n messagesByThread.delete(tid);\n }\n }\n // Count total messages\n let totalMessages = 0;\n for (const msgs of messagesByThread.values()) {\n totalMessages += msgs.length;\n }\n\n if (totalMessages === 0) {\n return;\n }\n\n // ════════════════════════════════════════════════════════════\n // THREAD SELECTION: Pick which threads to observe based on token threshold\n // - Sort by largest threads first (most messages = most value per Observer call)\n // - Accumulate until we hit the threshold\n // - This prevents making many small Observer calls for 1-message threads\n // ════════════════════════════════════════════════════════════\n const threshold = this.getMaxThreshold(this.observationConfig.messageTokens);\n\n // Calculate tokens per thread and sort by size (largest first)\n const threadTokenCounts = new Map<string, number>();\n for (const [threadId, msgs] of messagesByThread) {\n let tokens = 0;\n for (const msg of msgs) {\n tokens += this.tokenCounter.countMessage(msg);\n }\n threadTokenCounts.set(threadId, tokens);\n }\n\n const threadsBySize = Array.from(messagesByThread.keys()).sort((a, b) => {\n return (threadTokenCounts.get(b) ?? 0) - (threadTokenCounts.get(a) ?? 0);\n });\n\n // Select threads to observe until we hit the threshold\n let accumulatedTokens = 0;\n const threadsToObserve: string[] = [];\n\n for (const threadId of threadsBySize) {\n const threadTokens = threadTokenCounts.get(threadId) ?? 0;\n\n // If we've already accumulated enough, stop adding threads\n if (accumulatedTokens >= threshold) {\n break;\n }\n\n threadsToObserve.push(threadId);\n accumulatedTokens += threadTokens;\n }\n\n if (threadsToObserve.length === 0) {\n return;\n }\n\n // Now sort the selected threads by oldest message for consistent observation order\n const threadOrder = this.sortThreadsByOldestMessage(\n new Map(threadsToObserve.map(tid => [tid, messagesByThread.get(tid) ?? []])),\n );\n\n // Debug: Log message counts per thread and date ranges\n\n // ════════════════════════════════════════════════════════════\n // LOCKING: Acquire lock and re-check\n // Another request may have already observed while we were loading messages\n // ════════════════════════════════════════════════════════════\n await this.storage.setObservingFlag(record.id, true);\n registerOp(record.id, 'observing');\n\n // Generate unique cycle ID for this observation cycle\n // This ties together the start/end/failed markers across all threads\n const cycleId = crypto.randomUUID();\n\n // Declare variables outside try block so they're accessible in catch\n const threadsWithMessages = new Map<string, MastraDBMessage[]>();\n const threadTokensToObserve = new Map<string, number>();\n let observationStartedAt = '';\n\n try {\n // Re-check: reload record to see if another request already observed\n const freshRecord = await this.storage.getObservationalMemory(null, resourceId);\n if (freshRecord && freshRecord.lastObservedAt && record.lastObservedAt) {\n if (freshRecord.lastObservedAt > record.lastObservedAt) {\n return;\n }\n }\n\n const existingObservations = freshRecord?.activeObservations ?? record.activeObservations ?? '';\n\n // ═════════════════════════════════════════���══════════════════\n // BATCHED MULTI-THREAD OBSERVATION: Single Observer call for all threads\n // This is much more efficient than calling the Observer for each thread individually\n // ════════════════════════════════════════════════════════════\n\n // Filter to only threads with messages\n for (const threadId of threadOrder) {\n const msgs = messagesByThread.get(threadId);\n if (msgs && msgs.length > 0) {\n threadsWithMessages.set(threadId, msgs);\n }\n }\n\n // Emit debug event for observation triggered (combined for all threads)\n this.emitDebugEvent({\n type: 'observation_triggered',\n timestamp: new Date(),\n threadId: threadOrder.join(','),\n resourceId,\n previousObservations: existingObservations,\n messages: Array.from(threadsWithMessages.values())\n .flat()\n .map(m => ({\n role: m.role,\n content: typeof m.content === 'string' ? m.content : JSON.stringify(m.content),\n })),\n });\n\n // ════════════════════════════════════════════════════════════════════════\n // INSERT START MARKERS before observation\n // Each thread gets its own start marker in its last message\n // ════════════════════════════════════════════════════════════════════════\n observationStartedAt = new Date().toISOString();\n const allThreadIds = Array.from(threadsWithMessages.keys());\n\n for (const [threadId, msgs] of threadsWithMessages) {\n const lastMessage = msgs[msgs.length - 1];\n const tokensToObserve = this.tokenCounter.countMessages(msgs);\n threadTokensToObserve.set(threadId, tokensToObserve);\n\n if (lastMessage?.id) {\n const startMarker = this.createObservationStartMarker({\n cycleId,\n operationType: 'observation',\n tokensToObserve,\n recordId: record.id,\n threadId,\n threadIds: allThreadIds,\n });\n // Stream the start marker to the UI first - this adds the part via stream handler\n if (writer) {\n await writer.custom(startMarker).catch(() => {\n // Ignore errors from streaming - observation should continue\n });\n }\n\n // Then add to message (skipPush since writer.custom already added the part)\n }\n }\n\n // ════════════════════════════════════════════════════════════\n // PARALLEL BATCHING: Chunk threads into batches and process in parallel\n // This combines batching efficiency with parallel execution\n // ════��═══════════════════════════════════════════════════════\n const maxTokensPerBatch =\n this.observationConfig.maxTokensPerBatch ?? OBSERVATIONAL_MEMORY_DEFAULTS.observation.maxTokensPerBatch;\n const orderedThreadIds = threadOrder.filter(tid => threadsWithMessages.has(tid));\n\n // Chunk threads into batches based on token count\n const batches: Array<{ threadIds: string[]; threadMap: Map<string, MastraDBMessage[]> }> = [];\n let currentBatch: { threadIds: string[]; threadMap: Map<string, MastraDBMessage[]> } = {\n threadIds: [],\n threadMap: new Map(),\n };\n let currentBatchTokens = 0;\n\n for (const threadId of orderedThreadIds) {\n const msgs = threadsWithMessages.get(threadId)!;\n const threadTokens = threadTokenCounts.get(threadId) ?? 0;\n\n // If adding this thread would exceed the batch limit, start a new batch\n // (unless the current batch is empty - always include at least one thread)\n if (currentBatchTokens + threadTokens > maxTokensPerBatch && currentBatch.threadIds.length > 0) {\n batches.push(currentBatch);\n currentBatch = { threadIds: [], threadMap: new Map() };\n currentBatchTokens = 0;\n }\n\n currentBatch.threadIds.push(threadId);\n currentBatch.threadMap.set(threadId, msgs);\n currentBatchTokens += threadTokens;\n }\n\n // Don't forget the last batch\n if (currentBatch.threadIds.length > 0) {\n batches.push(currentBatch);\n }\n\n // Process batches in parallel\n const batchPromises = batches.map(async batch => {\n const batchResult = await this.callMultiThreadObserver(\n existingObservations,\n batch.threadMap,\n batch.threadIds,\n abortSignal,\n requestContext,\n );\n return batchResult;\n });\n\n const batchResults = await Promise.all(batchPromises);\n\n // Merge all batch results into a single map and accumulate usage\n const multiThreadResults = new Map<\n string,\n {\n observations: string;\n currentTask?: string;\n suggestedContinuation?: string;\n }\n >();\n let totalBatchUsage = { inputTokens: 0, outputTokens: 0, totalTokens: 0 };\n for (const batchResult of batchResults) {\n for (const [threadId, result] of batchResult.results) {\n multiThreadResults.set(threadId, result);\n }\n // Accumulate usage from each batch\n if (batchResult.usage) {\n totalBatchUsage.inputTokens += batchResult.usage.inputTokens ?? 0;\n totalBatchUsage.outputTokens += batchResult.usage.outputTokens ?? 0;\n totalBatchUsage.totalTokens += batchResult.usage.totalTokens ?? 0;\n }\n }\n\n // Convert to the expected format for downstream processing\n const observationResults: Array<{\n threadId: string;\n threadMessages: MastraDBMessage[];\n result: {\n observations: string;\n currentTask?: string;\n suggestedContinuation?: string;\n };\n } | null> = [];\n\n for (const threadId of threadOrder) {\n const threadMessages = messagesByThread.get(threadId) ?? [];\n if (threadMessages.length === 0) continue;\n\n const result = multiThreadResults.get(threadId);\n if (!result) {\n continue;\n }\n\n // Debug: Log Observer output for this thread\n\n observationResults.push({\n threadId,\n threadMessages,\n result,\n });\n }\n\n // Combine results: wrap each thread's observations and append to existing\n let currentObservations = existingObservations;\n let cycleObservationTokens = 0; // Track total new observation tokens generated in this cycle\n\n for (const obsResult of observationResults) {\n if (!obsResult) continue;\n\n const { threadId, threadMessages, result } = obsResult;\n\n // Track tokens generated for this thread\n cycleObservationTokens += this.tokenCounter.countObservations(result.observations);\n\n // Wrap with thread tag and append (in thread order for consistency)\n const threadSection = await this.wrapWithThreadTag(threadId, result.observations);\n currentObservations = this.replaceOrAppendThreadSection(currentObservations, threadId, threadSection);\n\n // Update thread-specific metadata:\n // - lastObservedAt: ALWAYS update to track per-thread observation progress\n // - currentTask, suggestedResponse: only if present in result\n const threadLastObservedAt = this.getMaxMessageTimestamp(threadMessages);\n const thread = await this.storage.getThreadById({ threadId });\n if (thread) {\n const newMetadata = setThreadOMMetadata(thread.metadata, {\n lastObservedAt: threadLastObservedAt.toISOString(),\n ...(result.suggestedContinuation && { suggestedResponse: result.suggestedContinuation }),\n ...(result.currentTask && { currentTask: result.currentTask }),\n });\n await this.storage.updateThread({\n id: threadId,\n title: thread.title ?? '',\n metadata: newMetadata,\n });\n }\n\n // Emit debug event for observation complete (usage is for the entire batch, added to first thread only)\n const isFirstThread = observationResults.indexOf(obsResult) === 0;\n this.emitDebugEvent({\n type: 'observation_complete',\n timestamp: new Date(),\n threadId,\n resourceId,\n observations: threadSection,\n rawObserverOutput: result.observations,\n previousObservations: record.activeObservations,\n messages: threadMessages.map(m => ({\n role: m.role,\n content: typeof m.content === 'string' ? m.content : JSON.stringify(m.content),\n })),\n // Add batch usage to first thread's event only (to avoid double-counting)\n usage: isFirstThread && totalBatchUsage.totalTokens > 0 ? totalBatchUsage : undefined,\n });\n }\n\n // After ALL threads observed, update the record with final observations\n let totalTokenCount = this.tokenCounter.countObservations(currentObservations);\n\n // Compute global lastObservedAt as a \"high water mark\" across all threads\n // Note: Per-thread cursors (stored in ThreadOMMetadata.lastObservedAt) are the authoritative source\n // for determining which messages each thread has observed. This global value is used for:\n // - Quick concurrency checks (has any observation happened since we started?)\n // - Thread-scoped observation (non-resource scope)\n const observedMessages = observationResults\n .filter((r): r is NonNullable<typeof r> => r !== null)\n .flatMap(r => r.threadMessages);\n const lastObservedAt = this.getMaxMessageTimestamp(observedMessages);\n\n // Collect message IDs being observed for the safeguard\n const newMessageIds = observedMessages.map(m => m.id);\n const existingIds = record.observedMessageIds ?? [];\n const allObservedIds = [...new Set([...existingIds, ...newMessageIds])];\n\n await this.storage.updateActiveObservations({\n id: record.id,\n observations: currentObservations,\n tokenCount: totalTokenCount,\n lastObservedAt,\n observedMessageIds: allObservedIds,\n });\n\n // ════════════════════════════════════════════════════════════════════════\n // INSERT END MARKERS into each thread's last message\n // This completes the observation boundary (start markers were inserted above)\n // ════════════════════════════════════════════════════════════════════════\n for (const obsResult of observationResults) {\n if (!obsResult) continue;\n const { threadId, threadMessages, result } = obsResult;\n const lastMessage = threadMessages[threadMessages.length - 1];\n if (lastMessage?.id) {\n const tokensObserved = threadTokensToObserve.get(threadId) ?? this.tokenCounter.countMessages(threadMessages);\n const endMarker = this.createObservationEndMarker({\n cycleId,\n operationType: 'observation',\n startedAt: observationStartedAt,\n tokensObserved,\n observationTokens: cycleObservationTokens,\n observations: result.observations,\n currentTask: result.currentTask,\n suggestedResponse: result.suggestedContinuation,\n recordId: record.id,\n threadId,\n });\n\n // Stream the end marker to the UI first - this adds the part via stream handler\n if (writer) {\n await writer.custom(endMarker).catch(() => {\n // Ignore errors from streaming - observation should continue\n });\n }\n\n // Then seal the message (skipPush since writer.custom already added the part)\n }\n }\n\n // Check for reflection AFTER all threads are observed\n await this.maybeReflect({\n record: { ...record, activeObservations: currentObservations },\n observationTokens: totalTokenCount,\n threadId: currentThreadId,\n writer,\n abortSignal,\n reflectionHooks,\n requestContext,\n });\n } catch (error) {\n // Insert FAILED markers into each thread's last message on error\n for (const [threadId, msgs] of threadsWithMessages) {\n const lastMessage = msgs[msgs.length - 1];\n if (lastMessage?.id) {\n const tokensAttempted = threadTokensToObserve.get(threadId) ?? 0;\n const failedMarker = this.createObservationFailedMarker({\n cycleId,\n operationType: 'observation',\n startedAt: observationStartedAt,\n tokensAttempted,\n error: error instanceof Error ? error.message : String(error),\n recordId: record.id,\n threadId,\n });\n\n // Stream the failed marker to the UI first - this adds the part via stream handler\n if (writer) {\n await writer.custom(failedMarker).catch(() => {\n // Ignore errors from streaming - observation should continue\n });\n }\n\n // Then seal the message (skipPush since writer.custom already added the part)\n }\n }\n // If aborted, re-throw so the main agent loop can handle cancellation\n if (abortSignal?.aborted) {\n throw error;\n }\n // Log the error but don't re-throw - observation failure should not crash the agent\n omError('[OM] Resource-scoped observation failed', error);\n } finally {\n await this.storage.setObservingFlag(record.id, false);\n unregisterOp(record.id, 'observing');\n }\n }\n\n /**\n * Check if async reflection should be triggered or activated.\n * Only handles the async path — will never do synchronous (blocking) reflection.\n * Safe to call after buffered observation activation.\n */\n private async maybeAsyncReflect(\n record: ObservationalMemoryRecord,\n observationTokens: number,\n writer?: ProcessorStreamWriter,\n messageList?: MessageList,\n requestContext?: RequestContext,\n ): Promise<void> {\n if (!this.isAsyncReflectionEnabled()) return;\n\n const lockKey = this.getLockKey(record.threadId, record.resourceId);\n const reflectThreshold = this.getMaxThreshold(this.reflectionConfig.observationTokens);\n\n omDebug(\n `[OM:reflect] maybeAsyncReflect: observationTokens=${observationTokens}, reflectThreshold=${reflectThreshold}, isReflecting=${record.isReflecting}, bufferedReflection=${record.bufferedReflection ? 'present (' + record.bufferedReflection.length + ' chars)' : 'empty'}, recordId=${record.id}, genCount=${record.generationCount}`,\n );\n\n // Below threshold: trigger background buffering if at the right interval\n if (observationTokens < reflectThreshold) {\n const shouldTrigger = this.shouldTriggerAsyncReflection(observationTokens, lockKey, record);\n omDebug(`[OM:reflect] below threshold: shouldTrigger=${shouldTrigger}`);\n if (shouldTrigger) {\n this.startAsyncBufferedReflection(record, observationTokens, lockKey, writer, requestContext);\n }\n return;\n }\n\n // At/above threshold: try to activate buffered reflection\n if (record.isReflecting) {\n if (isOpActiveInProcess(record.id, 'reflecting')) {\n omDebug(`[OM:reflect] skipping - actively reflecting in this process`);\n return;\n }\n omDebug(`[OM:reflect] isReflecting=true but stale (not active in this process), clearing`);\n await this.storage.setReflectingFlag(record.id, false);\n }\n\n omDebug(`[OM:reflect] at/above threshold, trying activation...`);\n const activationSuccess = await this.tryActivateBufferedReflection(record, lockKey, writer, messageList);\n omDebug(`[OM:reflect] activationSuccess=${activationSuccess}`);\n if (activationSuccess) return;\n\n // No buffered reflection available — start one now in the background.\n // This can happen when observations jump past the threshold via activation\n // without any background reflection having been triggered beforehand.\n omDebug(`[OM:reflect] no buffered reflection, starting background reflection...`);\n this.startAsyncBufferedReflection(record, observationTokens, lockKey, writer, requestContext);\n }\n\n /**\n * Check if reflection needed and trigger if so.\n * Supports both synchronous reflection and async buffered reflection.\n * When async buffering is enabled via `bufferTokens`, reflection is triggered\n * in the background at intervals, and activated when the threshold is reached.\n */\n private async maybeReflect(opts: {\n record: ObservationalMemoryRecord;\n observationTokens: number;\n threadId?: string;\n writer?: ProcessorStreamWriter;\n abortSignal?: AbortSignal;\n messageList?: MessageList;\n reflectionHooks?: Pick<ObserveHooks, 'onReflectionStart' | 'onReflectionEnd'>;\n requestContext?: RequestContext;\n }): Promise<void> {\n const { record, observationTokens, writer, abortSignal, messageList, reflectionHooks, requestContext } = opts;\n const lockKey = this.getLockKey(record.threadId, record.resourceId);\n const reflectThreshold = this.getMaxThreshold(this.reflectionConfig.observationTokens);\n\n // ════════════════════════════════════════════════════════════════════════\n // ASYNC BUFFERING: Trigger background reflection at bufferActivation ratio\n // This runs in the background and stores results to bufferedReflection.\n // ════════════════════════════════════════════════════════════════════════\n if (this.isAsyncReflectionEnabled() && observationTokens < reflectThreshold) {\n // Check if we've crossed the bufferActivation threshold\n if (this.shouldTriggerAsyncReflection(observationTokens, lockKey, record)) {\n // Start background reflection (fire-and-forget)\n this.startAsyncBufferedReflection(record, observationTokens, lockKey, writer, requestContext);\n }\n }\n\n // Check if we've reached the reflection threshold\n if (!this.shouldReflect(observationTokens)) {\n return;\n }\n\n // ═══════════════════════════════════════════════════════════\n // LOCKING: Check if reflection is already in progress\n // If the DB flag is set but this process isn't actively reflecting,\n // the flag is stale (from a crashed process) — clear it and proceed.\n // ════════════════════════════════════════════════════════════\n if (record.isReflecting) {\n if (isOpActiveInProcess(record.id, 'reflecting')) {\n omDebug(`[OM:reflect] isReflecting=true and active in this process, skipping`);\n return;\n }\n omDebug(`[OM:reflect] isReflecting=true but NOT active in this process — stale flag from dead process, clearing`);\n await this.storage.setReflectingFlag(record.id, false);\n }\n\n // ════════════════════════════════════════════════════════════════════════\n // ASYNC ACTIVATION: Try to activate buffered reflection first\n // If async buffering was enabled and we have buffered content, activate it.\n // This provides instant activation without blocking on new reflection.\n // ════════════════════════════════════════════════════════════════════════\n if (this.isAsyncReflectionEnabled()) {\n const activationSuccess = await this.tryActivateBufferedReflection(record, lockKey, writer, messageList);\n if (activationSuccess) {\n // Buffered reflection was activated - we're done\n return;\n }\n // No buffered content or activation failed.\n // When async is enabled, only fall through to sync if blockAfter is set and exceeded.\n if (this.reflectionConfig.blockAfter && observationTokens >= this.reflectionConfig.blockAfter) {\n omDebug(\n `[OM:reflect] blockAfter exceeded (${observationTokens} >= ${this.reflectionConfig.blockAfter}), falling through to sync reflection`,\n );\n } else {\n omDebug(\n `[OM:reflect] async activation failed, no blockAfter or below it (obsTokens=${observationTokens}, blockAfter=${this.reflectionConfig.blockAfter}) — starting background reflection`,\n );\n // Start background reflection so it's ready for next activation attempt\n this.startAsyncBufferedReflection(record, observationTokens, lockKey, writer, requestContext);\n return;\n }\n }\n\n // ════════════════════════════════════════════════════════════\n // SYNC PATH: Do synchronous reflection (blocking)\n // ════════════════════════════════════════════════════════════\n reflectionHooks?.onReflectionStart?.();\n await this.storage.setReflectingFlag(record.id, true);\n registerOp(record.id, 'reflecting');\n\n // Generate unique cycle ID for this reflection\n const cycleId = crypto.randomUUID();\n const startedAt = new Date().toISOString();\n const threadId = opts.threadId ?? 'unknown';\n\n // Stream START marker for reflection\n if (writer) {\n const startMarker = this.createObservationStartMarker({\n cycleId,\n operationType: 'reflection',\n tokensToObserve: observationTokens,\n recordId: record.id,\n threadId,\n threadIds: [threadId],\n });\n await writer.custom(startMarker).catch(() => {});\n }\n\n // Emit reflection_triggered debug event\n this.emitDebugEvent({\n type: 'reflection_triggered',\n timestamp: new Date(),\n threadId,\n resourceId: record.resourceId ?? '',\n inputTokens: observationTokens,\n activeObservationsLength: record.activeObservations?.length ?? 0,\n });\n\n // Create mutable stream context for retry tracking\n const streamContext = writer\n ? {\n writer,\n cycleId,\n startedAt,\n recordId: record.id,\n threadId,\n }\n : undefined;\n\n try {\n const reflectResult = await this.callReflector(\n record.activeObservations,\n undefined,\n streamContext,\n reflectThreshold,\n abortSignal,\n undefined,\n undefined,\n requestContext,\n );\n const reflectionTokenCount = this.tokenCounter.countObservations(reflectResult.observations);\n\n await this.storage.createReflectionGeneration({\n currentRecord: record,\n reflection: reflectResult.observations,\n tokenCount: reflectionTokenCount,\n });\n\n // Stream END marker for reflection (use streamContext values which may have been updated during retry)\n if (writer && streamContext) {\n const endMarker = this.createObservationEndMarker({\n cycleId: streamContext.cycleId,\n operationType: 'reflection',\n startedAt: streamContext.startedAt,\n tokensObserved: observationTokens,\n observationTokens: reflectionTokenCount,\n observations: reflectResult.observations,\n recordId: record.id,\n threadId,\n });\n await writer.custom(endMarker).catch(() => {});\n }\n\n // Emit reflection_complete debug event with usage\n this.emitDebugEvent({\n type: 'reflection_complete',\n timestamp: new Date(),\n threadId,\n resourceId: record.resourceId ?? '',\n inputTokens: observationTokens,\n outputTokens: reflectionTokenCount,\n observations: reflectResult.observations,\n usage: reflectResult.usage,\n });\n } catch (error) {\n // Stream FAILED marker for reflection (use streamContext values which may have been updated during retry)\n if (writer && streamContext) {\n const failedMarker = this.createObservationFailedMarker({\n cycleId: streamContext.cycleId,\n operationType: 'reflection',\n startedAt: streamContext.startedAt,\n tokensAttempted: observationTokens,\n error: error instanceof Error ? error.message : String(error),\n recordId: record.id,\n threadId,\n });\n await writer.custom(failedMarker).catch(() => {});\n }\n // If aborted, re-throw so the main agent loop can handle cancellation\n if (abortSignal?.aborted) {\n throw error;\n }\n // Log the error but don't re-throw - reflection failure should not crash the agent\n omError('[OM] Reflection failed', error);\n } finally {\n await this.storage.setReflectingFlag(record.id, false);\n reflectionHooks?.onReflectionEnd?.();\n unregisterOp(record.id, 'reflecting');\n }\n }\n\n /**\n * Manually trigger observation.\n *\n * When `messages` is provided, those are used directly (filtered for unobserved)\n * instead of reading from storage. This allows external systems (e.g., opencode)\n * to pass conversation messages without duplicating them into Mastra's DB.\n */\n async observe(opts: {\n threadId: string;\n resourceId?: string;\n messages?: MastraDBMessage[];\n hooks?: ObserveHooks;\n requestContext?: RequestContext;\n }): Promise<void> {\n const { threadId, resourceId, messages, hooks, requestContext } = opts;\n const lockKey = this.getLockKey(threadId, resourceId);\n const reflectionHooks = hooks\n ? { onReflectionStart: hooks.onReflectionStart, onReflectionEnd: hooks.onReflectionEnd }\n : undefined;\n\n await this.withLock(lockKey, async () => {\n // Re-fetch record inside lock to get latest state\n const freshRecord = await this.getOrCreateRecord(threadId, resourceId);\n\n if (this.scope === 'resource' && resourceId) {\n // Resource scope: check threshold before observing\n const currentMessages = messages ?? [];\n if (\n !this.meetsObservationThreshold({\n record: freshRecord,\n unobservedTokens: this.tokenCounter.countMessages(currentMessages),\n })\n ) {\n return;\n }\n\n hooks?.onObservationStart?.();\n try {\n await this.doResourceScopedObservation({\n record: freshRecord,\n currentThreadId: threadId,\n resourceId,\n currentThreadMessages: currentMessages,\n reflectionHooks,\n requestContext,\n });\n } finally {\n hooks?.onObservationEnd?.();\n }\n } else {\n // Thread scope: use provided messages or load from storage\n const unobservedMessages = messages\n ? this.getUnobservedMessages(messages, freshRecord)\n : await this.loadUnobservedMessages(\n threadId,\n resourceId,\n freshRecord.lastObservedAt ? new Date(freshRecord.lastObservedAt) : undefined,\n );\n\n if (unobservedMessages.length === 0) {\n return;\n }\n\n // Check token threshold before observing\n if (\n !this.meetsObservationThreshold({\n record: freshRecord,\n unobservedTokens: this.tokenCounter.countMessages(unobservedMessages),\n })\n ) {\n return;\n }\n\n hooks?.onObservationStart?.();\n try {\n await this.doSynchronousObservation({\n record: freshRecord,\n threadId,\n unobservedMessages,\n reflectionHooks,\n requestContext,\n });\n } finally {\n hooks?.onObservationEnd?.();\n }\n }\n });\n }\n\n /**\n * Manually trigger reflection with optional guidance prompt.\n *\n * @example\n * ```ts\n * // Trigger reflection with specific focus\n * await om.reflect(threadId, resourceId,\n * \"focus on the authentication implementation, only keep minimal details about UI styling\"\n * );\n * ```\n */\n async reflect(\n threadId: string,\n resourceId?: string,\n prompt?: string,\n requestContext?: RequestContext,\n ): Promise<void> {\n const record = await this.getOrCreateRecord(threadId, resourceId);\n\n if (!record.activeObservations) {\n return;\n }\n\n await this.storage.setReflectingFlag(record.id, true);\n registerOp(record.id, 'reflecting');\n\n try {\n const reflectThreshold = this.getMaxThreshold(this.reflectionConfig.observationTokens);\n const reflectResult = await this.callReflector(\n record.activeObservations,\n prompt,\n undefined,\n reflectThreshold,\n undefined,\n undefined,\n undefined,\n requestContext,\n );\n const reflectionTokenCount = this.tokenCounter.countObservations(reflectResult.observations);\n\n await this.storage.createReflectionGeneration({\n currentRecord: record,\n reflection: reflectResult.observations,\n tokenCount: reflectionTokenCount,\n });\n\n // Note: Thread metadata (currentTask, suggestedResponse) is preserved on each thread\n // and doesn't need to be updated during reflection - it was set during observation\n } finally {\n await this.storage.setReflectingFlag(record.id, false);\n unregisterOp(record.id, 'reflecting');\n }\n }\n\n /**\n * Get current observations for a thread/resource\n */\n async getObservations(threadId: string, resourceId?: string): Promise<string | undefined> {\n const ids = this.getStorageIds(threadId, resourceId);\n const record = await this.storage.getObservationalMemory(ids.threadId, ids.resourceId);\n return record?.activeObservations;\n }\n\n /**\n * Get current record for a thread/resource\n */\n async getRecord(threadId: string, resourceId?: string): Promise<ObservationalMemoryRecord | null> {\n const ids = this.getStorageIds(threadId, resourceId);\n return this.storage.getObservationalMemory(ids.threadId, ids.resourceId);\n }\n\n /**\n * Get observation history (previous generations)\n */\n async getHistory(threadId: string, resourceId?: string, limit?: number): Promise<ObservationalMemoryRecord[]> {\n const ids = this.getStorageIds(threadId, resourceId);\n return this.storage.getObservationalMemoryHistory(ids.threadId, ids.resourceId, limit);\n }\n\n /**\n * Clear all memory for a specific thread/resource\n */\n async clear(threadId: string, resourceId?: string): Promise<void> {\n const ids = this.getStorageIds(threadId, resourceId);\n await this.storage.clearObservationalMemory(ids.threadId, ids.resourceId);\n // Clean up static maps to prevent memory leaks\n this.cleanupStaticMaps(ids.threadId ?? ids.resourceId, ids.resourceId);\n }\n\n /**\n * Get the underlying storage adapter\n */\n getStorage(): MemoryStorage {\n return this.storage;\n }\n\n /**\n * Get the token counter\n */\n getTokenCounter(): TokenCounter {\n return this.tokenCounter;\n }\n\n /**\n * Get current observation configuration\n */\n getObservationConfig(): ResolvedObservationConfig {\n return this.observationConfig;\n }\n\n /**\n * Get current reflection configuration\n */\n getReflectionConfig(): ResolvedReflectionConfig {\n return this.reflectionConfig;\n }\n}\n"]}
|