File size: 12,898 Bytes
03535ab
 
 
 
 
 
 
 
 
 
 
d4f895f
03535ab
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
d4f895f
03535ab
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
d4f895f
03535ab
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
d4f895f
03535ab
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
d4f895f
03535ab
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
import json
import httpx
from typing import AsyncGenerator
from config import settings


class BaseAgent:
    role: str = ""
    model_key: str = ""
    system_prompt: str = ""
    temperature: float = 0.7
    max_tokens: int = 100000

    @property
    def model_id(self) -> str:
        return settings.MODEL_IDS[self.model_key]

    @property
    def model_name(self) -> str:
        return settings.MODEL_NAMES[self.model_key]

    async def call(
        self, messages: list[dict], stream: bool = True
    ) -> AsyncGenerator[str, None]:
        full_messages = [
            {"role": "system", "content": self.system_prompt},
            *messages,
        ]
        payload = {
            "model": self.model_id,
            "messages": full_messages,
            "temperature": self.temperature,
            "max_tokens": self.max_tokens,
            "stream": stream,
        }
        headers = {
            "Authorization": f"Bearer {settings.OPENROUTER_API_KEY}",
            "Content-Type": "application/json",
            "HTTP-Referer": "https://huggingface.co/spaces/nexus-builder",
            "X-Title": "Nexus Builder",
        }

        if stream:
            async with httpx.AsyncClient(
                timeout=httpx.Timeout(settings.STREAM_TIMEOUT, connect=30.0)
            ) as client:
                async with client.stream(
                    "POST",
                    settings.OPENROUTER_BASE_URL,
                    json=payload,
                    headers=headers,
                ) as resp:
                    if resp.status_code != 200:
                        body = await resp.aread()
                        raise Exception(
                            f"OpenRouter {resp.status_code}: {body.decode()[:500]}"
                        )
                    async for line in resp.aiter_lines():
                        if not line.startswith("data: "):
                            continue
                        raw = line[6:]
                        if raw.strip() == "[DONE]":
                            break
                        try:
                            chunk = json.loads(raw)
                            tok = (
                                chunk.get("choices", [{}])[0]
                                .get("delta", {})
                                .get("content", "")
                            )
                            if tok:
                                yield tok
                        except (json.JSONDecodeError, KeyError, IndexError):
                            continue
        else:
            async with httpx.AsyncClient(
                timeout=httpx.Timeout(settings.STREAM_TIMEOUT, connect=30.0)
            ) as client:
                resp = await client.post(
                    settings.OPENROUTER_BASE_URL,
                    json=payload,
                    headers=headers,
                )
                if resp.status_code != 200:
                    raise Exception(
                        f"OpenRouter {resp.status_code}: {resp.text[:500]}"
                    )
                data = resp.json()
                content = data["choices"][0]["message"]["content"]
                yield content

    async def call_full(self, messages: list[dict]) -> str:
        parts: list[str] = []
        async for token in self.call(messages, stream=True):
            parts.append(token)
        return "".join(parts)


# ────────────────────────────────────────────────────────────
# AGENT 1 β€” Research (GLM 4.5 Air)
# ────────────────────────────────────────────────────────────
class ResearchAgent(BaseAgent):
    role = "research"
    model_key = "research"
    temperature = 0.4
    max_tokens = 100000
    system_prompt = (
        "You are the RESEARCH AGENT for Nexus Builder, an AI web-app generator.\n\n"
        "YOUR ROLE: Given an app idea, produce a structured JSON research report.\n\n"
        "Output a JSON object with these exact keys:\n"
        "{\n"
        '  "stack_recommendation": "Frontend framework, CSS, backend, DB, hosting advice",\n'
        '  "schema_hints": "Database tables, columns, relationships for this app type",\n'
        '  "api_docs_summary": "Key API endpoints needed including PayPal, Supabase Auth",\n'
        '  "security_notes": "Auth flows, input validation, CORS, rate limiting, XSS, SQLI prevention",\n'
        '  "hosting_notes": "Firebase Hosting tips, Docker config, env var management",\n'
        '  "ui_patterns": "UI components, UX flows, and design patterns for this app type",\n'
        '  "competitor_analysis": "Brief analysis of similar apps and expected features"\n'
        "}\n\n"
        "RULES:\n"
        "- Always respond with VALID JSON inside a ```json code block\n"
        "- Be thorough but concise\n"
        "- Use 2024-2025 best practices\n"
        "- Prioritize: Supabase (DB/Auth), PayPal (payments), React+Tailwind (frontend), FastAPI (backend)"
    )


# ────────────────────────────────────────────────────────────
# AGENT 2 β€” Orchestrator (Trinity Large Preview)
# ────────────────────────────────────────────────────────────
class OrchestratorAgent(BaseAgent):
    role = "orchestrator"
    model_key = "orchestrator"
    temperature = 0.5
    max_tokens = 100000
    system_prompt = (
        "You are the MASTER ORCHESTRATOR for Nexus Builder.\n\n"
        "YOUR ROLE: Take a user's app description + research data and produce a MASTER BLUEPRINT.\n\n"
        "Output a JSON object with this structure:\n"
        "```json\n"
        "{\n"
        '  "project_name": "my-app",\n'
        '  "description": "...",\n'
        '  "systems": {\n'
        '    "client_portal": {\n'
        '      "pages": [\n'
        '        {"path":"/dashboard","title":"Dashboard","components":["Sidebar","StatsCards","RecentActivity"],"description":"Main dashboard","auth_required":true}\n'
        "      ],\n"
        '      "features": ["auth","billing","settings"]\n'
        "    },\n"
        '    "public_landing": {\n'
        '      "pages": [{"path":"/","title":"Home","components":["Hero","Features","Pricing","CTA"],"auth_required":false}],\n'
        '      "features": ["hero","pricing","signup","seo"]\n'
        "    },\n"
        '    "marketing_cms": {\n'
        '      "pages": [{"path":"/blog","title":"Blog","components":["BlogList","PostEditor"],"auth_required":true}],\n'
        '      "features": ["blog_editor","email_capture"]\n'
        "    },\n"
        '    "analytics_dashboard": {\n'
        '      "pages": [{"path":"/analytics","title":"Analytics","components":["Charts","Metrics","UserTable"],"auth_required":true}],\n'
        '      "features": ["realtime_metrics","charts","revenue"]\n'
        "    },\n"
        '    "admin_panel": {\n'
        '      "pages": [{"path":"/admin","title":"Admin","components":["UserMgmt","Logs","Settings"],"auth_required":true}],\n'
        '      "features": ["user_management","moderation","logs"]\n'
        "    }\n"
        "  },\n"
        '  "database_schema": {\n'
        '    "tables": [\n'
        '      {"name":"profiles","columns":[{"name":"id","type":"uuid","primary":true},{"name":"email","type":"text"},{"name":"role","type":"text","default":"user"},{"name":"created_at","type":"timestamptz","default":"now()"}],"rls_policies":["Users read own profile"]}\n'
        "    ]\n"
        "  },\n"
        '  "api_endpoints": [\n'
        '    {"method":"POST","path":"/api/auth/signup","description":"Register user"},\n'
        '    {"method":"POST","path":"/api/payments/create-order","description":"Create PayPal order"}\n'
        "  ],\n"
        '  "auth_config": {"providers":["email","google"],"jwt_expiry":3600},\n'
        '  "payment_config": {"provider":"paypal","plans":[{"name":"Free","price":0,"features":["Basic"]},{"name":"Pro","price":29,"features":["All features"]}]},\n'
        '  "design_tokens": {\n'
        '    "colors":{"primary":"#6C63FF","secondary":"#00D9FF","background":"#0A0A0F","surface":"#111118","text":"#F0F0FF"},\n'
        '    "fonts":{"heading":"Inter","body":"Inter","mono":"JetBrains Mono"}\n'
        "  }\n"
        "}\n"
        "```\n\n"
        "RULES:\n"
        "- Every page MUST have specific components listed\n"
        "- Every table MUST have complete column definitions\n"
        "- Include PayPal integration in billing pages\n"
        "- Include Supabase Auth in all auth flows\n"
        "- Customize EVERYTHING for the user's specific app idea\n"
        "- Response MUST be valid JSON in a ```json block"
    )


