some update for llm、util

This commit is contained in:
Star 2024-09-23 18:15:02 +08:00
parent e690ae764b
commit 5faf209709
13 changed files with 251 additions and 110 deletions

View File

@ -79,6 +79,7 @@ function main(...args) {
result, err := rt.RunMain(args...) result, err := rt.RunMain(args...)
if err != nil { if err != nil {
fmt.Println(u.BRed(err.Error())) fmt.Println(u.BRed(err.Error()))
fmt.Println(u.Red(" " + strings.Join(rt.GetCallStack(), "\n ")))
} else if result != nil { } else if result != nil {
fmt.Println(u.Cyan(u.JsonP(result))) fmt.Println(u.Cyan(u.JsonP(result)))
} }

View File

@ -575,7 +575,25 @@ func (f *nativeFuncObject) vmCall(vm *vm, n int) {
//vm.throw(Exception{ //vm.throw(Exception{
// val: ret.toString(), // val: ret.toString(),
//}) //})
vm.throw(ret) //stack := make([]StackFrame, 0)
//for i := len(vm.callStack) - 1; i >= 0; i-- {
// frame := &vm.callStack[i]
// if frame.prg != nil || frame.sb > 0 {
// var funcName unistring.String
// if prg := frame.prg; prg != nil {
// funcName = prg.funcName
// } else {
// funcName = getFuncName(vm.stack, frame.sb)
// }
// stack = append(stack, StackFrame{prg: vm.callStack[i].prg, pc: frame.pc, funcName: funcName})
// //prg := vm.callStack[i].prg
// //stack = append(stack, string(funcName)+" "+prg.src.Position(prg.sourceOffset(frame.pc)).String())
// }
//}
vm.throw(&Exception{
val: ret.ToString(),
})
return
} else { } else {
vm.stack[vm.sp-n-2] = ret vm.stack[vm.sp-n-2] = ret
vm.popCtx() vm.popCtx()

View File

@ -201,6 +201,8 @@ type Runtime struct {
promiseRejectionTracker PromiseRejectionTracker promiseRejectionTracker PromiseRejectionTracker
asyncContextTracker AsyncContextTracker asyncContextTracker AsyncContextTracker
GoData map[string]any
} }
type StackFrame struct { type StackFrame struct {

33
js.go
View File

@ -64,6 +64,14 @@ func (rt *Runtime) SetModuleLoader(fn func(filename string) string) {
rt.moduleLoader = fn rt.moduleLoader = fn
} }
func (rt *Runtime) GetCallStack() []string {
callStacks := make([]string, 0)
for _, stack := range rt.vm.CaptureCallStack(0, nil) {
callStacks = append(callStacks, stack.Position().String())
}
return callStacks
}
func (rt *Runtime) requireMod(name string) error { func (rt *Runtime) requireMod(name string) error {
var err error var err error
if name == "console" || name == "" { if name == "console" || name == "" {
@ -130,8 +138,10 @@ func (rt *Runtime) makeImport(matcher *regexp.Regexp, code string) (string, int,
} }
func New() *Runtime { func New() *Runtime {
vm := goja.New()
vm.GoData = map[string]any{}
return &Runtime{ return &Runtime{
vm: goja.New(), vm: vm,
required: map[string]bool{}, required: map[string]bool{},
} }
} }
@ -151,8 +161,10 @@ func (rt *Runtime) StartFromCode(code, refFile string) (any, error) {
if absFile, err := filepath.Abs(rt.file); err == nil { if absFile, err := filepath.Abs(rt.file); err == nil {
rt.file = absFile rt.file = absFile
} }
refPath := filepath.Dir(refFile)
rt.vm.GoData["startPath"] = refPath
InitFrom(filepath.Dir(refFile)) InitFrom(refPath)
if rt.srcCode == "" { if rt.srcCode == "" {
rt.srcCode = code rt.srcCode = code
@ -184,17 +196,20 @@ func (rt *Runtime) StartFromCode(code, refFile string) (any, error) {
// 处理模块引用 // 处理模块引用
require.NewRegistryWithLoader(func(path string) ([]byte, error) { require.NewRegistryWithLoader(func(path string) ([]byte, error) {
refPath := filepath.Join(filepath.Dir(rt.file), path) modFile := path
if !strings.HasSuffix(refPath, ".js") && !u.FileExists(refPath) { if !filepath.IsAbs(modFile) {
refPath += ".js" modFile = filepath.Join(filepath.Dir(rt.file), modFile)
}
if !strings.HasSuffix(modFile, ".js") && !u.FileExists(modFile) {
modFile += ".js"
} }
modCode := "" modCode := ""
if rt.moduleLoader != nil { if rt.moduleLoader != nil {
modCode = rt.moduleLoader(refPath) modCode = rt.moduleLoader(modFile)
} }
if modCode == "" { if modCode == "" {
var err error var err error
modCode, err = u.ReadFile(refPath) modCode, err = u.ReadFile(modFile)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -208,7 +223,7 @@ func (rt *Runtime) StartFromCode(code, refFile string) (any, error) {
if !checkMainMatcher.MatchString(rt.code) { if !checkMainMatcher.MatchString(rt.code) {
rt.code = "function main(...args){" + rt.code + "}" rt.code = "function main(...args){" + rt.code + "}"
} }
if r, err := rt.vm.RunScript("main", rt.code); err != nil { if r, err := rt.vm.RunScript(rt.file, rt.code); err != nil {
return nil, err return nil, err
} else { } else {
return r, nil return r, nil
@ -229,7 +244,7 @@ func (rt *Runtime) RunMain(args ...any) (any, error) {
if err := rt.vm.Set("__args", args); err != nil { if err := rt.vm.Set("__args", args); err != nil {
return nil, err return nil, err
} }
jsResult, err := rt.vm.RunScript(rt.file, "main(...__args)") jsResult, err := rt.vm.RunScript("main", "main(...__args)")
var result any var result any
if err == nil { if err == nil {

View File

@ -4,6 +4,7 @@ import (
"errors" "errors"
"github.com/dop251/goja" "github.com/dop251/goja"
"github.com/ssgo/u" "github.com/ssgo/u"
"path/filepath"
) )
func toMap(data any) map[string]any { func toMap(data any) map[string]any {
@ -82,3 +83,19 @@ func (args *Args) Map2StrArr(index int) []string {
} }
return headers return headers
} }
func findPath(vm *goja.Runtime, filename string) string {
if u.FileExists(filename) {
return filename
}
if !filepath.IsAbs(filename) {
startPath := u.String(vm.GoData["startPath"])
if startPath != "" {
tryFilename := filepath.Join(startPath, filename)
if u.FileExists(tryFilename) {
return tryFilename
}
}
}
return filename
}

View File

@ -2,7 +2,6 @@ package js
import ( import (
"errors" "errors"
"fmt"
"github.com/dop251/goja" "github.com/dop251/goja"
"github.com/ssgo/u" "github.com/ssgo/u"
) )
@ -13,18 +12,17 @@ func RequireFile() map[string]any {
if len(args.Arguments) < 1 { if len(args.Arguments) < 1 {
return vm.NewGoError(errors.New("arguments need 1, but given " + u.String(len(args.Arguments)))) return vm.NewGoError(errors.New("arguments need 1, but given " + u.String(len(args.Arguments))))
} }
if r, err := u.ReadFile(u.String(args.Arguments[0].Export())); err == nil { if r, err := u.ReadFile(findPath(vm, u.String(args.Arguments[0].Export()))); err == nil {
return vm.ToValue(r) return vm.ToValue(r)
} else { } else {
fmt.Println(err, "-----") panic(vm.NewGoError(err))
return vm.NewGoError(err)
} }
}, },
"write": func(args goja.FunctionCall, vm *goja.Runtime) goja.Value { "write": func(args goja.FunctionCall, vm *goja.Runtime) goja.Value {
if len(args.Arguments) < 2 { if len(args.Arguments) < 2 {
return vm.NewGoError(errors.New("arguments need 2, but given " + u.String(len(args.Arguments)))) return vm.NewGoError(errors.New("arguments need 2, but given " + u.String(len(args.Arguments))))
} }
if err := u.WriteFileBytes(u.String(args.Arguments[0].Export()), u.Bytes(args.Arguments[0].Export())); err == nil { if err := u.WriteFileBytes(findPath(vm, u.String(args.Arguments[0].Export())), u.Bytes(args.Arguments[0].Export())); err == nil {
return nil return nil
} else { } else {
return vm.NewGoError(err) return vm.NewGoError(err)
@ -34,7 +32,7 @@ func RequireFile() map[string]any {
if len(args.Arguments) < 1 { if len(args.Arguments) < 1 {
return vm.NewGoError(errors.New("arguments need 1, but given " + u.String(len(args.Arguments)))) return vm.NewGoError(errors.New("arguments need 1, but given " + u.String(len(args.Arguments))))
} }
if r, err := u.ReadDir(u.String(args.Arguments[0].Export())); err == nil { if r, err := u.ReadDir(findPath(vm, u.String(args.Arguments[0].Export()))); err == nil {
return vm.ToValue(r) return vm.ToValue(r)
} else { } else {
return vm.NewGoError(err) return vm.NewGoError(err)
@ -44,7 +42,13 @@ func RequireFile() map[string]any {
if len(args.Arguments) < 1 { if len(args.Arguments) < 1 {
return vm.NewGoError(errors.New("arguments need 1, but given " + u.String(len(args.Arguments)))) return vm.NewGoError(errors.New("arguments need 1, but given " + u.String(len(args.Arguments))))
} }
return vm.ToValue(u.GetFileInfo(u.String(args.Arguments[0].Export()))) return vm.ToValue(u.GetFileInfo(findPath(vm, u.String(args.Arguments[0].Export()))))
},
"find": func(args goja.FunctionCall, vm *goja.Runtime) goja.Value {
if len(args.Arguments) < 1 {
return vm.NewGoError(errors.New("arguments need 1, but given " + u.String(len(args.Arguments))))
}
return vm.ToValue(findPath(vm, u.String(args.Arguments[0].Export())))
}, },
} }
} }

View File

@ -123,26 +123,34 @@ func (hc *Http) Do(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
func (hc *Http) Upload(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value { func (hc *Http) Upload(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
args := MakeArgs(&argsIn, vm) args := MakeArgs(&argsIn, vm)
if err := args.Check(3); err != nil { if err := args.Check(2); err != nil {
return err return err
} }
postData := map[string]string{} postData := map[string]string{}
postFiles := map[string]any{} postFiles := map[string]any{}
u.Convert(args.Any(1), &postData) u.Convert(args.Any(1), &postData)
if len(argsIn.Arguments) > 2 {
u.Convert(args.Any(2), &postFiles) u.Convert(args.Any(2), &postFiles)
}
r, _ := hc.client.MPost(args.Str(0), postData, postFiles, args.Map2StrArr(3)...) r, _ := hc.client.MPost(args.Str(0), postData, postFiles, args.Map2StrArr(3)...)
return makeResult(r, vm) return makeResult(r, vm)
} }
func (hc *Http) Download(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value { func (hc *Http) Download(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
args := MakeArgs(&argsIn, vm) args := MakeArgs(&argsIn, vm)
if err := args.Check(3); err != nil { if err := args.Check(2); err != nil {
return err return err
} }
var r *httpclient.Result var r *httpclient.Result
if cb, ok := goja.AssertFunction(argsIn.Arguments[3]); ok { var callback goja.Callable
if len(argsIn.Arguments) > 2 {
if cb, ok := goja.AssertFunction(argsIn.Arguments[2]); ok {
callback = cb
}
}
if callback != nil {
r, _ = hc.client.Download(args.Str(0), args.Str(1), func(start, end int64, ok bool, finished, total int64) { r, _ = hc.client.Download(args.Str(0), args.Str(1), func(start, end int64, ok bool, finished, total int64) {
_, _ = cb(argsIn.This, vm.ToValue(finished), vm.ToValue(total)) _, _ = callback(argsIn.This, vm.ToValue(finished), vm.ToValue(total))
}, args.Map2StrArr(3)...) }, args.Map2StrArr(3)...)
} else { } else {
r, _ = hc.client.Download(args.Str(0), args.Str(1), nil, args.Map2StrArr(3)...) r, _ = hc.client.Download(args.Str(0), args.Str(1), nil, args.Map2StrArr(3)...)

View File

@ -11,6 +11,7 @@ function read(filename: string): string {return ''}
function write(filename: string, data: any): void {} function write(filename: string, data: any): void {}
function dir(filename: string): Array<FileInfo> {return null} function dir(filename: string): Array<FileInfo> {return null}
function stat(filename: string): FileInfo {return null} function stat(filename: string): FileInfo {return null}
function find(filename: string): string {return ''}
interface FileInfo { interface FileInfo {
Name: string Name: string

View File

@ -49,5 +49,5 @@ function md5(data:any): string {return ''}
function sha1(data:any): string {return ''} function sha1(data:any): string {return ''}
function sha256(data:any): string {return ''} function sha256(data:any): string {return ''}
function sha512(data:any): string {return ''} function sha512(data:any): string {return ''}
function tpl(text:string, data:any): string {return ''} function tpl(text:string, data:any, functions?:Object): string {return ''}
function shell(cmd:string, ...args:string[]): string[] {return []} function shell(cmd:string, ...args:string[]): string[] {return []}

View File

@ -4,7 +4,6 @@ import (
"bytes" "bytes"
"encoding/hex" "encoding/hex"
"encoding/json" "encoding/json"
"errors"
"github.com/dop251/goja" "github.com/dop251/goja"
"github.com/ssgo/u" "github.com/ssgo/u"
"gopkg.in/yaml.v3" "gopkg.in/yaml.v3"
@ -13,20 +12,24 @@ import (
func RequireUtil() map[string]any { func RequireUtil() map[string]any {
return map[string]any{ return map[string]any{
"json": func(args goja.FunctionCall, vm *goja.Runtime) goja.Value { "json": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
if len(args.Arguments) < 1 { args := MakeArgs(&argsIn, vm)
return vm.NewGoError(errors.New("arguments need 1, but given " + u.String(len(args.Arguments)))) if err := args.Check(1); err != nil {
return err
} }
if r, err := json.Marshal(args.Arguments[0].Export()); err == nil { if r, err := json.Marshal(args.Arguments[0].Export()); err == nil {
return vm.ToValue(string(r)) return vm.ToValue(string(r))
} else { } else {
return vm.NewGoError(err) return vm.NewGoError(err)
} }
}, },
"jsonP": func(args goja.FunctionCall, vm *goja.Runtime) goja.Value { "jsonP": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
if len(args.Arguments) < 1 { args := MakeArgs(&argsIn, vm)
return vm.NewGoError(errors.New("arguments need 1, but given " + u.String(len(args.Arguments)))) if err := args.Check(1); err != nil {
return err
} }
if r, err := json.Marshal(args.Arguments[0].Export()); err == nil { if r, err := json.Marshal(args.Arguments[0].Export()); err == nil {
r1 := bytes.Buffer{} r1 := bytes.Buffer{}
if err2 := json.Indent(&r1, r, "", " "); err2 == nil { if err2 := json.Indent(&r1, r, "", " "); err2 == nil {
@ -38,10 +41,12 @@ func RequireUtil() map[string]any {
return vm.NewGoError(err) return vm.NewGoError(err)
} }
}, },
"unJson": func(args goja.FunctionCall, vm *goja.Runtime) goja.Value { "unJson": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
if len(args.Arguments) < 1 { args := MakeArgs(&argsIn, vm)
return vm.NewGoError(errors.New("arguments need 1, but given " + u.String(len(args.Arguments)))) if err := args.Check(1); err != nil {
return err
} }
var r any var r any
if err := json.Unmarshal(u.Bytes(args.Arguments[0].Export()), &r); err == nil { if err := json.Unmarshal(u.Bytes(args.Arguments[0].Export()), &r); err == nil {
return vm.ToValue(r) return vm.ToValue(r)
@ -49,20 +54,24 @@ func RequireUtil() map[string]any {
return vm.NewGoError(err) return vm.NewGoError(err)
} }
}, },
"yaml": func(args goja.FunctionCall, vm *goja.Runtime) goja.Value { "yaml": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
if len(args.Arguments) < 1 { args := MakeArgs(&argsIn, vm)
return vm.NewGoError(errors.New("arguments need 1, but given " + u.String(len(args.Arguments)))) if err := args.Check(1); err != nil {
return err
} }
if r, err := yaml.Marshal(args.Arguments[0].Export()); err == nil { if r, err := yaml.Marshal(args.Arguments[0].Export()); err == nil {
return vm.ToValue(string(r)) return vm.ToValue(string(r))
} else { } else {
return vm.NewGoError(err) return vm.NewGoError(err)
} }
}, },
"unYaml": func(args goja.FunctionCall, vm *goja.Runtime) goja.Value { "unYaml": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
if len(args.Arguments) < 1 { args := MakeArgs(&argsIn, vm)
return vm.NewGoError(errors.New("arguments need 1, but given " + u.String(len(args.Arguments)))) if err := args.Check(1); err != nil {
return err
} }
var r any var r any
if err := yaml.Unmarshal(u.Bytes(args.Arguments[0].Export()), &r); err == nil { if err := yaml.Unmarshal(u.Bytes(args.Arguments[0].Export()), &r); err == nil {
return vm.ToValue(r) return vm.ToValue(r)
@ -70,131 +79,180 @@ func RequireUtil() map[string]any {
return vm.NewGoError(err) return vm.NewGoError(err)
} }
}, },
"base64": func(args goja.FunctionCall, vm *goja.Runtime) goja.Value { "base64": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
if len(args.Arguments) < 1 { args := MakeArgs(&argsIn, vm)
return vm.NewGoError(errors.New("arguments need 1, but given " + u.String(len(args.Arguments)))) if err := args.Check(1); err != nil {
return err
} }
return vm.ToValue(u.Base64(u.Bytes(args.Arguments[0].Export()))) return vm.ToValue(u.Base64(u.Bytes(args.Arguments[0].Export())))
}, },
"unBase64": func(args goja.FunctionCall, vm *goja.Runtime) goja.Value { "unBase64": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
if len(args.Arguments) < 1 { args := MakeArgs(&argsIn, vm)
return vm.NewGoError(errors.New("arguments need 1, but given " + u.String(len(args.Arguments)))) if err := args.Check(1); err != nil {
return err
} }
return vm.ToValue(u.UnBase64String(u.String(args.Arguments[0].Export())))
return vm.ToValue(u.UnBase64String(args.Str(0)))
}, },
"urlBase64": func(args goja.FunctionCall, vm *goja.Runtime) goja.Value { "urlBase64": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
if len(args.Arguments) < 1 { args := MakeArgs(&argsIn, vm)
return vm.NewGoError(errors.New("arguments need 1, but given " + u.String(len(args.Arguments)))) if err := args.Check(1); err != nil {
return err
} }
return vm.ToValue(u.UrlBase64String(u.String(args.Arguments[0].Export())))
return vm.ToValue(u.UrlBase64String(args.Str(0)))
}, },
"unUrlBase64": func(args goja.FunctionCall, vm *goja.Runtime) goja.Value { "unUrlBase64": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
if len(args.Arguments) < 1 { args := MakeArgs(&argsIn, vm)
return vm.NewGoError(errors.New("arguments need 1, but given " + u.String(len(args.Arguments)))) if err := args.Check(1); err != nil {
return err
} }
return vm.ToValue(u.UnUrlBase64String(u.String(args.Arguments[0].Export())))
return vm.ToValue(u.UnUrlBase64String(args.Str(0)))
}, },
"hex": func(args goja.FunctionCall, vm *goja.Runtime) goja.Value { "hex": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
if len(args.Arguments) < 1 { args := MakeArgs(&argsIn, vm)
return vm.NewGoError(errors.New("arguments need 1, but given " + u.String(len(args.Arguments)))) if err := args.Check(1); err != nil {
return err
} }
return vm.ToValue(hex.EncodeToString(u.Bytes(args.Arguments[0].Export()))) return vm.ToValue(hex.EncodeToString(u.Bytes(args.Arguments[0].Export())))
}, },
"unHex": func(args goja.FunctionCall, vm *goja.Runtime) goja.Value { "unHex": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
if len(args.Arguments) < 1 { args := MakeArgs(&argsIn, vm)
return vm.NewGoError(errors.New("arguments need 1, but given " + u.String(len(args.Arguments)))) if err := args.Check(1); err != nil {
return err
} }
if r, err := hex.DecodeString(u.String(args.Arguments[0].Export())); err == nil {
if r, err := hex.DecodeString(args.Str(0)); err == nil {
return vm.ToValue(string(r)) return vm.ToValue(string(r))
} else { } else {
return vm.NewGoError(err) return vm.NewGoError(err)
} }
}, },
"aes": func(args goja.FunctionCall, vm *goja.Runtime) goja.Value { "aes": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
if len(args.Arguments) < 3 { args := MakeArgs(&argsIn, vm)
return vm.NewGoError(errors.New("arguments need 3, but given " + u.String(len(args.Arguments)))) if err := args.Check(3); err != nil {
return err
} }
if r, err := u.EncryptAesBytes(u.Bytes(args.Arguments[0].Export()), u.Bytes(args.Arguments[1].Export()), u.Bytes(args.Arguments[2].Export())); err == nil { if r, err := u.EncryptAesBytes(u.Bytes(args.Arguments[0].Export()), u.Bytes(args.Arguments[1].Export()), u.Bytes(args.Arguments[2].Export())); err == nil {
return vm.ToValue(string(r)) return vm.ToValue(string(r))
} else { } else {
return vm.NewGoError(err) return vm.NewGoError(err)
} }
}, },
"unAes": func(args goja.FunctionCall, vm *goja.Runtime) goja.Value { "unAes": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
if len(args.Arguments) < 3 { args := MakeArgs(&argsIn, vm)
return vm.NewGoError(errors.New("arguments need 3, but given " + u.String(len(args.Arguments)))) if err := args.Check(3); err != nil {
return err
} }
if r, err := u.DecryptAesBytes(u.Bytes(args.Arguments[0].Export()), u.Bytes(args.Arguments[1].Export()), u.Bytes(args.Arguments[2].Export())); err == nil { if r, err := u.DecryptAesBytes(u.Bytes(args.Arguments[0].Export()), u.Bytes(args.Arguments[1].Export()), u.Bytes(args.Arguments[2].Export())); err == nil {
return vm.ToValue(string(r)) return vm.ToValue(string(r))
} else { } else {
return vm.NewGoError(err) return vm.NewGoError(err)
} }
}, },
"gzip": func(args goja.FunctionCall, vm *goja.Runtime) goja.Value { "gzip": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
if len(args.Arguments) < 1 { args := MakeArgs(&argsIn, vm)
return vm.NewGoError(errors.New("arguments need 1, but given " + u.String(len(args.Arguments)))) if err := args.Check(1); err != nil {
return err
} }
if r, err := u.Gzip(u.Bytes(args.Arguments[0].Export())); err == nil { if r, err := u.Gzip(u.Bytes(args.Arguments[0].Export())); err == nil {
return vm.ToValue(string(r)) return vm.ToValue(string(r))
} else { } else {
return vm.NewGoError(err) return vm.NewGoError(err)
} }
}, },
"gunzip": func(args goja.FunctionCall, vm *goja.Runtime) goja.Value { "gunzip": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
if len(args.Arguments) < 1 { args := MakeArgs(&argsIn, vm)
return vm.NewGoError(errors.New("arguments need 1, but given " + u.String(len(args.Arguments)))) if err := args.Check(1); err != nil {
return err
} }
if r, err := u.Gunzip(u.Bytes(args.Arguments[0].Export())); err == nil { if r, err := u.Gunzip(u.Bytes(args.Arguments[0].Export())); err == nil {
return vm.ToValue(string(r)) return vm.ToValue(string(r))
} else { } else {
return vm.NewGoError(err) return vm.NewGoError(err)
} }
}, },
"id": func(args goja.FunctionCall, vm *goja.Runtime) goja.Value { "id": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
return vm.ToValue(u.Id12()) return vm.ToValue(u.Id12())
}, },
"uniqueId": func(args goja.FunctionCall, vm *goja.Runtime) goja.Value { "uniqueId": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
return vm.ToValue(u.UniqueId()) return vm.ToValue(u.UniqueId())
}, },
"token": func(args goja.FunctionCall, vm *goja.Runtime) goja.Value { "token": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
size := 20 size := 20
if len(args.Arguments) > 0 { if len(argsIn.Arguments) > 0 {
size = u.Int(args.Arguments[0].Export()) size = u.Int(argsIn.Arguments[0].Export())
} }
return vm.ToValue(u.MakeToken(size)) return vm.ToValue(u.MakeToken(size))
}, },
"md5": func(args goja.FunctionCall, vm *goja.Runtime) goja.Value { "md5": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
if len(args.Arguments) < 1 { args := MakeArgs(&argsIn, vm)
return vm.NewGoError(errors.New("arguments need 1, but given " + u.String(len(args.Arguments)))) if err := args.Check(1); err != nil {
return err
} }
return vm.ToValue(u.MD5(u.Bytes(args.Arguments[0].Export()))) return vm.ToValue(u.MD5(u.Bytes(args.Arguments[0].Export())))
}, },
"sha1": func(args goja.FunctionCall, vm *goja.Runtime) goja.Value { "sha1": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
if len(args.Arguments) < 1 { args := MakeArgs(&argsIn, vm)
return vm.NewGoError(errors.New("arguments need 1, but given " + u.String(len(args.Arguments)))) if err := args.Check(1); err != nil {
return err
} }
return vm.ToValue(u.Sha1(u.Bytes(args.Arguments[0].Export()))) return vm.ToValue(u.Sha1(u.Bytes(args.Arguments[0].Export())))
}, },
"sha256": func(args goja.FunctionCall, vm *goja.Runtime) goja.Value { "sha256": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
if len(args.Arguments) < 1 { args := MakeArgs(&argsIn, vm)
return vm.NewGoError(errors.New("arguments need 1, but given " + u.String(len(args.Arguments)))) if err := args.Check(1); err != nil {
return err
} }
return vm.ToValue(u.Sha256(u.Bytes(args.Arguments[0].Export()))) return vm.ToValue(u.Sha256(u.Bytes(args.Arguments[0].Export())))
}, },
"sha512": func(args goja.FunctionCall, vm *goja.Runtime) goja.Value { "sha512": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
if len(args.Arguments) < 1 { args := MakeArgs(&argsIn, vm)
return vm.NewGoError(errors.New("arguments need 1, but given " + u.String(len(args.Arguments)))) if err := args.Check(1); err != nil {
return err
} }
return vm.ToValue(u.Sha512(u.Bytes(args.Arguments[0].Export()))) return vm.ToValue(u.Sha512(u.Bytes(args.Arguments[0].Export())))
}, },
"tpl": func(args goja.FunctionCall, vm *goja.Runtime) goja.Value { "tpl": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
if len(args.Arguments) < 2 { args := MakeArgs(&argsIn, vm)
return vm.NewGoError(errors.New("arguments need 2, but given " + u.String(len(args.Arguments)))) if err := args.Check(2); err != nil {
return err
} }
var tpl *template.Template
var functions = map[string]any{}
if len(argsIn.Arguments) > 2 {
obj := argsIn.Arguments[2].ToObject(vm)
for _, k := range obj.Keys() {
v := obj.Get(k)
if cb, ok := goja.AssertFunction(v); ok {
functions[k] = func(in string) string {
if r, err := cb(argsIn.This, vm.ToValue(in)); err == nil {
return r.String()
}
return ""
}
}
}
}
buf := bytes.NewBuffer(make([]byte, 0)) buf := bytes.NewBuffer(make([]byte, 0))
var err error var err error
if tpl, err = template.New("tpl").Parse(u.String(args.Arguments[0].Export())); err == nil { tpl := template.New("tpl")
if len(functions) > 0 {
tpl.Funcs(functions)
}
if tpl, err = tpl.Parse(args.Str(0)); err == nil {
err = tpl.Execute(buf, args.Arguments[1].Export()) err = tpl.Execute(buf, args.Arguments[1].Export())
} }
if err != nil { if err != nil {
@ -202,16 +260,18 @@ func RequireUtil() map[string]any {
} }
return vm.ToValue(buf.String()) return vm.ToValue(buf.String())
}, },
"shell": func(args goja.FunctionCall, vm *goja.Runtime) goja.Value { "shell": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
if len(args.Arguments) < 1 { args := MakeArgs(&argsIn, vm)
return vm.NewGoError(errors.New("arguments need 1 or more, but given " + u.String(len(args.Arguments)))) if err := args.Check(1); err != nil {
} return err
a := make([]string, len(args.Arguments)-1)
for i := 1; i < len(args.Arguments); i++ {
a[i-1] = u.String(args.Arguments[i].Export())
} }
if r, err := u.RunCommand(u.String(args.Arguments[0].Export()), a...); err == nil { a := make([]string, len(args.Arguments)-1)
for i := 1; i < len(args.Arguments); i++ {
a[i-1] = args.Str(i)
}
if r, err := u.RunCommand(args.Str(0), a...); err == nil {
return vm.ToValue(r) return vm.ToValue(r)
} else { } else {
return vm.NewGoError(err) return vm.NewGoError(err)

View File

@ -30,6 +30,7 @@ type Config struct {
ApiKey string ApiKey string
ChatConfig ChatConfig ChatConfig ChatConfig
GCConfig GCConfig GCConfig GCConfig
Debug bool
} }
type LLM interface { type LLM interface {

View File

@ -86,11 +86,18 @@ func (lm *LLM) Ask(messages []llm.ChatMessage, config llm.ChatConfig, callback f
contents[j] = part contents[j] = part
} }
} }
if len(contents) == 1 && contents[0].Type == llm.TypeText {
agentMessages[i] = openai.ChatCompletionMessage{
Role: RoleMap[msg.Role],
Content: contents[0].Text,
}
} else {
agentMessages[i] = openai.ChatCompletionMessage{ agentMessages[i] = openai.ChatCompletionMessage{
Role: RoleMap[msg.Role], Role: RoleMap[msg.Role],
MultiContent: contents, MultiContent: contents,
} }
} }
}
opt := openai.ChatCompletionRequest{ opt := openai.ChatCompletionRequest{
Model: config.GetModel(), Model: config.GetModel(),

View File

@ -83,11 +83,18 @@ func (lm *LLM) Ask(messages []llm.ChatMessage, config llm.ChatConfig, callback f
contents[j] = part contents[j] = part
} }
} }
if len(contents) == 1 && contents[0].Type == llm.TypeText {
cc.AddMessage(zhipu.ChatCompletionMessage{
Role: NameMap[msg.Role],
Content: contents[0].Text,
})
} else {
cc.AddMessage(zhipu.ChatCompletionMultiMessage{ cc.AddMessage(zhipu.ChatCompletionMultiMessage{
Role: NameMap[msg.Role], Role: NameMap[msg.Role],
Content: contents, Content: contents,
}) })
} }
}
for name := range config.GetTools() { for name := range config.GetTools() {
switch name { switch name {