Skip to content

Conversation

@frankbria
Copy link
Owner

@frankbria frankbria commented Feb 9, 2026

Summary

Implements #349: Adds phase-based event emission to the ReactAgent so cf work follow and SSE streaming show meaningful execution progress.

  • Added AgentPhase constants (EXPLORING, PLANNING, CREATING, EDITING, TESTING, FIXING, VERIFYING) mapped to specific tool calls
  • Enhanced ProgressEvent model with tool_name, file_path, and iteration fields
  • ReactAgent emits ProgressEvent at each phase transition and tool dispatch
  • ReactAgent emits CompletionEvent/ErrorEvent and closes SSE streams via complete_task_sync()
  • Wired EventPublisher from runtime into ReactAgent constructor

Acceptance Criteria

  • Phase enum/constants defined with all 7 phases
  • Events emitted via existing events.py before/after tool calls
  • Events include: phase name, tool name, file path (if applicable), iteration number
  • Compatible with existing streaming.py SSE infrastructure
  • Compatible with cf work follow command
  • Tests verifying correct event emission per tool type
  • All existing tests pass (1642 v2 tests, 0 regressions)

Test Plan

  • 42 tests in test_react_agent.py (22 new, 16 original, 4 stream completion)
  • Full v2 test suite: 1642 passed, 0 failures
  • Lint: ruff check clean on all modified files
  • Code review: critical issue (missing complete_task_sync) identified and fixed

Files Changed

File Lines Purpose
codeframe/core/models.py +21 AgentPhase constants, ProgressEvent enhancement
codeframe/core/react_agent.py +110 Phase emission, stream completion, tool-phase mapping
codeframe/core/runtime.py +2/-1 Wire event_publisher to ReactAgent
tests/core/test_react_agent.py +795 Comprehensive phase emission and stream completion tests

Closes #349

Summary by CodeRabbit

  • New Features
    • Enhanced progress tracking with agent phases (Exploring, Planning, Creating, Editing, Testing, Fixing, Verifying) for better workflow visibility.
    • Added event publishing support enabling real-time progress monitoring, completion, and error notifications.
    • Progress events now include tool name, file path, and iteration details for granular execution tracking.

Test User added 5 commits February 9, 2026 09:10
… model

Add AgentPhase class with phase constants (EXPLORING, PLANNING, CREATING,
EDITING, TESTING, FIXING, VERIFYING) for ReactAgent progress reporting.

Enhance ProgressEvent with three new optional fields: tool_name, file_path,
and iteration. Update the computed data property to include these fields
for SSE format compatibility.
Add _TOOL_PHASE_MAP for mapping tool names to AgentPhase constants.
Add event_publisher param to __init__ and _emit_progress() method.

Emit EXPLORING before context loading, PLANNING before system prompt
construction, phase-appropriate events before each tool call in the
react loop, VERIFYING before gates.run(), and FIXING during
verification retry tool calls.
Pass event_publisher from execute_agent() to ReactAgent constructor,
enabling phase-based progress events during react engine execution.
Update the NOTE comment to remove event_publisher from unsupported list.
Add TestToolPhaseMap tests verifying all 7 tool->phase mappings and
unknown tool default behavior.

Add TestPhaseEmissionEdgeCases with tests for publisher exceptions not
crashing the agent, multiple tool calls in a single iteration, run_command
mapping to TESTING, and correct task_id on all events.
ReactAgent now publishes CompletionEvent on success and ErrorEvent on
failure to the EventPublisher, then calls complete_task_sync() to send
the END_OF_STREAM sentinel. Without this, SSE subscribers would hang
until timeout.

Also filters existing phase tests to ProgressEvent instances so they
don't break when CompletionEvent/ErrorEvent are in the events list.
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 9, 2026

Walkthrough

Added AgentPhase constants class defining seven progress phases (EXPLORING, PLANNING, CREATING, EDITING, TESTING, FIXING, VERIFYING). Extended ProgressEvent with optional fields: tool_name, file_path, and iteration. Integrated event publishing into ReactAgent to emit progress events throughout the agent's execution lifecycle.

Changes

Cohort / File(s) Summary
Event Model Definition
codeframe/core/models.py
Introduced AgentPhase class with phase constants and extended ProgressEvent to include optional tool_name, file_path, and iteration fields in its data representation.
Event Emission Integration
codeframe/core/react_agent.py
Added optional EventPublisher parameter to ReactAgent, created tool-to-phase mapping (_TOOL_PHASE_MAP), and integrated event emission throughout initialization, main loop, verification, and error handling paths with helper methods (_emit_progress, _emit_stream_completion, _emit_stream_error).
Runtime Wiring
codeframe/core/runtime.py
Updated ReactAgent instantiation to pass event_publisher parameter from runtime execution context.
Comprehensive Test Coverage
tests/core/test_react_agent.py
Added extensive test suite covering AgentPhase constants, ProgressEvent fields, per-tool phase mappings, event emission lifecycle, edge cases (publisher exceptions, multiple tool calls, path safety), and runtime integration.

Sequence Diagram

sequenceDiagram
    actor Client
    participant Runtime
    participant ReactAgent
    participant EventPublisher
    participant Tools

    Client->>Runtime: execute_agent(task)
    Runtime->>ReactAgent: __init__(event_publisher)
    ReactAgent->>EventPublisher: emit ProgressEvent(EXPLORING)
    ReactAgent->>EventPublisher: emit ProgressEvent(PLANNING)
    
    loop ReAct Loop - Each Iteration
        ReactAgent->>Tools: dispatch tool
        EventPublisher-->>Client: emit ProgressEvent(phase, tool_name, file_path, iteration)
        Tools-->>ReactAgent: result
        alt Tool execution failed
            ReactAgent->>EventPublisher: emit ProgressEvent(FIXING)
            ReactAgent->>Tools: dispatch edit tool
            EventPublisher-->>Client: emit ProgressEvent(EDITING, iteration)
        end
    end
    
    rect rgba(100, 200, 150, 0.5)
    ReactAgent->>EventPublisher: emit ProgressEvent(VERIFYING)
    ReactAgent->>EventPublisher: emit CompletionEvent(task_id)
    end
    
    EventPublisher-->>Client: stream complete
    ReactAgent-->>Runtime: return result
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

  • PR #361: Likely introduces base eventing infrastructure that this PR extends with phase-based event emission and EventPublisher wiring into ReactAgent.
  • PR #363: Modifies ReactAgent construction and runtime instantiation, creating alignment on how ReactAgent is initialized and integrated into the execution engine.

Poem

🐰 Hops through phases with glee,
EXPLORING, CREATING, for all to see,
Progress events stream with care,
Tool names dancing through the air,
Each iteration, a rabbit's delight,
Phases shining oh so bright!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change: phase-based event emission for ReactAgent progress reporting.
Linked Issues check ✅ Passed The PR implements all acceptance criteria from issue #349: phase enum, event emission, field inclusion, SSE/cf work follow compatibility, and comprehensive tests.
Out of Scope Changes check ✅ Passed All changes are scoped to implementing phase-based event emission for ReactAgent; no unrelated modifications detected.
Docstring Coverage ✅ Passed Docstring coverage is 86.05% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feature/issue-349-phase-event-emission

No actionable comments were generated in the recent review. 🎉

🧹 Recent nitpick comments
codeframe/core/react_agent.py (1)

554-573: Consider computing actual duration_seconds.

The CompletionEvent is emitted with duration_seconds=0, losing timing information that could be valuable for SSE consumers monitoring task execution. Consider tracking the start time in run() and computing the actual duration.

♻️ Suggested improvement to track duration
 def run(self, task_id: str) -> AgentStatus:
     """Execute the full agent workflow for a task."""
     self._current_task_id = task_id
+    self._start_time = datetime.now(timezone.utc)
     self._emit(EventType.AGENT_STARTED, {"task_id": task_id})

Then in _emit_stream_completion:

-                    duration_seconds=0,
+                    duration_seconds=(datetime.now(timezone.utc) - self._start_time).total_seconds(),

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 9, 2026

