coderouter-cli 2.1.0__py3-none-any.whl → 2.2.0__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.
@@ -1,560 +0,0 @@
1
- Metadata-Version: 2.4
2
- Name: coderouter-cli
3
- Version: 2.1.0
4
- Summary: Local-first, free-first, fallback-built-in LLM router. Claude Code / OpenAI compatible.
5
- Project-URL: Homepage, https://github.com/zephel01/CodeRouter
6
- Project-URL: Repository, https://github.com/zephel01/CodeRouter
7
- Project-URL: Issues, https://github.com/zephel01/CodeRouter/issues
8
- Project-URL: Changelog, https://github.com/zephel01/CodeRouter/blob/main/CHANGELOG.md
9
- Project-URL: Documentation, https://github.com/zephel01/CodeRouter#documentation
10
- Author-email: zephel01 <zephel01@gmail.com>
11
- License: MIT
12
- License-File: LICENSE
13
- Keywords: claude,claude-code,fallback,llm,local-first,nvidia-nim,ollama,openai,openrouter,router
14
- Classifier: Development Status :: 5 - Production/Stable
15
- Classifier: License :: OSI Approved :: MIT License
16
- Classifier: Operating System :: MacOS
17
- Classifier: Operating System :: POSIX :: Linux
18
- Classifier: Programming Language :: Python :: 3.12
19
- Classifier: Programming Language :: Python :: 3.13
20
- Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
21
- Classifier: Topic :: Software Development :: Libraries :: Python Modules
22
- Classifier: Topic :: System :: Networking
23
- Classifier: Typing :: Typed
24
- Requires-Python: >=3.12
25
- Requires-Dist: fastapi>=0.115.0
26
- Requires-Dist: httpx>=0.27.0
27
- Requires-Dist: pydantic>=2.9.0
28
- Requires-Dist: pyyaml>=6.0.2
29
- Requires-Dist: uvicorn[standard]>=0.32.0
30
- Provides-Extra: dev
31
- Requires-Dist: mypy>=1.13.0; extra == 'dev'
32
- Requires-Dist: pytest-asyncio>=0.24.0; extra == 'dev'
33
- Requires-Dist: pytest-httpx>=0.32.0; extra == 'dev'
34
- Requires-Dist: pytest>=8.3.0; extra == 'dev'
35
- Requires-Dist: ruamel-yaml>=0.18.6; extra == 'dev'
36
- Requires-Dist: ruff>=0.7.0; extra == 'dev'
37
- Requires-Dist: types-pyyaml>=6.0.12; extra == 'dev'
38
- Provides-Extra: doctor
39
- Requires-Dist: ruamel-yaml>=0.18.6; extra == 'doctor'
40
- Description-Content-Type: text/markdown
41
-
42
- <h1 align="center">CodeRouter</h1>
43
-
44
- <p align="center">
45
- <strong>Claude Code でローカル LLM を使うと tool calling が壊れる問題、<br>ルーター側で直します。</strong>
46
- </p>
47
-
48
- <p align="center">
49
- qwen2.5-coder:7B、phi-4、mistral-nemo など小型・量子化モデルがしばしばやる<br>
50
- <strong>「<code>{"name":..., "arguments":...}</code> を plain text として吐いてしまう」</strong>現象を、<br>
51
- CodeRouter の <strong>tool-call 修復パス</strong>が Claude Code に届く前に<br>
52
- 有効な <code>tool_use</code> ブロックへ復元します。
53
- </p>
54
-
55
- <p align="center">
56
- <strong>「ローカル LLM にしたら agentic coding ができない」と諦めていた人へ。</strong><br>
57
- これで本気で使える local-first agent が組めます。
58
- </p>
59
-
60
- <p align="center">
61
- <a href="https://github.com/zephel01/CodeRouter/actions/workflows/ci.yml"><img src="https://github.com/zephel01/CodeRouter/actions/workflows/ci.yml/badge.svg?branch=main" alt="CI"></a>
62
- <a href=""><img src="https://img.shields.io/badge/status-stable-brightgreen" alt="status"></a>
63
- <a href=""><img src="https://img.shields.io/badge/version-2.1.0-blue" alt="version"></a>
64
- <a href=""><img src="https://img.shields.io/badge/python-3.12%2B-blue" alt="python"></a>
65
- <a href=""><img src="https://img.shields.io/badge/runtime%20deps-5-brightgreen" alt="deps"></a>
66
- <a href=""><img src="https://img.shields.io/badge/license-MIT-yellow" alt="license"></a>
67
- </p>
68
-
69
- <p align="center">
70
- <a href="./README.en.md">English</a> · <strong>日本語</strong> · <a href="./docs/usage-guide.md">利用ガイド</a> · <a href="./docs/security.md">Security</a>
71
- </p>
72
-
73
- <p align="center">
74
- <strong>10 分で動かす →</strong> <a href="./docs/quickstart.md">Quickstart</a>
75
- | <strong>詳しく →</strong> <a href="./docs/usage-guide.md">利用ガイド</a>
76
- | <strong>無料で回す →</strong> <a href="./docs/free-tier-guide.md">無料枠ガイド</a>
77
- | <strong>要るか判定 →</strong> <a href="./docs/when-do-i-need-coderouter.md">要否判定</a>
78
- </p>
79
-
80
- <!-- TODO: before/after GIF を docs/assets/before-after-toolcall.gif に配置予定。
81
- 暫定で ダッシュボードのスクショ だけリンク。 -->
82
- <!-- ![Before / After tool calling demo](./docs/assets/before-after-toolcall.gif) -->
83
-
84
- **CodeRouter が他に何をやってくれるか**
85
-
86
- - `coderouter doctor --check-model <provider>` でそのモデルが tool call / streaming / thinking に対応しているかを**実プローブで即診断**し、足りない宣言をコピペ可能な YAML パッチで教えてくれる
87
- - reasoning leak(`<think>...</think>` タグや `<|turn|>` など 6 種の stop マーカー漏れ)を SSE チャンク境界を跨いで自動スクラブ
88
- - ローカル → 無料クラウド(OpenRouter free / NVIDIA NIM 40 req/min 無料枠)→ 有料 API の自動フォールバック。既定で `ALLOW_PAID=false` なので課金はオプトイン制
89
- - v1.9.0 から **Anthropic prompt cache の hit/miss を全リクエストで記録**、`/dashboard` で hit_rate / saved tokens / USD コストが見える(cache savings は別計算)
90
- - v1.9.0 から **adaptive routing** で「いま遅い provider」を自動降格(profile に `adaptive: true` を付けるだけ)、**tool-loop guard** で stuck loop を検出(`warn` / `inject` / `break` の 3 段階 policy)
91
- - **v1.10.0 で Long-run reliability pillar が完成**: `cost.monthly_budget_usd` で provider 月次 USD 予算を強制、**L2 memory pressure detector**(Ollama / LM Studio が VRAM 切れで OOM になった時に自動クールダウン)、**L5 backend health 状態機械**(連続失敗で UNHEALTHY → chain 末尾に降格、1 回成功で即復帰)
92
- - **v1.10.0 で auto-router が 6 matcher に揃う**: `has_image` / `code_fence_ratio_min` / `content_contains` / `content_regex` / `model_pattern`(Opus/Sonnet/Haiku 分岐)/ `content_token_count_min`(長文 → 1M ctx Gemini Flash 等へ自動切替)
93
- - **v2.0.0 で Context Budget Management (L1 overflow 防止) を搭載**: 長時間 agent session で messages が context window に漸近 → backend 400 エラーで session 死亡する問題を根本解決。warn (80%) → auto trim (90%) の 2 段階 guard で **context overflow ゼロ**を実現。tool_use / tool_result ペアは atomic 保全、`X-CodeRouter-Context-Budget` ヘッダで状態通知、Prometheus メトリクス完備
94
- - **v2.1.0 で Long-run Reliability 3 機能を追加搭載**: **Drift Detection** (L4 品質劣化検知 — 5 シグナル rolling window + warn/promote/reload 3 段階アクション)、**Partial Stitching** (L6 mid-stream 失敗時の蓄積テキスト返却)、**Continuous Probing** (P3 idle 時 1-token 定期 probe + model drift 検知 + backend health 自動更新)
95
- - ランタイム依存 5 個(`fastapi` / `uvicorn` / `httpx` / `pydantic` / `pyyaml`)— 純 Python、MIT、テスト 950 本緑
96
-
97
- → **Claude Code / gemini-cli / codex + Ollama / llama.cpp / NVIDIA NIM で、破綻しない local-first agent が組める**
98
-
99
- ## ドキュメント
100
-
101
- | 目的 | ドキュメント | 内容 |
102
- |---|---|---|
103
- | **動かす** | [Quickstart](./docs/quickstart.md) | Claude Code / codex を local Ollama で 10〜15 分で動かす最短手順 |
104
- | **使いこなす** | [利用ガイド](./docs/usage-guide.md) | HW 別モデル選定・チューニング既定値・OS ごとの起動フロー・`doctor` / `verify` の読み方 |
105
- | **無料で回す** | [無料枠ガイド](./docs/free-tier-guide.md) | NVIDIA NIM 40 req/min × OpenRouter 無料枠の使い分け・live 検証済みモデル表・地雷 5 点 |
106
- | **要るか判断する** | [要否判定ガイド](./docs/when-do-i-need-coderouter.md) | エージェント × モデルの詳細マトリクスで「そもそも自分に必要か」を決める |
107
- | **長時間 session** | [Context Budget](./docs/context-budget.md) | v2.0.0 新機能。長時間 agent session の context overflow を自動防止する guard の設定・仕組み・可観測性 |
108
- | **詰まったとき** | [トラブルシューティング](./docs/troubleshooting.md) | `doctor` の使い方、`.env` の export 必須、Ollama サイレント失敗 5 症状、Claude Code 連携の罠 |
109
- | **llama.cpp 直叩き** | [llama.cpp 直叩きガイド](./docs/llamacpp-direct.md) | Qwen3.6 を Ollama 詰みから救出する経路。`llama.cpp` build → Unsloth GGUF → `llama-server` → CodeRouter 接続を 7 step で(v1.8.3 実機検証済)|
110
- | **LM Studio 直接** | [LM Studio 直接ガイド](./docs/lmstudio-direct.md) | `qwen35` / `qwen35moe` を救う第 2 経路。LM Studio 0.4.12+ Local Server 経由で OpenAI 互換 + Anthropic 互換 (`/v1/messages`) 両対応、prompt caching 透過(v1.8.4 実機検証済)|
111
- | **安全に使う** | [セキュリティ方針](./docs/security.md) | 脅威モデル・秘密情報の扱い・脆弱性報告経路 |
112
- | **履歴** | [CHANGELOG](./CHANGELOG.md) | 全リリース履歴(最新: v2.0.0 — Context Budget Management (L1 overflow 防止) で長時間 agent session の安定性を根本改善) |
113
- | **設計を追う** | [plan.md](./plan.md) | 設計不変項・マイルストーン・今後のロードマップ |
114
-
115
- English versions: [Quickstart](./docs/quickstart.en.md) · [Usage guide](./docs/usage-guide.en.md) · [Free-tier guide](./docs/free-tier-guide.en.md) · [When you need it](./docs/when-do-i-need-coderouter.en.md) · [Troubleshooting](./docs/troubleshooting.en.md) · [llama.cpp direct](./docs/llamacpp-direct.en.md) · [LM Studio direct](./docs/lmstudio-direct.en.md) · [Security](./docs/security.en.md)
116
-
117
- ## CodeRouter で何が楽になるか
118
-
119
- CodeRouter は、コーディングエージェント(Claude Code / gemini-cli / codex / 素の OpenAI SDK)と、その裏の LLM の間に挟まる小さなルーターです。ツールの向き先を 1 本のエンドポイントにまとめておけば、CodeRouter がプロバイダを順に選びます — まずローカル Ollama / llama.cpp、次に無料クラウド (OpenRouter free)、有料 API は明示的に opt-in したときだけ。
120
-
121
- 初心者が普通に使うとぶつかる「地雷」を、CodeRouter がまとめて面倒見てくれます:
122
-
123
- - **API キー無し・Anthropic 課金無しのまま Claude Code を回せる。** ローカルモデル(または OpenRouter 無料枠)が答えます。有料プロバイダは `ALLOW_PAID=true` を明示したときだけ呼ばれます。
124
- - **返答が途中で消えない。** 1 プロバイダが途中で落ちてもクライアントには綺麗な `event: error` が 1 本届くだけ — 2 モデルを継ぎ接ぎしたフランケン応答にはなりません。
125
- - **うっかり課金しない。** `ALLOW_PAID=false` が既定。有料プロバイダをチェーンから外したときは理由を 1 行ログに出すので、なぜ使われなかったかが後で grep できます。
126
- - **ローカル Ollama の上で Claude Code / gemini-cli / codex が動く。** Claude Code は Anthropic のワイアフォーマット、Ollama / llama.cpp / LM Studio は OpenAI。CodeRouter が双方向に変換し、小さいローカルモデルがテキストで吐いてしまう `{"name":..., "arguments":...}` を tool_use ブロックへ復元してからエージェントに渡します。
127
- - **「なぜか動かない」の原因を教えてくれる。** `coderouter doctor --check-model <provider>` が 6 種類の典型的な失敗モード(コンテキスト切り詰め / ストリーム早期終了 / ツール呼び出し欠落 / reasoning フィールド漏れ / 認証 / Anthropic `thinking`)を実地プローブし、コピペ可能な YAML パッチを出します。
128
- - **監査しやすい。** ランタイム依存 5 個(LiteLLM は 100+)。Pure Python、MIT、テスト 930 本緑。
129
-
130
- ```
131
- クライアント (Claude Code / OpenAI SDK / gemini-cli / codex / curl)
132
-
133
-
134
- CodeRouter ──► ① ローカルモデル (Ollama / llama.cpp — 無料・最優先)
135
- ② 無料クラウド (OpenRouter qwen3-coder:free, gpt-oss-120b:free, …)
136
- ③ 有料クラウド (Claude / GPT — ALLOW_PAID=true のときだけ)
137
- ```
138
-
139
- ### ライブダッシュボード
140
-
141
- `coderouter dashboard` は、障害調査中に実際に知りたい「いま何が起きているか」に、ログを grep せずに即答するための画面です:
142
-
143
- - どのプロバイダが生きていて、いま応答しているのは誰か
144
- - フォールバックは直近で発火したか、発火したなら何が理由か
145
- - 有料ゲートは閉じたままか(= まだ無料経路で走っているか)
146
- - 直近数分のリクエスト流量はどうか
147
- - ついさっき何が起きたか — 直近 N 件のイベントが時系列で
148
-
149
- ![CodeRouter ダッシュボード — プロバイダ状態 / フォールバック & ゲート / requests/min スパークライン / 直近イベント / usage mix](./docs/assets/dashboard-demo.png)
150
-
151
- 上のスクリーンショットは `scripts/demo_traffic.sh` で混合トラフィック(normal / stream / burst / fallback / paid-gate)をローカルのモックに流している最中のものです。左上から: プロバイダ状態、フォールバック & ゲート状態、requests/min スパークライン、直近イベント(新しい順)、usage mix。
152
-
153
- ## CodeRouter は自分に必要か?
154
-
155
- CodeRouter は wire 翻訳 + 絆創膏の層です。エージェントが既に OpenAI を喋り、モデルがお行儀良く動くなら、多くの場合不要です。下の 2 つの表が短縮版で、フルの判断ガイドは [`docs/when-do-i-need-coderouter.md`](./docs/when-do-i-need-coderouter.md) にあります。
156
-
157
- **エージェント別** — Ollama に直接向けられるか:
158
-
159
- | エージェント | wire | Ollama 直続き | CodeRouter 必要? |
160
- |---|---|---|---|
161
- | Claude Code | Anthropic | ✕ | **必須** — wire 翻訳 |
162
- | Codex CLI / 素の OpenAI SDK | OpenAI | ◯(`OPENAI_BASE_URL`) | オプション |
163
- | gemini-cli | Gemini | ✕ | 必要(アダプタ) |
164
- | GitHub Copilot CLI | GitHub 独自 | **✕(バックエンド固定)** | 無力 — 差し替え不可 |
165
-
166
- **モデル別** — 直続きで崩れるか:
167
-
168
- | モデル | 出力綺麗? | 効く CodeRouter フィルタ |
169
- |---|---|---|
170
- | `llama3.1` / `mistral-nemo` / `phi-4` / `qwen2.5`(`-coder` でない) | ◯ | — |
171
- | `qwen2.5-coder` | ✕ — `<think>` 漏れ | `strip_thinking` |
172
- | `gpt-oss` / `deepseek-r1` / `qwq` | ✕ — 推論過程漏れ | `strip_thinking` |
173
- | 小さい量子化(Q2 / Q3)、テンプレ不整合 Modelfile | ✕ — tool JSON 壊れ / stop marker 漏れ | `repair_tool_call` / `strip_stop_markers` |
174
-
175
- OpenAI 互換エージェント + お行儀の良いモデル + フォールバック不要、の構成なら `OPENAI_BASE_URL=http://localhost:11434/v1` の一行で済みます。それ以外 — 特に Claude Code、reasoning 系モデル、mid-stream ガード付きの多段フォールバック — が CodeRouter の仕事どころです。
176
-
177
- ## 直接つなげばいいのでは?
178
-
179
- - **Ollama / llama.cpp / LM Studio を直接叩く。** 確かに速くて無料ですが、Claude Code(および `/v1/messages` を前提にした多くのエージェント)は Anthropic 形式で話します — 上記サーバは OpenAI 形式だけ。結果、"unsupported endpoint" で弾かれるか、モデルが tool 呼び出しを素のテキストで吐いて tool-use が静かに壊れるかのどちらかです。CodeRouter は双方向に変換し、エージェントに渡る前に JSON を修復します。
180
- - **LiteLLM。** 良いプロダクトですが依存が重く(推移的依存 100+)、`/v1/messages` をネイティブに出しません。
181
- - **OpenRouter 単独。** 無料枠はレート制限があり、たまに落ちます。有料オンリーは新規ユーザーや CI には敷居が高い。
182
-
183
- 設計不変項と今後のロードマップは [`plan.md`](./plan.md) を参照。初心者向けに「同じローカルモデルでも、なぜ人によって動く/動かないが分かれるのか」を解説する記事は Zenn / Note で別途公開しています。
184
-
185
- ## エコシステム
186
-
187
- CodeRouter は **backend ルーター層** として独立して動くため、ローカル LLM を消費する他プロジェクトと組み合わせて使えます。`OPENAI_BASE_URL` (もしくは `OLLAMA_BASE_URL`) を CodeRouter に向けるだけで、相手プロジェクトを無改造で吸収:
188
-
189
- - **[Voice Bridge](https://github.com/zephel01/voice-bridge)** — リアルタイム音声翻訳 + AI 音声チャット (ずんだもん / リリンちゃん対応 + Live2D アバター連携)。chat mode の `OLLAMA_BASE_URL` を CodeRouter に向けると、ローカル LLM が不安定でも openrouter free / anthropic-direct に自動 fallback、**ずんだもんが沈黙しなくなる**。
190
-
191
- ```bash
192
- # 例: Voice Bridge を CodeRouter 経由で動かす
193
- $ coderouter serve --port 8088 --mode coding &
194
- $ export OLLAMA_BASE_URL=http://localhost:8088/v1
195
- $ python main.py --mode chat --vad # voice-bridge 側
196
- ```
197
-
198
- CodeRouter / Voice Bridge ともに独立した repo で進化していて、HTTP 経由で疎結合に繋がります。プラグイン化はせず、それぞれが自分の責務に集中する設計です。
199
-
200
- ## クイックスタート(3 コマンド)
201
-
202
- **v2.1.0 で Long-run Reliability pillar 完成** — Context Budget (L1) + Drift Detection (L4) + Partial Stitching (L6) + Continuous Probing (P3)。`uvx` 一発で動きます (Python 3.12 以上必須):
203
-
204
- ```bash
205
- # 1. サンプル設定を置く
206
- mkdir -p ~/.coderouter
207
- curl -fsSL https://raw.githubusercontent.com/zephel01/CodeRouter/main/examples/providers.yaml \
208
- > ~/.coderouter/providers.yaml
209
-
210
- # 2. uvx で起動 (インストール + 起動が 1 行)
211
- # PyPI 配布名 (coderouter-cli) と console script 名 (coderouter) が異なるため、
212
- # uv 0.11+ では --from 形式が必須 (旧 uv でも動く canonical 形式)
213
- uvx --from coderouter-cli coderouter serve --port 8088
214
- ```
215
-
216
- 恒久的にインストールしておきたい場合:
217
-
218
- ```bash
219
- uv tool install coderouter-cli
220
- coderouter serve --port 8088
221
- ```
222
-
223
- git clone して開発にも参加したい場合 (中級者向け):
224
-
225
- ```bash
226
- git clone https://github.com/zephel01/CodeRouter.git
227
- cd CodeRouter
228
- uv sync
229
- uv run coderouter serve --port 8088
230
- ```
231
-
232
- > **注**: PyPI 上のパッケージ名は `coderouter-cli` ですが、コマンド名と Python import 名は `coderouter` のままです。詳しくは [CHANGELOG `[v1.7.0]`](./CHANGELOG.md#v170--2026-04-25-pypi-公開-uvx-coderouter-cli-一発で動く) 参照。
233
- >
234
- > **`--apply` 自動化を使う場合** (v1.8.0+): `ruamel.yaml` を optional dep として一緒に入れます (`pip install 'coderouter-cli[doctor]'` または `uv pip install ruamel.yaml`)。基本機能には不要です。
235
-
236
- あとは任意の OpenAI クライアントを `http://127.0.0.1:8088` に向けるだけです:
237
-
238
- ```bash
239
- curl http://127.0.0.1:8088/v1/chat/completions \
240
- -H 'Content-Type: application/json' \
241
- -d '{
242
- "model": "ignored",
243
- "messages": [{"role": "user", "content": "Hello"}]
244
- }'
245
- ```
246
-
247
- `model` フィールドは現状プレースホルダです — ルーティングは `profile` フィールド(`providers.yaml` の `default` がデフォルト)で決まります。
248
-
249
- はじめての方は [利用ガイド](./docs/usage-guide.md) を参照してください。ハードウェア別のモデル選定、チューニング既定値、OS ごとの起動フロー、OpenRouter 無料枠とのペア方針を一通り解説しています。(English: [usage guide](./docs/usage-guide.en.md))
250
-
251
- **NVIDIA NIM 無料枠(40 req/min)と OpenRouter 無料枠をどう重ねるか**は [無料枠ガイド](./docs/free-tier-guide.md) にまとめてあります。live 検証済みのモデル一覧、`claude-code-nim` プロファイルの設計意図、よくあるハマり所 5 点 込み。(English: [free-tier guide](./docs/free-tier-guide.en.md))
252
-
253
- **API キーの管理が気になる方** (1Password / direnv + sops / OS Keychain 連携 + `.env` の安全運用) は v1.6.3 で `coderouter serve --env-file` と `coderouter doctor --check-env` を入れています。詳細は [トラブルシューティング §5](./docs/troubleshooting.md#5-env-のセキュリティ運用-v163-追加)。
254
-
255
- ## OS 対応
256
-
257
- CodeRouter 自体は純 Python 3.12+ で、実質的な OS 対応範囲は `min(coderouter, ollama, claude-code)` です。
258
-
259
- | OS | サーバー | ローカル推論 | メモ |
260
- |---|---|---|---|
261
- | macOS — Apple Silicon (M1–M5) | ✅ | ✅ Metal ネイティブ | **主要開発ターゲット** |
262
- | macOS — Intel | ✅ | ⚠️ CPU のみ | 実用はクラウドフォールバックのみ |
263
- | Linux — x86_64 (Ubuntu / Debian / Fedora) | ✅ | ✅ CUDA または CPU | フル対応 |
264
- | Linux — ARM64 (Pi 5 / Graviton) | ✅ | ⚠️ Pi では CPU | クラウド中継プロキシとして使える |
265
- | Windows — WSL2 (Ubuntu) | ✅ | ✅ | **Windows ではこの経路を推奨** |
266
- | Windows — native | ⚠️ 一部 | ✅ CUDA | `scripts/verify_*.sh` は bash 必須 (Git Bash/WSL2) |
267
-
268
- 注意点や「ローカル GPU なし」向けレシピを含むフル版マトリクス: [利用ガイド §1](./docs/usage-guide.md#1-os-互換性)
269
-
270
- ## ステータス — v2.1.0 (2026-05)
271
-
272
- **テスト 950 本通過。ランタイム依存 5 個 (39 sub-release 連続据え置き)。macOS / Linux / Windows WSL2 で動作。** v2.1.0 で **Long-run Reliability pillar が完成** — Context Budget (L1) / Drift Detection (L4) / Partial Stitching (L6) / Continuous Probing (P3) の 4 sub-release を統合出荷。v1.10.0 までに **Long-run Reliability** (L2/L3/L5)、**Cost pillar**、**Auto-router 6 matcher** が完成済み。v1.0 の総まとめは [`docs/retrospectives/v1.0.md`](./docs/retrospectives/v1.0.md)。
273
-
274
- 今日の CodeRouter が届ける価値:
275
-
276
- - **どのクライアントもどのプロバイダに橋渡し。** OpenAI 互換クライアントからのリクエストと Claude Code(`/v1/messages` 経由)両方を受け入れ、ストリーミング/非ストリーミングを問わず、ローカル Ollama / OpenRouter 無料 / Anthropic / それらの混在にルーティングします。
277
- - **部分レスポンスを垂れ流さず安全にフォールバック。** 最初のバイト前にプロバイダが失敗したら次を試す。**最初のバイト以降**に失敗したら、クライアントには綺麗な `event: error` が 1 本届くだけ — 2 つのプロバイダを継ぎ接ぎしたフランケン応答は起きません。
278
- - **明示的にオプトインしたときだけ課金。** `ALLOW_PAID=false`(既定)がチェーンから有料プロバイダを外し、ブロック時は 1 行の明確なログを出します。
279
- - **小さいローカルモデルが壊すものを修復。** Qwen / DeepSeek 系がテキストとして吐いた `{"name":..., "arguments":...}` は、Claude Code に届く前に有効な `tool_use` ブロックへ復元されます。
280
- - **何がおかしいかを教えてくれる。** `coderouter doctor --check-model <provider>` が 6 プローブ(認証 / コンテキスト切り詰め / ストリーム中断 / ツール呼び出し能力 / reasoning フィールド漏れ / Anthropic `thinking` 対応)を回し、宣言と実挙動が食い違えばコピペ可能な YAML パッチを出します。
281
- - **reasoning 漏れをスクラブ。** プロバイダに `output_filters: [strip_thinking, strip_stop_markers]` を付ければ `<think>…</think>` と 6 種の stop マーカー variants が SSE チャンク境界を跨いでも安定して剥がれます。
282
- - **Anthropic ネイティブ機能は Anthropic に届いたら保持。** `cache_control` / `thinking` / `anthropic-beta` ヘッダでゲートされる body フィールドは `kind: anthropic` プロバイダでそのまま通り、OpenAI 形状へ落ちる場合のロッシー変換は(沈黙ではなく)ログで可視化されます。
283
-
284
- **リリース単位の詳細が欲しい?** v0.x と v1.0-A/B/C の各スライス — 何が入り、何本のテストが増え、なぜ必要だったのか — は [CHANGELOG.md](./CHANGELOG.md) に揃っています。設計の不変項と今後のロードマップは [plan.md](./plan.md)。
285
-
286
- **次の予定**(v1.0 は [plan.md §10](./plan.md)、v1.0+ は §18): v1.5 ✅ メトリクス / `/dashboard` / `coderouter stats` TUI / `scripts/demo_traffic.sh`、v1.6 ✅ `auto_router` (task-aware routing) + NVIDIA NIM 無料枠 + トラブルシュートドキュメント分離 + `--env-file` / `doctor --check-env`、v1.7 ✅ PyPI 公開 (`uvx --from coderouter-cli coderouter`)、v1.8 ✅ 用途別 4 プロファイル (multi/coding/general/reasoning) + Gemma 4 / Qwen3.6 / Z.AI (GLM) 登録 + `setup.sh` onboarding ウィザード + `coderouter doctor --check-model --apply` (非破壊 YAML 書き戻し) + `claude_code_suitability` startup チェック + Trusted Publishing 自動化。残り (v1.9 候補) は `coderouter doctor --network` (CI 用) / launcher スクリプト / 起動時アップデートチェック (opt-in)。
287
-
288
- ### Claude Code と一緒に使う
289
-
290
- ```bash
291
- # ターミナル 1: Claude Code 向けにチューニングしたプロファイルで CodeRouter を起動
292
- uv run coderouter serve --port 8088
293
-
294
- # ターミナル 2: Claude Code を CodeRouter に向け、ヘッダでチューニング済みプロファイルを選ぶ
295
- ANTHROPIC_BASE_URL=http://localhost:8088 \
296
- ANTHROPIC_AUTH_TOKEN=dummy \
297
- claude
298
- ```
299
-
300
- `examples/providers.yaml` の `claude-code` プロファイル(7b を先頭、14b を品質フォールバック、14b のタイムアウトを 300s に拡大)を使うには、設定で既定にします:
301
-
302
- ```yaml
303
- # ~/.coderouter/providers.yaml
304
- default_profile: claude-code
305
- ```
306
-
307
- もしくは起動時に `--mode` フラグで選択 (v0.6-A):
308
-
309
- ```bash
310
- uv run coderouter serve --port 8088 --mode claude-code
311
- # 同等: CODEROUTER_MODE=claude-code uv run coderouter serve --port 8088
312
- ```
313
-
314
- `--mode` はこのプロセス限定で YAML の `default_profile` を上書きします。リクエスト単位の上書き (`X-CodeRouter-Profile` ヘッダ、または body の `profile` フィールド) は依然勝つので、`--mode` は「設定ファイルを編集せずに別のチェーンを試したい」ときのつまみです。未知のプロファイル名は初回リクエストではなく起動時 fast-fail です。
315
-
316
- `examples/providers.yaml` 側のプロファイルはこのような形です — そのままコピーし、各 `providers:` エントリの `base_url` / `model` をあなたのローカルスタックに合わせて書き換えてください:
317
-
318
- ```yaml
319
- # ANTHROPIC_BASE_URL=http://localhost:8088 claude 用にチューニング。
320
- # Claude Code は毎ターン全ツール (Bash/Glob/Read/Write/...) を宣言するので、
321
- # ルーターは常に v0.3-D の tool-downgrade 経路を使う。ユーザー体感レイテンシ
322
- # ≒ 上流のトータル応答時間。先頭に最速の tool 対応モデル、2 番手に 14b を品質
323
- # フォールバックに、レート制限脱出に無料クラウド 2 種、最後の砦に Claude。
324
- profiles:
325
- - name: claude-code
326
- providers:
327
- - ollama-qwen-coder-7b # M 系で ~30–60s/ターン、tool 対応
328
- - ollama-qwen-coder-14b # 品質フォールバック (timeout_s: 300)
329
- - openrouter-free # qwen/qwen3-coder:free (262K コンテキスト)
330
- - openrouter-gpt-oss-free # openai/gpt-oss-120b:free (別ベンダー = レート制限脱出)
331
- - openrouter-claude # 有料、ALLOW_PAID=true が必要
332
- ```
333
-
334
- 有料ティアを Anthropic のネイティブ API にしたい場合(Anthropic ingress 経由での `cache_control` / `thinking` ブロック生存が目的なら)、`openrouter-claude` を `anthropic-direct` に差し替えます — `examples/providers.yaml` の `claude-code-direct` プロファイルがまさにそれです。
335
-
336
- #### プロファイル単位のパラメータ上書き (v0.6-B)
337
-
338
- プロファイルはチェーン中の全試行に対し 2 つのパラメータを上書き可能で、同じプロバイダ一覧を別プロファイルで違った挙動にしたいとき(例: 長文 `/no_think` モード vs 短文チャットモード)に便利です:
339
-
340
- ```yaml
341
- profiles:
342
- - name: claude-code-long
343
- timeout_s: 600 # このプロファイルでは ProviderConfig.timeout_s を置換
344
- append_system_prompt: "" # 空文字 = プロバイダ指示を明示的にクリア
345
- providers:
346
- - ollama-qwen-coder-14b
347
- - openrouter-free
348
- ```
349
-
350
- セマンティクス: プロファイル値は設定されていればプロバイダ値を**置き換え**ます(append ではない)。`timeout_s` のようなスカラでの素直な挙動と一致。`append_system_prompt: ""` はこのプロファイル限定でプロバイダ指示を明示消去します(「未設定」= プロバイダ既定にフォールバック、と区別)。未設定フィールドはプロバイダ既定をそのまま残します。`retry_max` はアダプタレイヤのリトライが未実装のため後続マイナーに持ち越し — 現状はフォールバックチェーン自体がリトライ機構です。
351
-
352
- #### Mode エイリアス — `X-CodeRouter-Mode` (v0.6-D)
353
-
354
- 具体プロファイル名ではなく**意図**を表現したいクライアントは `X-CodeRouter-Mode` ヘッダを送れます。CodeRouter は YAML `mode_aliases:` ブロックで解決します:
355
-
356
- ```yaml
357
- # providers.yaml
358
- mode_aliases:
359
- coding: claude-code # クライアントが Mode: coding → プロファイル claude-code
360
- long: claude-code-long
361
- fast: ollama-only
362
- ```
363
-
364
- ```bash
365
- curl http://localhost:8088/v1/chat/completions \
366
- -H 'Content-Type: application/json' \
367
- -H 'X-CodeRouter-Mode: coding' \
368
- -d '{ "messages": [{"role":"user","content":"hi"}] }'
369
- ```
370
-
371
- 優先度(先着勝ち): body `profile` > `X-CodeRouter-Profile` ヘッダ > `X-CodeRouter-Mode` ヘッダ > `default_profile`。Mode が Profile より下なのは **Profile は実装、Mode は意図** であるため — 呼び出し側が具体プロファイルを指定したときはそのまま尊重します。CodeRouter の前段プロキシが Mode を自動付与する構成でも、呼び出し側の明示 body/ヘッダ `profile` が勝つ、これが大事な理由です。
372
-
373
- ガードレール: 壊れたエイリアス対象は起動時 fast-fail(`default_profile` バリデーションと同じ哲学)、未知 Mode は宣言済エイリアス一覧付き 400、解決ごとに `mode-alias-resolved` INFO を出すので運用者はマッピングを後で grep できます。
374
-
375
- #### モデルケイパビリティレジストリ — `model-capabilities.yaml` (v0.7-A)
376
-
377
- 「どの Anthropic ファミリが `thinking: {type: enabled}` を受け付けるか」の知識は、以前は `coderouter/routing/capability.py` 内の正規表現リテラルでした。v0.7-A からは `coderouter/data/model-capabilities.yaml`(パッケージ同梱)に移行し、任意で `~/.coderouter/model-capabilities.yaml` によるユーザー上書きが可能です。Anthropic が新ファミリを出したら YAML 1 行で追加 — コード変更もリリースサイクルも不要。
378
-
379
- ```yaml
380
- # ~/.coderouter/model-capabilities.yaml — 任意のユーザー上書き
381
- version: 1
382
- rules:
383
- # 仮に Anthropic が新ファミリを出し、CodeRouter の同梱既定更新前に使いたい場合。
384
- - match: "claude-sonnet-5-*"
385
- kind: anthropic
386
- capabilities:
387
- thinking: true
388
-
389
- # このタグのローカル Ollama では確実にツール呼び出しできるので宣言。
390
- # v0.7-B doctor の判定と合わせ、将来の glob 消費者からも
391
- # 方針のある既定として参照されるようにする。
392
- - match: "qwen3-coder:*"
393
- kind: openai_compat
394
- capabilities:
395
- tools: true
396
- ```
397
-
398
- スキーマ: 各ルールは `match` (`provider.model` に対する fnmatch glob、大小区別)、任意の `kind` フィルタ (`"anthropic"` / `"openai_compat"` / `"any"`、既定 `"any"`)、`capabilities:` マップ(`thinking` / `reasoning_passthrough` / `tools` / `max_context_tokens` を宣言可能)。ルールは上から順に評価され、**各フラグごとに最初に宣言したルール**が勝ちます。ルールは 1 つのケイパビリティだけ上書きし、他はフォールスルーさせる使い方も可能。
399
-
400
- レイヤ間の優先度は `providers.yaml` `capabilities.*`(プロバイダ単位の明示 opt-in)> ユーザー `model-capabilities.yaml` > 同梱 `model-capabilities.yaml` > 未設定(False 扱い)。ユーザーは常に上書き権限を失いません — `providers.yaml` のプロバイダで明示的に `capabilities.thinking: true` を付ければレジストリに勝つ点は v0.5-A から変わりません。
401
-
402
- タイポはロード時に検出: 未知のトップレベルフィールド、未知のフラグ名、不正な `kind` はいずれも `ValidationError` を上げてサーバーがトラフィックを受け付ける前に停止します。`default_profile` / `mode_aliases` バリデーションと同じ fast-fail 姿勢です。
403
-
404
- #### Doctor — `coderouter doctor --check-model <provider>` (v0.7-B)
405
-
406
- 「Ollama を立ててルーターを向けたけど、どうも何かがおかしい」は最多の onboarding 失敗です。v0.7-B の `doctor` サブコマンドはこれを一行診断に変えます:
407
-
408
- ```bash
409
- coderouter doctor --check-model ollama-qwen-coder-14b
410
- ```
411
-
412
- フォールバックチェーン全体ではなく、**指定したプロバイダ単体**に対し小さな 4 プローブ(各 ≤100 トークン)を走らせ、観測挙動が `providers.yaml` + `model-capabilities.yaml` の現宣言と食い違えば判定表とコピペ可能な YAML パッチを出力します:
413
-
414
- ```
415
- provider: ollama-qwen-coder-14b (kind=openai_compat, model=qwen2.5-coder:14b)
416
-
417
- probe verdict detail
418
- auth+basic-chat OK 200 in 1.4s, 18 tokens in / 6 tokens out
419
- tool_calls NEEDS_TUNING model emitted a tool_use block but registry says tools=false
420
- thinking N/A kind=openai_compat; thinking probe is anthropic-only
421
- reasoning-leak OK no stray `reasoning` field on choice.message
422
-
423
- suggested patch for ~/.coderouter/providers.yaml:
424
- providers:
425
- - name: ollama-qwen-coder-14b
426
- capabilities:
427
- tools: true # observed: model returned a well-formed tool_use block
428
- ```
429
-
430
- 4 プローブとその存在意義:
431
-
432
- - **auth+basic-chat** — 些細な 1 ターン。「API キー未設定」「`base_url` 違い」「プロバイダ到達不能」のクラスを先に捕まえる。失敗した場合、残り 3 プローブは `SKIP` となり症状追いで時間(とトークン)を浪費しない。
433
- - **tool_calls** — ダミー `echo(text: string)` ツール仕様と、それを発火させるはずのプロンプトを送る。意図的に非破壊(上流への副作用なし)。モデルが有効な `tool_use` を吐いたがレジストリが `tools: false` と言っている(あるいは逆)とき `NEEDS_TUNING`。
434
- - **thinking** — Anthropic 限定。`thinking: {type: enabled, budget_tokens: 16}` をネイティブ送出(OpenAI 形状アダプタをバイパス)し、上流がフィールドを受け付けるか確認。ファミリが `model-capabilities.yaml` に未登録ならレジストリパッチ(`providers.yaml` パッチではない)を出す。
435
- - **reasoning-leak** — chat ターンを発行し、v0.5-C strip が走る**前**の上流生ボディを検査。「モデルが `reasoning` を返した」と「アダプタが既に除去済」を区別できる。OpenRouter 無料モデル(`openai/gpt-oss-120b:free` など)で意味がある。
436
-
437
- 終了コード(CI 投入想定で設計):
438
-
439
- | コード | 意味 |
440
- |------|---------|
441
- | `0` | 全プローブが宣言ケイパビリティと一致、パッチ不要 |
442
- | `2` | 1 つ以上の `NEEDS_TUNING`、YAML パッチは出力内 |
443
- | `1` | プローブ実行不能 — auth 失敗、プロバイダ到達不能、または未知プロバイダ名。前提条件を直して再実行 |
444
-
445
- 複数シグナル同時発火時の優先度は `1`(ブロッカ)> `2`(チューニング)> `0`(クリーン)。Unix lint 規約(`2` = 自動修復可、`1` = 諦め)と揃えています。1 プローブの失敗で他が抑制されることはなく、auth 短絡時でもスキップされたプローブは `SKIP: upstream auth failed` と明記して透明性を維持します。
446
-
447
- このサブコマンドは**プロバイダ 1 つ**を対象とする設計です: doctor のプローブが、同ファミリを共有する他プロバイダに波及するレジストリ glob 変更を提案すべきではないからです。チェーン内の各プロバイダについて `--check-model` を変えて再実行してください。
448
-
449
- #### 体感の目安
450
-
451
- - **初バイトレイテンシ**: Claude Code は毎ターン全ツール (Bash/Glob/Read/Write/…) を宣言するので、CodeRouter は常に v0.3-D の tool-downgrade 経路(内部非ストリーミング + SSE リプレイ)を使います。体感レイテンシ ≒ 上流のトータル応答時間。
452
- - **M 系 macOS では** qwen2.5-coder:7b が ~30–60s/ターン、14b が ~2 分。主因は Claude Code が毎ターン送る 15–20K トークンのシステムプロンプト prefill で、**CodeRouter のオーバーヘッドではありません**。
453
- - **ツール選択の品質**はモデル側の限界で、ワイア層の問題ではありません。CodeRouter はワイア(テキスト JSON → `tool_use` ブロック)を修復しますが、モデルが**正しいツール**を選んだかは別問題。qwen2.5-coder:14b は `Bash` が正解の場面で `Glob` を選ぶことがあり — 対策はより強いローカルモデル、あるいは `ALLOW_PAID=true` で Claude にフォールスルーさせることです。
454
- - **ミッドストリーム失敗**(Ollama が最初のチャンク後に落ちる等)は単発の `event: error` としてクライアントに届き、リトライはありません — 部分レスポンスは保持され、ストリームはクリーンに閉じます。
455
-
456
- 予定(v1.0 は [plan.md §10](./plan.md)、v1.0+ は §18):
457
-
458
- - v1.0 ✅ — 14 ケースのリグレッションスイート、Code Mode (スリム版 Claude Code ハーネス); 出力クリーニングは **v1.0-A** で `output_filters` チェーンとして完了
459
- - v1.5 ✅ — **メトリクスダッシュボード(出荷済み)** — `MetricsCollector` + `GET /metrics.json` + `GET /metrics` (Prometheus) + `GET /dashboard` (HTML 1 ページ) + `coderouter stats` curses TUI + `scripts/demo_traffic.sh` トラフィックジェネレータ + `display_timezone` 設定
460
- - v1.6 ✅ — `auto_router` (task-aware routing、`default_profile: auto` で画像/コード濃度/その他を自動振り分け) + NVIDIA NIM 無料枠 8 段チェーン + ドキュメント言語スワップ (JA primary) + トラブルシュート独立ドキュメント + `--env-file` / `doctor --check-env`
461
- - v1.7 ✅ — PyPI 公開 (`uvx --from coderouter-cli coderouter` で 1 行起動) + Trusted Publishing 経路 (release.yml で自動 publish)
462
- - v1.8 ✅ — **用途別 4 プロファイル + GLM/Gemma 4/Qwen3.6 公式化 + apply 自動化**: `multi` (default) / `coding` / `general` / `reasoning` の 4 プロファイル + 全プロファイルに `append_system_prompt` で Claude 風応答 nudge + `mode_aliases` (default/fast/vision/think/cheap)、Ollama 公式 tag 化された `gemma4:e4b/26b/31b` / `qwen3.6:27b/35b` を active stanza に格上げ、Z.AI を OpenAI-compat で 2 base_url 提供 (Coding Plan / General API)、`coderouter doctor --check-model --apply` で YAML パッチを非破壊書き戻し (`ruamel.yaml` round-trip でコメント・key 順序保持、冪等)、`setup.sh` onboarding ウィザード、`claude_code_suitability` startup チェック (Llama-3.3-70B 系を `claude-code-*` profile で WARN)。残り (v1.9 以降): `coderouter doctor --network` (CI 用)、launcher スクリプト (`.command` / `.sh` / `.bat`)、opt-in 起動時アップデートチェック
463
-
464
- ## `kind: openai_compat` と `kind: anthropic` の選び方
465
-
466
- `providers.yaml` の各プロバイダに `kind` があります。2 択です。どちらを選ぶかでホップを超えて生存するワイアレベル機能と、到達可能なクライアントが変わります。
467
-
468
- | 観点 | `kind: openai_compat` | `kind: anthropic` |
469
- |---|---|---|
470
- | `/v1/chat/completions` から到達 | ✅ 変換不要 | ✅ v0.4-A 逆変換経由 |
471
- | `/v1/messages` から到達 | ✅ 変換 + tool-call 修復経由 | ✅ ネイティブパススルー |
472
- | 対象 | llama.cpp, Ollama, OpenRouter, LM Studio, Together, Groq, ... | `api.anthropic.com`、Bedrock の Anthropic シム、Messages ワイアを話す任意サーバー |
473
- | `cache_control` ブロック | ❌ ロスト(OpenAI 側に等価物なし) | ✅ `/v1/messages` 経由で end-to-end 保持 |
474
- | `thinking` ブロック | ❌ ロスト | ✅ `/v1/messages` 経由で保持 |
475
- | 構造化 `tool_use` SSE イベント | 修復から合成 (v0.3-D downgrade) | 上流からパススルー |
476
- | tool-call 修復 (素テキスト JSON → `tool_use`) | ✅ 壊れた JSON を吐くローカルモデル向けに必要 | n/a (Anthropic は壊れた JSON を出さない) |
477
- | `anthropic-beta` ヘッダ転送 (v0.4-D) | n/a | ✅ そのまま |
478
-
479
- **判断の目安:**
480
-
481
- - **ローカルモデルまたは OpenRouter 無料枠** → `kind: openai_compat`。逆経路は存在しますが、OpenAI ワイアをネイティブに話すプロバイダに対し変換コストを払う理由はありません。
482
- - **公式 API 経由の Claude で、`cache_control` / `thinking` を効かせたい** → `kind: anthropic`、`/v1/messages` 経由(= Claude Code から `ANTHROPIC_BASE_URL=http://localhost:8088`)。`examples/providers.yaml` の `claude-code-direct` プロファイルがこのケース用に事前配線されています。
483
- - **OpenAI クライアントから Claude に到達**(`openai` SDK / curl → `/v1/chat/completions`)→ `kind: anthropic` は引き続き動きます — 基本 chat / tools / vision は v0.4-A 逆経路で生き残ります。ただし OpenAI に等価形状が無いため `cache_control` / `thinking` は送れません。
484
- - **混在チェーン**(ローカル先頭、Claude を有料最終砦に)→ 同プロファイルに両 `kind` を並べます。エンジンの多態ディスパッチが各境界のホップを扱います。
485
-
486
- ## トラブルシューティング
487
-
488
- > **詳細は独立ドキュメント [`docs/troubleshooting.md`](./docs/troubleshooting.md) (v1.6.2 で分離)** を参照してください。
489
- > 本節は 30 秒で済む早見表。
490
-
491
- **まず第一に**: 失敗中のプロバイダに対して **[`coderouter doctor --check-model <provider>`](#doctor--coderouter-doctor---check-model-provider-v07-b)** を走らせてください。6 probe を回し、宣言と観測の不一致があればコピペ YAML パッチを出します。
492
-
493
- **症状別の入口** (詳細はリンク先):
494
-
495
- - 起動して上流に 401: `Header of type authorization was missing` → [§1 起動・設定の罠](./docs/troubleshooting.md#1-起動設定で踏みやすい-5-つの罠-v162-追加) (`.env` の `export` 必須、`coderouter serve --mode <profile>` の正しい使い方)
496
- - ログに `provider-failed` / `capability-degraded` / `chain-uniform-auth-failure` → [§2 ログの読み方](./docs/troubleshooting.md#2-ログの読み方とよくあるパターン)
497
- - Ollama に向けたら無音 / `<think>` タグ漏れ / 「ファイルが読めません」 → [§3 Ollama 5 症状](./docs/troubleshooting.md#3-ollama-初心者--サイレント失敗-5-症状-v07-c)
498
- - Claude Code 上で挨拶がツール呼び出しに化ける / `UserPromptSubmit hook error` → [§4 Claude Code 連携の罠](./docs/troubleshooting.md#4-claude-code-連携で踏みやすい罠-v162-追加)
499
-
500
- ダッシュボード `http://localhost:8088/dashboard` を別タブで開いておくと、ほとんどの罠が**目で見て 10 秒で**特定できます。
501
-
502
- ミッドストリーム失敗は SSE ストリーム内で単発の `event: error` / `type: api_error` として出ます (ヘッダは既送出なので 5xx HTTP ステータスは返らない)。これは「どのプロバイダも開始できなかった」 (`type: overloaded_error`) とは区別されます。
503
-
504
- <!-- 旧アンカーの後方互換 — 古い記事 / 検索結果からのリンクが切れないように -->
505
- <a id="ollama-初心者--サイレント失敗-5-症状-v07-c"></a>
506
- <a id="ollama-beginner--5-silent-fail-symptoms-v07-c"></a>
507
-
508
- ### Ollama 初心者 — サイレント失敗 5 症状
509
-
510
- 詳細は [`docs/troubleshooting.md` §3](./docs/troubleshooting.md#3-ollama-初心者--サイレント失敗-5-症状-v07-c) に移動しました。
511
-
512
- - 症状 1: 200 が返るのに返信が空/意味不明 → `num_ctx` 既定 2048 に切り詰められた
513
- - 症状 2: 「ファイルが読めません」を繰り返す → 小さなモデルが tools 仕様を扱えていない (`tools: false` 宣言)
514
- - 症状 3: `<think>...</think>` が漏れる → `output_filters: [strip_thinking]`
515
- - 症状 4: 初回リクエストが毎回失敗 → `ollama pull <tag>` 忘れ / `model:` タイポ
516
- - 症状 5: 全プロバイダが一様に失敗 → クラウド API キー未 export ([§1-2 / §1-3](./docs/troubleshooting.md#1-2-env-には-export-が必須))
517
-
518
- 各症状の `coderouter doctor` 出力例とコピペ可能 YAML パッチは [docs/troubleshooting.md](./docs/troubleshooting.md) に。HF-on-Ollama 構成 / lunacode との関係も同じドキュメントに集約。
519
-
520
- ## 依存ポリシー
521
-
522
- 厳密 — [`plan.md` §5.4](./plan.md) 参照。ランタイム依存:
523
-
524
- | パッケージ | 目的 |
525
- |---------|-----|
526
- | `fastapi` | HTTP ingress |
527
- | `uvicorn` | ASGI サーバー |
528
- | `httpx` | アウトバウンド HTTP(あえて Anthropic/OpenAI SDK を使わない) |
529
- | `pydantic` | スキーマ検証 |
530
- | `pyyaml` | 設定パース |
531
-
532
- 以上。`litellm` なし、`langchain` なし、`openai`/`anthropic` SDK なし。
533
-
534
- ## プログラムから例外をキャッチする (v1.0.1)
535
-
536
- CodeRouter を組み込んで使う場合 (engine を直接呼ぶ / `coderouter serve` を harness でラップする等)、CodeRouter が内部で raise する全例外は `CodeRouterError` を継承しています。1 つの `except` で全部拾えます:
537
-
538
- ```python
539
- from coderouter import CodeRouterError
540
-
541
- try:
542
- response = await engine.generate(chat_request)
543
- except CodeRouterError as exc:
544
- # AdapterError / NoProvidersAvailableError / MidStreamError の全てに該当
545
- logger.error("coderouter-failed", extra={"reason": str(exc)})
546
- ```
547
-
548
- leaf 例外は従来の場所 (`AdapterError` は `coderouter.adapters.base`、`NoProvidersAvailableError` と `MidStreamError` は `coderouter.routing.fallback`) に残っているので、既存の `except AdapterError:` のような catch はそのまま動きます。root class は downstream が leaf を個別 import して enumerate しなくて済むよう public API surface を固定するためだけに存在し、今後 leaf が増えても呼び出し側のコードを触る必要がありません。
549
-
550
- ## Security
551
-
552
- シークレットは設定ファイルではなく環境変数に置きます。CI はシークレット
553
- スキャン (`gitleaks`)、多重ソースの依存 CVE 監査 (`pip-audit` +
554
- OSV-Scanner)、lockfile 固定インストールを強制します —
555
- [`docs/security.md`](./docs/security.md) に完全な方針と
556
- 報告手順があります。
557
-
558
- ## License
559
-
560
- MIT