diff --git a/core/application/config_file_watcher.go b/core/application/config_file_watcher.go
index 8eb26355d132..c985c0d8012d 100644
--- a/core/application/config_file_watcher.go
+++ b/core/application/config_file_watcher.go
@@ -189,10 +189,11 @@ func readRuntimeSettingsJson(startupAppConfig config.ApplicationConfig) fileHand
handler := func(fileContent []byte, appConfig *config.ApplicationConfig) error {
xlog.Debug("processing runtime_settings.json")
- // Determine if settings came from env vars by comparing with startup config
- // startupAppConfig contains the original values set from env vars at startup.
- // If current values match startup values, they came from env vars (or defaults).
- // We apply file settings only if current values match startup values (meaning not from env vars).
+ // Determine if settings were changed via API after startup.
+ // startupAppConfig contains values set from env vars at startup.
+ // If current value matches startup value, it was NOT changed via API,
+ // so it's safe to apply file settings. If it differs, it was changed
+ // via API and should NOT be overwritten by the file.
envWatchdogIdle := appConfig.WatchDogIdle == startupAppConfig.WatchDogIdle
envWatchdogBusy := appConfig.WatchDogBusy == startupAppConfig.WatchDogBusy
envWatchdogIdleTimeout := appConfig.WatchDogIdleTimeout == startupAppConfig.WatchDogIdleTimeout
@@ -219,6 +220,16 @@ func readRuntimeSettingsJson(startupAppConfig config.ApplicationConfig) fileHand
envForceEvictionWhenBusy := appConfig.ForceEvictionWhenBusy == startupAppConfig.ForceEvictionWhenBusy
envLRUEvictionMaxRetries := appConfig.LRUEvictionMaxRetries == startupAppConfig.LRUEvictionMaxRetries
envLRUEvictionRetryInterval := appConfig.LRUEvictionRetryInterval == startupAppConfig.LRUEvictionRetryInterval
+ envAgentPoolEnabled := appConfig.AgentPool.Enabled == startupAppConfig.AgentPool.Enabled
+ envAgentPoolDefaultModel := appConfig.AgentPool.DefaultModel == startupAppConfig.AgentPool.DefaultModel
+ envAgentPoolEmbeddingModel := appConfig.AgentPool.EmbeddingModel == startupAppConfig.AgentPool.EmbeddingModel
+ envAgentPoolMaxChunkingSize := appConfig.AgentPool.MaxChunkingSize == startupAppConfig.AgentPool.MaxChunkingSize
+ envAgentPoolChunkOverlap := appConfig.AgentPool.ChunkOverlap == startupAppConfig.AgentPool.ChunkOverlap
+ envAgentPoolEnableLogs := appConfig.AgentPool.EnableLogs == startupAppConfig.AgentPool.EnableLogs
+ envAgentPoolCollectionDBPath := appConfig.AgentPool.CollectionDBPath == startupAppConfig.AgentPool.CollectionDBPath
+ envAgentPoolVectorEngine := appConfig.AgentPool.VectorEngine == startupAppConfig.AgentPool.VectorEngine
+ envAgentPoolDatabaseURL := appConfig.AgentPool.DatabaseURL == startupAppConfig.AgentPool.DatabaseURL
+ envAgentPoolAgentHubURL := appConfig.AgentPool.AgentHubURL == startupAppConfig.AgentPool.AgentHubURL
if len(fileContent) > 0 {
var settings config.RuntimeSettings
@@ -227,20 +238,20 @@ func readRuntimeSettingsJson(startupAppConfig config.ApplicationConfig) fileHand
return err
}
- // Apply file settings only if they don't match startup values (i.e., not from env vars)
- if settings.WatchdogIdleEnabled != nil && !envWatchdogIdle {
+ // Apply file settings only if current values match startup values (i.e., not changed via API)
+ if settings.WatchdogIdleEnabled != nil && envWatchdogIdle {
appConfig.WatchDogIdle = *settings.WatchdogIdleEnabled
if appConfig.WatchDogIdle {
appConfig.WatchDog = true
}
}
- if settings.WatchdogBusyEnabled != nil && !envWatchdogBusy {
+ if settings.WatchdogBusyEnabled != nil && envWatchdogBusy {
appConfig.WatchDogBusy = *settings.WatchdogBusyEnabled
if appConfig.WatchDogBusy {
appConfig.WatchDog = true
}
}
- if settings.WatchdogIdleTimeout != nil && !envWatchdogIdleTimeout {
+ if settings.WatchdogIdleTimeout != nil && envWatchdogIdleTimeout {
dur, err := time.ParseDuration(*settings.WatchdogIdleTimeout)
if err == nil {
appConfig.WatchDogIdleTimeout = dur
@@ -248,7 +259,7 @@ func readRuntimeSettingsJson(startupAppConfig config.ApplicationConfig) fileHand
xlog.Warn("invalid watchdog idle timeout in runtime_settings.json", "error", err, "timeout", *settings.WatchdogIdleTimeout)
}
}
- if settings.WatchdogBusyTimeout != nil && !envWatchdogBusyTimeout {
+ if settings.WatchdogBusyTimeout != nil && envWatchdogBusyTimeout {
dur, err := time.ParseDuration(*settings.WatchdogBusyTimeout)
if err == nil {
appConfig.WatchDogBusyTimeout = dur
@@ -257,11 +268,11 @@ func readRuntimeSettingsJson(startupAppConfig config.ApplicationConfig) fileHand
}
}
// Handle MaxActiveBackends (new) and SingleBackend (deprecated)
- if settings.MaxActiveBackends != nil && !envMaxActiveBackends {
+ if settings.MaxActiveBackends != nil && envMaxActiveBackends {
appConfig.MaxActiveBackends = *settings.MaxActiveBackends
// For backward compatibility, also set SingleBackend if MaxActiveBackends == 1
appConfig.SingleBackend = (*settings.MaxActiveBackends == 1)
- } else if settings.SingleBackend != nil && !envSingleBackend {
+ } else if settings.SingleBackend != nil && envSingleBackend {
// Legacy: SingleBackend maps to MaxActiveBackends = 1
appConfig.SingleBackend = *settings.SingleBackend
if *settings.SingleBackend {
@@ -270,22 +281,22 @@ func readRuntimeSettingsJson(startupAppConfig config.ApplicationConfig) fileHand
appConfig.MaxActiveBackends = 0
}
}
- if settings.MemoryReclaimerEnabled != nil && !envMemoryReclaimerEnabled {
+ if settings.MemoryReclaimerEnabled != nil && envMemoryReclaimerEnabled {
appConfig.MemoryReclaimerEnabled = *settings.MemoryReclaimerEnabled
if appConfig.MemoryReclaimerEnabled {
appConfig.WatchDog = true // Memory reclaimer requires watchdog
}
}
- if settings.MemoryReclaimerThreshold != nil && !envMemoryReclaimerThreshold {
+ if settings.MemoryReclaimerThreshold != nil && envMemoryReclaimerThreshold {
appConfig.MemoryReclaimerThreshold = *settings.MemoryReclaimerThreshold
}
- if settings.ForceEvictionWhenBusy != nil && !envForceEvictionWhenBusy {
+ if settings.ForceEvictionWhenBusy != nil && envForceEvictionWhenBusy {
appConfig.ForceEvictionWhenBusy = *settings.ForceEvictionWhenBusy
}
- if settings.LRUEvictionMaxRetries != nil && !envLRUEvictionMaxRetries {
+ if settings.LRUEvictionMaxRetries != nil && envLRUEvictionMaxRetries {
appConfig.LRUEvictionMaxRetries = *settings.LRUEvictionMaxRetries
}
- if settings.LRUEvictionRetryInterval != nil && !envLRUEvictionRetryInterval {
+ if settings.LRUEvictionRetryInterval != nil && envLRUEvictionRetryInterval {
dur, err := time.ParseDuration(*settings.LRUEvictionRetryInterval)
if err == nil {
appConfig.LRUEvictionRetryInterval = dur
@@ -293,46 +304,46 @@ func readRuntimeSettingsJson(startupAppConfig config.ApplicationConfig) fileHand
xlog.Warn("invalid LRU eviction retry interval in runtime_settings.json", "error", err, "interval", *settings.LRUEvictionRetryInterval)
}
}
- if settings.Threads != nil && !envThreads {
+ if settings.Threads != nil && envThreads {
appConfig.Threads = *settings.Threads
}
- if settings.ContextSize != nil && !envContextSize {
+ if settings.ContextSize != nil && envContextSize {
appConfig.ContextSize = *settings.ContextSize
}
- if settings.F16 != nil && !envF16 {
+ if settings.F16 != nil && envF16 {
appConfig.F16 = *settings.F16
}
- if settings.Debug != nil && !envDebug {
+ if settings.Debug != nil && envDebug {
appConfig.Debug = *settings.Debug
}
- if settings.CORS != nil && !envCORS {
+ if settings.CORS != nil && envCORS {
appConfig.CORS = *settings.CORS
}
- if settings.CSRF != nil && !envCSRF {
+ if settings.CSRF != nil && envCSRF {
appConfig.DisableCSRF = *settings.CSRF
}
- if settings.CORSAllowOrigins != nil && !envCORSAllowOrigins {
+ if settings.CORSAllowOrigins != nil && envCORSAllowOrigins {
appConfig.CORSAllowOrigins = *settings.CORSAllowOrigins
}
- if settings.P2PToken != nil && !envP2PToken {
+ if settings.P2PToken != nil && envP2PToken {
appConfig.P2PToken = *settings.P2PToken
}
- if settings.P2PNetworkID != nil && !envP2PNetworkID {
+ if settings.P2PNetworkID != nil && envP2PNetworkID {
appConfig.P2PNetworkID = *settings.P2PNetworkID
}
- if settings.Federated != nil && !envFederated {
+ if settings.Federated != nil && envFederated {
appConfig.Federated = *settings.Federated
}
- if settings.Galleries != nil && !envGalleries {
+ if settings.Galleries != nil && envGalleries {
appConfig.Galleries = *settings.Galleries
}
- if settings.BackendGalleries != nil && !envBackendGalleries {
+ if settings.BackendGalleries != nil && envBackendGalleries {
appConfig.BackendGalleries = *settings.BackendGalleries
}
- if settings.AutoloadGalleries != nil && !envAutoloadGalleries {
+ if settings.AutoloadGalleries != nil && envAutoloadGalleries {
appConfig.AutoloadGalleries = *settings.AutoloadGalleries
}
- if settings.AutoloadBackendGalleries != nil && !envAutoloadBackendGalleries {
+ if settings.AutoloadBackendGalleries != nil && envAutoloadBackendGalleries {
appConfig.AutoloadBackendGalleries = *settings.AutoloadBackendGalleries
}
if settings.ApiKeys != nil {
@@ -344,12 +355,42 @@ func readRuntimeSettingsJson(startupAppConfig config.ApplicationConfig) fileHand
// Replace all runtime keys with what's in runtime_settings.json
appConfig.ApiKeys = append(envKeys, runtimeKeys...)
}
- if settings.AgentJobRetentionDays != nil && !envAgentJobRetentionDays {
+ if settings.AgentJobRetentionDays != nil && envAgentJobRetentionDays {
appConfig.AgentJobRetentionDays = *settings.AgentJobRetentionDays
}
+ if settings.AgentPoolEnabled != nil && envAgentPoolEnabled {
+ appConfig.AgentPool.Enabled = *settings.AgentPoolEnabled
+ }
+ if settings.AgentPoolDefaultModel != nil && envAgentPoolDefaultModel {
+ appConfig.AgentPool.DefaultModel = *settings.AgentPoolDefaultModel
+ }
+ if settings.AgentPoolEmbeddingModel != nil && envAgentPoolEmbeddingModel {
+ appConfig.AgentPool.EmbeddingModel = *settings.AgentPoolEmbeddingModel
+ }
+ if settings.AgentPoolMaxChunkingSize != nil && envAgentPoolMaxChunkingSize {
+ appConfig.AgentPool.MaxChunkingSize = *settings.AgentPoolMaxChunkingSize
+ }
+ if settings.AgentPoolChunkOverlap != nil && envAgentPoolChunkOverlap {
+ appConfig.AgentPool.ChunkOverlap = *settings.AgentPoolChunkOverlap
+ }
+ if settings.AgentPoolEnableLogs != nil && envAgentPoolEnableLogs {
+ appConfig.AgentPool.EnableLogs = *settings.AgentPoolEnableLogs
+ }
+ if settings.AgentPoolCollectionDBPath != nil && envAgentPoolCollectionDBPath {
+ appConfig.AgentPool.CollectionDBPath = *settings.AgentPoolCollectionDBPath
+ }
+ if settings.AgentPoolVectorEngine != nil && envAgentPoolVectorEngine {
+ appConfig.AgentPool.VectorEngine = *settings.AgentPoolVectorEngine
+ }
+ if settings.AgentPoolDatabaseURL != nil && envAgentPoolDatabaseURL {
+ appConfig.AgentPool.DatabaseURL = *settings.AgentPoolDatabaseURL
+ }
+ if settings.AgentPoolAgentHubURL != nil && envAgentPoolAgentHubURL {
+ appConfig.AgentPool.AgentHubURL = *settings.AgentPoolAgentHubURL
+ }
// If watchdog is enabled via file but not via env, ensure WatchDog flag is set
- if !envWatchdogIdle && !envWatchdogBusy {
+ if envWatchdogIdle && envWatchdogBusy {
if settings.WatchdogEnabled != nil && *settings.WatchdogEnabled {
appConfig.WatchDog = true
}
diff --git a/core/application/startup.go b/core/application/startup.go
index 728c3c97221e..e0254da498c9 100644
--- a/core/application/startup.go
+++ b/core/application/startup.go
@@ -263,7 +263,7 @@ func New(opts ...config.AppOption) (*Application, error) {
// This applies file settings with env var precedence (env vars take priority)
// Note: startupConfigCopy was already created above, so it has the original env var values
if options.DynamicConfigsDir != "" {
- loadRuntimeSettingsFromFile(options)
+ loadRuntimeSettingsFromFile(options, &startupConfigCopy)
}
application.ModelLoader().SetBackendLoggingEnabled(options.EnableBackendLogging)
@@ -336,21 +336,9 @@ func startWatcher(options *config.ApplicationConfig) {
// loadRuntimeSettingsFromFile loads settings from runtime_settings.json with env var precedence
// This function is called at startup, before env vars are applied via AppOptions.
// Since env vars are applied via AppOptions in run.go, we need to check if they're set.
-// We do this by checking if the current options values differ from defaults, which would
-// indicate they were set from env vars. However, a simpler approach is to just apply
-// file settings here, and let the AppOptions (which are applied after this) override them.
-// But actually, this is called AFTER AppOptions are applied in New(), so we need to check env vars.
-// The cleanest solution: Store original values before applying file, or check if values match
-// what would be set from env vars. For now, we'll apply file settings and they'll be
-// overridden by AppOptions if env vars were set (but AppOptions are already applied).
-// Actually, this function is called in New() before AppOptions are fully processed for watchdog.
-// Let's check the call order: New() -> loadRuntimeSettingsFromFile() -> initializeWatchdog()
-// But AppOptions are applied in NewApplicationConfig() which is called first.
-// So at this point, options already has values from env vars. We should compare against
-// defaults to see if env vars were set. But we don't have defaults stored.
-// Simplest: Just apply file settings. If env vars were set, they're already in options.
-// The file watcher handler will handle runtime changes properly by comparing with startupAppConfig.
-func loadRuntimeSettingsFromFile(options *config.ApplicationConfig) {
+// We do this by comparing current values with startupConfig (values before file loading).
+// If current value matches startup value, it wasn't set from env var, so we can apply file.
+func loadRuntimeSettingsFromFile(options *config.ApplicationConfig, startupConfig *config.ApplicationConfig) {
settingsFile := filepath.Join(options.DynamicConfigsDir, "runtime_settings.json")
fileContent, err := os.ReadFile(settingsFile)
if err != nil {
@@ -370,16 +358,14 @@ func loadRuntimeSettingsFromFile(options *config.ApplicationConfig) {
}
// At this point, options already has values from env vars (via AppOptions in run.go).
- // To avoid env var duplication, we determine if env vars were set by checking if
- // current values differ from defaults. Defaults are: false for bools, 0 for durations.
- // If current value is at default, it likely wasn't set from env var, so we can apply file.
- // If current value is non-default, it was likely set from env var, so we preserve it.
- // Note: This means env vars explicitly setting to false/0 won't be distinguishable from defaults,
- // but that's an acceptable limitation to avoid env var duplication.
+ // startupConfig is a snapshot taken right after AppOptions were applied, so at this point
+ // options == startupConfig for all fields. The comparison ensures file settings are applied
+ // consistently with the file watcher logic in config_file_watcher.go.
+ // Note: At startup, file settings always override env vars. After startup, the file watcher
+ // only applies changes when values haven't been modified via API.
if settings.WatchdogIdleEnabled != nil {
- // Only apply if current value is default (false), suggesting it wasn't set from env var
- if !options.WatchDogIdle {
+ if options.WatchDogIdle == startupConfig.WatchDogIdle {
options.WatchDogIdle = *settings.WatchdogIdleEnabled
if options.WatchDogIdle {
options.WatchDog = true
@@ -387,7 +373,7 @@ func loadRuntimeSettingsFromFile(options *config.ApplicationConfig) {
}
}
if settings.WatchdogBusyEnabled != nil {
- if !options.WatchDogBusy {
+ if options.WatchDogBusy == startupConfig.WatchDogBusy {
options.WatchDogBusy = *settings.WatchdogBusyEnabled
if options.WatchDogBusy {
options.WatchDog = true
@@ -395,8 +381,7 @@ func loadRuntimeSettingsFromFile(options *config.ApplicationConfig) {
}
}
if settings.WatchdogIdleTimeout != nil {
- // Only apply if current value is default (0), suggesting it wasn't set from env var
- if options.WatchDogIdleTimeout == 0 {
+ if options.WatchDogIdleTimeout == startupConfig.WatchDogIdleTimeout {
dur, err := time.ParseDuration(*settings.WatchdogIdleTimeout)
if err == nil {
options.WatchDogIdleTimeout = dur
@@ -406,7 +391,7 @@ func loadRuntimeSettingsFromFile(options *config.ApplicationConfig) {
}
}
if settings.WatchdogBusyTimeout != nil {
- if options.WatchDogBusyTimeout == 0 {
+ if options.WatchDogBusyTimeout == startupConfig.WatchDogBusyTimeout {
dur, err := time.ParseDuration(*settings.WatchdogBusyTimeout)
if err == nil {
options.WatchDogBusyTimeout = dur
@@ -416,27 +401,24 @@ func loadRuntimeSettingsFromFile(options *config.ApplicationConfig) {
}
}
if settings.WatchdogInterval != nil {
- if options.WatchDogInterval == 0 {
+ if options.WatchDogInterval == startupConfig.WatchDogInterval {
dur, err := time.ParseDuration(*settings.WatchdogInterval)
if err == nil {
options.WatchDogInterval = dur
} else {
xlog.Warn("invalid watchdog interval in runtime_settings.json", "error", err, "interval", *settings.WatchdogInterval)
- options.WatchDogInterval = model.DefaultWatchdogInterval
}
}
}
// Handle MaxActiveBackends (new) and SingleBackend (deprecated)
if settings.MaxActiveBackends != nil {
- // Only apply if current value is default (0), suggesting it wasn't set from env var
- if options.MaxActiveBackends == 0 {
+ if options.MaxActiveBackends == startupConfig.MaxActiveBackends {
options.MaxActiveBackends = *settings.MaxActiveBackends
// For backward compatibility, also set SingleBackend if MaxActiveBackends == 1
options.SingleBackend = (*settings.MaxActiveBackends == 1)
}
} else if settings.SingleBackend != nil {
- // Legacy: SingleBackend maps to MaxActiveBackends = 1
- if !options.SingleBackend {
+ if options.SingleBackend == startupConfig.SingleBackend {
options.SingleBackend = *settings.SingleBackend
if *settings.SingleBackend {
options.MaxActiveBackends = 1
@@ -444,8 +426,7 @@ func loadRuntimeSettingsFromFile(options *config.ApplicationConfig) {
}
}
if settings.MemoryReclaimerEnabled != nil {
- // Only apply if current value is default (false), suggesting it wasn't set from env var
- if !options.MemoryReclaimerEnabled {
+ if options.MemoryReclaimerEnabled == startupConfig.MemoryReclaimerEnabled {
options.MemoryReclaimerEnabled = *settings.MemoryReclaimerEnabled
if options.MemoryReclaimerEnabled {
options.WatchDog = true // Memory reclaimer requires watchdog
@@ -453,26 +434,22 @@ func loadRuntimeSettingsFromFile(options *config.ApplicationConfig) {
}
}
if settings.MemoryReclaimerThreshold != nil {
- // Only apply if current value is default (0), suggesting it wasn't set from env var
- if options.MemoryReclaimerThreshold == 0 {
+ if options.MemoryReclaimerThreshold == startupConfig.MemoryReclaimerThreshold {
options.MemoryReclaimerThreshold = *settings.MemoryReclaimerThreshold
}
}
if settings.ForceEvictionWhenBusy != nil {
- // Only apply if current value is default (false), suggesting it wasn't set from env var
- if !options.ForceEvictionWhenBusy {
+ if options.ForceEvictionWhenBusy == startupConfig.ForceEvictionWhenBusy {
options.ForceEvictionWhenBusy = *settings.ForceEvictionWhenBusy
}
}
if settings.LRUEvictionMaxRetries != nil {
- // Only apply if current value is default (30), suggesting it wasn't set from env var
- if options.LRUEvictionMaxRetries == 0 {
+ if options.LRUEvictionMaxRetries == startupConfig.LRUEvictionMaxRetries {
options.LRUEvictionMaxRetries = *settings.LRUEvictionMaxRetries
}
}
if settings.LRUEvictionRetryInterval != nil {
- // Only apply if current value is default (1s), suggesting it wasn't set from env var
- if options.LRUEvictionRetryInterval == 0 {
+ if options.LRUEvictionRetryInterval == startupConfig.LRUEvictionRetryInterval {
dur, err := time.ParseDuration(*settings.LRUEvictionRetryInterval)
if err == nil {
options.LRUEvictionRetryInterval = dur
@@ -482,8 +459,7 @@ func loadRuntimeSettingsFromFile(options *config.ApplicationConfig) {
}
}
if settings.AgentJobRetentionDays != nil {
- // Only apply if current value is default (0), suggesting it wasn't set from env var
- if options.AgentJobRetentionDays == 0 {
+ if options.AgentJobRetentionDays == startupConfig.AgentJobRetentionDays {
options.AgentJobRetentionDays = *settings.AgentJobRetentionDays
}
}
@@ -495,39 +471,91 @@ func loadRuntimeSettingsFromFile(options *config.ApplicationConfig) {
// P2P settings
if settings.P2PToken != nil {
- if options.P2PToken == "" {
+ if options.P2PToken == startupConfig.P2PToken {
options.P2PToken = *settings.P2PToken
}
}
if settings.P2PNetworkID != nil {
- if options.P2PNetworkID == "" {
+ if options.P2PNetworkID == startupConfig.P2PNetworkID {
options.P2PNetworkID = *settings.P2PNetworkID
}
}
if settings.Federated != nil {
- if !options.Federated {
+ if options.Federated == startupConfig.Federated {
options.Federated = *settings.Federated
}
}
if settings.EnableBackendLogging != nil {
- if !options.EnableBackendLogging {
+ if options.EnableBackendLogging == startupConfig.EnableBackendLogging {
options.EnableBackendLogging = *settings.EnableBackendLogging
}
}
// Tracing settings
if settings.EnableTracing != nil {
- if !options.EnableTracing {
+ if options.EnableTracing == startupConfig.EnableTracing {
options.EnableTracing = *settings.EnableTracing
}
}
if settings.TracingMaxItems != nil {
- if options.TracingMaxItems == 0 {
+ if options.TracingMaxItems == startupConfig.TracingMaxItems {
options.TracingMaxItems = *settings.TracingMaxItems
}
}
+ // Agent Pool settings
+ if settings.AgentPoolEnabled != nil {
+ if options.AgentPool.Enabled == startupConfig.AgentPool.Enabled {
+ options.AgentPool.Enabled = *settings.AgentPoolEnabled
+ }
+ }
+ if settings.AgentPoolDefaultModel != nil {
+ if options.AgentPool.DefaultModel == startupConfig.AgentPool.DefaultModel {
+ options.AgentPool.DefaultModel = *settings.AgentPoolDefaultModel
+ }
+ }
+ if settings.AgentPoolEmbeddingModel != nil {
+ if options.AgentPool.EmbeddingModel == startupConfig.AgentPool.EmbeddingModel {
+ options.AgentPool.EmbeddingModel = *settings.AgentPoolEmbeddingModel
+ }
+ }
+ if settings.AgentPoolMaxChunkingSize != nil {
+ if options.AgentPool.MaxChunkingSize == startupConfig.AgentPool.MaxChunkingSize {
+ options.AgentPool.MaxChunkingSize = *settings.AgentPoolMaxChunkingSize
+ }
+ }
+ if settings.AgentPoolChunkOverlap != nil {
+ if options.AgentPool.ChunkOverlap == startupConfig.AgentPool.ChunkOverlap {
+ options.AgentPool.ChunkOverlap = *settings.AgentPoolChunkOverlap
+ }
+ }
+ if settings.AgentPoolEnableLogs != nil {
+ if options.AgentPool.EnableLogs == startupConfig.AgentPool.EnableLogs {
+ options.AgentPool.EnableLogs = *settings.AgentPoolEnableLogs
+ }
+ }
+ if settings.AgentPoolCollectionDBPath != nil {
+ if options.AgentPool.CollectionDBPath == startupConfig.AgentPool.CollectionDBPath {
+ options.AgentPool.CollectionDBPath = *settings.AgentPoolCollectionDBPath
+ }
+ }
+ if settings.AgentPoolVectorEngine != nil {
+ if options.AgentPool.VectorEngine == startupConfig.AgentPool.VectorEngine {
+ options.AgentPool.VectorEngine = *settings.AgentPoolVectorEngine
+ }
+ }
+ if settings.AgentPoolDatabaseURL != nil {
+ if options.AgentPool.DatabaseURL == startupConfig.AgentPool.DatabaseURL {
+ options.AgentPool.DatabaseURL = *settings.AgentPoolDatabaseURL
+ }
+ }
+ if settings.AgentPoolAgentHubURL != nil {
+ if options.AgentPool.AgentHubURL == startupConfig.AgentPool.AgentHubURL {
+ options.AgentPool.AgentHubURL = *settings.AgentPoolAgentHubURL
+ }
+ }
+
xlog.Debug("Runtime settings loaded from runtime_settings.json")
}
diff --git a/core/config/application_config.go b/core/config/application_config.go
index 8d55f83a61cf..5052f4c3efff 100644
--- a/core/config/application_config.go
+++ b/core/config/application_config.go
@@ -898,6 +898,9 @@ func (o *ApplicationConfig) ToRuntimeSettings() RuntimeSettings {
agentPoolChunkOverlap := o.AgentPool.ChunkOverlap
agentPoolEnableLogs := o.AgentPool.EnableLogs
agentPoolCollectionDBPath := o.AgentPool.CollectionDBPath
+ agentPoolVectorEngine := o.AgentPool.VectorEngine
+ agentPoolDatabaseURL := o.AgentPool.DatabaseURL
+ agentPoolAgentHubURL := o.AgentPool.AgentHubURL
return RuntimeSettings{
WatchdogEnabled: &watchdogEnabled,
@@ -940,6 +943,9 @@ func (o *ApplicationConfig) ToRuntimeSettings() RuntimeSettings {
AgentPoolChunkOverlap: &agentPoolChunkOverlap,
AgentPoolEnableLogs: &agentPoolEnableLogs,
AgentPoolCollectionDBPath: &agentPoolCollectionDBPath,
+ AgentPoolVectorEngine: &agentPoolVectorEngine,
+ AgentPoolDatabaseURL: &agentPoolDatabaseURL,
+ AgentPoolAgentHubURL: &agentPoolAgentHubURL,
}
}
@@ -1118,6 +1124,18 @@ func (o *ApplicationConfig) ApplyRuntimeSettings(settings *RuntimeSettings) (req
o.AgentPool.CollectionDBPath = *settings.AgentPoolCollectionDBPath
requireRestart = true
}
+ if settings.AgentPoolVectorEngine != nil {
+ o.AgentPool.VectorEngine = *settings.AgentPoolVectorEngine
+ requireRestart = true
+ }
+ if settings.AgentPoolDatabaseURL != nil {
+ o.AgentPool.DatabaseURL = *settings.AgentPoolDatabaseURL
+ requireRestart = true
+ }
+ if settings.AgentPoolAgentHubURL != nil {
+ o.AgentPool.AgentHubURL = *settings.AgentPoolAgentHubURL
+ requireRestart = true
+ }
// Note: ApiKeys requires special handling (merging with startup keys) - handled in caller
diff --git a/core/config/runtime_settings.go b/core/config/runtime_settings.go
index 6a4117f06490..812204f7aa87 100644
--- a/core/config/runtime_settings.go
+++ b/core/config/runtime_settings.go
@@ -71,4 +71,7 @@ type RuntimeSettings struct {
AgentPoolChunkOverlap *int `json:"agent_pool_chunk_overlap,omitempty"`
AgentPoolEnableLogs *bool `json:"agent_pool_enable_logs,omitempty"`
AgentPoolCollectionDBPath *string `json:"agent_pool_collection_db_path,omitempty"`
+ AgentPoolVectorEngine *string `json:"agent_pool_vector_engine,omitempty"`
+ AgentPoolDatabaseURL *string `json:"agent_pool_database_url,omitempty"`
+ AgentPoolAgentHubURL *string `json:"agent_pool_agent_hub_url,omitempty"`
}
diff --git a/core/http/react-ui/src/pages/Settings.jsx b/core/http/react-ui/src/pages/Settings.jsx
index 36f3bfaf3a04..3cda12527dc3 100644
--- a/core/http/react-ui/src/pages/Settings.jsx
+++ b/core/http/react-ui/src/pages/Settings.jsx
@@ -451,6 +451,15 @@ export default function Settings() {
update('agent_pool_collection_db_path', e.target.value)} placeholder="Leave empty for default" />
+
+ update('agent_pool_vector_engine', e.target.value)} placeholder="chromem" />
+
+
+ update('agent_pool_database_url', e.target.value)} placeholder="Leave empty for default" />
+
+
+ update('agent_pool_agent_hub_url', e.target.value)} placeholder="https://agenthub.localai.io" />
+