switchroom 0.19.39 → 0.19.41

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 (37) hide show
  1. package/dist/agent-scheduler/index.js +10 -1
  2. package/dist/auth-broker/index.js +12 -3
  3. package/dist/cli/notion-write-pretool.mjs +10 -1
  4. package/dist/cli/switchroom.js +562 -196
  5. package/dist/host-control/main.js +287 -20
  6. package/dist/vault/approvals/kernel-server.js +12 -3
  7. package/dist/vault/broker/server.js +12 -3
  8. package/package.json +1 -1
  9. package/profiles/_base/start.sh.hbs +10 -0
  10. package/telegram-plugin/bridge/bridge.ts +2 -2
  11. package/telegram-plugin/dist/bridge/bridge.js +10 -2
  12. package/telegram-plugin/dist/gateway/gateway.js +549 -232
  13. package/telegram-plugin/dist/server.js +10 -2
  14. package/telegram-plugin/gateway/backstop-delivery.ts +48 -0
  15. package/telegram-plugin/gateway/checklist-fallback.ts +370 -0
  16. package/telegram-plugin/gateway/compaction-marker.ts +84 -0
  17. package/telegram-plugin/gateway/gateway.ts +72 -72
  18. package/telegram-plugin/gateway/liveness-wiring.ts +15 -0
  19. package/telegram-plugin/gateway/outbound-send-path.ts +20 -0
  20. package/telegram-plugin/gateway/outbox-sweep.ts +116 -18
  21. package/telegram-plugin/gateway/silence-poke-session-event.ts +13 -0
  22. package/telegram-plugin/gateway/stream-render.ts +39 -1
  23. package/telegram-plugin/gateway/turn-record-status.ts +80 -0
  24. package/telegram-plugin/hooks/compaction-marker-precompact.mjs +70 -0
  25. package/telegram-plugin/hooks/hooks.json +11 -0
  26. package/telegram-plugin/session-tail.ts +20 -0
  27. package/telegram-plugin/silence-poke.ts +28 -0
  28. package/telegram-plugin/tests/checklist-fallback.test.ts +317 -0
  29. package/telegram-plugin/tests/gateway-outbound-redact.test.ts +10 -6
  30. package/telegram-plugin/tests/outbox-delivery.test.ts +38 -1
  31. package/telegram-plugin/tests/outbox-flush-ack-claim-race.test.ts +213 -0
  32. package/telegram-plugin/tests/outbox-reply-then-recap-e2e.test.ts +1 -1
  33. package/telegram-plugin/tests/outbox-sweep-flood-breaker.test.ts +4 -4
  34. package/telegram-plugin/tests/outbox-sweep-listen-button.test.ts +71 -8
  35. package/telegram-plugin/tests/send-reply-golden.test.ts +47 -0
  36. package/telegram-plugin/tests/silence-poke-compaction.test.ts +222 -0
  37. package/telegram-plugin/tests/turn-record-status.test.ts +62 -0
@@ -2,6 +2,7 @@ import { describe, expect, it } from 'vitest'
2
2
 
3
3
  import {
4
4
  computeTurnStatus,
5
+ computeTurnRoute,
5
6
  backstopSendOutcome,
6
7
  finalizeBackstopSend,
7
8
  buildTurnRecord,
@@ -39,6 +40,67 @@ describe('computeTurnStatus — recorded turn status reflects real outcome', ()
39
40
  })
40
41
  })
41
42
 
43
+ /**
44
+ * Honest delivery ROUTE. Derived from the SAME resolved delivery state
45
+ * `computeTurnStatus` reads, so the fleet-health detector can tell a
46
+ * flush-recovered turn (answer delivered by a backstop after the reply tool was
47
+ * bypassed) apart from a genuine silent no-op. These assert the mapping OUTCOME,
48
+ * not merely that a branch ran.
49
+ */
50
+ describe('computeTurnRoute — honest delivery route from resolved state', () => {
51
+ it('deliveryOutcome delivered → flush (backstop delivered the answer)', () => {
52
+ expect(
53
+ computeTurnRoute({ finalAnswerDelivered: true, replyCalled: false, deliveryOutcome: 'delivered' }),
54
+ ).toBe('flush')
55
+ })
56
+
57
+ it('deliveryOutcome suppressed → reply (flush short-circuited; reply delivered)', () => {
58
+ expect(
59
+ computeTurnRoute({ finalAnswerDelivered: true, replyCalled: true, deliveryOutcome: 'suppressed' }),
60
+ ).toBe('reply')
61
+ })
62
+
63
+ it('deliveryOutcome failed → none (nothing reached the user)', () => {
64
+ expect(
65
+ computeTurnRoute({ finalAnswerDelivered: true, replyCalled: true, deliveryOutcome: 'failed' }),
66
+ ).toBe('none')
67
+ })
68
+
69
+ it('undefined outcome + finalAnswer + replyCalled → reply (synchronous reply tail)', () => {
70
+ expect(
71
+ computeTurnRoute({ finalAnswerDelivered: true, replyCalled: true, deliveryOutcome: undefined }),
72
+ ).toBe('reply')
73
+ })
74
+
75
+ it('undefined outcome + finalAnswer + NOT replyCalled → stream', () => {
76
+ expect(
77
+ computeTurnRoute({ finalAnswerDelivered: true, replyCalled: false, deliveryOutcome: undefined }),
78
+ ).toBe('stream')
79
+ })
80
+
81
+ it('undefined outcome + no final answer → none (genuine no-reply)', () => {
82
+ expect(
83
+ computeTurnRoute({ finalAnswerDelivered: false, replyCalled: false, deliveryOutcome: undefined }),
84
+ ).toBe('none')
85
+ })
86
+
87
+ it('buildTurnRecord stamps route on the row (flush for a delivered backstop send)', () => {
88
+ const rec = buildTurnRecord(
89
+ {
90
+ agent: 'test-agent',
91
+ startedAt: 1_700_000_495_000,
92
+ toolCallCount: 0,
93
+ turnId: 'turn-route',
94
+ finalAnswerDelivered: true,
95
+ replyCalled: false,
96
+ deliveryOutcome: 'delivered',
97
+ },
98
+ 1_700_000_500_000,
99
+ )
100
+ expect(rec.route).toBe('flush')
101
+ })
102
+ })
103
+
42
104
  describe('backstopSendOutcome — resolve outcome from what happened on the wire', () => {
43
105
  it('throw → failed', () => {
44
106
  expect(backstopSendOutcome({ threw: true, sentCount: 0, chunkCount: 1 })).toBe('failed')