Skip to content

[Feature]: allow marking models as text-only from ocx provider add #3268

Closed as not planned

Description

@turin-dev

Area

CLI

What are you trying to accomplish?

I want to add a custom OpenAI-compatible provider from the CLI and mark its model as text-only in the same command, so OpenCodex knows that the model does not accept image input.

Today a typical custom-provider setup can be created entirely with ocx provider add, but noVisionModels cannot be configured there.

What prevents this today?

ocx provider add currently supports options such as --adapter, --base-url, --api-key, and --default-model, but there is no CLI option for noVisionModels.

The configuration format already supports:

{
  "providers": {
    "example": {
      "adapter": "openai-chat",
      "baseUrl": "https://example.invalid/v1",
      "defaultModel": "example-model",
      "noVisionModels": ["example-model"]
    }
  }
}

So users who create providers non-interactively must edit ~/.opencodex/config.json afterward just to mark the model as text-only.

What should OpenCodex do?

Provide a CLI option on ocx provider add (and ideally ocx provider edit) that writes the provider's noVisionModels configuration.

For the common case where one --default-model is being added, a simple flag such as --no-vision or --text-only could mark that default model as text-only.

For multiple models, a repeatable option such as --no-vision-model <model> could be supported.

The exact flag naming is flexible; the important behavior is that a custom provider can be fully configured as text-only without manually editing JSON.

Example usage or interface

Simple default-model form:

ocx provider add example \
  --adapter openai-chat \
  --base-url https://example.invalid/v1 \
  --api-key '<redacted>' \
  --default-model example-model \
  --no-vision \
  --force \
  --sync

Equivalent resulting configuration:

{
  "providers": {
    "example": {
      "adapter": "openai-chat",
      "baseUrl": "https://example.invalid/v1",
      "defaultModel": "example-model",
      "noVisionModels": ["example-model"]
    }
  }
}

A more explicit/repeatable form could be:

ocx provider add example \
  --adapter openai-chat \
  --base-url https://example.invalid/v1 \
  --default-model example-model \
  --no-vision-model example-model

Alternatives or workarounds

The current workaround is to run ocx provider add first, then manually edit ~/.opencodex/config.json and add the model to providers.<name>.noVisionModels.

That works, but it breaks an otherwise fully non-interactive provider setup and is inconvenient for scripts, provisioning, and reproducible configuration.

Additional context

noVisionModels is already a documented provider configuration field used by the vision-sidecar path. This proposal only asks for a CLI surface for an existing capability rather than a new vision-routing mechanism.

Checks

  • I searched existing issues and documentation.
  • This request describes a concrete OpenCodex workflow rather than merely naming a desired technology.
  • I removed secrets and personal data.

Activity

  1. added
    enhancementNew feature or request
    cliCLI, config inject, packaging flags
    providerProvider adapters, OpenAI-compat presets, upstream API quirks
    on Sep 2, 2026
  2. lidge-jun commented on Sep 2, 2026

    @lidge-jun
    Owner

    리뷰 · 우선순위 58 / 80

    설명

    이 이슈는 새 비전 라우팅을 만들자는 말이 아닙니다. 이미 설정과 런타임에 있는 providers.<name>.noVisionModels 필드를, 비대화형 CLI인 ocx provider add / ocx provider edit 에서도 쓸 수 있게 해 달라는 요청입니다.

    현재 dev HEAD 7424719ab (package.json 2.41.0) 기준으로 보면, 타입은 src/types/provider.ts 의 OcxProviderConfig.noVisionModels?: string[] 로 이미 정의되어 있습니다. 주석에도 “이미지를 받지 못하는 모델 목록이며, 프록시가 vision sidecar로 이미지를 텍스트로 바꿔 준다”고 적혀 있습니다. 실제 판정은 src/vision/eligibility.ts 의 isModelVisionSidecarConsumer 가 modelInList(provider.noVisionModels, modelId) 를 먼저 보고, 그다음 modelInputModalities 를 봅니다. 라우터 병합(src/router.ts)과 레지스트리 시드(src/providers/registry.ts)에도 같은 필드가 쓰입니다. 즉 “텍스트만 되는 모델” 표시 자체는 제품 기능으로 이미 살아 있습니다.

    그런데 CLI 쪽은 구멍이 있습니다. src/cli/provider.ts 의 ADD_USAGE / handleAdd 는 --adapter, --base-url, --api-key, --default-model, --force, --sync 까지만 파싱합니다. noVisionModels 를 쓰는 플래그가 없습니다. 커스텀 프로바이더를 스크립트로 넣는 사람은 ocx provider add 다음에 ~/.opencodex/config.json 을 손으로 고쳐야 합니다. 이슈에 적힌 재현 흐름과 정확히 맞습니다.

    편집 경로도 같습니다. src/cli/provider-runtime.ts 의 ocx provider edit 는 --retain-models, --live-models, --allow-private-network 같은 배열/불리언은 PATCH로 넘기지만 noVisionModels 는 없습니다. 관리 API(src/server/management/provider-routes.ts)도 retainModels / noStructuredOutputModels / omitReasoningEffortWithToolsModels 는 문자열 배열로 PATCH를 받지만, noVisionModels 쓰기 분기는 보이지 않습니다. 읽기 DTO(src/server/auth-cors.ts)에는 noVisionModels 가 노출되므로, “설정에는 있고 대시보드에서도 보이는데 CLI/PATCH로는 못 넣는다”는 비대칭이 됩니다. types.ts/config.ts 대분할 캠페인으로 무효화될 종류의 PR도 아닙니다. 작은 CLI+management 표면 추가입니다.

    제안된 --no-vision (기본 모델을 목록에 넣기) 과 --no-vision-model <id> (반복 가능) 둘 다 기존 필드 의미를 바꾸지 않고 쓰기만 열어 줍니다. 비전 사이드카 정책이나 modelInputModalities 의미를 새로 설계할 필요는 없고, 플래그 → noVisionModels: string[] 직렬화와 --force 덮어쓰기 시 기존 목록 보존/교체 규칙만 정하면 됩니다.

    라인 130 - src/cli/provider.ts ADD_USAGE에 --default-model까지는 있는데 noVisionModels용 플래그가 없어 문서/헬프와 실제 설정 표면이 어긋난다
    라인 150-198 - handleAdd가 apiKey/adapter/baseUrl/defaultModel만 반영하고 noVisionModels를 절대 쓰지 않는다
    라인 214-221 - --force 덮어쓰기 때 modelCosts만 보존하고 noVisionModels 등 다른 사용자 목록은 보존하지 않아, 나중에 플래그를 넣어도 기존 텍스트-only 목록이 날아갈 위험이 있다
    경로/심볼 src/cli/provider-runtime.ts edit() - --retain-models는 있으나 --no-vision-model 계열이 없어 add만 고쳐도 edit/재프로비저닝이 막힌다
    경로/심볼 src/server/management/provider-routes.ts - retainModels/noStructuredOutputModels PATCH는 있는데 noVisionModels 쓰기 분기가 없어, edit가 런타임 API를 타려면 여기도 같이 열어야 한다
    경로/심볼 src/types/provider.ts noVisionModels / src/vision/eligibility.ts isModelVisionSidecarConsumer - 런타임 의미는 이미 고정되어 있으니 CLI는 이 배열만 채우면 되고, 새 모달리티 엔진을 만들 자리가 아니다

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

    • 플래그 이름: --no-vision(defaultModel을 목록에 넣기)만으로 충분한지, 아니면 반복 --no-vision-model <id>까지 1차 범위에 넣을지
    • ocx provider edit와 management PATCH에 같은 필드를 같은 PR에서 열지, add만 먼저 좁게 넣을지
    • --force 시 기존 noVisionModels를 modelCosts처럼 보존할지, 플래그가 오면 교체/병합할지(교체면 스크립트 재실행이 목록을 지울 수 있음)
    • GUI/대시보드에서 이미 편집 가능한지와 CLI 우선순위 정렬(읽기 DTO에는 필드가 있음)

    너의 추천
    help wanted로 두고, 좁은 PR 하나를 받는 편이 좋습니다. (1) ocx provider add 에 --no-vision (있으면 defaultModel 필수) 와 반복 --no-vision-model 를 추가해 provConfig.noVisionModels 에 합치고, (2) provider edit + provider-routes PATCH에 noVisionModels 문자열 배열(클리어는 - 또는 null, retainModels 패턴 복제)을 열고, (3) --force 때 기존 noVisionModels 보존 규칙을 modelCosts 옆에 문서화한 단위 테스트를 넣으세요. types/config 대분할과 겹치지 않으니 close-don't-rebase 대상이 아닙니다. 중복 이슈가 보이면 이쪽에 묶고 나머지는 닫으면 됩니다.

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

  3. lidge-jun commented on Sep 3, 2026

    @lidge-jun
    Owner

    Closing in favor of #3377, which carries the remaining scope forward.

    Thank you @turin-dev — the request for marking models as text-only from ocx provider add is valid and still unimplemented.

    Verified current state. src/cli/provider.ts parses through --default-model but has no text-only flag, and src/cli/provider-runtime.ts has no equivalent on edit.

    All three open requests of this kind are blocked at the same layer: the provider/model row has nowhere to declare what the model can do, so each one would otherwise land as a separate bespoke flag. #3377 asks for the capability block that all three populate, names this issue, and credits you for the original analysis.

    Please follow #3377; if the consolidation lost a detail you asked for, say so there and it will be added.

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

    cliCLI, config inject, packaging flagsenhancementNew feature or requestproviderProvider adapters, OpenAI-compat presets, upstream API quirks

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions