* feat: add MiniMax M2.5 model and set as default
* fix: update MiniMax M2.5 contextWindow to 204_800
* Delete .changeset/add-minimax-m25.md
---------
Co-authored-by: Roo Code <roomote@roocode.com>
Co-authored-by: Matt Rubens <mrubens@users.noreply.github.com>
* feat: restore Unbound as a provider
* Adds translations
* fix: add unbound to ClineProvider test expectations
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* fix(bedrock): enable prompt caching for custom ARN and default to ON
- Set supportsPromptCache to true for custom-arn model info in useSelectedModel.ts
- Change awsUsePromptCache default from false to true using nullish coalescing
- Add tests for custom-arn prompt caching support
Closes#10846
* fix(bedrock): align backend awsUsePromptCache default with UI (?? true)
The backend treated undefined awsUsePromptCache as falsy (OFF) while the
UI checkbox defaulted to true via nullish coalescing. This caused the UI
to show prompt caching as ON but the backend to keep it OFF for new users.
Apply the same ?? true default in the backend so both sides agree.
---------
Co-authored-by: Roo Code <roomote@roocode.com>
* feat: disable apply_diff and enable edit tool for Vertex and Gemini providers
* feat: disable apply_diff and enable edit tool for Anthropic provider
* feat: disable apply_diff and enable edit tool for Anthropic Vertex provider
* fix: remove out-of-scope Anthropic/Anthropic-Vertex changes
The PR scope is Gemini and Vertex providers only. Reverting the
Anthropic and Anthropic-Vertex tool preference changes that were
not part of the stated scope.
---------
Co-authored-by: Roo Code <roomote@roocode.com>
Replace the incorrect Sonnet 4.6 Bedrock ID with the AWS-supported
model ID in the model registry and Bedrock capability lists.
Remove references to the deprecated dated ID and update Bedrock
tests to validate the corrected Sonnet 4.6 identifier.
* Add Anthropic Claude Sonnet 4.6 support across providers
Add model definitions and capability flags for Anthropic, Bedrock,
Vertex, OpenRouter, and Vercel AI Gateway.
Update Anthropic handler and UI model selection logic to support Claude
Sonnet 4.6 1M context behavior and tier pricing.
Add focused tests for provider handlers, fetchers, and selected-model
hooks.
Keep Bedrock UI tier pricing parity as-is because this is a
pre-existing issue for Opus 4.6 and will be handled separately.
Reference:
- https://www.anthropic.com/news/claude-sonnet-4-6
- https://platform.claude.com/docs/en/about-claude/models/overview#latest-models-comparison
* Delete .changeset/soft-carpets-hunt.md
---------
Co-authored-by: Hannes Rudolph <hrudolph@gmail.com>
* fix: correct Bedrock model ID for Claude Opus 4.6 (#11232)
Remove the :0 suffix from the Claude Opus 4.6 model ID to match
the correct AWS Bedrock model identifier.
The model ID was "anthropic.claude-opus-4-6-v1:0" but should be
"anthropic.claude-opus-4-6-v1" per AWS Bedrock documentation.
Fixes#11231
Co-authored-by: Roo Code <roomote@roocode.com>
* fix: guard against empty-string baseURL in provider constructors (#11233)
When the 'custom base URL' checkbox is unchecked in the UI, the setting
is set to '' (empty string). Providers that passed this directly to their
SDK constructors caused 'Failed to parse URL' errors because the SDK
treated '' as a valid but broken base URL override.
- gemini.ts: use || undefined (was passing raw option)
- openai-native.ts: use || undefined (was passing raw option)
- openai.ts: change ?? to || for fallback default
- deepseek.ts: change ?? to || for fallback default
- moonshot.ts: change ?? to || for fallback default
Adds test coverage for Gemini and OpenAI Native constructors verifying
empty-string baseURL is coerced to undefined.
* fix: make defaultTemperature required in getModelParams to prevent silent temperature overrides (#11218)
* fix: DeepSeek temperature defaulting to 0 instead of 0.3
Pass defaultTemperature: DEEP_SEEK_DEFAULT_TEMPERATURE to getModelParams() in
DeepSeekHandler.getModel() to ensure the correct default temperature (0.3)
is used when no user configuration is provided.
Closes#11194
* refactor: make defaultTemperature required in getModelParams
Make the defaultTemperature parameter required in getModelParams() instead
of defaulting to 0. This prevents providers with their own non-zero default
temperature (like DeepSeek's 0.3) from being silently overridden by the
implicit 0 default.
Every provider now explicitly declares its temperature default, making the
temperature resolution chain clear:
user setting → model default → provider default
---------
Co-authored-by: Roo Code <roomote@roocode.com>
Co-authored-by: daniel-lxs <ricciodaniel98@gmail.com>
* feat: batch consecutive tool calls in chat UI with shared utility (#11245)
* feat: group consecutive list_files tool calls into single UI block
Consolidate consecutive listFilesTopLevel/listFilesRecursive ask messages
into a single 'Roo wants to view multiple directories' block, matching the
existing read_file batching pattern.
* chore: add missing translation keys for all locales
* refactor: consolidate duplicate listFiles batch-handling blocks in ChatRow
Merge the separate listFilesTopLevel and listFilesRecursive case blocks
into a single combined case with shared batch-detection logic, selecting
the icon and translation key based on the tool type. This removes the
duplicated isBatchDirRequest check and BatchListFilesPermission render.
* feat: batch consecutive file-edit tool calls into single UI block
Add edit-file batching in ChatView groupedMessages that consolidates
consecutive editedExistingFile, appliedDiff, newFileCreated,
insertContent, and searchAndReplace asks into a single BatchDiffApproval
block. Move batchDiffs detection in ChatRow above the switch statement
so it applies to any file-edit tool type.
* refactor: extract batchConsecutive utility, fix batch UI issues
- Extract generic batchConsecutive() utility from 3 identical while-loops
- Fix React key collisions in BatchListFilesPermission, BatchFilePermission, BatchDiffApproval
- Normalize language prop to "shellsession" (was "shell-session" for top-level)
- Remove unused _batchedMessages property from synthetic messages
- Remove dead didViewMultipleDirectories i18n key from all 18 locale files
- Add batch button text for listFilesTopLevel/listFilesRecursive
- Add batchConsecutive utility tests (6 cases)
* fix: audit improvements for batch tool-call UI
- Make batchConsecutive() generic instead of ClineMessage-specific
- Add batch-aware button text for edit-file batches ("Save All"/"Deny All")
- Add dedicated list-batch/edit-batch i18n keys (stop reusing read-batch)
- Add JSON.parse defense-in-depth in all three synthesizers
- Fix mixed list_files batch icon to default to FolderTree
- Add 6 missing test cases (all-match, immutability, spy, single-dir)
* chore: minor type cleanup (out-of-scope housekeeping)
- Trim unused recursive/isOutsideWorkspace from DirPermissionItem interface
- Remove 4 pre-existing `as any` casts in ChatView.tsx:
- window cast → precise inline type
- checkpoint bracket access → removed unnecessary casts
- condensing message → `as ClineMessage`
- debounce cancel → `.clear()` (correct API)
- Update BatchListFilesPermission test data to match trimmed interface
* i18n: add list-batch and edit-batch translations for all locales
* feat: add IPC query handlers for commands, modes, and models (#11279)
Add GetCommands, GetModes, and GetModels to the IPC protocol so external
clients can fetch slash commands, available modes, and Roo provider models
without going through the internal webview message channel.
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* feat: add lock toggle to pin API config across all modes in workspace (#11295)
* feat: add lock toggle to pin API config across all modes in workspace
Add a lock/unlock toggle inside the API config selector popover (next to
the settings gear) that, when enabled, applies the selected API
configuration to all modes in the current workspace.
- Add lockApiConfigAcrossModes to ExtensionState and WebviewMessage types
- Store setting in workspaceState (per-workspace, not global)
- When locked, activateProviderProfile sets config for all modes
- Lock icon in ApiConfigSelector popover bottom bar next to gear
- Full i18n: English + 17 locale translations (all mention workspace scope)
- 9 new tests: 2 ClineProvider, 2 handler, 5 UI (77 total pass)
* refactor: replace write-fan-out with read-time override for lock API config
The original lock implementation used setModeConfig() fan-out to write the
locked config to ALL modes globally. Since the lock flag lives in workspace-
scoped workspaceState but modeApiConfigs are in global secrets, this caused
cross-workspace data destruction.
Replaced with read-time guards:
- handleModeSwitch: early return when lock is on (skip per-mode config load)
- createTaskWithHistoryItem: skip mode-based config restoration under lock
- activateProviderProfile: removed fan-out block
- lockApiConfigAcrossModes handler: simplified to flag + state post only
- Fixed pre-existing workspaceState mock gap in ClineProvider.spec.ts and
ClineProvider.sticky-profile.spec.ts
* fix: validate Gemini thinkingLevel against model capabilities and handle empty streams (#11303)
* fix: validate Gemini thinkingLevel against model capabilities and handle empty streams
getGeminiReasoning() now validates the selected effort against the model's
supportsReasoningEffort array before sending it as thinkingLevel. When a
stale settings value (e.g. 'medium' from a different model) is not in the
supported set, it falls back to the model's default reasoningEffort.
GeminiHandler.createMessage() now tracks whether any text content was
yielded during streaming and handles NoOutputGeneratedError gracefully
instead of surfacing the cryptic 'No output generated' error.
* fix: guard thinkingLevel fallback against 'none' effort and add i18n TODO
The array validation fallback in getGeminiReasoning() now only triggers
when the selected effort IS a valid Gemini thinking level but not in
the model's supported set. Values like 'none' (explicit no-reasoning
signal) are no longer overridden by the model default.
Also adds a TODO for moving the empty-stream message to i18n.
* fix: track tool_call_start in hasContent to avoid false empty-stream warning
Tool-only responses (no text) are valid content. Without this,
agentic tool-call responses would incorrectly trigger the empty
response warning message.
* chore(cli): prepare release v0.0.53 (#11425)
* feat: add GLM-5 model support to Z.ai provider (#11440)
* chore: regenerate pnpm-lock.yaml
* fix: resolve type errors and remove AI SDK test contamination
* docs: update progress.txt with rebuilt Batch 2 status
---------
Co-authored-by: roomote[bot] <219738659+roomote[bot]@users.noreply.github.com>
Co-authored-by: Roo Code <roomote@roocode.com>
Co-authored-by: daniel-lxs <ricciodaniel98@gmail.com>
Co-authored-by: Chris Estreich <cestreich@gmail.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* fix: add image content support to MCP tool responses (#10874)
Co-authored-by: Roo Code <roomote@roocode.com>
* fix: transform tool blocks to text before condensing (EXT-624) (#10975)
* refactor(read_file): Codex-inspired read_file refactor EXT-617 (#10981)
* feat: allow import settings in initial welcome screen (#10994)
Co-authored-by: Roo Code <roomote@roocode.com>
Co-authored-by: Matt Rubens <mrubens@users.noreply.github.com>
* fix(code-index): remove deprecated text-embedding-004 and migrate to gemini-embedding-001 (#11038)
Co-authored-by: Roo Code <roomote@roocode.com>
Co-authored-by: Hannes Rudolph <hrudolph@gmail.com>
* chore: treat extension .env as optional (#11116)
* fix: sanitize tool_use_id in tool_result blocks to match API history (#11131)
Tool IDs from providers like Gemini/OpenRouter contain special characters
(e.g., 'functions.read_file:0') that are sanitized when saving tool_use
blocks to API history. However, tool_result blocks were using the original
unsanitized IDs, causing ToolResultIdMismatchError.
This fix ensures tool_result blocks use sanitizeToolUseId() to match the
sanitized tool_use IDs in conversation history.
Fixes EXT-711
* fix: queue messages during command execution instead of losing them (#11140)
* IPC fixes for task cancellation and queued messages (#11162)
* feat: add support for AGENTS.local.md personal override files (#11183)
Co-authored-by: Roo Code <roomote@roocode.com>
Co-authored-by: roomote[bot] <219738659+roomote[bot]@users.noreply.github.com>
* fix(cli): resolve race condition causing provider switch during mode changes (#11205)
When using slash commands with `mode:` frontmatter (e.g., `/cli-release`
with `mode: code`), the CLI would fail with "Could not resolve
authentication method" from the Anthropic SDK, even when using a
non-Anthropic provider like `--provider roo`.
Root cause: In `markWebviewReady()`, the `webviewDidLaunch` message was
sent before `updateSettings`, creating a race condition. The
`webviewDidLaunch` handler's "first-time init" sync would read
`getState()` before CLI-provided settings were applied to the context
proxy. Since `getState()` defaults `apiProvider` to "anthropic" when
unset, this default was saved to the provider profile. When a slash
command triggered `handleModeSwitch()`, it found this corrupted profile
with `apiProvider: "anthropic"` (but no API key) and activated it,
overwriting the CLI's working roo provider configuration.
Fix:
1. Reorder `markWebviewReady()` to send `updateSettings` before
`webviewDidLaunch`, ensuring the context proxy has CLI-provided
values when the initialization handler runs.
2. Guard the first-time init sync with `checkExistKey(apiConfiguration)`
to prevent saving a profile with only the default "anthropic"
fallback and no actual API keys configured.
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
* chore: remove dead toolFormat code from getEnvironmentDetails (#11207)
Remove the toolFormat constant and <tool_format> line from environment
details output. Native tool calling is now the only supported protocol,
making this code unnecessary.
Fixes#11206
Co-authored-by: Roo Code <roomote@roocode.com>
* feat: extract translation and merge resolver modes into reusable skills (#11215)
* feat: extract translation and merge resolver modes into reusable skills
- Add roo-translation skill with comprehensive i18n guidelines
- Add roo-conflict-resolution skill for intelligent merge conflict resolution
- Add /roo-translate slash command as shortcut for translation skill
- Add /roo-resolve-conflicts slash command as shortcut for conflict resolution skill
The existing translate and merge-resolver modes are preserved. These new skills
and commands provide reusable access to the same functionality.
Closes CLO-722
* feat: add guidances directory with translator guidance file
- Add .roo/guidances/roo-translator.md for brand voice, tone, and word choice guidance
- Update roo-translation skill to reference the guidance file
The guidance file serves as a placeholder for translation style guidelines
that will be interpolated at runtime.
* fix: rename guidances directory to guidance (singular)
* fix: remove language-specific section from translator guidance
The guidance file should focus on brand voice, tone, and word choice only.
* fix: remove language-specific guidelines section from skill file
* Update .roo/skills/roo-translation/SKILL.md
Co-authored-by: roomote[bot] <219738659+roomote[bot]@users.noreply.github.com>
---------
Co-authored-by: Roo Code <roomote@roocode.com>
Co-authored-by: Bruno Bergher <bruno@roocode.com>
Co-authored-by: roomote[bot] <219738659+roomote[bot]@users.noreply.github.com>
* feat: add Claude Opus 4.6 support across all providers (#11224)
* feat: add Claude Opus 4.6 support across all providers
Add Claude Opus 4.6 (claude-opus-4-6) model definitions and 1M context
support across Anthropic, Bedrock, Vertex AI, OpenRouter, and Vercel AI
Gateway providers.
- Anthropic: 128K max output, /5 pricing, 1M context tiers
- Bedrock: anthropic.claude-opus-4-6-v1:0 with 1M context + global inference
- Vertex: claude-opus-4-6 with 1M context tiers
- OpenRouter: prompt caching + reasoning budget sets
- Vercel AI Gateway: Opus 4.5 and 4.6 added to capability sets
- UI: 1M context checkbox for Opus 4.6 on all providers
- i18n: Updated 1M context descriptions across 18 locales
Also adds Opus 4.5 to Vercel AI Gateway (previously missing) and
OpenRouter maxTokens overrides for Opus 4.5/4.6.
Closes#11223
* fix: apply tier pricing when 1M context is enabled on Bedrock
When awsBedrock1MContext is enabled for tiered models like Opus 4.6,
also apply the 1M tier pricing (inputPrice, outputPrice, cache prices)
instead of only updating contextWindow. This ensures cost calculations
and UI display use the correct >200K rates.
* feat: add gpt-5.3-codex model to OpenAI Codex provider (#11225)
feat: add gpt-5.3-codex model and make it default for OpenAI Codex provider
Co-authored-by: Roo Code <roomote@roocode.com>
* fix: prevent parent task state loss during orchestrator delegation (#11281)
* fix: make removeClineFromStack() delegation-aware to prevent orphaned parent tasks (#11302)
* fix: make removeClineFromStack() delegation-aware to prevent orphaned parent tasks
When a delegated child task is removed via removeClineFromStack() (e.g., Clear
Task, navigate to history, start new task), the parent task was left orphaned
in "delegated" status with a stale awaitingChildId. This made the parent
unresumable without manual history repair.
This fix captures parentTaskId and childTaskId before abort/dispose, then
repairs the parent metadata (status -> active, clear awaitingChildId) when
the popped task is a delegated child and awaitingChildId matches.
Parent lookup + updateTaskHistory are wrapped in try/catch so failures are
non-fatal (logged but do not block the pop).
Closes#11301
* fix: add skipDelegationRepair opt-out to removeClineFromStack() for nested delegation
---------
Co-authored-by: Roo Code <roomote@roocode.com>
* fix(reliability): prevent webview postMessage crashes and make dispose idempotent (#11313)
* fix(reliability): prevent webview postMessage crashes and make dispose idempotent
Closes: #11311
1. postMessageToWebview() now catches rejections from
webview.postMessage() so that messages sent after the webview is
disposed do not surface as unhandled promise rejections.
2. dispose() is guarded by a _disposed flag so that repeated calls
(e.g. during rapid extension deactivation) are no-ops.
3. CloudService mock in ClineProvider.spec.ts updated to include
off() — a pre-existing gap exposed by the new dispose test.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: add early _disposed check in postMessageToWebview
Skip the postMessage call entirely when the provider is already disposed,
avoiding unnecessary try/catch execution. Added test coverage for this path.
* chore: trigger CI
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: daniel-lxs <ricciodaniel98@gmail.com>
* fix: resolve race condition in new_task delegation that loses parent task history (#11331)
* fix: resolve race condition in new_task delegation that loses parent task history
When delegateParentAndOpenChild creates a child task via createTask(), the
Task constructor fires startTask() as a fire-and-forget async call. The child
immediately begins its task loop and eventually calls saveClineMessages() →
updateTaskHistory(), which reads globalState, modifies it, and writes back.
Meanwhile, delegateParentAndOpenChild persists the parent's delegation
metadata (status: 'delegated', delegatedToId, awaitingChildId, childIds) via
a separate updateTaskHistory() call AFTER createTask() returns.
These two concurrent read-modify-write operations on globalState race: the
last writer wins, overwriting the other's changes. When the child's write
lands last, the parent's delegation fields are lost, making the parent task
unresumable when the child finishes.
Fix: create the child task with startTask: false, persist the parent's
delegation metadata first, then manually call child.start(). This ensures
the parent metadata is safely in globalState before the child begins writing.
* docs: clarify Task.start() only handles new tasks, not history resume
* fix: serialize taskHistory writes and fix delegation status overwrite race (#11335)
Add a promise-chain mutex (withTaskHistoryLock) to serialize all
read-modify-write operations on taskHistory, preventing concurrent
interleaving from silently dropping entries.
Reorder reopenParentFromDelegation to close the child instance
before marking it completed, so the abort path's stale 'active'
status write no longer overwrites the 'completed' state.
Covered by new tests: RPD-04/05/06, UTH-02/04, and a full mutex
concurrency suite.
* Fix task resumption in the API module (#11369)
* chore: clean up repo-facing mode rules (#11410)
* fix: add maxReadFileLine to ExtensionState type for webview compatibility
---------
Co-authored-by: roomote[bot] <219738659+roomote[bot]@users.noreply.github.com>
Co-authored-by: Roo Code <roomote@roocode.com>
Co-authored-by: Daniel <57051444+daniel-lxs@users.noreply.github.com>
Co-authored-by: Matt Rubens <mrubens@users.noreply.github.com>
Co-authored-by: Chris Estreich <cestreich@gmail.com>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Co-authored-by: Bruno Bergher <bruno@roocode.com>
Co-authored-by: 0xMink <dennis@dennismink.com>
Co-authored-by: daniel-lxs <ricciodaniel98@gmail.com>
Revert to pre-AI-SDK state (commit 67e568f6b)
This commit reverts the codebase to the state before AI SDK migration work began.
Target commit: 67e568f6b - refactor: replace fetch_instructions with skill tool and built-in skills (#10913)
Date: January 29, 2026
This removes approximately 152 commits of AI SDK migration work.
A follow-up PR will add back bug fixes and features that are unrelated to AI SDK.
Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
* feat: migrate LiteLLM provider to AI SDK (@ai-sdk/openai-compatible)
- Replace raw OpenAI SDK (RouterProvider) with Vercel AI SDK's
createOpenAICompatible via OpenAICompatibleHandler base class
- Retain dynamic model fetching from LiteLLM server via /v1/model/info
- Use centralized getModelMaxOutputTokens() to cap output tokens at 20%
of context window, preventing overflow errors
- Remove LiteLLM-specific workarounds (Gemini thought signature injection,
prompt cache control headers) now handled by the proxy or AI SDK
- Rewrite tests to mock AI SDK (streamText, generateText) instead of
raw OpenAI SDK
* fix: call fetchModel() in completePrompt() before execution
Addresses review feedback - completePrompt() now fetches models
before executing to ensure correct model info for token limits,
matching the behavior of createMessage().
* refactor: migrate LM Studio provider to Vercel AI SDK
Migrate LmStudioHandler from raw OpenAI SDK to Vercel AI SDK via
OpenAICompatibleHandler base class.
Changes:
- Extend OpenAICompatibleHandler instead of BaseProvider
- Use createOpenAICompatible from @ai-sdk/openai-compatible
- Use streamText/generateText from ai package
- Add extractReasoningMiddleware for <think> tag extraction parity
- Pass draft_model via providerOptions for speculative decoding
- Remove unused getLmStudioModels function (active version in fetchers/)
- Update all tests to mock AI SDK instead of OpenAI SDK
* fix: wrap completePrompt with handleAiSdkError for consistent error handling
---------
Co-authored-by: Roo Code <roomote@roocode.com>
Replace @anthropic-ai/vertex-sdk with @ai-sdk/google-vertex/anthropic,
using streamText/generateText from the Vercel AI SDK for consistent
provider behavior.
Changes:
- Use createVertexAnthropic from @ai-sdk/google-vertex/anthropic
- Use streamText/generateText instead of direct Anthropic API calls
- Add AI SDK transform utilities for message/tool conversion
- Handle cache control via AI SDK providerOptions
- Handle thinking/reasoning via providerOptions.anthropic.thinking
- Add thought signature and redacted thinking block tracking
- Set isAiSdkProvider() to return true
- Remove unused deps: @anthropic-ai/vertex-sdk, google-auth-library
- Rewrite tests to mock AI SDK instead of @anthropic-ai/vertex-sdk
* Latest main branch snapshot from API
* feat: add dedicated Azure OpenAI provider using @ai-sdk/azure package
* feat: add Azure provider UI component and translations
* feat: add Azure provider translations for all locales
* chore: add missing Azure placeholder translations
* Delete .changeset/azure-ai-sdk-migration.md
* fix: add Azure provider validation for onboarding workflow
- Add azureApiKey to SECRET_STATE_KEYS for proper configuration detection
- Add Azure validation case in validateModelsAndKeysProvided
- Add validation translations for azureResourceName and azureDeploymentName across all 18 locales
This fixes the issue where the Finish button does nothing when setting up Azure provider in the onboarding workflow.
* feat(azure): add model metadata, model picker, rename to Azure AI Foundry
- Add static model metadata for 29 Azure models (from models.dev)
with Roo-specific flags (reasoning, tools, verbosity) matching
openAiNativeModels
- Add model picker dropdown to Azure provider settings for model
capability detection (context window, max tokens, pricing)
- Rename provider label from 'Azure OpenAI' to 'Azure AI Foundry'
across all 18 locales
- Make API key optional (supports Azure managed identity / Entra ID)
- Update default API version from 2024-08-01-preview to 2025-04-01-preview
- Fix maxOutputTokens validation (filter invalid values <= 0)
- Handler separates deployment name (API calls) from model ID
(capability lookup) with azureDefaultModelInfo (gpt-4o) fallback
- Remove unhelpful 'Get Azure AI Foundry Access' button
- Prevent stale model IDs from other providers carrying over
- Suppress validation errors on fresh provider selection
* fix(azure): add missing isAiSdkProvider() override for reasoning block preservation
* Azure Fixes for Hannes
* Quick Fix for Respones API Only (for Hannes)
* fix: use explicit azureOpenAiDefaultApiVersion fallback when apiVersion is empty
Addresses review feedback: the UI placeholder shows '2025-04-01-preview' via
azureOpenAiDefaultApiVersion, so the handler should use the same constant as
fallback instead of silently deferring to the SDK's internal default.
* fix: remove stale Cerebras references (retired provider)
* fix: add missing retiredProviderMessage translations for all locales
* fix: do not map promptCacheMissTokens to cacheWriteTokens for Azure
Azure uses OpenAI-compatible caching which does not report cache write
tokens separately. promptCacheMissTokens represents tokens NOT found in
cache (processed from scratch), not tokens written to cache. This aligns
the Azure handler with the OpenAI native handler behavior.
---------
Co-authored-by: Hannes Rudolph <hrudolph@gmail.com>
Co-authored-by: Roo Code <roomote@roocode.com>
Co-authored-by: daniel-lxs <ricciodaniel98@gmail.com>
Co-authored-by: Matt Rubens <mrubens@users.noreply.github.com>
* feat: migrate OpenAI Native provider to @ai-sdk/openai
Replace the raw OpenAI SDK (openai) usage in OpenAiNativeHandler with
@ai-sdk/openai and AI SDK's streamText/generateText, following the same
pattern used by other migrated providers (Groq, xAI, Fireworks, etc.).
Key changes:
- Use createOpenAI from @ai-sdk/openai with provider.responses() for
the Responses API
- Use streamText/generateText from ai for streaming and completions
- Pass OpenAI-specific features via providerOptions.openai (store,
reasoningEffort, reasoningSummary, textVerbosity, serviceTier,
promptCacheRetention, parallelToolCalls, include)
- Capture responseId, serviceTier, and encrypted reasoning content
from providerMetadata after streaming
- Preserve getEncryptedContent() and getResponseId() for Task.ts
- Preserve service tier pricing adjustment in cost calculation
- Mark as isAiSdkProvider: true
- Eliminate ~1100 lines of manual SSE parsing, raw fetch fallback,
and event handling code
- Rewrite all 3 test files to use AI SDK mocking pattern
* fix: remove non-existent cacheWriteTokens from providerMetadata
The OpenAI Responses API does not report cache write tokens separately.
Remove the reference to providerMetadata?.openai?.cacheWriteTokens which
does not exist in the @ai-sdk/openai provider metadata schema.
* fix: filter standalone encrypted reasoning items from messages
Task.ts buildCleanConversationHistory injects standalone reasoning items
with { type: 'reasoning', encrypted_content: '...' } into the messages
array. These have no 'role' property and would be silently dropped by
convertToAiSdkMessages. Filter them explicitly to prevent confusion.
Note: Encrypted reasoning content round-tripping for stateless continuity
is a known limitation of the AI SDK migration. The @ai-sdk/openai
provider does not support injecting raw Responses API reasoning items.
Plain-text reasoning round-tripping works correctly via isAiSdkProvider().
* fix: restore reasoning round-trip for OpenAI Responses API via AI SDK
- Strip plain-text reasoning blocks from assistant messages before
convertToAiSdkMessages() to eliminate 'Non-OpenAI reasoning parts'
warnings from @ai-sdk/openai Responses provider
- Re-inject encrypted reasoning items as AI SDK reasoning parts with
providerOptions.openai.itemId and reasoningEncryptedContent, restoring
reasoning continuity that was silently broken after the migration
- Restructure createMessage() into a 5-step pipeline:
collect → filter → strip → convert → inject
- Add 21 new tests for both plain-text stripping and encrypted
reasoning injection
---------
Co-authored-by: Hannes Rudolph <hrudolph@gmail.com>
* refactor: migrate Anthropic provider to @ai-sdk/anthropic
Replace the raw @anthropic-ai/sdk implementation with @ai-sdk/anthropic
(Vercel AI SDK) for consistency with other providers (Bedrock, DeepSeek,
Mistral, etc.).
Changes:
- Replace Anthropic() client with createAnthropic() from @ai-sdk/anthropic
- Replace manual stream parsing with streamText() + processAiSdkStreamPart()
- Replace client.messages.create() with generateText() for completePrompt()
- Use convertToAiSdkMessages() and convertToolsForAiSdk() for format conversion
- Handle prompt caching via AI SDK providerOptions (cacheControl on messages)
- Handle extended thinking via providerOptions.anthropic.thinking
- Add getThoughtSignature() and getRedactedThinkingBlocks() for thinking
signature round-tripping (matching Bedrock pattern, improves on original
which had a TODO for this)
- Add isAiSdkProvider() returning true
- Update tests to mock @ai-sdk/anthropic and ai instead of raw SDK
* fix: address PR review - remove apiKey fallback and use system+systemProviderOptions pattern