God Agent v7 commited on
Commit
fe91ccd
·
1 Parent(s): d5651c6

feat: God Agent OS v7 — 16-agent autonomous engineering OS

Browse files

NEW agents: BrowserAgent, FileAgent, GitAgent, TestAgent, VisionAgent
NEW: orchestrator_v7.py with parallel execution & self-healing
NEW: main_v7.py entry point
Updated: Dockerfile (port 7860), requirements.txt, README

Dockerfile CHANGED
@@ -1,23 +1,27 @@
1
- FROM python:3.12-slim
2
 
3
  WORKDIR /app
4
 
5
- RUN apt-get update && apt-get install -y \
6
- git curl build-essential \
7
- && rm -rf /var/lib/apt/lists/*
 
8
 
 
9
  COPY requirements.txt .
10
  RUN pip install --no-cache-dir -r requirements.txt
11
 
 
12
  COPY . .
13
 
14
- RUN mkdir -p /tmp/god_workspace /tmp/workspace
 
15
 
16
- ENV PYTHONUNBUFFERED=1
17
- ENV DB_PATH=/tmp/devin_agent.db
18
- ENV WORKSPACE_DIR=/tmp/god_workspace
19
  ENV PORT=7860
 
 
20
 
21
  EXPOSE 7860
22
 
23
- CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "7860", "--workers", "1", "--timeout-keep-alive", "75"]
 
1
+ FROM python:3.11-slim
2
 
3
  WORKDIR /app
4
 
5
+ # System deps
6
+ RUN apt-get update && apt-get install -y --no-install-recommends \
7
+ git curl build-essential && \
8
+ rm -rf /var/lib/apt/lists/*
9
 
10
+ # Python deps
11
  COPY requirements.txt .
12
  RUN pip install --no-cache-dir -r requirements.txt
13
 
14
+ # Copy backend source
15
  COPY . .
16
 
17
+ # Workspace dir
18
+ RUN mkdir -p /tmp/god_workspace
19
 
20
+ # HF Spaces runs on port 7860
 
 
21
  ENV PORT=7860
22
+ ENV WORKSPACE_DIR=/tmp/god_workspace
23
+ ENV PYTHONPATH=/app
24
 
25
  EXPOSE 7860
26
 
27
+ CMD ["uvicorn", "main_v7:app", "--host", "0.0.0.0", "--port", "7860", "--workers", "1"]
README.md CHANGED
@@ -1,58 +1,52 @@
1
  ---
2
- title: Devin Agent Platform
3
  emoji: 🤖
4
- colorFrom: blue
5
  colorTo: purple
6
  sdk: docker
7
  app_port: 7860
8
  pinned: true
9
  license: mit
10
- short_description: Production-grade autonomous AI engineering platform
11
  ---
12
 
13
- # 🤖 Devin Agent Platform v2.0
14
-
15
- > **Manus/Devin-style Autonomous AI Engineering Platform**
16
- > Real-time WebSocket streaming · Autonomous GitHub operations · Persistent memory
17
-
18
- ## ✨ Features
19
-
20
- - ⚡ **Real-time WebSocket streaming** — live token-by-token LLM output
21
- - 🗺️ **Autonomous task planning** — goal → plan → execute automatically
22
- - 🧠 **Persistent memory** — SQLite-backed conversation + project memory
23
- - 🐙 **GitHub automation** clone, commit, push, PR, issues autonomously
24
- - 🔁 **Self-healing** auto-retry with exponential backoff
25
- - 📡 **SSE fallback** Server-Sent Events for streaming compatibility
26
- - 🌐 **REST + WebSocket API** full-featured backend
27
-
28
- ## 🔌 API Endpoints
29
-
30
- | Method | Endpoint | Description |
31
- |--------|----------|-------------|
32
- | POST | `/api/v1/tasks/create` | Create autonomous task |
33
- | GET | `/api/v1/tasks/{id}` | Get task details |
34
- | POST | `/api/v1/tasks/{id}/cancel` | Cancel task |
35
- | POST | `/api/v1/tasks/{id}/retry` | Retry failed task |
36
- | GET | `/api/v1/tasks/{id}/stream` | SSE task stream |
37
- | POST | `/api/v1/chat` | Chat with agent |
38
- | POST | `/api/v1/goal` | Submit high-level goal |
39
- | POST | `/api/v1/plan` | Generate execution plan |
40
- | WS | `/ws/tasks/{task_id}` | Live task WebSocket |
41
- | WS | `/ws/logs` | Global log stream |
42
- | WS | `/ws/chat/{session_id}` | Chat WebSocket |
43
- | WS | `/ws/agent/status` | Agent status stream |
44
-
45
- ## 🔑 Environment Variables (HF Secrets)
46
-
47
- ```
48
- OPENAI_API_KEY = sk-... (for real AI)
49
- ANTHROPIC_API_KEY = sk-ant-... (alternative)
50
- GITHUB_TOKEN = ghp_... (GitHub ops)
51
- GITHUB_OWNER = your-username (GitHub ops)
52
- ```
53
-
54
- ## 🚀 Quick Start
55
-
56
- Visit `/api/docs` for interactive Swagger UI.
57
-
58
- **Demo mode** works without any API keys — set `OPENAI_API_KEY` for real AI.
 
1
  ---
2
+ title: God Agent OS v7
3
  emoji: 🤖
4
+ colorFrom: indigo
5
  colorTo: purple
6
  sdk: docker
7
  app_port: 7860
8
  pinned: true
9
  license: mit
10
+ short_description: Autonomous Engineering OS Manus + Genspark + Devin (OneHand)
11
  ---
12
 
13
+ # 🤖 GOD AGENT OS v7
14
+ **Autonomous Engineering Operating System**
15
+ *Manus + Genspark + Devin (OneHand) — Combined*
16
+
17
+ [![GitHub](https://img.shields.io/badge/GitHub-god--agent--os-blue?logo=github)](https://github.com/pyaesonegtckglay-dotcom/god-agent-os)
18
+
19
+ ## 🚀 16-Agent Fleet
20
+
21
+ | Agent | Capability |
22
+ |-------|-----------|
23
+ | 🧠 OrchestratorV7 | Central brain, parallel routing |
24
+ | 📋 Planner | Task graph decomposition |
25
+ | 💻 Coding | Production code generation |
26
+ | 🐛 Debug | Self-healing error resolution |
27
+ | 🌐 **Browser** ⭐ | Web research & scraping |
28
+ | 📁 **File** ⭐ | File system & project scaffold |
29
+ | 🔀 **Git** ⭐ | Git ops & GitHub PR creation |
30
+ | 🧪 **Test** | Auto test generation & execution |
31
+ | 🎨 **Vision** ⭐ | Design-to-code UI generation |
32
+ | 🖥️ Sandbox | Isolated code execution |
33
+ | 🚀 Deploy | Auto-deploy to cloud |
34
+ | 🔌 Connector | External integrations |
35
+ | 🧠 Memory | Long-term context |
36
+ | ⚙️ Workflow | n8n automation |
37
+ | 🎯 UI | Real-time UI updates |
38
+ | 🤔 Reasoning | Deep reasoning chains |
39
+
40
+ ## 🔑 Environment Variables (Set in Space Settings)
41
+
42
+ | Variable | Description |
43
+ |----------|-------------|
44
+ | `OPENAI_API_KEY` | GPT-4o (optional) |
45
+ | `GROQ_API_KEY` | Llama 3.3 70B — **Free & Recommended!** |
46
+ | `OPENROUTER_API_KEY` | 100+ models |
47
+ | `ANTHROPIC_API_KEY` | Claude 3.5 |
48
+ | `GITHUB_TOKEN` | Git operations |
49
+
50
+ ## API
51
+ - `/api/docs` — Interactive API documentation
52
+ - `/` — System status & agent list
 
 
 
 
 
 
agents/browser_agent.py ADDED
@@ -0,0 +1,147 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ BrowserAgent v7 — Autonomous web browsing, scraping, research (Manus-style)
3
+ Real browser control via Playwright/httpx for research, testing, web automation
4
+ """
5
+ import asyncio
6
+ import json
7
+ import os
8
+ import re
9
+ from typing import Dict, List, Optional
10
+ import structlog
11
+ from .base_agent import BaseAgent
12
+
13
+ log = structlog.get_logger()
14
+
15
+ BROWSER_SYSTEM = """You are an elite autonomous web research and browser automation agent.
16
+ You can:
17
+ - Search the web and extract structured information
18
+ - Navigate websites and fill forms
19
+ - Take screenshots and analyze visual content
20
+ - Scrape and parse complex web pages
21
+ - Run web automation tasks
22
+
23
+ Always provide structured, actionable results with source URLs.
24
+ """
25
+
26
+ class BrowserAgent(BaseAgent):
27
+ def __init__(self, ws_manager=None, ai_router=None):
28
+ super().__init__("BrowserAgent", ws_manager, ai_router)
29
+ self._session_cache: Dict[str, str] = {}
30
+
31
+ async def run(self, task: str, context: Dict = {}, **kwargs) -> str:
32
+ session_id = kwargs.get("session_id", "")
33
+ task_id = kwargs.get("task_id", "")
34
+
35
+ await self.emit(task_id, "agent_start", {
36
+ "agent": "BrowserAgent",
37
+ "task": task[:80],
38
+ }, session_id)
39
+
40
+ await self.emit(task_id, "tool_called", {
41
+ "agent": "BrowserAgent",
42
+ "tool": "web_research",
43
+ "step": f"Researching: {task[:60]}",
44
+ }, session_id)
45
+
46
+ # Extract search query or URL from task
47
+ urls = re.findall(r'https?://[^\s]+', task)
48
+
49
+ if urls:
50
+ result = await self._fetch_and_analyze(urls[0], task, task_id, session_id)
51
+ else:
52
+ result = await self._web_research(task, task_id, session_id)
53
+
54
+ await self.emit(task_id, "browser_result", {
55
+ "agent": "BrowserAgent",
56
+ "result_length": len(result),
57
+ }, session_id)
58
+
59
+ return result
60
+
61
+ async def _web_research(self, query: str, task_id: str, session_id: str) -> str:
62
+ """Perform web research using AI knowledge + httpx."""
63
+ import httpx
64
+
65
+ # Use DuckDuckGo search API (no key needed)
66
+ search_url = f"https://api.duckduckgo.com/?q={query.replace(' ', '+')}&format=json&no_html=1"
67
+
68
+ try:
69
+ async with httpx.AsyncClient(timeout=15, follow_redirects=True) as client:
70
+ resp = await client.get(search_url, headers={"User-Agent": "GodAgent/7.0"})
71
+ data = resp.json()
72
+
73
+ results = []
74
+ if data.get("AbstractText"):
75
+ results.append(f"**Summary:** {data['AbstractText']}")
76
+ if data.get("AbstractURL"):
77
+ results.append(f"**Source:** {data['AbstractURL']}")
78
+
79
+ related = data.get("RelatedTopics", [])[:5]
80
+ if related:
81
+ results.append("\n**Related:**")
82
+ for r in related:
83
+ if isinstance(r, dict) and r.get("Text"):
84
+ results.append(f"- {r['Text'][:200]}")
85
+
86
+ if results:
87
+ search_context = "\n".join(results)
88
+ else:
89
+ search_context = f"Web search for: {query}"
90
+
91
+ except Exception as e:
92
+ search_context = f"Search context for: {query}"
93
+
94
+ # Use AI to synthesize research
95
+ messages = [
96
+ {"role": "system", "content": BROWSER_SYSTEM},
97
+ {"role": "user", "content": (
98
+ f"Research task: {query}\n\n"
99
+ f"Search context:\n{search_context}\n\n"
100
+ f"Provide a comprehensive, structured research report with key findings, "
101
+ f"actionable insights, and relevant sources. Format with headers and bullet points."
102
+ )},
103
+ ]
104
+ return await self.llm(messages, task_id=task_id, session_id=session_id, temperature=0.3, max_tokens=4096)
105
+
106
+ async def _fetch_and_analyze(self, url: str, task: str, task_id: str, session_id: str) -> str:
107
+ """Fetch a URL and analyze its content."""
108
+ import httpx
109
+
110
+ try:
111
+ async with httpx.AsyncClient(timeout=20, follow_redirects=True) as client:
112
+ resp = await client.get(url, headers={
113
+ "User-Agent": "Mozilla/5.0 GodAgent/7.0",
114
+ "Accept": "text/html,application/json,*/*",
115
+ })
116
+ content_type = resp.headers.get("content-type", "")
117
+
118
+ if "json" in content_type:
119
+ page_content = json.dumps(resp.json(), indent=2)[:3000]
120
+ else:
121
+ # Strip HTML tags
122
+ html = resp.text
123
+ text = re.sub(r'<[^>]+>', ' ', html)
124
+ text = re.sub(r'\s+', ' ', text).strip()
125
+ page_content = text[:3000]
126
+
127
+ except Exception as e:
128
+ page_content = f"Could not fetch {url}: {str(e)}"
129
+
130
+ messages = [
131
+ {"role": "system", "content": BROWSER_SYSTEM},
132
+ {"role": "user", "content": (
133
+ f"Analyze this web page content for the task: {task}\n\n"
134
+ f"URL: {url}\n\n"
135
+ f"Page Content:\n{page_content}\n\n"
136
+ f"Provide a structured analysis with key information extracted."
137
+ )},
138
+ ]
139
+ return await self.llm(messages, task_id=task_id, session_id=session_id, temperature=0.3, max_tokens=4096)
140
+
141
+ async def screenshot_analyze(self, url: str, task_id: str = "", session_id: str = "") -> str:
142
+ """Describe what a webpage looks like (AI-powered visual analysis)."""
143
+ messages = [
144
+ {"role": "system", "content": BROWSER_SYSTEM},
145
+ {"role": "user", "content": f"Describe the visual layout and UI elements you'd expect at: {url}. Provide a detailed visual analysis."},
146
+ ]
147
+ return await self.llm(messages, task_id=task_id, session_id=session_id, temperature=0.5)
agents/file_agent.py ADDED
@@ -0,0 +1,227 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ FileAgent v7 — Autonomous file system management, code editing, project scaffolding
3
+ Like Devin's file browser + OneHand's file manipulation
4
+ """
5
+ import asyncio
6
+ import json
7
+ import os
8
+ import re
9
+ import shutil
10
+ from pathlib import Path
11
+ from typing import Dict, List, Optional
12
+ import structlog
13
+ from .base_agent import BaseAgent
14
+
15
+ log = structlog.get_logger()
16
+
17
+ FILE_SYSTEM = """You are an elite file system and project management agent.
18
+ You can:
19
+ - Create, read, edit, delete files and directories
20
+ - Scaffold complete project structures
21
+ - Analyze codebases and suggest improvements
22
+ - Generate file trees and project maps
23
+ - Apply patches and diffs to code files
24
+ - Manage project configuration files
25
+
26
+ Always provide complete, runnable file content.
27
+ """
28
+
29
+ WORKSPACE = os.environ.get("WORKSPACE_DIR", "/tmp/god_workspace")
30
+
31
+ class FileAgent(BaseAgent):
32
+ def __init__(self, ws_manager=None, ai_router=None):
33
+ super().__init__("FileAgent", ws_manager, ai_router)
34
+ os.makedirs(WORKSPACE, exist_ok=True)
35
+
36
+ async def run(self, task: str, context: Dict = {}, **kwargs) -> str:
37
+ session_id = kwargs.get("session_id", "")
38
+ task_id = kwargs.get("task_id", "")
39
+
40
+ await self.emit(task_id, "agent_start", {"agent": "FileAgent", "task": task[:80]}, session_id)
41
+
42
+ task_lower = task.lower()
43
+ if any(k in task_lower for k in ["create", "scaffold", "generate", "new project", "init"]):
44
+ result = await self._scaffold_project(task, context, task_id, session_id)
45
+ elif any(k in task_lower for k in ["read", "show", "view", "list", "tree"]):
46
+ result = await self._read_or_list(task, task_id, session_id)
47
+ elif any(k in task_lower for k in ["edit", "modify", "update", "change", "fix", "patch"]):
48
+ result = await self._edit_file(task, context, task_id, session_id)
49
+ elif any(k in task_lower for k in ["delete", "remove", "clean"]):
50
+ result = await self._delete_files(task, task_id, session_id)
51
+ else:
52
+ result = await self._ai_file_task(task, context, task_id, session_id)
53
+
54
+ return result
55
+
56
+ async def _scaffold_project(self, task: str, context: Dict, task_id: str, session_id: str) -> str:
57
+ """Scaffold a complete project structure."""
58
+ await self.emit(task_id, "tool_called", {
59
+ "agent": "FileAgent", "tool": "scaffold_project", "step": "Generating project structure"
60
+ }, session_id)
61
+
62
+ messages = [
63
+ {"role": "system", "content": FILE_SYSTEM},
64
+ {"role": "user", "content": (
65
+ f"Task: {task}\n\n"
66
+ "Generate a complete project scaffold. Return a JSON object with this structure:\n"
67
+ "{\n"
68
+ ' "project_name": "name",\n'
69
+ ' "files": [\n'
70
+ ' {"path": "relative/path/file.ext", "content": "full file content here"}\n'
71
+ " ],\n"
72
+ ' "description": "what was created",\n'
73
+ ' "run_commands": ["npm install", "npm run dev"]\n'
74
+ "}\n"
75
+ "Include all necessary files for a working project."
76
+ )},
77
+ ]
78
+ response = await self.llm(messages, task_id=task_id, session_id=session_id, temperature=0.2, max_tokens=8192)
79
+
80
+ # Parse JSON and create files
81
+ created_files = []
82
+ try:
83
+ start = response.find("{")
84
+ end = response.rfind("}") + 1
85
+ if start >= 0 and end > start:
86
+ data = json.loads(response[start:end])
87
+ project_name = data.get("project_name", "project")
88
+ project_path = os.path.join(WORKSPACE, project_name)
89
+ os.makedirs(project_path, exist_ok=True)
90
+
91
+ for f in data.get("files", []):
92
+ filepath = os.path.join(project_path, f["path"])
93
+ os.makedirs(os.path.dirname(filepath), exist_ok=True)
94
+ with open(filepath, "w") as fp:
95
+ fp.write(f["content"])
96
+ created_files.append(f["path"])
97
+ await self.emit(task_id, "file_written", {
98
+ "path": f["path"], "size": len(f["content"])
99
+ }, session_id)
100
+
101
+ result = (
102
+ f"✅ **Project Scaffolded**: `{project_name}`\n\n"
103
+ f"**Files Created** ({len(created_files)}):\n"
104
+ + "\n".join(f"- `{f}`" for f in created_files)
105
+ + f"\n\n**Description:** {data.get('description', '')}\n\n"
106
+ + "**Run Commands:**\n"
107
+ + "\n".join(f"```\n{cmd}\n```" for cmd in data.get("run_commands", []))
108
+ )
109
+ return result
110
+ except Exception as e:
111
+ log.warning("Failed to parse project scaffold JSON", error=str(e))
112
+
113
+ return response
114
+
115
+ async def _read_or_list(self, task: str, task_id: str, session_id: str) -> str:
116
+ """Read files or list directory structure."""
117
+ await self.emit(task_id, "tool_called", {
118
+ "agent": "FileAgent", "tool": "read_files", "step": "Reading file system"
119
+ }, session_id)
120
+
121
+ # Extract path from task
122
+ path_match = re.search(r'["\']([^"\']+)["\']|(\S+\.\w+)', task)
123
+ target_path = path_match.group(1) or path_match.group(2) if path_match else WORKSPACE
124
+
125
+ if not os.path.isabs(target_path):
126
+ target_path = os.path.join(WORKSPACE, target_path)
127
+
128
+ if os.path.isdir(target_path):
129
+ tree = self._get_tree(target_path)
130
+ return f"**Directory Tree:** `{target_path}`\n\n```\n{tree}\n```"
131
+ elif os.path.isfile(target_path):
132
+ with open(target_path) as f:
133
+ content = f.read()
134
+ return f"**File:** `{target_path}`\n\n```\n{content[:4000]}\n```"
135
+ else:
136
+ # List workspace
137
+ tree = self._get_tree(WORKSPACE, max_depth=3)
138
+ return f"**Workspace:** `{WORKSPACE}`\n\n```\n{tree}\n```"
139
+
140
+ async def _edit_file(self, task: str, context: Dict, task_id: str, session_id: str) -> str:
141
+ """Edit a file based on instructions."""
142
+ await self.emit(task_id, "tool_called", {
143
+ "agent": "FileAgent", "tool": "edit_file", "step": "Editing file"
144
+ }, session_id)
145
+
146
+ messages = [
147
+ {"role": "system", "content": FILE_SYSTEM},
148
+ {"role": "user", "content": (
149
+ f"Task: {task}\n\n"
150
+ f"Context: {json.dumps(context)[:500]}\n\n"
151
+ "Return a JSON with: {\"filepath\": \"path\", \"content\": \"full new file content\", \"explanation\": \"what changed\"}"
152
+ )},
153
+ ]
154
+ response = await self.llm(messages, task_id=task_id, session_id=session_id, temperature=0.1, max_tokens=8192)
155
+
156
+ try:
157
+ start = response.find("{")
158
+ end = response.rfind("}") + 1
159
+ if start >= 0 and end > start:
160
+ data = json.loads(response[start:end])
161
+ filepath = os.path.join(WORKSPACE, data.get("filepath", "output.txt"))
162
+ os.makedirs(os.path.dirname(filepath), exist_ok=True)
163
+ with open(filepath, "w") as f:
164
+ f.write(data.get("content", ""))
165
+ await self.emit(task_id, "file_written", {"path": data.get("filepath"), "edited": True}, session_id)
166
+ return f"✅ **File Edited:** `{data.get('filepath')}`\n\n{data.get('explanation', '')}"
167
+ except Exception:
168
+ pass
169
+ return response
170
+
171
+ async def _delete_files(self, task: str, task_id: str, session_id: str) -> str:
172
+ """Delete files or directories safely."""
173
+ path_match = re.search(r'["\']([^"\']+)["\']', task)
174
+ if path_match:
175
+ target = os.path.join(WORKSPACE, path_match.group(1))
176
+ if os.path.exists(target) and WORKSPACE in target:
177
+ if os.path.isdir(target):
178
+ shutil.rmtree(target)
179
+ else:
180
+ os.remove(target)
181
+ await self.emit(task_id, "file_deleted", {"path": path_match.group(1)}, session_id)
182
+ return f"✅ Deleted: `{path_match.group(1)}`"
183
+ return "❌ Could not find file/directory to delete. Please specify the path in quotes."
184
+
185
+ async def _ai_file_task(self, task: str, context: Dict, task_id: str, session_id: str) -> str:
186
+ """Handle generic file tasks via AI."""
187
+ messages = [
188
+ {"role": "system", "content": FILE_SYSTEM},
189
+ {"role": "user", "content": f"Task: {task}\n\nWorkspace: {WORKSPACE}\n\nContext: {json.dumps(context)[:300]}"},
190
+ ]
191
+ return await self.llm(messages, task_id=task_id, session_id=session_id, temperature=0.3, max_tokens=4096)
192
+
193
+ def _get_tree(self, path: str, prefix: str = "", max_depth: int = 4, depth: int = 0) -> str:
194
+ """Generate a directory tree string."""
195
+ if depth > max_depth:
196
+ return ""
197
+ try:
198
+ entries = sorted(os.scandir(path), key=lambda e: (e.is_file(), e.name))
199
+ except PermissionError:
200
+ return ""
201
+ lines = []
202
+ for i, entry in enumerate(entries):
203
+ if entry.name.startswith(".") and entry.name not in [".env", ".gitignore"]:
204
+ continue
205
+ connector = "└── " if i == len(entries) - 1 else "├── "
206
+ lines.append(f"{prefix}{connector}{entry.name}")
207
+ if entry.is_dir() and depth < max_depth:
208
+ extension = " " if i == len(entries) - 1 else "│ "
209
+ subtree = self._get_tree(entry.path, prefix + extension, max_depth, depth + 1)
210
+ if subtree:
211
+ lines.append(subtree)
212
+ return "\n".join(lines)
213
+
214
+ def list_workspace(self) -> Dict:
215
+ """List all workspace files."""
216
+ files = []
217
+ for root, dirs, filenames in os.walk(WORKSPACE):
218
+ dirs[:] = [d for d in dirs if not d.startswith(".") and d != "node_modules"]
219
+ for f in filenames:
220
+ full_path = os.path.join(root, f)
221
+ rel_path = os.path.relpath(full_path, WORKSPACE)
222
+ try:
223
+ size = os.path.getsize(full_path)
224
+ files.append({"path": rel_path, "size": size})
225
+ except Exception:
226
+ pass
227
+ return {"workspace": WORKSPACE, "files": files, "total": len(files)}
agents/git_agent.py ADDED
@@ -0,0 +1,120 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ GitAgent v7 — Autonomous Git operations, PR creation, code review
3
+ Full GitHub integration like Manus/Genspark autonomous coding
4
+ """
5
+ import asyncio
6
+ import json
7
+ import os
8
+ import re
9
+ from typing import Dict, List
10
+ import structlog
11
+ from .base_agent import BaseAgent
12
+
13
+ log = structlog.get_logger()
14
+
15
+ GIT_SYSTEM = """You are an elite autonomous Git and GitHub operations agent.
16
+ You can clone, commit, push, pull, create branches, PRs, review code,
17
+ generate commit messages, manage workflows, and handle merge conflicts.
18
+ Always write clear, conventional commit messages (feat/fix/chore/docs/refactor).
19
+ """
20
+
21
+
22
+ class GitAgent(BaseAgent):
23
+ def __init__(self, ws_manager=None, ai_router=None):
24
+ super().__init__("GitAgent", ws_manager, ai_router)
25
+ self.workspace = os.environ.get("WORKSPACE_DIR", "/tmp/god_workspace")
26
+
27
+ async def run(self, task: str, context: Dict = {}, **kwargs) -> str:
28
+ session_id = kwargs.get("session_id", "")
29
+ task_id = kwargs.get("task_id", "")
30
+ await self.emit(task_id, "agent_start", {"agent": "GitAgent", "task": task[:80]}, session_id)
31
+
32
+ t = task.lower()
33
+ if any(k in t for k in ["clone", "checkout"]):
34
+ return await self._clone_repo(task, context, task_id, session_id)
35
+ if any(k in t for k in ["commit", "push", "pull request", " pr "]):
36
+ return await self._commit_and_push(task, context, task_id, session_id)
37
+ if any(k in t for k in ["review", "analyze code", "audit"]):
38
+ return await self._code_review(task, context, task_id, session_id)
39
+ return await self._git_ai_task(task, context, task_id, session_id)
40
+
41
+ async def _clone_repo(self, task: str, context: Dict, task_id: str, session_id: str) -> str:
42
+ urls = re.findall(r'https?://github\.com/[^\s]+', task)
43
+ if not urls:
44
+ return "❌ No GitHub URL found in task."
45
+ url = urls[0]
46
+ repo_name = url.rstrip("/").split("/")[-1].replace(".git", "")
47
+ dest = os.path.join(self.workspace, repo_name)
48
+ await self.emit(task_id, "tool_called", {"agent": "GitAgent", "tool": "git_clone", "step": f"Cloning {repo_name}"}, session_id)
49
+ token = os.environ.get("GITHUB_TOKEN", "")
50
+ auth_url = url.replace("https://", f"https://{token}@") if token else url
51
+ r = await self._run_cmd(["git", "clone", auth_url, dest])
52
+ if r["returncode"] == 0:
53
+ await self.emit(task_id, "git_cloned", {"repo": repo_name, "path": dest}, session_id)
54
+ return f"✅ **Cloned** `{repo_name}` → `{dest}`\n```\n{r['stdout'][:500]}\n```"
55
+ return f"❌ Clone failed:\n```\n{r['stderr'][:500]}\n```"
56
+
57
+ async def _commit_and_push(self, task: str, context: Dict, task_id: str, session_id: str) -> str:
58
+ repo_path = context.get("repo_path", self.workspace)
59
+ await self.emit(task_id, "tool_called", {"agent": "GitAgent", "tool": "git_commit", "step": "Committing"}, session_id)
60
+ msgs = [
61
+ {"role": "system", "content": "Generate a conventional commit message. Return ONLY the one-line message."},
62
+ {"role": "user", "content": f"Task: {task}\nContext: {json.dumps(context)[:200]}"},
63
+ ]
64
+ commit_msg = (await self.llm(msgs, task_id=task_id, session_id=session_id, temperature=0.3, max_tokens=80)).strip().split("\n")[0][:100]
65
+ results = []
66
+ for cmd in [["git", "add", "-A"], ["git", "commit", "-m", commit_msg]]:
67
+ r = await self._run_cmd(cmd, cwd=repo_path)
68
+ results.append(f"$ {' '.join(cmd)}\n{r['stdout']}{r['stderr']}")
69
+ branch = context.get("branch", "main")
70
+ r = await self._run_cmd(["git", "push", "origin", branch], cwd=repo_path)
71
+ results.append(f"$ git push\n{r['stdout']}{r['stderr']}")
72
+ return f"✅ **Committed:** `{commit_msg}`\n\n```\n" + "\n".join(results) + "\n```"
73
+
74
+ async def _code_review(self, task: str, context: Dict, task_id: str, session_id: str) -> str:
75
+ repo_path = context.get("repo_path", self.workspace)
76
+ diff = await self._run_cmd(["git", "diff", "HEAD~1"], cwd=repo_path)
77
+ msgs = [
78
+ {"role": "system", "content": GIT_SYSTEM},
79
+ {"role": "user", "content": f"Task: {task}\n\nDiff:\n{diff['stdout'][:2500]}\n\nProvide code review: summary, issues, suggestions, score (1-10)."},
80
+ ]
81
+ return await self.llm(msgs, task_id=task_id, session_id=session_id, temperature=0.3, max_tokens=4096)
82
+
83
+ async def _git_ai_task(self, task: str, context: Dict, task_id: str, session_id: str) -> str:
84
+ msgs = [
85
+ {"role": "system", "content": GIT_SYSTEM},
86
+ {"role": "user", "content": f"Task: {task}\nWorkspace: {self.workspace}\nContext: {json.dumps(context)[:300]}"},
87
+ ]
88
+ return await self.llm(msgs, task_id=task_id, session_id=session_id, temperature=0.3, max_tokens=4096)
89
+
90
+ async def create_github_pr(self, repo_owner: str, repo_name: str, title: str, body: str,
91
+ head_branch: str, base_branch: str = "main",
92
+ task_id: str = "", session_id: str = "") -> Dict:
93
+ import httpx
94
+ token = os.environ.get("GITHUB_TOKEN", "")
95
+ if not token:
96
+ return {"error": "GITHUB_TOKEN not set"}
97
+ async with httpx.AsyncClient(timeout=30) as client:
98
+ resp = await client.post(
99
+ f"https://api.github.com/repos/{repo_owner}/{repo_name}/pulls",
100
+ headers={"Authorization": f"token {token}", "Accept": "application/vnd.github.v3+json"},
101
+ json={"title": title, "body": body, "head": head_branch, "base": base_branch},
102
+ )
103
+ data = resp.json()
104
+ if resp.status_code == 201:
105
+ await self.emit(task_id, "pr_created", {"url": data.get("html_url")}, session_id)
106
+ return {"success": True, "url": data.get("html_url")}
107
+ return {"error": data.get("message", "Failed"), "status": resp.status_code}
108
+
109
+ async def _run_cmd(self, cmd: List[str], cwd: str = None, timeout: int = 60) -> Dict:
110
+ try:
111
+ proc = await asyncio.create_subprocess_exec(
112
+ *cmd, cwd=cwd or self.workspace,
113
+ stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.PIPE,
114
+ )
115
+ stdout, stderr = await asyncio.wait_for(proc.communicate(), timeout=timeout)
116
+ return {"returncode": proc.returncode,
117
+ "stdout": stdout.decode("utf-8", errors="replace"),
118
+ "stderr": stderr.decode("utf-8", errors="replace")}
119
+ except Exception as e:
120
+ return {"returncode": -1, "stdout": "", "stderr": str(e)}
agents/orchestrator_v7.py ADDED
@@ -0,0 +1,338 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ God Agent Orchestrator v7 — True Autonomous Engineering OS
3
+ Manus + Genspark + Devin (OneHand) style multi-agent coordination
4
+ """
5
+ import asyncio
6
+ import json
7
+ import time
8
+ import uuid
9
+ from typing import Any, Dict, List, Optional
10
+ import structlog
11
+
12
+ log = structlog.get_logger()
13
+
14
+ SYSTEM_PROMPT_V7 = """You are GOD AGENT v7 — the world's most advanced autonomous AI engineering operating system.
15
+
16
+ You combine the best of:
17
+ - 🧠 **Manus** — Deep reasoning, multi-step planning, autonomous decision making
18
+ - ⚡ **Genspark** — Repository engineering, code generation at scale, multi-model AI routing
19
+ - 🤖 **Devin/OneHand** — Self-healing code execution, real browser control, file system mastery
20
+
21
+ Your specialized agent fleet (15 agents):
22
+ - **OrchestratorAgent** — Central brain, routes & coordinates all agents
23
+ - **PlannerAgent** — Breaks complex goals into executable task graphs
24
+ - **CodingAgent** — Generates production-quality code in any language
25
+ - **DebugAgent** — Autonomous error detection and self-healing
26
+ - **TestAgent** — Generates & runs comprehensive test suites
27
+ - **FileAgent** — Full file system control, project scaffolding
28
+ - **GitAgent** — Git operations, PR creation, code review
29
+ - **BrowserAgent** — Web research, scraping, web automation
30
+ - **VisionAgent** — UI/UX generation, design-to-code
31
+ - **SandboxAgent** — Code execution in isolated environments
32
+ - **DeployAgent** — Auto-deploy to Vercel, HF, Docker, AWS
33
+ - **ConnectorAgent** — External integrations (GitHub, Slack, Notion, etc.)
34
+ - **MemoryAgent** — Long-term memory and context management
35
+ - **WorkflowAgent** — n8n/automation workflow generation
36
+ - **UIAgent** — Real-time UI state updates
37
+
38
+ Operating principles:
39
+ 1. PLAN before executing — always create a step-by-step plan for complex tasks
40
+ 2. EXECUTE autonomously — don't ask for confirmation on obvious steps
41
+ 3. SELF-HEAL — when errors occur, automatically retry with corrections
42
+ 4. PARALLELIZE — run independent tasks simultaneously
43
+ 5. REMEMBER — store and recall relevant context from memory
44
+
45
+ Respond in Burmese or English based on user language.
46
+ Be decisive, thorough, and production-focused.
47
+ """
48
+
49
+
50
+ class GodAgentOrchestratorV7:
51
+ """
52
+ v7 Central Orchestrator — 15-agent autonomous engineering OS.
53
+ Routes tasks, coordinates parallel execution, self-heals failures.
54
+ """
55
+
56
+ def __init__(self, ws_manager=None, ai_router=None):
57
+ self.ws = ws_manager
58
+ self.ai_router = ai_router
59
+ self._agents: Dict[str, Any] = {}
60
+ self._active_tasks: Dict[str, Dict] = {}
61
+ self._task_history: List[Dict] = []
62
+
63
+ def register_agent(self, name: str, agent):
64
+ self._agents[name] = agent
65
+ log.info("v7 Agent registered", agent=name)
66
+
67
+ def get_agent(self, name: str):
68
+ return self._agents.get(name)
69
+
70
+ # ── Intent Classification ───────────────────────────────────────────────
71
+
72
+ async def classify_intent_v7(self, user_message: str) -> Dict:
73
+ """Advanced intent classification for 15-agent routing."""
74
+ classify_prompt = f"""Classify this user request for our 15-agent autonomous engineering OS.
75
+
76
+ User message: "{user_message}"
77
+
78
+ Available agents: orchestrator, planner, coding, debug, test, file, git, browser, vision, sandbox, deploy, connector, memory, workflow, ui
79
+
80
+ Respond ONLY with valid JSON:
81
+ {{
82
+ "primary_agent": "agent_name",
83
+ "secondary_agents": ["agent1", "agent2"],
84
+ "parallel_tasks": [],
85
+ "intent": "brief description",
86
+ "requires_planning": true/false,
87
+ "is_code_task": true/false,
88
+ "is_deployment": true/false,
89
+ "is_research": true/false,
90
+ "is_ui_task": true/false,
91
+ "is_git_task": true/false,
92
+ "is_test_task": true/false,
93
+ "language": "en|my",
94
+ "complexity": "simple|moderate|complex|ultra_complex",
95
+ "estimated_steps": 3
96
+ }}"""
97
+
98
+ if self.ai_router:
99
+ messages = [
100
+ {"role": "system", "content": "You are an intent classifier. Return only valid JSON."},
101
+ {"role": "user", "content": classify_prompt},
102
+ ]
103
+ raw = await self.ai_router.complete(messages, temperature=0.1, max_tokens=400)
104
+ try:
105
+ start = raw.find("{")
106
+ end = raw.rfind("}") + 1
107
+ if start >= 0 and end > start:
108
+ return json.loads(raw[start:end])
109
+ except Exception:
110
+ pass
111
+
112
+ # Heuristic fallback
113
+ msg = user_message.lower()
114
+ is_code = any(k in msg for k in ["code", "build", "create", "write", "fix", "debug", "api", "function", "class", "script", "app", "backend", "frontend"])
115
+ is_deploy = any(k in msg for k in ["deploy", "vercel", "github", "push", "publish", "release", "hf", "hugging"])
116
+ is_research = any(k in msg for k in ["research", "search", "find", "browse", "web", "scrape", "analyze"])
117
+ is_ui = any(k in msg for k in ["ui", "ux", "design", "component", "dashboard", "landing", "page", "frontend"])
118
+ is_git = any(k in msg for k in ["git", "commit", "pr", "pull request", "branch", "merge", "clone"])
119
+ is_test = any(k in msg for k in ["test", "testing", "pytest", "jest", "coverage", "qa"])
120
+ is_file = any(k in msg for k in ["file", "folder", "directory", "scaffold", "project structure"])
121
+ is_workflow = any(k in msg for k in ["workflow", "n8n", "automate", "trigger", "pipeline"])
122
+ is_memory = any(k in msg for k in ["remember", "recall", "memory", "history", "previous"])
123
+
124
+ primary = (
125
+ "vision" if is_ui else
126
+ "git" if is_git else
127
+ "test" if is_test else
128
+ "browser" if is_research else
129
+ "file" if is_file else
130
+ "coding" if is_code else
131
+ "deploy" if is_deploy else
132
+ "workflow" if is_workflow else
133
+ "memory" if is_memory else
134
+ "chat"
135
+ )
136
+
137
+ secondary = []
138
+ if is_code and is_deploy:
139
+ secondary.append("deploy")
140
+ if is_code and is_test:
141
+ secondary.append("test")
142
+ if is_code and is_git:
143
+ secondary.append("git")
144
+
145
+ return {
146
+ "primary_agent": primary,
147
+ "secondary_agents": secondary,
148
+ "parallel_tasks": [],
149
+ "intent": user_message[:80],
150
+ "requires_planning": is_code or is_deploy or len(user_message) > 150,
151
+ "is_code_task": is_code,
152
+ "is_deployment": is_deploy,
153
+ "is_research": is_research,
154
+ "is_ui_task": is_ui,
155
+ "is_git_task": is_git,
156
+ "is_test_task": is_test,
157
+ "language": "my" if any(c > "\u1000" for c in user_message) else "en",
158
+ "complexity": "ultra_complex" if len(user_message) > 500 else ("complex" if len(user_message) > 200 else "moderate"),
159
+ "estimated_steps": 5 if is_code else 3,
160
+ }
161
+
162
+ # ── Main Orchestration ─────────────────────────────────────────────────
163
+
164
+ async def orchestrate(
165
+ self,
166
+ user_message: str,
167
+ session_id: str = "",
168
+ task_id: str = "",
169
+ context: Dict = {},
170
+ ) -> str:
171
+ exec_id = task_id or f"v7_{uuid.uuid4().hex[:8]}"
172
+
173
+ await self._emit(session_id, task_id, "orchestrator_start", {
174
+ "message": user_message[:100],
175
+ "version": "v7",
176
+ "agents_available": len(self._agents),
177
+ })
178
+
179
+ # 1. Classify intent
180
+ intent = await self.classify_intent_v7(user_message)
181
+ log.info("v7 Intent classified", **{k: v for k, v in intent.items() if k != "parallel_tasks"})
182
+
183
+ await self._emit(session_id, task_id, "intent_classified", {
184
+ "primary_agent": intent["primary_agent"],
185
+ "secondary_agents": intent["secondary_agents"],
186
+ "complexity": intent["complexity"],
187
+ "language": intent["language"],
188
+ })
189
+
190
+ # 2. Planning phase for complex tasks
191
+ plan_context = {}
192
+ if intent.get("requires_planning") and intent.get("complexity") in ("complex", "ultra_complex"):
193
+ planner = self._agents.get("planner")
194
+ if planner:
195
+ await self._emit(session_id, task_id, "agent_called", {
196
+ "agent": "PlannerAgent", "phase": "planning"
197
+ })
198
+ try:
199
+ plan = await asyncio.wait_for(
200
+ planner.run(user_message, context={**context, "intent": intent},
201
+ session_id=session_id, task_id=exec_id),
202
+ timeout=60
203
+ )
204
+ plan_context["plan"] = plan
205
+ await self._emit(session_id, task_id, "plan_ready", {"plan_length": len(plan)})
206
+ except asyncio.TimeoutError:
207
+ log.warning("PlannerAgent timed out")
208
+
209
+ # 3. Route to primary agent
210
+ primary_name = intent["primary_agent"]
211
+ primary_agent = self._agents.get(primary_name) or self._agents.get("chat")
212
+
213
+ if not primary_agent:
214
+ return f"Agent '{primary_name}' not available."
215
+
216
+ await self._emit(session_id, task_id, "agent_called", {
217
+ "agent": primary_name,
218
+ "intent": intent["intent"],
219
+ })
220
+
221
+ full_context = {**context, **plan_context, "intent": intent}
222
+
223
+ # 4. Execute primary agent
224
+ try:
225
+ result = await asyncio.wait_for(
226
+ primary_agent.run(user_message, context=full_context, session_id=session_id, task_id=exec_id),
227
+ timeout=300
228
+ )
229
+ except asyncio.TimeoutError:
230
+ result = f"⚠️ Primary agent ({primary_name}) timed out. Please try a more specific request."
231
+ except Exception as e:
232
+ log.error("Primary agent error", agent=primary_name, error=str(e))
233
+ result = await self.self_heal(str(e), user_message, exec_id, session_id)
234
+
235
+ # 5. Run secondary agents in parallel
236
+ if intent.get("secondary_agents"):
237
+ secondary_tasks = []
238
+ for agent_name in intent["secondary_agents"]:
239
+ agent = self._agents.get(agent_name)
240
+ if agent:
241
+ secondary_tasks.append(
242
+ asyncio.wait_for(
243
+ agent.run(user_message, context={**full_context, "primary_result": result},
244
+ session_id=session_id, task_id=exec_id),
245
+ timeout=120
246
+ )
247
+ )
248
+ if secondary_tasks:
249
+ secondary_results = await asyncio.gather(*secondary_tasks, return_exceptions=True)
250
+ valid_results = [r for r in secondary_results if isinstance(r, str) and len(r) > 10]
251
+ if valid_results:
252
+ result += "\n\n---\n\n" + "\n\n".join(valid_results)
253
+
254
+ # 6. Save to memory asynchronously
255
+ memory_agent = self._agents.get("memory")
256
+ if memory_agent:
257
+ asyncio.create_task(memory_agent.save_interaction(
258
+ user_message=user_message,
259
+ assistant_response=result,
260
+ session_id=session_id,
261
+ intent=intent,
262
+ ))
263
+
264
+ # 7. Record in task history
265
+ self._task_history.append({
266
+ "id": exec_id,
267
+ "message": user_message[:200],
268
+ "primary_agent": primary_name,
269
+ "result_length": len(result),
270
+ "timestamp": time.time(),
271
+ })
272
+ if len(self._task_history) > 100:
273
+ self._task_history = self._task_history[-100:]
274
+
275
+ await self._emit(session_id, task_id, "orchestrator_complete", {
276
+ "primary_agent": primary_name,
277
+ "result_length": len(result),
278
+ "version": "v7",
279
+ })
280
+
281
+ return result
282
+
283
+ # ── Self-Healing ───────────────────────────────────────────────────────
284
+
285
+ async def self_heal(self, error: str, original_task: str, task_id: str = "",
286
+ session_id: str = "", max_retries: int = 3) -> str:
287
+ debug_agent = self._agents.get("debug")
288
+ if not debug_agent:
289
+ return f"❌ Self-heal unavailable. Error: {error}"
290
+
291
+ for attempt in range(1, max_retries + 1):
292
+ await self._emit(session_id, task_id, "self_heal_attempt", {
293
+ "attempt": attempt, "max": max_retries, "error": error[:200]
294
+ })
295
+ try:
296
+ fix = await asyncio.wait_for(
297
+ debug_agent.run(
298
+ f"Fix this error: {error}\n\nOriginal task: {original_task}",
299
+ context={"attempt": attempt, "error": error},
300
+ session_id=session_id, task_id=task_id,
301
+ ),
302
+ timeout=60
303
+ )
304
+ if fix and "❌" not in fix[:10]:
305
+ await self._emit(session_id, task_id, "self_heal_success", {"attempt": attempt})
306
+ return fix
307
+ except Exception as e:
308
+ log.warning("Self-heal attempt failed", attempt=attempt, error=str(e))
309
+
310
+ return f"❌ Self-healing failed after {max_retries} attempts. Error: {error}"
311
+
312
+ # ── Helpers ────────────────────────────────────────────────────────────
313
+
314
+ async def _emit(self, session_id: str, task_id: str, event: str, data: Dict):
315
+ if not self.ws:
316
+ return
317
+ try:
318
+ if task_id:
319
+ await self.ws.emit(task_id, event, data, session_id=session_id)
320
+ if session_id:
321
+ await self.ws.emit_chat(session_id, event, data)
322
+ except Exception:
323
+ pass
324
+
325
+ def get_status(self) -> Dict:
326
+ return {
327
+ "version": "7.0.0",
328
+ "agents": list(self._agents.keys()),
329
+ "total_agents": len(self._agents),
330
+ "active_tasks": len(self._active_tasks),
331
+ "tasks_completed": len(self._task_history),
332
+ "capabilities": [
333
+ "autonomous_planning", "multi_agent_parallel",
334
+ "self_healing", "web_browsing", "file_management",
335
+ "git_operations", "ui_generation", "test_generation",
336
+ "deployment", "memory", "workflow_automation"
337
+ ],
338
+ }
agents/sandbox_agent.py CHANGED
@@ -1,79 +1,70 @@
1
  """
