콘텐츠로 이동

변경 내역

Continuum Router의 모든 주요 변경 사항은 이 파일에 문서화되어 있습니다.

형식은 Keep a Changelog를 기반으로 하며, 이 프로젝트는 Semantic Versioning을 따릅니다.

v1.10.2 - 2026-06-15

추가됨

  • Kimi K2.7-Code와 GLM-5.2 모델 메타데이터를 추가했습니다 (#775). Kimi K2.7-Code는 MoonViT 비전 인코더와 256K 컨텍스트를 갖춘 1조 파라미터 MoE(활성 32B)입니다. thinking 모드로만 동작하고 추론을 네이티브 reasoning_content 필드로 반환하므로 <think> 마커 설정을 두지 않습니다. GLM-5.2는 GLM-5 계열의 코딩 플래그십으로 1M 컨텍스트 윈도우와 131K 최대 출력, 두 단계의 thinking-effort(High, Max)를 지원합니다. GLM 계열과 마찬가지로 표준 <think>/</think> 마커 설정을 둡니다. GLM-5.2 단독 API 가격은 출시 시점에 공개되지 않아 입력·출력 요금을 GLM-5/GLM-5.1 티어에서 추정했습니다.

수정됨

  • vLLM/OpenAI 호환 reasoning 필드를 /v1/chat/completions에서 정규 reasoning_content로 정규화했습니다 (#776, closes #774). 최신 vLLM이 추론 출력 필드를 reasoning_content에서 reasoning으로 바꾸었습니다(스트리밍 delta.reasoning, 비스트리밍 message.reasoning). 라우터가 이를 그대로 중계하면서 reasoning_content를 읽는 클라이언트는 self-host vLLM 추론 모델의 추론 텍스트를 조용히 잃었습니다. 정규화는 모든 OpenAI 호환 중계 경로에서 동작합니다. 스트리밍 기본·thinking 변환기, unix-socket 중계, mid-stream fallback 중계, 비스트리밍 프록시 본문이 대상입니다. 같은 객체에 reasoning_content가 없을 때만 적용하므로 정규 이름을 이미 쓰는 업스트림은 덮어쓰지 않습니다. Gemini·Anthropic 핸들러와 Responses API에는 적용되지 않습니다.

문서

  • reasoning-effort 아키텍처 문서(영문·국문)에 라우터가 업스트림 vLLM reasoning 필드를 reasoning_content로 정규화한다는 설명을 추가했습니다.

v1.10.1 - 2026-06-15

추가됨

  • API 키별·사용자별 사용량 통계 REST API를 추가했습니다. 관리자 인증 라우터 아래에 기존 /admin/stats/models와 같은 형태로 GET /admin/stats/api-keys, GET /admin/stats/api-keys/{id}, GET /admin/stats/users, GET /admin/stats/users/{user_id} 네 개 엔드포인트를 둡니다 (#772, closes #770). StatsCollectorper_api_keyper_user 차원이 추가됩니다. Prometheus llm_tokens_total 카운터를 갱신하는 바로 그 스폰 태스크에서 함께 기록하므로 이 인메모리 차원은 더 이상 metrics 피처에 의존하지 않으며 실패한 요청이나 토큰이 0인 요청까지 집계됩니다. api_key_id는 요청 핫 패스 밖에서 한 번만 해석하는 파생된 비가역 식별자입니다. 인증되지 않은 요청은 "anonymous" 버킷으로 묶이고 차원당 1000개 상한을 넘는 식별자는 "unknown" 오버플로 버킷으로 묶여 전체 합계에는 그대로 반영됩니다. GET /admin/stats/.../{id}는 기록된 사용량이 없는 식별자에 404를 반환합니다. 선택적 window 쿼리 파라미터는 응답에 그대로 돌려주지만 필터링하지는 않습니다. 집계가 /admin/stats/models처럼 전체 기간 누적 카운터이기 때문입니다. 스냅샷·영속 형식은 두 차원을 모두 #[serde(default)]로 추가하므로 이 변경 이전에 기록된 스냅샷도 형식 버전을 올리지 않고 그대로 로드됩니다.

변경됨

  • 루트 디렉터리의 .sh 스크립트를 .gitignore로 무시해 로컬 헬퍼 스크립트가 실수로 커밋되지 않도록 했습니다.

문서

  • 관리자 API 키 관리 엔드포인트와 API 키별·사용자별 사용량 통계를 영문과 국문 양쪽 관리자 REST API 레퍼런스에 문서화했습니다 (#773, closes #770). 새로 추가한 'API 키 관리 API' 절은 여덟 개 /admin/api-keys 엔드포인트(생성·목록·조회·수정·삭제·회전·활성화·비활성화)를 다룹니다. 여기에는 sk-***abcd 마스킹과 생성 시 전체 값을 한 번만 노출하는 동작을 반영한 요청·응답 스키마, ApiKeyConfig 필드, permissiveblocking api_keys.mode 동작, persistence_file을 통한 런타임 키 영속과 핫 리로드 설명이 들어갑니다. 통계 절에는 네 개의 새 통계 엔드포인트, window 에코, anonymousunknown 버킷, 차원당 상한, api_key_id와 발급된 키 id의 연결을 추가했습니다.

v1.10.0 - 2026-06-12

추가됨

  • Codex(ChatGPT OAuth) 백엔드의 동적 모델 열거를 추가했습니다 (#753, closes #752). Codex 백엔드에는 표준 /v1/models가 없으므로, 라우터가 모델 검색 시 로드된 OAuth 토큰으로 플랜에 따라 게이팅되는 GET <base>/models?client_version=<ver> 엔드포인트를 조회하고, 사용자에게 노출되는 항목(visibility: list이며 available_in_plans가 비어 있거나 계정의 chatgpt_plan_type 클레임과 일치)만 남겨 /v1/models 응답과 라우팅을 채웁니다. 네트워크 오류, 2xx 아닌 응답, 빈 목록 등 어떤 실패에도 설정된 models: 목록이 폴백으로 남으며, 이 동작은 Codex OAuth 백엔드에만 적용됩니다.

변경됨

  • src/services/responses/sse.rs에 공유 parse_responses_body를, src/http/streaming/handler.rs에 공유 build_openai_chat_request_core를 추출해, Codex, 패스스루, Anthropic 핸들러 변형에 걸쳐 중복돼 있던 /responses SSE 집계 파싱 경로와 스트리밍 요청 구성 로직을 제거했습니다 (#766, closes #762). 동작 변화는 없으며, 한 사본의 수정이 다른 사본에 전파되지 않는 드리프트 위험을 없앴습니다.

수정됨

  • Codex(ChatGPT OAuth) 채팅 완성을 백엔드의 /responses 엔드포인트로 라우팅합니다 (#755, closes #754). build_responses_url.../backend-api/codex 루트에 /v1/responses를 덧붙였는데, 업스트림 엣지가 그 경로를 403 HTML 페이지로 거부했고 라우터는 OAuth 토큰이 유효한데도 이를 불투명한 인증 오류로 노출했습니다. 이제 Codex 루트는 내부 /v1을 제거하는 공유 URL 컴포저를 거칩니다. 경로가 고쳐진 뒤에는 Codex가 문자열 input을 HTTP 400 "Input must be a list"로 거부하므로, sanitize_codex_responses_request가 단일 메시지의 문자열 input을 한 개짜리 아이템 리스트로 변환합니다.
  • OAuth 토큰 저장소에서 RFC3339 형식의 expires_at을 받아들입니다 (#756, closes #751). 이 필드가 단순 u64였기 때문에 날짜 문자열로 기록된 토큰 저장소는 역직렬화에 실패했고, 백엔드가 조용히 OAuth 전략을 잃은 채 인증 없이 요청을 보내 실제 원인이 가려진 불투명한 403으로 드러났습니다. expires_at은 이제 정수·실수 epoch 초, 숫자 문자열, 오프셋 포함 RFC3339 날짜를 모두 epoch 초로 정규화해 받아들이고, 그 외 값은 허용 형식을 명시한 오류로 거부합니다. 디스크의 표준 형태는 JSON 숫자 그대로이므로 기존 저장소와 저장/로드 왕복은 변하지 않습니다.
  • 클라우드 OpenAI로 향하는 /v1/chat/completions 요청에서 로컬 엔진 전용 필드(chat_template_kwargs, thinking_budget_tokens, enable_thinking, preserve_thinking, top_k, min_p, repeat_penalty)를 제거합니다 (#760, closes #758). 클라우드 OpenAI는 알 수 없는 최상위 키를 HTTP 400 "Unknown parameter"로 거부합니다. 이 제거는 api.openai.com을 게이트로 하는 공유 field_filter 모듈을 통해 기존 클라우드 Gemini 동작을 그대로 따르고, 클라우드 OpenAI로 채팅을 보내는 모든 지점(비스트리밍, 스트리밍, 폴백 루프의 각 홉)에서 실행되며, extra_bodyreasoning_effort는 절대 건드리지 않고, 로컬 OpenAI 호환 엔진에는 아무 동작도 하지 않아 백엔드 패스스루 계약을 보존합니다.
  • Codex 동적 열거에서 설정된 models: 선택을 존중하고 열거된 모델에 정리된 owned_by를 기록합니다 (#765, closes #763). 라이브 열거가 성공하면 운영자가 설정한 models: 허용 목록이 무시되어 /v1/models가 열거된 Codex 모델을 전부 노출했는데, 이제 후처리 필터가 일관되게 적용되어 비어 있지 않은 목록은 열거 결과를 선택한 부분집합으로 좁히고 빈 목록은 전체를 노출합니다. 열거된 Codex 항목의 owned_by에 원시 백엔드 이름이 들어가던 문제도 백엔드 타입에서 해소한 값(openai)으로 바로잡아 다른 모든 백엔드와 일치시켰습니다.
  • Codex(ChatGPT OAuth) 백엔드에서 stream:false로 들어온 /v1/chat/completions 요청에 올바른 비스트리밍 응답을 반환합니다 (#764, closes #761). Codex의 /responses 엔드포인트는 stream:true + store:false만 받아들이므로 stream:false를 보내면 HTTP 400 "Stream must be set to true"가 발생했습니다. sanitize_codex_responses_request가 이제 stream:truestore:false를 무조건 강제합니다. 두 번째 수정으로 PassthroughService::execute_request의 SSE 감지가 Content-Type: text/event-stream 없이 SSE 본문을 보내는 Codex 응답에도 대응합니다. looks_like_sse 스니퍼가 첫 비어 있지 않은 줄의 data:/event:/: 접두어를 확인하고, JSON 파싱이 실패하면 원래 파싱 오류를 드러내기 전에 SSE 집계를 한 번 재시도합니다.
  • Codex store:false 응답에서 response.output_text.delta 이벤트로부터 어시스턴트 메시지를 재구성합니다 (#768, closes #767). Codex가 store:false로 동작하면 종료 response.completed 이벤트의 output 배열이 비어 있고 어시스턴트 텍스트는 증분 response.output_text.delta 이벤트로만 전달됩니다. 이제 SSE 집계가 그 델타를 누적하고, 완료 이벤트에 어시스턴트 텍스트가 없으면 메시지 아이템을 합성해, 비스트리밍 클라이언트(제목/요약 유틸리티 경로 포함)가 빈 응답 대신 텍스트를 받습니다.

문서

  • v1.9.1 이후의 Codex 및 전송 계층 변경을 영문·국문 매뉴얼에 문서화했습니다. Codex Chat→Responses 요청 처리와 느슨한 expires_at 파싱(backends.md), 클라우드 OpenAI 필드 제거(backend-passthrough.md), Responses API의 item_reference 해소(api.md)를 다루고, 남은 국문 페이지를 정중한 -습니다 체로 통일해 모든 페이지가 한 목소리로 읽히게 했습니다.

v1.9.1 - 2026-06-11

추가됨

  • { "version": "<CARGO_PKG_VERSION>" }를 반환하는 GET /version 엔드포인트를 추가했습니다. appproxy를 비롯한 어떤 Cargo 피처에도 묶이지 않고 베이스 라우터에 무조건 등록되므로 표준 릴리스 바이너리에 항상 포함됩니다. 기존 GET /health 응답에도 version 필드를 더했습니다 (#750, closes #749). 두 엔드포인트 모두 /health와 마찬가지로 API 인증 경계 밖에 있어 다운스트림 소비자가 404에 막혀 fail-open으로 넘어가는 대신 실행 중인 라우터 버전을 확인해 기능을 게이팅할 수 있습니다.

v1.9.0 - 2026-06-10

추가됨

  • 옵트인 appproxy Cargo 피처로 AppProxy 워커 모드를 추가해, Continuum Router가 AppProxy 코디네이터의 제어를 받는 Backend.AI AppProxy 추론 워커로 동작할 수 있게 했습니다 (에픽 #709). 이 피처는 일부러 full에서 제외해 기본 빌드에는 영향이 없습니다.
  • 기반: 타입이 정의된 AppProxyWorkerConfig 섹션(코디네이터 URL, 공유 api_secret/jwt_secret, redis_url, 와일드카드 프런트엔드 파라미터, heartbeat/reconcile 주기, 이벤트 토글로 구성하며 두 bearer 시크릿은 Debug에서 가려지고 ${ENV_VAR} 참조는 backends[].api_key와 같은 경로로 해소됩니다), SerializableCircuit/RouteInfo 와이어 타입과 ProxyProtocol/AppMode/FrontendMode enum(snake_case와 kebab-case를 모두 허용하고 알 수 없는 필드는 무시), 그리고 모듈 골격을 마련했습니다 (#716).
  • 코디네이터 REST 클라이언트 CoordinatorClient를 추가했습니다. register, heartbeat, deregister, list_circuits, get_circuit를 제공하며 각 호출마다 X-BackendAI-Token과 매번 새로 발급한 X-BackendAI-RequestID를 싣고, 재시도 가능 오류(연결, 타임아웃)와 치명적 오류(HTTP 4xx)를 구분하는 오류 타입을 갖습니다 (#717).
  • 서킷-백엔드 변환과 reconcile: circuit_to_backends가 레플리카마다 BackendConfig 하나를 만들고(이름은 appproxy-<circuit_id>-r<route_key>, traffic_ratio는 라우트를 0으로 떨어뜨리지 않는 1..=1000 가중치로 매핑, runtime_variant로 vLLM 감지), apply_circuits가 변환된 백엔드를 기존 핫리로드 config_sender로 주입합니다. appproxy- 접두사로 네임스페이스를 두어 정적 설정과 Admin API 백엔드는 보존됩니다 (#718).
  • 워커 수명주기 서비스와 /status 엔드포인트: run_worker가 백오프와 함께 등록한 뒤 초기 서킷 풀을 수행하고, 이어 heartbeat 루프(코디네이터의 30초 LOST 타임아웃 안으로 유지)와 pull-reconcile 루프(놓친 이벤트를 받쳐 주는 상시 백스톱)를 돌립니다. 각 서킷의 모델은 레플리카의 GET /v1/models에서 자동 발견하고, 종료 시 등록을 해제합니다. 공유 인메모리 AppProxyRegistry는 서브도메인과 서킷 id로 색인됩니다 (#719).
  • 매니저가 발급한 엔드포인트 서브도메인을 구체적인 서킷으로 해소하고 요청 모델을 고정해, 기존 선택 경로가 그 서킷의 레플리카를 그대로 서빙하게 하는 Host/서브도메인 인그레스 리졸버를 추가했습니다. 디코드된 id를 서킷 id와 대조하고 alg:none 다운그레이드를 거부하는 HS256 서킷 bearer 검증, 교차 서킷 모델 집계를 위한 선택적 aggregation_hosts 필드, 그리고 wildcard_domain이 설정되지 않았을 때의 순수 통과 동작을 포함합니다 (#720).
  • 레거시 모드 코디네이터에 1초 미만의 서킷 갱신을 주는 Redis Pub/Sub 서킷-이벤트 오버레이: 지수 백오프 재연결을 갖춘 구독 루프, base64 + msgpack 봉투 코덱, circuit_created / circuit_removed / circuit_route_updated 핸들러, 그리고 코디네이터의 E10001 "Proxy worker not responding" 오류를 막는 ack 봉투를 추가했습니다 (#721).
  • Claude Fable 5(claude-fable-5)와 Mythos 5(claude-mythos-5) 모델을 지원합니다 (#747). 둘 다 1M 컨텍스트, 최대 출력 128K, MTok당 \(10/\)50 가격이며, Mythos 5는 안전 분류기를 제거한 동일 모델로 한정 공개인 Project Glasswing 릴리스로만 제공됩니다. 새 is_mythos_class 헬퍼가 두 id를 Anthropic 능력 게이트로 라우팅합니다. adaptive thinking이 필수이고(레거시 budget_tokens는 HTTP 400으로 거부되며 adaptive로 정규화), temperature/top_p/top_k는 제거되며, max effort 레벨을 지원하고(xhighmax로 매핑), 대화 중간 system 메시지를 보존합니다. 두 모델 모두 명시적 thinking.type == "disabled"를 거부하므로, explicit_thinking_for_model이 이제 Option을 반환해 400을 유발할 값을 전달하는 대신 thinking 파라미터를 아예 생략합니다. max effort 레벨이 더 이상 Opus 전용이 아니므로 opus_supports_max_effortsupports_max_effort로 이름을 바꿨습니다. 같은 처리가 OpenAI Responses API 변환 경로에도 적용됩니다.
  • Gemma 4 QAT 다섯 개 양자화 인식 학습(quantization-aware-training) 체크포인트(E2B, E4B, 12B Unified, 26B-A4B MoE, 31B dense)의 모델 메타데이터를 추가했습니다. 동작에 필요한 -it-qat 별칭과 해소/드리프트 가드 테스트를 포함합니다 (#723, #722 종료).
  • Gemma 4 12B Unified 모델 메타데이터를 추가했습니다 (#705).

변경됨

  • 요청 본문 추출기의 거부를 warn 수준으로 로깅해, 핸들러 실행 전에 Axum이 거부하는 잘못되거나 과대한 본문이 조용히 실패하지 않고 로그에 드러나도록 했습니다 (#707).

수정됨

  • 일시적인 속도 제한과 비일시적인 쿼터/크레딧 소진을 구분하고 업스트림 Retry-After 힌트를 존중해, HTTP 429에서 재시도 루프가 같은 업스트림을 연타하지 않게 했습니다 (#742, #740 종료). 이전에는 모든 429가 공급자의 Retry-After를 무시한 고정 지수 백오프로 최대 max_attempts(기본값 3)까지 재시도되어, 단일 업스트림이 제공하는 모델에서는 라우터가 이미 소진된 같은 엔드포인트를 다시 때리며 부하를 키우고 피할 수 없는 실패 앞에 지연만 더했습니다. RouterError::RateLimited 변형이 이제 retryable 플래그를 가집니다. 비일시적 429(OpenAI insufficient_quota / billing_hard_limit_reached, 그리고 "prepayment credits are depleted" 같은 명확한 크레딧 소진 문구)는 재시도 불가로 분류되어 라우터가 호출 한 번 만에 빠르게 실패하고 공급자의 상태 코드와 본문을 그대로 전달하며, 일시적 신호(순수 RESOURCE_EXHAUSTED/RPM 스로틀링, rate_limit_exceeded, rate_limit_error)는 재시도 가능으로 남습니다. 분류기는 일부러 좁게 두었습니다. Google이 일시적 스로틀링에 그대로 재사용하는 지나치게 광범위한 "billing"과 "exceeded your current quota" 마커를 제거해, 회복 가능한 Google 429가 더 이상 빠른 실패로 뒤집히지 않습니다. 재시도되는 429는 백오프에 업스트림 Retry-After를 사용하고(max_delay로 캡), 요청된 간격이 남은 전체 타임아웃 예산을 넘으면 잠들지 않고 즉시 실패합니다. 힌트는 끝까지 보존됩니다(Google의 RetryInfo.retryDelay와 정수 초 형식 Retry-After 헤더에서 파싱해 클라이언트로 향하는 Retry-After 헤더에 반영). 예산 프로브는 이제 saturating_add를 쓰고 파싱된 힌트는 24시간(MAX_RETRY_AFTER_SECS)으로 클램프해, 적대적 업스트림이 u64::MAX에 가까운 Retry-AfterDuration 덧셈을 오버플로시켜 요청 태스크를 중단시키던 원격 트리거 가능 패닉을 막습니다.
  • 스트리밍 변환 경로(Anthropic, Chat-Completions/Gemini 폴백)에서 누적된 /v1/responses 응답을 저장해, 스트리밍된 출력 항목을 {"type":"item_reference","id":"item_..."}로 참조하는 후속 요청(OpenAI 및 Vercel AI SDK의 기본 동작)이 1단계에서 store:true를 썼더라도 HTTP 400 대신 정상 해소되게 했습니다 (#746, #745 종료). 완료된 응답은 첫 response.completed 이벤트가 클라이언트에 도달하기 전에 저장됩니다. response.completed를 내보내지 않는 오류 종료 스트림은 비스트리밍 오류 경로와 마찬가지로 저장하지 않으며, 패스스루 스트리밍은 업스트림이 저장을 소유하므로 변경 없습니다.
  • 전략 dispatch 전에 item_reference input item을 해소해, 인라인 항목 대신 item_reference를 보내는 멀티-스텝 도구 호출에서 /v1/responses가 Anthropic/Claude 백엔드에 더 이상 HTTP 400을 반환하지 않게 했습니다 (#743, #741 참조). 참조는 인라인 FunctionCall/Message/FunctionCallOutput 항목으로 재작성되고(같은 call_id는 first-wins로 중복 제거), build_context_for_user는 저장된 함수 호출 출력 항목을 올바른 tool_use/tool_result 쌍으로 재구성하며, OpenAI/Azure 패스스루 경로는 참조를 그대로 전달합니다. 해소할 수 없는 참조는 id를 명시한 설명적 400을 반환하고, 256개 상한(MAX_ITEM_REFERENCES)이 요청당 세션 스토어 스캔 비용을 제한합니다.
  • server.workers를 Tokio 런타임에 전달합니다 (#736, #734 참조). 이 값은 config.yaml.example에 문서화되고 출하됐지만, main이 인자 없는 #[tokio::main]을 써서 런타임이 항상 num_cpus::get() 워커 스레드로 돌았기에 아무 효과가 없었습니다. 이제 main은 동기 함수입니다. 설정 파일에서 server.workers를 미리 읽어 기존 RuntimeConfig::build_runtime 경로로 적절한 크기의 멀티스레드 런타임을 만들고 그 위에서 비동기 본문을 실행하며, 값이 설정되지 않았거나 0이면 CPU 개수로 폴백합니다.
  • 패스스루가 아닌 공급자(Anthropic 및 chat-completions 기반 경로)에서 /v1/responses 스트리밍이 규격을 따르는 function_call 출력 항목과 인자 이벤트를 내보내도록 했습니다. 텍스트 출력 페이로드를 보존하고, 교차된 병렬 도구 호출 인자를 업스트림 인덱스로 추적합니다 (#725).
  • Files API 라우트가 별도 스토어를 만드는 대신 공유 ApiKeyStore를 재사용하게 해, 런타임에서 관리하는 API 키가 Files API와 라우터의 나머지 부분에서 일관되게 인식되도록 했습니다 (#706).
  • AppProxy: 단일 서킷 이벤트에서 형제 서킷을 보존합니다 (#737, #731 종료). 둘 이상의 서킷을 서빙하는 워커가 단일 서킷 이벤트마다 영향받지 않는 모든 형제의 appproxy-* 백엔드를 지워(다음 pull-reconcile까지, 최대 15초 동안 404/502) 버리던 문제가 있었습니다. RegistryEntry에 route 정보가 없어 재구성된 집합이 델타 서킷만 담았기 때문입니다. 이제 각 RegistryEntry에 전체 서킷을 캐시하고 변경되지 않은 형제는 그로부터 재구성하므로, 델타 서킷의 백엔드만 바뀝니다.
  • AppProxy: 와일드카드 서브도메인 인그레스에서 폴백 체인에 도달하게 했습니다 (#738, #735 종료). 레플리카가 모두 죽은 등록 서킷이 더 이상 막다른 길이 아닙니다. 서킷별 인가 후 그 서킷의 정규 모델로 고정되어 일반 파이프라인으로 넘어가고, 거기서 FallbackService가 이어받습니다(운영자가 기대하는 "배포가 죽으면 교차 공급자 모델로 트래픽이 넘어간다" 동작). 이 통과는 등록됐지만 죽은 서킷으로 한정되고, 정말 알 수 없는 서브도메인은 404로 남으며, open-to-public / bearer 토큰 / IP 허용 목록 게이트가 먼저 실행됩니다.
  • AppProxy: 주기적 reconcile에서 이벤트로 알게 된 모델을 보존합니다 (#739). Redis 이벤트 오버레이가 성공적인 pull 프로브보다 먼저 서킷의 모델을 알게 된 경우, reconcile이 등록됐지만 죽은 레지스트리 항목을 evict 하고 스코프드 폴백을 깨뜨릴 수 있었습니다. 이제 reconcile은 레플리카를 프로브하기 전에 공유 레지스트리가 이미 아는 모델을 재사용합니다.
  • AppProxy: WorkerRegisterResponse 역직렬화를 Backend.AI 코디네이터의 실제 응답 형태(slots는 배열, available_slots는 그 개수)와 맞췄습니다 (#726).

문서

  • Zensical 사용자 문서를 현재 상태 기준 매뉴얼로 다시 썼습니다. 개발 로그식 서술, 로드맵, "coming soon" 항목을 걷어내고, 실제 config 구조체와 어긋난 설정 레퍼런스(존재하지 않는 섹션과 키, retry 필드 이름, admin 인증 형태, 환경 변수 표, 설정 탐색 순서)를 바로잡았으며, 그동안 빠져 있던 출하 동작(CLI 플래그 7종, auth login 하위 명령, Windows AF_UNIX 지원과 Unix 소켓 위 SSE, Windows/musl 및 .deb 릴리스 산출물)을 문서화하고, 한국어 문서를 영어와 같은 수준으로 맞췄습니다.
  • AppProxy 워커 모드 설계 문서를 추가했습니다 (#708).
  • README "Recent Updates" 목록을 릴리스별 한 줄로 압축했습니다.

의존성

  • validator derive 의존성과 그 전이 의존성 proc-macro-error2를 제거해, validator에 안전한 업그레이드 경로가 없어 임시 cargo-deny ignore가 필요했던 RUSTSEC-2026-0173 권고를 해소했습니다 (#733, #732).
  • Rust 패키지 버전을 업데이트했습니다 (#732).

v1.8.2 - 2026-06-02

수정됨

  • /v1/responses 경로에서 클라이언트의 Accept-Encoding 헤더 전달을 중단했습니다 (#702). 클라이언트가 Accept-Encoding: gzip, deflate, br을 보내면 responses 경로의 헤더 필터가 차단 목록에서 accept-encoding을 빠뜨려 업스트림 백엔드로 그대로 전달했고, 업스트림은 gzip을 협상해 압축된 바이트를 반환했습니다. reqwest는 Accept-Encoding 헤더를 수동으로 설정하면 자동 압축 해제를 비활성화하기 때문에(명시적인 .header("Accept-Encoding", "identity") 호출은 전달된 값을 교체하지 않고 두 번째 값으로 덧붙기만 했습니다), SSE 변환기가 raw gzip 바이트를 받아 텍스트로 파싱하면서 선두의 response.created, output_item.added, content_part.added, output_text.delta 이벤트를 떨어뜨리고 item_idtext가 비어 있는 꼬리 조각만 남겼습니다. 이제 "accept-encoding"이 기본 convert 경로(src/http/handlers/responses.rs)와 responses 네이티브 패스스루 경로(src/proxy/responses_only.rs) 모두의 FILTERED_HEADERS에 포함되어 chat-completions 프록시(src/proxy/backend.rs)와 동등해졌고, 업스트림은 항상 Accept-Encoding: identity만 받습니다.
  • Responses SSE 라인의 이중 래핑을 중단해, 비 GPT /v1/responses 스트리밍 변환이 변환된 Anthropic 및 Chat-Completions 경로에서 중첩 레코드 대신 단일 레이어의 OpenAI 호환 SSE 레코드를 내보내도록 수정했습니다 (#701).

의존성

  • uuid 1.23.1 → 1.23.2, redis 1.2.1 → 1.2.2, socket2 0.6.3 → 0.6.4, serial_test 3.4.0 → 3.5.0으로 bump (#699).

테스트

  • 프로덕션 StreamService 변환 프로세서에 대한 회귀 커버리지를 강화해, 변환된 Anthropic 및 Chat-Completions 경로에서 단일 레이어 SSE 출력을 단언합니다 (#701).
  • Anthropic 백엔드와 gzip을 요청하는 클라이언트로 /v1/responses 스트리밍 경로를 검증하는 통합 회귀 테스트. 업스트림 요청이 Accept-Encoding: identity만 받는 것과, 변환된 Responses SSE 스트림이 텍스트와 item id가 채워진 전체 이벤트 시퀀스를 유지하는 것을 단언합니다 (#702).

v1.8.1 - 2026-05-29

추가됨

  • 하드코딩된 opus-4-7/opus-4-6 부분 문자열 게이트를 대체하는 claude_family_version 파서와 함께 Claude Opus 4.8 인식 추가 (#693, #687의 일부). 네 개의 Anthropic capability 술어가 이제 파싱된 (major, minor) 버전을 비교합니다: uses_adaptive_thinking_api ≥ (4,6), model_requires_adaptive_thinking / model_forbids_sampling_params ≥ (4,7), opus_supports_max_effort = Opus이면서 ≥ (4,6). 파서는 첫 번째 정수 토큰을 major로, 그다음 버전 모양 토큰(1~2자리, 값 < 100)을 minor로 취급하므로, 20250514 같은 8자리 날짜 접미사는 minor 0이 되어 버전으로 오인되지 않고, 새 minor 릴리스는 버전별 수정 없이 인식됩니다. claude-opus-4-8 메타데이터 항목(1M 컨텍스트, 128K 출력, \(5/\)25 가격, 적응형 사고, 2026년 1월 cutoff)을 추가하고 claude-opus-4-8 / claude-opus-4-8-latest를 내장 지원 모델 목록과 설정 샘플에 등록합니다. 4.5/4.6/4.7과 Sonnet 변형의 동작은 보존됩니다.
  • 백엔드별 anthropic_fast_mode opt-in(기본값 off) 뒤의 Anthropic fast mode (#694, #687의 일부). is_fast_mode_eligible은 Opus 4.6/4.7/4.8과 이후 Opus minor에서만 true를 반환하고, merge_beta_header는 클라이언트가 보낸 anthropic-beta를 보존하면서 beta 토큰을 쉼표로 결합하고 중복을 제거합니다. 네이티브 /anthropic/v1/messages 경로에서 resolve_fast_mode_beta는 요청이 speed: "fast"이고, 모델이 적합하며, 백엔드가 네이티브 Anthropic(Bedrock은 절대 아님)이고, opt-in이 켜진 경우에만 병합된 fast-mode-2026-02-01 beta 헤더를 주입합니다. fast mode가 적용되지 않으면 나가는 본문에서 speed를 제거해 의도치 않은 업스트림 400을 유발하지 못하게 합니다. OpenAI 호환 경로는 적합하고 opt-in된 네이티브 Anthropic 대상에만 speed: "fast"를 전달하고 beta 헤더를 주입합니다. Anthropic -> OpenAIAnthropic -> Google 폴백 파라미터 매핑은 speed를 제거해, fast mode 요청이 비 Anthropic 백엔드로 폴백할 때 네이티브 전용 필드가 누출되지 않게 합니다. 응답의 usage.speed는 보존됩니다.
  • Claude Opus 4.8+ 대화 중간 시스템 메시지 (#695, #687의 일부). 이전 Claude 패밀리가 HTTP 400으로 거부하는 messages 배열 내부의 role:"system" 항목이 이제 허용되며, claude_family_version을 재사용해 패밀리 버전 ≥ (4,8)에 매칭되는 새 supports_mid_conversation_system(model_id) 술어로 게이트됩니다. 네이티브 핸들러는 해당 항목을 네이티브 Anthropic 백엔드로 변경 없이 왕복시키고, 교차 공급자 변환은 System 역할을 OpenAI system 역할로 매핑하며 Gemini와 Responses에서는 user 역할 텍스트로 보존합니다. OpenAI 호환 변환은 지원 모델에 대해 대화 중간 system/developer 메시지(첫 user 턴 이후)를 배열 내 role:"system" 항목으로 내보내고, 선두 시스템 메시지는 여전히 최상위 system 필드를 채웁니다. 비지원 모델(Opus 4.7 이하, 모든 Sonnet/Haiku, Bedrock 접두사 id, 비 Claude id)은 단일 최상위 system으로 평탄화하는 기존 동작을 유지합니다.
  • 거부 응답의 stop_detailsrefusal stop reason이 전체 Anthropic 응답 파이프라인을 통해 전파됩니다 (#696, #687의 일부). map_anthropic_finish_reason"refusal""content_filter"로 매핑하고, 비스트리밍 변환과 스트리밍 message_delta 핸들러는 stop_reason"refusal"일 때 choice에 stop_details 객체를 붙이며, 업스트림이 명시적 null을 보내면 null을 전달하는 대신 키를 생략합니다.

수정됨

  • POST /v1/responses에서 인라인 image_url 대신 Files API 업로드를 file_id로 참조하는 input_image 콘텐츠 파트를 허용합니다 (#686, refs #681). 부모 enum들이 #[serde(untagged)]라서 {"type":"input_image","file_id":"file-..."} 파트는 이전에 일반적인 untagged-enum 오류로 역직렬화에 실패했고 Axum이 HTTP 422를 반환했습니다. 이제 image_url은 선택 사항이 되고 input_file을 따라 file_id가 추가되었습니다. 공유 헬퍼 resolve_local_file_to_data_url이 동일한 메타데이터, 소유권, 크기, 로드, base64 시퀀스를 거쳐 로컬 file_id를 인라인 base64 image_url 데이터 URL로 해석하며, 소유권과 10MB 크기 제한을 준수합니다. OpenAI/Anthropic/Gemini 변환기는 선택적 image_url을 처리해, 해석된 경우 이미지를 내보내고 해석되지 않은 file_id는 경고 후 건너뜁니다. validate_request는 메시지 콘텐츠를 순회해 image_urlfile_id도 없는 input_image를 파일 해석 전에 명확한 400으로 거부합니다.
  • Claude Opus 4.8 라우팅 게이트를 강화해, fast-mode speed는 전송 계층이 네이티브 Anthropic opt-in과 beta 헤더 주입을 확인한 경우에만 전달되고, 비 Opus Claude 패밀리는 대화 중간 시스템 메시지를 계속 평탄화하며, OpenAI 호환 Anthropic 응답은 usage.speed를 보존합니다 (#698, refs #687).

문서

  • Claude Opus 4.8 지원을 영어와 한국어로 문서화 (#697, closes #692, #687의 일부): reasoning-effort.md의 적응형 사고 모델 목록과 샘플링 파라미터 deprecated 경고에 claude-opus-4-8-* 추가; backends.md에 Claude Opus 4.8 모델 상세, Anthropic Fast Mode 섹션, 대화 중간 시스템 메시지 섹션, 거부 stop_reason -> content_filter 매핑 추가; 모델 인식, fast mode, 대화 중간 시스템 메시지, 거부 stop_details를 다루는 changelog 항목 추가.
  • api.md(영어와 한국어)에 input_imagefile_id 지원을 문서화. image_urlfile_id 중 정확히 하나가 필요하고, file_idinput_file 경로와 같은 소유권 및 10MB 크기 제한 아래 백엔드에 도달하기 전에 인라인 base64 데이터 URL로 해석된다는 점을 명시합니다 (#686, refs #681).

테스트

  • claude_family_versionsupports_mid_conversation_system 경계 테스트(4.7 false, 4.8 true, Sonnet/Haiku/구버전 false, Bedrock 접두사와 교차 리전/ARN id false), fast-mode 적합성, beta 헤더 병합/중복 제거, speed/usage.speed (역)직렬화, 클라이언트 beta 병합을 포함한 resolve_fast_mode_beta 게이팅, 폴백 공급자 간 speed 비누출 대 보존 (#693, #694, #695).
  • 거부 응답 커버리지: stop_details가 있는 경우와 없는 경우의 비스트리밍 및 스트리밍 거부, 명시적 null 생략 경로, end_turn/max_tokens/stop_sequence/tool_use 회귀 테스트 (#696).
  • input_imagefile_id 단독 및 image_url 단독 역직렬화, 회귀용으로 실패하던 전체 요청 페이로드, 소유권과 크기 제한을 준수하는 FileResolver 해석, 세 백엔드 전체의 변환기 출력, 두 필드 모두 없는 검증 사례 (#686).

v1.8.0 - 2026-05-28

추가됨

  • 클라이언트 API 키의 선택적 allowed_backends 허용 목록을 통한 API 키별 백엔드 접근 제어 (#677, closes #674). 목록이 비어 있지 않으면 해당 키로 인증된 요청은 명시된 백엔드로만 라우팅될 수 있고, 빈 목록이나 누락된 목록은 기존의 무제한 동작을 유지합니다. 이 필드는 엔드 투 엔드로 통합됩니다: 설정 파일과 핫 리로드, 런타임 ApiKeyAuthContext, 백엔드 선택 chokepoint와 Responses / Anthropic 선택 경로, 교차 공급자 폴백, Admin REST API(create/update/get/list), 런타임 키 영속화, 모델 목록 엔드포인트.
  • select_backend_with_retry와 Responses(StreamService), Anthropic 네이티브, count_tokens, 이미지 핸들러가 키의 허용 목록으로 후보를 필터링합니다. 모델은 존재하지만 허용 목록이 모든 후보를 거부하면, 403error_type = "permission_error"(재시도 불가)로 매핑되는 새 RouterError::Forbidden 변형으로 요청이 거부되며, 이는 401 AuthError와 구분됩니다.
  • /v1/models, /v1/models/extended, /anthropic/v1/models는 제한된 키로 인증된 경우 허용된 백엔드 중 적어도 하나가 제공하는 모델로 필터링되고, GET /v1/models/{model}은 키가 도달할 수 없는 모델에 404를 반환합니다. 비인증 또는 무제한 호출자는 전체 목록을 봅니다.
  • api_optional_auth_middleware가 허용(permissive) 모드로 레이어링됩니다. 제시된 bearer 토큰을 최선 노력으로 검증하고 절대 거부하지 않으면서 AuthContext를 첨부하므로, 키별 제한은 인증된 호출자에게 적용되고 익명 및 잘못된 토큰 호출자는 제한 없이 통과합니다. 기존 차단 모드 api_auth_middleware는 변경되지 않으며, 둘은 절대 함께 레이어링되지 않습니다.
  • 키의 allowed_backends가 알 수 없는 백엔드 이름을 참조하면 설정 검증이 하드 실패 대신 경고만 하므로, 운영자가 키를 업데이트하기 전에 백엔드 이름 변경이 라우터를 먹통으로 만들지 않습니다.
  • fallback.mid_stream_enabled 설정 필드(기본값 true). 운영자가 초기 연결의 저렴한 pre-stream 백엔드 재선택은 유지하면서 스트림별 mid-stream 버퍼링은 끌 수 있습니다 (#680, closes #676). 이전에는 fallback.enabled가 all-or-nothing이었습니다. 켜면 pre-stream과 mid-stream 폴백 모두(스트림당 약 100~200KB를 버퍼링하는 StreamAccumulator 포함), 끄면 폴백 전체가 비활성화됐습니다. 메모리가 제한되거나 동시성이 높은 호스트에 중간 지점이 생겼습니다.
  • 스트리밍 디스패치가 순수 헬퍼 decide_streaming_fallback_dispatch로 분리된 3-way 결정이 됩니다. fallback.enabled가 true이고 체인이 설정된 상태에서 mid_stream_enabled = true는 버퍼링 경로(handle_streaming_with_mid_stream_fallback)를 유지하고, mid_stream_enabled = false는 되살아난 handle_streaming_with_pre_stream_fallback으로 라우팅하며(StreamAccumulatorMidStreamFallbackContext 할당 없음, mid-stream 실패는 일반 스트림 오류로 표면화), 그 외에는 표준 무폴백 경로가 실행됩니다.
  • 이전에 dead code였던 handle_streaming_with_pre_stream_fallbackadvance_to_next_fallback이 이제 살아 있습니다. #[allow(dead_code)] 마커가 제거되었고, 키별 허용 목록이 폴백 재선택에 연결되어 새로 살아난 경로가 API 키별 접근 제어를 우회하지 않습니다.

변경됨

  • src/http/streaming/handler.rs의 스트리밍 로컬 복사본 transform_payload_for_openai와 그 requires_max_completion_tokens 헬퍼를 제거했습니다. 두 호출 사이트는 이제 crate::proxy::utils의 정식 구현으로 해석됩니다 (#679, closes #660). 두 복사본은 byte-for-byte 동일해서, 한쪽 변경이 다른 쪽에 반영되지 않는 drift 위험을 만들고 있었습니다. src/proxy/utils.rs의 정식 테스트가 같은 계약을 이미 커버하므로 스트리밍 로컬 중복 단위 테스트는 제거되었습니다.

수정됨

  • 기본 mid-stream 폴백 핸들러가 mid-stream 실패 후 백엔드를 재선택할 때 API 키별 백엔드 허용 목록을 강제합니다 (#683). fallback.mid_stream_enabled = true(기본값)에서, 폴백 체인이 비허용 백엔드로 매핑된 제한 키는 mid-stream 실패 시 그 백엔드로 투명하게 전환되었는데, 이는 PR #680의 새 mid_stream_enabled 작업이 pre-stream 경로에서만 닫았던 접근 제어 우회였습니다. handle_streaming_with_mid_stream_fallback은 이제 소유된 allowed_backends: Option<Vec<String>>을 받고(spawn된 스트리밍 태스크로 이동), 새 헬퍼 resolve_allowed_backend_name_for_modelresolve_backend_name_for_model을 감싸 모듈의 다른 모든 곳(try_get_healthy_backend_for_model, get_backend_for_model_streaming, get_healthy_backend_for_streaming)에서 쓰는 것과 같은 allowed_backends.filter(|l| !l.is_empty()) + 정확한 이름 멤버십 의미론을 적용합니다. 세 폴백 재선택 사이트 모두 이 헬퍼를 통해 해석합니다. 비허용이거나 해석 불가능한 후보는 None을 반환하므로 기존 warn + continue arm이 건너뛰고 체인 인덱스가 전진합니다. 남은 후보가 모두 필터링되면 루프는 기존 체인 소진 경로로 종료되고 클라이언트에 오류를 표면화합니다. 빈 목록이나 None 허용 목록은 이전의 무제한 동작과 byte-for-byte 동일합니다.
  • mid-stream 폴백에서 폴백 페이로드를 재구성하기 전에 허용된 폴백 백엔드를 해석하므로, 비허용 체인 항목이 건너뛰어지기 전에 current_payload를 변형할 수 없습니다 (#684).
  • Anthropic 네이티브 x-api-key 호출자가 AuthContext가 없을 때 Authorization: Bearer 인증 호출자와 동일한 allowed_backends 정책을 적용받으며, Messages, count_tokens, 모델 목록을 커버합니다 (#684). 키별 허용 목록이 네이티브 Anthropic surface에서 강제되지 않는다고 문서화돼 있던 기존 제한이 닫혔습니다.
  • 677 머지 후 보안 감사에서 발견된 POST /v1/responses/compact의 HIGH 심각도 인가 우회를 닫았습니다. 이 엔드포인트는 요청 extensions에서 AuthContext를 전혀 읽지 않는 유일한 클라이언트 대상 모델 라우팅 핸들러여서, 백엔드 집합 A로 범위가 제한된 키가 요청한 모델을 B가 제공하기만 하면 압축(compaction)을 통해 비허용 패스스루 백엔드 B(OpenAI / Azure)에 도달할 수 있었습니다. compact_response는 이제 create_response를 정확히 미러링합니다: allow_list_from_auth로 키별 허용 목록을 도출하고, 헬스 체크나 패스스루 전에 모델의 후보 백엔드를 그 목록으로 필터링하며, 모델은 존재하지만 키가 그 모델을 제공하는 어떤 백엔드로도 라우팅할 수 없을 때 결정론적 403 permission_error를 반환합니다. 필터가 백엔드 전달보다 먼저 실행되므로 업스트림 접촉 없이 거부됩니다.

문서

  • config.yaml.example, src/services/streaming/mid_stream_config.rs rustdoc, docs/en/configuration/advanced.md에서 mid_stream_fallback.enabled가 mid-stream 버퍼링을 비활성화하거나 메모리를 줄이지 않는다는 점을 명확히 했습니다. 값과 무관하게 StreamAccumulator는 여전히 생성되어 스트림당 약 100KB까지 버퍼링하고, mid-stream 폴백은 여전히 백엔드 실패 시 활성화됩니다 (#678, closes #675). 이 플래그는 폴백 요청의 continuation 모드와 restart 모드 중 하나를 선택할 뿐입니다. 버퍼링과 메모리의 실제 kill-switch는 fallback.enabled: false이거나 fallback.fallback_chains에서 모델을 빼는 것입니다. 한국어 문서(docs/ko/configuration/advanced.md)에는 대응하는 Mid-Stream Fallback 섹션이 없어 이 명확화에 대한 한국어 변경은 없지만, #680이 새 토글을 다루는 번역된 "미드스트림 버퍼링 비활성화" 하위 섹션을 별도로 추가했습니다.
  • API 키별 allowed_backends 허용 목록을 보안 문서(영어와 한국어)에 문서화했으며, 이제 닫힌 x-api-key Anthropic Messages 제한 사항도 포함합니다 (#677, #684).

테스트

  • resolve_allowed_backend_name_for_model의 결정론적 단위 테스트: 허용 목록이 해석된 백엔드를 제외하면 None 반환, 포함하면 Some 반환, 빈 목록은 Some 반환, None은 필터 없는 해석기와 일치, 해석 불가능한 모델은 None 반환 (#683).
  • 차단 인증 뒤에서 /v1/responses/compact를 구동하는 tests/per_key_backend_access_test.rs 통합 테스트: 비허용 백엔드만 제공하는 모델을 요청한 제한 키는 403 permission_error를 받고(보안 사례), 허용된 백엔드의 모델을 요청한 제한 키는 필터를 통과합니다 (#677).
  • fallback.enabled, mid_stream_enabled, 체인 존재 여부 사이의 3-way 결정 매트릭스를 커버하는 새 decide_streaming_fallback_dispatch 헬퍼 단위 테스트 (#680).

v1.7.1 - 2026-05-28

수정됨

  • Anthropic web_search_20250305 서버 도구 에뮬레이션이 더 이상 공급자 실패를 빈 결과 집합으로 가리지 않습니다. API 키 누락, HTTP 401/403/429, 타임아웃, 파싱 오류는 이제 매핑된 error_code(HTTP 429는 "too_many_requests", 그 외 모든 실패는 "unavailable")를 가진 web_search_tool_result_error 콘텐츠 블록으로 클라이언트에 표면화됩니다. 진짜로 비어 있지만 성공한 검색은 계속 빈 content: [] 배열을 내보내므로 두 결과는 여전히 구분 가능합니다. 비스트리밍과 스트리밍 SSE 코드 경로 모두 커버되며, 스트리밍 오류 경로를 지키는 명시적 SSE 이벤트 순서 단언이 포함됩니다. Serper 응답 형태 drift(깨끗이 파싱되지만 organic 키가 없는 본문)는 이제 감지되어 공급자 태그가 붙은 warn!으로 로깅되며, 관찰된 최상위 키만 기록하고 사용자 쿼리 텍스트는 절대 기록하지 않습니다. (#671, #672, #673)

의존성

  • lru 0.16 → 0.18, reqwest 0.13.3 → 0.13.4, rusqlite 0.39 → 0.40(libsqlite3-sys 0.37 → 0.38, CI가 Rust 1.95를 실행하게 되어 핀 해제)으로 bump, 그리고 전이적 lockfile 갱신(aws-lc-rs 1.16.3 → 1.17.0, h2 0.4.13 → 0.4.14, http 1.4.0 → 1.4.1, hyper/axum/reqwest 연쇄 개정). cargo audit은 의존성 그래프 전체에서 취약점 0건을 보고합니다 (#669, #670).

v1.7.0 - 2026-05-26

추가됨

  • Bearer 토큰 기반 AWS Bedrock Claude 백엔드 Phase 1 (bedrock-mantle) (#616, closes #613)
  • serde 별칭(aws-bedrock, bedrock-anthropic, AwsBedrock, ...)을 가진 새 type: bedrock 백엔드. is_commercial()은 true를 반환하고 owned_by()Some("anthropic")을 반환해, OpenAI 형식 클라이언트가 기대하는 모델 계보를 보게 됩니다.
  • endpoint_type: mantle(기본값)은 리전 템플릿 https://bedrock-mantle.{region}.api.aws에서 네이티브 Anthropic Messages API를 사용하고, /anthropic/v1/messages로 라우팅하며, Authorization: Bearer를 사용하고, anthropic-version을 생략합니다(있으면 Bedrock이 HTTP 400을 반환). 명시적 url: 필드가 프록시와 테스트를 위해 템플릿을 덮어쓰고, 빈 리전이나 대문자 리전은 로드 시 거부됩니다.
  • model_ids.rs는 일반(anthropic.<family>), 지리적(us./eu./jp./au.), 글로벌(global.anthropic.<family>), 전체 ARN 식별자를 인식하며, 지역 접두사가 실제 청구와 레지던시 결과를 수반하므로 자동 별칭 매핑 없이 변경 없이 전달합니다.
  • 기존 OpenAI/Anthropic 본문 변환과 Anthropic SSE 스트림 변환기를 변경 없이 재사용하므로, 모델별 특이 동작(Opus 4.7 샘플링 파라미터 금지, 적응형 사고)이 중복 없이 Bedrock에 동일하게 적용됩니다. endpoint_type: runtime은 여기서는 예약만 되어 있고 아래 Phase 2에서 구현됩니다.

  • 요청 경로 속도 제한이 이제 실제로 강제되고, Redis 스토리지 백엔드가 추가되었습니다 (#635, #632, closes #626)

  • state.rs가 이전에 initialize_rate_limiting이 반환한 MiddlewareLayer를 버려서 rate_limiting.* 설정이 조용한 no-op였습니다. 이제 레이어가 ServiceHandlesContinuumRouterBuilder::build_routerRouter::layer를 거쳐 조립된 Axum 앱에 부착되므로, 설정된 예산이 실제로 429를 반환합니다.
  • 다섯 개 rate_limiting 차원이 모두 선택 사항이 되었습니다: 이미 선택 사항이던 per_api_key/per_modelper_client, per_backend, global이 합류합니다. 운영자는 어떤 차원이든 생략해 비활성화 상태로 로드할 수 있고, Default impl은 세 차원을 그대로 유지하므로 기존 배포는 영향받지 않습니다 (#632).
  • redis-cache feature 게이트의 rate_limit_v2::redis_backend는 토큰 버킷과 슬라이딩 윈도우 Lua 스크립트를 각각 단일 원자적 EVAL로 실행하고, cr:rl:per_client:10.0.0.1 같은 키로 공유 create_redis_pool 헬퍼를 재사용합니다. 어떤 Redis 실패(풀 사용 불가, 타임아웃, Lua 오류)에서든 백엔드는 BackendUnavailable을 보고하고 호출자는 인프로세스 토큰 버킷으로 폴백해, 요청을 떨구는 대신 레플리카별 강제로 degrade합니다.

  • 교차 공급자 폴백이 이제 요청 디스패치와 핫 리로드에 연결되었습니다 (#631, #637, #665)

  • 완성된 src/core/fallback/ 모듈(약 4,900줄, 단위 테스트 36개)이 요청 경로에서 한 번도 호출되지 않아, 설정된 fallback.fallback_chains가 조용한 no-op였습니다. FallbackService가 이제 chat_completions(웹 검색 제외), completions, embeddings, rerank, sparse_embeddings, 이미지 생성에 대해 실행되며, execute_with_optional_fallback 래퍼(폴백 미설정 시 오버헤드 없음), X-Fallback-* 응답 헤더, executor bound를 충족하는 From<RouterError>TriggerReason 매핑을 포함합니다 (#631).
  • fallback.fallback_chainsfallback.fallback_policy 변경이 이제 핫 리로드 구독자를 통해 FallbackService::update_config로 런타임에 적용됩니다. fallback.enabled 토글은 여전히 재시작 전용이며, config.yaml.example에 그렇게 문서화되어 있습니다 (#637, #665).

  • 인터랙티브 데스크톱 사용을 위한 POST /v1/models/refresh 강제 새로고침 엔드포인트 (#593, #664)

  • ModelCache(all_models 키)를 비우고 응답 전에 설정된 모든 백엔드에서 동기적으로 재집계해, GET /v1/models와 같은 {"object":"list","data":[...]} 형태를 반환합니다. 데스크톱 클라이언트(예: backend.ai-go "Refresh models" 버튼)는 두 번째 왕복 없이 응답을 즉시 사용할 수 있습니다.
  • 검증된 API 키별로 속도 제한되며, 익명 또는 잘못된 토큰 호출자는 하나의 글로벌 익명 버킷을 공유합니다: 5초 버스트 윈도우당 3회, 분당 12회. 제한을 초과한 호출자는 429 Too Many Requests를 받습니다. 각 호출이 설정된 모든 백엔드에서 업스트림 fetch를 유발하므로 일반 목록 엔드포인트보다 의도적으로 엄격합니다.
  • model_aggregation.allow_force_refresh: bool 설정 필드(기본값 true)로 게이트됩니다. false로 설정하면 엔드포인트가 403 Forbidden을 반환하므로, 클라이언트가 TTL 기반 만료에 의존해야 하는 강화된 배포에 적합합니다.
  • 각 새로고침은 가능하면 검증된 API 키 ID를, 아니면 anonymousINFO 레벨로 로깅해 감사 상관관계를 지원합니다.
  • config.yaml.example이 데스크톱 임베디드 가이드로 확장되었습니다: backend.ai-go 스타일 임베디드 프록시를 위한 cache_ttl: 10, soft_ttl_ratio: 0.5, allow_force_refresh: true.
  • ModelAggregationService의 새 force_refresh(state) 헬퍼가 비우고 다시 집계하는 흐름을 캡슐화합니다. allow_force_refresh() 접근자가 설정 플래그를 핸들러에 노출합니다.

  • AWS Bedrock Claude 백엔드 Phase 2: SigV4 + AWS 바이너리 event-stream을 사용하는 bedrock-runtime (#614)

  • type: bedrock 백엔드의 새 endpoint_type: runtime 값은 https://bedrock-runtime.{region}.amazonaws.com/model/{modelId}/invoke[-with-response-stream]을 대상으로 합니다. 라우터는 각 요청을 AWS Signature V4(service: "bedrock")로 서명하고, OpenAI → Anthropic 본문을 "anthropic_version": "bedrock-2023-05-31"로 감싸고, 최상위 "model" 필드를 제거하며(Bedrock은 URL 경로에서 모델 ID를 취함), 모델 식별자를 경로에 퍼센트 인코딩해 버전 있는 파운데이션 ID(anthropic.claude-3-5-sonnet-20240620-v1:0)와 전체 ARN이 깔끔하게 왕복합니다.
  • 스트리밍 응답은 AWS application/vnd.amazon.eventstream 바이너리 프레임 형식으로 도착합니다. 새 bedrock::event_stream::EventStreamDecoder가 여러 TCP read에 걸친 프레임을 재조립하고, 각 chunk 페이로드를 base64 디코딩하며, 기존 AnthropicStreamTransformer가 OpenAI 형태 SSE로 번역할 수 있도록 합성 event: <type>\ndata: <json>\n\n SSE 바이트를 내보냅니다. 예외 프레임(ThrottlingException, ValidationException, ...)은 조용히 버려지는 대신 합성 event: error SSE 청크로 표면화됩니다.
  • AWS 자격 증명은 이 순서로 해석됩니다: 인라인 auth.aws.access_key_id + auth.aws.secret_access_key(+ 선택적 session_token), 그다음 auth.aws.profile을 통한 명명된 프로파일, 그다음 표준 AWS 체인(환경 변수, 공유 설정, IMDS, IRSA / EKS pod identity, ECS task role). 해석기 앞에 aws_credential_types::provider::SharedCredentialsProvider를 두어 임시 자격 증명이 요청 사이에 투명하게 갱신됩니다.
  • BackendAuthConfig의 새 BackendAuthType::Sigv4 변형과 auth.aws 아래의 AwsAuthConfig 서브 블록이 추가되었습니다. 둘 다 Debug redaction을 거치므로 정적 자격 증명이 로그로 새지 않습니다. BackendAuthType은 YAML 표기로 sigv4, aws_sigv4, aws-sigv4를 받습니다.
  • runtime 헬스 체크는 단일 토큰 본문으로 POST /model/{probe_model}/invoke를 프로브합니다. HTTP 2xx, 400, 401, 403, 429 모두 정상으로 간주되는데, AWS surface가 도달 가능함을 증명하고 인증/과금 문제는 운영자가 별도로 해결할 수 있기 때문입니다.
  • 모든 AWS SDK 크레이트(aws-sigv4, aws-smithy-eventstream, aws-credential-types, aws-config)는 새 선택적 bedrock-sigv4 Cargo feature 뒤에 있습니다. 기본 빌드는 이들을 끌어오지 않으며, feature 없이 endpoint_type: runtime을 설정하면 AWS 경계에서 실패하는 대신 리빌드 플래그를 가리키는 명확한 오류를 반환합니다. Phase 1 mantle 경로는 영향받지 않고 feature 유무와 무관하게 동작합니다.
  • src/proxy/backend.rssrc/http/handlers/anthropic/handler.rs의 프록시 헤더 정책이 endpoint_type에 따라 분기합니다: Bedrock-mantle은 Authorization: Bearer를 유지하고, Bedrock-runtime은 Backend trait 구현이 각 요청을 SigV4로 서명하므로 정적 Bearer 주입을 억제합니다.
  • docs/{en,ko}/configuration/backends.md의 영어와 한국어 문서가 새 endpoint_type: runtime 설정, 빌드 요구 사항, 자격 증명 체인, IAM 정책 스니펫, 지리/글로벌 프로파일 동작, 스트리밍 파이프라인 개요로 제자리에서 확장되었습니다.

  • 요청 게이트 하이브리드 모델 thinking 변환과 함께 EXAONE 4.0 (vLLM) 등록 (#640, refs #639)

  • EXAONE 4.0(예: EXAONE-4.0-32B-FP8-RNGD)은 하이브리드 reasoning 모델입니다. reasoning 모드에서는 단독 </think>로 끝나는 chain-of-thought를 content에 인라인으로 스트리밍하고, 비 reasoning 모드에서는 </think> 없이 일반 답변을 내보냅니다.
  • assume_reasoning_first(unterminated_start) 변환이 이제 HTTP와 Unix 소켓 스트리밍 결정 지점 모두에서 요청이 실제로 thinking을 켰는지(chat_template_kwargs.enable_thinking 또는 최상위 enable_thinking, 보수적 기본값 false)에 게이트되므로, 비 reasoning 모드가 더 이상 전체 답변을 빈 content와 함께 reasoning_content로 내보내지 않습니다. 실제 <think> 마커를 키로 쓰는 표준 패턴 모델은 영향받지 않습니다.
  • unterminated_start 설정으로 exaone-4.0-32b를 등록합니다. 서빙되는 -RNGD 이름은 아래의 하드웨어 접미사 peel로 해석됩니다.

  • 모델 ID 매칭의 NPU/가속기 하드웨어 변형 접미사 정규화 (#662)

  • is_recognized_format_token()에 HARDWARE/ACCELERATOR 카테고리(rngd, warboy, atom, atommax, rebel)를 추가해, FuriosaAI(RNGD/WARBOY)와 Rebellions(ATOM/ATOMMAX/REBEL) 서빙 타깃 접미사가 모델별 alias 없이 기존 계층적 peel 체인을 통해 정규 base 메타데이터 항목으로 정규화됩니다. layered_format_strip()이 peel 전에 소문자화하므로 런타임이 내보내는 대문자 이름도 정확히 해석됩니다.
  • 정확한 id와 정확한 alias phase가 peel보다 먼저 실행되므로, *-atom이나 *-rebel로 정당하게 등록된 모델은 먼저 정확한 매칭으로 승리합니다. 배포된 model-metadata.yaml의 grep으로 현재 충돌이 0건임을 확인했습니다. EXAONE-4.0-32B-FP8-RNGD는 이제 peel(-rngd 다음 -fp8)로 exaone-4.0-32b에 정규화됩니다.

변경됨

  • 폴백 핸들러의 LM Studio 호환 shim을 좁혀 //v1/models200을 반환하고, 그 외 매칭되지 않은 모든 라우트는 이제 404를 반환합니다. JSON 오류 본문 형태는 변경 없이 보존되므로, 본문을 이미 읽고 있는 소비자는 계속 동작합니다 (#628).

수정됨

  • 알 수 없는 키에 HTTP 400 INVALID_ARGUMENT를 반환하는 Gemini /v1beta/openai/chat/completions 엔드포인트로 전달하기 전에 비 OpenAI 최상위 필드 7개(chat_template_kwargs, thinking_budget_tokens, enable_thinking, preserve_thinking, top_k, min_p, repeat_penalty)를 제거합니다. extra_body 탈출구는 건드리지 않고 reasoning_effort는 유지됩니다(Google이 thinking_level로 매핑). 또한 3-flash3.5-flash에 부분 문자열 매칭되지 않았으므로 3.5-flash thinking 비활성화 및 is-thinking 매처도 확장했습니다 (#642).
  • 모든 Anthropic 핸들러 코드 경로(네이티브 HTTP/Unix, Bedrock mantle/runtime, OpenAI 호환, Responses API)의 스트리밍과 비스트리밍 모두에 요청 통계 기록을 연결하고, raw 패스스루 SSE에서 입력/출력 토큰을 누적하는 AnthropicStreamUsageTracker를 추가했습니다 (#627, #634).
  • mid-stream 비활성 감지에 하드코딩된 60초 대신 설정된 timeouts.request.streaming.chunk_interval을 사용하고 제한된 keep-alive를 내보내, 침묵하는 백엔드가 keep-alive 주석을 영원히 내보내는 대신 StreamOutcome::Failed를 통해 다음 폴백 모델로 전진하게 했습니다 (#633).
  • Option<String> 필드가 base 설정 위로 병합되는 새 StreamingTimeoutOverride/StandardTimeoutOverride 구조체로 부분적인 model_overrides.<model>.streaming/standard 블록을 허용해, --generate-config 출력 경로의 YAML 파싱 실패를 수정했습니다 (#630).
  • admin/metrics/metrics-persistence/webui import와 함수를 해당 Cargo feature 뒤로 게이트하고, 항상 컴파일되는 호출자가 쓰는 공개 surface를 미러링하는 #[cfg(not(feature = "metrics"))] no-op 메트릭 스텁을 추가해, feature를 줄인 빌드가 깔끔하게 컴파일됩니다 (#629, #666, closes #636).
  • 강제 새로고침 속도 제한을 강화해 익명과 잘못된 토큰 호출자가 하나의 글로벌 버킷을 공유하므로, 스푸핑된 Authorization/X-Forwarded-For/X-Real-IP 헤더로 예산을 우회할 수 없습니다.
  • 메트릭 히스토리 쿼리 제한, UTF-8 안전 메트릭 레이블 절단, 타입 있는 SigV4 구현을 통한 Bedrock runtime 라우팅 (#608, #609, #613, #614 후속).

문서

  • docs/{en,ko}/configuration/backends.md에 Bedrock 백엔드(리전 선택, 지리적 vs 글로벌 인퍼런스 프로파일, 모델 ID 형식, 자격 증명 체인, IAM 정책 스니펫, 스트리밍 파이프라인)를 문서화하고, docs/en/api.md에 Force-Refresh Models 섹션을 추가하고, config.yaml.example을 데스크톱 임베디드 모델 집계 가이드와 폴백 핫 리로드 주석으로 확장했습니다.

테스트

  • transform_payload_for_openai의 negative 및 positive 사례 커버리지 (#661).
  • 문서화된 버킷 리셋 동작을 포함한 속도 제한 미들웨어 핫 리로드 테스트와, 실제 ContinuumRouter를 빌드해 버스트 소진 시 429가 발생함을 단언하는 router_wiring_tests (#635, #638, #667).
  • web_search 주입이 패스스루 계약과 올바르게 상호작용하는지 검증 (#663).
  • MLxcel 스트리밍 패스스루 통합 테스트 (#659).
  • Bedrock 단위 및 통합 커버리지: serde 별칭, URL 템플릿, 헤더 정책, 모델 ID 파싱(지리/글로벌/ARN), runtime SigV4, wiremock 서버로 구동되는 event-stream 프레임 디코딩 (#616, #614).

의존성

  • tokio 1.52.1 → 1.52.3, tower-http 0.6.8 → 0.6.11, dashmap 6.1.0 → 6.2.1, serde_json 1.0.149 → 1.0.150, aws-config 1.8.16 → 1.8.17, aws-sigv4 1.4.3 → 1.4.4, aws-smithy-types 1.4.7 → 1.4.8로 bump (#619, #658).

v1.6.3 - 2026-05-12

추가됨

  • API 키별 LLM 토큰 사용량 메트릭 (#608, #610)
  • API 키, 모델, 백엔드, 토큰 종류별로 실제 프롬프트와 컴플리션 토큰 소비를 기록하는 새 Prometheus llm_tokens_total{api_key_id, model, backend, kind} 카운터. 핫 패스 카운터의 레이블 집합은 의도적으로 최소한으로 유지되며, 추가 차원은 아래의 동반 info-metric에 있습니다.
  • 동반 api_key_info{api_key_id, ...} info-metric은 API 키별 주석 레이블(예: email, team, environment)의 설정 가능한 allowlist를 노출하므로, 대시보드가 핫 패스 카운터의 레이블 집합을 부풀리지 않고 표준 PromQL * on(api_key_id) group_left(...) 조인으로 토큰 카운터를 그룹화/필터링할 수 있습니다.
  • derive_api_key_id는 설정된 id(인증 레이어가 요청을 매칭한 경우) 또는 raw bearer 토큰의 SHA-256 첫 12 hex 접두사 k_<hex>를 반환합니다. raw 키는 절대 레이블로 사용되지 않습니다. 전용 ApiKeyCardinalityTracker(기본 캡: 고유 키 ID 1000개)가 레이블 카디널리티 폭발을 방지합니다.
  • ApiKeyConfig와 인메모리 ApiKeyannotations: HashMap<String, String> 필드가 추가됩니다. MetricsConfig에는 annotation_labels: Vec<String>이 추가되는데, api_key_info의 레이블로 구체화되는 allowlist입니다. 예약된 정규 주석 키(email, uuid, owner, team, environment)가 문서화되어 있고, 운영자는 커스텀 키를 추가할 수 있습니다.
  • 스트리밍과 비스트리밍 경로는 StreamTransformConfig의 새 StreamObservabilityContext 필드를 통해 기존 usage 파싱 지점에서 기록합니다. 이 필드는 handle_anthropic_streaming / handle_gemini_streaming / handle_successful_backend_response를 관통해, OpenAI 호환 / Anthropic / Gemini / thinking-pattern 스트리밍 응답 빌더가 모두 중복 파싱 없이 카운터를 내보냅니다. 라우터는 OpenAI 호환 백엔드에 이미 stream_options.include_usage=true를 주입하므로, 클라이언트 opt-in과 무관하게 스트리밍 메트릭이 균일하게 동작합니다.
  • api_key_info는 시작 시 metrics.annotation_labels에서 한 번 초기화됩니다. 레이블 이름은 등록 시점에 고정됩니다(Prometheus는 레이블 이름 변경을 허용하지 않음). 주석 은 기존 config-watch 경로를 통해 핫 리로드되며, admin 작업이 동기화를 유지하도록 load_from_config, add_key, remove_key_by_id에서 ApiKeyStore::refresh_info_metric이 호출됩니다.
  • 모든 레이블 값은 CardinalityManager / sanitize_label_value를 거칩니다. 주석 값은 @, +, :를 보존하는 약간 덜 엄격한 sanitize_annotation_value를 사용해, 이메일과 네임스페이스 식별자가 깔끔하게 왕복합니다.
  • 설정 가능한 보존 기간을 가진 SQLite 기반 영속 로컬 메트릭 로그 (#609, #611)
  • WAL 모드, prepared-statement 캐시, PRAGMA user_version 스키마 버저닝을 갖춘 src/metrics/persistence/ 아래의 새 MetricsStore async trait + 번들 rusqlite v1 구현(store.rs / sqlite.rs / snapshot.rs / snapshot_task.rs). 히스토그램과 서머리는 샘플별 행 형태로 풀어집니다.
  • 카운터와 게이지는 시작 시 절대 복원되지 않습니다. 영속 로그는 별도의 읽기 경로이므로, 라이브 /metrics 엔드포인트는 Prometheus의 단조 카운터 의미론을 유지합니다. 과거 샘플은 새 GET /admin/metrics/history?metric=...&from=...&to=... surface(src/admin_metrics_history.rs)로 읽으며, 런타임에 영속화가 비활성화되면 404를, feature가 컴파일되지 않았으면 503을 반환합니다. v1에는 PromQL이 없습니다.
  • src/server/serve.rs의 핫 리로드 파이프라인이 설정 변경을 PersistenceCommand::{SetSnapshotInterval, SetRetentionDays, SetCompaction} 메시지로 번역해, 진행 중인 스냅샷을 떨구지 않고 ticker와 prune cutoff를 원자적으로 재구성합니다.
  • 사실상 일일 타이머에 불과한 작업에 전체 cron 크레이트를 끌어오지 않도록, 압축 스케줄은 minute hour * * * cron 서브셋을 따릅니다.
  • 기본값은 enabled: true이며 metrics.persistence.enabled: false로 끕니다. redbduckdb 변형은 YAML 스키마의 예약 키워드로, 구현이 생기기 전까지 시작 시 NotImplemented를 반환합니다.
  • 디스크 사용량: 합성 100-series × 10-snapshot 워크로드에서 샘플당 약 119바이트 측정(tests/metrics_persistence_test::disk_usage_smoke_check_under_synthetic_load 참조). 공식은 docs/en/persistent-metrics.mdconfig.yaml.example에 문서화되어 있습니다.

수정됨

  • release 빌드의 타입 추론 실패를 막기 위해 with_label_values의 토큰 사용량 레이블 값을 &str로 강제합니다. &String 레이블 변수를 &str 리터럴("prompt" / "completion")과 섞으면 컴파일러가 &[&String]을 선택해 리터럴을 거부했습니다. #610에서 도입된 회귀입니다.

문서

  • 두 메트릭 기능의 한국어 번역 (#612)
  • docs/ko/metrics.md: llm_tokens_total, api_key_id 도출, annotation_labels allowlist, api_key_info info-metric, PromQL 예시, Grafana 패널, 검증 단계를 다루는 새 ### API 키별 LLM 토큰 사용량 섹션.
  • docs/ko/persistent-metrics.md: docs/en/persistent-metrics.md를 번역한 새 페이지(SQLite 기반 스냅샷 의미론, 설정 필드, 디스크 사용량 공식, /admin/metrics/history surface, 스키마 레이아웃, 운영 노트).
  • docs/ko/admin-api.md: Stats와 Response Cache 사이에 ## 지속 메트릭 로그 API 섹션을 삽입하고 대응하는 TOC 항목 추가.
  • zensical.ko.toml: 한국어 사이드바에서 페이지에 도달할 수 있도록 운영 아래에 지속 메트릭 로그 nav 항목 추가.
  • 메트릭 정의, api_key_id 도출 규칙, 주석 설정 스키마, 카디널리티와 핫 리로드 의미론, 예시 PromQL(이메일별 토큰, top-10 키, 팀별 롤업), Grafana 패널 예시, 검증 단계를 다루는 새 docs/en/metrics.md ### Per-API-Key LLM Token Usage 섹션. config.yaml.example에는 문서화된 metrics.annotation_labels 블록과 각 API 키 항목 아래의 annotations: 예시가 추가되었습니다.

테스트

  • API 키별 토큰 사용량 단위 커버리지: derive_api_key_id 우선순위(설정된 id 우선, 없으면 해시, 없으면 anonymous), 결정론, 해시 형식 ^k_[0-9a-f]{12}$, 주석 레이블 정규화, info 게이지 1회 초기화, refresh 원자성, 카디널리티 경계, 이메일 보존 주석 sanitizer; 스트리밍 변환기 write-through; 미들웨어 주석 스냅샷 노출; tests/metrics_integration_test.rs의 통합 커버리지(두 kind를 모두 가진 4-label 카운터, 익명 폴백, 해시 정규식). (#610)
  • 영속 메트릭 SQLite 스토어 단위 커버리지(insert, 시간 범위 쿼리, 보존 삭제, 멱등 open, unknown-kind 왕복)와 tests/metrics_persistence_test.rs의 통합 커버리지(스냅샷 태스크가 SQLite에 행을 기록, 보존이 오래된 샘플만 prune, 보존 핫 리로드가 진행 중 스냅샷을 보존, 디스크 사용량 스모크 체크). (#611)

v1.6.2 - 2026-05-10

수정됨

  • /v1/responses/v1/chat/completions가 이제 OpenAI reasoning-API의 developer 역할을 허용합니다 (#603, #605, #606)
  • serde lowercase rename을 가진 MessageRole::Developer를 추가해 "developer"가 일급 변형으로 역직렬화됩니다. 이전 실패는 알 수 없는 역할 이름을 밝히는 대신 오해를 부르는 did not match any variant of untagged enum ResponseInput으로 표면화됐는데, 암묵적 메시지 역직렬화 오류가 이제 문제의 역할 문자열을 명시하고 유효한 역할 목록을 나열합니다.
  • 백엔드별 번역: OpenAI 호환 서버에는 developer 그대로 패스스루; Anthropic은 최상위 system 파라미터로 병합(system과 developer 텍스트가 모두 있으면 \n\n으로 연결되어 기존 덮어쓰기 버그 수정); Gemini는 system_instruction으로 병합; Ollama는 system으로 매핑(구버전 빌드가 developer를 거부).
  • Chat Completions → Responses 변환기가 developer를 instruction을 담는 역할로 인식합니다: 첫 번째 등장은 최상위 instructions가 되고, 이후 등장은 원래 역할을 와이어에 유지한 input 항목으로 남습니다.
  • 문자열 기반 인식 사이트 전반에서 developersystem을 동등하게 취급합니다: prefix-cache 키 추출, 교차 공급자 폴백 번역, OpenAI-to-Anthropic 변환의 시스템 콘텐츠 추출, global-prompt injector의 기존 시스템 메시지 lookup, smart-routing 분류기 / LLM 프롬프트 빌더.

문서

  • 문서 사이트를 MkDocs에서 Zensical로 마이그레이션하고 브랜드 스타일 복원 (#602)
  • mkdocs.ymlmkdocs.ko.yml을 제거하고 네이티브 zensical.tomlzensical.ko.toml로 대체. 둘 다 Zensical의 TOML 스키마에 따라 [project] 네임스페이스 아래에 루트를 두고, 확장별 옵션은 dict로 [project.markdown_extensions] 안에 둡니다(Zensical 설정 로더는 별도의 mdx_configs 테이블을 무시).
  • Zensical이 에셋 디렉터리의 심볼릭 링크를 따라가지 않으므로, docs/en/shareddocs/ko/shared 심볼릭 링크를 각 빌드 전에 실행되는 rsync -a --delete docs/shared/ docs/{en,ko}/shared/로 교체.
  • Zensical이 문서화한 primary = "custom" 메커니즘과, 오렌지 CSS 변수를 정의하는 docs/shared/stylesheets/extra.css[data-md-color-scheme="default"][data-md-color-primary="custom"] 셀렉터로 lablup 브랜드 컬러 등록.
  • Mermaid는 이제 호환되지 않는 mermaid2 플러그인에 의존하는 대신 pymdownx.superfences 커스텀 펜스로 등록. favicon이 없으면 logo.png로 폴백.
  • 아이콘, 다이어그램, 브랜드 컬러의 Zensical 렌더 출력 복원 (#604)
  • 제거된 materialx를 대체하는 zensical.extensions.emoji twemoji 인덱스/생성기로 pymdownx.emoji를 다시 활성화해, :material-*: 아이콘 문법이 리터럴 텍스트로 렌더링되지 않게 함.
  • <!-- diagram: PATH --> ... <!-- /diagram --> ASCII 대체를 Python-Markdown 확장(docs/hooks/diagram_extension.py)으로 재구현. Zensical이 MkDocs hook 라이프사이클을 노출하지 않아 기존 MkDocs on_page_content hook이 실행되지 않기 때문입니다. Zensical의 콘솔 스크립트 엔트리 포인트에서 확장을 import할 수 있도록 docs/__init__.py를 추가하고 빌드 앞에 PYTHONPATH=.를 붙임.
  • 커스텀 팔레트에 --md-primary-bg-color를 설정하고 .md-header / .md-tabs를 오버라이드해, Zensical의 modern 레이아웃 위에 오렌지 브랜드 밴드가 칠해지게 함.
  • 두 TOML 모두에서 nav 테이블을 첫 [project.X] 서브 테이블 위로 이동해 [[project.extra.social]] 아래로 조용히 파싱되지 않게 함(알파벳순 폴백이 정렬되지 않은 상단 메뉴와 잘못된 prev/next 푸터 이웃을 만들고 있었음).

테스트

  • 스트리밍과 비스트리밍 경로 모두에서 Anthropic 변환의 system/developer 연결에 대한 회귀 커버리지, 그리고 다섯 백엔드 전체에 대한 developer 역할의 백엔드별 변환기 매핑과 Chat Completions → Responses 변환기의 developer-then-system 순서 (#605, #606).

의존성

  • redis 1.2.0 → 1.2.1로 bump (#598).

v1.6.1 - 2026-05-07

수정됨

  • Claude Opus 4.7(claude-opus-4-7)이 이제 Anthropic 백엔드를 통해 올바르게 라우팅됩니다 (#599, #600, #601)
  • 적응형 사고 API 게이트(uses_adaptive_thinking_api)를 4.7 계열 모델 ID로 확장. Claude Opus 4.7은 thinking.type == "adaptive" + output_config.effort를 요구하며, 레거시 budget_tokens 형태를 보내면 HTTP 400이 발생합니다.
  • 4.7 계열 요청 형태 규칙을 위한 model_requires_adaptive_thinkingmodel_forbids_sampling_params 술어 추가: 명시적 수동 thinking은 적응형 사고로 정규화되고, temperature, top_p, top_k는 전달 전에 무조건 제거됩니다.
  • opus_supports_max_effort를 Opus 4.7로 확장해, xhigh reasoning effort가 Opus 4.7에서 output_config.effort = "max"로 매핑됩니다.
  • claude-opus-4-7claude-opus-4-7-latest를 내장 지원 모델 목록과 model-metadata.yaml에 추가. 추측성 claude-sonnet-4-7 항목은 Anthropic이 공개하기 전까지 의도적으로 광고하지 않습니다(사용자 제공 설정을 위한 방어적 요청 형태 매칭은 유지).

문서

  • reasoning-effort 문서(EN + KO)와 backends.md를 업데이트해, Claude 4.7 패밀리의 적응형 사고 요구 사항과 무조건적인 샘플링 파라미터 deprecation을 다룹니다 (#600).

테스트

  • Opus 4.7 적응형 사고와 무조건적 샘플링 파라미터 제거에 대한 Responses API 회귀 커버리지; Opus 4.6 / Sonnet 4.6 / Haiku 4.5 / Haiku 3.5에 대한 negative 회귀를 포함한 4.7 패밀리의 두 변환 경로(Chat Completions와 Responses) (#600, #601).

v1.6.0 - 2026-05-04

추가됨

  • ChatGPT 구독 / Codex 백엔드 OAuth 디바이스 플로우 인증 (#551, #592)
  • continuum-router auth login --backend <name> 명령이 OpenAI Codex 3단계 헤드리스 디바이스 코드 플로우를 실행합니다. POST /api/accounts/deviceauth/usercode로 일회성 user_code를 발급받고, POST /api/accounts/deviceauth/token을 폴링한 뒤, /oauth/token에서 PKCE 교환을 진행합니다. 표준 RFC 8628 디바이스 플로우는 향후 다른 공급자가 구현할 경우 그대로 쓸 수 있도록 남겨두었고, 새 OpenAICodexDeviceFlowClientprovider: openai에서 자동으로 선택됩니다.
  • 토큰은 SecretString으로 감싸져 설정된 token_store에 Unix 0600 모드로 기록되며, O_CREAT|O_EXCL 오픈 + 원자적 rename을 사용합니다. tempfile 접미사에 무작위 성분을 포함해 동시 저장 시 충돌을 방지하고, 중간 실패 시 부분 작성된 파일을 unlink해 비밀 정보가 디스크에 남지 않게 합니다.
  • 액세스 토큰 만료는 JWT exp 클레임에서 파싱하며(JWT가 아닌 토큰은 1시간 폴백), 공급자가 비정상적인 expires_in을 보내도 갱신 폭주를 막도록 사용 가능한 최소값으로 클램프됩니다.
  • 만료 60초 전에 사전 갱신이 발생하며, tokio::sync::Mutex로 single-flight 처리됩니다. 업스트림 백엔드가 401을 반환하면 정확히 한 번 강제 갱신 후 한 번만 재시도합니다. 공급자가 갱신 응답에서 refresh_token을 생략해도 이전 refresh token이 race-free로 보존됩니다.
  • 스트래티지가 identity_fingerprint()(백엔드 이름, client_id, token_store)를 보고하므로, 핫 리로드에서 이 값이 변경되면 이전 인메모리 상태를 조용히 유지하는 대신 스트래티지를 다시 만듭니다.
  • CLI는 verification_uri_completeuser_code에서 C0/C1 제어 문자를 출력 전에 제거해, 적대적인 공급자 응답이 ANSI 이스케이프로 터미널을 다시 그리지 못하게 막습니다.
  • auth.openai.comchatgpt.com/backend-api/codex로 향하는 모든 디바이스 플로우 및 런타임 요청에 originator: codex_cli_rs(auth.oauth.originator로 변경 가능)와 codex_cli_rs/<version> User-Agent(auth.oauth.user_agent로 변경 가능)가 들어가, 공식 Codex CLI와 일치시켜 Cloudflare가 403 JS 챌린지를 반환하는 대신 트래픽을 받아들이게 합니다.
  • YAML에서 auth.type: oauth가 받아들여지며, 레거시 snake_case 표기 o_auth도 함께 인식됩니다. client_idscope는 공개된 Codex CLI 값으로 기본 설정되어, ChatGPT 구독 사용 시 token_store만 지정하면 됩니다.
  • Anthropic Messages와 Chat Completions 양쪽 surface 모두 ChatGPT Codex 백엔드로 투명하게 라우팅됩니다 (#592)
  • auth.typeoauth이고 공급자가 Codex 플로우(현재 openai)를 사용하는 백엔드는 모델별 responses_only 메타데이터와 무관하게 모든 요청을 Responses API로 강제합니다. chatgpt.com/backend-api/codex/responses만 노출하고 /chat/completions이 없기 때문에, chat 모양 모델(예: gpt-5.5, alias 매핑된 claude-haiku-4-5)이나 알 수 없는 모델 ID도 모두 /v1/responses…/backend-api/codex/responses 경로로 dispatch됩니다. OAuth가 아닌 OpenAI 백엔드는 모델별 responses_only 플래그를 그대로 따릅니다.
  • core::url_utils::compose_backend_url/v1, /openai, /backend-api/codex 세 OpenAI 호환 루트의 백엔드 URL 합성을 한 곳으로 모았습니다. proxy/backend.rs, http/handlers/responses.rs, http/streaming/handler.rs, services/responses/stream_service.rs, Anthropic 핸들러에 흩어져 있던 ends_with("/v1") || ends_with("/openai") 체크를 대체해, /backend-api/codex 규칙이 일관되게 적용됩니다.
  • 프록시 핫 패스(proxy/backend.rs, proxy/responses_only.rs, proxy/image_gen.rs, proxy/image_edit.rs)는 이제 src/proxy/oauth_helper.rs를 통해 AppState에 노출된 백엔드 이름 키 기반 AuthStrategyRegistry를 거칩니다. 헬퍼가 스트래티지를 조회하고, 전송 직전에 refresh_if_needed()를 호출하며, 정적 bearer 헤더를 스트래티지가 만든 헤더로 교체하고, 401 응답에 한 번만 강제 갱신 + 재시도합니다. 스트래티지가 등록되지 않은 백엔드는 정적 api_key 인증이 변경 없이 계속 동작합니다.
  • Anthropic 호환 핸들러(src/http/handlers/anthropic/handler.rs)도 같은 레지스트리를 조회합니다. OAuth 스트래티지가 있는 백엔드에서는 클라이언트가 보낸 Authorization: sk-ant-…x-api-key 헤더를 OpenAI로 bearer로 전달하지 않고 떨어뜨립니다.
  • 모델 fetcher가 OAuth 인증 백엔드를 감지해 /v1/models 프로브 대신 설정된 models 목록으로 폴백합니다. chatgpt.com/backend-api/codex가 모델 엔드포인트를 노출하지 않기 때문입니다.
  • Codex 호환 Responses API 확장 (#536, #537)
  • 컨텍스트 압축용 POST /v1/responses/compact 엔드포인트. OpenAI / Azure OpenAI 네이티브 /v1/responses/compact로 패스스루하며, 다른 백엔드 유형은 501을 반환합니다.
  • ResponsesRequeststore 필드(기본값 true)가 업스트림 세션 영속화를 제어합니다. Codex는 임시(ephemeral) 요청에 store: false를 보냅니다.
  • input 항목에서 어시스턴트 콘텐츠와 사용자 콘텐츠를 구분할 수 있도록 input_text 옆에 output_text 콘텐츠 파트 타입이 추가되었습니다. 모든 변환기(OpenAI, Anthropic, Gemini)가 새 변형을 처리합니다.

문서

  • 루트 CHANGELOG.md와 한국어 문서(ko/configuration/backends.md, ko/configuration/advanced.md, ko/api.md, ko/architecture.md) 전반에 Codex / Responses-API 확장을 동기화. EN과 KO 빌드 양쪽의 zensical 빌드 경고를 모두 해결하고, pymdownx.slugs.slugify로 toc 앵커 slug의 유니코드를 보존합니다 (#596).
  • 영어와 한국어 mkdocs 소스 전반의 AI-slop 패턴 정리: 산문의 em dash 교체, filler/slop 단어 제거, 끝에 붙는 분사구와 과장된 동사 재작성, 콜론+불릿 AI 스타일 도입부 정리, 마무리 요약 slop을 구체적인 next-action 링크로 교체 (#597).

CI/CD

  • apple-actions/import-codesign-certs를 6에서 7로 bump (#590).

의존성

  • tokio 1.51.0 → 1.52.1, axum 0.8.8 → 0.8.9, reqwest 0.13.2 → 0.13.3, clap 4.6.0 → 4.6.1, fastrand 2.4.0 → 2.4.1, uuid 1.23.0 → 1.23.1, rand 0.10.0 → 0.10.1, lru 0.16.3 → 0.16.4로 bump (#595).

v1.5.6 - 2026-04-29

수정됨

  • responses_only reasoning 모델(gpt-5.4-pro, gpt-5.5-pro)에 대한 /v1/chat/completions 요청이 HTTP 502 responses_parse_failed로 실패하던 문제 수정. OpenAI의 /v1/responses 응답에 { "id": "rs_...", "type": "reasoning", "summary": [] } 모양의 출력 항목이 들어 있는데, OutputItem::Reasoningcontentstatus를 필수로 요구하던 탓에 serde가 missing field 'content'로 거절했습니다. Anthropic Messages surface는 다른 변환 경로로 우회하고 있어서 직접 테스트하기 전까지 버그가 가려져 있었습니다. 이제 OutputItem::Reasoningcontentstatus가 모두 선택 사항이며, reasoning 항목은 기존 정책에 따라 Chat Completions 클라이언트에 도달하기 전에 드롭됩니다. 즉 본문 모양은 deserialize에 성공하기만 하면 됩니다 (#594)

변경됨

  • model-metadata.yaml에서 Gemini 3.1 Pro 패밀리의 정규 ID를 gemini-3.1-pro-preview로 재정렬하고, gemini-3.1-pro(와 기존 -latest / -customtools 형태)는 alias로 강등. generativelanguage.googleapis.com이 실제로 제공하는 ID와 맞춘 결과로, 정규 형태의 gemini-3.1-pro는 업스트림에서 404를 돌려주기 때문에 GA 가용성이 있는 것처럼 보이지 않게 하려는 조정입니다. 메타데이터 캐시는 두 형태 모두 같은 항목으로 해석합니다. 참고로 업스트림으로 보내는 페이로드에서 alias를 정규 ID로 다시 쓰는 작업은 이번 릴리스 범위 밖이라, gemini-3.1-pro alias로 호출하는 클라이언트는 후속 작업이 들어오기 전까지 업스트림 404를 그대로 받게 됩니다 (#594)
  • 샘플 config.yaml에 새로 사용 가능해진 pro / 5.5 패밀리 모델(gpt-5.4-pro, gpt-5.2-pro, gpt-5.5, gpt-5.5-pro, claude-opus-4-7, gemini-3.1-pro, gemini-3.1-pro-preview)을 등록해 responses_only dispatch 경로를 실제 업스트림으로 end-to-end 검증할 수 있게 했고, 중복된 claude-haiku-4-5 항목 제거

v1.5.5 - 2026-04-27

추가됨

  • OpenAI Pro 모델용 투명한 Responses-API 라우팅 (epic #581)
  • model-metadata.yaml과 내장 OpenAI 레지스트리에 responses_only: true capability 플래그를 추가. gpt-5.2-pro, gpt-5.4-pro, gpt-5.5-pro가 업스트림 /v1/responses로만 제공되는 모델로 표시됨 (#574, #582)
  • responses_only 모델에 대한 /v1/chat/completions 요청이 업스트림 /v1/responses 엔드포인트로 dispatch되고, 응답이 strict 모드의 chat.completion(스트리밍은 chat.completion.chunk) 봉투로 다시 변환됩니다. 클라이언트에는 투명합니다. 스트림 usagestream_options.include_usage로 제어되며, responses_only 경로에 대한 모델별 latency / success 카운터가 기록됩니다 (#578, #584)
  • responses_only 모델에 대한 /anthropic/v1/messages 요청은 Responses API 모양으로 변환되어 /v1/responses로 dispatch되고, Anthropic Messages JSON(스트리밍은 Anthropic SSE 이벤트 시퀀스)으로 다시 변환됩니다. 도구 호출 왕복, 웹 검색 에뮬레이션, Unix 소켓 전송 모두 같은 플래그에서 분기합니다 (#575, #577, #583, #585, #586)
  • Anthropic Messages ↔ Responses 요청 변환기는 system → instructions, tools, tool_choice(disable_parallel_tool_useparallel_tool_calls: false 포함), max_tokensmax_output_tokens, reasoning effort 추론, 멀티턴 도구 왕복을 모두 다룹니다. 응답 변환기는 thinking/text/tool_use 순서와 stop-reason 충실도를 그대로 보존합니다 (#575, #583)
  • SSE 스트리밍 브리지(AnthropicResponsesStreamTranslator)는 Responses API 이벤트를 Anthropic Messages 이벤트로 매핑하면서 Anthropic의 엄격한 이벤트 순서 불변량(단일 message_start, 짝지어진 content_block_start/content_block_stop, 종결 message_stop)을 유지합니다. 중간 error / response.failed / response.cancelled, response.incompletestop_reason: max_tokens, 지연된 input 토큰, 그레이스풀한 조기 종료 합성도 처리합니다 (#576, #585)
  • /v1/responses는 OpenAI와 Azure OpenAI 백엔드만 제공합니다. responses_only 모델이 다른 백엔드 유형과 짝지어지면 업스트림 호출 전에 400 invalid_request_error가 반환됩니다(/v1/chat/completions/anthropic/v1/messages 양쪽에서 거절) (#577, #589)
  • (backend, model) 쌍별 첫 dispatch가 info 레벨로 로깅되므로, 디버그 로그를 켜지 않고도 운영자가 Responses-API 라우팅 여부를 확인할 수 있습니다
  • Anthropic Messages → Responses 요청은 명시적으로 store: false를 보내 업스트림 부작용을 피합니다 (#589)
  • {Anthropic, Chat} × {gpt-5.4-pro, gpt-5.2-pro} × {non-streaming, streaming} × {plain, tool-call, reasoning} 매트릭스, 양쪽 surface의 중간 백엔드 실패 negatives, 업스트림 바이트 단편화 회귀 가드를 다루는 22개 결정론적 in-process 통합 테스트 (#579, #588)
  • docs/en/configuration/advanced.md(Responses-API-only Models 섹션을 Models-marked-out-of-the-box, Marking-a-new-model, Dispatch-behavior, Backend-type-constraint 하위 섹션으로 분리), docs/en/architecture.md(Responses-API Routing 데이터 흐름 다이어그램), docs/en/api.md Chat Completions 및 Anthropic Messages surface 노트(투명한 Responses-API 라우팅 하위 섹션 포함)에 문서화 (#580, #587)

수정됨

  • Chat Completions responses-only 라우팅이 업스트림 dispatch 전에 호환되지 않는 백엔드 설정을 거절하고, 가능한 경우 호환되는 OpenAI/Azure Responses 백엔드를 선택하도록 수정 (#589)
  • Chat assistant tool_calls[]/v1/chat/completions의 stateless 도구 결과 턴에 대해 Responses function_call input 항목으로 보존되도록 수정 (#589)

v1.5.4 - 2026-04-25

변경됨

  • 2026년 4월 말 frontier 모델 출시에 맞춰 model-metadata.yaml 갱신 (#572, #573)
  • GPT-5.5 추가 (\(5/\)30 per 1M, 1M 컨텍스트, 지식 cutoff 2025-12, omnimodal, Terminal-Bench 2.0에서 82.7%로 1위)와 GPT-5.5 Pro 추가 (\(30/\)180 per 1M, Responses API 전용, 심층 reasoning) — 2026-04-23 출시
  • DeepSeek V4 Pro 추가 (1.6T total / 49B active MoE, 1M 컨텍스트, 384K 최대 출력, 3가지 reasoning effort 모드)와 DeepSeek V4 Flash 추가 (284B total / 13B active MoE, 1M 컨텍스트, 384K 최대 출력). 공식 API 문서에 따라 deepseek-chatdeepseek-reasoner는 deprecated alias로 유지 — 2026-04-24 출시
  • gpt-image-2 추가 (이미지당 과금 대신 토큰 단위 과금: 텍스트 \(5/\)30, 이미지 \(8/\)30 per 1M 토큰; 1K/2K/4K 해상도 단계; 거의 모든 언어에서 ~99% 텍스트 정확도; 생성 전 내장 reasoning; 컨텍스트 인식 멀티턴 편집; gpt-image-2-latest alias) — 2026-04-21 출시
  • Claude Opus 4.7 추가 (\(5/\)25 per 1M, 1M 컨텍스트, 128K 최대 출력, 지식 cutoff 2026-01, 최대 2576px / 3.75MP 고해상도 이미지 지원, 새 토크나이저로 이전 모델 대비 ~1.0–1.35× 토큰 사용, 새 xhigh effort 레벨) — 2026-04-16 출시
  • Gemini 3.1 시리즈를 preview에서 GA로 승격하고, fallback 호환을 위해 -preview 접미사를 alias로 유지 (#573)
  • gemini-3.1-pro-previewgemini-3.1-pro (alias: gemini-3.1-pro-preview, gemini-3.1-pro-preview-customtools, gemini-3.1-pro-latest)
  • gemini-3.1-flash-image-previewgemini-3.1-flash-image (alias: gemini-3.1-flash-image-preview, nano-banana-2, gemini-3.1-flash-image-latest)
  • gemini-3.1-flash-lite-previewgemini-3.1-flash-lite (alias: gemini-3.1-flash-lite-preview, gemini-3.1-flash-lite-latest)
  • gemini-3-flash-preview의 deprecation 노트를 새 GA gemini-3.1-pro ID로 가리키도록 업데이트

v1.5.3 - 2026-04-23

추가됨

  • src/models/pattern_matching.rs의 새 매칭 phase 5로 HuggingFace repo 접두사 제거 (#555)
  • try_strip_hf_repo_prefix()vendor/repo(또는 org/team/repo) 접두사를 MAX_PREFIX_SEGMENTS = 3 한계 안에서 검증하고, 빈 segment(/repo, vendor/, vendor//repo)를 거절하며, ASCII 공백이 들어가 있으면 거절한 뒤 잔류 문자열을 반환합니다
  • phase 5는 잔류 문자열로 phase 1-4에 재진입하는데, 재귀 깊이가 구조적으로 정확히 1로 보장됩니다(재진입 호출이 allow_prefix_strip 게이트를 닫습니다). 따라서 접두사 제거가 기존 계층적 접미사 peel과 단일 lookup 안에서 합성됩니다 — 동기 사례인 unsloth/Qwen3.6-35B-A3B-GGUF가 별도 alias 등록 없이도 qwen3.6-35b-a3b로 해결됩니다
  • phase 5는 wildcard phase 앞에서 실행됩니다. blast-radius 감사 결과 model-metadata.yaml*가 포함된 alias 중 /를 가진 게 없어, 순서 변경이 기존 라우팅 동작에 영향을 주지 않습니다
  • tracing 출력의 phase 번호를 문서화된 phase 체인과 일치시킴(이전 코드는 namespace fallback에 phase = 7을 출력하면서 주석은 phase 6이라고 부르고 있었음)
  • 표준 HF 형태, suffix peel과의 합성, 대소문자 구분 vendor, 등록된 alias 우선순위, 해결 불가능한 잔류, 3-segment 형태, segment-cap 거절, no-slash 입력, 공백 거절, 빈 segment, 재진입 한계, alias-phase 우선순위를 다루는 12개 단위 테스트
  • tests/format_suffix_normalization_test.rs의 9개 통합 테스트가 phase 5를 거치는 전체 RouterConfig / BackendConfig 공개 API를 검증
  • docs/en/configuration/advanced.md(과 한국어 카운터파트)의 파이프라인 문서에 합성 의미, 보안 한계, out-of-scope 항목(하이픈 접두사, HF API discovery)을 다루는 새 "HuggingFace repo-prefix stripping (phase 5)" 섹션 추가

변경됨

  • 이전 phase-6 namespace fallback을 새 phase-5 HuggingFace 접두사 제거 계층으로 교체. 이전 phase는 대소문자를 구분했고 suffix peel과 합성되지 않았는데, 새 phase는 더 엄격한 입력 검증(segment cap, 빈 segment 거절, 공백 거절)을 적용하면서 phase 4의 대소문자 무시 peel과 bounded re-entry로 합성됩니다. MAX_PREFIX_SEGMENTS(3)를 넘는 병적인 입력(provider/deep/nested/model 등)은 이제 재귀적인 rsplit_once fallback으로 조용히 매칭되는 대신 phase 5에서 거절됩니다 (#555)
  • 560 감사에서 vendor-prefix로 분류되었던 alias(Qwen/Qwen3.6-35B-A3B, MiniMaxAI/MiniMax-M2.5 등)가 #555 이후로 peel-coverable-adjacent가 되었습니다. phase 2가 명시적 alias에서 여전히 먼저 승리하지만, phase 5 + phase 4 조합으로도 같은 메타데이터에 도달합니다. 소급 제거는 #555 디자인 섹션 7에 따라 후속 감사로 미룹니다

수정됨

  • 선택된 백엔드가 unix:// URL로 설정되었을 때 POST /anthropic/v1/messages가 동작하도록 수정 (#567)
  • 네이티브 Anthropic 백엔드와 OpenAI 호환 백엔드 모두 비스트리밍과 스트리밍 요청에서 Unix 소켓 위로 동작
  • 공백이 포함된 소켓 경로(macOS ~/Library/Application Support/... 등)도 정확히 처리
  • Auth 헤더 선택(Anthropic 백엔드는 x-api-key, OpenAI 호환 백엔드는 Authorization: Bearer)이 Unix 소켓 경로에서 정확히 동작
  • anthropic-version 헤더가 Unix 소켓 경로의 Anthropic 백엔드에 자동으로 추가되어, HTTP 경로 동작과 일치

v1.5.2 - 2026-04-21

추가됨

  • llama.cpp와 MLxcel 백엔드의 transport-layer passthrough 계약을 잠그는 회귀 테스트 (#562)
  • tests/llamacpp_passthrough_test.rstests/mlxcel_passthrough_test.rs가 4개 passthrough 호출 사이트를 모두 다룸: 직접 백엔드 execute_chat_completion, factory로 빌드된 백엔드(BackendFactory -> LlamaCppBackend), proxy/backend.rs HTTP 핸들러, 스트리밍 핸들러
  • test_mlxcel_factory_backend_passthrough_nonstandard_fieldsBackendFactory -> LlamaCppBackend::execute_chat_completion이 비표준 필드를 transport 시점에 byte-for-byte 보존함을 단언
  • Anthropic input 테스트(tests/anthropic_input_test.rs)에 명시적 passthrough 커버리지 추가
  • passthrough 계약과 4개 보호된 호출 사이트, transport 직전에 실행되는 라우터 측 변환 목록(global_prompts, o1/o3/gpt-5*용 transform_payload_for_openai, web_search 주입)을 문서화한 docs/en/architecture/backend-passthrough.md와 한국어 카운터파트 docs/ko/architecture/backend-passthrough.md (#562, #563)
  • model-metadata.yaml의 모든 alias를 peel-redundant, peel-redundant-but-kept, peel-independent로 분류한 docs/reports/alias-audit-2026-04.md. docs/en/configuration/advanced.md(과 한국어 카운터파트)에 두 메커니즘 중 무엇을 선호할지 설명하는 "aliases vs peel" 정책 섹션 추가 (#560)

변경됨

  • passthrough 계약을 암묵적인 "byte-equivalent" 전역 보장에서 transport-layer 범위로 좁힘. 라우터는 transport 직전에 global_prompts 주입, o1/o3/gpt-5* 페이로드 변환, web_search 도구 주입을 여전히 수행할 수 있지만, transport 경계에서는 공급자별 재작성이 없음 (#563)
  • src/http/streaming/handler.rs, src/infrastructure/backends/factory/backend_factory.rs, src/infrastructure/backends/llamacpp/backend.rs, src/proxy/backend.rs에 주석 수준의 명확화
  • model-metadata.yaml alias를 peel-normalization 중복 여부로 감사: 정규 ID와 계층적 peel이 이미 처리하는 접미사(-4bit, -q4_k_m, -fp8, -gguf, -mlx, -awq 등)만 다른 alias는 제거하고, 정규 flavor 변형(-qat, -instruct)을 인코딩하거나 파라미터 카운트를 구분하는(-1.5b vs -7b) alias는 유지 (#557)
  • tests/alias_audit_helper.rstests/format_suffix_normalization_test.rs가 앞으로 peel-vs-alias 경계를 강제

CI

  • Debian 빌드 워크플로에서 25.10 (Questing) 대신 Ubuntu 26.04 LTS (Resolute) 타겟으로 변경
  • debian/update-changelog.sh가 최신 릴리스가 아직 draft 상태일 때 changelog가 회귀하지 않도록 release publishedAt이 null이면 createdAt로 폴백

v1.5.1 - 2026-04-20

추가됨

  • 자체 호스팅 LLM 백엔드용 내장 web_search 도구 (#553)
  • vLLM, Ollama, llama.cpp, MLxcel, LM Studio, Continuum Router, Generic 백엔드의 chat completion 요청에 라우터 단에서 투명하게 주입되는 도구
  • src/services/search/에 플러거블 SearchProvider 트레이트와 SerperProvider 구현. Exa와 Brave는 같은 트레이트 뒤에 스캐폴드 완료
  • 백엔드별 오버라이드가 가능한 inject_policy (auto/always/never). 상용 백엔드(OpenAI, Azure, Gemini, Anthropic)는 손대지 않아, 네이티브 web_search가 그대로 흐름
  • bounded 비스트리밍 도구 실행 루프가 web_search 도구 호출을 파싱해 공급자를 실행하고, tool-role 결과를 추가한 뒤 백엔드를 최대 max_tool_iterations 라운드까지 다시 호출
  • 상용/자체 호스팅 분할 불변량을 강제하는 단위 테스트가 포함된 새 BackendTypeConfig::is_self_hosted / is_commercial 헬퍼
  • API 키는 Debug 출력에서 마스킹되고 로그에 남지 않음. ${ENV} 치환을 지원하는 핫 리로드 친화적 WebSearchConfig
  • 도구 호출, 주입, iteration-cap 도달에 대한 Prometheus 카운터를 src/metrics/web_search에 추가
  • 모델 메타데이터 lookup용 계층적 양자화 및 형식 접미사 정규화 (#549)
  • src/models/pattern_matching.rs의 새 layered_format_strip()이 모델 ID 오른쪽에서 allowlist된 양자화/형식/flavor 토큰을 반복적으로 peel하며, peel마다 정확한 ID/alias/날짜 접미사 매칭을 다시 시도
  • 토큰 카테고리: BIT_WIDTH, GGUF_QUANT, FP_FORMAT, INT_FORMAT, LIBRARY, IMATRIX, UNSLOTH, CONTAINER, FLAVOR (전부 대소문자 무시)
  • 파라미터 카운트 접미사 보존: -Nbit은 양자화로 제거되고, -Nb, -aNb, -eNb, -0.6b는 파라미터 카운트로 유지
  • allowlist된 flavor로 끝나는 정규 base ID(gemma-3-12b-qat 등)는 peel 실행 전 정확한 ID 매칭으로 승리
  • 정규화 파이프라인이 find_matching_config, BackendConfig::get_model_metadata, RouterConfig::get_model_metadata, RouterConfig::get_thinking_pattern_config, resolve_model_tier(라우팅), get_model_profile(admin)에 연결됨
  • GLM 5.1, Qwen 3.6, MiniMax M2.7 모델 메타데이터 (#548)
  • 빌드와 Docker 작업이 끝난 뒤 Power Automate 웹훅을 통해 Microsoft Teams로 릴리스 알림 게시

변경됨

  • 문서 도구 체인을 MkDocs + Material for MkDocs에서 Zensical로 마이그레이션. mkdocs.yml을 네이티브로 읽고 필요한 확장을 번들링

수정됨

  • 보안: 계층적 peel phase에 MAX_MODEL_ID_LEN=256MAX_PEEL_ITERATIONS=8 캡을 적용해, -4bit-4bit-4bit-... 같은 병적 모델 ID로 인한 DoS(이전엔 O(n²) 할당)를 제거
  • 보안: /v1/chat/completions, /v1/completions, /v1/embeddings, /v1/embeddings/sparse에 256자 model 필드 길이 제한 적용 (기존 /v1/responses 체크와 동등)
  • 7-phase 메타데이터 매칭 파이프라인을 단일 구현(find_matching_config_slice)에 통합하고 호출 사이트마다 얇은 어댑터를 두어, BackendConfig, Config::get_model_metadata, Config::get_thinking_pattern_config, find_matching_config 사이의 drift 제거
  • hot path에서 cfg.to_ascii_lowercase() == peelstr::eq_ignore_ascii_case로 교체 (요청당 String 할당 약 4000개 감소)
  • MkDocs 빌드 실패를 막기 위해 Pygments <2.20 핀 (Zensical 마이그레이션으로 무효화)

CI

  • softprops/action-gh-release를 2에서 3으로 bump (#544)
  • actions/github-script를 8에서 9로 bump (#545)
  • actions/upload-pages-artifact를 4에서 5로 bump (#554)

문서

  • docs/en/configuration/advanced.md에 접미사 순서 모호성(-qat-4bit vs -4bit-qat)과 내부 peel phase 한계 문서화
  • docs/en/architecture.md의 Model Aggregation Service 모듈 목록에 pattern_matching.rs 추가하고, suffix normalization 섹션으로 상호 참조 링크
  • docs/en/web-search.md 기능 문서. config.yaml.exampleweb_search 섹션 확장

v1.5.0 - 2026-04-11

추가됨

  • 모델 tier 및 capability profile 레지스트리를 갖춘 smart routing 시스템 (#525, #531)
  • 규칙 기반 요청 분류기 및 smart routing 정책 엔진 (#526, #532)
  • 부하 인식 동적 tier 조정 (#527, #533)
  • 하이브리드 모드를 갖춘 LLM 기반 요청 분류기 (#528, #534)
  • Smart routing 관측, admin API, 문서 (#529, #535)
  • Codex 호환 Responses API 확장 (#536, #537)

변경됨

  • 핵심 의존성 업그레이드 — axum 0.8, sha2 0.11, rand 0.10 (#523)
  • Gemma 4 모델 패밀리 메타데이터 추가 (#538)

수정됨

  • Smart routing 통합 갭 보완
  • DefaultTransformer PDF 크기 제한을 20MB에서 32MB로 증가 (#542)

CI

  • actions/deploy-pages를 4에서 5로 bump (#521)

의존성

  • minor-and-patch 의존성 그룹 4개 업데이트 bump (#539)

문서

  • Codex 호환 Responses API 갭 분석 보고서 추가

v1.4.5 - 2026-03-27

수정됨

  • 파일 서비스가 설정되지 않은 상태에서 파일 참조가 사용되면 400 오류를 반환하도록 수정 (#519)

변경됨

  • GLM-5-Turbo 모델 메타데이터 추가 (#516)

문서

  • ko/ 문서의 한국어 anti-AI-slop 위반 수정
  • api.md의 슬롭 단어와 전환어 수정

v1.4.4 - 2026-03-18

수정됨

  • high/xhigh reasoning effort에서 Anthropic thinking이 실패하던 문제 수정. budget_tokens(32768)가 기본 max_tokens(16384)를 초과해 API가 거절했음 (#514)
  • thinking이 켜져 있고 budget이 max를 초과하면 max_tokensbudget_tokens + 4096으로 자동 조정

변경됨

  • GPT-5.4 모델 패밀리 추가: 1M 컨텍스트 윈도우의 gpt-5.4, gpt-5.4-pro, gpt-5.4-mini, gpt-5.4-nano (#515)
  • Gemini 3 시리즈 업데이트: gemini-3.1-pro-preview, gemini-3-flash-preview, gemini-3.1-flash-lite-preview 추가, gemini-3-pro-preview deprecation 표시
  • include_thoughts 자동 주입을 위해 Gemini 3 Flash와 3.1 Flash-Lite를 thinking 모델로 인식
  • Claude 4.6 모델 업데이트: 컨텍스트 윈도우 1M(GA), Sonnet 4.6 max_output을 64K로 수정, 지식 cutoff 보정
  • 8개 파일에 걸쳐 설정 예시와 문서를 최신 모델 이름으로 업데이트

v1.4.3 - 2026-03-18

수정됨

  • 라우터를 거친 스트리밍 응답에서 Gemini thinking 모델(2.5 Pro, 3 Pro 등)이 reasoning_content를 반환하지 않던 문제 수정 (#513)
  • transform_payload_for_gemini()transform_request_gemini()로 3개 Gemini 스트리밍 경로 모두에서 교체해 include_thoughts: true 자동 주입을 보장

v1.4.2 - 2026-03-17

변경됨

  • 스트리밍 안정성 개선을 위해 mid-stream fallback 기본값을 활성화로 변경 (#504)
  • Breaking: mid-stream fallback이 이제 기본 활성화. 이전 동작으로 복원하려면 mid_stream_fallback.enabled: false를 설정

문서

  • fallback 동작을 최적화하기 위한 failover latency 튜닝 가이드 추가

v1.4.1 - 2026-03-17

추가됨

  • 스트리밍 추론용 mid-stream fallback (#497) — SSE 스트리밍 중에 백엔드가 실패하면 라우터가 fallback 백엔드로 투명하게 재시도

변경됨

  • pre-stream fallback과 mid-stream fallback을 분리 (#500) — 각각 독립적으로 활성화/비활성화 가능
  • 의존성 버전을 최신 메이저로 bump

수정됨

  • 스트리밍 설정 변경이 핫 리로드에서 감지되지 않던 문제 수정 (#503)
  • fallback 중 mid-stream 연결 오류가 클라이언트로 누설되던 문제 수정 (#502)
  • 사용하지 않는 config crate 의존성 제거

CI

  • dorny/paths-filter를 3에서 4로 bump (#493)
  • actions/create-github-app-token을 2에서 3으로 bump (#494)

v1.4.0 - 2026-03-14

추가됨

  • Prefix-aware routing: PrefixAwareHash 선택 전략과 Bounded Loads를 적용한 Consistent Hash (CHWBL) (#455, #457, #461)
  • Response caching: SHA256 기반 캐시 키 계산, 스트리밍 응답 버퍼링과 완료 후 캐싱 (#456, #459, #462)
  • 다단계 CacheStore: 인메모리 백엔드 (#466), 연결 풀링이 있는 Redis/Valkey 백엔드 (#467), S3 기반 L1/L2 다단계 캐시 (#483)
  • KV 캐시 인덱스: 공유 데이터 구조 (#470), vLLM 백엔드 스트림용 KV 이벤트 컨슈머 (#471), 백엔드 선택에 통합된 prefix overlap 점수 (#473), 설정/메트릭/admin 엔드포인트 (#474)
  • 스토리지 tier 인식이 있는 Tiered KV cache (GPU hot / external warm) (#484)
  • 외부 KV 텐서 전송을 사용하는 disaggregated prefill/decode 오케스트레이션 (#485)
  • Anthropic cache_control breakpoint 자동 주입 (#460)
  • Gemini Embedding 2용 멀티모달 임베딩 지원 (#492)
  • 공유 캐시 설정 및 운영 메트릭 (#468)
  • model-metadata.yaml에 30개 신규 모델 추가 (#472)

변경됨

  • VAST 전용 식별자를 일반 S3/외부 스토리지 이름으로 변경 (#490) — VAST 전용 필드 이름을 사용 중이라면 설정 파일을 업데이트하세요

수정됨

  • 공백이 포함된 Unix 소켓 경로용으로 RequestExecutor를 transport-aware로 변경 (#488)
  • 문서의 상대 source tree 링크를 GitHub URL로 교체

CI

  • docker/setup-qemu-action을 3에서 4로 bump (#428)
  • docker/metadata-action을 5에서 6으로 bump (#426)
  • docker/setup-buildx-action을 3에서 4로 bump (#429)
  • docker/build-push-action을 6에서 7로 bump (#430)
  • docker/login-action을 3에서 4로 bump (#427)

문서

  • 종합적인 KV cache 기능 문서, 벤치마크, 설정 예시 (#477)
  • VAST Data 연결 가이드 및 통합 예시 (#486)
  • 한국어 문서를 영문 카운터파트와 동기화
  • 단일 configuration.md를 6개 파일로 분할

v1.3.0 - 2026-03-12

추가됨

  • Agent Communication Protocol (ACP) 지원: JSON-RPC 2.0 프로토콜 계층과 stdio transport (#414, #420)
  • ACP 세션 관리: 프로토콜 라이프사이클, initialize/shutdown handshake (#415, #421)
  • ACP-to-LLM 추론 파이프라인: 스트리밍 지원 (#416, #422)
  • ACP 도구 호출 보고와 권한 위임 (#417, #423)
  • MCP 서버 터널링용 MCP-over-ACP 브리지 (#418, #424)
  • 메타데이터와 설정 지원이 있는 ACP 에이전트 레지스트리 (#419, #425)
  • 프로토콜 라이프사이클과 세션 관리용 ACP 통합 테스트

수정됨

  • ACP 통합 테스트의 clippy field_reassign_with_default 경고 해결

CI

  • actions/upload-artifact를 6에서 7로 bump (#398)

문서

  • MkDocs 통합이 있는 ACP 아키텍처 문서
  • IDE 통합 예시가 있는 ACP 실용 사용 가이드
  • 라우터 단 캐싱 전략용 KV 캐시 통합 계획

v1.2.1 - 2026-03-07

추가됨

  • MLX 기반 모델 서빙용 MLxcel 백엔드 유형 지원 (#412, #413) — llama-server와 API가 완전히 호환되며, 헬스 체크/모델 디스커버리/프록싱에 같은 백엔드 구현을 재사용

v1.2.0 - 2026-03-06

추가됨

  • 관리자 통계 API - 관리자 API 엔드포인트를 통한 포괄적인 요청 수준 통계 수집 및 보고 추가 (#409)

    • GET /admin/stats - 전체, 모델별, 백엔드별 통계
    • GET /admin/stats/models - 모델별 통계만
    • GET /admin/stats/backends - 백엔드별 통계만
    • POST /admin/stats/reset - 수집된 모든 통계 초기화
    • ?window=1h, ?window=24h 등을 통한 시간 윈도우 쿼리
    • OpenAI 호환 API 응답에서의 토큰 사용량 추적
    • 링 버퍼에서 계산되는 지연 백분위수 (p50, p95, p99)
    • 최소 성능 영향을 위한 핫 패스에서의 락프리 원자적 카운터
    • 통계 설정 변경에 대한 핫 리로드 지원
  • 통계 영속화 - 관리자 통계를 위한 영속적 스토리지 추가 (#410, #411)

    • 설정 가능한 스냅샷 경로, 간격, 비활성 검사를 위한 최대 수명
    • 데이터 안전을 위한 원자적 쓰기 (임시 파일 + 이름 변경)
    • 누락, 손상 또는 비활성 파일의 그레이스풀 처리로 시작 시 디스크에서 통계 복원
    • 그레이스풀 셧다운 (SIGTERM/SIGINT) 시 최종 스냅샷 저장

문서

  • 설정 가이드에 관리자 통계 및 영속화 추가
  • v1.1.0 리팩토링 후 벤치마크 보고서 추가 (#407)
  • admin-api.md에 통계 API 문서화 (영어 및 한국어)

v1.1.1 - 2026-03-04

추가됨

  • 임베딩 가능한 라이브러리 크레이트 - continuum-router를 임베딩 가능한 라이브러리 크레이트로 활성화 (1단계) (#394)

    • 프로그래밍 방식의 라이브러리 사용을 위한 타입 안전 설정 빌더 (#400)
    • 선택적 라이브러리 의존성을 위한 Cargo 피처 플래그 (#399)
  • 영속적 런타임 API 키 - 런타임 API 키를 위한 영속적 스토리지 추가 (#405)

  • 모델 메타데이터 - 새로운 LLM 모델에 대한 모델 메타데이터 항목 추가 (#403)

수정됨

  • Anthropic 핸들러에서 Gemini 전용 변환 적용 (#404)

v1.1.0 - 2026-03-01

추가됨

  • 임베디드 WebUI - 설정 관리 및 API 키 관리를 위한 임베디드 WebUI 추가 (#388)

    • 라우터 바이너리에서 직접 제공되는 브라우저 기반 관리 인터페이스
    • 외부 도구 없이 설정 편집 및 관리
    • 그래픽 인터페이스를 통한 API 키 관리
  • Windows AF_UNIX 소켓 지원 - socket2 크레이트를 통한 Windows AF_UNIX 소켓 지원 추가 (#390)

    • socket2 크레이트를 사용한 Windows에서의 완전한 Unix 도메인 소켓 지원
    • Windows 전용 소켓 주소 처리 및 전송 파싱
    • Windows 플랫폼에서 로컬 IPC 활성화
  • Nano Banana 2 (Gemini 이미지 생성) - Nano Banana 2 이미지 생성 모델 지원 추가

    • 최신 모델 세대에 대한 업데이트된 Gemini 이미지 생성 지원

수정됨

  • ClientAddr::is_unix에서 튜플 변형 매칭 컴파일 오류 해결
  • Windows AF_UNIX 소켓 accept 실패 및 설정 검증 해결
  • Unix 소켓 설정 검증에서 Windows 절대 경로 허용 (#393)
  • Unix 소켓 테스트 및 전송 파싱에서 Windows 컴파일 오류 해결 (#392)

v1.0.0 - 2026-02-19

추가됨

  • Continuum Router / Backend.AI GO 백엔드 타입 - 연합 LLM 라우팅을 위한 continuum-router 전용 백엔드 타입 추가 (#385)

    • 원격 Continuum Router 인스턴스 또는 Backend.AI GO 배포에 연결
    • 다중 serde 별칭: continuum-router, continuum_router, ContinuumRouter, backendai, backend-ai, backend_ai
    • Bearer 토큰 인증 및 자동 헤더 주입
    • 실시간 응답을 위한 SSE 스트리밍 지원
    • /v1/models 엔드포인트를 통한 자동 모델 탐색
    • /health를 기본으로 /v1/models 폴백을 사용하는 헬스 체크
    • 사용 사례: 연합 라우팅, 다중 리전 로드 밸런싱, 계층적 페일오버
  • LM Studio 백엔드 타입 - lmstudio 전용 백엔드 타입 추가 (#381)

    • LM Studio 로컬 서버에 대한 네이티브 지원
    • 기본 URL: http://localhost:1234 (LM Studio 기본 포트)
    • Serde 별칭: LMStudio, lm-studio, lm_studio
    • /v1/models 기본, /api/v1/models 폴백을 사용하는 헬스 체크
    • LM Studio 모델 목록에서 자동 모델 탐색
    • /v1/models 응답에서 owned_by: lmstudio 적절한 귀속
  • Claude 4.6 적응형 사고와 output_config.effort - Claude 4.6 모델을 위한 Anthropic의 output_config.effort 파라미터 지원 추가 (#384)

    • Claude 4.6 모델(claude-opus-4-6-*, claude-sonnet-4-6-*)은 이제 budget_tokens 대신 thinking: {"type": "adaptive"} + output_config: {"effort": "<level>"} 사용
    • 새로운 xhigh"max" effort 매핑: Opus 4.6용, Sonnet 4.6은 자동으로 "high"로 다운그레이드 (max는 Opus 4.6 전용)
    • minimal reasoning effort는 "low" effort로 매핑 (Anthropic API에 minimal 레벨 없음)
    • auto effort는 output_config를 생략하여 Anthropic 기본값(high) 사용
    • 4.6 이전 모델은 기존 budget_tokens 방식 유지
    • 역변환: Anthropic 요청을 OpenAI 형식으로 변환 시 output_config.effortreasoning_effort로 매핑
    • Responses API 변환기가 Claude 4.6 모델에서 적응형 사고를 사용하도록 업데이트
  • 적응형 사고 및 auto Reasoning Effort 레벨 - Claude Opus 4.6과 함께 도입된 Anthropic의 적응형 사고({"type": "adaptive"}) 지원 추가 (#377)

    • Anthropic 백엔드에서 {"type": "adaptive"}로 매핑되는 새로운 auto reasoning effort 레벨. 모델이 사고의 시점과 정도를 동적으로 결정
    • 모든 백엔드에서 auto 허용: Anthropic에서는 네이티브 적응형 사고, OpenAI 및 Gemini에서는 자동으로 medium으로 다운그레이드
    • 적응형 사고(고정 예산 없음)를 지원하기 위해 AnthropicThinking.budget_tokensOption<u32>로 변경
    • 평면 형식(reasoning_effort: "auto")과 중첩 형식(reasoning: {effort: "auto"}) 모두 지원
    • 적응형 사고 활성화 시 temperature 파라미터 자동 제거
  • Cohere/Jina 호환 리랭킹 및 희소 임베딩 엔드포인트 - 고급 검색 API 지원 추가 (#374)

    • 2단계 검색을 위한 새로운 /v1/rerank 엔드포인트 (Cohere 호환)
    • 희소 임베딩 (SPLADE 형식)을 위한 새로운 /embed_sparse 엔드포인트 (TEI/Jina 호환)
    • 리랭킹을 위한 단순 문자열 문서 및 text 필드가 있는 구조화된 문서 모두 지원
    • model, query, documents 필드에 대한 포괄적인 검증이 포함된 요청/응답 타입
    • 새로운 기능 매핑: rerank -> rerank 메서드, sparse_embedding -> embed_sparse 메서드
    • model-metadata.yaml에 예제 모델 추가: BGE Reranker, Jina Reranker, SPLADE 모델
  • BGE-M3 및 다국어 임베딩 모델 지원 - BGE-M3 및 동등한 다국어 임베딩 모델에 대한 모델 메타데이터 및 설정 예제 추가 (#373)

    • BGE-M3: 568M 파라미터, 1024 차원, 100개 이상 언어, 8192 컨텍스트. Dense, sparse(어휘), ColBERT 멀티벡터 검색 지원
    • BGE-Large-EN-v1.5: 335M 파라미터, 1024 차원, 영어 전용, 512 컨텍스트
    • Multilingual-E5-Large: 560M 파라미터, 1024 차원, 100개 이상 언어, 514 컨텍스트
    • vLLM, Ollama, Text Embeddings Inference (TEI) 배포를 위한 예제 백엔드 설정
    • RAG 시스템의 교차 언어 검색 요구 사항 해결
  • Anthropic 파일 변환기에 일반 텍스트 지원 추가 - Anthropic 파일 변환기에 text/plain 지원 추가 (#342)

    • 텍스트 파일은 base64 데이터가 포함된 document 블록으로 변환 (PDF와 동일한 형식)
    • 최대 텍스트 파일 크기: 32MB (PDF와 동일)
    • 텍스트 파일은 매직 바이트 검증 없음 (모든 콘텐츠 허용)
    • SUPPORTED_DOCUMENT_TYPES에 application/pdf와 함께 text/plain 추가
    • 오류 메시지에 일반 텍스트 지원 언급 추가
  • OpenAI 및 Anthropic 파일 변환기에 PDF 지원 추가 - 파일 변환기에 PDF 파일 지원 추가 (#340)

    • OpenAI 변환기: PDF를 base64 데이터 또는 파일 ID가 포함된 file 블록으로 변환
    • Anthropic 변환기: PDF를 base64 데이터가 포함된 document 블록으로 변환
    • 보안을 위한 PDF 매직 바이트 검증 (%PDF- 시그니처)
    • 최대 PDF 크기: 32MB (백엔드에서 100페이지 제한 적용)
    • 이미지는 20MB 제한 유지
  • 네이티브 Anthropic Responses API 지원 - Responses API에 대한 네이티브 Anthropic Messages API 변환 추가 (#332)

    • Responses API 요청을 네이티브 Anthropic Messages 형식으로 변환하는 새로운 AnthropicConverter
    • Anthropic 문서 이해 기능을 통한 전체 PDF 파일 지원 (file_data가 포함된 input_file)
    • 자동 미디어 타입 감지를 통한 이미지 파일 지원
    • Claude 3+ 모델을 위한 확장 사고(Extended Thinking) 콘텐츠 지원
    • Anthropic 형식의 적절한 SSE 이벤트 변환을 통한 스트리밍 지원
    • 완전한 응답 변환을 통한 비스트리밍 지원

수정됨

  • 외부 파일 URL에 대한 SSRF 검증 - 외부 파일 가져오기 시 SSRF 보호 추가 (#332)

    • 사설 IP 주소 검증 (10.x.x.x, 172.16-31.x.x, 192.168.x.x, 127.x.x.x 차단)
    • Localhost 및 링크 로컬 주소 차단
    • IPv6 루프백 및 링크 로컬 주소 차단
    • 해석 후 IP 검증을 통한 DNS 리바인딩 보호
  • 파일 입력에 대한 미디어 타입 화이트리스트 - 허용된 파일 유형에 대한 보안 화이트리스트 추가 (#332)

    • PDF: application/pdf
    • 이미지: image/jpeg, image/png, image/gif, image/webp
    • 지원되지 않는 미디어 타입은 명확한 오류 메시지와 함께 거부
  • AI SDK Responses API 스트리밍 호환성 - Responses API 스트리밍에서 Vercel AI SDK 호환성 문제 수정 (#334)

    • OpenAI 스펙에 맞춰 ResponseStreamEvent 직렬화가 점으로 구분된 타입 이름 사용 (예: "type": "output_text_done" 대신 "type": "response.output_text.done")
    • OutputItemAdded, OutputItemInProgress, OutputItemDone 및 기타 스트리밍 이벤트에 item_id 필드 추가
    • 이벤트 순서 추적을 위한 sequence_number 필드 추가 (긴 스트리밍 세션에서 오버플로우 방지를 위해 u64 사용)
    • ResponseStreamEvent에 대한 커스텀 Serialize 구현으로 올바른 JSON 출력 형식 보장
    • 새 필드가 올바르게 직렬화되는지 확인하기 위해 모든 기존 스트리밍 테스트 업데이트
  • 핫 리로드 백엔드 동기화 후 즉시 헬스 체크 - 핫 리로드로 백엔드 추가 시 즉시 헬스 체크 실행 (#367)

    • 설정 핫 리로드로 추가된 새 백엔드가 이제 즉시 헬스 체크됨
    • 이전에는 새 백엔드가 최대 30초(기본 헬스 체크 간격) 동안 사용 불가 상태로 유지됨
    • 외부 호출을 위해 HealthChecker::perform_health_checks() 공개 설정
    • Backend.AI GO 및 기타 클라이언트에서 모델 가용성 응답성 개선

v0.36.1 - 2026-01-30

수정됨

  • 핫 리로드 중 sync_backends 직후 즉시 헬스 체크가 트리거되도록 수정 (#368) — 새 백엔드를 최대 30초 대기 대신 1-2초 안에 사용 가능
  • 핫 리로드 중 health_check_info 동기화와 URL 기반 업데이트 사용 (#369) — 새 백엔드가 API 키 인증을 정확히 수신
  • 최근 추가된 백엔드의 헬스 체크 가속화 — 추가 후 5분 동안 1초 간격으로 체크
  • 백엔드가 정상 상태로 전환될 때 5초 디바운스로 모델 캐시 갱신 트리거

v0.36.0 - 2026-01-27

추가됨

  • 엔드포인트 라우팅이 포함된 네이티브 Anthropic Messages API 핸들러 (#355)
  • Anthropic ↔ OpenAI 요청/응답 변환 (#356, #357)
  • Anthropic 스트리밍 응답 형식 (#358)
  • Anthropic ↔ Gemini 직접 요청/응답 변환 (#359)
  • Anthropic 입력의 file_id 소스 타입과 파일 해석 (#360)
  • Anthropic 핸들러용 Claude Code 호환성 (#365)
  • 모든 백엔드 유형에 대한 계층적 토큰 카운팅
  • 성능 향상을 위한 병렬 파일 참조 해석
  • anthropic-version 헤더 형식 검증

수정됨

  • SSRF 방지를 위해 이미지 및 문서 URL에 HTTPS 요구
  • 백엔드 세부 정보 대신 일반 오류 메시지를 클라이언트에 반환
  • 파일 소유권 체크에 API 키로 인증된 user_id 사용
  • 안전한 메시지/도구 ID 생성을 위한 UUID v4 사용
  • Anthropic-to-OpenAI 변환에서 도구 메시지를 사용자 텍스트 앞에 배치
  • tool_use 블록이 있을 때 stop_reason을 tool_use로 오버라이드
  • OpenAI로 라우팅되는 Anthropic 요청에 max_completion_tokens 변환 적용
  • 파일 접근 거부 및 not found 오류를 클라이언트로 전파
  • 일관된 동작을 위해 요청당 current_config()를 한 번만 호출

리팩터

  • 공통 SSE 이벤트 타입과 데이터 추출 로직 분리
  • 정확한 UTF-8 처리를 위해 SseParser에 parse_bytes 메서드 추가
  • AnthropicFileResolver의 불필요한 Arc 래퍼 제거
  • enum 크기를 줄이기 위해 FileResolutionResult::Resolved를 Box 처리

v0.35.0 - 2026-01-23

추가됨

  • 함수 호출에서 Gemini 3 thoughtSignature 지원 (#354)
  • OpenAI와 Anthropic 파일 변환기에 PDF 지원 (#340)
  • AnthropicFileTransformer의 text/plain 지원 (#342)

수정됨

  • DefaultTransformer와 파일 해석에 PDF 지원 추가 (#343)
  • 비스트리밍 Anthropic 요청에 도구 메시지 변환 추가 (#344)
  • DefaultTransformer가 이미지가 아닌 파일을 명확한 오류 메시지로 거절 (#338)
  • AI SDK가 Responses API 스트리밍 형식과 호환되지 않던 문제 수정 (#335)

v0.34.0 - 2026-01-16

추가됨

  • 자동 품질 파라미터 변환 - DALL-E와 GPT Image 모델 간 자동 품질 파라미터 변환 추가 (#330)
    • GPT Image 품질 값을 DALL-E 동등 값으로 변환하는 ImageQuality 열거형의 to_dalle_quality() 메서드
    • handle_openai_image_generation()handle_streaming_image_generation()에서 투명하게 적용되는 품질 변환
    • 품질 변환 매핑:
      • DALL-E 3: low/medium/auto → standard, high → hd
      • GPT Image: standard → medium, hd → high
      • Gemini 모델: 품질 파라미터 무시 (변경 불필요)
    • 정확한 DALL-E 3 모델 매칭을 위한 is_dalle3_model() 헬퍼
    • 코드 중복 제거를 위한 convert_quality_for_model() 헬퍼
    • 변환은 디버깅을 위해 로그되며 사용자 대면 경고 없이 투명하게 수행

v0.33.0 - 2026-01-13

추가됨

  • Responses API 로컬 파일 해석 - Responses API 요청에서 로컬 file_id 참조 해석 (#325)
    • Files API를 통해 업로드된 파일을 이제 Responses API 요청에서 file_id로 참조 가능
    • FileResolver 서비스가 요청에서 file_id 참조를 스캔하고 로컬 스토리지에서 콘텐츠 로드
    • 파일 콘텐츠가 백엔드로 전송되기 전에 base64 file_data 형식으로 변환
    • 보안 기능: 파일 소유권 검증(user_id 확인) 및 주입을 위한 10MB 크기 제한
    • 그레이스풀 디그레이드: 해석 실패 시 경고 로그와 함께 원본 요청으로 폴백

수정됨

  • Responses API 플랫 도구 형식 - Responses API /v1/responses 엔드포인트가 플랫 도구 형식을 허용하도록 수정 (#323)
    • 함수 도구는 이제 플랫 형식 사용: {"type": "function", "name": "...", "parameters": {...}}
    • OpenAI Responses API 사양에 맞춤
    • 중첩 형식(function 래퍼 객체 포함)은 더 이상 Responses API에서 허용되지 않음
    • 플랫 도구 형식 예제로 문서 업데이트

v0.32.0 - 2026-01-09

추가됨

  • Reasoning Effort 문서 및 xhigh 폴백 로깅 - 포괄적인 reasoning effort 문서 추가 및 xhigh effort 레벨의 폴백 로깅 개선 (#317)
    • reasoning effort 파라미터 사용법을 설명하는 새로운 문서
    • 비 GPT-5.2 모델에서 xhigh effort 레벨이 high로 폴백될 때의 개선된 로깅

수정됨

  • Responses API InputItem의 암시적 메시지 타입 추론 - role 필드가 없을 때 암시적 메시지 타입 추론 지원 (#316)
    • 더 나은 성능을 위한 최적화된 InputItem 역직렬화기
    • 잘못된 role 테스트 커버리지 추가
    • Responses API에서 더 유연한 입력 처리 활성화

v0.31.5 - 2026-01-09

추가됨

  • 네이티브 OpenAI 백엔드용 Responses API 패스스루 - 백엔드 유형에 따른 /v1/responses API 스마트 라우팅 (#313)

    • OpenAI 및 Azure OpenAI 백엔드는 이제 패스스루 모드를 사용하여 /v1/responses 엔드포인트로 요청을 직접 전달
    • 다른 백엔드(Anthropic, Gemini, vLLM, Ollama, LlamaCpp, Generic)는 자동으로 네이티브 형식으로 변환
    • 패스스루 모드 이점: 네이티브 PDF 지원, 보존된 추론 상태, 내장 도구(web_search, file_search) 접근, 향상된 캐시 활용
    • 라우팅 결정을 위한 ResponsesApiStrategy 열거형이 포함된 새로운 router.rs 모듈
    • 직접 요청 전달을 위한 PassthroughService가 포함된 새로운 passthrough.rs 모듈
    • DoS 방지를 위한 요청 페이로드 크기 검증 (16MB 제한)
    • 라우팅 전략, 오류 처리, 요청 검증에 대한 포괄적인 테스트 커버리지
  • OpenAI Responses API 파일 입력 유형 - Responses API에서 멀티모달 파일 입력 지원 추가 (#311)

    • 새로운 input_text, input_file, input_image 콘텐츠 파트 유형
    • base64 데이터 URL(file_data)을 통한 PDF 문서 및 이미지 지원
    • SSRF 검증이 포함된 외부 파일 URL(file_url) 지원
    • 지원되지 않는 file_id 참조에 대한 경고 로그 (Files API 통합 보류 중)
    • Anthropic(document/image 블록) 및 Gemini(inline_data/file_data)용 백엔드별 변환기
    • 모든 입력 유형에 대한 포괄적인 테스트 커버리지

수정됨

  • 패스스루 원시 오류 응답 - 더 나은 오류 디버깅을 위해 패스스루 모드에서 백엔드 원시 오류 응답 전달

v0.31.4 - 2026-01-07

수정됨

  • API 키 전달을 위한 핫 리로드 지원 - 프록시 및 스트리밍 핸들러에서 핫 리로드 지원 수정 (#310)
    • 프록시 및 스트리밍 핸들러에서 캡처된 설정 스냅샷 대신 current_config() 사용
    • 핫 리로드를 통한 API 키 및 기타 설정 변경이 이제 새 요청에 올바르게 적용됨
    • 런타임 설정 업데이트가 백엔드 요청 전달에 영향을 미치도록 보장
    • 핫 리로드 api_key 적용을 위한 포괄적인 엔드투엔드 테스트 추가

v0.31.3 - 2026-01-06

수정됨

  • Unix 소켓 Anthropic 요청/응답 변환 - 변환 누락으로 인한 Unix 소켓을 통한 Anthropic 백엔드 실패 수정 (#307, #308)

    • Unix 소켓 전송이 이제 HTTP 전송과 동일한 요청 변환을 Anthropic 백엔드에 적용
    • OpenAI 형식 요청이 전송 전에 Anthropic 형식으로 올바르게 변환됨
    • Anthropic 응답이 OpenAI 형식으로 다시 변환됨
    • 엔드포인트가 /v1/chat/completions에서 /v1/messages로 올바르게 재작성됨
    • Unix 소켓 Anthropic 변환을 위한 포괄적인 통합 테스트 추가
  • Anthropic 비스트리밍 스트림 파라미터 - Anthropic 비스트리밍 요청에 대한 스트림 파라미터 보존 (#305, #306)

    • 비스트리밍 경로에서 transform_openai_to_anthropic_request(stream: true 강제) 대신 transform_openai_to_anthropic_with_global_prompt 사용
    • stream: false인 요청이 잘못 stream: true로 Anthropic API에 전송되는 문제 수정
    • 명확성을 위해 transform_openai_to_anthropic_requesttransform_openai_to_anthropic_streaming으로 이름 변경

문서

  • Jinja2 구문 이스케이프 - mkdocs-macros-plugin 오류를 방지하기 위해 한국어 설정 문서에서 Jinja2 구문 이스케이프

v0.31.2 - 2026-01-05

추가됨

  • Anthropic 백엔드의 비스트리밍 지원 - 비스트리밍 채팅 완료 호출에 대해 OpenAI 형식 요청을 Anthropic 형식으로 변환하고 Anthropic 응답을 OpenAI 형식으로 다시 변환

    • Anthropic 백엔드로의 비스트리밍 요청이 이제 요청/응답 형식을 올바르게 변환
    • 적절한 도구 호출 처리를 위해 transform_str을 사용하도록 스트리밍 핸들러 업데이트
  • Anthropic 백엔드의 도구 호출 및 도구 결과 변환 - Anthropic 모델로 라우팅 시 적절한 도구 사용 워크플로우 활성화

    • 어시스턴트 메시지의 OpenAI 스타일 tool_calls를 Anthropic의 tool_use 형식으로 변환
    • 도구 결과 메시지를 Anthropic의 tool_result 형식으로 변환
    • Anthropic 모델과의 멀티턴 도구 사용 대화 활성화

의존성

  • rustls, tokio-stream, syn을 포함한 12개 패키지를 최신 버전으로 업데이트

v0.31.1 - 2026-01-04

수정됨

  • Anthropic 비스트리밍 인증 헤더 수정 - 잘못된 인증 헤더로 인한 Anthropic 비스트리밍 요청 실패 문제 수정 (#300, #301)
    • Anthropic 백엔드로의 비스트리밍 요청이 이제 Authorization: Bearer 대신 x-api-key 헤더를 올바르게 사용
    • 모든 Anthropic 백엔드 요청에 anthropic-version 헤더 추가
    • HTTP 및 Unix 소켓 전송 경로 간 일관된 헤더 처리 적용
    • Anthropic API가 "Invalid Anthropic API Key" 오류 (HTTP 400)를 반환하던 문제 수정

v0.31.0 - 2026-01-04

추가됨

  • Unix 소켓 서버 바인딩 - TCP와 함께 Unix 소켓 바인딩 지원 추가 (#298)

    • 서버가 이제 로컬 통신을 위해 Unix 도메인 소켓에 바인딩 가능
    • 설정 파일에서 server.unix_socket으로 설정
    • TCP와 Unix 소켓 동시 바인딩 지원
  • Responses API의 Reasoning 파라미터 지원 - /v1/responses 엔드포인트에 reasoning 파라미터 지원 추가 (#296)

    • 중첩 형식 지원: {"reasoning": {"effort": "high"}}
    • 유효한 노력 수준: low, medium, high, xhigh (GPT-5.2 전용)
    • ReasoningEffortLevel 열거형을 사용한 타입 안전 검증
    • 백엔드를 위한 평면 reasoning_effort 형식으로 자동 변환
    • 역직렬화 시 잘못된 노력 값은 명확한 오류 메시지와 함께 거부
    • ResponsesRequestwith_reasoning() 빌더 메서드 추가
  • 설정 가능한 헬스 체크 엔드포인트 - 백엔드 타입별 설정 가능한 헬스 체크 엔드포인트 추가

    • 백엔드 타입에 따른 헬스 체크 경로 커스터마이징
    • 백엔드별 헬스 검증 지원

v0.30.0 - 2026-01-01

추가됨

  • 와일드카드 패턴 및 모델 별칭의 날짜 접미사 처리 - 모델 별칭에서 와일드카드 패턴 및 자동 날짜 접미사 처리 지원 (#286)
    • 자동 날짜 접미사 정규화: 날짜 접미사가 있는 모델 (예: claude-opus-4-5-20251130)이 기본 모델 (예: claude-opus-4-5-20251101)의 메타데이터와 자동으로 매칭
    • 지원되는 날짜 형식: -YYYYMMDD, -YYYY-MM-DD, -YYMM, @YYYYMMDD
    • * 문자를 사용한 별칭의 와일드카드 패턴 매칭
    • 접두사 패턴: claude-*claude-opus, claude-sonnet 등과 매칭
    • 접미사 패턴: *-previewgpt-4o-preview, o1-preview 등과 매칭
    • 중위 패턴: gpt-*-turbogpt-4-turbo, gpt-3.5-turbo 등과 매칭
    • 제로 설정 날짜 처리: 설정 변경 없이 자동으로 작동
    • 매칭 우선순위: 정확한 ID > 정확한 별칭 > 날짜 접미사 > 와일드카드 > 기본 이름 폴백

수정됨

  • Anthropic 백엔드 기본 URL - 지정되지 않은 경우 Anthropic 백엔드에 기본 URL 적용 (#288)
  • 백엔드별 owned_by 값 - owned_by 플레이스홀더를 백엔드 타입별 값으로 교체 (#287)

문서

  • 와일드카드 패턴 및 날짜 접미사 처리 문서를 한국어로 번역 (#289)

v0.29.0 - 2026-01-01

추가됨

  • 백엔드 웜업 중 가속 헬스 체크 - 백엔드 웜업 시 가속 헬스 체크 구현 (#282)
    • 백엔드가 HTTP 503 (Service Unavailable)을 반환하면 "웜업 중" 상태로 진입
    • 웜업 중 헬스 체크가 가속된 간격(기본: 1초)으로 수행
    • 모델 가용성 감지 지연을 최대 30초에서 약 1초로 감소
    • warmup_check_interval (기본: 1초) 및 max_warmup_duration (기본: 300초)으로 설정 가능
    • 모델 로딩 중 HTTP 503을 반환하는 llama.cpp 같은 백엔드에 특히 유용
  • 모델 메타데이터 CLI 옵션 - 모델 메타데이터 파일 경로 지정을 위한 --model-metadata 옵션 추가 (#281)
    • 런타임에 모델 메타데이터 YAML 파일을 지정하는 새로운 --model-metadata CLI 인자
    • 설정 파일의 model_metadata_file 설정을 오버라이드
    • 절대 경로, 상대 경로, 틸다 확장(~) 지원

수정됨

  • OpenAI owned_by 필드 - OpenAI owned_by 플레이스홀더를 'openai'로 교체 (#280)
    • OpenAI 백엔드의 모델이 이제 플레이스홀더 텍스트 대신 owned_by: openai를 올바르게 표시
  • 관리자 API 경쟁 조건 - 관리자 API 동시 백엔드 생성에서 경쟁 조건 방지 (#278)
    • 동시 백엔드 생성 요청이 데이터 손상을 일으킬 수 있는 문제 수정
    • 백엔드 관리 작업에 적절한 동기화 추가
  • 핫 리로드 처리 단계 - 핫 리로드에 누락된 처리 단계 추가 (#277)
    • 일부 설정 변경이 핫 리로드 중 제대로 적용되지 않는 문제 수정
    • 설정 리로드 시 모든 처리 단계가 실행되도록 보장
  • 클라우드 백엔드 가용성 상태 - 클라우드 백엔드가 이제 /v1/models/{model_id}에서 available:true 표시 (#272)
    • 클라우드 백엔드(OpenAI, Anthropic, Gemini)가 잘못 사용 불가로 표시되는 문제 수정
    • 클라우드 백엔드가 건강할 때 사용 가능으로 올바르게 표시

문서

  • v0.29.0 기능에 대한 테스트 및 문서 추가 (#459da6a)

v0.28.0 - 2025-12-31

추가됨

  • 도구 호출을 위한 SSE 스트리밍 지원 - 도구 호출에 SSE 스트리밍 지원 추가 (#258)
    • Server-Sent Events를 통한 도구 호출 응답의 실시간 스트리밍
    • 함수 호출 시나리오에서 효율적인 스트리밍 응답 활성화
  • llama.cpp 도구 호출 자동 감지 - /props 엔드포인트를 통한 도구 호출 지원 자동 감지 (#263)
    • 모델 검색 시 /props 엔드포인트를 쿼리하여 chat_template 분석
    • 도구 관련 키워드 감지 (tool, tools, tool_call, function 등)
    • 감지 시 function_calling 기능 자동 활성화
    • /props 엔드포인트를 사용할 수 없는 경우 우아한 폴백
    • HTTP 및 Unix 소켓 백엔드 모두에서 작동
  • 확장된 /v1/models/{model_id} 엔드포인트 - 풍부한 메타데이터 필드로 확장 (#262)
    • 기능 및 가격을 포함한 종합적인 모델 메타데이터 반환
    • 추가 모델 정보가 포함된 향상된 응답 형식
  • 도구 결과 메시지 변환 - 멀티턴 대화에서 도구 결과 메시지 변환 구현 (#265)
    • 도구 결과 메시지 (role: "tool")를 백엔드 네이티브 형식으로 변환
    • Anthropic: user 역할로 tool_result 콘텐츠 블록과 함께 변환
    • Gemini: function 역할로 functionResponse 파트와 함께 변환
    • Anthropic용으로 연속 도구 결과 결합 (병렬 도구 호출)
    • Gemini 변환을 위한 자동 함수 이름 조회
    • 오류 응답을 위한 is_error 표시자 보존
  • 백엔드별 owned_by 플레이스홀더 - llamacpp, vllm, ollama, http 백엔드에 owned_by 플레이스홀더 추가 (#267)

개선됨

  • CLI 도움말 출력 포맷팅 - 제목 헤더 및 프로젝트 귀속을 포함한 --help 출력 포맷팅 개선 (#269)
    • 향상된 커맨드 라인 도움말 시각적 외관
    • 도움말 출력에 프로젝트 귀속 추가

수정됨

  • 모델 메타데이터 캐시 동기화 - 모델 메타데이터 캐시를 ConfigManager와 동기화 (#270)
    • 모델 캐시가 설정 변경을 적절히 반영하도록 보장

CI/CD

  • 도구 호출에 대한 포괄적인 통합 테스트 (#264)

의존성

  • minor-and-patch 그룹에서 3개 업데이트 (#257)

기술 개선

  • Windows 빌드에서 Unix 전용 항목에 대한 dead_code 경고 수정

v0.27.0 - 2025-12-29

추가됨

  • llama.cpp 도구 호출 자동 감지 - llama.cpp 백엔드의 도구 호출 지원 자동 감지 (#260)
    • 모델 검색 시 /props 엔드포인트를 쿼리하여 chat_template 분석
    • 도구 관련 키워드 감지 (tool, tools, tool_call, function 등)
    • 감지 시 function_calling 기능 자동 활성화
    • /props 엔드포인트를 사용할 수 없는 경우 우아한 폴백
    • HTTP 및 Unix 소켓 백엔드 모두에서 작동
  • 완전한 Unix 소켓 지원 - 모델 검색 및 스트리밍을 위한 완전한 Unix 소켓 지원 (#248, #252, #253, #254, #256)
    • Unix 소켓 백엔드의 SSE/스트리밍 지원으로 로컬 소켓을 통한 실시간 응답 가능
    • Unix 소켓 연결을 위한 백엔드 타입 자동 감지
    • Unix 소켓을 통한 vLLM 모델 검색 지원
    • Unix 소켓을 통한 llama.cpp 모델 검색 지원
    • 모델 페처가 Unix 소켓 백엔드를 완전히 지원
  • 도구 호출 변환 (Tool Call Transformation) - 모든 백엔드에서 OpenAI 도구 호출 변환 구현 (#244, #245, #246)
    • Anthropic, Gemini, llama.cpp 백엔드에 대한 도구 정의 변환
    • auto, none, required, 특정 함수 선택을 지원하는 도구 선택 변환
    • 프로바이더 간 통합 응답 형식을 위한 도구 호출 응답 변환
  • 멀티턴 도구 대화 지원 - 멀티턴 대화에서 도구 호출을 위한 메시지 변환 (#241)
    • 도구 결과 메시지 (role: "tool")를 백엔드 네이티브 형식으로 변환
    • Anthropic: user 역할로 tool_result 콘텐츠 블록과 함께 변환
    • Gemini: function 역할로 functionResponse 파트와 함께 변환
    • Anthropic용으로 연속 도구 결과 결합 (병렬 도구 호출)
    • Gemini 변환을 위한 자동 함수 이름 조회
    • 오류 응답을 위한 is_error 표시자 보존

v0.26.0 - 2025-12-27

추가됨

  • 도구 선택 변환 (Tool Choice Transformation) - 백엔드 간 tool_choice 파라미터 자동 변환 (#239)
    • auto, none, required, 특정 함수 선택 지원
    • Anthropic: {"type": "auto|any|tool"} 형식으로 변환, "none"은 도구 제거로 처리
    • Gemini: tool_config.function_calling_config 구조로 변환
    • llama.cpp: 병렬 함수 호출을 위해 parallel_tool_calls 파라미터 유지
    • 크로스 프로바이더 도구 호출을 위해 모델 폴백 시스템과 통합
  • 단일 모델 조회 엔드포인트 - 가용성 상태가 포함된 단일 모델 조회를 위한 GET /v1/models/{model} 엔드포인트 추가 (#236)
    • 실시간 가용성을 나타내는 추가 available 필드와 함께 모델 정보 반환
    • available: true: 최소 하나의 건강한 백엔드가 모델을 제공할 때
    • available: false: 모델은 존재하지만 이를 제공하는 모든 백엔드가 비정상일 때
    • 모델이 어느 백엔드에도 존재하지 않으면 404 반환
    • 특정 모델 조회를 타겟팅하여 전체 모델 집계를 피함으로써 성능 최적화

v0.25.0 - 2025-12-26

추가됨

  • CORS (Cross-Origin Resource Sharing) 지원 - 웹 애플리케이션에 라우터를 임베드하기 위한 설정 가능한 CORS 미들웨어 (#234)
    • Tauri 데스크톱 앱, Electron 앱, 웹 프론트엔드 지원
    • 와일드카드 오리진 및 포트 패턴 (예: http://localhost:*)
    • 커스텀 스킴 지원 (예: tauri://localhost)
    • 설정 가능한 메서드, 헤더, credentials
    • 설정 가능한 max-age의 프리플라이트 캐시
  • Unix 도메인 소켓 백엔드 지원 - Unix 소켓을 통한 안전한 로컬 LLM 통신 (#232)
    • 로컬 백엔드를 위한 unix:///path/to/socket URL 스킴 사용
    • 파일 시스템 권한을 통한 더 나은 보안 (TCP 포트 노출 없음)
    • localhost TCP 대비 낮은 지연 시간 (~30% 개선)
    • 여러 LLM 서버 실행 시 포트 충돌 없음
    • 플랫폼 지원: Linux 및 macOS (Windows는 향후 릴리스 예정)

v0.24.0 - 2025-12-26

추가됨

  • 로컬 LLM 추론용 llama.cpp 백엔드 지원 (#230)
  • 백엔드 설정 없이 라우터 시작을 허용 (#226)

변경됨

  • 설정의 백엔드 추가/제거에 핫 리로드 활성화 (#229)

v0.23.1 - 2025-12-25

CI/CD

  • Windows 빌드 지원 - 릴리스 워크플로우에 Windows x86_64 빌드 타겟 추가 (#224)
    • 릴리스 파이프라인에서 네이티브 Windows 빌드 활성화
    • mingw-w64를 사용한 Linux에서의 크로스 컴파일

v0.23.0 - 2025-12-23

추가됨

  • GLM 4.7 모델 지원 - 사고 기능을 포함한 Zhipu AI의 GLM 4.7 모델 지원 추가 (#222)
    • 전체 사양이 포함된 model-metadata.yaml의 모델 메타데이터 (355B MoE, 32B 활성 파라미터)
    • 사고(thinking) 파라미터 지원: enable_thinking (불린) 및 thinking_budget (1-204,800 토큰)
    • 최대 131K 토큰 출력이 가능한 200K 컨텍스트 윈도우
    • config.yaml.example에 Z.AI 백엔드 설정 예제 추가
    • SiliconFlow 대체 백엔드 설정
    • 모델 메타데이터에 대한 종합적인 통합 테스트
    • 가격: 입력 토큰 $0.60/1M, 출력 토큰 $2.20/1M
  • 사고 패턴 메타데이터 - 암시적 시작 태그를 사용하는 모델에 대한 사고 패턴 메타데이터 추가 (#218)
    • 암시적 사고 시작 태그를 사용하는 모델 지원
    • 사고 콘텐츠 추출을 위한 패턴 기반 감지
  • GCP 서비스 계정 인증 - Gemini 백엔드에 GCP 서비스 계정 인증 지원 추가 (#208)
    • JSON 키 파일 인증 지원
    • 환경 변수 기반 인증
    • 자동 토큰 갱신 및 관리
  • 분산 추적 - 상관관계 ID 전파를 통한 분산 추적 추가 (#207)
    • traceparent 헤더를 사용한 W3C Trace Context 지원
    • 설정 가능한 trace ID, request ID, correlation ID 헤더
    • 모든 재시도 시도에 걸친 Trace ID 전파
    • 헤더에서 가져온 trace ID에 대한 보안 검증
  • 새 모델 메타데이터 - NVIDIA Nemotron 3 Nano, Qwen Image Layered, Kakao Kanana-2 모델 메타데이터 추가 (#202)
  • ASCII 다이어그램 교체 - MkDocs용 ASCII 다이어그램을 이미지로 교체하는 시스템 추가 (#200)
    • MkDocs 빌드 시 ASCII 다이어그램을 SVG 이미지로 자동 교체
    • 원시 Markdown에서 ASCII 아트 가시성 유지

변경됨

  • CI 최적화 - 비코드 파일만 변경된 경우 Rust 테스트 건너뛰기 (#204)
    • 문서 전용 변경에 대한 더 빠른 CI
    • 테스트 실행을 위한 경로 기반 필터링

수정됨

  • 캐시 스탬피드 방지 - singleflight, stale-while-revalidate, 백그라운드 갱신으로 캐시 스탬피드 방지 (#220)
    • Singleflight 패턴으로 모델 캐시 만료 시 썬더링 허드 방지
    • Stale-while-revalidate로 백그라운드에서 갱신하면서 즉시 캐시된 데이터 반환
    • 백그라운드 갱신으로 만료 전 캐시를 사전에 업데이트
  • 전역 프롬프트 핫 리로드 - 핫 리로드를 통한 global_prompts 변경 적용 (#219)
    • 전역 프롬프트 설정 변경이 이제 재시작 없이 적용
  • 모델 캐시 무효화 - 백엔드 설정 변경 시 모델 캐시 무효화 (#206)
    • 백엔드 설정 변경이 이제 모델 캐시 갱신을 적절히 트리거
  • 문서 개선 - 인라인 SVG 및 반응형 크기 조정으로 다이어그램 렌더링 개선
  • 번역 오타 - 문서의 번역 오타 수정
  • Docker CI 수정 - Docker 매니페스트 생성에서 멀티라인 태그 처리
  • 프라이빗 저장소 접근 - CI에서 프라이빗 저장소 에셋 다운로드에 gh CLI 사용
  • GitHub 토큰 인증 - 프라이빗 저장소 접근을 위한 GitHub 토큰 인증 추가
  • 문서 워크플로우 - 환경 보호 오류를 방지하기 위해 문서 워크플로우에서 릴리스 트리거 제거

CI/CD

  • actions/github-script를 7에서 8로 업데이트 (#210)
  • apple-actions/import-codesign-certs를 3에서 6으로 업데이트 (#212)
  • actions/cache를 4에서 5로 업데이트 (#211)
  • actions/checkout을 4에서 6으로 업데이트 (#209)

v0.22.0 - 2025-12-19

추가됨

  • 사전 빌드 바이너리 Docker 지원 - GitHub Releases에서 사전 빌드된 바이너리를 다운로드하는 Dockerfile 및 Dockerfile.alpine 추가 (#189)
    • 일반 사용을 위한 Debian Bookworm 기반 이미지 (~50MB)
    • 최소 배포를 위한 Alpine 3.20 기반 이미지 (~10MB)
    • TARGETARCH를 사용한 멀티 아키텍처 지원 (linux/amd64, linux/arm64)
    • 릴리스 버전 선택을 위한 VERSION 빌드 인자
    • 보안을 위한 비루트 사용자 실행
    • 이미지 메타데이터를 위한 OCI 라벨
  • 컨테이너 헬스 체크 CLI - 컨테이너 오케스트레이션을 위한 --health-check CLI 인자 구현 (#189)
    • 서버가 정상이면 종료 코드 0, 비정상이면 1 반환
    • 사용자 정의 헬스 엔드포인트를 위한 선택적 --health-check-url
    • 적절한 IPv6 주소 처리
    • 기본 5초 타임아웃
  • Docker Compose 빠른 시작 - 간편한 배포를 위한 docker-compose.yml 추가 (#189)
    • 설정을 위한 볼륨 마운트
    • 환경 변수 지원 (RUST_LOG)
    • 리소스 제한 및 헬스 체크
  • 자동화된 Docker 이미지 퍼블리싱 - 릴리스 워크플로우에 Docker 빌드 및 ghcr.io 푸시 추가 (#189)
    • 바이너리 릴리스 후 Debian 및 Alpine 이미지 빌드
    • 멀티 플랫폼 지원 (linux/amd64, linux/arm64)
    • semver로 자동 태깅 (VERSION, MAJOR.MINOR, latest)
    • Alpine 이미지는 -alpine 접미사로 태그
    • 더 빠른 빌드를 위한 GitHub Actions 캐시
  • MkDocs 문서 웹사이트 - Material 테마로 종합적인 문서 사이트 구축 (#183)
    • 시작하기, 기능, 운영, 개발 섹션이 있는 전체 네비게이션 구조
    • GitHub Pages 자동 배포를 위한 GitHub Actions 워크플로우
    • 사용자 정의 스타일시트 및 테마 구성
  • 한국어 문서 번역 - 모든 문서의 완전한 한국어 현지화 (#190)
    • 20개 문서 파일 모두 한국어로 번역
    • 네비게이션에 언어 전환기 (영어/한국어)
    • GitHub Actions 워크플로우에서 다국어 빌드
  • 의존성 보안 감사 - 취약점 스캔을 위한 cargo-deny 추가 (#192)
    • CI 워크플로우에서 보안 권고 확인
    • 라이선스 준수 검증
    • 의존성 소스 검증
  • Dependabot 통합 - Cargo 및 GitHub Actions 자동 의존성 업데이트 (#192)
  • 보안 정책 - 취약점 보고 프로세스를 포함한 종합적인 SECURITY.md 추가 (#191)

변경됨

  • 고아 아키텍처 문서를 MkDocs 사이트에 통합 (#186)
  • URL 친화적 파일명을 위해 문서 파일명을 소문자 케밥케이스로 변경 (#186)
  • 다양한 GitHub Actions를 최신 버전으로 업데이트 (checkout@v6, setup-python@v6, upload-artifact@v6 등)

수정됨

  • 헬스 체크 응답 검증 로직 버그 (연산자 우선순위 문제)
  • 설정 오류를 조용히 숨기던 주소 파싱 폴백
  • 헬스 체크에서 IPv6 주소 형식 지정 (이제 브라켓 표기법을 올바르게 사용)

보안

  • reqwest 0.11→0.12, prometheus 0.13→0.14, validator 0.18→0.20 업데이트
  • 더 나은 유지보수를 위해 dotenv를 dotenvy로 교체
  • 빌드 컨텍스트에서 민감한 파일 제외를 위한 .dockerignore 추가

v0.21.0 - 2025-12-19

추가됨

  • Gemini 3 Flash Preview 모델 - gemini-3-flash-preview 모델 지원 추가 (#168)
  • 백엔드 오류 전달 - 4xx 응답에 대해 백엔드의 상세 오류 메시지 전달 (#177)
    • OpenAI, Anthropic, Gemini 백엔드의 원본 오류 메시지 파싱 및 전달
    • 가능한 경우 param 필드 보존 (잘못된 파라미터 오류에 유용)
    • 백엔드 응답 파싱 불가 시 일반 오류 메시지로 폴백
    • OpenAI 호환 오류 형식 유지
    • 모든 백엔드 형식에 대한 오류 파싱 단위 테스트 포함
  • API 엔드포인트 기본 인증 모드 - API 엔드포인트에 대한 설정 가능한 인증 적용 (#173)
    • api_keys 설정에 새 mode 필드: permissive (기본값) 또는 blocking
    • permissive 모드: API 키 없는 요청 허용 (하위 호환성 유지)
    • blocking 모드: 인증된 요청만 처리, 미인증 요청은 401 수신
    • 보호 엔드포인트: /v1/chat/completions, /v1/completions, /v1/responses, /v1/images/*, /v1/models
    • 헬스 엔드포인트 (/health, /healthz)는 항상 인증 없이 접근 가능
    • 인증 모드 변경에 대한 핫 리로드 지원
    • 두 모드에 대한 포괄적인 통합 테스트
    • API.md, configuration.md, manpage 문서 업데이트

수정됨

  • UTF-8 멀티바이트 문자 손상 - 스트리밍 응답에서 UTF-8 멀티바이트 문자 손상 처리 (#179)
  • GPT Image response_format - GPT Image 모델에서 response_format 파라미터 제거 (#176)
  • 자동 검색 검증 - Anthropic을 제외한 모든 백엔드에 대해 자동 검색 허용 (#172)

변경됨

  • architecture.md 업데이트 및 문서 오류 수정 (#167, #169)
  • AGENTS.md 추가 및 CLAUDE.md 연결

v0.20.0 - 2025-12-18

추가됨

  • Gemini 이미지 변형 지원 - Gemini (nano-banana) 모델에 대한 이미지 변형 지원 추가 (#165)
  • Gemini 이미지 편집 지원 - Gemini (nano-banana) 모델에 대한 제한적 이미지 편집 지원 구현 (#164)
  • 향상된 이미지 생성 - 스트리밍 및 GPT Image 기능으로 /v1/images/generations 향상 (#161)
  • GPT Image 1.5 모델 - gpt-image-1.5 모델 지원 추가 (#159)
  • 이미지 변형 엔드포인트 - 이미지 변형을 위한 /v1/images/variations 엔드포인트 구현 (#155)
  • 이미지 편집 엔드포인트 - 이미지 편집(인페인팅)을 위한 /v1/images/edits 엔드포인트 구현 (#156)
    • 완전한 OpenAI Images Edit API 호환성
    • GPT Image 모델 지원: gpt-image-1, gpt-image-1-mini, gpt-image-1.5 (권장)
    • dall-e-2 모델 레거시 지원
    • 공유 유틸리티를 사용한 multipart form-data 파싱
    • PNG 이미지 검증 (형식, 크기, 정사각형 치수)
    • 선택적 마스크 검증 (원본 이미지와 치수 일치)
  • 공유 이미지 유틸리티 - 이미지 편집/변형 엔드포인트를 위한 공유 유틸리티 구현 (#154)
  • 외부 프롬프트 파일 - 외부 Markdown 파일에서 시스템 프롬프트 로딩 지원 (#146)
    • BackendPromptConfigModelPromptConfig에 새 prompt_file 필드
    • GlobalPromptConfig에 새 default_fileprompts_dir 필드
    • 경로 순회 공격 방지를 위한 안전한 경로 검증
    • 프롬프트 파일 관리를 위한 REST API 엔드포인트
    • 크기 제한이 있는 파일 캐싱 (최대 100개 항목, 총 50MB)
    • 프롬프트 파일에 대한 핫 리로드 지원
  • Solar Open 100B 모델 - Solar Open 100B 모델 메타데이터 추가
  • 자동 모델 검색 - 모델이 명시적으로 설정되지 않은 경우 백엔드가 /v1/models API에서 자동으로 사용 가능한 모델 검색 (#142)
    • OpenAI, Gemini, vLLM 백엔드가 자동 검색 지원
    • Ollama 백엔드는 vLLM의 검색 메커니즘 사용 (OpenAI 호환 API)
    • 10초 타임아웃으로 시작 차단 방지
    • 검색 실패 시 하드코딩된 기본값으로 폴백

변경됨

  • BackendFactory::create_backend_from_typed_config()가 비동기 모델 검색을 지원하기 위해 async로 변경
  • OpenAI, Gemini, vLLM의 백엔드 from_config() 메서드가 async로 변경

보안

  • API 키 수정 - 자격 증명 노출 방지를 위한 API 키 수정 구현 (#150)

성능

  • 바이너리 크기 최적화 - 릴리스 바이너리 크기를 20MB에서 6MB로 최적화 (70% 감소) (#144)

리팩토링

  • 이슈 #147의 우선순위 2를 위한 대용량 파일 분할
  • 각 파일을 500줄 미만으로 유지하기 위한 대용량 파일 분할 (#148)

v0.19.0 - 2025-12-13

추가됨

  • 런타임 설정 관리 API - 런타임에 설정을 보고 수정하기 위한 포괄적인 REST API (#139)
    • 설정 쿼리 API:
      • GET /admin/config/full - 민감 정보가 마스킹된 전체 설정 조회
      • GET /admin/config/sections - 15개 설정 섹션 전체 목록
      • GET /admin/config/{section} - 특정 섹션 설정 조회
      • GET /admin/config/schema - 클라이언트 측 검증을 위한 JSON Schema
    • 설정 수정 API:
      • PUT /admin/config/{section} - 섹션 설정 교체
      • PATCH /admin/config/{section} - 부분 업데이트 (JSON merge patch)
      • POST /admin/config/validate - 적용 전 설정 검증
      • POST /admin/config/apply - 핫 리로드로 설정 적용
    • 설정 저장/복원 API:
      • POST /admin/config/export - 설정 내보내기 (YAML/JSON/TOML)
      • POST /admin/config/import - 설정 가져오기 및 적용
      • GET /admin/config/history - 설정 변경 이력 조회
      • POST /admin/config/rollback/{version} - 이전 버전으로 롤백
    • 백엔드 관리 API:
      • POST /admin/backends - 새 백엔드 추가
      • GET /admin/backends/{name} - 백엔드 설정 조회
      • PUT /admin/backends/{name} - 백엔드 설정 업데이트
      • DELETE /admin/backends/{name} - 백엔드 제거
      • PUT /admin/backends/{name}/weight - 백엔드 가중치 업데이트
      • PUT /admin/backends/{name}/models - 백엔드 모델 목록 업데이트
    • API 키, 비밀번호, 토큰에 대한 민감 정보 마스킹
    • 모든 설정 섹션에 대한 JSON Schema 생성
    • 설정 이력 추적 (최대 100개 항목, 설정 가능)
    • 크기 기반 퇴거를 통한 메모리 효율적 이력 저장 (10MB 제한)
    • 스레드 안전성을 위한 AtomicU64 사용 원자적 버전 카운터
    • 오류 코드가 포함된 구조화된 오류 응답
  • Admin REST API 문서 - 포괄적인 개발자 가이드 (docs/admin-api.md)
    • 요청/응답 예제가 포함된 완전한 API 레퍼런스
    • Python, JavaScript/TypeScript, Go용 클라이언트 SDK 예제
    • 모범 사례 및 보안 고려사항
  • 통합 테스트 - 설정 관리 API 엔드포인트에 대한 33개 통합 테스트

수정됨

  • 심각: 설정 변경이 이제 실행 중인 시스템에 실제로 적용됨
  • 심각: JSON 문자열 저장 및 크기 기반 퇴거로 메모리 증가 제어
  • 높음: 입력 검증 추가 (1MB 콘텐츠 제한, 32레벨 중첩 깊이)
  • 높음: 민감 내보내기에 권한 상승 및 감사 로깅 필요
  • 높음: 포괄적인 민감 필드 감지 (30개 이상 패턴)
  • 중간: 검증 함수가 이제 실제 검증 수행
  • 중간: 버전 카운터에 AtomicU64로 경쟁 조건 수정
  • 중간: 허용된 백엔드 이름 문자에서 콜론 제거
  • 중간: 오류 코드가 포함된 구조화된 오류 응답
  • 중간: 초기화 플래그로 중복 이력 항목 방지
  • 낮음: 더 나은 성능을 위해 불필요한 클론 제거
  • 낮음: AdminConfig를 통해 제한 설정 가능
  • 낮음: 중복 검증 로직 리팩토링
  • 낮음: 엣지 케이스에 대한 테스트 커버리지 개선

변경됨

  • 모든 가이드에서 설정 관리 API 문서 향상
  • 새 관리 엔드포인트로 manpage 업데이트
  • 포괄적인 설정 관리 API 섹션으로 API.md 업데이트

v0.18.0 - 2025-12-13

추가됨

  • API 키별 속도 제한 - API 키별 속도 제한 구현 (#137)
    • 각 API 키에 대한 개별 속도 제한
    • 키당 분당 요청 수 설정 가능
  • API 키 관리 시스템 - 포괄적인 API 키 관리 및 설정 시스템
    • 다중 키 소스: 설정 파일, 외부 파일, 환경 변수
    • 키 속성: 스코프, 속도 제한, 만료, 활성화 상태
    • 키 설정 변경에 대한 핫 리로드 지원
  • Files API 인증 - Files API에 대한 인증 및 권한 부여 구현 (#131)
    • 파일 작업에 대한 API 키 인증
    • 파일 소유권 적용
    • 모든 파일에 대한 관리자 접근 제어
  • 런타임 설정 핫 리로드 - 런타임 설정 업데이트를 위한 완전한 핫 리로드 기능 (#130)
    • 자동 설정 파일 감시
    • 분류된 업데이트: 즉시, 점진적, 재시작 필요

변경됨

  • 모듈식 구조로 대규모 리팩토링
    • CLI 및 앱 유틸리티를 모듈식 구조로 추출 (#132)
    • converter.rs를 모듈식 구조로 분할 (#132)
    • 대용량 소스 파일을 모듈식 구조로 분할
    • find_gemini_backend 함수 로직 통합
  • 리팩토링된 모듈 구조를 반영하도록 architecture.md 업데이트

수정됨

  • admin/metrics/files 엔드포인트에 ConnectInfo 확장 추가
  • API 키 관리의 보안 취약점 해결
  • API 키 관리의 코드 품질 문제 해결

문서

  • API 키 관리 문서 추가
  • 포괄적인 API 키 관리 테스트 추가

v0.17.0 - 2025-12-12

추가됨

  • Anthropic 백엔드 파일 콘텐츠 변환 - 라우터에 업로드된 파일을 이제 Anthropic 백엔드와 함께 사용 가능 (#126)
    • 파일 콘텐츠를 Anthropic 메시지 형식으로 자동 변환
    • base64 인코딩을 사용한 텍스트 및 문서 파일 지원
    • 파일 해결 미들웨어와 원활한 통합
  • Gemini 백엔드 파일 콘텐츠 변환 - 라우터에 업로드된 파일을 이제 Gemini 백엔드와 함께 사용 가능 (#127)
    • 파일 콘텐츠를 Gemini API 형식으로 자동 변환
    • 적절한 MIME 타입 처리를 통한 인라인 데이터 지원
    • 크로스 프로바이더 파일 지원으로 한 번 업로드한 파일을 모든 백엔드에서 사용 가능

수정됨

  • 스트리밍 파일 업로드 - 메모리 소진 방지를 위한 스트리밍 파일 업로드 구현 (#128)
    • 대용량 파일 업로드가 더 이상 전체 파일을 메모리에 로드하지 않음
    • 효율적인 메모리 사용을 위한 스트리밍 처리
    • 대용량 파일 업로드 시 OOM 오류 방지

변경됨

  • 없음

v0.16.0 - 2025-12-12

추가됨

  • OpenAI 호환 Files API - OpenAI Files API 엔드포인트 전체 구현 (#111)
    • multipart/form-data 지원 파일 업로드
    • 파일 목록, 조회, 삭제
    • 파일 콘텐츠 다운로드
    • 용도 지원: fine-tune, batch, assistants, user_data
  • 파일 해결 미들웨어 - 채팅 완료를 위한 자동 파일 콘텐츠 주입 (#120)
    • 파일 ID로 채팅 메시지에서 업로드된 파일 참조
    • 채팅 컨텍스트에 자동 콘텐츠 주입
  • 영속적 메타데이터 스토리지 - 서버 재시작 후에도 파일 메타데이터 유지 (#125)
    • 데이터 파일과 함께 저장되는 사이드카 JSON 파일 (.meta.json)
    • 파일에서 메타데이터 재빌드를 통한 시작 시 자동 복구
    • 고아 파일 감지 및 선택적 정리
  • OpenAI 백엔드 파일 처리 - 로컬에 업로드된 파일이 필요시 OpenAI로 전달됨 (#121, #122)
  • GPT-5.2 모델 지원 - OpenAI 백엔드에 GPT-5.2 모델 메타데이터 추가 (#124)
  • 서킷 브레이커 패턴 - 서킷 브레이커를 통한 자동 백엔드 장애 조치 (#93)
    • 상태: Closed → Open → Half-Open → Closed 사이클
    • 설정 가능한 실패 임계값 및 복구 타임아웃
    • 백엔드별 서킷 브레이커 인스턴스
    • 서킷 브레이커 상태 및 제어를 위한 관리자 엔드포인트
  • 관리자 엔드포인트 인증 - 인증 및 감사 로깅으로 관리자 엔드포인트 보안
  • 설정 가능한 폴백 모델 - 모델 사용 불가 시나리오에 대한 자동 모델 폴백 (#50)
    • 기본 모델에 대한 폴백 체인 정의 (예: gpt-4o → gpt-4-turbo → gpt-3.5-turbo)
    • 크로스 프로바이더 폴백 지원 (예: OpenAI → Anthropic)
    • 프로바이더 간 자동 파라미터 변환
    • 계층화된 장애 조치 보호를 위한 서킷 브레이커와 통합
    • 설정 가능한 트리거 조건 (오류 코드, 타임아웃, 연결 오류, 서킷 브레이커 오픈)
    • 폴백 사용 시 응답 헤더 표시 (X-Fallback-Used, X-Original-Model, X-Fallback-Model)
    • 폴백 모니터링을 위한 Prometheus 메트릭
  • Pre-commit Hook - 커밋 전 자동 코드 포맷팅 및 린팅

수정됨

  • 폴백 체인 검증 - 체인 검증을 Validate derive에 통합
  • 폴백 성능 - 폴백 체인 순회를 위한 인덱스 기반 조회 사용
  • 락 경합 - 스냅샷 패턴으로 FallbackService의 락 경합 감소
  • 보안 - 폴백 오류 헤더 및 메트릭 레이블 살균
  • 서킷 브레이커 보안 - 관리자 엔드포인트에 백엔드 이름 검증 추가
  • 스레드 안전성 - half-open 요청 제한을 위한 스레드 안전 CAS 루프 사용

변경됨

  • 문서 업데이트 - 폴백 설정, 서킷 브레이커, Files API에 대한 포괄적인 문서
  • 코드 품질 - clippy 경고 수정 및 코드 포맷팅
  • Pre-commit Hook 위치 - pre-commit hook을 .githooks 디렉토리로 이동

v0.15.0 - 2025-12-05

추가됨

  • Nano Banana API 지원 - OpenAI 호환 인터페이스로 Gemini 이미지 생성 API 지원 추가 (#102)
    • nano-banana 및 nano-banana-pro 모델 지원
    • OpenAI Images API와 Gemini Imagen API 간 자동 형식 변환
  • /v1/models 엔드포인트 분리 - 표준 경량 응답 vs 확장 메타데이터 응답 (#101)
    • /v1/models는 더 나은 성능을 위해 경량 응답 반환
    • /v1/models?extended=true는 상세 모델 정보를 위한 전체 메타데이터 반환

변경됨

  • StreamService 추출 - 모듈식 아키텍처를 위해 스트리밍 핸들러 로직을 전용 StreamService로 추출 (#106)
  • 재시도 로직 중복 제거 - proxy.rs에서 재시도 로직 코드 통합 (#103)

수정됨

  • 적절한 오류 전파 - HttpClientFactory에서 .expect() 패닉을 적절한 오류 전파로 교체 (#104)

성능

  • LRU 캐시 최적화 - 캐시 조회에 쓰기 락 대신 읽기 락 사용 (#105)

v0.14.2 - 2025-12-05

추가됨

  • 토큰 사용량 로깅 - 요청 완료 시 입력/출력 토큰 수 로깅 (#92)
  • 리포트 제외 목록 - 리포트에 대한 제외 목록 설정 추가

변경됨

  • 없음

수정됨

  • 없음

v0.14.1 - 2025-12-05

추가됨

  • TTFB 벤치마크 타겟 - Makefile에 TTFB 벤치마크 타겟 추가
  • 연결 사전 준비 - Anthropic, Gemini, OpenAI 백엔드에 대한 연결 사전 준비 추가

수정됨

  • Anthropic 백엔드 TTFT - 연결 풀링 및 HTTP/2로 Anthropic 백엔드 TTFT 최적화 (#90)
  • Gemini 백엔드 TTFT - 연결 풀링 및 HTTP/2로 Gemini 백엔드 TTFT 최적화 (#88)
  • 모델 메타데이터 별칭 매칭 - 모델 메타데이터 조회에서 별칭에 기본 이름 폴백 매칭 적용 (#84)

변경됨

  • 공유 HTTP 클라이언트 - HealthChecker와 요청 핸들러 간 HTTP 클라이언트 공유
  • 아키텍처 및 성능 문서 업데이트

v0.14.0 - 2025-12-04

추가됨

  • 전역 시스템 프롬프트 주입 - 라우터 전역 시스템 프롬프트 주입 추가 (#82)

수정됨

  • GitHub Actions - 더 이상 사용되지 않는 actions-rs/toolchain을 dtolnay/rust-toolchain으로 교체
  • macOS ARM64 빌드 - macOS ARM64 ring 빌드를 위한 RUSTFLAGS 추가
  • musl 빌드 - musl 크로스 컴파일 지원을 위해 rustls-tls로 전환

변경됨

  • GitHub Action runner 업데이트

v0.13.0 - 2025-12-04

추가됨

  • OpenAI Responses API (/v1/responses) - OpenAI Responses API 전체 구현 (#49)
    • 자동 만료가 있는 세션 기반 응답 관리
    • 만료된 세션에 대한 백그라운드 정리 작업
    • Responses API와 Chat Completions 간 요청/응답 형식 변환기
  • API 키용 SecretString - 모든 백엔드에서 SecretString을 사용한 안전한 API 키 저장 (#76)
  • 모델 메타데이터 오버라이드 - model-metadata.yaml을 통한 /v1/models 응답 필드 오버라이드 허용 (#75)

수정됨

  • 진정한 SSE 스트리밍 - /v1/responses API에 대한 적절한 Server-Sent Events 스트리밍 구현

변경됨

  • SseParser 즉시 모드 - 즉시 파싱 모드로 첫 응답 지연 감소
  • 문자열 할당 최적화 - 할당 감소로 성능 개선
  • 오류 처리 표준화 - 코드베이스 전체에 일관된 오류 처리 패턴

보안

  • 세션 접근 제어 - 세션 관리에 적절한 접근 제어 추가
  • 입력 검증 - Responses API에 대한 포괄적인 입력 검증

v0.12.0 - 2025-12-04

추가됨

  • SSRF 방지 모듈 - 포괄적인 SSRF 방지를 위한 새 UrlValidator 모듈 (#66)
  • 중앙화된 HTTP 클라이언트 팩토리 - 백엔드 간 일관된 HTTP 클라이언트 생성을 위한 HttpClientFactory (#67)

수정됨

  • 일관된 해시 알고리즘 - 적절한 라우팅을 위해 이진 검색에서 정확한 해시 일치 처리 (#72)
  • 패닉을 Option 반환으로 교체 - 패닉을 Option 반환으로 교체하여 신뢰성 향상 (#71)
  • 하드코딩된 인증 요구사항 제거 - /v1/models 엔드포인트에 더 이상 하드코딩된 인증 필요 없음
  • GitHub Actions - Projects V2 API 접근을 위해 GitHub App 토큰 사용

변경됨

  • OpenAI 모델 메타데이터 재구성 - 더 나은 유지보수성을 위해 모델 메타데이터를 패밀리별로 구성 (#74)
  • AnthropicStreamTransformer 추출 - Anthropic 스트림 변환을 위한 전용 모듈 (#73)
  • Backends 모듈 분할 - 더 깔끔한 아키텍처를 위해 backends mod.rs를 별도 모듈로 분할 (#69)
  • 임베디드 테스트 추출 - 더 나은 구성을 위해 테스트를 별도 파일로 이동 (#68)
  • RequestExecutor 추출 - 요청 실행을 위한 공유 공통 모듈 (#65)
  • HeaderBuilder 추출 - 인증 전략을 전용 모듈로 이동 (#64)
  • AtomicStatistics 추출 - 원자적 통계를 위한 공유 공통 모듈

기술 개선

  • 모듈식 아키텍처로 코드 구성 개선
  • 더 나은 관측성을 위한 통계 집계 구현
  • SSRF 방지 기능으로 보안 강화

v0.11.0 - 2025-12-03

추가됨

  • 네이티브 Anthropic Claude API 백엔드 (type: anthropic) - OpenAI 호환 엔드포인트 (#33)
    • CONTINUUM_ANTHROPIC_API_KEY 환경 변수에서 자동 API 키 로드
    • Claude 사고 모델을 위한 확장 사고 블록 지원
    • OpenAI에서 Claude로 reasoning 파라미터 변환 (reasoning_effort)
    • 플랫 reasoning_effort 파라미터 지원
  • Claude 4, 4.1, 4.5 모델 메타데이터 문서

수정됨

  • Anthropic/Gemini 백엔드에 대한 헬스 체크 및 모델 가져오기 개선
  • 압축 문제 방지를 위해 스트리밍 요청에 Accept-Encoding: identity 헤더 추가
  • 적절한 Accept-Encoding 처리를 위해 proxy.rs의 make_backend_request 수정

변경됨

  • 리팩토링: 코드 포맷팅 적용 및 clippy 경고 수정
  • 리팩토링: Accept-Encoding 헤더 대신 reqwest no_gzip/no_brotli/no_deflate 사용

v0.10.0 - 2025-12-03

추가됨

  • 네이티브 Google Gemini API 백엔드 (type: gemini) - OpenAI 호환 엔드포인트 (#32)
    • CONTINUUM_GEMINI_API_KEY 환경 변수에서 자동 API 키 로드
    • 사고 모델 (gemini-2.5-pro, gemini-3-pro)에 대한 300초 확장 스트리밍 타임아웃
    • 응답 잘림 방지를 위한 사고 모델의 자동 max_tokens 조정
    • reasoning_effort 파라미터 지원
  • 네이티브 OpenAI API 백엔드 (type: openai) - 내장 설정
    • CONTINUUM_OPENAI_API_KEY 환경 변수에서 자동 API 키 로드
    • /v1/models 응답에 내장 OpenAI 모델 메타데이터
  • OpenAI Images API 지원 (/v1/images/generations) - DALL-E 및 gpt-image-1 모델 (#35)
    • 설정 가능한 이미지 생성 타임아웃 (timeouts.request.image_generation)
    • 이미지 생성 파라미터에 대한 포괄적인 입력 검증
    • 이미지 생성 API에 대한 응답 형식 검증
  • OpenAI 및 API 키 백엔드에 대한 인증된 헬스 체크
  • 스트리밍 요청에 API 키 인증
  • 설정된 모델만 표시하도록 /v1/models 필터링
  • -c/--config로 명시적으로 지정된 경우 모든 설정 파일 경로 허용
  • .env.example 및 타입이 지정된 백엔드 설정 예제
  • GLM 4.6, Kimi K2, DeepSeek, GPT, Qwen3 시리즈에 대한 포괄적인 모델 메타데이터

수정됨

  • 사고 모델 (gemini-2.5-pro, gemini-3-pro)의 스트리밍 응답 잘림
  • Gemini 백엔드의 모델 ID 정규화 및 스트리밍 호환성
  • 최신 OpenAI 모델에 대해 max_tokensmax_completion_tokens로 변환
  • 모든 API 엔드포인트에 대한 올바른 URL 구성
  • 보안: 디버그 로그에서 민감 데이터 제거
  • 보안: DoS 공격 방지를 위한 요청 본문 크기 제한 추가

변경됨

  • 리팩토링: RequestType enum으로 요청 재시도 로직 통합
  • 리팩토링: 락 프리 통계 및 슬라이스 반환으로 Gemini 백엔드 성능 개선
  • Gemini 백엔드 문서 및 max_tokens 동작 문서 추가
  • 이미지 생성 API 문서 추가
  • model-metadata.yaml의 기능 명명 표준화

v0.9.0 - 2025-12-02

추가됨

  • 네이티브 Google Gemini API 백엔드 (type: gemini) - OpenAI 호환 엔드포인트 (#32)
    • CONTINUUM_GEMINI_API_KEY 환경 변수에서 자동 API 키 로드
    • 사고 모델 (gemini-2.5-pro, gemini-3-pro)에 대한 300초 확장 스트리밍 타임아웃
    • 응답 잘림 방지를 위한 사고 모델의 자동 max_tokens 조정
    • reasoning_effort 파라미터 지원
  • DALL-E 및 gpt-image-1 모델을 위한 OpenAI Images API 지원 (/v1/images/generations) (#35)
  • 설정 가능한 이미지 생성 타임아웃 (timeouts.request.image_generation)
  • GPT-5 패밀리, o-시리즈, 오디오/음성, 비디오 (Sora), 임베딩 모델을 포함한 OpenAI 모델의 포괄적인 메타데이터
  • 토큰 버킷 알고리즘을 사용한 향상된 속도 제한 (#11)
  • 포괄적인 Prometheus 메트릭 및 모니터링 (#10)
  • 설정 파일 마이그레이션 및 자동 수정 CLI 유틸리티 (#29)
  • 메트릭 엔드포인트에 대한 포괄적인 인증

수정됨

  • 심각: 토큰 리필에서 경쟁 조건 제거
  • 심각: SHA-256 해싱으로 API 키 보호
  • 심각: 무제한 버킷 증가를 통한 메모리 소진 방지
  • 심각: 헤더 인젝션 취약점 방지
  • 높음: X-Forwarded-For 조작을 통한 IP 스푸핑 방지
  • 높음: 메모리 누수 방지를 위한 메트릭 싱글톤 패턴 구현
  • 높음: 불필요한 문자열 할당 제거
  • 높음: 속도 제한을 위한 모델 추출 구현
  • 메트릭 폭발 DoS 공격 방지를 위한 포괄적인 카디널리티 제한 및 레이블 살균 추가
  • 패닉 조건 방지를 위한 오류 처리 개선
  • 설정 테스트에서 환경 변수 경쟁 조건 해결
  • 메트릭 RequestTimer의 통합 테스트 실패 수정
  • 메트릭 보안 모듈의 단위 테스트 실패 수정

변경됨

  • 리팩토링: 속도 제한에서 과도한 Arc 래핑 제거
  • 더 나은 유지보수성을 위한 문서 구조 재구성
  • 포괄적인 메트릭 문서 추가
  • 속도 제한 기능 문서 업데이트
  • 개발용 mock 서버 및 샘플 설정 파일 제거
  • 임시 테스트 파일 제거 및 gitignore 개선
  • 중복 man 페이지 제거 및 gitignore 업데이트
  • 올바른 레포지토리를 언급하도록 README.md 업데이트
  • 릴리스 워크플로우 업데이트

v0.8.0 - 2025-09-09

추가됨

  • 메타데이터 공유를 위한 모델 ID 별칭 지원 (#27)
  • 포괄적인 속도 제한 문서
  • 캐시 포이즈닝을 통한 DoS 방지를 위한 models 엔드포인트에 강력한 속도 제한

수정됨

  • 모든 백엔드가 비정상일 때 503 대신 빈 목록 반환 (#28)
  • 오류 처리 및 분류 개선
  • await 지점에서 보유된 MutexGuard에 대한 clippy 경고 해결

변경됨

  • 더 실용적인 /v1/models 엔드포인트 속도 제한 증가
  • configuration.md에 별칭 기능 문서 추가

v0.7.1 - 2025-09-08

수정됨

  • 홈 디렉토리 및 실행 파일 경로에 대한 설정 경로 검증 개선 (#26)

v0.7.0 - 2025-09-07

추가됨

  • 풍부한 메타데이터 지원으로 /v1/models 엔드포인트 확장 (#23) (#25)
  • 향상된 설정 관리 (#9) (#22)
  • 향상된 오류 처리를 포함한 고급 로드 밸런싱 전략 (#21)

수정됨

  • 하드코딩된 25초 제한 대신 config.yaml의 스트리밍 타임아웃 설정 사용

변경됨

  • 제외 목록에 yaml 추가

v0.6.0 - 2025-09-03

추가됨

  • GitHub Project 자동화 워크플로우
  • 포괄적인 타임아웃 설정 및 모델 문서 업데이트

수정됨

  • 하드코딩된 값 대신 config.yaml의 타임아웃 설정 사용 (#19)
  • clippy 경고 및 벤치마크 컴파일 문제 수정

변경됨

  • cargo fmt 적용

v0.5.0 - 2025-09-02

추가됨

  • 계층화된 설계를 갖춘 확장 가능한 아키텍처 (#16)
  • 포괄적인 통합 테스트 및 성능 최적화
  • 완전한 서비스 레이어 구현
  • 미들웨어 아키텍처 및 향상된 백엔드 추상화
  • CLI 및 설정 파일 지원을 포함한 설정 가능한 연결 풀 크기
  • YAML 지원을 포함한 포괄적인 설정 관리 (#7)
  • continuum-router용 Debian 패키징 및 man 페이지

수정됨

  • 테스트에서 Option 올바르게 처리
  • 모델 필드 없는 스트리밍 요청을 우아하게 처리하도록 테스트 업데이트
  • 테스트에서 부동 소수점 정밀도 및 타이밍 문제 해결
  • 객체 풀 및 SSE 파서에서 테스트 실패 및 교착 상태 해결
  • CI 테스트 실패 해결 및 테스트 성능 개선
  • CI 환경에서 설정 감시자 테스트 실패 해결
  • 초기 헬스 체크 경쟁 조건 해결
  • 오류 처리 및 재시도 로직의 심각한 보안 취약점
  • 타이밍 변동에 대한 타임아웃 테스트 허용 오차 조정

변경됨

  • 더 나은 가독성을 위해 복잡한 타입을 타입 별칭으로 추출
  • 모든 cargo fmt 및 clippy 경고 해결
  • 합리적인 기본값으로 재시도 설정을 선택적으로 변경
  • 설정 접근 최적화 및 포괄적인 타임아웃 관리 추가
  • 타임아웃 설정의 모델 이름을 최신 버전으로 업데이트
  • 완전한 문서 업데이트
  • 과대 모듈을 계층화된 아키텍처로 분할

성능

  • 설정 접근 최적화 및 포괄적인 타임아웃 관리 추가

v0.4.0 - 2025-08-25

추가됨

  • 헬스 모니터링을 포함한 모델 기반 라우팅 (#6)

수정됨

  • 더 나은 호환성을 위한 헬스 체크 통합 및 SSE 파싱 개선

변경됨

  • README.md 업데이트

v0.3.0 - 2025-08-25

추가됨

  • 실시간 채팅 완료를 위한 SSE 스트리밍 지원 (#5)

수정됨

  • 스트리밍 응답에서 비성공 상태 코드 처리
  • 백엔드가 404 또는 기타 오류 상태 코드를 반환해도 스트리밍 계속 허용
  • 클라이언트에 백엔드 오류 상태를 알리기 위해 SSE 오류 이벤트를 먼저 전송

v0.2.0 - 2025-08-25

추가됨

  • 여러 엔드포인트에서 모델 집계 (#4)

v0.1.0 - 2025-08-24

추가됨

  • OpenAI 호환 엔드포인트 및 프록시 기능
  • 사용 가능한 모델 목록을 위한 /v1/models 엔드포인트
  • 레거시 OpenAI completions API를 위한 /v1/completions 엔드포인트
  • 채팅 API를 위한 /v1/chat/completions 엔드포인트
  • 라운드 로빈 로드 밸런싱을 포함한 다중 백엔드 지원 (#1)
  • 적절한 오류 메시지를 포함한 정의되지 않은 라우트용 폴백 핸들러

수정됨

  • 모든 엔드포인트에서 오류 처리 일관성 개선

변경됨

  • 변경 내역 및 버전 정보로 README 업데이트