coderouter-cli 2.7.4__py3-none-any.whl → 2.7.5__py3-none-any.whl

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.
coderouter/cli.py CHANGED
@@ -10,6 +10,36 @@ import uvicorn
10
10
 
11
11
  from coderouter import __version__
12
12
 
13
+ # Bind addresses that keep the server loopback-only. Anything else means the
14
+ # operator is deliberately exposing CodeRouter beyond this machine, at which
15
+ # point the v2.7.0 Host-header validation (DNS-rebinding guard) will 403 every
16
+ # request whose Host is not allow-listed — a combination that has confused
17
+ # real users ("worked on 2.6, LAN access broken on 2.7").
18
+ _LOOPBACK_BIND_HOSTS = frozenset({"127.0.0.1", "localhost", "::1", "[::1]"})
19
+
20
+
21
+ def _external_bind_warning(host: str, allowed_hosts_env: str | None) -> str | None:
22
+ """Return a startup warning when binding beyond loopback needs config.
23
+
24
+ Fires only for the confusing combination: non-loopback bind (the operator
25
+ wants LAN/external access) while ``CODEROUTER_ALLOWED_HOSTS`` is unset
26
+ (so every non-loopback Host header will be rejected with 403). Returns
27
+ the warning text, or None when the configuration is coherent.
28
+ """
29
+ if host in _LOOPBACK_BIND_HOSTS:
30
+ return None
31
+ if allowed_hosts_env and allowed_hosts_env.strip():
32
+ return None
33
+ return (
34
+ f"serve: binding on {host!r} but CODEROUTER_ALLOWED_HOSTS is not set. "
35
+ "Requests whose Host header is not loopback will be rejected with 403 "
36
+ "(v2.7.0 DNS-rebinding guard). To allow LAN access, set "
37
+ "CODEROUTER_ALLOWED_HOSTS=<THIS machine's address as it appears in the "
38
+ "client's URL bar, e.g. 192.168.x.x — NOT the client's own IP> "
39
+ "(comma-separated, no port). Note the chat endpoints have no "
40
+ "authentication — do not expose CodeRouter directly to the internet."
41
+ )
42
+
13
43
 
14
44
  def _build_parser() -> argparse.ArgumentParser:
