Compare commits
4 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 0983119ae2 | |||
| 0371062e86 | |||
| 74bae32c83 | |||
| 4e67cd4baf |
@@ -60,9 +60,33 @@ func (h *OpenAIAPIHandler) Models() []map[string]any {
|
|||||||
// It returns a list of available AI models with their capabilities
|
// It returns a list of available AI models with their capabilities
|
||||||
// and specifications in OpenAI-compatible format.
|
// and specifications in OpenAI-compatible format.
|
||||||
func (h *OpenAIAPIHandler) OpenAIModels(c *gin.Context) {
|
func (h *OpenAIAPIHandler) OpenAIModels(c *gin.Context) {
|
||||||
|
// Get all available models
|
||||||
|
allModels := h.Models()
|
||||||
|
|
||||||
|
// Filter to only include the 4 required fields: id, object, created, owned_by
|
||||||
|
filteredModels := make([]map[string]any, len(allModels))
|
||||||
|
for i, model := range allModels {
|
||||||
|
filteredModel := map[string]any{
|
||||||
|
"id": model["id"],
|
||||||
|
"object": model["object"],
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add created field if it exists
|
||||||
|
if created, exists := model["created"]; exists {
|
||||||
|
filteredModel["created"] = created
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add owned_by field if it exists
|
||||||
|
if ownedBy, exists := model["owned_by"]; exists {
|
||||||
|
filteredModel["owned_by"] = ownedBy
|
||||||
|
}
|
||||||
|
|
||||||
|
filteredModels[i] = filteredModel
|
||||||
|
}
|
||||||
|
|
||||||
c.JSON(http.StatusOK, gin.H{
|
c.JSON(http.StatusOK, gin.H{
|
||||||
"object": "list",
|
"object": "list",
|
||||||
"data": h.Models(),
|
"data": filteredModels,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ type GeminiClient struct {
|
|||||||
// - *GeminiClient: A new Gemini client instance.
|
// - *GeminiClient: A new Gemini client instance.
|
||||||
func NewGeminiClient(httpClient *http.Client, cfg *config.Config, glAPIKey string) *GeminiClient {
|
func NewGeminiClient(httpClient *http.Client, cfg *config.Config, glAPIKey string) *GeminiClient {
|
||||||
// Generate unique client ID
|
// Generate unique client ID
|
||||||
clientID := fmt.Sprintf("gemini-apikey-%s-%d", glAPIKey[:8], time.Now().UnixNano()) // Use first 8 chars of API key
|
clientID := fmt.Sprintf("gemini-apikey-%s-%d", glAPIKey, time.Now().UnixNano())
|
||||||
|
|
||||||
client := &GeminiClient{
|
client := &GeminiClient{
|
||||||
ClientBase: ClientBase{
|
ClientBase: ClientBase{
|
||||||
|
|||||||
@@ -103,6 +103,17 @@ type FileRequestLogger struct {
|
|||||||
// Returns:
|
// Returns:
|
||||||
// - *FileRequestLogger: A new file-based request logger instance
|
// - *FileRequestLogger: A new file-based request logger instance
|
||||||
func NewFileRequestLogger(enabled bool, logsDir string) *FileRequestLogger {
|
func NewFileRequestLogger(enabled bool, logsDir string) *FileRequestLogger {
|
||||||
|
// Resolve logsDir relative to the executable directory when it's not absolute.
|
||||||
|
if !filepath.IsAbs(logsDir) {
|
||||||
|
if exePath, err := os.Executable(); err == nil {
|
||||||
|
// Resolve symlinks to get the real executable path
|
||||||
|
if realExe, errEvalSymlinks := filepath.EvalSymlinks(exePath); errEvalSymlinks == nil {
|
||||||
|
exePath = realExe
|
||||||
|
}
|
||||||
|
execDir := filepath.Dir(exePath)
|
||||||
|
logsDir = filepath.Join(execDir, logsDir)
|
||||||
|
}
|
||||||
|
}
|
||||||
return &FileRequestLogger{
|
return &FileRequestLogger{
|
||||||
enabled: enabled,
|
enabled: enabled,
|
||||||
logsDir: logsDir,
|
logsDir: logsDir,
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/luispater/CLIProxyAPI/internal/misc"
|
"github.com/luispater/CLIProxyAPI/internal/misc"
|
||||||
|
"github.com/luispater/CLIProxyAPI/internal/util"
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
"github.com/tidwall/gjson"
|
"github.com/tidwall/gjson"
|
||||||
"github.com/tidwall/sjson"
|
"github.com/tidwall/sjson"
|
||||||
@@ -230,6 +231,16 @@ func ConvertOpenAIRequestToGeminiCLI(modelName string, inputRawJSON []byte, _ bo
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var pathsToType []string
|
||||||
|
root := gjson.ParseBytes(out)
|
||||||
|
util.Walk(root, "", "type", &pathsToType)
|
||||||
|
for _, p := range pathsToType {
|
||||||
|
typeResult := gjson.GetBytes(out, p)
|
||||||
|
if strings.ToLower(typeResult.String()) == "select" {
|
||||||
|
out, _ = sjson.SetBytes(out, p, "STRING")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return out
|
return out
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/luispater/CLIProxyAPI/internal/misc"
|
"github.com/luispater/CLIProxyAPI/internal/misc"
|
||||||
|
"github.com/luispater/CLIProxyAPI/internal/util"
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
"github.com/tidwall/gjson"
|
"github.com/tidwall/gjson"
|
||||||
"github.com/tidwall/sjson"
|
"github.com/tidwall/sjson"
|
||||||
@@ -230,6 +231,16 @@ func ConvertOpenAIRequestToGemini(modelName string, inputRawJSON []byte, _ bool)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var pathsToType []string
|
||||||
|
root := gjson.ParseBytes(out)
|
||||||
|
util.Walk(root, "", "type", &pathsToType)
|
||||||
|
for _, p := range pathsToType {
|
||||||
|
typeResult := gjson.GetBytes(out, p)
|
||||||
|
if strings.ToLower(typeResult.String()) == "select" {
|
||||||
|
out, _ = sjson.SetBytes(out, p, "STRING")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return out
|
return out
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user