# Asynchronous Hierarchical Execution Flow

## Overview

The `WorkspaceExecutionEngine` has been refactored to support asynchronous hierarchical recursion without direct `await` calls. Child workspaces are now scheduled into a global execution queue and execute independently, with results flowing back to parents via normal message routing.

## Architecture Changes

### 1. Global Workspace Queue

- **Component**: `self.global_workspace_queue: asyncio.Queue[str]`
- **Purpose**: Holds workspace IDs that need execution
- **Methods**:
  - `schedule_workspace(workspace_id)`: Enqueues a workspace for execution
  - `run_global_scheduler()`: Processes all workspaces in the queue

### 2. Execution State Tracking

- **Component**: `self._running_workspaces: set[str]` and `workspace._is_running: bool`
- **Purpose**: Prevents workspaces from being enqueued or executed while already running
- **Behavior**: Workspaces are marked as running at the start of `run_workspace()` and cleared at the end

### 3. Subteam Request Tracking

- **Component**: `self._subteam_requesters: dict[str, str]` (child_id -> requesting_agent_name)
- **Purpose**: Tracks which agent in the parent workspace requested each child workspace
- **Usage**: Used when sending `subteam_result` messages back to parents

## Execution Flow Diagram

```
User Task
   ↓
Root Workspace (scheduled via run())
   ↓ schedules → Child 1
   ↓ schedules → Child 2
                     ↓ schedules → Child 2a
                                     ↓ schedules → Child 2a.i

Global Execution Queue:
┌─────────────────────────────────────┐
│ Root Workspace                       │ ← Processed first
│ Child 1                              │ ← Processed independently
│ Child 2                              │ ← Processed independently
│ Child 2a                             │ ← Processed independently
│ Child 2a.i                           │ ← Processed independently
└─────────────────────────────────────┘

All workspaces run independently in global event loop
No recursion - each workspace executes to completion

Subteam Results Flow:
Child 2a.i completes
   ↓ sends [subteam_result] message → Child 2a (via normal routing)
   ↓ schedules Child 2a for processing
   
Child 2a completes
   ↓ sends [subteam_result] message → Child 2 (via normal routing)
   ↓ schedules Child 2 for processing

Child 2 completes
   ↓ sends [subteam_result] message → Root (via normal routing)
   ↓ schedules Root for processing

Results flow upward via normal message routing
```

## Key Changes

### Before (Recursive)
```python
# In _handle_subteam_request:
await self.run_workspace(
    workspace_id=child_workspace.workspace_id,
    max_cycles=20,
)
# Parent waits for child to complete synchronously
```

### After (Asynchronous)
```python
# In _handle_subteam_request:
self.schedule_workspace(child_workspace.workspace_id)
# Parent continues immediately, child executes later
```

## Message Flow

1. **Subteam Request**: Agent sends `{"action": "request_subteam", ...}`
2. **Child Creation**: Engine creates child workspace and schedules it
3. **Child Execution**: Child runs independently via global scheduler
4. **Child Completion**: Child sends `[subteam_result]{...}` message to parent
5. **Parent Processing**: Parent workspace is scheduled to process the result
6. **Event Trigger**: Unprocessed messages trigger `message` events automatically

## Benefits

1. **No Stack Overflow**: Arbitrarily deep hierarchies without recursion limits
2. **Parallel Execution**: Multiple child workspaces can execute concurrently
3. **Better Resource Management**: Workspaces execute independently
4. **Scalability**: Can handle thousands of workspaces without stack growth

## Entry Point

```python
engine = WorkspaceExecutionEngine(planner, workspace_manager)
await engine.run(root_workspace_id)
```

This schedules the root workspace and processes all workspaces (including children) via the global scheduler.

## Safety Features

1. **Re-entry Prevention**: Workspaces cannot be enqueued while running
2. **Max Iterations**: Global scheduler has a safety limit (1000 iterations)
3. **Execution Tracking**: `_running_workspaces` set prevents concurrent execution
4. **Message Deduplication**: Events are deduplicated to prevent reprocessing

