- Add 17 new Codex-related i18n keys across all locale files
- Replace hardcoded English strings in OAuth flow with i18n lookups
- Internationalize Codex error messages in `errors.go`
- Localize token exchange and refresh failure messages
- Translate OAuth callback server responses and browser fallback text
- Add translations for usage limit and request status errors
- Cover DE, EN, ES, FA, FR, IT, JA, PL, PT-BR, PT-PT, ZH locales
- Add `context.Context` parameter to `ListModels` interface method
- Add `context.Context` parameter to `SendStream` interface method
- Thread caller context through `Chatter.Send` instead of using `context.Background()`
- Update all vendor implementations to accept context parameter
- Introduce `publicError` type wrapping Codex provider errors
- Normalize Codex error messages to lowercase for consistency
- Add context-aware `sendStreamUpdate` helper in Codex client
- Remove stale `context.Background()` calls from Anthropic and Azure AI Gateway
- Update all vendor test mocks and stubs with new signatures
- Pass HTTP request context from server handler into `chatter.Send`
- Remove OAuth flow, PKCE, and token refresh from codex.go
- Remove auth transport round-trip retry logic
- Remove unused OAuth types and helper structs
- Remove JWT parsing and token expiry utilities
- Remove error mapping and usage limit detection helpers
- Remove browser-open and version normalization functions
- Add `.maestro/` directory to `.gitignore`
- Add test for `SendStream` HTTP error mapping and channel close
- Clean up unused imports from codex client package
- Bump `anthropic-sdk-go` from v1.23.0 to v1.27.1
- Upgrade AWS SDK Go v2 packages to latest patch versions
- Update `gin-gonic/gin` to v1.12.0 and `go-git` to v5.17.0
- Bump `ollama/ollama` from v0.16.2 to v0.18.2
- Upgrade `google.golang.org/api` to v0.272.0 and `genai` to v1.51.0
- Update OpenTelemetry packages to v1.42.0/v0.67.0
- Bump `golang.org/x` packages to latest minor versions
- Remove deprecated `ModelClaude4Sonnet20250514` and `ModelClaude4Opus20250514` aliases
- Add `go.mongodb.org/mongo-driver/v2` as new indirect dependency
- Add MiniMax-M2.7 and MiniMax-M2.7-highspeed to static model list
- Place M2.7 models at the top of the list as new defaults
- Retain all previous models (M2.5, M2.5-highspeed, M2.5-lightning, M2, M2.1, M2.1-lightning) as alternatives
MiniMax-M2.7 is the latest flagship model with enhanced reasoning and coding capabilities.
## Bug: Streaming Deadlock in Chatter.Send
When a streaming error occurs, two goroutines can race to write to the
same buffered(1) error channel:
1. The SendStream goroutine returns an error and writes to errChan
2. The stream-update loop receives a StreamTypeError update and also
writes to errChan
Since errChan has a buffer of 1, the second write blocks forever,
causing a goroutine leak and a deadlock — the caller never returns.
### Fix
Introduce `recordFirstStreamError()` which uses a non-blocking
select/default to safely send only the first error, discarding
subsequent ones. This prevents the deadlock while preserving the
original error for the caller.
### Scenario that triggers the deadlock (before this fix):
1. Vendor stream emits a StreamTypeError update (e.g., rate limit)
2. The update loop writes the error to errChan (buffer fills)
3. SendStream also returns an error
4. SendStream goroutine tries to write to errChan → BLOCKS FOREVER
5. Chatter.Send never returns → user sees a hang
## Refactor: Unify Strategy Handling (Server + CLI)
The REST API server (chat.go) was loading strategy prompts inline by
reading JSON files directly with os.ReadFile, bypassing the core
Chatter layer entirely. This caused:
- Strategy prompts were prepended to UserInput instead of the system
message, breaking the prompt architecture
- The StrategyName was not passed to GetChatter(), so the core layer
had no knowledge of the strategy
- Duplicate strategy-loading logic between CLI and server paths
### Fix
- Pass StrategyName through to GetChatter() and ChatRequest so the
core Chatter.BuildSession() handles strategy loading uniformly
- Extract `buildPromptChatRequest()` helper for clean request
construction
- Remove inline os.ReadFile strategy loading from the server handler
## Refactor: Clean System Message Assembly
Replace raw string concatenation of context + pattern + strategy
prompts with `joinPromptSections()` which:
- Trims whitespace from each section
- Skips empty sections (no double newlines from missing context)
- Joins with a single newline separator
## Tests Added
- `TestChatter_BuildSession_SeparatesSystemSections`: Verifies
strategy, context, and pattern are joined with newline separators
in the correct order
- `TestChatter_Send_StreamingErrorUpdateAndReturnDoesNotDeadlock`:
Regression test with 2-second timeout that catches the deadlock
when both error paths fire simultaneously
- `TestBuildPromptChatRequest_PreservesStrategyAndUserInput`: Verifies
the extracted helper preserves all fields including StrategyName
- Add new Codex AI vendor plugin with OpenAI OAuth PKCE flow
- Implement browser-based login with automatic token refresh on 401
- Register Codex client in the plugin registry
- Allow explicit Codex model selection bypassing model listing
- Expose shared OpenAI `BuildResponseParams` and `ExtractText` helpers
- Move system/developer messages into Codex `instructions` field
- Add Codex i18n strings across all supported locales
- Add comprehensive unit tests for Codex OAuth, streaming, and retry
- Update README with Codex feature entry and provider listing
- Trim older changelog entries from README recent features section
- Fetch Bedrock regions dynamically from botocore endpoints.json (public, no auth)
Shows 40+ regions instead of hardcoded 6. Falls back to static list on error.
- Fix AWS_PROFILE env var conflict: users with AWS_PROFILE set for other tools
(terraform, aws-cli) would get 'failed to get shared config profile' errors
when using explicit ABSK or static credentials.
- Handle empty auth choice gracefully (skip instead of error)
Follow-up to #2044.
- add `maskAPIKey` to redact all but last 4 chars of API keys (CWE-200)
- add `isRedacted` guard to prevent writing masked values back to `.env`
- mask all provider API keys in `GET /config` response payload
- sanitize note filenames with `basename` and allowlist regex (CWE-78, CWE-22)
- replace `exec`/shell commands in obsidian route with native `fs` APIs
- remove `escapeShellArg` helper now that shell execution is fully eliminated
- add path-confinement double-check ensuring resolved paths stay within target dirs
- sanitize note filenames in notes route using `basename` to block path traversal (CWE-22)
- return `safeFilename` instead of raw user input in notes POST response
- Add `GetRaw` method to `PatternsEntity` for unprocessed pattern retrieval
- Replace inline raw pattern loading logic in server handler with `GetRaw`
- Remove manual `Pattern` struct construction from `PatternsHandler.Get`
- Simplify server handler by delegating storage access to database layer
- Add test coverage for `GetRaw` with custom patterns directory
Add 3-tier authentication for AWS Bedrock:
1. Bearer token (ABSK) - simplest, same as Claude Code
2. Static AWS credentials (access key + secret key)
3. Default AWS credential chain (existing behavior)
- Remove hasAWSCredentials() gate so Bedrock always appears in setup
- Custom guided Setup() flow: auth method, region, model
- Bearer token transport with token redaction
- Nil guards for uninitialized clients
- Temperature-only fix (no top_p) for Claude on Bedrock
- API key masking during re-setup
- Fallback model list when ListFoundationModels API is inaccessible
- i18n support for 11 locales (3 new keys each)
- 25 unit tests
- Add git CLI fallback when go-git in-memory clone fails
- Detect git CLI availability via `exec.LookPath` before fallback
- Extract `fetchFilesViaGoGit` into dedicated helper function
- Implement `fetchFilesViaGitCLI` using shallow `--depth 1` clone
- Use temp directory for CLI clone with deferred cleanup
- Add `copyFile` helper to support CLI-based file extraction
- Respect `SingleDirectory` and `PathPrefix` opts in CLI path
- Surface combined error when both go-git and CLI fallback fail
- Remove redundant inline comments from go-git implementation
- Add default `NeedsRawMode` method to shared `PluginBase` struct
- Remove redundant `NeedsRawMode` implementations across all AI vendor plugins
- Consolidate default `false` return logic into single base plugin method
- Clean up duplicate boilerplate from anthropic, bedrock, copilot, gemini plugins
- Remove identical implementations from azureaigateway, vertexai, lmstudio, dryrun
This commit addresses all review feedback from PR #2014 and adds
configurable API version support for Azure OpenAI backend.
PR Review Fixes:
- Add URL validation with HTTPS enforcement (ISC-C7)
- Implement cancellable context in SendStream with 300s timeout (ISC-C6)
- Add response body size limit (10MB) using io.LimitReader (ISC-C12)
- Update error body truncation from 200 to 500 characters (ISC-C13)
- Lowercase error messages per Go convention (ISC-C15)
- Add file-level documentation to all backend files (ISC-C14)
- Fix Bedrock max_tokens to respect opts.MaxTokens with fallback (ISC-C5)
- Document temperature/top_p mutual exclusivity in Bedrock (ISC-C11)
- Add debug logging when empty messages are skipped (ISC-C16)
- Add error check for empty message lists across all backends
- Verify and document Vertex AI endpoint path for APIM routing (ISC-C9)
- Update Azure OpenAI API version to 2025-04-01-preview (ISC-C10)
New Feature - Configurable API Version:
- Add APIVersion field to Client struct for Azure OpenAI backend
- Add optional setup question for API version (default: 2025-04-01-preview)
- Update AzureOpenAIBackend to accept and use configurable API version
- Maintain backward compatibility: empty version defaults to 2025-04-01-preview
- Add test coverage for custom API version and backward compatibility
- Update all existing tests to work with new backend signature
Test Coverage: 89.1% (maintained from 89.0%)
All 52 tests passing (49 existing + 3 new API version tests)
Internationalization polish: add AzureAIGateway locale strings across all 10 languages
- Add `azureaigateway_*` i18n keys to all 10 locale files
- Replace hardcoded error strings with `i18n.T()` calls
- Internationalize setup question prompts for gateway configuration
- Add `errors.New` in place of `fmt.Errorf` for static error strings
- Fix `url.QueryEscape` for API version query parameter encoding
- Correct `claude-opus-4-6-v1` model ID to include `:0` suffix
- Add error case for empty Bedrock text content blocks in `ParseResponse`
- Add test for Bedrock `ParseResponse` with no text content blocks
- Add `SendStream` context limitation note as inline code comment
- Truncate debug error body log output at 2000 characters
## CHANGES
- Add `Wire` log level constant to debug level enum
- Expose `GetLevel()` function for safe concurrent level reads
- Log outbound message roles and content at wire debug level
- Log inbound stream updates and token usage at wire level
- Log non-streaming LLM responses at wire debug level
- Update `--debug` flag description to include new level 4
- Update `set_debug_level` locale strings across all 10 languages
- Add three new DigitalOcean error message translation keys across all locales
- Add plugin registry vendor and setup default translation keys
- Move misplaced locale entries into correct alphabetical order
- Replace hardcoded English error strings with `i18n.T()` calls in DigitalOcean client
- Sort Go import statements alphabetically in YouTube tool
- Replace `fmt.Errorf("%s", ...)` with `errors.New()` across all packages
- Add `errors` import where needed, remove unused `fmt` imports
- Lowercase error message strings in i18n locale files for Go conventions
- Add `plugin_registry_run_setup_select_defaults` i18n key for setup prompt
- Add `plugin_registry_could_not_find_vendor` i18n key for vendor errors
- Internationalize hardcoded English strings in `plugin_registry.go`
- Update `db_error_loading_env_file` format verb from `%s` to `%w` for wrapping
- Normalize error casing in en, de, es, fr, it, ja, pt-BR, pt-PT, zh, fa locales
- Import the new `azureaigateway` plugin package
- Register `azureaigateway.NewClient()` in the plugin registry
- Enable Azure AI Gateway as an available AI provider
## CHANGES
- Add new `azure_entra` plugin client to plugin registry
- Extract shared Azure logic into `azurecommon` package
- Move `ParseDeployments`, `BuildEndpoint`, and middleware to `azurecommon`
- Upgrade `azidentity` to v1.13.1 with Entra ID/MSAL support
- Add `golang-jwt`, `pkg/browser`, and `go-keychain` as new dependencies
- Add `azure_credential_failure`, `azure_base_url_question` i18n keys across all locales
- Validate Azure deployment names are non-empty on configure
## CHANGES
- Document 1M token context window model support.
- Clarify model beta list maintenance and update strategy.
- Add Claude Sonnet 4.6 to context-1m beta list.
- Add Claude Opus 4.5 and 4.6 beta entries.
- Group model variants under clearer, annotated sections.
### CHANGES
- Implement internationalization support for all AI vendor plugins
- Update localization files for multiple languages with new keys
- Replace hardcoded strings in Spotify and YouTube tools
- Add unit tests for localized error handling in Ollama
- Refactor template plugins to use localized system error messages
- Standardize setup questions using the new i18n translation framework
- Bump go-sqlite3 from v1.14.33 to v1.14.34
- Bump ollama from v0.15.6 to v0.16.1
- Bump google.golang.org/api from v0.265.0 to v0.266.0
- Bump google.golang.org/grpc from v1.78.0 to v1.79.0
- Remove deprecated Claude 3.x model references from Anthropic client
- Remove claude-3-7-sonnet model from OpenAI-compatible provider config
- Add changelog entry for PR #1996
- Add PDFURL and URLPDF to VSCode spell-check dictionary
- incoming 1996 changelog entry
- Upgrade Anthropic SDK Go dependency to version 1.23.0
- Add Claude Sonnet 4.6 to list of supported models
- Update `go.sum` checksums for new SDK version
- Add optional API key setup question to client configuration
- Add `ApiKey` field to the LM Studio `Client` struct
- Create `addAuthorizationHeader` helper to attach Bearer token to requests
- Apply authorization header to all outgoing HTTP requests
- Skip authorization header when API key is empty or unset
- Replace hardcoded error strings in `file_manager.go` with i18n translation keys
- Add file manager, Vertex AI, and Copilot i18n keys to all 10 locale files
- Internationalize Copilot plugin error messages and debug logs
- Internationalize Vertex AI model fetching error messages
- Fix JSON trailing comma syntax errors across all locale files
- Normalize German locale JSON indentation from tabs to spaces
- Use `AddSetupQuestionWithEnvName` for Bedrock AWS region setup