# Deep Think: Memory Upgrade — Context-Aware Memory Injection

**Topic**: `context_aware_injection`
**Cycle**: 2
**Model**: gemini-2.5-pro
**Generated**: 2026-02-26T17:35:32.353078+00:00
**Elapsed**: 63.9s
**Thinking tokens**: 16384

---

## Generated Prompt (Phase 1 — Gemini Flash)

AIVA's `memory-lancedb` plugin (`enhanced_index.ts`) currently injects memories into the agent's context during the `api.on("before_agent_start")` hook if `cfg.autoRecall` is enabled. The `hybridSearch` function retrieves `RECALL_CANDIDATE_COUNT` (8) memories based on a weighted combination of `vectorScore` (0.4), `bm25Score` (0.3), `recencyScore` (0.2), and `importanceScore` (0.1), filtered by `RECALL_MIN_SIMILARITY` (0.15). These candidates are then diversified using `applyMMR` with `MMR_LAMBDA` (0.7) to select up to `RECALL_INJECT_MAX` (6) memories. Finally, `ensureCategoryDiversity` attempts to ensure at least two categories are present. The selected memories are formatted via `formatRelevantMemoriesContext` and prepended to the prompt.

This mechanism, while effective for general recall, lacks sophisticated context-awareness, leading to several suboptimal outcomes:

1.  **Low Precision for Dynamic Contexts**: The current retrieval relies heavily on the `event.prompt` for query generation. It does not dynamically adapt to the evolving conversation topic, the user's current emotional state (if detectable), or the specific task context (e.g., coding, personal planning, business strategy). This can lead to a P90 retrieval precision for *truly relevant* memories dropping by as much as 20-30% in multi-turn, topic-shifting conversations compared to single-turn queries.

2.  **Suboptimal Injection Placement**: Memories are always `prependContext`. This "one-size-fits-all" placement can disrupt prompt flow, especially for short prompts where a long block of memories might push critical user instructions out of the LLM's initial attention window. For an average prompt length of 200 tokens, injecting 6 memories (average 50 tokens each) adds 300 tokens, significantly altering the effective prompt structure. We estimate a 10-15% increase in LLM hallucination or misinterpretation of initial instructions due to this fixed placement.

3.  **Inefficient Suppression of Irrelevant High-Scoring Memories**: A memory might score highly on `hybridSearch` due to keyword overlap or recency, but be entirely irrelevant to the *current nuance* of the conversation. The system lacks a mechanism to dynamically re-rank or suppress such memories based on a deeper understanding of the conversation's intent, leading to up to 15% of injected memories being "noise" rather than signal, consuming valuable context window tokens.

4.  **Lack of Real-time User State Integration**: The system does not integrate real-time user state signals (e.g., explicit user mood, detected task intent from recent turns, current time of day/week) into the memory selection or ranking process. This limits personalization and could lead to injecting business-related memories during a personal chat, or vice-versa, decreasing user satisfaction by an estimated 5-10%.

Propose a **Context-Aware Memory Injection Layer** that addresses these issues.

**Specific Proposals Required:**

1.  **Dynamic Conversation Topic Modeling & Intent Detection**:
    *   **Proposal**: Implement a lightweight, real-time topic modeling and intent detection mechanism on the recent conversation history (e.g., last 3-5 user turns). This could involve an auxiliary embedding call or a keyword/phrase extraction heuristic.
    *   **Algorithmic Sketch**: Provide pseudocode or a TypeScript function signature for `getCurrentConversationContext(messages: Message[]): { topicVector: number[], keywords: string[], intent: string }`.
    *   **Integration**: How would this `topicVector` or `keywords` be combined with the existing `event.prompt` to form a more robust query for `db.hybridSearch`? Propose an updated `HYBRID_WEIGHTS` or a new "contextual relevance" score component.
    *   **Measurable Target**: Aim to improve the precision of *topic-aligned* memory recall by 15% (e.g., measured by human evaluation or LLM-based relevance scoring against detected topic).

2.  **Relevance Re-ranking and Suppression based on Intent/Topic**:
    *   **Proposal**: Introduce a post-retrieval re-ranking step that leverages the detected conversation context (topic, intent) to filter or re-order `candidates` before `applyMMR`. This should include a dynamic suppression mechanism.
    *   **Algorithmic Sketch**: Design a `reRankAndSuppress(candidates: HybridSearchResult[], conversationContext: ConversationContext): HybridSearchResult[]` function. This could involve:
        *   Semantic similarity check between `candidate.entry.vector` and `conversationContext.topicVector`.
        *   Keyword overlap check between `candidate.entry.text` and `conversationContext.keywords`.
        *   A rule-based or small LLM-based filter to suppress memories that strongly contradict `conversationContext.intent` (e.g., if intent is "personal chat", suppress high-scoring "business goal" memories).
    *   **Quantitative Threshold**: Define a `SUPPRESSION_THRESHOLD_CONTEXT_MISMATCH` (e.g., 0.2) below which a memory's overall score is heavily penalized or it is removed.
    *   **Measurable Target**: Reduce the number of contextually irrelevant injected memories (false positives) by 25% while maintaining recall of truly relevant items.

3.  **Adaptive Injection Placement**:
    *   **Proposal**: Implement logic to determine optimal injection placement (`prependContext` vs. `appendContext` vs. in-line) based on the nature of the memories and the current prompt structure.
    *   **Algorithmic Sketch**: Suggest a `determineInjectionPlacement(prompt: string, memories: Array<{ category: MemoryCategory; text: string }>): "prepend" | "append" | { position: number, text: string }` function. Considerations:
        *   If `event.prompt` is short (<50 tokens) and contains an explicit question, prefer `appendContext` or in-line if possible.
        *   If memories are "facts" or "preferences" directly answering a prompt, consider in-line injection.
        *   If memories are "events" or "decisions" providing background, `prependContext` might still be suitable.
    *   **Measurable Target**: Improve agent response quality (e.g., measured by coherence, directness, and absence of redundant information) by 10% when evaluated against fixed `prependContext` in diverse conversation scenarios.

4.  **User State Integration for Personalization**:
    *   **Proposal**: Design a simple mechanism to incorporate user state (e.g., `user_mood: "happy" | "neutral" | "stressed"`, `task_domain: "coding" | "personal" | "business"`, `time_of_day: "morning" | "afternoon" | "evening"`). Assume these states are provided by a hypothetical `api.getUserState()` or inferred from prior messages.
    *   **Integration**: How would these states influence `hybridSearch` (e.g., temporary boost to `importanceScore` for memories related to `task_domain` or `user_mood`)?
    *   **TypeScript Sketch**: Extend `MemoryConfig` to allow defining `CATEGORY_BOOSTS_BY_STATE` or similar.
    *   **Measurable Target**: Increase user engagement/satisfaction by 5% in a simulated environment where user state varies, by ensuring memories are consistently aligned with the current user context.

Provide a complete implementation roadmap with TypeScript code snippets suitable for direct integration into the `enhanced_index.ts` / `enhanced_config.ts` files.

---

## Thinking Process (Phase 2 — Gemini Pro)

**Context-Aware Memory Injection Layer: My Proposed Solution**

Okay, here's my plan to tackle the memory injection issues in the AIVA plugin. I need to design a system that's smarter, more adaptable, and ultimately more effective. I'll focus on dynamic context, relevance filtering, injection flexibility, and user state integration. I'll provide a roadmap that directly addresses all the user's requirements.

First, I'm going to look at the overall structure of the solution. I'll break it down into four key areas, all of which will have corresponding proposals, algorithmic sketches, integration plans, and measurable targets. Finally, I will deliver a complete implementation roadmap, detailing the necessary changes to the `enhanced_index.ts` and `enhanced_config.ts` files with code snippets and explanations.

**1.  Dynamic Conversation Topic Modeling & Intent Detection**

*   **Proposal:** I'll use a hybrid approach to capture conversation context. An embedding model will generate a `topicVector` for the conversation's general focus. Simultaneously, a lightweight NLP library will extract keywords and infer the user's intent to avoid the performance costs of an LLM.
*   **Algorithmic Sketch (`getCurrentConversationContext`):**
    *   Input: `messages: Message[]`.
    *   Logic: Concatenate the last 5 messages, get an embedding, extract keywords. Infer intent using simple rule-based heuristics (question, personal reflection).
    *   Output: `{ topicVector, keywords, intent }`.
*   **Integration:**
    *   I'll form a blended query: a weighted average of the initial prompt embedding and the conversation topic vector. `QUERY_VECTOR_WEIGHTS = { prompt: 0.7, topic: 0.3 }`. The keywords can be used to boost BM25 search.
*   **Measurable Target:** Aim for a 15% improvement in precision.

