@resolveio/server-lib 22.3.18 → 22.3.19

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 (674) hide show
  1. package/.nodemon.json +5 -0
  2. package/.vscode/settings.json +21 -0
  3. package/AGENTS.md +189 -0
  4. package/README.md +22 -0
  5. package/build_package.sh +5 -0
  6. package/compileDTS.pl +64 -0
  7. package/docs/ai-assistant-nightly-eval.md +65 -0
  8. package/docs/ai-assistant-preflight-checklist.md +23 -0
  9. package/docs/ai-assistant-report-builder-bridge-playbook.md +115 -0
  10. package/eslint-plugin-custom/index.js +7 -0
  11. package/eslint-plugin-custom/rules/no-filter-zero-index.js +44 -0
  12. package/eslint.config.js +103 -0
  13. package/gulpfile.js +216 -0
  14. package/methodAndPublicationListGenerator.py +344 -0
  15. package/mongodbensurers.js +2 -0
  16. package/mongostop.js +3 -0
  17. package/package.json +1 -1
  18. package/scripts/cleanup-bypassed-callmethod-logs.js +616 -0
  19. package/settings.development.json +25 -0
  20. package/settings.development.redacted.json +25 -0
  21. package/src/.env +12 -0
  22. package/src/ai/assistant-core-heuristics.ts +379 -0
  23. package/src/ai/resolveio-platform-intelligence-memory-corpus.ts +185 -0
  24. package/src/ai/resolveio-platform-intelligence-memory.ts +325 -0
  25. package/{ai/resolveio-platform-intelligence-types.d.ts → src/ai/resolveio-platform-intelligence-types.ts} +20 -15
  26. package/src/ai/resolveio-platform-intelligence.ts +462 -0
  27. package/src/client-server-app.ts +12 -0
  28. package/src/collections/ai-terminal-conversation.collection.ts +91 -0
  29. package/src/collections/ai-terminal-issue-report.collection.ts +99 -0
  30. package/src/collections/ai-terminal-message.collection.ts +77 -0
  31. package/src/collections/app-setting.collection.ts +104 -0
  32. package/src/collections/app-status.collection.ts +58 -0
  33. package/src/collections/communication-metric.collection.ts +84 -0
  34. package/src/collections/counter.collection.ts +56 -0
  35. package/src/collections/cron-job-history.collection.ts +94 -0
  36. package/src/collections/cron-job.collection.ts +92 -0
  37. package/src/collections/customer-notification.collection.ts +131 -0
  38. package/src/collections/customer-portal-password.collection.ts +76 -0
  39. package/src/collections/email-history.collection.ts +127 -0
  40. package/src/collections/email-verified.collection.ts +62 -0
  41. package/src/collections/file.collection.ts +74 -0
  42. package/src/collections/flag-update.collection.ts +57 -0
  43. package/src/collections/flag.collection.ts +57 -0
  44. package/src/collections/log-method-latency.collection.ts +77 -0
  45. package/src/collections/log-subscription.collection.ts +80 -0
  46. package/src/collections/log.collection.ts +93 -0
  47. package/src/collections/logged-in-users.collection.ts +67 -0
  48. package/src/collections/monitor-cpu.collection.ts +65 -0
  49. package/src/collections/monitor-function.collection.ts +74 -0
  50. package/src/collections/monitor-memory.collection.ts +77 -0
  51. package/src/collections/monitor-mongo.collection.ts +71 -0
  52. package/src/collections/notification.collection.ts +57 -0
  53. package/src/collections/openai-usage-ledger.collection.ts +77 -0
  54. package/src/collections/report-builder-dashboard-builder.collection.ts +109 -0
  55. package/src/collections/report-builder-library.collection.ts +89 -0
  56. package/src/collections/report-builder-report.collection.ts +184 -0
  57. package/src/collections/user-group.collection.ts +89 -0
  58. package/src/collections/user-guide.collection.ts +57 -0
  59. package/src/collections/user.collection.ts +181 -0
  60. package/src/cron/cron.ts +117 -0
  61. package/src/fixtures/cron-jobs.ts +95 -0
  62. package/src/fixtures/init.ts +35 -0
  63. package/src/http/auth.ts +764 -0
  64. package/src/http/health.ts +7 -0
  65. package/src/http/home.ts +90 -0
  66. package/src/http/slow-query-publication.ts +49 -0
  67. package/src/index.ts +1 -0
  68. package/src/managers/ai-assistant-codex-manager.manager.ts +1131 -0
  69. package/src/managers/communication-metric.manager.ts +82 -0
  70. package/src/managers/cron.manager.ts +333 -0
  71. package/src/managers/customer-notification-content.manager.ts +236 -0
  72. package/src/managers/diagnostic-manager-bootstrap.ts +165 -0
  73. package/src/managers/error-auto-fix.manager.ts +2767 -0
  74. package/src/managers/local-log.manager.ts +113 -0
  75. package/src/managers/method.manager.ts +1827 -0
  76. package/src/managers/mongo.manager.ts +4575 -0
  77. package/src/managers/monitor.manager.ts +507 -0
  78. package/src/managers/openai-usage-ledger.manager.ts +116 -0
  79. package/src/managers/slow-query-verifier.manager.ts +3590 -0
  80. package/src/managers/slow-query.manager.ts +519 -0
  81. package/src/managers/subscription.manager.ts +3128 -0
  82. package/src/managers/websocket.manager.ts +746 -0
  83. package/src/managers/worker-dispatcher.manager.ts +1360 -0
  84. package/src/managers/worker-server.manager.ts +536 -0
  85. package/src/methods/accounts.ts +532 -0
  86. package/src/methods/ai-terminal.ts +22943 -0
  87. package/src/methods/app-settings.ts +114 -0
  88. package/src/methods/aws.ts +649 -0
  89. package/src/methods/collections.ts +641 -0
  90. package/src/methods/counters.ts +69 -0
  91. package/src/methods/cron-jobs.ts +2614 -0
  92. package/src/methods/customer-notifications.ts +458 -0
  93. package/src/methods/diagnostics.ts +616 -0
  94. package/src/methods/flag-updates.ts +7 -0
  95. package/src/methods/flags.ts +7 -0
  96. package/src/methods/logs.ts +657 -0
  97. package/src/methods/mongo-explorer.ts +1880 -0
  98. package/src/methods/monitor.ts +540 -0
  99. package/src/methods/pdf.ts +1236 -0
  100. package/src/methods/publications.ts +129 -0
  101. package/src/methods/report-builder.ts +3300 -0
  102. package/src/methods/support.ts +335 -0
  103. package/src/models/ai-terminal-conversation.model.ts +19 -0
  104. package/src/models/ai-terminal-issue-report.model.ts +21 -0
  105. package/src/models/ai-terminal-message.model.ts +24 -0
  106. package/src/models/app-setting.model.ts +17 -0
  107. package/{models/app-status.model.d.ts → src/models/app-status.model.ts} +3 -2
  108. package/{models/billing-logged-in-users.model.d.ts → src/models/billing-logged-in-users.model.ts} +5 -4
  109. package/src/models/collection-document.model.ts +24 -0
  110. package/src/models/communication-metric.model.ts +23 -0
  111. package/{models/counter.model.d.ts → src/models/counter.model.ts} +4 -3
  112. package/src/models/cron-job-history.model.ts +16 -0
  113. package/src/models/cron-job.model.ts +15 -0
  114. package/src/models/customer-notification.model.ts +28 -0
  115. package/src/models/customer-portal-password.model.ts +12 -0
  116. package/src/models/dialog.model.ts +25 -0
  117. package/{models/email-history.model.js → src/models/email-history.model.ts} +35 -4
  118. package/{models/email-verified.model.d.ts → src/models/email-verified.model.ts} +6 -5
  119. package/{models/file.model.d.ts → src/models/file.model.ts} +8 -7
  120. package/{models/flag-update.model.d.ts → src/models/flag-update.model.ts} +4 -3
  121. package/{models/flag.model.d.ts → src/models/flag.model.ts} +4 -3
  122. package/src/models/log-method-latency.model.ts +11 -0
  123. package/{models/log-subscription.model.d.ts → src/models/log-subscription.model.ts} +11 -9
  124. package/src/models/log.model.ts +19 -0
  125. package/{models/logged-in-users.model.d.ts → src/models/logged-in-users.model.ts} +6 -5
  126. package/{models/method-response.model.d.ts → src/models/method-response.model.ts} +7 -6
  127. package/src/models/method.model.ts +25 -0
  128. package/{models/monitor-cpu.model.d.ts → src/models/monitor-cpu.model.ts} +9 -7
  129. package/src/models/monitor-function.model.ts +16 -0
  130. package/src/models/monitor-memory.model.ts +17 -0
  131. package/src/models/monitor-mongo.model.ts +15 -0
  132. package/{models/notification.model.d.ts → src/models/notification.model.ts} +6 -4
  133. package/src/models/openai-usage-ledger.model.ts +16 -0
  134. package/src/models/pagination.model.ts +35 -0
  135. package/src/models/permission.model.ts +14 -0
  136. package/src/models/report-builder-dashboard-builder.model.ts +29 -0
  137. package/src/models/report-builder-library.model.ts +20 -0
  138. package/src/models/report-builder-report.model.ts +136 -0
  139. package/src/models/report-builder.model.ts +68 -0
  140. package/src/models/select-data-label.model.ts +9 -0
  141. package/src/models/server-message.model.ts +31 -0
  142. package/src/models/slow-query-report.model.ts +23 -0
  143. package/src/models/subscription.model.ts +73 -0
  144. package/src/models/support-ticket.model.ts +104 -0
  145. package/src/models/user-group.model.ts +24 -0
  146. package/{models/user-guide.model.d.ts → src/models/user-guide.model.ts} +5 -4
  147. package/src/models/user.model.ts +96 -0
  148. package/src/private/images/ResolveIO.png +0 -0
  149. package/src/publications/ai-terminal.ts +73 -0
  150. package/src/publications/app-settings.ts +25 -0
  151. package/src/publications/app-status.ts +13 -0
  152. package/src/publications/cron-jobs.ts +40 -0
  153. package/src/publications/customer-notifications.ts +101 -0
  154. package/src/publications/files.ts +33 -0
  155. package/src/publications/flags-update.ts +19 -0
  156. package/src/publications/flags.ts +19 -0
  157. package/src/publications/logs.ts +163 -0
  158. package/src/publications/notifications.ts +13 -0
  159. package/src/publications/report-builder-dashboard-builders.ts +39 -0
  160. package/src/publications/report-builder-libraries.ts +41 -0
  161. package/src/publications/report-builder-reports.ts +47 -0
  162. package/src/publications/super-admin.ts +13 -0
  163. package/src/publications/user-groups.ts +12 -0
  164. package/src/publications/user-guides.ts +12 -0
  165. package/src/resolveio-server-app.ts +617 -0
  166. package/src/server-app.ts +3354 -0
  167. package/src/services/codex-client.ts +1223 -0
  168. package/src/services/openai-client.ts +265 -0
  169. package/src/types/error-report.ts +26 -0
  170. package/src/types/js-tiktoken.d.ts +11 -0
  171. package/src/types/slow-query-report.ts +28 -0
  172. package/src/util/ai-qa-policy.ts +654 -0
  173. package/src/util/common.ts +649 -0
  174. package/src/util/customer-portal-password.ts +183 -0
  175. package/src/util/error-reporter.ts +332 -0
  176. package/src/util/error-tracking.ts +79 -0
  177. package/src/util/report-builder-unwinds.ts +180 -0
  178. package/src/util/schema-report-builder.ts +448 -0
  179. package/src/util/slow-query-reporter.ts +216 -0
  180. package/src/util/subscription-dependency-context.ts +1096 -0
  181. package/src/util/tokenizer.ts +38 -0
  182. package/src/workers/codex-runner.worker.ts +142 -0
  183. package/start_server.sh +5 -0
  184. package/tests/ai-assistant-corpus-build.ts +484 -0
  185. package/tests/ai-assistant-corpus-replay-e2e.ts +774 -0
  186. package/tests/ai-assistant-data-parity-e2e.ts +1989 -0
  187. package/tests/ai-assistant-eval-triage.ts +831 -0
  188. package/tests/ai-assistant-openai-e2e.ts +1061 -0
  189. package/tests/ai-assistant-openai-git-e2e.ts +155 -0
  190. package/tests/ai-assistant-preflight-matrix.ts +215 -0
  191. package/tests/ai-assistant-routing-eval.test.ts +560 -0
  192. package/tests/ai-assistant-snf-live-eval.ts +975 -0
  193. package/tests/ai-assistant-utils.test.ts +2860 -0
  194. package/tests/ai-runner-contract.test.ts +60 -0
  195. package/tests/error-reporter.test.ts +145 -0
  196. package/tests/report-builder-linking.test.ts +79 -0
  197. package/tests/resolveio-platform-intelligence.test.ts +352 -0
  198. package/tests/server-app-cron-owner.test.ts +127 -0
  199. package/tests/subscription-connect-race.test.ts +158 -0
  200. package/tests/subscription-dependency-context.test.ts +324 -0
  201. package/tests/subscription-manager-collection-tracking.test.ts +86 -0
  202. package/tests/subscription-manager-invalidation.test.ts +86 -0
  203. package/tsconfig.json +34 -0
  204. package/ai/assistant-core-heuristics.d.ts +0 -11
  205. package/ai/assistant-core-heuristics.js +0 -356
  206. package/ai/assistant-core-heuristics.js.map +0 -1
  207. package/ai/resolveio-platform-intelligence-memory-corpus.d.ts +0 -3
  208. package/ai/resolveio-platform-intelligence-memory-corpus.js +0 -214
  209. package/ai/resolveio-platform-intelligence-memory-corpus.js.map +0 -1
  210. package/ai/resolveio-platform-intelligence-memory.d.ts +0 -20
  211. package/ai/resolveio-platform-intelligence-memory.js +0 -341
  212. package/ai/resolveio-platform-intelligence-memory.js.map +0 -1
  213. package/ai/resolveio-platform-intelligence-types.js +0 -4
  214. package/ai/resolveio-platform-intelligence-types.js.map +0 -1
  215. package/ai/resolveio-platform-intelligence.d.ts +0 -6
  216. package/ai/resolveio-platform-intelligence.js +0 -463
  217. package/ai/resolveio-platform-intelligence.js.map +0 -1
  218. package/client-server-app.d.ts +0 -1
  219. package/client-server-app.js +0 -68
  220. package/client-server-app.js.map +0 -1
  221. package/collections/ai-terminal-conversation.collection.d.ts +0 -2
  222. package/collections/ai-terminal-conversation.collection.js +0 -140
  223. package/collections/ai-terminal-conversation.collection.js.map +0 -1
  224. package/collections/ai-terminal-issue-report.collection.d.ts +0 -2
  225. package/collections/ai-terminal-issue-report.collection.js +0 -148
  226. package/collections/ai-terminal-issue-report.collection.js.map +0 -1
  227. package/collections/ai-terminal-message.collection.d.ts +0 -2
  228. package/collections/ai-terminal-message.collection.js +0 -121
  229. package/collections/ai-terminal-message.collection.js.map +0 -1
  230. package/collections/app-setting.collection.d.ts +0 -3
  231. package/collections/app-setting.collection.js +0 -103
  232. package/collections/app-setting.collection.js.map +0 -1
  233. package/collections/app-status.collection.d.ts +0 -3
  234. package/collections/app-status.collection.js +0 -57
  235. package/collections/app-status.collection.js.map +0 -1
  236. package/collections/communication-metric.collection.d.ts +0 -2
  237. package/collections/communication-metric.collection.js +0 -133
  238. package/collections/communication-metric.collection.js.map +0 -1
  239. package/collections/counter.collection.d.ts +0 -3
  240. package/collections/counter.collection.js +0 -56
  241. package/collections/counter.collection.js.map +0 -1
  242. package/collections/cron-job-history.collection.d.ts +0 -3
  243. package/collections/cron-job-history.collection.js +0 -137
  244. package/collections/cron-job-history.collection.js.map +0 -1
  245. package/collections/cron-job.collection.d.ts +0 -3
  246. package/collections/cron-job.collection.js +0 -92
  247. package/collections/cron-job.collection.js.map +0 -1
  248. package/collections/customer-notification.collection.d.ts +0 -3
  249. package/collections/customer-notification.collection.js +0 -130
  250. package/collections/customer-notification.collection.js.map +0 -1
  251. package/collections/customer-portal-password.collection.d.ts +0 -3
  252. package/collections/customer-portal-password.collection.js +0 -75
  253. package/collections/customer-portal-password.collection.js.map +0 -1
  254. package/collections/email-history.collection.d.ts +0 -3
  255. package/collections/email-history.collection.js +0 -127
  256. package/collections/email-history.collection.js.map +0 -1
  257. package/collections/email-verified.collection.d.ts +0 -3
  258. package/collections/email-verified.collection.js +0 -62
  259. package/collections/email-verified.collection.js.map +0 -1
  260. package/collections/file.collection.d.ts +0 -3
  261. package/collections/file.collection.js +0 -74
  262. package/collections/file.collection.js.map +0 -1
  263. package/collections/flag-update.collection.d.ts +0 -3
  264. package/collections/flag-update.collection.js +0 -57
  265. package/collections/flag-update.collection.js.map +0 -1
  266. package/collections/flag.collection.d.ts +0 -3
  267. package/collections/flag.collection.js +0 -57
  268. package/collections/flag.collection.js.map +0 -1
  269. package/collections/log-method-latency.collection.d.ts +0 -3
  270. package/collections/log-method-latency.collection.js +0 -77
  271. package/collections/log-method-latency.collection.js.map +0 -1
  272. package/collections/log-subscription.collection.d.ts +0 -3
  273. package/collections/log-subscription.collection.js +0 -80
  274. package/collections/log-subscription.collection.js.map +0 -1
  275. package/collections/log.collection.d.ts +0 -3
  276. package/collections/log.collection.js +0 -93
  277. package/collections/log.collection.js.map +0 -1
  278. package/collections/logged-in-users.collection.d.ts +0 -3
  279. package/collections/logged-in-users.collection.js +0 -67
  280. package/collections/logged-in-users.collection.js.map +0 -1
  281. package/collections/monitor-cpu.collection.d.ts +0 -3
  282. package/collections/monitor-cpu.collection.js +0 -65
  283. package/collections/monitor-cpu.collection.js.map +0 -1
  284. package/collections/monitor-function.collection.d.ts +0 -3
  285. package/collections/monitor-function.collection.js +0 -74
  286. package/collections/monitor-function.collection.js.map +0 -1
  287. package/collections/monitor-memory.collection.d.ts +0 -3
  288. package/collections/monitor-memory.collection.js +0 -77
  289. package/collections/monitor-memory.collection.js.map +0 -1
  290. package/collections/monitor-mongo.collection.d.ts +0 -3
  291. package/collections/monitor-mongo.collection.js +0 -71
  292. package/collections/monitor-mongo.collection.js.map +0 -1
  293. package/collections/notification.collection.d.ts +0 -3
  294. package/collections/notification.collection.js +0 -57
  295. package/collections/notification.collection.js.map +0 -1
  296. package/collections/openai-usage-ledger.collection.d.ts +0 -2
  297. package/collections/openai-usage-ledger.collection.js +0 -124
  298. package/collections/openai-usage-ledger.collection.js.map +0 -1
  299. package/collections/report-builder-dashboard-builder.collection.d.ts +0 -3
  300. package/collections/report-builder-dashboard-builder.collection.js +0 -109
  301. package/collections/report-builder-dashboard-builder.collection.js.map +0 -1
  302. package/collections/report-builder-library.collection.d.ts +0 -3
  303. package/collections/report-builder-library.collection.js +0 -87
  304. package/collections/report-builder-library.collection.js.map +0 -1
  305. package/collections/report-builder-report.collection.d.ts +0 -4
  306. package/collections/report-builder-report.collection.js +0 -184
  307. package/collections/report-builder-report.collection.js.map +0 -1
  308. package/collections/user-group.collection.d.ts +0 -4
  309. package/collections/user-group.collection.js +0 -89
  310. package/collections/user-group.collection.js.map +0 -1
  311. package/collections/user-guide.collection.d.ts +0 -3
  312. package/collections/user-guide.collection.js +0 -57
  313. package/collections/user-guide.collection.js.map +0 -1
  314. package/collections/user.collection.d.ts +0 -4
  315. package/collections/user.collection.js +0 -180
  316. package/collections/user.collection.js.map +0 -1
  317. package/cron/cron.d.ts +0 -14
  318. package/cron/cron.js +0 -216
  319. package/cron/cron.js.map +0 -1
  320. package/fixtures/cron-jobs.d.ts +0 -1
  321. package/fixtures/cron-jobs.js +0 -150
  322. package/fixtures/cron-jobs.js.map +0 -1
  323. package/fixtures/init.d.ts +0 -1
  324. package/fixtures/init.js +0 -91
  325. package/fixtures/init.js.map +0 -1
  326. package/http/auth.d.ts +0 -2
  327. package/http/auth.js +0 -906
  328. package/http/auth.js.map +0 -1
  329. package/http/health.d.ts +0 -1
  330. package/http/health.js +0 -11
  331. package/http/health.js.map +0 -1
  332. package/http/home.d.ts +0 -1
  333. package/http/home.js +0 -134
  334. package/http/home.js.map +0 -1
  335. package/http/slow-query-publication.d.ts +0 -2
  336. package/http/slow-query-publication.js +0 -99
  337. package/http/slow-query-publication.js.map +0 -1
  338. package/index.d.ts +0 -1
  339. package/index.js +0 -19
  340. package/index.js.map +0 -1
  341. package/managers/ai-assistant-codex-manager.manager.d.ts +0 -67
  342. package/managers/ai-assistant-codex-manager.manager.js +0 -1113
  343. package/managers/ai-assistant-codex-manager.manager.js.map +0 -1
  344. package/managers/communication-metric.manager.d.ts +0 -16
  345. package/managers/communication-metric.manager.js +0 -134
  346. package/managers/communication-metric.manager.js.map +0 -1
  347. package/managers/cron.manager.d.ts +0 -20
  348. package/managers/cron.manager.js +0 -534
  349. package/managers/cron.manager.js.map +0 -1
  350. package/managers/customer-notification-content.manager.d.ts +0 -55
  351. package/managers/customer-notification-content.manager.js +0 -158
  352. package/managers/customer-notification-content.manager.js.map +0 -1
  353. package/managers/diagnostic-manager-bootstrap.d.ts +0 -9
  354. package/managers/diagnostic-manager-bootstrap.js +0 -260
  355. package/managers/diagnostic-manager-bootstrap.js.map +0 -1
  356. package/managers/error-auto-fix.manager.d.ts +0 -149
  357. package/managers/error-auto-fix.manager.js +0 -3064
  358. package/managers/error-auto-fix.manager.js.map +0 -1
  359. package/managers/local-log.manager.d.ts +0 -18
  360. package/managers/local-log.manager.js +0 -88
  361. package/managers/local-log.manager.js.map +0 -1
  362. package/managers/method.manager.d.ts +0 -83
  363. package/managers/method.manager.js +0 -1941
  364. package/managers/method.manager.js.map +0 -1
  365. package/managers/mongo.manager.d.ts +0 -224
  366. package/managers/mongo.manager.js +0 -5000
  367. package/managers/mongo.manager.js.map +0 -1
  368. package/managers/monitor.manager.d.ts +0 -70
  369. package/managers/monitor.manager.js +0 -550
  370. package/managers/monitor.manager.js.map +0 -1
  371. package/managers/openai-usage-ledger.manager.d.ts +0 -15
  372. package/managers/openai-usage-ledger.manager.js +0 -144
  373. package/managers/openai-usage-ledger.manager.js.map +0 -1
  374. package/managers/slow-query-verifier.manager.d.ts +0 -144
  375. package/managers/slow-query-verifier.manager.js +0 -3857
  376. package/managers/slow-query-verifier.manager.js.map +0 -1
  377. package/managers/slow-query.manager.d.ts +0 -28
  378. package/managers/slow-query.manager.js +0 -468
  379. package/managers/slow-query.manager.js.map +0 -1
  380. package/managers/subscription.manager.d.ts +0 -169
  381. package/managers/subscription.manager.js +0 -3434
  382. package/managers/subscription.manager.js.map +0 -1
  383. package/managers/websocket.manager.d.ts +0 -73
  384. package/managers/websocket.manager.js +0 -673
  385. package/managers/websocket.manager.js.map +0 -1
  386. package/managers/worker-dispatcher.manager.d.ts +0 -120
  387. package/managers/worker-dispatcher.manager.js +0 -1266
  388. package/managers/worker-dispatcher.manager.js.map +0 -1
  389. package/managers/worker-server.manager.d.ts +0 -35
  390. package/managers/worker-server.manager.js +0 -582
  391. package/managers/worker-server.manager.js.map +0 -1
  392. package/methods/accounts.d.ts +0 -2
  393. package/methods/accounts.js +0 -624
  394. package/methods/accounts.js.map +0 -1
  395. package/methods/ai-terminal.d.ts +0 -322
  396. package/methods/ai-terminal.js +0 -22699
  397. package/methods/ai-terminal.js.map +0 -1
  398. package/methods/app-settings.d.ts +0 -2
  399. package/methods/app-settings.js +0 -169
  400. package/methods/app-settings.js.map +0 -1
  401. package/methods/aws.d.ts +0 -2
  402. package/methods/aws.js +0 -877
  403. package/methods/aws.js.map +0 -1
  404. package/methods/collections.d.ts +0 -2
  405. package/methods/collections.js +0 -719
  406. package/methods/collections.js.map +0 -1
  407. package/methods/counters.d.ts +0 -2
  408. package/methods/counters.js +0 -113
  409. package/methods/counters.js.map +0 -1
  410. package/methods/cron-jobs.d.ts +0 -2
  411. package/methods/cron-jobs.js +0 -2475
  412. package/methods/cron-jobs.js.map +0 -1
  413. package/methods/customer-notifications.d.ts +0 -2
  414. package/methods/customer-notifications.js +0 -528
  415. package/methods/customer-notifications.js.map +0 -1
  416. package/methods/diagnostics.d.ts +0 -2
  417. package/methods/diagnostics.js +0 -703
  418. package/methods/diagnostics.js.map +0 -1
  419. package/methods/flag-updates.d.ts +0 -2
  420. package/methods/flag-updates.js +0 -8
  421. package/methods/flag-updates.js.map +0 -1
  422. package/methods/flags.d.ts +0 -2
  423. package/methods/flags.js +0 -8
  424. package/methods/flags.js.map +0 -1
  425. package/methods/logs.d.ts +0 -2
  426. package/methods/logs.js +0 -751
  427. package/methods/logs.js.map +0 -1
  428. package/methods/mongo-explorer.d.ts +0 -2
  429. package/methods/mongo-explorer.js +0 -1808
  430. package/methods/mongo-explorer.js.map +0 -1
  431. package/methods/monitor.d.ts +0 -2
  432. package/methods/monitor.js +0 -543
  433. package/methods/monitor.js.map +0 -1
  434. package/methods/pdf.d.ts +0 -2
  435. package/methods/pdf.js +0 -1216
  436. package/methods/pdf.js.map +0 -1
  437. package/methods/publications.d.ts +0 -1
  438. package/methods/publications.js +0 -183
  439. package/methods/publications.js.map +0 -1
  440. package/methods/report-builder.d.ts +0 -2
  441. package/methods/report-builder.js +0 -3094
  442. package/methods/report-builder.js.map +0 -1
  443. package/methods/support.d.ts +0 -2
  444. package/methods/support.js +0 -430
  445. package/methods/support.js.map +0 -1
  446. package/models/ai-terminal-conversation.model.d.ts +0 -17
  447. package/models/ai-terminal-conversation.model.js +0 -4
  448. package/models/ai-terminal-conversation.model.js.map +0 -1
  449. package/models/ai-terminal-issue-report.model.d.ts +0 -19
  450. package/models/ai-terminal-issue-report.model.js +0 -4
  451. package/models/ai-terminal-issue-report.model.js.map +0 -1
  452. package/models/ai-terminal-message.model.d.ts +0 -22
  453. package/models/ai-terminal-message.model.js +0 -4
  454. package/models/ai-terminal-message.model.js.map +0 -1
  455. package/models/app-setting.model.d.ts +0 -16
  456. package/models/app-setting.model.js +0 -4
  457. package/models/app-setting.model.js.map +0 -1
  458. package/models/app-status.model.js +0 -4
  459. package/models/app-status.model.js.map +0 -1
  460. package/models/billing-logged-in-users.model.js +0 -4
  461. package/models/billing-logged-in-users.model.js.map +0 -1
  462. package/models/collection-document.model.d.ts +0 -21
  463. package/models/collection-document.model.js +0 -4
  464. package/models/collection-document.model.js.map +0 -1
  465. package/models/communication-metric.model.d.ts +0 -20
  466. package/models/communication-metric.model.js +0 -4
  467. package/models/communication-metric.model.js.map +0 -1
  468. package/models/counter.model.js +0 -4
  469. package/models/counter.model.js.map +0 -1
  470. package/models/cron-job-history.model.d.ts +0 -15
  471. package/models/cron-job-history.model.js +0 -4
  472. package/models/cron-job-history.model.js.map +0 -1
  473. package/models/cron-job.model.d.ts +0 -14
  474. package/models/cron-job.model.js +0 -4
  475. package/models/cron-job.model.js.map +0 -1
  476. package/models/customer-notification.model.d.ts +0 -26
  477. package/models/customer-notification.model.js +0 -4
  478. package/models/customer-notification.model.js.map +0 -1
  479. package/models/customer-portal-password.model.d.ts +0 -11
  480. package/models/customer-portal-password.model.js +0 -4
  481. package/models/customer-portal-password.model.js.map +0 -1
  482. package/models/dialog.model.d.ts +0 -23
  483. package/models/dialog.model.js +0 -4
  484. package/models/dialog.model.js.map +0 -1
  485. package/models/email-history.model.d.ts +0 -31
  486. package/models/email-history.model.js.map +0 -1
  487. package/models/email-verified.model.js +0 -4
  488. package/models/email-verified.model.js.map +0 -1
  489. package/models/file.model.js +0 -4
  490. package/models/file.model.js.map +0 -1
  491. package/models/flag-update.model.js +0 -4
  492. package/models/flag-update.model.js.map +0 -1
  493. package/models/flag.model.js +0 -4
  494. package/models/flag.model.js.map +0 -1
  495. package/models/log-method-latency.model.d.ts +0 -10
  496. package/models/log-method-latency.model.js +0 -4
  497. package/models/log-method-latency.model.js.map +0 -1
  498. package/models/log-subscription.model.js +0 -4
  499. package/models/log-subscription.model.js.map +0 -1
  500. package/models/log.model.d.ts +0 -17
  501. package/models/log.model.js +0 -4
  502. package/models/log.model.js.map +0 -1
  503. package/models/logged-in-users.model.js +0 -4
  504. package/models/logged-in-users.model.js.map +0 -1
  505. package/models/method-response.model.js +0 -4
  506. package/models/method-response.model.js.map +0 -1
  507. package/models/method.model.d.ts +0 -26
  508. package/models/method.model.js +0 -4
  509. package/models/method.model.js.map +0 -1
  510. package/models/monitor-cpu.model.js +0 -4
  511. package/models/monitor-cpu.model.js.map +0 -1
  512. package/models/monitor-function.model.d.ts +0 -14
  513. package/models/monitor-function.model.js +0 -4
  514. package/models/monitor-function.model.js.map +0 -1
  515. package/models/monitor-memory.model.d.ts +0 -15
  516. package/models/monitor-memory.model.js +0 -4
  517. package/models/monitor-memory.model.js.map +0 -1
  518. package/models/monitor-mongo.model.d.ts +0 -13
  519. package/models/monitor-mongo.model.js +0 -4
  520. package/models/monitor-mongo.model.js.map +0 -1
  521. package/models/notification.model.js +0 -4
  522. package/models/notification.model.js.map +0 -1
  523. package/models/openai-usage-ledger.model.d.ts +0 -15
  524. package/models/openai-usage-ledger.model.js +0 -4
  525. package/models/openai-usage-ledger.model.js.map +0 -1
  526. package/models/pagination.model.d.ts +0 -11
  527. package/models/pagination.model.js +0 -28
  528. package/models/pagination.model.js.map +0 -1
  529. package/models/permission.model.d.ts +0 -12
  530. package/models/permission.model.js +0 -4
  531. package/models/permission.model.js.map +0 -1
  532. package/models/report-builder-dashboard-builder.model.d.ts +0 -25
  533. package/models/report-builder-dashboard-builder.model.js +0 -4
  534. package/models/report-builder-dashboard-builder.model.js.map +0 -1
  535. package/models/report-builder-library.model.d.ts +0 -17
  536. package/models/report-builder-library.model.js +0 -4
  537. package/models/report-builder-library.model.js.map +0 -1
  538. package/models/report-builder-report.model.d.ts +0 -121
  539. package/models/report-builder-report.model.js +0 -4
  540. package/models/report-builder-report.model.js.map +0 -1
  541. package/models/report-builder.model.d.ts +0 -61
  542. package/models/report-builder.model.js +0 -4
  543. package/models/report-builder.model.js.map +0 -1
  544. package/models/select-data-label.model.d.ts +0 -9
  545. package/models/select-data-label.model.js +0 -4
  546. package/models/select-data-label.model.js.map +0 -1
  547. package/models/server-message.model.d.ts +0 -32
  548. package/models/server-message.model.js +0 -4
  549. package/models/server-message.model.js.map +0 -1
  550. package/models/slow-query-report.model.d.ts +0 -23
  551. package/models/slow-query-report.model.js +0 -4
  552. package/models/slow-query-report.model.js.map +0 -1
  553. package/models/subscription.model.d.ts +0 -31
  554. package/models/subscription.model.js +0 -4
  555. package/models/subscription.model.js.map +0 -1
  556. package/models/support-ticket.model.d.ts +0 -87
  557. package/models/support-ticket.model.js +0 -4
  558. package/models/support-ticket.model.js.map +0 -1
  559. package/models/user-group.model.d.ts +0 -20
  560. package/models/user-group.model.js +0 -4
  561. package/models/user-group.model.js.map +0 -1
  562. package/models/user-guide.model.js +0 -4
  563. package/models/user-guide.model.js.map +0 -1
  564. package/models/user.model.d.ts +0 -84
  565. package/models/user.model.js +0 -4
  566. package/models/user.model.js.map +0 -1
  567. package/private/images/ResolveIO.png +0 -0
  568. package/public_api.js +0 -112
  569. package/public_api.js.map +0 -1
  570. package/publications/ai-terminal.d.ts +0 -1
  571. package/publications/ai-terminal.js +0 -122
  572. package/publications/ai-terminal.js.map +0 -1
  573. package/publications/app-settings.d.ts +0 -2
  574. package/publications/app-settings.js +0 -28
  575. package/publications/app-settings.js.map +0 -1
  576. package/publications/app-status.d.ts +0 -2
  577. package/publications/app-status.js +0 -16
  578. package/publications/app-status.js.map +0 -1
  579. package/publications/cron-jobs.d.ts +0 -2
  580. package/publications/cron-jobs.js +0 -88
  581. package/publications/cron-jobs.js.map +0 -1
  582. package/publications/customer-notifications.d.ts +0 -2
  583. package/publications/customer-notifications.js +0 -161
  584. package/publications/customer-notifications.js.map +0 -1
  585. package/publications/files.d.ts +0 -2
  586. package/publications/files.js +0 -36
  587. package/publications/files.js.map +0 -1
  588. package/publications/flags-update.d.ts +0 -2
  589. package/publications/flags-update.js +0 -22
  590. package/publications/flags-update.js.map +0 -1
  591. package/publications/flags.d.ts +0 -2
  592. package/publications/flags.js +0 -22
  593. package/publications/flags.js.map +0 -1
  594. package/publications/logs.d.ts +0 -2
  595. package/publications/logs.js +0 -164
  596. package/publications/logs.js.map +0 -1
  597. package/publications/notifications.d.ts +0 -2
  598. package/publications/notifications.js +0 -16
  599. package/publications/notifications.js.map +0 -1
  600. package/publications/report-builder-dashboard-builders.d.ts +0 -2
  601. package/publications/report-builder-dashboard-builders.js +0 -42
  602. package/publications/report-builder-dashboard-builders.js.map +0 -1
  603. package/publications/report-builder-libraries.d.ts +0 -2
  604. package/publications/report-builder-libraries.js +0 -90
  605. package/publications/report-builder-libraries.js.map +0 -1
  606. package/publications/report-builder-reports.d.ts +0 -2
  607. package/publications/report-builder-reports.js +0 -50
  608. package/publications/report-builder-reports.js.map +0 -1
  609. package/publications/super-admin.d.ts +0 -2
  610. package/publications/super-admin.js +0 -16
  611. package/publications/super-admin.js.map +0 -1
  612. package/publications/user-groups.d.ts +0 -1
  613. package/publications/user-groups.js +0 -16
  614. package/publications/user-groups.js.map +0 -1
  615. package/publications/user-guides.d.ts +0 -1
  616. package/publications/user-guides.js +0 -16
  617. package/publications/user-guides.js.map +0 -1
  618. package/resolveio-server-app.d.ts +0 -70
  619. package/resolveio-server-app.js +0 -801
  620. package/resolveio-server-app.js.map +0 -1
  621. package/server-app.d.ts +0 -228
  622. package/server-app.js +0 -3566
  623. package/server-app.js.map +0 -1
  624. package/services/codex-client.d.ts +0 -126
  625. package/services/codex-client.js +0 -1622
  626. package/services/codex-client.js.map +0 -1
  627. package/services/openai-client.d.ts +0 -46
  628. package/services/openai-client.js +0 -318
  629. package/services/openai-client.js.map +0 -1
  630. package/types/error-report.d.ts +0 -25
  631. package/types/error-report.js +0 -4
  632. package/types/error-report.js.map +0 -1
  633. package/types/slow-query-report.d.ts +0 -27
  634. package/types/slow-query-report.js +0 -6
  635. package/types/slow-query-report.js.map +0 -1
  636. package/util/ai-qa-policy.d.ts +0 -94
  637. package/util/ai-qa-policy.js +0 -505
  638. package/util/ai-qa-policy.js.map +0 -1
  639. package/util/common.d.ts +0 -31
  640. package/util/common.js +0 -683
  641. package/util/common.js.map +0 -1
  642. package/util/customer-portal-password.d.ts +0 -13
  643. package/util/customer-portal-password.js +0 -209
  644. package/util/customer-portal-password.js.map +0 -1
  645. package/util/error-reporter.d.ts +0 -52
  646. package/util/error-reporter.js +0 -326
  647. package/util/error-reporter.js.map +0 -1
  648. package/util/error-tracking.d.ts +0 -13
  649. package/util/error-tracking.js +0 -120
  650. package/util/error-tracking.js.map +0 -1
  651. package/util/report-builder-unwinds.d.ts +0 -15
  652. package/util/report-builder-unwinds.js +0 -156
  653. package/util/report-builder-unwinds.js.map +0 -1
  654. package/util/schema-report-builder.d.ts +0 -6
  655. package/util/schema-report-builder.js +0 -481
  656. package/util/schema-report-builder.js.map +0 -1
  657. package/util/slow-query-reporter.d.ts +0 -28
  658. package/util/slow-query-reporter.js +0 -226
  659. package/util/slow-query-reporter.js.map +0 -1
  660. package/util/subscription-dependency-context.d.ts +0 -34
  661. package/util/subscription-dependency-context.js +0 -1283
  662. package/util/subscription-dependency-context.js.map +0 -1
  663. package/util/tokenizer.d.ts +0 -5
  664. package/util/tokenizer.js +0 -41
  665. package/util/tokenizer.js.map +0 -1
  666. package/workers/codex-runner.worker.d.ts +0 -1
  667. package/workers/codex-runner.worker.js +0 -192
  668. package/workers/codex-runner.worker.js.map +0 -1
  669. /package/{private → src/private}/email-templates/enrollment.html +0 -0
  670. /package/{private → src/private}/email-templates/forgot-password.html +0 -0
  671. /package/{private → src/private}/email-templates/support-ticket-deleted.html +0 -0
  672. /package/{private → src/private}/email-templates/support-ticket-modified.html +0 -0
  673. /package/{private → src/private}/email-templates/support-ticket.html +0 -0
  674. /package/{public_api.d.ts → src/public_api.ts} +0 -0
