@cartanova/qgrid-cli 2.10.9 → 2.11.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 (318) hide show
  1. package/bundle/dist/_virtual/_rolldown/runtime.js +1 -10
  2. package/bundle/dist/application/monit/log-buffer.js +12 -6
  3. package/bundle/dist/application/monit/monit.frame.js +11 -3
  4. package/bundle/dist/application/monit/monit.types.js +1 -1
  5. package/bundle/dist/application/qgrid/conv-routing.js +9 -6
  6. package/bundle/dist/application/qgrid/expired-token-reminder.js +2 -2
  7. package/bundle/dist/application/qgrid/oauth.js +31 -4
  8. package/bundle/dist/application/qgrid/qgrid-image-generation.js +1 -1
  9. package/bundle/dist/application/qgrid/qgrid-response-format.js +22 -20
  10. package/bundle/dist/application/qgrid/qgrid-run-lifecycle.js +43 -34
  11. package/bundle/dist/application/qgrid/qgrid.dispatcher.js +128 -93
  12. package/bundle/dist/application/qgrid/qgrid.frame.js +930 -49
  13. package/bundle/dist/application/qgrid/qgrid.types.js +212 -5
  14. package/bundle/dist/application/qgrid/schema-prompt.js +75 -48
  15. package/bundle/dist/application/qgrid/slack-user-map.js +1 -1
  16. package/bundle/dist/application/qgrid/token-death.js +1 -1
  17. package/bundle/dist/application/qgrid/token-subscriber.js +83 -30
  18. package/bundle/dist/application/qgrid/token-trigger-setup.js +1 -1
  19. package/bundle/dist/application/qgrid/token-window-keepalive.js +8 -6
  20. package/bundle/dist/application/qgrid/tool-emulation-schema.js +13 -13
  21. package/bundle/dist/application/qgrid/tool-emulation.js +19 -15
  22. package/bundle/dist/application/request-log/json-schema-type-text.js +29 -12
  23. package/bundle/dist/application/request-log/request-log.model.js +83 -69
  24. package/bundle/dist/application/request-log/request-log.types.js +8 -2
  25. package/bundle/dist/application/request-log/zod-code-format.js +1 -1
  26. package/bundle/dist/application/request-log-step/request-log-step.model.js +1 -1
  27. package/bundle/dist/application/request-log-step/request-log-step.types.js +1 -1
  28. package/bundle/dist/application/setting/setting.constant.js +1 -1
  29. package/bundle/dist/application/setting/setting.model.js +2 -2
  30. package/bundle/dist/application/setting/setting.store.js +2 -2
  31. package/bundle/dist/application/setting/setting.types.js +1 -1
  32. package/bundle/dist/application/sonamu.generated.js +40 -16
  33. package/bundle/dist/application/sonamu.generated.sso.js +2 -1
  34. package/bundle/dist/application/token/token.model.js +26 -9
  35. package/bundle/dist/application/token/token.types.js +20 -3
  36. package/bundle/dist/i18n/en.js +15 -1
  37. package/bundle/dist/i18n/ko.js +15 -1
  38. package/bundle/dist/i18n/sd.generated.js +2 -1
  39. package/bundle/dist/migrations/20260807133553_manual__backfill_request_log_cost.js +8 -6
  40. package/bundle/dist/migrations/20261018215031_alter_request_logs_add1_alter1.js +15 -0
  41. package/bundle/dist/server-bootstrap.js +4 -2
  42. package/bundle/dist/server-error-handler.js +1 -1
  43. package/bundle/dist/sonamu.config.js +37 -8
  44. package/bundle/dist/startup-migrations.js +17 -7
  45. package/bundle/dist/testing/global.js +1 -1
  46. package/bundle/dist/testing/schema-bench.js +0 -0
  47. package/bundle/dist/testing/test-database-name.js +1 -1
  48. package/bundle/dist/utils/providers/anthropic/anthropic-constants.js +1 -1
  49. package/bundle/dist/utils/providers/anthropic/anthropic-dispatcher.js +11 -5
  50. package/bundle/dist/utils/providers/anthropic/anthropic-quota.js +4 -4
  51. package/bundle/dist/utils/providers/anthropic/anthropic-thinking.js +1 -1
  52. package/bundle/dist/utils/providers/anthropic/claude-session.js +20 -19
  53. package/bundle/dist/utils/providers/anthropic/fence-strip.js +1 -1
  54. package/bundle/dist/utils/providers/anthropic/stream-json-adapter.js +49 -23
  55. package/bundle/dist/utils/providers/common/credentials.js +5 -1
  56. package/bundle/dist/utils/providers/common/effort.js +3 -3
  57. package/bundle/dist/utils/providers/common/model-cost.js +69 -14
  58. package/bundle/dist/utils/providers/common/provider-types.js +29 -1
  59. package/bundle/dist/utils/providers/common/schema-validation.js +78 -40
  60. package/bundle/dist/utils/providers/common/smooth-weighted-round-robin.js +1 -1
  61. package/bundle/dist/utils/providers/common/strictifier.js +62 -43
  62. package/bundle/dist/utils/providers/common/thinking.js +3 -2
  63. package/bundle/dist/utils/providers/common/ttft.js +1 -1
  64. package/bundle/dist/utils/providers/grok/grok-backend-protocol.js +427 -0
  65. package/bundle/dist/utils/providers/grok/grok-constants.js +55 -0
  66. package/bundle/dist/utils/providers/grok/grok-direct-client.js +196 -0
  67. package/bundle/dist/utils/providers/grok/grok-dispatcher.js +1313 -0
  68. package/bundle/dist/utils/providers/grok/grok-headers.js +118 -0
  69. package/bundle/dist/utils/providers/grok/grok-media-client.js +420 -0
  70. package/bundle/dist/utils/providers/grok/grok-models.js +114 -0
  71. package/bundle/dist/utils/providers/grok/grok-oauth.js +455 -0
  72. package/bundle/dist/utils/providers/grok/grok-quota.js +119 -0
  73. package/bundle/dist/utils/providers/grok/grok-refresh.js +192 -0
  74. package/bundle/dist/utils/providers/grok/grok-types.js +186 -0
  75. package/bundle/dist/utils/providers/grok/grok-voice-client.js +199 -0
  76. package/bundle/dist/utils/providers/grok/index.js +11 -0
  77. package/bundle/dist/utils/providers/openai/openai-backend-protocol.js +111 -83
  78. package/bundle/dist/utils/providers/openai/openai-callback-relay.js +3 -2
  79. package/bundle/dist/utils/providers/openai/openai-constants.js +1 -1
  80. package/bundle/dist/utils/providers/openai/openai-direct-client.js +23 -7
  81. package/bundle/dist/utils/providers/openai/openai-dispatcher.js +143 -106
  82. package/bundle/dist/utils/providers/openai/openai-image-generation.js +48 -33
  83. package/bundle/dist/utils/providers/openai/openai-oauth.js +28 -13
  84. package/bundle/dist/utils/providers/openai/openai-quota.js +38 -27
  85. package/bundle/dist/utils/providers/openai/openai-refresh.js +17 -9
  86. package/bundle/dist/utils/providers/openai/openai-sse.js +1 -1
  87. package/bundle/dist/utils/providers/openai/openai-transport-config.js +1 -1
  88. package/bundle/dist/utils/quiet-hours.js +1 -1
  89. package/bundle/dist/utils/slack-notify.js +14 -8
  90. package/bundle/dist/utils/subset-loaders.js +4 -5
  91. package/bundle/src/application/monit/log-buffer.ts +23 -9
  92. package/bundle/src/application/monit/monit.frame.ts +22 -5
  93. package/bundle/src/application/monit/monit.types.ts +6 -0
  94. package/bundle/src/application/qgrid/conv-routing.test.ts +76 -4
  95. package/bundle/src/application/qgrid/conv-routing.ts +35 -9
  96. package/bundle/src/application/qgrid/expired-token-reminder.ts +9 -1
  97. package/bundle/src/application/qgrid/oauth.ts +51 -15
  98. package/bundle/src/application/qgrid/qgrid-image-generation.ts +9 -0
  99. package/bundle/src/application/qgrid/qgrid-response-format.ts +50 -25
  100. package/bundle/src/application/qgrid/qgrid-run-lifecycle.test.ts +33 -0
  101. package/bundle/src/application/qgrid/qgrid-run-lifecycle.ts +87 -40
  102. package/bundle/src/application/qgrid/qgrid.dispatcher.test.ts +97 -0
  103. package/bundle/src/application/qgrid/qgrid.dispatcher.ts +274 -126
  104. package/bundle/src/application/qgrid/qgrid.frame.test.ts +1013 -3
  105. package/bundle/src/application/qgrid/qgrid.frame.ts +1415 -60
  106. package/bundle/src/application/qgrid/qgrid.types.ts +335 -0
  107. package/bundle/src/application/qgrid/schema-prompt.ts +105 -41
  108. package/bundle/src/application/qgrid/slack-user-map.ts +5 -0
  109. package/bundle/src/application/qgrid/token-death.ts +4 -0
  110. package/bundle/src/application/qgrid/token-subscriber.test.ts +21 -19
  111. package/bundle/src/application/qgrid/token-subscriber.ts +186 -53
  112. package/bundle/src/application/qgrid/token-trigger-setup.ts +2 -0
  113. package/bundle/src/application/qgrid/token-window-keepalive.ts +49 -6
  114. package/bundle/src/application/qgrid/tool-emulation-schema.ts +33 -29
  115. package/bundle/src/application/qgrid/tool-emulation.ts +52 -27
  116. package/bundle/src/application/request-log/json-schema-type-text.test.ts +5 -5
  117. package/bundle/src/application/request-log/json-schema-type-text.ts +81 -26
  118. package/bundle/src/application/request-log/request-log.entity.json +8 -0
  119. package/bundle/src/application/request-log/request-log.model.test.ts +111 -4
  120. package/bundle/src/application/request-log/request-log.model.ts +279 -145
  121. package/bundle/src/application/request-log/request-log.types.ts +17 -0
  122. package/bundle/src/application/request-log/zod-code-format.ts +11 -0
  123. package/bundle/src/application/request-log-step/request-log-step.model.ts +1 -0
  124. package/bundle/src/application/request-log-step/request-log-step.types.ts +2 -0
  125. package/bundle/src/application/setting/setting.constant.ts +9 -0
  126. package/bundle/src/application/setting/setting.model.ts +12 -2
  127. package/bundle/src/application/setting/setting.store.ts +5 -1
  128. package/bundle/src/application/setting/setting.types.ts +8 -0
  129. package/bundle/src/application/sonamu.generated.http +135 -0
  130. package/bundle/src/application/sonamu.generated.sso.ts +3 -0
  131. package/bundle/src/application/sonamu.generated.ts +29 -0
  132. package/bundle/src/application/token/token.identity.test.ts +20 -0
  133. package/bundle/src/application/token/token.model.ts +66 -7
  134. package/bundle/src/application/token/token.types.ts +24 -1
  135. package/bundle/src/i18n/en.ts +19 -0
  136. package/bundle/src/i18n/ko.ts +21 -0
  137. package/bundle/src/i18n/sd.generated.ts +24 -2
  138. package/bundle/src/migrations/20260807133553_manual__backfill_request_log_cost.ts +16 -8
  139. package/bundle/src/migrations/20261018215031_alter_request_logs_add1_alter1.ts +15 -0
  140. package/bundle/src/server-bootstrap.ts +4 -2
  141. package/bundle/src/server-error-handler.ts +1 -0
  142. package/bundle/src/sonamu.config.ts +69 -7
  143. package/bundle/src/startup-migrations.ts +27 -9
  144. package/bundle/src/testing/global.ts +20 -0
  145. package/bundle/src/testing/schema-bench.ts +105 -30
  146. package/bundle/src/testing/test-database-name.ts +2 -0
  147. package/bundle/src/utils/providers/anthropic/anthropic-constants.ts +8 -0
  148. package/bundle/src/utils/providers/anthropic/anthropic-dispatcher.ts +41 -6
  149. package/bundle/src/utils/providers/anthropic/anthropic-quota.ts +7 -3
  150. package/bundle/src/utils/providers/anthropic/anthropic-thinking.ts +6 -0
  151. package/bundle/src/utils/providers/anthropic/claude-session.ts +58 -24
  152. package/bundle/src/utils/providers/anthropic/fence-strip.ts +11 -0
  153. package/bundle/src/utils/providers/anthropic/stream-json-adapter.ts +110 -45
  154. package/bundle/src/utils/providers/common/credentials.ts +8 -0
  155. package/bundle/src/utils/providers/common/effort.ts +9 -2
  156. package/bundle/src/utils/providers/common/model-cost.test.ts +48 -1
  157. package/bundle/src/utils/providers/common/model-cost.ts +259 -158
  158. package/bundle/src/utils/providers/common/provider-dispatcher.ts +98 -2
  159. package/bundle/src/utils/providers/common/provider-types.ts +46 -3
  160. package/bundle/src/utils/providers/common/schema-validation.test.ts +5 -1
  161. package/bundle/src/utils/providers/common/schema-validation.ts +124 -56
  162. package/bundle/src/utils/providers/common/smooth-weighted-round-robin.ts +4 -0
  163. package/bundle/src/utils/providers/common/strictifier.ts +185 -59
  164. package/bundle/src/utils/providers/common/thinking.ts +2 -2
  165. package/bundle/src/utils/providers/common/ttft.ts +4 -2
  166. package/bundle/src/utils/providers/grok/__fixtures__/golden-responses-1.0.60.json +164 -0
  167. package/bundle/src/utils/providers/grok/grok-backend-protocol.test.ts +325 -0
  168. package/bundle/src/utils/providers/grok/grok-backend-protocol.ts +721 -0
  169. package/bundle/src/utils/providers/grok/grok-constants.ts +105 -0
  170. package/bundle/src/utils/providers/grok/grok-direct-client.test.ts +179 -0
  171. package/bundle/src/utils/providers/grok/grok-direct-client.ts +313 -0
  172. package/bundle/src/utils/providers/grok/grok-dispatcher.test.ts +1395 -0
  173. package/bundle/src/utils/providers/grok/grok-dispatcher.ts +2105 -0
  174. package/bundle/src/utils/providers/grok/grok-headers.test.ts +149 -0
  175. package/bundle/src/utils/providers/grok/grok-headers.ts +199 -0
  176. package/bundle/src/utils/providers/grok/grok-media-client.test.ts +446 -0
  177. package/bundle/src/utils/providers/grok/grok-media-client.ts +703 -0
  178. package/bundle/src/utils/providers/grok/grok-models.test.ts +96 -0
  179. package/bundle/src/utils/providers/grok/grok-models.ts +161 -0
  180. package/bundle/src/utils/providers/grok/grok-oauth.test.ts +406 -0
  181. package/bundle/src/utils/providers/grok/grok-oauth.ts +771 -0
  182. package/bundle/src/utils/providers/grok/grok-quota.test.ts +142 -0
  183. package/bundle/src/utils/providers/grok/grok-quota.ts +198 -0
  184. package/bundle/src/utils/providers/grok/grok-refresh.test.ts +239 -0
  185. package/bundle/src/utils/providers/grok/grok-refresh.ts +325 -0
  186. package/bundle/src/utils/providers/grok/grok-types.test.ts +252 -0
  187. package/bundle/src/utils/providers/grok/grok-types.ts +374 -0
  188. package/bundle/src/utils/providers/grok/grok-voice-client.test.ts +321 -0
  189. package/bundle/src/utils/providers/grok/grok-voice-client.ts +284 -0
  190. package/bundle/src/utils/providers/grok/index.ts +20 -0
  191. package/bundle/src/utils/providers/openai/openai-backend-protocol.ts +221 -137
  192. package/bundle/src/utils/providers/openai/openai-callback-relay.ts +12 -1
  193. package/bundle/src/utils/providers/openai/openai-constants.ts +2 -0
  194. package/bundle/src/utils/providers/openai/openai-direct-client.ts +111 -21
  195. package/bundle/src/utils/providers/openai/openai-dispatcher.ts +322 -169
  196. package/bundle/src/utils/providers/openai/openai-image-generation.ts +116 -36
  197. package/bundle/src/utils/providers/openai/openai-oauth.ts +48 -20
  198. package/bundle/src/utils/providers/openai/openai-quota.ts +77 -46
  199. package/bundle/src/utils/providers/openai/openai-refresh.ts +42 -18
  200. package/bundle/src/utils/providers/openai/openai-sse.ts +27 -3
  201. package/bundle/src/utils/providers/openai/openai-transport-config.ts +2 -0
  202. package/bundle/src/utils/quiet-hours.ts +12 -1
  203. package/bundle/src/utils/slack-notify.ts +44 -13
  204. package/bundle/src/utils/subset-loaders.ts +7 -7
  205. package/bundle/web-dist/client/assets/clsx-5XM_pHvN.js +1 -0
  206. package/bundle/web-dist/client/assets/index-BA7uQ-6c.js +31 -0
  207. package/bundle/web-dist/client/assets/index-Be2qCZmI.css +1 -0
  208. package/bundle/web-dist/client/assets/logs-C47OJGEI.js +1 -0
  209. package/bundle/web-dist/client/assets/monit-BS9no0dU.js +4 -0
  210. package/bundle/web-dist/client/assets/plus-sdACTfH0.js +1 -0
  211. package/bundle/web-dist/client/assets/refresh-cw-CY8o_1cT.js +1 -0
  212. package/bundle/web-dist/client/assets/request-model-BRtFuZvj.js +1 -0
  213. package/bundle/web-dist/client/assets/routes-kqgkUxE8.js +5 -0
  214. package/bundle/web-dist/client/assets/{services.generated-BsieU37H.js → services.generated-CefiDXEv.js} +5 -5
  215. package/bundle/web-dist/client/assets/settings-DNDvFGSw.js +1 -0
  216. package/bundle/web-dist/client/assets/show-u8Np69q3.js +2 -0
  217. package/bundle/web-dist/client/assets/tokens-QvP410NW.js +1 -0
  218. package/bundle/web-dist/client/assets/total-cost-MnfKU8IN.js +1 -0
  219. package/bundle/web-dist/client/assets/use-oauth-login-flow-Bzdh28Ws.js +1 -0
  220. package/bundle/web-dist/client/assets/use-update-token-mutation-CfJKaxmR.js +1 -0
  221. package/bundle/web-dist/client/assets/vendor-react-CUFFrVN9.js +244 -0
  222. package/bundle/web-dist/client/assets/vendor-tanstack-Bf_jag9G.js +1 -0
  223. package/bundle/web-dist/client/index.html +6 -6
  224. package/bundle/web-dist/server/assets/clsx-D_N5PN_2.js +16 -0
  225. package/bundle/web-dist/server/assets/{lazyRouteComponent-Dtd0NR4r.js → lazyRouteComponent-D8iTIHyn.js} +129 -2
  226. package/bundle/web-dist/server/assets/logs-B3OTd9hy.js +825 -0
  227. package/bundle/web-dist/server/assets/{monit-DvzribSE.js → monit-B2hqorPe.js} +385 -126
  228. package/bundle/web-dist/server/assets/plus-DwG7h9kq.js +28 -0
  229. package/bundle/web-dist/server/assets/{react-dom-B4a6-uuR.js → react-dom-BIYQzBqG.js} +2 -129
  230. package/bundle/web-dist/server/assets/refresh-cw-mMBkwOq0.js +44 -0
  231. package/bundle/web-dist/server/assets/{request-model-CbqfnQOJ.js → request-model-I6OdODSH.js} +15 -6
  232. package/bundle/web-dist/server/assets/{routes-BAPWTizT.js → routes-B95YlUv2.js} +760 -213
  233. package/bundle/web-dist/server/assets/{services.generated-CEbGjsI0.js → services.generated-DQATJ6qf.js} +12821 -12194
  234. package/bundle/web-dist/server/assets/settings-C3gbGk0m.js +830 -0
  235. package/bundle/web-dist/server/assets/{show-CxVZTAdv.js → show-Bxaj3rhH.js} +1355 -419
  236. package/bundle/web-dist/server/assets/tokens-CZjH3cB7.js +1038 -0
  237. package/bundle/web-dist/server/assets/total-cost-fTE9Xy82.js +18 -0
  238. package/bundle/web-dist/server/assets/use-oauth-login-flow-CKDHgc3U.js +2379 -0
  239. package/bundle/web-dist/server/assets/{use-update-token-mutation-CfYmk_4_.js → use-update-token-mutation-BEbgOzaa.js} +1 -1
  240. package/bundle/web-dist/server/entry-server.generated.js +4303 -22810
  241. package/dist/cli.js +9 -9
  242. package/package.json +4 -11
  243. package/postinstall.mjs +12 -0
  244. package/skills/qgrid/SKILL.md +1 -0
  245. package/skills/qgrid/references/cli-env-and-server-boot.md +4 -1
  246. package/skills/qgrid/references/decision-rationale.md +24 -1
  247. package/skills/qgrid/references/grok-runtime.md +89 -0
  248. package/skills/qgrid/references/provider-runtime-differences.md +30 -29
  249. package/skills/qgrid/references/repo-map.md +10 -0
  250. package/skills/qgrid/references/request-log-run-lifecycle.md +1 -1
  251. package/skills/qgrid/references/sonamu-api-web-flow.md +1 -1
  252. package/skills/qgrid/references/token-auth-quota-lifecycle.md +56 -3
  253. package/bundle/dist/node_modules/.pnpm/@jridgewell_sourcemap-codec@1.5.5/node_modules/@jridgewell/sourcemap-codec/dist/sourcemap-codec.js +0 -406
  254. package/bundle/dist/node_modules/.pnpm/@vitest_expect@4.1.10/node_modules/@vitest/expect/dist/index.js +0 -1507
  255. package/bundle/dist/node_modules/.pnpm/@vitest_pretty-format@4.1.10/node_modules/@vitest/pretty-format/dist/index.js +0 -887
  256. package/bundle/dist/node_modules/.pnpm/@vitest_runner@4.1.10/node_modules/@vitest/runner/dist/chunk-artifact.js +0 -2756
  257. package/bundle/dist/node_modules/.pnpm/@vitest_runner@4.1.10/node_modules/@vitest/runner/dist/index.js +0 -8
  258. package/bundle/dist/node_modules/.pnpm/@vitest_runner@4.1.10/node_modules/@vitest/runner/dist/utils.js +0 -8
  259. package/bundle/dist/node_modules/.pnpm/@vitest_snapshot@4.1.10/node_modules/@vitest/snapshot/dist/index.js +0 -922
  260. package/bundle/dist/node_modules/.pnpm/@vitest_spy@4.1.10/node_modules/@vitest/spy/dist/index.js +0 -386
  261. package/bundle/dist/node_modules/.pnpm/@vitest_utils@4.1.10/node_modules/@vitest/utils/dist/chunk-pathe.M-eThtNZ.js +0 -121
  262. package/bundle/dist/node_modules/.pnpm/@vitest_utils@4.1.10/node_modules/@vitest/utils/dist/constants.js +0 -51
  263. package/bundle/dist/node_modules/.pnpm/@vitest_utils@4.1.10/node_modules/@vitest/utils/dist/diff.js +0 -1317
  264. package/bundle/dist/node_modules/.pnpm/@vitest_utils@4.1.10/node_modules/@vitest/utils/dist/display.js +0 -561
  265. package/bundle/dist/node_modules/.pnpm/@vitest_utils@4.1.10/node_modules/@vitest/utils/dist/error.js +0 -40
  266. package/bundle/dist/node_modules/.pnpm/@vitest_utils@4.1.10/node_modules/@vitest/utils/dist/helpers.js +0 -272
  267. package/bundle/dist/node_modules/.pnpm/@vitest_utils@4.1.10/node_modules/@vitest/utils/dist/offset.js +0 -27
  268. package/bundle/dist/node_modules/.pnpm/@vitest_utils@4.1.10/node_modules/@vitest/utils/dist/serialize.js +0 -77
  269. package/bundle/dist/node_modules/.pnpm/@vitest_utils@4.1.10/node_modules/@vitest/utils/dist/source-map.js +0 -381
  270. package/bundle/dist/node_modules/.pnpm/@vitest_utils@4.1.10/node_modules/@vitest/utils/dist/timers.js +0 -51
  271. package/bundle/dist/node_modules/.pnpm/chai@6.2.2/node_modules/chai/index.js +0 -2986
  272. package/bundle/dist/node_modules/.pnpm/expect-type@1.3.0/node_modules/expect-type/dist/branding.js +0 -10
  273. package/bundle/dist/node_modules/.pnpm/expect-type@1.3.0/node_modules/expect-type/dist/index.js +0 -109
  274. package/bundle/dist/node_modules/.pnpm/expect-type@1.3.0/node_modules/expect-type/dist/messages.js +0 -10
  275. package/bundle/dist/node_modules/.pnpm/expect-type@1.3.0/node_modules/expect-type/dist/overloads.js +0 -10
  276. package/bundle/dist/node_modules/.pnpm/expect-type@1.3.0/node_modules/expect-type/dist/utils.js +0 -10
  277. package/bundle/dist/node_modules/.pnpm/magic-string@0.30.21/node_modules/magic-string/dist/magic-string.es.js +0 -1126
  278. package/bundle/dist/node_modules/.pnpm/pathe@2.0.3/node_modules/pathe/dist/index.js +0 -21
  279. package/bundle/dist/node_modules/.pnpm/pathe@2.0.3/node_modules/pathe/dist/shared/pathe.M-eThtNZ.js +0 -432
  280. package/bundle/dist/node_modules/.pnpm/tinybench@2.9.0/node_modules/tinybench/dist/index.js +0 -517
  281. package/bundle/dist/node_modules/.pnpm/tinyrainbow@3.1.0/node_modules/tinyrainbow/dist/index.js +0 -101
  282. package/bundle/dist/node_modules/.pnpm/vite@8.0.3_@emnapi_core@1.11.2_@emnapi_runtime@1.11.2_@types_node@25.0.7_esbuild@0.27.4_5b35fc1fb85d2af4d105e0d74f940f50/node_modules/vite/dist/node/module-runner.js +0 -1265
  283. package/bundle/dist/node_modules/.pnpm/vitest@4.1.10_@opentelemetry_api@1.9.0_@types_node@25.0.7_@vitest_coverage-v8@4.1.10_vi_a1977b93af7bb69308bcb1dbab39b618/node_modules/vitest/dist/chunks/_commonjsHelpers.D26ty3Ew.js +0 -9
  284. package/bundle/dist/node_modules/.pnpm/vitest@4.1.10_@opentelemetry_api@1.9.0_@types_node@25.0.7_@vitest_coverage-v8@4.1.10_vi_a1977b93af7bb69308bcb1dbab39b618/node_modules/vitest/dist/chunks/benchmark.CX_oY03V.js +0 -41
  285. package/bundle/dist/node_modules/.pnpm/vitest@4.1.10_@opentelemetry_api@1.9.0_@types_node@25.0.7_@vitest_coverage-v8@4.1.10_vi_a1977b93af7bb69308bcb1dbab39b618/node_modules/vitest/dist/chunks/evaluatedModules.Dg1zASAC.js +0 -19
  286. package/bundle/dist/node_modules/.pnpm/vitest@4.1.10_@opentelemetry_api@1.9.0_@types_node@25.0.7_@vitest_coverage-v8@4.1.10_vi_a1977b93af7bb69308bcb1dbab39b618/node_modules/vitest/dist/chunks/index.Chj8NDwU.js +0 -202
  287. package/bundle/dist/node_modules/.pnpm/vitest@4.1.10_@opentelemetry_api@1.9.0_@types_node@25.0.7_@vitest_coverage-v8@4.1.10_vi_a1977b93af7bb69308bcb1dbab39b618/node_modules/vitest/dist/chunks/index.DdgEv5B1.js +0 -46
  288. package/bundle/dist/node_modules/.pnpm/vitest@4.1.10_@opentelemetry_api@1.9.0_@types_node@25.0.7_@vitest_coverage-v8@4.1.10_vi_a1977b93af7bb69308bcb1dbab39b618/node_modules/vitest/dist/chunks/rpc.MzXet3jl.js +0 -119
  289. package/bundle/dist/node_modules/.pnpm/vitest@4.1.10_@opentelemetry_api@1.9.0_@types_node@25.0.7_@vitest_coverage-v8@4.1.10_vi_a1977b93af7bb69308bcb1dbab39b618/node_modules/vitest/dist/chunks/test.DNmyFkvJ.js +0 -3044
  290. package/bundle/dist/node_modules/.pnpm/vitest@4.1.10_@opentelemetry_api@1.9.0_@types_node@25.0.7_@vitest_coverage-v8@4.1.10_vi_a1977b93af7bb69308bcb1dbab39b618/node_modules/vitest/dist/chunks/utils.BX5Fg8C4.js +0 -59
  291. package/bundle/dist/node_modules/.pnpm/vitest@4.1.10_@opentelemetry_api@1.9.0_@types_node@25.0.7_@vitest_coverage-v8@4.1.10_vi_a1977b93af7bb69308bcb1dbab39b618/node_modules/vitest/dist/index.js +0 -28
  292. package/bundle/dist/testing/setup-mocks.js +0 -16
  293. package/bundle/src/testing/setup-mocks.ts +0 -44
  294. package/bundle/web-dist/client/assets/index-Bw2s88Ot.css +0 -1
  295. package/bundle/web-dist/client/assets/index-CrXKu_J8.js +0 -106
  296. package/bundle/web-dist/client/assets/logs-B2SmWJXA.js +0 -1
  297. package/bundle/web-dist/client/assets/monit-D-JwXXoA.js +0 -1
  298. package/bundle/web-dist/client/assets/plus-B62CuqT8.js +0 -1
  299. package/bundle/web-dist/client/assets/refresh-cw-NNcU0Cmq.js +0 -1
  300. package/bundle/web-dist/client/assets/request-model-CojtinqK.js +0 -1
  301. package/bundle/web-dist/client/assets/routes-C5r4gTvY.js +0 -5
  302. package/bundle/web-dist/client/assets/settings-D3tDSAck.js +0 -1
  303. package/bundle/web-dist/client/assets/show-Cah_kUKC.js +0 -2
  304. package/bundle/web-dist/client/assets/tokens-DU2Iyxxd.js +0 -1
  305. package/bundle/web-dist/client/assets/use-oauth-login-flow-D0UaR9_e.js +0 -1
  306. package/bundle/web-dist/client/assets/use-update-token-mutation-DAq0F8p-.js +0 -1
  307. package/bundle/web-dist/client/assets/vendor-react-DH4kUfK2.js +0 -9
  308. package/bundle/web-dist/client/assets/vendor-tanstack-DJRQAbrY.js +0 -1
  309. package/bundle/web-dist/server/assets/logs-l91avYif.js +0 -509
  310. package/bundle/web-dist/server/assets/plus-KZrECewT.js +0 -19
  311. package/bundle/web-dist/server/assets/refresh-cw-BND93JrF.js +0 -23
  312. package/bundle/web-dist/server/assets/settings-BZR5HSAL.js +0 -461
  313. package/bundle/web-dist/server/assets/tokens-D1hb4eKk.js +0 -448
  314. package/bundle/web-dist/server/assets/use-oauth-login-flow-Cvdy0zF8.js +0 -178
  315. package/dist/cli.d.ts +0 -10
  316. /package/bundle/web-dist/client/assets/{cost-DH2jZbrw.js → cost-DB3HbU7T.js} +0 -0
  317. /package/bundle/web-dist/client/assets/{preload-helper-ca-nBW7U.js → preload-helper-DWTEM3RW.js} +0 -0
  318. /package/bundle/web-dist/server/assets/{cost-eEHeTRT5.js → cost-BC9yzyA9.js} +0 -0
@@ -1,4 +1,5 @@
1
1
  import { getLogger } from "@logtape/logtape";
2
+ import { z } from "zod";
2
3
 
3
4
  import { RequestLogModel } from "../request-log/request-log.model";
4
5
  import {
@@ -7,39 +8,57 @@ import {
7
8
  } from "./qgrid-image-generation";
8
9
  import {
9
10
  buildImageGenerationToolSteps,
11
+ extractInputImagesForToolArgs,
10
12
  formatResponseForLog,
11
13
  getImageParts,
12
14
  } from "./qgrid-response-format";
13
15
  import { type QgridRunContext, type QueryInput, type QueryOutput } from "./qgrid.types";
16
+ import { composeSystemWithSchemaContract } from "./schema-prompt";
14
17
 
15
18
  const logger = getLogger(["qgrid", "run-lifecycle"]);
16
19
  const STALE_RUN_THRESHOLD_MS = 30 * 60 * 1000;
17
20
  const STALE_CLEANUP_INTERVAL_MS = 60 * 1000;
18
21
  let staleCleanupInFlight: Promise<void> | undefined;
19
22
  let lastStaleCleanupStartedAt = 0;
23
+
20
24
  function withProviderPrefix(
21
25
  routeModel: string | undefined,
22
26
  model: string | undefined,
23
27
  ): string | undefined {
24
28
  if (!model) return undefined;
29
+
25
30
  if (model.includes("/")) return model;
26
31
  const slash = routeModel?.indexOf("/") ?? -1;
27
32
  const provider = slash > 0 ? routeModel?.slice(0, slash) : undefined;
33
+
28
34
  return provider ? `${provider}/${model}` : model;
29
35
  }
30
36
 
31
37
  /**
32
38
  * history는 원본 그대로 저장하기보다는, run 분석에 필요한 user/assistant 정보만 필터링해서 저장
33
39
  */
34
- function filterHistoryForStorage(rawHistory: string | undefined): unknown {
40
+ // Kept items are stored as sent; only the type/role that select them are decoded.
41
+ const StoredHistoryMessage = z.looseObject({
42
+ type: z.literal("message"),
43
+ role: z.enum(["user", "assistant"]),
44
+ });
45
+
46
+ type StoredHistoryMessage = z.infer<typeof StoredHistoryMessage>;
47
+
48
+ function filterHistoryForStorage(
49
+ rawHistory: string | undefined,
50
+ ): StoredHistoryMessage[] | undefined {
35
51
  if (!rawHistory) return undefined;
52
+
36
53
  try {
37
- const items = JSON.parse(rawHistory) as unknown[];
38
- const filtered = items.filter((item) => {
39
- if (!item || typeof item !== "object") return false;
40
- const record = item as Record<string, unknown>;
41
- return record.type === "message" && (record.role === "user" || record.role === "assistant");
54
+ const items = z.array(z.unknown()).parse(JSON.parse(rawHistory));
55
+
56
+ const filtered = items.flatMap((item) => {
57
+ const message = StoredHistoryMessage.safeParse(item);
58
+
59
+ return message.success ? [message.data] : [];
42
60
  });
61
+
43
62
  return filtered.length > 0 ? filtered : undefined;
44
63
  } catch {
45
64
  return undefined;
@@ -49,6 +68,7 @@ function filterHistoryForStorage(rawHistory: string | undefined): unknown {
49
68
  function isParseableJson(text: string): boolean {
50
69
  try {
51
70
  JSON.parse(text);
71
+
52
72
  return true;
53
73
  } catch {
54
74
  return false;
@@ -84,14 +104,18 @@ export async function beforeQuery(args: QueryInput): Promise<{
84
104
  await cleanupStaleRuns();
85
105
  } else {
86
106
  await cleanupStaleRuns();
107
+ const inputImages = extractInputImagesForToolArgs(args);
87
108
  requestLogId = await RequestLogModel.createRun({
88
109
  user_prompt: args.prompt,
89
- system_prompt: args.system,
110
+ system_prompt: args.model?.startsWith("anthropic/")
111
+ ? composeSystemWithSchemaContract(args.system, args)
112
+ : args.system,
90
113
  requested_model_name: args.model,
91
114
  effort: args.thinking === false ? undefined : args.effort,
92
115
  service_tier: args.model?.startsWith("openai/") ? args.serviceTier : undefined,
93
116
  project_name: args.projectName,
94
117
  history: filterHistoryForStorage(args.history),
118
+ input_images: inputImages.length > 0 ? inputImages : undefined,
95
119
  tools: args.tools?.length ? args.tools : undefined,
96
120
  is_image_generation: args.imageGeneration === "auto" ? false : args.imageGeneration,
97
121
  json_schema: args.jsonSchema ?? null,
@@ -112,6 +136,7 @@ async function appendGenerateStep(
112
136
  args.model,
113
137
  args.model ?? result.requestedModel ?? result.model,
114
138
  );
139
+
115
140
  const servedModelName = withProviderPrefix(args.model, result.model);
116
141
 
117
142
  // generate step 기록
@@ -133,6 +158,7 @@ async function appendGenerateStep(
133
158
  ttft_ms: result.ttftMs,
134
159
  finish_reason: result.finishReason,
135
160
  });
161
+
136
162
  return { requestedModelName, servedModelName };
137
163
  }
138
164
 
@@ -150,10 +176,12 @@ export async function afterQuery(
150
176
  );
151
177
 
152
178
  const imageParts = getImageParts(result);
179
+
153
180
  const imageCostMicroUsd = estimateImageGenerationCostMicroUsd(
154
181
  result,
155
182
  args.imageGenerationOptions,
156
183
  );
184
+
157
185
  for (const step of buildImageGenerationToolSteps(args, imageParts, stepIndex)) {
158
186
  await RequestLogModel.appendStep(requestLogId, step);
159
187
  }
@@ -161,8 +189,10 @@ export async function afterQuery(
161
189
  if (result.finishReason === "tool-calls") {
162
190
  // tool-call step을 즉시 기록하고, 다음 follow-up이 같은 row에 결과를 채운다.
163
191
  const toolCalls = result.content.filter((c) => c.type === "tool-call");
192
+
164
193
  for (let i = 0; i < toolCalls.length; i++) {
165
194
  const tc = toolCalls[i]!;
195
+
166
196
  if (tc.type !== "tool-call") continue;
167
197
  await RequestLogModel.appendStep(requestLogId, {
168
198
  step_index: stepIndex,
@@ -180,7 +210,8 @@ export async function afterQuery(
180
210
  // finishReason === "stop" → run 종료 (전체 step usage 합산)
181
211
  const agg = await RequestLogModel.aggregateStepUsage(requestLogId);
182
212
  const responseText = formatResponseForLog(result);
183
- await RequestLogModel.finishRun(requestLogId, {
213
+
214
+ const finishParams: Parameters<typeof RequestLogModel.finishRun>[1] = {
184
215
  status: "succeeded",
185
216
  response: responseText,
186
217
  // structured 요청만 판정한다. deti 배치의 broken JSON 류를 목록에서 바로
@@ -202,13 +233,15 @@ export async function afterQuery(
202
233
  cost_usd: agg.cost_usd,
203
234
  cost_source: agg.cost_source,
204
235
  image_cost_usd: imageCostMicroUsd,
205
- ...(imageParts.length > 0 ? { is_image_generation: true } : {}),
206
236
  image_cost_method:
207
237
  imageCostMicroUsd !== null
208
238
  ? imageGenerationCostMethod(args.imageGenerationOptions, result)
209
239
  : null,
210
240
  history: filterHistoryForStorage(args.history),
211
- });
241
+ };
242
+
243
+ if (imageParts.length > 0) finishParams.is_image_generation = true;
244
+ await RequestLogModel.finishRun(requestLogId, finishParams);
212
245
 
213
246
  return {};
214
247
  }
@@ -243,63 +276,74 @@ async function finishTerminalRun(
243
276
  await appendGenerateStep(requestLogId, completedStep.stepIndex, args, completedStep.result);
244
277
  } catch (e) {
245
278
  logger.error(
246
- `appendGenerateStep failed while finishing ${status}: ${(e as Error).message}`,
279
+ `appendGenerateStep failed while finishing ${status}: ${e instanceof Error ? e.message : String(e)}`,
247
280
  );
248
281
  }
249
282
  }
283
+
250
284
  let aggregate: Awaited<ReturnType<typeof RequestLogModel.aggregateStepUsage>> | undefined;
285
+
251
286
  try {
252
287
  aggregate = await RequestLogModel.aggregateStepUsage(requestLogId);
253
288
  } catch (e) {
254
- logger.error(`aggregateStepUsage failed while finishing ${status}: ${(e as Error).message}`);
289
+ logger.error(
290
+ `aggregateStepUsage failed while finishing ${status}: ${e instanceof Error ? e.message : String(e)}`,
291
+ );
255
292
  }
256
293
 
257
- await RequestLogModel.finishRun(requestLogId, {
294
+ const finishParams: Parameters<typeof RequestLogModel.finishRun>[1] = {
258
295
  status,
259
296
  error_message: errorMessage,
260
297
  history: args ? filterHistoryForStorage(args.history) : undefined,
261
- ...(completedStep
262
- ? {
263
- token_name: completedStep.result.tokenName,
264
- requested_model_name: withProviderPrefix(
265
- args?.model,
266
- args?.model ?? completedStep.result.requestedModel ?? completedStep.result.model,
267
- ),
268
- model_name: withProviderPrefix(args?.model, completedStep.result.model),
269
- }
270
- : {}),
271
- ...(aggregate
272
- ? {
273
- input_tokens: aggregate.input_tokens,
274
- output_tokens: aggregate.output_tokens,
275
- cache_read_tokens: aggregate.cache_read_tokens,
276
- cache_creation_tokens: aggregate.cache_creation_tokens,
277
- cache_creation_5m_tokens: aggregate.cache_creation_5m_tokens,
278
- cache_creation_1h_tokens: aggregate.cache_creation_1h_tokens,
279
- duration_ms: aggregate.duration_ms,
280
- fallback_count: aggregate.fallback_count,
281
- cost_usd: aggregate.cost_usd,
282
- cost_source: aggregate.cost_source,
283
- }
284
- : {}),
285
- });
298
+ };
299
+
300
+ if (completedStep) {
301
+ finishParams.token_name = completedStep.result.tokenName;
302
+
303
+ finishParams.requested_model_name = withProviderPrefix(
304
+ args?.model,
305
+ args?.model ?? completedStep.result.requestedModel ?? completedStep.result.model,
306
+ );
307
+
308
+ finishParams.model_name = withProviderPrefix(args?.model, completedStep.result.model);
309
+ }
310
+
311
+ if (aggregate) {
312
+ finishParams.input_tokens = aggregate.input_tokens;
313
+ finishParams.output_tokens = aggregate.output_tokens;
314
+ finishParams.cache_read_tokens = aggregate.cache_read_tokens;
315
+ finishParams.cache_creation_tokens = aggregate.cache_creation_tokens;
316
+ finishParams.cache_creation_5m_tokens = aggregate.cache_creation_5m_tokens;
317
+ finishParams.cache_creation_1h_tokens = aggregate.cache_creation_1h_tokens;
318
+ finishParams.duration_ms = aggregate.duration_ms;
319
+ finishParams.fallback_count = aggregate.fallback_count;
320
+ finishParams.cost_usd = aggregate.cost_usd;
321
+ finishParams.cost_source = aggregate.cost_source;
322
+ }
323
+
324
+ await RequestLogModel.finishRun(requestLogId, finishParams);
286
325
  } catch (e) {
287
- logger.error(`finishTerminalRun(${status}) failed: ${(e as Error).message}`);
326
+ logger.error(
327
+ `finishTerminalRun(${status}) failed: ${e instanceof Error ? e.message : String(e)}`,
328
+ );
288
329
  }
289
330
  }
290
331
 
291
332
  async function cleanupStaleRuns(): Promise<void> {
292
333
  if (staleCleanupInFlight) {
293
334
  await staleCleanupInFlight;
335
+
294
336
  return;
295
337
  }
296
338
 
297
339
  const now = Date.now();
340
+
298
341
  if (now - lastStaleCleanupStartedAt < STALE_CLEANUP_INTERVAL_MS) return;
299
342
  lastStaleCleanupStartedAt = now;
300
343
 
301
344
  const cleanup = performStaleRunCleanup();
302
345
  staleCleanupInFlight = cleanup;
346
+
303
347
  try {
304
348
  await cleanup;
305
349
  } finally {
@@ -310,15 +354,18 @@ async function cleanupStaleRuns(): Promise<void> {
310
354
  async function performStaleRunCleanup(): Promise<void> {
311
355
  try {
312
356
  const errorMessage = "tool-call run: no follow-up within 30 minutes";
357
+
313
358
  const staleIds = await RequestLogModel.expireStaleToolWaitingRuns(
314
359
  STALE_RUN_THRESHOLD_MS,
315
360
  errorMessage,
316
361
  );
362
+
317
363
  const cleanedCount = staleIds.length;
364
+
318
365
  if (cleanedCount > 0) {
319
366
  logger.info(`cleaned up ${cleanedCount} stale running request logs`);
320
367
  }
321
368
  } catch (e) {
322
- logger.error(`stale cleanup failed: ${(e as Error).message}`);
369
+ logger.error(`stale cleanup failed: ${e instanceof Error ? e.message : String(e)}`);
323
370
  }
324
371
  }
@@ -358,6 +358,103 @@ describe("QgridDispatcherClass", () => {
358
358
  ).rejects.toMatchObject({ statusCode: 503 });
359
359
  });
360
360
 
361
+ it("grok without a registered dispatcher returns the Grok not-ready error", async () => {
362
+ const dispatcher = new QgridDispatcherClass();
363
+ dispatcher.openaiDispatcher = { generate: vi.fn(), generateStream: vi.fn() } as never;
364
+
365
+ expect(dispatcher.dispatchers.has("grok")).toBe(false);
366
+ await expect(dispatcher.query({ prompt: "hi", model: "grok/grok-4.7" })).rejects.toMatchObject({
367
+ statusCode: 503,
368
+ message: expect.stringContaining("Grok"),
369
+ });
370
+ await expect(
371
+ dispatcher.queryStream(
372
+ { prompt: "hi", model: "grok/grok-4.7" },
373
+ { onDelta: vi.fn(), onComplete: vi.fn(), onError: vi.fn() },
374
+ ),
375
+ ).rejects.toMatchObject({ statusCode: 503 });
376
+
377
+ dispatcher.startupState.grok = "failed";
378
+ await expect(dispatcher.query({ prompt: "hi", model: "grok/grok-4.7" })).rejects.toMatchObject({
379
+ statusCode: 500,
380
+ });
381
+ });
382
+
383
+ it("an unsupported provider prefix keeps the existing ProcessError", async () => {
384
+ const dispatcher = new QgridDispatcherClass();
385
+
386
+ await expect(dispatcher.query({ prompt: "hi", model: "mistral/large" })).rejects.toThrow(
387
+ /Direct LLM API fallback not implemented/,
388
+ );
389
+ });
390
+
391
+ it("assigning a provider dispatcher keeps the registry in sync", () => {
392
+ const dispatcher = new QgridDispatcherClass();
393
+ const anthropic = { generate: vi.fn(), generateStream: vi.fn() } as never;
394
+
395
+ dispatcher.anthropicDispatcher = anthropic;
396
+ expect(dispatcher.dispatchers.get("anthropic")).toBe(anthropic);
397
+ dispatcher.anthropicDispatcher = null;
398
+ expect(dispatcher.dispatchers.has("anthropic")).toBe(false);
399
+ });
400
+
401
+ it.each([false, true])(
402
+ "a constructor-injected grok dispatcher receives direct affinity requests (stream=%s)",
403
+ async (stream) => {
404
+ const cacheAffinityKey = "g".repeat(64);
405
+ const result = providerResult({
406
+ model: "grok-4.7",
407
+ tokenName: "grok-a",
408
+ threadCoord: { workerId: 21, threadId: "upstream", epoch: 0 },
409
+ });
410
+ const generate = vi.fn(async (_req: GenerateRequest) => result);
411
+ const generateStream = vi.fn(async (_req: GenerateRequest, cb: GenerateStreamCallbacks) =>
412
+ cb.onComplete(result),
413
+ );
414
+ const grok = {
415
+ generate,
416
+ generateStream,
417
+ start: vi.fn(async () => {}),
418
+ stop: vi.fn(async () => {}),
419
+ onTokenAdded: vi.fn(),
420
+ onTokenUpdated: vi.fn(),
421
+ onTokenRemoved: vi.fn(),
422
+ replaceTokens: vi.fn(),
423
+ };
424
+ const dispatcher = new QgridDispatcherClass({ grokDispatcher: grok });
425
+ const input = { prompt: "hi", model: "grok/grok-4.7", system: "sys", cacheAffinityKey };
426
+
427
+ let output: QueryOutput | undefined;
428
+ if (stream) {
429
+ await dispatcher.queryStream(input, {
430
+ onDelta: () => {},
431
+ onComplete: (value) => {
432
+ output = value;
433
+ },
434
+ onError: (error) => {
435
+ throw error;
436
+ },
437
+ });
438
+ } else {
439
+ output = await dispatcher.query(input);
440
+ }
441
+
442
+ const req = (stream ? generateStream : generate).mock.calls[0]?.[0];
443
+ expect(req).toMatchObject({
444
+ model: "grok-4.7",
445
+ systemPrompt: "sys",
446
+ promptCacheKey: cacheAffinityKey,
447
+ });
448
+ expect(output?.runContext?.threadCoord).toEqual({
449
+ workerId: 21,
450
+ threadId: cacheAffinityKey,
451
+ epoch: -1,
452
+ systemHash: systemHash("sys", "grok/grok-4.7"),
453
+ });
454
+ expect(dispatcher.requestCounts.get("grok\0grok-a")).toBe(1);
455
+ },
456
+ );
457
+
361
458
  it("provider prefix 없는 모델은 AnthropicDispatcher 로 암묵 라우팅하지 않는다", async () => {
362
459
  const dispatcher = new QgridDispatcherClass();
363
460
  const generate = vi.fn();