2
- SandboxAgent — GOD MODE+ V5
3
- Fixed: isolated session workspaces, asyncio timeout, no app crash
4
  """
5
  import asyncio
 
6
  import os
7
- from typing import Dict
 
 
8
  import structlog
9
  from .base_agent import BaseAgent
10
 
11
  log = structlog.get_logger()
12
 
13
- BASE_WORKSPACE = os.environ.get("WORKSPACE_DIR", "/tmp/god_workspace")
14
- os.makedirs(BASE_WORKSPACE, exist_ok=True)
15
-
16
- # Commands that are never allowed
17
- BLOCKED_PATTERNS = [
18
- "rm -rf /", "rm -rf ~", ":(){ :|:& };:", "mkfs", "shutdown",
19
- "reboot", "halt", "dd if=/dev/", "chmod -R 777 /", "chown -R",
20
- "> /dev/sda", "fork bomb",
21
- ]
22
-
23
-
24
- def _get_session_dir(session_id: str) -> str:
25
- """Each session gets its own isolated workspace directory."""
26
- safe_id = "".join(c for c in session_id if c.isalnum() or c in "-_")[:32] or "default"
27
- path = os.path.join(BASE_WORKSPACE, safe_id)
28
- os.makedirs(path, exist_ok=True)
29
- return path
30
 
31
 
32
  class SandboxAgent(BaseAgent):
33
  def __init__(self, ws_manager=None, ai_router=None):
34
  super().__init__("SandboxAgent", ws_manager, ai_router)
 
35
 
36
  async def run(self, task: str, context: Dict = {}, **kwargs) -> str:
37
- session_id = kwargs.get("session_id", "default")
38
  task_id = kwargs.get("task_id", "")
 
39
  task_lower = task.lower()
40
 
41
- if any(k in task_lower for k in ["execute", "run", "terminal", "bash", "shell"]):
42
  cmd = context.get("command", task)
43
  return await self.execute(cmd, task_id=task_id, session_id=session_id)
44
- elif any(k in task_lower for k in ["write file", "create file", "save file"]):
45
  filename = context.get("filename", "output.txt")
46
  content = context.get("content", "")
47
  return await self.write_file(filename, content, task_id=task_id, session_id=session_id)
48
  elif "read file" in task_lower:
49
  filename = context.get("filename", "")
50
  return await self.read_file(filename, task_id=task_id, session_id=session_id)
51
- elif "workspace" in task_lower or "ls" in task_lower:
52
- info = await self.get_workspace_info(session_id=session_id)
53
- return str(info)
54
  else:
55
  return await self.execute(task, task_id=task_id, session_id=session_id)
56
 
 
 
57
  async def execute(
58
  self,
59
  command: str,
60
  cwd: str = "",
61
  timeout: int = 30,
62
  task_id: str = "",
63
- session_id: str = "default",
64
  ) -> str:
65
- """Execute shell command in isolated session workspace with timeout."""
66
- # Safety check
67
- for blocked in BLOCKED_PATTERNS:
68
- if blocked in command:
69
- return f"❌ Blocked dangerous command pattern: '{blocked}'"
70
 
71
- work_dir = cwd or _get_session_dir(session_id)
 
 
 
 
72
 
73
- try:
74
- await self.emit(task_id, "sandbox_exec", {"command": command[:200], "cwd": work_dir}, session_id)
75
- except Exception:
76
- pass
77
 
78
  try:
79
  proc = await asyncio.create_subprocess_shell(
@@ -82,86 +73,177 @@ class SandboxAgent(BaseAgent):
82
  stderr=asyncio.subprocess.PIPE,
83
  cwd=work_dir,
84
  )
85
- try:
86
- stdout, stderr = await asyncio.wait_for(proc.communicate(), timeout=float(timeout))
87
- except asyncio.TimeoutError:
88
- try:
89
- proc.kill()
90
- except Exception:
91
- pass
92
- return f"⏱️ Command timed out after {timeout}s: {command[:80]}"
93
-
94
- output = stdout.decode("utf-8", errors="replace") if stdout else ""
95
- err = stderr.decode("utf-8", errors="replace") if stderr else ""
96
- result = output[:4000]
97
- if err:
98
- result += f"\n[stderr]: {err[:1000]}"
99
- if proc.returncode and proc.returncode != 0:
100
- result += f"\n[exit code: {proc.returncode}]"
101
- return result.strip() or "(no output)"
102
-
103
  except Exception as e:
104
- return f"❌ Execution error: {str(e)[:200]}"
 
 
105
 
106
  async def write_file(
107
  self,
108
  filename: str,
109
  content: str,
110
  task_id: str = "",
111
- session_id: str = "default",
112
  ) -> str:
113
- """Write file to isolated session workspace."""
 
 
114
  try:
115
- work_dir = _get_session_dir(session_id)
116
- # Strip path traversal
117
- safe_name = os.path.basename(filename) or "output.txt"
118
- filepath = os.path.join(work_dir, safe_name)
119
  with open(filepath, "w", encoding="utf-8") as f:
120
  f.write(content)
121
- try:
122
- await self.emit(task_id, "file_written", {"filename": safe_name, "size": len(content)}, session_id)
123
- except Exception:
124
- pass
125
- return f"✅ Written {len(content)} bytes to {safe_name}"
 
 
126
  except Exception as e:
127
- return f"❌ Write error: {str(e)}"
128
 
129
  async def read_file(
130
  self,
131
  filename: str,
132
  task_id: str = "",
133
- session_id: str = "default",
134
  ) -> str:
135
- """Read file from session workspace."""
 
136
  try:
137
- work_dir = _get_session_dir(session_id)
138
- safe_name = os.path.basename(filename)
139
- filepath = os.path.join(work_dir, safe_name)
140
- if not os.path.exists(filepath):
141
- return f"❌ File not found: {safe_name}"
142
- with open(filepath, "r", encoding="utf-8", errors="replace") as f:
143
- content = f.read(50000)
144
- return content
 
145
  except Exception as e:
146
- return f"❌ Read error: {str(e)}"
147
 
148
- async def get_workspace_info(self, session_id: str = "default") -> dict:
149
- """Get workspace file listing for session."""
 
150
  try:
151
- work_dir = _get_session_dir(session_id)
152
- entries = []
153
- for entry in os.scandir(work_dir):
154
- stat = entry.stat()
155
- entries.append({
156
- "name": entry.name,
157
- "type": "file" if entry.is_file() else "dir",
158
- "size": stat.st_size if entry.is_file() else 0,
159
- })
160
- return {
161
- "workspace": work_dir,
162
- "session_id": session_id,
163
- "files": sorted(entries, key=lambda x: x["name"]),
164
- "file_count": len([e for e in entries if e["type"] == "file"]),
165
- }
166
- except Exception as e:
167
- return {"workspace": "", "session_id": session_id, "files": [], "error": str(e)}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  """
2
+ SandboxAgent — Persistent VS Code sandbox execution (Devin-style)
3
+ Controls file system, terminal, git operations in workspace
4
  """
5
  import asyncio
6
+ import json
7
  import os
8
+ import subprocess
9
+ import tempfile
10
+ from typing import Dict, List, Optional
11
  import structlog
12
  from .base_agent import BaseAgent
13
 
14
  log = structlog.get_logger()
15
 
16
+ WORKSPACE = os.environ.get("WORKSPACE_DIR", "/tmp/god_workspace")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
17
 
18
 
19
  class SandboxAgent(BaseAgent):
20
  def __init__(self, ws_manager=None, ai_router=None):
21
  super().__init__("SandboxAgent", ws_manager, ai_router)
22
+ os.makedirs(WORKSPACE, exist_ok=True)
23
 
24
  async def run(self, task: str, context: Dict = {}, **kwargs) -> str:
25
+ session_id = kwargs.get("session_id", "")
26
  task_id = kwargs.get("task_id", "")
27
+
28
  task_lower = task.lower()
29
 
30
+ if "execute" in task_lower or "run" in task_lower or "terminal" in task_lower:
31
  cmd = context.get("command", task)
32
  return await self.execute(cmd, task_id=task_id, session_id=session_id)
33
+ elif "write file" in task_lower or "create file" in task_lower:
34
  filename = context.get("filename", "output.txt")
35
  content = context.get("content", "")
36
  return await self.write_file(filename, content, task_id=task_id, session_id=session_id)
37
  elif "read file" in task_lower:
38
  filename = context.get("filename", "")
39
  return await self.read_file(filename, task_id=task_id, session_id=session_id)
40
+ elif "git" in task_lower:
41
+ return await self.git_operation(task, task_id=task_id, session_id=session_id)
 
42
  else:
43
  return await self.execute(task, task_id=task_id, session_id=session_id)
44
 
45
+ # ─── Terminal Execution ───────────────────────────────────────────────────
46
+
47
  async def execute(
48
  self,
49
  command: str,
50
  cwd: str = "",
51
  timeout: int = 30,
52
  task_id: str = "",
53
+ session_id: str = "",
54
  ) -> str:
55
+ """Execute shell command in sandbox workspace."""
56
+ work_dir = cwd or WORKSPACE
 
 
 
57
 
58
+ # Safety: block dangerous commands
59
+ blocked = ["rm -rf /", ":(){ :|:& };:", "mkfs", "shutdown", "reboot", "halt", "dd if=/dev/"]
60
+ for b in blocked:
61
+ if b in command:
62
+ return f"❌ Blocked dangerous command: {command[:50]}"
63
 
64
+ await self.emit(task_id, "sandbox_exec", {
65
+ "command": command[:200],
66
+ "cwd": work_dir,
67
+ }, session_id)
68
 
69
  try:
70
  proc = await asyncio.create_subprocess_shell(
 
73
  stderr=asyncio.subprocess.PIPE,
74
  cwd=work_dir,
75
  )
76
+ stdout, stderr = await asyncio.wait_for(proc.communicate(), timeout=timeout)
77
+ output = stdout.decode("utf-8", errors="replace")
78
+ err = stderr.decode("utf-8", errors="replace")
79
+
80
+ result = output[:3000]
81
+ if err and proc.returncode != 0:
82
+ result += f"\n⚠️ stderr:\n{err[:500]}"
83
+
84
+ await self.emit(task_id, "sandbox_result", {
85
+ "command": command[:100],
86
+ "exit_code": proc.returncode,
87
+ "output_length": len(output),
88
+ "success": proc.returncode == 0,
89
+ }, session_id)
90
+
91
+ return result or f"Command executed (exit code: {proc.returncode})"
92
+ except asyncio.TimeoutError:
93
+ return f"⚠️ Command timed out after {timeout}s"
94
  except Exception as e:
95
+ return f"❌ Execution error: {str(e)}"
96
+
97
+ # ─── File Operations ──────────────────────────────────────────────────────
98
 
99
  async def write_file(
100
  self,
101
  filename: str,
102
  content: str,
103
  task_id: str = "",
104
+ session_id: str = "",
105
  ) -> str:
106
+ """Write file to workspace."""
107
+ filepath = os.path.join(WORKSPACE, filename)
108
+ os.makedirs(os.path.dirname(filepath), exist_ok=True)
109
  try:
 
 
 
 
110
  with open(filepath, "w", encoding="utf-8") as f:
111
  f.write(content)
112
+ await self.emit(task_id, "file_written", {
113
+ "filename": filename,
114
+ "size": len(content),
115
+ "lines": len(content.split("\n")),
116
+ "path": filepath,
117
+ }, session_id)
118
+ return f"✅ File written: `{filename}` ({len(content)} chars, {len(content.split(chr(10)))} lines)"
119
  except Exception as e:
120
+ return f"❌ Write failed: {str(e)}"
121
 
122
  async def read_file(
123
  self,
124
  filename: str,
125
  task_id: str = "",
126
+ session_id: str = "",
127
  ) -> str:
128
+ """Read file from workspace."""
129
+ filepath = os.path.join(WORKSPACE, filename)
130
  try:
131
+ with open(filepath, "r", encoding="utf-8") as f:
132
+ content = f.read()
133
+ await self.emit(task_id, "file_read", {
134
+ "filename": filename,
135
+ "size": len(content),
136
+ }, session_id)
137
+ return content[:5000]
138
+ except FileNotFoundError:
139
+ return f"❌ File not found: {filename}"
140
  except Exception as e:
141
+ return f"❌ Read failed: {str(e)}"
142
 
143
+ async def list_files(self, path: str = "") -> List[str]:
144
+ """List files in workspace."""
145
+ target = os.path.join(WORKSPACE, path) if path else WORKSPACE
146
  try:
147
+ result = []
148
+ for root, dirs, files in os.walk(target):
149
+ # Skip hidden and cache dirs
150
+ dirs[:] = [d for d in dirs if not d.startswith(".") and d != "__pycache__" and d != "node_modules"]
151
+ for f in files:
152
+ rel = os.path.relpath(os.path.join(root, f), WORKSPACE)
153
+ result.append(rel)
154
+ if len(result) > 100:
155
+ break
156
+ return result
157
+ except Exception:
158
+ return []
159
+
160
+ # ─── Git Operations ───────────────────────────────────────────────────────
161
+
162
+ async def git_operation(
163
+ self,
164
+ task: str,
165
+ repo_path: str = "",
166
+ task_id: str = "",
167
+ session_id: str = "",
168
+ ) -> str:
169
+ """Perform git operations in workspace."""
170
+ work_dir = repo_path or WORKSPACE
171
+ task_lower = task.lower()
172
+
173
+ if "clone" in task_lower:
174
+ # Extract URL
175
+ words = task.split()
176
+ urls = [w for w in words if "github.com" in w or "gitlab.com" in w or ".git" in w]
177
+ if urls:
178
+ url = urls[0]
179
+ return await self.execute(f"git clone {url}", cwd=WORKSPACE, task_id=task_id, session_id=session_id)
180
+ return "❌ No git URL found in task."
181
+
182
+ elif "commit" in task_lower:
183
+ msg = task.replace("commit", "").strip() or "God Agent automated commit"
184
+ cmds = [
185
+ "git add -A",
186
+ f'git commit -m "{msg}"',
187
+ ]
188
+ results = []
189
+ for cmd in cmds:
190
+ r = await self.execute(cmd, cwd=work_dir, task_id=task_id, session_id=session_id)
191
+ results.append(r)
192
+ return "\n".join(results)
193
+
194
+ elif "push" in task_lower:
195
+ return await self.execute("git push", cwd=work_dir, task_id=task_id, session_id=session_id)
196
+
197
+ elif "status" in task_lower:
198
+ return await self.execute("git status", cwd=work_dir, task_id=task_id, session_id=session_id)
199
+
200
+ elif "log" in task_lower:
201
+ return await self.execute("git log --oneline -10", cwd=work_dir, task_id=task_id, session_id=session_id)
202
+
203
+ elif "init" in task_lower:
204
+ return await self.execute("git init && git add -A", cwd=work_dir, task_id=task_id, session_id=session_id)
205
+
206
+ else:
207
+ return await self.execute(task, cwd=work_dir, task_id=task_id, session_id=session_id)
208
+
209
+ # ─── Package Management ───────────────────────────────────────────────────
210
+
211
+ async def install_packages(
212
+ self,
213
+ packages: List[str],
214
+ manager: str = "pip",
215
+ task_id: str = "",
216
+ session_id: str = "",
217
+ ) -> str:
218
+ """Install packages in workspace."""
219
+ pkg_str = " ".join(packages)
220
+ if manager == "pip":
221
+ cmd = f"pip install {pkg_str}"
222
+ elif manager == "npm":
223
+ cmd = f"npm install {pkg_str}"
224
+ elif manager == "pnpm":
225
+ cmd = f"pnpm add {pkg_str}"
226
+ else:
227
+ cmd = f"{manager} install {pkg_str}"
228
+
229
+ await self.emit(task_id, "installing_packages", {
230
+ "manager": manager,
231
+ "packages": packages,
232
+ }, session_id)
233
+ return await self.execute(cmd, task_id=task_id, session_id=session_id)
234
+
235
+ # ─── Workspace Info ───────────────────────────────────────────────────────
236
+
237
+ async def get_workspace_info(self) -> Dict:
238
+ """Get workspace status."""
239
+ files = await self.list_files()
240
+ try:
241
+ disk = await self.execute("df -h /tmp | tail -1")
242
+ except Exception:
243
+ disk = "N/A"
244
+ return {
245
+ "path": WORKSPACE,
246
+ "file_count": len(files),
247
+ "files": files[:20],
248
+ "disk_usage": disk,
249
+ }
agents/test_agent.py ADDED
@@ -0,0 +1,103 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ TestAgent v7 — Autonomous test generation, execution, and quality assurance
3
+ Like Devin's self-testing loop + Genspark's QA automation
4
+ """
5
+ import asyncio
6
+ import json
7
+ import os
8
+ import re
9
+ from typing import Dict, List
10
+ import structlog
11
+ from .base_agent import BaseAgent
12
+
13
+ log = structlog.get_logger()
14
+
15
+ TEST_SYSTEM = """You are an elite autonomous test engineer.
16
+ You generate comprehensive tests: unit, integration, e2e, performance.
17
+ You analyze code for bugs, edge cases, and security vulnerabilities.
18
+ You write pytest (Python) and Jest/Vitest (TypeScript) tests.
19
+ Always aim for 80%+ test coverage and meaningful assertions.
20
+ """
21
+
22
+
23
+ class TestAgent(BaseAgent):
24
+ def __init__(self, ws_manager=None, ai_router=None):
25
+ super().__init__("TestAgent", ws_manager, ai_router)
26
+ self.workspace = os.environ.get("WORKSPACE_DIR", "/tmp/god_workspace")
27
+
28
+ async def run(self, task: str, context: Dict = {}, **kwargs) -> str:
29
+ session_id = kwargs.get("session_id", "")
30
+ task_id = kwargs.get("task_id", "")
31
+ await self.emit(task_id, "agent_start", {"agent": "TestAgent", "task": task[:80]}, session_id)
32
+
33
+ t = task.lower()
34
+ if any(k in t for k in ["generate test", "write test", "create test"]):
35
+ return await self._generate_tests(task, context, task_id, session_id)
36
+ if any(k in t for k in ["run test", "execute test", "pytest", "jest"]):
37
+ return await self._run_tests(task, context, task_id, session_id)
38
+ if any(k in t for k in ["coverage", "quality", "audit"]):
39
+ return await self._quality_audit(task, context, task_id, session_id)
40
+ return await self._generate_tests(task, context, task_id, session_id)
41
+
42
+ async def _generate_tests(self, task: str, context: Dict, task_id: str, session_id: str) -> str:
43
+ code = context.get("code", "")
44
+ language = context.get("language", "python")
45
+ await self.emit(task_id, "tool_called", {
46
+ "agent": "TestAgent", "tool": "generate_tests", "step": "Generating tests"
47
+ }, session_id)
48
+ msgs = [
49
+ {"role": "system", "content": TEST_SYSTEM},
50
+ {"role": "user", "content": (
51
+ f"Task: {task}\nLanguage: {language}\n\n"
52
+ f"Code to test:\n{code[:3000] if code else 'Generate tests for: ' + task}\n\n"
53
+ "Generate comprehensive tests with:\n"
54
+ "1. Happy path tests\n2. Edge case tests\n3. Error handling tests\n"
55
+ "4. Mocks for external dependencies\n5. Clear test descriptions"
56
+ )},
57
+ ]
58
+ result = await self.llm(msgs, task_id=task_id, session_id=session_id, temperature=0.2, max_tokens=8192)
59
+ # Save test file to workspace
60
+ test_filename = f"test_{re.sub(r'[^a-z0-9]', '_', task.lower()[:30])}.py"
61
+ test_path = os.path.join(self.workspace, "tests", test_filename)
62
+ os.makedirs(os.path.dirname(test_path), exist_ok=True)
63
+ code_blocks = re.findall(r'```(?:python|py)?\n(.*?)```', result, re.DOTALL)
64
+ if code_blocks:
65
+ with open(test_path, "w") as f:
66
+ f.write(code_blocks[0])
67
+ await self.emit(task_id, "file_written", {"path": test_path}, session_id)
68
+ return result
69
+
70
+ async def _run_tests(self, task: str, context: Dict, task_id: str, session_id: str) -> str:
71
+ repo_path = context.get("repo_path", self.workspace)
72
+ await self.emit(task_id, "tool_called", {
73
+ "agent": "TestAgent", "tool": "run_tests", "step": "Executing tests"
74
+ }, session_id)
75
+ # Detect test runner
76
+ if os.path.exists(os.path.join(repo_path, "package.json")):
77
+ cmd = ["npm", "test", "--", "--watchAll=false"]
78
+ else:
79
+ cmd = ["python", "-m", "pytest", "-v", "--tb=short"]
80
+ try:
81
+ proc = await asyncio.create_subprocess_exec(
82
+ *cmd, cwd=repo_path,
83
+ stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.PIPE,
84
+ )
85
+ stdout, stderr = await asyncio.wait_for(proc.communicate(), timeout=120)
86
+ output = stdout.decode() + stderr.decode()
87
+ passed = len(re.findall(r'PASSED|✓|pass', output, re.I))
88
+ failed = len(re.findall(r'FAILED|✗|fail', output, re.I))
89
+ await self.emit(task_id, "tests_complete", {"passed": passed, "failed": failed}, session_id)
90
+ return f"**Test Results:** ✅ {passed} passed | ❌ {failed} failed\n\n```\n{output[:3000]}\n```"
91
+ except Exception as e:
92
+ return f"❌ Test run error: {str(e)}"
93
+
94
+ async def _quality_audit(self, task: str, context: Dict, task_id: str, session_id: str) -> str:
95
+ code = context.get("code", "")
96
+ msgs = [
97
+ {"role": "system", "content": TEST_SYSTEM},
98
+ {"role": "user", "content": (
99
+ f"Task: {task}\n\nCode:\n{code[:3000]}\n\n"
100
+ "Provide quality audit: coverage estimate, complexity score, bugs found, security issues, and recommendations."
101
+ )},
102
+ ]
103
+ return await self.llm(msgs, task_id=task_id, session_id=session_id, temperature=0.3, max_tokens=4096)
agents/vision_agent.py ADDED
@@ -0,0 +1,109 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ VisionAgent v7 — UI/UX generation, design-to-code, screenshot analysis
3
+ Converts designs, wireframes, and visual specs into real code
4
+ """
5
+ import json
6
+ import os
7
+ from typing import Dict
8
+ import structlog
9
+ from .base_agent import BaseAgent
10
+
11
+ log = structlog.get_logger()
12
+
13
+ VISION_SYSTEM = """You are an elite UI/UX engineer and design-to-code specialist.
14
+ You can:
15
+ - Convert design mockups and wireframes into pixel-perfect React/Next.js components
16
+ - Generate beautiful, responsive UI components with Tailwind CSS
17
+ - Create complete page layouts with animations (Framer Motion)
18
+ - Analyze screenshots and reproduce UI components
19
+ - Generate design systems, color palettes, and typography scales
20
+ - Build dashboards, landing pages, admin panels, mobile-first UIs
21
+
22
+ Always produce production-ready code with:
23
+ - Responsive design (mobile-first)
24
+ - Accessibility (ARIA labels, semantic HTML)
25
+ - Dark/light mode support
26
+ - Smooth animations and transitions
27
+ - TypeScript types
28
+ """
29
+
30
+
31
+ class VisionAgent(BaseAgent):
32
+ def __init__(self, ws_manager=None, ai_router=None):
33
+ super().__init__("VisionAgent", ws_manager, ai_router)
34
+ self.workspace = os.environ.get("WORKSPACE_DIR", "/tmp/god_workspace")
35
+
36
+ async def run(self, task: str, context: Dict = {}, **kwargs) -> str:
37
+ session_id = kwargs.get("session_id", "")
38
+ task_id = kwargs.get("task_id", "")
39
+ await self.emit(task_id, "agent_start", {"agent": "VisionAgent", "task": task[:80]}, session_id)
40
+
41
+ t = task.lower()
42
+ if any(k in t for k in ["dashboard", "admin", "panel"]):
43
+ return await self._generate_dashboard(task, context, task_id, session_id)
44
+ if any(k in t for k in ["landing", "homepage", "hero"]):
45
+ return await self._generate_landing_page(task, context, task_id, session_id)
46
+ if any(k in t for k in ["component", "button", "card", "form", "modal", "nav"]):
47
+ return await self._generate_component(task, context, task_id, session_id)
48
+ return await self._generate_ui(task, context, task_id, session_id)
49
+
50
+ async def _generate_dashboard(self, task: str, context: Dict, task_id: str, session_id: str) -> str:
51
+ await self.emit(task_id, "tool_called", {
52
+ "agent": "VisionAgent", "tool": "generate_dashboard", "step": "Generating dashboard UI"
53
+ }, session_id)
54
+ msgs = [
55
+ {"role": "system", "content": VISION_SYSTEM},
56
+ {"role": "user", "content": (
57
+ f"Build a complete dashboard UI: {task}\n\n"
58
+ "Requirements:\n"
59
+ "- Dark theme with glass morphism effects\n"
60
+ "- Sidebar navigation with icons\n"
61
+ "- Header with user menu\n"
62
+ "- Stats cards with trends\n"
63
+ "- Data tables with sorting\n"
64
+ "- Charts/graphs area\n"
65
+ "- React + TypeScript + Tailwind CSS\n"
66
+ "Generate the complete component code."
67
+ )},
68
+ ]
69
+ return await self.llm(msgs, task_id=task_id, session_id=session_id, temperature=0.4, max_tokens=8192)
70
+
71
+ async def _generate_landing_page(self, task: str, context: Dict, task_id: str, session_id: str) -> str:
72
+ await self.emit(task_id, "tool_called", {
73
+ "agent": "VisionAgent", "tool": "generate_landing", "step": "Generating landing page"
74
+ }, session_id)
75
+ msgs = [
76
+ {"role": "system", "content": VISION_SYSTEM},
77
+ {"role": "user", "content": (
78
+ f"Create a stunning landing page: {task}\n\n"
79
+ "Include: Hero section, Features grid, Pricing table, Testimonials, CTA, Footer\n"
80
+ "Style: Modern, gradient backgrounds, glassmorphism, smooth animations\n"
81
+ "Tech: Next.js + TypeScript + Tailwind + Framer Motion"
82
+ )},
83
+ ]
84
+ return await self.llm(msgs, task_id=task_id, session_id=session_id, temperature=0.5, max_tokens=8192)
85
+
86
+ async def _generate_component(self, task: str, context: Dict, task_id: str, session_id: str) -> str:
87
+ await self.emit(task_id, "tool_called", {
88
+ "agent": "VisionAgent", "tool": "generate_component", "step": "Generating UI component"
89
+ }, session_id)
90
+ msgs = [
91
+ {"role": "system", "content": VISION_SYSTEM},
92
+ {"role": "user", "content": (
93
+ f"Create a polished UI component: {task}\n\n"
94
+ "Requirements:\n"
95
+ "- Fully typed with TypeScript\n"
96
+ "- Responsive and accessible\n"
97
+ "- Dark/light mode support\n"
98
+ "- Smooth hover/focus animations\n"
99
+ "- Props with sensible defaults"
100
+ )},
101
+ ]
102
+ return await self.llm(msgs, task_id=task_id, session_id=session_id, temperature=0.4, max_tokens=8192)
103
+
104
+ async def _generate_ui(self, task: str, context: Dict, task_id: str, session_id: str) -> str:
105
+ msgs = [
106
+ {"role": "system", "content": VISION_SYSTEM},
107
+ {"role": "user", "content": f"Generate UI for: {task}\n\nContext: {json.dumps(context)[:300]}"},
108
+ ]
109
+ return await self.llm(msgs, task_id=task_id, session_id=session_id, temperature=0.5, max_tokens=8192)
main_v7.py ADDED
@@ -0,0 +1,363 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ 🚀 GOD AGENT OS v7 — Autonomous Engineering Operating System
3
+ Manus + Genspark + Devin (OneHand) Combined
4
+ Version: 7.0.0
5
+ """
6
+
7
+ import asyncio
8
+ import json
9
+ import logging
10
+ import os
11
+ import time
12
+ import uuid
13
+ from contextlib import asynccontextmanager
14
+ from typing import Optional
15
+
16
+ import structlog
17
+ from fastapi import FastAPI, WebSocket, WebSocketDisconnect, HTTPException, Request
18
+ from fastapi.middleware.cors import CORSMiddleware
19
+ from fastapi.middleware.gzip import GZipMiddleware
20
+ from fastapi.responses import JSONResponse
21
+ from slowapi import Limiter, _rate_limit_exceeded_handler
22
+ from slowapi.util import get_remote_address
23
+ from slowapi.errors import RateLimitExceeded
24
+
25
+ from api.routes import tasks, chat, memory, github, health
26
+ from api.routes import connectors, agents as agents_router
27
+ from api.websocket_manager import WebSocketManager
28
+ from core.task_engine import TaskEngine
29
+ from memory.db import init_db
30
+
31
+ # ─── v7 God Agent Ecosystem ────────────────────────────────────────────────────
32
+ from ai_router.router import AIRouter
33
+ from agents.orchestrator_v7 import GodAgentOrchestratorV7
34
+ from agents.chat_agent import ChatAgent
35
+ from agents.planner_agent import PlannerAgent
36
+ from agents.coding_agent import CodingAgent
37
+ from agents.debug_agent import DebugAgent
38
+ from agents.memory_agent import MemoryAgent
39
+ from agents.connector_agent import ConnectorAgent
40
+ from agents.deploy_agent import DeployAgent
41
+ from agents.workflow_agent import WorkflowAgent
42
+ from agents.sandbox_agent import SandboxAgent
43
+ from agents.ui_agent import UIAgent
44
+ from agents.reasoning_agent import ReasoningAgent
45
+ # v7 new agents
46
+ from agents.browser_agent import BrowserAgent
47
+ from agents.file_agent import FileAgent
48
+ from agents.git_agent import GitAgent
49
+ from agents.test_agent import TestAgent
50
+ from agents.vision_agent import VisionAgent
51
+ from connectors.manager import ConnectorManager
52
+
53
+ # ─── Structured Logging ────────────────────────────────────────────────────────
54
+ structlog.configure(
55
+ processors=[
56
+ structlog.processors.TimeStamper(fmt="iso"),
57
+ structlog.stdlib.add_log_level,
58
+ structlog.processors.StackInfoRenderer(),
59
+ structlog.dev.ConsoleRenderer(),
60
+ ]
61
+ )
62
+ log = structlog.get_logger()
63
+
64
+ # ─── Rate Limiter ──────────────────────────────────────────────────────────────
65
+ limiter = Limiter(key_func=get_remote_address)
66
+
67
+ # ─── Global Managers ──────────────────────────────────────────────────────────
68
+ ws_manager = WebSocketManager()
69
+ task_engine = TaskEngine(ws_manager)
70
+ ai_router = AIRouter(ws_manager)
71
+ connector_manager = ConnectorManager()
72
+
73
+
74
+ # ─── Build v7 God Agent Ecosystem ─────────────────────────────────────────────
75
+ def build_orchestrator_v7() -> GodAgentOrchestratorV7:
76
+ orchestrator = GodAgentOrchestratorV7(ws_manager=ws_manager, ai_router=ai_router)
77
+
78
+ # ── Core agents (v3 retained) ──────────────────────────────────────────
79
+ orchestrator.register_agent("chat", ChatAgent(ws_manager, ai_router))
80
+ orchestrator.register_agent("planner", PlannerAgent(ws_manager, ai_router))
81
+ orchestrator.register_agent("coding", CodingAgent(ws_manager, ai_router))
82
+ orchestrator.register_agent("debug", DebugAgent(ws_manager, ai_router))
83
+ orchestrator.register_agent("memory", MemoryAgent(ws_manager, ai_router))
84
+ orchestrator.register_agent("connector", ConnectorAgent(ws_manager, ai_router))
85
+ orchestrator.register_agent("deploy", DeployAgent(ws_manager, ai_router))
86
+ orchestrator.register_agent("workflow", WorkflowAgent(ws_manager, ai_router))
87
+ orchestrator.register_agent("sandbox", SandboxAgent(ws_manager, ai_router))
88
+ orchestrator.register_agent("ui", UIAgent(ws_manager, ai_router))
89
+ orchestrator.register_agent("reasoning", ReasoningAgent(ws_manager, ai_router))
90
+
91
+ # ── v7 NEW agents ──────────────────────────────────────────────────────
92
+ orchestrator.register_agent("browser", BrowserAgent(ws_manager, ai_router))
93
+ orchestrator.register_agent("file", FileAgent(ws_manager, ai_router))
94
+ orchestrator.register_agent("git", GitAgent(ws_manager, ai_router))
95
+ orchestrator.register_agent("test", TestAgent(ws_manager, ai_router))
96
+ orchestrator.register_agent("vision", VisionAgent(ws_manager, ai_router))
97
+
98
+ log.info("🤖 GOD AGENT v7 Ecosystem initialized", agents=16)
99
+ return orchestrator
100
+
101
+
102
+ orchestrator = build_orchestrator_v7()
103
+
104
+
105
+ @asynccontextmanager
106
+ async def lifespan(app: FastAPI):
107
+ log.info("🚀 Starting GOD AGENT OS v7 — Autonomous Engineering Platform...")
108
+ await init_db()
109
+ await task_engine.start()
110
+ asyncio.create_task(ws_manager.heartbeat_loop())
111
+ log.info("✅ GOD AGENT v7 — All 16 agents online")
112
+ log.info("🤖 Core: Chat, Planner, Coding, Debug, Memory, Connector, Deploy, Workflow, Sandbox, UI, Reasoning")
113
+ log.info("⚡ v7 New: Browser, File, Git, Test, Vision")
114
+ log.info("🌐 AI Router: OpenAI → Groq → Cerebras → OpenRouter → Anthropic (auto-failover)")
115
+ yield
116
+ log.info("🛑 Shutting down GOD AGENT v7...")
117
+ await task_engine.stop()
118
+ log.info("✅ Shutdown complete")
119
+
120
+
121
+ # ─── FastAPI App ───────────────────────────────────────────────────────────────
122
+ app = FastAPI(
123
+ title="🤖 GOD AGENT OS v7",
124
+ description="Autonomous Engineering OS — Manus + Genspark + Devin (OneHand) Combined",
125
+ version="7.0.0",
126
+ lifespan=lifespan,
127
+ docs_url="/api/docs",
128
+ redoc_url="/api/redoc",
129
+ )
130
+
131
+ app.state.limiter = limiter
132
+ app.add_exception_handler(RateLimitExceeded, _rate_limit_exceeded_handler)
133
+
134
+ # ─── Share state ───────────────────────────────────────────────────────────────
135
+ app.state.ws_manager = ws_manager
136
+ app.state.task_engine = task_engine
137
+ app.state.ai_router = ai_router
138
+ app.state.orchestrator = orchestrator
139
+ app.state.connector_manager = connector_manager
140
+
141
+ # ─── Middleware ────────────────────────────────────────────────────────────────
142
+ app.add_middleware(
143
+ CORSMiddleware,
144
+ allow_origins=["*"],
145
+ allow_credentials=True,
146
+ allow_methods=["*"],
147
+ allow_headers=["*"],
148
+ )
149
+ app.add_middleware(GZipMiddleware, minimum_size=1000)
150
+
151
+
152
+ @app.middleware("http")
153
+ async def log_requests(request: Request, call_next):
154
+ start = time.time()
155
+ response = await call_next(request)
156
+ duration = round((time.time() - start) * 1000, 2)
157
+ log.info("HTTP", method=request.method, path=request.url.path, status=response.status_code, ms=duration)
158
+ return response
159
+
160
+
161
+ # ─── REST API Routers ──────────────────────────────────────────────────────────
162
+ app.include_router(health.router, prefix="/api/v1", tags=["health"])
163
+ app.include_router(tasks.router, prefix="/api/v1/tasks", tags=["tasks"])
164
+ app.include_router(chat.router, prefix="/api/v1", tags=["chat"])
165
+ app.include_router(memory.router, prefix="/api/v1/memory", tags=["memory"])
166
+ app.include_router(github.router, prefix="/api/v1/github", tags=["github"])
167
+ app.include_router(connectors.router, prefix="/api/v1/connectors", tags=["connectors"])
168
+ app.include_router(agents_router.router, prefix="/api/v1/agents", tags=["agents"])
169
+
170
+
171
+ # ─── WebSocket Endpoints ───────────────────────────────────────────────────────
172
+ @app.websocket("/ws/tasks/{task_id}")
173
+ async def ws_task(websocket: WebSocket, task_id: str):
174
+ await ws_manager.connect(websocket, room=f"task:{task_id}")
175
+ try:
176
+ while True:
177
+ data = await websocket.receive_text()
178
+ msg = json.loads(data)
179
+ if msg.get("type") == "ping":
180
+ await websocket.send_json({"type": "pong", "timestamp": time.time()})
181
+ except WebSocketDisconnect:
182
+ ws_manager.disconnect(websocket, room=f"task:{task_id}")
183
+
184
+
185
+ @app.websocket("/ws/logs")
186
+ async def ws_logs(websocket: WebSocket):
187
+ await ws_manager.connect(websocket, room="logs")
188
+ try:
189
+ while True:
190
+ data = await websocket.receive_text()
191
+ msg = json.loads(data)
192
+ if msg.get("type") == "ping":
193
+ await websocket.send_json({"type": "pong", "timestamp": time.time()})
194
+ except WebSocketDisconnect:
195
+ ws_manager.disconnect(websocket, room="logs")
196
+
197
+
198
+ @app.websocket("/ws/chat/{session_id}")
199
+ async def ws_chat(websocket: WebSocket, session_id: str):
200
+ await ws_manager.connect(websocket, room=f"chat:{session_id}")
201
+ try:
202
+ while True:
203
+ data = await websocket.receive_text()
204
+ msg = json.loads(data)
205
+ if msg.get("type") == "ping":
206
+ await websocket.send_json({"type": "pong", "timestamp": time.time()})
207
+ elif msg.get("type") == "chat_message":
208
+ asyncio.create_task(
209
+ orchestrator.orchestrate(
210
+ user_message=msg.get("content", ""),
211
+ session_id=session_id,
212
+ context=msg.get("context", {}),
213
+ )
214
+ )
215
+ elif msg.get("type") == "task_message":
216
+ from core.models import TaskCreateRequest
217
+ req = TaskCreateRequest(
218
+ goal=msg.get("content", ""),
219
+ session_id=session_id,
220
+ )
221
+ asyncio.create_task(task_engine.submit(req))
222
+ except WebSocketDisconnect:
223
+ ws_manager.disconnect(websocket, room=f"chat:{session_id}")
224
+
225
+
226
+ @app.websocket("/ws/agent/status")
227
+ async def ws_agent_status(websocket: WebSocket):
228
+ await ws_manager.connect(websocket, room="agent_status")
229
+ try:
230
+ while True:
231
+ data = await websocket.receive_text()
232
+ msg = json.loads(data)
233
+ if msg.get("type") == "ping":
234
+ await websocket.send_json({"type": "pong", "timestamp": time.time()})
235
+ elif msg.get("type") == "get_status":
236
+ await websocket.send_json({
237
+ "type": "agent_status",
238
+ "data": orchestrator.get_status(),
239
+ })
240
+ except WebSocketDisconnect:
241
+ ws_manager.disconnect(websocket, room="agent_status")
242
+
243
+
244
+ @app.websocket("/ws/sandbox/{session_id}")
245
+ async def ws_sandbox(websocket: WebSocket, session_id: str):
246
+ await ws_manager.connect(websocket, room=f"sandbox:{session_id}")
247
+ sandbox = orchestrator.get_agent("sandbox")
248
+ try:
249
+ while True:
250
+ data = await websocket.receive_text()
251
+ msg = json.loads(data)
252
+ if msg.get("type") == "ping":
253
+ await websocket.send_json({"type": "pong", "timestamp": time.time()})
254
+ elif msg.get("type") == "execute" and sandbox:
255
+ cmd = msg.get("command", "")
256
+ result = await sandbox.execute(cmd, session_id=session_id)
257
+ await websocket.send_json({
258
+ "type": "terminal_output",
259
+ "command": cmd,
260
+ "output": result,
261
+ "timestamp": time.time(),
262
+ })
263
+ except WebSocketDisconnect:
264
+ ws_manager.disconnect(websocket, room=f"sandbox:{session_id}")
265
+
266
+
267
+ # ─── v7 New Endpoints ──────────────────────────────────────────────────────────
268
+ @app.post("/api/v1/browser/research")
269
+ async def browser_research(request: Request):
270
+ body = await request.json()
271
+ query = body.get("query", "")
272
+ session_id = body.get("session_id", "")
273
+ browser = orchestrator.get_agent("browser")
274
+ if not browser:
275
+ raise HTTPException(status_code=503, detail="BrowserAgent not available")
276
+ result = await browser.run(query, session_id=session_id)
277
+ return {"result": result}
278
+
279
+
280
+ @app.get("/api/v1/files/workspace")
281
+ async def list_workspace():
282
+ file_agent = orchestrator.get_agent("file")
283
+ if not file_agent:
284
+ return {"workspace": "/tmp/god_workspace", "files": [], "total": 0}
285
+ return file_agent.list_workspace()
286
+
287
+
288
+ @app.post("/api/v1/git/pr")
289
+ async def create_pr(request: Request):
290
+ body = await request.json()
291
+ git_agent = orchestrator.get_agent("git")
292
+ if not git_agent:
293
+ raise HTTPException(status_code=503, detail="GitAgent not available")
294
+ result = await git_agent.create_github_pr(
295
+ repo_owner=body.get("owner", ""),
296
+ repo_name=body.get("repo", ""),
297
+ title=body.get("title", ""),
298
+ body=body.get("body", ""),
299
+ head_branch=body.get("head_branch", "main"),
300
+ base_branch=body.get("base_branch", "main"),
301
+ )
302
+ return result
303
+
304
+
305
+ @app.post("/api/v1/vision/generate")
306
+ async def generate_ui(request: Request):
307
+ body = await request.json()
308
+ vision = orchestrator.get_agent("vision")
309
+ if not vision:
310
+ raise HTTPException(status_code=503, detail="VisionAgent not available")
311
+ result = await vision.run(
312
+ body.get("prompt", ""),
313
+ context=body.get("context", {}),
314
+ session_id=body.get("session_id", ""),
315
+ )
316
+ return {"result": result}
317
+
318
+
319
+ # ─── Root ──────────────────────────────────────────────────────────────────────
320
+ @app.get("/")
321
+ async def root():
322
+ cs = connector_manager.get_summary()
323
+ status = orchestrator.get_status()
324
+ return {
325
+ "name": "🤖 GOD AGENT OS v7",
326
+ "version": "7.0.0",
327
+ "status": "operational",
328
+ "mode": "autonomous_engineering_os",
329
+ "description": "Manus + Genspark + Devin (OneHand) — Autonomous Engineering Platform",
330
+ "agents": status["agents"],
331
+ "total_agents": status["total_agents"],
332
+ "capabilities": status["capabilities"],
333
+ "connectors": {
334
+ "connected": cs["connected"],
335
+ "total": cs["total"],
336
+ "ai_ready": cs["ai_ready"],
337
+ },
338
+ "docs": "/api/docs",
339
+ "websockets": [
340
+ "/ws/tasks/{task_id}",
341
+ "/ws/logs",
342
+ "/ws/chat/{session_id}",
343
+ "/ws/agent/status",
344
+ "/ws/sandbox/{session_id}",
345
+ ],
346
+ "v7_new_features": [
347
+ "🌐 BrowserAgent — Web research & scraping",
348
+ "📁 FileAgent — Full file system control & project scaffolding",
349
+ "🔀 GitAgent — Autonomous Git & GitHub PR operations",
350
+ "🧪 TestAgent — Auto test generation & execution",
351
+ "🎨 VisionAgent — Design-to-code UI generation",
352
+ "⚡ 16-agent parallel orchestration",
353
+ "🔄 Advanced self-healing loop",
354
+ "🧠 Enhanced intent classification",
355
+ "📊 Real-time execution timeline",
356
+ ],
357
+ }
358
+
359
+
360
+ if __name__ == "__main__":
361
+ import uvicorn
362
+ port = int(os.environ.get("PORT", 8000))
363
+ uvicorn.run("main_v7:app", host="0.0.0.0", port=port, reload=False, workers=1)
requirements.txt CHANGED
@@ -3,17 +3,24 @@ uvicorn[standard]==0.29.0
3
  websockets==12.0
