@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.
- package/README.md +132 -0
- package/ciel-runtime-menu.py +56 -6
- package/ciel_runtime.py +9379 -35909
- package/ciel_runtime_support/advisor_client.py +193 -0
- package/ciel_runtime_support/advisor_policy.py +320 -0
- package/ciel_runtime_support/advisor_refinement.py +160 -0
- package/ciel_runtime_support/advisor_request_builder.py +261 -0
- package/ciel_runtime_support/agy_installer.py +169 -0
- package/ciel_runtime_support/agy_mcp_restore.py +182 -0
- package/ciel_runtime_support/anthropic_model_policy.py +186 -0
- package/ciel_runtime_support/anthropic_response_writer.py +255 -0
- package/ciel_runtime_support/anthropic_tool_turns.py +130 -0
- package/ciel_runtime_support/api_key_cooldown.py +159 -0
- package/ciel_runtime_support/architecture.py +488 -1
- package/ciel_runtime_support/architecture_budget.py +42 -0
- package/ciel_runtime_support/channel_backlog.py +90 -0
- package/ciel_runtime_support/channel_cli.py +119 -0
- package/ciel_runtime_support/channel_compact_injection.py +82 -0
- package/ciel_runtime_support/channel_compact_poll.py +67 -0
- package/ciel_runtime_support/channel_compact_request_repository.py +113 -0
- package/ciel_runtime_support/channel_config_service.py +281 -0
- package/ciel_runtime_support/channel_connection_lifecycle.py +180 -0
- package/ciel_runtime_support/channel_connection_registry.py +128 -0
- package/ciel_runtime_support/channel_connection_worker.py +284 -0
- package/ciel_runtime_support/channel_cursor_recovery.py +92 -0
- package/ciel_runtime_support/channel_cursor_repository.py +89 -0
- package/ciel_runtime_support/channel_cursor_service.py +178 -0
- package/ciel_runtime_support/channel_event_identity.py +212 -0
- package/ciel_runtime_support/channel_event_projection.py +315 -0
- package/ciel_runtime_support/channel_inflight.py +127 -0
- package/ciel_runtime_support/channel_injection.py +115 -0
- package/ciel_runtime_support/channel_launch_guard_repository.py +58 -0
- package/ciel_runtime_support/channel_launch_policy.py +180 -0
- package/ciel_runtime_support/channel_llm_context.py +156 -0
- package/ciel_runtime_support/channel_mcp_discovery.py +186 -0
- package/ciel_runtime_support/channel_mcp_http_controller.py +239 -0
- package/ciel_runtime_support/channel_mcp_ownership.py +148 -0
- package/ciel_runtime_support/channel_mcp_tools.py +240 -0
- package/ciel_runtime_support/channel_mcp_transport.py +394 -0
- package/ciel_runtime_support/channel_message_dedupe.py +65 -0
- package/ciel_runtime_support/channel_message_policy.py +256 -0
- package/ciel_runtime_support/channel_message_prompt.py +305 -0
- package/ciel_runtime_support/channel_message_repository.py +234 -0
- package/ciel_runtime_support/channel_notification_projection.py +217 -0
- package/ciel_runtime_support/channel_panel.py +162 -0
- package/ciel_runtime_support/channel_pending_injection.py +209 -0
- package/ciel_runtime_support/channel_pending_poll.py +109 -0
- package/ciel_runtime_support/channel_probe_cache.py +433 -0
- package/ciel_runtime_support/channel_probe_report.py +101 -0
- package/ciel_runtime_support/channel_runtime_environment.py +181 -0
- package/ciel_runtime_support/channel_session_lifecycle.py +114 -0
- package/ciel_runtime_support/channel_session_repository.py +90 -0
- package/ciel_runtime_support/channel_terminal_dispatch.py +115 -0
- package/ciel_runtime_support/channel_terminal_input.py +277 -0
- package/ciel_runtime_support/channel_terminal_proxy.py +447 -0
- package/ciel_runtime_support/channel_tool_context.py +166 -0
- package/ciel_runtime_support/channel_transcript.py +414 -0
- package/ciel_runtime_support/channel_transcript_repository.py +96 -0
- package/ciel_runtime_support/channel_wake_claim_repository.py +126 -0
- package/ciel_runtime_support/channel_wake_delivery_repository.py +88 -0
- package/ciel_runtime_support/chat_files.py +138 -0
- package/ciel_runtime_support/chat_http_controller.py +235 -0
- package/ciel_runtime_support/claude_environment.py +375 -0
- package/ciel_runtime_support/claude_router.py +247 -193
- package/ciel_runtime_support/cli_dispatch.py +792 -0
- package/ciel_runtime_support/cli_parser.py +165 -0
- package/ciel_runtime_support/cli_usage.py +100 -0
- package/ciel_runtime_support/codex_app_server.py +20 -5
- package/ciel_runtime_support/codex_channel_sse_launch.py +87 -0
- package/ciel_runtime_support/codex_cli.py +42 -6
- package/ciel_runtime_support/codex_config.py +323 -0
- package/ciel_runtime_support/codex_launch_configuration.py +240 -0
- package/ciel_runtime_support/codex_launch_policy.py +66 -0
- package/ciel_runtime_support/codex_mcp_integration.py +195 -0
- package/ciel_runtime_support/codex_mcp_restore.py +304 -0
- package/ciel_runtime_support/codex_model_catalog.py +133 -0
- package/ciel_runtime_support/codex_process_lifecycle.py +271 -0
- package/ciel_runtime_support/codex_router.py +147 -1
- package/ciel_runtime_support/codex_session_repository.py +115 -0
- package/ciel_runtime_support/codex_session_selection.py +114 -0
- package/ciel_runtime_support/command_asset_installer.py +103 -0
- package/ciel_runtime_support/compatibility_probe.py +295 -0
- package/ciel_runtime_support/compatibility_protocol.py +251 -0
- package/ciel_runtime_support/compatibility_runtime.py +166 -0
- package/ciel_runtime_support/compatibility_test.py +370 -0
- package/ciel_runtime_support/config_migrations.py +307 -0
- package/ciel_runtime_support/config_repository.py +175 -0
- package/ciel_runtime_support/config_value_codec.py +64 -0
- package/ciel_runtime_support/configuration_cli.py +374 -0
- package/ciel_runtime_support/context_compaction.py +280 -0
- package/ciel_runtime_support/context_setup.py +208 -0
- package/ciel_runtime_support/context_summary_policy.py +392 -0
- package/ciel_runtime_support/credential_cli.py +104 -0
- package/ciel_runtime_support/credential_management.py +261 -0
- package/ciel_runtime_support/credentials.py +269 -0
- package/ciel_runtime_support/executable_discovery.py +141 -0
- package/ciel_runtime_support/github_copilot_oauth.py +335 -0
- package/ciel_runtime_support/github_copilot_oauth_runtime.py +213 -0
- package/ciel_runtime_support/header_forwarding.py +73 -0
- package/ciel_runtime_support/headless_config.py +221 -0
- package/ciel_runtime_support/http_response.py +129 -0
- package/ciel_runtime_support/install_diagnostics.py +149 -0
- package/ciel_runtime_support/kimi_identity.py +123 -0
- package/ciel_runtime_support/launch_diagnostics.py +204 -0
- package/ciel_runtime_support/launch_state.py +127 -0
- package/ciel_runtime_support/live_api_key_controller.py +58 -0
- package/ciel_runtime_support/llm_config_http.py +148 -0
- package/ciel_runtime_support/llm_option_config.py +259 -0
- package/ciel_runtime_support/llm_presentation_data.py +447 -0
- package/ciel_runtime_support/llm_presets.py +773 -0
- package/ciel_runtime_support/lm_studio_runtime.py +401 -0
- package/ciel_runtime_support/managed_mcp_config.py +144 -0
- package/ciel_runtime_support/managed_mcp_discovery.py +151 -0
- package/ciel_runtime_support/managed_service_cleanup.py +89 -0
- package/ciel_runtime_support/mcp_config_reader.py +230 -0
- package/ciel_runtime_support/mcp_http_proxy.py +607 -0
- package/ciel_runtime_support/mcp_inventory.py +59 -0
- package/ciel_runtime_support/mcp_notification_wait_policy.py +159 -0
- package/ciel_runtime_support/mcp_probe_codec.py +136 -0
- package/ciel_runtime_support/mcp_probe_transport.py +328 -0
- package/ciel_runtime_support/mcp_proxy_codec.py +345 -0
- package/ciel_runtime_support/mcp_proxy_config.py +107 -0
- package/ciel_runtime_support/mcp_proxy_notifications.py +261 -0
- package/ciel_runtime_support/mcp_proxy_process.py +560 -0
- package/ciel_runtime_support/mcp_split_proxy_http.py +165 -0
- package/ciel_runtime_support/mcp_stdio_probe.py +240 -0
- package/ciel_runtime_support/mcp_transport.py +146 -0
- package/ciel_runtime_support/model_cache_lifecycle.py +78 -0
- package/ciel_runtime_support/model_catalog_projection.py +61 -0
- package/ciel_runtime_support/model_context_hints.py +109 -0
- package/ciel_runtime_support/model_panel.py +147 -0
- package/ciel_runtime_support/model_registry_repository.py +231 -0
- package/ciel_runtime_support/npm_runtime.py +191 -0
- package/ciel_runtime_support/ollama_catalog.py +462 -0
- package/ciel_runtime_support/ollama_catalog_cli.py +41 -0
- package/ciel_runtime_support/ollama_catalog_repository.py +75 -0
- package/ciel_runtime_support/ollama_context_sync.py +87 -0
- package/ciel_runtime_support/ollama_forwarding.py +449 -0
- package/ciel_runtime_support/openai_chat_passthrough.py +67 -0
- package/ciel_runtime_support/openai_chat_router.py +64 -0
- package/ciel_runtime_support/openai_forwarding.py +194 -0
- package/ciel_runtime_support/openai_responses_router.py +291 -0
- package/ciel_runtime_support/openai_responses_stream.py +135 -0
- package/ciel_runtime_support/output_budget.py +89 -0
- package/ciel_runtime_support/package_lifecycle.py +217 -0
- package/ciel_runtime_support/plan_artifact_controller.py +104 -0
- package/ciel_runtime_support/prelaunch.py +959 -0
- package/ciel_runtime_support/prelaunch_launch_preference.py +75 -0
- package/ciel_runtime_support/prelaunch_panel_projection.py +396 -0
- package/ciel_runtime_support/prelaunch_terminal.py +764 -0
- package/ciel_runtime_support/process_control.py +708 -0
- package/ciel_runtime_support/prompt_compaction.py +322 -0
- package/ciel_runtime_support/prompt_injection.py +176 -0
- package/ciel_runtime_support/protocols/__init__.py +24 -0
- package/ciel_runtime_support/protocols/anthropic_content.py +29 -0
- package/ciel_runtime_support/protocols/anthropic_thinking_policy.py +336 -0
- package/ciel_runtime_support/protocols/chat_projection.py +315 -0
- package/ciel_runtime_support/protocols/conversation_policy.py +217 -0
- package/ciel_runtime_support/protocols/conversation_turn_policy.py +972 -0
- package/ciel_runtime_support/protocols/ollama_chat.py +111 -0
- package/ciel_runtime_support/protocols/ollama_response.py +231 -0
- package/ciel_runtime_support/protocols/openai_reasoning.py +75 -0
- package/ciel_runtime_support/protocols/openai_responses.py +271 -0
- package/ciel_runtime_support/protocols/pseudo_tool_history.py +248 -0
- package/ciel_runtime_support/protocols/tool_result_projection.py +112 -0
- package/ciel_runtime_support/provider_adapters.py +160 -0
- package/ciel_runtime_support/provider_catalog_sources.py +316 -0
- package/ciel_runtime_support/provider_choice.py +201 -0
- package/ciel_runtime_support/provider_compatibility.py +165 -0
- package/ciel_runtime_support/provider_config_mutations.py +361 -0
- package/ciel_runtime_support/provider_configuration_service.py +162 -0
- package/ciel_runtime_support/provider_context.py +308 -0
- package/ciel_runtime_support/provider_contract_projection.py +73 -0
- package/ciel_runtime_support/provider_descriptor.py +82 -0
- package/ciel_runtime_support/provider_endpoint_policy.py +130 -0
- package/ciel_runtime_support/provider_endpoint_probe.py +165 -0
- package/ciel_runtime_support/provider_launch_endpoint.py +109 -0
- package/ciel_runtime_support/provider_limits.py +457 -0
- package/ciel_runtime_support/provider_model_identity.py +139 -0
- package/ciel_runtime_support/provider_model_selection.py +431 -0
- package/ciel_runtime_support/provider_model_specs.py +142 -0
- package/ciel_runtime_support/provider_models.py +263 -0
- package/ciel_runtime_support/provider_network.py +176 -0
- package/ciel_runtime_support/provider_option_cli.py +238 -0
- package/ciel_runtime_support/provider_option_panel.py +275 -0
- package/ciel_runtime_support/provider_option_status.py +192 -0
- package/ciel_runtime_support/provider_policy.py +101 -0
- package/ciel_runtime_support/provider_query_policy.py +67 -0
- package/ciel_runtime_support/provider_readiness.py +112 -0
- package/ciel_runtime_support/provider_request_access.py +131 -0
- package/ciel_runtime_support/provider_request_builder.py +250 -0
- package/ciel_runtime_support/provider_responses_passthrough.py +81 -0
- package/ciel_runtime_support/provider_runtime_info.py +113 -0
- package/ciel_runtime_support/provider_runtime_modes.py +150 -0
- package/ciel_runtime_support/provider_sampling_policy.py +46 -0
- package/ciel_runtime_support/provider_status.py +145 -0
- package/ciel_runtime_support/provider_timeout_policy.py +184 -0
- package/ciel_runtime_support/provider_tool_policy.py +145 -0
- package/ciel_runtime_support/providers/__init__.py +65 -0
- package/ciel_runtime_support/providers/anthropic.py +160 -0
- package/ciel_runtime_support/providers/anthropic_catalog.py +119 -0
- package/ciel_runtime_support/providers/base.py +232 -0
- package/ciel_runtime_support/providers/catalog.py +326 -0
- package/ciel_runtime_support/providers/cloud.py +194 -0
- package/ciel_runtime_support/providers/constants.py +54 -0
- package/ciel_runtime_support/providers/deepseek.py +115 -0
- package/ciel_runtime_support/providers/fireworks.py +158 -0
- package/ciel_runtime_support/providers/github_copilot_oauth.py +199 -0
- package/ciel_runtime_support/providers/kimi.py +297 -0
- package/ciel_runtime_support/providers/lm_studio.py +76 -0
- package/ciel_runtime_support/providers/meta.py +257 -0
- package/ciel_runtime_support/providers/native.py +194 -0
- package/ciel_runtime_support/providers/nim.py +69 -0
- package/ciel_runtime_support/providers/nvidia.py +158 -0
- package/ciel_runtime_support/providers/nvidia_runtime.py +285 -0
- package/ciel_runtime_support/providers/ollama.py +181 -0
- package/ciel_runtime_support/providers/ollama_context.py +195 -0
- package/ciel_runtime_support/providers/ollama_runtime.py +213 -0
- package/ciel_runtime_support/providers/opencode.py +220 -0
- package/ciel_runtime_support/providers/opencode_go.py +37 -0
- package/ciel_runtime_support/providers/openrouter.py +57 -0
- package/ciel_runtime_support/providers/vllm.py +65 -0
- package/ciel_runtime_support/providers/zai.py +119 -0
- package/ciel_runtime_support/pseudo_tool_parser.py +115 -0
- package/ciel_runtime_support/rate_limit_policy.py +117 -0
- package/ciel_runtime_support/rate_limit_repository.py +154 -0
- package/ciel_runtime_support/registry.py +46 -0
- package/ciel_runtime_support/request_shortcuts.py +253 -0
- package/ciel_runtime_support/request_trace.py +323 -0
- package/ciel_runtime_support/response_collection.py +209 -0
- package/ciel_runtime_support/router_access.py +238 -0
- package/ciel_runtime_support/router_client_lifecycle.py +366 -0
- package/ciel_runtime_support/router_health_policy.py +101 -0
- package/ciel_runtime_support/router_http.py +513 -0
- package/ciel_runtime_support/router_process_lifecycle.py +401 -0
- package/ciel_runtime_support/router_rate_limit_service.py +285 -0
- package/ciel_runtime_support/router_server_runtime.py +103 -0
- package/ciel_runtime_support/router_shortcuts.py +201 -0
- package/ciel_runtime_support/routing_fallback.py +73 -0
- package/ciel_runtime_support/runtime_activity_repository.py +143 -0
- package/ciel_runtime_support/runtime_adapters.py +104 -0
- package/ciel_runtime_support/runtime_command_factory.py +73 -0
- package/ciel_runtime_support/runtime_compatibility.py +50 -0
- package/ciel_runtime_support/runtime_constants.py +178 -0
- package/ciel_runtime_support/runtime_launch.py +1602 -0
- package/ciel_runtime_support/runtime_llm_options.py +312 -0
- package/ciel_runtime_support/runtime_logging.py +161 -0
- package/ciel_runtime_support/runtime_paths.py +157 -0
- package/ciel_runtime_support/runtime_restart.py +84 -0
- package/ciel_runtime_support/runtime_upgrade.py +149 -0
- package/ciel_runtime_support/secure_json_repository.py +55 -0
- package/ciel_runtime_support/session_import.py +356 -0
- package/ciel_runtime_support/settings_repository.py +8 -0
- package/ciel_runtime_support/slash_command_assets.py +211 -0
- package/ciel_runtime_support/sse_stream.py +57 -0
- package/ciel_runtime_support/sse_trace.py +225 -0
- package/ciel_runtime_support/statusline_script.py +593 -0
- package/ciel_runtime_support/statusline_settings.py +53 -0
- package/ciel_runtime_support/stream_chunk_policy.py +18 -0
- package/ciel_runtime_support/streaming_anthropic.py +1955 -0
- package/ciel_runtime_support/synthetic_tool_policy.py +105 -0
- package/ciel_runtime_support/terminal_platform_io.py +127 -0
- package/ciel_runtime_support/timeout_profile.py +196 -0
- package/ciel_runtime_support/tool_dialects.py +85 -0
- package/ciel_runtime_support/tool_exposure_policy.py +63 -0
- package/ciel_runtime_support/tool_guard_hooks.py +218 -0
- package/ciel_runtime_support/tool_request_projection.py +96 -0
- package/ciel_runtime_support/tool_schema.py +483 -0
- package/ciel_runtime_support/tool_side_effect_dedupe.py +95 -0
- package/ciel_runtime_support/ui_text.py +266 -0
- package/ciel_runtime_support/upstream_error_policy.py +104 -0
- package/ciel_runtime_support/upstream_retry.py +419 -0
- package/ciel_runtime_support/upstream_stream_io.py +106 -0
- package/ciel_runtime_support/usage_events.py +96 -0
- package/ciel_runtime_support/visible_stream_filters.py +130 -0
- package/ciel_runtime_support/web_endpoints.py +447 -0
- package/ciel_runtime_support/web_ui.py +915 -0
- package/ciel_runtime_support/web_ui_controller.py +189 -0
- package/ciel_runtime_support/windows_console_input.py +137 -0
- package/ciel_runtime_support/windows_console_mode.py +112 -0
- package/docs/Architecture.md +54 -0
- package/docs/Configuration.md +17 -0
- package/docs/Module-Map.md +1093 -26
- package/docs/Providers.md +46 -1
- package/docs/adr/0001-runtime-bounded-contexts.md +295 -0
- package/npm-bin/run-ciel-runtime.js +22 -2
- package/package.json +9 -2
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
"""Static Claude slash-command documents installed by Ciel Runtime."""
|
|
2
|
+
|
|
3
|
+
VERSION_SLASH_COMMAND = """---
|
|
4
|
+
description: Show ciel-runtime version
|
|
5
|
+
argument-hint: [ignored]
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
CIEL_RUNTIME_VERSION_STATUS
|
|
9
|
+
|
|
10
|
+
Show the running ciel-runtime version for this session. This command is handled locally by the ciel-runtime router and must not be forwarded upstream.
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
ADVISOR_SLASH_COMMAND = """---
|
|
14
|
+
description: Run the selected ciel-runtime Advisor Model
|
|
15
|
+
argument-hint: [question or focus]
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
CIEL_RUNTIME_ADVISOR_CALL
|
|
19
|
+
|
|
20
|
+
Focus: $ARGUMENTS
|
|
21
|
+
|
|
22
|
+
Use the Advisor Model selected in the ciel-runtime launch menu. If the Advisor Model is off, explain how to enable it. Otherwise review the current conversation, tool history, and task state. Return concise guidance with the blocker, next concrete action, and validation step.
|
|
23
|
+
"""
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
ADVISOR_NATIVE_DISABLED_SLASH_COMMAND = """---
|
|
27
|
+
description: Ciel Runtime Advisor unavailable in Claude Native mode
|
|
28
|
+
argument-hint: [ignored]
|
|
29
|
+
---
|
|
30
|
+
|
|
31
|
+
Ciel Runtime Advisor is unavailable in direct Claude Native mode.
|
|
32
|
+
|
|
33
|
+
Do not run tools, shell commands, file searches, config scans, or environment checks for this command. Reply immediately with this exact status and the short enablement hint below.
|
|
34
|
+
|
|
35
|
+
This session bypasses the ciel-runtime router, so /advisor cannot call the configured Advisor Model here. To use /advisor, launch a non-native provider or enable Anthropic routed mode in ciel-runtime.
|
|
36
|
+
"""
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
ROUTER_DEBUG_SLASH_COMMAND = """---
|
|
40
|
+
description: Toggle ciel-runtime router external debug access
|
|
41
|
+
argument-hint: [on|off|status]
|
|
42
|
+
---
|
|
43
|
+
|
|
44
|
+
CIEL_RUNTIME_ROUTER_DEBUG_ACCESS
|
|
45
|
+
|
|
46
|
+
Value: $ARGUMENTS
|
|
47
|
+
|
|
48
|
+
Toggle ciel-runtime router debug external access. With no argument, this toggles the current state. Use `on`, `off`, or `status` for explicit control.
|
|
49
|
+
"""
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
ROUTER_DEBUG_NATIVE_DISABLED_SLASH_COMMAND = """---
|
|
53
|
+
description: ciel-runtime router debug unavailable in Claude Native mode
|
|
54
|
+
argument-hint: [ignored]
|
|
55
|
+
---
|
|
56
|
+
|
|
57
|
+
ciel-runtime router debug controls are unavailable in direct Claude Native mode.
|
|
58
|
+
|
|
59
|
+
Do not run tools, shell commands, file searches, config scans, or environment checks for this command. Reply immediately with this exact status and the short enablement hint below.
|
|
60
|
+
|
|
61
|
+
This session bypasses the ciel-runtime router. Launch a non-native provider or enable Anthropic routed mode to use /router-debug.
|
|
62
|
+
"""
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
LLM_SLIDER_SLASH_COMMAND = """---
|
|
66
|
+
description: Move/select ciel-runtime live LLM preset slider
|
|
67
|
+
argument-hint: [left|right|status|list|restore|preset-id]
|
|
68
|
+
---
|
|
69
|
+
|
|
70
|
+
CIEL_RUNTIME_LIVE_LLM_OPTIONS
|
|
71
|
+
|
|
72
|
+
Value: $0
|
|
73
|
+
Arguments: $ARGUMENTS
|
|
74
|
+
|
|
75
|
+
Use one compact ciel-runtime live LLM preset control. With no argument, show the current slider. Use `left` or `right` to move one preset, `restore` to return to captured options, or a preset id/alias such as `coding`, `300k`, `512k`, or `1m`.
|
|
76
|
+
"""
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
LLM_OPTIONS_SLASH_COMMAND = """---
|
|
80
|
+
description: Show or change ciel-runtime live LLM options
|
|
81
|
+
argument-hint: [left|right|status|list|restore|preset-id]
|
|
82
|
+
---
|
|
83
|
+
|
|
84
|
+
CIEL_RUNTIME_LIVE_LLM_OPTIONS
|
|
85
|
+
|
|
86
|
+
Value: $0
|
|
87
|
+
Arguments: $ARGUMENTS
|
|
88
|
+
|
|
89
|
+
Show or change the live ciel-runtime LLM preset for this routed session. With no argument, show status and the compact preset slider. Use `left` or `right` to move one preset, `restore` to return to captured options, or a preset id/alias such as `coding`, `300k`, `512k`, or `1m`.
|
|
90
|
+
"""
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
LLM_RESTORE_SLASH_COMMAND = """---
|
|
94
|
+
description: Restore ciel-runtime live LLM options
|
|
95
|
+
argument-hint: [ignored]
|
|
96
|
+
---
|
|
97
|
+
|
|
98
|
+
CIEL_RUNTIME_LIVE_LLM_OPTIONS
|
|
99
|
+
|
|
100
|
+
Value: restore
|
|
101
|
+
|
|
102
|
+
Restore the LLM options captured before the first live preset change in this routed session.
|
|
103
|
+
"""
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
CHANNEL_CLEAR_SLASH_COMMAND = """---
|
|
107
|
+
description: Discard pending ciel-runtime external channel backlog
|
|
108
|
+
argument-hint: [all|status]
|
|
109
|
+
---
|
|
110
|
+
|
|
111
|
+
CIEL_RUNTIME_CHANNEL_CLEAR_BACKLOG
|
|
112
|
+
|
|
113
|
+
Value: $ARGUMENTS
|
|
114
|
+
|
|
115
|
+
Discard pending ciel-runtime external channel backlog without sending it to the model. Use `status` to show pending counts without clearing.
|
|
116
|
+
"""
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
API_KEYS_SLASH_COMMAND = """---
|
|
120
|
+
description: Set/show ciel-runtime live API key(s)
|
|
121
|
+
argument-hint: [status|clear|KEY|KEY1,KEY2]
|
|
122
|
+
---
|
|
123
|
+
|
|
124
|
+
Set API key(s) for the current ciel-runtime provider without restarting Claude Code. With no argument, show masked key status. Use `clear` or `unset` to remove keys for only the current provider. Multiple keys may be comma-, semicolon-, or newline-separated and are used round-robin. Never print raw keys.
|
|
125
|
+
|
|
126
|
+
CIEL_RUNTIME_LIVE_API_KEYS
|
|
127
|
+
|
|
128
|
+
Value: $0
|
|
129
|
+
Arguments:
|
|
130
|
+
$ARGUMENTS
|
|
131
|
+
"""
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
IMPORT_SESSION_SLASH_COMMAND = """---
|
|
135
|
+
description: Import a Claude/Codex session transcript into this session
|
|
136
|
+
argument-hint: Codex|Claude [transcript-path]
|
|
137
|
+
---
|
|
138
|
+
|
|
139
|
+
CIEL_RUNTIME_IMPORT_SESSION
|
|
140
|
+
|
|
141
|
+
Target: $1
|
|
142
|
+
Path: $2
|
|
143
|
+
Arguments: $ARGUMENTS
|
|
144
|
+
|
|
145
|
+
Import a session transcript into the current Ciel Runtime-routed session. `Target` names the source transcript format and must be `Codex` or `Claude`.
|
|
146
|
+
"""
|
|
147
|
+
|
|
148
|
+
|
|
149
|
+
LEGACY_MARKER_PREFIX = "CLAUDE" + "_ANY"
|
|
150
|
+
LEGACY_ADVISOR_CALL_MARKER = LEGACY_MARKER_PREFIX + "_ADVISOR_CALL"
|
|
151
|
+
LEGACY_ROUTER_DEBUG_ACCESS_MARKER = LEGACY_MARKER_PREFIX + "_ROUTER_DEBUG_ACCESS"
|
|
152
|
+
LEGACY_LIVE_LLM_OPTIONS_MARKER = LEGACY_MARKER_PREFIX + "_LIVE_LLM_OPTIONS"
|
|
153
|
+
LEGACY_CHANNEL_CLEAR_BACKLOG_MARKER = LEGACY_MARKER_PREFIX + "_CHANNEL_CLEAR_BACKLOG"
|
|
154
|
+
LEGACY_LIVE_API_KEYS_MARKER = LEGACY_MARKER_PREFIX + "_LIVE_API_KEYS"
|
|
155
|
+
|
|
156
|
+
ADVISOR_REQUEST_MARKERS = ("CIEL_RUNTIME_ADVISOR_CALL", LEGACY_ADVISOR_CALL_MARKER)
|
|
157
|
+
ROUTER_DEBUG_REQUEST_MARKERS = (
|
|
158
|
+
"CIEL_RUNTIME_ROUTER_DEBUG_ACCESS",
|
|
159
|
+
LEGACY_ROUTER_DEBUG_ACCESS_MARKER,
|
|
160
|
+
)
|
|
161
|
+
VERSION_REQUEST_MARKERS = ("CIEL_RUNTIME_VERSION_STATUS",)
|
|
162
|
+
LIVE_LLM_OPTIONS_REQUEST_MARKERS = (
|
|
163
|
+
"CIEL_RUNTIME_LIVE_LLM_OPTIONS",
|
|
164
|
+
LEGACY_LIVE_LLM_OPTIONS_MARKER,
|
|
165
|
+
)
|
|
166
|
+
CHANNEL_CLEAR_REQUEST_MARKERS = (
|
|
167
|
+
"CIEL_RUNTIME_CHANNEL_CLEAR_BACKLOG",
|
|
168
|
+
LEGACY_CHANNEL_CLEAR_BACKLOG_MARKER,
|
|
169
|
+
)
|
|
170
|
+
LIVE_API_KEYS_REQUEST_MARKERS = (
|
|
171
|
+
"CIEL_RUNTIME_LIVE_API_KEYS",
|
|
172
|
+
LEGACY_LIVE_API_KEYS_MARKER,
|
|
173
|
+
)
|
|
174
|
+
IMPORT_SESSION_REQUEST_MARKERS = ("CIEL_RUNTIME_IMPORT_SESSION",)
|
|
175
|
+
|
|
176
|
+
CIEL_RUNTIME_ADVISOR_COMMAND_MARKERS = (
|
|
177
|
+
"CIEL_RUNTIME_ADVISOR_CALL",
|
|
178
|
+
"Run the selected ciel-runtime Advisor Model",
|
|
179
|
+
"Ciel Runtime Advisor is unavailable in direct Claude Native mode",
|
|
180
|
+
LEGACY_ADVISOR_CALL_MARKER,
|
|
181
|
+
)
|
|
182
|
+
CIEL_RUNTIME_ROUTER_DEBUG_COMMAND_MARKERS = (
|
|
183
|
+
"CIEL_RUNTIME_ROUTER_DEBUG_ACCESS",
|
|
184
|
+
"Toggle ciel-runtime router external debug access",
|
|
185
|
+
"ciel-runtime router debug controls are unavailable in direct Claude Native mode",
|
|
186
|
+
LEGACY_ROUTER_DEBUG_ACCESS_MARKER,
|
|
187
|
+
)
|
|
188
|
+
CIEL_RUNTIME_VERSION_COMMAND_MARKERS = (
|
|
189
|
+
"CIEL_RUNTIME_VERSION_STATUS",
|
|
190
|
+
"Show ciel-runtime version",
|
|
191
|
+
)
|
|
192
|
+
CIEL_RUNTIME_LLM_OPTIONS_COMMAND_MARKERS = (
|
|
193
|
+
"CIEL_RUNTIME_LIVE_LLM_OPTIONS",
|
|
194
|
+
"Show or change ciel-runtime live LLM options",
|
|
195
|
+
"Restore ciel-runtime live LLM options",
|
|
196
|
+
LEGACY_LIVE_LLM_OPTIONS_MARKER,
|
|
197
|
+
)
|
|
198
|
+
CIEL_RUNTIME_CHANNEL_CLEAR_COMMAND_MARKERS = (
|
|
199
|
+
"CIEL_RUNTIME_CHANNEL_CLEAR_BACKLOG",
|
|
200
|
+
"Discard pending ciel-runtime external channel backlog",
|
|
201
|
+
LEGACY_CHANNEL_CLEAR_BACKLOG_MARKER,
|
|
202
|
+
)
|
|
203
|
+
CIEL_RUNTIME_API_KEYS_COMMAND_MARKERS = (
|
|
204
|
+
"CIEL_RUNTIME_LIVE_API_KEYS",
|
|
205
|
+
"Set/show ciel-runtime live API key(s)",
|
|
206
|
+
LEGACY_LIVE_API_KEYS_MARKER,
|
|
207
|
+
)
|
|
208
|
+
CIEL_RUNTIME_IMPORT_SESSION_COMMAND_MARKERS = (
|
|
209
|
+
"CIEL_RUNTIME_IMPORT_SESSION",
|
|
210
|
+
"Import a Claude/Codex session transcript",
|
|
211
|
+
)
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
"""Reusable Server-Sent Events stream parser and dispatch loop."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from dataclasses import dataclass
|
|
6
|
+
from typing import Any, Callable
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
@dataclass(frozen=True, slots=True)
|
|
10
|
+
class SseStreamServices:
|
|
11
|
+
should_continue: Callable[[], bool]
|
|
12
|
+
dispatch: Callable[[str, list[str], str | None], Any]
|
|
13
|
+
invalid_retry: Callable[[str], Any]
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
@dataclass(slots=True)
|
|
17
|
+
class SseRetryState:
|
|
18
|
+
seconds: float
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def consume_sse_stream(
|
|
22
|
+
response: Any,
|
|
23
|
+
retry: SseRetryState,
|
|
24
|
+
end_message: str,
|
|
25
|
+
services: SseStreamServices,
|
|
26
|
+
) -> None:
|
|
27
|
+
event_name = "message"
|
|
28
|
+
event_id: str | None = None
|
|
29
|
+
data_lines: list[str] = []
|
|
30
|
+
while services.should_continue():
|
|
31
|
+
raw = response.readline()
|
|
32
|
+
if raw == b"":
|
|
33
|
+
raise ConnectionError(end_message)
|
|
34
|
+
line = raw.decode("utf-8", errors="replace").rstrip("\r\n")
|
|
35
|
+
if not line:
|
|
36
|
+
if data_lines:
|
|
37
|
+
services.dispatch(event_name, data_lines, event_id)
|
|
38
|
+
event_name = "message"
|
|
39
|
+
event_id = None
|
|
40
|
+
data_lines = []
|
|
41
|
+
continue
|
|
42
|
+
if line.startswith(":"):
|
|
43
|
+
continue
|
|
44
|
+
field, _, value = line.partition(":")
|
|
45
|
+
if value.startswith(" "):
|
|
46
|
+
value = value[1:]
|
|
47
|
+
if field == "event":
|
|
48
|
+
event_name = value or "message"
|
|
49
|
+
elif field == "data":
|
|
50
|
+
data_lines.append(value)
|
|
51
|
+
elif field == "id":
|
|
52
|
+
event_id = value
|
|
53
|
+
elif field == "retry":
|
|
54
|
+
try:
|
|
55
|
+
retry.seconds = max(1.0, min(60.0, int(value) / 1000.0))
|
|
56
|
+
except (TypeError, ValueError):
|
|
57
|
+
services.invalid_retry(value)
|
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
"""Bounded SSE event tracing and tool-call JSONL observability."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import json
|
|
6
|
+
import os
|
|
7
|
+
import time
|
|
8
|
+
from collections.abc import Callable
|
|
9
|
+
from dataclasses import dataclass
|
|
10
|
+
from pathlib import Path
|
|
11
|
+
from typing import Any
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
@dataclass(frozen=True, slots=True)
|
|
15
|
+
class SseTraceConfig:
|
|
16
|
+
config_dir: Path
|
|
17
|
+
last_path: Path
|
|
18
|
+
trace_path: Path
|
|
19
|
+
tool_call_path: Path
|
|
20
|
+
event_limit: int
|
|
21
|
+
payload_limit: int
|
|
22
|
+
max_bytes: int
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
@dataclass(frozen=True, slots=True)
|
|
26
|
+
class SseTracePorts:
|
|
27
|
+
enabled: Callable[[], bool]
|
|
28
|
+
truncate: Callable[[str, int], str]
|
|
29
|
+
log: Callable[[str, str], None]
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def summarize_payload(
|
|
33
|
+
payload: dict[str, Any], truncate: Callable[[str, int], str]
|
|
34
|
+
) -> dict[str, Any]:
|
|
35
|
+
summary: dict[str, Any] = {"type": payload.get("type")}
|
|
36
|
+
if "index" in payload:
|
|
37
|
+
summary["index"] = payload.get("index")
|
|
38
|
+
payload_type = payload.get("type")
|
|
39
|
+
if payload_type == "message_start":
|
|
40
|
+
message = payload.get("message") if isinstance(payload.get("message"), dict) else {}
|
|
41
|
+
summary["message"] = {
|
|
42
|
+
"id": message.get("id"),
|
|
43
|
+
"model": message.get("model"),
|
|
44
|
+
"role": message.get("role"),
|
|
45
|
+
"content_len": len(message.get("content") or []),
|
|
46
|
+
"usage": message.get("usage"),
|
|
47
|
+
}
|
|
48
|
+
elif payload_type == "message_delta":
|
|
49
|
+
summary["delta"] = payload.get("delta")
|
|
50
|
+
summary["usage"] = payload.get("usage")
|
|
51
|
+
elif payload_type == "content_block_start":
|
|
52
|
+
block = payload.get("content_block") if isinstance(payload.get("content_block"), dict) else {}
|
|
53
|
+
block_summary = {"type": block.get("type")}
|
|
54
|
+
if block.get("type") == "tool_use":
|
|
55
|
+
block_summary.update(
|
|
56
|
+
{"id": block.get("id"), "name": block.get("name"), "input": block.get("input")}
|
|
57
|
+
)
|
|
58
|
+
elif block.get("type") == "text":
|
|
59
|
+
block_summary["text_len"] = len(str(block.get("text") or ""))
|
|
60
|
+
else:
|
|
61
|
+
block_summary["keys"] = sorted(str(key) for key in block)
|
|
62
|
+
summary["content_block"] = block_summary
|
|
63
|
+
elif payload_type == "content_block_delta":
|
|
64
|
+
delta = payload.get("delta") if isinstance(payload.get("delta"), dict) else {}
|
|
65
|
+
delta_type = delta.get("type")
|
|
66
|
+
delta_summary: dict[str, Any] = {"type": delta_type}
|
|
67
|
+
if delta_type == "text_delta":
|
|
68
|
+
text = str(delta.get("text") or "")
|
|
69
|
+
delta_summary.update({"text_len": len(text), "text": truncate(text, 500)})
|
|
70
|
+
elif delta_type == "input_json_delta":
|
|
71
|
+
partial = str(delta.get("partial_json") or "")
|
|
72
|
+
delta_summary.update(
|
|
73
|
+
{
|
|
74
|
+
"partial_json_len": len(partial),
|
|
75
|
+
"partial_json": truncate(partial, 1000),
|
|
76
|
+
}
|
|
77
|
+
)
|
|
78
|
+
else:
|
|
79
|
+
delta_summary["keys"] = sorted(str(key) for key in delta)
|
|
80
|
+
summary["delta"] = delta_summary
|
|
81
|
+
else:
|
|
82
|
+
summary["keys"] = sorted(str(key) for key in payload)
|
|
83
|
+
return summary
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
class SseTraceRepository:
|
|
87
|
+
def __init__(self, config: SseTraceConfig, ports: SseTracePorts) -> None:
|
|
88
|
+
self.config = config
|
|
89
|
+
self.ports = ports
|
|
90
|
+
|
|
91
|
+
def begin(
|
|
92
|
+
self,
|
|
93
|
+
provider: str,
|
|
94
|
+
model: str,
|
|
95
|
+
source: str,
|
|
96
|
+
source_body: dict[str, Any] | None = None,
|
|
97
|
+
) -> dict[str, Any]:
|
|
98
|
+
return {
|
|
99
|
+
"time": time.strftime("%Y-%m-%dT%H:%M:%S"),
|
|
100
|
+
"provider": provider,
|
|
101
|
+
"model": model,
|
|
102
|
+
"source": source,
|
|
103
|
+
"stream": True,
|
|
104
|
+
"messages_count": len(source_body.get("messages") or [])
|
|
105
|
+
if isinstance(source_body, dict)
|
|
106
|
+
else None,
|
|
107
|
+
"tools_count": len(source_body.get("tools") or [])
|
|
108
|
+
if isinstance(source_body, dict)
|
|
109
|
+
else None,
|
|
110
|
+
"metadata_keys": sorted(str(key) for key in (source_body.get("metadata") or {}))
|
|
111
|
+
if isinstance(source_body, dict) and isinstance(source_body.get("metadata"), dict)
|
|
112
|
+
else [],
|
|
113
|
+
"event_count": 0,
|
|
114
|
+
"events_truncated": False,
|
|
115
|
+
"events": [],
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
def record(
|
|
119
|
+
self, trace: dict[str, Any] | None, event_name: str, payload: dict[str, Any]
|
|
120
|
+
) -> None:
|
|
121
|
+
if not isinstance(trace, dict):
|
|
122
|
+
return
|
|
123
|
+
try:
|
|
124
|
+
trace["event_count"] = int(trace.get("event_count") or 0) + 1
|
|
125
|
+
events = trace.get("events")
|
|
126
|
+
if not isinstance(events, list):
|
|
127
|
+
events = []
|
|
128
|
+
trace["events"] = events
|
|
129
|
+
if len(events) >= self.config.event_limit:
|
|
130
|
+
trace["events_truncated"] = True
|
|
131
|
+
return
|
|
132
|
+
raw = ""
|
|
133
|
+
if self.ports.enabled():
|
|
134
|
+
try:
|
|
135
|
+
encoded = json.dumps(payload, ensure_ascii=False, separators=(",", ":"))
|
|
136
|
+
raw = self.ports.truncate(encoded, self.config.payload_limit)
|
|
137
|
+
except (TypeError, ValueError, OverflowError) as exc:
|
|
138
|
+
self.ports.log(
|
|
139
|
+
"WARN",
|
|
140
|
+
f"sse_trace_payload_encode_failed event={event_name} "
|
|
141
|
+
f"error={type(exc).__name__}: {exc}",
|
|
142
|
+
)
|
|
143
|
+
event = {
|
|
144
|
+
"n": trace["event_count"],
|
|
145
|
+
"event": event_name,
|
|
146
|
+
"payload": summarize_payload(payload, self.ports.truncate),
|
|
147
|
+
}
|
|
148
|
+
if raw:
|
|
149
|
+
event["raw"] = raw
|
|
150
|
+
events.append(event)
|
|
151
|
+
except Exception as exc:
|
|
152
|
+
self.ports.log(
|
|
153
|
+
"WARN",
|
|
154
|
+
f"sse_trace_event_record_failed event={event_name} "
|
|
155
|
+
f"error={type(exc).__name__}: {exc}",
|
|
156
|
+
)
|
|
157
|
+
|
|
158
|
+
def finish(self, trace: dict[str, Any] | None, **outcome: Any) -> None:
|
|
159
|
+
if not isinstance(trace, dict):
|
|
160
|
+
return
|
|
161
|
+
try:
|
|
162
|
+
trace.update({"finished_at": time.strftime("%Y-%m-%dT%H:%M:%S"), **outcome})
|
|
163
|
+
self.config.config_dir.mkdir(parents=True, exist_ok=True)
|
|
164
|
+
temporary = self.config.last_path.with_name(
|
|
165
|
+
f"{self.config.last_path.name}.{os.getpid()}.{time.time_ns()}.tmp"
|
|
166
|
+
)
|
|
167
|
+
encoded = json.dumps(trace, ensure_ascii=False, separators=(",", ":"))
|
|
168
|
+
temporary.write_text(encoded, encoding="utf-8")
|
|
169
|
+
temporary.replace(self.config.last_path)
|
|
170
|
+
if self.ports.enabled():
|
|
171
|
+
self._rotate(self.config.trace_path, self.config.max_bytes)
|
|
172
|
+
with self.config.trace_path.open("a", encoding="utf-8") as stream:
|
|
173
|
+
stream.write(encoded + "\n")
|
|
174
|
+
except Exception as exc:
|
|
175
|
+
self.ports.log(
|
|
176
|
+
"WARN",
|
|
177
|
+
f"sse_trace_finish_failed outcome={outcome.get('outcome')} "
|
|
178
|
+
f"error={type(exc).__name__}: {exc}",
|
|
179
|
+
)
|
|
180
|
+
|
|
181
|
+
def finish_stream(
|
|
182
|
+
self,
|
|
183
|
+
trace: dict[str, Any] | None,
|
|
184
|
+
*,
|
|
185
|
+
outcome: str,
|
|
186
|
+
text_len: int = 0,
|
|
187
|
+
tool_call_count: int = 0,
|
|
188
|
+
chunks: int = 0,
|
|
189
|
+
stop_reason: str | None = None,
|
|
190
|
+
error: str | None = None,
|
|
191
|
+
) -> None:
|
|
192
|
+
result: dict[str, Any] = {
|
|
193
|
+
"outcome": outcome,
|
|
194
|
+
"text_len": text_len,
|
|
195
|
+
"tool_call_count": tool_call_count,
|
|
196
|
+
"chunks": chunks,
|
|
197
|
+
"stop_reason": stop_reason,
|
|
198
|
+
}
|
|
199
|
+
if error:
|
|
200
|
+
result["error"] = error
|
|
201
|
+
self.finish(trace, **result)
|
|
202
|
+
|
|
203
|
+
def append_tool_call(self, event: str, payload: dict[str, Any]) -> None:
|
|
204
|
+
try:
|
|
205
|
+
self.config.config_dir.mkdir(parents=True, exist_ok=True)
|
|
206
|
+
self._rotate(self.config.tool_call_path, 2_000_000)
|
|
207
|
+
record = {
|
|
208
|
+
"time": time.strftime("%Y-%m-%dT%H:%M:%S"),
|
|
209
|
+
"event": event,
|
|
210
|
+
**payload,
|
|
211
|
+
}
|
|
212
|
+
with self.config.tool_call_path.open("a", encoding="utf-8") as stream:
|
|
213
|
+
stream.write(
|
|
214
|
+
json.dumps(record, ensure_ascii=False, separators=(",", ":")) + "\n"
|
|
215
|
+
)
|
|
216
|
+
except Exception as exc:
|
|
217
|
+
self.ports.log(
|
|
218
|
+
"WARN",
|
|
219
|
+
f"tool_call_log_write_failed event={event} error={type(exc).__name__}: {exc}",
|
|
220
|
+
)
|
|
221
|
+
|
|
222
|
+
@staticmethod
|
|
223
|
+
def _rotate(path: Path, max_bytes: int) -> None:
|
|
224
|
+
if path.exists() and path.stat().st_size > max_bytes:
|
|
225
|
+
path.replace(path.with_suffix(".jsonl.1"))
|