diff --git a/docs-site/src/content/docs/guides/sidecars.md b/docs-site/src/content/docs/guides/sidecars.md index 006287ab9..a397f08a9 100644 --- a/docs-site/src/content/docs/guides/sidecars.md +++ b/docs-site/src/content/docs/guides/sidecars.md @@ -70,14 +70,20 @@ failures after response headers have started are delivered as `response.failed` ## Vision sidecar When the routed model is listed in its provider's `noVisionModels` and a request carries an image, -opencodex describes each image **before** the main call and replaces it with text. The Dashboard and -management API present `gpt-5.6-luna` as the current default, and startup migrates an explicitly -persisted legacy `gpt-5.4-mini` value to Luna. If the `visionSidecar.model` field is entirely absent, -the vision execution path still has a `gpt-5.4-mini` code fallback. +opencodex describes each image **before** the main call and replaces it with text. When +`visionSidecar.model` is absent or blank, the OpenAI execution path, Dashboard, and management API +use the `gpt-5.4-mini` fallback. Startup still migrates an explicitly persisted legacy +`gpt-5.4-mini` value to `gpt-5.6-luna`; that migration applies to a stored value, not to an absent +model field. - Images can come from user, developer, and tool-result messages, including Codex's `view_image`. -- Each image is sent to the configured native vision model with `reasoning.effort: "low"`; its - description replaces the image part inline. +- On the OpenAI path (ChatGPT-login passthrough), each image is sent to the configured vision model + over the Responses endpoint with the selected `reasoning.effort` (`low` by default), and its + description replaces the image part inline. The Anthropic path uses the Messages endpoint with its + own thinking-budget mapping and ignores this OpenAI-specific setting. +- For native models with known capability metadata, unsupported reasoning is normalized to the + highest supported rung at or below the requested level; if none exists, the lowest supported rung + is used. Unknown or custom models remain permissive when reliable capability metadata is absent. - Descriptions run with bounded concurrency (3 at a time, input order preserved). User context sent to the describer is capped at 800 characters, and each injected description is capped at 2,000 characters. The request does not send `max_output_tokens`, which the ChatGPT backend rejects. @@ -90,14 +96,17 @@ the vision execution path still has a `gpt-5.4-mini` code fallback. available, the raw image is stripped rather than forwarded to a text-only backend. - `maxDescriptionsPerTurn` (default 8) limits new descriptions per main-model turn. Cache hits and same-turn duplicates do not consume it. Successful `data:` image descriptions are cached by - backend, model, detail, image bytes, and message context; mutable `https:` images are not cached. + backend, model, detail, image bytes, and message context — plus the reasoning effort on OpenAI + keys (Anthropic keys omit it, since that field is ignored there); mutable `https:` images are not + cached. ```json { "visionSidecar": { "enabled": true, - "backend": "anthropic", - "model": "claude-sonnet-5", + "backend": "openai", + "model": "gpt-5.6-luna", + "reasoning": "medium", "maxDescriptionsPerTurn": 8, "timeoutMs": 45000 } diff --git a/docs-site/src/content/docs/ja/guides/sidecars.md b/docs-site/src/content/docs/ja/guides/sidecars.md index cc64fc789..376bdabaa 100644 --- a/docs-site/src/content/docs/ja/guides/sidecars.md +++ b/docs-site/src/content/docs/ja/guides/sidecars.md @@ -69,14 +69,20 @@ stall は全体生成 timeout ではありません。SSE 開始前の失敗は ## ビジョンサイドカー ルーティングモデルが該当プロバイダーの `noVisionModels` にありリクエストに画像が来る場合、opencodex は -メイン呼び出し**前に**各画像を説明したテキストに差し替えます。ダッシュボードと管理 API の現在のデフォルト選択は -`gpt-5.6-luna` で、起動時に明示的に保存された既存 `gpt-5.4-mini` 値も Luna にマイグレーションします。 -ただし `visionSidecar.model` フィールド自体がない場合はビジョン実行経路はコードフォールバックの `gpt-5.4-mini` を使います。 +メイン呼び出し**前に**各画像を説明したテキストに差し替えます。`visionSidecar.model` が未設定または空の場合、 +OpenAI 実行経路、ダッシュボード、管理 API は `gpt-5.4-mini` をフォールバックとして使います。起動時には +明示的に保存された旧 `gpt-5.4-mini` 値を引き続き `gpt-5.6-luna` にマイグレーションしますが、この +マイグレーションは保存済みの値だけが対象で、モデルフィールドがない場合には適用されません。 - 画像はユーザー、developer、ツール結果メッセージから来ます。Codex の `view_image` 結果も 含まれます。 -- 各画像は設定されたネイティブビジョンモデルに `reasoning.effort: "low"` で渡され、説明が画像 - 部分をインラインに差し替えます。 +- OpenAI パス(ChatGPT ログインパススルー)では、各画像は選択した `reasoning.effort`(デフォルト + `low`)付きで Responses エンドポイント経由で設定済みのビジョンモデルに送信され、説明が画像部分 + をインラインで置き換えます。Anthropic パスは Messages エンドポイントを使い、独自の思考予算 + マッピングで動作し、この OpenAI 固有の設定を無視します。 +- 信頼できる能力メタデータがあるネイティブモデルでは、未対応の推論レベルは要求値以下で最も高い + 対応レベルに正規化されます。該当するレベルがない場合は最も低い対応レベルを使います。能力情報を + 信頼できない不明モデルやカスタムモデルは制限せず、そのまま扱います。 - 説明は一度に 3 件並列処理し入力順序を維持します。説明モデルに渡すユーザー文脥は 800 文字、注入する画像説明は 1 枚あたり 2,000 文字に制限します。ChatGPT バックエンドが拒否する `max_output_tokens` は送信しません。 @@ -89,14 +95,17 @@ stall は全体生成 timeout ではありません。SSE 開始前の失敗は テキスト専用バックエンドに元画像を送らず削除します。 - `maxDescriptionsPerTurn`(デフォルト 8)はメインモデル 1 ターンで新規実行する説明数を制限します。キャッシュ ヒットと同じターンの重複要求は限度を消費しません。成功した `data:` 画像説明はバックエンド、モデル、 - detail、画像バイト、メッセージ文脈を基準にキャッシュし、変わり得る `https:` 画像はキャッシュしません。 + detail、画像バイト、メッセージ文脈を基準にキャッシュし、OpenAI のキーには推論負荷も含まれます + (Anthropic のキーには含まれません。そこではこのフィールドは無視されるため)。変わり得る + `https:` 画像はキャッシュしません。 ```json { "visionSidecar": { "enabled": true, - "backend": "anthropic", - "model": "claude-sonnet-5", + "backend": "openai", + "model": "gpt-5.6-luna", + "reasoning": "medium", "maxDescriptionsPerTurn": 8, "timeoutMs": 45000 } diff --git a/docs-site/src/content/docs/ja/reference/configuration/server.md b/docs-site/src/content/docs/ja/reference/configuration/server.md index d702ec883..026747378 100644 --- a/docs-site/src/content/docs/ja/reference/configuration/server.md +++ b/docs-site/src/content/docs/ja/reference/configuration/server.md @@ -144,9 +144,10 @@ OpenAI バックエンドには、ChatGPT ログインと有効な ChatGPT `forw | `enabled?` | `boolean` |使用可能な場合はオン |マスターイメージと説明のスイッチ。 | | `backend?` | `"openai" \| "anthropic"` |自動 | Web 検索と同じ、明示的優先、人間認証情報を意識した選択。 | | `model?` | `string` |バックエンド依存 | OpenAI の場合は `gpt-5.4-mini`、Anthropic の場合は `claude-sonnet-5`。 | +| `reasoning?` | `"low" \| "medium" \| "high" \| "xhigh" \| "max"` | `"low"` | OpenAI Responses の推論負荷。Anthropic は無視します。 | | `maxDescriptionsPerTurn?` | `number` | `8` |新しい説明のキャッシュミスはメインターンごとに許可されます。 `0` は通話を無効にします。無効な値にはデフォルトが使用されます。 | | `timeoutMs?` | `number` | `45000` |サイドカーのフェッチタイムアウト。 | -Vision は、プロバイダーの `noVisionModels` のモデルに送信された画像に対してのみアクティブになります。 OpenAI には、検索と同じログイン/転送要件があります。明示的に選択された Anthropic は、使用可能な認証情報がないと失敗します。成功した `data:` 記述では、バックエンド、モデル、詳細、画像バイト、および正規化されたメッセージ コンテキストをキーとした境界付きキャッシュが使用されます。ヒットと同じターンの重複は制限を消費しません。リモート `https:` イメージと失敗した説明、または空の説明はキャッシュされません。 +対応するレベルは、上流プロバイダーの能力と選択したモデルが公表する推論ラダーによって制限されます。 Vision は、プロバイダーの `noVisionModels` のモデルに送信された画像に対してのみアクティブになります。 OpenAI には、検索と同じログイン/転送要件があります。明示的に選択された Anthropic は、使用可能な認証情報がないと失敗します。成功した `data:` 記述では、バックエンド、モデル、詳細、画像バイト、および正規化されたメッセージ コンテキストをキーとした境界付きキャッシュが使用されます。OpenAI のキーには推論負荷も含まれます(Anthropic のキーには含まれません)。ヒットと同じターンの重複は制限を消費しません。リモート `https:` イメージと失敗した説明、または空の説明はキャッシュされません。 Anthropic OAuth サイドカーは、opencodex の既存のクロード コード OAuth フィンガープリントを再利用します。対象のアカウントとワークロードをソークテストします。 diff --git a/docs-site/src/content/docs/ko/guides/sidecars.md b/docs-site/src/content/docs/ko/guides/sidecars.md index 1ea7596bd..d22e8c66e 100644 --- a/docs-site/src/content/docs/ko/guides/sidecars.md +++ b/docs-site/src/content/docs/ko/guides/sidecars.md @@ -70,14 +70,20 @@ stall은 전체 생성 timeout이 아닙니다. SSE가 시작되기 전 실패 ## 비전 사이드카 라우팅 모델이 해당 프로바이더의 `noVisionModels`에 있고 요청에 이미지가 들어오면, opencodex는 -메인 호출 **전에** 각 이미지를 설명한 텍스트로 바꿉니다. Dashboard와 관리 API의 현재 기본 선택값은 -`gpt-5.6-luna`이며, 시작할 때 명시적으로 저장된 기존 `gpt-5.4-mini` 값도 Luna로 마이그레이션합니다. -다만 `visionSidecar.model` 필드 자체가 없으면 비전 실행 경로는 코드 폴백인 `gpt-5.4-mini`를 씁니다. +메인 호출 **전에** 각 이미지를 설명한 텍스트로 바꿉니다. `visionSidecar.model`이 없거나 빈 값이면 +OpenAI 실행 경로, Dashboard, 관리 API는 `gpt-5.4-mini`를 폴백으로 사용합니다. 시작 시 명시적으로 +저장된 기존 `gpt-5.4-mini` 값은 계속 `gpt-5.6-luna`로 마이그레이션되지만, 이 마이그레이션은 저장된 +값에만 적용되고 모델 필드가 없는 경우에는 적용되지 않습니다. - 이미지는 사용자, developer, 도구 결과 메시지에서 올 수 있습니다. Codex의 `view_image` 결과도 포함됩니다. -- 각 이미지는 설정된 네이티브 비전 모델에 `reasoning.effort: "low"`로 전달되고, 설명이 이미지 - 부분을 인라인으로 대체합니다. +- OpenAI 경로(ChatGPT 로그인 패스스루)에서는 각 이미지가 선택한 `reasoning.effort`(기본값 + `low`)와 함께 Responses 엔드포인트로 설정된 비전 모델에 전송되고, 설명이 이미지 부분을 인라인으로 + 대체합니다. Anthropic 경로는 Messages 엔드포인트와 자체 thinking 예산 매핑을 사용하며 이 + OpenAI 전용 설정을 무시합니다. +- 신뢰할 수 있는 기능 메타데이터가 있는 네이티브 모델에서는 지원되지 않는 추론 수준을 요청값 이하에서 + 가장 높은 지원 단계로 정규화합니다. 해당 단계가 없으면 가장 낮은 지원 단계를 사용합니다. 신뢰할 수 + 있는 기능 메타데이터가 없는 알 수 없는 모델이나 커스텀 모델은 제한하지 않습니다. - 설명은 한 번에 3개씩 병렬 처리하며 입력 순서를 유지합니다. 설명 모델에 전달하는 사용자 문맥은 800자, 주입하는 이미지 설명은 장당 2,000자로 제한합니다. ChatGPT 백엔드가 거부하는 `max_output_tokens`는 보내지 않습니다. @@ -90,15 +96,17 @@ stall은 전체 생성 timeout이 아닙니다. SSE가 시작되기 전 실패 없으면 텍스트 전용 백엔드에 원본 이미지를 보내지 않고 제거합니다. - `maxDescriptionsPerTurn`(기본값 8)은 메인 모델 한 턴에서 새로 실행할 설명 수를 제한합니다. 캐시 적중과 같은 턴의 중복 요청은 한도를 쓰지 않습니다. 성공한 `data:` 이미지 설명은 백엔드, 모델, - detail, 이미지 바이트, 메시지 문맥을 기준으로 캐시하며, 바뀔 수 있는 `https:` 이미지는 캐시하지 - 않습니다. + detail, 이미지 바이트, 메시지 문맥을 기준으로 캐시하며, OpenAI 키에는 추론 강도도 포함됩니다 + (Anthropic 키에는 포함되지 않습니다. 해당 필드는 거기서 무시되기 때문입니다). 바뀔 수 있는 + `https:` 이미지는 캐시하지 않습니다. ```json { "visionSidecar": { "enabled": true, - "backend": "anthropic", - "model": "claude-sonnet-5", + "backend": "openai", + "model": "gpt-5.6-luna", + "reasoning": "medium", "maxDescriptionsPerTurn": 8, "timeoutMs": 45000 } diff --git a/docs-site/src/content/docs/ko/reference/configuration/server.md b/docs-site/src/content/docs/ko/reference/configuration/server.md index 3ac1fba3d..ac267cf28 100644 --- a/docs-site/src/content/docs/ko/reference/configuration/server.md +++ b/docs-site/src/content/docs/ko/reference/configuration/server.md @@ -144,9 +144,10 @@ OpenAI 백엔드는 ChatGPT 로그인과 활성화된 ChatGPT `forward` provider | `enabled?` | `boolean` | on when usable | 주 이미지 설명 스위치입니다. | | `backend?` | `"openai" \| "anthropic"` | auto | web search와 같은, 명시값 우선 및 Anthropic 자격 증명 인식 선택 방식입니다. | | `model?` | `string` | backend-dependent | OpenAI는 `gpt-5.4-mini`, Anthropic은 `claude-sonnet-5`입니다. | +| `reasoning?` | `"low" \| "medium" \| "high" \| "xhigh" \| "max"` | `"low"` | OpenAI Responses 추론 강도입니다. Anthropic은 무시합니다. | | `maxDescriptionsPerTurn?` | `number` | `8` | 메인 턴당 허용되는 새 설명 캐시 미스 수입니다. `0`이면 호출이 비활성화되며, 잘못된 값은 기본값을 사용합니다. | | `timeoutMs?` | `number` | `45000` | 사이드카 fetch 제한 시간입니다. | -Vision은 provider의 `noVisionModels`에 속한 모델로 보낸 이미지에만 활성화됩니다. OpenAI는 검색과 같은 로그인/forward 요건을 갖고 있으며, 명시적으로 선택한 Anthropic은 사용할 수 있는 자격 증명이 없으면 닫힌 상태로 실패합니다. 성공한 `data:` 설명은 backend, model, detail, image bytes, 그리고 정규화된 메시지 컨텍스트를 키로 하는 bounded cache를 사용합니다. 히트와 같은 턴의 중복은 한도를 소모하지 않습니다. 원격 `https:` 이미지와 실패했거나 비어 있는 설명은 캐시하지 않습니다. +지원되는 수준은 업스트림 제공자의 역량과 선택한 모델이 공개한 추론 사다리에 따라 제한됩니다. Vision은 provider의 `noVisionModels`에 속한 모델로 보낸 이미지에만 활성화됩니다. OpenAI는 검색과 같은 로그인/forward 요건을 갖고 있으며, 명시적으로 선택한 Anthropic은 사용할 수 있는 자격 증명이 없으면 닫힌 상태로 실패합니다. 성공한 `data:` 설명은 backend, model, detail, image bytes, 그리고 정규화된 메시지 컨텍스트를 키로 하는 bounded cache를 사용합니다. OpenAI 키에는 reasoning effort도 포함됩니다(Anthropic 키에는 없습니다). 히트와 같은 턴의 중복은 한도를 소모하지 않습니다. 원격 `https:` 이미지와 실패했거나 비어 있는 설명은 캐시하지 않습니다. Anthropic OAuth 사이드카는 opencodex의 기존 Claude Code OAuth fingerprint를 재사용합니다. 의도한 계정과 워크로드로 소크 테스트를 수행합니다. diff --git a/docs-site/src/content/docs/ru/guides/sidecars.md b/docs-site/src/content/docs/ru/guides/sidecars.md index 861d4bb05..717707f0c 100644 --- a/docs-site/src/content/docs/ru/guides/sidecars.md +++ b/docs-site/src/content/docs/ru/guides/sidecars.md @@ -80,15 +80,21 @@ SSE-событие `response.failed`. Когда маршрутизируемая модель указана в `noVisionModels` своего провайдера, а запрос содержит изображение, opencodex описывает каждое изображение **до** основного вызова и заменяет его текстом. -Дашборд и API управления показывают `gpt-5.6-luna` как текущее значение по умолчанию, а при запуске -явно сохранённое устаревшее значение `gpt-5.4-mini` мигрирует на Luna. Если поле -`visionSidecar.model` полностью отсутствует, путь выполнения vision всё же имеет зашитый в код -фолбэк `gpt-5.4-mini`. +Если `visionSidecar.model` отсутствует или пуст, путь выполнения OpenAI, дашборд и API управления +используют фолбэк `gpt-5.4-mini`. При запуске явно сохранённое устаревшее значение +`gpt-5.4-mini` по-прежнему мигрирует на `gpt-5.6-luna`; миграция применяется только к сохранённому +значению, а не к отсутствующему полю модели. - Изображения могут приходить из сообщений пользователя, разработчика и результатов инструментов, включая `view_image` из Codex. -- Каждое изображение отправляется в настроенную нативную vision-модель с - `reasoning.effort: "low"`; полученное описание заменяет часть с изображением на месте. +- На пути OpenAI (passthrough с логином ChatGPT) каждое изображение отправляется в настроенную + vision-модель через endpoint Responses с выбранным `reasoning.effort` (по умолчанию `low`), и + полученное описание заменяет часть с изображением на месте. Путь Anthropic использует endpoint + Messages со своим mapping'ом thinking-бюджета и игнорирует эту специфичную для OpenAI настройку. +- Для нативных моделей с надёжными метаданными возможностей неподдерживаемый уровень нормализуется + к самому высокому поддерживаемому уровню, не превышающему запрошенный; если такого нет, + используется самый низкий поддерживаемый уровень. Неизвестные и пользовательские модели без + надёжных метаданных остаются без ограничений. - Описания выполняются с ограниченной параллельностью (по 3 одновременно, порядок входа сохраняется). Пользовательский контекст, передаваемый описывающей модели, ограничен 800 символами, а каждое внедряемое описание — 2 000 символами. Запрос не отправляет @@ -103,14 +109,16 @@ SSE-событие `response.failed`. - `maxDescriptionsPerTurn` (по умолчанию 8) ограничивает число новых описаний за один ход основной модели. Попадания в кэш и дубликаты в рамках того же хода лимит не расходуют. Успешные описания `data:`-изображений кэшируются по бэкенду, модели, детализации, байтам изображения и контексту - сообщения; изменяемые `https:`-изображения не кэшируются. + сообщения; в ключи OpenAI дополнительно входит уровень рассуждений (в ключи Anthropic — нет, + поскольку там это поле игнорируется). Изменяемые `https:`-изображения не кэшируются. ```json { "visionSidecar": { "enabled": true, - "backend": "anthropic", - "model": "claude-sonnet-5", + "backend": "openai", + "model": "gpt-5.6-luna", + "reasoning": "medium", "maxDescriptionsPerTurn": 8, "timeoutMs": 45000 } diff --git a/docs-site/src/content/docs/ru/reference/configuration/server.md b/docs-site/src/content/docs/ru/reference/configuration/server.md index 4fd226855..d36fa3383 100644 --- a/docs-site/src/content/docs/ru/reference/configuration/server.md +++ b/docs-site/src/content/docs/ru/reference/configuration/server.md @@ -179,14 +179,17 @@ routed-model и hosted-search timeout. Эффективный watchdog мост | `enabled?` | `boolean` | on when usable | Главный переключатель описания изображений. | | `backend?` | `"openai" \| "anthropic"` | auto | Та же логика выбора explicit-first/Anthropic-credential-aware, что и у web search. | | `model?` | `string` | backend-dependent | `gpt-5.4-mini` для OpenAI или `claude-sonnet-5` для Anthropic. | +| `reasoning?` | `"low" \| "medium" \| "high" \| "xhigh" \| "max"` | `"low"` | Уровень рассуждений OpenAI Responses. Anthropic его игнорирует. | | `maxDescriptionsPerTurn?` | `number` | `8` | Максимум новых промахов description-cache за один main turn. `0` отключает вызовы; некорректные значения возвращают дефолт. | | `timeoutMs?` | `number` | `45000` | Таймаут запроса sidecar'а. | -Vision включается только для изображений, отправленных в модель, входящую в `noVisionModels` её +Поддерживаемые уровни зависят от возможностей вышестоящего провайдера и заявленной лестницы +рассуждений выбранной модели. Vision включается только для изображений, отправленных в модель, входящую в `noVisionModels` её провайдера. У OpenAI требования по login/forward те же, что и у поиска; явный Anthropic без рабочего credential завершается ошибкой. Успешные описания `data:` используют ограниченный cache, ключ которого включает backend, model, detail, bytes изображения и нормализованный message -context. Попадания в cache и дубликаты в пределах одного turn'а не расходуют лимит. Удалённые +context; в ключи OpenAI дополнительно входит reasoning effort (в ключи Anthropic — нет). +Попадания в cache и дубликаты в пределах одного turn'а не расходуют лимит. Удалённые `https:`-изображения, а также пустые и неуспешные описания не кэшируются. Sidecar'ы Anthropic OAuth повторно используют уже существующий OAuth fingerprint Claude Code от diff --git a/docs-site/src/content/docs/zh-cn/guides/sidecars.md b/docs-site/src/content/docs/zh-cn/guides/sidecars.md index 1b49584b1..136d27d2d 100644 --- a/docs-site/src/content/docs/zh-cn/guides/sidecars.md +++ b/docs-site/src/content/docs/zh-cn/guides/sidecars.md @@ -64,13 +64,16 @@ Anthropic OAuth provider。Sidecar 错误会转换成长度受限的工具结果 ## Vision sidecar 当路由模型列在其 provider 的 `noVisionModels` 中,并且请求包含图像时,opencodex 会在主调用 -**之前**描述每张图像,并用文字替换图像。Dashboard 和管理 API 当前显示的默认值是 -`gpt-5.6-luna`,启动时也会把明确保存的旧 `gpt-5.4-mini` 值迁移到 Luna。只有在 -`visionSidecar.model` 字段完全不存在时,vision 执行路径才会使用代码中的 `gpt-5.4-mini` 回退值。 +**之前**描述每张图像,并用文字替换图像。当 `visionSidecar.model` 缺失或为空时,OpenAI 执行路径、 +Dashboard 和管理 API 都使用 `gpt-5.4-mini` 作为回退。启动时仍会把明确保存的旧 +`gpt-5.4-mini` 值迁移到 `gpt-5.6-luna`;该迁移只作用于已保存值,不适用于缺失的 model 字段。 - 图像可以来自 user、developer 和 tool-result message,也包括 Codex 的 `view_image` 结果。 -- 每张图像会以 `reasoning.effort: "low"` 发送给配置的原生 vision 模型,描述结果会就地替换 - 图像部分。 +- OpenAI 路径(ChatGPT 登录透传)会通过 Responses 端点把每张图像发送给配置的视觉模型,并携带所选 + 的 `reasoning.effort`(默认为 `low`),描述结果就地替换图像部分。Anthropic 路径走 Messages + 端点并使用自己的思考预算映射,会忽略这个 OpenAI 专用设置。 +- 对于具有可靠能力元数据的原生模型,不支持的推理等级会归一化到不高于请求值的最高支持档位;如果 + 不存在这样的档位,则使用最低支持档位。对于缺少可靠能力元数据的未知模型或自定义模型,保持宽松处理。 - 描述任务最多同时处理 3 张图像,并保持输入顺序。发送给描述模型的用户上下文最多 800 个字符, 每张图像注入的描述最多 2,000 个字符。请求不会发送 ChatGPT 后端不支持的 `max_output_tokens`。 @@ -83,14 +86,16 @@ Anthropic OAuth provider。Sidecar 错误会转换成长度受限的工具结果 移除,而不会继续转发给纯文本后端。 - `maxDescriptionsPerTurn`(默认 8)限制每个主模型 turn 的新增描述次数。缓存命中和同一 turn 的重复请求不会消耗配额。成功的 `data:` 图像描述会按后端、模型、detail、图像字节和消息上下文 - 缓存;内容可变的 `https:` 图像不会缓存。 + 缓存;OpenAI 的缓存键还会额外包含推理强度(Anthropic 键不含,因为该字段在那里被忽略)。 + 内容可变的 `https:` 图像不会缓存。 ```json { "visionSidecar": { "enabled": true, - "backend": "anthropic", - "model": "claude-sonnet-5", + "backend": "openai", + "model": "gpt-5.6-luna", + "reasoning": "medium", "maxDescriptionsPerTurn": 8, "timeoutMs": 45000 } diff --git a/docs-site/src/content/docs/zh-cn/reference/configuration/server.md b/docs-site/src/content/docs/zh-cn/reference/configuration/server.md index e3c530cc1..5da45c40f 100644 --- a/docs-site/src/content/docs/zh-cn/reference/configuration/server.md +++ b/docs-site/src/content/docs/zh-cn/reference/configuration/server.md @@ -159,9 +159,10 @@ routed 重放会把主 ChatGPT 认证注入内部请求。Anthropic 后端使用 | `enabled?` | `boolean` | 在可用时启用 | 图像描述总开关。 | | `backend?` | `"openai" \| "anthropic"` | auto | 与 web search 相同的显式优先、感知 Anthropic 凭据的选择方式。 | | `model?` | `string` | 依后端而定 | OpenAI 使用 `gpt-5.4-mini`,Anthropic 使用 `claude-sonnet-5`。 | +| `reasoning?` | `"low" \| "medium" \| "high" \| "xhigh" \| "max"` | `"low"` | OpenAI Responses 推理强度;Anthropic 会忽略该项。 | | `maxDescriptionsPerTurn?` | `number` | `8` | 每个主轮次允许的新增描述缓存未命中次数。`0` 会禁用调用;无效值会使用默认值。 | | `timeoutMs?` | `number` | `45000` | 侧车获取超时。 | -Vision 只会对发送给其提供方 `noVisionModels` 中模型的图像生效。OpenAI 具有与 search 相同的登录/forward 要求;显式选择的 Anthropic 在没有可用凭据时会失败并关闭。成功的 `data:` 描述会使用一个受限缓存,其键由后端、模型、detail、图像字节以及规范化消息上下文组成。命中和同轮重复不会消耗限额。远程 `https:` 图像以及失败或空的描述不会被缓存。 +支持的等级受上游提供方能力与所选模型公布的推理阶梯限制。Vision 只会对发送给其提供方 `noVisionModels` 中模型的图像生效。OpenAI 具有与 search 相同的登录/forward 要求;显式选择的 Anthropic 在没有可用凭据时会失败并关闭。成功的 `data:` 描述会使用一个受限缓存,其键由后端、模型、detail、图像字节以及规范化消息上下文组成;OpenAI 的键还会额外包含推理强度(Anthropic 键不含)。命中和同轮重复不会消耗限额。远程 `https:` 图像以及失败或空的描述不会被缓存。 Anthropic OAuth 侧车会复用 opencodex 现有的 Claude Code OAuth 指纹。请对目标账户和负载进行 soak 测试。 diff --git a/gui/src/i18n/vision-reasoning-labels.ts b/gui/src/i18n/vision-reasoning-labels.ts new file mode 100644 index 000000000..2a9d5f43c --- /dev/null +++ b/gui/src/i18n/vision-reasoning-labels.ts @@ -0,0 +1,17 @@ +import type { Locale } from "./shared"; + +export type VisionReasoningLabelLevel = "low" | "medium" | "high" | "xhigh" | "max"; + +const VISION_REASONING_LABELS = { + en: { low: "Low", medium: "Medium", high: "High", xhigh: "Extra high", max: "Maximum" }, + de: { low: "Niedrig", medium: "Mittel", high: "Hoch", xhigh: "Sehr hoch", max: "Maximum" }, + ko: { low: "낮음", medium: "보통", high: "높음", xhigh: "매우 높음", max: "최대" }, + zh: { low: "低", medium: "中", high: "高", xhigh: "极高", max: "最大" }, + ru: { low: "Низкий", medium: "Средний", high: "Высокий", xhigh: "Очень высокий", max: "Максимальный" }, + ja: { low: "低", medium: "中", high: "高", xhigh: "非常に高い", max: "最大" }, +} satisfies Record>; + +/** Localized display label for the wire-level vision reasoning value. */ +export function visionReasoningLabel(locale: Locale, level: VisionReasoningLabelLevel): string { + return VISION_REASONING_LABELS[locale][level]; +} diff --git a/gui/src/pages/dashboard-overview-sections.tsx b/gui/src/pages/dashboard-overview-sections.tsx index 1b74a7021..f62403a88 100644 --- a/gui/src/pages/dashboard-overview-sections.tsx +++ b/gui/src/pages/dashboard-overview-sections.tsx @@ -1,10 +1,11 @@ import { useEffect, useRef, useState } from "react"; import { IconAlert, IconCheck, IconInfo, IconRefresh, IconX } from "../icons"; import { Trans } from "../i18n/provider"; +import { visionReasoningLabel } from "../i18n/vision-reasoning-labels"; import { Select } from "../ui"; import { formatNamespacedModelId } from "../provider-icons"; import { navigateHash } from "../hash-routing"; -import { EFFORT_CAP_LEVELS, requireJson, shadowCallModelOptions, sidecarBackendForModel, updateJobLabel } from "./dashboard-shared"; +import { clampVisionReasoningToLadder, EFFORT_CAP_LEVELS, requireJson, shadowCallModelOptions, sidecarBackendForModel, updateJobLabel, visionReasoningLadder, visionReasoningOptionsFor, visionReasoningPatch } from "./dashboard-shared"; import { shadowSourceModelBadge } from "./shadow-call-source"; import type { useDashboardData } from "./use-dashboard-data"; @@ -91,14 +92,6 @@ export function DashboardEffortCapPanel({ apiBase, d }: { apiBase: string; d: Da ); } -/** - * Delegation row: pick the model (and effort) inline, with a link to the rest. - * - * The two switches moved to the Subagents tab, which is where the roster they affect lives. - * The model pick stays: it is the same shape as the sidecar rows below it (label left, - * dropdown right), and it is the one delegation choice worth changing without leaving the - * status page. - */ export function DashboardInjectionPanel({ d }: { apiBase: string; d: Dash }) { const { t, injectionModel, injectionEffort, injectionEfforts, injectionAvailable, injectionSaving, @@ -131,11 +124,7 @@ export function DashboardInjectionPanel({ d }: { apiBase: string; d: Dash }) { label={t("dash.injectionEffortLabel")} /> )} - @@ -148,23 +137,11 @@ export function DashboardMaintenancePanel({ d }: { d: Dash }) { t, runSync, syncing, updateTriggerRef, openUpdateDialog, updateLoading, updateOpen, syncResult, syncError, updateJob, reconnecting, clearSyncFeedback, } = d; - - // A sync result that carries actionable guidance (generic warning, native subagent - // defaults override, or the stale app-server hint) is the ONLY place that warning is - // visible, so it must not vanish on a timer: it stays until the next sync or an - // explicit dismiss. const syncHoldsWarning = !!syncResult && ( !!syncResult.warning || !!syncResult.nativeSubagentDefaultsWarning || !!syncResult.staleAppServerHint ); - - // Sync feedback is a transient fixed toast instead of an inline notice: the toast sits - // outside the layout flow, so the result can appear without pushing the panels below - // this card down by a full box height (the old notice shifted the whole dashboard on - // every sync click). Plain results auto-dismiss; a new sync clears and re-arms it. - // Dismissal is published to the dashboard data (clearSyncFeedback), not just a local - // flag, so switching tabs and back cannot resurrect a stale result as a fresh toast. const [syncToastDismissed, setSyncToastDismissed] = useState(false); const syncToastTimerRef = useRef | null>(null); @@ -186,14 +163,11 @@ export function DashboardMaintenancePanel({ d }: { d: Dash }) { }; }, [syncResult, syncError, syncHoldsWarning, clearSyncFeedback]); - // A fresh click re-arms the toast even if the previous one was already auto-dismissed. const handleRunSync = () => { setSyncToastDismissed(false); void runSync(); }; - // Shared dismiss affordance for the sync toast: closes it locally AND clears the - // dashboard-level result so it cannot remount as fresh on the next Overview visit. const dismissSyncToast = () => { setSyncToastDismissed(true); clearSyncFeedback(); @@ -202,7 +176,6 @@ export function DashboardMaintenancePanel({ d }: { d: Dash }) { return ( <>
- {/* Same one-row chrome as Sub-agent delegation: copy left, action right. */}
{t("dash.syncModels")}
@@ -212,13 +185,6 @@ export function DashboardMaintenancePanel({ d }: { d: Dash }) { - {/* - The update flow lives in the sidebar footer, which reports whether one is waiting - and is reachable from every page. A second button here duplicated it without - adding that signal. The trigger stays as a zero-size anchor so the deep link - (`#dashboard/update`) still has something to open against and the dialog has a - focus target to return to on close. - */}