feat(browser): add /live/browser/* handlers for loading presets via OSC#200
Open
keshav55 wants to merge 1 commit intoideoforms:masterfrom
Open
feat(browser): add /live/browser/* handlers for loading presets via OSC#200keshav55 wants to merge 1 commit intoideoforms:masterfrom
keshav55 wants to merge 1 commit intoideoforms:masterfrom
Conversation
Problem
-------
AbletonOSC exposes clip/track/device/scene/song handlers but no way to
LOAD instruments or audio effects onto tracks programmatically. External
clients wanting to drive Live end-to-end have to ask humans to drag
presets from the browser, which is a UX hole for agent-driven setups.
Solution
--------
New BrowserHandler in abletonosc/browser.py that uses Live's
Live.Application.get_application().browser to search the stock browser
tree and load the first matching item onto a specified track.
New OSC endpoints:
/live/browser/list_categories
→ replies (category_names...) for the top-level roots
(sounds, instruments, drums, audio_effects, midi_effects, samples,
plugins, clips, user_library, current_project, packs, max_for_live)
/live/browser/list_children [category, max_items=30]
→ replies (category, child_names...) one level under the root —
useful for discovery before loading.
/live/browser/load_by_query [track_index, query]
→ BFS the user-facing roots in priority order (sounds → instruments
→ drums → samples → packs → user_library). Select track_index,
load_item() the first loadable item whose name contains `query`
(case-insensitive substring). Reply with the loaded item name or ""
if no match.
/live/browser/load_from_category [track_index, category, query]
→ same but restricted to one top-level root. Safer for avoiding
accidental matches across categories.
Search is capped at MAX_ITEMS_SCANNED=2000 and MAX_DEPTH=6 to avoid
walking 100k-item preset libraries on pathological queries.
Reload-ordering fix
-------------------
`manager.py`'s `reload_imports()` re-ordered so the PACKAGE is reloaded
BEFORE individual submodules. Previously, `importlib.reload(abletonosc.browser)`
would fail silently when `browser` wasn't yet an attribute of the cached
`abletonosc` package (as happens on the first reload after adding a new
submodule), short-circuiting the whole reload. Now we reload the package
first (which re-runs __init__.py and picks up any new `from .browser import`
lines), then iterate known submodules tolerantly.
Why it matters
--------------
For external tooling that programmatically builds Live sessions (agent-driven
production, automated test sessions, education tools), this closes the one
remaining "you still need a human to drag presets" gap. Combined with
existing track/clip/device handlers, it's now possible to drive a session
from empty project → loaded instruments → MIDI clips → playing — all via
OSC, zero clicks.
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
Adds a new
BrowserHandlerthat exposes Live's browser API over OSC, so external clients can load instruments and audio effects onto tracks without asking humans to drag presets.Four new endpoints:
/live/browser/list_categories— enumerate top-level browser roots/live/browser/list_children [category, max_items=30]— names of one level under a root/live/browser/load_by_query [track_index, query]— search across user-facing roots, load first loadable match onto track/live/browser/load_from_category [track_index, category, query]— restricted-scope versionSearch is capped (
MAX_ITEMS_SCANNED=2000,MAX_DEPTH=6) so pathological queries don't walk the full library.Why
AbletonOSC already covers clips, tracks, devices, scenes, song. The missing piece for end-to-end programmatic session building (agents, automated test sessions, education tools) was preset loading. Currently external clients have to ask humans to drag instruments from the browser, which is a UX hole for agent-driven workflows.
With these endpoints, a client can now go from empty Live project → tracks with instruments loaded → MIDI clips written → playing — all via OSC.
Extra:
reload_imports()ordering fix inmanager.pyOn
/live/api/reloadafter adding a new submodule (first reload afterbrowser.pyexists), the previous implementation would hitimportlib.reload(abletonosc.browser)beforeabletonosc.browserwas an attribute of the cached package, throwAttributeError, and short-circuit the rest of the reload. The fix: reload the package first (re-runs__init__.py, picks up newfrom .browser import BrowserHandler), then iterate submodules tolerantly (getattr(abletonosc, modname, None); skip if absent).Test notes
/live/browser/list_categoriesreturns all 12 expected roots;/live/browser/load_from_category [track, 'audio_effects', 'compressor']correctly inserts a Compressor onto the target track./live/api/reloadafter adding browser.py in-place).Backwards compatibility
Purely additive — no existing endpoints or reply shapes changed.
Context
This was built while driving Ableton from an AI agent (atris-studio, private). Happy to iterate on naming/shape if you'd prefer a different convention for the browser endpoints.