diff --git a/apiserver/pkg/chat/chat.go b/apiserver/pkg/chat/chat.go index 69a614c5a..8771572e9 100644 --- a/apiserver/pkg/chat/chat.go +++ b/apiserver/pkg/chat/chat.go @@ -19,6 +19,7 @@ package chat import ( "context" "errors" + "fmt" "sync" "time" @@ -46,24 +47,24 @@ func AppRun(ctx context.Context, req ChatReqBody, respStream chan string) (*Chat token := auth.ForOIDCToken(ctx) c, err := client.GetClient(token) if err != nil { - return nil, err + return nil, fmt.Errorf("failed to get a dynamic client: %w", err) } obj, err := c.Resource(schema.GroupVersionResource{Group: v1alpha1.GroupVersion.Group, Version: v1alpha1.GroupVersion.Version, Resource: "applications"}). Namespace(req.AppNamespace).Get(ctx, req.APPName, metav1.GetOptions{}) if err != nil { - return nil, err + return nil, fmt.Errorf("failed to get application: %w", err) } app := &v1alpha1.Application{} err = runtime.DefaultUnstructuredConverter.FromUnstructured(obj.UnstructuredContent(), app) if err != nil { - return nil, err + return nil, fmt.Errorf("failed to convert application: %w", err) } if !app.Status.IsReady() { return nil, errors.New("application is not ready") } var conversation Conversation currentUser, _ := ctx.Value(auth.UserNameContextKey).(string) - if req.ConversationID != "" { + if !req.NewChat { var ok bool conversation, ok = Conversations[req.ConversationID] if !ok { @@ -80,7 +81,7 @@ func AppRun(ctx context.Context, req ChatReqBody, respStream chan string) (*Chat } } else { conversation = Conversation{ - ID: string(uuid.NewUUID()), + ID: req.ConversationID, AppName: req.APPName, AppNamespce: req.AppNamespace, StartedAt: time.Now(), @@ -102,8 +103,8 @@ func AppRun(ctx context.Context, req ChatReqBody, respStream chan string) (*Chat if err != nil { return nil, err } - klog.Infoln("begin to run application", obj.GetName()) - out, err := appRun.Run(ctx, c, respStream, application.Input{Question: req.Query, NeedStream: req.ResponseMode == Streaming, History: conversation.History}) + klog.FromContext(ctx).Info("begin to run application", "appName", req.APPName, "appNamespace", req.AppNamespace) + out, err := appRun.Run(ctx, c, respStream, application.Input{Question: req.Query, NeedStream: req.ResponseMode.IsStreaming(), History: conversation.History}) if err != nil { return nil, err } diff --git a/apiserver/pkg/chat/chat_type.go b/apiserver/pkg/chat/chat_type.go index 67f970bb0..a710e6cab 100644 --- a/apiserver/pkg/chat/chat_type.go +++ b/apiserver/pkg/chat/chat_type.go @@ -26,6 +26,10 @@ import ( type ResponseMode string +func (r ResponseMode) IsStreaming() bool { + return r == Streaming +} + const ( // Blocking means the response is returned in a blocking manner Blocking ResponseMode = "blocking" @@ -62,6 +66,7 @@ type ChatReqBody struct { ResponseMode ResponseMode `json:"response_mode" binding:"required" example:"blocking"` ConversationReqBody `json:",inline"` Debug bool `json:"-"` + NewChat bool `json:"-"` } type ChatRespBody struct { diff --git a/apiserver/pkg/requestid/requestid.go b/apiserver/pkg/requestid/requestid.go new file mode 100644 index 000000000..c08da5e2d --- /dev/null +++ b/apiserver/pkg/requestid/requestid.go @@ -0,0 +1,37 @@ +/* +Copyright 2023 KubeAGI. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package requestid + +import ( + "github.com/gin-contrib/requestid" + "github.com/gin-gonic/gin" + "k8s.io/klog/v2" +) + +func RequestIDInterceptor() gin.HandlerFunc { + return requestid.New(requestid.WithHandler(addRequestIDToLog)) +} + +func addRequestIDToLog(c *gin.Context, id string) { + ctx := c.Request.Context() + logger := klog.FromContext(ctx) + newLogger := logger.WithValues("requestID", id) + newLogger.Info("new request") + c.Request = c.Request.WithContext(klog.NewContext(ctx, newLogger)) + + c.Next() +} diff --git a/apiserver/service/chat.go b/apiserver/service/chat.go index c19730b58..efcdb7606 100644 --- a/apiserver/service/chat.go +++ b/apiserver/service/chat.go @@ -17,18 +17,22 @@ limitations under the License. package service import ( + "errors" + "fmt" "io" "net/http" "strings" "time" "github.com/gin-gonic/gin" + "k8s.io/apimachinery/pkg/util/uuid" "k8s.io/klog/v2" "github.com/kubeagi/arcadia/apiserver/config" "github.com/kubeagi/arcadia/apiserver/pkg/auth" "github.com/kubeagi/arcadia/apiserver/pkg/chat" "github.com/kubeagi/arcadia/apiserver/pkg/oidc" + "github.com/kubeagi/arcadia/apiserver/pkg/requestid" ) // @BasePath /chat @@ -53,23 +57,44 @@ func chatHandler() gin.HandlerFunc { return } req.Debug = c.Query("debug") == "true" - stream := req.ResponseMode == chat.Streaming + req.NewChat = len(req.ConversationID) == 0 + if req.NewChat { + req.ConversationID = string(uuid.NewUUID()) + } var response *chat.ChatRespBody var err error - if stream { + if req.ResponseMode.IsStreaming() { buf := strings.Builder{} // handle chat streaming mode respStream := make(chan string, 1) go func() { defer func() { - if err := recover(); err != nil { - klog.Errorln("An error occurred when run chat.AppRun: %s", err) + if e := recover(); e != nil { + err, ok := e.(error) + if ok { + klog.FromContext(c.Request.Context()).Error(err, "A panic occurred when run chat.AppRun") + } else { + klog.FromContext(c.Request.Context()).Error(fmt.Errorf("get err:%#v", e), "A panic occurred when run chat.AppRun") + } } }() - response, err = chat.AppRun(c, req, respStream) - if response.Message == buf.String() { + response, err = chat.AppRun(c.Request.Context(), req, respStream) + if err != nil { + c.SSEvent("error", chat.ChatRespBody{ + ConversationID: req.ConversationID, + Message: err.Error(), + CreatedAt: time.Now(), + }) + // c.JSON(http.StatusInternalServerError, chat.ErrorResp{Err: err.Error()}) + klog.FromContext(c.Request.Context()).Error(err, "error resp") close(respStream) + return + } + if response != nil { + if str := buf.String(); response.Message == str || strings.TrimSpace(str) == strings.TrimSpace(response.Message) { + close(respStream) + } } }() @@ -98,7 +123,7 @@ func chatHandler() gin.HandlerFunc { c.Writer.Header().Set("Cache-Control", "no-cache") c.Writer.Header().Set("Connection", "keep-alive") c.Writer.Header().Set("Transfer-Encoding", "chunked") - klog.Infoln("start to receive messages...") + klog.FromContext(c.Request.Context()).Info("start to receive messages...") clientDisconnected := c.Stream(func(w io.Writer) bool { if msg, ok := <-respStream; ok { c.SSEvent("", chat.ChatRespBody{ @@ -113,19 +138,20 @@ func chatHandler() gin.HandlerFunc { return false }) if clientDisconnected { - klog.Infoln("chatHandler: client is disconnected") + klog.FromContext(c.Request.Context()).Info("chatHandler: the client is disconnected") } - klog.Infoln("end to receive messages.") + klog.FromContext(c.Request.Context()).Info("end to receive messages") } else { // handle chat blocking mode - response, err = chat.AppRun(c, req, nil) + response, err = chat.AppRun(c.Request.Context(), req, nil) if err != nil { c.JSON(http.StatusInternalServerError, chat.ErrorResp{Err: err.Error()}) - klog.Infof("error resp: %v", err) + klog.FromContext(c.Request.Context()).Error(err, "error resp") return } c.JSON(http.StatusOK, response) } + klog.FromContext(c.Request.Context()).V(3).Info("chat done", "req", req) } } @@ -144,15 +170,17 @@ func listConversationHandler() gin.HandlerFunc { return func(c *gin.Context) { req := chat.APPMetadata{} if err := c.ShouldBindJSON(&req); err != nil { + klog.FromContext(c.Request.Context()).Error(err, "list conversation: error binding json") c.JSON(http.StatusBadRequest, chat.ErrorResp{Err: err.Error()}) return } resp, err := chat.ListConversations(c, req) if err != nil { + klog.FromContext(c.Request.Context()).Error(err, "error list conversation") c.JSON(http.StatusInternalServerError, chat.ErrorResp{Err: err.Error()}) - klog.Infof("error resp: %v", err) return } + klog.FromContext(c.Request.Context()).V(3).Info("list conversation done", "req", req) c.JSON(http.StatusOK, resp) } } @@ -172,15 +200,18 @@ func deleteConversationHandler() gin.HandlerFunc { return func(c *gin.Context) { conversationID := c.Param("conversationID") if conversationID == "" { - c.JSON(http.StatusBadRequest, chat.ErrorResp{Err: "conversationID is required"}) + err := errors.New("conversationID is required") + klog.FromContext(c.Request.Context()).Error(err, "conversationID is required") + c.JSON(http.StatusBadRequest, chat.ErrorResp{Err: err.Error()}) return } err := chat.DeleteConversation(c, conversationID) if err != nil { + klog.FromContext(c.Request.Context()).Error(err, "error delete conversation") c.JSON(http.StatusInternalServerError, chat.ErrorResp{Err: err.Error()}) - klog.Infof("error resp: %v", err) return } + klog.FromContext(c.Request.Context()).V(3).Info("delete conversation done", "conversationID", conversationID) c.JSON(http.StatusOK, chat.SimpleResp{Message: "ok"}) } } @@ -200,16 +231,18 @@ func historyHandler() gin.HandlerFunc { return func(c *gin.Context) { req := chat.ConversationReqBody{} if err := c.ShouldBindJSON(&req); err != nil { + klog.FromContext(c.Request.Context()).Error(err, "historyHandler: error binding json") c.JSON(http.StatusBadRequest, chat.ErrorResp{Err: err.Error()}) return } resp, err := chat.ListMessages(c, req) if err != nil { + klog.FromContext(c.Request.Context()).Error(err, "error list messages") c.JSON(http.StatusInternalServerError, chat.ErrorResp{Err: err.Error()}) - klog.Infof("error resp: %v", err) return } c.JSON(http.StatusOK, resp) + klog.FromContext(c.Request.Context()).V(3).Info("get message history done", "req", req) } } @@ -229,32 +262,36 @@ func referenceHandler() gin.HandlerFunc { return func(c *gin.Context) { messageID := c.Param("messageID") if messageID == "" { - c.JSON(http.StatusBadRequest, chat.ErrorResp{Err: "messageID is required"}) + err := errors.New("messageID is required") + klog.FromContext(c.Request.Context()).Error(err, "messageID is required") + c.JSON(http.StatusBadRequest, chat.ErrorResp{Err: err.Error()}) return } req := chat.MessageReqBody{ MessageID: messageID, } if err := c.ShouldBindJSON(&req); err != nil { + klog.FromContext(c.Request.Context()).Error(err, "referenceHandler: error binding json") c.JSON(http.StatusBadRequest, chat.ErrorResp{Err: err.Error()}) return } resp, err := chat.GetMessageReferences(c, req) if err != nil { + klog.FromContext(c.Request.Context()).Error(err, "error get message references") c.JSON(http.StatusInternalServerError, chat.ErrorResp{Err: err.Error()}) - klog.Infof("error resp: %v", err) return } + klog.FromContext(c.Request.Context()).V(3).Info("get message references done", "req", req) c.JSON(http.StatusOK, resp) } } func registerChat(g *gin.RouterGroup, conf config.ServerConfig) { - g.POST("", auth.AuthInterceptor(conf.EnableOIDC, oidc.Verifier, "get", "applications"), chatHandler()) // chat with bot + g.POST("", auth.AuthInterceptor(conf.EnableOIDC, oidc.Verifier, "get", "applications"), requestid.RequestIDInterceptor(), chatHandler()) // chat with bot - g.POST("/conversations", auth.AuthInterceptor(conf.EnableOIDC, oidc.Verifier, "get", "applications"), listConversationHandler()) // list conversations - g.DELETE("/conversations/:conversationID", auth.AuthInterceptor(conf.EnableOIDC, oidc.Verifier, "get", "applications"), deleteConversationHandler()) // delete conversation + g.POST("/conversations", auth.AuthInterceptor(conf.EnableOIDC, oidc.Verifier, "get", "applications"), requestid.RequestIDInterceptor(), listConversationHandler()) // list conversations + g.DELETE("/conversations/:conversationID", auth.AuthInterceptor(conf.EnableOIDC, oidc.Verifier, "get", "applications"), requestid.RequestIDInterceptor(), deleteConversationHandler()) // delete conversation - g.POST("/messages", auth.AuthInterceptor(conf.EnableOIDC, oidc.Verifier, "get", "applications"), historyHandler()) // messages history - g.POST("/messages/:messageID/references", auth.AuthInterceptor(conf.EnableOIDC, oidc.Verifier, "get", "applications"), referenceHandler()) // messages reference + g.POST("/messages", auth.AuthInterceptor(conf.EnableOIDC, oidc.Verifier, "get", "applications"), requestid.RequestIDInterceptor(), historyHandler()) // messages history + g.POST("/messages/:messageID/references", auth.AuthInterceptor(conf.EnableOIDC, oidc.Verifier, "get", "applications"), requestid.RequestIDInterceptor(), referenceHandler()) // messages reference } diff --git a/go.mod b/go.mod index 3c51c1cd1..6e3abd10c 100644 --- a/go.mod +++ b/go.mod @@ -7,6 +7,7 @@ require ( github.com/KawashiroNitori/butcher/v2 v2.0.1 github.com/amikos-tech/chroma-go v0.0.0-20230901221218-d0087270239e github.com/coreos/go-oidc/v3 v3.7.0 + github.com/gin-contrib/requestid v0.0.6 github.com/gin-gonic/gin v1.9.1 github.com/go-logr/logr v1.2.0 github.com/gofiber/fiber/v2 v2.49.1 diff --git a/go.sum b/go.sum index 78c102b42..09f93f7ab 100644 --- a/go.sum +++ b/go.sum @@ -203,8 +203,11 @@ github.com/getkin/kin-openapi v0.76.0/go.mod h1:660oXbgy5JFMKreazJaQTw7o+X00qeSy github.com/getsentry/raven-go v0.2.0/go.mod h1:KungGk8q33+aIAZUIVWZDr2OfAEBsO49PX4NzFV5kcQ= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/gin-contrib/gzip v0.0.6 h1:NjcunTcGAj5CO1gn4N8jHOSIeRFHIbn51z6K+xaN4d4= +github.com/gin-contrib/requestid v0.0.6 h1:mGcxTnHQ45F6QU5HQRgQUDsAfHprD3P7g2uZ4cSZo9o= +github.com/gin-contrib/requestid v0.0.6/go.mod h1:9i4vKATX/CdggbkY252dPVasgVucy/ggBeELXuQztm4= github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= +github.com/gin-gonic/gin v1.8.1/go.mod h1:ji8BvRH1azfM+SYow9zQ6SZMvR8qOMZHmsCuWR9tTTk= github.com/gin-gonic/gin v1.9.1 h1:4idEAncQnU5cB7BeOkPtxjfCSye0AAm1R0RVIqJ+Jmg= github.com/gin-gonic/gin v1.9.1/go.mod h1:hPrL7YrpYKXt5YId3A/Tnip5kqbEAP+KLuI3SUcPTeU= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= @@ -238,16 +241,21 @@ github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh github.com/go-openapi/swag v0.19.14/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ= github.com/go-openapi/swag v0.22.6 h1:dnqg1XfHXL9aBxSbktBqFR5CxVyVI+7fYWhAf1JOeTw= github.com/go-openapi/swag v0.22.6/go.mod h1:Gl91UqO+btAM0plGGxHqJcQZ1ZTy6jbmridBTsDy8A0= +github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s= +github.com/go-playground/locales v0.14.0/go.mod h1:sawfccIbzZTqEDETgFXqTho0QybSa7l++s0DH+LDiLs= github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA= github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY= +github.com/go-playground/universal-translator v0.18.0/go.mod h1:UvRDBj+xPUEGrFYl+lu/H90nyDXpg0fqeB/AQUGNTVA= github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY= github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= +github.com/go-playground/validator/v10 v10.10.0/go.mod h1:74x4gJWsvQexRdW8Pn3dXSGrTK4nAUsbPlLADvpJkos= github.com/go-playground/validator/v10 v10.16.0 h1:x+plE831WK4vaKHO/jpgUGsvLKIqRRkz6M78GuJAfGE= github.com/go-playground/validator/v10 v10.16.0/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU= github.com/go-sql-driver/mysql v1.7.1 h1:lUIinVbN1DY0xBg0eMOzmmtGoHwWBbvnWubQUrtU8EI= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= +github.com/goccy/go-json v0.9.7/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU= github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= @@ -337,6 +345,7 @@ github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm4 github.com/google/s2a-go v0.1.4 h1:1kZ/sQM3srePvKs3tXAvQzo66XfcReoqFpIpIccE7Oc= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.3.1 h1:KjJaJ9iWZ3jOFZIf1Lqf4laDRCasjl0BCmnEGxkdLb4= github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/enterprise-certificate-proxy v0.2.3 h1:yk9/cqRKtT9wXZSsRH9aurXEpJX+U6FLtpYTdC3R06k= @@ -423,6 +432,8 @@ github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= @@ -430,6 +441,7 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/ledongthuc/pdf v0.0.0-20220302134840-0c2507a12d80 h1:6Yzfa6GP0rIo/kULo2bwGEkFvCePZ3qHDDTC3/J9Swo= github.com/ledongthuc/pdf v0.0.0-20220302134840-0c2507a12d80/go.mod h1:imJHygn/1yfhB7XSJJKlFZKl/J+dCPAknuiaGOshXAs= +github.com/leodido/go-urn v1.2.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ictyFfxY= github.com/leodido/go-urn v1.2.4 h1:XlAE/cm/ms7TE/VMVoduSpNBoyc2dOxHs5MZSwAN63Q= github.com/leodido/go-urn v1.2.4/go.mod h1:7ZrI8mTSeBSHl/UaRyKQW1qZeMgak41ANeCNaVckg+4= github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= @@ -442,6 +454,7 @@ github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaO github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= +github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= @@ -512,9 +525,11 @@ github.com/onsi/gomega v1.18.1/go.mod h1:0q+aL8jAiMXy9hbwj2mr5GziHiwhAIQpFmmtT5h github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= +github.com/pelletier/go-toml/v2 v2.0.1/go.mod h1:r9LEWfGN8R5k0VXJ+0BkIe7MYkRdwZOjgMj2KwnJFUo= github.com/pelletier/go-toml/v2 v2.1.1 h1:LWAJwfNvjQZCFIDKWYQaM62NcYeYViCmWIwmOStowAI= github.com/pelletier/go-toml/v2 v2.1.1/go.mod h1:tJU2Z3ZkXwnxa4DPO899bsyIoywizdUvyaeZurnPPDc= github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= +github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= @@ -560,6 +575,8 @@ github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJ github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= +github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE= github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M= github.com/rs/xid v1.5.0 h1:mKX4bl4iPYJtEIxp6CYiUuLQ/8DYMoz0PUdtGgMFRVc= github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= @@ -628,6 +645,8 @@ github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1 github.com/tmc/grpc-websocket-proxy v0.0.0-20201229170055-e5319fda7802/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI= github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08= +github.com/ugorji/go v1.2.7/go.mod h1:nF9osbDWLy6bDVv/Rtoh6QgnvNDpmCalQV5urGCCS6M= +github.com/ugorji/go/codec v1.2.7/go.mod h1:WGN1fab3R1fzQlVQTkfxVtIBhWDRqOviHU95kRgeqEY= github.com/ugorji/go/codec v1.2.12 h1:9LC83zGrHhuUA9l16C9AHXAqEV/2wBQ4nkvumAE65EE= github.com/ugorji/go/codec v1.2.12/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= @@ -719,6 +738,7 @@ golang.org/x/crypto v0.0.0-20190911031432-227b76d455e7/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20220214200702-86341886e292/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= @@ -909,6 +929,7 @@ golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210831042530-f4d43177bf5e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -1134,6 +1155,7 @@ google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlba google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= google.golang.org/protobuf v1.32.0 h1:pPC6BG5ex8PDFnkbrGU3EixyhKcQ2aDuBS36lqK/C7I= google.golang.org/protobuf v1.32.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= @@ -1144,6 +1166,7 @@ gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8 gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= diff --git a/pkg/application/app_run.go b/pkg/application/app_run.go index bff008f3a..292d00aa9 100644 --- a/pkg/application/app_run.go +++ b/pkg/application/app_run.go @@ -107,10 +107,10 @@ func (a *Application) Init(ctx context.Context, cli dynamic.Interface) (err erro for _, node := range a.Spec.Nodes { n, err := InitNode(ctx, node.Name, *node.Ref, cli) if err != nil { - return fmt.Errorf("initnode %s failed: %v", node.Name, err) + return fmt.Errorf("initnode %s failed: %w", node.Name, err) } if err := n.Init(ctx, cli, map[string]any{}); err != nil { // TODO arg - return fmt.Errorf("node %s init failed: %v", node.Name, err) + return fmt.Errorf("node %s init failed: %w", node.Name, err) } a.Nodes[node.Name] = n if node.Name == inputNodeName { @@ -142,7 +142,7 @@ func (a *Application) Init(ctx context.Context, cli dynamic.Interface) (err erro a.StartingNodes = append(a.StartingNodes, current) } } - klog.Infof("init application success ending node: %#v\n", a.EndingNode) + klog.FromContext(ctx).V(5).Info(fmt.Sprintf("init application success starting nodes: %#v\n", a.StartingNodes)) return nil } @@ -189,44 +189,56 @@ func (a *Application) Run(ctx context.Context, cli dynamic.Interface, respStream return output, nil } -func InitNode(ctx context.Context, name string, ref arcadiav1alpha1.TypedObjectReference, cli dynamic.Interface) (base.Node, error) { +func InitNode(ctx context.Context, name string, ref arcadiav1alpha1.TypedObjectReference, cli dynamic.Interface) (n base.Node, err error) { + logger := klog.FromContext(ctx) + defer func() { + if err != nil { + logger.Error(err, "initnode failed") + } + }() baseNode := base.NewBaseNode(name, ref) + err = fmt.Errorf("unknown kind %s:%v", name, ref) switch baseNode.Group() { case "chain": switch baseNode.Kind() { case "llmchain": + logger.V(3).Info("initnode llmchain") return chain.NewLLMChain(baseNode), nil case "retrievalqachain": + logger.V(3).Info("initnode retrievalqachain") return chain.NewRetrievalQAChain(baseNode), nil default: - return nil, fmt.Errorf("%s:%v kind is not found", name, ref) + return nil, err } case "retriever": switch baseNode.Kind() { case "knowledgebaseretriever": + logger.V(3).Info("initnode knowledgebaseretriever") return retriever.NewKnowledgeBaseRetriever(ctx, baseNode, cli) default: - return nil, fmt.Errorf("%s:%v kind is not found", name, ref) + return nil, err } case "": switch baseNode.Kind() { case "llm": + logger.V(3).Info("initnode llm") return llm.NewLLM(baseNode), nil case "input": return base.NewInput(baseNode), nil case "output": return base.NewOutput(baseNode), nil default: - return nil, fmt.Errorf("%s:%v kind is not found", name, ref) + return nil, err } case "prompt": switch baseNode.Kind() { case "prompt": + logger.V(3).Info("initnode prompt") return prompt.NewPrompt(baseNode), nil default: - return nil, fmt.Errorf("%s:%v kind is not found", name, ref) + return nil, err } default: - return nil, fmt.Errorf("%s:%v group is not found", name, ref) + return nil, fmt.Errorf("unknown group %s:%v", name, ref) } } diff --git a/pkg/application/chain/common.go b/pkg/application/chain/common.go index e715315ab..597184d7f 100644 --- a/pkg/application/chain/common.go +++ b/pkg/application/chain/common.go @@ -18,7 +18,7 @@ package chain import ( "context" - "errors" + "fmt" "github.com/tmc/langchaingo/chains" "github.com/tmc/langchaingo/llms" @@ -31,16 +31,18 @@ import ( func stream(res map[string]any) func(ctx context.Context, chunk []byte) error { return func(ctx context.Context, chunk []byte) error { + logger := klog.FromContext(ctx) if _, ok := res["_answer_stream"]; !ok { - klog.Errorln("no _answer_stream found, create a new one") + logger.Info("no _answer_stream found, create a new one") res["_answer_stream"] = make(chan string) } streamChan, ok := res["_answer_stream"].(chan string) if !ok { - klog.Errorln("answer_stream is not chan string") - return errors.New("answer_stream is not chan string") + err := fmt.Errorf("answer_stream is not chan string, but %T", res["_answer_stream"]) + logger.Error(err, "answer_stream is not chan string") + return err } - klog.V(5).Infoln("stream out:", string(chunk)) + logger.V(5).Info("stream out:" + string(chunk)) streamChan <- string(chunk) return nil } diff --git a/pkg/application/chain/llmchain.go b/pkg/application/chain/llmchain.go index 964f7d4c0..0a0d36599 100644 --- a/pkg/application/chain/llmchain.go +++ b/pkg/application/chain/llmchain.go @@ -82,7 +82,7 @@ func (l *LLMChain) Run(ctx context.Context, cli dynamic.Interface, args map[stri } err = runtime.DefaultUnstructuredConverter.FromUnstructured(obj.UnstructuredContent(), instance) if err != nil { - return args, err + return args, fmt.Errorf("can't convert obj to LLMChain: %w", err) } options := getChainOptions(instance.Spec.CommonChainConfig) @@ -100,9 +100,10 @@ func (l *LLMChain) Run(ctx context.Context, cli dynamic.Interface, args map[stri out, err = chains.Predict(ctx, l.LLMChain, args) } } - klog.V(5).Infof("blocking out: %s", out) + klog.FromContext(ctx).V(5).Info("use llmchain, blocking out:" + out) if err == nil { args["_answer"] = out + return args, nil } - return args, err + return args, fmt.Errorf("llmchain run error: %w", err) } diff --git a/pkg/application/chain/retrievalqachain.go b/pkg/application/chain/retrievalqachain.go index 36a60903c..d98c50946 100644 --- a/pkg/application/chain/retrievalqachain.go +++ b/pkg/application/chain/retrievalqachain.go @@ -91,7 +91,7 @@ func (l *RetrievalQAChain) Run(ctx context.Context, cli dynamic.Interface, args } err = runtime.DefaultUnstructuredConverter.FromUnstructured(obj.UnstructuredContent(), instance) if err != nil { - return args, err + return args, fmt.Errorf("can't convert obj to RetrievalQAChain: %w", err) } options := getChainOptions(instance.Spec.CommonChainConfig) @@ -121,9 +121,10 @@ func (l *RetrievalQAChain) Run(ctx context.Context, cli dynamic.Interface, args if stuffDocuments != nil && len(stuffDocuments.References) > 0 { args["_references"] = stuffDocuments.References } - klog.V(5).Infof("blocking out: %s", out) + klog.FromContext(ctx).V(5).Info("use retrievalqachain, blocking out:" + out) if err == nil { args["_answer"] = out + return args, nil } - return args, err + return args, fmt.Errorf("retrievalqachain run error: %w", err) } diff --git a/pkg/application/llm/llm.go b/pkg/application/llm/llm.go index c16ad9e6f..1df5eeb26 100644 --- a/pkg/application/llm/llm.go +++ b/pkg/application/llm/llm.go @@ -52,11 +52,11 @@ func (z *LLM) Init(ctx context.Context, cli dynamic.Interface, args map[string]a } err = runtime.DefaultUnstructuredConverter.FromUnstructured(obj.UnstructuredContent(), instance) if err != nil { - return err + return fmt.Errorf("can't convert the llm in cluster: %w", err) } llm, err := langchainwrap.GetLangchainLLM(ctx, instance, nil, cli) if err != nil { - return err + return fmt.Errorf("can't convert to langchain llm: %w", err) } z.LanguageModel = llm return nil diff --git a/pkg/application/prompt/prompt.go b/pkg/application/prompt/prompt.go index 01b48ae20..a5644ed6b 100644 --- a/pkg/application/prompt/prompt.go +++ b/pkg/application/prompt/prompt.go @@ -18,6 +18,7 @@ package prompt import ( "context" + "fmt" "github.com/tmc/langchaingo/prompts" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -46,14 +47,14 @@ func (p *Prompt) Run(ctx context.Context, cli dynamic.Interface, args map[string obj, err := cli.Resource(schema.GroupVersionResource{Group: v1alpha1.GroupVersion.Group, Version: v1alpha1.GroupVersion.Version, Resource: "prompts"}). Namespace(p.Ref.GetNamespace(ns)).Get(ctx, p.Ref.Name, metav1.GetOptions{}) if err != nil { - return args, err + return args, fmt.Errorf("can't find the prompt in cluster: %w", err) } err = runtime.DefaultUnstructuredConverter.FromUnstructured(obj.UnstructuredContent(), instance) if err != nil { - return args, err + return args, fmt.Errorf("can't convert the prompt in cluster: %w", err) } template := prompts.NewChatPromptTemplate([]prompts.MessageFormatter{ - prompts.NewSystemMessagePromptTemplate(instance.Spec.SystemMessage, []string{}), // It's not working now, and it's counterproductive. + prompts.NewSystemMessagePromptTemplate(instance.Spec.SystemMessage, []string{}), prompts.NewHumanMessagePromptTemplate(instance.Spec.UserMessage, []string{"question"}), }) // todo format diff --git a/pkg/application/retriever/knowledgebaseretriever.go b/pkg/application/retriever/knowledgebaseretriever.go index c6561c726..34f5a379d 100644 --- a/pkg/application/retriever/knowledgebaseretriever.go +++ b/pkg/application/retriever/knowledgebaseretriever.go @@ -68,7 +68,7 @@ func NewKnowledgeBaseRetriever(ctx context.Context, baseNode base.BaseNode, cli } err = runtime.DefaultUnstructuredConverter.FromUnstructured(obj.UnstructuredContent(), instance) if err != nil { - return nil, err + return nil, fmt.Errorf("can't convert the retriever in cluster: %w", err) } knowledgebaseName := instance.Spec.Input.KnowledgeBaseRef.Name @@ -76,11 +76,11 @@ func NewKnowledgeBaseRetriever(ctx context.Context, baseNode base.BaseNode, cli obj, err = cli.Resource(schema.GroupVersionResource{Group: v1alpha1.GroupVersion.Group, Version: v1alpha1.GroupVersion.Version, Resource: "knowledgebases"}). Namespace(baseNode.Ref.GetNamespace(ns)).Get(ctx, knowledgebaseName, metav1.GetOptions{}) if err != nil { - return nil, err + return nil, fmt.Errorf("can't find the knowledgebase in cluster: %w", err) } err = runtime.DefaultUnstructuredConverter.FromUnstructured(obj.UnstructuredContent(), knowledgebase) if err != nil { - return nil, err + return nil, fmt.Errorf("can't convert the knowledgebase in cluster: %w", err) } embedderReq := knowledgebase.Spec.Embedder @@ -93,25 +93,25 @@ func NewKnowledgeBaseRetriever(ctx context.Context, baseNode base.BaseNode, cli obj, err = cli.Resource(schema.GroupVersionResource{Group: v1alpha1.GroupVersion.Group, Version: v1alpha1.GroupVersion.Version, Resource: "embedders"}). Namespace(embedderReq.GetNamespace(ns)).Get(ctx, embedderReq.Name, metav1.GetOptions{}) if err != nil { - return nil, err + return nil, fmt.Errorf("can't find the embedder in cluster: %w", err) } err = runtime.DefaultUnstructuredConverter.FromUnstructured(obj.UnstructuredContent(), embedder) if err != nil { - return nil, err + return nil, fmt.Errorf("can't convert the embedder in cluster: %w", err) } em, err := langchainwrap.GetLangchainEmbedder(ctx, embedder, nil, cli) if err != nil { - return nil, err + return nil, fmt.Errorf("can't convert to langchain embedder: %w", err) } vectorStore := &v1alpha1.VectorStore{} obj, err = cli.Resource(schema.GroupVersionResource{Group: v1alpha1.GroupVersion.Group, Version: v1alpha1.GroupVersion.Version, Resource: "vectorstores"}). Namespace(vectorStoreReq.GetNamespace(ns)).Get(ctx, vectorStoreReq.Name, metav1.GetOptions{}) if err != nil { - return nil, err + return nil, fmt.Errorf("can't find the vectorstore in cluster: %w", err) } err = runtime.DefaultUnstructuredConverter.FromUnstructured(obj.UnstructuredContent(), vectorStore) if err != nil { - return nil, err + return nil, fmt.Errorf("can't convert the vectorstore in cluster: %w", err) } switch vectorStore.Spec.Type() { // nolint: gocritic case v1alpha1.VectorStoreTypeChroma: @@ -151,16 +151,17 @@ type KnowledgeBaseStuffDocuments struct { var _ chains.Chain = &KnowledgeBaseStuffDocuments{} var _ callbacks.Handler = &KnowledgeBaseStuffDocuments{} -func (c *KnowledgeBaseStuffDocuments) joinDocuments(docs []langchaingoschema.Document) string { +func (c *KnowledgeBaseStuffDocuments) joinDocuments(ctx context.Context, docs []langchaingoschema.Document) string { + logger := klog.FromContext(ctx) var text string docLen := len(docs) for k, doc := range docs { - klog.Infof("KnowledgeBaseRetriever: related doc[%d] raw text: %s, raw score: %f\n", k, doc.PageContent, doc.Score) + logger.V(3).Info(fmt.Sprintf("KnowledgeBaseRetriever: related doc[%d] raw text: %s, raw score: %f\n", k, doc.PageContent, doc.Score)) for key, v := range doc.Metadata { if str, ok := v.([]byte); ok { - klog.Infof("KnowledgeBaseRetriever: related doc[%d] metadata[%s]: %s\n", k, key, string(str)) + logger.V(3).Info(fmt.Sprintf("KnowledgeBaseRetriever: related doc[%d] metadata[%s]: %s\n", k, key, string(str))) } else { - klog.Infof("KnowledgeBaseRetriever: related doc[%d] metadata[%s]: %#v\n", k, key, v) + logger.V(3).Info(fmt.Sprintf("KnowledgeBaseRetriever: related doc[%d] metadata[%s]: %#v\n", k, key, v)) } } answer, _ := doc.Metadata["a"].([]byte) @@ -182,7 +183,7 @@ func (c *KnowledgeBaseStuffDocuments) joinDocuments(docs []langchaingoschema.Doc LineNumber: line, }) } - klog.Infof("KnowledgeBaseRetriever: finally get related text: %s\n", text) + logger.V(3).Info(fmt.Sprintf("KnowledgeBaseRetriever: finally get related text: %s\n", text)) if len(text) == 0 { c.isDocNullReturn = true } @@ -208,7 +209,7 @@ func (c *KnowledgeBaseStuffDocuments) Call(ctx context.Context, values map[strin inputValues[key] = value } - inputValues[c.DocumentVariableName] = c.joinDocuments(docs) + inputValues[c.DocumentVariableName] = c.joinDocuments(ctx, docs) return chains.Call(ctx, c.LLMChain, inputValues, options...) } @@ -224,10 +225,10 @@ func (c KnowledgeBaseStuffDocuments) GetOutputKeys() []string { return c.StuffDocuments.GetOutputKeys() } -func (c KnowledgeBaseStuffDocuments) HandleChainEnd(_ context.Context, outputValues map[string]any) { +func (c KnowledgeBaseStuffDocuments) HandleChainEnd(ctx context.Context, outputValues map[string]any) { if !c.isDocNullReturn { return } - klog.Infof("raw llmChain output: %s, but there is no doc return, so set output to %s\n", outputValues[c.LLMChain.OutputKey], c.DocNullReturn) + klog.FromContext(ctx).Info(fmt.Sprintf("raw llmChain output: %s, but there is no doc return, so set output to %s\n", outputValues[c.LLMChain.OutputKey], c.DocNullReturn)) outputValues[c.LLMChain.OutputKey] = c.DocNullReturn }