mirror of
https://github.com/infiniflow/ragflow.git
synced 2026-07-28 03:38:11 +08:00
Go: add gitee and siliconflow as model provider (#14336)
### What problem does this PR solve? As title ### 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:
@@ -337,7 +337,7 @@ func (c *HTTPClient) RequestJSON(method, path string, useAPIBase bool, authKind
|
||||
}
|
||||
|
||||
// RequestStream makes an HTTP request for SSE streaming and returns the response body reader
|
||||
func (c *HTTPClient) RequestStream(method, path string, useAPIBase bool, authKind string, headers map[string]string, jsonBody map[string]interface{}) (io.ReadCloser, float64, error) {
|
||||
func (c *HTTPClient) RequestStream(method, path string, useAPIBase bool, authKind string, headers map[string]string, jsonBody map[string]interface{}) (io.ReadCloser, error) {
|
||||
url := c.BuildURL(path, useAPIBase)
|
||||
mergedHeaders := c.Headers(authKind, headers)
|
||||
|
||||
@@ -345,7 +345,7 @@ func (c *HTTPClient) RequestStream(method, path string, useAPIBase bool, authKin
|
||||
if jsonBody != nil {
|
||||
jsonData, err := json.Marshal(jsonBody)
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
return nil, err
|
||||
}
|
||||
body = bytes.NewReader(jsonData)
|
||||
if mergedHeaders == nil {
|
||||
@@ -361,24 +361,22 @@ func (c *HTTPClient) RequestStream(method, path string, useAPIBase bool, authKin
|
||||
|
||||
req, err := http.NewRequest(method, url, body)
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for k, v := range mergedHeaders {
|
||||
req.Header.Set(k, v)
|
||||
}
|
||||
|
||||
startTime := time.Now()
|
||||
resp, err := c.client.Do(req)
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
return nil, err
|
||||
}
|
||||
duration := time.Since(startTime).Seconds()
|
||||
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
resp.Body.Close()
|
||||
return nil, duration, fmt.Errorf("HTTP %d", resp.StatusCode)
|
||||
return nil, fmt.Errorf("HTTP %d", resp.StatusCode)
|
||||
}
|
||||
|
||||
return resp.Body, duration, nil
|
||||
return resp.Body, nil
|
||||
}
|
||||
|
||||
@@ -303,6 +303,22 @@ func (l *Lexer) lookupIdent(ident string) Token {
|
||||
return Token{Type: TokenChat, Value: ident}
|
||||
case "THINK":
|
||||
return Token{Type: TokenThink, Value: ident}
|
||||
case "EFFORT":
|
||||
return Token{Type: TokenEffort, Value: ident}
|
||||
case "VERBOSITY":
|
||||
return Token{Type: TokenVerbosity, Value: ident}
|
||||
case "NONE":
|
||||
return Token{Type: TokenNone, Value: ident}
|
||||
case "MINIMAL":
|
||||
return Token{Type: TokenMinimal, Value: ident}
|
||||
case "LOW":
|
||||
return Token{Type: TokenLow, Value: ident}
|
||||
case "MEDIUM":
|
||||
return Token{Type: TokenMedium, Value: ident}
|
||||
case "HIGH":
|
||||
return Token{Type: TokenHigh, Value: ident}
|
||||
case "MAX":
|
||||
return Token{Type: TokenMax, Value: ident}
|
||||
case "STREAM":
|
||||
return Token{Type: TokenStream, Value: ident}
|
||||
case "LS":
|
||||
|
||||
@@ -140,6 +140,7 @@ func (r *NonStreamResponse) PrintOut() {
|
||||
fmt.Printf("Thinking: %s\n", r.ReasoningContent)
|
||||
}
|
||||
fmt.Printf("Answer: %s\n", r.Answer)
|
||||
fmt.Printf("Time: %f\n", r.Duration)
|
||||
} else {
|
||||
fmt.Println("ERROR")
|
||||
fmt.Printf("%d, %s\n", r.Code, r.Message)
|
||||
@@ -166,7 +167,9 @@ func (r *StreamMessageResponse) SetOutputFormat(format OutputFormat) {
|
||||
}
|
||||
|
||||
func (r *StreamMessageResponse) PrintOut() {
|
||||
if r.Code != 0 {
|
||||
if r.Code == 0 {
|
||||
fmt.Printf("Time: %f\n", r.Duration)
|
||||
} else {
|
||||
fmt.Println("ERROR")
|
||||
fmt.Printf("%d, %s\n", r.Code, r.Message)
|
||||
}
|
||||
|
||||
@@ -117,6 +117,14 @@ const (
|
||||
TokenUse
|
||||
TokenCheck
|
||||
TokenThink
|
||||
TokenEffort
|
||||
TokenVerbosity
|
||||
TokenNone
|
||||
TokenMinimal
|
||||
TokenLow
|
||||
TokenMedium
|
||||
TokenHigh
|
||||
TokenMax
|
||||
TokenLS
|
||||
TokenCat
|
||||
TokenInsert
|
||||
|
||||
@@ -24,6 +24,7 @@ import (
|
||||
"os"
|
||||
ce "ragflow/internal/cli/contextengine"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
// PingServer pings the server to check if it's alive
|
||||
@@ -1460,13 +1461,13 @@ func (c *RAGFlowClient) ChatToModel(cmd *Command) (ResponseIf, error) {
|
||||
|
||||
// Check if composite_model_name is provided in command
|
||||
if compositeModelName, ok := cmd.Params["composite_model_name"].(string); ok && compositeModelName != "" {
|
||||
names := strings.Split(compositeModelName, "/")
|
||||
names := strings.Split(compositeModelName, "@")
|
||||
if len(names) != 3 {
|
||||
return nil, fmt.Errorf("model name must be in format 'provider/instance/model'")
|
||||
return nil, fmt.Errorf("model name must be in format 'model@instance@provider'")
|
||||
}
|
||||
providerName = names[0]
|
||||
providerName = names[2]
|
||||
instanceName = names[1]
|
||||
modelName = names[2]
|
||||
modelName = names[0]
|
||||
} else if c.CurrentModel != nil {
|
||||
// Use current model if set
|
||||
providerName = c.CurrentModel.Provider
|
||||
@@ -1479,18 +1480,27 @@ func (c *RAGFlowClient) ChatToModel(cmd *Command) (ResponseIf, error) {
|
||||
message := cmd.Params["message"].(string)
|
||||
thinking := cmd.Params["thinking"].(bool)
|
||||
stream := cmd.Params["stream"].(bool)
|
||||
effort := cmd.Params["effort"].(string)
|
||||
verbosity := cmd.Params["verbosity"].(string)
|
||||
|
||||
url := fmt.Sprintf("/providers/%s/instances/%s/models/%s", providerName, instanceName, modelName)
|
||||
url := fmt.Sprintf("/providers/%s/instances/%s/models", providerName, instanceName)
|
||||
|
||||
payload := map[string]interface{}{
|
||||
"message": message,
|
||||
"stream": stream, // use stream API
|
||||
"thinking": thinking,
|
||||
"model_name": modelName,
|
||||
"message": message,
|
||||
"stream": stream, // use stream API
|
||||
"thinking": thinking,
|
||||
}
|
||||
|
||||
if thinking {
|
||||
payload["effort"] = effort
|
||||
payload["verbosity"] = verbosity
|
||||
}
|
||||
|
||||
if stream {
|
||||
// Call stream http api
|
||||
reader, duration, err := c.HTTPClient.RequestStream("POST", url, true, "web", nil, payload)
|
||||
startTime := time.Now()
|
||||
reader, err := c.HTTPClient.RequestStream("POST", url, true, "web", nil, payload)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to chat model: %w", err)
|
||||
}
|
||||
@@ -1513,6 +1523,7 @@ func (c *RAGFlowClient) ChatToModel(cmd *Command) (ResponseIf, error) {
|
||||
if reasoningPrint {
|
||||
fmt.Print("Thinking: ")
|
||||
reasoningPrint = false
|
||||
thinking = true
|
||||
} else {
|
||||
fmt.Print(data)
|
||||
}
|
||||
@@ -1543,7 +1554,7 @@ func (c *RAGFlowClient) ChatToModel(cmd *Command) (ResponseIf, error) {
|
||||
return nil, fmt.Errorf("chat error: received error event from server")
|
||||
}
|
||||
}
|
||||
|
||||
duration := time.Since(startTime).Seconds()
|
||||
if err := scanner.Err(); err != nil {
|
||||
return nil, fmt.Errorf("error reading stream: %w", err)
|
||||
}
|
||||
@@ -1633,15 +1644,15 @@ func (c *RAGFlowClient) UseModel(cmd *Command) (ResponseIf, error) {
|
||||
return nil, fmt.Errorf("model identifier not provided")
|
||||
}
|
||||
|
||||
names := strings.Split(compositeModelName, "/")
|
||||
names := strings.Split(compositeModelName, "@")
|
||||
if len(names) != 3 {
|
||||
return nil, fmt.Errorf("model identifier must be in format 'provider/instance/model'")
|
||||
return nil, fmt.Errorf("model identifier must be in format 'model@instance@provider'")
|
||||
}
|
||||
|
||||
c.CurrentModel = &CurrentModel{
|
||||
Provider: names[0],
|
||||
Provider: names[2],
|
||||
Instance: names[1],
|
||||
Model: names[2],
|
||||
Model: names[0],
|
||||
}
|
||||
|
||||
var result SimpleResponse
|
||||
|
||||
@@ -2241,12 +2241,12 @@ func (p *Parser) parseChatCommand() (*Command, error) {
|
||||
var message string
|
||||
|
||||
// Check if we have a quoted string that looks like a model identifier (contains two slashes)
|
||||
// Format: 'provider/instance/model' or just 'message'
|
||||
// Format: 'model@instance@provider' or just 'message'
|
||||
if p.curToken.Type == TokenQuotedString {
|
||||
firstArg := p.curToken.Value
|
||||
|
||||
// Check if it looks like a model identifier (contains exactly 2 slashes)
|
||||
slashCount := strings.Count(firstArg, "/")
|
||||
slashCount := strings.Count(firstArg, "@")
|
||||
if slashCount == 2 {
|
||||
// This is likely a model identifier, expect another quoted string for message
|
||||
compositeModelName = firstArg
|
||||
@@ -2271,18 +2271,69 @@ func (p *Parser) parseChatCommand() (*Command, error) {
|
||||
return nil, fmt.Errorf("expected model name (quoted string) or message")
|
||||
}
|
||||
|
||||
cmd := NewCommand("chat_to_model")
|
||||
|
||||
effort := "default"
|
||||
verbosity := "low"
|
||||
if p.curToken.Type == TokenWith {
|
||||
p.nextToken() // pass WITH
|
||||
switch p.curToken.Type {
|
||||
case TokenEffort:
|
||||
{
|
||||
p.nextToken() // pass VERBOSITY
|
||||
switch p.curToken.Type {
|
||||
case TokenNone:
|
||||
effort = "none"
|
||||
case TokenMinimal:
|
||||
effort = "minimal"
|
||||
case TokenLow:
|
||||
effort = "low"
|
||||
case TokenMedium:
|
||||
effort = "medium"
|
||||
case TokenHigh:
|
||||
effort = "high"
|
||||
case TokenMax:
|
||||
effort = "max"
|
||||
default:
|
||||
return nil, fmt.Errorf("invalid effort level")
|
||||
}
|
||||
p.nextToken()
|
||||
break
|
||||
}
|
||||
case TokenVerbosity:
|
||||
{
|
||||
p.nextToken() // pass VERBOSITY
|
||||
switch p.curToken.Type {
|
||||
case TokenLow:
|
||||
verbosity = "low"
|
||||
case TokenMedium:
|
||||
verbosity = "median"
|
||||
case TokenHigh:
|
||||
verbosity = "high"
|
||||
default:
|
||||
return nil, fmt.Errorf("invalid verbosity level")
|
||||
}
|
||||
p.nextToken()
|
||||
break
|
||||
}
|
||||
default:
|
||||
return nil, fmt.Errorf("expected VERBOSITY or EFFORT")
|
||||
}
|
||||
}
|
||||
|
||||
// Semicolon is optional
|
||||
if p.curToken.Type == TokenSemicolon {
|
||||
p.nextToken()
|
||||
}
|
||||
|
||||
cmd := NewCommand("chat_to_model")
|
||||
if compositeModelName != "" {
|
||||
cmd.Params["composite_model_name"] = compositeModelName
|
||||
}
|
||||
cmd.Params["message"] = message
|
||||
cmd.Params["thinking"] = false
|
||||
cmd.Params["stream"] = false
|
||||
cmd.Params["effort"] = effort
|
||||
cmd.Params["verbosity"] = verbosity
|
||||
return cmd, nil
|
||||
}
|
||||
|
||||
@@ -2369,10 +2420,10 @@ func (p *Parser) parseUseCommand() (*Command, error) {
|
||||
}
|
||||
p.nextToken() // consume MODEL
|
||||
|
||||
// Parse model identifier in format 'provider/instance/model'
|
||||
// Parse model identifier in format 'model@instance@provider'
|
||||
compositeModelName, err := p.parseQuotedString()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("expected model identifier in format 'provider/instance/model': %w", err)
|
||||
return nil, fmt.Errorf("expected model identifier in format 'model@instance@provider': %w", err)
|
||||
}
|
||||
p.nextToken()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user