GPT-5 Harmony 누수 감지를 커밋된 어시스턴트 메시지에 적용했습니다(openai-codex만 해당). detectHarmonyLeakInAssistantMessage는 이제 스트리밍된 done/error 결과와 후행 폴백에서 실행되므로 누수된 최종 응답이 그대로 커밋되는 대신 기존 완화 메커니즘에 의해 중단 및 재시도됩니다. 도구 인자(tool_arg) 스캔은 후행 가비지 T 코-신호에서 제어되며 호출자가 detectHarmonyLeakInAssistantMessage의 새로운 선택적 toolArgParseEnd 리솔버를 통해 파싱 경계를 제공할 때만 실행됩니다. 에이전트 루프는 이를 전달하지 않습니다. 스트리밍된 도구 DSL을 경계지을 수 없기 때문입니다. 따라서 이 표면은 비활성 상태로 유지되며 합법적으로 채널 단어 또는 비라틴 문자(예: harmony 피크처 편집)와 함께 to=functions.*를 포함하는 내용을 가진 정당한 codex 도구 호출은 절대 강제로 중단되지 않습니다.
@oh-my-pi/pi-ai
Added
anthropic-client 내보내기를 통해 AnthropicMessagesClient와 관련 Anthropic 와이어 타입/에러를 추가했으므로 호출자가 @anthropic-ai/sdk에 의존하지 않고도 독립형 Anthropic Messages 클라이언트를 구성할 수 있습니다.
parseClaudeRateLimitHeaders와 AuthStorage.ingestUsageHeaders를 추가하여 Anthropic 속도 제한 응답 헤더가 스로틀링 중에 자격 증명 별 사용 캐시를 예열하면서 마지막 전체 사용 보고서의 티어별 데이터를 보존할 수 있습니다.
Changed
Anthropic 요청 처리를 변경하여 @anthropic-ai/sdk 대신 패키지 로컬 AnthropicMessagesClient 구현을 기본 전송으로 사용합니다.
AnthropicOptions.client 표면을 messages.create를 포함한 모든 AnthropicMessagesClientLike 구현을 수용하도록 업데이트하여 사용자 정의 호환 클라이언트를 활성화합니다.
생성된 OAuth 메타데이터 user_id를 무작위 값 대신 설치 ID에서 파생된 결정론적 device_id를 사용하도록 변경했습니다.
claudeCodeVersion을 현재 Claude Code 릴리즈와 일치하도록 2.1.148로 범프했습니다.
X-Stainless-Package-Version을 0.94.0으로 업데이트(번들된 @anthropic-ai/sdk 버전과 일치), X-Stainless-Runtime-Version을 v24.3.0으로 고정(CC 2.1.148과 번들된 Bun 버전), X-Stainless-Os 헤더 키를 X-Stainless-OS로 수정했습니다.
createClaudeBillingHeader는 이제 결정론적 청구 헤더(cc_version=<claudeCodeVersion>.<suffix>; cc_entrypoint=cli; cch=00000;)를 내보냅니다. 여기서 <suffix>는 SHA-256(salt + msg[4] + msg[7] + msg[20] + version)의 처음 3개 16진 문자이며 무작위 바이트 대신입니다. 지문 시드는 첫 번째 사용자 메시지에서 가져오며(합성/개발자 주입 건너뜀), Claude Code의 computeFingerprintFromMessages를 미러링합니다.
cch 증명 구현됨: cch=00000은 OAuth 요청의 경우 wrapFetchForCch가 와이어에서 XXHash64(body, 0x4D659218E32A3268) & 0xFFFFF로 다시 작성하는 플레이스홀더이며 Bun.hash.xxHash64를 통해 제자리에서 계산되고 5개의 소문자 16진 문자로 형식화됩니다. 다시 작성은 system[0] 청구 헤더 접두사에 고정되어 사용자 콘텐츠가 절대 변경되지 않으며 청구 헤더 접두사가 있을 때만 설치됩니다(OAuth 턴).
anthropic-beta 헤더가 OAuth 모델 검색 및 Claude 사용 API 요청에 설정되어 context-1m-2025-08-07, redact-thinking-2026-02-12, mid-conversation-system-2026-04-07, advanced-tool-use-2025-11-20, effort-2025-11-24, extended-cache-ttl-2025-04-11를 추가하도록 확장되었습니다. 사용 API user-agent는 claude-cli/2.1.158 (external, cli)로 범프됩니다.
추론 모델은 이제 요청별 Anthropic-Beta 헤더에 effort-2025-11-24를 추가합니다(Claude Code와 일치).
buildAnthropicSystemBlocks(CC 명령 모드)는 이제 Claude Code와 동일한 3 블록 레이아웃을 내보냅니다: 청구 헤더(절대 캐시 안 함), 시스템 명령어(캐시됨), 모든 사용자 콘텐츠가 \n\n으로 하나의 블록에 병합됨(캐시됨). 이전에는 항목당 하나의 블록을 내보냈고 마지막 항목에만 캐시를 했으므로 블록 수로 호출자를 지문화했습니다.
applyPromptCaching은 이제 Claude Code의 중단점 레이아웃과 일치합니다: 2개 시스템(명령어 + 병합된 콘텐츠) + 2개 메시지, 도구 중단점 없음. 도구 중단점은 중복되었습니다. 도구는 토큰 시퀀스에서 시스템을 따르므로 시스템이 변경되면 도구 캐시 접두사도 변경됩니다. 명령어 블록(system[1])은 모든 요청에서 안정적이며 이제 자체 보장된 히트 중단점을 얻습니다.
applyPromptCaching은 마지막 두 사용자 메시지 대신 역할에 관계없이 마지막 두 메시지를 캐시합니다. 이전 턴의 이전 어시스턴트 메시지(도구 호출 + 응답)는 이전 사용자 메시지보다 크고 최근에 생성되어 더 높은 가치의 캐시 대상입니다.
OAuth 범위 세트 확장됨: user:sessions:claude_code, user:mcp_servers, user:file_upload 추가. AUTHORIZE_URL은 claude.ai/oauth/authorize에, TOKEN_URL은 api.anthropic.com/v1/oauth/token에 유지됩니다. platform.claude.com 동등 항목은 CC의 콘솔 자격 증명 흐름이며 OMP가 직접 OAuth 토큰 추론에 필요한 user:inference를 부여하지 않습니다.
토큰 새로 고침 POST는 이제 anthropic-beta: oauth-2025-04-20과 User-Agent: anthropic-sdk-typescript/0.94.0 userOAuthProvider를 전송합니다(CC는 초기 코드 교환이 아닌 새로 고침에서 이를 전송함).
Fixed
도구 인자 검증을 수정하여 스키마가 배열을 요구할 때 일반 문자열을 싱글톤 배열로 래핑하여 도구 수준 경로/리스트 정규화가 베어 문자열 인자에서 복구할 수 있도록 합니다.
OAuth Anthropic 도구 정의에서 eager_input_streaming과 엄격한 플래그를 복원했으므로 모델 호환성이 eager 스트리밍을 허용할 때 사용합니다.
주입된 사용자 정의 클라이언트가 client.beta.messages.create를 요구하는 대신 client.messages.create로 폴백하여 beta 클라이언트를 놓친 OAuth 스트림 호출을 수정했습니다.
외부 SDK를 요구하지 않으면서 재시도/시간 제한 및 잘못된 형식의 에러 분류가 호환되도록 유지하기 위해 내부 API 클라이언트 타입의 직접 사용을 수정했습니다.
도구 결과 이력 후 최종 컨텍스트 메시지가 활성 사용자 턴이라고 가정하는 대신 최신 사용자/개발자 턴을 선택하여 Cannot send empty user message to Cursor API 오류로 실패하는 Cursor 공급자 요청을 수정했습니다.
CLAUDE_CODE_USE_FOUNDRY가 설정되지 않았을 때 Anthropic 웹 검색이 ANTHROPIC_CUSTOM_HEADERS를 제거하여 기업 API 게이트웨이에서 401을 발생시키는 문제를 수정했습니다. resolveAnthropicCustomHeadersForBaseUrl은 이제 기본 URL이 비 Anthropic이거나 Foundry가 활성화될 때마다 파싱된 헤더를 전달하며 buildAnthropicSearchHeaders는 이를 buildAnthropicHeaders를 통해 스레드하므로 검색 및 스트리밍 경로가 동일하게 동작합니다(#1693).
OpenCode Go Anthropic 형식 모델(예: qwen3.7-max)이 OpenCode 베어러 토큰과 함께 Anthropic X-Api-Key 인증을 전송하여 허위 Alibaba 401 Invalid API-key provided 오류를 피하는 문제를 수정했습니다. (#1661)
OAuth 토큰 교환 및 새로 고침 흐름을 수정하여 토큰 응답이 계정 정보를 생략할 때 Claude CLI 부트스트랩 ID를 가져오므로 accountId와 email이 이제 사용 가능할 때 복구됩니다.
직접 OAuth 요청에서 Anthropic 생각 추적이 손실되는 문제를 수정했습니다. OAuth 요청은 더 이상 생각이 명시적으로 숨겨지지 않는 한 redact-thinking-2026-02-12를 전송하지 않으며, Opus 4.7+ 적응형 생각은 display: "summarized"를 선택하고, 상위 사용자 대면 생각 티어는 이제 다음 하위 "xhigh" 티어가 아닌 Anthropic의 output_config.effort = "max"를 전송합니다.
Removed
@anthropic-ai/sdk 런타임 종속성을 제거했습니다. Anthropic 공급자는 이제 패키지 로컬 AnthropicMessagesClient와 providers/anthropic-wire.ts의 수동 유지 와이어 타입을 사용합니다. SDK는 URL 조립, 인증 헤더 주입, 제한된 재시도, 사전 응답 시간 제한, HTTP 에러 대 상태 매핑에만 사용되었으며 이 모든 항목은 동일한 관찰 가능한 동작으로 재현됩니다.
@oh-my-pi/pi-coding-agent
Added
세션 선택기(pi --resume / /resume)에 모든 프로젝트 범위를 추가했습니다. Tab을 눌러 현재 폴더의 세션과 모든 프로젝트 전체의 모든 세션 사이를 전환할 수 있습니다. 모든 프로젝트 목록은 지연 로드되며 각 세션의 디렉토리를 표시합니다. 현재 폴더에 세션이 없으면 선택기는 "No sessions found"를 인쇄하는 대신 모든 프로젝트 범위로 바로 열립니다.
Kagi 웹 검색 공급자를 Kagi의 V1 Search API(POST /api/v1/search)로 마이그레이션하여 해제된 V0 엔드포인트를 교체하면서 kagi 공급자 ID, KAGI_API_KEY 자격 증명, /login kagi 흐름을 변경 없이 유지합니다(#1272 by @thismat)
/usage 및 상태 라인 사용 세그먼트에 대한 Anthropic anthropic-ratelimit-unified-* 응답 헤더 예열을 추가하여 활성 사용 중 직접 OAuth /usage 프로브를 줄이도록 제한합니다.
Changed
Anthropic API 요청 메타데이터 user_id.device_id를 영구적 설치 ID에서 파생되도록 변경하여 동일한 설치에서 Anthropic 계정 변경 후에도 안정적으로 유지합니다.
eval parallel() / pipeline() 헬퍼를 변경하여 concurrency 인자를 제거하고 task 도구 배치만큼 넓게 실행합니다. 워커 풀 상한선은 이제 호스트를 통해 라이브로 해결되는 새로운 __concurrency__ 브릿지(기본값 32; 0 = 모든 항목을 한 번에 실행)를 통해 task.maxConcurrency 설정을 추적하며 기본값 4이고 16으로 상한선이 있는 이전의 호출별 concurrency 옵션 대신입니다. 이는 eval 팬아웃이 세션이 구성된 병렬 처리를 과소 사용하지 않도록 합니다.
하위 에이전트 / agent:// 출력 ID를 숫자 접두사 스킴(0-Anna, 1-Bob, 중첩 0-Anna.1-Bob)에서 이름 우선 스킴으로 변경합니다: 요청된 이름이 그대로 사용되며 세션 내에서 동일한 이름이 반복될 때만 -2/-3/… 접미사가 추가됩니다(Anna, Anna-2, Anna-3). 중첩 ID는 부모(Anna.Bob) 아래 그룹화되며 라이브 작업 위젯은 이를 Anna>Bob로 렌더링합니다. 주 에이전트의 IRC ID는 이제 Main입니다(이전 0-Main). AgentOutputManager는 여전히 재개 시 기존 .md 출력을 스캔하므로 이전 출력을 덮어쓸 이름을 절대 재사용하지 않습니다.
다른 프로젝트에 속하는 세션 재개를 변경하여 프로세스를 해당 프로젝트의 작업 디렉토리로 전환합니다. pi --resume과 세션 내 /resume 선택기는 이제 재개된 세션의 cwd로 chdir하고 모든 cwd 파생 입력을 다시 범위화합니다. 프로젝트 디렉토리, 프로젝트 설정(.claude/settings.yml, .omp/settings.json, 경로 범위 enabledModels/disabledProviders), 플러그인 루트, 기능, 슬래시 명령, ssh 도구. 따라서 도구, 검색, 구성, 명령은 모두 재개된 프로젝트를 따릅니다. SessionManager는 로드 시 재개된 세션의 자체 cwd/세션 디렉토리를 채택합니다(전환이 실패하면 롤백됨).
docs/environment-variables.md에서 ANTHROPIC_SEARCH_API_KEY와 ANTHROPIC_SEARCH_BASE_URL을 더 철저히 문서화하고 docs/tools/web_search.md의 Anthropic 공급자 섹션에 표면화하고 omp --help의 env-var 요약에 ANTHROPIC_SEARCH_BASE_URL을 추가하여 검색 전용 재정의가 ANTHROPIC_SEARCH_API_KEY와 함께 발견 가능하도록 합니다(#1694).
Kagi 웹 검색 공급자를 Kagi의 V1 Search API(POST /api/v1/search)로 마이그레이션하여 해제된 V0 엔드포인트를 교체하면서 kagi 공급자 ID, KAGI_API_KEY 자격 증명, /login kagi 흐름을 변경 없이 유지합니다(#1272 by @thismat)
Fixed
read, search, find, ast_grep, ast_edit가 모델이 여러 기존 경로를 쉼표, 세미콜론 또는 공백으로 구분된 하나의 문자열로 평탄화할 때 복구되도록 수정하면서 구분 기호를 포함하는 실제 경로를 유지합니다.
Exa 자격 증명 없이 Exa 웹 검색이 사용 가능으로 보고하는 문제를 수정했습니다. 이는 검색을 인증되지 않은 공용 MCP 폴백으로 라우팅하고 다음 공급자를 시도하기 전에 지연될 수 있습니다. 가용성과 searchExa()는 이제 표준 AuthStorage 캐스케이드(EXA_API_KEY 환경 또는 저장된 자격 증명)를 통해 해결됩니다(#1695).
Anthropic 웹 검색이 저장된 Anthropic 인증 또는 일반 Anthropic 환경 폴백이 아닌 ANTHROPIC_SEARCH_API_KEY에서 자격 증명이 올 때 ANTHROPIC_SEARCH_BASE_URL을 무시하는 문제를 수정했습니다(#1694).
web_search가 기업 Anthropic API 게이트웨이에서 401을 반환하는 문제를 수정했습니다. ANTHROPIC_CUSTOM_HEADERS는 이제 Foundry 모드에서뿐만 아니라 ANTHROPIC_BASE_URL이 비 Anthropic 호스트를 가리킬 때마다 웹 검색 요청으로 전달됩니다(#1693).
WSL에서 내보낸 로컬 파일을 열 때 wslpath -w를 통해 기존 경로를 전송하고 사용 가능할 때 wslview를 직접 시작하도록 수정하여 xdg-open의 손상된 파일 핸들러 경로 변환을 피합니다(#950 by @rxreyn3).
/move(및 크로스 프로젝트 재개)가 대상 디렉토리로 라이브 프로젝트 설정을 다시 범위화하지 않는 문제를 수정했습니다. 세션의 작업 디렉토리를 변경하면 이제 프로젝트 설정 레이어가 제자리에서 다시 로드되므로(Settings.reloadForCwd를 통해) 프로젝트 범위 구성과 경로 범위 enabledModels/disabledProviders가 시작 디렉토리에 고정된 상태로 유지되는 대신 이동을 따릅니다.
read <db.sqlite>이 큰 데이터베이스에서 TUI를 정지하는 문제를 수정했습니다. 테이블 나열은 테이블당 제한되지 않은 SELECT COUNT(*)를 실행했고, bun:sqlite가 렌더링과 입력을 구동하는 동일한 JS 스레드에서 동기적으로 실행되므로 다중 GB 데이터베이스의 전체 테이블 스캔은 UI를 초 단위로 차단했습니다. 나열은 이제 스캔 상한선 위의 테이블에 대해 플래너의 sqlite_stat1 추정치를 읽고(~N rows로 표시) 테이블이 명백히 작을 때만 정확히 계산하며 최대 cap + 1 행을 읽습니다(상한선 테이블은 N+ rows 표시). 8.4 GB 통계 데이터베이스에서 나열은 다중 초 전체 스캔에서 ~2 ms로 단축되었습니다.
tools/eval이 tools/renderers보다 먼저 임포트될 때마다 트리거되는 모듈 로드 크래시(ReferenceError: Cannot access 'evalToolRenderer' before initialization)를 수정했습니다. eval JS 백엔드는 정적으로 에이전트/태스크/SDK/확장 체인을 가져옵니다. 이는 루트 배럴 → modes/components → tool-execution → renderers를 재진입하며 eval.ts가 여전히 초기화되는 중입니다. 따라서 renderers.ts는 TDZ에서 evalToolRenderer를 읽습니다. eval TUI 렌더러는 이제 renderers.ts가 직접 임포트하는 의존성 경량 tools/eval-render.ts로 분할되므로(순수 렌더링을 eval 런타임에서 분리) eval.ts는 호환성을 위해 evalToolRenderer/EVAL_DEFAULT_PREVIEW_LINES을 다시 내보냅니다.
/logout이 환경/구성 폴백에 의해서만 인증된 공급자를 제공하는 문제를 수정했습니다. 이는 저장된 자격 증명이 제거된 후 OpenCode Go/Zen이 계속 로그인된 것처럼 보이게 했습니다(#1658).
대화형 사용자가 크로스 프로젝트 포크 프롬프트를 거부할 때 omp --resume <id>가 확인되지 않은 예외로 크래시되는 문제를 수정했습니다. createSessionManager는 이제 해당 취소에 대해 undefined를 반환합니다.