livepilot 1.23.0 → 1.23.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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,22 @@
1
1
  # Changelog
2
2
 
3
+ ## v1.23.2 — 2026-04-25
4
+
5
+ ### Fixed
6
+ - M4L bridge `.amxd` ping version now matches the release version. v1.23.1 shipped with the frozen `LivePilot_Analyzer.amxd` still embedding `"version": "1.23.0"` (the m4l_device files weren't bumped during the v1.23.1 patch), which tripped the `amxd-freeze-drift` CI guard introduced after past releases lost to the same drift. In-place binary patch at offsets 32653 + 6691677 (same byte count, file size unchanged at 6,754,576 bytes), plus source bumps in `livepilot_bridge.js` (`var VERSION`) and `LivePilot_Analyzer.maxpat` (UI label) so the next freeze starts in sync.
7
+
8
+ ### Notes
9
+ - Bridge functionality is unchanged from v1.23.1. This is a metadata-only patch: end users who looked at the bridge UI in v1.23.1 saw "1.23.0" — that's now corrected.
10
+ - All distribution channels (npm, GitHub release MCPB, marketplace mirror) are re-published from this commit.
11
+
12
+ ## v1.23.1 — 2026-04-25
13
+
14
+ ### Fixed
15
+ - `extension_atlas_search` multi-word queries returned 0 hits because the search did literal-substring matching. `"sophie ponyboy"` failed to match `"SOPHIE — Ponyboy kick"` because of the em-dash separator. Now: query is tokenized on whitespace, each token must match somewhere (AND semantics), per-token scores sum for ranking. Single-token queries collapse to the original behavior — fully backwards-compatible.
16
+
17
+ ### Tests
18
+ - 3 new tests covering multi-token AND, em-dash separator handling, per-token score aggregation.
19
+
3
20
  ## v1.23.0 — 2026-04-25
4
21
 
5
22
  ### Added
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.23.0";
37
+ var VERSION = "1.23.2";
38
38
 
39
39
  // ── State ──────────────────────────────────────────────────────────────────
40
40
 
@@ -1,2 +1,2 @@
1
1
  """LivePilot MCP Server — bridges MCP protocol to Ableton Live."""
2
- __version__ = "1.23.0"
2
+ __version__ = "1.23.2"
@@ -91,14 +91,20 @@ class OverlayIndex:
91
91
  def search(self, query: str, namespace: Optional[str] = None,
92
92
  entity_type: Optional[str] = None,
93
93
  limit: int = 10) -> list[OverlayEntry]:
94
- """Weighted substring search.
94
+ """Weighted substring search with whitespace-tokenized AND semantics.
95
95
 
96
- Scores per entry:
97
- +1000 if query == entity_id (case-insensitive exact)
96
+ The query is split on whitespace into tokens. Each token is scored
97
+ against each entry independently:
98
+ +1000 if token == entity_id (case-insensitive exact match)
98
99
  +100 per substring hit in name
99
100
  +50 per substring hit in tag or artist
100
101
  +10 per substring hit in description
101
102
 
103
+ An entry matches only if EVERY token scores > 0 somewhere (AND
104
+ semantics — prevents 'sophie ponyboy' from matching unrelated
105
+ entries that contain only one of the two words). The entry's
106
+ final score is the sum across all tokens.
107
+
102
108
  Sorts by descending score, then by entity_id for stable ties.
103
109
  Filters by namespace and/or entity_type if provided.
104
110
  Empty query returns empty list.
@@ -106,6 +112,9 @@ class OverlayIndex:
106
112
  q = (query or "").strip().lower()
107
113
  if not q:
108
114
  return []
115
+ tokens = q.split()
116
+ if not tokens:
117
+ return []
109
118
 
110
119
  scored: list[tuple[int, str, OverlayEntry]] = []
111
120
  for entry in self._entries.values():
@@ -113,21 +122,33 @@ class OverlayIndex:
113
122
  continue
114
123
  if entity_type is not None and entry.entity_type != entity_type:
115
124
  continue
116
- score = 0
117
- if entry.entity_id.lower() == q:
118
- score += 1000
119
- if q in entry.name.lower():
120
- score += 100
121
- for tag in entry.tags:
122
- if q in str(tag).lower():
123
- score += 50
124
- for artist in entry.artists:
125
- if q in str(artist).lower():
126
- score += 50
127
- if q in entry.description.lower():
128
- score += 10
129
- if score > 0:
130
- scored.append((score, entry.entity_id, entry))
125
+
126
+ name_lower = entry.name.lower()
127
+ entity_id_lower = entry.entity_id.lower()
128
+ description_lower = entry.description.lower()
129
+ tags_lower = [str(t).lower() for t in entry.tags]
130
+ artists_lower = [str(a).lower() for a in entry.artists]
131
+
132
+ token_scores = []
133
+ for tok in tokens:
134
+ s = 0
135
+ if entity_id_lower == tok:
136
+ s += 1000
137
+ if tok in name_lower:
138
+ s += 100
139
+ for tag in tags_lower:
140
+ if tok in tag:
141
+ s += 50
142
+ for artist in artists_lower:
143
+ if tok in artist:
144
+ s += 50
145
+ if tok in description_lower:
146
+ s += 10
147
+ token_scores.append(s)
148
+
149
+ # AND semantics — every token must match somewhere
150
+ if all(s > 0 for s in token_scores):
151
+ scored.append((sum(token_scores), entry.entity_id, entry))
131
152
 
132
153
  scored.sort(key=lambda triple: (-triple[0], triple[1]))
133
154
  return [entry for (_, _, entry) in scored[:max(0, limit)]]
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "livepilot",
3
- "version": "1.23.0",
3
+ "version": "1.23.2",
4
4
  "mcpName": "io.github.dreamrec/livepilot",
5
5
  "description": "Agentic production system for Ableton Live 12 — 433 tools, 53 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",
@@ -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.23.0"
8
+ __version__ = "1.23.2"
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.23.0",
9
+ "version": "1.23.2",
10
10
  "packages": [
11
11
  {
12
12
  "registryType": "npm",
13
13
  "identifier": "livepilot",
14
- "version": "1.23.0",
14
+ "version": "1.23.1",
15
15
  "transport": {
16
16
  "type": "stdio"
17
17
  }