Skip to content

Commit 2f684aa

Browse files
zhou-zhichaolidge-jun
authored andcommitted
fix(images): fail closed when Imagine OAuth is missing
When images.bridgeEnabled is on and the xAI provider has no Grok token, return 400 instead of silently billing ChatGPT. Document the /v1/images OAuth relay on the ja/ko/ru/zh-cn image-bridge pages.
1 parent 2a36e2b commit 2f684aa

12 files changed

Lines changed: 78 additions & 13 deletions

File tree

docs-site/src/content/docs/guides/codex-integration.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,8 @@ Standalone `/images/generations` calls never enter that bridge.
5858
- **xAI Imagine (Grok OAuth) relay:** when `images.bridgeEnabled` is `true` and an `xai` provider
5959
has a usable Grok CLI OAuth token (`ocx login xai`) or API key, `/v1/images/generations` and
6060
`/v1/images/edits` are sent to `https://api.x.ai/v1` with that token. ChatGPT credentials are
61-
not forwarded. The relay maps Codex `size` / `aspect_ratio` onto xAI's Imagine body and returns
61+
not forwarded. If the token is missing, the proxy returns 400 instead of billing ChatGPT.
62+
The relay maps Codex `size` / `aspect_ratio` onto xAI's Imagine body and returns
6263
the same `{created, data:[{b64_json}]}` shape. Combined decoded bytes and base64-encoded output
6364
across the batch (inline `b64_json` and downloaded URLs) stay under 100 MiB; a batch that would
6465
exceed that cap returns 502. This is independent of the Responses Image Bridge loop (which

docs-site/src/content/docs/guides/image-bridge.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ xAI Grok Imagine, so the model you're actually chatting with can still generate
2020
The same `bridgeEnabled` flag does arm the separate Codex `/v1/images` relay so the built-in
2121
`image_gen` client can call Imagine with the Grok CLI grant — see
2222
[Built-in image generation](/guides/codex-integration/#built-in-image-generation-image_gen).
23+
If that grant (or an xAI API key) is missing, `/v1/images` returns an error instead of
24+
falling through to ChatGPT.
2325

2426
```json
2527
{

docs-site/src/content/docs/ja/guides/codex-integration.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ Codex の組み込み `image_gen` ツールは、`/v1/responses` を経由しま
4040
失敗。壊れた/期限切れのプール認証情報が、別途請求される API 使用量の背後に隠れることはありません。
4141
- **明示的なカスタム プロバイダー:** `images.provider` をカスタム API キーの ID に設定します。
4242
`openai-responses` プロバイダー。そのエンドポイントは OpenAI Images API を実装します。明示的な選択はクローズに失敗し、別の有料アップストリームにフォールバックすることはありません。レジストリで管理されているプロバイダー ID はここでは受け入れられません。組み込みの OpenAI 層を使用するには、`images.provider` を省略します。
43-
- **xAI Imagine (Grok OAuth) リレー:** `images.bridgeEnabled``true` で、`xai` プロバイダーに利用可能な Grok CLI OAuth トークン(`ocx login xai`)または API キーがある場合、`/v1/images/generations``/v1/images/edits` はそのトークン付きで `https://api.x.ai/v1` に送られます。ChatGPT の資格情報は転送されません。リレーは Codex の `size` / `aspect_ratio` を xAI Imagine のボディに写し、同じ `{created, data:[{b64_json}]}` 形を返します。バッチ全体(インライン `b64_json` とダウンロードした URL)のデコード済みバイトと base64 エンコード出力は合わせて 100 MiB 未満です。上限を超えるバッチは 502 を返します。これは API キー専用の Responses Image Bridge ループとは独立です。
43+
- **xAI Imagine (Grok OAuth) リレー:** `images.bridgeEnabled``true` で、`xai` プロバイダーに利用可能な Grok CLI OAuth トークン(`ocx login xai`)または API キーがある場合、`/v1/images/generations``/v1/images/edits` はそのトークン付きで `https://api.x.ai/v1` に送られます。ChatGPT の資格情報は転送されません。トークンが無い場合、プロキシは ChatGPT に課金せず 400 を返します。リレーは Codex の `size` / `aspect_ratio` を xAI Imagine のボディに写し、同じ `{created, data:[{b64_json}]}` 形を返します。バッチ全体(インライン `b64_json` とダウンロードした URL)のデコード済みバイトと base64 エンコード出力は合わせて 100 MiB 未満です。上限を超えるバッチは 502 を返します。これは API キー専用の Responses Image Bridge ループとは独立です。
4444
- **Google Antigravity (CCA) フォールバック:** OpenAI 前方候補でもキー付きでもない場合
4545
プロバイダーが構成されている場合、`/v1/images/generations` (`/images/edits` ではありません) は、`gemini-3.1-flash-image` モデルを使用して Antigravity **Cloud Code Assist** エンドポイントにフォールバックします。フォールバックは、OpenAI 候補が構成されていない場合だけでなく、OpenAI 認証の解決が失敗した後 (ChatGPT 資格情報の期限切れまたは欠落など) にも起動されます。これには `ocx login google-antigravity` が必要です。 OAuth トークンは、固定された CCA レジストリ ホストにのみ送信され、構成レベルの `baseUrl` オーバーライドには送信されません。応答は、Codex が期待するのと同じ `{created, data:[{b64_json}]}` 形状で返されます。
4646
- **どちらでもない:** プロキシは一般的な 404 ではなく明確なエラーを返します。 ルーティングされたプロバイダー

docs-site/src/content/docs/ja/guides/image-bridge.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ OpenAI 以外のモデル (Claude、Gemini、Grok など) を介して Codex を
1212
- **設定で `images.bridgeEnabled: true` を設定してブリッジを有効にします** (これはオフになっています)
1313
予期しない xAI 請求を避けるためのデフォルト — 以下の [構成](#configuration) を参照してください)。
1414
- **API キー**を持つ `xai` プロバイダー エントリ。ブリッジはフルフィルメントをレジストリ xAI に固定します
15-
画像エンドポイント (`https://api.x.ai/v1`);設定された `baseUrl` オーバーライドは、イメージ呼び出しでは無視されます。 OAuth / `ocx login xai` だけではブリッジを準備しません** (Grok CLI OAuth トランスポートはチャット指向であり`/images/*` には使用されません)
15+
画像エンドポイント (`https://api.x.ai/v1`);設定された `baseUrl` オーバーライドは、イメージ呼び出しでは無視されます。 OAuth / `ocx login xai` だけではこのサイドカー・ループは有効になりません。同じ `bridgeEnabled` フラグは、別系統の Codex `/v1/images` リレーを有効にし、組み込みの `image_gen` クライアントが Grok CLI の認可で Imagine を呼べるようにします。認可(または xAI API キー)が無い場合`/v1/images` は ChatGPT にフォールスルーせずエラーを返します。詳細は [組み込み画像生成](/guides/codex-integration/#built-in-image-generation-image_gen) を参照してください
1616

1717
`json { "providers": { "xai": { "adapter": "openai-chat", "apiKey": "xai-…", "authMode": "key" } } } `
1818

docs-site/src/content/docs/ko/guides/codex-integration.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ Codex의 내장 `image_gen` 도구는 `/v1/responses`를 거치지 않습니다.
3737
- **모드 인식 forward 후보 하나:** Pool은 적격한 메인/추가 계정을 선택하고, Direct는 호출자 OAuth bearer를 사용합니다. 설정된 모드는 이미지 요청에도 일관되게 적용됩니다.
3838
- **OpenAI API-key provider:** forward 후보 중 누구도 인증 실패를 가지지 않을 때만 사용합니다. 고장 나거나 만료된 Pool credential을 별도로 청구되는 API 사용 뒤에 숨기지 않습니다.
3939
- **명시적 커스텀 provider:** `images.provider`를 OpenAI Images API를 구현한 커스텀 API-key `openai-responses` provider id로 설정할 수 있습니다. 명시적으로 선택한 provider는 닫힌 상태로 실패하며, 다른 유료 upstream으로 fallback하지 않습니다. registry-managed provider id는 여기서 허용하지 않습니다. 기본 제공 OpenAI tiers를 쓰려면 `images.provider`를 생략하세요.
40-
- **xAI Imagine (Grok OAuth) relay:** `images.bridgeEnabled``true`이고 `xai` provider에 사용 가능한 Grok CLI OAuth 토큰(`ocx login xai`) 또는 API key가 있으면 `/v1/images/generations``/v1/images/edits`가 그 토큰으로 `https://api.x.ai/v1`에 전송됩니다. ChatGPT credential은 전달되지 않습니다. relay는 Codex `size` / `aspect_ratio`를 xAI Imagine body에 매핑하고 같은 `{created, data:[{b64_json}]}` 형태를 반환합니다. 배치 전체(인라인 `b64_json`과 내려받은 URL)의 디코드 바이트와 base64 인코드 출력은 합쳐서 100 MiB 미만입니다. 한도를 넘는 배치는 502를 반환합니다. 이 경로는 API-key-only Responses Image Bridge 루프와 별개입니다.
40+
- **xAI Imagine (Grok OAuth) relay:** `images.bridgeEnabled``true`이고 `xai` provider에 사용 가능한 Grok CLI OAuth 토큰(`ocx login xai`) 또는 API key가 있으면 `/v1/images/generations``/v1/images/edits`가 그 토큰으로 `https://api.x.ai/v1`에 전송됩니다. ChatGPT credential은 전달되지 않습니다. 토큰이 없으면 프록시는 ChatGPT에 과금하지 않고 400을 반환합니다. relay는 Codex `size` / `aspect_ratio`를 xAI Imagine body에 매핑하고 같은 `{created, data:[{b64_json}]}` 형태를 반환합니다. 배치 전체(인라인 `b64_json`과 내려받은 URL)의 디코드 바이트와 base64 인코드 출력은 합쳐서 100 MiB 미만입니다. 한도를 넘는 배치는 502를 반환합니다. 이 경로는 API-key-only Responses Image Bridge 루프와 별개입니다.
4141
- **Google Antigravity (CCA) fallback:** OpenAI forward 후보도 keyed provider도 없을 때, `/v1/images/generations`(`/images/edits`는 제외)는 `gemini-3.1-flash-image` 모델을 사용해서 Antigravity **Cloud Code Assist** endpoint로 fallback합니다. OpenAI 인증 해석이 실패할 때(예: 만료되었거나 누락된 ChatGPT credential)에도 이 fallback이 동작하며, OpenAI 후보가 아예 없을 때만 발생하는 것은 아닙니다. 이 기능은 `ocx login google-antigravity`를 필요로 합니다. OAuth token은 오직 고정된 CCA registry host로만 전송되며, config-level `baseUrl` override로는 가지 않습니다. 응답은 Codex가 기대하는 `{created, data:[{b64_json}]}` 형식으로 반환됩니다.
4242
- **둘 다 없음:** 프록시는 generic 404 대신 명확한 오류를 반환합니다. 라우팅되는 provider(Cursor, Gemini, Kiro 등)는 `image_generation` tool relay를 제공할 수 없습니다. 이 도구를 아예 노출하고 싶지 않다면 Codex에서 `codex features disable image_generation`(`config.toml``[features] image_generation = false`)으로 끄세요.
4343

docs-site/src/content/docs/ko/guides/image-bridge.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ Codex를 Claude, Gemini, Grok 같은 OpenAI가 아닌 모델로 라우팅하면
1010
## 사전 조건
1111

1212
- 구성에서 `images.bridgeEnabled: true`로 설정해 브리지를 켭니다. 예상치 못한 xAI 요금을 피하려고 기본값은 꺼져 있습니다. 아래 [Configuration](#configuration)을 참고합니다.
13-
- API 키가 있는 `xai` provider 항목이 필요합니다. 브리지는 처리를 레지스트리의 xAI Images endpoint (`https://api.x.ai/v1`)에 고정하며, 이미지 호출에서는 설정된 `baseUrl` override를 무시합니다. OAuth / `ocx login xai`만으로는 브리지가 활성화되지 않습니다. Grok CLI OAuth transport는 채팅용이며 `/images/*`에는 사용되지 않습니다.
13+
- API 키가 있는 `xai` provider 항목이 필요합니다. 브리지는 처리를 레지스트리의 xAI Images endpoint (`https://api.x.ai/v1`)에 고정하며, 이미지 호출에서는 설정된 `baseUrl` override를 무시합니다. OAuth / `ocx login xai`만으로는 이 sidecar 루프가 켜지지 않습니다. 같은 `bridgeEnabled` 플래그는 별도의 Codex `/v1/images` relay를 켜서, 내장 `image_gen` 클라이언트가 Grok CLI grant로 Imagine을 호출할 수 있게 합니다. 그 grant(또는 xAI API key)가 없으면 `/v1/images`는 ChatGPT로 넘어가지 않고 오류를 반환합니다. [Built-in image generation](/guides/codex-integration/#built-in-image-generation-image_gen)을 참고하세요.
1414

1515
```json
1616
{

docs-site/src/content/docs/ru/guides/codex-integration.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ reference-image), используя тот же bearer ChatGPT, что и дл
5959
провал жёсткий: никакого fallback на другой платный upstream нет. Id провайдера, управляемые
6060
registry, здесь не принимаются; если хотите использовать встроенные уровни OpenAI, опустите
6161
`images.provider`.
62-
- **Relay xAI Imagine (Grok OAuth):** если `images.bridgeEnabled` равно `true` и у провайдера `xai` есть действующий OAuth-токен Grok CLI (`ocx login xai`) или API-ключ, `/v1/images/generations` и `/v1/images/edits` уходят на `https://api.x.ai/v1` с этим токеном. Учётные данные ChatGPT не пересылаются. Relay отображает Codex `size` / `aspect_ratio` на тело Imagine и возвращает ту же форму `{created, data:[{b64_json}]}`. Суммарные декодированные байты и base64-выход партии (inline `b64_json` и скачанные URL) остаются ниже 100 MiB; превышение даёт 502. Это отдельно от цикла Responses Image Bridge, который по-прежнему только с API-ключом.
62+
- **Relay xAI Imagine (Grok OAuth):** если `images.bridgeEnabled` равно `true` и у провайдера `xai` есть действующий OAuth-токен Grok CLI (`ocx login xai`) или API-ключ, `/v1/images/generations` и `/v1/images/edits` уходят на `https://api.x.ai/v1` с этим токеном. Учётные данные ChatGPT не пересылаются. Если токена нет, прокси возвращает 400 и не тарифицирует ChatGPT. Relay отображает Codex `size` / `aspect_ratio` на тело Imagine и возвращает ту же форму `{created, data:[{b64_json}]}`. Суммарные декодированные байты и base64-выход партии (inline `b64_json` и скачанные URL) остаются ниже 100 MiB; превышение даёт 502. Это отдельно от цикла Responses Image Bridge, который по-прежнему только с API-ключом.
6363
- **Fallback Google Antigravity (CCA):** если не настроен ни один OpenAI forward-candidate и ни
6464
один keyed provider, `/v1/images/generations` (но не `/images/edits`) переходит на endpoint
6565
Antigravity **Cloud Code Assist** с моделью `gemini-3.1-flash-image`. Этот fallback также

docs-site/src/content/docs/ru/guides/image-bridge.md

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,12 @@ Image Bridge обнаруживает такие вызовы и прозрач
1616
чтобы не создавать неожиданных расходов xAI — см. [Конфигурацию](#configuration) ниже).
1717
- Нужна запись провайдера `xai` с **API-ключом**. Bridge жёстко привязывает выполнение к
1818
registry-endpoint'у xAI Images (`https://api.x.ai/v1`); любой настроенный override `baseUrl`
19-
для image-вызовов игнорируется. Одного OAuth / `ocx login xai` для активации bridge
20-
недостаточно (OAuth-транспорт Grok CLI ориентирован на чат и не используется для `/images/*`).
19+
для image-вызовов игнорируется. Одного OAuth / `ocx login xai` недостаточно, чтобы
20+
включить этот sidecar-цикл. Тот же флаг `bridgeEnabled` включает отдельный relay Codex
21+
`/v1/images`, чтобы встроенный клиент `image_gen` мог вызывать Imagine с grant'ом Grok CLI —
22+
см. [Встроенную генерацию изображений](/guides/codex-integration/#built-in-image-generation-image_gen).
23+
Если grant (или API-ключ xAI) отсутствует, `/v1/images` возвращает ошибку и не
24+
переходит на ChatGPT.
2125

2226
```json
2327
{

docs-site/src/content/docs/zh-cn/guides/codex-integration.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ ChatGPT bearer auth。由于注入的 `base_url` 指向 opencodex,proxy 会把
5454
`openai-responses` provider 的 id,该 endpoint 必须实现 OpenAI Images API。显式选择会失败即关闭,
5555
不会 fallback 到其他付费上游。这里不接受 registry 管理的 provider id;省略 `images.provider`
5656
即可使用内置的 OpenAI tiers。
57-
- **xAI Imagine(Grok OAuth)中继:**`images.bridgeEnabled``true`,且 `xai` provider 有可用的 Grok CLI OAuth token(`ocx login xai`)或 API key 时,`/v1/images/generations``/v1/images/edits` 会带着该 token 发到 `https://api.x.ai/v1`。ChatGPT 凭据不会被转发。该中继会把 Codex 的 `size` / `aspect_ratio` 映射到 xAI Imagine 请求体,并返回同样的 `{created, data:[{b64_json}]}` 形状。整批(inline `b64_json` 与下载的 URL)解码字节与 base64 编码输出合计不超过 100 MiB;超出则返回 502。这与仍仅支持 API key 的 Responses Image Bridge 循环相互独立。
57+
- **xAI Imagine(Grok OAuth)中继:**`images.bridgeEnabled``true`,且 `xai` provider 有可用的 Grok CLI OAuth token(`ocx login xai`)或 API key 时,`/v1/images/generations``/v1/images/edits` 会带着该 token 发到 `https://api.x.ai/v1`。ChatGPT 凭据不会被转发。若 token 缺失,代理返回 400,而不会向 ChatGPT 计费。该中继会把 Codex 的 `size` / `aspect_ratio` 映射到 xAI Imagine 请求体,并返回同样的 `{created, data:[{b64_json}]}` 形状。整批(inline `b64_json` 与下载的 URL)解码字节与 base64 编码输出合计不超过 100 MiB;超出则返回 502。这与仍仅支持 API key 的 Responses Image Bridge 循环相互独立。
5858
- **Google Antigravity(CCA)fallback:** 当既没有 OpenAI forward 候选,也没有已配置的 keyed
5959
provider 时,`/v1/images/generations`(不是 `/images/edits`)会 fallback 到 Antigravity
6060
**Cloud Code Assist** endpoint,并使用 `gemini-3.1-flash-image` 模型。该 fallback 也会在

docs-site/src/content/docs/zh-cn/guides/image-bridge.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ description: 在使用非 OpenAI 提供方时,将 image_generation 托管工
1010
## 前提条件
1111

1212
- **启用桥接**:在配置中设置 `images.bridgeEnabled: true`(默认关闭,以避免意外产生 xAI 费用 - 见下文的 [配置](#configuration))。
13-
- 配置一个带有 **API 密钥**`xai` provider 条目。桥接会将执行固定到注册表中的 xAI Images 端点(`https://api.x.ai/v1`);任何已配置的 `baseUrl` 覆盖都会被图像调用忽略。仅有 OAuth / `ocx login xai` **不会** 让桥接生效(Grok CLI 的 OAuth 传输是面向聊天的,不用于 `/images/*`
13+
- 配置一个带有 **API 密钥**`xai` provider 条目。桥接会将执行固定到注册表中的 xAI Images 端点(`https://api.x.ai/v1`);任何已配置的 `baseUrl` 覆盖都会被图像调用忽略。仅有 OAuth / `ocx login xai` **不会** 启用这条 sidecar 循环。同一项 `bridgeEnabled` 会启用另一条 Codex `/v1/images` 中继,让内置 `image_gen` 客户端用 Grok CLI 授权调用 Imagine — 见 [内置图像生成](/guides/codex-integration/#built-in-image-generation-image_gen)。若该授权(或 xAI API key)缺失,`/v1/images` 会返回错误,而不会落到 ChatGPT
1414

1515
```json
1616
{

0 commit comments

Comments
 (0)