@relaycast/engine 1.1.7

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 (445) hide show
  1. package/dist/adapters/node/database.d.ts +25 -0
  2. package/dist/adapters/node/database.d.ts.map +1 -0
  3. package/dist/adapters/node/database.js +71 -0
  4. package/dist/adapters/node/database.js.map +1 -0
  5. package/dist/adapters/node/event-queue.d.ts +15 -0
  6. package/dist/adapters/node/event-queue.d.ts.map +1 -0
  7. package/dist/adapters/node/event-queue.js +27 -0
  8. package/dist/adapters/node/event-queue.js.map +1 -0
  9. package/dist/adapters/node/files.d.ts +47 -0
  10. package/dist/adapters/node/files.d.ts.map +1 -0
  11. package/dist/adapters/node/files.js +128 -0
  12. package/dist/adapters/node/files.js.map +1 -0
  13. package/dist/adapters/node/index.d.ts +60 -0
  14. package/dist/adapters/node/index.d.ts.map +1 -0
  15. package/dist/adapters/node/index.js +79 -0
  16. package/dist/adapters/node/index.js.map +1 -0
  17. package/dist/adapters/node/kv.d.ts +27 -0
  18. package/dist/adapters/node/kv.d.ts.map +1 -0
  19. package/dist/adapters/node/kv.js +67 -0
  20. package/dist/adapters/node/kv.js.map +1 -0
  21. package/dist/adapters/node/mcp.d.ts +18 -0
  22. package/dist/adapters/node/mcp.d.ts.map +1 -0
  23. package/dist/adapters/node/mcp.js +53 -0
  24. package/dist/adapters/node/mcp.js.map +1 -0
  25. package/dist/adapters/node/presence.d.ts +33 -0
  26. package/dist/adapters/node/presence.d.ts.map +1 -0
  27. package/dist/adapters/node/presence.js +113 -0
  28. package/dist/adapters/node/presence.js.map +1 -0
  29. package/dist/adapters/node/rate-limit.d.ts +17 -0
  30. package/dist/adapters/node/rate-limit.d.ts.map +1 -0
  31. package/dist/adapters/node/rate-limit.js +36 -0
  32. package/dist/adapters/node/rate-limit.js.map +1 -0
  33. package/dist/adapters/node/realtime.d.ts +72 -0
  34. package/dist/adapters/node/realtime.d.ts.map +1 -0
  35. package/dist/adapters/node/realtime.js +274 -0
  36. package/dist/adapters/node/realtime.js.map +1 -0
  37. package/dist/auth/index.d.ts +21 -0
  38. package/dist/auth/index.d.ts.map +1 -0
  39. package/dist/auth/index.js +50 -0
  40. package/dist/auth/index.js.map +1 -0
  41. package/dist/bin/serve.d.ts +3 -0
  42. package/dist/bin/serve.d.ts.map +1 -0
  43. package/dist/bin/serve.js +74 -0
  44. package/dist/bin/serve.js.map +1 -0
  45. package/dist/db/index.d.ts +16 -0
  46. package/dist/db/index.d.ts.map +1 -0
  47. package/dist/db/index.js +24 -0
  48. package/dist/db/index.js.map +1 -0
  49. package/dist/db/migrate.d.ts +14 -0
  50. package/dist/db/migrate.d.ts.map +1 -0
  51. package/dist/db/migrate.js +16 -0
  52. package/dist/db/migrate.js.map +1 -0
  53. package/dist/db/migrations/0000_broad_dagger.sql +227 -0
  54. package/dist/db/migrations/0001_fts5_search.sql +23 -0
  55. package/dist/db/migrations/0002_add_metadata_columns.sql +16 -0
  56. package/dist/db/migrations/0003_add_channel_mute.sql +5 -0
  57. package/dist/db/migrations/0004_a2a_agents.sql +21 -0
  58. package/dist/db/migrations/0005_certifications.sql +24 -0
  59. package/dist/db/migrations/0006_message_logs.sql +30 -0
  60. package/dist/db/migrations/0007_directory.sql +125 -0
  61. package/dist/db/migrations/0008_smart_routing.sql +30 -0
  62. package/dist/db/migrations/0009_drop_workspace_name_unique.sql +4 -0
  63. package/dist/db/migrations/0010_actions_and_harness.sql +108 -0
  64. package/dist/db/migrations/0011_stable_handle.sql +5 -0
  65. package/dist/db/migrations/0012_delivery_and_sequence_constraints.sql +26 -0
  66. package/dist/db/migrations/0013_status_active.sql +9 -0
  67. package/dist/db/migrations/meta/0000_snapshot.json +1694 -0
  68. package/dist/db/migrations/meta/_journal.json +13 -0
  69. package/dist/db/schema.d.ts +4742 -0
  70. package/dist/db/schema.d.ts.map +1 -0
  71. package/dist/db/schema.js +572 -0
  72. package/dist/db/schema.js.map +1 -0
  73. package/dist/engine/a2a-health.d.ts +11 -0
  74. package/dist/engine/a2a-health.d.ts.map +1 -0
  75. package/dist/engine/a2a-health.js +65 -0
  76. package/dist/engine/a2a-health.js.map +1 -0
  77. package/dist/engine/a2a.d.ts +73 -0
  78. package/dist/engine/a2a.d.ts.map +1 -0
  79. package/dist/engine/a2a.js +549 -0
  80. package/dist/engine/a2a.js.map +1 -0
  81. package/dist/engine/action.d.ts +85 -0
  82. package/dist/engine/action.d.ts.map +1 -0
  83. package/dist/engine/action.js +220 -0
  84. package/dist/engine/action.js.map +1 -0
  85. package/dist/engine/activity.d.ts +21 -0
  86. package/dist/engine/activity.d.ts.map +1 -0
  87. package/dist/engine/activity.js +46 -0
  88. package/dist/engine/activity.js.map +1 -0
  89. package/dist/engine/agent.d.ts +155 -0
  90. package/dist/engine/agent.d.ts.map +1 -0
  91. package/dist/engine/agent.js +408 -0
  92. package/dist/engine/agent.js.map +1 -0
  93. package/dist/engine/cache.d.ts +19 -0
  94. package/dist/engine/cache.d.ts.map +1 -0
  95. package/dist/engine/cache.js +40 -0
  96. package/dist/engine/cache.js.map +1 -0
  97. package/dist/engine/certify.d.ts +84 -0
  98. package/dist/engine/certify.d.ts.map +1 -0
  99. package/dist/engine/certify.js +452 -0
  100. package/dist/engine/certify.js.map +1 -0
  101. package/dist/engine/channel.d.ts +67 -0
  102. package/dist/engine/channel.d.ts.map +1 -0
  103. package/dist/engine/channel.js +375 -0
  104. package/dist/engine/channel.js.map +1 -0
  105. package/dist/engine/console.d.ts +83 -0
  106. package/dist/engine/console.d.ts.map +1 -0
  107. package/dist/engine/console.js +189 -0
  108. package/dist/engine/console.js.map +1 -0
  109. package/dist/engine/directory.d.ts +241 -0
  110. package/dist/engine/directory.d.ts.map +1 -0
  111. package/dist/engine/directory.js +528 -0
  112. package/dist/engine/directory.js.map +1 -0
  113. package/dist/engine/dm.d.ts +63 -0
  114. package/dist/engine/dm.d.ts.map +1 -0
  115. package/dist/engine/dm.js +397 -0
  116. package/dist/engine/dm.js.map +1 -0
  117. package/dist/engine/dmAll.d.ts +11 -0
  118. package/dist/engine/dmAll.d.ts.map +1 -0
  119. package/dist/engine/dmAll.js +117 -0
  120. package/dist/engine/dmAll.js.map +1 -0
  121. package/dist/engine/event-id.d.ts +2 -0
  122. package/dist/engine/event-id.d.ts.map +1 -0
  123. package/dist/engine/event-id.js +0 -0
  124. package/dist/engine/event-id.js.map +1 -0
  125. package/dist/engine/eventDelivery.d.ts +12 -0
  126. package/dist/engine/eventDelivery.d.ts.map +1 -0
  127. package/dist/engine/eventDelivery.js +103 -0
  128. package/dist/engine/eventDelivery.js.map +1 -0
  129. package/dist/engine/eventQueue.d.ts +6 -0
  130. package/dist/engine/eventQueue.d.ts.map +1 -0
  131. package/dist/engine/eventQueue.js +23 -0
  132. package/dist/engine/eventQueue.js.map +1 -0
  133. package/dist/engine/eventSubscription.d.ts +59 -0
  134. package/dist/engine/eventSubscription.d.ts.map +1 -0
  135. package/dist/engine/eventSubscription.js +74 -0
  136. package/dist/engine/eventSubscription.js.map +1 -0
  137. package/dist/engine/file.d.ts +43 -0
  138. package/dist/engine/file.d.ts.map +1 -0
  139. package/dist/engine/file.js +115 -0
  140. package/dist/engine/file.js.map +1 -0
  141. package/dist/engine/groupDm.d.ts +54 -0
  142. package/dist/engine/groupDm.d.ts.map +1 -0
  143. package/dist/engine/groupDm.js +262 -0
  144. package/dist/engine/groupDm.js.map +1 -0
  145. package/dist/engine/inboundWebhook.d.ts +45 -0
  146. package/dist/engine/inboundWebhook.d.ts.map +1 -0
  147. package/dist/engine/inboundWebhook.js +170 -0
  148. package/dist/engine/inboundWebhook.js.map +1 -0
  149. package/dist/engine/inbox.d.ts +34 -0
  150. package/dist/engine/inbox.d.ts.map +1 -0
  151. package/dist/engine/inbox.js +141 -0
  152. package/dist/engine/inbox.js.map +1 -0
  153. package/dist/engine/index.d.ts +10 -0
  154. package/dist/engine/index.d.ts.map +1 -0
  155. package/dist/engine/index.js +10 -0
  156. package/dist/engine/index.js.map +1 -0
  157. package/dist/engine/message.d.ts +81 -0
  158. package/dist/engine/message.d.ts.map +1 -0
  159. package/dist/engine/message.js +293 -0
  160. package/dist/engine/message.js.map +1 -0
  161. package/dist/engine/presence.d.ts +12 -0
  162. package/dist/engine/presence.d.ts.map +1 -0
  163. package/dist/engine/presence.js +24 -0
  164. package/dist/engine/presence.js.map +1 -0
  165. package/dist/engine/reaction.d.ts +19 -0
  166. package/dist/engine/reaction.d.ts.map +1 -0
  167. package/dist/engine/reaction.js +97 -0
  168. package/dist/engine/reaction.js.map +1 -0
  169. package/dist/engine/receipt.d.ts +19 -0
  170. package/dist/engine/receipt.d.ts.map +1 -0
  171. package/dist/engine/receipt.js +96 -0
  172. package/dist/engine/receipt.js.map +1 -0
  173. package/dist/engine/resyncQuery.d.ts +15 -0
  174. package/dist/engine/resyncQuery.d.ts.map +1 -0
  175. package/dist/engine/resyncQuery.js +124 -0
  176. package/dist/engine/resyncQuery.js.map +1 -0
  177. package/dist/engine/routing.d.ts +45 -0
  178. package/dist/engine/routing.d.ts.map +1 -0
  179. package/dist/engine/routing.js +390 -0
  180. package/dist/engine/routing.js.map +1 -0
  181. package/dist/engine/search.d.ts +19 -0
  182. package/dist/engine/search.d.ts.map +1 -0
  183. package/dist/engine/search.js +60 -0
  184. package/dist/engine/search.js.map +1 -0
  185. package/dist/engine/searchQuery.d.ts +8 -0
  186. package/dist/engine/searchQuery.d.ts.map +1 -0
  187. package/dist/engine/searchQuery.js +19 -0
  188. package/dist/engine/searchQuery.js.map +1 -0
  189. package/dist/engine/sessionEvent.d.ts +29 -0
  190. package/dist/engine/sessionEvent.d.ts.map +1 -0
  191. package/dist/engine/sessionEvent.js +76 -0
  192. package/dist/engine/sessionEvent.js.map +1 -0
  193. package/dist/engine/snowflake.d.ts +14 -0
  194. package/dist/engine/snowflake.d.ts.map +1 -0
  195. package/dist/engine/snowflake.js +88 -0
  196. package/dist/engine/snowflake.js.map +1 -0
  197. package/dist/engine/systemPrompt.d.ts +13 -0
  198. package/dist/engine/systemPrompt.d.ts.map +1 -0
  199. package/dist/engine/systemPrompt.js +31 -0
  200. package/dist/engine/systemPrompt.js.map +1 -0
  201. package/dist/engine/thread.d.ts +56 -0
  202. package/dist/engine/thread.d.ts.map +1 -0
  203. package/dist/engine/thread.js +158 -0
  204. package/dist/engine/thread.js.map +1 -0
  205. package/dist/engine/tokenRotate.d.ts +8 -0
  206. package/dist/engine/tokenRotate.d.ts.map +1 -0
  207. package/dist/engine/tokenRotate.js +25 -0
  208. package/dist/engine/tokenRotate.js.map +1 -0
  209. package/dist/engine/usage.d.ts +16 -0
  210. package/dist/engine/usage.d.ts.map +1 -0
  211. package/dist/engine/usage.js +24 -0
  212. package/dist/engine/usage.js.map +1 -0
  213. package/dist/engine/workspace.d.ts +44 -0
  214. package/dist/engine/workspace.d.ts.map +1 -0
  215. package/dist/engine/workspace.js +127 -0
  216. package/dist/engine/workspace.js.map +1 -0
  217. package/dist/engine/wsTransform.d.ts +14 -0
  218. package/dist/engine/wsTransform.d.ts.map +1 -0
  219. package/dist/engine/wsTransform.js +196 -0
  220. package/dist/engine/wsTransform.js.map +1 -0
  221. package/dist/engine.d.ts +18 -0
  222. package/dist/engine.d.ts.map +1 -0
  223. package/dist/engine.js +275 -0
  224. package/dist/engine.js.map +1 -0
  225. package/dist/entrypoints/node.d.ts +35 -0
  226. package/dist/entrypoints/node.d.ts.map +1 -0
  227. package/dist/entrypoints/node.js +114 -0
  228. package/dist/entrypoints/node.js.map +1 -0
  229. package/dist/env.d.ts +38 -0
  230. package/dist/env.d.ts.map +1 -0
  231. package/dist/env.js +2 -0
  232. package/dist/env.js.map +1 -0
  233. package/dist/index.d.ts +14 -0
  234. package/dist/index.d.ts.map +1 -0
  235. package/dist/index.js +16 -0
  236. package/dist/index.js.map +1 -0
  237. package/dist/lib/logger.d.ts +47 -0
  238. package/dist/lib/logger.d.ts.map +1 -0
  239. package/dist/lib/logger.js +214 -0
  240. package/dist/lib/logger.js.map +1 -0
  241. package/dist/lib/origin.d.ts +25 -0
  242. package/dist/lib/origin.d.ts.map +1 -0
  243. package/dist/lib/origin.js +80 -0
  244. package/dist/lib/origin.js.map +1 -0
  245. package/dist/lib/serverTelemetry.d.ts +12 -0
  246. package/dist/lib/serverTelemetry.d.ts.map +1 -0
  247. package/dist/lib/serverTelemetry.js +46 -0
  248. package/dist/lib/serverTelemetry.js.map +1 -0
  249. package/dist/lib/ssrf.d.ts +23 -0
  250. package/dist/lib/ssrf.d.ts.map +1 -0
  251. package/dist/lib/ssrf.js +57 -0
  252. package/dist/lib/ssrf.js.map +1 -0
  253. package/dist/lib/workspaceStream.d.ts +9 -0
  254. package/dist/lib/workspaceStream.d.ts.map +1 -0
  255. package/dist/lib/workspaceStream.js +53 -0
  256. package/dist/lib/workspaceStream.js.map +1 -0
  257. package/dist/middleware/auth.d.ts +9 -0
  258. package/dist/middleware/auth.d.ts.map +1 -0
  259. package/dist/middleware/auth.js +40 -0
  260. package/dist/middleware/auth.js.map +1 -0
  261. package/dist/middleware/engine-context.d.ts +9 -0
  262. package/dist/middleware/engine-context.d.ts.map +1 -0
  263. package/dist/middleware/engine-context.js +15 -0
  264. package/dist/middleware/engine-context.js.map +1 -0
  265. package/dist/middleware/idempotency.d.ts +24 -0
  266. package/dist/middleware/idempotency.d.ts.map +1 -0
  267. package/dist/middleware/idempotency.js +148 -0
  268. package/dist/middleware/idempotency.js.map +1 -0
  269. package/dist/middleware/logger.d.ts +4 -0
  270. package/dist/middleware/logger.d.ts.map +1 -0
  271. package/dist/middleware/logger.js +163 -0
  272. package/dist/middleware/logger.js.map +1 -0
  273. package/dist/middleware/planLimits.d.ts +5 -0
  274. package/dist/middleware/planLimits.d.ts.map +1 -0
  275. package/dist/middleware/planLimits.js +35 -0
  276. package/dist/middleware/planLimits.js.map +1 -0
  277. package/dist/middleware/presenceRefresh.d.ts +3 -0
  278. package/dist/middleware/presenceRefresh.d.ts.map +1 -0
  279. package/dist/middleware/presenceRefresh.js +18 -0
  280. package/dist/middleware/presenceRefresh.js.map +1 -0
  281. package/dist/middleware/rateLimit.d.ts +3 -0
  282. package/dist/middleware/rateLimit.d.ts.map +1 -0
  283. package/dist/middleware/rateLimit.js +69 -0
  284. package/dist/middleware/rateLimit.js.map +1 -0
  285. package/dist/middleware/usageTracker.d.ts +3 -0
  286. package/dist/middleware/usageTracker.d.ts.map +1 -0
  287. package/dist/middleware/usageTracker.js +10 -0
  288. package/dist/middleware/usageTracker.js.map +1 -0
  289. package/dist/ports/auth.d.ts +45 -0
  290. package/dist/ports/auth.d.ts.map +1 -0
  291. package/dist/ports/auth.js +2 -0
  292. package/dist/ports/auth.js.map +1 -0
  293. package/dist/ports/database.d.ts +20 -0
  294. package/dist/ports/database.d.ts.map +1 -0
  295. package/dist/ports/database.js +2 -0
  296. package/dist/ports/database.js.map +1 -0
  297. package/dist/ports/entitlements.d.ts +25 -0
  298. package/dist/ports/entitlements.d.ts.map +1 -0
  299. package/dist/ports/entitlements.js +2 -0
  300. package/dist/ports/entitlements.js.map +1 -0
  301. package/dist/ports/event-queue.d.ts +19 -0
  302. package/dist/ports/event-queue.d.ts.map +1 -0
  303. package/dist/ports/event-queue.js +2 -0
  304. package/dist/ports/event-queue.js.map +1 -0
  305. package/dist/ports/files.d.ts +28 -0
  306. package/dist/ports/files.d.ts.map +1 -0
  307. package/dist/ports/files.js +2 -0
  308. package/dist/ports/files.js.map +1 -0
  309. package/dist/ports/index.d.ts +84 -0
  310. package/dist/ports/index.d.ts.map +1 -0
  311. package/dist/ports/index.js +2 -0
  312. package/dist/ports/index.js.map +1 -0
  313. package/dist/ports/kv.d.ts +25 -0
  314. package/dist/ports/kv.d.ts.map +1 -0
  315. package/dist/ports/kv.js +2 -0
  316. package/dist/ports/kv.js.map +1 -0
  317. package/dist/ports/mcp.d.ts +18 -0
  318. package/dist/ports/mcp.d.ts.map +1 -0
  319. package/dist/ports/mcp.js +2 -0
  320. package/dist/ports/mcp.js.map +1 -0
  321. package/dist/ports/presence.d.ts +18 -0
  322. package/dist/ports/presence.d.ts.map +1 -0
  323. package/dist/ports/presence.js +2 -0
  324. package/dist/ports/presence.js.map +1 -0
  325. package/dist/ports/rate-limit.d.ts +20 -0
  326. package/dist/ports/rate-limit.d.ts.map +1 -0
  327. package/dist/ports/rate-limit.js +2 -0
  328. package/dist/ports/rate-limit.js.map +1 -0
  329. package/dist/ports/realtime.d.ts +104 -0
  330. package/dist/ports/realtime.d.ts.map +1 -0
  331. package/dist/ports/realtime.js +19 -0
  332. package/dist/ports/realtime.js.map +1 -0
  333. package/dist/ports/telemetry.d.ts +20 -0
  334. package/dist/ports/telemetry.d.ts.map +1 -0
  335. package/dist/ports/telemetry.js +2 -0
  336. package/dist/ports/telemetry.js.map +1 -0
  337. package/dist/providers/noop-telemetry.d.ts +13 -0
  338. package/dist/providers/noop-telemetry.d.ts.map +1 -0
  339. package/dist/providers/noop-telemetry.js +16 -0
  340. package/dist/providers/noop-telemetry.js.map +1 -0
  341. package/dist/providers/static-entitlements.d.ts +23 -0
  342. package/dist/providers/static-entitlements.d.ts.map +1 -0
  343. package/dist/providers/static-entitlements.js +42 -0
  344. package/dist/providers/static-entitlements.js.map +1 -0
  345. package/dist/routes/a2a.d.ts +4 -0
  346. package/dist/routes/a2a.d.ts.map +1 -0
  347. package/dist/routes/a2a.js +375 -0
  348. package/dist/routes/a2a.js.map +1 -0
  349. package/dist/routes/action.d.ts +4 -0
  350. package/dist/routes/action.d.ts.map +1 -0
  351. package/dist/routes/action.js +213 -0
  352. package/dist/routes/action.js.map +1 -0
  353. package/dist/routes/agent.d.ts +4 -0
  354. package/dist/routes/agent.d.ts.map +1 -0
  355. package/dist/routes/agent.js +431 -0
  356. package/dist/routes/agent.js.map +1 -0
  357. package/dist/routes/background.d.ts +13 -0
  358. package/dist/routes/background.d.ts.map +1 -0
  359. package/dist/routes/background.js +33 -0
  360. package/dist/routes/background.js.map +1 -0
  361. package/dist/routes/certify.d.ts +4 -0
  362. package/dist/routes/certify.d.ts.map +1 -0
  363. package/dist/routes/certify.js +119 -0
  364. package/dist/routes/certify.js.map +1 -0
  365. package/dist/routes/channel.d.ts +4 -0
  366. package/dist/routes/channel.d.ts.map +1 -0
  367. package/dist/routes/channel.js +492 -0
  368. package/dist/routes/channel.js.map +1 -0
  369. package/dist/routes/console.d.ts +4 -0
  370. package/dist/routes/console.d.ts.map +1 -0
  371. package/dist/routes/console.js +117 -0
  372. package/dist/routes/console.js.map +1 -0
  373. package/dist/routes/directory.d.ts +4 -0
  374. package/dist/routes/directory.d.ts.map +1 -0
  375. package/dist/routes/directory.js +236 -0
  376. package/dist/routes/directory.js.map +1 -0
  377. package/dist/routes/dm.d.ts +4 -0
  378. package/dist/routes/dm.d.ts.map +1 -0
  379. package/dist/routes/dm.js +157 -0
  380. package/dist/routes/dm.js.map +1 -0
  381. package/dist/routes/eventSubscription.d.ts +4 -0
  382. package/dist/routes/eventSubscription.d.ts.map +1 -0
  383. package/dist/routes/eventSubscription.js +115 -0
  384. package/dist/routes/eventSubscription.js.map +1 -0
  385. package/dist/routes/fanout.d.ts +17 -0
  386. package/dist/routes/fanout.d.ts.map +1 -0
  387. package/dist/routes/fanout.js +150 -0
  388. package/dist/routes/fanout.js.map +1 -0
  389. package/dist/routes/file.d.ts +4 -0
  390. package/dist/routes/file.d.ts.map +1 -0
  391. package/dist/routes/file.js +166 -0
  392. package/dist/routes/file.js.map +1 -0
  393. package/dist/routes/groupDm.d.ts +4 -0
  394. package/dist/routes/groupDm.d.ts.map +1 -0
  395. package/dist/routes/groupDm.js +204 -0
  396. package/dist/routes/groupDm.js.map +1 -0
  397. package/dist/routes/health.d.ts +4 -0
  398. package/dist/routes/health.d.ts.map +1 -0
  399. package/dist/routes/health.js +10 -0
  400. package/dist/routes/health.js.map +1 -0
  401. package/dist/routes/inboundWebhook.d.ts +4 -0
  402. package/dist/routes/inboundWebhook.d.ts.map +1 -0
  403. package/dist/routes/inboundWebhook.js +149 -0
  404. package/dist/routes/inboundWebhook.js.map +1 -0
  405. package/dist/routes/inbox.d.ts +4 -0
  406. package/dist/routes/inbox.d.ts.map +1 -0
  407. package/dist/routes/inbox.js +23 -0
  408. package/dist/routes/inbox.js.map +1 -0
  409. package/dist/routes/message.d.ts +4 -0
  410. package/dist/routes/message.d.ts.map +1 -0
  411. package/dist/routes/message.js +164 -0
  412. package/dist/routes/message.js.map +1 -0
  413. package/dist/routes/presence.d.ts +4 -0
  414. package/dist/routes/presence.d.ts.map +1 -0
  415. package/dist/routes/presence.js +70 -0
  416. package/dist/routes/presence.js.map +1 -0
  417. package/dist/routes/reaction.d.ts +4 -0
  418. package/dist/routes/reaction.d.ts.map +1 -0
  419. package/dist/routes/reaction.js +152 -0
  420. package/dist/routes/reaction.js.map +1 -0
  421. package/dist/routes/receipt.d.ts +4 -0
  422. package/dist/routes/receipt.d.ts.map +1 -0
  423. package/dist/routes/receipt.js +100 -0
  424. package/dist/routes/receipt.js.map +1 -0
  425. package/dist/routes/routing.d.ts +4 -0
  426. package/dist/routes/routing.d.ts.map +1 -0
  427. package/dist/routes/routing.js +186 -0
  428. package/dist/routes/routing.js.map +1 -0
  429. package/dist/routes/search.d.ts +4 -0
  430. package/dist/routes/search.d.ts.map +1 -0
  431. package/dist/routes/search.js +48 -0
  432. package/dist/routes/search.js.map +1 -0
  433. package/dist/routes/systemPrompt.d.ts +4 -0
  434. package/dist/routes/systemPrompt.d.ts.map +1 -0
  435. package/dist/routes/systemPrompt.js +66 -0
  436. package/dist/routes/systemPrompt.js.map +1 -0
  437. package/dist/routes/thread.d.ts +4 -0
  438. package/dist/routes/thread.d.ts.map +1 -0
  439. package/dist/routes/thread.js +126 -0
  440. package/dist/routes/thread.js.map +1 -0
  441. package/dist/routes/workspace.d.ts +4 -0
  442. package/dist/routes/workspace.d.ts.map +1 -0
  443. package/dist/routes/workspace.js +355 -0
  444. package/dist/routes/workspace.js.map +1 -0
  445. package/package.json +71 -0
