@m6d/cortex-server 1.8.0 → 2.0.1

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 (354) hide show
  1. package/README.md +8 -3
  2. package/contracts/README.md +23 -0
  3. package/contracts/graph/embed.ts +50 -0
  4. package/{src/lib → contracts}/graph/helpers.ts +4 -10
  5. package/{src/lib → contracts}/graph/neo4j.ts +14 -27
  6. package/contracts/graph/schema.ts +65 -0
  7. package/{src/lib → contracts}/graph/types.ts +2 -29
  8. package/contracts/graph.ts +36 -0
  9. package/contracts/rich-text.ts +207 -0
  10. package/contracts/runtime.ts +243 -0
  11. package/contracts/wire.ts +143 -0
  12. package/dist/contracts/graph/embed.d.ts +22 -0
  13. package/dist/{src/lib → contracts}/graph/helpers.d.ts +16 -14
  14. package/dist/{src/lib → contracts}/graph/neo4j.d.ts +5 -5
  15. package/dist/contracts/graph/schema.d.ts +62 -0
  16. package/dist/{src/lib → contracts}/graph/types.d.ts +1 -1
  17. package/dist/contracts/graph.d.ts +14 -0
  18. package/dist/contracts/rich-text.d.ts +32 -0
  19. package/dist/contracts/runtime.d.ts +310 -0
  20. package/dist/contracts/wire.d.ts +120 -0
  21. package/dist/src/lib/adapters/database/index.d.ts +61 -0
  22. package/dist/src/lib/adapters/database/message-content.d.ts +30 -0
  23. package/dist/src/lib/adapters/database/mssql/attachments.d.ts +100 -0
  24. package/dist/src/lib/adapters/database/mssql/client.d.ts +8 -0
  25. package/dist/src/lib/adapters/database/mssql/index.d.ts +194 -0
  26. package/dist/src/lib/adapters/database/mssql/llm-requests.d.ts +17 -0
  27. package/dist/src/lib/adapters/database/mssql/messages.d.ts +37 -0
  28. package/dist/src/lib/adapters/database/mssql/threads.d.ts +50 -0
  29. package/dist/src/lib/adapters/database/postgres/attachments.d.ts +113 -0
  30. package/dist/src/lib/adapters/database/postgres/client.d.ts +8 -0
  31. package/dist/src/lib/adapters/database/postgres/index.d.ts +207 -0
  32. package/dist/src/lib/adapters/database/postgres/llm-requests.d.ts +17 -0
  33. package/dist/src/lib/adapters/database/postgres/messages.d.ts +37 -0
  34. package/dist/src/lib/adapters/database/postgres/threads.d.ts +50 -0
  35. package/{src/lib/adapters/storage.ts → dist/src/lib/adapters/storage/index.d.ts} +1 -1
  36. package/dist/src/lib/adapters/{minio.d.ts → storage/minio.d.ts} +1 -1
  37. package/dist/src/lib/ai/active-runs.d.ts +63 -0
  38. package/dist/src/lib/ai/attachments.d.ts +30 -0
  39. package/dist/src/lib/ai/backend-url.d.ts +16 -0
  40. package/dist/src/lib/ai/cc-runtime.d.ts +61 -0
  41. package/dist/src/lib/ai/commit-gate.d.ts +21 -0
  42. package/dist/src/lib/ai/context/builder.d.ts +6 -7
  43. package/dist/src/lib/ai/context/compression-middleware.d.ts +15 -0
  44. package/dist/src/lib/ai/context/compressor.d.ts +2 -13
  45. package/dist/src/lib/ai/context/intra-turn-compressor.d.ts +9 -9
  46. package/dist/src/lib/ai/context/optimize-thread-context.d.ts +9 -0
  47. package/dist/src/lib/ai/context/summarizer.d.ts +3 -3
  48. package/dist/src/lib/ai/context/token-estimator.d.ts +5 -8
  49. package/dist/src/lib/ai/fetch.d.ts +1 -1
  50. package/dist/src/lib/ai/finish-turn.d.ts +23 -0
  51. package/dist/src/lib/ai/helpers.d.ts +37 -4
  52. package/dist/src/lib/ai/index.d.ts +6 -3
  53. package/dist/src/lib/ai/inspector.d.ts +41 -0
  54. package/dist/src/lib/ai/interceptors/request-interceptor.d.ts +6 -5
  55. package/dist/src/lib/ai/prompt.d.ts +5 -4
  56. package/dist/src/lib/ai/redis-runs.d.ts +41 -0
  57. package/dist/src/lib/ai/redis-stream-log.d.ts +39 -0
  58. package/dist/src/lib/ai/tools/execute-code.tool.d.ts +18 -4
  59. package/dist/src/lib/ai/tools/query-graph.tool.d.ts +13 -5
  60. package/dist/src/lib/ai/tools/read-attachment.tool.d.ts +21 -0
  61. package/dist/src/lib/ai/tools/search-common.d.ts +17 -0
  62. package/dist/src/lib/ai/tools/search-knowledge.tool.d.ts +15 -0
  63. package/dist/src/lib/ai/tools/search-services.tool.d.ts +12 -0
  64. package/dist/src/lib/ai/tools/search-tools.tool.d.ts +12 -0
  65. package/dist/src/lib/ai/turn-tools.d.ts +39 -0
  66. package/dist/src/lib/ai/vision/rasterize-pdf.d.ts +26 -0
  67. package/dist/src/lib/ai/vision/rasterize-pdf.worker.d.ts +1 -0
  68. package/dist/src/lib/ai/vision/vision-reader.d.ts +45 -0
  69. package/dist/src/lib/cc/client.d.ts +183 -0
  70. package/dist/src/lib/cc/config-cache.d.ts +20 -0
  71. package/dist/src/lib/cc/format.d.ts +23 -0
  72. package/dist/src/lib/cc/registry.d.ts +34 -0
  73. package/dist/src/lib/cc/types.d.ts +27 -0
  74. package/dist/src/lib/config.d.ts +81 -64
  75. package/dist/src/lib/db/drizzle.config.mssql.d.ts +2 -0
  76. package/dist/src/lib/db/drizzle.config.pg.d.ts +2 -0
  77. package/dist/src/lib/db/migrate.d.ts +7 -1
  78. package/dist/src/lib/db/{schema.d.ts → schema.mssql.d.ts} +138 -29
  79. package/dist/src/lib/db/schema.pg.d.ts +546 -0
  80. package/dist/src/lib/factory.d.ts +2 -12
  81. package/dist/src/lib/graph/index.d.ts +10 -11
  82. package/dist/src/lib/graph/resolver.d.ts +2 -3
  83. package/dist/src/lib/index.d.ts +3 -3
  84. package/dist/src/lib/redis.d.ts +19 -0
  85. package/dist/src/lib/routes/chat.d.ts +1 -1
  86. package/dist/src/lib/routes/files.d.ts +1 -1
  87. package/dist/src/lib/routes/owned-thread.d.ts +17 -0
  88. package/dist/src/lib/routes/threads.d.ts +1 -1
  89. package/dist/src/lib/routes/ws.d.ts +1 -1
  90. package/dist/src/lib/types.d.ts +20 -37
  91. package/dist/src/lib/ws/connections.d.ts +2 -1
  92. package/package.json +33 -18
  93. package/src/lib/adapters/database/index.ts +78 -0
  94. package/src/lib/adapters/database/message-content.ts +39 -0
  95. package/src/lib/adapters/database/mssql/attachments.ts +90 -0
  96. package/src/lib/adapters/database/mssql/client.ts +11 -0
  97. package/src/lib/adapters/database/mssql/index.ts +23 -0
  98. package/src/lib/adapters/database/mssql/llm-requests.ts +43 -0
  99. package/src/lib/adapters/database/mssql/messages.ts +92 -0
  100. package/src/lib/adapters/database/mssql/threads.ts +83 -0
  101. package/src/lib/adapters/database/postgres/attachments.ts +88 -0
  102. package/src/lib/adapters/database/postgres/client.ts +11 -0
  103. package/src/lib/adapters/database/postgres/index.ts +23 -0
  104. package/src/lib/adapters/database/postgres/llm-requests.ts +45 -0
  105. package/src/lib/adapters/database/postgres/messages.ts +92 -0
  106. package/src/lib/adapters/database/postgres/threads.ts +84 -0
  107. package/{dist/src/lib/adapters/storage.d.ts → src/lib/adapters/storage/index.ts} +1 -1
  108. package/src/lib/adapters/{minio.ts → storage/minio.ts} +5 -5
  109. package/src/lib/ai/active-runs.ts +157 -0
  110. package/src/lib/ai/attachments.ts +144 -0
  111. package/src/lib/ai/backend-url.ts +27 -0
  112. package/src/lib/ai/cc-runtime.ts +63 -0
  113. package/src/lib/ai/commit-gate.ts +116 -0
  114. package/src/lib/ai/context/builder.ts +12 -14
  115. package/src/lib/ai/context/compression-middleware.ts +44 -0
  116. package/src/lib/ai/context/compressor.ts +67 -59
  117. package/src/lib/ai/context/intra-turn-compressor.ts +121 -204
  118. package/src/lib/ai/context/optimize-thread-context.ts +50 -0
  119. package/src/lib/ai/context/summarizer.ts +28 -30
  120. package/src/lib/ai/context/token-estimator.ts +35 -30
  121. package/src/lib/ai/fetch.ts +10 -5
  122. package/src/lib/ai/finish-turn.ts +75 -0
  123. package/src/lib/ai/helpers.ts +83 -15
  124. package/src/lib/ai/index.ts +366 -329
  125. package/src/lib/ai/inspector.ts +112 -0
  126. package/src/lib/ai/interceptors/request-interceptor.ts +70 -42
  127. package/src/lib/ai/prompt.ts +126 -125
  128. package/src/lib/ai/redis-runs.ts +167 -0
  129. package/src/lib/ai/redis-stream-log.ts +219 -0
  130. package/src/lib/ai/tools/execute-code.tool.ts +178 -67
  131. package/src/lib/ai/tools/query-graph.tool.ts +7 -8
  132. package/src/lib/ai/tools/read-attachment.tool.ts +59 -0
  133. package/src/lib/ai/tools/search-common.ts +15 -0
  134. package/src/lib/ai/tools/search-knowledge.tool.ts +33 -0
  135. package/src/lib/ai/tools/search-services.tool.ts +31 -0
  136. package/src/lib/ai/tools/search-tools.tool.ts +29 -0
  137. package/src/lib/ai/turn-tools.ts +154 -0
  138. package/src/lib/ai/vision/rasterize-pdf.ts +69 -0
  139. package/src/lib/ai/vision/rasterize-pdf.worker.ts +81 -0
  140. package/src/lib/ai/vision/vision-reader.ts +130 -0
  141. package/src/lib/auth/middleware.ts +5 -3
  142. package/src/lib/cc/client.ts +273 -0
  143. package/src/lib/cc/config-cache.ts +32 -0
  144. package/src/lib/cc/format.ts +92 -0
  145. package/src/lib/cc/registry.ts +62 -0
  146. package/src/lib/cc/types.ts +44 -0
  147. package/src/lib/config.ts +102 -71
  148. package/src/lib/db/drizzle.config.mssql.ts +9 -0
  149. package/src/lib/db/drizzle.config.pg.ts +9 -0
  150. package/src/lib/db/migrate.ts +45 -10
  151. package/src/lib/db/migrations/mssql/20260729092726_talented_wilson_fisk/migration.sql +20 -0
  152. package/src/lib/db/migrations/mssql/20260729092726_talented_wilson_fisk/snapshot.json +497 -0
  153. package/src/lib/db/migrations/mssql/20260801003652_perpetual_blue_shield/migration.sql +1 -0
  154. package/src/lib/db/migrations/mssql/20260801003652_perpetual_blue_shield/snapshot.json +516 -0
  155. package/src/lib/db/migrations/mssql/20260812174642_user_id_text/migration.sql +2 -0
  156. package/src/lib/db/migrations/mssql/20260812174642_user_id_text/snapshot.json +516 -0
  157. package/src/lib/db/migrations/pg/20260801084117_thick_ben_grimm/migration.sql +53 -0
  158. package/src/lib/db/migrations/pg/20260801084117_thick_ben_grimm/snapshot.json +584 -0
  159. package/src/lib/db/migrations/pg/20260812174622_user_id_text/migration.sql +2 -0
  160. package/src/lib/db/migrations/pg/20260812174622_user_id_text/snapshot.json +584 -0
  161. package/src/lib/db/{schema.ts → schema.mssql.ts} +29 -18
  162. package/src/lib/db/schema.pg.ts +95 -0
  163. package/src/lib/factory.ts +44 -89
  164. package/src/lib/graph/index.ts +12 -40
  165. package/src/lib/graph/resolver.ts +146 -116
  166. package/src/lib/index.ts +11 -4
  167. package/src/lib/redis.ts +44 -0
  168. package/src/lib/routes/chat.ts +91 -62
  169. package/src/lib/routes/files.ts +105 -83
  170. package/src/lib/routes/owned-thread.ts +17 -0
  171. package/src/lib/routes/threads.ts +14 -30
  172. package/src/lib/routes/ws.ts +9 -3
  173. package/src/lib/types.ts +37 -36
  174. package/src/lib/ws/connections.ts +9 -1
  175. package/tsconfig.json +48 -0
  176. package/dist/src/lib/adapters/database.d.ts +0 -45
  177. package/dist/src/lib/adapters/mssql.d.ts +0 -3
  178. package/dist/src/lib/ai/active-streams.d.ts +0 -14
  179. package/dist/src/lib/ai/context/index.d.ts +0 -16
  180. package/dist/src/lib/ai/tools/capture-files.tool.d.ts +0 -6
  181. package/dist/src/lib/cli/extract-endpoints.d.ts +0 -6
  182. package/dist/src/lib/graph/expand-domains.d.ts +0 -2
  183. package/dist/src/lib/graph/generate-cypher.d.ts +0 -22
  184. package/dist/src/lib/graph/seed.d.ts +0 -19
  185. package/dist/src/lib/graph/validate.d.ts +0 -2
  186. package/dist/src/lib/routes/index.d.ts +0 -4
  187. package/dist/src/lib/ws/events.d.ts +0 -39
  188. package/dist/src/lib/ws/index.d.ts +0 -3
  189. package/dist/src/lib/ws/notify.d.ts +0 -2
  190. package/src/lib/adapters/database.ts +0 -48
  191. package/src/lib/adapters/mssql.ts +0 -231
  192. package/src/lib/ai/active-streams.ts +0 -123
  193. package/src/lib/ai/context/index.ts +0 -80
  194. package/src/lib/ai/tools/capture-files.tool.ts +0 -20
  195. package/src/lib/cli/extract-endpoints.ts +0 -550
  196. package/src/lib/graph/expand-domains.ts +0 -276
  197. package/src/lib/graph/generate-cypher.ts +0 -192
  198. package/src/lib/graph/seed.ts +0 -162
  199. package/src/lib/graph/validate.ts +0 -78
  200. package/src/lib/routes/index.ts +0 -4
  201. package/src/lib/ws/events.ts +0 -39
  202. package/src/lib/ws/index.ts +0 -11
  203. package/src/lib/ws/notify.ts +0 -9
  204. package/src/sample/db/client.ts +0 -9
  205. package/src/sample/db/migrations/20260411023125_rich_purple_man/migration.sql +0 -5
  206. package/src/sample/db/migrations/20260411023125_rich_purple_man/snapshot.json +0 -50
  207. package/src/sample/db/schema.ts +0 -10
  208. package/src/sample/domains/account/concepts/session.concept.ts +0 -17
  209. package/src/sample/domains/account/endpoints/listCurrentSessions.endpoint.ts +0 -31
  210. package/src/sample/domains/account/endpoints/revokeAllOtherSessions.endpoint.ts +0 -22
  211. package/src/sample/domains/account/endpoints/revokeCurrentSession.endpoint.ts +0 -33
  212. package/src/sample/domains/account/index.ts +0 -18
  213. package/src/sample/domains/appraisals/concepts/appraisalCycle.concept.ts +0 -15
  214. package/src/sample/domains/appraisals/concepts/appraisalRecord.concept.ts +0 -20
  215. package/src/sample/domains/appraisals/concepts/appraisalRecordCompetency.concept.ts +0 -10
  216. package/src/sample/domains/appraisals/concepts/appraisalRecordFunctionalRequirement.concept.ts +0 -10
  217. package/src/sample/domains/appraisals/concepts/appraisalRecordGoal.concept.ts +0 -17
  218. package/src/sample/domains/appraisals/endpoints/getAppraisalRecordById.endpoint.ts +0 -321
  219. package/src/sample/domains/appraisals/endpoints/getAppraisalRecordCompetencies.endpoint.ts +0 -120
  220. package/src/sample/domains/appraisals/endpoints/getAppraisalRecordFunctionalRequirements.endpoint.ts +0 -126
  221. package/src/sample/domains/appraisals/endpoints/getAppraisalRecordGoals.endpoint.ts +0 -104
  222. package/src/sample/domains/appraisals/endpoints/getAppraisalRecordScore.endpoint.ts +0 -58
  223. package/src/sample/domains/appraisals/endpoints/listAppraisalCyclesSimple.endpoint.ts +0 -52
  224. package/src/sample/domains/appraisals/endpoints/listAppraisalRecords.endpoint.ts +0 -245
  225. package/src/sample/domains/appraisals/endpoints/listAppraisalTemplatesSimple.endpoint.ts +0 -52
  226. package/src/sample/domains/appraisals/index.ts +0 -40
  227. package/src/sample/domains/appraisals/rules/appraisalRecordScoping.rule.ts +0 -7
  228. package/src/sample/domains/attendance/concepts/attendancePermission.concept.ts +0 -17
  229. package/src/sample/domains/attendance/concepts/attendanceTransaction.concept.ts +0 -17
  230. package/src/sample/domains/attendance/concepts/publicHoliday.concept.ts +0 -10
  231. package/src/sample/domains/attendance/concepts/punch.concept.ts +0 -19
  232. package/src/sample/domains/attendance/endpoints/getAttendanceTransactionById.endpoint.ts +0 -444
  233. package/src/sample/domains/attendance/endpoints/getCurrentAttendanceProfile.endpoint.ts +0 -886
  234. package/src/sample/domains/attendance/endpoints/getCurrentAttendanceStatistics.endpoint.ts +0 -49
  235. package/src/sample/domains/attendance/endpoints/listAttendancePermissions.endpoint.ts +0 -176
  236. package/src/sample/domains/attendance/endpoints/listAttendanceTransactionStates.endpoint.ts +0 -26
  237. package/src/sample/domains/attendance/endpoints/listAttendanceTransactions.endpoint.ts +0 -373
  238. package/src/sample/domains/attendance/endpoints/listPublicHolidaysSimple.endpoint.ts +0 -52
  239. package/src/sample/domains/attendance/endpoints/listPunchTypes.endpoint.ts +0 -25
  240. package/src/sample/domains/attendance/endpoints/listPunches.endpoint.ts +0 -178
  241. package/src/sample/domains/attendance/index.ts +0 -41
  242. package/src/sample/domains/attendance/services/attendancePermissions.service.ts +0 -15
  243. package/src/sample/domains/employees/concepts/employee.concept.ts +0 -20
  244. package/src/sample/domains/employees/concepts/employeeBankAccount.concept.ts +0 -19
  245. package/src/sample/domains/employees/concepts/employeeChild.concept.ts +0 -19
  246. package/src/sample/domains/employees/concepts/employeeDocument.concept.ts +0 -21
  247. package/src/sample/domains/employees/concepts/employeeEvent.concept.ts +0 -21
  248. package/src/sample/domains/employees/concepts/employeeExperience.concept.ts +0 -18
  249. package/src/sample/domains/employees/concepts/employeeJobLevelChange.concept.ts +0 -21
  250. package/src/sample/domains/employees/concepts/employeeMedal.concept.ts +0 -20
  251. package/src/sample/domains/employees/concepts/employeeQualification.concept.ts +0 -20
  252. package/src/sample/domains/employees/concepts/employeeSpouse.concept.ts +0 -21
  253. package/src/sample/domains/employees/concepts/employeeViolation.concept.ts +0 -19
  254. package/src/sample/domains/employees/endpoints/getCurrentEmployee.endpoint.ts +0 -1651
  255. package/src/sample/domains/employees/endpoints/getCurrentIdentity.endpoint.ts +0 -197
  256. package/src/sample/domains/employees/endpoints/getCurrentManagers.endpoint.ts +0 -142
  257. package/src/sample/domains/employees/endpoints/getEmployeeById.endpoint.ts +0 -1659
  258. package/src/sample/domains/employees/endpoints/getEmployeeStatistics.endpoint.ts +0 -43
  259. package/src/sample/domains/employees/endpoints/listBankAccounts.endpoint.ts +0 -223
  260. package/src/sample/domains/employees/endpoints/listChildren.endpoint.ts +0 -211
  261. package/src/sample/domains/employees/endpoints/listDocuments.endpoint.ts +0 -222
  262. package/src/sample/domains/employees/endpoints/listEmployeesSimple.endpoint.ts +0 -156
  263. package/src/sample/domains/employees/endpoints/listEvents.endpoint.ts +0 -120
  264. package/src/sample/domains/employees/endpoints/listExperiences.endpoint.ts +0 -188
  265. package/src/sample/domains/employees/endpoints/listJobLevelChanges.endpoint.ts +0 -240
  266. package/src/sample/domains/employees/endpoints/listMedals.endpoint.ts +0 -266
  267. package/src/sample/domains/employees/endpoints/listQualifications.endpoint.ts +0 -265
  268. package/src/sample/domains/employees/endpoints/listSpouses.endpoint.ts +0 -278
  269. package/src/sample/domains/employees/endpoints/listViolations.endpoint.ts +0 -245
  270. package/src/sample/domains/employees/index.ts +0 -75
  271. package/src/sample/domains/employees/services/employees.service.ts +0 -181
  272. package/src/sample/domains/index.ts +0 -10
  273. package/src/sample/domains/leaves/concepts/leave.concept.ts +0 -21
  274. package/src/sample/domains/leaves/concepts/leaveBalance.concept.ts +0 -17
  275. package/src/sample/domains/leaves/concepts/leaveBalanceTransaction.concept.ts +0 -16
  276. package/src/sample/domains/leaves/concepts/leaveType.concept.ts +0 -13
  277. package/src/sample/domains/leaves/concepts/leaveTypes.concept.ts +0 -205
  278. package/src/sample/domains/leaves/endpoints/getBalance.endpoint.ts +0 -53
  279. package/src/sample/domains/leaves/endpoints/getLeaveById.endpoint.ts +0 -53
  280. package/src/sample/domains/leaves/endpoints/listBalanceTransactions.endpoint.ts +0 -196
  281. package/src/sample/domains/leaves/endpoints/listBalanceTypes.endpoint.ts +0 -26
  282. package/src/sample/domains/leaves/endpoints/listBalances.endpoint.ts +0 -201
  283. package/src/sample/domains/leaves/endpoints/listLeaveTypes.endpoint.ts +0 -28
  284. package/src/sample/domains/leaves/endpoints/listLeaves.endpoint.ts +0 -234
  285. package/src/sample/domains/leaves/index.ts +0 -38
  286. package/src/sample/domains/leaves/services/leaveRequests.service.ts +0 -232
  287. package/src/sample/domains/notifications/concepts/notification.concept.ts +0 -19
  288. package/src/sample/domains/notifications/endpoints/countMyNotifications.endpoint.ts +0 -21
  289. package/src/sample/domains/notifications/endpoints/getMyNotification.endpoint.ts +0 -57
  290. package/src/sample/domains/notifications/endpoints/listMyNotifications.endpoint.ts +0 -59
  291. package/src/sample/domains/notifications/endpoints/markMyNotificationAsRead.endpoint.ts +0 -32
  292. package/src/sample/domains/notifications/index.ts +0 -20
  293. package/src/sample/domains/payroll/concepts/payslip.concept.ts +0 -18
  294. package/src/sample/domains/payroll/concepts/salaryCertificate.concept.ts +0 -17
  295. package/src/sample/domains/payroll/concepts/salaryCertificateRequestingEntity.concept.ts +0 -8
  296. package/src/sample/domains/payroll/endpoints/getPayslipById.endpoint.ts +0 -238
  297. package/src/sample/domains/payroll/endpoints/listPayslips.endpoint.ts +0 -216
  298. package/src/sample/domains/payroll/endpoints/listSalaryCertificateLanguages.endpoint.ts +0 -25
  299. package/src/sample/domains/payroll/endpoints/listSalaryCertificateRequestingEntities.endpoint.ts +0 -62
  300. package/src/sample/domains/payroll/endpoints/listSalaryCertificateTypes.endpoint.ts +0 -24
  301. package/src/sample/domains/payroll/endpoints/listSalaryCertificates.endpoint.ts +0 -122
  302. package/src/sample/domains/payroll/endpoints/previewSalaryCertificate.endpoint.ts +0 -45
  303. package/src/sample/domains/payroll/index.ts +0 -32
  304. package/src/sample/domains/payroll/rules/payrollEmployeeContext.rule.ts +0 -7
  305. package/src/sample/domains/payroll/services/salaryCertificates.service.ts +0 -15
  306. package/src/sample/domains/servicing/concepts/service.concept.ts +0 -6
  307. package/src/sample/domains/servicing/concepts/serviceRequest.concept.ts +0 -12
  308. package/src/sample/domains/servicing/concepts/serviceRequestApproval.concept.ts +0 -9
  309. package/src/sample/domains/servicing/endpoints/cancelServiceRequest.endpoint.ts +0 -21
  310. package/src/sample/domains/servicing/endpoints/createServiceRequest.endpoint.ts +0 -511
  311. package/src/sample/domains/servicing/endpoints/getServiceRequest.endpoint.ts +0 -352
  312. package/src/sample/domains/servicing/endpoints/getServiceRequestFormItems.endpoint.ts +0 -219
  313. package/src/sample/domains/servicing/endpoints/getServiceRequestTransactionFormItems.endpoint.ts +0 -216
  314. package/src/sample/domains/servicing/endpoints/getServiceStates.endpoint.ts +0 -47
  315. package/src/sample/domains/servicing/endpoints/invokeServiceRequestAction.endpoint.ts +0 -139
  316. package/src/sample/domains/servicing/endpoints/listServiceRequests.endpoint.ts +0 -292
  317. package/src/sample/domains/servicing/endpoints/listServices.endpoint.ts +0 -108
  318. package/src/sample/domains/servicing/endpoints/updateServiceRequest.endpoint.ts +0 -355
  319. package/src/sample/domains/servicing/index.ts +0 -44
  320. package/src/sample/domains/servicing/rules/checkValidActions.rule.ts +0 -7
  321. package/src/sample/domains/servicing/rules/createServiceRequest.rule.ts +0 -7
  322. package/src/sample/domains/servicing/rules/filterServiceRequestsByState.rule.ts +0 -7
  323. package/src/sample/domains/servicing/rules/passingOptionFields.rule.ts +0 -7
  324. package/src/sample/domains/shared/rules/pagination.rule.ts +0 -7
  325. package/src/sample/domains/suggestions/concepts/suggestion.concept.ts +0 -19
  326. package/src/sample/domains/suggestions/concepts/suggestionCategory.concept.ts +0 -7
  327. package/src/sample/domains/suggestions/concepts/suggestionImpactLevel.concept.ts +0 -7
  328. package/src/sample/domains/suggestions/endpoints/createSuggestion.endpoint.ts +0 -705
  329. package/src/sample/domains/suggestions/endpoints/deleteSuggestion.endpoint.ts +0 -32
  330. package/src/sample/domains/suggestions/endpoints/getSuggestionById.endpoint.ts +0 -635
  331. package/src/sample/domains/suggestions/endpoints/listSuggestionCategories.endpoint.ts +0 -62
  332. package/src/sample/domains/suggestions/endpoints/listSuggestionImpactLevels.endpoint.ts +0 -62
  333. package/src/sample/domains/suggestions/endpoints/listSuggestionStates.endpoint.ts +0 -24
  334. package/src/sample/domains/suggestions/endpoints/listSuggestions.endpoint.ts +0 -132
  335. package/src/sample/domains/suggestions/endpoints/updateSuggestion.endpoint.ts +0 -690
  336. package/src/sample/domains/suggestions/endpoints/updateSuggestionState.endpoint.ts +0 -39
  337. package/src/sample/domains/suggestions/index.ts +0 -34
  338. package/src/sample/domains/suggestions/rules/suggestionScope.rule.ts +0 -7
  339. package/src/sample/domains/surveys/concepts/survey.concept.ts +0 -10
  340. package/src/sample/domains/surveys/concepts/surveyResponse.concept.ts +0 -14
  341. package/src/sample/domains/surveys/endpoints/getSurveyResponseById.endpoint.ts +0 -131
  342. package/src/sample/domains/surveys/endpoints/getTargetedSurvey.endpoint.ts +0 -129
  343. package/src/sample/domains/surveys/endpoints/listTargetedSurveys.endpoint.ts +0 -160
  344. package/src/sample/domains/surveys/endpoints/respondToSurvey.endpoint.ts +0 -144
  345. package/src/sample/domains/surveys/index.ts +0 -21
  346. package/src/sample/drizzle.config.ts +0 -11
  347. package/src/sample/index.bak.ts +0 -341
  348. package/src/sample/index.ts +0 -318
  349. package/src/sample/official-statements/defaults.ts +0 -57
  350. package/src/sample/official-statements/routes.ts +0 -137
  351. package/src/sample/official-statements/service.ts +0 -148
  352. package/src/sample/official-statements/types.ts +0 -23
  353. /package/src/lib/db/migrations/{20260326231647_nice_speedball → mssql/20260326231647_nice_speedball}/migration.sql +0 -0
  354. /package/src/lib/db/migrations/{20260326231647_nice_speedball → mssql/20260326231647_nice_speedball}/snapshot.json +0 -0
