Spaces:
Running
A newer version of the Gradio SDK is available: 6.19.0
SoniCoder β Project Memory
This file is the project's persistent memory. The agent reads it on every session. Edit it freely β it overrides defaults.
What is SoniCoder?
SoniCoder is a local-first AI coding agent that can:
- Generate complete fullstack applications in any language/framework
- Read, write, and edit files in a sandboxed workspace
- Run shell commands (git, npm, pip, tests)
- 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)
- Deploy to HuggingFace Spaces with one click
Architecture
app.py β Entry point: launches Gradio Server
code/
βββ config/constants.py β App config, system prompt, language options
βββ model/
β βββ loader.py β Dual model loading (text + VLM)
β βββ inference.py β Streaming inference (text + VLM)
βββ agent/__init__.py β Agent loop (model β tools, supports custom agents)
βββ tools/
β βββ fs.py β read_file, write_file, edit_file, glob, grep, list_dir
β βββ bash.py β Sandboxed shell execution
β βββ todos.py β Todo list management
β βββ github.py β GitHub repo import (shallow clone + strip heavy dirs)
βββ skills/
β βββ __init__.py β Skill discovery + loading
β βββ builtins/ β Built-in skills (markdown)
βββ agents/ β Custom Agent system (AI-generated personas)
β βββ __init__.py β Agent CRUD + system-prompt builder
β βββ builtins/ β Built-in agents (code-reviewer, test-writer)
βββ commands/
β βββ __init__.py β Slash command parser + expander
β βββ builtins/ β Built-in commands (markdown, includes /agent and /github)
βββ hooks/
β βββ __init__.py β Hook rule engine
β βββ builtins/ β Built-in hook rules (markdown)
βββ execution/
β βββ code_extractor.py β Code extraction from model output
β βββ python_runner.py β Sandboxed Python execution
β βββ gradio_runner.py β Gradio app subprocess runner
βββ huggingface/
β βββ dockerfile_gen.py β Auto Dockerfile/package.json for JS
β βββ push.py β HF Hub push + ZIP packaging
βββ websearch/google_scraper.py β DuckDuckGo + Google scraping (no API)
βββ server/
βββ chat_helpers.py β Chat history + prompt building
βββ routes.py β All HTTP + API endpoints
index.html β Frontend (single-file SPA)
workspace/ β Sandboxed agent workspace (auto-created)
Conventions
- Python: 3.11+, type hints everywhere,
from __future__ import annotations - Style: Black formatting, 4-space indent, 100 char line limit
- Docstrings: Google style for modules, functions, classes
- Error handling: catch specific exceptions, never bare
except: - Logging: use
logging.getLogger(__name__), neverprint() - Tests: pytest, in
tests/directory,test_*.pynaming - Frontend: single-file HTML with inline CSS/JS, no build step
Server rules
- All servers bind to
0.0.0.0(neverlocalhost) - Default port:
7860(HF Spaces convention) - Sub-servers use
7861,7862, etc.
Model
- Default:
openbmb/MiniCPM5-1B(text-only, 2.17 GB) - Optional:
openbmb/MiniCPM-V-4.6(vision + text, 2.8 GB) - Loaded in background thread on startup
- Streaming inference via
TextIteratorStreamer
Tool call format
The model calls tools by emitting fenced code blocks with tool as the language:
read_file
path: src/app.py
Multi-line values use YAML block scalars:
write_file
path: src/new.py
content: |
import os
def main():
pass
Slash commands
| Command | Description |
|---|---|
/commit |
Create a git commit with a generated message |
/review |
Review current changes for bugs and quality |
/feature <desc> |
Guided feature development workflow |
/design <brief> |
Generate a distinctive frontend design |
/explain <target> |
Explain how code works |
/test <target> |
Generate tests |
/refactor <target> |
Refactor code for clarity |
/skill <name> |
Load and apply a skill |
/agent create <desc> |
AI generates a custom agent from natural-language description |
/agent use <name> |
Activate a saved agent |
/agent list |
List all saved agents |
/agent show <name> |
Show an agent's full definition |
/agent delete <name> |
Delete a user-defined agent |
/agent reset |
Reset to default SoniCoder persona |
/github <url> [subdir] [--branch <name>] [--into <path>] |
Import a GitHub repo into the workspace |
/help |
Show available commands and skills |
Custom Agents
Custom agents are AI-generated personas layered on top of the base SoniCoder system prompt. They can restrict the tool whitelist, auto-load skills, and override temperature / max-iterations.
Agent file format
Agents live in workspace/.sonicoder/agents/<name>/AGENT.md (built-ins in
code/agents/builtins/<name>/AGENT.md). Format:
---
name: my-agent
description: One-line description
tools: read_file, list_dir, grep, bash
skills: code-review
temperature: 0.2
max_iterations: 12
tags: review, quality
author: AI-generated
created: 2026-06-20
---
# My Agent
Full system-prompt extension here. Define the persona, workflow, output format,
and any hard rules.
How /agent create works
- User runs
/agent create a security reviewer that flags hardcoded secrets. - The slash-command expansion substitutes
AGENT_GENERATION_PROMPT(defined incode/agents/__init__.py) into the prompt. - The base SoniCoder model (NOT a custom agent) authors an
AGENT.mdfile viawrite_fileand saves it under.sonicoder/agents/<name>/. - The user can then
/agent use <name>or click the agent in the UI.
Built-in agents
| Agent | Description |
|---|---|
code-reviewer |
Read-only reviewer, structured issues table output |
test-writer |
Generates pytest/jest tests, runs them, iterates until green |
API endpoints
| Endpoint | Description |
|---|---|
list_agents |
List all agents (builtins + user) and the active one |
get_agent(name) |
Get a single agent's full definition |
save_agent(...) |
Create or overwrite a user agent (manual save) |
delete_agent(name) |
Delete a user agent (built-ins protected) |
set_active_agent(name) |
Set/clear the active agent for subsequent prompts |
import_github(url, branch, subdir, target_subdir, depth, timeout) |
Clone a GitHub repo into the workspace (shallow, heavy dirs stripped) |
github_url_examples() |
Return accepted GitHub URL formats |
push_github(repo_name, github_token, username, branch?, commit_message?, timeout?) |
Snapshot workspace β commit β push to a GitHub repo |
The agent_run endpoint also intercepts /agent use|reset|delete|list and
dispatches them directly to the agents module, bypassing the model entirely
for instant session-state updates.
GitHub Import
SoniCoder can clone any public GitHub repo into the workspace, allowing the agent to read, edit, extend, or refactor real-world code.
How it works
- User submits a GitHub URL via the Agent tab UI box (or via
/github <url>slash command in chat while Agent mode is ON). - The backend (
code/tools/github.py::import_github_repo) parses the URL (supports HTTPS, SSH, and/tree/<branch>/<subdir>forms) and validates that the host isgithub.com. - The repo is shallow-cloned (
git clone --depth 1 --single-branch) into a temp directory. - Files are copied into the workspace (root or
target_subdir) with these directories stripped:.git,.hg,.svn,node_modules,__pycache__,.venv,venv,env,.tox,.mypy_cache,.pytest_cache,.ruff_cache,dist,build,.next,.nuxt,.cache,.gradle,target,Pods..DS_StoreandThumbs.dbare also dropped. - The workspace tree refreshes; Agent mode auto-enables if it wasn't already.
Security
- Only
github.comURLs are accepted (HTTPS or SSH form). target_subdiris sanitized β no path escapes.- The upstream repo is never modified (clone happens in temp dir, then
copied). The
.gitdirectory is stripped so the agent doesn't walk it. - Default clone timeout: 120s (UI uses 180s). Max: 600s.
Slash command
/github <url> [subdir] [--branch <name>] [--into <path>] [--depth <N>] [--timeout <s>]
The slash command (defined in code/commands/builtins/github.md) instructs
the agent to invoke import_github_repo via bash, then list the top-level
files and suggest next steps based on what was imported.
GitHub Push
Push the current workspace back to a GitHub repo as a commit. Only 3 inputs are required: repo name, GitHub token, username.
How it works (code/tools/github.py::push_to_github)
- Snapshot the workspace via
snapshot_workspace()(returns a{relative_path: content}dict). - Create a temp dir,
git init -b <branch>inside it, write the snapshot files in,git add -A+git commit -m <message>. - Build a push URL of the form
https://<username>:<token>@github.com/<owner>/<repo>.gitand rungit push --force-with-lease <url> <branch>. - If
--force-with-leasefails because the remote has no refs yet (brand-new empty repo), retry with a plaingit push. - Delete the temp dir. The token is never logged; error messages scrub it before being returned.
Why --force-with-lease
SoniCoder treats the workspace as the source of truth. --force-with-lease
replaces the remote tip with the workspace snapshot, but fails loudly (rather
than silently clobbering) if someone else pushed commits in the meantime β
because the temp repo has no reflog of the remote tip, the lease fails and
the user is told to pull first.
UI
Located in the Deploy tab, in a "Push Update to GitHub" section below the
HuggingFace section. Only 3 fields are required: repo name, token, username.
An "Advanced" <details> exposes optional branch and commit_message
fields.
Security
- Token is sent over HTTPS to the SoniCoder backend, used once for the push, then dropped (not stored, not logged).
- Error messages are scrubbed to remove the token before being returned.
- The temp repo is deleted at the end of the call (context manager).
- The local SoniCoder workspace is never turned into a git repo; the
workspace's
.git(if any, e.g. after an import β though imports strip.git) is never read.
Skills
| Skill | Description |
|---|---|
frontend-design |
Distinctive visual design guidance |
feature-dev |
Guided feature implementation workflow |
code-review |
High-signal code review |
debugging |
Systematic debugging workflow |
fullstack-scaffold |
Project structure scaffolding rules |
commit-workflow |
Git commit best practices |
Hooks
Hooks are markdown rules that fire on events (bash, file, prompt, stop).
They can warn (show a message) or block (prevent the action).
Built-in hooks:
block-dangerous-rmβ blocksrm -rf /,~,$HOME,..warn-debug-codeβ warns onconsole.log,debugger,print,alertwarn-secrets-in-codeβ warns on hardcoded API_KEY/SECRET/TOKEN/PASSWORDwarn-eval-execβ warns oneval()andexec()
Users can add custom hooks in workspace/.sonicoder/hooks/*.local.md.
Workspace
The agent's sandboxed filesystem lives at ./workspace/ (configurable via
SONICODER_WORKSPACE env var). All file tools refuse paths that escape this root.
Deploy
Generated projects can be pushed to HuggingFace Spaces via the Deploy tab. Supported SDKs:
staticβ HTML/CSS/JSgradioβ Python Gradio appsstreamlitβ Python Streamlit appsdockerβ JS/TS frameworks (auto-generates Dockerfile + package.json)