@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
package/docs/Providers.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Providers — 지원 LLM 제공자
2
2
 
3
- > 소스: `ciel_runtime.py` `PROVIDER_ALIASES`, `PROVIDER_LABELS`, 각 `forward_*` 함수
3
+ > 단일 등록 원천: `ciel_runtime_support/provider_adapters.py`와 `providers/` 패키지
4
4
 
5
5
  ---
6
6
 
@@ -23,6 +23,44 @@
23
23
  | `openrouter` | OpenRouter | OpenAI Chat | `https://openrouter.ai/api` |
24
24
  | `fireworks` | Fireworks.ai | OpenAI Chat | `https://api.fireworks.ai/inference` |
25
25
 
26
+ ### 선언형 OpenAI Chat 호환 제공자
27
+
28
+ 아래 제공자는 동일한 OpenAI Chat/Models 계약을 공유하지만 각각 독립된 내부 ID,
29
+ 레이블, 기본 endpoint, 모델 fallback과 별칭을 갖는다. API 키 또는 발급받은 access
30
+ token은 Bearer header로 전송하며, 사용자 지정 `base_url`로 사설 gateway도 사용할 수
31
+ 있다.
32
+
33
+ | 범주 | 내부 ID |
34
+ |------|---------|
35
+ | 글로벌 API | `openai`, `gemini`, `xai`, `groq`, `cerebras`, `cohere`, `huggingface`, `mistral`, `together`, `perplexity`, `openrouter` |
36
+ | 모델 gateway | `blackbox`, `chutes`, `featherless`, `hyperbolic`, `nebius`, `siliconflow`, `venice`, `vercel-ai-gateway` |
37
+ | 중국·아시아 | `alicode`, `alicode-intl`, `alims-intl`, `byteplus`, `glm-cn`, `volcengine-ark`, `xiaomi-mimo`, `xiaomi-tokenplan`, `mimo-free`, `mmf` |
38
+ | 수동 OAuth token | `cline`, `clinepass`, `codebuddy-cn`, `github`, `gitlab`, `iflow`, `kilocode`, `kimchi`, `qwen` |
39
+ | 동적 cloud endpoint | `cloudflare-ai`, `vertex`, `vertex-partner` |
40
+
41
+ `cloudflare-ai`, `vertex`, `vertex-partner`는 계정·프로젝트·region마다 URL이 달라
42
+ 기본 URL을 추측하지 않는다. 각 서비스에서 발급된 OpenAI-compatible endpoint를
43
+ `base_url`로 명시해야 한다. “수동 OAuth token” 범주는 transport가 구현된 상태를
44
+ 뜻하며, Ciel이 브라우저 로그인이나 refresh token을 대신 발급한다는 뜻은 아니다.
45
+
46
+ ### Anthropic Messages 호환 제공자
47
+
48
+ `minimax`와 `minimax-cn`은 OpenAI 변환을 거치지 않고 Anthropic Messages 계약,
49
+ thinking 보존, `/v1/messages` endpoint를 사용한다.
50
+
51
+ ### Azure OpenAI
52
+
53
+ `azure`는 deployment root를 `base_url`로 받고 `/chat/completions`를 결합한다.
54
+ 인증은 Azure 규격의 raw `api-key` header를 사용하며 `api_version` 설정값을 query로
55
+ 추가한다. 기본값은 `2024-10-21`이다.
56
+
57
+ ### 범위 경계
58
+
59
+ 9router 레지스트리의 검색, 임베딩, 이미지 생성, TTS/STT 항목은 LLM Provider
60
+ Adapter로 위장해 등록하지 않는다. 이들은 Ciel의 향후 capability별 port/adapter에
61
+ 속한다. 또한 Cursor/Kiro의 비공개 wire protocol, 웹 cookie 재사용, client 위장
62
+ 방식은 공식적이고 안정적인 API 계약이 아니므로 일반 Provider로 취급하지 않는다.
63
+
26
64
  ---
27
65
 
28
66
  ## 제공자 별칭 (PROVIDER_ALIASES)
@@ -55,11 +93,18 @@
55
93
 
56
94
  | 모델 | compat_max_tokens | thinking |
57
95
  |------|------------------|---------|
96
+ | `glm-5.2:cloud` | 64 | ✅ |
58
97
  | `glm-4.7` | 64 | ✅ |
