Skip to content

Latest commit

 

History

History
447 lines (379 loc) · 42 KB

File metadata and controls

447 lines (379 loc) · 42 KB
title 설정 레퍼런스
description ~/.opencodex/config.json의 모든 필드 — 최상위 옵션, 프로바이더, 사이드카.

opencodex는 ~/.opencodex/config.json에서 설정을 읽습니다. ocx init과 대시보드가 이 파일을 쓰지만 직접 편집해도 됩니다. 프록시는 시작할 때 다시 읽습니다. 서비스가 실행 중일 때는 직접 고치기 전에 프록시를 멈추거나 대시보드/관리 API를 쓰세요. 실행 중인 프로세스는 설정을 메모리에 두고, 중간에 저장하면 디스크를 덮어쓸 수 있습니다. v2.7.41부터 손수 수정한 claudeCode 하위 트리는 그런 저장에서도 유지됩니다. 다른 키(예: providers)는 여전히 덮어써질 수 있습니다. 잘렸거나 올바른 JSON이 아닌 등 파일을 파싱할 수 없으면 config.json.invalid-<timestamp>로 백업하고 콘솔에 경고한 뒤 기본값으로 시작합니다. 파일이 없어도 기본 설정(단일 openai forward 프로바이더)을 사용합니다.

예약된 OpenAI 프로바이더

openaiopenai-apikey는 고정된 예약 id입니다. openai.codexAccountMode는 기본 "pool"로 메인과 추가 계정을 선택하고, "direct"는 현재 Codex caller/메인 로그인만 사용합니다. API는 설정된 API key/key pool만 사용합니다. bare 모델 또는 openai-apikey/<model>로 선택하며 자격증명 경로 간 fallback은 없습니다. API GPT-5.6 metadata는 context 1,050,000 / max input 922,000이고 Pro virtual id는 wire에서 base 모델과 reasoning.mode: "pro"로 변환됩니다.

openaiProviderTierVersion: 2는 현재 단일 프로바이더 projection 마커입니다. shipped v1 config를 이관하기 전에 config.json.pre-openai-tiers-v2.bak을 no-replace로 만들고 알려진 레거시 namespaced selected id를 bare id로 바꿉니다.

최상위 (OcxConfig)

