| # Context Provision Analysis: Intent Agent Context Flow | |
| ## Problem Statement | |
| The Intent Recognition Agent (`src/agents/intent_agent.py`) expects a context dictionary with a `conversation_history` key, but the actual context structure provided by `EfficientContextManager` does not include this key. This results in `Available Context: []` being shown in the intent recognition prompt. | |
| ## Context Flow Trace | |
| ### Step 1: Orchestrator Retrieves Context | |
| **Location**: `src/orchestrator_engine.py:172` | |
| ```python | |
| context = await self._get_or_create_context(session_id, user_input, user_id) | |
| ``` | |
| This calls `context_manager.manage_context()` which returns a context dictionary. | |
| ### Step 2: Context Structure Returned by Context Manager | |
| **Location**: `src/context_manager.py:550-579` (`_optimize_context` method) | |
| The context manager returns the following structure: | |
| ```python | |
| { | |
| "session_id": str, | |
| "user_id": str, | |
| "user_context": str, # 500-token user persona summary | |
| "interaction_contexts": [ # List of interaction summary dicts | |
| { | |
| "summary": str, # 50-token interaction summary | |
| "timestamp": str | |
| }, | |
| ... | |
| ], | |
| "combined_context": str, # Formatted string: "[User Context]\n...\n[Interaction Context #N]\n..." | |
| "preferences": dict, | |
| "active_tasks": list, | |
| "last_activity": str | |
| } | |
| ``` | |
| ### Step 3: Intent Agent Receives Context | |
| **Location**: `src/orchestrator_engine.py:201-203` | |
| ```python | |
| intent_result = await self.agents['intent_recognition'].execute( | |
| user_input=user_input, | |
| context=context | |
| ) | |
| ``` | |
| ### Step 4: Intent Agent Attempts to Access Context | |
| **Location**: `src/agents/intent_agent.py:109` | |
| ```python | |
| def _build_chain_of_thought_prompt(self, user_input: str, context: Dict[str, Any]) -> str: | |
| return f""" | |
| Analyze the user's intent step by step: | |
| User Input: "{user_input}" | |
| Available Context: {context.get('conversation_history', [])[-2:] if context else []} | |
| ... | |
| """ | |
| ``` | |
| **Issue**: The code attempts to access `context.get('conversation_history', [])`, but the context dictionary **does not contain this key**. | |
| ## Root Cause Analysis | |
| ### Expected Context Structure (by Intent Agent) | |
| The intent agent expects: | |
| ```python | |
| context = { | |
| 'conversation_history': [ | |
| {...}, # Previous conversation turn | |
| {...}, # Another previous turn | |
| ... | |
| ] | |
| } | |
| ``` | |
| ### Actual Context Structure (from Context Manager) | |
| The context manager provides: | |
| ```python | |
| context = { | |
| 'interaction_contexts': [ | |
| {'summary': '...', 'timestamp': '...'}, | |
| {'summary': '...', 'timestamp': '...'}, | |
| ... | |
| ], | |
| 'user_context': '...', | |
| 'combined_context': '...', | |
| ... | |
| } | |
| ``` | |
| ### Why This Mismatch Exists | |
| 1. **Historical Evolution**: The intent agent was likely designed with an earlier context structure in mind | |
| 2. **Context Manager Redesign**: The context manager was redesigned to use hierarchical summarization (50/100/500 token tiers) instead of full conversation history | |
| 3. **Missing Adaptation**: The intent agent was not updated to use the new context structure | |
| ## Impact Analysis | |
| ### First Turn (No Previous Context) | |
| - `interaction_contexts` = `[]` (empty list) | |
| - `user_context` = `""` (empty string if first-time user) | |
| - **Result**: `Available Context: []` ✓ (Correct, but for wrong reason - key doesn't exist) | |
| ### Second Turn (After First Interaction) | |
| - `interaction_contexts` = `[{summary: "...", timestamp: "..."}]` (1 interaction) | |
| - `user_context` = `""` or persona summary if user has history | |
| - **Result**: `Available Context: []` ✗ (Incorrect - context exists but wrong key accessed) | |
| ### Third Turn and Beyond | |
| - `interaction_contexts` = `[{...}, {...}, ...]` (multiple interactions) | |
| - `user_context` = Persona summary (if user has sufficient history) | |
| - **Result**: `Available Context: []` ✗ (Incorrect - rich context exists but not accessible) | |
| ## Context Accumulation Over Multiple Turns | |
| ### Turn 1: User says "What is machine learning?" | |
| 1. Context Manager retrieves context: | |
| - `interaction_contexts`: `[]` (no previous interactions) | |
| - `user_context`: `""` (first-time user, no persona yet) | |
| - Context passed to intent agent | |
| 2. Intent Agent builds prompt: | |
| - `context.get('conversation_history', [])[-2:]` → `[]` | |
| - **Shows**: `Available Context: []` | |
| 3. After response, interaction context generated: | |
| - `generate_interaction_context()` called | |
| - Creates 50-token summary: "User asked about machine learning definition" | |
| - Stored in `interaction_contexts` table | |
| ### Turn 2: User says "How does it differ from deep learning?" | |
| 1. Context Manager retrieves context: | |
| - `interaction_contexts`: `[{summary: "User asked about machine learning definition", timestamp: "..."}]` | |
| - `user_context`: Still `""` (not enough history for persona) | |
| - Context passed to intent agent | |
| 2. Intent Agent builds prompt: | |
| - `context.get('conversation_history', [])[-2:]` → `[]` (key doesn't exist!) | |
| - **Shows**: `Available Context: []` ✗ **SHOULD show the interaction summary** | |
| 3. After response, another interaction context generated: | |
| - Creates: "User asked about differences between machine learning and deep learning" | |
| - Stored in `interaction_contexts` table | |
| - Now has 2 interaction contexts | |
| ### Turn 3: User says "Can you explain neural networks?" | |
| 1. Context Manager retrieves context: | |
| - `interaction_contexts`: `[{summary: "...deep learning..."}, {summary: "...machine learning..."}]` | |
| - `user_context`: Still `""` (persona generated only after sufficient history) | |
| - Context passed to intent agent | |
| 2. Intent Agent builds prompt: | |
| - `context.get('conversation_history', [])[-2:]` → `[]` (key doesn't exist!) | |
| - **Shows**: `Available Context: []` ✗ **SHOULD show 2 interaction summaries** | |
| ### After ~20-50 Interactions (User Persona Generation) | |
| 1. Context Manager retrieves context: | |
| - `interaction_contexts`: `[{...}, {...}, ...]` (up to 20 most recent) | |
| - `user_context`: `"User persona: Interested in AI topics, asks technical questions..."` (500-token summary) | |
| - Context passed to intent agent | |
| 2. Intent Agent builds prompt: | |
| - `context.get('conversation_history', [])[-2:]` → `[]` (key doesn't exist!) | |
| - **Shows**: `Available Context: []` ✗ **SHOULD show rich context including user persona and interaction history** | |
| ## Available Context Data (Not Being Used) | |
| ### What Context Actually Contains | |
| #### Turn 1: | |
| ```python | |
| context = { | |
| "interaction_contexts": [], # Empty - first turn | |
| "user_context": "", # Empty - first-time user | |
| "combined_context": "", # Empty | |
| } | |
| ``` | |
| #### Turn 2: | |
| ```python | |
| context = { | |
| "interaction_contexts": [ | |
| {"summary": "User asked about machine learning definition", "timestamp": "..."} | |
| ], | |
| "user_context": "", # Still empty | |
| "combined_context": "[Interaction Context #1]\nUser asked about machine learning definition", | |
| } | |
| ``` | |
| #### Turn 3+: | |
| ```python | |
| context = { | |
| "interaction_contexts": [ | |
| {"summary": "User asked about differences between ML and DL", "timestamp": "..."}, | |
| {"summary": "User asked about machine learning definition", "timestamp": "..."}, | |
| # ... more interactions | |
| ], | |
| "user_context": "User persona: Interested in AI topics...", # If sufficient history | |
| "combined_context": "[User Context]\nUser persona...\n\n[Interaction Context #2]\n...\n\n[Interaction Context #1]\n...", | |
| } | |
| ``` | |
| ## Recommended Solutions | |
| ### Option 1: Use `interaction_contexts` Directly (Minimal Change) | |
| **Modify**: `src/agents/intent_agent.py:109` | |
| ```python | |
| # OLD: | |
| Available Context: {context.get('conversation_history', [])[-2:] if context else []} | |
| # NEW: | |
| Available Context: {[ic.get('summary', '') for ic in context.get('interaction_contexts', [])[-2:]] if context else []} | |
| ``` | |
| **Pros**: | |
| - Minimal code change | |
| - Uses actual context data | |
| - Shows last 2 interaction summaries | |
| **Cons**: | |
| - Only shows summaries, not full conversation | |
| - Loses timestamp information | |
| ### Option 2: Use `combined_context` (Preferred) | |
| **Modify**: `src/agents/intent_agent.py:109` | |
| ```python | |
| # OLD: | |
| Available Context: {context.get('conversation_history', [])[-2:] if context else []} | |
| # NEW: | |
| Available Context: {context.get('combined_context', 'No previous context available') if context else 'No context available'} | |
| ``` | |
| **Pros**: | |
| - Uses pre-formatted context string | |
| - Includes both user context and interaction contexts | |
| - More informative for intent recognition | |
| - Better reflects the hierarchical context system | |
| **Cons**: | |
| - May include more than just last 2 turns (includes up to 10 interactions) | |
| - Longer context string | |
| ### Option 3: Build Conversation History from Interaction Contexts (Most Flexible) | |
| **Modify**: `src/agents/intent_agent.py:101-118` | |
| ```python | |
| def _build_chain_of_thought_prompt(self, user_input: str, context: Dict[str, Any]) -> str: | |
| """Build Chain of Thought prompt for intent recognition""" | |
| # Extract conversation history from interaction_contexts | |
| conversation_history = [] | |
| if context: | |
| interaction_contexts = context.get('interaction_contexts', []) | |
| # Get last 2 interaction summaries for context | |
| for ic in interaction_contexts[-2:]: | |
| conversation_history.append({ | |
| 'summary': ic.get('summary', ''), | |
| 'timestamp': ic.get('timestamp', '') | |
| }) | |
| # Optionally include user context | |
| user_context_summary = "" | |
| if context and context.get('user_context'): | |
| user_context_summary = f"\nUser Context: {context.get('user_context')[:200]}..." # Truncate for brevity | |
| return f""" | |
| Analyze the user's intent step by step: | |
| User Input: "{user_input}" | |
| Previous Context: {conversation_history if conversation_history else 'No previous interactions'} | |
| {user_context_summary} | |
| Step 1: Identify key entities, actions, and questions in the input | |
| Step 2: Map to intent categories: {', '.join(self.intent_categories)} | |
| Step 3: Consider the conversation flow and user's likely goals | |
| Step 4: Assign confidence scores (0.0-1.0) for each relevant intent | |
| Step 5: Provide reasoning for the classification | |
| Respond with JSON format containing primary_intent, secondary_intents, confidence_scores, and reasoning_chain. | |
| """ | |
| ``` | |
| **Pros**: | |
| - Flexible format | |
| - Can include both interaction history and user context | |
| - Properly handles empty context | |
| - More informative for LLM | |
| **Cons**: | |
| - More code changes | |
| - Slightly more complex | |
| ## Current Behavior Summary | |
| | Turn | Interaction Contexts Available | User Context Available | Intent Agent Sees | | |
| |------|-------------------------------|----------------------|-------------------| | |
| | 1 | 0 | No | `[]` (empty) | | |
| | 2 | 1 | No | `[]` (empty) ✗ | | |
| | 3 | 2 | Possibly | `[]` (empty) ✗ | | |
| | 10+ | 10-20 | Yes (if sufficient history) | `[]` (empty) ✗ | | |
| **Key Issue**: Intent agent never sees the available context data because it looks for the wrong key (`conversation_history` instead of `interaction_contexts` or `combined_context`). | |
| ## Testing Recommendations | |
| 1. **Verify Context Structure**: Log the actual context dict passed to intent agent | |
| 2. **Test Multiple Turns**: Verify context accumulates correctly over multiple interactions | |
| 3. **Test Persona Generation**: Verify user_context appears after sufficient history | |
| 4. **Compare Intent Accuracy**: Measure if fixing context access improves intent recognition accuracy | |
| ## Implementation Priority | |
| **High Priority**: This bug prevents the intent agent from using available conversation context, which likely: | |
| - Reduces intent recognition accuracy for follow-up questions | |
| - Prevents context-aware intent classification | |
| - Wastes the hierarchical context summarization system | |
| **Recommended Fix**: Option 2 (Use `combined_context`) as it's the simplest and most comprehensive solution. | |