RFC-0021 Pre-Flight Analysis¶
State Inventory¶
Instance-Level Mutable State in BaseAgent¶
| Field | Type | Shared? | Migration Priority | Usage Count |
|---|---|---|---|---|
_cancelled |
bool | ✅ Yes | Critical | 15+ locations |
_current_stream_task |
asyncio.Task | ✅ Yes | Critical | 8 locations |
_event_queue |
asyncio.Queue | ✅ Yes | Critical | 6 locations |
_injection_manager |
PromptInjectionManager | ✅ Yes | High | 9 locations |
_background_task |
asyncio.Task | ✅ Yes | Medium | 4 locations |
_formatted_system_prompt |
str | ⚠️ Shared (intentional) | Do NOT migrate | 3 locations |
_internal_fs |
IsolatedMemoryFileSystem | ⚠️ Shared (intentional) | Do NOT migrate | 2 locations |
State Usage Analysis¶
1. _cancelled Usage¶
# Files accessing _cancelled:
- native_agent.py: Lines 767, 835, 848, 858, 906, 917 (finally)
- base_agent.py: Lines 229 (init), 486 (reset), 494 (set), 618 (reset), 998 (set)
- claude_code_agent.py: Line ~120
2. _current_stream_task Usage¶
# Files accessing _current_stream_task:
- native_agent.py: Lines 619 (set), 647 (reset), 959 (interrupt)
- base_agent.py: Lines 230 (init), 619 (set), 647 (reset)
3. _event_queue Usage¶
# Files accessing _event_queue:
- base_agent.py: Lines 213 (init), 350 (emit)
- context.py: Line 71 (report_progress)
- event_emitter.py: Line 350 (_emit)
4. _injection_manager Usage¶
# Files accessing _injection_manager:
- base_agent.py: Lines 231 (init), 532, 551, 555, 559, 563, 621, 625, 645, 648
Subclass Audit¶
| Subclass | File | Custom State Access | Risk Level |
|---|---|---|---|
| NativeAgent | native_agent/agent.py | _cancelled (6x), _current_stream_task (3x) | High |
| ACPAgent | acp_agent/acp_agent.py | _event_queue, _cancelled | Medium |
| AGUIAgent | agui_agent/agui_agent.py | _cancelled, _current_stream_task | Medium |
| ClaudeCodeAgent | claude_code_agent/claude_code_agent.py | _event_queue, _cancelled | Medium |
| CodexAgent | codex_agent/codex_agent.py | Needs audit | Unknown |
Cross-Cutting Dependencies¶
AgentContext.report_progress()
└── self.agent._event_queue.put() # Needs run_ctx access
StreamEventEmitter._emit()
└── self._context.agent._event_queue.put() # Needs run_ctx access
BaseAgent.interrupt()
└── self._cancelled = True # Must target specific run
└── self._current_stream_task.cancel() # Must target specific run
Critical Code Paths¶
Path 1: run_stream → _run_stream_once¶
run_stream()
└── _run_stream_once()
└── _stream_events()
└── agent_iteration_task()
└── [Uses _cancelled check every iteration]
Path 2: Event Emission¶
Agent/Tool emits event
└── StreamEventEmitter._emit()
└── agent._event_queue.put(event) # [Must use run_ctx queue]
Path 3: Interruption¶
External interrupt()
└── self._cancelled = True # [Must set run_ctx.cancelled]
└── self._current_stream_task.cancel()
Known Issues¶
Issue 1: finally Block Bug¶
Location: native_agent.py:917
Impact: Causes premature termination in concurrent scenarios Fix: Only set cancelled on actual cancellationIssue 2: Interrupt Targeting¶
Location: base_agent.py interrupt() method Current: Targets instance-level _current_stream_task Problem: In concurrent scenario, which task gets interrupted? Fix: Need run-specific interrupt handle
Migration Complexity¶
High Complexity (Critical Path)¶
_cancelled- Checked throughout iteration loop_event_queue- Cross-cutting: used by AgentContext, StreamEventEmitter_current_stream_task- Used for interruption
Medium Complexity¶
_injection_manager- Localized to prompt injection methods_background_task- Used in run_in_background mode
Do Not Migrate¶
_formatted_system_prompt- Represents shared agent personality_internal_fs- Shared filesystem is intentional feature
Test Coverage Gaps¶
Missing Tests¶
- ❌ Concurrent call isolation test
- ❌ Cancellation isolation test
- ❌ Event queue isolation test
- ❌ Performance regression test
- ❌ Subclass compatibility test
- ❌ Interruption targeting test
Recommendations¶
State Migration Order¶
- First:
_cancelled+_current_stream_task(tightly coupled) - Second:
_event_queue(most complex, cross-cutting) - Third:
_injection_manager - Last:
_background_task
Risk Mitigation¶
- Each migration must have passing tests before proceeding
- Maintain backward compatibility property accessors during transition
- Document shared vs isolated state clearly
Sign-Off¶
Analysis Date: 2025-04-05 Analyst: yuchen.liu Status: Ready for test suite creation