omniroute 3.4.7 → 3.4.8

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 (256) hide show
  1. package/app/.next/BUILD_ID +1 -1
  2. package/app/.next/build-manifest.json +3 -3
  3. package/app/.next/prerender-manifest.json +3 -3
  4. package/app/.next/server/app/(dashboard)/dashboard/agents/page_client-reference-manifest.js +1 -1
  5. package/app/.next/server/app/(dashboard)/dashboard/analytics/page_client-reference-manifest.js +1 -1
  6. package/app/.next/server/app/(dashboard)/dashboard/api-manager/page_client-reference-manifest.js +1 -1
  7. package/app/.next/server/app/(dashboard)/dashboard/audit/page_client-reference-manifest.js +1 -1
  8. package/app/.next/server/app/(dashboard)/dashboard/auto-combo/page_client-reference-manifest.js +1 -1
  9. package/app/.next/server/app/(dashboard)/dashboard/cache/page_client-reference-manifest.js +1 -1
  10. package/app/.next/server/app/(dashboard)/dashboard/cli-tools/page_client-reference-manifest.js +1 -1
  11. package/app/.next/server/app/(dashboard)/dashboard/combos/page_client-reference-manifest.js +1 -1
  12. package/app/.next/server/app/(dashboard)/dashboard/costs/page_client-reference-manifest.js +1 -1
  13. package/app/.next/server/app/(dashboard)/dashboard/endpoint/page_client-reference-manifest.js +1 -1
  14. package/app/.next/server/app/(dashboard)/dashboard/health/page_client-reference-manifest.js +1 -1
  15. package/app/.next/server/app/(dashboard)/dashboard/limits/page_client-reference-manifest.js +1 -1
  16. package/app/.next/server/app/(dashboard)/dashboard/logs/page_client-reference-manifest.js +1 -1
  17. package/app/.next/server/app/(dashboard)/dashboard/media/page_client-reference-manifest.js +1 -1
  18. package/app/.next/server/app/(dashboard)/dashboard/memory/page_client-reference-manifest.js +1 -1
  19. package/app/.next/server/app/(dashboard)/dashboard/onboarding/page_client-reference-manifest.js +1 -1
  20. package/app/.next/server/app/(dashboard)/dashboard/page_client-reference-manifest.js +1 -1
  21. package/app/.next/server/app/(dashboard)/dashboard/playground/page_client-reference-manifest.js +1 -1
  22. package/app/.next/server/app/(dashboard)/dashboard/providers/[id]/page_client-reference-manifest.js +1 -1
  23. package/app/.next/server/app/(dashboard)/dashboard/providers/new/page_client-reference-manifest.js +1 -1
  24. package/app/.next/server/app/(dashboard)/dashboard/providers/page_client-reference-manifest.js +1 -1
  25. package/app/.next/server/app/(dashboard)/dashboard/search-tools/page_client-reference-manifest.js +1 -1
  26. package/app/.next/server/app/(dashboard)/dashboard/settings/page_client-reference-manifest.js +1 -1
  27. package/app/.next/server/app/(dashboard)/dashboard/settings/pricing/page_client-reference-manifest.js +1 -1
  28. package/app/.next/server/app/(dashboard)/dashboard/skills/page_client-reference-manifest.js +1 -1
  29. package/app/.next/server/app/(dashboard)/dashboard/translator/page_client-reference-manifest.js +1 -1
  30. package/app/.next/server/app/400/page_client-reference-manifest.js +1 -1
  31. package/app/.next/server/app/401/page_client-reference-manifest.js +1 -1
  32. package/app/.next/server/app/403/page_client-reference-manifest.js +1 -1
  33. package/app/.next/server/app/408/page_client-reference-manifest.js +1 -1
  34. package/app/.next/server/app/429/page_client-reference-manifest.js +1 -1
  35. package/app/.next/server/app/500/page_client-reference-manifest.js +1 -1
  36. package/app/.next/server/app/502/page_client-reference-manifest.js +1 -1
  37. package/app/.next/server/app/503/page_client-reference-manifest.js +1 -1
  38. package/app/.next/server/app/_global-error.html +1 -1
  39. package/app/.next/server/app/_global-error.rsc +1 -1
  40. package/app/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  41. package/app/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  42. package/app/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  43. package/app/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  44. package/app/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  45. package/app/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  46. package/app/.next/server/app/api/system/version/route.js.nft.json +1 -1
  47. package/app/.next/server/app/api/v1/api/chat/route.js +15 -15
  48. package/app/.next/server/app/api/v1/api/chat/route.js.nft.json +1 -1
  49. package/app/.next/server/app/api/v1/audio/speech/route.js +11 -11
  50. package/app/.next/server/app/api/v1/audio/speech/route.js.nft.json +1 -1
  51. package/app/.next/server/app/api/v1/audio/transcriptions/route.js +5 -5
  52. package/app/.next/server/app/api/v1/audio/transcriptions/route.js.nft.json +1 -1
  53. package/app/.next/server/app/api/v1/chat/completions/route.js +14 -14
  54. package/app/.next/server/app/api/v1/chat/completions/route.js.nft.json +1 -1
  55. package/app/.next/server/app/api/v1/completions/route.js +14 -14
  56. package/app/.next/server/app/api/v1/completions/route.js.nft.json +1 -1
  57. package/app/.next/server/app/api/v1/images/generations/route.js +10 -10
  58. package/app/.next/server/app/api/v1/images/generations/route.js.nft.json +1 -1
  59. package/app/.next/server/app/api/v1/messages/route.js +16 -16
  60. package/app/.next/server/app/api/v1/messages/route.js.nft.json +1 -1
  61. package/app/.next/server/app/api/v1/models/route.js +5 -5
  62. package/app/.next/server/app/api/v1/models/route.js.nft.json +1 -1
  63. package/app/.next/server/app/api/v1/moderations/route.js +9 -9
  64. package/app/.next/server/app/api/v1/moderations/route.js.nft.json +1 -1
  65. package/app/.next/server/app/api/v1/music/generations/route.js +10 -10
  66. package/app/.next/server/app/api/v1/providers/[provider]/chat/completions/route.js +16 -16
  67. package/app/.next/server/app/api/v1/providers/[provider]/chat/completions/route.js.nft.json +1 -1
  68. package/app/.next/server/app/api/v1/providers/[provider]/embeddings/route.js +7 -7
  69. package/app/.next/server/app/api/v1/providers/[provider]/embeddings/route.js.nft.json +1 -1
  70. package/app/.next/server/app/api/v1/providers/[provider]/images/generations/route.js +10 -10
  71. package/app/.next/server/app/api/v1/providers/[provider]/images/generations/route.js.nft.json +1 -1
  72. package/app/.next/server/app/api/v1/rerank/route.js +9 -9
  73. package/app/.next/server/app/api/v1/rerank/route.js.nft.json +1 -1
  74. package/app/.next/server/app/api/v1/responses/[...path]/route.js +16 -16
  75. package/app/.next/server/app/api/v1/responses/[...path]/route.js.nft.json +1 -1
  76. package/app/.next/server/app/api/v1/responses/route.js +16 -16
  77. package/app/.next/server/app/api/v1/responses/route.js.nft.json +1 -1
  78. package/app/.next/server/app/api/v1/route.js +5 -5
  79. package/app/.next/server/app/api/v1/route.js.nft.json +1 -1
  80. package/app/.next/server/app/api/v1/search/analytics/route.js +7 -7
  81. package/app/.next/server/app/api/v1/search/analytics/route.js.nft.json +1 -1
  82. package/app/.next/server/app/api/v1/videos/generations/route.js +10 -10
  83. package/app/.next/server/app/api/v1beta/models/[...path]/route.js +14 -14
  84. package/app/.next/server/app/api/v1beta/models/[...path]/route.js.nft.json +1 -1
  85. package/app/.next/server/app/callback/page_client-reference-manifest.js +1 -1
  86. package/app/.next/server/app/docs/page_client-reference-manifest.js +1 -1
  87. package/app/.next/server/app/forbidden/page_client-reference-manifest.js +1 -1
  88. package/app/.next/server/app/forgot-password/page_client-reference-manifest.js +1 -1
  89. package/app/.next/server/app/landing/page_client-reference-manifest.js +1 -1
  90. package/app/.next/server/app/login/page_client-reference-manifest.js +1 -1
  91. package/app/.next/server/app/maintenance/page_client-reference-manifest.js +1 -1
  92. package/app/.next/server/app/offline/page_client-reference-manifest.js +1 -1
  93. package/app/.next/server/app/page_client-reference-manifest.js +1 -1
  94. package/app/.next/server/app/privacy/page_client-reference-manifest.js +1 -1
  95. package/app/.next/server/app/status/page_client-reference-manifest.js +1 -1
  96. package/app/.next/server/app/terms/page_client-reference-manifest.js +1 -1
  97. package/app/.next/server/chunks/{[root-of-the-server]__0nxyldc._.js → [root-of-the-server]__0-zca2p._.js} +1 -1
  98. package/app/.next/server/chunks/{[root-of-the-server]__0urvs3.._.js → [root-of-the-server]__01hbf~_._.js} +1 -1
  99. package/app/.next/server/chunks/[root-of-the-server]__01ojood._.js +1 -1
  100. package/app/.next/server/chunks/[root-of-the-server]__030_-af._.js +1 -1
  101. package/app/.next/server/chunks/{[root-of-the-server]__0j~-yu1._.js → [root-of-the-server]__03l6k3k._.js} +1 -1
  102. package/app/.next/server/chunks/{[root-of-the-server]__01b8762._.js → [root-of-the-server]__05~jdzu._.js} +1 -1
  103. package/app/.next/server/chunks/{[root-of-the-server]__07eee_s._.js → [root-of-the-server]__08~6j3q._.js} +1 -1
  104. package/app/.next/server/chunks/[root-of-the-server]__0a8ozdb._.js +1 -1
  105. package/app/.next/server/chunks/[root-of-the-server]__0bd4ccn._.js +2 -2
  106. package/app/.next/server/chunks/{[root-of-the-server]__0_a98vk._.js → [root-of-the-server]__0d6bqbw._.js} +1 -1
  107. package/app/.next/server/chunks/{[root-of-the-server]__0_c_.ye._.js → [root-of-the-server]__0f2rz58._.js} +1 -1
  108. package/app/.next/server/chunks/[root-of-the-server]__0jp3yj4._.js +1 -1
  109. package/app/.next/server/chunks/{[root-of-the-server]__06stuoz._.js → [root-of-the-server]__0jvnjwl._.js} +1 -1
  110. package/app/.next/server/chunks/[root-of-the-server]__0mj7x5~._.js +1 -1
  111. package/app/.next/server/chunks/[root-of-the-server]__0n-~kvf._.js +1 -1
  112. package/app/.next/server/chunks/{[root-of-the-server]__0-y3k-t._.js → [root-of-the-server]__0nzi7ym._.js} +1 -1
  113. package/app/.next/server/chunks/[root-of-the-server]__0ofxxzh._.js +2 -2
  114. package/app/.next/server/chunks/{[root-of-the-server]__0uu3t5x._.js → [root-of-the-server]__0pd~24c._.js} +2 -2
  115. package/app/.next/server/chunks/[root-of-the-server]__0s1dq3.._.js +1 -1
  116. package/app/.next/server/chunks/[root-of-the-server]__0tsl88m._.js +1 -1
  117. package/app/.next/server/chunks/[root-of-the-server]__0u5-mph._.js +1 -1
  118. package/app/.next/server/chunks/{[root-of-the-server]__0vi3.0k._.js → [root-of-the-server]__0uryxsh._.js} +1 -1
  119. package/app/.next/server/chunks/{[root-of-the-server]__0lwc40h._.js → [root-of-the-server]__0v1kwmx._.js} +1 -1
  120. package/app/.next/server/chunks/{[root-of-the-server]__04y3b4q._.js → [root-of-the-server]__0vt49c9._.js} +1 -1
  121. package/app/.next/server/chunks/{[root-of-the-server]__0pylsu2._.js → [root-of-the-server]__0vy97gy._.js} +2 -2
  122. package/app/.next/server/chunks/{[root-of-the-server]__0~s45~f._.js → [root-of-the-server]__0wd~o5b._.js} +1 -1
  123. package/app/.next/server/chunks/[root-of-the-server]__0x5yxjy._.js +2 -2
  124. package/app/.next/server/chunks/{[root-of-the-server]__0vmajf6._.js → [root-of-the-server]__0x_hqjb._.js} +1 -1
  125. package/app/.next/server/chunks/[root-of-the-server]__0~0hd.s._.js +2 -2
  126. package/app/.next/server/chunks/{[root-of-the-server]__10~-ypp._.js → [root-of-the-server]__11ptf~3._.js} +1 -1
  127. package/app/.next/server/chunks/_00.pgsp._.js +1 -1
  128. package/app/.next/server/chunks/_013gowh._.js +1 -1
  129. package/app/.next/server/chunks/{_0ucpa5q._.js → _02._8wx._.js} +1 -1
  130. package/app/.next/server/chunks/_036lxbr._.js +1 -1
  131. package/app/.next/server/chunks/_05reh6o._.js +1 -1
  132. package/app/.next/server/chunks/{_0-~thzo._.js → _083_x9z._.js} +2 -2
  133. package/app/.next/server/chunks/_083a5zg._.js +1 -1
  134. package/app/.next/server/chunks/{_004r3br._.js → _08cwbl2._.js} +2 -2
  135. package/app/.next/server/chunks/_0a3.3sc._.js +1 -1
  136. package/app/.next/server/chunks/_0c.abwr._.js +1 -1
  137. package/app/.next/server/chunks/_0dfpto1._.js +1 -1
  138. package/app/.next/server/chunks/_0due8oe._.js +1 -1
  139. package/app/.next/server/chunks/_0h-j8c2._.js +1 -1
  140. package/app/.next/server/chunks/_0vx-r0i._.js +2 -2
  141. package/app/.next/server/chunks/_0w4f3bm._.js +1 -1
  142. package/app/.next/server/chunks/_10.rw9f._.js +1 -1
  143. package/app/.next/server/chunks/open-sse_0dawtxk._.js +2 -2
  144. package/app/.next/server/chunks/open-sse_0p~.88y._.js +1 -1
  145. package/app/.next/server/chunks/open-sse_0sthby3._.js +1 -1
  146. package/app/.next/server/chunks/src_0cbm0~g._.js +1 -1
  147. package/app/.next/server/chunks/src_shared_utils_apiKey_ts_0gzf59_._.js +1 -1
  148. package/app/.next/server/chunks/src_shared_utils_apiKey_ts_12~h.oz._.js +1 -1
  149. package/app/.next/server/chunks/ssr/_008ht2n._.js +1 -1
  150. package/app/.next/server/chunks/ssr/_0oo1f90._.js +1 -1
  151. package/app/.next/server/chunks/ssr/src_04s-8a5._.js +1 -1
  152. package/app/.next/server/chunks/ssr/src_0vjsxxr._.js +1 -1
  153. package/app/.next/server/chunks/ssr/src_shared_utils_apiKey_ts_0l8g1z8._.js +1 -1
  154. package/app/.next/server/middleware-build-manifest.js +3 -3
  155. package/app/.next/server/pages/500.html +1 -1
  156. package/app/.next/server/server-reference-manifest.js +1 -1
  157. package/app/.next/server/server-reference-manifest.json +1 -1
  158. package/app/.next/static/chunks/0ipwpwjb2g0uv.js +1 -0
  159. package/app/.next/static/chunks/0~c--kcvaumm~.js +1 -0
  160. package/app/.next/static/chunks/{02q7h~xz7j6i3.js → 0~v1trn07bitv.js} +1 -1
  161. package/app/CHANGELOG.md +12 -0
  162. package/app/bin/reset-password.mjs +3 -1
  163. package/app/docs/openapi.yaml +1 -1
  164. package/app/open-sse/config/registryUtils.ts +1 -0
  165. package/app/open-sse/config/videoRegistry.ts +1 -3
  166. package/app/open-sse/executors/antigravity.ts +22 -12
  167. package/app/open-sse/executors/gemini-cli.ts +3 -1
  168. package/app/open-sse/executors/qoder.ts +1 -8
  169. package/app/open-sse/handlers/audioSpeech.ts +1 -0
  170. package/app/open-sse/handlers/chatCore.ts +2 -1
  171. package/app/open-sse/handlers/embeddings.ts +1 -0
  172. package/app/open-sse/handlers/imageGeneration.ts +6 -2
  173. package/app/open-sse/handlers/musicGeneration.ts +9 -2
  174. package/app/open-sse/handlers/search.ts +1 -0
  175. package/app/open-sse/handlers/videoGeneration.ts +11 -3
  176. package/app/open-sse/mcp-server/index.ts +0 -1
  177. package/app/open-sse/package.json +1 -1
  178. package/app/open-sse/services/claudeCodeCompatible.ts +2 -2
  179. package/app/open-sse/services/modelCapabilities.ts +3 -4
  180. package/app/open-sse/services/qoderCli.ts +5 -2
  181. package/app/open-sse/services/tokenRefresh.ts +3 -1
  182. package/app/open-sse/services/usage.ts +13 -9
  183. package/app/open-sse/services/workflowFSM.ts +298 -61
  184. package/app/open-sse/translator/index.ts +5 -1
  185. package/app/open-sse/translator/response/gemini-to-openai.ts +5 -1
  186. package/app/open-sse/utils/progressTracker.ts +4 -1
  187. package/app/open-sse/utils/stream.ts +7 -1
  188. package/app/open-sse/utils/streamPayloadCollector.ts +5 -1
  189. package/app/package-lock.json +3 -3
  190. package/app/package.json +1 -1
  191. package/app/scripts/check-route-validation.mjs +3 -1
  192. package/app/scripts/i18n/apply-priority-overrides.mjs +7 -1
  193. package/app/scripts/prepublish.mjs +2 -2
  194. package/app/scripts/run-protocol-clients-tests.mjs +7 -1
  195. package/app/src/app/(dashboard)/dashboard/analytics/components/DiversityScoreCard.tsx +1 -1
  196. package/app/src/app/(dashboard)/dashboard/auto-combo/page.tsx +0 -1
  197. package/app/src/app/(dashboard)/dashboard/media/MediaPageClient.tsx +9 -3
  198. package/app/src/app/(dashboard)/dashboard/providers/[id]/page.tsx +25 -23
  199. package/app/src/app/(dashboard)/dashboard/search-tools/components/SearchHistory.tsx +3 -1
  200. package/app/src/app/api/auth/status/route.ts +1 -3
  201. package/app/src/app/api/mcp/sse/route.ts +2 -2
  202. package/app/src/app/api/mcp/status/route.ts +1 -2
  203. package/app/src/app/api/mcp/stream/route.ts +5 -3
  204. package/app/src/app/api/openapi/spec/route.ts +4 -1
  205. package/app/src/app/api/openapi/try/route.ts +4 -1
  206. package/app/src/app/api/providers/[id]/models/route.ts +4 -4
  207. package/app/src/app/api/providers/[id]/sync-models/route.ts +9 -3
  208. package/app/src/app/api/settings/auto-disable-accounts/route.ts +6 -1
  209. package/app/src/app/api/skills/[id]/route.ts +4 -1
  210. package/app/src/app/api/v1/issues/report/route.ts +9 -1
  211. package/app/src/app/api/v1beta/models/route.ts +8 -6
  212. package/app/src/app/api/webhooks/[id]/route.ts +9 -7
  213. package/app/src/domain/fallbackPolicy.ts +0 -1
  214. package/app/src/domain/modelAvailability.ts +0 -1
  215. package/app/src/domain/providerExpiration.ts +2 -6
  216. package/app/src/lib/db/models.ts +23 -13
  217. package/app/src/lib/evals/evalRunner.ts +0 -1
  218. package/app/src/lib/evals/scheduler.ts +2 -6
  219. package/app/src/lib/oauth/services/antigravity.ts +6 -1
  220. package/app/src/lib/oauth/services/kiro.ts +12 -2
  221. package/app/src/lib/oauth/services/oauth.ts +10 -2
  222. package/app/src/lib/oauth/utils/server.ts +4 -1
  223. package/app/src/lib/plugins/index.ts +2 -8
  224. package/app/src/lib/usageAnalytics.ts +5 -1
  225. package/app/src/mitm/manager.js +1 -1
  226. package/app/src/mitm/manager.ts +1 -1
  227. package/app/src/shared/components/Button.tsx +0 -1
  228. package/app/src/shared/components/Card.tsx +0 -2
  229. package/app/src/shared/components/FilterBar.tsx +4 -12
  230. package/app/src/shared/components/Input.tsx +1 -1
  231. package/app/src/shared/components/Modal.tsx +0 -1
  232. package/app/src/shared/components/NotificationToast.tsx +1 -3
  233. package/app/src/shared/components/Select.tsx +1 -1
  234. package/app/src/shared/components/Sidebar.tsx +3 -3
  235. package/app/src/shared/components/ThemeToggle.tsx +7 -1
  236. package/app/src/shared/constants/cliCompatProviders.ts +0 -1
  237. package/app/src/shared/constants/errorCodes.ts +114 -19
  238. package/app/src/shared/utils/apiKey.ts +2 -4
  239. package/app/src/shared/utils/fetchTimeout.ts +0 -1
  240. package/app/src/shared/utils/inputSanitizer.ts +8 -4
  241. package/app/src/shared/utils/requestTimeout.ts +5 -1
  242. package/app/src/sse/handlers/chat.ts +1 -0
  243. package/app/src/sse/services/auth.ts +8 -3
  244. package/app/src/sse/services/streamState.ts +5 -1
  245. package/app/src/store/notificationStore.ts +3 -7
  246. package/app/tests/unit/t20-t22-provider-headers.test.mjs +3 -1
  247. package/bin/reset-password.mjs +3 -1
  248. package/open-sse/mcp-server/__tests__/glmCodingProviderConfig.test.ts +5 -1
  249. package/open-sse/mcp-server/index.ts +0 -1
  250. package/package.json +1 -1
  251. package/app/.next/server/chunks/_0-jnvci._.js +0 -19
  252. package/app/.next/static/chunks/0l88mho31mflv.js +0 -1
  253. package/app/.next/static/chunks/0wt-4zl7_gil8.js +0 -1
  254. /package/app/.next/static/{ri1SkwBU-ygQ2qIDe8jf2 → 1dZBzAZ8QsddVCQRQtqjg}/_buildManifest.js +0 -0
  255. /package/app/.next/static/{ri1SkwBU-ygQ2qIDe8jf2 → 1dZBzAZ8QsddVCQRQtqjg}/_clientMiddlewareManifest.js +0 -0
  256. /package/app/.next/static/{ri1SkwBU-ygQ2qIDe8jf2 → 1dZBzAZ8QsddVCQRQtqjg}/_ssgManifest.js +0 -0