4
  pydantic==2.7.1
5
  pydantic-settings==2.2.1
 
6
  python-multipart==0.0.9
7
  aiohttp==3.9.5
8
  aiosqlite==0.20.0
 
9
  httpx==0.27.0
 
 
10
  gitpython==3.1.43
11
  pygithub==2.3.0
12
  python-dotenv==1.0.1
13
  slowapi==0.1.9
14
  structlog==24.1.0
15
  rich==13.7.1
16
- psutil==5.9.8
17
- python-jose[cryptography]==3.3.0
18
  passlib[bcrypt]==1.7.4
19
  cryptography==42.0.7
 
 
 
 
 
 
3
  websockets==12.0
4
  pydantic==2.7.1
5
  pydantic-settings==2.2.1
6
+ python-jose[cryptography]==3.3.0
7
  python-multipart==0.0.9
8
  aiohttp==3.9.5
9
  aiosqlite==0.20.0
10
+ sqlalchemy[asyncio]==2.0.30
11
  httpx==0.27.0
12
+ openai==1.30.1
13
+ anthropic==0.26.1
14
  gitpython==3.1.43
15
  pygithub==2.3.0
16
  python-dotenv==1.0.1
17
  slowapi==0.1.9
18
  structlog==24.1.0
19
  rich==13.7.1
 
 
20
  passlib[bcrypt]==1.7.4
21
  cryptography==42.0.7
22
+ psutil==5.9.8
23
+ huggingface_hub==0.23.2
24
+ requests==2.32.2
25
+ beautifulsoup4==4.12.3
26
+ lxml==5.2.2