15
45
  parser = argparse.ArgumentParser(
@@ -366,6 +396,15 @@ def main(argv: list[str] | None = None) -> int:
366
396
  if stripped:
367
397
  os.environ["CODEROUTER_MODE"] = stripped
368
398
 
399
+ # v2.7.5: warn about the "bound beyond loopback but Host validation
400
+ # will reject everything" trap BEFORE uvicorn takes over the console,
401
+ # so the hint is the first thing an operator sees.
402
+ warning = _external_bind_warning(
403
+ args.host, os.environ.get("CODEROUTER_ALLOWED_HOSTS")
404
+ )
405
+ if warning:
406
+ print(f"WARNING: {warning}", file=sys.stderr)
407
+
369
408
  uvicorn.run(
370
409
  "coderouter.ingress.app:create_app",
371
410
  factory=True,
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: coderouter-cli
3
- Version: 2.7.4
3
+ Version: 2.7.5
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
@@ -98,7 +98,7 @@ Description-Content-Type: text/markdown
98
98
  | backend が落ちたらセッション終了 | ローカル → 無料 → 有料へ自動フォールバック |
99
99
  | 長時間で context 溢れ・drift・ループ | 6 系統ガード + self-healing |
100
100
  | モデル名がハードコード (リタイアで即エラー) | プロファイルで抽象化、差し替え 1 行 |
101
- | 何が悪いか分からない | `doctor` 6 プローブ + `/dashboard` + audit/replay |
101
+ | 何が悪いか分からない | `doctor` 7 プローブ + `/dashboard` + audit/replay |
102
102
 
103
103
  直結で困っていないなら CodeRouter は不要です。**長時間・無人・弱いモデル**のどれかに当てはまったら、戻ってきてください。
104
104
 
@@ -167,14 +167,14 @@ ANTHROPIC_BASE_URL=http://localhost:8088 ANTHROPIC_AUTH_TOKEN=dummy claude
167
167
  | **Drift Detection** | モデルの応答品質が徐々に劣化 → 別 provider に切替 or KV cache flush (6 シグナル、`goal_mode` で目標達成停滞も検知) |
168
168
  | **Self-healing** | backend が落ちた → 自動除外 + restart + 回復 probe で自動復帰 |
169
169
  | **Tool Loop Guard** | 同じツールを無限に呼び続ける → 検知して停止 |
170
- | **Memory Pressure** | GPU メモリ不足を検知軽量モデルに切替 |
170
+ | **Memory Pressure** | OOM を出した backend を一時除外 チェーンの次の provider へフォールスルー |
171
171
  | **Mid-stream Guard** | 応答途中で落ちた → 溜まったテキストを安全に返却 |
172
172
 
173
173
  ### 診断と可視化
174
174
 
175
175
  | 機能 | 何がわかるか |
176
176
  |---|---|
177
- | **`coderouter doctor`** | プロバイダの問題を 6 プローブで即診断 + 修正パッチ出力 |
177
+ | **`coderouter doctor`** | プロバイダの問題を 7 プローブで即診断 + 修正パッチ出力 |
178
178
  | **`/dashboard`** | ブラウザで今何が起きてるかリアルタイム確認 |
179
179
  | **`coderouter audit`** | guard 発火履歴を検索 |
180
180
  | **`coderouter replay`** | provider 切替の効果を統計比較 (A/B 分析) / `--suggest-rules` でルール最適化提案 |
@@ -281,6 +281,7 @@ providers:
281
281
  | 無料で回す | [無料枠ガイド](./docs/guides/free-tier-guide.md) |
282
282
  | llama.cpp / vllm を GUI で起動 | [Launcher ガイド](./docs/backends/launcher.md) |
283
283
  | 言語税を計測・回避する | [言語税ガイド](./docs/guides/language-tax.md) |
284
+ | 別の PC から安全に繋ぐ | [リモートアクセスガイド](./docs/guides/remote-access.md) |
284
285
  | 詰まった | [トラブルシューティング](./docs/guides/troubleshooting.md) |
285
286
  | 設計を知りたい | [アーキテクチャ詳細](./docs/concepts/architecture.md) |
286
287
  | 全リリース履歴 | [CHANGELOG](./CHANGELOG.md) |
@@ -307,7 +308,7 @@ English: [Quickstart](./docs/start/quickstart.en.md) · [Usage guide](./docs/gui
307
308
  ## 技術スペック
308
309
 
309
310
  - **ランタイム依存**: `fastapi` / `uvicorn` / `httpx` / `pydantic` / `pyyaml` の 5 個のみ
310
- - **テスト**: 964 (41 sub-release 連続で依存追加なし)
311
+ - **テスト**: 1,500+ 本(ランタイム依存 5 個は v1 系から不変)
311
312
  - **対応 OS**: macOS (Apple Silicon 推奨) / Linux / Windows WSL2
312
313
  - **対応 backend**: Ollama / llama.cpp / LM Studio / vLLM / MLX-LM / OpenRouter / NVIDIA NIM / Anthropic API
313
314
  - **ライセンス**: MIT
@@ -1,6 +1,6 @@
1
1
  coderouter/__init__.py,sha256=ghdjPrLtnRzY8fyQ4CJZI1UJKADyNTLtA3G7se8H7Ns,696
2
2
  coderouter/__main__.py,sha256=-LCgxJnvgUV240HjQKv7ly-mn2NuKHpC4nCpvTHjeSU,130
3
- coderouter/cli.py,sha256=KE49IACJVw692H6dlfu1tAah1jQgbwH92F4lCkhRk6U,28168
3
+ coderouter/cli.py,sha256=7zxt6riKPTpHGiDms9SVaPbe-n4ytfCrhIVtuPII-oU,30173
4
4
  coderouter/cli_stats.py,sha256=CCjzc1G4hTRHZ2gG1XhxhDpUkJnnl3NXbcbp1T18jpg,29894
5
5
  coderouter/cost.py,sha256=32h6uzb4nxh2eA5d2Hn3kD9yJbtis6CFDAbeIy5KRkM,7431
6
6
  coderouter/doctor.py,sha256=2luNk6BHSRvpQStJnHcqzNvNi-SKdOuKV0WZdorZhVk,82854
@@ -67,8 +67,8 @@ coderouter/translation/__init__.py,sha256=PYXN7XVEwpG1uC8RLy6fvnGbzEZhhrEuUapH8I
67
67
  coderouter/translation/anthropic.py,sha256=aZkcYH4x82b0x7efJgJb9RWn9Hbyc9pEOthXe4vjUdU,11113
68
68
  coderouter/translation/convert.py,sha256=VV4kpu4dvLmGBmJfQnCLY5ryy_AnQcV2NuwjqRtaR8Q,52633
69
69
  coderouter/translation/tool_repair.py,sha256=DGOKArM53yfVbIfiAveoul1vGq9NEKmjagf43Qh4IkM,57630
70
- coderouter_cli-2.7.4.dist-info/METADATA,sha256=55ucKwRohGC6WEQr_NyGWjRjzhVgE7rOYgl4rfDNNkw,15388
71
- coderouter_cli-2.7.4.dist-info/WHEEL,sha256=mffPy8wBnZQn2VnJUU5jE99KsxaSfiyMHV9Yt0aLVxs,87
72
- coderouter_cli-2.7.4.dist-info/entry_points.txt,sha256=-dnLfD1YZ2WjH2zSdNCvlO65wYltM9bsHt9Fhg3yGss,51
73
- coderouter_cli-2.7.4.dist-info/licenses/LICENSE,sha256=wkEzoR86jFw33jvfOHjULqmkGEfxTFMgMaJnpR8mPRw,1065
74
- coderouter_cli-2.7.4.dist-info/RECORD,,
70
+ coderouter_cli-2.7.5.dist-info/METADATA,sha256=VsPe8Z7VLlfIRAm5OHEP8VP-gE6CZmWcQFDqWlxiXIE,15546
71
+ coderouter_cli-2.7.5.dist-info/WHEEL,sha256=mffPy8wBnZQn2VnJUU5jE99KsxaSfiyMHV9Yt0aLVxs,87
72
+ coderouter_cli-2.7.5.dist-info/entry_points.txt,sha256=-dnLfD1YZ2WjH2zSdNCvlO65wYltM9bsHt9Fhg3yGss,51
73
+ coderouter_cli-2.7.5.dist-info/licenses/LICENSE,sha256=wkEzoR86jFw33jvfOHjULqmkGEfxTFMgMaJnpR8mPRw,1065
74
+ coderouter_cli-2.7.5.dist-info/RECORD,,