Skip to content

Phase 2: MIDI control — synth definitions, tools, and deps#2

Merged
pnilan merged 4 commits intomainfrom
phase-2/midi-control
Mar 7, 2026
Merged

Phase 2: MIDI control — synth definitions, tools, and deps#2
pnilan merged 4 commits intomainfrom
phase-2/midi-control

Conversation

@pnilan
Copy link
Owner

@pnilan pnilan commented Mar 7, 2026

What

Add MIDI output support and synth definition loading so the agent can send CC messages to hardware synths. Introduces PydanticAI dependency injection, five agent tools, Pydantic models for synth definitions, YAML synth configs, and a python-rtmidi MIDI layer. Also adds ruff for linting and formatting with CI enforcement.

How

  • patchwork/synth_definitions.pyCCParameter and SynthDefinition Pydantic models with validation (CC 0-127, channel 1-16, value_range ordering). YAML loader reads synths/*.yaml and *.yml, validates against models, errors on duplicate names. Default path anchored to project root via __file__.
  • patchwork/midi.pyMidiConnection class wrapping python-rtmidi. Handles port listing, open/close, and CC sends with 1-based channel API (converted to 0-based internally). Validates at the MIDI layer so tools don't need to. Closes existing connection before opening a new one to prevent leaks.
  • patchwork/deps.pyPatchworkDeps dataclass holding MidiConnection and synth definitions dict, used as PydanticAI's deps_type.
  • patchwork/tools/midi_control.py — Five agent tools: list_midi_ports, connect_midi, list_synths, send_cc, send_patch. Tools return descriptive strings (not exceptions) so the agent relays errors naturally. Parameter lookups normalize case and spaces→underscores. send_patch is partial-success tolerant.
  • patchwork/agent.py — Updated with deps_type=PatchworkDeps, registered all 5 tools, added tool usage instructions to system prompt, and a dynamic @agent.system_prompt that appends loaded synth CC parameters at runtime.
  • patchwork/cli.py — Initializes MidiConnection, loads synth definitions, creates PatchworkDeps, passes deps= to agent.run_stream(). MIDI cleanup in try/finally.
  • synths/ — Starter YAML definitions for Moog Minitaur (12 params) and Roland TB-03 (7 params).
  • pyproject.toml — Added python-rtmidi, pyyaml, and ruff (dev). Ruff configured with rules: E, W, F, I, UP, B, SIM, RUF at 100 char line length.
  • .github/workflows/test.yml — Renamed to "CI", added parallel lint job running ruff check and ruff format --check.
  • Tests — 34 new tests across 4 files (synth definitions, MIDI layer, tools, YAML validation). All tests mock MIDI — no hardware needed.

Recommended Review Order

  1. patchwork/synth_definitions.py — models and loader
  2. patchwork/midi.py — MIDI layer
  3. patchwork/deps.py — dependency injection type
  4. patchwork/tools/midi_control.py — agent tools
  5. patchwork/agent.py — agent updates
  6. patchwork/cli.py — REPL integration
  7. synths/moog_minitaur.yaml, synths/roland_tb03.yaml — synth configs
  8. pyproject.toml — dependencies and ruff config
  9. .github/workflows/test.yml — CI pipeline
  10. tests/ — test files

pnilan added 2 commits March 7, 2026 13:50
Introduce MIDI output support via python-rtmidi, synth definition loading
from YAML files, PydanticAI dependency injection, and agent tools for
controlling hardware synths over MIDI CC. Includes Minitaur and TB-03
synth definitions, comprehensive test coverage for all new modules.
- Close existing connection before opening a new one in MidiConnection.open()
- Guard against negative port_index with 0 <= port_index < len(ports)
- Anchor default synths_dir to project root via __file__ instead of CWD
- Move MIDI connection check before parameter validation in send_cc
  for consistency with send_patch
- Remove unnecessary f-string prefixes on non-interpolated strings
@pnilan pnilan force-pushed the phase-2/midi-control branch from 13ad660 to 803d7f4 Compare March 7, 2026 21:50
pnilan added 2 commits March 7, 2026 13:52
- Add ruff as dev dependency with rules: E, W, F, I, UP, B, SIM, RUF
- Fix all lint issues (line length, unused imports, unused vars, quoted annotations)
- Run ruff format across codebase
- Add lint job to CI workflow (ruff check + ruff format --check)
- Rename workflow from "Tests" to "CI"
@pnilan pnilan merged commit 4299c24 into main Mar 7, 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