@animalabs/connectome-host 0.7.3 → 0.7.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 +156 -10
- package/HEADLESS-FLEET-PLAN.md +22 -0
- package/README.md +12 -1
- package/docs/AGENT-ONBOARDING.md +1 -1
- package/docs/debug-context-api.md +2 -2
- package/docs/retrieval-traces.md +173 -0
- package/docs/webui-deployment.md +2 -1
- package/package.json +2 -2
- package/scripts/audit-module-optins.ts +288 -0
- package/src/framework-strategy.ts +13 -4
- package/src/headless.ts +14 -0
- package/src/index.ts +12 -9
- package/src/modules/fleet-module.ts +60 -1
- package/src/modules/fleet-types.ts +30 -1
- package/src/modules/mcpl-admin-module.ts +33 -4
- package/src/modules/retrieval-module.ts +249 -51
- package/src/modules/retrieval-trace-page.ts +254 -0
- package/src/modules/retrieval-trace.ts +904 -0
- package/src/modules/tts-relay-module.ts +33 -18
- package/src/modules/web-ui-module.ts +445 -894
- package/src/recipe.ts +55 -4
- package/src/retrieval-config.ts +39 -0
- package/src/strategies/frontdesk-strategy.ts +34 -125
- package/src/tui.ts +325 -54
- package/src/web/panel-data.ts +1187 -0
- package/src/web/protocol.ts +75 -10
- package/test/audit-module-optins.test.ts +167 -0
- package/test/fleet-panel-request.test.ts +90 -0
- package/test/framework-strategy-defaults.test.ts +22 -0
- package/test/frontdesk-strategy.test.ts +25 -37
- package/test/headless-panel-request.test.ts +201 -0
- package/test/mcpl-admin-module.test.ts +23 -0
- package/test/mock-headless-child.ts +14 -0
- package/test/retrieval-auth-loopback.test.ts +49 -0
- package/test/retrieval-config.test.ts +74 -0
- package/test/retrieval-module.test.ts +821 -0
- package/test/tui-format.test.ts +106 -0
- package/test/web-ui-context-coverage.test.ts +1 -1
- package/test/web-ui-module.test.ts +189 -3
- package/test/web-ui-observers.test.ts +8 -5
- package/test/web-ui-protocol.test.ts +0 -0
- package/web/src/App.tsx +159 -44
- package/web/src/Context.tsx +35 -8
- package/web/src/ContextDocument.tsx +20 -5
- package/web/src/Files.tsx +2 -8
- package/web/src/Lessons.tsx +2 -38
- package/web/src/Mcpl.tsx +80 -14
- package/web/src/Pins.tsx +5 -0
- package/web/src/Settings.tsx +5 -0
- package/web/vite.config.ts +8 -2
|
@@ -232,6 +232,13 @@ function rawChannelId(mcplId: string): string {
|
|
|
232
232
|
return ix === -1 ? mcplId : mcplId.slice(ix + 1);
|
|
233
233
|
}
|
|
234
234
|
|
|
235
|
+
/** Channel-bound inference traces carry `channelId` at runtime, but the
|
|
236
|
+
* framework's TraceEvent union doesn't declare it — read it through a cast. */
|
|
237
|
+
function traceChannelId(event: unknown): string | undefined {
|
|
238
|
+
const v = (event as { channelId?: unknown }).channelId;
|
|
239
|
+
return typeof v === 'string' ? v : undefined;
|
|
240
|
+
}
|
|
241
|
+
|
|
235
242
|
const collapseWs = (s: string): string => s.replace(/\s+/g, ' ').trim();
|
|
236
243
|
|
|
237
244
|
export class TtsRelayModule implements Module {
|
|
@@ -338,18 +345,41 @@ export class TtsRelayModule implements Module {
|
|
|
338
345
|
}
|
|
339
346
|
|
|
340
347
|
private onTraceEvent(event: TraceEvent): void {
|
|
348
|
+
// `mcpl:speech-routed` is a custom trace type emitted by the speech
|
|
349
|
+
// router, not part of the framework's TraceEvent union — the typed
|
|
350
|
+
// switch below could never narrow to it. Handle it up front via the
|
|
351
|
+
// standard custom-trace cast.
|
|
352
|
+
if ((event as { type: string }).type === 'mcpl:speech-routed') {
|
|
353
|
+
// Remember what landed where, so an interruption can find its edit
|
|
354
|
+
// target: (channelId, messageId, text) per posted segment.
|
|
355
|
+
const e = event as unknown as {
|
|
356
|
+
channelId: string; messageId?: string; text: string; timestamp: number;
|
|
357
|
+
};
|
|
358
|
+
this.routed.push({
|
|
359
|
+
rawChannelId: rawChannelId(e.channelId),
|
|
360
|
+
mcplChannelId: e.channelId,
|
|
361
|
+
messageId: e.messageId,
|
|
362
|
+
text: e.text,
|
|
363
|
+
at: e.timestamp,
|
|
364
|
+
});
|
|
365
|
+
if (this.routed.length > ROUTED_RING_MAX) {
|
|
366
|
+
this.routed.splice(0, this.routed.length - ROUTED_RING_MAX);
|
|
367
|
+
}
|
|
368
|
+
return;
|
|
369
|
+
}
|
|
370
|
+
|
|
341
371
|
switch (event.type) {
|
|
342
372
|
case 'inference:started': {
|
|
343
373
|
// A context-budget restart re-emits inference:started mid-turn; the
|
|
344
374
|
// existing activation (announced or not) simply carries on.
|
|
345
375
|
const st = this.activation(event.agentName);
|
|
346
|
-
this.adoptChannel(st, event.agentName, event
|
|
376
|
+
this.adoptChannel(st, event.agentName, traceChannelId(event));
|
|
347
377
|
break;
|
|
348
378
|
}
|
|
349
379
|
|
|
350
380
|
case 'inference:tokens': {
|
|
351
381
|
const st = this.activation(event.agentName);
|
|
352
|
-
this.adoptChannel(st, event.agentName, event
|
|
382
|
+
this.adoptChannel(st, event.agentName, traceChannelId(event));
|
|
353
383
|
if (!st.rawChannelId) break; // no locus — nothing to voice into
|
|
354
384
|
st.blocks.set(event.blockIndex, (st.blocks.get(event.blockIndex) ?? '') + event.content);
|
|
355
385
|
this.client?.emit('chunk', {
|
|
@@ -367,7 +397,7 @@ export class TtsRelayModule implements Module {
|
|
|
367
397
|
|
|
368
398
|
case 'inference:content_block': {
|
|
369
399
|
const st = this.activation(event.agentName);
|
|
370
|
-
this.adoptChannel(st, event.agentName, event
|
|
400
|
+
this.adoptChannel(st, event.agentName, traceChannelId(event));
|
|
371
401
|
if (!st.rawChannelId) break;
|
|
372
402
|
const base = {
|
|
373
403
|
channelId: st.rawChannelId,
|
|
@@ -398,21 +428,6 @@ export class TtsRelayModule implements Module {
|
|
|
398
428
|
this.endActivation(event.agentName, 'error');
|
|
399
429
|
break;
|
|
400
430
|
|
|
401
|
-
case 'mcpl:speech-routed': {
|
|
402
|
-
// Remember what landed where, so an interruption can find its edit
|
|
403
|
-
// target: (channelId, messageId, text) per posted segment.
|
|
404
|
-
this.routed.push({
|
|
405
|
-
rawChannelId: rawChannelId(event.channelId),
|
|
406
|
-
mcplChannelId: event.channelId,
|
|
407
|
-
messageId: event.messageId,
|
|
408
|
-
text: event.text,
|
|
409
|
-
at: event.timestamp,
|
|
410
|
-
});
|
|
411
|
-
if (this.routed.length > ROUTED_RING_MAX) {
|
|
412
|
-
this.routed.splice(0, this.routed.length - ROUTED_RING_MAX);
|
|
413
|
-
}
|
|
414
|
-
break;
|
|
415
|
-
}
|
|
416
431
|
|
|
417
432
|
default:
|
|
418
433
|
break;
|