mirror of
https://github.com/RooVetGit/Roo-Code.git
synced 2026-09-07 08:26:51 +00:00
fix: make Qdrant configuration workspace-specific (fixes #9063)
- Added workspace state management to ContextProxy for Qdrant config - Modified CodeIndexConfigManager to use workspace-specific storage - Updated webview message handler to read/write workspace state - Added fallback from workspace to global state for backward compatibility - Updated tests to reflect workspace-specific configuration This allows different VS Code workspaces to connect to different Qdrant servers without manual reconfiguration when switching between them.
This commit is contained in:
parent
65230f1f5c
commit
2748b753c1
4 changed files with 321 additions and 117 deletions
|
|
@ -39,6 +39,7 @@ export class ContextProxy {
|
|||
|
||||
private stateCache: GlobalState
|
||||
private secretCache: SecretState
|
||||
private workspaceStateCache: Map<string, any> = new Map()
|
||||
private _isInitialized = false
|
||||
|
||||
constructor(context: vscode.ExtensionContext) {
|
||||
|
|
@ -187,6 +188,73 @@ export class ContextProxy {
|
|||
return Object.fromEntries(GLOBAL_STATE_KEYS.map((key) => [key, this.getGlobalState(key)]))
|
||||
}
|
||||
|
||||
/**
|
||||
* Workspace State Management
|
||||
* These methods handle workspace-specific state storage
|
||||
*/
|
||||
|
||||
getWorkspaceState<T>(key: string): T | undefined
|
||||
getWorkspaceState<T>(key: string, defaultValue: T): T
|
||||
getWorkspaceState<T>(key: string, defaultValue?: T): T | undefined {
|
||||
// Check cache first
|
||||
if (this.workspaceStateCache.has(key)) {
|
||||
return this.workspaceStateCache.get(key) as T
|
||||
}
|
||||
|
||||
// Get from VS Code workspace state
|
||||
const value = this.originalContext.workspaceState.get<T>(key)
|
||||
|
||||
// Update cache
|
||||
if (value !== undefined) {
|
||||
this.workspaceStateCache.set(key, value)
|
||||
}
|
||||
|
||||
return value !== undefined ? value : defaultValue
|
||||
}
|
||||
|
||||
async updateWorkspaceState<T>(key: string, value: T | undefined): Promise<void> {
|
||||
// Update cache
|
||||
if (value === undefined) {
|
||||
this.workspaceStateCache.delete(key)
|
||||
} else {
|
||||
this.workspaceStateCache.set(key, value)
|
||||
}
|
||||
|
||||
// Persist to VS Code workspace state
|
||||
await this.originalContext.workspaceState.update(key, value)
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Qdrant configuration from workspace state with fallback to global state
|
||||
* This allows migration from global to workspace-specific configuration
|
||||
*/
|
||||
getQdrantConfig(): { url: string; apiKey: string } {
|
||||
// Try workspace state first
|
||||
let url = this.getWorkspaceState<string>("codebaseIndexQdrantUrl")
|
||||
let apiKey = this.getWorkspaceState<string>("codeIndexQdrantApiKey")
|
||||
|
||||
// Fallback to global state if not in workspace state
|
||||
if (!url) {
|
||||
const globalConfig = this.getGlobalState("codebaseIndexConfig") || {}
|
||||
url = globalConfig.codebaseIndexQdrantUrl || "http://localhost:6333"
|
||||
}
|
||||
|
||||
// API key from secrets if not in workspace state
|
||||
if (!apiKey) {
|
||||
apiKey = this.getSecret("codeIndexQdrantApiKey" as SecretStateKey) || ""
|
||||
}
|
||||
|
||||
return { url, apiKey }
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Qdrant configuration in workspace state
|
||||
*/
|
||||
async setQdrantConfig(url: string, apiKey: string): Promise<void> {
|
||||
await this.updateWorkspaceState("codebaseIndexQdrantUrl", url)
|
||||
await this.updateWorkspaceState("codeIndexQdrantApiKey", apiKey)
|
||||
}
|
||||
|
||||
/**
|
||||
* ExtensionContext.secrets
|
||||
* https://code.visualstudio.com/api/references/vscode-api#ExtensionContext.secrets
|
||||
|
|
|
|||
|
|
@ -2508,11 +2508,18 @@ export const webviewMessageHandler = async (
|
|||
const embedderProviderChanged =
|
||||
currentConfig.codebaseIndexEmbedderProvider !== settings.codebaseIndexEmbedderProvider
|
||||
|
||||
// Save global state settings atomically
|
||||
// Save Qdrant URL and API key to workspace state for workspace-specific configuration
|
||||
if (settings.codebaseIndexQdrantUrl !== undefined || settings.codeIndexQdrantApiKey !== undefined) {
|
||||
const qdrantUrl = settings.codebaseIndexQdrantUrl ?? "http://localhost:6333"
|
||||
const qdrantApiKey = settings.codeIndexQdrantApiKey ?? ""
|
||||
await provider.contextProxy.setQdrantConfig(qdrantUrl, qdrantApiKey)
|
||||
}
|
||||
|
||||
// Save global state settings atomically (but without Qdrant config)
|
||||
const globalStateConfig = {
|
||||
...currentConfig,
|
||||
codebaseIndexEnabled: settings.codebaseIndexEnabled,
|
||||
codebaseIndexQdrantUrl: settings.codebaseIndexQdrantUrl,
|
||||
// Don't save Qdrant config to global state anymore
|
||||
codebaseIndexEmbedderProvider: settings.codebaseIndexEmbedderProvider,
|
||||
codebaseIndexEmbedderBaseUrl: settings.codebaseIndexEmbedderBaseUrl,
|
||||
codebaseIndexEmbedderModelId: settings.codebaseIndexEmbedderModelId,
|
||||
|
|
@ -2525,13 +2532,10 @@ export const webviewMessageHandler = async (
|
|||
// Save global state first
|
||||
await updateGlobalState("codebaseIndexConfig", globalStateConfig)
|
||||
|
||||
// Save secrets directly using context proxy
|
||||
// Save secrets directly using context proxy (except Qdrant API key which is now workspace-specific)
|
||||
if (settings.codeIndexOpenAiKey !== undefined) {
|
||||
await provider.contextProxy.storeSecret("codeIndexOpenAiKey", settings.codeIndexOpenAiKey)
|
||||
}
|
||||
if (settings.codeIndexQdrantApiKey !== undefined) {
|
||||
await provider.contextProxy.storeSecret("codeIndexQdrantApiKey", settings.codeIndexQdrantApiKey)
|
||||
}
|
||||
if (settings.codebaseIndexOpenAiCompatibleApiKey !== undefined) {
|
||||
await provider.contextProxy.storeSecret(
|
||||
"codebaseIndexOpenAiCompatibleApiKey",
|
||||
|
|
@ -2690,7 +2694,11 @@ export const webviewMessageHandler = async (
|
|||
case "requestCodeIndexSecretStatus": {
|
||||
// Check if secrets are set using the VSCode context directly for async access
|
||||
const hasOpenAiKey = !!(await provider.context.secrets.get("codeIndexOpenAiKey"))
|
||||
const hasQdrantApiKey = !!(await provider.context.secrets.get("codeIndexQdrantApiKey"))
|
||||
|
||||
// Check Qdrant API key from workspace state
|
||||
const qdrantConfig = provider.contextProxy.getQdrantConfig()
|
||||
const hasQdrantApiKey = !!qdrantConfig.apiKey
|
||||
|
||||
const hasOpenAiCompatibleApiKey = !!(await provider.context.secrets.get(
|
||||
"codebaseIndexOpenAiCompatibleApiKey",
|
||||
))
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -56,7 +56,6 @@ export class CodeIndexConfigManager {
|
|||
|
||||
const {
|
||||
codebaseIndexEnabled,
|
||||
codebaseIndexQdrantUrl,
|
||||
codebaseIndexEmbedderProvider,
|
||||
codebaseIndexEmbedderBaseUrl,
|
||||
codebaseIndexEmbedderModelId,
|
||||
|
|
@ -64,8 +63,10 @@ export class CodeIndexConfigManager {
|
|||
codebaseIndexSearchMaxResults,
|
||||
} = codebaseIndexConfig
|
||||
|
||||
// Get Qdrant configuration from workspace state (with fallback to global state)
|
||||
const qdrantConfig = this.contextProxy?.getQdrantConfig() ?? { url: "http://localhost:6333", apiKey: "" }
|
||||
|
||||
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") ?? ""
|
||||
|
|
@ -76,8 +77,8 @@ export class CodeIndexConfigManager {
|
|||
|
||||
// Update instance variables with configuration
|
||||
this.codebaseIndexEnabled = codebaseIndexEnabled ?? true
|
||||
this.qdrantUrl = codebaseIndexQdrantUrl
|
||||
this.qdrantApiKey = qdrantApiKey ?? ""
|
||||
this.qdrantUrl = qdrantConfig.url
|
||||
this.qdrantApiKey = qdrantConfig.apiKey
|
||||
this.searchMinScore = codebaseIndexSearchMinScore
|
||||
this.searchMaxResults = codebaseIndexSearchMaxResults
|
||||
|
||||
|
|
@ -500,4 +501,13 @@ export class CodeIndexConfigManager {
|
|||
public get currentSearchMaxResults(): number {
|
||||
return this.searchMaxResults ?? DEFAULT_MAX_SEARCH_RESULTS
|
||||
}
|
||||
|
||||
/**
|
||||
* Save Qdrant configuration to workspace state
|
||||
*/
|
||||
public async saveQdrantConfig(url: string, apiKey: string): Promise<void> {
|
||||
await this.contextProxy.setQdrantConfig(url, apiKey)
|
||||
this.qdrantUrl = url
|
||||
this.qdrantApiKey = apiKey
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue