mvp-factory-openhands/openhands-workflow-with-ver...

366 lines
10 KiB
JSON

{
"name": "OpenHands API Test - With File Verification",
"nodes": [
{
"parameters": {},
"id": "manual-trigger",
"name": "Manual Trigger",
"type": "n8n-nodes-base.manualTrigger",
"typeVersion": 1,
"position": [240, 300]
},
{
"parameters": {
"jsCode": "// Initialize retry counter in workflow data\nreturn {\n retry_count: 0,\n max_retries: 15,\n initialized: true,\n timestamp: new Date().toISOString()\n};"
},
"id": "init-workflow",
"name": "Initialize Workflow",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [460, 300]
},
{
"parameters": {
"url": "http://10.10.10.11:3000/api/conversations",
"method": "POST",
"sendBody": true,
"bodyParameters": {
"parameters": [
{
"name": "initial_user_msg",
"value": "Create a file named hello.txt with content: Hello from n8n! This is a test."
}
]
},
"options": {
"response": {
"response": {
"responseFormat": "json"
}
}
}
},
"id": "create-conversation",
"name": "1. Create Conversation",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [680, 300]
},
{
"parameters": {
"url": "=http://10.10.10.11:3000/api/conversations/{{ $json.conversation_id }}/start",
"method": "POST",
"sendBody": true,
"specifyBody": "json",
"jsonBody": "={}",
"options": {
"response": {
"response": {
"responseFormat": "json"
}
}
}
},
"id": "start-conversation",
"name": "2. Start Agent Loop",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [900, 300]
},
{
"parameters": {
"amount": 10,
"unit": "seconds"
},
"id": "wait-10s",
"name": "3. Wait 10s",
"type": "n8n-nodes-base.wait",
"typeVersion": 1.1,
"position": [1120, 300],
"webhookId": "wait-10s"
},
{
"parameters": {
"url": "=http://10.10.10.11:3000/api/conversations/{{ $('1. Create Conversation').item.json.conversation_id }}",
"method": "GET",
"options": {
"response": {
"response": {
"responseFormat": "json"
}
}
}
},
"id": "get-status",
"name": "4. Check Status",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [1340, 300]
},
{
"parameters": {
"conditions": {
"options": {
"combineOperation": "any"
},
"conditions": [
{
"id": "status-running",
"leftValue": "={{ $json.status }}",
"rightValue": "RUNNING",
"operator": {
"type": "string",
"operation": "equals"
}
},
{
"id": "status-stopped",
"leftValue": "={{ $json.status }}",
"rightValue": "STOPPED",
"operator": {
"type": "string",
"operation": "equals"
}
},
{
"id": "status-awaiting",
"leftValue": "={{ $json.status }}",
"rightValue": "AWAITING_USER_INPUT",
"operator": {
"type": "string",
"operation": "equals"
}
}
]
},
"options": {}
},
"id": "check-ready",
"name": "5. Is Ready?",
"type": "n8n-nodes-base.if",
"typeVersion": 2,
"position": [1560, 300]
},
{
"parameters": {
"amount": 15,
"unit": "seconds"
},
"id": "wait-retry",
"name": "Wait 15s Retry",
"type": "n8n-nodes-base.wait",
"typeVersion": 1.1,
"position": [1780, 180],
"webhookId": "wait-retry"
},
{
"parameters": {
"jsCode": "// Get retry count from input or default to 0\nconst currentRetries = $input.item.json.retry_count || 0;\nconst maxRetries = 15; // 15 * 15s = ~4 minutes\n\nif (currentRetries >= maxRetries) {\n throw new Error('Timeout: Agent did not start within 4 minutes');\n}\n\nconst convId = $('1. Create Conversation').item.json.conversation_id;\n\nreturn {\n conversation_id: convId,\n retry_count: currentRetries + 1\n};"
},
"id": "retry-counter",
"name": "Retry Counter",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [2000, 180]
},
{
"parameters": {
"url": "=http://10.10.10.11:3000/api/conversations/{{ $('1. Create Conversation').item.json.conversation_id }}/events",
"method": "GET",
"options": {
"response": {
"response": {
"responseFormat": "json"
}
}
}
},
"id": "get-events",
"name": "6. Get Events",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [1780, 420]
},
{
"parameters": {
"jsCode": "// Extract conversation results\nconst events = $input.item.json.events || [];\nconst convId = $('1. Create Conversation').item.json.conversation_id;\nconst status = $('4. Check Status').item.json.status;\n\n// Check for file creation in events\nconst fileCreated = events.some(e => \n e.message?.includes('hello.txt') || \n e.observation?.includes('hello.txt')\n);\n\n// Get last few events\nconst recentEvents = events.slice(-5).map(e => ({\n timestamp: e.timestamp,\n source: e.source,\n observation: e.observation,\n message: e.message?.substring(0, 100)\n}));\n\nreturn {\n conversation_id: convId,\n status: status,\n total_events: events.length,\n file_created: fileCreated,\n recent_events: recentEvents,\n success: fileCreated && (status === 'STOPPED' || status === 'AWAITING_USER_INPUT')\n};"
},
"id": "analyze-results",
"name": "7. Analyze Results",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [2000, 420]
},
{
"parameters": {
"command": "=ls -la /home/bam/workspace/hello.txt 2>&1 && echo '---FILE CONTENT---' && cat /home/bam/workspace/hello.txt 2>&1 || echo 'File not found'"
},
"id": "verify-file",
"name": "8. Verify File Created",
"type": "n8n-nodes-base.executeCommand",
"typeVersion": 1,
"position": [2220, 420]
},
{
"parameters": {
"jsCode": "// Parse command output to verify file\nconst commandOutput = $input.item.json.stdout || $input.item.json.stderr || JSON.stringify($input.item.json);\nconst analysisData = $('7. Analyze Results').item.json;\n\n// Check if file exists and has content\nconst fileExists = commandOutput.includes('hello.txt') && !commandOutput.includes('File not found');\nconst hasContent = commandOutput.includes('Hello from n8n');\n\nreturn {\n conversation_id: analysisData.conversation_id,\n status: analysisData.status,\n total_events: analysisData.total_events,\n file_verified: fileExists,\n content_correct: hasContent,\n file_output: commandOutput,\n overall_success: fileExists && hasContent,\n message: fileExists && hasContent ? \n '✅ SUCCESS: File created and verified!' : \n '❌ FAILED: File not found or incorrect content'\n};"
},
"id": "final-verification",
"name": "9. Final Verification",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [2440, 420]
}
],
"connections": {
"Manual Trigger": {
"main": [
[
{
"node": "Initialize Workflow",
"type": "main",
"index": 0
}
]
]
},
"Initialize Workflow": {
"main": [
[
{
"node": "1. Create Conversation",
"type": "main",
"index": 0
}
]
]
},
"1. Create Conversation": {
"main": [
[
{
"node": "2. Start Agent Loop",
"type": "main",
"index": 0
}
]
]
},
"2. Start Agent Loop": {
"main": [
[
{
"node": "3. Wait 10s",
"type": "main",
"index": 0
}
]
]
},
"3. Wait 10s": {
"main": [
[
{
"node": "4. Check Status",
"type": "main",
"index": 0
}
]
]
},
"4. Check Status": {
"main": [
[
{
"node": "5. Is Ready?",
"type": "main",
"index": 0
}
]
]
},
"5. Is Ready?": {
"main": [
[
{
"node": "6. Get Events",
"type": "main",
"index": 0
}
],
[
{
"node": "Wait 15s Retry",
"type": "main",
"index": 0
}
]
]
},
"Wait 15s Retry": {
"main": [
[
{
"node": "Retry Counter",
"type": "main",
"index": 0
}
]
]
},
"Retry Counter": {
"main": [
[
{
"node": "4. Check Status",
"type": "main",
"index": 0
}
]
]
},
"6. Get Events": {
"main": [
[
{
"node": "7. Analyze Results",
"type": "main",
"index": 0
}
]
]
},
"7. Analyze Results": {
"main": [
[
{
"node": "8. Verify File Created",
"type": "main",
"index": 0
}
]
]
},
"8. Verify File Created": {
"main": [
[
{
"node": "9. Final Verification",
"type": "main",
"index": 0
}
]
]
}
},
"pinData": {},
"settings": {
"executionOrder": "v1"
},
"staticData": null,
"tags": [],
"triggerCount": 0,
"updatedAt": "2025-11-30T08:30:00.000Z",
"versionId": "1"
}