switchroom 0.18.23 → 0.18.25

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.
Files changed (45) hide show
  1. package/dist/cli/switchroom.js +59 -11
  2. package/dist/host-control/main.js +1 -1
  3. package/package.json +1 -1
  4. package/telegram-plugin/dist/bridge/bridge.js +26 -0
  5. package/telegram-plugin/dist/gateway/gateway.js +1608 -841
  6. package/telegram-plugin/dist/server.js +26 -0
  7. package/telegram-plugin/gateway/callback-query-handlers.ts +7 -0
  8. package/telegram-plugin/gateway/gateway.ts +524 -16
  9. package/telegram-plugin/gateway/model-command.ts +188 -56
  10. package/telegram-plugin/gateway/redelivery-decision.ts +139 -0
  11. package/telegram-plugin/gateway/vault-grant-inbound-builders.ts +42 -1
  12. package/telegram-plugin/history.ts +118 -0
  13. package/telegram-plugin/registry/turns-schema.ts +89 -1
  14. package/telegram-plugin/reply-owner-resolve.ts +160 -0
  15. package/telegram-plugin/session-tail.ts +185 -0
  16. package/telegram-plugin/subagent-watcher.ts +45 -0
  17. package/telegram-plugin/tests/crash-redelivery-resume-exclusion.test.ts +133 -0
  18. package/telegram-plugin/tests/crash-redelivery-wiring.test.ts +72 -0
  19. package/telegram-plugin/tests/history.test.ts +91 -0
  20. package/telegram-plugin/tests/model-command.test.ts +189 -12
  21. package/telegram-plugin/tests/redelivery-decision.test.ts +84 -0
  22. package/telegram-plugin/tests/registry-turns.test.ts +51 -0
  23. package/telegram-plugin/tests/reply-owner-resolve.test.ts +279 -0
  24. package/telegram-plugin/tests/session-model-source.test.ts +11 -0
  25. package/telegram-plugin/tests/session-tail.test.ts +145 -0
  26. package/telegram-plugin/tests/subagent-watcher.test.ts +50 -0
  27. package/telegram-plugin/tests/tool-activity-summary.test.ts +109 -0
  28. package/telegram-plugin/tests/trailing-answer-projector.test.ts +124 -0
  29. package/telegram-plugin/tests/vault-grant-inbound-builders.test.ts +125 -0
  30. package/telegram-plugin/tests/worker-feed-coalesce.test.ts +117 -1
  31. package/telegram-plugin/tests/worker-feed-pin-persistence.test.ts +306 -0
  32. package/telegram-plugin/tool-activity-summary.ts +54 -3
  33. package/telegram-plugin/worker-activity-feed.ts +222 -10
  34. package/vendor/hindsight-memory/scripts/backfill_transcripts.py +762 -0
  35. package/vendor/hindsight-memory/scripts/drain_pending.py +13 -1
  36. package/vendor/hindsight-memory/scripts/lib/client.py +14 -4
  37. package/vendor/hindsight-memory/scripts/lib/config.py +8 -0
  38. package/vendor/hindsight-memory/scripts/lib/pacing.py +102 -0
  39. package/vendor/hindsight-memory/scripts/lib/watermark.py +213 -0
  40. package/vendor/hindsight-memory/scripts/reconcile_tail.py +344 -0
  41. package/vendor/hindsight-memory/scripts/retain.py +299 -143
  42. package/vendor/hindsight-memory/scripts/session_start.py +14 -0
  43. package/vendor/hindsight-memory/scripts/tests/test_backfill.py +362 -0
  44. package/vendor/hindsight-memory/scripts/tests/test_reconcile_durability.py +350 -0
  45. package/vendor/hindsight-memory/tests/test_hooks.py +8 -2
@@ -17357,6 +17357,13 @@ function projectAssistantTextBlocks(content, make) {
17357
17357
  });
17358
17358
  return out;
17359
17359
  }
