| 496 | } |
| 497 | |
| 498 | func (a *Application) start() error { |
| 499 | galleryService := galleryop.NewGalleryService(a.ApplicationConfig(), a.ModelLoader()) |
| 500 | err := galleryService.Start(a.ApplicationConfig().Context, a.ModelConfigLoader(), a.ApplicationConfig().SystemState) |
| 501 | if err != nil { |
| 502 | return err |
| 503 | } |
| 504 | |
| 505 | a.galleryService = galleryService |
| 506 | |
| 507 | // LocalAI Assistant: in-process MCP server exposing admin tools. Initialised |
| 508 | // once at startup and reused across chat sessions that opt in via metadata. |
| 509 | if !a.applicationConfig.DisableLocalAIAssistant { |
| 510 | holder := mcpTools.NewLocalAIAssistantHolder() |
| 511 | assistantClient := localaiInproc.New( |
| 512 | a.applicationConfig, |
| 513 | a.applicationConfig.SystemState, |
| 514 | a.backendLoader, |
| 515 | a.modelLoader, |
| 516 | a.galleryService, |
| 517 | ) |
| 518 | // Wire usage tracking so the assistant's get_usage_stats tool |
| 519 | // returns real data; nil values keep the tool returning a clear |
| 520 | // "unavailable" error if startup ran with --disable-stats. |
| 521 | assistantClient.StatsRecorder = a.statsRecorder |
| 522 | assistantClient.FallbackUser = a.fallbackUser |
| 523 | // PII filter — same nil-or-real wiring. |
| 524 | assistantClient.PIIRedactor = a.piiRedactor |
| 525 | assistantClient.PIIEvents = a.piiEvents |
| 526 | assistantClient.RouterDecisions = a.routerDecisions |
| 527 | if err := holder.Initialize(a.applicationConfig.Context, assistantClient, localaitools.Options{}); err != nil { |
| 528 | // Why log+continue instead of fail: the assistant is an optional |
| 529 | // feature; a failure here must not take down the whole server. |
| 530 | xlog.Warn("LocalAI Assistant initialisation failed; feature unavailable", "error", err) |
| 531 | } else { |
| 532 | a.localAIAssistant = holder |
| 533 | // Tear the in-memory transport pair down on SIGINT/SIGTERM so the |
| 534 | // goroutine ends cleanly. Mirrors how core/http/endpoints/mcp/tools.go |
| 535 | // closes its per-model MCP sessions on graceful termination. |
| 536 | signals.RegisterGracefulTerminationHandler(func() { |
| 537 | _ = holder.Close() |
| 538 | }) |
| 539 | } |
| 540 | } |
| 541 | |
| 542 | // Initialize agent job service (Start() is deferred to after distributed wiring) |
| 543 | agentJobService := agentpool.NewAgentJobService( |
| 544 | a.ApplicationConfig(), |
| 545 | a.ModelLoader(), |
| 546 | a.ModelConfigLoader(), |
| 547 | a.TemplatesEvaluator(), |
| 548 | ) |
| 549 | |
| 550 | a.agentJobService = agentJobService |
| 551 | |
| 552 | return nil |
| 553 | } |
| 554 | |
| 555 | // StartAgentPool initializes and starts the agent pool service (LocalAGI integration). |