# Dispatcher Integration Guide - Luzia CLI Enhancement

## Summary of Changes

The Responsive Dispatcher improves Luzia CLI responsiveness by:

1. **Eliminating blocking** during task dispatch - CLI returns immediately with job_id
2. **Adding background monitoring** - Jobs progress tracked asynchronously
3. **Implementing status feedback** - Live progress updates without blocking
4. **Enabling concurrent management** - Multiple tasks tracked independently
5. **Providing responsive CLI** - Always responsive after dispatch

## Performance Improvements

### Before (Blocking Dispatch)
```
User: luzia overbits "task"
  ↓ [BLOCKS HERE - CLI waits for agent startup]
  (3-5 seconds of blocking)
  ↓
Output: job_id
Result: CLI frozen during dispatch
```

### After (Non-Blocking Dispatch)
```
User: luzia overbits "task"
  ↓ [RETURNS IMMEDIATELY]
  (<100ms)
  ↓
Output: job_id
Result: CLI responsive, task runs in background
```

### Metrics
- **Dispatch latency**: <100ms (vs 3-5s before)
- **Throughput**: 434 tasks/second
- **Status retrieval**: <1ms (cached) or <50µs (fresh)
- **Memory per job**: ~2KB

## New Modules

### 1. `lib/responsive_dispatcher.py`
Core non-blocking dispatcher engine.

**Key Classes:**
- `ResponseiveDispatcher` - Main dispatcher with:
  - `dispatch_task()` - Returns immediately with job_id
  - `get_status()` - Poll job status with caching
  - `update_status()` - Update job progress (used by monitor)
  - `list_jobs()` - Get job history
  - `wait_for_job()` - Block until completion (optional)
  - `start_background_monitor()` - Start monitor thread

**Features:**
- Atomic status file operations
- Intelligent caching (1-second TTL)
- Background monitoring queue
- Job history persistence

### 2. `lib/cli_feedback.py`
Pretty-printed CLI feedback and status display.

**Key Classes:**
- `CLIFeedback` - Responsive output formatting:
  - `job_dispatched()` - Show dispatch confirmation
  - `show_status()` - Display job status with progress
  - `show_jobs_list()` - List all jobs
  - `show_concurrent_jobs()` - Summary view

- `Colors` - ANSI color codes
- `ProgressBar` - ASCII progress bar renderer
- `ResponseiveOutput` - Context manager for operations

### 3. `lib/dispatcher_enhancements.py`
Integration layer connecting dispatcher to existing Luzia code.

**Key Classes:**
- `EnhancedDispatcher` - Wrapper combining responsive dispatcher + feedback
  - `dispatch_and_report()` - Dispatch with automatic feedback
  - `get_status_and_display()` - Get and display status
  - `show_jobs_summary()` - Show jobs for a project
  - `show_concurrent_summary()` - Show all jobs

**Integration Functions:**
- `enhanced_spawn_claude_agent()` - Replacement for existing spawn
- `track_existing_job()` - Retroactive tracking
- `show_job_status_interactive()` - Interactive monitoring
- `start_background_monitoring()` - Start monitor thread

## Integration Steps

### Step 1: Import New Modules

In `bin/luzia`, add at the top:

```python
from lib.responsive_dispatcher import ResponseiveDispatcher
from lib.cli_feedback import CLIFeedback
from lib.dispatcher_enhancements import EnhancedDispatcher, get_enhanced_dispatcher
```

### Step 2: Enhanced Project Task Handler

Replace the existing `route_project_task` handler:

```python
def route_project_task(config: dict, args: list, kwargs: dict) -> int:
    """Handler: luzia <project> <task> (with responsive dispatch)"""

    # ... existing validation code ...

    project = args[0]
    task = " ".join(args[1:])

    # ... existing setup code ...

    # Use enhanced dispatcher for responsive dispatch
    enhanced = get_enhanced_dispatcher()

    # Dispatch and show feedback
    job_id, status = enhanced.dispatch_and_report(
        project=project,
        task=task,
        show_details=not is_command,  # Show details for natural language only
        show_feedback=VERBOSE
    )

    # Output job_id for tracking
    print(f"agent:{project}:{job_id}")
    return 0
```

### Step 3: Add Job Status Commands

Add new route for `luzia jobs`:

```python
def route_jobs(config: dict, args: list, kwargs: dict) -> int:
    """Handler: luzia jobs [job_id]"""

    enhanced = get_enhanced_dispatcher()

    if not args:
        # Show all jobs
        enhanced.show_jobs_summary()
        return 0

    job_id = args[0]

    if "--watch" in args:
        # Interactive monitoring
        from lib.dispatcher_enhancements import show_job_status_interactive
        show_job_status_interactive(job_id)
    else:
        # Show status
        enhanced.get_status_and_display(job_id, show_full=True)

    return 0
```

### Step 4: Start Background Monitor

Add to main startup:

```python
def main():
    # ... existing code ...

    # Start background monitoring
    enhanced = get_enhanced_dispatcher()
    enhanced.dispatcher.start_background_monitor()

    # ... rest of main ...
```