**2.  Relevance Re-ranking and Suppression**

*   **Proposal:** We'll filter candidate memories *after* the initial retrieval. We'll use the topic vector from the context to eliminate irrelevant results.
*   **Algorithmic Sketch (`reRankAndSuppress`):**
    *   Input: `candidates: HybridSearchResult[], conversationContext: ConversationContext`.
    *   Logic: Compute a relevance score (cosine similarity) between each candidate's vector and the `topicVector`. Suppress memories with scores below `SUPPRESSION_THRESHOLD_CONTEXT_MISMATCH = 0.2`. Penalize instead of removing. Implement intent-based filters.
    *   Output: Re-ranked and filtered `HybridSearchResult[]`.
*   **Quantitative Threshold:** `SUPPRESSION_THRESHOLD_CONTEXT_MISMATCH = 0.2`.
*   **Measurable Target:** Reduce false positives by 25%.

**3.  Adaptive Injection Placement**

*   **Proposal:** I will improve the agent's behavior to offer more injection options. Assume the `api` can `prepend`, `append`, and `inject` context.
*   **Algorithmic Sketch (`determineInjectionPlacement`):**
    *   Input: `prompt: string, memories: FormattedMemory[]`.
    *   Logic: Use `if/else` rules:
        *   If the prompt is short and a question, append the memory.
        *   If it's a coding prompt, prepend.
        *   If memories relate to feelings, and the prompt is reflective, prepend.
        *   Default to prepend (safe fallback).
    *   In-line injection is more complex, so I'll stick to append/prepend for the main implementation.
*   **Measurable Target:** Improve quality by 10%.

**4.  User State Integration**

*   **Proposal:** We will personalize recall using user state information. Modify the candidate scores by boosting certain categories based on the user's current state.
*   **Integration:**
    *   Inside the main processing hook, access user state from the API. Apply score boosts using a configuration file.
    *   Define a new configuration with `CATEGORY_BOOSTS_BY_STATE`. Example: `{ task_domain: { coding: { 'code_snippet': 1.5, 'technical_concept': 1.3 } } }`.
*   **TypeScript Sketch:**
    *   In `enhanced_config.ts`, add the `CATEGORY_BOOSTS_BY_STATE` type.
    *   In `enhanced_index.ts`, get user state: `const userState = await api.getUserState();`.
    *   Create `applyStateBoosts(candidates, userState, config)` to modify `hybridScore` according to the boosts.
*   **Meas

---

## Deep Think Response

Of course. Here is a detailed proposal for a **Context-Aware Memory Injection Layer** for AIVA's `memory-lancedb` plugin, addressing the specified issues with concrete implementation details and TypeScript code snippets.

---

## Proposal: A Context-Aware Memory Injection Layer

This proposal outlines a new, multi-stage memory processing pipeline within the `before_agent_start` hook that replaces the current static retrieval and injection mechanism. The new pipeline will be:

**Current Pipeline:**
`Generate Query` -> `hybridSearch` -> `applyMMR` -> `ensureCategoryDiversity` -> `prependContext`

**Proposed Pipeline:**
1.  **Context Generation:** `getCurrentConversationContext`
2.  **Query Enhancement:** `createEnhancedQuery`
3.  **Initial Retrieval:** `hybridSearch`
4.  **Personalization Boost:** `applyStateBoosts` (integrates user state)
5.  **Relevance Re-ranking:** `reRankAndSuppress` (filters based on context)
6.  **Diversification:** `applyMMR` & `ensureCategoryDiversity`
7.  **Adaptive Placement:** `determineInjectionPlacement` & `injectContext`

This new layer will be implemented primarily in `enhanced_index.ts` with supporting configuration in `enhanced_config.ts`.

---

### 1. Dynamic Conversation Topic Modeling & Intent Detection

**Proposal:**
We will implement a lightweight `getCurrentConversationContext` function that runs before the memory search. It will analyze the last `CONVERSATION_HISTORY_WINDOW` (e.g., 5) messages to generate a composite `topicVector`, extract salient `keywords`, and infer a basic `intent`. The `topicVector` will be an average of the embeddings of recent messages and the current prompt, providing a smoothed representation of the conversation's semantic focus.

**Algorithmic Sketch & Implementation:**

