coderouter-cli 2.4.0__tar.gz → 2.5.0__tar.gz

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 (193) hide show
  1. {coderouter_cli-2.4.0 → coderouter_cli-2.5.0}/CHANGELOG.md +48 -0
  2. {coderouter_cli-2.4.0 → coderouter_cli-2.5.0}/PKG-INFO +35 -3
  3. {coderouter_cli-2.4.0 → coderouter_cli-2.5.0}/README.en.md +34 -2
  4. {coderouter_cli-2.4.0 → coderouter_cli-2.5.0}/README.md +34 -2
  5. {coderouter_cli-2.4.0 → coderouter_cli-2.5.0}/coderouter/config/schemas.py +135 -0
  6. {coderouter_cli-2.4.0 → coderouter_cli-2.5.0}/coderouter/ingress/app.py +11 -0
  7. {coderouter_cli-2.4.0 → coderouter_cli-2.5.0}/coderouter/ingress/dashboard_routes.py +1 -0
  8. coderouter_cli-2.5.0/coderouter/ingress/launcher_routes.py +1176 -0
  9. {coderouter_cli-2.4.0 → coderouter_cli-2.5.0}/coderouter/state/suggest_rules.py +4 -4
  10. {coderouter_cli-2.4.0 → coderouter_cli-2.5.0}/docs/architecture.md +82 -2
  11. coderouter_cli-2.5.0/docs/launcher-gui.md +200 -0
  12. coderouter_cli-2.5.0/docs/launcher-quickstart.md +187 -0
  13. coderouter_cli-2.5.0/docs/launcher.md +288 -0
  14. coderouter_cli-2.5.0/docs/openrouter-roster/CHANGES.md +50 -0
  15. {coderouter_cli-2.4.0 → coderouter_cli-2.5.0}/docs/openrouter-roster/latest.json +11 -41
  16. {coderouter_cli-2.4.0 → coderouter_cli-2.5.0}/docs/quickstart.en.md +22 -3
  17. {coderouter_cli-2.4.0 → coderouter_cli-2.5.0}/docs/quickstart.md +23 -3
  18. coderouter_cli-2.5.0/examples/providers.llama-cpp-vllm.yaml +151 -0
  19. {coderouter_cli-2.4.0 → coderouter_cli-2.5.0}/pyproject.toml +1 -1
  20. {coderouter_cli-2.4.0 → coderouter_cli-2.5.0}/scripts/verify_ollama_0_23.py +4 -5
  21. coderouter_cli-2.4.0/docs/openrouter-roster/CHANGES.md +0 -24
  22. {coderouter_cli-2.4.0 → coderouter_cli-2.5.0}/.gitignore +0 -0
  23. {coderouter_cli-2.4.0 → coderouter_cli-2.5.0}/LICENSE +0 -0
  24. {coderouter_cli-2.4.0 → coderouter_cli-2.5.0}/coderouter/__init__.py +0 -0
  25. {coderouter_cli-2.4.0 → coderouter_cli-2.5.0}/coderouter/__main__.py +0 -0
  26. {coderouter_cli-2.4.0 → coderouter_cli-2.5.0}/coderouter/adapters/__init__.py +0 -0
  27. {coderouter_cli-2.4.0 → coderouter_cli-2.5.0}/coderouter/adapters/anthropic_native.py +0 -0
  28. {coderouter_cli-2.4.0 → coderouter_cli-2.5.0}/coderouter/adapters/base.py +0 -0
  29. {coderouter_cli-2.4.0 → coderouter_cli-2.5.0}/coderouter/adapters/openai_compat.py +0 -0
  30. {coderouter_cli-2.4.0 → coderouter_cli-2.5.0}/coderouter/adapters/registry.py +0 -0
  31. {coderouter_cli-2.4.0 → coderouter_cli-2.5.0}/coderouter/cli.py +1 -1
  32. {coderouter_cli-2.4.0 → coderouter_cli-2.5.0}/coderouter/cli_stats.py +0 -0
  33. {coderouter_cli-2.4.0 → coderouter_cli-2.5.0}/coderouter/config/__init__.py +0 -0
  34. {coderouter_cli-2.4.0 → coderouter_cli-2.5.0}/coderouter/config/capability_registry.py +0 -0
  35. {coderouter_cli-2.4.0 → coderouter_cli-2.5.0}/coderouter/config/env_file.py +0 -0
  36. {coderouter_cli-2.4.0 → coderouter_cli-2.5.0}/coderouter/config/loader.py +0 -0
  37. {coderouter_cli-2.4.0 → coderouter_cli-2.5.0}/coderouter/cost.py +0 -0
  38. {coderouter_cli-2.4.0 → coderouter_cli-2.5.0}/coderouter/data/__init__.py +0 -0
  39. {coderouter_cli-2.4.0 → coderouter_cli-2.5.0}/coderouter/data/model-capabilities.yaml +0 -0
  40. {coderouter_cli-2.4.0 → coderouter_cli-2.5.0}/coderouter/doctor.py +0 -0
  41. {coderouter_cli-2.4.0 → coderouter_cli-2.5.0}/coderouter/doctor_apply.py +0 -0
  42. {coderouter_cli-2.4.0 → coderouter_cli-2.5.0}/coderouter/env_security.py +0 -0
  43. {coderouter_cli-2.4.0 → coderouter_cli-2.5.0}/coderouter/errors.py +0 -0
  44. {coderouter_cli-2.4.0 → coderouter_cli-2.5.0}/coderouter/guards/__init__.py +0 -0
  45. {coderouter_cli-2.4.0 → coderouter_cli-2.5.0}/coderouter/guards/_fingerprint.py +0 -0
  46. {coderouter_cli-2.4.0 → coderouter_cli-2.5.0}/coderouter/guards/backend_health.py +0 -0
  47. {coderouter_cli-2.4.0 → coderouter_cli-2.5.0}/coderouter/guards/context_budget.py +0 -0
  48. {coderouter_cli-2.4.0 → coderouter_cli-2.5.0}/coderouter/guards/continuous_probe.py +0 -0
  49. {coderouter_cli-2.4.0 → coderouter_cli-2.5.0}/coderouter/guards/drift_actions.py +0 -0
  50. {coderouter_cli-2.4.0 → coderouter_cli-2.5.0}/coderouter/guards/drift_detection.py +0 -0
  51. {coderouter_cli-2.4.0 → coderouter_cli-2.5.0}/coderouter/guards/memory_pressure.py +0 -0
  52. {coderouter_cli-2.4.0 → coderouter_cli-2.5.0}/coderouter/guards/self_healing.py +0 -0
  53. {coderouter_cli-2.4.0 → coderouter_cli-2.5.0}/coderouter/guards/tool_loop.py +0 -0
  54. {coderouter_cli-2.4.0 → coderouter_cli-2.5.0}/coderouter/ingress/__init__.py +0 -0
  55. {coderouter_cli-2.4.0 → coderouter_cli-2.5.0}/coderouter/ingress/anthropic_routes.py +0 -0
  56. {coderouter_cli-2.4.0 → coderouter_cli-2.5.0}/coderouter/ingress/metrics_routes.py +0 -0
  57. {coderouter_cli-2.4.0 → coderouter_cli-2.5.0}/coderouter/ingress/openai_routes.py +0 -0
  58. {coderouter_cli-2.4.0 → coderouter_cli-2.5.0}/coderouter/logging.py +0 -0
  59. {coderouter_cli-2.4.0 → coderouter_cli-2.5.0}/coderouter/metrics/__init__.py +0 -0
  60. {coderouter_cli-2.4.0 → coderouter_cli-2.5.0}/coderouter/metrics/collector.py +0 -0
  61. {coderouter_cli-2.4.0 → coderouter_cli-2.5.0}/coderouter/metrics/prometheus.py +0 -0
  62. {coderouter_cli-2.4.0 → coderouter_cli-2.5.0}/coderouter/output_filters.py +0 -0
  63. {coderouter_cli-2.4.0 → coderouter_cli-2.5.0}/coderouter/plugins/__init__.py +0 -0
  64. {coderouter_cli-2.4.0 → coderouter_cli-2.5.0}/coderouter/plugins/base.py +0 -0
  65. {coderouter_cli-2.4.0 → coderouter_cli-2.5.0}/coderouter/plugins/loader.py +0 -0
  66. {coderouter_cli-2.4.0 → coderouter_cli-2.5.0}/coderouter/plugins/registry.py +0 -0
  67. {coderouter_cli-2.4.0 → coderouter_cli-2.5.0}/coderouter/routing/__init__.py +0 -0
  68. {coderouter_cli-2.4.0 → coderouter_cli-2.5.0}/coderouter/routing/adaptive.py +0 -0
  69. {coderouter_cli-2.4.0 → coderouter_cli-2.5.0}/coderouter/routing/auto_router.py +0 -0
  70. {coderouter_cli-2.4.0 → coderouter_cli-2.5.0}/coderouter/routing/budget.py +0 -0
  71. {coderouter_cli-2.4.0 → coderouter_cli-2.5.0}/coderouter/routing/capability.py +0 -0
  72. {coderouter_cli-2.4.0 → coderouter_cli-2.5.0}/coderouter/routing/fallback.py +0 -0
  73. {coderouter_cli-2.4.0 → coderouter_cli-2.5.0}/coderouter/state/__init__.py +0 -0
  74. {coderouter_cli-2.4.0 → coderouter_cli-2.5.0}/coderouter/state/audit_log.py +0 -0
  75. {coderouter_cli-2.4.0 → coderouter_cli-2.5.0}/coderouter/state/replay.py +0 -0
  76. {coderouter_cli-2.4.0 → coderouter_cli-2.5.0}/coderouter/state/request_log.py +0 -0
  77. {coderouter_cli-2.4.0 → coderouter_cli-2.5.0}/coderouter/state/store.py +0 -0
  78. {coderouter_cli-2.4.0 → coderouter_cli-2.5.0}/coderouter/token_estimation.py +0 -0
  79. {coderouter_cli-2.4.0 → coderouter_cli-2.5.0}/coderouter/translation/__init__.py +0 -0
  80. {coderouter_cli-2.4.0 → coderouter_cli-2.5.0}/coderouter/translation/anthropic.py +0 -0
  81. {coderouter_cli-2.4.0 → coderouter_cli-2.5.0}/coderouter/translation/convert.py +0 -0
  82. {coderouter_cli-2.4.0 → coderouter_cli-2.5.0}/coderouter/translation/tool_repair.py +0 -0
  83. {coderouter_cli-2.4.0 → coderouter_cli-2.5.0}/docs/assets/dashboard-demo.png +0 -0
  84. {coderouter_cli-2.4.0 → coderouter_cli-2.5.0}/docs/context-budget.md +0 -0
  85. {coderouter_cli-2.4.0 → coderouter_cli-2.5.0}/docs/continuous-probing.md +0 -0
  86. {coderouter_cli-2.4.0 → coderouter_cli-2.5.0}/docs/designs/v1.5-dashboard-mockup.html +0 -0
  87. {coderouter_cli-2.4.0 → coderouter_cli-2.5.0}/docs/designs/v1.6-auto-router-verification.md +0 -0
  88. {coderouter_cli-2.4.0 → coderouter_cli-2.5.0}/docs/designs/v1.6-auto-router.md +0 -0
  89. {coderouter_cli-2.4.0 → coderouter_cli-2.5.0}/docs/drift-detection.md +0 -0
  90. {coderouter_cli-2.4.0 → coderouter_cli-2.5.0}/docs/free-tier-guide.en.md +0 -0
  91. {coderouter_cli-2.4.0 → coderouter_cli-2.5.0}/docs/free-tier-guide.md +0 -0
  92. {coderouter_cli-2.4.0 → coderouter_cli-2.5.0}/docs/gguf_dl.md +0 -0
  93. {coderouter_cli-2.4.0 → coderouter_cli-2.5.0}/docs/hf-ollama-models.md +0 -0
  94. {coderouter_cli-2.4.0 → coderouter_cli-2.5.0}/docs/llamacpp-direct.en.md +0 -0
  95. {coderouter_cli-2.4.0 → coderouter_cli-2.5.0}/docs/llamacpp-direct.md +0 -0
  96. {coderouter_cli-2.4.0 → coderouter_cli-2.5.0}/docs/lmstudio-direct.en.md +0 -0
  97. {coderouter_cli-2.4.0 → coderouter_cli-2.5.0}/docs/lmstudio-direct.md +0 -0
  98. {coderouter_cli-2.4.0 → coderouter_cli-2.5.0}/docs/openrouter-roster/README.md +0 -0
  99. {coderouter_cli-2.4.0 → coderouter_cli-2.5.0}/docs/partial-stitch.md +0 -0
  100. {coderouter_cli-2.4.0 → coderouter_cli-2.5.0}/docs/retrospectives/v0.4.md +0 -0
  101. {coderouter_cli-2.4.0 → coderouter_cli-2.5.0}/docs/retrospectives/v0.5-verify.md +0 -0
  102. {coderouter_cli-2.4.0 → coderouter_cli-2.5.0}/docs/retrospectives/v0.5.md +0 -0
  103. {coderouter_cli-2.4.0 → coderouter_cli-2.5.0}/docs/retrospectives/v0.6.md +0 -0
  104. {coderouter_cli-2.4.0 → coderouter_cli-2.5.0}/docs/retrospectives/v0.7.md +0 -0
  105. {coderouter_cli-2.4.0 → coderouter_cli-2.5.0}/docs/retrospectives/v1.0-verify.md +0 -0
  106. {coderouter_cli-2.4.0 → coderouter_cli-2.5.0}/docs/retrospectives/v1.0.md +0 -0
  107. {coderouter_cli-2.4.0 → coderouter_cli-2.5.0}/docs/security.en.md +0 -0
  108. {coderouter_cli-2.4.0 → coderouter_cli-2.5.0}/docs/security.md +0 -0
  109. {coderouter_cli-2.4.0 → coderouter_cli-2.5.0}/docs/troubleshooting.en.md +0 -0
  110. {coderouter_cli-2.4.0 → coderouter_cli-2.5.0}/docs/troubleshooting.md +0 -0
  111. {coderouter_cli-2.4.0 → coderouter_cli-2.5.0}/docs/usage-guide.en.md +0 -0
  112. {coderouter_cli-2.4.0 → coderouter_cli-2.5.0}/docs/usage-guide.md +0 -0
  113. {coderouter_cli-2.4.0 → coderouter_cli-2.5.0}/docs/verify-ollama-0.23.1.md +0 -0
  114. {coderouter_cli-2.4.0 → coderouter_cli-2.5.0}/docs/when-do-i-need-coderouter.en.md +0 -0
  115. {coderouter_cli-2.4.0 → coderouter_cli-2.5.0}/docs/when-do-i-need-coderouter.md +0 -0
  116. {coderouter_cli-2.4.0 → coderouter_cli-2.5.0}/examples/.env.example +0 -0
  117. {coderouter_cli-2.4.0 → coderouter_cli-2.5.0}/examples/providers.auto-custom.yaml +0 -0
  118. {coderouter_cli-2.4.0 → coderouter_cli-2.5.0}/examples/providers.auto.yaml +0 -0
  119. {coderouter_cli-2.4.0 → coderouter_cli-2.5.0}/examples/providers.note-2026.yaml +0 -0
  120. {coderouter_cli-2.4.0 → coderouter_cli-2.5.0}/examples/providers.nvidia-nim.yaml +0 -0
  121. {coderouter_cli-2.4.0 → coderouter_cli-2.5.0}/examples/providers.raspberrypi.yaml +0 -0
  122. {coderouter_cli-2.4.0 → coderouter_cli-2.5.0}/examples/providers.v2-context-budget.yaml +0 -0
  123. {coderouter_cli-2.4.0 → coderouter_cli-2.5.0}/examples/providers.yaml +0 -0
  124. {coderouter_cli-2.4.0 → coderouter_cli-2.5.0}/scripts/demo_traffic.sh +0 -0
  125. {coderouter_cli-2.4.0 → coderouter_cli-2.5.0}/scripts/openrouter_roster_diff.py +0 -0
  126. {coderouter_cli-2.4.0 → coderouter_cli-2.5.0}/scripts/smoke_v2_2.sh +0 -0
  127. {coderouter_cli-2.4.0 → coderouter_cli-2.5.0}/scripts/verify-providers.yaml +0 -0
  128. {coderouter_cli-2.4.0 → coderouter_cli-2.5.0}/scripts/verify_v0_5.sh +0 -0
  129. {coderouter_cli-2.4.0 → coderouter_cli-2.5.0}/scripts/verify_v1_0.sh +0 -0
  130. {coderouter_cli-2.4.0 → coderouter_cli-2.5.0}/tests/__init__.py +0 -0
  131. {coderouter_cli-2.4.0 → coderouter_cli-2.5.0}/tests/conftest.py +0 -0
  132. {coderouter_cli-2.4.0 → coderouter_cli-2.5.0}/tests/test_adapter_anthropic.py +0 -0
  133. {coderouter_cli-2.4.0 → coderouter_cli-2.5.0}/tests/test_audit_log.py +0 -0
  134. {coderouter_cli-2.4.0 → coderouter_cli-2.5.0}/tests/test_auto_router.py +0 -0
  135. {coderouter_cli-2.4.0 → coderouter_cli-2.5.0}/tests/test_backend_health.py +0 -0
  136. {coderouter_cli-2.4.0 → coderouter_cli-2.5.0}/tests/test_budget.py +0 -0
  137. {coderouter_cli-2.4.0 → coderouter_cli-2.5.0}/tests/test_capability.py +0 -0
  138. {coderouter_cli-2.4.0 → coderouter_cli-2.5.0}/tests/test_capability_degraded_payload.py +0 -0
  139. {coderouter_cli-2.4.0 → coderouter_cli-2.5.0}/tests/test_capability_registry.py +0 -0
  140. {coderouter_cli-2.4.0 → coderouter_cli-2.5.0}/tests/test_capability_registry_cache_control.py +0 -0
  141. {coderouter_cli-2.4.0 → coderouter_cli-2.5.0}/tests/test_claude_code_suitability.py +0 -0
  142. {coderouter_cli-2.4.0 → coderouter_cli-2.5.0}/tests/test_cli.py +0 -0
  143. {coderouter_cli-2.4.0 → coderouter_cli-2.5.0}/tests/test_cli_stats.py +0 -0
  144. {coderouter_cli-2.4.0 → coderouter_cli-2.5.0}/tests/test_config.py +0 -0
  145. {coderouter_cli-2.4.0 → coderouter_cli-2.5.0}/tests/test_context_budget.py +0 -0
  146. {coderouter_cli-2.4.0 → coderouter_cli-2.5.0}/tests/test_continuous_probe.py +0 -0
  147. {coderouter_cli-2.4.0 → coderouter_cli-2.5.0}/tests/test_dashboard_endpoint.py +0 -0
  148. {coderouter_cli-2.4.0 → coderouter_cli-2.5.0}/tests/test_doctor.py +0 -0
  149. {coderouter_cli-2.4.0 → coderouter_cli-2.5.0}/tests/test_doctor_apply.py +0 -0
  150. {coderouter_cli-2.4.0 → coderouter_cli-2.5.0}/tests/test_doctor_cache_probe.py +0 -0
  151. {coderouter_cli-2.4.0 → coderouter_cli-2.5.0}/tests/test_drift_actions.py +0 -0
  152. {coderouter_cli-2.4.0 → coderouter_cli-2.5.0}/tests/test_drift_detection.py +0 -0
  153. {coderouter_cli-2.4.0 → coderouter_cli-2.5.0}/tests/test_drift_detection_integration.py +0 -0
  154. {coderouter_cli-2.4.0 → coderouter_cli-2.5.0}/tests/test_env_file.py +0 -0
  155. {coderouter_cli-2.4.0 → coderouter_cli-2.5.0}/tests/test_env_security.py +0 -0
  156. {coderouter_cli-2.4.0 → coderouter_cli-2.5.0}/tests/test_errors.py +0 -0
  157. {coderouter_cli-2.4.0 → coderouter_cli-2.5.0}/tests/test_examples_yaml.py +0 -0
  158. {coderouter_cli-2.4.0 → coderouter_cli-2.5.0}/tests/test_fallback.py +0 -0
  159. {coderouter_cli-2.4.0 → coderouter_cli-2.5.0}/tests/test_fallback_anthropic.py +0 -0
  160. {coderouter_cli-2.4.0 → coderouter_cli-2.5.0}/tests/test_fallback_cache_control.py +0 -0
  161. {coderouter_cli-2.4.0 → coderouter_cli-2.5.0}/tests/test_fallback_cache_observed.py +0 -0
  162. {coderouter_cli-2.4.0 → coderouter_cli-2.5.0}/tests/test_fallback_misconfig_warn.py +0 -0
  163. {coderouter_cli-2.4.0 → coderouter_cli-2.5.0}/tests/test_fallback_paid_gate.py +0 -0
  164. {coderouter_cli-2.4.0 → coderouter_cli-2.5.0}/tests/test_fallback_thinking.py +0 -0
  165. {coderouter_cli-2.4.0 → coderouter_cli-2.5.0}/tests/test_guards_tool_loop.py +0 -0
  166. {coderouter_cli-2.4.0 → coderouter_cli-2.5.0}/tests/test_ingress_anthropic.py +0 -0
  167. {coderouter_cli-2.4.0 → coderouter_cli-2.5.0}/tests/test_ingress_profile.py +0 -0
  168. {coderouter_cli-2.4.0 → coderouter_cli-2.5.0}/tests/test_memory_pressure.py +0 -0
  169. {coderouter_cli-2.4.0 → coderouter_cli-2.5.0}/tests/test_metrics_cache.py +0 -0
  170. {coderouter_cli-2.4.0 → coderouter_cli-2.5.0}/tests/test_metrics_collector.py +0 -0
  171. {coderouter_cli-2.4.0 → coderouter_cli-2.5.0}/tests/test_metrics_cost.py +0 -0
  172. {coderouter_cli-2.4.0 → coderouter_cli-2.5.0}/tests/test_metrics_endpoint.py +0 -0
  173. {coderouter_cli-2.4.0 → coderouter_cli-2.5.0}/tests/test_metrics_jsonl.py +0 -0
  174. {coderouter_cli-2.4.0 → coderouter_cli-2.5.0}/tests/test_metrics_prometheus.py +0 -0
  175. {coderouter_cli-2.4.0 → coderouter_cli-2.5.0}/tests/test_metrics_prometheus_cache.py +0 -0
  176. {coderouter_cli-2.4.0 → coderouter_cli-2.5.0}/tests/test_openai_compat.py +0 -0
  177. {coderouter_cli-2.4.0 → coderouter_cli-2.5.0}/tests/test_openrouter_roster_diff.py +0 -0
  178. {coderouter_cli-2.4.0 → coderouter_cli-2.5.0}/tests/test_output_filters.py +0 -0
  179. {coderouter_cli-2.4.0 → coderouter_cli-2.5.0}/tests/test_output_filters_adapters.py +0 -0
  180. {coderouter_cli-2.4.0 → coderouter_cli-2.5.0}/tests/test_partial_stitch.py +0 -0
  181. {coderouter_cli-2.4.0 → coderouter_cli-2.5.0}/tests/test_plugins_integration.py +0 -0
  182. {coderouter_cli-2.4.0 → coderouter_cli-2.5.0}/tests/test_plugins_loader.py +0 -0
  183. {coderouter_cli-2.4.0 → coderouter_cli-2.5.0}/tests/test_plugins_registry.py +0 -0
  184. {coderouter_cli-2.4.0 → coderouter_cli-2.5.0}/tests/test_reasoning_strip.py +0 -0
  185. {coderouter_cli-2.4.0 → coderouter_cli-2.5.0}/tests/test_request_log.py +0 -0
  186. {coderouter_cli-2.4.0 → coderouter_cli-2.5.0}/tests/test_routing_adaptive.py +0 -0
  187. {coderouter_cli-2.4.0 → coderouter_cli-2.5.0}/tests/test_self_healing.py +0 -0
  188. {coderouter_cli-2.4.0 → coderouter_cli-2.5.0}/tests/test_setup_sh.py +0 -0
  189. {coderouter_cli-2.4.0 → coderouter_cli-2.5.0}/tests/test_state_store.py +0 -0
  190. {coderouter_cli-2.4.0 → coderouter_cli-2.5.0}/tests/test_token_estimation.py +0 -0
  191. {coderouter_cli-2.4.0 → coderouter_cli-2.5.0}/tests/test_tool_repair.py +0 -0
  192. {coderouter_cli-2.4.0 → coderouter_cli-2.5.0}/tests/test_translation_anthropic.py +0 -0
  193. {coderouter_cli-2.4.0 → coderouter_cli-2.5.0}/tests/test_translation_reverse.py +0 -0
