Skip to content
Merged
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
16 changes: 16 additions & 0 deletions devlog/_plan/260818_fastwire_b2_openrouter/evidence/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# Evidence — FastWire B2 (OpenRouter)

`010_logs_openrouter_priority_lower_bound.png` — Logs table with three seeded OpenRouter
requests on `openai/gpt-5.6-sol`, captured against a local proxy with a temporary
`OPENCODEX_HOME`:

| Row | Attempt outcome | Rendering |
| --- | --- | --- |
| `or-priority-confirmed` | upstream echoed `service_tier: "priority"` | `≥$0.1105` — priced at the standard rate but marked a floor, because OpenRouter publishes no bundled tier price and documents priority as higher cost |
| `or-priority-declined` | upstream echoed `service_tier: "default"` | `~$0.1105` — a real downgrade, so no floor marker |
| `or-standard` | no tier requested | `~$0.1105` |

All three totals match on purpose: without a bundled priority price every row is computed at
the standard rate, so the only thing that differs is whether the cost is presented as an
estimate (`~$`) or as a known lower bound (`≥$`). The marker matches the convention used by
the parallel xAI unit (#2072).
29 changes: 29 additions & 0 deletions docs-site/src/content/docs/reference/configuration/providers.md
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,35 @@ contract; existing configurations see these migration deltas:

Explicit capability `false` and Responses caller-tier forwarding retain their existing contracts.

### OpenRouter Fast

The canonical `https://openrouter.ai/api/v1` preset advertises Fast only for these exact
OpenAI-backed model slugs:

- `openai/gpt-5.6-sol`
- `openai/gpt-5.6-terra`
- `openai/gpt-5.6-luna`

`anthropic/claude-sonnet-5` and undeclared OpenRouter models remain unclassified. A provider-level
`supportsServiceTier` default is intentionally absent, and a user-set `supportsServiceTier: false`
still disables the exact-model declarations. The registry declarations apply only while the
provider still targets the canonical OpenRouter base URL; a same-named custom destination is not
assumed to share OpenRouter's contract.

Fast sends `service_tier: "priority"`. It does not add or rewrite `provider.only`,
`provider.order`, or `provider.allow_fallbacks`. OpenRouter documents priority endpoints as the
first routing choice, followed by graceful fallback to other endpoints when priority capacity is
unavailable. Billing follows the endpoint actually used, and the response reports the actual
top-level `service_tier`. Pinning tier endpoints and disabling fallback would therefore reduce
availability without improving billing safety.

Request logs use that response echo as the authority. `priority` confirms Fast as applied;
`default` records a downgrade and uses the standard-price estimate; a missing field leaves the
attempt assumed rather than guessing a downgrade. OpenRouter's priority multiplier varies by
upstream and is not bundled here. When priority is confirmed but no exact priority price is known,
the dashboard keeps the standard-price estimate as a documented lower bound and prefixes it with
`≥`; downgraded attempts have no lower-bound marker.

API-key providers may hold a literal key or an environment reference. OAuth providers use the
credential store populated by `ocx login`; subscription-backed Claude Code launch behavior is
configured under [`claudeCode.authMode`](/reference/configuration/server/#claude-code).
Expand Down
4 changes: 4 additions & 0 deletions gui/src/i18n/de.ts
Original file line number Diff line number Diff line change
Expand Up @@ -645,6 +645,9 @@ export const de: Record<TKey, string> = {
"logs.conversation.totals": "{requests} Anfragen · {tokens} Tokens · {cost}",
"logs.conversation.scope": "Summen gelten nur für den aktuell geladenen Logs-Ring.",
"logs.conversation.excluded": "({unpriced} ohne Preis, {unmetered} ohne Messung vom ~$ ausgenommen)",
"logs.cost.approximate": "ca. {amount}",
"logs.cost.lowerBound": "mind. {amount}",
"logs.cost.unavailable": "nicht verfügbar",
"logs.detail.conversation": "Konversation",
"logs.badge.claude": "Claude",
"logs.badge.grok": "Grok",
Expand Down Expand Up @@ -711,6 +714,7 @@ export const de: Record<TKey, string> = {
"logs.detail.estimate.cache_detail_missing": "Cache-Details fehlen; Eingabe ist als Obergrenze geschätzt.",
"logs.detail.estimate.expected_price_overlay": "Ein verifizierter Expected-Listenpreis wurde verwendet.",
"logs.detail.estimate.provider_cost_overlay": "Ein vom Anbieter konfiguriertes Preis-Overlay wurde verwendet.",
"logs.detail.estimate.priority_lower_bound": "Der bestätigte OpenRouter-Priority-Preis ist nicht verfügbar; die angezeigte Standardpreisschätzung ist eine bekannte Untergrenze.",
"logs.col.error": "Fehler",
"logs.col.upstreamReason": "Upstream-Grund",
"logs.col.duration": "Dauer",
Expand Down
4 changes: 4 additions & 0 deletions gui/src/i18n/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -678,6 +678,9 @@ export const en = {
"logs.conversation.totals": "{requests} requests · {tokens} tokens · {cost}",
"logs.conversation.scope": "Totals cover the currently loaded Logs ring only.",
"logs.conversation.excluded": "({unpriced} unpriced, {unmetered} unmetered excluded from ~$)",
"logs.cost.approximate": "~{amount}",
"logs.cost.lowerBound": "≥{amount}",
"logs.cost.unavailable": "—",
"logs.detail.conversation": "Conversation",
"logs.badge.claude": "Claude",
"logs.badge.grok": "Grok",
Expand Down Expand Up @@ -744,6 +747,7 @@ export const en = {
"logs.detail.estimate.cache_detail_missing": "Cache details were unavailable; input is an upper-bound estimate.",
"logs.detail.estimate.expected_price_overlay": "A verified expected list price was used.",
"logs.detail.estimate.provider_cost_overlay": "A provider-configured price overlay was used.",
"logs.detail.estimate.priority_lower_bound": "The confirmed OpenRouter priority price is unavailable; the displayed standard-price estimate is a known lower bound.",
"logs.col.error": "Error",
"logs.col.upstreamReason": "Upstream reason",
"logs.col.duration": "Duration",
Expand Down
4 changes: 4 additions & 0 deletions gui/src/i18n/fr.ts
Original file line number Diff line number Diff line change
Expand Up @@ -659,6 +659,9 @@ export const fr: Record<TKey, string> = {
"logs.conversation.totals": "{requests} requêtes · {tokens} jetons · {cost}",
"logs.conversation.scope": "Les totaux couvrent uniquement le tampon circulaire des journaux actuellement chargé.",
"logs.conversation.excluded": "({unpriced} sans tarif, {unmetered} sans mesure exclus du total en ~$)",
"logs.cost.approximate": "env. {amount}",
"logs.cost.lowerBound": "au moins {amount}",
"logs.cost.unavailable": "indisponible",
"logs.detail.conversation": "Conversation",
"logs.badge.claude": "Claude",
"logs.badge.grok": "Grok",
Expand Down Expand Up @@ -725,6 +728,7 @@ export const fr: Record<TKey, string> = {
"logs.detail.estimate.cache_detail_missing": "Les détails du cache n’étaient pas disponibles ; l’entrée est une estimation de la limite supérieure.",
"logs.detail.estimate.expected_price_overlay": "Un tarif catalogue attendu et vérifié a été utilisé.",
"logs.detail.estimate.provider_cost_overlay": "Un remplacement de tarif configuré pour le fournisseur a été utilisé.",
"logs.detail.estimate.priority_lower_bound": "Le tarif Priority OpenRouter confirmé n’est pas disponible ; l’estimation au tarif standard affichée est une borne inférieure connue.",
"logs.col.error": "Erreur",
"logs.col.upstreamReason": "Motif en amont",
"logs.col.duration": "Durée",
Expand Down
4 changes: 4 additions & 0 deletions gui/src/i18n/ja.ts
Original file line number Diff line number Diff line change
Expand Up @@ -621,6 +621,9 @@ export const ja: Record<TKey, string> = {
"logs.conversation.totals": "{requests} 件 · {tokens} トークン · {cost}",
"logs.conversation.scope": "合計は現在読み込まれている Logs リングのみです。",
"logs.conversation.excluded": "(~$ から価格なし {unpriced} / 未計測 {unmetered} を除外)",
"logs.cost.approximate": "約{amount}",
"logs.cost.lowerBound": "最低{amount}",
"logs.cost.unavailable": "利用不可",
"logs.detail.conversation": "会話",
"logs.badge.claude": "Claude",
"logs.badge.grok": "Grok",
Expand Down Expand Up @@ -687,6 +690,7 @@ export const ja: Record<TKey, string> = {
"logs.detail.estimate.cache_detail_missing": "キャッシュの詳細が利用できませんでした; 入力は上限の推定です。",
"logs.detail.estimate.expected_price_overlay": "検証済みの予想定価が使用されました。",
"logs.detail.estimate.provider_cost_overlay": "プロバイダー設定の価格オーバーレイが使用されました。",
"logs.detail.estimate.priority_lower_bound": "確認済みの OpenRouter Priority 価格は取得できないため、表示される標準価格の見積もりは既知の下限です。",
"logs.col.error": "エラー",
"logs.col.upstreamReason": "上流の理由",
"logs.col.duration": "所要時間",
Expand Down
4 changes: 4 additions & 0 deletions gui/src/i18n/ko.ts
Original file line number Diff line number Diff line change
Expand Up @@ -664,6 +664,9 @@ export const ko: Record<TKey, string> = {
"logs.conversation.totals": "{requests}건 요청 · {tokens} 토큰 · {cost}",
"logs.conversation.scope": "합계는 현재 로드된 Logs 링만 포함합니다.",
"logs.conversation.excluded": "(~$에서 가격 없음 {unpriced}건, 미측정 {unmetered}건 제외)",
"logs.cost.approximate": "약 {amount}",
"logs.cost.lowerBound": "최소 {amount}",
"logs.cost.unavailable": "사용 불가",
"logs.detail.conversation": "대화",
"logs.badge.claude": "Claude",
"logs.badge.grok": "Grok",
Expand Down Expand Up @@ -730,6 +733,7 @@ export const ko: Record<TKey, string> = {
"logs.detail.estimate.cache_detail_missing": "캐시 상세가 없어 입력 전액을 상한으로 추정했습니다.",
"logs.detail.estimate.expected_price_overlay": "검증된 expected 정가를 사용했습니다.",
"logs.detail.estimate.provider_cost_overlay": "프로바이더 구성 가격 오버레이를 사용했습니다.",
"logs.detail.estimate.priority_lower_bound": "확인된 OpenRouter Priority 가격을 사용할 수 없어 표시된 표준 가격 추정치는 알려진 하한입니다.",
"logs.col.error": "오류",
"logs.col.upstreamReason": "업스트림 원인",
"logs.col.duration": "소요 시간",
Expand Down
4 changes: 4 additions & 0 deletions gui/src/i18n/ru.ts
Original file line number Diff line number Diff line change
Expand Up @@ -662,6 +662,9 @@ export const ru: Record<TKey, string> = {
"logs.conversation.totals": "{requests} запросов · {tokens} токенов · {cost}",
"logs.conversation.scope": "Итоги только по загруженному кольцу Logs.",
"logs.conversation.excluded": "(из ~$ исключены {unpriced} без цены, {unmetered} без учёта)",
"logs.cost.approximate": "около {amount}",
"logs.cost.lowerBound": "не менее {amount}",
"logs.cost.unavailable": "недоступно",
"logs.detail.conversation": "Диалог",
"logs.badge.claude": "Claude",
"logs.badge.grok": "Grok",
Expand Down Expand Up @@ -728,6 +731,7 @@ export const ru: Record<TKey, string> = {
"logs.detail.estimate.cache_detail_missing": "Детализация кэша недоступна; входные токены оценены по верхней границе.",
"logs.detail.estimate.expected_price_overlay": "Использована подтверждённая ожидаемая цена из прайс-листа.",
"logs.detail.estimate.provider_cost_overlay": "Использован ценовой оверлей провайдера.",
"logs.detail.estimate.priority_lower_bound": "Подтверждённая цена OpenRouter Priority недоступна; показанная оценка по стандартной цене является известной нижней границей.",
"logs.col.error": "Ошибка",
"logs.col.upstreamReason": "Причина от провайдера",
"logs.col.duration": "Длительность",
Expand Down
4 changes: 4 additions & 0 deletions gui/src/i18n/tr.ts
Original file line number Diff line number Diff line change
Expand Up @@ -669,6 +669,9 @@ export const tr: Record<TKey, string> = {
"logs.conversation.totals": "{requests} istek · {tokens} jeton · {cost}",
"logs.conversation.scope": "Toplamlar yalnızca yüklü günlükleri kapsar.",
"logs.conversation.excluded": "({unpriced} fiyatlandırılmamış, {unmetered} ölçülmemiş hariç)",
"logs.cost.approximate": "yaklaşık {amount}",
"logs.cost.lowerBound": "en az {amount}",
"logs.cost.unavailable": "kullanılamıyor",
"logs.detail.conversation": "Sohbet",
"logs.badge.claude": "Claude",
"logs.badge.grok": "Grok",
Expand Down Expand Up @@ -735,6 +738,7 @@ export const tr: Record<TKey, string> = {
"logs.detail.estimate.cache_detail_missing": "Önbellek detayları eksik.",
"logs.detail.estimate.expected_price_overlay": "Doğrulanmış liste fiyatı kullanıldı.",
"logs.detail.estimate.provider_cost_overlay": "Kullanıcı tarafından yapılandırılan bir sağlayıcı fiyat katmanı kullanıldı.",
"logs.detail.estimate.priority_lower_bound": "Doğrulanan OpenRouter Priority fiyatı kullanılamıyor; gösterilen standart fiyat tahmini bilinen bir alt sınırdır.",
"logs.col.error": "Hata",
"logs.col.upstreamReason": "Yukarı akış nedeni",
"logs.col.duration": "Süre",
Expand Down
4 changes: 4 additions & 0 deletions gui/src/i18n/zh-TW.ts
Original file line number Diff line number Diff line change
Expand Up @@ -516,6 +516,9 @@ export const zhTW: Record<TKey, string> = {
"logs.conversation.totals": "{requests} 次請求 · {tokens} tokens · {cost}",
"logs.conversation.scope": "合計僅涵蓋目前已載入的 Logs 環形緩衝。",
"logs.conversation.excluded": "(~$ 已排除 {unpriced} 筆無定價、{unmetered} 筆無計量)",
"logs.cost.approximate": "約 {amount}",
"logs.cost.lowerBound": "至少 {amount}",
"logs.cost.unavailable": "無法估算",
"logs.detail.conversation": "對話",
"logs.badge.claude": "Claude",
"logs.col.time": "時間",
Expand Down Expand Up @@ -1809,6 +1812,7 @@ export const zhTW: Record<TKey, string> = {
"logs.detail.attempt.recovery.emptyCompletion": "空白完成重試",
"logs.detail.attempt.recovery.unknown": "未知的復原原因",
"logs.detail.estimate.provider_cost_overlay": "已使用供應商設定的價格覆蓋。",
"logs.detail.estimate.priority_lower_bound": "無法取得已確認的 OpenRouter Priority 價格;目前顯示的標準價格估算是已知下限。",
"pws.cockpitImportDescription": "從此裝置匯入 Cockpit Tools Antigravity JSON 匯出檔。不會顯示檔案內容。",
"pws.cockpitImportFileLabel": "Cockpit Tools Antigravity JSON 匯出檔",
"pws.cockpitImportChooseFile": "選擇 JSON 檔案",
Expand Down
4 changes: 4 additions & 0 deletions gui/src/i18n/zh.ts
Original file line number Diff line number Diff line change
Expand Up @@ -657,6 +657,9 @@ export const zh: Record<TKey, string> = {
"logs.conversation.totals": "{requests} 次请求 · {tokens} tokens · {cost}",
"logs.conversation.scope": "合计仅覆盖当前已加载的 Logs 环形缓冲。",
"logs.conversation.excluded": "(~$ 已排除 {unpriced} 条无定价、{unmetered} 条无计量)",
"logs.cost.approximate": "约 {amount}",
"logs.cost.lowerBound": "至少 {amount}",
"logs.cost.unavailable": "无法估算",
"logs.detail.conversation": "会话",
"logs.badge.claude": "Claude",
"logs.badge.grok": "Grok",
Expand Down Expand Up @@ -723,6 +726,7 @@ export const zh: Record<TKey, string> = {
"logs.detail.estimate.cache_detail_missing": "缺少缓存明细;输入费用按上限估算。",
"logs.detail.estimate.expected_price_overlay": "使用了已验证的 Expected 标价。",
"logs.detail.estimate.provider_cost_overlay": "使用了用户配置的提供方价格覆盖。",
"logs.detail.estimate.priority_lower_bound": "暂无已确认的 OpenRouter Priority 价格;当前显示的标准价估算是已知下界。",
"logs.col.error": "错误",
"logs.col.upstreamReason": "上游原因",
"logs.col.duration": "耗时",
Expand Down
Loading
Loading