From ffb5923046334331192c3535875fc44345aec3cd Mon Sep 17 00:00:00 2001 From: rohan Date: Thu, 18 Sep 2025 02:57:27 +0530 Subject: [PATCH 1/3] added api and updates ui --- transports/bifrost-http/handlers/config.go | 97 +++++++- ui/app/config/page.tsx | 6 + ui/app/config/views/logStoreForm.tsx | 149 ++++++++++++ ui/app/config/views/vectorStoreForm.tsx | 269 +++++++++++++++++++++ ui/lib/store/apis/baseApi.ts | 2 + ui/lib/store/apis/configApi.ts | 49 +++- ui/lib/types/config.ts | 45 ++++ 7 files changed, 611 insertions(+), 6 deletions(-) create mode 100644 ui/app/config/views/logStoreForm.tsx create mode 100644 ui/app/config/views/vectorStoreForm.tsx diff --git a/transports/bifrost-http/handlers/config.go b/transports/bifrost-http/handlers/config.go index 6773a1391..ec79693a6 100644 --- a/transports/bifrost-http/handlers/config.go +++ b/transports/bifrost-http/handlers/config.go @@ -9,6 +9,8 @@ import ( bifrost "github.com/maximhq/bifrost/core" "github.com/maximhq/bifrost/core/schemas" "github.com/maximhq/bifrost/framework/configstore" + "github.com/maximhq/bifrost/framework/logstore" + "github.com/maximhq/bifrost/framework/vectorstore" "github.com/maximhq/bifrost/transports/bifrost-http/lib" "github.com/valyala/fasthttp" ) @@ -37,6 +39,14 @@ func (h *ConfigHandler) RegisterRoutes(r *router.Router) { r.GET("/api/config", h.getConfig) r.PUT("/api/config", h.updateConfig) r.GET("/api/version", h.getVersion) + + // Vector store configuration endpoints + r.GET("/api/config/vector-store", h.getVectorStoreConfig) + r.PUT("/api/config/vector-store", h.updateVectorStoreConfig) + + // Log store configuration endpoints + r.GET("/api/config/log-store", h.getLogStoreConfig) + r.PUT("/api/config/log-store", h.updateLogStoreConfig) } // getVersion handles GET /api/version - Get the current version @@ -124,8 +134,87 @@ func (h *ConfigHandler) updateConfig(ctx *fasthttp.RequestCtx) { } ctx.SetStatusCode(fasthttp.StatusOK) - SendJSON(ctx, map[string]any{ - "status": "success", - "message": "configuration updated successfully", - }, h.logger) + SendJSON(ctx, map[string]string{"status": "success"}, h.logger) +} + +// getVectorStoreConfig handles GET /api/config/vector-store - Get the current vector store configuration +func (h *ConfigHandler) getVectorStoreConfig(ctx *fasthttp.RequestCtx) { + if h.store.ConfigStore == nil { + SendError(ctx, fasthttp.StatusServiceUnavailable, "config store not available", h.logger) + return + } + + config, err := h.store.ConfigStore.GetVectorStoreConfig() + if err != nil { + SendError(ctx, fasthttp.StatusInternalServerError, + fmt.Sprintf("failed to fetch vector store config: %v", err), h.logger) + return + } + + SendJSON(ctx, config, h.logger) +} + +// updateVectorStoreConfig handles PUT /api/config/vector-store - Update vector store configuration +func (h *ConfigHandler) updateVectorStoreConfig(ctx *fasthttp.RequestCtx) { + if h.store.ConfigStore == nil { + SendError(ctx, fasthttp.StatusInternalServerError, "Config store not initialized", h.logger) + return + } + + var req vectorstore.Config + + if err := json.Unmarshal(ctx.PostBody(), &req); err != nil { + SendError(ctx, fasthttp.StatusBadRequest, fmt.Sprintf("Invalid request format: %v", err), h.logger) + return + } + + if err := h.store.ConfigStore.UpdateVectorStoreConfig(&req); err != nil { + h.logger.Warn(fmt.Sprintf("failed to save vector store configuration: %v", err)) + SendError(ctx, fasthttp.StatusInternalServerError, fmt.Sprintf("failed to save vector store configuration: %v", err), h.logger) + return + } + + ctx.SetStatusCode(fasthttp.StatusOK) + SendJSON(ctx, map[string]string{"status": "success"}, h.logger) +} + +// getLogStoreConfig handles GET /api/config/log-store - Get the current log store configuration +func (h *ConfigHandler) getLogStoreConfig(ctx *fasthttp.RequestCtx) { + if h.store.ConfigStore == nil { + SendError(ctx, fasthttp.StatusServiceUnavailable, "config store not available", h.logger) + return + } + + config, err := h.store.ConfigStore.GetLogsStoreConfig() + if err != nil { + SendError(ctx, fasthttp.StatusInternalServerError, + fmt.Sprintf("failed to fetch log store config: %v", err), h.logger) + return + } + + SendJSON(ctx, config, h.logger) +} + +// updateLogStoreConfig handles PUT /api/config/log-store - Update log store configuration +func (h *ConfigHandler) updateLogStoreConfig(ctx *fasthttp.RequestCtx) { + if h.store.ConfigStore == nil { + SendError(ctx, fasthttp.StatusInternalServerError, "Config store not initialized", h.logger) + return + } + + var req logstore.Config + + if err := json.Unmarshal(ctx.PostBody(), &req); err != nil { + SendError(ctx, fasthttp.StatusBadRequest, fmt.Sprintf("Invalid request format: %v", err), h.logger) + return + } + + if err := h.store.ConfigStore.UpdateLogsStoreConfig(&req); err != nil { + h.logger.Warn(fmt.Sprintf("failed to save log store configuration: %v", err)) + SendError(ctx, fasthttp.StatusInternalServerError, fmt.Sprintf("failed to save log store configuration: %v", err), h.logger) + return + } + + ctx.SetStatusCode(fasthttp.StatusOK) + SendJSON(ctx, map[string]string{"status": "success"}, h.logger) } diff --git a/ui/app/config/page.tsx b/ui/app/config/page.tsx index 514966fd9..1bfb42a8b 100644 --- a/ui/app/config/page.tsx +++ b/ui/app/config/page.tsx @@ -1,6 +1,8 @@ "use client"; import PluginsForm from "@/app/config/views/pluginsForm"; +import VectorStoreForm from "@/app/config/views/vectorStoreForm"; +import LogStoreForm from "@/app/config/views/logStoreForm"; import FullPageLoader from "@/components/fullPageLoader"; import { Alert, AlertDescription } from "@/components/ui/alert"; import { CardDescription, CardHeader, CardTitle } from "@/components/ui/card"; @@ -364,6 +366,10 @@ export default function ConfigPage() { + + + +
diff --git a/ui/app/config/views/logStoreForm.tsx b/ui/app/config/views/logStoreForm.tsx new file mode 100644 index 000000000..a1c692f6b --- /dev/null +++ b/ui/app/config/views/logStoreForm.tsx @@ -0,0 +1,149 @@ +"use client"; + +import { Alert, AlertDescription } from "@/components/ui/alert"; +import { Button } from "@/components/ui/button"; +import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"; +import { Input } from "@/components/ui/input"; +import { Label } from "@/components/ui/label"; +import { Switch } from "@/components/ui/switch"; +import { useGetLogStoreConfigQuery, useUpdateLogStoreConfigMutation } from "@/lib/store"; +import { LogStoreConfig, SQLiteConfig } from "@/lib/types/config"; +import { getErrorMessage } from "@/lib/store"; +import { AlertTriangle, Database, Save } from "lucide-react"; +import { useCallback, useEffect, useState } from "react"; +import { toast } from "sonner"; + +const defaultSQLiteConfig: SQLiteConfig = { + path: "./bifrost.db", +}; + +export default function LogStoreForm() { + const { data: logStoreConfig, isLoading } = useGetLogStoreConfigQuery(); + const [updateLogStoreConfig] = useUpdateLogStoreConfigMutation(); + + const [localConfig, setLocalConfig] = useState({ + enabled: false, + type: "sqlite", + config: defaultSQLiteConfig, + }); + + const [needsRestart, setNeedsRestart] = useState(false); + const [hasChanges, setHasChanges] = useState(false); + + // Update local config when data is loaded + useEffect(() => { + if (logStoreConfig) { + setLocalConfig(logStoreConfig); + setHasChanges(false); + } + }, [logStoreConfig]); + + // Track changes + useEffect(() => { + if (logStoreConfig) { + const hasConfigChanges = JSON.stringify(localConfig) !== JSON.stringify(logStoreConfig); + setHasChanges(hasConfigChanges); + setNeedsRestart(hasConfigChanges); + } + }, [localConfig, logStoreConfig]); + + const handleEnabledChange = useCallback((enabled: boolean) => { + setLocalConfig(prev => ({ ...prev, enabled })); + }, []); + + const handleSQLiteConfigChange = useCallback((field: keyof SQLiteConfig, value: string) => { + setLocalConfig(prev => ({ + ...prev, + config: { + ...(prev.config as SQLiteConfig), + [field]: value, + }, + })); + }, []); + + const handleSave = useCallback(async () => { + try { + await updateLogStoreConfig(localConfig).unwrap(); + toast.success("Log store configuration updated successfully."); + setHasChanges(false); + setNeedsRestart(false); + } catch (error) { + toast.error(getErrorMessage(error)); + } + }, [localConfig, updateLogStoreConfig]); + + if (isLoading) { + return
Loading log store configuration...
; + } + + return ( + + + + + Log Store Configuration + + + Configure log store for request and response logging to a SQLite database. + + + +
+
+ +

+ Enable logging of requests and responses to a SQLite database. This can add 40-60mb of overhead to the system memory. +

+
+ +
+ + {localConfig.enabled && ( + <> +
+

SQLite Configuration

+
+ + handleSQLiteConfigChange("path", e.target.value)} + placeholder="./bifrost.db" + /> +

+ Path to the SQLite database file. Use relative path for current directory or absolute path. +

+
+
+ + {needsRestart && ( + + + + Log store configuration changes require a Bifrost service restart to take effect. + + + )} + + {hasChanges && ( +
+ +
+ )} + + )} +
+
+ ); +} + diff --git a/ui/app/config/views/vectorStoreForm.tsx b/ui/app/config/views/vectorStoreForm.tsx new file mode 100644 index 000000000..9f4d19d33 --- /dev/null +++ b/ui/app/config/views/vectorStoreForm.tsx @@ -0,0 +1,269 @@ +"use client"; + +import { Alert, AlertDescription } from "@/components/ui/alert"; +import { Button } from "@/components/ui/button"; +import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"; +import { Input } from "@/components/ui/input"; +import { Label } from "@/components/ui/label"; +import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"; +import { Switch } from "@/components/ui/switch"; +import { Textarea } from "@/components/ui/textarea"; +import { useGetVectorStoreConfigQuery, useUpdateVectorStoreConfigMutation } from "@/lib/store"; +import { VectorStoreConfig, WeaviateConfig, RedisConfig, VectorStoreType } from "@/lib/types/config"; +import { getErrorMessage } from "@/lib/store"; +import { AlertTriangle, Database, Save } from "lucide-react"; +import { useCallback, useEffect, useState } from "react"; +import { toast } from "sonner"; + +const defaultWeaviateConfig: WeaviateConfig = { + scheme: "http", + host: "localhost:8080", + api_key: "", +}; + +const defaultRedisConfig: RedisConfig = { + addr: "localhost:6379", + username: "", + password: "", + db: 0 +}; + +export default function VectorStoreForm() { + const { data: vectorStoreConfig, isLoading } = useGetVectorStoreConfigQuery(); + const [updateVectorStoreConfig] = useUpdateVectorStoreConfigMutation(); + + const [localConfig, setLocalConfig] = useState({ + enabled: false, + type: "weaviate", + config: defaultWeaviateConfig, + }); + + const [needsRestart, setNeedsRestart] = useState(false); + const [hasChanges, setHasChanges] = useState(false); + + // Update local config when data is loaded + useEffect(() => { + if (vectorStoreConfig) { + setLocalConfig(vectorStoreConfig); + setHasChanges(false); + } + }, [vectorStoreConfig]); + + // Track changes + useEffect(() => { + if (vectorStoreConfig) { + const hasConfigChanges = JSON.stringify(localConfig) !== JSON.stringify(vectorStoreConfig); + setHasChanges(hasConfigChanges); + setNeedsRestart(hasConfigChanges); + } + }, [localConfig, vectorStoreConfig]); + + const handleEnabledChange = useCallback((enabled: boolean) => { + setLocalConfig(prev => ({ ...prev, enabled })); + }, []); + + const handleTypeChange = useCallback((type: VectorStoreType) => { + const defaultConfig = type === "weaviate" ? defaultWeaviateConfig : defaultRedisConfig; + setLocalConfig(prev => ({ ...prev, type, config: defaultConfig })); + }, []); + + const handleWeaviateConfigChange = useCallback((field: keyof WeaviateConfig, value: string | number | boolean | Record) => { + setLocalConfig(prev => ({ + ...prev, + config: { + ...(prev.config as WeaviateConfig), + [field]: value, + }, + })); + }, []); + + const handleRedisConfigChange = useCallback((field: keyof RedisConfig, value: string | number) => { + setLocalConfig(prev => ({ + ...prev, + config: { + ...(prev.config as RedisConfig), + [field]: value, + }, + })); + }, []); + + const handleSave = useCallback(async () => { + try { + await updateVectorStoreConfig(localConfig).unwrap(); + toast.success("Vector store configuration updated successfully."); + setHasChanges(false); + setNeedsRestart(false); + } catch (error) { + toast.error(getErrorMessage(error)); + } + }, [localConfig, updateVectorStoreConfig]); + + const renderWeaviateConfig = () => { + const config = localConfig.config as WeaviateConfig; + return ( +
+
+
+ + +
+
+ + handleWeaviateConfigChange("host", e.target.value)} + placeholder="localhost:8080" + /> +
+
+
+ + handleWeaviateConfigChange("api_key", e.target.value)} + placeholder="Enter API key if required" + /> +
+
+ ); + }; + + const renderRedisConfig = () => { + const config = localConfig.config as RedisConfig; + return ( +
+
+
+ + handleRedisConfigChange("addr", e.target.value)} + placeholder="localhost:6379" + /> +
+
+ + handleRedisConfigChange("db", parseInt(e.target.value) || 0)} + min="0" + /> +
+
+
+
+ + handleRedisConfigChange("username", e.target.value)} + placeholder="Redis username" + /> +
+
+ + handleRedisConfigChange("password", e.target.value)} + placeholder="Redis password" + /> +
+
+
+ ); + }; + + if (isLoading) { + return
Loading vector store configuration...
; + } + + return ( + + + + + Vector Store Configuration + + + Configure vector store for semantic caching and embeddings storage. + + + +
+
+ +

+ Enable vector store for semantic caching and embeddings storage. +

+
+ +
+ + {localConfig.enabled && ( + <> +
+ + +
+ +
+

+ {localConfig.type === "weaviate" ? "Weaviate Configuration" : "Redis Configuration"} +

+ {localConfig.type === "weaviate" ? renderWeaviateConfig() : renderRedisConfig()} +
+ + {needsRestart && ( + + + + Vector store configuration changes require a Bifrost service restart to take effect. + + + )} + + {hasChanges && ( +
+ +
+ )} + + )} +
+
+ ); +} diff --git a/ui/lib/store/apis/baseApi.ts b/ui/lib/store/apis/baseApi.ts index 26e4249a5..b1ca3e978 100644 --- a/ui/lib/store/apis/baseApi.ts +++ b/ui/lib/store/apis/baseApi.ts @@ -67,6 +67,8 @@ export const baseApi = createApi({ "MCPClients", "Config", "CacheConfig", + "VectorStoreConfig", + "LogStoreConfig", "VirtualKeys", "Teams", "Customers", diff --git a/ui/lib/store/apis/configApi.ts b/ui/lib/store/apis/configApi.ts index a95e84dff..d409f9ce2 100644 --- a/ui/lib/store/apis/configApi.ts +++ b/ui/lib/store/apis/configApi.ts @@ -1,4 +1,4 @@ -import { BifrostConfig, CoreConfig } from "@/lib/types/config"; +import { BifrostConfig, CoreConfig, VectorStoreConfig, LogStoreConfig } from "@/lib/types/config"; import { baseApi } from "./baseApi"; export const configApi = baseApi.injectEndpoints({ @@ -28,7 +28,52 @@ export const configApi = baseApi.injectEndpoints({ }), invalidatesTags: ["Config"], }), + + // Get vector store configuration + getVectorStoreConfig: builder.query({ + query: () => ({ + url: "/config/vector-store", + }), + providesTags: ["VectorStoreConfig"], + }), + + // Update vector store configuration + updateVectorStoreConfig: builder.mutation({ + query: (data) => ({ + url: "/config/vector-store", + method: "PUT", + body: data, + }), + invalidatesTags: ["VectorStoreConfig", "Config"], + }), + + // Get log store configuration + getLogStoreConfig: builder.query({ + query: () => ({ + url: "/config/log-store", + }), + providesTags: ["LogStoreConfig"], + }), + + // Update log store configuration + updateLogStoreConfig: builder.mutation({ + query: (data) => ({ + url: "/config/log-store", + method: "PUT", + body: data, + }), + invalidatesTags: ["LogStoreConfig", "Config"], + }), }), }); -export const { useGetVersionQuery, useGetCoreConfigQuery, useUpdateCoreConfigMutation, useLazyGetCoreConfigQuery } = configApi; +export const { + useGetVersionQuery, + useGetCoreConfigQuery, + useUpdateCoreConfigMutation, + useLazyGetCoreConfigQuery, + useGetVectorStoreConfigQuery, + useUpdateVectorStoreConfigMutation, + useGetLogStoreConfigQuery, + useUpdateLogStoreConfigMutation +} = configApi; diff --git a/ui/lib/types/config.ts b/ui/lib/types/config.ts index 914ca2657..11d9bfdfe 100644 --- a/ui/lib/types/config.ts +++ b/ui/lib/types/config.ts @@ -268,5 +268,50 @@ export interface ProviderFormData { custom_provider_config?: FormCustomProviderConfig; } +// Vector Store Configuration Types +export type VectorStoreType = "weaviate" | "redis"; + +export interface WeaviateConfig { + scheme: string; + host: string; + api_key?: string; +} + +export interface RedisConfig { + addr: string; + username?: string; + password?: string; + db?: number; + pool_size?: number; + max_active_conns?: number; + min_idle_conns?: number; + max_idle_conns?: number; + conn_max_lifetime?: number; // Duration in seconds + conn_max_idle_time?: number; // Duration in seconds + dial_timeout?: number; // Duration in seconds + read_timeout?: number; // Duration in seconds + write_timeout?: number; // Duration in seconds + context_timeout?: number; // Duration in seconds +} + +export interface VectorStoreConfig { + enabled: boolean; + type: VectorStoreType; + config: WeaviateConfig | RedisConfig; +} + +// Log Store Configuration Types +export type LogStoreType = "sqlite"; + +export interface SQLiteConfig { + path: string; +} + +export interface LogStoreConfig { + enabled: boolean; + type: LogStoreType; + config: SQLiteConfig; +} + // Status types export type ProviderStatus = "active" | "error" | "added" | "updated" | "deleted"; From 8c55d3ed73a5d6ff81eef71eb234abba5d8a93c9 Mon Sep 17 00:00:00 2001 From: rohan Date: Thu, 18 Sep 2025 03:30:10 +0530 Subject: [PATCH 2/3] removed extra parameters from redisConfig --- ui/lib/types/config.ts | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/ui/lib/types/config.ts b/ui/lib/types/config.ts index 11d9bfdfe..7cb1ce64e 100644 --- a/ui/lib/types/config.ts +++ b/ui/lib/types/config.ts @@ -282,16 +282,6 @@ export interface RedisConfig { username?: string; password?: string; db?: number; - pool_size?: number; - max_active_conns?: number; - min_idle_conns?: number; - max_idle_conns?: number; - conn_max_lifetime?: number; // Duration in seconds - conn_max_idle_time?: number; // Duration in seconds - dial_timeout?: number; // Duration in seconds - read_timeout?: number; // Duration in seconds - write_timeout?: number; // Duration in seconds - context_timeout?: number; // Duration in seconds } export interface VectorStoreConfig { From eec23aa3d57678dc7e0d7c2d357f48df0bbdfca9 Mon Sep 17 00:00:00 2001 From: rohan Date: Sat, 20 Sep 2025 20:58:51 +0530 Subject: [PATCH 3/3] updated config logic --- transports/bifrost-http/handlers/config.go | 60 ++++++++++++++++++++-- transports/bifrost-http/lib/config.go | 14 +++++ 2 files changed, 70 insertions(+), 4 deletions(-) diff --git a/transports/bifrost-http/handlers/config.go b/transports/bifrost-http/handlers/config.go index ec79693a6..b9df5bdab 100644 --- a/transports/bifrost-http/handlers/config.go +++ b/transports/bifrost-http/handlers/config.go @@ -39,11 +39,9 @@ func (h *ConfigHandler) RegisterRoutes(r *router.Router) { r.GET("/api/config", h.getConfig) r.PUT("/api/config", h.updateConfig) r.GET("/api/version", h.getVersion) - // Vector store configuration endpoints r.GET("/api/config/vector-store", h.getVectorStoreConfig) r.PUT("/api/config/vector-store", h.updateVectorStoreConfig) - // Log store configuration endpoints r.GET("/api/config/log-store", h.getLogStoreConfig) r.PUT("/api/config/log-store", h.updateLogStoreConfig) @@ -144,7 +142,7 @@ func (h *ConfigHandler) getVectorStoreConfig(ctx *fasthttp.RequestCtx) { return } - config, err := h.store.ConfigStore.GetVectorStoreConfig() + config, err := h.store.GetVectorStoreConfigRedacted() if err != nil { SendError(ctx, fasthttp.StatusInternalServerError, fmt.Sprintf("failed to fetch vector store config: %v", err), h.logger) @@ -168,7 +166,25 @@ func (h *ConfigHandler) updateVectorStoreConfig(ctx *fasthttp.RequestCtx) { return } - if err := h.store.ConfigStore.UpdateVectorStoreConfig(&req); err != nil { + // Get the raw config to access actual values for merging with redacted request values + oldConfigRaw, err := h.store.ConfigStore.GetVectorStoreConfig() + if err != nil { + SendError(ctx, fasthttp.StatusInternalServerError, fmt.Sprintf("failed to get current vector store config: %v", err), h.logger) + return + } + + if oldConfigRaw == nil { + oldConfigRaw = &vectorstore.Config{} + } + + // Merge redacted values with actual values + mergedConfig, err := h.mergeVectorStoreConfig(oldConfigRaw, &req) + if err != nil { + SendError(ctx, fasthttp.StatusBadRequest, fmt.Sprintf("failed to merge vector store config: %v", err), h.logger) + return + } + + if err := h.store.ConfigStore.UpdateVectorStoreConfig(mergedConfig); err != nil { h.logger.Warn(fmt.Sprintf("failed to save vector store configuration: %v", err)) SendError(ctx, fasthttp.StatusInternalServerError, fmt.Sprintf("failed to save vector store configuration: %v", err), h.logger) return @@ -218,3 +234,39 @@ func (h *ConfigHandler) updateLogStoreConfig(ctx *fasthttp.RequestCtx) { ctx.SetStatusCode(fasthttp.StatusOK) SendJSON(ctx, map[string]string{"status": "success"}, h.logger) } + +// mergeVectorStoreConfig merges new config with old, preserving values that are redacted in the new config +func (h *ConfigHandler) mergeVectorStoreConfig(oldConfig *vectorstore.Config, newConfig *vectorstore.Config) (*vectorstore.Config, error) { + // Start with the new config + merged := *newConfig + + // Handle different vector store types + if oldConfig.Type == newConfig.Type { + switch newConfig.Type { + case vectorstore.VectorStoreTypeWeaviate: + oldWeaviateConfig, oldOk := oldConfig.Config.(*vectorstore.WeaviateConfig) + newWeaviateConfig, newOk := newConfig.Config.(*vectorstore.WeaviateConfig) + if oldOk && newOk { + mergedWeaviateConfig := *newWeaviateConfig + // Preserve old API key if new one is redacted + if lib.IsRedacted(newWeaviateConfig.ApiKey) && oldWeaviateConfig.ApiKey != "" { + mergedWeaviateConfig.ApiKey = oldWeaviateConfig.ApiKey + } + merged.Config = &mergedWeaviateConfig + } + case vectorstore.VectorStoreTypeRedis: + oldRedisConfig, oldOk := oldConfig.Config.(*vectorstore.RedisConfig) + newRedisConfig, newOk := newConfig.Config.(*vectorstore.RedisConfig) + if oldOk && newOk { + mergedRedisConfig := *newRedisConfig + // Preserve old password if new one is redacted + if lib.IsRedacted(newRedisConfig.Addr) && oldRedisConfig.Addr != "" { + mergedRedisConfig.Addr = oldRedisConfig.Addr + } + merged.Config = &mergedRedisConfig + } + } + } + + return &merged, nil +} diff --git a/transports/bifrost-http/lib/config.go b/transports/bifrost-http/lib/config.go index c116b4beb..456260780 100644 --- a/transports/bifrost-http/lib/config.go +++ b/transports/bifrost-http/lib/config.go @@ -2050,6 +2050,20 @@ func (s *Config) GetVectorStoreConfigRedacted() (*vectorstore.Config, error) { redactedVectorStoreConfig := *vectorStoreConfig redactedVectorStoreConfig.Config = &redactedWeaviateConfig return &redactedVectorStoreConfig, nil + } else if vectorStoreConfig.Type == vectorstore.VectorStoreTypeRedis { + redisConfig, ok := vectorStoreConfig.Config.(*vectorstore.RedisConfig) + if !ok { + return nil, fmt.Errorf("failed to cast vector store config to redis config") + } + // Create a copy to avoid modifying the original + redactedRedisConfig := *redisConfig + // Redact details here + if redactedRedisConfig.Addr != "" { + redactedRedisConfig.Addr = RedactKey(redactedRedisConfig.Addr) + } + redactedVectorStoreConfig := *vectorStoreConfig + redactedVectorStoreConfig.Config = &redactedRedisConfig + return &redactedVectorStoreConfig, nil } return nil, nil }