Note

Currently processing new changes in this PR. This may take a few minutes, please wait...

 ____________________________________________________________________________________________________________________________________________
< Organize teams around functionality. Don't separate designers from coders, testers from data modelers. Build teams the way you build code. >
 --------------------------------------------------------------------------------------------------------------------------------------------
  \
   \   \
        \ /\
        ( )
      .( o ).

✏️ Tip: You can disable in-progress messages and the fortune message in your review settings.

Tip

You can customize the high-level summary generated by CodeRabbit.

Configure the reviews.high_level_summary_instructions setting to provide custom instructions for generating the high-level summary.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feature/issue-349-phase-event-emission

Comment @coderabbitai help to get the list of available commands and usage tips.

2 similar comments
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 9, 2026

Note

Currently processing new changes in this PR. This may take a few minutes, please wait...

 ____________________________________________________________________________________________________________________________________________
< Organize teams around functionality. Don't separate designers from coders, testers from data modelers. Build teams the way you build code. >
 --------------------------------------------------------------------------------------------------------------------------------------------
  \
   \   \
        \ /\
        ( )
      .( o ).

✏️ Tip: You can disable in-progress messages and the fortune message in your review settings.

Tip

You can customize the high-level summary generated by CodeRabbit.

Configure the reviews.high_level_summary_instructions setting to provide custom instructions for generating the high-level summary.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feature/issue-349-phase-event-emission

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 9, 2026

Note

Currently processing new changes in this PR. This may take a few minutes, please wait...

 ____________________________________________________________________________________________________________________________________________
< Organize teams around functionality. Don't separate designers from coders, testers from data modelers. Build teams the way you build code. >
 --------------------------------------------------------------------------------------------------------------------------------------------
  \
   \   \
        \ /\
        ( )
      .( o ).

✏️ Tip: You can disable in-progress messages and the fortune message in your review settings.

Tip

You can customize the high-level summary generated by CodeRabbit.

Configure the reviews.high_level_summary_instructions setting to provide custom instructions for generating the high-level summary.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feature/issue-349-phase-event-emission

Comment @coderabbitai help to get the list of available commands and usage tips.

@macroscopeapp
Copy link
Contributor

macroscopeapp bot commented Feb 9, 2026

Add phase-based progress events and terminal stream events to ReactAgent with new AgentPhase constants and tool-to-phase mapping for progress reporting

Introduce AgentPhase constants and extend ProgressEvent with tool_name, file_path, and iteration. Wire an optional event_publisher into ReactAgent to emit phase-based progress, verification/fixing updates, and terminal CompletionEvent/ErrorEvent. Update runtime construction to pass the publisher and add tests for phase mapping, event payloads, and stream closure.

📍Where to Start

Start with the progress emission logic in ReactAgent.run and ReactAgent._react_loop in react_agent.py.


Macroscope summarized 6b9c17d.

5 similar comments
@macroscopeapp
Copy link
Contributor

macroscopeapp bot commented Feb 9, 2026

Add phase-based progress events and terminal stream events to ReactAgent with new AgentPhase constants and tool-to-phase mapping for progress reporting

Introduce AgentPhase constants and extend ProgressEvent with tool_name, file_path, and iteration. Wire an optional event_publisher into ReactAgent to emit phase-based progress, verification/fixing updates, and terminal CompletionEvent/ErrorEvent. Update runtime construction to pass the publisher and add tests for phase mapping, event payloads, and stream closure.

📍Where to Start

Start with the progress emission logic in ReactAgent.run and ReactAgent._react_loop in react_agent.py.


Macroscope summarized 6b9c17d.

@macroscopeapp
Copy link
Contributor

macroscopeapp bot commented Feb 9, 2026

Add phase-based progress events and terminal stream events to ReactAgent with new AgentPhase constants and tool-to-phase mapping for progress reporting

