@oneciel-ai/ciel-runtime 0.1.1 → 0.2.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 (287) hide show
  1. package/README.md +132 -0
  2. package/ciel-runtime-menu.py +56 -6
  3. package/ciel_runtime.py +9379 -35909
  4. package/ciel_runtime_support/advisor_client.py +193 -0
  5. package/ciel_runtime_support/advisor_policy.py +320 -0
  6. package/ciel_runtime_support/advisor_refinement.py +160 -0
  7. package/ciel_runtime_support/advisor_request_builder.py +261 -0
  8. package/ciel_runtime_support/agy_installer.py +169 -0
  9. package/ciel_runtime_support/agy_mcp_restore.py +182 -0
  10. package/ciel_runtime_support/anthropic_model_policy.py +186 -0
  11. package/ciel_runtime_support/anthropic_response_writer.py +255 -0
  12. package/ciel_runtime_support/anthropic_tool_turns.py +130 -0
  13. package/ciel_runtime_support/api_key_cooldown.py +159 -0
  14. package/ciel_runtime_support/architecture.py +488 -1
  15. package/ciel_runtime_support/architecture_budget.py +42 -0
  16. package/ciel_runtime_support/channel_backlog.py +90 -0
  17. package/ciel_runtime_support/channel_cli.py +119 -0
  18. package/ciel_runtime_support/channel_compact_injection.py +82 -0
  19. package/ciel_runtime_support/channel_compact_poll.py +67 -0
  20. package/ciel_runtime_support/channel_compact_request_repository.py +113 -0
  21. package/ciel_runtime_support/channel_config_service.py +281 -0
  22. package/ciel_runtime_support/channel_connection_lifecycle.py +180 -0
  23. package/ciel_runtime_support/channel_connection_registry.py +128 -0
  24. package/ciel_runtime_support/channel_connection_worker.py +284 -0
  25. package/ciel_runtime_support/channel_cursor_recovery.py +92 -0
  26. package/ciel_runtime_support/channel_cursor_repository.py +89 -0
  27. package/ciel_runtime_support/channel_cursor_service.py +178 -0
  28. package/ciel_runtime_support/channel_event_identity.py +212 -0
  29. package/ciel_runtime_support/channel_event_projection.py +315 -0
  30. package/ciel_runtime_support/channel_inflight.py +127 -0
  31. package/ciel_runtime_support/channel_injection.py +115 -0
  32. package/ciel_runtime_support/channel_launch_guard_repository.py +58 -0
  33. package/ciel_runtime_support/channel_launch_policy.py +180 -0
  34. package/ciel_runtime_support/channel_llm_context.py +156 -0
  35. package/ciel_runtime_support/channel_mcp_discovery.py +186 -0
  36. package/ciel_runtime_support/channel_mcp_http_controller.py +239 -0
  37. package/ciel_runtime_support/channel_mcp_ownership.py +148 -0
  38. package/ciel_runtime_support/channel_mcp_tools.py +240 -0
  39. package/ciel_runtime_support/channel_mcp_transport.py +394 -0
  40. package/ciel_runtime_support/channel_message_dedupe.py +65 -0
  41. package/ciel_runtime_support/channel_message_policy.py +256 -0
  42. package/ciel_runtime_support/channel_message_prompt.py +305 -0
  43. package/ciel_runtime_support/channel_message_repository.py +234 -0
  44. package/ciel_runtime_support/channel_notification_projection.py +217 -0
  45. package/ciel_runtime_support/channel_panel.py +162 -0
  46. package/ciel_runtime_support/channel_pending_injection.py +209 -0
  47. package/ciel_runtime_support/channel_pending_poll.py +109 -0
  48. package/ciel_runtime_support/channel_probe_cache.py +433 -0
  49. package/ciel_runtime_support/channel_probe_report.py +101 -0
  50. package/ciel_runtime_support/channel_runtime_environment.py +181 -0
  51. package/ciel_runtime_support/channel_session_lifecycle.py +114 -0
  52. package/ciel_runtime_support/channel_session_repository.py +90 -0
  53. package/ciel_runtime_support/channel_terminal_dispatch.py +115 -0
  54. package/ciel_runtime_support/channel_terminal_input.py +277 -0
  55. package/ciel_runtime_support/channel_terminal_proxy.py +447 -0
  56. package/ciel_runtime_support/channel_tool_context.py +166 -0
  57. package/ciel_runtime_support/channel_transcript.py +414 -0
  58. package/ciel_runtime_support/channel_transcript_repository.py +96 -0
  59. package/ciel_runtime_support/channel_wake_claim_repository.py +126 -0
  60. package/ciel_runtime_support/channel_wake_delivery_repository.py +88 -0
  61. package/ciel_runtime_support/chat_files.py +138 -0
  62. package/ciel_runtime_support/chat_http_controller.py +235 -0
  63. package/ciel_runtime_support/claude_environment.py +375 -0
  64. package/ciel_runtime_support/claude_router.py +247 -193
  65. package/ciel_runtime_support/cli_dispatch.py +792 -0
  66. package/ciel_runtime_support/cli_parser.py +165 -0
  67. package/ciel_runtime_support/cli_usage.py +100 -0
  68. package/ciel_runtime_support/codex_app_server.py +20 -5
  69. package/ciel_runtime_support/codex_channel_sse_launch.py +87 -0
  70. package/ciel_runtime_support/codex_cli.py +42 -6
  71. package/ciel_runtime_support/codex_config.py +323 -0
  72. package/ciel_runtime_support/codex_launch_configuration.py +240 -0
  73. package/ciel_runtime_support/codex_launch_policy.py +66 -0
  74. package/ciel_runtime_support/codex_mcp_integration.py +195 -0
  75. package/ciel_runtime_support/codex_mcp_restore.py +304 -0
  76. package/ciel_runtime_support/codex_model_catalog.py +133 -0
  77. package/ciel_runtime_support/codex_process_lifecycle.py +271 -0
  78. package/ciel_runtime_support/codex_router.py +147 -1
  79. package/ciel_runtime_support/codex_session_repository.py +115 -0
  80. package/ciel_runtime_support/codex_session_selection.py +114 -0
  81. package/ciel_runtime_support/command_asset_installer.py +103 -0
  82. package/ciel_runtime_support/compatibility_probe.py +295 -0
  83. package/ciel_runtime_support/compatibility_protocol.py +251 -0
  84. package/ciel_runtime_support/compatibility_runtime.py +166 -0
  85. package/ciel_runtime_support/compatibility_test.py +370 -0
  86. package/ciel_runtime_support/config_migrations.py +307 -0
  87. package/ciel_runtime_support/config_repository.py +175 -0
  88. package/ciel_runtime_support/config_value_codec.py +64 -0
  89. package/ciel_runtime_support/configuration_cli.py +374 -0
  90. package/ciel_runtime_support/context_compaction.py +280 -0
  91. package/ciel_runtime_support/context_setup.py +208 -0
  92. package/ciel_runtime_support/context_summary_policy.py +392 -0
  93. package/ciel_runtime_support/credential_cli.py +104 -0
  94. package/ciel_runtime_support/credential_management.py +261 -0
  95. package/ciel_runtime_support/credentials.py +269 -0
  96. package/ciel_runtime_support/executable_discovery.py +141 -0
  97. package/ciel_runtime_support/github_copilot_oauth.py +335 -0
  98. package/ciel_runtime_support/github_copilot_oauth_runtime.py +213 -0
  99. package/ciel_runtime_support/header_forwarding.py +73 -0
  100. package/ciel_runtime_support/headless_config.py +221 -0
  101. package/ciel_runtime_support/http_response.py +129 -0
  102. package/ciel_runtime_support/install_diagnostics.py +149 -0
  103. package/ciel_runtime_support/kimi_identity.py +123 -0
  104. package/ciel_runtime_support/launch_diagnostics.py +204 -0
  105. package/ciel_runtime_support/launch_state.py +127 -0
  106. package/ciel_runtime_support/live_api_key_controller.py +58 -0
  107. package/ciel_runtime_support/llm_config_http.py +148 -0
  108. package/ciel_runtime_support/llm_option_config.py +259 -0
  109. package/ciel_runtime_support/llm_presentation_data.py +447 -0
  110. package/ciel_runtime_support/llm_presets.py +773 -0
  111. package/ciel_runtime_support/lm_studio_runtime.py +401 -0
  112. package/ciel_runtime_support/managed_mcp_config.py +144 -0
  113. package/ciel_runtime_support/managed_mcp_discovery.py +151 -0
  114. package/ciel_runtime_support/managed_service_cleanup.py +89 -0
  115. package/ciel_runtime_support/mcp_config_reader.py +230 -0
  116. package/ciel_runtime_support/mcp_http_proxy.py +607 -0
  117. package/ciel_runtime_support/mcp_inventory.py +59 -0
  118. package/ciel_runtime_support/mcp_notification_wait_policy.py +159 -0
  119. package/ciel_runtime_support/mcp_probe_codec.py +136 -0
  120. package/ciel_runtime_support/mcp_probe_transport.py +328 -0
  121. package/ciel_runtime_support/mcp_proxy_codec.py +345 -0
  122. package/ciel_runtime_support/mcp_proxy_config.py +107 -0
  123. package/ciel_runtime_support/mcp_proxy_notifications.py +261 -0
  124. package/ciel_runtime_support/mcp_proxy_process.py +560 -0
  125. package/ciel_runtime_support/mcp_split_proxy_http.py +165 -0
  126. package/ciel_runtime_support/mcp_stdio_probe.py +240 -0
  127. package/ciel_runtime_support/mcp_transport.py +146 -0
  128. package/ciel_runtime_support/model_cache_lifecycle.py +78 -0
  129. package/ciel_runtime_support/model_catalog_projection.py +61 -0
  130. package/ciel_runtime_support/model_context_hints.py +109 -0
  131. package/ciel_runtime_support/model_panel.py +147 -0
  132. package/ciel_runtime_support/model_registry_repository.py +231 -0
  133. package/ciel_runtime_support/npm_runtime.py +191 -0
  134. package/ciel_runtime_support/ollama_catalog.py +462 -0
  135. package/ciel_runtime_support/ollama_catalog_cli.py +41 -0
  136. package/ciel_runtime_support/ollama_catalog_repository.py +75 -0
  137. package/ciel_runtime_support/ollama_context_sync.py +87 -0
  138. package/ciel_runtime_support/ollama_forwarding.py +449 -0
  139. package/ciel_runtime_support/openai_chat_passthrough.py +67 -0
  140. package/ciel_runtime_support/openai_chat_router.py +64 -0
  141. package/ciel_runtime_support/openai_forwarding.py +194 -0
  142. package/ciel_runtime_support/openai_responses_router.py +291 -0
  143. package/ciel_runtime_support/openai_responses_stream.py +135 -0
  144. package/ciel_runtime_support/output_budget.py +89 -0
  145. package/ciel_runtime_support/package_lifecycle.py +217 -0
  146. package/ciel_runtime_support/plan_artifact_controller.py +104 -0
  147. package/ciel_runtime_support/prelaunch.py +959 -0
  148. package/ciel_runtime_support/prelaunch_launch_preference.py +75 -0
  149. package/ciel_runtime_support/prelaunch_panel_projection.py +396 -0
  150. package/ciel_runtime_support/prelaunch_terminal.py +764 -0
  151. package/ciel_runtime_support/process_control.py +708 -0
  152. package/ciel_runtime_support/prompt_compaction.py +322 -0
  153. package/ciel_runtime_support/prompt_injection.py +176 -0
  154. package/ciel_runtime_support/protocols/__init__.py +24 -0
  155. package/ciel_runtime_support/protocols/anthropic_content.py +29 -0
  156. package/ciel_runtime_support/protocols/anthropic_thinking_policy.py +336 -0
  157. package/ciel_runtime_support/protocols/chat_projection.py +315 -0
  158. package/ciel_runtime_support/protocols/conversation_policy.py +217 -0
  159. package/ciel_runtime_support/protocols/conversation_turn_policy.py +972 -0
  160. package/ciel_runtime_support/protocols/ollama_chat.py +111 -0
  161. package/ciel_runtime_support/protocols/ollama_response.py +231 -0
  162. package/ciel_runtime_support/protocols/openai_reasoning.py +75 -0
  163. package/ciel_runtime_support/protocols/openai_responses.py +271 -0
  164. package/ciel_runtime_support/protocols/pseudo_tool_history.py +248 -0
  165. package/ciel_runtime_support/protocols/tool_result_projection.py +112 -0
  166. package/ciel_runtime_support/provider_adapters.py +160 -0
  167. package/ciel_runtime_support/provider_catalog_sources.py +316 -0
  168. package/ciel_runtime_support/provider_choice.py +201 -0
  169. package/ciel_runtime_support/provider_compatibility.py +165 -0
  170. package/ciel_runtime_support/provider_config_mutations.py +361 -0
  171. package/ciel_runtime_support/provider_configuration_service.py +162 -0
  172. package/ciel_runtime_support/provider_context.py +308 -0
  173. package/ciel_runtime_support/provider_contract_projection.py +73 -0
  174. package/ciel_runtime_support/provider_descriptor.py +82 -0
  175. package/ciel_runtime_support/provider_endpoint_policy.py +130 -0
  176. package/ciel_runtime_support/provider_endpoint_probe.py +165 -0
  177. package/ciel_runtime_support/provider_launch_endpoint.py +109 -0
  178. package/ciel_runtime_support/provider_limits.py +457 -0
  179. package/ciel_runtime_support/provider_model_identity.py +139 -0
  180. package/ciel_runtime_support/provider_model_selection.py +431 -0
  181. package/ciel_runtime_support/provider_model_specs.py +142 -0
  182. package/ciel_runtime_support/provider_models.py +263 -0
  183. package/ciel_runtime_support/provider_network.py +176 -0
  184. package/ciel_runtime_support/provider_option_cli.py +238 -0
  185. package/ciel_runtime_support/provider_option_panel.py +275 -0
  186. package/ciel_runtime_support/provider_option_status.py +192 -0
  187. package/ciel_runtime_support/provider_policy.py +101 -0
  188. package/ciel_runtime_support/provider_query_policy.py +67 -0
  189. package/ciel_runtime_support/provider_readiness.py +112 -0
  190. package/ciel_runtime_support/provider_request_access.py +131 -0
  191. package/ciel_runtime_support/provider_request_builder.py +250 -0
  192. package/ciel_runtime_support/provider_responses_passthrough.py +81 -0
  193. package/ciel_runtime_support/provider_runtime_info.py +113 -0
  194. package/ciel_runtime_support/provider_runtime_modes.py +150 -0
  195. package/ciel_runtime_support/provider_sampling_policy.py +46 -0
  196. package/ciel_runtime_support/provider_status.py +145 -0
  197. package/ciel_runtime_support/provider_timeout_policy.py +184 -0
  198. package/ciel_runtime_support/provider_tool_policy.py +145 -0
  199. package/ciel_runtime_support/providers/__init__.py +65 -0
  200. package/ciel_runtime_support/providers/anthropic.py +160 -0
  201. package/ciel_runtime_support/providers/anthropic_catalog.py +119 -0
  202. package/ciel_runtime_support/providers/base.py +232 -0
  203. package/ciel_runtime_support/providers/catalog.py +326 -0
  204. package/ciel_runtime_support/providers/cloud.py +194 -0
  205. package/ciel_runtime_support/providers/constants.py +54 -0
  206. package/ciel_runtime_support/providers/deepseek.py +115 -0
  207. package/ciel_runtime_support/providers/fireworks.py +158 -0
  208. package/ciel_runtime_support/providers/github_copilot_oauth.py +199 -0
  209. package/ciel_runtime_support/providers/kimi.py +297 -0
  210. package/ciel_runtime_support/providers/lm_studio.py +76 -0
  211. package/ciel_runtime_support/providers/meta.py +257 -0
  212. package/ciel_runtime_support/providers/native.py +194 -0
  213. package/ciel_runtime_support/providers/nim.py +69 -0
  214. package/ciel_runtime_support/providers/nvidia.py +158 -0
  215. package/ciel_runtime_support/providers/nvidia_runtime.py +285 -0
  216. package/ciel_runtime_support/providers/ollama.py +181 -0
  217. package/ciel_runtime_support/providers/ollama_context.py +195 -0
  218. package/ciel_runtime_support/providers/ollama_runtime.py +213 -0
  219. package/ciel_runtime_support/providers/opencode.py +220 -0
  220. package/ciel_runtime_support/providers/opencode_go.py +37 -0
  221. package/ciel_runtime_support/providers/openrouter.py +57 -0
  222. package/ciel_runtime_support/providers/vllm.py +65 -0
  223. package/ciel_runtime_support/providers/zai.py +119 -0
  224. package/ciel_runtime_support/pseudo_tool_parser.py +115 -0
  225. package/ciel_runtime_support/rate_limit_policy.py +117 -0
  226. package/ciel_runtime_support/rate_limit_repository.py +154 -0
  227. package/ciel_runtime_support/registry.py +46 -0
  228. package/ciel_runtime_support/request_shortcuts.py +253 -0
  229. package/ciel_runtime_support/request_trace.py +323 -0
  230. package/ciel_runtime_support/response_collection.py +209 -0
  231. package/ciel_runtime_support/router_access.py +238 -0
  232. package/ciel_runtime_support/router_client_lifecycle.py +366 -0
  233. package/ciel_runtime_support/router_health_policy.py +101 -0
  234. package/ciel_runtime_support/router_http.py +513 -0
  235. package/ciel_runtime_support/router_process_lifecycle.py +401 -0
  236. package/ciel_runtime_support/router_rate_limit_service.py +285 -0
  237. package/ciel_runtime_support/router_server_runtime.py +103 -0
  238. package/ciel_runtime_support/router_shortcuts.py +201 -0
  239. package/ciel_runtime_support/routing_fallback.py +73 -0
  240. package/ciel_runtime_support/runtime_activity_repository.py +143 -0
  241. package/ciel_runtime_support/runtime_adapters.py +104 -0
  242. package/ciel_runtime_support/runtime_command_factory.py +73 -0
  243. package/ciel_runtime_support/runtime_compatibility.py +50 -0
  244. package/ciel_runtime_support/runtime_constants.py +178 -0
  245. package/ciel_runtime_support/runtime_launch.py +1602 -0
  246. package/ciel_runtime_support/runtime_llm_options.py +312 -0
  247. package/ciel_runtime_support/runtime_logging.py +161 -0
  248. package/ciel_runtime_support/runtime_paths.py +157 -0
  249. package/ciel_runtime_support/runtime_restart.py +84 -0
  250. package/ciel_runtime_support/runtime_upgrade.py +149 -0
  251. package/ciel_runtime_support/secure_json_repository.py +55 -0
  252. package/ciel_runtime_support/session_import.py +356 -0
  253. package/ciel_runtime_support/settings_repository.py +8 -0
  254. package/ciel_runtime_support/slash_command_assets.py +211 -0
  255. package/ciel_runtime_support/sse_stream.py +57 -0
  256. package/ciel_runtime_support/sse_trace.py +225 -0
  257. package/ciel_runtime_support/statusline_script.py +593 -0
  258. package/ciel_runtime_support/statusline_settings.py +53 -0
  259. package/ciel_runtime_support/stream_chunk_policy.py +18 -0
  260. package/ciel_runtime_support/streaming_anthropic.py +1955 -0
  261. package/ciel_runtime_support/synthetic_tool_policy.py +105 -0
  262. package/ciel_runtime_support/terminal_platform_io.py +127 -0
  263. package/ciel_runtime_support/timeout_profile.py +196 -0
  264. package/ciel_runtime_support/tool_dialects.py +85 -0
  265. package/ciel_runtime_support/tool_exposure_policy.py +63 -0
  266. package/ciel_runtime_support/tool_guard_hooks.py +218 -0
  267. package/ciel_runtime_support/tool_request_projection.py +96 -0
  268. package/ciel_runtime_support/tool_schema.py +483 -0
  269. package/ciel_runtime_support/tool_side_effect_dedupe.py +95 -0
  270. package/ciel_runtime_support/ui_text.py +266 -0
  271. package/ciel_runtime_support/upstream_error_policy.py +104 -0
  272. package/ciel_runtime_support/upstream_retry.py +419 -0
  273. package/ciel_runtime_support/upstream_stream_io.py +106 -0
  274. package/ciel_runtime_support/usage_events.py +96 -0
  275. package/ciel_runtime_support/visible_stream_filters.py +130 -0
  276. package/ciel_runtime_support/web_endpoints.py +447 -0
  277. package/ciel_runtime_support/web_ui.py +915 -0
  278. package/ciel_runtime_support/web_ui_controller.py +189 -0
  279. package/ciel_runtime_support/windows_console_input.py +137 -0
  280. package/ciel_runtime_support/windows_console_mode.py +112 -0
  281. package/docs/Architecture.md +54 -0
  282. package/docs/Configuration.md +17 -0
  283. package/docs/Module-Map.md +1093 -26
  284. package/docs/Providers.md +46 -1
  285. package/docs/adr/0001-runtime-bounded-contexts.md +295 -0
  286. package/npm-bin/run-ciel-runtime.js +22 -2
  287. package/package.json +9 -2
