Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(component): implement instill app features #670

Merged
merged 6 commits into from
Oct 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
93 changes: 73 additions & 20 deletions pkg/component/application/instillapp/v0/app_operation.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,34 +13,41 @@ import (
appPB "github.com/instill-ai/protogen-go/app/app/v1alpha"
)

// ReadChatHistoryInput is the input struct for the ReadChatHistory operation
type ReadChatHistoryInput struct {
Namespace string `json:"namespace"`
AppUID string `json:"app-id"`
AppID string `json:"app-id"`
ConversationID string `json:"conversation-id"`
Role string `json:"role"`
MessageType string `json:"message-type"`
Duration string `json:"duration"`
MaxMessageCount int `json:"max-message-count"`
}

// ReadChatHistoryOutput is the output struct for the ReadChatHistory operation
type ReadChatHistoryOutput struct {
Messages []Message `json:"messages"`
}

// Message is the struct for a message
type Message struct {
Content []Content `json:"content"`
Role string `json:"role"`
Name string `json:"name,omitempty"`
// Role can be either 'user' or 'assistant'
Role string `json:"role"`
Name string `json:"name,omitempty"`
}

// Content is the struct for the content of a message.
// It can be either text, image_url, or image_base64.
// Only one of the fields should be set, and Type should be set to the type of the content.
type Content struct {
Type string `json:"type"`
Text string `json:"text,omitempty"`
ImageURL string `json:"image-url,omitempty"`
ImageBase64 string `json:"image-base64,omitempty"`
}

func (in *ReadChatHistoryInput) Validate() error {
func (in *ReadChatHistoryInput) validate() error {
if in.Role != "" && in.Role != "user" && in.Role != "assistant" {
return fmt.Errorf("role must be either 'user' or 'assistant'")
}
Expand All @@ -58,7 +65,7 @@ func (in *ReadChatHistoryInput) Validate() error {
return nil
}

func (out *ReadChatHistoryOutput) Filter(inputStruct ReadChatHistoryInput, messages []*appPB.Message) {
func (out *ReadChatHistoryOutput) filter(inputStruct ReadChatHistoryInput, messages []*appPB.Message) {
for _, message := range messages {

if inputStruct.Role != "" && inputStruct.Role != message.Role {
Expand All @@ -81,7 +88,7 @@ func (out *ReadChatHistoryOutput) Filter(inputStruct ReadChatHistoryInput, messa

content := []Content{
{
Type: message.Type.String(),
Type: convertPBTypeToJSONType(message.Type.String()),
Text: message.Content,
},
}
Expand All @@ -93,6 +100,15 @@ func (out *ReadChatHistoryOutput) Filter(inputStruct ReadChatHistoryInput, messa
}
}

func convertPBTypeToJSONType(pbType string) string {
switch pbType {
case "MESSAGE_TYPE_TEXT":
return "text"
default:
return "unknown"
}
}

func (e *execution) readChatHistory(input *structpb.Struct) (*structpb.Struct, error) {

inputStruct := ReadChatHistoryInput{}
Expand All @@ -102,7 +118,7 @@ func (e *execution) readChatHistory(input *structpb.Struct) (*structpb.Struct, e
return nil, fmt.Errorf("failed to convert input struct: %w", err)
}

err = inputStruct.Validate()
err = inputStruct.validate()
if err != nil {
return nil, fmt.Errorf("invalid input: %w", err)
}
Expand All @@ -117,7 +133,7 @@ func (e *execution) readChatHistory(input *structpb.Struct) (*structpb.Struct, e

res, err := appClient.ListMessages(ctx, &appPB.ListMessagesRequest{
NamespaceId: inputStruct.Namespace,
AppId: inputStruct.AppUID,
AppId: inputStruct.AppID,
ConversationId: inputStruct.ConversationID,
IncludeSystemMessages: true,
})
Expand All @@ -130,12 +146,12 @@ func (e *execution) readChatHistory(input *structpb.Struct) (*structpb.Struct, e
Messages: make([]Message, 0),
}

output.Filter(inputStruct, res.Messages)
output.filter(inputStruct, res.Messages)

for res.NextPageToken != "" || (len(output.Messages) < inputStruct.MaxMessageCount && inputStruct.MaxMessageCount > 0) {
res, err = appClient.ListMessages(ctx, &appPB.ListMessagesRequest{
NamespaceId: inputStruct.Namespace,
AppId: inputStruct.AppUID,
AppId: inputStruct.AppID,
ConversationId: inputStruct.ConversationID,
IncludeSystemMessages: true,
PageToken: res.NextPageToken,
Expand All @@ -145,7 +161,7 @@ func (e *execution) readChatHistory(input *structpb.Struct) (*structpb.Struct, e
return nil, fmt.Errorf("failed to list messages: %w", err)
}

output.Filter(inputStruct, res.Messages)
output.filter(inputStruct, res.Messages)
}

return base.ConvertToStructpb(output)
Expand All @@ -154,7 +170,7 @@ func (e *execution) readChatHistory(input *structpb.Struct) (*structpb.Struct, e

type WriteChatMessageInput struct {
Namespace string `json:"namespace"`
AppUID string `json:"app-id"`
AppID string `json:"app-id"`
ConversationID string `json:"conversation-id"`
Message WriteMessage `json:"message"`
}
Expand All @@ -170,7 +186,7 @@ type WriteChatMessageOutput struct {
UpdateTime string `json:"update-time"`
}

func (in *WriteChatMessageInput) Validate() error {
func (in *WriteChatMessageInput) validate() error {
role := in.Message.Role
if role != "" && role != "user" && role != "assistant" {
return fmt.Errorf("role must be either 'user' or 'assistant'")
Expand All @@ -186,7 +202,7 @@ func (e *execution) writeChatMessage(input *structpb.Struct) (*structpb.Struct,
return nil, fmt.Errorf("failed to convert input struct: %w", err)
}

err = inputStruct.Validate()
err = inputStruct.validate()

if err != nil {
return nil, fmt.Errorf("invalid input: %w", err)
Expand All @@ -200,20 +216,57 @@ func (e *execution) writeChatMessage(input *structpb.Struct) (*structpb.Struct,

ctx = metadata.NewOutgoingContext(ctx, getRequestMetadata(e.SystemVariables))

apps, err := appClient.ListApps(ctx, &appPB.ListAppsRequest{
NamespaceId: inputStruct.Namespace,
})

if err != nil {
return nil, fmt.Errorf("failed to list apps: %w", err)
}

found := false

for _, app := range apps.Apps {
if app.AppId == inputStruct.AppID {
found = true
break
}
}

if !found {
_, err = appClient.CreateApp(ctx, &appPB.CreateAppRequest{
NamespaceId: inputStruct.Namespace,
Id: inputStruct.AppID,
})

if err != nil {
return nil, fmt.Errorf("failed to create app: %w", err)
}
}

conversations, err := appClient.ListConversations(ctx, &appPB.ListConversationsRequest{
NamespaceId: inputStruct.Namespace,
AppId: inputStruct.AppUID,
ConversationId: inputStruct.ConversationID,
NamespaceId: inputStruct.Namespace,
AppId: inputStruct.AppID,
IfAll: true,
})

if err != nil {
return nil, fmt.Errorf("failed to list conversations: %w", err)
}

if len(conversations.Conversations) == 0 {
found = false

for _, conversation := range conversations.Conversations {
if conversation.Id == inputStruct.ConversationID {
found = true
break
}
}

if !found {
_, err = appClient.CreateConversation(ctx, &appPB.CreateConversationRequest{
NamespaceId: inputStruct.Namespace,
AppId: inputStruct.AppUID,
AppId: inputStruct.AppID,
ConversationId: inputStruct.ConversationID,
})

Expand All @@ -224,7 +277,7 @@ func (e *execution) writeChatMessage(input *structpb.Struct) (*structpb.Struct,

res, err := appClient.CreateMessage(ctx, &appPB.CreateMessageRequest{
NamespaceId: inputStruct.Namespace,
AppId: inputStruct.AppUID,
AppId: inputStruct.AppID,
ConversationId: inputStruct.ConversationID,
Role: inputStruct.Message.Role,
Type: appPB.Message_MessageType(appPB.Message_MessageType_value["MESSAGE_TYPE_TEXT"]),
Expand Down
3 changes: 2 additions & 1 deletion pkg/component/store/store.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import (
"github.com/instill-ai/pipeline-backend/pkg/component/application/github/v0"
"github.com/instill-ai/pipeline-backend/pkg/component/application/googlesearch/v0"
"github.com/instill-ai/pipeline-backend/pkg/component/application/hubspot/v0"
"github.com/instill-ai/pipeline-backend/pkg/component/application/instillapp/v0"
"github.com/instill-ai/pipeline-backend/pkg/component/application/jira/v0"
"github.com/instill-ai/pipeline-backend/pkg/component/application/numbers/v0"
"github.com/instill-ai/pipeline-backend/pkg/component/application/slack/v0"
Expand Down Expand Up @@ -169,7 +170,7 @@ func Init(
compStore.Import(conn)
}

// compStore.Import(instillapp.Init(baseComp))
compStore.Import(instillapp.Init(baseComp))
compStore.Import(bigquery.Init(baseComp))
compStore.Import(googlecloudstorage.Init(baseComp))
compStore.Import(googlesearch.Init(baseComp))
Expand Down
19 changes: 19 additions & 0 deletions pkg/service/component_definition.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"google.golang.org/protobuf/proto"
"google.golang.org/protobuf/reflect/protoreflect"

"github.com/instill-ai/pipeline-backend/config"
"github.com/instill-ai/pipeline-backend/pkg/recipe"
"github.com/instill-ai/pipeline-backend/pkg/repository"
"github.com/instill-ai/x/paginate"
Expand Down Expand Up @@ -222,6 +223,13 @@ func (s *service) ListComponentDefinitions(ctx context.Context, req *pb.ListComp
if req.GetView() != pb.ComponentDefinition_VIEW_FULL {
def.Spec = nil
}

// Temporary solution to filter out the instill-app component for local-ce:dev edition
// In the future the non-CE definitions shouldn't be in the CE repositories and Cloud should extend the CE component store to initialize the private components.
if skipComponentInCE(def.GetId()) {
continue
}

defs[i] = def
}

Expand All @@ -235,6 +243,17 @@ func (s *service) ListComponentDefinitions(ctx context.Context, req *pb.ListComp
return resp, nil
}

var skipComponentsInCE = map[string]bool{
"instill-app": true,
}

func skipComponentInCE(componentID string) bool {
if skipComponentsInCE[componentID] && config.Config.Server.Edition == "local-ce:dev" {
return true
}
return false
}

var implementedReleaseStages = map[pb.ComponentDefinition_ReleaseStage]bool{
pb.ComponentDefinition_RELEASE_STAGE_ALPHA: true,
pb.ComponentDefinition_RELEASE_STAGE_BETA: true,
Expand Down
Loading