From 14a5315aad88f9392a306b2fab65981c3d8b852d Mon Sep 17 00:00:00 2001 From: Omprakash Sahani Date: Wed, 6 May 2026 09:40:08 +0000 Subject: [PATCH 1/2] feat: add provider field to model config --- config/config.yaml | 2 ++ types/types.go | 1 + 2 files changed, 3 insertions(+) diff --git a/config/config.yaml b/config/config.yaml index 0494480..45f0dc3 100644 --- a/config/config.yaml +++ b/config/config.yaml @@ -3,6 +3,7 @@ preferences: models: - name: gpt-4.1 + provider: openai endpoint: https://api.openai.com/v1/chat/completions auth_env_var: OPENAI_API_KEY org_env_var: OPENAI_ORG_ID @@ -15,6 +16,7 @@ models: content: "```bash\necho \"hi\"\n```" - name: gpt-4.1-mini + provider: openai endpoint: https://api.openai.com/v1/chat/completions auth_env_var: OPENAI_API_KEY org_env_var: OPENAI_ORG_ID diff --git a/types/types.go b/types/types.go index 525fb94..f58d056 100644 --- a/types/types.go +++ b/types/types.go @@ -2,6 +2,7 @@ package types type ModelConfig struct { ModelName string `yaml:"name"` + Provider string `yaml:"provider,omitempty"` Endpoint string `yaml:"endpoint"` Auth string `yaml:"auth_env_var"` OrgID string `yaml:"org_env_var,omitempty"` From 6e8b08b44ab424385c8cbf3a7e25c0f9b69ad455 Mon Sep 17 00:00:00 2001 From: Omprakash Sahani Date: Wed, 6 May 2026 09:48:50 +0000 Subject: [PATCH 2/2] feat: add provider-aware request headers --- llm/llm.go | 38 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 36 insertions(+), 2 deletions(-) diff --git a/llm/llm.go b/llm/llm.go index 35e43e5..e2f8b49 100644 --- a/llm/llm.go +++ b/llm/llm.go @@ -31,24 +31,43 @@ func NewLLMClient(config ModelConfig) *LLMClient { } } +func (c *LLMClient) provider() string { + if c.config.Provider == "" { + return "openai" + } + return strings.ToLower(c.config.Provider) +} + +func (c *LLMClient) isAnthropic() bool { + return c.provider() == "anthropic" +} + func (c *LLMClient) createRequest(payload Payload) (*http.Request, error) { payloadBytes, err := json.Marshal(payload) if err != nil { return nil, fmt.Errorf("failed to marshal payload: %w", err) } + req, err := http.NewRequest("POST", c.config.Endpoint, bytes.NewBuffer(payloadBytes)) if err != nil { return nil, fmt.Errorf("failed to create request: %w", err) } - if strings.Contains(c.config.Endpoint, "openai.azure.com") { + + if c.isAnthropic() { + req.Header.Set("x-api-key", c.config.Auth) + req.Header.Set("anthropic-version", "2023-06-01") + } else if strings.Contains(c.config.Endpoint, "openai.azure.com") { req.Header.Set("Api-Key", c.config.Auth) } else { req.Header.Set("Authorization", "Bearer "+c.config.Auth) } - if c.config.OrgID != "" { + + if c.provider() == "openai" && c.config.OrgID != "" { req.Header.Set("OpenAI-Organization", c.config.OrgID) } + req.Header.Set("Content-Type", "application/json") + return req, nil } @@ -67,7 +86,9 @@ func (c *LLMClient) Query(query string) (string, error) { if err != nil { return "", err } + c.messages = append(c.messages, message) + return message.Content, nil } @@ -75,15 +96,19 @@ func (c *LLMClient) processStream(resp *http.Response) (string, error) { counter := 0 streamReader := bufio.NewReader(resp.Body) totalData := "" + for { line, err := streamReader.ReadString('\n') if err != nil { break } + line = strings.TrimSpace(line) + if line == "data: [DONE]" { break } + if strings.HasPrefix(line, "data:") { payload := strings.TrimPrefix(line, "data:") @@ -93,18 +118,23 @@ func (c *LLMClient) processStream(resp *http.Response) (string, error) { fmt.Println("Error parsing data:", err) continue } + if len(responseData.Choices) == 0 { continue } + content := responseData.Choices[0].Delta.Content + if counter < 2 && strings.Count(content, "\n") > 0 { continue } + totalData += content c.StreamCallback(totalData, nil) counter++ } } + return totalData, nil } @@ -113,15 +143,19 @@ func (c *LLMClient) callStream(payload Payload) (Message, error) { if err != nil { return Message{}, fmt.Errorf("failed to create the request: %w", err) } + resp, err := c.httpClient.Do(req) if err != nil { return Message{}, fmt.Errorf("failed to make the API request: %w", err) } + defer resp.Body.Close() if resp.StatusCode != 200 { return Message{}, fmt.Errorf("API request failed: %s", resp.Status) } + content, err := c.processStream(resp) + return Message{Role: "assistant", Content: content}, err }