Field Type Default Meaning
port number 10100 프록시가 수신할 포트.
hostname? string "127.0.0.1" 바인드 주소. LAN에 공개하려면 "0.0.0.0"으로 설정합니다(OPENCODEX_API_AUTH_TOKEN 필요, 아래 원격 접근 참조).
proxy? string 외부로 나가는 HTTP(S) 프록시 URL 또는 ${ENV_VAR} 참조. 해당 환경 변수가 비어 있을 때 HTTP_PROXY / HTTPS_PROXY에 적용하고, loopback은 NO_PROXY에 유지합니다.
providers Record<string, OcxProviderConfig> 프로바이더 이름 → 설정 map.
openaiProviderTierVersion? 2 migration 설정 단일 옵션형 OpenAI projection 완료 마커.
defaultProvider string "openai" 라우팅에서 더 나은 match를 찾지 못했을 때 쓸 프로바이더.
subagentModels? string[] gpt-5.5, GPT-5.6 3종, gpt-5.4-mini Codex 서브에이전트 선택기 앞쪽에 표시할 네이티브 slug 또는 provider/model id. 최대 5개이며, 명시적인 빈 배열도 그대로 보존합니다. v2 가이던스 로스터는 설정 목록과 Codex의 picker-visible·v2 호환·priority 순 상위 5개의 교집합이며 정규 카탈로그 slug와 사용 가능한 effort 사다리를 씁니다. 제외된 항목도 설정에는 남습니다.
injectionModel? string 선호하는 네이티브/라우팅 서브에이전트 모델. 별도 multiAgentGuidanceEnabled가 제어하는 OpenCodex 작성 v2 위임 가이드에서 사용하며, syncCodexSubagentDefaults를 선택하면 새 task의 Codex 네이티브 기본값으로도 적용할 수 있습니다.
injectionEffort? string 선호하는 서브에이전트 reasoning effort(low부터 ultra). injectionModel과 함께 쓸 때만 의미가 있으며, 위임 가이드와 선택적인 Codex 네이티브 기본값에서 사용합니다.
syncCodexSubagentDefaults? boolean false OpenCodex가 활성 Codex 라우팅을 관리할 때 선택한 injectionModel/injectionEffort를 다음 sync 또는 restart에서 Codex 네이티브 [agents] 서브에이전트 기본값으로 적용하는 선택 기능. 외부 사용자 관리 provider 설정은 변경하지 않습니다. 새로 생성되는 Codex task에만 적용하고 위임 자체를 일으키지는 않습니다. 기존 사용자 소유 대상 항목은 충돌로 취급해 덮어쓰지 않고 보존합니다. injectionModel이 필요하며 모델을 지우면 이 옵션도 꺼집니다. GET/PUT /api/injection-model의 부분 업데이트 필드로 제공됩니다.
effortCap? string reasoning effort에 요청별로 적용하는 강제 상한입니다. 멀티 에이전트 V2 전용 기능으로, 자체 도구 목록에 V2 협업 표면이 있는 메인 턴과, x-openai-subagent: collab_spawn 헤더 또는 x-codex-turn-metadata"subagent_kind": "thread_spawn" 표식이 정확히 일치하는 스폰된 자식 턴에 적용됩니다(표식이 붙은 자식은 자체 도구 표면과 무관하게 적용 대상입니다). 일반 메인 턴과 V1 표면 메인 턴은 건드리지 않고, 컴팩션 턴은 항상 상한을 우회하며, multiAgentMode: "v1"은 상한 기능 전체를 비활성화합니다(대시보드도 패널을 숨깁니다). low부터 ultra까지 허용하며 값을 높이지 않고 낮추기만 합니다. 상한 이하에서 모델이 지원하는 가장 높은 단계로 내립니다. 모델이 effort 제어를 노출하지 않거나 상한 이하에 지원 단계가 없으면 effort 필드를 제거하고 프로바이더 기본값을 적용합니다. maxultra도 허용하지만 더 낮은 rank 상한을 만들지는 않습니다(클라이언트가 ultramax로 변환하므로 요청은 low부터 max로 들어옵니다). 단, 알려진 모델 effort 사다리에 따라 단계가 내려가거나 필드가 제거될 수 있습니다. 대시보드 선택기는 low부터 xhigh까지 제공합니다. GET /api/effort-capsPUT /api/effort-caps로 관리합니다.
subagentEffortCap? string 같은 강제 상한을 codex-rs 표식이 정확히 일치하는 스폰된 자식 턴에만 적용합니다: x-openai-subagent: collab_spawn 또는 x-codex-turn-metadata"subagent_kind": "thread_spawn". 그 외 내부 서브에이전트 범주(리뷰, 컴팩션, 메모리 정리)는 이 상한에 걸리지 않으며, multiAgentMode: "v1"은 기능 전체를 비활성화합니다. low부터 ultra까지 허용하며 두 상한이 모두 설정되면 더 낮은 값이 적용되고, 값을 높이지 않고 낮추기만 합니다. 상한 이하에서 모델이 지원하는 가장 높은 단계로 내립니다. 모델이 effort 제어를 노출하지 않거나 상한 이하에 지원 단계가 없으면 effort 필드를 제거하고 프로바이더 기본값을 적용합니다. maxultra도 허용하지만 더 낮은 rank 상한을 만들지는 않습니다(클라이언트가 ultramax로 변환하므로 요청은 low부터 max로 들어옵니다). 단, 알려진 모델 effort 사다리에 따라 단계가 내려가거나 필드가 제거될 수 있습니다. 대시보드 선택기는 low부터 xhigh까지 제공합니다. GET /api/effort-capsPUT /api/effort-caps로 관리합니다.
injectionPrompt? string 주입되는 v2 안내 본문을 통째로 교체하는 커스텀 텍스트. {{model}}, {{effort}}, {{roster}} 플레이스홀더가 치환되며 발화 조건은 그대로입니다. PUT /api/injection-modelprompt 키로도 설정할 수 있습니다.
multiAgentGuidanceEnabled? boolean true OpenCodex가 작성하는 multi-agent developer 가이던스만 제어합니다. 미설정/true는 v1/v2 가이던스를 유지하고, false는 Codex 네이티브 [agents] 기본값, collaboration surface, subagentModels, routing, effort cap을 바꾸지 않고 둘 다 억제합니다. GET/PUT /api/injection-model은 유효값을 제공하며 PUT은 부분 업데이트입니다.
disabledModels? string[] Codex에서 숨길 모델. 라우팅된 provider/model id는 카탈로그와 /v1/models에서 제외합니다. gpt-5.4 같은 일반 네이티브 GPT slug는 카탈로그 항목을 visibility: "hide"로 바꾸고 일반 /v1/models 목록에서 뺍니다. 대시보드 Models 페이지에서 모델별로 전환할 수 있습니다.
multiAgentMode? "v1" | "default" | "v2" "default" 3단계 multi-agent surface override. "v1"은 업스트림 pin보다 우선해 모든 모델을 v1로, "default"는 업스트림 model pin(sol/terra=v2, luna=v1)을 따르고, "v2"는 모두 v2로 강제합니다. 대시보드 Models 페이지나 ocx v2 mode에서 설정합니다.
providerContextCaps? Record<string,number> {} 프로바이더별 Codex 표시 context cap. 알려진 context window를 낮추기만 합니다.
contextCapValue? number 350000 대시보드 context-cap control에서 쓸 값. 바꾸면 providerContextCaps에서 활성화된 모든 항목을 갱신합니다.
stallTimeoutSec? number 300 업스트림 데이터가 오지 않을 때 bridge가 중단하고 response.incomplete를 내보내기까지의 초. 최소 1.
connectTimeoutMs? number 200000 DNS/TCP/TLS와 최종 응답 헤더만 기다리는 시도별 deadline. 응답 body 생성 전 종료됩니다.
shutdownTimeoutMs? number 5000 진행 중인 turn을 중단하기 전 graceful drain deadline.
websockets? boolean false supports_websockets를 알려 Codex가 Responses WebSocket 경로를 쓰게 합니다. 생략하거나 false이면 HTTP/SSE를 유지합니다.
apiKeys? OcxApiKey[] [] 비-loopback 바인드에서 관리 API와 data plane 인증에 추가로 허용할 생성형 ocx_… 자격 증명. 대시보드가 관리하며 항목 필드는 아래에 설명합니다.
codexAutoStart? boolean true Codex shim이 Codex 실행 전에 ocx ensure를 실행하게 합니다. false이면 ocx ensure가 아무 작업도 하지 않습니다.
codexShimAutoRestore? boolean true 완료된 외부 Codex 업데이트가 이전에 설치한 shim을 교체하면 자동으로 복구합니다. 끄려면 false로 설정하거나 프로세스에 OPENCODEX_CODEX_SHIM_AUTO_RESTORE=0을 설정합니다.
syncResumeHistory? boolean true 되돌릴 수 있는 Codex App 기록 호환 모드. opencodex가 원래 Codex thread metadata를 백업하고, 예전 OpenAI interactive row를 opencodex로 재매핑하며, opencodex가 만든 exec row를 App에 보이는 source로 잠시 승격합니다. ocx stop / ocx restore는 백업한 OpenAI row를 복원하고 남은 opencodex user thread를 OpenAI로 돌려 네이티브 Codex가 config.toml에서 프록시를 제거한 뒤에도 이어서 열 수 있게 합니다. 끄려면 false로 설정합니다.
codexAccounts? CodexAccount[] [] Codex Auth 대시보드에서 관리하는 ChatGPT/Codex pool 계정 metadata. secret은 codex-accounts.json에 따로 둡니다.
pausedCodexAccountIds? string[] [] Codex Auth에서 재개할 때까지 이후의 모든 Pool 선택에서 제외할 계정 ID. 메인 계정을 일시 중지하면 __main__도 포함됩니다.
codexAccountNamespaces? Record<string,string> 공개 model selector namespace에서 저장된 Codex 계정 target으로 연결하는 선택적 map입니다. <selector>/<native OpenAI model>은 매핑된 계정으로만 routing되며, 이 설정 자체는 model picker row를 추가하지 않습니다.
activeCodexAccountId? string 수동으로 선택한 pool 계정. 선택 시 기존 thread affinity를 지우고 다음 요청부터 적용하며, 진행 중인 요청은 기존 계정을 유지합니다.
autoSwitchThreshold? number 80 새 세션 자동 전환용 사용량 백분율 threshold. 알려진 5시간, 주간, 30일 quota window 중 가장 높은 점수를 씁니다. 0이면 quota 자동 전환을 끕니다. quota 전략과 fill-first drain threshold에도 사용됩니다.
accountPoolStrategy? "quota" | "round-robin" | "fill-first" "quota" Codex pool의 새 세션 rotation 전략. 새 세션에만 적용되며 기존 thread id는 affinity를 유지합니다. quota(기본) — 활성 계정이 autoSwitchThreshold를 넘으면 알려진 usage가 가장 낮은 계정 선택. round-robin — 적격 계정 간 smooth weighted 균등 분배. fill-first — cooldown, 사용 불가 또는(설정 시) autoSwitchThreshold까지 활성 계정을 소진(알 수 없는 usage는 강제 전환하지 않음)한 뒤 안정 정렬 순으로 다음 계정.
accountPoolStickyLimit? number 1 한 round-robin 선택이 다음으로 넘어가기 전에 유지하는 성공적 새 세션 bind 수. 범위 1–100. accountPoolStrategyround-robin일 때만 적용.
upstreamFailoverThreshold? number 3 일시적인 업스트림 실패가 연속으로 발생한 뒤, 이후 새 세션을 다른 적합한 pool 계정으로 failover할 횟수. 0이면 실패 기반 failover를 끕니다.
modelCacheTtlMs? number 300000 프로바이더별 /models 캐시의 유효 기간(5분).
appOwnedMemoryBudgetMb? number 256 제거 가능한 앱 소유 유지 상태(로그, 캐시, Blob, 연속 응답 페이로드)의 프로세스 전체 상한(MiB)입니다. 유효 범위는 64~4096이며 RSS나 네이티브 런타임 메모리 상한이 아닙니다.
cacheRetention? "none" | "short" | "long" "short" Anthropic prompt cache 정책. 끔, 5분 ephemeral, 1시간 extended 중 하나입니다.
webSearchSidecar? OcxWebSearchSidecarConfig on 웹 검색 사이드카 옵션(아래 참조).
visionSidecar? OcxVisionSidecarConfig on 비전 사이드카 옵션(아래 참조).
tokenGuardian? OcxTokenGuardianConfig off 선택형 proactive OAuth 갱신 및 Codex 계정 warmup 정책. 필드는 아래에 설명합니다.
corsAllowOrigins? string[] [] CORS에서 추가로 허용할 정확한 origin. loopback origin은 항상 허용합니다.

