@kernel.chat/kbot 3.49.0 → 3.51.0
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/dist/agent-teams.d.ts.map +1 -1
- package/dist/agent-teams.js +7 -0
- package/dist/agent-teams.js.map +1 -1
- package/dist/agents/producer.d.ts +21 -0
- package/dist/agents/producer.d.ts.map +1 -0
- package/dist/agents/producer.js +139 -0
- package/dist/agents/producer.js.map +1 -0
- package/dist/agents/specialists.d.ts.map +1 -1
- package/dist/agents/specialists.js +19 -0
- package/dist/agents/specialists.js.map +1 -1
- package/dist/completions.d.ts.map +1 -1
- package/dist/completions.js +1 -0
- package/dist/completions.js.map +1 -1
- package/dist/integrations/ableton-osc.d.ts +146 -0
- package/dist/integrations/ableton-osc.d.ts.map +1 -0
- package/dist/integrations/ableton-osc.js +590 -0
- package/dist/integrations/ableton-osc.js.map +1 -0
- package/dist/learned-router.d.ts.map +1 -1
- package/dist/learned-router.js +20 -0
- package/dist/learned-router.js.map +1 -1
- package/dist/tools/ableton-knowledge.d.ts +2 -0
- package/dist/tools/ableton-knowledge.d.ts.map +1 -0
- package/dist/tools/ableton-knowledge.js +419 -0
- package/dist/tools/ableton-knowledge.js.map +1 -0
- package/dist/tools/ableton.d.ts +2 -0
- package/dist/tools/ableton.d.ts.map +1 -0
- package/dist/tools/ableton.js +1023 -0
- package/dist/tools/ableton.js.map +1 -0
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +2 -0
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/music-theory.d.ts +175 -0
- package/dist/tools/music-theory.d.ts.map +1 -0
- package/dist/tools/music-theory.js +1020 -0
- package/dist/tools/music-theory.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,590 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ableton-osc.ts — Zero-dependency OSC over UDP transport for AbletonOSC
|
|
3
|
+
*
|
|
4
|
+
* Implements OSC 1.0 binary protocol using only Node.js built-ins (dgram, buffer).
|
|
5
|
+
* Communicates with https://github.com/ideoforms/AbletonOSC running inside Ableton Live.
|
|
6
|
+
*
|
|
7
|
+
* Default ports:
|
|
8
|
+
* Send to Ableton: UDP 11000
|
|
9
|
+
* Receive from Ableton: UDP 11001
|
|
10
|
+
*/
|
|
11
|
+
import * as dgram from 'node:dgram';
|
|
12
|
+
import { Buffer } from 'node:buffer';
|
|
13
|
+
// ---------------------------------------------------------------------------
|
|
14
|
+
// OSC Binary Protocol — Encoding
|
|
15
|
+
// ---------------------------------------------------------------------------
|
|
16
|
+
/**
|
|
17
|
+
* Encode a string as an OSC string: null-terminated, padded to 4-byte boundary.
|
|
18
|
+
*/
|
|
19
|
+
export function encodeOscString(str) {
|
|
20
|
+
const strBytes = Buffer.from(str, 'utf-8');
|
|
21
|
+
// Need at least one null terminator, then pad to 4-byte boundary
|
|
22
|
+
const padded = 4 - ((strBytes.length + 1) % 4);
|
|
23
|
+
const totalNulls = padded === 4 ? 1 : padded + 1;
|
|
24
|
+
const buf = Buffer.alloc(strBytes.length + totalNulls);
|
|
25
|
+
strBytes.copy(buf, 0);
|
|
26
|
+
// Remaining bytes are already 0x00 from Buffer.alloc
|
|
27
|
+
return buf;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Encode a blob as OSC blob: int32 size prefix + data + padding to 4-byte boundary.
|
|
31
|
+
*/
|
|
32
|
+
function encodeOscBlob(data) {
|
|
33
|
+
const padding = (4 - (data.length % 4)) % 4;
|
|
34
|
+
const buf = Buffer.alloc(4 + data.length + padding);
|
|
35
|
+
buf.writeInt32BE(data.length, 0);
|
|
36
|
+
data.copy(buf, 4);
|
|
37
|
+
return buf;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Encode a complete OSC message: address + type tag string + argument data.
|
|
41
|
+
*/
|
|
42
|
+
export function encodeOscMessage(address, args) {
|
|
43
|
+
const addressBuf = encodeOscString(address);
|
|
44
|
+
// Build type tag string: comma prefix + one char per arg
|
|
45
|
+
const typeTag = ',' + args.map((a) => a.type).join('');
|
|
46
|
+
const typeTagBuf = encodeOscString(typeTag);
|
|
47
|
+
// Encode each argument
|
|
48
|
+
const argBuffers = [];
|
|
49
|
+
for (const arg of args) {
|
|
50
|
+
switch (arg.type) {
|
|
51
|
+
case 'i': {
|
|
52
|
+
const buf = Buffer.alloc(4);
|
|
53
|
+
buf.writeInt32BE(arg.value, 0);
|
|
54
|
+
argBuffers.push(buf);
|
|
55
|
+
break;
|
|
56
|
+
}
|
|
57
|
+
case 'f': {
|
|
58
|
+
const buf = Buffer.alloc(4);
|
|
59
|
+
buf.writeFloatBE(arg.value, 0);
|
|
60
|
+
argBuffers.push(buf);
|
|
61
|
+
break;
|
|
62
|
+
}
|
|
63
|
+
case 's': {
|
|
64
|
+
argBuffers.push(encodeOscString(arg.value));
|
|
65
|
+
break;
|
|
66
|
+
}
|
|
67
|
+
case 'b': {
|
|
68
|
+
argBuffers.push(encodeOscBlob(arg.value));
|
|
69
|
+
break;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
return Buffer.concat([addressBuf, typeTagBuf, ...argBuffers]);
|
|
74
|
+
}
|
|
75
|
+
// ---------------------------------------------------------------------------
|
|
76
|
+
// OSC Binary Protocol — Decoding
|
|
77
|
+
// ---------------------------------------------------------------------------
|
|
78
|
+
/**
|
|
79
|
+
* Read a null-terminated, 4-byte-aligned string from a buffer at the given offset.
|
|
80
|
+
* Returns the decoded string and the new offset after the padded string.
|
|
81
|
+
*/
|
|
82
|
+
function readOscString(buf, offset) {
|
|
83
|
+
// Find the null terminator
|
|
84
|
+
let end = offset;
|
|
85
|
+
while (end < buf.length && buf[end] !== 0) {
|
|
86
|
+
end++;
|
|
87
|
+
}
|
|
88
|
+
const str = buf.toString('utf-8', offset, end);
|
|
89
|
+
// Advance past null terminator(s) to 4-byte boundary
|
|
90
|
+
const totalLen = end - offset + 1; // includes one null
|
|
91
|
+
const padded = totalLen + ((4 - (totalLen % 4)) % 4);
|
|
92
|
+
return [str, offset + padded];
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Read an OSC blob from a buffer at the given offset.
|
|
96
|
+
* Returns the blob data and the new offset.
|
|
97
|
+
*/
|
|
98
|
+
function readOscBlob(buf, offset) {
|
|
99
|
+
const size = buf.readInt32BE(offset);
|
|
100
|
+
offset += 4;
|
|
101
|
+
const data = buf.subarray(offset, offset + size);
|
|
102
|
+
offset += size;
|
|
103
|
+
const padding = (4 - (size % 4)) % 4;
|
|
104
|
+
offset += padding;
|
|
105
|
+
return [Buffer.from(data), offset];
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Decode a complete OSC message from a raw UDP buffer.
|
|
109
|
+
*/
|
|
110
|
+
export function decodeOscMessage(buf) {
|
|
111
|
+
if (buf.length < 4) {
|
|
112
|
+
throw new Error('OSC message too short');
|
|
113
|
+
}
|
|
114
|
+
let offset = 0;
|
|
115
|
+
// Read address
|
|
116
|
+
const [address, afterAddress] = readOscString(buf, offset);
|
|
117
|
+
offset = afterAddress;
|
|
118
|
+
if (!address.startsWith('/')) {
|
|
119
|
+
throw new Error(`Invalid OSC address: ${address}`);
|
|
120
|
+
}
|
|
121
|
+
// Read type tag string (optional — some messages have no args)
|
|
122
|
+
const args = [];
|
|
123
|
+
if (offset >= buf.length) {
|
|
124
|
+
return { address, args };
|
|
125
|
+
}
|
|
126
|
+
// Check if there is a type tag string (starts with ',')
|
|
127
|
+
if (buf[offset] !== 0x2c /* ',' */) {
|
|
128
|
+
// No type tag string — return address only
|
|
129
|
+
return { address, args };
|
|
130
|
+
}
|
|
131
|
+
const [typeTag, afterTypeTag] = readOscString(buf, offset);
|
|
132
|
+
offset = afterTypeTag;
|
|
133
|
+
// Parse each argument according to type tags (skip the leading comma)
|
|
134
|
+
for (let i = 1; i < typeTag.length; i++) {
|
|
135
|
+
const tag = typeTag[i];
|
|
136
|
+
switch (tag) {
|
|
137
|
+
case 'i': {
|
|
138
|
+
if (offset + 4 > buf.length)
|
|
139
|
+
throw new Error('OSC buffer underflow reading int32');
|
|
140
|
+
const value = buf.readInt32BE(offset);
|
|
141
|
+
offset += 4;
|
|
142
|
+
args.push({ type: 'i', value });
|
|
143
|
+
break;
|
|
144
|
+
}
|
|
145
|
+
case 'f': {
|
|
146
|
+
if (offset + 4 > buf.length)
|
|
147
|
+
throw new Error('OSC buffer underflow reading float32');
|
|
148
|
+
const value = buf.readFloatBE(offset);
|
|
149
|
+
offset += 4;
|
|
150
|
+
args.push({ type: 'f', value });
|
|
151
|
+
break;
|
|
152
|
+
}
|
|
153
|
+
case 's': {
|
|
154
|
+
const [value, next] = readOscString(buf, offset);
|
|
155
|
+
offset = next;
|
|
156
|
+
args.push({ type: 's', value });
|
|
157
|
+
break;
|
|
158
|
+
}
|
|
159
|
+
case 'b': {
|
|
160
|
+
const [value, next] = readOscBlob(buf, offset);
|
|
161
|
+
offset = next;
|
|
162
|
+
args.push({ type: 'b', value });
|
|
163
|
+
break;
|
|
164
|
+
}
|
|
165
|
+
case 'T': // OSC True — skip, no data bytes
|
|
166
|
+
case 'F': // OSC False — skip, no data bytes
|
|
167
|
+
case 'N': // OSC Nil — skip
|
|
168
|
+
break;
|
|
169
|
+
default:
|
|
170
|
+
// Unknown type tag — we can't know the size, so stop parsing
|
|
171
|
+
return { address, args };
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
return { address, args };
|
|
175
|
+
}
|
|
176
|
+
// ---------------------------------------------------------------------------
|
|
177
|
+
// Convenience: auto-detect argument types
|
|
178
|
+
// ---------------------------------------------------------------------------
|
|
179
|
+
/**
|
|
180
|
+
* Auto-detect OSC argument types from plain JS values.
|
|
181
|
+
*
|
|
182
|
+
* - Integers (no fractional part, safe integer range) become 'i'
|
|
183
|
+
* - Other numbers become 'f'
|
|
184
|
+
* - Strings become 's'
|
|
185
|
+
*/
|
|
186
|
+
export function oscArgs(...values) {
|
|
187
|
+
return values.map((v) => {
|
|
188
|
+
if (typeof v === 'string') {
|
|
189
|
+
return { type: 's', value: v };
|
|
190
|
+
}
|
|
191
|
+
if (Number.isInteger(v) && Math.abs(v) <= 0x7fffffff) {
|
|
192
|
+
return { type: 'i', value: v };
|
|
193
|
+
}
|
|
194
|
+
return { type: 'f', value: v };
|
|
195
|
+
});
|
|
196
|
+
}
|
|
197
|
+
// ---------------------------------------------------------------------------
|
|
198
|
+
// AbletonOSC Client
|
|
199
|
+
// ---------------------------------------------------------------------------
|
|
200
|
+
export class AbletonOSC {
|
|
201
|
+
static instance = null;
|
|
202
|
+
sendSocket = null;
|
|
203
|
+
recvSocket = null;
|
|
204
|
+
connected = false;
|
|
205
|
+
pending = new Map();
|
|
206
|
+
listeners = new Map();
|
|
207
|
+
recvPort = 11001;
|
|
208
|
+
cleanupRegistered = false;
|
|
209
|
+
static SEND_PORT = 11000;
|
|
210
|
+
static RECV_PORT = 11001;
|
|
211
|
+
static HOST = '127.0.0.1';
|
|
212
|
+
static TIMEOUT = 3000;
|
|
213
|
+
static MAX_PORT_RETRIES = 3;
|
|
214
|
+
/** Safe UDP payload size — well under the 65507 byte UDP limit */
|
|
215
|
+
static MAX_UDP_PAYLOAD = 8192;
|
|
216
|
+
constructor() { }
|
|
217
|
+
/**
|
|
218
|
+
* Get the singleton AbletonOSC instance.
|
|
219
|
+
*/
|
|
220
|
+
static getInstance() {
|
|
221
|
+
if (!AbletonOSC.instance) {
|
|
222
|
+
AbletonOSC.instance = new AbletonOSC();
|
|
223
|
+
}
|
|
224
|
+
return AbletonOSC.instance;
|
|
225
|
+
}
|
|
226
|
+
/**
|
|
227
|
+
* Connect to AbletonOSC. Creates UDP sockets, binds the receive socket,
|
|
228
|
+
* and verifies Ableton is responding via /live/test.
|
|
229
|
+
*
|
|
230
|
+
* Returns true if Ableton responded, false on timeout.
|
|
231
|
+
*/
|
|
232
|
+
async connect() {
|
|
233
|
+
if (this.connected && this.sendSocket && this.recvSocket) {
|
|
234
|
+
// Already connected — verify with a quick test
|
|
235
|
+
try {
|
|
236
|
+
await this.query('/live/test');
|
|
237
|
+
return true;
|
|
238
|
+
}
|
|
239
|
+
catch {
|
|
240
|
+
// Connection stale, reconnect below
|
|
241
|
+
this.closeSocketsSilently();
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
this.closeSocketsSilently();
|
|
245
|
+
// Create send socket (unbound — just for sending)
|
|
246
|
+
this.sendSocket = dgram.createSocket('udp4');
|
|
247
|
+
this.sendSocket.on('error', (err) => {
|
|
248
|
+
// Send socket errors are non-fatal; queries will timeout
|
|
249
|
+
if (err.code !== 'ERR_SOCKET_DGRAM_NOT_RUNNING') {
|
|
250
|
+
// Silently ignore — will surface as query timeouts
|
|
251
|
+
}
|
|
252
|
+
});
|
|
253
|
+
// Create receive socket with EADDRINUSE retry
|
|
254
|
+
const bound = await this.bindRecvSocket();
|
|
255
|
+
if (!bound) {
|
|
256
|
+
this.closeSocketsSilently();
|
|
257
|
+
return false;
|
|
258
|
+
}
|
|
259
|
+
// Register process cleanup (once)
|
|
260
|
+
if (!this.cleanupRegistered) {
|
|
261
|
+
this.cleanupRegistered = true;
|
|
262
|
+
const cleanup = () => {
|
|
263
|
+
try {
|
|
264
|
+
this.disconnect();
|
|
265
|
+
}
|
|
266
|
+
catch {
|
|
267
|
+
// Best-effort cleanup
|
|
268
|
+
}
|
|
269
|
+
};
|
|
270
|
+
process.on('exit', cleanup);
|
|
271
|
+
process.on('SIGINT', cleanup);
|
|
272
|
+
process.on('SIGTERM', cleanup);
|
|
273
|
+
}
|
|
274
|
+
// Verify Ableton is alive
|
|
275
|
+
try {
|
|
276
|
+
await this.query('/live/test');
|
|
277
|
+
this.connected = true;
|
|
278
|
+
return true;
|
|
279
|
+
}
|
|
280
|
+
catch {
|
|
281
|
+
this.closeSocketsSilently();
|
|
282
|
+
return false;
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
/**
|
|
286
|
+
* Bind the receive socket with EADDRINUSE fallback.
|
|
287
|
+
* Tries RECV_PORT, then RECV_PORT+1, RECV_PORT+2, etc.
|
|
288
|
+
*/
|
|
289
|
+
async bindRecvSocket() {
|
|
290
|
+
for (let attempt = 0; attempt < AbletonOSC.MAX_PORT_RETRIES; attempt++) {
|
|
291
|
+
const port = AbletonOSC.RECV_PORT + attempt;
|
|
292
|
+
try {
|
|
293
|
+
await this.tryBindRecv(port);
|
|
294
|
+
this.recvPort = port;
|
|
295
|
+
return true;
|
|
296
|
+
}
|
|
297
|
+
catch (err) {
|
|
298
|
+
const code = err.code;
|
|
299
|
+
if (code === 'EADDRINUSE') {
|
|
300
|
+
// Port in use — try next one
|
|
301
|
+
continue;
|
|
302
|
+
}
|
|
303
|
+
// Unexpected error — stop
|
|
304
|
+
return false;
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
return false;
|
|
308
|
+
}
|
|
309
|
+
tryBindRecv(port) {
|
|
310
|
+
return new Promise((resolve, reject) => {
|
|
311
|
+
const socket = dgram.createSocket({ type: 'udp4', reuseAddr: false });
|
|
312
|
+
const onError = (err) => {
|
|
313
|
+
socket.removeListener('listening', onListening);
|
|
314
|
+
try {
|
|
315
|
+
socket.close();
|
|
316
|
+
}
|
|
317
|
+
catch {
|
|
318
|
+
// ignore
|
|
319
|
+
}
|
|
320
|
+
reject(err);
|
|
321
|
+
};
|
|
322
|
+
const onListening = () => {
|
|
323
|
+
socket.removeListener('error', onError);
|
|
324
|
+
// Set up message handler
|
|
325
|
+
socket.on('message', (msg) => {
|
|
326
|
+
this.handleMessage(msg);
|
|
327
|
+
});
|
|
328
|
+
socket.on('error', () => {
|
|
329
|
+
// Runtime errors after successful bind — mark disconnected
|
|
330
|
+
this.connected = false;
|
|
331
|
+
});
|
|
332
|
+
this.recvSocket = socket;
|
|
333
|
+
resolve();
|
|
334
|
+
};
|
|
335
|
+
socket.once('error', onError);
|
|
336
|
+
socket.once('listening', onListening);
|
|
337
|
+
socket.bind(port, AbletonOSC.HOST);
|
|
338
|
+
});
|
|
339
|
+
}
|
|
340
|
+
/**
|
|
341
|
+
* Close sockets without throwing.
|
|
342
|
+
*/
|
|
343
|
+
closeSocketsSilently() {
|
|
344
|
+
this.connected = false;
|
|
345
|
+
if (this.sendSocket) {
|
|
346
|
+
try {
|
|
347
|
+
this.sendSocket.close();
|
|
348
|
+
}
|
|
349
|
+
catch {
|
|
350
|
+
// ignore
|
|
351
|
+
}
|
|
352
|
+
this.sendSocket = null;
|
|
353
|
+
}
|
|
354
|
+
if (this.recvSocket) {
|
|
355
|
+
try {
|
|
356
|
+
this.recvSocket.close();
|
|
357
|
+
}
|
|
358
|
+
catch {
|
|
359
|
+
// ignore
|
|
360
|
+
}
|
|
361
|
+
this.recvSocket = null;
|
|
362
|
+
}
|
|
363
|
+
// Reject all pending queries
|
|
364
|
+
for (const queue of this.pending.values()) {
|
|
365
|
+
for (const p of queue) {
|
|
366
|
+
clearTimeout(p.timer);
|
|
367
|
+
p.reject(new Error('AbletonOSC: connection closed'));
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
this.pending.clear();
|
|
371
|
+
}
|
|
372
|
+
/**
|
|
373
|
+
* Disconnect from AbletonOSC. Closes both sockets and clears all state.
|
|
374
|
+
*/
|
|
375
|
+
disconnect() {
|
|
376
|
+
this.closeSocketsSilently();
|
|
377
|
+
this.listeners.clear();
|
|
378
|
+
}
|
|
379
|
+
/**
|
|
380
|
+
* Check if currently connected to Ableton.
|
|
381
|
+
*/
|
|
382
|
+
isConnected() {
|
|
383
|
+
return this.connected;
|
|
384
|
+
}
|
|
385
|
+
/**
|
|
386
|
+
* Fire-and-forget: send an OSC message to Ableton.
|
|
387
|
+
*/
|
|
388
|
+
send(address, ...args) {
|
|
389
|
+
if (!this.sendSocket) {
|
|
390
|
+
throw new Error('AbletonOSC: not connected. Call connect() first.');
|
|
391
|
+
}
|
|
392
|
+
const msg = encodeOscMessage(address, oscArgs(...args));
|
|
393
|
+
this.sendRaw(msg);
|
|
394
|
+
}
|
|
395
|
+
/**
|
|
396
|
+
* Send a raw encoded OSC buffer. Handles chunking if needed.
|
|
397
|
+
*/
|
|
398
|
+
sendRaw(msg) {
|
|
399
|
+
if (!this.sendSocket)
|
|
400
|
+
return;
|
|
401
|
+
// UDP has a hard limit of 65507 bytes. We stay well under.
|
|
402
|
+
// If a message somehow exceeds our safe limit, send it anyway —
|
|
403
|
+
// the OS will fragment or reject it, and we'll get a timeout on the query.
|
|
404
|
+
this.sendSocket.send(msg, 0, msg.length, AbletonOSC.SEND_PORT, AbletonOSC.HOST, (err) => {
|
|
405
|
+
if (err) {
|
|
406
|
+
// Send errors surface as query timeouts; nothing to do here
|
|
407
|
+
}
|
|
408
|
+
});
|
|
409
|
+
}
|
|
410
|
+
/**
|
|
411
|
+
* Send an OSC message and wait for a response on the same address.
|
|
412
|
+
*
|
|
413
|
+
* AbletonOSC convention: queries use addresses like /live/song/get/tempo
|
|
414
|
+
* and the response arrives on the same address.
|
|
415
|
+
*
|
|
416
|
+
* Includes one auto-reconnect attempt on failure.
|
|
417
|
+
*/
|
|
418
|
+
async query(address, ...args) {
|
|
419
|
+
try {
|
|
420
|
+
return await this.queryOnce(address, ...args);
|
|
421
|
+
}
|
|
422
|
+
catch (err) {
|
|
423
|
+
// If not connected or timed out, try one reconnect
|
|
424
|
+
if (this.connected) {
|
|
425
|
+
// Was connected but query failed — try reconnecting
|
|
426
|
+
this.closeSocketsSilently();
|
|
427
|
+
const reconnected = await this.connect();
|
|
428
|
+
if (reconnected) {
|
|
429
|
+
return await this.queryOnce(address, ...args);
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
throw err;
|
|
433
|
+
}
|
|
434
|
+
}
|
|
435
|
+
queryOnce(address, ...args) {
|
|
436
|
+
return new Promise((resolve, reject) => {
|
|
437
|
+
if (!this.sendSocket) {
|
|
438
|
+
reject(new Error('AbletonOSC: not connected. Call connect() first.'));
|
|
439
|
+
return;
|
|
440
|
+
}
|
|
441
|
+
const timer = setTimeout(() => {
|
|
442
|
+
// Remove this specific pending entry
|
|
443
|
+
this.removePending(address, entry);
|
|
444
|
+
reject(new Error(`AbletonOSC: timeout waiting for response on ${address} (${AbletonOSC.TIMEOUT}ms)`));
|
|
445
|
+
}, AbletonOSC.TIMEOUT);
|
|
446
|
+
const entry = { resolve, reject, timer };
|
|
447
|
+
// Multiple queries to the same address are queued (FIFO)
|
|
448
|
+
if (!this.pending.has(address)) {
|
|
449
|
+
this.pending.set(address, []);
|
|
450
|
+
}
|
|
451
|
+
this.pending.get(address).push(entry);
|
|
452
|
+
const msg = encodeOscMessage(address, oscArgs(...args));
|
|
453
|
+
this.sendRaw(msg);
|
|
454
|
+
});
|
|
455
|
+
}
|
|
456
|
+
removePending(address, entry) {
|
|
457
|
+
const queue = this.pending.get(address);
|
|
458
|
+
if (!queue)
|
|
459
|
+
return;
|
|
460
|
+
const idx = queue.indexOf(entry);
|
|
461
|
+
if (idx !== -1) {
|
|
462
|
+
queue.splice(idx, 1);
|
|
463
|
+
}
|
|
464
|
+
if (queue.length === 0) {
|
|
465
|
+
this.pending.delete(address);
|
|
466
|
+
}
|
|
467
|
+
}
|
|
468
|
+
/**
|
|
469
|
+
* Handle an incoming OSC message from Ableton.
|
|
470
|
+
*/
|
|
471
|
+
handleMessage(msg) {
|
|
472
|
+
let decoded;
|
|
473
|
+
try {
|
|
474
|
+
decoded = decodeOscMessage(msg);
|
|
475
|
+
}
|
|
476
|
+
catch {
|
|
477
|
+
// Malformed message — discard
|
|
478
|
+
return;
|
|
479
|
+
}
|
|
480
|
+
const { address, args } = decoded;
|
|
481
|
+
// Check if this resolves a pending query (FIFO order)
|
|
482
|
+
const queue = this.pending.get(address);
|
|
483
|
+
if (queue && queue.length > 0) {
|
|
484
|
+
const entry = queue.shift();
|
|
485
|
+
if (queue.length === 0) {
|
|
486
|
+
this.pending.delete(address);
|
|
487
|
+
}
|
|
488
|
+
clearTimeout(entry.timer);
|
|
489
|
+
entry.resolve(args);
|
|
490
|
+
return;
|
|
491
|
+
}
|
|
492
|
+
// Otherwise dispatch to registered listeners
|
|
493
|
+
const handlers = this.listeners.get(address);
|
|
494
|
+
if (handlers) {
|
|
495
|
+
for (const handler of handlers) {
|
|
496
|
+
try {
|
|
497
|
+
handler(args);
|
|
498
|
+
}
|
|
499
|
+
catch {
|
|
500
|
+
// Listener errors are swallowed — don't crash the transport
|
|
501
|
+
}
|
|
502
|
+
}
|
|
503
|
+
}
|
|
504
|
+
}
|
|
505
|
+
/**
|
|
506
|
+
* Register a listener for incoming OSC messages on a specific address.
|
|
507
|
+
*/
|
|
508
|
+
on(address, handler) {
|
|
509
|
+
if (!this.listeners.has(address)) {
|
|
510
|
+
this.listeners.set(address, new Set());
|
|
511
|
+
}
|
|
512
|
+
this.listeners.get(address).add(handler);
|
|
513
|
+
}
|
|
514
|
+
/**
|
|
515
|
+
* Remove a specific listener, or all listeners for an address.
|
|
516
|
+
*/
|
|
517
|
+
off(address, handler) {
|
|
518
|
+
if (!handler) {
|
|
519
|
+
this.listeners.delete(address);
|
|
520
|
+
return;
|
|
521
|
+
}
|
|
522
|
+
const handlers = this.listeners.get(address);
|
|
523
|
+
if (handlers) {
|
|
524
|
+
handlers.delete(handler);
|
|
525
|
+
if (handlers.size === 0) {
|
|
526
|
+
this.listeners.delete(address);
|
|
527
|
+
}
|
|
528
|
+
}
|
|
529
|
+
}
|
|
530
|
+
/**
|
|
531
|
+
* Send a batch of OSC messages. Useful for large MIDI note arrays.
|
|
532
|
+
* Groups messages into UDP packets up to MAX_UDP_PAYLOAD bytes each.
|
|
533
|
+
*/
|
|
534
|
+
sendBatch(messages) {
|
|
535
|
+
if (!this.sendSocket) {
|
|
536
|
+
throw new Error('AbletonOSC: not connected. Call connect() first.');
|
|
537
|
+
}
|
|
538
|
+
for (const { address, args } of messages) {
|
|
539
|
+
const msg = encodeOscMessage(address, oscArgs(...args));
|
|
540
|
+
this.sendRaw(msg);
|
|
541
|
+
}
|
|
542
|
+
}
|
|
543
|
+
}
|
|
544
|
+
// ---------------------------------------------------------------------------
|
|
545
|
+
// Helper Functions
|
|
546
|
+
// ---------------------------------------------------------------------------
|
|
547
|
+
/**
|
|
548
|
+
* Get the AbletonOSC singleton, connecting if necessary.
|
|
549
|
+
* Throws a clear, user-friendly error if Ableton is not responding.
|
|
550
|
+
*/
|
|
551
|
+
export async function ensureAbleton() {
|
|
552
|
+
const client = AbletonOSC.getInstance();
|
|
553
|
+
if (client.isConnected()) {
|
|
554
|
+
return client;
|
|
555
|
+
}
|
|
556
|
+
const ok = await client.connect();
|
|
557
|
+
if (!ok) {
|
|
558
|
+
throw new Error(formatAbletonError());
|
|
559
|
+
}
|
|
560
|
+
return client;
|
|
561
|
+
}
|
|
562
|
+
/**
|
|
563
|
+
* Return a user-friendly error message when Ableton is not reachable.
|
|
564
|
+
*/
|
|
565
|
+
export function formatAbletonError() {
|
|
566
|
+
return [
|
|
567
|
+
'Could not connect to Ableton Live via AbletonOSC.',
|
|
568
|
+
'',
|
|
569
|
+
'To use Ableton integration, you need:',
|
|
570
|
+
'',
|
|
571
|
+
' 1. Ableton Live running on this machine',
|
|
572
|
+
' 2. AbletonOSC installed as a Remote Script',
|
|
573
|
+
' https://github.com/ideoforms/AbletonOSC',
|
|
574
|
+
'',
|
|
575
|
+
'Setup:',
|
|
576
|
+
' - Download AbletonOSC from the GitHub releases page',
|
|
577
|
+
' - Copy the AbletonOSC folder to:',
|
|
578
|
+
' macOS: /Users/YOU/Music/Ableton/User Library/Remote Scripts/',
|
|
579
|
+
' Win: \\Users\\YOU\\Documents\\Ableton\\User Library\\Remote Scripts\\',
|
|
580
|
+
' - In Ableton Live, go to Preferences > Link, Tempo & MIDI',
|
|
581
|
+
' - Under Control Surface, select "AbletonOSC"',
|
|
582
|
+
' - AbletonOSC listens on UDP 11000 and replies on UDP 11001',
|
|
583
|
+
'',
|
|
584
|
+
'Troubleshooting:',
|
|
585
|
+
' - Make sure Ableton Live is open and a project is loaded',
|
|
586
|
+
' - Check that no other process is using ports 11000/11001',
|
|
587
|
+
' - Try restarting the AbletonOSC control surface in Preferences',
|
|
588
|
+
].join('\n');
|
|
589
|
+
}
|
|
590
|
+
//# sourceMappingURL=ableton-osc.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ableton-osc.js","sourceRoot":"","sources":["../../src/integrations/ableton-osc.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"learned-router.d.ts","sourceRoot":"","sources":["../src/learned-router.ts"],"names":[],"mappings":"AA0BA,kCAAkC;AAClC,MAAM,WAAW,aAAa;IAC5B,+BAA+B;IAC/B,MAAM,EAAE,MAAM,CAAA;IACd,0CAA0C;IAC1C,QAAQ,EAAE,MAAM,EAAE,CAAA;IAClB,+BAA+B;IAC/B,KAAK,EAAE,MAAM,CAAA;IACb,4FAA4F;IAC5F,MAAM,EAAE,SAAS,GAAG,UAAU,GAAG,SAAS,GAAG,UAAU,GAAG,KAAK,CAAA;IAC/D,wDAAwD;IACxD,OAAO,EAAE,OAAO,CAAA;IAChB,2CAA2C;IAC3C,KAAK,EAAE,MAAM,CAAA;IACb,gBAAgB;IAChB,QAAQ,EAAE,MAAM,CAAA;CACjB;AAED,kDAAkD;AAClD,MAAM,WAAW,WAAW;IAC1B,qBAAqB;IACrB,KAAK,EAAE,MAAM,CAAA;IACb,qBAAqB;IACrB,UAAU,EAAE,MAAM,CAAA;IAClB,sCAAsC;IACtC,MAAM,EAAE,SAAS,GAAG,UAAU,GAAG,SAAS,GAAG,UAAU,GAAG,KAAK,CAAA;IAC/D,2CAA2C;IAC3C,MAAM,EAAE,OAAO,CAAA;CAChB;
|
|
1
|
+
{"version":3,"file":"learned-router.d.ts","sourceRoot":"","sources":["../src/learned-router.ts"],"names":[],"mappings":"AA0BA,kCAAkC;AAClC,MAAM,WAAW,aAAa;IAC5B,+BAA+B;IAC/B,MAAM,EAAE,MAAM,CAAA;IACd,0CAA0C;IAC1C,QAAQ,EAAE,MAAM,EAAE,CAAA;IAClB,+BAA+B;IAC/B,KAAK,EAAE,MAAM,CAAA;IACb,4FAA4F;IAC5F,MAAM,EAAE,SAAS,GAAG,UAAU,GAAG,SAAS,GAAG,UAAU,GAAG,KAAK,CAAA;IAC/D,wDAAwD;IACxD,OAAO,EAAE,OAAO,CAAA;IAChB,2CAA2C;IAC3C,KAAK,EAAE,MAAM,CAAA;IACb,gBAAgB;IAChB,QAAQ,EAAE,MAAM,CAAA;CACjB;AAED,kDAAkD;AAClD,MAAM,WAAW,WAAW;IAC1B,qBAAqB;IACrB,KAAK,EAAE,MAAM,CAAA;IACb,qBAAqB;IACrB,UAAU,EAAE,MAAM,CAAA;IAClB,sCAAsC;IACtC,MAAM,EAAE,SAAS,GAAG,UAAU,GAAG,SAAS,GAAG,UAAU,GAAG,KAAK,CAAA;IAC/D,2CAA2C;IAC3C,MAAM,EAAE,OAAO,CAAA;CAChB;AAmMD;;;;;;;;GAQG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,WAAW,GAAG,IAAI,CA4EhE;AAED;;;GAGG;AACH,wBAAgB,WAAW,CACzB,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,WAAW,CAAC,QAAQ,CAAC,EAC7B,OAAO,GAAE,OAAc,GACtB,IAAI,CA0CN;AA0BD,wBAAwB;AACxB,wBAAgB,eAAe,IAAI;IACjC,WAAW,EAAE,MAAM,CAAA;IACnB,WAAW,EAAE,MAAM,CAAA;IACnB,YAAY,EAAE,MAAM,CAAA;IACpB,WAAW,EAAE,MAAM,CAAA;IACnB,YAAY,EAAE,MAAM,CAAA;IACpB,YAAY,EAAE,MAAM,CAAA;IACpB,YAAY,EAAE,MAAM,CAAA;CACrB,CAqBA;AAED,yCAAyC;AACzC,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,IAAI,CAsBzE"}
|
package/dist/learned-router.js
CHANGED
|
@@ -154,6 +154,17 @@ const AGENT_KEYWORDS = {
|
|
|
154
154
|
'historiography', 'periodization', 'antiquity', 'medieval', 'colonial',
|
|
155
155
|
'revolution', 'empire', 'ancient', 'archaeology',
|
|
156
156
|
],
|
|
157
|
+
producer: [
|
|
158
|
+
'ableton', 'daw', 'produce', 'producer', 'production', 'session',
|
|
159
|
+
'clip', 'scene', 'tempo', 'bpm', 'transport', 'arm', 'mute', 'solo',
|
|
160
|
+
'midi', 'chord', 'progression', 'melody', 'bassline', 'beat', 'drum',
|
|
161
|
+
'mix', 'mixer', 'volume', 'pan', 'send', 'return', 'sidechain',
|
|
162
|
+
'device', 'plugin', 'vst', 'instrument', 'effect', 'fx',
|
|
163
|
+
'reverb', 'delay', 'compressor', 'eq', 'filter', 'arrangement',
|
|
164
|
+
'launch', 'fire', 'warp', 'loop', 'synth', 'wavetable', 'operator',
|
|
165
|
+
'sampler', 'mastering', 'limiter', 'stereo', 'automation',
|
|
166
|
+
'groove', 'swing', 'quantize', 'humanize', 'kick', 'snare', 'hihat',
|
|
167
|
+
],
|
|
157
168
|
creative: CREATIVE_KEYWORDS,
|
|
158
169
|
developer: DEVELOPER_KEYWORDS,
|
|
159
170
|
trader: TRADER_KEYWORDS,
|
|
@@ -190,6 +201,15 @@ const CATEGORY_PATTERNS = [
|
|
|
190
201
|
...CREATIVE_PATTERNS,
|
|
191
202
|
...DEVELOPER_PATTERNS,
|
|
192
203
|
...TRADER_PATTERNS.map(pattern => ({ pattern, agent: 'trader', confidence: 0.75 })),
|
|
204
|
+
{ pattern: /\b(ableton|daw|live\s*set|session\s*view)\b/i, agent: 'producer', confidence: 0.85 },
|
|
205
|
+
{ pattern: /\b(play|stop|record)\b.*\b(track|clip|scene)\b/i, agent: 'producer', confidence: 0.8 },
|
|
206
|
+
{ pattern: /\b(mute|solo|arm)\b.*\b(track|channel)\b/i, agent: 'producer', confidence: 0.8 },
|
|
207
|
+
{ pattern: /\b(set|change)\b.*\b(tempo|bpm)\b/i, agent: 'producer', confidence: 0.8 },
|
|
208
|
+
{ pattern: /\b(add|write|create|make)\b.*\b(chord|melody|midi|progression|beat|pattern|drum)\b.*\b(track|clip)\b/i, agent: 'producer', confidence: 0.8 },
|
|
209
|
+
{ pattern: /\b(fire|launch)\b.*\b(scene|clip)\b/i, agent: 'producer', confidence: 0.8 },
|
|
210
|
+
{ pattern: /\b(sidechain|parallel\s*compress)\b/i, agent: 'producer', confidence: 0.85 },
|
|
211
|
+
{ pattern: /\b(wavetable|operator|analog|drift|meld|simpler|collision|tension|electric)\b/i, agent: 'producer', confidence: 0.8 },
|
|
212
|
+
{ pattern: /\b(make|build|set\s*up)\b.*\b(house|techno|hip\s*hop|trap|ambient|lofi|jazz|pop|rnb)\b.*\b(track|beat|song)\b/i, agent: 'producer', confidence: 0.85 },
|
|
193
213
|
];
|
|
194
214
|
/**
|
|
195
215
|
* Cascaded route — try each level in order, return first confident match.
|