fix: trim URL inputs and expand openai-compatible embedding model profiles

- Add input trimming for URL and identifier fields in CodeIndexPopover
  handleSaveSettings to prevent leading/trailing whitespace from causing
  silent authentication failures (Bug 3 from #12366)
- Expand openai-compatible model profiles with popular third-party
  embedding models (Qwen, BAAI BGE, Nomic, Mixedbread) for better
  auto-dimension detection (Bug 2 from #12366)
- Add tests for new model dimension lookups
This commit is contained in:
Roo Code 2026-05-14 19:29:26 +00:00
parent e921f9d21e
commit 45cfeb4b4e
3 changed files with 48 additions and 2 deletions

View file

@ -57,6 +57,25 @@ describe("embeddingModels", () => {
expect(getModelDimension("openai", "text-embedding-3-large")).toBe(3072)
expect(getModelDimension("openai", "text-embedding-ada-002")).toBe(1536)
})
it("should return correct dimensions for openai-compatible third-party models", () => {
// Qwen models (commonly available on Featherless AI, Together AI, etc.)
expect(getModelDimension("openai-compatible", "Qwen/Qwen3-Embedding-0.6B")).toBe(1024)
expect(getModelDimension("openai-compatible", "Qwen/Qwen3-Embedding-4B")).toBe(2560)
expect(getModelDimension("openai-compatible", "Qwen/Qwen3-Embedding-8B")).toBe(4096)
// BAAI BGE models
expect(getModelDimension("openai-compatible", "BAAI/bge-large-en-v1.5")).toBe(1024)
expect(getModelDimension("openai-compatible", "BAAI/bge-base-en-v1.5")).toBe(768)
expect(getModelDimension("openai-compatible", "BAAI/bge-small-en-v1.5")).toBe(384)
// Nomic models
expect(getModelDimension("openai-compatible", "nomic-embed-text")).toBe(768)
// Mixedbread models
expect(getModelDimension("openai-compatible", "mixedbread-ai/mxbai-embed-large-v1")).toBe(1024)
})
it("should still return undefined for unknown models on openai-compatible", () => {
expect(getModelDimension("openai-compatible", "some-unknown-model")).toBeUndefined()
})
})
describe("getModelScoreThreshold", () => {

View file

@ -32,6 +32,19 @@ export const EMBEDDING_MODEL_PROFILES: EmbeddingModelProfiles = {
scoreThreshold: 0.15,
queryPrefix: "Represent this query for searching relevant code: ",
},
// Nomic models (commonly available on third-party providers)
"nomic-embed-text": { dimension: 768, scoreThreshold: 0.4 },
"nomic-ai/nomic-embed-text-v1.5": { dimension: 768, scoreThreshold: 0.4 },
// Qwen embedding models (Featherless AI, Together AI, etc.)
"Qwen/Qwen3-Embedding-0.6B": { dimension: 1024, scoreThreshold: 0.4 },
"Qwen/Qwen3-Embedding-4B": { dimension: 2560, scoreThreshold: 0.4 },
"Qwen/Qwen3-Embedding-8B": { dimension: 4096, scoreThreshold: 0.4 },
// BAAI BGE models (commonly self-hosted)
"BAAI/bge-large-en-v1.5": { dimension: 1024, scoreThreshold: 0.4 },
"BAAI/bge-base-en-v1.5": { dimension: 768, scoreThreshold: 0.4 },
"BAAI/bge-small-en-v1.5": { dimension: 384, scoreThreshold: 0.4 },
// Mixedbread models
"mixedbread-ai/mxbai-embed-large-v1": { dimension: 1024, scoreThreshold: 0.4 },
},
gemini: {
"gemini-embedding-001": { dimension: 3072, scoreThreshold: 0.4 },

View file

@ -539,6 +539,15 @@ export const CodeIndexPopover: React.FC<CodeIndexPopoverProps> = ({
// Prepare settings to save
const settingsToSave: any = {}
// Keys whose string values should be trimmed before saving
const trimKeys = new Set([
"codebaseIndexQdrantUrl",
"codebaseIndexEmbedderBaseUrl",
"codebaseIndexOpenAiCompatibleBaseUrl",
"codebaseIndexEmbedderModelId",
"codebaseIndexQdrantApiKey",
])
// Iterate through all current settings
for (const [key, value] of Object.entries(currentSettings)) {
// For secret fields with placeholder, don't send the placeholder
@ -549,8 +558,13 @@ export const CodeIndexPopover: React.FC<CodeIndexPopoverProps> = ({
continue
}
// Include all other fields, including empty strings (which clear secrets)
settingsToSave[key] = value
// Trim whitespace from URL and identifier fields to prevent silent failures
if (trimKeys.has(key) && typeof value === "string") {
settingsToSave[key] = value.trim()
} else {
// Include all other fields, including empty strings (which clear secrets)
settingsToSave[key] = value
}
}
// Always include codebaseIndexEnabled to ensure it's persisted