diff --git a/api/base/v1alpha1/embedder.go b/api/base/v1alpha1/embedder.go index 83a7d104f..be81ed316 100644 --- a/api/base/v1alpha1/embedder.go +++ b/api/base/v1alpha1/embedder.go @@ -77,6 +77,8 @@ func (e Embedder) Get3rdPartyModels() []string { return embeddings.ZhiPuAIModels case embeddings.OpenAI: return embeddings.OpenAIModels + case embeddings.Gemini: + return embeddings.GeminiModels } return []string{} diff --git a/api/base/v1alpha1/llm.go b/api/base/v1alpha1/llm.go index 75e49a1dc..fcf5dd67f 100644 --- a/api/base/v1alpha1/llm.go +++ b/api/base/v1alpha1/llm.go @@ -87,6 +87,8 @@ func (llm LLM) Get3rdPartyModels() []string { return llms.ZhiPuAIModels case llms.OpenAI: return llms.OpenAIModels + case llms.Gemini: + return llms.GeminiModels } return []string{} } diff --git a/apiserver/pkg/chat/chat_docs.go b/apiserver/pkg/chat/chat_docs.go index be040125c..bbb7909ac 100644 --- a/apiserver/pkg/chat/chat_docs.go +++ b/apiserver/pkg/chat/chat_docs.go @@ -282,7 +282,7 @@ func (cs *ChatServer) GenerateSingleDocSummary(ctx context.Context, req Conversa return "", fmt.Errorf("failed to get app due to %s", err.Error()) } - var llm langchainllms.LLM + var llm langchainllms.Model var mpChainNode runtimebase.BaseNode // find LLM along with chain call options for _, n := range app.Spec.Nodes { diff --git a/apiserver/pkg/chat/chat_server.go b/apiserver/pkg/chat/chat_server.go index fb9f5e08d..8aaac3d6e 100644 --- a/apiserver/pkg/chat/chat_server.go +++ b/apiserver/pkg/chat/chat_server.go @@ -210,7 +210,7 @@ func (cs *ChatServer) ListPromptStarters(ctx context.Context, req APPMetadata, l } var kb *v1alpha1.KnowledgeBase var chainOptions []chains.ChainCallOption - var model langchainllms.LLM + var model langchainllms.Model for _, n := range app.Spec.Nodes { baseNode := base.NewBaseNode(app.Namespace, n.Name, *n.Ref) switch baseNode.Group() { diff --git a/config/samples/app_shared_llm_service_gemini.yaml b/config/samples/app_shared_llm_service_gemini.yaml new file mode 100644 index 000000000..354f1abf8 --- /dev/null +++ b/config/samples/app_shared_llm_service_gemini.yaml @@ -0,0 +1,22 @@ +apiVersion: v1 +kind: Secret +metadata: + name: app-shared-llm-secret + namespace: arcadia +type: Opaque +data: + apiKey: "QUl6YVN5QVZOdGRYOHpkeU5pNWpubzNYSExUWGM0UnpJSGxIRUFz" +--- +apiVersion: arcadia.kubeagi.k8s.com.cn/v1alpha1 +kind: LLM +metadata: + name: app-shared-llm-service + namespace: arcadia +spec: + type: "gemini" + provider: + endpoint: + url: "https://generativelanguage.googleapis.com/" + authSecret: + kind: secret + name: app-shared-llm-secret diff --git a/config/samples/app_shared_llm_service.yaml b/config/samples/app_shared_llm_service_zhipu.yaml similarity index 100% rename from config/samples/app_shared_llm_service.yaml rename to config/samples/app_shared_llm_service_zhipu.yaml diff --git a/config/samples/arcadia_v1alpha1_embedders_gemini.yaml b/config/samples/arcadia_v1alpha1_embedders_gemini.yaml new file mode 100644 index 000000000..5fd811202 --- /dev/null +++ b/config/samples/arcadia_v1alpha1_embedders_gemini.yaml @@ -0,0 +1,22 @@ +apiVersion: v1 +kind: Secret +metadata: + name: gemini + namespace: arcadia +type: Opaque +data: + apiKey: "QUl6YVN5QVZOdGRYOHpkeU5pNWpubzNYSExUWGM0UnpJSGxIRUFz" +--- +apiVersion: arcadia.kubeagi.k8s.com.cn/v1alpha1 +kind: Embedder +metadata: + name: embedders-sample + namespace: arcadia +spec: + type: "gemini" + provider: + endpoint: + url: "https://generativelanguage.googleapis.com/" + authSecret: + kind: secret + name: gemini diff --git a/config/samples/arcadia_v1alpha1_embedders.yaml b/config/samples/arcadia_v1alpha1_embedders_zhipu.yaml similarity index 94% rename from config/samples/arcadia_v1alpha1_embedders.yaml rename to config/samples/arcadia_v1alpha1_embedders_zhipu.yaml index c5b0fd050..7a58cde85 100644 --- a/config/samples/arcadia_v1alpha1_embedders.yaml +++ b/config/samples/arcadia_v1alpha1_embedders_zhipu.yaml @@ -10,7 +10,7 @@ data: apiVersion: arcadia.kubeagi.k8s.com.cn/v1alpha1 kind: Embedder metadata: - name: zhipuai-embedders-sample + name: embedders-sample namespace: arcadia spec: type: "zhipuai" diff --git a/config/samples/arcadia_v1alpha1_knowledgebase.yaml b/config/samples/arcadia_v1alpha1_knowledgebase.yaml index c0db4915e..0736336eb 100644 --- a/config/samples/arcadia_v1alpha1_knowledgebase.yaml +++ b/config/samples/arcadia_v1alpha1_knowledgebase.yaml @@ -8,7 +8,7 @@ spec: description: "测试 KnowledgeBase" embedder: kind: Embedders - name: zhipuai-embedders-sample + name: embedders-sample namespace: arcadia vectorStore: kind: VectorStores diff --git a/config/samples/arcadia_v1alpha1_knowledgebase_pgvector.yaml b/config/samples/arcadia_v1alpha1_knowledgebase_pgvector.yaml index e63c8f2b0..e57d4d33d 100644 --- a/config/samples/arcadia_v1alpha1_knowledgebase_pgvector.yaml +++ b/config/samples/arcadia_v1alpha1_knowledgebase_pgvector.yaml @@ -8,7 +8,7 @@ spec: description: "测试 KnowledgeBase" embedder: kind: Embedders - name: zhipuai-embedders-sample + name: embedders-sample namespace: arcadia vectorStore: kind: VectorStores diff --git a/controllers/base/embedder_controller.go b/controllers/base/embedder_controller.go index a620a4a48..4e522cd6e 100644 --- a/controllers/base/embedder_controller.go +++ b/controllers/base/embedder_controller.go @@ -24,6 +24,7 @@ import ( "github.com/go-logr/logr" langchainembeddings "github.com/tmc/langchaingo/embeddings" + "github.com/tmc/langchaingo/llms/googleai" langchainopenai "github.com/tmc/langchaingo/llms/openai" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/types" @@ -227,6 +228,27 @@ func (r *EmbedderReconciler) check3rdPartyEmbedder(ctx context.Context, logger l } msg = "Success" } + case embeddings.Gemini: + // validate all embedding models + for _, model := range models { + llm, err := googleai.New( + ctx, + googleai.WithAPIKey(apiKey), + googleai.WithDefaultEmbeddingModel(model), + ) + if err != nil { + return r.UpdateStatus(ctx, instance, nil, err) + } + embedClient, err := langchainembeddings.NewEmbedder(llm) + if err != nil { + return r.UpdateStatus(ctx, instance, nil, err) + } + _, err = embedClient.EmbedQuery(ctx, embedingText) + if err != nil { + return r.UpdateStatus(ctx, instance, nil, err) + } + msg = "Success" + } default: return r.UpdateStatus(ctx, instance, nil, fmt.Errorf("unsupported service type: %s", instance.Spec.Type)) } diff --git a/controllers/base/llm_controller.go b/controllers/base/llm_controller.go index 35aa6d12e..157a98306 100644 --- a/controllers/base/llm_controller.go +++ b/controllers/base/llm_controller.go @@ -25,6 +25,7 @@ import ( "github.com/go-logr/logr" langchainllms "github.com/tmc/langchaingo/llms" + "github.com/tmc/langchaingo/llms/googleai" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/types" ctrl "sigs.k8s.io/controller-runtime" @@ -215,6 +216,19 @@ func (r *LLMReconciler) check3rdPartyLLM(ctx context.Context, logger logr.Logger } msg = strings.Join([]string{msg, res.String()}, "\n") } + case llms.Gemini: + llmClient, err := googleai.New(ctx, googleai.WithAPIKey(apiKey)) + if err != nil { + return r.UpdateStatus(ctx, instance, nil, err) + } + // validate against models + for _, model := range models { + res, err := llmClient.Call(ctx, "Hello", langchainllms.WithModel(model)) + if err != nil { + return r.UpdateStatus(ctx, instance, nil, err) + } + msg = strings.Join([]string{msg, res}, "\n") + } default: return r.UpdateStatus(ctx, instance, nil, fmt.Errorf("unsupported service type: %s", instance.Spec.Type)) } diff --git a/controllers/base/prompt_controller.go b/controllers/base/prompt_controller.go index 2b9460e5e..1d306f475 100644 --- a/controllers/base/prompt_controller.go +++ b/controllers/base/prompt_controller.go @@ -18,6 +18,7 @@ package controllers import ( "context" + "errors" "fmt" "reflect" @@ -139,6 +140,8 @@ func (r *PromptReconciler) CallLLM(ctx context.Context, logger logr.Logger, prom if err != nil { return r.UpdateStatus(ctx, prompt, nil, err) } + case llms.Gemini: + return r.UpdateStatus(ctx, prompt, nil, errors.New("not implemented yet")) default: llmClient = llms.NewUnknowLLM() } diff --git a/go.mod b/go.mod index e69f419d3..de787403b 100644 --- a/go.mod +++ b/go.mod @@ -7,7 +7,7 @@ toolchain go1.21.5 require ( github.com/99designs/gqlgen v0.17.40 github.com/KawashiroNitori/butcher/v2 v2.0.1 - github.com/amikos-tech/chroma-go v0.0.0-20231228181736-e8f5e927093e + github.com/amikos-tech/chroma-go v0.0.0-20240109142503-c8fb49c3e28c github.com/coreos/go-oidc/v3 v3.7.0 github.com/gin-contrib/requestid v0.0.6 github.com/gin-gonic/gin v1.9.1 @@ -36,6 +36,8 @@ require ( ) require ( + cloud.google.com/go/ai v0.3.0 // indirect + cloud.google.com/go/longrunning v0.5.4 // indirect github.com/KyleBanks/depth v1.2.1 // indirect github.com/Masterminds/goutils v1.1.1 // indirect github.com/Masterminds/semver/v3 v3.2.0 // indirect @@ -58,6 +60,10 @@ require ( github.com/gobwas/glob v0.2.3 // indirect github.com/goccy/go-json v0.10.2 // indirect github.com/gocolly/colly v1.2.0 // indirect + github.com/google/generative-ai-go v0.5.0 // indirect + github.com/google/s2a-go v0.1.7 // indirect + github.com/googleapis/enterprise-certificate-proxy v0.3.2 // indirect + github.com/googleapis/gax-go/v2 v2.12.0 // indirect github.com/goph/emperror v0.17.2 // indirect github.com/gorilla/websocket v1.5.0 // indirect github.com/hashicorp/golang-lru/v2 v2.0.3 // indirect @@ -89,15 +95,21 @@ require ( github.com/twitchyliquid64/golang-asm v0.15.1 // indirect github.com/ugorji/go/codec v1.2.12 // indirect github.com/yargevad/filepathx v1.0.0 // indirect + go.opencensus.io v0.24.0 // indirect go.starlark.net v0.0.0-20230302034142-4b1e35fe2254 // indirect golang.org/x/arch v0.6.0 // indirect golang.org/x/sync v0.5.0 // indirect golang.org/x/tools v0.16.1 // indirect + google.golang.org/api v0.152.0 // indirect + google.golang.org/genproto v0.0.0-20231120223509-83a465c0220f // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20231211222908-989df2bf70f3 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20231211222908-989df2bf70f3 // indirect + google.golang.org/grpc v1.60.0 // indirect gopkg.in/ini.v1 v1.67.0 // indirect ) require ( - cloud.google.com/go/compute v1.23.1 // indirect + cloud.google.com/go/compute v1.23.3 // indirect cloud.google.com/go/compute/metadata v0.2.3 // indirect github.com/Azure/go-autorest v14.2.0+incompatible // indirect github.com/Azure/go-autorest/autorest v0.11.18 // indirect @@ -110,7 +122,7 @@ require ( github.com/andybalholm/cascadia v1.3.2 // indirect github.com/aymerick/douceur v0.2.0 // indirect github.com/beorn7/perks v1.0.1 // indirect - github.com/cespare/xxhash/v2 v2.1.2 // indirect + github.com/cespare/xxhash/v2 v2.2.0 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/dlclark/regexp2 v1.8.1 // indirect github.com/emicklei/go-restful v2.9.5+incompatible // indirect @@ -129,11 +141,11 @@ require ( github.com/google/gofuzz v1.1.0 // indirect github.com/google/uuid v1.5.0 // indirect github.com/gorilla/css v1.0.0 // indirect - github.com/imdario/mergo v0.3.12 // indirect + github.com/imdario/mergo v0.3.13 // indirect github.com/inconshreveable/mousetrap v1.0.0 // indirect github.com/josharian/intern v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect - github.com/klauspost/compress v1.17.0 // indirect + github.com/klauspost/compress v1.17.2 // indirect github.com/ledongthuc/pdf v0.0.0-20220302134840-0c2507a12d80 // indirect github.com/mailru/easyjson v0.7.7 // indirect github.com/mattn/go-colorable v0.1.13 // indirect @@ -167,11 +179,11 @@ require ( golang.org/x/crypto v0.17.0 // indirect golang.org/x/exp v0.0.0-20230713183714-613f0c0eb8a1 // indirect golang.org/x/net v0.19.0 // indirect - golang.org/x/oauth2 v0.13.0 + golang.org/x/oauth2 v0.15.0 golang.org/x/sys v0.15.0 // indirect golang.org/x/term v0.15.0 // indirect golang.org/x/text v0.14.0 // indirect - golang.org/x/time v0.0.0-20220210224613-90d013bbcef8 // indirect + golang.org/x/time v0.5.0 // indirect gomodules.xyz/jsonpatch/v2 v2.2.0 // indirect google.golang.org/appengine v1.6.8 // indirect google.golang.org/protobuf v1.32.0 // indirect @@ -189,4 +201,4 @@ require ( sigs.k8s.io/yaml v1.3.0 // indirect ) -replace github.com/tmc/langchaingo => github.com/kubeagi/langchaingo v0.0.0-20240228082936-a5a23d621373 // branch dev +replace github.com/tmc/langchaingo => github.com/kubeagi/langchaingo v0.0.0-20240229054113-5336bfef6e5e // branch dev diff --git a/go.sum b/go.sum index b3035d82b..05104a759 100644 --- a/go.sum +++ b/go.sum @@ -18,27 +18,29 @@ cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmW cloud.google.com/go v0.78.0/go.mod h1:QjdrLG0uq+YwhjoVOLsS1t7TW8fs36kLs4XO5R5ECHg= cloud.google.com/go v0.79.0/go.mod h1:3bzgcEeQlzbuEAYu4mrWhKqWjmpprinYgKJLgKHnbb8= cloud.google.com/go v0.81.0/go.mod h1:mk/AM35KwGk/Nm2YSeZbxXdrNK3KZOYHmLkOqC2V6E0= -cloud.google.com/go v0.110.8 h1:tyNdfIxjzaWctIiLYOTalaLKZ17SI44SKFW26QbOhME= -cloud.google.com/go v0.110.8/go.mod h1:Iz8AkXJf1qmxC3Oxoep8R1T36w8B92yU29PcBhHO5fk= -cloud.google.com/go/aiplatform v1.51.1 h1:g+y03dll9HnX9U0oBKIqUOI+8VQWT1QJF12VGxkal0Q= -cloud.google.com/go/aiplatform v1.51.1/go.mod h1:kY3nIMAVQOK2XDqDPHaOuD9e+FdMA6OOpfBjsvaFSOo= +cloud.google.com/go v0.111.0 h1:YHLKNupSD1KqjDbQ3+LVdQ81h/UJbJyZG203cEfnQgM= +cloud.google.com/go v0.111.0/go.mod h1:0mibmpKP1TyOOFYQY5izo0LnT+ecvOQ0Sg3OdmMiNRU= +cloud.google.com/go/ai v0.3.0 h1:M617N0brv+XFch2KToZUhv6ggzgFZMUnmDkNQjW2pYg= +cloud.google.com/go/ai v0.3.0/go.mod h1:dTuQIBA8Kljuas5z1WNot1QZOl476A9TsFqEi6pzJlI= +cloud.google.com/go/aiplatform v1.58.0 h1:xyCAfpI4yUMOQ4VtHN/bdmxPQ8xoEkTwFM1nbVmuQhs= +cloud.google.com/go/aiplatform v1.58.0/go.mod h1:pwZMGvqe0JRkI1GWSZCtnAfrR4K1bv65IHILGA//VEU= cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= -cloud.google.com/go/compute v1.23.1 h1:V97tBoDaZHb6leicZ1G6DLK2BAaZLJ/7+9BB/En3hR0= -cloud.google.com/go/compute v1.23.1/go.mod h1:CqB3xpmPKKt3OJpW2ndFIXnA9A4xAy/F3Xp1ixncW78= +cloud.google.com/go/compute v1.23.3 h1:6sVlXXBmbd7jNX0Ipq0trII3e4n1/MsADLK6a+aiVlk= +cloud.google.com/go/compute v1.23.3/go.mod h1:VCgBUoMnIVIR0CscqQiPJLAG25E3ZRZMzcFZeQ+h8CI= cloud.google.com/go/compute/metadata v0.2.3 h1:mg4jlk7mCAj6xXp9UJ4fjI9VUI5rubuGBW5aJ7UnBMY= cloud.google.com/go/compute/metadata v0.2.3/go.mod h1:VAV5nSsACxMJvgaAuX6Pk2AawlZn8kiOGuCv6gTkwuA= cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= cloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk= -cloud.google.com/go/iam v1.1.3 h1:18tKG7DzydKWUnLjonWcJO6wjSCAtzh4GcRKlH/Hrzc= -cloud.google.com/go/iam v1.1.3/go.mod h1:3khUlaBXfPKKe7huYgEpDn6FtgRyMEqbkvBxrQyY5SE= -cloud.google.com/go/longrunning v0.5.2 h1:u+oFqfEwwU7F9dIELigxbe0XVnBAo9wqMuQLA50CZ5k= -cloud.google.com/go/longrunning v0.5.2/go.mod h1:nqo6DQbNV2pXhGDbDMoN2bWz68MjZUzqv2YttZiveCs= +cloud.google.com/go/iam v1.1.5 h1:1jTsCu4bcsNsE4iiqNT5SHwrDRCfRmIaaaVFhRveTJI= +cloud.google.com/go/iam v1.1.5/go.mod h1:rB6P/Ic3mykPbFio+vo7403drjlgvoWfYpJhMXEbzv8= +cloud.google.com/go/longrunning v0.5.4 h1:w8xEcbZodnA2BbW6sVirkkoC+1gP8wS57EUUgGS0GVg= +cloud.google.com/go/longrunning v0.5.4/go.mod h1:zqNVncI0BOP8ST6XQD1+VcvuShMmq7+xFSzOL++V0dI= cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= @@ -93,8 +95,8 @@ github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuy github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= -github.com/amikos-tech/chroma-go v0.0.0-20231228181736-e8f5e927093e h1:68YtjXFDWgquXICyGFa0gZ+nqZbs4OURutAyUjH1mYs= -github.com/amikos-tech/chroma-go v0.0.0-20231228181736-e8f5e927093e/go.mod h1:uJwgGN4rBUTMI88Rn68Xia+cTRogOo0/elcPvJYFtBU= +github.com/amikos-tech/chroma-go v0.0.0-20240109142503-c8fb49c3e28c h1:DzSXJSUVK5ed+HhAnGA1TKgBdXqAW/iXPRvpd9rXWLc= +github.com/amikos-tech/chroma-go v0.0.0-20240109142503-c8fb49c3e28c/go.mod h1:uJwgGN4rBUTMI88Rn68Xia+cTRogOo0/elcPvJYFtBU= github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883 h1:bvNMNQO63//z+xNgfBlViaCIJKLlCJ6/fmUseuG0wVQ= github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8= github.com/andybalholm/brotli v1.0.5 h1:8uQZIdzKmjc/iuPu7O2ioW48L81FgatrcpfFmiq/cCs= @@ -144,8 +146,9 @@ github.com/certifi/gocertifi v0.0.0-20191021191039-0944d244cd40/go.mod h1:sGbDF6 github.com/certifi/gocertifi v0.0.0-20200922220541-2c3bb06c6054/go.mod h1:sGbDF6GwGcLpkNXPUTkMRoywsNa/ol15pxFe6ERfguA= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE= github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= +github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/chenzhuoyu/base64x v0.0.0-20211019084208-fb5309c8db06/go.mod h1:DH46F32mSOjUmXrMHnKwZdA8wcEefY7UVqBKYGjpdQY= github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311/go.mod h1:b583jCggY9gE99b6G5LEC39OIiVsWj+R97kbl5odCEk= github.com/chenzhuoyu/base64x v0.0.0-20230717121745-296ad89f973d h1:77cEq6EriyTZ0g/qfRdp61a3Uu/AWrgIq2s0ClJV1g0= @@ -341,6 +344,8 @@ github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ github.com/google/btree v1.0.1/go.mod h1:xXMiIv4Fb/0kKde4SpL7qlzvu5cMJDRkFDxJfI9uaxA= github.com/google/cel-go v0.10.1/go.mod h1:U7ayypeSkw23szu4GaQTPJGx66c20mx8JklMSxrmI1w= github.com/google/cel-spec v0.6.0/go.mod h1:Nwjgxy5CbjlPrtCWjeDjUyKMl8w41YBYGjsyDdqk0xA= +github.com/google/generative-ai-go v0.5.0 h1:PfzPuSGdsmcSyPG7RIoijcKWZ7/x2kvgyNryvmXMUmA= +github.com/google/generative-ai-go v0.5.0/go.mod h1:8fXQk4w+eyTzFokGGJrBFL0/xwXqm3QNhTqOWyX11zs= github.com/google/gnostic v0.5.7-v3refs h1:FhTMOKj2VhjpouxvWJAV1TL304uMlb9zcDqkl6cEI54= github.com/google/gnostic v0.5.7-v3refs/go.mod h1:73MKFl6jIHelAJNaBGFzt3SPtZULs9dYrGFt8OiIsHQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= @@ -433,8 +438,8 @@ github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1: github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= github.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= -github.com/imdario/mergo v0.3.12 h1:b6R2BslTbIEToALKP7LxUvijTsNI9TAe80pLWN2g/HU= -github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= +github.com/imdario/mergo v0.3.13 h1:lFzP57bqS/wsqKssCGmtLAb8A0wKjLGrve2q3PPVcBk= +github.com/imdario/mergo v0.3.13/go.mod h1:4lJ1jqUDcsbIECGy0RUJAXNIhg+6ocWgb1ALK2O4oXg= github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM= @@ -474,8 +479,8 @@ github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvW github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= -github.com/klauspost/compress v1.17.0 h1:Rnbp4K9EjcDuVuHtd0dgA4qNuv9yKDYKK1ulpJwgrqM= -github.com/klauspost/compress v1.17.0/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= +github.com/klauspost/compress v1.17.2 h1:RlWWUY/Dr4fL8qk9YG7DTZ7PDgME2V4csBXA8L/ixi4= +github.com/klauspost/compress v1.17.2/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= github.com/klauspost/cpuid/v2 v2.0.1/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.2.6 h1:ndNyv040zDGIDh8thGkXYjnFtiN02M1PVVF+JE/48xc= @@ -495,8 +500,8 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= -github.com/kubeagi/langchaingo v0.0.0-20240228082936-a5a23d621373 h1:g6A1cXPE+ixJ+Tfrt9fPsaZliZGEUHHbAYlF798+ww8= -github.com/kubeagi/langchaingo v0.0.0-20240228082936-a5a23d621373/go.mod h1:vOFzX91wqTXvirejd6xjPXSmGn8yYKHt/FunAgrOBmI= +github.com/kubeagi/langchaingo v0.0.0-20240229054113-5336bfef6e5e h1:xNUDtr3TdqEfXnD4pKi//eyKaWeAG3fNSupW8PxL5Rg= +github.com/kubeagi/langchaingo v0.0.0-20240229054113-5336bfef6e5e/go.mod h1:RLtnUED/hH2v765vdjS9Z6gonErZAXURuJHph0BttqM= github.com/ledongthuc/pdf v0.0.0-20220302134840-0c2507a12d80 h1:6Yzfa6GP0rIo/kULo2bwGEkFvCePZ3qHDDTC3/J9Swo= github.com/ledongthuc/pdf v0.0.0-20220302134840-0c2507a12d80/go.mod h1:imJHygn/1yfhB7XSJJKlFZKl/J+dCPAknuiaGOshXAs= github.com/leodido/go-urn v1.2.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ictyFfxY= @@ -950,8 +955,8 @@ golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.13.0 h1:jDDenyj+WgFtmV3zYVoi8aE2BwtXFLWOA67ZfNWftiY= -golang.org/x/oauth2 v0.13.0/go.mod h1:/JMhi4ZRXAf4HG9LiNmxvk+45+96RUlVThiH8FzNBn0= +golang.org/x/oauth2 v0.15.0 h1:s8pnnxNVzjWyrvYdFUQq5llS1PX2zhPXmccZv99h7uQ= +golang.org/x/oauth2 v0.15.0/go.mod h1:q48ptWNTY5XWf+JNten23lcvHpLJ0ZSxF5ttTHKVCAM= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -1074,8 +1079,9 @@ golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxb golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20220210224613-90d013bbcef8 h1:vVKdlvoWBphwdxWKrFZEuM0kGgGLxUOYcY4U/2Vjg44= golang.org/x/time v0.0.0-20220210224613-90d013bbcef8/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= +golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -1166,8 +1172,8 @@ google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34q google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8= google.golang.org/api v0.41.0/go.mod h1:RkxM5lITDfTzmyKFPt+wGrCJbVfniCr2ool8kTBzRTU= google.golang.org/api v0.43.0/go.mod h1:nQsDGjRXMo4lvh5hP0TKqF244gqhGcr/YSIykhUk/94= -google.golang.org/api v0.149.0 h1:b2CqT6kG+zqJIVKRQ3ELJVLN1PwHZ6DJ3dW8yl82rgY= -google.golang.org/api v0.149.0/go.mod h1:Mwn1B7JTXrzXtnvmzQE2BD6bYZQ8DShKZDZbeN9I7qI= +google.golang.org/api v0.152.0 h1:t0r1vPnfMc260S2Ci+en7kfCZaLOPs5KI0sVV/6jZrY= +google.golang.org/api v0.152.0/go.mod h1:3qNJX5eOmhiWYc67jRA/3GsDw97UFb5ivv7Y2PrriAY= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= @@ -1223,12 +1229,12 @@ google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaE google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= google.golang.org/genproto v0.0.0-20210831024726-fe130286e0e2/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= google.golang.org/genproto v0.0.0-20220107163113-42d7afdf6368/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20231016165738-49dd2c1f3d0b h1:+YaDE2r2OG8t/z5qmsh7Y+XXwCbvadxxZ0YY6mTdrVA= -google.golang.org/genproto v0.0.0-20231016165738-49dd2c1f3d0b/go.mod h1:CgAqfJo+Xmu0GwA0411Ht3OU3OntXwsGmrmjI8ioGXI= -google.golang.org/genproto/googleapis/api v0.0.0-20231016165738-49dd2c1f3d0b h1:CIC2YMXmIhYw6evmhPxBKJ4fmLbOFtXQN/GV3XOZR8k= -google.golang.org/genproto/googleapis/api v0.0.0-20231016165738-49dd2c1f3d0b/go.mod h1:IBQ646DjkDkvUIsVq/cc03FUFQ9wbZu7yE396YcL870= -google.golang.org/genproto/googleapis/rpc v0.0.0-20231016165738-49dd2c1f3d0b h1:ZlWIi1wSK56/8hn4QcBp/j9M7Gt3U/3hZw3mC7vDICo= -google.golang.org/genproto/googleapis/rpc v0.0.0-20231016165738-49dd2c1f3d0b/go.mod h1:swOH3j0KzcDDgGUWr+SNpyTen5YrXjS3eyPzFYKc6lc= +google.golang.org/genproto v0.0.0-20231120223509-83a465c0220f h1:Vn+VyHU5guc9KjB5KrjI2q0wCOWEOIh0OEsleqakHJg= +google.golang.org/genproto v0.0.0-20231120223509-83a465c0220f/go.mod h1:nWSwAFPb+qfNJXsoeO3Io7zf4tMSfN8EA8RlDA04GhY= +google.golang.org/genproto/googleapis/api v0.0.0-20231211222908-989df2bf70f3 h1:EWIeHfGuUf00zrVZGEgYFxok7plSAXBGcH7NNdMAWvA= +google.golang.org/genproto/googleapis/api v0.0.0-20231211222908-989df2bf70f3/go.mod h1:k2dtGpRrbsSyKcNPKKI5sstZkrNCZwpU/ns96JoHbGg= +google.golang.org/genproto/googleapis/rpc v0.0.0-20231211222908-989df2bf70f3 h1:kzJAXnzZoFbe5bhZd4zjUuHos/I31yH4thfMb/13oVY= +google.golang.org/genproto/googleapis/rpc v0.0.0-20231211222908-989df2bf70f3/go.mod h1:eJVxU6o+4G1PSczBr85xmyvSNYAKvAYgkub40YGomFM= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= @@ -1251,8 +1257,8 @@ google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAG google.golang.org/grpc v1.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= -google.golang.org/grpc v1.59.0 h1:Z5Iec2pjwb+LEOqzpB2MR12/eKFhDPhuqW91O+4bwUk= -google.golang.org/grpc v1.59.0/go.mod h1:aUPDwccQo6OTjy7Hct4AfBPD1GptF4fyUjIkQ9YtF98= +google.golang.org/grpc v1.60.0 h1:6FQAR0kM31P6MRdeluor2w2gPaS4SVNrD/DNTxrQ15k= +google.golang.org/grpc v1.60.0/go.mod h1:OlCHIeLYqSSsLi6i49B5QGdzaMZK9+M7LXN2FKz4eGM= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= @@ -1303,6 +1309,7 @@ gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gorm.io/driver/postgres v1.5.4 h1:Iyrp9Meh3GmbSuyIAGyjkN+n9K+GHX9b9MqsTL4EJCo= diff --git a/pkg/appruntime/agent/executor.go b/pkg/appruntime/agent/executor.go index 5af7a3222..f086ed140 100644 --- a/pkg/appruntime/agent/executor.go +++ b/pkg/appruntime/agent/executor.go @@ -52,9 +52,9 @@ func (p *Executor) Run(ctx context.Context, cli client.Client, args map[string]a if !ok { return args, errors.New("no llm") } - llm, ok := v1.(llms.LLM) + llm, ok := v1.(llms.Model) if !ok { - return args, errors.New("llm not llms.LanguageModel") + return args, errors.New("llm not llms.Model") } instance := &v1alpha1.Agent{} if err := cli.Get(ctx, types.NamespacedName{Namespace: p.RefNamespace(), Name: p.Ref.Name}, instance); err != nil { diff --git a/pkg/appruntime/chain/apichain.go b/pkg/appruntime/chain/apichain.go index c1d5df8fb..f457e8b4e 100644 --- a/pkg/appruntime/chain/apichain.go +++ b/pkg/appruntime/chain/apichain.go @@ -58,9 +58,9 @@ func (l *APIChain) Run(ctx context.Context, _ client.Client, args map[string]any if !ok { return args, errors.New("no llm") } - llm, ok := v1.(llms.LLM) + llm, ok := v1.(llms.Model) if !ok { - return args, errors.New("llm not llms.LanguageModel") + return args, errors.New("llm not llms.Model") } v2, ok := args["prompt"] if !ok { diff --git a/pkg/appruntime/chain/common.go b/pkg/appruntime/chain/common.go index ca52ca585..bfd46bae2 100644 --- a/pkg/appruntime/chain/common.go +++ b/pkg/appruntime/chain/common.go @@ -88,7 +88,7 @@ func GetChainOptions(config v1alpha1.CommonChainConfig) []chains.ChainCallOption return options } -func getMemory(llm llms.LLM, config v1alpha1.Memory, history langchaingoschema.ChatMessageHistory, inputKey, outputKey string) langchaingoschema.Memory { +func getMemory(llm llms.Model, config v1alpha1.Memory, history langchaingoschema.ChatMessageHistory, inputKey, outputKey string) langchaingoschema.Memory { if inputKey == "" { inputKey = "question" } diff --git a/pkg/appruntime/chain/llmchain.go b/pkg/appruntime/chain/llmchain.go index 865047505..ad82d99dd 100644 --- a/pkg/appruntime/chain/llmchain.go +++ b/pkg/appruntime/chain/llmchain.go @@ -60,9 +60,9 @@ func (l *LLMChain) Run(ctx context.Context, _ client.Client, args map[string]any if !ok { return args, errors.New("no llm") } - llm, ok := v1.(llms.LLM) + llm, ok := v1.(llms.Model) if !ok { - return args, errors.New("llm not llms.LanguageModel") + return args, errors.New("llm not llms.Model") } v2, ok := args["prompt"] if !ok { diff --git a/pkg/appruntime/chain/mpchain.go b/pkg/appruntime/chain/mpchain.go index 6227333ba..05a1644f8 100644 --- a/pkg/appruntime/chain/mpchain.go +++ b/pkg/appruntime/chain/mpchain.go @@ -93,9 +93,9 @@ func (l *MapReduceChain) Init(ctx context.Context, cli client.Client, args map[s if !ok { return errors.New("no llm") } - llm, ok := v1.(llms.LLM) + llm, ok := v1.(llms.Model) if !ok { - return errors.New("llm not llms.LLM") + return errors.New("llm not llms.Model") } // only group `chain` is allowed diff --git a/pkg/appruntime/chain/retrievalqachain.go b/pkg/appruntime/chain/retrievalqachain.go index ac8390b8e..0653de904 100644 --- a/pkg/appruntime/chain/retrievalqachain.go +++ b/pkg/appruntime/chain/retrievalqachain.go @@ -61,9 +61,9 @@ func (l *RetrievalQAChain) Run(ctx context.Context, _ client.Client, args map[st if !ok { return args, errors.New("no llm") } - llm, ok := v1.(llms.LLM) + llm, ok := v1.(llms.Model) if !ok { - return args, errors.New("llm not llms.LanguageModel") + return args, errors.New("llm not llms.Model") } v2, ok := args["prompt"] if !ok { diff --git a/pkg/appruntime/log/log.go b/pkg/appruntime/log/log.go new file mode 100644 index 000000000..0682e5b54 --- /dev/null +++ b/pkg/appruntime/log/log.go @@ -0,0 +1,160 @@ +/* +Copyright 2024 KubeAGI. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package log + +import ( + "context" + "fmt" + "strings" + + "github.com/tmc/langchaingo/callbacks" + "github.com/tmc/langchaingo/llms" + "github.com/tmc/langchaingo/schema" + "k8s.io/klog/v2" +) + +// KLogHandler is a callback handler that prints to klog v3 +type KLogHandler struct { + LogLevel int +} + +var _ callbacks.Handler = KLogHandler{} + +func (l KLogHandler) HandleLLMGenerateContentStart(ctx context.Context, ms []llms.MessageContent) { + logger := klog.FromContext(ctx) + logger.V(l.LogLevel).Info("Entering LLM with messages:") + for _, m := range ms { + // TODO: Implement logging of other content types + var buf strings.Builder + for _, t := range m.Parts { + if t, ok := t.(llms.TextContent); ok { + buf.WriteString(t.Text) + } + } + logger.V(l.LogLevel).Info("Role:", m.Role) + logger.V(l.LogLevel).Info("Text:", buf.String()) + } +} + +func (l KLogHandler) HandleLLMGenerateContentEnd(ctx context.Context, res *llms.ContentResponse) { + logger := klog.FromContext(ctx) + logger.V(l.LogLevel).Info("Exiting LLM with response:") + for _, c := range res.Choices { + if c.Content != "" { + logger.V(l.LogLevel).Info("Content:", c.Content) + } + if c.StopReason != "" { + logger.V(l.LogLevel).Info("StopReason:", c.StopReason) + } + if len(c.GenerationInfo) > 0 { + logger.V(l.LogLevel).Info("GenerationInfo:") + for k, v := range c.GenerationInfo { + fmt.Printf("%20s: %v\n", k, v) + } + } + if c.FuncCall != nil { + logger.V(l.LogLevel).Info("FuncCall: ", c.FuncCall.Name, c.FuncCall.Arguments) + } + } +} + +func (l KLogHandler) HandleStreamingFunc(ctx context.Context, chunk []byte) { + logger := klog.FromContext(ctx) + logger.V(l.LogLevel).Info(string(chunk)) +} + +func (l KLogHandler) HandleText(ctx context.Context, text string) { + logger := klog.FromContext(ctx) + logger.V(l.LogLevel).Info(text) +} + +func (l KLogHandler) HandleLLMStart(ctx context.Context, prompts []string) { + logger := klog.FromContext(ctx) + logger.V(l.LogLevel).Info("Entering LLM with prompts:", prompts) +} + +func (l KLogHandler) HandleLLMError(ctx context.Context, err error) { + logger := klog.FromContext(ctx) + logger.V(l.LogLevel).Info("Exiting LLM with error:", err) +} + +func (l KLogHandler) HandleChainStart(ctx context.Context, inputs map[string]any) { + logger := klog.FromContext(ctx) + logger.V(l.LogLevel).Info("Entering chain with inputs:", formatChainValues(inputs)) +} + +func (l KLogHandler) HandleChainEnd(ctx context.Context, outputs map[string]any) { + logger := klog.FromContext(ctx) + logger.V(l.LogLevel).Info("Exiting chain with outputs:", formatChainValues(outputs)) +} + +func (l KLogHandler) HandleChainError(ctx context.Context, err error) { + logger := klog.FromContext(ctx) + logger.V(l.LogLevel).Info("Exiting chain with error:", err) +} + +func (l KLogHandler) HandleToolStart(ctx context.Context, input string) { + logger := klog.FromContext(ctx) + logger.V(l.LogLevel).Info("Entering tool with input:", removeNewLines(input)) +} + +func (l KLogHandler) HandleToolEnd(ctx context.Context, output string) { + logger := klog.FromContext(ctx) + logger.V(l.LogLevel).Info("Exiting tool with output:", removeNewLines(output)) +} + +func (l KLogHandler) HandleToolError(ctx context.Context, err error) { + logger := klog.FromContext(ctx) + logger.V(l.LogLevel).Info("Exiting tool with error:", err) +} + +func (l KLogHandler) HandleAgentAction(ctx context.Context, action schema.AgentAction) { + logger := klog.FromContext(ctx) + logger.V(l.LogLevel).Info("Agent selected action:", formatAgentAction(action)) +} + +func (l KLogHandler) HandleAgentFinish(ctx context.Context, finish schema.AgentFinish) { + logger := klog.FromContext(ctx) + logger.V(l.LogLevel).Info(fmt.Sprintf("Agent finish: %v", finish)) +} + +func (l KLogHandler) HandleRetrieverStart(ctx context.Context, query string) { + logger := klog.FromContext(ctx) + logger.V(l.LogLevel).Info("Entering retriever with query:", removeNewLines(query)) +} + +func (l KLogHandler) HandleRetrieverEnd(ctx context.Context, query string, documents []schema.Document) { + logger := klog.FromContext(ctx) + logger.V(l.LogLevel).Info(fmt.Sprintf("Exiting retriever with documents for query:%s documents: %v", query, documents)) +} + +func formatChainValues(values map[string]any) string { + output := "" + for key, value := range values { + output += fmt.Sprintf("\"%s\" : \"%s\", ", removeNewLines(key), removeNewLines(value)) + } + + return output +} + +func formatAgentAction(action schema.AgentAction) string { + return fmt.Sprintf("\"%s\" with input \"%s\"", removeNewLines(action.Tool), removeNewLines(action.ToolInput)) +} + +func removeNewLines(s any) string { + return strings.ReplaceAll(fmt.Sprint(s), "\n", " ") +} diff --git a/pkg/appruntime/retriever/knowledgebaseretriever.go b/pkg/appruntime/retriever/knowledgebaseretriever.go index ad549586a..f3334c26e 100644 --- a/pkg/appruntime/retriever/knowledgebaseretriever.go +++ b/pkg/appruntime/retriever/knowledgebaseretriever.go @@ -34,6 +34,7 @@ import ( apiretriever "github.com/kubeagi/arcadia/api/app-node/retriever/v1alpha1" "github.com/kubeagi/arcadia/api/base/v1alpha1" "github.com/kubeagi/arcadia/pkg/appruntime/base" + "github.com/kubeagi/arcadia/pkg/appruntime/log" "github.com/kubeagi/arcadia/pkg/documentloaders" "github.com/kubeagi/arcadia/pkg/langchainwrap" pkgvectorstore "github.com/kubeagi/arcadia/pkg/vectorstore" @@ -157,7 +158,11 @@ func (l *KnowledgeBaseRetriever) Run(ctx context.Context, cli client.Client, arg if err != nil { return nil, err } - l.Retriever = vectorstores.ToRetriever(s, instance.Spec.NumDocuments, vectorstores.WithScoreThreshold(instance.Spec.ScoreThreshold)) + logger := klog.FromContext(ctx) + logger.V(3).Info(fmt.Sprintf("retriever created with scorethreshold: %f", instance.Spec.ScoreThreshold)) + retriever := vectorstores.ToRetriever(s, instance.Spec.NumDocuments, vectorstores.WithScoreThreshold(instance.Spec.ScoreThreshold)) + retriever.CallbacksHandler = log.KLogHandler{LogLevel: 3} + l.Retriever = retriever args["retriever"] = l return args, nil } diff --git a/pkg/embeddings/embeddings.go b/pkg/embeddings/embeddings.go index ac259e080..4e938da64 100644 --- a/pkg/embeddings/embeddings.go +++ b/pkg/embeddings/embeddings.go @@ -21,10 +21,12 @@ type EmbeddingType string const ( OpenAI EmbeddingType = "openai" ZhiPuAI EmbeddingType = "zhipuai" + Gemini EmbeddingType = "gemini" Unknown EmbeddingType = "unknown" ) var ( ZhiPuAIModels = []string{"text_embedding"} OpenAIModels = []string{"text-embedding-ada-002"} + GeminiModels = []string{"embedding-001"} ) diff --git a/pkg/evaluation/jobs.go b/pkg/evaluation/jobs.go index 935e9ff3a..c072eed77 100644 --- a/pkg/evaluation/jobs.go +++ b/pkg/evaluation/jobs.go @@ -215,6 +215,8 @@ func JudgeJobGenerator(ctx context.Context, c client.Client) func(*evav1alpha1.R model = "gtp4" case llms.ZhiPuAI: model = "glm-4" + case llms.Gemini: + model = "gemini-pro" default: return nil, fmt.Errorf("not support type %s", llm.Spec.Type) } diff --git a/pkg/langchainwrap/embedder.go b/pkg/langchainwrap/embedder.go index abc14ac83..2645f8630 100644 --- a/pkg/langchainwrap/embedder.go +++ b/pkg/langchainwrap/embedder.go @@ -22,6 +22,7 @@ import ( "fmt" langchaingoembeddings "github.com/tmc/langchaingo/embeddings" + "github.com/tmc/langchaingo/llms/googleai" "github.com/tmc/langchaingo/llms/openai" "k8s.io/apimachinery/pkg/types" "sigs.k8s.io/controller-runtime/pkg/client" @@ -68,6 +69,25 @@ func GetLangchainEmbedder(ctx context.Context, e *v1alpha1.Embedder, c client.Cl return nil, err } return langchaingoembeddings.NewEmbedder(llm, opts...) + case embeddings.Gemini: + apiKey, err := e.AuthAPIKey(ctx, c) + if err != nil { + return nil, err + } + + if model == "" { + models := e.GetModelList() + if len(models) == 0 { + return nil, errors.New("no valid models for this Embedder") + } + model = models[0] + } + + llm, err := googleai.New(ctx, googleai.WithAPIKey(apiKey), googleai.WithDefaultEmbeddingModel(model)) + if err != nil { + return nil, err + } + return langchaingoembeddings.NewEmbedder(llm, opts...) } case v1alpha1.ProviderTypeWorker: gateway, err := config.GetGateway(ctx, c) diff --git a/pkg/langchainwrap/llm.go b/pkg/langchainwrap/llm.go index 4418ce163..ba2300a22 100644 --- a/pkg/langchainwrap/llm.go +++ b/pkg/langchainwrap/llm.go @@ -23,6 +23,7 @@ import ( "os" langchainllms "github.com/tmc/langchaingo/llms" + "github.com/tmc/langchaingo/llms/googleai" "github.com/tmc/langchaingo/llms/openai" "k8s.io/apimachinery/pkg/types" "sigs.k8s.io/controller-runtime/pkg/client" @@ -37,7 +38,7 @@ const ( GatewayUseExternalURLEnv = "GATEWAY_USE_EXTERNAL_URL" ) -func GetLangchainLLM(ctx context.Context, llm *v1alpha1.LLM, c client.Client, model string) (langchainllms.LLM, error) { +func GetLangchainLLM(ctx context.Context, llm *v1alpha1.LLM, c client.Client, model string) (langchainllms.Model, error) { switch llm.Spec.Provider.GetType() { case v1alpha1.ProviderType3rdParty: apiKey, err := llm.AuthAPIKey(ctx, c) @@ -60,6 +61,15 @@ func GetLangchainLLM(ctx context.Context, llm *v1alpha1.LLM, c client.Client, mo model = models[0] } return openai.New(openai.WithToken(apiKey), openai.WithBaseURL(llm.Get3rdPartyLLMBaseURL()), openai.WithModel(model)) + case llms.Gemini: + if model == "" { + models := llm.GetModelList() + if len(models) == 0 { + return nil, errors.New("no valid models for this LLM") + } + model = models[0] + } + return googleai.New(ctx, googleai.WithAPIKey(apiKey), googleai.WithDefaultModel(model)) } case v1alpha1.ProviderTypeWorker: gateway, err := config.GetGateway(ctx, c) diff --git a/pkg/llms/llms.go b/pkg/llms/llms.go index 16b0231f1..4588a9f73 100644 --- a/pkg/llms/llms.go +++ b/pkg/llms/llms.go @@ -29,10 +29,14 @@ const ( OpenAI LLMType = "openai" ZhiPuAI LLMType = "zhipuai" DashScope LLMType = "dashscope" + Gemini LLMType = "gemini" Unknown LLMType = "unknown" ) -var OpenAIModels = []string{"gpt-3.5", "gpt-3.5-turbo"} +var ( + OpenAIModels = []string{"gpt-3.5", "gpt-3.5-turbo"} + GeminiModels = []string{"gemini-pro"} +) var ( ZhiPuAILite string = "chatglm_lite" diff --git a/pkg/llms/zhipuai/langchainllm.go b/pkg/llms/zhipuai/langchainllm.go index 4a98886a5..5f1cc30b9 100644 --- a/pkg/llms/zhipuai/langchainllm.go +++ b/pkg/llms/zhipuai/langchainllm.go @@ -21,14 +21,14 @@ import ( "context" "encoding/json" "errors" - "fmt" "math/rand" "reflect" - "strings" "time" "github.com/r3labs/sse/v2" + "github.com/tmc/langchaingo/callbacks" langchainllm "github.com/tmc/langchaingo/llms" + "github.com/tmc/langchaingo/llms/openai" "github.com/tmc/langchaingo/schema" "k8s.io/klog/v2" ) @@ -39,11 +39,12 @@ var ( ) var ( - _ langchainllm.LLM = (*ZhiPuAILLM)(nil) + _ langchainllm.Model = (*ZhiPuAILLM)(nil) ) type options struct { - retryTimes int + retryTimes int + callbacksHandler callbacks.Handler } type Option func(*options) @@ -54,6 +55,12 @@ func WithRetryTimes(retryTimes int) Option { } } +func WithCallback(callbacksHandler callbacks.Handler) Option { + return func(o *options) { + o.callbacksHandler = callbacksHandler + } +} + type ZhiPuAILLM struct { c *ZhiPuAI options *options @@ -78,22 +85,38 @@ func (z *ZhiPuAILLM) GetNumTokens(text string) int { } func (z *ZhiPuAILLM) Call(ctx context.Context, prompt string, options ...langchainllm.CallOption) (string, error) { - r, err := z.Generate(ctx, []string{prompt}, options...) - if err != nil { - return "", fmt.Errorf("failed to generate: %w", err) - } - if len(r) == 0 { - return "", ErrEmptyResponse - } - return r[0].Text, nil + return langchainllm.GenerateFromSinglePrompt(ctx, z, prompt, options...) } -func (z *ZhiPuAILLM) Generate(ctx context.Context, prompts []string, options ...langchainllm.CallOption) ([]*langchainllm.Generation, error) { +func (z *ZhiPuAILLM) GenerateContent(ctx context.Context, messages []langchainllm.MessageContent, options ...langchainllm.CallOption) (*langchainllm.ContentResponse, error) { + if z.options.callbacksHandler != nil { + z.options.callbacksHandler.HandleLLMGenerateContentStart(ctx, messages) + } opts := langchainllm.CallOptions{} for _, opt := range options { opt(&opts) } - generations := make([]*langchainllm.Generation, 0, len(prompts)) + chatMsgs := make([]*openai.ChatMessage, 0, len(messages)) + for _, mc := range messages { + msg := &openai.ChatMessage{MultiContent: mc.Parts} + switch mc.Role { + case schema.ChatMessageTypeAI: + msg.Role = string(Assistant) + case schema.ChatMessageTypeHuman: + msg.Role = string(User) + case schema.ChatMessageTypeGeneric: + msg.Role = string(User) + case schema.ChatMessageTypeSystem: + fallthrough + case schema.ChatMessageTypeFunction: + fallthrough + default: + klog.Infof("unsupported role: %s, just skip", mc.Role) + continue + } + + chatMsgs = append(chatMsgs, msg) + } params := DefaultModelParams() if opts.TopP > 0 && opts.TopP < 1 { params.TopP = float32(opts.TopP) @@ -104,71 +127,79 @@ func (z *ZhiPuAILLM) Generate(ctx context.Context, prompts []string, options ... if opts.Model != "" { params.Model = opts.Model } - if len(prompts) == 0 { + if len(messages) == 0 { return nil, ErrEmptyPrompt } - for _, prompt := range prompts { - params.Prompt = append(params.Prompt, Prompt{Role: User, Content: prompt}) - needStream := opts.StreamingFunc != nil - if needStream { - res := bytes.NewBuffer(nil) - err := z.c.SSEInvoke(params, func(event *sse.Event) { - if string(event.Event) == "finish" { - return + for _, prompt := range chatMsgs { + content := prompt.Content + if content == "" { + for i := range prompt.MultiContent { + c, ok := prompt.MultiContent[i].(langchainllm.TextContent) + if ok { + content = c.Text } - _, _ = res.Write(event.Data) - _ = opts.StreamingFunc(ctx, event.Data) - }) - if err != nil { - return nil, err } - return []*langchainllm.Generation{ - { - Text: res.String(), - }, - }, nil } - var resp *Response - var err error - i := 0 - for { - i++ - resp, err = z.c.Invoke(params) - if err != nil { - return nil, err - } - if resp == nil { - return nil, ErrEmptyResponse - } - if resp.Data == nil { - klog.Errorf("empty response: msg:%s code:%d\n", resp.Msg, resp.Code) - if i <= z.options.retryTimes { - r := rand.Intn(5) - klog.Infof("retry[%d], sleep %d seconds, then recall...\n", i, r) - time.Sleep(time.Duration(r) * time.Second) - continue - } - return nil, ErrEmptyResponse - } - if len(resp.Data.Choices) == 0 { - return nil, ErrEmptyResponse + params.Prompt = append(params.Prompt, Prompt{Role: User, Content: content}) + } + needStream := opts.StreamingFunc != nil + if needStream { + res := bytes.NewBuffer(nil) + err := z.c.SSEInvoke(params, func(event *sse.Event) { + if string(event.Event) == "finish" { + return } - break + _, _ = res.Write(event.Data) + _ = opts.StreamingFunc(ctx, event.Data) + }) + if err != nil { + return nil, err } - generationInfo := make(map[string]any, reflect.ValueOf(resp.Data.Usage).NumField()) - generationInfo["TotalTokens"] = resp.Data.Usage.TotalTokens - var s string - if err := json.Unmarshal([]byte(resp.Data.Choices[0].Content), &s); err != nil { + return &langchainllm.ContentResponse{Choices: []*langchainllm.ContentChoice{{Content: res.String()}}}, nil + } + var resp *Response + var err error + i := 0 + for { + i++ + resp, err = z.c.Invoke(params) + if err != nil { return nil, err } - msg := &schema.AIChatMessage{ - Content: strings.TrimSpace(s), + if resp == nil { + return nil, ErrEmptyResponse } - generations = append(generations, &langchainllm.Generation{ - Message: msg, - Text: msg.Content, - GenerationInfo: generationInfo, - }) + if resp.Data == nil { + klog.Errorf("empty response: msg:%s code:%d\n", resp.Msg, resp.Code) + if i <= z.options.retryTimes { + r := rand.Intn(5) + klog.Infof("retry[%d], sleep %d seconds, then recall...\n", i, r) + time.Sleep(time.Duration(r) * time.Second) + continue + } + return nil, ErrEmptyResponse + } + if len(resp.Data.Choices) == 0 { + return nil, ErrEmptyResponse + } + break + } + generationInfo := make(map[string]any, reflect.ValueOf(resp.Data.Usage).NumField()) + generationInfo["TotalTokens"] = resp.Data.Usage.TotalTokens + choices := make([]*langchainllm.ContentChoice, 0, len(resp.Data.Choices)) + for _, c := range resp.Data.Choices { + var s string + if err := json.Unmarshal([]byte(c.Content), &s); err == nil { + choices = append(choices, &langchainllm.ContentChoice{ + Content: s, + GenerationInfo: generationInfo, + }) + } + } + + response := &langchainllm.ContentResponse{Choices: choices} + if z.options.callbacksHandler != nil { + z.options.callbacksHandler.HandleLLMGenerateContentEnd(ctx, response) } - return generations, nil + return response, nil } diff --git a/pkg/vectorstore/vectorstore.go b/pkg/vectorstore/vectorstore.go index 6fba45550..9ea609470 100644 --- a/pkg/vectorstore/vectorstore.go +++ b/pkg/vectorstore/vectorstore.go @@ -92,7 +92,12 @@ func RemoveCollection(ctx context.Context, log logr.Logger, vs *arcadiav1alpha1. log.Error(err, "reconcile delete: init pgvector error, may leave garbage data") return err } - if err = v.RemoveCollection(ctx); err != nil { + tx, err := v.Conn.Begin(ctx) + if err != nil { + log.Error(err, "reconcile delete: get tx error, may leave garbage data") + return err + } + if err = v.RemoveCollection(ctx, tx); err != nil { log.Error(err, "reconcile delete: remove vector store error, may leave garbage data") return err } diff --git a/tests/example-test.sh b/tests/example-test.sh index 35e6b8c5a..f2724e3cc 100755 --- a/tests/example-test.sh +++ b/tests/example-test.sh @@ -202,7 +202,7 @@ function getRespInAppChat() { if [ $testStream == "true" ]; then info "just test stream mode" data=$(jq -n --arg appname "$appname" --arg query "$query" --arg namespace "$namespace" --arg conversationID "$conversationID" '{"query":$query,"response_mode":"streaming","conversation_id":$conversationID,"app_name":$appname, "app_namespace":$namespace}') - curl -s -XPOST http://127.0.0.1:8081/chat --data "$data" + curl --max-time $TimeoutSeconds -s -XPOST http://127.0.0.1:8081/chat --data "$data" fi break CURRENT_TIME=$(date +%s) @@ -276,8 +276,16 @@ kubectl apply -f config/samples/arcadia_v1alpha1_versioneddataset.yaml waitCRDStatusReady "VersionedDataset" "arcadia" "dataset-playground-v1" info "7.3 create embedder and wait it ready" -kubectl apply -f config/samples/arcadia_v1alpha1_embedders.yaml -waitCRDStatusReady "Embedders" "arcadia" "zhipuai-embedders-sample" +# TODO gemini embedding not support chinese now https://github.com/kubeagi/arcadia/issues/739#issuecomment-1960679242 +#if [[ $GITHUB_ACTIONS == "true" ]]; then +# info "in github action, use gemini" +# kubectl apply -f config/samples/arcadia_v1alpha1_embedders_gemini.yaml +#else +# info "in local, use zhipu" +# kubectl apply -f config/samples/arcadia_v1alpha1_embedders_zhipu.yaml +#fi +kubectl apply -f config/samples/arcadia_v1alpha1_embedders_zhipu.yaml +waitCRDStatusReady "Embedders" "arcadia" "embedders-sample" info "7.4 create knowledgebase and wait it ready" info "7.4.1 create knowledgebase based on chroma and wait it ready" @@ -294,8 +302,8 @@ kubectl port-forward -n arcadia svc/arcadia-chromadb 8000:8000 >/dev/null 2>&1 & chroma_pid=$! info "port-forward chroma in pid: $chroma_pid" sleep 3 -collection_test_id=$(curl http://127.0.0.1:8000/api/v1/collections/arcadia_knowledgebase-sample | jq -r .id) -collection_test_count=$(curl http://127.0.0.1:8000/api/v1/collections/${collection_test_id}/count) +collection_test_id=$(curl --max-time $TimeoutSeconds http://127.0.0.1:8000/api/v1/collections/arcadia_knowledgebase-sample | jq -r .id) +collection_test_count=$(curl --max-time $TimeoutSeconds http://127.0.0.1:8000/api/v1/collections/${collection_test_id}/count) if [[ $collection_test_count =~ ^[0-9]+$ ]]; then info "collection test count: $collection_test_count" else @@ -348,7 +356,15 @@ fi info "8 validate simple app can work normally" info "Prepare dependent LLM service" -kubectl apply -f config/samples/app_shared_llm_service.yaml +if [[ $GITHUB_ACTIONS == "true" ]]; then + info "in github action, use gemini" + sed -i 's/model: chatglm_turbo/model: gemini-pro/g' config/samples/* + sed -i 's/model: glm-4/model: gemini-pro/g' config/samples/* + kubectl apply -f config/samples/app_shared_llm_service_gemini.yaml +else + info "in local, use zhipu" + kubectl apply -f config/samples/app_shared_llm_service_zhipu.yaml +fi info "8.1 app of llmchain" kubectl apply -f config/samples/app_llmchain_englishteacher.yaml @@ -400,38 +416,38 @@ fi info "8.4 check other chat rest api" info "8.4.1 conversation list" -resp=$(curl -s -XPOST http://127.0.0.1:8081/chat/conversations --data '{"app_name": "base-chat-with-bot", "app_namespace": "arcadia"}') +resp=$(curl --max-time $TimeoutSeconds -s -XPOST http://127.0.0.1:8081/chat/conversations --data '{"app_name": "base-chat-with-bot", "app_namespace": "arcadia"}') echo $resp | jq . delete_conversation_id=$(echo $resp | jq -r '.[0].id') info "8.4.2 message list" data=$(jq -n --arg conversationID "$delete_conversation_id" '{"conversation_id":$conversationID, "app_name": "base-chat-with-bot", "app_namespace": "arcadia"}') -resp=$(curl -s -XPOST http://127.0.0.1:8081/chat/messages --data "$data") +resp=$(curl --max-time $TimeoutSeconds -s -XPOST http://127.0.0.1:8081/chat/messages --data "$data") echo $resp | jq . info "8.4.3 message references" -resp=$(curl -s -XPOST http://127.0.0.1:8081/chat/conversations --data '{"app_name": "base-chat-with-knowledgebase-pgvector", "app_namespace": "arcadia"}') -message_id=$(echo $resp | jq -r '.[0].messages[0].id') -conversation_id=$(echo $resp | jq -r '.[0].id') +resp=$(curl --max-time $TimeoutSeconds -s -XPOST http://127.0.0.1:8081/chat/conversations --data '{"app_name": "base-chat-with-knowledgebase-pgvector", "app_namespace": "arcadia"}') +message_id=$(echo $resp | jq -r '.[1].messages[0].id') +conversation_id=$(echo $resp | jq -r '.[1].id') data=$(jq -n --arg conversationID "$conversation_id" '{"conversation_id":$conversationID, "app_name": "base-chat-with-knowledgebase-pgvector", "app_namespace": "arcadia"}') -resp=$(curl -s -XPOST http://127.0.0.1:8081/chat/messages/$message_id/references --data "$data") +resp=$(curl --max-time $TimeoutSeconds -s -XPOST http://127.0.0.1:8081/chat/messages/$message_id/references --data "$data") echo $resp | jq . info "8.4.4 delete conversation" -resp=$(curl -s -XDELETE http://127.0.0.1:8081/chat/conversations/$delete_conversation_id) +resp=$(curl --max-time $TimeoutSeconds -s -XDELETE http://127.0.0.1:8081/chat/conversations/$delete_conversation_id) echo $resp | jq . -resp=$(curl -s -XPOST http://127.0.0.1:8081/chat/conversations --data '{"app_name": "base-chat-with-bot", "app_namespace": "arcadia"}') +resp=$(curl --max-time $TimeoutSeconds -s -XPOST http://127.0.0.1:8081/chat/conversations --data '{"app_name": "base-chat-with-bot", "app_namespace": "arcadia"}') if [[ $resp == *"$delete_conversation_id"* ]]; then echo "delete conversation failed" exit 1 fi info "8.4.5 get app prompt starters" -resp=$(curl -s -XPOST http://127.0.0.1:8081/chat/prompt-starter --data '{"app_name": "base-chat-with-bot", "app_namespace": "arcadia"}') +resp=$(curl --max-time $TimeoutSeconds -s -XPOST http://127.0.0.1:8081/chat/prompt-starter --data '{"app_name": "base-chat-with-bot", "app_namespace": "arcadia"}') echo $resp | jq . -if [[ $resp == *"err"* ]]; then +if [[ $resp == *"error"* ]]; then echo "failed" exit 1 fi -resp=$(curl -s -XPOST http://127.0.0.1:8081/chat/prompt-starter --data '{"app_name": "base-chat-with-knowledgebase-pgvector", "app_namespace": "arcadia"}') +resp=$(curl --max-time $TimeoutSeconds -s -XPOST http://127.0.0.1:8081/chat/prompt-starter --data '{"app_name": "base-chat-with-knowledgebase-pgvector", "app_namespace": "arcadia"}') echo $resp | jq . -if [[ $resp == *"err"* ]]; then +if [[ $resp == *"error"* ]]; then echo "failed" exit 1 fi @@ -450,7 +466,7 @@ info "8.5 apichain test" kubectl apply -f config/samples/app_apichain_movie.yaml waitCRDStatusReady "Application" "arcadia" "movie-bot" sleep 3 -curl -s -XPOST http://127.0.0.1:8081/chat --data '{"query":"年会不能停的主演有谁?","response_mode":"blocking","conversation_id":"","app_name":"movie-bot", "app_namespace":"arcadia"}' +curl --max-time $TimeoutSeconds -s -XPOST http://127.0.0.1:8081/chat --data '{"query":"年会不能停的主演有谁?","response_mode":"blocking","conversation_id":"","app_name":"movie-bot", "app_namespace":"arcadia"}' #if [[ $resp != *"温度"* ]]; then # echo "Because conversationWindowSize is enabled to be 2, llm should record history, but resp:"$resp "dont contains Jim" # exit 1