livepilot 1.16.1 → 1.17.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +311 -0
- package/README.md +16 -15
- package/installer/codex.js +14 -0
- package/m4l_device/LivePilot_Analyzer.amxd +0 -0
- package/m4l_device/livepilot_bridge.js +1 -1
- package/mcp_server/__init__.py +1 -1
- package/mcp_server/atlas/__init__.py +85 -0
- package/mcp_server/atlas/device_atlas.json +3183 -382
- package/mcp_server/atlas/device_techniques_index.json +1510 -0
- package/mcp_server/atlas/enrichments/__init__.py +1 -0
- package/mcp_server/atlas/enrichments/audio_effects/amp.yaml +112 -0
- package/mcp_server/atlas/enrichments/audio_effects/audio_effect_rack.yaml +77 -0
- package/mcp_server/atlas/enrichments/audio_effects/cabinet.yaml +81 -0
- package/mcp_server/atlas/enrichments/audio_effects/corpus.yaml +128 -0
- package/mcp_server/atlas/enrichments/audio_effects/envelope_follower.yaml +99 -0
- package/mcp_server/atlas/enrichments/audio_effects/external_audio_effect.yaml +64 -0
- package/mcp_server/atlas/enrichments/audio_effects/looper.yaml +85 -0
- package/mcp_server/atlas/enrichments/audio_effects/resonators.yaml +121 -0
- package/mcp_server/atlas/enrichments/audio_effects/snipper.yaml +17 -0
- package/mcp_server/atlas/enrichments/audio_effects/spectrum.yaml +61 -0
- package/mcp_server/atlas/enrichments/audio_effects/tuner.yaml +43 -0
- package/mcp_server/atlas/enrichments/audio_effects/utility.yaml +118 -0
- package/mcp_server/atlas/enrichments/audio_effects/vocoder.yaml +94 -0
- package/mcp_server/atlas/enrichments/instruments/analog.yaml +11 -0
- package/mcp_server/atlas/enrichments/instruments/bass.yaml +11 -0
- package/mcp_server/atlas/enrichments/instruments/bell_tower.yaml +38 -0
- package/mcp_server/atlas/enrichments/instruments/collision.yaml +11 -0
- package/mcp_server/atlas/enrichments/instruments/drift.yaml +11 -0
- package/mcp_server/atlas/enrichments/instruments/drum_rack.yaml +142 -0
- package/mcp_server/atlas/enrichments/instruments/electric.yaml +11 -0
- package/mcp_server/atlas/enrichments/instruments/emit.yaml +11 -0
- package/mcp_server/atlas/enrichments/instruments/meld.yaml +11 -0
- package/mcp_server/atlas/enrichments/instruments/operator.yaml +11 -0
- package/mcp_server/atlas/enrichments/instruments/poli.yaml +11 -0
- package/mcp_server/atlas/enrichments/instruments/sampler.yaml +12 -0
- package/mcp_server/atlas/enrichments/instruments/simpler.yaml +15 -0
- package/mcp_server/atlas/enrichments/instruments/tension.yaml +11 -0
- package/mcp_server/atlas/enrichments/instruments/vector_fm.yaml +11 -0
- package/mcp_server/atlas/enrichments/instruments/vector_grain.yaml +11 -0
- package/mcp_server/atlas/enrichments/instruments/wavetable.yaml +11 -0
- package/mcp_server/atlas/enrichments/midi_effects/filler.yaml +17 -0
- package/mcp_server/atlas/enrichments/utility/performer.yaml +15 -0
- package/mcp_server/atlas/enrichments/utility/vector_map.yaml +21 -0
- package/mcp_server/atlas/tools.py +291 -0
- package/mcp_server/m4l_bridge.py +19 -2
- package/mcp_server/sample_engine/tools.py +201 -128
- package/mcp_server/splice_client/http_bridge.py +319 -116
- package/mcp_server/tools/automation.py +168 -0
- package/package.json +2 -2
- package/remote_script/LivePilot/__init__.py +1 -1
- package/remote_script/LivePilot/arrangement.py +216 -1
- package/server.json +3 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,316 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 1.17.1 — Splice auto-reconnect + Codex installer fix (April 23 2026)
|
|
4
|
+
|
|
5
|
+
Two bug fixes discovered in a parallel worktree hours after v1.17.0
|
|
6
|
+
shipped. Non-breaking, test-locked, ships as a patch.
|
|
7
|
+
|
|
8
|
+
### Fixed
|
|
9
|
+
|
|
10
|
+
- **Splice client auto-reconnect** (`mcp_server/sample_engine/tools.py`):
|
|
11
|
+
Every Splice MCP tool now reconnects the shared gRPC client on demand
|
|
12
|
+
via a new `_ensure_splice_client_connected()` helper. Before this fix,
|
|
13
|
+
if the Splice desktop app launched AFTER the MCP server (common when
|
|
14
|
+
users start the MCP via Claude Code before booting Splice), every
|
|
15
|
+
Splice tool stayed stuck in a disconnected state until the WHOLE MCP
|
|
16
|
+
server was restarted. The fix re-checks on every tool invocation, so
|
|
17
|
+
the first successful Splice-desktop boot auto-recovers the client
|
|
18
|
+
transparently. Tools affected: `get_splice_credits`,
|
|
19
|
+
`splice_catalog_hunt`, `search_samples` (when routing through Splice),
|
|
20
|
+
plus every other Splice tool that reads from the shared context.
|
|
21
|
+
3 new regression tests in `tests/test_splice_reconnect_tools.py` lock
|
|
22
|
+
the reconnect behavior.
|
|
23
|
+
- **Codex plugin installer writes `.mcp.json`** (`installer/codex.js`):
|
|
24
|
+
The installer was copying plugin files into the Codex plugins
|
|
25
|
+
directory but omitting the `.mcp.json` config that tells Codex how
|
|
26
|
+
to launch the MCP server. Codex users had to manually create the
|
|
27
|
+
file or run the command with additional flags. Now
|
|
28
|
+
`writeLocalMcpConfig(destDir)` writes the correct
|
|
29
|
+
`{mcpServers: {livepilot: {command, args}}}` shape during install.
|
|
30
|
+
1 new regression test in `tests/test_codex_plugin_installer.py`
|
|
31
|
+
asserts the file content.
|
|
32
|
+
|
|
33
|
+
### Verified
|
|
34
|
+
|
|
35
|
+
155/155 tests green. `sync_metadata.py --check`: all metadata in sync
|
|
36
|
+
at version=1.17.1, tools=426, domains=52, bridge_cmds=30, enriched=120.
|
|
37
|
+
|
|
38
|
+
### Distribution
|
|
39
|
+
|
|
40
|
+
Same channels as v1.17.0 — GitHub release + npm + `.mcpb` + plugin
|
|
41
|
+
cache. Tool count and domain count unchanged; this is purely a
|
|
42
|
+
reliability patch.
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
## 1.17.0 — 2026-04-22 handoff close-out (April 22 2026, late)
|
|
46
|
+
|
|
47
|
+
Closes every item in the 2026-04-22 handoff document: Splice's
|
|
48
|
+
Describe-a-Sound + Variations go LIVE via captured GraphQL
|
|
49
|
+
endpoints, the M4L Analyzer gains a 9th spectrum band (sub_low
|
|
50
|
+
20-60 Hz), track-level arrangement automation lands via a
|
|
51
|
+
two-phase session-record workaround, the atlas gains a
|
|
52
|
+
by_pack index + `atlas_pack_info` MCP tool, the device atlas
|
|
53
|
+
adds 13 enrichments including a Drum Rack container entry, and
|
|
54
|
+
Tier C of the pack-knowledge reference expands from 7 clusters
|
|
55
|
+
to 14 individually-documented packs.
|
|
56
|
+
|
|
57
|
+
**Tool count**: 422 → 426 (+5 new, −1 retired):
|
|
58
|
+
- `+` `atlas_pack_info` — inspect a pack's device list + enrichment coverage
|
|
59
|
+
- `+` `atlas_describe_chain` — free-text describe-a-chain, mirror of
|
|
60
|
+
`splice_describe_sound` for the device library. "A granular pad like
|
|
61
|
+
Tim Hecker" → device chain proposal via artist + genre vocabulary
|
|
62
|
+
matching
|
|
63
|
+
- `+` `atlas_techniques_for_device` — reverse-lookup: what techniques
|
|
64
|
+
reference this device? Reads an auto-generated index of 146 technique
|
|
65
|
+
cross-references across 58 devices
|
|
66
|
+
- `+` `set_arrangement_automation_via_session_record` — T5 workaround,
|
|
67
|
+
two-phase protocol with tempo-scaled sleep
|
|
68
|
+
- `+` `splice_http_diagnose` — per-endpoint verified-status reporter
|
|
69
|
+
- `−` `splice_search_with_sound` — retired (user handles
|
|
70
|
+
audio-reference search directly in Splice's UI; capture recipe
|
|
71
|
+
preserved at `docs/2026-04-22-splice-https-capture-recipe.md`)
|
|
72
|
+
|
|
73
|
+
**Domain count**: unchanged at 52.
|
|
74
|
+
**Enrichment YAMLs**: 107 → 120 (+13).
|
|
75
|
+
**Atlas pack coverage**: 0 → 641 devices indexed (614 Core Library
|
|
76
|
+
via auto-heuristic + 27 explicit-pack YAML declarations).
|
|
77
|
+
**Signature-technique coverage**: 32 → 47 enrichment files have the
|
|
78
|
+
`signature_techniques` field (+15 files × 3 techniques each = +45
|
|
79
|
+
technique entries from native-synth backfill). Coverage rose from
|
|
80
|
+
27% → 39% of enrichments.
|
|
81
|
+
**Tests**: 2644 → 2696+ (+52 new regression guards).
|
|
82
|
+
|
|
83
|
+
### Live-verified end-to-end
|
|
84
|
+
|
|
85
|
+
Against a running Ableton 12.4 + Splice desktop 5.4.9 session on
|
|
86
|
+
2026-04-22:
|
|
87
|
+
|
|
88
|
+
- `get_master_spectrum()` → 9 keys with `sub_low` first, real-audio
|
|
89
|
+
energy distribution (`sub_low=0.0003 sub=0.0008 low=0.0064 …`)
|
|
90
|
+
- `atlas_pack_info("Drone Lab")` → Harmonic Drone Generator in
|
|
91
|
+
both Sounds and M4L variants with URIs
|
|
92
|
+
- `splice_describe_sound("warm dub techno chord stab", limit=5)` →
|
|
93
|
+
5 real samples out of 4100 total hits (Dub Techno 2 pluck, NEONIC
|
|
94
|
+
atmos, Visions chord, Organic Elements 2, Underground Techno),
|
|
95
|
+
with Splice's ML rephrasing `rephrased_query_string: "dub techno,
|
|
96
|
+
chords, stabs, warm"`
|
|
97
|
+
|
|
98
|
+
### Splice HTTPS bridge — endpoint capture
|
|
99
|
+
|
|
100
|
+
Captured via mitmproxy against Splice desktop v5.4.9 (unpinned TLS,
|
|
101
|
+
intercepts cleanly once CA is trusted). Two GraphQL operations
|
|
102
|
+
wired:
|
|
103
|
+
|
|
104
|
+
- **`SamplesSearch`** at `surfaces-graphql.splice.com/graphql` —
|
|
105
|
+
describe + keyword search in one operation, flagged via
|
|
106
|
+
`semantic=1` + `rephrase=true`. 5938-char query embedded as
|
|
107
|
+
`mcp_server/splice_client/graphql_queries/samples_search.graphql`
|
|
108
|
+
- **`AssetSimilarSoundsQuery`** at the same endpoint — Splice's
|
|
109
|
+
"Variations" / "Similar Sounds" feature. Input is a sample
|
|
110
|
+
`uuid` + `isLegacy` bool; returns up to 10 recommendations.
|
|
111
|
+
886-char query embedded as
|
|
112
|
+
`mcp_server/splice_client/graphql_queries/asset_similar_sounds.graphql`
|
|
113
|
+
- Auth: `Authorization: Bearer <JWT>` via local gRPC `GetSession`
|
|
114
|
+
RPC — no stored credentials, token rotates with the running
|
|
115
|
+
Splice desktop app
|
|
116
|
+
- User-Agent: LivePilot default (override via env var if
|
|
117
|
+
Cloudflare blocks — mimic pattern: `Splice Baelish/darwin/
|
|
118
|
+
arm64/arm64 5.4.9/<hash>/stable`)
|
|
119
|
+
- Response normalizer `_flatten_sample_item()` is shared between
|
|
120
|
+
both operations so samples from describe + variations flatten
|
|
121
|
+
to identical dicts — 14 new unit tests lock this invariant
|
|
122
|
+
- Per-endpoint `describe_verified` / `variation_verified` flags
|
|
123
|
+
replace the coarse `is_user_configured` gate
|
|
124
|
+
|
|
125
|
+
### Changed
|
|
126
|
+
|
|
127
|
+
- `splice_generate_variation` signature changed: `(file_hash,
|
|
128
|
+
target_key, target_bpm, count)` → `(uuid, is_legacy)`. The
|
|
129
|
+
operation is a recommender lookup, not AI audio synthesis, so
|
|
130
|
+
target-key / target-bpm / count aren't API-supported. The
|
|
131
|
+
underlying GraphQL returns up to 10 similar samples with the
|
|
132
|
+
same flat shape as `splice_describe_sound` results.
|
|
133
|
+
- `splice_describe_sound` — status flipped from "scaffolded" to
|
|
134
|
+
"LIVE". Adds new `rephrase: bool = True` parameter surfacing
|
|
135
|
+
Splice's `rephrased_query_string` in the response.
|
|
136
|
+
|
|
137
|
+
### Added
|
|
138
|
+
|
|
139
|
+
**Sub_low spectrum band** (T3 from handoff):
|
|
140
|
+
- M4L Analyzer `fffb~` filter bank: 8 bands → 9 bands. New band
|
|
141
|
+
center frequencies: `35 85 175 350 700 1400 2800 5600 12000`
|
|
142
|
+
(Hz), with `sub_low` (20-60 Hz) prepended to separate kick
|
|
143
|
+
fundamental from DC rumble
|
|
144
|
+
- `mcp_server/m4l_bridge.py`: `BAND_NAMES_8` + `BAND_NAMES_9`
|
|
145
|
+
auto-selected based on payload length — older frozen .amxd
|
|
146
|
+
builds (pre-v1.17) still work without re-freeze
|
|
147
|
+
- `LivePilot_Analyzer.amxd` re-frozen from modified
|
|
148
|
+
`LivePilot_Analyzer.maxpat` source, 6751650 bytes, synced to
|
|
149
|
+
repo / Max 9 Library cache / Ableton User Library
|
|
150
|
+
- `docs/2026-04-22-sub-low-band-max-workflow.md` — runbook for
|
|
151
|
+
future band-count changes (Max editor walkthrough)
|
|
152
|
+
|
|
153
|
+
**Track-level arrangement automation workaround** (T5 from handoff):
|
|
154
|
+
- New MCP tool `set_arrangement_automation_via_session_record` —
|
|
155
|
+
async two-phase protocol that creates a session clip with the
|
|
156
|
+
automation, arms the track, records into arrangement at a
|
|
157
|
+
target beat, cleans up
|
|
158
|
+
- Two new remote-script handlers:
|
|
159
|
+
`arrangement_automation_via_session_record_start` returns the
|
|
160
|
+
live `song.tempo` so the MCP layer can compute the sleep
|
|
161
|
+
duration, `_complete` stops record + locates the new
|
|
162
|
+
arrangement clip
|
|
163
|
+
- MCP layer sleeps `duration_beats × 60/tempo + 0.5s` with a
|
|
164
|
+
600s ceiling and graceful exception handling — incomplete
|
|
165
|
+
sleep still tries to complete so tracks don't stay armed
|
|
166
|
+
- 17 new contract tests (two-phase ordering, tempo scaling,
|
|
167
|
+
ceiling, default-tempo fallback, start-failure short-circuit)
|
|
168
|
+
|
|
169
|
+
**Atlas `by_pack` index + `atlas_pack_info` tool** (T4):
|
|
170
|
+
- New `_by_pack` index on `AtlasManager`, populated from
|
|
171
|
+
enrichment YAML `pack:` fields plus a Core Library
|
|
172
|
+
auto-heuristic for native instruments/effects without an
|
|
173
|
+
explicit pack declaration
|
|
174
|
+
- New `pack_info(name)` and `list_packs()` methods
|
|
175
|
+
- New MCP tool `atlas_pack_info(pack_name)` — `""` returns the
|
|
176
|
+
full pack list with device counts, otherwise returns
|
|
177
|
+
`{pack, device_count, enriched_count, devices[...]}` for one
|
|
178
|
+
pack. Case-insensitive name lookup
|
|
179
|
+
- `genre_affinity` (enriched field) now feeds the `_by_genre`
|
|
180
|
+
index alongside the raw `genres` field, so
|
|
181
|
+
`microhouse`/`deep_minimal`/`dub_techno` tags added to YAMLs
|
|
182
|
+
post-v1.11 finally surface in genre lookups
|
|
183
|
+
|
|
184
|
+
**Drum Rack atlas enrichment + 12 audio-effects YAMLs** (T1/T2):
|
|
185
|
+
- New `instruments/drum_rack.yaml` — treats Drum Rack as a
|
|
186
|
+
meta-type container with per-pad key_parameters, 3 starter
|
|
187
|
+
recipes, 8 gotchas (including MIDI pitch conventions, chain
|
|
188
|
+
volume vs pad volume)
|
|
189
|
+
- 12 new audio-effects enrichments: `utility`, `corpus`,
|
|
190
|
+
`vocoder`, `tuner`, `spectrum`, `amp`, `cabinet`, `resonators`,
|
|
191
|
+
`looper`, `envelope_follower`, `audio_effect_rack`,
|
|
192
|
+
`external_audio_effect`. Takes `audio_effects/` count from 40
|
|
193
|
+
→ 52
|
|
194
|
+
- Simpler + Sampler enrichments gain 3 new gotchas (Snap=OFF
|
|
195
|
+
silence bug, -12 dB default, slice base pitch = 36+N)
|
|
196
|
+
- `pack` field added to `_ENRICHMENT_FIELDS` allowlist — was
|
|
197
|
+
silently dropped from atlas JSON before; now drives the
|
|
198
|
+
`by_pack` index
|
|
199
|
+
|
|
200
|
+
**Pack-knowledge reference** (T7):
|
|
201
|
+
- `livepilot/skills/livepilot-core/references/pack-knowledge.md`
|
|
202
|
+
Tier C expanded from 7 merged clusters (~62 lines) to 14
|
|
203
|
+
individually-documented packs (Build and Drop, Drive and Glow,
|
|
204
|
+
Punch and Tilt, Skitter and Step, Trap Drums, Beat Tools, Drum
|
|
205
|
+
Essentials, SONiVOX Orchestral Brass/Strings/Woodwinds, Grand
|
|
206
|
+
Piano, Synth Essentials, Session Drums Club + Studio, Core
|
|
207
|
+
Library) with consistent Essence/Scores/Top/Use/Avoid structure
|
|
208
|
+
|
|
209
|
+
**Deepened shallow enrichments** (T8):
|
|
210
|
+
- Added `pairs_well_with` + expanded `gotchas` +
|
|
211
|
+
`signature_techniques` for: `snipper`, `bell_tower`,
|
|
212
|
+
`performer`, `vector_map`, `filler`
|
|
213
|
+
|
|
214
|
+
### Concept surface — knowledge the LLM can reason over
|
|
215
|
+
|
|
216
|
+
Late-v1.17 audit found LivePilot's concept-vs-recipe ratio was already
|
|
217
|
+
healthy (sample-philosophy.md, sound-design-deep.md, per-device
|
|
218
|
+
`signature_techniques`, aesthetic-tagged `character_tags`), but two gaps
|
|
219
|
+
were worth closing before the release: native-synth enrichments heavy
|
|
220
|
+
on `starter_recipes` but thin on `signature_techniques`, and no
|
|
221
|
+
structured artist/genre → device-vocabulary bridge.
|
|
222
|
+
|
|
223
|
+
Added:
|
|
224
|
+
|
|
225
|
+
- **`livepilot/skills/livepilot-core/references/artist-vocabularies.md`** —
|
|
226
|
+
~25 producers (Villalobos, Hawtin/Plastikman, Basic Channel, Gas,
|
|
227
|
+
Basinski, Stars of the Lid, Hecker, Aphex, Autechre, OPN, Arca,
|
|
228
|
+
Dilla, Premier, Madlib, Burial, Mala, Jeff Mills, Moodymann, Daft
|
|
229
|
+
Punk, Rashad, Photek, Com Truise, Boards of Canada, etc.) with
|
|
230
|
+
four-field structured entries (sonic fingerprint / reach for /
|
|
231
|
+
avoid / key techniques). Each entry cross-references
|
|
232
|
+
`signature_techniques` in per-device YAML or technique names in
|
|
233
|
+
`sample-techniques.md` / `sound-design-deep.md` — no duplication,
|
|
234
|
+
just a translation layer from producer names to LivePilot devices
|
|
235
|
+
- **`livepilot/skills/livepilot-core/references/genre-vocabularies.md`** —
|
|
236
|
+
15 genres (microhouse, dub_techno, deep_minimal, minimal_techno,
|
|
237
|
+
ambient, idm, modern_classical, hip_hop, trap, dubstep, house,
|
|
238
|
+
dnb, garage, experimental, synthwave) with tempo / kick / bass /
|
|
239
|
+
percussion / harmonic / texture / reach-for / avoid structure.
|
|
240
|
+
Read-before-tool-selection reference for genre-driven workflows
|
|
241
|
+
- **Native-synth `signature_techniques` backfill** — 15 YAMLs that
|
|
242
|
+
had starter_recipes but no aesthetic-level guidance now have 3
|
|
243
|
+
techniques each, tagged to known producers (Hawtin subtractive pad,
|
|
244
|
+
303 acid bass, Reese bass for DnB, J Dilla micro-timed kit, Villalobos
|
|
245
|
+
sub-bass layer, Basinski tape degradation, Tim Hecker grain cloud,
|
|
246
|
+
etc.). Files updated: analog, operator, wavetable, drift, collision,
|
|
247
|
+
tension, electric, simpler, sampler, bass, poli, emit, meld,
|
|
248
|
+
vector_fm, vector_grain
|
|
249
|
+
- **`mcp_server/atlas/device_techniques_index.json`** — auto-generated
|
|
250
|
+
reverse-index of 146 device→technique cross-references across 58
|
|
251
|
+
devices, mined from per-device `signature_techniques` +
|
|
252
|
+
`sample-techniques.md` + `sound-design-deep.md`
|
|
253
|
+
|
|
254
|
+
### Docs
|
|
255
|
+
|
|
256
|
+
- `docs/2026-04-22-release-verification.md` — end-to-end
|
|
257
|
+
verification report with live-verified evidence per task
|
|
258
|
+
- `docs/2026-04-22-splice-https-capture-recipe.md` — mitmproxy
|
|
259
|
+
runbook for capturing additional Splice GraphQL operations
|
|
260
|
+
- `docs/2026-04-22-live-api-probe-arrangement-automation.md` —
|
|
261
|
+
design rationale for the T5 two-phase split
|
|
262
|
+
- `docs/2026-04-22-sub-low-band-max-workflow.md` — Max
|
|
263
|
+
editor runbook for future filter-bank edits
|
|
264
|
+
- `docs/manual/index.md` — rewrote domain map from source-of-truth
|
|
265
|
+
per-domain counts (was drifting 30+ entries). Added 7 missing
|
|
266
|
+
domains (scales, grooves, take_lanes, follow_actions, miditool,
|
|
267
|
+
diagnostics, synthesis_brain)
|
|
268
|
+
- `docs/manual/tool-reference.md` — new sections for Device Atlas,
|
|
269
|
+
Sample Engine & Splice, Diagnostics; added v1.17 tools
|
|
270
|
+
(`atlas_pack_info`, `set_arrangement_automation_via_session_record`,
|
|
271
|
+
`splice_http_diagnose`, `splice_describe_sound` LIVE,
|
|
272
|
+
`splice_generate_variation` LIVE); added `add_drum_rack_pad` +
|
|
273
|
+
`verify_device_alive` + `verify_all_devices_health` that were
|
|
274
|
+
missing since v1.16
|
|
275
|
+
- `docs/manual/tool-catalog.md` — replaced hand-curated drifting
|
|
276
|
+
version with single auto-generated file (run
|
|
277
|
+
`python3 scripts/generate_tool_catalog.py > docs/manual/tool-catalog.md`).
|
|
278
|
+
Retired `docs/manual/tool-catalog-generated.md` (duplicate
|
|
279
|
+
with -generated suffix)
|
|
280
|
+
- **Deleted**: `docs/TOOL_REFERENCE.md` (v1.7-era, 317 tools /
|
|
281
|
+
43 domains — misleadingly stale)
|
|
282
|
+
- **Archived**: `docs/manual/release-smoke-board.md` → `docs/archive/release-smoke-board-v1.10-era.md`
|
|
283
|
+
|
|
284
|
+
### Internal
|
|
285
|
+
|
|
286
|
+
- `mcp_server/splice_client/graphql_queries/` — new directory,
|
|
287
|
+
holds captured `.graphql` query strings, loaded lazily via
|
|
288
|
+
`_load_graphql_query()` with caching
|
|
289
|
+
- `docs/research/splice-api-capture/` — gitignored local archive
|
|
290
|
+
of 4 operation captures (request + response pairs):
|
|
291
|
+
`SamplesSearch`, `SoundsSearchAutocomplete`,
|
|
292
|
+
`RefreshSamplePreview`, `AssetSimilarSoundsQuery`
|
|
293
|
+
- 5 additional GraphQL operations captured but not wired —
|
|
294
|
+
candidates for future tools: `DesktopPackSearch`,
|
|
295
|
+
`SampleAssetSidebarQuery`, `BrowseCarousels`,
|
|
296
|
+
`CreditsStoreQuery`, `UserService`
|
|
297
|
+
|
|
298
|
+
### Known non-blockers
|
|
299
|
+
|
|
300
|
+
- Splice Search-with-Sound (audio-file reference search) is
|
|
301
|
+
retired — feature not exposed in Splice desktop v5.4.9's UI,
|
|
302
|
+
user handles it manually. Recipe preserved if a future Splice
|
|
303
|
+
build re-exposes it.
|
|
304
|
+
- T5 live end-to-end verification in a real Ableton session
|
|
305
|
+
deferred — contract tests (17) lock the protocol; first real
|
|
306
|
+
invocation will confirm Live LOM assumptions (classic
|
|
307
|
+
v1.16.0 → v1.16.1 pattern — any surprises fix in one edit).
|
|
308
|
+
- `splice_http_diagnose` token-availability probe reported a
|
|
309
|
+
false negative pre-1.17 (walked the wrong context path); fixed
|
|
310
|
+
to use `ctx.lifespan_context["splice_client"]` + actually call
|
|
311
|
+
`fetch_session_token`.
|
|
312
|
+
|
|
313
|
+
|
|
3
314
|
## 1.16.1 — Post-publish live-verification bug sweep (April 22 2026)
|
|
4
315
|
|
|
5
316
|
Three rounds of live verification after 1.16.0 shipped caught five
|
package/README.md
CHANGED
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
|
|
18
18
|
<p align="center">
|
|
19
19
|
An agentic production system for Ableton Live 12.<br>
|
|
20
|
-
|
|
20
|
+
426 tools. 52 domains. Device atlas. Plan-aware Splice integration. Auto-composition. Spectral perception. Technique memory. Drum-rack pad builder. Live dead-device detection.
|
|
21
21
|
</p>
|
|
22
22
|
|
|
23
23
|
<br>
|
|
@@ -33,16 +33,17 @@
|
|
|
33
33
|
|
|
34
34
|
## What LivePilot Does
|
|
35
35
|
|
|
36
|
-
Most MCP servers are tool collections — they execute commands. LivePilot is an **agentic production system**. It has
|
|
36
|
+
Most MCP servers are tool collections — they execute commands. LivePilot is an **agentic production system**. It has seven layers that work together:
|
|
37
37
|
|
|
38
38
|
| Layer | What it provides |
|
|
39
39
|
|-------|-----------------|
|
|
40
40
|
| **Deterministic Tools** | Direct control: transport, tracks, clips, notes, devices, scenes, mixing, arrangement, browser, automation |
|
|
41
|
-
| **Device Atlas** | Knowledge of every device in Ableton's library — 1305 devices indexed by name, URI, category, tag, and
|
|
42
|
-
| **
|
|
43
|
-
| **
|
|
41
|
+
| **Device Atlas** | Knowledge of every device in Ableton's library — 1305 devices indexed by name, URI, category, tag, genre, and pack (641 pack-indexed). 120 enriched with sonic intelligence (47 with aesthetic-tagged `signature_techniques`). 683 drum kits mapped. **Free-text `atlas_describe_chain`** ("a granular pad like Tim Hecker") and **reverse-lookup `atlas_techniques_for_device`** (what techniques reference this device?) added in v1.17 |
|
|
42
|
+
| **Concept Surface** | **New in v1.17.** Two reference files let the LLM's training translate into LivePilot: `artist-vocabularies.md` maps ~25 producers (Villalobos, Hawtin, Basic Channel, Gas, Basinski, Hecker, Aphex, Autechre, Dilla, Burial, Henke, Daft Punk, …) to `reach_for` / `avoid` / `key_techniques`; `genre-vocabularies.md` maps 15 genres to tempo / kick / bass / percussion / harmonic / texture / devices. 146 cross-references between devices and techniques. The LLM reads "sound like Gas" and gets a concrete device chain, not guesswork |
|
|
43
|
+
| **Sample Engine** | Three-source sample intelligence — Ableton's browser, your filesystem, and Splice's catalog (plan-aware: Ableton Live plan uses daily quota, Sounds+/Creator uses credits, free samples bypass both). 6 fitness critics. 29 processing techniques. Collections, presets, preview-URL audition, **LIVE Describe-a-Sound + Variations via Splice GraphQL (v1.17)** |
|
|
44
|
+
| **Spectral Perception** | Real-time ears via M4L — **9-band FFT (v1.17+, sub_low split at 20-60 Hz)**, RMS/peak metering, Krumhansl-Schmuckler key detection, pitch tracking, FluCoMa mel/chroma/onset. Closes the feedback loop so the AI hears its own changes |
|
|
44
45
|
| **Technique Memory** | Persistent library of production decisions. Save a beat pattern, device chain, or mix template. Recall by mood, genre, or texture across sessions |
|
|
45
|
-
| **Creative Intelligence** |
|
|
46
|
+
| **Creative Intelligence** | A dozen engines that understand song identity, learn your taste, diagnose stuck sessions, generate creative options, and evaluate results before claiming success |
|
|
46
47
|
|
|
47
48
|
<br>
|
|
48
49
|
|
|
@@ -56,9 +57,9 @@ Most MCP servers are tool collections — they execute commands. LivePilot is an
|
|
|
56
57
|
│ KNOWLEDGE PERCEPTION MEMORY │
|
|
57
58
|
│ ────────────── ────────────── ────────────── │
|
|
58
59
|
│ │
|
|
59
|
-
│ Device Atlas
|
|
60
|
+
│ Device Atlas 9-band FFT recall by mood, │
|
|
60
61
|
│ 1305 devices RMS / peak genre, texture │
|
|
61
|
-
│
|
|
62
|
+
│ 120 enriched pitch tracking 29 techniques │
|
|
62
63
|
│ 683 drum kits key detection replay into session │
|
|
63
64
|
│ │
|
|
64
65
|
│ Sample Engine Corpus Intelligence Taste Graph │
|
|
@@ -79,7 +80,7 @@ Most MCP servers are tool collections — they execute commands. LivePilot is an
|
|
|
79
80
|
│ └─────────────────┼──────────────────┘ │
|
|
80
81
|
│ ▼ │
|
|
81
82
|
│ ┌─────────────────┐ │
|
|
82
|
-
│ │
|
|
83
|
+
│ │ 426 MCP Tools │ │
|
|
83
84
|
│ │ 52 domains │ │
|
|
84
85
|
│ └────────┬────────┘ │
|
|
85
86
|
│ │ │
|
|
@@ -102,7 +103,7 @@ Most MCP servers are tool collections — they execute commands. LivePilot is an
|
|
|
102
103
|
|
|
103
104
|
**M4L Bridge** (`m4l_device/`) — Optional Max for Live Audio Effect on the master track. Provides deep LOM access through Max's LiveAPI that the ControlSurface API can't reach. UDP 9880 (M4L to server) carries spectral data and LiveAPI responses. OSC 9881 (server to M4L) sends commands. The 32 spectral/analyzer tools strictly require the bridge; device and sample tools that call the bridge also have graceful fallbacks, so core functionality works without it. Backed by 30 bridge commands for hidden parameters, Simpler internals, warp markers, display values, and Simpler warp / Compressor sidechain writes that live on child objects Python can't reach.
|
|
104
105
|
|
|
105
|
-
**Device Atlas** (`mcp_server/atlas/`) — In-memory indexed JSON database. 1305 devices with browser URIs,
|
|
106
|
+
**Device Atlas** (`mcp_server/atlas/`) — In-memory indexed JSON database. 1305 devices with browser URIs, 120 enriched with YAML sonic intelligence profiles (mood, genre, texture, recommended chains). 6 indexes: by_id, by_name, by_uri, by_category, by_tag, by_genre. The AI never hallucinates a device name or preset — it always resolves against the atlas first.
|
|
106
107
|
|
|
107
108
|
**Sample Engine** (`mcp_server/sample_engine/`) — Searches three sources simultaneously: BrowserSource (Ableton's library), SpliceSource (local Splice catalog via SQLite), FilesystemSource (user directories). Every result passes through a 6-critic fitness battery (key, tempo, spectral, genre, mood, technical). 29 processing techniques (Surgeon precision vs. Alchemist experimentation). Builds complete sample processing plans with warp, slice, and effect recommendations.
|
|
108
109
|
|
|
@@ -120,7 +121,7 @@ Most MCP servers are tool collections — they execute commands. LivePilot is an
|
|
|
120
121
|
|
|
121
122
|
## The Intelligence Layer
|
|
122
123
|
|
|
123
|
-
12 engines sit on top of the
|
|
124
|
+
12 engines sit on top of the 426 tools. They give the AI musical judgment, not just musical execution.
|
|
124
125
|
|
|
125
126
|
### SongBrain — What the Song Is
|
|
126
127
|
|
|
@@ -172,7 +173,7 @@ Every engine follows: **measure before → act → measure after → compare**.
|
|
|
172
173
|
|
|
173
174
|
## Tools
|
|
174
175
|
|
|
175
|
-
|
|
176
|
+
426 tools across 52 domains. Highlights below — [full catalog here](docs/manual/tool-catalog.md).
|
|
176
177
|
|
|
177
178
|
<br>
|
|
178
179
|
|
|
@@ -232,7 +233,7 @@ The atlas is an in-memory indexed database of Ableton's entire device library.
|
|
|
232
233
|
|
|
233
234
|
```
|
|
234
235
|
1305 devices total
|
|
235
|
-
|
|
236
|
+
120 enriched with sonic intelligence (mood, genre, texture, chains)
|
|
236
237
|
683 drum kits mapped with note assignments
|
|
237
238
|
6 indexes: by_id, by_name, by_uri, by_category, by_tag, by_genre
|
|
238
239
|
```
|
|
@@ -360,7 +361,7 @@ The V2 intelligence layer. These tools analyze, diagnose, plan, evaluate, and le
|
|
|
360
361
|
| Creative Constraints | 5 | constraint activation, reference-inspired variants |
|
|
361
362
|
| Preview Studio | 5 | variant creation, preview rendering, comparison, commit |
|
|
362
363
|
|
|
363
|
-
> **[View all
|
|
364
|
+
> **[View all 426 tools →](docs/manual/tool-catalog.md)**
|
|
364
365
|
|
|
365
366
|
<br>
|
|
366
367
|
|
|
@@ -587,7 +588,7 @@ See [CONTRIBUTING.md](CONTRIBUTING.md) for architecture details, code guidelines
|
|
|
587
588
|
|
|
588
589
|
| Document | What's inside |
|
|
589
590
|
|----------|---------------|
|
|
590
|
-
| [Manual](docs/manual/index.md) | Complete reference: architecture, all
|
|
591
|
+
| [Manual](docs/manual/index.md) | Complete reference: architecture, all 426 tools, workflows |
|
|
591
592
|
| [Intelligence Layer](docs/manual/intelligence.md) | How the 12 engines connect — conductor, moves, preview, evaluation |
|
|
592
593
|
| [Device Atlas](docs/manual/device-atlas.md) | 1305 devices indexed — search, suggest, chain building |
|
|
593
594
|
| [Samples & Slicing](docs/manual/samples.md) | 3-source search, fitness critics, slice workflows |
|
package/installer/codex.js
CHANGED
|
@@ -42,6 +42,19 @@ function loadManifest() {
|
|
|
42
42
|
return JSON.parse(fs.readFileSync(SOURCE_MANIFEST, "utf-8"));
|
|
43
43
|
}
|
|
44
44
|
|
|
45
|
+
function writeLocalMcpConfig(destDir) {
|
|
46
|
+
const file = path.join(destDir, ".mcp.json");
|
|
47
|
+
const config = {
|
|
48
|
+
mcpServers: {
|
|
49
|
+
livepilot: {
|
|
50
|
+
command: process.execPath,
|
|
51
|
+
args: [path.join(ROOT, "bin", "livepilot.js")],
|
|
52
|
+
},
|
|
53
|
+
},
|
|
54
|
+
};
|
|
55
|
+
fs.writeFileSync(file, JSON.stringify(config, null, 2) + "\n");
|
|
56
|
+
}
|
|
57
|
+
|
|
45
58
|
function ensureMarketplace(pluginName) {
|
|
46
59
|
const file = marketplacePath();
|
|
47
60
|
let marketplace = {
|
|
@@ -115,6 +128,7 @@ function installCodexPlugin() {
|
|
|
115
128
|
fs.mkdirSync(path.dirname(destDir), { recursive: true });
|
|
116
129
|
fs.rmSync(destDir, { recursive: true, force: true });
|
|
117
130
|
copyDirSync(SOURCE_DIR, destDir);
|
|
131
|
+
writeLocalMcpConfig(destDir);
|
|
118
132
|
|
|
119
133
|
console.log("Done! Next steps:");
|
|
120
134
|
console.log(" 1. Open or refresh Codex");
|
|
Binary file
|
package/mcp_server/__init__.py
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
"""LivePilot MCP Server — bridges MCP protocol to Ableton Live."""
|
|
2
|
-
__version__ = "1.
|
|
2
|
+
__version__ = "1.17.1"
|
|
@@ -28,6 +28,7 @@ class AtlasManager:
|
|
|
28
28
|
self._by_category: Dict[str, List[Dict[str, Any]]] = {}
|
|
29
29
|
self._by_tag: Dict[str, List[Dict[str, Any]]] = {}
|
|
30
30
|
self._by_genre: Dict[str, List[Dict[str, Any]]] = {}
|
|
31
|
+
self._by_pack: Dict[str, List[Dict[str, Any]]] = {}
|
|
31
32
|
|
|
32
33
|
for dev in self._devices:
|
|
33
34
|
dev_id = dev.get("id", "")
|
|
@@ -55,6 +56,30 @@ class AtlasManager:
|
|
|
55
56
|
self._by_genre.setdefault(genre.lower(), []).append(dev)
|
|
56
57
|
for genre in dev.get("genres", {}).get("secondary", []):
|
|
57
58
|
self._by_genre.setdefault(genre.lower(), []).append(dev)
|
|
59
|
+
# Also read the enriched genre_affinity field, which is where
|
|
60
|
+
# curated YAML entries land after merge (scanners emit `genres`,
|
|
61
|
+
# enrichments emit `genre_affinity` — both must feed the index
|
|
62
|
+
# or new minimal/microhouse/dub_techno tags would never surface).
|
|
63
|
+
aff = dev.get("genre_affinity", {}) or {}
|
|
64
|
+
for genre in aff.get("primary", []) if isinstance(aff, dict) else []:
|
|
65
|
+
self._by_genre.setdefault(str(genre).lower(), []).append(dev)
|
|
66
|
+
for genre in aff.get("secondary", []) if isinstance(aff, dict) else []:
|
|
67
|
+
self._by_genre.setdefault(str(genre).lower(), []).append(dev)
|
|
68
|
+
|
|
69
|
+
# Pack index — enriched devices declare `pack:` in YAML. Native
|
|
70
|
+
# Live devices without an explicit pack default to "Core Library"
|
|
71
|
+
# so the index covers everything shipped with the stock install.
|
|
72
|
+
pack_name = dev.get("pack")
|
|
73
|
+
if not pack_name and dev.get("source") in (None, "native", "browser"):
|
|
74
|
+
# Heuristic: if we have no explicit pack and the scan source
|
|
75
|
+
# is the built-in browser, treat as Core Library. Don't fake
|
|
76
|
+
# a pack for plugins/user samples where the source isn't the
|
|
77
|
+
# stock library.
|
|
78
|
+
if dev_category in ("instruments", "audio_effects",
|
|
79
|
+
"midi_effects", "max_for_live"):
|
|
80
|
+
pack_name = "Core Library"
|
|
81
|
+
if pack_name:
|
|
82
|
+
self._by_pack.setdefault(pack_name, []).append(dev)
|
|
58
83
|
|
|
59
84
|
# ── Properties ──────────────────────────────────────────────────
|
|
60
85
|
|
|
@@ -83,9 +108,69 @@ class AtlasManager:
|
|
|
83
108
|
"by_category": len(self._by_category),
|
|
84
109
|
"by_tag": len(self._by_tag),
|
|
85
110
|
"by_genre": len(self._by_genre),
|
|
111
|
+
"by_pack": len(self._by_pack),
|
|
86
112
|
},
|
|
87
113
|
}
|
|
88
114
|
|
|
115
|
+
# ── Pack lookup ────────────────────────────────────────────────
|
|
116
|
+
def pack_info(self, pack_name: str) -> Dict[str, Any]:
|
|
117
|
+
"""Return summary of a pack — device list + enrichment coverage.
|
|
118
|
+
|
|
119
|
+
Matches the pack name case-insensitively; the index stores the
|
|
120
|
+
canonical casing from the YAML (e.g. "Core Library", "Drone Lab").
|
|
121
|
+
"""
|
|
122
|
+
if not pack_name:
|
|
123
|
+
return {"pack": "", "device_count": 0, "enriched_count": 0,
|
|
124
|
+
"devices": []}
|
|
125
|
+
|
|
126
|
+
target = pack_name.strip().lower()
|
|
127
|
+
# Find canonical name
|
|
128
|
+
canonical = None
|
|
129
|
+
for name in self._by_pack.keys():
|
|
130
|
+
if name.lower() == target:
|
|
131
|
+
canonical = name
|
|
132
|
+
break
|
|
133
|
+
|
|
134
|
+
if canonical is None:
|
|
135
|
+
return {
|
|
136
|
+
"pack": pack_name,
|
|
137
|
+
"device_count": 0,
|
|
138
|
+
"enriched_count": 0,
|
|
139
|
+
"devices": [],
|
|
140
|
+
"available_packs": sorted(self._by_pack.keys()),
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
devices = self._by_pack[canonical]
|
|
144
|
+
enriched = [d for d in devices if d.get("enriched")]
|
|
145
|
+
return {
|
|
146
|
+
"pack": canonical,
|
|
147
|
+
"device_count": len(devices),
|
|
148
|
+
"enriched_count": len(enriched),
|
|
149
|
+
"devices": [
|
|
150
|
+
{
|
|
151
|
+
"id": d.get("id", ""),
|
|
152
|
+
"name": d.get("name", ""),
|
|
153
|
+
"category": d.get("category", ""),
|
|
154
|
+
"enriched": bool(d.get("enriched")),
|
|
155
|
+
"uri": d.get("uri", ""),
|
|
156
|
+
}
|
|
157
|
+
for d in devices
|
|
158
|
+
],
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
def list_packs(self) -> List[Dict[str, Any]]:
|
|
162
|
+
"""All known packs with device counts, sorted by size descending."""
|
|
163
|
+
packs = [
|
|
164
|
+
{
|
|
165
|
+
"name": name,
|
|
166
|
+
"device_count": len(devs),
|
|
167
|
+
"enriched_count": sum(1 for d in devs if d.get("enriched")),
|
|
168
|
+
}
|
|
169
|
+
for name, devs in self._by_pack.items()
|
|
170
|
+
]
|
|
171
|
+
packs.sort(key=lambda p: -p["device_count"])
|
|
172
|
+
return packs
|
|
173
|
+
|
|
89
174
|
# ── Lookup ──────────────────────────────────────────────────────
|
|
90
175
|
|
|
91
176
|
def lookup(self, name_or_id: str) -> Optional[Dict[str, Any]]:
|