Phase 2: MIDI control — synth definitions, tools, and deps#2
Merged
Conversation
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
13ad660 to
803d7f4
Compare
- 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"
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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.py—CCParameterandSynthDefinitionPydantic models with validation (CC 0-127, channel 1-16, value_range ordering). YAML loader readssynths/*.yamland*.yml, validates against models, errors on duplicate names. Default path anchored to project root via__file__.patchwork/midi.py—MidiConnectionclass wrappingpython-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.py—PatchworkDepsdataclass holdingMidiConnectionand synth definitions dict, used as PydanticAI'sdeps_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_patchis partial-success tolerant.patchwork/agent.py— Updated withdeps_type=PatchworkDeps, registered all 5 tools, added tool usage instructions to system prompt, and a dynamic@agent.system_promptthat appends loaded synth CC parameters at runtime.patchwork/cli.py— InitializesMidiConnection, loads synth definitions, createsPatchworkDeps, passesdeps=toagent.run_stream(). MIDI cleanup intry/finally.synths/— Starter YAML definitions for Moog Minitaur (12 params) and Roland TB-03 (7 params).pyproject.toml— Addedpython-rtmidi,pyyaml, andruff(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 parallellintjob runningruff checkandruff format --check.Recommended Review Order
patchwork/synth_definitions.py— models and loaderpatchwork/midi.py— MIDI layerpatchwork/deps.py— dependency injection typepatchwork/tools/midi_control.py— agent toolspatchwork/agent.py— agent updatespatchwork/cli.py— REPL integrationsynths/moog_minitaur.yaml,synths/roland_tb03.yaml— synth configspyproject.toml— dependencies and ruff config.github/workflows/test.yml— CI pipelinetests/— test files