fix(llm): support Anthropic auth header (#77)

This commit is contained in:
zhouzhihao 2026-06-08 19:35:12 +08:00 committed by GitHub
parent fb819510ca
commit 48dc1b37d4
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
11 changed files with 428 additions and 32 deletions

View file

@ -6,6 +6,7 @@ import (
"os"
"path/filepath"
"strconv"
"strings"
)
// Default config file location: ~/.opencodereview/config.json
@ -79,6 +80,7 @@ type Config struct {
type LlmConfig struct {
URL string `json:"url,omitempty"`
AuthToken string `json:"auth_token,omitempty"`
AuthHeader string `json:"auth_header,omitempty"`
Model string `json:"model,omitempty"`
UseAnthropic *bool `json:"use_anthropic,omitempty"` // nil = default true; false = OpenAI protocol
ExtraBody map[string]any `json:"extra_body,omitempty"`
@ -129,6 +131,8 @@ func setConfigValue(cfg *Config, key, value string) error {
cfg.Llm.URL = value
case "llm.auth_token", "llm.AuthToken":
cfg.Llm.AuthToken = value
case "llm.auth_header", "llm.AuthHeader":
cfg.Llm.AuthHeader = normalizeConfigAuthHeader(value)
case "llm.model", "llm.Model":
cfg.Llm.Model = value
case "llm.use_anthropic", "llm.UseAnthropic":
@ -166,11 +170,23 @@ func setConfigValue(cfg *Config, key, value string) error {
}
cfg.Llm.ExtraBody = m
default:
return fmt.Errorf("unknown config key: %s\nSupported keys: llm.url, llm.auth_token, llm.model, llm.use_anthropic, llm.extra_body, language, telemetry.enabled, telemetry.exporter, telemetry.otlp_endpoint, telemetry.content_logging", key)
return fmt.Errorf("unknown config key: %s\nSupported keys: llm.url, llm.auth_token, llm.auth_header, llm.model, llm.use_anthropic, llm.extra_body, language, telemetry.enabled, telemetry.exporter, telemetry.otlp_endpoint, telemetry.content_logging", key)
}
return nil
}
func normalizeConfigAuthHeader(header string) string {
header = strings.TrimSpace(header)
switch strings.ToLower(header) {
case "x-api-key":
return "x-api-key"
case "authorization", "bearer":
return "authorization"
default:
return header
}
}
func (c *Config) ensureTelemetry() {
if c.Telemetry == nil {
c.Telemetry = &TelemetryConfig{}

View file

@ -0,0 +1,27 @@
package main
import "testing"
func TestSetConfigValueAuthHeaderNormalizesKnownValues(t *testing.T) {
cfg := &Config{}
if err := setConfigValue(cfg, "llm.auth_header", " bearer "); err != nil {
t.Fatalf("setConfigValue: %v", err)
}
if cfg.Llm.AuthHeader != "authorization" {
t.Errorf("AuthHeader = %q, want %q", cfg.Llm.AuthHeader, "authorization")
}
}
func TestSetConfigValueAuthHeaderTrimsCustomHeader(t *testing.T) {
cfg := &Config{}
if err := setConfigValue(cfg, "llm.auth_header", " X-Custom-Auth "); err != nil {
t.Fatalf("setConfigValue: %v", err)
}
if cfg.Llm.AuthHeader != "X-Custom-Auth" {
t.Errorf("AuthHeader = %q, want %q", cfg.Llm.AuthHeader, "X-Custom-Auth")
}
}

View file

@ -256,10 +256,11 @@ Usage:
Examples:
ocr config set llm.url https://xx/v1/openai/chat/completions
ocr config set llm.auth_token xxxxxxxxxx
ocr config set llm.auth_header x-api-key
ocr config set llm.model claude-opus-4-6
ocr config set llm.extra_body '{"thinking":{"type":"disabled"}}'
ocr config set language English
ocr config set telemetry.enabled true
Supported keys: llm.url, llm.auth_token, llm.model, llm.use_anthropic, llm.extra_body, language, telemetry.enabled, telemetry.exporter, telemetry.otlp_endpoint, telemetry.content_logging`)
Supported keys: llm.url, llm.auth_token, llm.auth_header, llm.model, llm.use_anthropic, llm.extra_body, language, telemetry.enabled, telemetry.exporter, telemetry.otlp_endpoint, telemetry.content_logging`)
}