@@ -5,79 +5,293 @@
5
5
  * Risk-based phase skipping: high=all phases, medium=skip planner, low=execute+test only.
6
6
  */
7
7
 
8
- export type Phase = "classify"|"plan"|"plan_review"|"execute"|"code_review"|"quality_review"|"security"|"test"|"output_review"|"done"|"failed"|"paused";
9
- export type RiskLevel = "low"|"medium"|"high";
10
- export type Verdict = "approve"|"approve_with_notes"|"request_changes"|"reject"|"block";
8
+ export type Phase =
9
+ | "classify"
10
+ | "plan"
11
+ | "plan_review"
12
+ | "execute"
13
+ | "code_review"
14
+ | "quality_review"
15
+ | "security"
16
+ | "test"
17
+ | "output_review"
18
+ | "done"
19
+ | "failed"
20
+ | "paused";
21
+ export type RiskLevel = "low" | "medium" | "high";
22
+ export type Verdict = "approve" | "approve_with_notes" | "request_changes" | "reject" | "block";
11
23
 
12
24
  export interface PhaseRecord {
13
- phase: Phase; enteredAt: string; exitedAt: string|null;
14
- verdict: Verdict|null; provider: string|null; model: string|null;
15
- retryCount: number; notes: string|null;
25
+ phase: Phase;
26
+ enteredAt: string;
27
+ exitedAt: string | null;
28
+ verdict: Verdict | null;
29
+ provider: string | null;
30
+ model: string | null;
31
+ retryCount: number;
32
+ notes: string | null;
16
33
  }
17
34
 
18
35
  export interface WorkflowContext {
19
- id: string; currentPhase: Phase; risk: RiskLevel;
20
- lastVerdict: Verdict|null; retries: Record<string,number>;
21
- maxRetries: number; testsPass: boolean;
22
- history: PhaseRecord[]; createdAt: string;
23
- metadata: Record<string,unknown>;
36
+ id: string;
37
+ currentPhase: Phase;
38
+ risk: RiskLevel;
39
+ lastVerdict: Verdict | null;
40
+ retries: Record<string, number>;
41
+ maxRetries: number;
42
+ testsPass: boolean;
43
+ history: PhaseRecord[];
44
+ createdAt: string;
45
+ metadata: Record<string, unknown>;
24
46
  }
25
47
 
26
- interface Transition { from: Phase; to: Phase; condition: (ctx: WorkflowContext) => boolean; description: string; }
48
+ interface Transition {
49
+ from: Phase;
50
+ to: Phase;
51
+ condition: (ctx: WorkflowContext) => boolean;
52
+ description: string;
53
+ }
27
54
 
28
- const HIGH_KEYWORDS = ["schema","migration","deploy","delete","drop","env","database","refactor","security","auth","production","secrets","credentials","permission"];
29
- const MED_KEYWORDS = ["endpoint","feature","service","model","api","integration","webhook","middleware","route"];
55
+ const HIGH_KEYWORDS = [
56
+ "schema",
57
+ "migration",
58
+ "deploy",
59
+ "delete",
60
+ "drop",
61
+ "env",
62
+ "database",
63
+ "refactor",
64
+ "security",
65
+ "auth",
66
+ "production",
67
+ "secrets",
68
+ "credentials",
69
+ "permission",
70
+ ];
71
+ const MED_KEYWORDS = [
72
+ "endpoint",
73
+ "feature",
74
+ "service",
75
+ "model",
76
+ "api",
77
+ "integration",
78
+ "webhook",
79
+ "middleware",
80
+ "route",
81
+ ];
30
82
 
31
83
  export function classifyRisk(desc: string): RiskLevel {
32
84
  const l = desc.toLowerCase();
33
- if (HIGH_KEYWORDS.some(k => l.includes(k))) return "high";
34
- if (MED_KEYWORDS.some(k => l.includes(k))) return "medium";
85
+ if (HIGH_KEYWORDS.some((k) => l.includes(k))) return "high";
86
+ if (MED_KEYWORDS.some((k) => l.includes(k))) return "medium";
35
87
  return "low";
36
88
  }
37
89
 
38
- const PHASE_ORDER: Phase[] = ["classify","plan","plan_review","execute","code_review","quality_review","security","test","output_review"];
90
+ const PHASE_ORDER: Phase[] = [
91
+ "classify",
92
+ "plan",
93
+ "plan_review",
94
+ "execute",
95
+ "code_review",
96
+ "quality_review",
97
+ "security",
98
+ "test",
99
+ "output_review",
100
+ ];
39
101
 
40
102
  const T: Transition[] = [
41
- {from:"classify",to:"plan",condition:c=>c.risk==="high",description:"High risk -> full planning"},
42
- {from:"classify",to:"execute",condition:c=>c.risk==="medium",description:"Medium risk -> skip planner"},
43
- {from:"classify",to:"execute",condition:c=>c.risk==="low",description:"Low risk -> direct execute"},
44
- {from:"plan",to:"plan_review",condition:()=>true,description:"Plan -> review"},
45
- {from:"plan_review",to:"execute",condition:c=>c.lastVerdict==="approve"||c.lastVerdict==="approve_with_notes",description:"Plan approved -> execute"},
46
- {from:"plan_review",to:"plan",condition:c=>(c.lastVerdict==="reject"||c.lastVerdict==="request_changes")&&(c.retries["plan"]??0)<c.maxRetries,description:"Plan rejected -> retry"},
47
- {from:"plan_review",to:"failed",condition:c=>(c.lastVerdict==="reject"||c.lastVerdict==="request_changes")&&(c.retries["plan"]??0)>=c.maxRetries,description:"Plan rejected max retries"},
48
- {from:"execute",to:"code_review",condition:c=>c.risk!=="low",description:"Non-low -> code review"},
49
- {from:"execute",to:"test",condition:c=>c.risk==="low",description:"Low -> skip reviews"},
50
- {from:"code_review",to:"quality_review",condition:c=>c.lastVerdict==="approve"||c.lastVerdict==="approve_with_notes",description:"Code approved -> quality"},
51
- {from:"code_review",to:"execute",condition:c=>(c.lastVerdict==="reject"||c.lastVerdict==="request_changes")&&(c.retries["execute"]??0)<c.maxRetries,description:"Code rejected -> re-execute"},
52
- {from:"code_review",to:"failed",condition:c=>(c.lastVerdict==="reject"||c.lastVerdict==="request_changes")&&(c.retries["execute"]??0)>=c.maxRetries,description:"Code rejected max retries"},
53
- {from:"quality_review",to:"security",condition:c=>c.risk==="high",description:"High -> security audit"},
54
- {from:"quality_review",to:"test",condition:c=>c.risk!=="high",description:"Non-high -> skip security"},
55
- {from:"security",to:"failed",condition:c=>c.lastVerdict==="block",description:"Security BLOCK -> failed"},
56
- {from:"security",to:"test",condition:c=>c.lastVerdict!=="block",description:"Security passed -> test"},
57
- {from:"test",to:"output_review",condition:c=>c.testsPass,description:"Tests pass -> output review"},
58
- {from:"test",to:"execute",condition:c=>!c.testsPass&&(c.retries["execute"]??0)<c.maxRetries,description:"Tests fail -> re-execute"},
59
- {from:"test",to:"failed",condition:c=>!c.testsPass&&(c.retries["execute"]??0)>=c.maxRetries,description:"Tests fail max retries"},
60
- {from:"output_review",to:"done",condition:()=>true,description:"Output reviewed -> done"},
103
+ {
104
+ from: "classify",
105
+ to: "plan",
106
+ condition: (c) => c.risk === "high",
107
+ description: "High risk -> full planning",
108
+ },
109
+ {
110
+ from: "classify",
111
+ to: "execute",
112
+ condition: (c) => c.risk === "medium",
113
+ description: "Medium risk -> skip planner",
114
+ },
115
+ {
116
+ from: "classify",
117
+ to: "execute",
118
+ condition: (c) => c.risk === "low",
119
+ description: "Low risk -> direct execute",
120
+ },
121
+ { from: "plan", to: "plan_review", condition: () => true, description: "Plan -> review" },
122
+ {
123
+ from: "plan_review",
124
+ to: "execute",
125
+ condition: (c) => c.lastVerdict === "approve" || c.lastVerdict === "approve_with_notes",
126
+ description: "Plan approved -> execute",
127
+ },
128
+ {
129
+ from: "plan_review",
130
+ to: "plan",
131
+ condition: (c) =>
132
+ (c.lastVerdict === "reject" || c.lastVerdict === "request_changes") &&
133
+ (c.retries["plan"] ?? 0) < c.maxRetries,
134
+ description: "Plan rejected -> retry",
135
+ },
136
+ {
137
+ from: "plan_review",
138
+ to: "failed",
139
+ condition: (c) =>
140
+ (c.lastVerdict === "reject" || c.lastVerdict === "request_changes") &&
141
+ (c.retries["plan"] ?? 0) >= c.maxRetries,
142
+ description: "Plan rejected max retries",
143
+ },
144
+ {
145
+ from: "execute",
146
+ to: "code_review",
147
+ condition: (c) => c.risk !== "low",
148
+ description: "Non-low -> code review",
149
+ },
150
+ {
151
+ from: "execute",
152
+ to: "test",
153
+ condition: (c) => c.risk === "low",
154
+ description: "Low -> skip reviews",
155
+ },
156
+ {
157
+ from: "code_review",
158
+ to: "quality_review",
159
+ condition: (c) => c.lastVerdict === "approve" || c.lastVerdict === "approve_with_notes",
160
+ description: "Code approved -> quality",
161
+ },
162
+ {
163
+ from: "code_review",
164
+ to: "execute",
165
+ condition: (c) =>
166
+ (c.lastVerdict === "reject" || c.lastVerdict === "request_changes") &&
167
+ (c.retries["execute"] ?? 0) < c.maxRetries,
168
+ description: "Code rejected -> re-execute",
169
+ },
170
+ {
171
+ from: "code_review",
172
+ to: "failed",
173
+ condition: (c) =>
174
+ (c.lastVerdict === "reject" || c.lastVerdict === "request_changes") &&
175
+ (c.retries["execute"] ?? 0) >= c.maxRetries,
176
+ description: "Code rejected max retries",
177
+ },
178
+ {
179
+ from: "quality_review",
180
+ to: "security",
181
+ condition: (c) => c.risk === "high",
182
+ description: "High -> security audit",
183
+ },
184
+ {
185
+ from: "quality_review",
186
+ to: "test",
187
+ condition: (c) => c.risk !== "high",
188
+ description: "Non-high -> skip security",
189
+ },
190
+ {
191
+ from: "security",
192
+ to: "failed",
193
+ condition: (c) => c.lastVerdict === "block",
194
+ description: "Security BLOCK -> failed",
195
+ },
196
+ {
197
+ from: "security",
198
+ to: "test",
199
+ condition: (c) => c.lastVerdict !== "block",
200
+ description: "Security passed -> test",
201
+ },
202
+ {
203
+ from: "test",
204
+ to: "output_review",
205
+ condition: (c) => c.testsPass,
206
+ description: "Tests pass -> output review",
207
+ },
208
+ {
209
+ from: "test",
210
+ to: "execute",
211
+ condition: (c) => !c.testsPass && (c.retries["execute"] ?? 0) < c.maxRetries,
212
+ description: "Tests fail -> re-execute",
213
+ },
214
+ {
215
+ from: "test",
216
+ to: "failed",
217
+ condition: (c) => !c.testsPass && (c.retries["execute"] ?? 0) >= c.maxRetries,
218
+ description: "Tests fail max retries",
219
+ },
220
+ {
221
+ from: "output_review",
222
+ to: "done",
223
+ condition: () => true,
224
+ description: "Output reviewed -> done",
225
+ },
61
226
  ];