@@ -0,0 +1,158 @@
1
+ """Fireworks.ai provider adapter."""
2
+
3
+ from dataclasses import dataclass, field, replace
4
+ import re
5
+ from typing import Any, Mapping
6
+ from urllib.parse import quote
7
+
8
+ from ..architecture import (
9
+ MessageProtocol,
10
+ ProviderCapabilities,
11
+ ProviderConfigurationPolicy,
12
+ ProviderConfig,
13
+ ProviderContextPolicy,
14
+ ProviderModelCatalogPolicy,
15
+ ProviderOptionPresentationPolicy,
16
+ ProviderStatusPolicy,
17
+ )
18
+ from .base import (
19
+ OpenAICompatibleProviderAdapter,
20
+ configuration_policy,
21
+ provider_configuration,
22
+ )
23
+ from .constants import DEFAULT_REQUEST_TIMEOUT_MS, PROVIDER_DEFAULT_BASE_URLS
24
+
25
+
26
+ @dataclass(frozen=True)
27
+ class FireworksProviderAdapter(OpenAICompatibleProviderAdapter):
28
+ name: str = "fireworks"
29
+ base_url: str = PROVIDER_DEFAULT_BASE_URLS["fireworks"]
30
+ configuration_defaults_value: dict = field(
31
+ default_factory=lambda: provider_configuration(
32
+ "accounts/fireworks/models/kimi-k2p5",
33
+ custom_models=("accounts/fireworks/models/kimi-k2p5",),
34
+ native_compat=True,
35
+ account_id="fireworks",
36
+ model_api_base_url="https://api.fireworks.ai",
37
+ context_window=262144,
38
+ max_output_tokens=8192,
39
+ context_reserve_tokens=8192,
40
+ request_timeout_ms=DEFAULT_REQUEST_TIMEOUT_MS,
41
+ stream_enabled=True,
42
+ stream_word_chunking=False,
43
+ haiku_model="accounts/fireworks/models/kimi-k2p5",
44
+ subagent_model="accounts/fireworks/models/kimi-k2p5",
45
+ )
46
+ )
47
+ send_placeholder_key: bool = True
48
+ api_key_display_name_value: str = "Fireworks.ai"
49
+ api_key_launch_error_value: str = (
50
+ "Launch blocked: Fireworks.ai requires a Fireworks API key."
51
+ )
52
+ capabilities_value: ProviderCapabilities = field(
53
+ default_factory=lambda: ProviderCapabilities(
54
+ upstream_protocol="openai_chat", requires_api_key=True
55
+ )
56
+ )
57
+ model_catalog_policy_value: ProviderModelCatalogPolicy = field(
58
+ default_factory=lambda: ProviderModelCatalogPolicy(kind="fireworks")
59
+ )
60
+
61
+ def context_policy(self, config: ProviderConfig) -> ProviderContextPolicy:
62
+ del config
63
+ return ProviderContextPolicy(
64
+ capacity_strategy="configured_first",
65
+ settings_strategy="standard",
66
+ hosted_timeout=True,
67
+ )
68
+
69
+ def option_presentation_policy(
70
+ self, config: ProviderConfig
71
+ ) -> ProviderOptionPresentationPolicy:
72
+ return replace(super().option_presentation_policy(config), show_sampling=False)
73
+
74
+ def supported_protocols(
75
+ self, config: ProviderConfig, model: str | None = None
76
+ ) -> frozenset[MessageProtocol]:
77
+ del config, model
78
+ return frozenset({"anthropic_messages", "openai_chat"})
79
+
80
+ def status_policy(self, config: ProviderConfig) -> ProviderStatusPolicy:
81
+ account_id = str(config.options.get("account_id") or "").strip()
82
+ if not account_id:
83
+ match = re.match(r"^accounts/([^/]+)/models/[^/]+$", config.model)
84
+ account_id = match.group(1) if match else "fireworks"
85
+ return ProviderStatusPolicy(
86
+ kind="catalog",
87
+ label="Fireworks.ai",
88
+ catalog_path=f"/v1/accounts/{quote(account_id, safe='')}/models?pageSize=1",
89
+ catalog_scope="fireworks_management",
90
+ catalog_count_label="sampled",
91
+ )
92
+
93
+ def select_protocol(
94
+ self,
95
+ operation: MessageProtocol,
96
+ config: ProviderConfig,
97
+ model: str | None = None,
98
+ ) -> MessageProtocol:
99
+ del config, model
100
+ return (
101
+ "openai_chat"
102
+ if operation in {"openai_chat", "openai_responses"}
103
+ else "anthropic_messages"
104
+ )
105
+
106
+ def configuration_policy(
107
+ self, config: ProviderConfig
108
+ ) -> ProviderConfigurationPolicy:
109
+ del config
110
+ return configuration_policy(
111
+ text_option_aliases={
112
+ "account": "account_id",
113
+ "account_id": "account_id",
114
+ "management_base_url": "model_api_base_url",
115
+ "model_api_base_url": "model_api_base_url",
116
+ "model_base_url": "model_api_base_url",
117
+ "models_base_url": "model_api_base_url",
118
+ },
119
+ strip_trailing_slash_fields=frozenset({"model_api_base_url"}),
120
+ )
121
+
122
+ def project_model_metadata(self, raw: Mapping[str, Any]) -> Mapping[str, Any]:
123
+ metadata = dict(super().project_model_metadata(raw))
124
+ for source_key, target_key in (
125
+ ("displayName", "display_name"),
126
+ ("description", "description"),
127
+ ("kind", "kind"),
128
+ ("importedFrom", "imported_from"),
129
+ ):
130
+ value = raw.get(source_key)
131
+ if value is not None:
132
+ metadata[target_key] = value
133
+ for source_key, target_key in (
134
+ ("supportsTools", "supports_tool_call"),
135
+ ("supportsImageInput", "supports_vision"),
136
+ ("public", "public"),
137
+ ("supportsServerless", "supports_serverless"),
138
+ ):
139
+ value = raw.get(source_key)
140
+ if isinstance(value, bool):
141
+ metadata[target_key] = value
142
+ details = raw.get("baseModelDetails")
143
+ if isinstance(details, Mapping):
144
+ if details.get("parameterCount") is not None:
145
+ metadata["parameter_count"] = str(details["parameterCount"])
146
+ for source_key, target_key in (
147
+ ("worldSize", "world_size"),
148
+ ("checkpointFormat", "checkpoint_format"),
149
+ ("modelType", "model_type"),
150
+ ("defaultPrecision", "default_precision"),
151
+ ):
152
+ value = details.get(source_key)
153
+ if value is not None:
154
+ metadata[target_key] = value
155
+ return metadata
156
+
157
+
158
+ __all__ = ["FireworksProviderAdapter"]
@@ -0,0 +1,199 @@
1
+ """GitHub Copilot provider backed by GitHub Device OAuth."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from dataclasses import dataclass, field
6
+ from typing import Any, Mapping
7
+
8
+ from ..architecture import (
9
+ MessageProtocol,
10
+ ProviderCapabilities,
11
+ ProviderConfig,
12
+ ProviderContextPolicy,
13
+ ProviderModelCatalogPolicy,
14
+ ProviderOptionPresentationPolicy,
15
+ ProviderRequestPolicy,
16
+ ProviderStatusPolicy,
17
+ )
18
+ from ..github_copilot_oauth import (
19
+ COPILOT_API_VERSION,
20
+ COPILOT_CHAT_VERSION,
21
+ COPILOT_USER_AGENT,
22
+ COPILOT_VSCODE_VERSION,
23
+ )
24
+ from .base import HttpBearerProviderAdapter, provider_configuration
25
+
26
+
27
+ GITHUB_COPILOT_BASE_URL = "https://api.githubcopilot.com"
28
+ GITHUB_COPILOT_MODELS = (
29
+ "gpt-5.4",
30
+ "gpt-5.3-codex",
31
+ "gpt-5.2-codex",
32
+ "claude-sonnet-4.6",
33
+ "claude-opus-4.6",
34
+ "gemini-3.1-pro-preview",
35
+ )
36
+
37
+
38
+ @dataclass(frozen=True)
39
+ class GitHubCopilotOAuthProviderAdapter(HttpBearerProviderAdapter):
40
+ name: str = "github-copilot-oauth"
41
+ base_url: str = GITHUB_COPILOT_BASE_URL
42
+ configuration_defaults_value: dict = field(
43
+ default_factory=lambda: provider_configuration(
44
+ GITHUB_COPILOT_MODELS[0],
45
+ custom_models=GITHUB_COPILOT_MODELS,
46
+ native_compat=True,
47
+ context_window=128_000,
48
+ max_output_tokens=16_384,
49
+ context_reserve_tokens=16_384,
50
+ request_timeout_ms=300_000,
51
+ stream_enabled=True,
52
+ stream_word_chunking=False,
53
+ )
54
+ )
55
+ include_x_api_key: bool = False
56
+ require_api_key: bool = True
57
+ api_key_display_name_value: str = "GitHub Copilot OAuth"
58
+ api_key_launch_error_value: str = (
59
+ "Launch blocked: GitHub Copilot OAuth login is required. "
60
+ "Run: ciel-runtimectl copilot-oauth login"
61
+ )
62
+ capabilities_value: ProviderCapabilities = field(
63
+ default_factory=lambda: ProviderCapabilities(
64
+ upstream_protocol="openai_chat",
65
+ supports_thinking=True,
66
+ preserves_anthropic_thinking=True,
67
+ requires_api_key=True,
68
+ )
69
+ )
70
+ request_policy_value: ProviderRequestPolicy = field(
71
+ default_factory=lambda: ProviderRequestPolicy(
72
+ chat_path="/chat/completions",
73
+ models_path="/models",
74
+ )
75
+ )
76
+ model_catalog_policy_value: ProviderModelCatalogPolicy = field(
77
+ default_factory=lambda: ProviderModelCatalogPolicy(
78
+ kind="openai",
79
+ fallback_models=GITHUB_COPILOT_MODELS,
80
+ allow_configured_fallback=True,
81
+ )
82
+ )
83
+
84
+ def build_headers(
85
+ self,
86
+ config: ProviderConfig,
87
+ api_key: str | None,
88
+ ) -> Mapping[str, str]:
89
+ headers = dict(super().build_headers(config, api_key))
90
+ headers.update(
91
+ {
92
+ "copilot-integration-id": "vscode-chat",
93
+ "editor-version": f"vscode/{COPILOT_VSCODE_VERSION}",
94
+ "editor-plugin-version": (
95
+ f"copilot-chat/{COPILOT_CHAT_VERSION}"
96
+ ),
97
+ "user-agent": COPILOT_USER_AGENT,
98
+ "openai-intent": "conversation-panel",
99
+ "x-github-api-version": COPILOT_API_VERSION,
100
+ "x-vscode-user-agent-library-version": "electron-fetch",
101
+ "X-Initiator": "user",
102
+ "Accept": "application/json",
103
+ }
104
+ )
105
+ return headers
106
+
107
+ def build_model_headers(
108
+ self,
109
+ config: ProviderConfig,
110
+ api_key: str | None,
111
+ ) -> Mapping[str, str]:
112
+ return self.build_headers(config, api_key)
113
+
114
+ def context_policy(self, config: ProviderConfig) -> ProviderContextPolicy:
115
+ del config
116
+ return ProviderContextPolicy(
117
+ capacity_strategy="configured_first",
118
+ settings_strategy="standard",
119
+ hosted_timeout=True,
120
+ )
121
+
122
+ def supported_protocols(
123
+ self,
124
+ config: ProviderConfig,
125
+ model: str | None = None,
126
+ ) -> frozenset[MessageProtocol]:
127
+ del config, model
128
+ return frozenset(
129
+ {"openai_chat", "openai_responses", "anthropic_messages"}
130
+ )
131
+
132
+ def select_protocol(
133
+ self,
134
+ operation: MessageProtocol,
135
+ config: ProviderConfig,
136
+ model: str | None = None,
137
+ ) -> MessageProtocol:
138
+ del config
139
+ normalized = str(model or "").lower()
140
+ if "claude" in normalized:
141
+ return "anthropic_messages"
142
+ if operation == "openai_responses" and not any(
143
+ family in normalized for family in ("gemini", "claude")
144
+ ):
145
+ return "openai_responses"
146
+ return "openai_chat"
147
+
148
+ def router_native_anthropic_enabled(
149
+ self,
150
+ config: ProviderConfig,
151
+ model: str | None = None,
152
+ ) -> bool:
153
+ del config
154
+ return "claude" in str(model or "").lower()
155
+
156
+ def normalize_request_options(
157
+ self,
158
+ config: ProviderConfig,
159
+ request: Mapping[str, Any],
160
+ ) -> Mapping[str, Any]:
161
+ del config
162
+ normalized = dict(request)
163
+ if normalized.get("reasoning_effort") == "none":
164
+ normalized.pop("reasoning_effort", None)
165
+ model = str(normalized.get("model") or "").lower()
166
+ if (
167
+ ("gpt-5" in model or model.startswith(("o1", "o3", "o4")))
168
+ and "max_tokens" in normalized
169
+ ):
170
+ normalized["max_completion_tokens"] = normalized.pop("max_tokens")
171
+ return normalized
172
+
173
+ def option_presentation_policy(
174
+ self, config: ProviderConfig
175
+ ) -> ProviderOptionPresentationPolicy:
176
+ del config
177
+ return ProviderOptionPresentationPolicy(
178
+ show_native=True,
179
+ show_tool_choice=True,
180
+ show_stream=True,
181
+ show_rate_limit_controls=True,
182
+ show_sampling_controls=False,
183
+ show_ip_family_control=True,
184
+ )
185
+
186
+ def status_policy(self, config: ProviderConfig) -> ProviderStatusPolicy:
187
+ del config
188
+ return ProviderStatusPolicy(
189
+ kind="catalog",
190
+ label="GitHub Copilot OAuth",
191
+ catalog_path="/models",
192
+ )
193
+
194
+
195
+ __all__ = [
196
+ "GITHUB_COPILOT_BASE_URL",
197
+ "GITHUB_COPILOT_MODELS",
198
+ "GitHubCopilotOAuthProviderAdapter",
199
+ ]
@@ -0,0 +1,297 @@
1
+ """Kimi provider adapter."""
2
+
3
+ from dataclasses import dataclass, field
4
+ from pathlib import Path
5
+ from typing import Any, Mapping
6
+
7
+ from ..architecture import (
8
+ MessageProtocol,
9
+ ProviderCapabilities,
10
+ ProviderConfig,
11
+ ProviderContextPolicy,
12
+ ProviderModelCatalogPolicy,
13
+ ProviderOptionPresentationPolicy,
14
+ ProviderRequestPolicy,
15
+ ProviderStatusPolicy,
16
+ ProviderUiPolicy,
17
+ )
18
+ from .base import HttpBearerProviderAdapter, provider_configuration
19
+ from .constants import PROVIDER_DEFAULT_BASE_URLS
20
+ from ..runtime_constants import KIMI_MODEL_FALLBACK_IDS
21
+ from ..kimi_identity import identity_headers, oauth_access_token
22
+
23
+
24
+ @dataclass(frozen=True)
25
+ class KimiProviderAdapter(HttpBearerProviderAdapter):
26
+ name: str = "kimi"
27
+ base_url: str = PROVIDER_DEFAULT_BASE_URLS["kimi"]
28
+ configuration_defaults_value: dict = field(
29
+ default_factory=lambda: provider_configuration(
30
+ "kimi-for-coding",
31
+ custom_models=KIMI_MODEL_FALLBACK_IDS,
32
+ native_compat=True,
33
+ preserve_anthropic_thinking=True,
34
+ normalize_anthropic_tool_use=True,
35
+ supports_tool_choice=True,
36
+ claude_code_supported_capabilities=["effort", "thinking"],
37
+ context_window=262144,
38
+ max_output_tokens=32768,
39
+ context_reserve_tokens=32768,
40
+ request_timeout_ms=600000,
41
+ stream_enabled=True,
42
+ stream_word_chunking=False,
43
+ effort_level="high",
44
+ haiku_model="kimi-for-coding",
45
+ subagent_model="kimi-for-coding",
46
+ )
47
+ )
48
+ send_placeholder_key: bool = True
49
+ api_key_display_name_value: str = "Kimi.com"
50
+ api_key_launch_error_value: str = (
51
+ "Launch blocked: Kimi.com requires a Kimi API key."
52
+ )
53
+
54
+ def build_headers(
55
+ self, config: ProviderConfig, api_key: str | None
56
+ ) -> Mapping[str, str]:
57
+ token = api_key or oauth_access_token(Path.home())
58
+ headers = dict(super().build_headers(config, token))
59
+ headers.update(identity_headers(Path.home()))
60
+ return headers
61
+
62
+ def launch_api_key_error(self, config: ProviderConfig) -> str | None:
63
+ if oauth_access_token(Path.home()) is not None:
64
+ return None
65
+ return super().launch_api_key_error(config)
66
+ capabilities_value: ProviderCapabilities = field(
67
+ default_factory=lambda: ProviderCapabilities(
68
+ upstream_protocol="anthropic_messages",
69
+ supports_thinking=True,
70
+ requires_api_key=True,
71
+ )
72
+ )
73
+ request_policy_value: ProviderRequestPolicy = field(
74
+ default_factory=lambda: ProviderRequestPolicy(
75
+ chat_path="/v1/messages", models_path="/v1/models"
76
+ )
77
+ )
78
+ model_catalog_policy_value: ProviderModelCatalogPolicy = field(
79
+ default_factory=lambda: ProviderModelCatalogPolicy(
80
+ kind="openai", allow_configured_fallback=True
81
+ )
82
+ )
83
+
84
+ def routing_mode_update(self, enabled: bool) -> tuple[str, ...]:
85
+ return ("Kimi Code routing mode updated.", f"mode: {'kimi-routed' if enabled else 'kimi-native'}")
86
+
87
+ def selection_config_updates(self, config: ProviderConfig) -> Mapping[str, Any]:
88
+ del config
89
+ return {"route_through_router": False}
90
+
91
+ def selection_status_lines(self, config: ProviderConfig) -> tuple[str, ...]:
92
+ return (f"mode: {'kimi-routed' if config.options.get('route_through_router') else 'kimi-native'}",)
93
+
94
+ def ui_policy(self, config: ProviderConfig) -> ProviderUiPolicy:
95
+ del config
96
+ return ProviderUiPolicy(menu_label="Kimi Native", routed_menu_label="Kimi Routed", native_choice="kimi:native", routed_choice="kimi:routed")
97
+
98
+ def normalize_model_id(self, model_id: str) -> str:
99
+ raw = str(model_id or "").strip()
100
+ wants_one_million = raw.lower().endswith("[1m]")
101
+ normalized = super().normalize_model_id(raw)
102
+ lowered = normalized.lower().replace("_", "-").strip()
103
+ if lowered in ("k3", "kimi-k3", "kimi/k3", "kimi-code/k3"):
104
+ return "k3[1m]" if wants_one_million else "k3"
105
+ if lowered in (
106
+ "kimi-code/kimi-for-coding",
107
+ "kimi/kimi-for-coding",
108
+ "moonshot/kimi-for-coding",
109
+ "kimi-k2.7-code",
110
+ "kimi-k2.7-coding",
111
+ "k2.7-code",
112
+ "k2.7-coding",
113
+ ):
114
+ return "kimi-for-coding"
115
+ if lowered in (
116
+ "kimi-for-coding-highspeed",
117
+ "kimi-code/kimi-for-coding-highspeed",
118
+ "kimi/kimi-for-coding-highspeed",
119
+ ):
120
+ return "kimi-for-coding-highspeed"
121
+ return normalized
122
+
123
+ def upstream_api_model_id(self, model_id: str) -> str:
124
+ normalized = self.normalize_model_id(model_id)
125
+ return "k3" if normalized == "k3[1m]" else normalized
126
+
127
+ def model_configuration_profile(
128
+ self, config: ProviderConfig
129
+ ) -> tuple[Mapping[str, Any], str | None]:
130
+ model = self.normalize_model_id(config.model)
131
+ if model == "kimi-for-coding-highspeed":
132
+ return (
133
+ {
134
+ "context_window": 262144,
135
+ "max_model_len": 262144,
136
+ "model_profile": "kimi-k2.7-highspeed-256k",
137
+ },
138
+ "Kimi K2.7 Code HighSpeed profile applied: 256K context; "
139
+ "requires Allegretto or above and uses about 3x quota. Start a new session.",
140
+ )
141
+ if model == "kimi-for-coding":
142
+ return (
143
+ {
144
+ "context_window": 262144,
145
+ "max_model_len": 262144,
146
+ "model_profile": "kimi-k2.7-256k",
147
+ },
148
+ "Kimi K2.7 Code profile applied: 256K context with Thinking enabled. "
149
+ "Start a new session after changing models.",
150
+ )
151
+ if model not in {"k3", "k3[1m]"}:
152
+ return {}, None
153
+ context = 1048576
154
+ return (
155
+ {
156
+ "context_window": context,
157
+ "max_model_len": context,
158
+ "effort_level": "high",
159
+ "model_profile": "kimi-k3-1m",
160
+ },
161
+ "Kimi K3 profile applied: 1M context and high reasoning effort. "
162
+ "Start a new session after changing model, context, or reasoning effort.",
163
+ )
164
+
165
+ def model_selection_config_updates(
166
+ self, config: ProviderConfig, model_id: str
167
+ ) -> dict[str, str]:
168
+ del config
169
+ return {
170
+ "haiku_model": model_id,
171
+ "opus_model": model_id,
172
+ "sonnet_model": model_id,
173
+ "subagent_model": model_id,
174
+ }
175
+
176
+ def context_policy(self, config: ProviderConfig) -> ProviderContextPolicy:
177
+ del config
178
+ return ProviderContextPolicy(
179
+ capacity_strategy="hint_first",
180
+ settings_strategy="standard",
181
+ hosted_timeout=True,
182
+ )
183
+
184
+ def router_native_anthropic_enabled(
185
+ self, config: ProviderConfig, model: str | None = None
186
+ ) -> bool:
187
+ del model
188
+ return bool(config.options.get("native_compat", True))
189
+
190
+ def option_presentation_policy(
191
+ self, config: ProviderConfig
192
+ ) -> ProviderOptionPresentationPolicy:
193
+ del config
194
+ return ProviderOptionPresentationPolicy(
195
+ show_native=True,
196
+ show_tool_choice=True,
197
+ show_stream=True,
198
+ show_rate_limit_controls=True,
199
+ show_sampling_controls=False,
200
+ show_ip_family_control=True,
201
+ )
202
+
203
+ def supported_protocols(
204
+ self, config: ProviderConfig, model: str | None = None
205
+ ) -> frozenset[MessageProtocol]:
206
+ del config, model
207
+ return frozenset({"anthropic_messages", "openai_chat"})
208
+
209
+ def status_policy(self, config: ProviderConfig) -> ProviderStatusPolicy:
210
+ del config
211
+ return ProviderStatusPolicy(
212
+ kind="catalog", label="Kimi.com", catalog_path="/v1/models"
213
+ )
214
+
215
+ def select_protocol(
216
+ self,
217
+ operation: MessageProtocol,
218
+ config: ProviderConfig,
219
+ model: str | None = None,
220
+ ) -> MessageProtocol:
221
+ del config, model
222
+ return (
223
+ "openai_chat"
224
+ if operation in {"openai_chat", "openai_responses"}
225
+ else "anthropic_messages"
226
+ )
227
+
228
+ def normalize_request_options(
229
+ self, config: ProviderConfig, request: Mapping[str, Any]
230
+ ) -> Mapping[str, Any]:
231
+ del config
232
+ model = (
233
+ str(request.get("model") or "")
234
+ .split("[", 1)[0]
235
+ .strip()
236
+ .lower()
237
+ .replace("_", "-")
238
+ )
239
+ if model.startswith("ciel-runtime-kimi-"):
240
+ model = model[len("ciel-runtime-kimi-") :]
241
+ normalized = dict(request)
242
+ for key in ("temperature", "top_p", "top_k", "n"):
243
+ normalized.pop(key, None)
244
+ thinking = request.get("thinking")
245
+ if not isinstance(thinking, Mapping):
246
+ return normalized
247
+ if str(thinking.get("type") or "").strip().lower() == "disabled":
248
+ thinking = {**thinking, "type": "enabled"}
249
+ if model in {"k3", "k3-1m", "kimi-k3", "kimi/k3", "kimi-code/k3"}:
250
+ normalized["thinking"] = {
251
+ **thinking,
252
+ "effort": self._reasoning_effort(thinking.get("effort")),
253
+ }
254
+ else:
255
+ normalized["thinking"] = thinking
256
+ return normalized
257
+
258
+ def openai_reasoning_effort(
259
+ self, config: ProviderConfig, model: str, request: Mapping[str, Any]
260
+ ) -> str | None:
261
+ if self.normalize_model_id(model) not in {"k3", "k3[1m]"}:
262
+ return None
263
+ thinking = request.get("thinking")
264
+ requested = thinking.get("effort") if isinstance(thinking, Mapping) else None
265
+ if requested is None:
266
+ requested = config.options.get("effort_level")
267
+ return self._reasoning_effort(requested)
268
+
269
+ def allows_sampling_overrides(self, config: ProviderConfig) -> bool:
270
+ del config
271
+ return False
272
+
273
+ @staticmethod
274
+ def _reasoning_effort(value: Any) -> str:
275
+ effort = str(value or "high").strip().lower()
276
+ if effort == "ultra":
277
+ return "max"
278
+ if effort in {"minimum", "light"}:
279
+ return "low"
280
+ if effort in {"low", "medium", "high", "xhigh", "max"}:
281
+ return effort
282
+ return "high"
283
+
284
+ def normalize_tool_choice(
285
+ self, config: ProviderConfig, model: str, tool_choice: Any
286
+ ) -> Any:
287
+ del model
288
+ if config.options.get("supports_tool_choice") is False or not isinstance(
289
+ tool_choice, Mapping
290
+ ):
291
+ return tool_choice
292
+ if str(tool_choice.get("type") or "").strip().lower() in {"any", "tool"}:
293
+ return {"type": "auto"}
294
+ return tool_choice
295
+
296
+
297
+ __all__ = ["KimiProviderAdapter"]