From 5475e0ab39f3dcdaddc7818cba3c7e37228cfa13 Mon Sep 17 00:00:00 2001 From: Max Date: Tue, 25 Feb 2025 11:27:04 +0800 Subject: [PATCH] Add Assets method to assistant for retrieving and processing asset files - Implement Assets method in Assistant struct to read asset files - Add jsAssets function to JavaScript bridge for accessing assets - Support optional data replacement in asset file content - Enable dynamic asset retrieval with optional template data processing --- neo/assistant/api.go | 18 ++++++++------- neo/assistant/assistant.go | 25 +++++++++++++++++++++ neo/assistant/object.go | 45 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 80 insertions(+), 8 deletions(-) diff --git a/neo/assistant/api.go b/neo/assistant/api.go index 6222f1ba..2e183f44 100644 --- a/neo/assistant/api.go +++ b/neo/assistant/api.go @@ -242,14 +242,16 @@ func (next *NextAction) Execute(c *gin.Context, ctx chatctx.Context, contents *c // Create a new Text // Send loading message and mark as new - msg := chatMessage.New().Map(map[string]interface{}{ - "new": true, - "role": "assistant", - "type": "loading", - "props": map[string]interface{}{"placeholder": "Calling " + assistant.Name}, - }) - msg.Assistant(assistant.ID, assistant.Name, assistant.Avatar) - msg.Write(c.Writer) + if !ctx.Silent { + msg := chatMessage.New().Map(map[string]interface{}{ + "new": true, + "role": "assistant", + "type": "loading", + "props": map[string]interface{}{"placeholder": "Calling " + assistant.Name}, + }) + msg.Assistant(assistant.ID, assistant.Name, assistant.Avatar) + msg.Write(c.Writer) + } newContents := chatMessage.NewContents() // Update the context id diff --git a/neo/assistant/assistant.go b/neo/assistant/assistant.go index e320f91e..7af06d0b 100644 --- a/neo/assistant/assistant.go +++ b/neo/assistant/assistant.go @@ -3,12 +3,15 @@ package assistant import ( "context" "fmt" + "path" "time" "github.com/fatih/color" jsoniter "github.com/json-iterator/go" + "github.com/yaoapp/gou/fs" "github.com/yaoapp/gou/rag/driver" "github.com/yaoapp/kun/log" + sui "github.com/yaoapp/yao/sui/core" ) // Save save the assistant @@ -156,6 +159,28 @@ func (ast *Assistant) Validate() error { return nil } +// Assets get the assets content +func (ast *Assistant) Assets(name string, data sui.Data) (string, error) { + + app, err := fs.Get("app") + if err != nil { + return "", err + } + + root := path.Join(ast.Path, "assets", name) + raw, err := app.ReadFile(root) + if err != nil { + return "", err + } + + if data != nil { + content, _ := data.Replace(string(raw)) + return content, nil + } + + return string(raw), nil +} + // Clone creates a deep copy of the assistant func (ast *Assistant) Clone() *Assistant { if ast == nil { diff --git a/neo/assistant/object.go b/neo/assistant/object.go index ef18de3e..af1eb9fc 100644 --- a/neo/assistant/object.go +++ b/neo/assistant/object.go @@ -51,6 +51,51 @@ func (ast *Assistant) InitObject(v8ctx *v8.Context, c *gin.Context, context chat v8ctx.WithFunction("Plan", jsPlan) // Create a new plan object v8ctx.WithFunction("Send", jsSend) v8ctx.WithFunction("Call", jsCall) + v8ctx.WithFunction("Assets", jsAssets) +} + +// jsAssets function, get the assets content +func jsAssets(info *v8go.FunctionCallbackInfo) *v8go.Value { + + global, err := global(info) + if err != nil { + return bridge.JsException(info.Context(), err.Error()) + } + + // Get the message + args := info.Args() + if len(args) < 1 { + return bridge.JsException(info.Context(), "Assets requires at least one argument") + } + + // Get the name + name := args[0].String() + + data := map[string]interface{}{} + if len(args) > 1 { + raw, err := bridge.GoValue(args[1], info.Context()) + if err != nil { + return bridge.JsException(info.Context(), err.Error()) + } + + v, ok := raw.(map[string]interface{}) + if !ok { + return bridge.JsException(info.Context(), "Assets requires a map") + } + data = v + } + + content, err := global.Assistant.Assets(name, data) + if err != nil { + return bridge.JsException(info.Context(), err.Error()) + } + + jsContent, err := bridge.JsValue(info.Context(), content) + if err != nil { + return bridge.JsException(info.Context(), err.Error()) + } + + return jsContent } // jsSend function, send a message to the http stream connection