62
227
 
63
- export function createWorkflow(id: string, description: string, opts?: {maxRetries?: number; metadata?: Record<string,unknown>}): WorkflowContext {
228
+ export function createWorkflow(
229
+ id: string,
230
+ description: string,
231
+ opts?: { maxRetries?: number; metadata?: Record<string, unknown> }
232
+ ): WorkflowContext {
64
233
  const risk = classifyRisk(description);
65
- return {id, currentPhase:"classify", risk, lastVerdict:null, retries:{}, maxRetries:opts?.maxRetries??3, testsPass:false,
66
- history:[{phase:"classify",enteredAt:new Date().toISOString(),exitedAt:null,verdict:null,provider:null,model:null,retryCount:0,notes:`Risk: ${risk}`}],
67
- createdAt:new Date().toISOString(), metadata:opts?.metadata??{}};
234
+ return {
235
+ id,
236
+ currentPhase: "classify",
237
+ risk,
238
+ lastVerdict: null,
239
+ retries: {},
240
+ maxRetries: opts?.maxRetries ?? 3,
241
+ testsPass: false,
242
+ history: [
243
+ {
244
+ phase: "classify",
245
+ enteredAt: new Date().toISOString(),
246
+ exitedAt: null,
247
+ verdict: null,
248
+ provider: null,
249
+ model: null,
250
+ retryCount: 0,
251
+ notes: `Risk: ${risk}`,
252
+ },
253
+ ],
254
+ createdAt: new Date().toISOString(),
255
+ metadata: opts?.metadata ?? {},
256
+ };
68
257
  }
69
258
 
70
- export function advance(ctx: WorkflowContext, result?: {verdict?:Verdict;testsPass?:boolean;provider?:string;model?:string;notes?:string}): Phase|null {
71
- if(result?.verdict!=null) ctx.lastVerdict=result.verdict;
72
- if(result?.testsPass!=null) ctx.testsPass=result.testsPass;
73
- const cur=ctx.history[ctx.history.length-1];
74
- if(cur){cur.exitedAt=new Date().toISOString();cur.verdict=result?.verdict??null;cur.provider=result?.provider??null;cur.model=result?.model??null;cur.notes=result?.notes??null;}
75
- for(const t of T){
76
- if(t.from===ctx.currentPhase&&t.condition(ctx)){
77
- const fi=PHASE_ORDER.indexOf(t.from),ti=PHASE_ORDER.indexOf(t.to);
78
- if(ti>=0&&fi>=0&&ti<=fi) ctx.retries[t.to]=(ctx.retries[t.to]??0)+1;
79
- ctx.currentPhase=t.to;
80
- ctx.history.push({phase:t.to,enteredAt:new Date().toISOString(),exitedAt:null,verdict:null,provider:null,model:null,retryCount:ctx.retries[t.to]??0,notes:t.description});
259
+ export function advance(
260
+ ctx: WorkflowContext,
261
+ result?: {
262
+ verdict?: Verdict;
263
+ testsPass?: boolean;
264
+ provider?: string;
265
+ model?: string;
266
+ notes?: string;
267
+ }
268
+ ): Phase | null {
269
+ if (result?.verdict != null) ctx.lastVerdict = result.verdict;
270
+ if (result?.testsPass != null) ctx.testsPass = result.testsPass;
271
+ const cur = ctx.history[ctx.history.length - 1];
272
+ if (cur) {
273
+ cur.exitedAt = new Date().toISOString();
274
+ cur.verdict = result?.verdict ?? null;
275
+ cur.provider = result?.provider ?? null;
276
+ cur.model = result?.model ?? null;
277
+ cur.notes = result?.notes ?? null;
278
+ }
279
+ for (const t of T) {
280
+ if (t.from === ctx.currentPhase && t.condition(ctx)) {
281
+ const fi = PHASE_ORDER.indexOf(t.from),
282
+ ti = PHASE_ORDER.indexOf(t.to);
283
+ if (ti >= 0 && fi >= 0 && ti <= fi) ctx.retries[t.to] = (ctx.retries[t.to] ?? 0) + 1;
284
+ ctx.currentPhase = t.to;
285
+ ctx.history.push({
286
+ phase: t.to,
287
+ enteredAt: new Date().toISOString(),
288
+ exitedAt: null,
289
+ verdict: null,
290
+ provider: null,
291
+ model: null,
292
+ retryCount: ctx.retries[t.to] ?? 0,
293
+ notes: t.description,
294
+ });
81
295
  return t.to;
82
296
  }
83
297
  }
@@ -85,19 +299,42 @@ export function advance(ctx: WorkflowContext, result?: {verdict?:Verdict;testsPa
85
299
  }
86
300
 
87
301
  export function pause(ctx: WorkflowContext, reason: string): void {
88
- ctx.currentPhase="paused";
89
- ctx.history.push({phase:"paused",enteredAt:new Date().toISOString(),exitedAt:null,verdict:null,provider:null,model:null,retryCount:0,notes:reason});
302
+ ctx.currentPhase = "paused";
303
+ ctx.history.push({
304
+ phase: "paused",
305
+ enteredAt: new Date().toISOString(),
306
+ exitedAt: null,
307
+ verdict: null,
308
+ provider: null,
309
+ model: null,
310
+ retryCount: 0,
311
+ notes: reason,
312
+ });
90
313
  }
91
314
 
92
315
  export function resume(ctx: WorkflowContext, phase: Phase): void {
93
- const p=ctx.history[ctx.history.length-1];if(p)p.exitedAt=new Date().toISOString();
94
- ctx.currentPhase=phase;
95
- ctx.history.push({phase,enteredAt:new Date().toISOString(),exitedAt:null,verdict:null,provider:null,model:null,retryCount:ctx.retries[phase]??0,notes:"Resumed"});
316
+ const p = ctx.history[ctx.history.length - 1];
317
+ if (p) p.exitedAt = new Date().toISOString();
318
+ ctx.currentPhase = phase;
319
+ ctx.history.push({
320
+ phase,
321
+ enteredAt: new Date().toISOString(),
322
+ exitedAt: null,
323
+ verdict: null,
324
+ provider: null,
325
+ model: null,
326
+ retryCount: ctx.retries[phase] ?? 0,
327
+ notes: "Resumed",
328
+ });
96
329
  }
97
330
 
98
- export function isTerminated(ctx: WorkflowContext): boolean { return ctx.currentPhase==="done"||ctx.currentPhase==="failed"; }
99
- export function getPhaseSequence(ctx: WorkflowContext): Phase[] { return ctx.history.map(r=>r.phase); }
331
+ export function isTerminated(ctx: WorkflowContext): boolean {
332
+ return ctx.currentPhase === "done" || ctx.currentPhase === "failed";
333
+ }
334
+ export function getPhaseSequence(ctx: WorkflowContext): Phase[] {
335
+ return ctx.history.map((r) => r.phase);
336
+ }
100
337
  export function getLLMCallCount(ctx: WorkflowContext): number {
101
- const sys: Phase[]=["classify","paused","done","failed"];
102
- return ctx.history.filter(r=>!sys.includes(r.phase)&&r.exitedAt!=null).length;
338
+ const sys: Phase[] = ["classify", "paused", "done", "failed"];
339
+ return ctx.history.filter((r) => !sys.includes(r.phase) && r.exitedAt != null).length;
103
340
  }
@@ -84,7 +84,11 @@ export function translateRequest(
84
84
  credentials = null,
85
85
  provider = null,
86
86
  reqLogger = null,
87
- options?: { normalizeToolCallId?: boolean; preserveDeveloperRole?: boolean; preserveCacheControl?: boolean }
87
+ options?: {
88
+ normalizeToolCallId?: boolean;
89
+ preserveDeveloperRole?: boolean;
90
+ preserveCacheControl?: boolean;
91
+ }
88
92
  ) {
89
93
  let result = body;
90
94
  const use9CharId = options?.normalizeToolCallId === true;
@@ -227,7 +227,11 @@ export function geminiToOpenAIResponse(chunk, state) {
227
227
  }
228
228
  // Content blocked by Gemini safety filters — pass through as "content_filter"
229
229
  // so downstream clients can distinguish from normal completion.
230
- if (finishReason === "safety" || finishReason === "recitation" || finishReason === "blocklist") {
230
+ if (
231
+ finishReason === "safety" ||
232
+ finishReason === "recitation" ||
233
+ finishReason === "blocklist"
234
+ ) {
231
235
  finishReason = "content_filter";
232
236
  }
233
237
 
@@ -21,7 +21,10 @@ const DEFAULT_INTERVAL_MS = 2000;
21
21
  * @param {AbortSignal} [options.signal] - Abort signal for cancellation
22
22
  * @returns {TransformStream}
23
23
  */
24
- export function createProgressTransform({ intervalMs = DEFAULT_INTERVAL_MS, signal }: { intervalMs?: number; signal?: AbortSignal } = {}) {
24
+ export function createProgressTransform({
25
+ intervalMs = DEFAULT_INTERVAL_MS,
26
+ signal,
27
+ }: { intervalMs?: number; signal?: AbortSignal } = {}) {
25
28
  let tokenCount = 0;
26
29
  let startTime = Date.now();
27
30
  let intervalId;
@@ -10,7 +10,13 @@ import {
10
10
  filterUsageForFormat,
11
11
  COLORS,
12
12
  } from "./usageTracking.ts";
13
- import { parseSSELine, hasValuableContent, fixInvalidId, formatSSE, unwrapGeminiChunk } from "./streamHelpers.ts";
13
+ import {
14
+ parseSSELine,
15
+ hasValuableContent,
16
+ fixInvalidId,
17
+ formatSSE,
18
+ unwrapGeminiChunk,
19
+ } from "./streamHelpers.ts";
14
20
  import {
15
21
  createStructuredSSECollector,
16
22
  buildStreamSummaryFromEvents,
@@ -158,7 +158,11 @@ function buildOpenAISummary(events: StructuredSSEEvent[], fallbackModel?: string
158
158
  reasoningParts.push(delta.reasoning_content);
159
159
  }
160
160
  // Normalize `reasoning` alias (NVIDIA kimi-k2.5 etc.)
161
- if (typeof delta.reasoning === "string" && delta.reasoning.length > 0 && !delta.reasoning_content) {
161
+ if (
162
+ typeof delta.reasoning === "string" &&
163
+ delta.reasoning.length > 0 &&
164
+ !delta.reasoning_content
165
+ ) {
162
166
  reasoningParts.push(delta.reasoning);
163
167
  }
164
168
 
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "omniroute",
3
- "version": "3.4.7",
3
+ "version": "3.4.8",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "omniroute",
9
- "version": "3.4.7",
9
+ "version": "3.4.8",
10
10
  "hasInstallScript": true,
11
11
  "license": "MIT",
12
12
  "workspaces": [
@@ -20886,7 +20886,7 @@
20886
20886
  },
20887
20887
  "open-sse": {
20888
20888
  "name": "@omniroute/open-sse",
20889
- "version": "3.4.7"
20889
+ "version": "3.4.8"
20890
20890
  }
20891
20891
  }
20892
20892
  }
package/app/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "omniroute",
3
- "version": "3.4.7",
3
+ "version": "3.4.8",
4
4
  "description": "Smart AI Router with auto fallback — route to FREE & cheap models, zero downtime. Works with Cursor, Cline, Claude Desktop, Codex, and any OpenAI-compatible tool.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -51,7 +51,9 @@ for (const fullPath of routeFiles) {
51
51
  }
52
52
 
53
53
  if (missingValidation.length > 0) {
54
- console.error("[t06:route-validation] FAIL - routes with request.json() without validateBody() or .safeParse():");
54
+ console.error(
55
+ "[t06:route-validation] FAIL - routes with request.json() without validateBody() or .safeParse():"
56
+ );
55
57
  for (const file of missingValidation) {
56
58
  console.error(` - ${file}`);
57
59
  }
@@ -170,9 +170,15 @@ function setByPath(target, pathStr, value) {
170
170
  const tokens = pathStr.split(".");
171
171
  let current = target;
172
172
  for (let i = 0; i < tokens.length - 1; i += 1) {
173
+ if (tokens[i] === "__proto__" || tokens[i] === "constructor" || tokens[i] === "prototype")
174
+ continue;
175
+ if (typeof current[tokens[i]] !== "object") current[tokens[i]] = {};
173
176
  current = current[tokens[i]];
174
177
  }
175
- current[tokens[tokens.length - 1]] = value;
178
+ const last = tokens[tokens.length - 1];
179
+ if (last !== "__proto__" && last !== "constructor" && last !== "prototype") {
180
+ current[last] = value;
181
+ }
176
182
  }
177
183
 
178
184
  async function applyMessageOverrides() {
@@ -240,7 +240,7 @@ if (existsSync(mitmSrc)) {
240
240
  writeFileSync(tmpTsconfigPath, JSON.stringify(mitmTsconfig, null, 2));
241
241
 
242
242
  try {
243
- execSync("npx tsc -p " + JSON.stringify(tmpTsconfigPath), { cwd: ROOT, stdio: "inherit" });
243
+ execSync("npx tsc -p tsconfig.mitm.tmp.json", { cwd: ROOT, stdio: "inherit" });
244
244
  console.log(" ✅ MITM utilities compiled to app/src/mitm/");
245
245
  } catch (err) {
246
246
  console.warn(" ⚠️ MITM compile warning (non-fatal):", err.message);
@@ -264,7 +264,7 @@ if (existsSync(mcpSrcFile)) {
264
264
  mkdirSync(mcpDestDir, { recursive: true });
265
265
  try {
266
266
  execSync(
267
- `npx esbuild ${JSON.stringify(mcpSrcFile)} --bundle --platform=node --packages=external --format=esm --outfile=${JSON.stringify(mcpDestFile)}`,
267
+ `npx esbuild open-sse/mcp-server/server.ts --bundle --platform=node --packages=external --format=esm --outfile=app/open-sse/mcp-server/server.js`,
268
268
  { cwd: ROOT, stdio: "inherit" }
269
269
  );
270
270
  console.log(" ✅ MCP Server bundled to app/open-sse/mcp-server/server.js");
@@ -45,7 +45,13 @@ async function main() {
45
45
 
46
46
  const vitestProcess = spawn(
47
47
  process.execPath,
48
- ["./node_modules/vitest/vitest.mjs", "run", "tests/e2e/protocol-clients.test.ts", "--dir", "tests"],
48
+ [
49
+ "./node_modules/vitest/vitest.mjs",
50
+ "run",
51
+ "tests/e2e/protocol-clients.test.ts",
52
+ "--dir",
53
+ "tests",
54
+ ],
49
55
  {
50
56
  stdio: "inherit",
51
57
  env: testEnv,
@@ -54,7 +54,7 @@ export default function DiversityScoreCard() {
54
54
  Provider Diversity Score
55
55
  </h3>
56
56
  <span
57
- className={`text-xs px-2 py-0.5 rounded-md border ${gaugeColor.replace("bg-", "border-").replace("500", "500/20")} ${gaugeColor.replace("bg-", "bg-").replace("500", "500/10")} ${riskColor}`}
57
+ className={`text-xs px-2 py-0.5 rounded-md border ${gaugeColor.replace("bg-", "border-").replace("500", "500/20")} ${gaugeColor.replace("500", "500/10")} ${riskColor}`}
58
58
  >
59
59
  Shannon Entropy
60
60
  </span>
@@ -144,7 +144,6 @@ export default function AutoComboDashboard() {
144
144
  tierPriority: "🏷️ Tier",
145
145
  };
146
146
 
147
-
148
147
  const MODE_PACKS = [
149
148
  { id: "ship-fast", label: "🚀 Ship Fast" },
150
149
  { id: "cost-saver", label: "💰 Cost Saver" },
@@ -753,7 +753,9 @@ export default function MediaPageClient() {
753
753
  {/* Transcription: file upload */}
754
754
  {activeTab === "transcription" ? (
755
755
  <div>
756
- <label className="block text-sm font-medium text-text-main mb-2">Audio / Video File</label>
756
+ <label className="block text-sm font-medium text-text-main mb-2">
757
+ Audio / Video File
758
+ </label>
757
759
  <input
758
760
  type="file"
759
761
  accept="audio/*,video/*"
@@ -761,7 +763,9 @@ export default function MediaPageClient() {
761
763
  const file = e.target.files?.[0] ?? null;
762
764
  setFileSizeError(null);
763
765
  if (file && file.size > MAX_TRANSCRIPTION_FILE_SIZE) {
764
- setFileSizeError(`File too large (${formatFileSize(file.size)}). Maximum allowed: 4 GB.`);
766
+ setFileSizeError(
767
+ `File too large (${formatFileSize(file.size)}). Maximum allowed: 4 GB.`
768
+ );
765
769
  setAudioFile(null);
766
770
  e.target.value = "";
767
771
  return;
@@ -781,7 +785,9 @@ export default function MediaPageClient() {
781
785
  {audioFile.name} ({formatFileSize(audioFile.size)})
782
786
  </p>
783
787
  )}
784
- <p className="text-[10px] text-text-muted/60 mt-1">Supports audio and video files up to 4 GB</p>
788
+ <p className="text-[10px] text-text-muted/60 mt-1">
789
+ Supports audio and video files up to 4 GB
790
+ </p>
785
791
  </div>
786
792
  ) : (
787
793
  /* Prompt / Text */