@@ -0,0 +1,53 @@
1
+ import { randomUUID } from 'node:crypto';
2
+ import { WebStandardStreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/webStandardStreamableHttp.js';
3
+ import { createRelayMcpServer } from '@relaycast/mcp';
4
+ /**
5
+ * In-process MCP Streamable-HTTP session host, replacing McpSessionDO. Sessions
6
+ * are held in a `Map` keyed by a generated UUID; an unknown/closed session id
7
+ * returns the same 404 a hosted (evicted-DO) session would, so clients
8
+ * re-initialize identically.
9
+ */
10
+ export class InProcessMcpSessionHost {
11
+ options;
12
+ sessions = new Map();
13
+ constructor(options = {}) {
14
+ this.options = options;
15
+ }
16
+ async handle(request, sessionId) {
17
+ if (request.method === 'DELETE') {
18
+ if (sessionId) {
19
+ const session = this.sessions.get(sessionId);
20
+ if (session) {
21
+ await session.transport.close();
22
+ this.sessions.delete(sessionId);
23
+ }
24
+ }
25
+ return new Response(null, { status: 204 });
26
+ }
27
+ if (sessionId) {
28
+ const session = this.sessions.get(sessionId);
29
+ if (!session) {
30
+ return Response.json({ jsonrpc: '2.0', error: { code: -32000, message: 'Invalid or expired session' }, id: null }, { status: 404 });
31
+ }
32
+ return session.transport.handleRequest(request);
33
+ }
34
+ // New session (initialize).
35
+ const newSessionId = randomUUID();
36
+ const transport = new WebStandardStreamableHTTPServerTransport({
37
+ sessionIdGenerator: () => newSessionId,
38
+ });
39
+ const apiKey = request.headers.get('x-relay-api-key') ?? undefined;
40
+ const server = createRelayMcpServer({
41
+ apiKey,
42
+ baseUrl: this.options.baseUrl,
43
+ telemetryTransport: 'http',
44
+ });
45
+ transport.onclose = () => {
46
+ this.sessions.delete(newSessionId);
47
+ };
48
+ await server.connect(transport);
49
+ this.sessions.set(newSessionId, { transport, server });
50
+ return transport.handleRequest(request);
51
+ }
52
+ }
53
+ //# sourceMappingURL=mcp.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp.js","sourceRoot":"","sources":["../../../src/adapters/node/mcp.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,wCAAwC,EAAE,MAAM,+DAA+D,CAAC;AAEzH,OAAO,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AAatD;;;;;GAKG;AACH,MAAM,OAAO,uBAAuB;IAGL;IAFZ,QAAQ,GAAG,IAAI,GAAG,EAAmB,CAAC;IAEvD,YAA6B,UAA+B,EAAE;QAAjC,YAAO,GAAP,OAAO,CAA0B;IAAG,CAAC;IAElE,KAAK,CAAC,MAAM,CAAC,OAAgB,EAAE,SAA6B;QAC1D,IAAI,OAAO,CAAC,MAAM,KAAK,QAAQ,EAAE,CAAC;YAChC,IAAI,SAAS,EAAE,CAAC;gBACd,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;gBAC7C,IAAI,OAAO,EAAE,CAAC;oBACZ,MAAM,OAAO,CAAC,SAAS,CAAC,KAAK,EAAE,CAAC;oBAChC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;gBAClC,CAAC;YACH,CAAC;YACD,OAAO,IAAI,QAAQ,CAAC,IAAI,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC;QAC7C,CAAC;QAED,IAAI,SAAS,EAAE,CAAC;YACd,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;YAC7C,IAAI,CAAC,OAAO,EAAE,CAAC;gBACb,OAAO,QAAQ,CAAC,IAAI,CAClB,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,4BAA4B,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,EAC5F,EAAE,MAAM,EAAE,GAAG,EAAE,CAChB,CAAC;YACJ,CAAC;YACD,OAAO,OAAO,CAAC,SAAS,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;QAClD,CAAC;QAED,4BAA4B;QAC5B,MAAM,YAAY,GAAG,UAAU,EAAE,CAAC;QAClC,MAAM,SAAS,GAAG,IAAI,wCAAwC,CAAC;YAC7D,kBAAkB,EAAE,GAAG,EAAE,CAAC,YAAY;SACvC,CAAC,CAAC;QACH,MAAM,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC,IAAI,SAAS,CAAC;QACnE,MAAM,MAAM,GAAG,oBAAoB,CAAC;YAClC,MAAM;YACN,OAAO,EAAE,IAAI,CAAC,OAAO,CAAC,OAAO;YAC7B,kBAAkB,EAAE,MAAM;SAC3B,CAAC,CAAC;QAEH,SAAS,CAAC,OAAO,GAAG,GAAG,EAAE;YACvB,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC;QACrC,CAAC,CAAC;QAEF,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;QAChC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,YAAY,EAAE,EAAE,SAAS,EAAE,MAAM,EAAE,CAAC,CAAC;QAEvD,OAAO,SAAS,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;IAC1C,CAAC;CACF"}
@@ -0,0 +1,33 @@
1
+ import type { PresenceTracker } from '../../ports/presence.js';
2
+ import type { RealtimeBus } from '../../ports/realtime.js';
3
+ export interface InProcessPresenceOptions {
4
+ /** Agents not seen within this window are considered offline. */
5
+ ttlMs?: number;
6
+ /** How often the stale-sweep runs. Set 0 to disable the timer (tests call sweep() directly). */
7
+ sweepIntervalMs?: number;
8
+ }
9
+ /**
10
+ * Single-process presence tracker replacing PresenceDO. Heartbeats are kept in
11
+ * a per-workspace map; a `setInterval` sweep (mirroring the DO alarm) marks
12
+ * agents offline after the TTL and fans out `agent.offline` events through the
13
+ * realtime bus. Emits `agent.online` on the offline→online transition.
14
+ */
15
+ export declare class InProcessPresence implements PresenceTracker {
16
+ private readonly bus;
17
+ private readonly workspaces;
18
+ private readonly ttlMs;
19
+ private timer;
20
+ constructor(bus: RealtimeBus, options?: InProcessPresenceOptions);
21
+ /** Stop the sweep timer (server shutdown / test teardown). */
22
+ stop(): void;
23
+ private ws;
24
+ private onlineIds;
25
+ private buildEvent;
26
+ private broadcast;
27
+ heartbeat(workspaceId: string, agentId: string, agentName?: string): Promise<void>;
28
+ disconnect(workspaceId: string, agentId: string, agentName?: string): Promise<void>;
29
+ getOnline(workspaceId: string): Promise<string[]>;
30
+ /** Sweep stale agents across all workspaces, emitting `agent.offline`. */
31
+ sweep(): Promise<void>;
32
+ }
33
+ //# sourceMappingURL=presence.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"presence.d.ts","sourceRoot":"","sources":["../../../src/adapters/node/presence.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAC/D,OAAO,KAAK,EAAE,WAAW,EAAe,MAAM,yBAAyB,CAAC;AAUxE,MAAM,WAAW,wBAAwB;IACvC,iEAAiE;IACjE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,gGAAgG;IAChG,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED;;;;;GAKG;AACH,qBAAa,iBAAkB,YAAW,eAAe;IAK3C,OAAO,CAAC,QAAQ,CAAC,GAAG;IAJhC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAiD;IAC5E,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAS;IAC/B,OAAO,CAAC,KAAK,CAA6C;gBAE7B,GAAG,EAAE,WAAW,EAAE,OAAO,GAAE,wBAA6B;IAYrF,8DAA8D;IAC9D,IAAI,IAAI,IAAI;IAKZ,OAAO,CAAC,EAAE;IASV,OAAO,CAAC,SAAS;IASjB,OAAO,CAAC,UAAU;YAcJ,SAAS;IAOjB,SAAS,CAAC,WAAW,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAalF,UAAU,CAAC,WAAW,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAUnF,SAAS,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAIvD,0EAA0E;IACpE,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAoB7B"}
@@ -0,0 +1,113 @@
1
+ const DEFAULT_TTL_MS = 60_000;
2
+ const DEFAULT_SWEEP_MS = 60_000;
3
+ /**
4
+ * Single-process presence tracker replacing PresenceDO. Heartbeats are kept in
5
+ * a per-workspace map; a `setInterval` sweep (mirroring the DO alarm) marks
6
+ * agents offline after the TTL and fans out `agent.offline` events through the
7
+ * realtime bus. Emits `agent.online` on the offline→online transition.
8
+ */
9
+ export class InProcessPresence {
10
+ bus;
11
+ workspaces = new Map();
12
+ ttlMs;
13
+ timer;
14
+ constructor(bus, options = {}) {
15
+ this.bus = bus;
16
+ this.ttlMs = options.ttlMs ?? DEFAULT_TTL_MS;
17
+ const sweepMs = options.sweepIntervalMs ?? DEFAULT_SWEEP_MS;
18
+ if (sweepMs > 0) {
19
+ this.timer = setInterval(() => {
20
+ void this.sweep();
21
+ }, sweepMs);
22
+ // Don't keep the Node process alive solely for the presence sweep.
23
+ this.timer.unref?.();
24
+ }
25
+ }
26
+ /** Stop the sweep timer (server shutdown / test teardown). */
27
+ stop() {
28
+ if (this.timer)
29
+ clearInterval(this.timer);
30
+ this.timer = undefined;
31
+ }
32
+ ws(workspaceId) {
33
+ let m = this.workspaces.get(workspaceId);
34
+ if (!m) {
35
+ m = new Map();
36
+ this.workspaces.set(workspaceId, m);
37
+ }
38
+ return m;
39
+ }
40
+ onlineIds(workspaceId) {
41
+ const now = Date.now();
42
+ const out = [];
43
+ for (const [agentId, entry] of this.ws(workspaceId)) {
44
+ if (now - entry.ts < this.ttlMs)
45
+ out.push(agentId);
46
+ }
47
+ return out;
48
+ }
49
+ buildEvent(type, agentId, name) {
50
+ return {
51
+ type,
52
+ agent: { name },
53
+ agent_name: name,
54
+ subject_agent_id: agentId,
55
+ timestamp: new Date().toISOString(),
56
+ };
57
+ }
58
+ async broadcast(workspaceId, onlineAgentIds, event) {
59
+ await Promise.allSettled([
60
+ this.bus.deliverToAgents({ workspaceId, agentIds: onlineAgentIds, event }),
61
+ this.bus.publishToWorkspaceStream({ workspaceId, event }),
62
+ ]);
63
+ }
64
+ async heartbeat(workspaceId, agentId, agentName) {
65
+ const map = this.ws(workspaceId);
66
+ const prev = map.get(agentId);
67
+ const wasOffline = !prev || Date.now() - prev.ts >= this.ttlMs;
68
+ const name = agentName?.trim() || prev?.name || agentId;
69
+ map.set(agentId, { ts: Date.now(), name });
70
+ if (wasOffline) {
71
+ const event = this.buildEvent('agent.online', agentId, name);
72
+ await this.broadcast(workspaceId, this.onlineIds(workspaceId), event);
73
+ }
74
+ }
75
+ async disconnect(workspaceId, agentId, agentName) {
76
+ const map = this.ws(workspaceId);
77
+ const prev = map.get(agentId);
78
+ if (!prev)
79
+ return;
80
+ const name = agentName?.trim() || prev.name || agentId;
81
+ map.delete(agentId);
82
+ const event = this.buildEvent('agent.offline', agentId, name);
83
+ await this.broadcast(workspaceId, this.onlineIds(workspaceId), event);
84
+ }
85
+ async getOnline(workspaceId) {
86
+ return this.onlineIds(workspaceId);
87
+ }
88
+ /** Sweep stale agents across all workspaces, emitting `agent.offline`. */
89
+ async sweep() {
90
+ const now = Date.now();
91
+ for (const [workspaceId, map] of this.workspaces) {
92
+ const stale = [];
93
+ for (const [agentId, entry] of map) {
94
+ if (now - entry.ts >= this.ttlMs) {
95
+ stale.push({ id: agentId, name: entry.name ?? agentId });
96
+ }
97
+ }
98
+ if (stale.length === 0)
99
+ continue;
100
+ for (const s of stale)
101
+ map.delete(s.id);
102
+ const stillOnline = this.onlineIds(workspaceId);
103
+ for (const s of stale) {
104
+ await this.broadcast(workspaceId, stillOnline, this.buildEvent('agent.offline', s.id, s.name));
105
+ }
106
+ // Reclaim the workspace entry once it has no tracked agents, so the map
107
+ // doesn't grow unbounded with workspace churn.
108
+ if (map.size === 0)
109
+ this.workspaces.delete(workspaceId);
110
+ }
111
+ }
112
+ }
113
+ //# sourceMappingURL=presence.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"presence.js","sourceRoot":"","sources":["../../../src/adapters/node/presence.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ import type { RateLimiter, RateLimitResult } from '../../ports/rate-limit.js';
2
+ /**
3
+ * In-memory sliding-window rate limiter, mirroring RateLimitDO. Buckets expire
4
+ * after their window; a periodic cleanup keeps the map bounded. Single-process
5
+ * only (each Node process counts independently).
6
+ */
7
+ export declare class InProcessRateLimiter implements RateLimiter {
8
+ private readonly buckets;
9
+ private lastCleanup;
10
+ private cleanup;
11
+ check(args: {
12
+ bucketKey: string;
13
+ limit: number;
14
+ windowMs: number;
15
+ }): Promise<RateLimitResult>;
16
+ }
17
+ //# sourceMappingURL=rate-limit.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rate-limit.d.ts","sourceRoot":"","sources":["../../../src/adapters/node/rate-limit.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAE9E;;;;GAIG;AACH,qBAAa,oBAAqB,YAAW,WAAW;IACtD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA2D;IACnF,OAAO,CAAC,WAAW,CAAc;IAEjC,OAAO,CAAC,OAAO;IAQT,KAAK,CAAC,IAAI,EAAE;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,eAAe,CAAC;CAmBpG"}
@@ -0,0 +1,36 @@
1
+ /**
2
+ * In-memory sliding-window rate limiter, mirroring RateLimitDO. Buckets expire
3
+ * after their window; a periodic cleanup keeps the map bounded. Single-process
4
+ * only (each Node process counts independently).
5
+ */
6
+ export class InProcessRateLimiter {
7
+ buckets = new Map();
8
+ lastCleanup = Date.now();
9
+ cleanup(now) {
10
+ if (now - this.lastCleanup < 30_000)
11
+ return;
12
+ this.lastCleanup = now;
13
+ for (const [key, bucket] of this.buckets) {
14
+ if (bucket.expiresAt <= now)
15
+ this.buckets.delete(key);
16
+ }
17
+ }
18
+ async check(args) {
19
+ const { bucketKey, limit, windowMs } = args;
20
+ const now = Date.now();
21
+ this.cleanup(now);
22
+ let bucket = this.buckets.get(bucketKey);
23
+ if (!bucket || bucket.expiresAt <= now) {
24
+ bucket = { count: 0, expiresAt: now + windowMs };
25
+ this.buckets.set(bucketKey, bucket);
26
+ }
27
+ bucket.count += 1;
28
+ const count = bucket.count;
29
+ return {
30
+ count,
31
+ remaining: Math.max(0, limit - count),
32
+ allowed: count <= limit,
33
+ };
34
+ }
35
+ }
36
+ //# sourceMappingURL=rate-limit.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rate-limit.js","sourceRoot":"","sources":["../../../src/adapters/node/rate-limit.ts"],"names":[],"mappings":"AAEA;;;;GAIG;AACH,MAAM,OAAO,oBAAoB;IACd,OAAO,GAAG,IAAI,GAAG,EAAgD,CAAC;IAC3E,WAAW,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAEzB,OAAO,CAAC,GAAW;QACzB,IAAI,GAAG,GAAG,IAAI,CAAC,WAAW,GAAG,MAAM;YAAE,OAAO;QAC5C,IAAI,CAAC,WAAW,GAAG,GAAG,CAAC;QACvB,KAAK,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YACzC,IAAI,MAAM,CAAC,SAAS,IAAI,GAAG;gBAAE,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QACxD,CAAC;IACH,CAAC;IAED,KAAK,CAAC,KAAK,CAAC,IAA4D;QACtE,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,QAAQ,EAAE,GAAG,IAAI,CAAC;QAC5C,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACvB,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QAElB,IAAI,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QACzC,IAAI,CAAC,MAAM,IAAI,MAAM,CAAC,SAAS,IAAI,GAAG,EAAE,CAAC;YACvC,MAAM,GAAG,EAAE,KAAK,EAAE,CAAC,EAAE,SAAS,EAAE,GAAG,GAAG,QAAQ,EAAE,CAAC;YACjD,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;QACtC,CAAC;QAED,MAAM,CAAC,KAAK,IAAI,CAAC,CAAC;QAClB,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC;QAC3B,OAAO;YACL,KAAK;YACL,SAAS,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,GAAG,KAAK,CAAC;YACrC,OAAO,EAAE,KAAK,IAAI,KAAK;SACxB,CAAC;IACJ,CAAC;CACF"}
@@ -0,0 +1,72 @@
1
+ import type { RealtimeBus, ConnectionRegistry, EngineEvent, BroadcastToChannelArgs, UpgradeArgs } from '../../ports/realtime.js';
2
+ import type { EngineDb } from '../../ports/database.js';
3
+ import type { PresenceTracker } from '../../ports/presence.js';
4
+ /**
5
+ * Transport-agnostic socket the adapter writes to. The Node entrypoint adapts a
6
+ * `ws` WebSocket to this shape; tests can pass a plain stub. Keeping the adapter
7
+ * off any concrete socket type makes the realtime semantics unit-testable
8
+ * without a network.
9
+ */
10
+ export interface EngineSocket {
11
+ send(data: string): void;
12
+ close(code?: number, reason?: string): void;
13
+ }
14
+ /** Returned by attach helpers; the transport drives these on socket events. */
15
+ export interface SocketHandle {
16
+ handleMessage(raw: string): Promise<void>;
17
+ handleClose(): Promise<void>;
18
+ }
19
+ /**
20
+ * Single-process, in-memory implementation of both {@link RealtimeBus} and
21
+ * {@link ConnectionRegistry}, replacing the Cloudflare ChannelDO + AgentDO +
22
+ * WorkspaceStreamDO. Per-agent `agent_seq` and per-channel `channel_seq` are
23
+ * plain counters; JS single-threadedness makes the read-increment-write atomic
24
+ * with no await between, so concurrent broadcasts stay strictly monotonic.
25
+ *
26
+ * Limitation: a single Node process only. Sequence counters, socket sets, and
27
+ * the resync ring live in memory — horizontally scaling would need a shared
28
+ * backend (Redis pub/sub for fanout, a shared counter store) plugged in behind
29
+ * these same two interfaces.
30
+ */
31
+ export declare class InProcessRealtime implements RealtimeBus, ConnectionRegistry {
32
+ private readonly db;
33
+ private readonly agents;
34
+ private readonly channels;
35
+ private readonly workspaceSockets;
36
+ private presence;
37
+ constructor(db: EngineDb);
38
+ /** Wire the presence tracker after construction (ping → heartbeat, close → offline). */
39
+ setPresence(presence: PresenceTracker): void;
40
+ private agentKey;
41
+ private getAgent;
42
+ private getChannel;
43
+ /** Load channel members (and muted ids) from the DB when the cache is cold. */
44
+ private loadMembersFromDb;
45
+ broadcastToChannel(args: BroadcastToChannelArgs): Promise<{
46
+ channelSeq: number;
47
+ }>;
48
+ deliverToAgents(args: {
49
+ workspaceId: string;
50
+ agentIds: string[];
51
+ event: EngineEvent;
52
+ }): Promise<void>;
53
+ publishToWorkspaceStream(args: {
54
+ workspaceId: string;
55
+ event: EngineEvent;
56
+ }): Promise<void>;
57
+ setChannelMembers(workspaceId: string, channelId: string, members: string[]): Promise<void>;
58
+ setChannelMuted(workspaceId: string, channelId: string, muted: string[]): Promise<void>;
59
+ upgrade(_args: UpgradeArgs): Promise<Response>;
60
+ pushToAgent(workspaceId: string, agentId: string, event: EngineEvent): Promise<{
61
+ agentSeq: number;
62
+ }>;
63
+ disconnectAgent(workspaceId: string, agentId: string): Promise<void>;
64
+ /** Register a live agent socket; returns handlers the transport drives. */
65
+ attachAgentSocket(workspaceId: string, agentId: string, socket: EngineSocket): SocketHandle;
66
+ /** Register a live workspace-stream socket; returns handlers the transport drives. */
67
+ attachWorkspaceSocket(workspaceId: string, socket: EngineSocket): SocketHandle;
68
+ private onAgentMessage;
69
+ private onWorkspaceMessage;
70
+ private replayBuffered;
71
+ }
72
+ //# sourceMappingURL=realtime.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"realtime.d.ts","sourceRoot":"","sources":["../../../src/adapters/node/realtime.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,WAAW,EACX,kBAAkB,EAClB,WAAW,EACX,sBAAsB,EACtB,WAAW,EACZ,MAAM,yBAAyB,CAAC;AAEjC,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AACxD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAO/D;;;;;GAKG;AACH,MAAM,WAAW,YAAY;IAC3B,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC7C;AAED,+EAA+E;AAC/E,MAAM,WAAW,YAAY;IAC3B,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1C,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CAC9B;AAcD;;;;;;;;;;;GAWG;AACH,qBAAa,iBAAkB,YAAW,WAAW,EAAE,kBAAkB;IAM3D,OAAO,CAAC,QAAQ,CAAC,EAAE;IAL/B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAgC;IACvD,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAmC;IAC5D,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAwC;IACzE,OAAO,CAAC,QAAQ,CAA8B;gBAEjB,EAAE,EAAE,QAAQ;IAEzC,wFAAwF;IACxF,WAAW,CAAC,QAAQ,EAAE,eAAe,GAAG,IAAI;IAI5C,OAAO,CAAC,QAAQ;IAIhB,OAAO,CAAC,QAAQ;IAUhB,OAAO,CAAC,UAAU;IAYlB,+EAA+E;YACjE,iBAAiB;IAUzB,kBAAkB,CAAC,IAAI,EAAE,sBAAsB,GAAG,OAAO,CAAC;QAAE,UAAU,EAAE,MAAM,CAAA;KAAE,CAAC;IA4CjF,eAAe,CAAC,IAAI,EAAE;QAAE,WAAW,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,EAAE,CAAC;QAAC,KAAK,EAAE,WAAW,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAMrG,wBAAwB,CAAC,IAAI,EAAE;QAAE,WAAW,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,WAAW,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAa1F,iBAAiB,CAAC,WAAW,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAI3F,eAAe,CAAC,WAAW,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAMvF,OAAO,CAAC,KAAK,EAAE,WAAW,GAAG,OAAO,CAAC,QAAQ,CAAC;IAO9C,WAAW,CACf,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,WAAW,GACjB,OAAO,CAAC;QAAE,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC;IAmB1B,eAAe,CAAC,WAAW,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAe1E,2EAA2E;IAC3E,iBAAiB,CAAC,WAAW,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,YAAY,GAAG,YAAY;IAc3F,sFAAsF;IACtF,qBAAqB,CAAC,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,YAAY,GAAG,YAAY;YAehE,cAAc;YAmDd,kBAAkB;IAShC,OAAO,CAAC,cAAc;CA4BvB"}
@@ -0,0 +1,274 @@
1
+ import { sql } from 'drizzle-orm';
2
+ import { replayMissedEvents } from '../../engine/resyncQuery.js';
3
+ /** Matches the Cloudflare AgentDO resync ring size. */
4
+ const RESYNC_BUFFER_SIZE = 500;
5
+ const MESSAGE_EVENT_TYPES = new Set(['message.created', 'message', 'thread.reply']);
6
+ /**
7
+ * Single-process, in-memory implementation of both {@link RealtimeBus} and
8
+ * {@link ConnectionRegistry}, replacing the Cloudflare ChannelDO + AgentDO +
9
+ * WorkspaceStreamDO. Per-agent `agent_seq` and per-channel `channel_seq` are
10
+ * plain counters; JS single-threadedness makes the read-increment-write atomic
11
+ * with no await between, so concurrent broadcasts stay strictly monotonic.
12
+ *
13
+ * Limitation: a single Node process only. Sequence counters, socket sets, and
14
+ * the resync ring live in memory — horizontally scaling would need a shared
15
+ * backend (Redis pub/sub for fanout, a shared counter store) plugged in behind
16
+ * these same two interfaces.
17
+ */
18
+ export class InProcessRealtime {
19
+ db;
20
+ agents = new Map();
21
+ channels = new Map();
22
+ workspaceSockets = new Map();
23
+ presence;
24
+ constructor(db) {
25
+ this.db = db;
26
+ }
27
+ /** Wire the presence tracker after construction (ping → heartbeat, close → offline). */
28
+ setPresence(presence) {
29
+ this.presence = presence;
30
+ }
31
+ agentKey(workspaceId, agentId) {
32
+ return `${workspaceId}:${agentId}`;
33
+ }
34
+ getAgent(workspaceId, agentId) {
35
+ const key = this.agentKey(workspaceId, agentId);
36
+ let conn = this.agents.get(key);
37
+ if (!conn) {
38
+ conn = { seq: 0, sockets: new Set(), ring: [] };
39
+ this.agents.set(key, conn);
40
+ }
41
+ return conn;
42
+ }
43
+ getChannel(workspaceId, channelId) {
44
+ const key = `${workspaceId}:${channelId}`;
45
+ let ch = this.channels.get(key);
46
+ if (!ch) {
47
+ ch = { seq: 0, members: [], muted: [] };
48
+ this.channels.set(key, ch);
49
+ }
50
+ return ch;
51
+ }
52
+ /* ---------------------------- RealtimeBus ---------------------------- */
53
+ /** Load channel members (and muted ids) from the DB when the cache is cold. */
54
+ async loadMembersFromDb(channelId) {
55
+ const rows = await this.db.all(sql `
56
+ SELECT agent_id, is_muted FROM channel_members WHERE channel_id = ${channelId}
57
+ `);
58
+ return {
59
+ members: rows.map((r) => r.agent_id),
60
+ muted: rows.filter((r) => r.is_muted === 1).map((r) => r.agent_id),
61
+ };
62
+ }
63
+ async broadcastToChannel(args) {
64
+ const { workspaceId, channelId, event, members, mutedMembers } = args;
65
+ const ch = this.getChannel(workspaceId, channelId);
66
+ // Cold-start member-cache init, mirroring ChannelDO.
67
+ if (members && members.length > 0 && ch.members.length === 0) {
68
+ ch.members = members;
69
+ }
70
+ if (mutedMembers) {
71
+ ch.muted = mutedMembers;
72
+ }
73
+ // Fall back to the DB when the cache is empty (e.g. after a process restart),
74
+ // matching ChannelDO's D1 reload so realtime delivery survives restarts.
75
+ if (ch.members.length === 0) {
76
+ try {
77
+ const loaded = await this.loadMembersFromDb(channelId);
78
+ if (loaded.members.length > 0) {
79
+ ch.members = loaded.members;
80
+ if (ch.muted.length === 0)
81
+ ch.muted = loaded.muted;
82
+ }
83
+ }
84
+ catch {
85
+ // best-effort; proceed with whatever is cached
86
+ }
87
+ }
88
+ const seq = ++ch.seq;
89
+ const payload = { ...event, channel_seq: seq };
90
+ let deliverTo = ch.members;
91
+ if (ch.muted.length > 0) {
92
+ const type = typeof payload.type === 'string' ? payload.type : '';
93
+ if (MESSAGE_EVENT_TYPES.has(type)) {
94
+ const muted = new Set(ch.muted);
95
+ deliverTo = ch.members.filter((id) => !muted.has(id));
96
+ }
97
+ }
98
+ for (const agentId of deliverTo) {
99
+ await this.pushToAgent(workspaceId, agentId, payload);
100
+ }
101
+ return { channelSeq: seq };
102
+ }
103
+ async deliverToAgents(args) {
104
+ for (const agentId of args.agentIds) {
105
+ await this.pushToAgent(args.workspaceId, agentId, args.event);
106
+ }
107
+ }
108
+ async publishToWorkspaceStream(args) {
109
+ const set = this.workspaceSockets.get(args.workspaceId);
110
+ if (!set || set.size === 0)
111
+ return;
112
+ const data = JSON.stringify(args.event);
113
+ for (const socket of set) {
114
+ try {
115
+ socket.send(data);
116
+ }
117
+ catch {
118
+ // Socket may have closed between enumeration and send.
119
+ }
120
+ }
121
+ }
122
+ async setChannelMembers(workspaceId, channelId, members) {
123
+ this.getChannel(workspaceId, channelId).members = members;
124
+ }
125
+ async setChannelMuted(workspaceId, channelId, muted) {
126
+ this.getChannel(workspaceId, channelId).muted = muted;
127
+ }
128
+ /* ------------------------- ConnectionRegistry ------------------------ */
129
+ async upgrade(_args) {
130
+ // In Node the WebSocket upgrade is handled at the HTTP-server level by the
131
+ // entrypoint (see entrypoints/node.ts), which calls attachAgentSocket /
132
+ // attachWorkspaceSocket directly. This method exists for interface parity.
133
+ return new Response('WebSocket upgrade is handled by the Node server', { status: 426 });
134
+ }
135
+ async pushToAgent(workspaceId, agentId, event) {
136
+ const conn = this.getAgent(workspaceId, agentId);
137
+ const seq = ++conn.seq;
138
+ const payload = { ...event, agent_seq: seq };
139
+ conn.ring.push({ seq, payload });
140
+ if (conn.ring.length > RESYNC_BUFFER_SIZE)
141
+ conn.ring.shift();
142
+ const data = JSON.stringify(payload);
143
+ for (const socket of conn.sockets) {
144
+ try {
145
+ socket.send(data);
146
+ }
147
+ catch {
148
+ // Socket may have closed; the transport's close handler will clean up.
149
+ }
150
+ }
151
+ return { agentSeq: seq };
152
+ }
153
+ async disconnectAgent(workspaceId, agentId) {
154
+ const conn = this.agents.get(this.agentKey(workspaceId, agentId));
155
+ if (!conn)
156
+ return;
157
+ for (const socket of [...conn.sockets]) {
158
+ try {
159
+ socket.close(1000, 'force-disconnect');
160
+ }
161
+ catch {
162
+ // already closed
163
+ }
164
+ conn.sockets.delete(socket);
165
+ }
166
+ }
167
+ /* --------------------- Node transport attach helpers ----------------- */
168
+ /** Register a live agent socket; returns handlers the transport drives. */
169
+ attachAgentSocket(workspaceId, agentId, socket) {
170
+ const conn = this.getAgent(workspaceId, agentId);
171
+ conn.sockets.add(socket);
172
+ return {
173
+ handleMessage: (raw) => this.onAgentMessage(workspaceId, agentId, socket, raw),
174
+ handleClose: async () => {
175
+ conn.sockets.delete(socket);
176
+ if (conn.sockets.size === 0 && this.presence) {
177
+ await this.presence.disconnect(workspaceId, agentId).catch(() => { });
178
+ }
179
+ },
180
+ };
181
+ }
182
+ /** Register a live workspace-stream socket; returns handlers the transport drives. */
183
+ attachWorkspaceSocket(workspaceId, socket) {
184
+ let set = this.workspaceSockets.get(workspaceId);
185
+ if (!set) {
186
+ set = new Set();
187
+ this.workspaceSockets.set(workspaceId, set);
188
+ }
189
+ set.add(socket);
190
+ return {
191
+ handleMessage: async (raw) => this.onWorkspaceMessage(socket, raw),
192
+ handleClose: async () => {
193
+ set.delete(socket);
194
+ },
195
+ };
196
+ }
197
+ async onAgentMessage(workspaceId, agentId, socket, raw) {
198
+ let parsed;
199
+ try {
200
+ parsed = JSON.parse(raw);
201
+ }
202
+ catch {
203
+ return;
204
+ }
205
+ if (parsed.type === 'ping') {
206
+ socket.send(JSON.stringify({ type: 'pong' }));
207
+ if (this.presence) {
208
+ await this.presence.heartbeat(workspaceId, agentId).catch(() => { });
209
+ }
210
+ return;
211
+ }
212
+ if (parsed.type === 'resync' && typeof parsed.last_seen_seq === 'number') {
213
+ const { replayed, gapDetected } = this.replayBuffered(workspaceId, agentId, socket, parsed.last_seen_seq);
214
+ let dbReplayed = 0;
215
+ if (gapDetected && parsed.since) {
216
+ try {
217
+ const events = await replayMissedEvents(this.db, agentId, workspaceId, parsed.since);
218
+ for (const e of events) {
219
+ try {
220
+ socket.send(JSON.stringify(e));
221
+ dbReplayed++;
222
+ }
223
+ catch {
224
+ break;
225
+ }
226
+ }
227
+ }
228
+ catch {
229
+ // DB replay best-effort; the ack still reports buffered replay.
230
+ }
231
+ }
232
+ socket.send(JSON.stringify({
233
+ type: 'resync_ack',
234
+ last_seen_seq: parsed.last_seen_seq,
235
+ current_seq: this.getAgent(workspaceId, agentId).seq,
236
+ replayed: replayed + dbReplayed,
237
+ gap_detected: gapDetected,
238
+ }));
239
+ }
240
+ }
241
+ async onWorkspaceMessage(socket, raw) {
242
+ try {
243
+ const parsed = JSON.parse(raw);
244
+ if (parsed.type === 'ping')
245
+ socket.send(JSON.stringify({ type: 'pong' }));
246
+ }
247
+ catch {
248
+ // ignore malformed frames
249
+ }
250
+ }
251
+ replayBuffered(workspaceId, agentId, socket, lastSeen) {
252
+ const conn = this.getAgent(workspaceId, agentId);
253
+ const currentSeq = conn.seq;
254
+ if (lastSeen >= currentSeq) {
255
+ return { replayed: 0, gapDetected: false };
256
+ }
257
+ const oldestBuffered = conn.ring.length > 0 ? conn.ring[0].seq : currentSeq + 1;
258
+ const gapDetected = lastSeen < oldestBuffered - 1;
259
+ let replayed = 0;
260
+ for (const item of conn.ring) {
261
+ if (item.seq > lastSeen) {
262
+ try {
263
+ socket.send(JSON.stringify(item.payload));
264
+ replayed++;
265
+ }
266
+ catch {
267
+ break;
268
+ }
269
+ }
270
+ }
271
+ return { replayed, gapDetected };
272
+ }
273
+ }
274
+ //# sourceMappingURL=realtime.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"realtime.js","sourceRoot":"","sources":["../../../src/adapters/node/realtime.ts"],"names":[],"mappings":"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"}