兼容新的mongo方法格式,并且修复client的apitoken覆盖问题
This commit is contained in:
@@ -34,9 +34,10 @@ type CreateChatRes struct {
|
|||||||
|
|
||||||
// UpdateChatReq 更新对话配置请求
|
// UpdateChatReq 更新对话配置请求
|
||||||
type UpdateChatReq struct {
|
type UpdateChatReq struct {
|
||||||
Name string `json:"name,omitempty"` // 对话配置名称
|
Name string `json:"name,omitempty"` // 对话配置名称
|
||||||
DatasetIds []string `json:"dataset_ids,omitempty"` // 关联的知识库ID列表
|
Description string `json:"description,omitempty"` // 对话描述
|
||||||
Prompt *PromptConfig `json:"prompt,omitempty"` // 提示词配置
|
DatasetIds []string `json:"dataset_ids,omitempty"` // 关联的知识库ID列表(RAGFlow API使用下划线格式)
|
||||||
|
Prompt *PromptConfig `json:"prompt,omitempty"` // 提示词配置
|
||||||
}
|
}
|
||||||
|
|
||||||
// 聊天助手管理
|
// 聊天助手管理
|
||||||
@@ -122,6 +123,11 @@ func (c *Client) CreateChat(ctx context.Context, req *CreateChatReq) (*Chat, err
|
|||||||
if res.Code != 0 {
|
if res.Code != 0 {
|
||||||
return nil, gerror.Newf("create chat failed: %s", res.Msg)
|
return nil, gerror.Newf("create chat failed: %s", res.Msg)
|
||||||
}
|
}
|
||||||
|
// 检查响应数据是否为空:防止RAGFlow API返回 {"code":0, "data":null}
|
||||||
|
// 如果不检查直接返回,调用方会收到 (nil, nil),导致空指针异常
|
||||||
|
if res.Data == nil {
|
||||||
|
return nil, gerror.Newf("create chat returned null data: %s", res.Msg)
|
||||||
|
}
|
||||||
return res.Data, nil
|
return res.Data, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -7,9 +7,10 @@ import (
|
|||||||
"sync"
|
"sync"
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
|
|
||||||
commonHttp "gitee.com/red-future---jilin-g/common/http"
|
"github.com/gogf/gf/v2/encoding/gjson"
|
||||||
"github.com/gogf/gf/v2/errors/gerror"
|
"github.com/gogf/gf/v2/errors/gerror"
|
||||||
"github.com/gogf/gf/v2/frame/g"
|
"github.com/gogf/gf/v2/frame/g"
|
||||||
|
"github.com/gogf/gf/v2/net/gclient"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@@ -116,7 +117,23 @@ func (r *CommonResponse) IsSuccess() bool {
|
|||||||
return r.Code == 0
|
return r.Code == 0
|
||||||
}
|
}
|
||||||
|
|
||||||
// request 发送 HTTP 请求(使用统一的common/http包,支持负载均衡)
|
// request 发送 HTTP 请求
|
||||||
|
//
|
||||||
|
// 为什么不使用 common/http 包:
|
||||||
|
// 1. common/http/http.go:61 会用内部请求的Authorization覆盖RAGFlow API key:
|
||||||
|
// Httpclient.SetHeader("Authorization", g.RequestFromCtx(ctx).GetHeader("Authorization"))
|
||||||
|
// 这会导致RAGFlow API认证失败,因为内部token不是RAGFlow的API key
|
||||||
|
//
|
||||||
|
// 2. common/http/http.go:69-74 强制解析为内部API响应格式(ghttp.DefaultHandlerResponse):
|
||||||
|
// resultStrut := &ghttp.DefaultHandlerResponse{}
|
||||||
|
// if err = gconv.Struct(result, &resultStrut); err != nil {
|
||||||
|
// err = errors.New(resultStrut.Message)
|
||||||
|
// } else if resultStrut.Code == 200 || resultStrut.Code == 0 {
|
||||||
|
// gconv.Struct(resultStrut.Data, target)
|
||||||
|
// }
|
||||||
|
// RAGFlow API返回格式与内部API不同,会导致解析失败
|
||||||
|
//
|
||||||
|
// 因此直接使用 g.Client() 调用第三方API,避免上述问题
|
||||||
func (c *Client) request(ctx context.Context, method, path string, body interface{}, result interface{}) (err error) {
|
func (c *Client) request(ctx context.Context, method, path string, body interface{}, result interface{}) (err error) {
|
||||||
endpoint := c.getNextEndpoint()
|
endpoint := c.getNextEndpoint()
|
||||||
if endpoint == "" {
|
if endpoint == "" {
|
||||||
@@ -124,26 +141,51 @@ func (c *Client) request(ctx context.Context, method, path string, body interfac
|
|||||||
}
|
}
|
||||||
fullURL := endpoint + path
|
fullURL := endpoint + path
|
||||||
|
|
||||||
headers := map[string]string{
|
// 添加详细日志:请求信息
|
||||||
"Authorization": "Bearer " + c.APIKey,
|
g.Log().Infof(ctx, "RAGFlow请求: %s %s", method, fullURL)
|
||||||
"Content-Type": "application/json",
|
if body != nil {
|
||||||
|
bodyJSON := g.NewVar(body).String()
|
||||||
|
g.Log().Infof(ctx, "RAGFlow请求体: %s", bodyJSON)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 创建新的HTTP客户端实例(避免共享状态)
|
||||||
|
client := g.Client()
|
||||||
|
client.SetHeader("Authorization", "Bearer "+c.APIKey)
|
||||||
|
client.SetHeader("Content-Type", "application/json")
|
||||||
|
|
||||||
|
var response *gclient.Response
|
||||||
switch method {
|
switch method {
|
||||||
case "GET":
|
case "GET":
|
||||||
err = commonHttp.Get(ctx, fullURL, headers, result, body)
|
response, err = client.Get(ctx, fullURL, body)
|
||||||
case "POST":
|
case "POST":
|
||||||
err = commonHttp.Post(ctx, fullURL, headers, result, body)
|
response, err = client.Post(ctx, fullURL, body)
|
||||||
case "PUT":
|
case "PUT":
|
||||||
err = commonHttp.Put(ctx, fullURL, headers, result, body)
|
response, err = client.Put(ctx, fullURL, body)
|
||||||
case "DELETE":
|
case "DELETE":
|
||||||
err = commonHttp.Delete(ctx, fullURL, headers, result, body)
|
response, err = client.Delete(ctx, fullURL, body)
|
||||||
default:
|
default:
|
||||||
return gerror.Newf("unsupported method: %s", method)
|
return gerror.Newf("unsupported method: %s", method)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return gerror.Newf("RAGFlow API request failed: %v", err)
|
g.Log().Errorf(ctx, "RAGFlow HTTP请求失败: %v", err)
|
||||||
|
return gerror.Wrapf(err, "HTTP request to RAGFlow failed")
|
||||||
|
}
|
||||||
|
|
||||||
|
if response == nil {
|
||||||
|
return gerror.New("HTTP response is nil")
|
||||||
|
}
|
||||||
|
|
||||||
|
defer response.Close()
|
||||||
|
|
||||||
|
// 读取响应体
|
||||||
|
respBytes := response.ReadAll()
|
||||||
|
g.Log().Infof(ctx, "RAGFlow响应: %s", string(respBytes))
|
||||||
|
|
||||||
|
// 解析JSON到result
|
||||||
|
if err = gjson.DecodeTo(respBytes, result); err != nil {
|
||||||
|
g.Log().Errorf(ctx, "RAGFlow响应解析失败: %v, 原始响应: %s", err, string(respBytes))
|
||||||
|
return gerror.Wrapf(err, "failed to decode RAGFlow response")
|
||||||
}
|
}
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
|
|
||||||
"github.com/gogf/gf/v2/errors/gerror"
|
"github.com/gogf/gf/v2/errors/gerror"
|
||||||
|
"github.com/gogf/gf/v2/frame/g"
|
||||||
)
|
)
|
||||||
|
|
||||||
// 数据集管理
|
// 数据集管理
|
||||||
@@ -82,17 +83,38 @@ type DeleteDatasetsReq struct {
|
|||||||
|
|
||||||
// CreateDataset 创建数据集
|
// CreateDataset 创建数据集
|
||||||
func (c *Client) CreateDataset(ctx context.Context, req *CreateDatasetReq) (*Dataset, error) {
|
func (c *Client) CreateDataset(ctx context.Context, req *CreateDatasetReq) (*Dataset, error) {
|
||||||
|
g.Log().Infof(ctx, "CreateDataset请求: name=%s, description=%s, embedding_model=%s", req.Name, req.Description, req.EmbeddingModel)
|
||||||
|
|
||||||
var res struct {
|
var res struct {
|
||||||
Code int `json:"code"`
|
Code int `json:"code"`
|
||||||
Data *Dataset `json:"data"`
|
Data *Dataset `json:"data"`
|
||||||
Msg string `json:"message"`
|
Msg string `json:"message"`
|
||||||
}
|
}
|
||||||
if err := c.request(ctx, "POST", "/api/v1/datasets", req, &res); err != nil {
|
if err := c.request(ctx, "POST", "/api/v1/datasets", req, &res); err != nil {
|
||||||
|
g.Log().Errorf(ctx, "CreateDataset请求失败: %v", err)
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if res.Code != 0 {
|
|
||||||
return nil, gerror.Newf("create dataset failed: %s", res.Msg)
|
g.Log().Infof(ctx, "CreateDataset响应: code=%d, msg=%s, data_is_nil=%v", res.Code, res.Msg, res.Data == nil)
|
||||||
|
|
||||||
|
// code=101表示dataset名称已存在(正常业务场景,不是错误)
|
||||||
|
// 调用方应该通过ListDatasets查找已有dataset并复用
|
||||||
|
if res.Code == 101 {
|
||||||
|
return nil, gerror.Newf("Dataset名称已存在: %s", res.Msg)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 其他非0的code表示真正的错误
|
||||||
|
if res.Code != 0 {
|
||||||
|
return nil, gerror.Newf("创建知识库失败(code=%d): %s", res.Code, res.Msg)
|
||||||
|
}
|
||||||
|
|
||||||
|
// code=0但data=null,表示创建异常(可能是RAGFlow配置问题,如embedding模型不可用、权限不足等)
|
||||||
|
// 这不是正常状态,应该返回错误而不是(nil, nil)
|
||||||
|
if res.Data == nil {
|
||||||
|
return nil, gerror.Newf("创建知识库返回空数据(code=0,data=null),可能是RAGFlow配置问题: %s", res.Msg)
|
||||||
|
}
|
||||||
|
|
||||||
|
g.Log().Infof(ctx, "CreateDataset成功: id=%s, name=%s", res.Data.Id, res.Data.Name)
|
||||||
return res.Data, nil
|
return res.Data, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -134,6 +156,10 @@ func (c *Client) ListDatasets(ctx context.Context, req *ListDatasetsReq) (*ListD
|
|||||||
if err := c.request(ctx, "GET", path, nil, &res); err != nil {
|
if err := c.request(ctx, "GET", path, nil, &res); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 添加调试日志
|
||||||
|
g.Log().Infof(ctx, "ListDatasets原始响应: code=%d, total=%d, data_len=%d", res.Code, res.Total, len(res.Data))
|
||||||
|
|
||||||
if res.Code != 0 {
|
if res.Code != 0 {
|
||||||
return nil, gerror.Newf("list datasets failed: code=%d", res.Code)
|
return nil, gerror.Newf("list datasets failed: code=%d", res.Code)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -90,6 +90,11 @@ func (c *Client) CreateSession(ctx context.Context, chatId string, req *CreateSe
|
|||||||
if res.Code != 0 {
|
if res.Code != 0 {
|
||||||
return nil, gerror.Newf("create session failed: %s", res.Msg)
|
return nil, gerror.Newf("create session failed: %s", res.Msg)
|
||||||
}
|
}
|
||||||
|
// 检查响应数据是否为空:防止RAGFlow API返回 {"code":0, "data":null}
|
||||||
|
// 如果不检查直接返回,调用方会收到 (nil, nil),导致空指针异常
|
||||||
|
if res.Data == nil {
|
||||||
|
return nil, gerror.Newf("create session returned null data: %s", res.Msg)
|
||||||
|
}
|
||||||
return res.Data, nil
|
return res.Data, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user