@fudrouter/fsrouter 0.6.64 → 0.6.65

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 (556) hide show
  1. package/open-sse/AGENTS.md +39 -0
  2. package/open-sse/config/anthropicHeaders.js +87 -0
  3. package/open-sse/config/appConstants.js +238 -0
  4. package/open-sse/config/audioRegistry.js +506 -0
  5. package/open-sse/config/cliFingerprints.js +304 -0
  6. package/open-sse/config/codexInstructions.js +119 -0
  7. package/open-sse/config/codexQuotaScopes.js +42 -0
  8. package/open-sse/config/constants.js +4 -0
  9. package/open-sse/config/contextEditing.js +68 -0
  10. package/open-sse/config/credentialLoader.js +83 -0
  11. package/open-sse/config/defaultThinkingSignature.js +12 -0
  12. package/open-sse/config/embeddingRegistry.js +264 -0
  13. package/open-sse/config/errorConfig.js +96 -0
  14. package/open-sse/config/freeModelCatalog.data.js +121 -0
  15. package/open-sse/config/freeModelCatalog.js +90 -0
  16. package/open-sse/config/freeTierCatalog.js +81 -0
  17. package/open-sse/config/googleTtsLanguages.js +62 -0
  18. package/open-sse/config/imageParamDefs.js +360 -0
  19. package/open-sse/config/imageRegistry.js +493 -0
  20. package/open-sse/config/kiroConstants.js +268 -0
  21. package/open-sse/config/mediaConfig.js +27 -0
  22. package/open-sse/config/mediaServiceKinds.js +71 -0
  23. package/open-sse/config/models.js +13 -0
  24. package/open-sse/config/moderationRegistry.js +71 -0
  25. package/open-sse/config/musicRegistry.js +99 -0
  26. package/open-sse/config/ocrRegistry.js +61 -0
  27. package/open-sse/config/ollamaModels.js +19 -0
  28. package/open-sse/config/providerErrorRules.js +114 -0
  29. package/open-sse/config/providerFieldStrips.js +35 -0
  30. package/open-sse/config/providerHeaderProfiles.js +191 -0
  31. package/open-sse/config/providerModels.js +106 -0
  32. package/open-sse/config/providerRegistry.js +16 -0
  33. package/open-sse/config/providers.js +19 -0
  34. package/open-sse/config/registryUtils.js +106 -0
  35. package/open-sse/config/rerankRegistry.js +177 -0
  36. package/open-sse/config/runtimeConfig.js +96 -0
  37. package/open-sse/config/runway.js +39 -0
  38. package/open-sse/config/searchRegistry.js +153 -0
  39. package/open-sse/config/toolCloaking.js +199 -0
  40. package/open-sse/config/ttsModels.js +129 -0
  41. package/open-sse/config/videoRegistry.js +207 -0
  42. package/open-sse/executors/adapta-web.js +435 -0
  43. package/open-sse/executors/antigravity.js +534 -0
  44. package/open-sse/executors/antigravityUpstreamError.js +13 -0
  45. package/open-sse/executors/auggie.js +437 -0
  46. package/open-sse/executors/azure-openai.js +32 -0
  47. package/open-sse/executors/azure.js +57 -0
  48. package/open-sse/executors/base.js +181 -0
  49. package/open-sse/executors/bedrock.js +633 -0
  50. package/open-sse/executors/blackbox-web.js +578 -0
  51. package/open-sse/executors/chatgpt-web.js +2042 -0
  52. package/open-sse/executors/chipotle.js +357 -0
  53. package/open-sse/executors/claude-web-with-auto-refresh.js +73 -0
  54. package/open-sse/executors/claude-web.js +586 -0
  55. package/open-sse/executors/cliproxyapi.js +296 -0
  56. package/open-sse/executors/cloudflare-ai.js +46 -0
  57. package/open-sse/executors/codebuddy-cn.js +40 -0
  58. package/open-sse/executors/codex.js +1324 -0
  59. package/open-sse/executors/commandCode.js +558 -0
  60. package/open-sse/executors/commandcode.js +88 -0
  61. package/open-sse/executors/copilot-m365-connection.js +176 -0
  62. package/open-sse/executors/copilot-m365-frames.js +192 -0
  63. package/open-sse/executors/copilot-m365-web.js +299 -0
  64. package/open-sse/executors/copilot-web.js +580 -0
  65. package/open-sse/executors/cursor.js +795 -0
  66. package/open-sse/executors/deepseek-web-with-auto-refresh.js +150 -0
  67. package/open-sse/executors/deepseek-web.js +875 -0
  68. package/open-sse/executors/default.js +430 -0
  69. package/open-sse/executors/devin-cli.js +351 -0
  70. package/open-sse/executors/doubao-web.js +550 -0
  71. package/open-sse/executors/duckduckgo-web.js +629 -0
  72. package/open-sse/executors/forceResponsesUpstream.js +33 -0
  73. package/open-sse/executors/gemini-business.js +320 -0
  74. package/open-sse/executors/gemini-cli.js +89 -0
  75. package/open-sse/executors/gemini-web.js +297 -0
  76. package/open-sse/executors/github.js +379 -0
  77. package/open-sse/executors/gitlab.js +569 -0
  78. package/open-sse/executors/glm.js +361 -0
  79. package/open-sse/executors/grok-cli.js +119 -0
  80. package/open-sse/executors/grok-web.js +345 -0
  81. package/open-sse/executors/huggingchat.js +467 -0
  82. package/open-sse/executors/iflow.js +108 -0
  83. package/open-sse/executors/index.js +78 -0
  84. package/open-sse/executors/inner-ai.js +527 -0
  85. package/open-sse/executors/kimchi.js +123 -0
  86. package/open-sse/executors/kimi-web.js +325 -0
  87. package/open-sse/executors/kimi.js +97 -0
  88. package/open-sse/executors/kiro.js +503 -0
  89. package/open-sse/executors/kiroThinking.js +44 -0
  90. package/open-sse/executors/lmarena.js +395 -0
  91. package/open-sse/executors/mimo-free.js +167 -0
  92. package/open-sse/executors/mimocode.js +392 -0
  93. package/open-sse/executors/ninerouter.js +155 -0
  94. package/open-sse/executors/nlpcloud.js +438 -0
  95. package/open-sse/executors/ollama-local.js +14 -0
  96. package/open-sse/executors/opencode-go.js +41 -0
  97. package/open-sse/executors/opencode.js +32 -0
  98. package/open-sse/executors/perplexity-web.js +581 -0
  99. package/open-sse/executors/poe-web.js +133 -0
  100. package/open-sse/executors/pollinations.js +95 -0
  101. package/open-sse/executors/puter.js +31 -0
  102. package/open-sse/executors/qoder.js +448 -0
  103. package/open-sse/executors/qwen-web.js +372 -0
  104. package/open-sse/executors/qwen.js +129 -0
  105. package/open-sse/executors/t3-chat-web.js +417 -0
  106. package/open-sse/executors/theoldllm.js +290 -0
  107. package/open-sse/executors/trae.js +418 -0
  108. package/open-sse/executors/v0-vercel-web.js +141 -0
  109. package/open-sse/executors/venice-web.js +142 -0
  110. package/open-sse/executors/vertex.js +131 -0
  111. package/open-sse/executors/vertexMedia.js +236 -0
  112. package/open-sse/executors/windsurf.js +560 -0
  113. package/open-sse/executors/xai.js +46 -0
  114. package/open-sse/executors/xiaomi-tokenplan.js +19 -0
  115. package/open-sse/executors/yuanbao-web.js +385 -0
  116. package/open-sse/executors/zed-hosted.js +281 -0
  117. package/open-sse/executors/zenmux-free.js +247 -0
  118. package/open-sse/handlers/audioSpeech.js +759 -0
  119. package/open-sse/handlers/audioTranscription.js +395 -0
  120. package/open-sse/handlers/audioTranslation.js +181 -0
  121. package/open-sse/handlers/chatCore/nonStreamingHandler.js +300 -0
  122. package/open-sse/handlers/chatCore/requestDetail.js +102 -0
  123. package/open-sse/handlers/chatCore/sseToJsonHandler.js +231 -0
  124. package/open-sse/handlers/chatCore/streamingHandler.js +95 -0
  125. package/open-sse/handlers/chatCore.js +404 -0
  126. package/open-sse/handlers/embeddingProviders/_base.js +4 -0
  127. package/open-sse/handlers/embeddingProviders/gemini.js +54 -0
  128. package/open-sse/handlers/embeddingProviders/index.js +23 -0
  129. package/open-sse/handlers/embeddingProviders/openai.js +39 -0
  130. package/open-sse/handlers/embeddingProviders/openaiCompatNode.js +13 -0
  131. package/open-sse/handlers/embeddingsCore.js +126 -0
  132. package/open-sse/handlers/fetch/index.js +237 -0
  133. package/open-sse/handlers/imageGenerationCore.js +230 -0
  134. package/open-sse/handlers/imageProviders/_base.js +31 -0
  135. package/open-sse/handlers/imageProviders/antigravity.js +73 -0
  136. package/open-sse/handlers/imageProviders/blackForestLabs.js +63 -0
  137. package/open-sse/handlers/imageProviders/cloudflareAi.js +207 -0
  138. package/open-sse/handlers/imageProviders/codex.js +217 -0
  139. package/open-sse/handlers/imageProviders/comfyui.js +25 -0
  140. package/open-sse/handlers/imageProviders/falAi.js +62 -0
  141. package/open-sse/handlers/imageProviders/gemini.js +40 -0
  142. package/open-sse/handlers/imageProviders/huggingface.js +38 -0
  143. package/open-sse/handlers/imageProviders/index.js +44 -0
  144. package/open-sse/handlers/imageProviders/leonardo.js +435 -0
  145. package/open-sse/handlers/imageProviders/nanobanana.js +79 -0
  146. package/open-sse/handlers/imageProviders/openai.js +61 -0
  147. package/open-sse/handlers/imageProviders/runwayml.js +72 -0
  148. package/open-sse/handlers/imageProviders/sdwebui.js +36 -0
  149. package/open-sse/handlers/imageProviders/stabilityAi.js +59 -0
  150. package/open-sse/handlers/imageProviders/weavy.js +222 -0
  151. package/open-sse/handlers/moderations.js +92 -0
  152. package/open-sse/handlers/ocr.js +89 -0
  153. package/open-sse/handlers/rerank.js +223 -0
  154. package/open-sse/handlers/responseSanitizer/reasoning.js +144 -0
  155. package/open-sse/handlers/responsesHandler.js +99 -0
  156. package/open-sse/handlers/search/callers.js +371 -0
  157. package/open-sse/handlers/search/chatSearch.js +409 -0
  158. package/open-sse/handlers/search/index.js +201 -0
  159. package/open-sse/handlers/search/normalizers.js +223 -0
  160. package/open-sse/handlers/search.js +1056 -0
  161. package/open-sse/handlers/sseParser.js +469 -0
  162. package/open-sse/handlers/sttCore.js +193 -0
  163. package/open-sse/handlers/ttsCore.js +74 -0
  164. package/open-sse/handlers/ttsProviders/_base.js +39 -0
  165. package/open-sse/handlers/ttsProviders/edgeTts.js +89 -0
  166. package/open-sse/handlers/ttsProviders/elevenlabs.js +48 -0
  167. package/open-sse/handlers/ttsProviders/gemini.js +117 -0
  168. package/open-sse/handlers/ttsProviders/genericFormats.js +169 -0
  169. package/open-sse/handlers/ttsProviders/googleTts.js +54 -0
  170. package/open-sse/handlers/ttsProviders/index.js +50 -0
  171. package/open-sse/handlers/ttsProviders/localDevice.js +87 -0
  172. package/open-sse/handlers/ttsProviders/minimax.js +59 -0
  173. package/open-sse/handlers/ttsProviders/openai.js +30 -0
  174. package/open-sse/handlers/ttsProviders/openrouter.js +70 -0
  175. package/open-sse/handlers/usageExtractor.js +93 -0
  176. package/open-sse/handlers/videoGenerationCore.js +119 -0
  177. package/open-sse/handlers/videoProviders/index.js +22 -0
  178. package/open-sse/handlers/videoProviders/leonardo.js +511 -0
  179. package/open-sse/handlers/videoProviders/weavy.js +198 -0
  180. package/open-sse/handlers/webFetch.js +200 -0
  181. package/open-sse/index.js +79 -0
  182. package/open-sse/mcp-server/audit.js +283 -0
  183. package/open-sse/mcp-server/catalog.js +184 -0
  184. package/open-sse/mcp-server/descriptionCompressor.js +175 -0
  185. package/open-sse/mcp-server/httpAuthContext.js +32 -0
  186. package/open-sse/mcp-server/httpTransport.js +229 -0
  187. package/open-sse/mcp-server/index.js +33 -0
  188. package/open-sse/mcp-server/mcpCallerIdentity.js +21 -0
  189. package/open-sse/mcp-server/runtimeHeartbeat.js +110 -0
  190. package/open-sse/mcp-server/schemas/a2a.js +153 -0
  191. package/open-sse/mcp-server/schemas/audit.js +17 -0
  192. package/open-sse/mcp-server/schemas/index.js +166 -0
  193. package/open-sse/mcp-server/schemas/pickFastestModel.js +90 -0
  194. package/open-sse/mcp-server/schemas/toolDefinition.js +0 -0
  195. package/open-sse/mcp-server/schemas/toolSearch.js +32 -0
  196. package/open-sse/mcp-server/schemas/tools.js +1219 -0
  197. package/open-sse/mcp-server/scopeEnforcement.js +80 -0
  198. package/open-sse/mcp-server/server.js +1168 -0
  199. package/open-sse/mcp-server/toolCardinality.js +78 -0
  200. package/open-sse/mcp-server/toolSearch/catalog.js +66 -0
  201. package/open-sse/mcp-server/toolSearch/handler.js +20 -0
  202. package/open-sse/mcp-server/toolSearch/index.js +10 -0
  203. package/open-sse/mcp-server/toolSearch/register.js +21 -0
  204. package/open-sse/mcp-server/toolSearch/search.js +55 -0
  205. package/open-sse/mcp-server/toolSearch/signature.js +67 -0
  206. package/open-sse/mcp-server/tools/advancedTools.js +893 -0
  207. package/open-sse/mcp-server/tools/agentSkillTools.js +69 -0
  208. package/open-sse/mcp-server/tools/compressionTools.js +309 -0
  209. package/open-sse/mcp-server/tools/gamificationTools.js +134 -0
  210. package/open-sse/mcp-server/tools/githubSkillTools.js +102 -0
  211. package/open-sse/mcp-server/tools/memoryTools.js +118 -0
  212. package/open-sse/mcp-server/tools/notionTools.js +101 -0
  213. package/open-sse/mcp-server/tools/obsidianTools.js +307 -0
  214. package/open-sse/mcp-server/tools/pickFastestModel.js +223 -0
  215. package/open-sse/mcp-server/tools/pluginTools.js +181 -0
  216. package/open-sse/mcp-server/tools/poolTools.js +139 -0
  217. package/open-sse/mcp-server/tools/skillTools.js +113 -0
  218. package/open-sse/package.json +10 -0
  219. package/open-sse/providers/REGISTRY_TEMPLATE.js +98 -0
  220. package/open-sse/providers/capabilities.js +293 -0
  221. package/open-sse/providers/index.js +51 -0
  222. package/open-sse/providers/models/helpers.js +20 -0
  223. package/open-sse/providers/models/namePatterns.js +33 -0
  224. package/open-sse/providers/models/schema.js +40 -0
  225. package/open-sse/providers/pricing.js +308 -0
  226. package/open-sse/providers/registry/alicode-intl.js +30 -0
  227. package/open-sse/providers/registry/alicode.js +31 -0
  228. package/open-sse/providers/registry/anthropic.js +37 -0
  229. package/open-sse/providers/registry/antigravity.js +81 -0
  230. package/open-sse/providers/registry/assemblyai.js +38 -0
  231. package/open-sse/providers/registry/aws-polly.js +45 -0
  232. package/open-sse/providers/registry/azure.js +21 -0
  233. package/open-sse/providers/registry/black-forest-labs.js +32 -0
  234. package/open-sse/providers/registry/blackbox.js +41 -0
  235. package/open-sse/providers/registry/brave-search.js +35 -0
  236. package/open-sse/providers/registry/byteplus.js +35 -0
  237. package/open-sse/providers/registry/cartesia.js +36 -0
  238. package/open-sse/providers/registry/cerebras.js +31 -0
  239. package/open-sse/providers/registry/chutes.js +24 -0
  240. package/open-sse/providers/registry/claude.js +87 -0
  241. package/open-sse/providers/registry/cline.js +51 -0
  242. package/open-sse/providers/registry/clinepass.js +57 -0
  243. package/open-sse/providers/registry/cloudflare-ai.js +55 -0
  244. package/open-sse/providers/registry/codebuddy-cn.js +77 -0
  245. package/open-sse/providers/registry/codex.js +100 -0
  246. package/open-sse/providers/registry/cohere.js +27 -0
  247. package/open-sse/providers/registry/comfyui.js +20 -0
  248. package/open-sse/providers/registry/commandcode.js +43 -0
  249. package/open-sse/providers/registry/coqui.js +30 -0
  250. package/open-sse/providers/registry/cursor.js +58 -0
  251. package/open-sse/providers/registry/deepgram.js +33 -0
  252. package/open-sse/providers/registry/deepseek.js +51 -0
  253. package/open-sse/providers/registry/digitalocean.js +92 -0
  254. package/open-sse/providers/registry/edge-tts.js +24 -0
  255. package/open-sse/providers/registry/elevenlabs.js +35 -0
  256. package/open-sse/providers/registry/exa.js +50 -0
  257. package/open-sse/providers/registry/fal-ai.js +34 -0
  258. package/open-sse/providers/registry/featherless.js +34 -0
  259. package/open-sse/providers/registry/firecrawl.js +34 -0
  260. package/open-sse/providers/registry/fireworks.js +29 -0
  261. package/open-sse/providers/registry/gemini-cli.js +58 -0
  262. package/open-sse/providers/registry/gemini.js +83 -0
  263. package/open-sse/providers/registry/github.js +88 -0
  264. package/open-sse/providers/registry/gitlab.js +32 -0
  265. package/open-sse/providers/registry/glm-cn.js +35 -0
  266. package/open-sse/providers/registry/glm.js +58 -0
  267. package/open-sse/providers/registry/google-pse.js +35 -0
  268. package/open-sse/providers/registry/google-tts.js +24 -0
  269. package/open-sse/providers/registry/grok-cli.js +86 -0
  270. package/open-sse/providers/registry/grok-web.js +39 -0
  271. package/open-sse/providers/registry/groq.js +37 -0
  272. package/open-sse/providers/registry/huggingface.js +34 -0
  273. package/open-sse/providers/registry/hyperbolic.js +35 -0
  274. package/open-sse/providers/registry/ibm-bob.js +27 -0
  275. package/open-sse/providers/registry/iflow.js +52 -0
  276. package/open-sse/providers/registry/index.js +210 -0
  277. package/open-sse/providers/registry/inworld.js +36 -0
  278. package/open-sse/providers/registry/jina-ai.js +42 -0
  279. package/open-sse/providers/registry/jina-reader.js +34 -0
  280. package/open-sse/providers/registry/kilocode.js +51 -0
  281. package/open-sse/providers/registry/kimchi.js +49 -0
  282. package/open-sse/providers/registry/kimi-coding.js +65 -0
  283. package/open-sse/providers/registry/kimi.js +56 -0
  284. package/open-sse/providers/registry/kiro.js +115 -0
  285. package/open-sse/providers/registry/linkup.js +34 -0
  286. package/open-sse/providers/registry/local-device.js +24 -0
  287. package/open-sse/providers/registry/mimo-free.js +24 -0
  288. package/open-sse/providers/registry/minimax-cn.js +76 -0
  289. package/open-sse/providers/registry/minimax.js +83 -0
  290. package/open-sse/providers/registry/mistral.js +34 -0
  291. package/open-sse/providers/registry/mmf.js +19 -0
  292. package/open-sse/providers/registry/nanobanana.js +35 -0
  293. package/open-sse/providers/registry/nebius.js +27 -0
  294. package/open-sse/providers/registry/nvidia.js +43 -0
  295. package/open-sse/providers/registry/ollama-local.js +19 -0
  296. package/open-sse/providers/registry/ollama.js +36 -0
  297. package/open-sse/providers/registry/openai.js +84 -0
  298. package/open-sse/providers/registry/opencode-go.js +41 -0
  299. package/open-sse/providers/registry/opencode.js +25 -0
  300. package/open-sse/providers/registry/openrouter.js +60 -0
  301. package/open-sse/providers/registry/perplexity-agent.js +49 -0
  302. package/open-sse/providers/registry/perplexity-web.js +33 -0
  303. package/open-sse/providers/registry/perplexity.js +37 -0
  304. package/open-sse/providers/registry/playht.js +36 -0
  305. package/open-sse/providers/registry/qoder.js +54 -0
  306. package/open-sse/providers/registry/qwen.js +33 -0
  307. package/open-sse/providers/registry/recraft.js +24 -0
  308. package/open-sse/providers/registry/runwayml.js +30 -0
  309. package/open-sse/providers/registry/sdwebui.js +20 -0
  310. package/open-sse/providers/registry/searchapi.js +35 -0
  311. package/open-sse/providers/registry/searxng.js +35 -0
  312. package/open-sse/providers/registry/serper.js +35 -0
  313. package/open-sse/providers/registry/siliconflow.js +39 -0
  314. package/open-sse/providers/registry/stability-ai.js +31 -0
  315. package/open-sse/providers/registry/tavily.js +50 -0
  316. package/open-sse/providers/registry/together.js +31 -0
  317. package/open-sse/providers/registry/topaz.js +19 -0
  318. package/open-sse/providers/registry/tortoise.js +30 -0
  319. package/open-sse/providers/registry/venice.js +56 -0
  320. package/open-sse/providers/registry/vercel-ai-gateway.js +41 -0
  321. package/open-sse/providers/registry/vertex-partner.js +29 -0
  322. package/open-sse/providers/registry/vertex.js +32 -0
  323. package/open-sse/providers/registry/volcengine-ark.js +35 -0
  324. package/open-sse/providers/registry/voyage-ai.js +30 -0
  325. package/open-sse/providers/registry/xai.js +45 -0
  326. package/open-sse/providers/registry/xiaomi-mimo.js +46 -0
  327. package/open-sse/providers/registry/xiaomi-tokenplan.js +63 -0
  328. package/open-sse/providers/registry/youcom.js +35 -0
  329. package/open-sse/providers/schema.js +76 -0
  330. package/open-sse/providers/shared.js +74 -0
  331. package/open-sse/providers/thinkingLevels.js +48 -0
  332. package/open-sse/rtk/applyFilter.js +15 -0
  333. package/open-sse/rtk/autodetect.js +111 -0
  334. package/open-sse/rtk/caveman.js +100 -0
  335. package/open-sse/rtk/cavemanPrompts.js +78 -0
  336. package/open-sse/rtk/constants.js +55 -0
  337. package/open-sse/rtk/filters/buildOutput.js +127 -0
  338. package/open-sse/rtk/filters/dedupLog.js +44 -0
  339. package/open-sse/rtk/filters/find.js +50 -0
  340. package/open-sse/rtk/filters/gitDiff.js +92 -0
  341. package/open-sse/rtk/filters/gitLog.js +99 -0
  342. package/open-sse/rtk/filters/gitStatus.js +117 -0
  343. package/open-sse/rtk/filters/grep.js +48 -0
  344. package/open-sse/rtk/filters/ls.js +79 -0
  345. package/open-sse/rtk/filters/readNumbered.js +27 -0
  346. package/open-sse/rtk/filters/searchList.js +52 -0
  347. package/open-sse/rtk/filters/smartTruncate.js +15 -0
  348. package/open-sse/rtk/filters/tree.js +32 -0
  349. package/open-sse/rtk/headroom.js +215 -0
  350. package/open-sse/rtk/index.js +155 -0
  351. package/open-sse/rtk/paleo.js +47 -0
  352. package/open-sse/rtk/ponytail.js +9 -0
  353. package/open-sse/rtk/ponytailPrompt.js +52 -0
  354. package/open-sse/rtk/ponytailPrompts.js +76 -0
  355. package/open-sse/rtk/pxpipe.js +104 -0
  356. package/open-sse/rtk/registry.js +38 -0
  357. package/open-sse/rtk/systemInject.js +98 -0
  358. package/open-sse/services/accountFallback.js +323 -0
  359. package/open-sse/services/antigravityHeaders.js +91 -0
  360. package/open-sse/services/antigravityVersion.js +154 -0
  361. package/open-sse/services/clinepassModels.js +63 -0
  362. package/open-sse/services/codexQuotaFetcher.js +312 -0
  363. package/open-sse/services/codexVerbosity.js +30 -0
  364. package/open-sse/services/combo/context.js +12 -0
  365. package/open-sse/services/combo/fingerprintExpansion.js +51 -0
  366. package/open-sse/services/combo/headroomRanking.js +28 -0
  367. package/open-sse/services/combo/quotaExhaustionCutoff.js +87 -0
  368. package/open-sse/services/combo/quotaScoring.js +226 -0
  369. package/open-sse/services/combo/quotaShareConcurrency.js +25 -0
  370. package/open-sse/services/combo/quotaShareInflight.js +50 -0
  371. package/open-sse/services/combo/quotaShareStrategy.js +130 -0
  372. package/open-sse/services/combo/resolveAutoStrategy.js +231 -0
  373. package/open-sse/services/combo/responseValidation.js +140 -0
  374. package/open-sse/services/combo/runtimeUnits.js +195 -0
  375. package/open-sse/services/combo/sessionStickiness.js +128 -0
  376. package/open-sse/services/combo/shadowRouting.js +131 -0
  377. package/open-sse/services/combo/targetExhaustion.js +75 -0
  378. package/open-sse/services/combo/targetSorters.js +126 -0
  379. package/open-sse/services/combo/targetTimeoutRunner.js +65 -0
  380. package/open-sse/services/combo/validateQuality.js +271 -0
  381. package/open-sse/services/combo.js +571 -0
  382. package/open-sse/services/comboAgentMiddleware.js +91 -0
  383. package/open-sse/services/comboConfig.js +153 -0
  384. package/open-sse/services/comboManifestMetrics.js +10 -0
  385. package/open-sse/services/comboMetrics.js +278 -0
  386. package/open-sse/services/compact.js +71 -0
  387. package/open-sse/services/copilotModels.js +155 -0
  388. package/open-sse/services/emergencyFallback.js +109 -0
  389. package/open-sse/services/errorClassifier.js +190 -0
  390. package/open-sse/services/evalRouting.js +201 -0
  391. package/open-sse/services/freeWebSearch.js +4 -0
  392. package/open-sse/services/fusion.js +223 -0
  393. package/open-sse/services/intentClassifier.js +631 -0
  394. package/open-sse/services/kimchiModels.js +176 -0
  395. package/open-sse/services/kiroModels.js +332 -0
  396. package/open-sse/services/model.js +136 -0
  397. package/open-sse/services/modelCapabilities.js +5 -0
  398. package/open-sse/services/modelDeprecation.js +101 -0
  399. package/open-sse/services/modelFamilyFallback.js +166 -0
  400. package/open-sse/services/oauthCredentialManager.js +156 -0
  401. package/open-sse/services/pipeline.js +107 -0
  402. package/open-sse/services/projectId.js +306 -0
  403. package/open-sse/services/provider.js +169 -0
  404. package/open-sse/services/providerCooldownTracker.js +94 -0
  405. package/open-sse/services/providerDefaultRateLimit.js +11 -0
  406. package/open-sse/services/proxyAutoSelector.js +24 -0
  407. package/open-sse/services/qoderModels.js +214 -0
  408. package/open-sse/services/quotaFetchThrottle.js +103 -0
  409. package/open-sse/services/quotaMonitor.js +310 -0
  410. package/open-sse/services/quotaPreflight.js +266 -0
  411. package/open-sse/services/rateLimitManager/headers.js +56 -0
  412. package/open-sse/services/rateLimitManager.js +616 -0
  413. package/open-sse/services/rateLimitSemaphore.js +112 -0
  414. package/open-sse/services/responsesInputSanitizer.js +99 -0
  415. package/open-sse/services/slidingWindowLimiter.js +44 -0
  416. package/open-sse/services/streamRecovery.js +355 -0
  417. package/open-sse/services/taskAwareRouter.js +227 -0
  418. package/open-sse/services/taskAwareRouting.js +332 -0
  419. package/open-sse/services/thinkingBudget.js +247 -0
  420. package/open-sse/services/tokenRefresh/dedup.js +31 -0
  421. package/open-sse/services/tokenRefresh/providers.js +624 -0
  422. package/open-sse/services/tokenRefresh.js +254 -0
  423. package/open-sse/services/usage/claude.js +147 -0
  424. package/open-sse/services/usage/codebuddy-cn.js +138 -0
  425. package/open-sse/services/usage/codex.js +267 -0
  426. package/open-sse/services/usage/github.js +100 -0
  427. package/open-sse/services/usage/google.js +241 -0
  428. package/open-sse/services/usage/grok-cli.js +274 -0
  429. package/open-sse/services/usage/kiro.js +188 -0
  430. package/open-sse/services/usage/minimax.js +234 -0
  431. package/open-sse/services/usage/misc.js +288 -0
  432. package/open-sse/services/usage/shared.js +70 -0
  433. package/open-sse/services/usage.js +62 -0
  434. package/open-sse/services/usageDb.js +2 -0
  435. package/open-sse/services/webSearchRouting.js +25 -0
  436. package/open-sse/services/wildcardRouter.js +59 -0
  437. package/open-sse/shared/clineAuth.js +37 -0
  438. package/open-sse/shared/machineId.js +19 -0
  439. package/open-sse/shared/qoder/constants.js +64 -0
  440. package/open-sse/shared/qoder/cosy.js +175 -0
  441. package/open-sse/shared/qoder/encoding.js +55 -0
  442. package/open-sse/transformer/responsesTransformer.js +439 -0
  443. package/open-sse/transformer/streamToJsonConverter.js +103 -0
  444. package/open-sse/translator/concerns/chunk.js +11 -0
  445. package/open-sse/translator/concerns/finishReason.js +63 -0
  446. package/open-sse/translator/concerns/image.js +124 -0
  447. package/open-sse/translator/concerns/json.js +5 -0
  448. package/open-sse/translator/concerns/message.js +7 -0
  449. package/open-sse/translator/concerns/modality.js +155 -0
  450. package/open-sse/translator/concerns/paramSupport.js +75 -0
  451. package/open-sse/translator/concerns/prefetch.js +96 -0
  452. package/open-sse/translator/concerns/reasoning.js +24 -0
  453. package/open-sse/translator/concerns/thinking.js +53 -0
  454. package/open-sse/translator/concerns/thinkingUnified.js +329 -0
  455. package/open-sse/translator/concerns/toolCall.js +153 -0
  456. package/open-sse/translator/concerns/usage.js +69 -0
  457. package/open-sse/translator/formats/claude.js +368 -0
  458. package/open-sse/translator/formats/gemini.js +380 -0
  459. package/open-sse/translator/formats/maxTokens.js +34 -0
  460. package/open-sse/translator/formats/openai.js +134 -0
  461. package/open-sse/translator/formats/responsesApi.js +141 -0
  462. package/open-sse/translator/formats.js +36 -0
  463. package/open-sse/translator/helpers/claudeHelper.js +216 -0
  464. package/open-sse/translator/helpers/geminiHelper.js +372 -0
  465. package/open-sse/translator/helpers/imageHelper.js +34 -0
  466. package/open-sse/translator/helpers/maxTokensHelper.js +27 -0
  467. package/open-sse/translator/helpers/openaiHelper.js +130 -0
  468. package/open-sse/translator/helpers/responsesApiHelper.js +139 -0
  469. package/open-sse/translator/helpers/toolCallHelper.js +148 -0
  470. package/open-sse/translator/index.js +252 -0
  471. package/open-sse/translator/request/antigravity-to-openai.js +242 -0
  472. package/open-sse/translator/request/claude-to-kiro.js +478 -0
  473. package/open-sse/translator/request/claude-to-openai.js +263 -0
  474. package/open-sse/translator/request/gemini-to-openai.js +152 -0
  475. package/open-sse/translator/request/openai-responses.js +385 -0
  476. package/open-sse/translator/request/openai-to-claude.js +383 -0
  477. package/open-sse/translator/request/openai-to-commandcode.js +176 -0
  478. package/open-sse/translator/request/openai-to-cursor.js +185 -0
  479. package/open-sse/translator/request/openai-to-gemini.js +442 -0
  480. package/open-sse/translator/request/openai-to-kiro.js +607 -0
  481. package/open-sse/translator/request/openai-to-kiro.old.js +278 -0
  482. package/open-sse/translator/request/openai-to-ollama.js +195 -0
  483. package/open-sse/translator/request/openai-to-vertex.js +42 -0
  484. package/open-sse/translator/response/claude-to-openai.js +195 -0
  485. package/open-sse/translator/response/commandcode-to-openai.js +188 -0
  486. package/open-sse/translator/response/cursor-to-openai.js +30 -0
  487. package/open-sse/translator/response/gemini-to-openai.js +147 -0
  488. package/open-sse/translator/response/kiro-to-claude.js +261 -0
  489. package/open-sse/translator/response/kiro-to-openai.js +160 -0
  490. package/open-sse/translator/response/ollama-to-openai.js +134 -0
  491. package/open-sse/translator/response/openai-responses.js +535 -0
  492. package/open-sse/translator/response/openai-to-antigravity.js +123 -0
  493. package/open-sse/translator/response/openai-to-claude.js +265 -0
  494. package/open-sse/translator/schema/blocks.js +43 -0
  495. package/open-sse/translator/schema/defaults.js +7 -0
  496. package/open-sse/translator/schema/finishReasons.js +27 -0
  497. package/open-sse/translator/schema/index.js +8 -0
  498. package/open-sse/translator/schema/roles.js +16 -0
  499. package/open-sse/utils/agentGoalPolicy.js +85 -0
  500. package/open-sse/utils/aiSdkCompat.js +75 -0
  501. package/open-sse/utils/bypassHandler.js +298 -0
  502. package/open-sse/utils/cacheControlPolicy.js +189 -0
  503. package/open-sse/utils/claudeCloaking.js +155 -0
  504. package/open-sse/utils/claudeHeaderCache.js +70 -0
  505. package/open-sse/utils/claudeSignature.js +41 -0
  506. package/open-sse/utils/clientDetector.js +63 -0
  507. package/open-sse/utils/codebuddySanitizer.js +96 -0
  508. package/open-sse/utils/composerToolCalls.js +158 -0
  509. package/open-sse/utils/cors.js +13 -0
  510. package/open-sse/utils/cursorChecksum.js +149 -0
  511. package/open-sse/utils/cursorImages.js +224 -0
  512. package/open-sse/utils/cursorProtobuf.js +904 -0
  513. package/open-sse/utils/cursorVersionDetector.js +55 -0
  514. package/open-sse/utils/debugLog.js +14 -0
  515. package/open-sse/utils/diagnostics.js +143 -0
  516. package/open-sse/utils/error.js +164 -0
  517. package/open-sse/utils/estimateSize.js +33 -0
  518. package/open-sse/utils/finishReason.js +32 -0
  519. package/open-sse/utils/flattenToolHistory.js +68 -0
  520. package/open-sse/utils/headers.js +36 -0
  521. package/open-sse/utils/heapPressure.js +35 -0
  522. package/open-sse/utils/jsonToSse.js +125 -0
  523. package/open-sse/utils/keepaliveThreshold.js +40 -0
  524. package/open-sse/utils/logger.js +104 -0
  525. package/open-sse/utils/noThinkingAlias.js +74 -0
  526. package/open-sse/utils/number.js +7 -0
  527. package/open-sse/utils/ollamaTransform.js +85 -0
  528. package/open-sse/utils/opencodeHeaders.js +47 -0
  529. package/open-sse/utils/progressTracker.js +81 -0
  530. package/open-sse/utils/providerRequestLogging.js +219 -0
  531. package/open-sse/utils/proxyFetch.js +369 -0
  532. package/open-sse/utils/reasoningContentInjector.js +79 -0
  533. package/open-sse/utils/reasoningFields.js +70 -0
  534. package/open-sse/utils/requestLogger.js +260 -0
  535. package/open-sse/utils/responsesInputNormalization.js +92 -0
  536. package/open-sse/utils/responsesStatePolicy.js +52 -0
  537. package/open-sse/utils/responsesStreamHelpers.js +49 -0
  538. package/open-sse/utils/sessionManager.js +240 -0
  539. package/open-sse/utils/sleep.js +6 -0
  540. package/open-sse/utils/sse.js +14 -0
  541. package/open-sse/utils/sseConstants.js +23 -0
  542. package/open-sse/utils/sseHeartbeat.js +104 -0
  543. package/open-sse/utils/stream.js +517 -0
  544. package/open-sse/utils/streamFailureFinalization.js +134 -0
  545. package/open-sse/utils/streamHandler.js +250 -0
  546. package/open-sse/utils/streamHelpers.js +137 -0
  547. package/open-sse/utils/textualToolCall.js +104 -0
  548. package/open-sse/utils/thinkCloseMarker.js +72 -0
  549. package/open-sse/utils/thinkTagParser.js +146 -0
  550. package/open-sse/utils/toolCallArguments.js +12 -0
  551. package/open-sse/utils/toolDeduper.js +49 -0
  552. package/open-sse/utils/toolSources.js +31 -0
  553. package/open-sse/utils/upstreamResponseHeaders.js +25 -0
  554. package/open-sse/utils/urlSanitize.js +15 -0
  555. package/open-sse/utils/usageTracking.js +347 -0
  556. package/package.json +1 -1
@@ -0,0 +1,223 @@
1
+ /**
2
+ * Rerank Handler
3
+ *
4
+ * Handles /v1/rerank requests following the Cohere rerank API format.
5
+ * Routes to the appropriate provider based on the model prefix or lookup.
6
+ * Converted from OmniRoute TypeScript.
7
+ */
8
+
9
+ const CORS_HEADERS = {
10
+ "Access-Control-Allow-Origin": "*",
11
+ "Access-Control-Allow-Methods": "GET, POST, PUT, DELETE, OPTIONS",
12
+ "Access-Control-Allow-Headers": "Content-Type, Authorization",
13
+ };
14
+
15
+ import { errorResponse } from "../utils/error.js";
16
+ import { RERANK_PROVIDERS, parseRerankModel, getRerankProvider } from "../config/rerankRegistry.js";
17
+
18
+ // ── Inline stubs for @/ imports ──────────────────────────────────────
19
+ function attachOmniRouteMetaHeaders(headers, meta) {
20
+ if (meta.provider) headers.set("X-Provider", meta.provider);
21
+ if (meta.model) headers.set("X-Model", meta.model);
22
+ if (meta.latencyMs != null) headers.set("X-Latency-Ms", String(meta.latencyMs));
23
+ }
24
+
25
+ function generateRequestId() {
26
+ return crypto.randomUUID();
27
+ }
28
+
29
+ async function calculateModalCost(_type, _provider, _model, _opts) {
30
+ return 0;
31
+ }
32
+
33
+ async function saveCallLog(_entry) {
34
+ // noop stub — wire up to actual logging when available
35
+ }
36
+
37
+ // ── Helpers ──────────────────────────────────────────────────────────
38
+
39
+ /**
40
+ * Build authorization header for a rerank provider
41
+ */
42
+ function buildAuthHeader(providerConfig, token) {
43
+ if (providerConfig.authHeader === "bearer") {
44
+ return { Authorization: `Bearer ${token}` };
45
+ }
46
+ return {};
47
+ }
48
+
49
+ /**
50
+ * Transform request body for provider-specific formats (e.g. NVIDIA ranking API)
51
+ */
52
+ export function transformRequestForProvider(providerConfig, body) {
53
+ if (providerConfig.format === "nvidia") {
54
+ return {
55
+ model: body.model,
56
+ query: { text: body.query },
57
+ passages: (body.documents || []).map((doc) => ({
58
+ text: typeof doc === "string" ? doc : doc.text || "",
59
+ })),
60
+ top_n: body.top_n,
61
+ };
62
+ }
63
+ // DeepInfra inference API: the model goes in the URL path (handled by the caller), the body
64
+ // carries {queries:[query], documents:[strings]} and the response is a positional {scores:[…]}.
65
+ if (providerConfig.format === "deepinfra") {
66
+ return {
67
+ queries: [body.query],
68
+ documents: (body.documents || []).map((doc) =>
69
+ typeof doc === "string" ? doc : doc.text || ""
70
+ ),
71
+ };
72
+ }
73
+ // Default: Cohere-compatible format (used by Together, Fireworks, Cohere, SiliconFlow)
74
+ return body;
75
+ }
76
+
77
+ /**
78
+ * Transform response from provider-specific formats back to Cohere format
79
+ */
80
+ export function transformResponseFromProvider(providerConfig, data, options = {}) {
81
+ if (providerConfig.format === "nvidia") {
82
+ return {
83
+ id: data.id != null ? String(data.id) : `rerank-${Date.now()}`,
84
+ results: (data.rankings || []).map((r) => ({
85
+ index: r.index,
86
+ relevance_score: r.logit || r.score || 0,
87
+ document: { text: r.text || "" },
88
+ })),
89
+ meta: {
90
+ api_version: { version: "2" },
91
+ billed_units: { search_units: 1 },
92
+ },
93
+ };
94
+ }
95
+ // DeepInfra returns {scores:[…]} — one float per document, in document order. Map to Cohere's
96
+ // results[] (index + relevance_score + optional document), sorted by score desc, honoring top_n.
97
+ if (providerConfig.format === "deepinfra") {
98
+ const documents = Array.isArray(options.documents) ? options.documents : [];
99
+ const returnDocuments = options.return_documents !== false;
100
+ const scored = (Array.isArray(data.scores) ? data.scores : []).map((score, index) => {
101
+ const doc = documents[index];
102
+ const text = typeof doc === "string" ? doc : doc?.text || "";
103
+ return {
104
+ index,
105
+ relevance_score: typeof score === "number" ? score : 0,
106
+ ...(returnDocuments ? { document: { text } } : {}),
107
+ };
108
+ });
109
+ scored.sort((a, b) => b.relevance_score - a.relevance_score);
110
+ const topN = typeof options.top_n === "number" && options.top_n > 0 ? options.top_n : undefined;
111
+ return {
112
+ id: `rerank-${Date.now()}`,
113
+ results: topN ? scored.slice(0, topN) : scored,
114
+ meta: {
115
+ api_version: { version: "2" },
116
+ billed_units: { search_units: 1 },
117
+ },
118
+ };
119
+ }
120
+ return data;
121
+ }
122
+
123
+ /**
124
+ * Handle a rerank request
125
+ */
126
+ export async function handleRerank({
127
+ model,
128
+ query,
129
+ documents,
130
+ top_n,
131
+ return_documents,
132
+ credentials,
133
+ }) {
134
+ const startTime = Date.now();
135
+ if (!model) return errorResponse(400, "model is required");
136
+ if (!query) return errorResponse(400, "query is required");
137
+ if (!documents || !Array.isArray(documents) || documents.length === 0) {
138
+ return errorResponse(400, "documents must be a non-empty array");
139
+ }
140
+
141
+ const { provider: providerId, model: modelId } = parseRerankModel(model);
142
+ const providerConfig = providerId ? getRerankProvider(providerId) : null;
143
+
144
+ if (!providerConfig) {
145
+ const availableProviders = Object.keys(RERANK_PROVIDERS).join(", ");
146
+ return errorResponse(
147
+ 400,
148
+ `No rerank provider found for model "${model}". Available: ${availableProviders}`
149
+ );
150
+ }
151
+
152
+ const token = credentials?.apiKey || credentials?.accessToken;
153
+ if (!token) {
154
+ return errorResponse(401, `No credentials for rerank provider: ${providerId}`);
155
+ }
156
+
157
+ const requestBody = transformRequestForProvider(providerConfig, {
158
+ model: modelId,
159
+ query,
160
+ documents,
161
+ top_n: top_n || documents.length,
162
+ return_documents: return_documents !== false,
163
+ });
164
+
165
+ // DeepInfra puts the model in the URL path (POST /v1/inference/<model>); all others use a fixed
166
+ // rerank endpoint with the model in the body.
167
+ const rerankUrl =
168
+ providerConfig.format === "deepinfra"
169
+ ? `${providerConfig.baseUrl}/${modelId}`
170
+ : providerConfig.baseUrl;
171
+
172
+ try {
173
+ const res = await fetch(rerankUrl, {
174
+ method: "POST",
175
+ headers: {
176
+ "Content-Type": "application/json",
177
+ ...buildAuthHeader(providerConfig, token),
178
+ },
179
+ body: JSON.stringify(requestBody),
180
+ });
181
+
182
+ if (!res.ok) {
183
+ const errData = await res.json().catch(() => ({}));
184
+ return errorResponse(
185
+ res.status,
186
+ errData.message || errData.error?.message || `Provider returned HTTP ${res.status}`
187
+ );
188
+ }
189
+
190
+ const data = await res.json();
191
+ const result = transformResponseFromProvider(providerConfig, data, {
192
+ documents,
193
+ top_n: top_n || documents.length,
194
+ return_documents,
195
+ });
196
+
197
+ const searchUnits = Number(result?.meta?.billed_units?.search_units) || 0;
198
+ const costUsd = await calculateModalCost("rerank", providerId, modelId, { searchUnits });
199
+
200
+ saveCallLog({
201
+ method: "POST",
202
+ path: "/v1/rerank",
203
+ status: 200,
204
+ model: `${providerId}/${modelId}`,
205
+ provider: providerId,
206
+ duration: Date.now() - startTime,
207
+ tokens: { prompt_tokens: 0, completion_tokens: 0 },
208
+ responseBody: { results_count: Array.isArray(result?.results) ? result.results.length : 0 },
209
+ }).catch(() => {});
210
+
211
+ const headers = new Headers({ ...CORS_HEADERS, "Content-Type": "application/json" });
212
+ attachOmniRouteMetaHeaders(headers, {
213
+ provider: providerId,
214
+ model: modelId,
215
+ costUsd,
216
+ latencyMs: Date.now() - startTime,
217
+ requestId: generateRequestId(),
218
+ });
219
+ return new Response(JSON.stringify(result), { status: 200, headers });
220
+ } catch (err) {
221
+ return errorResponse(500, `Rerank request failed: ${err.message}`);
222
+ }
223
+ }
@@ -0,0 +1,144 @@
1
+ export const REASONING_TAG_NAMES = ["think", "thinking", "thought", "internal_thought"];
2
+ export const REASONING_TAG_PATTERN = REASONING_TAG_NAMES.join("|");
3
+ // Matches complete <think>/<thinking>/<thought>/<internal_thought> blocks.
4
+ export const THINK_TAG_REGEX = new RegExp(
5
+ `<(${REASONING_TAG_PATTERN})\\b[^>]*>([\\s\\S]*?)<\\/\\1>`,
6
+ "gi"
7
+ );
8
+ export const REASONING_CLOSE_TAG_REGEX = new RegExp(`</(${REASONING_TAG_PATTERN})>`, "i");
9
+ export const REASONING_TAG_FRAGMENT_REGEX = new RegExp(
10
+ `</?(${REASONING_TAG_PATTERN})\\b[^>]*>`,
11
+ "gi"
12
+ );
13
+ export const CONTENT_OPEN_TAG_REGEX = /<content\b[^>]*>/i;
14
+ // Matches an unclosed reasoning tag at the end of a message. Some providers can
15
+ // emit malformed/open reasoning wrappers (for example "<thought\n...") before a
16
+ // tool call. Treat that tail as reasoning instead of visible assistant text.
17
+ export const UNCLOSED_REASONING_TAG_REGEX = new RegExp(
18
+ `<(${REASONING_TAG_PATTERN})(?:\\s[^>]*)?(?:>|\\r?\\n)([\\s\\S]*)$`,
19
+ "i"
20
+ );
21
+
22
+ // #638, #727: Collapse runs of 2+ consecutive newlines into \n\n
23
+
24
+ // Tool call responses from thinking models often accumulate excessive newlines
25
+ export const EXCESSIVE_NEWLINES = /\n{2,}/g;
26
+ export function collapseExcessiveNewlines(text) {
27
+ return text.replace(EXCESSIVE_NEWLINES, "\n\n");
28
+ }
29
+
30
+ export function cleanReasoningFragment(text) {
31
+ return text.replace(REASONING_TAG_FRAGMENT_REGEX, "").trim();
32
+ }
33
+
34
+ export function splitClosingOnlyReasoningPrefix(text) {
35
+ const closeMatch = text.match(REASONING_CLOSE_TAG_REGEX);
36
+ if (!closeMatch || closeMatch.index === undefined || closeMatch.index === 0) return null;
37
+ const closeIndex = closeMatch.index;
38
+
39
+ const suffix = text.slice(closeIndex + closeMatch[0].length);
40
+ if (!CONTENT_OPEN_TAG_REGEX.test(suffix)) return null;
41
+
42
+ const thinking = cleanReasoningFragment(text.slice(0, closeIndex));
43
+ if (!thinking) return null;
44
+ return { content: suffix.trim(), thinking };
45
+ }
46
+
47
+ export function movePrefixBeforeContentTagToThinking(
48
+ cleaned,
49
+ thinkingParts
50
+ ) {
51
+ const contentMatch = cleaned.match(CONTENT_OPEN_TAG_REGEX);
52
+ if (!contentMatch || contentMatch.index === undefined || contentMatch.index <= 0) return cleaned;
53
+ const contentIndex = contentMatch.index;
54
+
55
+ const prefix = cleanReasoningFragment(cleaned.slice(0, contentIndex));
56
+ if (prefix) thinkingParts.unshift(prefix);
57
+ return cleaned.slice(contentIndex);
58
+ }
59
+
60
+ /**
61
+ * Extract <think> blocks from text content and return separated parts.
62
+ * @returns {{ content: string, thinking: string | null }}
63
+ */
64
+ export function extractThinkingFromContent(text) {
65
+ if (!text || typeof text !== "string") {
66
+ return { content: text || "", thinking: null };
67
+ }
68
+
69
+ const thinkingParts = [];
70
+ let hasThinkTags = false;
71
+
72
+ let cleaned = text.replace(THINK_TAG_REGEX, (_match, _tagName, thinkContent) => {
73
+ hasThinkTags = true;
74
+ const trimmed = thinkContent.trim();
75
+ if (trimmed) {
76
+ thinkingParts.push(trimmed);
77
+ }
78
+ return "";
79
+ });
80
+
81
+ if (!hasThinkTags) {
82
+ const closingOnly = splitClosingOnlyReasoningPrefix(cleaned);
83
+ if (closingOnly) {
84
+ return closingOnly;
85
+ }
86
+ }
87
+
88
+ const unclosedMatch = cleaned.match(UNCLOSED_REASONING_TAG_REGEX);
89
+ if (unclosedMatch?.index !== undefined) {
90
+ hasThinkTags = true;
91
+ const reasoning = String(unclosedMatch[2] || "").trim();
92
+ if (reasoning) thinkingParts.push(reasoning);
93
+ const prefix = cleaned.slice(0, unclosedMatch.index);
94
+ cleaned = /^(?:\s|§\d+§)*$/.test(prefix) ? "" : prefix;
95
+ }
96
+
97
+ if (!hasThinkTags) {
98
+ return { content: text, thinking: null };
99
+ }
100
+
101
+ cleaned = movePrefixBeforeContentTagToThinking(cleaned, thinkingParts);
102
+
103
+ return {
104
+ content: cleaned.trim(),
105
+ thinking: thinkingParts.length > 0 ? thinkingParts.join("\n\n") : null,
106
+ };
107
+ }
108
+
109
+ export function normalizeReasoningRouteId(value) {
110
+ return typeof value === "string" ? value.toLowerCase() : "";
111
+ }
112
+
113
+ export function isAntigravityReasoningRoute(providerId, modelId) {
114
+ return (
115
+ providerId.includes("antigravity") ||
116
+ providerId === "agy" ||
117
+ modelId.includes("antigravity/") ||
118
+ modelId.startsWith("agy/")
119
+ );
120
+ }
121
+
122
+ export function isTextualReasoningTagNativeRoute(providerId, modelId) {
123
+ const routeId = `${providerId}/${modelId}`;
124
+ return (
125
+ /deepseek[-_/]?r1\b/.test(routeId) ||
126
+ /r1[-_/]?distill\b/.test(routeId) ||
127
+ /(?:^|[/:_-])qwq(?:[/._:-]|$)/.test(routeId) ||
128
+ // 9router#2231: MiniMax M3 leaks raw <think>...</think> into `content` on its
129
+ // OpenAI-format provider tiers (trae, huggingchat, bazaarlink, ollama-cloud,
130
+ // opencode, cline, opencode-zen, codebuddy-cn). The direct minimax/minimax-cn
131
+ // tiers stay on Anthropic's Messages format (targetFormat: "claude") and
132
+ // already surface reasoning natively, so they are excluded here.
133
+ (providerId !== "minimax" && providerId !== "minimax-cn" && /minimax[-_]?m3\b/.test(routeId))
134
+ );
135
+ }
136
+
137
+ export function shouldParseTextualReasoningTags(provider, model) {
138
+ const providerId = normalizeReasoningRouteId(provider);
139
+ const modelId = normalizeReasoningRouteId(model);
140
+ return (
141
+ !isAntigravityReasoningRoute(providerId, modelId) &&
142
+ isTextualReasoningTagNativeRoute(providerId, modelId)
143
+ );
144
+ }
@@ -0,0 +1,99 @@
1
+ /**
2
+ * Responses API Handler for Workers
3
+ * Converts Chat Completions to Codex Responses API format
4
+ */
5
+
6
+ import { handleChatCore } from "./chatCore.js";
7
+ import { convertResponsesApiFormat } from "../translator/formats/responsesApi.js";
8
+ import { createResponsesApiTransformStream } from "../transformer/responsesTransformer.js";
9
+ import { convertResponsesStreamToJson } from "../transformer/streamToJsonConverter.js";
10
+ import { SSE_HEADERS_CORS } from "../utils/sseConstants.js";
11
+
12
+ /**
13
+ * Handle /v1/responses request
14
+ * @param {object} options
15
+ * @param {object} options.body - Request body (Responses API format)
16
+ * @param {object} options.modelInfo - { provider, model }
17
+ * @param {object} options.credentials - Provider credentials
18
+ * @param {object} options.log - Logger instance (optional)
19
+ * @param {function} options.onCredentialsRefreshed - Callback when credentials are refreshed
20
+ * @param {function} options.onRequestSuccess - Callback when request succeeds
21
+ * @param {function} options.onDisconnect - Callback when client disconnects
22
+ * @param {string} options.connectionId - Connection ID for usage tracking
23
+ * @returns {Promise<{success: boolean, response?: Response, status?: number, error?: string}>}
24
+ */
25
+ export async function handleResponsesCore({ body, modelInfo, credentials, log, onCredentialsRefreshed, onRequestSuccess, onDisconnect, connectionId }) {
26
+ // Convert Responses API format to Chat Completions format
27
+ const convertedBody = convertResponsesApiFormat(body);
28
+
29
+ // Preserve client's stream preference (matches OpenClaw behavior)
30
+ // Default to false if omitted: Boolean(undefined) = false
31
+ const clientRequestedStreaming = convertedBody.stream === true;
32
+ if (convertedBody.stream === undefined) {
33
+ convertedBody.stream = false;
34
+ }
35
+
36
+ // Call chat core handler — force sourceFormat so streaming path knows this is a Responses API client
37
+ const result = await handleChatCore({
38
+ body: convertedBody,
39
+ modelInfo,
40
+ credentials,
41
+ log,
42
+ onCredentialsRefreshed,
43
+ onRequestSuccess,
44
+ onDisconnect,
45
+ connectionId,
46
+ sourceFormatOverride: "openai-responses"
47
+ });
48
+
49
+ if (!result.success || !result.response) {
50
+ return result;
51
+ }
52
+
53
+ const response = result.response;
54
+ const contentType = response.headers.get("Content-Type") || "";
55
+
56
+ // Case 1: Client wants non-streaming, but got SSE (provider forced it, e.g., Codex)
57
+ if (!clientRequestedStreaming && contentType.includes("text/event-stream")) {
58
+ try {
59
+ const jsonResponse = await convertResponsesStreamToJson(response.body);
60
+
61
+ return {
62
+ success: true,
63
+ response: new Response(JSON.stringify(jsonResponse), {
64
+ status: 200,
65
+ headers: {
66
+ "Content-Type": "application/json",
67
+ "Cache-Control": "no-cache",
68
+ "Access-Control-Allow-Origin": "*"
69
+ }
70
+ })
71
+ };
72
+ } catch (error) {
73
+ console.error("[Responses API] Stream-to-JSON conversion failed:", error);
74
+ return {
75
+ success: false,
76
+ status: 500,
77
+ error: "Failed to convert streaming response to JSON"
78
+ };
79
+ }
80
+ }
81
+
82
+ // Case 2: Client wants streaming, got SSE - transform it
83
+ if (clientRequestedStreaming && contentType.includes("text/event-stream")) {
84
+ const transformStream = createResponsesApiTransformStream(null);
85
+ const transformedBody = response.body.pipeThrough(transformStream);
86
+
87
+ return {
88
+ success: true,
89
+ response: new Response(transformedBody, {
90
+ status: 200,
91
+ headers: { ...SSE_HEADERS_CORS }
92
+ })
93
+ };
94
+ }
95
+
96
+ // Case 3: Non-SSE response (error or non-streaming from provider) - return as-is
97
+ return result;
98
+ }
99
+