livepilot 1.20.3 → 1.21.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 +290 -0
- package/README.md +62 -33
- 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/affordances/__init__.py +31 -0
- package/mcp_server/affordances/_schema.py +143 -0
- package/mcp_server/affordances/devices/auto-filter.yaml +14 -0
- package/mcp_server/affordances/devices/delay.yaml +18 -0
- package/mcp_server/affordances/devices/reverb.yaml +16 -0
- package/mcp_server/affordances/presets.py +74 -0
- package/mcp_server/experiment/tools.py +149 -12
- package/mcp_server/memory/tools.py +10 -0
- package/mcp_server/runtime/tools.py +7 -0
- package/mcp_server/semantic_moves/device_creation_compilers.py +37 -3
- package/mcp_server/semantic_moves/device_creation_moves.py +7 -7
- package/mcp_server/semantic_moves/device_mutation_compilers.py +66 -12
- package/mcp_server/semantic_moves/performance_compilers.py +157 -0
- package/mcp_server/semantic_moves/performance_moves.py +46 -1
- package/mcp_server/semantic_moves/tools.py +8 -5
- package/mcp_server/song_brain/tools.py +6 -0
- package/mcp_server/stuckness_detector/tools.py +4 -0
- package/mcp_server/tools/_agent_os_engine/taste.py +6 -0
- package/mcp_server/tools/memory.py +7 -0
- package/mcp_server/wonder_mode/tools.py +4 -0
- package/package.json +2 -2
- package/remote_script/LivePilot/__init__.py +1 -1
- package/server.json +3 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,295 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 1.21.1 — Audit-response patch: experiment-commit safety + doc hygiene + lockfile (April 24 2026)
|
|
4
|
+
|
|
5
|
+
Small patch release responding to an external audit of v1.21.0 performed
|
|
6
|
+
the same day it shipped. The audit surfaced one real safety bug
|
|
7
|
+
(commit_experiment status allowlist was an exclusion list when the
|
|
8
|
+
intent was an inclusion list) plus several doc-consistency drifts.
|
|
9
|
+
No new features. No API changes beyond the tightened commit_experiment
|
|
10
|
+
contract. v1.21.0 callers already doing the right thing
|
|
11
|
+
(run_experiment → commit the ranked winner) continue to work unchanged.
|
|
12
|
+
|
|
13
|
+
### P1 — commit_experiment only accepts `status='evaluated'`
|
|
14
|
+
|
|
15
|
+
Pre-fix (v1.21.0 and all prior versions with commit_experiment), the
|
|
16
|
+
status check was an EXCLUSION list:
|
|
17
|
+
|
|
18
|
+
```python
|
|
19
|
+
if target.status in ("rejected", "analytical", "failed"):
|
|
20
|
+
return {"error": ...}
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
Blocks 3 statuses; implicitly allows the other 6 — including `pending`,
|
|
24
|
+
`running`, `discarded`, and `interesting_but_failed`. Those branches
|
|
25
|
+
can't be ranked by `compare_experiments()`, but `commit_experiment`
|
|
26
|
+
would accept them as long as a compiled plan was attached. The code's
|
|
27
|
+
own inline comment already described the correct contract ("only
|
|
28
|
+
status='evaluated' branches are ranking candidates"); the implementation
|
|
29
|
+
had the wrong polarity. The fix flips it to an INCLUSION check:
|
|
30
|
+
|
|
31
|
+
```python
|
|
32
|
+
if target.status != "evaluated":
|
|
33
|
+
return {"error": ...}
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
Error message updated to enumerate all 9 possible statuses and explain
|
|
37
|
+
which state each represents (pending/running = not yet evaluated;
|
|
38
|
+
rejected/analytical/failed = classifier exclusions; committed =
|
|
39
|
+
already committed; discarded = explicitly thrown out;
|
|
40
|
+
interesting_but_failed = exploration-audit only).
|
|
41
|
+
|
|
42
|
+
Why this matters: v1.21.0's `commit_experiment` ledger writer records
|
|
43
|
+
every commit into `SessionLedger` where anti-repetition filters read
|
|
44
|
+
it. Without the tighter status check, a caller bypassing the ranking
|
|
45
|
+
layer could pollute the ledger with entries the system explicitly
|
|
46
|
+
classified as non-winners — degrading anti-repetition signal quality.
|
|
47
|
+
|
|
48
|
+
**Regression tests added (4)** in `tests/test_commit_experiment_ledger.py`:
|
|
49
|
+
`test_commit_on_pending_branch_rejects`,
|
|
50
|
+
`test_commit_on_running_branch_rejects`,
|
|
51
|
+
`test_commit_on_discarded_branch_rejects`,
|
|
52
|
+
`test_commit_on_interesting_but_failed_branch_rejects`. All FAILED
|
|
53
|
+
pre-fix (reproducing the audit's finding), all PASS post-fix.
|
|
54
|
+
|
|
55
|
+
### P1 — package-lock.json bumped 1.17.5 → 1.21.1
|
|
56
|
+
|
|
57
|
+
Lockfile's root `.version` and `.packages[""].version` had been stale
|
|
58
|
+
at 1.17.5 since before v1.18. `npm publish` doesn't read these fields
|
|
59
|
+
(it reads package.json), so the npm registry was always correct — but
|
|
60
|
+
the repo-local lockfile misled local `npm install` workflows and any
|
|
61
|
+
release-check tooling that compared package.json vs lockfile. Fixed by
|
|
62
|
+
surgical replace on the 2 stale strings; no dependency tree
|
|
63
|
+
regeneration (keeps dep versions identical to v1.21.0).
|
|
64
|
+
|
|
65
|
+
### P2 — Analyzer tool count: 32/33 → 38 (actual)
|
|
66
|
+
|
|
67
|
+
README.md previously said "32 spectral/analyzer tools" in one place
|
|
68
|
+
and "38 analyzer tools" in another — inconsistent within the same file.
|
|
69
|
+
`docs/M4L_BRIDGE.md` said "33 MCP tools in the analyzer domain" in two
|
|
70
|
+
places. Actual `@mcp.tool` count in `mcp_server/tools/analyzer.py` is
|
|
71
|
+
**38** (grep-verified). All stale 32/33 refs corrected to 38.
|
|
72
|
+
|
|
73
|
+
### P2 — Reversibility language hedge
|
|
74
|
+
|
|
75
|
+
README's header NOTE block said "Everything is reversible with undo,"
|
|
76
|
+
which is too strong. Live-session mutations (clips, devices, mixer,
|
|
77
|
+
arrangement) do route through Ableton's undo stack and are reversible
|
|
78
|
+
— but Splice downloads, memory/ledger writes, installer actions, atlas
|
|
79
|
+
scans, and filesystem writes persist beyond undo. Hedged the language
|
|
80
|
+
to reflect this.
|
|
81
|
+
|
|
82
|
+
### Deferred to v1.22
|
|
83
|
+
|
|
84
|
+
Audit-surfaced items that aren't patch-release material:
|
|
85
|
+
|
|
86
|
+
- **Atlas statistics reconciliation.** Docs claim "1305 devices / 120
|
|
87
|
+
enriched / 641 pack-indexed" across 9 description fields, but the
|
|
88
|
+
shipped `device_atlas.json` has 5264 devices and 135 entries with
|
|
89
|
+
`.enriched` truthy. The "1305" number appears to be a long-stale
|
|
90
|
+
cargo-culted count. Requires deciding whether `.devices` contains
|
|
91
|
+
duplicates, what the canonical "enriched" definition is, and
|
|
92
|
+
whether to restructure atlas JSON or fix the readers that look for
|
|
93
|
+
`.meta.version`. v1.22 scope.
|
|
94
|
+
- **`sync_metadata` expansion** to check package-lock.json project
|
|
95
|
+
version, semantic-move count via `registry.count()`, and
|
|
96
|
+
analyzer-tool count via grep on `analyzer.py`. Would convert this
|
|
97
|
+
entire class of drift into CI failures.
|
|
98
|
+
- **Dev-install path** for local contributors hitting missing
|
|
99
|
+
`soundfile` / `scipy` / `pretty_midi` / `pytest_asyncio` deps during
|
|
100
|
+
bare-python local runs. CI has these installed via requirements.txt.
|
|
101
|
+
|
|
102
|
+
### Credits
|
|
103
|
+
|
|
104
|
+
External audit performed same day v1.21.0 shipped. Findings
|
|
105
|
+
file-linked and reproducible. Response time: ~2 hours from audit
|
|
106
|
+
receipt to v1.21.1 patch shipping.
|
|
107
|
+
|
|
108
|
+
### Scope stats
|
|
109
|
+
|
|
110
|
+
- 1 code fix (`mcp_server/experiment/tools.py` — commit_experiment status check)
|
|
111
|
+
- 4 new regression tests (all initially FAILING pre-fix to reproduce
|
|
112
|
+
the audit, all PASSING post-fix)
|
|
113
|
+
- 3 doc corrections (README.md × 2, docs/M4L_BRIDGE.md × 2, plus the
|
|
114
|
+
reversibility hedge)
|
|
115
|
+
- 15 version-string sites + `.amxd` binary patch (2 bytes) +
|
|
116
|
+
package-lock.json (2 version fields)
|
|
117
|
+
- Test suite: 3120 → 3124 pass (+4). Zero regressions.
|
|
118
|
+
|
|
119
|
+
---
|
|
120
|
+
|
|
121
|
+
## 1.21.0 — Consolidation: experiment ledger + preset library + record-readiness + reader audit (April 24 2026)
|
|
122
|
+
|
|
123
|
+
Consolidation release closing five items from the v1.20 plan §12 non-goals
|
|
124
|
+
that were tractable in a 2-session scope. Adds 1 new semantic move + 1
|
|
125
|
+
major-tool auto-ledger-write + minimal preset-library infrastructure +
|
|
126
|
+
a store-purpose audit that turns the v1.20 director-SKILL fix into a
|
|
127
|
+
codebase-wide invariant, all gated behind a test-first wire-format
|
|
128
|
+
parity extension that caught 1 pre-v1.20 drift bug and closed the
|
|
129
|
+
audit window.
|
|
130
|
+
|
|
131
|
+
Registry: 43 → 44 moves. Test suite: 3043 → 3118 pass (+75 across all
|
|
132
|
+
chunks). Wire-format parity suite: 10 → 44 scenarios. Zero regressions.
|
|
133
|
+
|
|
134
|
+
### New semantic moves (1)
|
|
135
|
+
|
|
136
|
+
- **`configure_record_readiness`** (performance family, low risk, protects
|
|
137
|
+
`signal_integrity=0.7`)
|
|
138
|
+
- seed_args: `{track_index, armed, exclusive?}`
|
|
139
|
+
- Non-exclusive: single step `set_track_arm(track_index, arm=armed)` — note
|
|
140
|
+
the wire-format key is `arm`, not `armed` (the MCP tool accepts `armed`
|
|
141
|
+
as an ergonomic kwarg but renames to `arm` before send_command; the
|
|
142
|
+
remote_command backend bypasses that rename).
|
|
143
|
+
- Exclusive (`exclusive=True` + `armed=True`): N+1 step plan —
|
|
144
|
+
`set_track_arm(arm=False)` for every other regular track, then
|
|
145
|
+
`set_track_arm(target, arm=True)` for the target. Emulates Ableton's
|
|
146
|
+
exclusive-arm mode manually because `song.exclusive_arm` has no
|
|
147
|
+
Python setter in Live 12.4 (pre-existing v1.20.3 Remote Script bug
|
|
148
|
+
surfaced during v1.21 live-test pre-flight — see plan correction #6).
|
|
149
|
+
Requires `session_info.tracks` (automatically built by
|
|
150
|
+
`apply_semantic_move`).
|
|
151
|
+
- Rejects `exclusive=True + armed=False` (contradictory), missing `armed`
|
|
152
|
+
seed_arg, and negative `track_index` (return tracks can't be armed
|
|
153
|
+
per Ableton's handler at `remote_script/LivePilot/tracks.py:261`).
|
|
154
|
+
- Closes the one tech_debt entry seeded during v1.20 live test 6.
|
|
155
|
+
|
|
156
|
+
### Experiment-engine ledger writer
|
|
157
|
+
|
|
158
|
+
- **`commit_experiment`** now writes to `SessionLedger` after a successful
|
|
159
|
+
commit, mirroring v1.20's `apply_semantic_move` pattern (commit `0b3489b`).
|
|
160
|
+
Anti-repetition filters downstream now see experiment commits the same
|
|
161
|
+
way they see direct semantic-move applies.
|
|
162
|
+
- `engine` tag reflects branch SOURCE (not escalation success): `"composer"`
|
|
163
|
+
when `target.seed.source == "composer"`, else `"experiment"`. A composer-
|
|
164
|
+
sourced branch that fell back to scaffold execution is still
|
|
165
|
+
`engine=composer` — the escalation-success detail lives in
|
|
166
|
+
`target.evaluation["composer_escalation"]`.
|
|
167
|
+
- `move_class` via `_infer_move_family(target)`: `seed.family` when set,
|
|
168
|
+
else inspect first compiled_plan step's tool via `_TOOL_TO_FAMILY`
|
|
169
|
+
lookup, else default `"mix"`.
|
|
170
|
+
- `actions` = one entry per ok row in `commit_result["execution_log"]`
|
|
171
|
+
(the router's actual execution record — captures the post-escalation
|
|
172
|
+
plan when composer escalation fired).
|
|
173
|
+
- Response gains `ledger_entry_id` field (same pattern as
|
|
174
|
+
`apply_semantic_move`). Best-effort — a ledger-write exception is logged
|
|
175
|
+
and swallowed so the commit never fails on a bookkeeping path.
|
|
176
|
+
|
|
177
|
+
### Minimal affordance preset library
|
|
178
|
+
|
|
179
|
+
- New path `mcp_server/affordances/` with loader (`presets.py`), schema
|
|
180
|
+
validator (`_schema.py`), and 3 seed YAML files:
|
|
181
|
+
- `reverb.yaml` — preset `dub-cathedral` (Basic Channel-adjacent huge
|
|
182
|
+
space; Decay 0.85, Room 0.95, Dry/Wet 0.40, Predelay 0.45, Diffusion 0.80)
|
|
183
|
+
- `delay.yaml` — preset `ping-pong-dub` (dotted 8th, feedback 0.45,
|
|
184
|
+
HP+LP filtered)
|
|
185
|
+
- `auto-filter.yaml` — preset `slow-sweep` (LP type, bar-long LFO,
|
|
186
|
+
moderate resonance)
|
|
187
|
+
- `configure_device` compiler gained optional `preset` + `device_slug`
|
|
188
|
+
seed_args (additive — v1.20 callers unaffected). Merge: preset resolves
|
|
189
|
+
first, explicit `param_overrides` win on per-key conflict (last-write-wins).
|
|
190
|
+
v1.21 requires explicit `device_slug` when `preset` is used; v1.22
|
|
191
|
+
adds class_name → slug auto-inference.
|
|
192
|
+
- `livepilot-creative-director/references/phase-6-execution.md` §Affordance-
|
|
193
|
+
preset resolution rewritten to document the live import path and the
|
|
194
|
+
three dispatch patterns (preset reference, preset + explicit override,
|
|
195
|
+
fallback to Python resolve).
|
|
196
|
+
|
|
197
|
+
### Wire-format parity retroactive gate
|
|
198
|
+
|
|
199
|
+
- `tests/test_compiler_wire_format_parity.py` extended from 10 to 44
|
|
200
|
+
scenarios (10 v1.20 + 33 pre-v1.20 + 1 new `configure_record_readiness`).
|
|
201
|
+
Gate surfaced **1 pre-v1.20 drift pattern** affecting 7 moves:
|
|
202
|
+
`create_chaos_modulator`, `create_feedback_resonator`,
|
|
203
|
+
`create_wavefolder_effect`, `create_bitcrusher_effect`,
|
|
204
|
+
`create_karplus_string`, `create_stochastic_texture`, `create_fdn_reverb`
|
|
205
|
+
all shipped with a `find_and_load_device` plan_template emitting
|
|
206
|
+
`{"query": "Wonder X"}` but no `track_index`. The `remote_command`
|
|
207
|
+
backend bypasses MCP normalization, so Ableton's handler threw
|
|
208
|
+
`KeyError` on `params["track_index"]` — broken at runtime since
|
|
209
|
+
pre-v1.20, caught now.
|
|
210
|
+
- Fix: `device_creation_compilers.py::_compile_device_creation` threads
|
|
211
|
+
`track_index` from `seed_args` into `find_and_load_device` steps.
|
|
212
|
+
Plan templates updated from `{"query": ...}` to `{"device_name": ...}`
|
|
213
|
+
across all 7 Device Forge moves.
|
|
214
|
+
- Variant-B' consideration (>3 drift bugs → pause v1.21, ship patch):
|
|
215
|
+
all 7 failures were one pattern in one file, fixable in one commit.
|
|
216
|
+
Path B (inline fix as part of Task 1.1.5a) taken — single-pattern
|
|
217
|
+
single-file fixes are exactly what Task 1.1.5a was written for.
|
|
218
|
+
See `docs/plans/v1.21-impl-status.md` §3 for the decision log.
|
|
219
|
+
|
|
220
|
+
### Store-purpose reader audit
|
|
221
|
+
|
|
222
|
+
- Every file in `mcp_server/` that imports `SessionLedger` or calls
|
|
223
|
+
`memory_list` / `get_session_memory` now carries a
|
|
224
|
+
`# store_purpose: <purpose>` comment naming its intent.
|
|
225
|
+
- Allowed purposes (closed set): `writer`, `anti_repetition`,
|
|
226
|
+
`audit_readonly`, `technique_library`, `session_observations`,
|
|
227
|
+
`escape_hatch_log`, `mcp_tool_definition`.
|
|
228
|
+
- **`tests/test_ledger_readers.py`** new (5 test cases): enforces the
|
|
229
|
+
annotation contract at CI, AND guards against any file annotated
|
|
230
|
+
`anti_repetition` also calling `memory_list` — which would be the
|
|
231
|
+
latent v1.20 store-confusion bug (director SKILL originally pointed
|
|
232
|
+
at `memory_list` for recency; `memory_list` reads the persistent
|
|
233
|
+
technique library, not the action ledger).
|
|
234
|
+
- Audit was clean across the entire `mcp_server` tree — no anti-repetition
|
|
235
|
+
caller was found reading the wrong store. The audit is purely
|
|
236
|
+
documentation contracts enforced at CI.
|
|
237
|
+
|
|
238
|
+
### Plan corrections applied during execution (6, logged in impl-status doc)
|
|
239
|
+
|
|
240
|
+
Documented for future release planners in `docs/plans/v1.21-impl-status.md`:
|
|
241
|
+
|
|
242
|
+
1. **Baseline drift** — v1.20.2 and v1.20.3 shipped between plan-write and
|
|
243
|
+
execution; all version-string literals in the plan needed `1.20.1 →
|
|
244
|
+
1.20.3` remapping.
|
|
245
|
+
2. **Wire-format drift in device_creation** — plan_templates emitted
|
|
246
|
+
`{"query": ...}`; handler requires `{"track_index", "device_name"}`.
|
|
247
|
+
3. **`set_track_arm` wire format** — plan §3.1 used `{"armed": ...}`;
|
|
248
|
+
handler reads `params["arm"]`. MCP tool renames `armed → arm` before
|
|
249
|
+
send_command; remote_command backend bypasses the rename.
|
|
250
|
+
4. **`set_exclusive_arm` shape** — plan §3.1 assumed a per-track signature
|
|
251
|
+
`(track_index=...)`; handler is a global mode toggle taking
|
|
252
|
+
`{"enabled": bool}`.
|
|
253
|
+
5. **Return-track arm rejection** — plan's test expected negative
|
|
254
|
+
`track_index` to succeed; handler raises `ValueError: "Cannot arm a
|
|
255
|
+
return track"`. Corrected test pins compile-time rejection.
|
|
256
|
+
6. **`set_exclusive_arm` is broken in Live 12.4 LOM** — live-test pre-flight
|
|
257
|
+
(2026-04-24) surfaced that `song.exclusive_arm` is a property WITHOUT a
|
|
258
|
+
Python setter in Live 12.4's Remote Script API. The v1.20.3 handler's
|
|
259
|
+
direct assignment `song.exclusive_arm = bool(...)` errors with
|
|
260
|
+
"property of 'Song' object has no setter". v1.21's
|
|
261
|
+
`configure_record_readiness` exclusive-mode now emulates the behavior
|
|
262
|
+
manually (disarm-all-others + arm-target loop) — correctness is
|
|
263
|
+
identical, works in any Live version. The broken v1.20.3
|
|
264
|
+
`set_exclusive_arm` handler is LEFT AS-IS for potential future fix
|
|
265
|
+
(when/if Ableton re-exposes the setter, or someone finds a LOM method
|
|
266
|
+
alternative); it's tracked as an independent bug in the Remote Script.
|
|
267
|
+
|
|
268
|
+
### Non-goals (deferred)
|
|
269
|
+
|
|
270
|
+
- **Hard cutover of the escape hatch.** v1.22+ target, conditional on
|
|
271
|
+
zero `tech_debt` log entries accumulating in one month of production.
|
|
272
|
+
- **Standard / Deep preset catalog.** v1.22+. Minimal library from v1.21
|
|
273
|
+
proves the loader; catalog fills in after real-usage signal.
|
|
274
|
+
- **class_name → slug auto-inference** for the preset library. v1.22+.
|
|
275
|
+
- **Pre-v1.20 move compiler refactors** beyond the 1 drift fix. v1.22+.
|
|
276
|
+
- **New move families beyond the canonical 7.** The performance family
|
|
277
|
+
already exists; `configure_record_readiness` joins it.
|
|
278
|
+
- **Taste-graph integration for preset ranking.** v1.22+ once the catalog
|
|
279
|
+
exists.
|
|
280
|
+
|
|
281
|
+
### Scope stats
|
|
282
|
+
|
|
283
|
+
- 7 atomic commits on `v1.21.0-dev` (fix + gate + 4 feature + refactor + release)
|
|
284
|
+
- 28 files changed, +1933 / -63 lines
|
|
285
|
+
- 3 new test files (commit_experiment_ledger, performance_moves,
|
|
286
|
+
affordance_presets, ledger_readers) + 1 doc (impl-status)
|
|
287
|
+
- 1 new package (`mcp_server/affordances/`) + 3 YAML seed files
|
|
288
|
+
- 15 version-string sites bumped + `.amxd` binary patch (2 bytes)
|
|
289
|
+
- 10 files annotated with `# store_purpose:`
|
|
290
|
+
|
|
291
|
+
---
|
|
292
|
+
|
|
3
293
|
## 1.20.3 — Automated analyzer pre-flight (April 24 2026)
|
|
4
294
|
|
|
5
295
|
Micro-release closing one class of operator error that broke the v1.20.1
|
package/README.md
CHANGED
|
@@ -25,7 +25,9 @@
|
|
|
25
25
|
> [!NOTE]
|
|
26
26
|
> LivePilot works with **any MCP client** — Claude Code, Claude Desktop, Cursor, VS Code, Windsurf.
|
|
27
27
|
> All tools execute on Ableton's main thread through the official Live Object Model API.
|
|
28
|
-
>
|
|
28
|
+
> Live-session mutations (clips, devices, mixer, arrangement) route through Ableton's undo stack.
|
|
29
|
+
> Side effects that touch state outside the Live project — Splice downloads, memory/ledger writes,
|
|
30
|
+
> installer actions, atlas scans, filesystem writes — persist beyond undo.
|
|
29
31
|
|
|
30
32
|
<br>
|
|
31
33
|
|
|
@@ -38,12 +40,12 @@ Most MCP servers are tool collections — they execute commands. LivePilot is an
|
|
|
38
40
|
| Layer | What it provides |
|
|
39
41
|
|-------|-----------------|
|
|
40
42
|
| **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
|
|
42
|
-
| **Concept Surface** |
|
|
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,
|
|
44
|
-
| **Spectral Perception** | Real-time ears via M4L —
|
|
43
|
+
| **Device Atlas** | Knowledge of every device in Ableton's library — 1305 devices indexed 7 ways (by_id, by_name, by_uri, by_category, by_tag, by_genre, by_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` cross-reference 146 techniques across 58 devices |
|
|
44
|
+
| **Concept Surface** | 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. The LLM reads "sound like Gas" and gets a concrete device chain, not guesswork |
|
|
45
|
+
| **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 |
|
|
46
|
+
| **Spectral Perception** | Real-time ears via M4L — 9-band FFT (with sub_low split at 20-60 Hz for kick fundamentals), RMS/peak metering, Krumhansl-Schmuckler key detection, pitch tracking, FluCoMa mel/chroma/onset. Auto-loaded via `ensure_analyzer_on_master` (v1.20.3) — no more silently-degraded mix moves from forgotten analyzer |
|
|
45
47
|
| **Technique Memory** | Persistent library of production decisions. Save a beat pattern, device chain, or mix template. Recall by mood, genre, or texture across sessions |
|
|
46
|
-
| **Creative Intelligence** |
|
|
48
|
+
| **Creative Intelligence** | 12 engines on top of the tools: SongBrain, Taste Graph, Wonder Mode, Mix/Sound-Design/Transition/Reference/Translation engines, Hook Hunter, Stuckness Detector, Session Continuity, Preview Studio. **44 semantic moves** (v1.21) — musical intents like "tighten the low end" or "make kick and bass lock" that compile into tool sequences with risk levels and target dimensions |
|
|
47
49
|
|
|
48
50
|
<br>
|
|
49
51
|
|
|
@@ -101,9 +103,9 @@ Most MCP servers are tool collections — they execute commands. LivePilot is an
|
|
|
101
103
|
|
|
102
104
|
**MCP Server** (`mcp_server/`) — Python FastMCP server. Validates inputs, routes commands to the Remote Script over TCP, manages the M4L bridge, runs the atlas, sample engine, composer, and all intelligence engines. This is what your AI client connects to.
|
|
103
105
|
|
|
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
|
|
106
|
+
**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 38 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 31 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.
|
|
105
107
|
|
|
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).
|
|
108
|
+
**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). 7 indexes: by_id, by_name, by_uri, by_category, by_tag, by_genre, by_pack (641 devices mapped to their source pack). Reverse-index `device_techniques_index.json` powers `atlas_techniques_for_device` (146 cross-references across 58 devices). The AI never hallucinates a device name or preset — it always resolves against the atlas first.
|
|
107
109
|
|
|
108
110
|
**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.
|
|
109
111
|
|
|
@@ -133,7 +135,7 @@ Learns your production preferences across sessions. Tracks which move families y
|
|
|
133
135
|
|
|
134
136
|
### Semantic Moves — Musical Actions, Not Parameters
|
|
135
137
|
|
|
136
|
-
|
|
138
|
+
**44 high-level intents** across 7 families (mix, arrangement, transition, sound_design, performance, device_creation, sample) — "add contrast," "tighten the low end," "make kick and bass lock," "sample vocal ghost," "destroy then rebuild." Each move compiles into a concrete tool sequence with risk level, target dimensions, and protection thresholds. Analyzer-gated moves (`tighten_low_end`, `make_kick_bass_lock`) mark their spectrum pre-reads as optional so the plan continues even when the analyzer isn't available. The AI knows what it's risking with every action.
|
|
137
139
|
|
|
138
140
|
### Wonder Mode — Stuck-Rescue Workflow
|
|
139
141
|
|
|
@@ -177,7 +179,7 @@ Every engine follows: **measure before → act → measure after → compare**.
|
|
|
177
179
|
|
|
178
180
|
<br>
|
|
179
181
|
|
|
180
|
-
### Core
|
|
182
|
+
### Core Ableton Control — highlights
|
|
181
183
|
|
|
182
184
|
| Domain | # | What it covers |
|
|
183
185
|
|--------|:-:|----------------|
|
|
@@ -200,12 +202,12 @@ Every engine follows: **measure before → act → measure after → compare**.
|
|
|
200
202
|
|
|
201
203
|
<br>
|
|
202
204
|
|
|
203
|
-
### M4L Bridge —
|
|
205
|
+
### M4L Bridge — 38 analyzer tools `[optional]`, 31 bridge commands
|
|
204
206
|
|
|
205
|
-
The M4L Analyzer sits on the master track. UDP 9880 carries spectral data to the server. OSC 9881 sends commands back.
|
|
207
|
+
The M4L Analyzer sits on the master track. UDP 9880 carries spectral data to the server. OSC 9881 sends commands back. The `ensure_analyzer_on_master` pre-flight (v1.20.3) loads the analyzer idempotently on first use — call it once at session start and forget about it.
|
|
206
208
|
|
|
207
209
|
> [!TIP]
|
|
208
|
-
> Most tools work without the analyzer — it adds
|
|
210
|
+
> Most tools work without the analyzer — it adds 38 spectral/analyzer tools (frequency, loudness, perception, Simpler, warp) and closes the feedback loop.
|
|
209
211
|
|
|
210
212
|
```
|
|
211
213
|
SPECTRAL ─────── 9-band frequency decomposition (sub_low → air)
|
|
@@ -228,36 +230,43 @@ WARP ─────────── get / add / move / remove markers
|
|
|
228
230
|
|
|
229
231
|
<br>
|
|
230
232
|
|
|
231
|
-
### Device Atlas —
|
|
233
|
+
### Device Atlas — 10 tools
|
|
232
234
|
|
|
233
235
|
The atlas is an in-memory indexed database of Ableton's entire device library.
|
|
234
236
|
|
|
235
237
|
```
|
|
236
238
|
1305 devices total
|
|
237
239
|
120 enriched with sonic intelligence (mood, genre, texture, chains)
|
|
238
|
-
|
|
239
|
-
|
|
240
|
+
47 with aesthetic-tagged signature_techniques
|
|
241
|
+
683 drum kits mapped with note assignments
|
|
242
|
+
7 indexes: by_id, by_name, by_uri, by_category, by_tag, by_genre, by_pack
|
|
243
|
+
146 technique cross-references across 58 devices (reverse-index)
|
|
240
244
|
```
|
|
241
245
|
|
|
242
246
|
```
|
|
243
|
-
atlas_search
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
247
|
+
atlas_search Search devices by name, category, or tag
|
|
248
|
+
atlas_device_info Full enriched profile for a single device
|
|
249
|
+
atlas_suggest Suggest devices for a musical intent (e.g., "warm pad")
|
|
250
|
+
atlas_chain_suggest Build a device chain from a genre, artist, or purpose
|
|
251
|
+
atlas_compare Compare two devices side-by-side
|
|
252
|
+
atlas_describe_chain Free-text describe-a-chain ("granular pad like Tim Hecker")
|
|
253
|
+
atlas_techniques_for_device Reverse-lookup: what techniques reference this device?
|
|
254
|
+
atlas_pack_info Inspect a single Ableton pack — devices + enrichment coverage
|
|
255
|
+
scan_full_library Scan what's actually installed on this machine
|
|
256
|
+
reload_atlas Hot-reload the atlas after adding enrichments
|
|
249
257
|
```
|
|
250
258
|
|
|
251
259
|
<br>
|
|
252
260
|
|
|
253
|
-
### Sample Engine —
|
|
261
|
+
### Sample Engine — 23 tools
|
|
254
262
|
|
|
255
|
-
Three-source sample intelligence with critic-driven fitness scoring.
|
|
263
|
+
Three-source sample intelligence with critic-driven fitness scoring, plus deep Splice integration (catalog search, preview, collections, preset downloads).
|
|
256
264
|
|
|
257
265
|
```
|
|
258
266
|
SOURCES ─────────── BrowserSource (Ableton's built-in library)
|
|
259
267
|
SpliceSource (local Splice catalog via SQLite)
|
|
260
268
|
FilesystemSource (user-specified directories)
|
|
269
|
+
Splice LIVE (gRPC + GraphQL for the full catalog)
|
|
261
270
|
|
|
262
271
|
CRITICS ─────────── key fitness · tempo fitness · spectral match
|
|
263
272
|
genre alignment · mood alignment · technical quality
|
|
@@ -265,15 +274,35 @@ CRITICS ─────────── key fitness · tempo fitness · spectr
|
|
|
265
274
|
TECHNIQUES ─────── 29 processing recipes:
|
|
266
275
|
Surgeon (precise, transparent) vs.
|
|
267
276
|
Alchemist (experimental, transformative)
|
|
277
|
+
|
|
278
|
+
PLAN-AWARE ─────── Ableton Live plan 100 samples/day (no credit drain)
|
|
279
|
+
Sounds+/Creator CREDIT_HARD_FLOOR=5 safety gate
|
|
280
|
+
Free samples bypass both gates
|
|
268
281
|
```
|
|
269
282
|
|
|
270
283
|
```
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
284
|
+
Sample analysis & planning
|
|
285
|
+
analyze_sample Build complete SampleProfile (material, key, BPM, spectral)
|
|
286
|
+
search_samples Multi-source search with critic scoring
|
|
287
|
+
evaluate_sample_fit Score a candidate sample against session context
|
|
288
|
+
suggest_sample_technique Recommend processing technique for a sample
|
|
289
|
+
plan_sample_workflow Full processing pipeline: warp + slice + effects
|
|
290
|
+
plan_slice_workflow Slice-specific workflow for breaks / drum loops
|
|
291
|
+
get_sample_opportunities Surface sample-friendly spots in the session
|
|
292
|
+
|
|
293
|
+
Splice LIVE (catalog, collections, presets)
|
|
294
|
+
get_splice_credits Plan + remaining credits + daily quota state
|
|
295
|
+
splice_catalog_hunt Query the full Splice catalog (gRPC)
|
|
296
|
+
splice_download_sample Plan-aware download (credit floor + quota check)
|
|
297
|
+
splice_preview_sample Zero-cost audition via PreviewURL
|
|
298
|
+
splice_describe_sound Natural-language search via Splice GraphQL
|
|
299
|
+
splice_generate_variation Find catalog samples similar to a given UUID
|
|
300
|
+
splice_list_collections Enumerate user's Likes / bass / keys folders
|
|
301
|
+
splice_search_in_collection / add_to_collection / remove_from_collection / create_collection
|
|
302
|
+
splice_list_presets Purchased instrument presets
|
|
303
|
+
splice_preset_info · splice_download_preset
|
|
304
|
+
splice_pack_info Per-pack metadata
|
|
305
|
+
splice_http_diagnose Debug the Splice HTTPS bridge
|
|
277
306
|
```
|
|
278
307
|
|
|
279
308
|
<br>
|
|
@@ -461,12 +490,12 @@ livepilot --install
|
|
|
461
490
|
</details>
|
|
462
491
|
|
|
463
492
|
<details>
|
|
464
|
-
<summary><strong>3. M4L Analyzer (optional — adds
|
|
493
|
+
<summary><strong>3. M4L Analyzer (optional — adds 38 tools)</strong></summary>
|
|
465
494
|
|
|
466
495
|
Drag `LivePilot_Analyzer.amxd` onto the master track for real-time spectral analysis.
|
|
467
|
-
The `--setup` wizard and Desktop Extension do this automatically.
|
|
496
|
+
The `--setup` wizard and Desktop Extension do this automatically. From v1.20.3, your AI client can also call `ensure_analyzer_on_master` — an idempotent pre-flight that loads the device if missing and no-ops otherwise. The Creative Director skill does this on every session's Phase 1 ground read so you can't forget.
|
|
468
497
|
|
|
469
|
-
> **Important:** The Analyzer must be the LAST device on the master track — after all effects (EQ, Compressor, Utility) so it reads the final output signal.
|
|
498
|
+
> **Important:** The Analyzer must be the LAST device on the master track — after all effects (EQ, Compressor, Utility) so it reads the final output signal. The pre-flight tool reports `is_last_on_master: bool` and warns if the invariant is broken.
|
|
470
499
|
|
|
471
500
|
</details>
|
|
472
501
|
|
|
Binary file
|
|
@@ -34,7 +34,7 @@ outlets = 2; // 0: to udpsend (responses), 1: to buffer~/status
|
|
|
34
34
|
// Single source of truth for the bridge version — bumped alongside the
|
|
35
35
|
// rest of the release manifest. Surfaced in the UI via messnamed("livepilot_version", ...)
|
|
36
36
|
// so the frozen .amxd visibly reports which build it was last exported from.
|
|
37
|
-
var VERSION = "1.
|
|
37
|
+
var VERSION = "1.21.1";
|
|
38
38
|
|
|
39
39
|
// ── State ──────────────────────────────────────────────────────────────────
|
|
40
40
|
|
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.21.1"
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
"""Affordance-preset library — named presets per Ableton device class.
|
|
2
|
+
|
|
3
|
+
v1.21 (minimal): infrastructure + 3 seed presets proving the resolver
|
|
4
|
+
pattern:
|
|
5
|
+
- reverb.yaml → preset: dub-cathedral
|
|
6
|
+
- delay.yaml → preset: ping-pong-dub
|
|
7
|
+
- auto-filter.yaml → preset: slow-sweep
|
|
8
|
+
|
|
9
|
+
v1.22 (planned): full catalog coverage, class_name → slug inference,
|
|
10
|
+
taste-graph integration for preset ranking.
|
|
11
|
+
|
|
12
|
+
Public API (re-exported for ``from mcp_server.affordances import ...``):
|
|
13
|
+
resolve_preset(device_slug, preset_name) -> dict[str, number|bool] | None
|
|
14
|
+
list_devices() -> list[str]
|
|
15
|
+
list_presets(device_slug) -> list[str]
|
|
16
|
+
get_preset_metadata(device_slug, preset_name) -> dict | None
|
|
17
|
+
"""
|
|
18
|
+
|
|
19
|
+
from .presets import (
|
|
20
|
+
resolve_preset,
|
|
21
|
+
list_devices,
|
|
22
|
+
list_presets,
|
|
23
|
+
get_preset_metadata,
|
|
24
|
+
)
|
|
25
|
+
|
|
26
|
+
__all__ = [
|
|
27
|
+
"resolve_preset",
|
|
28
|
+
"list_devices",
|
|
29
|
+
"list_presets",
|
|
30
|
+
"get_preset_metadata",
|
|
31
|
+
]
|