mirror of
https://github.com/router-for-me/CLIProxyAPI.git
synced 2026-02-02 20:40:52 +08:00
feat: add API endpoint to query models for auth credentials
This commit is contained in:
@@ -26,6 +26,7 @@ import (
|
|||||||
"github.com/router-for-me/CLIProxyAPI/v6/internal/auth/qwen"
|
"github.com/router-for-me/CLIProxyAPI/v6/internal/auth/qwen"
|
||||||
"github.com/router-for-me/CLIProxyAPI/v6/internal/interfaces"
|
"github.com/router-for-me/CLIProxyAPI/v6/internal/interfaces"
|
||||||
"github.com/router-for-me/CLIProxyAPI/v6/internal/misc"
|
"github.com/router-for-me/CLIProxyAPI/v6/internal/misc"
|
||||||
|
"github.com/router-for-me/CLIProxyAPI/v6/internal/registry"
|
||||||
"github.com/router-for-me/CLIProxyAPI/v6/internal/util"
|
"github.com/router-for-me/CLIProxyAPI/v6/internal/util"
|
||||||
sdkAuth "github.com/router-for-me/CLIProxyAPI/v6/sdk/auth"
|
sdkAuth "github.com/router-for-me/CLIProxyAPI/v6/sdk/auth"
|
||||||
coreauth "github.com/router-for-me/CLIProxyAPI/v6/sdk/cliproxy/auth"
|
coreauth "github.com/router-for-me/CLIProxyAPI/v6/sdk/cliproxy/auth"
|
||||||
@@ -266,6 +267,54 @@ func (h *Handler) ListAuthFiles(c *gin.Context) {
|
|||||||
c.JSON(200, gin.H{"files": files})
|
c.JSON(200, gin.H{"files": files})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetAuthFileModels returns the models supported by a specific auth file
|
||||||
|
func (h *Handler) GetAuthFileModels(c *gin.Context) {
|
||||||
|
name := c.Query("name")
|
||||||
|
if name == "" {
|
||||||
|
c.JSON(400, gin.H{"error": "name is required"})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Try to find auth ID via authManager
|
||||||
|
var authID string
|
||||||
|
if h.authManager != nil {
|
||||||
|
auths := h.authManager.List()
|
||||||
|
for _, auth := range auths {
|
||||||
|
if auth.FileName == name || auth.ID == name {
|
||||||
|
authID = auth.ID
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if authID == "" {
|
||||||
|
authID = name // fallback to filename as ID
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get models from registry
|
||||||
|
reg := registry.GetGlobalRegistry()
|
||||||
|
models := reg.GetModelsForClient(authID)
|
||||||
|
|
||||||
|
result := make([]gin.H, 0, len(models))
|
||||||
|
for _, m := range models {
|
||||||
|
entry := gin.H{
|
||||||
|
"id": m.ID,
|
||||||
|
}
|
||||||
|
if m.DisplayName != "" {
|
||||||
|
entry["display_name"] = m.DisplayName
|
||||||
|
}
|
||||||
|
if m.Type != "" {
|
||||||
|
entry["type"] = m.Type
|
||||||
|
}
|
||||||
|
if m.OwnedBy != "" {
|
||||||
|
entry["owned_by"] = m.OwnedBy
|
||||||
|
}
|
||||||
|
result = append(result, entry)
|
||||||
|
}
|
||||||
|
|
||||||
|
c.JSON(200, gin.H{"models": result})
|
||||||
|
}
|
||||||
|
|
||||||
// List auth files from disk when the auth manager is unavailable.
|
// List auth files from disk when the auth manager is unavailable.
|
||||||
func (h *Handler) listAuthFilesFromDisk(c *gin.Context) {
|
func (h *Handler) listAuthFilesFromDisk(c *gin.Context) {
|
||||||
entries, err := os.ReadDir(h.cfg.AuthDir)
|
entries, err := os.ReadDir(h.cfg.AuthDir)
|
||||||
|
|||||||
@@ -568,6 +568,7 @@ func (s *Server) registerManagementRoutes() {
|
|||||||
mgmt.DELETE("/oauth-excluded-models", s.mgmt.DeleteOAuthExcludedModels)
|
mgmt.DELETE("/oauth-excluded-models", s.mgmt.DeleteOAuthExcludedModels)
|
||||||
|
|
||||||
mgmt.GET("/auth-files", s.mgmt.ListAuthFiles)
|
mgmt.GET("/auth-files", s.mgmt.ListAuthFiles)
|
||||||
|
mgmt.GET("/auth-files/models", s.mgmt.GetAuthFileModels)
|
||||||
mgmt.GET("/auth-files/download", s.mgmt.DownloadAuthFile)
|
mgmt.GET("/auth-files/download", s.mgmt.DownloadAuthFile)
|
||||||
mgmt.POST("/auth-files", s.mgmt.UploadAuthFile)
|
mgmt.POST("/auth-files", s.mgmt.UploadAuthFile)
|
||||||
mgmt.DELETE("/auth-files", s.mgmt.DeleteAuthFile)
|
mgmt.DELETE("/auth-files", s.mgmt.DeleteAuthFile)
|
||||||
|
|||||||
@@ -871,3 +871,32 @@ func (r *ModelRegistry) GetFirstAvailableModel(handlerType string) (string, erro
|
|||||||
|
|
||||||
return "", fmt.Errorf("no available clients for any model in handler type: %s", handlerType)
|
return "", fmt.Errorf("no available clients for any model in handler type: %s", handlerType)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetModelsForClient returns the models registered for a specific client.
|
||||||
|
// Parameters:
|
||||||
|
// - clientID: The client identifier (typically auth file name or auth ID)
|
||||||
|
//
|
||||||
|
// Returns:
|
||||||
|
// - []*ModelInfo: List of models registered for this client, nil if client not found
|
||||||
|
func (r *ModelRegistry) GetModelsForClient(clientID string) []*ModelInfo {
|
||||||
|
r.mutex.RLock()
|
||||||
|
defer r.mutex.RUnlock()
|
||||||
|
|
||||||
|
modelIDs, exists := r.clientModels[clientID]
|
||||||
|
if !exists || len(modelIDs) == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
seen := make(map[string]struct{})
|
||||||
|
result := make([]*ModelInfo, 0, len(modelIDs))
|
||||||
|
for _, modelID := range modelIDs {
|
||||||
|
if _, dup := seen[modelID]; dup {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
seen[modelID] = struct{}{}
|
||||||
|
if reg, ok := r.models[modelID]; ok && reg.Info != nil {
|
||||||
|
result = append(result, reg.Info)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user