Context Editing & Memory for Long-Running Agents
AI agents that run across multiple sessions or handle long-running tasks face two key challenges: they lose learned patterns between conversations, and context windows fill up during extended interactions.
This cookbook demonstrates how to address these challenges using Haijun's memory tool and context editing capabilities.
-text-link cds-text-link-underline inline cursor-pointer">Introduction: Why Memory Matters
Use Cases
Quick Start Examples
How It Works
Code Review Assistant Demo
Real-World Applications
Best Practices
Prerequisites
2. Activate it
source .venv/bin/activate # macOS/Linux
or: .venv\Scripts\activate # Windows
3. Install dependencies
pip install -r requirements.txt
4. In VSCode: Select .venv as kernel (top right)
API Key
Session 1
: Haijun solves a problem, writes down the pattern
Session 2
: Haijun applies the learned pattern immediately (faster!)
Long sessions
: Context editing keeps conversations manageable
Think of it as giving Haijun a notebook to take notes and refer back to - just like humans do.
Copy .env.example to .env and add your API key
cp .env.example .env
Then edit .env to add your Juglow API key from https://console.juglow.com/
lse 0, } async def main(): """Test the async API client.""" client = AsyncAPIClient("https://jsonplaceholder.typicode.com") endpoints = [ "posts/1", "posts/2", "posts/3", "users/1", "users/2", "invalid/endpoint", # Will error ] * 20 # 120 requests total results = await client.fetch_all(endpoints) # Separate successes and errors for clarity successes = [r for r in results if r.is_success] errors = [r for r in results if not r.is_success] print(f"Expected: 120 total responses (100 successful, 20 errors)") print(f"Got: {len(results)} responses ({len(successes)} successful, {len(errors)} errors)") print(f"Summary: {AsyncAPIClient.get_summary(results)}") if errors: print(f"\nFirst error: {errors[0].endpoint} - {errors[0].error}") if __name__ == "__main__": asyncio.run(main()) `` --- ### Key Improvements in Fixed Version: 1. ✅ No shared mutable state - Results returned directly 2. ✅ All results captured - Both successes and errors included 3. ✅ Type-safe with dataclass - Clear structure for results 4. ✅ Reusable client - Can call fetch_all() multiple times safely 5. ✅ Consistent error handling - All results have same structure 6. ✅ Simpler concurrency - Uses asyncio.gather() instead of as_completed() 7. ✅ Static summary method - Takes results as parameter, no state dependency --- ### Alternative: If You Need Shared State If you absolutely need to accumulate results in the instance (e.g., for streaming/progressive updates), use an asyncio.Lock: `python import asyncio class AsyncAPIClient: def __init__(self, base_url: str): self.base_url = base_url self.responses = [] self.error_count = 0 self._lock = asyncio.Lock() # Add lock async def fetch_all(self, endpoints: List[str]) -> List[Dict[str, Any]]: async with aiohttp.ClientSession() as session: tasks = [self.fetch_endpoint(session, endpoint) for endpoint in endpoints] for coro in asyncio.as_completed(tasks): result = await coro # Protect shared state with lock async with self._lock: if "error" in result: self.error_count += 1 else: self.responses.append(result) return self.responses ` However, the stateless design I showed first is strongly preferred for async code. import asyncio from typing import List, Dict, Any, TypedDict ### Testing Recommendation Add tests that verify all 120 requests are accounted for: `python async def test_all_results_captured(): client = AsyncAPIClient("https://jsonplaceholder.typicode.com") endpoints = ["posts/1"] * 100 results = await client.fetch_all(endpoints) assert len(results) == 100, f"Expected 100, got {len(results)}" `` ============================================================ ✅ Session 2 complete! ============================================================
Notice the difference:
nition persisting)
✅
Configure context editing
with token triggers and retention policies (Session 3 demonstrated automatic clearing)
✅
Apply security best practices
including path validation and memory poisoning prevention