Skip to content

Z.AI Chat rows advertise glm-5.3-flash as text-only, so client exports block image attachments on a native VLM #4296

Closed

Description

@lidge-jun

Client or integration

Other (every client that consumes an ocx config export: ZCode, Pi, OMP)

Provider or upstream service

zai (Z.AI GLM Coding Plan) and zhipu-bigmodel-coding

OpenCodex version

2.50.0 (installed), dev at 29d632f

Endpoint or capability

Model discovery / input modality metadata

Current behaviour

glm-5.3-flash is a native VLM, but the two Chat-path Z.AI rows describe it only negatively. They list the text-only siblings in noVisionModels and declare no modelInputModalities at all:

noVisionModels: ZAI_GLM_5X_SIDECAR_VISION_MODELS,
// (= ZAI_GLM_5X_MODELS.filter(id => id !== "glm-5.3-flash"))

That keeps Flash out of the vision sidecar, which is correct, but it never tells the catalog what the model can read. configuredInputModalities returns undefined (src/codex/catalog/provider-fetch.ts:674-677) and the catalog falls back to the ["text"] floor, so inputModalitiesForClient emits ["text"] and every client export lists a native multimodal model as text-only. The picker then refuses to attach an image.

The Responses sibling row does it correctly, so the same model is described two different ways in one registry:

modelInputModalities: { "glm-5.3": ["text"], "glm-5.3-flash": ["text", "image"], "glm-5-turbo": ["text"] }

Expected behaviour

The Chat-path rows should declare the modality positively, the same way the Responses row does: glm-5.3 as text-only and glm-5.3-flash as text + image.

Minimal redacted request or reproduction

curl -s https://api.z.ai/api/v1/models -H "Authorization: Bearer <redacted>" \
  | python3 -c "import json,sys;[print(m['slug'], m['input_modalities']) for m in json.load(sys.stdin)['models']]"

Actual response or error

glm-5.3 ['text']
glm-5.3-flash ['text', 'image']
glm-5-turbo ['text']
# but an ocx client export lists glm-5.3-flash with modalities.input = ["text"]

Upstream documentation

https://docs.z.ai/guides/vlm/glm-5.3-flash

GLM-5.3-Flash is the first native multimodal model in the GLM-5 series
Input Modality: Video / Image / Text / File

https://docs.z.ai/guides/llm/glm-5.3

GLM-5.3 currently supports text-only inputs, with a 1M-token context window and a maximum output length of 128K tokens.

https://docs.z.ai/devpack/latest-model

GLM-5.3 is a text-only model, so uncheck Support Images; GLM-5.3-FLASH is a multimodal model, so Support Images can be checked

Suggested mapping or implementation notes

Add one shared positive declaration next to ZAI_GLM_5X_SIDECAR_VISION_MODELS and reference it from both Chat rows:

const ZAI_GLM_5X_INPUT_MODALITIES: Record<string, string[]> = {
  ...Object.fromEntries(ZAI_GLM_5X_SIDECAR_VISION_MODELS.map(id => [id, ["text"]])),
  "glm-5.3-flash": ["text", "image"],
};

Upstream also lists video and file for Flash. Those stay out of scope: the internal modality vocabulary is text / image / audio and the ZCode and Pi export vocabulary is text / image, so there is nowhere to express them. Declaring image closes the picker defect.

The vendored snapshot behind src/generated/model-metadata.ts has no glm-5.3-flash row at all, but that file is byte-synced by tests/codex-integration/model-metadata-sync.test.ts and refreshing it is a separate deliberate commit. Registry declarations win over that fallback, so the defect closes in the registry alone.

Additional context and attachments

Related: #4286 reports the same class of defect from the other end, a client export dropping per-model image capability.

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 11, 2026

    @lidge-jun
    OwnerAuthor

    리뷰 · 우선순위 66 / 80

    설명

    이 이슈는 Z.AI Chat 경로 행이 glm-5.3-flash를 “비전 사이드카에 넣지 말 것”으로만 표시하고, “이미지는 읽을 수 있다”는 긍정 선언을 하지 않아서, 클라이언트 export가 네이티브 VLM을 text-only로 광고하는 버그입니다. 지금 dev HEAD cb7f96cbc의 src/providers/registry.ts에서 zai와 zhipu-bigmodel-coding은 noVisionModels: ZAI_GLM_5X_SIDECAR_VISION_MODELS만 두고 modelInputModalities는 없습니다. ZAI_GLM_5X_SIDECAR_VISION_MODELS는 flash를 빼서 사이드카 우회를 막는 용도로는 맞지만, 카탈로그 builder가 긍정 modality를 못 보면 configuredInputModalities가 undefined가 되고(src/codex/catalog/provider-fetch.ts 근처), 바닥값 ["text"]로 떨어집니다.

    같은 파일의 zhipu-bigmodel-responses 행은 이미 올바릅니다. modelInputModalities: { "glm-5.3": ["text"], "glm-5.3-flash": ["text", "image"], "glm-5-turbo": ["text"] }처럼 flash만 image를 명시합니다. 그래서 같은 모델 id가 Chat 행과 Responses 행에서 서로 다른 능력으로 보입니다. ZCode/Pi/OMP 같은 export 소비자는 inputModalitiesForClient가 돌려준 목록으로 첨부 UI를 켜므로, Chat 행을 쓰는 사용자는 flash에 이미지를 붙일 수 없습니다. upstream 문서(docs.z.ai VLM 가이드)와 /api/v1/models의 input_modalities도 flash가 multimodal임을 말합니다.

    #4286 / #4300과의 관계도 짚어야 합니다. #4286은 OpenCode export가 attachment/modalities 필드를 아예 안 써서 생기는 클라이언트 벽이고, #4300이 그 export 경로를 고칩니다. 이 이슈는 그 한 겹 아래, 카탈로그가 flash에 image를 안 실어 주는 registry 선언 문제입니다. #4300만 랜딩해도 “선언된 모델”은 OpenCode에 전달되지만, Chat 행이 계속 text 바닥이면 flash는 여전히 첨부가 막힙니다. 반대로 이 이슈만 고쳐도 Pi/ZCode/OMP는 이득을 보고, OpenCode는 #4300이 추가로 필요합니다.

    우선순위 66입니다. 재현·원인·고칠 위치가 한 파일에 가깝고, Responses 행에 이미 정답이 있어 복사 비용이 낮습니다. #4297(Responses 기본 전환)과 겹칠 수 있으나, Chat 형제를 남기는 한 이 수정은 여전히 필요합니다.

    라인 - src/providers/registry.ts id: "zai" - modelInputModalities 부재가 직접 원인입니다. Responses 행과 같은 표를 넣는 것이 최소 수정입니다.
    라인 - id: "zhipu-bigmodel-coding" - 동일하게 noVisionModels만 있고 긍정 modality가 없습니다. 이슈 제목이 두 Chat 행을 함께 지목한 이유가 이것입니다.
    경로/심볼 - configuredInputModalities / inputModalitiesForClient - 바닥값 ["text"] 동작은 HEAD에서 의도된 fallback입니다. 고치는 쪽은 fallback이 아니라 registry 선언입니다.
    관련 - #4286/#4300/#4297 - export 필드 누락, 국제 Responses 기본, 이 modality 누락은 한 사용자 증상으로 겹쳐 보이지만 레이어가 다릅니다. 닫을 때 서로 supersede로 뭉개지 마세요.

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

    • Chat 행에 Responses와 동일한 modelInputModalities 표를 복제할지, jawcodeBundle/zai 공통 상수로 한곳에서 공급할지
    • #4297이 Chat 행을 곧 줄이거나 없앨 계획이면, 그 PR에 이 수정을 흡수할지 지금 작은 PR로 먼저 넣을지
    • bracket 변형(glm-5.3[1m] 등)에도 같은 modality를 명시할지

    너의 추천
    수락하고 작은 registry PR로 바로 고치세요. zai와 zhipu-bigmodel-coding에 Responses 행과 같은 modelInputModalities를 추가하고, flash 외 5.x는 text-only로 두면 됩니다. #4300과는 독립이니 병렬로 머지해도 됩니다. #4297이 커지면 이 수정을 그 PR에 흡수해도 되지만, 기다릴 이유는 없습니다.

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

  2. lidge-jun commented on Sep 11, 2026

    @lidge-jun
    OwnerAuthor

    Landed on `dev` in #4304. PRs here target `dev`, so closing by hand. Both Chat rows now declare glm-5.3-flash as text+image from the upstream catalog, so client exports stop advertising a native VLM as text-only.

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

    providerProvider 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