콘텐츠로 이동
OmniRoute source

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>를 실제 값으로 바꾸세요:

~/.codex/config.toml
model = "cx/gpt-5.5"
model_provider = "omniroute"
model_reasoning_effort = "xhigh"
model_context_window = 400000
model_auto_compact_token_limit = 350000
tool_output_token_limit = 32768 # 도구 호출별 기록 저장 한도
[model_providers.omniroute]
name = "OmniRoute"
base_url = "http://<YOUR_HOST>:20128/v1"
env_key = "OMNIROUTE_API_KEY"
requires_openai_auth = false
wire_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 codex
codex --version

인증이 필요 없는 로컬 OmniRoute: 자리표시자 키로 충분함

섹션 제목: “인증이 필요 없는 로컬 OmniRoute: 자리표시자 키로 충분함”

Codex는 첫 번째 요청이 CLI를 떠나기 전에 env_key로 지정된 환경 변수가 존재하는지 확인합니다. 로컬 OmniRoute 인스턴스에 인증이 필요하지 않다면 비어 있지 않은 임의의 자리표시자를 사용할 수 있습니다:

터미널 창
export OMNIROUTE_API_KEY="${OMNIROUTE_API_KEY:-local}"

OmniRoute 서버가 보호되어 있거나 원격에 있는 경우에는 실제 키를 사용하세요.

일반적인 호스트 옵션

접근 방식 URL
로컬 네트워크 http://192.168.0.1:20128/v1
Tailscale 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%를 초과하지 마세요. 초과하는 값은 별도 알림 없이 무시됩니다.


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에서 암호화된 블롭뿐만 아니라 사고 텍스트도 표시할 수 있도록 추론 요약도 설정하세요:

~/.codex/config.toml
model_reasoning_effort = "xhigh" # 지원되는 경우 ultra도 가능
model_reasoning_summary = "detailed" # auto | concise | detailed | none

OmniRoute 호스트에서 Codex의 추론 수준/요약이 업스트림에 전달되려면 Settings → AI → Thinking Budget을 **passthrough**로 설정해야 합니다. auto 모드는 클라이언트의 모든 reasoning / reasoning_effort 필드를 제거하므로, Codex가 올바르게 구성되어 있어도 사고 패널이 비어 있게 됩니다.

전체 가이드: THINKING_BUDGET.md.

압축과 프롬프트 캐시는 서로 독립적이며 passthrough에서도 계속 작동합니다.


프로필 — 모델/워크플로별 명명된 구성

섹션 제목: “프로필 — 모델/워크플로별 명명된 구성”

프로필을 사용하면 단일 플래그로 모델과 컨텍스트 창을 전환할 수 있습니다. 각 프로필은 기본 config.toml 위에 오버레이되는 평면 구조의 ~/.codex/&lt;name&gt;.config.toml 파일입니다.

명명 규칙(Codex CLI v0.137+): 파일 이름은 반드시 ~/.codex/&lt;name&gt;.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=low
codex -p medium # cx/gpt-5.5, effort=medium
codex -p high # cx/gpt-5.5, effort=high
codex -p xhigh # cx/gpt-5.5, effort=xhigh(기본값)
codex -p chat # cx/gpt-5.5, 추론 수준 미설정(서버 기본값)
프로필 모델 컨텍스트 용도
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/&lt;name&gt;.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/&lt;name&gt;.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.&lt;id&gt;] 필드

섹션 제목: “새로운 [model_providers.&lt;id&gt;] 필드”
[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"
[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"

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

플래그 단축형 효과
--model &lt;id&gt; -m 이번 호출에서 model을 재정의함
--profile &lt;name&gt; -p ~/.codex/&lt;name&gt;.config.toml을 로드함
--config key=value -c config.toml 필드를 재정의함(반복 가능)
--enable &lt;feature&gt; — 기능 플래그를 강제로 활성화함
--disable &lt;feature&gt; — 기능 플래그를 강제로 비활성화함
--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=0
FETCH_BODY_TIMEOUT_MS=0

또는 예상되는 가장 긴 무응답 간격보다 큰 값으로 설정합니다(단위는 밀리초):

터미널 창
# 예시: 업스트림 청크 사이에 최대 2시간의 무응답 허용
STREAM_IDLE_TIMEOUT_MS=7200000
FETCH_BODY_TIMEOUT_MS=7200000

이 환경 변수를 변경한 후 OmniRoute를 재시작하세요.

구체적인 절차 — 여러 시간 동안 실행되는 Codex 작업

섹션 제목: “구체적인 절차 — 여러 시간 동안 실행되는 Codex 작업”
  1. 계정 고정: Dashboard → Settings → Routing → Session affinity → Affinity TTL = 43200(12시간) 또는 86400(최대 24시간).
  2. OmniRoute 환경에서 유휴 제한을 늘리거나 비활성화합니다.
터미널 창
STREAM_IDLE_TIMEOUT_MS=0
FETCH_BODY_TIMEOUT_MS=0
  1. 일반적인 Codex config.toml(wire_api = "responses", 올바른 base_url, OMNIROUTE_API_KEY)을 그대로 사용하세요. 이 두 동작을 제어하는 Codex 측 선호도/유휴 설정은 없습니다.
  2. OmniRoute를 재시작한 후 장시간 Codex 작업을 시작하세요.
설정 제공 기본값 이 가이드에서 변경?
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/&lt;provider&gt;를 여세요.

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 &lt;name&gt;이 아무 알림 없이 무시됨) 파일이 ~/.codex/&lt;name&gt;.config.toml에 존재하는지 확인하세요(profile- 접두사 없음). ls ~/.codex/*.config.toml을 실행하세요.

장시간 실행되는 Codex 작업이 도중에 중단되거나 턴 사이에 계정이 전환됨 장시간 실행 작업을 참조하세요. 세션 선호도(TTL을 작업 시간보다 길게 설정)를 활성화하고 STREAM_IDLE_TIMEOUT_MS / FETCH_BODY_TIMEOUT_MS 값을 늘리거나 비활성화하세요. OmniRoute 로그에서 Idle timeout: no data from을 grep으로 검색하세요.


OmniRoute 소스 코드 (a58000c7685f)

HagiCode

HagiCode는 구조화된 워크플로, 다중 에이전트 실행, Hero Dungeon 뷰를 갖춘 에이전트 코딩 작업 공간입니다.

더 스마트하고 빠르며 즐거운 에이전트 워크플로로 유용한 소프트웨어를 만드세요.

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