add db、log support
support embedding for llm support watch run for js many other updates
This commit is contained in:
parent
767d87ac3e
commit
e69b9a3a12
2
ai.go
2
ai.go
@ -1,7 +1,7 @@
|
|||||||
package ai
|
package ai
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"apigo.cc/ai/ai/llm"
|
"apigo.cc/ai/ai/interface/llm"
|
||||||
_ "apigo.cc/ai/ai/llm/openai"
|
_ "apigo.cc/ai/ai/llm/openai"
|
||||||
_ "apigo.cc/ai/ai/llm/zhipu"
|
_ "apigo.cc/ai/ai/llm/zhipu"
|
||||||
"github.com/ssgo/config"
|
"github.com/ssgo/config"
|
||||||
|
4
ai/ai.go
4
ai/ai.go
@ -2,9 +2,11 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"apigo.cc/ai/ai"
|
"apigo.cc/ai/ai"
|
||||||
"apigo.cc/ai/ai/ai/watcher"
|
"apigo.cc/ai/ai/watcher"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
_ "github.com/go-sql-driver/mysql"
|
||||||
"github.com/ssgo/u"
|
"github.com/ssgo/u"
|
||||||
|
_ "modernc.org/sqlite"
|
||||||
"os"
|
"os"
|
||||||
"os/signal"
|
"os/signal"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
18
go.mod
18
go.mod
@ -9,10 +9,13 @@ require (
|
|||||||
github.com/fsnotify/fsnotify v1.7.0
|
github.com/fsnotify/fsnotify v1.7.0
|
||||||
github.com/go-resty/resty/v2 v2.15.2
|
github.com/go-resty/resty/v2 v2.15.2
|
||||||
github.com/go-sourcemap/sourcemap v2.1.4+incompatible
|
github.com/go-sourcemap/sourcemap v2.1.4+incompatible
|
||||||
|
github.com/go-sql-driver/mysql v1.5.0
|
||||||
github.com/golang-jwt/jwt/v5 v5.2.1
|
github.com/golang-jwt/jwt/v5 v5.2.1
|
||||||
github.com/google/pprof v0.0.0-20240910150728-a0b0bb1d4134
|
github.com/google/pprof v0.0.0-20240910150728-a0b0bb1d4134
|
||||||
github.com/sashabaranov/go-openai v1.30.3
|
github.com/sashabaranov/go-openai v1.30.3
|
||||||
github.com/ssgo/config v1.7.7
|
github.com/ssgo/config v1.7.7
|
||||||
|
github.com/ssgo/dao v0.1.1
|
||||||
|
github.com/ssgo/db v1.7.8
|
||||||
github.com/ssgo/httpclient v1.7.7
|
github.com/ssgo/httpclient v1.7.7
|
||||||
github.com/ssgo/log v1.7.7
|
github.com/ssgo/log v1.7.7
|
||||||
github.com/ssgo/u v1.7.7
|
github.com/ssgo/u v1.7.7
|
||||||
@ -22,12 +25,27 @@ require (
|
|||||||
golang.org/x/text v0.18.0
|
golang.org/x/text v0.18.0
|
||||||
gopkg.in/yaml.v2 v2.4.0
|
gopkg.in/yaml.v2 v2.4.0
|
||||||
gopkg.in/yaml.v3 v3.0.1
|
gopkg.in/yaml.v3 v3.0.1
|
||||||
|
modernc.org/sqlite v1.33.1
|
||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||||
|
github.com/dustin/go-humanize v1.0.1 // indirect
|
||||||
|
github.com/google/uuid v1.6.0 // indirect
|
||||||
|
github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect
|
||||||
github.com/kr/text v0.2.0 // indirect
|
github.com/kr/text v0.2.0 // indirect
|
||||||
|
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||||
|
github.com/mattn/go-sqlite3 v1.14.17 // indirect
|
||||||
|
github.com/mitchellh/mapstructure v1.4.1 // indirect
|
||||||
|
github.com/ncruces/go-strftime v0.1.9 // indirect
|
||||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||||
|
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect
|
||||||
github.com/ssgo/standard v1.7.7 // indirect
|
github.com/ssgo/standard v1.7.7 // indirect
|
||||||
golang.org/x/sys v0.25.0 // indirect
|
golang.org/x/sys v0.25.0 // indirect
|
||||||
|
modernc.org/gc/v3 v3.0.0-20240107210532-573471604cb6 // indirect
|
||||||
|
modernc.org/libc v1.55.3 // indirect
|
||||||
|
modernc.org/mathutil v1.6.0 // indirect
|
||||||
|
modernc.org/memory v1.8.0 // indirect
|
||||||
|
modernc.org/strutil v1.2.0 // indirect
|
||||||
|
modernc.org/token v1.1.0 // indirect
|
||||||
)
|
)
|
||||||
|
@ -1,5 +1,11 @@
|
|||||||
package llm
|
package llm
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/binary"
|
||||||
|
"math"
|
||||||
|
)
|
||||||
|
|
||||||
type ChatMessage struct {
|
type ChatMessage struct {
|
||||||
Role string
|
Role string
|
||||||
Contents []ChatMessageContent
|
Contents []ChatMessageContent
|
||||||
@ -59,10 +65,11 @@ func (chatConfig *ChatConfig) GetTools() map[string]any {
|
|||||||
return chatConfig.Tools
|
return chatConfig.Tools
|
||||||
}
|
}
|
||||||
|
|
||||||
type TokenUsage struct {
|
type Usage struct {
|
||||||
AskTokens int64
|
AskTokens int64
|
||||||
AnswerTokens int64
|
AnswerTokens int64
|
||||||
TotalTokens int64
|
TotalTokens int64
|
||||||
|
UsedTime int64
|
||||||
}
|
}
|
||||||
|
|
||||||
type MessagesMaker struct {
|
type MessagesMaker struct {
|
||||||
@ -143,3 +150,38 @@ func (m *MessagesMaker) Video(text string) *MessagesMaker {
|
|||||||
}
|
}
|
||||||
return m
|
return m
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func bin2float64(in []byte) []float64 {
|
||||||
|
buf := bytes.NewBuffer(in)
|
||||||
|
out := make([]float64, len(in)/4)
|
||||||
|
for i := 0; i < len(out); i++ {
|
||||||
|
var f float32
|
||||||
|
_ = binary.Read(buf, binary.LittleEndian, &f)
|
||||||
|
out[i] = float64(f)
|
||||||
|
}
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
|
func Similarity(buf1, buf2 []byte) float64 {
|
||||||
|
a := bin2float64(buf1)
|
||||||
|
b := bin2float64(buf2)
|
||||||
|
if len(a) != len(b) {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
var dotProduct, magnitudeA, magnitudeB float64
|
||||||
|
for i := 0; i < len(a); i++ {
|
||||||
|
dotProduct += a[i] * b[i]
|
||||||
|
magnitudeA += a[i] * a[i]
|
||||||
|
magnitudeB += b[i] * b[i]
|
||||||
|
}
|
||||||
|
|
||||||
|
magnitudeA = math.Sqrt(magnitudeA)
|
||||||
|
magnitudeB = math.Sqrt(magnitudeB)
|
||||||
|
|
||||||
|
if magnitudeA == 0 || magnitudeB == 0 {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
return dotProduct / (magnitudeA * magnitudeB)
|
||||||
|
}
|
@ -35,21 +35,24 @@ type Config struct {
|
|||||||
|
|
||||||
type LLM interface {
|
type LLM interface {
|
||||||
Support() Support
|
Support() Support
|
||||||
Ask(messages []ChatMessage, config ChatConfig, callback func(answer string)) (string, TokenUsage, error)
|
Ask(messages []ChatMessage, config ChatConfig, callback func(answer string)) (string, Usage, error)
|
||||||
FastAsk(messages []ChatMessage, callback func(answer string)) (string, TokenUsage, error)
|
FastAsk(messages []ChatMessage, callback func(answer string)) (string, Usage, error)
|
||||||
LongAsk(messages []ChatMessage, callback func(answer string)) (string, TokenUsage, error)
|
LongAsk(messages []ChatMessage, callback func(answer string)) (string, Usage, error)
|
||||||
BatterAsk(messages []ChatMessage, callback func(answer string)) (string, TokenUsage, error)
|
BatterAsk(messages []ChatMessage, callback func(answer string)) (string, Usage, error)
|
||||||
BestAsk(messages []ChatMessage, callback func(answer string)) (string, TokenUsage, error)
|
BestAsk(messages []ChatMessage, callback func(answer string)) (string, Usage, error)
|
||||||
MultiAsk(messages []ChatMessage, callback func(answer string)) (string, TokenUsage, error)
|
MultiAsk(messages []ChatMessage, callback func(answer string)) (string, Usage, error)
|
||||||
BestMultiAsk(messages []ChatMessage, callback func(answer string)) (string, TokenUsage, error)
|
BestMultiAsk(messages []ChatMessage, callback func(answer string)) (string, Usage, error)
|
||||||
CodeInterpreterAsk(messages []ChatMessage, callback func(answer string)) (string, TokenUsage, error)
|
CodeInterpreterAsk(messages []ChatMessage, callback func(answer string)) (string, Usage, error)
|
||||||
WebSearchAsk(messages []ChatMessage, callback func(answer string)) (string, TokenUsage, error)
|
WebSearchAsk(messages []ChatMessage, callback func(answer string)) (string, Usage, error)
|
||||||
MakeImage(prompt string, config GCConfig) ([]string, error)
|
MakeImage(prompt string, config GCConfig) ([]string, Usage, error)
|
||||||
FastMakeImage(prompt string, config GCConfig) ([]string, error)
|
FastMakeImage(prompt string, config GCConfig) ([]string, Usage, error)
|
||||||
BestMakeImage(prompt string, config GCConfig) ([]string, error)
|
BestMakeImage(prompt string, config GCConfig) ([]string, Usage, error)
|
||||||
MakeVideo(prompt string, config GCConfig) ([]string, []string, error)
|
MakeVideo(prompt string, config GCConfig) ([]string, []string, Usage, error)
|
||||||
FastMakeVideo(prompt string, config GCConfig) ([]string, []string, error)
|
FastMakeVideo(prompt string, config GCConfig) ([]string, []string, Usage, error)
|
||||||
BestMakeVideo(prompt string, config GCConfig) ([]string, []string, error)
|
BestMakeVideo(prompt string, config GCConfig) ([]string, []string, Usage, error)
|
||||||
|
Embedding(text string, model string) ([]byte, Usage, error)
|
||||||
|
FastEmbedding(text string) ([]byte, Usage, error)
|
||||||
|
BestEmbedding(text string) ([]byte, Usage, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
var llmMakers = map[string]func(Config) LLM{}
|
var llmMakers = map[string]func(Config) LLM{}
|
135
js.go
135
js.go
@ -3,18 +3,24 @@ package ai
|
|||||||
import (
|
import (
|
||||||
"apigo.cc/ai/ai/goja"
|
"apigo.cc/ai/ai/goja"
|
||||||
"apigo.cc/ai/ai/goja_nodejs/require"
|
"apigo.cc/ai/ai/goja_nodejs/require"
|
||||||
|
"apigo.cc/ai/ai/interface/llm"
|
||||||
"apigo.cc/ai/ai/js"
|
"apigo.cc/ai/ai/js"
|
||||||
"apigo.cc/ai/ai/llm"
|
"apigo.cc/ai/ai/watcher"
|
||||||
"bytes"
|
"bytes"
|
||||||
_ "embed"
|
_ "embed"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"github.com/ssgo/log"
|
||||||
"github.com/ssgo/u"
|
"github.com/ssgo/u"
|
||||||
|
"os"
|
||||||
|
"os/signal"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"regexp"
|
"regexp"
|
||||||
"strings"
|
"strings"
|
||||||
|
"syscall"
|
||||||
"text/template"
|
"text/template"
|
||||||
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
//go:embed js/lib/ai.ts
|
//go:embed js/lib/ai.ts
|
||||||
@ -32,6 +38,12 @@ var utilTS string
|
|||||||
//go:embed js/lib/http.ts
|
//go:embed js/lib/http.ts
|
||||||
var httpTS string
|
var httpTS string
|
||||||
|
|
||||||
|
//go:embed js/lib/log.ts
|
||||||
|
var logTS string
|
||||||
|
|
||||||
|
//go:embed js/lib/db.ts
|
||||||
|
var dbTS 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...)
|
||||||
}
|
}
|
||||||
@ -98,14 +110,22 @@ func (rt *Runtime) requireMod(name string) error {
|
|||||||
err = rt.vm.Set("http", js.RequireHTTP())
|
err = rt.vm.Set("http", js.RequireHTTP())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if err == nil && (name == "log" || name == "") {
|
||||||
|
if !rt.required["log"] {
|
||||||
|
rt.required["log"] = true
|
||||||
|
err = rt.vm.Set("log", js.RequireLog())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if err == nil && (name == "db" || name == "") {
|
||||||
|
if !rt.required["db"] {
|
||||||
|
rt.required["db"] = true
|
||||||
|
err = rt.vm.Set("db", js.RequireDB())
|
||||||
|
}
|
||||||
|
}
|
||||||
if err == nil && (name == "ai" || name == "") {
|
if err == nil && (name == "ai" || name == "") {
|
||||||
if !rt.required["ai"] {
|
if !rt.required["ai"] {
|
||||||
rt.required["ai"] = true
|
rt.required["ai"] = true
|
||||||
aiList := make(map[string]any)
|
err = rt.vm.Set("ai", js.RequireAI())
|
||||||
for name, lm := range llm.List() {
|
|
||||||
aiList[name] = js.RequireAI(lm)
|
|
||||||
}
|
|
||||||
err = rt.vm.Set("ai", aiList)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
@ -139,7 +159,9 @@ func (rt *Runtime) makeImport(matcher *regexp.Regexp, code string) (string, int,
|
|||||||
|
|
||||||
func New() *Runtime {
|
func New() *Runtime {
|
||||||
vm := goja.New()
|
vm := goja.New()
|
||||||
vm.GoData = map[string]any{}
|
vm.GoData = map[string]any{
|
||||||
|
"logger": log.New(u.ShortUniqueId()),
|
||||||
|
}
|
||||||
return &Runtime{
|
return &Runtime{
|
||||||
vm: vm,
|
vm: vm,
|
||||||
required: map[string]bool{},
|
required: map[string]bool{},
|
||||||
@ -216,6 +238,7 @@ func (rt *Runtime) StartFromCode(code, refFile string) (any, error) {
|
|||||||
}
|
}
|
||||||
modCode, _, _ = rt.makeImport(importLibMatcher, modCode)
|
modCode, _, _ = rt.makeImport(importLibMatcher, modCode)
|
||||||
modCode, _, _ = rt.makeImport(requireLibMatcher, modCode)
|
modCode, _, _ = rt.makeImport(requireLibMatcher, modCode)
|
||||||
|
modCode = importModMatcher.ReplaceAllString(modCode, "let $1 = require('$2')")
|
||||||
return []byte(modCode), modErr
|
return []byte(modCode), modErr
|
||||||
}).Enable(rt.vm)
|
}).Enable(rt.vm)
|
||||||
|
|
||||||
@ -298,10 +321,108 @@ func ExportForDev() (string, error) {
|
|||||||
_ = u.WriteFile(filepath.Join("lib", "file.ts"), fileTS)
|
_ = u.WriteFile(filepath.Join("lib", "file.ts"), fileTS)
|
||||||
_ = u.WriteFile(filepath.Join("lib", "util.ts"), utilTS)
|
_ = u.WriteFile(filepath.Join("lib", "util.ts"), utilTS)
|
||||||
_ = u.WriteFile(filepath.Join("lib", "http.ts"), httpTS)
|
_ = u.WriteFile(filepath.Join("lib", "http.ts"), httpTS)
|
||||||
|
_ = u.WriteFile(filepath.Join("lib", "log.ts"), logTS)
|
||||||
|
_ = u.WriteFile(filepath.Join("lib", "db.ts"), dbTS)
|
||||||
|
|
||||||
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 log from './lib/log'
|
||||||
import util from './lib/util'
|
import util from './lib/util'
|
||||||
import http from './lib/http'
|
import http from './lib/http'
|
||||||
|
import db from './lib/db'
|
||||||
import file from './lib/file'`, nil
|
import file from './lib/file'`, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//func RunFile(file string, args ...any) (any, error) {
|
||||||
|
// return Run(u.ReadFileN(file), file, args...)
|
||||||
|
//}
|
||||||
|
|
||||||
|
type WatchRunner struct {
|
||||||
|
w *watcher.Watcher
|
||||||
|
}
|
||||||
|
|
||||||
|
func (wr *WatchRunner) WaitForKill() {
|
||||||
|
exitCh := make(chan os.Signal, 1)
|
||||||
|
closeCh := make(chan bool, 1)
|
||||||
|
signal.Notify(exitCh, os.Interrupt, syscall.SIGTERM, syscall.SIGINT, syscall.SIGHUP)
|
||||||
|
go func() {
|
||||||
|
<-exitCh
|
||||||
|
closeCh <- true
|
||||||
|
}()
|
||||||
|
<-closeCh
|
||||||
|
wr.w.Stop()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (wr *WatchRunner) Stop() {
|
||||||
|
wr.w.Stop()
|
||||||
|
}
|
||||||
|
|
||||||
|
func WatchRun(file string, extDirs, extTypes []string, args ...any) (*WatchRunner, error) {
|
||||||
|
wr := &WatchRunner{}
|
||||||
|
run := func() {
|
||||||
|
rt := New()
|
||||||
|
if wr.w != nil {
|
||||||
|
rt.SetModuleLoader(func(filename string) string {
|
||||||
|
filePath := filepath.Dir(filename)
|
||||||
|
needWatch := true
|
||||||
|
for _, v := range wr.w.WatchList() {
|
||||||
|
if v == filePath {
|
||||||
|
needWatch = false
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if needWatch {
|
||||||
|
fmt.Println(u.BMagenta("[watching module path]"), filePath)
|
||||||
|
_ = wr.w.Add(filePath)
|
||||||
|
}
|
||||||
|
return u.ReadFileN(filename)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
_, err := rt.StartFromFile(file)
|
||||||
|
result, err := rt.RunMain(args...)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(u.BRed(err.Error()))
|
||||||
|
fmt.Println(u.Red(" " + strings.Join(rt.GetCallStack(), "\n ")))
|
||||||
|
} else if result != nil {
|
||||||
|
fmt.Println(u.Cyan(u.JsonP(result)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var isWaitingRun = false
|
||||||
|
onChange := func(filename string, event string) {
|
||||||
|
if !isWaitingRun {
|
||||||
|
_, _ = os.Stdout.WriteString("\x1b[3;J\x1b[H\x1b[2J")
|
||||||
|
isWaitingRun = true
|
||||||
|
go func() {
|
||||||
|
time.Sleep(time.Millisecond * 10)
|
||||||
|
isWaitingRun = false
|
||||||
|
run()
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
fmt.Println(u.BYellow("[changed]"), filename)
|
||||||
|
}
|
||||||
|
_, _ = os.Stdout.WriteString("\x1b[3;J\x1b[H\x1b[2J")
|
||||||
|
watchStartPath := filepath.Dir(file)
|
||||||
|
fmt.Println(u.BMagenta("[watching root path]"), watchStartPath)
|
||||||
|
watchDirs := []string{watchStartPath}
|
||||||
|
watchTypes := []string{"js", "json", "yml"}
|
||||||
|
if extDirs != nil {
|
||||||
|
for _, v := range extDirs {
|
||||||
|
watchDirs = append(watchDirs, v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if extTypes != nil {
|
||||||
|
for _, v := range extTypes {
|
||||||
|
watchTypes = append(watchTypes, v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if w, err := watcher.Start(watchDirs, watchTypes, onChange); err == nil {
|
||||||
|
wr.w = w
|
||||||
|
go func() {
|
||||||
|
run()
|
||||||
|
}()
|
||||||
|
return wr, nil
|
||||||
|
} else {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
136
js/ai.go
136
js/ai.go
@ -2,121 +2,136 @@ package js
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"apigo.cc/ai/ai/goja"
|
"apigo.cc/ai/ai/goja"
|
||||||
"apigo.cc/ai/ai/llm"
|
"apigo.cc/ai/ai/interface/llm"
|
||||||
"github.com/ssgo/u"
|
"github.com/ssgo/u"
|
||||||
"reflect"
|
"reflect"
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
type ChatResult struct {
|
func RequireAI() map[string]any {
|
||||||
llm.TokenUsage
|
aiObj := map[string]any{
|
||||||
Result string
|
"similarity": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
|
||||||
Error string
|
args := MakeArgs(&argsIn, vm).Check(2)
|
||||||
|
return vm.ToValue(llm.Similarity(args.Bytes(0), args.Bytes(1)))
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for name, lm := range llm.List() {
|
||||||
|
aiObj[name] = RequireLLM(lm)
|
||||||
|
}
|
||||||
|
return aiObj
|
||||||
}
|
}
|
||||||
|
|
||||||
type AIGCResult struct {
|
func RequireLLM(lm llm.LLM) map[string]any {
|
||||||
Result string
|
|
||||||
Preview string
|
|
||||||
Results []string
|
|
||||||
Previews []string
|
|
||||||
Error string
|
|
||||||
}
|
|
||||||
|
|
||||||
func RequireAI(lm llm.LLM) map[string]any {
|
|
||||||
return map[string]any{
|
return map[string]any{
|
||||||
"ask": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
|
"ask": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
|
||||||
args := MakeArgs(&argsIn, vm).Check(1)
|
args := MakeArgs(&argsIn, vm).Check(1)
|
||||||
conf, cb := getAskArgs(args.This, vm, args.Arguments)
|
conf, cb := getAskArgs(args.This, vm, args.Arguments)
|
||||||
result, usage, err := lm.Ask(makeChatMessages(args.Arguments), conf, cb)
|
result, usage, err := lm.Ask(makeChatMessages(args.Arguments), conf, cb)
|
||||||
return vm.ToValue(map[string]any{"tokenUsage": toMap(usage), "result": result, "error": getErrorStr(err)})
|
return makeChatResult(vm, result, &usage, err)
|
||||||
},
|
},
|
||||||
"fastAsk": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
|
"fastAsk": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
|
||||||
args := MakeArgs(&argsIn, vm).Check(1)
|
args := MakeArgs(&argsIn, vm).Check(1)
|
||||||
_, cb := getAskArgs(args.This, vm, args.Arguments)
|
_, cb := getAskArgs(args.This, vm, args.Arguments)
|
||||||
result, usage, err := lm.FastAsk(makeChatMessages(args.Arguments), cb)
|
result, usage, err := lm.FastAsk(makeChatMessages(args.Arguments), cb)
|
||||||
return vm.ToValue(map[string]any{"tokenUsage": toMap(usage), "result": result, "error": getErrorStr(err)})
|
return makeChatResult(vm, result, &usage, err)
|
||||||
},
|
},
|
||||||
"longAsk": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
|
"longAsk": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
|
||||||
args := MakeArgs(&argsIn, vm).Check(1)
|
args := MakeArgs(&argsIn, vm).Check(1)
|
||||||
_, cb := getAskArgs(args.This, vm, args.Arguments)
|
_, cb := getAskArgs(args.This, vm, args.Arguments)
|
||||||
result, usage, err := lm.LongAsk(makeChatMessages(args.Arguments), cb)
|
result, usage, err := lm.LongAsk(makeChatMessages(args.Arguments), cb)
|
||||||
return vm.ToValue(map[string]any{"tokenUsage": toMap(usage), "result": result, "error": getErrorStr(err)})
|
return makeChatResult(vm, result, &usage, err)
|
||||||
},
|
},
|
||||||
"batterAsk": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
|
"batterAsk": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
|
||||||
args := MakeArgs(&argsIn, vm).Check(1)
|
args := MakeArgs(&argsIn, vm).Check(1)
|
||||||
_, cb := getAskArgs(args.This, vm, args.Arguments)
|
_, cb := getAskArgs(args.This, vm, args.Arguments)
|
||||||
result, usage, err := lm.BatterAsk(makeChatMessages(args.Arguments), cb)
|
result, usage, err := lm.BatterAsk(makeChatMessages(args.Arguments), cb)
|
||||||
return vm.ToValue(map[string]any{"tokenUsage": toMap(usage), "result": result, "error": getErrorStr(err)})
|
return makeChatResult(vm, result, &usage, err)
|
||||||
},
|
},
|
||||||
"bestAsk": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
|
"bestAsk": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
|
||||||
args := MakeArgs(&argsIn, vm).Check(1)
|
args := MakeArgs(&argsIn, vm).Check(1)
|
||||||
_, cb := getAskArgs(args.This, vm, args.Arguments)
|
_, cb := getAskArgs(args.This, vm, args.Arguments)
|
||||||
result, usage, err := lm.BestAsk(makeChatMessages(args.Arguments), cb)
|
result, usage, err := lm.BestAsk(makeChatMessages(args.Arguments), cb)
|
||||||
return vm.ToValue(map[string]any{"tokenUsage": toMap(usage), "result": result, "error": getErrorStr(err)})
|
return makeChatResult(vm, result, &usage, err)
|
||||||
},
|
},
|
||||||
|
|
||||||
"multiAsk": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
|
"multiAsk": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
|
||||||
args := MakeArgs(&argsIn, vm).Check(1)
|
args := MakeArgs(&argsIn, vm).Check(1)
|
||||||
_, cb := getAskArgs(args.This, vm, args.Arguments)
|
_, cb := getAskArgs(args.This, vm, args.Arguments)
|
||||||
result, usage, err := lm.MultiAsk(makeChatMessages(args.Arguments), cb)
|
result, usage, err := lm.MultiAsk(makeChatMessages(args.Arguments), cb)
|
||||||
return vm.ToValue(map[string]any{"tokenUsage": toMap(usage), "result": result, "error": getErrorStr(err)})
|
return makeChatResult(vm, result, &usage, err)
|
||||||
},
|
},
|
||||||
"bestMultiAsk": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
|
"bestMultiAsk": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
|
||||||
args := MakeArgs(&argsIn, vm).Check(1)
|
args := MakeArgs(&argsIn, vm).Check(1)
|
||||||
_, cb := getAskArgs(args.This, vm, args.Arguments)
|
_, cb := getAskArgs(args.This, vm, args.Arguments)
|
||||||
result, usage, err := lm.BestMultiAsk(makeChatMessages(args.Arguments), cb)
|
result, usage, err := lm.BestMultiAsk(makeChatMessages(args.Arguments), cb)
|
||||||
return vm.ToValue(map[string]any{"tokenUsage": toMap(usage), "result": result, "error": getErrorStr(err)})
|
return makeChatResult(vm, result, &usage, err)
|
||||||
},
|
},
|
||||||
|
|
||||||
"codeInterpreterAsk": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
|
"codeInterpreterAsk": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
|
||||||
args := MakeArgs(&argsIn, vm).Check(1)
|
args := MakeArgs(&argsIn, vm).Check(1)
|
||||||
_, cb := getAskArgs(args.This, vm, args.Arguments)
|
_, cb := getAskArgs(args.This, vm, args.Arguments)
|
||||||
result, usage, err := lm.CodeInterpreterAsk(makeChatMessages(args.Arguments), cb)
|
result, usage, err := lm.CodeInterpreterAsk(makeChatMessages(args.Arguments), cb)
|
||||||
return vm.ToValue(map[string]any{"tokenUsage": toMap(usage), "result": result, "error": getErrorStr(err)})
|
return makeChatResult(vm, result, &usage, err)
|
||||||
},
|
},
|
||||||
"webSearchAsk": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
|
"webSearchAsk": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
|
||||||
args := MakeArgs(&argsIn, vm).Check(1)
|
args := MakeArgs(&argsIn, vm).Check(1)
|
||||||
_, cb := getAskArgs(args.This, vm, args.Arguments)
|
_, cb := getAskArgs(args.This, vm, args.Arguments)
|
||||||
result, usage, err := lm.WebSearchAsk(makeChatMessages(args.Arguments), cb)
|
result, usage, err := lm.WebSearchAsk(makeChatMessages(args.Arguments), cb)
|
||||||
return vm.ToValue(map[string]any{"tokenUsage": toMap(usage), "result": result, "error": getErrorStr(err)})
|
return makeChatResult(vm, result, &usage, err)
|
||||||
},
|
},
|
||||||
|
|
||||||
"makeImage": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
|
"makeImage": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
|
||||||
args := MakeArgs(&argsIn, vm).Check(1)
|
args := MakeArgs(&argsIn, vm).Check(1)
|
||||||
prompt, conf := getAIGCArgs(args.Arguments)
|
prompt, conf := getGCArgs(args.Arguments)
|
||||||
results, err := lm.MakeImage(prompt, conf)
|
results, usage, err := lm.MakeImage(prompt, conf)
|
||||||
return makeAIGCResult(vm, results, nil, err)
|
return makeGCResult(vm, results, nil, &usage, err)
|
||||||
},
|
},
|
||||||
"fastMakeImage": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
|
"fastMakeImage": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
|
||||||
args := MakeArgs(&argsIn, vm).Check(1)
|
args := MakeArgs(&argsIn, vm).Check(1)
|
||||||
prompt, conf := getAIGCArgs(args.Arguments)
|
prompt, conf := getGCArgs(args.Arguments)
|
||||||
results, err := lm.FastMakeImage(prompt, conf)
|
results, usage, err := lm.FastMakeImage(prompt, conf)
|
||||||
return makeAIGCResult(vm, results, nil, err)
|
return makeGCResult(vm, results, nil, &usage, err)
|
||||||
},
|
},
|
||||||
"bestMakeImage": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
|
"bestMakeImage": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
|
||||||
args := MakeArgs(&argsIn, vm).Check(1)
|
args := MakeArgs(&argsIn, vm).Check(1)
|
||||||
prompt, conf := getAIGCArgs(args.Arguments)
|
prompt, conf := getGCArgs(args.Arguments)
|
||||||
results, err := lm.BestMakeImage(prompt, conf)
|
results, usage, err := lm.BestMakeImage(prompt, conf)
|
||||||
return makeAIGCResult(vm, results, nil, err)
|
return makeGCResult(vm, results, nil, &usage, err)
|
||||||
},
|
},
|
||||||
|
|
||||||
"makeVideo": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
|
"makeVideo": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
|
||||||
args := MakeArgs(&argsIn, vm).Check(1)
|
args := MakeArgs(&argsIn, vm).Check(1)
|
||||||
prompt, conf := getAIGCArgs(args.Arguments)
|
prompt, conf := getGCArgs(args.Arguments)
|
||||||
results, previews, err := lm.MakeVideo(prompt, conf)
|
results, previews, usage, err := lm.MakeVideo(prompt, conf)
|
||||||
return makeAIGCResult(vm, results, previews, err)
|
return makeGCResult(vm, results, previews, &usage, err)
|
||||||
},
|
},
|
||||||
"fastMakeVideo": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
|
"fastMakeVideo": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
|
||||||
args := MakeArgs(&argsIn, vm).Check(1)
|
args := MakeArgs(&argsIn, vm).Check(1)
|
||||||
prompt, conf := getAIGCArgs(args.Arguments)
|
prompt, conf := getGCArgs(args.Arguments)
|
||||||
results, previews, err := lm.FastMakeVideo(prompt, conf)
|
results, previews, usage, err := lm.FastMakeVideo(prompt, conf)
|
||||||
return makeAIGCResult(vm, results, previews, err)
|
return makeGCResult(vm, results, previews, &usage, err)
|
||||||
},
|
},
|
||||||
"bestMakeVideo": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
|
"bestMakeVideo": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
|
||||||
args := MakeArgs(&argsIn, vm).Check(1)
|
args := MakeArgs(&argsIn, vm).Check(1)
|
||||||
prompt, conf := getAIGCArgs(args.Arguments)
|
prompt, conf := getGCArgs(args.Arguments)
|
||||||
results, previews, err := lm.BestMakeVideo(prompt, conf)
|
results, previews, usage, err := lm.BestMakeVideo(prompt, conf)
|
||||||
return makeAIGCResult(vm, results, previews, err)
|
return makeGCResult(vm, results, previews, &usage, err)
|
||||||
|
},
|
||||||
|
|
||||||
|
"embedding": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
|
||||||
|
args := MakeArgs(&argsIn, vm).Check(2)
|
||||||
|
results, usage, err := lm.Embedding(args.Str(0), args.Str(1))
|
||||||
|
return makeEmbeddingResult(vm, results, &usage, err)
|
||||||
|
},
|
||||||
|
"fastEmbedding": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
|
||||||
|
args := MakeArgs(&argsIn, vm).Check(1)
|
||||||
|
results, usage, err := lm.FastEmbedding(args.Str(0))
|
||||||
|
return makeEmbeddingResult(vm, results, &usage, err)
|
||||||
|
},
|
||||||
|
"bestEmbedding": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
|
||||||
|
args := MakeArgs(&argsIn, vm).Check(1)
|
||||||
|
results, usage, err := lm.BestEmbedding(args.Str(0))
|
||||||
|
return makeEmbeddingResult(vm, results, &usage, err)
|
||||||
},
|
},
|
||||||
|
|
||||||
"support": lm.Support(),
|
"support": lm.Support(),
|
||||||
@ -130,7 +145,36 @@ func getErrorStr(err error) string {
|
|||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
func makeAIGCResult(vm *goja.Runtime, results []string, previews []string, err error) goja.Value {
|
func makeChatResult(vm *goja.Runtime, result string, usage *llm.Usage, err error) goja.Value {
|
||||||
|
if err != nil {
|
||||||
|
panic(vm.NewGoError(err))
|
||||||
|
}
|
||||||
|
return vm.ToValue(map[string]any{
|
||||||
|
"result": result,
|
||||||
|
"askTokens": usage.AskTokens,
|
||||||
|
"answerTokens": usage.AnswerTokens,
|
||||||
|
"totalTokens": usage.TotalTokens,
|
||||||
|
"usedTime": usage.UsedTime,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func makeEmbeddingResult(vm *goja.Runtime, result []byte, usage *llm.Usage, err error) goja.Value {
|
||||||
|
if err != nil {
|
||||||
|
panic(vm.NewGoError(err))
|
||||||
|
}
|
||||||
|
return vm.ToValue(map[string]any{
|
||||||
|
"result": result,
|
||||||
|
"askTokens": usage.AskTokens,
|
||||||
|
"answerTokens": usage.AnswerTokens,
|
||||||
|
"totalTokens": usage.TotalTokens,
|
||||||
|
"usedTime": usage.UsedTime,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func makeGCResult(vm *goja.Runtime, results []string, previews []string, usage *llm.Usage, err error) goja.Value {
|
||||||
|
if err != nil {
|
||||||
|
panic(vm.NewGoError(err))
|
||||||
|
}
|
||||||
result := ""
|
result := ""
|
||||||
preview := ""
|
preview := ""
|
||||||
if len(results) > 0 {
|
if len(results) > 0 {
|
||||||
@ -148,11 +192,11 @@ func makeAIGCResult(vm *goja.Runtime, results []string, previews []string, err e
|
|||||||
"preview": preview,
|
"preview": preview,
|
||||||
"results": results,
|
"results": results,
|
||||||
"previews": previews,
|
"previews": previews,
|
||||||
"error": getErrorStr(err),
|
"usedTime": usage.UsedTime,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func getAIGCArgs(args []goja.Value) (string, llm.GCConfig) {
|
func getGCArgs(args []goja.Value) (string, llm.GCConfig) {
|
||||||
prompt := ""
|
prompt := ""
|
||||||
var config llm.GCConfig
|
var config llm.GCConfig
|
||||||
if len(args) > 0 {
|
if len(args) > 0 {
|
||||||
@ -173,7 +217,7 @@ func getAskArgs(thisArg goja.Value, vm *goja.Runtime, args []goja.Value) (llm.Ch
|
|||||||
callback = func(answer string) {
|
callback = func(answer string) {
|
||||||
_, _ = cb(thisArg, vm.ToValue(answer))
|
_, _ = cb(thisArg, vm.ToValue(answer))
|
||||||
}
|
}
|
||||||
} else {
|
} else if args[i].ExportType() != nil {
|
||||||
switch args[i].ExportType().Kind() {
|
switch args[i].ExportType().Kind() {
|
||||||
case reflect.Map, reflect.Struct:
|
case reflect.Map, reflect.Struct:
|
||||||
u.Convert(args[i].Export(), &chatConfig)
|
u.Convert(args[i].Export(), &chatConfig)
|
||||||
@ -192,6 +236,7 @@ func makeChatMessages(args []goja.Value) []llm.ChatMessage {
|
|||||||
v := args[0].Export()
|
v := args[0].Export()
|
||||||
vv := reflect.ValueOf(v)
|
vv := reflect.ValueOf(v)
|
||||||
t := args[0].ExportType()
|
t := args[0].ExportType()
|
||||||
|
if t != nil {
|
||||||
lastRoleIsUser := false
|
lastRoleIsUser := false
|
||||||
switch t.Kind() {
|
switch t.Kind() {
|
||||||
// 数组,根据成员类型处理
|
// 数组,根据成员类型处理
|
||||||
@ -260,6 +305,7 @@ func makeChatMessages(args []goja.Value) []llm.ChatMessage {
|
|||||||
out = append(out, llm.ChatMessage{Role: llm.RoleUser, Contents: []llm.ChatMessageContent{makeChatMessageContent(u.String(v))}})
|
out = append(out, llm.ChatMessage{Role: llm.RoleUser, Contents: []llm.ChatMessageContent{makeChatMessageContent(u.String(v))}})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return out
|
return out
|
||||||
}
|
}
|
||||||
|
|
||||||
|
54
js/common.go
54
js/common.go
@ -7,9 +7,9 @@ import (
|
|||||||
"path/filepath"
|
"path/filepath"
|
||||||
)
|
)
|
||||||
|
|
||||||
func toMap(data any) map[string]any {
|
//func toMap(data any) map[string]any {
|
||||||
return u.UnJsonMap(u.FixedJson(data))
|
// return u.UnJsonMap(u.FixedJson(data))
|
||||||
}
|
//}
|
||||||
|
|
||||||
type Args struct {
|
type Args struct {
|
||||||
This goja.Value
|
This goja.Value
|
||||||
@ -39,6 +39,13 @@ func (args *Args) Int(index int) int {
|
|||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (args *Args) Int64(index int) int64 {
|
||||||
|
if len(args.Arguments) > index {
|
||||||
|
return u.Int64(args.Arguments[index].Export())
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
func (args *Args) Any(index int) any {
|
func (args *Args) Any(index int) any {
|
||||||
if len(args.Arguments) > index {
|
if len(args.Arguments) > index {
|
||||||
return args.Arguments[index].Export()
|
return args.Arguments[index].Export()
|
||||||
@ -53,6 +60,20 @@ func (args *Args) Str(index int) string {
|
|||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (args *Args) Bytes(index int) []byte {
|
||||||
|
if len(args.Arguments) > index {
|
||||||
|
return u.Bytes(args.Arguments[index].Export())
|
||||||
|
}
|
||||||
|
return []byte{}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (args *Args) Bool(index int) bool {
|
||||||
|
if len(args.Arguments) > index {
|
||||||
|
return u.Bool(args.Arguments[index].Export())
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
func (args *Args) Map(index int) map[string]any {
|
func (args *Args) Map(index int) map[string]any {
|
||||||
out := map[string]any{}
|
out := map[string]any{}
|
||||||
if len(args.Arguments) > index {
|
if len(args.Arguments) > index {
|
||||||
@ -72,6 +93,17 @@ func (args *Args) StrArr(startIndex int) []string {
|
|||||||
return make([]string, 0)
|
return make([]string, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (args *Args) Arr(startIndex int) []any {
|
||||||
|
if len(args.Arguments) > startIndex {
|
||||||
|
a := make([]any, len(args.Arguments)-startIndex)
|
||||||
|
for index := startIndex; index < len(args.Arguments); index++ {
|
||||||
|
a[index-startIndex] = u.String(args.Arguments[index].Export())
|
||||||
|
}
|
||||||
|
return a
|
||||||
|
}
|
||||||
|
return make([]any, 0)
|
||||||
|
}
|
||||||
|
|
||||||
func (args *Args) Map2StrArr(index int) []string {
|
func (args *Args) Map2StrArr(index int) []string {
|
||||||
headerMap := args.Map(index)
|
headerMap := args.Map(index)
|
||||||
headers := make([]string, len(headerMap)*2)
|
headers := make([]string, len(headerMap)*2)
|
||||||
@ -84,6 +116,18 @@ func (args *Args) Map2StrArr(index int) []string {
|
|||||||
return headers
|
return headers
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (args *Args) Map2Arr(index int) []any {
|
||||||
|
arrMap := args.Map(index)
|
||||||
|
arr := make([]any, len(arrMap)*2)
|
||||||
|
i := 0
|
||||||
|
for k, v := range arrMap {
|
||||||
|
arr[i] = k
|
||||||
|
arr[i+1] = u.String(v)
|
||||||
|
i += 2
|
||||||
|
}
|
||||||
|
return arr
|
||||||
|
}
|
||||||
|
|
||||||
func findPath(vm *goja.Runtime, filename string) string {
|
func findPath(vm *goja.Runtime, filename string) string {
|
||||||
if u.FileExists(filename) {
|
if u.FileExists(filename) {
|
||||||
return filename
|
return filename
|
||||||
@ -99,3 +143,7 @@ func findPath(vm *goja.Runtime, filename string) string {
|
|||||||
}
|
}
|
||||||
return filename
|
return filename
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (args *Args) Path(index int) string {
|
||||||
|
return findPath(args.VM, args.Str(index))
|
||||||
|
}
|
||||||
|
@ -4,6 +4,7 @@ import (
|
|||||||
"apigo.cc/ai/ai/goja"
|
"apigo.cc/ai/ai/goja"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/ssgo/u"
|
"github.com/ssgo/u"
|
||||||
|
"reflect"
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -43,19 +44,106 @@ func RequireConsole() map[string]any {
|
|||||||
_, _ = fmt.Scanln(&line)
|
_, _ = fmt.Scanln(&line)
|
||||||
return vm.ToValue(line)
|
return vm.ToValue(line)
|
||||||
},
|
},
|
||||||
|
"black": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
|
||||||
|
args := MakeArgs(&argsIn, vm)
|
||||||
|
return vm.ToValue(u.Black(fmt.Sprint(args.Arr(0)...)))
|
||||||
|
},
|
||||||
|
"red": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
|
||||||
|
args := MakeArgs(&argsIn, vm)
|
||||||
|
return vm.ToValue(u.Red(fmt.Sprint(args.Arr(0)...)))
|
||||||
|
},
|
||||||
|
"green": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
|
||||||
|
args := MakeArgs(&argsIn, vm)
|
||||||
|
return vm.ToValue(u.Green(fmt.Sprint(args.Arr(0)...)))
|
||||||
|
},
|
||||||
|
"yellow": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
|
||||||
|
args := MakeArgs(&argsIn, vm)
|
||||||
|
return vm.ToValue(u.Yellow(fmt.Sprint(args.Arr(0)...)))
|
||||||
|
},
|
||||||
|
"blue": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
|
||||||
|
args := MakeArgs(&argsIn, vm)
|
||||||
|
return vm.ToValue(u.Blue(fmt.Sprint(args.Arr(0)...)))
|
||||||
|
},
|
||||||
|
"magenta": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
|
||||||
|
args := MakeArgs(&argsIn, vm)
|
||||||
|
return vm.ToValue(u.Magenta(fmt.Sprint(args.Arr(0)...)))
|
||||||
|
},
|
||||||
|
"cyan": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
|
||||||
|
args := MakeArgs(&argsIn, vm)
|
||||||
|
return vm.ToValue(u.Cyan(fmt.Sprint(args.Arr(0)...)))
|
||||||
|
},
|
||||||
|
"white": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
|
||||||
|
args := MakeArgs(&argsIn, vm)
|
||||||
|
return vm.ToValue(u.White(fmt.Sprint(args.Arr(0)...)))
|
||||||
|
},
|
||||||
|
"dim": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
|
||||||
|
args := MakeArgs(&argsIn, vm)
|
||||||
|
return vm.ToValue(u.Dim(fmt.Sprint(args.Arr(0)...)))
|
||||||
|
},
|
||||||
|
"italic": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
|
||||||
|
args := MakeArgs(&argsIn, vm)
|
||||||
|
return vm.ToValue(u.Italic(fmt.Sprint(args.Arr(0)...)))
|
||||||
|
},
|
||||||
|
"bBlack": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
|
||||||
|
args := MakeArgs(&argsIn, vm)
|
||||||
|
return vm.ToValue(u.BBlack(fmt.Sprint(args.Arr(0)...)))
|
||||||
|
},
|
||||||
|
"bRed": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
|
||||||
|
args := MakeArgs(&argsIn, vm)
|
||||||
|
return vm.ToValue(u.BRed(fmt.Sprint(args.Arr(0)...)))
|
||||||
|
},
|
||||||
|
"bGreen": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
|
||||||
|
args := MakeArgs(&argsIn, vm)
|
||||||
|
return vm.ToValue(u.BGreen(fmt.Sprint(args.Arr(0)...)))
|
||||||
|
},
|
||||||
|
"bYellow": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
|
||||||
|
args := MakeArgs(&argsIn, vm)
|
||||||
|
return vm.ToValue(u.BYellow(fmt.Sprint(args.Arr(0)...)))
|
||||||
|
},
|
||||||
|
"bBlue": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
|
||||||
|
args := MakeArgs(&argsIn, vm)
|
||||||
|
return vm.ToValue(u.BBlue(fmt.Sprint(args.Arr(0)...)))
|
||||||
|
},
|
||||||
|
"bMagenta": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
|
||||||
|
args := MakeArgs(&argsIn, vm)
|
||||||
|
return vm.ToValue(u.BMagenta(fmt.Sprint(args.Arr(0)...)))
|
||||||
|
},
|
||||||
|
"bCyan": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
|
||||||
|
args := MakeArgs(&argsIn, vm)
|
||||||
|
return vm.ToValue(u.BCyan(fmt.Sprint(args.Arr(0)...)))
|
||||||
|
},
|
||||||
|
"bWhite": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
|
||||||
|
args := MakeArgs(&argsIn, vm)
|
||||||
|
return vm.ToValue(u.BWhite(fmt.Sprint(args.Arr(0)...)))
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func consolePrint(args goja.FunctionCall, typ string, vm *goja.Runtime) {
|
func consolePrint(args goja.FunctionCall, typ string, vm *goja.Runtime) {
|
||||||
arr := make([]any, len(args.Arguments))
|
arr := make([]any, len(args.Arguments))
|
||||||
textColor := u.TextNone
|
textColor := u.TextNone
|
||||||
|
bgColor := u.BgNone
|
||||||
switch typ {
|
switch typ {
|
||||||
case "info":
|
case "info":
|
||||||
textColor = u.TextCyan
|
textColor = u.TextCyan
|
||||||
|
bgColor = u.BgCyan
|
||||||
case "warn":
|
case "warn":
|
||||||
textColor = u.TextYellow
|
textColor = u.TextYellow
|
||||||
|
bgColor = u.BgYellow
|
||||||
case "error":
|
case "error":
|
||||||
textColor = u.TextRed
|
textColor = u.TextRed
|
||||||
|
bgColor = u.BgRed
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(args.Arguments) == 1 && args.Argument(0).ExportType().Kind() == reflect.Map {
|
||||||
|
ex := args.Argument(0).ToObject(vm)
|
||||||
|
message := ex.Get("message")
|
||||||
|
stack := ex.Get("stack")
|
||||||
|
if message != nil && stack != nil {
|
||||||
|
fmt.Println(u.Color(u.String(message.Export()), textColor, u.BgNone))
|
||||||
|
fmt.Println(u.Color(u.String(stack.Export()), u.TextWhite, bgColor))
|
||||||
|
return
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for i, arg := range args.Arguments {
|
for i, arg := range args.Arguments {
|
||||||
@ -69,7 +157,7 @@ func consolePrint(args goja.FunctionCall, typ string, vm *goja.Runtime) {
|
|||||||
if (typ == "warn" || typ == "error" || typ == "debug") && vm != nil {
|
if (typ == "warn" || typ == "error" || typ == "debug") && vm != nil {
|
||||||
callStacks := make([]string, 0)
|
callStacks := make([]string, 0)
|
||||||
for _, stack := range vm.CaptureCallStack(0, nil) {
|
for _, stack := range vm.CaptureCallStack(0, nil) {
|
||||||
callStacks = append(callStacks, u.Color(" "+stack.Position().String(), textColor, u.BgNone))
|
callStacks = append(callStacks, u.Color(" "+stack.Position().String(), u.TextWhite, bgColor))
|
||||||
}
|
}
|
||||||
fmt.Println(arr...)
|
fmt.Println(arr...)
|
||||||
fmt.Println(strings.Join(callStacks, "\n"))
|
fmt.Println(strings.Join(callStacks, "\n"))
|
||||||
|
214
js/db.go
Normal file
214
js/db.go
Normal file
@ -0,0 +1,214 @@
|
|||||||
|
package js
|
||||||
|
|
||||||
|
import (
|
||||||
|
"apigo.cc/ai/ai/goja"
|
||||||
|
"github.com/ssgo/dao/dao"
|
||||||
|
"github.com/ssgo/db"
|
||||||
|
"github.com/ssgo/log"
|
||||||
|
"github.com/ssgo/u"
|
||||||
|
)
|
||||||
|
|
||||||
|
func RequireDB() map[string]any {
|
||||||
|
return map[string]any{
|
||||||
|
"get": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
|
||||||
|
args := MakeArgs(&argsIn, vm).Check(1)
|
||||||
|
conn := db.GetDB(args.Str(0), getLogger(vm))
|
||||||
|
return vm.ToValue(makeDBObject(conn, nil, vm))
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func makeDBObject(conn *db.DB, tx *db.Tx, vm *goja.Runtime) map[string]any {
|
||||||
|
obj := map[string]any{
|
||||||
|
"conn": conn,
|
||||||
|
"tx": tx,
|
||||||
|
"query": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
|
||||||
|
args, conn, tx, _ := initDBArgs(argsIn, vm, 1)
|
||||||
|
var r *db.QueryResult
|
||||||
|
if tx != nil {
|
||||||
|
r = tx.Query(args.Str(0), args.Arr(1)...)
|
||||||
|
} else {
|
||||||
|
r = conn.Query(args.Str(0), args.Arr(1)...)
|
||||||
|
}
|
||||||
|
if r.Error == nil {
|
||||||
|
return vm.ToValue(makeQueryResult(r, r.MapResults()))
|
||||||
|
} else {
|
||||||
|
panic(vm.NewGoError(r.Error))
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"query1": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
|
||||||
|
args, conn, tx, _ := initDBArgs(argsIn, vm, 1)
|
||||||
|
var r *db.QueryResult
|
||||||
|
if tx != nil {
|
||||||
|
r = tx.Query(args.Str(0), args.Arr(1)...)
|
||||||
|
} else {
|
||||||
|
r = conn.Query(args.Str(0), args.Arr(1)...)
|
||||||
|
}
|
||||||
|
if r.Error == nil {
|
||||||
|
return vm.ToValue(makeQueryResult(r, r.MapOnR1()))
|
||||||
|
} else {
|
||||||
|
panic(vm.NewGoError(r.Error))
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"query11": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
|
||||||
|
args, conn, tx, _ := initDBArgs(argsIn, vm, 1)
|
||||||
|
var r *db.QueryResult
|
||||||
|
if tx != nil {
|
||||||
|
r = tx.Query(args.Str(0), args.Arr(1)...)
|
||||||
|
} else {
|
||||||
|
r = conn.Query(args.Str(0), args.Arr(1)...)
|
||||||
|
}
|
||||||
|
if r.Error == nil {
|
||||||
|
a := r.SliceResults()
|
||||||
|
if len(a) > 0 && len(a[0]) > 0 {
|
||||||
|
return vm.ToValue(makeQueryResult(r, a[0][0]))
|
||||||
|
}
|
||||||
|
return vm.ToValue(nil)
|
||||||
|
} else {
|
||||||
|
panic(vm.NewGoError(r.Error))
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"exec": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
|
||||||
|
args, conn, tx, _ := initDBArgs(argsIn, vm, 1)
|
||||||
|
var r *db.ExecResult
|
||||||
|
if tx != nil {
|
||||||
|
r = tx.Exec(args.Str(0), args.Arr(1)...)
|
||||||
|
} else {
|
||||||
|
r = conn.Exec(args.Str(0), args.Arr(1)...)
|
||||||
|
}
|
||||||
|
if r.Error == nil {
|
||||||
|
return vm.ToValue(makeExecResult(r))
|
||||||
|
} else {
|
||||||
|
panic(vm.NewGoError(r.Error))
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"insert": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
|
||||||
|
args, conn, tx, _ := initDBArgs(argsIn, vm, 2)
|
||||||
|
var r *db.ExecResult
|
||||||
|
if tx != nil {
|
||||||
|
r = tx.Insert(args.Str(0), args.Any(1))
|
||||||
|
} else {
|
||||||
|
r = conn.Insert(args.Str(0), args.Any(1))
|
||||||
|
}
|
||||||
|
if r.Error == nil {
|
||||||
|
return vm.ToValue(makeExecResult(r))
|
||||||
|
} else {
|
||||||
|
panic(vm.NewGoError(r.Error))
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"replace": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
|
||||||
|
args, conn, tx, _ := initDBArgs(argsIn, vm, 2)
|
||||||
|
var r *db.ExecResult
|
||||||
|
if tx != nil {
|
||||||
|
r = tx.Replace(args.Str(0), args.Any(1))
|
||||||
|
} else {
|
||||||
|
r = conn.Replace(args.Str(0), args.Any(1))
|
||||||
|
}
|
||||||
|
if r.Error == nil {
|
||||||
|
return vm.ToValue(makeExecResult(r))
|
||||||
|
} else {
|
||||||
|
panic(vm.NewGoError(r.Error))
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"update": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
|
||||||
|
args, conn, tx, _ := initDBArgs(argsIn, vm, 3)
|
||||||
|
var r *db.ExecResult
|
||||||
|
if tx != nil {
|
||||||
|
r = tx.Update(args.Str(0), args.Any(1), args.Str(2), args.Arr(3)...)
|
||||||
|
} else {
|
||||||
|
r = conn.Update(args.Str(0), args.Any(1), args.Str(2), args.Arr(3)...)
|
||||||
|
}
|
||||||
|
if r.Error == nil {
|
||||||
|
return vm.ToValue(makeExecResult(r))
|
||||||
|
} else {
|
||||||
|
panic(vm.NewGoError(r.Error))
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"delete": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
|
||||||
|
args, conn, tx, _ := initDBArgs(argsIn, vm, 2)
|
||||||
|
var r *db.ExecResult
|
||||||
|
if tx != nil {
|
||||||
|
r = tx.Delete(args.Str(0), args.Str(1), args.Arr(2)...)
|
||||||
|
} else {
|
||||||
|
r = conn.Delete(args.Str(0), args.Str(1), args.Arr(2)...)
|
||||||
|
}
|
||||||
|
if r.Error == nil {
|
||||||
|
return vm.ToValue(makeExecResult(r))
|
||||||
|
} else {
|
||||||
|
panic(vm.NewGoError(r.Error))
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
if conn != nil {
|
||||||
|
obj["make"] = func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
|
||||||
|
args, conn, _, logger := initDBArgs(argsIn, vm, 1)
|
||||||
|
arg0 := args.Str(0)
|
||||||
|
tryFile := findPath(vm, arg0)
|
||||||
|
if u.FileExists(tryFile) {
|
||||||
|
arg0 = u.ReadFileN(tryFile)
|
||||||
|
}
|
||||||
|
if err := dao.MakeDBFromDesc(conn, args.Str(0), logger); err == nil {
|
||||||
|
return nil
|
||||||
|
} else {
|
||||||
|
panic(vm.NewGoError(err))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
obj["destroy"] = func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
|
||||||
|
_, conn, _, _ := initDBArgs(argsIn, vm, 0)
|
||||||
|
if err := conn.Destroy(); err == nil {
|
||||||
|
return nil
|
||||||
|
} else {
|
||||||
|
panic(vm.NewGoError(err))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
obj["begin"] = func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
|
||||||
|
_, conn, _, _ := initDBArgs(argsIn, vm, 0)
|
||||||
|
return vm.ToValue(makeDBObject(nil, conn.Begin(), vm))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if tx != nil {
|
||||||
|
obj["end"] = func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
|
||||||
|
args, _, tx, _ := initDBArgs(argsIn, vm, 1)
|
||||||
|
if err := tx.Finish(args.Bool(0)); err != nil {
|
||||||
|
panic(vm.NewGoError(err))
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return obj
|
||||||
|
}
|
||||||
|
|
||||||
|
func makeQueryResult(r *db.QueryResult, result any) map[string]any {
|
||||||
|
return map[string]any{
|
||||||
|
"sql": *r.Sql,
|
||||||
|
"args": r.Args,
|
||||||
|
"result": result,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func makeExecResult(r *db.ExecResult) map[string]any {
|
||||||
|
return map[string]any{
|
||||||
|
"sql": *r.Sql,
|
||||||
|
"args": r.Args,
|
||||||
|
"id": r.Id(),
|
||||||
|
"changes": r.Changes(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func initDBArgs(argsIn goja.FunctionCall, vm *goja.Runtime, checkArgsNum int) (*Args, *db.DB, *db.Tx, *log.Logger) {
|
||||||
|
args := MakeArgs(&argsIn, vm).Check(checkArgsNum)
|
||||||
|
logger := getLogger(vm)
|
||||||
|
conn, _ := args.This.ToObject(vm).Get("conn").Export().(*db.DB)
|
||||||
|
//if !connOk {
|
||||||
|
// panic(vm.NewGoError(errors.New("this is not a db object")))
|
||||||
|
//}
|
||||||
|
var tx *db.Tx
|
||||||
|
if conn == nil {
|
||||||
|
tx, _ = args.This.ToObject(vm).Get("tx").Export().(*db.Tx)
|
||||||
|
}
|
||||||
|
return args, conn, tx, logger
|
||||||
|
}
|
43
js/file.go
43
js/file.go
@ -3,13 +3,14 @@ package js
|
|||||||
import (
|
import (
|
||||||
"apigo.cc/ai/ai/goja"
|
"apigo.cc/ai/ai/goja"
|
||||||
"github.com/ssgo/u"
|
"github.com/ssgo/u"
|
||||||
|
"os"
|
||||||
)
|
)
|
||||||
|
|
||||||
func RequireFile() map[string]any {
|
func RequireFile() map[string]any {
|
||||||
return map[string]any{
|
return map[string]any{
|
||||||
"read": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
|
"read": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
|
||||||
args := MakeArgs(&argsIn, vm).Check(1)
|
args := MakeArgs(&argsIn, vm).Check(1)
|
||||||
if r, err := u.ReadFile(findPath(vm, args.Str(0))); err == nil {
|
if r, err := u.ReadFile(args.Path(0)); err == nil {
|
||||||
return vm.ToValue(r)
|
return vm.ToValue(r)
|
||||||
} else {
|
} else {
|
||||||
panic(vm.NewGoError(err))
|
panic(vm.NewGoError(err))
|
||||||
@ -17,7 +18,7 @@ func RequireFile() map[string]any {
|
|||||||
},
|
},
|
||||||
"write": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
|
"write": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
|
||||||
args := MakeArgs(&argsIn, vm).Check(2)
|
args := MakeArgs(&argsIn, vm).Check(2)
|
||||||
if err := u.WriteFileBytes(findPath(vm, args.Str(0)), u.Bytes(args.Any(0))); err == nil {
|
if err := u.WriteFileBytes(args.Path(0), u.Bytes(args.Any(0))); err == nil {
|
||||||
return nil
|
return nil
|
||||||
} else {
|
} else {
|
||||||
panic(vm.NewGoError(err))
|
panic(vm.NewGoError(err))
|
||||||
@ -25,19 +26,49 @@ func RequireFile() map[string]any {
|
|||||||
},
|
},
|
||||||
"dir": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
|
"dir": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
|
||||||
args := MakeArgs(&argsIn, vm).Check(1)
|
args := MakeArgs(&argsIn, vm).Check(1)
|
||||||
if r, err := u.ReadDir(findPath(vm, args.Str(0))); err == nil {
|
if r, err := u.ReadDir(args.Path(0)); err == nil {
|
||||||
return vm.ToValue(r)
|
list := make([]map[string]any, len(r))
|
||||||
|
for i, info := range r {
|
||||||
|
list[i] = makeFileInfo(&info)
|
||||||
|
}
|
||||||
|
return vm.ToValue(list)
|
||||||
} else {
|
} else {
|
||||||
panic(vm.NewGoError(err))
|
panic(vm.NewGoError(err))
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"stat": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
|
"stat": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
|
||||||
args := MakeArgs(&argsIn, vm).Check(1)
|
args := MakeArgs(&argsIn, vm).Check(1)
|
||||||
return vm.ToValue(u.GetFileInfo(findPath(vm, args.Str(0))))
|
return vm.ToValue(makeFileInfo(u.GetFileInfo(args.Path(0))))
|
||||||
},
|
},
|
||||||
"find": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
|
"find": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
|
||||||
args := MakeArgs(&argsIn, vm).Check(1)
|
args := MakeArgs(&argsIn, vm).Check(1)
|
||||||
return vm.ToValue(findPath(vm, args.Str(0)))
|
return vm.ToValue(args.Path(0))
|
||||||
|
},
|
||||||
|
"remove": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
|
||||||
|
args := MakeArgs(&argsIn, vm).Check(1)
|
||||||
|
if err := os.RemoveAll(args.Path(0)); err == nil {
|
||||||
|
return nil
|
||||||
|
} else {
|
||||||
|
panic(vm.NewGoError(err))
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"copy": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
|
||||||
|
args := MakeArgs(&argsIn, vm).Check(2)
|
||||||
|
if err := u.CopyFile(args.Path(0), args.Path(1)); err == nil {
|
||||||
|
return nil
|
||||||
|
} else {
|
||||||
|
panic(vm.NewGoError(err))
|
||||||
|
}
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func makeFileInfo(info *u.FileInfo) map[string]any {
|
||||||
|
return map[string]any{
|
||||||
|
"name": info.Name,
|
||||||
|
"size": info.Size,
|
||||||
|
"fullName": info.FullName,
|
||||||
|
"isDir": info.IsDir,
|
||||||
|
"modTime": info.ModTime.UnixMilli(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
18
js/lib/ai.ts
18
js/lib/ai.ts
@ -5,11 +5,14 @@ let {{.}}: LLM
|
|||||||
{{- end}}
|
{{- end}}
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
similarity,
|
||||||
{{- range .LLMList}}
|
{{- range .LLMList}}
|
||||||
{{.}},
|
{{.}},
|
||||||
{{- end}}
|
{{- end}}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function similarity(a: any, b: any): number{return 0}
|
||||||
|
|
||||||
interface ChatConfig {
|
interface ChatConfig {
|
||||||
model: string
|
model: string
|
||||||
ratio: number
|
ratio: number
|
||||||
@ -24,7 +27,7 @@ interface ChatResult {
|
|||||||
askTokens: number
|
askTokens: number
|
||||||
answerTokens: number
|
answerTokens: number
|
||||||
totalTokens: number
|
totalTokens: number
|
||||||
error: string
|
usedTime: number
|
||||||
}
|
}
|
||||||
|
|
||||||
interface GCConfig {
|
interface GCConfig {
|
||||||
@ -38,7 +41,15 @@ interface GCResult {
|
|||||||
preview: string
|
preview: string
|
||||||
results: Array<string>
|
results: Array<string>
|
||||||
previews: Array<string>
|
previews: Array<string>
|
||||||
error: string
|
usedTime: number
|
||||||
|
}
|
||||||
|
|
||||||
|
interface EmbeddingResult {
|
||||||
|
result: string
|
||||||
|
askTokens: number
|
||||||
|
answerTokens: number
|
||||||
|
totalTokens: number
|
||||||
|
usedTime: number
|
||||||
}
|
}
|
||||||
|
|
||||||
interface Support {
|
interface Support {
|
||||||
@ -68,5 +79,8 @@ interface LLM {
|
|||||||
makeVideo(prompt: string, config?: GCConfig): GCResult
|
makeVideo(prompt: string, config?: GCConfig): GCResult
|
||||||
fastMakeVideo(prompt: string, config?: GCConfig): GCResult
|
fastMakeVideo(prompt: string, config?: GCConfig): GCResult
|
||||||
bestMakeVideo(prompt: string, config?: GCConfig): GCResult
|
bestMakeVideo(prompt: string, config?: GCConfig): GCResult
|
||||||
|
embedding(text: string, model: string): EmbeddingResult
|
||||||
|
fastEmbedding(text: string): EmbeddingResult
|
||||||
|
bestEmbedding(text: string): EmbeddingResult
|
||||||
support: Support
|
support: Support
|
||||||
}
|
}
|
||||||
|
@ -9,6 +9,24 @@ export default {
|
|||||||
warn,
|
warn,
|
||||||
error,
|
error,
|
||||||
input,
|
input,
|
||||||
|
black,
|
||||||
|
red,
|
||||||
|
green,
|
||||||
|
yellow,
|
||||||
|
blue,
|
||||||
|
magenta,
|
||||||
|
cyan,
|
||||||
|
white,
|
||||||
|
dim,
|
||||||
|
italic,
|
||||||
|
bBlack,
|
||||||
|
bRed,
|
||||||
|
bGreen,
|
||||||
|
bYellow,
|
||||||
|
bBlue,
|
||||||
|
bMagenta,
|
||||||
|
bCyan,
|
||||||
|
bWhite,
|
||||||
}
|
}
|
||||||
|
|
||||||
function print(...data: any[]): void {}
|
function print(...data: any[]): void {}
|
||||||
@ -19,3 +37,22 @@ function info(...data: any[]): void {}
|
|||||||
function warn(...data: any[]): void {}
|
function warn(...data: any[]): void {}
|
||||||
function error(...data: any[]): void {}
|
function error(...data: any[]): void {}
|
||||||
function input(...data: any[]): string {return ''}
|
function input(...data: any[]): string {return ''}
|
||||||
|
|
||||||
|
function black(...data: any[]): string {return ''}
|
||||||
|
function red(...data: any[]): string {return ''}
|
||||||
|
function green(...data: any[]): string {return ''}
|
||||||
|
function yellow(...data: any[]): string {return ''}
|
||||||
|
function blue(...data: any[]): string {return ''}
|
||||||
|
function magenta(...data: any[]): string {return ''}
|
||||||
|
function cyan(...data: any[]): string {return ''}
|
||||||
|
function white(...data: any[]): string {return ''}
|
||||||
|
function dim(...data: any[]): string {return ''}
|
||||||
|
function italic(...data: any[]): string {return ''}
|
||||||
|
function bBlack(...data: any[]): string {return ''}
|
||||||
|
function bRed(...data: any[]): string {return ''}
|
||||||
|
function bGreen(...data: any[]): string {return ''}
|
||||||
|
function bYellow(...data: any[]): string {return ''}
|
||||||
|
function bBlue(...data: any[]): string {return ''}
|
||||||
|
function bMagenta(...data: any[]): string {return ''}
|
||||||
|
function bCyan(...data: any[]): string {return ''}
|
||||||
|
function bWhite(...data: any[]): string {return ''}
|
58
js/lib/db.ts
Normal file
58
js/lib/db.ts
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
// just for develop
|
||||||
|
|
||||||
|
export default {
|
||||||
|
get,
|
||||||
|
}
|
||||||
|
|
||||||
|
function get(dbName: string): DB {return null}
|
||||||
|
|
||||||
|
interface DB {
|
||||||
|
make(descFileOrContent: string): Array<Object>
|
||||||
|
query(sql: string, ...args:any): QueryResult
|
||||||
|
query1(sql: string, ...args:any): QueryResult1
|
||||||
|
query11(sql: string, ...args:any): QueryResult11
|
||||||
|
exec(sql: string, ...args:any): ExecResult
|
||||||
|
insert(table: string, data:Object): ExecResult
|
||||||
|
replace(table: string, data:Object): ExecResult
|
||||||
|
update(table: string, data:Object, where: string, ...args:any): ExecResult
|
||||||
|
delete(table: string, where: string, ...args:any): ExecResult
|
||||||
|
destroy(): void
|
||||||
|
begin(): Tx
|
||||||
|
}
|
||||||
|
|
||||||
|
interface Tx {
|
||||||
|
query(sql: string, ...args:any): QueryResult
|
||||||
|
query1(sql: string, ...args:any): QueryResult1
|
||||||
|
query11(sql: string, ...args:any): QueryResult11
|
||||||
|
exec(sql: string, ...args:any): ExecResult
|
||||||
|
insert(table: string, data:Object): ExecResult
|
||||||
|
replace(table: string, data:Object): ExecResult
|
||||||
|
update(table: string, data:Object, where: string, ...args:any): ExecResult
|
||||||
|
delete(table: string, where: string, ...args:any): ExecResult
|
||||||
|
end(ok:boolean): void
|
||||||
|
}
|
||||||
|
|
||||||
|
interface QueryResult {
|
||||||
|
sql: string
|
||||||
|
args: Array<any>
|
||||||
|
result: Array<Object>
|
||||||
|
}
|
||||||
|
|
||||||
|
interface QueryResult1 {
|
||||||
|
sql: string
|
||||||
|
args: Array<any>
|
||||||
|
result: Object
|
||||||
|
}
|
||||||
|
|
||||||
|
interface QueryResult11 {
|
||||||
|
sql: string
|
||||||
|
args: Array<any>
|
||||||
|
result: any
|
||||||
|
}
|
||||||
|
|
||||||
|
interface ExecResult {
|
||||||
|
sql: string
|
||||||
|
args: Array<any>
|
||||||
|
id: number
|
||||||
|
changes: number
|
||||||
|
}
|
@ -4,7 +4,10 @@ export default {
|
|||||||
read,
|
read,
|
||||||
write,
|
write,
|
||||||
dir,
|
dir,
|
||||||
stat
|
stat,
|
||||||
|
find,
|
||||||
|
remove,
|
||||||
|
copy
|
||||||
}
|
}
|
||||||
|
|
||||||
function read(filename: string): string {return ''}
|
function read(filename: string): string {return ''}
|
||||||
@ -12,11 +15,13 @@ 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 ''}
|
function find(filename: string): string {return ''}
|
||||||
|
function remove(filename: string): void {}
|
||||||
|
function copy(from: string, to: string): void {}
|
||||||
|
|
||||||
interface FileInfo {
|
interface FileInfo {
|
||||||
Name: string
|
name: string
|
||||||
FullName: string
|
fullName: string
|
||||||
IsDir: boolean
|
isDir: boolean
|
||||||
Size: number
|
size: number
|
||||||
ModTime: number
|
modTime: number
|
||||||
}
|
}
|
||||||
|
13
js/lib/log.ts
Normal file
13
js/lib/log.ts
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
// just for develop
|
||||||
|
|
||||||
|
export default {
|
||||||
|
debug,
|
||||||
|
info,
|
||||||
|
warn,
|
||||||
|
error,
|
||||||
|
}
|
||||||
|
|
||||||
|
function debug(message:string, info?:Object): void {}
|
||||||
|
function info(message:string, info?:Object): void {}
|
||||||
|
function warn(message:string, info?:Object): void {}
|
||||||
|
function error(message:string, info?:Object): void {}
|
@ -6,6 +6,8 @@ export default {
|
|||||||
unJson,
|
unJson,
|
||||||
yaml,
|
yaml,
|
||||||
unYaml,
|
unYaml,
|
||||||
|
load,
|
||||||
|
save,
|
||||||
base64,
|
base64,
|
||||||
unBase64,
|
unBase64,
|
||||||
urlBase64,
|
urlBase64,
|
||||||
@ -24,7 +26,11 @@ export default {
|
|||||||
sha256,
|
sha256,
|
||||||
sha512,
|
sha512,
|
||||||
tpl,
|
tpl,
|
||||||
shell
|
shell,
|
||||||
|
toDatetime,
|
||||||
|
fromDatetime,
|
||||||
|
toDate,
|
||||||
|
fromDate
|
||||||
}
|
}
|
||||||
|
|
||||||
function json(data:any): string {return ''}
|
function json(data:any): string {return ''}
|
||||||
@ -32,6 +38,8 @@ function jsonP(data:any): string {return ''}
|
|||||||
function unJson(data:string): any {return null}
|
function unJson(data:string): any {return null}
|
||||||
function yaml(data:any): string {return ''}
|
function yaml(data:any): string {return ''}
|
||||||
function unYaml(data:string): any {return null}
|
function unYaml(data:string): any {return null}
|
||||||
|
function load(filename:string): any {return null}
|
||||||
|
function save(filename:string, data:any) {}
|
||||||
function base64(data:any): string {return ''}
|
function base64(data:any): string {return ''}
|
||||||
function unBase64(data:string): any {return null}
|
function unBase64(data:string): any {return null}
|
||||||
function urlBase64(data:any): string {return ''}
|
function urlBase64(data:any): string {return ''}
|
||||||
@ -51,3 +59,7 @@ function sha256(data:any): string {return ''}
|
|||||||
function sha512(data:any): string {return ''}
|
function sha512(data:any): string {return ''}
|
||||||
function tpl(text:string, data:any, functions?:Object): 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 []}
|
||||||
|
function toDatetime(timestamp:number): string {return ''}
|
||||||
|
function fromDatetime(datetimeStr:string): number {return 0}
|
||||||
|
function toDate(timestamp:number): string {return ''}
|
||||||
|
function fromDate(dateStr:string): number {return 0}
|
||||||
|
40
js/log.go
Normal file
40
js/log.go
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
package js
|
||||||
|
|
||||||
|
import (
|
||||||
|
"apigo.cc/ai/ai/goja"
|
||||||
|
"github.com/ssgo/log"
|
||||||
|
)
|
||||||
|
|
||||||
|
func RequireLog() map[string]any {
|
||||||
|
return map[string]any{
|
||||||
|
"info": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
|
||||||
|
args := MakeArgs(&argsIn, vm).Check(1)
|
||||||
|
getLogger(vm).Info(args.Str(0), args.Map2Arr(1)...)
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
"warn": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
|
||||||
|
args := MakeArgs(&argsIn, vm).Check(1)
|
||||||
|
getLogger(vm).Warning(args.Str(0), args.Map2Arr(1)...)
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
"error": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
|
||||||
|
args := MakeArgs(&argsIn, vm).Check(1)
|
||||||
|
getLogger(vm).Error(args.Str(0), args.Map2Arr(1)...)
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
"debug": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
|
||||||
|
args := MakeArgs(&argsIn, vm).Check(1)
|
||||||
|
getLogger(vm).Debug(args.Str(0), args.Map2Arr(1)...)
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func getLogger(vm *goja.Runtime) *log.Logger {
|
||||||
|
if vm.GoData["logger"] != nil {
|
||||||
|
if logger, ok := vm.GoData["logger"].(*log.Logger); ok {
|
||||||
|
return logger
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return log.DefaultLogger
|
||||||
|
}
|
50
js/util.go
50
js/util.go
@ -9,6 +9,7 @@ import (
|
|||||||
"gopkg.in/yaml.v3"
|
"gopkg.in/yaml.v3"
|
||||||
"strings"
|
"strings"
|
||||||
"text/template"
|
"text/template"
|
||||||
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
func RequireUtil() map[string]any {
|
func RequireUtil() map[string]any {
|
||||||
@ -104,7 +105,7 @@ func RequireUtil() map[string]any {
|
|||||||
},
|
},
|
||||||
"unBase64": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
|
"unBase64": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
|
||||||
args := MakeArgs(&argsIn, vm).Check(1)
|
args := MakeArgs(&argsIn, vm).Check(1)
|
||||||
return vm.ToValue(u.UnBase64String(args.Str(0)))
|
return vm.ToValue(u.UnBase64(args.Str(0)))
|
||||||
},
|
},
|
||||||
"urlBase64": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
|
"urlBase64": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
|
||||||
args := MakeArgs(&argsIn, vm).Check(1)
|
args := MakeArgs(&argsIn, vm).Check(1)
|
||||||
@ -112,7 +113,7 @@ func RequireUtil() map[string]any {
|
|||||||
},
|
},
|
||||||
"unUrlBase64": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
|
"unUrlBase64": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
|
||||||
args := MakeArgs(&argsIn, vm).Check(1)
|
args := MakeArgs(&argsIn, vm).Check(1)
|
||||||
return vm.ToValue(u.UnUrlBase64String(args.Str(0)))
|
return vm.ToValue(u.UnUrlBase64(args.Str(0)))
|
||||||
},
|
},
|
||||||
"hex": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
|
"hex": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
|
||||||
args := MakeArgs(&argsIn, vm).Check(1)
|
args := MakeArgs(&argsIn, vm).Check(1)
|
||||||
@ -121,7 +122,7 @@ func RequireUtil() map[string]any {
|
|||||||
"unHex": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
|
"unHex": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
|
||||||
args := MakeArgs(&argsIn, vm).Check(1)
|
args := MakeArgs(&argsIn, vm).Check(1)
|
||||||
if r, err := hex.DecodeString(args.Str(0)); err == nil {
|
if r, err := hex.DecodeString(args.Str(0)); err == nil {
|
||||||
return vm.ToValue(string(r))
|
return vm.ToValue(r)
|
||||||
} else {
|
} else {
|
||||||
panic(vm.NewGoError(err))
|
panic(vm.NewGoError(err))
|
||||||
}
|
}
|
||||||
@ -129,7 +130,7 @@ func RequireUtil() map[string]any {
|
|||||||
"aes": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
|
"aes": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
|
||||||
args := MakeArgs(&argsIn, vm).Check(3)
|
args := MakeArgs(&argsIn, vm).Check(3)
|
||||||
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(r)
|
||||||
} else {
|
} else {
|
||||||
panic(vm.NewGoError(err))
|
panic(vm.NewGoError(err))
|
||||||
}
|
}
|
||||||
@ -137,7 +138,7 @@ func RequireUtil() map[string]any {
|
|||||||
"unAes": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
|
"unAes": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
|
||||||
args := MakeArgs(&argsIn, vm).Check(3)
|
args := MakeArgs(&argsIn, vm).Check(3)
|
||||||
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(r)
|
||||||
} else {
|
} else {
|
||||||
panic(vm.NewGoError(err))
|
panic(vm.NewGoError(err))
|
||||||
}
|
}
|
||||||
@ -145,7 +146,7 @@ func RequireUtil() map[string]any {
|
|||||||
"gzip": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
|
"gzip": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
|
||||||
args := MakeArgs(&argsIn, vm).Check(1)
|
args := MakeArgs(&argsIn, vm).Check(1)
|
||||||
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(r)
|
||||||
} else {
|
} else {
|
||||||
panic(vm.NewGoError(err))
|
panic(vm.NewGoError(err))
|
||||||
}
|
}
|
||||||
@ -153,7 +154,7 @@ func RequireUtil() map[string]any {
|
|||||||
"gunzip": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
|
"gunzip": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
|
||||||
args := MakeArgs(&argsIn, vm).Check(1)
|
args := MakeArgs(&argsIn, vm).Check(1)
|
||||||
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(r)
|
||||||
} else {
|
} else {
|
||||||
panic(vm.NewGoError(err))
|
panic(vm.NewGoError(err))
|
||||||
}
|
}
|
||||||
@ -232,5 +233,40 @@ func RequireUtil() map[string]any {
|
|||||||
panic(vm.NewGoError(err))
|
panic(vm.NewGoError(err))
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"toDatetime": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
|
||||||
|
args := MakeArgs(&argsIn, vm).Check(1)
|
||||||
|
return vm.ToValue(time.UnixMilli(args.Int64(0)).Format("2006-01-02 15:04:05"))
|
||||||
|
},
|
||||||
|
"fromDatetime": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
|
||||||
|
args := MakeArgs(&argsIn, vm).Check(1)
|
||||||
|
timeStr := args.Str(0)
|
||||||
|
if len(timeStr) > 19 {
|
||||||
|
timeStr = timeStr[0:19]
|
||||||
|
}
|
||||||
|
if strings.ContainsRune(timeStr, 'T') {
|
||||||
|
timeStr = strings.ReplaceAll(timeStr, "T", " ")
|
||||||
|
}
|
||||||
|
if tm, err := time.ParseInLocation("2006-01-02 15:04:05", timeStr, time.Local); err == nil {
|
||||||
|
return vm.ToValue(tm.UnixMilli())
|
||||||
|
} else {
|
||||||
|
panic(vm.NewGoError(err))
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"toDate": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
|
||||||
|
args := MakeArgs(&argsIn, vm).Check(1)
|
||||||
|
return vm.ToValue(time.UnixMilli(args.Int64(0)).Format("2006-01-02"))
|
||||||
|
},
|
||||||
|
"fromDate": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
|
||||||
|
args := MakeArgs(&argsIn, vm).Check(1)
|
||||||
|
timeStr := args.Str(0)
|
||||||
|
if len(timeStr) > 10 {
|
||||||
|
timeStr = timeStr[0:10]
|
||||||
|
}
|
||||||
|
if tm, err := time.ParseInLocation("2006-01-02", timeStr, time.Local); err == nil {
|
||||||
|
return vm.ToValue(tm.UnixMilli())
|
||||||
|
} else {
|
||||||
|
panic(vm.NewGoError(err))
|
||||||
|
}
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,64 +1,68 @@
|
|||||||
package openai
|
package openai
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"apigo.cc/ai/ai/llm"
|
"apigo.cc/ai/ai/interface/llm"
|
||||||
|
"bytes"
|
||||||
"context"
|
"context"
|
||||||
|
"encoding/binary"
|
||||||
|
"fmt"
|
||||||
"github.com/sashabaranov/go-openai"
|
"github.com/sashabaranov/go-openai"
|
||||||
"github.com/ssgo/log"
|
"github.com/ssgo/log"
|
||||||
"strings"
|
"strings"
|
||||||
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (lm *LLM) FastAsk(messages []llm.ChatMessage, callback func(answer string)) (string, llm.TokenUsage, error) {
|
func (lm *LLM) FastAsk(messages []llm.ChatMessage, callback func(answer string)) (string, llm.Usage, error) {
|
||||||
return lm.Ask(messages, llm.ChatConfig{
|
return lm.Ask(messages, llm.ChatConfig{
|
||||||
Model: ModelGPT_4o_mini_2024_07_18,
|
Model: ModelGPT_4o_mini_2024_07_18,
|
||||||
}, callback)
|
}, callback)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (lm *LLM) LongAsk(messages []llm.ChatMessage, callback func(answer string)) (string, llm.TokenUsage, error) {
|
func (lm *LLM) LongAsk(messages []llm.ChatMessage, callback func(answer string)) (string, llm.Usage, error) {
|
||||||
return lm.Ask(messages, llm.ChatConfig{
|
return lm.Ask(messages, llm.ChatConfig{
|
||||||
Model: ModelGPT_4_32k_0613,
|
Model: ModelGPT_4_32k_0613,
|
||||||
}, callback)
|
}, callback)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (lm *LLM) BatterAsk(messages []llm.ChatMessage, callback func(answer string)) (string, llm.TokenUsage, error) {
|
func (lm *LLM) BatterAsk(messages []llm.ChatMessage, callback func(answer string)) (string, llm.Usage, error) {
|
||||||
return lm.Ask(messages, llm.ChatConfig{
|
return lm.Ask(messages, llm.ChatConfig{
|
||||||
Model: ModelGPT_4_turbo,
|
Model: ModelGPT_4_turbo,
|
||||||
}, callback)
|
}, callback)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (lm *LLM) BestAsk(messages []llm.ChatMessage, callback func(answer string)) (string, llm.TokenUsage, error) {
|
func (lm *LLM) BestAsk(messages []llm.ChatMessage, callback func(answer string)) (string, llm.Usage, error) {
|
||||||
return lm.Ask(messages, llm.ChatConfig{
|
return lm.Ask(messages, llm.ChatConfig{
|
||||||
Model: ModelGPT_4o_2024_08_06,
|
Model: ModelGPT_4o_2024_08_06,
|
||||||
}, callback)
|
}, callback)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (lm *LLM) MultiAsk(messages []llm.ChatMessage, callback func(answer string)) (string, llm.TokenUsage, error) {
|
func (lm *LLM) MultiAsk(messages []llm.ChatMessage, callback func(answer string)) (string, llm.Usage, error) {
|
||||||
return lm.Ask(messages, llm.ChatConfig{
|
return lm.Ask(messages, llm.ChatConfig{
|
||||||
Model: ModelGPT_4o_mini_2024_07_18,
|
Model: ModelGPT_4o_mini_2024_07_18,
|
||||||
}, callback)
|
}, callback)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (lm *LLM) BestMultiAsk(messages []llm.ChatMessage, callback func(answer string)) (string, llm.TokenUsage, error) {
|
func (lm *LLM) BestMultiAsk(messages []llm.ChatMessage, callback func(answer string)) (string, llm.Usage, error) {
|
||||||
return lm.Ask(messages, llm.ChatConfig{
|
return lm.Ask(messages, llm.ChatConfig{
|
||||||
Model: ModelGPT_4o_2024_08_06,
|
Model: ModelGPT_4o_2024_08_06,
|
||||||
}, callback)
|
}, callback)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (lm *LLM) CodeInterpreterAsk(messages []llm.ChatMessage, callback func(answer string)) (string, llm.TokenUsage, error) {
|
func (lm *LLM) CodeInterpreterAsk(messages []llm.ChatMessage, callback func(answer string)) (string, llm.Usage, error) {
|
||||||
return lm.Ask(messages, llm.ChatConfig{
|
return lm.Ask(messages, llm.ChatConfig{
|
||||||
Model: ModelGPT_4o,
|
Model: ModelGPT_4o,
|
||||||
Tools: map[string]any{llm.ToolCodeInterpreter: nil},
|
Tools: map[string]any{llm.ToolCodeInterpreter: nil},
|
||||||
}, callback)
|
}, callback)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (lm *LLM) WebSearchAsk(messages []llm.ChatMessage, callback func(answer string)) (string, llm.TokenUsage, error) {
|
func (lm *LLM) WebSearchAsk(messages []llm.ChatMessage, callback func(answer string)) (string, llm.Usage, error) {
|
||||||
return lm.Ask(messages, llm.ChatConfig{
|
return lm.Ask(messages, llm.ChatConfig{
|
||||||
Model: ModelGPT_4o_mini_2024_07_18,
|
Model: ModelGPT_4o_mini_2024_07_18,
|
||||||
Tools: map[string]any{llm.ToolWebSearch: nil},
|
Tools: map[string]any{llm.ToolWebSearch: nil},
|
||||||
}, callback)
|
}, callback)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (lm *LLM) Ask(messages []llm.ChatMessage, config llm.ChatConfig, callback func(answer string)) (string, llm.TokenUsage, error) {
|
func (lm *LLM) Ask(messages []llm.ChatMessage, config llm.ChatConfig, callback func(answer string)) (string, llm.Usage, error) {
|
||||||
openaiConf := openai.DefaultConfig(lm.config.ApiKey)
|
openaiConf := openai.DefaultConfig(lm.config.ApiKey)
|
||||||
if lm.config.Endpoint != "" {
|
if lm.config.Endpoint != "" {
|
||||||
openaiConf.BaseURL = lm.config.Endpoint
|
openaiConf.BaseURL = lm.config.Endpoint
|
||||||
@ -124,7 +128,7 @@ func (lm *LLM) Ask(messages []llm.ChatMessage, config llm.ChatConfig, callback f
|
|||||||
r, err := c.CreateChatCompletionStream(context.Background(), opt)
|
r, err := c.CreateChatCompletionStream(context.Background(), opt)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
results := make([]string, 0)
|
results := make([]string, 0)
|
||||||
usage := llm.TokenUsage{}
|
usage := llm.Usage{}
|
||||||
for {
|
for {
|
||||||
if r2, err := r.Recv(); err == nil {
|
if r2, err := r.Recv(); err == nil {
|
||||||
if r2.Choices != nil {
|
if r2.Choices != nil {
|
||||||
@ -147,26 +151,75 @@ func (lm *LLM) Ask(messages []llm.ChatMessage, config llm.ChatConfig, callback f
|
|||||||
return strings.Join(results, ""), usage, nil
|
return strings.Join(results, ""), usage, nil
|
||||||
} else {
|
} else {
|
||||||
log.DefaultLogger.Error(err.Error())
|
log.DefaultLogger.Error(err.Error())
|
||||||
return "", llm.TokenUsage{}, err
|
return "", llm.Usage{}, err
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
r, err := c.CreateChatCompletion(context.Background(), opt)
|
t1 := time.Now().UnixMilli()
|
||||||
|
if r, err := c.CreateChatCompletion(context.Background(), opt); err == nil {
|
||||||
if err == nil {
|
t2 := time.Now().UnixMilli() - t1
|
||||||
results := make([]string, 0)
|
results := make([]string, 0)
|
||||||
if r.Choices != nil {
|
if r.Choices != nil {
|
||||||
for _, ch := range r.Choices {
|
for _, ch := range r.Choices {
|
||||||
results = append(results, ch.Message.Content)
|
results = append(results, ch.Message.Content)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return strings.Join(results, ""), llm.TokenUsage{
|
return strings.Join(results, ""), llm.Usage{
|
||||||
AskTokens: int64(r.Usage.PromptTokens),
|
AskTokens: int64(r.Usage.PromptTokens),
|
||||||
AnswerTokens: int64(r.Usage.CompletionTokens),
|
AnswerTokens: int64(r.Usage.CompletionTokens),
|
||||||
TotalTokens: int64(r.Usage.TotalTokens),
|
TotalTokens: int64(r.Usage.TotalTokens),
|
||||||
|
UsedTime: t2,
|
||||||
}, nil
|
}, nil
|
||||||
} else {
|
} else {
|
||||||
//fmt.Println(u.BMagenta(err.Error()), u.BMagenta(u.JsonP(r)))
|
//fmt.Println(u.BMagenta(err.Error()), u.BMagenta(u.JsonP(r)))
|
||||||
return "", llm.TokenUsage{}, err
|
return "", llm.Usage{}, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (lm *LLM) FastEmbedding(text string) ([]byte, llm.Usage, error) {
|
||||||
|
return lm.Embedding(text, string(openai.AdaEmbeddingV2))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (lm *LLM) BestEmbedding(text string) ([]byte, llm.Usage, error) {
|
||||||
|
return lm.Embedding(text, string(openai.LargeEmbedding3))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (lm *LLM) Embedding(text, model string) ([]byte, llm.Usage, error) {
|
||||||
|
fmt.Println(111, model, text)
|
||||||
|
openaiConf := openai.DefaultConfig(lm.config.ApiKey)
|
||||||
|
if lm.config.Endpoint != "" {
|
||||||
|
openaiConf.BaseURL = lm.config.Endpoint
|
||||||
|
}
|
||||||
|
|
||||||
|
c := openai.NewClientWithConfig(openaiConf)
|
||||||
|
req := openai.EmbeddingRequest{
|
||||||
|
Input: text,
|
||||||
|
Model: openai.EmbeddingModel(model),
|
||||||
|
User: "",
|
||||||
|
EncodingFormat: "",
|
||||||
|
Dimensions: 0,
|
||||||
|
}
|
||||||
|
|
||||||
|
t1 := time.Now().UnixMilli()
|
||||||
|
if r, err := c.CreateEmbeddings(context.Background(), req); err == nil {
|
||||||
|
t2 := time.Now().UnixMilli() - t1
|
||||||
|
buf := new(bytes.Buffer)
|
||||||
|
if r.Data != nil {
|
||||||
|
for _, ch := range r.Data {
|
||||||
|
for _, v := range ch.Embedding {
|
||||||
|
_ = binary.Write(buf, binary.LittleEndian, v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fmt.Println(len(buf.Bytes()))
|
||||||
|
return buf.Bytes(), llm.Usage{
|
||||||
|
AskTokens: int64(r.Usage.PromptTokens),
|
||||||
|
AnswerTokens: int64(r.Usage.CompletionTokens),
|
||||||
|
TotalTokens: int64(r.Usage.TotalTokens),
|
||||||
|
UsedTime: t2,
|
||||||
|
}, nil
|
||||||
|
} else {
|
||||||
|
fmt.Println(err.Error())
|
||||||
|
return nil, llm.Usage{}, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
package openai
|
package openai
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"apigo.cc/ai/ai/llm"
|
"apigo.cc/ai/ai/interface/llm"
|
||||||
"github.com/sashabaranov/go-openai"
|
"github.com/sashabaranov/go-openai"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -1,32 +1,33 @@
|
|||||||
package openai
|
package openai
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"apigo.cc/ai/ai/llm"
|
"apigo.cc/ai/ai/interface/llm"
|
||||||
"context"
|
"context"
|
||||||
"github.com/sashabaranov/go-openai"
|
"github.com/sashabaranov/go-openai"
|
||||||
"strings"
|
"strings"
|
||||||
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
// func (lm *LLM) FastMakeImage(prompt, size, refImage string) ([]string, error) {
|
// func (lm *LLM) FastMakeImage(prompt, size, refImage string) ([]string, llm.Usage, error) {
|
||||||
// return lm.MakeImage(ModelDallE3Std, prompt, size, refImage)
|
// return lm.MakeImage(ModelDallE3Std, prompt, size, refImage)
|
||||||
// }
|
// }
|
||||||
//
|
//
|
||||||
// func (lm *LLM) BestMakeImage(prompt, size, refImage string) ([]string, error) {
|
// func (lm *LLM) BestMakeImage(prompt, size, refImage string) ([]string, llm.Usage, error) {
|
||||||
// return lm.MakeImage(ModelDallE3HD, prompt, size, refImage)
|
// return lm.MakeImage(ModelDallE3HD, prompt, size, refImage)
|
||||||
// }
|
// }
|
||||||
//
|
//
|
||||||
// func (lm *LLM) MakeImage(model, prompt, size, refImage string) ([]string, error) {
|
// func (lm *LLM) MakeImage(model, prompt, size, refImage string) ([]string, llm.Usage, error) {
|
||||||
func (lm *LLM) FastMakeImage(prompt string, config llm.GCConfig) ([]string, error) {
|
func (lm *LLM) FastMakeImage(prompt string, config llm.GCConfig) ([]string, llm.Usage, error) {
|
||||||
config.Model = ModelDallE3Std
|
config.Model = ModelDallE3Std
|
||||||
return lm.MakeImage(prompt, config)
|
return lm.MakeImage(prompt, config)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (lm *LLM) BestMakeImage(prompt string, config llm.GCConfig) ([]string, error) {
|
func (lm *LLM) BestMakeImage(prompt string, config llm.GCConfig) ([]string, llm.Usage, error) {
|
||||||
config.Model = ModelDallE3HD
|
config.Model = ModelDallE3HD
|
||||||
return lm.MakeImage(prompt, config)
|
return lm.MakeImage(prompt, config)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (lm *LLM) MakeImage(prompt string, config llm.GCConfig) ([]string, error) {
|
func (lm *LLM) MakeImage(prompt string, config llm.GCConfig) ([]string, llm.Usage, error) {
|
||||||
openaiConf := openai.DefaultConfig(lm.config.ApiKey)
|
openaiConf := openai.DefaultConfig(lm.config.ApiKey)
|
||||||
if lm.config.Endpoint != "" {
|
if lm.config.Endpoint != "" {
|
||||||
openaiConf.BaseURL = lm.config.Endpoint
|
openaiConf.BaseURL = lm.config.Endpoint
|
||||||
@ -43,6 +44,7 @@ func (lm *LLM) MakeImage(prompt string, config llm.GCConfig) ([]string, error) {
|
|||||||
quality = openai.CreateImageQualityHD
|
quality = openai.CreateImageQualityHD
|
||||||
model = model[0 : len(model)-3]
|
model = model[0 : len(model)-3]
|
||||||
}
|
}
|
||||||
|
t1 := time.Now().UnixMilli()
|
||||||
r, err := c.CreateImage(context.Background(), openai.ImageRequest{
|
r, err := c.CreateImage(context.Background(), openai.ImageRequest{
|
||||||
Prompt: prompt,
|
Prompt: prompt,
|
||||||
Model: model,
|
Model: model,
|
||||||
@ -51,25 +53,31 @@ func (lm *LLM) MakeImage(prompt string, config llm.GCConfig) ([]string, error) {
|
|||||||
Style: style,
|
Style: style,
|
||||||
ResponseFormat: openai.CreateImageResponseFormatURL,
|
ResponseFormat: openai.CreateImageResponseFormatURL,
|
||||||
})
|
})
|
||||||
|
t2 := time.Now().UnixMilli() - t1
|
||||||
if err == nil {
|
if err == nil {
|
||||||
results := make([]string, 0)
|
results := make([]string, 0)
|
||||||
for _, item := range r.Data {
|
for _, item := range r.Data {
|
||||||
results = append(results, item.URL)
|
results = append(results, item.URL)
|
||||||
}
|
}
|
||||||
return results, nil
|
return results, llm.Usage{
|
||||||
|
AskTokens: 0,
|
||||||
|
AnswerTokens: 0,
|
||||||
|
TotalTokens: 0,
|
||||||
|
UsedTime: t2,
|
||||||
|
}, nil
|
||||||
} else {
|
} else {
|
||||||
return nil, err
|
return nil, llm.Usage{}, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (lm *LLM) FastMakeVideo(prompt string, config llm.GCConfig) ([]string, []string, error) {
|
func (lm *LLM) FastMakeVideo(prompt string, config llm.GCConfig) ([]string, []string, llm.Usage, error) {
|
||||||
return lm.MakeVideo(prompt, config)
|
return lm.MakeVideo(prompt, config)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (lm *LLM) BestMakeVideo(prompt string, config llm.GCConfig) ([]string, []string, error) {
|
func (lm *LLM) BestMakeVideo(prompt string, config llm.GCConfig) ([]string, []string, llm.Usage, error) {
|
||||||
return lm.MakeVideo(prompt, config)
|
return lm.MakeVideo(prompt, config)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (lm *LLM) MakeVideo(prompt string, config llm.GCConfig) ([]string, []string, error) {
|
func (lm *LLM) MakeVideo(prompt string, config llm.GCConfig) ([]string, []string, llm.Usage, error) {
|
||||||
return nil, nil, nil
|
return nil, nil, llm.Usage{}, nil
|
||||||
}
|
}
|
||||||
|
@ -1,67 +1,70 @@
|
|||||||
package zhipu
|
package zhipu
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"apigo.cc/ai/ai/llm"
|
"apigo.cc/ai/ai/interface/llm"
|
||||||
"apigo.cc/ai/ai/llm/zhipu/zhipu"
|
"apigo.cc/ai/ai/llm/zhipu/zhipu"
|
||||||
|
"bytes"
|
||||||
"context"
|
"context"
|
||||||
|
"encoding/binary"
|
||||||
"strings"
|
"strings"
|
||||||
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (lm *LLM) FastAsk(messages []llm.ChatMessage, callback func(answer string)) (string, llm.TokenUsage, error) {
|
func (lm *LLM) FastAsk(messages []llm.ChatMessage, callback func(answer string)) (string, llm.Usage, error) {
|
||||||
return lm.Ask(messages, llm.ChatConfig{
|
return lm.Ask(messages, llm.ChatConfig{
|
||||||
Model: ModelGLM4Flash,
|
Model: ModelGLM4Flash,
|
||||||
}, callback)
|
}, callback)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (lm *LLM) LongAsk(messages []llm.ChatMessage, callback func(answer string)) (string, llm.TokenUsage, error) {
|
func (lm *LLM) LongAsk(messages []llm.ChatMessage, callback func(answer string)) (string, llm.Usage, error) {
|
||||||
return lm.Ask(messages, llm.ChatConfig{
|
return lm.Ask(messages, llm.ChatConfig{
|
||||||
Model: ModelGLM4Long,
|
Model: ModelGLM4Long,
|
||||||
}, callback)
|
}, callback)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (lm *LLM) BatterAsk(messages []llm.ChatMessage, callback func(answer string)) (string, llm.TokenUsage, error) {
|
func (lm *LLM) BatterAsk(messages []llm.ChatMessage, callback func(answer string)) (string, llm.Usage, error) {
|
||||||
return lm.Ask(messages, llm.ChatConfig{
|
return lm.Ask(messages, llm.ChatConfig{
|
||||||
Model: ModelGLM4Plus,
|
Model: ModelGLM4Plus,
|
||||||
}, callback)
|
}, callback)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (lm *LLM) BestAsk(messages []llm.ChatMessage, callback func(answer string)) (string, llm.TokenUsage, error) {
|
func (lm *LLM) BestAsk(messages []llm.ChatMessage, callback func(answer string)) (string, llm.Usage, error) {
|
||||||
return lm.Ask(messages, llm.ChatConfig{
|
return lm.Ask(messages, llm.ChatConfig{
|
||||||
Model: ModelGLM40520,
|
Model: ModelGLM40520,
|
||||||
}, callback)
|
}, callback)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (lm *LLM) MultiAsk(messages []llm.ChatMessage, callback func(answer string)) (string, llm.TokenUsage, error) {
|
func (lm *LLM) MultiAsk(messages []llm.ChatMessage, callback func(answer string)) (string, llm.Usage, error) {
|
||||||
return lm.Ask(messages, llm.ChatConfig{
|
return lm.Ask(messages, llm.ChatConfig{
|
||||||
Model: ModelGLM4VPlus,
|
Model: ModelGLM4VPlus,
|
||||||
}, callback)
|
}, callback)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (lm *LLM) BestMultiAsk(messages []llm.ChatMessage, callback func(answer string)) (string, llm.TokenUsage, error) {
|
func (lm *LLM) BestMultiAsk(messages []llm.ChatMessage, callback func(answer string)) (string, llm.Usage, error) {
|
||||||
return lm.Ask(messages, llm.ChatConfig{
|
return lm.Ask(messages, llm.ChatConfig{
|
||||||
Model: ModelGLM4V,
|
Model: ModelGLM4V,
|
||||||
}, callback)
|
}, callback)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (lm *LLM) CodeInterpreterAsk(messages []llm.ChatMessage, callback func(answer string)) (string, llm.TokenUsage, error) {
|
func (lm *LLM) CodeInterpreterAsk(messages []llm.ChatMessage, callback func(answer string)) (string, llm.Usage, error) {
|
||||||
return lm.Ask(messages, llm.ChatConfig{
|
return lm.Ask(messages, llm.ChatConfig{
|
||||||
Model: ModelGLM4AllTools,
|
Model: ModelGLM4AllTools,
|
||||||
Tools: map[string]any{llm.ToolCodeInterpreter: nil},
|
Tools: map[string]any{llm.ToolCodeInterpreter: nil},
|
||||||
}, callback)
|
}, callback)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (lm *LLM) WebSearchAsk(messages []llm.ChatMessage, callback func(answer string)) (string, llm.TokenUsage, error) {
|
func (lm *LLM) WebSearchAsk(messages []llm.ChatMessage, callback func(answer string)) (string, llm.Usage, error) {
|
||||||
return lm.Ask(messages, llm.ChatConfig{
|
return lm.Ask(messages, llm.ChatConfig{
|
||||||
Model: ModelGLM4AllTools,
|
Model: ModelGLM4AllTools,
|
||||||
Tools: map[string]any{llm.ToolWebSearch: nil},
|
Tools: map[string]any{llm.ToolWebSearch: nil},
|
||||||
}, callback)
|
}, callback)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (lm *LLM) Ask(messages []llm.ChatMessage, config llm.ChatConfig, callback func(answer string)) (string, llm.TokenUsage, error) {
|
func (lm *LLM) Ask(messages []llm.ChatMessage, config llm.ChatConfig, callback func(answer string)) (string, llm.Usage, error) {
|
||||||
config.SetDefault(&lm.config.ChatConfig)
|
config.SetDefault(&lm.config.ChatConfig)
|
||||||
c, err := zhipu.NewClient(zhipu.WithAPIKey(lm.config.ApiKey), zhipu.WithBaseURL(lm.config.Endpoint))
|
c, err := zhipu.NewClient(zhipu.WithAPIKey(lm.config.ApiKey), zhipu.WithBaseURL(lm.config.Endpoint))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", llm.TokenUsage{}, err
|
return "", llm.Usage{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
cc := c.ChatCompletion(config.GetModel())
|
cc := c.ChatCompletion(config.GetModel())
|
||||||
@ -126,19 +129,60 @@ func (lm *LLM) Ask(messages []llm.ChatMessage, config llm.ChatConfig, callback f
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
t1 := time.Now().UnixMilli()
|
||||||
if r, err := cc.Do(context.Background()); err == nil {
|
if r, err := cc.Do(context.Background()); err == nil {
|
||||||
|
t2 := time.Now().UnixMilli() - t1
|
||||||
results := make([]string, 0)
|
results := make([]string, 0)
|
||||||
if r.Choices != nil {
|
if r.Choices != nil {
|
||||||
for _, ch := range r.Choices {
|
for _, ch := range r.Choices {
|
||||||
results = append(results, ch.Message.Content)
|
results = append(results, ch.Message.Content)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return strings.Join(results, ""), llm.TokenUsage{
|
return strings.Join(results, ""), llm.Usage{
|
||||||
AskTokens: r.Usage.PromptTokens,
|
AskTokens: r.Usage.PromptTokens,
|
||||||
AnswerTokens: r.Usage.CompletionTokens,
|
AnswerTokens: r.Usage.CompletionTokens,
|
||||||
TotalTokens: r.Usage.TotalTokens,
|
TotalTokens: r.Usage.TotalTokens,
|
||||||
|
UsedTime: t2,
|
||||||
}, nil
|
}, nil
|
||||||
} else {
|
} else {
|
||||||
return "", llm.TokenUsage{}, err
|
return "", llm.Usage{}, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (lm *LLM) FastEmbedding(text string) ([]byte, llm.Usage, error) {
|
||||||
|
return lm.Embedding(text, ModelEmbedding3)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (lm *LLM) BestEmbedding(text string) ([]byte, llm.Usage, error) {
|
||||||
|
return lm.Embedding(text, ModelEmbedding3)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (lm *LLM) Embedding(text, model string) ([]byte, llm.Usage, error) {
|
||||||
|
c, err := zhipu.NewClient(zhipu.WithAPIKey(lm.config.ApiKey), zhipu.WithBaseURL(lm.config.Endpoint))
|
||||||
|
if err != nil {
|
||||||
|
return nil, llm.Usage{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
cc := c.Embedding(model)
|
||||||
|
cc.SetInput(text)
|
||||||
|
t1 := time.Now().UnixMilli()
|
||||||
|
if r, err := cc.Do(context.Background()); err == nil {
|
||||||
|
t2 := time.Now().UnixMilli() - t1
|
||||||
|
buf := new(bytes.Buffer)
|
||||||
|
if r.Data != nil {
|
||||||
|
for _, ch := range r.Data {
|
||||||
|
for _, v := range ch.Embedding {
|
||||||
|
_ = binary.Write(buf, binary.LittleEndian, float32(v))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return buf.Bytes(), llm.Usage{
|
||||||
|
AskTokens: r.Usage.PromptTokens,
|
||||||
|
AnswerTokens: r.Usage.CompletionTokens,
|
||||||
|
TotalTokens: r.Usage.TotalTokens,
|
||||||
|
UsedTime: t2,
|
||||||
|
}, nil
|
||||||
|
} else {
|
||||||
|
return nil, llm.Usage{}, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
package zhipu
|
package zhipu
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"apigo.cc/ai/ai/llm"
|
"apigo.cc/ai/ai/interface/llm"
|
||||||
"apigo.cc/ai/ai/llm/zhipu/zhipu"
|
"apigo.cc/ai/ai/llm/zhipu/zhipu"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -1,69 +1,75 @@
|
|||||||
package zhipu
|
package zhipu
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"apigo.cc/ai/ai/llm"
|
"apigo.cc/ai/ai/interface/llm"
|
||||||
"apigo.cc/ai/ai/llm/zhipu/zhipu"
|
"apigo.cc/ai/ai/llm/zhipu/zhipu"
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (lm *LLM) FastMakeImage(prompt string, config llm.GCConfig) ([]string, error) {
|
func (lm *LLM) FastMakeImage(prompt string, config llm.GCConfig) ([]string, llm.Usage, error) {
|
||||||
config.Model = ModelCogView3Plus
|
config.Model = ModelCogView3Plus
|
||||||
return lm.MakeImage(prompt, config)
|
return lm.MakeImage(prompt, config)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (lm *LLM) BestMakeImage(prompt string, config llm.GCConfig) ([]string, error) {
|
func (lm *LLM) BestMakeImage(prompt string, config llm.GCConfig) ([]string, llm.Usage, error) {
|
||||||
config.Model = ModelCogView3
|
config.Model = ModelCogView3
|
||||||
return lm.MakeImage(prompt, config)
|
return lm.MakeImage(prompt, config)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (lm *LLM) MakeImage(prompt string, config llm.GCConfig) ([]string, error) {
|
func (lm *LLM) MakeImage(prompt string, config llm.GCConfig) ([]string, llm.Usage, error) {
|
||||||
c, err := zhipu.NewClient(zhipu.WithAPIKey(lm.config.ApiKey), zhipu.WithBaseURL(lm.config.Endpoint))
|
c, err := zhipu.NewClient(zhipu.WithAPIKey(lm.config.ApiKey), zhipu.WithBaseURL(lm.config.Endpoint))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, llm.Usage{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
config.SetDefault(&lm.config.GCConfig)
|
config.SetDefault(&lm.config.GCConfig)
|
||||||
cc := c.ImageGeneration(config.Model).SetPrompt(prompt)
|
cc := c.ImageGeneration(config.Model).SetPrompt(prompt)
|
||||||
cc.SetSize(config.GetSize())
|
cc.SetSize(config.GetSize())
|
||||||
|
|
||||||
|
t1 := time.Now().UnixMilli()
|
||||||
if r, err := cc.Do(context.Background()); err == nil {
|
if r, err := cc.Do(context.Background()); err == nil {
|
||||||
|
t2 := time.Now().UnixMilli() - t1
|
||||||
results := make([]string, 0)
|
results := make([]string, 0)
|
||||||
for _, item := range r.Data {
|
for _, item := range r.Data {
|
||||||
results = append(results, item.URL)
|
results = append(results, item.URL)
|
||||||
}
|
}
|
||||||
return results, nil
|
return results, llm.Usage{
|
||||||
|
UsedTime: t2,
|
||||||
|
}, nil
|
||||||
} else {
|
} else {
|
||||||
return nil, err
|
return nil, llm.Usage{}, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (lm *LLM) FastMakeVideo(prompt string, config llm.GCConfig) ([]string, []string, error) {
|
func (lm *LLM) FastMakeVideo(prompt string, config llm.GCConfig) ([]string, []string, llm.Usage, error) {
|
||||||
config.Model = ModelCogVideoX
|
config.Model = ModelCogVideoX
|
||||||
return lm.MakeVideo(prompt, config)
|
return lm.MakeVideo(prompt, config)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (lm *LLM) BestMakeVideo(prompt string, config llm.GCConfig) ([]string, []string, error) {
|
func (lm *LLM) BestMakeVideo(prompt string, config llm.GCConfig) ([]string, []string, llm.Usage, error) {
|
||||||
config.Model = ModelCogVideoX
|
config.Model = ModelCogVideoX
|
||||||
return lm.MakeVideo(prompt, config)
|
return lm.MakeVideo(prompt, config)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (lm *LLM) MakeVideo(prompt string, config llm.GCConfig) ([]string, []string, error) {
|
func (lm *LLM) MakeVideo(prompt string, config llm.GCConfig) ([]string, []string, llm.Usage, error) {
|
||||||
c, err := zhipu.NewClient(zhipu.WithAPIKey(lm.config.ApiKey), zhipu.WithBaseURL(lm.config.Endpoint))
|
c, err := zhipu.NewClient(zhipu.WithAPIKey(lm.config.ApiKey), zhipu.WithBaseURL(lm.config.Endpoint))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, llm.Usage{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
config.SetDefault(&lm.config.GCConfig)
|
config.SetDefault(&lm.config.GCConfig)
|
||||||
cc := c.VideoGeneration(config.Model).SetPrompt(prompt)
|
cc := c.VideoGeneration(config.Model).SetPrompt(prompt)
|
||||||
cc.SetImageURL(config.GetRef())
|
cc.SetImageURL(config.GetRef())
|
||||||
|
|
||||||
|
t1 := time.Now().UnixMilli()
|
||||||
if resp, err := cc.Do(context.Background()); err == nil {
|
if resp, err := cc.Do(context.Background()); err == nil {
|
||||||
|
t2 := time.Now().UnixMilli() - t1
|
||||||
for i := 0; i < 1200; i++ {
|
for i := 0; i < 1200; i++ {
|
||||||
r, err := c.AsyncResult(resp.ID).Do(context.Background())
|
r, err := c.AsyncResult(resp.ID).Do(context.Background())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, llm.Usage{}, err
|
||||||
}
|
}
|
||||||
if r.TaskStatus == zhipu.VideoGenerationTaskStatusSuccess {
|
if r.TaskStatus == zhipu.VideoGenerationTaskStatusSuccess {
|
||||||
covers := make([]string, 0)
|
covers := make([]string, 0)
|
||||||
@ -72,15 +78,17 @@ func (lm *LLM) MakeVideo(prompt string, config llm.GCConfig) ([]string, []string
|
|||||||
results = append(results, item.URL)
|
results = append(results, item.URL)
|
||||||
covers = append(covers, item.CoverImageURL)
|
covers = append(covers, item.CoverImageURL)
|
||||||
}
|
}
|
||||||
return results, covers, nil
|
return results, covers, llm.Usage{
|
||||||
|
UsedTime: t2,
|
||||||
|
}, nil
|
||||||
}
|
}
|
||||||
if r.TaskStatus == zhipu.VideoGenerationTaskStatusFail {
|
if r.TaskStatus == zhipu.VideoGenerationTaskStatusFail {
|
||||||
return nil, nil, errors.New("fail on task " + resp.ID)
|
return nil, nil, llm.Usage{}, errors.New("fail on task " + resp.ID)
|
||||||
}
|
}
|
||||||
time.Sleep(3 * time.Second)
|
time.Sleep(3 * time.Second)
|
||||||
}
|
}
|
||||||
return nil, nil, errors.New("timeout on task " + resp.ID)
|
return nil, nil, llm.Usage{}, errors.New("timeout on task " + resp.ID)
|
||||||
} else {
|
} else {
|
||||||
return nil, nil, err
|
return nil, nil, llm.Usage{}, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,8 +2,8 @@ package tests
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"apigo.cc/ai/ai"
|
"apigo.cc/ai/ai"
|
||||||
|
llm2 "apigo.cc/ai/ai/interface/llm"
|
||||||
"apigo.cc/ai/ai/js"
|
"apigo.cc/ai/ai/js"
|
||||||
"apigo.cc/ai/ai/llm"
|
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/ssgo/u"
|
"github.com/ssgo/u"
|
||||||
@ -39,13 +39,13 @@ func TestAgent(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func testChat(t *testing.T, llmName string) {
|
func testChat(t *testing.T, llmName string) {
|
||||||
lm := llm.Get(llmName)
|
lm := llm2.Get(llmName)
|
||||||
|
|
||||||
if lm == nil {
|
if lm == nil {
|
||||||
t.Fatal("agent is nil")
|
t.Fatal("interface is nil")
|
||||||
}
|
}
|
||||||
|
|
||||||
r, usage, err := lm.FastAsk(llm.Messages().User().Text("你是什么模型,请给出具体名称、版本号").Make(), func(text string) {
|
r, usage, err := lm.FastAsk(llm2.Messages().User().Text("你是什么模型,请给出具体名称、版本号").Make(), func(text string) {
|
||||||
fmt.Print(u.BCyan(text))
|
fmt.Print(u.BCyan(text))
|
||||||
fmt.Print(" ")
|
fmt.Print(" ")
|
||||||
})
|
})
|
||||||
@ -60,13 +60,13 @@ func testChat(t *testing.T, llmName string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func testCode(t *testing.T, llmName string) {
|
func testCode(t *testing.T, llmName string) {
|
||||||
lm := llm.Get(llmName)
|
lm := llm2.Get(llmName)
|
||||||
|
|
||||||
if lm == nil {
|
if lm == nil {
|
||||||
t.Fatal("agent is nil")
|
t.Fatal("interface is nil")
|
||||||
}
|
}
|
||||||
|
|
||||||
r, usage, err := lm.CodeInterpreterAsk(llm.Messages().User().Text("计算[5,10,20,700,99,310,978,100]的平均值和方差。").Make(), func(text string) {
|
r, usage, err := lm.CodeInterpreterAsk(llm2.Messages().User().Text("计算[5,10,20,700,99,310,978,100]的平均值和方差。").Make(), func(text string) {
|
||||||
fmt.Print(u.BCyan(text))
|
fmt.Print(u.BCyan(text))
|
||||||
fmt.Print(" ")
|
fmt.Print(" ")
|
||||||
})
|
})
|
||||||
@ -81,13 +81,13 @@ func testCode(t *testing.T, llmName string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func testSearch(t *testing.T, llmName string) {
|
func testSearch(t *testing.T, llmName string) {
|
||||||
lm := llm.Get(llmName)
|
lm := llm2.Get(llmName)
|
||||||
|
|
||||||
if lm == nil {
|
if lm == nil {
|
||||||
t.Fatal("agent is nil")
|
t.Fatal("interface is nil")
|
||||||
}
|
}
|
||||||
|
|
||||||
r, usage, err := lm.WebSearchAsk(llm.Messages().User().Text("今天上海的天气怎么样?").Make(), func(text string) {
|
r, usage, err := lm.WebSearchAsk(llm2.Messages().User().Text("今天上海的天气怎么样?").Make(), func(text string) {
|
||||||
fmt.Print(u.BCyan(text))
|
fmt.Print(u.BCyan(text))
|
||||||
fmt.Print(" ")
|
fmt.Print(" ")
|
||||||
})
|
})
|
||||||
@ -102,10 +102,10 @@ func testSearch(t *testing.T, llmName string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func testAskWithImage(t *testing.T, llmName, imageFile string) {
|
func testAskWithImage(t *testing.T, llmName, imageFile string) {
|
||||||
lm := llm.Get(llmName)
|
lm := llm2.Get(llmName)
|
||||||
|
|
||||||
if lm == nil {
|
if lm == nil {
|
||||||
t.Fatal("agent is nil")
|
t.Fatal("interface is nil")
|
||||||
}
|
}
|
||||||
|
|
||||||
ask := `请回答:
|
ask := `请回答:
|
||||||
@ -114,7 +114,7 @@ func testAskWithImage(t *testing.T, llmName, imageFile string) {
|
|||||||
3、正在用什么软件播放什么歌?谁演唱的?歌曲的大意是?
|
3、正在用什么软件播放什么歌?谁演唱的?歌曲的大意是?
|
||||||
4、后面的浏览器中正在浏览什么内容?猜测一下我浏览这个网页是想干嘛?
|
4、后面的浏览器中正在浏览什么内容?猜测一下我浏览这个网页是想干嘛?
|
||||||
`
|
`
|
||||||
r, usage, err := lm.MultiAsk(llm.Messages().User().Text(ask).Image("data:image/jpeg;base64,"+u.Base64(u.ReadFileBytesN(imageFile))).Make(), func(text string) {
|
r, usage, err := lm.MultiAsk(llm2.Messages().User().Text(ask).Image("data:image/jpeg;base64,"+u.Base64(u.ReadFileBytesN(imageFile))).Make(), func(text string) {
|
||||||
fmt.Print(u.BCyan(text))
|
fmt.Print(u.BCyan(text))
|
||||||
fmt.Print(" ")
|
fmt.Print(" ")
|
||||||
})
|
})
|
||||||
@ -129,10 +129,10 @@ func testAskWithImage(t *testing.T, llmName, imageFile string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func testAskWithVideo(t *testing.T, llmName, videoFile string) {
|
func testAskWithVideo(t *testing.T, llmName, videoFile string) {
|
||||||
lm := llm.Get(llmName)
|
lm := llm2.Get(llmName)
|
||||||
|
|
||||||
if lm == nil {
|
if lm == nil {
|
||||||
t.Fatal("agent is nil")
|
t.Fatal("interface is nil")
|
||||||
}
|
}
|
||||||
|
|
||||||
ask := `请回答:
|
ask := `请回答:
|
||||||
@ -140,7 +140,7 @@ func testAskWithVideo(t *testing.T, llmName, videoFile string) {
|
|||||||
4、后面的浏览器中正在浏览什么内容?猜测一下我浏览这个网页是想干嘛?
|
4、后面的浏览器中正在浏览什么内容?猜测一下我浏览这个网页是想干嘛?
|
||||||
`
|
`
|
||||||
|
|
||||||
r, usage, err := lm.MultiAsk(llm.Messages().User().Text(ask).Video("data:video/mp4,"+u.Base64(u.ReadFileBytesN(videoFile))).Make(), func(text string) {
|
r, usage, err := lm.MultiAsk(llm2.Messages().User().Text(ask).Video("data:video/mp4,"+u.Base64(u.ReadFileBytesN(videoFile))).Make(), func(text string) {
|
||||||
fmt.Print(u.BCyan(text))
|
fmt.Print(u.BCyan(text))
|
||||||
fmt.Print(" ")
|
fmt.Print(" ")
|
||||||
})
|
})
|
||||||
@ -155,13 +155,13 @@ func testAskWithVideo(t *testing.T, llmName, videoFile string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func testMakeImage(t *testing.T, llmName, prompt, refImage string) {
|
func testMakeImage(t *testing.T, llmName, prompt, refImage string) {
|
||||||
lm := llm.Get(llmName)
|
lm := llm2.Get(llmName)
|
||||||
|
|
||||||
if lm == nil {
|
if lm == nil {
|
||||||
t.Fatal("agent is nil")
|
t.Fatal("interface is nil")
|
||||||
}
|
}
|
||||||
|
|
||||||
r, err := lm.FastMakeImage(prompt, llm.GCConfig{
|
r, err := lm.FastMakeImage(prompt, llm2.GCConfig{
|
||||||
Size: "1024x1024",
|
Size: "1024x1024",
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -176,13 +176,13 @@ func testMakeImage(t *testing.T, llmName, prompt, refImage string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func testMakeVideo(t *testing.T, llmName, prompt, refImage string) {
|
func testMakeVideo(t *testing.T, llmName, prompt, refImage string) {
|
||||||
lm := llm.Get(llmName)
|
lm := llm2.Get(llmName)
|
||||||
|
|
||||||
if lm == nil {
|
if lm == nil {
|
||||||
t.Fatal("agent is nil")
|
t.Fatal("interface is nil")
|
||||||
}
|
}
|
||||||
|
|
||||||
r, covers, err := lm.FastMakeVideo(prompt, llm.GCConfig{
|
r, covers, err := lm.FastMakeVideo(prompt, llm2.GCConfig{
|
||||||
Size: "1280x720",
|
Size: "1280x720",
|
||||||
Ref: refImage,
|
Ref: refImage,
|
||||||
})
|
})
|
||||||
|
Loading…
Reference in New Issue
Block a user