Codex CLI — Configuration with OmniRoute (한국어)
실제로 적용되는 형식은 TOML뿐입니다. 최신 Codex는 오직
~/.codex/config.toml만 읽습니다(codex-cli 0.147.0에서 확인됨:codex --help에는-c/--config재정의가 “~/.codex/config.toml에서 로드됨”이라고 설명되어 있습니다). 이전~/.codex/config.yaml은 레거시 npm CLI용이었으며 아무런 알림 없이 무시됩니다. 대시보드 생성기(/api/cli-tools/apply, 도구codex)는 보수적인 병합 방식으로 TOML을 작성합니다. 기존 키와 다른 공급자 블록은 보존되고, API 키는OMNIROUTE_API_KEY에 유지되며(파일에는 절대 저장되지 않음), 남아 있는 레거시config.yaml은 수정되지 않은 상태로 마이그레이션 참고 사항에 보고됩니다.
바로 붙여 넣을 수 있는 config.toml
섹션 제목: “바로 붙여 넣을 수 있는 config.toml”<YOUR_HOST>와 <YOUR_KEY>를 실제 값으로 바꾸세요:
model = "cx/gpt-5.5"model_provider = "omniroute"model_reasoning_effort = "xhigh"model_context_window = 400000model_auto_compact_token_limit = 350000tool_output_token_limit = 32768 # 도구 호출별 기록 저장 한도
[model_providers.omniroute]name = "OmniRoute"base_url = "http://<YOUR_HOST>:20128/v1"env_key = "OMNIROUTE_API_KEY"requires_openai_auth = falsewire_api = "responses"# ~/.bashrc 또는 ~/.zshrc — 실제 키 값이며 config.toml에는 절대 저장하지 않음export OMNIROUTE_API_KEY="<YOUR_KEY>"macOS: ChatGPT 앱에 번들로 포함된 Codex
섹션 제목: “macOS: ChatGPT 앱에 번들로 포함된 Codex”ChatGPT 데스크톱 앱을 통해 Codex를 설치했다면 codex 바이너리가
앱 번들 내부에만 존재하고 아직 셸 PATH에 포함되지 않았을 수 있습니다. 리소스
디렉터리를 셸 시작 파일에 추가하세요:
export PATH="/Applications/ChatGPT.app/Contents/Resources:$PATH"새 셸을 연 후 다음과 같이 확인하세요:
command -v codexcodex --version인증이 필요 없는 로컬 OmniRoute: 자리표시자 키로 충분함
섹션 제목: “인증이 필요 없는 로컬 OmniRoute: 자리표시자 키로 충분함”Codex는 첫 번째 요청이 CLI를 떠나기 전에 env_key로 지정된 환경 변수가
존재하는지 확인합니다. 로컬 OmniRoute 인스턴스에 인증이 필요하지 않다면
비어 있지 않은 임의의 자리표시자를 사용할 수 있습니다:
export OMNIROUTE_API_KEY="${OMNIROUTE_API_KEY:-local}"OmniRoute 서버가 보호되어 있거나 원격에 있는 경우에는 실제 키를 사용하세요.
일반적인 호스트 옵션
접근 방식 URL 로컬 네트워크 http://192.168.0.1:20128/v1Tailscale http://100.x.x.x:20128/v1루프백 http://localhost:20128/v1
wire_api = "responses" — 모든 모델에서 작동하는 이유
섹션 제목: “wire_api = "responses" — 모든 모델에서 작동하는 이유”Codex CLI는 2026년 2월에 wire_api = "chat"(Chat Completions)을 더 이상 지원하지 않도록 변경했으며, 이제 wire_api = "responses"(OpenAI Responses API)를 필수로 요구합니다. v0.138부터 wire_api = "chat"으로 설정하면 시작 즉시 충돌이 발생합니다.
GLM과 Kimi를 포함한 많은 공급자는 여전히 Chat Completions 엔드포인트만 제공합니다. 이제 DeepSeek V4는 Anthropic 호환 엔드포인트와 함께 네이티브 Responses API도 제공합니다. OmniRoute는 기본적으로 Responses를 사용하며, 각 DeepSeek 연결에서 Anthropic 호환성을 선택할 수 있도록 합니다.
OmniRoute는 이를 투명하게 해결합니다:
Codex CLI → wire_api = "responses" → POST /v1/responses (OmniRoute) → OmniRoute가 공급자의 네이티브 프로토콜을 선택하고 필요할 때 변환 → POST /responses (DeepSeek V4) 또는 /chat/completions (Mistral / GLM / Kimi / 기타)OmniRoute를 사용할 때는 별도의 변환 프록시가 필요하지 않습니다. 모든 모델은 wire_api = "responses"를 사용하며, 나머지는 OmniRoute가 처리합니다.
wire_api는 기본값입니다 — 이 필드의 기본값은"responses"이므로config.toml에서 완전히 생략할 수 있습니다. 설정 의도를 문서화하려는 경우에만 명시적으로 지정하세요.
컨텍스트 창 및 압축
섹션 제목: “컨텍스트 창 및 압축”토큰 구성 필드
섹션 제목: “토큰 구성 필드”| 필드 | 설명 |
|---|---|
model_context_window |
활성 모델의 전체 토큰 예산입니다. 모델에서 명시한 한도로 설정합니다. |
model_auto_compact_token_limit |
자동 기록 압축을 트리거하는 임계값입니다. 최대: model_context_window의 90% — 90%를 초과하는 값은 별도 알림 없이 무시됩니다. |
tool_output_token_limit |
기록에 저장되는 각 도구 호출 출력의 토큰 상한입니다. 하나의 대용량 도구 응답이 컨텍스트 창을 가득 채우는 것을 방지합니다. 최대 출력이 아니라, 기록 저장 한도입니다. |
compact_prompt |
압축 중 사용되는 시스템 프롬프트에 대한 인라인 재정의입니다(v0.138+). |
model_max_output_tokens참고: 이 필드는 Codex CLI 구성 스키마에 포함되지 않습니다(Codex Rust 코드베이스에 존재하지 않음). 설정해도 별도 알림 없이 무시됩니다. 이 필드에 의존하지 말고, 기록에 저장되는 도구 출력의 양을 제어하려면tool_output_token_limit을 사용하세요.
모델별 컨텍스트 창
섹션 제목: “모델별 컨텍스트 창”| 모델 | OmniRoute ID | 컨텍스트 창 | auto_compact |
tool_output_limit |
|---|---|---|---|---|
| GPT-5.5 | cx/gpt-5.5 |
안정적 400k(최대 1M) | 350,000 | 32,768 |
| Kimi K2.7 (추론) | kmc/kimi-k2.7 |
131,072 | 112,000 | 32,768 |
| Kimi K2.6 | kmc/kimi-k2.6 |
131,072 | 112,000 | 32,768 |
| GLM-5.2 / 5.2-max (추론) | glm/glm-5.2 |
131,072 | 112,000 | 32,768 |
| MiMo V2.5 Pro (추론) | opencode-go/mimo-v2.5-pro |
131,072 | 112,000 | 32,768 |
| Qwen 3.7 Plus (추론) | opencode-go/qwen3.7-plus |
32,768 | 28,000 | 16,384 |
| DeepSeek V4 Pro (OllamaCloud) | ollamacloud/deepseek-v4-pro |
131,072 | 112,000 | 32,768 |
| DeepSeek V4 Pro | ds/deepseek-v4-pro |
1,000,000 | 900,000 | 65,536 |
| MiMo V2.5 | opencode-go/mimo-v2.5 |
131,072 | 112,000 | 32,768 |
| Gemma 4 31B (OllamaCloud) | ollamacloud/gemma4:31b |
32,768 | 28,000 | 16,384 |
| Nemotron 3 Super (OllamaCloud) | ollamacloud/nemotron-3-super |
32,768 | 28,000 | 16,384 |
| GPT-OSS 20B (OllamaCloud) | ollamacloud/gpt-oss:20b |
32,768 | 28,000 | 16,384 |
| DeepSeek V4 Flash (OllamaCloud) | ollamacloud/deepseek-v4-flash |
65,536 | 56,000 | 16,384 |
| Gemini 3 Flash Preview (OllamaCloud) | ollamacloud/gemini-3-flash-preview |
1,000,000 | 850,000 | 32,768 |
| GLM-5 Turbo | glm/glm-5-turbo |
131,072 | 112,000 | 16,384 |
| GLM-4.7 Flash | glm/glm-4.7-flash |
131,072 | 112,000 | 16,384 |
| Mistral Large Latest | mistral/mistral-large-latest |
262,144 | 220,000 | 16,384 |
압축 공식:
effective_window = model_context_window - min(tool_output_token_limit, 20000). 20k를 초과하는 값은 압축 트리거에 영향을 주지 않습니다.
경험 법칙:
model_auto_compact_token_limit을model_context_window의 85~88%로 설정하세요. 절대로 90%를 초과하지 마세요. 초과하는 값은 별도 알림 없이 무시됩니다.
모델 접두사: cx/
섹션 제목: “모델 접두사: cx/”OmniRoute의 모든 Codex 모델은 cx/ 접두사를 사용합니다:
| Codex CLI 이름 | OmniRoute 모델 |
|---|---|
cx/gpt-5.5 |
GPT-5.5 표준 |
cx/gpt-5.4 |
GPT-5.4 표준 |
cx/gpt-5.4-mini |
GPT-5.4 mini |
cx/gpt-5.1-codex-mini |
GPT-5.1 Codex mini |
다른 제공자는 자체 접두사(kmc/, glm/, ds/, ollamacloud/, opencode-go/, mistral/)를 사용하며, 접두사는 OmniRoute 제공자 별칭과 일치합니다.
추론 수준
섹션 제목: “추론 수준”응답하기 전에 모델이 얼마나 많이 “생각”할지 제어합니다.
| 값 | 용도 |
|---|---|
none |
추론 없음 — 직접 응답 |
low |
단순한 작업(이름 변경, 서식 지정) |
medium |
지정하지 않은 경우의 서버 기본값 |
high |
중간 수준의 작업(리팩터링, 디버깅) |
xhigh |
아키텍처, 심층 분석, 복잡한 문제 |
# 호출별 재정의codex -c model_reasoning_effort=low "rename variable x to count"codex -c model_reasoning_effort=xhigh "design the auth module"Desktop에서 암호화된 블롭뿐만 아니라 사고 텍스트도 표시할 수 있도록 추론 요약도 설정하세요:
model_reasoning_effort = "xhigh" # 지원되는 경우 ultra도 가능model_reasoning_summary = "detailed" # auto | concise | detailed | noneOmniRoute 사고 예산(서버 설정)
섹션 제목: “OmniRoute 사고 예산(서버 설정)”OmniRoute 호스트에서 Codex의 추론 수준/요약이 업스트림에 전달되려면 Settings → AI → Thinking Budget을 **passthrough**로 설정해야 합니다. auto 모드는 클라이언트의 모든 reasoning / reasoning_effort 필드를 제거하므로, Codex가 올바르게 구성되어 있어도 사고 패널이 비어 있게 됩니다.
전체 가이드: THINKING_BUDGET.md.
압축과 프롬프트 캐시는 서로 독립적이며 passthrough에서도 계속 작동합니다.
프로필 — 모델/워크플로별 명명된 구성
섹션 제목: “프로필 — 모델/워크플로별 명명된 구성”프로필을 사용하면 단일 플래그로 모델과 컨텍스트 창을 전환할 수 있습니다. 각 프로필은 기본 config.toml 위에 오버레이되는 평면 구조의
~/.codex/<name>.config.toml 파일입니다.
명명 규칙(Codex CLI v0.137+): 파일 이름은 반드시
~/.codex/<name>.config.toml이어야 하며,profile-접두사를 사용하면 안 됩니다. CLI는-p kimi-k27을~/.codex/kimi-k27.config.toml로 해석합니다. 파일을 찾지 못하면 기본값이 별다른 알림 없이 적용됩니다.
codex --profile kimi-k27 "analyze 10k lines of this codebase"codex -p glm52 "architecture review"codex --profile deepseek-flash "rename variable" # 빠르고 저렴함추론 수준 프로필(동일한 모델, 서로 다른 추론 수준)
섹션 제목: “추론 수준 프로필(동일한 모델, 서로 다른 추론 수준)”codex -p low # cx/gpt-5.5, effort=lowcodex -p medium # cx/gpt-5.5, effort=mediumcodex -p high # cx/gpt-5.5, effort=highcodex -p xhigh # cx/gpt-5.5, effort=xhigh(기본값)codex -p chat # cx/gpt-5.5, 추론 수준 미설정(서버 기본값)사고 모델 — xhigh + 상세 요약
섹션 제목: “사고 모델 — xhigh + 상세 요약”| 프로필 | 모델 | 컨텍스트 | 용도 |
|---|---|---|---|
kimi-k27 |
kmc/kimi-k2.7 |
128k | 최고의 사고 품질(Kimi) |
glm52 |
glm/glm-5.2 |
128k | GLM 사고 |
glm52max |
glm/glm-5.2-max |
128k | GLM 최대 사고 |
mimo-pro |
opencode-go/mimo-v2.5-pro |
128k | MiMo 사고 |
qwen37plus |
opencode-go/qwen3.7-plus |
32k | Qwen 사고 |
우수 모델 — 높은 추론 수준
섹션 제목: “우수 모델 — 높은 추론 수준”| 프로필 | 모델 | 컨텍스트 | 용도 |
|---|---|---|---|
kimi-k26 |
kmc/kimi-k2.6 |
128k | 범용(Kimi) |
deepseek-pro |
ollamacloud/deepseek-v4-pro |
128k | OllamaCloud를 통한 DeepSeek Pro |
deepseek |
ds/deepseek-v4-pro |
1M | DeepSeek Pro 직접 연결, 초대형 컨텍스트 |
mimo |
opencode-go/mimo-v2.5 |
128k | 범용 MiMo |
단순 모델 — 추론 수준 없음
섹션 제목: “단순 모델 — 추론 수준 없음”| 프로필 | 모델 | 컨텍스트 | 용도 |
|---|---|---|---|
gemma4 |
ollamacloud/gemma4:31b |
32k | 비용 효율적이고 유능함 |
nemotron |
ollamacloud/nemotron-3-super |
32k | NVIDIA Nemotron |
gptoss |
ollamacloud/gpt-oss:20b |
32k | 오픈 소스 GPT |
빠른 모델 — 낮은 추론 수준
섹션 제목: “빠른 모델 — 낮은 추론 수준”| 프로필 | 모델 | 컨텍스트 | 용도 |
|---|---|---|---|
deepseek-flash |
ollamacloud/deepseek-v4-flash |
64k | 빠른 작업 |
gemini-flash |
ollamacloud/gemini-3-flash-preview |
1M | 매우 빠르고 초대형 컨텍스트 |
glm5turbo |
glm/glm-5-turbo |
128k | GLM Turbo |
glm47flash |
glm/glm-4.7-flash |
128k | GLM Flash |
mistral |
mistral/mistral-large-latest |
256k | Mistral Large |
빠른 결정 표
섹션 제목: “빠른 결정 표”| 작업 | 권장 프로필 |
|---|---|
| 이름 변경, 포맷팅, 상용구 | --profile deepseek-flash 또는 -p low |
| 설명, 간단한 검토 | -p chat 또는 -p gemini-flash |
| 디버깅, 중간 규모 리팩터링 | -p medium 또는 -p kimi-k26 |
| 신규 기능, 복잡한 테스트 | -p high 또는 -p mimo |
| 아키텍처, 심층 분석 | -p kimi-k27 또는 -p glm52 또는 -p xhigh |
| 코드베이스 분석(1M 컨텍스트 필요) | --profile deepseek 또는 --profile gemini-flash |
| 최고 수준의 추론 품질 | -p glm52max 또는 -p mimo-pro |
| 비용 절감 | -p gemma4 또는 -p gptoss |
omniroute setup-codex로 프로필 자동 생성하기
섹션 제목: “omniroute setup-codex로 프로필 자동 생성하기”VPS에서 OmniRoute를 실행하는 경우, 실시간 모델 카탈로그에서 프로필 파일을 자동으로 생성할 수 있습니다:
# VPS에서 실행(포트 20128의 로컬 OmniRoute 사용)omniroute setup-codex
# 어느 머신에서든 실행 가능 — VPS 지정omniroute setup-codex --remote http://100.x.x.x:20128 --api-key sk-xxx
# 파일을 작성하지 않고 미리 보기omniroute setup-codex --remote http://100.x.x.x:20128 --dry-run
# GLM 및 Kimi 프로필만 생성omniroute setup-codex --only glm,kimi
# 사용자 지정 디렉터리에 작성omniroute setup-codex --codex-home /path/to/.codex이 명령은 /v1/models를 가져오고, 알려진 모델에는 최적화된 프로필을 사용하며, 그 외 호환되는 텍스트 모델에는 카탈로그 메타데이터를 대체 수단으로 사용한 다음, 각 모델에 대해 ~/.codex/<name>.config.toml을 작성합니다. 멱등성을 보장하므로 안전하게 다시 실행할 수 있습니다.
OmniRoute는 공급자 모델 검색/가져오기가 성공하여 실시간 카탈로그가 변경된 후 동일한 프로필 파일을 자동 동기화할 수도 있습니다. 이 기능은 옵트인이며 기본적으로 비활성화되어 있습니다. CLI Code 대시보드에서 전환하거나(“CLI profile auto-sync” → Codex), OMNIROUTE_AUTO_SYNC_CODEX_PROFILES=true를 설정하세요(CLI_ALLOW_CONFIG_WRITES도 따르며, 기본적으로 활성화되어 있습니다). 활성화하면 별도의 ~/.codex/*.config.toml 프로필 파일만 작성하며, 활성/기본 ~/.codex/config.toml, Codex-lb 설정, 인증 또는 공급자 선택은 절대 변경하지 않습니다.
omniroute launch-codex로 Codex 실행하기
섹션 제목: “omniroute launch-codex로 Codex 실행하기”Codex를 실행하기 전에 OmniRoute 인스턴스의 상태를 확인합니다:
# 로컬 OmniRoute를 대상으로 실행(기본 포트 20128)omniroute launch-codex
# 특정 프로필로 실행omniroute launch-codex --profile kimi-k27
# 원격 VPS를 대상으로 실행omniroute launch-codex --remote http://100.x.x.x:20128/v1 --api-key sk-xxx
# codex에 추가 인수 전달omniroute launch-codex --profile glm52 -- --yolo "fix this bug"Codex는 매니페스트 기반의 두 범용 진입점
(bin/cli/cli-manifest.mjs)에서도 대상이 됩니다:
# 대화형 모델 선택기 → ~/.codex/<name>.config.toml 작성(TOML, env_key)omniroute configure codex
# -c 플래그를 통해 omniroute 공급자를 주입하여 codex 실행(설정 파일을 작성하지 않음)omniroute run codex새로운 Codex CLI 기능(v0.138–v0.141)
섹션 제목: “새로운 Codex CLI 기능(v0.138–v0.141)”| 버전 | 기능 |
|---|---|
| v0.138 | 데스크톱 앱으로 전환(/app), v2 개인 액세스 토큰, 전용 프로필 선택기로서의 --profile(레거시 파일 내 [profiles] 테이블은 시작 시 충돌을 일으킴) |
| v0.139 | web_search = "live" — 코드 모드의 네이티브 웹 검색, MCP 도구 스키마의 oneOf/allOf, codex doctor 환경 진단 |
| v0.140 | 세션 내 /usage 토큰 보기, Claude Code 세션에서 /import, codex delete <SESSION_ID> 하위 명령, 공급자 설정의 aws 객체를 통한 Amazon Bedrock 인증 |
| v0.141 | 원격 실행기를 위한 E2E 암호화 Noise 릴레이, SQLite WAL 수정, P-521 TLS 지원 |
새로운 config.toml 필드(v0.137 이후)
섹션 제목: “새로운 config.toml 필드(v0.137 이후)”# 네이티브 웹 검색(v0.139)web_search = "live" # "disabled" | "cached" | "live"
# 별도의 개발자 시스템 프롬프트(v0.138)developer_instructions = "Always prefer functional style."
# 사용자 지정 압축 프롬프트compact_prompt = "Summarise the above as bullet points."
# /review를 더 저렴한 모델로 라우팅review_model = "glm/glm-5-turbo"
# OpenAI 서비스 계층service_tier = "fast" # "fast" | "flex"새로운 [model_providers.<id>] 필드
섹션 제목: “새로운 [model_providers.<id>] 필드”[model_providers.omniroute]base_url = "http://100.x.x.x:20128/v1"env_key = "OMNIROUTE_API_KEY"requires_openai_auth = false
# 모든 요청에 추가되는 정적 헤더[model_providers.omniroute.http_headers]"X-Custom-Header" = "value"
# 환경 변수에서 읽어 오는 헤더[model_providers.omniroute.env_http_headers]"X-Trace-Id" = "TRACE_ID"
# 추가 URL 쿼리 매개변수(Azure api-version에 유용)[model_providers.omniroute.query_params]"api-version" = "2024-12-01-preview"Amazon Bedrock 인증(v0.140)
섹션 제목: “Amazon Bedrock 인증(v0.140)”[model_providers.bedrock]base_url = "https://bedrock-runtime.us-east-1.amazonaws.com"
[model_providers.bedrock.aws]profile = "default" # ~/.aws/credentials 프로필region = "us-east-1"여러 서버
섹션 제목: “여러 서버”[model_providers.omniroute-main]base_url = "http://192.168.0.1:20128/v1"env_key = "OMNIROUTE_API_KEY"
[model_providers.omniroute-tailscale]base_url = "http://100.x.x.x:20128/v1"env_key = "OMNIROUTE_API_KEY"Claude Code — 동등한 구성
섹션 제목: “Claude Code — 동등한 구성”Codex CLI (config.toml) |
Claude Code (환경 변수) | 효과 |
|---|---|---|
tool_output_token_limit = 32768 |
(직접 노출되지 않음) | 도구별 기록 한도 |
model_context_window = 400000 |
(모델에 의해 결정됨) | 컨텍스트 창 |
| — | CLAUDE_CODE_MAX_OUTPUT_TOKENS=65536 |
응답당 최대 토큰 수 |
# ~/.bashrc — Claude Code 토큰 한도export CLAUDE_CODE_MAX_OUTPUT_TOKENS=65536빠른 참조 — CLI 플래그
섹션 제목: “빠른 참조 — CLI 플래그”| 플래그 | 단축형 | 효과 |
|---|---|---|
--model <id> |
-m |
이번 호출에서 model을 재정의함 |
--profile <name> |
-p |
~/.codex/<name>.config.toml을 로드함 |
--config key=value |
-c |
config.toml 필드를 재정의함(반복 가능) |
--enable <feature> |
— | 기능 플래그를 강제로 활성화함 |
--disable <feature> |
— | 기능 플래그를 강제로 비활성화함 |
--search |
— | 이번 호출에서 실시간 웹 검색을 활성화함 |
v0.140의 새로운 기능:
codex delete <SESSION_ID> # 세션 삭제codex delete <SESSION_ID> --force # 확인 건너뛰기codex debug models --bundled # 번들 모델 카탈로그를 JSON으로 나열대화형 세션 내부:
| 명령어 | 효과 |
|---|---|
/model |
모델 선택기를 엶 |
/usage |
이 세션의 토큰 사용량을 표시함(v0.140) |
/app |
데스크톱 앱으로 넘김(v0.138) |
/import |
Claude Code 세션을 가져옴(v0.140) |
/help |
모든 슬래시 명령어를 나열함 |
장시간 실행 작업
섹션 제목: “장시간 실행 작업”두 가지 OmniRoute 기본값이 여러 시간 동안 실행되는 Codex CLI 세션을 눈에 띄지 않게 방해할 수 있습니다. 어느 것도 Codex CLI 설정이 아니며, 둘 다 OmniRoute 측에 있습니다. 계정을 고정하고 유휴 시간 제한을 비활성화하는 업스트림 프록시에서 구성을 마이그레이션하는 사용자는 두 문제를 모두 겪은 뒤 OmniRoute가 “장시간 세션을 유지할 수 없다”고 결론 내리는 경우가 많습니다.
| 증상 | 가능한 원인 | 설정 항목 |
|---|---|---|
| 세션이 계속 계정을 전환함 / 턴 사이에 프롬프트 캐시 연속성이 사라짐 | 세션 선호도 TTL이 0임(비활성화됨) |
sessionAffinityTtlMs |
| 클라이언트에 표시되는 안내 없이 추론 도중 연결이 끊김 | 업스트림 청크가 10분 동안 없어 스트림 유휴 감시기가 작동함 | STREAM_IDLE_TIMEOUT_MS |
관련 논의: #7126 (장시간 작업 중단), #5718 (선호도가 기본적으로 비활성화된 이유). 추적: #7287.
1. 세션 선호도 — 하나의 대화를 하나의 계정에 고정
섹션 제목: “1. 세션 선호도 — 하나의 대화를 하나의 계정에 고정”기본값: sessionAffinityTtlMs = 0 (비활성화됨).
설정 위치
- 대시보드 → 설정 → 라우팅 → 세션 선호도 → 선호도 TTL(초) (
ComboDefaultsTab) - 또는 밀리초 단위의
sessionAffinityTtlMs로 설정을 PATCH함(Zod 범위0–86_400_000, 즉 최대 24시간)
#7274에서 Codex 전용이었던
codexSessionAffinityTtlMs의 이름이 변경되었습니다. 레거시 키는 여전히 읽기 전용 별칭으로 허용되지만, 새 구성에서는sessionAffinityTtlMs를 사용해야 합니다. 이제 TTL이0보다 크면 선호도가 Codex뿐만 아니라 모든 제공자에 적용됩니다.docs/architecture/RESILIENCE_GUIDE.md→ 세션 선호도를 참조하세요.
0으로 유지할 때 발생하는 문제
여러 턴으로 구성된 Codex 대화의 각 턴은 활성 조합 전략에 따라 독립적으로 라우팅되며, 턴마다 다른 계정에 할당될 수 있습니다. 이로 인해 업스트림 세션 / 프롬프트 캐시 연속성이 깨집니다. OmniRoute는 TTL이 0보다 큰 경우에만 Codex 세션 헤더(x-codex-session-id / x-session-id / x-omniroute-session)와 prompt_cache_key / session_id 같은 본문 필드를 참조합니다(src/sse/services/auth.ts의 extractSessionAffinityKey).
여러 시간 동안 실행되는 단일 작업에 대한 권장 설정
TTL을 예상 작업 경과 시간보다 길게 설정하세요(UI 최대값은 86400초 = 24시간):
| 예상 작업 시간 | 선호도 TTL(UI, 초) | sessionAffinityTtlMs |
|---|---|---|
| 몇 시간 | 14400 (4시간) |
14400000 |
| 밤새 / 약 12시간 | 43200 (12시간) |
43200000 |
| 하루 종일 | 86400 (24시간, 최대값) |
86400000 |
옵트인은 의도된 동작입니다. 선호도를 비활성화하면 여러 계정 간의 부하 분산에 유리하고, 활성화하면 하나의 장시간 에이전트 세션에서 연속성을 유지하는 데 유리합니다. 이 가이드에서는 기본값을 변경하지 않습니다. 장시간 Codex 작업을 실행하는 운영자는 직접 옵트인해야 합니다.
2. 스트림 유휴 시간 제한 — 조용한 추론 턴을 종료하지 않기
섹션 제목: “2. 스트림 유휴 시간 제한 — 조용한 추론 턴을 종료하지 않기”기본값: STREAM_IDLE_TIMEOUT_MS = 600000 (10분). 설정되지 않은 경우 REQUEST_TIMEOUT_MS에서 상속되며, 공유 기준값 역시 600000입니다. docs/guides/SETUP_GUIDE.md → 시간 제한을 참조하세요.
기본값에서 발생하는 문제
10분 넘게 실제 업스트림 청크가 하나도 없이 조용히 유지되는 Codex 추론/도구 턴은 SSE 유휴 감시기(open-sse/utils/stream.ts)에 의해 강제로 종료됩니다. 클라이언트에서는 아무 설명 없는 연결 끊김으로 보이는 경우가 많으며, 이는 “알림 없이 자동으로 중지됨”이라는 현상과 일치합니다.
중요한 세부 사항: OmniRoute의 합성 SSE 하트비트는 유휴 타이머를 재설정하지 않습니다. 실제 업스트림 본문 청크만 lastChunkTime을 갱신합니다. 여전히 “생각 중”이지만 조용한 모델은 감시기의 관점에서 중단된 업스트림과 동일하게 보입니다.
관련된 Undici 본문 비활성 제한: FETCH_BODY_TIMEOUT_MS(기본값 역시 동일한 10분 기준이며, 0으로 설정하면 비활성화됩니다). 스트리밍에서 FETCH_TIMEOUT_MS는 연결 설정/첫 번째 헤더 수신까지만 적용됩니다. 스트림이 활성화된 이후의 중단은 STREAM_IDLE_TIMEOUT_MS와 FETCH_BODY_TIMEOUT_MS에 의해 제어됩니다.
여러 시간 동안 실행되는 단일 작업에 대한 권장 설정
OmniRoute 프로세스 환경(.env / compose / systemd)에서:
# 긴 추론 턴을 위해 스트림 유휴 및 본문 비활성 제한을 비활성화STREAM_IDLE_TIMEOUT_MS=0FETCH_BODY_TIMEOUT_MS=0또는 예상되는 가장 긴 무응답 간격보다 큰 값으로 설정합니다(단위는 밀리초):
# 예시: 업스트림 청크 사이에 최대 2시간의 무응답 허용STREAM_IDLE_TIMEOUT_MS=7200000FETCH_BODY_TIMEOUT_MS=7200000이 환경 변수를 변경한 후 OmniRoute를 재시작하세요.
구체적인 절차 — 여러 시간 동안 실행되는 Codex 작업
섹션 제목: “구체적인 절차 — 여러 시간 동안 실행되는 Codex 작업”- 계정 고정: Dashboard → Settings → Routing → Session affinity → Affinity TTL =
43200(12시간) 또는86400(최대 24시간). - OmniRoute 환경에서 유휴 제한을 늘리거나 비활성화합니다.
STREAM_IDLE_TIMEOUT_MS=0FETCH_BODY_TIMEOUT_MS=0- 일반적인 Codex
config.toml(wire_api = "responses", 올바른base_url,OMNIROUTE_API_KEY)을 그대로 사용하세요. 이 두 동작을 제어하는 Codex 측 선호도/유휴 설정은 없습니다. - OmniRoute를 재시작한 후 장시간 Codex 작업을 시작하세요.
기본값 결정 (#7287)
섹션 제목: “기본값 결정 (#7287)”| 설정 | 제공 기본값 | 이 가이드에서 변경? |
|---|---|---|
sessionAffinityTtlMs |
0(꺼짐) |
아니요 — 옵트인 상태 유지(부하 분산과 연속성 간의 절충, Discussion #5718 참조) |
STREAM_IDLE_TIMEOUT_MS |
600000(10분) |
아니요 — 일반 트래픽에는 10분 유지. 장시간 Codex 운영자는 값을 늘리거나 비활성화 |
두 기본값 중 하나라도 전역적으로 변경하면 Codex뿐만 아니라 해당 인스턴스의 모든 클라이언트 동작이 바뀝니다. 설정 방법을 문서화하되, 운영자가 명시적으로 다른 결정을 내리기 전까지는 기본값을 그대로 유지하세요.
유휴 종료 진단
섹션 제목: “유휴 종료 진단”유휴 감시기가 작동하면 OmniRoute는 다음과 같은 형식의 로그를 남깁니다.
[STREAM] 유휴 시간 초과: 600000ms 동안 codex에서 데이터가 없음 (모델: cx/gpt-5.5)Idle timeout: no data from(또는 코드 stream_idle_timeout / 오류 이름 StreamIdleTimeoutError)을 grep으로 검색하세요. 공급자 부분에는 해당 요청에 대해 OmniRoute가 사용한 값(codex, 다른 공급자 ID 또는 알 수 없는 경우 provider)이 표시되므로, 항상 리터럴 문자열 codex인 것은 아닙니다.
문제 해결
섹션 제목: “문제 해결”Error: wire_api = "chat" is no longer supported
설정에서 wire_api = "chat"을 제거하세요. wire_api = "responses"로 설정하거나 해당 필드를 생략하세요(v0.138부터 기본값은 "responses"입니다).
Error: model not found
OmniRoute에 올바른 접두사를 사용하는 모델이 존재하는지 확인하세요. omniroute models list를 사용하거나 /dashboard/providers/<provider>를 여세요.
Authentication error
OMNIROUTE_API_KEY가 내보내졌는지 확인하세요: echo $OMNIROUTE_API_KEY.
ERROR: Missing environment variable: OMNIROUTE_API_KEY
Codex는 첫 번째 요청을 보내기 전에 환경 변수가 존재하는지 확인합니다. 인증이 필요한 서버에서는
실제 키를 내보내고, 로컬 OmniRoute 인스턴스에서
인증을 요구하지 않는 경우에는 OMNIROUTE_API_KEY=local과 같이 비어 있지 않은 자리표시자를 사용하세요.
~/.bashrc 또는 ~/.zshrc에 추가했다면 셸을 다시 시작하세요.
Connection refused
OmniRoute가 실행 중인지, 그리고 base_url 호스트/포트가 네트워크 환경(로컬, Tailscale 또는 VPS)에 맞게 올바른지 확인하세요.
컨텍스트 한도 근처에서 세션이 중단됨
model_context_window와 model_auto_compact_token_limit을 명시적으로 설정하세요. 위의 컨텍스트 창 표를 참조하세요.
압축이 너무 늦게 실행됨
model_auto_compact_token_limit을 컨텍스트 창의 80~85%로 낮추세요. 절대로 90%를 초과하도록 설정하지 마세요.
프로필이 로드되지 않음 (-p <name>이 아무 알림 없이 무시됨)
파일이 ~/.codex/<name>.config.toml에 존재하는지 확인하세요(profile- 접두사 없음). ls ~/.codex/*.config.toml을 실행하세요.
장시간 실행되는 Codex 작업이 도중에 중단되거나 턴 사이에 계정이 전환됨
장시간 실행 작업을 참조하세요. 세션 선호도(TTL을 작업 시간보다 길게 설정)를 활성화하고 STREAM_IDLE_TIMEOUT_MS / FETCH_BODY_TIMEOUT_MS 값을 늘리거나 비활성화하세요. OmniRoute 로그에서 Idle timeout: no data from을 grep으로 검색하세요.
HagiCode
HagiCode는 구조화된 워크플로, 다중 에이전트 실행, Hero Dungeon 뷰를 갖춘 에이전트 코딩 작업 공간입니다.
더 스마트하고 빠르며 즐거운 에이전트 워크플로로 유용한 소프트웨어를 만드세요.

- Smart구조화된 워크플로는 의도를 아이디어부터 배포까지 실행 가능한 경로로 바꿉니다.
- Efficient다중 에이전트 워크플로로 조사, 구현, 검토를 병렬로 진행합니다.
- FunHero Dungeon은 긴 코딩 세션을 시각적이고 협업적인 경험으로 만듭니다.