diff --git a/openhands-workflow-fixed.json b/openhands-workflow-fixed.json new file mode 100644 index 0000000..540d282 --- /dev/null +++ b/openhands-workflow-fixed.json @@ -0,0 +1,302 @@ +{ + "name": "OpenHands API Test - Fixed", + "nodes": [ + { + "parameters": {}, + "id": "manual-trigger", + "name": "Manual Trigger", + "type": "n8n-nodes-base.manualTrigger", + "typeVersion": 1, + "position": [240, 300] + }, + { + "parameters": { + "url": "http://172.18.0.1: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": [460, 300] + }, + { + "parameters": { + "url": "=http://172.18.0.1: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": [680, 300] + }, + { + "parameters": { + "amount": 10, + "unit": "seconds" + }, + "id": "wait-10s", + "name": "3. Wait 10s", + "type": "n8n-nodes-base.wait", + "typeVersion": 1.1, + "position": [900, 300], + "webhookId": "wait-10s" + }, + { + "parameters": { + "url": "=http://172.18.0.1: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": [1120, 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": [1340, 300] + }, + { + "parameters": { + "amount": 15, + "unit": "seconds" + }, + "id": "wait-retry", + "name": "Wait 15s Retry", + "type": "n8n-nodes-base.wait", + "typeVersion": 1.1, + "position": [1560, 180], + "webhookId": "wait-retry" + }, + { + "parameters": { + "jsCode": "// Retry counter with max retries\nconst retries = $workflow.staticData.retries || 0;\nconst maxRetries = 15; // 15 * 15s = ~4 minutes\n\nif (retries >= maxRetries) {\n throw new Error('Timeout: Agent did not start within 4 minutes');\n}\n\n$workflow.staticData.retries = retries + 1;\n\nconst convId = $('1. Create Conversation').item.json.conversation_id;\n\nreturn {\n conversation_id: convId,\n retry_count: retries + 1\n};" + }, + "id": "retry-counter", + "name": "Retry Counter", + "type": "n8n-nodes-base.code", + "typeVersion": 2, + "position": [1780, 180] + }, + { + "parameters": { + "url": "=http://172.18.0.1: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": [1560, 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\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": [1780, 420] + } + ], + "connections": { + "Manual Trigger": { + "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 + } + ] + ] + } + }, + "pinData": {}, + "settings": { + "executionOrder": "v1" + }, + "staticData": null, + "tags": [], + "triggerCount": 0, + "updatedAt": "2025-11-29T20:30:00.000Z", + "versionId": "1" +}