diff --git a/internal/cli/client.go b/internal/cli/client.go index 15df81682d..961265328e 100644 --- a/internal/cli/client.go +++ b/internal/cli/client.go @@ -295,6 +295,8 @@ func (c *RAGFlowClient) ExecuteUserCommand(cmd *Command) (ResponseIf, error) { return c.ParseFileUserCommand(cmd) case "check_provider_connection": return c.CheckProviderConnection(cmd) + case "check_provider_with_key": + return c.CheckProviderWithKey(cmd) case "use_model": return c.UseModel(cmd) case "show_current_model": diff --git a/internal/cli/user_command.go b/internal/cli/user_command.go index 448295445d..35b2c9dc7f 100644 --- a/internal/cli/user_command.go +++ b/internal/cli/user_command.go @@ -2551,6 +2551,64 @@ func (c *RAGFlowClient) CheckProviderConnection(cmd *Command) (ResponseIf, error return &result, nil } +func (c *RAGFlowClient) CheckProviderWithKey(cmd *Command) (ResponseIf, error) { + if c.HTTPClient.APIToken == "" && c.HTTPClient.LoginToken == "" { + return nil, fmt.Errorf("API token not set. Please login first") + } + if c.ServerType != "user" { + return nil, fmt.Errorf("this command is only allowed in USER mode") + } + + providerName, ok := cmd.Params["provider_name"].(string) + if !ok || providerName == "" { + return nil, fmt.Errorf("provider name not provided") + } + region, ok := cmd.Params["region"].(string) + if !ok || region == "" { + return nil, fmt.Errorf("region not provided") + } + apiKey, ok := cmd.Params["api_key"].(string) + if !ok { + return nil, fmt.Errorf("api_key not provided") + } + baseURL, _ := cmd.Params["base_url"].(string) + + var apiKeyValue interface{} + if apiKey != "" { + apiKeyValue = apiKey + } else { + apiKeyValue = nil + } + + url := fmt.Sprintf("/providers/%s/connection", providerName) + + payload := map[string]interface{}{ + "region": region, + "api_key": apiKeyValue, + } + if baseURL != "" { + payload["base_url"] = baseURL + } + + resp, err := c.HTTPClient.Request("GET", url, "api", nil, payload) + if err != nil { + return nil, fmt.Errorf("failed to check provider connection with key: %w", err) + } + if resp.StatusCode != 200 { + return nil, fmt.Errorf("failed to check provider connection: HTTP %d, body: %s", resp.StatusCode, string(resp.Body)) + } + + var result SimpleResponse + if err = json.Unmarshal(resp.Body, &result); err != nil { + return nil, fmt.Errorf("check provider connection failed: invalid JSON (%w)", err) + } + if result.Code != 0 { + return nil, fmt.Errorf("%s", result.Message) + } + result.Duration = resp.Duration + return &result, nil +} + // UseModel sets the current model for chat func (c *RAGFlowClient) UseModel(cmd *Command) (ResponseIf, error) { if c.HTTPClient.APIToken == "" && c.HTTPClient.LoginToken == "" { diff --git a/internal/cli/user_parser.go b/internal/cli/user_parser.go index 2575d25173..4919ad13a7 100644 --- a/internal/cli/user_parser.go +++ b/internal/cli/user_parser.go @@ -3118,6 +3118,17 @@ func (p *Parser) parseModelParseCommand() (*Command, error) { func (p *Parser) parseCheckCommand() (*Command, error) { p.nextToken() // consume CHECK + switch p.curToken.Type { + case TokenInstance: + return p.parseCheckInstanceCommand() + case TokenProvider: + return p.parseCheckProviderByKeyCommand() + default: + return nil, fmt.Errorf("expected INSTANCE or PROVIDER after CHECK") + } +} + +func (p *Parser) parseCheckInstanceCommand() (*Command, error) { if p.curToken.Type != TokenInstance { return nil, fmt.Errorf("expected INSTANCE after CHECK") } @@ -3151,6 +3162,68 @@ func (p *Parser) parseCheckCommand() (*Command, error) { return cmd, nil } +func (p *Parser) parseCheckProviderByKeyCommand() (*Command, error) { + if p.curToken.Type != TokenProvider { + return nil, fmt.Errorf("expected PROVIDER after CHECK") + } + p.nextToken() + + if p.curToken.Type != TokenQuotedString { + return nil, fmt.Errorf("expected provider name after PROVIDER") + } + providerName := p.curToken.Value + p.nextToken() + + if p.curToken.Type != TokenRegion { + return nil, fmt.Errorf("expected REGION after provider name") + } + p.nextToken() + + if p.curToken.Type != TokenQuotedString { + return nil, fmt.Errorf("expected region name after REGION") + } + regionName := p.curToken.Value + p.nextToken() + + if p.curToken.Type != TokenKey { + return nil, fmt.Errorf("expected KEY after region name") + } + p.nextToken() + + if p.curToken.Type != TokenQuotedString { + return nil, fmt.Errorf("expected API key after KEY") + } + apiKey := p.curToken.Value + p.nextToken() + + baseURL := "" + if p.curToken.Type == TokenURL { + p.nextToken() + if p.curToken.Type != TokenQuotedString { + return nil, fmt.Errorf("expected base URL after URL") + } + baseURL = p.curToken.Value + p.nextToken() + } + + if p.curToken.Type == TokenSemicolon { + p.nextToken() + } + if p.curToken.Type != TokenEOF { + return nil, fmt.Errorf("unexpected token: %s", p.curToken.Value) + } + + cmd := NewCommand("check_provider_with_key") + cmd.Params["provider_name"] = providerName + cmd.Params["region"] = regionName + cmd.Params["api_key"] = apiKey + if baseURL != "" { + cmd.Params["base_url"] = baseURL + } + + return cmd, nil +} + func (p *Parser) parseUseCommand() (*Command, error) { p.nextToken() // consume USE