mirror of
https://github.com/RooVetGit/Roo-Code.git
synced 2026-09-19 00:01:19 +00:00
553 lines
20 KiB
TypeScript
553 lines
20 KiB
TypeScript
import { ApiHandlerOptions } from "../../shared/api"
|
|
import { ContextProxy } from "../../core/config/ContextProxy"
|
|
import { EmbedderProvider } from "./interfaces/manager"
|
|
import { CodeIndexConfig, PreviousConfigSnapshot } from "./interfaces/config"
|
|
import { DEFAULT_SEARCH_MIN_SCORE, DEFAULT_MAX_SEARCH_RESULTS } from "./constants"
|
|
import { getDefaultModelId, getModelDimension, getModelScoreThreshold } from "../../shared/embeddingModels"
|
|
|
|
/**
|
|
* Manages configuration state and validation for the code indexing feature.
|
|
* Handles loading, validating, and providing access to configuration values.
|
|
*/
|
|
export class CodeIndexConfigManager {
|
|
private codebaseIndexEnabled: boolean = false
|
|
private embedderProvider: EmbedderProvider = "openai"
|
|
private modelId?: string
|
|
private modelDimension?: number
|
|
private openAiOptions?: ApiHandlerOptions
|
|
private ollamaOptions?: ApiHandlerOptions
|
|
private openAiCompatibleOptions?: { baseUrl: string; apiKey: string }
|
|
private geminiOptions?: { apiKey: string }
|
|
private mistralOptions?: { apiKey: string }
|
|
private vercelAiGatewayOptions?: { apiKey: string }
|
|
private bedrockOptions?: { region: string; profile?: string }
|
|
private openRouterOptions?: { apiKey: string; specificProvider?: string }
|
|
private qdrantUrl?: string = "http://localhost:6333"
|
|
private qdrantApiKey?: string
|
|
private searchMinScore?: number
|
|
private searchMaxResults?: number
|
|
private codebaseIndexRespectGitIgnore: boolean = true
|
|
|
|
constructor(private readonly contextProxy: ContextProxy) {
|
|
// Initialize with current configuration to avoid false restart triggers
|
|
this._loadAndSetConfiguration()
|
|
}
|
|
|
|
/**
|
|
* Gets the context proxy instance
|
|
*/
|
|
public getContextProxy(): ContextProxy {
|
|
return this.contextProxy
|
|
}
|
|
|
|
/**
|
|
* Private method that handles loading configuration from storage and updating instance variables.
|
|
* This eliminates code duplication between initializeWithCurrentConfig() and loadConfiguration().
|
|
*/
|
|
private _loadAndSetConfiguration(): void {
|
|
// Load configuration from storage
|
|
const codebaseIndexConfig = this.contextProxy?.getGlobalState("codebaseIndexConfig") ?? {
|
|
codebaseIndexEnabled: false,
|
|
codebaseIndexQdrantUrl: "http://localhost:6333",
|
|
codebaseIndexEmbedderProvider: "openai",
|
|
codebaseIndexEmbedderBaseUrl: "",
|
|
codebaseIndexEmbedderModelId: "",
|
|
codebaseIndexSearchMinScore: undefined,
|
|
codebaseIndexSearchMaxResults: undefined,
|
|
codebaseIndexBedrockRegion: "us-east-1",
|
|
codebaseIndexBedrockProfile: "",
|
|
}
|
|
|
|
const {
|
|
codebaseIndexEnabled,
|
|
codebaseIndexQdrantUrl,
|
|
codebaseIndexEmbedderProvider,
|
|
codebaseIndexEmbedderBaseUrl,
|
|
codebaseIndexEmbedderModelId,
|
|
codebaseIndexSearchMinScore,
|
|
codebaseIndexSearchMaxResults,
|
|
} = codebaseIndexConfig
|
|
|
|
const openAiKey = this.contextProxy?.getSecret("codeIndexOpenAiKey") ?? ""
|
|
const qdrantApiKey = this.contextProxy?.getSecret("codeIndexQdrantApiKey") ?? ""
|
|
// Fix: Read OpenAI Compatible settings from the correct location within codebaseIndexConfig
|
|
const openAiCompatibleBaseUrl = codebaseIndexConfig.codebaseIndexOpenAiCompatibleBaseUrl ?? ""
|
|
const openAiCompatibleApiKey = this.contextProxy?.getSecret("codebaseIndexOpenAiCompatibleApiKey") ?? ""
|
|
const geminiApiKey = this.contextProxy?.getSecret("codebaseIndexGeminiApiKey") ?? ""
|
|
const mistralApiKey = this.contextProxy?.getSecret("codebaseIndexMistralApiKey") ?? ""
|
|
const vercelAiGatewayApiKey = this.contextProxy?.getSecret("codebaseIndexVercelAiGatewayApiKey") ?? ""
|
|
const bedrockRegion = codebaseIndexConfig.codebaseIndexBedrockRegion ?? "us-east-1"
|
|
const bedrockProfile = codebaseIndexConfig.codebaseIndexBedrockProfile ?? ""
|
|
const openRouterApiKey = this.contextProxy?.getSecret("codebaseIndexOpenRouterApiKey") ?? ""
|
|
const openRouterSpecificProvider = codebaseIndexConfig.codebaseIndexOpenRouterSpecificProvider ?? ""
|
|
|
|
// Update instance variables with configuration
|
|
this.codebaseIndexEnabled = codebaseIndexEnabled ?? false
|
|
this.qdrantUrl = codebaseIndexQdrantUrl
|
|
this.qdrantApiKey = qdrantApiKey ?? ""
|
|
this.searchMinScore = codebaseIndexSearchMinScore
|
|
this.searchMaxResults = codebaseIndexSearchMaxResults
|
|
this.codebaseIndexRespectGitIgnore = codebaseIndexConfig.codebaseIndexRespectGitIgnore ?? true
|
|
|
|
// Validate and set model dimension
|
|
const rawDimension = codebaseIndexConfig.codebaseIndexEmbedderModelDimension
|
|
if (rawDimension !== undefined && rawDimension !== null) {
|
|
const dimension = Number(rawDimension)
|
|
if (!isNaN(dimension) && dimension > 0) {
|
|
this.modelDimension = dimension
|
|
} else {
|
|
console.warn(
|
|
`Invalid codebaseIndexEmbedderModelDimension value: ${rawDimension}. Must be a positive number.`,
|
|
)
|
|
this.modelDimension = undefined
|
|
}
|
|
} else {
|
|
this.modelDimension = undefined
|
|
}
|
|
|
|
this.openAiOptions = { openAiNativeApiKey: openAiKey }
|
|
|
|
// Set embedder provider with support for openai-compatible
|
|
if (codebaseIndexEmbedderProvider === "ollama") {
|
|
this.embedderProvider = "ollama"
|
|
} else if (codebaseIndexEmbedderProvider === "openai-compatible") {
|
|
this.embedderProvider = "openai-compatible"
|
|
} else if (codebaseIndexEmbedderProvider === "gemini") {
|
|
this.embedderProvider = "gemini"
|
|
} else if (codebaseIndexEmbedderProvider === "mistral") {
|
|
this.embedderProvider = "mistral"
|
|
} else if (codebaseIndexEmbedderProvider === "vercel-ai-gateway") {
|
|
this.embedderProvider = "vercel-ai-gateway"
|
|
} else if ((codebaseIndexEmbedderProvider as string) === "bedrock") {
|
|
this.embedderProvider = "bedrock"
|
|
} else if (codebaseIndexEmbedderProvider === "openrouter") {
|
|
this.embedderProvider = "openrouter"
|
|
} else {
|
|
this.embedderProvider = "openai"
|
|
}
|
|
|
|
this.modelId = codebaseIndexEmbedderModelId || undefined
|
|
|
|
this.ollamaOptions = {
|
|
ollamaBaseUrl: codebaseIndexEmbedderBaseUrl,
|
|
}
|
|
|
|
this.openAiCompatibleOptions =
|
|
openAiCompatibleBaseUrl && openAiCompatibleApiKey
|
|
? {
|
|
baseUrl: openAiCompatibleBaseUrl,
|
|
apiKey: openAiCompatibleApiKey,
|
|
}
|
|
: undefined
|
|
|
|
this.geminiOptions = geminiApiKey ? { apiKey: geminiApiKey } : undefined
|
|
this.mistralOptions = mistralApiKey ? { apiKey: mistralApiKey } : undefined
|
|
this.vercelAiGatewayOptions = vercelAiGatewayApiKey ? { apiKey: vercelAiGatewayApiKey } : undefined
|
|
this.openRouterOptions = openRouterApiKey
|
|
? { apiKey: openRouterApiKey, specificProvider: openRouterSpecificProvider || undefined }
|
|
: undefined
|
|
// Set bedrockOptions if region is provided (profile is optional)
|
|
this.bedrockOptions = bedrockRegion
|
|
? { region: bedrockRegion, profile: bedrockProfile || undefined }
|
|
: undefined
|
|
}
|
|
|
|
/**
|
|
* Loads persisted configuration from globalState.
|
|
*/
|
|
public async loadConfiguration(): Promise<{
|
|
configSnapshot: PreviousConfigSnapshot
|
|
currentConfig: {
|
|
isConfigured: boolean
|
|
embedderProvider: EmbedderProvider
|
|
modelId?: string
|
|
modelDimension?: number
|
|
openAiOptions?: ApiHandlerOptions
|
|
ollamaOptions?: ApiHandlerOptions
|
|
openAiCompatibleOptions?: { baseUrl: string; apiKey: string }
|
|
geminiOptions?: { apiKey: string }
|
|
mistralOptions?: { apiKey: string }
|
|
vercelAiGatewayOptions?: { apiKey: string }
|
|
bedrockOptions?: { region: string; profile?: string }
|
|
openRouterOptions?: { apiKey: string }
|
|
qdrantUrl?: string
|
|
qdrantApiKey?: string
|
|
searchMinScore?: number
|
|
}
|
|
requiresRestart: boolean
|
|
}> {
|
|
// Capture the ACTUAL previous state before loading new configuration
|
|
const previousConfigSnapshot: PreviousConfigSnapshot = {
|
|
enabled: this.codebaseIndexEnabled,
|
|
configured: this.isConfigured(),
|
|
embedderProvider: this.embedderProvider,
|
|
modelId: this.modelId,
|
|
modelDimension: this.modelDimension,
|
|
openAiKey: this.openAiOptions?.openAiNativeApiKey ?? "",
|
|
ollamaBaseUrl: this.ollamaOptions?.ollamaBaseUrl ?? "",
|
|
openAiCompatibleBaseUrl: this.openAiCompatibleOptions?.baseUrl ?? "",
|
|
openAiCompatibleApiKey: this.openAiCompatibleOptions?.apiKey ?? "",
|
|
geminiApiKey: this.geminiOptions?.apiKey ?? "",
|
|
mistralApiKey: this.mistralOptions?.apiKey ?? "",
|
|
vercelAiGatewayApiKey: this.vercelAiGatewayOptions?.apiKey ?? "",
|
|
bedrockRegion: this.bedrockOptions?.region ?? "",
|
|
bedrockProfile: this.bedrockOptions?.profile ?? "",
|
|
openRouterApiKey: this.openRouterOptions?.apiKey ?? "",
|
|
openRouterSpecificProvider: this.openRouterOptions?.specificProvider ?? "",
|
|
qdrantUrl: this.qdrantUrl ?? "",
|
|
qdrantApiKey: this.qdrantApiKey ?? "",
|
|
codebaseIndexRespectGitIgnore: this.codebaseIndexRespectGitIgnore,
|
|
}
|
|
|
|
// Refresh secrets from VSCode storage to ensure we have the latest values
|
|
await this.contextProxy.refreshSecrets()
|
|
|
|
// Load new configuration from storage and update instance variables
|
|
this._loadAndSetConfiguration()
|
|
|
|
const requiresRestart = this.doesConfigChangeRequireRestart(previousConfigSnapshot)
|
|
|
|
return {
|
|
configSnapshot: previousConfigSnapshot,
|
|
currentConfig: {
|
|
isConfigured: this.isConfigured(),
|
|
embedderProvider: this.embedderProvider,
|
|
modelId: this.modelId,
|
|
modelDimension: this.modelDimension,
|
|
openAiOptions: this.openAiOptions,
|
|
ollamaOptions: this.ollamaOptions,
|
|
openAiCompatibleOptions: this.openAiCompatibleOptions,
|
|
geminiOptions: this.geminiOptions,
|
|
mistralOptions: this.mistralOptions,
|
|
vercelAiGatewayOptions: this.vercelAiGatewayOptions,
|
|
bedrockOptions: this.bedrockOptions,
|
|
openRouterOptions: this.openRouterOptions,
|
|
qdrantUrl: this.qdrantUrl,
|
|
qdrantApiKey: this.qdrantApiKey,
|
|
searchMinScore: this.currentSearchMinScore,
|
|
},
|
|
requiresRestart,
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Checks if the service is properly configured based on the embedder type.
|
|
*/
|
|
public isConfigured(): boolean {
|
|
if (this.embedderProvider === "openai") {
|
|
const openAiKey = this.openAiOptions?.openAiNativeApiKey
|
|
const qdrantUrl = this.qdrantUrl
|
|
return !!(openAiKey && qdrantUrl)
|
|
} else if (this.embedderProvider === "ollama") {
|
|
// Ollama model ID has a default, so only base URL is strictly required for config
|
|
const ollamaBaseUrl = this.ollamaOptions?.ollamaBaseUrl
|
|
const qdrantUrl = this.qdrantUrl
|
|
return !!(ollamaBaseUrl && qdrantUrl)
|
|
} else if (this.embedderProvider === "openai-compatible") {
|
|
const baseUrl = this.openAiCompatibleOptions?.baseUrl
|
|
const apiKey = this.openAiCompatibleOptions?.apiKey
|
|
const qdrantUrl = this.qdrantUrl
|
|
const isConfigured = !!(baseUrl && apiKey && qdrantUrl)
|
|
return isConfigured
|
|
} else if (this.embedderProvider === "gemini") {
|
|
const apiKey = this.geminiOptions?.apiKey
|
|
const qdrantUrl = this.qdrantUrl
|
|
const isConfigured = !!(apiKey && qdrantUrl)
|
|
return isConfigured
|
|
} else if (this.embedderProvider === "mistral") {
|
|
const apiKey = this.mistralOptions?.apiKey
|
|
const qdrantUrl = this.qdrantUrl
|
|
const isConfigured = !!(apiKey && qdrantUrl)
|
|
return isConfigured
|
|
} else if (this.embedderProvider === "vercel-ai-gateway") {
|
|
const apiKey = this.vercelAiGatewayOptions?.apiKey
|
|
const qdrantUrl = this.qdrantUrl
|
|
const isConfigured = !!(apiKey && qdrantUrl)
|
|
return isConfigured
|
|
} else if (this.embedderProvider === "bedrock") {
|
|
// Only region is required for Bedrock (profile is optional)
|
|
const region = this.bedrockOptions?.region
|
|
const qdrantUrl = this.qdrantUrl
|
|
const isConfigured = !!(region && qdrantUrl)
|
|
return isConfigured
|
|
} else if (this.embedderProvider === "openrouter") {
|
|
const apiKey = this.openRouterOptions?.apiKey
|
|
const qdrantUrl = this.qdrantUrl
|
|
const isConfigured = !!(apiKey && qdrantUrl)
|
|
return isConfigured
|
|
}
|
|
return false // Should not happen if embedderProvider is always set correctly
|
|
}
|
|
|
|
/**
|
|
* Determines if a configuration change requires restarting the indexing process.
|
|
* Simplified logic: only restart for critical changes that affect service functionality.
|
|
*
|
|
* CRITICAL CHANGES (require restart):
|
|
* - Provider changes (openai -> ollama, etc.)
|
|
* - Authentication changes (API keys, base URLs)
|
|
* - Vector dimension changes (model changes that affect embedding size)
|
|
* - Qdrant connection changes (URL, API key)
|
|
* - Feature enable/disable transitions
|
|
*
|
|
* MINOR CHANGES (no restart needed):
|
|
* - Search minimum score adjustments
|
|
* - UI-only settings
|
|
* - Non-functional configuration tweaks
|
|
*/
|
|
doesConfigChangeRequireRestart(prev: PreviousConfigSnapshot): boolean {
|
|
const nowConfigured = this.isConfigured()
|
|
|
|
// Handle null/undefined values safely
|
|
const prevEnabled = prev?.enabled ?? false
|
|
const prevConfigured = prev?.configured ?? false
|
|
const prevProvider = prev?.embedderProvider ?? "openai"
|
|
const prevOpenAiKey = prev?.openAiKey ?? ""
|
|
const prevOllamaBaseUrl = prev?.ollamaBaseUrl ?? ""
|
|
const prevOpenAiCompatibleBaseUrl = prev?.openAiCompatibleBaseUrl ?? ""
|
|
const prevOpenAiCompatibleApiKey = prev?.openAiCompatibleApiKey ?? ""
|
|
const prevModelDimension = prev?.modelDimension
|
|
const prevGeminiApiKey = prev?.geminiApiKey ?? ""
|
|
const prevMistralApiKey = prev?.mistralApiKey ?? ""
|
|
const prevVercelAiGatewayApiKey = prev?.vercelAiGatewayApiKey ?? ""
|
|
const prevBedrockRegion = prev?.bedrockRegion ?? ""
|
|
const prevBedrockProfile = prev?.bedrockProfile ?? ""
|
|
const prevOpenRouterApiKey = prev?.openRouterApiKey ?? ""
|
|
const prevOpenRouterSpecificProvider = prev?.openRouterSpecificProvider ?? ""
|
|
const prevQdrantUrl = prev?.qdrantUrl ?? ""
|
|
const prevQdrantApiKey = prev?.qdrantApiKey ?? ""
|
|
|
|
// 1. Transition from disabled/unconfigured to enabled/configured
|
|
if ((!prevEnabled || !prevConfigured) && this.codebaseIndexEnabled && nowConfigured) {
|
|
return true
|
|
}
|
|
|
|
// 2. Transition from enabled to disabled
|
|
if (prevEnabled && !this.codebaseIndexEnabled) {
|
|
return true
|
|
}
|
|
|
|
// 3. If wasn't ready before and isn't ready now, no restart needed
|
|
if ((!prevEnabled || !prevConfigured) && (!this.codebaseIndexEnabled || !nowConfigured)) {
|
|
return false
|
|
}
|
|
|
|
// 4. CRITICAL CHANGES - Always restart for these
|
|
// Only check for critical changes if feature is enabled
|
|
if (!this.codebaseIndexEnabled) {
|
|
return false
|
|
}
|
|
|
|
// Provider change
|
|
if (prevProvider !== this.embedderProvider) {
|
|
return true
|
|
}
|
|
|
|
// Authentication changes (API keys)
|
|
const currentOpenAiKey = this.openAiOptions?.openAiNativeApiKey ?? ""
|
|
const currentOllamaBaseUrl = this.ollamaOptions?.ollamaBaseUrl ?? ""
|
|
const currentOpenAiCompatibleBaseUrl = this.openAiCompatibleOptions?.baseUrl ?? ""
|
|
const currentOpenAiCompatibleApiKey = this.openAiCompatibleOptions?.apiKey ?? ""
|
|
const currentModelDimension = this.modelDimension
|
|
const currentGeminiApiKey = this.geminiOptions?.apiKey ?? ""
|
|
const currentMistralApiKey = this.mistralOptions?.apiKey ?? ""
|
|
const currentVercelAiGatewayApiKey = this.vercelAiGatewayOptions?.apiKey ?? ""
|
|
const currentBedrockRegion = this.bedrockOptions?.region ?? ""
|
|
const currentBedrockProfile = this.bedrockOptions?.profile ?? ""
|
|
const currentOpenRouterApiKey = this.openRouterOptions?.apiKey ?? ""
|
|
const currentOpenRouterSpecificProvider = this.openRouterOptions?.specificProvider ?? ""
|
|
const currentQdrantUrl = this.qdrantUrl ?? ""
|
|
const currentQdrantApiKey = this.qdrantApiKey ?? ""
|
|
|
|
if (prevOpenAiKey !== currentOpenAiKey) {
|
|
return true
|
|
}
|
|
|
|
if (prevOllamaBaseUrl !== currentOllamaBaseUrl) {
|
|
return true
|
|
}
|
|
|
|
if (
|
|
prevOpenAiCompatibleBaseUrl !== currentOpenAiCompatibleBaseUrl ||
|
|
prevOpenAiCompatibleApiKey !== currentOpenAiCompatibleApiKey
|
|
) {
|
|
return true
|
|
}
|
|
|
|
if (prevGeminiApiKey !== currentGeminiApiKey) {
|
|
return true
|
|
}
|
|
|
|
if (prevMistralApiKey !== currentMistralApiKey) {
|
|
return true
|
|
}
|
|
|
|
if (prevVercelAiGatewayApiKey !== currentVercelAiGatewayApiKey) {
|
|
return true
|
|
}
|
|
|
|
if (prevBedrockRegion !== currentBedrockRegion || prevBedrockProfile !== currentBedrockProfile) {
|
|
return true
|
|
}
|
|
|
|
if (prevOpenRouterApiKey !== currentOpenRouterApiKey) {
|
|
return true
|
|
}
|
|
|
|
// OpenRouter specific provider change
|
|
if (prevOpenRouterSpecificProvider !== currentOpenRouterSpecificProvider) {
|
|
return true
|
|
}
|
|
|
|
// Check for model dimension changes (generic for all providers)
|
|
if (prevModelDimension !== currentModelDimension) {
|
|
return true
|
|
}
|
|
|
|
if (prevQdrantUrl !== currentQdrantUrl || prevQdrantApiKey !== currentQdrantApiKey) {
|
|
return true
|
|
}
|
|
|
|
// Vector dimension changes (still important for compatibility)
|
|
if (this._hasVectorDimensionChanged(prevProvider, prev?.modelId)) {
|
|
return true
|
|
}
|
|
|
|
// codebaseIndexRespectGitIgnore change
|
|
const prevRespectGitIgnore = prev?.codebaseIndexRespectGitIgnore ?? true
|
|
if (prevRespectGitIgnore !== this.codebaseIndexRespectGitIgnore) {
|
|
return true
|
|
}
|
|
|
|
return false
|
|
}
|
|
|
|
/**
|
|
* Checks if model changes result in vector dimension changes that require restart.
|
|
*/
|
|
private _hasVectorDimensionChanged(prevProvider: EmbedderProvider, prevModelId?: string): boolean {
|
|
const currentProvider = this.embedderProvider
|
|
const currentModelId = this.modelId ?? getDefaultModelId(currentProvider)
|
|
const resolvedPrevModelId = prevModelId ?? getDefaultModelId(prevProvider)
|
|
|
|
// If model IDs are the same and provider is the same, no dimension change
|
|
if (prevProvider === currentProvider && resolvedPrevModelId === currentModelId) {
|
|
return false
|
|
}
|
|
|
|
// Get vector dimensions for both models
|
|
const prevDimension = getModelDimension(prevProvider, resolvedPrevModelId)
|
|
const currentDimension = getModelDimension(currentProvider, currentModelId)
|
|
|
|
// If we can't determine dimensions, be safe and restart
|
|
if (prevDimension === undefined || currentDimension === undefined) {
|
|
return true
|
|
}
|
|
|
|
// Only restart if dimensions actually changed
|
|
return prevDimension !== currentDimension
|
|
}
|
|
|
|
/**
|
|
* Gets the current configuration state.
|
|
*/
|
|
public getConfig(): CodeIndexConfig {
|
|
return {
|
|
isConfigured: this.isConfigured(),
|
|
embedderProvider: this.embedderProvider,
|
|
modelId: this.modelId,
|
|
modelDimension: this.modelDimension,
|
|
openAiOptions: this.openAiOptions,
|
|
ollamaOptions: this.ollamaOptions,
|
|
openAiCompatibleOptions: this.openAiCompatibleOptions,
|
|
geminiOptions: this.geminiOptions,
|
|
mistralOptions: this.mistralOptions,
|
|
vercelAiGatewayOptions: this.vercelAiGatewayOptions,
|
|
bedrockOptions: this.bedrockOptions,
|
|
openRouterOptions: this.openRouterOptions,
|
|
qdrantUrl: this.qdrantUrl,
|
|
qdrantApiKey: this.qdrantApiKey,
|
|
searchMinScore: this.currentSearchMinScore,
|
|
searchMaxResults: this.currentSearchMaxResults,
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Gets whether the code indexing feature is enabled
|
|
*/
|
|
public get isFeatureEnabled(): boolean {
|
|
return this.codebaseIndexEnabled
|
|
}
|
|
|
|
/**
|
|
* Gets whether the code indexing feature is properly configured
|
|
*/
|
|
public get isFeatureConfigured(): boolean {
|
|
return this.isConfigured()
|
|
}
|
|
|
|
/**
|
|
* Gets the current embedder type (openai or ollama)
|
|
*/
|
|
public get currentEmbedderProvider(): EmbedderProvider {
|
|
return this.embedderProvider
|
|
}
|
|
|
|
/**
|
|
* Gets the current Qdrant configuration
|
|
*/
|
|
public get qdrantConfig(): { url?: string; apiKey?: string } {
|
|
return {
|
|
url: this.qdrantUrl,
|
|
apiKey: this.qdrantApiKey,
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Gets the current model ID being used for embeddings.
|
|
*/
|
|
public get currentModelId(): string | undefined {
|
|
return this.modelId
|
|
}
|
|
|
|
/**
|
|
* Gets the current model dimension being used for embeddings.
|
|
* Returns the model's built-in dimension if available, otherwise falls back to custom dimension.
|
|
*/
|
|
public get currentModelDimension(): number | undefined {
|
|
// First try to get the model-specific dimension
|
|
const modelId = this.modelId ?? getDefaultModelId(this.embedderProvider)
|
|
const modelDimension = getModelDimension(this.embedderProvider, modelId)
|
|
|
|
// Only use custom dimension if model doesn't have a built-in dimension
|
|
if (!modelDimension && this.modelDimension && this.modelDimension > 0) {
|
|
return this.modelDimension
|
|
}
|
|
|
|
return modelDimension
|
|
}
|
|
|
|
/**
|
|
* Gets the configured minimum search score based on user setting, model-specific threshold, or fallback.
|
|
* Priority: 1) User setting, 2) Model-specific threshold, 3) Default DEFAULT_SEARCH_MIN_SCORE constant.
|
|
*/
|
|
public get currentSearchMinScore(): number {
|
|
// First check if user has configured a custom score threshold
|
|
if (this.searchMinScore !== undefined) {
|
|
return this.searchMinScore
|
|
}
|
|
|
|
// Fall back to model-specific threshold
|
|
const currentModelId = this.modelId ?? getDefaultModelId(this.embedderProvider)
|
|
const modelSpecificThreshold = getModelScoreThreshold(this.embedderProvider, currentModelId)
|
|
return modelSpecificThreshold ?? DEFAULT_SEARCH_MIN_SCORE
|
|
}
|
|
|
|
/**
|
|
* Gets the configured maximum search results.
|
|
* Returns user setting if configured, otherwise returns default.
|
|
*/
|
|
public get currentSearchMaxResults(): number {
|
|
return this.searchMaxResults ?? DEFAULT_MAX_SEARCH_RESULTS
|
|
}
|
|
}
|