@oneciel-ai/ciel-runtime 0.2.2 → 0.2.4

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 (136) hide show
  1. package/ciel_runtime.py +2555 -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/config_repository.py +30 -0
  36. package/ciel_runtime_support/configuration_cli.py +38 -0
  37. package/ciel_runtime_support/context_compaction.py +9 -4
  38. package/ciel_runtime_support/credential_management.py +12 -0
  39. package/ciel_runtime_support/credentials.py +12 -0
  40. package/ciel_runtime_support/github_copilot_oauth.py +2 -2
  41. package/ciel_runtime_support/hosted_formula_tools.py +216 -0
  42. package/ciel_runtime_support/kimi_runtime_context.py +208 -0
  43. package/ciel_runtime_support/llm_preset_context.py +338 -0
  44. package/ciel_runtime_support/managed_mcp_config.py +8 -4
  45. package/ciel_runtime_support/mcp_configuration_context.py +291 -0
  46. package/ciel_runtime_support/mcp_http_proxy.py +14 -8
  47. package/ciel_runtime_support/mcp_probe_transport.py +47 -15
  48. package/ciel_runtime_support/mcp_transport.py +14 -1
  49. package/ciel_runtime_support/native_context_recovery.py +72 -0
  50. package/ciel_runtime_support/ollama_catalog_context.py +213 -0
  51. package/ciel_runtime_support/ollama_stream_collection.py +103 -0
  52. package/ciel_runtime_support/ollama_thinking.py +6 -1
  53. package/ciel_runtime_support/ollama_wire_projection.py +157 -0
  54. package/ciel_runtime_support/openai_forwarding.py +32 -10
  55. package/ciel_runtime_support/openai_responses_router.py +12 -0
  56. package/ciel_runtime_support/package_lifecycle.py +39 -0
  57. package/ciel_runtime_support/prelaunch_assembly.py +37 -0
  58. package/ciel_runtime_support/prelaunch_panel_context.py +418 -0
  59. package/ciel_runtime_support/prelaunch_shell_context.py +394 -0
  60. package/ciel_runtime_support/prompt_compaction.py +144 -0
  61. package/ciel_runtime_support/prompt_injection.py +45 -0
  62. package/ciel_runtime_support/protocols/anthropic_thinking_policy.py +1 -1
  63. package/ciel_runtime_support/protocols/chat_projection.py +85 -5
  64. package/ciel_runtime_support/protocols/conversation_turn_policy.py +43 -0
  65. package/ciel_runtime_support/protocols/ollama_chat.py +31 -0
  66. package/ciel_runtime_support/protocols/ollama_response.py +57 -5
  67. package/ciel_runtime_support/protocols/openai_reasoning.py +5 -2
  68. package/ciel_runtime_support/protocols/openai_responses.py +61 -15
  69. package/ciel_runtime_support/provider_adapters.py +26 -0
  70. package/ciel_runtime_support/provider_administration_context.py +207 -0
  71. package/ciel_runtime_support/provider_config_mutations.py +3 -0
  72. package/ciel_runtime_support/provider_model_catalog_context.py +137 -0
  73. package/ciel_runtime_support/provider_model_context.py +107 -0
  74. package/ciel_runtime_support/provider_model_metadata_context.py +197 -0
  75. package/ciel_runtime_support/provider_model_selection.py +10 -3
  76. package/ciel_runtime_support/provider_models.py +45 -2
  77. package/ciel_runtime_support/provider_option_cli.py +19 -0
  78. package/ciel_runtime_support/provider_policy.py +1 -1
  79. package/ciel_runtime_support/provider_readiness_context.py +189 -0
  80. package/ciel_runtime_support/provider_request_builder.py +64 -28
  81. package/ciel_runtime_support/provider_responses_passthrough.py +21 -2
  82. package/ciel_runtime_support/provider_timeout_policy.py +54 -0
  83. package/ciel_runtime_support/provider_tool_policy.py +9 -1
  84. package/ciel_runtime_support/providers/__init__.py +6 -0
  85. package/ciel_runtime_support/providers/alibaba.py +634 -0
  86. package/ciel_runtime_support/providers/catalog.py +24 -16
  87. package/ciel_runtime_support/providers/deepseek.py +73 -0
  88. package/ciel_runtime_support/providers/github_copilot_oauth.py +22 -1
  89. package/ciel_runtime_support/providers/kimi.py +69 -9
  90. package/ciel_runtime_support/providers/ollama.py +8 -0
  91. package/ciel_runtime_support/providers/ollama_context.py +21 -2
  92. package/ciel_runtime_support/providers/vllm.py +7 -1
  93. package/ciel_runtime_support/response_collection.py +68 -18
  94. package/ciel_runtime_support/response_collection_context.py +391 -0
  95. package/ciel_runtime_support/response_stream_context.py +555 -0
  96. package/ciel_runtime_support/responses_input_compatibility.py +121 -0
  97. package/ciel_runtime_support/responses_usage_observer.py +83 -0
  98. package/ciel_runtime_support/router_client_lifecycle.py +1 -0
  99. package/ciel_runtime_support/router_http.py +245 -3
  100. package/ciel_runtime_support/router_observability_context.py +251 -0
  101. package/ciel_runtime_support/router_process_context.py +200 -0
  102. package/ciel_runtime_support/router_process_lifecycle.py +2 -0
  103. package/ciel_runtime_support/router_request_assembly.py +399 -0
  104. package/ciel_runtime_support/router_request_context.py +215 -0
  105. package/ciel_runtime_support/router_server_context.py +84 -0
  106. package/ciel_runtime_support/runaway_output_guard.py +488 -0
  107. package/ciel_runtime_support/runtime_asset_assembly.py +147 -0
  108. package/ciel_runtime_support/runtime_asset_context.py +297 -0
  109. package/ciel_runtime_support/runtime_constants.py +16 -1
  110. package/ciel_runtime_support/runtime_launch.py +9 -5
  111. package/ciel_runtime_support/runtime_launch_context.py +130 -0
  112. package/ciel_runtime_support/runtime_maintenance_assembly.py +60 -0
  113. package/ciel_runtime_support/runtime_maintenance_context.py +309 -0
  114. package/ciel_runtime_support/runtime_maintenance_services.py +265 -0
  115. package/ciel_runtime_support/runtime_paths.py +60 -40
  116. package/ciel_runtime_support/runtime_primitives.py +78 -0
  117. package/ciel_runtime_support/speech_http_controller.py +335 -0
  118. package/ciel_runtime_support/sse_stream_collection.py +236 -0
  119. package/ciel_runtime_support/statusline_script.py +57 -8
  120. package/ciel_runtime_support/streaming_anthropic.py +361 -24
  121. package/ciel_runtime_support/tool_schema.py +40 -2
  122. package/ciel_runtime_support/tool_side_effect_dedupe.py +117 -12
  123. package/ciel_runtime_support/upstream_dump.py +68 -0
  124. package/ciel_runtime_support/upstream_retry_context.py +259 -0
  125. package/ciel_runtime_support/web_ui.py +248 -1
  126. package/ciel_runtime_support/workspace_router_selection.py +86 -0
  127. package/docs/COLAB_SPEECH.md +32 -0
  128. package/docs/Configuration.md +50 -0
  129. package/docs/Test-Suite.md +1 -0
  130. package/package.json +4 -1
  131. package/scripts/colab/__pycache__/bootstrap_moss_tts.cpython-311.pyc +0 -0
  132. package/scripts/colab/__pycache__/bootstrap_qwen_asr.cpython-311.pyc +0 -0
  133. package/scripts/colab/bootstrap_moss_tts.py +106 -0
  134. package/scripts/colab/bootstrap_qwen_asr.py +106 -0
  135. package/scripts/configure_speech_workers.py +37 -0
  136. package/scripts/deploy_colab_speech.ps1 +47 -0
