@vellumai/assistant 0.4.16 → 0.4.18

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 (536) hide show
  1. package/Dockerfile +6 -6
  2. package/README.md +1 -2
  3. package/eslint.config.mjs +2 -2
  4. package/package.json +1 -1
  5. package/src/__tests__/access-request-decision.test.ts +128 -120
  6. package/src/__tests__/account-registry.test.ts +121 -110
  7. package/src/__tests__/active-skill-tools.test.ts +200 -172
  8. package/src/__tests__/actor-token-service.test.ts +341 -274
  9. package/src/__tests__/agent-loop-thinking.test.ts +28 -19
  10. package/src/__tests__/agent-loop.test.ts +798 -378
  11. package/src/__tests__/anthropic-provider.test.ts +405 -247
  12. package/src/__tests__/app-builder-tool-scripts.test.ts +97 -97
  13. package/src/__tests__/app-bundler.test.ts +112 -79
  14. package/src/__tests__/app-executors.test.ts +205 -178
  15. package/src/__tests__/app-git-history.test.ts +90 -73
  16. package/src/__tests__/app-git-service.test.ts +67 -53
  17. package/src/__tests__/app-open-proxy.test.ts +29 -25
  18. package/src/__tests__/approval-conversation-turn.test.ts +100 -81
  19. package/src/__tests__/approval-hardcoded-copy-guard.test.ts +45 -17
  20. package/src/__tests__/approval-message-composer.test.ts +119 -119
  21. package/src/__tests__/approval-primitive.test.ts +264 -233
  22. package/src/__tests__/approval-routes-http.test.ts +4 -3
  23. package/src/__tests__/asset-materialize-tool.test.ts +250 -178
  24. package/src/__tests__/asset-search-tool.test.ts +251 -191
  25. package/src/__tests__/assistant-attachment-directive.test.ts +187 -142
  26. package/src/__tests__/assistant-attachments.test.ts +254 -186
  27. package/src/__tests__/assistant-event-hub.test.ts +105 -63
  28. package/src/__tests__/assistant-event.test.ts +66 -58
  29. package/src/__tests__/assistant-events-sse-hardening.test.ts +113 -73
  30. package/src/__tests__/assistant-feature-flag-guard.test.ts +78 -52
  31. package/src/__tests__/assistant-feature-flag-guardrails.test.ts +48 -45
  32. package/src/__tests__/assistant-feature-flags-integration.test.ts +118 -77
  33. package/src/__tests__/assistant-id-boundary-guard.test.ts +158 -104
  34. package/src/__tests__/attachments-store.test.ts +240 -183
  35. package/src/__tests__/attachments.test.ts +70 -62
  36. package/src/__tests__/audit-log-rotation.test.ts +50 -35
  37. package/src/__tests__/browser-fill-credential.test.ts +169 -101
  38. package/src/__tests__/browser-manager.test.ts +97 -75
  39. package/src/__tests__/browser-runtime-check.test.ts +16 -15
  40. package/src/__tests__/browser-skill-baseline-tool-payload.test.ts +12 -10
  41. package/src/__tests__/browser-skill-endstate.test.ts +97 -72
  42. package/src/__tests__/bundle-scanner.test.ts +47 -22
  43. package/src/__tests__/bundled-asset.test.ts +74 -47
  44. package/src/__tests__/call-constants.test.ts +19 -19
  45. package/src/__tests__/call-controller.test.ts +1073 -751
  46. package/src/__tests__/call-conversation-messages.test.ts +90 -65
  47. package/src/__tests__/call-domain.test.ts +149 -121
  48. package/src/__tests__/call-pointer-message-composer.test.ts +113 -83
  49. package/src/__tests__/call-pointer-messages.test.ts +213 -154
  50. package/src/__tests__/call-pointer-no-hardcoded-copy.guard.test.ts +9 -10
  51. package/src/__tests__/call-recovery.test.ts +232 -212
  52. package/src/__tests__/call-routes-http.test.ts +328 -279
  53. package/src/__tests__/call-start-guardian-guard.test.ts +32 -30
  54. package/src/__tests__/call-state-machine.test.ts +62 -51
  55. package/src/__tests__/call-state.test.ts +89 -75
  56. package/src/__tests__/call-store.test.ts +387 -316
  57. package/src/__tests__/callback-handoff-copy.test.ts +84 -82
  58. package/src/__tests__/canonical-guardian-store.test.ts +331 -280
  59. package/src/__tests__/channel-approval-routes.test.ts +1643 -1126
  60. package/src/__tests__/channel-approval.test.ts +139 -137
  61. package/src/__tests__/channel-approvals.test.ts +226 -182
  62. package/src/__tests__/channel-delivery-store.test.ts +232 -194
  63. package/src/__tests__/channel-guardian.test.ts +6 -3
  64. package/src/__tests__/channel-invite-transport.test.ts +107 -92
  65. package/src/__tests__/channel-policy.test.ts +42 -38
  66. package/src/__tests__/channel-readiness-service.test.ts +119 -102
  67. package/src/__tests__/channel-reply-delivery.test.ts +147 -118
  68. package/src/__tests__/channel-retry-sweep.test.ts +153 -110
  69. package/src/__tests__/checker.test.ts +3309 -1850
  70. package/src/__tests__/clarification-resolver.test.ts +91 -79
  71. package/src/__tests__/classifier.test.ts +64 -54
  72. package/src/__tests__/claude-code-skill-regression.test.ts +42 -37
  73. package/src/__tests__/claude-code-tool-profiles.test.ts +31 -29
  74. package/src/__tests__/clawhub.test.ts +92 -82
  75. package/src/__tests__/cli.test.ts +30 -30
  76. package/src/__tests__/clipboard.test.ts +53 -46
  77. package/src/__tests__/commit-guarantee.test.ts +59 -52
  78. package/src/__tests__/commit-message-enrichment-service.test.ts +203 -75
  79. package/src/__tests__/compaction.benchmark.test.ts +33 -31
  80. package/src/__tests__/computer-use-session-compaction.test.ts +60 -50
  81. package/src/__tests__/computer-use-session-lifecycle.test.ts +145 -117
  82. package/src/__tests__/computer-use-session-working-dir.test.ts +62 -48
  83. package/src/__tests__/computer-use-skill-baseline.test.ts +22 -19
  84. package/src/__tests__/computer-use-skill-endstate.test.ts +45 -31
  85. package/src/__tests__/computer-use-skill-lifecycle-cleanup.test.ts +121 -88
  86. package/src/__tests__/computer-use-skill-manifest-regression.test.ts +65 -42
  87. package/src/__tests__/computer-use-skill-proxy-bridge.test.ts +33 -18
  88. package/src/__tests__/computer-use-tools.test.ts +121 -98
  89. package/src/__tests__/config-schema.test.ts +443 -347
  90. package/src/__tests__/config-watcher.test.ts +96 -81
  91. package/src/__tests__/confirmation-request-guardian-bridge.test.ts +148 -133
  92. package/src/__tests__/conflict-intent-tokenization.test.ts +96 -78
  93. package/src/__tests__/conflict-policy.test.ts +151 -80
  94. package/src/__tests__/conflict-store.test.ts +203 -157
  95. package/src/__tests__/connection-policy.test.ts +89 -59
  96. package/src/__tests__/contacts-tools.test.ts +247 -178
  97. package/src/__tests__/context-memory-e2e.test.ts +306 -214
  98. package/src/__tests__/context-token-estimator.test.ts +114 -74
  99. package/src/__tests__/context-window-manager.test.ts +269 -167
  100. package/src/__tests__/contradiction-checker.test.ts +161 -135
  101. package/src/__tests__/conversation-attention-store.test.ts +350 -290
  102. package/src/__tests__/conversation-attention-telegram.test.ts +156 -114
  103. package/src/__tests__/conversation-pairing.test.ts +220 -113
  104. package/src/__tests__/conversation-routes-guardian-reply.test.ts +164 -104
  105. package/src/__tests__/conversation-routes.test.ts +71 -41
  106. package/src/__tests__/conversation-store.test.ts +390 -235
  107. package/src/__tests__/credential-broker-browser-fill.test.ts +325 -250
  108. package/src/__tests__/credential-broker-server-use.test.ts +283 -243
  109. package/src/__tests__/credential-broker.test.ts +128 -74
  110. package/src/__tests__/credential-host-pattern-match.test.ts +64 -44
  111. package/src/__tests__/credential-metadata-store.test.ts +360 -311
  112. package/src/__tests__/credential-policy-validate.test.ts +81 -65
  113. package/src/__tests__/credential-resolve.test.ts +212 -145
  114. package/src/__tests__/credential-security-e2e.test.ts +144 -103
  115. package/src/__tests__/credential-security-invariants.test.ts +253 -208
  116. package/src/__tests__/credential-selection.test.ts +254 -146
  117. package/src/__tests__/credential-vault-unit.test.ts +531 -341
  118. package/src/__tests__/credential-vault.test.ts +761 -484
  119. package/src/__tests__/daemon-assistant-events.test.ts +91 -66
  120. package/src/__tests__/daemon-lifecycle.test.ts +258 -190
  121. package/src/__tests__/daemon-server-session-init.test.ts +257 -191
  122. package/src/__tests__/date-context.test.ts +314 -249
  123. package/src/__tests__/db-migration-rollback.test.ts +259 -130
  124. package/src/__tests__/db-schedule-syntax-migration.test.ts +78 -41
  125. package/src/__tests__/delete-managed-skill-tool.test.ts +77 -53
  126. package/src/__tests__/deterministic-verification-control-plane.test.ts +183 -135
  127. package/src/__tests__/dictation-mode-detection.test.ts +77 -55
  128. package/src/__tests__/dictation-profile-store.test.ts +70 -56
  129. package/src/__tests__/dictation-text-processing.test.ts +53 -35
  130. package/src/__tests__/diff.test.ts +102 -98
  131. package/src/__tests__/domain-normalize.test.ts +54 -54
  132. package/src/__tests__/domain-policy.test.ts +71 -55
  133. package/src/__tests__/dynamic-page-surface.test.ts +31 -33
  134. package/src/__tests__/dynamic-skill-workflow-prompt.test.ts +69 -69
  135. package/src/__tests__/edit-engine.test.ts +56 -56
  136. package/src/__tests__/elevenlabs-client.test.ts +117 -91
  137. package/src/__tests__/elevenlabs-config.test.ts +32 -31
  138. package/src/__tests__/email-classifier.test.ts +15 -12
  139. package/src/__tests__/email-cli.test.ts +121 -108
  140. package/src/__tests__/emit-signal-routing-intent.test.ts +76 -69
  141. package/src/__tests__/encrypted-store.test.ts +180 -154
  142. package/src/__tests__/entity-extractor.test.ts +108 -87
  143. package/src/__tests__/entity-search.test.ts +664 -258
  144. package/src/__tests__/ephemeral-permissions.test.ts +224 -188
  145. package/src/__tests__/event-bus.test.ts +81 -77
  146. package/src/__tests__/extract-email.test.ts +51 -0
  147. package/src/__tests__/file-edit-tool.test.ts +62 -44
  148. package/src/__tests__/file-ops-service.test.ts +131 -114
  149. package/src/__tests__/file-read-tool.test.ts +48 -31
  150. package/src/__tests__/file-write-tool.test.ts +43 -37
  151. package/src/__tests__/filesystem-tools.test.ts +238 -209
  152. package/src/__tests__/followup-tools.test.ts +237 -162
  153. package/src/__tests__/forbidden-legacy-symbols.test.ts +19 -20
  154. package/src/__tests__/frontmatter.test.ts +96 -81
  155. package/src/__tests__/fuzzy-match-property.test.ts +75 -81
  156. package/src/__tests__/fuzzy-match.test.ts +71 -65
  157. package/src/__tests__/gateway-client-managed-outbound.test.ts +76 -57
  158. package/src/__tests__/gateway-only-enforcement.test.ts +467 -369
  159. package/src/__tests__/gateway-only-guard.test.ts +54 -56
  160. package/src/__tests__/gemini-image-service.test.ts +113 -100
  161. package/src/__tests__/gemini-provider.test.ts +297 -220
  162. package/src/__tests__/get-weather.test.ts +188 -114
  163. package/src/__tests__/gmail-integration.test.ts +47 -46
  164. package/src/__tests__/guardian-action-conversation-turn.test.ts +226 -171
  165. package/src/__tests__/guardian-action-copy-generator.test.ts +111 -93
  166. package/src/__tests__/guardian-action-followup-executor.test.ts +215 -151
  167. package/src/__tests__/guardian-action-followup-store.test.ts +199 -167
  168. package/src/__tests__/guardian-action-grant-mint-consume.test.ts +297 -250
  169. package/src/__tests__/guardian-action-late-reply.test.ts +462 -316
  170. package/src/__tests__/guardian-action-no-hardcoded-copy.test.ts +23 -18
  171. package/src/__tests__/guardian-action-store.test.ts +158 -109
  172. package/src/__tests__/guardian-action-sweep.test.ts +114 -100
  173. package/src/__tests__/guardian-actions-endpoint.test.ts +440 -256
  174. package/src/__tests__/guardian-control-plane-policy.test.ts +497 -331
  175. package/src/__tests__/guardian-decision-primitive-canonical.test.ts +217 -215
  176. package/src/__tests__/guardian-dispatch.test.ts +316 -256
  177. package/src/__tests__/guardian-grant-minting.test.ts +247 -178
  178. package/src/__tests__/guardian-outbound-http.test.ts +337 -209
  179. package/src/__tests__/guardian-principal-id-roundtrip.test.ts +99 -96
  180. package/src/__tests__/guardian-question-copy.test.ts +17 -17
  181. package/src/__tests__/guardian-question-mode.test.ts +134 -100
  182. package/src/__tests__/guardian-routing-invariants.test.ts +679 -613
  183. package/src/__tests__/guardian-routing-state.test.ts +256 -209
  184. package/src/__tests__/guardian-verification-intent-routing.test.ts +94 -88
  185. package/src/__tests__/guardian-verification-voice-binding.test.ts +47 -41
  186. package/src/__tests__/guardian-verify-setup-skill-regression.test.ts +0 -1
  187. package/src/__tests__/handle-user-message-secret-resume.test.ts +43 -21
  188. package/src/__tests__/handlers-add-trust-rule-metadata.test.ts +92 -76
  189. package/src/__tests__/handlers-cu-observation-blob.test.ts +103 -70
  190. package/src/__tests__/handlers-ipc-blob-probe.test.ts +77 -51
  191. package/src/__tests__/handlers-slack-config.test.ts +63 -54
  192. package/src/__tests__/handlers-task-submit-slash.test.ts +18 -18
  193. package/src/__tests__/handlers-telegram-config.test.ts +662 -329
  194. package/src/__tests__/handlers-twitter-config.test.ts +525 -298
  195. package/src/__tests__/handlers-user-message-approval-consumption.test.ts +270 -195
  196. package/src/__tests__/headless-browser-interactions.test.ts +444 -280
  197. package/src/__tests__/headless-browser-navigate.test.ts +116 -79
  198. package/src/__tests__/headless-browser-read-tools.test.ts +123 -86
  199. package/src/__tests__/headless-browser-snapshot.test.ts +71 -56
  200. package/src/__tests__/heartbeat-service.test.ts +76 -58
  201. package/src/__tests__/history-repair-observability.test.ts +14 -14
  202. package/src/__tests__/history-repair.test.ts +171 -167
  203. package/src/__tests__/home-base-bootstrap.test.ts +30 -27
  204. package/src/__tests__/hooks-blocking.test.ts +86 -37
  205. package/src/__tests__/hooks-cli.test.ts +104 -68
  206. package/src/__tests__/hooks-config.test.ts +81 -43
  207. package/src/__tests__/hooks-discovery.test.ts +106 -96
  208. package/src/__tests__/hooks-integration.test.ts +78 -72
  209. package/src/__tests__/hooks-manager.test.ts +99 -61
  210. package/src/__tests__/hooks-runner.test.ts +94 -71
  211. package/src/__tests__/hooks-settings.test.ts +69 -64
  212. package/src/__tests__/hooks-templates.test.ts +85 -54
  213. package/src/__tests__/hooks-ts-runner.test.ts +82 -45
  214. package/src/__tests__/hooks-watch.test.ts +32 -22
  215. package/src/__tests__/host-file-edit-tool.test.ts +190 -148
  216. package/src/__tests__/host-file-read-tool.test.ts +86 -63
  217. package/src/__tests__/host-file-write-tool.test.ts +98 -64
  218. package/src/__tests__/host-shell-tool.test.ts +342 -233
  219. package/src/__tests__/inbound-invite-redemption.test.ts +194 -152
  220. package/src/__tests__/ingress-member-store.test.ts +163 -159
  221. package/src/__tests__/ingress-reconcile.test.ts +183 -142
  222. package/src/__tests__/ingress-routes-http.test.ts +441 -356
  223. package/src/__tests__/ingress-url-consistency.test.ts +125 -64
  224. package/src/__tests__/integration-status.test.ts +93 -73
  225. package/src/__tests__/intent-routing.test.ts +148 -118
  226. package/src/__tests__/invite-redemption-service.test.ts +163 -121
  227. package/src/__tests__/ipc-blob-store.test.ts +104 -91
  228. package/src/__tests__/ipc-contract-inventory.test.ts +27 -15
  229. package/src/__tests__/ipc-contract.test.ts +24 -23
  230. package/src/__tests__/ipc-protocol.test.ts +52 -46
  231. package/src/__tests__/ipc-roundtrip.benchmark.test.ts +61 -50
  232. package/src/__tests__/ipc-snapshot.test.ts +1135 -1056
  233. package/src/__tests__/ipc-validate.test.ts +240 -179
  234. package/src/__tests__/key-migration.test.ts +123 -90
  235. package/src/__tests__/keychain.test.ts +150 -123
  236. package/src/__tests__/lifecycle-docs-guard.test.ts +65 -64
  237. package/src/__tests__/llm-usage-store.test.ts +112 -87
  238. package/src/__tests__/managed-skill-lifecycle.test.ts +147 -108
  239. package/src/__tests__/managed-store.test.ts +411 -360
  240. package/src/__tests__/mcp-cli.test.ts +189 -123
  241. package/src/__tests__/mcp-health-check.test.ts +26 -21
  242. package/src/__tests__/media-generate-image.test.ts +122 -99
  243. package/src/__tests__/media-reuse-story.e2e.test.ts +282 -214
  244. package/src/__tests__/media-visibility-policy.test.ts +86 -38
  245. package/src/__tests__/memory-context-benchmark.benchmark.test.ts +146 -100
  246. package/src/__tests__/memory-lifecycle-e2e.test.ts +385 -297
  247. package/src/__tests__/memory-query-builder.test.ts +32 -33
  248. package/src/__tests__/memory-recall-quality.test.ts +761 -407
  249. package/src/__tests__/memory-regressions.experimental.test.ts +443 -380
  250. package/src/__tests__/memory-regressions.test.ts +3725 -2642
  251. package/src/__tests__/memory-retrieval-budget.test.ts +7 -8
  252. package/src/__tests__/memory-retrieval.benchmark.test.ts +144 -109
  253. package/src/__tests__/memory-upsert-concurrency.test.ts +292 -201
  254. package/src/__tests__/messaging-send-tool.test.ts +36 -29
  255. package/src/__tests__/migration-cli-flows.test.ts +69 -53
  256. package/src/__tests__/migration-ordering.test.ts +103 -86
  257. package/src/__tests__/mime-builder.test.ts +55 -32
  258. package/src/__tests__/mock-signup-server.test.ts +384 -246
  259. package/src/__tests__/model-intents.test.ts +61 -37
  260. package/src/__tests__/no-direct-anthropic-sdk-imports.test.ts +9 -12
  261. package/src/__tests__/no-is-trusted-guard.test.ts +24 -21
  262. package/src/__tests__/non-member-access-request.test.ts +294 -249
  263. package/src/__tests__/notification-broadcaster.test.ts +99 -81
  264. package/src/__tests__/notification-decision-fallback.test.ts +223 -178
  265. package/src/__tests__/notification-decision-strategy.test.ts +375 -337
  266. package/src/__tests__/notification-deep-link.test.ts +67 -61
  267. package/src/__tests__/notification-guardian-path.test.ts +248 -206
  268. package/src/__tests__/notification-routing-intent.test.ts +166 -93
  269. package/src/__tests__/notification-telegram-adapter.test.ts +60 -46
  270. package/src/__tests__/notification-thread-candidate-validation.test.ts +78 -75
  271. package/src/__tests__/notification-thread-candidates.test.ts +64 -61
  272. package/src/__tests__/oauth-callback-registry.test.ts +40 -30
  273. package/src/__tests__/oauth-connect-handler.test.ts +109 -89
  274. package/src/__tests__/oauth-scope-policy.test.ts +63 -55
  275. package/src/__tests__/oauth2-gateway-transport.test.ts +252 -174
  276. package/src/__tests__/onboarding-starter-tasks.test.ts +93 -89
  277. package/src/__tests__/onboarding-template-contract.test.ts +93 -94
  278. package/src/__tests__/openai-provider.test.ts +366 -274
  279. package/src/__tests__/pairing-concurrent.test.ts +18 -12
  280. package/src/__tests__/pairing-routes.test.ts +45 -41
  281. package/src/__tests__/parallel-tool.benchmark.test.ts +108 -58
  282. package/src/__tests__/parser.test.ts +316 -226
  283. package/src/__tests__/path-classifier.test.ts +24 -25
  284. package/src/__tests__/path-policy.test.ts +187 -147
  285. package/src/__tests__/phone.test.ts +36 -36
  286. package/src/__tests__/platform-move-helper.test.ts +48 -40
  287. package/src/__tests__/platform-socket-path.test.ts +23 -24
  288. package/src/__tests__/platform-workspace-migration.test.ts +464 -414
  289. package/src/__tests__/platform.test.ts +61 -53
  290. package/src/__tests__/playbook-execution.test.ts +397 -265
  291. package/src/__tests__/playbook-tools.test.ts +267 -196
  292. package/src/__tests__/prebuilt-home-base-seed.test.ts +30 -27
  293. package/src/__tests__/pricing.test.ts +316 -136
  294. package/src/__tests__/profile-compiler.test.ts +206 -188
  295. package/src/__tests__/provider-commit-message-generator.test.ts +114 -106
  296. package/src/__tests__/provider-error-scenarios.test.ts +212 -158
  297. package/src/__tests__/provider-fail-open-selection.test.ts +51 -44
  298. package/src/__tests__/provider-registry-ollama.test.ts +13 -9
  299. package/src/__tests__/provider-streaming.benchmark.test.ts +232 -183
  300. package/src/__tests__/proxy-approval-callback.test.ts +180 -119
  301. package/src/__tests__/public-ingress-urls.test.ts +112 -94
  302. package/src/__tests__/qdrant-manager.test.ts +147 -98
  303. package/src/__tests__/ratelimit.test.ts +152 -82
  304. package/src/__tests__/recording-handler.test.ts +273 -151
  305. package/src/__tests__/recording-intent-fallback.test.ts +94 -75
  306. package/src/__tests__/recording-intent-handler.test.ts +422 -292
  307. package/src/__tests__/recording-intent.test.ts +578 -379
  308. package/src/__tests__/recording-state-machine.test.ts +530 -316
  309. package/src/__tests__/recurrence-engine-rruleset.test.ts +150 -92
  310. package/src/__tests__/recurrence-engine.test.ts +81 -41
  311. package/src/__tests__/recurrence-types.test.ts +63 -44
  312. package/src/__tests__/relay-server.test.ts +2131 -1602
  313. package/src/__tests__/reminder-store.test.ts +158 -80
  314. package/src/__tests__/reminder.test.ts +113 -109
  315. package/src/__tests__/remote-skill-policy.test.ts +96 -72
  316. package/src/__tests__/request-file-tool.test.ts +74 -67
  317. package/src/__tests__/response-tier.test.ts +131 -74
  318. package/src/__tests__/runtime-attachment-metadata.test.ts +107 -70
  319. package/src/__tests__/runtime-events-sse-parity.test.ts +167 -145
  320. package/src/__tests__/runtime-events-sse.test.ts +67 -51
  321. package/src/__tests__/sandbox-diagnostics.test.ts +66 -56
  322. package/src/__tests__/sandbox-host-parity.test.ts +377 -301
  323. package/src/__tests__/scaffold-managed-skill-tool.test.ts +213 -161
  324. package/src/__tests__/schedule-store.test.ts +268 -205
  325. package/src/__tests__/schedule-tools.test.ts +702 -524
  326. package/src/__tests__/scheduler-recurrence.test.ts +240 -130
  327. package/src/__tests__/scoped-approval-grants.test.ts +258 -168
  328. package/src/__tests__/scoped-grant-security-matrix.test.ts +160 -146
  329. package/src/__tests__/script-proxy-certs.test.ts +38 -35
  330. package/src/__tests__/script-proxy-connect-tunnel.test.ts +71 -46
  331. package/src/__tests__/script-proxy-decision-trace.test.ts +161 -84
  332. package/src/__tests__/script-proxy-http-forwarder.test.ts +146 -129
  333. package/src/__tests__/script-proxy-injection-runtime.test.ts +139 -113
  334. package/src/__tests__/script-proxy-mitm-handler.test.ts +226 -142
  335. package/src/__tests__/script-proxy-policy-runtime.test.ts +126 -86
  336. package/src/__tests__/script-proxy-policy.test.ts +308 -153
  337. package/src/__tests__/script-proxy-rewrite-specificity.test.ts +74 -62
  338. package/src/__tests__/script-proxy-router.test.ts +111 -77
  339. package/src/__tests__/script-proxy-session-manager.test.ts +156 -113
  340. package/src/__tests__/script-proxy-session-runtime.test.ts +28 -24
  341. package/src/__tests__/secret-allowlist.test.ts +105 -90
  342. package/src/__tests__/secret-ingress-handler.test.ts +41 -30
  343. package/src/__tests__/secret-onetime-send.test.ts +67 -50
  344. package/src/__tests__/secret-prompt-log-hygiene.test.ts +35 -31
  345. package/src/__tests__/secret-response-routing.test.ts +50 -41
  346. package/src/__tests__/secret-scanner-executor.test.ts +152 -111
  347. package/src/__tests__/secret-scanner.test.ts +495 -413
  348. package/src/__tests__/secure-keys.test.ts +132 -121
  349. package/src/__tests__/send-endpoint-busy.test.ts +313 -232
  350. package/src/__tests__/send-notification-tool.test.ts +43 -42
  351. package/src/__tests__/sensitive-output-placeholders.test.ts +72 -64
  352. package/src/__tests__/sequence-store.test.ts +335 -167
  353. package/src/__tests__/server-history-render.test.ts +341 -202
  354. package/src/__tests__/session-abort-tool-results.test.ts +133 -70
  355. package/src/__tests__/session-approval-overrides.test.ts +93 -91
  356. package/src/__tests__/session-confirmation-signals.test.ts +252 -160
  357. package/src/__tests__/session-conflict-gate.test.ts +775 -585
  358. package/src/__tests__/session-error.test.ts +222 -191
  359. package/src/__tests__/session-evictor.test.ts +79 -62
  360. package/src/__tests__/session-init.benchmark.test.ts +170 -108
  361. package/src/__tests__/session-load-history-repair.test.ts +273 -139
  362. package/src/__tests__/session-messaging-secret-redirect.test.ts +130 -90
  363. package/src/__tests__/session-pre-run-repair.test.ts +106 -59
  364. package/src/__tests__/session-profile-injection.test.ts +198 -130
  365. package/src/__tests__/session-provider-retry-repair.test.ts +223 -141
  366. package/src/__tests__/session-queue.test.ts +624 -321
  367. package/src/__tests__/session-runtime-assembly.test.ts +425 -329
  368. package/src/__tests__/session-runtime-workspace.test.ts +69 -61
  369. package/src/__tests__/session-skill-tools.test.ts +973 -678
  370. package/src/__tests__/session-slash-known.test.ts +185 -133
  371. package/src/__tests__/session-slash-queue.test.ts +147 -81
  372. package/src/__tests__/session-slash-unknown.test.ts +135 -90
  373. package/src/__tests__/session-surfaces-task-progress.test.ts +122 -87
  374. package/src/__tests__/session-tool-setup-app-refresh.test.ts +338 -177
  375. package/src/__tests__/session-tool-setup-memory-scope.test.ts +63 -40
  376. package/src/__tests__/session-tool-setup-side-effect-flag.test.ts +60 -37
  377. package/src/__tests__/session-tool-setup-tools-disabled.test.ts +28 -26
  378. package/src/__tests__/session-undo.test.ts +43 -30
  379. package/src/__tests__/session-workspace-cache-state.test.ts +108 -67
  380. package/src/__tests__/session-workspace-injection.test.ts +245 -117
  381. package/src/__tests__/session-workspace-tool-tracking.test.ts +260 -93
  382. package/src/__tests__/shared-filesystem-errors.test.ts +47 -47
  383. package/src/__tests__/shell-credential-ref.test.ts +126 -90
  384. package/src/__tests__/shell-identity.test.ts +134 -111
  385. package/src/__tests__/shell-parser-fuzz.test.ts +263 -179
  386. package/src/__tests__/shell-parser-property.test.ts +435 -288
  387. package/src/__tests__/shell-tool-proxy-mode.test.ts +142 -70
  388. package/src/__tests__/size-guard.test.ts +42 -44
  389. package/src/__tests__/skill-feature-flags-integration.test.ts +79 -52
  390. package/src/__tests__/skill-feature-flags.test.ts +75 -47
  391. package/src/__tests__/skill-include-graph.test.ts +143 -148
  392. package/src/__tests__/skill-load-feature-flag.test.ts +94 -59
  393. package/src/__tests__/skill-load-tool.test.ts +371 -199
  394. package/src/__tests__/skill-projection-feature-flag.test.ts +131 -88
  395. package/src/__tests__/skill-projection.benchmark.test.ts +93 -65
  396. package/src/__tests__/skill-script-runner-host.test.ts +460 -250
  397. package/src/__tests__/skill-script-runner-sandbox.test.ts +168 -108
  398. package/src/__tests__/skill-script-runner.test.ts +115 -74
  399. package/src/__tests__/skill-tool-factory.test.ts +140 -96
  400. package/src/__tests__/skill-tool-manifest.test.ts +306 -210
  401. package/src/__tests__/skill-version-hash.test.ts +70 -56
  402. package/src/__tests__/skills.test.ts +0 -1
  403. package/src/__tests__/slack-channel-config.test.ts +127 -84
  404. package/src/__tests__/slack-skill.test.ts +60 -47
  405. package/src/__tests__/slash-commands-catalog.test.ts +37 -31
  406. package/src/__tests__/slash-commands-parser.test.ts +71 -64
  407. package/src/__tests__/slash-commands-resolver.test.ts +143 -107
  408. package/src/__tests__/slash-commands-rewrite.test.ts +22 -22
  409. package/src/__tests__/sms-messaging-provider.test.ts +74 -47
  410. package/src/__tests__/speaker-identification.test.ts +28 -25
  411. package/src/__tests__/starter-bundle.test.ts +27 -23
  412. package/src/__tests__/starter-task-flow.test.ts +67 -52
  413. package/src/__tests__/subagent-manager-notify.test.ts +154 -108
  414. package/src/__tests__/subagent-tools.test.ts +311 -270
  415. package/src/__tests__/subagent-types.test.ts +40 -40
  416. package/src/__tests__/surface-mutex-cleanup.test.ts +42 -30
  417. package/src/__tests__/swarm-dag-pathological.test.ts +122 -111
  418. package/src/__tests__/swarm-orchestrator.test.ts +135 -101
  419. package/src/__tests__/swarm-plan-validator.test.ts +125 -73
  420. package/src/__tests__/swarm-recursion.test.ts +58 -46
  421. package/src/__tests__/swarm-router-planner.test.ts +99 -74
  422. package/src/__tests__/swarm-session-integration.test.ts +148 -91
  423. package/src/__tests__/swarm-tool.test.ts +65 -45
  424. package/src/__tests__/swarm-worker-backend.test.ts +59 -45
  425. package/src/__tests__/swarm-worker-runner.test.ts +133 -118
  426. package/src/__tests__/system-prompt.test.ts +290 -256
  427. package/src/__tests__/task-compiler.test.ts +176 -120
  428. package/src/__tests__/task-management-tools.test.ts +561 -456
  429. package/src/__tests__/task-memory-cleanup.test.ts +627 -362
  430. package/src/__tests__/task-runner.test.ts +117 -94
  431. package/src/__tests__/task-scheduler.test.ts +113 -84
  432. package/src/__tests__/task-tools.test.ts +349 -264
  433. package/src/__tests__/terminal-sandbox.test.ts +138 -108
  434. package/src/__tests__/terminal-tools.test.ts +350 -305
  435. package/src/__tests__/thread-seed-composer.test.ts +307 -180
  436. package/src/__tests__/tool-approval-handler.test.ts +238 -137
  437. package/src/__tests__/tool-audit-listener.test.ts +69 -69
  438. package/src/__tests__/tool-domain-event-publisher.test.ts +142 -132
  439. package/src/__tests__/tool-execution-abort-cleanup.test.ts +153 -146
  440. package/src/__tests__/tool-execution-pipeline.benchmark.test.ts +136 -105
  441. package/src/__tests__/tool-executor-lifecycle-events.test.ts +355 -239
  442. package/src/__tests__/tool-executor-redaction.test.ts +112 -109
  443. package/src/__tests__/tool-executor-shell-integration.test.ts +130 -79
  444. package/src/__tests__/tool-executor.test.ts +1274 -674
  445. package/src/__tests__/tool-grant-request-escalation.test.ts +401 -283
  446. package/src/__tests__/tool-metrics-listener.test.ts +97 -85
  447. package/src/__tests__/tool-notification-listener.test.ts +42 -25
  448. package/src/__tests__/tool-permission-simulate-handler.test.ts +137 -113
  449. package/src/__tests__/tool-policy.test.ts +44 -25
  450. package/src/__tests__/tool-profiling-listener.test.ts +99 -93
  451. package/src/__tests__/tool-result-truncation.test.ts +5 -4
  452. package/src/__tests__/tool-trace-listener.test.ts +131 -111
  453. package/src/__tests__/top-level-renderer.test.ts +62 -58
  454. package/src/__tests__/top-level-scanner.test.ts +68 -64
  455. package/src/__tests__/trace-emitter.test.ts +56 -56
  456. package/src/__tests__/trust-context-guards.test.ts +65 -65
  457. package/src/__tests__/trust-store.test.ts +1239 -806
  458. package/src/__tests__/trusted-contact-approval-notifier.test.ts +339 -275
  459. package/src/__tests__/trusted-contact-inline-approval-integration.test.ts +484 -373
  460. package/src/__tests__/trusted-contact-lifecycle-notifications.test.ts +264 -241
  461. package/src/__tests__/trusted-contact-multichannel.test.ts +182 -142
  462. package/src/__tests__/trusted-contact-verification.test.ts +251 -231
  463. package/src/__tests__/turn-commit.test.ts +259 -200
  464. package/src/__tests__/twilio-config.test.ts +49 -41
  465. package/src/__tests__/twilio-provider.test.ts +140 -126
  466. package/src/__tests__/twilio-rest.test.ts +22 -18
  467. package/src/__tests__/twilio-routes-elevenlabs.test.ts +188 -162
  468. package/src/__tests__/twilio-routes-twiml.test.ts +55 -55
  469. package/src/__tests__/twilio-routes.test.ts +389 -281
  470. package/src/__tests__/twitter-auth-handler.test.ts +184 -139
  471. package/src/__tests__/twitter-cli-error-shaping.test.ts +88 -73
  472. package/src/__tests__/twitter-cli-routing.test.ts +146 -99
  473. package/src/__tests__/twitter-oauth-client.test.ts +82 -65
  474. package/src/__tests__/update-bulletin-format.test.ts +69 -66
  475. package/src/__tests__/update-bulletin-state.test.ts +66 -60
  476. package/src/__tests__/update-bulletin.test.ts +150 -114
  477. package/src/__tests__/update-template-contract.test.ts +15 -10
  478. package/src/__tests__/url-safety.test.ts +288 -265
  479. package/src/__tests__/user-reference.test.ts +32 -32
  480. package/src/__tests__/view-image-tool.test.ts +118 -96
  481. package/src/__tests__/voice-invite-redemption.test.ts +111 -106
  482. package/src/__tests__/voice-quality.test.ts +117 -102
  483. package/src/__tests__/voice-scoped-grant-consumer.test.ts +204 -146
  484. package/src/__tests__/voice-session-bridge.test.ts +351 -216
  485. package/src/__tests__/weather-skill-regression.test.ts +170 -120
  486. package/src/__tests__/web-fetch.test.ts +664 -526
  487. package/src/__tests__/web-search.test.ts +379 -213
  488. package/src/__tests__/work-item-output.test.ts +90 -53
  489. package/src/__tests__/workspace-git-service.test.ts +437 -356
  490. package/src/__tests__/workspace-heartbeat-service.test.ts +125 -91
  491. package/src/__tests__/workspace-lifecycle.test.ts +98 -64
  492. package/src/__tests__/workspace-policy.test.ts +139 -71
  493. package/src/commands/__tests__/cc-command-registry.test.ts +142 -134
  494. package/src/config/__tests__/feature-flag-registry-guard.test.ts +48 -39
  495. package/src/config/bundled-skills/chatgpt-import/tools/chatgpt-import.ts +44 -4
  496. package/src/config/bundled-skills/doordash/__tests__/doordash-session.test.ts +0 -1
  497. package/src/config/bundled-skills/messaging/SKILL.md +9 -7
  498. package/src/config/bundled-skills/messaging/tools/gmail-outreach-scan.ts +15 -5
  499. package/src/config/bundled-skills/messaging/tools/gmail-sender-digest.ts +16 -5
  500. package/src/config/bundled-skills/messaging/tools/messaging-reply.ts +11 -7
  501. package/src/config/bundled-skills/slack/tools/slack-scan-digest.ts +34 -32
  502. package/src/config/bundled-tool-registry.ts +2 -0
  503. package/src/config/env.ts +38 -29
  504. package/src/daemon/handlers/skills.ts +18 -10
  505. package/src/daemon/ipc-contract/messages.ts +1 -0
  506. package/src/daemon/ipc-contract/surfaces.ts +7 -1
  507. package/src/daemon/session-agent-loop-handlers.ts +5 -0
  508. package/src/daemon/session-agent-loop.ts +1 -1
  509. package/src/daemon/session-process.ts +1 -1
  510. package/src/daemon/session-surfaces.ts +42 -2
  511. package/src/memory/db-connection.ts +16 -10
  512. package/src/messaging/providers/gmail/adapter.ts +10 -3
  513. package/src/messaging/providers/gmail/client.ts +280 -72
  514. package/src/runtime/auth/__tests__/context.test.ts +75 -65
  515. package/src/runtime/auth/__tests__/credential-service.test.ts +137 -114
  516. package/src/runtime/auth/__tests__/guard-tests.test.ts +84 -90
  517. package/src/runtime/auth/__tests__/ipc-auth-context.test.ts +40 -40
  518. package/src/runtime/auth/__tests__/middleware.test.ts +80 -74
  519. package/src/runtime/auth/__tests__/policy.test.ts +9 -9
  520. package/src/runtime/auth/__tests__/route-policy.test.ts +76 -65
  521. package/src/runtime/auth/__tests__/scopes.test.ts +68 -60
  522. package/src/runtime/auth/__tests__/subject.test.ts +54 -54
  523. package/src/runtime/auth/__tests__/token-service.test.ts +115 -108
  524. package/src/runtime/auth/scopes.ts +3 -0
  525. package/src/runtime/auth/token-service.ts +78 -48
  526. package/src/runtime/auth/types.ts +2 -1
  527. package/src/runtime/http-server.ts +2 -1
  528. package/src/security/secure-keys.ts +103 -53
  529. package/src/sequence/reply-matcher.ts +10 -6
  530. package/src/skills/frontmatter.ts +9 -6
  531. package/src/tools/browser/__tests__/auth-cache.test.ts +69 -63
  532. package/src/tools/browser/__tests__/auth-detector.test.ts +218 -157
  533. package/src/tools/browser/__tests__/jit-auth.test.ts +83 -99
  534. package/src/tools/ui-surface/definitions.ts +2 -1
  535. package/src/util/platform.ts +0 -12
  536. package/docs/architecture/http-token-refresh.md +0 -274
@@ -1,6 +1,6 @@
1
- import { beforeEach, describe, expect, it, mock } from 'bun:test';
1
+ import { beforeEach, describe, expect, it, mock } from "bun:test";
2
2
 
3
- import type { RuntimeAttachmentMetadata } from '../runtime/http-types.js';
3
+ import type { RuntimeAttachmentMetadata } from "../runtime/http-types.js";
4
4
 
5
5
  type DeliveryCall = {
6
6
  callbackUrl: string;
@@ -9,14 +9,21 @@ type DeliveryCall = {
9
9
  };
10
10
 
11
11
  const deliveryCalls: DeliveryCall[] = [];
12
- const conversationMessages: Array<{ id: string; role: string; content: string }> = [];
13
- const attachmentsByMessageId = new Map<string, Array<{
12
+ const conversationMessages: Array<{
14
13
  id: string;
15
- originalFilename?: string;
16
- mimeType?: string;
17
- sizeBytes?: number;
18
- kind?: string;
19
- }>>();
14
+ role: string;
15
+ content: string;
16
+ }> = [];
17
+ const attachmentsByMessageId = new Map<
18
+ string,
19
+ Array<{
20
+ id: string;
21
+ originalFilename?: string;
22
+ mimeType?: string;
23
+ sizeBytes?: number;
24
+ kind?: string;
25
+ }>
26
+ >();
20
27
 
21
28
  let renderedHistoryContent: {
22
29
  text: string;
@@ -26,7 +33,7 @@ let renderedHistoryContent: {
26
33
  contentOrder: string[];
27
34
  surfaces: unknown[];
28
35
  } = {
29
- text: '',
36
+ text: "",
30
37
  textSegments: [],
31
38
  toolCalls: [],
32
39
  toolCallsBeforeText: false,
@@ -36,29 +43,32 @@ let renderedHistoryContent: {
36
43
 
37
44
  let deliveryFailAtIndex = -1;
38
45
 
39
- mock.module('../runtime/gateway-client.js', () => ({
46
+ mock.module("../runtime/gateway-client.js", () => ({
40
47
  deliverChannelReply: async (
41
48
  callbackUrl: string,
42
49
  payload: Record<string, unknown>,
43
50
  bearerToken?: string,
44
51
  ) => {
45
- if (deliveryFailAtIndex >= 0 && deliveryCalls.length === deliveryFailAtIndex) {
46
- throw new Error('Simulated delivery failure (502)');
52
+ if (
53
+ deliveryFailAtIndex >= 0 &&
54
+ deliveryCalls.length === deliveryFailAtIndex
55
+ ) {
56
+ throw new Error("Simulated delivery failure (502)");
47
57
  }
48
58
  deliveryCalls.push({ callbackUrl, payload, bearerToken });
49
59
  },
50
60
  }));
51
61
 
52
- mock.module('../memory/conversation-store.js', () => ({
53
- getConversationThreadType: () => 'default',
62
+ mock.module("../memory/conversation-store.js", () => ({
63
+ getConversationThreadType: () => "default",
54
64
  setConversationOriginChannelIfUnset: () => {},
55
65
  updateConversationContextWindow: () => {},
56
66
  deleteMessageById: () => {},
57
67
  updateConversationTitle: () => {},
58
68
  updateConversationUsage: () => {},
59
- addMessage: () => ({ id: 'mock-msg-id' }),
69
+ addMessage: () => ({ id: "mock-msg-id" }),
60
70
  getConversation: () => ({
61
- id: 'conv-1',
71
+ id: "conv-1",
62
72
  contextSummary: null,
63
73
  contextCompactedMessageCount: 0,
64
74
  totalInputTokens: 0,
@@ -66,30 +76,35 @@ mock.module('../memory/conversation-store.js', () => ({
66
76
  totalEstimatedCost: 0,
67
77
  title: null,
68
78
  }),
69
- provenanceFromGuardianContext: () => ({ source: 'user', guardianContext: undefined }),
79
+ provenanceFromGuardianContext: () => ({
80
+ source: "user",
81
+ guardianContext: undefined,
82
+ }),
70
83
  getConversationOriginInterface: () => null,
71
84
  getConversationOriginChannel: () => null,
72
85
  getMessages: () => conversationMessages,
73
86
  }));
74
87
 
75
- mock.module('../memory/attachments-store.js', () => ({
76
- getAttachmentMetadataForMessage: (messageId: string) => attachmentsByMessageId.get(messageId) ?? [],
88
+ mock.module("../memory/attachments-store.js", () => ({
89
+ getAttachmentMetadataForMessage: (messageId: string) =>
90
+ attachmentsByMessageId.get(messageId) ?? [],
77
91
  }));
78
92
 
79
- mock.module('../daemon/handlers.js', () => ({
93
+ mock.module("../daemon/handlers.js", () => ({
80
94
  renderHistoryContent: () => renderedHistoryContent,
81
95
  }));
82
96
 
83
- const { deliverRenderedReplyViaCallback, deliverReplyViaCallback } = await import('../runtime/channel-reply-delivery.js');
97
+ const { deliverRenderedReplyViaCallback, deliverReplyViaCallback } =
98
+ await import("../runtime/channel-reply-delivery.js");
84
99
 
85
- describe('channel-reply-delivery', () => {
100
+ describe("channel-reply-delivery", () => {
86
101
  beforeEach(() => {
87
102
  deliveryCalls.length = 0;
88
103
  deliveryFailAtIndex = -1;
89
104
  conversationMessages.length = 0;
90
105
  attachmentsByMessageId.clear();
91
106
  renderedHistoryContent = {
92
- text: '',
107
+ text: "",
93
108
  textSegments: [],
94
109
  toolCalls: [],
95
110
  toolCallsBeforeText: false,
@@ -98,130 +113,144 @@ describe('channel-reply-delivery', () => {
98
113
  };
99
114
  });
100
115
 
101
- it('sends non-empty text segments as separate messages and puts attachments on the last segment', async () => {
116
+ it("sends non-empty text segments as separate messages and puts attachments on the last segment", async () => {
102
117
  const attachments: RuntimeAttachmentMetadata[] = [
103
- { id: 'att-1', filename: 'file.txt', mimeType: 'text/plain', sizeBytes: 5, kind: 'uploaded' },
118
+ {
119
+ id: "att-1",
120
+ filename: "file.txt",
121
+ mimeType: "text/plain",
122
+ sizeBytes: 5,
123
+ kind: "uploaded",
124
+ },
104
125
  ];
105
126
 
106
127
  await deliverRenderedReplyViaCallback({
107
- callbackUrl: 'http://gateway/deliver/telegram',
108
- chatId: 'chat-1',
109
- textSegments: ['Before tool.', ' ', '', 'After tool.'],
110
- fallbackText: 'Before tool.After tool.',
128
+ callbackUrl: "http://gateway/deliver/telegram",
129
+ chatId: "chat-1",
130
+ textSegments: ["Before tool.", " ", "", "After tool."],
131
+ fallbackText: "Before tool.After tool.",
111
132
  attachments,
112
- assistantId: 'assistant-1',
113
- bearerToken: 'token',
133
+ assistantId: "assistant-1",
134
+ bearerToken: "token",
114
135
  interSegmentDelayMs: 0,
115
136
  });
116
137
 
117
138
  expect(deliveryCalls).toHaveLength(2);
118
139
  expect(deliveryCalls[0]).toEqual({
119
- callbackUrl: 'http://gateway/deliver/telegram',
140
+ callbackUrl: "http://gateway/deliver/telegram",
120
141
  payload: {
121
- chatId: 'chat-1',
122
- text: 'Before tool.',
142
+ chatId: "chat-1",
143
+ text: "Before tool.",
123
144
  attachments: undefined,
124
- assistantId: 'assistant-1',
145
+ assistantId: "assistant-1",
125
146
  },
126
- bearerToken: 'token',
147
+ bearerToken: "token",
127
148
  });
128
149
  expect(deliveryCalls[1]).toEqual({
129
- callbackUrl: 'http://gateway/deliver/telegram',
150
+ callbackUrl: "http://gateway/deliver/telegram",
130
151
  payload: {
131
- chatId: 'chat-1',
132
- text: 'After tool.',
152
+ chatId: "chat-1",
153
+ text: "After tool.",
133
154
  attachments,
134
- assistantId: 'assistant-1',
155
+ assistantId: "assistant-1",
135
156
  },
136
- bearerToken: 'token',
157
+ bearerToken: "token",
137
158
  });
138
159
  });
139
160
 
140
- it('falls back to rendered.text when no non-empty textSegments exist', async () => {
161
+ it("falls back to rendered.text when no non-empty textSegments exist", async () => {
141
162
  await deliverRenderedReplyViaCallback({
142
- callbackUrl: 'http://gateway/deliver/sms',
143
- chatId: 'chat-2',
144
- textSegments: [' ', ''],
145
- fallbackText: 'Fallback text',
163
+ callbackUrl: "http://gateway/deliver/sms",
164
+ chatId: "chat-2",
165
+ textSegments: [" ", ""],
166
+ fallbackText: "Fallback text",
146
167
  interSegmentDelayMs: 0,
147
168
  });
148
169
 
149
170
  expect(deliveryCalls).toHaveLength(1);
150
- expect(deliveryCalls[0].payload.text).toBe('Fallback text');
171
+ expect(deliveryCalls[0].payload.text).toBe("Fallback text");
151
172
  });
152
173
 
153
- it('uses rendered textSegments (tool boundaries) when delivering from conversation history', async () => {
174
+ it("uses rendered textSegments (tool boundaries) when delivering from conversation history", async () => {
154
175
  conversationMessages.push(
155
- { id: 'msg-user', role: 'user', content: 'hi' },
156
- { id: 'msg-assistant', role: 'assistant', content: '[{"type":"text","text":"ignored"}]' },
176
+ { id: "msg-user", role: "user", content: "hi" },
177
+ {
178
+ id: "msg-assistant",
179
+ role: "assistant",
180
+ content: '[{"type":"text","text":"ignored"}]',
181
+ },
157
182
  );
158
- attachmentsByMessageId.set('msg-assistant', [{
159
- id: 'att-2',
160
- originalFilename: 'log.txt',
161
- mimeType: 'text/plain',
162
- sizeBytes: 42,
163
- kind: 'uploaded',
164
- }]);
183
+ attachmentsByMessageId.set("msg-assistant", [
184
+ {
185
+ id: "att-2",
186
+ originalFilename: "log.txt",
187
+ mimeType: "text/plain",
188
+ sizeBytes: 42,
189
+ kind: "uploaded",
190
+ },
191
+ ]);
165
192
  renderedHistoryContent = {
166
- text: 'Before tool.After tool.',
167
- textSegments: ['Before tool.', 'After tool.'],
193
+ text: "Before tool.After tool.",
194
+ textSegments: ["Before tool.", "After tool."],
168
195
  toolCalls: [],
169
196
  toolCallsBeforeText: false,
170
- contentOrder: ['text:0', 'tool:0', 'text:1'],
197
+ contentOrder: ["text:0", "tool:0", "text:1"],
171
198
  surfaces: [],
172
199
  };
173
200
 
174
201
  await deliverReplyViaCallback(
175
- 'conv-1',
176
- 'chat-3',
177
- 'http://gateway/deliver/telegram',
178
- 'token',
179
- 'assistant-2',
202
+ "conv-1",
203
+ "chat-3",
204
+ "http://gateway/deliver/telegram",
205
+ "token",
206
+ "assistant-2",
180
207
  );
181
208
 
182
209
  expect(deliveryCalls).toHaveLength(2);
183
210
  expect(deliveryCalls[0].payload).toEqual({
184
- chatId: 'chat-3',
185
- text: 'Before tool.',
211
+ chatId: "chat-3",
212
+ text: "Before tool.",
186
213
  attachments: undefined,
187
- assistantId: 'assistant-2',
214
+ assistantId: "assistant-2",
188
215
  });
189
216
  expect(deliveryCalls[1].payload).toEqual({
190
- chatId: 'chat-3',
191
- text: 'After tool.',
192
- attachments: [{
193
- id: 'att-2',
194
- filename: 'log.txt',
195
- mimeType: 'text/plain',
196
- sizeBytes: 42,
197
- kind: 'uploaded',
198
- }],
199
- assistantId: 'assistant-2',
217
+ chatId: "chat-3",
218
+ text: "After tool.",
219
+ attachments: [
220
+ {
221
+ id: "att-2",
222
+ filename: "log.txt",
223
+ mimeType: "text/plain",
224
+ sizeBytes: 42,
225
+ kind: "uploaded",
226
+ },
227
+ ],
228
+ assistantId: "assistant-2",
200
229
  });
201
230
  });
202
231
 
203
- it('skips already-delivered segments when startFromSegment is set', async () => {
232
+ it("skips already-delivered segments when startFromSegment is set", async () => {
204
233
  await deliverRenderedReplyViaCallback({
205
- callbackUrl: 'http://gateway/deliver/telegram',
206
- chatId: 'chat-resume',
207
- textSegments: ['Segment A.', 'Segment B.', 'Segment C.'],
234
+ callbackUrl: "http://gateway/deliver/telegram",
235
+ chatId: "chat-resume",
236
+ textSegments: ["Segment A.", "Segment B.", "Segment C."],
208
237
  interSegmentDelayMs: 0,
209
238
  startFromSegment: 1,
210
239
  });
211
240
 
212
241
  // Should only deliver segments B and C (indices 1 and 2)
213
242
  expect(deliveryCalls).toHaveLength(2);
214
- expect(deliveryCalls[0].payload.text).toBe('Segment B.');
215
- expect(deliveryCalls[1].payload.text).toBe('Segment C.');
243
+ expect(deliveryCalls[0].payload.text).toBe("Segment B.");
244
+ expect(deliveryCalls[1].payload.text).toBe("Segment C.");
216
245
  });
217
246
 
218
- it('calls onSegmentDelivered after each successful segment', async () => {
247
+ it("calls onSegmentDelivered after each successful segment", async () => {
219
248
  const delivered: number[] = [];
220
249
 
221
250
  await deliverRenderedReplyViaCallback({
222
- callbackUrl: 'http://gateway/deliver/telegram',
223
- chatId: 'chat-progress',
224
- textSegments: ['Part 1.', 'Part 2.', 'Part 3.'],
251
+ callbackUrl: "http://gateway/deliver/telegram",
252
+ chatId: "chat-progress",
253
+ textSegments: ["Part 1.", "Part 2.", "Part 3."],
225
254
  interSegmentDelayMs: 0,
226
255
  onSegmentDelivered: (count) => delivered.push(count),
227
256
  });
@@ -230,15 +259,15 @@ describe('channel-reply-delivery', () => {
230
259
  expect(deliveryCalls).toHaveLength(3);
231
260
  });
232
261
 
233
- it('does not call onSegmentDelivered for a failing segment', async () => {
262
+ it("does not call onSegmentDelivered for a failing segment", async () => {
234
263
  const delivered: number[] = [];
235
264
  deliveryFailAtIndex = 2;
236
265
 
237
266
  try {
238
267
  await deliverRenderedReplyViaCallback({
239
- callbackUrl: 'http://gateway/deliver/telegram',
240
- chatId: 'chat-fail',
241
- textSegments: ['Part 1.', 'Part 2.', 'Part 3.'],
268
+ callbackUrl: "http://gateway/deliver/telegram",
269
+ chatId: "chat-fail",
270
+ textSegments: ["Part 1.", "Part 2.", "Part 3."],
242
271
  interSegmentDelayMs: 0,
243
272
  onSegmentDelivered: (count) => delivered.push(count),
244
273
  });
@@ -251,16 +280,16 @@ describe('channel-reply-delivery', () => {
251
280
  expect(deliveryCalls).toHaveLength(2);
252
281
  });
253
282
 
254
- it('resumes delivery after partial failure using startFromSegment', async () => {
283
+ it("resumes delivery after partial failure using startFromSegment", async () => {
255
284
  const delivered: number[] = [];
256
285
 
257
286
  // First attempt: fails on third segment (index 2)
258
287
  deliveryFailAtIndex = 2;
259
288
  try {
260
289
  await deliverRenderedReplyViaCallback({
261
- callbackUrl: 'http://gateway/deliver/telegram',
262
- chatId: 'chat-retry',
263
- textSegments: ['Seg A.', 'Seg B.', 'Seg C.'],
290
+ callbackUrl: "http://gateway/deliver/telegram",
291
+ chatId: "chat-retry",
292
+ textSegments: ["Seg A.", "Seg B.", "Seg C."],
264
293
  interSegmentDelayMs: 0,
265
294
  onSegmentDelivered: (count) => delivered.push(count),
266
295
  });
@@ -278,9 +307,9 @@ describe('channel-reply-delivery', () => {
278
307
 
279
308
  // Retry: start from segment 2 (the last delivered count)
280
309
  await deliverRenderedReplyViaCallback({
281
- callbackUrl: 'http://gateway/deliver/telegram',
282
- chatId: 'chat-retry',
283
- textSegments: ['Seg A.', 'Seg B.', 'Seg C.'],
310
+ callbackUrl: "http://gateway/deliver/telegram",
311
+ chatId: "chat-retry",
312
+ textSegments: ["Seg A.", "Seg B.", "Seg C."],
284
313
  interSegmentDelayMs: 0,
285
314
  startFromSegment: 2,
286
315
  onSegmentDelivered: (count) => delivered.push(count),
@@ -288,15 +317,15 @@ describe('channel-reply-delivery', () => {
288
317
 
289
318
  // Only segment C should be delivered
290
319
  expect(deliveryCalls).toHaveLength(1);
291
- expect(deliveryCalls[0].payload.text).toBe('Seg C.');
320
+ expect(deliveryCalls[0].payload.text).toBe("Seg C.");
292
321
  expect(delivered).toEqual([3]);
293
322
  });
294
323
 
295
- it('skips all segments when startFromSegment equals total count', async () => {
324
+ it("skips all segments when startFromSegment equals total count", async () => {
296
325
  await deliverRenderedReplyViaCallback({
297
- callbackUrl: 'http://gateway/deliver/telegram',
298
- chatId: 'chat-done',
299
- textSegments: ['Done A.', 'Done B.'],
326
+ callbackUrl: "http://gateway/deliver/telegram",
327
+ chatId: "chat-done",
328
+ textSegments: ["Done A.", "Done B."],
300
329
  interSegmentDelayMs: 0,
301
330
  startFromSegment: 2,
302
331
  });
@@ -305,27 +334,27 @@ describe('channel-reply-delivery', () => {
305
334
  expect(deliveryCalls).toHaveLength(0);
306
335
  });
307
336
 
308
- it('passes startFromSegment through deliverReplyViaCallback options', async () => {
337
+ it("passes startFromSegment through deliverReplyViaCallback options", async () => {
309
338
  conversationMessages.push(
310
- { id: 'msg-u', role: 'user', content: 'hi' },
311
- { id: 'msg-a', role: 'assistant', content: '"text"' },
339
+ { id: "msg-u", role: "user", content: "hi" },
340
+ { id: "msg-a", role: "assistant", content: '"text"' },
312
341
  );
313
342
  renderedHistoryContent = {
314
- text: 'Alpha.Beta.Gamma.',
315
- textSegments: ['Alpha.', 'Beta.', 'Gamma.'],
343
+ text: "Alpha.Beta.Gamma.",
344
+ textSegments: ["Alpha.", "Beta.", "Gamma."],
316
345
  toolCalls: [],
317
346
  toolCallsBeforeText: false,
318
- contentOrder: ['text:0', 'tool:0', 'text:1', 'tool:1', 'text:2'],
347
+ contentOrder: ["text:0", "tool:0", "text:1", "tool:1", "text:2"],
319
348
  surfaces: [],
320
349
  };
321
350
 
322
351
  const delivered: number[] = [];
323
352
  await deliverReplyViaCallback(
324
- 'conv-resume',
325
- 'chat-resume',
326
- 'http://gateway/deliver/telegram',
327
- 'token',
328
- 'assistant-3',
353
+ "conv-resume",
354
+ "chat-resume",
355
+ "http://gateway/deliver/telegram",
356
+ "token",
357
+ "assistant-3",
329
358
  {
330
359
  startFromSegment: 1,
331
360
  onSegmentDelivered: (count) => delivered.push(count),
@@ -334,8 +363,8 @@ describe('channel-reply-delivery', () => {
334
363
 
335
364
  // Should skip 'Alpha.' and deliver 'Beta.' and 'Gamma.'
336
365
  expect(deliveryCalls).toHaveLength(2);
337
- expect(deliveryCalls[0].payload.text).toBe('Beta.');
338
- expect(deliveryCalls[1].payload.text).toBe('Gamma.');
366
+ expect(deliveryCalls[0].payload.text).toBe("Beta.");
367
+ expect(deliveryCalls[1].payload.text).toBe("Gamma.");
339
368
  expect(delivered).toEqual([2, 3]);
340
369
  });
341
370
  });