Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: inference-gateway/cli
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: v0.99.1
Choose a base ref
...
head repository: inference-gateway/cli
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: v0.99.2
Choose a head ref
  • 2 commits
  • 125 files changed
  • 2 contributors

Commits on Jan 25, 2026

  1. refactor: Replace agent loop with event-driven state machine (#379)

    ## Overview
    
    This PR completes the agent state machine refactoring by extracting all
    state handlers into separate, maintainable files following the **State
    Design Pattern**. This improves code organization, readability, and
    scalability.
    
    ## Problem Statement
    
    The previous implementation had all state handlers in a single 1400+
    line file (`agent_event_driven.go`), making it:
    - **Hard to navigate**: Finding specific state logic required scrolling
    through unrelated code
    - **Difficult to maintain**: Changes to one state risked affecting
    others
    - **Complex to review**: PR reviews had to parse through the entire
    event-driven agent implementation
    - **Not scalable**: Adding new states or modifying existing ones became
    increasingly difficult
    
    ## Solution
    
    Refactored the agent state machine to follow the [State Design
    Pattern](https://refactoring.guru/design-patterns/state):
    
    ### Architecture Changes
    
    **Before:**
    ```
    internal/services/
    ├── agent.go (1400+ lines - monolithic)
    ├── agent_event_driven.go
    └── tools/
    ```
    
    **After:**
    ```
    internal/agent/
    ├── agent.go (1200 lines) - core service
    ├── agent_event_driven.go (400 lines) - event coordinator
    ├── agent_state_machine.go - state transitions
    ├── agent_streaming.go - LLM streaming
    ├── agent_tools.go - tool execution
    ├── agent_utils.go - helpers
    └── states/ (12 files, ~50-100 lines each)
        ├── idle.go
        ├── checking_queue.go
        ├── streaming_llm.go
        ├── post_stream.go
        ├── evaluating_tools.go
        ├── approving_tools.go
        ├── executing_tools.go
        ├── post_tool_execution.go
        ├── completing.go
        ├── error.go
        ├── cancelled.go
        └── stopped.go
    ```
    
    ### Key Components
    
    1. **State Handler Interface** (`state_handler.go`)
       - Defines `Handle(event)` method all states must implement
       - `StateContext` provides access to agent dependencies
    
    2. **Concrete States** (`states/*.go`)
       - Each state in its own file
       - Implements the `StateHandler` interface
       - Processes events relevant to that state
    
    3. **Event-Driven Agent** (`agent_event_driven.go`)
       - Simplified to ~400 lines (from 1400+)
       - Maintains state handler registry
       - Delegates events to appropriate state handlers
    
    ## Changes Made
    
    ### Phase 1: Infrastructure
    - ✅ Created `StateHandler` interface and `StateContext` struct
    - ✅ Created `states/` package for state implementations
    
    ### Phase 2: State Extraction
    Extracted all 12 states into separate files:
    1. ✅ `idle.go` - Initial state, transitions to CheckingQueue
    2. ✅ `error.go` - Terminal state for errors
    3. ✅ `cancelled.go` - Terminal state for user cancellation
    4. ✅ `stopped.go` - Terminal state for stops
    5. ✅ `completing.go` - Finalization and cleanup
    6. ✅ `evaluating_tools.go` - Tool approval evaluation
    7. ✅ `streaming_llm.go` - LLM streaming coordination
    8. ✅ `post_stream.go` - Post-streaming transitions
    9. ✅ `executing_tools.go` - Tool execution coordination
    10. ✅ `checking_queue.go` - Queue processing and completion logic
    11. ✅ `approving_tools.go` - User approval workflow
    12. ✅ `post_tool_execution.go` - Post-tool transitions
    
    ### Phase 3: Event-Driven Agent Refactoring
    - ✅ Added state handler registry (`stateHandlers` map)
    - ✅ Implemented `registerStateHandlers()` method
    - ✅ Simplified `handleEvent()` to dispatch pattern
    - ✅ Removed all `handle*State()` methods (~1000 lines deleted)
    
    ### Phase 4: Testing & Cleanup
    - ✅ Updated tests to match new architecture
    - ✅ Fixed test expectations for improved message storage timing
    - ✅ Removed outdated comments
    - ✅ All tests passing
    - ✅ Linter clean (0 issues)
    
    ## Benefits
    
    ### Code Organization
    - **Before**: 1400+ line file with 12 state handlers
    - **After**: 12 focused files, each 30-100 lines
    - Clear separation: one state = one file
    - Easy to locate and modify state-specific logic
    
    ### Maintainability
    - Each state is isolated (LSP compliance)
    - PR reviews focus on specific state files
    - New states just add a new file + registration line
    - Reduced merge conflicts (different files)
    
    ### Testability
    - Each state tested in isolation with its own test file
    - Easy to mock `StateContext` for state-specific tests
    - Test failures clearly indicate problematic state
    
    ### Scalability
    - 12 states = 12 files × 50-100 lines (manageable)
    - Adding states doesn't increase file complexity
    - Clear pattern for new state implementations
    
    ## Design Patterns Applied
    
    1. **State Design Pattern** - Context delegates to state handlers
    2. **Single Responsibility Principle** - One file handles one state's
    events
    3. **Open/Closed Principle** - Open for extension, closed for
    modification
    4. **Dependency Inversion** - States depend on `StateContext` interface
    
    ## Testing
    
    - ✅ All unit tests passing
    - ✅ Integration tests passing
    - ✅ No race conditions (`go test -race`)
    - ✅ Code coverage maintained
    - ✅ Manual testing confirms normal operation
    
    ## Migration Impact
    
    - **Lines Removed**: ~1000 (state handlers extracted)
    - **Lines Added**: ~800 (12 new state files + infrastructure)
    - **Net Reduction**: ~200 lines
    - **Complexity Reduction**: Significant (from one 1400-line file to 12
    focused files)
    
    ## Verification
    
    ```bash
    # Build
    task build
    ✅ Success
    
    # Tests
    task test
    ✅ All tests passing (internal/agent: 1.212s)
    
    # Linter
    task lint
    ✅ 0 issues
    ```
    
    ## Breaking Changes
    
    None. This is a pure refactoring with no API or behavior changes.
    
    ## References
    
    - [State Design Pattern - Refactoring
    Guru](https://refactoring.guru/design-patterns/state)
    - [State Pattern in
    Go](https://refactoring.guru/design-patterns/state/go/example)
    - [Go Code Review
    Comments](https://github.com/golang/go/wiki/CodeReviewComments)
    edenreich authored Jan 25, 2026
    Configuration menu
    Copy the full SHA
    536fdc6 View commit details
    Browse the repository at this point in the history
  2. chore(release): 0.99.2 [skip ci]

    ## [0.99.2](v0.99.1...v0.99.2) (2026-01-25)
    
    ### ♻️ Code Refactoring
    
    * Replace agent loop with event-driven state machine ([#379](#379)) ([536fdc6](536fdc6))
    semantic-release-bot committed Jan 25, 2026
    Configuration menu
    Copy the full SHA
    da90102 View commit details
    Browse the repository at this point in the history
Loading