@mupt-ai/dari-gateway 0.2.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (385) hide show
  1. package/README.md +8 -4
  2. package/dist/bun.d.ts +2 -0
  3. package/dist/bun.js +4 -0
  4. package/dist/context/eval_catalog.d.ts +3 -0
  5. package/dist/context/eval_catalog.js +7 -0
  6. package/dist/context/interaction_fingerprint.d.ts +27 -0
  7. package/dist/context/interaction_fingerprint.js +519 -0
  8. package/dist/context/interaction_fingerprint_format.d.ts +42 -0
  9. package/dist/context/interaction_fingerprint_format.js +113 -0
  10. package/dist/context/interaction_lease_depth.d.ts +2 -0
  11. package/dist/context/interaction_lease_depth.js +110 -0
  12. package/dist/context/lease_history.d.ts +7 -0
  13. package/dist/context/lease_history.js +158 -0
  14. package/dist/context/pricing.d.ts +4 -0
  15. package/dist/context/pricing.js +27 -0
  16. package/dist/context/provider_prompt_accounting.d.ts +14 -0
  17. package/dist/context/provider_prompt_accounting.js +187 -0
  18. package/dist/context/routing_context.d.ts +40 -0
  19. package/dist/context/routing_context.js +211 -0
  20. package/dist/http/auth.d.ts +2 -0
  21. package/dist/http/auth.js +35 -0
  22. package/dist/http/errors.d.ts +19 -0
  23. package/dist/http/errors.js +89 -0
  24. package/dist/http/handler.d.ts +12 -0
  25. package/dist/http/handler.js +88 -0
  26. package/dist/http/http2_server.d.ts +6 -0
  27. package/dist/http/http2_server.js +103 -0
  28. package/dist/http/serve.d.ts +20 -0
  29. package/dist/http/serve.js +78 -0
  30. package/dist/index.d.ts +7 -0
  31. package/dist/index.js +9 -0
  32. package/dist/ingress/anthropic_messages.d.ts +3 -0
  33. package/dist/ingress/anthropic_messages.js +122 -0
  34. package/dist/ingress/anthropic_models.d.ts +1 -0
  35. package/dist/ingress/anthropic_models.js +23 -0
  36. package/dist/ingress/chat_completions.d.ts +2 -0
  37. package/dist/ingress/chat_completions.js +44 -0
  38. package/dist/ingress/claude_code/request_context.d.ts +2 -0
  39. package/dist/ingress/claude_code/request_context.js +31 -0
  40. package/dist/ingress/codex.d.ts +3 -0
  41. package/dist/ingress/codex.js +69 -0
  42. package/dist/ingress/codex_models.d.ts +2 -0
  43. package/dist/ingress/codex_models.js +89 -0
  44. package/dist/ingress/json.d.ts +1 -0
  45. package/dist/ingress/json.js +95 -0
  46. package/dist/ingress/models.d.ts +1 -0
  47. package/dist/ingress/models.js +65 -0
  48. package/dist/ingress/muse_code.d.ts +2 -0
  49. package/dist/ingress/muse_code.js +8 -0
  50. package/dist/ingress/muse_models.d.ts +9 -0
  51. package/dist/ingress/muse_models.js +32 -0
  52. package/dist/interaction/capabilities.d.ts +3 -0
  53. package/dist/interaction/capabilities.js +24 -0
  54. package/dist/interaction/image.d.ts +4 -0
  55. package/dist/interaction/image.js +13 -0
  56. package/dist/interaction/portable_reasoning_state.d.ts +4 -0
  57. package/dist/interaction/portable_reasoning_state.js +18 -0
  58. package/dist/interaction/provider_continuation_state.d.ts +6 -0
  59. package/dist/interaction/provider_continuation_state.js +27 -0
  60. package/dist/interaction/tool_identity.d.ts +10 -0
  61. package/dist/interaction/tool_identity.js +41 -0
  62. package/dist/interaction/types.d.ts +204 -0
  63. package/dist/interaction/types.js +5 -0
  64. package/dist/models/catalog.d.ts +35 -0
  65. package/dist/models/catalog.js +232 -0
  66. package/dist/models/context_limits.d.ts +2 -0
  67. package/dist/models/context_limits.js +7 -0
  68. package/dist/models/execution_provider.d.ts +9 -0
  69. package/dist/models/execution_provider.js +17 -0
  70. package/dist/models/gateways.d.ts +11 -0
  71. package/dist/models/gateways.js +45 -0
  72. package/dist/models/ids.d.ts +1 -0
  73. package/dist/models/ids.js +15 -0
  74. package/dist/models/provider_defaults.d.ts +4 -0
  75. package/dist/models/provider_defaults.js +44 -0
  76. package/dist/models/runtime_overrides.d.ts +7 -0
  77. package/dist/models/runtime_overrides.js +226 -0
  78. package/dist/models/subscriptions.d.ts +8 -0
  79. package/dist/models/subscriptions.js +37 -0
  80. package/dist/observability/errors.d.ts +8 -0
  81. package/dist/observability/errors.js +11 -0
  82. package/dist/platform/platform.d.ts +156 -0
  83. package/dist/platform/platform.js +11 -0
  84. package/dist/platform/routing_contract.d.ts +2 -0
  85. package/dist/platform/routing_contract.js +5 -0
  86. package/dist/protocol/input/anthropic_messages.d.ts +2 -0
  87. package/dist/protocol/input/anthropic_messages.js +494 -0
  88. package/dist/protocol/input/chat_completions.d.ts +4 -0
  89. package/dist/protocol/input/chat_completions.js +214 -0
  90. package/dist/protocol/input/chat_completions_validation.d.ts +2 -0
  91. package/dist/protocol/input/chat_completions_validation.js +258 -0
  92. package/dist/protocol/input/openai_responses.d.ts +2 -0
  93. package/dist/protocol/input/openai_responses.js +666 -0
  94. package/dist/protocol/input/router_model.d.ts +7 -0
  95. package/dist/protocol/input/router_model.js +43 -0
  96. package/dist/protocol/output/anthropic_messages.d.ts +10 -0
  97. package/dist/protocol/output/anthropic_messages.js +15 -0
  98. package/dist/protocol/output/anthropic_messages_output.d.ts +10 -0
  99. package/dist/protocol/output/anthropic_messages_output.js +124 -0
  100. package/dist/protocol/output/anthropic_messages_stream.d.ts +16 -0
  101. package/dist/protocol/output/anthropic_messages_stream.js +267 -0
  102. package/dist/protocol/output/chat_completions.d.ts +29 -0
  103. package/dist/protocol/output/chat_completions.js +406 -0
  104. package/dist/protocol/output/chat_reasoning_detail.d.ts +2 -0
  105. package/dist/protocol/output/chat_reasoning_detail.js +13 -0
  106. package/dist/protocol/output/delivered_stream_snapshot.d.ts +10 -0
  107. package/dist/protocol/output/delivered_stream_snapshot.js +31 -0
  108. package/dist/protocol/output/openai_responses.d.ts +10 -0
  109. package/dist/protocol/output/openai_responses.js +14 -0
  110. package/dist/protocol/output/openai_responses_output.d.ts +14 -0
  111. package/dist/protocol/output/openai_responses_output.js +125 -0
  112. package/dist/protocol/output/openai_responses_stream.d.ts +18 -0
  113. package/dist/protocol/output/openai_responses_stream.js +546 -0
  114. package/dist/protocol/output/sse_stream.d.ts +31 -0
  115. package/dist/protocol/output/sse_stream.js +67 -0
  116. package/dist/providers/anthropic_safeguards.d.ts +11 -0
  117. package/dist/providers/anthropic_safeguards.js +81 -0
  118. package/dist/providers/aws_assume_role.d.ts +17 -0
  119. package/dist/providers/aws_assume_role.js +107 -0
  120. package/dist/providers/cancel_estimate.d.ts +43 -0
  121. package/dist/providers/cancel_estimate.js +89 -0
  122. package/dist/providers/execution.d.ts +72 -0
  123. package/dist/providers/execution.js +491 -0
  124. package/dist/providers/model_capabilities.d.ts +11 -0
  125. package/dist/providers/model_capabilities.js +29 -0
  126. package/dist/providers/pi.d.ts +65 -0
  127. package/dist/providers/pi.js +325 -0
  128. package/dist/providers/pi_context.d.ts +7 -0
  129. package/dist/providers/pi_context.js +405 -0
  130. package/dist/providers/pi_options.d.ts +11 -0
  131. package/dist/providers/pi_options.js +410 -0
  132. package/dist/providers/pi_output.d.ts +2 -0
  133. package/dist/providers/pi_output.js +453 -0
  134. package/dist/providers/provider_attempt_runner.d.ts +55 -0
  135. package/dist/providers/provider_attempt_runner.js +90 -0
  136. package/dist/providers/provider_call.d.ts +77 -0
  137. package/dist/providers/provider_call.js +296 -0
  138. package/dist/providers/provider_reported_cost.d.ts +10 -0
  139. package/dist/providers/provider_reported_cost.js +123 -0
  140. package/dist/providers/reasoning.d.ts +12 -0
  141. package/dist/providers/reasoning.js +30 -0
  142. package/dist/providers/response_capture.d.ts +23 -0
  143. package/dist/providers/response_capture.js +47 -0
  144. package/dist/providers/stream_finalization.d.ts +46 -0
  145. package/dist/providers/stream_finalization.js +165 -0
  146. package/dist/providers/subscription_limits.d.ts +33 -0
  147. package/dist/providers/subscription_limits.js +179 -0
  148. package/dist/providers/subscription_usage.d.ts +10 -0
  149. package/dist/providers/subscription_usage.js +79 -0
  150. package/dist/runtime/claude_code/auxiliary_routing.d.ts +3 -0
  151. package/dist/runtime/claude_code/auxiliary_routing.js +60 -0
  152. package/dist/runtime/customer_disconnect.d.ts +20 -0
  153. package/dist/runtime/customer_disconnect.js +49 -0
  154. package/dist/runtime/explicit_model.d.ts +7 -0
  155. package/dist/runtime/explicit_model.js +57 -0
  156. package/dist/runtime/harness_identity/conversation.d.ts +33 -0
  157. package/dist/runtime/harness_identity/conversation.js +39 -0
  158. package/dist/runtime/harness_identity/extract.d.ts +8 -0
  159. package/dist/runtime/harness_identity/extract.js +214 -0
  160. package/dist/runtime/harness_identity/index.d.ts +2 -0
  161. package/dist/runtime/harness_identity/index.js +2 -0
  162. package/dist/runtime/prepare_routed_completion.d.ts +33 -0
  163. package/dist/runtime/prepare_routed_completion.js +186 -0
  164. package/dist/runtime/provider_stream_lifecycle.d.ts +31 -0
  165. package/dist/runtime/provider_stream_lifecycle.js +88 -0
  166. package/dist/runtime/provider_stream_outcome.d.ts +23 -0
  167. package/dist/runtime/provider_stream_outcome.js +55 -0
  168. package/dist/runtime/request_tags.d.ts +7 -0
  169. package/dist/runtime/request_tags.js +33 -0
  170. package/dist/runtime/routed_completion.d.ts +17 -0
  171. package/dist/runtime/routed_completion.js +80 -0
  172. package/dist/runtime/routed_protocol.d.ts +30 -0
  173. package/dist/runtime/routed_protocol.js +1 -0
  174. package/dist/runtime/routed_runtime.d.ts +40 -0
  175. package/dist/runtime/routed_runtime.js +535 -0
  176. package/dist/runtime/routing_lease.d.ts +26 -0
  177. package/dist/runtime/routing_lease.js +210 -0
  178. package/dist/runtime/runtime_reporter.d.ts +71 -0
  179. package/dist/runtime/runtime_reporter.js +35 -0
  180. package/dist/runtime/strict_provider_access.d.ts +6 -0
  181. package/dist/runtime/strict_provider_access.js +40 -0
  182. package/dist/self_host/config.d.ts +46 -0
  183. package/dist/self_host/config.js +105 -0
  184. package/dist/self_host/main.d.ts +16 -0
  185. package/dist/self_host/main.js +95 -0
  186. package/dist/self_host/platform.d.ts +13 -0
  187. package/dist/self_host/platform.js +50 -0
  188. package/dist/self_host/prefix_store.d.ts +46 -0
  189. package/dist/self_host/prefix_store.js +261 -0
  190. package/dist/self_host/resolve.d.ts +28 -0
  191. package/dist/self_host/resolve.js +167 -0
  192. package/dist/self_host/subscriptions/access.d.ts +10 -0
  193. package/dist/self_host/subscriptions/access.js +37 -0
  194. package/dist/self_host/subscriptions/http.d.ts +15 -0
  195. package/dist/self_host/subscriptions/http.js +187 -0
  196. package/dist/self_host/subscriptions/index.d.ts +24 -0
  197. package/dist/self_host/subscriptions/index.js +24 -0
  198. package/dist/self_host/subscriptions/oauth.d.ts +59 -0
  199. package/dist/self_host/subscriptions/oauth.js +376 -0
  200. package/dist/self_host/subscriptions/store.d.ts +78 -0
  201. package/dist/self_host/subscriptions/store.js +236 -0
  202. package/dist/strategies/auto_routing_selector.d.ts +12 -0
  203. package/dist/strategies/auto_routing_selector.js +61 -0
  204. package/dist/strategies/eval_relevance.d.ts +17 -0
  205. package/dist/strategies/eval_relevance.js +32 -0
  206. package/dist/strategies/fallback_decision.d.ts +8 -0
  207. package/dist/strategies/fallback_decision.js +17 -0
  208. package/dist/strategies/priority_selector.d.ts +7 -0
  209. package/dist/strategies/priority_selector.js +37 -0
  210. package/dist/strategies/route_decision.d.ts +22 -0
  211. package/dist/strategies/route_decision.js +65 -0
  212. package/dist/strategies/routing.d.ts +74 -0
  213. package/dist/strategies/routing.js +280 -0
  214. package/dist/strategies/selector_projection.d.ts +15 -0
  215. package/dist/strategies/selector_projection.js +161 -0
  216. package/dist/telemetry/background.d.ts +7 -0
  217. package/dist/telemetry/background.js +33 -0
  218. package/dist/telemetry/benchmark_replay.d.ts +37 -0
  219. package/dist/telemetry/benchmark_replay.js +108 -0
  220. package/dist/telemetry/billing_finalization.d.ts +64 -0
  221. package/dist/telemetry/billing_finalization.js +96 -0
  222. package/dist/telemetry/ingest_values.d.ts +4 -0
  223. package/dist/telemetry/ingest_values.js +12 -0
  224. package/dist/telemetry/model_cost.d.ts +3 -0
  225. package/dist/telemetry/model_cost.js +15 -0
  226. package/dist/telemetry/prefix_state.d.ts +47 -0
  227. package/dist/telemetry/prefix_state.js +116 -0
  228. package/dist/telemetry/report.d.ts +88 -0
  229. package/dist/telemetry/report.js +621 -0
  230. package/dist/telemetry/requests/interaction_observability.d.ts +45 -0
  231. package/dist/telemetry/requests/interaction_observability.js +180 -0
  232. package/dist/telemetry/requests/retained_interaction_request.d.ts +8 -0
  233. package/dist/telemetry/requests/retained_interaction_request.js +10 -0
  234. package/dist/telemetry/scrub.d.ts +2 -0
  235. package/dist/telemetry/scrub.js +31 -0
  236. package/dist/telemetry/skills/claude/catalog.d.ts +6 -0
  237. package/dist/telemetry/skills/claude/catalog.js +99 -0
  238. package/dist/telemetry/skills/claude/file_reads.d.ts +4 -0
  239. package/dist/telemetry/skills/claude/file_reads.js +110 -0
  240. package/dist/telemetry/skills/claude/observations.d.ts +3 -0
  241. package/dist/telemetry/skills/claude/observations.js +366 -0
  242. package/dist/telemetry/skills/codex/catalog.d.ts +11 -0
  243. package/dist/telemetry/skills/codex/catalog.js +138 -0
  244. package/dist/telemetry/skills/codex/exec_file_reads.d.ts +9 -0
  245. package/dist/telemetry/skills/codex/exec_file_reads.js +36 -0
  246. package/dist/telemetry/skills/codex/explicit.d.ts +3 -0
  247. package/dist/telemetry/skills/codex/explicit.js +90 -0
  248. package/dist/telemetry/skills/codex/file_reads.d.ts +4 -0
  249. package/dist/telemetry/skills/codex/file_reads.js +37 -0
  250. package/dist/telemetry/skills/codex/identity.d.ts +2 -0
  251. package/dist/telemetry/skills/codex/identity.js +20 -0
  252. package/dist/telemetry/skills/observations.d.ts +21 -0
  253. package/dist/telemetry/skills/observations.js +41 -0
  254. package/dist/telemetry/skills/paths.d.ts +11 -0
  255. package/dist/telemetry/skills/paths.js +61 -0
  256. package/dist/telemetry/skills/pi.d.ts +6 -0
  257. package/dist/telemetry/skills/pi.js +223 -0
  258. package/dist/telemetry/skills/shell_file_reads.d.ts +7 -0
  259. package/dist/telemetry/skills/shell_file_reads.js +226 -0
  260. package/dist/telemetry/skills/shell_words.d.ts +13 -0
  261. package/dist/telemetry/skills/shell_words.js +189 -0
  262. package/dist/telemetry/tools/input.d.ts +2 -0
  263. package/dist/telemetry/tools/input.js +14 -0
  264. package/dist/telemetry/tools/observations.d.ts +29 -0
  265. package/dist/telemetry/tools/observations.js +247 -0
  266. package/dist/telemetry/usage.d.ts +57 -0
  267. package/dist/telemetry/usage.js +136 -0
  268. package/dist/types.d.ts +97 -0
  269. package/dist/types.js +1 -0
  270. package/package.json +22 -7
  271. package/src/bun.ts +2 -2
  272. package/src/context/eval_catalog.ts +1 -1
  273. package/src/context/interaction_fingerprint.ts +9 -9
  274. package/src/context/interaction_fingerprint_format.ts +1 -1
  275. package/src/context/interaction_lease_depth.ts +1 -1
  276. package/src/context/pricing.ts +6 -3
  277. package/src/context/provider_prompt_accounting.ts +5 -5
  278. package/src/context/routing_context.ts +16 -16
  279. package/src/http/auth.ts +1 -1
  280. package/src/http/handler.ts +15 -8
  281. package/src/http/serve.ts +3 -3
  282. package/src/index.ts +14 -6
  283. package/src/ingress/anthropic_messages.ts +12 -12
  284. package/src/ingress/anthropic_models.ts +1 -1
  285. package/src/ingress/chat_completions.ts +17 -10
  286. package/src/ingress/claude_code/request_context.ts +2 -2
  287. package/src/ingress/codex.ts +14 -10
  288. package/src/ingress/codex_models.ts +4 -4
  289. package/src/ingress/json.ts +1 -1
  290. package/src/ingress/models.ts +22 -10
  291. package/src/ingress/muse_code.ts +9 -0
  292. package/src/ingress/muse_models.ts +36 -0
  293. package/src/interaction/capabilities.ts +1 -1
  294. package/src/interaction/portable_reasoning_state.ts +1 -1
  295. package/src/interaction/provider_continuation_state.ts +1 -1
  296. package/src/interaction/tool_identity.ts +2 -2
  297. package/src/interaction/types.ts +2 -0
  298. package/src/models/catalog.ts +310 -0
  299. package/src/models/context_limits.ts +1 -1
  300. package/src/models/execution_provider.ts +5 -2
  301. package/src/models/ids.ts +1 -1
  302. package/src/models/provider_defaults.ts +4 -1
  303. package/src/models/runtime_overrides.ts +23 -1
  304. package/src/models/subscriptions.ts +54 -0
  305. package/src/observability/errors.ts +2 -2
  306. package/src/platform/platform.ts +9 -5
  307. package/src/protocol/input/anthropic_messages.ts +7 -7
  308. package/src/protocol/input/chat_completions.ts +8 -6
  309. package/src/protocol/input/chat_completions_validation.ts +6 -5
  310. package/src/protocol/input/openai_responses.ts +6 -6
  311. package/src/protocol/output/anthropic_messages.ts +3 -3
  312. package/src/protocol/output/anthropic_messages_output.ts +6 -4
  313. package/src/protocol/output/anthropic_messages_stream.ts +7 -7
  314. package/src/protocol/output/chat_completions.ts +13 -13
  315. package/src/protocol/output/chat_reasoning_detail.ts +1 -1
  316. package/src/protocol/output/openai_responses.ts +3 -3
  317. package/src/protocol/output/openai_responses_output.ts +4 -2
  318. package/src/protocol/output/openai_responses_stream.ts +6 -6
  319. package/src/protocol/output/sse_stream.ts +3 -3
  320. package/src/providers/anthropic_safeguards.ts +2 -2
  321. package/src/providers/aws_assume_role.ts +2 -2
  322. package/src/providers/cancel_estimate.ts +1 -1
  323. package/src/providers/execution.ts +17 -17
  324. package/src/providers/pi.ts +34 -19
  325. package/src/providers/pi_context.ts +6 -6
  326. package/src/providers/pi_options.ts +27 -11
  327. package/src/providers/pi_output.ts +5 -5
  328. package/src/providers/provider_attempt_runner.ts +1 -1
  329. package/src/providers/provider_call.ts +21 -17
  330. package/src/providers/provider_reported_cost.ts +3 -3
  331. package/src/providers/reasoning.ts +2 -2
  332. package/src/providers/stream_finalization.ts +9 -9
  333. package/src/providers/subscription_limits.ts +24 -7
  334. package/src/runtime/claude_code/auxiliary_routing.ts +5 -5
  335. package/src/runtime/customer_disconnect.ts +1 -1
  336. package/src/runtime/explicit_model.ts +19 -20
  337. package/src/runtime/harness_identity/conversation.ts +1 -1
  338. package/src/runtime/harness_identity/extract.ts +3 -3
  339. package/src/runtime/harness_identity/index.ts +2 -2
  340. package/src/runtime/prepare_routed_completion.ts +35 -16
  341. package/src/runtime/provider_stream_lifecycle.ts +1 -1
  342. package/src/runtime/provider_stream_outcome.ts +2 -2
  343. package/src/runtime/request_tags.ts +2 -2
  344. package/src/runtime/routed_completion.ts +11 -11
  345. package/src/runtime/routed_protocol.ts +2 -2
  346. package/src/runtime/routed_runtime.ts +20 -19
  347. package/src/runtime/routing_lease.ts +7 -7
  348. package/src/runtime/runtime_reporter.ts +3 -3
  349. package/src/runtime/strict_provider_access.ts +42 -0
  350. package/src/self_host/main.ts +12 -12
  351. package/src/self_host/platform.ts +5 -5
  352. package/src/self_host/prefix_store.ts +2 -2
  353. package/src/self_host/resolve.ts +17 -31
  354. package/src/self_host/subscriptions/access.ts +2 -2
  355. package/src/self_host/subscriptions/http.ts +2 -2
  356. package/src/self_host/subscriptions/index.ts +4 -4
  357. package/src/self_host/subscriptions/oauth.ts +139 -8
  358. package/src/self_host/subscriptions/store.ts +2 -1
  359. package/src/strategies/auto_routing_selector.ts +2 -2
  360. package/src/strategies/eval_relevance.ts +3 -3
  361. package/src/strategies/priority_selector.ts +1 -1
  362. package/src/strategies/route_decision.ts +7 -7
  363. package/src/strategies/routing.ts +10 -10
  364. package/src/strategies/selector_projection.ts +2 -2
  365. package/src/telemetry/billing_finalization.ts +3 -3
  366. package/src/telemetry/model_cost.ts +1 -1
  367. package/src/telemetry/prefix_state.ts +4 -4
  368. package/src/telemetry/report.ts +21 -21
  369. package/src/telemetry/requests/interaction_observability.ts +1 -1
  370. package/src/telemetry/requests/retained_interaction_request.ts +1 -1
  371. package/src/telemetry/skills/claude/catalog.ts +1 -1
  372. package/src/telemetry/skills/claude/file_reads.ts +6 -6
  373. package/src/telemetry/skills/claude/observations.ts +3 -3
  374. package/src/telemetry/skills/codex/catalog.ts +3 -3
  375. package/src/telemetry/skills/codex/exec_file_reads.ts +4 -4
  376. package/src/telemetry/skills/codex/explicit.ts +3 -3
  377. package/src/telemetry/skills/codex/file_reads.ts +5 -5
  378. package/src/telemetry/skills/observations.ts +7 -7
  379. package/src/telemetry/skills/pi.ts +3 -3
  380. package/src/telemetry/skills/shell_file_reads.ts +2 -2
  381. package/src/telemetry/skills/shell_words.ts +1 -1
  382. package/src/telemetry/tools/input.ts +1 -1
  383. package/src/telemetry/tools/observations.ts +9 -9
  384. package/src/telemetry/usage.ts +5 -5
  385. package/src/types.ts +20 -3
