Timothy Eastridge commited on
Commit
da2713e
Β·
1 Parent(s): ead5455

clean up on seeding and system overview

Browse files
SYSTEM_OVERVIEW.md ADDED
@@ -0,0 +1,263 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Graph-Driven Agentic System with Human-in-the-Loop Controls
2
+
3
+ ## What This System Is
4
+
5
+ This is a **production-ready agentic workflow orchestration system** that demonstrates how to build AI agents with human oversight and complete audit trails. The system combines:
6
+
7
+ - **πŸ€– Autonomous AI Agent**: Processes natural language queries and generates SQL
8
+ - **πŸ“Š Graph Database**: Neo4j stores all workflow metadata and audit trails
9
+ - **⏸️ Human-in-the-Loop**: Configurable pause points for human review and intervention
10
+ - **🎯 Single API Gateway**: All operations routed through MCP (Model Context Protocol) server
11
+ - **🌐 Real-time Interface**: React frontend with live workflow visualization
12
+ - **πŸ” Complete Observability**: Every action logged with timestamps and relationships
13
+
14
+ ## What It Does
15
+
16
+ ### Core Workflow
17
+ 1. **User asks a question** in natural language via the web interface
18
+ 2. **System creates a workflow** with multiple instruction steps in Neo4j
19
+ 3. **Agent discovers the question** and begins processing
20
+ 4. **Pause for human review** (5 minutes by default, configurable)
21
+ 5. **Human can edit instructions** during pause via Neo4j Browser
22
+ 6. **Agent generates SQL** from natural language using LLM
23
+ 7. **Agent executes SQL** against PostgreSQL database
24
+ 8. **Results displayed** in formatted table with complete audit trail
25
+
26
+ ### Architecture Components
27
+ ```
28
+ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
29
+ β”‚ Frontend │────│ MCP Server │────│ Neo4j β”‚
30
+ β”‚ (Next.js) β”‚ β”‚ (FastAPI) β”‚ β”‚ (Graph) β”‚
31
+ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
32
+ β”‚
33
+ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
34
+ β”‚ Agent │────│ PostgreSQL β”‚
35
+ β”‚ (Python) β”‚ β”‚ (Data) β”‚
36
+ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
37
+ ```
38
+
39
+ - **Neo4j Graph Database**: Stores workflows, instructions, executions, and logs
40
+ - **MCP Server**: FastAPI gateway for all Neo4j operations with parameter fixing
41
+ - **Python Agent**: Polls for instructions, pauses for human input, executes tasks
42
+ - **PostgreSQL**: Sample data source for SQL generation and execution
43
+ - **Next.js Frontend**: Chat interface with Cytoscape.js graph visualization
44
+
45
+ ## Why It's Valuable
46
+
47
+ ### 🎯 **Demonstrates Production Patterns**
48
+ - **Human Oversight**: Shows how to build AI systems with meaningful human control
49
+ - **Audit Trails**: Complete graph-based logging of all operations and decisions
50
+ - **Error Recovery**: System continues gracefully after interruptions or edits
51
+ - **Scalable Architecture**: Clean separation of concerns, containerized deployment
52
+
53
+ ### πŸ”„ **Agentic Workflow Orchestration**
54
+ - **Graph-Driven**: Workflows stored as connected nodes, not brittle state machines
55
+ - **Dynamic Editing**: Instructions can be modified during execution
56
+ - **Sequence Management**: Proper instruction chaining and dependency handling
57
+ - **Status Tracking**: Real-time visibility into workflow progress
58
+
59
+ ### πŸ›‘οΈ **Human-in-the-Loop Controls**
60
+ - **Configurable Pauses**: Built-in review periods before critical operations
61
+ - **Live Editing**: Modify AI behavior during execution via graph database
62
+ - **Stop Controls**: Terminate workflows at any point
63
+ - **Parameter Updates**: Change questions, settings, or instructions mid-flight
64
+
65
+ ### πŸ“Š **Complete Observability**
66
+ - **Graph Visualization**: Real-time workflow progress with color-coded status
67
+ - **Audit Logging**: Every MCP operation logged with timestamps
68
+ - **Execution Tracking**: Full history of what was generated and executed
69
+ - **Result Storage**: All outputs preserved in queryable graph format
70
+
71
+ ### πŸš€ **Production Ready**
72
+ - **Containerized**: Full Docker Compose setup with health checks
73
+ - **Environment Configuration**: Flexible .env-based configuration
74
+ - **Error Handling**: Graceful failures and recovery mechanisms
75
+ - **Documentation**: Comprehensive setup, usage, and troubleshooting guides
76
+
77
+ ## How to Make It Run
78
+
79
+ ### Quick Start (5 minutes)
80
+
81
+ ```bash
82
+ # 1. Clone and navigate to the repo
83
+ git clone <repository-url>
84
+ cd <repository-name>
85
+
86
+ # 2. Copy environment template
87
+ cp .env.example .env
88
+
89
+ # 3. Add your LLM API key to .env
90
+ # Edit .env and set: LLM_API_KEY=your-openai-or-anthropic-key-here
91
+
92
+ # 4. Start everything
93
+ docker-compose up -d
94
+
95
+ # 5. Seed Neo4j with demo data (IMPORTANT!)
96
+ docker-compose exec mcp python /app/ops/scripts/seed.py
97
+
98
+ # 6. Open the interface
99
+ # Frontend: http://localhost:3000
100
+ # Neo4j Browser: http://localhost:7474 (neo4j/password)
101
+ ```
102
+
103
+ ### Database Seeding Options
104
+
105
+ **Basic Seeding** (Quick demo):
106
+ ```bash
107
+ docker-compose exec mcp python /app/ops/scripts/seed.py
108
+ ```
109
+ Creates:
110
+ - **Demo Workflow**: A 3-step process (discover schema β†’ generate SQL β†’ review results)
111
+ - **Query Examples**: 3 basic SQL templates for testing
112
+ - **Graph Structure**: Proper relationships between components
113
+
114
+ **Comprehensive Seeding** (Full system):
115
+ ```bash
116
+ docker-compose exec mcp python /app/ops/scripts/seed_comprehensive.py
117
+ ```
118
+ Creates:
119
+ - **Workflow Templates**: Multiple workflow patterns (basic query, analysis, reporting)
120
+ - **Instruction Type Library**: 6 different instruction types with schemas
121
+ - **Query Library**: 6+ categorized SQL examples (basic, analytics, detailed)
122
+ - **Demo Workflows**: Ready-to-run and template workflows
123
+ - **System Configuration**: Default settings and supported features
124
+
125
+ **⚠️ Fresh Installation**: On a brand-new machine, Neo4j starts completely empty. You MUST run a seed script to have any workflows or instructions to interact with.
126
+
127
+ **πŸ’‘ Recommendation**: Use comprehensive seeding for full system exploration, basic seeding for quick demos.
128
+
129
+ ### PowerShell Fresh Start (Windows)
130
+ ```powershell
131
+ # Fresh deployment with API key
132
+ powershell -ExecutionPolicy Bypass -File ops/scripts/fresh_start.ps1 -ApiKey "your-api-key-here"
133
+
134
+ # Or run the demo (assumes system is already running)
135
+ powershell -ExecutionPolicy Bypass -File ops/scripts/demo.ps1
136
+ ```
137
+
138
+ ### Manual Health Check
139
+ ```bash
140
+ # Check all services
141
+ docker-compose ps
142
+
143
+ # Validate system
144
+ docker-compose exec mcp python /app/ops/scripts/validate.py
145
+
146
+ # Monitor logs
147
+ docker-compose logs -f agent
148
+ ```
149
+
150
+ ### Test the System
151
+
152
+ 1. **Open http://localhost:3000**
153
+ 2. **Ask a question**: "How many customers do we have?"
154
+ 3. **Watch the workflow**:
155
+ - Graph visualization shows progress
156
+ - Agent pauses for 5 minutes
157
+ - You can edit instructions in Neo4j Browser
158
+ - Results appear in formatted table
159
+
160
+ ### Clean Reset
161
+ ```bash
162
+ # Stop and clean everything
163
+ docker-compose down
164
+ docker-compose up -d
165
+ docker-compose exec mcp python /app/ops/scripts/seed.py
166
+ ```
167
+
168
+ ## Key Features for Developers
169
+
170
+ ### Graph Database Schema
171
+ - **Workflow** nodes: High-level process containers
172
+ - **Instruction** nodes: Individual tasks with parameters and status
173
+ - **Execution** nodes: Results of instruction processing
174
+ - **Log** nodes: Audit trail of all MCP operations
175
+ - **Relationships**: `HAS_INSTRUCTION`, `EXECUTED_AS`, `NEXT_INSTRUCTION`
176
+
177
+ ### Configuration Options
178
+ - **Pause Duration**: `PAUSE_DURATION` in .env (default: 300 seconds)
179
+ - **Polling Interval**: `AGENT_POLL_INTERVAL` in .env (default: 30 seconds)
180
+ - **LLM Model**: `LLM_MODEL` in .env (gpt-4, claude-3-sonnet, etc.)
181
+
182
+ ### Extension Points
183
+ - **New Instruction Types**: Add handlers in `agent/main.py`
184
+ - **Custom Data Sources**: Extend MCP server with new connectors
185
+ - **Frontend Customization**: Modify React components in `frontend/app/`
186
+ - **Workflow Templates**: Create reusable instruction sequences
187
+
188
+ ### Human Intervention Examples
189
+ ```cypher
190
+ // Find pending instructions
191
+ MATCH (i:Instruction {status: 'pending'}) RETURN i
192
+
193
+ // Change a question
194
+ MATCH (i:Instruction {type: 'generate_sql', status: 'pending'})
195
+ SET i.parameters = '{"question": "Show me top 10 customers by revenue"}'
196
+
197
+ // Stop a workflow
198
+ MATCH (w:Workflow {status: 'active'})
199
+ SET w.status = 'stopped'
200
+ ```
201
+
202
+ ## Development Setup
203
+
204
+ ### Prerequisites
205
+ - Docker & Docker Compose
206
+ - OpenAI or Anthropic API key
207
+ - Modern web browser
208
+
209
+ ### Project Structure
210
+ ```
211
+ β”œβ”€β”€ agent/ # Python agent that executes instructions
212
+ β”œβ”€β”€ frontend/ # Next.js chat interface
213
+ β”œβ”€β”€ mcp/ # FastAPI server for Neo4j operations
214
+ β”œβ”€β”€ neo4j/ # Neo4j configuration
215
+ β”œβ”€β”€ postgres/ # PostgreSQL setup with sample data
216
+ β”œβ”€β”€ ops/scripts/ # Operational scripts (seed, validate, demo)
217
+ β”œβ”€β”€ docker-compose.yml
218
+ β”œβ”€β”€ Makefile # Convenience commands
219
+ └── README.md # Detailed documentation
220
+ ```
221
+
222
+ ### Available Commands
223
+ ```bash
224
+ # If you have make installed
225
+ make up # Start all services
226
+ make seed # Create demo data
227
+ make health # Check service health
228
+ make logs # View all logs
229
+ make clean # Reset everything
230
+
231
+ # Using docker-compose directly
232
+ docker-compose up -d
233
+ docker-compose exec mcp python /app/ops/scripts/seed.py
234
+ docker-compose ps
235
+ docker-compose logs -f
236
+ docker-compose down
237
+ ```
238
+
239
+ ## Use Cases
240
+
241
+ ### 🏒 **Enterprise AI Governance**
242
+ - Audit trails for compliance
243
+ - Human oversight for critical decisions
244
+ - Risk management in AI operations
245
+
246
+ ### πŸ”¬ **Research & Development**
247
+ - Experiment with agentic workflows
248
+ - Study human-AI collaboration patterns
249
+ - Prototype autonomous systems with safety controls
250
+
251
+ ### πŸ“š **Educational Examples**
252
+ - Demonstrate production AI architecture
253
+ - Teach graph database concepts
254
+ - Show containerized deployment patterns
255
+
256
+ ### πŸ› οΈ **Template for New Projects**
257
+ - Fork as starting point for agentic systems
258
+ - Adapt components for specific domains
259
+ - Scale architecture for production workloads
260
+
261
+ ---
262
+
263
+ **This system demonstrates that AI agents can be both autonomous and controllable, providing the benefits of automation while maintaining human oversight and complete transparency.**
app_requirements/6_feature_Streamlit.md ADDED
@@ -0,0 +1,64 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Feature 6: Lightweight Streamlit MCP Monitor & Query Tester
2
+ 6. Feature: Streamlit MCP Monitor & Query Tester
3
+ 6.1 Story: As a developer, I need a lightweight Streamlit app to monitor MCP connections and test the agentic query engine.
4
+
5
+ 6.1.1 Task: Create /streamlit/requirements.txt with streamlit==1.28.0, requests==2.31.0, pandas==2.1.0, python-dotenv==1.0.0 - NO neo4j driver as all Neo4j access MUST go through MCP server
6
+ 6.1.2 Task: Create /streamlit/app.py that ONLY communicates with MCP server at http://mcp:8000/mcp, never directly to Neo4j - use st.set_page_config(page_title="MCP Monitor", layout="wide"), create two tabs using st.tabs(["πŸ”Œ Connection Status", "πŸ€– Query Tester"])
7
+ 6.1.3 Task: Create /streamlit/Dockerfile with FROM python:3.11-slim, WORKDIR /app, install requirements, expose port 8501, CMD ["streamlit", "run", "app.py", "--server.address=0.0.0.0"]
8
+ 6.1.4 Task: Add streamlit service to docker-compose.yml with build: ./streamlit, ports: 8501:8501, depends_on: mcp, environment: MCP_URL=http://mcp:8000/mcp, MCP_API_KEY=dev-key-123, explicitly NOT including NEO4J_BOLT_URL as direct access is forbidden
9
+
10
+ 6.2 Story: As a user, I need to monitor the health and performance of all MCP connections in real-time.
11
+
12
+ 6.2.1 Task: Create connection test function that calls MCP tools ONLY - test Neo4j via call_mcp("get_schema"), test PostgreSQL via call_mcp("query_postgres", {"query": "SELECT 1"}), never use direct database connections
13
+ 6.2.2 Task: Display connection status in 3-column layout using st.columns(), show Neo4j (via MCP), PostgreSQL (via MCP), MCP Server status with st.metric(label, value="Online"/"Offline", delta=f"{response_ms}ms")
14
+ 6.2.3 Task: Implement auto-refresh using st.empty() placeholder with while True loop, time.sleep(5), st.rerun() to update every 5 seconds, show "Last checked: {timestamp}" with st.caption()
15
+ 6.2.4 Task: Add manual refresh button with st.button("πŸ”„ Refresh Now") that immediately re-runs all MCP-based connection tests and updates metrics
16
+ 6.2.5 Task: Query performance stats via MCP call_mcp("query_graph", {"query": "MATCH (l:Log) WHERE l.timestamp > datetime() - duration('PT1H') RETURN count(l) as count"}), display with st.info() - emphasize this is the ONLY way to query Neo4j
17
+
18
+ 6.3 Story: As a user, I need to test natural language queries through the agentic engine without using the main chat interface.
19
+
20
+ 6.3.1 Task: Create query input section with st.text_area("Enter your question:", height=100), st.button("πŸš€ Execute Query", type="primary") to trigger workflow creation via MCP server only
21
+ 6.3.2 Task: On execute, create workflow via call_mcp("write_graph", {action: "create_node", label: "Workflow", properties: {...}}), then create instructions via MCP write_graph, store workflow_id in st.session_state - all graph writes MUST use MCP
22
+ 6.3.3 Task: Poll workflow status via call_mcp("query_graph", {"query": "MATCH (i:Instruction) WHERE i.workflow_id=$id RETURN i.status", "parameters": {"id": workflow_id}}) every 2 seconds, update st.progress() based on results
23
+ 6.3.4 Task: Fetch results via call_mcp("query_graph", {"query": "MATCH (e:Execution) WHERE e.workflow_id=$id RETURN e.result", "parameters": {"id": workflow_id}}), display SQL in st.code() and data in st.dataframe()
24
+ 6.3.5 Task: Add "Clear Results" button that resets st.session_state.workflow_id and clears displayed results, ready for next query
25
+
26
+ 6.4 Story: As a developer, I need to examine the agentic process flow to understand how answers are derived.
27
+
28
+ 6.4.1 Task: Fetch execution trace via call_mcp("query_graph", {"query": "MATCH (w:Workflow {id: $id})-[:HAS_INSTRUCTION]->(i)-[:EXECUTED_AS]->(e) RETURN i, e ORDER BY i.sequence", "parameters": {"id": workflow_id}}) - this is the ONLY way to get execution data
29
+ 6.4.2 Task: Display each step in expandable sections using st.expander(f"Step {i.sequence}: {i.type}"), show instruction parameters, execution times, and status from MCP query results
30
+ 6.4.3 Task: For SQL generation steps, query schema context via call_mcp("query_graph", {"query": "MATCH (t:Table)-[:HAS_COLUMN]->(c:Column) RETURN t.name, collect(c.name)"}), display in st.code() to show what LLM received
31
+ 6.4.4 Task: Show execution timeline by calculating time differences from execution nodes returned by MCP query_graph, display as: "Schema Discovery (5s) β†’ [Pause 30s] β†’ SQL Generation (3s) β†’ Results (1s)"
32
+ 6.4.5 Task: Add "View Raw Execution Data" toggle that shows full JSON response from call_mcp("query_graph", {"query": "MATCH (e:Execution {workflow_id: $id}) RETURN e"}), displayed with st.json()
33
+
34
+ 6.5 Story: As a developer, I need the Streamlit app to handle errors gracefully and provide useful debugging information.
35
+
36
+ 6.5.1 Task: Wrap all call_mcp() invocations in try/except blocks, on exception show st.error(f"MCP Server Error: {str(e)}") emphasizing no direct database access is possible
37
+ 6.5.2 Task: Implement retry logic for failed MCP calls with 3 attempts and exponential backoff, show st.warning("Retrying MCP connection...") during retries, cache last successful response
38
+ 6.5.3 Task: Add debug panel with st.expander("πŸ”§ Debug Information") showing last 5 MCP requests/responses from st.session_state.debug_log, emphasize all database operations go through MCP
39
+ 6.5.4 Task: On workflow execution failure, query error details via call_mcp("query_graph", {"query": "MATCH (e:Execution {status: 'failed'}) RETURN e.error"}), display with suggestions for common issues
40
+ 6.5.5 Task: Create MCP diagnostics on startup - if call_mcp("get_schema") fails, show st.error("Cannot reach Neo4j through MCP server. The app cannot directly connect to Neo4j - all access must go through MCP at {MCP_URL}")
41
+
42
+
43
+ Critical Implementation Notes
44
+ The Streamlit app MUST:
45
+
46
+ NEVER import or use neo4j Python driver
47
+ NEVER import or use psycopg2 directly
48
+ ONLY communicate with databases through MCP server endpoints
49
+ ALWAYS use call_mcp() for any data retrieval or storage
50
+ EXPLICITLY show in error messages that direct database access is not permitted
51
+
52
+ Example of CORRECT implementation:
53
+ python# βœ… CORRECT - All Neo4j access through MCP
54
+ def get_workflow_status(workflow_id):
55
+ result, _ = call_mcp("query_graph", {
56
+ "query": "MATCH (w:Workflow {id: $id}) RETURN w.status",
57
+ "parameters": {"id": workflow_id}
58
+ })
59
+ return result['data'][0]['status'] if result else None
60
+ Example of INCORRECT implementation:
61
+ python# ❌ WRONG - Direct Neo4j access is forbidden
62
+ from neo4j import GraphDatabase
63
+ driver = GraphDatabase.driver("bolt://neo4j:7687") # NEVER DO THIS
64
+ This ensures the Streamlit app respects the architecture principle that all Neo4j access MUST go through the MCP server gateway, maintaining the single point of control and audit trail.
app_requirements/{6_feature_parking_lot_items.txt β†’ 99_feature_parking_lot_items.txt} RENAMED
File without changes
ops/scripts/demo.ps1 CHANGED
@@ -60,7 +60,8 @@ if ($agentStatus) {
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 ""
 
60
  }