codexAccountNamespaces 키는 공개 selector입니다. 길이는 1~64자이고 시작과 끝은 ASCII 영숫자여야 하며, 내부에는 영숫자, ., _, -를 사용할 수 있습니다. 예약된 JavaScript object 이름은 거부됩니다. 값은 유효한 pool account id(내부 __main__ 제외)이거나 Codex Desktop 계정을 나타내는 "@main"입니다. provider 및 예약된 openai / combo 충돌은 대소문자를 구분하지 않고 검사하며, namespace가 있는 combo alias는 selector를 namespace prefix로 재사용할 수 없습니다. 설정된 pool id와 다른 selector target도 selector로 재사용할 수 없습니다. raw account id와 email은 비공개로 유지하고 selector를 공개 이름으로 사용하세요. side/gpt-5.6-sol 같은 요청은 openai가 Direct mode여도 side에 매핑된 계정만 사용하고 업스트림에는 gpt-5.6-sol을 보냅니다. target을 사용할 수 없으면 다른 계정으로 전환하지 않고 fail closed하며 active Pool account도 변경하지 않습니다. bare native model은 기존 Pool / Direct routing을 유지합니다. 이 map 자체는 model picker entry를 만들지 않습니다.

maxConcurrentThreadsPerSessionconfig.json 키가 아니라 PUT /api/v2에서 쓰는 camel-case 필드입니다. ocx v2 threads <n>은 대응하는 max_concurrent_threads_per_session 값을 Codex의 $CODEX_HOME/config.toml[features.multi_agent_v2]에 저장합니다. 해당 table이 생기도록 v2를 먼저 켜세요.

백업 지원 이전의 개발 빌드에서 이미 syncResumeHistory를 실행했다면 ocx recover-history --legacy-openai로 같은 native-provider 복구를 강제할 수 있습니다.

:::note[Codex 계정 풀] pool 계정 추가와 quota 갱신은 대시보드의 Codex Auth 페이지에서 처리하세요. 설정에는 secret이 아닌 계정 metadata만 저장하고, access/refresh token은 강화된 Codex 계정 credential store에 따로 보관합니다. 기존 thread id는 계정 affinity를 유지하며, 새 세션은 accountPoolStrategy, quota, cooldown, health에 따라 자동 라우팅됩니다. 일시 중지된 계정과 quota metadata는 계속 표시되지만 자동 전환, 재시도/failover 선택, cooldown 복구 probe, 수동 활성화에서는 제외됩니다. 일시 중지는 해당 계정의 thread affinity map도 지웁니다. 진행 중인 요청은 이미 확보한 credential을 유지하지만, 이후 턴은 다시 라우팅되며 일시 중지된 계정은 재사용할 수 없습니다. 상태는 재시작 후에도 유지되며, 모든 계정이 일시 중지되면 Pool 라우팅은 계정을 몰래 선택하지 않고 실패합니다. 한도 도달 계정 일시 중지는 credential이 있는 적격 계정만 먼저 새로고친 뒤 관련 quota window가 이번 응답에서 100%로 확인된 계정만 일시 중지합니다. credential이 없는 계정과 quota가 없거나 새로고침에 실패한 계정은 변경하지 않습니다.

rotation 전략(새 세션만; bound thread는 변경 없음): quota(기본) — autoSwitchThreshold 초과 시 최저 usage 선택; round-robin — 균등 분배, accountPoolStickyLimit(기본 1, 1–100)로 한 선택당 성공 bind 수; fill-first — 활성 계정을 cooldown, 재인증 또는 threshold까지 소진(알 수 없는 usage는 강제 전환하지 않음)한 뒤 안정 정렬 순으로 다음 계정. rotation은 provider enforcement를 우회하지 않습니다 — 다계정 사용은 ToS 위반일 수 있습니다. :::

관리형 레코드 형태

apiKeys[] 항목에는 id: string, name: string, 생성된 key: string, ISO 형식의 createdAt: string이 들어갑니다. codexAccounts[] 항목에는 필수 id, email, isMain과 선택 plan, chatgptAccountId, 개인정보가 없는 logLabel 문자열이 들어갑니다. 보통 대시보드에서 관리합니다.

tokenGuardian (OcxTokenGuardianConfig)

Field Type Default Meaning
enabled? boolean false proactive refresh 전체 스위치.
tickSeconds? number 21600 sweep 간격(6시간, 최소 60초).
jitterSeconds? number 300 sweep 전에 더할 무작위 지연.
concurrency? number 3 sweep 한 번에 동시에 갱신할 최대 개수.
leadSeconds? number 900 한 tick에 더하는 선제 갱신 여유 시간.
failureBackoffBaseSeconds? number 300 첫 일시적 실패 backoff.
failureBackoffMaxSeconds? number 3600 backoff 상한 및 영구 실패 지연.
codexWarmupEnabled? boolean false 합성 Codex pool 계정 검증 opt-in.
codexWarmupMaxAgeSeconds? number 691200 계정을 다시 검증할 최대 기간(8일).
codexWarmupModel? string gpt-5.4-mini 선택형 warmup에 쓸 네이티브 모델.

원격 접근

