coderouter-cli 2.15.0__py3-none-any.whl → 2.15.1__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/doctor.py +48 -1
- {coderouter_cli-2.15.0.dist-info → coderouter_cli-2.15.1.dist-info}/METADATA +16 -4
- {coderouter_cli-2.15.0.dist-info → coderouter_cli-2.15.1.dist-info}/RECORD +6 -6
- {coderouter_cli-2.15.0.dist-info → coderouter_cli-2.15.1.dist-info}/WHEEL +1 -1
- {coderouter_cli-2.15.0.dist-info → coderouter_cli-2.15.1.dist-info}/entry_points.txt +0 -0
- {coderouter_cli-2.15.0.dist-info → coderouter_cli-2.15.1.dist-info}/licenses/LICENSE +0 -0
coderouter/doctor.py
CHANGED
|
@@ -635,6 +635,49 @@ _PROBE_TOOL_SPEC_ANTHROPIC = {
|
|
|
635
635
|
}
|
|
636
636
|
|
|
637
637
|
|
|
638
|
+
# v2.15.1: llama.cpp changed ``llama-server``'s default listen port from
|
|
639
|
+
# 8080 to 9931 (ggml-org/llama.cpp#30159, build b11521, 2026-10-09). A server
|
|
640
|
+
# started without ``--port`` on a new build is invisible to a provider that
|
|
641
|
+
# still points at :8080, and the reverse holds for configs written against
|
|
642
|
+
# the new default. When the basic probe cannot connect to one of those two
|
|
643
|
+
# ports on a loopback host, check the other one so the transport error can
|
|
644
|
+
# name the likely cause instead of looking like "server not running".
|
|
645
|
+
_LLAMACPP_PORT_PAIR: dict[int, int] = {8080: 9931, 9931: 8080}
|
|
646
|
+
_LOOPBACK_HOSTS = frozenset({"localhost", "127.0.0.1", "::1"})
|
|
647
|
+
|
|
648
|
+
|
|
649
|
+
async def _llamacpp_port_hint(base_url: object) -> str | None:
|
|
650
|
+
"""Return a hint when the other llama.cpp default port answers.
|
|
651
|
+
|
|
652
|
+
Only fires for loopback hosts on port 8080 or 9931. The alternate
|
|
653
|
+
port is probed at ``GET /health`` (llama-server's readiness route)
|
|
654
|
+
with a short timeout on the IPv4 literal — ``localhost`` can resolve
|
|
655
|
+
to ``::1`` first on macOS, where llama-server is not listening. The
|
|
656
|
+
config is never rewritten; the operator decides.
|
|
657
|
+
"""
|
|
658
|
+
try:
|
|
659
|
+
parsed = httpx.URL(str(base_url))
|
|
660
|
+
except (httpx.InvalidURL, TypeError):
|
|
661
|
+
return None
|
|
662
|
+
if parsed.host not in _LOOPBACK_HOSTS or parsed.port not in _LLAMACPP_PORT_PAIR:
|
|
663
|
+
return None
|
|
664
|
+
other = _LLAMACPP_PORT_PAIR[parsed.port]
|
|
665
|
+
try:
|
|
666
|
+
async with httpx.AsyncClient(timeout=1.5) as client:
|
|
667
|
+
resp = await client.get(f"http://127.0.0.1:{other}/health")
|
|
668
|
+
except httpx.HTTPError:
|
|
669
|
+
return None
|
|
670
|
+
if resp.status_code >= 500:
|
|
671
|
+
return None
|
|
672
|
+
return (
|
|
673
|
+
f"Something is answering on port {other} instead. llama.cpp "
|
|
674
|
+
f"builds b11521+ listen on 9931 when started without --port "
|
|
675
|
+
f"(older builds: 8080). Either start llama-server with "
|
|
676
|
+
f"--port {parsed.port}, or change this provider's base_url to "
|
|
677
|
+
f"port {other}"
|
|
678
|
+
)
|
|
679
|
+
|
|
680
|
+
|
|
638
681
|
async def _probe_auth_and_basic_chat(
|
|
639
682
|
provider: ProviderConfig,
|
|
640
683
|
) -> ProbeResult:
|
|
@@ -670,10 +713,14 @@ async def _probe_auth_and_basic_chat(
|
|
|
670
713
|
)
|
|
671
714
|
|
|
672
715
|
if status is None:
|
|
716
|
+
detail = f"could not reach {url}: {raw}"
|
|
717
|
+
hint = await _llamacpp_port_hint(provider.base_url)
|
|
718
|
+
if hint:
|
|
719
|
+
detail = f"{detail}. {hint}"
|
|
673
720
|
return ProbeResult(
|
|
674
721
|
name="auth+basic-chat",
|
|
675
722
|
verdict=ProbeVerdict.TRANSPORT_ERROR,
|
|
676
|
-
detail=
|
|
723
|
+
detail=detail,
|
|
677
724
|
)
|
|
678
725
|
|
|
679
726
|
if status in (401, 403):
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: coderouter-cli
|
|
3
|
-
Version: 2.15.
|
|
3
|
+
Version: 2.15.1
|
|
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
|
|
@@ -66,7 +66,7 @@ Description-Content-Type: text/markdown
|
|
|
66
66
|
## 何ができるか — 30 秒で
|
|
67
67
|
|
|
68
68
|
```
|
|
69
|
-
あなたのエージェント (Claude Code /
|
|
69
|
+
あなたのエージェント (Claude Code / agy ほか ※)
|
|
70
70
|
│
|
|
71
71
|
▼
|
|
72
72
|
┌─ CodeRouter ─┐
|
|
@@ -76,6 +76,8 @@ Description-Content-Type: text/markdown
|
|
|
76
76
|
└──────────────┘
|
|
77
77
|
```
|
|
78
78
|
|
|
79
|
+
※ 現行の codex CLI は Responses API(`/v1/responses`)専用になったため、CodeRouter 経由ではまだ使えません(対応予定)。直結の代替手順 → [quickstart Pattern B](./docs/start/quickstart.md#pattern-b-codex-cli-で使う)
|
|
80
|
+
|
|
79
81
|
**やってくれること:**
|
|
80
82
|
|
|
81
83
|
- ローカルモデルが壊した tool calling を Claude Code に届く前に修復する
|
|
@@ -118,6 +120,8 @@ uvx --from coderouter-cli coderouter serve --port 8088
|
|
|
118
120
|
|
|
119
121
|
恒久インストールしたい場合: `uv tool install coderouter-cli`
|
|
120
122
|
|
|
123
|
+
> **パッケージ名に注意**: PyPI のパッケージ名は **`coderouter-cli`** です。PyPI の `coderouter`(名前だけ同じ)は別の製品なので、`pip install coderouter` と打たないでください。
|
|
124
|
+
|
|
121
125
|
---
|
|
122
126
|
|
|
123
127
|
## Claude Code で使う
|
|
@@ -143,7 +147,7 @@ ANTHROPIC_BASE_URL=http://localhost:8088 ANTHROPIC_AUTH_TOKEN=dummy claude
|
|
|
143
147
|
| Claude Code + ローカル Ollama で tool calling が壊れる | **必須** — tool 修復 (+ 必要なら wire 変換) |
|
|
144
148
|
| Claude Code + ローカルで長時間回すと止まる | **必須級** — 6 系統ガード + self-healing |
|
|
145
149
|
| Ollama v0.14+ / LM Studio にネイティブ直結で動いてる | **便利** — 直結に無い fallback / ガード / 診断を追加 (passthrough で翻訳ゼロ) |
|
|
146
|
-
| codex / agy + Ollama 直繋ぎで動いてる | オプション — フォールバックが欲しいなら |
|
|
150
|
+
| codex / agy + Ollama 直繋ぎで動いてる | オプション — フォールバックが欲しいなら(codex は `/v1/responses` 対応後) |
|
|
147
151
|
| Claude API を直接叩いてて問題ない | 不要 |
|
|
148
152
|
|
|
149
153
|
詳細は → [要否判定ガイド](./docs/start/when-do-i-need-coderouter.md)
|
|
@@ -156,7 +160,7 @@ ANTHROPIC_BASE_URL=http://localhost:8088 ANTHROPIC_AUTH_TOKEN=dummy claude
|
|
|
156
160
|
|
|
157
161
|
| 機能 | 何をしてくれるか |
|
|
158
162
|
|---|---|
|
|
159
|
-
| **Tool-call 修復** | ローカルモデルがテキストで吐いた JSON を正しい tool_use
|
|
163
|
+
| **Tool-call 修復** | ローカルモデルがテキストで吐いた JSON を正しい tool_use ブロックに復元。実測は [修復ベンチ](./benchmarks/tool-repair/README.md)(壊れた tool call を出す 4 モデルで成功率 0% → 80〜100%、回帰コーパスで誤修復 0 件。CI でゲート) |
|
|
160
164
|
| **3 層フォールバック** | ローカル → 無料クラウド → 有料の順に自動切替 |
|
|
161
165
|
| **出力フィルタ** | `<think>` タグ漏れ、stop marker 漏れ、byte-fallback (`<0xNN>`) を自動除去/修復 |
|
|
162
166
|
| **Wire 翻訳** | Anthropic 形式 ↔ OpenAI 形式を自動変換 (ネイティブ `/v1/messages` 対応 backend は passthrough で翻訳ゼロ) |
|
|
@@ -333,6 +337,14 @@ CodeRouter は backend ルーター層として独立して動きます。`OPENA
|
|
|
333
337
|
|
|
334
338
|
シークレットは環境変数に置きます。[`docs/security.md`](./docs/guides/security.md) に完全な方針と報告手順があります。
|
|
335
339
|
|
|
340
|
+
リリースは多層で守っています。どれか 1 つを根拠に「安全」とは言いません(正規のパイプラインでビルドされた汚染版が出た例があります)。
|
|
341
|
+
|
|
342
|
+
- PyPI へは Trusted Publishing(OIDC)で公開し、長期の API トークンを置かない
|
|
343
|
+
- PyPI 側の公開許可は `release.yml` の `pypi` 環境に限定している
|
|
344
|
+
- タグは事前検査スクリプトを通してから打つ(version・CHANGELOG・main の一致を機械的に確認)
|
|
345
|
+
- 実行時の依存は 5 個に絞っている
|
|
346
|
+
- 各リリースに SBOM(CycloneDX)を添付する
|
|
347
|
+
|
|
336
348
|
## License
|
|
337
349
|
|
|
338
350
|
MIT
|
|
@@ -4,7 +4,7 @@ coderouter/cli.py,sha256=Nbx1ur_HnssFtuM48yPELwhY40veVNnTAfK7OVF2uVc,42400
|
|
|
4
4
|
coderouter/cli_stats.py,sha256=CCjzc1G4hTRHZ2gG1XhxhDpUkJnnl3NXbcbp1T18jpg,29894
|
|
5
5
|
coderouter/cost.py,sha256=32h6uzb4nxh2eA5d2Hn3kD9yJbtis6CFDAbeIy5KRkM,7431
|
|
6
6
|
coderouter/credentials.py,sha256=R_PdrcA941_jJX_U8hxrjPDTCVVzLd4dsw2c00KwAwE,12991
|
|
7
|
-
coderouter/doctor.py,sha256=
|
|
7
|
+
coderouter/doctor.py,sha256=0EUqKaEw2GaqX6zGKjR-bVDdlmBznFIklSz3yIoQbE0,91969
|
|
8
8
|
coderouter/doctor_apply.py,sha256=tZT3bEd1G6t67YRhf1TGY4NlSvZuJJbnEqN-3AKy8Hc,29972
|
|
9
9
|
coderouter/env_security.py,sha256=FEBZnXfJ0xE39kmMMn39zk0W_DRRnmcB_REmP9f4xWo,14796
|
|
10
10
|
coderouter/errors.py,sha256=Xmq67lheyw8iv3Ox39jh2c4tvNI5RcUR4QkoxVDN6l4,1130
|
|
@@ -77,8 +77,8 @@ coderouter/translation/anthropic.py,sha256=ZQQGS9itN_3o7IKD68lKr5gR_Kem32Jsd7OcG
|
|
|
77
77
|
coderouter/translation/convert.py,sha256=VrstDAMsUpcQ1VgMTn_-ETp1OjGX8v0ZGhCkcd4icyU,53037
|
|
78
78
|
coderouter/translation/tool_repair.py,sha256=1p8rmdyyscGX2g0DDOYitMnLv-nKfR1SLuLaRB4z7GM,64244
|
|
79
79
|
coderouter/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
80
|
-
coderouter_cli-2.15.
|
|
81
|
-
coderouter_cli-2.15.
|
|
82
|
-
coderouter_cli-2.15.
|
|
83
|
-
coderouter_cli-2.15.
|
|
84
|
-
coderouter_cli-2.15.
|
|
80
|
+
coderouter_cli-2.15.1.dist-info/METADATA,sha256=oJXnZHAWbbgbFy7wWTJW4LxBTHkA0NSDMWubhzUqo_0,18221
|
|
81
|
+
coderouter_cli-2.15.1.dist-info/WHEEL,sha256=W3fkpkm7-wf9vBI5Z-7s0eWkeM-spu78I8Neb98DeEg,87
|
|
82
|
+
coderouter_cli-2.15.1.dist-info/entry_points.txt,sha256=-dnLfD1YZ2WjH2zSdNCvlO65wYltM9bsHt9Fhg3yGss,51
|
|
83
|
+
coderouter_cli-2.15.1.dist-info/licenses/LICENSE,sha256=wkEzoR86jFw33jvfOHjULqmkGEfxTFMgMaJnpR8mPRw,1065
|
|
84
|
+
coderouter_cli-2.15.1.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|