Spaces:
Running
Running
chore: consolidate deps into pyproject.toml and add CLAUDE.md
Browse filesRemove requirements.txt and move all dependencies (torch, huggingface_hub,
einops, einx, spaces) into pyproject.toml for uv-managed workflow.
Update README install instructions to use `uv sync`.
Add CLAUDE.md with architecture notes for Claude Code.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- CLAUDE.md +54 -0
- README.md +1 -1
- pyproject.toml +5 -0
- requirements.txt +0 -7
CLAUDE.md
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# CLAUDE.md
|
| 2 |
+
|
| 3 |
+
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
| 4 |
+
|
| 5 |
+
## Commands
|
| 6 |
+
|
| 7 |
+
```bash
|
| 8 |
+
# Install dependencies
|
| 9 |
+
uv sync
|
| 10 |
+
|
| 11 |
+
# Run the app
|
| 12 |
+
uv run python app.py
|
| 13 |
+
```
|
| 14 |
+
|
| 15 |
+
App serves at **http://127.0.0.1:7860**
|
| 16 |
+
|
| 17 |
+
Set `HF_TOKEN` environment variable to authenticate with Hugging Face (required for Godzilla model download).
|
| 18 |
+
|
| 19 |
+
## Architecture
|
| 20 |
+
|
| 21 |
+
**SYNTHIA** is a browser-based MIDI keyboard with AI continuation. Three layers:
|
| 22 |
+
|
| 23 |
+
- **Backend** (`app.py`, `engines.py`, `midi_model.py`, `midi.py`, `config.py`): Python/Gradio
|
| 24 |
+
- **Frontend** (`static/keyboard.js`, `static/styles.css`, `keyboard.html`): Tone.js audio synthesis
|
| 25 |
+
- **Bridge**: Hidden Gradio components (textboxes + buttons with `elem_id`s) act as the API layer between JS and Python
|
| 26 |
+
|
| 27 |
+
### Frontend → Backend Communication Pattern
|
| 28 |
+
|
| 29 |
+
JavaScript communicates with Python by:
|
| 30 |
+
1. Writing a JSON string into a hidden `gr.Textbox` (`elem_id="vk_engine_input"`, etc.)
|
| 31 |
+
2. Programmatically clicking a hidden `gr.Button` (`elem_id="vk_engine_cpu_btn"` or `"vk_engine_gpu_btn"`)
|
| 32 |
+
3. Reading the JSON response from a hidden output `gr.Textbox`
|
| 33 |
+
|
| 34 |
+
This pattern is used for all three bridges: `get_config`, `save_midi`, and `process_engine` (CPU and GPU variants).
|
| 35 |
+
|
| 36 |
+
### Engine System
|
| 37 |
+
|
| 38 |
+
Engines live in `engines.py` and are registered in `EngineRegistry._engines`. Each engine class has a `process(events, options, request, device)` method that takes/returns MIDI event dicts with keys: `type`, `note`, `velocity`, `time`, `channel`.
|
| 39 |
+
|
| 40 |
+
Current engines: `parrot`, `reverse_parrot`, `godzilla_continue`.
|
| 41 |
+
|
| 42 |
+
To add a new engine: create a class in `engines.py`, register it in `EngineRegistry._engines`, and add a tooltip in `keyboard.js` (`populateEngineSelect()`).
|
| 43 |
+
|
| 44 |
+
### GPU vs CPU
|
| 45 |
+
|
| 46 |
+
`process_engine_event_bridge_gpu` is decorated with `@spaces.GPU(duration=120)` for Hugging Face Spaces. The `device` parameter (`"cuda"` or `"cpu"`) is forwarded all the way to the model inference.
|
| 47 |
+
|
| 48 |
+
### Godzilla Model
|
| 49 |
+
|
| 50 |
+
`midi_model.py` handles the Hugging Face transformer model. It's preloaded in a background daemon thread at startup (`start_background_preload()`). `get_model("godzilla")` returns a cached singleton. The model tokenizes MIDI events, runs autoregressive generation, then detokenizes back to events.
|
| 51 |
+
|
| 52 |
+
### Config as Single Source of Truth
|
| 53 |
+
|
| 54 |
+
`config.py` defines `INSTRUMENTS`, `KEYBOARD_KEYS`, and `KEYBOARD_SHORTCUTS`. These are served to the frontend via the `get_config` bridge endpoint — the frontend does not hardcode them.
|
README.md
CHANGED
|
@@ -18,7 +18,7 @@ Play, record, and let AI continue your musical phrases in real-time. 🎹
|
|
| 18 |
|
| 19 |
```bash
|
| 20 |
# Install dependencies
|
| 21 |
-
uv
|
| 22 |
|
| 23 |
# Run the app
|
| 24 |
uv run python app.py
|
|
|
|
| 18 |
|
| 19 |
```bash
|
| 20 |
# Install dependencies
|
| 21 |
+
uv sync
|
| 22 |
|
| 23 |
# Run the app
|
| 24 |
uv run python app.py
|
pyproject.toml
CHANGED
|
@@ -5,6 +5,11 @@ description = "Add your description here"
|
|
| 5 |
readme = "README.md"
|
| 6 |
requires-python = ">=3.10"
|
| 7 |
dependencies = [
|
|
|
|
|
|
|
| 8 |
"gradio==5.49.1",
|
|
|
|
| 9 |
"mido>=1.3.3",
|
|
|
|
|
|
|
| 10 |
]
|
|
|
|
| 5 |
readme = "README.md"
|
| 6 |
requires-python = ">=3.10"
|
| 7 |
dependencies = [
|
| 8 |
+
"einops>=0.6",
|
| 9 |
+
"einx>=0.3.0",
|
| 10 |
"gradio==5.49.1",
|
| 11 |
+
"huggingface-hub>=1.4.1",
|
| 12 |
"mido>=1.3.3",
|
| 13 |
+
"spaces>=0.47.0",
|
| 14 |
+
"torch>=2.10.0",
|
| 15 |
]
|
requirements.txt
DELETED
|
@@ -1,7 +0,0 @@
|
|
| 1 |
-
gradio
|
| 2 |
-
mido
|
| 3 |
-
torch
|
| 4 |
-
huggingface_hub
|
| 5 |
-
einops>=0.6
|
| 6 |
-
einx
|
| 7 |
-
spaces
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|