@oneciel-ai/ciel-runtime 0.2.2 → 0.2.3

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 (126) hide show
  1. package/ciel_runtime.py +2553 -9635
  2. package/ciel_runtime_support/advisor_request_builder.py +8 -21
  3. package/ciel_runtime_support/anthropic_tool_turns.py +13 -8
  4. package/ciel_runtime_support/architecture.py +68 -0
  5. package/ciel_runtime_support/architecture_budget.py +1 -1
  6. package/ciel_runtime_support/channel_connection_context.py +233 -0
  7. package/ciel_runtime_support/channel_delivery_context.py +332 -0
  8. package/ciel_runtime_support/channel_mcp_context.py +313 -0
  9. package/ciel_runtime_support/channel_mcp_discovery.py +47 -0
  10. package/ciel_runtime_support/channel_mcp_transport.py +5 -1
  11. package/ciel_runtime_support/channel_message_context.py +212 -0
  12. package/ciel_runtime_support/channel_message_repository.py +14 -3
  13. package/ciel_runtime_support/channel_pending_injection.py +9 -0
  14. package/ciel_runtime_support/channel_probe_launch_context.py +213 -0
  15. package/ciel_runtime_support/channel_replay_policy.py +38 -0
  16. package/ciel_runtime_support/channel_runtime_environment.py +8 -0
  17. package/ciel_runtime_support/channel_session_context.py +236 -0
  18. package/ciel_runtime_support/channel_terminal_context.py +350 -0
  19. package/ciel_runtime_support/channel_wake_context.py +532 -0
  20. package/ciel_runtime_support/claude_environment.py +60 -0
  21. package/ciel_runtime_support/claude_launch_assembly.py +249 -0
  22. package/ciel_runtime_support/claude_router.py +62 -12
  23. package/ciel_runtime_support/cli_application_context.py +132 -0
  24. package/ciel_runtime_support/cli_assembly.py +50 -0
  25. package/ciel_runtime_support/codex_backend_context.py +363 -0
  26. package/ciel_runtime_support/codex_config.py +13 -1
  27. package/ciel_runtime_support/codex_launch_assembly.py +213 -0
  28. package/ciel_runtime_support/codex_launch_configuration.py +30 -1
  29. package/ciel_runtime_support/codex_mcp_integration.py +90 -8
  30. package/ciel_runtime_support/codex_model_catalog.py +4 -1
  31. package/ciel_runtime_support/codex_reasoning_rejects.py +225 -0
  32. package/ciel_runtime_support/codex_router.py +38 -8
  33. package/ciel_runtime_support/codex_turn_recovery.py +154 -0
  34. package/ciel_runtime_support/config_migrations.py +103 -0
  35. package/ciel_runtime_support/configuration_cli.py +38 -0
  36. package/ciel_runtime_support/context_compaction.py +9 -4
  37. package/ciel_runtime_support/credential_management.py +12 -0
  38. package/ciel_runtime_support/credentials.py +12 -0
  39. package/ciel_runtime_support/github_copilot_oauth.py +2 -2
  40. package/ciel_runtime_support/hosted_formula_tools.py +216 -0
  41. package/ciel_runtime_support/kimi_runtime_context.py +208 -0
  42. package/ciel_runtime_support/llm_preset_context.py +338 -0
  43. package/ciel_runtime_support/managed_mcp_config.py +8 -4
  44. package/ciel_runtime_support/mcp_configuration_context.py +291 -0
  45. package/ciel_runtime_support/mcp_http_proxy.py +14 -8
  46. package/ciel_runtime_support/mcp_probe_transport.py +47 -15
  47. package/ciel_runtime_support/mcp_transport.py +14 -1
  48. package/ciel_runtime_support/native_context_recovery.py +72 -0
  49. package/ciel_runtime_support/ollama_catalog_context.py +213 -0
  50. package/ciel_runtime_support/ollama_stream_collection.py +103 -0
  51. package/ciel_runtime_support/ollama_thinking.py +6 -1
  52. package/ciel_runtime_support/ollama_wire_projection.py +157 -0
  53. package/ciel_runtime_support/openai_forwarding.py +32 -10
  54. package/ciel_runtime_support/openai_responses_router.py +12 -0
  55. package/ciel_runtime_support/package_lifecycle.py +39 -0
  56. package/ciel_runtime_support/prelaunch_assembly.py +37 -0
  57. package/ciel_runtime_support/prelaunch_panel_context.py +418 -0
  58. package/ciel_runtime_support/prelaunch_shell_context.py +394 -0
  59. package/ciel_runtime_support/prompt_compaction.py +144 -0
  60. package/ciel_runtime_support/prompt_injection.py +45 -0
  61. package/ciel_runtime_support/protocols/anthropic_thinking_policy.py +1 -1
  62. package/ciel_runtime_support/protocols/chat_projection.py +85 -5
  63. package/ciel_runtime_support/protocols/conversation_turn_policy.py +43 -0
  64. package/ciel_runtime_support/protocols/ollama_chat.py +31 -0
  65. package/ciel_runtime_support/protocols/ollama_response.py +57 -5
  66. package/ciel_runtime_support/protocols/openai_reasoning.py +5 -2
  67. package/ciel_runtime_support/protocols/openai_responses.py +61 -15
  68. package/ciel_runtime_support/provider_adapters.py +26 -0
  69. package/ciel_runtime_support/provider_administration_context.py +207 -0
  70. package/ciel_runtime_support/provider_config_mutations.py +3 -0
  71. package/ciel_runtime_support/provider_model_catalog_context.py +137 -0
  72. package/ciel_runtime_support/provider_model_context.py +107 -0
  73. package/ciel_runtime_support/provider_model_metadata_context.py +197 -0
  74. package/ciel_runtime_support/provider_model_selection.py +10 -3
  75. package/ciel_runtime_support/provider_models.py +45 -2
  76. package/ciel_runtime_support/provider_option_cli.py +19 -0
  77. package/ciel_runtime_support/provider_policy.py +1 -1
  78. package/ciel_runtime_support/provider_readiness_context.py +189 -0
  79. package/ciel_runtime_support/provider_request_builder.py +64 -28
  80. package/ciel_runtime_support/provider_responses_passthrough.py +21 -2
  81. package/ciel_runtime_support/provider_timeout_policy.py +54 -0
  82. package/ciel_runtime_support/provider_tool_policy.py +9 -1
  83. package/ciel_runtime_support/providers/__init__.py +6 -0
  84. package/ciel_runtime_support/providers/alibaba.py +634 -0
  85. package/ciel_runtime_support/providers/catalog.py +24 -16
  86. package/ciel_runtime_support/providers/deepseek.py +73 -0
  87. package/ciel_runtime_support/providers/github_copilot_oauth.py +22 -1
  88. package/ciel_runtime_support/providers/kimi.py +69 -9
  89. package/ciel_runtime_support/providers/ollama.py +8 -0
  90. package/ciel_runtime_support/providers/ollama_context.py +21 -2
  91. package/ciel_runtime_support/providers/vllm.py +7 -1
  92. package/ciel_runtime_support/response_collection.py +68 -18
  93. package/ciel_runtime_support/response_collection_context.py +391 -0
  94. package/ciel_runtime_support/response_stream_context.py +555 -0
  95. package/ciel_runtime_support/responses_input_compatibility.py +121 -0
  96. package/ciel_runtime_support/responses_usage_observer.py +83 -0
  97. package/ciel_runtime_support/router_client_lifecycle.py +1 -0
  98. package/ciel_runtime_support/router_http.py +239 -3
  99. package/ciel_runtime_support/router_observability_context.py +251 -0
  100. package/ciel_runtime_support/router_process_context.py +200 -0
  101. package/ciel_runtime_support/router_process_lifecycle.py +2 -0
  102. package/ciel_runtime_support/router_request_assembly.py +399 -0
  103. package/ciel_runtime_support/router_request_context.py +215 -0
  104. package/ciel_runtime_support/router_server_context.py +82 -0
  105. package/ciel_runtime_support/runaway_output_guard.py +488 -0
  106. package/ciel_runtime_support/runtime_asset_assembly.py +147 -0
  107. package/ciel_runtime_support/runtime_asset_context.py +297 -0
  108. package/ciel_runtime_support/runtime_constants.py +16 -1
  109. package/ciel_runtime_support/runtime_launch.py +9 -5
  110. package/ciel_runtime_support/runtime_launch_context.py +130 -0
  111. package/ciel_runtime_support/runtime_maintenance_assembly.py +60 -0
  112. package/ciel_runtime_support/runtime_maintenance_context.py +309 -0
  113. package/ciel_runtime_support/runtime_maintenance_services.py +265 -0
  114. package/ciel_runtime_support/runtime_paths.py +60 -40
  115. package/ciel_runtime_support/runtime_primitives.py +78 -0
  116. package/ciel_runtime_support/sse_stream_collection.py +236 -0
  117. package/ciel_runtime_support/statusline_script.py +57 -8
  118. package/ciel_runtime_support/streaming_anthropic.py +361 -24
  119. package/ciel_runtime_support/tool_schema.py +40 -2
  120. package/ciel_runtime_support/tool_side_effect_dedupe.py +117 -12
  121. package/ciel_runtime_support/upstream_dump.py +68 -0
  122. package/ciel_runtime_support/upstream_retry_context.py +259 -0
  123. package/ciel_runtime_support/workspace_router_selection.py +86 -0
  124. package/docs/Configuration.md +50 -0
  125. package/docs/Test-Suite.md +1 -0
  126. package/package.json +1 -1
