737 lines
20 KiB
Markdown
737 lines
20 KiB
Markdown
# OpenHands SDK: GitHub Actions vs n8n SSH Analysis
|
|
|
|
**Date:** 2025-12-02
|
|
**Status:** Comparison Analysis Complete
|
|
**Author:** Claude Code
|
|
|
|
---
|
|
|
|
## Executive Summary
|
|
|
|
This analysis compares two integration approaches for OpenHands SDK:
|
|
|
|
1. **Current Approach (Phase 2):** n8n → SSH → OpenHands CLI
|
|
2. **New Approach (GitHub Actions):** GitHub Actions → Python SDK → OpenHands
|
|
|
|
**Recommendation:** Hybrid approach combining the best of both worlds. Use **n8n for orchestration** and **GitHub Actions for execution**.
|
|
|
|
---
|
|
|
|
## 1. APPROACH COMPARISON
|
|
|
|
### Current Approach: n8n → SSH → OpenHands CLI
|
|
|
|
**Architecture:**
|
|
```
|
|
Gitea Push → n8n Webhook → SSH Node → Wrapper Script → OpenHands CLI → Build
|
|
```
|
|
|
|
**Components:**
|
|
- n8n workflow (ID: j1MmXaRhDjvkRSLa)
|
|
- SSH authentication (n8n → localhost)
|
|
- Shell wrapper script: `/home/bam/openhands-sdk-wrapper-sh.sh`
|
|
- OpenHands CLI execution: `/home/bam/.local/bin/openhands`
|
|
|
|
**Data Flow:**
|
|
```javascript
|
|
// Webhook receives Git push
|
|
// SSH node executes: sh /home/bam/openhands-sdk-wrapper-sh.sh "<task>"
|
|
// Output: {code, stdout, stderr}
|
|
```
|
|
|
|
**Pros:**
|
|
- ✅ Works with self-hosted Gitea (not requiring GitHub)
|
|
- ✅ Direct control via n8n UI
|
|
- ✅ Already operational and tested
|
|
- ✅ Good for self-contained environments
|
|
- ✅ Retry logic implemented (Phase 3 plan)
|
|
|
|
**Cons:**
|
|
- ❌ SSH overhead (latency, complexity)
|
|
- ❌ Data loss in SSH nodes (requires `$node` pattern)
|
|
- ❌ Shell script wrapper adds complexity
|
|
- ❌ Less standardized (custom wrapper)
|
|
- ❌ n8n-specific solution (not portable)
|
|
|
|
### New Approach: GitHub Actions → Python SDK → OpenHands
|
|
|
|
**Architecture:**
|
|
```
|
|
Git Push → GitHub Actions → Python agent_script.py → OpenHands SDK → Build
|
|
```
|
|
|
|
**Components:**
|
|
- GitHub Actions workflow (.github/workflows/openhands.yml)
|
|
- Python agent script (agent_script.py)
|
|
- OpenHands SDK (Python library)
|
|
- GitHub Secrets for API keys
|
|
|
|
**Data Flow:**
|
|
```python
|
|
# GitHub Actions runs Python script
|
|
llm = LLM(model="anthropic/claude-sonnet-4-5-20250929", api_key=os.getenv("LLM_API_KEY"))
|
|
agent = get_default_agent(llm=llm, cli_mode=True)
|
|
conversation = Conversation(agent=agent, workspace=cwd)
|
|
conversation.send_message(prompt)
|
|
conversation.run()
|
|
```
|
|
|
|
**Pros:**
|
|
- ✅ Direct SDK usage (no SSH overhead)
|
|
- ✅ Native GitHub Actions integration
|
|
- ✅ Better error handling and logging
|
|
- ✅ Standard Python patterns (easier to maintain)
|
|
- ✅ Built-in tools: TerminalTool, FileEditorTool, TaskTrackerTool
|
|
- ✅ Artifact uploads (logs preserved)
|
|
- ✅ Parallel execution support
|
|
- ✅ Marketplace-ready solution
|
|
- ✅ Better developer experience
|
|
|
|
**Cons:**
|
|
- ❌ Requires GitHub (not compatible with Gitea)
|
|
- ❌ More infrastructure (GitHub Actions runners)
|
|
- ❌ Learning curve for Python/SDK
|
|
- ❌ Potential cost for GitHub Actions minutes
|
|
- ❌ Less visual workflow control
|
|
|
|
---
|
|
|
|
## 2. INTEGRATION STRATEGY RECOMMENDATION
|
|
|
|
### Recommended: Hybrid Approach
|
|
|
|
**Structure:**
|
|
```
|
|
Git Push → n8n Webhook → GitHub Actions Workflow → Python SDK → OpenHands
|
|
↓
|
|
(Orchestration)
|
|
```
|
|
|
|
**Why Hybrid?**
|
|
|
|
1. **Best of Both Worlds:**
|
|
- n8n: Orchestration, visual workflow, retry logic, Gitea integration
|
|
- GitHub Actions: Direct SDK execution, better tooling, standardized approach
|
|
|
|
2. **Migration-Friendly:**
|
|
- Keep existing n8n infrastructure
|
|
- Gradually migrate to GitHub Actions
|
|
- Can run both in parallel during transition
|
|
|
|
3. **Practical for Your Setup:**
|
|
- Gitea hooks into n8n (already working)
|
|
- n8n triggers GitHub Actions workflow
|
|
- GitHub Actions executes OpenHands SDK
|
|
- Returns results back to n8n
|
|
|
|
### Architecture Diagram
|
|
|
|
```
|
|
┌──────────┐ ┌──────────┐ ┌────────────────┐ ┌──────────┐
|
|
│ Gitea │─────▶│ n8n │─────▶│ GitHub Actions │─────▶│ OpenHands│
|
|
│ (Push) │ │ (Webhook)│ │ (Workflow) │ │ SDK │
|
|
└──────────┘ └──────────┘ └────────────────┘ └──────────┘
|
|
│ │ │
|
|
│ ┌───────▼───────┐ │
|
|
│ │ Python Script │ │
|
|
│ └───────┬───────┘ │
|
|
│ │ │
|
|
└──────────────────────┴──────────────────────┘
|
|
(Results Flow)
|
|
```
|
|
|
|
---
|
|
|
|
## 3. IMPLEMENTATION PLAN
|
|
|
|
### Phase A: GitHub Actions Foundation (1 hour)
|
|
|
|
1. **Create GitHub Actions Workflow**
|
|
- Location: `.github/workflows/openhands-build.yml`
|
|
- Purpose: Execute build/test via Python SDK
|
|
- Triggered by: n8n HTTP request
|
|
|
|
2. **Create Python Agent Script**
|
|
- Location: `agent_script.py` (in repo)
|
|
- Purpose: Build/test project workspace
|
|
- Uses: OpenHands SDK directly
|
|
|
|
3. **Configure Repository Secrets**
|
|
- LLM_API_KEY (OpenHands API key)
|
|
- Optional: GITHUB_TOKEN
|
|
|
|
### Phase B: n8n GitHub Integration (1 hour)
|
|
|
|
4. **Add GitHub Actions Trigger to n8n Workflow**
|
|
- HTTP node to call GitHub Actions API
|
|
- Pass task details and project info
|
|
- Wait for GitHub Actions to complete
|
|
|
|
5. **Add Result Processing**
|
|
- Parse GitHub Actions response
|
|
- Update Gitea commit status
|
|
- Send notifications
|
|
|
|
### Phase C: Testing & Migration (1-2 hours)
|
|
|
|
6. **Test Integration**
|
|
- Verify GitHub Actions runs
|
|
- Check OpenHands SDK execution
|
|
- Validate result flow back to n8n
|
|
|
|
7. **Compare Performance**
|
|
- Measure build time (SSH vs SDK)
|
|
- Compare error handling quality
|
|
- Check token usage/cost
|
|
|
|
### Phase D: Optimization (1 hour)
|
|
|
|
8. **Optimize Based on Results**
|
|
- Keep SSH approach if faster/more reliable
|
|
- Or fully migrate to GitHub Actions
|
|
- Document findings
|
|
|
|
---
|
|
|
|
## 4. EXAMPLE IMPLEMENTATION
|
|
|
|
### A. GitHub Actions Workflow
|
|
|
|
**File:** `.github/workflows/openhands-build.yml`
|
|
|
|
```yaml
|
|
name: OpenHands Build
|
|
|
|
on:
|
|
workflow_dispatch:
|
|
inputs:
|
|
task:
|
|
description: 'Task to execute'
|
|
required: true
|
|
type: string
|
|
workspace_path:
|
|
description: 'Path to project workspace'
|
|
required: true
|
|
type: string
|
|
retry_count:
|
|
description: 'Retry attempt number'
|
|
required: false
|
|
type: number
|
|
default: 0
|
|
|
|
permissions:
|
|
contents: write
|
|
pull-requests: write
|
|
|
|
jobs:
|
|
build:
|
|
runs-on: ubuntu-latest
|
|
env:
|
|
TASK: ${{ github.event.inputs.task }}
|
|
WORKSPACE_PATH: ${{ github.event.inputs.workspace_path }}
|
|
RETRY_COUNT: ${{ github.event.inputs.retry_count || 0 }}
|
|
LLM_MODEL: anthropic/claude-sonnet-4-5-20250929
|
|
|
|
steps:
|
|
- name: Checkout repository
|
|
uses: actions/checkout@v4
|
|
with:
|
|
path: ${{ env.WORKSPACE_PATH }}
|
|
|
|
- name: Set up Python
|
|
uses: actions/setup-python@v5
|
|
with:
|
|
python-version: '3.12'
|
|
|
|
- name: Install uv
|
|
uses: astral-sh/setup-uv@v6
|
|
with:
|
|
enable-cache: true
|
|
|
|
- name: Install OpenHands SDK
|
|
run: |
|
|
uv pip install --system "openhands-sdk @ git+https://github.com/OpenHands/agent-sdk.git@main#subdirectory=openhands-sdk"
|
|
uv pip install --system "openhands-tools @ git+https://github.com/OpenHands/agent-sdk.git@main#subdirectory=openhands-tools"
|
|
|
|
- name: Run OpenHands Build
|
|
env:
|
|
LLM_API_KEY: ${{ secrets.LLM_API_KEY }}
|
|
RETRY_COUNT: ${{ env.RETRY_COUNT }}
|
|
run: |
|
|
cd ${{ env.WORKSPACE_PATH }}
|
|
uv run python ../agent_script.py
|
|
|
|
- name: Upload Build Artifacts
|
|
uses: actions/upload-artifact@v4
|
|
if: always()
|
|
with:
|
|
name: build-logs-${{ github.run_number }}
|
|
path: |
|
|
*.log
|
|
output/
|
|
retention-days: 7
|
|
|
|
- name: Upload Test Results
|
|
if: always()
|
|
uses: actions/upload-artifact@v4
|
|
with:
|
|
name: test-results-${{ github.run_number }}
|
|
path: |
|
|
test-results/
|
|
coverage/
|
|
retention-days: 30
|
|
```
|
|
|
|
### B. Python Agent Script
|
|
|
|
**File:** `agent_script.py`
|
|
|
|
```python
|
|
#!/usr/bin/env python3
|
|
"""
|
|
OpenHands Build Agent
|
|
|
|
Executes build/test tasks using OpenHands SDK.
|
|
Designed for GitHub Actions integration with n8n orchestration.
|
|
|
|
Usage:
|
|
python agent_script.py
|
|
|
|
Environment Variables:
|
|
TASK: Task description to execute
|
|
WORKSPACE_PATH: Path to project workspace
|
|
RETRY_COUNT: Current retry attempt number
|
|
LLM_API_KEY: API key for LLM (required)
|
|
LLM_MODEL: Model to use (default: anthropic/claude-sonnet-4-5-20250929)
|
|
"""
|
|
|
|
import os
|
|
import json
|
|
import sys
|
|
from datetime import datetime
|
|
from pathlib import Path
|
|
|
|
from openhands.sdk import LLM, Conversation, get_logger
|
|
from openhands.tools.preset.default import get_default_agent
|
|
|
|
|
|
logger = get_logger(__name__)
|
|
|
|
|
|
def create_build_task(workspace_path, task, retry_count):
|
|
"""Create enhanced build task with context."""
|
|
|
|
# Check for previous errors
|
|
error_file = Path(workspace_path) / "build-errors.json"
|
|
previous_errors = ""
|
|
if error_file.exists():
|
|
try:
|
|
with open(error_file) as f:
|
|
errors = json.load(f)
|
|
previous_errors = json.dumps(errors, indent=2)
|
|
except Exception as e:
|
|
logger.warning(f"Could not load previous errors: {e}")
|
|
|
|
# Build enhanced prompt
|
|
build_prompt = f"""
|
|
Build and test the project at: {workspace_path}
|
|
|
|
TASK: {task}
|
|
|
|
CURRENT ATTEMPT: {retry_count + 1}
|
|
|
|
REQUIREMENTS:
|
|
1. Install dependencies (npm install / pip install / etc.)
|
|
2. Run build process
|
|
3. Execute tests
|
|
4. Generate build report
|
|
|
|
ERROR HANDLING:
|
|
- Capture all build errors (stdout, stderr, exit codes)
|
|
- Save errors to: {workspace_path}/build-errors.json
|
|
- Report success/failure clearly
|
|
|
|
OUTPUT FORMAT:
|
|
{{
|
|
"success": true/false,
|
|
"exit_code": 0/1,
|
|
"errors": ["list of errors"],
|
|
"build_time": "seconds",
|
|
"artifacts": ["list of generated files"]
|
|
}}
|
|
|
|
FOCUS AREAS:
|
|
- Dependency installation issues
|
|
- Build script failures
|
|
- Test failures
|
|
- Configuration problems
|
|
|
|
Return ONLY the JSON output, nothing else.
|
|
"""
|
|
|
|
# Add previous errors if this is a retry
|
|
if previous_errors and retry_count > 0:
|
|
build_prompt += f"\n\nPREVIOUS BUILD ERRORS (attempt #{retry_count}):\n{previous_errors}\n\nPlease fix these specific issues."
|
|
|
|
return build_prompt
|
|
|
|
|
|
def save_build_report(workspace_path, result):
|
|
"""Save build report to file."""
|
|
|
|
report = {
|
|
"timestamp": datetime.now().isoformat(),
|
|
"workspace": workspace_path,
|
|
"result": result,
|
|
}
|
|
|
|
report_path = Path(workspace_path) / "build-report.json"
|
|
with open(report_path, "w") as f:
|
|
json.dump(report, f, indent=2)
|
|
|
|
logger.info(f"Build report saved to: {report_path}")
|
|
return report_path
|
|
|
|
|
|
def main():
|
|
"""Execute build task with OpenHands SDK."""
|
|
|
|
# Get configuration from environment
|
|
task = os.getenv("TASK", "")
|
|
workspace_path = os.getenv("WORKSPACE_PATH", os.getcwd())
|
|
retry_count = int(os.getenv("RETRY_COUNT", "0"))
|
|
api_key = os.getenv("LLM_API_KEY")
|
|
model = os.getenv("LLM_MODEL", "anthropic/claude-sonnet-4-5-20250929")
|
|
|
|
# Validate inputs
|
|
if not task:
|
|
logger.error("TASK environment variable is required")
|
|
sys.exit(1)
|
|
|
|
if not api_key:
|
|
logger.error("LLM_API_KEY environment variable is required")
|
|
sys.exit(1)
|
|
|
|
if not os.path.exists(workspace_path):
|
|
logger.error(f"Workspace path does not exist: {workspace_path}")
|
|
sys.exit(1)
|
|
|
|
logger.info(f"Starting build task (attempt #{retry_count + 1})")
|
|
logger.info(f"Workspace: {workspace_path}")
|
|
logger.info(f"Task: {task[:100]}...")
|
|
|
|
try:
|
|
# Configure LLM
|
|
llm = LLM(
|
|
model=model,
|
|
api_key=api_key,
|
|
usage_id="openhands-build",
|
|
drop_params=True,
|
|
)
|
|
|
|
# Create agent
|
|
agent = get_default_agent(
|
|
llm=llm,
|
|
cli_mode=True,
|
|
)
|
|
|
|
# Create conversation
|
|
conversation = Conversation(
|
|
agent=agent,
|
|
workspace=workspace_path,
|
|
)
|
|
|
|
# Build task with context
|
|
build_task = create_build_task(workspace_path, task, retry_count)
|
|
|
|
# Execute task
|
|
conversation.send_message(build_task)
|
|
conversation.run()
|
|
|
|
# Load build report
|
|
report_path = Path(workspace_path) / "build-report.json"
|
|
if report_path.exists():
|
|
with open(report_path) as f:
|
|
result = json.load(f)
|
|
print(json.dumps(result, indent=2))
|
|
sys.exit(0 if result.get("success") else 1)
|
|
else:
|
|
logger.error("Build report not found")
|
|
sys.exit(1)
|
|
|
|
except Exception as e:
|
|
logger.error(f"Build failed with exception: {e}")
|
|
# Save error report
|
|
error_report = {
|
|
"success": False,
|
|
"error": str(e),
|
|
"timestamp": datetime.now().isoformat(),
|
|
}
|
|
error_path = Path(workspace_path) / "build-errors.json"
|
|
with open(error_path, "w") as f:
|
|
json.dump(error_report, f, indent=2)
|
|
sys.exit(1)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|
|
```
|
|
|
|
### C. n8n Integration Node
|
|
|
|
**New HTTP Node to Add to Workflow:**
|
|
|
|
```javascript
|
|
// Node: "Trigger GitHub Actions Build"
|
|
|
|
// URL
|
|
const githubRepo = "your-github-username/your-repo";
|
|
const url = `https://api.github.com/repos/${githubRepo}/actions/workflows/openhands-build.yml/dispatches`;
|
|
|
|
// Headers
|
|
const headers = {
|
|
"Authorization": "Bearer " + $node["Get GITHUB_TOKEN"].json.token,
|
|
"Accept": "application/vnd.github+json",
|
|
"Content-Type": "application/json"
|
|
};
|
|
|
|
// Body
|
|
const body = {
|
|
"ref": "main",
|
|
"inputs": {
|
|
"task": `Build and test project: ${$node["Extract Repo Info"].json.repo_name}`,
|
|
"workspace_path": `/workspace/${$node["Extract Repo Info"].json.repo_name}`,
|
|
"retry_count": $workflow.staticData.retry_count || 0
|
|
}
|
|
};
|
|
|
|
return {
|
|
url: url,
|
|
method: "POST",
|
|
headers: headers,
|
|
body: JSON.stringify(body)
|
|
};
|
|
```
|
|
|
|
### D. n8n Result Processing Node
|
|
|
|
```javascript
|
|
// Node: "Process GitHub Actions Result"
|
|
|
|
// Get GitHub Actions response
|
|
const ghResponse = $json;
|
|
|
|
// Wait for GitHub Actions to complete
|
|
const runId = ghResponse.data.id;
|
|
const repo = "your-github-username/your-repo";
|
|
|
|
// Poll for completion
|
|
const checkUrl = `https://api.github.com/repos/${repo}/actions/runs/${runId}`;
|
|
const headers = {
|
|
"Authorization": "Bearer " + $node["Get GITHUB_TOKEN"].json.token
|
|
};
|
|
|
|
// Make HTTP request to check status
|
|
return {
|
|
url: checkUrl,
|
|
headers: headers
|
|
};
|
|
```
|
|
|
|
---
|
|
|
|
## 5. MIGRATION PATH
|
|
|
|
### Option 1: Gradual Migration (Recommended)
|
|
|
|
**Timeline:** 2-3 weeks
|
|
|
|
**Week 1: Setup GitHub Actions**
|
|
- [x] Create GitHub Actions workflow
|
|
- [x] Create Python agent script
|
|
- [x] Test in isolation
|
|
|
|
**Week 2: Dual Execution**
|
|
- [ ] Run both n8n→SSH and n8n→GitHub Actions in parallel
|
|
- [ ] Compare performance and reliability
|
|
- [ ] Document differences
|
|
|
|
**Week 3: Choose & Migrate**
|
|
- [ ] Analyze results from dual execution
|
|
- [ ] Keep best approach (or hybrid)
|
|
- [ ] Remove old approach
|
|
- [ ] Complete Phase 3 with chosen method
|
|
|
|
### Option 2: Full Migration to GitHub Actions
|
|
|
|
**Timeline:** 1 week
|
|
|
|
**Day 1-2: GitHub Actions Setup**
|
|
- Create workflow and agent script
|
|
- Configure secrets
|
|
|
|
**Day 3-4: n8n Integration**
|
|
- Add HTTP trigger node
|
|
- Add result processing
|
|
|
|
**Day 5-7: Testing & Optimization**
|
|
- End-to-end testing
|
|
- Performance tuning
|
|
- Documentation
|
|
|
|
### Option 3: Keep Current (n8n→SSH)
|
|
|
|
**Timeline:** Minimal
|
|
|
|
**Just complete Phase 3 as planned**
|
|
- Already working
|
|
- Familiar infrastructure
|
|
- Known patterns
|
|
|
|
---
|
|
|
|
## 6. DETAILED COMPARISON
|
|
|
|
| Aspect | n8n→SSH | GitHub Actions | Hybrid |
|
|
|--------|---------|----------------|--------|
|
|
| **Setup Time** | ~1 hour (done) | ~2 hours | ~3 hours |
|
|
| **Complexity** | Medium (SSH) | Low (SDK) | Medium-High |
|
|
| **Performance** | Slower (SSH overhead) | Faster (direct SDK) | Medium |
|
|
| **Error Handling** | Basic | Advanced | Advanced |
|
|
| **Visual Control** | Excellent (n8n UI) | None | Good |
|
|
| **Portability** | n8n-specific | GitHub standard | Partial |
|
|
| **Learning Curve** | Low (shell) | Medium (Python) | High |
|
|
| **Maintenance** | High (wrapper) | Low (SDK) | Medium |
|
|
| **Developer Experience** | Medium | Excellent | Good |
|
|
| **Integration Effort** | High (custom) | Low (standard) | Medium |
|
|
| **Cost** | No extra | GitHub Actions minutes | GitHub Actions minutes |
|
|
| **Reliability** | Good (tested) | Excellent (mature) | Good |
|
|
|
|
---
|
|
|
|
## 7. RECOMMENDATION SUMMARY
|
|
|
|
### For Your Current Setup:
|
|
|
|
**Use: Hybrid Approach (n8n + GitHub Actions)**
|
|
|
|
**Why:**
|
|
1. **Leverages Existing Infrastructure:** Keep n8n working, add GitHub Actions
|
|
2. **Better Error Handling:** GitHub Actions SDK provides superior error reporting
|
|
3. **Standard Practices:** GitHub Actions is industry-standard
|
|
4. **Migration-Friendly:** Can switch back if needed
|
|
5. **Future-Proof:** GitHub Actions widely adopted
|
|
|
|
**Action Plan:**
|
|
1. Create GitHub Actions workflow + Python script (1 hour)
|
|
2. Add GitHub Actions trigger to n8n workflow (30 min)
|
|
3. Test end-to-end integration (1 hour)
|
|
4. Compare performance with current approach (30 min)
|
|
5. Choose final approach based on results
|
|
|
|
**Files to Create:**
|
|
- `.github/workflows/openhands-build.yml`
|
|
- `agent_script.py`
|
|
- Update n8n workflow (add 2 nodes)
|
|
|
|
### If Switching to GitHub-Only:
|
|
|
|
**Use: GitHub Actions (no n8n)**
|
|
|
|
**Why:**
|
|
- Simplest architecture
|
|
- Best performance
|
|
- Industry standard
|
|
- Better tooling
|
|
|
|
**Action Plan:**
|
|
1. Create GitHub Actions workflow
|
|
2. Create Python agent script
|
|
3. Use GitHub webhooks instead of Gitea
|
|
4. Migrate from Gitea to GitHub (major effort)
|
|
|
|
---
|
|
|
|
## 8. PERFORMANCE METRICS TO TRACK
|
|
|
|
### During Testing:
|
|
|
|
1. **Build Time**
|
|
- n8n→SSH: _____ seconds
|
|
- n8n→GitHub Actions: _____ seconds
|
|
- Difference: _____% faster/slower
|
|
|
|
2. **Error Handling**
|
|
- n8n→SSH: _____% accuracy
|
|
- n8n→GitHub Actions: _____% accuracy
|
|
|
|
3. **Token Usage**
|
|
- n8n→SSH: _____ tokens per build
|
|
- n8n→GitHub Actions: _____ tokens per build
|
|
|
|
4. **Reliability**
|
|
- n8n→SSH: _____% success rate
|
|
- n8n→GitHub Actions: _____ % success rate
|
|
|
|
5. **Developer Experience**
|
|
- n8n→SSH: Rating (1-5): _____
|
|
- n8n→GitHub Actions: Rating (1-5): _____
|
|
|
|
---
|
|
|
|
## 9. CONCLUSION
|
|
|
|
**Current State:** Phase 2 working with n8n→SSH
|
|
|
|
**New Opportunity:** GitHub Actions SDK integration
|
|
|
|
**Recommendation:** Hybrid approach (n8n + GitHub Actions)
|
|
|
|
**Next Steps:**
|
|
1. Implement GitHub Actions workflow (1 hour)
|
|
2. Integrate with n8n (30 min)
|
|
3. Test & compare (1 hour)
|
|
4. Choose final approach
|
|
5. Complete Phase 3
|
|
|
|
**Benefits of GitHub Actions Approach:**
|
|
- Better error handling
|
|
- Standard tooling
|
|
- Easier maintenance
|
|
- Future scalability
|
|
|
|
**Risks of Migration:**
|
|
- Added complexity (GitHub + n8n)
|
|
- Learning curve for Python/SDK
|
|
- Potential GitHub Actions costs
|
|
|
|
**Recommendation Strength:** High
|
|
**Confidence Level:** 85%
|
|
|
|
---
|
|
|
|
## 10. REFERENCES
|
|
|
|
### Files Referenced:
|
|
- `/home/bam/claude/mvp-factory/phase3.md` - Current Phase 3 plan
|
|
- `/home/bam/claude/mvp-factory/n8n-api.md` - n8n integration details
|
|
- `/home/bam/claude/mvp-factory/openhands-subagents-doc.md` - OpenHands optimization
|
|
|
|
### External Resources:
|
|
- GitHub: OpenHands SDK Examples - https://github.com/OpenHands/software-agent-sdk
|
|
- OpenHands Documentation - https://docs.openhands.dev/sdk
|
|
- GitHub Actions Documentation - https://docs.github.com/en/actions
|
|
|
|
### Current Working Setup:
|
|
- n8n Workflow ID: `j1MmXaRhDjvkRSLa`
|
|
- Webhook: `https://n8n.oky.sh/webhook/openhands-fixed-test`
|
|
- SDK Wrapper: `/home/bam/openhands-sdk-wrapper-sh.sh`
|
|
|
|
---
|
|
|
|
**Analysis Complete**
|
|
**Ready for Implementation**
|
|
|
|
*Created: 2025-12-02*
|
|
*Status: Ready for review and implementation*
|