From f05bff7a60a2862e571a1ef48eb839b8b28dc765 Mon Sep 17 00:00:00 2001 From: bjwswang Date: Fri, 29 Mar 2024 06:23:38 +0000 Subject: [PATCH] feat: add gpts url in gpts config and add api to return the gptsconfig Signed-off-by: bjwswang --- apiserver/graph/generated/generated.go | 271 +++++++++++++++++++- apiserver/graph/generated/models_gen.go | 8 + apiserver/graph/impl/gpt.resolvers.go | 9 + apiserver/graph/schema/gpt.gql | 9 + apiserver/graph/schema/gpt.graphqls | 9 +- apiserver/pkg/common/common.go | 5 + apiserver/pkg/gpt/gpt.go | 12 + deploy/charts/arcadia/Chart.yaml | 2 +- deploy/charts/arcadia/templates/config.yaml | 1 + gqlgen.yaml | 2 + pkg/config/gpts_config.go | 7 + 11 files changed, 332 insertions(+), 3 deletions(-) diff --git a/apiserver/graph/generated/generated.go b/apiserver/graph/generated/generated.go index 11cb5edb7..ccb9349cd 100644 --- a/apiserver/graph/generated/generated.go +++ b/apiserver/graph/generated/generated.go @@ -405,11 +405,17 @@ type ComplexityRoot struct { } GPTQuery struct { + GetGPTStore func(childComplexity int) int GetGpt func(childComplexity int, name string) int ListGPTCategory func(childComplexity int) int ListGpt func(childComplexity int, input ListGPTInput) int } + GPTStore struct { + PublicNamespace func(childComplexity int) int + URL func(childComplexity int) int + } + KnowledgeBase struct { Annotations func(childComplexity int) int BatchSize func(childComplexity int) int @@ -885,6 +891,7 @@ type GPTQueryResolver interface { GetGpt(ctx context.Context, obj *GPTQuery, name string) (*Gpt, error) ListGpt(ctx context.Context, obj *GPTQuery, input ListGPTInput) (*PaginatedResult, error) ListGPTCategory(ctx context.Context, obj *GPTQuery) ([]*GPTCategory, error) + GetGPTStore(ctx context.Context, obj *GPTQuery) (*GPTStore, error) } type KnowledgeBaseMutationResolver interface { CreateKnowledgeBase(ctx context.Context, obj *KnowledgeBaseMutation, input CreateKnowledgeBaseInput) (*KnowledgeBase, error) @@ -2737,6 +2744,13 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.GPTCategory.NameEn(childComplexity), true + case "GPTQuery.getGPTStore": + if e.complexity.GPTQuery.GetGPTStore == nil { + break + } + + return e.complexity.GPTQuery.GetGPTStore(childComplexity), true + case "GPTQuery.getGPT": if e.complexity.GPTQuery.GetGpt == nil { break @@ -2768,6 +2782,20 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.GPTQuery.ListGpt(childComplexity, args["input"].(ListGPTInput)), true + case "GPTStore.public_namespace": + if e.complexity.GPTStore.PublicNamespace == nil { + break + } + + return e.complexity.GPTStore.PublicNamespace(childComplexity), true + + case "GPTStore.url": + if e.complexity.GPTStore.URL == nil { + break + } + + return e.complexity.GPTStore.URL(childComplexity), true + case "KnowledgeBase.annotations": if e.complexity.KnowledgeBase.Annotations == nil { break @@ -6576,17 +6604,24 @@ type GPT { notReadyReasonCode: String } -# GPTCategory in gpt store +"""GPTCategory in gpt store""" type GPTCategory { id: String! name: String! nameEn: String! } +type GPTStore { + url: String! + public_namespace: String! +} + type GPTQuery { getGPT(name: String!): GPT! listGPT(input: ListGPTInput!): PaginatedResult! listGPTCategory: [GPTCategory]! + """get the gpt store info""" + getGPTStore: GPTStore! } extend type Query{ @@ -20381,6 +20416,144 @@ func (ec *executionContext) fieldContext_GPTQuery_listGPTCategory(ctx context.Co return fc, nil } +func (ec *executionContext) _GPTQuery_getGPTStore(ctx context.Context, field graphql.CollectedField, obj *GPTQuery) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_GPTQuery_getGPTStore(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.GPTQuery().GetGPTStore(rctx, obj) + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(*GPTStore) + fc.Result = res + return ec.marshalNGPTStore2ᚖgithubᚗcomᚋkubeagiᚋarcadiaᚋapiserverᚋgraphᚋgeneratedᚐGPTStore(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_GPTQuery_getGPTStore(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "GPTQuery", + Field: field, + IsMethod: true, + IsResolver: true, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "url": + return ec.fieldContext_GPTStore_url(ctx, field) + case "public_namespace": + return ec.fieldContext_GPTStore_public_namespace(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type GPTStore", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) _GPTStore_url(ctx context.Context, field graphql.CollectedField, obj *GPTStore) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_GPTStore_url(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.URL, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_GPTStore_url(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "GPTStore", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _GPTStore_public_namespace(ctx context.Context, field graphql.CollectedField, obj *GPTStore) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_GPTStore_public_namespace(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.PublicNamespace, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_GPTStore_public_namespace(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "GPTStore", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + func (ec *executionContext) _KnowledgeBase_id(ctx context.Context, field graphql.CollectedField, obj *KnowledgeBase) (ret graphql.Marshaler) { fc, err := ec.fieldContext_KnowledgeBase_id(ctx, field) if err != nil { @@ -27535,6 +27708,8 @@ func (ec *executionContext) fieldContext_Query_GPT(ctx context.Context, field gr return ec.fieldContext_GPTQuery_listGPT(ctx, field) case "listGPTCategory": return ec.fieldContext_GPTQuery_listGPTCategory(ctx, field) + case "getGPTStore": + return ec.fieldContext_GPTQuery_getGPTStore(ctx, field) } return nil, fmt.Errorf("no field named %q was found under type GPTQuery", field.Name) }, @@ -43197,6 +43372,86 @@ func (ec *executionContext) _GPTQuery(ctx context.Context, sel ast.SelectionSet, } out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) + case "getGPTStore": + field := field + + innerFunc := func(ctx context.Context, fs *graphql.FieldSet) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._GPTQuery_getGPTStore(ctx, field, obj) + if res == graphql.Null { + atomic.AddUint32(&fs.Invalids, 1) + } + return res + } + + if field.Deferrable != nil { + dfs, ok := deferred[field.Deferrable.Label] + di := 0 + if ok { + dfs.AddField(field) + di = len(dfs.Values) - 1 + } else { + dfs = graphql.NewFieldSet([]graphql.CollectedField{field}) + deferred[field.Deferrable.Label] = dfs + } + dfs.Concurrently(di, func(ctx context.Context) graphql.Marshaler { + return innerFunc(ctx, dfs) + }) + + // don't run the out.Concurrently() call below + out.Values[i] = graphql.Null + continue + } + + out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch(ctx) + if out.Invalids > 0 { + return graphql.Null + } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + + return out +} + +var gPTStoreImplementors = []string{"GPTStore"} + +func (ec *executionContext) _GPTStore(ctx context.Context, sel ast.SelectionSet, obj *GPTStore) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, gPTStoreImplementors) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("GPTStore") + case "url": + out.Values[i] = ec._GPTStore_url(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "public_namespace": + out.Values[i] = ec._GPTStore_public_namespace(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } default: panic("unknown field " + strconv.Quote(field.Name)) } @@ -47898,6 +48153,20 @@ func (ec *executionContext) marshalNGPTCategory2ᚕᚖgithubᚗcomᚋkubeagiᚋa return ret } +func (ec *executionContext) marshalNGPTStore2githubᚗcomᚋkubeagiᚋarcadiaᚋapiserverᚋgraphᚋgeneratedᚐGPTStore(ctx context.Context, sel ast.SelectionSet, v GPTStore) graphql.Marshaler { + return ec._GPTStore(ctx, sel, &v) +} + +func (ec *executionContext) marshalNGPTStore2ᚖgithubᚗcomᚋkubeagiᚋarcadiaᚋapiserverᚋgraphᚋgeneratedᚐGPTStore(ctx context.Context, sel ast.SelectionSet, v *GPTStore) graphql.Marshaler { + if v == nil { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + return graphql.Null + } + return ec._GPTStore(ctx, sel, v) +} + func (ec *executionContext) unmarshalNInt2int(ctx context.Context, v interface{}) (int, error) { res, err := graphql.UnmarshalInt(v) return res, graphql.ErrorOnPath(ctx, err) diff --git a/apiserver/graph/generated/models_gen.go b/apiserver/graph/generated/models_gen.go index 55003c61e..8cfd25a78 100644 --- a/apiserver/graph/generated/models_gen.go +++ b/apiserver/graph/generated/models_gen.go @@ -898,6 +898,7 @@ type Gpt struct { func (Gpt) IsPageNode() {} +// GPTCategory in gpt store type GPTCategory struct { ID string `json:"id"` Name string `json:"name"` @@ -908,6 +909,13 @@ type GPTQuery struct { GetGpt Gpt `json:"getGPT"` ListGpt PaginatedResult `json:"listGPT"` ListGPTCategory []*GPTCategory `json:"listGPTCategory"` + // get the gpt store info + GetGPTStore GPTStore `json:"getGPTStore"` +} + +type GPTStore struct { + URL string `json:"url"` + PublicNamespace string `json:"public_namespace"` } // 知识库 diff --git a/apiserver/graph/impl/gpt.resolvers.go b/apiserver/graph/impl/gpt.resolvers.go index 9b256e8b4..5f9c33513 100644 --- a/apiserver/graph/impl/gpt.resolvers.go +++ b/apiserver/graph/impl/gpt.resolvers.go @@ -38,6 +38,15 @@ func (r *gPTQueryResolver) ListGPTCategory(ctx context.Context, obj *generated.G return gpt.ListGPTCategory(ctx, c) } +// GetGPTStore is the resolver for the getGPTStore field. +func (r *gPTQueryResolver) GetGPTStore(ctx context.Context, obj *generated.GPTQuery) (*generated.GPTStore, error) { + c, err := getAdminClient() + if err != nil { + return nil, err + } + return gpt.GetGPTStore(ctx, c) +} + // Gpt is the resolver for the GPT field. func (r *queryResolver) Gpt(ctx context.Context) (*generated.GPTQuery, error) { return &generated.GPTQuery{}, nil diff --git a/apiserver/graph/schema/gpt.gql b/apiserver/graph/schema/gpt.gql index 7e1762b38..ccbdcfd85 100644 --- a/apiserver/graph/schema/gpt.gql +++ b/apiserver/graph/schema/gpt.gql @@ -56,4 +56,13 @@ query listGPTCategory { nameEn } } +} + +query getGPTStore { + GPT { + getGPTStore { + url + public_namespace + } + } } \ No newline at end of file diff --git a/apiserver/graph/schema/gpt.graphqls b/apiserver/graph/schema/gpt.graphqls index 121dae474..9e14d1847 100644 --- a/apiserver/graph/schema/gpt.graphqls +++ b/apiserver/graph/schema/gpt.graphqls @@ -107,17 +107,24 @@ type GPT { notReadyReasonCode: String } -# GPTCategory in gpt store +"""GPTCategory in gpt store""" type GPTCategory { id: String! name: String! nameEn: String! } +type GPTStore { + url: String! + public_namespace: String! +} + type GPTQuery { getGPT(name: String!): GPT! listGPT(input: ListGPTInput!): PaginatedResult! listGPTCategory: [GPTCategory]! + """get the gpt store info""" + getGPTStore: GPTStore! } extend type Query{ diff --git a/apiserver/pkg/common/common.go b/apiserver/pkg/common/common.go index eee760c36..af73c12c6 100644 --- a/apiserver/pkg/common/common.go +++ b/apiserver/pkg/common/common.go @@ -109,6 +109,11 @@ func GetAPIServer(ctx context.Context, cli client.Client, external bool) (string return api, nil } +// GetGPTsURL returns the gpts url to access arcadia's gpt store +func GetGPTStoreConfig(ctx context.Context, cli client.Client) (*config.GPTsConfig, error) { + return config.GetGPTsConfig(ctx, cli) +} + // GetObjStatus is used to calculate the state of the resource, unified management, // in general, a resource will only record its own state, // then the state calculation of this resource, should be written to this function. diff --git a/apiserver/pkg/gpt/gpt.go b/apiserver/pkg/gpt/gpt.go index 7c188fdae..a556cb52a 100644 --- a/apiserver/pkg/gpt/gpt.go +++ b/apiserver/pkg/gpt/gpt.go @@ -194,3 +194,15 @@ func ListGPTCategory(ctx context.Context, c client.Client) ([]*generated.GPTCate } return resp, nil } + +// GetGPTStore get gpt store info +func GetGPTStore(ctx context.Context, cli client.Client) (*generated.GPTStore, error) { + cfg, err := common.GetGPTStoreConfig(ctx, cli) + if err != nil { + return nil, err + } + return &generated.GPTStore{ + URL: cfg.URL, + PublicNamespace: cfg.PublicNamespace, + }, nil +} diff --git a/deploy/charts/arcadia/Chart.yaml b/deploy/charts/arcadia/Chart.yaml index 85452c221..f1a579969 100644 --- a/deploy/charts/arcadia/Chart.yaml +++ b/deploy/charts/arcadia/Chart.yaml @@ -2,7 +2,7 @@ apiVersion: v2 name: arcadia description: A Helm chart(Also a KubeBB Component) for KubeAGI Arcadia type: application -version: 0.3.26 +version: 0.3.27 appVersion: "0.2.1" keywords: diff --git a/deploy/charts/arcadia/templates/config.yaml b/deploy/charts/arcadia/templates/config.yaml index ea1bafe87..2168f9b8f 100644 --- a/deploy/charts/arcadia/templates/config.yaml +++ b/deploy/charts/arcadia/templates/config.yaml @@ -71,6 +71,7 @@ data: database: {{ .Values.postgresql.global.postgresql.auth.database }} # configurations for gpts gptsConfig: | + url: https://{{ .Values.gpts.agentportal.ingress.host }}/{{ .Values.gpts.agentportal.ingress.path }} public_namespace: {{ .Values.gpts.public_namespace }} categories: - id: 1 diff --git a/gqlgen.yaml b/gqlgen.yaml index bc33b9f88..2a0942e63 100644 --- a/gqlgen.yaml +++ b/gqlgen.yaml @@ -300,6 +300,8 @@ models: resolver: true listGPTCategory: resolver: true + getGPTStore: + resolver: true NodeQuery: fields: listNodes: diff --git a/pkg/config/gpts_config.go b/pkg/config/gpts_config.go index edf01f01f..75b31de1d 100644 --- a/pkg/config/gpts_config.go +++ b/pkg/config/gpts_config.go @@ -19,6 +19,7 @@ package config import ( "context" "fmt" + "strings" corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/util/yaml" @@ -35,6 +36,8 @@ var ( // GPTsConfig is the configurations for GPT Store type GPTsConfig struct { + // URL is the url of gpt store + URL string `json:"url,omitempty"` // PublicNamespace is the namespace which all gpt-releated resources are public PublicNamespace string `json:"public_namespace,omitempty"` Categories []Category `json:"categories,omitempty"` @@ -65,6 +68,10 @@ func GetGPTsConfig(ctx context.Context, c client.Client) (gptsConfig *GPTsConfig if err = yaml.Unmarshal([]byte(value), &gptsConfig); err != nil { return nil, err } + + // trim suffix / + gptsConfig.URL = strings.TrimSuffix(gptsConfig.URL, "/") + return gptsConfig, nil }