Introduce AgentPhase constants and extend ProgressEvent with tool_name, file_path, and iteration. Wire an optional event_publisher into ReactAgent to emit phase-based progress, verification/fixing updates, and terminal CompletionEvent/ErrorEvent. Update runtime construction to pass the publisher and add tests for phase mapping, event payloads, and stream closure.

📍Where to Start

Start with the progress emission logic in ReactAgent.run and ReactAgent._react_loop in react_agent.py.


Macroscope summarized 6b9c17d.

@macroscopeapp
Copy link
Contributor

macroscopeapp bot commented Feb 9, 2026

Add phase-based progress events and terminal stream events to ReactAgent with new AgentPhase constants and tool-to-phase mapping for progress reporting

Introduce AgentPhase constants and extend ProgressEvent with tool_name, file_path, and iteration. Wire an optional event_publisher into ReactAgent to emit phase-based progress, verification/fixing updates, and terminal CompletionEvent/ErrorEvent. Update runtime construction to pass the publisher and add tests for phase mapping, event payloads, and stream closure.

📍Where to Start

Start with the progress emission logic in ReactAgent.run and ReactAgent._react_loop in react_agent.py.


Macroscope summarized 6b9c17d.

@macroscopeapp
Copy link
Contributor

macroscopeapp bot commented Feb 9, 2026

Add phase-based progress events and terminal stream events to ReactAgent with new AgentPhase constants and tool-to-phase mapping for progress reporting

Introduce AgentPhase constants and extend ProgressEvent with tool_name, file_path, and iteration. Wire an optional event_publisher into ReactAgent to emit phase-based progress, verification/fixing updates, and terminal CompletionEvent/ErrorEvent. Update runtime construction to pass the publisher and add tests for phase mapping, event payloads, and stream closure.

📍Where to Start

Start with the progress emission logic in ReactAgent.run and ReactAgent._react_loop in react_agent.py.


Macroscope summarized 6b9c17d.

@macroscopeapp
Copy link
Contributor

macroscopeapp bot commented Feb 9, 2026

Add phase-based progress events and terminal stream events to ReactAgent with new AgentPhase constants and tool-to-phase mapping for progress reporting

Introduce AgentPhase constants and extend ProgressEvent with tool_name, file_path, and iteration. Wire an optional event_publisher into ReactAgent to emit phase-based progress, verification/fixing updates, and terminal CompletionEvent/ErrorEvent. Update runtime construction to pass the publisher and add tests for phase mapping, event payloads, and stream closure.

📍Where to Start

Start with the progress emission logic in ReactAgent.run and ReactAgent._react_loop in react_agent.py.


Macroscope summarized 6b9c17d.

@macroscopeapp
Copy link
Contributor

macroscopeapp bot commented Feb 9, 2026

Add phase-based progress and terminal event emission to ReactAgent.run and verification loop using AgentPhase constants and EventPublisher

Introduce AgentPhase constants and extend ProgressEvent with tool_name, file_path, and iteration; wire EventPublisher into ReactAgent to emit phase progress during startup, verification, and fixing, and publish completion or error stream events. Update runtime to pass the publisher to ReactAgent. See codeframe/core/react_agent.py and codeframe/core/models.py.

📍Where to Start

Start in ReactAgent.run and the _react_loop verification sequence in codeframe/core/react_agent.py.


Macroscope summarized 406f4bc.

Moves complete_task_sync() into finally blocks in _emit_stream_completion
and _emit_stream_error to prevent SSE stream leaks if publish_sync throws.
@claude
Copy link

claude bot commented Feb 9, 2026

Code Review: Phase-Based Event Emission for ReactAgent

This PR successfully implements phase-based progress reporting for the ReactAgent, enabling meaningful execution visibility through cf work follow and SSE streaming. The implementation is well-structured, comprehensive, and follows the v2 headless architecture principles.

✅ Strengths

1. Architecture & Design

  • Clean separation of concerns: AgentPhase constants in models, _TOOL_PHASE_MAP in react_agent
  • Proper use of TYPE_CHECKING to avoid circular imports with EventPublisher
  • Backward compatible: event_publisher is optional, agent works without it
  • Follows v2 headless pattern: no FastAPI imports in core

