<read-files>/<modified-files>/<previous-summary>)와 모든 출력 형식 제목은 바이트 동일하게 유지@oh-my-pi/pi-catalog 패키지로 이동: 서브경로 임포트(calculateCost, Codex 와이어 상수) 및 이전에 @oh-my-pi/pi-ai 루트에서 가져온 카탈로그 값(getBundledModel, clampThinkingLevelForModel)(pi-ai가 더 이상 재내보내지 않음); pi-ai의 타입 전용 Model/Api/Effort 임포트는 변경 없음@oh-my-pi/pi-catalog 패키지로 이동됨. 깊은 서브경로 내보내기인 @oh-my-pi/pi-ai/models.json, /models, /model-cache, /model-manager, /model-thinking, /effort, /provider-models*, /utils/discovery*, /providers/openai-codex/constants, /providers/google-gemini-headers, /providers/openai-completions-compat는 제거됨 — @oh-my-pi/pi-catalog 동등 항목(/models.json, /models, /model-cache, /model-manager, /model-thinking, /effort, /provider-models*, /discovery*, /wire/codex, /wire/gemini-headers, /compat/openai)에서 임포트. pi-ai 루트 배럴은 자신의 시그니처가 사용하는 모델/노력 _타입_만 재내보냄(Model, Api, ThinkingConfig, Effort, Usage, 호환성 인터페이스) — 카탈로그 값(getBundledModel(s), calculateCost, modelsAreEqual, clampThinkingLevelForModel, DEFAULT_MODEL_PER_PROVIDER, …)은 @oh-my-pi/pi-catalog에서 임포트해야 함.ProviderDefinition은 이제 인증 전용: defaultModel, createModelManagerOptions, catalogDiscovery, dynamicModelsAuthoritative, allowUnauthenticated, specialModelManager가 pi-catalog의 CATALOG_PROVIDERS 테이블로 이동되고, KnownProviderId는 pi-catalog의 KnownProvider로 대체됨(레지스트리 완전성은 해당 union에 대한 컴파일 타임 검사로 강제됨). GitHub Copilot 순수 키/엔드포인트 헬퍼는 registry/oauth/github-copilot에서 @oh-my-pi/pi-catalog/wire/github-copilot로 이동.cch 증명을 삽입할 수 있도록 wrapFetchForCch를 내보냄(cch=00000 자리표시자 대신).setTimeout 생성/삭제 쌍 대신 지속적으로 재무장된 타이머를 사용하며, 지속적 레이스 promise는 매 1024개 항목마다 새로 생성되어 레이스 반응 레코드가 스트림의 전체 수명 동안 축적될 수 없음.write 클래스 호출은 더 이상 수백 KB의 페이로드를 오류 메시지로 모델에 에코백하지 않음.envKeys 리터럴을 삭제(huggingface/qwen-portal/xai-oauth의 순수 $pickenv 픽커 포함), getEnvApiKey는 이제 CATALOG_PROVIDERS[].envVars에서 이러한 폴백을 도출하고, envKeys는 계산된 리졸버(Anthropic Foundry, Vertex ADC, Bedrock 자격증명 체인)와 비카탈로그 제공자(kagi, tavily, parallel, perplexity)에만 남음.model.compat 리더: 요청당 resolve*Compat/detect*Compat 호출(anthropic ×11, responses ×3, completions 래퍼), 인라인 strictResponsesPairing 호스트 감지, OpenCode reasoning_content 변이 블록, 모든 resolvedBaseUrl 스레딩은 제거됨. Compat은 모델 빌드 시점에 한 번 물질화됨(@oh-my-pi/pi-catalog buildModel); OpenCode 사고방식 쿼크는 사전 계산된 compat.whenThinking 포인터 스왑이고, 요청 시간 기본 URL 재정의는 HTTP 클라이언트에만 제공됨. 동작은 변경 없음(Anthropic supportsLongCacheRetention 공식 엔드포인트 게이트는 감지로 접혀짐).model.compat.supportsSamplingParams에 게이팅하고 적응형 display를 model.thinking.supportsDisplay(Bedrock도)에 게이팅하고, 적응형 노력 티어는 구워진 thinking.effortMap에서 나오며, Google thinkingLevel 맵은 정적이고, 노력-다이얼이 없는 리즈너(thinking: undefined, 예: xai-oauth/grok-build)는 제거된 modelOmitsReasoningEffort 술어 없이 resolveOpenAiReasoningEffort를 단락시킴.retry-after 힌트는 여전히 우선되고, 502s와 같은 재시도 가능한 사전 콘텐츠 실패는 더 이상 3회 시도 후 중단되지 않음.omitMaxOutputTokens를 존중하고, 추론이 명시적으로 비활성화될 때 think: false를 전송하고, HTTP 400 응답 본문을 표시된 오류에 보존하도록 수정.AuthStorage.markUsageLimitReached가 "모든 형제가 일시적으로 차단됨"을 "형제가 없음"으로 축소하도록 수정: 이제 가장 빠른 형제 차단 만료(retryAtMs)가 있는 UsageLimitMarkResult를 반환하므로 재시도 계층은 단기 차단(401 후 60초, 5분 사용 프로브)을 기다릴 수 있음(제공자의 다중 시간 재시도 후를 채택하는 대신). rotateSessionCredential과 인증 게이트웨이는 새 형태에 적응.stop으로 제시하도록 수정: 인밴드 {"error":{...}} 이벤트와 promptFeedback.blockReason 청크는 절대 검사되지 않았고, 어떤 finishReason 없이 끝나는 스트림은 초기화된 stop을 유지했음 — 모두 셋 다 오류로 표시됨(API-키 및 gemini-cli/Antigravity 소비자 모두), toolUse 중단 이유 재정의는 더 이상 유효한 도구 호출 이후에 도착하는 SAFETY/MALFORMED_FUNCTION_CALL 마무리를 마스크하지 않음.MALFORMED_FUNCTION_CALL, RECITATION, guardrail_intervened, …)는 이제 표시된 오류 메시지에 기록됨.retry-after를 무시하도록 수정 — 이제 max(headerDelay, backoff) 대신 max(headerDelay, backoff)를 기다림. 보장된 실패의 ~14초 내에 속도 제한 엔드포인트를 3회 망치지 않음.error 이벤트가 원시 JSON 엔벨로프로 throw되도록 수정; 구조화된 error.type/message는 파싱되고, 재시도 분류는 우발적 regex 히트 대신 타입화된 토큰에서 유지됨.message_start 이후, 이미 종료된 인덱스의 재생된 content_block_start 이벤트는 이제 중복 텍스트/도구 호출을 추가하는 대신 조용히 소비됨.{type:"text", text:123})을 알 수 없는 블록 캐치올을 통해 수락하여 기록을 손상시키고 나중에 불명확한 TypeError로 표시되도록 수정 — 이제 깔끔한 400으로 검증 실패. 게이트웨이의 인코드 스트림은 또한 15초마다 ping 킵얼라이브를 내보내고 내부 스트림이 터미널 이벤트 없이 끝날 때 완전한 message_start/message_delta/message_stop 엔벨로프를 내보내므로 엄격한 클라이언트는 더 이상 느리거나 빈 스트림을 프로토콜 오류로 분류하지 않음.claude-opus-4.7/4.8 GitHub Copilot, Vercel AI Gateway, Zenmux)가 적응형 사고방식 display 지원이 누락되도록 수정 — 스트리밍된 추론은 디스플레이 술어가 대시 형식 ID만 일치했기 때문에 해당 항목에 숨겨져 있음(동일한 실패 클래스 as #1373).requiresThinkingAsText 재생 경로가 문자열 어시스턴트 콘텐츠에서 .unshift()를 호출하도록 수정 — 사고방식과 텍스트 모두를 포함하는 같은 모델 기록 턴을 실패하게 하는 무조건 TypeError.encrypted_content를 제거하도록 수정(스트립 모드 스키마), codex 스타일 상태 비저장 재생이 손상됨; 스키마는 이제 느슨하고, 아웃바운드 인코더가 이미 유지한 대칭을 복원. 복합 내부 callId|itemId ID는 와이어에 도달하기 전에 분할되므로 call_id 문자 집합을 검증하는 타사 클라이언트는 더 이상 거부하지 않음.response.completed 핸들러에 이식: 손실된 output_item.done은 더 이상 오래된 {} 인수와 임시 파서 필드를 가진 도구 호출을 세션 기록에 유지할 수 없음.content_part.added를 삭제할 때 라이브 텍스트가 항목 완료까지 중단되도록 수정: 누락된 부분은 이제 첫 output_text/refusal 델타에서 합성됨(공유 및 codex 디코더).content/tool_calls 델타가 도구 호출을 잘린 호출 + 이름 없는 유령으로 조각내도록 수정: 텍스트/사고방식 전환은 더 이상 열린 도구 호출 블록을 완료하지 않으므로 인덱스 전용 연속 델타가 다시 찾음.AZURE_OPENAI_DEPLOYMENT_NAME_MAP을 무시하도록 수정(Responses 제공자만 존중), 배포 이름이 카탈로그 모델 ID와 다를 때 불명확한 404 생성.reasoning_content를 삭제하도록 수정, DeepSeek/Kimi 정확 재생 업스트림에 모델의 실제 추론 대신 자리표시자를 제공; 이제 사고방식 블록으로 왕복 이동하고, toolcall_end는 스트리밍된 시작이 빈 값을 전달했을 때 수정 id/name 청크를 내보냄.EventStream.end()가 .result()를 무한정 대기하도록 남기도록 수정(확장 스트림 및 레이지 래퍼를 통해 도달 가능); 이제 합성 오류로 거부됨.Retry-After(30초로 제한)를 존중하고 다른 상태는 재시도되지 않는 반면, 상태 없는 전송 오류는 선형 재시도를 유지.<에서 최대 256자에 대해 디스플레이를 중단시키도록 수정: 유휴 상태 홀드는 이제 엄격한 DSML 섹션 열기 접두사에서만 트리거되고, 1MB 파라미터 상한을 초과하는 것은 더 이상 종료 엔벨로프 태그를 보이는 텍스트로 누출하지 않음; 제한된 파라미터 값은 또한 도구를 조용히 손상된 입력으로 실행하는 대신 명시적 …[parameter truncated] 마커를 전달.{}로 공백화하도록 수정: 방문 집합 사이클 가드는 두 속성에서 재사용되는 서브스키마 객체를 사이클로 취급했음; 경로 추적 enter/exit은 이제 사이클을 단락시키면서도 공유를 허용하고, 동결된 입력 스키마는 더 이상 throw하지 않으며, 경로 카운터는 더 이상 사이클 분기에서 깊이를 누출하지 않음(같은 객체의 나중 정규화마다 사이클을 잘못 보고하게 만들었음).AbortSignal에 바인딩되어 한 병렬 Vertex 호출이 취소될 때 모든 동시 대기자를 실패시키도록 수정; 호출자는 이제 자신의 신호를 분리된 새로고침과 경합하고, 이는 자체 30초 시간 초과로 제한되어 행 중인 페치가 프로세스 재시작까지 인플라이트 슬롯을 고정할 수 없음.functionCall.args를 {}로 기본값.toolChoice가 "none"일 때 toolConfig를 완전히 삭제하도록 수정하는 동시에 기록은 여전히 도구 블록을 포함 — Converse API는 그러한 요청을 거부하므로 도구 사양은 유지되고 선택만 생략.credential_process/SSO 페치를 생성하는 대신 단일 플라이트 — 공유 해석은 첫 호출자의 중단 신호에서 분리됨(취소된 한 요청은 더 이상 모든 대기자를 실패시키지 않음) 및 자체 30초 시간 초과로 제한. 이벤트스트림 리더는 또한 HTTP 연결이 배수되도록 남겨두는 대신 비정상 종료에서 응답 본문을 취소.websocket_connection_limit_reached에서 발생하도록 수정: 무 콘텐츠 재연결 경로는 절대 재시도 예산을 참조하지 않았고 절대 기다리지 않았으며, 한계가 계정 범위일 때 엔드포인트를 무한정 망치고 있음. 재연결은 이제 모든 다른 WS 재시도 경로처럼 예산 및 지연되며, 소진되면 단일 SSE 재생으로 폴백.toolcall_end가 전달된 후 턴 재생을 거부하고, 같은 도구 호출을 다시 내보내는 대신 오류를 표시.web_search_call)을 실패 시도에서 재생된 턴의 providerPayload로 누출하고 기준선을 추가하도록 수정.websocket closed before open)로 분류되는 동시 호출자의 인플라이트 CONNECTING 핸드셰이크 포함, 치명적이고 전체 세션의 WebSocket을 비활성화. 실패 정리는 이제 CONNECTING 소켓을 건너뛰고 풀은 교체 핸드셰이크를 다시 결합(제한됨).분량 관계로 이후 내용은 번역에서 제외했습니다. 전체 내용은 위 원문 링크에서 확인하세요.