59
98
  | `deepseek-r1` | 64 | ✅ |
60
99
  | `qwen3-coder` | 16 | ❌ |
61
100
  | `llama3.3:70b` | 16 | ❌ |
62
101
 
102
+ Ollama의 GLM-5.2 모델 메타데이터와 Chat API에 맞춰 `think: true`와 최대
103
+ `options.num_ctx: 999424`(표시값 976K)를 사용한다. `tools`, `keep_alive`,
104
+ `options.num_predict`는 Ollama Chat API의 공식 필드 위치를 유지한다. Z.AI의
105
+ Anthropic thinking 객체나 문서로 확인되지 않은 GLM-5.2 effort 문자열은 Ollama
106
+ 요청에 복사하지 않는다.
107
+
63
108
  ---
64
109
 
65
110
  ## DeepSeek
@@ -0,0 +1,295 @@
1
+ # ADR 0001: Runtime bounded contexts and file-size budget
2
+
3
+ ## Status
4
+
5
+ Accepted. Migration is in progress on `architecture/runtime-evolution-2026-07-19`.
6
+
7
+ ## Decision
8
+
9
+ `ciel_runtime.py` becomes a compatibility facade and composition root. It may
10
+ select adapters and assemble typed services, but it must not own provider wire
11
+ logic, persistence, UI rendering, channel transport, retry state machines, or
12
+ runtime process implementations.
13
+
14
+ Production code is partitioned into these inward-facing contexts:
15
+
16
+ 1. `architecture`, registries, policies, and immutable domain values
17
+ 2. provider and protocol adapters
18
+ 3. channel application services and infrastructure adapters
19
+ 4. router application services and HTTP adapters
20
+ 5. runtime launch/process application services
21
+ 6. configuration repositories and migrations
22
+ 7. presentation policies and terminal/web adapters
23
+ 8. the top-level composition root and compatibility facade
24
+
25
+ Dependencies point from adapters and composition toward domain/application
26
+ contracts. Support modules never import `ciel_runtime`. Cross-context behavior
27
+ uses typed ports or immutable values, not provider-name conditionals or a shared
28
+ service-locator dictionary.
29
+
30
+ Every production Python file must remain below 5,000 physical lines. The final
31
+ facade budget is 4,999 lines. During migration, `MAIN_FILE_LINE_BUDGET` is a
32
+ monotonically decreasing ratchet and may never be raised.
33
+
34
+ ## Current channel boundaries
35
+
36
+ - `channel_mcp_transport.py` owns MCP transport configuration and state.
37
+ - `channel_notification_projection.py` maps chat records to MCP notifications.
38
+ - `channel_compact_request_repository.py` owns the durable compact-request slot,
39
+ expiration, and atomic persistence boundary.
40
+ - `channel_cursor_repository.py` owns cursor file I/O, while
41
+ `channel_cursor_service.py` owns cursor advancement and client-resume policy.
42
+
43
+ The facade only composes these objects and retains narrow compatibility
44
+ functions for callers that still import historical private names.
45
+
46
+ Codex configuration parsing and MCP server discovery live in
47
+ `codex_config.py`; runtime launch orchestration consumes their projections and
48
+ does not parse TOML itself.
49
+
50
+ Codex launch argument decisions live in `codex_launch_policy.py`, the local
51
+ resume index is isolated behind `codex_session_repository.py`, and bundled
52
+ model projection plus atomic catalog writes live in `codex_model_catalog.py`.
53
+
54
+ Provider-emitted pseudo tool envelopes are parsed by
55
+ `pseudo_tool_parser.py`, and transport-independent word buffering lives in
56
+ `stream_chunk_policy.py`. Provider adapters compose these policies instead of
57
+ embedding their grammars.
58
+
59
+ Upstream failure classification and localized retry presentation live in
60
+ `upstream_error_policy.py`. Cross-runtime transcript discovery, bounded JSONL
61
+ reading, and response projection live behind the Repository and Application
62
+ Service in `session_import.py`.
63
+
64
+ Locally generated Anthropic JSON/SSE responses are serialized by the HTTP
65
+ Adapter in `anthropic_response_writer.py`. Its single block serializer handles
66
+ text, thinking, redacted-thinking, and tool-use projections without facade
67
+ duplication.
68
+
69
+ Provider wire request construction lives in `provider_request_builder.py`.
70
+ Separate typed ports own budgeting, Ollama projection, OpenAI projection, and
71
+ provider option policy; each port is capped at ten dependencies.
72
+
73
+ Upstream socket timeout, downstream disconnect detection, cancellable line
74
+ iteration, and retry sleep live in the Infrastructure Adapter
75
+ `upstream_stream_io.py`.
76
+
77
+ Provider-specific Advisor message projection, input budgeting, request/response
78
+ mapping, and endpoint selection live in `advisor_request_builder.py`. Network
79
+ and rate-limit side effects remain outside this pure Builder boundary.
80
+
81
+ Advisor feedback injection and the optional second-pass response decoration
82
+ live in `advisor_refinement.py`; typed text, policy, and I/O ports keep the
83
+ refinement workflow independent of provider transport implementations.
84
+
85
+ Advisor network execution and refinement provider calls live in
86
+ `advisor_client.py`. `AdvisorClient` owns review I/O while
87
+ `ProviderChatExecutor` selects the Ollama or OpenAI-compatible transport
88
+ strategy through typed policy and I/O ports.
89
+
90
+ MCP channel capability probing, durable cache persistence, record
91
+ classification, capable-server projection, and source-path lookup live behind
92
+ `ChannelProbeCacheRepository` and `ChannelProbeService` in
93
+ `channel_probe_cache.py`.
94
+
95
+ The same service owns launch candidate projection, cache-refresh decisions,
96
+ and refresh failure isolation so launch orchestration does not depend on the
97
+ probe cache schema.
98
+
99
+ HTTP MCP configuration projection, environment-backed authentication headers,
100
+ external server discovery, allow-list filtering, and automatic connection
101
+ startup live in `channel_mcp_discovery.py`.
102
+
103
+ Notification-stream ownership is read by `ChannelProxyOwnershipRepository`,
104
+ while `ChannelRouterLifecycle` filters proxy-owned servers and starts only the
105
+ router-owned workers. Both live in `channel_mcp_ownership.py`.
106
+
107
+ Persisted channel lists, passthrough imports, delivery-mode normalization, and
108
+ add/remove/clear mutations live in `channel_config_service.py`; CLI handlers
109
+ only translate command arguments and render returned messages.
110
+
111
+ Channel CLI parsing and presentation live in `channel_cli.py`. Its controller
112
+ uses separate view and command ports and never reads or writes configuration
113
+ files directly.
114
+
115
+ Provider and LLM option status projection lives in
116
+ `provider_option_status.py`. It consumes adapter-declared context and
117
+ presentation policies through an explicit ten-field port, keeping
118
+ provider-specific display rules outside the compatibility facade without
119
+ reintroducing provider-name dispatch.
120
+
121
+ Provider option command orchestration lives in `provider_option_cli.py`.
122
+ The controller coordinates provider selection, persistence, model-cache
123
+ invalidation, recommended limits, and presentation through three ports of at
124
+ most five dependencies; mutation rules remain in provider policies.
125
+
126
+ Context-relative output caps are pure policies in `provider_context.py`.
127
+ Context-aware request timeout calculation and mutation live in
128
+ `provider_timeout_policy.py`, which composes adapter context policy with model,
129
+ catalog, preset, and output information through explicit settings and ports.
130
+
131
+ Context mode calculation, localized setup projection, and adapter-owned context
132
+ mutation live in `context_setup.py`. Persistence remains outside this service,
133
+ while post-mutation caps and timeout recalculation are explicit ports.
134
+
135
+ Current-model metadata lookup, adapter-owned context projection, and refresh
136
+ failure isolation live in `provider_model_specs.py`. Cache identity matching,
137
+ configuration mutation, and remote refresh are separate dependency groups.
138
+
139
+ User-selected timeout profile lookup, localization, projection, mutation, and
140
+ LLM preset token overrides live in `timeout_profile.py`, separate from the
141
+ context-aware automatic timeout calculation policy.
142
+
143
+ LM Studio target-context discovery, load/unload lifecycle, and loaded-context
144
+ guard behavior live together in `lm_studio_runtime.py`; the facade retains
145
+ only compatibility wrappers and composition.
146
+
147
+ Model-identity context heuristics live in `model_context_hints.py`. Qwen, Kimi,
148
+ Z.ai, catalog, and preset hints form one pure ordered policy instead of leaking
149
+ string matching into provider orchestration.
150
+
151
+ Runtime LLM snapshot/restore, preset application, slider navigation, and
152
+ status projection live in `runtime_llm_options.py`. Configuration persistence,
153
+ presentation, and preset mutation are separate typed port groups; slash action
154
+ aliases dispatch through the same controller.
155
+
156
+ Live API-key status and mutation action dispatch live in
157
+ `live_api_key_controller.py`; the HTTP layer receives only masked projection
158
+ lines and a changed flag.
159
+
160
+ Compatibility probe request/response framing and HTTP error decoding live in
161
+ `compatibility_protocol.py`; orchestration remains in `compatibility_test.py`.
162
+
163
+ Compatibility runtime diagnostics and durable result-cache mutation live in
164
+ `compatibility_runtime.py`, separate from probe transport and protocol framing.
165
+
166
+ Claude Code model aliasing, context-limit projection, launch environment
167
+ construction, runtime settings, and shell rendering live in
168
+ `claude_environment.py`. These policies receive provider/catalog behavior via
169
+ small typed port groups; the composition root retains only compatibility
170
+ wrappers and dependency assembly.
171
+
172
+ Managed-router client leases, idle shutdown, health supervision, runner
173
+ lifetime, and routed-launch diagnostics live in `router_client_lifecycle.py`.
174
+ The composition root supplies health/start/stop callbacks while filesystem,
175
+ environment, and thread mechanics stay behind the lifecycle adapter.
176
+
177
+ Single-process termination, descendant traversal, wrapper-parent discovery,
178
+ and process-tree termination share `ProcessTreeController` in
179
+ `process_control.py`; they no longer duplicate ps/taskkill/signal mechanics in
180
+ the composition root.
181
+
182
+ Managed router reuse, active-client replacement, version/config mismatch
183
+ handling, process spawn, and readiness waiting live alongside shutdown policy
184
+ in `router_process_lifecycle.py`. State decisions and spawn effects use
185
+ separate typed ports.
186
+
187
+ Runtime-specific provider choices use immutable strategies in
188
+ `provider_choice.py`. Alias normalization and native/routed configuration no
189
+ longer branch across Anthropic, AGY, and Codex inside the composition root.
190
+
191
+ Explicit model selection is coordinated by `ModelSelectionController` in
192
+ `provider_model_selection.py`. Provider-specific follow-up updates are adapter
193
+ methods, while profile/context/preset/timeout and persistence effects arrive
194
+ through bounded typed ports.
195
+
196
+ Codex backend URL mapping, GET/POST forwarding, capacity retry, and streamed
197
+ response delivery live in `CodexBackendHttpAdapter` within `router_http.py`.
198
+ Channel mutation/request effects and retry/observability effects are separate
199
+ typed port groups.
200
+
201
+ The events dashboard, filtered recent-event response, and SSE long-poll stream
202
+ are projected by `EventHttpAdapter`; the facade supplies EventBus and response
203
+ writer ports without owning HTTP streaming loops.
204
+
205
+ Codex split-MCP HTTP forwarding is isolated in `McpSplitProxyHttpAdapter`.
206
+ Server resolution and router response effects are bounded ports, while the
207
+ adapter owns upstream HTTP, body/SSE streaming, error projection, and duplicate
208
+ native channel-notification suppression as one cohesive transport boundary.
209
+
210
+ The LLM configuration endpoint uses `LlmConfigHttpController` for presentation
211
+ projection and action dispatch. Identity, panel catalogs, mutation strategies,
212
+ and HTTP effects are separate bounded ports, keeping provider behavior in its
213
+ existing provider/configuration services and HTTP workflow out of the facade.
214
+
215
+ Router and context activity snapshots use `RuntimeActivityRepository` instead
216
+ of three facade-owned atomic-write implementations. Paths, clock generation,
217
+ and event/log effects are explicit ports, and snapshot failures are observable
218
+ rather than silently swallowed.
219
+
220
+ NVIDIA's nvd-claude-proxy lifecycle and model-ID translation live beside its
221
+ provider adapter in `providers/nvidia_runtime.py`. The provider runtime owns
222
+ pip/process/readiness mechanics; configuration and generic HTTP/executable
223
+ capabilities arrive through a bounded port instead of facade globals.
224
+
225
+ AGY's official manifest installation and update lifecycle lives in
226
+ `AgyInstaller`. Platform selection, download, checksum, archive extraction,
227
+ post-install, and native-update fallback form one installation boundary; the
228
+ facade injects executable/version/command effects through a bounded port.
229
+
230
+ Channel backlog inspection and clearing use `ChannelBacklogService`. Cursor
231
+ stores/caches and live session/notification state are separate typed ports, so
232
+ the facade only supplies controlled global-state setters and no longer owns the
233
+ multi-lock clear transaction.
234
+
235
+ Upstream tool visibility is projected by `ToolExposurePolicy`. Provider-owned
236
+ blocked-tool declarations and request workflow state are explicit inputs, and
237
+ the policy removes tools and matching forced choices without mutating the
238
+ original request body.
239
+
240
+ The runtime/provider ownership boundary is materialized by
241
+ `RuntimeCommandFactory`. It constructs normalized contracts and delegates argv
242
+ generation to the registered runtime adapter; API-key parsing and registry
243
+ creation are its only external ports.
244
+
245
+ Runtime model metadata discovery uses `ProviderRuntimeInfoService`. Compatibility
246
+ strategy selects specialized LM Studio discovery or a generic model catalog;
247
+ context-field normalization, current-model selection, fallback, and observable
248
+ HTTP failure handling no longer live in the facade.
249
+
250
+ Local Claude Code tool synthesis is split into `SyntheticTasklistPolicy` and
251
+ `ForcedPlanModeController`. Conversation continuation decisions and forced-tool
252
+ request handling remain separate, while both preserve the public facade entry
253
+ points used by router pipelines.
254
+
255
+ Managed Web, Z.AI, and channel MCP configuration is generated by
256
+ `ManagedMcpConfigService`. Executable selection, credential projection, JSON
257
+ persistence, and channel cursor initialization are explicit ports rather than
258
+ facade-owned filesystem and environment logic.
259
+
260
+ MCP proxy configuration is materialized by `McpProxyConfigService`. It owns
261
+ server precedence, stdio/forced-HTTP proxy selection, per-server artifacts,
262
+ notification-stream overrides, and proxy command projection behind bounded
263
+ reader/classification/persistence ports.
264
+
265
+ Chat attachment decoding, size validation, safe naming, storage, URL metadata,
266
+ and Markdown projection live in `ChatFileRepository`; only clocks are injected
267
+ and callers no longer own filesystem mechanics.
268
+
269
+ `ChannelMessageRepository` owns the JSONL append transaction as well as reads:
270
+ rotation, ID resynchronization, payload projection, duplicate return semantics,
271
+ and notification are coordinated under injected lock/condition ports. The
272
+ facade retains only its compatibility function and legacy next-ID mirror.
273
+
274
+ Incremental terminal mouse-report filtering lives in
275
+ `channel_terminal_input.py`, next to newline and wake-input policies, rather
276
+ than as a stateful parser class in the composition root.
277
+ The same platform boundary resolves and validates the Windows console input
278
+ handle, including its `CONIN$` fallback; the facade retains only a compatibility
279
+ delegate so terminal consumers can keep stable patch and call points.
280
+
281
+ Generic npm-backed runtime installation and update checks live in
282
+ `NpmPackageLifecycle`. Runtime-specific wrappers supply package names and
283
+ version readers while npm/prefix/version/output effects use one bounded port.
284
+ Self-update uses a separate `SelfUpdateLifecycle` because it must preserve the
285
+ current package root/prefix and restart through the freshly installed entrypoint.
286
+
287
+ ## Rejected alternatives
288
+
289
+ - Moving the monolith unchanged into a differently named file
290
+ - Loading source fragments with `exec` into a shared global namespace
291
+ - Circular wildcard imports between numbered runtime fragments
292
+ - A global dictionary used as an untyped service locator
293
+ - Provider-specific branches inside runtime, protocol, or presentation layers
294
+
295
+ These alternatives reduce a filename's line count without reducing coupling.
@@ -10,6 +10,7 @@ const extra = process.argv.slice(2);
10
10
  const mode = Object.prototype.hasOwnProperty.call(process.env, "CIEL_RUNTIME_NPM_MODE")