## File Structure

New files created:

```
/opt/server-agents/orchestrator/
├── lib/
│   ├── responsive_dispatcher.py      # Core dispatcher
│   ├── cli_feedback.py               # CLI feedback system
│   └── dispatcher_enhancements.py    # Integration layer
├── tests/
│   └── test_responsive_dispatcher.py # Test suite (11 tests)
├── examples/
│   └── demo_concurrent_tasks.py      # Live demonstration
└── docs/
    ├── RESPONSIVE-DISPATCHER.md      # User guide
    └── DISPATCHER-INTEGRATION-GUIDE.md (this file)
```

## Usage Examples

### Basic Dispatch (Non-blocking)

```bash
$ luzia overbits "fix the login button"
✓ Dispatched
  Job ID: 113754-a2f5
  Project: overbits

  Use: luzia jobs to view status
       luzia jobs 113754-a2f5 for details

$ # CLI is responsive immediately!
$ luzia jobs     # Check status without waiting
```

### Monitor Multiple Jobs

```bash
$ luzia overbits "task 1" & luzia musica "task 2" & luzia dss "task 3" &
agent:overbits:113754-a2f5
agent:musica:113754-8e4b
agent:dss:113754-9f3c

$ # All 3 running concurrently
$ luzia jobs
  Task Summary:
    Running:    3
    Pending:    0
```

### Watch Job Progress

```bash
$ luzia jobs 113754-a2f5 --watch

  Monitoring job: 113754-a2f5

  starting       [░░░░░░░░░░░░░░░░░░░░] 5%
  running        [██████░░░░░░░░░░░░░░] 30%
  running        [████████████░░░░░░░░] 65%
  completed      [██████████████████████] 100%
```

## Testing

Run the test suite:

```bash
python3 tests/test_responsive_dispatcher.py
```

All 11 tests should pass:
- ✓ Immediate dispatch
- ✓ Status retrieval
- ✓ Status updates
- ✓ Concurrent jobs
- ✓ Cache behavior
- ✓ CLI feedback
- ✓ Progress bar
- ✓ Background monitoring
- ✓ Enhanced dispatcher dispatch
- ✓ Enhanced dispatcher display
- ✓ Enhanced dispatcher summary

## Demo

Run the live demo:

```bash
python3 examples/demo_concurrent_tasks.py
```

Demonstrates:
1. Concurrent dispatch (5 tasks in <50ms)
2. Non-blocking status polling
3. Independent job monitoring
4. Job listing and summaries
5. Performance metrics (434 tasks/sec, <1ms status retrieval)

## Backward Compatibility

The implementation maintains full backward compatibility:

- Existing `spawn_claude_agent()` still works
- Existing route handlers can continue to work
- New functionality is opt-in through `EnhancedDispatcher`
- Status files stored separately in `/var/lib/luzia/jobs/`
- No changes to job output or agent execution

## Migration Checklist

To fully integrate responsive dispatcher into Luzia:

- [ ] Import new modules in bin/luzia
- [ ] Update route_project_task to use EnhancedDispatcher
- [ ] Add route_jobs handler for `luzia jobs`
- [ ] Start background monitor in main()
- [ ] Add `--watch` flag support to jobs command
- [ ] Test with existing workflows
- [ ] Run full test suite
- [ ] Update CLI help text
- [ ] Document new `luzia jobs` command
- [ ] Document `--watch` flag usage

## Configuration

Optional environment variables:

```bash
# Cache TTL in seconds (default: 1)
export LUZIA_CACHE_TTL=2

# Monitor poll interval (default: 1)
export LUZIA_MONITOR_INTERVAL=0.5

# Max job history (default: 1000)
export LUZIA_MAX_JOBS=500

# Job directory (default: /var/lib/luzia/jobs)
export LUZIA_JOBS_DIR=/custom/path
```

## Troubleshooting

### Monitor not running

Check if background thread started:
```bash
ps aux | grep python | grep luzia
```

Start manually if needed:
```python
from lib.dispatcher_enhancements import start_background_monitoring
start_background_monitoring()
```

### Jobs not updating

Ensure job directory is writable:
```bash
ls -la /var/lib/luzia/jobs/
chmod 755 /var/lib/luzia/jobs
```

### Status cache stale

Force fresh read:
```python
status = dispatcher.get_status(job_id, use_cache=False)
```

## Future Enhancements

Planned additions:
- [ ] Web dashboard for job monitoring
- [ ] WebSocket support for real-time updates
- [ ] Job retry with exponential backoff
- [ ] Job cancellation with graceful shutdown
- [ ] Resource-aware scheduling
- [ ] Job dependencies and DAG execution
- [ ] Slack/email notifications
- [ ] Database persistence (SQLite)
- [ ] Job timeout management

## Support

For issues or questions:
1. Check test suite: `python3 tests/test_responsive_dispatcher.py`
2. Run demo: `python3 examples/demo_concurrent_tasks.py`
3. Review documentation: `docs/RESPONSIVE-DISPATCHER.md`
4. Check logs: `/var/log/luz-orchestrator/`
