* fix: remove explicit cache_control for Google models in OpenRouter (#4487)
- Remove all Google models from OPEN_ROUTER_PROMPT_CACHING_MODELS set
- This resolves 3+ minute lag when using google/gemini-2.5-pro-preview
- OpenRouter still provides automatic implicit ephemeral caching for these models
- Updated tests to handle intentional exclusion of Google models from explicit caching
Fixes#4487
* refactor: simplify OpenRouter caching test logic
- Replace hardcoded exclusion list with simple Google model filter
- Keep original validation logic but make it more maintainable
- Still ensures all our caching models are supported by OpenRouter
- Still verifies we exclude all Google models from explicit caching
* cleanup: remove unused excludedModels variable
- Variable was defined but never used
- Keeps the test logic clean and focused
* refactor: only exclude google/gemini-2.5-pro-preview from caching
- More surgical approach - only exclude the specific problematic model
- Keep other Google models in caching (they work fine)
- Add comment explaining the exclusion with issue reference
- Update test to only exclude the specific model
This targets just the model causing 3+ minute lag while preserving
caching benefits for other Google models that work properly.
* Clarify that the default not the max is 15 files
* Update webview-ui/src/i18n/locales/en/settings.json
Co-authored-by: Matt Rubens <mrubens@users.noreply.github.com>
* Update all languages for CONCURRENT_FILE_READS setting
---------
Co-authored-by: Matt Rubens <mrubens@users.noreply.github.com>
* refactor: streamline text copying by removing history highlight spans
* refactor: improve regex for stripping history highlight spans to handle all content types
---------
Co-authored-by: Daniel Riccio <ricciodaniel98@gmail.com>
* feat: Add safeWriteJson utility for atomic file operations
Implements a robust JSON file writing utility that:
- Prevents concurrent writes to the same file using in-memory locks
- Ensures atomic operations with temporary file and backup strategies
- Handles error cases with proper rollback mechanisms
- Cleans up temporary files even when operations fail
- Provides comprehensive test coverage for success and failure scenarios
Signed-off-by: Eric Wheeler <roo-code@z.ewheeler.org>
* fix: use safeWriteJson for all JSON file writes
This change refactors all direct JSON file writes to use the safeWriteJson
utility, which implements atomic file writes to prevent data corruption
during write operations.
- Modified safeWriteJson to accept optional replacer and space arguments
- Updated tests to verify correct behavior with the new implementation
Fixes: #722
Signed-off-by: Eric Wheeler <roo-code@z.ewheeler.org>
* feat: Implement inter-process file locking for safeWriteJson
Replaces the previous in-memory lock in `safeWriteJson` with
`proper-lockfile` to provide robust, cross-process advisory file
locking. This enhances safety when multiple processes might attempt
concurrent writes to the same JSON file.
Key changes:
- Added `proper-lockfile` and `@types/proper-lockfile` dependencies.
- `safeWriteJson` now uses `proper-lockfile.lock()` with configured
retries, staleness checks (31s), and lock update intervals (10s).
- An `onCompromised` handler is included to manage scenarios where
the lock state is unexpectedly altered.
- Logging and comments within `safeWriteJson` have been refined for
clarity, ensuring error logs include backtraces.
- The test suite `safeWriteJson.test.ts` has been significantly
updated to:
- Use real timers (`jest.useRealTimers()`).
- Employ a more comprehensive mock for `fs/promises`.
- Correctly manage file pre-existence for various scenarios.
- Simulate lock contention by mocking `proper-lockfile.lock()`
using `jest.doMock` and a dynamic require for the SUT.
- Verify lock release by checking for the absence of the `.lock`
file.
All tests are passing with these changes.
Signed-off-by: Eric Wheeler <roo-code@z.ewheeler.org>
* feat: implement streaming JSON write in safeWriteJson
Refactor safeWriteJson to use stream-json for memory-efficient JSON serialization:
- Replace in-memory string creation with streaming pipeline
- Add Disassembler and Stringer from stream-json library
- Extract streaming logic to a dedicated helper function
- Add proper-lockfile and stream-json dependencies
This implementation reduces memory usage when writing large JSON objects.
Signed-off-by: Eric Wheeler <roo-code@z.ewheeler.org>
* fix: improve safeWriteJson locking mechanism
- Use file path itself for locking instead of separate lock file
- Improve error handling and clarity of code
- Enhance cleanup of temporary files
Signed-off-by: Eric Wheeler <roo-code@z.ewheeler.org>
* test: fix safeWriteJson test failures
- Ensure test file exists before locking
- Add proper mocking for fs.createWriteStream
- Fix test assertions to match expected behavior
- Improve test comments to follow project guidelines
Signed-off-by: Eric Wheeler <roo-code@z.ewheeler.org>
* test: update tests to work with safeWriteJson
Updated tests to work with safeWriteJson instead of direct fs.writeFile calls:
- Updated importExport.test.ts to expect safeWriteJson calls instead of fs.writeFile
- Fixed McpHub.test.ts by properly mocking fs/promises module:
- Moved jest.mock() to the top of the file before any imports
- Added mock implementations for all fs functions used by safeWriteJson
- Updated the test setup to work with the mocked fs module
All tests now pass successfully.
Signed-off-by: Eric Wheeler <roo-code@z.ewheeler.org>
* refactor: replace JSON.stringify with safeWriteJson for file operations
Replace all non-test instances of JSON.stringify used for writing to JSON files with safeWriteJson to ensure safer file operations with proper locking, error handling, and atomic writes.
- Updated src/services/mcp/McpHub.ts
- Updated src/services/code-index/cache-manager.ts
- Updated src/api/providers/fetchers/modelEndpointCache.ts
- Updated src/api/providers/fetchers/modelCache.ts
- Updated tests to match the new implementation
Signed-off-by: Eric Wheeler <roo-code@z.ewheeler.org>
* docs: add rules for using safeWriteJson
Add concise rules for using safeWriteJson instead of JSON.stringify with file operations to ensure atomic writes and prevent data corruption.
Signed-off-by: Eric Wheeler <roo-code@z.ewheeler.org>
---------
Signed-off-by: Eric Wheeler <roo-code@z.ewheeler.org>
Co-authored-by: Eric Wheeler <roo-code@z.ewheeler.org>
Co-authored-by: Daniel <57051444+daniel-lxs@users.noreply.github.com>
* Added changeset for my code changes
* Use URL constructor for joining baseUrl and path in litellm.ts
* Restoring Roo dotfiles
* Moved Roo dotfiles to root directory
* Revert this
* Add tests for litellm URL constructor fix
---------
Co-authored-by: Kevin White <kcwhite@ancestry.com>
Co-authored-by: Daniel <57051444+daniel-lxs@users.noreply.github.com>
Co-authored-by: Daniel Riccio <ricciodaniel98@gmail.com>
Implements a more robust bundling strategy for Mermaid diagrams to prevent
dynamic chunk loading at runtime, which was causing CSP violations.
Key changes:
- Added manualChunks function in vite.config.ts to consolidate all Mermaid
code and dependencies into a single bundle
- Added mermaid and dagre to optimizeDeps.include for pre-bundling
- Customized chunkFileNames to ensure predictable output
- Removed incorrect static imports in MermaidBlock.tsx
This resolves the CSP errors where Mermaid was attempting to dynamically
load chunks like chunk-RZ5BOZE2.js and channel.js from the webview origin.
Fixes: #3680
Signed-off-by: Eric Wheeler <roo-code@z.ewheeler.org>
Co-authored-by: Eric Wheeler <roo-code@z.ewheeler.org>
Co-authored-by: Daniel <57051444+daniel-lxs@users.noreply.github.com>
* feat(prompts): enforce codebase_search as primary code understanding tool
- Add conditional codebase_search enforcement in tool use guidelines
- Modify objective section to prioritize codebase_search when available
- Update rules section with critical codebase_search-first rule
- Pass CodeIndexManager to prompt sections for availability checks
- Ensure graceful degradation when codebase_search is unavailable
* chore(docs): remove codebase search enforcement documentation
* fix: update snapshot and reorder capabilities section
- Update system.test.ts snapshot to reflect architect mode without codebase_search enforcement
- Reorder capabilities section to place search_files description after codebase_search
- Ensures logical flow: codebase_search (semantic) → search_files (regex) → other tools
* refactor: improve tool-use-guidelines numbering logic
- Replace subsequentNumbers object with array-based approach
- Use automatic incrementing with itemNumber++ for sequential numbering
- Build guidelines as an array and join at the end
- Fix potential numbering issues with conditional logic
- Update tests and snapshots to match new format
As suggested by daniel-lxs in PR #4340
* feat: Add OpenAI Compatible embedder for codebase indexing
- Implement OpenAiCompatibleEmbedder with batching and retry logic
- Add configuration support for base URL and API key
- Update UI with provider selection and input fields
- Add comprehensive test coverage
- Support for all OpenAI-compatible endpoints (LiteLLM, LMStudio, Ollama, etc.)
- Add internationalization for 17 languages
* fix: Update CodeIndexSettings tests for OpenAI Compatible provider
- Fix field count expectations (4 fields including Qdrant)
- Use specific test IDs for button selection
- Fix input handling with clear() before type()
- Use toHaveBeenLastCalledWith for better assertions
- Fix status text matching with regex pattern
* fix: resolve UI test failures and ESLint errors
- Remove unused waitFor import to fix ESLint error
- Fix test expectations to match actual component behavior for input fields
- Simplify provider selection test by removing complex mock interactions
- All CodeIndexSettings tests now pass (20/20)
* feat: add custom model infrastructure for OpenAI-compatible embedder
- Add manual model ID and embedding dimension configuration
- Enable custom model input via text field in settings UI
- Add modelDimension parameter to OpenAiCompatibleEmbedder
- Update configuration management to persist dimension setting
- Prioritize manual dimension over hardcoded model profiles
- Add comprehensive test coverage for new functionality
This allows users to specify any custom embedding model and its
dimension for OpenAI-compatible providers, removing dependency
on hardcoded model profiles.
* Add missing translations for OpenAI-compatible model dimension settings in all locales
* refactor: remove unused modelDimension parameter from OpenAiCompatibleEmbedder
- Remove modelDimension property and constructor parameter from OpenAiCompatibleEmbedder class
- Update ServiceFactory to not pass dimension to embedder constructor
- Update tests to match new constructor signature
- The dimension is still used for QdrantVectorStore configuration
* chore: bot suggestion
Co-authored-by: ellipsis-dev[bot] <65095814+ellipsis-dev[bot]@users.noreply.github.com>
* chore: bot suggestion
Co-authored-by: ellipsis-dev[bot] <65095814+ellipsis-dev[bot]@users.noreply.github.com>
* refactor: rename OpenAiCompatibleEmbedder to OpenAICompatibleEmbedder for consistency
* feat: add model dimension validation for OpenAI-compatible settings
* refactor: improve default model ID retrieval logic for embedding providers
* feat: add default model ID retrieval for openai-compatible provider
* refactor: update default model ID retrieval to use shared utility function
* fix: Remove unnecessary type assertion in OpenAICompatibleEmbedder
* feat: add model dimension input for openai-compatible provider
---------
Co-authored-by: Daniel Riccio <ricciodaniel98@gmail.com>
Co-authored-by: Daniel <57051444+daniel-lxs@users.noreply.github.com>
Co-authored-by: ellipsis-dev[bot] <65095814+ellipsis-dev[bot]@users.noreply.github.com>