@m6d/cortex-server 1.8.0 → 2.0.0

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 (352) 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/runtime.ts +208 -0
  10. package/contracts/wire.ts +143 -0
  11. package/dist/contracts/graph/embed.d.ts +22 -0
  12. package/dist/{src/lib → contracts}/graph/helpers.d.ts +16 -14
  13. package/dist/{src/lib → contracts}/graph/neo4j.d.ts +5 -5
  14. package/dist/contracts/graph/schema.d.ts +62 -0
  15. package/dist/{src/lib → contracts}/graph/types.d.ts +1 -1
  16. package/dist/contracts/graph.d.ts +14 -0
  17. package/dist/contracts/runtime.d.ts +278 -0
  18. package/dist/contracts/wire.d.ts +120 -0
  19. package/dist/src/lib/adapters/database/index.d.ts +61 -0
  20. package/dist/src/lib/adapters/database/message-content.d.ts +30 -0
  21. package/dist/src/lib/adapters/database/mssql/attachments.d.ts +100 -0
  22. package/dist/src/lib/adapters/database/mssql/client.d.ts +8 -0
  23. package/dist/src/lib/adapters/database/mssql/index.d.ts +194 -0
  24. package/dist/src/lib/adapters/database/mssql/llm-requests.d.ts +17 -0
  25. package/dist/src/lib/adapters/database/mssql/messages.d.ts +37 -0
  26. package/dist/src/lib/adapters/database/mssql/threads.d.ts +50 -0
  27. package/dist/src/lib/adapters/database/postgres/attachments.d.ts +113 -0
  28. package/dist/src/lib/adapters/database/postgres/client.d.ts +8 -0
  29. package/dist/src/lib/adapters/database/postgres/index.d.ts +207 -0
  30. package/dist/src/lib/adapters/database/postgres/llm-requests.d.ts +17 -0
  31. package/dist/src/lib/adapters/database/postgres/messages.d.ts +37 -0
  32. package/dist/src/lib/adapters/database/postgres/threads.d.ts +50 -0
  33. package/{src/lib/adapters/storage.ts → dist/src/lib/adapters/storage/index.d.ts} +1 -1
  34. package/dist/src/lib/adapters/{minio.d.ts → storage/minio.d.ts} +1 -1
  35. package/dist/src/lib/ai/active-runs.d.ts +63 -0
  36. package/dist/src/lib/ai/attachments.d.ts +30 -0
  37. package/dist/src/lib/ai/backend-url.d.ts +16 -0
  38. package/dist/src/lib/ai/cc-runtime.d.ts +61 -0
  39. package/dist/src/lib/ai/commit-gate.d.ts +21 -0
  40. package/dist/src/lib/ai/context/builder.d.ts +6 -7
  41. package/dist/src/lib/ai/context/compression-middleware.d.ts +15 -0
  42. package/dist/src/lib/ai/context/compressor.d.ts +2 -13
  43. package/dist/src/lib/ai/context/intra-turn-compressor.d.ts +9 -9
  44. package/dist/src/lib/ai/context/optimize-thread-context.d.ts +9 -0
  45. package/dist/src/lib/ai/context/summarizer.d.ts +3 -3
  46. package/dist/src/lib/ai/context/token-estimator.d.ts +5 -8
  47. package/dist/src/lib/ai/fetch.d.ts +1 -1
  48. package/dist/src/lib/ai/finish-turn.d.ts +23 -0
  49. package/dist/src/lib/ai/helpers.d.ts +37 -4
  50. package/dist/src/lib/ai/index.d.ts +6 -3
  51. package/dist/src/lib/ai/inspector.d.ts +41 -0
  52. package/dist/src/lib/ai/interceptors/request-interceptor.d.ts +6 -5
  53. package/dist/src/lib/ai/prompt.d.ts +5 -4
  54. package/dist/src/lib/ai/redis-runs.d.ts +41 -0
  55. package/dist/src/lib/ai/redis-stream-log.d.ts +39 -0
  56. package/dist/src/lib/ai/tools/execute-code.tool.d.ts +18 -4
  57. package/dist/src/lib/ai/tools/query-graph.tool.d.ts +13 -5
  58. package/dist/src/lib/ai/tools/read-attachment.tool.d.ts +21 -0
  59. package/dist/src/lib/ai/tools/search-common.d.ts +17 -0
  60. package/dist/src/lib/ai/tools/search-knowledge.tool.d.ts +15 -0
  61. package/dist/src/lib/ai/tools/search-services.tool.d.ts +12 -0
  62. package/dist/src/lib/ai/tools/search-tools.tool.d.ts +12 -0
  63. package/dist/src/lib/ai/turn-tools.d.ts +39 -0
  64. package/dist/src/lib/ai/vision/rasterize-pdf.d.ts +26 -0
  65. package/dist/src/lib/ai/vision/rasterize-pdf.worker.d.ts +1 -0
  66. package/dist/src/lib/ai/vision/vision-reader.d.ts +45 -0
  67. package/dist/src/lib/cc/client.d.ts +183 -0
  68. package/dist/src/lib/cc/config-cache.d.ts +20 -0
  69. package/dist/src/lib/cc/format.d.ts +23 -0
  70. package/dist/src/lib/cc/registry.d.ts +34 -0
  71. package/dist/src/lib/cc/types.d.ts +27 -0
  72. package/dist/src/lib/config.d.ts +81 -64
  73. package/dist/src/lib/db/drizzle.config.mssql.d.ts +2 -0
  74. package/dist/src/lib/db/drizzle.config.pg.d.ts +2 -0
  75. package/dist/src/lib/db/migrate.d.ts +7 -1
  76. package/dist/src/lib/db/{schema.d.ts → schema.mssql.d.ts} +138 -29
  77. package/dist/src/lib/db/schema.pg.d.ts +546 -0
  78. package/dist/src/lib/factory.d.ts +2 -12
  79. package/dist/src/lib/graph/index.d.ts +10 -11
  80. package/dist/src/lib/graph/resolver.d.ts +2 -3
  81. package/dist/src/lib/index.d.ts +3 -3
  82. package/dist/src/lib/redis.d.ts +19 -0
  83. package/dist/src/lib/routes/chat.d.ts +1 -1
  84. package/dist/src/lib/routes/files.d.ts +1 -1
  85. package/dist/src/lib/routes/owned-thread.d.ts +17 -0
  86. package/dist/src/lib/routes/threads.d.ts +1 -1
  87. package/dist/src/lib/routes/ws.d.ts +1 -1
  88. package/dist/src/lib/types.d.ts +20 -37
  89. package/dist/src/lib/ws/connections.d.ts +2 -1
  90. package/package.json +33 -18
  91. package/src/lib/adapters/database/index.ts +78 -0
  92. package/src/lib/adapters/database/message-content.ts +39 -0
  93. package/src/lib/adapters/database/mssql/attachments.ts +90 -0
  94. package/src/lib/adapters/database/mssql/client.ts +11 -0
  95. package/src/lib/adapters/database/mssql/index.ts +23 -0
  96. package/src/lib/adapters/database/mssql/llm-requests.ts +43 -0
  97. package/src/lib/adapters/database/mssql/messages.ts +92 -0
  98. package/src/lib/adapters/database/mssql/threads.ts +83 -0
  99. package/src/lib/adapters/database/postgres/attachments.ts +88 -0
  100. package/src/lib/adapters/database/postgres/client.ts +11 -0
  101. package/src/lib/adapters/database/postgres/index.ts +23 -0
  102. package/src/lib/adapters/database/postgres/llm-requests.ts +45 -0
  103. package/src/lib/adapters/database/postgres/messages.ts +92 -0
  104. package/src/lib/adapters/database/postgres/threads.ts +84 -0
  105. package/{dist/src/lib/adapters/storage.d.ts → src/lib/adapters/storage/index.ts} +1 -1
  106. package/src/lib/adapters/{minio.ts → storage/minio.ts} +5 -5
  107. package/src/lib/ai/active-runs.ts +157 -0
  108. package/src/lib/ai/attachments.ts +144 -0
  109. package/src/lib/ai/backend-url.ts +27 -0
  110. package/src/lib/ai/cc-runtime.ts +63 -0
  111. package/src/lib/ai/commit-gate.ts +116 -0
  112. package/src/lib/ai/context/builder.ts +12 -14
  113. package/src/lib/ai/context/compression-middleware.ts +44 -0
  114. package/src/lib/ai/context/compressor.ts +67 -59
  115. package/src/lib/ai/context/intra-turn-compressor.ts +121 -204
  116. package/src/lib/ai/context/optimize-thread-context.ts +50 -0
  117. package/src/lib/ai/context/summarizer.ts +28 -30
  118. package/src/lib/ai/context/token-estimator.ts +35 -30
  119. package/src/lib/ai/fetch.ts +10 -5
  120. package/src/lib/ai/finish-turn.ts +75 -0
  121. package/src/lib/ai/helpers.ts +83 -15
  122. package/src/lib/ai/index.ts +359 -329
  123. package/src/lib/ai/inspector.ts +112 -0
  124. package/src/lib/ai/interceptors/request-interceptor.ts +70 -42
  125. package/src/lib/ai/prompt.ts +126 -125
  126. package/src/lib/ai/redis-runs.ts +167 -0
  127. package/src/lib/ai/redis-stream-log.ts +219 -0
  128. package/src/lib/ai/tools/execute-code.tool.ts +178 -67
  129. package/src/lib/ai/tools/query-graph.tool.ts +7 -8
  130. package/src/lib/ai/tools/read-attachment.tool.ts +59 -0
  131. package/src/lib/ai/tools/search-common.ts +15 -0
  132. package/src/lib/ai/tools/search-knowledge.tool.ts +33 -0
  133. package/src/lib/ai/tools/search-services.tool.ts +31 -0
  134. package/src/lib/ai/tools/search-tools.tool.ts +29 -0
  135. package/src/lib/ai/turn-tools.ts +154 -0
  136. package/src/lib/ai/vision/rasterize-pdf.ts +69 -0
  137. package/src/lib/ai/vision/rasterize-pdf.worker.ts +81 -0
  138. package/src/lib/ai/vision/vision-reader.ts +130 -0
  139. package/src/lib/auth/middleware.ts +5 -3
  140. package/src/lib/cc/client.ts +273 -0
  141. package/src/lib/cc/config-cache.ts +32 -0
  142. package/src/lib/cc/format.ts +96 -0
  143. package/src/lib/cc/registry.ts +62 -0
  144. package/src/lib/cc/types.ts +44 -0
  145. package/src/lib/config.ts +102 -71
  146. package/src/lib/db/drizzle.config.mssql.ts +9 -0
  147. package/src/lib/db/drizzle.config.pg.ts +9 -0
  148. package/src/lib/db/migrate.ts +45 -10
  149. package/src/lib/db/migrations/mssql/20260729092726_talented_wilson_fisk/migration.sql +20 -0
  150. package/src/lib/db/migrations/mssql/20260729092726_talented_wilson_fisk/snapshot.json +497 -0
  151. package/src/lib/db/migrations/mssql/20260801003652_perpetual_blue_shield/migration.sql +1 -0
  152. package/src/lib/db/migrations/mssql/20260801003652_perpetual_blue_shield/snapshot.json +516 -0
  153. package/src/lib/db/migrations/mssql/20260812174642_user_id_text/migration.sql +2 -0
  154. package/src/lib/db/migrations/mssql/20260812174642_user_id_text/snapshot.json +516 -0
  155. package/src/lib/db/migrations/pg/20260801084117_thick_ben_grimm/migration.sql +53 -0
  156. package/src/lib/db/migrations/pg/20260801084117_thick_ben_grimm/snapshot.json +584 -0
  157. package/src/lib/db/migrations/pg/20260812174622_user_id_text/migration.sql +2 -0
  158. package/src/lib/db/migrations/pg/20260812174622_user_id_text/snapshot.json +584 -0
  159. package/src/lib/db/{schema.ts → schema.mssql.ts} +29 -18
  160. package/src/lib/db/schema.pg.ts +95 -0
  161. package/src/lib/factory.ts +44 -89
  162. package/src/lib/graph/index.ts +12 -40
  163. package/src/lib/graph/resolver.ts +146 -116
  164. package/src/lib/index.ts +11 -4
  165. package/src/lib/redis.ts +44 -0
  166. package/src/lib/routes/chat.ts +91 -62
  167. package/src/lib/routes/files.ts +105 -83
  168. package/src/lib/routes/owned-thread.ts +17 -0
  169. package/src/lib/routes/threads.ts +14 -30
  170. package/src/lib/routes/ws.ts +9 -3
  171. package/src/lib/types.ts +37 -36
  172. package/src/lib/ws/connections.ts +9 -1
  173. package/tsconfig.json +48 -0
  174. package/dist/src/lib/adapters/database.d.ts +0 -45
  175. package/dist/src/lib/adapters/mssql.d.ts +0 -3
  176. package/dist/src/lib/ai/active-streams.d.ts +0 -14
  177. package/dist/src/lib/ai/context/index.d.ts +0 -16
  178. package/dist/src/lib/ai/tools/capture-files.tool.d.ts +0 -6
  179. package/dist/src/lib/cli/extract-endpoints.d.ts +0 -6
  180. package/dist/src/lib/graph/expand-domains.d.ts +0 -2
  181. package/dist/src/lib/graph/generate-cypher.d.ts +0 -22
  182. package/dist/src/lib/graph/seed.d.ts +0 -19
  183. package/dist/src/lib/graph/validate.d.ts +0 -2
  184. package/dist/src/lib/routes/index.d.ts +0 -4
  185. package/dist/src/lib/ws/events.d.ts +0 -39
  186. package/dist/src/lib/ws/index.d.ts +0 -3
  187. package/dist/src/lib/ws/notify.d.ts +0 -2
  188. package/src/lib/adapters/database.ts +0 -48
  189. package/src/lib/adapters/mssql.ts +0 -231
  190. package/src/lib/ai/active-streams.ts +0 -123
  191. package/src/lib/ai/context/index.ts +0 -80
  192. package/src/lib/ai/tools/capture-files.tool.ts +0 -20
  193. package/src/lib/cli/extract-endpoints.ts +0 -550
  194. package/src/lib/graph/expand-domains.ts +0 -276
  195. package/src/lib/graph/generate-cypher.ts +0 -192
  196. package/src/lib/graph/seed.ts +0 -162
  197. package/src/lib/graph/validate.ts +0 -78
  198. package/src/lib/routes/index.ts +0 -4
  199. package/src/lib/ws/events.ts +0 -39
  200. package/src/lib/ws/index.ts +0 -11
  201. package/src/lib/ws/notify.ts +0 -9
  202. package/src/sample/db/client.ts +0 -9
  203. package/src/sample/db/migrations/20260411023125_rich_purple_man/migration.sql +0 -5
  204. package/src/sample/db/migrations/20260411023125_rich_purple_man/snapshot.json +0 -50
  205. package/src/sample/db/schema.ts +0 -10
  206. package/src/sample/domains/account/concepts/session.concept.ts +0 -17
  207. package/src/sample/domains/account/endpoints/listCurrentSessions.endpoint.ts +0 -31
  208. package/src/sample/domains/account/endpoints/revokeAllOtherSessions.endpoint.ts +0 -22
  209. package/src/sample/domains/account/endpoints/revokeCurrentSession.endpoint.ts +0 -33
  210. package/src/sample/domains/account/index.ts +0 -18
  211. package/src/sample/domains/appraisals/concepts/appraisalCycle.concept.ts +0 -15
  212. package/src/sample/domains/appraisals/concepts/appraisalRecord.concept.ts +0 -20
  213. package/src/sample/domains/appraisals/concepts/appraisalRecordCompetency.concept.ts +0 -10
  214. package/src/sample/domains/appraisals/concepts/appraisalRecordFunctionalRequirement.concept.ts +0 -10
  215. package/src/sample/domains/appraisals/concepts/appraisalRecordGoal.concept.ts +0 -17
  216. package/src/sample/domains/appraisals/endpoints/getAppraisalRecordById.endpoint.ts +0 -321
  217. package/src/sample/domains/appraisals/endpoints/getAppraisalRecordCompetencies.endpoint.ts +0 -120
  218. package/src/sample/domains/appraisals/endpoints/getAppraisalRecordFunctionalRequirements.endpoint.ts +0 -126
  219. package/src/sample/domains/appraisals/endpoints/getAppraisalRecordGoals.endpoint.ts +0 -104
  220. package/src/sample/domains/appraisals/endpoints/getAppraisalRecordScore.endpoint.ts +0 -58
  221. package/src/sample/domains/appraisals/endpoints/listAppraisalCyclesSimple.endpoint.ts +0 -52
  222. package/src/sample/domains/appraisals/endpoints/listAppraisalRecords.endpoint.ts +0 -245
  223. package/src/sample/domains/appraisals/endpoints/listAppraisalTemplatesSimple.endpoint.ts +0 -52
  224. package/src/sample/domains/appraisals/index.ts +0 -40
  225. package/src/sample/domains/appraisals/rules/appraisalRecordScoping.rule.ts +0 -7
  226. package/src/sample/domains/attendance/concepts/attendancePermission.concept.ts +0 -17
  227. package/src/sample/domains/attendance/concepts/attendanceTransaction.concept.ts +0 -17
  228. package/src/sample/domains/attendance/concepts/publicHoliday.concept.ts +0 -10
  229. package/src/sample/domains/attendance/concepts/punch.concept.ts +0 -19
  230. package/src/sample/domains/attendance/endpoints/getAttendanceTransactionById.endpoint.ts +0 -444
  231. package/src/sample/domains/attendance/endpoints/getCurrentAttendanceProfile.endpoint.ts +0 -886
  232. package/src/sample/domains/attendance/endpoints/getCurrentAttendanceStatistics.endpoint.ts +0 -49
  233. package/src/sample/domains/attendance/endpoints/listAttendancePermissions.endpoint.ts +0 -176
  234. package/src/sample/domains/attendance/endpoints/listAttendanceTransactionStates.endpoint.ts +0 -26
  235. package/src/sample/domains/attendance/endpoints/listAttendanceTransactions.endpoint.ts +0 -373
  236. package/src/sample/domains/attendance/endpoints/listPublicHolidaysSimple.endpoint.ts +0 -52
  237. package/src/sample/domains/attendance/endpoints/listPunchTypes.endpoint.ts +0 -25
  238. package/src/sample/domains/attendance/endpoints/listPunches.endpoint.ts +0 -178
  239. package/src/sample/domains/attendance/index.ts +0 -41
  240. package/src/sample/domains/attendance/services/attendancePermissions.service.ts +0 -15
  241. package/src/sample/domains/employees/concepts/employee.concept.ts +0 -20
  242. package/src/sample/domains/employees/concepts/employeeBankAccount.concept.ts +0 -19
  243. package/src/sample/domains/employees/concepts/employeeChild.concept.ts +0 -19
  244. package/src/sample/domains/employees/concepts/employeeDocument.concept.ts +0 -21
  245. package/src/sample/domains/employees/concepts/employeeEvent.concept.ts +0 -21
  246. package/src/sample/domains/employees/concepts/employeeExperience.concept.ts +0 -18
  247. package/src/sample/domains/employees/concepts/employeeJobLevelChange.concept.ts +0 -21
  248. package/src/sample/domains/employees/concepts/employeeMedal.concept.ts +0 -20
  249. package/src/sample/domains/employees/concepts/employeeQualification.concept.ts +0 -20
  250. package/src/sample/domains/employees/concepts/employeeSpouse.concept.ts +0 -21
  251. package/src/sample/domains/employees/concepts/employeeViolation.concept.ts +0 -19
  252. package/src/sample/domains/employees/endpoints/getCurrentEmployee.endpoint.ts +0 -1651
  253. package/src/sample/domains/employees/endpoints/getCurrentIdentity.endpoint.ts +0 -197
  254. package/src/sample/domains/employees/endpoints/getCurrentManagers.endpoint.ts +0 -142
  255. package/src/sample/domains/employees/endpoints/getEmployeeById.endpoint.ts +0 -1659
  256. package/src/sample/domains/employees/endpoints/getEmployeeStatistics.endpoint.ts +0 -43
  257. package/src/sample/domains/employees/endpoints/listBankAccounts.endpoint.ts +0 -223
  258. package/src/sample/domains/employees/endpoints/listChildren.endpoint.ts +0 -211
  259. package/src/sample/domains/employees/endpoints/listDocuments.endpoint.ts +0 -222
  260. package/src/sample/domains/employees/endpoints/listEmployeesSimple.endpoint.ts +0 -156
  261. package/src/sample/domains/employees/endpoints/listEvents.endpoint.ts +0 -120
  262. package/src/sample/domains/employees/endpoints/listExperiences.endpoint.ts +0 -188
  263. package/src/sample/domains/employees/endpoints/listJobLevelChanges.endpoint.ts +0 -240
  264. package/src/sample/domains/employees/endpoints/listMedals.endpoint.ts +0 -266
  265. package/src/sample/domains/employees/endpoints/listQualifications.endpoint.ts +0 -265
  266. package/src/sample/domains/employees/endpoints/listSpouses.endpoint.ts +0 -278
  267. package/src/sample/domains/employees/endpoints/listViolations.endpoint.ts +0 -245
  268. package/src/sample/domains/employees/index.ts +0 -75
  269. package/src/sample/domains/employees/services/employees.service.ts +0 -181
  270. package/src/sample/domains/index.ts +0 -10
  271. package/src/sample/domains/leaves/concepts/leave.concept.ts +0 -21
  272. package/src/sample/domains/leaves/concepts/leaveBalance.concept.ts +0 -17
  273. package/src/sample/domains/leaves/concepts/leaveBalanceTransaction.concept.ts +0 -16
  274. package/src/sample/domains/leaves/concepts/leaveType.concept.ts +0 -13
  275. package/src/sample/domains/leaves/concepts/leaveTypes.concept.ts +0 -205
  276. package/src/sample/domains/leaves/endpoints/getBalance.endpoint.ts +0 -53
  277. package/src/sample/domains/leaves/endpoints/getLeaveById.endpoint.ts +0 -53
  278. package/src/sample/domains/leaves/endpoints/listBalanceTransactions.endpoint.ts +0 -196
  279. package/src/sample/domains/leaves/endpoints/listBalanceTypes.endpoint.ts +0 -26
  280. package/src/sample/domains/leaves/endpoints/listBalances.endpoint.ts +0 -201
  281. package/src/sample/domains/leaves/endpoints/listLeaveTypes.endpoint.ts +0 -28
  282. package/src/sample/domains/leaves/endpoints/listLeaves.endpoint.ts +0 -234
  283. package/src/sample/domains/leaves/index.ts +0 -38
  284. package/src/sample/domains/leaves/services/leaveRequests.service.ts +0 -232
  285. package/src/sample/domains/notifications/concepts/notification.concept.ts +0 -19
  286. package/src/sample/domains/notifications/endpoints/countMyNotifications.endpoint.ts +0 -21
  287. package/src/sample/domains/notifications/endpoints/getMyNotification.endpoint.ts +0 -57
  288. package/src/sample/domains/notifications/endpoints/listMyNotifications.endpoint.ts +0 -59
  289. package/src/sample/domains/notifications/endpoints/markMyNotificationAsRead.endpoint.ts +0 -32
  290. package/src/sample/domains/notifications/index.ts +0 -20
  291. package/src/sample/domains/payroll/concepts/payslip.concept.ts +0 -18
  292. package/src/sample/domains/payroll/concepts/salaryCertificate.concept.ts +0 -17
  293. package/src/sample/domains/payroll/concepts/salaryCertificateRequestingEntity.concept.ts +0 -8
  294. package/src/sample/domains/payroll/endpoints/getPayslipById.endpoint.ts +0 -238
  295. package/src/sample/domains/payroll/endpoints/listPayslips.endpoint.ts +0 -216
  296. package/src/sample/domains/payroll/endpoints/listSalaryCertificateLanguages.endpoint.ts +0 -25
  297. package/src/sample/domains/payroll/endpoints/listSalaryCertificateRequestingEntities.endpoint.ts +0 -62
  298. package/src/sample/domains/payroll/endpoints/listSalaryCertificateTypes.endpoint.ts +0 -24
  299. package/src/sample/domains/payroll/endpoints/listSalaryCertificates.endpoint.ts +0 -122
  300. package/src/sample/domains/payroll/endpoints/previewSalaryCertificate.endpoint.ts +0 -45
  301. package/src/sample/domains/payroll/index.ts +0 -32
  302. package/src/sample/domains/payroll/rules/payrollEmployeeContext.rule.ts +0 -7
  303. package/src/sample/domains/payroll/services/salaryCertificates.service.ts +0 -15
  304. package/src/sample/domains/servicing/concepts/service.concept.ts +0 -6
  305. package/src/sample/domains/servicing/concepts/serviceRequest.concept.ts +0 -12
  306. package/src/sample/domains/servicing/concepts/serviceRequestApproval.concept.ts +0 -9
  307. package/src/sample/domains/servicing/endpoints/cancelServiceRequest.endpoint.ts +0 -21
  308. package/src/sample/domains/servicing/endpoints/createServiceRequest.endpoint.ts +0 -511
  309. package/src/sample/domains/servicing/endpoints/getServiceRequest.endpoint.ts +0 -352
  310. package/src/sample/domains/servicing/endpoints/getServiceRequestFormItems.endpoint.ts +0 -219
  311. package/src/sample/domains/servicing/endpoints/getServiceRequestTransactionFormItems.endpoint.ts +0 -216
  312. package/src/sample/domains/servicing/endpoints/getServiceStates.endpoint.ts +0 -47
  313. package/src/sample/domains/servicing/endpoints/invokeServiceRequestAction.endpoint.ts +0 -139
  314. package/src/sample/domains/servicing/endpoints/listServiceRequests.endpoint.ts +0 -292
  315. package/src/sample/domains/servicing/endpoints/listServices.endpoint.ts +0 -108
  316. package/src/sample/domains/servicing/endpoints/updateServiceRequest.endpoint.ts +0 -355
  317. package/src/sample/domains/servicing/index.ts +0 -44
  318. package/src/sample/domains/servicing/rules/checkValidActions.rule.ts +0 -7
  319. package/src/sample/domains/servicing/rules/createServiceRequest.rule.ts +0 -7
  320. package/src/sample/domains/servicing/rules/filterServiceRequestsByState.rule.ts +0 -7
  321. package/src/sample/domains/servicing/rules/passingOptionFields.rule.ts +0 -7
  322. package/src/sample/domains/shared/rules/pagination.rule.ts +0 -7
  323. package/src/sample/domains/suggestions/concepts/suggestion.concept.ts +0 -19
  324. package/src/sample/domains/suggestions/concepts/suggestionCategory.concept.ts +0 -7
  325. package/src/sample/domains/suggestions/concepts/suggestionImpactLevel.concept.ts +0 -7
  326. package/src/sample/domains/suggestions/endpoints/createSuggestion.endpoint.ts +0 -705
  327. package/src/sample/domains/suggestions/endpoints/deleteSuggestion.endpoint.ts +0 -32
  328. package/src/sample/domains/suggestions/endpoints/getSuggestionById.endpoint.ts +0 -635
  329. package/src/sample/domains/suggestions/endpoints/listSuggestionCategories.endpoint.ts +0 -62
  330. package/src/sample/domains/suggestions/endpoints/listSuggestionImpactLevels.endpoint.ts +0 -62
  331. package/src/sample/domains/suggestions/endpoints/listSuggestionStates.endpoint.ts +0 -24
  332. package/src/sample/domains/suggestions/endpoints/listSuggestions.endpoint.ts +0 -132
  333. package/src/sample/domains/suggestions/endpoints/updateSuggestion.endpoint.ts +0 -690
  334. package/src/sample/domains/suggestions/endpoints/updateSuggestionState.endpoint.ts +0 -39
  335. package/src/sample/domains/suggestions/index.ts +0 -34
  336. package/src/sample/domains/suggestions/rules/suggestionScope.rule.ts +0 -7
  337. package/src/sample/domains/surveys/concepts/survey.concept.ts +0 -10
  338. package/src/sample/domains/surveys/concepts/surveyResponse.concept.ts +0 -14
  339. package/src/sample/domains/surveys/endpoints/getSurveyResponseById.endpoint.ts +0 -131
  340. package/src/sample/domains/surveys/endpoints/getTargetedSurvey.endpoint.ts +0 -129
  341. package/src/sample/domains/surveys/endpoints/listTargetedSurveys.endpoint.ts +0 -160
  342. package/src/sample/domains/surveys/endpoints/respondToSurvey.endpoint.ts +0 -144
  343. package/src/sample/domains/surveys/index.ts +0 -21
  344. package/src/sample/drizzle.config.ts +0 -11
  345. package/src/sample/index.bak.ts +0 -341
  346. package/src/sample/index.ts +0 -318
  347. package/src/sample/official-statements/defaults.ts +0 -57
  348. package/src/sample/official-statements/routes.ts +0 -137
  349. package/src/sample/official-statements/service.ts +0 -148
  350. package/src/sample/official-statements/types.ts +0 -23
  351. /package/src/lib/db/migrations/{20260326231647_nice_speedball → mssql/20260326231647_nice_speedball}/migration.sql +0 -0
  352. /package/src/lib/db/migrations/{20260326231647_nice_speedball → mssql/20260326231647_nice_speedball}/snapshot.json +0 -0
