summaryrefslogtreecommitdiff
path: root/Omni/Agent/DESIGN.md
blob: ae1f6b3528490648060aa01bf4673d1ba9357fbc (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
# Multi-Agent System 2.0 Design

**Goal:** Replace the current bash-script based worker system (`start-worker.sh`, etc.) with a robust, type-safe Haskell application `Omni/Agent.hs`.

## 1. CLI Interface

The `agent` command (compiled from `Omni/Agent.hs`) will provide a unified interface for managing workers.

```bash
agent start <name> [--background]  # Start a worker (foreground by default, background with flag)
agent stop <name>                  # Stop a background worker
agent status                       # List all workers and their status
agent log <name> [-f]              # View/tail worker logs
agent sync                         # Sync local state with live (helper)
```

## 2. Module Structure (`Omni/Agent/`)

We will refactor the bash logic into Haskell modules:

- **Omni.Agent** (`Omni/Agent.hs`): Main entry point and CLI parsing (Docopt).
- **Omni.Agent.Core**: Core data types and state management.
- **Omni.Agent.Worker**: The worker loop logic (sync, claim, work, submit).
- **Omni.Agent.Git**: Git operations (worktree, branch, merge, commit).
- **Omni.Agent.Process**: Process management (PID files, signals).
- **Omni.Agent.Log**: Log streaming and filtering (the "monitor" logic).

## 3. Data Types

```haskell
data WorkerStatus
  = Idle
  | Syncing
  | Working TaskId
  | Submitting TaskId
  | Error Text
  deriving (Show, Eq, Generic)

data Worker = Worker
  { workerName :: Text
  , workerPid :: Maybe Int
  , workerStatus :: WorkerStatus
  , workerPath :: FilePath
  }
```

## 4. Implementation Details

### 4.1 Worker Loop (`agent start`)
The Haskell implementation should replicate the logic of `start-worker.sh` but with better error handling and logging.

1.  **Setup**: Ensure worktree exists (or create it).
2.  **Loop**:
    - `Git.syncWithLive` (Rebase-based to preserve local history)
    - `Task.sync`
    - `task <- Task.findReady`
    - If `task`:
        - `Task.claim task`
        - `baseBranch <- Git.determineBaseBranch task` (Check dependencies)
        - `Git.checkoutTaskBranch task baseBranch` (Force checkout to clean untracked files)
        - `Engine.runAgent prompt` (Native LLM agent via OpenRouter)
        - `Git.commit`
        - `Git.checkoutBase`
        - `Task.submitReview task`
    - Else: `sleep 60`

### 4.2 Process Management
- Store PIDs in `.tasks/workers/<name>.pid`.
- `agent stop` sends SIGTERM to the PID.
- `agent status` checks if PID is alive.

### 4.3 Logging
- The Engine module uses callbacks to report activity and costs in real-time.
- `agent log` displays the status bar with worker progress information.
- **UI Design**:
    - **Two-line Status**: The CLI should maintain two reserved lines at the bottom (or top) of the output for each worker:
        - **Line 1 (Meta)**: `[Worker: omni-worker-1] Task: t-123 | Files: 3 | Credits: $0.45 | Time: 05:23`
        - **Line 2 (Activity)**: `[14:05:22] 🤖 Thinking...` (updates in place)
    - **Task Details**: When claiming a task, print the full task description/details to the log/console so the user can see what is being worked on without looking it up.
    - **Completion**: When a task finishes, print a summary line (e.g., `[✓] Task t-123 completed in 12m 30s`) and a hard line break before starting the next loop.
    - **History**: Previous log lines (tool outputs, thoughts) scroll up above these two status lines.

### 4.5 Git Robustness (Learnings)
- **Identity**: Configure `git config user.name "Omni Worker"` and `user.email` in the worktree to clearly distinguish worker commits from human commits.
- **Force Checkout**: The worker must use `git checkout -f` (or equivalent) when switching to task branches to ensure untracked files (like `.tasks/counters.jsonl`) don't block the switch.
- **Base Branch Logic**: 
    - If the task depends on another task that is *not* yet in `live` (e.g., in `Review`), the worker should branch off the dependency's branch (`task/<dep-id>`).
    - Otherwise, branch off `live` directly. Do NOT use the local worker branch (`omni-worker-N`) as the base, as it may contain temporary sync commits that shouldn't be merged.
- **Commit Hygiene**: Bundle the task status update (marking as 'Review') *inside* the feature implementation commit. This keeps the history clean (one commit per feature) and avoids separate "sync" commits for status changes.
- **Clean State**: The worker should ensure the workspace is clean (no uncommitted changes) before starting a new loop iteration.
- **Rebase Safety**: Always check the exit code of `git rebase`. If it fails (conflicts), abort immediately (`git rebase --abort`) to avoid leaving the repo in a broken interactive rebase state.
- **Status Verification**: Verify that task status updates actually succeed. Check `task ready` output against `live` state to prevent "zombie" tasks (completed in live but stuck in local loop) from being re-claimed.
- **Binary Freshness**: Ensure the `task` binary used by the worker is rebuilt/updated when source code changes, otherwise logic fixes (like `task ready` filtering) won't take effect.

## 5. Migration Strategy

1.  **Parallel Existence**: Keep bash scripts while developing Haskell version.
2.  **Feature Parity**: Ensure `agent start` works exactly like `start-worker.sh`.
3.  **Cutover**: Update `WORKER_AGENT_GUIDE.md` to use `agent` command.
4.  **Cleanup**: Delete bash scripts.

## 6. Testing Plan

### 6.1 Unit Tests (`Omni/Agent/Test.hs`)
- Test `Git` module commands (mocked).
- Test `Log` filtering logic.
- Test CLI argument parsing.

### 6.2 Integration Tests
- Create a temporary test repo.
- Spawn a worker.
- Mock the Engine LLM calls or use a test API key.
- Verify task moves from Open -> InProgress -> Review.

## 7. References
- `Omni/Agent/start-worker.sh` (Current implementation)
- `Omni/Task.hs` (Task manager integration)