Skip to content

ClaudeInterceptor injects memory too late - patches write() but subprocess already started #6

Description

@rileyedwards77

Issue

Using agentic-learning v0.4.3 with Claude Agent SDK, memory capture works but memory injection doesn't.

Root Cause

The ClaudeInterceptor patches SubprocessCLITransport.write() to inject memory into self._options.system_prompt. However, by the time write() is called, the subprocess has already started with the original system_prompt baked into CLI args.

The execution order is:

  1. ClaudeSDKClient.__aenter__() calls connect()
  2. connect() calls _build_command() which reads self._options.system_prompt and builds CLI args including --system-prompt "..."
  3. connect() spawns the subprocess with those args
  4. query() is called, which calls write()
  5. Now the interceptor runs and modifies self._options.system_prompt - but it's too late, the subprocess is already running

The docstring in claude.py line 119 says "on first write (during client.connect())" but write() is not called during connect() - it's called later when sending the user query.

Our Workaround

We patched SubprocessCLITransport.connect() instead, injecting memory BEFORE _build_command() runs:

_original_connect = SubprocessCLITransport.connect

async def patched_connect(self):
    config = get_current_config()
    if config and not config.get('capture_only', False):
        client = config.get('client')
        agent_name = config.get('agent_name')
        if client and agent_name:
            memory_context = await client.memory.context.retrieve(agent=agent_name)
            if memory_context:
                self._options.system_prompt += f"\n\n{memory_context}"
                self._memory_injected = True  # Skip SDK's broken injection
    
    return await _original_connect(self)

SubprocessCLITransport.connect = patched_connect

This works alongside the existing interceptor - capture still works via the write()/read_messages() patches, we just fixed the injection timing.

Suggested Fix

The ClaudeInterceptor.install() method should patch connect() (or _build_command()) instead of write() for the memory injection logic.

Environment

  • agentic-learning: 0.4.3
  • claude-agent-sdk: latest
  • Python: 3.14

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions