@oh-my-pi/pi-ai/effort 모듈을 추가했습니다. 이 모듈은 Effort enum과 THINKING_EFFORTS를 내보내며, model-thinking에서 분리되었으므로 hot-path 소비자는 model-thinking 및 해당 provider-compat 종속성 그래프를 불러오지 않고도 추론 레벨을 가져올 수 있습니다. 패키지 barrel은 계속 두 이름을 모두 재내보내므로 기존 import는 영향을 받지 않습니다.Antigravity 사용량 공급자가 모델별로 하나의 막대를 내보내는 대신 티어별로 중복 제거하도록 수정했습니다. 이제 단일 계정의 15개 이상의 모델 항목이 하나의 막대로 축약되어 상위 API의 공유 할당량 현실과 일치합니다.
Antigravity 사용량 보고서에서 메타데이터의 email과 accountId가 누락되는 문제를 수정했습니다. 이제 /usage 디스플레이와 중복 제거기가 보고서를 자격 증명과 연결할 수 있습니다.
Google Cloud 공급자의 경우 사용량 보고서 중복 제거가 projectId를 무시하는 문제를 수정했습니다. 이제 중복된 자격 증명 항목이 동일한 계정으로 인식됩니다.
Cloud Code Assist(Antigravity / Gemini CLI)가 pr 매개변수 스키마에 anyOf: [string, array]가 포함되어 있을 때 github 도구를 HTTP 400으로 거부하는 문제를 수정했습니다. CCA 혼합 유형 결합 축약이 첫 번째 null이 아닌 유형(string)을 선택했지만 변형 분기에서 유형별 키를 무분별하게 복사했습니다. 배열 변형의 items이 문자열 유형 결과로 유출되어 {type: "string", items: {...}}을 생성했으며, Google의 API는 이를 유효하지 않은 것으로 거부했습니다. 이제 축약은 결합된 변형 필드를 우승 유형의 허용된 키 집합에 대해 필터링합니다. (#2002)
OpenAI Responses 계열 공급자(Codex, OpenAI Responses, Azure Responses)가 사용자가 도구 호출에서 끝나는 노드로 세션 트리를 분기하거나 탐색한 후(tool-result 자식이 재구성된 히스토리에서 삭제됨) 또는 호출 스트리밍과 그 결과 저장 사이에 턴이 중단되거나 충돌한 후 400 No tool output found for function call …로 요청을 거부하는 문제를 수정했습니다. 이제 변환기는 쌍을 이루지 않은 function_call/custom_tool_call 직후에 placeholder function_call_output/custom_tool_output을 즉시 합성합니다. 이는 기존 orphan-output 복구와 대칭이므로 모델은 여전히 호출을 보고 전체 요청이 400이 되는 대신 복구할 수 있습니다.
Anthropic 호환 추론 엔드포인트가 부호 없는 thinking 블록을 내보낼 때 계속 요청에서 이전 턴의 추론을 잃는 문제를 수정했습니다. convertAnthropicMessages가 알 수 없는 엔드포인트를 서명 강제로 취급하고 부호 없는 추론을 type: "text"로 강등했으며, 이는 다음 턴의 도구 호출 인수 직렬화를 불안정하게 했습니다. todo 도구에 대해 보고된 args?.ops?.map is not a function 충돌의 상위 증상입니다. 공식 api.anthropic.com은 보수적인 텍스트 폴백을 유지하고, 비공식 anthropic-messages 추론 모델은 이제 부호 없는 추론을 네이티브 type: "thinking"으로 재생합니다 (#2005).
providers.parallelFetch 부울 설정을 providers.fetch enum(auto / native / trafilatura / lynx / parallel / jina)으로 대체했습니다. 이는 read/fetch 도구의 URL 리더 백엔드 우선순위를 선택하며, providers.image/providers.webSearch를 미러링합니다. 기존 설정은 자동으로 마이그레이션됩니다. 레거시 키는 삭제되고 새로운 auto 기본값이 적용됩니다.read/web-fetch GitHub 스크래퍼에 GitHub Actions 읽기 핸들러를 추가했습니다. github.com/{owner}/{repo}/actions/runs/{id}를 가져오면 실행 메타데이터와 작업별 분석(성공하지 않은 작업에 대해 나열된 단계)이 렌더링되고, …/actions/runs/{id}/job/{id}(또한 API 스타일 …/jobs/{id})를 가져오면 단일 작업의 메타데이터, 단계 테이블 및 전체 일반 텍스트 로그가 렌더링됩니다. 로그는 GITHUB_TOKEN/GH_TOKEN이 있을 때 이를 사용하여 actions/jobs/{id}/logs 리디렉션을 통해 가져와지며, 줄당 ISO 타임스탐프 접두사와 선행 BOM은 제거됩니다. 로그를 사용할 수 없을 때(토큰 없음, 비공개 저장소 또는 만료됨/미확정 실행) 섹션은 명시적인 공지로 축소됩니다.agent() 서브에이전트가 task.maxRuntimeMs wall-clock 제한의 대상이 되지 않도록 변경했습니다. 부모 셀의 유휴 감시 장치는 전체 bridge 호출(withBridgeTimeoutPause) 동안 이미 일시 중지되어 있으므로 장시간 실행되는 fan-out/복구 워크플로우는 서브에이전트 런타임 제한으로 인해 종료되어서는 안 됩니다. runEvalAgent는 이제 maxRuntimeMs: 0을 runSubprocess로 전달하며, 이는 상속된 설정보다 명시적인 ExecutorOptions.maxRuntimeMs 재정의를 우선합니다.PI_TIMING=x pi는 CLI 그래프가 로드되기 전에 모듈 타이머를 사전 로드하고 (modules) 보고서를 포함합니다. PI_TIMING=full은 이제 인쇄 후 PI_TIMING=x와 일치하도록 종료되므로 전체 모듈 보고서는 TUI를 시작하지 않고도 cold-start 측정에 사용할 수 있습니다. cold-start 측정을 위해 동일한 프로필된 시작 경로를 위해 루트 dev:timing 스크립트를 추가했습니다.InteractiveMode를 직접 import하고, print/RPC/ACP 실행기를 branch 전용 경로에 유지하며, 마켓플레이스 자동 업데이트 작업을 경량의 지연된 시작 뒤로 이동합니다.main.ts에 의해 정적으로 import되지 않습니다. 현재 설정 버전은 이제 작은 종속성 없는 modes/setup-version 모듈에 위치하며, 마법사 barrel은 저장된 설정 버전이 stale하거나 마법사가 강제될 때만 lazy-load됩니다. 일반적인 최신 시작은 완전히 로드를 건너뜁니다.@oh-my-pi/pi-ai barrel을 불러오지 않습니다. commands/launch.ts와 cli/args.ts는 작은 @oh-my-pi/pi-ai/effort 모듈에서 THINKING_EFFORTS/Effort를 import하고, config/model-registry.ts는 이제 약 20개의 기호를 barrel 대신 좁은 서브경로(api-registry, model-cache, model-manager, model-thinking, models, provider-models, types, utils/event-stream)에서 import합니다. 따라서 시작은 더 이상 barrel에서 재내보내는 모든 공급자, 인증, OAuth 및 사용량 모듈을 갈망스럽게 로드하지 않습니다.read/fetch HTML 리더 백엔드 우선순위를 native > trafilatura > lynx > parallel > jina로 변경했습니다(이전: parallel > jina > trafilatura > lynx > native). in-process 네이티브 htmlToMarkdown이 먼저 실행됩니다. 즉각적이며, 네트워크가 없고, 충실도가 높으므로 일반적인 경우는 더 이상 원격 서비스에 의존하지 않으며, 정지된 원격 백엔드는 더 이상 이를 마스킹할 수 없습니다. providers.fetch를 통해 특정 백엔드를 선택하면 먼저 시도하고 나머지는 폴백됩니다. 낮은 품질 게이트(>100 문자이고 isLowQualityOutput이 아님)는 이제 모든 백엔드에 균일하게 적용됩니다. 아무도 이를 제거하지 않으면 최고 우선순위의 실질적이지만 낮은 품질 출력이 여전히 표시되므로 llms.txt / 문서 추출 폴백이 계속 실행됩니다.agent() 실패가 이유 없이 불명확한 RuntimeError: bridge call '__agent__' failed로 표시되는 문제를 수정했습니다. 서브에이전트가 중단되었을 때 runEvalAgent는 result.error ?? result.stderr ?? result.abortReason ?? …로 실패 메시지를 구성했지만, result.stderr는 clean abort 시 빈 문자열이고(result.error는 비어있지 않은 stderr에만 gated됨), nullish chain은 ""에서 멈추고 abortReason에 도달하지 않았습니다. 빈 문자열은 loopback bridge와 Python 서문의 RuntimeError(msg or "bridge call … failed")를 통해 전파되어 실제 이유를 버렸습니다. chain은 이제 ||를 사용하므로 빈 stderr는 abortReason을 통과합니다.stopReason: "aborted"이고 호출자 신호 없음, 런타임 제한 타이머 없음) 일반적인 "Caller에 의해 취소됨"으로 잘못 레이블이 지정되는 문제를 수정했습니다. runSubprocess는 이제 해당 경우에 중단된 Assistant 메시지의 errorMessage(예: "Request was aborted" 또는 특정 스트림 오류)를 선호하는 한편, 실제 호출자 신호 또는 wall-clock abort는 여전히 정확한 이유를 보고합니다.Ctrl+O로 확장할 때 스크롤된 헤드를 삭제하는 문제를 수정했습니다. 스트리밍 write(컨텐츠 스트리밍 중)와 스트리밍 eval(고정 코드 셀 아래 stdout 스트리밍)은 top-anchored로 렌더링되고 append-only로 증가하지만 도구 블록은 자신을 append-only 트랜스크립트에 보고하지 않았으므로 렌더러의 commit-as-you-go 경계는 블록 시작에서 멈추고 뷰포트 위로 스크롤된 이전 행은 어디에도 커밋되지 않았습니다. 미리보기가 순환 버퍼처럼 보이는 상태로 사라졌습니다. ToolExecutionComponent는 이제 isTranscriptBlockAppendOnly()를 구현합니다(isTranscriptBlockFinalized()에 gated되므로 eval 같은 partial-result streams도 포함). 렌더러가 선언한 isStreamingPreviewAppendOnly 조건부에 위임하므로 확장된 스트림이 스트리밍된 Assistant 응답과 정확히 같은 방식으로 헤드를 커밋합니다. 축약된 미리보기(제한된 sliding tail windows)와 finalized/result 미리보기(capped view로 축약될 수 있음)는 지연됩니다.read/fetch가 malformed list markup이 있는 페이지의 전체 list 섹션을 자동으로 삭제하는 문제를 수정했습니다. 예를 들어 <ul>의 직접 자식으로 stray <img>, text 또는 <video> 노드가 있습니다(예: Alacritty changelog). Jina 리더(이전에 로컬 렌더러 전에 시도됨)는 그러한 list를 잘못 추출하여 빈 Added/Changed 섹션을 반환했습니다. 네이티브 in-process 렌더러는 이제 먼저 실행되고 전체 컨텐츠를 보존합니다./usage 집계 금액 폴백이 raw limits.length를 계정 수로 사용하는 문제를 수정했습니다. 이제 limit scopes에서 고유한 accountId 값을 계산하므로 단일 계정의 N개 제한이 "N accts"로 표시되지 않습니다./usage 계정 레이블이 primary identity로 projectId를 사용하는 공급자(예: Google Antigravity, Gemini CLI)에 대해 "account N"으로 폴백하는 문제를 수정했습니다. 이제 report 메타데이터의 projectId를 일반 폴백 전에 고려합니다.todo 도구의 TUI 렌더러가 스트리밍 도구 호출 delta가 non-array ops 필드를 표시할 때 TypeError: args?.ops?.map is not a function으로 충돌하는 문제를 수정했습니다(mid-stream parseStreamingJson shapes 예: { ops: "[{" } 또는 fields가 도착하기 전의 [null] entries). 렌더러는 이제 non-array ops, non-object entries, non-array items을 충돌하는 대신 누락된 구조로 취급하며, 각 malformed delta를 따른 spam-warn cascade도 중지합니다. packages/ai의 Anthropic-side reasoning-replay fix와 쌍을 이룹니다 (#2005).agent()가 subagent runtime-limit aborts 및 기타 empty-stderr aborts를 일반적인 RuntimeError: bridge call '__agent__' failed로 축약하는 문제를 수정했습니다. runEvalAgent는 ??로 실패 메시지를 coalece했으며, 빈 stderr에서 멈추고 abortReason에 도달하지 않았으므로 loopback bridge를 통해 empty error를 전달했습니다. bridge는 이제 aborts에 대해 abortReason을 선호하고 폴백 chain에서 empty stderr/error를 제거하므로 Python은 actionable reason(예: Subagent runtime limit exceeded (task.maxRuntimeMs=900000))을 표시합니다 (#2006).TERM_FEATURES Sy 광고와 WT_SESSION(Windows Terminal / WSL)을 우선하고, 더 이상 SSH를 blanket-disable하지 않습니다(DEC 2026은 외부 터미널로 pass through됨). 위험한 multiplexer는 여전히 off로 시작하고 probe에 의존합니다. 공유된 opt-out/force resolver로 synchronizedOutputUserOverride()를 추가했습니다.logger.printTimings()(PI_TIMING 시작 트리)는 이제 두 개의 이전에 보이지 않는 영역을 표시합니다: runtime init / uncaptured pre-marker 작업을 위한 (before instrumentation) 줄과 root span의 자신의 untimed 작업을 위한 (unattributed self) 줄. 이제 보이는 top-level spans과 Total 사이의 gap이 더 이상 swallowed되지 않습니다. Total은 이제 (since first marker)로 레이블이 지정되어 window를 명시적으로 만듭니다. 복원된 module-timer.ts preload는 module spans을 보고서로 공급할 수 있습니다: 각 module은 onLoad → final top-level marker를 total로, prepended body marker → final marker를 body/TLA로, resolved static imports를 bounded dependency tree로 기록하므로 보고서는 graph wait를 실제 top-level module 작업과 분리합니다.Full Changelog: v15.9.69...v15.10.0
분량 관계로 이후 내용은 번역에서 제외했습니다. 전체 내용은 위 원문 링크에서 확인하세요.