Skip to content

Phase 3: Patch library — SQLite storage, tools, and tests#6

Merged
pnilan merged 4 commits intomainfrom
phase-3/patch-library
Mar 9, 2026
Merged

Phase 3: Patch library — SQLite storage, tools, and tests#6
pnilan merged 4 commits intomainfrom
phase-3/patch-library

Conversation

@pnilan
Copy link
Owner

@pnilan pnilan commented Mar 9, 2026

What

Adds a SQLite-backed patch library so users can save, list, load, recall, and delete named patches. A "recall" sends all saved CC values back to the hardware synth, restoring the sound. This completes the core save/recall workflow described in the master plan.

How

  • patchwork/patch_library.py: New PatchLibrary class wrapping SQLite with Patch dataclass. Supports upsert semantics (same-synth re-save overwrites, cross-synth overwrite rejected), case-insensitive synth filtering, JSON settings roundtrip, context manager protocol, and WAL journal mode. Schema matches the master plan.
  • patchwork/tools/patches.py: Five agent tools (save_patch, load_patch, recall_patch, list_patches, delete_patch) following the same patterns as the MIDI control tools — RunContext[PatchworkDeps], string returns, descriptive error messages. save_patch normalizes parameter keys to canonical form before storage and validates CC values against value_range (parity with send_cc/send_patch). recall_patch composes the DB and MIDI layers to restore patches to hardware, skipping out-of-range values with warnings.
  • patchwork/deps.py: Added patches: PatchLibrary field to PatchworkDeps.
  • patchwork/agent.py: Registered all 5 patch tools and updated system prompt with tool descriptions and usage instructions.
  • patchwork/cli.py: Uses PatchLibrary context manager for safe cleanup, fixed except syntax bug.
  • data/.gitkeep + .gitignore update: Tracks data/ directory but ignores *.db files.

Follow-up Issues

Recommended Review Order

  1. patchwork/patch_library.py — core data layer
  2. patchwork/tools/patches.py — agent tool layer, validation, cross-synth guard
  3. patchwork/deps.py — small change, new field
  4. patchwork/agent.py — tool registration and prompt updates
  5. patchwork/cli.py — context manager wiring, except syntax fix
  6. tests/test_patch_library.py — 14 data layer tests
  7. tests/test_patch_tools.py — 24 tool layer tests
  8. tests/test_midi_control_tools.py — minimal update for new deps field

Add PatchLibrary with SQLite storage for saving, loading, recalling,
listing, and deleting named synth patches. Recall sends all saved CC
values back to hardware to restore a sound.

New files:
- patchwork/patch_library.py: PatchLibrary class, Patch dataclass
- patchwork/tools/patches.py: save/load/recall/list/delete patch tools
- tests/test_patch_library.py: 13 tests for database operations
- tests/test_patch_tools.py: 18 tests for tool functions
- data/.gitkeep: track data directory for runtime DB

Modified:
- patchwork/deps.py: add patches field to PatchworkDeps
- patchwork/agent.py: register patch tools, update system prompt
- patchwork/cli.py: initialize and close PatchLibrary
- tests/test_midi_control_tools.py: update helper for new deps field
- .gitignore: ignore data/*.db instead of entire data/
pnilan added 3 commits March 8, 2026 20:48
- save_patch: validate CC values against value_range before saving
- save_patch: reject cross-synth overwrites (same name, different synth)
- recall_patch: skip out-of-range values with warning (matches send_patch)
- recall_patch: fix MIDI-not-connected message to match midi_control.py
- load_patch: show updated_at instead of created_at
- cli.py: use PatchLibrary context manager, fix except syntax
- Add tests: value-range validation, cross-synth rejection, empty settings,
  same-synth overwrite, recall out-of-range skip, operations after close
@pnilan pnilan merged commit 9a61206 into main Mar 9, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant