@threadplane/langgraph 0.0.61 → 0.0.62

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.
@@ -407,6 +407,32 @@ class SubagentTracker {
407
407
  });
408
408
  this.onSubagentChange?.();
409
409
  }
410
+ /**
411
+ * Authoritative namespace→tool-call binding, from the server.
412
+ *
413
+ * `threadplane.middleware.langgraph.announce_subagent` emits a custom event
414
+ * pairing the child's checkpoint namespace with its tool-call id — the two
415
+ * halves that are never linked on the wire otherwise. Unlike the matching
416
+ * ladder this is not a heuristic: it overrides nothing that is already
417
+ * mapped, works with any number of children outstanding, and replays any
418
+ * chunks that streamed before the binding arrived.
419
+ */
420
+ bindChildStream(namespaceId, toolCallId) {
421
+ if (this.namespaceToToolCallId.get(namespaceId) === toolCallId)
422
+ return;
423
+ this.namespaceToToolCallId.set(namespaceId, toolCallId);
424
+ const subagent = this.subagents.get(toolCallId);
425
+ if (subagent) {
426
+ const buffered = this.unattributedMessages.get(namespaceId);
427
+ this.subagents.set(toolCallId, {
428
+ ...subagent,
429
+ status: subagent.status === 'complete' || subagent.status === 'error' ? subagent.status : 'running',
430
+ messages: buffered ? mergeMessages$1(subagent.messages, buffered) : subagent.messages,
431
+ });
432
+ this.unattributedMessages.delete(namespaceId);
433
+ }
434
+ this.onSubagentChange?.();
435
+ }
410
436
  /**
411
437
  * Attribute a `tools:` child stream to its parent tool call as soon as the
412
438
  * child is seen, without requiring a description to match on.
@@ -1484,6 +1510,20 @@ function createStreamManagerBridge({ options, subjects, threadId$, destroy$ }) {
1484
1510
  break;
1485
1511
  case 'custom': {
1486
1512
  const eventData = event['data'];
1513
+ // Server-announced subagent identity (threadplane-middleware's
1514
+ // `announce_subagent`). Consumed here rather than forwarded: it is
1515
+ // protocol chatter, not application data.
1516
+ if (isRecord$1(eventData)
1517
+ && eventData['type'] === 'threadplane.subagent_binding'
1518
+ && typeof eventData['namespace'] === 'string'
1519
+ && typeof eventData['tool_call_id'] === 'string') {
1520
+ const bound = childStreamRefFromNamespace([eventData['namespace']]);
1521
+ if (bound?.kind === 'tool') {
1522
+ subagentManager.bindChildStream(bound.key, eventData['tool_call_id']);
1523
+ publishSubagents();
1524
+ }
1525
+ break;
1526
+ }
1487
1527
  const name = (event['name'] ?? eventData?.['name'] ?? '');
1488
1528
  const data = eventData?.['data'] ?? eventData;
1489
1529
  const current = subjects.custom$.value;