feat: auto-create search/tts providers at startup with enable toggle

- Add `enable` column (default false) to search_providers and tts_providers tables
- Auto-create default entries for all provider types on startup (disabled by default)
- Add enable/disable Switch toggle in frontend for both search and TTS providers
- Show green status dot in sidebar for enabled providers, sort enabled first
- Filter bot settings dropdowns to only show enabled providers
This commit is contained in:
Acbox
2026-03-28 23:47:09 +08:00
parent c0057b5c54
commit 90ac222bc9
25 changed files with 420 additions and 63 deletions
+24
View File
@@ -263,6 +263,8 @@ func runServe() {
injectToolProviders,
startRegistrySync,
startMemoryProviderBootstrap,
startSearchProviderBootstrap,
startTtsProviderBootstrap,
startScheduleService,
startHeartbeatService,
startChannelManager,
@@ -875,6 +877,28 @@ func startMemoryProviderBootstrap(lc fx.Lifecycle, log *slog.Logger, mpService *
})
}
func startTtsProviderBootstrap(lc fx.Lifecycle, log *slog.Logger, ttsService *ttspkg.Service) {
lc.Append(fx.Hook{
OnStart: func(ctx context.Context) error {
if err := ttsService.EnsureDefaults(ctx); err != nil {
log.Warn("failed to ensure default tts providers", slog.Any("error", err))
}
return nil
},
})
}
func startSearchProviderBootstrap(lc fx.Lifecycle, log *slog.Logger, spService *searchproviders.Service) {
lc.Append(fx.Hook{
OnStart: func(ctx context.Context) error {
if err := spService.EnsureDefaults(ctx); err != nil {
log.Warn("failed to ensure default search providers", slog.Any("error", err))
}
return nil
},
})
}
func startScheduleService(lc fx.Lifecycle, scheduleService *schedule.Service) {
lc.Append(fx.Hook{
OnStart: func(ctx context.Context) error {
+24
View File
@@ -190,6 +190,8 @@ func runServe() {
injectToolProviders,
startRegistrySync,
startMemoryProviderBootstrap,
startSearchProviderBootstrap,
startTtsProviderBootstrap,
startScheduleService,
startHeartbeatService,
startChannelManager,
@@ -314,6 +316,28 @@ func startMemoryProviderBootstrap(lc fx.Lifecycle, log *slog.Logger, mpService *
})
}
func startTtsProviderBootstrap(lc fx.Lifecycle, log *slog.Logger, ttsService *ttspkg.Service) {
lc.Append(fx.Hook{
OnStart: func(ctx context.Context) error {
if err := ttsService.EnsureDefaults(ctx); err != nil {
log.Warn("failed to ensure default tts providers", slog.Any("error", err))
}
return nil
},
})
}
func startSearchProviderBootstrap(lc fx.Lifecycle, log *slog.Logger, spService *searchproviders.Service) {
lc.Append(fx.Hook{
OnStart: func(ctx context.Context) error {
if err := spService.EnsureDefaults(ctx); err != nil {
log.Warn("failed to ensure default search providers", slog.Any("error", err))
}
return nil
},
})
}
func provideRouteService(log *slog.Logger, queries *dbsqlc.Queries, chatService *conversation.Service) *route.DBService {
return route.NewService(log, queries, chatService)
}