livepilot 1.26.0 → 1.26.2

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.
Files changed (191) hide show
  1. package/CHANGELOG.md +41 -0
  2. package/README.md +1 -1
  3. package/installer/codex.js +87 -9
  4. package/livepilot/.Codex-plugin/plugin.json +8 -0
  5. package/livepilot/.claude-plugin/plugin.json +8 -0
  6. package/livepilot/.mcp.json +8 -0
  7. package/livepilot/agents/livepilot-producer/AGENT.md +314 -0
  8. package/livepilot/commands/arrange.md +47 -0
  9. package/livepilot/commands/beat.md +81 -0
  10. package/livepilot/commands/evaluate.md +51 -0
  11. package/livepilot/commands/memory.md +22 -0
  12. package/livepilot/commands/mix.md +47 -0
  13. package/livepilot/commands/perform.md +42 -0
  14. package/livepilot/commands/session.md +13 -0
  15. package/livepilot/commands/sounddesign.md +58 -0
  16. package/livepilot/rubrics/default_preset_check.md +82 -0
  17. package/livepilot/rubrics/layer_accumulation.md +79 -0
  18. package/livepilot/rubrics/layer_precision.md +79 -0
  19. package/livepilot/rubrics/modulation_presence.md +63 -0
  20. package/livepilot/rubrics/sound_design_depth.md +40 -0
  21. package/livepilot/skills/livepilot-arrangement/SKILL.md +164 -0
  22. package/livepilot/skills/livepilot-composition-engine/SKILL.md +151 -0
  23. package/livepilot/skills/livepilot-composition-engine/references/form-patterns.md +97 -0
  24. package/livepilot/skills/livepilot-composition-engine/references/transition-archetypes.md +102 -0
  25. package/livepilot/skills/livepilot-core/SKILL.md +261 -0
  26. package/livepilot/skills/livepilot-core/references/ableton-workflow-patterns.md +831 -0
  27. package/livepilot/skills/livepilot-core/references/affordances/_schema.md +160 -0
  28. package/livepilot/skills/livepilot-core/references/affordances/devices/auto-filter.yaml +133 -0
  29. package/livepilot/skills/livepilot-core/references/affordances/devices/chorus-ensemble.yaml +91 -0
  30. package/livepilot/skills/livepilot-core/references/affordances/devices/compressor.yaml +98 -0
  31. package/livepilot/skills/livepilot-core/references/affordances/devices/convolution-reverb.yaml +113 -0
  32. package/livepilot/skills/livepilot-core/references/affordances/devices/corpus.yaml +84 -0
  33. package/livepilot/skills/livepilot-core/references/affordances/devices/drift.yaml +105 -0
  34. package/livepilot/skills/livepilot-core/references/affordances/devices/echo.yaml +108 -0
  35. package/livepilot/skills/livepilot-core/references/affordances/devices/eq-eight.yaml +95 -0
  36. package/livepilot/skills/livepilot-core/references/affordances/devices/glue-compressor.yaml +88 -0
  37. package/livepilot/skills/livepilot-core/references/affordances/devices/granulator-iii.yaml +104 -0
  38. package/livepilot/skills/livepilot-core/references/affordances/devices/hybrid-reverb.yaml +83 -0
  39. package/livepilot/skills/livepilot-core/references/affordances/devices/operator.yaml +98 -0
  40. package/livepilot/skills/livepilot-core/references/affordances/devices/ping-pong-delay.yaml +104 -0
  41. package/livepilot/skills/livepilot-core/references/affordances/devices/poli.yaml +98 -0
  42. package/livepilot/skills/livepilot-core/references/affordances/devices/saturator.yaml +98 -0
  43. package/livepilot/skills/livepilot-core/references/affordances/devices/shifter.yaml +77 -0
  44. package/livepilot/skills/livepilot-core/references/affordances/devices/simpler.yaml +113 -0
  45. package/livepilot/skills/livepilot-core/references/affordances/devices/utility.yaml +95 -0
  46. package/livepilot/skills/livepilot-core/references/affordances/devices/vinyl-distortion.yaml +92 -0
  47. package/livepilot/skills/livepilot-core/references/affordances/devices/wavetable.yaml +98 -0
  48. package/livepilot/skills/livepilot-core/references/artist-vocabularies.md +389 -0
  49. package/livepilot/skills/livepilot-core/references/automation-atlas.md +272 -0
  50. package/livepilot/skills/livepilot-core/references/concepts/_schema.md +158 -0
  51. package/livepilot/skills/livepilot-core/references/concepts/artists/akufen.yaml +116 -0
  52. package/livepilot/skills/livepilot-core/references/concepts/artists/aphex-twin.yaml +133 -0
  53. package/livepilot/skills/livepilot-core/references/concepts/artists/arca-sophie.yaml +131 -0
  54. package/livepilot/skills/livepilot-core/references/concepts/artists/autechre.yaml +130 -0
  55. package/livepilot/skills/livepilot-core/references/concepts/artists/basic-channel.yaml +140 -0
  56. package/livepilot/skills/livepilot-core/references/concepts/artists/basinski.yaml +126 -0
  57. package/livepilot/skills/livepilot-core/references/concepts/artists/boards-of-canada.yaml +124 -0
  58. package/livepilot/skills/livepilot-core/references/concepts/artists/burial.yaml +127 -0
  59. package/livepilot/skills/livepilot-core/references/concepts/artists/com-truise-tycho.yaml +121 -0
  60. package/livepilot/skills/livepilot-core/references/concepts/artists/daft-punk.yaml +117 -0
  61. package/livepilot/skills/livepilot-core/references/concepts/artists/dj-premier-rza.yaml +119 -0
  62. package/livepilot/skills/livepilot-core/references/concepts/artists/gas.yaml +134 -0
  63. package/livepilot/skills/livepilot-core/references/concepts/artists/hawtin.yaml +127 -0
  64. package/livepilot/skills/livepilot-core/references/concepts/artists/isolee-luomo.yaml +130 -0
  65. package/livepilot/skills/livepilot-core/references/concepts/artists/j-dilla.yaml +133 -0
  66. package/livepilot/skills/livepilot-core/references/concepts/artists/jeff-mills.yaml +120 -0
  67. package/livepilot/skills/livepilot-core/references/concepts/artists/johannsson-richter.yaml +132 -0
  68. package/livepilot/skills/livepilot-core/references/concepts/artists/madlib.yaml +124 -0
  69. package/livepilot/skills/livepilot-core/references/concepts/artists/moodymann-theo-parrish.yaml +121 -0
  70. package/livepilot/skills/livepilot-core/references/concepts/artists/oneohtrix-point-never.yaml +126 -0
  71. package/livepilot/skills/livepilot-core/references/concepts/artists/photek-source-direct.yaml +120 -0
  72. package/livepilot/skills/livepilot-core/references/concepts/artists/rashad-spinn-traxman.yaml +122 -0
  73. package/livepilot/skills/livepilot-core/references/concepts/artists/robert-henke.yaml +113 -0
  74. package/livepilot/skills/livepilot-core/references/concepts/artists/shackleton.yaml +124 -0
  75. package/livepilot/skills/livepilot-core/references/concepts/artists/skream-mala.yaml +119 -0
  76. package/livepilot/skills/livepilot-core/references/concepts/artists/stars-of-the-lid.yaml +119 -0
  77. package/livepilot/skills/livepilot-core/references/concepts/artists/tim-hecker.yaml +122 -0
  78. package/livepilot/skills/livepilot-core/references/concepts/artists/villalobos.yaml +135 -0
  79. package/livepilot/skills/livepilot-core/references/concepts/genres/ambient.yaml +137 -0
  80. package/livepilot/skills/livepilot-core/references/concepts/genres/boom_bap.yaml +124 -0
  81. package/livepilot/skills/livepilot-core/references/concepts/genres/deep-minimal.yaml +130 -0
  82. package/livepilot/skills/livepilot-core/references/concepts/genres/deep_house.yaml +130 -0
  83. package/livepilot/skills/livepilot-core/references/concepts/genres/detroit_techno.yaml +116 -0
  84. package/livepilot/skills/livepilot-core/references/concepts/genres/disco.yaml +123 -0
  85. package/livepilot/skills/livepilot-core/references/concepts/genres/downtempo.yaml +129 -0
  86. package/livepilot/skills/livepilot-core/references/concepts/genres/drone.yaml +133 -0
  87. package/livepilot/skills/livepilot-core/references/concepts/genres/drum-and-bass.yaml +119 -0
  88. package/livepilot/skills/livepilot-core/references/concepts/genres/dub-techno.yaml +132 -0
  89. package/livepilot/skills/livepilot-core/references/concepts/genres/dub.yaml +129 -0
  90. package/livepilot/skills/livepilot-core/references/concepts/genres/dubstep.yaml +120 -0
  91. package/livepilot/skills/livepilot-core/references/concepts/genres/experimental.yaml +136 -0
  92. package/livepilot/skills/livepilot-core/references/concepts/genres/footwork.yaml +119 -0
  93. package/livepilot/skills/livepilot-core/references/concepts/genres/hip-hop.yaml +132 -0
  94. package/livepilot/skills/livepilot-core/references/concepts/genres/house.yaml +126 -0
  95. package/livepilot/skills/livepilot-core/references/concepts/genres/hyperpop.yaml +128 -0
  96. package/livepilot/skills/livepilot-core/references/concepts/genres/idm.yaml +134 -0
  97. package/livepilot/skills/livepilot-core/references/concepts/genres/lo_fi.yaml +129 -0
  98. package/livepilot/skills/livepilot-core/references/concepts/genres/microhouse.yaml +138 -0
  99. package/livepilot/skills/livepilot-core/references/concepts/genres/minimal-techno.yaml +116 -0
  100. package/livepilot/skills/livepilot-core/references/concepts/genres/modern-classical.yaml +123 -0
  101. package/livepilot/skills/livepilot-core/references/concepts/genres/soul.yaml +125 -0
  102. package/livepilot/skills/livepilot-core/references/concepts/genres/synthwave.yaml +123 -0
  103. package/livepilot/skills/livepilot-core/references/concepts/genres/techno.yaml +123 -0
  104. package/livepilot/skills/livepilot-core/references/concepts/genres/trap.yaml +120 -0
  105. package/livepilot/skills/livepilot-core/references/concepts/genres/uk-garage.yaml +121 -0
  106. package/livepilot/skills/livepilot-core/references/device-atlas/00-index.md +110 -0
  107. package/livepilot/skills/livepilot-core/references/device-atlas/distortion-and-character.md +687 -0
  108. package/livepilot/skills/livepilot-core/references/device-atlas/drums-and-percussion.md +753 -0
  109. package/livepilot/skills/livepilot-core/references/device-atlas/dynamics-and-punch.md +525 -0
  110. package/livepilot/skills/livepilot-core/references/device-atlas/eq-and-filtering.md +402 -0
  111. package/livepilot/skills/livepilot-core/references/device-atlas/midi-tools.md +963 -0
  112. package/livepilot/skills/livepilot-core/references/device-atlas/movement-and-modulation.md +874 -0
  113. package/livepilot/skills/livepilot-core/references/device-atlas/space-and-depth.md +571 -0
  114. package/livepilot/skills/livepilot-core/references/device-atlas/spectral-and-weird.md +714 -0
  115. package/livepilot/skills/livepilot-core/references/device-atlas/synths-native.md +953 -0
  116. package/livepilot/skills/livepilot-core/references/device-knowledge/00-index.md +34 -0
  117. package/livepilot/skills/livepilot-core/references/device-knowledge/automation-as-music.md +204 -0
  118. package/livepilot/skills/livepilot-core/references/device-knowledge/chains-genre.md +173 -0
  119. package/livepilot/skills/livepilot-core/references/device-knowledge/creative-thinking.md +211 -0
  120. package/livepilot/skills/livepilot-core/references/device-knowledge/effects-distortion.md +188 -0
  121. package/livepilot/skills/livepilot-core/references/device-knowledge/effects-space.md +162 -0
  122. package/livepilot/skills/livepilot-core/references/device-knowledge/effects-spectral.md +229 -0
  123. package/livepilot/skills/livepilot-core/references/device-knowledge/instruments-synths.md +243 -0
  124. package/livepilot/skills/livepilot-core/references/genre-vocabularies.md +382 -0
  125. package/livepilot/skills/livepilot-core/references/m4l-devices.md +352 -0
  126. package/livepilot/skills/livepilot-core/references/memory-guide.md +178 -0
  127. package/livepilot/skills/livepilot-core/references/midi-recipes.md +402 -0
  128. package/livepilot/skills/livepilot-core/references/mixing-patterns.md +578 -0
  129. package/livepilot/skills/livepilot-core/references/overview.md +300 -0
  130. package/livepilot/skills/livepilot-core/references/pack-knowledge.md +319 -0
  131. package/livepilot/skills/livepilot-core/references/sample-manipulation.md +724 -0
  132. package/livepilot/skills/livepilot-core/references/sound-design-deep.md +140 -0
  133. package/livepilot/skills/livepilot-core/references/sound-design.md +393 -0
  134. package/livepilot/skills/livepilot-corpus-builder/SKILL.md +379 -0
  135. package/livepilot/skills/livepilot-creative-director/SKILL.md +462 -0
  136. package/livepilot/skills/livepilot-creative-director/references/anti-repetition-rules.md +214 -0
  137. package/livepilot/skills/livepilot-creative-director/references/creative-brief-template.md +222 -0
  138. package/livepilot/skills/livepilot-creative-director/references/hybrid-compilation.md +185 -0
  139. package/livepilot/skills/livepilot-creative-director/references/move-family-diversity-rule.md +258 -0
  140. package/livepilot/skills/livepilot-creative-director/references/phase-6-execution.md +409 -0
  141. package/livepilot/skills/livepilot-creative-director/references/the-four-move-rule.md +192 -0
  142. package/livepilot/skills/livepilot-devices/SKILL.md +213 -0
  143. package/livepilot/skills/livepilot-devices/references/load_browser_item-uri-grammar.md +82 -0
  144. package/livepilot/skills/livepilot-evaluation/SKILL.md +195 -0
  145. package/livepilot/skills/livepilot-evaluation/references/capability-modes.md +176 -0
  146. package/livepilot/skills/livepilot-evaluation/references/evaluation-contracts.md +121 -0
  147. package/livepilot/skills/livepilot-evaluation/references/memory-promotion.md +110 -0
  148. package/livepilot/skills/livepilot-mix-engine/SKILL.md +144 -0
  149. package/livepilot/skills/livepilot-mix-engine/references/mix-critics.md +143 -0
  150. package/livepilot/skills/livepilot-mix-engine/references/mix-moves.md +105 -0
  151. package/livepilot/skills/livepilot-mixing/SKILL.md +164 -0
  152. package/livepilot/skills/livepilot-notes/SKILL.md +130 -0
  153. package/livepilot/skills/livepilot-performance-engine/SKILL.md +122 -0
  154. package/livepilot/skills/livepilot-performance-engine/references/performance-safety.md +98 -0
  155. package/livepilot/skills/livepilot-release/SKILL.md +151 -0
  156. package/livepilot/skills/livepilot-sample-engine/SKILL.md +117 -0
  157. package/livepilot/skills/livepilot-sample-engine/references/sample-critics.md +87 -0
  158. package/livepilot/skills/livepilot-sample-engine/references/sample-philosophy.md +51 -0
  159. package/livepilot/skills/livepilot-sample-engine/references/sample-techniques.md +131 -0
  160. package/livepilot/skills/livepilot-sound-design-engine/SKILL.md +247 -0
  161. package/livepilot/skills/livepilot-sound-design-engine/references/patch-model.md +119 -0
  162. package/livepilot/skills/livepilot-sound-design-engine/references/sound-design-critics.md +118 -0
  163. package/livepilot/skills/livepilot-wonder/SKILL.md +143 -0
  164. package/m4l_device/LivePilot_Analyzer.amxd +0 -0
  165. package/m4l_device/LivePilot_Elektron.amxd +0 -0
  166. package/m4l_device/LivePilot_Elektron.maxpat +758 -0
  167. package/m4l_device/livepilot_bridge.js +1 -1
  168. package/m4l_device/livepilot_elektron_bridge.js +82 -0
  169. package/mcp_server/__init__.py +1 -1
  170. package/mcp_server/composer/develop/apply.py +1 -1
  171. package/mcp_server/composer/full/apply.py +32 -6
  172. package/mcp_server/composer/full/brief_builder.py +9 -0
  173. package/mcp_server/evaluation/feature_extractors.py +152 -8
  174. package/mcp_server/m4l_bridge.py +5 -0
  175. package/mcp_server/mix_engine/state_builder.py +19 -2
  176. package/mcp_server/mix_engine/tools.py +22 -0
  177. package/mcp_server/runtime/execution_router.py +6 -0
  178. package/mcp_server/runtime/mcp_dispatch.py +18 -0
  179. package/mcp_server/runtime/remote_commands.py +2 -0
  180. package/mcp_server/server.py +11 -7
  181. package/mcp_server/sound_design/tools.py +33 -0
  182. package/mcp_server/tools/_agent_os_engine/evaluation.py +7 -44
  183. package/mcp_server/tools/_agent_os_engine/models.py +2 -1
  184. package/mcp_server/tools/_conductor.py +5 -2
  185. package/mcp_server/tools/_evaluation_contracts.py +1 -1
  186. package/mcp_server/tools/_snapshot_normalizer.py +32 -3
  187. package/package.json +20 -5
  188. package/remote_script/LivePilot/__init__.py +1 -1
  189. package/remote_script/LivePilot/server.py +63 -2
  190. package/requirements.txt +3 -3
  191. package/server.json +3 -3