61
 
62
  Write-Host ""
63
+ Write-Host "Step 3: Seeding Neo4j database..." -ForegroundColor Blue
64
+ Write-Host " (This populates the empty graph with demo workflows)" -ForegroundColor Gray
65
  docker-compose exec mcp python /app/ops/scripts/seed.py
66
 
67
  Write-Host ""
ops/scripts/fresh_start.ps1 ADDED
@@ -0,0 +1,170 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Fresh Start Script for Graph-Driven Agentic System (Windows PowerShell)
2
+ # Run this script to deploy the system from scratch
3
+
4
+ param(
5
+ [string]$ApiKey = "",
6
+ [string]$Model = "gpt-4"
7
+ )
8
+
9
+ Write-Host "πŸš€ Fresh Start Deployment" -ForegroundColor Green
10
+ Write-Host "=========================" -ForegroundColor Green
11
+ Write-Host ""
12
+
13
+ # Step 1: Check prerequisites
14
+ Write-Host "πŸ“‹ Step 1: Checking prerequisites..." -ForegroundColor Blue
15
+
16
+ try {
17
+ docker --version | Out-Null
18
+ Write-Host "βœ… Docker found" -ForegroundColor Green
19
+ } catch {
20
+ Write-Host "❌ Docker not found. Please install Docker Desktop" -ForegroundColor Red
21
+ exit 1
22
+ }
23
+
24
+ try {
25
+ docker-compose --version | Out-Null
26
+ Write-Host "βœ… Docker Compose found" -ForegroundColor Green
27
+ } catch {
28
+ Write-Host "❌ Docker Compose not found" -ForegroundColor Red
29
+ exit 1
30
+ }
31
+
32
+ # Step 2: Setup environment
33
+ Write-Host ""
34
+ Write-Host "βš™οΈ Step 2: Setting up environment..." -ForegroundColor Blue
35
+
36
+ if (Test-Path ".env") {
37
+ Write-Host "⚠️ .env file already exists, backing up to .env.backup" -ForegroundColor Yellow
38
+ Copy-Item ".env" ".env.backup"
39
+ }
40
+
41
+ Copy-Item ".env.example" ".env"
42
+ Write-Host "βœ… Created .env from template" -ForegroundColor Green
43
+
44
+ # Update API key if provided
45
+ if ($ApiKey -ne "") {
46
+ (Get-Content ".env") -replace "LLM_API_KEY=.*", "LLM_API_KEY=$ApiKey" | Set-Content ".env"
47
+ (Get-Content ".env") -replace "LLM_MODEL=.*", "LLM_MODEL=$Model" | Set-Content ".env"
48
+ Write-Host "βœ… Updated LLM configuration in .env" -ForegroundColor Green
49
+ } else {
50
+ Write-Host "⚠️ No API key provided. You'll need to edit .env manually" -ForegroundColor Yellow
51
+ Write-Host " Add your OpenAI or Anthropic API key to the LLM_API_KEY variable" -ForegroundColor Gray
52
+ }
53
+
54
+ # Step 3: Clean existing containers
55
+ Write-Host ""
56
+ Write-Host "🧹 Step 3: Cleaning existing containers..." -ForegroundColor Blue
57
+
58
+ docker-compose down 2>$null
59
+ docker system prune -f 2>$null
60
+ Write-Host "βœ… Cleaned existing containers" -ForegroundColor Green
61
+
62
+ # Step 4: Build services
63
+ Write-Host ""
64
+ Write-Host "πŸ”¨ Step 4: Building services..." -ForegroundColor Blue
65
+
66
+ docker-compose build
67
+ if ($LASTEXITCODE -ne 0) {
68
+ Write-Host "❌ Build failed" -ForegroundColor Red
69
+ exit 1
70
+ }
71
+ Write-Host "βœ… All services built successfully" -ForegroundColor Green
72
+
73
+ # Step 5: Start services
74
+ Write-Host ""
75
+ Write-Host "πŸš€ Step 5: Starting services..." -ForegroundColor Blue
76
+
77
+ docker-compose up -d
78
+ if ($LASTEXITCODE -ne 0) {
79
+ Write-Host "❌ Failed to start services" -ForegroundColor Red
80
+ exit 1
81
+ }
82
+ Write-Host "βœ… All services started" -ForegroundColor Green
83
+
84
+ # Step 6: Wait for health checks
85
+ Write-Host ""
86
+ Write-Host "⏳ Step 6: Waiting for services to be healthy (60 seconds)..." -ForegroundColor Blue
87
+
88
+ $healthyServices = 0
89
+ $maxWait = 60
90
+ $elapsed = 0
91
+
92
+ while ($elapsed -lt $maxWait -and $healthyServices -lt 3) {
93
+ Start-Sleep 5
94
+ $elapsed += 5
95
+
96
+ $healthyServices = 0
97
+
98
+ # Check Neo4j
99
+ try {
100
+ docker-compose exec neo4j cypher-shell -u neo4j -p password "MATCH (n) RETURN count(n) LIMIT 1" 2>$null | Out-Null
101
+ if ($LASTEXITCODE -eq 0) { $healthyServices++ }
102
+ } catch {}
103
+
104
+ # Check PostgreSQL
105
+ try {
106
+ docker-compose exec postgres pg_isready -U postgres 2>$null | Out-Null
107
+ if ($LASTEXITCODE -eq 0) { $healthyServices++ }
108
+ } catch {}
109
+
110
+ # Check MCP
111
+ try {
112
+ $response = Invoke-WebRequest -Uri "http://localhost:8000/health" -UseBasicParsing -TimeoutSec 2 2>$null
113
+ if ($response.StatusCode -eq 200) { $healthyServices++ }
114
+ } catch {}
115
+
116
+ Write-Host " Healthy services: $healthyServices/3 (${elapsed}s elapsed)" -ForegroundColor Gray
117
+ }
118
+
119
+ if ($healthyServices -eq 3) {
120
+ Write-Host "βœ… All core services are healthy" -ForegroundColor Green
121
+ } else {
122
+ Write-Host "⚠️ Some services may not be fully ready, but continuing..." -ForegroundColor Yellow
123
+ }
124
+
125
+ # Step 7: Seed database
126
+ Write-Host ""
127
+ Write-Host "🌱 Step 7: Seeding Neo4j database..." -ForegroundColor Blue
128
+
129
+ docker-compose exec mcp python /app/ops/scripts/seed.py
130
+ if ($LASTEXITCODE -eq 0) {
131
+ Write-Host "βœ… Database seeded successfully" -ForegroundColor Green
132
+ } else {
133
+ Write-Host "❌ Database seeding failed" -ForegroundColor Red
134
+ Write-Host " You can try manual seeding later with:" -ForegroundColor Gray
135
+ Write-Host " docker-compose exec mcp python /app/ops/scripts/seed.py" -ForegroundColor Gray
136
+ }
137
+
138
+ # Step 8: Final status check
139
+ Write-Host ""
140
+ Write-Host "πŸ“Š Step 8: Final status check..." -ForegroundColor Blue
141
+
142
+ docker-compose ps
143
+
144
+ # Step 9: Success message
145
+ Write-Host ""
146
+ Write-Host "πŸŽ‰ DEPLOYMENT COMPLETE!" -ForegroundColor Green
147
+ Write-Host "======================" -ForegroundColor Green
148
+ Write-Host ""
149
+ Write-Host "πŸ“± Access Points:" -ForegroundColor Yellow
150
+ Write-Host " β€’ Frontend Interface: http://localhost:3000" -ForegroundColor White
151
+ Write-Host " β€’ Neo4j Browser: http://localhost:7474" -ForegroundColor White
152
+ Write-Host " Login: neo4j / password" -ForegroundColor Gray
153
+ Write-Host ""
154
+ Write-Host "πŸ”§ Management Commands:" -ForegroundColor Yellow
155
+ Write-Host " β€’ View logs: docker-compose logs -f" -ForegroundColor White
156
+ Write-Host " β€’ Stop system: docker-compose down" -ForegroundColor White
157
+ Write-Host " β€’ Check health: docker-compose ps" -ForegroundColor White
158
+ Write-Host ""
159
+ Write-Host "🎯 Quick Test:" -ForegroundColor Yellow
160
+ Write-Host " 1. Open http://localhost:3000" -ForegroundColor White
161
+ Write-Host " 2. Ask: 'How many customers do we have?'" -ForegroundColor White
162
+ Write-Host " 3. Watch the agent process the workflow!" -ForegroundColor White
163
+ Write-Host ""
164
+
165
+ if ($ApiKey -eq "") {
166
+ Write-Host "⚠️ REMINDER: Update your LLM API key in .env before testing!" -ForegroundColor Yellow
167
+ Write-Host ""
168
+ }
169
+
170
+ Write-Host "System is ready for use! πŸš€" -ForegroundColor Green
ops/scripts/fresh_start_check.py ADDED
@@ -0,0 +1,256 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ """
3
+ Fresh Start Validation Script
4
+ Checks all requirements for launching the system from scratch
5
+ """
6
+
7
+ import os
8
+ import sys
9
+ import subprocess
10
+ import json
11
+
12
+ def check_file_exists(filepath, description):
13
+ """Check if a critical file exists"""
14
+ if os.path.exists(filepath):
15
+ print(f"βœ… {description}: {filepath}")
16
+ return True
17
+ else:
18
+ print(f"❌ MISSING {description}: {filepath}")
19
+ return False
20
+
21
+ def check_docker_files():
22
+ """Check all Docker-related files"""
23
+ print("🐳 Checking Docker files...")
24
+ files = [
25
+ ("docker-compose.yml", "Main orchestration file"),
26
+ ("agent/Dockerfile", "Agent service Docker config"),
27
+ ("mcp/Dockerfile", "MCP service Docker config"),
28
+ ("frontend/Dockerfile", "Frontend service Docker config"),
29
+ ("neo4j/Dockerfile", "Neo4j service Docker config"),
30
+ (".env.example", "Environment template")
31
+ ]
32
+
33
+ all_good = True
34
+ for filepath, desc in files:
35
+ all_good &= check_file_exists(filepath, desc)
36
+
37
+ return all_good
38
+
39
+ def check_frontend_files():
40
+ """Check frontend critical files"""
41
+ print("\n🌐 Checking Frontend files...")
42
+ files = [
43
+ ("frontend/package.json", "Frontend dependencies"),
44
+ ("frontend/tsconfig.json", "TypeScript config"),
45
+ ("frontend/tailwind.config.js", "Tailwind CSS config"),
46
+ ("frontend/next.config.js", "Next.js config"),
47
+ ("frontend/app/page.tsx", "Main chat interface"),
48
+ ("frontend/app/layout.tsx", "Root layout"),
49
+ ("frontend/types/cytoscape-fcose.d.ts", "Cytoscape types")
50
+ ]
51
+
52
+ all_good = True
53
+ for filepath, desc in files:
54
+ all_good &= check_file_exists(filepath, desc)
55
+
56
+ return all_good
57
+
58
+ def check_backend_files():
59
+ """Check backend service files"""
60
+ print("\nπŸ”§ Checking Backend files...")
61
+ files = [
62
+ ("agent/main.py", "Agent service main file"),
63
+ ("agent/requirements.txt", "Agent dependencies"),
64
+ ("mcp/main.py", "MCP service main file"),
65
+ ("mcp/requirements.txt", "MCP dependencies"),
66
+ ("postgres/init.sql", "PostgreSQL initialization"),
67
+ ]
68
+
69
+ all_good = True
70
+ for filepath, desc in files:
71
+ all_good &= check_file_exists(filepath, desc)
72
+
73
+ return all_good
74
+
75
+ def check_operational_files():
76
+ """Check operational scripts"""
77
+ print("\nπŸ› οΈ Checking Operational files...")
78
+ files = [
79
+ ("ops/scripts/seed.py", "Basic seeding script"),
80
+ ("ops/scripts/seed_comprehensive.py", "Comprehensive seeding script"),
81
+ ("ops/scripts/validate.py", "System validation script"),
82
+ ("ops/scripts/demo.ps1", "PowerShell demo script"),
83
+ ("Makefile", "Build automation"),
84
+ ("README.md", "Main documentation"),
85
+ ("SYSTEM_OVERVIEW.md", "System overview")
86
+ ]
87
+
88
+ all_good = True
89
+ for filepath, desc in files:
90
+ all_good &= check_file_exists(filepath, desc)
91
+
92
+ return all_good
93
+
94
+ def check_env_variables():
95
+ """Check if .env.example has all required variables"""
96
+ print("\nβš™οΈ Checking Environment variables...")
97
+
98
+ if not os.path.exists(".env.example"):
99
+ print("❌ .env.example file missing")
100
+ return False
101
+
102
+ with open(".env.example", "r") as f:
103
+ env_content = f.read()
104
+
105
+ required_vars = [
106
+ "NEO4J_AUTH",
107
+ "NEO4J_BOLT_URL",
108
+ "POSTGRES_PASSWORD",
109
+ "POSTGRES_CONNECTION",
110
+ "MCP_API_KEYS",
111
+ "MCP_PORT",
112
+ "AGENT_POLL_INTERVAL",
113
+ "PAUSE_DURATION",
114
+ "LLM_API_KEY",
115
+ "LLM_MODEL"
116
+ ]
117
+
118
+ all_good = True
119
+ for var in required_vars:
120
+ if var in env_content:
121
+ print(f"βœ… Environment variable: {var}")
122
+ else:
123
+ print(f"❌ MISSING environment variable: {var}")
124
+ all_good = False
125
+
126
+ return all_good
127
+
128
+ def check_docker_compose_structure():
129
+ """Check docker-compose.yml structure"""
130
+ print("\nπŸ”— Checking Docker Compose structure...")
131
+
132
+ if not os.path.exists("docker-compose.yml"):
133
+ print("❌ docker-compose.yml missing")
134
+ return False
135
+
136
+ try:
137
+ import yaml
138
+ with open("docker-compose.yml", "r") as f:
139
+ compose = yaml.safe_load(f)
140
+
141
+ required_services = ["neo4j", "postgres", "mcp", "agent", "frontend"]
142
+ all_good = True
143
+
144
+ for service in required_services:
145
+ if service in compose.get("services", {}):
146
+ print(f"βœ… Service defined: {service}")
147
+ else:
148
+ print(f"❌ MISSING service: {service}")
149
+ all_good = False
150
+
151
+ return all_good
152
+
153
+ except ImportError:
154
+ print("⚠️ PyYAML not available, skipping structure check")
155
+ return True
156
+ except Exception as e:
157
+ print(f"❌ Error parsing docker-compose.yml: {e}")
158
+ return False
159
+
160
+ def check_package_json():
161
+ """Check frontend package.json for required dependencies"""
162
+ print("\nπŸ“¦ Checking Frontend dependencies...")
163
+
164
+ if not os.path.exists("frontend/package.json"):
165
+ print("❌ frontend/package.json missing")
166
+ return False
167
+
168
+ with open("frontend/package.json", "r") as f:
169
+ package = json.load(f)
170
+
171
+ required_deps = [
172
+ "next", "react", "react-dom", "typescript",
173
+ "cytoscape", "cytoscape-fcose", "tailwindcss"
174
+ ]
175
+
176
+ all_deps = {**package.get("dependencies", {}), **package.get("devDependencies", {})}
177
+ all_good = True
178
+
179
+ for dep in required_deps:
180
+ if dep in all_deps:
181
+ print(f"βœ… Frontend dependency: {dep}")
182
+ else:
183
+ print(f"❌ MISSING frontend dependency: {dep}")
184
+ all_good = False
185
+
186
+ return all_good
187
+
188
+ def generate_startup_commands():
189
+ """Generate the exact commands for fresh startup"""
190
+ print("\nπŸš€ Fresh Startup Commands:")
191
+ print("=" * 50)
192
+ print("# 1. Copy environment file")
193
+ print("cp .env.example .env")
194
+ print("")
195
+ print("# 2. Edit .env and add your LLM API key")
196
+ print("# LLM_API_KEY=your-openai-or-anthropic-key-here")
197
+ print("")
198
+ print("# 3. Clean any existing containers")
199
+ print("docker-compose down")
200
+ print("docker system prune -f")
201
+ print("")
202
+ print("# 4. Build and start services")
203
+ print("docker-compose build")
204
+ print("docker-compose up -d")
205
+ print("")
206
+ print("# 5. Wait for services to be healthy (30 seconds)")
207
+ print("Start-Sleep 30")
208
+ print("")
209
+ print("# 6. Seed the database")
210
+ print("docker-compose exec mcp python /app/ops/scripts/seed.py")
211
+ print("")
212
+ print("# 7. Open the interface")
213
+ print("# Frontend: http://localhost:3000")
214
+ print("# Neo4j Browser: http://localhost:7474 (neo4j/password)")
215
+ print("=" * 50)
216
+
217
+ def main():
218
+ print("πŸ” FRESH START VALIDATION")
219
+ print("========================")
220
+ print("")
221
+
222
+ checks = [
223
+ ("Docker Files", check_docker_files),
224
+ ("Frontend Files", check_frontend_files),
225
+ ("Backend Files", check_backend_files),
226
+ ("Operational Files", check_operational_files),
227
+ ("Environment Variables", check_env_variables),
228
+ ("Docker Compose Structure", check_docker_compose_structure),
229
+ ("Frontend Dependencies", check_package_json)
230
+ ]
231
+
232
+ all_passed = True
233
+
234
+ for check_name, check_func in checks:
235
+ try:
236
+ result = check_func()
237
+ all_passed &= result
238
+ except Exception as e:
239
+ print(f"❌ ERROR in {check_name}: {e}")
240
+ all_passed = False
241
+
242
+ print("\n" + "=" * 50)
243
+ if all_passed:
244
+ print("βœ… ALL CHECKS PASSED!")
245
+ print("System is ready for fresh deployment")
246
+ generate_startup_commands()
247
+ else:
248
+ print("❌ SOME CHECKS FAILED")
249
+ print("Please fix the missing files/configurations before deploying")
250
+
251
+ print("=" * 50)
252
+ return all_passed
253
+
254
+ if __name__ == "__main__":
255
+ success = main()
256
+ sys.exit(0 if success else 1)
ops/scripts/seed_comprehensive.py ADDED
@@ -0,0 +1,387 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ """
3
+ Comprehensive seed script for the agentic system.
4
+ Creates multiple workflow templates and instruction types for various scenarios.
5
+ """
6
+
7
+ import requests
8
+ import json
9
+ import time
10
+ import os
11
+
12
+ # Configuration
13
+ MCP_URL = os.getenv("MCP_URL", "http://localhost:8000/mcp")
14
+ API_KEY = os.getenv("MCP_API_KEY", "dev-key-123")
15
+
16
+ def call_mcp(tool, params=None):
17
+ """Call the MCP API"""
18
+ response = requests.post(
19
+ MCP_URL,
20
+ headers={"X-API-Key": API_KEY, "Content-Type": "application/json"},
21
+ json={"tool": tool, "params": params or {}}
22
+ )
23
+ return response.json()
24
+
25
+ def create_workflow_templates():
26
+ """Create different workflow templates for various use cases"""
27
+ print("🌱 Creating workflow templates...")
28
+
29
+ workflows = [
30
+ {
31
+ "id": "template-basic-query",
32
+ "name": "Basic Data Query",
33
+ "description": "Simple question-to-SQL workflow",
34
+ "status": "template"
35
+ },
36
+ {
37
+ "id": "template-analysis",
38
+ "name": "Data Analysis Workflow",
39
+ "description": "Multi-step analysis with validation",
40
+ "status": "template"
41
+ },
42
+ {
43
+ "id": "template-report",
44
+ "name": "Report Generation",
45
+ "description": "Generate formatted reports from data",
46
+ "status": "template"
47
+ }
48
+ ]
49
+
50
+ for workflow in workflows:
51
+ result = call_mcp("write_graph", {
52
+ "action": "create_node",
53
+ "label": "WorkflowTemplate",
54
+ "properties": {
55
+ **workflow,
56
+ "created_at": time.strftime("%Y-%m-%dT%H:%M:%SZ")
57
+ }
58
+ })
59
+ print(f"βœ… Created workflow template: {workflow['name']}")
60
+
61
+ def create_instruction_types():
62
+ """Create instruction type definitions"""
63
+ print("πŸ”§ Creating instruction type definitions...")
64
+
65
+ instruction_types = [
66
+ {
67
+ "type": "discover_schema",
68
+ "name": "Schema Discovery",
69
+ "description": "Discover and analyze database schema",
70
+ "default_pause": 60,
71
+ "parameters_schema": "{}"
72
+ },
73
+ {
74
+ "type": "generate_sql",
75
+ "name": "SQL Generation",
76
+ "description": "Convert natural language to SQL",
77
+ "default_pause": 300,
78
+ "parameters_schema": json.dumps({
79
+ "question": "string",
80
+ "context": "string (optional)"
81
+ })
82
+ },
83
+ {
84
+ "type": "execute_sql",
85
+ "name": "SQL Execution",
86
+ "description": "Execute SQL query against database",
87
+ "default_pause": 120,
88
+ "parameters_schema": json.dumps({
89
+ "query": "string",
90
+ "limit": "integer (optional)"
91
+ })
92
+ },
93
+ {
94
+ "type": "validate_results",
95
+ "name": "Result Validation",
96
+ "description": "Validate and check query results",
97
+ "default_pause": 60,
98
+ "parameters_schema": json.dumps({
99
+ "validation_rules": "array (optional)"
100
+ })
101
+ },
102
+ {
103
+ "type": "format_output",
104
+ "name": "Output Formatting",
105
+ "description": "Format results for presentation",
106
+ "default_pause": 30,
107
+ "parameters_schema": json.dumps({
108
+ "format": "string (table|chart|json)",
109
+ "title": "string (optional)"
110
+ })
111
+ },
112
+ {
113
+ "type": "review_results",
114
+ "name": "Human Review",
115
+ "description": "Human review checkpoint",
116
+ "default_pause": 300,
117
+ "parameters_schema": "{}"
118
+ }
119
+ ]
120
+
121
+ for inst_type in instruction_types:
122
+ result = call_mcp("write_graph", {
123
+ "action": "create_node",
124
+ "label": "InstructionType",
125
+ "properties": {
126
+ **inst_type,
127
+ "created_at": time.strftime("%Y-%m-%dT%H:%M:%SZ")
128
+ }
129
+ })
130
+ print(f"βœ… Created instruction type: {inst_type['name']}")
131
+
132
+ def create_query_library():
133
+ """Create a library of common queries"""
134
+ print("πŸ“š Creating query library...")
135
+
136
+ queries = [
137
+ {
138
+ "id": "query-customer-count",
139
+ "category": "basic",
140
+ "question": "How many customers do we have?",
141
+ "sql": "SELECT COUNT(*) as customer_count FROM customers",
142
+ "description": "Total customer count"
143
+ },
144
+ {
145
+ "id": "query-recent-orders",
146
+ "category": "basic",
147
+ "question": "Show me recent orders",
148
+ "sql": "SELECT o.id, o.order_date, c.name, o.total_amount FROM orders o JOIN customers c ON o.customer_id = c.id ORDER BY o.order_date DESC LIMIT 10",
149
+ "description": "Last 10 orders with customer info"
150
+ },
151
+ {
152
+ "id": "query-revenue-total",
153
+ "category": "analytics",
154
+ "question": "What's our total revenue?",
155
+ "sql": "SELECT SUM(total_amount) as total_revenue FROM orders",
156
+ "description": "Sum of all order amounts"
157
+ },
158
+ {
159
+ "id": "query-top-customers",
160
+ "category": "analytics",
161
+ "question": "Who are our top customers by revenue?",
162
+ "sql": "SELECT c.name, c.email, SUM(o.total_amount) as total_spent FROM customers c JOIN orders o ON c.id = o.customer_id GROUP BY c.id, c.name, c.email ORDER BY total_spent DESC LIMIT 5",
163
+ "description": "Top 5 customers by total spending"
164
+ },
165
+ {
166
+ "id": "query-monthly-trend",
167
+ "category": "analytics",
168
+ "question": "Show monthly revenue trend",
169
+ "sql": "SELECT DATE_TRUNC('month', order_date) as month, SUM(total_amount) as monthly_revenue FROM orders GROUP BY DATE_TRUNC('month', order_date) ORDER BY month",
170
+ "description": "Revenue by month"
171
+ },
172
+ {
173
+ "id": "query-customer-orders",
174
+ "category": "detailed",
175
+ "question": "Show customers with their order details",
176
+ "sql": "SELECT c.name, c.email, o.order_date, o.total_amount, o.status FROM customers c LEFT JOIN orders o ON c.id = o.customer_id ORDER BY c.name, o.order_date DESC",
177
+ "description": "Customer and order details"
178
+ }
179
+ ]
180
+
181
+ for query in queries:
182
+ result = call_mcp("write_graph", {
183
+ "action": "create_node",
184
+ "label": "QueryTemplate",
185
+ "properties": {
186
+ **query,
187
+ "created_at": time.strftime("%Y-%m-%dT%H:%M:%SZ")
188
+ }
189
+ })
190
+ print(f"βœ… Created query: {query['description']}")
191
+
192
+ def create_demo_workflows():
193
+ """Create ready-to-run demo workflows"""
194
+ print("🎯 Creating demo workflows...")
195
+
196
+ # Demo Workflow 1: Simple Query
197
+ workflow1 = call_mcp("write_graph", {
198
+ "action": "create_node",
199
+ "label": "Workflow",
200
+ "properties": {
201
+ "id": "demo-simple-query",
202
+ "name": "Simple Customer Count",
203
+ "description": "Demo: Count total customers",
204
+ "status": "active",
205
+ "created_at": time.strftime("%Y-%m-%dT%H:%M:%SZ")
206
+ }
207
+ })
208
+
209
+ # Instructions for workflow 1
210
+ inst1 = call_mcp("write_graph", {
211
+ "action": "create_node",
212
+ "label": "Instruction",
213
+ "properties": {
214
+ "id": "demo-simple-1",
215
+ "type": "generate_sql",
216
+ "sequence": 1,
217
+ "status": "pending",
218
+ "pause_duration": 60, # 1 minute for demo
219
+ "parameters": json.dumps({"question": "How many customers do we have?"}),
220
+ "created_at": time.strftime("%Y-%m-%dT%H:%M:%SZ")
221
+ }
222
+ })
223
+
224
+ # Link instruction to workflow
225
+ call_mcp("query_graph", {
226
+ "query": "MATCH (w:Workflow {id: 'demo-simple-query'}), (i:Instruction {id: 'demo-simple-1'}) CREATE (w)-[:HAS_INSTRUCTION]->(i)"
227
+ })
228
+
229
+ print("βœ… Created simple demo workflow")
230
+
231
+ # Demo Workflow 2: Multi-step Analysis
232
+ workflow2 = call_mcp("write_graph", {
233
+ "action": "create_node",
234
+ "label": "Workflow",
235
+ "properties": {
236
+ "id": "demo-analysis",
237
+ "name": "Customer Revenue Analysis",
238
+ "description": "Demo: Multi-step customer analysis",
239
+ "status": "template", # Not active by default
240
+ "created_at": time.strftime("%Y-%m-%dT%H:%M:%SZ")
241
+ }
242
+ })
243
+
244
+ # Multi-step instructions
245
+ analysis_instructions = [
246
+ {
247
+ "id": "demo-analysis-1",
248
+ "type": "discover_schema",
249
+ "sequence": 1,
250
+ "description": "Discover customer and order tables",
251
+ "parameters": "{}"
252
+ },
253
+ {
254
+ "id": "demo-analysis-2",
255
+ "type": "generate_sql",
256
+ "sequence": 2,
257
+ "description": "Generate customer revenue query",
258
+ "parameters": json.dumps({"question": "Show me top customers by total revenue"})
259
+ },
260
+ {
261
+ "id": "demo-analysis-3",
262
+ "type": "review_results",
263
+ "sequence": 3,
264
+ "description": "Review results before final output",
265
+ "parameters": "{}"
266
+ }
267
+ ]
268
+
269
+ for inst in analysis_instructions:
270
+ call_mcp("write_graph", {
271
+ "action": "create_node",
272
+ "label": "Instruction",
273
+ "properties": {
274
+ **inst,
275
+ "status": "template",
276
+ "pause_duration": 120,
277
+ "created_at": time.strftime("%Y-%m-%dT%H:%M:%SZ")
278
+ }
279
+ })
280
+
281
+ # Link to workflow
282
+ call_mcp("query_graph", {
283
+ "query": "MATCH (w:Workflow {id: 'demo-analysis'}), (i:Instruction {id: $iid}) CREATE (w)-[:HAS_INSTRUCTION]->(i)",
284
+ "parameters": {"iid": inst["id"]}
285
+ })
286
+
287
+ # Create instruction chain
288
+ for i in range(len(analysis_instructions) - 1):
289
+ current = analysis_instructions[i]["id"]
290
+ next_inst = analysis_instructions[i + 1]["id"]
291
+ call_mcp("query_graph", {
292
+ "query": "MATCH (i1:Instruction {id: $id1}), (i2:Instruction {id: $id2}) CREATE (i1)-[:NEXT_INSTRUCTION]->(i2)",
293
+ "parameters": {"id1": current, "id2": next_inst}
294
+ })
295
+
296
+ print("βœ… Created multi-step analysis workflow")
297
+
298
+ def create_system_config():
299
+ """Create system configuration nodes"""
300
+ print("βš™οΈ Creating system configuration...")
301
+
302
+ config = {
303
+ "system_version": "1.0.0",
304
+ "default_pause_duration": 300,
305
+ "max_retry_attempts": 3,
306
+ "default_polling_interval": 30,
307
+ "supported_instruction_types": json.dumps([
308
+ "discover_schema", "generate_sql", "execute_sql",
309
+ "validate_results", "format_output", "review_results"
310
+ ]),
311
+ "created_at": time.strftime("%Y-%m-%dT%H:%M:%SZ")
312
+ }
313
+
314
+ result = call_mcp("write_graph", {
315
+ "action": "create_node",
316
+ "label": "SystemConfig",
317
+ "properties": config
318
+ })
319
+
320
+ print("βœ… Created system configuration")
321
+
322
+ def verify_seeding():
323
+ """Verify all seeded data"""
324
+ print("\nπŸ” Verifying seeded data...")
325
+
326
+ # Count nodes by type
327
+ counts = call_mcp("query_graph", {
328
+ "query": """
329
+ MATCH (n)
330
+ RETURN labels(n)[0] as label, count(n) as count
331
+ ORDER BY count DESC
332
+ """
333
+ })
334
+
335
+ print("\nπŸ“Š Node Statistics:")
336
+ for item in counts.get("data", []):
337
+ print(f" - {item['label']}: {item['count']} nodes")
338
+
339
+ # Check active workflows
340
+ active_workflows = call_mcp("query_graph", {
341
+ "query": "MATCH (w:Workflow {status: 'active'}) RETURN w.name as name"
342
+ })
343
+
344
+ if active_workflows.get("data"):
345
+ print(f"\n🎯 Active Workflows:")
346
+ for wf in active_workflows["data"]:
347
+ print(f" - {wf['name']}")
348
+
349
+ print(f"\nβœ… Comprehensive seeding completed successfully!")
350
+
351
+ def main():
352
+ print("πŸš€ Starting comprehensive seed process...")
353
+
354
+ # Check services first
355
+ try:
356
+ health_response = requests.get(f"{MCP_URL.replace('/mcp', '/health')}", timeout=5)
357
+ if health_response.status_code != 200:
358
+ print("❌ MCP service not available")
359
+ return False
360
+ except Exception as e:
361
+ print(f"❌ Service check failed: {e}")
362
+ return False
363
+
364
+ print("βœ… Services are available\n")
365
+
366
+ # Run all seeding functions
367
+ create_workflow_templates()
368
+ create_instruction_types()
369
+ create_query_library()
370
+ create_demo_workflows()
371
+ create_system_config()
372
+ verify_seeding()
373
+
374
+ print("\nπŸ“‹ What's Available:")
375
+ print("1. Open http://localhost:3000 - Frontend interface")
376
+ print("2. Open http://localhost:7474 - Neo4j Browser (neo4j/password)")
377
+ print("3. Try asking: 'How many customers do we have?'")
378
+ print("4. Check the 'Customer Revenue Analysis' workflow template")
379
+ print("5. Explore the query library for more examples")
380
+
381
+ return True
382
+
383
+ if __name__ == "__main__":
384
+ if main():
385
+ exit(0)
386
+ else:
387
+ exit(1)