move js to root
This commit is contained in:
Star 2024-09-18 18:29:21 +08:00
parent b4cddad489
commit afce45396e
14 changed files with 386 additions and 131 deletions

View File

@ -1,7 +1,7 @@
package main package main
import ( import (
"apigo.cc/ai/ai/js" "apigo.cc/ai/ai"
"fmt" "fmt"
"github.com/ssgo/u" "github.com/ssgo/u"
"os" "os"
@ -10,7 +10,7 @@ import (
func main() { func main() {
if len(os.Args) > 1 && (os.Args[1] == "-e" || os.Args[1] == "export") { if len(os.Args) > 1 && (os.Args[1] == "-e" || os.Args[1] == "export") {
imports, err := js.ExportForDev() imports, err := ai.ExportForDev()
if err != nil { if err != nil {
fmt.Println(err.Error()) fmt.Println(err.Error())
} else { } else {
@ -40,7 +40,7 @@ function main(...args) {
for i := 2; i < len(os.Args); i++ { for i := 2; i < len(os.Args); i++ {
args[i-2] = os.Args[i] args[i-2] = os.Args[i]
} }
result, err := js.RunFile(jsFile, args...) result, err := ai.RunFile(jsFile, args...)
if err != nil { if err != nil {
fmt.Println(err.Error()) fmt.Println(err.Error())
} else if result != nil { } else if result != nil {

6
go.mod
View File

@ -4,6 +4,7 @@ go 1.22
require ( require (
github.com/dop251/goja v0.0.0-20240828124009-016eb7256539 github.com/dop251/goja v0.0.0-20240828124009-016eb7256539
github.com/dop251/goja_nodejs v0.0.0-20240728170619-29b559befffc
github.com/go-resty/resty/v2 v2.15.0 github.com/go-resty/resty/v2 v2.15.0
github.com/golang-jwt/jwt/v5 v5.2.1 github.com/golang-jwt/jwt/v5 v5.2.1
github.com/sashabaranov/go-openai v1.29.2 github.com/sashabaranov/go-openai v1.29.2
@ -16,7 +17,6 @@ require (
require ( require (
github.com/davecgh/go-spew v1.1.1 // indirect github.com/davecgh/go-spew v1.1.1 // indirect
github.com/dlclark/regexp2 v1.11.4 // indirect github.com/dlclark/regexp2 v1.11.4 // indirect
github.com/dop251/goja_nodejs v0.0.0-20240728170619-29b559befffc // indirect
github.com/go-sourcemap/sourcemap v2.1.4+incompatible // indirect github.com/go-sourcemap/sourcemap v2.1.4+incompatible // indirect
github.com/google/pprof v0.0.0-20240910150728-a0b0bb1d4134 // indirect github.com/google/pprof v0.0.0-20240910150728-a0b0bb1d4134 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect
@ -25,7 +25,3 @@ require (
golang.org/x/text v0.18.0 // indirect golang.org/x/text v0.18.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect
) )
replace (
github.com/ssgo/config v1.7.7 => ../../ssgo/config
)

View File

@ -1,7 +1,7 @@
package js package ai
import ( import (
"apigo.cc/ai/ai" "apigo.cc/ai/ai/js"
"apigo.cc/ai/ai/llm" "apigo.cc/ai/ai/llm"
"bytes" "bytes"
_ "embed" _ "embed"
@ -17,24 +17,27 @@ import (
"text/template" "text/template"
) )
//go:embed lib/ai.ts //go:embed js/lib/ai.ts
var aiTS string var aiTS string
//go:embed lib/console.ts //go:embed js/lib/console.ts
var consoleTS string var consoleTS string
//go:embed lib/file.ts //go:embed js/lib/file.ts
var fileTS string var fileTS string
//go:embed js/lib/util.ts
var utilTS string
func RunFile(file string, args ...any) (any, error) { func RunFile(file string, args ...any) (any, error) {
return Run(u.ReadFileN(file), file, args...) return Run(u.ReadFileN(file), file, args...)
} }
func Run(code string, refFile string, args ...any) (any, error) { func Run(code string, refFile string, args ...any) (any, error) {
var r any var r any
js, err := StartFromCode(code, refFile) rt, err := StartFromCode(code, refFile)
if err == nil { if err == nil {
r, err = js.Run(args...) r, err = rt.Run(args...)
} }
return r, err return r, err
} }
@ -44,7 +47,7 @@ var importLibMatcher = regexp.MustCompile(`(?im)^\s*(import)\s+(.+?)\s+from\s+['
var requireLibMatcher = regexp.MustCompile(`(?im)^\s*(const|let|var)\s+(.+?)\s*=\s*require\s*\(\s*['"][./\\\w:]+lib[/\\](.+?)(\.ts)?['"]\s*\)`) var requireLibMatcher = regexp.MustCompile(`(?im)^\s*(const|let|var)\s+(.+?)\s*=\s*require\s*\(\s*['"][./\\\w:]+lib[/\\](.+?)(\.ts)?['"]\s*\)`)
var checkMainMatcher = regexp.MustCompile(`(?im)^\s*function\s+main\s*\(`) var checkMainMatcher = regexp.MustCompile(`(?im)^\s*function\s+main\s*\(`)
type JS struct { type Runtime struct {
vm *goja.Runtime vm *goja.Runtime
required map[string]bool required map[string]bool
file string file string
@ -52,34 +55,40 @@ type JS struct {
code string code string
} }
func (js *JS) 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 == "" {
if !js.required["console"] { if !rt.required["console"] {
js.required["console"] = true rt.required["console"] = true
err = js.vm.Set("console", requireConsole()) err = rt.vm.Set("console", js.RequireConsole())
} }
} }
if err == nil && (name == "file" || name == "") { if err == nil && (name == "file" || name == "") {
if !js.required["file"] { if !rt.required["file"] {
js.required["file"] = true rt.required["file"] = true
err = js.vm.Set("file", requireFile()) err = rt.vm.Set("file", js.RequireFile())
}
}
if err == nil && (name == "util" || name == "") {
if !rt.required["util"] {
rt.required["util"] = true
err = rt.vm.Set("util", js.RequireUtil())
} }
} }
if err == nil && (name == "ai" || name == "") { if err == nil && (name == "ai" || name == "") {
if !js.required["ai"] { if !rt.required["ai"] {
js.required["ai"] = true rt.required["ai"] = true
aiList := make(map[string]any) aiList := make(map[string]any)
for name, lm := range llm.List() { for name, lm := range llm.List() {
aiList[name] = requireAI(lm) aiList[name] = js.RequireAI(lm)
} }
err = js.vm.Set("ai", aiList) err = rt.vm.Set("ai", aiList)
} }
} }
return err return err
} }
func (js *JS) makeImport(matcher *regexp.Regexp, code string) (string, int, error) { func (rt *Runtime) makeImport(matcher *regexp.Regexp, code string) (string, int, error) {
var modErr error var modErr error
importCount := 0 importCount := 0
code = matcher.ReplaceAllStringFunc(code, func(str string) string { code = matcher.ReplaceAllStringFunc(code, func(str string) string {
@ -92,7 +101,7 @@ func (js *JS) makeImport(matcher *regexp.Regexp, code string) (string, int, erro
modName := m[3] modName := m[3]
importCount++ importCount++
if modErr == nil { if modErr == nil {
if err := js.requireMod(modName); err != nil { if err := rt.requireMod(modName); err != nil {
modErr = err modErr = err
} }
} }
@ -105,11 +114,11 @@ func (js *JS) makeImport(matcher *regexp.Regexp, code string) (string, int, erro
return code, importCount, modErr return code, importCount, modErr
} }
func StartFromFile(file string) (*JS, error) { func StartFromFile(file string) (*Runtime, error) {
return StartFromCode(u.ReadFileN(file), file) return StartFromCode(u.ReadFileN(file), file)
} }
func StartFromCode(code, refFile string) (*JS, error) { func StartFromCode(code, refFile string) (*Runtime, error) {
if refFile == "" { if refFile == "" {
refFile = "main.js" refFile = "main.js"
} }
@ -118,9 +127,9 @@ func StartFromCode(code, refFile string) (*JS, error) {
refFile = absFile refFile = absFile
} }
ai.InitFrom(filepath.Dir(refFile)) InitFrom(filepath.Dir(refFile))
js := &JS{ rt := &Runtime{
vm: goja.New(), vm: goja.New(),
required: map[string]bool{}, required: map[string]bool{},
file: refFile, file: refFile,
@ -131,29 +140,29 @@ func StartFromCode(code, refFile string) (*JS, error) {
// 按需加载引用 // 按需加载引用
var importCount int var importCount int
var modErr error var modErr error
js.code, importCount, modErr = js.makeImport(importLibMatcher, js.code) rt.code, importCount, modErr = rt.makeImport(importLibMatcher, rt.code)
if modErr == nil { if modErr == nil {
importCount1 := importCount importCount1 := importCount
js.code, importCount, modErr = js.makeImport(requireLibMatcher, js.code) rt.code, importCount, modErr = rt.makeImport(requireLibMatcher, rt.code)
importCount += importCount1 importCount += importCount1
} }
// 将 import 转换为 require // 将 import 转换为 require
js.code = importModMatcher.ReplaceAllString(js.code, "let $1 = require('$2')") rt.code = importModMatcher.ReplaceAllString(rt.code, "let $1 = require('$2')")
// 如果没有import默认import所有 // 如果没有import默认import所有
if modErr == nil && importCount == 0 { if modErr == nil && importCount == 0 {
modErr = js.requireMod("") modErr = rt.requireMod("")
} }
if modErr != nil { if modErr != nil {
return nil, modErr return nil, modErr
} }
//fmt.Println(u.BCyan(js.code)) //fmt.Println(u.BCyan(rt.code))
// 处理模块引用 // 处理模块引用
require.NewRegistryWithLoader(func(path string) ([]byte, error) { require.NewRegistryWithLoader(func(path string) ([]byte, error) {
refPath := filepath.Join(filepath.Dir(js.file), path) refPath := filepath.Join(filepath.Dir(rt.file), path)
if !strings.HasSuffix(refPath, ".js") && !u.FileExists(refPath) { if !strings.HasSuffix(refPath, ".js") && !u.FileExists(refPath) {
refPath += ".js" refPath += ".js"
} }
@ -161,23 +170,23 @@ func StartFromCode(code, refFile string) (*JS, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
modCode, _, _ = js.makeImport(importLibMatcher, modCode) modCode, _, _ = rt.makeImport(importLibMatcher, modCode)
modCode, _, _ = js.makeImport(requireLibMatcher, modCode) modCode, _, _ = rt.makeImport(requireLibMatcher, modCode)
return []byte(modCode), modErr return []byte(modCode), modErr
}).Enable(js.vm) }).Enable(rt.vm)
// 初始化主函数 // 初始化主函数
if !checkMainMatcher.MatchString(js.code) { if !checkMainMatcher.MatchString(rt.code) {
js.code = "function main(...args){" + js.code + "}" rt.code = "function main(...args){" + rt.code + "}"
} }
if _, err := js.vm.RunScript("main", js.code); err != nil { if _, err := rt.vm.RunScript("main", rt.code); err != nil {
return nil, err return nil, err
} }
return js, nil return rt, nil
} }
func (js *JS) Run(args ...any) (any, error) { func (rt *Runtime) Run(args ...any) (any, error) {
// 解析参数 // 解析参数
for i, arg := range args { for i, arg := range args {
if str, ok := arg.(string); ok { if str, ok := arg.(string); ok {
@ -188,10 +197,10 @@ func (js *JS) Run(args ...any) (any, error) {
} }
} }
if err := js.vm.Set("__args", args); err != nil { if err := rt.vm.Set("__args", args); err != nil {
return nil, err return nil, err
} }
jsResult, err := js.vm.RunScript(js.file, "main(...__args)") jsResult, err := rt.vm.RunScript(rt.file, "main(...__args)")
var result any var result any
if err == nil { if err == nil {
@ -207,7 +216,7 @@ type Exports struct {
} }
func ExportForDev() (string, error) { func ExportForDev() (string, error) {
ai.Init() Init()
if len(llm.List()) == 0 && !u.FileExists("env.yml") && !u.FileExists("env.json") && !u.FileExists("llm.yml") && !u.FileExists("llm.json") { if len(llm.List()) == 0 && !u.FileExists("env.yml") && !u.FileExists("env.json") && !u.FileExists("llm.yml") && !u.FileExists("llm.json") {
return "", errors.New("no llm config found, please run `ai -e` on env.yml or llm.yml path") return "", errors.New("no llm config found, please run `ai -e` on env.yml or llm.yml path")
} }
@ -231,8 +240,10 @@ func ExportForDev() (string, error) {
_ = u.WriteFile(filepath.Join("lib", "console.ts"), consoleTS) _ = u.WriteFile(filepath.Join("lib", "console.ts"), consoleTS)
_ = u.WriteFile(filepath.Join("lib", "file.ts"), fileTS) _ = u.WriteFile(filepath.Join("lib", "file.ts"), fileTS)
_ = u.WriteFile(filepath.Join("lib", "util.ts"), utilTS)
return `import {` + strings.Join(exports.LLMList, ", ") + `} from './lib/ai' return `import {` + strings.Join(exports.LLMList, ", ") + `} from './lib/ai'
import console from './lib/console' import console from './lib/console'
import util from './lib/util'
import file from './lib/file'`, nil import file from './lib/file'`, nil
} }

View File

@ -22,7 +22,7 @@ type AIGCResult struct {
Error string Error string
} }
func requireAI(lm llm.LLM) map[string]any { func RequireAI(lm llm.LLM) map[string]any {
return map[string]any{ return map[string]any{
"ask": func(args goja.FunctionCall, vm *goja.Runtime) goja.Value { "ask": func(args goja.FunctionCall, vm *goja.Runtime) goja.Value {
conf, cb := getAskArgs(args.This, vm, args.Arguments) conf, cb := getAskArgs(args.This, vm, args.Arguments)

View File

@ -7,7 +7,7 @@ import (
"strings" "strings"
) )
func requireConsole() map[string]any { func RequireConsole() map[string]any {
return map[string]any{ return map[string]any{
"print": func(args goja.FunctionCall) goja.Value { "print": func(args goja.FunctionCall) goja.Value {
consolePrint(args, "print", nil) consolePrint(args, "print", nil)

View File

@ -6,7 +6,7 @@ import (
"github.com/ssgo/u" "github.com/ssgo/u"
) )
func requireFile() map[string]any { func RequireFile() map[string]any {
return map[string]any{ return map[string]any{
"read": func(args goja.FunctionCall, vm *goja.Runtime) goja.Value { "read": func(args goja.FunctionCall, vm *goja.Runtime) goja.Value {
if len(args.Arguments) < 1 { if len(args.Arguments) < 1 {

View File

@ -2,15 +2,15 @@
{{range .LLMList}} {{range .LLMList}}
let {{.}}: LLM let {{.}}: LLM
{{end}} {{- end}}
export default { export default {
{{range .LLMList}} {{- range .LLMList}}
{{.}}, {{.}},
{{end}} {{- end}}
} }
interface ChatModelConfig { interface ChatConfig {
model: string model: string
ratio: number ratio: number
maxTokens: number maxTokens: number
@ -27,6 +27,12 @@ interface ChatResult {
error: string error: string
} }
interface GCConfig {
model: string
size: string
ref: string
}
interface GCResult { interface GCResult {
result: string result: string
preview: string preview: string
@ -47,35 +53,20 @@ interface Support {
} }
interface LLM { interface LLM {
ask(messages: any, config?: ChatModelConfig, callback?: (answer: string) => void): ChatResult ask(messages: any, config?: ChatConfig, callback?: (answer: string) => void): ChatResult
fastAsk(messages: any, callback?: (answer: string) => void): ChatResult fastAsk(messages: any, callback?: (answer: string) => void): ChatResult
longAsk(messages: any, callback?: (answer: string) => void): ChatResult longAsk(messages: any, callback?: (answer: string) => void): ChatResult
batterAsk(messages: any, callback?: (answer: string) => void): ChatResult batterAsk(messages: any, callback?: (answer: string) => void): ChatResult
bestAsk(messages: any, callback?: (answer: string) => void): ChatResult bestAsk(messages: any, callback?: (answer: string) => void): ChatResult
multiAsk(messages: any, callback?: (answer: string) => void): ChatResult multiAsk(messages: any, callback?: (answer: string) => void): ChatResult
bestMultiAsk(messages: any, callback?: (answer: string) => void): ChatResult bestMultiAsk(messages: any, callback?: (answer: string) => void): ChatResult
codeInterpreterAsk(messages: any, callback?: (answer: string) => void): ChatResult codeInterpreterAsk(messages: any, callback?: (answer: string) => void): ChatResult
webSearchAsk(messages: any, callback?: (answer: string) => void): ChatResult webSearchAsk(messages: any, callback?: (answer: string) => void): ChatResult
makeImage(prompt: string, config?: GCConfig): GCResult
makeImage(model: string, prompt: string, size?: string, refImage?: string): GCResult fastMakeImage(prompt: string, config?: GCConfig): GCResult
bestMakeImage(prompt: string, config?: GCConfig): GCResult
fastMakeImage(prompt: string, size?: string, refImage?: string): GCResult makeVideo(prompt: string, config?: GCConfig): GCResult
fastMakeVideo(prompt: string, config?: GCConfig): GCResult
bestMakeImage(prompt: string, size?: string, refImage?: string): GCResult bestMakeVideo(prompt: string, config?: GCConfig): GCResult
makeVideo(arg2: string, arg3: string, arg4: string, arg5: string): GCResult
fastMakeVideo(prompt: string, size?: string, refImage?: string): GCResult
bestMakeVideo(prompt: string, size?: string, refImage?: string): GCResult
support: Support support: Support
} }

View File

@ -11,27 +11,11 @@ export default {
input, input,
} }
function print(...data: any[]): void { function print(...data: any[]): void {}
} function println(...data: any[]): void {}
function log(...data: any[]): void {}
function println(...data: any[]): void { function debug(...data: any[]): void {}
} function info(...data: any[]): void {}
function warn(...data: any[]): void {}
function log(...data: any[]): void { function error(...data: any[]): void {}
} function input(...data: any[]): string {return ''}
function debug(...data: any[]): void {
}
function info(...data: any[]): void {
}
function warn(...data: any[]): void {
}
function error(...data: any[]): void {
}
function input(...data: any[]): string {
return ''
}

View File

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

51
js/lib/util.ts Normal file
View File

@ -0,0 +1,51 @@
// just for develop
export default {
json,
jsonP,
unJson,
yaml,
unYaml,
base64,
unBase64,
urlBase64,
unUrlBase64,
hex,
unHex,
aes,
unAes,
gzip,
gunzip,
id,
uniqueId,
token,
md5,
sha1,
sha256,
sha512,
tpl
}
function json(data:any): string {return ''}
function jsonP(data:any): string {return ''}
function unJson(data:string): any {return null}
function yaml(data:any): string {return ''}
function unYaml(data:string): any {return null}
function base64(data:any): string {return ''}
function unBase64(data:string): any {return null}
function urlBase64(data:any): string {return ''}
function unUrlBase64(data:string): any {return null}
function hex(data:any): string {return ''}
function unHex(data:string): any {return null}
function aes(data:any, key:string, iv:string): string {return ''}
function unAes(data:string, key:string, iv:string): any {return null}
function gzip(data:any): string {return ''}
function gunzip(data:string): any {return null}
function id(): string {return ''}
function uniqueId(): string {return ''}
function token(size:number): string {return ''}
function md5(data:any): string {return ''}
function sha1(data:any): string {return ''}
function sha256(data:any): string {return ''}
function sha512(data:any): string {return ''}
function tpl(text:string, data:any): string {return ''}

206
js/util.go Normal file
View File

@ -0,0 +1,206 @@
package js
import (
"bytes"
"encoding/hex"
"encoding/json"
"errors"
"github.com/dop251/goja"
"github.com/ssgo/u"
"gopkg.in/yaml.v3"
"text/template"
)
func RequireUtil() map[string]any {
return map[string]any{
"json": func(args goja.FunctionCall, vm *goja.Runtime) goja.Value {
if len(args.Arguments) < 1 {
return vm.NewGoError(errors.New("arguments need 1 given " + u.String(len(args.Arguments))))
}
if r, err := json.Marshal(args.Arguments[0].Export()); err == nil {
return vm.ToValue(string(r))
} else {
return vm.NewGoError(err)
}
},
"jsonP": func(args goja.FunctionCall, vm *goja.Runtime) goja.Value {
if len(args.Arguments) < 1 {
return vm.NewGoError(errors.New("arguments need 1 given " + u.String(len(args.Arguments))))
}
if r, err := json.Marshal(args.Arguments[0].Export()); err == nil {
r1 := bytes.Buffer{}
if err2 := json.Indent(&r1, r, "", " "); err2 == nil {
return vm.ToValue(string(r))
} else {
return vm.ToValue(string(r))
}
} else {
return vm.NewGoError(err)
}
},
"unJson": func(args goja.FunctionCall, vm *goja.Runtime) goja.Value {
if len(args.Arguments) < 1 {
return vm.NewGoError(errors.New("arguments need 1 given " + u.String(len(args.Arguments))))
}
var r any
if err := json.Unmarshal(u.Bytes(args.Arguments[0].Export()), &r); err == nil {
return vm.ToValue(r)
} else {
return vm.NewGoError(err)
}
},
"yaml": func(args goja.FunctionCall, vm *goja.Runtime) goja.Value {
if len(args.Arguments) < 1 {
return vm.NewGoError(errors.New("arguments need 1 given " + u.String(len(args.Arguments))))
}
if r, err := yaml.Marshal(args.Arguments[0].Export()); err == nil {
return vm.ToValue(string(r))
} else {
return vm.NewGoError(err)
}
},
"unYaml": func(args goja.FunctionCall, vm *goja.Runtime) goja.Value {
if len(args.Arguments) < 1 {
return vm.NewGoError(errors.New("arguments need 1 given " + u.String(len(args.Arguments))))
}
var r any
if err := yaml.Unmarshal(u.Bytes(args.Arguments[0].Export()), &r); err == nil {
return vm.ToValue(r)
} else {
return vm.NewGoError(err)
}
},
"base64": func(args goja.FunctionCall, vm *goja.Runtime) goja.Value {
if len(args.Arguments) < 1 {
return vm.NewGoError(errors.New("arguments need 1 given " + u.String(len(args.Arguments))))
}
return vm.ToValue(u.Base64(u.Bytes(args.Arguments[0].Export())))
},
"unBase64": func(args goja.FunctionCall, vm *goja.Runtime) goja.Value {
if len(args.Arguments) < 1 {
return vm.NewGoError(errors.New("arguments need 1 given " + u.String(len(args.Arguments))))
}
return vm.ToValue(u.UnBase64String(u.String(args.Arguments[0].Export())))
},
"urlBase64": func(args goja.FunctionCall, vm *goja.Runtime) goja.Value {
if len(args.Arguments) < 1 {
return vm.NewGoError(errors.New("arguments need 1 given " + u.String(len(args.Arguments))))
}
return vm.ToValue(u.UrlBase64String(u.String(args.Arguments[0].Export())))
},
"unUrlBase64": func(args goja.FunctionCall, vm *goja.Runtime) goja.Value {
if len(args.Arguments) < 1 {
return vm.NewGoError(errors.New("arguments need 1 given " + u.String(len(args.Arguments))))
}
return vm.ToValue(u.UnUrlBase64String(u.String(args.Arguments[0].Export())))
},
"hex": func(args goja.FunctionCall, vm *goja.Runtime) goja.Value {
if len(args.Arguments) < 1 {
return vm.NewGoError(errors.New("arguments need 1 given " + u.String(len(args.Arguments))))
}
return vm.ToValue(hex.EncodeToString(u.Bytes(args.Arguments[0].Export())))
},
"unHex": func(args goja.FunctionCall, vm *goja.Runtime) goja.Value {
if len(args.Arguments) < 1 {
return vm.NewGoError(errors.New("arguments need 1 given " + u.String(len(args.Arguments))))
}
if r, err := hex.DecodeString(u.String(args.Arguments[0].Export())); err == nil {
return vm.ToValue(string(r))
} else {
return vm.NewGoError(err)
}
},
"aes": func(args goja.FunctionCall, vm *goja.Runtime) goja.Value {
if len(args.Arguments) < 3 {
return vm.NewGoError(errors.New("arguments need 3 given " + u.String(len(args.Arguments))))
}
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))
} else {
return vm.NewGoError(err)
}
},
"unAes": func(args goja.FunctionCall, vm *goja.Runtime) goja.Value {
if len(args.Arguments) < 3 {
return vm.NewGoError(errors.New("arguments need 3 given " + u.String(len(args.Arguments))))
}
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))
} else {
return vm.NewGoError(err)
}
},
"gzip": func(args goja.FunctionCall, vm *goja.Runtime) goja.Value {
if len(args.Arguments) < 1 {
return vm.NewGoError(errors.New("arguments need 1 given " + u.String(len(args.Arguments))))
}
if r, err := u.Gzip(u.Bytes(args.Arguments[0].Export())); err == nil {
return vm.ToValue(string(r))
} else {
return vm.NewGoError(err)
}
},
"gunzip": func(args goja.FunctionCall, vm *goja.Runtime) goja.Value {
if len(args.Arguments) < 1 {
return vm.NewGoError(errors.New("arguments need 1 given " + u.String(len(args.Arguments))))
}
if r, err := u.Gunzip(u.Bytes(args.Arguments[0].Export())); err == nil {
return vm.ToValue(string(r))
} else {
return vm.NewGoError(err)
}
},
"id": func(args goja.FunctionCall, vm *goja.Runtime) goja.Value {
return vm.ToValue(u.Id12())
},
"uniqueId": func(args goja.FunctionCall, vm *goja.Runtime) goja.Value {
return vm.ToValue(u.UniqueId())
},
"token": func(args goja.FunctionCall, vm *goja.Runtime) goja.Value {
size := 20
if len(args.Arguments) > 0 {
size = u.Int(args.Arguments[0].Export())
}
return vm.ToValue(u.MakeToken(size))
},
"md5": func(args goja.FunctionCall, vm *goja.Runtime) goja.Value {
if len(args.Arguments) < 1 {
return vm.NewGoError(errors.New("arguments need 1 given " + u.String(len(args.Arguments))))
}
return vm.ToValue(u.MD5(u.Bytes(args.Arguments[0].Export())))
},
"sha1": func(args goja.FunctionCall, vm *goja.Runtime) goja.Value {
if len(args.Arguments) < 1 {
return vm.NewGoError(errors.New("arguments need 1 given " + u.String(len(args.Arguments))))
}
return vm.ToValue(u.Sha1(u.Bytes(args.Arguments[0].Export())))
},
"sha256": func(args goja.FunctionCall, vm *goja.Runtime) goja.Value {
if len(args.Arguments) < 1 {
return vm.NewGoError(errors.New("arguments need 1 given " + u.String(len(args.Arguments))))
}
return vm.ToValue(u.Sha256(u.Bytes(args.Arguments[0].Export())))
},
"sha512": func(args goja.FunctionCall, vm *goja.Runtime) goja.Value {
if len(args.Arguments) < 1 {
return vm.NewGoError(errors.New("arguments need 1 given " + u.String(len(args.Arguments))))
}
return vm.ToValue(u.Sha512(u.Bytes(args.Arguments[0].Export())))
},
"tpl": func(args goja.FunctionCall, vm *goja.Runtime) goja.Value {
if len(args.Arguments) < 2 {
return vm.NewGoError(errors.New("arguments need 2 given " + u.String(len(args.Arguments))))
}
var tpl *template.Template
buf := bytes.NewBuffer(make([]byte, 0))
var err error
if tpl, err = template.New("tpl").Parse(u.String(args.Arguments[0])); err == nil {
err = tpl.Execute(buf, args.Arguments[1])
}
if err != nil {
return vm.NewGoError(err)
}
return vm.ToValue(buf.String())
},
}
}

View File

@ -31,21 +31,23 @@ func (lm *LLM) MakeImage(prompt string, config llm.GCConfig) ([]string, error) {
if lm.config.Endpoint != "" { if lm.config.Endpoint != "" {
openaiConf.BaseURL = lm.config.Endpoint openaiConf.BaseURL = lm.config.Endpoint
} }
config.SetDefault(&lm.config.GCConfig)
c := openai.NewClientWithConfig(openaiConf) c := openai.NewClientWithConfig(openaiConf)
style := openai.CreateImageStyleVivid style := openai.CreateImageStyleVivid
if (!strings.Contains(prompt, "vivid") || !strings.Contains(prompt, "生动的")) && (strings.Contains(prompt, "natural") || strings.Contains(prompt, "自然的")) { if (!strings.Contains(prompt, "vivid") || !strings.Contains(prompt, "生动的")) && (strings.Contains(prompt, "natural") || strings.Contains(prompt, "自然的")) {
style = openai.CreateImageStyleNatural style = openai.CreateImageStyleNatural
} }
quality := openai.CreateImageQualityStandard quality := openai.CreateImageQualityStandard
if strings.HasSuffix(config.Model, "-hd") { model := config.GetModel()
if strings.HasSuffix(model, "-hd") {
quality = openai.CreateImageQualityHD quality = openai.CreateImageQualityHD
config.Model = config.Model[0 : len(config.Model)-3] model = model[0 : len(model)-3]
} }
r, err := c.CreateImage(context.Background(), openai.ImageRequest{ r, err := c.CreateImage(context.Background(), openai.ImageRequest{
Prompt: prompt, Prompt: prompt,
Model: config.Model, Model: model,
Quality: quality, Quality: quality,
Size: config.Size, Size: config.GetSize(),
Style: style, Style: style,
ResponseFormat: openai.CreateImageResponseFormatURL, ResponseFormat: openai.CreateImageResponseFormatURL,
}) })

View File

@ -24,10 +24,9 @@ func (lm *LLM) MakeImage(prompt string, config llm.GCConfig) ([]string, error) {
return nil, err return nil, err
} }
config.SetDefault(&lm.config.GCConfig)
cc := c.ImageGeneration(config.Model).SetPrompt(prompt) cc := c.ImageGeneration(config.Model).SetPrompt(prompt)
if config.Size != "" { cc.SetSize(config.GetSize())
cc.SetSize(config.Size)
}
if r, err := cc.Do(context.Background()); err == nil { if r, err := cc.Do(context.Background()); err == nil {
results := make([]string, 0) results := make([]string, 0)
@ -56,10 +55,9 @@ func (lm *LLM) MakeVideo(prompt string, config llm.GCConfig) ([]string, []string
return nil, nil, err return nil, nil, err
} }
config.SetDefault(&lm.config.GCConfig)
cc := c.VideoGeneration(config.Model).SetPrompt(prompt) cc := c.VideoGeneration(config.Model).SetPrompt(prompt)
if config.Ref != "" { cc.SetImageURL(config.GetRef())
cc.SetImageURL(config.Ref)
}
if resp, err := cc.Do(context.Background()); err == nil { if resp, err := cc.Do(context.Background()); err == nil {
for i := 0; i < 1200; i++ { for i := 0; i < 1200; i++ {

View File

@ -4,6 +4,7 @@ import (
"apigo.cc/ai/ai" "apigo.cc/ai/ai"
"apigo.cc/ai/ai/js" "apigo.cc/ai/ai/js"
"apigo.cc/ai/ai/llm" "apigo.cc/ai/ai/llm"
"encoding/hex"
"fmt" "fmt"
"github.com/ssgo/u" "github.com/ssgo/u"
"testing" "testing"
@ -32,8 +33,9 @@ func TestAgent(t *testing.T) {
//testMakeImage(t, "glm", "", keys.Zhipu, "冬天大雪纷飞,一个男人身穿军绿色棉大衣,戴着红色围巾和绿色帽子走在铺面大雪的小镇路上", "") //testMakeImage(t, "glm", "", keys.Zhipu, "冬天大雪纷飞,一个男人身穿军绿色棉大衣,戴着红色围巾和绿色帽子走在铺面大雪的小镇路上", "")
//testMakeVideo(t, "glm", "", keys.Zhipu, "大雪纷飞,男人蹦蹦跳跳", "https://aigc-files.bigmodel.cn/api/cogview/20240904133130c4b7121019724aa3_0.png") //testMakeVideo(t, "glm", "", keys.Zhipu, "大雪纷飞,男人蹦蹦跳跳", "https://aigc-files.bigmodel.cn/api/cogview/20240904133130c4b7121019724aa3_0.png")
testJS(t) //testJS(t)
//testFile(t) //testFile(t)
testUtil(t)
} }
func testChat(t *testing.T, llmName string) { func testChat(t *testing.T, llmName string) {
@ -196,7 +198,7 @@ func testMakeVideo(t *testing.T, llmName, prompt, refImage string) {
} }
func testJS(t *testing.T) { func testJS(t *testing.T) {
r1, err := js.RunFile("test.js", "1+2=4吗") r1, err := ai.RunFile("test.js", "1+2=4吗")
if err != nil { if err != nil {
t.Fatal("发生错误", err.Error()) t.Fatal("发生错误", err.Error())
} }
@ -209,7 +211,7 @@ func testJS(t *testing.T) {
} }
func testFile(t *testing.T) { func testFile(t *testing.T) {
r1, err := js.Run(` r1, err := ai.Run(`
import fs from './lib/file' import fs from './lib/file'
import out from './lib/console' import out from './lib/console'
let r = fs.read('test.js') let r = fs.read('test.js')
@ -222,3 +224,28 @@ return r
fmt.Println() fmt.Println()
fmt.Println("result:", r1) fmt.Println("result:", r1)
} }
func testUtil(t *testing.T) {
fmt.Println(hex.EncodeToString(u.Sha256([]byte{0, 98, 2})))
r, err := ai.Run(`
let s = String.fromCharCode(0, 98, 2)
//let r = util.base64(s)
//let r2 = util.unBase64(r)
//console.info(r)
//console.info(r2.length, r2)
//console.info(s.charCodeAt(0), r2.charCodeAt(0))
//return r2 === s
let r = util.hex(util.sha256(s))
console.info(r)
return r == '278f25d5e7c09b2cdde1ed72dd83fbb7a7d7dd668ef967c9af65f68aa04049cd'
`, "test.js")
if err != nil {
t.Fatal("发生错误", err.Error())
}
if r != true {
t.Fatal("运行结果不正确", r)
}
fmt.Println()
fmt.Println("result:", r)
}