@@ -8,8 +8,8 @@ import {
8
8
  type RoutingDecision,
9
9
  } from "@mupt-ai/dari-router/policy-engine";
10
10
 
11
- import { buildRoutingContext } from "../context/routing_context";
12
- import type { InteractionRequest } from "../interaction/types";
11
+ import { buildRoutingContext } from "../context/routing_context.js";
12
+ import type { InteractionRequest } from "../interaction/types.js";
13
13
  import {
14
14
  completeNonStreaming,
15
15
  executeNonStreaming,
@@ -17,7 +17,7 @@ import {
17
17
  prepareStreamingExecution,
18
18
  type CompletedNonStreamingExecution,
19
19
  type ProviderChoice,
20
- } from "../providers/execution";
20
+ } from "../providers/execution.js";
21
21
  import {
22
22
  prepareProviderExecution,
23
23
  startProviderCompletion,
@@ -25,16 +25,16 @@ import {
25
25
  type ProviderExecution,
26
26
  type StartedCompletion,
27
27
  type StartedStream,
28
- } from "../providers/provider_call";
29
- import type { SelectorBackend } from "../strategies/routing";
30
- import { routeDecision, type RoutedDecision } from "../strategies/route_decision";
31
- import { executionProviderForModel } from "../models/execution_provider";
32
- import { trackBackgroundTelemetry } from "../telemetry/background";
33
- import { estimateBenchmarkReplay } from "../telemetry/benchmark_replay";
34
- import { buildCompletedPrefixHit } from "../telemetry/prefix_state";
35
- import { scrubSecrets } from "../telemetry/scrub";
36
- import type { ResolvedRouter } from "../types";
37
- import type { PreparedRoutedCompletion } from "./prepare_routed_completion";
28
+ } from "../providers/provider_call.js";
29
+ import type { SelectorBackend } from "../strategies/routing.js";
30
+ import { routeDecision, type RoutedDecision } from "../strategies/route_decision.js";
31
+ import { executionProviderForModel } from "../models/execution_provider.js";
32
+ import { trackBackgroundTelemetry } from "../telemetry/background.js";
33
+ import { estimateBenchmarkReplay } from "../telemetry/benchmark_replay.js";
34
+ import { buildCompletedPrefixHit } from "../telemetry/prefix_state.js";
35
+ import { scrubSecrets } from "../telemetry/scrub.js";
36
+ import type { ResolvedRouter } from "../types.js";
37
+ import type { PreparedRoutedCompletion } from "./prepare_routed_completion.js";
38
38
  import { auxiliaryDecision } from "./claude_code/auxiliary_routing.js";
39
39
  import { explicitModelDecision, strictModelDecision } from "./explicit_model.js";
40
40
  import {
@@ -47,12 +47,12 @@ import {
47
47
  prefetchNextLease,
48
48
  selectorNegotiatesLeases,
49
49
  } from "./routing_lease.js";
50
- import type { RoutedProtocol } from "./routed_protocol";
50
+ import type { RoutedProtocol } from "./routed_protocol.js";
51
51
  import {
52
52
  createExperimentRoutedRuntimeReporter,
53
53
  type RoutedRuntimeReporter,
54
- } from "./runtime_reporter";
55
- import { HttpError } from "../http/errors";
54
+ } from "./runtime_reporter.js";
55
+ import { HttpError } from "../http/errors.js";
56
56
 
57
57
  type SpeculativeExecution = {
58
58
  decision: RoutingDecision;
@@ -113,12 +113,12 @@ export type {
113
113
  SelectorAdapterArgs,
114
114
  SelectorBackend,
115
115
  SelectorRun,
116
- } from "../strategies/routing";
116
+ } from "../strategies/routing.js";
117
117
  export type {
118
118
  ExperimentRoutedRuntimeReporter,
119
119
  RoutedRuntimeReporter,
120
- } from "./runtime_reporter";
121
- export { createExperimentRoutedRuntimeReporter } from "./runtime_reporter";
120
+ } from "./runtime_reporter.js";
121
+ export { createExperimentRoutedRuntimeReporter } from "./runtime_reporter.js";
122
122
 