@@ -0,0 +1,215 @@
1
+ """Runtime protocol request handling and router selection bounded context."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import urllib.error
6
+ from dataclasses import dataclass
7
+ from http.server import BaseHTTPRequestHandler
8
+ from typing import Any, Callable
9
+
10
+ from .agent_router import (
11
+ RuntimeRouter,
12
+ missing_common_capabilities,
13
+ router_capability_matrix,
14
+ )
15
+ from .claude_router import ClaudeRouter, ClaudeRouterServices
16
+ from .codex_router import CodexRouter
17
+ from .openai_chat_router import OpenAIChatRouter
18
+ from .openai_responses_router import (
19
+ OpenAIResponsesServices,
20
+ handle_openai_responses_request,
21
+ )
22
+
23
+
24
+ @dataclass(frozen=True, slots=True)
25
+ class RouterRequestPorts:
26
+ openai_responses: OpenAIResponsesServices
27
+ forward_backend_json: Callable[..., Any]
28
+ forward_backend_get: Callable[..., Any]
29
+ write_responses_error: Callable[..., Any]
30
+ write_json: Callable[..., Any]
31
+ upstream_error_message: Callable[..., str]
32
+ is_client_disconnect: Callable[[BaseException], bool]
33
+
34
+
35
+ @dataclass(frozen=True, slots=True)
36
+ class RuntimeRouterPorts:
37
+ codex_routed_enabled: Callable[..., bool]
38
+ forward_provider_chat: Callable[..., Any]
39
+ claude_services: ClaudeRouterServices
40
+
41
+
42
+ @dataclass(frozen=True, slots=True)
43
+ class RouterRequestContext:
44
+ request: RouterRequestPorts
45
+ runtime: RuntimeRouterPorts
46
+
47
+ def handle_openai_responses_post(
48
+ self,
49
+ handler: BaseHTTPRequestHandler,
50
+ cfg: dict[str, Any],
51
+ provider: str,
52
+ pcfg: dict[str, Any],
53
+ body: dict[str, Any],
54
+ ) -> None:
55
+ handle_openai_responses_request(
56
+ handler,
57
+ cfg,
58
+ provider,
59
+ pcfg,
60
+ body,
61
+ self.request.openai_responses,
62
+ )
63
+
64
+ def handle_codex_backend_passthrough_post(
65
+ self,
66
+ handler: BaseHTTPRequestHandler,
67
+ provider: str,
68
+ pcfg: dict[str, Any],
69
+ body: dict[str, Any],
70
+ ) -> None:
71
+ try:
72
+ self.request.forward_backend_json(
73
+ handler,
74
+ provider,
75
+ pcfg,
76
+ body,
77
+ mutate_responses=False,
78
+ )
79
+ except urllib.error.HTTPError as exc:
80
+ raw = exc.read().decode("utf-8", errors="ignore")
81
+ self.request.write_responses_error(
82
+ handler,
83
+ self.request.upstream_error_message(exc, raw),
84
+ stream=False,
85
+ status=exc.code,
86
+ )
87
+ except Exception as exc:
88
+ if self.request.is_client_disconnect(exc):
89
+ return
90
+ self.request.write_responses_error(
91
+ handler,
92
+ f"{type(exc).__name__}: {exc}",
93
+ stream=False,
94
+ )
95
+
96
+ def handle_codex_backend_passthrough_get(
97
+ self,
98
+ handler: BaseHTTPRequestHandler,
99
+ provider: str,
100
+ pcfg: dict[str, Any],
101
+ ) -> None:
102
+ try:
103
+ self.request.forward_backend_get(handler, provider, pcfg)
104
+ except urllib.error.HTTPError as exc:
105
+ raw = exc.read().decode("utf-8", errors="ignore")
106
+ self.request.write_json(
107
+ handler,
108
+ {"error": {"message": self.request.upstream_error_message(exc, raw)}},
109
+ status=exc.code,
110
+ )
111
+ except Exception as exc:
112
+ if self.request.is_client_disconnect(exc):
113
+ return
114
+ self.request.write_json(
115
+ handler,
116
+ {"error": {"message": f"{type(exc).__name__}: {exc}"}},
117
+ status=502,
118
+ )
119
+
120
+ def build_claude_router_services(self) -> ClaudeRouterServices:
121
+ return self.runtime.claude_services
122
+
123
+ def build_runtime_routers(self) -> tuple[RuntimeRouter, ...]:
124
+ return (
125
+ CodexRouter(
126
+ routed_enabled=self.runtime.codex_routed_enabled,
127
+ handle_responses_post=self.handle_openai_responses_post,
128
+ handle_backend_passthrough_post=(
129
+ self.handle_codex_backend_passthrough_post
130
+ ),
131
+ handle_backend_passthrough_get=(
132
+ self.handle_codex_backend_passthrough_get
133
+ ),
134
+ ),
135
+ OpenAIChatRouter(self.runtime.forward_provider_chat),
136
+ ClaudeRouter(services=self.runtime.claude_services),
137
+ )
138
+
139
+ def capability_matrix(self) -> dict[str, dict[str, Any]]:
140
+ return router_capability_matrix(self.build_runtime_routers())
141
+
142
+ def capability_gaps(self) -> dict[str, list[str]]:
143
+ return missing_common_capabilities(self.build_runtime_routers())
144
+
145
+ def route_get(
146
+ self,
147
+ handler: BaseHTTPRequestHandler,
148
+ path: str,
149
+ provider: str,
150
+ pcfg: dict[str, Any],
151
+ ) -> bool:
152
+ for router in self.build_runtime_routers():
153
+ if router.can_handle_get(path, provider, pcfg):
154
+ return bool(router.handle_get(handler, path, provider, pcfg))
155
+ return False
156
+
157
+ def route_post(
158
+ self,
159
+ handler: BaseHTTPRequestHandler,
160
+ cfg: dict[str, Any],
161
+ provider: str,
162
+ pcfg: dict[str, Any],
163
+ path: str,
164
+ body: dict[str, Any],
165
+ ) -> bool:
166
+ for router in self.build_runtime_routers():
167
+ if router.can_handle_post(path, provider, pcfg):
168
+ return bool(
169
+ router.handle_post(handler, cfg, provider, pcfg, path, body)
170
+ )
171
+ return False
172
+
173
+
174
+ @dataclass(frozen=True, slots=True)
175
+ class RouterRequestCompatibilityApi:
176
+ context: Callable[[], RouterRequestContext]
177
+
178
+ def handle_openai_responses_post(self, *args: Any, **kwargs: Any) -> None:
179
+ self.context().handle_openai_responses_post(*args, **kwargs)
180
+
181
+ def handle_codex_backend_passthrough_post(
182
+ self, *args: Any, **kwargs: Any
183
+ ) -> None:
184
+ self.context().handle_codex_backend_passthrough_post(*args, **kwargs)
185
+
186
+ def handle_codex_backend_passthrough_get(
187
+ self, *args: Any, **kwargs: Any
188
+ ) -> None:
189
+ self.context().handle_codex_backend_passthrough_get(*args, **kwargs)
190
+
191
+ def build_claude_router_services(self) -> ClaudeRouterServices:
192
+ return self.context().build_claude_router_services()
193
+
194
+ def build_runtime_routers(self) -> tuple[RuntimeRouter, ...]:
195
+ return self.context().build_runtime_routers()
196
+
197
+ def capability_matrix(self) -> dict[str, dict[str, Any]]:
198
+ return self.context().capability_matrix()
199
+
200
+ def capability_gaps(self) -> dict[str, list[str]]:
201
+ return self.context().capability_gaps()
202
+
203
+ def route_get(self, *args: Any, **kwargs: Any) -> bool:
204
+ return self.context().route_get(*args, **kwargs)
205
+
206
+ def route_post(self, *args: Any, **kwargs: Any) -> bool:
207
+ return self.context().route_post(*args, **kwargs)
208
+
209
+
210
+ __all__ = [
211
+ "RouterRequestCompatibilityApi",
212
+ "RouterRequestContext",
213
+ "RouterRequestPorts",
214
+ "RuntimeRouterPorts",
215
+ ]
@@ -0,0 +1,82 @@
1
+ """Router HTTP presentation and server lifecycle bounded context."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from dataclasses import dataclass
6
+ from pathlib import Path
7
+ from typing import Any, Callable
8
+
9
+ from .router_http import RouterHttpServices
10
+ from .router_server_runtime import RouterServerRuntime
11
+
12
+
13
+ @dataclass(frozen=True, slots=True)
14
+ class RouterHealthPresentationPorts:
15
+ version: str
16
+ source_fingerprint: str
17
+ current_pid: Callable[[], int]
18
+ current_user: Callable[[], str]
19
+ home: Path
20
+ config_dir: Path
21
+ workspace: str
22
+ router_port: int
23
+ current_alias: Callable[[dict[str, Any]], str]
24
+
25
+
26
+ @dataclass(frozen=True, slots=True)
27
+ class RouterServerContext:
28
+ health: RouterHealthPresentationPorts
29
+ http_services: RouterHttpServices
30
+ server_runtime: RouterServerRuntime
31
+
32
+ def health_payload(
33
+ self,
34
+ cfg: dict[str, Any],
35
+ provider: str,
36
+ pcfg: dict[str, Any],
37
+ ) -> dict[str, Any]:
38
+ del pcfg
39
+ return {
40
+ "ok": True,
41
+ "version": self.health.version,
42
+ "source_fingerprint": self.health.source_fingerprint,
43
+ "pid": self.health.current_pid(),
44
+ "user": self.health.current_user(),
45
+ "home": str(self.health.home),
46
+ "config_dir": str(self.health.config_dir),
47
+ "workspace": self.health.workspace,
48
+ "router_port": self.health.router_port,
49
+ "provider": provider,
50
+ "model": self.health.current_alias(cfg),
51
+ "web_chat": "/ca/web/chat",
52
+ "chat": "/ca/chat/health",
53
+ "plan": "/ca/plan/artifacts",
54
+ "events": "/ca/events",
55
+ }
56
+
57
+ def build_http_services(self) -> RouterHttpServices:
58
+ return self.http_services
59
+
60
+ def serve(self, _: Any) -> None:
61
+ self.server_runtime.run()
62
+
63
+
64
+ @dataclass(frozen=True, slots=True)
65
+ class RouterServerCompatibilityApi:
66
+ context: Callable[[], RouterServerContext]
67
+
68
+ def health_payload(self, *args: Any, **kwargs: Any) -> dict[str, Any]:
69
+ return self.context().health_payload(*args, **kwargs)
70
+
71
+ def build_http_services(self) -> RouterHttpServices:
72
+ return self.context().build_http_services()
73
+
74
+ def serve(self, args: Any) -> None:
75
+ self.context().serve(args)
76
+
77
+
78
+ __all__ = [
79
+ "RouterHealthPresentationPorts",
80
+ "RouterServerCompatibilityApi",
81
+ "RouterServerContext",
82
+ ]