@@ -0,0 +1,167 @@
1
+ import type { RedisConnections } from "@/redis";
2
+ import type { ActiveRun, RunCoordinator } from "./active-runs";
3
+ import { JOIN_FIRST_CHUNK_TIMEOUT_MS } from "./active-runs";
4
+ import { offsetBelongsToRun, redisStreamLog } from "./redis-stream-log";
5
+
6
+ /**
7
+ * The claim is the producer's liveness signal: a heartbeat refreshes its short
8
+ * TTL while the run is live, so a claim that expired means the producer died —
9
+ * that is how joiners on an orphaned run learn to stop tailing, and how a
10
+ * crashed instance's threads free up within a minute instead of fifteen. The
11
+ * stream TTL governs how long a run's chunk log stays replayable.
12
+ */
13
+ const CLAIM_TTL_SECONDS = 60;
14
+ const CLAIM_HEARTBEAT_MS = 20_000;
15
+ const DEFAULT_STREAM_TTL_SECONDS = 24 * 60 * 60;
16
+
17
+ /**
18
+ * Cross-instance abort: the producer's AbortController lives in-process on
19
+ * whichever instance runs the turn, but a stop may land on any instance — so
20
+ * abort publishes the run id and every instance listens, aborting the run if
21
+ * it owns the controller. Single-instance works too: the publisher's own
22
+ * subscriber receives the message.
23
+ */
24
+ const ABORT_CHANNEL = "cortex:chat:abort";
25
+
26
+ /**
27
+ * The claim doubles as mutex and discovery pointer: a joiner that only knows
28
+ * the thread id finds the live run here.
29
+ */
30
+ function claimKey(threadId: string) {
31
+ return `cortex:chat:active:${threadId}`;
32
+ }
33
+
34
+ /**
35
+ * Atomically take the claim and learn who held it. Two concurrent starts on
36
+ * one thread each see the other exactly once, so the loser is always aborted —
37
+ * a GET-then-SET pair could interleave and leave both producers running.
38
+ */
39
+ const CLAIM_SWAP = `local previous = redis.call("get", KEYS[1])
40
+ redis.call("set", KEYS[1], ARGV[1], "EX", ARGV[2])
41
+ return previous`;
42
+
43
+ /** Release only if still held by this run — a superseded run finishing late
44
+ * must not evict its replacement. GET-then-DEL would race; the script cannot. */
45
+ const RELEASE_IF_HELD = `if redis.call("get", KEYS[1]) == ARGV[1] then return redis.call("del", KEYS[1]) else return 0 end`;
46
+
47
+ /** The heartbeat must never resurrect a claim that abort or supersede released. */
48
+ const REFRESH_IF_HELD = `if redis.call("get", KEYS[1]) == ARGV[1] then return redis.call("expire", KEYS[1], ARGV[2]) else return 0 end`;
49
+
50
+ type RedisRunOptions = {
51
+ streamTtlSeconds?: number;
52
+ };
53
+
54
+ export function createRedisRuns(connections: RedisConnections, options: RedisRunOptions = {}) {
55
+ const { publisher, subscriber } = connections;
56
+ const streamTtlMs = (options.streamTtlSeconds ?? DEFAULT_STREAM_TTL_SECONDS) * 1000;
57
+ const logOptions = { streamTtlMs, firstChunkDeadlineMs: JOIN_FIRST_CHUNK_TIMEOUT_MS };
58
+ const aborters = new Map<string, AbortController>();
59
+ const heartbeats = new Map<string, ReturnType<typeof setInterval>>();
60
+
61
+ subscriber.on("message", function (channel: string, runId: string) {
62
+ if (channel === ABORT_CHANNEL) aborters.get(runId)?.abort();
63
+ });
64
+
65
+ /**
66
+ * Lazy and retried, never memoized-rejected: caching one boot-time
67
+ * subscribe promise would leave every future startRun rethrowing a single
68
+ * transient outage forever. Once it resolves, ioredis re-subscribes by
69
+ * itself across reconnects.
70
+ */
71
+ let abortSubscription: Promise<unknown> | undefined;
72
+ function ensureAbortSubscription() {
73
+ abortSubscription ??= subscriber.subscribe(ABORT_CHANNEL).catch((error: unknown) => {
74
+ abortSubscription = undefined;
75
+ throw error;
76
+ });
77
+ return abortSubscription;
78
+ }
79
+
80
+ async function abortRun(threadId: string) {
81
+ const runId = await publisher.get(claimKey(threadId));
82
+ if (!runId) return false;
83
+ // The local abort is immediate; the publish reaches the other instances.
84
+ aborters.get(runId)?.abort();
85
+ await publisher.publish(ABORT_CHANNEL, runId);
86
+ await publisher.eval(RELEASE_IF_HELD, 1, claimKey(threadId), runId);
87
+ return true;
88
+ }
89
+
90
+ function startHeartbeat(threadId: string, runId: string) {
91
+ const timer = setInterval(function () {
92
+ void publisher
93
+ .eval(REFRESH_IF_HELD, 1, claimKey(threadId), runId, String(CLAIM_TTL_SECONDS))
94
+ .catch((error: unknown) =>
95
+ console.error("[cortex-server] redis claim heartbeat:", error),
96
+ );
97
+ }, CLAIM_HEARTBEAT_MS);
98
+ heartbeats.set(runId, timer);
99
+ }
100
+
101
+ function stopHeartbeat(runId: string) {
102
+ const timer = heartbeats.get(runId);
103
+ if (timer !== undefined) clearInterval(timer);
104
+ heartbeats.delete(runId);
105
+ }
106
+
107
+ return {
108
+ async startRun(threadId) {
109
+ // A producer must be able to hear aborts before it may exist, or a
110
+ // stop from another instance could slip by while we boot.
111
+ await ensureAbortSubscription();
112
+ const run: ActiveRun = {
113
+ runId: crypto.randomUUID(),
114
+ abortController: new AbortController(),
115
+ };
116
+ // Registered before the claim exists, so an abort cannot land in
117
+ // between; unregistered again if the claim never materializes.
118
+ aborters.set(run.runId, run.abortController);
119
+ try {
120
+ const superseded = (await publisher.eval(
121
+ CLAIM_SWAP,
122
+ 1,
123
+ claimKey(threadId),
124
+ run.runId,
125
+ String(CLAIM_TTL_SECONDS),
126
+ )) as string | null;
127
+ if (superseded !== null) {
128
+ aborters.get(superseded)?.abort();
129
+ await publisher.publish(ABORT_CHANNEL, superseded);
130
+ }
131
+ } catch (error) {
132
+ aborters.delete(run.runId);
133
+ throw error;
134
+ }
135
+ startHeartbeat(threadId, run.runId);
136
+ return run;
137
+ },
138
+ async getRunId(threadId) {
139
+ return (await publisher.get(claimKey(threadId))) ?? undefined;
140
+ },
141
+ async runningThreadIds(threadIds) {
142
+ if (threadIds.length === 0) return new Set<string>();
143
+ const claims = await publisher.mget(threadIds.map(claimKey));
144
+ return new Set(threadIds.filter((_, index) => claims[index] !== null));
145
+ },
146
+ abortRun,
147
+ async endRun(threadId, runId) {
148
+ stopHeartbeat(runId);
149
+ aborters.delete(runId);
150
+ await publisher.eval(RELEASE_IF_HELD, 1, claimKey(threadId), runId);
151
+ },
152
+ producerLog(runId) {
153
+ return redisStreamLog(publisher, runId, { resumeOffset: null, ...logOptions });
154
+ },
155
+ joinLog(threadId, runId, offset = "-1") {
156
+ return redisStreamLog(publisher, runId, {
157
+ resumeOffset: offset,
158
+ // The claim is the producer's pulse: while this run holds it the
159
+ // reader may park between chunks indefinitely, and once it is
160
+ // gone with the log still unclosed, the producer died.
161
+ isLive: async () => (await publisher.get(claimKey(threadId))) === runId,
162
+ ...logOptions,
163
+ });
164
+ },
165
+ offsetBelongsToRun,
166
+ } satisfies RunCoordinator;
167
+ }
@@ -0,0 +1,219 @@
1
+ import type { Redis } from "ioredis";
2
+ import type { StreamChunk, StreamDurability } from "@tanstack/ai";
3
+
4
+ /**
5
+ * A `StreamDurability` adapter over a Redis Stream, one stream per run. The
6
+ * entry id is naturally ordered, so — wrapped in a run-scoped prefix — it is
7
+ * the resumable offset. Redis holds the actual chunk log rather than acting as
8
+ * a pub/sub rendezvous, so resume survives a producer restart and works from
9
+ * any instance.
10
+ */
11
+
12
+ const OFFSET_PREFIX = "redis:v1:";
13
+
14
+ /** How long a blocked read waits before re-checking its deadline and abort signal. */
15
+ const READ_BLOCK_MS = 5_000;
16
+
17
+ function streamKey(runId: string) {
18
+ return `cortex:stream:${runId}`;
19
+ }
20
+
21
+ function runPrefix(runId: string) {
22
+ return `${OFFSET_PREFIX}${encodeURIComponent(runId)}:`;
23
+ }
24
+
25
+ /**
26
+ * Whether a client-supplied resume offset belongs to `runId`. The offset names
27
+ * the log it replays, so an offset naming another run would replay that run's
28
+ * log to whoever presents it — matching the prefix this adapter encodes is what
29
+ * binds a resume to the thread the caller owns.
30
+ */
31
+ export function offsetBelongsToRun(offset: string, runId: string) {
32
+ return offset.startsWith(runPrefix(runId));
33
+ }
34
+
35
+ function encodeOffset(runId: string, entryId: string) {
36
+ return `${runPrefix(runId)}${entryId}`;
37
+ }
38
+
39
+ function decodeOffset(offset: string, runId: string) {
40
+ const entryId = offset.slice(runPrefix(runId).length);
41
+ if (!offsetBelongsToRun(offset, runId) || !/^\d+-\d+$/.test(entryId)) {
42
+ throw new Error(`Invalid redis stream offset for run ${JSON.stringify(runId)}: ${offset}`);
43
+ }
44
+ return entryId;
45
+ }
46
+
47
+ /** An entry is either `chunk <json>` or the `end` marker `close()` writes. */
48
+ function fieldValue(fields: string[], name: string) {
49
+ for (let index = 0; index < fields.length; index += 2) {
50
+ if (fields[index] === name) return fields[index + 1];
51
+ }
52
+ return undefined;
53
+ }
54
+
55
+ /**
56
+ * Where a read starts: from the beginning, or the entry id a concrete offset
57
+ * names. The contract's "now" sentinel never reaches this adapter — cortex's
58
+ * join paths always pass "-1" or a validated concrete offset — so it falls
59
+ * through to decodeOffset's rejection instead of carrying dead code.
60
+ */
61
+ function resolveStartId(runId: string, offset: string) {
62
+ return offset === "-1" ? "0" : decodeOffset(offset, runId);
63
+ }
64
+
65
+ const READ_ABORTED = Symbol("read aborted");
66
+
67
+ /** What an idle (null) reply means: keep parking, or the run will never end. */
68
+ function idlePolicy(runId: string, options: RedisStreamLogOptions) {
69
+ const deadline = Date.now() + options.firstChunkDeadlineMs;
70
+ let producerGoneTicks = 0;
71
+ return {
72
+ sawData() {
73
+ producerGoneTicks = 0;
74
+ },
75
+ async onIdle(logHasData: boolean) {
76
+ if (options.isLive && !(await options.isLive())) {
77
+ // One more blocking read before failing: an abort releases the
78
+ // claim moments before the terminal marker lands, and that
79
+ // close must win the race.
80
+ producerGoneTicks += 1;
81
+ if (producerGoneTicks > 1) {
82
+ throw new Error(
83
+ `Redis stream run was abandoned by its producer: ${JSON.stringify(runId)}`,
84
+ );
85
+ }
86
+ return;
87
+ }
88
+ if (!logHasData && Date.now() >= deadline) {
89
+ throw new Error(
90
+ `Redis stream run produced no data within ${options.firstChunkDeadlineMs}ms: ${JSON.stringify(runId)}`,
91
+ );
92
+ }
93
+ },
94
+ };
95
+ }
96
+
97
+ async function blockingRead(reader: Redis, key: string, lastId: string, signal?: AbortSignal) {
98
+ try {
99
+ return await reader.xread("BLOCK", READ_BLOCK_MS, "STREAMS", key, lastId);
100
+ } catch (error) {
101
+ // disconnect() rejects the in-flight read; that is the abort path.
102
+ if (signal?.aborted) return READ_ABORTED;
103
+ throw error;
104
+ }
105
+ }
106
+
107
+ function parseBatch(runId: string, entries: [id: string, fields: string[]][], lastId: string) {
108
+ const items: { offset: string; chunk: StreamChunk }[] = [];
109
+ let closed = false;
110
+ for (const [entryId, fields] of entries) {
111
+ lastId = entryId;
112
+ if (fieldValue(fields, "end") !== undefined) {
113
+ closed = true;
114
+ break;
115
+ }
116
+ const chunk = fieldValue(fields, "chunk");
117
+ if (chunk !== undefined) {
118
+ items.push({
119
+ offset: encodeOffset(runId, entryId),
120
+ chunk: JSON.parse(chunk) as StreamChunk,
121
+ });
122
+ }
123
+ }
124
+ return { items, closed, lastId };
125
+ }
126
+
127
+ type RedisStreamLogOptions = {
128
+ /** `null` builds a producer (appends flow into the log); an offset builds a reader. */
129
+ resumeOffset: string | null;
130
+ /** How long the log stays replayable after its last append or `close()`. */
131
+ streamTtlMs: number;
132
+ /** How long a reader waits for the run's first entry before failing. */
133
+ firstChunkDeadlineMs: number;
134
+ /**
135
+ * Whether the run's producer is still alive. While it is, a caught-up
136
+ * reader parks indefinitely between chunks — the producer owns termination.
137
+ * Once it reports dead with the log still unclosed, the run was orphaned
138
+ * (producer crashed before `close()`), and the read fails so the joiner
139
+ * gets a terminal error instead of tailing forever.
140
+ */
141
+ isLive?: () => Promise<boolean>;
142
+ };
143
+
144
+ export function redisStreamLog(redis: Redis, runId: string, options: RedisStreamLogOptions) {
145
+ const key = streamKey(runId);
146
+
147
+ return {
148
+ resumeFrom: () => options.resumeOffset,
149
+
150
+ append: async (chunks) => {
151
+ if (chunks.length === 0) return [];
152
+ const pipeline = redis.pipeline();
153
+ for (const chunk of chunks) pipeline.xadd(key, "*", "chunk", JSON.stringify(chunk));
154
+ // Refreshed on every append so a crashed producer's log — which
155
+ // never reaches close() — still expires instead of leaking forever.
156
+ pipeline.pexpire(key, options.streamTtlMs);
157
+ const results = (await pipeline.exec()) ?? [];
158
+ return results.slice(0, chunks.length).map(function ([error, entryId]) {
159
+ if (error) throw error;
160
+ return encodeOffset(runId, entryId as string);
161
+ });
162
+ },
163
+
164
+ snapshot: async () => {
165
+ // XRANGE on a missing key returns [], satisfying the contract's
166
+ // empty-run case without the existence probe read() needs.
167
+ const entries = await redis.xrange(key, "-", "+");
168
+ return parseBatch(runId, entries, "0").items;
169
+ },
170
+
171
+ close: async () => {
172
+ // The marker is what ends a tailing read — a terminal chunk cannot,
173
+ // since the agent loop emits one per iteration. The TTL then bounds
174
+ // how long the finished log lingers for late replays.
175
+ await redis.xadd(key, "*", "end", "1");
176
+ await redis.pexpire(key, options.streamTtlMs);
177
+ },
178
+
179
+ read: async function* (offset: string, signal?: AbortSignal) {
180
+ let lastId = resolveStartId(runId, offset);
181
+ // Armed while the log is empty, matching memoryStream: once a run
182
+ // has produced anything the producer owns termination, and a
183
+ // caught-up reader may legitimately park between chunks — a slow
184
+ // tool call must not read as "no data".
185
+ let logHasData = (await redis.exists(key)) === 1;
186
+ if (offset !== "-1" && !logHasData) {
187
+ // A concrete offset names entries that existed, so a missing
188
+ // key means the log expired — fail rather than park forever.
189
+ throw new Error(`Unknown or expired redis stream run: ${JSON.stringify(runId)}`);
190
+ }
191
+
192
+ // A blocked XREAD stalls every command queued behind it, so each
193
+ // reader tails on a connection of its own for as long as it lives.
194
+ const reader = redis.duplicate();
195
+ const onAbort = () => reader.disconnect();
196
+ signal?.addEventListener("abort", onAbort, { once: true });
197
+ const idle = idlePolicy(runId, options);
198
+ try {
199
+ while (!signal?.aborted) {
200
+ const reply = await blockingRead(reader, key, lastId, signal);
201
+ if (reply === READ_ABORTED) return;
202
+ if (reply === null) {
203
+ await idle.onIdle(logHasData);
204
+ continue;
205
+ }
206
+ idle.sawData();
207
+ logHasData = true;
208
+ const batch = parseBatch(runId, reply[0]?.[1] ?? [], lastId);
209
+ lastId = batch.lastId;
210
+ for (const item of batch.items) yield item;
211
+ if (batch.closed) return;
212
+ }
213
+ } finally {
214
+ signal?.removeEventListener("abort", onAbort);
215
+ reader.disconnect();
216
+ }
217
+ },
218
+ } satisfies StreamDurability;
219
+ }