123
123
  export async function runPreparedRoutedCompletion(args: {
124
124
  prepared: PreparedRoutedCompletion;
@@ -709,6 +709,7 @@ const inProcessProtocol: RoutedProtocol = {
709
709
  selected_model: args.routing.selectedModel,
710
710
  reasoning_effort: args.routing.reasoningEffort,
711
711
  reason: args.routing.reason,
712
+ request_id: args.id,
712
713
  ...(args.conversationId ? { conversation_id: args.conversationId } : {}),
713
714
  },
714
715
  }),
@@ -6,16 +6,16 @@ import {
6
6
  type RoutingDecision,
7
7
  } from "@mupt-ai/dari-router/policy-engine";
8
8
 
9
- import { deriveFallbackDecision } from "../strategies/fallback_decision";
10
- import { executionProviderForModel } from "../models/execution_provider";
11
- import type { SelectorBackend } from "../strategies/routing";
9
+ import { deriveFallbackDecision } from "../strategies/fallback_decision.js";
10
+ import { executionProviderForModel } from "../models/execution_provider.js";
11
+ import type { SelectorBackend } from "../strategies/routing.js";
12
12
  import {
13
13
  routeDecision,
14
14
  type RoutedDecision,
15
- } from "../strategies/route_decision";
16
- import { reportPendingLease } from "../telemetry/prefix_state";
17
- import { scrubSecrets } from "../telemetry/scrub";
18
- import type { PreparedRoutedCompletion } from "./prepare_routed_completion";
15
+ } from "../strategies/route_decision.js";
16
+ import { reportPendingLease } from "../telemetry/prefix_state.js";
17
+ import { scrubSecrets } from "../telemetry/scrub.js";
18
+ import type { PreparedRoutedCompletion } from "./prepare_routed_completion.js";
19
19
 
