# Phase 3 Workflow Diagram ## Current Workflow (7 Nodes) → Target Workflow (11 Nodes) ``` ┌─────────────────────────────────────────────────────────────────────────┐ │ PHASE 3: AUTONOMOUS BUILD TEST │ │ Workflow ID: j1MmXaRhDjvkRSLa │ └─────────────────────────────────────────────────────────────────────────┘ ┌────────────────┐ │ [1] Gitea │ Webhook: /webhook/openhands-autonomous-build │ Webhook │ Trigger: Push events └────────┬───────┘ │ ▼ ┌────────────────┐ │ [2] Extract │ Code Node │ Repo Info │ Extract: repo_name, owner, branch, commit_sha └────────┬───────┘ │ ▼ ┌────────────────┐ │ [3] Initialize │ Code Node ★ NEW │ Retry Count │ Initialize: $workflow.staticData.retry_count = 0 └────────┬───────┘ │ ▼ ┌────────────────┐ │ [4] OpenHands │ SSH Node ★ MODIFIED │ Build │ - Enhanced task with error feedback │ - Data preservation pattern │ - Retry logic on loop back ▼ ┌────────────────┐ │ [5] Wait │ Wait Node (10 seconds) │ 10s │ └────────┬───────┘ │ ▼ ┌────────────────┐ │ [6] Check │ Code Node ★ MODIFIED │ Build │ Add: build_success, error_details │ Results │ └────────┬───────┘ │ ▼ ┌────────────────┐ │ [7] Decision │ IF Node ★ NEW │ Build OK? │ Condition: build_success == true └───────┬────────┘ │ ├──────────────────────┐ │ │ ▼ ▼ ┌───────────────┐ ┌──────────────────┐ │ [8] Update │ │ [9] Format Error│ Code Node ★ NEW │ Gitea │ │ for Retry │ Format: error_message │ Success │ │ │ └───────┬───────┘ └────────┬─────────┘ │ │ │ ▼ │ ┌──────────────────┐ │ │ [10] Check Retry│ IF Node ★ NEW │ │ Count │ Condition: can_retry == true │ └───────┬────────┘ │ │ │ ┌───────┴────────┐ │ │ │ │ ▼ ▼ │ ┌────────────────┐ ┌──────────────────┐ │ │ Loop back to │ │ [11] Final │ Code Node │ │ Node 4 │ │ Response │ ★ MODIFIED │ └────────────────┘ │ (Failure) │ │ └────────┬─────────┘ │ │ └────────────────────────────────────┘ │ ▼ ┌────────────────┐ │ [12] HTTP │ Respond to Webhook │ Response │ Status: 200/500 └────────────────┘ ═══════════════════════════════════════════════════════════════════════════ DATA FLOW PATTERNS ═══════════════════════════════════════════════════════════════════════════ [2] Extract Repo Info ───┐ │ Output: { [3] Initialize Retry ────┤ repo_name, owner, branch, │ commit_sha, retry_count [4] OpenHands ───────────┤ } ↓ │ [4] preserves data ──────┼──► return { │ ...repoData, ← PRESERVE │ code, stdout, │ stderr, status [6] Check Results ───────┤ } │ ↓ │ [7] Decision ────────────┼──► build_success? → true/false │ [8] Update Gitea ────────┤ On success → POST to Gitea API │ [9] Format Error ────────┤ On failure → Format comprehensive error │ [10] Retry Check ────────┤ can_retry? → true/false │ [4] Loop back ───────────┤ If true → Back to OpenHands with feedback │ If false → Final failure │ [11] Final Response ─────┴──► SUCCESS or FAILED with details ═══════════════════════════════════════════════════════════════════════════ RETRY FLOW DETAIL ═══════════════════════════════════════════════════════════════════════════ Attempt 1: [3] retry_count = 0 → [4] OpenHands (first attempt) → [6] Check → [7] FAIL → [9] Format Error → [10] Check: can_retry? YES (0 < 2) → Loop to [4] Attempt 2: [3] retry_count = 1 → [4] OpenHands (with error feedback) → [6] Check → [7] FAIL → [9] Format Error → [10] Check: can_retry? YES (1 < 2) → Loop to [4] Attempt 3: [3] retry_count = 2 → [4] OpenHands (with error feedback) → [6] Check → [7] FAIL → [9] Format Error → [10] Check: can_retry? NO (2 ≮ 2) → [11] Final Failure Stop: Max retries (3) exceeded ═══════════════════════════════════════════════════════════════════════════ SUCCESS FLOW ═══════════════════════════════════════════════════════════════════════════ Attempt 1 (Success): [3] retry_count = 0 → [4] OpenHands (first attempt) → [6] Check → [7] SUCCESS → [8] Update Gitea → [11] Final Response (Success) ═══════════════════════════════════════════════════════════════════════════ KEY IMPLEMENTATION NOTES ═══════════════════════════════════════════════════════════════════════════ ⚠️ CRITICAL: Data Preservation Pattern In Node 4 (SSH), ALWAYS preserve previous node data: ``` return { ...repoData, // ← This line is CRITICAL code: sshOutput.code, stdout: sshOutput.stdout, stderr: sshOutput.stderr }; ``` ⚠️ CRITICAL: Retry Counter Initialization In Node 3, MUST initialize staticData: ``` $workflow.staticData = $workflow.staticData || {}; $workflow.staticData.retry_count = ($workflow.staticData.retry_count || 0) + 1; ``` ⚠️ CRITICAL: Error Feedback Loop In Node 4, include previous errors in task: ``` if (retryCount > 0) { task += `PREVIOUS BUILD FAILED:\n${errorDetails}`; } ``` ═══════════════════════════════════════════════════════════════════════════ NODE CONFIGURATIONS ═══════════════════════════════════════════════════════════════════════════ Node Type Matrix: ┌──────┬─────────────────┬──────────────────────────────────────────────┐ │ Node │ Type │ Key Configuration │ ├──────┼─────────────────┼──────────────────────────────────────────────┤ │ 1 │ Webhook │ Path: /webhook/openhands-autonomous-build │ │ 2 │ Code │ Extract repo data │ │ 3 │ Code │ Initialize $workflow.staticData.retry_count │ │ 4 │ SSH │ Host: localhost, Timeout: 300000ms │ │ 5 │ Wait │ 10 seconds │ │ 6 │ Code │ Evaluate build_success │ │ 7 │ IF │ Condition: build_success == true │ │ 8 │ HTTP │ POST Gitea API │ │ 9 │ Code │ Format error with feedback │ │ 10 │ IF │ Condition: can_retry == true │ │ 11 │ Code │ Final SUCCESS/FAILED response │ │ 12 │ Respond to Web │ Return HTTP 200/500 │ └──────┴─────────────────┴──────────────────────────────────────────────┘ ═══════════════════════════════════════════════════════════════════════════ GITEA STATUS UPDATES ═══════════════════════════════════════════════════════════════════════════ Success Path (Node 8): POST https://git.oky.sh/api/v1/repos/{owner}/{repo}/statuses/{sha} Body: { "state": "success", "description": "✅ Build passed after {retry_count} attempt(s)", "context": "openhands/autonomous-build" } Failure Path (Node 11): POST https://git.oky.sh/api/v1/repos/{owner}/{repo}/statuses/{sha} Body: { "state": "failure", "description": "❌ Build failed after 3 attempts", "context": "openhands/autonomous-build" } ═══════════════════════════════════════════════════════════════════════════ EXECUTION TIMELINE ═══════════════════════════════════════════════════════════════════════════ Success (No Retry): T+0s → Webhook received T+5s → OpenHands starts build T+15s → Build complete, result checked T+16s → Gitea status updated T+17s → Response sent Success (After 2 Retries): T+0s → Webhook received T+5s → 1st OpenHands attempt T+15s → 1st failure, formatted T+20s → 2nd OpenHands attempt (with feedback) T+30s → 2nd failure, formatted T+35s → 3rd OpenHands attempt (with feedback) T+45s → 3rd success T+46s → Gitea status updated T+47s → Response sent Failure (Max Retries): T+0s → Webhook received T+5s → 1st OpenHands attempt T+15s → 1st failure T+20s → 2nd OpenHands attempt T+30s → 2nd failure T+35s → 3rd OpenHands attempt T+45s → 3rd failure T+46s → Gitea status updated (failure) T+47s → Response sent (max retries exceeded) ═══════════════════════════════════════════════════════════════════════════ FILE REFERENCES ═══════════════════════════════════════════════════════════════════════════ 📄 Documentation: - phase3.md (Original plan) - phase3-implementation-plan.md (Detailed guide) - phase3-code-snippets.md (Ready-to-copy code) - phase3-quickstart.md (Quick start) 🔧 Configuration: - n8n API Key: /home/bam/.n8n_api_key - SSH Key: /home/bam/.ssh/n8n_key - OpenHands: /home/bam/openhands-sdk-wrapper-sh.sh 🧪 Testing: - Test repo: autonomous-build-test - Webhook: /webhook/openhands-autonomous-build ═══════════════════════════════════════════════════════════════════════════