Timothy Eastridge commited on
Commit
795ed51
·
1 Parent(s): 9930ba9

commit updates

Browse files
agent/Dockerfile ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ FROM python:3.11-slim
2
+
3
+ WORKDIR /app
4
+
5
+ COPY requirements.txt .
6
+ RUN pip install --no-cache-dir -r requirements.txt
7
+
8
+ COPY main.py .
9
+
10
+ CMD ["python", "main.py"]
agent/main.py ADDED
@@ -0,0 +1,77 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import time
3
+ import json
4
+ import requests
5
+ from datetime import datetime
6
+
7
+ MCP_URL = os.getenv("MCP_URL", "http://mcp:8000/mcp")
8
+ API_KEY = os.getenv("MCP_API_KEY", "dev-key-123")
9
+ POLL_INTERVAL = int(os.getenv("AGENT_POLL_INTERVAL", "30"))
10
+
11
+ def call_mcp(tool, params=None):
12
+ response = requests.post(
13
+ MCP_URL,
14
+ headers={"X-API-Key": API_KEY, "Content-Type": "application/json"},
15
+ json={"tool": tool, "params": params or {}}
16
+ )
17
+ return response.json()
18
+
19
+ def main():
20
+ print(f"[{datetime.now()}] Agent starting, polling every {POLL_INTERVAL}s")
21
+
22
+ while True:
23
+ try:
24
+ # Get next instruction
25
+ result = call_mcp("get_next_instruction")
26
+ instruction = result.get("instruction")
27
+
28
+ if instruction:
29
+ print(f"[{datetime.now()}] Found instruction: {instruction['id']}, type: {instruction['type']}")
30
+
31
+ # Update status to executing
32
+ call_mcp("query_graph", {
33
+ "query": "MATCH (i:Instruction {id: $id}) SET i.status = 'executing'",
34
+ "parameters": {"id": instruction['id']}
35
+ })
36
+
37
+ # Create dummy execution for now
38
+ exec_result = call_mcp("write_graph", {
39
+ "action": "create_node",
40
+ "label": "Execution",
41
+ "properties": {
42
+ "id": f"exec-{instruction['id']}-{int(time.time())}",
43
+ "started_at": datetime.now().isoformat(),
44
+ "completed_at": datetime.now().isoformat(),
45
+ "result": "Dummy execution completed"
46
+ }
47
+ })
48
+
49
+ # Link execution to instruction
50
+ call_mcp("query_graph", {
51
+ "query": """
52
+ MATCH (i:Instruction {id: $iid}), (e:Execution {id: $eid})
53
+ CREATE (i)-[:EXECUTED_AS]->(e)
54
+ """,
55
+ "parameters": {
56
+ "iid": instruction['id'],
57
+ "eid": exec_result['created']['id']
58
+ }
59
+ })
60
+
61
+ # Mark complete
62
+ call_mcp("query_graph", {
63
+ "query": "MATCH (i:Instruction {id: $id}) SET i.status = 'complete'",
64
+ "parameters": {"id": instruction['id']}
65
+ })
66
+
67
+ print(f"[{datetime.now()}] Completed instruction: {instruction['id']}")
68
+ else:
69
+ print(f"[{datetime.now()}] No pending instructions")
70
+
71
+ except Exception as e:
72
+ print(f"[{datetime.now()}] Error: {e}")
73
+
74
+ time.sleep(POLL_INTERVAL)
75
+
76
+ if __name__ == "__main__":
77
+ main()
agent/requirements.txt ADDED
@@ -0,0 +1,2 @@
 
 
 
1
+ requests==2.31.0
2
+ python-dotenv==1.0.0
docker-compose.yml CHANGED
@@ -40,6 +40,17 @@ services:
40
  depends_on:
41
  - neo4j
42
 
 
 
 
 
 
 
 
 
 
 
 
43
  volumes:
44
  neo4j_data:
45
  postgres_data:
 
40
  depends_on:
41
  - neo4j
42
 
