File size: 8,135 Bytes
ccb935d
 
 
 
 
 
 
 
 
e6e75d6
ccb935d
 
 
 
e6e75d6
 
 
 
 
 
 
 
 
ccb935d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
e6e75d6
ccb935d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
e6e75d6
81aa0b5
 
 
e6e75d6
81aa0b5
 
 
 
ccb935d
e6e75d6
ccb935d
e6e75d6
 
 
 
ccb935d
e6e75d6
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
ccb935d
81aa0b5
e6e75d6
 
 
 
ccb935d
81aa0b5
e6e75d6
 
ccb935d
81aa0b5
 
 
ccb935d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
"""Application-wide constants, regex patterns, language options, and system prompt."""

from __future__ import annotations

import re

# ─── App Identity ────────────────────────────────────────────────────────

APP_TITLE = "SoniCoder"
MODEL_URL = "https://huggingface.co/Qwen/Qwen2.5-Coder-1.5B-Instruct"

# ─── Model Configs ───────────────────────────────────────────────────────

MODEL_CONFIGS = {
    "qwen25-coder-1.5b": {
        "id": "Qwen/Qwen2.5-Coder-1.5B-Instruct",
        "name": "Qwen2.5-Coder-1.5B",
        "type": "text",
        "description": "Smart 1B code model β€” best at tool-calling & writing real files",
        "auto_class": "AutoModelForCausalLM",
        "tokenizer_class": "AutoTokenizer",
        "size_gb": 3.0,
    },
    "minicpm5-1b": {
        "id": "openbmb/MiniCPM5-1B",
        "name": "MiniCPM5-1B",
        "type": "text",
        "description": "Text-only, fast code generation",
        "auto_class": "AutoModelForCausalLM",
        "tokenizer_class": "AutoTokenizer",
        "size_gb": 2.17,
    },
    "minicpm-v-4.6": {
        "id": "openbmb/MiniCPM-V-4.6",
        "name": "MiniCPM-V-4.6",
        "type": "vlm",
        "description": "Vision + Text, image understanding & code",
        "auto_class": "AutoModelForImageTextToText",
        "processor_class": "AutoProcessor",
        "size_gb": 2.8,
    },
}

DEFAULT_MODEL_KEY = "qwen25-coder-1.5b"

# Keep backward compat aliases
MODEL_ID = MODEL_CONFIGS[DEFAULT_MODEL_KEY]["id"]

# ─── Runtime Defaults ───────────────────────────────────────────────────

DEFAULT_TEMPERATURE = 0.4
DEFAULT_MAX_TOKENS = 2048
PY_TIMEOUT_S = 15
GRADIO_TIMEOUT_S = 30
PY_MEM_LIMIT_MB = 1024
MAX_STDIO_CHARS = 16_000
OUTPUT_PNG = "output.png"

# ─── Regex Patterns ─────────────────────────────────────────────────────

THINKING_BLOCK_RE = re.compile(
    r"<\s*think\s*>.*?<\s*/\s*think\s*>", re.IGNORECASE | re.DOTALL
)
CODE_BLOCK_RE = re.compile(
    r"```([a-zA-Z0-9_+.#-]*)\s*\n(.*?)```", re.DOTALL
)
FILE_BLOCK_RE = re.compile(
    r"@@FILE:\s*(.+?)@@\s*\n(.*?)(?=@@FILE:|@@END@@)", re.DOTALL
)

# ─── Supported Languages & Frameworks ───────────────────────────────────

LANGUAGE_OPTIONS: list[tuple[str, list[str]]] = [
    ("Python", ["Gradio", "Flask", "Django", "FastAPI", "Streamlit", "Plain Python"]),
    ("JavaScript", ["React", "Vue.js", "Next.js", "Express.js", "Node.js", "Vanilla JS"]),
    ("TypeScript", ["React", "Next.js", "Express.js", "NestJS"]),
    ("HTML/CSS/JS", ["Tailwind CSS", "Bootstrap", "Vanilla"]),
    ("Java", ["Spring Boot", "Maven", "Gradle"]),
    ("Go", ["Gin", "Fiber", "Echo", "Plain Go"]),
    ("Rust", ["Actix", "Axum", "Rocket"]),
    ("PHP", ["Laravel", "Symfony", "Plain PHP"]),
    ("Ruby", ["Rails", "Sinatra"]),
    ("C#", ["ASP.NET", "Blazor"]),
    ("Swift", ["Vapor", "SwiftUI"]),
    ("Kotlin", ["Ktor", "Spring Boot"]),
]

LANGUAGE_MAP: dict[str, list[str]] = {lang: frameworks for lang, frameworks in LANGUAGE_OPTIONS}

# ─── System Prompt ───────────────────────────────────────────────────────

SYSTEM_PROMPT = """You are SoniCoder β€” an autonomous coding agent that writes files to a sandboxed workspace using tools.

CAPABILITIES:
- Generate complete, runnable applications in any language/framework
- Read, write, and edit files in the workspace via tools
- Run shell commands (git, npm, pip, tests) via the bash tool
- Track multi-step tasks with the todo system
- Apply specialized skills (frontend-design, feature-dev, code-review, debugging, fullstack-scaffold, commit-workflow)
- Respond to slash commands: /commit, /review, /feature, /design, /explain, /test, /refactor, /skill, /help

CRITICAL RULES β€” READ CAREFULLY:

1. NEVER paste code directly in your reply as a markdown code block.
   - Do NOT use ```python, ```html, ```javascript, etc. for code that should be saved.
   - Do NOT use the @@FILE: format.
   - ALL code MUST be saved to files using the `write_file` tool.

2. For ANY file you want to create (Python, HTML, JS, config, README, etc.), call the `write_file` tool with the full path and content. The file will be written to the sandboxed workspace automatically.

3. For multi-step tasks, ALWAYS create a todo list first with `todo_write`.

4. Read files before editing them β€” call `read_file` first, then `edit_file`.

5. Match the codebase's existing style and conventions.

6. After each tool call, briefly note what you did (one short sentence), then continue with the next step or finish.

7. Do NOT use <think> or <thinking> tags. Do NOT reason aloud.

8. When done, give a concise summary of which files you created or modified.

WORKFLOW EXAMPLE:
- User asks: "Build a Flask API for a book library"
- You: call todo_write β†’ call write_file (app.py) β†’ call write_file (requirements.txt) β†’ call write_file (README.md) β†’ respond with a short summary listing the files created.

FULLSTACK PROJECT RULES:
- For React/Next.js/Vue/Express/NestJS: create package.json, vite.config.js or next.config.js as needed, plus all source files via `write_file`.
- Server ports MUST be 7860 and bind to 0.0.0.0.
- Do NOT include node_modules or lock files.
- For Python web apps: use gradio/flask/fastapi/streamlit as appropriate.

GRADIO APP RULES:
- Create a single app.py file via `write_file` that imports gradio, defines the UI, and calls .launch(server_name="0.0.0.0", server_port=7860).

WEB APP RULES (HTML/CSS/JS):
- Save a single self-contained index.html via `write_file` with all CSS and JS inline.

PYTHON RULES:
- Prefer standard library or common packages.
- Add proper error handling and comments.

If web search results are provided, use them to inform your code generation.
If the user provides an image, analyze it and generate code based on what you see.
If a hook warns you, acknowledge it and adjust your approach.
"""

# ─── Example Prompts ────────────────────────────────────────────────────

EXAMPLE_PROMPTS: list[tuple[str, str, str, str]] = [
    (
        "🎨 Gradio Image Filter",
        "Create a Gradio app that lets users upload an image and apply filters like grayscale, blur, sepia, and edge detection using PIL. Show the original and filtered images side by side.",
        "Python",
        "Gradio",
    ),
    (
        "πŸ€– Gradio Chat App",
        "Build a Gradio chatbot app with gr.Blocks that has a chat interface, a text input, and a send button. Include a simple echo bot that repeats the user's message with a fun twist.",
        "Python",
        "Gradio",
    ),
    (
        "🌐 React Todo App",
        "Build a React todo application with add, delete, mark complete, and filter functionality. Use modern hooks and a clean responsive UI.",
        "JavaScript",
        "React",
    ),
    (
        "🐍 Flask API",
        "Create a Flask REST API for a book library with CRUD operations, in-memory storage, and proper error handling.",
        "Python",
        "Flask",
    ),
    (
        "🎨 Landing Page",
        "Build a modern landing page for a SaaS product with a hero section, features grid, pricing cards, and a footer. Use Tailwind-style CSS.",
        "HTML/CSS/JS",
        "Vanilla",
    ),
    (
        "πŸ“Š Dashboard",
        "Create an interactive data dashboard with charts (bar, line, pie), a sidebar navigation, and summary cards. All in a single HTML file.",
        "HTML/CSS/JS",
        "Vanilla",
    ),
]