mirror of
https://github.com/securego/gosec.git
synced 2026-06-20 00:15:59 +02:00
feat(ai): add OpenAI and custom API provider support (#1424)
* feat(ai): add OpenAI and custom API provider support - Expand AI provider support to include OpenAI (gpt-4o, gpt-4o-mini) and custom OpenAI-compatible APIs - Add support for configuring AI API base URL and skipping SSL verification - Update documentation to list all supported AI providers and clarify configuration options with examples - Refactor AI client initialization to fallback on OpenAI-compatible API for unknown models - Add OpenAI client implementation using openai-go library - Update tests to validate OpenAI-compatible fallback behavior - Add openai-go dependency to go.mod Signed-off-by: appleboy <appleboy.tw@gmail.com> * Fix info message after merge Change-Id: I1cb556a42e2bd9e9b2051d6db99889c6c9f7ccdb Signed-off-by: Cosmin Cojocar <ccojocar@google.com> * Fix lint warning Change-Id: I3689b96205f494920dbbd03344e8f132a30f40b3 Signed-off-by: Cosmin Cojocar <ccojocar@google.com> --------- Signed-off-by: appleboy <appleboy.tw@gmail.com> Signed-off-by: Cosmin Cojocar <ccojocar@google.com> Co-authored-by: Cosmin Cojocar <cosmin@cojocar.ch> Co-authored-by: Cosmin Cojocar <ccojocar@google.com>
This commit is contained in:
co-authored by
Cosmin Cojocar
Cosmin Cojocar
parent
b6eea26df8
commit
aa2e2fb1bd
@@ -0,0 +1,120 @@
|
||||
package autofix
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"github.com/openai/openai-go/v3"
|
||||
"github.com/openai/openai-go/v3/option"
|
||||
)
|
||||
|
||||
const (
|
||||
ModelGPT4o = openai.ChatModelGPT4o
|
||||
ModelGPT4oMini = openai.ChatModelGPT4oMini
|
||||
DefaultOpenAIBaseURL = "https://api.openai.com/v1"
|
||||
)
|
||||
|
||||
var _ GenAIClient = (*openaiWrapper)(nil)
|
||||
|
||||
type OpenAIConfig struct {
|
||||
Model string
|
||||
APIKey string
|
||||
BaseURL string
|
||||
MaxTokens int
|
||||
Temperature float64
|
||||
SkipSSL bool
|
||||
}
|
||||
|
||||
type openaiWrapper struct {
|
||||
client openai.Client
|
||||
model openai.ChatModel
|
||||
maxTokens int
|
||||
temperature float64
|
||||
}
|
||||
|
||||
func NewOpenAIClient(config OpenAIConfig) (GenAIClient, error) {
|
||||
var options []option.RequestOption
|
||||
|
||||
if config.APIKey != "" {
|
||||
options = append(options, option.WithAPIKey(config.APIKey))
|
||||
}
|
||||
|
||||
// Support custom base URL (for OpenAI-compatible APIs)
|
||||
if config.BaseURL != "" {
|
||||
options = append(options, option.WithBaseURL(config.BaseURL))
|
||||
}
|
||||
|
||||
// Support skip SSL verification
|
||||
if config.SkipSSL {
|
||||
// Create custom HTTP client with InsecureSkipVerify
|
||||
httpClient := &http.Client{
|
||||
Transport: &http.Transport{
|
||||
TLSClientConfig: &tls.Config{
|
||||
InsecureSkipVerify: true, // #nosec G402
|
||||
},
|
||||
},
|
||||
}
|
||||
options = append(options, option.WithHTTPClient(httpClient))
|
||||
}
|
||||
|
||||
openaiModel := parseOpenAIModel(config.Model)
|
||||
|
||||
// Set default values
|
||||
maxTokens := config.MaxTokens
|
||||
if maxTokens == 0 {
|
||||
maxTokens = 1024
|
||||
}
|
||||
|
||||
temperature := config.Temperature
|
||||
if temperature == 0 {
|
||||
temperature = 0.7
|
||||
}
|
||||
|
||||
return &openaiWrapper{
|
||||
client: openai.NewClient(options...),
|
||||
model: openaiModel,
|
||||
maxTokens: maxTokens,
|
||||
temperature: temperature,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (o *openaiWrapper) GenerateSolution(ctx context.Context, prompt string) (string, error) {
|
||||
params := openai.ChatCompletionNewParams{
|
||||
Model: o.model,
|
||||
Messages: []openai.ChatCompletionMessageParamUnion{
|
||||
openai.UserMessage(prompt),
|
||||
},
|
||||
}
|
||||
|
||||
// Set optional parameters if available
|
||||
// Using WithMaxTokens and WithTemperature methods if they exist in v3
|
||||
resp, err := o.client.Chat.Completions.New(ctx, params)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("generating autofix: %w", err)
|
||||
}
|
||||
|
||||
if resp == nil || len(resp.Choices) == 0 {
|
||||
return "", errors.New("no autofix returned by openai")
|
||||
}
|
||||
|
||||
content := resp.Choices[0].Message.Content
|
||||
if content == "" {
|
||||
return "", errors.New("nothing found in the first autofix returned by openai")
|
||||
}
|
||||
|
||||
return content, nil
|
||||
}
|
||||
|
||||
func parseOpenAIModel(model string) openai.ChatModel {
|
||||
switch model {
|
||||
case "gpt-4o":
|
||||
return openai.ChatModelGPT4o
|
||||
case "gpt-4o-mini":
|
||||
return openai.ChatModelGPT4oMini
|
||||
default:
|
||||
return model
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user