2. Event Emission Strategy

  • Events emitted at all critical phase transitions (EXPLORING, PLANNING, CREATING, EDITING, TESTING, FIXING, VERIFYING)
  • Rich event context: tool_name, file_path, iteration provide detailed progress tracking
  • Proper stream lifecycle management: CompletionEvent/ErrorEvent + complete_task_sync() ensures no SSE stream leaks

3. Robustness

  • finally blocks in _emit_stream_completion/error ensure streams close even if publish_sync fails (commits 5-6)
  • Exception handling: publishing failures don't crash the agent (logged at debug level)
  • No-op pattern: all _emit_* methods gracefully handle missing publisher

4. Test Coverage

  • 42 comprehensive tests covering all 7 phases, edge cases, error scenarios, and stream lifecycle
  • Tests verify correct phase mapping, event payloads, iteration tracking, and multiple tool calls
  • Tests confirm stream closure under all exit paths (success, failure, exception)
  • Existing tests unaffected: 1642 v2 tests passing with 0 regressions

🔍 Code Quality Observations

1. AgentPhase as Class vs Enum

class AgentPhase:
    EXPLORING = "exploring"
    PLANNING = "planning"
    # ...

This works but consider using Enum or StrEnum (Python 3.11+) for better type safety and IDE support:

from enum import StrEnum

class AgentPhase(StrEnum):
    EXPLORING = "exploring"
    PLANNING = "planning"
    # ...

Impact: Low (current approach works fine, but enum would provide stricter typing)

2. Tool-to-Phase Mapping Completeness
_TOOL_PHASE_MAP covers 7 tools but defaults unknown tools to EXPLORING via dict.get(). This is reasonable but could mask issues if new tools are added without updating the map.

Suggestion: Add a comment or doc noting that unmapped tools default to EXPLORING, or add logging when the default is used.

3. Stream Completion Timing
The agent emits CompletionEvent and calls complete_task_sync() at three exit points:

  • Success after verification passes
  • Failure due to max iterations
  • Failure due to verification retry exhaustion
  • Failure due to exception

This is correct, but the duration_seconds=0 in CompletionEvent is a placeholder. Consider passing actual duration if available.

4. Type Annotations
In _emit_progress, the signature uses str | None (Python 3.10+ union syntax) which is good:

def _emit_progress(
    self,
    phase: str,
    *,
    message: str | None = None,  # ✅ Modern syntax
    # ...
)

🎯 Alignment with CLAUDE.md Guidelines

Core-first architecture: No FastAPI imports in react_agent.py or models.py
Headless design: EventPublisher is optional, CLI works without server
Agent state separation: Events emitted via publisher, not directly to HTTP
Test coverage: Comprehensive v2 test suite with phase-specific tests
No over-engineering: Simple string-based phase constants, minimal abstraction

🔒 Security & Performance

Security: ✅ No security concerns. Event payloads contain task data (file paths, tool names) which is appropriate for authenticated SSE streams.

Performance: ✅ Minimal overhead. Events are only published when event_publisher is present. The finally blocks add negligible latency.

📋 Acceptance Criteria Verification

  • Phase enum/constants defined with all 7 phases (models.py:1036-1048)
  • Events emitted before/after tool calls (react_agent.py:250-260, 279-290)
  • Events include phase, tool, file path, iteration (models.py:1062-1064)
  • Compatible with existing SSE infrastructure (streaming.py integration confirmed)
  • Compatible with cf work follow (via EventPublisher)
  • Tests verify event emission per tool type (42 tests in test_react_agent.py)
  • All existing tests pass (1642 v2 tests, 0 regressions)

🎉 Summary

This is production-ready code that successfully closes #349. The implementation is thoughtful, well-tested, and maintains CodeFRAME's architectural principles. The minor suggestions above are for future enhancement and don't block merging.

Recommendation:Approve and merge

Great work on the comprehensive test coverage and the critical fix in commit 6 ensuring stream closure via finally blocks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Phase 2.5-C] Add phase-based event emission for progress reporting

1 participant