@@ -0,0 +1,88 @@
1
+ // fallow-ignore-file code-duplication -- mirrors ../mssql/attachments.ts by design;
2
+ // Drizzle types query builders per dialect. See DatabaseAdapter in ../index.ts.
3
+ import { and, asc, count, eq, isNull, or, sql } from "drizzle-orm";
4
+ import { attachments, threads } from "@/db/schema.pg";
5
+ import type { DatabaseAdapter } from "@/adapters/database/index";
6
+ import type { PostgresDb } from "./client";
7
+
8
+ export function createAttachmentsRepository(db: PostgresDb) {
9
+ return {
10
+ async createPending(row, limit) {
11
+ return await db.transaction(async function (tx) {
12
+ await tx.execute(
13
+ sql`SELECT 1 FROM ${threads} WHERE ${threads.id} = ${row.threadId} FOR UPDATE`,
14
+ );
15
+ const pending = await tx
16
+ .select({ value: count() })
17
+ .from(attachments)
18
+ .where(
19
+ and(
20
+ eq(attachments.threadId, row.threadId),
21
+ eq(attachments.userId, row.userId),
22
+ isNull(attachments.messageId),
23
+ ),
24
+ )
25
+ .execute()
26
+ .then((rows) => rows[0]!.value);
27
+ if (pending >= limit) return undefined;
28
+
29
+ return await tx
30
+ .insert(attachments)
31
+ .values(row)
32
+ .returning()
33
+ .then((rows) => rows[0]!);
34
+ });
35
+ },
36
+
37
+ async getById(id, userId) {
38
+ return await db
39
+ .select()
40
+ .from(attachments)
41
+ .where(and(eq(attachments.id, id), eq(attachments.userId, userId)))
42
+ .limit(1)
43
+ .execute()
44
+ .then((rows) => rows[0]);
45
+ },
46
+
47
+ async listByThread(threadId, userId) {
48
+ return await db
49
+ .select()
50
+ .from(attachments)
51
+ .where(and(eq(attachments.threadId, threadId), eq(attachments.userId, userId)))
52
+ .orderBy(asc(attachments.createdAt), asc(attachments.id))
53
+ .execute();
54
+ },
55
+
56
+ async claimForMessage(threadId, userId, messageId) {
57
+ // ponytail: retries only this message's pending rows; add claim timestamps for cross-message recovery.
58
+ return await db
59
+ .update(attachments)
60
+ .set({ messageId })
61
+ .where(
62
+ and(
63
+ eq(attachments.threadId, threadId),
64
+ eq(attachments.userId, userId),
65
+ eq(attachments.status, "pending"),
66
+ or(isNull(attachments.messageId), eq(attachments.messageId, messageId)),
67
+ ),
68
+ )
69
+ .returning();
70
+ },
71
+
72
+ async setDescription(id, userId, status, description) {
73
+ await db
74
+ .update(attachments)
75
+ .set(description === undefined ? { status } : { status, description })
76
+ .where(and(eq(attachments.id, id), eq(attachments.userId, userId)))
77
+ .execute();
78
+ },
79
+
80
+ async remove(id, userId) {
81
+ return await db
82
+ .delete(attachments)
83
+ .where(and(eq(attachments.id, id), eq(attachments.userId, userId)))
84
+ .returning()
85
+ .then((rows) => rows[0]);
86
+ },
87
+ } satisfies DatabaseAdapter["attachments"];
88
+ }
@@ -0,0 +1,11 @@
1
+ import { drizzle } from "drizzle-orm/node-postgres";
2
+
3
+ /**
4
+ * Global snake_case mapping means schema columns are never spelled out twice —
5
+ * the TypeScript name is the source of truth and Drizzle derives the column.
6
+ */
7
+ export function createPostgresDb(connectionString: string) {
8
+ return drizzle(connectionString, { casing: "snake_case" });
9
+ }
10
+
11
+ export type PostgresDb = ReturnType<typeof createPostgresDb>;
@@ -0,0 +1,23 @@
1
+ import type { DatabaseAdapter } from "@/adapters/database/index";
2
+ import type { StorageAdapter } from "@/adapters/storage/index";
3
+ import { createPostgresDb } from "./client";
4
+ import { createThreadsRepository } from "./threads";
5
+ import { createMessagesRepository } from "./messages";
6
+ import { createLlmRequestsRepository } from "./llm-requests";
7
+ import { createAttachmentsRepository } from "./attachments";
8
+
9
+ /**
10
+ * The Postgres implementation of the database contract. One repository per
11
+ * table; only threads takes storage, because deleting a thread is the one
12
+ * operation that also has to reach into object storage.
13
+ */
14
+ export function createPostgresAdapter(connectionString: string, storage?: StorageAdapter) {
15
+ const db = createPostgresDb(connectionString);
16
+
17
+ return {
18
+ threads: createThreadsRepository(db, storage),
19
+ messages: createMessagesRepository(db),
20
+ llmRequests: createLlmRequestsRepository(db),
21
+ attachments: createAttachmentsRepository(db),
22
+ } satisfies DatabaseAdapter;
23
+ }
@@ -0,0 +1,45 @@
1
+ // fallow-ignore-file code-duplication -- mirrors ../mssql/llm-requests.ts by design;
2
+ // Drizzle types query builders per dialect. See DatabaseAdapter in ../index.ts.
3
+ import { asc, eq, type InferInsertModel } from "drizzle-orm";
4
+ import { llmRequests } from "@/db/schema.pg";
5
+ import type { DatabaseAdapter } from "@/adapters/database/index";
6
+ import type { PostgresDb } from "./client";
7
+
8
+ export function createLlmRequestsRepository(db: PostgresDb) {
9
+ return {
10
+ async insert(requests) {
11
+ if (!requests.length) return;
12
+
13
+ await db
14
+ .insert(llmRequests)
15
+ .values(
16
+ requests.map(
17
+ (r) =>
18
+ ({
19
+ messageId: r.messageId,
20
+ stepNumber: r.stepNumber,
21
+ prompt: r.prompt,
22
+ output: r.output,
23
+ tokenUsage: r.tokenUsage,
24
+ }) satisfies InferInsertModel<typeof llmRequests>,
25
+ ),
26
+ )
27
+ .execute();
28
+ },
29
+
30
+ /** Ordered by step so the inspector replays a turn in the order it ran. */
31
+ async listByMessageId(messageId) {
32
+ return await db
33
+ .select({
34
+ id: llmRequests.id,
35
+ prompt: llmRequests.prompt,
36
+ output: llmRequests.output,
37
+ tokenUsage: llmRequests.tokenUsage,
38
+ })
39
+ .from(llmRequests)
40
+ .where(eq(llmRequests.messageId, messageId))
41
+ .orderBy(asc(llmRequests.stepNumber))
42
+ .execute();
43
+ },
44
+ } satisfies DatabaseAdapter["llmRequests"];
45
+ }
@@ -0,0 +1,92 @@
1
+ // fallow-ignore-file code-duplication -- mirrors ../mssql/messages.ts by design;
2
+ // Drizzle types query builders per dialect. See DatabaseAdapter in ../index.ts.
3
+ import { and, desc, eq, getColumns, inArray, type InferInsertModel } from "drizzle-orm";
4
+ import { threads, messages } from "@/db/schema.pg";
5
+ import type { ChatMessage } from "@/types";
6
+ import type { DatabaseAdapter } from "@/adapters/database/index";
7
+ import {
8
+ mergeStoredContent,
9
+ textOf,
10
+ withOwnedAttachments,
11
+ } from "@/adapters/database/message-content";
12
+ import type { PostgresDb } from "./client";
13
+
14
+ const DEFAULT_MESSAGE_LIMIT = 100;
15
+
16
+ export function createMessagesRepository(db: PostgresDb) {
17
+ return {
18
+ /**
19
+ * Fetches the newest N and reverses, so a limit keeps the most recent
20
+ * messages while callers still receive them oldest-first.
21
+ */
22
+ async list(userId, threadId, opts) {
23
+ return await db
24
+ .select(getColumns(messages))
25
+ .from(messages)
26
+ .innerJoin(threads, eq(threads.id, messages.threadId))
27
+ .where(and(eq(threads.userId, userId), eq(threads.id, threadId)))
28
+ .orderBy(desc(messages.createdAt), desc(messages.ordinal))
29
+ .limit(opts?.limit ?? DEFAULT_MESSAGE_LIMIT)
30
+ .then((x) => x.reverse());
31
+ },
32
+
33
+ /**
34
+ * Ids are client-generated, so a turn mixes new messages with edits to
35
+ * ones already stored. Splitting on existence lets the new ones go in as
36
+ * a single insert; the rest are updated individually.
37
+ */
38
+ async upsert(
39
+ threadId: string,
40
+ messagesToUpsert: ChatMessage[],
41
+ options?: { replaceAttachments?: boolean },
42
+ ) {
43
+ const incomingMessages = withOwnedAttachments(
44
+ messagesToUpsert,
45
+ options?.replaceAttachments,
46
+ );
47
+ const existingMessages = await db
48
+ .select({ id: messages.id, content: messages.content })
49
+ .from(messages)
50
+ .where(
51
+ inArray(
52
+ messages.id,
53
+ incomingMessages.map((x) => x.id),
54
+ ),
55
+ )
56
+ .execute();
57
+ const existingById = new Map(
58
+ existingMessages.map((message) => [message.id, message.content]),
59
+ );
60
+
61
+ const newMessages = incomingMessages.filter((x) => !existingById.has(x.id));
62
+ if (newMessages.length) {
63
+ await db
64
+ .insert(messages)
65
+ .values(
66
+ newMessages.map(
67
+ (x, ordinal) =>
68
+ ({
69
+ id: x.id,
70
+ role: x.role,
71
+ threadId,
72
+ content: x,
73
+ text: textOf(x),
74
+ ordinal,
75
+ }) satisfies InferInsertModel<typeof messages>,
76
+ ),
77
+ )
78
+ .execute();
79
+ }
80
+
81
+ for (const message of incomingMessages.filter((x) => existingById.has(x.id))) {
82
+ const content = mergeStoredContent(existingById.get(message.id)!, message);
83
+
84
+ await db
85
+ .update(messages)
86
+ .set({ content, text: textOf(content) })
87
+ .where(eq(messages.id, message.id))
88
+ .execute();
89
+ }
90
+ },
91
+ } satisfies DatabaseAdapter["messages"];
92
+ }
@@ -0,0 +1,84 @@
1
+ // fallow-ignore-file code-duplication -- mirrors ../mssql/threads.ts by design;
2
+ // Drizzle types query builders per dialect. See DatabaseAdapter in ../index.ts.
3
+ import { and, desc, eq } from "drizzle-orm";
4
+ import { attachments, threads } from "@/db/schema.pg";
5
+ import type { Thread } from "@/types";
6
+ import type { ThreadContextMeta } from "@/ai/context/types";
7
+ import type { DatabaseAdapter } from "@/adapters/database/index";
8
+ import type { PostgresDb } from "./client";
9
+ import type { StorageAdapter } from "@/adapters/storage/index";
10
+
11
+ export function createThreadsRepository(db: PostgresDb, storage?: StorageAdapter) {
12
+ return {
13
+ async list(userId, agentId) {
14
+ return await db
15
+ .select()
16
+ .from(threads)
17
+ .where(and(eq(threads.userId, userId), eq(threads.agentId, agentId)))
18
+ .orderBy(desc(threads.updatedAt), desc(threads.createdAt));
19
+ },
20
+
21
+ async getById(userId, threadId) {
22
+ const result = await db
23
+ .select()
24
+ .from(threads)
25
+ .where(and(eq(threads.id, threadId), eq(threads.userId, userId)))
26
+ .limit(1)
27
+ .execute();
28
+ return result.length ? (result[0] as Thread) : null;
29
+ },
30
+
31
+ async create(userId, agentId) {
32
+ const result = await db.insert(threads).values({ userId, agentId }).returning();
33
+ return result[0] as Thread;
34
+ },
35
+
36
+ /** Object storage has no foreign keys, so attachment paths must be swept before row cascade. */
37
+ async delete(userId, threadId) {
38
+ const attachmentPaths = await db
39
+ .select({ storageKey: attachments.storageKey })
40
+ .from(attachments)
41
+ .where(and(eq(attachments.threadId, threadId), eq(attachments.userId, userId)))
42
+ .execute()
43
+ .then((rows) => rows.map((row) => row.storageKey));
44
+
45
+ if (storage && attachmentPaths.length) {
46
+ await storage.delete(attachmentPaths);
47
+ }
48
+
49
+ // attachments.message_id has no cascade, so those rows go first.
50
+ await db.delete(attachments).where(eq(attachments.threadId, threadId)).execute();
51
+
52
+ await db
53
+ .delete(threads)
54
+ .where(and(eq(threads.id, threadId), eq(threads.userId, userId)))
55
+ .execute();
56
+ },
57
+
58
+ async touch(threadId) {
59
+ const result = await db
60
+ .update(threads)
61
+ .set({ updatedAt: new Date() })
62
+ .where(eq(threads.id, threadId))
63
+ .returning();
64
+
65
+ return result[0] as Thread;
66
+ },
67
+
68
+ async updateTitle(threadId, title) {
69
+ await db.update(threads).set({ title }).where(eq(threads.id, threadId)).execute();
70
+ },
71
+
72
+ async updateSession(threadId, session) {
73
+ await db.update(threads).set({ session }).where(eq(threads.id, threadId)).execute();
74
+ },
75
+
76
+ async updateContextMeta(threadId, meta: ThreadContextMeta) {
77
+ await db
78
+ .update(threads)
79
+ .set({ contextMeta: meta })
80
+ .where(eq(threads.id, threadId))
81
+ .execute();
82
+ },
83
+ } satisfies DatabaseAdapter["threads"];
84
+ }
@@ -2,5 +2,5 @@ export type StorageAdapter = {
2
2
  put(path: string, data: string): Promise<boolean>;
3
3
  get(path: string): Promise<string | false>;
4
4
  delete(paths: string[]): Promise<boolean>;
5
- stream(path: string): Promise<ReadableStream>;
5
+ stream(path: string): Promise<ReadableStream<Uint8Array>>;
6
6
  };