@@ -6,6 +6,54 @@ versioning follows [SemVer](https://semver.org/).
6
6
 
7
7
  ---
8
8
 
9
+ ## [v2.5.0] — 2026-05-22 (Launcher — llama.cpp / vllm GUI)
10
+
11
+ Browser-based process manager for local inference backends, integrated
12
+ into the existing CodeRouter web UI at `/launcher`.
13
+
14
+ ### Added
15
+
16
+ - **`coderouter/ingress/launcher_routes.py`**: New route module providing
17
+ the Launcher UI and its backing API.
18
+
19
+ - `GET /launcher` — Single-page HTML UI (Tailwind CDN + inline JS,
20
+ same dark-theme aesthetic as `/dashboard`).
21
+ - `GET /api/launcher/models` — Recursively scans `launcher.model_dirs`
22
+ and returns discovered model files with name, path, size (GB), and
23
+ extension.
24
+ - `GET /api/launcher/option-profiles` — Returns named option presets
25
+ from `providers.yaml` keyed by backend (`llama.cpp`, `vllm`).
26
+ - `GET /api/launcher/processes` — Lists all managed processes.
27
+ - `POST /api/launcher/start` — Starts a backend process. Accepts name,
28
+ backend, model_path, port, options dict, and extra_args free-text.
29
+ - `POST /api/launcher/stop/{id}` — SIGTERM → SIGKILL (5 s timeout).
30
+ - `DELETE /api/launcher/processes/{id}` — Removes a stopped process.
31
+ - `GET /api/launcher/logs/{id}` — Returns last N lines from the
32
+ process's 200-line stdout/stderr ring buffer.
33
+
34
+ - **`LauncherOptionProfile` / `LauncherConfig`** (`config/schemas.py`):
35
+ New Pydantic models for the `launcher:` block in `providers.yaml`.
36
+ Adding new CLI flags requires only a YAML edit — no code change.
37
+
38
+ - **`launcher_profiles.yaml.example`**: Template with 7 llama.cpp
39
+ presets and 7 vllm presets. For GitHub distribution and community
40
+ profile contributions.
41
+
42
+ - **`/dashboard` header**: Added a "Launcher" navigation link.
43
+
44
+ ### Design notes
45
+
46
+ - **YAML-driven**: option profiles live entirely in `providers.yaml`.
47
+ No code changes needed to add new backend flags.
48
+ - **Multi-process**: each launched process gets a UUID-based ID and is
49
+ tracked independently. llama.cpp and vllm can run side by side.
50
+ - **Zero new dependencies**: uses `asyncio.create_subprocess_exec`
51
+ (stdlib only). The 5-dep invariant is maintained.
52
+ - **In-memory registry**: does not persist across CodeRouter restarts
53
+ (intentional — avoids zombie GPU allocations on restart).
54
+
55
+ ---
56
+
9
57
  ## [v2.4.0] — 2026-05-15 (Goal-session awareness — P1-4/5/6)
10
58
 
11
59
  Stable release following v2.3.0a4. Promotes the Plugin SDK to stable,
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: coderouter-cli
3
- Version: 2.4.0
3
+ Version: 2.5.0
4
4
  Summary: Local-first, free-first, fallback-built-in LLM router. Claude Code / OpenAI compatible.
5
5
  Project-URL: Homepage, https://github.com/zephel01/CodeRouter
6
6
  Project-URL: Repository, https://github.com/zephel01/CodeRouter
@@ -141,7 +141,7 @@ ANTHROPIC_BASE_URL=http://localhost:8088 ANTHROPIC_AUTH_TOKEN=dummy claude
141
141
  | ガード | 何から守るか |
142
142
  |---|---|
143
143
  | **Context Budget** | メッセージが溜まりすぎて context window 溢れ → 自動 trim |
144
- | **Drift Detection** | モデルの応答品質が徐々に劣化 → 別 provider に切替 or KV cache flush |
144
+ | **Drift Detection** | モデルの応答品質が徐々に劣化 → 別 provider に切替 or KV cache flush (6 シグナル、`goal_mode` で目標達成停滞も検知) |
145
145
  | **Self-healing** | backend が落ちた → 自動除外 + restart + 回復 probe で自動復帰 |
146
146
  | **Tool Loop Guard** | 同じツールを無限に呼び続ける → 検知して停止 |
147
147
  | **Memory Pressure** | GPU メモリ不足を検知 → 軽量モデルに切替 |
@@ -154,9 +154,40 @@ ANTHROPIC_BASE_URL=http://localhost:8088 ANTHROPIC_AUTH_TOKEN=dummy claude
154
154
  | **`coderouter doctor`** | プロバイダの問題を 6 プローブで即診断 + 修正パッチ出力 |
155
155
  | **`/dashboard`** | ブラウザで今何が起きてるかリアルタイム確認 |
156
156
  | **`coderouter audit`** | guard 発火履歴を検索 |
157
- | **`coderouter replay`** | provider 切替の効果を統計比較 (A/B 分析) |
157
+ | **`coderouter replay`** | provider 切替の効果を統計比較 (A/B 分析) / `--suggest-rules` でルール最適化提案 |
158
158
  | **Continuous Probe** | idle 時も定期的に backend を監視 |
159
159
 
160
+ ### Launcher — llama.cpp / vllm 起動 UI
161
+
162
+ `http://localhost:8088/launcher` で開けるブラウザ UI。llama.cpp や vllm を GUI で起動・管理できます。
163
+
164
+ | 機能 | 詳細 |
165
+ |---|---|
166
+ | **モデルスキャン** | `model_dirs` に指定したフォルダを再帰スキャンして `.gguf` / `.safetensors` をリスト化 |
167
+ | **オプションプロファイル** | `providers.yaml` に名前付きプリセットを定義 → ドロップダウンで選択するだけ |
168
+ | **複数プロセス管理** | llama.cpp と vllm を同時に起動し、ポートごとに独立管理 |
169
+ | **ログビューア** | 各プロセスの stdout/stderr をブラウザ内でリアルタイム確認 |
170
+
171
+ ```yaml
172
+ # providers.yaml に追記するだけで有効になる
173
+ launcher:
174
+ model_dirs:
175
+ - ~/models
176
+ option_profiles:
177
+ llama.cpp:
178
+ - name: "GPU フル活用"
179
+ args:
180
+ "-ngl": 99
181
+ "--ctx-size": 4096
182
+ vllm:
183
+ - name: "標準"
184
+ args:
185
+ "--dtype": "auto"
186
+ "--max-model-len": 4096
187
+ ```
188
+
189
+ 詳細 → [Launcher ガイド](./docs/launcher.md)
190
+
160
191
  ---
161
192
 
162
193
  ## 設定例 (最小)
@@ -193,6 +224,7 @@ providers:
193
224
  | すぐ動かす | [Quickstart](./docs/quickstart.md) |
194
225
  | 使いこなす | [利用ガイド](./docs/usage-guide.md) |
195
226
  | 無料で回す | [無料枠ガイド](./docs/free-tier-guide.md) |
227
+ | llama.cpp / vllm を GUI で起動 | [Launcher ガイド](./docs/launcher.md) |
196
228
  | 詰まった | [トラブルシューティング](./docs/troubleshooting.md) |
197
229
  | 設計を知りたい | [アーキテクチャ詳細](./docs/architecture.md) |
198
230
  | 全リリース履歴 | [CHANGELOG](./CHANGELOG.md) |
@@ -100,7 +100,7 @@ Full decision matrix → [Do I need CodeRouter?](./docs/when-do-i-need-coderoute
100
100
  | Guard | What it protects against |
101
101
  |---|---|
102
102
  | **Context Budget** | Messages piling up → context window overflow. Auto-trim at 90% |
103
- | **Drift Detection** | Model quality degrading over time → switch provider or flush KV cache |
103
+ | **Drift Detection** | Model quality degrading over time → switch provider or flush KV cache (6 signals incl. `goal_progress_stall`; `goal_mode` for tighter thresholds) |
104
104
  | **Self-healing** | Backend crashes → auto-exclude + restart + recovery probe → auto-restore |
105
105
  | **Tool Loop Guard** | Agent calling the same tool forever → detect and break |
106
106
  | **Memory Pressure** | GPU running out of VRAM → switch to lighter model |
@@ -113,9 +113,40 @@ Full decision matrix → [Do I need CodeRouter?](./docs/when-do-i-need-coderoute
113
113
  | **`coderouter doctor`** | 6-probe diagnosis of provider issues + copy-paste YAML patches |
114
114
  | **`/dashboard`** | Real-time browser view of what's happening |
115
115
  | **`coderouter audit`** | Search guard activation history |
116
- | **`coderouter replay`** | Compare providers statistically (A/B analysis) |
116
+ | **`coderouter replay`** | Compare providers statistically (A/B analysis) / `--suggest-rules` for automated rule suggestions |
117
117
  | **Continuous Probe** | Background health monitoring even during idle |
118
118
 
119
+ ### Launcher — llama.cpp / vllm GUI
120
+
121
+ Browser UI at `http://localhost:8088/launcher` for starting and managing local inference backends.
122
+
123
+ | Feature | Detail |
124
+ |---|---|
125
+ | **Model scanner** | Recursively scans `model_dirs` for `.gguf` / `.safetensors` and lists them |
126
+ | **Option profiles** | Name your flag presets in `providers.yaml` — select from a dropdown, no CLI needed |
127
+ | **Multi-process** | Run llama.cpp and vllm side by side on different ports |
128
+ | **Log viewer** | stdout/stderr of each process shown live in the browser |
129
+
130
+ ```yaml
131
+ # Add to providers.yaml — no code changes needed
132
+ launcher:
133
+ model_dirs:
134
+ - ~/models
135
+ option_profiles:
136
+ llama.cpp:
137
+ - name: "Full GPU"
138
+ args:
139
+ "-ngl": 99
140
+ "--ctx-size": 4096
141
+ vllm:
142
+ - name: "Standard"
143
+ args:
144
+ "--dtype": "auto"
145
+ "--max-model-len": 4096
146
+ ```
147
+
148
+ Details → [Launcher guide](./docs/launcher.md)
149
+
119
150
  ---
120
151
 
121
152
  ## Minimal Config
@@ -152,6 +183,7 @@ More detail → [Usage guide](./docs/usage-guide.en.md) · [Architecture](./docs
152
183
  | Get running fast | [Quickstart](./docs/quickstart.en.md) |
153
184
  | Use it well | [Usage guide](./docs/usage-guide.en.md) |
154
185
  | Run for free | [Free-tier guide](./docs/free-tier-guide.en.md) |
186
+ | Launch llama.cpp / vllm via GUI | [Launcher guide](./docs/launcher.md) |
155
187
  | Stuck? | [Troubleshooting](./docs/troubleshooting.en.md) |
156
188
  | Understand the design | [Architecture](./docs/architecture.md) |
157
189
  | Full release history | [CHANGELOG](./CHANGELOG.md) |
@@ -100,7 +100,7 @@ ANTHROPIC_BASE_URL=http://localhost:8088 ANTHROPIC_AUTH_TOKEN=dummy claude
100
100
  | ガード | 何から守るか |
101
101
  |---|---|
102
102
  | **Context Budget** | メッセージが溜まりすぎて context window 溢れ → 自動 trim |
103
- | **Drift Detection** | モデルの応答品質が徐々に劣化 → 別 provider に切替 or KV cache flush |
103
+ | **Drift Detection** | モデルの応答品質が徐々に劣化 → 別 provider に切替 or KV cache flush (6 シグナル、`goal_mode` で目標達成停滞も検知) |
104
104
  | **Self-healing** | backend が落ちた → 自動除外 + restart + 回復 probe で自動復帰 |
105
105
  | **Tool Loop Guard** | 同じツールを無限に呼び続ける → 検知して停止 |
106
106
  | **Memory Pressure** | GPU メモリ不足を検知 → 軽量モデルに切替 |
@@ -113,9 +113,40 @@ ANTHROPIC_BASE_URL=http://localhost:8088 ANTHROPIC_AUTH_TOKEN=dummy claude
113
113
  | **`coderouter doctor`** | プロバイダの問題を 6 プローブで即診断 + 修正パッチ出力 |
114
114
  | **`/dashboard`** | ブラウザで今何が起きてるかリアルタイム確認 |
115
115
  | **`coderouter audit`** | guard 発火履歴を検索 |
116
- | **`coderouter replay`** | provider 切替の効果を統計比較 (A/B 分析) |
116
+ | **`coderouter replay`** | provider 切替の効果を統計比較 (A/B 分析) / `--suggest-rules` でルール最適化提案 |
117
117
  | **Continuous Probe** | idle 時も定期的に backend を監視 |
118
118
 
119
+ ### Launcher — llama.cpp / vllm 起動 UI
120
+
121
+ `http://localhost:8088/launcher` で開けるブラウザ UI。llama.cpp や vllm を GUI で起動・管理できます。
122
+
123
+ | 機能 | 詳細 |
124
+ |---|---|
125
+ | **モデルスキャン** | `model_dirs` に指定したフォルダを再帰スキャンして `.gguf` / `.safetensors` をリスト化 |
126
+ | **オプションプロファイル** | `providers.yaml` に名前付きプリセットを定義 → ドロップダウンで選択するだけ |
127
+ | **複数プロセス管理** | llama.cpp と vllm を同時に起動し、ポートごとに独立管理 |
128
+ | **ログビューア** | 各プロセスの stdout/stderr をブラウザ内でリアルタイム確認 |
129
+
130
+ ```yaml
131
+ # providers.yaml に追記するだけで有効になる
132
+ launcher:
133
+ model_dirs:
134
+ - ~/models
135
+ option_profiles:
136
+ llama.cpp:
137
+ - name: "GPU フル活用"
138
+ args:
139
+ "-ngl": 99
140
+ "--ctx-size": 4096
141
+ vllm:
142
+ - name: "標準"
143
+ args:
144
+ "--dtype": "auto"
145
+ "--max-model-len": 4096
146
+ ```
147
+
148
+ 詳細 → [Launcher ガイド](./docs/launcher.md)
149
+
119
150
  ---
120
151
 
121
152
  ## 設定例 (最小)
@@ -152,6 +183,7 @@ providers:
152
183
  | すぐ動かす | [Quickstart](./docs/quickstart.md) |
153
184
  | 使いこなす | [利用ガイド](./docs/usage-guide.md) |
154
185
  | 無料で回す | [無料枠ガイド](./docs/free-tier-guide.md) |
186
+ | llama.cpp / vllm を GUI で起動 | [Launcher ガイド](./docs/launcher.md) |
155
187
  | 詰まった | [トラブルシューティング](./docs/troubleshooting.md) |
156
188
  | 設計を知りたい | [アーキテクチャ詳細](./docs/architecture.md) |
157
189
  | 全リリース履歴 | [CHANGELOG](./CHANGELOG.md) |
@@ -874,6 +874,130 @@ class AutoRouterConfig(BaseModel):
874
874
  )
875
875
 
876
876
 
877
+ class LauncherBackendConfig(BaseModel):
878
+ """Per-backend binary path configuration for the Launcher.
879
+
880
+ When ``binary`` is unset, the Launcher falls back to the default
881
+ executable name (``llama-server`` for llama.cpp, ``python`` for vllm)
882
+ and relies on ``$PATH`` resolution — which works when the tool is
883
+ globally installed. Set ``binary`` when:
884
+
885
+ - llama.cpp was built from source (e.g. ``~/llama.cpp/build/bin/llama-server``)
886
+ - vllm lives in a virtualenv (e.g. ``~/.venv/bin/python``)
887
+ - Multiple builds coexist and you want to pin a specific one
888
+
889
+ Tilde (``~``) and environment variables are expanded at launch time.
890
+
891
+ Example::
892
+
893
+ backends:
894
+ llama.cpp:
895
+ binary: ~/llama.cpp/build/bin/llama-server
896
+ vllm:
897
+ binary: ~/.venv/bin/python
898
+ """
899
+
900
+ model_config = ConfigDict(extra="forbid")
901
+
902
+ binary: str | None = Field(
903
+ default=None,
904
+ description=(
905
+ "Absolute or ``~``-relative path to the backend executable. "
906
+ "llama.cpp default: ``llama-server`` (PATH). "
907
+ "vllm default: ``python`` (PATH). "
908
+ "Expanded at launch time."
909
+ ),
910
+ )
911
+
912
+
913
+ class LauncherOptionProfile(BaseModel):
914
+ """One named option preset for a launcher backend (e.g. llama.cpp / vllm).
915
+
916
+ ``args`` maps CLI flag strings to their values. A bool value of
917
+ ``True`` means "include the flag without a value" (e.g. ``--no-mmap``);
918
+ ``False`` means "omit the flag entirely". All other value types are
919
+ converted to strings and appended as ``--flag value`` pairs.
920
+
921
+ Example::
922
+
923
+ name: "GPU速度重視"
924
+ args:
925
+ "-ngl": 99
926
+ "--ctx-size": 4096
927
+ "--no-mmap": false
928
+ """
929
+
930
+ model_config = ConfigDict(extra="forbid")
931
+
932
+ name: str = Field(..., description="Display name shown in the Launcher UI dropdown.")
933
+ args: dict[str, str | int | float | bool] = Field(
934
+ default_factory=dict,
935
+ description=(
936
+ "CLI flag → value mapping. "
937
+ "bool True = flag only (no value). "
938
+ "bool False = omit flag. "
939
+ "All other types are stringified and passed as '--flag value'."
940
+ ),
941
+ )
942
+
943
+
944
+ class LauncherConfig(BaseModel):
945
+ """The ``launcher:`` block in providers.yaml.
946
+
947
+ Controls the Launcher UI available at ``/launcher``.
948
+
949
+ Example::
950
+
951
+ launcher:
952
+ model_dirs:
953
+ - ~/models
954
+ - /data/gguf
955
+ option_profiles:
956
+ llama.cpp:
957
+ - name: "GPU速度重視"
958
+ args:
959
+ "-ngl": 99
960
+ "--ctx-size": 4096
961
+ vllm:
962
+ - name: "標準"
963
+ args:
964
+ "--dtype": "auto"
965
+ "--max-model-len": 4096
966
+ """
967
+
968
+ model_config = ConfigDict(extra="forbid")
969
+
970
+ model_dirs: list[str] = Field(
971
+ default_factory=list,
972
+ description=(
973
+ "Directories to scan for model files "
974
+ "(.gguf, .safetensors, .bin, .pt, .ggml). "
975
+ "Paths are expanded (~ and env vars) at scan time, not at load. "
976
+ "Non-existent paths are silently skipped."
977
+ ),
978
+ )
979
+ backends: dict[str, LauncherBackendConfig] = Field(
980
+ default_factory=dict,
981
+ description=(
982
+ "Per-backend binary path overrides. "
983
+ "Keys are backend names ('llama.cpp', 'vllm'). "
984
+ "When a key is absent, the default executable is used "
985
+ "('llama-server' / 'python') and resolved via PATH. "
986
+ "Useful when running a from-source build or a venv-specific binary."
987
+ ),
988
+ )
989
+ option_profiles: dict[str, list[LauncherOptionProfile]] = Field(
990
+ default_factory=dict,
991
+ description=(
992
+ "Named option presets per backend. "
993
+ "Keys should be backend names: 'llama.cpp', 'vllm'. "
994
+ "Each key maps to an ordered list of named presets. "
995
+ "A free-form 'extra args' field is always available in the UI "
996
+ "for one-off overrides without touching this config."
997
+ ),
998
+ )
999
+
1000
+
877
1001
  class PluginsConfig(BaseModel):
878
1002
  """The ``plugins:`` block in providers.yaml (v2.3.0).
879
1003
 
@@ -1082,6 +1206,17 @@ class CodeRouterConfig(BaseModel):
1082
1206
  "plugins (zero-cost, backward-compatible default)."
1083
1207
  ),
1084
1208
  )
1209
+ launcher: LauncherConfig | None = Field(
1210
+ default=None,
1211
+ description=(
1212
+ "Launcher configuration for the /launcher UI. "
1213
+ "Defines model_dirs to scan and option_profiles per backend "
1214
+ "('llama.cpp', 'vllm'). "
1215
+ "Unset (None) = Launcher UI shows empty model list and no profiles. "
1216
+ "The Launcher UI itself is always available at /launcher "
1217
+ "regardless of this setting."
1218
+ ),
1219
+ )
1085
1220
 
1086
1221
  @model_validator(mode="after")
1087
1222
  def _check_default_profile_exists(self) -> CodeRouterConfig:
@@ -13,6 +13,7 @@ from coderouter import __version__
13
13
  from coderouter.config import load_config
14
14
  from coderouter.ingress.anthropic_routes import router as anthropic_router
15
15
  from coderouter.ingress.dashboard_routes import router as dashboard_router
16
+ from coderouter.ingress.launcher_routes import router as launcher_router
16
17
  from coderouter.ingress.metrics_routes import router as metrics_router
17
18
  from coderouter.ingress.openai_routes import router as openai_router
18
19
  from coderouter.logging import configure_logging, get_logger
@@ -178,6 +179,12 @@ def create_app(config_path: str | None = None) -> FastAPI:
178
179
  with contextlib.suppress(Exception):
179
180
  await probe_task
180
181
 
182
+ # Launcher: stop child llama.cpp / vllm processes so they don't orphan.
183
+ from coderouter.ingress.launcher_routes import shutdown_launcher
184
+
185
+ with contextlib.suppress(Exception):
186
+ await shutdown_launcher(app)
187
+
181
188
  # v2.0-J: graceful shutdown of recovery probe tasks.
182
189
  with contextlib.suppress(Exception):
183
190
  await engine.shutdown_recovery_probes()
@@ -259,6 +266,10 @@ def create_app(config_path: str | None = None) -> FastAPI:
259
266
  # Same root-level mount as /metrics.json — the dashboard is a UI
260
267
  # concern and doesn't belong under the /v1 API surface.
261
268
  app.include_router(dashboard_router, tags=["dashboard"])
269
+ # Launcher UI + process management API.
270
+ # /launcher → single-page HTML UI
271
+ # /api/launcher/* → model scan, process start/stop/logs
272
+ app.include_router(launcher_router, tags=["launcher"])
262
273
 
263
274
  return app
264
275
 
@@ -76,6 +76,7 @@ _DASHBOARD_HTML = r"""<!doctype html>
76
76
  <header class="border-b border-slate-800 px-6 py-3">
77
77
  <div class="max-w-7xl mx-auto flex flex-wrap items-center gap-x-6 gap-y-2 text-sm">
78
78
  <span class="text-lg font-semibold tracking-tight">CodeRouter</span>
79
+ <a href="/launcher" class="text-slate-400 hover:text-slate-200 transition-colors text-sm">Launcher</a>
79
80
  <span class="text-slate-400">profile: <span data-bind="profile" class="text-slate-100 font-mono">—</span></span>
80
81
  <span class="text-slate-400">uptime: <span data-bind="uptime" class="text-slate-100 font-mono tabnum">—</span></span>
81
82
  <span class="text-slate-400">requests: <span data-bind="requests_total" class="text-slate-100 font-mono tabnum">0</span></span>