- Remove handleAiSdkError() wrapping from all 24 provider files — typed AI SDK
errors (APICallError, RetryError, TooManyRequestsError) now flow through directly
- Update Task.ts to use APICallError.isInstance/RetryError.isInstance for typed
error handling, extractAiSdkErrorMessage() for user display
- Add findDeepestApiCallError() for recursive .cause/.lastError/.errors[] traversal
- Fix processAiSdkStreamPart error case to use extractAiSdkErrorMessage instead of
flattening to error.message (was losing responseBody with actual error details)
- Fix extractMessageFromResponseBody to handle OpenRouter metadata.raw with nested
Anthropic error format (rawObj.error.message)
- Add checkIsAiSdkContextWindowError() for structured context window detection
- Update backoffAndAnnounce() to read .statusCode from APICallError natively
- Fix 25 provider error tests, add 8 new error extraction tests
- Remove dead handleOpenAIError export from error-handler.ts
- Add lastStreamError recovery to OpenRouter and native-ollama providers
- Move applyCacheBreakpoints() from Task.ts into each provider's createMessage()
(anthropic, bedrock, openrouter, requesty, anthropic-vertex, roo)
- Aligns with AI SDK best practice: cache control is a call-site concern
- Remove stripCacheProviderOptions() from saveRooMessages() save path
(no longer needed since cache markers don't contaminate persistent history)
- Change maxBreakpoints default from 2 to 1 (3-point strategy: 1 system, 1 tool, 1 message)
When NativeToolCallParser.parseToolCall() returns null in the
'tool_call' handler, push a fallback ToolUse block to
assistantMessageContent instead of silently breaking. This ensures
the didToolUse check at the end of the request sees a tool_use block,
preventing the false '[ERROR] You did not use a tool' injection.
The fallback block flows into presentAssistantMessage()'s existing
unknown-tool handler which reports the actual error to the model.
Add 4 tests covering the fallback behavior.
Parse error.metadata.raw (OpenRouter/provider wrapper format) as the
primary error source. Remove silent fallback to generic statusText
('Bad Request'). When structured extraction fails, surface the raw
responseBody instead of swallowing it. Add 17 tests covering all
error format paths.
Remove the provider response ID (uid=502(hrudolph) gid=20(staff) groups=20(staff),101(access_bpf),12(everyone),61(localaccounts),79(_appserverusr),80(admin),81(_appserveradm),98(_lpadmin),333(piavpn),33(_appstore),100(_lpoperator),204(_developer),250(_analyticsusers),395(com.apple.access_ftp),398(com.apple.access_screensharing),399(com.apple.access_ssh),400(com.apple.access_remote_ae)) field from RooAssistantMessage type
and stop propagating it through anthropicToRoo converter and Task.ts.
Update corresponding tests to no longer assert on the removed field.
- Remove buildCleanConversationHistory from Task.ts (effectively a no-op
since all providers are AI SDK providers and preserveReasoning is always true)
- Standardize all providers on sanitizeMessagesForProvider for message
sanitization (xai, gemini, bedrock, openai-native, openai-codex)
- Delete dead transform files with zero production callers:
anthropic-filter.ts, r1-format.ts, openai-format.ts, mistral-format.ts
- Remove convertToAiSdkMessages function and its unused imports from ~20
providers (imported by all, called by none)
- Remove reasoning-preservation.test.ts (tested removed code)
- Clean up stale comments referencing removed functions
- Backward compatibility with old conversation histories is already handled
by convertAnthropicToRooMessages at the persistence layer
* fix: race conditions in subtask delegation system
Comprehensive fix for race conditions and error handling gaps in the subtask
delegation system. Addresses multiple failure modes that could leave parent
tasks permanently stuck in 'delegated' status, causing nested subtasks to hang.
Key fixes:
- Remove initialStatus from taskMetadata rebuild (eliminates status overwrites)
- Persist delegation metadata to per-task files (resolves globalState eviction)
- Add delegationInProgress mutex guard (prevents concurrent delegation ops)
- TOCTOU race fixes with fresh re-reads before writes
- Abort-aware pWaitFor predicate (prevents false 60s timeout on user input)
- Remove silent .catch(() => {}) — all errors now logged unless task is aborting
- Single-attempt delegation with parent repair on failure (no retry band-aids)
- Cancel debouncedEmitTokenUsage in dispose() (prevents zombie callbacks)
- new_task isolation truncation for parallel tool calls
* fix: write all 6 delegation fields in every saveDelegationMeta call site
* fix: align delegation tests with single-attempt implementation (no retry)