fix(backend): 修复 golangci-lint 报告的问题
- gofmt: 修复代码格式问题 - errcheck: 处理 WriteString 和 Close 返回值 - staticcheck: 错误信息改为小写开头 - staticcheck: 移除无效的 nil 检查 - staticcheck: 使用 append 替换循环 - staticcheck: 使用无条件的 TrimPrefix - ineffassign: 移除无效赋值 - unused: 移除未使用的 geminiOAuthService 字段 - 重新生成 wire_gen.go
This commit is contained in:
@@ -221,10 +221,10 @@ func setDefaults() {
|
||||
|
||||
// TokenRefresh
|
||||
viper.SetDefault("token_refresh.enabled", true)
|
||||
viper.SetDefault("token_refresh.check_interval_minutes", 5) // 每5分钟检查一次
|
||||
viper.SetDefault("token_refresh.check_interval_minutes", 5) // 每5分钟检查一次
|
||||
viper.SetDefault("token_refresh.refresh_before_expiry_hours", 0.5) // 提前30分钟刷新(适配Google 1小时token)
|
||||
viper.SetDefault("token_refresh.max_retries", 3) // 最多重试3次
|
||||
viper.SetDefault("token_refresh.retry_backoff_seconds", 2) // 重试退避基础2秒
|
||||
viper.SetDefault("token_refresh.max_retries", 3) // 最多重试3次
|
||||
viper.SetDefault("token_refresh.retry_backoff_seconds", 2) // 重试退避基础2秒
|
||||
|
||||
// Gemini OAuth - configure via environment variables or config file
|
||||
// GEMINI_OAUTH_CLIENT_ID and GEMINI_OAUTH_CLIENT_SECRET
|
||||
|
||||
@@ -19,4 +19,3 @@ var DefaultModels = []Model{
|
||||
|
||||
// DefaultTestModel is the default model to preselect in test flows.
|
||||
const DefaultTestModel = "gemini-2.5-pro"
|
||||
|
||||
|
||||
@@ -152,7 +152,7 @@ func EffectiveOAuthConfig(cfg OAuthConfig, oauthType string) (OAuthConfig, error
|
||||
|
||||
// Require OAuth credentials to be configured
|
||||
if effective.ClientID == "" || effective.ClientSecret == "" {
|
||||
return OAuthConfig{}, fmt.Errorf("Gemini OAuth credentials not configured. Set GEMINI_OAUTH_CLIENT_ID and GEMINI_OAUTH_CLIENT_SECRET environment variables")
|
||||
return OAuthConfig{}, fmt.Errorf("gemini OAuth credentials not configured, set GEMINI_OAUTH_CLIENT_ID and GEMINI_OAUTH_CLIENT_SECRET environment variables")
|
||||
}
|
||||
|
||||
if effective.Scopes == "" {
|
||||
|
||||
@@ -22,4 +22,3 @@ func HTTPStatusToGoogleStatus(status int) string {
|
||||
return "UNKNOWN"
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -43,7 +43,6 @@ type AccountTestService struct {
|
||||
accountRepo AccountRepository
|
||||
oauthService *OAuthService
|
||||
openaiOAuthService *OpenAIOAuthService
|
||||
geminiOAuthService *GeminiOAuthService
|
||||
geminiTokenProvider *GeminiTokenProvider
|
||||
httpUpstream HTTPUpstream
|
||||
}
|
||||
@@ -53,7 +52,6 @@ func NewAccountTestService(
|
||||
accountRepo AccountRepository,
|
||||
oauthService *OAuthService,
|
||||
openaiOAuthService *OpenAIOAuthService,
|
||||
geminiOAuthService *GeminiOAuthService,
|
||||
geminiTokenProvider *GeminiTokenProvider,
|
||||
httpUpstream HTTPUpstream,
|
||||
) *AccountTestService {
|
||||
@@ -61,7 +59,6 @@ func NewAccountTestService(
|
||||
accountRepo: accountRepo,
|
||||
oauthService: oauthService,
|
||||
openaiOAuthService: openaiOAuthService,
|
||||
geminiOAuthService: geminiOAuthService,
|
||||
geminiTokenProvider: geminiTokenProvider,
|
||||
httpUpstream: httpUpstream,
|
||||
}
|
||||
@@ -460,7 +457,7 @@ func (s *AccountTestService) testGeminiAccountConnection(c *gin.Context, account
|
||||
func (s *AccountTestService) buildGeminiAPIKeyRequest(ctx context.Context, account *model.Account, modelID string, payload []byte) (*http.Request, error) {
|
||||
apiKey := account.GetCredential("api_key")
|
||||
if strings.TrimSpace(apiKey) == "" {
|
||||
return nil, fmt.Errorf("No API key available")
|
||||
return nil, fmt.Errorf("no API key available")
|
||||
}
|
||||
|
||||
baseURL := account.GetCredential("base_url")
|
||||
@@ -486,13 +483,13 @@ func (s *AccountTestService) buildGeminiAPIKeyRequest(ctx context.Context, accou
|
||||
// buildGeminiOAuthRequest builds request for Gemini OAuth accounts
|
||||
func (s *AccountTestService) buildGeminiOAuthRequest(ctx context.Context, account *model.Account, modelID string, payload []byte) (*http.Request, error) {
|
||||
if s.geminiTokenProvider == nil {
|
||||
return nil, fmt.Errorf("Gemini token provider not configured")
|
||||
return nil, fmt.Errorf("gemini token provider not configured")
|
||||
}
|
||||
|
||||
// Get access token (auto-refreshes if needed)
|
||||
accessToken, err := s.geminiTokenProvider.GetAccessToken(ctx, account)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Failed to get access token: %w", err)
|
||||
return nil, fmt.Errorf("failed to get access token: %w", err)
|
||||
}
|
||||
|
||||
projectID := strings.TrimSpace(account.GetCredential("project_id"))
|
||||
|
||||
@@ -365,10 +365,6 @@ func (s *GeminiMessagesCompatService) Forward(ctx context.Context, c *gin.Contex
|
||||
return nil, fmt.Errorf("unsupported account type: %s", account.Type)
|
||||
}
|
||||
|
||||
if buildReq == nil {
|
||||
return nil, s.writeClaudeError(c, http.StatusBadGateway, "upstream_error", "Gemini upstream not configured")
|
||||
}
|
||||
|
||||
var resp *http.Response
|
||||
for attempt := 1; attempt <= geminiMaxRetries; attempt++ {
|
||||
upstreamReq, idHeader, err := buildReq(ctx)
|
||||
@@ -1128,7 +1124,6 @@ func (s *GeminiMessagesCompatService) handleStreamingResponse(c *gin.Context, re
|
||||
"index": openToolIndex,
|
||||
})
|
||||
openToolIndex = -1
|
||||
openToolID = ""
|
||||
openToolName = ""
|
||||
seenToolJSON = ""
|
||||
}
|
||||
@@ -2069,7 +2064,7 @@ func extractClaudeContentText(v any) string {
|
||||
}
|
||||
if pm["type"] == "text" {
|
||||
if text, ok := pm["text"].(string); ok {
|
||||
sb.WriteString(text)
|
||||
_, _ = sb.WriteString(text)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -436,7 +436,7 @@ func fetchProjectIDFromResourceManager(ctx context.Context, accessToken, proxyUR
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("resource manager request failed: %w", err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
defer func() { _ = resp.Body.Close() }()
|
||||
|
||||
bodyBytes, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
|
||||
@@ -445,13 +445,11 @@ func (s *PricingService) buildModelLookupCandidates(modelLower string) []string
|
||||
normalizeModelNameForPricing(modelLower),
|
||||
modelLower,
|
||||
}
|
||||
for _, cand := range []string{
|
||||
candidates = append(candidates,
|
||||
strings.TrimPrefix(modelLower, "models/"),
|
||||
lastSegment(modelLower),
|
||||
lastSegment(strings.TrimPrefix(modelLower, "models/")),
|
||||
} {
|
||||
candidates = append(candidates, cand)
|
||||
}
|
||||
)
|
||||
|
||||
seen := make(map[string]struct{}, len(candidates))
|
||||
out := make([]string, 0, len(candidates))
|
||||
@@ -479,13 +477,8 @@ func normalizeModelNameForPricing(model string) string {
|
||||
// - projects/.../locations/.../publishers/google/models/gemini-1.5-pro
|
||||
model = strings.TrimSpace(model)
|
||||
model = strings.TrimLeft(model, "/")
|
||||
|
||||
if strings.HasPrefix(model, "models/") {
|
||||
model = strings.TrimPrefix(model, "models/")
|
||||
}
|
||||
if strings.HasPrefix(model, "publishers/google/models/") {
|
||||
model = strings.TrimPrefix(model, "publishers/google/models/")
|
||||
}
|
||||
model = strings.TrimPrefix(model, "models/")
|
||||
model = strings.TrimPrefix(model, "publishers/google/models/")
|
||||
|
||||
if idx := strings.LastIndex(model, "/publishers/google/models/"); idx != -1 {
|
||||
model = model[idx+len("/publishers/google/models/"):]
|
||||
|
||||
Reference in New Issue
Block a user