@@ -9,6 +9,8 @@ from __future__ import annotations
9
9
  from fastmcp import Context
10
10
 
11
11
  from ..server import mcp
12
+ from ..evaluation.feature_extractors import extract_character_profile
13
+ from ..tools._snapshot_normalizer import normalize_sonic_snapshot
12
14
  from .models import (
13
15
  LayerStrategy,
14
16
  PatchBlock,
@@ -189,9 +191,36 @@ def _fetch_sound_design_data(ctx: Context, track_index: int) -> dict:
189
191
  # Get devices from track_info response (already included by Remote Script)
190
192
  devices: list[dict] = track_info.get("devices", [])
191
193
 
194
+ sonic = None
195
+ try:
196
+ spectral = ctx.lifespan_context.get("spectral")
197
+ if spectral and spectral.is_connected:
198
+ sonic = {}
199
+ spec_data = spectral.get("spectrum")
200
+ if spec_data:
201
+ sonic["bands"] = spec_data["value"]
202
+ rms_snap = spectral.get("rms")
203
+ if rms_snap:
204
+ sonic["rms"] = rms_snap["value"]
205
+ peak_snap = spectral.get("peak")
206
+ if peak_snap:
207
+ sonic["peak"] = peak_snap["value"]
208
+ key_snap = spectral.get("key")
209
+ if key_snap:
210
+ sonic["detected_key"] = key_snap["value"]
211
+ for key in ("spectral_shape", "mel_bands", "chroma", "onset", "novelty", "loudness"):
212
+ snap = spectral.get(key)
213
+ if snap:
214
+ sonic[key] = snap["value"]
215
+ if not sonic:
216
+ sonic = None
217
+ except Exception:
218
+ sonic = None
219
+
192
220
  return {
193
221
  "track_info": track_info,
194
222
  "devices": devices,
223
+ "sonic_snapshot": normalize_sonic_snapshot(sonic, source="sound_design"),
195
224
  }
196
225
 
197
226
 
@@ -262,9 +291,11 @@ def analyze_sound_design(ctx: Context, track_index: int) -> dict:
262
291
  issues, data["track_info"].get("name", "")
263
292
  )
264
293
  moves = plan_sound_design_moves(issues, state)
294
+ sonic_character = extract_character_profile(data.get("sonic_snapshot") or {})
265
295
 
266
296
  return {
267
297
  "state": state.to_dict(),
298
+ "sonic_character": sonic_character,
268
299
  "issues": [i.to_dict() for i in issues],
269
300
  "suggested_moves": [m.to_dict() for m in moves],
270
301
  "issue_count": len(issues),
@@ -295,6 +326,7 @@ def get_sound_design_issues(ctx: Context, track_index: int) -> dict:
295
326
  )
296
327
 
297
328
  return {
329
+ "sonic_character": extract_character_profile(data.get("sonic_snapshot") or {}),
298
330
  "issues": [i.to_dict() for i in issues],
299
331
  "issue_count": len(issues),
300
332
  }
@@ -330,6 +362,7 @@ def plan_sound_design_move(ctx: Context, track_index: int) -> dict:
330
362
  moves = plan_sound_design_moves(issues, state)
331
363
 
332
364
  result: dict = {
365
+ "sonic_character": extract_character_profile(data.get("sonic_snapshot") or {}),
333
366
  "moves": [m.to_dict() for m in moves],
334
367
  "move_count": len(moves),
335
368
  "issue_count": len(issues),
@@ -11,6 +11,10 @@ import re
11
11
  from dataclasses import asdict, dataclass, field
12
12
  from typing import Any, Optional
13
13
 
14
+ from ...evaluation.feature_extractors import (
15
+ extract_dimension_value as _shared_extract_dimension_value,
16
+ )
17
+ from .._snapshot_normalizer import normalize_sonic_snapshot
14
18
  from .models import QUALITY_DIMENSIONS, GoalVector, WorldModel, _clamp
15
19
  from .taste import compute_taste_fit
16
20
 
@@ -29,50 +33,10 @@ def _extract_dimension_value(
29
33
  """
30
34
  if not sonic:
31
35
  return None
32
- # Accept both "spectrum" and "bands" keys — get_master_spectrum returns
33
- # {"bands": {...}} while the evaluator historically expected {"spectrum": {...}}.
34
- # Finding 2 fix: tolerate either shape so raw analyzer output works.
35
- bands = sonic.get("spectrum") or sonic.get("bands")
36
- if not bands:
37
- return None
38
- rms = sonic.get("rms")
39
- peak = sonic.get("peak")
40
-
41
- if dimension == "brightness":
42
- high = bands.get("high", 0)
43
- presence = bands.get("presence", 0)
44
- return _clamp((high + presence) / 2.0)
45
- elif dimension == "warmth":
46
- return _clamp(bands.get("low_mid", 0))
47
- elif dimension == "weight":
48
- sub = bands.get("sub", 0)
49
- low = bands.get("low", 0)
50
- return _clamp((sub + low) / 2.0)
51
- elif dimension == "clarity":
52
- low_mid = bands.get("low_mid", 0)
53
- return _clamp(1.0 - low_mid)
54
- elif dimension == "density":
55
- # Spectral flatness: geometric mean / arithmetic mean of band values.
56
- # Higher = more evenly distributed energy (noise-like).
57
- # Lower = more tonal (energy concentrated in few bands).
58
- vals = [max(v, 1e-10) for v in bands.values() if isinstance(v, (int, float))]
59
- if not vals:
60
- return None
61
- geo_mean = math.exp(sum(math.log(v) for v in vals) / len(vals))
62
- arith_mean = sum(vals) / len(vals)
63
- return _clamp(geo_mean / max(arith_mean, 1e-10))
64
- elif dimension == "energy":
65
- return _clamp(rms) if rms is not None else None
66
- elif dimension == "punch":
67
- if rms and peak and rms > 0:
68
- crest_db = 20.0 * math.log10(max(peak / rms, 1.0))
69
- # Normalize: 0 dB = 0.0, 20 dB = 1.0
70
- return _clamp(crest_db / 20.0)
71
- return None
72
- else:
73
- # Unmeasurable in Phase 1 (width, depth, motion, contrast,
74
- # groove, tension, novelty, polish, emotion, cohesion)
36
+ normalized = normalize_sonic_snapshot(sonic, source="agent_os")
37
+ if normalized is None:
75
38
  return None
39
+ return _shared_extract_dimension_value(normalized, dimension)
76
40
 
77
41
  def compute_evaluation_score(
78
42
  goal: GoalVector,
@@ -203,4 +167,3 @@ def compute_evaluation_score(
203
167
  # I5: hint for the agent to track consecutive undos
204
168
  "consecutive_undo_hint": not keep_change,
205
169
  }
206
-
@@ -33,6 +33,8 @@ MEASURABLE_PROXIES: dict[str, str] = {
33
33
  "density": "spectral flatness (geometric/arithmetic mean ratio)",
34
34
  "energy": "RMS level",
35
35
  "punch": "crest factor in dB (20*log10(peak/rms))",
36
+ "motion": "spectral novelty + onset strength",
37
+ "novelty": "FluCoMa novelty score",
36
38
  }
37
39
 
38
40
  VALID_MODES = frozenset({"observe", "improve", "explore", "finish", "diagnose"})
@@ -129,4 +131,3 @@ class TechniqueCard:
129
131
  "verification": self.verification,
130
132
  "evidence": self.evidence,
131
133
  }
132
-
@@ -70,7 +70,7 @@ class ConductorPlan:
70
70
  _ROUTING_PATTERNS: list[tuple[str, str, str, str, list[str]]] = [
71
71
  # Mix requests
72
72
  (r"clean|mud|muddy|low.?mid|eq|equaliz", "mix_engine", "mix", "analyze_mix", ["plan_mix_move", "evaluate_mix_move"]),
73
- (r"punch|punchy|transient|dynamics|compress", "mix_engine", "mix", "analyze_mix", ["plan_mix_move"]),
73
+ (r"dynamics|compress|crest|over.?compress|flat.?dynamics", "mix_engine", "mix", "analyze_mix", ["plan_mix_move"]),
74
74
  (r"wide|wider|width|stereo|narrow|mono.?compat", "mix_engine", "mix", "analyze_mix", ["plan_mix_move"]),
75
75
  (r"glue|cohes|bus.?comp|mix.?bus", "mix_engine", "mix", "analyze_mix", ["plan_mix_move"]),
76
76
  (r"balance|level|volume.?balanc|gain.?stag", "mix_engine", "mix", "analyze_mix", ["plan_mix_move"]),
@@ -87,6 +87,7 @@ _ROUTING_PATTERNS: list[tuple[str, str, str, str, list[str]]] = [
87
87
 
88
88
  # Sound design requests
89
89
  (r"synth|patch|oscillat|timbre|timbral|wavetable|operator", "sound_design", "sound_design", "analyze_sound_design", ["plan_sound_design_move"]),
90
+ (r"punch|punchy|hit.?harder|snap|attack|transient", "sound_design", "sound_design", "analyze_sound_design", ["plan_sound_design_move"]),
90
91
  (r"haunted|lush|aggressive|warm.?pad|fat.?bass|bright.?lead", "sound_design", "sound_design", "analyze_sound_design", ["plan_sound_design_move"]),
91
92
  (r"modulation|lfo|movement|evolv|texture", "sound_design", "sound_design", "get_patch_model", ["analyze_sound_design"]),
92
93
  (r"layer|sub.?layer|transient.?layer|body", "sound_design", "sound_design", "analyze_sound_design", ["plan_sound_design_move"]),
@@ -254,7 +255,7 @@ def classify_request(request: str) -> ConductorPlan:
254
255
 
255
256
  # Determine capability requirements
256
257
  caps = ["session_access"]
257
- if any(r.engine == "mix_engine" for r in routes):
258
+ if any(r.engine in ("mix_engine", "sound_design") for r in routes):
258
259
  caps.append("analyzer")
259
260
  if any(r.engine in ("reference_engine",) for r in routes):
260
261
  caps.append("offline_perception")
@@ -267,6 +268,8 @@ def classify_request(request: str) -> ConductorPlan:
267
268
  notes.append("Multi-engine task — start with get_session_kernel for shared state")
268
269
  if any(r.engine == "mix_engine" for r in routes):
269
270
  notes.append("Mix engine works best with analyzer data — check get_capability_state")
271
+ if any(r.engine == "sound_design" for r in routes):
272
+ notes.append("Sound design should use analyzer character before level or pan changes")
270
273
 
271
274
  # V2: Search semantic moves for matching intents
272
275
  semantic_moves = _find_matching_semantic_moves(lower)
@@ -22,7 +22,7 @@ from typing import Optional
22
22
  # must report confidence=0.0 for that dimension.
23
23
  MEASURABLE_DIMENSIONS: frozenset[str] = frozenset({
24
24
  "brightness", "warmth", "weight", "clarity",
25
- "density", "energy", "punch",
25
+ "density", "energy", "punch", "motion", "novelty",
26
26
  })
27
27
 
28
28
  # All valid quality dimensions (measurable + unmeasurable).
@@ -13,6 +13,18 @@ import time
13
13
  from typing import Optional
14
14
 
15
15
 
16
+ _RICH_ANALYZER_KEYS = (
17
+ "spectral_shape",
18
+ "mel_bands",
19
+ "chroma",
20
+ "onset",
21
+ "onsets",
22
+ "novelty",
23
+ "loudness",
24
+ "sub_detail",
25
+ )
26
+
27
+
16
28
  def normalize_sonic_snapshot(
17
29
  raw: Optional[dict],
18
30
  source: str = "unknown",
@@ -20,6 +32,9 @@ def normalize_sonic_snapshot(
20
32
  """Normalize a raw analyzer/perception output into canonical snapshot form.
21
33
 
22
34
  Accepts both {"bands": {...}} and {"spectrum": {...}} shapes.
35
+ Rich analyzer streams are preserved when present so evaluators can
36
+ reason from FluCoMa character descriptors instead of collapsing every
37
+ decision down to the 9-band spectrum.
23
38
  Returns None if input is empty or None.
24
39
 
25
40
  Canonical form:
@@ -28,6 +43,12 @@ def normalize_sonic_snapshot(
28
43
  "rms": float or None,
29
44
  "peak": float or None,
30
45
  "detected_key": str or None,
46
+ "spectral_shape": dict or None,
47
+ "mel_bands": list or None,
48
+ "chroma": dict/list or None,
49
+ "onset": dict or None,
50
+ "novelty": dict or None,
51
+ "loudness": dict or None,
31
52
  "source": str,
32
53
  "normalized_at_ms": int,
33
54
  }
@@ -35,11 +56,12 @@ def normalize_sonic_snapshot(
35
56
  if not raw or not isinstance(raw, dict):
36
57
  return None
37
58
 
38
- bands = raw.get("spectrum") or raw.get("bands")
39
- if not bands:
59
+ bands = raw.get("spectrum") or raw.get("bands") or {}
60
+ has_rich_analyzer_data = any(raw.get(k) is not None for k in _RICH_ANALYZER_KEYS)
61
+ if not bands and not has_rich_analyzer_data:
40
62
  return None
41
63
 
42
- return {
64
+ normalized = {
43
65
  "spectrum": bands,
44
66
  "rms": raw.get("rms"),
45
67
  "peak": raw.get("peak"),
@@ -47,3 +69,10 @@ def normalize_sonic_snapshot(
47
69
  "source": source,
48
70
  "normalized_at_ms": int(time.time() * 1000),
49
71
  }
72
+
73
+ for key in _RICH_ANALYZER_KEYS:
74
+ if key in raw and raw.get(key) is not None:
75
+ out_key = "onset" if key == "onsets" else key
76
+ normalized[out_key] = raw.get(key)
77
+
78
+ return normalized
package/package.json CHANGED
@@ -1,17 +1,17 @@
1
1
  {
2
2
  "name": "livepilot",
3
- "version": "1.26.0",
3
+ "version": "1.26.2",
4
4
  "mcpName": "io.github.dreamrec/livepilot",
5
- "description": "Agentic production system for Ableton Live 12 \u2014 465 tools, 56 domains, 44 semantic moves. Device atlas (5264 devices, 120 enriched, 7 indexes), Splice intelligence (gRPC + GraphQL describe-a-sound + preview + collections + presets), 9-band spectral perception auto-loaded via ensure_analyzer_on_master, Creative Director skill, technique memory, 12 creative intelligence engines",
5
+ "description": "Agentic production system for Ableton Live 12 465 tools, 56 domains, 44 semantic moves. Device atlas (5264 devices, 120 enriched, 7 indexes), Splice intelligence (gRPC + GraphQL describe-a-sound + preview + collections + presets), 9-band spectral perception auto-loaded via ensure_analyzer_on_master, Creative Director skill, technique memory, 12 creative intelligence engines",
6
6
  "author": "Pilot Studio",
7
7
  "license": "BSL-1.1",
8
8
  "type": "commonjs",
9
9
  "bin": {
10
- "livepilot": "./bin/livepilot.js"
10
+ "livepilot": "bin/livepilot.js"
11
11
  },
12
12
  "repository": {
13
13
  "type": "git",
14
- "url": "https://github.com/dreamrec/LivePilot"
14
+ "url": "git+https://github.com/dreamrec/LivePilot.git"
15
15
  },
16
16
  "homepage": "https://github.com/dreamrec/LivePilot",
17
17
  "bugs": {
@@ -47,6 +47,7 @@
47
47
  "files": [
48
48
  "bin/**/*.js",
49
49
  "installer/**/*.js",
50
+ "livepilot/**",
50
51
  "mcp_server/**/*.py",
51
52
  "mcp_server/**/*.json",
52
53
  "mcp_server/**/*.yaml",
@@ -56,6 +57,9 @@
56
57
  "m4l_device/LivePilot_Analyzer.amxd",
57
58
  "m4l_device/LivePilot_Analyzer.adv",
58
59
  "m4l_device/livepilot_bridge.js",
60
+ "m4l_device/LivePilot_Elektron.amxd",
61
+ "m4l_device/LivePilot_Elektron.maxpat",
62
+ "m4l_device/livepilot_elektron_bridge.js",
59
63
  "m4l_device/BUILD_GUIDE.md",
60
64
  "requirements.txt",
61
65
  "README.md",
@@ -64,6 +68,17 @@
64
68
  "server.json",
65
69
  "!**/__pycache__/**",
66
70
  "!**/*.pyc",
67
- "!**/.DS_Store"
71
+ "!**/.DS_Store",
72
+ "!livepilot/skills/livepilot-core/references/device-atlas/synths-m4l.md",
73
+ "!livepilot/skills/livepilot-core/references/device-atlas/plugins-synths.md",
74
+ "!livepilot/skills/livepilot-core/references/device-atlas/utility-and-workflow.md",
75
+ "!livepilot/skills/livepilot-core/references/device-atlas/samples-and-irs.md",
76
+ "!livepilot/skills/livepilot-core/references/device-atlas/presets-by-vibe.md",
77
+ "!livepilot/skills/livepilot-devices/references/m4l-vendor/**",
78
+ "!livepilot/skills/livepilot-devices/references/m4l-depth-pass-findings.md",
79
+ "!livepilot/skills/livepilot-devices/references/m4l-depth-pass-resume.md",
80
+ "!livepilot/skills/livepilot-devices/references/m4l-library-deep.md",
81
+ "!livepilot/skills/livepilot-devices/references/m4l-master-reference.md",
82
+ "!livepilot/skills/livepilot-devices/references/m4l-technique-map.md"
68
83
  ]
69
84
  }
@@ -5,7 +5,7 @@ Entry point for the ControlSurface. Ableton calls create_instance(c_instance)
5
5
  when this script is selected in Preferences > Link, Tempo & MIDI.
6
6
  """
7
7
 
8
- __version__ = "1.26.0"
8
+ __version__ = "1.26.2"
9
9
 
10
10
  from _Framework.ControlSurface import ControlSurface
11
11
  from . import router
@@ -60,6 +60,67 @@ WRITE_COMMANDS = frozenset([
60
60
  "clear_clip_automation",
61
61
  ])
62
62
 
63
+ # Future-safe write detection. WRITE_COMMANDS remains the explicit allow-list
64
+ # for older handlers and readability; the prefix classifier catches newer
65
+ # mutating handlers so they still receive the write timeout and settle delay.
66
+ READ_COMMAND_PREFIXES = ("get_", "list_", "scan_")
67
+ READ_ONLY_COMMANDS = frozenset([
68
+ "ping",
69
+ "reload_handlers",
70
+ ])
71
+ WRITE_COMMAND_PREFIXES = (
72
+ "add_",
73
+ "apply_",
74
+ "arrangement_automation_",
75
+ "assign_",
76
+ "back_to_",
77
+ "capture_",
78
+ "cleanup_",
79
+ "clear_",
80
+ "continue_",
81
+ "copy_",
82
+ "create_",
83
+ "delete_",
84
+ "duplicate_",
85
+ "find_and_load_",
86
+ "fire_",
87
+ "flatten_",
88
+ "force_",
89
+ "freeze_",
90
+ "import_",
91
+ "insert_",
92
+ "jump_",
93
+ "load_",
94
+ "modify_",
95
+ "move_",
96
+ "nudge_",
97
+ "quantize_",
98
+ "randomize_",
99
+ "recall_",
100
+ "remove_",
101
+ "replace_",
102
+ "reset_",
103
+ "set_",
104
+ "start_",
105
+ "stop_",
106
+ "store_",
107
+ "tap_",
108
+ "toggle_",
109
+ "transpose_",
110
+ )
111
+
112
+
113
+ def is_write_command(command_type):
114
+ """Return True if a command is expected to mutate Live state."""
115
+ if command_type in WRITE_COMMANDS:
116
+ return True
117
+ if command_type in READ_ONLY_COMMANDS:
118
+ return False
119
+ if command_type.startswith(READ_COMMAND_PREFIXES):
120
+ return False
121
+ return command_type.startswith(WRITE_COMMAND_PREFIXES)
122
+
123
+
63
124
  # Commands that need longer timeouts (e.g., freeze renders audio)
64
125
  SLOW_WRITE_COMMANDS = frozenset([
65
126
  "freeze_track",
@@ -277,7 +338,7 @@ class LivePilotServer(object):
277
338
  cmd_type = command.get("type", "")
278
339
 
279
340
  # Determine timeout based on read vs write vs slow write
280
- is_write = cmd_type in WRITE_COMMANDS
341
+ is_write = is_write_command(cmd_type)
281
342
  if cmd_type in SLOW_WRITE_COMMANDS:
282
343
  timeout = 35
283
344
  elif is_write:
@@ -343,7 +404,7 @@ class LivePilotServer(object):
343
404
  return
344
405
 
345
406
  cmd_type = command.get("type", "")
346
- is_write = cmd_type in WRITE_COMMANDS
407
+ is_write = is_write_command(cmd_type)
347
408
 
348
409
  try:
349
410
  song = self._cs.song()
package/requirements.txt CHANGED
@@ -1,6 +1,6 @@
1
1
  # LivePilot MCP Server dependencies
2
- numpy>=2.4.4
3
- fastmcp>=3.2.4,<3.3.0 # pinned upper bound — _get_all_tools() accesses private internals
2
+ numpy>=2.4.6
3
+ fastmcp>=3.3.1,<3.4.0 # pinned upper bound — _get_all_tools() accesses private internals
4
4
  midiutil>=1.2.1
5
5
  pretty_midi>=0.2.11
6
6
  # v1.8 Perception Layer (offline analysis)
@@ -13,7 +13,7 @@ mutagen>=1.47.0
13
13
  # falls back to the SQLite sounds.db which only returns locally downloaded
14
14
  # samples (see docs/2026-04-14-bugs-discovered.md — P0-2).
15
15
  grpcio>=1.80.0
16
- protobuf>=7.34.1
16
+ protobuf>=7.35.0
17
17
 
18
18
  # Known benign warning during install:
19
19
  # ERROR: pip's dependency resolver does not currently take into account
package/server.json CHANGED
@@ -1,17 +1,17 @@
1
1
  {
2
2
  "$schema": "https://static.modelcontextprotocol.io/schemas/2025-12-11/server.schema.json",
3
3
  "name": "io.github.dreamrec/livepilot",
4
- "description": "465-tool agentic MCP production system for Ableton Live 12 \u2014 55 domains, 44 semantic moves, device atlas (5264 devices), Splice intelligence (gRPC + GraphQL), 9-band spectral perception auto-loaded, Creative Director skill, technique memory, 12 creative engines",
4
+ "description": "465-tool agentic MCP production system for Ableton Live 12 \u2014 56 domains, 44 semantic moves, device atlas (5264 devices), Splice intelligence (gRPC + GraphQL), 9-band spectral perception auto-loaded, Creative Director skill, technique memory, 12 creative engines",
5
5
  "repository": {
6
6
  "url": "https://github.com/dreamrec/LivePilot",
7
7
  "source": "github"
8
8
  },
9
- "version": "1.26.0",
9
+ "version": "1.26.2",
10
10
  "packages": [
11
11
  {
12
12
  "registryType": "npm",
13
13
  "identifier": "livepilot",
14
- "version": "1.26.0",
14
+ "version": "1.26.2",
15
15
  "transport": {
16
16
  "type": "stdio"
17
17
  }