1
0
mirror of https://github.com/securego/gosec.git synced 2025-11-23 22:15:04 +02:00
Files
gosec/autofix/ai.go
Matteo Calabrò 64ebfc0106 feat(autofix): update gemini sdk and add anthropic claude
* upgrade gemini sdk to google.golang.org/genai v1.25.0
* support newer gemini models
* add anthropic claude
2025-09-22 08:24:39 +00:00

76 lines
2.0 KiB
Go

package autofix
import (
"context"
"errors"
"fmt"
"strings"
"time"
"github.com/securego/gosec/v2/issue"
)
const (
AIProviderFlagHelp = `AI API provider to generate auto fixes to issues. Valid options are:
- gemini-2.5-pro, gemini-2.5-flash, gemini-2.5-flash-lite, gemini-2.0-flash, gemini-2.0-flash-lite (gemini, default);
- claude-sonnet-4-0 (claude, default), claude-opus-4-0, claude-opus-4-1, claude-sonnet-3-7`
AIPrompt = `Provide a brief explanation and a solution to fix this security issue
in Go programming language: %q.
Answer in markdown format and keep the response limited to 200 words.`
timeout = 30 * time.Second
)
type GenAIClient interface {
GenerateSolution(ctx context.Context, prompt string) (string, error)
}
// GenerateSolution generates a solution for the given issues using the specified AI provider
func GenerateSolution(model, aiAPIKey string, issues []*issue.Issue) (err error) {
var client GenAIClient
switch {
case strings.HasPrefix(model, "claude"):
client, err = NewClaudeClient(model, aiAPIKey)
case strings.HasPrefix(model, "gemini"):
client, err = NewGeminiClient(model, aiAPIKey)
}
switch {
case err != nil:
return fmt.Errorf("initializing AI client: %w", err)
case client == nil:
return fmt.Errorf("unsupported AI backend: %s", model)
}
return generateSolution(client, issues)
}
func generateSolution(client GenAIClient, issues []*issue.Issue) error {
ctx, cancel := context.WithTimeout(context.Background(), timeout)
defer cancel()
cachedAutofix := make(map[string]string)
for _, issue := range issues {
if val, ok := cachedAutofix[issue.What]; ok {
issue.Autofix = val
continue
}
prompt := fmt.Sprintf(AIPrompt, issue.What)
resp, err := client.GenerateSolution(ctx, prompt)
if err != nil {
return fmt.Errorf("generating autofix with gemini: %w", err)
}
if resp == "" {
return errors.New("no autofix returned by gemini")
}
issue.Autofix = resp
cachedAutofix[issue.What] = issue.Autofix
}
return nil
}