20
20
  export type RoutingLeaseDecision = {
21
21
  decision: RoutingDecision;
@@ -1,7 +1,7 @@
1
1
  import type { RoutingDecision } from "@mupt-ai/dari-router/policy-engine";
2
- import type { InteractionOutput } from "../interaction/types";
3
- import type { SelectorRun } from "../strategies/routing";
4
- import type { ProviderKeySource } from "../types";
2
+ import type { InteractionOutput } from "../interaction/types.js";
3
+ import type { SelectorRun } from "../strategies/routing.js";
4
+ import type { ProviderKeySource } from "../types.js";
5
5
 
6
6
  export type ReportedProviderExecution = {
7
7
  provider: string;
@@ -0,0 +1,42 @@
1
+ import { getBuiltinModels, getBuiltinProviders } from "@mupt-ai/pi-ai/providers/all";
2
+ import { HttpError } from "../http/errors.js";
3
+ import type { InteractionRequest } from "../interaction/types.js";
4
+ import { explicitModelId } from "../protocol/input/router_model.js";
5
+ import type { ResolvedRouter } from "../types.js";
6
+ import { modelNotEnabled, strictModelRequired } from "./explicit_model.js";
7
+
8
+ // Resolve only the requested catalog model, never turn a provider grant into
9
+ // selector candidates. Unknown IDs fail closed; a grant-only router has no
10
+ // candidates to route among, so it refuses them here with the strict errors.
11
+ export function strictProviderAccess(
12
+ credentials: ResolvedRouter,
13
+ interaction: InteractionRequest,
14
+ ): { credentials: ResolvedRouter; interaction: InteractionRequest } {
15
+ const providers = credentials.strict_providers;
16
+ if (credentials.strict !== true || !providers?.length) return { credentials, interaction };
17
+ const requested = explicitModelId(interaction.model);
18
+ const grantOnly = credentials.enabled_models.length === 0;
19
+ if (requested === null) {
20
+ if (grantOnly) throw strictModelRequired();
21
+ return { credentials, interaction };
22
+ }
23
+ const matches = new Set<string>();
24
+ for (const provider of providers) {
25
+ if (!(getBuiltinProviders() as readonly string[]).includes(provider)) {
26
+ throw new HttpError(400, `Unknown strict provider '${provider}'.`, "unknown_provider");
27
+ }
28
+ for (const model of getBuiltinModels(provider as never)) {
29
+ const id = `${provider}/${model.id}`;
30
+ if (requested === id) matches.add(id);
31
+ }
32
+ }
33
+ const model = [...matches][0];
34
+ if (model === undefined) {
35
+ if (grantOnly) throw modelNotEnabled(requested);
36
+ return { credentials, interaction };
37
+ }
38
+ return {
39
+ credentials: { ...credentials, enabled_models: [...new Set([...credentials.enabled_models, model])] },
40
+ interaction: { ...interaction, model: `dari/model/${model}` },
41
+ };
42
+ }
@@ -3,18 +3,18 @@ import { chmodSync, existsSync } from "node:fs";
3
3
  import { Database } from "bun:sqlite";
4
4
  import { builtinModels } from "@mupt-ai/pi-ai/providers/all";
5
5
 
6
- import { bearerToken } from "../http/auth";
7
- import { errorResponse, HttpError } from "../http/errors";
8
- import { createRequestHandler } from "../http/handler";
9
- import { installShutdownHandlers, startServer } from "../http/serve";
10
- import { createAutoRoutingSelectorBackend } from "../strategies/auto_routing_selector";
11
- import { createPrioritySelectorBackend } from "../strategies/priority_selector";
12
- import type { SelectorBackend } from "../strategies/routing";
13
- import { loadGatewayConfig } from "./config";
14
- import { createSelfHostedPlatform } from "./platform";
15
- import { gatewayKeyIndex } from "./resolve";
16
- import { PrefixStore } from "./prefix_store";
17
- import { handleSubscriptionRequest, SubscriptionStore } from "./subscriptions";
6
+ import { bearerToken } from "../http/auth.js";
7
+ import { errorResponse, HttpError } from "../http/errors.js";
8
+ import { createRequestHandler } from "../http/handler.js";
9
+ import { installShutdownHandlers, startServer } from "../http/serve.js";
10
+ import { createAutoRoutingSelectorBackend } from "../strategies/auto_routing_selector.js";
11
+ import { createPrioritySelectorBackend } from "../strategies/priority_selector.js";
12
+ import type { SelectorBackend } from "../strategies/routing.js";
13
+ import { loadGatewayConfig } from "./config.js";
14
+ import { createSelfHostedPlatform } from "./platform.js";
15
+ import { gatewayKeyIndex } from "./resolve.js";
16
+ import { PrefixStore } from "./prefix_store.js";
17
+ import { handleSubscriptionRequest, SubscriptionStore } from "./subscriptions/index.js";
18
18
 
19
19
  const SUBSCRIPTION_ROUTES = "/v1/organizations/current/credentials";
20
20
 
@@ -1,8 +1,8 @@
1
- import { errorCode } from "../http/errors";
2
- import type { GatewayPlatform } from "../platform/platform";
3
- import type { PrefixStore } from "./prefix_store";
4
- import { resolveSelfHostedRouter, type SelfHostedResolverDeps } from "./resolve";
5
- import type { SubscriptionStore } from "./subscriptions";
1
+ import { errorCode } from "../http/errors.js";
2
+ import type { GatewayPlatform } from "../platform/platform.js";
3
+ import type { PrefixStore } from "./prefix_store.js";
4
+ import { resolveSelfHostedRouter, type SelfHostedResolverDeps } from "./resolve.js";
5
+ import type { SubscriptionStore } from "./subscriptions/index.js";
6
6
 
7
7
  /**
8
8
  * The self-hosted platform: routers from the config file, subscriptions and
@@ -14,8 +14,8 @@
14
14
  import type { Database } from "bun:sqlite";
15
15
  import type { ReasoningEffort, RouterPrefixHit } from "@mupt-ai/dari-router/policy-engine";
16
16
 
17
- import type { PendingLeaseWrite, PrefixStateWrite } from "../platform/platform";
18
- import { ROUTING_PREFIX_HASHES_MAX_COUNT } from "../platform/routing_contract";
17
+ import type { PendingLeaseWrite, PrefixStateWrite } from "../platform/platform.js";
18
+ import { ROUTING_PREFIX_HASHES_MAX_COUNT } from "../platform/routing_contract.js";
19
19
 
20
20
  // Resolve returns entries up to this age so a continuation after a pause still
21
21
  // recovers its conversation id and previous decision; the runtime itself
@@ -4,33 +4,27 @@ import {
4
4
  nativeModelId,
5
5
  providerForModel,
6
6
  type ReasoningEffort,
7
- type RouterModelPrice,
8
7
  type RouterPrefixHit,
9
8
  } from "@mupt-ai/dari-router/policy-engine";
10
- import { HttpError } from "../http/errors";
11
- import type { ResolveRouterRequest } from "../platform/platform";
12
- import { registeredModelPrice } from "../providers/pi";
13
- import type {
14
- ProviderKeySource,
15
- ResolvedRouter,
16
- ResolvedRouterModelConfig,
17
- } from "../types";
18
- import type { GatewayConfig, RouterConfig } from "./config";
9
+ import { HttpError } from "../http/errors.js";
10
+ import type { ResolveRouterRequest } from "../platform/platform.js";
11
+ import { codexModelConfig } from "../models/subscriptions.js";
12
+ import { registeredModelPrice } from "../providers/pi.js";
13
+ import type { ProviderKeySource, ResolvedRouter } from "../types.js";
14
+ import type { GatewayConfig, RouterConfig } from "./config.js";
19
15
  import {
20
16
  freshAccessToken,
21
17
  type OAuthFetch,
22
18
  type SubscriptionCredential,
23
19
  type SubscriptionProvider,
24
20
  type SubscriptionStore,
25
- } from "./subscriptions";
21
+ } from "./subscriptions/index.js";
26
22
 
27
23
  // A self-hosted gateway is one tenant; these stand in for the hosted
28
24
  // organization and the user a personal subscription belongs to.
29
25
  export const SELF_HOSTED_ORGANIZATION_ID = "self-hosted";
30
26
  export const SELF_HOSTED_USER_ID = "self-hosted";
31
27
 
32
- const CODEX_BACKEND_URL = "https://chatgpt.com/backend-api";
33
-
34
28
  export type SelfHostedResolverDeps = {
35
29
  config: GatewayConfig;
36
30
  gatewayKeys: readonly string[];
@@ -176,8 +170,8 @@ export function gatewayKeyIndex(keys: readonly string[], presented: string): num
176
170
  return null;
177
171
  }
178
172
 
179
- // Claude Code plans serve only Claude Code itself; ChatGPT plans serve any
180
- // client through the Codex backend.
173
+ // Claude Code plans serve only Claude Code itself and Muse Code plans only
174
+ // Muse Code; ChatGPT plans serve any client through the Codex backend.
181
175
  function subscriptionProviderFor(
182
176
  provider: string,
183
177
  clientHarness: ResolveRouterRequest["clientHarness"],
@@ -185,6 +179,7 @@ function subscriptionProviderFor(
185
179
  if (provider === "anthropic") {
186
180
  return clientHarness === "claude_code" ? "anthropic_claude_code" : null;
187
181
  }
182
+ if (provider === "meta") return clientHarness === "muse_code" ? "meta_muse" : null;
188
183
  if (provider === "openai") return "openai_codex";
189
184
  return null;
190
185
  }
@@ -197,34 +192,25 @@ function servingProviders(provider: string, credential: ProviderCredential): str
197
192
  : [provider];
198
193
  }
199
194
 
200
- function codexModelConfig(
201
- modelId: string,
202
- price: RouterModelPrice | null,
203
- ): ResolvedRouterModelConfig {
204
- return {
205
- provider: "openai-codex",
206
- native_model_id: nativeModelId(modelId),
207
- api: "openai-codex-responses",
208
- base_url: CODEX_BACKEND_URL,
209
- // A plan bills no tokens; the catalog price only feeds cost estimates.
210
- cost: price ?? { input: 0, output: 0 },
211
- fast_mode: false,
212
- };
213
- }
214
-
215
195
  function thinkingLevels(router: RouterConfig): Record<string, ReasoningEffort[]> {
216
196
  return Object.fromEntries(
217
197
  router.models.flatMap((model) => model.thinking ? [[model.id, model.thinking]] : []),
218
198
  );
219
199
  }
220
200
 
201
+ const SUBSCRIPTION_PLAN_NAMES: Record<SubscriptionProvider, string> = {
202
+ anthropic_claude_code: "Claude Code",
203
+ openai_codex: "ChatGPT",
204
+ meta_muse: "Muse Code",
205
+ };
206
+
221
207
  function unavailableRouterError(
222
208
  routerId: string,
223
209
  exhausted: ReadonlySet<SubscriptionProvider>,
224
210
  ): HttpError {
225
211
  if (exhausted.size > 0) {
226
212
  const plans = [...exhausted]
227
- .map((provider) => provider === "anthropic_claude_code" ? "Claude Code" : "ChatGPT")
213
+ .map((provider) => SUBSCRIPTION_PLAN_NAMES[provider])
228
214
  .join(" and ");
229
215
  return new HttpError(
230
216
  424,
@@ -1,5 +1,5 @@
1
- import { refreshOAuth, type OAuthFetch } from "./oauth";
2
- import type { SubscriptionCredential, SubscriptionStore } from "./store";
1
+ import { refreshOAuth, type OAuthFetch } from "./oauth.js";
2
+ import type { SubscriptionCredential, SubscriptionStore } from "./store.js";
3
3
 
4
4
  const REFRESH_MARGIN_MS = 5 * 60_000;
5
5
 
@@ -12,8 +12,8 @@ import {
12
12
  startOAuth,
13
13
  type OAuthFetch,
14
14
  type SubscriptionProvider,
15
- } from "./oauth";
16
- import { isHeld, type SubscriptionCredential, type SubscriptionStore } from "./store";
15
+ } from "./oauth.js";
16
+ import { isHeld, type SubscriptionCredential, type SubscriptionStore } from "./store.js";
17
17
 
18
18
  export type SubscriptionHttpDeps = {
19
19
  store: SubscriptionStore;
@@ -18,8 +18,8 @@
18
18
  * `store.markUnavailable` holds that subscription until its reset and says
19
19
  * whether another one can serve the retry.
20
20
  */
21
- export { freshAccessToken } from "./access";
22
- export { handleSubscriptionRequest, type SubscriptionHttpDeps } from "./http";
21
+ export { freshAccessToken } from "./access.js";
22
+ export { handleSubscriptionRequest, type SubscriptionHttpDeps } from "./http.js";
23
23
  export {
24
24
  CODEX_APPROVAL_PENDING,
25
25
  SUBSCRIPTION_PROVIDERS,
@@ -34,10 +34,10 @@ export {
34
34
  type OAuthOptions,
35
35
  type OAuthTokens,
36
36
  type SubscriptionProvider,
37
- } from "./oauth";
37
+ } from "./oauth.js";
38
38
  export {
39
39
  SubscriptionStore,
40
40
  isHeld,
41
41
  type PendingOAuthSession,
42
42
  type SubscriptionCredential,
43
- } from "./store";
43
+ } from "./store.js";
@@ -2,16 +2,18 @@ import { createHash, randomBytes } from "node:crypto";
2
2
 
3
3
  /**
4
4
  * OAuth protocols for personal subscriptions: Claude Code (PKCE, the user
5
- * pastes back the `code#state` Anthropic shows) and ChatGPT/Codex (device
6
- * code, the gateway polls for approval). Every network call goes through the
7
- * injected `fetch`.
5
+ * pastes back the `code#state` Anthropic shows), ChatGPT/Codex (device code,
6
+ * the gateway polls for approval), and Muse Code (Meta's device code, then the
7
+ * subscription's Model API key minted from the sign-in token). Every network
8
+ * call goes through the injected `fetch`.
8
9
  */
9
10
 
10
- export type SubscriptionProvider = "anthropic_claude_code" | "openai_codex";
11
+ export type SubscriptionProvider = "anthropic_claude_code" | "openai_codex" | "meta_muse";
11
12
 
12
13
  export const SUBSCRIPTION_PROVIDERS: readonly SubscriptionProvider[] = [
13
14
  "anthropic_claude_code",
14
15
  "openai_codex",
16
+ "meta_muse",
15
17
  ];
16
18
 
17
19
  export type OAuthFetch = (url: string, init: RequestInit) => Promise<Response>;
@@ -20,7 +22,8 @@ export type OAuthOptions = { fetch: OAuthFetch; now?: Date };
20
22
 
21
23
  /** The provider refused or could not be reached (HTTP 502 at the edge). */
22
24
  export class SubscriptionOAuthProviderError extends Error {
23
- constructor(message: string, readonly status?: number) {
25
+ // `errorCode` is the provider's OAuth `error` code, such as `authorization_pending`.
26
+ constructor(message: string, readonly status?: number, readonly errorCode?: string) {
24
27
  super(message);
25
28
  this.name = "SubscriptionOAuthProviderError";
26
29
  }
@@ -43,6 +46,8 @@ export type OAuthAuthorization = {
43
46
  flow: Record<string, string>;
44
47
  };
45
48
 
49
+ // A Muse Code plan's access token is the Model API key minted for it, and its
50
+ // refresh token the Meta sign-in token the key is minted from.
46
51
  export type OAuthTokens = {
47
52
  provider: SubscriptionProvider;
48
53
  accessToken: string;
@@ -76,6 +81,23 @@ const CODEX_ACCOUNT_CLAIM = "https://api.openai.com/auth";
76
81
  export const CODEX_APPROVAL_PENDING =
77
82
  "OpenAI approval is still pending. Enter the code at OpenAI, finish approval, then try again.";
78
83
 
84
+ // Muse Code's own device sign-in (`muse login`), as its public launcher runs it.
85
+ export const MUSE_CODE_CLIENT_ID = "1031625952748946";
86
+ const META_AUTH_BASE_URL = "https://auth.meta.com";
87
+ const META_DEVICE_AUTHORIZATION_URL = `${META_AUTH_BASE_URL}/oidc/device/authorization/`;
88
+ const META_TOKEN_URL = `${META_AUTH_BASE_URL}/oidc/device/token/`;
89
+ // Muse Code mints its subscription's Model API key from the sign-in token here.
90
+ const MUSE_MINT_URL = "https://api.meta.ai/muse-code/key";
91
+ // Meta states no lifetime for a minted key, and Muse Code mints a fresh one at
92
+ // every start, so the key is minted again on this cadence.
93
+ const MUSE_KEY_LIFETIME_MS = 12 * 60 * 60_000;
94
+ // Marks a stored sign-in refresh token, which is exchanged for a fresh sign-in
95
+ // token before each mint. Without it the stored value is the sign-in token.
96
+ const MUSE_SIGN_IN_REFRESH_PREFIX = "refresh:";
97
+
98
+ export const META_APPROVAL_PENDING =
99
+ "Meta approval is still pending. Enter the code at Meta, finish approval, then try again.";
100
+
79
101
  export async function startOAuth(
80
102
  provider: SubscriptionProvider,
81
103
  options: OAuthOptions,
@@ -103,6 +125,23 @@ export async function startOAuth(
103
125
  flow: { code_verifier: verifier, state },
104
126
  };
105
127
  }
128
+ if (provider === "meta_muse") {
129
+ const payload = await postForm(
130
+ options.fetch,
131
+ META_DEVICE_AUTHORIZATION_URL,
132
+ { client_id: MUSE_CODE_CLIENT_ID },
133
+ "Meta device code request",
134
+ );
135
+ const complete = payload.verification_uri_complete;
136
+ return {
137
+ authorizationUrl: typeof complete === "string" && complete.startsWith("https://")
138
+ ? complete
139
+ : requiredString(payload, "verification_uri"),
140
+ expiresAt,
141
+ userCode: requiredString(payload, "user_code"),
142
+ flow: { device_code: requiredString(payload, "device_code") },
143
+ };
144
+ }
106
145
  const payload = await postJson(
107
146
  options.fetch,
108
147
  `${CODEX_DEVICE_AUTH_URL}/usercode`,
@@ -120,7 +159,7 @@ export async function startOAuth(
120
159
 
121
160
  /**
122
161
  * Finish a flow. Claude Code needs the pasted authorization response; the
123
- * device-code flow ignores it and asks OpenAI whether the user approved.
162
+ * device-code flows ignore it and ask the provider whether the user approved.
124
163
  */
125
164
  export async function completeOAuth(
126
165
  provider: SubscriptionProvider,
@@ -154,6 +193,35 @@ export async function completeOAuth(
154
193
  );
155
194
  return claudeTokens(token, now, null);
156
195
  }
196
+ if (provider === "meta_muse") {
197
+ let token: Record<string, unknown>;
198
+ try {
199
+ token = await postForm(
200
+ options.fetch,
201
+ META_TOKEN_URL,
202
+ {
203
+ grant_type: "urn:ietf:params:oauth:grant-type:device_code",
204
+ device_code: requiredString(flow, "device_code"),
205
+ client_id: MUSE_CODE_CLIENT_ID,
206
+ },
207
+ "Meta device approval check",
208
+ );
209
+ } catch (error) {
210
+ if (error instanceof SubscriptionOAuthProviderError) {
211
+ if (error.errorCode === "authorization_pending" || error.errorCode === "slow_down") {
212
+ throw new SubscriptionOAuthInputError(META_APPROVAL_PENDING);
213
+ }
214
+ if (error.errorCode === "access_denied") {
215
+ throw new SubscriptionOAuthInputError("The sign-in was declined on Meta. Start again to retry.");
216
+ }
217
+ if (error.errorCode === "expired_token") {
218
+ throw new SubscriptionOAuthInputError("The Meta sign-in code expired. Start again.");
219
+ }
220
+ }
221
+ throw error;
222
+ }
223
+ return await museTokens(requiredString(token, "access_token"), museRefreshToken(token), options.fetch, now);
224
+ }
157
225
 
158
226
  // The provider, not user-supplied input, supplies the authorization code.
159
227
  let approval: Record<string, unknown>;
@@ -207,6 +275,28 @@ export async function refreshOAuth(
207
275
  );
208
276
  return claudeTokens(token, now, credential.refreshToken);
209
277
  }
278
+ if (credential.provider === "meta_muse") {
279
+ let stored = credential.refreshToken;
280
+ let signInToken = stored;
281
+ if (stored.startsWith(MUSE_SIGN_IN_REFRESH_PREFIX)) {
282
+ const token = await postForm(
283
+ options.fetch,
284
+ META_TOKEN_URL,
285
+ {
286
+ grant_type: "refresh_token",
287
+ refresh_token: stored.slice(MUSE_SIGN_IN_REFRESH_PREFIX.length),
288
+ client_id: MUSE_CODE_CLIENT_ID,
289
+ },
290
+ "Meta sign-in refresh",
291
+ );
292
+ signInToken = requiredString(token, "access_token");
293
+ stored = museRefreshToken(token) ?? stored;
294
+ }
295
+ // A lapsed plan fails routing like any other refresh failure.
296
+ return await museTokens(signInToken, stored, options.fetch, now).catch((error: unknown) => {
297
+ throw error instanceof SubscriptionOAuthInputError ? new SubscriptionOAuthProviderError(error.message) : error;
298
+ });
299
+ }
210
300
  const token = await postJson(
211
301
  options.fetch,
212
302
  CODEX_TOKEN_URL,
@@ -258,6 +348,43 @@ function claudeTokens(
258
348
  };
259
349
  }
260
350
 
351
+ function museRefreshToken(token: Record<string, unknown>): string | null {
352
+ const value = token.refresh_token;
353
+ return typeof value === "string" && value ? MUSE_SIGN_IN_REFRESH_PREFIX + value : null;
354
+ }
355
+
356
+ // Mints the plan's Model API key from the Meta sign-in token.
357
+ async function museTokens(
358
+ signInToken: string,
359
+ refreshToken: string | null,
360
+ fetch: OAuthFetch,
361
+ now: Date,
362
+ ): Promise<OAuthTokens> {
363
+ const minted = await requestJson(
364
+ fetch,
365
+ MUSE_MINT_URL,
366
+ "{}",
367
+ "application/json",
368
+ "Muse Code subscription key mint",
369
+ { Authorization: `Bearer ${signInToken}`, "x-api-version": "1.0.0" },
370
+ );
371
+ // A key minted without an active plan bills Model API pay-as-you-go.
372
+ if (minted.is_subs_active !== true) {
373
+ throw new SubscriptionOAuthInputError(
374
+ "This Meta account has no active Muse Code subscription. Subscribe at https://accountscenter.meta.com/muse_code/, then connect again.",
375
+ );
376
+ }
377
+ const email = minted.user_email;
378
+ return {
379
+ provider: "meta_muse",
380
+ accessToken: requiredString(minted, "api_key"),
381
+ refreshToken: refreshToken ?? signInToken,
382
+ expiresAt: new Date(now.getTime() + MUSE_KEY_LIFETIME_MS),
383
+ accountId: null,
384
+ accountEmail: typeof email === "string" && email ? email : null,
385
+ };
386
+ }
387
+
261
388
  function codexTokens(
262
389
  payload: Record<string, unknown>,
263
390
  now: Date,
@@ -353,12 +480,13 @@ async function requestJson(
353
480
  body: string,
354
481
  contentType: string,
355
482
  operation: string,
483
+ headers: Record<string, string> = {},
356
484
  ): Promise<Record<string, unknown>> {
357
485
  let response: Response;
358
486
  try {
359
487
  response = await fetch(url, {
360
488
  method: "POST",
361
- headers: { Accept: "application/json", "Content-Type": contentType, "User-Agent": "Dari/1.0" },
489
+ headers: { Accept: "application/json", "Content-Type": contentType, "User-Agent": "Dari/1.0", ...headers },
362
490
  body,
363
491
  signal: AbortSignal.timeout(REQUEST_TIMEOUT_MS),
364
492
  });
@@ -366,10 +494,13 @@ async function requestJson(
366
494
  throw new SubscriptionOAuthProviderError(`${operation} could not reach the provider.`);
367
495
  }
368
496
  if (!response.ok) {
369
- await response.body?.cancel();
497
+ // Only the RFC 6749 `error` code is kept; the rest may carry provider detail.
498
+ const failure: unknown = await response.json().catch(() => undefined);
499
+ const errorCode = isRecord(failure) && typeof failure.error === "string" ? failure.error : undefined;
370
500
  throw new SubscriptionOAuthProviderError(
371
501
  `${operation} failed with provider status ${response.status}.`,
372
502
  response.status,
503
+ errorCode,
373
504
  );
374
505
  }
375
506
  let decoded: unknown;
@@ -13,7 +13,7 @@
13
13
  import type { Database } from "bun:sqlite";
14
14
  import { randomBytes, randomUUID } from "node:crypto";
15
15
 
16
- import type { OAuthTokens, SubscriptionProvider } from "./oauth";
16
+ import type { OAuthTokens, SubscriptionProvider } from "./oauth.js";
17
17
 
18
18
  export type SubscriptionCredential = {
19
19
  id: string;
@@ -47,6 +47,7 @@ export type PendingOAuthSession = {
47
47
  const BASE_NAMES: Record<SubscriptionProvider, string> = {
48
48
  anthropic_claude_code: "ANTHROPIC_CLAUDE_CODE_OAUTH_TOKEN",
49
49
  openai_codex: "OPENAI_CODEX_OAUTH_TOKEN",
50
+ meta_muse: "META_MUSE_OAUTH_TOKEN",
50
51
  };
51
52
 
52
53
  type CredentialRow = {
@@ -1,6 +1,6 @@
1
1
  import { parseSelectorDecision } from "@mupt-ai/dari-router/policy-engine";
2
- import { HttpError } from "../http/errors";
3
- import type { SelectorBackend } from "./routing";
2
+ import { HttpError } from "../http/errors.js";
3
+ import type { SelectorBackend } from "./routing.js";
4
4
 
5
5
  export const DARI_AUTO_ROUTING_ENDPOINT = "https://routing.dari.dev/v1/auto-router";
6
6
  // Same selector identity and input budget as `createAutoRouter` in
@@ -8,9 +8,9 @@ import {
8
8
  type RouterEval,
9
9
  } from "@mupt-ai/dari-router/policy-engine";
10
10
 
11
- import { publicCatalogSelectorEvals } from "../context/eval_catalog";
12
- import { scrubSecrets } from "../telemetry/scrub";
13
- import type { ResolvedRouter } from "../types";
11
+ import { publicCatalogSelectorEvals } from "../context/eval_catalog.js";
12
+ import { scrubSecrets } from "../telemetry/scrub.js";
13
+ import type { ResolvedRouter } from "../types.js";
14
14
 
15
15
  export type EvalRelevanceDetails =
16
16
  | {
@@ -1,4 +1,4 @@
1
- import type { SelectorBackend } from "./routing";
1
+ import type { SelectorBackend } from "./routing.js";
2
2
 
3
3
  const PRIORITY_SELECTOR_MODEL = "dari-gateway/priority";
4
4
  // Priority selection reads no messages, so the sized selector input only