Remove deprecated studio package and refactor agent integration - Deleted the studio package, which is no longer in use, to streamline the codebase. - Updated references in the agent and chat modules to utilize the new agent package instead of the deprecated neo package. - Ensured that all related middleware and routing functionalities are now aligned with the agent architecture, enhancing overall system coherence.
701 lines
20 KiB
Go
701 lines
20 KiB
Go
package assistant
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
|
|
"github.com/fatih/color"
|
|
"github.com/google/uuid"
|
|
"github.com/yaoapp/gou/runtime/v8/bridge"
|
|
"github.com/yaoapp/kun/log"
|
|
chatctx "github.com/yaoapp/yao/agent/context"
|
|
chatMessage "github.com/yaoapp/yao/agent/message"
|
|
"rogchap.com/v8go"
|
|
)
|
|
|
|
// objectCall is the object for the call function
|
|
type objectCall struct{}
|
|
|
|
// OptionsCall is the options for the call function
|
|
type OptionsCall struct {
|
|
Retry OptionsCallRetry `json:"retry,omitempty"` // Retry options
|
|
Options map[string]interface{} `json:"options,omitempty"` // LLM API options
|
|
Silent bool `json:"silent,omitempty"` // Silent mode, default is true
|
|
}
|
|
|
|
// OptionsCallRetry is the retry options for the call function
|
|
type OptionsCallRetry struct {
|
|
Times int `json:"times,omitempty"` // Retry times, default is 3
|
|
Delay int `json:"delay,omitempty"` // Retry delay, default is 200
|
|
DelayMax int `json:"delay_max,omitempty"` // Retry delay max, default is 5000
|
|
Prompt string `json:"prompt,omitempty"` // Retry prompt, default is "Please fix the error. \n {{ error }}"
|
|
}
|
|
|
|
// allowedEvents is the allowed events for the call function
|
|
var allowedEvents = map[string]bool{
|
|
"done": true,
|
|
"retry": true,
|
|
"message": true,
|
|
}
|
|
|
|
var callProps = []string{
|
|
"assistant_id",
|
|
"input",
|
|
"options",
|
|
"retry_times",
|
|
}
|
|
|
|
// jsNewPlan create a plan object and return it
|
|
func jsCall(info *v8go.FunctionCallbackInfo) *v8go.Value {
|
|
|
|
args := info.Args()
|
|
if len(args) < 2 {
|
|
return bridge.JsException(info.Context(), "Run requires at least two arguments")
|
|
}
|
|
|
|
options := v8go.Undefined(info.Context().Isolate())
|
|
if len(args) > 2 {
|
|
options = args[2]
|
|
}
|
|
|
|
// Export the object
|
|
obj := &objectCall{}
|
|
objectTmpl := obj.ExportObject(info)
|
|
this, err := objectTmpl.NewInstance(info.Context())
|
|
if err != nil {
|
|
return bridge.JsException(info.Context(), err.Error())
|
|
}
|
|
|
|
// Copy global properties
|
|
global := info.This()
|
|
for _, prop := range objectProperties {
|
|
if !global.Has(prop) {
|
|
continue
|
|
}
|
|
value, err := global.Get(prop)
|
|
if err != nil {
|
|
return bridge.JsException(info.Context(), fmt.Sprintf("Failed to get property %s: %s", prop, err.Error()))
|
|
}
|
|
this.Set(prop, value)
|
|
}
|
|
|
|
this.Set("assistant_id", args[0])
|
|
this.Set("input", args[1])
|
|
this.Set("options", options)
|
|
this.Set("retry_times", int32(1))
|
|
return this.Value
|
|
}
|
|
|
|
// ExportObject Export as a FS Object
|
|
func (obj *objectCall) ExportObject(info *v8go.FunctionCallbackInfo) *v8go.ObjectTemplate {
|
|
tmpl := v8go.NewObjectTemplate(info.Context().Isolate())
|
|
tmpl.Set("On", v8go.NewFunctionTemplate(info.Context().Isolate(), obj.on)) // On the call
|
|
tmpl.Set("Run", v8go.NewFunctionTemplate(info.Context().Isolate(), obj.run)) // Run the call
|
|
return tmpl
|
|
}
|
|
|
|
// on bind the callback to the call object
|
|
func (obj *objectCall) on(info *v8go.FunctionCallbackInfo) *v8go.Value {
|
|
|
|
args := info.Args()
|
|
if len(args) < 2 {
|
|
return bridge.JsException(info.Context(), "On requires at least one argument")
|
|
}
|
|
|
|
if !args[0].IsString() {
|
|
return bridge.JsException(info.Context(), "The first argument should be a string")
|
|
}
|
|
|
|
name := args[0].String()
|
|
if !allowedEvents[name] {
|
|
return bridge.JsException(info.Context(), fmt.Sprintf("Invalid event %s", name))
|
|
}
|
|
|
|
cb := args[1]
|
|
if !cb.IsFunction() {
|
|
return bridge.JsException(info.Context(), fmt.Sprintf("The second argument should be a function for event %s", name))
|
|
}
|
|
|
|
this := info.This()
|
|
this.Set(fmt.Sprintf("on_%s", name), cb)
|
|
return this.Value
|
|
}
|
|
|
|
// run run the call
|
|
func (obj *objectCall) run(info *v8go.FunctionCallbackInfo) *v8go.Value {
|
|
|
|
this := info.This()
|
|
args := info.Args()
|
|
|
|
global, err := getGlobal(info.Context(), this)
|
|
if err != nil {
|
|
return bridge.JsException(info.Context(), err.Error())
|
|
}
|
|
|
|
goArgs := []interface{}{}
|
|
jsArgs := []v8go.Valuer{}
|
|
if len(args) > 0 {
|
|
for _, arg := range args {
|
|
v, err := bridge.GoValue(arg, info.Context())
|
|
if err != nil {
|
|
return bridge.JsException(info.Context(), err.Error())
|
|
}
|
|
goArgs = append(goArgs, v)
|
|
jsArgs = append(jsArgs, arg)
|
|
}
|
|
}
|
|
|
|
// Get the assistant id
|
|
jsAssistantID, err := this.Get("assistant_id")
|
|
if err != nil {
|
|
return bridge.JsException(info.Context(), err.Error())
|
|
}
|
|
|
|
assistantID := jsAssistantID.String()
|
|
|
|
// Get the input
|
|
jsInput, err := this.Get("input")
|
|
if err != nil {
|
|
return bridge.JsException(info.Context(), fmt.Sprintf("Failed to get the input: %s", err.Error()))
|
|
}
|
|
|
|
input, err := bridge.GoValue(jsInput, info.Context())
|
|
if err != nil {
|
|
return bridge.JsException(info.Context(), fmt.Sprintf("Failed to unmarshal the input: %s", err.Error()))
|
|
}
|
|
|
|
// Get the retry input
|
|
if this.Has("retry_input") {
|
|
|
|
jsRetryInput, err := this.Get("retry_input")
|
|
if err != nil {
|
|
return bridge.JsException(info.Context(), fmt.Sprintf("Failed to get the retry input: %s", err.Error()))
|
|
}
|
|
|
|
input, err = bridge.GoValue(jsRetryInput, info.Context())
|
|
if err != nil {
|
|
return bridge.JsException(info.Context(), fmt.Sprintf("Failed to unmarshal the retry input: %s", err.Error()))
|
|
}
|
|
}
|
|
|
|
// Options
|
|
options := OptionsCall{
|
|
// Retry: OptionsCallRetry{
|
|
// Times: 3,
|
|
// Delay: 200,
|
|
// DelayMax: 1000,
|
|
// Prompt: "{{ input }}\n**Answer is not correct, please try again.**\nError:\n{{ error }} \nAssistant's last answer:\n{{ output }}",
|
|
// },
|
|
Silent: true,
|
|
Options: map[string]interface{}{}, // LLM API options
|
|
}
|
|
|
|
// Get the options
|
|
if this.Has("options") {
|
|
jsOptions, err := this.Get("options")
|
|
if err != nil {
|
|
return bridge.JsException(info.Context(), fmt.Sprintf("Failed to get the options: %s", err.Error()))
|
|
}
|
|
|
|
// Check if the options is undefined
|
|
if !jsOptions.IsUndefined() {
|
|
err = bridge.Unmarshal(jsOptions, &options)
|
|
if err != nil {
|
|
return bridge.JsException(info.Context(), fmt.Sprintf("Failed to unmarshal the options: %s", err.Error()))
|
|
}
|
|
}
|
|
}
|
|
|
|
// Get the assistant
|
|
newAst, err := Get(assistantID)
|
|
if err != nil {
|
|
return bridge.JsException(info.Context(), fmt.Sprintf("Failed to get the assistant: %s", err.Error()))
|
|
}
|
|
|
|
// Get the message event ( it will be used for the message event )
|
|
eventMessage := ""
|
|
goCallProps := map[string]interface{}{}
|
|
if this.Has("on_message") {
|
|
jsEventMessage, err := this.Get("on_message")
|
|
if err != nil {
|
|
return bridge.JsException(info.Context(), fmt.Sprintf("Failed to get the message: %s", err.Error()))
|
|
}
|
|
eventMessage = jsEventMessage.String()
|
|
|
|
for _, prop := range callProps {
|
|
if this.Has(prop) {
|
|
value, err := this.Get(prop)
|
|
if err != nil {
|
|
return bridge.JsException(info.Context(), fmt.Sprintf("Failed to get the %s property: %s", prop, err.Error()))
|
|
}
|
|
goValue, err := bridge.GoValue(value, info.Context())
|
|
if err != nil {
|
|
return bridge.JsException(info.Context(), fmt.Sprintf("Failed to get the %s property: %s", prop, err.Error()))
|
|
}
|
|
goCallProps[prop] = goValue
|
|
}
|
|
}
|
|
}
|
|
|
|
// Update the chat context
|
|
var chatCtx chatctx.Context = global.ChatContext
|
|
chatCtx.AssistantID = assistantID
|
|
chatCtx.ChatID = fmt.Sprintf("call_%s", uuid.New().String()) // New chat id
|
|
chatCtx.Silent = options.Silent
|
|
chatCtx.ClientType = chatctx.ClientTypeAgent // Set the client type to agent
|
|
chatCtx.Args = goArgs // Arguments for call
|
|
|
|
// Define the callback function
|
|
var cb func(msg *chatMessage.Message) = nil
|
|
var output = []chatMessage.Message{}
|
|
cb = func(msg *chatMessage.Message) {
|
|
output = append(output, *msg)
|
|
if eventMessage != "" {
|
|
err := obj.triggerAnonymous(chatCtx, global, goCallProps, eventMessage, goArgs, msg)
|
|
if err != nil {
|
|
color.Red("Failed to trigger the message event: %s", err.Error())
|
|
log.Error("Failed to trigger the message event: %s", err.Error())
|
|
return
|
|
}
|
|
}
|
|
}
|
|
|
|
// Execute the assistant
|
|
result, err := newAst.Execute(global.GinContext, chatCtx, input, options.Options, cb) // Execute the assistant
|
|
if err != nil {
|
|
// result, err = obj.retry(jsArgs, err, input, output, info, options)
|
|
// if err != nil {
|
|
// return bridge.JsException(info.Context(), err.Error())
|
|
// }
|
|
return bridge.JsException(info.Context(), err.Error())
|
|
}
|
|
|
|
// Copy props
|
|
for name, value := range goCallProps {
|
|
info.Context().Global().Set(name, value)
|
|
}
|
|
|
|
// Trigger the done event
|
|
doneResult, err := obj.trigger(info, "done", jsArgs...)
|
|
if err != nil {
|
|
// result, err = obj.retry(jsArgs, err, input, output, info, options)
|
|
// if err != nil {
|
|
// return bridge.JsException(info.Context(), err.Error())
|
|
// }
|
|
return bridge.JsException(info.Context(), err.Error())
|
|
}
|
|
|
|
// Return the done result
|
|
if doneResult != nil && !doneResult.IsUndefined() {
|
|
return doneResult
|
|
}
|
|
|
|
// Return Value
|
|
switch v := result.(type) {
|
|
case *v8go.Value:
|
|
return v
|
|
case error:
|
|
return bridge.JsException(info.Context(), v.Error())
|
|
}
|
|
|
|
// Return Value
|
|
jsResult, err := bridge.JsValue(info.Context(), result)
|
|
if err != nil {
|
|
return bridge.JsException(info.Context(), fmt.Sprintf("Failed to get the result: %s", err.Error()))
|
|
}
|
|
return jsResult
|
|
}
|
|
|
|
// Deprecated this function is not used anymore
|
|
// Use the hook retry instead
|
|
// func (obj *objectCall) retry(jsArgs []v8go.Valuer, err error, input interface{}, output []chatMessage.Message, info *v8go.FunctionCallbackInfo, options OptionsCall) (*v8go.Value, error) {
|
|
|
|
// // Retry times, if not set, return the error
|
|
// if options.Retry.Times <= 0 {
|
|
// return nil, err
|
|
// }
|
|
|
|
// this := info.This()
|
|
// errmsg := exception.Trim(err)
|
|
|
|
// // Get current retry times
|
|
// jsTimes, retryErr := this.Get("retry_times")
|
|
// if retryErr != nil {
|
|
// return nil, fmt.Errorf("%s occurred but failed to get the retry times: %s", errmsg, retryErr.Error())
|
|
// }
|
|
|
|
// times := int(jsTimes.Int32())
|
|
// if times > options.Retry.Times {
|
|
// return nil, fmt.Errorf("%s occurred, max retry times reached", errmsg)
|
|
// }
|
|
|
|
// // Update the retry times
|
|
// times = times + 1
|
|
// this.Set("retry_times", int32(times))
|
|
|
|
// // Message content
|
|
// content := ""
|
|
// for _, msg := range output {
|
|
// if msg.Type == "text" && msg.IsDelta {
|
|
// content += msg.Text
|
|
// }
|
|
// }
|
|
|
|
// // Delay
|
|
// delay := options.Retry.Delay * int(times)
|
|
// if delay > options.Retry.DelayMax {
|
|
// delay = options.Retry.DelayMax
|
|
// }
|
|
|
|
// // Wait for the delay
|
|
// if delay > 0 {
|
|
// time.Sleep(time.Duration(delay) * time.Millisecond)
|
|
// }
|
|
|
|
// // Format the input
|
|
// var lastUserMessage *chatMessage.Message = nil
|
|
// var inputMessages []*chatMessage.Message = nil
|
|
// var lastUserMessageIndex int = 0
|
|
// switch v := input.(type) {
|
|
// case string:
|
|
// lastUserMessage = &chatMessage.Message{Type: "text", Text: v, Role: "user"}
|
|
// inputMessages = []*chatMessage.Message{lastUserMessage}
|
|
|
|
// case []interface{}:
|
|
// // Get the last user message
|
|
// raw, parseErr := jsoniter.Marshal(v)
|
|
// if parseErr != nil {
|
|
// return nil, fmt.Errorf("%s occurred but failed to marshal the input: %s", errmsg, parseErr.Error())
|
|
// }
|
|
|
|
// parseErr = jsoniter.Unmarshal(raw, &inputMessages)
|
|
// if parseErr != nil {
|
|
// return nil, fmt.Errorf("%s occurred but failed to unmarshal the input: %s", errmsg, parseErr.Error())
|
|
// }
|
|
|
|
// // Get the last user message
|
|
// for i := len(inputMessages) - 1; i >= 0; i-- {
|
|
// if inputMessages[i].Type == "text" && inputMessages[i].Role == "user" {
|
|
// lastUserMessage = inputMessages[i]
|
|
// lastUserMessageIndex = i
|
|
// break
|
|
// }
|
|
// }
|
|
|
|
// case *chatMessage.Message:
|
|
// lastUserMessage = v
|
|
// inputMessages = []*chatMessage.Message{lastUserMessage}
|
|
|
|
// case map[string]interface{}:
|
|
// text, ok := v["text"].(string)
|
|
// if !ok {
|
|
// return nil, fmt.Errorf("%s occurred but failed to get the text", errmsg)
|
|
// }
|
|
|
|
// if v["role"] != "user" {
|
|
// return nil, fmt.Errorf("%s occurred but the role is not user", errmsg)
|
|
// }
|
|
|
|
// lastUserMessage = &chatMessage.Message{Type: "text", Text: text, Role: "user"}
|
|
// inputMessages = []*chatMessage.Message{lastUserMessage}
|
|
// }
|
|
|
|
// // Get the prompt from the options
|
|
// promptTmpl := options.Retry.Prompt
|
|
// data := sui.Data{
|
|
// "error": errmsg,
|
|
// "output": strings.TrimSpace(content),
|
|
// "input": lastUserMessage.Text,
|
|
// }
|
|
// prompt, _ := data.Replace(promptTmpl)
|
|
|
|
// // Custom retry prompt by hooking the retry event
|
|
// if this.Has("on_retry") {
|
|
// info.Context().Global().Set("error", errmsg) // Set error
|
|
// jsDelay, _ := bridge.JsValue(info.Context(), delay)
|
|
// jsPrompt, _ := bridge.JsValue(info.Context(), prompt)
|
|
// newPrompt, retryErr := obj.trigger(info, "retry", jsTimes, jsDelay, jsPrompt)
|
|
// if retryErr != nil {
|
|
// return nil, fmt.Errorf("%s occurred but failed to trigger the retry event: %s", errmsg, retryErr.Error())
|
|
// }
|
|
// // Update the prompt
|
|
// if newPrompt.IsString() {
|
|
// prompt = newPrompt.String()
|
|
// }
|
|
// }
|
|
|
|
// // Generate the new input with the prompt
|
|
// // Update the input
|
|
// inputMessages[lastUserMessageIndex].Text = prompt
|
|
// jsInput, inputErr := bridge.JsValue(info.Context(), inputMessages)
|
|
// if inputErr != nil {
|
|
// return nil, fmt.Errorf("%s occurred but failed to update the input: %s", errmsg, inputErr.Error())
|
|
// }
|
|
// // Update the input
|
|
// this.Set("retry_input", jsInput)
|
|
|
|
// // Call the run function
|
|
// run, funcErr := this.Get("Run")
|
|
// if funcErr != nil {
|
|
// return nil, fmt.Errorf("%s occurred but failed to get the run function: %s", errmsg, funcErr.Error())
|
|
// }
|
|
|
|
// if !run.IsFunction() {
|
|
// return nil, fmt.Errorf("%s occurred but the run function is not a function", errmsg)
|
|
// }
|
|
|
|
// fn, fnErr := run.AsFunction()
|
|
// if fnErr != nil {
|
|
// return nil, fmt.Errorf("%s occurred but failed to get the run function: %s", errmsg, fnErr.Error())
|
|
// }
|
|
|
|
// result, resErr := fn.Call(this, jsArgs...)
|
|
// if resErr != nil {
|
|
// return nil, fmt.Errorf("%s (%d)", exception.Trim(resErr), times-1)
|
|
// }
|
|
|
|
// return result, nil
|
|
// }
|
|
|
|
func (obj *objectCall) triggerAnonymous(chatCtx chatctx.Context, global *GlobalVariables, goCallProps map[string]interface{}, source string, bindArgs []interface{}, fnArgs ...interface{}) error {
|
|
|
|
ctx, err := global.Assistant.Script.NewContext(global.ChatContext.Sid, nil)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer ctx.Close()
|
|
|
|
// Update Context
|
|
global.Assistant.InitObject(ctx, global.GinContext, chatCtx, global.Contents)
|
|
|
|
// Copy props
|
|
for k, v := range goCallProps {
|
|
ctx.WithGlobal(k, v)
|
|
}
|
|
|
|
// Add the args
|
|
ctx.WithGlobal("args", bindArgs)
|
|
_, err = ctx.CallAnonymousWith(context.Background(), source, fnArgs...)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
return nil
|
|
|
|
}
|
|
|
|
// trigger trigger the callback
|
|
func (obj *objectCall) trigger(info *v8go.FunctionCallbackInfo, name string, fnArgs ...v8go.Valuer) (*v8go.Value, error) {
|
|
// Try to get the callback
|
|
this := info.This()
|
|
if this.Has(fmt.Sprintf("on_%s", name)) {
|
|
event, err := this.Get(fmt.Sprintf("on_%s", name))
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if event.IsFunction() {
|
|
|
|
cb, err := event.AsFunction()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
result, err := cb.Call(this, fnArgs...)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return result, nil
|
|
}
|
|
}
|
|
|
|
return nil, nil
|
|
}
|
|
|
|
// jsCallBackup is the backup function for the call function
|
|
// func jsCallBackup(info *v8go.FunctionCallbackInfo) *v8go.Value {
|
|
|
|
// // Get the args
|
|
// args := info.Args()
|
|
// if len(args) < 2 {
|
|
// return bridge.JsException(info.Context(), "Run requires at least two arguments")
|
|
// }
|
|
|
|
// // Get the assistant id
|
|
// assistantID := args[0].String()
|
|
|
|
// // Get the assistant
|
|
// newAst, err := Get(assistantID)
|
|
// if err != nil {
|
|
// return bridge.JsException(info.Context(), err.Error())
|
|
// }
|
|
|
|
// // Get the input
|
|
// input := args[1].String()
|
|
|
|
// // Get the global variables
|
|
// global, err := global(info)
|
|
// if err != nil {
|
|
// return bridge.JsException(info.Context(), err.Error())
|
|
// }
|
|
|
|
// // Update Context
|
|
// chatContext := global.ChatContext
|
|
// chatContext.AssistantID = assistantID
|
|
// chatContext.ChatID = fmt.Sprintf("chat_%s", uuid.New().String()) // New chat id
|
|
// chatContext.Silent = true // Silent mode
|
|
|
|
// var cb func(msg *chatMessage.Message) = nil
|
|
// if len(args) > 2 {
|
|
|
|
// // Rest args
|
|
// var jsArgs *v8go.Value
|
|
// goArgs := []interface{}{}
|
|
// if len(args) > 3 {
|
|
// jsArgs = args[3]
|
|
// if jsArgs != nil {
|
|
// if jsArgs.IsArray() {
|
|
// v, err := bridge.GoValue(jsArgs, info.Context())
|
|
// if err != nil {
|
|
// return bridge.JsException(info.Context(), err.Error())
|
|
// }
|
|
// arr, ok := v.([]interface{})
|
|
// if !ok {
|
|
// return bridge.JsException(info.Context(), "Invalid arguments")
|
|
// }
|
|
// goArgs = arr
|
|
// } else {
|
|
// v, err := bridge.GoValue(jsArgs, info.Context())
|
|
// if err != nil {
|
|
// return bridge.JsException(info.Context(), err.Error())
|
|
// }
|
|
// goArgs = []interface{}{v}
|
|
// }
|
|
// }
|
|
// }
|
|
|
|
// // Parse the callback
|
|
// funcType := "method"
|
|
// name := ""
|
|
// userArgs := []interface{}{}
|
|
// if args[2].IsFunction() {
|
|
// funcType = "anonymous"
|
|
// } else {
|
|
// goValue, err := bridge.GoValue(args[2], info.Context())
|
|
// if err != nil {
|
|
// return bridge.JsException(info.Context(), err.Error())
|
|
// }
|
|
// switch v := goValue.(type) {
|
|
// case string:
|
|
// name = v
|
|
// case map[string]interface{}:
|
|
// if fname, ok := v["name"].(string); ok {
|
|
// name = fname
|
|
// }
|
|
// if args, ok := v["args"].([]interface{}); ok {
|
|
// userArgs = args
|
|
// }
|
|
// }
|
|
|
|
// if strings.Contains(name, ".") {
|
|
// funcType = "process"
|
|
// }
|
|
// }
|
|
|
|
// switch funcType {
|
|
// case "anonymous":
|
|
// source := args[2].String()
|
|
// cb = func(msg *chatMessage.Message) {
|
|
// cbArgs := []interface{}{msg}
|
|
// cbArgs = append(cbArgs, goArgs...)
|
|
// ctx, err := global.Assistant.Script.NewContext(global.ChatContext.Sid, nil)
|
|
// if err != nil {
|
|
// fmt.Println("Failed to create context", err.Error())
|
|
// return
|
|
// }
|
|
// defer ctx.Close()
|
|
|
|
// global.Assistant.InitObject(ctx, global.GinContext, chatContext, global.Contents)
|
|
// _, err = ctx.CallAnonymousWith(context.Background(), source, cbArgs...)
|
|
// if err != nil {
|
|
// log.Error("Failed to call the method: %s", err.Error())
|
|
// color.Red("Failed to call the method: %s", err.Error())
|
|
// return
|
|
// }
|
|
// }
|
|
// break
|
|
|
|
// case "process":
|
|
|
|
// cb = func(msg *chatMessage.Message) {
|
|
// cbArgs := []interface{}{}
|
|
// cbArgs = append(cbArgs, msg)
|
|
// cbArgs = append(cbArgs, userArgs...)
|
|
// p, err := process.Of(name, cbArgs...)
|
|
// if err != nil {
|
|
// log.Error("Failed to get the process: %s", err.Error())
|
|
// color.Red("Failed to get the process: %s", err.Error())
|
|
// return
|
|
// }
|
|
// err = p.Execute()
|
|
// if err != nil {
|
|
// log.Error("Failed to execute the process: %s", err.Error())
|
|
// color.Red("Failed to execute the process: %s", err.Error())
|
|
// return
|
|
// }
|
|
// defer p.Release()
|
|
// }
|
|
|
|
// case "method":
|
|
|
|
// cb = func(msg *chatMessage.Message) {
|
|
// cbArgs := []interface{}{}
|
|
// cbArgs = append(cbArgs, msg)
|
|
// cbArgs = append(cbArgs, userArgs...)
|
|
// ctx, err := global.Assistant.Script.NewContext(global.ChatContext.Sid, nil)
|
|
// if err != nil {
|
|
// return
|
|
// }
|
|
// defer ctx.Close()
|
|
|
|
// global.Assistant.InitObject(ctx, global.GinContext, global.ChatContext, global.Contents)
|
|
// _, err = ctx.CallWith(context.Background(), name, cbArgs...)
|
|
// if err != nil {
|
|
// log.Error("Failed to call the method: %s", err.Error())
|
|
// color.Red("Failed to call the method: %s", err.Error())
|
|
// return
|
|
// }
|
|
// }
|
|
// }
|
|
|
|
// }
|
|
|
|
// // Parse the options
|
|
// options := map[string]interface{}{}
|
|
// if len(args) > 4 {
|
|
// optionsRaw, err := bridge.GoValue(args[4], info.Context())
|
|
// if err != nil {
|
|
// return bridge.JsException(info.Context(), err.Error())
|
|
// }
|
|
|
|
// // Parse the options
|
|
// if optionsRaw != nil {
|
|
// switch v := optionsRaw.(type) {
|
|
// case string:
|
|
// err := jsoniter.UnmarshalFromString(v, &options)
|
|
// if err != nil {
|
|
// return bridge.JsException(info.Context(), err.Error())
|
|
// }
|
|
// case map[string]interface{}:
|
|
// options = v
|
|
// default:
|
|
// return bridge.JsException(info.Context(), "Invalid options")
|
|
// }
|
|
// }
|
|
// }
|
|
|
|
// err = newAst.Execute(global.GinContext, chatContext, input, options, cb) // Execute the assistant
|
|
// if err != nil {
|
|
// return bridge.JsException(info.Context(), err.Error())
|
|
// }
|
|
// return nil
|
|
// }
|