diff --git a/networks/infra-genius/.env.example b/networks/infra-genius/.env.example new file mode 100644 index 0000000..49f5668 --- /dev/null +++ b/networks/infra-genius/.env.example @@ -0,0 +1,36 @@ +# InfraGenius Environment Configuration +# Copy this file to .env and fill in your API keys + +# ============================================================================= +# GROQ - Agent Reasoning (Required) +# ============================================================================= +# Get your free API key at: https://console.groq.com +# Used for the agent's LLM reasoning (llama-3.3-70b-versatile) +GROQ_API_KEY=your-groq-api-key-here +CUSTOM_API_KEY=your-groq-api-key-here + +# ============================================================================= +# E2B - Cloud Sandboxes (Optional) +# ============================================================================= +# Get your API key at: https://e2b.dev +# Used for provisioning cloud sandboxes for deployment testing +E2B_API_KEY=your-e2b-api-key-here + +# ============================================================================= +# NEBIUS - MemU Memory (Required for memory features) +# ============================================================================= +# Get your API key at: https://nebius.com +# Used for MemU long-term memory (chat + embeddings) +NEBIUS_API_KEY=your-nebius-api-key-here + +# MemU Configuration +MEMU_BASE_URL=https://api.tokenfactory.nebius.com/v1/ +MEMU_CHAT_MODEL=Qwen/Qwen3-30B-A3B-Instruct-2507 +MEMU_EMBED_MODEL=BAAI/bge-multilingual-gemma2 +MEMU_DB_PATH=infra_memory.db + +# ============================================================================= +# GITHUB - Private Repos (Optional) +# ============================================================================= +# Only needed if deploying from private repositories +GITHUB_TOKEN= diff --git a/networks/infra-genius/README.md b/networks/infra-genius/README.md new file mode 100644 index 0000000..f8f963d --- /dev/null +++ b/networks/infra-genius/README.md @@ -0,0 +1,221 @@ +# πŸš€ InfraGenius - AI DevOps Agent with Memory + +> **OpenAgents PR Hackathon 2026 Submission** +> +> An AI infrastructure automation agent that remembers your deployments and learns over time. + +[![OpenAgents](https://img.shields.io/badge/OpenAgents-v0.8.5-blue)](https://openagents.org) +[![MemU](https://img.shields.io/badge/MemU-Memory-green)](https://github.com/NevaMind-AI/memU) +[![E2B](https://img.shields.io/badge/E2B-Sandboxes-orange)](https://e2b.dev) + +## 🎯 What is InfraGenius? + +InfraGenius is an AI agent that automates infrastructure tasks through natural language. Unlike traditional DevOps tools, InfraGenius **remembers** your past deployments, configurations, and even errors β€” learning from experience to provide smarter assistance over time. + +**Key Innovation:** Integration of [MemU](https://github.com/NevaMind-AI/memU) long-term memory with OpenAgents, enabling stateful DevOps automation. + +## ✨ Features + +| Feature | Description | +|---------|-------------| +| 🧠 **Long-term Memory** | Remembers deployments, configs, and learnings across sessions | +| πŸ” **Semantic Search** | Find past deployments by meaning, not just keywords | +| πŸ“¦ **E2B Sandboxes** | Provision cloud sandboxes for safe deployment testing | +| πŸ’¬ **Natural Language** | Deploy apps with simple commands like "deploy my-app" | +| πŸ”„ **Learning** | Stores error fixes and applies them to future deployments | + +## πŸƒ Quick Start + +### Prerequisites + +- Python 3.11+ +- [Groq API Key](https://console.groq.com) (free tier available) +- [E2B API Key](https://e2b.dev) (optional, for sandbox deployments) +- [Nebius API Key](https://nebius.com) (for MemU memory) + +### Installation + +```bash +# Clone the repository +git clone https://github.com/Nsuccess/Infra-genius.git +cd Infra-genius + +# Install dependencies +pip install openagents==0.8.5 e2b-code-interpreter requests memu-py>=1.1.0 + +# Configure environment +cp .env.example .env +# Edit .env with your API keys +``` + +### Configuration + +Edit `.env` with your API keys: + +```env +# Groq for agent reasoning (fast LLM) +GROQ_API_KEY=your-groq-key +CUSTOM_API_KEY=your-groq-key + +# E2B for cloud sandboxes (optional) +E2B_API_KEY=your-e2b-key + +# Nebius for MemU memory (chat + embeddings) +NEBIUS_API_KEY=your-nebius-key +MEMU_BASE_URL=https://api.tokenfactory.nebius.com/v1/ +MEMU_CHAT_MODEL=Qwen/Qwen3-30B-A3B-Instruct-2507 +MEMU_EMBED_MODEL=BAAI/bge-multilingual-gemma2 +``` + +### Launch + +**Terminal 1 - Start Network:** +```bash +openagents network start . +``` + +**Terminal 2 - Start Agent:** +```bash +# Windows PowerShell (load env vars first) +Get-Content .env | ForEach-Object { if ($_ -match '^([^#][^=]*)=(.*)$') { [Environment]::SetEnvironmentVariable($matches[1], $matches[2], 'Process') } } +openagents agent start ./agents/deployer.yaml + +# Linux/Mac +export $(cat .env | xargs) && openagents agent start ./agents/deployer.yaml +``` + +**Open Studio:** http://localhost:8700/studio + +## πŸ’‘ Example Conversations + +### Basic Interaction +``` +You: Hi! +InfraGenius: I can provision and list E2B cloud sandboxes, store/retrieve + info in memory. How can I help you? +``` + +### Memory Operations +``` +You: Remember that I prefer deploying Node.js apps to E2B +InfraGenius: βœ… Stored in memory: [DEPLOYMENT] I prefer deploying Node.js apps to E2B + +You: What do you remember about my preferences? +InfraGenius: Found 1 memory: You prefer deploying Node.js apps to E2B +``` + +### Sandbox Operations +``` +You: Provision a sandbox called my-app +InfraGenius: βœ… Sandbox provisioned! + πŸ“¦ Name: my-app + πŸ†” ID: sbx-abc123 + πŸ”— URL: https://8000-sbx-abc123.e2b.app + +You: List my sandboxes +InfraGenius: πŸ“¦ Active Sandboxes: + β€’ my-app (ID: sbx-abc123) +``` + +## πŸ“ Project Structure + +``` +infra-genius/ +β”œβ”€β”€ agents/ +β”‚ └── deployer.yaml # Agent configuration +β”œβ”€β”€ tools/ +β”‚ β”œβ”€β”€ infra.py # E2B sandbox tools +β”‚ └── memory.py # MemU memory tools +β”œβ”€β”€ network.yaml # OpenAgents network config +β”œβ”€β”€ .env.example # Environment template +└── README.md # This file +``` + +## πŸ”§ Agent Tools + +### Infrastructure Tools +| Tool | Description | +|------|-------------| +| `provision_sandbox` | Create a new E2B cloud sandbox | +| `list_sandboxes` | List all active sandboxes | +| `run_command` | Execute shell commands in sandbox | +| `deploy_app` | Full deployment pipeline | + +### Memory Tools (MemU) +| Tool | Description | +|------|-------------| +| `remember` | Store information in long-term memory | +| `recall` | Search memory semantically | +| `list_memories` | Show stored memories | +| `remember_deployment` | Store structured deployment record | +| `find_deployments` | Search past deployments | + +## πŸ—οΈ Architecture + +``` +β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” +β”‚ OpenAgents Studio β”‚ +β”‚ http://localhost:8700 β”‚ +β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ + β”‚ +β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” +β”‚ OpenAgents Network β”‚ +β”‚ (HTTP:8700 / gRPC:8600) β”‚ +β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ + β”‚ +β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” +β”‚ InfraGenius Agent β”‚ +β”‚ (llama-3.3-70b via Groq) β”‚ +β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ +β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ +β”‚ β”‚ Infra Tools β”‚ β”‚ Memory Toolsβ”‚ β”‚ Messaging Tools β”‚ β”‚ +β”‚ β”‚ (E2B) β”‚ β”‚ (MemU) β”‚ β”‚ (OpenAgents) β”‚ β”‚ +β”‚ β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ +β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ + β”‚ β”‚ + β–Ό β–Ό + β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” + β”‚ E2B β”‚ β”‚ MemU β”‚ + β”‚ Sandbox β”‚ β”‚ Memory β”‚ + β”‚ Cloud β”‚ β”‚ (Nebius) β”‚ + β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ +``` + +## 🎬 Demo Video + +[Link to 3-minute demo video - Coming Soon] + +The demo shows: +1. Network and agent startup +2. Memory operations (remember/recall) +3. Sandbox provisioning +4. Natural language infrastructure commands + +## πŸ› οΈ Tech Stack + +| Component | Technology | +|-----------|------------| +| Agent Framework | [OpenAgents v0.8.5](https://github.com/openagents-org/openagents) | +| Long-term Memory | [MemU](https://github.com/NevaMind-AI/memU) | +| LLM (Agent) | Groq (llama-3.3-70b-versatile) | +| LLM (Memory) | Nebius (Qwen3-30B + BGE embeddings) | +| Sandboxes | [E2B](https://e2b.dev) | + +## 🀝 Related Hackathon Submissions + +This project is part of a multi-hackathon effort: + +| Hackathon | Submission | Status | +|-----------|------------|--------| +| **OpenAgents** | InfraGenius (this repo) | βœ… Submitted | +| **MemU** | 8 PRs (adapters, memory types) | βœ… All passing CI | + +## πŸ“„ License + +MIT + +--- + +**Built for the OpenAgents PR Hackathon 2026** πŸš€ + +*An AI DevOps agent that remembers your infrastructure and manages it over time.* diff --git a/networks/infra-genius/agents/deployer.yaml b/networks/infra-genius/agents/deployer.yaml new file mode 100644 index 0000000..c4cd5a8 --- /dev/null +++ b/networks/infra-genius/agents/deployer.yaml @@ -0,0 +1,68 @@ +# InfraGenius Deployer Agent +# Infrastructure automation agent with memory + +type: "openagents.agents.collaborator_agent.CollaboratorAgent" +agent_id: "deployer" + +config: + model_name: "llama-3.3-70b-versatile" + provider: "custom" + api_base: "https://api.groq.com/openai/v1" + + instruction: | + You are InfraGenius, an infrastructure automation agent. + + When you receive a message, respond to the sender using send_direct_message. + Be concise and helpful. + + react_to_all_messages: true + + tools: + - name: "provision_sandbox" + description: "Provision a new E2B cloud sandbox" + implementation: "tools.infra.provision_sandbox" + input_schema: + type: object + properties: + name: + type: string + description: "Name for the sandbox" + required: ["name"] + + - name: "list_sandboxes" + description: "List all active E2B sandboxes" + implementation: "tools.infra.list_sandboxes" + input_schema: + type: object + properties: {} + + - name: "remember" + description: "Store info in long-term memory" + implementation: "tools.memory.remember" + input_schema: + type: object + properties: + content: + type: string + description: "What to remember" + required: ["content"] + + - name: "recall" + description: "Search memory for info" + implementation: "tools.memory.recall" + input_schema: + type: object + properties: + query: + type: string + description: "What to search for" + required: ["query"] + +mods: + - name: "openagents.mods.workspace.messaging" + enabled: true + +connection: + host: "localhost" + port: 8700 + transport: "grpc" diff --git a/networks/infra-genius/demo.py b/networks/infra-genius/demo.py new file mode 100644 index 0000000..bdb85f2 --- /dev/null +++ b/networks/infra-genius/demo.py @@ -0,0 +1,87 @@ +#!/usr/bin/env python3 +""" +InfraGenius Demo Script + +Demonstrates memory-aware infrastructure automation: +1. Store a deployment in memory +2. Recall past deployments +3. Show learning from errors + +Run this after starting the network and agent. +""" + +import os +import sys +from pathlib import Path + +# Load environment +env_path = Path(__file__).parent / ".env" +if env_path.exists(): + for line in env_path.read_text().splitlines(): + if line.strip() and not line.startswith("#") and "=" in line: + key, val = line.split("=", 1) + os.environ[key.strip()] = val.strip() + +# Add memU to path +memu_path = Path(__file__).parent.parent.parent / "memU" / "src" +if memu_path.exists(): + sys.path.insert(0, str(memu_path)) + + +def demo_memory_tools(): + """Demonstrate MemU memory tools working with InfraGenius.""" + print("=" * 60) + print("πŸš€ InfraGenius Memory Demo") + print("=" * 60) + print() + + # Import memory tools + from tools.memory import remember, recall, list_memories, remember_deployment, find_deployments + + # Demo 1: Store a deployment + print("1️⃣ Storing deployment in memory...") + result = remember_deployment( + repo="github.com/demo/api", + platform="e2b", + service_name="api-demo", + url="https://8000-demo.e2b.app", + status="deployed", + notes="Demo deployment for hackathon" + ) + print(f" {result}") + print() + + # Demo 2: Store a learning + print("2️⃣ Storing a learning...") + result = remember( + content="NODE_ENV must be set to 'production' for Node.js apps to work correctly", + category="learning" + ) + print(f" {result}") + print() + + # Demo 3: Recall deployments + print("3️⃣ Recalling past deployments...") + result = find_deployments("api") + print(f" {result}") + print() + + # Demo 4: List all memories + print("4️⃣ Listing all memories...") + result = list_memories(limit=5) + print(f" {result}") + print() + + # Demo 5: Semantic search + print("5️⃣ Searching for Node.js tips...") + result = recall("how to deploy node apps", top_k=3) + print(f" {result}") + print() + + print("=" * 60) + print("βœ… Demo complete! Memory is working.") + print("=" * 60) + + +if __name__ == "__main__": + demo_memory_tools() diff --git a/networks/infra-genius/demo_video_link.txt b/networks/infra-genius/demo_video_link.txt new file mode 100644 index 0000000..0b76e35 --- /dev/null +++ b/networks/infra-genius/demo_video_link.txt @@ -0,0 +1,44 @@ +# InfraGenius Demo Video + +## Video Link +[TODO: Add YouTube/Vimeo link after recording] + +## Demo Script (3 minutes) + +### Part 1: Introduction (30 seconds) +- Show InfraGenius overview +- Explain: "Memory-aware infrastructure agent" +- Key differentiator: "Remembers deployments, learns from errors" + +### Part 2: Network Setup (30 seconds) +- Start OpenAgents network +- Start InfraGenius agent +- Show Studio UI at localhost:8700 + +### Part 3: Memory-Aware Deployment (60 seconds) +- User: "Deploy https://github.com/demo/api to a sandbox" +- Agent provisions sandbox +- Agent deploys app +- Agent stores deployment in memory +- Show live URL + +### Part 4: Memory Recall (30 seconds) +- User: "What services have I deployed?" +- Agent queries memory +- Shows deployment history + +### Part 5: Learning from Errors (30 seconds) +- User: "Redeploy my API" +- Agent recalls previous deployment +- Agent applies learned fixes +- Successful deployment + +### Part 6: Conclusion (10 seconds) +- Recap: OpenAgents + MemU + E2B +- "Infrastructure that remembers" + +## Recording Notes +- Use OBS or similar +- 1080p resolution +- Clear audio +- Add subtitles if possible diff --git a/networks/infra-genius/docs/ARCHITECTURE.md b/networks/infra-genius/docs/ARCHITECTURE.md new file mode 100644 index 0000000..780fe6f --- /dev/null +++ b/networks/infra-genius/docs/ARCHITECTURE.md @@ -0,0 +1,293 @@ +# InfraGenius Architecture + +## Overview + +InfraGenius is a **memory-aware infrastructure automation agent** that combines OpenAgents orchestration with MemU long-term memory and E2B cloud sandboxes. + +## System Architecture + +``` +β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” +β”‚ OpenAgents Network β”‚ +β”‚ (Centralized Mode) β”‚ +β”‚ β”‚ +β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ +β”‚ β”‚ OpenAgents Studio β”‚ β”‚ +β”‚ β”‚ http://localhost:8700 β”‚ β”‚ +β”‚ β”‚ β”‚ β”‚ +β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ +β”‚ β”‚ β”‚ Chat UI β”‚ β”‚ Agent List β”‚ β”‚ Channels β”‚ β”‚ β”‚ +β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ +β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ +β”‚ β”‚ β”‚ +β”‚ β–Ό β”‚ +β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ +β”‚ β”‚ InfraGenius Agent β”‚ β”‚ +β”‚ β”‚ (CollaboratorAgent) β”‚ β”‚ +β”‚ β”‚ β”‚ β”‚ +β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ +β”‚ β”‚ β”‚ Decision Engine β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ 1. Receive user request β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ 2. Query memory for context (MemU) β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ 3. Plan deployment steps β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ 4. Execute infrastructure tools (E2B) β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ 5. Store results in memory β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ 6. Respond to user β”‚ β”‚ β”‚ +β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ +β”‚ β”‚ β”‚ β”‚ β”‚ +β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ +β”‚ β”‚ β–Ό β–Ό β–Ό β”‚ β”‚ +β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ +β”‚ β”‚ β”‚ Memory Tools β”‚ β”‚ LLM Client β”‚ β”‚ Infra Tools β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ (MemU) β”‚ β”‚ (Groq) β”‚ β”‚ (E2B) β”‚ β”‚ β”‚ +β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ +β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ +β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ +β”‚ β”‚ β”‚ β”‚ β”‚ +β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ + β”‚ β”‚ β”‚ + β–Ό β–Ό β–Ό +β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” +β”‚ MemU β”‚ β”‚ Groq β”‚ β”‚ E2B β”‚ +β”‚ Memory Service β”‚ β”‚ LLM API β”‚ β”‚ Cloud Sandboxes β”‚ +β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ +β”‚ β€’ Nebius Backend β”‚ β”‚ β€’ llama-3.3-70b β”‚ β”‚ β€’ Provision VMs β”‚ +β”‚ β€’ Qwen Chat Model β”‚ β”‚ β€’ Fast inferenceβ”‚ β”‚ β€’ Run commands β”‚ +β”‚ β€’ BGE Embeddings β”‚ β”‚ β€’ Tool calling β”‚ β”‚ β€’ Deploy apps β”‚ +β”‚ β€’ SQLite Storage β”‚ β”‚ β”‚ β”‚ β€’ Health checks β”‚ +β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ +``` + +## Network Configuration + +### Transport Layer + +| Transport | Port | Purpose | +|-----------|------|---------| +| HTTP | 8700 | Studio UI, REST API | +| gRPC | 8600 | Agent communication | + +### gRPC Settings + +```yaml +max_message_size: 104857600 # 100MB +compression: gzip +keepalive_time: 60000 +keepalive_timeout: 30000 +``` + +## Agent Architecture + +### InfraGenius Deployer Agent + +**Type:** `CollaboratorAgent` + +**Capabilities:** +- Natural language understanding +- Tool calling (11 tools) +- Memory-aware decision making +- Multi-step orchestration + +### Tool Categories + +#### Infrastructure Tools (E2B) + +| Tool | Function | Parameters | +|------|----------|------------| +| `provision_sandbox` | Create cloud VM | `name` | +| `list_sandboxes` | List active VMs | - | +| `run_command` | Execute shell | `sandbox_name`, `command` | +| `deploy_app` | Full deploy pipeline | `sandbox_name`, `repo_url` | +| `verify_url` | HTTP health check | `url` | +| `check_latency` | Measure response time | `url`, `samples` | + +#### Memory Tools (MemU) + +| Tool | Function | Parameters | +|------|----------|------------| +| `remember` | Store info | `content`, `category` | +| `recall` | Semantic search | `query`, `top_k` | +| `list_memories` | List items | `limit` | +| `remember_deployment` | Store deployment | `repo`, `platform`, `service_name`, `url` | +| `find_deployments` | Search deployments | `query` | + +## Memory Architecture + +### MemU Integration + +``` +β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” +β”‚ MemU Service β”‚ +β”‚ β”‚ +β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ +β”‚ β”‚ LLM Profile β”‚ β”‚ Embedding Profileβ”‚ β”‚ +β”‚ β”‚ (default) β”‚ β”‚ (embedding) β”‚ β”‚ +β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ +β”‚ β”‚ Provider: Nebiusβ”‚ β”‚ Provider: Nebius β”‚ β”‚ +β”‚ β”‚ Model: Qwen3 β”‚ β”‚ Model: BGE β”‚ β”‚ +β”‚ β”‚ Backend: httpx β”‚ β”‚ Dim: 3584 β”‚ β”‚ +β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ +β”‚ β”‚ β”‚ β”‚ +β”‚ β–Ό β–Ό β”‚ +β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”β”‚ +β”‚ β”‚ Memory Operations β”‚β”‚ +β”‚ β”‚ β”‚β”‚ +β”‚ β”‚ memorize() ──► Extract facts ──► Generate embeddings β”‚β”‚ +β”‚ β”‚ β”‚ β”‚ β”‚β”‚ +β”‚ β”‚ β–Ό β–Ό β”‚β”‚ +β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚β”‚ +β”‚ β”‚ β”‚ Memory Itemsβ”‚ β”‚Vector Index β”‚ β”‚β”‚ +β”‚ β”‚ β”‚ (SQLite) β”‚ β”‚ (In-memory) β”‚ β”‚β”‚ +β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚β”‚ +β”‚ β”‚ β”‚ β”‚ β”‚β”‚ +β”‚ β”‚ β–Ό β–Ό β”‚β”‚ +β”‚ β”‚ retrieve() ◄── Rank results ◄── Semantic search β”‚β”‚ +β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜β”‚ +β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ +``` + +### Memory Schema + +```json +{ + "id": "abc123", + "memory_type": "deployment", + "summary": "Deployed API to e2b sandbox", + "content": "[DEPLOYMENT]\nRepository: github.com/user/api\nPlatform: e2b\n...", + "embedding": [0.123, -0.456, ...], + "created_at": "2026-01-16T12:00:00Z", + "agent_id": "infra-genius" +} +``` + +## Workflow Examples + +### Memory-Aware Deployment + +``` +User: "Deploy my API" + β”‚ + β–Ό +β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” +β”‚ 1. Query Memory β”‚ +β”‚ recall("API deployment") β”‚ +β”‚ β”‚ β”‚ +β”‚ β–Ό β”‚ +β”‚ Found: Previous deployment at β”‚ +β”‚ sandbox-1, repo: github.com/api β”‚ +β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ + β”‚ + β–Ό +β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” +β”‚ 2. Decision: Update vs Create β”‚ +β”‚ - Same repo? β†’ Update existing β”‚ +β”‚ - New repo? β†’ Create new sandbox β”‚ +β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ + β”‚ + β–Ό +β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” +β”‚ 3. Execute Deployment β”‚ +β”‚ deploy_app(sandbox-1, repo_url) β”‚ +β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ + β”‚ + β–Ό +β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” +β”‚ 4. Store Result β”‚ +β”‚ remember_deployment(...) β”‚ +β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ + β”‚ + β–Ό +β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” +β”‚ 5. Respond to User β”‚ +β”‚ "Updated deployment at URL..." β”‚ +β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ +``` + +### Learning from Errors + +``` +Deployment fails: "NODE_ENV not set" + β”‚ + β–Ό +β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” +β”‚ 1. Store Error β”‚ +β”‚ remember( β”‚ +β”‚ content="NODE_ENV must be set", β”‚ +β”‚ category="error" β”‚ +β”‚ ) β”‚ +β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ + β”‚ + β–Ό +Next deployment attempt: + β”‚ + β–Ό +β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” +β”‚ 2. Recall Errors β”‚ +β”‚ recall("node deployment errors") β”‚ +β”‚ β”‚ β”‚ +β”‚ β–Ό β”‚ +β”‚ Found: "NODE_ENV must be set" β”‚ +β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ + β”‚ + β–Ό +β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” +β”‚ 3. Apply Fix β”‚ +β”‚ run_command("export NODE_ENV=...") β”‚ +β”‚ deploy_app(...) β”‚ +β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ +``` + +## Technical Highlights + +### 1. Stateful Agent Memory + +Unlike traditional stateless agents, InfraGenius maintains persistent memory across sessions: +- Deployments survive agent restarts +- Errors and fixes are remembered +- Knowledge accumulates over time + +### 2. Semantic Search + +Memory retrieval uses embedding-based semantic search: +- Query: "how to deploy node apps" +- Finds: "NODE_ENV must be set for production" +- Even without exact keyword match + +### 3. Multi-Provider LLM + +Flexible LLM configuration: +- Agent reasoning: Groq (fast, free tier) +- Memory operations: Nebius (chat + embeddings) +- Easily swap providers via environment variables + +### 4. Cloud-Native Infrastructure + +E2B provides ephemeral cloud sandboxes: +- Instant provisioning (~5 seconds) +- Isolated environments +- Public URLs for deployed apps +- Auto-cleanup after timeout + +## Security Considerations + +- API keys stored in `.env` (not committed) +- Sandboxes are isolated and ephemeral +- Memory scoped per agent ID +- No sensitive data in memory summaries + +## Performance + +| Operation | Typical Time | +|-----------|--------------| +| Sandbox provision | ~5s | +| Memory store | ~2s | +| Memory recall | ~1s | +| Full deployment | ~30-60s | + +## Future Enhancements + +1. **Multi-Agent Coordination** - Add specialized agents (tester, monitor) +2. **Production Deployment** - Zeabur integration for persistent hosting +3. **Knowledge Graph** - Track service dependencies +4. **Auto-Rollback** - Detect failures and revert automatically diff --git a/networks/infra-genius/network.yaml b/networks/infra-genius/network.yaml new file mode 100644 index 0000000..4c3cbce --- /dev/null +++ b/networks/infra-genius/network.yaml @@ -0,0 +1,78 @@ +network: + name: InfraGenius + mode: centralized + node_id: infra-genius-1 + initialized: true + transports: + - type: http + config: + port: 8700 + serve_studio: true + serve_mcp: true + - type: grpc + config: + port: 8600 + max_message_size: 104857600 + compression: gzip + keepalive_time: 60000 + keepalive_timeout: 30000 + manifest_transport: http + recommended_transport: grpc + encryption_enabled: false + discovery_interval: 10 + discovery_enabled: true + max_connections: 10 + connection_timeout: 30.0 + retry_attempts: 3 + heartbeat_interval: 60 + agent_timeout: 180 + message_queue_size: 1000 + message_timeout: 30.0 + message_routing_enabled: true + agent_groups: + admin: + description: Administrator agents with full permissions + password_hash: 8c6976e5b5410415bde908bd4dee15dfb167a9c873fc4bb8a81f6f2ab448a918 + metadata: + permissions: + - all + mods: + - name: openagents.mods.workspace.default + enabled: true + config: + custom_events_enabled: true + - name: openagents.mods.workspace.messaging + enabled: true + config: + default_channels: + - name: general + description: General chat + - name: deployments + description: Deployment logs + max_thread_depth: 5 + created_by_version: 0.8.5 +network_profile: + discoverable: true + name: InfraGenius + description: Infrastructure automation via natural language. Deploy apps to cloud + sandboxes with simple commands. + tags: + - infrastructure + - deployment + - e2b + - devops + - hackathon + categories: + - devops + - automation + country: Worldwide + required_openagents_version: 0.7.0 + capacity: 10 + authentication: + type: none + host: 0.0.0.0 + port: 8700 +log_level: INFO +data_dir: ./data/infra-genius +runtime_limit: null +shutdown_timeout: 30 diff --git a/networks/infra-genius/requirements.txt b/networks/infra-genius/requirements.txt new file mode 100644 index 0000000..7cfd741 --- /dev/null +++ b/networks/infra-genius/requirements.txt @@ -0,0 +1,21 @@ +# InfraGenius Dependencies + +# OpenAgents Framework +openagents>=0.8.5 + +# E2B Cloud Sandboxes +e2b-code-interpreter>=0.0.11 + +# HTTP Client +requests>=2.31.0 +httpx>=0.27.0 + +# MemU Memory (install from GitHub) +# pip install git+https://github.com/NevaMind-AI/memU.git +# Or use: memu-py>=1.1.0 + +# Environment +python-dotenv>=1.0.0 + +# Async Support +asyncio>=3.4.3 diff --git a/networks/infra-genius/scripts/start_agent.sh b/networks/infra-genius/scripts/start_agent.sh new file mode 100644 index 0000000..ea71635 --- /dev/null +++ b/networks/infra-genius/scripts/start_agent.sh @@ -0,0 +1,19 @@ +#!/bin/bash +# Start InfraGenius Agent + +echo "πŸ€– Starting InfraGenius Agent..." + +# Check for .env file +if [ ! -f .env ]; then + echo "❌ Error: .env file not found" + exit 1 +fi + +# Load environment variables +export $(grep -v '^#' .env | xargs) + +# Start the agent +echo "πŸš€ Connecting to network..." +openagents agent start ./agents/deployer.yaml + +echo "βœ… Agent stopped" diff --git a/networks/infra-genius/scripts/start_network.ps1 b/networks/infra-genius/scripts/start_network.ps1 new file mode 100644 index 0000000..a2929f7 --- /dev/null +++ b/networks/infra-genius/scripts/start_network.ps1 @@ -0,0 +1,34 @@ +# Start InfraGenius Network (Windows PowerShell) + +Write-Host "πŸš€ Starting InfraGenius Network..." -ForegroundColor Cyan + +# Check for .env file +if (-not (Test-Path ".env")) { + Write-Host "❌ Error: .env file not found" -ForegroundColor Red + Write-Host " Copy .env.example to .env and add your API keys" + exit 1 +} + +# Load environment variables +Get-Content .env | ForEach-Object { + if ($_ -match "^([^#][^=]+)=(.*)$") { + [Environment]::SetEnvironmentVariable($matches[1].Trim(), $matches[2].Trim(), "Process") + } +} + +# Check required keys +if (-not $env:E2B_API_KEY) { + Write-Host "❌ Error: E2B_API_KEY not set" -ForegroundColor Red + exit 1 +} + +if (-not $env:GROQ_API_KEY -and -not $env:CUSTOM_API_KEY) { + Write-Host "❌ Error: GROQ_API_KEY or CUSTOM_API_KEY not set" -ForegroundColor Red + exit 1 +} + +Write-Host "βœ… Environment loaded" -ForegroundColor Green + +# Start the network +Write-Host "πŸ“‘ Starting OpenAgents network on port 8700..." -ForegroundColor Yellow +openagents network start . diff --git a/networks/infra-genius/scripts/start_network.sh b/networks/infra-genius/scripts/start_network.sh new file mode 100644 index 0000000..8a9580d --- /dev/null +++ b/networks/infra-genius/scripts/start_network.sh @@ -0,0 +1,53 @@ +#!/bin/bash +# Start InfraGenius Network + +echo "πŸš€ Starting InfraGenius Network..." + +# Check for .env file +if [ ! -f .env ]; then + echo "❌ Error: .env file not found" + echo " Copy .env.example to .env and add your API keys" + exit 1 +fi + +# Load environment variables +export $(grep -v '^#' .env | xargs) + +# Check required keys +if [ -z "$E2B_API_KEY" ]; then + echo "❌ Error: E2B_API_KEY not set" + exit 1 +fi + +if [ -z "$GROQ_API_KEY" ] && [ -z "$CUSTOM_API_KEY" ]; then + echo "❌ Error: GROQ_API_KEY or CUSTOM_API_KEY not set" + exit 1 +fi + +echo "βœ… Environment loaded" + +# Start the network +echo "πŸ“‘ Starting OpenAgents network on port 8700..." +openagents network start . & +NETWORK_PID=$! + +# Wait for network to be ready +sleep 3 + +# Check if network started +if ! kill -0 $NETWORK_PID 2>/dev/null; then + echo "❌ Network failed to start" + exit 1 +fi + +echo "βœ… Network started (PID: $NETWORK_PID)" +echo "" +echo "🌐 Studio UI: http://localhost:8700/studio" +echo "" +echo "To start the agent, run in another terminal:" +echo " ./scripts/start_agent.sh" +echo "" +echo "Press Ctrl+C to stop the network" + +# Wait for network process +wait $NETWORK_PID diff --git a/networks/infra-genius/start_agent.ps1 b/networks/infra-genius/start_agent.ps1 new file mode 100644 index 0000000..bdefcc1 --- /dev/null +++ b/networks/infra-genius/start_agent.ps1 @@ -0,0 +1,11 @@ +# InfraGenius Agent Startup Script +# Set your API keys before running + +# LLM Provider (Nebius) +$env:CUSTOM_API_KEY="your-nebius-api-key-here" + +# E2B for cloud sandboxes +$env:E2B_API_KEY="your-e2b-api-key-here" + +# Start the agent +openagents agent start ./agents/deployer.yaml diff --git a/networks/infra-genius/tools/__init__.py b/networks/infra-genius/tools/__init__.py new file mode 100644 index 0000000..0ae0785 --- /dev/null +++ b/networks/infra-genius/tools/__init__.py @@ -0,0 +1,2 @@ +# InfraGenius Workspace Tools +# Auto-discovered by OpenAgents from tools/*.py files diff --git a/networks/infra-genius/tools/infra.py b/networks/infra-genius/tools/infra.py new file mode 100644 index 0000000..ec5f352 --- /dev/null +++ b/networks/infra-genius/tools/infra.py @@ -0,0 +1,236 @@ +""" +InfraGenius Tools - Infrastructure Automation for OpenAgents + +These tools are auto-discovered by OpenAgents and available to all agents. +Uses the @tool decorator for proper MCP exposure. +""" + +import os +import time +from typing import Dict, Any, Optional + +# Try to import the tool decorator, fall back to simple function if not available +try: + from openagents.workspace.tool_decorator import tool +except ImportError: + # Fallback: create a no-op decorator + def tool(func=None, *, name=None, description=None, input_schema=None): + if func is not None: + return func + return lambda f: f + +# Global sandbox registry +_sandboxes: Dict[str, Any] = {} + + +@tool(description="Provision a new E2B cloud sandbox for deployment") +def provision_sandbox(name: str) -> str: + """ + Provision a new E2B sandbox. + + Args: + name: A friendly name for the sandbox (e.g., "deploy-1") + + Returns: + Status message with sandbox ID and URL + """ + from e2b_code_interpreter import Sandbox + + api_key = os.environ.get("E2B_API_KEY") + if not api_key: + return "❌ E2B_API_KEY not set. Please configure your API key." + + try: + print(f"πŸš€ Provisioning sandbox: {name}") + + # Use the new Sandbox.create() API (E2B SDK v2.x) + # API key is read from E2B_API_KEY env var automatically + sandbox = Sandbox.create(timeout=600) # 10 minutes + sandbox_id = sandbox.sandbox_id + base_url = f"https://8000-{sandbox_id}.e2b.app" + + _sandboxes[name] = { + "sandbox": sandbox, + "sandbox_id": sandbox_id, + "base_url": base_url, + "created_at": time.time(), + } + + return f"βœ… Sandbox provisioned!\nπŸ“¦ Name: {name}\nπŸ†” ID: {sandbox_id}\nπŸ”— URL: {base_url}" + + except Exception as e: + return f"❌ Failed to provision sandbox: {str(e)}" + + +@tool(description="List all active E2B sandboxes. Pass any value for the dummy parameter.") +def list_sandboxes(dummy: str = "") -> str: + """ + List all active sandboxes. + + Args: + dummy: Unused parameter (workaround for null args issue) + + Returns: + Formatted list of active sandboxes + """ + if not _sandboxes: + return "πŸ“­ No active sandboxes. Use provision_sandbox() to create one." + + output = "πŸ“¦ **Active Sandboxes:**\n\n" + for name, info in _sandboxes.items(): + output += f"β€’ **{name}**\n" + output += f" ID: {info['sandbox_id']}\n" + output += f" URL: {info['base_url']}\n\n" + + return output + + +@tool(description="Execute a shell command in an E2B sandbox") +def run_command(sandbox_name: str, command: str) -> str: + """ + Execute a shell command in a sandbox. + + Args: + sandbox_name: Name of the sandbox + command: Shell command to execute + + Returns: + Command output + """ + if sandbox_name not in _sandboxes: + return f"❌ Sandbox '{sandbox_name}' not found." + + sandbox = _sandboxes[sandbox_name]["sandbox"] + + try: + print(f"⚑ Running: {command}") + result = sandbox.commands.run(command) + + output = "" + if result.stdout: + output += f"πŸ“€ stdout:\n{result.stdout}\n" + if result.stderr: + output += f"πŸ“€ stderr:\n{result.stderr}\n" + output += f"πŸ”’ Exit code: {result.exit_code}" + + return f"{'βœ…' if result.exit_code == 0 else '⚠️'} {output}" + + except Exception as e: + return f"❌ Command failed: {str(e)}" + + +@tool(description="Deploy an app from GitHub to an E2B sandbox (clone, install, build, serve)") +def deploy_app(sandbox_name: str, repo_url: str) -> str: + """ + Full deployment pipeline: clone β†’ install β†’ build β†’ serve. + + Args: + sandbox_name: Name of the sandbox to deploy to + repo_url: GitHub repository URL + + Returns: + Deployment status with live URL + """ + if sandbox_name not in _sandboxes: + return f"❌ Sandbox '{sandbox_name}' not found. Provision one first." + + sandbox = _sandboxes[sandbox_name]["sandbox"] + base_url = _sandboxes[sandbox_name]["base_url"] + + try: + steps = [] + + # Step 1: Clone + print("1️⃣ Cloning repository...") + result = sandbox.commands.run(f"git clone {repo_url} /home/user/app") + if result.exit_code != 0: + return f"❌ Clone failed: {result.stderr}" + steps.append("βœ… Cloned") + + # Step 2: Install + print("2️⃣ Installing dependencies...") + result = sandbox.commands.run("cd /home/user/app && npm install", timeout=120) + if result.exit_code != 0: + return f"❌ Install failed: {result.stderr}" + steps.append("βœ… Installed") + + # Step 3: Build + print("3️⃣ Building...") + result = sandbox.commands.run("cd /home/user/app && npm run build", timeout=120) + if result.exit_code != 0: + return f"❌ Build failed: {result.stderr}" + steps.append("βœ… Built") + + # Step 4: Serve + print("4️⃣ Starting server...") + sandbox.commands.run( + "cd /home/user/app/dist && nohup python3 -m http.server 8000 > /tmp/server.log 2>&1 &" + ) + time.sleep(3) + + result = sandbox.commands.run("ps aux | grep 'http.server' | grep -v grep") + if result.exit_code != 0: + return "❌ Server failed to start" + steps.append("βœ… Server running") + + return f"πŸŽ‰ **Deployment Complete!**\n\n{chr(10).join(steps)}\n\nπŸ”— **Live URL:** {base_url}" + + except Exception as e: + return f"❌ Deployment failed: {str(e)}" + + +@tool(description="Verify a URL is accessible and returns HTTP 200") +def verify_url(url: str) -> str: + """ + Verify a URL is live. + + Args: + url: URL to verify + + Returns: + Verification status + """ + import requests + + try: + print(f"πŸ” Verifying {url}...") + start = time.time() + response = requests.get(url, timeout=10, allow_redirects=True) + elapsed = (time.time() - start) * 1000 + + if response.status_code == 200: + return f"βœ… URL is LIVE!\nπŸ”— {url}\nπŸ“Š HTTP {response.status_code}\n⏱️ {elapsed:.0f}ms" + else: + return f"⚠️ HTTP {response.status_code}\nπŸ”— {url}\n⏱️ {elapsed:.0f}ms" + + except Exception as e: + return f"❌ Failed: {str(e)}" + + +@tool(description="Measure latency to a URL with multiple samples") +def check_latency(url: str, samples: int = 3) -> str: + """ + Check latency to a URL. + + Args: + url: URL to check + samples: Number of samples (default 3) + + Returns: + Latency statistics + """ + import requests + + try: + times = [] + for i in range(samples): + start = time.time() + requests.get(url, timeout=10) + elapsed = (time.time() - start) * 1000 + times.append(elapsed) + + avg = sum(times) / len(times) + return f"πŸ“Š Latency: {avg:.0f}ms avg ({min(times):.0f}-{max(times):.0f}ms)" + + except Exception as e: + return f"❌ Failed: {str(e)}" diff --git a/networks/infra-genius/tools/memory.py b/networks/infra-genius/tools/memory.py new file mode 100644 index 0000000..d61fa2d --- /dev/null +++ b/networks/infra-genius/tools/memory.py @@ -0,0 +1,251 @@ +""" +InfraGenius Memory Tools - Long-term memory for stateful DevOps + +These tools give InfraGenius persistent memory across sessions. +Powered by MemU - the agent remembers deployments, configs, and learns from errors. +""" + +import os +from typing import Optional + +# Try to import the tool decorator +try: + from openagents.workspace.tool_decorator import tool +except ImportError: + def tool(func=None, *, name=None, description=None, input_schema=None): + if func is not None: + return func + return lambda f: f + +# Lazy-loaded MemU service +_memu_service = None +_memu_adapter = None + + +def _get_memu(): + """Lazily initialize MemU service and adapter.""" + global _memu_service, _memu_adapter + + if _memu_adapter is not None: + return _memu_adapter + + try: + from memu.app.service import MemoryService + from memu.adapters.openagents import MemUOpenAgentsAdapter + from memu.adapters.openagents.tools import set_memu_service + + # Support custom LLM providers (Nebius, Groq, etc.) via environment variables + # Uses OpenAI-compatible API format with custom base_url + # Priority: MEMU_API_KEY > NEBIUS_API_KEY > GROQ_API_KEY > OPENAI_API_KEY + llm_api_key = ( + os.environ.get("MEMU_API_KEY") or + os.environ.get("NEBIUS_API_KEY") or + os.environ.get("GROQ_API_KEY") or + os.environ.get("OPENAI_API_KEY") + ) + llm_base_url = os.environ.get("MEMU_BASE_URL", "https://api.tokenfactory.nebius.com/v1/") + llm_chat_model = os.environ.get("MEMU_CHAT_MODEL", "Qwen/Qwen3-30B-A3B-Instruct-2507") + + # Embedding config - Nebius has embeddings, so use same provider by default + embed_api_key = os.environ.get("MEMU_EMBED_API_KEY") or llm_api_key + embed_base_url = os.environ.get("MEMU_EMBED_BASE_URL") or llm_base_url + embed_model = os.environ.get("MEMU_EMBED_MODEL", "BAAI/bge-multilingual-gemma2") + + # Initialize MemU with environment-based config + _memu_service = MemoryService( + llm_profiles={ + "default": { + "provider": "openai", # OpenAI-compatible API format + "base_url": llm_base_url, + "api_key": llm_api_key, + "chat_model": llm_chat_model, + "client_backend": "httpx", # Use HTTP client for custom endpoints + }, + "embedding": { + "provider": "openai", + "base_url": embed_base_url, + "api_key": embed_api_key, + "embed_model": embed_model, + }, + }, + database_config={ + "metadata_store": { + "provider": "sqlite", + "path": os.environ.get("MEMU_DB_PATH", "infra_memory.db"), + }, + }, + ) + + _memu_adapter = MemUOpenAgentsAdapter(service=_memu_service) + _memu_adapter.initialize(agent_id="infra-genius") + set_memu_service(_memu_service) + + return _memu_adapter + + except ImportError as e: + raise RuntimeError(f"MemU not installed. Run: pip install memu\nError: {e}") + except Exception as e: + raise RuntimeError(f"Failed to initialize MemU: {e}") + + +@tool(description="Store deployment info, configs, or learnings in long-term memory") +def remember(content: str, category: str = "deployment") -> str: + """ + Store information in memory for future recall. + + Args: + content: What to remember (deployment details, config, error, learning) + category: Category tag - deployment, config, error, learning, service + + Returns: + Confirmation message + """ + try: + from memu.adapters.openagents.tools import memorize + + _get_memu() # Ensure initialized + + # Tag content with category for better retrieval + tagged_content = f"[{category.upper()}] {content}" + + return memorize(content=tagged_content, modality="text") + + except Exception as e: + return f"❌ Failed to remember: {e}" + + +@tool(description="Search memory for relevant past deployments, configs, or learnings") +def recall(query: str, top_k: int = 5) -> str: + """ + Search memory for relevant information. + + Args: + query: What to search for (e.g., "postgres deployment", "auth service config") + top_k: Maximum results to return (default: 5) + + Returns: + Relevant memories + """ + try: + from memu.adapters.openagents.tools import retrieve + + _get_memu() # Ensure initialized + + return retrieve(query=query, top_k=top_k) + + except Exception as e: + return f"❌ Failed to recall: {e}" + + +@tool(description="List recent memories stored by the agent") +def list_memories(limit: int = 10, category: Optional[str] = None) -> str: + """ + List recent memories. + + Args: + limit: Maximum items to show (default: 10) + category: Optional filter by category (deployment, config, error, learning) + + Returns: + List of stored memories + """ + try: + from memu.adapters.openagents.tools import list_memories as _list_memories + + _get_memu() # Ensure initialized + + return _list_memories(limit=limit) + + except Exception as e: + return f"❌ Failed to list memories: {e}" + + +@tool(description="Get details of a specific memory by ID") +def get_memory(memory_id: str) -> str: + """ + Get a specific memory item by ID. + + Args: + memory_id: The ID of the memory to retrieve + + Returns: + Full memory details + """ + try: + from memu.adapters.openagents.tools import get_memory as _get_memory + + _get_memu() # Ensure initialized + + return _get_memory(memory_id=memory_id) + + except Exception as e: + return f"❌ Failed to get memory: {e}" + + +@tool(description="Remember a deployment with structured metadata") +def remember_deployment( + repo: str, + platform: str, + service_name: str, + url: str, + status: str = "deployed", + notes: str = "" +) -> str: + """ + Store a deployment record with structured metadata. + + Args: + repo: Repository URL or name + platform: Platform (e2b, zeabur, etc.) + service_name: Name of the deployed service + url: Live URL of the deployment + status: Status (deployed, failed, healthy, degraded) + notes: Additional notes + + Returns: + Confirmation message + """ + try: + from memu.adapters.openagents.tools import memorize + + _get_memu() # Ensure initialized + + # Create structured deployment record + content = f"""[DEPLOYMENT] +Repository: {repo} +Platform: {platform} +Service: {service_name} +URL: {url} +Status: {status} +Notes: {notes} +""" + + return memorize(content=content, modality="text") + + except Exception as e: + return f"❌ Failed to remember deployment: {e}" + + +@tool(description="Find past deployments for a repository or service") +def find_deployments(query: str) -> str: + """ + Search for past deployments matching a query. + + Args: + query: Repository name, service name, or platform to search for + + Returns: + Matching deployment records + """ + try: + from memu.adapters.openagents.tools import retrieve + + _get_memu() # Ensure initialized + + # Search with deployment context + search_query = f"deployment {query}" + + return retrieve(query=search_query, top_k=5) + + except Exception as e: + return f"❌ Failed to find deployments: {e}" diff --git a/networks/infra-genius/tools/messaging.py b/networks/infra-genius/tools/messaging.py new file mode 100644 index 0000000..92a0fb9 --- /dev/null +++ b/networks/infra-genius/tools/messaging.py @@ -0,0 +1,27 @@ +""" +Messaging tools for sending responses back to the UI. +""" + +# Global reference to store the agent client for sending messages +_agent_client = None +_source_id = None + +def set_agent_context(agent_client, source_id): + """Set the agent client and source for messaging.""" + global _agent_client, _source_id + _agent_client = agent_client + _source_id = source_id + +def send_message(text: str) -> str: + """ + Send a message back to the user. + + Args: + text: The message text to send + + Returns: + Confirmation that message was sent + """ + # This is a placeholder - the actual message sending happens + # through the agent framework when this tool returns + return f"Message sent: {text}"