Skip to content

Google AI Studio model discovery rejects native models[] envelope #3926

Closed

Description

@DaveW001

Client or integration

Codex CLI

Provider or upstream service

Google Gemini API / AI Studio

OpenCodex version

2.41.0 installed. I also checked the v2.46.0 tagged source.

Endpoint or capability

Model discovery: GET https://generativelanguage.googleapis.com/v1beta/models?pageSize=1000

Current behaviour

Every catalog sync reports Google discovery as malformed even though the API returns HTTP 200. OpenCodex then falls back to the configured static catalog:

[opencodex] Provider model discovery for "google" returned malformed 2xx data [status=200, contentType=application/json, urlClass=provider-models, fallback=configured].

The provider connection test accepts the same response and reports 54 available models. Authoritative catalog discovery does not: it accepts only a top-level array or data[], while Google AI Studio returns models[]. The result is a split behavior where the same response proves connectivity but cannot update the catalog.

Expected behaviour

For Google AI Studio, OpenCodex should treat the native models[] response as an authoritative catalog source. I would expect it to strip the models/ prefix from name, filter to rows that support generateContent, and use fields such as inputTokenLimit and outputTokenLimit for catalog metadata.

Vertex and Cloud Code Assist can keep their current discovery behavior. If authoritative parsing is intentionally out of scope, the connection test and sync logs should use the same vocabulary and status so the provider is not shown as connected while discovery calls its successful response malformed.

Minimal redacted request or reproduction

export GEMINI_API_KEY='<redacted>'

curl -sS -D - \
  -H "x-goog-api-key: $GEMINI_API_KEY" \
  'https://generativelanguage.googleapis.com/v1beta/models?pageSize=1000'

ocx sync
ocx provider test google --json
ocx models live --provider google --json

Actual response or error

HTTP/1.1 200 OK
content-type: application/json; charset=UTF-8

{
  "models": [
    {
      "name": "models/gemini-2.5-flash",
      "inputTokenLimit": "<redacted>",
      "outputTokenLimit": "<redacted>",
      "supportedGenerationMethods": [
        "generateContent",
        "countTokens"
      ]
    }
  ]
}

The response had one top-level property, models, and 54 rows. The first row exposed name, token limits, supportedGenerationMethods, and display metadata. I removed values and nonessential fields.

Upstream documentation

https://ai.google.dev/api/models

Suggested mapping or implementation notes

The connection-test path already reads models[] for a count, so it may be possible to share a Google-specific normalization step with catalog discovery. The mapping should be scoped to AI Studio mode so Vertex and Antigravity keep their existing parsers.

Additional context and attachments

Closed PR #55 described this exact response-shape mismatch, and the maintainer comment said the stabilization branch handled models[], response parsing, context hints, and pageSize=1000. I still see the authoritative catalog reject that envelope in v2.46.0 source. Related catalog-discovery work is #406 and #652.

Checks

  • I searched existing provider and compatibility issues.
  • The request and response were redacted.
  • The expected behaviour is based on an upstream specification or a concrete client requirement.

