livepilot 1.17.3 → 1.17.4

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 CHANGED
@@ -1,5 +1,53 @@
1
1
  # Changelog
2
2
 
3
+ ## 1.17.4 — Shape cleanup + memory probe (April 23 2026)
4
+
5
+ ### Fixed
6
+
7
+ - **`get_session_kernel` now probes the memory store** instead of
8
+ hardcoding `memory_ok=True` (`mcp_server/runtime/tools.py`). If the
9
+ underlying technique store raises on `list_techniques` (disk full,
10
+ corrupted index, permissions error), the kernel previously still
11
+ reported memory as available to orchestration planners. Same
12
+ truth-gap class as the v1.17.3 web/flucoma fix — should have been
13
+ caught by the same review pass. Now probed the same way
14
+ `get_capability_state` does, wrapped in try/except.
15
+ - **`capability_state` flat shape** in session kernel
16
+ (`mcp_server/runtime/tools.py`): `state.to_dict()` wraps its output as
17
+ `{"capability_state": {...}}` — that's the right shape for the
18
+ standalone `get_capability_state` tool, but when stored on the kernel
19
+ it produced the ugly double-nested
20
+ `kernel["capability_state"]["capability_state"]["domains"]`. v1.17.3
21
+ probe tests worked around it with defensive
22
+ `outer.get("capability_state", outer)`. Fix: unwrap the outer key
23
+ once before passing to `build_session_kernel`. Consumer path is
24
+ now `kernel["capability_state"]["domains"]` directly. Standalone
25
+ `get_capability_state` return shape unchanged.
26
+
27
+ ### Tests
28
+
29
+ - 4 new TDD tests in `tests/test_runtime_capability_probes.py`:
30
+ - memory probe raises → kernel reports memory unavailable
31
+ - memory probe succeeds → kernel reports available
32
+ - kernel's capability_state has no nested `capability_state` key
33
+ - end-to-end flat access without defensive fallbacks
34
+ - Consumer updates:
35
+ - `test_session_kernel.py:203` — removed extra level
36
+ - `test_runtime_capability_probes.py` (4 places) — removed
37
+ defensive `outer.get('capability_state', outer)` pattern now that
38
+ the shape is known-flat
39
+
40
+ 2722 → 2726 passing.
41
+
42
+ ### Known follow-up
43
+
44
+ Audit while writing this release flagged a third bug in
45
+ `mcp_server/runtime/safety_kernel.py:244`: the safety kernel reads
46
+ `capability_state.get("mode", "normal")` but the actual shape uses
47
+ `overall_mode`, not `mode`. The `.get(..., "normal")` default silently
48
+ falls back, so `read_only` mode gating never kicks in. Separate fix,
49
+ out of scope for this release.
50
+
3
51
  ## 1.17.3 — Truth-gap remediation, for real (April 23 2026)
4
52
 
5
53
  ### Fixed
Binary file
@@ -95,7 +95,7 @@ function anything() {
95
95
  function dispatch(cmd, args) {
96
96
  switch(cmd) {
97
97
  case "ping":
98
- send_response({"ok": true, "version": "1.17.3"});
98
+ send_response({"ok": true, "version": "1.17.4"});
99
99
  break;
100
100
  case "get_params":
101
101
  cmd_get_params(args);
@@ -1,2 +1,2 @@
1
1
  """LivePilot MCP Server — bridges MCP protocol to Ableton Live."""
2
- __version__ = "1.17.3"
2
+ __version__ = "1.17.4"
@@ -185,11 +185,21 @@ def get_session_kernel(
185
185
  web_ok = _probe_web()
186
186
  flucoma_ok = _probe_flucoma()
187
187
 
188
+ # v1.17.4: probe memory the same way too. Previously memory_ok=True was
189
+ # hardcoded — if the store raised, the kernel still reported memory
190
+ # available. Same truth-gap class as the v1.17.3 web/flucoma fix.
191
+ memory_ok = False
192
+ try:
193
+ _memory_store.list_techniques(limit=1)
194
+ memory_ok = True
195
+ except Exception as exc:
196
+ logger.debug("get_session_kernel memory probe failed: %s", exc)
197
+
188
198
  state = build_capability_state(
189
199
  session_ok=session_ok,
190
200
  analyzer_ok=analyzer_ok,
191
201
  analyzer_fresh=analyzer_fresh,
192
- memory_ok=True,
202
+ memory_ok=memory_ok,
193
203
  web_ok=web_ok,
194
204
  flucoma_ok=flucoma_ok,
195
205
  )
@@ -248,9 +258,18 @@ def get_session_kernel(
248
258
  except Exception as e:
249
259
  kernel_warnings.append(f"session_memory_unavailable: {e}")
250
260
 
261
+ # v1.17.4: state.to_dict() wraps its output as {"capability_state": {...}}
262
+ # because that shape is what the standalone get_capability_state tool
263
+ # returns. When building the session kernel, that wrapper becomes the
264
+ # ugly double-nested kernel["capability_state"]["capability_state"]["domains"]
265
+ # path. Unwrap once here so kernel consumers get
266
+ # kernel["capability_state"]["domains"] directly.
267
+ _cap_dict = state.to_dict()
268
+ _cap_flat = _cap_dict.get("capability_state", _cap_dict)
269
+
251
270
  kernel = build_session_kernel(
252
271
  session_info=session_info,
253
- capability_state=state.to_dict(),
272
+ capability_state=_cap_flat,
254
273
  request_text=request_text,
255
274
  mode=mode,
256
275
  aggression=aggression,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "livepilot",
3
- "version": "1.17.3",
3
+ "version": "1.17.4",
4
4
  "mcpName": "io.github.dreamrec/livepilot",
5
5
  "description": "Agentic production system for Ableton Live 12 — 427 tools, 52 domains. Device atlas (1305 devices), sample engine (Splice + browser + filesystem), auto-composition, spectral perception, technique memory, creative intelligence (12 engines)",
6
6
  "author": "Pilot Studio",
@@ -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.17.3"
8
+ __version__ = "1.17.4"
9
9
 
10
10
  from _Framework.ControlSurface import ControlSurface
11
11
  from . import router
package/server.json CHANGED
@@ -6,12 +6,12 @@
6
6
  "url": "https://github.com/dreamrec/LivePilot",
7
7
  "source": "github"
8
8
  },
9
- "version": "1.17.3",
9
+ "version": "1.17.4",
10
10
  "packages": [
11
11
  {
12
12
  "registryType": "npm",
13
13
  "identifier": "livepilot",
14
- "version": "1.17.3",
14
+ "version": "1.17.4",
15
15
  "transport": {
16
16
  "type": "stdio"
17
17
  }