opencodex는 기본적으로 127.0.0.1(loopback 전용)에 바인드합니다. hostname0.0.0.0 같은 비-loopback 주소로 설정하면 관리 API(/api/*)와 data plane(/v1/responses) 모두에 token 인증을 강제합니다.

시작 전에 OPENCODEX_API_AUTH_TOKEN 환경 변수를 설정하세요.

export OPENCODEX_API_AUTH_TOKEN="your-secret-token"
ocx start

비-loopback 바인드에서는 이 변수가 없으면 프록시가 시작되지 않습니다. LAN 접근용 백그라운드 서비스를 설치할 때도 같은 변수를 먼저 export한 뒤 ocx service install을 실행해야 launchd, systemd, Task Scheduler에 전달됩니다. 클라이언트는 모든 요청의 x-opencodex-api-key 헤더에 token을 넣어야 합니다.

x-opencodex-api-key: your-secret-token

받는 헤더는 엔드포인트마다 다릅니다. 항상 되는 건 x-opencodex-api-key 하나입니다:

엔드포인트 Authorization: Bearer x-opencodex-api-key x-api-key
/v1/responses 안 됨 필수 안 됨
/v1/chat/completions 안 됨 필수 안 됨
/v1/messages 가능 가능 가능
/v1/models 가능 가능 가능

Responses와 Chat Completions가 전용 헤더만 받는 이유는, 그 두 경로의 Authorization이 Codex Direct 패스스루의 것일 수 있어서입니다. 두 bearer 영역이 헷갈리면 안 됩니다. 대시보드 API 탭도 이 표를 서버에서 받아 그리기 때문에 코드와 어긋날 수 없습니다.

시작 후에는 대시보드에서 생성한 apiKeys를 환경 변수 token 대신 쓸 수 있습니다. 모든 후보는 timing side channel을 막기 위해 상수 시간(timingSafeEqual)으로 비교합니다.

:::caution[LAN 노출] 0.0.0.0에 바인드하면 프록시와 설정된 모든 프로바이더 자격 증명이 로컬 네트워크에 노출됩니다. 신뢰할 수 있는 네트워크에서만 사용하고 강력한 OPENCODEX_API_AUTH_TOKEN을 반드시 설정하세요. :::

프로바이더 (OcxProviderConfig)

Field Type Meaning
adapter string openai-chat, openai-responses, anthropic, google, kiro, cursor, azure-openai(또는 별칭 azure) 중 하나.
baseUrl string 업스트림 API base URL. 고정 endpoint를 쓰는 대부분의 기본 제공 provider는 일치하지 않는 URL을 무시합니다. 새로 승격된 충돌 보호 API-key preset은 기존의 같은 이름 custom provider 목적지를 유지합니다. 고정 프로바이더 엔드포인트를 참조하세요.
responsesPath? string key 인증 openai-responses 요청에 사용할 선택적 상대 resource path. /로 시작해야 하며 URL scheme, query, fragment를 포함할 수 없습니다. 생략하면 기존 /v1/responses URL 구성을 유지합니다.
disabled? boolean 설정은 디스크에 남기되 라우팅과 모델/카탈로그 목록에서 제외합니다.
apiKey? string API 키 또는 요청 시점에 해석할 ${ENV_VAR} / $ENV_VAR 참조.
apiKeyTransport? "x-api-key" | "bearer" Anthropic API 키 헤더 방식입니다. 기본값은 네이티브 x-api-key이며, Authorization: Bearer <key>를 요구하는 호환 gateway에는 "bearer"를 설정합니다. key 인증 anthropic 프로바이더에서만 유효합니다.
apiKeyPool? ApiKeyPoolEntry[] 여러 키를 담는 pool. apiKey는 활성 항목을 반영합니다. 각 항목에는 id, key, 선택 label, 선택 숫자 addedAt이 있습니다.
defaultModel? string 명시적인 모델 없이 이 프로바이더를 선택했을 때 쓸 모델.
models? string[] seed/fallback 모델 목록. liveModelsfalse이면 여기 있는 모델만 발견됩니다.
liveModels? boolean 시작/동기화 시 프로바이더의 실시간 모델 카탈로그를 가져옵니다(기본 true). 기본 제공 preset은 registry의 신뢰된 URL·쿼리·필터를 사용할 수 있고, 사용자 지정 provider는 ${baseUrl}/models가 기본입니다. false이면 설정된 models만 사용합니다.
selectedModels? string[] 모델 발견 뒤 적용할 카탈로그 allowlist. 비어 있지 않으면 해당 id만 Codex에 노출하고, 비어 있거나 생략하면 발견한 모델을 모두 노출합니다.
contextWindow? number 라우팅 카탈로그 항목에 표시할 프로바이더 단위 context-window cap. 실시간 metadata가 더 작으면 그대로 둡니다.
modelContextWindows? Record<string,number> 모델별 context-window cap. 일치하는 모델에서는 contextWindow보다 우선하며 더 작은 실시간 metadata를 올리지 않습니다.
modelInputModalities? Record<string,string[]> ["text"], ["text", "image"] 같은 모델별 카탈로그 input hint.
headers? Record<string,string> 추가 업스트림 헤더. Authorization, cookie, API-key 헤더, 줄바꿈이 든 값, 잘못된 헤더 이름은 거부합니다.
openRouterRouting? OpenRouterProviderRouting 기본 OpenRouter 프로바이더 라우팅 설정. order, only, allowFallbacks를 지원하며 canonical OpenRouter URL과 openai-chat adapter에서만 유효합니다.
modelOpenRouterRouting? Record<string,OpenRouterProviderRouting> openRouterRouting을 대체하는 정확한 모델 id별 설정입니다.
authMode? "key" | "forward" | "oauth" 인증 방식(기본 key). 프로바이더 참조.
codexAccountMode? "pool" | "direct" canonical openai 전용. 생략하면 Pool이며 Direct는 풀 상태를 건너뜁니다.
refreshPolicy? "proactive" | "lazy-only" | "disabled" 이 OAuth 프로바이더의 Token Guardian 정책 override.
reasoningEfforts? string[] 알리고 전송할 프로바이더 단위 Codex reasoning 레이블(low, medium, high, xhigh, max, ultra).
modelReasoningEfforts? Record<string,string[]> 모델별 reasoning 레이블. 빈 배열은 해당 모델의 effort control을 숨깁니다.
modelSupportsReasoningSummaries? Record<string,boolean> 모델별 reasoning summary capability. 모델 값을 false로 두면 summary 지원을 알리지 않고 openai-responses 요청 전에 summary-delivery 필드를 제거합니다.
modelReasoningSummaryDelivery? Record<string,"sequential" | "sequential_cutoff" | "concurrent" | "concurrent_cutoff"> 모델별 Responses delivery enum입니다. 설정된 모델은 summary 지원을 유지하며 기존 stream_options.reasoning_summary_delivery 값만 바꿉니다. 같은 모델의 summary capability를 false로 설정할 수 없습니다.
modelAdapters? Record<string,string> 여러 wire를 쓰는 모델이 한 게이트웨이에 섞여 있을 때의 모델별 wire 지정. 키는 upstream native 모델 ID이고 값은 openai-chat 또는 openai-responses만 허용합니다. web_search 같은 hosted tool 때문에 한 모델만 Responses API가 필요할 때 씁니다. upstream이 wire를 고정한 모델과 canonical ChatGPT forward provider에서는 override가 거부됩니다.
reasoningEffortMap? Record<string,string> 프로바이더 단위 reasoning 레이블 wire alias. 업스트림이 다른 값을 요구할 때만 사용합니다.
modelReasoningEffortMap? Record<string,Record<string,string>> 모델별 reasoning 레이블 wire alias.
noReasoningModels? string[] reasoning/thinking 파라미터를 거부하는 모델. 어댑터가 reasoning_effort를 제거합니다.
noTemperatureModels? string[] 호출자가 지정한 temperature를 거부하는 모델.
noTopPModels? string[] 호출자가 지정한 top_p를 거부하는 모델.
noPenaltyModels? string[] presence/frequency penalty를 거부하는 모델.
parallelToolCalls? boolean 병렬 툴 호출을 켜거나 끕니다. OpenAI Chat은 기본 on이며, chat 외 어댑터는 명시적인 true에서만 지원을 알립니다.
autoToolChoiceOnlyModels? string[] tool_choice에서 auto 또는 none만 받는 모델. 강제/지정 선택은 downgrade합니다.
preserveReasoningContentModels? string[] 이전 assistant reasoning_content를 chat history에 유지해야 하는 모델.
thinkingToggleModels? string[] effort 단계 대신 vendor thinking.enabled toggle을 쓰는 chat 모델.
thinkingBudgetModels? string[] 정수 thinking_budget을 쓰는 chat 모델. effort를 budget 비율로 매핑합니다.
noVisionModels? string[] 텍스트 전용 모델. 비전 사이드카가 이미지를 설명합니다. Ollama의 :size 태그도 일치시킵니다.
escapeBuiltinToolNames? boolean Umans 같은 Anthropic 호환 gateway가 wire에서 툴 이름 escaping을 요구할 때 사용합니다. opencodex는 툴 호출을 Codex에 돌려주기 전에 prefix를 제거합니다.
googleMode? "ai-studio" | "vertex" | "cloud-code-assist" Google 전송/인증 모드. 기본 ai-studio.
project? string Vertex project id 또는 Antigravity Cloud Code Assist project id.
location? string Vertex location. 환경 변수 fallback은 GOOGLE_CLOUD_LOCATION.
mcpServers? Record<string,CursorMcpServerConfig> Cursor 전용. stdio로 시작하거나 Streamable HTTP로 연결할 MCP server. 필드는 아래에 설명합니다.
desktopExecutor? DesktopExecutorConfig Cursor 전용. 외부 computer-use/record-screen 명령. 필드는 아래에 설명합니다.
unsafeAllowNativeLocalExec? boolean Cursor 어댑터 전용. Cursor 서버가 지시한 로컬 read / write / delete / ls / grep / shell / fetch 실행을 허용하는 opt-in escape hatch. 기본 false라 원격 Cursor 메시지가 Codex 승인과 sandbox를 우회하지 못합니다. 아래 Cursor 프로바이더 참조.

고정 프로바이더 엔드포인트

라우팅은 adapter가 요청을 보기 전에 provider endpoint를 결정합니다. 대부분의 기본 제공 provider에서는 config의 baseUrl보다 registry endpoint가 우선합니다. 이 단계에서 설정 URL을 유지하는 경우는 네 가지입니다.

  • override를 명시적으로 허용하는 provider: ollama, vllm, lm-studio, litellm, qwen-cloud, alibaba-token-plan-intl.
  • registry endpoint가 사용자가 채우는 template인 provider(예: azure-openai, cloudflare-ai-gateway).
  • 이름 충돌을 보호하는 새 고정 API-key preset. 기존의 같은 이름 custom provider가 다른 목적지를 가리키면 원래 목적지를 유지하며 key를 새 registry host로 보내지 않습니다.
  • registry에 없고 사용자가 직접 정의한 provider.

그 뒤에도 adapter가 결정된 URL을 조정할 수 있습니다. 예를 들어 kiro adapter는 canonical runtime.{region}.kiro.dev host에서 가져온 credential의 API region을 사용합니다. adapter별 규칙은 Adapters를 참조하세요.

라우팅이 설정된 baseUrl을 버리면 opencodex가 경고를 출력합니다. registry endpoint는 전체를 표시하고 설정 URL은 origin만 표시합니다. path는 credential 정보를 포함할 수 있으므로 기록하지 않습니다. 사용하지 않는 baseUrl을 제거하거나 목적 URL과 endpoint가 일치하는 provider를 선택하세요. 지역별 서비스에서는 올바른 항목을 사용해야 합니다. alibaba-token-plan은 베이징으로 고정되고, alibaba-token-plan-intl은 국제 endpoint override를 허용합니다.

Cursor 프로바이더 (adapter: "cursor")

Cursor bridge는 실험적입니다. ocx login cursor를 실행한 뒤 ~/.opencodex/config.json(Windows: %USERPROFILE%\.opencodex\config.json)의 providers 아래에 cursor 항목을 추가하거나 편집하세요.

Cursor 서버가 지시하는 네이티브 로컬 툴은 기본적으로 꺼져 있습니다. Codex는 자체 툴 (apply_patch, exec_command 등)을 기존 승인 및 sandbox 정책에 따라 계속 사용합니다. Cursor가 Codex 승인 경로 없이 로컬 파일을 읽고, 쓰고, 지우고, 나열하거나 grep/shell/fetch를 실행해도 되는 신뢰된 로컬 실험에서만 unsafeAllowNativeLocalExec을 설정하세요.

{
  "providers": {
    "cursor": {
      "adapter": "cursor",
      "baseUrl": "https://api2.cursor.sh",
      "authMode": "oauth",
      "defaultModel": "auto",
      "unsafeAllowNativeLocalExec": true
    }
  }
}

이 플래그는 최상위 config.json이 아니라 프로바이더 객체(providers.cursor)에 둡니다.

웹 대시보드에서도 설정할 수 있습니다. Providers → Cursor → Edit JSON에서 "unsafeAllowNativeLocalExec": true를 추가해 저장한 뒤 프록시를 재시작하세요(ocx restart 또는 ocx stop + ocx start).

MCP, 화면 녹화, computer-use는 별도의 mcpServers / desktopExecutor 설정을 쓰며 이 플래그의 영향을 받지 않습니다.

Cursor 통합 레코드

mcpServers.<name> 값은 command(stdio) 또는 url(Streamable HTTP) 중 하나를 받습니다. stdio 항목에는 args?: string[], env?: Record<string,string>, cwd?: string도 넣을 수 있고, HTTP 항목에는 headers?: Record<string,string>을 넣을 수 있습니다. 두 형식 모두 enabled?: boolean(기본 true)과 toolPrefix?: string을 지원합니다.

desktopExecutorcomputerUseCommand?, recordScreenCommand?, cwd?, env?: Record<string,string>, timeoutMs?(기본 30000)를 받습니다. 명령은 sh -c로 실행되며, stdin에서 JSON 요청 하나를 읽고 stdout에 JSON 결과 하나를 써야 합니다.

:::caution[보안] Codex 승인과 sandbox 규칙을 우회하는 Cursor 네이티브 로컬 실행이 명확히 필요한 경우가 아니라면 unsafeAllowNativeLocalExec을 생략하거나 false로 두세요. :::

OpenRouter 프로바이더 라우팅

OpenRouter에서 같은 모델을 제공하는 endpoint마다 prompt cache 지원, 적중률, 유지 시간과 가격이 다를 수 있습니다. openRouterRouting으로 기본 프로바이더를 지정하고, modelOpenRouterRouting으로 특정 모델의 설정을 대체할 수 있습니다. 설정은 OpenRouter의 order, only, allow_fallbacks 요청 필드로 변환됩니다. allowFallbacks: false는 지정한 프로바이더가 실패했을 때 다른 endpoint로 전환하지 않고 요청을 실패시킵니다.

{
  "openRouterRouting": { "order": ["deepseek"], "allowFallbacks": false },
  "modelOpenRouterRouting": {
    "anthropic/claude-sonnet-5": { "only": ["anthropic"], "allowFallbacks": false }
  }
}

정적 모델 allowlist

일부 프로바이더는 실시간 모델 카탈로그가 매우 크거나 느립니다. Codex에 models로 고정한 모델만 보이게 하려면 liveModelsfalse로 설정하세요.

실시간 discovery 응답이 4 MiB 또는 원시 모델 행 2,000개를 넘으면 캐시 전에 거부됩니다. 기본 제공 preset은 이 한도를 더 낮추고 혼합 카탈로그를 채팅 가능 행으로 필터링할 수 있습니다. 한도 초과 또는 손상된 응답은 stale/static fallback을 사용하고, 부적격 행은 제외됩니다. 유효한 응답에 적격 행이 없으면 권위 있는 빈 카탈로그가 되며, 한도 초과 응답을 조용히 잘라 사용하지 않습니다.

liveModelsfalse이고 models가 비어 있거나 생략되면 opencodex는 해당 프로바이더의 라우팅 모델을 하나도 노출하지 않습니다.

selectedModels는 목적이 다릅니다. 모델 발견은 계속 실행하되 선택한 id만 Codex 카탈로그와 /v1/models에 게시합니다. 대시보드에는 전체 모델 목록이 남으므로 나중에 allowlist를 바꿀 수 있습니다.

프리뷰 GPT-5.6 fallback 항목도 같은 방식을 씁니다. OpenAI API 키 preset은 base와 Pro id를 context 1050000, max input 922000으로 seed하고, OpenRouter preset은 openai/gpt-5.6-sol, openai/gpt-5.6-terra, openai/gpt-5.6-luna를 context 1050000으로 seed합니다. Pool/Direct Codex catalog 계약은 372000입니다. 동기화된 Codex 카탈로그에서는 max reasoning을 알리되 xhigh와 구분합니다. 실시간 프로바이더 결과와 이 명시적 항목을 합치려면 liveModels를 켜 두고, models만 노출하려면 false로 설정하세요.

{
  "providers": {
    "openrouter": {
      "adapter": "openai-chat",
      "baseUrl": "https://openrouter.ai/api/v1",
      "apiKey": "${OPENROUTER_API_KEY}",
      "liveModels": false,
      "models": ["deepseek/deepseek-v4-flash", "qwen/qwen3-coder-plus"]
    }
  }
}

사이드카

webSearchSidecar (OcxWebSearchSidecarConfig)

Field Type Default Meaning
enabled? boolean 선택한 백엔드를 쓸 수 있을 때 on 전체 스위치. 웹 검색 사이드카를 끄려면 false로 설정합니다.
backend? "openai" | "anthropic" 자동 실행 백엔드. 명시한 값이 우선하며, 생략하면 쓸 수 있는 Anthropic OAuth 계정이 있을 때 anthropic, 없을 때 openai를 선택합니다.
model? string 백엔드별 기본값 검색 모델. openaigpt-5.6-luna, anthropicclaude-sonnet-5를 씁니다. 명시적으로 남은 기존 gpt-5.4-mini 값은 시작할 때 마이그레이션합니다.
reasoning? string low 사이드카 reasoning effort(minimal은 웹 검색과 함께 쓸 수 없음).
maxSearchesPerTurn? number 3 메인 모델 한 turn에서 실행할 실제 검색 총횟수(loop guard).
routedModelStallTimeoutMs? number 200000 설정 파일에서만 지정할 수 있는 라우팅 모델 반복별 원시 응답 byte 연속 무활동 deadline. 1부터 2147483647까지의 정수여야 하며, 비어 있지 않은 응답 body chunk가 올 때마다 다시 시작됩니다.
timeoutMs? number 200000 호스팅 웹 검색 요청 하나를 제한하는 별도 deadline.

openai 백엔드는 활성화된 ChatGPT forward 프로바이더에서 호스팅 검색을 실행하므로 ChatGPT 로그인과 해당 프로바이더가 모두 필요합니다. Claude Code에서 들어온 라우팅 요청은 내부 사이드카 호출에 메인 ChatGPT 인증을 주입하므로 이 경로에 연결할 수 있습니다. anthropic 백엔드는 활성화된 Anthropic OAuth 프로바이더의 저장된 활성 자격 증명으로 Claude의 web_search_20250305 도구를 실행합니다. backend: "anthropic"을 명시했는데 활성 계정을 쓸 수 없거나 needsReauth 상태라면 OpenAI로 바꾸지 않고 실패 후 중단합니다.

웹 검색 경로에는 네 가지 clock이 있습니다. 기본 bridge event stall 예산(stallTimeoutSec), DNS/TCP/TLS/최종 header 예산(connectTimeoutMs), 라우팅 모델의 원시 byte 무활동 (routedModelStallTimeoutMs), 호스팅 검색 하나의 제한(timeoutMs)입니다. 실제 bridge watchdog은 max(기본 stall, connect timeout, 라우팅 모델 stall, 사이드카 timeout) + 30초입니다. 라우팅 모델 stall은 무활동 감시 장치이며 전체 생성 timeout이 아닙니다.

visionSidecar (OcxVisionSidecarConfig)

Field Type Default Meaning
enabled? boolean 선택한 백엔드를 쓸 수 있을 때 on 전체 스위치. 이미지 설명을 끄려면 false로 설정합니다.
backend? "openai" | "anthropic" 자동 실행 백엔드. 웹 검색과 같은 명시값 우선, Anthropic 자격 증명 감지 규칙을 사용합니다.
model? string 백엔드별 기본값 이미지 설명 모델. openaigpt-5.4-mini, anthropicclaude-sonnet-5를 씁니다.
maxDescriptionsPerTurn? number 8 메인 모델 한 turn에서 새로 실행할 설명(cache miss)의 최대 개수. 0이면 설명 호출을 하지 않으며, 잘못된 값은 기본값을 씁니다.
timeoutMs? number 45000 사이드카 fetch timeout.

비전 사이드카는 프로바이더의 noVisionModels 목록에 해당하는 모델로 이미지가 들어올 때만 작동합니다. OpenAI 백엔드는 웹 검색과 마찬가지로 ChatGPT 로그인과 forward 프로바이더가 모두 필요합니다. Anthropic 백엔드는 저장된 OAuth를 사용하며, 사용할 수 있는 자격 증명 없이 명시하면 실패 후 중단합니다. 성공한 data: 이미지 설명은 백엔드, 모델, detail, 이미지 바이트, 정규화한 메시지 문맥을 키로 삼아 크기가 제한된 프로세스 캐시에 저장합니다. 캐시 적중과 같은 turn의 중복 요청은 maxDescriptionsPerTurn 한도를 쓰지 않습니다. 원격 https: 이미지와 실패하거나 빈 설명은 캐시하지 않습니다.

Anthropic OAuth 검색과 이미지 설명 요청은 opencodex에서 이미 사용 중인 Claude Code OAuth fingerprint 방식을 그대로 따릅니다. 저장소의 기존 OAuth 선례 안에 있지만, 실제로 사용할 계정과 작업량으로 충분히 soak test하는 편이 좋습니다.

전체 예시

{
  "port": 10100,
  "defaultProvider": "openai",
  "providers": {
    "openai": {
      "adapter": "openai-responses",
      "baseUrl": "https://chatgpt.com/backend-api/codex",
      "authMode": "forward"
    },
    "anthropic": {
      "adapter": "anthropic",
      "baseUrl": "https://api.anthropic.com",
      "authMode": "oauth",
      "defaultModel": "claude-sonnet-4-6"
    },
    "ollama-cloud": {
      "adapter": "openai-chat",
      "baseUrl": "https://ollama.com/v1",
      "apiKey": "${OLLAMA_API_KEY}",
      "defaultModel": "glm-5.2",
      "noVisionModels": ["glm-5.2", "gpt-oss", "qwen3-coder", "deepseek-v4-pro"]
    }
  },
  "subagentModels": ["anthropic/claude-opus-5", "ollama-cloud/glm-5.2"],
  "disabledModels": [],
  "websockets": false,
  "webSearchSidecar": {
    "maxSearchesPerTurn": 3,
    "routedModelStallTimeoutMs": 200000,
    "timeoutMs": 200000
  },
  "visionSidecar": { "enabled": true }
}

:::tip[시크릿] 키에는 ${ENV_VAR} 참조를 사용해 config.json에 시크릿이 남지 않게 하세요. OAuth와 forward 프로바이더는 키를 저장하지 않습니다. :::

:::note[원자적 쓰기] 모든 설정 및 카탈로그 파일(config.toml, opencodex-catalog.json)은 atomicWriteFile(임시 파일 + 이름 바꾸기)로 원자적으로 기록합니다. ocx stop과 프록시 자체 종료 handler처럼 여러 writer가 동시에 Codex를 복원하더라도 파일이 반만 기록되는 일을 막습니다. :::