FJFehr Claude Sonnet 4.6 commited on
Commit
4d8957d
·
1 Parent(s): cee0097

chore: consolidate deps into pyproject.toml and add CLAUDE.md

Browse files

Remove 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>

Files changed (4) hide show
  1. CLAUDE.md +54 -0
  2. README.md +1 -1
  3. pyproject.toml +5 -0
  4. 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 pip install -r requirements.txt
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