diff options
Diffstat (limited to 'internal/lsp/server.go')
| -rw-r--r-- | internal/lsp/server.go | 85 |
1 files changed, 85 insertions, 0 deletions
diff --git a/internal/lsp/server.go b/internal/lsp/server.go index 7b8bc88..28f3218 100644 --- a/internal/lsp/server.go +++ b/internal/lsp/server.go @@ -6,6 +6,7 @@ import ( "encoding/json" "io" "log" + "os" "strings" "sync" "time" @@ -29,6 +30,8 @@ type Server struct { configStore *runtimeconfig.Store cfg appconfig.App llmClient llm.Client + llmProvider string + altClients map[string]llm.Client lastInput time.Time // LLM request stats llmReqTotal int64 @@ -186,6 +189,12 @@ func (s *Server) applyOptions(opts ServerOptions) { } } s.llmClient = opts.Client + if opts.Client != nil { + s.llmProvider = canonicalProvider(opts.Client.Name()) + } else { + s.llmProvider = canonicalProvider(s.cfg.Provider) + } + s.altClients = make(map[string]llm.Client) } // ApplyOptions updates the server's configuration at runtime. @@ -199,6 +208,82 @@ func (s *Server) currentLLMClient() llm.Client { return s.llmClient } +func newClientForProvider(cfg appconfig.App, provider string) (llm.Client, error) { + llmCfg := llm.Config{ + Provider: provider, + OpenAIBaseURL: cfg.OpenAIBaseURL, + OpenAIModel: cfg.OpenAIModel, + OpenAITemperature: cfg.OpenAITemperature, + OllamaBaseURL: cfg.OllamaBaseURL, + OllamaModel: cfg.OllamaModel, + OllamaTemperature: cfg.OllamaTemperature, + CopilotBaseURL: cfg.CopilotBaseURL, + CopilotModel: cfg.CopilotModel, + CopilotTemperature: cfg.CopilotTemperature, + } + oaKey := strings.TrimSpace(os.Getenv("HEXAI_OPENAI_API_KEY")) + if oaKey == "" { + oaKey = strings.TrimSpace(os.Getenv("OPENAI_API_KEY")) + } + cpKey := strings.TrimSpace(os.Getenv("HEXAI_COPILOT_API_KEY")) + if cpKey == "" { + cpKey = strings.TrimSpace(os.Getenv("COPILOT_API_KEY")) + } + return llm.NewFromConfig(llmCfg, oaKey, cpKey) +} + +func (s *Server) clientFor(spec requestSpec) llm.Client { + provider := canonicalProvider(spec.provider) + s.mu.RLock() + baseProvider := s.llmProvider + baseClient := s.llmClient + if baseClient != nil && strings.TrimSpace(baseProvider) == "" { + baseProvider = canonicalProvider(baseClient.Name()) + } + if provider == "" { + provider = baseProvider + } + if provider == baseProvider && baseClient != nil { + s.mu.RUnlock() + return baseClient + } + if c, ok := s.altClients[provider]; ok { + s.mu.RUnlock() + return c + } + cfg := s.cfg + store := s.configStore + s.mu.RUnlock() + if store != nil { + cfg = store.Snapshot() + } + client, err := newClientForProvider(cfg, provider) + if err != nil { + logging.Logf("lsp ", "failed to build client for provider=%s: %v", provider, err) + if baseClient != nil { + return baseClient + } + return nil + } + s.mu.Lock() + defer s.mu.Unlock() + if provider == s.llmProvider { + if s.llmClient == nil { + s.llmClient = client + s.llmProvider = provider + } + return s.llmClient + } + if existing, ok := s.altClients[provider]; ok { + return existing + } + if s.altClients == nil { + s.altClients = make(map[string]llm.Client) + } + s.altClients[provider] = client + return client +} + func (s *Server) currentConfig() appconfig.App { if s.configStore != nil { return s.configStore.Snapshot() |
