MCPcopy Create free account
hub / github.com/diillson/chatcli / getClient

Method getClient

server/handler.go:157–208  ·  view source on GitHub ↗

getClient resolves the LLM client to use, optionally overriding provider/model. If clientAPIKey is non-empty or providerConfig has entries, creates a new client using the caller's credentials instead of the server's default ones. When metrics are enabled, the returned client is wrapped with instrume

(provider, model, clientAPIKey string, providerConfig map[string]string)

Source from the content-addressed store, hash-verified

155// using the caller's credentials instead of the server's default ones.
156// When metrics are enabled, the returned client is wrapped with instrumentation.
157func (h *Handler) getClient(provider, model, clientAPIKey string, providerConfig map[string]string) (client.LLMClient, error) {
158 if provider == "" {
159 provider = h.defaultProvider
160 }
161 if model == "" {
162 model = h.defaultModel
163 }
164
165 var (
166 c client.LLMClient
167 err error
168 )
169
170 // Security: SSRF prevention — validate provider_config URLs before use (H1)
171 if len(providerConfig) > 0 && h.ssrfValidator != nil {
172 if err := h.ssrfValidator.ValidateProviderConfig(providerConfig); err != nil {
173 h.logger.Warn("SSRF: blocked provider config",
174 zap.String("provider", provider),
175 zap.Error(err),
176 )
177 return nil, fmt.Errorf("invalid provider configuration: %w", err)
178 }
179 }
180
181 // Client-forwarded credentials with provider-specific config (StackSpot, Ollama, etc.)
182 if len(providerConfig) > 0 {
183 h.logger.Info(i18n.T("server.handler.client_config"),
184 zap.String("provider", provider),
185 zap.Int("config_keys", len(providerConfig)),
186 )
187 c, err = h.llmManager.CreateClientWithConfig(provider, model, clientAPIKey, providerConfig)
188 } else if clientAPIKey != "" {
189 // Client-forwarded API key only (OpenAI, Claude, Google, xAI)
190 h.logger.Info(i18n.T("server.handler.client_api_key"),
191 zap.String("provider", provider),
192 )
193 c, err = h.llmManager.CreateClientWithKey(provider, model, clientAPIKey)
194 } else {
195 c, err = h.llmManager.GetClient(provider, model)
196 }
197
198 if err != nil {
199 return nil, err
200 }
201
202 // Wrap with metrics instrumentation if enabled
203 if h.llmMetrics != nil {
204 return client.NewInstrumentedClient(c, &llmMetricsAdapter{m: h.llmMetrics}, provider), nil
205 }
206
207 return c, nil
208}
209
210// llmMetricsAdapter bridges metrics.LLMMetrics to client.MetricsRecorder interface.
211type llmMetricsAdapter struct {

Callers 5

SendPromptMethod · 0.95
StreamPromptMethod · 0.95
InteractiveSessionMethod · 0.95
AnalyzeIssueMethod · 0.95
AgenticStepMethod · 0.95

Calls 11

TFunction · 0.92
NewInstrumentedClientFunction · 0.92
WarnMethod · 0.80
ErrorfMethod · 0.80
ErrorMethod · 0.65
InfoMethod · 0.65
CreateClientWithKeyMethod · 0.65
GetClientMethod · 0.65
StringMethod · 0.45

Tested by

no test coverage detected