Spaces:
Sleeping
Sleeping
| """ | |
| ConnectorAgent β GitHub, HuggingFace, Vercel, n8n, Telegram, Discord integrations | |
| """ | |
| import json | |
| import os | |
| from typing import Dict, List, Optional | |
| import httpx | |
| import structlog | |
| from .base_agent import BaseAgent | |
| log = structlog.get_logger() | |
| class ConnectorAgent(BaseAgent): | |
| def __init__(self, ws_manager=None, ai_router=None): | |
| super().__init__("ConnectorAgent", ws_manager, ai_router) | |
| async def run(self, task: str, context: Dict = {}, **kwargs) -> str: | |
| session_id = kwargs.get("session_id", "") | |
| task_id = kwargs.get("task_id", "") | |
| task_lower = task.lower() | |
| if "github" in task_lower: | |
| return await self.github_operation(task, task_id=task_id, session_id=session_id) | |
| elif "huggingface" in task_lower or "hf" in task_lower: | |
| return await self.hf_operation(task, task_id=task_id, session_id=session_id) | |
| elif "vercel" in task_lower: | |
| return await self.vercel_operation(task, task_id=task_id, session_id=session_id) | |
| else: | |
| return await self._generic_connector(task, task_id=task_id, session_id=session_id) | |
| # βββ GitHub βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| async def github_operation(self, task: str, task_id: str = "", session_id: str = "") -> str: | |
| token = os.environ.get("GITHUB_TOKEN", "") | |
| if not token: | |
| return "β οΈ GITHUB_TOKEN not set. Please add it to environment variables." | |
| headers = { | |
| "Authorization": f"token {token}", | |
| "Accept": "application/vnd.github.v3+json", | |
| } | |
| task_lower = task.lower() | |
| try: | |
| async with httpx.AsyncClient(timeout=30) as client: | |
| if "create repo" in task_lower or "new repo" in task_lower: | |
| return await self._github_create_repo(client, headers, task, task_id, session_id) | |
| elif "list repo" in task_lower: | |
| return await self._github_list_repos(client, headers, task_id, session_id) | |
| elif "commit" in task_lower: | |
| return f"β GitHub commit operation noted. Use SandboxAgent for actual commits." | |
| elif "issue" in task_lower: | |
| return await self._github_create_issue(client, headers, task, task_id, session_id) | |
| else: | |
| return await self._github_user_info(client, headers, task_id, session_id) | |
| except Exception as e: | |
| return f"β GitHub error: {str(e)}" | |
| async def _github_user_info(self, client, headers, task_id, session_id) -> str: | |
| resp = await client.get("https://api.github.com/user", headers=headers) | |
| if resp.status_code == 200: | |
| data = resp.json() | |
| await self.emit(task_id, "connector_result", { | |
| "connector": "github", | |
| "action": "user_info", | |
| "user": data.get("login"), | |
| }, session_id) | |
| return f"β GitHub connected as **{data.get('login')}** ({data.get('public_repos')} repos)" | |
| return f"β GitHub auth failed: {resp.status_code}" | |
| async def _github_create_repo(self, client, headers, task, task_id, session_id) -> str: | |
| # Extract repo name from task using simple heuristic | |
| words = task.split() | |
| name_candidates = [w for w in words if w.replace("-", "").replace("_", "").isalnum() and len(w) > 3] | |
| repo_name = name_candidates[-1] if name_candidates else "god-agent-project" | |
| payload = { | |
| "name": repo_name, | |
| "description": "Created by God Agent Platform", | |
| "private": False, | |
| "auto_init": True, | |
| } | |
| resp = await client.post("https://api.github.com/user/repos", headers=headers, json=payload) | |
| if resp.status_code == 201: | |
| data = resp.json() | |
| await self.emit(task_id, "connector_result", { | |
| "connector": "github", | |
| "action": "repo_created", | |
| "repo": data.get("full_name"), | |
| "url": data.get("html_url"), | |
| }, session_id) | |
| return f"β GitHub repo created: [{data.get('full_name')}]({data.get('html_url')})" | |
| return f"β Failed to create repo: {resp.status_code} β {resp.text[:200]}" | |
| async def _github_list_repos(self, client, headers, task_id, session_id) -> str: | |
| resp = await client.get("https://api.github.com/user/repos?per_page=10&sort=updated", headers=headers) | |
| if resp.status_code == 200: | |
| repos = resp.json() | |
| lines = [f"- [{r['full_name']}]({r['html_url']}) β{r['stargazers_count']}" for r in repos[:10]] | |
| return "π¦ **Your GitHub Repos:**\n\n" + "\n".join(lines) | |
| return f"β Failed to list repos: {resp.status_code}" | |
| async def _github_create_issue(self, client, headers, task, task_id, session_id) -> str: | |
| return "β GitHub issue creation requires repo context. Specify: 'create issue in owner/repo: title'" | |
| # βββ HuggingFace ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| async def hf_operation(self, task: str, task_id: str = "", session_id: str = "") -> str: | |
| token = os.environ.get("HF_TOKEN", "") | |
| if not token: | |
| return "β οΈ HF_TOKEN not set. Add HuggingFace token to environment." | |
| headers = {"Authorization": f"Bearer {token}"} | |
| try: | |
| async with httpx.AsyncClient(timeout=30) as client: | |
| resp = await client.get("https://huggingface.co/api/whoami", headers=headers) | |
| if resp.status_code == 200: | |
| data = resp.json() | |
| await self.emit(task_id, "connector_result", { | |
| "connector": "huggingface", | |
| "user": data.get("name"), | |
| }, session_id) | |
| return f"β HuggingFace connected as **{data.get('name')}**" | |
| return f"β HF auth failed: {resp.status_code}" | |
| except Exception as e: | |
| return f"β HuggingFace error: {str(e)}" | |
| # βββ Vercel βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| async def vercel_operation(self, task: str, task_id: str = "", session_id: str = "") -> str: | |
| token = os.environ.get("VERCEL_TOKEN", "") | |
| if not token: | |
| return "β οΈ VERCEL_TOKEN not set. Add Vercel token to environment." | |
| headers = {"Authorization": f"Bearer {token}"} | |
| try: | |
| async with httpx.AsyncClient(timeout=30) as client: | |
| resp = await client.get("https://api.vercel.com/v2/user", headers=headers) | |
| if resp.status_code == 200: | |
| data = resp.json() | |
| user = data.get("user", {}) | |
| await self.emit(task_id, "connector_result", { | |
| "connector": "vercel", | |
| "user": user.get("username"), | |
| }, session_id) | |
| return f"β Vercel connected as **{user.get('username')}** ({user.get('email')})" | |
| return f"β Vercel auth failed: {resp.status_code}" | |
| except Exception as e: | |
| return f"β Vercel error: {str(e)}" | |
| async def _generic_connector(self, task: str, task_id: str = "", session_id: str = "") -> str: | |
| return ( | |
| "π **Available Connectors:**\n\n" | |
| "| Connector | Status | Env Var |\n" | |
| "|-----------|--------|---------||\n" | |
| f"| GitHub | {'β ' if os.environ.get('GITHUB_TOKEN') else 'β'} | GITHUB_TOKEN |\n" | |
| f"| HuggingFace | {'β ' if os.environ.get('HF_TOKEN') else 'β'} | HF_TOKEN |\n" | |
| f"| Vercel | {'β ' if os.environ.get('VERCEL_TOKEN') else 'β'} | VERCEL_TOKEN |\n" | |
| f"| OpenAI | {'β ' if os.environ.get('OPENAI_API_KEY') else 'β'} | OPENAI_API_KEY |\n" | |
| f"| Groq | {'β ' if os.environ.get('GROQ_API_KEY') else 'β'} | GROQ_API_KEY |\n" | |
| f"| OpenRouter | {'β ' if os.environ.get('OPENROUTER_API_KEY') else 'β'} | OPENROUTER_API_KEY |\n" | |
| ) | |
| def get_connector_status(self) -> Dict: | |
| """Return status of all connectors.""" | |
| connectors = { | |
| "github": bool(os.environ.get("GITHUB_TOKEN")), | |
| "huggingface": bool(os.environ.get("HF_TOKEN")), | |
| "vercel": bool(os.environ.get("VERCEL_TOKEN")), | |
| "openai": bool(os.environ.get("OPENAI_API_KEY")), | |
| "groq": bool(os.environ.get("GROQ_API_KEY")), | |
| "cerebras": bool(os.environ.get("CEREBRAS_API_KEY")), | |
| "openrouter": bool(os.environ.get("OPENROUTER_API_KEY")), | |
| "anthropic": bool(os.environ.get("ANTHROPIC_API_KEY")), | |
| "n8n": bool(os.environ.get("N8N_URL")), | |
| "telegram": bool(os.environ.get("TELEGRAM_BOT_TOKEN")), | |
| "discord": bool(os.environ.get("DISCORD_BOT_TOKEN")), | |
| } | |
| return { | |
| "connectors": connectors, | |
| "connected_count": sum(connectors.values()), | |
| "total": len(connectors), | |
| } | |