@@ -1,6 +1,6 @@
1
1
  import * as Minio from "minio";
2
2
  import { Readable } from "node:stream";
3
- import type { StorageAdapter } from "./storage";
3
+ import type { StorageAdapter } from "./index";
4
4
 
5
5
  export type MinioConfig = {
6
6
  endPoint: string;
@@ -53,11 +53,11 @@ export function createMinioAdapter(config: MinioConfig) {
53
53
  return await new Promise<string>((resolve, reject) => {
54
54
  const chunks: Uint8Array[] = [];
55
55
 
56
- stream.on("error", () => {
57
- reject();
56
+ stream.on("error", (error: Error) => {
57
+ reject(error);
58
58
  });
59
59
 
60
- stream.on("data", (chunk) => chunks.push(chunk));
60
+ stream.on("data", (chunk: Buffer) => chunks.push(chunk));
61
61
  stream.on("end", () => {
62
62
  const buffer = Buffer.concat(chunks);
63
63
  resolve(buffer.toString("base64"));
@@ -82,7 +82,7 @@ export function createMinioAdapter(config: MinioConfig) {
82
82
 
83
83
  async stream(path: string) {
84
84
  const nodeStream = await client.getObject(bucketName, path);
85
- return Readable.toWeb(nodeStream) as unknown as ReadableStream;
85
+ return Readable.toWeb(nodeStream) as ReadableStream<Uint8Array>;
86
86
  },
87
87
  };
88
88
 
@@ -0,0 +1,157 @@
1
+ // fallow-ignore-file duplicate-export -- coordinator-facing wrapper intentionally shares redis-stream-log's helper name
2
+ import { memoryStream, type StreamDurability } from "@tanstack/ai";
3
+
4
+ /**
5
+ * The live turn on a thread. Generation runs detached from the HTTP request that
6
+ * started it, so this registry — not the request — owns the run's lifetime: it is
7
+ * how abort reaches a producer and how a reconnecting client finds the run to
8
+ * rejoin.
9
+ */
10
+ export type ActiveRun = {
11
+ runId: string;
12
+ abortController: AbortController;
13
+ };
14
+
15
+ /**
16
+ * One backend owns both halves of a live run: the thread→run claim registry and
17
+ * the durability log the run streams through. In-memory is the single-process
18
+ * default; `createCortex({ redis })` swaps in the Redis coordinator so claims,
19
+ * aborts, and logs survive a producer restart and reach every instance.
20
+ */
21
+ export type RunCoordinator = {
22
+ /** Claims the thread for a new run, aborting whatever was running on it. */
23
+ startRun: (threadId: string) => Promise<ActiveRun>;
24
+ getRunId: (threadId: string) => Promise<string | undefined>;
25
+ /** Which of `threadIds` have a live run — one round trip, for list views. */
26
+ runningThreadIds: (threadIds: string[]) => Promise<Set<string>>;
27
+ /** Aborts the thread's live run. False when there was none to abort — the
28
+ * caller must not report an abort that never happened. */
29
+ abortRun: (threadId: string) => Promise<boolean>;
30
+ /** Releases the thread, but only for the run that still holds it — a
31
+ * superseded run finishing late must not evict its replacement. */
32
+ endRun: (threadId: string, runId: string) => Promise<void>;
33
+ /** The producer's sink: `resumeFrom()` is null, so appends flow into the log. */
34
+ producerLog: (runId: string) => StreamDurability;
35
+ /** A reader on the run's log, replaying from `offset` and tailing until close.
36
+ * Takes the thread too: the thread's claim is how a reader can tell a live
37
+ * producer from a dead one. */
38
+ joinLog: (threadId: string, runId: string, offset?: string) => StreamDurability;
39
+ /**
40
+ * Whether a client-supplied resume offset belongs to `runId`. The offset is
41
+ * the adapter's own opaque token and names the log it replays — so an offset
42
+ * naming another run would replay that run's log to whoever presents it.
43
+ */
44
+ offsetBelongsToRun: (offset: string, runId: string) => boolean;
45
+ };
46
+
47
+ /**
48
+ * How long a joiner waits for a run's first chunk. The adapter arms this on any
49
+ * empty log, and it cannot tell "the producer died" from "the producer has not
50
+ * reached the model yet" — so it has to clear the worst case: a compression
51
+ * middleware's extra summarization call plus the model's time to first token.
52
+ * It is generous because it is only a backstop: a producer that fails writes its
53
+ * own terminal event into the log, and a run that ended is gone from the
54
+ * registry, so neither ever reaches this timer.
55
+ */
56
+ export const JOIN_FIRST_CHUNK_TIMEOUT_MS = 5 * 60_000;
57
+
58
+ /**
59
+ * `memoryStream` keys its log by the run id it reads off a request, so a
60
+ * synthetic request is how a detached producer names the log it writes to and
61
+ * how a joiner names the one it reads from. The URL is never fetched.
62
+ */
63
+ function logRequest(runId: string, offset?: string) {
64
+ const query = offset === undefined ? "" : `&offset=${offset}`;
65
+ return new Request(`http://cortex.invalid/run?runId=${encodeURIComponent(runId)}${query}`);
66
+ }
67
+
68
+ function createMemoryRuns() {
69
+ const runs = new Map<string, ActiveRun>();
70
+
71
+ function abort(threadId: string) {
72
+ const run = runs.get(threadId);
73
+ if (!run) return false;
74
+ runs.delete(threadId);
75
+ run.abortController.abort();
76
+ return true;
77
+ }
78
+
79
+ return {
80
+ startRun(threadId) {
81
+ abort(threadId);
82
+ const run: ActiveRun = {
83
+ runId: crypto.randomUUID(),
84
+ abortController: new AbortController(),
85
+ };
86
+ runs.set(threadId, run);
87
+ return Promise.resolve(run);
88
+ },
89
+ getRunId(threadId) {
90
+ return Promise.resolve(runs.get(threadId)?.runId);
91
+ },
92
+ runningThreadIds(threadIds) {
93
+ return Promise.resolve(new Set(threadIds.filter((threadId) => runs.has(threadId))));
94
+ },
95
+ abortRun(threadId) {
96
+ return Promise.resolve(abort(threadId));
97
+ },
98
+ endRun(threadId, runId) {
99
+ if (runs.get(threadId)?.runId === runId) runs.delete(threadId);
100
+ return Promise.resolve();
101
+ },
102
+ producerLog(runId) {
103
+ return memoryStream(logRequest(runId));
104
+ },
105
+ joinLog(_threadId, runId, offset = "-1") {
106
+ return memoryStream(logRequest(runId, offset), {
107
+ firstChunkDeadlineMs: JOIN_FIRST_CHUNK_TIMEOUT_MS,
108
+ });
109
+ },
110
+ offsetBelongsToRun(offset, runId) {
111
+ return offset.startsWith(`memory:v1:${encodeURIComponent(runId)}:`);
112
+ },
113
+ } satisfies RunCoordinator;
114
+ }
115
+
116
+ let coordinator: RunCoordinator = createMemoryRuns();
117
+
118
+ /** `createCortex` swaps the backend in once at startup; everything below delegates. */
119
+ export function configureRunCoordination(backend: RunCoordinator) {
120
+ coordinator = backend;
121
+ }
122
+
123
+ export function startRun(threadId: string) {
124
+ return coordinator.startRun(threadId);
125
+ }
126
+
127
+ export function getRunId(threadId: string) {
128
+ return coordinator.getRunId(threadId);
129
+ }
130
+
131
+ export async function isRunning(threadId: string) {
132
+ return (await coordinator.getRunId(threadId)) !== undefined;
133
+ }
134
+
135
+ export function runningThreadIds(threadIds: string[]) {
136
+ return coordinator.runningThreadIds(threadIds);
137
+ }
138
+
139
+ export function abortRun(threadId: string) {
140
+ return coordinator.abortRun(threadId);
141
+ }
142
+
143
+ export function endRun(threadId: string, runId: string) {
144
+ return coordinator.endRun(threadId, runId);
145
+ }
146
+
147
+ export function producerLog(runId: string) {
148
+ return coordinator.producerLog(runId);
149
+ }
150
+
151
+ export function joinLog(threadId: string, runId: string, offset?: string) {
152
+ return coordinator.joinLog(threadId, runId, offset);
153
+ }
154
+
155
+ export function offsetBelongsToRun(offset: string, runId: string) {
156
+ return coordinator.offsetBelongsToRun(offset, runId);
157
+ }