mirror of
https://github.com/infiniflow/ragflow.git
synced 2026-06-29 23:41:12 +08:00
Go: add balance command (#14262)
### What problem does this PR solve? ``` RAGFlow(user)> list supported models from 'moonshot' 'test'; +---------------------------------+ | model_name | +---------------------------------+ | moonshot-v1-32k-vision-preview | | kimi-k2.6 | | moonshot-v1-8k | | moonshot-v1-auto | | moonshot-v1-128k | | moonshot-v1-32k | | kimi-k2.5 | | moonshot-v1-8k-vision-preview | | moonshot-v1-128k-vision-preview | +---------------------------------+ RAGFlow(user)> show balance from 'moonshot' 'test'; +---------+----------+ | balance | currency | +---------+----------+ | 0 | CNY | +---------+----------+ ``` ### Type of change - [x] New Feature (non-breaking change which adds functionality) --------- Signed-off-by: Jin Hai <haijin.chn@gmail.com>
This commit is contained in:
@@ -236,6 +236,8 @@ func (c *RAGFlowClient) ExecuteUserCommand(cmd *Command) (ResponseIf, error) {
|
||||
return c.ListProviderInstances(cmd)
|
||||
case "show_provider_instance":
|
||||
return c.ShowProviderInstance(cmd)
|
||||
case "show_instance_balance":
|
||||
return c.ShowInstanceBalance(cmd)
|
||||
case "alter_provider_instance":
|
||||
return c.AlterProviderInstance(cmd)
|
||||
case "drop_provider_instance":
|
||||
|
||||
@@ -369,6 +369,8 @@ func (l *Lexer) lookupIdent(ident string) Token {
|
||||
return Token{Type: TokenSupported, Value: ident}
|
||||
case "NAME":
|
||||
return Token{Type: TokenName, Value: ident}
|
||||
case "BALANCE":
|
||||
return Token{Type: TokenBalance, Value: ident}
|
||||
case "INSTANCE":
|
||||
return Token{Type: TokenInstance, Value: ident}
|
||||
case "INSTANCES":
|
||||
|
||||
@@ -109,6 +109,7 @@ const (
|
||||
TokenVector
|
||||
TokenSize
|
||||
TokenName // For ALTER PROVIDER <name> NAME <new_name>
|
||||
TokenBalance
|
||||
TokenInstance
|
||||
TokenInstances
|
||||
TokenDisable
|
||||
|
||||
@@ -1234,6 +1234,47 @@ func (c *RAGFlowClient) ShowProviderInstance(cmd *Command) (ResponseIf, error) {
|
||||
return &result, nil
|
||||
}
|
||||
|
||||
// ShowInstanceBalance shows balance of a specific instance
|
||||
// SHOW BALANCE FROM PROVIDER <provider_name> <instance_name>
|
||||
func (c *RAGFlowClient) ShowInstanceBalance(cmd *Command) (ResponseIf, error) {
|
||||
if c.ServerType != "user" {
|
||||
return nil, fmt.Errorf("this command is only allowed in USER mode")
|
||||
}
|
||||
|
||||
instanceName, ok := cmd.Params["instance_name"].(string)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("instance name not provided")
|
||||
}
|
||||
|
||||
providerName, ok := cmd.Params["provider_name"].(string)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("provider name not provided")
|
||||
}
|
||||
|
||||
url := fmt.Sprintf("/providers/%s/instances/%s/balance", providerName, instanceName)
|
||||
|
||||
resp, err := c.HTTPClient.Request("GET", url, true, "web", nil, nil)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to show instance: %w", err)
|
||||
}
|
||||
|
||||
if resp.StatusCode != 200 {
|
||||
return nil, fmt.Errorf("failed to show instance: HTTP %d, body: %s", resp.StatusCode, string(resp.Body))
|
||||
}
|
||||
|
||||
var result CommonDataResponse
|
||||
if err = json.Unmarshal(resp.Body, &result); err != nil {
|
||||
return nil, fmt.Errorf("show instance failed: invalid JSON (%w)", err)
|
||||
}
|
||||
|
||||
if result.Code != 0 {
|
||||
return nil, fmt.Errorf("%s", result.Message)
|
||||
}
|
||||
|
||||
result.Duration = resp.Duration
|
||||
return &result, nil
|
||||
}
|
||||
|
||||
// AlterProviderInstance renames a provider instance
|
||||
// ALTER INSTANCE <name> NAME <new_name> FROM PROVIDER <name>
|
||||
func (c *RAGFlowClient) AlterProviderInstance(cmd *Command) (ResponseIf, error) {
|
||||
|
||||
@@ -352,6 +352,8 @@ func (p *Parser) parseShowCommand() (*Command, error) {
|
||||
return p.parseShowModel()
|
||||
case TokenInstance:
|
||||
return p.parseShowInstance()
|
||||
case TokenBalance:
|
||||
return p.parseShowBalance()
|
||||
default:
|
||||
return nil, fmt.Errorf("unknown SHOW target: %s", p.curToken.Value)
|
||||
}
|
||||
@@ -1301,6 +1303,45 @@ func (p *Parser) parseShowInstance() (*Command, error) {
|
||||
return cmd, nil
|
||||
}
|
||||
|
||||
// parseShowInstance parses SHOW BALANCE FROM <provider_name> <instance_name>
|
||||
func (p *Parser) parseShowBalance() (*Command, error) {
|
||||
p.nextToken() // consume INSTANCE
|
||||
|
||||
if p.curToken.Type != TokenFrom {
|
||||
return nil, fmt.Errorf("expected FROM")
|
||||
}
|
||||
p.nextToken()
|
||||
|
||||
if p.curToken.Type != TokenQuotedString {
|
||||
return nil, fmt.Errorf("expected provider name after FROM PROVIDER")
|
||||
}
|
||||
providerName, err := p.parseQuotedString()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("expected provider name after FROM PROVIDER: %w", err)
|
||||
}
|
||||
p.nextToken()
|
||||
|
||||
if p.curToken.Type != TokenQuotedString {
|
||||
return nil, fmt.Errorf("expected instance name")
|
||||
}
|
||||
instanceName, err := p.parseQuotedString()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("expected instance name: %w", err)
|
||||
}
|
||||
p.nextToken()
|
||||
|
||||
cmd := NewCommand("show_instance_balance")
|
||||
cmd.Params["instance_name"] = instanceName
|
||||
cmd.Params["provider_name"] = providerName
|
||||
|
||||
p.nextToken()
|
||||
// Semicolon is optional
|
||||
if p.curToken.Type == TokenSemicolon {
|
||||
p.nextToken()
|
||||
}
|
||||
return cmd, nil
|
||||
}
|
||||
|
||||
// parseAlterInstance parses ALTER INSTANCE <name> NAME <new_name> FROM PROVIDER <name> command
|
||||
func (p *Parser) parseAlterInstance() (*Command, error) {
|
||||
p.nextToken() // consume INSTANCE
|
||||
|
||||
@@ -49,6 +49,10 @@ func NewDeepSeekModel(baseURL map[string]string, urlSuffix URLSuffix) *DeepSeekM
|
||||
}
|
||||
}
|
||||
|
||||
func (z *DeepSeekModel) Name() string {
|
||||
return "deepseek"
|
||||
}
|
||||
|
||||
// Chat sends a message and returns response
|
||||
func (z *DeepSeekModel) Chat(modelName, message *string, apiConfig *APIConfig, chatModelConfig *ChatConfig) (*ChatResponse, error) {
|
||||
return nil, fmt.Errorf("not implemented")
|
||||
@@ -145,3 +149,7 @@ func (z *DeepSeekModel) ListModels(apiConfig *APIConfig) ([]string, error) {
|
||||
|
||||
return models, nil
|
||||
}
|
||||
|
||||
func (z *DeepSeekModel) Balance(apiConfig *APIConfig) (map[string]interface{}, error) {
|
||||
return nil, fmt.Errorf("%s, no such method", z.Name())
|
||||
}
|
||||
|
||||
@@ -34,6 +34,10 @@ func NewDummyModel(baseURL map[string]string, urlSuffix URLSuffix) *DummyModel {
|
||||
}
|
||||
}
|
||||
|
||||
func (z *DummyModel) Name() string {
|
||||
return "dummy"
|
||||
}
|
||||
|
||||
// Chat sends a message and returns response
|
||||
func (z *DummyModel) Chat(modelName, message *string, apiConfig *APIConfig, modelConfig *ChatConfig) (*ChatResponse, error) {
|
||||
return nil, fmt.Errorf("not implemented")
|
||||
@@ -52,3 +56,7 @@ func (z *DummyModel) EncodeToEmbedding(modelName *string, texts []string, apiCon
|
||||
func (z *DummyModel) ListModels(apiConfig *APIConfig) ([]string, error) {
|
||||
return nil, fmt.Errorf("not implemented")
|
||||
}
|
||||
|
||||
func (z *DummyModel) Balance(apiConfig *APIConfig) (map[string]interface{}, error) {
|
||||
return nil, fmt.Errorf("no such method")
|
||||
}
|
||||
|
||||
@@ -38,7 +38,7 @@ func (f *ModelFactory) CreateModelDriver(providerName string, baseURL map[string
|
||||
case "deepseek":
|
||||
return NewDeepSeekModel(baseURL, urlSuffix), nil
|
||||
case "moonshot":
|
||||
return NewMooshotModel(baseURL, urlSuffix), nil
|
||||
return NewMoonshotModel(baseURL, urlSuffix), nil
|
||||
default:
|
||||
return NewDummyModel(baseURL, urlSuffix), nil
|
||||
}
|
||||
|
||||
@@ -25,16 +25,16 @@ import (
|
||||
"time"
|
||||
)
|
||||
|
||||
// MooshotModel implements ModelDriver for Mooshot
|
||||
type MooshotModel struct {
|
||||
// MoonshotModel implements ModelDriver for Moonshot
|
||||
type MoonshotModel struct {
|
||||
BaseURL map[string]string
|
||||
URLSuffix URLSuffix
|
||||
httpClient *http.Client // Reusable HTTP client with connection pool
|
||||
}
|
||||
|
||||
// NewMooshotModel creates a new Mooshot model instance
|
||||
func NewMooshotModel(baseURL map[string]string, urlSuffix URLSuffix) *MooshotModel {
|
||||
return &MooshotModel{
|
||||
// NewMoonshotModel creates a new Moonshot model instance
|
||||
func NewMoonshotModel(baseURL map[string]string, urlSuffix URLSuffix) *MoonshotModel {
|
||||
return &MoonshotModel{
|
||||
BaseURL: baseURL,
|
||||
URLSuffix: urlSuffix,
|
||||
httpClient: &http.Client{
|
||||
@@ -49,22 +49,26 @@ func NewMooshotModel(baseURL map[string]string, urlSuffix URLSuffix) *MooshotMod
|
||||
}
|
||||
}
|
||||
|
||||
func (z *MoonshotModel) Name() string {
|
||||
return "moonshot"
|
||||
}
|
||||
|
||||
// Chat sends a message and returns response
|
||||
func (z *MooshotModel) Chat(modelName, message *string, apiConfig *APIConfig, chatModelConfig *ChatConfig) (*ChatResponse, error) {
|
||||
func (z *MoonshotModel) Chat(modelName, message *string, apiConfig *APIConfig, chatModelConfig *ChatConfig) (*ChatResponse, error) {
|
||||
return nil, fmt.Errorf("not implemented")
|
||||
}
|
||||
|
||||
// ChatStreamlyWithSender sends a message and streams response via sender function (best performance, no channel)
|
||||
func (z *MooshotModel) ChatStreamlyWithSender(modelName, message *string, apiConfig *APIConfig, chatModelConfig *ChatConfig, sender func(*string, *string) error) error {
|
||||
func (z *MoonshotModel) ChatStreamlyWithSender(modelName, message *string, apiConfig *APIConfig, chatModelConfig *ChatConfig, sender func(*string, *string) error) error {
|
||||
return fmt.Errorf("not implemented")
|
||||
}
|
||||
|
||||
// EncodeToEmbedding encodes a list of texts into embeddings
|
||||
func (z *MooshotModel) EncodeToEmbedding(modelName *string, texts []string, apiConfig *APIConfig, embeddingConfig *EmbeddingConfig) ([][]float64, error) {
|
||||
func (z *MoonshotModel) EncodeToEmbedding(modelName *string, texts []string, apiConfig *APIConfig, embeddingConfig *EmbeddingConfig) ([][]float64, error) {
|
||||
return nil, fmt.Errorf("not implemented")
|
||||
}
|
||||
|
||||
func (z *MooshotModel) ListModels(apiConfig *APIConfig) ([]string, error) {
|
||||
func (z *MoonshotModel) ListModels(apiConfig *APIConfig) ([]string, error) {
|
||||
var region = "default"
|
||||
if apiConfig.Region != nil {
|
||||
region = *apiConfig.Region
|
||||
@@ -80,7 +84,7 @@ func (z *MooshotModel) ListModels(apiConfig *APIConfig) ([]string, error) {
|
||||
return nil, fmt.Errorf("failed to marshal request: %w", err)
|
||||
}
|
||||
|
||||
req, err := http.NewRequest("POST", url, bytes.NewBuffer(jsonData))
|
||||
req, err := http.NewRequest("GET", url, bytes.NewBuffer(jsonData))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to create request: %w", err)
|
||||
}
|
||||
@@ -109,10 +113,70 @@ func (z *MooshotModel) ListModels(apiConfig *APIConfig) ([]string, error) {
|
||||
return nil, fmt.Errorf("failed to parse response: %w", err)
|
||||
}
|
||||
|
||||
models, ok := result["models"].([]string)
|
||||
if !ok || len(models) == 0 {
|
||||
return nil, fmt.Errorf("no models in response")
|
||||
// convert result["data"] to []map[string]interface{}
|
||||
models := make([]string, 0)
|
||||
for _, model := range result["data"].([]interface{}) {
|
||||
modelMap := model.(map[string]interface{})
|
||||
modelName := modelMap["id"].(string)
|
||||
models = append(models, modelName)
|
||||
}
|
||||
|
||||
return models, nil
|
||||
}
|
||||
|
||||
func (z *MoonshotModel) Balance(apiConfig *APIConfig) (map[string]interface{}, error) {
|
||||
|
||||
var region = "default"
|
||||
if apiConfig.Region != nil {
|
||||
region = *apiConfig.Region
|
||||
}
|
||||
|
||||
url := fmt.Sprintf("%s/%s", z.BaseURL[region], z.URLSuffix.Balance)
|
||||
|
||||
// Build request body
|
||||
reqBody := map[string]interface{}{}
|
||||
|
||||
jsonData, err := json.Marshal(reqBody)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to marshal request: %w", err)
|
||||
}
|
||||
|
||||
req, err := http.NewRequest("GET", url, bytes.NewBuffer(jsonData))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to create request: %w", err)
|
||||
}
|
||||
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", *apiConfig.ApiKey))
|
||||
|
||||
resp, err := z.httpClient.Do(req)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to send request: %w", err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
body, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to read response: %w", err)
|
||||
}
|
||||
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
return nil, fmt.Errorf("API request failed with status %d: %s", resp.StatusCode, string(body))
|
||||
}
|
||||
|
||||
// Parse response
|
||||
var result map[string]interface{}
|
||||
if err = json.Unmarshal(body, &result); err != nil {
|
||||
return nil, fmt.Errorf("failed to parse response: %w", err)
|
||||
}
|
||||
|
||||
data := result["data"].(map[string]interface{})
|
||||
balance := data["available_balance"].(float64)
|
||||
|
||||
var response = map[string]interface{}{
|
||||
"balance": balance,
|
||||
"currency": "CNY",
|
||||
}
|
||||
|
||||
return response, nil
|
||||
}
|
||||
|
||||
@@ -2,6 +2,8 @@ package models
|
||||
|
||||
// EmbeddingModel interface for embedding models
|
||||
type ModelDriver interface {
|
||||
Name() string
|
||||
|
||||
// Chat sends a message and returns response
|
||||
Chat(modelName, message *string, apiConfig *APIConfig, modelConfig *ChatConfig) (*ChatResponse, error)
|
||||
// ChatStreamlyWithSender sends a message and streams response via sender function (best performance, no channel)
|
||||
@@ -10,6 +12,8 @@ type ModelDriver interface {
|
||||
EncodeToEmbedding(modelName *string, texts []string, apiConfig *APIConfig, embeddingConfig *EmbeddingConfig) ([][]float64, error)
|
||||
// List suppported models
|
||||
ListModels(apiConfig *APIConfig) ([]string, error)
|
||||
|
||||
Balance(apiConfig *APIConfig) (map[string]interface{}, error)
|
||||
}
|
||||
|
||||
type ChatResponse struct {
|
||||
|
||||
@@ -52,6 +52,10 @@ func NewZhipuAIModel(baseURL map[string]string, urlSuffix URLSuffix) *ZhipuAIMod
|
||||
}
|
||||
}
|
||||
|
||||
func (z *ZhipuAIModel) Name() string {
|
||||
return "zhipu"
|
||||
}
|
||||
|
||||
// Chat sends a message and returns response
|
||||
func (z *ZhipuAIModel) Chat(modelName, message *string, apiConfig *APIConfig, chatModelConfig *ChatConfig) (*ChatResponse, error) {
|
||||
if message == nil {
|
||||
@@ -281,7 +285,7 @@ func (z *ZhipuAIModel) ChatStreamlyWithSender(modelName, message *string, apiCon
|
||||
|
||||
// Parse the JSON event
|
||||
var event map[string]interface{}
|
||||
if err := json.Unmarshal([]byte(data), &event); err != nil {
|
||||
if err = json.Unmarshal([]byte(data), &event); err != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
@@ -322,7 +326,7 @@ func (z *ZhipuAIModel) ChatStreamlyWithSender(modelName, message *string, apiCon
|
||||
|
||||
// Send [DONE] marker for OpenAI compatibility
|
||||
endOfStream := "[DONE]"
|
||||
if err := sender(&endOfStream, nil); err != nil {
|
||||
if err = sender(&endOfStream, nil); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -377,7 +381,7 @@ func (z *ZhipuAIModel) EncodeToEmbedding(modelName *string, texts []string, apiC
|
||||
|
||||
// Parse response
|
||||
var result map[string]interface{}
|
||||
if err := json.Unmarshal(body, &result); err != nil {
|
||||
if err = json.Unmarshal(body, &result); err != nil {
|
||||
return nil, fmt.Errorf("failed to parse response: %w", err)
|
||||
}
|
||||
|
||||
@@ -415,5 +419,9 @@ func (z *ZhipuAIModel) EncodeToEmbedding(modelName *string, texts []string, apiC
|
||||
}
|
||||
|
||||
func (z *ZhipuAIModel) ListModels(apiConfig *APIConfig) ([]string, error) {
|
||||
return nil, fmt.Errorf("no such method")
|
||||
return nil, fmt.Errorf("%s, no such method", z.Name())
|
||||
}
|
||||
|
||||
func (z *ZhipuAIModel) Balance(apiConfig *APIConfig) (map[string]interface{}, error) {
|
||||
return nil, fmt.Errorf("%s, no such method", z.Name())
|
||||
}
|
||||
|
||||
@@ -355,6 +355,44 @@ func (h *ProviderHandler) ShowProviderInstance(c *gin.Context) {
|
||||
})
|
||||
}
|
||||
|
||||
func (h *ProviderHandler) ShowInstanceBalance(c *gin.Context) {
|
||||
providerName := c.Param("provider_name")
|
||||
if providerName == "" {
|
||||
c.JSON(http.StatusBadRequest, gin.H{
|
||||
"code": 400,
|
||||
"message": "Provider name is required",
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
instanceName := c.Param("instance_name")
|
||||
if instanceName == "" {
|
||||
c.JSON(http.StatusBadRequest, gin.H{
|
||||
"code": 400,
|
||||
"message": "Instance name is required",
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
userID := c.GetString("user_id")
|
||||
|
||||
// Get tenant ID from user
|
||||
balance, errorCode, err := h.modelProviderService.ShowInstanceBalance(providerName, instanceName, userID)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"code": errorCode,
|
||||
"message": err.Error(),
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"code": 0,
|
||||
"message": "success",
|
||||
"data": balance,
|
||||
})
|
||||
}
|
||||
|
||||
type AlterProviderInstanceRequest struct {
|
||||
LLMName string `json:"llm_name" binding:"required"`
|
||||
}
|
||||
|
||||
@@ -212,6 +212,7 @@ func (r *Router) Setup(engine *gin.Engine) {
|
||||
provider.POST("/:provider_name/instances", r.providerHandler.CreateProviderInstance)
|
||||
provider.GET("/:provider_name/instances", r.providerHandler.ListProviderInstances)
|
||||
provider.GET("/:provider_name/instances/:instance_name", r.providerHandler.ShowProviderInstance)
|
||||
provider.GET("/:provider_name/instances/:instance_name/balance", r.providerHandler.ShowInstanceBalance)
|
||||
provider.PUT("/:provider_name/instances/:instance_name", r.providerHandler.AlterProviderInstance)
|
||||
provider.DELETE("/:provider_name/instances", r.providerHandler.DropProviderInstance)
|
||||
provider.GET("/:provider_name/instances/:instance_name/models", r.providerHandler.ListInstanceModels)
|
||||
|
||||
@@ -423,6 +423,76 @@ func (m *ModelProviderService) ShowProviderInstance(providerName, instanceName,
|
||||
return result, common.CodeSuccess, nil
|
||||
}
|
||||
|
||||
func (m *ModelProviderService) ShowInstanceBalance(providerName, instanceName, userID string) (map[string]interface{}, common.ErrorCode, error) {
|
||||
|
||||
// Get tenant ID from user
|
||||
tenants, err := m.userTenantDAO.GetByUserIDAndRole(userID, "owner")
|
||||
if err != nil {
|
||||
return nil, common.CodeServerError, err
|
||||
}
|
||||
|
||||
if len(tenants) == 0 {
|
||||
return nil, common.CodeNotFound, errors.New("user has no tenants")
|
||||
}
|
||||
|
||||
tenantID := tenants[0].TenantID
|
||||
|
||||
// Check if provider exists
|
||||
provider, err := m.modelProviderDAO.GetByTenantIDAndProviderName(tenantID, providerName)
|
||||
if err != nil {
|
||||
return nil, common.CodeServerError, err
|
||||
}
|
||||
|
||||
instance, err := m.modelInstanceDAO.GetByProviderIDAndInstanceName(provider.ID, instanceName)
|
||||
if err != nil {
|
||||
return nil, common.CodeServerError, err
|
||||
}
|
||||
|
||||
providerInfo := dao.GetModelProviderManager().FindProvider(providerName)
|
||||
if providerInfo == nil {
|
||||
return nil, common.CodeServerError, fmt.Errorf("provider %s not found", providerName)
|
||||
}
|
||||
|
||||
var extra map[string]string
|
||||
err = json.Unmarshal([]byte(instance.Extra), &extra)
|
||||
if err != nil {
|
||||
return nil, common.CodeServerError, err
|
||||
}
|
||||
|
||||
apiConfig := &modelModule.APIConfig{
|
||||
ApiKey: nil,
|
||||
Region: nil,
|
||||
}
|
||||
|
||||
region := extra["region"]
|
||||
apiConfig.Region = ®ion
|
||||
apiConfig.ApiKey = &instance.APIKey
|
||||
|
||||
var result map[string]interface{}
|
||||
result, err = providerInfo.ModelDriver.Balance(apiConfig)
|
||||
if err != nil {
|
||||
return nil, common.CodeServerError, err
|
||||
}
|
||||
return result, common.CodeSuccess, nil
|
||||
|
||||
// convert instance.Extra (json string) to map
|
||||
//var extra map[string]string
|
||||
//err = json.Unmarshal([]byte(instance.Extra), &extra)
|
||||
//if err != nil {
|
||||
// return nil, common.CodeServerError, err
|
||||
//}
|
||||
//
|
||||
//result := map[string]interface{}{
|
||||
// "id": instance.ID,
|
||||
// "instanceName": instance.InstanceName,
|
||||
// "providerID": instance.ProviderID,
|
||||
// "status": instance.Status,
|
||||
// "region": extra["region"],
|
||||
//}
|
||||
//
|
||||
//return result, common.CodeSuccess, nil
|
||||
}
|
||||
|
||||
func (m *ModelProviderService) AlterProviderInstance(providerName, instanceName, newInstanceName, apiKey, userID string) (common.ErrorCode, error) {
|
||||
return common.CodeSuccess, nil
|
||||
}
|
||||
|
||||
23
uv.lock
generated
23
uv.lock
generated
@@ -1745,6 +1745,27 @@ version = "0.8.3"
|
||||
source = { registry = "https://mirrors.aliyun.com/pypi/simple" }
|
||||
sdist = { url = "https://mirrors.aliyun.com/pypi/packages/51/0b/c0f53a14317b304e2e93b29a831b0c83306caae9af7f0e2e037d17c4f63f/datrie-0.8.3.tar.gz", hash = "sha256:ea021ad4c8a8bf14e08a71c7872a622aa399a510f981296825091c7ca0436e80" }
|
||||
|
||||
[[package]]
|
||||
name = "debugpy"
|
||||
version = "1.8.20"
|
||||
source = { registry = "https://mirrors.aliyun.com/pypi/simple" }
|
||||
sdist = { url = "https://mirrors.aliyun.com/pypi/packages/e0/b7/cd8080344452e4874aae67c40d8940e2b4d47b01601a8fd9f44786c757c7/debugpy-1.8.20.tar.gz", hash = "sha256:55bc8701714969f1ab89a6d5f2f3d40c36f91b2cbe2f65d98bf8196f6a6a2c33" }
|
||||
wheels = [
|
||||
{ url = "https://mirrors.aliyun.com/pypi/packages/14/57/7f34f4736bfb6e00f2e4c96351b07805d83c9a7b33d28580ae01374430f7/debugpy-1.8.20-cp312-cp312-macosx_15_0_universal2.whl", hash = "sha256:4ae3135e2089905a916909ef31922b2d733d756f66d87345b3e5e52b7a55f13d" },
|
||||
{ url = "https://mirrors.aliyun.com/pypi/packages/ab/78/b193a3975ca34458f6f0e24aaf5c3e3da72f5401f6054c0dfd004b41726f/debugpy-1.8.20-cp312-cp312-manylinux_2_34_x86_64.whl", hash = "sha256:88f47850a4284b88bd2bfee1f26132147d5d504e4e86c22485dfa44b97e19b4b" },
|
||||
{ url = "https://mirrors.aliyun.com/pypi/packages/c1/55/f14deb95eaf4f30f07ef4b90a8590fc05d9e04df85ee379712f6fb6736d7/debugpy-1.8.20-cp312-cp312-win32.whl", hash = "sha256:4057ac68f892064e5f98209ab582abfee3b543fb55d2e87610ddc133a954d390" },
|
||||
{ url = "https://mirrors.aliyun.com/pypi/packages/a1/39/2bef246368bd42f9bd7cba99844542b74b84dacbdbea0833e610f384fee8/debugpy-1.8.20-cp312-cp312-win_amd64.whl", hash = "sha256:a1a8f851e7cf171330679ef6997e9c579ef6dd33c9098458bd9986a0f4ca52e3" },
|
||||
{ url = "https://mirrors.aliyun.com/pypi/packages/15/e2/fc500524cc6f104a9d049abc85a0a8b3f0d14c0a39b9c140511c61e5b40b/debugpy-1.8.20-cp313-cp313-macosx_15_0_universal2.whl", hash = "sha256:5dff4bb27027821fdfcc9e8f87309a28988231165147c31730128b1c983e282a" },
|
||||
{ url = "https://mirrors.aliyun.com/pypi/packages/90/83/fb33dcea789ed6018f8da20c5a9bc9d82adc65c0c990faed43f7c955da46/debugpy-1.8.20-cp313-cp313-manylinux_2_34_x86_64.whl", hash = "sha256:84562982dd7cf5ebebfdea667ca20a064e096099997b175fe204e86817f64eaf" },
|
||||
{ url = "https://mirrors.aliyun.com/pypi/packages/a6/25/b1e4a01bfb824d79a6af24b99ef291e24189080c93576dfd9b1a2815cd0f/debugpy-1.8.20-cp313-cp313-win32.whl", hash = "sha256:da11dea6447b2cadbf8ce2bec59ecea87cc18d2c574980f643f2d2dfe4862393" },
|
||||
{ url = "https://mirrors.aliyun.com/pypi/packages/13/f7/a0b368ce54ffff9e9028c098bd2d28cfc5b54f9f6c186929083d4c60ba58/debugpy-1.8.20-cp313-cp313-win_amd64.whl", hash = "sha256:eb506e45943cab2efb7c6eafdd65b842f3ae779f020c82221f55aca9de135ed7" },
|
||||
{ url = "https://mirrors.aliyun.com/pypi/packages/33/2e/f6cb9a8a13f5058f0a20fe09711a7b726232cd5a78c6a7c05b2ec726cff9/debugpy-1.8.20-cp314-cp314-macosx_15_0_universal2.whl", hash = "sha256:9c74df62fc064cd5e5eaca1353a3ef5a5d50da5eb8058fcef63106f7bebe6173" },
|
||||
{ url = "https://mirrors.aliyun.com/pypi/packages/c5/56/6ddca50b53624e1ca3ce1d1e49ff22db46c47ea5fb4c0cc5c9b90a616364/debugpy-1.8.20-cp314-cp314-manylinux_2_34_x86_64.whl", hash = "sha256:077a7447589ee9bc1ff0cdf443566d0ecf540ac8aa7333b775ebcb8ce9f4ecad" },
|
||||
{ url = "https://mirrors.aliyun.com/pypi/packages/c5/d9/d64199c14a0d4c476df46c82470a3ce45c8d183a6796cfb5e66533b3663c/debugpy-1.8.20-cp314-cp314-win32.whl", hash = "sha256:352036a99dd35053b37b7803f748efc456076f929c6a895556932eaf2d23b07f" },
|
||||
{ url = "https://mirrors.aliyun.com/pypi/packages/e0/d9/1f07395b54413432624d61524dfd98c1a7c7827d2abfdb8829ac92638205/debugpy-1.8.20-cp314-cp314-win_amd64.whl", hash = "sha256:a98eec61135465b062846112e5ecf2eebb855305acc1dfbae43b72903b8ab5be" },
|
||||
{ url = "https://mirrors.aliyun.com/pypi/packages/e0/c3/7f67dea8ccf8fdcb9c99033bbe3e90b9e7395415843accb81428c441be2d/debugpy-1.8.20-py2.py3-none-any.whl", hash = "sha256:5be9bed9ae3be00665a06acaa48f8329d2b9632f15fd09f6a9a8c8d9907e54d7" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "decorator"
|
||||
version = "5.2.1"
|
||||
@@ -6549,6 +6570,7 @@ dependencies = [
|
||||
{ name = "cohere" },
|
||||
{ name = "crawl4ai" },
|
||||
{ name = "dashscope" },
|
||||
{ name = "debugpy" },
|
||||
{ name = "deepl" },
|
||||
{ name = "demjson3" },
|
||||
{ name = "discord-py" },
|
||||
@@ -6692,6 +6714,7 @@ requires-dist = [
|
||||
{ name = "cohere", specifier = "==5.6.2" },
|
||||
{ name = "crawl4ai", specifier = ">=0.4.0,<1.0.0" },
|
||||
{ name = "dashscope", specifier = "==1.25.11" },
|
||||
{ name = "debugpy", specifier = ">=1.8.13" },
|
||||
{ name = "deepl", specifier = "==1.18.0" },
|
||||
{ name = "demjson3", specifier = "==3.0.6" },
|
||||
{ name = "discord-py", specifier = "==2.3.2" },
|
||||
|
||||
Reference in New Issue
Block a user