```typescript
// In enhanced_config.ts
export const ENHANCED_MEMORY_CONFIG = {
  // ... existing config
  CONVERSATION_HISTORY_WINDOW: 5, // Number of recent messages to consider for context
  QUERY_VECTOR_WEIGHTS: {
    prompt: 0.6, // Weight for the current prompt's vector
    topic: 0.4,   // Weight for the historical context vector
  },
};

// In enhanced_index.ts (new helper function)
import { Message, AivaPluginAPI } from "aiva-sdk"; // Assuming SDK types

export interface ConversationContext {
  topicVector: number[];
  keywords: string[];
  intent: "question" | "task" | "reflection" | "unknown";
}

/**
 * Analyzes recent conversation history to generate a contextual summary.
 */
export async function getCurrentConversationContext(
  messages: Message[],
  currentPrompt: string,
  api: AivaPluginAPI
): Promise<ConversationContext> {
  const recentMessages = messages.slice(-cfg.CONVERSATION_HISTORY_WINDOW);
  const contextText = recentMessages.map(m => m.content).join("\n");
  const fullText = contextText + "\n" + currentPrompt;

  // 1. Generate Topic Vector
  const topicVector = await api.getEmbedding(fullText);

  // 2. Extract Keywords (heuristic)
  // A more robust solution could use a lightweight NLP library.
  const words = fullText.toLowerCase().match(/\b(\w{4,})\b/g) || [];
  const wordCounts = words.reduce((acc, word) => {
    acc[word] = (acc[word] || 0) + 1;
    return acc;
  }, {} as Record<string, number>);
  const keywords = Object.entries(wordCounts)
    .sort(([, a], [, b]) => b - a)
    .slice(0, 5) // Top 5 keywords
    .map(([word]) => word);

  // 3. Detect Intent (heuristic)
  let intent: ConversationContext["intent"] = "unknown";
  const lowerPrompt = currentPrompt.toLowerCase();
  if (lowerPrompt.match(/\b(how|what|why|when|who|where)\b/g) || lowerPrompt.endsWith('?')) {
    intent = "question";
  } else if (lowerPrompt.match(/\b(create|write|generate|code|plan|do)\b/g)) {
    intent = "task";
  } else if (lowerPrompt.match(/\b(i feel|i think|remember when|i'm wondering)\b/g)) {
    intent = "reflection";
  }

  return { topicVector, keywords, intent };
}
```

**Integration:**
The `topicVector` will be blended with the vector of the immediate `event.prompt` to create a more stable query. The `keywords` will be prepended to the text query for BM25.

```typescript
// In enhanced_index.ts (within the hook)
// Assume 'promptVector' is the embedding of 'event.prompt'
const blendedVector = promptVector.map((val, i) => 
  val * cfg.QUERY_VECTOR_WEIGHTS.prompt + conversationContext.topicVector[i] * cfg.QUERY_VECTOR_WEIGHTS.topic
);

const bm25Query = `${conversationContext.keywords.join(' ')} ${event.prompt}`;

// Use blendedVector and bm25Query in db.hybridSearch
const candidates = await db.hybridSearch(blendedVector, bm25Query, {
  // ... existing options
});
```

**Measurable Target**: Improve topic-aligned memory recall precision by 15%.

---

### 2. Relevance Re-ranking and Suppression based on Intent/Topic

**Proposal:**
After the initial `hybridSearch`, we will introduce a `reRankAndSuppress` step. This function will calculate a `contextRelevanceScore` for each candidate memory by comparing its vector to the `conversationContext.topicVector`. Memories with a score below a `SUPPRESSION_THRESHOLD_CONTEXT_MISMATCH` will be heavily penalized, effectively removing them from consideration unless they are extremely diverse. It will also apply rule-based penalties based on intent mismatch.

**Algorithmic Sketch & Implementation:**

```typescript
// In enhanced_config.ts
export const ENHANCED_MEMORY_CONFIG = {
  // ... existing config
  SUPPRESSION_THRESHOLD_CONTEXT_MISMATCH: 0.20, // Cosine similarity threshold
  INTENT_MISMATCH_PENALTY: 0.1, // Multiplier for scores of irrelevant memories
};

// In enhanced_index.ts (new helper function)

// Helper for cosine similarity
function cosineSimilarity(vecA: number[], vecB: number[]): number {
    const dotProduct = vecA.reduce((acc, val, i) => acc + val * vecB[i], 0);
    const magA = Math.sqrt(vecA.reduce((acc, val) => acc + val * val, 0));
    const magB = Math.sqrt(vecB.reduce((acc, val) => acc + val * val, 0));
    if (magA === 0 || magB === 0) return 0;
    return dotProduct / (magA * magB);
}

/**
 * Re-ranks and suppresses memories based on their relevance to the current conversation context.
 */
export function reRankAndSuppress(
  candidates: HybridSearchResult[],
  conversationContext: ConversationContext
): HybridSearchResult[] {
  return candidates.map(candidate => {
    const newCandidate = { ...candidate, entry: { ...candidate.entry } };

    // 1. Calculate Topic Similarity Score
    const topicSimilarity = cosineSimilarity(newCandidate.entry.vector, conversationContext.topicVector);

    // 2. Apply Suppression Threshold
    if (topicSimilarity < cfg.SUPPRESSION_THRESHOLD_CONTEXT_MISMATCH) {
      newCandidate.hybridScore *= cfg.INTENT_MISMATCH_PENALTY; // Heavy penalty
    } else {
      // Modulate score by relevance
      newCandidate.hybridScore *= (0.5 + topicSimilarity * 0.5); // Boost relevant, slightly penalize less relevant
    }

    // 3. Apply Rule-based Intent Filtering
    const { intent } = conversationContext;
    const { category } = newCandidate.entry;
    if (intent === 'task' && ['personal_feeling', 'dream'].includes(category)) {
        newCandidate.hybridScore *= cfg.INTENT_MISMATCH_PENALTY;
    }
    if (intent === 'reflection' && ['code_snippet', 'business_goal'].includes(category)) {
        newCandidate.hybridScore *= cfg.INTENT_MISMATCH_PENALTY;
    }

    return newCandidate;
  }).sort((a, b) => b.hybridScore - a.hybridScore); // Re-sort based on new scores
}
```

**Measurable Target**: Reduce contextually irrelevant injected memories by 25%.

---

### 3. Adaptive Injection Placement

**Proposal:**
We will introduce a `determineInjectionPlacement` function that analyzes the prompt's structure and the nature of the retrieved memories to decide the best injection strategy: `prepend`, `append`, or (for future extension) `inline`. This avoids disrupting short, direct questions and places context where it's most effective.

**Algorithmic Sketch & Implementation:**

```typescript
// In enhanced_config.ts
export const ENHANCED_MEMORY_CONFIG = {
  // ... existing config
  SHORT_PROMPT_THRESHOLD: 50, // in tokens/characters
};

// In enhanced_index.ts (new helper function)
type InjectionPlacement = "prepend" | "append"; // Inline is a future enhancement

/**
 * Determines the optimal placement for injecting memories into the context.
 */
export function determineInjectionPlacement(
  prompt: string,
  memories: FormattedMemory[] // Assuming a type for formatted memories
): InjectionPlacement {
  // Rule 1: Short, direct questions
  if (prompt.length < cfg.SHORT_PROMPT_THRESHOLD && prompt.trim().endsWith('?')) {
    // Appending context provides background after the core question is stated.
    return "append";
  }

  // Rule 2: Coding or technical tasks
  const isCodingPrompt = prompt.toLowerCase().match(/\b(code|javascript|python|function|class|error|debug)\b/);
  if (isCodingPrompt) {
      // Prepending context (e.g., previous snippets, preferences) is standard for coding.
      return "prepend";
  }
  
  // Default: Prepend context for general conversation and reflection.
  return "prepend";
}

// In the hook's final step:
const placement = determineInjectionPlacement(event.prompt, finalMemories);
const memoryContext = formatRelevantMemoriesContext(finalMemories);

if (placement === "append") {
    api.appendContext(memoryContext);
} else {
    api.prependContext(memoryContext);
}
```

**Measurable Target**: Improve agent response quality (coherence, directness) by 10%.

---

### 4. User State Integration for Personalization

**Proposal:**
We will define a configuration structure, `CATEGORY_BOOSTS_BY_STATE`, to map user states (like `task_domain`) to score multipliers for specific memory categories. An `applyStateBoosts` function will use this map to dynamically promote memories that align with the user's current detected state.

**Algorithmic Sketch & Implementation:**