17360
+ function sumUsageTokens(usage) {
17361
+ if (usage == null || typeof usage !== "object")
17362
+ return 0;
17363
+ const u = usage;
17364
+ const n = (v) => typeof v === "number" && Number.isFinite(v) ? v : 0;
17365
+ return n(u.input_tokens) + n(u.output_tokens) + n(u.cache_creation_input_tokens);
17366
+ }
17360
17367
  function assistantLineCarriesAnswerSurface(content) {
17361
17368
  if (!Array.isArray(content))
17362
17369
  return false;
@@ -17412,6 +17419,15 @@ function projectTranscriptLine(line) {
17412
17419
  if (typeof mainModel === "string" && !isModelSentinel(mainModel)) {
17413
17420
  events.push({ kind: "model", model: mainModel });
17414
17421
  }
17422
+ const mainUsageTotal = sumUsageTokens(message?.usage);
17423
+ if (mainUsageTotal > 0) {
17424
+ const mainMsgId = message?.id;
17425
+ events.push({
17426
+ kind: "usage",
17427
+ messageId: typeof mainMsgId === "string" ? mainMsgId : null,
17428
+ totalTokens: mainUsageTotal
17429
+ });
17430
+ }
17415
17431
  const textEvents = projectAssistantTextBlocks(content, (text, blockIndex, lastInMessage) => ({ kind: "text", text, blockIndex, lastInMessage }));
17416
17432
  content.forEach((c, i) => {
17417
17433
  const ct = c.type;
@@ -17518,6 +17534,16 @@ function projectSubagentLine(line, agentId, state) {
17518
17534
  if (typeof subModel === "string" && !isModelSentinel(subModel)) {
17519
17535
  events.push({ kind: "sub_agent_model", agentId, model: subModel });
17520
17536
  }
17537
+ const subUsageTotal = sumUsageTokens(message?.usage);
17538
+ if (subUsageTotal > 0) {
17539
+ const subMsgId = message?.id;
17540
+ events.push({
17541
+ kind: "sub_agent_usage",
17542
+ agentId,
17543
+ messageId: typeof subMsgId === "string" ? subMsgId : null,
17544
+ totalTokens: subUsageTotal
17545
+ });
17546
+ }
17521
17547
  const textEvents = projectAssistantTextBlocks(content, (text, blockIndex, lastInMessage) => ({
17522
17548
  kind: "sub_agent_text",
17523
17549
  agentId,
@@ -52,6 +52,7 @@ import {
52
52
  import {
53
53
  buildVaultGrantApprovedInbound,
54
54
  buildVaultGrantApprovedCardText,
55
+ normalizeGrantReason,
55
56
  buildVaultGrantDeniedInbound,
56
57
  buildVaultSaveCompletedInbound,
57
58
  buildVaultSaveFailedInbound,
@@ -786,6 +787,10 @@ async function performVaultAccessApproval(
786
787
  pendingCardStore.remove(stageId)
787
788
  if (pending.card_message_id != null) {
788
789
  const days = Math.round(pending.ttl_seconds / 86400)
790
+ // Normalize + cap the agent-supplied reason to a single line BEFORE
791
+ // escaping, so the value passed into the card builder is already
792
+ // safe to render inside the `_Reason: …_` italic clause.
793
+ const reasonNormalized = normalizeGrantReason(pending.reason)
789
794
  const footer =
790
795
  getVaultApprovalAuthMode() === 'telegram-id'
791
796
  ? `\n_Approver verified by Telegram identity — broker auto-unlocked at startup._`
@@ -801,6 +806,8 @@ async function performVaultAccessApproval(
801
806
  key: pending.key,
802
807
  days,
803
808
  grantId: id,
809
+ reasonEscaped:
810
+ reasonNormalized.length > 0 ? escapeHtmlForTg(reasonNormalized) : undefined,
804
811
  footer,
805
812
  }),
806
813
  ),