# Orchestrator - Dual-Agent Pipeline Architecture

主流程编排器：创建两个持久化 agent（规划和执行），流水线式处理所有 issue。

> **Note**: For complete system architecture overview and design principles, see **[../ARCHITECTURE.md](../ARCHITECTURE.md)**

## Architecture Overview

```
┌─────────────────────────────────────────────────────────┐
│        Main Orchestrator (Claude Code)                  │
│        流水线式分配任务给两个持久化 agent               │
└──────┬────────────────────────────────────────┬────────┘
       │ send_input                             │ send_input
       │ (逐个 issue)                           │ (逐个 solution)
       ▼                                        ▼
┌──────────────────┐                    ┌──────────────────┐
│ Planning Agent   │                    │ Execution Agent  │
│ (持久化)         │                    │ (持久化)         │
│                  │                    │                  │
│ • 接收 issue    │                    │ • 接收 solution │
│ • 设计方案      │                    │ • 执行 tasks   │
│ • 返回 solution │                    │ • 返回执行结果 │
└──────────────────┘                    └──────────────────┘
       ▲                                        ▲
       └────────────────┬─────────────────────┘
              wait for completion
```

## Main Orchestrator Pseudocode

```javascript
async function mainOrchestrator(workDir, issues) {
  const planningResults = { results: [] };  // 统一存储
  const executionResults = { results: [] }; // 统一存储

  // 1. Create persistent agents (never close until done)
  const planningAgentId = spawn_agent({
    message: Read('prompts/planning-agent-system.md')
  });

  const executionAgentId = spawn_agent({
    message: Read('prompts/execution-agent-system.md')
  });

  try {
    // Phase 1: Planning Pipeline
    for (const issue of issues) {
      // Send issue to planning agent (不新建 agent，用 send_input)
      send_input({
        id: planningAgentId,
        message: buildPlanningRequest(issue)
      });

      // Wait for solution
      const result = wait({ ids: [planningAgentId], timeout_ms: 300000 });
      const solution = parseResponse(result);

      // Store in unified results
      planningResults.results.push({
        issue_id: issue.id,
        solution: solution,
        status: solution ? "completed" : "failed"
      });
    }

    // Save planning results once
    Write(`${workDir}/planning-results.json`, JSON.stringify(planningResults, null, 2));

    // Phase 2: Execution Pipeline
    for (const planning of planningResults.results) {
      if (planning.status !== "completed") continue;

      // Send solution to execution agent (不新建 agent，用 send_input)
      send_input({
        id: executionAgentId,
        message: buildExecutionRequest(planning.solution)
      });

      // Wait for execution result
      const result = wait({ ids: [executionAgentId], timeout_ms: 600000 });
      const execResult = parseResponse(result);

      // Store in unified results
      executionResults.results.push({
        issue_id: planning.issue_id,
        status: execResult?.status || "failed",
        commit_hash: execResult?.commit_hash
      });
    }

    // Save execution results once
    Write(`${workDir}/execution-results.json`, JSON.stringify(executionResults, null, 2));

  } finally {
    // Close agents after ALL issues processed
    close_agent({ id: planningAgentId });
    close_agent({ id: executionAgentId });
  }

  generateFinalReport(workDir, planningResults, executionResults);
}
```

## Key Design Principles

### 1. Agent Persistence

- **Creating**: Each agent created once at the beginning
- **Running**: Agents continue running, receiving multiple `send_input` calls
- **Closing**: Agents closed only after all issues processed
- **Benefit**: Agent maintains context across multiple issues

### 2. Unified Results Storage

```json
// planning-results.json
{
  "phase": "planning",
  "created_at": "2025-01-29T12:00:00Z",
  "results": [
    {
      "issue_id": "ISS-001",
      "solution_id": "SOL-ISS-001-1",
      "status": "completed",
      "solution": { "id": "...", "tasks": [...] },
      "planned_at": "2025-01-29T12:05:00Z"
    },
    {
      "issue_id": "ISS-002",
      "solution_id": "SOL-ISS-002-1",
      "status": "completed",
      "solution": { "id": "...", "tasks": [...] },
      "planned_at": "2025-01-29T12:10:00Z"
    }
  ]
}

// execution-results.json
{
  "phase": "execution",
  "created_at": "2025-01-29T12:15:00Z",
  "results": [
    {
      "issue_id": "ISS-001",
      "solution_id": "SOL-ISS-001-1",
      "status": "completed",
      "commit_hash": "abc123def",
      "files_modified": ["src/auth.ts"],
      "executed_at": "2025-01-29T12:20:00Z"
    }
  ]
}
```

**优点**:
- 单一 JSON 文件，易于查询和分析
- 完整的处理历史
- 减少文件 I/O 次数

### 3. Pipeline Flow

```
Issue 1 → Planning Agent → Wait → Solution 1 (save)
Issue 2 → Planning Agent → Wait → Solution 2 (save)
Issue 3 → Planning Agent → Wait → Solution 3 (save)
[All saved to planning-results.json]

Solution 1 → Execution Agent → Wait → Result 1 (save)
Solution 2 → Execution Agent → Wait → Result 2 (save)
Solution 3 → Execution Agent → Wait → Result 3 (save)
[All saved to execution-results.json]
```

### 4. Agent Communication via send_input

Instead of creating new agents, reuse persistent ones:

```javascript
// ❌ OLD: Create new agent per issue
for (const issue of issues) {
  const agentId = spawn_agent({ message: prompt });
  const result = wait({ ids: [agentId] });
  close_agent({ id: agentId });  // ← Expensive!
}

// ✅ NEW: Persistent agent with send_input
const agentId = spawn_agent({ message: initialPrompt });
for (const issue of issues) {
  send_input({ id: agentId, message: taskPrompt });  // ← Reuse!
  const result = wait({ ids: [agentId] });
}
close_agent({ id: agentId });  // ← Single cleanup
```

### 5. Path Resolution for Global Installation

When this skill is installed globally:
- **Skill-internal paths**: Use relative paths from skill root (e.g., `prompts/planning-agent-system.md`)
- **Project paths**: Use project-relative paths starting with `.` (e.g., `.workflow/project-tech.json`)
- **User-home paths**: Use `~` prefix (e.g., `~/.codex/agents/...`)
- **Working directory**: Always relative to the project root when skill executes

## Benefits of This Architecture

| 方面 | 优势 |
|------|------|
| **性能** | Agent 创建/销毁开销仅一次（而非 N 次） |
| **上下文** | Agent 在多个任务间保持上下文 |
| **存储** | 统一的 JSON 文件，易于追踪和查询 |
| **通信** | 通过 send_input 实现 agent 间的数据传递 |
| **可维护性** | 流水线结构清晰，易于调试 |