Activity

  1. lidge-jun commented on Sep 7, 2026

    @lidge-jun
    Owner

    리뷰 · 우선순위 62 / 80

    이 이슈는 Google AI Studio(Gemini API) 모델 목록을 가져올 때, 연결 테스트는 성공하는데 카탈로그 동기화는 “형태가 이상하다”고 실패하는 갈라짐을 말합니다. 재현 경로는 GET https://generativelanguage.googleapis.com/v1beta/models?pageSize=1000 이고, 응답은 HTTP 200에 최상위 키가 models 배열인 JSON입니다. 각 행은 name(예: models/gemini-2.5-flash), 토큰 한도, supportedGenerationMethods 같은 필드를 가집니다. 보고자는 OpenCodex 2.41.0과 태그된 2.46.0 소스에서도 같은 로그를 봤다고 적었습니다: Provider model discovery for "google" returned malformed 2xx data ... fallback=configured. 그 결과 라이브 카탈로그는 갱신되지 않고, 설정에 박혀 있는 정적 Google 목록으로 떨어집니다. 반면 ocx provider test google 는 같은 응답으로 “54개 모델 연결됨”처럼 통과합니다.

    지금 dev(HEAD 09f669a75, package 2.48.0, tip #3925로 open-dev)를 보면 이 갈라짐은 우연이 아니라 코드에 적힌 경계입니다. 카탈로그 쪽 src/codex/catalog/provider-fetch.ts 는 성공 응답을 extractProviderModelItems(src/providers/model-discovery.ts)로만 해석합니다. 그 함수는 최상위 배열이거나 OpenAI식 data[] 봉투만 인정하고, 단독 models[] 는 invalid_shape → “malformed 2xx data” 로 떨어뜨립니다. 주석에도 openai-chat 응답의 떠도는 models 키를 권위 목록으로 쓰지 말라고 적혀 있습니다. 반대로 연결 테스트 src/server/management/provider-routes.ts 는 의도적으로 Google /v1beta/models 의 models[].name 을 “연결만 세는 용도”로 읽고, “권위 있는 카탈로그 소스가 아니다”라고 주석으로 못 박아 둡니다. 레지스트리의 google 시드(src/providers/registry.ts)는 이미 gemini-3.x 정적 목록·컨텍스트·모달리티를 갖고 있어서, 발견이 실패해도 제품이 완전히 비지는 않습니다. Vertex(googleMode: "vertex")와 Antigravity/CCA는 각자 다른 경로를 탑니다.

    그래서 이 티켓의 핵심은 “파서가 버그로 models[] 를 못 읽는다”가 아니라, “AI Studio 네이티브 봉투를 권위 카탈로그로 올릴지”를 아직 열지 않았다는 설계 결정입니다. 닫힌 #55 와 #406/#652 계열 카탈로그 작업이 예전에 비슷한 모양을 다뤘다는 맥락도 본문에 있습니다. 요청하신 매핑(이름에서 models/ 접두 제거, generateContent 지원만, 토큰 한도 메타)은 AI Studio 전용 정규화 단계로 넣으면 Vertex/Antigravity와 섞이지 않게 할 수 있습니다. 다만 지금 HEAD의 의도적 경계(연결 카운트 ≠ 권위 목록)를 뒤집는 일이라, 단순 원라이너 수정으로 취급하면 안 됩니다. types/config 분할에 무효화되는 PR도 아니고, 2.47 릴리스 회귀 묶음(#3927)과도 직접 겹치지 않습니다.

    경로 src/providers/model-discovery.ts extractProviderModelItems - 권위 목록은 data[] 또는 최상위 배열만 받는다. 단독 models[] 는 invalid_shape 로 떨어진다.
    경로 src/codex/catalog/provider-fetch.ts - 위 추출 실패 시 malformed 2xx + fallback=configured 로그를 남기고 정적/설정 목록으로 내려간다. 보고 로그와 일치한다.
    경로 src/server/management/provider-routes.ts 연결 테스트 - Google models[].name 을 연결 카운트만으로 읽고, 권위 카탈로그가 아니라고 주석으로 명시한다. 테스트 OK / sync 실패 갈라짐의 직접 원인이다.
    경로 src/providers/registry.ts google 시드 - 실패 시에도 gemini-3.x 정적 카탈로그가 남는다. “완전 고장”이 아니라 “라이브 갱신 거절”에 가깝다.
    경로 범위 - Vertex/Antigravity/CCA 경로를 건드리지 말고 AI Studio(googleMode 기본/미설정)만 정규화할지, 아니면 로그·연결 테스트 어휘만 맞출지가 갈린다.

    메인테이너의 판단이 필요한 지점

    너의 추천
    provider-compatibility 로 두고, “AI Studio 전용 models[] → CatalogModel 정규화(접두 제거·generateContent 필터·토큰 한도)” 작은 PR을 받되 Vertex/Antigravity는 그대로 둔다. 승격이 싫다면 연결 테스트 메시지에 “카탈로그는 정적 시드, 연결만 확인”을 명시해 갈라짐만 없앤다. 지금 당장 2.47 컷에 넣지는 말고 #3927 이후 백로그로 받는다.

    이 댓글은 grok-bot이 작성했습니다

  2. lidge-jun commented on Sep 9, 2026

    @lidge-jun
    Owner

    Landed via #4068 at f757a47

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    landed-via-maintainerOriginal PR closed after landing via a maintainer merge trainproviderProvider adapters, OpenAI-compat presets, upstream API quirksprovider-compatibilityProvider compatibility reports

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions