Spaces:
No application file
No application file
Timothy Eastridge commited on
Commit ·
ead5455
1
Parent(s): 28e46ad
commit step 10
Browse files- ops/scripts/acceptance_test.md +145 -0
- ops/scripts/demo.ps1 +108 -0
- ops/scripts/demo.sh +74 -0
- ops/scripts/validate.py +180 -0
ops/scripts/acceptance_test.md
ADDED
|
@@ -0,0 +1,145 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# MVP Acceptance Test Checklist
|
| 2 |
+
|
| 3 |
+
## Pre-requisites
|
| 4 |
+
- [ ] Docker and Docker Compose installed
|
| 5 |
+
- [ ] LLM API key configured in `.env`
|
| 6 |
+
- [ ] All containers running (`docker-compose up -d`)
|
| 7 |
+
|
| 8 |
+
## Test Scenarios
|
| 9 |
+
|
| 10 |
+
### Scenario 1: Basic Query Flow
|
| 11 |
+
1. [ ] Open http://localhost:3000
|
| 12 |
+
2. [ ] Type: "Show all customers"
|
| 13 |
+
3. [ ] Verify workflow created message appears
|
| 14 |
+
4. [ ] Verify graph visualization updates
|
| 15 |
+
5. [ ] Wait for results (may take 5+ minutes due to pauses)
|
| 16 |
+
6. [ ] Verify table with customer data appears
|
| 17 |
+
7. [ ] Verify SQL query is displayed
|
| 18 |
+
|
| 19 |
+
### Scenario 2: Human Intervention
|
| 20 |
+
1. [ ] Start new query: "Count all orders"
|
| 21 |
+
2. [ ] During the 5-minute pause (watch agent logs)
|
| 22 |
+
3. [ ] Open Neo4j Browser: http://localhost:7474
|
| 23 |
+
4. [ ] Run query: `MATCH (i:Instruction {status: 'pending', type: 'generate_sql'}) RETURN i`
|
| 24 |
+
5. [ ] Edit instruction: `SET i.parameters = '{"question": "Count orders with status completed"}'`
|
| 25 |
+
6. [ ] Verify agent uses modified query after pause
|
| 26 |
+
7. [ ] Verify results reflect the change
|
| 27 |
+
|
| 28 |
+
### Scenario 3: Stop Workflow
|
| 29 |
+
1. [ ] Start query: "Find expensive orders"
|
| 30 |
+
2. [ ] Click STOP button during execution
|
| 31 |
+
3. [ ] Verify workflow stops
|
| 32 |
+
4. [ ] Check Neo4j: `MATCH (w:Workflow) RETURN w.status` shows 'stopped'
|
| 33 |
+
|
| 34 |
+
### Scenario 4: Graph Visualization
|
| 35 |
+
1. [ ] Start any query
|
| 36 |
+
2. [ ] Verify workflow node appears (blue/gray)
|
| 37 |
+
3. [ ] Verify instruction nodes appear
|
| 38 |
+
4. [ ] Verify colors change:
|
| 39 |
+
- Gray = pending
|
| 40 |
+
- Yellow = executing
|
| 41 |
+
- Green = complete
|
| 42 |
+
5. [ ] Click on node shows properties
|
| 43 |
+
|
| 44 |
+
### Scenario 5: Audit Trail
|
| 45 |
+
1. [ ] After running queries, open Neo4j Browser
|
| 46 |
+
2. [ ] Run: `MATCH (l:Log) RETURN l ORDER BY l.timestamp DESC LIMIT 10`
|
| 47 |
+
3. [ ] Verify all MCP operations are logged
|
| 48 |
+
4. [ ] Run: `MATCH (e:Execution) RETURN e`
|
| 49 |
+
5. [ ] Verify all executions have results
|
| 50 |
+
|
| 51 |
+
## Performance Checks
|
| 52 |
+
- [ ] Agent processes instructions within 30 seconds of becoming available
|
| 53 |
+
- [ ] Frontend responds within 1 second
|
| 54 |
+
- [ ] Graph updates within 10 seconds
|
| 55 |
+
- [ ] No memory leaks after 10+ queries
|
| 56 |
+
|
| 57 |
+
## Data Validation
|
| 58 |
+
Run these queries in Neo4j Browser:
|
| 59 |
+
|
| 60 |
+
```cypher
|
| 61 |
+
// Check schema discovered
|
| 62 |
+
MATCH (t:Table) RETURN t.name
|
| 63 |
+
|
| 64 |
+
// Check instructions executed
|
| 65 |
+
MATCH (i:Instruction)-[:EXECUTED_AS]->(e:Execution)
|
| 66 |
+
RETURN i.type, i.status, e.completed_at
|
| 67 |
+
|
| 68 |
+
// Check successful SQL generation
|
| 69 |
+
MATCH (qt:QueryTemplate)
|
| 70 |
+
RETURN qt.query, qt.created_at
|
| 71 |
+
ORDER BY qt.created_at DESC
|
| 72 |
+
LIMIT 5
|
| 73 |
+
|
| 74 |
+
// Check workflow completion rate
|
| 75 |
+
MATCH (w:Workflow)
|
| 76 |
+
RETURN w.status, count(w) as count
|
| 77 |
+
```
|
| 78 |
+
|
| 79 |
+
## Sign-off
|
| 80 |
+
- [ ] All test scenarios pass
|
| 81 |
+
- [ ] No errors in container logs
|
| 82 |
+
- [ ] System recovers from agent restart
|
| 83 |
+
- [ ] Clean startup from `docker-compose down && docker-compose up -d`
|
| 84 |
+
|
| 85 |
+
**Tester:** _________________
|
| 86 |
+
**Date:** _________________
|
| 87 |
+
**Version:** MVP 1.0
|
| 88 |
+
|
| 89 |
+
---
|
| 90 |
+
|
| 91 |
+
## Final validation commands:
|
| 92 |
+
|
| 93 |
+
```bash
|
| 94 |
+
# Complete test sequence
|
| 95 |
+
docker-compose down
|
| 96 |
+
docker-compose up -d
|
| 97 |
+
sleep 10
|
| 98 |
+
|
| 99 |
+
# Check health
|
| 100 |
+
curl -s http://localhost:8000/health && echo "MCP: OK"
|
| 101 |
+
curl -s http://localhost:3000 > /dev/null && echo "Frontend: OK"
|
| 102 |
+
|
| 103 |
+
# Seed data
|
| 104 |
+
docker-compose exec mcp python /app/ops/scripts/seed.py
|
| 105 |
+
|
| 106 |
+
# Run automated validation
|
| 107 |
+
docker-compose exec mcp python /app/ops/scripts/validate.py
|
| 108 |
+
|
| 109 |
+
# Run demo
|
| 110 |
+
bash ops/scripts/demo.sh
|
| 111 |
+
|
| 112 |
+
# In another terminal, watch all logs
|
| 113 |
+
docker-compose logs -f
|
| 114 |
+
|
| 115 |
+
# Manual test in another terminal
|
| 116 |
+
curl -X POST http://localhost:8000/mcp \
|
| 117 |
+
-H "Content-Type: application/json" \
|
| 118 |
+
-H "X-API-Key: dev-key-123" \
|
| 119 |
+
-d '{
|
| 120 |
+
"tool": "write_graph",
|
| 121 |
+
"params": {
|
| 122 |
+
"action": "create_node",
|
| 123 |
+
"label": "Instruction",
|
| 124 |
+
"properties": {
|
| 125 |
+
"id": "final-test",
|
| 126 |
+
"type": "generate_sql",
|
| 127 |
+
"status": "pending",
|
| 128 |
+
"sequence": 999,
|
| 129 |
+
"pause_duration": 30,
|
| 130 |
+
"parameters": "{\"question\": \"What is the total revenue from all orders?\"}"
|
| 131 |
+
}
|
| 132 |
+
}
|
| 133 |
+
}'
|
| 134 |
+
|
| 135 |
+
# Check execution after ~30 seconds
|
| 136 |
+
curl -X POST http://localhost:8000/mcp \
|
| 137 |
+
-H "Content-Type: application/json" \
|
| 138 |
+
-H "X-API-Key: dev-key-123" \
|
| 139 |
+
-d '{
|
| 140 |
+
"tool": "query_graph",
|
| 141 |
+
"params": {
|
| 142 |
+
"query": "MATCH (i:Instruction {id: \"final-test\"})-[:EXECUTED_AS]->(e:Execution) RETURN e.result"
|
| 143 |
+
}
|
| 144 |
+
}'
|
| 145 |
+
```
|
ops/scripts/demo.ps1
ADDED
|
@@ -0,0 +1,108 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Graph-Driven Agent Demo Script for PowerShell
|
| 2 |
+
# Run this with: powershell -ExecutionPolicy Bypass -File ops/scripts/demo.ps1
|
| 3 |
+
|
| 4 |
+
Write-Host "🚀 Graph-Driven Agent Demo" -ForegroundColor Green
|
| 5 |
+
Write-Host "=========================" -ForegroundColor Green
|
| 6 |
+
Write-Host ""
|
| 7 |
+
|
| 8 |
+
Write-Host "Step 1: Starting services..." -ForegroundColor Blue
|
| 9 |
+
docker-compose up -d
|
| 10 |
+
Start-Sleep 10
|
| 11 |
+
|
| 12 |
+
Write-Host "Step 2: Checking health..." -ForegroundColor Blue
|
| 13 |
+
|
| 14 |
+
Write-Host "Checking Neo4j..." -ForegroundColor Cyan
|
| 15 |
+
docker-compose exec neo4j cypher-shell -u neo4j -p password "MATCH (n) RETURN count(n) LIMIT 1" 2>$null
|
| 16 |
+
if ($LASTEXITCODE -eq 0) {
|
| 17 |
+
Write-Host "✅ Neo4j: Healthy" -ForegroundColor Green
|
| 18 |
+
} else {
|
| 19 |
+
Write-Host "❌ Neo4j: Unhealthy" -ForegroundColor Red
|
| 20 |
+
}
|
| 21 |
+
|
| 22 |
+
Write-Host "Checking PostgreSQL..." -ForegroundColor Cyan
|
| 23 |
+
docker-compose exec postgres pg_isready -U postgres 2>$null
|
| 24 |
+
if ($LASTEXITCODE -eq 0) {
|
| 25 |
+
Write-Host "✅ PostgreSQL: Healthy" -ForegroundColor Green
|
| 26 |
+
} else {
|
| 27 |
+
Write-Host "❌ PostgreSQL: Unhealthy" -ForegroundColor Red
|
| 28 |
+
}
|
| 29 |
+
|
| 30 |
+
Write-Host "Checking MCP Server..." -ForegroundColor Cyan
|
| 31 |
+
try {
|
| 32 |
+
$response = Invoke-WebRequest -Uri "http://localhost:8000/health" -UseBasicParsing -TimeoutSec 5
|
| 33 |
+
if ($response.StatusCode -eq 200) {
|
| 34 |
+
Write-Host "✅ MCP Server: Healthy" -ForegroundColor Green
|
| 35 |
+
} else {
|
| 36 |
+
Write-Host "❌ MCP Server: Unhealthy" -ForegroundColor Red
|
| 37 |
+
}
|
| 38 |
+
} catch {
|
| 39 |
+
Write-Host "❌ MCP Server: Unhealthy" -ForegroundColor Red
|
| 40 |
+
}
|
| 41 |
+
|
| 42 |
+
Write-Host "Checking Frontend..." -ForegroundColor Cyan
|
| 43 |
+
try {
|
| 44 |
+
$response = Invoke-WebRequest -Uri "http://localhost:3000" -UseBasicParsing -TimeoutSec 5
|
| 45 |
+
if ($response.StatusCode -eq 200) {
|
| 46 |
+
Write-Host "✅ Frontend: Healthy" -ForegroundColor Green
|
| 47 |
+
} else {
|
| 48 |
+
Write-Host "❌ Frontend: Unhealthy" -ForegroundColor Red
|
| 49 |
+
}
|
| 50 |
+
} catch {
|
| 51 |
+
Write-Host "❌ Frontend: Unhealthy" -ForegroundColor Red
|
| 52 |
+
}
|
| 53 |
+
|
| 54 |
+
Write-Host "Checking Agent..." -ForegroundColor Cyan
|
| 55 |
+
$agentStatus = docker-compose ps agent | Select-String "Up"
|
| 56 |
+
if ($agentStatus) {
|
| 57 |
+
Write-Host "✅ Agent: Running" -ForegroundColor Green
|
| 58 |
+
} else {
|
| 59 |
+
Write-Host "❌ Agent: Not running" -ForegroundColor Red
|
| 60 |
+
}
|
| 61 |
+
|
| 62 |
+
Write-Host ""
|
| 63 |
+
Write-Host "Step 3: Seeding demo workflow..." -ForegroundColor Blue
|
| 64 |
+
docker-compose exec mcp python /app/ops/scripts/seed.py
|
| 65 |
+
|
| 66 |
+
Write-Host ""
|
| 67 |
+
Write-Host "✅ Demo environment ready!" -ForegroundColor Green
|
| 68 |
+
Write-Host ""
|
| 69 |
+
Write-Host "📝 Demo Instructions:" -ForegroundColor Yellow
|
| 70 |
+
Write-Host "-------------------" -ForegroundColor Yellow
|
| 71 |
+
Write-Host "1. Open http://localhost:3000 in your browser" -ForegroundColor White
|
| 72 |
+
Write-Host ""
|
| 73 |
+
Write-Host "2. In the chat, type: 'Show me customers who have ordered more than `$100'" -ForegroundColor White
|
| 74 |
+
Write-Host ""
|
| 75 |
+
Write-Host "3. You'll see:" -ForegroundColor White
|
| 76 |
+
Write-Host " - 'Workflow created!' message" -ForegroundColor Gray
|
| 77 |
+
Write-Host " - Graph visualization showing workflow nodes" -ForegroundColor Gray
|
| 78 |
+
Write-Host " - Status showing 'Agent thinking...'" -ForegroundColor Gray
|
| 79 |
+
Write-Host ""
|
| 80 |
+
Write-Host "4. The agent will:" -ForegroundColor White
|
| 81 |
+
Write-Host " - Pause for 5 minutes (or configured duration)" -ForegroundColor Gray
|
| 82 |
+
Write-Host " - Discover PostgreSQL schema" -ForegroundColor Gray
|
| 83 |
+
Write-Host " - Generate SQL query" -ForegroundColor Gray
|
| 84 |
+
Write-Host " - Execute and return results" -ForegroundColor Gray
|
| 85 |
+
Write-Host ""
|
| 86 |
+
Write-Host "5. During the pause, you can:" -ForegroundColor White
|
| 87 |
+
Write-Host " - Open Neo4j Browser: http://localhost:7474" -ForegroundColor Gray
|
| 88 |
+
Write-Host " - Login: neo4j/password" -ForegroundColor Gray
|
| 89 |
+
Write-Host " - Run: MATCH (i:Instruction {status: 'pending'}) RETURN i" -ForegroundColor Gray
|
| 90 |
+
Write-Host " - Edit parameters to change the query" -ForegroundColor Gray
|
| 91 |
+
Write-Host ""
|
| 92 |
+
Write-Host "6. After execution completes:" -ForegroundColor White
|
| 93 |
+
Write-Host " - Results appear in a table" -ForegroundColor Gray
|
| 94 |
+
Write-Host " - Generated SQL is shown" -ForegroundColor Gray
|
| 95 |
+
Write-Host " - Graph shows all nodes as green (complete)" -ForegroundColor Gray
|
| 96 |
+
Write-Host ""
|
| 97 |
+
Write-Host "Optional: Edit instruction during pause" -ForegroundColor Yellow
|
| 98 |
+
Write-Host "docker-compose exec neo4j cypher-shell -u neo4j -p password \"
|
| 99 |
+
Write-Host " \"MATCH (i:Instruction {type: 'generate_sql', status: 'pending'}) \"
|
| 100 |
+
Write-Host " SET i.parameters = '{\"question\": \"Count all orders\"}'\""
|
| 101 |
+
Write-Host ""
|
| 102 |
+
Write-Host "🎉 DEMO IS RUNNING!" -ForegroundColor Green
|
| 103 |
+
Write-Host "Press Ctrl+C to stop monitoring logs." -ForegroundColor Yellow
|
| 104 |
+
Write-Host ""
|
| 105 |
+
|
| 106 |
+
# Keep running and show agent logs
|
| 107 |
+
Write-Host "Monitoring agent logs..." -ForegroundColor Blue
|
| 108 |
+
docker-compose logs -f agent
|
ops/scripts/demo.sh
ADDED
|
@@ -0,0 +1,74 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/bin/bash
|
| 2 |
+
|
| 3 |
+
echo "🚀 Graph-Driven Agent Demo"
|
| 4 |
+
echo "========================="
|
| 5 |
+
echo ""
|
| 6 |
+
|
| 7 |
+
# Colors for output
|
| 8 |
+
GREEN='\033[0;32m'
|
| 9 |
+
BLUE='\033[0;34m'
|
| 10 |
+
YELLOW='\033[1;33m'
|
| 11 |
+
NC='\033[0m' # No Color
|
| 12 |
+
|
| 13 |
+
echo -e "${BLUE}Step 1: Starting services...${NC}"
|
| 14 |
+
docker-compose up -d
|
| 15 |
+
sleep 10
|
| 16 |
+
|
| 17 |
+
echo -e "${BLUE}Step 2: Checking health...${NC}"
|
| 18 |
+
echo "Checking Neo4j..."
|
| 19 |
+
docker-compose exec neo4j cypher-shell -u neo4j -p password "MATCH (n) RETURN count(n) LIMIT 1" > /dev/null 2>&1 && echo "✅ Neo4j: Healthy" || echo "❌ Neo4j: Unhealthy"
|
| 20 |
+
|
| 21 |
+
echo "Checking PostgreSQL..."
|
| 22 |
+
docker-compose exec postgres pg_isready -U postgres > /dev/null 2>&1 && echo "✅ PostgreSQL: Healthy" || echo "❌ PostgreSQL: Unhealthy"
|
| 23 |
+
|
| 24 |
+
echo "Checking MCP Server..."
|
| 25 |
+
curl -s http://localhost:8000/health > /dev/null && echo "✅ MCP Server: Healthy" || echo "❌ MCP Server: Unhealthy"
|
| 26 |
+
|
| 27 |
+
echo "Checking Frontend..."
|
| 28 |
+
curl -s http://localhost:3000 > /dev/null && echo "✅ Frontend: Healthy" || echo "❌ Frontend: Unhealthy"
|
| 29 |
+
|
| 30 |
+
echo "Checking Agent..."
|
| 31 |
+
docker-compose ps agent | grep -q "Up" && echo "✅ Agent: Running" || echo "❌ Agent: Not running"
|
| 32 |
+
|
| 33 |
+
echo -e "${BLUE}Step 3: Seeding demo workflow...${NC}"
|
| 34 |
+
docker-compose exec mcp python /app/ops/scripts/seed.py
|
| 35 |
+
|
| 36 |
+
echo -e "${GREEN}✅ Demo environment ready!${NC}"
|
| 37 |
+
echo ""
|
| 38 |
+
echo "📝 Demo Script:"
|
| 39 |
+
echo "---------------"
|
| 40 |
+
echo "1. Open http://localhost:3000 in your browser"
|
| 41 |
+
echo ""
|
| 42 |
+
echo "2. In the chat, type: 'Show me customers who have ordered more than \$100'"
|
| 43 |
+
echo ""
|
| 44 |
+
echo "3. You'll see:"
|
| 45 |
+
echo " - 'Workflow created!' message"
|
| 46 |
+
echo " - Graph visualization showing workflow nodes"
|
| 47 |
+
echo " - Status showing 'Agent thinking...'"
|
| 48 |
+
echo ""
|
| 49 |
+
echo "4. The agent will:"
|
| 50 |
+
echo " - Pause for 5 minutes (or configured duration)"
|
| 51 |
+
echo " - Discover PostgreSQL schema"
|
| 52 |
+
echo " - Generate SQL query"
|
| 53 |
+
echo " - Execute and return results"
|
| 54 |
+
echo ""
|
| 55 |
+
echo "5. During the pause, you can:"
|
| 56 |
+
echo " - Open Neo4j Browser: http://localhost:7474"
|
| 57 |
+
echo " - Login: neo4j/password"
|
| 58 |
+
echo " - Run: MATCH (i:Instruction {status: 'pending'}) RETURN i"
|
| 59 |
+
echo " - Edit parameters to change the query"
|
| 60 |
+
echo ""
|
| 61 |
+
echo "6. After execution completes:"
|
| 62 |
+
echo " - Results appear in a table"
|
| 63 |
+
echo " - Generated SQL is shown"
|
| 64 |
+
echo " - Graph shows all nodes as green (complete)"
|
| 65 |
+
echo ""
|
| 66 |
+
echo -e "${YELLOW}Optional: Edit instruction during pause${NC}"
|
| 67 |
+
echo "docker-compose exec neo4j cypher-shell -u neo4j -p password \\"
|
| 68 |
+
echo " \"MATCH (i:Instruction {type: 'generate_sql', status: 'pending'}) \\"
|
| 69 |
+
echo " SET i.parameters = '{\\\"question\\\": \\\"Count all orders\\\"}'\""
|
| 70 |
+
echo ""
|
| 71 |
+
echo -e "${GREEN}Demo is running! Press Ctrl+C to stop.${NC}"
|
| 72 |
+
|
| 73 |
+
# Keep running
|
| 74 |
+
docker-compose logs -f agent
|
ops/scripts/validate.py
ADDED
|
@@ -0,0 +1,180 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env python3
|
| 2 |
+
"""Validate that the MVP system is working correctly"""
|
| 3 |
+
|
| 4 |
+
import requests
|
| 5 |
+
import time
|
| 6 |
+
import json
|
| 7 |
+
import sys
|
| 8 |
+
|
| 9 |
+
MCP_URL = "http://localhost:8000/mcp"
|
| 10 |
+
API_KEY = "dev-key-123"
|
| 11 |
+
|
| 12 |
+
def call_mcp(tool, params=None):
|
| 13 |
+
response = requests.post(
|
| 14 |
+
MCP_URL,
|
| 15 |
+
headers={"X-API-Key": API_KEY, "Content-Type": "application/json"},
|
| 16 |
+
json={"tool": tool, "params": params or {}}
|
| 17 |
+
)
|
| 18 |
+
return response.json()
|
| 19 |
+
|
| 20 |
+
def validate_step(step_name, validation_func):
|
| 21 |
+
"""Run a validation step and report results"""
|
| 22 |
+
print(f"Validating: {step_name}...", end=" ")
|
| 23 |
+
try:
|
| 24 |
+
result = validation_func()
|
| 25 |
+
if result:
|
| 26 |
+
print("✅ PASSED")
|
| 27 |
+
return True
|
| 28 |
+
else:
|
| 29 |
+
print("❌ FAILED")
|
| 30 |
+
return False
|
| 31 |
+
except Exception as e:
|
| 32 |
+
print(f"❌ ERROR: {e}")
|
| 33 |
+
return False
|
| 34 |
+
|
| 35 |
+
def check_neo4j():
|
| 36 |
+
"""Check Neo4j is accessible via MCP"""
|
| 37 |
+
result = call_mcp("get_schema")
|
| 38 |
+
return "labels" in result
|
| 39 |
+
|
| 40 |
+
def check_postgres():
|
| 41 |
+
"""Check PostgreSQL has sample data"""
|
| 42 |
+
result = call_mcp("query_postgres", {"query": "SELECT COUNT(*) as count FROM customers"})
|
| 43 |
+
return result.get("data", [{}])[0].get("count", 0) > 0
|
| 44 |
+
|
| 45 |
+
def check_schema_discovery():
|
| 46 |
+
"""Check schema can be discovered"""
|
| 47 |
+
result = call_mcp("discover_postgres_schema")
|
| 48 |
+
schema = result.get("schema", {})
|
| 49 |
+
return "customers" in schema and "orders" in schema
|
| 50 |
+
|
| 51 |
+
def create_test_workflow():
|
| 52 |
+
"""Create a test workflow"""
|
| 53 |
+
# Create workflow
|
| 54 |
+
workflow = call_mcp("write_graph", {
|
| 55 |
+
"action": "create_node",
|
| 56 |
+
"label": "Workflow",
|
| 57 |
+
"properties": {
|
| 58 |
+
"id": "validation-workflow",
|
| 59 |
+
"name": "Validation Test",
|
| 60 |
+
"status": "active"
|
| 61 |
+
}
|
| 62 |
+
})
|
| 63 |
+
|
| 64 |
+
# Create test instruction
|
| 65 |
+
instruction = call_mcp("write_graph", {
|
| 66 |
+
"action": "create_node",
|
| 67 |
+
"label": "Instruction",
|
| 68 |
+
"properties": {
|
| 69 |
+
"id": "validation-inst-1",
|
| 70 |
+
"type": "generate_sql",
|
| 71 |
+
"sequence": 1,
|
| 72 |
+
"status": "pending",
|
| 73 |
+
"pause_duration": 5, # Short pause for testing
|
| 74 |
+
"parameters": json.dumps({"question": "Count all customers"})
|
| 75 |
+
}
|
| 76 |
+
})
|
| 77 |
+
|
| 78 |
+
# Link instruction to workflow
|
| 79 |
+
call_mcp("query_graph", {
|
| 80 |
+
"query": """
|
| 81 |
+
MATCH (w:Workflow {id: 'validation-workflow'}),
|
| 82 |
+
(i:Instruction {id: 'validation-inst-1'})
|
| 83 |
+
CREATE (w)-[:HAS_INSTRUCTION]->(i)
|
| 84 |
+
"""
|
| 85 |
+
})
|
| 86 |
+
|
| 87 |
+
return workflow.get("created") is not None
|
| 88 |
+
|
| 89 |
+
def check_instruction_execution():
|
| 90 |
+
"""Check if instruction gets executed"""
|
| 91 |
+
# Wait for agent to pick it up (max 60 seconds)
|
| 92 |
+
for _ in range(12):
|
| 93 |
+
result = call_mcp("query_graph", {
|
| 94 |
+
"query": """
|
| 95 |
+
MATCH (i:Instruction {id: 'validation-inst-1'})
|
| 96 |
+
RETURN i.status as status
|
| 97 |
+
"""
|
| 98 |
+
})
|
| 99 |
+
|
| 100 |
+
status = result["data"][0]["status"] if result.get("data") else "unknown"
|
| 101 |
+
|
| 102 |
+
if status in ["executing", "complete"]:
|
| 103 |
+
return True
|
| 104 |
+
|
| 105 |
+
time.sleep(5)
|
| 106 |
+
|
| 107 |
+
return False
|
| 108 |
+
|
| 109 |
+
def check_execution_logged():
|
| 110 |
+
"""Check if execution was logged"""
|
| 111 |
+
result = call_mcp("query_graph", {
|
| 112 |
+
"query": """
|
| 113 |
+
MATCH (i:Instruction {id: 'validation-inst-1'})-[:EXECUTED_AS]->(e:Execution)
|
| 114 |
+
RETURN e
|
| 115 |
+
"""
|
| 116 |
+
})
|
| 117 |
+
|
| 118 |
+
return len(result.get("data", [])) > 0
|
| 119 |
+
|
| 120 |
+
def check_frontend():
|
| 121 |
+
"""Check if frontend is accessible"""
|
| 122 |
+
try:
|
| 123 |
+
response = requests.get("http://localhost:3000")
|
| 124 |
+
return response.status_code == 200
|
| 125 |
+
except:
|
| 126 |
+
return False
|
| 127 |
+
|
| 128 |
+
def main():
|
| 129 |
+
print("=" * 50)
|
| 130 |
+
print("MVP SYSTEM VALIDATION")
|
| 131 |
+
print("=" * 50)
|
| 132 |
+
print()
|
| 133 |
+
|
| 134 |
+
# Track results
|
| 135 |
+
all_passed = True
|
| 136 |
+
|
| 137 |
+
# Core services
|
| 138 |
+
all_passed &= validate_step("Neo4j accessible via MCP", check_neo4j)
|
| 139 |
+
all_passed &= validate_step("PostgreSQL has sample data", check_postgres)
|
| 140 |
+
all_passed &= validate_step("Frontend is accessible", check_frontend)
|
| 141 |
+
|
| 142 |
+
# Functionality
|
| 143 |
+
all_passed &= validate_step("Schema discovery works", check_schema_discovery)
|
| 144 |
+
all_passed &= validate_step("Workflow creation works", create_test_workflow)
|
| 145 |
+
|
| 146 |
+
print()
|
| 147 |
+
print("Waiting for agent to process instruction...")
|
| 148 |
+
all_passed &= validate_step("Instruction gets executed", check_instruction_execution)
|
| 149 |
+
all_passed &= validate_step("Execution is logged", check_execution_logged)
|
| 150 |
+
|
| 151 |
+
# Final verification
|
| 152 |
+
print()
|
| 153 |
+
print("=" * 50)
|
| 154 |
+
if all_passed:
|
| 155 |
+
print("✅ ALL VALIDATIONS PASSED!")
|
| 156 |
+
print("The MVP system is working correctly.")
|
| 157 |
+
|
| 158 |
+
# Show sample query result
|
| 159 |
+
result = call_mcp("query_graph", {
|
| 160 |
+
"query": """
|
| 161 |
+
MATCH (n)
|
| 162 |
+
RETURN labels(n)[0] as label, count(n) as count
|
| 163 |
+
ORDER BY count DESC
|
| 164 |
+
"""
|
| 165 |
+
})
|
| 166 |
+
|
| 167 |
+
print()
|
| 168 |
+
print("Graph Statistics:")
|
| 169 |
+
for item in result.get("data", []):
|
| 170 |
+
print(f" - {item['label']}: {item['count']} nodes")
|
| 171 |
+
|
| 172 |
+
else:
|
| 173 |
+
print("❌ SOME VALIDATIONS FAILED")
|
| 174 |
+
print("Please check the logs and fix issues.")
|
| 175 |
+
sys.exit(1)
|
| 176 |
+
|
| 177 |
+
print("=" * 50)
|
| 178 |
+
|
| 179 |
+
if __name__ == "__main__":
|
| 180 |
+
main()
|