43
+ agent:
44
+ build: ./agent
45
+ container_name: agent
46
+ environment:
47
+ - MCP_URL=http://mcp:8000/mcp
48
+ - MCP_API_KEY=dev-key-123
49
+ - AGENT_POLL_INTERVAL=${AGENT_POLL_INTERVAL:-30}
50
+ depends_on:
51
+ - mcp
52
+ - neo4j
53
+
54
  volumes:
55
  neo4j_data:
56
  postgres_data:
ops/health/neo4j.sh ADDED
@@ -0,0 +1,2 @@
 
 
 
1
+ #!/bin/bash
2
+ docker-compose exec neo4j cypher-shell -u neo4j -p password "MATCH (n) RETURN count(n) LIMIT 1" && echo "✅ Neo4j healthy"
ops/scripts/seed.py ADDED
@@ -0,0 +1,73 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import requests
2
+ import json
3
+
4
+ MCP_URL = "http://mcp:8000/mcp"
5
+ API_KEY = "dev-key-123"
6
+
7
+ def call_mcp(tool, params=None):
8
+ response = requests.post(
9
+ MCP_URL,
10
+ headers={"X-API-Key": API_KEY, "Content-Type": "application/json"},
11
+ json={"tool": tool, "params": params or {}}
12
+ )
13
+ return response.json()
14
+
15
+ # Create demo workflow
16
+ workflow = call_mcp("write_graph", {
17
+ "action": "create_node",
18
+ "label": "Workflow",
19
+ "properties": {
20
+ "id": "demo-workflow-1",
21
+ "name": "Entity Resolution Demo",
22
+ "status": "active",
23
+ "max_iterations": 10,
24
+ "current_iteration": 0
25
+ }
26
+ })
27
+ print(f"Created workflow: {workflow}")
28
+
29
+ # Create three instructions
30
+ instructions = [
31
+ {"id": "inst-1", "sequence": 1, "type": "discover_schema", "status": "pending", "pause_duration": 300},
32
+ {"id": "inst-2", "sequence": 2, "type": "generate_sql", "status": "pending", "pause_duration": 300},
33
+ {"id": "inst-3", "sequence": 3, "type": "review_results", "status": "pending", "pause_duration": 300}
34
+ ]
35
+
36
+ for inst in instructions:
37
+ result = call_mcp("write_graph", {
38
+ "action": "create_node",
39
+ "label": "Instruction",
40
+ "properties": inst
41
+ })
42
+ print(f"Created instruction: {inst['id']}")
43
+
44
+ # Link to workflow
45
+ call_mcp("query_graph", {
46
+ "query": """
47
+ MATCH (w:Workflow {id: $wid}), (i:Instruction {id: $iid})
48
+ CREATE (w)-[:HAS_INSTRUCTION]->(i)
49
+ """,
50
+ "parameters": {"wid": "demo-workflow-1", "iid": inst['id']}
51
+ })
52
+
53
+ # Create instruction chain
54
+ call_mcp("query_graph", {
55
+ "query": """
56
+ MATCH (i1:Instruction {id: 'inst-1'}), (i2:Instruction {id: 'inst-2'})
57
+ CREATE (i1)-[:NEXT_INSTRUCTION]->(i2)
58
+ """
59
+ })
60
+
61
+ call_mcp("query_graph", {
62
+ "query": """
63
+ MATCH (i2:Instruction {id: 'inst-2'}), (i3:Instruction {id: 'inst-3'})
64
+ CREATE (i2)-[:NEXT_INSTRUCTION]->(i3)
65
+ """
66
+ })
67
+
68
+ # Create indexes
69
+ call_mcp("query_graph", {"query": "CREATE INDEX workflow_id IF NOT EXISTS FOR (w:Workflow) ON (w.id)"})
70
+ call_mcp("query_graph", {"query": "CREATE INDEX instruction_id IF NOT EXISTS FOR (i:Instruction) ON (i.id)"})
71
+ call_mcp("query_graph", {"query": "CREATE INDEX instruction_status_seq IF NOT EXISTS FOR (i:Instruction) ON (i.status, i.sequence)"})
72
+
73
+ print("✅ Seeding complete!")