11
11
  ? process.env.CIEL_RUNTIME_NPM_MODE
12
12
  : "cli";
13
+ const minimumPython = { major: 3, minor: 10 };
13
14
 
14
15
  function candidates() {
15
16
  const configuredPython = process.env.CIEL_RUNTIME_PYTHON;
@@ -31,7 +32,11 @@ function candidates() {
31
32
 
32
33
  let lastError = null;
33
34
  for (const [command, prefix] of candidates()) {
34
- const probe = spawnSync(command, [...prefix, "--version"], { encoding: "utf8", stdio: "pipe" });
35
+ const probe = spawnSync(
36
+ command,
37
+ [...prefix, "-c", "import sys; print(f'{sys.version_info.major}.{sys.version_info.minor}.{sys.version_info.micro}')"],
38
+ { encoding: "utf8", stdio: "pipe" },
39
+ );
35
40
  if (probe.error && probe.error.code === "ENOENT") {
36
41
  lastError = probe.error;
37
42
  continue;
@@ -42,7 +47,22 @@ for (const [command, prefix] of candidates()) {
42
47
  }
43
48
  if ((probe.status ?? 1) !== 0) {
44
49
  const detail = String(probe.stderr || probe.stdout || "").trim();
45
- lastError = new Error(detail || `${command} ${prefix.join(" ")} --version failed`);
50
+ lastError = new Error(detail || `${command} ${prefix.join(" ")} version probe failed`);
51
+ continue;
52
+ }
53
+ const versionText = String(probe.stdout || "").trim();
54
+ const versionMatch = /^(\d+)\.(\d+)(?:\.(\d+))?/.exec(versionText);
55
+ if (!versionMatch) {
56
+ lastError = new Error(`Could not parse Python version reported by ${command}: ${versionText || "<empty>"}`);
57
+ continue;
58
+ }
59
+ const major = Number(versionMatch[1]);
60
+ const minor = Number(versionMatch[2]);
61
+ if (major < minimumPython.major || (major === minimumPython.major && minor < minimumPython.minor)) {
62
+ lastError = new Error(
63
+ `Found Python ${versionText} via ${command}, but Ciel Runtime requires Python ` +
64
+ `${minimumPython.major}.${minimumPython.minor} or newer.`,
65
+ );
46
66
  continue;
47
67
  }
48
68
  const scriptArgs = mode ? [mode, ...extra] : extra;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@oneciel-ai/ciel-runtime",
3
- "version": "0.1.1",
3
+ "version": "0.2.0",
4
4
  "description": "Universal AI coding-agent runtime and model-routing layer for Claude, Codex, AGY, and compatible runtimes.",
5
5
  "license": "MIT",
6
6
  "author": "One Ciel LLC",
@@ -22,6 +22,8 @@
22
22
  "files": [
23
23
  "ciel_runtime.py",
24
24
  "ciel_runtime_support/*.py",
25
+ "ciel_runtime_support/providers/*.py",
26
+ "ciel_runtime_support/protocols/*.py",
25
27
  "ciel-runtime",
26
28
  "ciel-runtime.cmd",
27
29
  "ciel-runtime.ps1",
@@ -42,7 +44,12 @@
42
44
  "docs/"
43
45
  ],
44
46
  "scripts": {
45
- "test": "python -m py_compile ciel_runtime.py ciel_runtime_support/__init__.py ciel_runtime_support/architecture.py ciel_runtime_support/agent_router.py ciel_runtime_support/claude_router.py ciel_runtime_support/codex_app_server.py ciel_runtime_support/codex_cli.py ciel_runtime_support/codex_router.py ciel_runtime_support/observability.py ciel_runtime_support/transcript_filter.py ciel-runtime-menu.py ciel-runtime-tool-guard.py scripts/make_demo_assets.py && python -m unittest discover -s tests -p \"test_*.py\"",
47
+ "test": "python -m compileall -q ciel_runtime.py ciel_runtime_support ciel-runtime-menu.py ciel-runtime-tool-guard.py scripts && python -m unittest discover -s tests -p \"test_*.py\"",
48
+ "test:unit": "python scripts/run_test_group.py unit",
49
+ "test:router": "python scripts/run_test_group.py router",
50
+ "test:channel": "python scripts/run_test_group.py channel",
51
+ "test:runtime": "python scripts/run_test_group.py runtime",
52
+ "check:docs": "python scripts/check_project_metadata.py",
46
53
  "lint": "python -m ruff check .",
47
54
  "demo:assets": "python scripts/make_demo_assets.py"
48
55
  },