@@ -0,0 +1,106 @@
1
+ """Bootstrap Qwen3-ASR on a Colab T4 and publish it only to the tailnet.
2
+
3
+ Required Colab Secret: TAILSCALE_AUTHKEY
4
+ Optional Colab Secret: CIEL_SPEECH_API_KEY
5
+ """
6
+
7
+ from __future__ import annotations
8
+
9
+ import json
10
+ import os
11
+ from pathlib import Path
12
+ import shutil
13
+ import subprocess
14
+ import sys
15
+ import time
16
+ import urllib.request
17
+
18
+
19
+ HOSTNAME = os.environ.get("CIEL_ASR_HOSTNAME", "ciel-asr")
20
+ PORT = 8000
21
+ SOCKET = "/tmp/ciel-asr-tailscaled.sock"
22
+ STATE = "/tmp/ciel-asr-tailscaled.state"
23
+ LOG_DIR = Path("/content/ciel-speech-logs")
24
+
25
+
26
+ def secret(name: str, *, required: bool = False) -> str:
27
+ value = str(os.environ.get(name) or "").strip()
28
+ if not value:
29
+ try:
30
+ from google.colab import userdata # type: ignore
31
+
32
+ value = str(userdata.get(name) or "").strip()
33
+ except Exception:
34
+ value = ""
35
+ if required and not value:
36
+ raise RuntimeError(f"Add {name} to Colab Secrets and allow notebook access, then rerun this script.")
37
+ return value
38
+
39
+
40
+ def run(*args: str, check: bool = True) -> subprocess.CompletedProcess[str]:
41
+ print("+", " ".join(args))
42
+ return subprocess.run(args, check=check, text=True, capture_output=False)
43
+
44
+
45
+ def install_tailscale() -> None:
46
+ if shutil.which("tailscale"):
47
+ return
48
+ run("bash", "-lc", "curl -fsSL https://tailscale.com/install.sh | sh")
49
+
50
+
51
+ def start_tailscale(auth_key: str) -> tuple[str, str]:
52
+ install_tailscale()
53
+ LOG_DIR.mkdir(parents=True, exist_ok=True)
54
+ tail_log = (LOG_DIR / "tailscale-asr.log").open("ab")
55
+ subprocess.Popen(
56
+ ["tailscaled", f"--socket={SOCKET}", f"--state={STATE}", "--tun=userspace-networking"],
57
+ stdout=tail_log,
58
+ stderr=subprocess.STDOUT,
59
+ start_new_session=True,
60
+ )
61
+ for _ in range(60):
62
+ if Path(SOCKET).exists():
63
+ break
64
+ time.sleep(1)
65
+ run("tailscale", f"--socket={SOCKET}", "up", f"--auth-key={auth_key}", f"--hostname={HOSTNAME}", "--accept-dns=true", "--reset")
66
+ status = subprocess.check_output(["tailscale", f"--socket={SOCKET}", "status", "--json"], text=True)
67
+ dns_name = str(json.loads(status).get("Self", {}).get("DNSName") or HOSTNAME).rstrip(".")
68
+ serve = run("tailscale", f"--socket={SOCKET}", "serve", "--bg", "--https=443", f"http://127.0.0.1:{PORT}", check=False)
69
+ if serve.returncode == 0:
70
+ return dns_name, f"https://{dns_name}"
71
+ run("tailscale", f"--socket={SOCKET}", "serve", "--bg", "--http=80", f"http://127.0.0.1:{PORT}")
72
+ return dns_name, f"http://{dns_name}"
73
+
74
+
75
+ def wait_for_server(api_key: str) -> None:
76
+ headers = {"authorization": f"Bearer {api_key}"} if api_key else {}
77
+ for _ in range(180):
78
+ try:
79
+ with urllib.request.urlopen(urllib.request.Request(f"http://127.0.0.1:{PORT}/health", headers=headers), timeout=3) as response:
80
+ if response.status < 500:
81
+ return
82
+ except Exception:
83
+ time.sleep(2)
84
+ raise RuntimeError("Qwen ASR did not become healthy; inspect /content/ciel-speech-logs/qwen-asr.log")
85
+
86
+
87
+ def main() -> None:
88
+ auth_key = secret("TAILSCALE_AUTHKEY", required=True)
89
+ api_key = secret("CIEL_SPEECH_API_KEY")
90
+ run(sys.executable, "-m", "pip", "install", "-U", "qwen-asr[vllm]", "vllm[audio]")
91
+ LOG_DIR.mkdir(parents=True, exist_ok=True)
92
+ command = [
93
+ "qwen-asr-serve", "Qwen/Qwen3-ASR-0.6B", "--host", "127.0.0.1", "--port", str(PORT),
94
+ "--gpu-memory-utilization", "0.78", "--max-model-len", "8192",
95
+ ]
96
+ if api_key:
97
+ command.extend(["--api-key", api_key])
98
+ server_log = (LOG_DIR / "qwen-asr.log").open("ab")
99
+ subprocess.Popen(command, stdout=server_log, stderr=subprocess.STDOUT, start_new_session=True)
100
+ wait_for_server(api_key)
101
+ dns_name, base_url = start_tailscale(auth_key)
102
+ print(json.dumps({"ok": True, "role": "asr", "hostname": dns_name, "base_url": base_url, "model": "Qwen/Qwen3-ASR-0.6B", "api_key_set": bool(api_key)}, indent=2))
103
+
104
+
105
+ if __name__ == "__main__":
106
+ main()
@@ -0,0 +1,37 @@
1
+ """Persist deployed speech worker URLs in the active Ciel Runtime config."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import argparse
6
+ from pathlib import Path
7
+ import sys
8
+ from typing import Any
9
+
10
+ sys.path.insert(0, str(Path(__file__).resolve().parents[1]))
11
+
12
+
13
+ def configure(asr_base_url: str, tts_base_url: str) -> dict[str, Any]:
14
+ import ciel_runtime
15
+
16
+ config = ciel_runtime.load_config()
17
+ speech = config.setdefault("speech", {})
18
+ asr = speech.setdefault("asr", {})
19
+ tts = speech.setdefault("tts", {})
20
+ asr.update({"enabled": True, "base_url": asr_base_url.rstrip("/"), "model": "Qwen/Qwen3-ASR-0.6B"})
21
+ tts.update({"enabled": True, "base_url": tts_base_url.rstrip("/"), "model": "OpenMOSS-Team/MOSS-TTS-Nano"})
22
+ ciel_runtime.save_config(config)
23
+ return {"asr": asr["base_url"], "tts": tts["base_url"]}
24
+
25
+
26
+ def main() -> int:
27
+ parser = argparse.ArgumentParser()
28
+ parser.add_argument("--asr-base-url", required=True)
29
+ parser.add_argument("--tts-base-url", required=True)
30
+ args = parser.parse_args()
31
+ result = configure(args.asr_base_url, args.tts_base_url)
32
+ print(f"Configured Ciel speech workers: ASR={result['asr']} TTS={result['tts']}")
33
+ return 0
34
+
35
+
36
+ if __name__ == "__main__":
37
+ raise SystemExit(main())
@@ -0,0 +1,47 @@
1
+ param(
2
+ [string]$Distribution = "Ubuntu-26.04",
3
+ [string]$AsrSession = "ciel-asr",
4
+ [string]$TtsSession = "ciel-tts"
5
+ )
6
+
7
+ $ErrorActionPreference = "Stop"
8
+ $repo = (Resolve-Path (Join-Path $PSScriptRoot "..")).Path
9
+ $wslRepo = (& wsl -d $Distribution -- wslpath -a ($repo -replace '\\', '/')).Trim()
10
+ if (-not $wslRepo) { throw "Could not resolve the repository path in WSL." }
11
+
12
+ Write-Host "Checking Colab CLI authentication..."
13
+ & wsl -d $Distribution -- bash -lc "colab status >/dev/null"
14
+ if ($LASTEXITCODE -ne 0) {
15
+ throw "Colab CLI is not authenticated. Configure ADC in WSL (gcloud auth application-default login), then rerun."
16
+ }
17
+
18
+ Write-Host "Creating ASR T4 session: $AsrSession"
19
+ & wsl -d $Distribution -- bash -lc "colab new --gpu T4 --session '$AsrSession'"
20
+ if ($LASTEXITCODE -ne 0) { throw "Could not create ASR Colab session." }
21
+
22
+ Write-Host "Creating TTS T4 session: $TtsSession"
23
+ & wsl -d $Distribution -- bash -lc "colab new --gpu T4 --session '$TtsSession'"
24
+ if ($LASTEXITCODE -ne 0) { throw "Could not create TTS Colab session." }
25
+
26
+ Write-Host "Installing Qwen3-ASR and its Tailscale service..."
27
+ $asrOutput = (& wsl -d $Distribution -- bash -lc "colab exec --session '$AsrSession' --file '$wslRepo/scripts/colab/bootstrap_qwen_asr.py'" 2>&1 | Tee-Object -Variable asrDisplay) -join "`n"
28
+ if ($LASTEXITCODE -ne 0) { throw "ASR bootstrap failed." }
29
+
30
+ Write-Host "Installing MOSS-TTS-Nano and its Tailscale service..."
31
+ $ttsOutput = (& wsl -d $Distribution -- bash -lc "colab exec --session '$TtsSession' --file '$wslRepo/scripts/colab/bootstrap_moss_tts.py'" 2>&1 | Tee-Object -Variable ttsDisplay) -join "`n"
32
+ if ($LASTEXITCODE -ne 0) { throw "TTS bootstrap failed." }
33
+
34
+ function Read-BootstrapResult([string]$Text, [string]$Role) {
35
+ $matches = [regex]::Matches($Text, '(?s)\{\s*"ok"\s*:\s*true.*?\}')
36
+ if ($matches.Count -eq 0) { throw "Could not find the $Role bootstrap result in Colab output." }
37
+ $result = $matches[$matches.Count - 1].Value | ConvertFrom-Json
38
+ if ($result.role -ne $Role -or -not $result.base_url) { throw "Invalid $Role bootstrap result." }
39
+ return $result
40
+ }
41
+
42
+ $asr = Read-BootstrapResult $asrOutput "asr"
43
+ $tts = Read-BootstrapResult $ttsOutput "tts"
44
+ & python (Join-Path $PSScriptRoot "configure_speech_workers.py") --asr-base-url $asr.base_url --tts-base-url $tts.base_url
45
+ if ($LASTEXITCODE -ne 0) { throw "Workers started, but Ciel speech configuration failed." }
46
+
47
+ Write-Host "Both services are running and connected to Web Chat > Speech Settings."