Roo-Code/src/shared/embeddingModels.ts
SannidhyaSah a80795b78d
feat: Add OpenAI Compatible embedder for codebase indexing (#4066)
* 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>
2025-06-04 17:00:52 -04:00

93 lines
3.3 KiB
TypeScript

/**
* Defines profiles for different embedding models, including their dimensions.
*/
export type EmbedderProvider = "openai" | "ollama" | "openai-compatible" // Add other providers as needed
export interface EmbeddingModelProfile {
dimension: number
// Add other model-specific properties if needed, e.g., context window size
}
export type EmbeddingModelProfiles = {
[provider in EmbedderProvider]?: {
[modelId: string]: EmbeddingModelProfile
}
}
// Example profiles - expand this list as needed
export const EMBEDDING_MODEL_PROFILES: EmbeddingModelProfiles = {
openai: {
"text-embedding-3-small": { dimension: 1536 },
"text-embedding-3-large": { dimension: 3072 },
"text-embedding-ada-002": { dimension: 1536 },
},
ollama: {
"nomic-embed-text": { dimension: 768 },
"mxbai-embed-large": { dimension: 1024 },
"all-minilm": { dimension: 384 },
// Add default Ollama model if applicable, e.g.:
// 'default': { dimension: 768 } // Assuming a default dimension
},
"openai-compatible": {
"text-embedding-3-small": { dimension: 1536 },
"text-embedding-3-large": { dimension: 3072 },
"text-embedding-ada-002": { dimension: 1536 },
},
}
/**
* Retrieves the embedding dimension for a given provider and model ID.
* @param provider The embedder provider (e.g., "openai").
* @param modelId The specific model ID (e.g., "text-embedding-3-small").
* @returns The dimension size or undefined if the model is not found.
*/
export function getModelDimension(provider: EmbedderProvider, modelId: string): number | undefined {
const providerProfiles = EMBEDDING_MODEL_PROFILES[provider]
if (!providerProfiles) {
console.warn(`Provider not found in profiles: ${provider}`)
return undefined
}
const modelProfile = providerProfiles[modelId]
if (!modelProfile) {
// Don't warn here, as it might be a custom model ID not in our profiles
// console.warn(`Model not found for provider ${provider}: ${modelId}`)
return undefined // Or potentially return a default/fallback dimension?
}
return modelProfile.dimension
}
/**
* Gets the default *specific* embedding model ID based on the provider.
* Does not include the provider prefix.
* Currently defaults to OpenAI's 'text-embedding-3-small'.
* TODO: Make this configurable or more sophisticated.
* @param provider The embedder provider.
* @returns The default specific model ID for the provider (e.g., "text-embedding-3-small").
*/
export function getDefaultModelId(provider: EmbedderProvider): string {
switch (provider) {
case "openai":
case "openai-compatible":
return "text-embedding-3-small"
case "ollama": {
// Choose a sensible default for Ollama, e.g., the first one listed or a specific one
const ollamaModels = EMBEDDING_MODEL_PROFILES.ollama
const defaultOllamaModel = ollamaModels && Object.keys(ollamaModels)[0]
if (defaultOllamaModel) {
return defaultOllamaModel
}
// Fallback if no Ollama models are defined (shouldn't happen with the constant)
console.warn("No default Ollama model found in profiles.")
// Return a placeholder or throw an error, depending on desired behavior
return "unknown-default" // Placeholder specific model ID
}
default:
// Fallback for unknown providers
console.warn(`Unknown provider for default model ID: ${provider}. Falling back to OpenAI default.`)
return "text-embedding-3-small"
}
}