```typescript
// In enhanced_config.ts
export type UserState = {
  task_domain?: "coding" | "personal" | "business" | "writing";
  user_mood?: "happy" | "neutral" | "stressed";
  // ... other states like time_of_day
};

export const ENHANCED_MEMORY_CONFIG = {
  // ... existing config
  CATEGORY_BOOSTS_BY_STATE: {
    task_domain: {
      coding: {
        code_snippet: 1.5,
        technical_concept: 1.3,
        api_key: 1.2,
      },
      personal: {
        personal_feeling: 1.4,
        life_event: 1.3,
        personal_preference: 1.2,
      },
      business: {
        business_goal: 1.5,
        meeting_note: 1.4,
        contact_info: 1.2,
      },
    },
  },
};

// In enhanced_index.ts (new helper function)
/**
 * Applies score boosts to candidates based on the current user state.
 */
export function applyStateBoosts(
  candidates: HybridSearchResult[],
  userState: UserState | null
): HybridSearchResult[] {
  if (!userState) return candidates;

  const boosts = cfg.CATEGORY_BOOSTS_BY_STATE;

  return candidates.map(candidate => {
    let boost = 1.0;
    const category = candidate.entry.category;

    if (userState.task_domain && boosts.task_domain[userState.task_domain]) {
        boost *= boosts.task_domain[userState.task_domain][category] || 1.0;
    }
    // Future: Add boosts for user_mood, etc.

    if (boost > 1.0) {
        return { ...candidate, hybridScore: candidate.hybridScore * boost };
    }
    return candidate;
  });
}
```

**Measurable Target**: Increase user engagement/satisfaction by 5% through better personalization.

---

### Complete Implementation Roadmap (`enhanced_index.ts`)

Here is how the main hook would be restructured to incorporate the new layer:

```typescript
// enhanced_index.ts

// ... imports and helper functions defined above ...

export default async function MemoryPlugin(api: AivaPluginAPI, cfg: EnhancedMemoryConfig) {
  // ... db initialization ...

  api.on("before_agent_start", async (event) => {
    if (!cfg.autoRecall || !db) return;

    try {
      // =================================================================
      // 1. CONTEXT GENERATION
      // =================================================================
      const history = await api.getMessages({ limit: cfg.CONVERSATION_HISTORY_WINDOW });
      const conversationContext = await getCurrentConversationContext(history, event.prompt, api);

      // =================================================================
      // 2. ENHANCED QUERY CREATION
      // =================================================================
      const promptVector = await api.getEmbedding(event.prompt);
      const blendedVector = promptVector.map((val, i) =>
        val * cfg.QUERY_VECTOR_WEIGHTS.prompt + conversationContext.topicVector[i] * cfg.QUERY_VECTOR_WEIGHTS.topic
      );
      const bm25Query = `${conversationContext.keywords.join(" ")} ${event.prompt}`;

      // =================================================================
      // 3. INITIAL RETRIEVAL
      // =================================================================
      let candidates = await db.hybridSearch(blendedVector, bm25Query, {
        limit: cfg.RECALL_CANDIDATE_COUNT,
        hybridWeights: cfg.HYBRID_WEIGHTS,
        filter: (r) => r.vectorScore > cfg.RECALL_MIN_SIMILARITY,
      });

      // =================================================================
      // 4. PERSONALIZATION BOOST (User State)
      // =================================================================
      const userState = await api.getUserState(); // Assume API provides this
      candidates = applyStateBoosts(candidates, userState);
      
      // =================================================================
      // 5. RELEVANCE RE-RANKING & SUPPRESSION
      // =================================================================
      candidates = reRankAndSuppress(candidates, conversationContext);

      // =================================================================
      // 6. DIVERSIFICATION
      // =================================================================
      let selectedMemories = await applyMMR(candidates, {
          limit: cfg.RECALL_INJECT_MAX,
          lambda: cfg.MMR_LAMBDA,
      });
      selectedMemories = ensureCategoryDiversity(selectedMemories, { minCategories: 2 });

      if (selectedMemories.length === 0) return;

      const formattedMemories = selectedMemories.map(m => m.entry); // Assuming applyMMR returns full entry

      // =================================================================
      // 7. ADAPTIVE PLACEMENT
      // =================================================================
      const placement = determineInjectionPlacement(event.prompt, formattedMemories);
      const memoryContext = formatRelevantMemoriesContext(formattedMemories);

      api.log.info(`Injecting ${formattedMemories.length} memories with placement: ${placement}`);

      if (placement === "append") {
        api.appendContext(memoryContext);
      } else { // Default to prepend
        api.prependContext(memoryContext);
      }

    } catch (error) {
      api.log.error("Error during context-aware memory recall:", error);
    }
  });
}
```