@@ -0,0 +1,774 @@
1
+ import * as fs from 'fs';
2
+ import * as path from 'path';
3
+ import { ResolveIOServer } from '../src/resolveio-server-app';
4
+ import { classifyAssistantRequestType } from '../src/methods/ai-terminal';
5
+
6
+ type CorpusPromptEntry = {
7
+ id?: string;
8
+ prompt?: string;
9
+ score?: number;
10
+ };
11
+
12
+ type CorpusFile = {
13
+ prompts?: CorpusPromptEntry[];
14
+ };
15
+
16
+ type ReplayResult = {
17
+ id: string;
18
+ prompt: string;
19
+ pass: boolean;
20
+ errors: string[];
21
+ conversationId?: string;
22
+ classification?: {
23
+ type?: string;
24
+ dataQuestion?: boolean;
25
+ source?: string;
26
+ };
27
+ tool?: {
28
+ type?: string;
29
+ collection?: string;
30
+ rowCount?: number;
31
+ total?: number | null;
32
+ columns?: string[];
33
+ source?: string;
34
+ };
35
+ };
36
+
37
+ type AssistantDirective = {
38
+ type: 'read' | 'aggregate';
39
+ payload: Record<string, any>;
40
+ source: 'metadata.debug.directive' | 'assistant.directive_line';
41
+ };
42
+
43
+ function parseBoolean(value: any): boolean {
44
+ return ['true', '1', 'yes', 'y', 'on'].includes(String(value || '').trim().toLowerCase());
45
+ }
46
+
47
+ function normalizeOptionalString(value: any): string {
48
+ return String(value ?? '').trim();
49
+ }
50
+
51
+ function parseInteger(value: any, fallback: number, min: number, max: number): number {
52
+ const parsed = Number(value);
53
+ if (!Number.isFinite(parsed)) {
54
+ return fallback;
55
+ }
56
+ return Math.min(Math.max(Math.round(parsed), min), max);
57
+ }
58
+
59
+ function loadDotEnvFile(filePath: string): Record<string, string> {
60
+ const parsed: Record<string, string> = {};
61
+ if (!fs.existsSync(filePath)) {
62
+ return parsed;
63
+ }
64
+ const content = fs.readFileSync(filePath, 'utf8');
65
+ content.split(/\r?\n/g).forEach((lineRaw) => {
66
+ const line = lineRaw.trim();
67
+ if (!line || line.startsWith('#')) {
68
+ return;
69
+ }
70
+ const jsonLike = line.match(/^"([A-Za-z_][A-Za-z0-9_]*)"\s*:\s*(.+?)\s*,?$/);
71
+ if (jsonLike?.[1]) {
72
+ const key = jsonLike[1];
73
+ let value = String(jsonLike[2] || '').trim();
74
+ if ((value.startsWith('"') && value.endsWith('"')) || (value.startsWith('\'') && value.endsWith('\''))) {
75
+ value = value.slice(1, -1);
76
+ }
77
+ if (key) {
78
+ parsed[key] = value;
79
+ }
80
+ return;
81
+ }
82
+ const separator = line.indexOf('=');
83
+ if (separator <= 0) {
84
+ return;
85
+ }
86
+ const key = line.slice(0, separator).trim();
87
+ let value = line.slice(separator + 1).trim();
88
+ if ((value.startsWith('"') && value.endsWith('"')) || (value.startsWith('\'') && value.endsWith('\''))) {
89
+ value = value.slice(1, -1);
90
+ }
91
+ if (key) {
92
+ parsed[key] = value;
93
+ }
94
+ });
95
+ return parsed;
96
+ }
97
+
98
+ function applyEnvFromServerDir(serverDir: string): void {
99
+ const envFiles = [
100
+ path.join(serverDir, '.env.codex'),
101
+ path.join(serverDir, '.env.production'),
102
+ path.join(serverDir, '.env')
103
+ ];
104
+ envFiles.forEach((filePath) => {
105
+ const values = loadDotEnvFile(filePath);
106
+ Object.keys(values).forEach((key) => {
107
+ if (!process.env[key]) {
108
+ process.env[key] = values[key];
109
+ }
110
+ });
111
+ });
112
+ }
113
+
114
+ async function sleep(ms: number): Promise<void> {
115
+ return await new Promise(resolve => setTimeout(resolve, ms));
116
+ }
117
+
118
+ async function pollFinalAssistantMessage(db: any, idConversation: string, timeoutMs = 180000): Promise<any> {
119
+ const started = Date.now();
120
+ while (Date.now() - started < timeoutMs) {
121
+ const message = await db.collection('ai-terminal-messages').findOne(
122
+ { id_conversation: idConversation, role: 'assistant' },
123
+ { sort: { createdAt: -1 } }
124
+ );
125
+ if (message && message?.metadata?.pending !== true) {
126
+ return message;
127
+ }
128
+ await sleep(1200);
129
+ }
130
+ throw new Error(`Timed out waiting for final assistant message (${idConversation}).`);
131
+ }
132
+
133
+ function buildMethodContext(methodManager: any, idUser: string): any {
134
+ return Object.assign({}, methodManager, Object.getPrototypeOf(methodManager), {
135
+ id_user: idUser,
136
+ user: 'AI Corpus Replay',
137
+ id_ws: 'ai-assistant-corpus-replay-e2e'
138
+ });
139
+ }
140
+
141
+ async function callMethodAsUser(methodManager: any, idUser: string, method: string, payload: Record<string, any>): Promise<any> {
142
+ const ctx = buildMethodContext(methodManager, idUser);
143
+ return await methodManager.callMethod.call(ctx, method, payload);
144
+ }
145
+
146
+ async function findSuperAdminUserId(db: any): Promise<string> {
147
+ const user = await db.collection('users').findOne(
148
+ { 'roles.super_admin': true },
149
+ { projection: { _id: 1 }, sort: { updatedAt: -1, createdAt: -1 } }
150
+ );
151
+ if (!user?._id) {
152
+ throw new Error('Could not find super admin user.');
153
+ }
154
+ return String(user._id);
155
+ }
156
+
157
+ async function runPrompt(methodManager: any, db: any, idUser: string, prompt: string, appId: string): Promise<{ conversationId: string; message: any }> {
158
+ const model = String(process.env.AI_ASSISTANT_CODEX_MODEL || process.env.OPENAI_MODEL || '').trim();
159
+ const payload = {
160
+ message: prompt,
161
+ id_app: appId,
162
+ max_history: 0,
163
+ config: {
164
+ ...(model ? { model } : {})
165
+ }
166
+ };
167
+ const response = await callMethodAsUser(methodManager, idUser, 'aiCoderTerminalRunCodex', payload);
168
+ const conversationId = String(response?.conversation?._id || response?.conversation?.id_conversation || '').trim();
169
+ if (!conversationId) {
170
+ throw new Error('No conversation id returned from aiCoderTerminalRunCodex.');
171
+ }
172
+ const message = await pollFinalAssistantMessage(db, conversationId);
173
+ return { conversationId, message };
174
+ }
175
+
176
+ function parseDirectiveLine(content: string): AssistantDirective | null {
177
+ const lines = String(content || '').split(/\r?\n/g);
178
+ for (const lineRaw of lines) {
179
+ const line = lineRaw.trim();
180
+ if (!line) {
181
+ continue;
182
+ }
183
+ const readPrefix = 'REPORT_BUILDER_READ:';
184
+ const aggPrefix = 'REPORT_BUILDER_AGG:';
185
+ let type: AssistantDirective['type'] | null = null;
186
+ let jsonText = '';
187
+ if (line.startsWith(readPrefix)) {
188
+ type = 'read';
189
+ jsonText = line.slice(readPrefix.length).trim();
190
+ }
191
+ else if (line.startsWith(aggPrefix)) {
192
+ type = 'aggregate';
193
+ jsonText = line.slice(aggPrefix.length).trim();
194
+ }
195
+ if (!type || !jsonText) {
196
+ continue;
197
+ }
198
+ try {
199
+ const payload = JSON.parse(jsonText);
200
+ if (!payload || typeof payload !== 'object' || Array.isArray(payload)) {
201
+ continue;
202
+ }
203
+ return {
204
+ type,
205
+ payload,
206
+ source: 'assistant.directive_line'
207
+ };
208
+ }
209
+ catch {
210
+ continue;
211
+ }
212
+ }
213
+ return null;
214
+ }
215
+
216
+ function extractDirectiveFromMessage(message: any): AssistantDirective | null {
217
+ const debugDirective = message?.metadata?.debug?.directive;
218
+ if (debugDirective && typeof debugDirective === 'object') {
219
+ const normalizedType = normalizeOptionalString(debugDirective?.type).toLowerCase();
220
+ if ((normalizedType === 'read' || normalizedType === 'aggregate')
221
+ && debugDirective.payload
222
+ && typeof debugDirective.payload === 'object'
223
+ && !Array.isArray(debugDirective.payload)) {
224
+ return {
225
+ type: normalizedType as AssistantDirective['type'],
226
+ payload: debugDirective.payload,
227
+ source: 'metadata.debug.directive'
228
+ };
229
+ }
230
+ const rawLineDirective = parseDirectiveLine(normalizeOptionalString(debugDirective?.rawLine));
231
+ if (rawLineDirective) {
232
+ return {
233
+ ...rawLineDirective,
234
+ source: 'metadata.debug.directive'
235
+ };
236
+ }
237
+ }
238
+ return parseDirectiveLine(normalizeOptionalString(message?.content));
239
+ }
240
+
241
+ function buildSyntheticToolResultFromDirective(directive: AssistantDirective, methodResponse: any): any {
242
+ const display = methodResponse?.display && typeof methodResponse.display === 'object'
243
+ ? methodResponse.display
244
+ : {
245
+ columns: [] as string[],
246
+ rows: [] as Array<Record<string, any>>,
247
+ rowCount: 0,
248
+ truncated: false
249
+ };
250
+ const rowCount = Array.isArray(methodResponse?.documents)
251
+ ? methodResponse.documents.length
252
+ : Number(display?.rowCount || 0);
253
+ const total = typeof methodResponse?.total === 'number' ? methodResponse.total : undefined;
254
+ const collection = normalizeOptionalString(methodResponse?.debug?.collectionResolved)
255
+ || normalizeOptionalString(methodResponse?.debug?.collection)
256
+ || normalizeOptionalString(directive.payload?.collection);
257
+ return {
258
+ type: directive.type === 'aggregate' ? 'mongo_agg' : 'mongo_read',
259
+ input: directive.payload,
260
+ output: {
261
+ display,
262
+ total,
263
+ collection: collection || undefined,
264
+ rowCount,
265
+ columns: Array.isArray(display?.columns) ? display.columns : [],
266
+ truncated: display?.truncated === true
267
+ }
268
+ };
269
+ }
270
+
271
+ function toNormalizedKey(value: string): string {
272
+ return String(value || '').toLowerCase().replace(/[^a-z0-9]+/g, '');
273
+ }
274
+
275
+ function parseNumericLoose(value: any): number | null {
276
+ if (typeof value === 'number' && Number.isFinite(value)) {
277
+ return value;
278
+ }
279
+ if (typeof value !== 'string') {
280
+ return null;
281
+ }
282
+ const trimmed = value.trim();
283
+ if (!trimmed) {
284
+ return null;
285
+ }
286
+ const normalized = trimmed
287
+ .replace(/\$/g, '')
288
+ .replace(/,/g, '')
289
+ .replace(/%/g, '')
290
+ .replace(/\s+/g, '');
291
+ if (!normalized || !/^[-+]?\d*\.?\d+$/.test(normalized)) {
292
+ return null;
293
+ }
294
+ const parsed = Number(normalized);
295
+ return Number.isFinite(parsed) ? parsed : null;
296
+ }
297
+
298
+ function normalizeCellValue(value: any): any {
299
+ const numeric = parseNumericLoose(value);
300
+ if (numeric !== null) {
301
+ return Number(numeric.toFixed(6));
302
+ }
303
+ if (value instanceof Date) {
304
+ return value.toISOString();
305
+ }
306
+ if (typeof value === 'string') {
307
+ const trimmed = value.trim();
308
+ const maybeDate = /[0-9]{4}-[0-9]{2}-[0-9]{2}/.test(trimmed) ? Date.parse(trimmed) : Number.NaN;
309
+ if (Number.isFinite(maybeDate)) {
310
+ return new Date(maybeDate).toISOString();
311
+ }
312
+ return trimmed;
313
+ }
314
+ if (value === undefined) {
315
+ return null;
316
+ }
317
+ return value;
318
+ }
319
+
320
+ function normalizeDisplayRows(display: any): Array<Record<string, any>> {
321
+ const rows = Array.isArray(display?.rows) ? display.rows : [];
322
+ return rows.map((row: any) => {
323
+ const next: Record<string, any> = {};
324
+ Object.keys(row || {}).forEach((key) => {
325
+ next[toNormalizedKey(key)] = normalizeCellValue((row as any)[key]);
326
+ });
327
+ return next;
328
+ });
329
+ }
330
+
331
+ function normalizeDisplayColumns(display: any): string[] {
332
+ const columns = Array.isArray(display?.columns) ? display.columns : [];
333
+ return columns.map((column: any) => toNormalizedKey(String(column || ''))).filter(Boolean).sort();
334
+ }
335
+
336
+ function collectMonthColumns(columns: string[]): string[] {
337
+ return columns.filter(column => /^\d{4}-\d{2}$/.test(String(column || '').trim()));
338
+ }
339
+
340
+ function parseMonthlyTotalsFromDisplay(display: any): Map<string, number> | null {
341
+ if (!display || !Array.isArray(display.columns) || !Array.isArray(display.rows) || !display.rows.length) {
342
+ return null;
343
+ }
344
+ const columns = display.columns.map((column: any) => String(column || '').trim());
345
+ const monthColumns = collectMonthColumns(columns);
346
+ if (monthColumns.length) {
347
+ const firstColumn = columns[0] || '';
348
+ const normalizedFirst = toNormalizedKey(firstColumn);
349
+ if (normalizedFirst === 'metric') {
350
+ const metricRow = display.rows.find((row: any) => {
351
+ const metricValue = String(row?.[firstColumn] || '').toLowerCase();
352
+ return metricValue.includes('revenue') || metricValue.includes('total');
353
+ }) || display.rows[0];
354
+ const result = new Map<string, number>();
355
+ monthColumns.forEach((month) => {
356
+ const numeric = parseNumericLoose(metricRow?.[month]);
357
+ if (numeric !== null) {
358
+ result.set(month, numeric);
359
+ }
360
+ });
361
+ return result.size ? result : null;
362
+ }
363
+ const result = new Map<string, number>();
364
+ monthColumns.forEach((month) => {
365
+ let sum = 0;
366
+ display.rows.forEach((row: any) => {
367
+ const numeric = parseNumericLoose(row?.[month]);
368
+ if (numeric !== null) {
369
+ sum += numeric;
370
+ }
371
+ });
372
+ result.set(month, sum);
373
+ });
374
+ return result;
375
+ }
376
+ const normalizedColumns = columns.map(toNormalizedKey);
377
+ const monthColumnIndex = normalizedColumns.findIndex((column) => column.includes('month'));
378
+ const totalColumnIndex = normalizedColumns.findIndex((column) => column.includes('revenue') || column.includes('total'));
379
+ if (monthColumnIndex === -1 || totalColumnIndex === -1) {
380
+ return null;
381
+ }
382
+ const monthColumn = columns[monthColumnIndex];
383
+ const totalColumn = columns[totalColumnIndex];
384
+ const result = new Map<string, number>();
385
+ display.rows.forEach((row: any) => {
386
+ const monthValue = String(row?.[monthColumn] || '').trim();
387
+ if (!/^\d{4}-\d{2}$/.test(monthValue)) {
388
+ return;
389
+ }
390
+ const numeric = parseNumericLoose(row?.[totalColumn]);
391
+ if (numeric === null) {
392
+ return;
393
+ }
394
+ result.set(monthValue, (result.get(monthValue) || 0) + numeric);
395
+ });
396
+ return result.size ? result : null;
397
+ }
398
+
399
+ function parseCustomerMonthTotalsFromDisplay(display: any): Map<string, number> | null {
400
+ if (!display || !Array.isArray(display.columns) || !Array.isArray(display.rows) || !display.rows.length) {
401
+ return null;
402
+ }
403
+ const columns = display.columns.map((column: any) => String(column || '').trim());
404
+ const normalizedColumns = columns.map(toNormalizedKey);
405
+ const monthColumns = collectMonthColumns(columns);
406
+ const monthTotals = new Map<string, number>();
407
+
408
+ if (monthColumns.length && normalizedColumns[0]?.includes('customer')) {
409
+ display.rows.forEach((row: any) => {
410
+ monthColumns.forEach((month) => {
411
+ const total = parseNumericLoose(row?.[month]);
412
+ if (total === null) {
413
+ return;
414
+ }
415
+ monthTotals.set(month, (monthTotals.get(month) || 0) + total);
416
+ });
417
+ });
418
+ return monthTotals.size ? monthTotals : null;
419
+ }
420
+
421
+ const monthColumnIndex = normalizedColumns.findIndex((column) => column.includes('month'));
422
+ const totalColumnIndex = normalizedColumns.findIndex((column) => column.includes('revenue') || column.includes('total'));
423
+ if (monthColumnIndex === -1 || totalColumnIndex === -1) {
424
+ return null;
425
+ }
426
+ const monthColumn = columns[monthColumnIndex];
427
+ const totalColumn = columns[totalColumnIndex];
428
+ display.rows.forEach((row: any) => {
429
+ const month = String(row?.[monthColumn] || '').trim();
430
+ if (!/^\d{4}-\d{2}$/.test(month)) {
431
+ return;
432
+ }
433
+ const total = parseNumericLoose(row?.[totalColumn]);
434
+ if (total === null) {
435
+ return;
436
+ }
437
+ monthTotals.set(month, (monthTotals.get(month) || 0) + total);
438
+ });
439
+ return monthTotals.size ? monthTotals : null;
440
+ }
441
+
442
+ function compareNumericMaps(expected: Map<string, number>, actual: Map<string, number>, tolerance = 0.05): string[] {
443
+ const errors: string[] = [];
444
+ const keys = new Set<string>([...Array.from(expected.keys()), ...Array.from(actual.keys())]);
445
+ keys.forEach((key) => {
446
+ const left = expected.get(key);
447
+ const right = actual.get(key);
448
+ if (left === undefined || right === undefined) {
449
+ errors.push(`missing_or_extra_key:${key}`);
450
+ return;
451
+ }
452
+ if (Math.abs(left - right) > tolerance) {
453
+ errors.push(`mismatch:${key}:${left}:${right}`);
454
+ }
455
+ });
456
+ return errors;
457
+ }
458
+
459
+ function compareReplayDisplay(toolDisplay: any, replayDisplay: any, toolRowCount: number, replayRowCount: number): string[] {
460
+ const errors: string[] = [];
461
+ if (toolRowCount === 0 && replayRowCount === 0) {
462
+ return [];
463
+ }
464
+ const toolColumns = normalizeDisplayColumns(toolDisplay);
465
+ const replayColumns = normalizeDisplayColumns(replayDisplay);
466
+ if (toolRowCount !== replayRowCount) {
467
+ errors.push(`Replay rowCount mismatch: tool_result=${toolRowCount}, replay=${replayRowCount}.`);
468
+ }
469
+ const sourceRows = normalizeDisplayRows(toolDisplay);
470
+ const replayRows = normalizeDisplayRows(replayDisplay);
471
+ const stringifySortedRows = (rows: Array<Record<string, any>>) => rows
472
+ .map(row => JSON.stringify(row, Object.keys(row).sort()))
473
+ .sort();
474
+ const sourceSorted = stringifySortedRows(sourceRows);
475
+ const replaySorted = stringifySortedRows(replayRows);
476
+ if (sourceSorted.length === replaySorted.length) {
477
+ let mismatch = false;
478
+ for (let index = 0; index < sourceSorted.length; index += 1) {
479
+ if (sourceSorted[index] !== replaySorted[index]) {
480
+ mismatch = true;
481
+ break;
482
+ }
483
+ }
484
+ if (!mismatch) {
485
+ return [];
486
+ }
487
+ }
488
+ const alignRowsToKeys = (rows: Array<Record<string, any>>, keys: string[]) => rows.map((row) => {
489
+ const next: Record<string, any> = {};
490
+ keys.forEach((key) => {
491
+ next[key] = Object.prototype.hasOwnProperty.call(row, key) ? row[key] : null;
492
+ });
493
+ return next;
494
+ });
495
+ const allRowKeys = Array.from(new Set([
496
+ ...sourceRows.flatMap(row => Object.keys(row || {})),
497
+ ...replayRows.flatMap(row => Object.keys(row || {}))
498
+ ])).sort();
499
+ if (allRowKeys.length) {
500
+ const sourceAligned = stringifySortedRows(alignRowsToKeys(sourceRows, allRowKeys));
501
+ const replayAligned = stringifySortedRows(alignRowsToKeys(replayRows, allRowKeys));
502
+ if (sourceAligned.length === replayAligned.length) {
503
+ let alignedMismatch = false;
504
+ for (let index = 0; index < sourceAligned.length; index += 1) {
505
+ if (sourceAligned[index] !== replayAligned[index]) {
506
+ alignedMismatch = true;
507
+ break;
508
+ }
509
+ }
510
+ if (!alignedMismatch) {
511
+ return [];
512
+ }
513
+ }
514
+ }
515
+ const sourceMonthly = parseMonthlyTotalsFromDisplay(toolDisplay);
516
+ const replayMonthly = parseMonthlyTotalsFromDisplay(replayDisplay);
517
+ if (sourceMonthly && replayMonthly && !compareNumericMaps(sourceMonthly, replayMonthly, 0.05).length) {
518
+ return errors;
519
+ }
520
+ const sourceCustomerMonthly = parseCustomerMonthTotalsFromDisplay(toolDisplay);
521
+ const replayCustomerMonthly = parseCustomerMonthTotalsFromDisplay(replayDisplay);
522
+ if (sourceCustomerMonthly && replayCustomerMonthly && !compareNumericMaps(sourceCustomerMonthly, replayCustomerMonthly, 0.05).length) {
523
+ return errors;
524
+ }
525
+ if (toolColumns.join('|') !== replayColumns.join('|')) {
526
+ errors.push(`Replay columns mismatch: tool=[${toolColumns.join(',')}], replay=[${replayColumns.join(',')}].`);
527
+ }
528
+ errors.push(`Replay display mismatch: tool_result rows=${sourceRows.length}, replay rows=${replayRows.length}.`);
529
+ return errors;
530
+ }
531
+
532
+ function containsAssistantInternalError(content: string): boolean {
533
+ const text = String(content || '').toLowerCase();
534
+ if (!text) {
535
+ return false;
536
+ }
537
+ return text.includes('i ran into an internal error while preparing that response');
538
+ }
539
+
540
+ async function runReplayCase(
541
+ methodManager: any,
542
+ db: any,
543
+ idUser: string,
544
+ appId: string,
545
+ entry: CorpusPromptEntry,
546
+ index: number
547
+ ): Promise<ReplayResult> {
548
+ const id = normalizeOptionalString(entry.id) || `corpus_case_${String(index + 1).padStart(3, '0')}`;
549
+ const prompt = normalizeOptionalString(entry.prompt);
550
+ const result: ReplayResult = {
551
+ id,
552
+ prompt,
553
+ pass: false,
554
+ errors: []
555
+ };
556
+ if (!prompt) {
557
+ result.errors.push('Prompt is empty.');
558
+ return result;
559
+ }
560
+ try {
561
+ const ai = await runPrompt(methodManager, db, idUser, prompt, appId);
562
+ result.conversationId = ai.conversationId;
563
+ const message = ai.message || {};
564
+ const assistantContent = normalizeOptionalString(message?.content);
565
+ const classification = classifyAssistantRequestType(prompt);
566
+ result.classification = {
567
+ type: classification.type,
568
+ dataQuestion: classification.dataQuestion,
569
+ source: classification.source
570
+ };
571
+ if (containsAssistantInternalError(assistantContent)) {
572
+ result.errors.push('Assistant returned internal error response.');
573
+ }
574
+ let toolResult = message?.metadata?.tool_result;
575
+ let toolSource = 'metadata.tool_result';
576
+ if ((!toolResult?.input || !toolResult?.output) && classification.dataQuestion) {
577
+ const directive = extractDirectiveFromMessage(message);
578
+ if (!directive) {
579
+ result.errors.push('No tool_result found for data question and no directive was recoverable.');
580
+ }
581
+ else {
582
+ const replayMethod = directive.type === 'aggregate' ? 'aiAssistantMongoAggregate' : 'aiAssistantMongoRead';
583
+ try {
584
+ const directiveReplay = await callMethodAsUser(methodManager, idUser, replayMethod, directive.payload || {});
585
+ toolResult = buildSyntheticToolResultFromDirective(directive, directiveReplay);
586
+ toolSource = `synthetic_from_${directive.source}`;
587
+ }
588
+ catch (directiveError: any) {
589
+ result.errors.push(`Directive replay failed: ${String(directiveError?.message || directiveError || 'unknown error')}`);
590
+ }
591
+ }
592
+ }
593
+ if (toolResult?.input && toolResult?.output) {
594
+ const replayMethod = toolResult.type === 'mongo_agg' ? 'aiAssistantMongoAggregate' : 'aiAssistantMongoRead';
595
+ const replay = await callMethodAsUser(methodManager, idUser, replayMethod, toolResult.input || {});
596
+ const toolRowCount = Number(toolResult?.output?.rowCount || 0);
597
+ const replayRowCount = Array.isArray(replay?.documents)
598
+ ? replay.documents.length
599
+ : Number(replay?.display?.rowCount || 0);
600
+ const replayErrors = compareReplayDisplay(toolResult?.output?.display, replay?.display, toolRowCount, replayRowCount);
601
+ if (replayErrors.length) {
602
+ result.errors.push(...replayErrors);
603
+ }
604
+ result.tool = {
605
+ type: normalizeOptionalString(toolResult?.type),
606
+ collection: normalizeOptionalString(toolResult?.output?.collection) || normalizeOptionalString(toolResult?.input?.collection),
607
+ rowCount: toolRowCount,
608
+ total: typeof toolResult?.output?.total === 'number' ? toolResult.output.total : null,
609
+ columns: Array.isArray(toolResult?.output?.columns) ? toolResult.output.columns : [],
610
+ source: toolSource
611
+ };
612
+ }
613
+ else if (classification.dataQuestion) {
614
+ result.errors.push('Data question did not produce a usable tool_result.');
615
+ }
616
+ result.pass = result.errors.length === 0;
617
+ return result;
618
+ }
619
+ catch (error: any) {
620
+ result.errors.push(String(error?.message || error || 'Unknown error'));
621
+ result.pass = false;
622
+ return result;
623
+ }
624
+ }
625
+
626
+ async function run(): Promise<void> {
627
+ const repoRoot = process.cwd();
628
+ const defaultServerDir = path.resolve(repoRoot, '../resolveio-all/geochem/server');
629
+ const serverDir = normalizeOptionalString(process.env.AI_ASSISTANT_CORPUS_SERVER_DIR) || defaultServerDir;
630
+ const settingsPath = path.join(serverDir, normalizeOptionalString(process.env.AI_ASSISTANT_CORPUS_SETTINGS) || 'settings.local.json');
631
+ const appId = normalizeOptionalString(process.env.AI_ASSISTANT_CORPUS_APP_ID) || path.basename(path.dirname(serverDir));
632
+ const corpusPath = path.join(repoRoot, normalizeOptionalString(process.env.AI_ASSISTANT_CORPUS_PATH) || 'tmp/ai-assistant-query-corpus.json');
633
+ const outputPath = path.join(repoRoot, normalizeOptionalString(process.env.AI_ASSISTANT_CORPUS_REPLAY_OUTPUT) || 'tmp/ai-assistant-corpus-replay-e2e-output.json');
634
+ const runLimit = parseInteger(process.env.AI_ASSISTANT_CORPUS_RUN_LIMIT, 40, 1, 500);
635
+ const dryRun = parseBoolean(process.env.AI_ASSISTANT_CORPUS_DRY_RUN);
636
+ const caseFilter = normalizeOptionalString(process.env.AI_ASSISTANT_CORPUS_CASES)
637
+ .split(',')
638
+ .map(value => value.trim())
639
+ .filter(Boolean);
640
+
641
+ if (!fs.existsSync(settingsPath)) {
642
+ throw new Error(`Settings file not found: ${settingsPath}`);
643
+ }
644
+ if (!fs.existsSync(corpusPath)) {
645
+ throw new Error(`Corpus file not found: ${corpusPath}`);
646
+ }
647
+
648
+ const corpus = JSON.parse(fs.readFileSync(corpusPath, 'utf8')) as CorpusFile;
649
+ const prompts = Array.isArray(corpus?.prompts) ? corpus.prompts : [];
650
+ const selected = prompts
651
+ .filter((entry) => normalizeOptionalString(entry?.prompt))
652
+ .filter((entry) => {
653
+ if (!caseFilter.length) {
654
+ return true;
655
+ }
656
+ const id = normalizeOptionalString(entry?.id);
657
+ return !!id && caseFilter.includes(id);
658
+ })
659
+ .sort((a, b) => Number(b?.score || 0) - Number(a?.score || 0))
660
+ .slice(0, runLimit);
661
+
662
+ if (!selected.length) {
663
+ throw new Error('No corpus prompts selected.');
664
+ }
665
+
666
+ if (dryRun) {
667
+ console.log(JSON.stringify({
668
+ mode: 'dry-run',
669
+ serverDir,
670
+ settingsPath,
671
+ appId,
672
+ corpusPath,
673
+ outputPath,
674
+ runLimit,
675
+ selected: selected.map(entry => normalizeOptionalString(entry.id) || normalizeOptionalString(entry.prompt))
676
+ }, null, 2));
677
+ return;
678
+ }
679
+
680
+ applyEnvFromServerDir(serverDir);
681
+ process.env.AI_ASSISTANT_WORKSPACE_ROOT = process.env.AI_ASSISTANT_WORKSPACE_ROOT || path.resolve(serverDir, '../..');
682
+ if (!process.env.OPENAI_API_KEY) {
683
+ throw new Error('OPENAI_API_KEY is required for corpus replay E2E run.');
684
+ }
685
+
686
+ const runtimeTmpDir = path.join(serverDir, 'tmp');
687
+ const runtimeSrcDir = path.join(serverDir, 'src');
688
+ const runtimeDir = fs.existsSync(path.join(runtimeTmpDir, 'server-app.js')) ? runtimeTmpDir : runtimeSrcDir;
689
+ const clientRoutesPath = path.join(runtimeDir, 'client-routes');
690
+ if (!fs.existsSync(clientRoutesPath) && !fs.existsSync(`${clientRoutesPath}.js`)) {
691
+ throw new Error(`client-routes module not found under runtime dir: ${runtimeDir}`);
692
+ }
693
+ const { CLIENT_ROUTES } = require(clientRoutesPath);
694
+ const serverConfig = JSON.parse(fs.readFileSync(settingsPath, 'utf8'));
695
+ const envDatabase = normalizeOptionalString(process.env.DATABASE);
696
+ const envMongoUrl = normalizeOptionalString(process.env.MONGO_URL);
697
+ const envOplogUrl = normalizeOptionalString(process.env.OPLOG_URL);
698
+ if (envDatabase) {
699
+ serverConfig.DATABASE = envDatabase;
700
+ }
701
+ if (envMongoUrl) {
702
+ serverConfig.MONGO_URL = envMongoUrl;
703
+ }
704
+ if (envOplogUrl) {
705
+ serverConfig.OPLOG_URL = envOplogUrl;
706
+ }
707
+
708
+ const codexHome = process.env.CODEX_HOME || path.join(repoRoot, 'tmp', '.codex-ai-corpus');
709
+ const codexSessions = path.join(codexHome, 'sessions');
710
+ const codexZdotdir = process.env.AI_DASHBOARD_CODEX_ZDOTDIR || path.join(repoRoot, 'tmp', '.codex-zdotdir-corpus');
711
+ fs.mkdirSync(codexSessions, { recursive: true });
712
+ fs.mkdirSync(codexZdotdir, { recursive: true });
713
+ process.env.CODEX_HOME = codexHome;
714
+ process.env.AI_DASHBOARD_CODEX_ZDOTDIR = codexZdotdir;
715
+ process.env.IS_WORKERS_ENABLED = 'false';
716
+ process.env.IS_WORKER_INSTANCE = 'false';
717
+ process.env.WORKER_INDEX = '';
718
+ process.env.NODE_APP_INSTANCE = process.env.NODE_APP_INSTANCE || '8';
719
+ process.env.AI_ASSISTANT_WORKER_DEBUG = process.env.AI_ASSISTANT_WORKER_DEBUG || 'false';
720
+
721
+ await ResolveIOServer.create(serverConfig, CLIENT_ROUTES(), appId.toUpperCase(), runtimeDir, false, false);
722
+ const mainServer = ResolveIOServer.getMainServer();
723
+ const methodManager = mainServer?.getMethodManager();
724
+ if (!methodManager) {
725
+ throw new Error('MethodManager unavailable after ResolveIOServer initialization.');
726
+ }
727
+ await methodManager.waitUntilReady(120000);
728
+
729
+ const dbName = normalizeOptionalString(serverConfig.DATABASE) || 'resolveio';
730
+ const db = ResolveIOServer.getMongoConnection().db(dbName);
731
+ const idUser = normalizeOptionalString(process.env.AI_ASSISTANT_CORPUS_USER_ID) || await findSuperAdminUserId(db);
732
+ const now = new Date();
733
+
734
+ const results: ReplayResult[] = [];
735
+ for (let index = 0; index < selected.length; index += 1) {
736
+ const entry = selected[index];
737
+ const replayResult = await runReplayCase(methodManager, db, idUser, appId, entry, index);
738
+ results.push(replayResult);
739
+ const status = replayResult.pass ? 'PASS' : 'FAIL';
740
+ const error = replayResult.errors.length ? `error=${replayResult.errors[0]}` : '';
741
+ console.log(`${status} ${replayResult.id} ${error}`.trim());
742
+ }
743
+
744
+ const passed = results.filter((result) => result.pass).length;
745
+ const failed = results.length - passed;
746
+ const output = {
747
+ now: now.toISOString(),
748
+ serverDir,
749
+ settingsPath,
750
+ appId,
751
+ database: dbName,
752
+ corpusPath,
753
+ total: results.length,
754
+ passed,
755
+ failed,
756
+ results
757
+ };
758
+ fs.mkdirSync(path.dirname(outputPath), { recursive: true });
759
+ fs.writeFileSync(outputPath, JSON.stringify(output, null, 2));
760
+ console.log(`ai assistant corpus replay e2e: ${passed}/${results.length} passed`);
761
+ console.log(`wrote ${outputPath}`);
762
+ if (failed > 0) {
763
+ process.exitCode = 1;
764
+ }
765
+ }
766
+
767
+ run()
768
+ .then(() => {
769
+ process.exit(process.exitCode ?? 0);
770
+ })
771
+ .catch((error) => {
772
+ console.error(error);
773
+ process.exit(1);
774
+ });