# ────────────────────────────────────────────────────────────
# AGENT 3 β€” Frontend (Qwen3 Coder 480B)
# ────────────────────────────────────────────────────────────
class FrontendAgent(BaseAgent):
    role = "frontend"
    model_key = "frontend"
    temperature = 0.6
    max_tokens = 100000
    system_prompt = (
        "You are the FRONTEND CODE GENERATION AGENT for Nexus Builder.\n\n"
        "TECH STACK: React 18, Tailwind CSS, React Router v6, Supabase JS, "
        "@paypal/react-paypal-js, Recharts, Lucide React icons.\n\n"
        "DESIGN SYSTEM:\n"
        "Dark: bg #0A0A0F, surface #111118, border #1E1E2E, accent #6C63FF, "
        "cyan #00D9FF, text #F0F0FF, muted #8888AA, success #22D3A8, error #FF4D6D\n"
        "Light: bg #F8F8FC, surface #FFFFFF, border #E0E0EF, accent #5B53E8\n\n"
        "RULES:\n"
        "1. Generate COMPLETE files β€” NO placeholders, NO truncation, NO '...rest'\n"
        "2. Every component must be fully functional with state management\n"
        "3. Mobile-first responsive design with Tailwind\n"
        "4. Dark/light mode via CSS variables\n"
        "5. Smooth animations and transitions\n"
        "6. Accessible markup (ARIA labels, semantic HTML)\n"
        "7. Error boundaries and loading states\n\n"
        "OUTPUT FORMAT β€” Mark each file clearly:\n"
        "// FILE: system_name/src/ComponentName.jsx\n"
        "[complete file content]\n\n"
        "// FILE: system_name/src/App.jsx\n"
        "[complete file content]\n\n"
        "Generate ALL files for the requested system. Include pages, components, "
        "routing, Supabase client, theme provider, package.json, tailwind config, "
        "index.html, and CSS. Make it look PREMIUM β€” glass morphism, gradients, micro-animations."
    )


# ────────────────────────────────────────────────────────────
# AGENT 4 β€” Backend (MiniMax M2.5)
# ────────────────────────────────────────────────────────────
class BackendAgent(BaseAgent):
    role = "backend"
    model_key = "backend"
    temperature = 0.4
    max_tokens = 100000
    system_prompt = (
        "You are the BACKEND, SECURITY, DATABASE & DEVOPS AGENT for Nexus Builder.\n\n"
        "TECH STACK: Python FastAPI, Supabase (PostgreSQL + Auth + Realtime + Edge Functions), "
        "PayPal REST API v2, Docker, Firebase Hosting.\n\n"
        "YOUR OUTPUTS:\n"
        "1. Supabase SQL Schema β€” CREATE TABLE, RLS policies, triggers, indexes\n"
        "2. FastAPI backend β€” routes, auth middleware, PayPal integration, rate limiting, CORS\n"
        "3. Supabase Edge Functions (TypeScript) β€” webhooks, emails\n"
        "4. Security β€” input validation, SQL injection prevention, XSS headers\n"
        "5. DevOps β€” Dockerfile, docker-compose.yml, .env.example, firebase.json, DEPLOY.md\n\n"
        "RULES:\n"
        "1. Generate COMPLETE files β€” NO placeholders or truncation\n"
        "2. All SQL must be valid PostgreSQL\n"
        "3. All Python must be valid, typed, and async\n"
        "4. Never expose secrets β€” always use environment variables\n"
        "5. Comprehensive error handling everywhere\n\n"
        "OUTPUT FORMAT β€” Mark each file:\n"
        "# FILE: backend/main.py\n"
        "[complete content]\n\n"
        "-- FILE: database/schema.sql\n"
        "[complete SQL]\n\n"
        "# FILE: deploy/Dockerfile\n"
        "[complete content]"
    )