From ba85408cf8dc1b62f86712f9c076d29dc7321cac Mon Sep 17 00:00:00 2001 From: bjwswang Date: Fri, 19 Jan 2024 08:13:53 +0000 Subject: [PATCH 1/2] fix: avoid to update resource status with explictly status check Signed-off-by: bjwswang --- api/base/v1alpha1/datasource.go | 42 ++++++++++++++++ api/base/v1alpha1/embedder.go | 39 +++++++++++++++ api/base/v1alpha1/llm.go | 39 +++++++++++++++ api/base/v1alpha1/model.go | 40 ++++++++++++++++ controllers/base/datasource_controller.go | 19 +------- controllers/base/embedder_controller.go | 33 ++----------- controllers/base/llm_controller.go | 58 ++++++----------------- controllers/base/model_controller.go | 20 +------- pkg/llms/llms.go | 2 +- 9 files changed, 183 insertions(+), 109 deletions(-) diff --git a/api/base/v1alpha1/datasource.go b/api/base/v1alpha1/datasource.go index 73452c54e..344301fbf 100644 --- a/api/base/v1alpha1/datasource.go +++ b/api/base/v1alpha1/datasource.go @@ -16,6 +16,11 @@ limitations under the License. package v1alpha1 +import ( + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + const ( LabelDatasourceType = Group + "/datasource-type" ) @@ -41,3 +46,40 @@ func (ds DatasourceSpec) Type() DatasourceType { return DatasourceTypeUnknown } } + +func (datasource Datasource) ReadyCondition() Condition { + currCon := datasource.Status.GetCondition(TypeReady) + // return current condition if condition not changed + if currCon.Status == corev1.ConditionTrue && currCon.Reason == ReasonAvailable { + return currCon + } + return Condition{ + Type: TypeReady, + Status: corev1.ConditionTrue, + Reason: ReasonAvailable, + Message: "Check Success", + LastTransitionTime: metav1.Now(), + LastSuccessfulTime: metav1.Now(), + } +} + +func (datasource Datasource) ErrorCondition(msg string) Condition { + currCon := datasource.Status.GetCondition(TypeReady) + // return current condition if condition not changed + if currCon.Status == corev1.ConditionFalse && currCon.Reason == ReasonUnavailable && currCon.Message == msg { + return currCon + } + // keep original LastSuccessfulTime if have + lastSuccessfulTime := metav1.Now() + if currCon.LastSuccessfulTime.IsZero() { + lastSuccessfulTime = currCon.LastSuccessfulTime + } + return Condition{ + Type: TypeReady, + Status: corev1.ConditionFalse, + Reason: ReasonUnavailable, + Message: msg, + LastSuccessfulTime: lastSuccessfulTime, + LastTransitionTime: metav1.Now(), + } +} diff --git a/api/base/v1alpha1/embedder.go b/api/base/v1alpha1/embedder.go index 88f502147..baf321c0a 100644 --- a/api/base/v1alpha1/embedder.go +++ b/api/base/v1alpha1/embedder.go @@ -19,6 +19,8 @@ package v1alpha1 import ( "context" + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/client-go/dynamic" "sigs.k8s.io/controller-runtime/pkg/client" @@ -75,3 +77,40 @@ func (e Embedder) Get3rdPartyModels() []string { return []string{} } + +func (e Embedder) ReadyCondition(msg string) Condition { + currCon := e.Status.GetCondition(TypeReady) + // return current condition if condition not changed + if currCon.Status == corev1.ConditionTrue && currCon.Reason == ReasonAvailable && currCon.Message == msg { + return currCon + } + return Condition{ + Type: TypeReady, + Status: corev1.ConditionTrue, + Reason: ReasonAvailable, + Message: msg, + LastTransitionTime: metav1.Now(), + LastSuccessfulTime: metav1.Now(), + } +} + +func (e Embedder) ErrorCondition(msg string) Condition { + currCon := e.Status.GetCondition(TypeReady) + // return current condition if condition not changed + if currCon.Status == corev1.ConditionFalse && currCon.Reason == ReasonUnavailable && currCon.Message == msg { + return currCon + } + // keep original LastSuccessfulTime if have + lastSuccessfulTime := metav1.Now() + if currCon.LastSuccessfulTime.IsZero() { + lastSuccessfulTime = currCon.LastSuccessfulTime + } + return Condition{ + Type: TypeReady, + Status: corev1.ConditionFalse, + Reason: ReasonUnavailable, + Message: msg, + LastSuccessfulTime: lastSuccessfulTime, + LastTransitionTime: metav1.Now(), + } +} diff --git a/api/base/v1alpha1/llm.go b/api/base/v1alpha1/llm.go index c86962c88..82ed1a61e 100644 --- a/api/base/v1alpha1/llm.go +++ b/api/base/v1alpha1/llm.go @@ -19,6 +19,8 @@ package v1alpha1 import ( "context" + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/client-go/dynamic" "sigs.k8s.io/controller-runtime/pkg/client" @@ -84,3 +86,40 @@ func (llm LLM) Get3rdPartyModels() []string { } return []string{} } + +func (llm LLM) ReadyCondition(msg string) Condition { + currCon := llm.Status.GetCondition(TypeReady) + // return current condition if condition not changed + if currCon.Status == corev1.ConditionTrue && currCon.Reason == ReasonAvailable && currCon.Message == msg { + return currCon + } + return Condition{ + Type: TypeReady, + Status: corev1.ConditionTrue, + Reason: ReasonAvailable, + Message: msg, + LastTransitionTime: metav1.Now(), + LastSuccessfulTime: metav1.Now(), + } +} + +func (llm LLM) ErrorCondition(msg string) Condition { + currCon := llm.Status.GetCondition(TypeReady) + // return current condition if condition not changed + if currCon.Status == corev1.ConditionFalse && currCon.Reason == ReasonUnavailable && currCon.Message == msg { + return currCon + } + // keep original LastSuccessfulTime if have + lastSuccessfulTime := metav1.Now() + if currCon.LastSuccessfulTime.IsZero() { + lastSuccessfulTime = currCon.LastSuccessfulTime + } + return Condition{ + Type: TypeReady, + Status: corev1.ConditionFalse, + Reason: ReasonUnavailable, + Message: msg, + LastSuccessfulTime: lastSuccessfulTime, + LastTransitionTime: metav1.Now(), + } +} diff --git a/api/base/v1alpha1/model.go b/api/base/v1alpha1/model.go index 4d454bbd1..2650d2996 100644 --- a/api/base/v1alpha1/model.go +++ b/api/base/v1alpha1/model.go @@ -19,6 +19,9 @@ package v1alpha1 import ( "fmt" "strings" + + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) const ( @@ -58,3 +61,40 @@ func (model Model) FullPath() string { func (model Model) ObjectPath() string { return fmt.Sprintf("model/%s/", model.Name) } + +func (model Model) ReadyCondition() Condition { + currCon := model.Status.GetCondition(TypeReady) + // return current condition if condition not changed + if currCon.Status == corev1.ConditionTrue && currCon.Reason == ReasonAvailable { + return currCon + } + return Condition{ + Type: TypeReady, + Status: corev1.ConditionTrue, + Reason: ReasonAvailable, + Message: "Check Success", + LastTransitionTime: metav1.Now(), + LastSuccessfulTime: metav1.Now(), + } +} + +func (model Model) ErrorCondition(msg string) Condition { + currCon := model.Status.GetCondition(TypeReady) + // return current condition if condition not changed + if currCon.Status == corev1.ConditionFalse && currCon.Reason == ReasonUnavailable && currCon.Message == msg { + return currCon + } + // keep original LastSuccessfulTime if have + lastSuccessfulTime := metav1.Now() + if currCon.LastSuccessfulTime.IsZero() { + lastSuccessfulTime = currCon.LastSuccessfulTime + } + return Condition{ + Type: TypeReady, + Status: corev1.ConditionFalse, + Reason: ReasonUnavailable, + Message: msg, + LastSuccessfulTime: lastSuccessfulTime, + LastTransitionTime: metav1.Now(), + } +} diff --git a/controllers/base/datasource_controller.go b/controllers/base/datasource_controller.go index 39a4a58b3..59d8dabdb 100644 --- a/controllers/base/datasource_controller.go +++ b/controllers/base/datasource_controller.go @@ -22,8 +22,6 @@ import ( "reflect" "github.com/go-logr/logr" - corev1 "k8s.io/api/core/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/builder" @@ -198,23 +196,10 @@ func (r *DatasourceReconciler) UpdateStatus(ctx context.Context, instance *arcad var newCondition arcadiav1alpha1.Condition if err != nil { // set condition to False - newCondition = arcadiav1alpha1.Condition{ - Type: arcadiav1alpha1.TypeReady, - Status: corev1.ConditionFalse, - Reason: arcadiav1alpha1.ReasonUnavailable, - Message: err.Error(), - LastTransitionTime: metav1.Now(), - } + newCondition = instance.ErrorCondition(err.Error()) } else { // set condition to True - newCondition = arcadiav1alpha1.Condition{ - Type: arcadiav1alpha1.TypeReady, - Status: corev1.ConditionTrue, - Reason: arcadiav1alpha1.ReasonAvailable, - Message: "Check Success", - LastTransitionTime: metav1.Now(), - LastSuccessfulTime: metav1.Now(), - } + newCondition = instance.ReadyCondition() } instanceCopy.Status.SetConditions(newCondition) return r.Client.Status().Update(ctx, instanceCopy) diff --git a/controllers/base/embedder_controller.go b/controllers/base/embedder_controller.go index 26c5355c8..773a6bcf4 100644 --- a/controllers/base/embedder_controller.go +++ b/controllers/base/embedder_controller.go @@ -25,8 +25,6 @@ import ( "github.com/go-logr/logr" langchainembeddings "github.com/tmc/langchaingo/embeddings" langchainopenai "github.com/tmc/langchaingo/llms/openai" - corev1 "k8s.io/api/core/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/types" ctrl "sigs.k8s.io/controller-runtime" @@ -127,16 +125,6 @@ func (r *EmbedderReconciler) SetupWithManager(mgr ctrl.Manager) error { newEmbedder := ue.ObjectNew.(*arcadiav1alpha1.Embedder) return !reflect.DeepEqual(oldEmbedder.Spec, newEmbedder.Spec) || newEmbedder.DeletionTimestamp != nil }, - // for other event handler, we must add the function explicitly. - CreateFunc: func(event.CreateEvent) bool { - return true - }, - DeleteFunc: func(event.DeleteEvent) bool { - return true - }, - GenericFunc: func(event.GenericEvent) bool { - return true - }, })). Watches(&source.Kind{Type: &arcadiav1alpha1.Worker{}}, handler.EnqueueRequestsFromMapFunc(func(o client.Object) []reconcile.Request { @@ -257,28 +245,15 @@ func (r *EmbedderReconciler) UpdateStatus(ctx context.Context, instance *arcadia instanceCopy := instance.DeepCopy() var newCondition arcadiav1alpha1.Condition if err != nil { - // Set status to unavailable - newCondition = arcadiav1alpha1.Condition{ - Type: arcadiav1alpha1.TypeReady, - Status: corev1.ConditionFalse, - Reason: arcadiav1alpha1.ReasonUnavailable, - Message: err.Error(), - LastTransitionTime: metav1.Now(), - } + // set condition to False + newCondition = instance.ErrorCondition(err.Error()) } else { msg, ok := t.(string) if !ok { msg = _StatusNilResponse } - // Set status to available - newCondition = arcadiav1alpha1.Condition{ - Type: arcadiav1alpha1.TypeReady, - Status: corev1.ConditionTrue, - Reason: arcadiav1alpha1.ReasonAvailable, - Message: msg, - LastTransitionTime: metav1.Now(), - LastSuccessfulTime: metav1.Now(), - } + // set condition to True + newCondition = instance.ReadyCondition(msg) } instanceCopy.Status.SetConditions(newCondition) return r.Client.Status().Update(ctx, instanceCopy) diff --git a/controllers/base/llm_controller.go b/controllers/base/llm_controller.go index 34452ac0c..abe135047 100644 --- a/controllers/base/llm_controller.go +++ b/controllers/base/llm_controller.go @@ -25,8 +25,6 @@ import ( "github.com/go-logr/logr" langchainllms "github.com/tmc/langchaingo/llms" - corev1 "k8s.io/api/core/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/types" ctrl "sigs.k8s.io/controller-runtime" @@ -122,7 +120,14 @@ func (r *LLMReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.R // SetupWithManager sets up the controller with the Manager. func (r *LLMReconciler) SetupWithManager(mgr ctrl.Manager) error { return ctrl.NewControllerManagedBy(mgr). - For(&arcadiav1alpha1.LLM{}, builder.WithPredicates(LLMPredicates{})). + For(&arcadiav1alpha1.LLM{}, builder.WithPredicates(predicate.Funcs{ + UpdateFunc: func(ue event.UpdateEvent) bool { + // Avoid to handle the event that it's not spec update or delete + oldLLM := ue.ObjectOld.(*arcadiav1alpha1.LLM) + newLLM := ue.ObjectNew.(*arcadiav1alpha1.LLM) + return !reflect.DeepEqual(oldLLM.Spec, newLLM.Spec) || oldLLM.DeletionTimestamp != nil + }, + })). Watches(&source.Kind{Type: &arcadiav1alpha1.Worker{}}, handler.EnqueueRequestsFromMapFunc(func(o client.Object) []reconcile.Request { worker := o.(*arcadiav1alpha1.Worker) @@ -228,53 +233,18 @@ func (r *LLMReconciler) checkWorkerLLM(ctx context.Context, logger logr.Logger, func (r *LLMReconciler) UpdateStatus(ctx context.Context, instance *arcadiav1alpha1.LLM, t interface{}, err error) error { instanceCopy := instance.DeepCopy() + var newCondition arcadiav1alpha1.Condition if err != nil { - // Set status to unavailable - instanceCopy.Status.SetConditions(arcadiav1alpha1.Condition{ - Type: arcadiav1alpha1.TypeReady, - Status: corev1.ConditionFalse, - Reason: arcadiav1alpha1.ReasonUnavailable, - Message: err.Error(), - LastTransitionTime: metav1.Now(), - }) + // set condition to False + newCondition = instance.ErrorCondition(err.Error()) } else { msg, ok := t.(string) if !ok { msg = _StatusNilResponse } - // Set status to available - instanceCopy.Status.SetConditions(arcadiav1alpha1.Condition{ - Type: arcadiav1alpha1.TypeReady, - Status: corev1.ConditionTrue, - Reason: arcadiav1alpha1.ReasonAvailable, - Message: msg, - LastTransitionTime: metav1.Now(), - LastSuccessfulTime: metav1.Now(), - }) + // set condition to True + newCondition = instance.ReadyCondition(msg) } + instanceCopy.Status.SetConditions(newCondition) return r.Client.Status().Update(ctx, instanceCopy) } - -type LLMPredicates struct { - predicate.Funcs -} - -func (llm LLMPredicates) Create(ce event.CreateEvent) bool { - prompt := ce.Object.(*arcadiav1alpha1.LLM) - return len(prompt.Status.ConditionedStatus.Conditions) == 0 -} - -func (llm LLMPredicates) Update(ue event.UpdateEvent) bool { - oldLLM := ue.ObjectOld.(*arcadiav1alpha1.LLM) - newLLM := ue.ObjectNew.(*arcadiav1alpha1.LLM) - - return !reflect.DeepEqual(oldLLM.Spec, newLLM.Spec) || newLLM.DeletionTimestamp != nil -} - -func (llm LLMPredicates) Delete(de event.DeleteEvent) bool { - return true -} - -func (llm LLMPredicates) Generic(ge event.GenericEvent) bool { - return true -} diff --git a/controllers/base/model_controller.go b/controllers/base/model_controller.go index 5a4af1806..28ddbd482 100644 --- a/controllers/base/model_controller.go +++ b/controllers/base/model_controller.go @@ -23,8 +23,6 @@ import ( "strconv" "github.com/go-logr/logr" - corev1 "k8s.io/api/core/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/builder" @@ -250,23 +248,9 @@ func (r *ModelReconciler) UpdateStatus(ctx context.Context, instance *arcadiav1a var newCondition arcadiav1alpha1.Condition if err != nil { // set condition to False - newCondition = arcadiav1alpha1.Condition{ - Type: arcadiav1alpha1.TypeReady, - Status: corev1.ConditionFalse, - Reason: arcadiav1alpha1.ReasonUnavailable, - Message: err.Error(), - LastTransitionTime: metav1.Now(), - } + newCondition = instance.ErrorCondition(err.Error()) } else { - // set condition to True - newCondition = arcadiav1alpha1.Condition{ - Type: arcadiav1alpha1.TypeReady, - Status: corev1.ConditionTrue, - Reason: arcadiav1alpha1.ReasonAvailable, - Message: "Check Success", - LastTransitionTime: metav1.Now(), - LastSuccessfulTime: metav1.Now(), - } + newCondition = instance.ReadyCondition() } instanceCopy.Status.SetConditions(newCondition) return r.Client.Status().Update(ctx, instanceCopy) diff --git a/pkg/llms/llms.go b/pkg/llms/llms.go index 6717e6564..16b0231f1 100644 --- a/pkg/llms/llms.go +++ b/pkg/llms/llms.go @@ -46,7 +46,7 @@ var ( // Character LLM ZhiPuAICharGLM3 string = "charglm-3" ) -var ZhiPuAIModels = []string{ZhiPuAILite, ZhiPuAIStd, ZhiPuAIPro, ZhiPuAITurbo} +var ZhiPuAIModels = []string{ZhiPuAILite, ZhiPuAIStd, ZhiPuAIPro, ZhiPuAITurbo, ZhiPuAIGLM3Turbo, ZhiPuAIGLM4} type LLM interface { Type() LLMType From e07201e08c30a884291640c7255b370842fc51f2 Mon Sep 17 00:00:00 2001 From: bjwswang Date: Fri, 19 Jan 2024 08:49:12 +0000 Subject: [PATCH 2/2] fix: add displayName in graphql TypedObjectReference Signed-off-by: bjwswang --- apiserver/graph/generated/generated.go | 74 ++++++++++++++++++-- apiserver/graph/generated/models_gen.go | 9 +-- apiserver/graph/schema/entrypoint.graphqls | 1 + apiserver/pkg/common/common.go | 9 +++ apiserver/pkg/knowledgebase/knowledgebase.go | 50 +++++++++---- 5 files changed, 121 insertions(+), 22 deletions(-) diff --git a/apiserver/graph/generated/generated.go b/apiserver/graph/generated/generated.go index c67d9fdf0..177dc95cc 100644 --- a/apiserver/graph/generated/generated.go +++ b/apiserver/graph/generated/generated.go @@ -538,10 +538,11 @@ type ComplexityRoot struct { } TypedObjectReference struct { - APIGroup func(childComplexity int) int - Kind func(childComplexity int) int - Name func(childComplexity int) int - Namespace func(childComplexity int) int + APIGroup func(childComplexity int) int + DisplayName func(childComplexity int) int + Kind func(childComplexity int) int + Name func(childComplexity int) int + Namespace func(childComplexity int) int } VersionedDataset struct { @@ -3260,6 +3261,13 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.TypedObjectReference.APIGroup(childComplexity), true + case "TypedObjectReference.displayName": + if e.complexity.TypedObjectReference.DisplayName == nil { + break + } + + return e.complexity.TypedObjectReference.DisplayName(childComplexity), true + case "TypedObjectReference.kind": if e.complexity.TypedObjectReference.Kind == nil { break @@ -5040,6 +5048,7 @@ type TypedObjectReference { apiGroup: String kind: String! name: String! + displayName: String namespace: String } @@ -15648,6 +15657,8 @@ func (ec *executionContext) fieldContext_Endpoint_authSecret(ctx context.Context return ec.fieldContext_TypedObjectReference_kind(ctx, field) case "name": return ec.fieldContext_TypedObjectReference_name(ctx, field) + case "displayName": + return ec.fieldContext_TypedObjectReference_displayName(ctx, field) case "namespace": return ec.fieldContext_TypedObjectReference_namespace(ctx, field) } @@ -16408,6 +16419,8 @@ func (ec *executionContext) fieldContext_KnowledgeBase_embedder(ctx context.Cont return ec.fieldContext_TypedObjectReference_kind(ctx, field) case "name": return ec.fieldContext_TypedObjectReference_name(ctx, field) + case "displayName": + return ec.fieldContext_TypedObjectReference_displayName(ctx, field) case "namespace": return ec.fieldContext_TypedObjectReference_namespace(ctx, field) } @@ -16459,6 +16472,8 @@ func (ec *executionContext) fieldContext_KnowledgeBase_vectorStore(ctx context.C return ec.fieldContext_TypedObjectReference_kind(ctx, field) case "name": return ec.fieldContext_TypedObjectReference_name(ctx, field) + case "displayName": + return ec.fieldContext_TypedObjectReference_displayName(ctx, field) case "namespace": return ec.fieldContext_TypedObjectReference_namespace(ctx, field) } @@ -22852,6 +22867,47 @@ func (ec *executionContext) fieldContext_TypedObjectReference_name(ctx context.C return fc, nil } +func (ec *executionContext) _TypedObjectReference_displayName(ctx context.Context, field graphql.CollectedField, obj *TypedObjectReference) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_TypedObjectReference_displayName(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.DisplayName, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalOString2áš–string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_TypedObjectReference_displayName(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "TypedObjectReference", + 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) _TypedObjectReference_namespace(ctx context.Context, field graphql.CollectedField, obj *TypedObjectReference) (ret graphql.Marshaler) { fc, err := ec.fieldContext_TypedObjectReference_namespace(ctx, field) if err != nil { @@ -23272,6 +23328,8 @@ func (ec *executionContext) fieldContext_VersionedDataset_dataset(ctx context.Co return ec.fieldContext_TypedObjectReference_kind(ctx, field) case "name": return ec.fieldContext_TypedObjectReference_name(ctx, field) + case "displayName": + return ec.fieldContext_TypedObjectReference_displayName(ctx, field) case "namespace": return ec.fieldContext_TypedObjectReference_namespace(ctx, field) } @@ -24585,6 +24643,8 @@ func (ec *executionContext) fieldContext_Worker_model(ctx context.Context, field return ec.fieldContext_TypedObjectReference_kind(ctx, field) case "name": return ec.fieldContext_TypedObjectReference_name(ctx, field) + case "displayName": + return ec.fieldContext_TypedObjectReference_displayName(ctx, field) case "namespace": return ec.fieldContext_TypedObjectReference_namespace(ctx, field) } @@ -27426,6 +27486,8 @@ func (ec *executionContext) fieldContext_filegroup_source(ctx context.Context, f return ec.fieldContext_TypedObjectReference_kind(ctx, field) case "name": return ec.fieldContext_TypedObjectReference_name(ctx, field) + case "displayName": + return ec.fieldContext_TypedObjectReference_displayName(ctx, field) case "namespace": return ec.fieldContext_TypedObjectReference_namespace(ctx, field) } @@ -27518,6 +27580,8 @@ func (ec *executionContext) fieldContext_filegroupdetail_source(ctx context.Cont return ec.fieldContext_TypedObjectReference_kind(ctx, field) case "name": return ec.fieldContext_TypedObjectReference_name(ctx, field) + case "displayName": + return ec.fieldContext_TypedObjectReference_displayName(ctx, field) case "namespace": return ec.fieldContext_TypedObjectReference_namespace(ctx, field) } @@ -36020,6 +36084,8 @@ func (ec *executionContext) _TypedObjectReference(ctx context.Context, sel ast.S if out.Values[i] == graphql.Null { out.Invalids++ } + case "displayName": + out.Values[i] = ec._TypedObjectReference_displayName(ctx, field, obj) case "namespace": out.Values[i] = ec._TypedObjectReference_namespace(ctx, field, obj) default: diff --git a/apiserver/graph/generated/models_gen.go b/apiserver/graph/generated/models_gen.go index 2a7fed60b..97edbc90a 100644 --- a/apiserver/graph/generated/models_gen.go +++ b/apiserver/graph/generated/models_gen.go @@ -1174,10 +1174,11 @@ type ResourcesInput struct { } type TypedObjectReference struct { - APIGroup *string `json:"apiGroup,omitempty"` - Kind string `json:"kind"` - Name string `json:"name"` - Namespace *string `json:"namespace,omitempty"` + APIGroup *string `json:"apiGroup,omitempty"` + Kind string `json:"kind"` + Name string `json:"name"` + DisplayName *string `json:"displayName,omitempty"` + Namespace *string `json:"namespace,omitempty"` } type TypedObjectReferenceInput struct { diff --git a/apiserver/graph/schema/entrypoint.graphqls b/apiserver/graph/schema/entrypoint.graphqls index b5fa7e08c..bd8b0d0df 100644 --- a/apiserver/graph/schema/entrypoint.graphqls +++ b/apiserver/graph/schema/entrypoint.graphqls @@ -72,6 +72,7 @@ type TypedObjectReference { apiGroup: String kind: String! name: String! + displayName: String namespace: String } diff --git a/apiserver/pkg/common/common.go b/apiserver/pkg/common/common.go index 46413f458..bd1419c1d 100644 --- a/apiserver/pkg/common/common.go +++ b/apiserver/pkg/common/common.go @@ -221,3 +221,12 @@ func PagePosition(page, size, total int) (int, int) { } return start, end } + +func TypedObjectReferenceToInput(ref generated.TypedObjectReference) generated.TypedObjectReferenceInput { + return generated.TypedObjectReferenceInput{ + APIGroup: ref.APIGroup, + Kind: ref.Kind, + Namespace: ref.Namespace, + Name: ref.Name, + } +} diff --git a/apiserver/pkg/knowledgebase/knowledgebase.go b/apiserver/pkg/knowledgebase/knowledgebase.go index e8c7b5c35..7f45edc3d 100644 --- a/apiserver/pkg/knowledgebase/knowledgebase.go +++ b/apiserver/pkg/knowledgebase/knowledgebase.go @@ -18,6 +18,7 @@ package knowledgebase import ( "context" + "fmt" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" @@ -32,11 +33,13 @@ import ( "github.com/kubeagi/arcadia/pkg/utils" ) -func knowledgebase2modelConverter(obj *unstructured.Unstructured) (generated.PageNode, error) { - return knowledgebase2model(obj) +func knowledgebase2modelConverter(ctx context.Context, c dynamic.Interface) func(*unstructured.Unstructured) (generated.PageNode, error) { + return func(u *unstructured.Unstructured) (generated.PageNode, error) { + return knowledgebase2model(ctx, c, u) + } } -func knowledgebase2model(obj *unstructured.Unstructured) (*generated.KnowledgeBase, error) { +func knowledgebase2model(ctx context.Context, c dynamic.Interface, obj *unstructured.Unstructured) (*generated.KnowledgeBase, error) { knowledgebase := &v1alpha1.KnowledgeBase{} if err := utils.UnstructuredToStructured(obj, knowledgebase); err != nil { return nil, err @@ -85,6 +88,25 @@ func knowledgebase2model(obj *unstructured.Unstructured) (*generated.KnowledgeBa filegroupdetails = append(filegroupdetails, filegroupdetail) } + embedder := generated.TypedObjectReference{ + APIGroup: &apiversion, + Kind: knowledgebase.Spec.Embedder.Kind, + Name: knowledgebase.Spec.Embedder.Name, + Namespace: knowledgebase.Spec.Embedder.Namespace, + } + // read displayname + embedderUnstrctured, err := common.ResourceGet(ctx, c, common.TypedObjectReferenceToInput(embedder), metav1.GetOptions{}) + if err != nil { + displayName := fmt.Sprintf("Unknown: %s", err.Error()) + embedder.DisplayName = &displayName + } else { + embedderResource := &v1alpha1.Embedder{} + if err := utils.UnstructuredToStructured(embedderUnstrctured, embedderResource); err != nil { + return nil, err + } + embedder.DisplayName = &embedderResource.Spec.DisplayName + } + md := generated.KnowledgeBase{ ID: &id, Name: obj.GetName(), @@ -97,12 +119,7 @@ func knowledgebase2model(obj *unstructured.Unstructured) (*generated.KnowledgeBa CreationTimestamp: &creationtimestamp, UpdateTimestamp: &condition.LastTransitionTime.Time, // Embedder info - Embedder: &generated.TypedObjectReference{ - APIGroup: &apiversion, - Kind: knowledgebase.Spec.Embedder.Kind, - Name: knowledgebase.Spec.Embedder.Name, - Namespace: knowledgebase.Spec.Embedder.Namespace, - }, + Embedder: &embedder, // Vector info VectorStore: &generated.TypedObjectReference{ APIGroup: &apiversion, @@ -154,7 +171,7 @@ func CreateKnowledgeBase(ctx context.Context, c dynamic.Interface, name, namespa if err != nil { return nil, err } - kb, err := knowledgebase2model(obj) + kb, err := knowledgebase2model(ctx, c, obj) if err != nil { return nil, err } @@ -163,7 +180,12 @@ func CreateKnowledgeBase(ctx context.Context, c dynamic.Interface, name, namespa details := make([]*generated.Filegroupdetail, len(filegroups)) for index, fg := range filegroups { fgDetail := &generated.Filegroupdetail{ - Source: (*generated.TypedObjectReference)(fg.Source), + Source: &generated.TypedObjectReference{ + APIGroup: fg.Source.APIGroup, + Kind: fg.Source.Kind, + Name: fg.Source.Name, + Namespace: fg.Source.Namespace, + }, } fileDetails := make([]*generated.Filedetail, len(fg.Paths)) for findex, path := range fg.Paths { @@ -217,7 +239,7 @@ func UpdateKnowledgeBase(ctx context.Context, c dynamic.Interface, input *genera return nil, err } - return knowledgebase2model(updatedObject) + return knowledgebase2model(ctx, c, updatedObject) } func DeleteKnowledgeBase(ctx context.Context, c dynamic.Interface, name, namespace, labelSelector, fieldSelector string) (*string, error) { @@ -245,7 +267,7 @@ func ReadKnowledgeBase(ctx context.Context, c dynamic.Interface, name, namespace if err != nil { return nil, err } - return knowledgebase2model(u) + return knowledgebase2model(ctx, c, u) } func ListKnowledgeBases(ctx context.Context, c dynamic.Interface, input generated.ListKnowledgeBaseInput) (*generated.PaginatedResult, error) { @@ -281,5 +303,5 @@ func ListKnowledgeBases(ctx context.Context, c dynamic.Interface, input generate return nil, err } - return common.ListReources(us, page, pageSize, knowledgebase2modelConverter, filter...) + return common.ListReources(us, page, pageSize, knowledgebase2modelConverter(ctx, c), filter...) }