feat: Support for Chat Flow & Agent Support for binding a single chat flow (#765)
Co-authored-by: Yu Yang <72337138+tomasyu985@users.noreply.github.com> Co-authored-by: zengxiaohui <csu.zengxiaohui@gmail.com> Co-authored-by: lijunwen.gigoo <lijunwen.gigoo@bytedance.com> Co-authored-by: lvxinyu.1117 <lvxinyu.1117@bytedance.com> Co-authored-by: liuyunchao.0510 <liuyunchao.0510@bytedance.com> Co-authored-by: haozhenfei <37089575+haozhenfei@users.noreply.github.com> Co-authored-by: July <jiangxujin@bytedance.com> Co-authored-by: tecvan-fe <fanwenjie.fe@bytedance.com>
This commit is contained in:
@@ -24,6 +24,7 @@ import (
|
||||
"github.com/cloudwego/eino/schema"
|
||||
|
||||
workflowModel "github.com/coze-dev/coze-studio/backend/api/model/crossdomain/workflow"
|
||||
conventity "github.com/coze-dev/coze-studio/backend/domain/conversation/conversation/entity"
|
||||
"github.com/coze-dev/coze-studio/backend/domain/workflow/config"
|
||||
"github.com/coze-dev/coze-studio/backend/domain/workflow/entity"
|
||||
"github.com/coze-dev/coze-studio/backend/domain/workflow/entity/vo"
|
||||
@@ -55,12 +56,41 @@ type AsTool interface {
|
||||
allInterruptEvents map[string]*entity.ToolInterruptEvent) compose.Option
|
||||
}
|
||||
|
||||
type ChatFlowRole interface {
|
||||
CreateChatFlowRole(ctx context.Context, role *vo.ChatFlowRoleCreate) (int64, error)
|
||||
UpdateChatFlowRole(ctx context.Context, workflowID int64, role *vo.ChatFlowRoleUpdate) error
|
||||
GetChatFlowRole(ctx context.Context, workflowID int64, version string) (*entity.ChatFlowRole, error)
|
||||
DeleteChatFlowRole(ctx context.Context, id int64, workflowID int64) error
|
||||
PublishChatFlowRole(ctx context.Context, policy *vo.PublishRolePolicy) error
|
||||
}
|
||||
|
||||
type Conversation interface {
|
||||
CreateDraftConversationTemplate(ctx context.Context, template *vo.CreateConversationTemplateMeta) (int64, error)
|
||||
UpdateDraftConversationTemplateName(ctx context.Context, appID int64, userID int64, templateID int64, name string) error
|
||||
DeleteDraftConversationTemplate(ctx context.Context, templateID int64, wfID2ConversationName map[int64]string) (int64, error)
|
||||
CheckWorkflowsToReplace(ctx context.Context, appID int64, templateID int64) ([]*entity.Workflow, error)
|
||||
DeleteDynamicConversation(ctx context.Context, env vo.Env, templateID int64) (int64, error)
|
||||
ListConversationTemplate(ctx context.Context, env vo.Env, policy *vo.ListConversationTemplatePolicy) ([]*entity.ConversationTemplate, error)
|
||||
MGetStaticConversation(ctx context.Context, env vo.Env, userID, connectorID int64, templateIDs []int64) ([]*entity.StaticConversation, error)
|
||||
ListDynamicConversation(ctx context.Context, env vo.Env, policy *vo.ListConversationPolicy) ([]*entity.DynamicConversation, error)
|
||||
ReleaseConversationTemplate(ctx context.Context, appID int64, version string) error
|
||||
InitApplicationDefaultConversationTemplate(ctx context.Context, spaceID int64, appID int64, userID int64) error
|
||||
GetOrCreateConversation(ctx context.Context, env vo.Env, appID, connectorID, userID int64, conversationName string) (int64, int64, error)
|
||||
UpdateConversation(ctx context.Context, env vo.Env, appID, connectorID, userID int64, conversationName string) (int64, error)
|
||||
GetTemplateByName(ctx context.Context, env vo.Env, appID int64, templateName string) (*entity.ConversationTemplate, bool, error)
|
||||
GetDynamicConversationByName(ctx context.Context, env vo.Env, appID, connectorID, userID int64, name string) (*entity.DynamicConversation, bool, error)
|
||||
GetConversationNameByID(ctx context.Context, env vo.Env, appID, connectorID, conversationID int64) (string, bool, error)
|
||||
}
|
||||
|
||||
type InterruptEventStore interface {
|
||||
SaveInterruptEvents(ctx context.Context, wfExeID int64, events []*entity.InterruptEvent) error
|
||||
GetFirstInterruptEvent(ctx context.Context, wfExeID int64) (*entity.InterruptEvent, bool, error)
|
||||
UpdateFirstInterruptEvent(ctx context.Context, wfExeID int64, event *entity.InterruptEvent) error
|
||||
PopFirstInterruptEvent(ctx context.Context, wfExeID int64) (*entity.InterruptEvent, bool, error)
|
||||
ListInterruptEvents(ctx context.Context, wfExeID int64) ([]*entity.InterruptEvent, error)
|
||||
|
||||
BindConvRelatedInfo(ctx context.Context, convID int64, info entity.ConvRelatedInfo) error
|
||||
GetConvRelatedInfo(ctx context.Context, convID int64) (*entity.ConvRelatedInfo, bool, func() error, error)
|
||||
}
|
||||
|
||||
type CancelSignalStore interface {
|
||||
@@ -93,6 +123,33 @@ type ToolFromWorkflow interface {
|
||||
GetWorkflow() *entity.Workflow
|
||||
}
|
||||
|
||||
type ConversationIDGenerator func(ctx context.Context, appID int64, userID, connectorID int64) (*conventity.Conversation, error)
|
||||
|
||||
type ConversationRepository interface {
|
||||
CreateDraftConversationTemplate(ctx context.Context, template *vo.CreateConversationTemplateMeta) (int64, error)
|
||||
UpdateDraftConversationTemplateName(ctx context.Context, templateID int64, name string) error
|
||||
DeleteDraftConversationTemplate(ctx context.Context, templateID int64) (int64, error)
|
||||
GetConversationTemplate(ctx context.Context, env vo.Env, policy vo.GetConversationTemplatePolicy) (*entity.ConversationTemplate, bool, error)
|
||||
DeleteDynamicConversation(ctx context.Context, env vo.Env, id int64) (int64, error)
|
||||
ListConversationTemplate(ctx context.Context, env vo.Env, policy *vo.ListConversationTemplatePolicy) ([]*entity.ConversationTemplate, error)
|
||||
MGetStaticConversation(ctx context.Context, env vo.Env, userID, connectorID int64, templateIDs []int64) ([]*entity.StaticConversation, error)
|
||||
GetOrCreateStaticConversation(ctx context.Context, env vo.Env, idGen ConversationIDGenerator, meta *vo.CreateStaticConversation) (int64, int64, bool, error)
|
||||
GetOrCreateDynamicConversation(ctx context.Context, env vo.Env, idGen ConversationIDGenerator, meta *vo.CreateDynamicConversation) (int64, int64, bool, error)
|
||||
GetDynamicConversationByName(ctx context.Context, env vo.Env, appID, connectorID, userID int64, name string) (*entity.DynamicConversation, bool, error)
|
||||
GetStaticConversationByTemplateID(ctx context.Context, env vo.Env, userID, connectorID, templateID int64) (*entity.StaticConversation, bool, error)
|
||||
ListDynamicConversation(ctx context.Context, env vo.Env, policy *vo.ListConversationPolicy) ([]*entity.DynamicConversation, error)
|
||||
BatchCreateOnlineConversationTemplate(ctx context.Context, templates []*entity.ConversationTemplate, version string) error
|
||||
UpdateDynamicConversationNameByID(ctx context.Context, env vo.Env, templateID int64, name string) error
|
||||
UpdateStaticConversation(ctx context.Context, env vo.Env, templateID int64, connectorID int64, userID int64, newConversationID int64) error
|
||||
UpdateDynamicConversation(ctx context.Context, env vo.Env, conversationID, newConversationID int64) error
|
||||
CopyTemplateConversationByAppID(ctx context.Context, appID int64, toAppID int64) error
|
||||
GetStaticConversationByID(ctx context.Context, env vo.Env, appID, connectorID, conversationID int64) (string, bool, error)
|
||||
GetDynamicConversationByID(ctx context.Context, env vo.Env, appID, connectorID, conversationID int64) (*entity.DynamicConversation, bool, error)
|
||||
}
|
||||
type WorkflowConfig interface {
|
||||
GetNodeOfCodeConfig() *config.NodeOfCodeConfig
|
||||
}
|
||||
|
||||
type Suggester interface {
|
||||
Suggest(ctx context.Context, input *vo.SuggestInfo) ([]string, error)
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ type WorkflowConfig struct {
|
||||
NodeOfCodeConfig *NodeOfCodeConfig `yaml:"NodeOfCodeConfig"`
|
||||
}
|
||||
|
||||
func (w WorkflowConfig) GetNodeOfCodeConfig() *NodeOfCodeConfig {
|
||||
func (w *WorkflowConfig) GetNodeOfCodeConfig() *NodeOfCodeConfig {
|
||||
return w.NodeOfCodeConfig
|
||||
}
|
||||
|
||||
|
||||
37
backend/domain/workflow/entity/chatflow_role.go
Normal file
37
backend/domain/workflow/entity/chatflow_role.go
Normal file
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* 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 entity
|
||||
|
||||
import "time"
|
||||
|
||||
type ChatFlowRole struct {
|
||||
ID int64
|
||||
WorkflowID int64
|
||||
ConnectorID int64
|
||||
Name string
|
||||
Description string
|
||||
Version string
|
||||
AvatarUri string
|
||||
BackgroundImageInfo string
|
||||
OnboardingInfo string
|
||||
SuggestReplyInfo string
|
||||
AudioConfig string
|
||||
UserInputConfig string
|
||||
CreatorID int64
|
||||
CreatedAt time.Time
|
||||
UpdatedAt time.Time
|
||||
}
|
||||
39
backend/domain/workflow/entity/conversation.go
Normal file
39
backend/domain/workflow/entity/conversation.go
Normal file
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* 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 entity
|
||||
|
||||
type ConversationTemplate struct {
|
||||
SpaceID int64
|
||||
AppID int64
|
||||
Name string
|
||||
TemplateID int64
|
||||
}
|
||||
|
||||
type StaticConversation struct {
|
||||
UserID int64
|
||||
ConnectorID int64
|
||||
TemplateID int64
|
||||
ConversationID int64
|
||||
}
|
||||
|
||||
type DynamicConversation struct {
|
||||
ID int64
|
||||
UserID int64
|
||||
ConnectorID int64
|
||||
ConversationID int64
|
||||
Name string
|
||||
}
|
||||
@@ -74,3 +74,9 @@ type ToolInterruptEvent struct {
|
||||
ExecuteID int64
|
||||
*InterruptEvent
|
||||
}
|
||||
|
||||
type ConvRelatedInfo struct {
|
||||
EventID int64
|
||||
ExecID int64
|
||||
NodeType NodeType
|
||||
}
|
||||
|
||||
@@ -144,8 +144,11 @@ const (
|
||||
NodeTypeCodeRunner NodeType = "CodeRunner"
|
||||
NodeTypePlugin NodeType = "Plugin"
|
||||
NodeTypeCreateConversation NodeType = "CreateConversation"
|
||||
NodeTypeConversationList NodeType = "ConversationList"
|
||||
NodeTypeMessageList NodeType = "MessageList"
|
||||
NodeTypeClearMessage NodeType = "ClearMessage"
|
||||
NodeTypeCreateMessage NodeType = "CreateMessage"
|
||||
NodeTypeEditMessage NodeType = "EditMessage"
|
||||
NodeTypeDeleteMessage NodeType = "DeleteMessage"
|
||||
NodeTypeLambda NodeType = "Lambda"
|
||||
NodeTypeLLM NodeType = "LLM"
|
||||
NodeTypeSelector NodeType = "Selector"
|
||||
@@ -153,6 +156,10 @@ const (
|
||||
NodeTypeSubWorkflow NodeType = "SubWorkflow"
|
||||
NodeTypeJsonSerialization NodeType = "JsonSerialization"
|
||||
NodeTypeJsonDeserialization NodeType = "JsonDeserialization"
|
||||
NodeTypeConversationUpdate NodeType = "ConversationUpdate"
|
||||
NodeTypeConversationDelete NodeType = "ConversationDelete"
|
||||
NodeTypeClearConversationHistory NodeType = "ClearConversationHistory"
|
||||
NodeTypeConversationHistory NodeType = "ConversationHistory"
|
||||
NodeTypeComment NodeType = "Comment"
|
||||
)
|
||||
|
||||
@@ -272,6 +279,7 @@ var NodeTypeMetas = map[NodeType]*NodeTypeMeta{
|
||||
PostFillNil: true,
|
||||
InputSourceAware: true,
|
||||
MayUseChatModel: true,
|
||||
UseCtxCache: true,
|
||||
},
|
||||
EnUSName: "LLM",
|
||||
EnUSDescription: "Invoke the large language model, generate responses using variables and prompt words.",
|
||||
@@ -324,6 +332,7 @@ var NodeTypeMetas = map[NodeType]*NodeTypeMeta{
|
||||
ExecutableMeta: ExecutableMeta{
|
||||
PreFillZero: true,
|
||||
PostFillNil: true,
|
||||
UseCtxCache: true,
|
||||
},
|
||||
EnUSName: "Knowledge retrieval",
|
||||
EnUSDescription: "In the selected knowledge, the best matching information is recalled based on the input variable and returned as an Array.",
|
||||
@@ -487,6 +496,7 @@ var NodeTypeMetas = map[NodeType]*NodeTypeMeta{
|
||||
PreFillZero: true,
|
||||
PostFillNil: true,
|
||||
MayUseChatModel: true,
|
||||
UseCtxCache: true,
|
||||
},
|
||||
EnUSName: "Intent recognition",
|
||||
EnUSDescription: "Used for recognizing the intent in user input and matching it with preset intent options.",
|
||||
@@ -593,7 +603,6 @@ var NodeTypeMetas = map[NodeType]*NodeTypeMeta{
|
||||
Color: "#F2B600",
|
||||
IconURL: "https://lf3-static.bytednsdoc.com/obj/eden-cn/dvsmryvd_avi_dvsm/ljhwZthlaukjlkulzlp/icon/icon-Conversation-List.jpeg",
|
||||
SupportBatch: false,
|
||||
Disabled: true,
|
||||
ExecutableMeta: ExecutableMeta{
|
||||
PreFillZero: true,
|
||||
PostFillNil: true,
|
||||
@@ -601,16 +610,15 @@ var NodeTypeMetas = map[NodeType]*NodeTypeMeta{
|
||||
EnUSName: "Query message list",
|
||||
EnUSDescription: "Used to query the message list",
|
||||
},
|
||||
NodeTypeClearMessage: {
|
||||
NodeTypeClearConversationHistory: {
|
||||
ID: 38,
|
||||
Key: NodeTypeClearMessage,
|
||||
Name: "清除上下文",
|
||||
Category: "conversation_history",
|
||||
Key: NodeTypeClearConversationHistory,
|
||||
Name: "清空会话历史",
|
||||
Category: "conversation_history", // Mapped from cate_list
|
||||
Desc: "用于清空会话历史,清空后LLM看到的会话历史为空",
|
||||
Color: "#F2B600",
|
||||
IconURL: "https://lf3-static.bytednsdoc.com/obj/eden-cn/dvsmryvd_avi_dvsm/ljhwZthlaukjlkulzlp/icon/icon-Conversation-Delete.jpeg",
|
||||
SupportBatch: false,
|
||||
Disabled: true,
|
||||
SupportBatch: false, // supportBatch: 1
|
||||
ExecutableMeta: ExecutableMeta{
|
||||
PreFillZero: true,
|
||||
PostFillNil: true,
|
||||
@@ -627,7 +635,6 @@ var NodeTypeMetas = map[NodeType]*NodeTypeMeta{
|
||||
Color: "#F2B600",
|
||||
IconURL: "https://lf3-static.bytednsdoc.com/obj/eden-cn/dvsmryvd_avi_dvsm/ljhwZthlaukjlkulzlp/icon/icon-Conversation-Create.jpeg",
|
||||
SupportBatch: false,
|
||||
Disabled: true,
|
||||
ExecutableMeta: ExecutableMeta{
|
||||
PreFillZero: true,
|
||||
PostFillNil: true,
|
||||
@@ -730,6 +737,118 @@ var NodeTypeMetas = map[NodeType]*NodeTypeMeta{
|
||||
EnUSName: "Add Data",
|
||||
EnUSDescription: "Add new data records to the table, and insert them into the database after the user enters the data content",
|
||||
},
|
||||
NodeTypeConversationUpdate: {
|
||||
ID: 51,
|
||||
Name: "修改会话",
|
||||
Key: NodeTypeConversationUpdate,
|
||||
Category: "conversation_management",
|
||||
Desc: "用于修改会话的名字",
|
||||
Color: "#F2B600",
|
||||
IconURL: "https://lf3-static.bytednsdoc.com/obj/eden-cn/dvsmryvd_avi_dvsm/ljhwZthlaukjlkulzlp/icon/icon-编辑会话.jpg",
|
||||
SupportBatch: false,
|
||||
ExecutableMeta: ExecutableMeta{
|
||||
PreFillZero: true,
|
||||
PostFillNil: true,
|
||||
},
|
||||
EnUSName: "Edit Conversation",
|
||||
EnUSDescription: "Used to modify the name of a conversation.",
|
||||
},
|
||||
|
||||
NodeTypeConversationDelete: {
|
||||
ID: 52,
|
||||
Name: "删除会话",
|
||||
Key: NodeTypeConversationDelete,
|
||||
Category: "conversation_management",
|
||||
Desc: "用于删除会话",
|
||||
Color: "#F2B600",
|
||||
IconURL: "https://lf3-static.bytednsdoc.com/obj/eden-cn/dvsmryvd_avi_dvsm/ljhwZthlaukjlkulzlp/icon/icon-删除会话.jpg",
|
||||
SupportBatch: false,
|
||||
ExecutableMeta: ExecutableMeta{
|
||||
PreFillZero: true,
|
||||
PostFillNil: true,
|
||||
},
|
||||
EnUSName: "Delete Conversation",
|
||||
EnUSDescription: "Used to delete a conversation.",
|
||||
},
|
||||
NodeTypeConversationList: {
|
||||
ID: 53,
|
||||
Name: "查询会话列表",
|
||||
Key: NodeTypeConversationList,
|
||||
Category: "conversation_management",
|
||||
Desc: "用于查询所有会话,包含静态会话、动态会话",
|
||||
Color: "#F2B600",
|
||||
IconURL: "https://lf3-static.bytednsdoc.com/obj/eden-cn/dvsmryvd_avi_dvsm/ljhwZthlaukjlkulzlp/icon/icon-查询会话.jpg",
|
||||
SupportBatch: false,
|
||||
ExecutableMeta: ExecutableMeta{
|
||||
PostFillNil: true,
|
||||
},
|
||||
EnUSName: "Query Conversation List",
|
||||
EnUSDescription: "Used to query all conversations, including static conversations and dynamic conversations",
|
||||
},
|
||||
NodeTypeConversationHistory: {
|
||||
ID: 54,
|
||||
Name: "查询会话历史",
|
||||
Key: NodeTypeConversationHistory,
|
||||
Category: "conversation_history", // Mapped from cate_list
|
||||
Desc: "用于查询会话历史,返回LLM可见的会话消息",
|
||||
Color: "#F2B600",
|
||||
IconURL: "https://lf3-static.bytednsdoc.com/obj/eden-cn/dvsmryvd_avi_dvsm/ljhwZthlaukjlkulzlp/icon/icon-查询会话历史.jpg",
|
||||
SupportBatch: false,
|
||||
ExecutableMeta: ExecutableMeta{
|
||||
PreFillZero: true,
|
||||
PostFillNil: true,
|
||||
},
|
||||
EnUSName: "Query Conversation History",
|
||||
EnUSDescription: "Used to query conversation history, returns conversation messages visible to the LLM",
|
||||
},
|
||||
NodeTypeCreateMessage: {
|
||||
ID: 55,
|
||||
Name: "创建消息",
|
||||
Key: NodeTypeCreateMessage,
|
||||
Category: "message",
|
||||
Desc: "用于创建消息",
|
||||
Color: "#F2B600",
|
||||
IconURL: "https://lf3-static.bytednsdoc.com/obj/eden-cn/dvsmryvd_avi_dvsm/ljhwZthlaukjlkulzlp/icon/icon-创建消息.jpg",
|
||||
SupportBatch: false, // supportBatch: 1
|
||||
ExecutableMeta: ExecutableMeta{
|
||||
PreFillZero: true,
|
||||
PostFillNil: true,
|
||||
},
|
||||
EnUSName: "Create message",
|
||||
EnUSDescription: "Used to create messages",
|
||||
},
|
||||
NodeTypeEditMessage: {
|
||||
ID: 56,
|
||||
Name: "修改消息",
|
||||
Key: NodeTypeEditMessage,
|
||||
Category: "message",
|
||||
Desc: "用于修改消息",
|
||||
Color: "#F2B600",
|
||||
IconURL: "https://lf3-static.bytednsdoc.com/obj/eden-cn/dvsmryvd_avi_dvsm/ljhwZthlaukjlkulzlp/icon/icon-修改消息.jpg",
|
||||
SupportBatch: false, // supportBatch: 1
|
||||
ExecutableMeta: ExecutableMeta{
|
||||
PreFillZero: true,
|
||||
PostFillNil: true,
|
||||
},
|
||||
EnUSName: "Edit message",
|
||||
EnUSDescription: "Used to edit messages",
|
||||
},
|
||||
NodeTypeDeleteMessage: {
|
||||
ID: 57,
|
||||
Name: "删除消息",
|
||||
Key: NodeTypeDeleteMessage,
|
||||
Category: "message",
|
||||
Desc: "用于删除消息",
|
||||
Color: "#F2B600",
|
||||
IconURL: "https://lf3-static.bytednsdoc.com/obj/eden-cn/dvsmryvd_avi_dvsm/ljhwZthlaukjlkulzlp/icon/icon-删除消息.jpg",
|
||||
SupportBatch: false, // supportBatch: 1
|
||||
ExecutableMeta: ExecutableMeta{
|
||||
PreFillZero: true,
|
||||
PostFillNil: true,
|
||||
},
|
||||
EnUSName: "Delete message",
|
||||
EnUSDescription: "Used to delete messages",
|
||||
},
|
||||
NodeTypeJsonSerialization: {
|
||||
// ID is the unique identifier of this node type. Used in various front-end APIs.
|
||||
ID: 58,
|
||||
|
||||
@@ -17,6 +17,8 @@
|
||||
package vo
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
model "github.com/coze-dev/coze-studio/backend/api/model/crossdomain/modelmgr"
|
||||
"github.com/coze-dev/coze-studio/backend/api/model/workflow"
|
||||
"github.com/coze-dev/coze-studio/backend/pkg/i18n"
|
||||
@@ -108,7 +110,8 @@ type Data struct {
|
||||
type Inputs struct {
|
||||
// InputParameters are the fields defined by user for this particular node.
|
||||
InputParameters []*Param `json:"inputParameters"`
|
||||
|
||||
// ChatHistorySetting configures the chat history setting for this node in chatflow mode.
|
||||
ChatHistorySetting *ChatHistorySetting `json:"chatHistorySetting,omitempty"`
|
||||
// SettingOnError configures common error handling strategy for nodes.
|
||||
// NOTE: enable in frontend node's form first.
|
||||
SettingOnError *SettingOnError `json:"settingOnError,omitempty"`
|
||||
@@ -432,9 +435,8 @@ type DatabaseInfo struct {
|
||||
}
|
||||
|
||||
type IntentDetector struct {
|
||||
ChatHistorySetting *ChatHistorySetting `json:"chatHistorySetting,omitempty"`
|
||||
Intents []*Intent `json:"intents,omitempty"`
|
||||
Mode string `json:"mode,omitempty"`
|
||||
Intents []*Intent `json:"intents,omitempty"`
|
||||
Mode string `json:"mode,omitempty"`
|
||||
}
|
||||
type ChatHistorySetting struct {
|
||||
EnableChatHistory bool `json:"enableChatHistory,omitempty"`
|
||||
@@ -826,6 +828,133 @@ const defaultEnUSInitCanvasJsonSchema = `{
|
||||
}
|
||||
}`
|
||||
|
||||
const defaultZhCNInitCanvasJsonSchemaChat = `{
|
||||
"nodes": [{
|
||||
"id": "100001",
|
||||
"type": "1",
|
||||
"meta": {
|
||||
"position": {
|
||||
"x": 0,
|
||||
"y": 0
|
||||
}
|
||||
},
|
||||
"data": {
|
||||
"outputs": [{
|
||||
"type": "string",
|
||||
"name": "USER_INPUT",
|
||||
"required": true
|
||||
}, {
|
||||
"type": "string",
|
||||
"name": "CONVERSATION_NAME",
|
||||
"required": false,
|
||||
"description": "本次请求绑定的会话,会自动写入消息、会从该会话读对话历史。",
|
||||
"defaultValue": "%s"
|
||||
}],
|
||||
"nodeMeta": {
|
||||
"title": "开始",
|
||||
"icon": "https://lf3-static.bytednsdoc.com/obj/eden-cn/dvsmryvd_avi_dvsm/ljhwZthlaukjlkulzlp/icon/icon-Start.png",
|
||||
"description": "工作流的起始节点,用于设定启动工作流需要的信息",
|
||||
"subTitle": ""
|
||||
}
|
||||
}
|
||||
}, {
|
||||
"id": "900001",
|
||||
"type": "2",
|
||||
"meta": {
|
||||
"position": {
|
||||
"x": 1000,
|
||||
"y": 0
|
||||
}
|
||||
},
|
||||
"data": {
|
||||
"nodeMeta": {
|
||||
"title": "结束",
|
||||
"icon": "https://lf3-static.bytednsdoc.com/obj/eden-cn/dvsmryvd_avi_dvsm/ljhwZthlaukjlkulzlp/icon/icon-End.png",
|
||||
"description": "工作流的最终节点,用于返回工作流运行后的结果信息",
|
||||
"subTitle": ""
|
||||
},
|
||||
"inputs": {
|
||||
"terminatePlan": "useAnswerContent",
|
||||
"streamingOutput": true,
|
||||
"inputParameters": [{
|
||||
"name": "output",
|
||||
"input": {
|
||||
"type": "string",
|
||||
"value": {
|
||||
"type": "ref"
|
||||
}
|
||||
}
|
||||
}]
|
||||
}
|
||||
}
|
||||
}]
|
||||
}`
|
||||
const defaultEnUSInitCanvasJsonSchemaChat = `{
|
||||
"nodes": [{
|
||||
"id": "100001",
|
||||
"type": "1",
|
||||
"meta": {
|
||||
"position": {
|
||||
"x": 0,
|
||||
"y": 0
|
||||
}
|
||||
},
|
||||
"data": {
|
||||
"outputs": [{
|
||||
"type": "string",
|
||||
"name": "USER_INPUT",
|
||||
"required": true
|
||||
}, {
|
||||
"type": "string",
|
||||
"name": "CONVERSATION_NAME",
|
||||
"required": false,
|
||||
"description": "The conversation bound to this request will automatically write messages and read conversation history from that conversation.",
|
||||
"defaultValue": "%s"
|
||||
}],
|
||||
"nodeMeta": {
|
||||
"title": "Start",
|
||||
"icon": "https://lf3-static.bytednsdoc.com/obj/eden-cn/dvsmryvd_avi_dvsm/ljhwZthlaukjlkulzlp/icon/icon-Start.png",
|
||||
"description": "The starting node of the workflow, used to set the information needed to initiate the workflow.",
|
||||
"subTitle": ""
|
||||
}
|
||||
}
|
||||
}, {
|
||||
"id": "900001",
|
||||
"type": "2",
|
||||
"meta": {
|
||||
"position": {
|
||||
"x": 1000,
|
||||
"y": 0
|
||||
}
|
||||
},
|
||||
"data": {
|
||||
"nodeMeta": {
|
||||
"title": "End",
|
||||
"icon": "https://lf3-static.bytednsdoc.com/obj/eden-cn/dvsmryvd_avi_dvsm/ljhwZthlaukjlkulzlp/icon/icon-End.png",
|
||||
"description": "The final node of the workflow, used to return the result information after the workflow runs.",
|
||||
"subTitle": ""
|
||||
},
|
||||
"inputs": {
|
||||
"terminatePlan": "useAnswerContent",
|
||||
"streamingOutput": true,
|
||||
"inputParameters": [{
|
||||
"name": "output",
|
||||
"input": {
|
||||
"type": "string",
|
||||
"value": {
|
||||
"type": "ref"
|
||||
}
|
||||
}
|
||||
}]
|
||||
}
|
||||
}
|
||||
}]
|
||||
}`
|
||||
|
||||
func GetDefaultInitCanvasJsonSchema(locale i18n.Locale) string {
|
||||
return ternary.IFElse(locale == i18n.LocaleEN, defaultEnUSInitCanvasJsonSchema, defaultZhCNInitCanvasJsonSchema)
|
||||
}
|
||||
|
||||
func GetDefaultInitCanvasJsonSchemaChat(locale i18n.Locale, name string) string {
|
||||
return ternary.IFElse(locale == i18n.LocaleEN, fmt.Sprintf(defaultEnUSInitCanvasJsonSchemaChat, name), fmt.Sprintf(defaultZhCNInitCanvasJsonSchemaChat, name))
|
||||
}
|
||||
|
||||
48
backend/domain/workflow/entity/vo/chat_flow_role.go
Normal file
48
backend/domain/workflow/entity/vo/chat_flow_role.go
Normal file
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* 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 vo
|
||||
|
||||
type ChatFlowRoleCreate struct {
|
||||
WorkflowID int64
|
||||
CreatorID int64
|
||||
Name string
|
||||
Description string
|
||||
AvatarUri string
|
||||
BackgroundImageInfo string
|
||||
OnboardingInfo string
|
||||
SuggestReplyInfo string
|
||||
AudioConfig string
|
||||
UserInputConfig string
|
||||
}
|
||||
|
||||
type ChatFlowRoleUpdate struct {
|
||||
WorkflowID int64
|
||||
Name *string
|
||||
Description *string
|
||||
AvatarUri *string
|
||||
BackgroundImageInfo *string
|
||||
OnboardingInfo *string
|
||||
SuggestReplyInfo *string
|
||||
AudioConfig *string
|
||||
UserInputConfig *string
|
||||
}
|
||||
|
||||
type PublishRolePolicy struct {
|
||||
WorkflowID int64
|
||||
CreatorID int64
|
||||
Version string
|
||||
}
|
||||
84
backend/domain/workflow/entity/vo/chatflow.go
Normal file
84
backend/domain/workflow/entity/vo/chatflow.go
Normal file
@@ -0,0 +1,84 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* 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 vo
|
||||
|
||||
import "github.com/cloudwego/eino/schema"
|
||||
|
||||
type ChatFlowEvent string
|
||||
|
||||
const (
|
||||
ChatFlowCreated ChatFlowEvent = "conversation.chat.created"
|
||||
ChatFlowInProgress ChatFlowEvent = "conversation.chat.in_progress"
|
||||
ChatFlowCompleted ChatFlowEvent = "conversation.chat.completed"
|
||||
ChatFlowFailed ChatFlowEvent = "conversation.chat.failed"
|
||||
ChatFlowRequiresAction ChatFlowEvent = "conversation.chat.requires_action"
|
||||
ChatFlowError ChatFlowEvent = "error"
|
||||
ChatFlowDone ChatFlowEvent = "done"
|
||||
ChatFlowMessageDelta ChatFlowEvent = "conversation.message.delta"
|
||||
ChatFlowMessageCompleted ChatFlowEvent = "conversation.message.completed"
|
||||
)
|
||||
|
||||
type Usage struct {
|
||||
TokenCount *int32 `form:"token_count" json:"token_count,omitempty"`
|
||||
OutputTokens *int32 `form:"output_count" json:"output_count,omitempty"`
|
||||
InputTokens *int32 `form:"input_count" json:"input_count,omitempty"`
|
||||
}
|
||||
|
||||
type Status string
|
||||
|
||||
const (
|
||||
Created Status = "created"
|
||||
InProgress Status = "in_progress"
|
||||
Completed Status = "completed"
|
||||
Failed Status = "failed"
|
||||
RequiresAction Status = "requires_action"
|
||||
Canceled Status = "canceled"
|
||||
)
|
||||
|
||||
type ChatFlowDetail struct {
|
||||
ID string `json:"id,omitempty"`
|
||||
ConversationID string `json:"conversation_id,omitempty"`
|
||||
BotID string `json:"bot_id,omitempty"`
|
||||
Status Status `json:"status,omitempty"`
|
||||
Usage *Usage `json:"usage,omitempty"`
|
||||
ExecuteID string `json:"execute_id,omitempty"`
|
||||
SectionID string `json:"section_id"`
|
||||
}
|
||||
|
||||
type MessageDetail struct {
|
||||
ID string `json:"id"`
|
||||
ChatID string `json:"chat_id"`
|
||||
ConversationID string `json:"conversation_id"`
|
||||
BotID string `json:"bot_id"`
|
||||
Role string `json:"role"`
|
||||
Type string `json:"type"`
|
||||
Content string `json:"content"`
|
||||
ContentType string `json:"content_type"`
|
||||
SectionID string `json:"section_id"`
|
||||
}
|
||||
|
||||
type ErrorDetail struct {
|
||||
Code string `form:"code,required" json:"code,required"`
|
||||
Msg string `form:"msg,required" json:"msg,required"`
|
||||
DebugUrl string `form:"debug_url" json:"debug_url,omitempty"`
|
||||
}
|
||||
|
||||
type SuggestInfo struct {
|
||||
UserInput *schema.Message `json:"user_input,omitempty"`
|
||||
AnswerInput *schema.Message `json:"answer,omitempty"`
|
||||
PersonaInput *string `json:"persona_input,omitempty"`
|
||||
}
|
||||
74
backend/domain/workflow/entity/vo/conversation.go
Normal file
74
backend/domain/workflow/entity/vo/conversation.go
Normal file
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* 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 vo
|
||||
|
||||
type Env string
|
||||
|
||||
const (
|
||||
Draft Env = "draft"
|
||||
Online Env = "online"
|
||||
)
|
||||
|
||||
type CreateConversationTemplateMeta struct {
|
||||
UserID int64
|
||||
AppID int64
|
||||
SpaceID int64
|
||||
Name string
|
||||
}
|
||||
|
||||
type GetConversationTemplatePolicy struct {
|
||||
AppID *int64
|
||||
Name *string
|
||||
Version *string
|
||||
TemplateID *int64
|
||||
}
|
||||
|
||||
type ListConversationTemplatePolicy struct {
|
||||
AppID int64
|
||||
Page *Page
|
||||
NameLike *string
|
||||
Version *string
|
||||
}
|
||||
|
||||
type ListConversationMeta struct {
|
||||
APPID int64
|
||||
UserID int64
|
||||
ConnectorID int64
|
||||
}
|
||||
|
||||
type ListConversationPolicy struct {
|
||||
ListConversationMeta
|
||||
|
||||
Page *Page
|
||||
NameLike *string
|
||||
Version *string
|
||||
}
|
||||
|
||||
type CreateStaticConversation struct {
|
||||
AppID int64
|
||||
UserID int64
|
||||
ConnectorID int64
|
||||
|
||||
TemplateID int64
|
||||
}
|
||||
type CreateDynamicConversation struct {
|
||||
AppID int64
|
||||
UserID int64
|
||||
ConnectorID int64
|
||||
|
||||
Name string
|
||||
}
|
||||
@@ -68,6 +68,7 @@ type MetaUpdate struct {
|
||||
IconURI *string
|
||||
HasPublished *bool
|
||||
LatestPublishedVersion *string
|
||||
WorkflowMode *Mode
|
||||
}
|
||||
|
||||
type MetaQuery struct {
|
||||
@@ -80,4 +81,5 @@ type MetaQuery struct {
|
||||
LibOnly bool
|
||||
NeedTotalNumber bool
|
||||
DescByUpdate bool
|
||||
Mode *workflow.WorkflowMode
|
||||
}
|
||||
|
||||
@@ -21,4 +21,5 @@ type ReleaseWorkflowConfig struct {
|
||||
PluginIDs []int64
|
||||
|
||||
ConnectorIDs []int64
|
||||
WorkflowIDs []int64
|
||||
}
|
||||
|
||||
@@ -26,6 +26,7 @@ import (
|
||||
"github.com/coze-dev/coze-studio/backend/domain/workflow/entity"
|
||||
"github.com/coze-dev/coze-studio/backend/domain/workflow/entity/vo"
|
||||
"github.com/coze-dev/coze-studio/backend/infra/contract/idgen"
|
||||
"github.com/coze-dev/coze-studio/backend/infra/contract/storage"
|
||||
)
|
||||
|
||||
//go:generate mockgen -destination ../../internal/mock/domain/workflow/interface.go --package mockWorkflow -source interface.go
|
||||
@@ -39,12 +40,15 @@ type Service interface {
|
||||
Publish(ctx context.Context, policy *vo.PublishPolicy) (err error)
|
||||
UpdateMeta(ctx context.Context, id int64, metaUpdate *vo.MetaUpdate) (err error)
|
||||
CopyWorkflow(ctx context.Context, workflowID int64, policy vo.CopyWorkflowPolicy) (*entity.Workflow, error)
|
||||
WorkflowSchemaCheck(ctx context.Context, wf *entity.Workflow, checks []workflow.CheckType) ([]*workflow.CheckResult, error)
|
||||
|
||||
QueryNodeProperties(ctx context.Context, id int64) (map[string]*vo.NodeProperty, error) // only draft
|
||||
ValidateTree(ctx context.Context, id int64, validateConfig vo.ValidateTreeConfig) ([]*workflow.ValidateTreeInfo, error)
|
||||
|
||||
GetWorkflowReference(ctx context.Context, id int64) (map[int64]*vo.Meta, error)
|
||||
|
||||
GetWorkflowVersionsByConnector(ctx context.Context, connectorID, workflowID int64, limit int) ([]string, error)
|
||||
|
||||
Executable
|
||||
AsTool
|
||||
|
||||
@@ -53,17 +57,29 @@ type Service interface {
|
||||
DuplicateWorkflowsByAppID(ctx context.Context, sourceAPPID, targetAppID int64, related vo.ExternalResourceRelated) ([]*entity.Workflow, error)
|
||||
GetWorkflowDependenceResource(ctx context.Context, workflowID int64) (*vo.DependenceResource, error)
|
||||
SyncRelatedWorkflowResources(ctx context.Context, appID int64, relatedWorkflows map[int64]entity.IDVersionPair, related vo.ExternalResourceRelated) error
|
||||
|
||||
ChatFlowRole
|
||||
Conversation
|
||||
|
||||
BindConvRelatedInfo(ctx context.Context, convID int64, info entity.ConvRelatedInfo) error
|
||||
GetConvRelatedInfo(ctx context.Context, convID int64) (*entity.ConvRelatedInfo, bool, func() error, error)
|
||||
Suggest(ctx context.Context, input *vo.SuggestInfo) ([]string, error)
|
||||
}
|
||||
|
||||
type Repository interface {
|
||||
CreateMeta(ctx context.Context, meta *vo.Meta) (int64, error)
|
||||
CreateVersion(ctx context.Context, id int64, info *vo.VersionInfo, newRefs map[entity.WorkflowReferenceKey]struct{}) (err error)
|
||||
CreateOrUpdateDraft(ctx context.Context, id int64, draft *vo.DraftInfo) error
|
||||
CreateChatFlowRoleConfig(ctx context.Context, chatFlowRole *entity.ChatFlowRole) (int64, error)
|
||||
UpdateChatFlowRoleConfig(ctx context.Context, workflowID int64, chatFlowRole *vo.ChatFlowRoleUpdate) error
|
||||
GetChatFlowRoleConfig(ctx context.Context, workflowID int64, version string) (*entity.ChatFlowRole, error, bool)
|
||||
DeleteChatFlowRoleConfig(ctx context.Context, id int64, workflowID int64) error
|
||||
Delete(ctx context.Context, id int64) error
|
||||
MDelete(ctx context.Context, ids []int64) error
|
||||
GetMeta(ctx context.Context, id int64) (*vo.Meta, error)
|
||||
UpdateMeta(ctx context.Context, id int64, metaUpdate *vo.MetaUpdate) error
|
||||
GetVersion(ctx context.Context, id int64, version string) (*vo.VersionInfo, error)
|
||||
GetVersion(ctx context.Context, id int64, version string) (*vo.VersionInfo, bool, error)
|
||||
GetVersionListByConnectorAndWorkflowID(ctx context.Context, connectorID, workflowID int64, limit int) ([]string, error)
|
||||
|
||||
GetEntity(ctx context.Context, policy *vo.GetPolicy) (*entity.Workflow, error)
|
||||
|
||||
@@ -95,12 +111,15 @@ type Repository interface {
|
||||
|
||||
IsApplicationConnectorWorkflowVersion(ctx context.Context, connectorID, workflowID int64, version string) (b bool, err error)
|
||||
|
||||
GetObjectUrl(ctx context.Context, objectKey string, opts ...storage.GetOptFn) (string, error)
|
||||
|
||||
compose.CheckPointStore
|
||||
idgen.IDGenerator
|
||||
|
||||
GetKnowledgeRecallChatModel() model.BaseChatModel
|
||||
|
||||
ConversationRepository
|
||||
WorkflowConfig
|
||||
Suggester
|
||||
}
|
||||
|
||||
var repositorySingleton Repository
|
||||
|
||||
@@ -34,6 +34,7 @@ import (
|
||||
"github.com/coze-dev/coze-studio/backend/domain/workflow/internal/nodes"
|
||||
"github.com/coze-dev/coze-studio/backend/domain/workflow/internal/nodes/batch"
|
||||
"github.com/coze-dev/coze-studio/backend/domain/workflow/internal/nodes/code"
|
||||
"github.com/coze-dev/coze-studio/backend/domain/workflow/internal/nodes/conversation"
|
||||
"github.com/coze-dev/coze-studio/backend/domain/workflow/internal/nodes/database"
|
||||
"github.com/coze-dev/coze-studio/backend/domain/workflow/internal/nodes/emitter"
|
||||
"github.com/coze-dev/coze-studio/backend/domain/workflow/internal/nodes/entry"
|
||||
@@ -674,6 +675,36 @@ func RegisterAllNodeAdaptors() {
|
||||
nodes.RegisterNodeAdaptor(entity.NodeTypeLLM, func() nodes.NodeAdaptor {
|
||||
return &llm.Config{}
|
||||
})
|
||||
nodes.RegisterNodeAdaptor(entity.NodeTypeCreateConversation, func() nodes.NodeAdaptor {
|
||||
return &conversation.CreateConversationConfig{}
|
||||
})
|
||||
nodes.RegisterNodeAdaptor(entity.NodeTypeConversationUpdate, func() nodes.NodeAdaptor {
|
||||
return &conversation.UpdateConversationConfig{}
|
||||
})
|
||||
nodes.RegisterNodeAdaptor(entity.NodeTypeConversationDelete, func() nodes.NodeAdaptor {
|
||||
return &conversation.DeleteConversationConfig{}
|
||||
})
|
||||
nodes.RegisterNodeAdaptor(entity.NodeTypeConversationList, func() nodes.NodeAdaptor {
|
||||
return &conversation.ConversationListConfig{}
|
||||
})
|
||||
nodes.RegisterNodeAdaptor(entity.NodeTypeConversationHistory, func() nodes.NodeAdaptor {
|
||||
return &conversation.ConversationHistoryConfig{}
|
||||
})
|
||||
nodes.RegisterNodeAdaptor(entity.NodeTypeClearConversationHistory, func() nodes.NodeAdaptor {
|
||||
return &conversation.ClearConversationHistoryConfig{}
|
||||
})
|
||||
nodes.RegisterNodeAdaptor(entity.NodeTypeMessageList, func() nodes.NodeAdaptor {
|
||||
return &conversation.MessageListConfig{}
|
||||
})
|
||||
nodes.RegisterNodeAdaptor(entity.NodeTypeCreateMessage, func() nodes.NodeAdaptor {
|
||||
return &conversation.CreateMessageConfig{}
|
||||
})
|
||||
nodes.RegisterNodeAdaptor(entity.NodeTypeEditMessage, func() nodes.NodeAdaptor {
|
||||
return &conversation.EditMessageConfig{}
|
||||
})
|
||||
nodes.RegisterNodeAdaptor(entity.NodeTypeDeleteMessage, func() nodes.NodeAdaptor {
|
||||
return &conversation.DeleteMessageConfig{}
|
||||
})
|
||||
|
||||
// register branch adaptors
|
||||
nodes.RegisterBranchAdaptor(entity.NodeTypeSelector, func() nodes.BranchAdaptor {
|
||||
|
||||
@@ -0,0 +1,93 @@
|
||||
{
|
||||
"nodes": [
|
||||
{
|
||||
"id": "100001",
|
||||
"type": "1",
|
||||
"meta": {
|
||||
"position": {
|
||||
"x": 13.818572856225469,
|
||||
"y": -37.20384999753011
|
||||
}
|
||||
},
|
||||
"data": {
|
||||
"nodeMeta": {
|
||||
"title": "开始",
|
||||
"description": "工作流的起始节点,用于设定启动工作流需要的信息",
|
||||
"icon": "https://lf3-static.bytednsdoc.com/obj/eden-cn/dvsmryvd_avi_dvsm/ljhwZthlaukjlkulzlp/icon/icon-Start-v2.jpg",
|
||||
"subTitle": ""
|
||||
},
|
||||
"settings": null,
|
||||
"version": "",
|
||||
"outputs": [
|
||||
{
|
||||
"type": "string",
|
||||
"name": "USER_INPUT",
|
||||
"required": false
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"name": "CONVERSATION_NAME",
|
||||
"required": false,
|
||||
"description": "本次请求绑定的会话,会自动写入消息、会从该会话读对话历史。",
|
||||
"defaultValue": "Default"
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"name": "input",
|
||||
"required": false
|
||||
}
|
||||
],
|
||||
"trigger_parameters": []
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "900001",
|
||||
"type": "2",
|
||||
"meta": {
|
||||
"position": {
|
||||
"x": 642.9671427865745,
|
||||
"y": -37.20384999753011
|
||||
}
|
||||
},
|
||||
"data": {
|
||||
"nodeMeta": {
|
||||
"description": "工作流的最终节点,用于返回工作流运行后的结果信息",
|
||||
"icon": "https://lf3-static.bytednsdoc.com/obj/eden-cn/dvsmryvd_avi_dvsm/ljhwZthlaukjlkulzlp/icon/icon-End-v2.jpg",
|
||||
"subTitle": "",
|
||||
"title": "结束"
|
||||
},
|
||||
"inputs": {
|
||||
"terminatePlan": "returnVariables",
|
||||
"inputParameters": [
|
||||
{
|
||||
"name": "output",
|
||||
"input": {
|
||||
"type": "string",
|
||||
"value": {
|
||||
"type": "ref",
|
||||
"content": {
|
||||
"source": "block-output",
|
||||
"blockID": "100001",
|
||||
"name": "input"
|
||||
},
|
||||
"rawMeta": {
|
||||
"type": 1
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"edges": [
|
||||
{
|
||||
"sourceNodeID": "100001",
|
||||
"targetNodeID": "900001"
|
||||
}
|
||||
],
|
||||
"versions": {
|
||||
"loop": "v2"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
{
|
||||
"nodes": [{
|
||||
"blocks": [],
|
||||
"data": {
|
||||
"nodeMeta": {
|
||||
"description": "工作流的起始节点,用于设定启动工作流需要的信息",
|
||||
"icon": "https://lf3-static.bytednsdoc.com/obj/eden-cn/dvsmryvd_avi_dvsm/ljhwZthlaukjlkulzlp/icon/icon-Start-v2.jpg",
|
||||
"subTitle": "",
|
||||
"title": "开始"
|
||||
},
|
||||
"outputs": [{
|
||||
"name": "USER_INPUT",
|
||||
"required": false,
|
||||
"type": "string"
|
||||
}, {
|
||||
"defaultValue": "Default",
|
||||
"description": "本次请求绑定的会话,会自动写入消息、会从该会话读对话历史。",
|
||||
"name": "CONVERSATION_NAME",
|
||||
"required": false,
|
||||
"type": "string"
|
||||
}],
|
||||
"trigger_parameters": []
|
||||
},
|
||||
"edges": null,
|
||||
"id": "100001",
|
||||
"meta": {
|
||||
"position": {
|
||||
"x": 0,
|
||||
"y": 0
|
||||
}
|
||||
},
|
||||
"type": "1"
|
||||
}, {
|
||||
"blocks": [],
|
||||
"data": {
|
||||
"inputs": {
|
||||
"content": {
|
||||
"type": "string",
|
||||
"value": {
|
||||
"content": "{{output}}",
|
||||
"type": "literal"
|
||||
}
|
||||
},
|
||||
"inputParameters": [{
|
||||
"input": {
|
||||
"type": "string",
|
||||
"value": {
|
||||
"content": {
|
||||
"blockID": "100001",
|
||||
"name": "USER_INPUT",
|
||||
"source": "block-output"
|
||||
},
|
||||
"rawMeta": {
|
||||
"type": 1
|
||||
},
|
||||
"type": "ref"
|
||||
}
|
||||
},
|
||||
"name": "output"
|
||||
}],
|
||||
"streamingOutput": true,
|
||||
"terminatePlan": "useAnswerContent"
|
||||
},
|
||||
"nodeMeta": {
|
||||
"description": "工作流的最终节点,用于返回工作流运行后的结果信息",
|
||||
"icon": "https://lf3-static.bytednsdoc.com/obj/eden-cn/dvsmryvd_avi_dvsm/ljhwZthlaukjlkulzlp/icon/icon-End-v2.jpg",
|
||||
"subTitle": "",
|
||||
"title": "结束"
|
||||
}
|
||||
},
|
||||
"edges": null,
|
||||
"id": "900001",
|
||||
"meta": {
|
||||
"position": {
|
||||
"x": 1000,
|
||||
"y": 0
|
||||
}
|
||||
},
|
||||
"type": "2"
|
||||
}],
|
||||
"edges": [{
|
||||
"sourceNodeID": "100001",
|
||||
"targetNodeID": "900001",
|
||||
"sourcePortID": ""
|
||||
}],
|
||||
"versions": {
|
||||
"loop": "v2"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,193 @@
|
||||
{
|
||||
"nodes": [{
|
||||
"blocks": [],
|
||||
"data": {
|
||||
"nodeMeta": {
|
||||
"description": "工作流的起始节点,用于设定启动工作流需要的信息",
|
||||
"icon": "https://lf3-static.bytednsdoc.com/obj/eden-cn/dvsmryvd_avi_dvsm/ljhwZthlaukjlkulzlp/icon/icon-Start-v2.jpg",
|
||||
"subTitle": "",
|
||||
"title": "开始"
|
||||
},
|
||||
"outputs": [{
|
||||
"name": "USER_INPUT",
|
||||
"required": false,
|
||||
"type": "string"
|
||||
}, {
|
||||
"defaultValue": "Default",
|
||||
"description": "本次请求绑定的会话,会自动写入消息、会从该会话读对话历史。",
|
||||
"name": "CONVERSATION_NAME",
|
||||
"required": false,
|
||||
"type": "string"
|
||||
}],
|
||||
"trigger_parameters": []
|
||||
},
|
||||
"edges": null,
|
||||
"id": "100001",
|
||||
"meta": {
|
||||
"position": {
|
||||
"x": 0,
|
||||
"y": 0
|
||||
}
|
||||
},
|
||||
"type": "1"
|
||||
}, {
|
||||
"blocks": [],
|
||||
"data": {
|
||||
"inputs": {
|
||||
"content": {
|
||||
"type": "string",
|
||||
"value": {
|
||||
"content": "{{output}}",
|
||||
"type": "literal"
|
||||
}
|
||||
},
|
||||
"inputParameters": [{
|
||||
"input": {
|
||||
"schema": {
|
||||
"schema": [{
|
||||
"name": "conversationName",
|
||||
"type": "string"
|
||||
}, {
|
||||
"name": "conversationId",
|
||||
"type": "string"
|
||||
}],
|
||||
"type": "object"
|
||||
},
|
||||
"type": "list",
|
||||
"value": {
|
||||
"content": {
|
||||
"blockID": "107363",
|
||||
"name": "conversationList",
|
||||
"source": "block-output"
|
||||
},
|
||||
"rawMeta": {
|
||||
"type": 103
|
||||
},
|
||||
"type": "ref"
|
||||
}
|
||||
},
|
||||
"name": "output"
|
||||
}],
|
||||
"streamingOutput": true,
|
||||
"terminatePlan": "useAnswerContent"
|
||||
},
|
||||
"nodeMeta": {
|
||||
"description": "工作流的最终节点,用于返回工作流运行后的结果信息",
|
||||
"icon": "https://lf3-static.bytednsdoc.com/obj/eden-cn/dvsmryvd_avi_dvsm/ljhwZthlaukjlkulzlp/icon/icon-End-v2.jpg",
|
||||
"subTitle": "",
|
||||
"title": "结束"
|
||||
}
|
||||
},
|
||||
"edges": null,
|
||||
"id": "900001",
|
||||
"meta": {
|
||||
"position": {
|
||||
"x": 1058,
|
||||
"y": -13
|
||||
}
|
||||
},
|
||||
"type": "2"
|
||||
}, {
|
||||
"blocks": [],
|
||||
"data": {
|
||||
"inputs": {
|
||||
"inputParameters": []
|
||||
},
|
||||
"nodeMeta": {
|
||||
"description": "用于查询所有会话,包含静态会话、动态会话",
|
||||
"icon": "https://lf3-static.bytednsdoc.com/obj/eden-cn/dvsmryvd_avi_dvsm/ljhwZthlaukjlkulzlp/icon/icon-查询会话.jpg",
|
||||
"mainColor": "#F2B600",
|
||||
"subTitle": "查询会话列表",
|
||||
"title": "查询会话列表"
|
||||
},
|
||||
"outputs": [{
|
||||
"name": "conversationList",
|
||||
"schema": {
|
||||
"schema": [{
|
||||
"name": "conversationName",
|
||||
"type": "string"
|
||||
}, {
|
||||
"name": "conversationId",
|
||||
"type": "string"
|
||||
}],
|
||||
"type": "object"
|
||||
},
|
||||
"type": "list"
|
||||
}]
|
||||
},
|
||||
"edges": null,
|
||||
"id": "107363",
|
||||
"meta": {
|
||||
"position": {
|
||||
"x": 561,
|
||||
"y": 186
|
||||
}
|
||||
},
|
||||
"type": "53"
|
||||
}, {
|
||||
"blocks": [],
|
||||
"data": {
|
||||
"inputs": {
|
||||
"inputParameters": [{
|
||||
"input": {
|
||||
"type": "string",
|
||||
"value": {
|
||||
"content": {
|
||||
"blockID": "100001",
|
||||
"name": "CONVERSATION_NAME",
|
||||
"source": "block-output"
|
||||
},
|
||||
"rawMeta": {
|
||||
"type": 1
|
||||
},
|
||||
"type": "ref"
|
||||
}
|
||||
},
|
||||
"name": "conversationName"
|
||||
}]
|
||||
},
|
||||
"nodeMeta": {
|
||||
"description": "用于创建会话",
|
||||
"icon": "https://lf3-static.bytednsdoc.com/obj/eden-cn/dvsmryvd_avi_dvsm/ljhwZthlaukjlkulzlp/icon/icon-Conversation-Create.jpeg",
|
||||
"mainColor": "#F2B600",
|
||||
"subTitle": "创建会话",
|
||||
"title": "创建会话"
|
||||
},
|
||||
"outputs": [{
|
||||
"name": "isSuccess",
|
||||
"type": "boolean"
|
||||
}, {
|
||||
"name": "isExisted",
|
||||
"type": "boolean"
|
||||
}, {
|
||||
"name": "conversationId",
|
||||
"type": "string"
|
||||
}]
|
||||
},
|
||||
"edges": null,
|
||||
"id": "110245",
|
||||
"meta": {
|
||||
"position": {
|
||||
"x": 487,
|
||||
"y": -196
|
||||
}
|
||||
},
|
||||
"type": "39"
|
||||
}],
|
||||
"edges": [{
|
||||
"sourceNodeID": "100001",
|
||||
"targetNodeID": "110245",
|
||||
"sourcePortID": ""
|
||||
}, {
|
||||
"sourceNodeID": "107363",
|
||||
"targetNodeID": "900001",
|
||||
"sourcePortID": ""
|
||||
}, {
|
||||
"sourceNodeID": "110245",
|
||||
"targetNodeID": "107363",
|
||||
"sourcePortID": ""
|
||||
}],
|
||||
"versions": {
|
||||
"loop": "v2"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,137 @@
|
||||
{
|
||||
"nodes": [
|
||||
{
|
||||
"id": "100001",
|
||||
"type": "1",
|
||||
"meta": {
|
||||
"position": {
|
||||
"x": 180,
|
||||
"y": 13.700000000000003
|
||||
}
|
||||
},
|
||||
"data": {
|
||||
"nodeMeta": {
|
||||
"description": "工作流的起始节点,用于设定启动工作流需要的信息",
|
||||
"icon": "https://lf3-static.bytednsdoc.com/obj/eden-cn/dvsmryvd_avi_dvsm/ljhwZthlaukjlkulzlp/icon/icon-Start-v2.jpg",
|
||||
"subTitle": "",
|
||||
"title": "开始"
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
"type": "string",
|
||||
"name": "input",
|
||||
"required": false
|
||||
}
|
||||
],
|
||||
"trigger_parameters": []
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "900001",
|
||||
"type": "2",
|
||||
"meta": {
|
||||
"position": {
|
||||
"x": 1100,
|
||||
"y": 0.7000000000000028
|
||||
}
|
||||
},
|
||||
"data": {
|
||||
"nodeMeta": {
|
||||
"description": "工作流的最终节点,用于返回工作流运行后的结果信息",
|
||||
"icon": "https://lf3-static.bytednsdoc.com/obj/eden-cn/dvsmryvd_avi_dvsm/ljhwZthlaukjlkulzlp/icon/icon-End-v2.jpg",
|
||||
"subTitle": "",
|
||||
"title": "结束"
|
||||
},
|
||||
"inputs": {
|
||||
"terminatePlan": "returnVariables",
|
||||
"inputParameters": [
|
||||
{
|
||||
"name": "output",
|
||||
"input": {
|
||||
"type": "string",
|
||||
"value": {
|
||||
"type": "ref",
|
||||
"content": {
|
||||
"source": "block-output",
|
||||
"blockID": "163698",
|
||||
"name": "conversationId"
|
||||
},
|
||||
"rawMeta": {
|
||||
"type": 1
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "163698",
|
||||
"type": "39",
|
||||
"meta": {
|
||||
"position": {
|
||||
"x": 640,
|
||||
"y": 0
|
||||
}
|
||||
},
|
||||
"data": {
|
||||
"outputs": [
|
||||
{
|
||||
"type": "boolean",
|
||||
"name": "isSuccess"
|
||||
},
|
||||
{
|
||||
"type": "boolean",
|
||||
"name": "isExisted"
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"name": "conversationId"
|
||||
}
|
||||
],
|
||||
"nodeMeta": {
|
||||
"title": "创建会话",
|
||||
"icon": "https://lf3-static.bytednsdoc.com/obj/eden-cn/dvsmryvd_avi_dvsm/ljhwZthlaukjlkulzlp/icon/icon-Conversation-Create.jpeg",
|
||||
"description": "用于创建会话",
|
||||
"mainColor": "#F2B600",
|
||||
"subTitle": "创建会话"
|
||||
},
|
||||
"inputs": {
|
||||
"inputParameters": [
|
||||
{
|
||||
"name": "conversationName",
|
||||
"input": {
|
||||
"type": "string",
|
||||
"value": {
|
||||
"type": "ref",
|
||||
"content": {
|
||||
"source": "block-output",
|
||||
"blockID": "100001",
|
||||
"name": "input"
|
||||
},
|
||||
"rawMeta": {
|
||||
"type": 1
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"edges": [
|
||||
{
|
||||
"sourceNodeID": "100001",
|
||||
"targetNodeID": "163698"
|
||||
},
|
||||
{
|
||||
"sourceNodeID": "163698",
|
||||
"targetNodeID": "900001"
|
||||
}
|
||||
],
|
||||
"versions": {
|
||||
"loop": "v2"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,129 @@
|
||||
{
|
||||
"nodes": [
|
||||
{
|
||||
"id": "100001",
|
||||
"type": "1",
|
||||
"meta": {
|
||||
"position": {
|
||||
"x": -13.523809523809522,
|
||||
"y": -25.294372294372295
|
||||
}
|
||||
},
|
||||
"data": {
|
||||
"nodeMeta": {
|
||||
"description": "工作流的起始节点,用于设定启动工作流需要的信息",
|
||||
"icon": "https://lf3-static.bytednsdoc.com/obj/eden-cn/dvsmryvd_avi_dvsm/ljhwZthlaukjlkulzlp/icon/icon-Start-v2.jpg",
|
||||
"subTitle": "",
|
||||
"title": "开始"
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
"type": "string",
|
||||
"name": "input",
|
||||
"required": false
|
||||
}
|
||||
],
|
||||
"trigger_parameters": []
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "900001",
|
||||
"type": "2",
|
||||
"meta": {
|
||||
"position": {
|
||||
"x": 890.3549783549786,
|
||||
"y": -71.48917748917748
|
||||
}
|
||||
},
|
||||
"data": {
|
||||
"nodeMeta": {
|
||||
"description": "工作流的最终节点,用于返回工作流运行后的结果信息",
|
||||
"icon": "https://lf3-static.bytednsdoc.com/obj/eden-cn/dvsmryvd_avi_dvsm/ljhwZthlaukjlkulzlp/icon/icon-End-v2.jpg",
|
||||
"subTitle": "",
|
||||
"title": "结束"
|
||||
},
|
||||
"inputs": {
|
||||
"terminatePlan": "returnVariables",
|
||||
"inputParameters": [
|
||||
{
|
||||
"name": "output",
|
||||
"input": {
|
||||
"type": "boolean",
|
||||
"value": {
|
||||
"type": "ref",
|
||||
"content": {
|
||||
"source": "block-output",
|
||||
"blockID": "118024",
|
||||
"name": "isSuccess"
|
||||
},
|
||||
"rawMeta": {
|
||||
"type": 3
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "118024",
|
||||
"type": "52",
|
||||
"meta": {
|
||||
"position": {
|
||||
"x": 423.6623376623378,
|
||||
"y": -126.39999999999999
|
||||
}
|
||||
},
|
||||
"data": {
|
||||
"outputs": [
|
||||
{
|
||||
"type": "boolean",
|
||||
"name": "isSuccess"
|
||||
}
|
||||
],
|
||||
"nodeMeta": {
|
||||
"title": "删除会话",
|
||||
"icon": "https://lf3-static.bytednsdoc.com/obj/eden-cn/dvsmryvd_avi_dvsm/ljhwZthlaukjlkulzlp/icon/icon-删除会话.jpg",
|
||||
"description": "用于删除会话",
|
||||
"mainColor": "#F2B600",
|
||||
"subTitle": "删除会话"
|
||||
},
|
||||
"inputs": {
|
||||
"inputParameters": [
|
||||
{
|
||||
"name": "conversationName",
|
||||
"input": {
|
||||
"type": "string",
|
||||
"value": {
|
||||
"type": "ref",
|
||||
"content": {
|
||||
"source": "block-output",
|
||||
"blockID": "100001",
|
||||
"name": "input"
|
||||
},
|
||||
"rawMeta": {
|
||||
"type": 1
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"edges": [
|
||||
{
|
||||
"sourceNodeID": "100001",
|
||||
"targetNodeID": "118024"
|
||||
},
|
||||
{
|
||||
"sourceNodeID": "118024",
|
||||
"targetNodeID": "900001"
|
||||
}
|
||||
],
|
||||
"versions": {
|
||||
"loop": "v2"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,191 @@
|
||||
{
|
||||
"nodes": [
|
||||
{
|
||||
"id": "100001",
|
||||
"type": "1",
|
||||
"meta": {
|
||||
"position": {
|
||||
"x": -243.67931247880136,
|
||||
"y": -233.598184501318
|
||||
}
|
||||
},
|
||||
"data": {
|
||||
"nodeMeta": {
|
||||
"description": "工作流的起始节点,用于设定启动工作流需要的信息",
|
||||
"icon": "https://lf3-static.bytednsdoc.com/obj/eden-cn/dvsmryvd_avi_dvsm/ljhwZthlaukjlkulzlp/icon/icon-Start-v2.jpg",
|
||||
"subTitle": "",
|
||||
"title": "开始"
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
"type": "string",
|
||||
"name": "input",
|
||||
"required": false
|
||||
}
|
||||
],
|
||||
"trigger_parameters": []
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "900001",
|
||||
"type": "2",
|
||||
"meta": {
|
||||
"position": {
|
||||
"x": 911.2952705396514,
|
||||
"y": -331.2250749763467
|
||||
}
|
||||
},
|
||||
"data": {
|
||||
"nodeMeta": {
|
||||
"description": "工作流的最终节点,用于返回工作流运行后的结果信息",
|
||||
"icon": "https://lf3-static.bytednsdoc.com/obj/eden-cn/dvsmryvd_avi_dvsm/ljhwZthlaukjlkulzlp/icon/icon-End-v2.jpg",
|
||||
"subTitle": "",
|
||||
"title": "结束"
|
||||
},
|
||||
"inputs": {
|
||||
"terminatePlan": "returnVariables",
|
||||
"inputParameters": [
|
||||
{
|
||||
"name": "output",
|
||||
"input": {
|
||||
"value": {
|
||||
"type": "object_ref"
|
||||
},
|
||||
"type": "object",
|
||||
"schema": [
|
||||
{
|
||||
"name": "isSuccess",
|
||||
"input": {
|
||||
"type": "boolean",
|
||||
"value": {
|
||||
"type": "ref",
|
||||
"content": {
|
||||
"source": "block-output",
|
||||
"blockID": "122336",
|
||||
"name": "isSuccess"
|
||||
},
|
||||
"rawMeta": {
|
||||
"type": 3
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "isExisted",
|
||||
"input": {
|
||||
"type": "boolean",
|
||||
"value": {
|
||||
"type": "ref",
|
||||
"content": {
|
||||
"source": "block-output",
|
||||
"blockID": "122336",
|
||||
"name": "isExisted"
|
||||
},
|
||||
"rawMeta": {
|
||||
"type": 3
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "conversationId",
|
||||
"input": {
|
||||
"type": "string",
|
||||
"value": {
|
||||
"type": "ref",
|
||||
"content": {
|
||||
"source": "block-output",
|
||||
"blockID": "122336",
|
||||
"name": "conversationId"
|
||||
},
|
||||
"rawMeta": {
|
||||
"type": 1
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "122336",
|
||||
"type": "51",
|
||||
"meta": {
|
||||
"position": {
|
||||
"x": 343.08704991877585,
|
||||
"y": -462.38794621339696
|
||||
}
|
||||
},
|
||||
"data": {
|
||||
"outputs": [
|
||||
{
|
||||
"type": "boolean",
|
||||
"name": "isSuccess"
|
||||
},
|
||||
{
|
||||
"type": "boolean",
|
||||
"name": "isExisted"
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"name": "conversationId"
|
||||
}
|
||||
],
|
||||
"nodeMeta": {
|
||||
"title": "修改会话",
|
||||
"icon": "https://lf3-static.bytednsdoc.com/obj/eden-cn/dvsmryvd_avi_dvsm/ljhwZthlaukjlkulzlp/icon/icon-编辑会话.jpg",
|
||||
"description": "用于修改会话的名字",
|
||||
"mainColor": "#F2B600",
|
||||
"subTitle": "修改会话"
|
||||
},
|
||||
"inputs": {
|
||||
"inputParameters": [
|
||||
{
|
||||
"name": "conversationName",
|
||||
"input": {
|
||||
"type": "string",
|
||||
"value": {
|
||||
"type": "literal",
|
||||
"content": "template_v1",
|
||||
"rawMeta": {
|
||||
"type": 1
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "newConversationName",
|
||||
"input": {
|
||||
"type": "string",
|
||||
"value": {
|
||||
"type": "literal",
|
||||
"content": "new",
|
||||
"rawMeta": {
|
||||
"type": 1
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"edges": [
|
||||
{
|
||||
"sourceNodeID": "100001",
|
||||
"targetNodeID": "122336"
|
||||
},
|
||||
{
|
||||
"sourceNodeID": "122336",
|
||||
"targetNodeID": "900001"
|
||||
}
|
||||
],
|
||||
"versions": {
|
||||
"loop": "v2"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,262 @@
|
||||
{
|
||||
"nodes": [
|
||||
{
|
||||
"id": "100001",
|
||||
"type": "1",
|
||||
"meta": {
|
||||
"position": {
|
||||
"x": 180,
|
||||
"y": 13.700000000000003
|
||||
}
|
||||
},
|
||||
"data": {
|
||||
"nodeMeta": {
|
||||
"description": "工作流的起始节点,用于设定启动工作流需要的信息",
|
||||
"icon": "https://lf3-static.bytednsdoc.com/obj/eden-cn/dvsmryvd_avi_dvsm/ljhwZthlaukjlkulzlp/icon/icon-Start-v2.jpg",
|
||||
"subTitle": "",
|
||||
"title": "开始"
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
"type": "string",
|
||||
"name": "input",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"name": "new_name",
|
||||
"required": true
|
||||
}
|
||||
],
|
||||
"trigger_parameters": []
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "900001",
|
||||
"type": "2",
|
||||
"meta": {
|
||||
"position": {
|
||||
"x": 1560,
|
||||
"y": 0.7000000000000028
|
||||
}
|
||||
},
|
||||
"data": {
|
||||
"nodeMeta": {
|
||||
"description": "工作流的最终节点,用于返回工作流运行后的结果信息",
|
||||
"icon": "https://lf3-static.bytednsdoc.com/obj/eden-cn/dvsmryvd_avi_dvsm/ljhwZthlaukjlkulzlp/icon/icon-End-v2.jpg",
|
||||
"subTitle": "",
|
||||
"title": "结束"
|
||||
},
|
||||
"inputs": {
|
||||
"terminatePlan": "returnVariables",
|
||||
"inputParameters": [
|
||||
{
|
||||
"name": "obj",
|
||||
"input": {
|
||||
"value": {
|
||||
"type": "object_ref"
|
||||
},
|
||||
"type": "object",
|
||||
"schema": [
|
||||
{
|
||||
"name": "isSuccess",
|
||||
"input": {
|
||||
"type": "boolean",
|
||||
"value": {
|
||||
"type": "ref",
|
||||
"content": {
|
||||
"source": "block-output",
|
||||
"blockID": "193175",
|
||||
"name": "isSuccess"
|
||||
},
|
||||
"rawMeta": {
|
||||
"type": 3
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "isExisted",
|
||||
"input": {
|
||||
"type": "boolean",
|
||||
"value": {
|
||||
"type": "ref",
|
||||
"content": {
|
||||
"source": "block-output",
|
||||
"blockID": "193175",
|
||||
"name": "isExisted"
|
||||
},
|
||||
"rawMeta": {
|
||||
"type": 3
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "conversationId",
|
||||
"input": {
|
||||
"type": "string",
|
||||
"value": {
|
||||
"type": "ref",
|
||||
"content": {
|
||||
"source": "block-output",
|
||||
"blockID": "193175",
|
||||
"name": "conversationId"
|
||||
},
|
||||
"rawMeta": {
|
||||
"type": 1
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "139551",
|
||||
"type": "39",
|
||||
"meta": {
|
||||
"position": {
|
||||
"x": 627.929589270746,
|
||||
"y": -36.21123218776195
|
||||
}
|
||||
},
|
||||
"data": {
|
||||
"outputs": [
|
||||
{
|
||||
"type": "boolean",
|
||||
"name": "isSuccess"
|
||||
},
|
||||
{
|
||||
"type": "boolean",
|
||||
"name": "isExisted"
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"name": "conversationId"
|
||||
}
|
||||
],
|
||||
"nodeMeta": {
|
||||
"title": "创建会话",
|
||||
"icon": "https://lf3-static.bytednsdoc.com/obj/eden-cn/dvsmryvd_avi_dvsm/ljhwZthlaukjlkulzlp/icon/icon-Conversation-Create.jpeg",
|
||||
"description": "用于创建会话",
|
||||
"mainColor": "#F2B600",
|
||||
"subTitle": "创建会话"
|
||||
},
|
||||
"inputs": {
|
||||
"inputParameters": [
|
||||
{
|
||||
"name": "conversationName",
|
||||
"input": {
|
||||
"type": "string",
|
||||
"value": {
|
||||
"type": "ref",
|
||||
"content": {
|
||||
"source": "block-output",
|
||||
"blockID": "100001",
|
||||
"name": "input"
|
||||
},
|
||||
"rawMeta": {
|
||||
"type": 1
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "193175",
|
||||
"type": "51",
|
||||
"meta": {
|
||||
"position": {
|
||||
"x": 1100,
|
||||
"y": 0
|
||||
}
|
||||
},
|
||||
"data": {
|
||||
"outputs": [
|
||||
{
|
||||
"type": "boolean",
|
||||
"name": "isSuccess"
|
||||
},
|
||||
{
|
||||
"type": "boolean",
|
||||
"name": "isExisted"
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"name": "conversationId"
|
||||
}
|
||||
],
|
||||
"nodeMeta": {
|
||||
"title": "修改会话",
|
||||
"icon": "https://lf3-static.bytednsdoc.com/obj/eden-cn/dvsmryvd_avi_dvsm/ljhwZthlaukjlkulzlp/icon/icon-编辑会话.jpg",
|
||||
"description": "用于修改会话的名字",
|
||||
"mainColor": "#F2B600",
|
||||
"subTitle": "修改会话"
|
||||
},
|
||||
"inputs": {
|
||||
"inputParameters": [
|
||||
{
|
||||
"name": "conversationName",
|
||||
"input": {
|
||||
"type": "string",
|
||||
"value": {
|
||||
"type": "ref",
|
||||
"content": {
|
||||
"source": "block-output",
|
||||
"blockID": "100001",
|
||||
"name": "input"
|
||||
},
|
||||
"rawMeta": {
|
||||
"type": 1
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "newConversationName",
|
||||
"input": {
|
||||
"type": "string",
|
||||
"value": {
|
||||
"type": "ref",
|
||||
"content": {
|
||||
"source": "block-output",
|
||||
"blockID": "100001",
|
||||
"name": "new_name"
|
||||
},
|
||||
"rawMeta": {
|
||||
"type": 1
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"edges": [
|
||||
{
|
||||
"sourceNodeID": "100001",
|
||||
"targetNodeID": "139551"
|
||||
},
|
||||
{
|
||||
"sourceNodeID": "193175",
|
||||
"targetNodeID": "900001"
|
||||
},
|
||||
{
|
||||
"sourceNodeID": "139551",
|
||||
"targetNodeID": "193175"
|
||||
}
|
||||
],
|
||||
"versions": {
|
||||
"loop": "v2"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,234 @@
|
||||
{
|
||||
"nodes": [{
|
||||
"blocks": [],
|
||||
"data": {
|
||||
"nodeMeta": {
|
||||
"description": "工作流的起始节点,用于设定启动工作流需要的信息",
|
||||
"icon": "https://lf3-static.bytednsdoc.com/obj/eden-cn/dvsmryvd_avi_dvsm/ljhwZthlaukjlkulzlp/icon/icon-Start-v2.jpg",
|
||||
"subTitle": "",
|
||||
"title": "开始"
|
||||
},
|
||||
"outputs": [{
|
||||
"name": "USER_INPUT",
|
||||
"required": false,
|
||||
"type": "string"
|
||||
}, {
|
||||
"defaultValue": "Default",
|
||||
"description": "本次请求绑定的会话,会自动写入消息、会从该会话读对话历史。",
|
||||
"name": "CONVERSATION_NAME",
|
||||
"required": false,
|
||||
"type": "string"
|
||||
}],
|
||||
"trigger_parameters": []
|
||||
},
|
||||
"edges": null,
|
||||
"id": "100001",
|
||||
"meta": {
|
||||
"position": {
|
||||
"x": 0,
|
||||
"y": 0
|
||||
}
|
||||
},
|
||||
"type": "1"
|
||||
}, {
|
||||
"blocks": [],
|
||||
"data": {
|
||||
"inputs": {
|
||||
"inputParameters": [{
|
||||
"input": {
|
||||
"type": "boolean",
|
||||
"value": {
|
||||
"content": {
|
||||
"blockID": "195185",
|
||||
"name": "isSuccess",
|
||||
"source": "block-output"
|
||||
},
|
||||
"rawMeta": {
|
||||
"type": 3
|
||||
},
|
||||
"type": "ref"
|
||||
}
|
||||
},
|
||||
"name": "output"
|
||||
}, {
|
||||
"input": {
|
||||
"type": "string",
|
||||
"value": {
|
||||
"content": {
|
||||
"blockID": "195185",
|
||||
"name": "message.messageId",
|
||||
"source": "block-output"
|
||||
},
|
||||
"rawMeta": {
|
||||
"type": 1
|
||||
},
|
||||
"type": "ref"
|
||||
}
|
||||
},
|
||||
"name": "mID"
|
||||
}],
|
||||
"terminatePlan": "returnVariables"
|
||||
},
|
||||
"nodeMeta": {
|
||||
"description": "工作流的最终节点,用于返回工作流运行后的结果信息",
|
||||
"icon": "https://lf3-static.bytednsdoc.com/obj/eden-cn/dvsmryvd_avi_dvsm/ljhwZthlaukjlkulzlp/icon/icon-End-v2.jpg",
|
||||
"subTitle": "",
|
||||
"title": "结束"
|
||||
}
|
||||
},
|
||||
"edges": null,
|
||||
"id": "900001",
|
||||
"meta": {
|
||||
"position": {
|
||||
"x": 1000,
|
||||
"y": 0
|
||||
}
|
||||
},
|
||||
"type": "2"
|
||||
}, {
|
||||
"blocks": [],
|
||||
"data": {
|
||||
"inputs": {
|
||||
"inputParameters": [{
|
||||
"input": {
|
||||
"type": "string",
|
||||
"value": {
|
||||
"content": {
|
||||
"blockID": "100001",
|
||||
"name": "CONVERSATION_NAME",
|
||||
"source": "block-output"
|
||||
},
|
||||
"rawMeta": {
|
||||
"type": 1
|
||||
},
|
||||
"type": "ref"
|
||||
}
|
||||
},
|
||||
"name": "conversationName"
|
||||
}, {
|
||||
"input": {
|
||||
"type": "string",
|
||||
"value": {
|
||||
"content": "user",
|
||||
"type": "literal"
|
||||
}
|
||||
},
|
||||
"name": "role"
|
||||
}, {
|
||||
"input": {
|
||||
"type": "string",
|
||||
"value": {
|
||||
"content": "1",
|
||||
"rawMeta": {
|
||||
"type": 1
|
||||
},
|
||||
"type": "literal"
|
||||
}
|
||||
},
|
||||
"name": "content"
|
||||
}]
|
||||
},
|
||||
"nodeMeta": {
|
||||
"description": "用于创建消息",
|
||||
"icon": "https://lf3-static.bytednsdoc.com/obj/eden-cn/dvsmryvd_avi_dvsm/ljhwZthlaukjlkulzlp/icon/icon-创建消息.jpg",
|
||||
"mainColor": "#F2B600",
|
||||
"subTitle": "创建消息",
|
||||
"title": "创建消息"
|
||||
},
|
||||
"outputs": [{
|
||||
"name": "isSuccess",
|
||||
"type": "boolean"
|
||||
}, {
|
||||
"name": "message",
|
||||
"schema": [{
|
||||
"name": "messageId",
|
||||
"type": "string"
|
||||
}, {
|
||||
"name": "role",
|
||||
"type": "string"
|
||||
}, {
|
||||
"name": "contentType",
|
||||
"type": "string"
|
||||
}, {
|
||||
"name": "content",
|
||||
"type": "string"
|
||||
}],
|
||||
"type": "object"
|
||||
}]
|
||||
},
|
||||
"edges": null,
|
||||
"id": "195185",
|
||||
"meta": {
|
||||
"position": {
|
||||
"x": 482,
|
||||
"y": -13
|
||||
}
|
||||
},
|
||||
"type": "55"
|
||||
}, {
|
||||
"blocks": [],
|
||||
"data": {
|
||||
"inputs": {
|
||||
"inputParameters": [{
|
||||
"input": {
|
||||
"type": "string",
|
||||
"value": {
|
||||
"content": {
|
||||
"blockID": "100001",
|
||||
"name": "CONVERSATION_NAME",
|
||||
"source": "block-output"
|
||||
},
|
||||
"rawMeta": {
|
||||
"type": 1
|
||||
},
|
||||
"type": "ref"
|
||||
}
|
||||
},
|
||||
"name": "conversationName"
|
||||
}]
|
||||
},
|
||||
"nodeMeta": {
|
||||
"description": "用于创建会话",
|
||||
"icon": "https://lf3-static.bytednsdoc.com/obj/eden-cn/dvsmryvd_avi_dvsm/ljhwZthlaukjlkulzlp/icon/icon-Conversation-Create.jpeg",
|
||||
"mainColor": "#F2B600",
|
||||
"subTitle": "创建会话",
|
||||
"title": "创建会话"
|
||||
},
|
||||
"outputs": [{
|
||||
"name": "isSuccess",
|
||||
"type": "boolean"
|
||||
}, {
|
||||
"name": "isExisted",
|
||||
"type": "boolean"
|
||||
}, {
|
||||
"name": "conversationId",
|
||||
"type": "string"
|
||||
}]
|
||||
},
|
||||
"edges": null,
|
||||
"id": "121849",
|
||||
"meta": {
|
||||
"position": {
|
||||
"x": 302,
|
||||
"y": -236
|
||||
}
|
||||
},
|
||||
"type": "39"
|
||||
}],
|
||||
"edges": [{
|
||||
"sourceNodeID": "100001",
|
||||
"targetNodeID": "121849",
|
||||
"sourcePortID": ""
|
||||
}, {
|
||||
"sourceNodeID": "195185",
|
||||
"targetNodeID": "900001",
|
||||
"sourcePortID": ""
|
||||
}, {
|
||||
"sourceNodeID": "121849",
|
||||
"targetNodeID": "195185",
|
||||
"sourcePortID": ""
|
||||
}],
|
||||
"versions": {
|
||||
"loop": "v2"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,310 @@
|
||||
{
|
||||
"nodes": [{
|
||||
"blocks": [],
|
||||
"data": {
|
||||
"nodeMeta": {
|
||||
"description": "工作流的起始节点,用于设定启动工作流需要的信息",
|
||||
"icon": "https://lf3-static.bytednsdoc.com/obj/eden-cn/dvsmryvd_avi_dvsm/ljhwZthlaukjlkulzlp/icon/icon-Start-v2.jpg",
|
||||
"subTitle": "",
|
||||
"title": "开始"
|
||||
},
|
||||
"outputs": [{
|
||||
"name": "USER_INPUT",
|
||||
"required": false,
|
||||
"type": "string"
|
||||
}, {
|
||||
"defaultValue": "Default",
|
||||
"description": "本次请求绑定的会话,会自动写入消息、会从该会话读对话历史。",
|
||||
"name": "CONVERSATION_NAME",
|
||||
"required": false,
|
||||
"type": "string"
|
||||
}],
|
||||
"trigger_parameters": []
|
||||
},
|
||||
"edges": null,
|
||||
"id": "100001",
|
||||
"meta": {
|
||||
"position": {
|
||||
"x": 0,
|
||||
"y": 0
|
||||
}
|
||||
},
|
||||
"type": "1"
|
||||
}, {
|
||||
"blocks": [],
|
||||
"data": {
|
||||
"inputs": {
|
||||
"inputParameters": [{
|
||||
"input": {
|
||||
"schema": {
|
||||
"schema": [{
|
||||
"name": "messageId",
|
||||
"type": "string"
|
||||
}, {
|
||||
"name": "role",
|
||||
"type": "string"
|
||||
}, {
|
||||
"name": "contentType",
|
||||
"type": "string"
|
||||
}, {
|
||||
"name": "content",
|
||||
"type": "string"
|
||||
}],
|
||||
"type": "object"
|
||||
},
|
||||
"type": "list",
|
||||
"value": {
|
||||
"content": {
|
||||
"blockID": "132703",
|
||||
"name": "messageList",
|
||||
"source": "block-output"
|
||||
},
|
||||
"rawMeta": {
|
||||
"type": 103
|
||||
},
|
||||
"type": "ref"
|
||||
}
|
||||
},
|
||||
"name": "output"
|
||||
}],
|
||||
"terminatePlan": "returnVariables"
|
||||
},
|
||||
"nodeMeta": {
|
||||
"description": "工作流的最终节点,用于返回工作流运行后的结果信息",
|
||||
"icon": "https://lf3-static.bytednsdoc.com/obj/eden-cn/dvsmryvd_avi_dvsm/ljhwZthlaukjlkulzlp/icon/icon-End-v2.jpg",
|
||||
"subTitle": "",
|
||||
"title": "结束"
|
||||
}
|
||||
},
|
||||
"edges": null,
|
||||
"id": "900001",
|
||||
"meta": {
|
||||
"position": {
|
||||
"x": 1000,
|
||||
"y": 0
|
||||
}
|
||||
},
|
||||
"type": "2"
|
||||
}, {
|
||||
"blocks": [],
|
||||
"data": {
|
||||
"inputs": {
|
||||
"inputParameters": [{
|
||||
"input": {
|
||||
"type": "string",
|
||||
"value": {
|
||||
"content": {
|
||||
"blockID": "100001",
|
||||
"name": "CONVERSATION_NAME",
|
||||
"source": "block-output"
|
||||
},
|
||||
"rawMeta": {
|
||||
"type": 1
|
||||
},
|
||||
"type": "ref"
|
||||
}
|
||||
},
|
||||
"name": "conversationName"
|
||||
}]
|
||||
},
|
||||
"nodeMeta": {
|
||||
"description": "用于查询消息列表",
|
||||
"icon": "https://lf3-static.bytednsdoc.com/obj/eden-cn/dvsmryvd_avi_dvsm/ljhwZthlaukjlkulzlp/icon/icon-Conversation-List.jpeg",
|
||||
"mainColor": "#F2B600",
|
||||
"subTitle": "查询消息列表",
|
||||
"title": "查询消息列表"
|
||||
},
|
||||
"outputs": [{
|
||||
"name": "messageList",
|
||||
"schema": {
|
||||
"schema": [{
|
||||
"name": "messageId",
|
||||
"type": "string"
|
||||
}, {
|
||||
"name": "role",
|
||||
"type": "string"
|
||||
}, {
|
||||
"name": "contentType",
|
||||
"type": "string"
|
||||
}, {
|
||||
"name": "content",
|
||||
"type": "string"
|
||||
}],
|
||||
"type": "object"
|
||||
},
|
||||
"type": "list"
|
||||
}, {
|
||||
"name": "firstId",
|
||||
"type": "string"
|
||||
}, {
|
||||
"name": "lastId",
|
||||
"type": "string"
|
||||
}, {
|
||||
"name": "hasMore",
|
||||
"type": "boolean"
|
||||
}]
|
||||
},
|
||||
"edges": null,
|
||||
"id": "132703",
|
||||
"meta": {
|
||||
"position": {
|
||||
"x": 514,
|
||||
"y": 96
|
||||
}
|
||||
},
|
||||
"type": "37"
|
||||
}, {
|
||||
"blocks": [],
|
||||
"data": {
|
||||
"inputs": {
|
||||
"inputParameters": [{
|
||||
"input": {
|
||||
"type": "string",
|
||||
"value": {
|
||||
"content": {
|
||||
"blockID": "100001",
|
||||
"name": "CONVERSATION_NAME",
|
||||
"source": "block-output"
|
||||
},
|
||||
"rawMeta": {
|
||||
"type": 1
|
||||
},
|
||||
"type": "ref"
|
||||
}
|
||||
},
|
||||
"name": "conversationName"
|
||||
}]
|
||||
},
|
||||
"nodeMeta": {
|
||||
"description": "用于创建会话",
|
||||
"icon": "https://lf3-static.bytednsdoc.com/obj/eden-cn/dvsmryvd_avi_dvsm/ljhwZthlaukjlkulzlp/icon/icon-Conversation-Create.jpeg",
|
||||
"mainColor": "#F2B600",
|
||||
"subTitle": "创建会话",
|
||||
"title": "创建会话"
|
||||
},
|
||||
"outputs": [{
|
||||
"name": "isSuccess",
|
||||
"type": "boolean"
|
||||
}, {
|
||||
"name": "isExisted",
|
||||
"type": "boolean"
|
||||
}, {
|
||||
"name": "conversationId",
|
||||
"type": "string"
|
||||
}]
|
||||
},
|
||||
"edges": null,
|
||||
"id": "166724",
|
||||
"meta": {
|
||||
"position": {
|
||||
"x": 323,
|
||||
"y": -332
|
||||
}
|
||||
},
|
||||
"type": "39"
|
||||
}, {
|
||||
"blocks": [],
|
||||
"data": {
|
||||
"inputs": {
|
||||
"inputParameters": [{
|
||||
"input": {
|
||||
"type": "string",
|
||||
"value": {
|
||||
"content": {
|
||||
"blockID": "100001",
|
||||
"name": "CONVERSATION_NAME",
|
||||
"source": "block-output"
|
||||
},
|
||||
"rawMeta": {
|
||||
"type": 1
|
||||
},
|
||||
"type": "ref"
|
||||
}
|
||||
},
|
||||
"name": "conversationName"
|
||||
}, {
|
||||
"input": {
|
||||
"type": "string",
|
||||
"value": {
|
||||
"content": "user",
|
||||
"type": "literal"
|
||||
}
|
||||
},
|
||||
"name": "role"
|
||||
}, {
|
||||
"input": {
|
||||
"type": "string",
|
||||
"value": {
|
||||
"content": {
|
||||
"blockID": "100001",
|
||||
"name": "USER_INPUT",
|
||||
"source": "block-output"
|
||||
},
|
||||
"rawMeta": {
|
||||
"type": 1
|
||||
},
|
||||
"type": "ref"
|
||||
}
|
||||
},
|
||||
"name": "content"
|
||||
}]
|
||||
},
|
||||
"nodeMeta": {
|
||||
"description": "用于创建消息",
|
||||
"icon": "https://lf3-static.bytednsdoc.com/obj/eden-cn/dvsmryvd_avi_dvsm/ljhwZthlaukjlkulzlp/icon/icon-创建消息.jpg",
|
||||
"mainColor": "#F2B600",
|
||||
"subTitle": "创建消息",
|
||||
"title": "创建消息"
|
||||
},
|
||||
"outputs": [{
|
||||
"name": "isSuccess",
|
||||
"type": "boolean"
|
||||
}, {
|
||||
"name": "message",
|
||||
"schema": [{
|
||||
"name": "messageId",
|
||||
"type": "string"
|
||||
}, {
|
||||
"name": "role",
|
||||
"type": "string"
|
||||
}, {
|
||||
"name": "contentType",
|
||||
"type": "string"
|
||||
}, {
|
||||
"name": "content",
|
||||
"type": "string"
|
||||
}],
|
||||
"type": "object"
|
||||
}]
|
||||
},
|
||||
"edges": null,
|
||||
"id": "157061",
|
||||
"meta": {
|
||||
"position": {
|
||||
"x": 479,
|
||||
"y": -127
|
||||
}
|
||||
},
|
||||
"type": "55"
|
||||
}],
|
||||
"edges": [{
|
||||
"sourceNodeID": "100001",
|
||||
"targetNodeID": "166724",
|
||||
"sourcePortID": ""
|
||||
}, {
|
||||
"sourceNodeID": "132703",
|
||||
"targetNodeID": "900001",
|
||||
"sourcePortID": ""
|
||||
}, {
|
||||
"sourceNodeID": "157061",
|
||||
"targetNodeID": "132703",
|
||||
"sourcePortID": ""
|
||||
}, {
|
||||
"sourceNodeID": "166724",
|
||||
"targetNodeID": "157061",
|
||||
"sourcePortID": ""
|
||||
}],
|
||||
"versions": {
|
||||
"loop": "v2"
|
||||
}
|
||||
}
|
||||
@@ -19,6 +19,7 @@ package validate
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"regexp"
|
||||
"strconv"
|
||||
|
||||
@@ -29,6 +30,7 @@ import (
|
||||
"github.com/coze-dev/coze-studio/backend/domain/workflow/internal/nodes"
|
||||
"github.com/coze-dev/coze-studio/backend/domain/workflow/internal/schema"
|
||||
"github.com/coze-dev/coze-studio/backend/domain/workflow/variable"
|
||||
"github.com/coze-dev/coze-studio/backend/pkg/errorx"
|
||||
"github.com/coze-dev/coze-studio/backend/pkg/sonic"
|
||||
"github.com/coze-dev/coze-studio/backend/types/errno"
|
||||
)
|
||||
@@ -390,10 +392,13 @@ func (cv *CanvasValidator) CheckSubWorkFlowTerminatePlanType(ctx context.Context
|
||||
|
||||
if len(subID2SubVersion) > 0 {
|
||||
for id, version := range subID2SubVersion {
|
||||
v, err := workflow.GetRepository().GetVersion(ctx, id, version)
|
||||
v, existed, err := workflow.GetRepository().GetVersion(ctx, id, version)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if !existed {
|
||||
return nil, vo.WrapError(errno.ErrWorkflowNotFound, fmt.Errorf("workflow version %s not found for ID %d: %w", version, id, err), errorx.KV("id", strconv.FormatInt(id, 10)))
|
||||
}
|
||||
|
||||
var canvas vo.Canvas
|
||||
if err = sonic.UnmarshalString(v.Canvas, &canvas); err != nil {
|
||||
|
||||
@@ -28,6 +28,7 @@ import (
|
||||
|
||||
workflowModel "github.com/coze-dev/coze-studio/backend/api/model/crossdomain/workflow"
|
||||
workflow2 "github.com/coze-dev/coze-studio/backend/api/model/workflow"
|
||||
crossmessage "github.com/coze-dev/coze-studio/backend/crossdomain/contract/message"
|
||||
"github.com/coze-dev/coze-studio/backend/domain/workflow/entity"
|
||||
"github.com/coze-dev/coze-studio/backend/domain/workflow/entity/vo"
|
||||
"github.com/coze-dev/coze-studio/backend/domain/workflow/internal/execute"
|
||||
@@ -87,6 +88,11 @@ func init() {
|
||||
_ = compose.RegisterSerializableType[workflowModel.Locator]("wf_locator")
|
||||
_ = compose.RegisterSerializableType[workflowModel.BizType]("biz_type")
|
||||
_ = compose.RegisterSerializableType[*execute.AppVariables]("app_variables")
|
||||
_ = compose.RegisterSerializableType[workflow2.WorkflowMode]("workflow_mode")
|
||||
_ = compose.RegisterSerializableType[*schema.Message]("schema_message")
|
||||
_ = compose.RegisterSerializableType[*crossmessage.WfMessage]("history_messages")
|
||||
_ = compose.RegisterSerializableType[*crossmessage.Content]("content")
|
||||
|
||||
}
|
||||
|
||||
func (s *State) AddQuestion(nodeKey vo.NodeKey, question *qa.Question) {
|
||||
|
||||
@@ -31,6 +31,8 @@ import (
|
||||
model2 "github.com/cloudwego/eino/components/model"
|
||||
"github.com/cloudwego/eino/compose"
|
||||
"github.com/cloudwego/eino/schema"
|
||||
workflowModel "github.com/coze-dev/coze-studio/backend/api/model/crossdomain/workflow"
|
||||
"github.com/coze-dev/coze-studio/backend/domain/workflow/internal/execute"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"go.uber.org/mock/gomock"
|
||||
|
||||
@@ -98,6 +100,14 @@ func TestLLM(t *testing.T) {
|
||||
|
||||
ctx := ctxcache.Init(context.Background())
|
||||
|
||||
defer mockey.Mock(execute.GetExeCtx).Return(&execute.Context{
|
||||
RootCtx: execute.RootCtx{
|
||||
ExeCfg: workflowModel.ExecuteConfig{
|
||||
WorkflowMode: 0,
|
||||
},
|
||||
},
|
||||
NodeCtx: &execute.NodeCtx{},
|
||||
}).Build().UnPatch()
|
||||
t.Run("plain text output, non-streaming mode", func(t *testing.T) {
|
||||
if openaiModel == nil {
|
||||
defer func() {
|
||||
|
||||
@@ -98,13 +98,24 @@ func TestQuestionAnswer(t *testing.T) {
|
||||
defer s.Close()
|
||||
|
||||
redisClient := redis.NewWithAddrAndPassword(s.Addr(), "")
|
||||
|
||||
var oneChatModel = chatModel
|
||||
if oneChatModel == nil {
|
||||
oneChatModel = &testutil.UTChatModel{
|
||||
InvokeResultProvider: func(_ int, in []*schema.Message) (*schema.Message, error) {
|
||||
return &schema.Message{
|
||||
Role: schema.Assistant,
|
||||
Content: "-1",
|
||||
}, nil
|
||||
},
|
||||
}
|
||||
}
|
||||
mockIDGen := mock.NewMockIDGenerator(ctrl)
|
||||
mockIDGen.EXPECT().GenID(gomock.Any()).Return(time.Now().UnixNano(), nil).AnyTimes()
|
||||
mockTos := storageMock.NewMockStorage(ctrl)
|
||||
mockTos.EXPECT().GetObjectUrl(gomock.Any(), gomock.Any(), gomock.Any()).Return("", nil).AnyTimes()
|
||||
repo := repo2.NewRepository(mockIDGen, db, redisClient, mockTos,
|
||||
checkpoint.NewRedisStore(redisClient), nil, nil)
|
||||
repo, _ := repo2.NewRepository(mockIDGen, db, redisClient, mockTos,
|
||||
checkpoint.NewRedisStore(redisClient), oneChatModel, nil)
|
||||
|
||||
mockey.Mock(workflow.GetRepository).Return(repo).Build()
|
||||
|
||||
t.Run("answer directly, no structured output", func(t *testing.T) {
|
||||
|
||||
@@ -380,7 +380,7 @@ func handleEvent(ctx context.Context, event *Event, repo workflow.Repository,
|
||||
}
|
||||
|
||||
if updatedRows, currentStatus, err = repo.UpdateWorkflowExecution(ctx, wfExec, []entity.WorkflowExecuteStatus{entity.WorkflowRunning,
|
||||
entity.WorkflowInterrupted}); err != nil {
|
||||
entity.WorkflowInterrupted, entity.WorkflowCancel}); err != nil {
|
||||
return noTerminate, fmt.Errorf("failed to save workflow execution when canceled: %v", err)
|
||||
} else if updatedRows == 0 {
|
||||
return noTerminate, fmt.Errorf("failed to update workflow execution to canceled for execution id %d, current status is %v", exeID, currentStatus)
|
||||
|
||||
@@ -0,0 +1,141 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* 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 conversation
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"sync/atomic"
|
||||
|
||||
workflowModel "github.com/coze-dev/coze-studio/backend/api/model/crossdomain/workflow"
|
||||
crossconversation "github.com/coze-dev/coze-studio/backend/crossdomain/contract/conversation"
|
||||
wf "github.com/coze-dev/coze-studio/backend/domain/workflow"
|
||||
"github.com/coze-dev/coze-studio/backend/domain/workflow/entity"
|
||||
"github.com/coze-dev/coze-studio/backend/domain/workflow/entity/vo"
|
||||
"github.com/coze-dev/coze-studio/backend/domain/workflow/internal/canvas/convert"
|
||||
"github.com/coze-dev/coze-studio/backend/domain/workflow/internal/execute"
|
||||
"github.com/coze-dev/coze-studio/backend/domain/workflow/internal/nodes"
|
||||
"github.com/coze-dev/coze-studio/backend/domain/workflow/internal/schema"
|
||||
"github.com/coze-dev/coze-studio/backend/pkg/errorx"
|
||||
"github.com/coze-dev/coze-studio/backend/pkg/lang/ptr"
|
||||
"github.com/coze-dev/coze-studio/backend/pkg/lang/ternary"
|
||||
"github.com/coze-dev/coze-studio/backend/types/errno"
|
||||
)
|
||||
|
||||
type ClearConversationHistoryConfig struct{}
|
||||
|
||||
type ClearConversationHistory struct{}
|
||||
|
||||
func (c *ClearConversationHistoryConfig) Adapt(_ context.Context, n *vo.Node, _ ...nodes.AdaptOption) (*schema.NodeSchema, error) {
|
||||
ns := &schema.NodeSchema{
|
||||
Key: vo.NodeKey(n.ID),
|
||||
Type: entity.NodeTypeClearConversationHistory,
|
||||
Name: n.Data.Meta.Title,
|
||||
Configs: c,
|
||||
}
|
||||
|
||||
if err := convert.SetInputsForNodeSchema(n, ns); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err := convert.SetOutputTypesForNodeSchema(n, ns); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return ns, nil
|
||||
}
|
||||
|
||||
func (c *ClearConversationHistoryConfig) Build(_ context.Context, ns *schema.NodeSchema, _ ...schema.BuildOption) (any, error) {
|
||||
return &ClearConversationHistory{}, nil
|
||||
}
|
||||
|
||||
func (c *ClearConversationHistory) Invoke(ctx context.Context, in map[string]any) (map[string]any, error) {
|
||||
|
||||
var (
|
||||
execCtx = execute.GetExeCtx(ctx)
|
||||
env = ternary.IFElse(execCtx.ExeCfg.Mode == workflowModel.ExecuteModeRelease, vo.Online, vo.Draft)
|
||||
appID = execCtx.ExeCfg.AppID
|
||||
agentID = execCtx.ExeCfg.AgentID
|
||||
connectorID = execCtx.ExeCfg.ConnectorID
|
||||
userID = execCtx.ExeCfg.Operator
|
||||
version = execCtx.ExeCfg.Version
|
||||
)
|
||||
|
||||
if agentID != nil {
|
||||
return nil, vo.WrapError(errno.ErrConversationNodesNotAvailable, fmt.Errorf("in the agent scenario, query conversation list is not available"))
|
||||
}
|
||||
if appID == nil {
|
||||
return nil, vo.WrapError(errno.ErrConversationNodesNotAvailable, fmt.Errorf("query conversation list node, app id is required"))
|
||||
}
|
||||
|
||||
conversationName, ok := in["conversationName"].(string)
|
||||
if !ok {
|
||||
return nil, vo.WrapError(errno.ErrInvalidParameter, errors.New("conversation name is required"))
|
||||
}
|
||||
|
||||
t, existed, err := wf.GetRepository().GetConversationTemplate(ctx, env, vo.GetConversationTemplatePolicy{
|
||||
AppID: appID,
|
||||
Name: ptr.Of(conversationName),
|
||||
Version: ptr.Of(version),
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return nil, vo.WrapError(errno.ErrConversationNodeOperationFail, err, errorx.KV("cause", vo.UnwrapRootErr(err).Error()))
|
||||
}
|
||||
var conversationID int64
|
||||
if existed {
|
||||
ret, existed, err := wf.GetRepository().GetStaticConversationByTemplateID(ctx, env, userID, connectorID, t.TemplateID)
|
||||
if err != nil {
|
||||
return nil, vo.WrapError(errno.ErrConversationNodeOperationFail, err, errorx.KV("cause", vo.UnwrapRootErr(err).Error()))
|
||||
}
|
||||
if existed {
|
||||
conversationID = ret.ConversationID
|
||||
}
|
||||
} else {
|
||||
ret, existed, err := wf.GetRepository().GetDynamicConversationByName(ctx, env, *appID, connectorID, userID, conversationName)
|
||||
if err != nil {
|
||||
return nil, vo.WrapError(errno.ErrConversationNodeOperationFail, err, errorx.KV("cause", vo.UnwrapRootErr(err).Error()))
|
||||
}
|
||||
if existed {
|
||||
conversationID = ret.ConversationID
|
||||
}
|
||||
}
|
||||
|
||||
if !existed {
|
||||
return map[string]any{
|
||||
"isSuccess": false,
|
||||
}, nil
|
||||
}
|
||||
|
||||
resp, err := crossconversation.DefaultSVC().ClearConversationHistory(ctx, &crossconversation.ClearConversationHistoryReq{
|
||||
ConversationID: conversationID,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, vo.WrapError(errno.ErrConversationNodeOperationFail, err, errorx.KV("cause", vo.UnwrapRootErr(err).Error()))
|
||||
}
|
||||
if resp == nil {
|
||||
return nil, vo.WrapError(errno.ErrConversationNodeOperationFail, fmt.Errorf("clear conversation history failed, response is nil"))
|
||||
}
|
||||
if execCtx.ExeCfg.SectionID != nil {
|
||||
atomic.StoreInt64(execCtx.ExeCfg.SectionID, resp.SectionID)
|
||||
}
|
||||
return map[string]any{
|
||||
"isSuccess": true,
|
||||
}, nil
|
||||
|
||||
}
|
||||
@@ -0,0 +1,190 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* 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 conversation
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
workflowModel "github.com/coze-dev/coze-studio/backend/api/model/crossdomain/workflow"
|
||||
crossconversation "github.com/coze-dev/coze-studio/backend/crossdomain/contract/conversation"
|
||||
crossmessage "github.com/coze-dev/coze-studio/backend/crossdomain/contract/message"
|
||||
|
||||
wf "github.com/coze-dev/coze-studio/backend/domain/workflow"
|
||||
"github.com/coze-dev/coze-studio/backend/domain/workflow/entity"
|
||||
"github.com/coze-dev/coze-studio/backend/domain/workflow/entity/vo"
|
||||
"github.com/coze-dev/coze-studio/backend/domain/workflow/internal/canvas/convert"
|
||||
"github.com/coze-dev/coze-studio/backend/domain/workflow/internal/execute"
|
||||
"github.com/coze-dev/coze-studio/backend/domain/workflow/internal/nodes"
|
||||
"github.com/coze-dev/coze-studio/backend/domain/workflow/internal/schema"
|
||||
"github.com/coze-dev/coze-studio/backend/pkg/errorx"
|
||||
"github.com/coze-dev/coze-studio/backend/pkg/lang/ptr"
|
||||
"github.com/coze-dev/coze-studio/backend/pkg/lang/ternary"
|
||||
"github.com/coze-dev/coze-studio/backend/types/errno"
|
||||
)
|
||||
|
||||
type ConversationHistoryConfig struct{}
|
||||
|
||||
type ConversationHistory struct{}
|
||||
|
||||
func (ch *ConversationHistoryConfig) Adapt(_ context.Context, n *vo.Node, _ ...nodes.AdaptOption) (*schema.NodeSchema, error) {
|
||||
ns := &schema.NodeSchema{
|
||||
Key: vo.NodeKey(n.ID),
|
||||
Type: entity.NodeTypeConversationHistory,
|
||||
Name: n.Data.Meta.Title,
|
||||
Configs: ch,
|
||||
}
|
||||
|
||||
if err := convert.SetInputsForNodeSchema(n, ns); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err := convert.SetOutputTypesForNodeSchema(n, ns); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return ns, nil
|
||||
}
|
||||
|
||||
func (ch *ConversationHistoryConfig) Build(_ context.Context, ns *schema.NodeSchema, _ ...schema.BuildOption) (any, error) {
|
||||
return &ConversationHistory{}, nil
|
||||
}
|
||||
|
||||
func (ch *ConversationHistory) Invoke(ctx context.Context, input map[string]any) (map[string]any, error) {
|
||||
var (
|
||||
execCtx = execute.GetExeCtx(ctx)
|
||||
env = ternary.IFElse(execCtx.ExeCfg.Mode == workflowModel.ExecuteModeRelease, vo.Online, vo.Draft)
|
||||
appID = execCtx.ExeCfg.AppID
|
||||
agentID = execCtx.ExeCfg.AgentID
|
||||
connectorID = execCtx.ExeCfg.ConnectorID
|
||||
userID = execCtx.ExeCfg.Operator
|
||||
version = execCtx.ExeCfg.Version
|
||||
initRunID = execCtx.ExeCfg.InitRoundID
|
||||
)
|
||||
if agentID != nil {
|
||||
return nil, vo.WrapError(errno.ErrConversationNodesNotAvailable, fmt.Errorf("in the agent scenario, query conversation list is not available"))
|
||||
}
|
||||
if appID == nil {
|
||||
return nil, vo.WrapError(errno.ErrConversationNodesNotAvailable, fmt.Errorf("query conversation list node, app id is required"))
|
||||
}
|
||||
|
||||
conversationName, ok := input["conversationName"].(string)
|
||||
if !ok {
|
||||
return nil, vo.WrapError(errno.ErrInvalidParameter, errors.New("conversation name is required"))
|
||||
}
|
||||
|
||||
rounds, ok := input["rounds"].(int64)
|
||||
if !ok {
|
||||
return nil, vo.WrapError(errno.ErrInvalidParameter, errors.New("rounds is required"))
|
||||
}
|
||||
|
||||
template, existed, err := wf.GetRepository().GetConversationTemplate(ctx, env, vo.GetConversationTemplatePolicy{
|
||||
AppID: appID,
|
||||
Name: ptr.Of(conversationName),
|
||||
Version: ptr.Of(version),
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return nil, vo.WrapError(errno.ErrConversationNodeOperationFail, err, errorx.KV("cause", vo.UnwrapRootErr(err).Error()))
|
||||
}
|
||||
|
||||
var conversationID int64
|
||||
if existed {
|
||||
var sc *entity.StaticConversation
|
||||
sc, existed, err = wf.GetRepository().GetStaticConversationByTemplateID(ctx, env, userID, connectorID, template.TemplateID)
|
||||
if err != nil {
|
||||
return nil, vo.WrapError(errno.ErrConversationNodeOperationFail, err, errorx.KV("cause", vo.UnwrapRootErr(err).Error()))
|
||||
}
|
||||
if existed {
|
||||
conversationID = sc.ConversationID
|
||||
}
|
||||
|
||||
} else {
|
||||
var dc *entity.DynamicConversation
|
||||
dc, existed, err = wf.GetRepository().GetDynamicConversationByName(ctx, env, *appID, connectorID, userID, conversationName)
|
||||
if err != nil {
|
||||
return nil, vo.WrapError(errno.ErrConversationNodeOperationFail, err, errorx.KV("cause", vo.UnwrapRootErr(err).Error()))
|
||||
}
|
||||
if existed {
|
||||
conversationID = dc.ConversationID
|
||||
}
|
||||
}
|
||||
|
||||
if !existed {
|
||||
return nil, vo.WrapError(errno.ErrConversationOfAppNotFound, fmt.Errorf("the conversation name does not exist: '%v'", conversationName))
|
||||
}
|
||||
|
||||
currentConversationID := execCtx.ExeCfg.ConversationID
|
||||
isCurrentConversation := currentConversationID != nil && *currentConversationID == conversationID
|
||||
var sectionID int64
|
||||
if isCurrentConversation {
|
||||
if execCtx.ExeCfg.SectionID == nil {
|
||||
return nil, vo.WrapError(errno.ErrInvalidParameter, errors.New("section id is required"))
|
||||
}
|
||||
sectionID = *execCtx.ExeCfg.SectionID
|
||||
} else {
|
||||
cInfo, err := crossconversation.DefaultSVC().GetByID(ctx, conversationID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
sectionID = cInfo.SectionID
|
||||
}
|
||||
|
||||
runIDs, err := crossmessage.DefaultSVC().GetLatestRunIDs(ctx, &crossmessage.GetLatestRunIDsRequest{
|
||||
ConversationID: conversationID,
|
||||
UserID: userID,
|
||||
AppID: *appID,
|
||||
Rounds: rounds,
|
||||
InitRunID: initRunID,
|
||||
SectionID: sectionID,
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return nil, vo.WrapError(errno.ErrConversationNodeOperationFail, err, errorx.KV("cause", vo.UnwrapRootErr(err).Error()))
|
||||
}
|
||||
|
||||
if len(runIDs) == 0 {
|
||||
return map[string]any{
|
||||
"messageList": []any{},
|
||||
}, nil
|
||||
}
|
||||
|
||||
response, err := crossmessage.DefaultSVC().GetMessagesByRunIDs(ctx, &crossmessage.GetMessagesByRunIDsRequest{
|
||||
ConversationID: conversationID,
|
||||
RunIDs: runIDs,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, vo.WrapError(errno.ErrConversationNodeOperationFail, err, errorx.KV("cause", vo.UnwrapRootErr(err).Error()))
|
||||
}
|
||||
|
||||
var messageList []any
|
||||
for _, msg := range response.Messages {
|
||||
content, err := nodes.ConvertMessageToString(ctx, msg)
|
||||
if err != nil {
|
||||
return nil, vo.WrapError(errno.ErrConversationNodeOperationFail, err, errorx.KV("cause", vo.UnwrapRootErr(err).Error()))
|
||||
}
|
||||
messageList = append(messageList, map[string]any{
|
||||
"role": string(msg.Role),
|
||||
"content": content,
|
||||
})
|
||||
}
|
||||
|
||||
return map[string]any{
|
||||
"messageList": messageList,
|
||||
}, nil
|
||||
}
|
||||
@@ -0,0 +1,153 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* 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 conversation
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strconv"
|
||||
|
||||
workflowModel "github.com/coze-dev/coze-studio/backend/api/model/crossdomain/workflow"
|
||||
|
||||
"github.com/coze-dev/coze-studio/backend/domain/workflow"
|
||||
"github.com/coze-dev/coze-studio/backend/domain/workflow/entity"
|
||||
"github.com/coze-dev/coze-studio/backend/domain/workflow/entity/vo"
|
||||
"github.com/coze-dev/coze-studio/backend/domain/workflow/internal/canvas/convert"
|
||||
"github.com/coze-dev/coze-studio/backend/domain/workflow/internal/execute"
|
||||
"github.com/coze-dev/coze-studio/backend/domain/workflow/internal/nodes"
|
||||
"github.com/coze-dev/coze-studio/backend/domain/workflow/internal/schema"
|
||||
"github.com/coze-dev/coze-studio/backend/pkg/lang/ptr"
|
||||
"github.com/coze-dev/coze-studio/backend/pkg/lang/slices"
|
||||
"github.com/coze-dev/coze-studio/backend/pkg/lang/ternary"
|
||||
"github.com/coze-dev/coze-studio/backend/types/errno"
|
||||
)
|
||||
|
||||
type ConversationList struct{}
|
||||
|
||||
type ConversationListConfig struct{}
|
||||
|
||||
func (c *ConversationListConfig) Adapt(_ context.Context, n *vo.Node, _ ...nodes.AdaptOption) (*schema.NodeSchema, error) {
|
||||
ns := &schema.NodeSchema{
|
||||
Key: vo.NodeKey(n.ID),
|
||||
Type: entity.NodeTypeConversationList,
|
||||
Name: n.Data.Meta.Title,
|
||||
Configs: c,
|
||||
}
|
||||
|
||||
if err := convert.SetInputsForNodeSchema(n, ns); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err := convert.SetOutputTypesForNodeSchema(n, ns); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return ns, nil
|
||||
}
|
||||
|
||||
func (c *ConversationListConfig) Build(_ context.Context, ns *schema.NodeSchema, _ ...schema.BuildOption) (any, error) {
|
||||
return &ConversationList{}, nil
|
||||
}
|
||||
|
||||
type conversationInfo struct {
|
||||
conversationName string
|
||||
conversationId string
|
||||
}
|
||||
|
||||
func (c *ConversationList) Invoke(ctx context.Context, _ map[string]any) (map[string]any, error) {
|
||||
var (
|
||||
execCtx = execute.GetExeCtx(ctx)
|
||||
env = ternary.IFElse(execCtx.ExeCfg.Mode == workflowModel.ExecuteModeRelease, vo.Online, vo.Draft)
|
||||
appID = execCtx.ExeCfg.AppID
|
||||
agentID = execCtx.ExeCfg.AgentID
|
||||
connectorID = execCtx.ExeCfg.ConnectorID
|
||||
userID = execCtx.ExeCfg.Operator
|
||||
version = execCtx.ExeCfg.Version
|
||||
)
|
||||
if agentID != nil {
|
||||
return nil, vo.WrapError(errno.ErrConversationNodesNotAvailable, fmt.Errorf("in the agent scenario, query conversation list is not available"))
|
||||
}
|
||||
if appID == nil {
|
||||
return nil, vo.WrapError(errno.ErrConversationNodesNotAvailable, fmt.Errorf("query conversation list node, app id is required"))
|
||||
}
|
||||
|
||||
templates, err := workflow.GetRepository().ListConversationTemplate(ctx, env, &vo.ListConversationTemplatePolicy{
|
||||
AppID: *appID,
|
||||
Version: ptr.Of(version),
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
templateIds := make([]int64, 0, len(templates))
|
||||
for _, template := range templates {
|
||||
templateIds = append(templateIds, template.TemplateID)
|
||||
}
|
||||
|
||||
staticConversations, err := workflow.GetRepository().MGetStaticConversation(ctx, env, userID, connectorID, templateIds)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
templateIDToConvID := slices.ToMap(staticConversations, func(conv *entity.StaticConversation) (int64, int64) {
|
||||
return conv.TemplateID, conv.ConversationID
|
||||
})
|
||||
|
||||
var conversationList []conversationInfo
|
||||
|
||||
for _, template := range templates {
|
||||
convID, ok := templateIDToConvID[template.TemplateID]
|
||||
if !ok {
|
||||
convID = 0
|
||||
}
|
||||
conversationList = append(conversationList, conversationInfo{
|
||||
conversationName: template.Name,
|
||||
conversationId: strconv.FormatInt(convID, 10),
|
||||
})
|
||||
}
|
||||
|
||||
dynamicConversations, err := workflow.GetRepository().ListDynamicConversation(ctx, env, &vo.ListConversationPolicy{
|
||||
ListConversationMeta: vo.ListConversationMeta{
|
||||
APPID: *appID,
|
||||
UserID: userID,
|
||||
ConnectorID: connectorID,
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, conv := range dynamicConversations {
|
||||
conversationList = append(conversationList, conversationInfo{
|
||||
conversationName: conv.Name,
|
||||
conversationId: strconv.FormatInt(conv.ConversationID, 10),
|
||||
})
|
||||
}
|
||||
|
||||
resultList := make([]any, len(conversationList))
|
||||
for i, v := range conversationList {
|
||||
resultList[i] = map[string]any{
|
||||
"conversationName": v.conversationName,
|
||||
"conversationId": v.conversationId,
|
||||
}
|
||||
}
|
||||
|
||||
return map[string]any{
|
||||
"conversationList": resultList,
|
||||
}, nil
|
||||
|
||||
}
|
||||
@@ -0,0 +1,142 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* 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 conversation
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/coze-dev/coze-studio/backend/api/model/conversation/common"
|
||||
|
||||
workflowModel "github.com/coze-dev/coze-studio/backend/api/model/crossdomain/workflow"
|
||||
crossconversation "github.com/coze-dev/coze-studio/backend/crossdomain/contract/conversation"
|
||||
conventity "github.com/coze-dev/coze-studio/backend/domain/conversation/conversation/entity"
|
||||
|
||||
"github.com/coze-dev/coze-studio/backend/domain/workflow"
|
||||
"github.com/coze-dev/coze-studio/backend/domain/workflow/entity"
|
||||
"github.com/coze-dev/coze-studio/backend/domain/workflow/entity/vo"
|
||||
"github.com/coze-dev/coze-studio/backend/domain/workflow/internal/canvas/convert"
|
||||
"github.com/coze-dev/coze-studio/backend/domain/workflow/internal/execute"
|
||||
"github.com/coze-dev/coze-studio/backend/domain/workflow/internal/nodes"
|
||||
"github.com/coze-dev/coze-studio/backend/domain/workflow/internal/schema"
|
||||
"github.com/coze-dev/coze-studio/backend/pkg/lang/ptr"
|
||||
"github.com/coze-dev/coze-studio/backend/pkg/lang/ternary"
|
||||
"github.com/coze-dev/coze-studio/backend/types/errno"
|
||||
)
|
||||
|
||||
type CreateConversationConfig struct{}
|
||||
|
||||
type CreateConversation struct{}
|
||||
|
||||
func (c *CreateConversationConfig) Adapt(_ context.Context, n *vo.Node, _ ...nodes.AdaptOption) (*schema.NodeSchema, error) {
|
||||
ns := &schema.NodeSchema{
|
||||
Key: vo.NodeKey(n.ID),
|
||||
Type: entity.NodeTypeCreateConversation,
|
||||
Name: n.Data.Meta.Title,
|
||||
Configs: c,
|
||||
}
|
||||
|
||||
if err := convert.SetInputsForNodeSchema(n, ns); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err := convert.SetOutputTypesForNodeSchema(n, ns); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return ns, nil
|
||||
}
|
||||
|
||||
func (c *CreateConversationConfig) Build(_ context.Context, ns *schema.NodeSchema, _ ...schema.BuildOption) (any, error) {
|
||||
return &CreateConversation{}, nil
|
||||
}
|
||||
|
||||
func (c *CreateConversation) Invoke(ctx context.Context, input map[string]any) (map[string]any, error) {
|
||||
|
||||
var (
|
||||
execCtx = execute.GetExeCtx(ctx)
|
||||
env = ternary.IFElse(execCtx.ExeCfg.Mode == workflowModel.ExecuteModeRelease, vo.Online, vo.Draft)
|
||||
appID = execCtx.ExeCfg.AppID
|
||||
agentID = execCtx.ExeCfg.AgentID
|
||||
version = execCtx.ExeCfg.Version
|
||||
connectorID = execCtx.ExeCfg.ConnectorID
|
||||
userID = execCtx.ExeCfg.Operator
|
||||
conversationIDGenerator = workflow.ConversationIDGenerator(func(ctx context.Context, appID int64, userID, connectorID int64) (*conventity.Conversation, error) {
|
||||
return crossconversation.DefaultSVC().CreateConversation(ctx, &conventity.CreateMeta{
|
||||
AgentID: appID,
|
||||
UserID: userID,
|
||||
ConnectorID: connectorID,
|
||||
Scene: common.Scene_SceneWorkflow,
|
||||
})
|
||||
})
|
||||
)
|
||||
if agentID != nil {
|
||||
return nil, vo.WrapError(errno.ErrConversationNodesNotAvailable, fmt.Errorf("in the agent scenario, create conversation is not available"))
|
||||
}
|
||||
|
||||
if appID == nil {
|
||||
return nil, vo.WrapError(errno.ErrConversationNodesNotAvailable, errors.New("create conversation node, app id is required"))
|
||||
}
|
||||
|
||||
conversationName, ok := input["conversationName"].(string)
|
||||
if !ok {
|
||||
return nil, vo.WrapError(errno.ErrInvalidParameter, errors.New("conversation name is required"))
|
||||
}
|
||||
|
||||
template, existed, err := workflow.GetRepository().GetConversationTemplate(ctx, env, vo.GetConversationTemplatePolicy{
|
||||
AppID: appID,
|
||||
Name: ptr.Of(conversationName),
|
||||
Version: ptr.Of(version),
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if existed {
|
||||
cID, _, existed, err := workflow.GetRepository().GetOrCreateStaticConversation(ctx, env, conversationIDGenerator, &vo.CreateStaticConversation{
|
||||
AppID: ptr.From(appID),
|
||||
TemplateID: template.TemplateID,
|
||||
UserID: userID,
|
||||
ConnectorID: connectorID,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return map[string]any{
|
||||
"isSuccess": true,
|
||||
"conversationId": cID,
|
||||
"isExisted": existed,
|
||||
}, nil
|
||||
}
|
||||
|
||||
cID, _, existed, err := workflow.GetRepository().GetOrCreateDynamicConversation(ctx, env, conversationIDGenerator, &vo.CreateDynamicConversation{
|
||||
AppID: ptr.From(appID),
|
||||
UserID: userID,
|
||||
ConnectorID: connectorID,
|
||||
Name: conversationName,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return map[string]any{
|
||||
"isSuccess": true,
|
||||
"conversationId": cID,
|
||||
"isExisted": existed,
|
||||
}, nil
|
||||
|
||||
}
|
||||
@@ -0,0 +1,299 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* 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 conversation
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/coze-dev/coze-studio/backend/api/model/conversation/common"
|
||||
conventity "github.com/coze-dev/coze-studio/backend/domain/conversation/conversation/entity"
|
||||
|
||||
"strconv"
|
||||
"sync/atomic"
|
||||
|
||||
einoSchema "github.com/cloudwego/eino/schema"
|
||||
model "github.com/coze-dev/coze-studio/backend/api/model/crossdomain/message"
|
||||
workflowModel "github.com/coze-dev/coze-studio/backend/api/model/crossdomain/workflow"
|
||||
crossagentrun "github.com/coze-dev/coze-studio/backend/crossdomain/contract/agentrun"
|
||||
crossconversation "github.com/coze-dev/coze-studio/backend/crossdomain/contract/conversation"
|
||||
crossmessage "github.com/coze-dev/coze-studio/backend/crossdomain/contract/message"
|
||||
"github.com/coze-dev/coze-studio/backend/pkg/errorx"
|
||||
|
||||
agententity "github.com/coze-dev/coze-studio/backend/domain/conversation/agentrun/entity"
|
||||
"github.com/coze-dev/coze-studio/backend/domain/workflow"
|
||||
"github.com/coze-dev/coze-studio/backend/domain/workflow/entity"
|
||||
"github.com/coze-dev/coze-studio/backend/domain/workflow/entity/vo"
|
||||
"github.com/coze-dev/coze-studio/backend/domain/workflow/internal/canvas/convert"
|
||||
"github.com/coze-dev/coze-studio/backend/domain/workflow/internal/execute"
|
||||
"github.com/coze-dev/coze-studio/backend/domain/workflow/internal/nodes"
|
||||
"github.com/coze-dev/coze-studio/backend/domain/workflow/internal/schema"
|
||||
"github.com/coze-dev/coze-studio/backend/pkg/lang/ptr"
|
||||
"github.com/coze-dev/coze-studio/backend/pkg/lang/ternary"
|
||||
"github.com/coze-dev/coze-studio/backend/types/errno"
|
||||
)
|
||||
|
||||
type CreateMessageConfig struct{}
|
||||
|
||||
type CreateMessage struct{}
|
||||
|
||||
func (c *CreateMessageConfig) Adapt(_ context.Context, n *vo.Node, _ ...nodes.AdaptOption) (*schema.NodeSchema, error) {
|
||||
ns := &schema.NodeSchema{
|
||||
Key: vo.NodeKey(n.ID),
|
||||
Type: entity.NodeTypeCreateMessage,
|
||||
Name: n.Data.Meta.Title,
|
||||
Configs: c,
|
||||
}
|
||||
|
||||
if err := convert.SetInputsForNodeSchema(n, ns); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err := convert.SetOutputTypesForNodeSchema(n, ns); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return ns, nil
|
||||
}
|
||||
|
||||
func (c *CreateMessageConfig) Build(_ context.Context, ns *schema.NodeSchema, _ ...schema.BuildOption) (any, error) {
|
||||
return &CreateMessage{}, nil
|
||||
}
|
||||
|
||||
func (c *CreateMessage) getConversationIDByName(ctx context.Context, env vo.Env, appID *int64, version, conversationName string, userID, connectorID int64) (int64, error) {
|
||||
template, isExist, err := workflow.GetRepository().GetConversationTemplate(ctx, env, vo.GetConversationTemplatePolicy{
|
||||
AppID: appID,
|
||||
Name: ptr.Of(conversationName),
|
||||
Version: ptr.Of(version),
|
||||
})
|
||||
if err != nil {
|
||||
return 0, vo.WrapError(errno.ErrMessageNodeOperationFail, err, errorx.KV("cause", vo.UnwrapRootErr(err).Error()))
|
||||
}
|
||||
|
||||
conversationIDGenerator := workflow.ConversationIDGenerator(func(ctx context.Context, appID int64, userID, connectorID int64) (*conventity.Conversation, error) {
|
||||
return crossconversation.DefaultSVC().CreateConversation(ctx, &conventity.CreateMeta{
|
||||
AgentID: appID,
|
||||
UserID: userID,
|
||||
ConnectorID: connectorID,
|
||||
Scene: common.Scene_SceneWorkflow,
|
||||
})
|
||||
})
|
||||
|
||||
var conversationID int64
|
||||
if isExist {
|
||||
cID, _, _, err := workflow.GetRepository().GetOrCreateStaticConversation(ctx, env, conversationIDGenerator, &vo.CreateStaticConversation{
|
||||
AppID: ptr.From(appID),
|
||||
TemplateID: template.TemplateID,
|
||||
UserID: userID,
|
||||
ConnectorID: connectorID,
|
||||
})
|
||||
if err != nil {
|
||||
return 0, vo.WrapError(errno.ErrMessageNodeOperationFail, err, errorx.KV("cause", vo.UnwrapRootErr(err).Error()))
|
||||
}
|
||||
conversationID = cID
|
||||
} else {
|
||||
dc, _, err := workflow.GetRepository().GetDynamicConversationByName(ctx, env, *appID, connectorID, userID, conversationName)
|
||||
if err != nil {
|
||||
return 0, vo.WrapError(errno.ErrMessageNodeOperationFail, err, errorx.KV("cause", vo.UnwrapRootErr(err).Error()))
|
||||
}
|
||||
if dc != nil {
|
||||
conversationID = dc.ConversationID
|
||||
}
|
||||
}
|
||||
return conversationID, nil
|
||||
}
|
||||
|
||||
func (c *CreateMessage) Invoke(ctx context.Context, input map[string]any) (map[string]any, error) {
|
||||
var (
|
||||
execCtx = execute.GetExeCtx(ctx)
|
||||
env = ternary.IFElse(execCtx.ExeCfg.Mode == workflowModel.ExecuteModeRelease, vo.Online, vo.Draft)
|
||||
appID = execCtx.ExeCfg.AppID
|
||||
agentID = execCtx.ExeCfg.AgentID
|
||||
version = execCtx.ExeCfg.Version
|
||||
connectorID = execCtx.ExeCfg.ConnectorID
|
||||
userID = execCtx.ExeCfg.Operator
|
||||
)
|
||||
|
||||
conversationName, ok := input["conversationName"].(string)
|
||||
if !ok {
|
||||
return nil, vo.WrapError(errno.ErrInvalidParameter, errors.New("conversationName is required"))
|
||||
}
|
||||
|
||||
role, ok := input["role"].(string)
|
||||
if !ok {
|
||||
return nil, vo.WrapError(errno.ErrInvalidParameter, errors.New("role is required"))
|
||||
}
|
||||
if role != "user" && role != "assistant" {
|
||||
return nil, vo.WrapError(errno.ErrInvalidParameter, fmt.Errorf("role must be user or assistant"))
|
||||
}
|
||||
|
||||
content, ok := input["content"].(string)
|
||||
if !ok {
|
||||
return nil, vo.WrapError(errno.ErrInvalidParameter, errors.New("content is required"))
|
||||
}
|
||||
|
||||
var conversationID int64
|
||||
var err error
|
||||
var resolvedAppID int64
|
||||
if appID == nil {
|
||||
if conversationName != "Default" {
|
||||
return nil, vo.WrapError(errno.ErrOnlyDefaultConversationAllowInAgentScenario, errors.New("conversation node only allow in application"))
|
||||
}
|
||||
if agentID == nil || execCtx.ExeCfg.ConversationID == nil {
|
||||
return map[string]any{
|
||||
"isSuccess": false,
|
||||
"message": map[string]any{
|
||||
"messageId": "0",
|
||||
"role": role,
|
||||
"contentType": "text",
|
||||
"content": content,
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
conversationID = *execCtx.ExeCfg.ConversationID
|
||||
resolvedAppID = *agentID
|
||||
} else {
|
||||
conversationID, err = c.getConversationIDByName(ctx, env, appID, version, conversationName, userID, connectorID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
resolvedAppID = *appID
|
||||
}
|
||||
|
||||
if conversationID == 0 {
|
||||
return map[string]any{
|
||||
"isSuccess": false,
|
||||
"message": map[string]any{
|
||||
"messageId": "0",
|
||||
"role": role,
|
||||
"contentType": "text",
|
||||
"content": content,
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
|
||||
currentConversationID := execCtx.ExeCfg.ConversationID
|
||||
isCurrentConversation := currentConversationID != nil && *currentConversationID == conversationID
|
||||
var runID int64
|
||||
var sectionID int64
|
||||
if isCurrentConversation {
|
||||
if execCtx.ExeCfg.SectionID != nil {
|
||||
sectionID = *execCtx.ExeCfg.SectionID
|
||||
} else {
|
||||
return nil, vo.WrapError(errno.ErrInvalidParameter, errors.New("section id is required"))
|
||||
}
|
||||
} else {
|
||||
cInfo, err := crossconversation.DefaultSVC().GetByID(ctx, conversationID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
sectionID = cInfo.SectionID
|
||||
}
|
||||
|
||||
if role == "user" {
|
||||
// For user messages, always create a new run and store the ID in the context.
|
||||
runRecord, err := crossagentrun.DefaultSVC().Create(ctx, &agententity.AgentRunMeta{
|
||||
AgentID: resolvedAppID,
|
||||
ConversationID: conversationID,
|
||||
UserID: strconv.FormatInt(userID, 10),
|
||||
ConnectorID: connectorID,
|
||||
SectionID: sectionID,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
newRunID := runRecord.ID
|
||||
if execCtx.ExeCfg.RoundID != nil {
|
||||
atomic.StoreInt64(execCtx.ExeCfg.RoundID, newRunID)
|
||||
}
|
||||
runID = newRunID
|
||||
} else if isCurrentConversation {
|
||||
// For assistant messages in the same conversation, reuse the runID from the context.
|
||||
if execCtx.ExeCfg.RoundID == nil {
|
||||
// This indicates an inconsistent state, as a user message should have set this.
|
||||
return map[string]any{
|
||||
"isSuccess": false,
|
||||
"message": map[string]any{
|
||||
"messageId": "0",
|
||||
"role": role,
|
||||
"contentType": "text",
|
||||
"content": content,
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
runID = *execCtx.ExeCfg.RoundID
|
||||
} else {
|
||||
// For assistant messages in a different conversation or a new workflow run,
|
||||
// find the latest runID or create a new one as a fallback.
|
||||
runIDs, err := crossmessage.DefaultSVC().GetLatestRunIDs(ctx, &crossmessage.GetLatestRunIDsRequest{
|
||||
ConversationID: conversationID,
|
||||
UserID: userID,
|
||||
AppID: resolvedAppID,
|
||||
Rounds: 1,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(runIDs) > 0 && runIDs[0] != 0 {
|
||||
runID = runIDs[0]
|
||||
} else {
|
||||
runRecord, err := crossagentrun.DefaultSVC().Create(ctx, &agententity.AgentRunMeta{
|
||||
AgentID: resolvedAppID,
|
||||
ConversationID: conversationID,
|
||||
UserID: strconv.FormatInt(userID, 10),
|
||||
ConnectorID: connectorID,
|
||||
SectionID: sectionID,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, vo.WrapError(errno.ErrMessageNodeOperationFail, err, errorx.KV("cause", vo.UnwrapRootErr(err).Error()))
|
||||
}
|
||||
runID = runRecord.ID
|
||||
}
|
||||
}
|
||||
|
||||
message := &model.Message{
|
||||
ConversationID: conversationID,
|
||||
Role: einoSchema.RoleType(role),
|
||||
Content: content,
|
||||
ContentType: model.ContentType("text"),
|
||||
UserID: strconv.FormatInt(userID, 10),
|
||||
AgentID: resolvedAppID,
|
||||
RunID: runID,
|
||||
SectionID: sectionID,
|
||||
}
|
||||
if message.Role == einoSchema.User {
|
||||
message.MessageType = model.MessageTypeQuestion
|
||||
} else {
|
||||
message.MessageType = model.MessageTypeAnswer
|
||||
}
|
||||
msg, err := crossmessage.DefaultSVC().Create(ctx, message)
|
||||
if err != nil {
|
||||
return nil, vo.WrapError(errno.ErrMessageNodeOperationFail, err, errorx.KV("cause", vo.UnwrapRootErr(err).Error()))
|
||||
}
|
||||
|
||||
messageOutput := map[string]any{
|
||||
"messageId": msg.ID,
|
||||
"role": role,
|
||||
"contentType": "text",
|
||||
"content": content,
|
||||
}
|
||||
|
||||
return map[string]any{
|
||||
"isSuccess": true,
|
||||
"message": messageOutput,
|
||||
}, nil
|
||||
}
|
||||
@@ -0,0 +1,122 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* 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 conversation
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
workflowModel "github.com/coze-dev/coze-studio/backend/api/model/crossdomain/workflow"
|
||||
|
||||
"github.com/coze-dev/coze-studio/backend/domain/workflow"
|
||||
"github.com/coze-dev/coze-studio/backend/domain/workflow/entity"
|
||||
"github.com/coze-dev/coze-studio/backend/domain/workflow/entity/vo"
|
||||
"github.com/coze-dev/coze-studio/backend/domain/workflow/internal/canvas/convert"
|
||||
"github.com/coze-dev/coze-studio/backend/domain/workflow/internal/execute"
|
||||
"github.com/coze-dev/coze-studio/backend/domain/workflow/internal/nodes"
|
||||
"github.com/coze-dev/coze-studio/backend/domain/workflow/internal/schema"
|
||||
"github.com/coze-dev/coze-studio/backend/pkg/lang/ptr"
|
||||
"github.com/coze-dev/coze-studio/backend/pkg/lang/ternary"
|
||||
"github.com/coze-dev/coze-studio/backend/types/errno"
|
||||
)
|
||||
|
||||
type DeleteConversationConfig struct{}
|
||||
|
||||
type DeleteConversation struct{}
|
||||
|
||||
func (d *DeleteConversationConfig) Adapt(_ context.Context, n *vo.Node, _ ...nodes.AdaptOption) (*schema.NodeSchema, error) {
|
||||
ns := &schema.NodeSchema{
|
||||
Key: vo.NodeKey(n.ID),
|
||||
Type: entity.NodeTypeConversationDelete,
|
||||
Name: n.Data.Meta.Title,
|
||||
Configs: d,
|
||||
}
|
||||
|
||||
if err := convert.SetInputsForNodeSchema(n, ns); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err := convert.SetOutputTypesForNodeSchema(n, ns); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return ns, nil
|
||||
}
|
||||
|
||||
func (d *DeleteConversationConfig) Build(_ context.Context, ns *schema.NodeSchema, _ ...schema.BuildOption) (any, error) {
|
||||
return &DeleteConversation{}, nil
|
||||
}
|
||||
|
||||
func (d *DeleteConversation) Invoke(ctx context.Context, in map[string]any) (map[string]any, error) {
|
||||
|
||||
var (
|
||||
execCtx = execute.GetExeCtx(ctx)
|
||||
env = ternary.IFElse(execCtx.ExeCfg.Mode == workflowModel.ExecuteModeRelease, vo.Online, vo.Draft)
|
||||
appID = execCtx.ExeCfg.AppID
|
||||
agentID = execCtx.ExeCfg.AgentID
|
||||
version = execCtx.ExeCfg.Version
|
||||
connectorID = execCtx.ExeCfg.ConnectorID
|
||||
userID = execCtx.ExeCfg.Operator
|
||||
)
|
||||
|
||||
if agentID != nil {
|
||||
return nil, vo.WrapError(errno.ErrConversationNodesNotAvailable, fmt.Errorf("in the agent scenario, delete conversation is not available"))
|
||||
}
|
||||
|
||||
if appID == nil {
|
||||
return nil, vo.WrapError(errno.ErrConversationNodesNotAvailable, errors.New("delete conversation node, app id is required"))
|
||||
}
|
||||
|
||||
cName, ok := in["conversationName"]
|
||||
if !ok {
|
||||
return nil, vo.WrapError(errno.ErrInvalidParameter, errors.New("conversation name is required"))
|
||||
}
|
||||
|
||||
conversationName := cName.(string)
|
||||
|
||||
_, existed, err := workflow.GetRepository().GetConversationTemplate(ctx, env, vo.GetConversationTemplatePolicy{
|
||||
AppID: appID,
|
||||
Name: ptr.Of(conversationName),
|
||||
Version: ptr.Of(version),
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if existed {
|
||||
return nil, vo.WrapError(errno.ErrConversationNodeInvalidOperation, fmt.Errorf("only conversation created through nodes are allowed to be modified or deleted"))
|
||||
}
|
||||
|
||||
dyConversation, existed, err := workflow.GetRepository().GetDynamicConversationByName(ctx, env, *appID, connectorID, userID, conversationName)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if !existed {
|
||||
return nil, vo.WrapError(errno.ErrConversationOfAppNotFound, fmt.Errorf("the conversation name does not exist: '%v'", conversationName))
|
||||
}
|
||||
|
||||
_, err = workflow.GetRepository().DeleteDynamicConversation(ctx, env, dyConversation.ID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return map[string]any{
|
||||
"isSuccess": true,
|
||||
}, nil
|
||||
}
|
||||
@@ -0,0 +1,162 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* 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 conversation
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"strconv"
|
||||
|
||||
workflowModel "github.com/coze-dev/coze-studio/backend/api/model/crossdomain/workflow"
|
||||
crossmessage "github.com/coze-dev/coze-studio/backend/crossdomain/contract/message"
|
||||
msgentity "github.com/coze-dev/coze-studio/backend/domain/conversation/message/entity"
|
||||
"github.com/coze-dev/coze-studio/backend/pkg/errorx"
|
||||
|
||||
wf "github.com/coze-dev/coze-studio/backend/domain/workflow"
|
||||
"github.com/coze-dev/coze-studio/backend/domain/workflow/entity"
|
||||
"github.com/coze-dev/coze-studio/backend/domain/workflow/entity/vo"
|
||||
"github.com/coze-dev/coze-studio/backend/domain/workflow/internal/canvas/convert"
|
||||
"github.com/coze-dev/coze-studio/backend/domain/workflow/internal/execute"
|
||||
"github.com/coze-dev/coze-studio/backend/domain/workflow/internal/nodes"
|
||||
"github.com/coze-dev/coze-studio/backend/domain/workflow/internal/schema"
|
||||
"github.com/coze-dev/coze-studio/backend/pkg/lang/ptr"
|
||||
"github.com/coze-dev/coze-studio/backend/pkg/lang/ternary"
|
||||
"github.com/coze-dev/coze-studio/backend/types/errno"
|
||||
)
|
||||
|
||||
type DeleteMessageConfig struct{}
|
||||
|
||||
type DeleteMessage struct{}
|
||||
|
||||
func (d *DeleteMessageConfig) Adapt(_ context.Context, n *vo.Node, _ ...nodes.AdaptOption) (*schema.NodeSchema, error) {
|
||||
ns := &schema.NodeSchema{
|
||||
Key: vo.NodeKey(n.ID),
|
||||
Type: entity.NodeTypeDeleteMessage,
|
||||
Name: n.Data.Meta.Title,
|
||||
Configs: d,
|
||||
}
|
||||
|
||||
if err := convert.SetInputsForNodeSchema(n, ns); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err := convert.SetOutputTypesForNodeSchema(n, ns); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return ns, nil
|
||||
}
|
||||
|
||||
func (d *DeleteMessageConfig) Build(_ context.Context, ns *schema.NodeSchema, _ ...schema.BuildOption) (any, error) {
|
||||
return &DeleteMessage{}, nil
|
||||
}
|
||||
|
||||
func (d *DeleteMessage) Invoke(ctx context.Context, input map[string]any) (map[string]any, error) {
|
||||
var (
|
||||
execCtx = execute.GetExeCtx(ctx)
|
||||
env = ternary.IFElse(execCtx.ExeCfg.Mode == workflowModel.ExecuteModeRelease, vo.Online, vo.Draft)
|
||||
appID = execCtx.ExeCfg.AppID
|
||||
agentID = execCtx.ExeCfg.AgentID
|
||||
version = execCtx.ExeCfg.Version
|
||||
connectorID = execCtx.ExeCfg.ConnectorID
|
||||
userID = execCtx.ExeCfg.Operator
|
||||
|
||||
successMap = map[string]any{
|
||||
"isSuccess": true,
|
||||
}
|
||||
failedMap = map[string]any{
|
||||
"isSuccess": false,
|
||||
}
|
||||
)
|
||||
|
||||
conversationName, ok := input["conversationName"].(string)
|
||||
if !ok {
|
||||
return nil, vo.WrapError(errno.ErrInvalidParameter, errors.New("conversationName is required"))
|
||||
}
|
||||
messageStr, ok := input["messageId"].(string)
|
||||
if !ok {
|
||||
return nil, vo.WrapError(errno.ErrInvalidParameter, errors.New("messageId is required"))
|
||||
}
|
||||
messageID, err := strconv.ParseInt(messageStr, 10, 64)
|
||||
if err != nil {
|
||||
return nil, vo.WrapError(errno.ErrInvalidParameter, err)
|
||||
}
|
||||
|
||||
if appID == nil {
|
||||
if conversationName != "Default" {
|
||||
return nil, vo.WrapError(errno.ErrOnlyDefaultConversationAllowInAgentScenario, fmt.Errorf("only default conversation allow in agent scenario"))
|
||||
}
|
||||
|
||||
if agentID == nil || execCtx.ExeCfg.ConversationID == nil {
|
||||
return failedMap, nil
|
||||
}
|
||||
|
||||
err = crossmessage.DefaultSVC().Delete(ctx, &msgentity.DeleteMeta{MessageIDs: []int64{messageID}, ConversationID: execCtx.ExeCfg.ConversationID})
|
||||
if err != nil {
|
||||
return nil, vo.WrapError(errno.ErrMessageNodeOperationFail, err, errorx.KV("cause", vo.UnwrapRootErr(err).Error()))
|
||||
}
|
||||
|
||||
return successMap, nil
|
||||
}
|
||||
|
||||
t, existed, err := wf.GetRepository().GetConversationTemplate(ctx, env, vo.GetConversationTemplatePolicy{
|
||||
AppID: appID,
|
||||
Name: ptr.Of(conversationName),
|
||||
Version: ptr.Of(version),
|
||||
})
|
||||
if err != nil {
|
||||
return nil, vo.WrapError(errno.ErrMessageNodeOperationFail, err, errorx.KV("cause", vo.UnwrapRootErr(err).Error()))
|
||||
}
|
||||
|
||||
if existed {
|
||||
sc, existed, err := wf.GetRepository().GetStaticConversationByTemplateID(ctx, env, userID, connectorID, t.TemplateID)
|
||||
if err != nil {
|
||||
return nil, vo.WrapError(errno.ErrMessageNodeOperationFail, err, errorx.KV("cause", vo.UnwrapRootErr(err).Error()))
|
||||
}
|
||||
|
||||
if !existed {
|
||||
return failedMap, nil
|
||||
}
|
||||
|
||||
err = crossmessage.DefaultSVC().Delete(ctx, &msgentity.DeleteMeta{MessageIDs: []int64{messageID}, ConversationID: ptr.Of(sc.ConversationID)})
|
||||
if err != nil {
|
||||
return nil, vo.WrapError(errno.ErrMessageNodeOperationFail, err, errorx.KV("cause", vo.UnwrapRootErr(err).Error()))
|
||||
}
|
||||
|
||||
return successMap, nil
|
||||
|
||||
} else {
|
||||
dc, existed, err := wf.GetRepository().GetDynamicConversationByName(ctx, env, *appID, connectorID, userID, conversationName)
|
||||
if err != nil {
|
||||
return nil, vo.WrapError(errno.ErrMessageNodeOperationFail, err, errorx.KV("cause", vo.UnwrapRootErr(err).Error()))
|
||||
}
|
||||
|
||||
if !existed {
|
||||
return failedMap, nil
|
||||
}
|
||||
|
||||
err = crossmessage.DefaultSVC().Delete(ctx, &msgentity.DeleteMeta{MessageIDs: []int64{messageID}, ConversationID: ptr.Of(dc.ConversationID)})
|
||||
if err != nil {
|
||||
return nil, vo.WrapError(errno.ErrMessageNodeOperationFail, err, errorx.KV("cause", vo.UnwrapRootErr(err).Error()))
|
||||
}
|
||||
|
||||
return successMap, nil
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,181 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* 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 conversation
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
model "github.com/coze-dev/coze-studio/backend/api/model/crossdomain/message"
|
||||
"strconv"
|
||||
|
||||
workflowModel "github.com/coze-dev/coze-studio/backend/api/model/crossdomain/workflow"
|
||||
"github.com/coze-dev/coze-studio/backend/crossdomain/contract/message"
|
||||
crossmessage "github.com/coze-dev/coze-studio/backend/crossdomain/contract/message"
|
||||
"github.com/coze-dev/coze-studio/backend/domain/workflow"
|
||||
"github.com/coze-dev/coze-studio/backend/domain/workflow/entity"
|
||||
"github.com/coze-dev/coze-studio/backend/domain/workflow/entity/vo"
|
||||
"github.com/coze-dev/coze-studio/backend/domain/workflow/internal/canvas/convert"
|
||||
"github.com/coze-dev/coze-studio/backend/domain/workflow/internal/execute"
|
||||
"github.com/coze-dev/coze-studio/backend/domain/workflow/internal/nodes"
|
||||
"github.com/coze-dev/coze-studio/backend/domain/workflow/internal/schema"
|
||||
"github.com/coze-dev/coze-studio/backend/pkg/errorx"
|
||||
"github.com/coze-dev/coze-studio/backend/pkg/lang/ptr"
|
||||
"github.com/coze-dev/coze-studio/backend/pkg/lang/ternary"
|
||||
"github.com/coze-dev/coze-studio/backend/types/errno"
|
||||
)
|
||||
|
||||
type EditMessageConfig struct{}
|
||||
|
||||
type EditMessage struct{}
|
||||
|
||||
func (e *EditMessageConfig) Adapt(_ context.Context, n *vo.Node, _ ...nodes.AdaptOption) (*schema.NodeSchema, error) {
|
||||
ns := &schema.NodeSchema{
|
||||
Key: vo.NodeKey(n.ID),
|
||||
Type: entity.NodeTypeEditMessage,
|
||||
Name: n.Data.Meta.Title,
|
||||
Configs: e,
|
||||
}
|
||||
|
||||
if err := convert.SetInputsForNodeSchema(n, ns); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err := convert.SetOutputTypesForNodeSchema(n, ns); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return ns, nil
|
||||
}
|
||||
|
||||
func (e *EditMessageConfig) Build(_ context.Context, ns *schema.NodeSchema, _ ...schema.BuildOption) (any, error) {
|
||||
return &EditMessage{}, nil
|
||||
}
|
||||
|
||||
func (e *EditMessage) Invoke(ctx context.Context, input map[string]any) (map[string]any, error) {
|
||||
var (
|
||||
execCtx = execute.GetExeCtx(ctx)
|
||||
env = ternary.IFElse(execCtx.ExeCfg.Mode == workflowModel.ExecuteModeRelease, vo.Online, vo.Draft)
|
||||
appID = execCtx.ExeCfg.AppID
|
||||
agentID = execCtx.ExeCfg.AgentID
|
||||
version = execCtx.ExeCfg.Version
|
||||
connectorID = execCtx.ExeCfg.ConnectorID
|
||||
userID = execCtx.ExeCfg.Operator
|
||||
|
||||
successMap = map[string]any{
|
||||
"isSuccess": true,
|
||||
}
|
||||
failedMap = map[string]any{
|
||||
"isSuccess": false,
|
||||
}
|
||||
)
|
||||
|
||||
conversationName, ok := input["conversationName"].(string)
|
||||
if !ok {
|
||||
return nil, vo.WrapError(errno.ErrInvalidParameter, errors.New("conversationName is required"))
|
||||
}
|
||||
|
||||
messageStr, ok := input["messageId"].(string)
|
||||
if !ok {
|
||||
return nil, vo.WrapError(errno.ErrInvalidParameter, errors.New("messageId is required"))
|
||||
}
|
||||
|
||||
messageID, err := strconv.ParseInt(messageStr, 10, 64)
|
||||
if err != nil {
|
||||
return nil, vo.WrapError(errno.ErrMessageNodeOperationFail, err, errorx.KV("cause", vo.UnwrapRootErr(err).Error()))
|
||||
}
|
||||
|
||||
newContent, ok := input["newContent"].(string)
|
||||
if !ok {
|
||||
return nil, vo.WrapError(errno.ErrInvalidParameter, errors.New("newContent is required"))
|
||||
}
|
||||
|
||||
if appID == nil {
|
||||
if conversationName != "Default" {
|
||||
return nil, vo.WrapError(errno.ErrOnlyDefaultConversationAllowInAgentScenario, fmt.Errorf("only default conversation allow in agent scenario"))
|
||||
}
|
||||
|
||||
if agentID == nil || execCtx.ExeCfg.ConversationID == nil {
|
||||
return failedMap, nil
|
||||
}
|
||||
|
||||
_, err = crossmessage.DefaultSVC().Edit(ctx, &model.Message{ConversationID: *execCtx.ExeCfg.ConversationID, ID: messageID, Content: newContent})
|
||||
if err != nil {
|
||||
return nil, vo.WrapError(errno.ErrMessageNodeOperationFail, err, errorx.KV("cause", vo.UnwrapRootErr(err).Error()))
|
||||
}
|
||||
return successMap, err
|
||||
}
|
||||
|
||||
msg, err := message.DefaultSVC().GetMessageByID(ctx, messageID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if msg == nil {
|
||||
return nil, vo.NewError(errno.ErrMessageNodeOperationFail, errorx.KV("cause", "message not found"))
|
||||
}
|
||||
|
||||
if msg.Content == newContent {
|
||||
return successMap, nil
|
||||
}
|
||||
|
||||
t, existed, err := workflow.GetRepository().GetConversationTemplate(ctx, env, vo.GetConversationTemplatePolicy{
|
||||
AppID: appID,
|
||||
Name: ptr.Of(conversationName),
|
||||
Version: ptr.Of(version),
|
||||
})
|
||||
if err != nil {
|
||||
return nil, vo.WrapError(errno.ErrMessageNodeOperationFail, err, errorx.KV("cause", vo.UnwrapRootErr(err).Error()))
|
||||
}
|
||||
|
||||
if existed {
|
||||
sts, existed, err := workflow.GetRepository().GetStaticConversationByTemplateID(ctx, env, userID, connectorID, t.TemplateID)
|
||||
if err != nil {
|
||||
return nil, vo.WrapError(errno.ErrMessageNodeOperationFail, err, errorx.KV("cause", vo.UnwrapRootErr(err).Error()))
|
||||
}
|
||||
|
||||
if !existed {
|
||||
return failedMap, nil
|
||||
}
|
||||
|
||||
_, err = crossmessage.DefaultSVC().Edit(ctx, &model.Message{ConversationID: sts.ConversationID, ID: messageID, Content: newContent})
|
||||
if err != nil {
|
||||
return nil, vo.WrapError(errno.ErrMessageNodeOperationFail, err, errorx.KV("cause", vo.UnwrapRootErr(err).Error()))
|
||||
}
|
||||
|
||||
return successMap, nil
|
||||
|
||||
} else {
|
||||
dyConversation, existed, err := workflow.GetRepository().GetDynamicConversationByName(ctx, env, *appID, connectorID, userID, conversationName)
|
||||
if err != nil {
|
||||
return nil, vo.WrapError(errno.ErrMessageNodeOperationFail, err, errorx.KV("cause", vo.UnwrapRootErr(err).Error()))
|
||||
}
|
||||
|
||||
if !existed {
|
||||
return failedMap, nil
|
||||
}
|
||||
|
||||
_, err = crossmessage.DefaultSVC().Edit(ctx, &model.Message{ConversationID: dyConversation.ConversationID, ID: messageID, Content: newContent})
|
||||
if err != nil {
|
||||
return nil, vo.WrapError(errno.ErrMessageNodeOperationFail, err, errorx.KV("cause", vo.UnwrapRootErr(err).Error()))
|
||||
}
|
||||
|
||||
return successMap, nil
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,207 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* 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 conversation
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"strconv"
|
||||
|
||||
workflowModel "github.com/coze-dev/coze-studio/backend/api/model/crossdomain/workflow"
|
||||
crossmessage "github.com/coze-dev/coze-studio/backend/crossdomain/contract/message"
|
||||
"github.com/coze-dev/coze-studio/backend/domain/workflow"
|
||||
"github.com/coze-dev/coze-studio/backend/domain/workflow/entity"
|
||||
"github.com/coze-dev/coze-studio/backend/domain/workflow/entity/vo"
|
||||
"github.com/coze-dev/coze-studio/backend/domain/workflow/internal/canvas/convert"
|
||||
"github.com/coze-dev/coze-studio/backend/domain/workflow/internal/execute"
|
||||
"github.com/coze-dev/coze-studio/backend/domain/workflow/internal/nodes"
|
||||
"github.com/coze-dev/coze-studio/backend/domain/workflow/internal/schema"
|
||||
"github.com/coze-dev/coze-studio/backend/pkg/errorx"
|
||||
"github.com/coze-dev/coze-studio/backend/pkg/lang/ptr"
|
||||
"github.com/coze-dev/coze-studio/backend/pkg/lang/ternary"
|
||||
"github.com/coze-dev/coze-studio/backend/types/errno"
|
||||
)
|
||||
|
||||
type MessageListConfig struct{}
|
||||
|
||||
type MessageList struct{}
|
||||
|
||||
func (m *MessageListConfig) Adapt(_ context.Context, n *vo.Node, _ ...nodes.AdaptOption) (*schema.NodeSchema, error) {
|
||||
ns := &schema.NodeSchema{
|
||||
Key: vo.NodeKey(n.ID),
|
||||
Type: entity.NodeTypeMessageList,
|
||||
Name: n.Data.Meta.Title,
|
||||
Configs: m,
|
||||
}
|
||||
|
||||
if err := convert.SetInputsForNodeSchema(n, ns); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err := convert.SetOutputTypesForNodeSchema(n, ns); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return ns, nil
|
||||
}
|
||||
|
||||
func (m *MessageListConfig) Build(_ context.Context, ns *schema.NodeSchema, _ ...schema.BuildOption) (any, error) {
|
||||
return &MessageList{}, nil
|
||||
}
|
||||
|
||||
func (m *MessageList) getConversationIDByName(ctx context.Context, env vo.Env, appID *int64, version, conversationName string, userID, connectorID int64) (int64, error) {
|
||||
template, isExist, err := workflow.GetRepository().GetConversationTemplate(ctx, env, vo.GetConversationTemplatePolicy{
|
||||
AppID: appID,
|
||||
Name: ptr.Of(conversationName),
|
||||
Version: ptr.Of(version),
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return 0, vo.WrapError(errno.ErrMessageNodeOperationFail, err, errorx.KV("cause", vo.UnwrapRootErr(err).Error()))
|
||||
}
|
||||
|
||||
var conversationID int64
|
||||
if isExist {
|
||||
sc, _, err := workflow.GetRepository().GetStaticConversationByTemplateID(ctx, env, userID, connectorID, template.TemplateID)
|
||||
if err != nil {
|
||||
return 0, vo.WrapError(errno.ErrMessageNodeOperationFail, err, errorx.KV("cause", vo.UnwrapRootErr(err).Error()))
|
||||
}
|
||||
if sc != nil {
|
||||
conversationID = sc.ConversationID
|
||||
}
|
||||
} else {
|
||||
dc, _, err := workflow.GetRepository().GetDynamicConversationByName(ctx, env, *appID, connectorID, userID, conversationName)
|
||||
if err != nil {
|
||||
return 0, vo.WrapError(errno.ErrMessageNodeOperationFail, err, errorx.KV("cause", vo.UnwrapRootErr(err).Error()))
|
||||
}
|
||||
if dc != nil {
|
||||
conversationID = dc.ConversationID
|
||||
}
|
||||
}
|
||||
|
||||
return conversationID, nil
|
||||
}
|
||||
|
||||
func (m *MessageList) Invoke(ctx context.Context, input map[string]any) (map[string]any, error) {
|
||||
var (
|
||||
execCtx = execute.GetExeCtx(ctx)
|
||||
env = ternary.IFElse(execCtx.ExeCfg.Mode == workflowModel.ExecuteModeRelease, vo.Online, vo.Draft)
|
||||
appID = execCtx.ExeCfg.AppID
|
||||
agentID = execCtx.ExeCfg.AgentID
|
||||
version = execCtx.ExeCfg.Version
|
||||
connectorID = execCtx.ExeCfg.ConnectorID
|
||||
userID = execCtx.ExeCfg.Operator
|
||||
)
|
||||
|
||||
conversationName, ok := input["conversationName"].(string)
|
||||
if !ok {
|
||||
return nil, vo.WrapError(errno.ErrConversationNodeInvalidOperation, errors.New("ConversationName is required"))
|
||||
}
|
||||
|
||||
var conversationID int64
|
||||
var err error
|
||||
var resolvedAppID int64
|
||||
if appID == nil {
|
||||
if conversationName != "Default" {
|
||||
return nil, vo.WrapError(errno.ErrOnlyDefaultConversationAllowInAgentScenario, errors.New("conversation node only allow in application"))
|
||||
}
|
||||
if agentID == nil || execCtx.ExeCfg.ConversationID == nil {
|
||||
return map[string]any{
|
||||
"messageList": []any{},
|
||||
"firstId": "0",
|
||||
"lastId": "0",
|
||||
"hasMore": false,
|
||||
}, nil
|
||||
}
|
||||
conversationID = *execCtx.ExeCfg.ConversationID
|
||||
resolvedAppID = *agentID
|
||||
} else {
|
||||
conversationID, err = m.getConversationIDByName(ctx, env, appID, version, conversationName, userID, connectorID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
resolvedAppID = *appID
|
||||
}
|
||||
|
||||
req := &crossmessage.MessageListRequest{
|
||||
UserID: userID,
|
||||
AppID: resolvedAppID,
|
||||
ConversationID: conversationID,
|
||||
}
|
||||
|
||||
if req.ConversationID == 0 {
|
||||
return map[string]any{
|
||||
"messageList": []any{},
|
||||
"firstId": "0",
|
||||
"lastId": "0",
|
||||
"hasMore": false,
|
||||
}, nil
|
||||
}
|
||||
|
||||
limit, ok := input["limit"].(int64)
|
||||
if ok {
|
||||
if limit > 0 && limit <= 50 {
|
||||
req.Limit = limit
|
||||
} else {
|
||||
req.Limit = 50
|
||||
}
|
||||
} else {
|
||||
req.Limit = 50
|
||||
}
|
||||
beforeID, ok := input["beforeId"].(string)
|
||||
if ok {
|
||||
|
||||
req.BeforeID = &beforeID
|
||||
}
|
||||
afterID, ok := input["afterId"].(string)
|
||||
if ok {
|
||||
|
||||
req.AfterID = &afterID
|
||||
}
|
||||
|
||||
if beforeID != "" && afterID != "" {
|
||||
return nil, vo.WrapError(errno.ErrInvalidParameter, fmt.Errorf("BeforeID and AfterID cannot be set at the same time"))
|
||||
}
|
||||
|
||||
ml, err := crossmessage.DefaultSVC().MessageList(ctx, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var messageList []any
|
||||
for _, msg := range ml.Messages {
|
||||
content, err := nodes.ConvertMessageToString(ctx, msg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
messageList = append(messageList, map[string]any{
|
||||
"messageId": strconv.FormatInt(msg.ID, 10),
|
||||
"role": string(msg.Role),
|
||||
"contentType": msg.ContentType,
|
||||
"content": content,
|
||||
})
|
||||
}
|
||||
|
||||
return map[string]any{
|
||||
"messageList": messageList,
|
||||
"firstId": ml.FirstID,
|
||||
"lastId": ml.LastID,
|
||||
"hasMore": ml.HasMore,
|
||||
}, nil
|
||||
|
||||
}
|
||||
@@ -0,0 +1,149 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* 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 conversation
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"strconv"
|
||||
|
||||
workflowModel "github.com/coze-dev/coze-studio/backend/api/model/crossdomain/workflow"
|
||||
|
||||
wf "github.com/coze-dev/coze-studio/backend/domain/workflow"
|
||||
"github.com/coze-dev/coze-studio/backend/domain/workflow/entity"
|
||||
"github.com/coze-dev/coze-studio/backend/domain/workflow/entity/vo"
|
||||
"github.com/coze-dev/coze-studio/backend/domain/workflow/internal/canvas/convert"
|
||||
"github.com/coze-dev/coze-studio/backend/domain/workflow/internal/execute"
|
||||
"github.com/coze-dev/coze-studio/backend/domain/workflow/internal/nodes"
|
||||
"github.com/coze-dev/coze-studio/backend/domain/workflow/internal/schema"
|
||||
"github.com/coze-dev/coze-studio/backend/pkg/lang/ptr"
|
||||
"github.com/coze-dev/coze-studio/backend/pkg/lang/ternary"
|
||||
"github.com/coze-dev/coze-studio/backend/types/errno"
|
||||
)
|
||||
|
||||
type UpdateConversationConfig struct{}
|
||||
|
||||
type UpdateConversation struct{}
|
||||
|
||||
func (c *UpdateConversationConfig) Adapt(_ context.Context, n *vo.Node, _ ...nodes.AdaptOption) (*schema.NodeSchema, error) {
|
||||
ns := &schema.NodeSchema{
|
||||
Key: vo.NodeKey(n.ID),
|
||||
Type: entity.NodeTypeConversationUpdate,
|
||||
Name: n.Data.Meta.Title,
|
||||
Configs: c,
|
||||
}
|
||||
|
||||
if err := convert.SetInputsForNodeSchema(n, ns); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err := convert.SetOutputTypesForNodeSchema(n, ns); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return ns, nil
|
||||
}
|
||||
|
||||
func (c *UpdateConversationConfig) Build(_ context.Context, ns *schema.NodeSchema, _ ...schema.BuildOption) (any, error) {
|
||||
return &UpdateConversation{}, nil
|
||||
}
|
||||
|
||||
func (c *UpdateConversation) Invoke(ctx context.Context, in map[string]any) (map[string]any, error) {
|
||||
|
||||
var (
|
||||
execCtx = execute.GetExeCtx(ctx)
|
||||
env = ternary.IFElse(execCtx.ExeCfg.Mode == workflowModel.ExecuteModeRelease, vo.Online, vo.Draft)
|
||||
appID = execCtx.ExeCfg.AppID
|
||||
agentID = execCtx.ExeCfg.AgentID
|
||||
version = execCtx.ExeCfg.Version
|
||||
connectorID = execCtx.ExeCfg.ConnectorID
|
||||
userID = execCtx.ExeCfg.Operator
|
||||
)
|
||||
cName, ok := in["conversationName"]
|
||||
if !ok {
|
||||
return nil, vo.WrapError(errno.ErrInvalidParameter, errors.New("conversation name is required"))
|
||||
}
|
||||
|
||||
conversationName := cName.(string)
|
||||
|
||||
ncName, ok := in["newConversationName"]
|
||||
if !ok {
|
||||
return nil, vo.WrapError(errno.ErrInvalidParameter, errors.New("new conversationName name is required"))
|
||||
}
|
||||
|
||||
newConversationName := ncName.(string)
|
||||
|
||||
if agentID != nil {
|
||||
return nil, vo.WrapError(errno.ErrConversationNodesNotAvailable, fmt.Errorf("in the agent scenario, update conversation is not available"))
|
||||
}
|
||||
|
||||
if appID == nil {
|
||||
return nil, vo.WrapError(errno.ErrConversationNodesNotAvailable, errors.New("conversation update node, app id is required"))
|
||||
}
|
||||
|
||||
_, existed, err := wf.GetRepository().GetConversationTemplate(ctx, env, vo.GetConversationTemplatePolicy{
|
||||
AppID: appID,
|
||||
Name: ptr.Of(conversationName),
|
||||
Version: ptr.Of(version),
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if existed {
|
||||
return nil, vo.WrapError(errno.ErrConversationNodeInvalidOperation, fmt.Errorf("only conversation created through nodes are allowed to be modified or deleted"))
|
||||
}
|
||||
|
||||
conversation, existed, err := wf.GetRepository().GetDynamicConversationByName(ctx, env, *appID, connectorID, userID, conversationName)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if !existed {
|
||||
return map[string]any{
|
||||
"conversationId": "0",
|
||||
"isSuccess": false,
|
||||
"isExisted": false,
|
||||
}, nil
|
||||
}
|
||||
|
||||
ncConversation, existed, err := wf.GetRepository().GetDynamicConversationByName(ctx, env, *appID, connectorID, userID, newConversationName)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if existed {
|
||||
return map[string]any{
|
||||
"conversationId": strconv.FormatInt(ncConversation.ConversationID, 10),
|
||||
"isSuccess": false,
|
||||
"isExisted": true,
|
||||
}, nil
|
||||
}
|
||||
|
||||
err = wf.GetRepository().UpdateDynamicConversationNameByID(ctx, env, conversation.ID, newConversationName)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return map[string]any{
|
||||
"conversationId": strconv.FormatInt(conversation.ConversationID, 10),
|
||||
"isSuccess": true,
|
||||
"isExisted": false,
|
||||
}, nil
|
||||
|
||||
}
|
||||
@@ -20,6 +20,7 @@ import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"maps"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
@@ -29,21 +30,26 @@ import (
|
||||
"github.com/spf13/cast"
|
||||
|
||||
model "github.com/coze-dev/coze-studio/backend/api/model/crossdomain/modelmgr"
|
||||
crossmessage "github.com/coze-dev/coze-studio/backend/crossdomain/contract/message"
|
||||
crossmodelmgr "github.com/coze-dev/coze-studio/backend/crossdomain/contract/modelmgr"
|
||||
"github.com/coze-dev/coze-studio/backend/domain/workflow/entity"
|
||||
"github.com/coze-dev/coze-studio/backend/domain/workflow/entity/vo"
|
||||
"github.com/coze-dev/coze-studio/backend/domain/workflow/internal/canvas/convert"
|
||||
"github.com/coze-dev/coze-studio/backend/domain/workflow/internal/execute"
|
||||
"github.com/coze-dev/coze-studio/backend/domain/workflow/internal/nodes"
|
||||
schema2 "github.com/coze-dev/coze-studio/backend/domain/workflow/internal/schema"
|
||||
"github.com/coze-dev/coze-studio/backend/pkg/ctxcache"
|
||||
"github.com/coze-dev/coze-studio/backend/pkg/lang/ternary"
|
||||
"github.com/coze-dev/coze-studio/backend/pkg/logs"
|
||||
"github.com/coze-dev/coze-studio/backend/pkg/sonic"
|
||||
)
|
||||
|
||||
type Config struct {
|
||||
Intents []string
|
||||
SystemPrompt string
|
||||
IsFastMode bool
|
||||
LLMParams *model.LLMParams
|
||||
Intents []string
|
||||
SystemPrompt string
|
||||
IsFastMode bool
|
||||
LLMParams *model.LLMParams
|
||||
ChatHistorySetting *vo.ChatHistorySetting
|
||||
}
|
||||
|
||||
func (c *Config) Adapt(_ context.Context, n *vo.Node, _ ...nodes.AdaptOption) (*schema2.NodeSchema, error) {
|
||||
@@ -59,6 +65,10 @@ func (c *Config) Adapt(_ context.Context, n *vo.Node, _ ...nodes.AdaptOption) (*
|
||||
return nil, fmt.Errorf("intent detector node's llmParam is nil")
|
||||
}
|
||||
|
||||
if n.Data.Inputs.ChatHistorySetting != nil {
|
||||
c.ChatHistorySetting = n.Data.Inputs.ChatHistorySetting
|
||||
}
|
||||
|
||||
llmParam, ok := param.(vo.IntentDetectorLLMParam)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("llm node's llmParam must be LLMParam, got %v", llmParam)
|
||||
@@ -141,14 +151,16 @@ func (c *Config) Build(ctx context.Context, _ *schema2.NodeSchema, _ ...schema2.
|
||||
&schema.Message{Content: sptTemplate, Role: schema.System},
|
||||
&schema.Message{Content: "{{query}}", Role: schema.User})
|
||||
|
||||
r, err := chain.AppendChatTemplate(prompts).AppendChatModel(m).Compile(ctx)
|
||||
r, err := chain.AppendChatTemplate(newHistoryChatTemplate(prompts, c.ChatHistorySetting)).AppendChatModel(m).Compile(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &IntentDetector{
|
||||
isFastMode: c.IsFastMode,
|
||||
systemPrompt: c.SystemPrompt,
|
||||
runner: r,
|
||||
isFastMode: c.IsFastMode,
|
||||
systemPrompt: c.SystemPrompt,
|
||||
runner: r,
|
||||
ChatHistorySetting: c.ChatHistorySetting,
|
||||
}, nil
|
||||
}
|
||||
|
||||
@@ -182,6 +194,10 @@ func (c *Config) ExpectPorts(ctx context.Context, n *vo.Node) []string {
|
||||
return expects
|
||||
}
|
||||
|
||||
type contextKey string
|
||||
|
||||
const chatHistoryKey contextKey = "chatHistory"
|
||||
|
||||
const SystemIntentPrompt = `
|
||||
# Role
|
||||
You are an intention classification expert, good at being able to judge which classification the user's input belongs to.
|
||||
@@ -240,9 +256,10 @@ Note:
|
||||
const classificationID = "classificationId"
|
||||
|
||||
type IntentDetector struct {
|
||||
isFastMode bool
|
||||
systemPrompt string
|
||||
runner compose.Runnable[map[string]any, *schema.Message]
|
||||
isFastMode bool
|
||||
systemPrompt string
|
||||
runner compose.Runnable[map[string]any, *schema.Message]
|
||||
ChatHistorySetting *vo.ChatHistorySetting
|
||||
}
|
||||
|
||||
func (id *IntentDetector) parseToNodeOut(content string) (map[string]any, error) {
|
||||
@@ -320,3 +337,66 @@ func toIntentString(its []string) (string, error) {
|
||||
|
||||
return sonic.MarshalString(vs)
|
||||
}
|
||||
|
||||
func (id *IntentDetector) ToCallbackInput(ctx context.Context, in map[string]any) (map[string]any, error) {
|
||||
if id.ChatHistorySetting == nil || !id.ChatHistorySetting.EnableChatHistory {
|
||||
return in, nil
|
||||
}
|
||||
|
||||
var messages []*crossmessage.WfMessage
|
||||
var scMessages []*schema.Message
|
||||
var sectionID *int64
|
||||
execCtx := execute.GetExeCtx(ctx)
|
||||
if execCtx != nil {
|
||||
messages = execCtx.ExeCfg.ConversationHistory
|
||||
scMessages = execCtx.ExeCfg.ConversationHistorySchemaMessages
|
||||
sectionID = execCtx.ExeCfg.SectionID
|
||||
}
|
||||
|
||||
ret := map[string]any{
|
||||
"chatHistory": []any{},
|
||||
}
|
||||
maps.Copy(ret, in)
|
||||
|
||||
if len(messages) == 0 {
|
||||
return ret, nil
|
||||
}
|
||||
if sectionID != nil && messages[0].SectionID != *sectionID {
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
maxRounds := int(id.ChatHistorySetting.ChatHistoryRound)
|
||||
if execCtx != nil && execCtx.ExeCfg.MaxHistoryRounds != nil {
|
||||
maxRounds = min(int(*execCtx.ExeCfg.MaxHistoryRounds), maxRounds)
|
||||
}
|
||||
|
||||
count := 0
|
||||
startIdx := 0
|
||||
for i := len(messages) - 1; i >= 0; i-- {
|
||||
if messages[i].Role == schema.User {
|
||||
count++
|
||||
}
|
||||
if count >= maxRounds {
|
||||
startIdx = i
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
var historyMessages []any
|
||||
for _, msg := range messages[startIdx:] {
|
||||
content, err := nodes.ConvertMessageToString(ctx, msg)
|
||||
if err != nil {
|
||||
logs.CtxWarnf(ctx, "failed to convert message to string: %v", err)
|
||||
continue
|
||||
}
|
||||
historyMessages = append(historyMessages, map[string]any{
|
||||
"role": string(msg.Role),
|
||||
"content": content,
|
||||
})
|
||||
}
|
||||
|
||||
ctxcache.Store(ctx, chatHistoryKey, scMessages[startIdx:])
|
||||
|
||||
ret["chatHistory"] = historyMessages
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
@@ -0,0 +1,85 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* 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 intentdetector
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"github.com/cloudwego/eino/components/prompt"
|
||||
"github.com/cloudwego/eino/schema"
|
||||
|
||||
"github.com/coze-dev/coze-studio/backend/api/model/workflow"
|
||||
"github.com/coze-dev/coze-studio/backend/domain/workflow/entity/vo"
|
||||
"github.com/coze-dev/coze-studio/backend/domain/workflow/internal/execute"
|
||||
"github.com/coze-dev/coze-studio/backend/pkg/ctxcache"
|
||||
"github.com/coze-dev/coze-studio/backend/pkg/logs"
|
||||
)
|
||||
|
||||
type historyChatTemplate struct {
|
||||
basePrompt prompt.ChatTemplate
|
||||
chatHistorySetting *vo.ChatHistorySetting
|
||||
}
|
||||
|
||||
func newHistoryChatTemplate(basePrompt prompt.ChatTemplate, chatHistorySetting *vo.ChatHistorySetting) prompt.ChatTemplate {
|
||||
return &historyChatTemplate{
|
||||
basePrompt: basePrompt,
|
||||
chatHistorySetting: chatHistorySetting,
|
||||
}
|
||||
}
|
||||
|
||||
func (t *historyChatTemplate) Format(ctx context.Context, vs map[string]any, opts ...prompt.Option) ([]*schema.Message, error) {
|
||||
baseMessages, err := t.basePrompt.Format(ctx, vs, opts...)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to format base prompt: %w", err)
|
||||
}
|
||||
if len(baseMessages) == 0 {
|
||||
return nil, fmt.Errorf("base prompt returned no messages")
|
||||
}
|
||||
|
||||
if t.chatHistorySetting == nil || !t.chatHistorySetting.EnableChatHistory {
|
||||
return baseMessages, nil
|
||||
}
|
||||
|
||||
exeCtx := execute.GetExeCtx(ctx)
|
||||
if exeCtx == nil {
|
||||
logs.CtxWarnf(ctx, "execute context is nil, skipping chat history")
|
||||
return baseMessages, nil
|
||||
}
|
||||
|
||||
if exeCtx.ExeCfg.WorkflowMode != workflow.WorkflowMode_ChatFlow {
|
||||
return baseMessages, nil
|
||||
}
|
||||
|
||||
historyMessages, ok := ctxcache.Get[[]*schema.Message](ctx, chatHistoryKey)
|
||||
if !ok || len(historyMessages) == 0 {
|
||||
logs.CtxWarnf(ctx, "conversation history is empty")
|
||||
return baseMessages, nil
|
||||
}
|
||||
|
||||
if len(historyMessages) == 0 {
|
||||
return baseMessages, nil
|
||||
}
|
||||
|
||||
finalMessages := make([]*schema.Message, 0, len(baseMessages)+len(historyMessages))
|
||||
finalMessages = append(finalMessages, baseMessages[0]) // System prompt
|
||||
finalMessages = append(finalMessages, historyMessages...)
|
||||
if len(baseMessages) > 1 {
|
||||
finalMessages = append(finalMessages, baseMessages[1:]...) // User prompt and any others
|
||||
}
|
||||
|
||||
return finalMessages, nil
|
||||
}
|
||||
@@ -19,24 +19,37 @@ package knowledge
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"maps"
|
||||
|
||||
"github.com/spf13/cast"
|
||||
|
||||
einoSchema "github.com/cloudwego/eino/schema"
|
||||
|
||||
"github.com/coze-dev/coze-studio/backend/api/model/crossdomain/knowledge"
|
||||
"github.com/coze-dev/coze-studio/backend/api/model/workflow"
|
||||
crossknowledge "github.com/coze-dev/coze-studio/backend/crossdomain/contract/knowledge"
|
||||
crossmessage "github.com/coze-dev/coze-studio/backend/crossdomain/contract/message"
|
||||
"github.com/coze-dev/coze-studio/backend/domain/workflow/entity"
|
||||
"github.com/coze-dev/coze-studio/backend/domain/workflow/entity/vo"
|
||||
"github.com/coze-dev/coze-studio/backend/domain/workflow/internal/canvas/convert"
|
||||
"github.com/coze-dev/coze-studio/backend/domain/workflow/internal/execute"
|
||||
"github.com/coze-dev/coze-studio/backend/domain/workflow/internal/nodes"
|
||||
"github.com/coze-dev/coze-studio/backend/domain/workflow/internal/schema"
|
||||
"github.com/coze-dev/coze-studio/backend/pkg/ctxcache"
|
||||
"github.com/coze-dev/coze-studio/backend/pkg/lang/slices"
|
||||
"github.com/coze-dev/coze-studio/backend/pkg/logs"
|
||||
)
|
||||
|
||||
const outputList = "outputList"
|
||||
|
||||
type contextKey string
|
||||
|
||||
const chatHistoryKey contextKey = "chatHistory"
|
||||
|
||||
type RetrieveConfig struct {
|
||||
KnowledgeIDs []int64
|
||||
RetrievalStrategy *knowledge.RetrievalStrategy
|
||||
KnowledgeIDs []int64
|
||||
RetrievalStrategy *knowledge.RetrievalStrategy
|
||||
ChatHistorySetting *vo.ChatHistorySetting
|
||||
}
|
||||
|
||||
func (r *RetrieveConfig) Adapt(_ context.Context, n *vo.Node, _ ...nodes.AdaptOption) (*schema.NodeSchema, error) {
|
||||
@@ -60,6 +73,10 @@ func (r *RetrieveConfig) Adapt(_ context.Context, n *vo.Node, _ ...nodes.AdaptOp
|
||||
}
|
||||
r.KnowledgeIDs = knowledgeIDs
|
||||
|
||||
if inputs.ChatHistorySetting != nil {
|
||||
r.ChatHistorySetting = inputs.ChatHistorySetting
|
||||
}
|
||||
|
||||
retrievalStrategy := &knowledge.RetrievalStrategy{}
|
||||
|
||||
var getDesignatedParamContent = func(name string) (any, bool) {
|
||||
@@ -154,14 +171,16 @@ func (r *RetrieveConfig) Build(_ context.Context, _ *schema.NodeSchema, _ ...sch
|
||||
}
|
||||
|
||||
return &Retrieve{
|
||||
knowledgeIDs: r.KnowledgeIDs,
|
||||
retrievalStrategy: r.RetrievalStrategy,
|
||||
knowledgeIDs: r.KnowledgeIDs,
|
||||
retrievalStrategy: r.RetrievalStrategy,
|
||||
ChatHistorySetting: r.ChatHistorySetting,
|
||||
}, nil
|
||||
}
|
||||
|
||||
type Retrieve struct {
|
||||
knowledgeIDs []int64
|
||||
retrievalStrategy *knowledge.RetrievalStrategy
|
||||
knowledgeIDs []int64
|
||||
retrievalStrategy *knowledge.RetrievalStrategy
|
||||
ChatHistorySetting *vo.ChatHistorySetting
|
||||
}
|
||||
|
||||
func (kr *Retrieve) Invoke(ctx context.Context, input map[string]any) (map[string]any, error) {
|
||||
@@ -173,6 +192,7 @@ func (kr *Retrieve) Invoke(ctx context.Context, input map[string]any) (map[strin
|
||||
req := &knowledge.RetrieveRequest{
|
||||
Query: query,
|
||||
KnowledgeIDs: kr.knowledgeIDs,
|
||||
ChatHistory: kr.GetChatHistoryOrNil(ctx, kr.ChatHistorySetting),
|
||||
Strategy: kr.retrievalStrategy,
|
||||
}
|
||||
|
||||
@@ -190,3 +210,89 @@ func (kr *Retrieve) Invoke(ctx context.Context, input map[string]any) (map[strin
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (kr *Retrieve) GetChatHistoryOrNil(ctx context.Context, ChatHistorySetting *vo.ChatHistorySetting) []*einoSchema.Message {
|
||||
if ChatHistorySetting == nil || !ChatHistorySetting.EnableChatHistory {
|
||||
return nil
|
||||
}
|
||||
|
||||
exeCtx := execute.GetExeCtx(ctx)
|
||||
if exeCtx == nil {
|
||||
logs.CtxWarnf(ctx, "execute context is nil, skipping chat history")
|
||||
return nil
|
||||
}
|
||||
if exeCtx.ExeCfg.WorkflowMode != workflow.WorkflowMode_ChatFlow {
|
||||
return nil
|
||||
}
|
||||
|
||||
historyMessages, ok := ctxcache.Get[[]*einoSchema.Message](ctx, chatHistoryKey)
|
||||
|
||||
if !ok || len(historyMessages) == 0 {
|
||||
logs.CtxWarnf(ctx, "conversation history is empty")
|
||||
return nil
|
||||
}
|
||||
return historyMessages
|
||||
}
|
||||
|
||||
func (kr *Retrieve) ToCallbackInput(ctx context.Context, in map[string]any) (map[string]any, error) {
|
||||
if kr.ChatHistorySetting == nil || !kr.ChatHistorySetting.EnableChatHistory {
|
||||
return in, nil
|
||||
}
|
||||
|
||||
var messages []*crossmessage.WfMessage
|
||||
var scMessages []*einoSchema.Message
|
||||
var sectionID *int64
|
||||
execCtx := execute.GetExeCtx(ctx)
|
||||
if execCtx != nil {
|
||||
messages = execCtx.ExeCfg.ConversationHistory
|
||||
scMessages = execCtx.ExeCfg.ConversationHistorySchemaMessages
|
||||
sectionID = execCtx.ExeCfg.SectionID
|
||||
}
|
||||
|
||||
ret := map[string]any{
|
||||
"chatHistory": []any{},
|
||||
}
|
||||
maps.Copy(ret, in)
|
||||
|
||||
if len(messages) == 0 {
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
if sectionID != nil && messages[0].SectionID != *sectionID {
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
maxRounds := int(kr.ChatHistorySetting.ChatHistoryRound)
|
||||
if execCtx != nil && execCtx.ExeCfg.MaxHistoryRounds != nil {
|
||||
maxRounds = min(int(*execCtx.ExeCfg.MaxHistoryRounds), maxRounds)
|
||||
}
|
||||
|
||||
count := 0
|
||||
startIdx := 0
|
||||
for i := len(messages) - 1; i >= 0; i-- {
|
||||
if messages[i].Role == einoSchema.User {
|
||||
count++
|
||||
}
|
||||
if count >= maxRounds {
|
||||
startIdx = i
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
var historyMessages []any
|
||||
for _, msg := range messages[startIdx:] {
|
||||
content, err := nodes.ConvertMessageToString(ctx, msg)
|
||||
if err != nil {
|
||||
logs.CtxWarnf(ctx, "failed to convert message to string: %v", err)
|
||||
continue
|
||||
}
|
||||
historyMessages = append(historyMessages, map[string]any{
|
||||
"role": string(msg.Role),
|
||||
"content": content,
|
||||
})
|
||||
}
|
||||
ctxcache.Store(ctx, chatHistoryKey, scMessages[startIdx:])
|
||||
|
||||
ret["chatHistory"] = historyMessages
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
@@ -40,6 +40,7 @@ import (
|
||||
workflowModel "github.com/coze-dev/coze-studio/backend/api/model/crossdomain/workflow"
|
||||
workflow3 "github.com/coze-dev/coze-studio/backend/api/model/workflow"
|
||||
crossknowledge "github.com/coze-dev/coze-studio/backend/crossdomain/contract/knowledge"
|
||||
crossmessage "github.com/coze-dev/coze-studio/backend/crossdomain/contract/message"
|
||||
crossmodelmgr "github.com/coze-dev/coze-studio/backend/crossdomain/contract/modelmgr"
|
||||
crossplugin "github.com/coze-dev/coze-studio/backend/crossdomain/contract/plugin"
|
||||
"github.com/coze-dev/coze-studio/backend/domain/workflow"
|
||||
@@ -59,6 +60,10 @@ import (
|
||||
"github.com/coze-dev/coze-studio/backend/types/errno"
|
||||
)
|
||||
|
||||
type contextKey string
|
||||
|
||||
const chatHistoryKey contextKey = "chatHistory"
|
||||
|
||||
type Format int
|
||||
|
||||
const (
|
||||
@@ -167,12 +172,14 @@ type KnowledgeRecallConfig struct {
|
||||
}
|
||||
|
||||
type Config struct {
|
||||
SystemPrompt string
|
||||
UserPrompt string
|
||||
OutputFormat Format
|
||||
LLMParams *crossmodel.LLMParams
|
||||
FCParam *vo.FCParam
|
||||
BackupLLMParams *crossmodel.LLMParams
|
||||
SystemPrompt string
|
||||
UserPrompt string
|
||||
OutputFormat Format
|
||||
LLMParams *crossmodel.LLMParams
|
||||
FCParam *vo.FCParam
|
||||
BackupLLMParams *crossmodel.LLMParams
|
||||
ChatHistorySetting *vo.ChatHistorySetting
|
||||
AssociateStartNodeUserInputFields map[string]struct{}
|
||||
}
|
||||
|
||||
func (c *Config) Adapt(_ context.Context, n *vo.Node, _ ...nodes.AdaptOption) (*schema2.NodeSchema, error) {
|
||||
@@ -202,6 +209,13 @@ func (c *Config) Adapt(_ context.Context, n *vo.Node, _ ...nodes.AdaptOption) (*
|
||||
c.SystemPrompt = convertedLLMParam.SystemPrompt
|
||||
c.UserPrompt = convertedLLMParam.Prompt
|
||||
|
||||
if convertedLLMParam.EnableChatHistory {
|
||||
c.ChatHistorySetting = &vo.ChatHistorySetting{
|
||||
EnableChatHistory: true,
|
||||
ChatHistoryRound: convertedLLMParam.ChatHistoryRound,
|
||||
}
|
||||
}
|
||||
|
||||
var resFormat Format
|
||||
switch convertedLLMParam.ResponseFormat {
|
||||
case crossmodel.ResponseFormatText:
|
||||
@@ -273,6 +287,15 @@ func (c *Config) Adapt(_ context.Context, n *vo.Node, _ ...nodes.AdaptOption) (*
|
||||
}
|
||||
}
|
||||
|
||||
c.AssociateStartNodeUserInputFields = make(map[string]struct{})
|
||||
for _, info := range ns.InputSources {
|
||||
if len(info.Path) == 1 && info.Source.Ref != nil && info.Source.Ref.FromNodeKey == entity.EntryNodeKey {
|
||||
if compose.FromFieldPath(info.Source.Ref.FromPath).Equals(compose.FromField("USER_INPUT")) {
|
||||
c.AssociateStartNodeUserInputFields[info.Path[0]] = struct{}{}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ns, nil
|
||||
}
|
||||
|
||||
@@ -320,7 +343,14 @@ func llmParamsToLLMParam(params vo.LLMParam) (*crossmodel.LLMParams, error) {
|
||||
case "systemPrompt":
|
||||
strVal := param.Input.Value.Content.(string)
|
||||
p.SystemPrompt = strVal
|
||||
case "chatHistoryRound", "generationDiversity", "frequencyPenalty", "presencePenalty":
|
||||
case "chatHistoryRound":
|
||||
strVal := param.Input.Value.Content.(string)
|
||||
int64Val, err := strconv.ParseInt(strVal, 10, 64)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
p.ChatHistoryRound = int64Val
|
||||
case "generationDiversity", "frequencyPenalty", "presencePenalty":
|
||||
// do nothing
|
||||
case "topP":
|
||||
strVal := param.Input.Value.Content.(string)
|
||||
@@ -590,11 +620,12 @@ func (c *Config) Build(ctx context.Context, ns *schema2.NodeSchema, _ ...schema2
|
||||
inputs[knowledgeUserPromptTemplateKey] = &vo.TypeInfo{
|
||||
Type: vo.DataTypeString,
|
||||
}
|
||||
sp := newPromptTpl(schema.System, c.SystemPrompt, inputs, nil)
|
||||
up := newPromptTpl(schema.User, userPrompt, inputs, []string{knowledgeUserPromptTemplateKey})
|
||||
sp := newPromptTpl(schema.System, c.SystemPrompt, inputs)
|
||||
up := newPromptTpl(schema.User, userPrompt, inputs, withReservedKeys([]string{knowledgeUserPromptTemplateKey}), withAssociateUserInputFields(c.AssociateStartNodeUserInputFields))
|
||||
template := newPrompts(sp, up, modelWithInfo)
|
||||
templateWithChatHistory := newPromptsWithChatHistory(template, c.ChatHistorySetting)
|
||||
|
||||
_ = g.AddChatTemplateNode(templateNodeKey, template,
|
||||
_ = g.AddChatTemplateNode(templateNodeKey, templateWithChatHistory,
|
||||
compose.WithStatePreHandler(func(ctx context.Context, in map[string]any, state llmState) (map[string]any, error) {
|
||||
for k, v := range state {
|
||||
in[k] = v
|
||||
@@ -604,10 +635,12 @@ func (c *Config) Build(ctx context.Context, ns *schema2.NodeSchema, _ ...schema2
|
||||
_ = g.AddEdge(knowledgeLambdaKey, templateNodeKey)
|
||||
|
||||
} else {
|
||||
sp := newPromptTpl(schema.System, c.SystemPrompt, ns.InputTypes, nil)
|
||||
up := newPromptTpl(schema.User, userPrompt, ns.InputTypes, nil)
|
||||
sp := newPromptTpl(schema.System, c.SystemPrompt, ns.InputTypes)
|
||||
up := newPromptTpl(schema.User, userPrompt, ns.InputTypes, withAssociateUserInputFields(c.AssociateStartNodeUserInputFields))
|
||||
template := newPrompts(sp, up, modelWithInfo)
|
||||
_ = g.AddChatTemplateNode(templateNodeKey, template)
|
||||
templateWithChatHistory := newPromptsWithChatHistory(template, c.ChatHistorySetting)
|
||||
|
||||
_ = g.AddChatTemplateNode(templateNodeKey, templateWithChatHistory)
|
||||
|
||||
_ = g.AddEdge(compose.START, templateNodeKey)
|
||||
}
|
||||
@@ -747,10 +780,11 @@ func (c *Config) Build(ctx context.Context, ns *schema2.NodeSchema, _ ...schema2
|
||||
}
|
||||
|
||||
llm := &LLM{
|
||||
r: r,
|
||||
outputFormat: format,
|
||||
requireCheckpoint: requireCheckpoint,
|
||||
fullSources: ns.FullSources,
|
||||
r: r,
|
||||
outputFormat: format,
|
||||
requireCheckpoint: requireCheckpoint,
|
||||
fullSources: ns.FullSources,
|
||||
chatHistorySetting: c.ChatHistorySetting,
|
||||
}
|
||||
|
||||
return llm, nil
|
||||
@@ -825,10 +859,11 @@ func toRetrievalSearchType(s int64) (knowledge.SearchType, error) {
|
||||
}
|
||||
|
||||
type LLM struct {
|
||||
r compose.Runnable[map[string]any, map[string]any]
|
||||
outputFormat Format
|
||||
requireCheckpoint bool
|
||||
fullSources map[string]*schema2.SourceInfo
|
||||
r compose.Runnable[map[string]any, map[string]any]
|
||||
outputFormat Format
|
||||
requireCheckpoint bool
|
||||
fullSources map[string]*schema2.SourceInfo
|
||||
chatHistorySetting *vo.ChatHistorySetting
|
||||
}
|
||||
|
||||
const (
|
||||
@@ -1193,6 +1228,68 @@ type ToolInterruptEventStore interface {
|
||||
ResumeToolInterruptEvent(llmNodeKey vo.NodeKey, toolCallID string) (string, error)
|
||||
}
|
||||
|
||||
func (l *LLM) ToCallbackInput(ctx context.Context, input map[string]any) (map[string]any, error) {
|
||||
if l.chatHistorySetting == nil || !l.chatHistorySetting.EnableChatHistory {
|
||||
return input, nil
|
||||
}
|
||||
|
||||
var messages []*crossmessage.WfMessage
|
||||
var scMessages []*schema.Message
|
||||
var sectionID *int64
|
||||
execCtx := execute.GetExeCtx(ctx)
|
||||
if execCtx != nil {
|
||||
messages = execCtx.ExeCfg.ConversationHistory
|
||||
scMessages = execCtx.ExeCfg.ConversationHistorySchemaMessages
|
||||
sectionID = execCtx.ExeCfg.SectionID
|
||||
}
|
||||
|
||||
ret := map[string]any{
|
||||
"chatHistory": []any{},
|
||||
}
|
||||
maps.Copy(ret, input)
|
||||
|
||||
if len(messages) == 0 {
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
if sectionID != nil && messages[0].SectionID != *sectionID {
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
maxRounds := int(l.chatHistorySetting.ChatHistoryRound)
|
||||
if execCtx != nil && execCtx.ExeCfg.MaxHistoryRounds != nil {
|
||||
maxRounds = min(int(*execCtx.ExeCfg.MaxHistoryRounds), maxRounds)
|
||||
}
|
||||
count := 0
|
||||
startIdx := 0
|
||||
for i := len(messages) - 1; i >= 0; i-- {
|
||||
if messages[i].Role == schema.User {
|
||||
count++
|
||||
}
|
||||
if count >= maxRounds {
|
||||
startIdx = i
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
var historyMessages []any
|
||||
for _, msg := range messages[startIdx:] {
|
||||
content, err := nodes.ConvertMessageToString(ctx, msg)
|
||||
if err != nil {
|
||||
logs.CtxWarnf(ctx, "failed to convert message to string: %v", err)
|
||||
continue
|
||||
}
|
||||
historyMessages = append(historyMessages, map[string]any{
|
||||
"role": string(msg.Role),
|
||||
"content": content,
|
||||
})
|
||||
}
|
||||
ctxcache.Store(ctx, chatHistoryKey, scMessages[startIdx:])
|
||||
|
||||
ret["chatHistory"] = historyMessages
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func (l *LLM) ToCallbackOutput(ctx context.Context, output map[string]any) (*nodes.StructuredCallbackOutput, error) {
|
||||
c := execute.GetExeCtx(ctx)
|
||||
if c == nil {
|
||||
|
||||
@@ -23,12 +23,14 @@ import (
|
||||
"github.com/cloudwego/eino/components/prompt"
|
||||
"github.com/cloudwego/eino/schema"
|
||||
|
||||
"github.com/coze-dev/coze-studio/backend/api/model/workflow"
|
||||
"github.com/coze-dev/coze-studio/backend/domain/workflow/entity/vo"
|
||||
"github.com/coze-dev/coze-studio/backend/domain/workflow/internal/execute"
|
||||
"github.com/coze-dev/coze-studio/backend/domain/workflow/internal/nodes"
|
||||
schema2 "github.com/coze-dev/coze-studio/backend/domain/workflow/internal/schema"
|
||||
"github.com/coze-dev/coze-studio/backend/infra/contract/modelmgr"
|
||||
"github.com/coze-dev/coze-studio/backend/pkg/ctxcache"
|
||||
"github.com/coze-dev/coze-studio/backend/pkg/logs"
|
||||
"github.com/coze-dev/coze-studio/backend/pkg/sonic"
|
||||
)
|
||||
|
||||
@@ -38,12 +40,30 @@ type prompts struct {
|
||||
mwi ModelWithInfo
|
||||
}
|
||||
|
||||
type promptsWithChatHistory struct {
|
||||
prompts *prompts
|
||||
cfg *vo.ChatHistorySetting
|
||||
}
|
||||
|
||||
func withReservedKeys(keys []string) func(tpl *promptTpl) {
|
||||
return func(tpl *promptTpl) {
|
||||
tpl.reservedKeys = keys
|
||||
}
|
||||
}
|
||||
|
||||
func withAssociateUserInputFields(fs map[string]struct{}) func(tpl *promptTpl) {
|
||||
return func(tpl *promptTpl) {
|
||||
tpl.associateUserInputFields = fs
|
||||
}
|
||||
}
|
||||
|
||||
type promptTpl struct {
|
||||
role schema.RoleType
|
||||
tpl string
|
||||
parts []promptPart
|
||||
hasMultiModal bool
|
||||
reservedKeys []string
|
||||
role schema.RoleType
|
||||
tpl string
|
||||
parts []promptPart
|
||||
hasMultiModal bool
|
||||
reservedKeys []string
|
||||
associateUserInputFields map[string]struct{}
|
||||
}
|
||||
|
||||
type promptPart struct {
|
||||
@@ -54,12 +74,20 @@ type promptPart struct {
|
||||
func newPromptTpl(role schema.RoleType,
|
||||
tpl string,
|
||||
inputTypes map[string]*vo.TypeInfo,
|
||||
reservedKeys []string,
|
||||
opts ...func(*promptTpl),
|
||||
) *promptTpl {
|
||||
if len(tpl) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
pTpl := &promptTpl{
|
||||
role: role,
|
||||
tpl: tpl,
|
||||
}
|
||||
for _, opt := range opts {
|
||||
opt(pTpl)
|
||||
}
|
||||
|
||||
parts := nodes.ParseTemplate(tpl)
|
||||
promptParts := make([]promptPart, 0, len(parts))
|
||||
hasMultiModal := false
|
||||
@@ -87,14 +115,10 @@ func newPromptTpl(role schema.RoleType,
|
||||
|
||||
hasMultiModal = true
|
||||
}
|
||||
pTpl.parts = promptParts
|
||||
pTpl.hasMultiModal = hasMultiModal
|
||||
|
||||
return &promptTpl{
|
||||
role: role,
|
||||
tpl: tpl,
|
||||
parts: promptParts,
|
||||
hasMultiModal: hasMultiModal,
|
||||
reservedKeys: reservedKeys,
|
||||
}
|
||||
return pTpl
|
||||
}
|
||||
|
||||
const sourceKey = "sources_%s"
|
||||
@@ -107,23 +131,53 @@ func newPrompts(sp, up *promptTpl, model ModelWithInfo) *prompts {
|
||||
}
|
||||
}
|
||||
|
||||
func newPromptsWithChatHistory(prompts *prompts, cfg *vo.ChatHistorySetting) *promptsWithChatHistory {
|
||||
return &promptsWithChatHistory{
|
||||
prompts: prompts,
|
||||
cfg: cfg,
|
||||
}
|
||||
}
|
||||
|
||||
func (pl *promptTpl) render(ctx context.Context, vs map[string]any,
|
||||
sources map[string]*schema2.SourceInfo,
|
||||
supportedModals map[modelmgr.Modal]bool,
|
||||
) (*schema.Message, error) {
|
||||
if !pl.hasMultiModal || len(supportedModals) == 0 {
|
||||
var opts []nodes.RenderOption
|
||||
if len(pl.reservedKeys) > 0 {
|
||||
opts = append(opts, nodes.WithReservedKey(pl.reservedKeys...))
|
||||
isChatFlow := execute.GetExeCtx(ctx).ExeCfg.WorkflowMode == workflow.WorkflowMode_ChatFlow
|
||||
userMessage := execute.GetExeCtx(ctx).ExeCfg.UserMessage
|
||||
|
||||
if !isChatFlow {
|
||||
if !pl.hasMultiModal || len(supportedModals) == 0 {
|
||||
var opts []nodes.RenderOption
|
||||
if len(pl.reservedKeys) > 0 {
|
||||
opts = append(opts, nodes.WithReservedKey(pl.reservedKeys...))
|
||||
}
|
||||
r, err := nodes.Render(ctx, pl.tpl, vs, sources, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &schema.Message{
|
||||
Role: pl.role,
|
||||
Content: r,
|
||||
}, nil
|
||||
}
|
||||
r, err := nodes.Render(ctx, pl.tpl, vs, sources, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
if (!pl.hasMultiModal || len(supportedModals) == 0) &&
|
||||
(len(pl.associateUserInputFields) == 0 ||
|
||||
(len(pl.associateUserInputFields) > 0 && userMessage != nil && userMessage.MultiContent == nil)) {
|
||||
var opts []nodes.RenderOption
|
||||
if len(pl.reservedKeys) > 0 {
|
||||
opts = append(opts, nodes.WithReservedKey(pl.reservedKeys...))
|
||||
}
|
||||
r, err := nodes.Render(ctx, pl.tpl, vs, sources, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &schema.Message{
|
||||
Role: pl.role,
|
||||
Content: r,
|
||||
}, nil
|
||||
}
|
||||
return &schema.Message{
|
||||
Role: pl.role,
|
||||
Content: r,
|
||||
}, nil
|
||||
|
||||
}
|
||||
|
||||
multiParts := make([]schema.ChatMessagePart, 0, len(pl.parts))
|
||||
@@ -141,6 +195,13 @@ func (pl *promptTpl) render(ctx context.Context, vs map[string]any,
|
||||
continue
|
||||
}
|
||||
|
||||
if _, ok := pl.associateUserInputFields[part.part.Value]; ok && userMessage != nil && isChatFlow {
|
||||
for _, p := range userMessage.MultiContent {
|
||||
multiParts = append(multiParts, transformMessagePart(p, supportedModals))
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
skipped, invalid := part.part.Skipped(sources)
|
||||
if invalid {
|
||||
var reserved bool
|
||||
@@ -164,6 +225,7 @@ func (pl *promptTpl) render(ctx context.Context, vs map[string]any,
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if part.fileType == nil {
|
||||
multiParts = append(multiParts, schema.ChatMessagePart{
|
||||
Type: schema.ChatMessagePartTypeText,
|
||||
@@ -172,64 +234,38 @@ func (pl *promptTpl) render(ctx context.Context, vs map[string]any,
|
||||
continue
|
||||
}
|
||||
|
||||
var originalPart schema.ChatMessagePart
|
||||
switch *part.fileType {
|
||||
case vo.FileTypeImage, vo.FileTypeSVG:
|
||||
if _, ok := supportedModals[modelmgr.ModalImage]; !ok {
|
||||
multiParts = append(multiParts, schema.ChatMessagePart{
|
||||
Type: schema.ChatMessagePartTypeText,
|
||||
Text: r,
|
||||
})
|
||||
} else {
|
||||
multiParts = append(multiParts, schema.ChatMessagePart{
|
||||
Type: schema.ChatMessagePartTypeImageURL,
|
||||
ImageURL: &schema.ChatMessageImageURL{
|
||||
URL: r,
|
||||
},
|
||||
})
|
||||
originalPart = schema.ChatMessagePart{
|
||||
Type: schema.ChatMessagePartTypeImageURL,
|
||||
ImageURL: &schema.ChatMessageImageURL{
|
||||
URL: r,
|
||||
},
|
||||
}
|
||||
case vo.FileTypeAudio, vo.FileTypeVoice:
|
||||
if _, ok := supportedModals[modelmgr.ModalAudio]; !ok {
|
||||
multiParts = append(multiParts, schema.ChatMessagePart{
|
||||
Type: schema.ChatMessagePartTypeText,
|
||||
Text: r,
|
||||
})
|
||||
} else {
|
||||
multiParts = append(multiParts, schema.ChatMessagePart{
|
||||
Type: schema.ChatMessagePartTypeAudioURL,
|
||||
AudioURL: &schema.ChatMessageAudioURL{
|
||||
URL: r,
|
||||
},
|
||||
})
|
||||
originalPart = schema.ChatMessagePart{
|
||||
Type: schema.ChatMessagePartTypeAudioURL,
|
||||
AudioURL: &schema.ChatMessageAudioURL{
|
||||
URL: r,
|
||||
},
|
||||
}
|
||||
case vo.FileTypeVideo:
|
||||
if _, ok := supportedModals[modelmgr.ModalVideo]; !ok {
|
||||
multiParts = append(multiParts, schema.ChatMessagePart{
|
||||
Type: schema.ChatMessagePartTypeText,
|
||||
Text: r,
|
||||
})
|
||||
} else {
|
||||
multiParts = append(multiParts, schema.ChatMessagePart{
|
||||
Type: schema.ChatMessagePartTypeVideoURL,
|
||||
VideoURL: &schema.ChatMessageVideoURL{
|
||||
URL: r,
|
||||
},
|
||||
})
|
||||
originalPart = schema.ChatMessagePart{
|
||||
Type: schema.ChatMessagePartTypeVideoURL,
|
||||
VideoURL: &schema.ChatMessageVideoURL{
|
||||
URL: r,
|
||||
},
|
||||
}
|
||||
default:
|
||||
if _, ok := supportedModals[modelmgr.ModalFile]; !ok {
|
||||
multiParts = append(multiParts, schema.ChatMessagePart{
|
||||
Type: schema.ChatMessagePartTypeText,
|
||||
Text: r,
|
||||
})
|
||||
} else {
|
||||
multiParts = append(multiParts, schema.ChatMessagePart{
|
||||
Type: schema.ChatMessagePartTypeFileURL,
|
||||
FileURL: &schema.ChatMessageFileURL{
|
||||
URL: r,
|
||||
},
|
||||
})
|
||||
originalPart = schema.ChatMessagePart{
|
||||
Type: schema.ChatMessagePartTypeFileURL,
|
||||
FileURL: &schema.ChatMessageFileURL{
|
||||
URL: r,
|
||||
},
|
||||
}
|
||||
}
|
||||
multiParts = append(multiParts, transformMessagePart(originalPart, supportedModals))
|
||||
}
|
||||
|
||||
return &schema.Message{
|
||||
@@ -238,6 +274,40 @@ func (pl *promptTpl) render(ctx context.Context, vs map[string]any,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func transformMessagePart(part schema.ChatMessagePart, supportedModals map[modelmgr.Modal]bool) schema.ChatMessagePart {
|
||||
switch part.Type {
|
||||
case schema.ChatMessagePartTypeImageURL:
|
||||
if _, ok := supportedModals[modelmgr.ModalImage]; !ok {
|
||||
return schema.ChatMessagePart{
|
||||
Type: schema.ChatMessagePartTypeText,
|
||||
Text: part.ImageURL.URL,
|
||||
}
|
||||
}
|
||||
case schema.ChatMessagePartTypeAudioURL:
|
||||
if _, ok := supportedModals[modelmgr.ModalAudio]; !ok {
|
||||
return schema.ChatMessagePart{
|
||||
Type: schema.ChatMessagePartTypeText,
|
||||
Text: part.AudioURL.URL,
|
||||
}
|
||||
}
|
||||
case schema.ChatMessagePartTypeVideoURL:
|
||||
if _, ok := supportedModals[modelmgr.ModalVideo]; !ok {
|
||||
return schema.ChatMessagePart{
|
||||
Type: schema.ChatMessagePartTypeText,
|
||||
Text: part.VideoURL.URL,
|
||||
}
|
||||
}
|
||||
case schema.ChatMessagePartTypeFileURL:
|
||||
if _, ok := supportedModals[modelmgr.ModalFile]; !ok {
|
||||
return schema.ChatMessagePart{
|
||||
Type: schema.ChatMessagePartTypeText,
|
||||
Text: part.FileURL.URL,
|
||||
}
|
||||
}
|
||||
}
|
||||
return part
|
||||
}
|
||||
|
||||
func (p *prompts) Format(ctx context.Context, vs map[string]any, _ ...prompt.Option) (
|
||||
_ []*schema.Message, err error,
|
||||
) {
|
||||
@@ -288,3 +358,45 @@ func (p *prompts) Format(ctx context.Context, vs map[string]any, _ ...prompt.Opt
|
||||
|
||||
return []*schema.Message{systemMsg, userMsg}, nil
|
||||
}
|
||||
|
||||
func (p *promptsWithChatHistory) Format(ctx context.Context, vs map[string]any, _ ...prompt.Option) (
|
||||
[]*schema.Message, error) {
|
||||
baseMessages, err := p.prompts.Format(ctx, vs)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if p.cfg == nil || !p.cfg.EnableChatHistory {
|
||||
return baseMessages, nil
|
||||
}
|
||||
|
||||
exeCtx := execute.GetExeCtx(ctx)
|
||||
if exeCtx == nil {
|
||||
logs.CtxWarnf(ctx, "execute context is nil, skipping chat history")
|
||||
return baseMessages, nil
|
||||
}
|
||||
|
||||
if exeCtx.ExeCfg.WorkflowMode != workflow.WorkflowMode_ChatFlow {
|
||||
return baseMessages, nil
|
||||
}
|
||||
|
||||
historyMessages, ok := ctxcache.Get[[]*schema.Message](ctx, chatHistoryKey)
|
||||
|
||||
if !ok || len(historyMessages) == 0 {
|
||||
logs.CtxWarnf(ctx, "conversation history is empty")
|
||||
return baseMessages, nil
|
||||
}
|
||||
|
||||
if len(historyMessages) == 0 {
|
||||
return baseMessages, nil
|
||||
}
|
||||
|
||||
finalMessages := make([]*schema.Message, 0, len(baseMessages)+len(historyMessages))
|
||||
if len(baseMessages) > 0 && baseMessages[0].Role == schema.System {
|
||||
finalMessages = append(finalMessages, baseMessages[0])
|
||||
baseMessages = baseMessages[1:]
|
||||
}
|
||||
finalMessages = append(finalMessages, historyMessages...)
|
||||
finalMessages = append(finalMessages, baseMessages...)
|
||||
|
||||
return finalMessages, nil
|
||||
}
|
||||
|
||||
@@ -17,14 +17,17 @@
|
||||
package nodes
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"maps"
|
||||
"reflect"
|
||||
"strings"
|
||||
|
||||
"github.com/cloudwego/eino/compose"
|
||||
|
||||
crossmessage "github.com/coze-dev/coze-studio/backend/crossdomain/contract/message"
|
||||
"github.com/coze-dev/coze-studio/backend/domain/workflow/entity/vo"
|
||||
"github.com/coze-dev/coze-studio/backend/pkg/lang/ptr"
|
||||
"github.com/coze-dev/coze-studio/backend/pkg/logs"
|
||||
"github.com/coze-dev/coze-studio/backend/pkg/sonic"
|
||||
"github.com/coze-dev/coze-studio/backend/types/errno"
|
||||
@@ -279,3 +282,30 @@ func GetConcatFunc(typ reflect.Type) func(reflect.Value) (reflect.Value, error)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func ConvertMessageToString(_ context.Context, msg *crossmessage.WfMessage) (string, error) {
|
||||
if msg.MultiContent != nil {
|
||||
var textContents []string
|
||||
var otherContents []string
|
||||
for _, m := range msg.MultiContent {
|
||||
if m.Text != nil {
|
||||
textContents = append(textContents, ptr.From(m.Text))
|
||||
} else if m.Uri != nil {
|
||||
otherContents = append(otherContents, ptr.From(m.Url))
|
||||
}
|
||||
}
|
||||
|
||||
var allParts []string
|
||||
if len(textContents) > 0 {
|
||||
allParts = append(allParts, textContents...)
|
||||
}
|
||||
if len(otherContents) > 0 {
|
||||
allParts = append(allParts, otherContents...)
|
||||
}
|
||||
return strings.Join(allParts, ","), nil
|
||||
} else if msg.Text != nil {
|
||||
return ptr.From(msg.Text), nil
|
||||
} else {
|
||||
return "", vo.WrapError(errno.ErrInvalidParameter, errors.New("message is invalid"))
|
||||
}
|
||||
}
|
||||
|
||||
940
backend/domain/workflow/internal/repo/conversation_repository.go
Normal file
940
backend/domain/workflow/internal/repo/conversation_repository.go
Normal file
@@ -0,0 +1,940 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* 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 repo
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"gorm.io/gen"
|
||||
"gorm.io/gorm"
|
||||
|
||||
crossconversation "github.com/coze-dev/coze-studio/backend/crossdomain/contract/conversation"
|
||||
"github.com/coze-dev/coze-studio/backend/domain/workflow"
|
||||
"github.com/coze-dev/coze-studio/backend/domain/workflow/entity"
|
||||
"github.com/coze-dev/coze-studio/backend/domain/workflow/entity/vo"
|
||||
"github.com/coze-dev/coze-studio/backend/domain/workflow/internal/repo/dal/model"
|
||||
"github.com/coze-dev/coze-studio/backend/pkg/lang/slices"
|
||||
"github.com/coze-dev/coze-studio/backend/types/errno"
|
||||
)
|
||||
|
||||
const batchSize = 10
|
||||
|
||||
func (r *RepositoryImpl) CreateDraftConversationTemplate(ctx context.Context, template *vo.CreateConversationTemplateMeta) (int64, error) {
|
||||
id, err := r.GenID(ctx)
|
||||
if err != nil {
|
||||
return 0, vo.WrapError(errno.ErrIDGenError, err)
|
||||
}
|
||||
m := &model.AppConversationTemplateDraft{
|
||||
ID: id,
|
||||
AppID: template.AppID,
|
||||
SpaceID: template.SpaceID,
|
||||
Name: template.Name,
|
||||
CreatorID: template.UserID,
|
||||
TemplateID: id,
|
||||
}
|
||||
err = r.query.AppConversationTemplateDraft.WithContext(ctx).Create(m)
|
||||
if err != nil {
|
||||
return 0, vo.WrapError(errno.ErrDatabaseError, err)
|
||||
}
|
||||
|
||||
return id, nil
|
||||
}
|
||||
|
||||
func (r *RepositoryImpl) GetConversationTemplate(ctx context.Context, env vo.Env, policy vo.GetConversationTemplatePolicy) (*entity.ConversationTemplate, bool, error) {
|
||||
var (
|
||||
appID = policy.AppID
|
||||
name = policy.Name
|
||||
version = policy.Version
|
||||
templateID = policy.TemplateID
|
||||
)
|
||||
|
||||
conditions := make([]gen.Condition, 0)
|
||||
if env == vo.Draft {
|
||||
if appID != nil {
|
||||
conditions = append(conditions, r.query.AppConversationTemplateDraft.AppID.Eq(*appID))
|
||||
}
|
||||
if name != nil {
|
||||
conditions = append(conditions, r.query.AppConversationTemplateDraft.Name.Eq(*name))
|
||||
}
|
||||
if templateID != nil {
|
||||
conditions = append(conditions, r.query.AppConversationTemplateDraft.TemplateID.Eq(*templateID))
|
||||
}
|
||||
|
||||
template, err := r.query.AppConversationTemplateDraft.WithContext(ctx).Where(conditions...).First()
|
||||
if err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return nil, false, nil
|
||||
}
|
||||
return nil, false, vo.WrapError(errno.ErrDatabaseError, err)
|
||||
}
|
||||
return &entity.ConversationTemplate{
|
||||
AppID: template.AppID,
|
||||
Name: template.Name,
|
||||
TemplateID: template.TemplateID,
|
||||
}, true, nil
|
||||
|
||||
} else if env == vo.Online {
|
||||
if policy.Version != nil {
|
||||
conditions = append(conditions, r.query.AppConversationTemplateOnline.Version.Eq(*version))
|
||||
}
|
||||
if appID != nil {
|
||||
conditions = append(conditions, r.query.AppConversationTemplateOnline.AppID.Eq(*appID))
|
||||
}
|
||||
if name != nil {
|
||||
conditions = append(conditions, r.query.AppConversationTemplateOnline.Name.Eq(*name))
|
||||
}
|
||||
|
||||
if templateID != nil {
|
||||
conditions = append(conditions, r.query.AppConversationTemplateOnline.TemplateID.Eq(*templateID))
|
||||
}
|
||||
|
||||
template, err := r.query.AppConversationTemplateOnline.WithContext(ctx).Where(conditions...).Order(r.query.AppConversationTemplateOnline.CreatedAt.Desc()).First()
|
||||
if err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return nil, false, nil
|
||||
}
|
||||
return nil, false, err
|
||||
}
|
||||
return &entity.ConversationTemplate{
|
||||
AppID: template.AppID,
|
||||
Name: template.Name,
|
||||
TemplateID: template.TemplateID,
|
||||
}, true, nil
|
||||
}
|
||||
|
||||
return nil, false, fmt.Errorf("unknown env %v", env)
|
||||
|
||||
}
|
||||
|
||||
func (r *RepositoryImpl) UpdateDraftConversationTemplateName(ctx context.Context, templateID int64, name string) error {
|
||||
_, err := r.query.AppConversationTemplateDraft.WithContext(ctx).Where(
|
||||
r.query.AppConversationTemplateDraft.TemplateID.Eq(templateID),
|
||||
).UpdateColumnSimple(r.query.AppConversationTemplateDraft.Name.Value(name))
|
||||
|
||||
if err != nil {
|
||||
return vo.WrapError(errno.ErrDatabaseError, err)
|
||||
}
|
||||
return nil
|
||||
|
||||
}
|
||||
|
||||
func (r *RepositoryImpl) DeleteDraftConversationTemplate(ctx context.Context, templateID int64) (int64, error) {
|
||||
resultInfo, err := r.query.AppConversationTemplateDraft.WithContext(ctx).Where(
|
||||
r.query.AppConversationTemplateDraft.TemplateID.Eq(templateID),
|
||||
).Delete()
|
||||
|
||||
if err != nil {
|
||||
return 0, vo.WrapError(errno.ErrDatabaseError, err)
|
||||
}
|
||||
return resultInfo.RowsAffected, nil
|
||||
|
||||
}
|
||||
|
||||
func (r *RepositoryImpl) DeleteDynamicConversation(ctx context.Context, env vo.Env, id int64) (int64, error) {
|
||||
if env == vo.Draft {
|
||||
info, err := r.query.AppDynamicConversationDraft.WithContext(ctx).Where(r.query.AppDynamicConversationDraft.ID.Eq(id)).Delete()
|
||||
if err != nil {
|
||||
return 0, vo.WrapError(errno.ErrDatabaseError, err)
|
||||
}
|
||||
return info.RowsAffected, nil
|
||||
} else if env == vo.Online {
|
||||
info, err := r.query.AppDynamicConversationOnline.WithContext(ctx).Where(r.query.AppDynamicConversationOnline.ID.Eq(id)).Delete()
|
||||
if err != nil {
|
||||
return 0, vo.WrapError(errno.ErrDatabaseError, err)
|
||||
}
|
||||
return info.RowsAffected, nil
|
||||
} else {
|
||||
return 0, fmt.Errorf("unknown env %v", env)
|
||||
}
|
||||
}
|
||||
|
||||
func (r *RepositoryImpl) ListConversationTemplate(ctx context.Context, env vo.Env, policy *vo.ListConversationTemplatePolicy) ([]*entity.ConversationTemplate, error) {
|
||||
if env == vo.Draft {
|
||||
return r.listDraftConversationTemplate(ctx, policy)
|
||||
} else if env == vo.Online {
|
||||
return r.listOnlineConversationTemplate(ctx, policy)
|
||||
} else {
|
||||
return nil, fmt.Errorf("unknown env %v", env)
|
||||
}
|
||||
}
|
||||
|
||||
func (r *RepositoryImpl) listDraftConversationTemplate(ctx context.Context, policy *vo.ListConversationTemplatePolicy) ([]*entity.ConversationTemplate, error) {
|
||||
conditions := make([]gen.Condition, 0)
|
||||
conditions = append(conditions, r.query.AppConversationTemplateDraft.AppID.Eq(policy.AppID))
|
||||
|
||||
if policy.NameLike != nil {
|
||||
conditions = append(conditions, r.query.AppConversationTemplateDraft.Name.Like("%%"+*policy.NameLike+"%%"))
|
||||
}
|
||||
appConversationTemplateDraftDao := r.query.AppConversationTemplateDraft.WithContext(ctx)
|
||||
var (
|
||||
templates []*model.AppConversationTemplateDraft
|
||||
err error
|
||||
)
|
||||
|
||||
if policy.Page != nil {
|
||||
templates, err = appConversationTemplateDraftDao.Where(conditions...).Offset(policy.Page.Offset()).Limit(policy.Page.Limit()).Find()
|
||||
} else {
|
||||
templates, err = appConversationTemplateDraftDao.Where(conditions...).Find()
|
||||
|
||||
}
|
||||
if err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return []*entity.ConversationTemplate{}, nil
|
||||
}
|
||||
return nil, vo.WrapError(errno.ErrDatabaseError, err)
|
||||
}
|
||||
|
||||
return slices.Transform(templates, func(a *model.AppConversationTemplateDraft) *entity.ConversationTemplate {
|
||||
return &entity.ConversationTemplate{
|
||||
SpaceID: a.SpaceID,
|
||||
AppID: a.AppID,
|
||||
Name: a.Name,
|
||||
TemplateID: a.TemplateID,
|
||||
}
|
||||
}), nil
|
||||
|
||||
}
|
||||
|
||||
func (r *RepositoryImpl) listOnlineConversationTemplate(ctx context.Context, policy *vo.ListConversationTemplatePolicy) ([]*entity.ConversationTemplate, error) {
|
||||
conditions := make([]gen.Condition, 0)
|
||||
conditions = append(conditions, r.query.AppConversationTemplateOnline.AppID.Eq(policy.AppID))
|
||||
if policy.Version == nil {
|
||||
return nil, fmt.Errorf("list online template fail, version is required")
|
||||
}
|
||||
conditions = append(conditions, r.query.AppConversationTemplateOnline.Version.Eq(*policy.Version))
|
||||
|
||||
if policy.NameLike != nil {
|
||||
conditions = append(conditions, r.query.AppConversationTemplateOnline.Name.Like("%%"+*policy.NameLike+"%%"))
|
||||
}
|
||||
appConversationTemplateOnlineDao := r.query.AppConversationTemplateOnline.WithContext(ctx)
|
||||
var (
|
||||
templates []*model.AppConversationTemplateOnline
|
||||
err error
|
||||
)
|
||||
if policy.Page != nil {
|
||||
templates, err = appConversationTemplateOnlineDao.Where(conditions...).Offset(policy.Page.Offset()).Limit(policy.Page.Limit()).Find()
|
||||
|
||||
} else {
|
||||
templates, err = appConversationTemplateOnlineDao.Where(conditions...).Find()
|
||||
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return []*entity.ConversationTemplate{}, nil
|
||||
}
|
||||
return nil, vo.WrapError(errno.ErrDatabaseError, err)
|
||||
}
|
||||
|
||||
return slices.Transform(templates, func(a *model.AppConversationTemplateOnline) *entity.ConversationTemplate {
|
||||
return &entity.ConversationTemplate{
|
||||
SpaceID: a.SpaceID,
|
||||
AppID: a.AppID,
|
||||
Name: a.Name,
|
||||
TemplateID: a.TemplateID,
|
||||
}
|
||||
}), nil
|
||||
|
||||
}
|
||||
|
||||
func (r *RepositoryImpl) MGetStaticConversation(ctx context.Context, env vo.Env, userID, connectorID int64, templateIDs []int64) ([]*entity.StaticConversation, error) {
|
||||
if env == vo.Draft {
|
||||
return r.mGetDraftStaticConversation(ctx, userID, connectorID, templateIDs)
|
||||
} else if env == vo.Online {
|
||||
return r.mGetOnlineStaticConversation(ctx, userID, connectorID, templateIDs)
|
||||
} else {
|
||||
return nil, fmt.Errorf("unknown env %v", env)
|
||||
}
|
||||
}
|
||||
|
||||
func (r *RepositoryImpl) mGetDraftStaticConversation(ctx context.Context, userID, connectorID int64, templateIDs []int64) ([]*entity.StaticConversation, error) {
|
||||
conditions := make([]gen.Condition, 0, 3)
|
||||
conditions = append(conditions, r.query.AppStaticConversationDraft.UserID.Eq(userID))
|
||||
conditions = append(conditions, r.query.AppStaticConversationDraft.ConnectorID.Eq(connectorID))
|
||||
if len(templateIDs) == 1 {
|
||||
conditions = append(conditions, r.query.AppStaticConversationDraft.TemplateID.Eq(templateIDs[0]))
|
||||
} else {
|
||||
conditions = append(conditions, r.query.AppStaticConversationDraft.TemplateID.In(templateIDs...))
|
||||
}
|
||||
|
||||
cs, err := r.query.AppStaticConversationDraft.WithContext(ctx).Where(conditions...).Find()
|
||||
|
||||
if err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return []*entity.StaticConversation{}, nil
|
||||
}
|
||||
return nil, vo.WrapError(errno.ErrDatabaseError, err)
|
||||
}
|
||||
|
||||
return slices.Transform(cs, func(a *model.AppStaticConversationDraft) *entity.StaticConversation {
|
||||
return &entity.StaticConversation{
|
||||
TemplateID: a.TemplateID,
|
||||
ConversationID: a.ConversationID,
|
||||
UserID: a.UserID,
|
||||
ConnectorID: a.ConnectorID,
|
||||
}
|
||||
}), nil
|
||||
}
|
||||
|
||||
func (r *RepositoryImpl) mGetOnlineStaticConversation(ctx context.Context, userID, connectorID int64, templateIDs []int64) ([]*entity.StaticConversation, error) {
|
||||
conditions := make([]gen.Condition, 0, 3)
|
||||
conditions = append(conditions, r.query.AppStaticConversationOnline.UserID.Eq(userID))
|
||||
conditions = append(conditions, r.query.AppStaticConversationOnline.ConnectorID.Eq(connectorID))
|
||||
if len(templateIDs) == 1 {
|
||||
conditions = append(conditions, r.query.AppStaticConversationOnline.TemplateID.Eq(templateIDs[0]))
|
||||
} else {
|
||||
conditions = append(conditions, r.query.AppStaticConversationOnline.TemplateID.In(templateIDs...))
|
||||
}
|
||||
|
||||
cs, err := r.query.AppStaticConversationOnline.WithContext(ctx).Where(conditions...).Find()
|
||||
if err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return []*entity.StaticConversation{}, nil
|
||||
}
|
||||
return nil, vo.WrapError(errno.ErrDatabaseError, err)
|
||||
}
|
||||
|
||||
return slices.Transform(cs, func(a *model.AppStaticConversationOnline) *entity.StaticConversation {
|
||||
return &entity.StaticConversation{
|
||||
TemplateID: a.TemplateID,
|
||||
ConversationID: a.ConversationID,
|
||||
}
|
||||
}), nil
|
||||
}
|
||||
|
||||
func (r *RepositoryImpl) ListDynamicConversation(ctx context.Context, env vo.Env, policy *vo.ListConversationPolicy) ([]*entity.DynamicConversation, error) {
|
||||
if env == vo.Draft {
|
||||
return r.listDraftDynamicConversation(ctx, policy)
|
||||
} else if env == vo.Online {
|
||||
return r.listOnlineDynamicConversation(ctx, policy)
|
||||
} else {
|
||||
return nil, fmt.Errorf("unknown env %v", env)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func (r *RepositoryImpl) listDraftDynamicConversation(ctx context.Context, policy *vo.ListConversationPolicy) ([]*entity.DynamicConversation, error) {
|
||||
var (
|
||||
appID = policy.APPID
|
||||
userID = policy.UserID
|
||||
connectorID = policy.ConnectorID
|
||||
)
|
||||
|
||||
conditions := make([]gen.Condition, 0)
|
||||
conditions = append(conditions, r.query.AppDynamicConversationDraft.AppID.Eq(appID))
|
||||
conditions = append(conditions, r.query.AppDynamicConversationDraft.UserID.Eq(userID))
|
||||
conditions = append(conditions, r.query.AppDynamicConversationDraft.ConnectorID.Eq(connectorID))
|
||||
if policy.NameLike != nil {
|
||||
conditions = append(conditions, r.query.AppDynamicConversationDraft.Name.Like("%%"+*policy.NameLike+"%%"))
|
||||
}
|
||||
|
||||
appDynamicConversationDraftDao := r.query.AppDynamicConversationDraft.WithContext(ctx).Where(conditions...)
|
||||
var (
|
||||
dynamicConversations = make([]*model.AppDynamicConversationDraft, 0)
|
||||
err error
|
||||
)
|
||||
|
||||
if policy.Page != nil {
|
||||
dynamicConversations, err = appDynamicConversationDraftDao.Offset(policy.Page.Offset()).Limit(policy.Page.Limit()).Find()
|
||||
|
||||
} else {
|
||||
dynamicConversations, err = appDynamicConversationDraftDao.Where(conditions...).Find()
|
||||
}
|
||||
if err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return []*entity.DynamicConversation{}, nil
|
||||
}
|
||||
return nil, vo.WrapError(errno.ErrDatabaseError, err)
|
||||
}
|
||||
return slices.Transform(dynamicConversations, func(a *model.AppDynamicConversationDraft) *entity.DynamicConversation {
|
||||
return &entity.DynamicConversation{
|
||||
ID: a.ID,
|
||||
Name: a.Name,
|
||||
UserID: a.UserID,
|
||||
ConnectorID: a.ConnectorID,
|
||||
ConversationID: a.ConversationID,
|
||||
}
|
||||
}), nil
|
||||
}
|
||||
|
||||
func (r *RepositoryImpl) listOnlineDynamicConversation(ctx context.Context, policy *vo.ListConversationPolicy) ([]*entity.DynamicConversation, error) {
|
||||
var (
|
||||
appID = policy.APPID
|
||||
userID = policy.UserID
|
||||
connectorID = policy.ConnectorID
|
||||
)
|
||||
|
||||
conditions := make([]gen.Condition, 0)
|
||||
conditions = append(conditions, r.query.AppDynamicConversationOnline.AppID.Eq(appID))
|
||||
conditions = append(conditions, r.query.AppDynamicConversationOnline.UserID.Eq(userID))
|
||||
conditions = append(conditions, r.query.AppDynamicConversationOnline.AppID.Eq(appID))
|
||||
conditions = append(conditions, r.query.AppDynamicConversationOnline.ConnectorID.Eq(connectorID))
|
||||
if policy.NameLike != nil {
|
||||
conditions = append(conditions, r.query.AppDynamicConversationOnline.Name.Like("%%"+*policy.NameLike+"%%"))
|
||||
}
|
||||
|
||||
appDynamicConversationOnlineDao := r.query.AppDynamicConversationOnline.WithContext(ctx).Where(conditions...)
|
||||
var (
|
||||
dynamicConversations = make([]*model.AppDynamicConversationOnline, 0)
|
||||
err error
|
||||
)
|
||||
if policy.Page != nil {
|
||||
dynamicConversations, err = appDynamicConversationOnlineDao.Offset(policy.Page.Offset()).Limit(policy.Page.Limit()).Find()
|
||||
} else {
|
||||
dynamicConversations, err = appDynamicConversationOnlineDao.Where(conditions...).Find()
|
||||
}
|
||||
if err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return []*entity.DynamicConversation{}, nil
|
||||
}
|
||||
return nil, vo.WrapError(errno.ErrDatabaseError, err)
|
||||
}
|
||||
|
||||
return slices.Transform(dynamicConversations, func(a *model.AppDynamicConversationOnline) *entity.DynamicConversation {
|
||||
return &entity.DynamicConversation{
|
||||
ID: a.ID,
|
||||
Name: a.Name,
|
||||
UserID: a.UserID,
|
||||
ConnectorID: a.ConnectorID,
|
||||
ConversationID: a.ConversationID,
|
||||
}
|
||||
}), nil
|
||||
}
|
||||
|
||||
func (r *RepositoryImpl) GetOrCreateStaticConversation(ctx context.Context, env vo.Env, idGen workflow.ConversationIDGenerator, meta *vo.CreateStaticConversation) (int64, int64, bool, error) {
|
||||
if env == vo.Draft {
|
||||
return r.getOrCreateDraftStaticConversation(ctx, idGen, meta)
|
||||
} else if env == vo.Online {
|
||||
return r.getOrCreateOnlineStaticConversation(ctx, idGen, meta)
|
||||
} else {
|
||||
return 0, 0, false, fmt.Errorf("unknown env %v", env)
|
||||
}
|
||||
|
||||
}
|
||||
func (r *RepositoryImpl) GetOrCreateDynamicConversation(ctx context.Context, env vo.Env, idGen workflow.ConversationIDGenerator, meta *vo.CreateDynamicConversation) (int64, int64, bool, error) {
|
||||
if env == vo.Draft {
|
||||
|
||||
appDynamicConversationDraft := r.query.AppDynamicConversationDraft
|
||||
ret, err := appDynamicConversationDraft.WithContext(ctx).Where(
|
||||
appDynamicConversationDraft.AppID.Eq(meta.AppID),
|
||||
appDynamicConversationDraft.ConnectorID.Eq(meta.ConnectorID),
|
||||
appDynamicConversationDraft.UserID.Eq(meta.UserID),
|
||||
appDynamicConversationDraft.Name.Eq(meta.Name),
|
||||
).First()
|
||||
if err == nil {
|
||||
cInfo, err := crossconversation.DefaultSVC().GetByID(ctx, ret.ConversationID)
|
||||
if err != nil {
|
||||
return 0, 0, false, vo.WrapError(errno.ErrDatabaseError, err)
|
||||
}
|
||||
if cInfo == nil {
|
||||
return 0, 0, false, vo.WrapError(errno.ErrDatabaseError, fmt.Errorf("conversation not found"))
|
||||
}
|
||||
return ret.ConversationID, cInfo.SectionID, true, nil
|
||||
}
|
||||
|
||||
if !errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return 0, 0, false, vo.WrapError(errno.ErrDatabaseError, err)
|
||||
}
|
||||
|
||||
conv, err := idGen(ctx, meta.AppID, meta.UserID, meta.ConnectorID)
|
||||
if err != nil {
|
||||
return 0, 0, false, err
|
||||
}
|
||||
|
||||
id, err := r.GenID(ctx)
|
||||
if err != nil {
|
||||
return 0, 0, false, vo.WrapError(errno.ErrIDGenError, err)
|
||||
}
|
||||
|
||||
err = r.query.AppDynamicConversationDraft.WithContext(ctx).Create(&model.AppDynamicConversationDraft{
|
||||
ID: id,
|
||||
AppID: meta.AppID,
|
||||
Name: meta.Name,
|
||||
UserID: meta.UserID,
|
||||
ConnectorID: meta.ConnectorID,
|
||||
ConversationID: conv.ID,
|
||||
})
|
||||
if err != nil {
|
||||
return 0, 0, false, vo.WrapError(errno.ErrDatabaseError, err)
|
||||
}
|
||||
|
||||
return conv.ID, conv.SectionID, false, nil
|
||||
|
||||
} else if env == vo.Online {
|
||||
appDynamicConversationOnline := r.query.AppDynamicConversationOnline
|
||||
ret, err := appDynamicConversationOnline.WithContext(ctx).Where(
|
||||
appDynamicConversationOnline.AppID.Eq(meta.AppID),
|
||||
appDynamicConversationOnline.ConnectorID.Eq(meta.ConnectorID),
|
||||
appDynamicConversationOnline.UserID.Eq(meta.UserID),
|
||||
appDynamicConversationOnline.Name.Eq(meta.Name),
|
||||
).First()
|
||||
if err == nil {
|
||||
cInfo, err := crossconversation.DefaultSVC().GetByID(ctx, ret.ConversationID)
|
||||
if err != nil {
|
||||
return 0, 0, false, vo.WrapError(errno.ErrDatabaseError, err)
|
||||
}
|
||||
if cInfo == nil {
|
||||
return 0, 0, false, vo.WrapError(errno.ErrDatabaseError, fmt.Errorf("conversation not found"))
|
||||
}
|
||||
return ret.ConversationID, cInfo.SectionID, true, nil
|
||||
}
|
||||
if !errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return 0, 0, false, vo.WrapError(errno.ErrDatabaseError, err)
|
||||
}
|
||||
|
||||
conv, err := idGen(ctx, meta.AppID, meta.UserID, meta.ConnectorID)
|
||||
if err != nil {
|
||||
return 0, 0, false, err
|
||||
}
|
||||
id, err := r.GenID(ctx)
|
||||
if err != nil {
|
||||
return 0, 0, false, vo.WrapError(errno.ErrIDGenError, err)
|
||||
}
|
||||
|
||||
err = r.query.AppDynamicConversationOnline.WithContext(ctx).Create(&model.AppDynamicConversationOnline{
|
||||
ID: id,
|
||||
AppID: meta.AppID,
|
||||
Name: meta.Name,
|
||||
UserID: meta.UserID,
|
||||
ConnectorID: meta.ConnectorID,
|
||||
ConversationID: conv.ID,
|
||||
})
|
||||
if err != nil {
|
||||
return 0, 0, false, vo.WrapError(errno.ErrDatabaseError, err)
|
||||
}
|
||||
|
||||
return conv.ID, conv.SectionID, false, nil
|
||||
|
||||
} else {
|
||||
return 0, 0, false, fmt.Errorf("unknown env %v", env)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func (r *RepositoryImpl) GetStaticConversationByTemplateID(ctx context.Context, env vo.Env, userID, connectorID, templateID int64) (*entity.StaticConversation, bool, error) {
|
||||
if env == vo.Draft {
|
||||
conditions := make([]gen.Condition, 0, 3)
|
||||
conditions = append(conditions, r.query.AppStaticConversationDraft.UserID.Eq(userID))
|
||||
conditions = append(conditions, r.query.AppStaticConversationDraft.ConnectorID.Eq(connectorID))
|
||||
conditions = append(conditions, r.query.AppStaticConversationDraft.TemplateID.Eq(templateID))
|
||||
cs, err := r.query.AppStaticConversationDraft.WithContext(ctx).Where(conditions...).First()
|
||||
if err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return nil, false, nil
|
||||
}
|
||||
return nil, false, vo.WrapError(errno.ErrDatabaseError, err)
|
||||
}
|
||||
return &entity.StaticConversation{
|
||||
UserID: cs.UserID,
|
||||
ConnectorID: cs.ConnectorID,
|
||||
TemplateID: cs.TemplateID,
|
||||
ConversationID: cs.ConversationID,
|
||||
}, true, nil
|
||||
} else if env == vo.Online {
|
||||
conditions := make([]gen.Condition, 0, 3)
|
||||
conditions = append(conditions, r.query.AppStaticConversationOnline.UserID.Eq(userID))
|
||||
conditions = append(conditions, r.query.AppStaticConversationOnline.ConnectorID.Eq(connectorID))
|
||||
conditions = append(conditions, r.query.AppStaticConversationOnline.TemplateID.Eq(templateID))
|
||||
cs, err := r.query.AppStaticConversationOnline.WithContext(ctx).Where(conditions...).First()
|
||||
if err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return nil, false, nil
|
||||
}
|
||||
return nil, false, vo.WrapError(errno.ErrDatabaseError, err)
|
||||
}
|
||||
return &entity.StaticConversation{
|
||||
UserID: cs.UserID,
|
||||
ConnectorID: cs.ConnectorID,
|
||||
TemplateID: cs.TemplateID,
|
||||
ConversationID: cs.ConversationID,
|
||||
}, true, nil
|
||||
} else {
|
||||
return nil, false, fmt.Errorf("unknown env %v", env)
|
||||
}
|
||||
}
|
||||
|
||||
func (r *RepositoryImpl) getOrCreateDraftStaticConversation(ctx context.Context, idGen workflow.ConversationIDGenerator, meta *vo.CreateStaticConversation) (int64, int64, bool, error) {
|
||||
cs, err := r.mGetDraftStaticConversation(ctx, meta.UserID, meta.ConnectorID, []int64{meta.TemplateID})
|
||||
if err != nil {
|
||||
return 0, 0, false, vo.WrapError(errno.ErrDatabaseError, err)
|
||||
}
|
||||
|
||||
if len(cs) > 0 {
|
||||
cInfo, err := crossconversation.DefaultSVC().GetByID(ctx, cs[0].ConversationID)
|
||||
if err != nil {
|
||||
return 0, 0, false, vo.WrapError(errno.ErrDatabaseError, err)
|
||||
}
|
||||
if cInfo == nil {
|
||||
return 0, 0, false, vo.WrapError(errno.ErrDatabaseError, fmt.Errorf("conversation not found"))
|
||||
}
|
||||
return cs[0].ConversationID, cInfo.SectionID, true, nil
|
||||
}
|
||||
|
||||
conv, err := idGen(ctx, meta.AppID, meta.UserID, meta.ConnectorID)
|
||||
if err != nil {
|
||||
return 0, 0, false, err
|
||||
}
|
||||
|
||||
id, err := r.GenID(ctx)
|
||||
if err != nil {
|
||||
return 0, 0, false, vo.WrapError(errno.ErrIDGenError, err)
|
||||
}
|
||||
object := &model.AppStaticConversationDraft{
|
||||
ID: id,
|
||||
UserID: meta.UserID,
|
||||
ConnectorID: meta.ConnectorID,
|
||||
TemplateID: meta.TemplateID,
|
||||
ConversationID: conv.ID,
|
||||
}
|
||||
err = r.query.AppStaticConversationDraft.WithContext(ctx).Create(object)
|
||||
if err != nil {
|
||||
return 0, 0, false, vo.WrapError(errno.ErrDatabaseError, err)
|
||||
}
|
||||
|
||||
return conv.ID, conv.SectionID, false, nil
|
||||
}
|
||||
|
||||
func (r *RepositoryImpl) getOrCreateOnlineStaticConversation(ctx context.Context, idGen workflow.ConversationIDGenerator, meta *vo.CreateStaticConversation) (int64, int64, bool, error) {
|
||||
cs, err := r.mGetOnlineStaticConversation(ctx, meta.UserID, meta.ConnectorID, []int64{meta.TemplateID})
|
||||
if err != nil {
|
||||
return 0, 0, false, vo.WrapError(errno.ErrDatabaseError, err)
|
||||
}
|
||||
|
||||
if len(cs) > 0 {
|
||||
cInfo, err := crossconversation.DefaultSVC().GetByID(ctx, cs[0].ConversationID)
|
||||
if err != nil {
|
||||
return 0, 0, false, vo.WrapError(errno.ErrDatabaseError, err)
|
||||
}
|
||||
if cInfo == nil {
|
||||
return 0, 0, false, vo.WrapError(errno.ErrDatabaseError, fmt.Errorf("conversation not found"))
|
||||
}
|
||||
return cs[0].ConversationID, cInfo.SectionID, true, nil
|
||||
}
|
||||
|
||||
conv, err := idGen(ctx, meta.AppID, meta.UserID, meta.ConnectorID)
|
||||
if err != nil {
|
||||
return 0, 0, false, err
|
||||
}
|
||||
|
||||
id, err := r.GenID(ctx)
|
||||
if err != nil {
|
||||
return 0, 0, false, vo.WrapError(errno.ErrIDGenError, err)
|
||||
}
|
||||
object := &model.AppStaticConversationOnline{
|
||||
ID: id,
|
||||
UserID: meta.UserID,
|
||||
ConnectorID: meta.ConnectorID,
|
||||
TemplateID: meta.TemplateID,
|
||||
ConversationID: conv.ID,
|
||||
}
|
||||
err = r.query.AppStaticConversationOnline.WithContext(ctx).Create(object)
|
||||
if err != nil {
|
||||
return 0, 0, false, vo.WrapError(errno.ErrDatabaseError, err)
|
||||
}
|
||||
|
||||
return conv.ID, conv.SectionID, false, nil
|
||||
}
|
||||
|
||||
func (r *RepositoryImpl) BatchCreateOnlineConversationTemplate(ctx context.Context, templates []*entity.ConversationTemplate, version string) error {
|
||||
ids, err := r.GenMultiIDs(ctx, len(templates))
|
||||
if err != nil {
|
||||
return vo.WrapError(errno.ErrIDGenError, err)
|
||||
}
|
||||
|
||||
objects := make([]*model.AppConversationTemplateOnline, 0, len(templates))
|
||||
for idx := range templates {
|
||||
template := templates[idx]
|
||||
objects = append(objects, &model.AppConversationTemplateOnline{
|
||||
ID: ids[idx],
|
||||
SpaceID: template.SpaceID,
|
||||
AppID: template.AppID,
|
||||
TemplateID: template.TemplateID,
|
||||
Name: template.Name,
|
||||
Version: version,
|
||||
})
|
||||
}
|
||||
|
||||
err = r.query.AppConversationTemplateOnline.WithContext(ctx).CreateInBatches(objects, batchSize)
|
||||
if err != nil {
|
||||
return vo.WrapError(errno.ErrDatabaseError, err)
|
||||
}
|
||||
return nil
|
||||
|
||||
}
|
||||
|
||||
func (r *RepositoryImpl) GetDynamicConversationByName(ctx context.Context, env vo.Env, appID, connectorID, userID int64, name string) (*entity.DynamicConversation, bool, error) {
|
||||
if env == vo.Draft {
|
||||
appDynamicConversationDraft := r.query.AppDynamicConversationDraft
|
||||
ret, err := appDynamicConversationDraft.WithContext(ctx).Where(
|
||||
appDynamicConversationDraft.AppID.Eq(appID),
|
||||
appDynamicConversationDraft.ConnectorID.Eq(connectorID),
|
||||
appDynamicConversationDraft.UserID.Eq(userID),
|
||||
appDynamicConversationDraft.Name.Eq(name)).First()
|
||||
if err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return nil, false, nil
|
||||
}
|
||||
return nil, false, err
|
||||
}
|
||||
|
||||
return &entity.DynamicConversation{
|
||||
ID: ret.ID,
|
||||
UserID: ret.UserID,
|
||||
ConnectorID: ret.ConnectorID,
|
||||
ConversationID: ret.ConversationID,
|
||||
Name: ret.Name,
|
||||
}, true, nil
|
||||
|
||||
} else if env == vo.Online {
|
||||
appDynamicConversationOnline := r.query.AppDynamicConversationOnline
|
||||
ret, err := appDynamicConversationOnline.WithContext(ctx).Where(
|
||||
appDynamicConversationOnline.AppID.Eq(appID),
|
||||
appDynamicConversationOnline.ConnectorID.Eq(connectorID),
|
||||
appDynamicConversationOnline.UserID.Eq(userID),
|
||||
appDynamicConversationOnline.Name.Eq(name)).First()
|
||||
if err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return nil, false, nil
|
||||
}
|
||||
return nil, false, err
|
||||
}
|
||||
return &entity.DynamicConversation{
|
||||
ID: ret.ID,
|
||||
UserID: ret.UserID,
|
||||
ConnectorID: ret.ConnectorID,
|
||||
ConversationID: ret.ConversationID,
|
||||
Name: ret.Name,
|
||||
}, true, nil
|
||||
|
||||
} else {
|
||||
return nil, false, fmt.Errorf("unknown env %v", env)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func (r *RepositoryImpl) UpdateDynamicConversationNameByID(ctx context.Context, env vo.Env, templateID int64, name string) error {
|
||||
if env == vo.Draft {
|
||||
appDynamicConversationDraft := r.query.AppDynamicConversationDraft
|
||||
_, err := appDynamicConversationDraft.WithContext(ctx).Where(
|
||||
appDynamicConversationDraft.ID.Eq(templateID),
|
||||
).UpdateColumnSimple(appDynamicConversationDraft.Name.Value(name))
|
||||
if err != nil {
|
||||
return vo.WrapError(errno.ErrDatabaseError, err)
|
||||
}
|
||||
return nil
|
||||
} else if env == vo.Online {
|
||||
appDynamicConversationOnline := r.query.AppDynamicConversationOnline
|
||||
_, err := appDynamicConversationOnline.WithContext(ctx).Where(
|
||||
appDynamicConversationOnline.ID.Eq(templateID),
|
||||
).UpdateColumnSimple(appDynamicConversationOnline.Name.Value(name))
|
||||
if err != nil {
|
||||
return vo.WrapError(errno.ErrDatabaseError, err)
|
||||
}
|
||||
return nil
|
||||
|
||||
} else {
|
||||
return fmt.Errorf("unknown env %v", env)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func (r *RepositoryImpl) UpdateStaticConversation(ctx context.Context, env vo.Env, templateID int64, connectorID int64, userID int64, newConversationID int64) error {
|
||||
|
||||
if env == vo.Draft {
|
||||
appStaticConversationDraft := r.query.AppStaticConversationDraft
|
||||
_, err := appStaticConversationDraft.WithContext(ctx).Where(
|
||||
appStaticConversationDraft.TemplateID.Eq(templateID),
|
||||
appStaticConversationDraft.ConnectorID.Eq(connectorID),
|
||||
appStaticConversationDraft.UserID.Eq(userID),
|
||||
).UpdateColumn(appStaticConversationDraft.ConversationID, newConversationID)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return err
|
||||
|
||||
} else if env == vo.Online {
|
||||
appStaticConversationOnline := r.query.AppStaticConversationOnline
|
||||
_, err := appStaticConversationOnline.WithContext(ctx).Where(
|
||||
appStaticConversationOnline.TemplateID.Eq(templateID),
|
||||
appStaticConversationOnline.ConnectorID.Eq(connectorID),
|
||||
appStaticConversationOnline.UserID.Eq(userID),
|
||||
).UpdateColumn(appStaticConversationOnline.ConversationID, newConversationID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
} else {
|
||||
return fmt.Errorf("unknown env %v", env)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func (r *RepositoryImpl) UpdateDynamicConversation(ctx context.Context, env vo.Env, conversationID, newConversationID int64) error {
|
||||
if env == vo.Draft {
|
||||
appDynamicConversationDraft := r.query.AppDynamicConversationDraft
|
||||
_, err := appDynamicConversationDraft.WithContext(ctx).Where(appDynamicConversationDraft.ConversationID.Eq(conversationID)).
|
||||
UpdateColumn(appDynamicConversationDraft.ConversationID, newConversationID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
} else if env == vo.Online {
|
||||
appDynamicConversationOnline := r.query.AppDynamicConversationOnline
|
||||
_, err := appDynamicConversationOnline.WithContext(ctx).Where(appDynamicConversationOnline.ConversationID.Eq(conversationID)).
|
||||
UpdateColumn(appDynamicConversationOnline.ConversationID, newConversationID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
} else {
|
||||
return fmt.Errorf("unknown env %v", env)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func (r *RepositoryImpl) CopyTemplateConversationByAppID(ctx context.Context, appID int64, toAppID int64) error {
|
||||
appConversationTemplateDraft := r.query.AppConversationTemplateDraft
|
||||
templates, err := appConversationTemplateDraft.WithContext(ctx).Where(appConversationTemplateDraft.AppID.Eq(appID), appConversationTemplateDraft.Name.Neq("Default")).Find()
|
||||
if err != nil {
|
||||
return vo.WrapError(errno.ErrDatabaseError, err)
|
||||
}
|
||||
|
||||
if len(templates) == 0 {
|
||||
return nil
|
||||
}
|
||||
templateTemplates := make([]*model.AppConversationTemplateDraft, 0, len(templates))
|
||||
ids, err := r.GenMultiIDs(ctx, len(templates))
|
||||
if err != nil {
|
||||
return vo.WrapError(errno.ErrIDGenError, err)
|
||||
}
|
||||
for i := range templates {
|
||||
copiedTemplate := templates[i]
|
||||
copiedTemplate.ID = ids[i]
|
||||
copiedTemplate.TemplateID = ids[i]
|
||||
copiedTemplate.AppID = toAppID
|
||||
templateTemplates = append(templateTemplates, copiedTemplate)
|
||||
}
|
||||
err = appConversationTemplateDraft.WithContext(ctx).CreateInBatches(templateTemplates, batchSize)
|
||||
if err != nil {
|
||||
return vo.WrapError(errno.ErrDatabaseError, err)
|
||||
}
|
||||
return nil
|
||||
|
||||
}
|
||||
|
||||
func (r *RepositoryImpl) GetStaticConversationByID(ctx context.Context, env vo.Env, appID, connectorID, conversationID int64) (string, bool, error) {
|
||||
if env == vo.Draft {
|
||||
appStaticConversationDraft := r.query.AppStaticConversationDraft
|
||||
ret, err := appStaticConversationDraft.WithContext(ctx).Where(
|
||||
appStaticConversationDraft.ConnectorID.Eq(connectorID),
|
||||
appStaticConversationDraft.ConversationID.Eq(conversationID),
|
||||
).First()
|
||||
if err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return "", false, nil
|
||||
}
|
||||
return "", false, err
|
||||
}
|
||||
appConversationTemplateDraft := r.query.AppConversationTemplateDraft
|
||||
template, err := appConversationTemplateDraft.WithContext(ctx).Where(
|
||||
appConversationTemplateDraft.TemplateID.Eq(ret.TemplateID),
|
||||
appConversationTemplateDraft.AppID.Eq(appID),
|
||||
).First()
|
||||
if err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return "", false, nil
|
||||
}
|
||||
return "", false, err
|
||||
}
|
||||
return template.Name, true, nil
|
||||
} else if env == vo.Online {
|
||||
appStaticConversationOnline := r.query.AppStaticConversationOnline
|
||||
ret, err := appStaticConversationOnline.WithContext(ctx).Where(
|
||||
appStaticConversationOnline.ConnectorID.Eq(connectorID),
|
||||
appStaticConversationOnline.ConversationID.Eq(conversationID),
|
||||
).First()
|
||||
if err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return "", false, nil
|
||||
}
|
||||
return "", false, err
|
||||
}
|
||||
appConversationTemplateOnline := r.query.AppConversationTemplateOnline
|
||||
template, err := appConversationTemplateOnline.WithContext(ctx).Where(
|
||||
appConversationTemplateOnline.TemplateID.Eq(ret.TemplateID),
|
||||
appConversationTemplateOnline.AppID.Eq(appID),
|
||||
).First()
|
||||
if err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return "", false, nil
|
||||
}
|
||||
return "", false, err
|
||||
}
|
||||
return template.Name, true, nil
|
||||
}
|
||||
return "", false, fmt.Errorf("unknown env %v", env)
|
||||
}
|
||||
|
||||
func (r *RepositoryImpl) GetDynamicConversationByID(ctx context.Context, env vo.Env, appID, connectorID, conversationID int64) (*entity.DynamicConversation, bool, error) {
|
||||
if env == vo.Draft {
|
||||
appDynamicConversationDraft := r.query.AppDynamicConversationDraft
|
||||
ret, err := appDynamicConversationDraft.WithContext(ctx).Where(
|
||||
appDynamicConversationDraft.AppID.Eq(appID),
|
||||
appDynamicConversationDraft.ConnectorID.Eq(connectorID),
|
||||
appDynamicConversationDraft.ConversationID.Eq(conversationID),
|
||||
).First()
|
||||
if err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return nil, false, nil
|
||||
}
|
||||
return nil, false, err
|
||||
}
|
||||
return &entity.DynamicConversation{
|
||||
ID: ret.ID,
|
||||
UserID: ret.UserID,
|
||||
ConnectorID: ret.ConnectorID,
|
||||
ConversationID: ret.ConversationID,
|
||||
Name: ret.Name,
|
||||
}, true, nil
|
||||
} else if env == vo.Online {
|
||||
appDynamicConversationOnline := r.query.AppDynamicConversationOnline
|
||||
ret, err := appDynamicConversationOnline.WithContext(ctx).Where(
|
||||
appDynamicConversationOnline.AppID.Eq(appID),
|
||||
appDynamicConversationOnline.ConnectorID.Eq(connectorID),
|
||||
appDynamicConversationOnline.ConversationID.Eq(conversationID),
|
||||
).First()
|
||||
if err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return nil, false, nil
|
||||
}
|
||||
return nil, false, err
|
||||
}
|
||||
return &entity.DynamicConversation{
|
||||
ID: ret.ID,
|
||||
UserID: ret.UserID,
|
||||
ConnectorID: ret.ConnectorID,
|
||||
ConversationID: ret.ConversationID,
|
||||
Name: ret.Name,
|
||||
}, true, nil
|
||||
}
|
||||
return nil, false, fmt.Errorf("unknown env %v", env)
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
// Code generated by gorm.io/gen. DO NOT EDIT.
|
||||
// Code generated by gorm.io/gen. DO NOT EDIT.
|
||||
// Code generated by gorm.io/gen. DO NOT EDIT.
|
||||
|
||||
package model
|
||||
|
||||
import (
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
const TableNameAppConversationTemplateDraft = "app_conversation_template_draft"
|
||||
|
||||
// AppConversationTemplateDraft mapped from table <app_conversation_template_draft>
|
||||
type AppConversationTemplateDraft struct {
|
||||
ID int64 `gorm:"column:id;primaryKey;comment:id" json:"id"` // id
|
||||
AppID int64 `gorm:"column:app_id;not null;comment:app id" json:"app_id"` // app id
|
||||
SpaceID int64 `gorm:"column:space_id;not null;comment:space id" json:"space_id"` // space id
|
||||
Name string `gorm:"column:name;not null;comment:conversion name" json:"name"` // conversion name
|
||||
TemplateID int64 `gorm:"column:template_id;not null;comment:template id" json:"template_id"` // template id
|
||||
CreatorID int64 `gorm:"column:creator_id;not null;comment:creator id" json:"creator_id"` // creator id
|
||||
CreatedAt int64 `gorm:"column:created_at;not null;autoCreateTime:milli;comment:create time in millisecond" json:"created_at"` // create time in millisecond
|
||||
UpdatedAt int64 `gorm:"column:updated_at;autoUpdateTime:milli;comment:update time in millisecond" json:"updated_at"` // update time in millisecond
|
||||
DeletedAt gorm.DeletedAt `gorm:"column:deleted_at;comment:delete time in millisecond" json:"deleted_at"` // delete time in millisecond
|
||||
}
|
||||
|
||||
// TableName AppConversationTemplateDraft's table name
|
||||
func (*AppConversationTemplateDraft) TableName() string {
|
||||
return TableNameAppConversationTemplateDraft
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
// Code generated by gorm.io/gen. DO NOT EDIT.
|
||||
// Code generated by gorm.io/gen. DO NOT EDIT.
|
||||
// Code generated by gorm.io/gen. DO NOT EDIT.
|
||||
|
||||
package model
|
||||
|
||||
const TableNameAppConversationTemplateOnline = "app_conversation_template_online"
|
||||
|
||||
// AppConversationTemplateOnline mapped from table <app_conversation_template_online>
|
||||
type AppConversationTemplateOnline struct {
|
||||
ID int64 `gorm:"column:id;primaryKey;comment:id" json:"id"` // id
|
||||
AppID int64 `gorm:"column:app_id;not null;comment:app id" json:"app_id"` // app id
|
||||
SpaceID int64 `gorm:"column:space_id;not null;comment:space id" json:"space_id"` // space id
|
||||
Name string `gorm:"column:name;not null;comment:conversion name" json:"name"` // conversion name
|
||||
TemplateID int64 `gorm:"column:template_id;not null;comment:template id" json:"template_id"` // template id
|
||||
Version string `gorm:"column:version;not null;comment:version name" json:"version"` // version name
|
||||
CreatorID int64 `gorm:"column:creator_id;not null;comment:creator id" json:"creator_id"` // creator id
|
||||
CreatedAt int64 `gorm:"column:created_at;not null;autoCreateTime:milli;comment:create time in millisecond" json:"created_at"` // create time in millisecond
|
||||
}
|
||||
|
||||
// TableName AppConversationTemplateOnline's table name
|
||||
func (*AppConversationTemplateOnline) TableName() string {
|
||||
return TableNameAppConversationTemplateOnline
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
// Code generated by gorm.io/gen. DO NOT EDIT.
|
||||
// Code generated by gorm.io/gen. DO NOT EDIT.
|
||||
// Code generated by gorm.io/gen. DO NOT EDIT.
|
||||
|
||||
package model
|
||||
|
||||
import (
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
const TableNameAppDynamicConversationDraft = "app_dynamic_conversation_draft"
|
||||
|
||||
// AppDynamicConversationDraft mapped from table <app_dynamic_conversation_draft>
|
||||
type AppDynamicConversationDraft struct {
|
||||
ID int64 `gorm:"column:id;primaryKey;comment:id" json:"id"` // id
|
||||
AppID int64 `gorm:"column:app_id;not null;comment:app id" json:"app_id"` // app id
|
||||
Name string `gorm:"column:name;not null;comment:conversion name" json:"name"` // conversion name
|
||||
UserID int64 `gorm:"column:user_id;not null;comment:user id" json:"user_id"` // user id
|
||||
ConnectorID int64 `gorm:"column:connector_id;not null;comment:connector id" json:"connector_id"` // connector id
|
||||
ConversationID int64 `gorm:"column:conversation_id;not null;comment:conversation id" json:"conversation_id"` // conversation id
|
||||
CreatedAt int64 `gorm:"column:created_at;not null;autoCreateTime:milli;comment:create time in millisecond" json:"created_at"` // create time in millisecond
|
||||
DeletedAt gorm.DeletedAt `gorm:"column:deleted_at;comment:delete time in millisecond" json:"deleted_at"` // delete time in millisecond
|
||||
}
|
||||
|
||||
// TableName AppDynamicConversationDraft's table name
|
||||
func (*AppDynamicConversationDraft) TableName() string {
|
||||
return TableNameAppDynamicConversationDraft
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
// Code generated by gorm.io/gen. DO NOT EDIT.
|
||||
// Code generated by gorm.io/gen. DO NOT EDIT.
|
||||
// Code generated by gorm.io/gen. DO NOT EDIT.
|
||||
|
||||
package model
|
||||
|
||||
import (
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
const TableNameAppDynamicConversationOnline = "app_dynamic_conversation_online"
|
||||
|
||||
// AppDynamicConversationOnline mapped from table <app_dynamic_conversation_online>
|
||||
type AppDynamicConversationOnline struct {
|
||||
ID int64 `gorm:"column:id;primaryKey;comment:id" json:"id"` // id
|
||||
AppID int64 `gorm:"column:app_id;not null;comment:app id" json:"app_id"` // app id
|
||||
Name string `gorm:"column:name;not null;comment:conversion name" json:"name"` // conversion name
|
||||
UserID int64 `gorm:"column:user_id;not null;comment:user id" json:"user_id"` // user id
|
||||
ConnectorID int64 `gorm:"column:connector_id;not null;comment:connector id" json:"connector_id"` // connector id
|
||||
ConversationID int64 `gorm:"column:conversation_id;not null;comment:conversation id" json:"conversation_id"` // conversation id
|
||||
CreatedAt int64 `gorm:"column:created_at;not null;autoCreateTime:milli;comment:create time in millisecond" json:"created_at"` // create time in millisecond
|
||||
DeletedAt gorm.DeletedAt `gorm:"column:deleted_at;comment:delete time in millisecond" json:"deleted_at"` // delete time in millisecond
|
||||
}
|
||||
|
||||
// TableName AppDynamicConversationOnline's table name
|
||||
func (*AppDynamicConversationOnline) TableName() string {
|
||||
return TableNameAppDynamicConversationOnline
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
// Code generated by gorm.io/gen. DO NOT EDIT.
|
||||
// Code generated by gorm.io/gen. DO NOT EDIT.
|
||||
// Code generated by gorm.io/gen. DO NOT EDIT.
|
||||
|
||||
package model
|
||||
|
||||
import (
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
const TableNameAppStaticConversationDraft = "app_static_conversation_draft"
|
||||
|
||||
// AppStaticConversationDraft mapped from table <app_static_conversation_draft>
|
||||
type AppStaticConversationDraft struct {
|
||||
ID int64 `gorm:"column:id;primaryKey;comment:id" json:"id"` // id
|
||||
TemplateID int64 `gorm:"column:template_id;not null;comment:template id" json:"template_id"` // template id
|
||||
UserID int64 `gorm:"column:user_id;not null;comment:user id" json:"user_id"` // user id
|
||||
ConnectorID int64 `gorm:"column:connector_id;not null;comment:connector id" json:"connector_id"` // connector id
|
||||
ConversationID int64 `gorm:"column:conversation_id;not null;comment:conversation id" json:"conversation_id"` // conversation id
|
||||
CreatedAt int64 `gorm:"column:created_at;not null;autoCreateTime:milli;comment:create time in millisecond" json:"created_at"` // create time in millisecond
|
||||
DeletedAt gorm.DeletedAt `gorm:"column:deleted_at;comment:delete time in millisecond" json:"deleted_at"` // delete time in millisecond
|
||||
}
|
||||
|
||||
// TableName AppStaticConversationDraft's table name
|
||||
func (*AppStaticConversationDraft) TableName() string {
|
||||
return TableNameAppStaticConversationDraft
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
// Code generated by gorm.io/gen. DO NOT EDIT.
|
||||
// Code generated by gorm.io/gen. DO NOT EDIT.
|
||||
// Code generated by gorm.io/gen. DO NOT EDIT.
|
||||
|
||||
package model
|
||||
|
||||
const TableNameAppStaticConversationOnline = "app_static_conversation_online"
|
||||
|
||||
// AppStaticConversationOnline mapped from table <app_static_conversation_online>
|
||||
type AppStaticConversationOnline struct {
|
||||
ID int64 `gorm:"column:id;primaryKey;comment:id" json:"id"` // id
|
||||
TemplateID int64 `gorm:"column:template_id;not null;comment:template id" json:"template_id"` // template id
|
||||
UserID int64 `gorm:"column:user_id;not null;comment:user id" json:"user_id"` // user id
|
||||
ConnectorID int64 `gorm:"column:connector_id;not null;comment:connector id" json:"connector_id"` // connector id
|
||||
ConversationID int64 `gorm:"column:conversation_id;not null;comment:conversation id" json:"conversation_id"` // conversation id
|
||||
CreatedAt int64 `gorm:"column:created_at;not null;autoCreateTime:milli;comment:create time in millisecond" json:"created_at"` // create time in millisecond
|
||||
}
|
||||
|
||||
// TableName AppStaticConversationOnline's table name
|
||||
func (*AppStaticConversationOnline) TableName() string {
|
||||
return TableNameAppStaticConversationOnline
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
// Code generated by gorm.io/gen. DO NOT EDIT.
|
||||
// Code generated by gorm.io/gen. DO NOT EDIT.
|
||||
// Code generated by gorm.io/gen. DO NOT EDIT.
|
||||
|
||||
package model
|
||||
|
||||
import (
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
const TableNameChatFlowRoleConfig = "chat_flow_role_config"
|
||||
|
||||
// ChatFlowRoleConfig mapped from table <chat_flow_role_config>
|
||||
type ChatFlowRoleConfig struct {
|
||||
ID int64 `gorm:"column:id;primaryKey;comment:id" json:"id"` // id
|
||||
WorkflowID int64 `gorm:"column:workflow_id;not null;comment:workflow id" json:"workflow_id"` // workflow id
|
||||
Name string `gorm:"column:name;not null;comment:role name" json:"name"` // role name
|
||||
Description string `gorm:"column:description;not null;comment:role description" json:"description"` // role description
|
||||
Version string `gorm:"column:version;not null;comment:version" json:"version"` // version
|
||||
Avatar string `gorm:"column:avatar;not null;comment:avatar uri" json:"avatar"` // avatar uri
|
||||
BackgroundImageInfo string `gorm:"column:background_image_info;not null;comment:background image information, object structure" json:"background_image_info"` // background image information, object structure
|
||||
OnboardingInfo string `gorm:"column:onboarding_info;not null;comment:intro information, object structure" json:"onboarding_info"` // intro information, object structure
|
||||
SuggestReplyInfo string `gorm:"column:suggest_reply_info;not null;comment:user suggestions, object structure" json:"suggest_reply_info"` // user suggestions, object structure
|
||||
AudioConfig string `gorm:"column:audio_config;not null;comment:agent audio config, object structure" json:"audio_config"` // agent audio config, object structure
|
||||
UserInputConfig string `gorm:"column:user_input_config;not null;comment:user input config, object structure" json:"user_input_config"` // user input config, object structure
|
||||
CreatorID int64 `gorm:"column:creator_id;not null;comment:creator id" json:"creator_id"` // creator id
|
||||
CreatedAt int64 `gorm:"column:created_at;not null;autoCreateTime:milli;comment:create time in millisecond" json:"created_at"` // create time in millisecond
|
||||
UpdatedAt int64 `gorm:"column:updated_at;autoUpdateTime:milli;comment:update time in millisecond" json:"updated_at"` // update time in millisecond
|
||||
DeletedAt gorm.DeletedAt `gorm:"column:deleted_at;comment:delete time in millisecond" json:"deleted_at"` // delete time in millisecond
|
||||
ConnectorID int64 `gorm:"column:connector_id;comment:connector id" json:"connector_id"` // connector id
|
||||
}
|
||||
|
||||
// TableName ChatFlowRoleConfig's table name
|
||||
func (*ChatFlowRoleConfig) TableName() string {
|
||||
return TableNameChatFlowRoleConfig
|
||||
}
|
||||
@@ -0,0 +1,412 @@
|
||||
// Code generated by gorm.io/gen. DO NOT EDIT.
|
||||
// Code generated by gorm.io/gen. DO NOT EDIT.
|
||||
// Code generated by gorm.io/gen. DO NOT EDIT.
|
||||
|
||||
package query
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"gorm.io/gorm"
|
||||
"gorm.io/gorm/clause"
|
||||
"gorm.io/gorm/schema"
|
||||
|
||||
"gorm.io/gen"
|
||||
"gorm.io/gen/field"
|
||||
|
||||
"gorm.io/plugin/dbresolver"
|
||||
|
||||
"github.com/coze-dev/coze-studio/backend/domain/workflow/internal/repo/dal/model"
|
||||
)
|
||||
|
||||
func newAppConversationTemplateDraft(db *gorm.DB, opts ...gen.DOOption) appConversationTemplateDraft {
|
||||
_appConversationTemplateDraft := appConversationTemplateDraft{}
|
||||
|
||||
_appConversationTemplateDraft.appConversationTemplateDraftDo.UseDB(db, opts...)
|
||||
_appConversationTemplateDraft.appConversationTemplateDraftDo.UseModel(&model.AppConversationTemplateDraft{})
|
||||
|
||||
tableName := _appConversationTemplateDraft.appConversationTemplateDraftDo.TableName()
|
||||
_appConversationTemplateDraft.ALL = field.NewAsterisk(tableName)
|
||||
_appConversationTemplateDraft.ID = field.NewInt64(tableName, "id")
|
||||
_appConversationTemplateDraft.AppID = field.NewInt64(tableName, "app_id")
|
||||
_appConversationTemplateDraft.SpaceID = field.NewInt64(tableName, "space_id")
|
||||
_appConversationTemplateDraft.Name = field.NewString(tableName, "name")
|
||||
_appConversationTemplateDraft.TemplateID = field.NewInt64(tableName, "template_id")
|
||||
_appConversationTemplateDraft.CreatorID = field.NewInt64(tableName, "creator_id")
|
||||
_appConversationTemplateDraft.CreatedAt = field.NewInt64(tableName, "created_at")
|
||||
_appConversationTemplateDraft.UpdatedAt = field.NewInt64(tableName, "updated_at")
|
||||
_appConversationTemplateDraft.DeletedAt = field.NewField(tableName, "deleted_at")
|
||||
|
||||
_appConversationTemplateDraft.fillFieldMap()
|
||||
|
||||
return _appConversationTemplateDraft
|
||||
}
|
||||
|
||||
type appConversationTemplateDraft struct {
|
||||
appConversationTemplateDraftDo
|
||||
|
||||
ALL field.Asterisk
|
||||
ID field.Int64 // id
|
||||
AppID field.Int64 // app id
|
||||
SpaceID field.Int64 // space id
|
||||
Name field.String // conversion name
|
||||
TemplateID field.Int64 // template id
|
||||
CreatorID field.Int64 // creator id
|
||||
CreatedAt field.Int64 // create time in millisecond
|
||||
UpdatedAt field.Int64 // update time in millisecond
|
||||
DeletedAt field.Field // delete time in millisecond
|
||||
|
||||
fieldMap map[string]field.Expr
|
||||
}
|
||||
|
||||
func (a appConversationTemplateDraft) Table(newTableName string) *appConversationTemplateDraft {
|
||||
a.appConversationTemplateDraftDo.UseTable(newTableName)
|
||||
return a.updateTableName(newTableName)
|
||||
}
|
||||
|
||||
func (a appConversationTemplateDraft) As(alias string) *appConversationTemplateDraft {
|
||||
a.appConversationTemplateDraftDo.DO = *(a.appConversationTemplateDraftDo.As(alias).(*gen.DO))
|
||||
return a.updateTableName(alias)
|
||||
}
|
||||
|
||||
func (a *appConversationTemplateDraft) updateTableName(table string) *appConversationTemplateDraft {
|
||||
a.ALL = field.NewAsterisk(table)
|
||||
a.ID = field.NewInt64(table, "id")
|
||||
a.AppID = field.NewInt64(table, "app_id")
|
||||
a.SpaceID = field.NewInt64(table, "space_id")
|
||||
a.Name = field.NewString(table, "name")
|
||||
a.TemplateID = field.NewInt64(table, "template_id")
|
||||
a.CreatorID = field.NewInt64(table, "creator_id")
|
||||
a.CreatedAt = field.NewInt64(table, "created_at")
|
||||
a.UpdatedAt = field.NewInt64(table, "updated_at")
|
||||
a.DeletedAt = field.NewField(table, "deleted_at")
|
||||
|
||||
a.fillFieldMap()
|
||||
|
||||
return a
|
||||
}
|
||||
|
||||
func (a *appConversationTemplateDraft) GetFieldByName(fieldName string) (field.OrderExpr, bool) {
|
||||
_f, ok := a.fieldMap[fieldName]
|
||||
if !ok || _f == nil {
|
||||
return nil, false
|
||||
}
|
||||
_oe, ok := _f.(field.OrderExpr)
|
||||
return _oe, ok
|
||||
}
|
||||
|
||||
func (a *appConversationTemplateDraft) fillFieldMap() {
|
||||
a.fieldMap = make(map[string]field.Expr, 9)
|
||||
a.fieldMap["id"] = a.ID
|
||||
a.fieldMap["app_id"] = a.AppID
|
||||
a.fieldMap["space_id"] = a.SpaceID
|
||||
a.fieldMap["name"] = a.Name
|
||||
a.fieldMap["template_id"] = a.TemplateID
|
||||
a.fieldMap["creator_id"] = a.CreatorID
|
||||
a.fieldMap["created_at"] = a.CreatedAt
|
||||
a.fieldMap["updated_at"] = a.UpdatedAt
|
||||
a.fieldMap["deleted_at"] = a.DeletedAt
|
||||
}
|
||||
|
||||
func (a appConversationTemplateDraft) clone(db *gorm.DB) appConversationTemplateDraft {
|
||||
a.appConversationTemplateDraftDo.ReplaceConnPool(db.Statement.ConnPool)
|
||||
return a
|
||||
}
|
||||
|
||||
func (a appConversationTemplateDraft) replaceDB(db *gorm.DB) appConversationTemplateDraft {
|
||||
a.appConversationTemplateDraftDo.ReplaceDB(db)
|
||||
return a
|
||||
}
|
||||
|
||||
type appConversationTemplateDraftDo struct{ gen.DO }
|
||||
|
||||
type IAppConversationTemplateDraftDo interface {
|
||||
gen.SubQuery
|
||||
Debug() IAppConversationTemplateDraftDo
|
||||
WithContext(ctx context.Context) IAppConversationTemplateDraftDo
|
||||
WithResult(fc func(tx gen.Dao)) gen.ResultInfo
|
||||
ReplaceDB(db *gorm.DB)
|
||||
ReadDB() IAppConversationTemplateDraftDo
|
||||
WriteDB() IAppConversationTemplateDraftDo
|
||||
As(alias string) gen.Dao
|
||||
Session(config *gorm.Session) IAppConversationTemplateDraftDo
|
||||
Columns(cols ...field.Expr) gen.Columns
|
||||
Clauses(conds ...clause.Expression) IAppConversationTemplateDraftDo
|
||||
Not(conds ...gen.Condition) IAppConversationTemplateDraftDo
|
||||
Or(conds ...gen.Condition) IAppConversationTemplateDraftDo
|
||||
Select(conds ...field.Expr) IAppConversationTemplateDraftDo
|
||||
Where(conds ...gen.Condition) IAppConversationTemplateDraftDo
|
||||
Order(conds ...field.Expr) IAppConversationTemplateDraftDo
|
||||
Distinct(cols ...field.Expr) IAppConversationTemplateDraftDo
|
||||
Omit(cols ...field.Expr) IAppConversationTemplateDraftDo
|
||||
Join(table schema.Tabler, on ...field.Expr) IAppConversationTemplateDraftDo
|
||||
LeftJoin(table schema.Tabler, on ...field.Expr) IAppConversationTemplateDraftDo
|
||||
RightJoin(table schema.Tabler, on ...field.Expr) IAppConversationTemplateDraftDo
|
||||
Group(cols ...field.Expr) IAppConversationTemplateDraftDo
|
||||
Having(conds ...gen.Condition) IAppConversationTemplateDraftDo
|
||||
Limit(limit int) IAppConversationTemplateDraftDo
|
||||
Offset(offset int) IAppConversationTemplateDraftDo
|
||||
Count() (count int64, err error)
|
||||
Scopes(funcs ...func(gen.Dao) gen.Dao) IAppConversationTemplateDraftDo
|
||||
Unscoped() IAppConversationTemplateDraftDo
|
||||
Create(values ...*model.AppConversationTemplateDraft) error
|
||||
CreateInBatches(values []*model.AppConversationTemplateDraft, batchSize int) error
|
||||
Save(values ...*model.AppConversationTemplateDraft) error
|
||||
First() (*model.AppConversationTemplateDraft, error)
|
||||
Take() (*model.AppConversationTemplateDraft, error)
|
||||
Last() (*model.AppConversationTemplateDraft, error)
|
||||
Find() ([]*model.AppConversationTemplateDraft, error)
|
||||
FindInBatch(batchSize int, fc func(tx gen.Dao, batch int) error) (results []*model.AppConversationTemplateDraft, err error)
|
||||
FindInBatches(result *[]*model.AppConversationTemplateDraft, batchSize int, fc func(tx gen.Dao, batch int) error) error
|
||||
Pluck(column field.Expr, dest interface{}) error
|
||||
Delete(...*model.AppConversationTemplateDraft) (info gen.ResultInfo, err error)
|
||||
Update(column field.Expr, value interface{}) (info gen.ResultInfo, err error)
|
||||
UpdateSimple(columns ...field.AssignExpr) (info gen.ResultInfo, err error)
|
||||
Updates(value interface{}) (info gen.ResultInfo, err error)
|
||||
UpdateColumn(column field.Expr, value interface{}) (info gen.ResultInfo, err error)
|
||||
UpdateColumnSimple(columns ...field.AssignExpr) (info gen.ResultInfo, err error)
|
||||
UpdateColumns(value interface{}) (info gen.ResultInfo, err error)
|
||||
UpdateFrom(q gen.SubQuery) gen.Dao
|
||||
Attrs(attrs ...field.AssignExpr) IAppConversationTemplateDraftDo
|
||||
Assign(attrs ...field.AssignExpr) IAppConversationTemplateDraftDo
|
||||
Joins(fields ...field.RelationField) IAppConversationTemplateDraftDo
|
||||
Preload(fields ...field.RelationField) IAppConversationTemplateDraftDo
|
||||
FirstOrInit() (*model.AppConversationTemplateDraft, error)
|
||||
FirstOrCreate() (*model.AppConversationTemplateDraft, error)
|
||||
FindByPage(offset int, limit int) (result []*model.AppConversationTemplateDraft, count int64, err error)
|
||||
ScanByPage(result interface{}, offset int, limit int) (count int64, err error)
|
||||
Scan(result interface{}) (err error)
|
||||
Returning(value interface{}, columns ...string) IAppConversationTemplateDraftDo
|
||||
UnderlyingDB() *gorm.DB
|
||||
schema.Tabler
|
||||
}
|
||||
|
||||
func (a appConversationTemplateDraftDo) Debug() IAppConversationTemplateDraftDo {
|
||||
return a.withDO(a.DO.Debug())
|
||||
}
|
||||
|
||||
func (a appConversationTemplateDraftDo) WithContext(ctx context.Context) IAppConversationTemplateDraftDo {
|
||||
return a.withDO(a.DO.WithContext(ctx))
|
||||
}
|
||||
|
||||
func (a appConversationTemplateDraftDo) ReadDB() IAppConversationTemplateDraftDo {
|
||||
return a.Clauses(dbresolver.Read)
|
||||
}
|
||||
|
||||
func (a appConversationTemplateDraftDo) WriteDB() IAppConversationTemplateDraftDo {
|
||||
return a.Clauses(dbresolver.Write)
|
||||
}
|
||||
|
||||
func (a appConversationTemplateDraftDo) Session(config *gorm.Session) IAppConversationTemplateDraftDo {
|
||||
return a.withDO(a.DO.Session(config))
|
||||
}
|
||||
|
||||
func (a appConversationTemplateDraftDo) Clauses(conds ...clause.Expression) IAppConversationTemplateDraftDo {
|
||||
return a.withDO(a.DO.Clauses(conds...))
|
||||
}
|
||||
|
||||
func (a appConversationTemplateDraftDo) Returning(value interface{}, columns ...string) IAppConversationTemplateDraftDo {
|
||||
return a.withDO(a.DO.Returning(value, columns...))
|
||||
}
|
||||
|
||||
func (a appConversationTemplateDraftDo) Not(conds ...gen.Condition) IAppConversationTemplateDraftDo {
|
||||
return a.withDO(a.DO.Not(conds...))
|
||||
}
|
||||
|
||||
func (a appConversationTemplateDraftDo) Or(conds ...gen.Condition) IAppConversationTemplateDraftDo {
|
||||
return a.withDO(a.DO.Or(conds...))
|
||||
}
|
||||
|
||||
func (a appConversationTemplateDraftDo) Select(conds ...field.Expr) IAppConversationTemplateDraftDo {
|
||||
return a.withDO(a.DO.Select(conds...))
|
||||
}
|
||||
|
||||
func (a appConversationTemplateDraftDo) Where(conds ...gen.Condition) IAppConversationTemplateDraftDo {
|
||||
return a.withDO(a.DO.Where(conds...))
|
||||
}
|
||||
|
||||
func (a appConversationTemplateDraftDo) Order(conds ...field.Expr) IAppConversationTemplateDraftDo {
|
||||
return a.withDO(a.DO.Order(conds...))
|
||||
}
|
||||
|
||||
func (a appConversationTemplateDraftDo) Distinct(cols ...field.Expr) IAppConversationTemplateDraftDo {
|
||||
return a.withDO(a.DO.Distinct(cols...))
|
||||
}
|
||||
|
||||
func (a appConversationTemplateDraftDo) Omit(cols ...field.Expr) IAppConversationTemplateDraftDo {
|
||||
return a.withDO(a.DO.Omit(cols...))
|
||||
}
|
||||
|
||||
func (a appConversationTemplateDraftDo) Join(table schema.Tabler, on ...field.Expr) IAppConversationTemplateDraftDo {
|
||||
return a.withDO(a.DO.Join(table, on...))
|
||||
}
|
||||
|
||||
func (a appConversationTemplateDraftDo) LeftJoin(table schema.Tabler, on ...field.Expr) IAppConversationTemplateDraftDo {
|
||||
return a.withDO(a.DO.LeftJoin(table, on...))
|
||||
}
|
||||
|
||||
func (a appConversationTemplateDraftDo) RightJoin(table schema.Tabler, on ...field.Expr) IAppConversationTemplateDraftDo {
|
||||
return a.withDO(a.DO.RightJoin(table, on...))
|
||||
}
|
||||
|
||||
func (a appConversationTemplateDraftDo) Group(cols ...field.Expr) IAppConversationTemplateDraftDo {
|
||||
return a.withDO(a.DO.Group(cols...))
|
||||
}
|
||||
|
||||
func (a appConversationTemplateDraftDo) Having(conds ...gen.Condition) IAppConversationTemplateDraftDo {
|
||||
return a.withDO(a.DO.Having(conds...))
|
||||
}
|
||||
|
||||
func (a appConversationTemplateDraftDo) Limit(limit int) IAppConversationTemplateDraftDo {
|
||||
return a.withDO(a.DO.Limit(limit))
|
||||
}
|
||||
|
||||
func (a appConversationTemplateDraftDo) Offset(offset int) IAppConversationTemplateDraftDo {
|
||||
return a.withDO(a.DO.Offset(offset))
|
||||
}
|
||||
|
||||
func (a appConversationTemplateDraftDo) Scopes(funcs ...func(gen.Dao) gen.Dao) IAppConversationTemplateDraftDo {
|
||||
return a.withDO(a.DO.Scopes(funcs...))
|
||||
}
|
||||
|
||||
func (a appConversationTemplateDraftDo) Unscoped() IAppConversationTemplateDraftDo {
|
||||
return a.withDO(a.DO.Unscoped())
|
||||
}
|
||||
|
||||
func (a appConversationTemplateDraftDo) Create(values ...*model.AppConversationTemplateDraft) error {
|
||||
if len(values) == 0 {
|
||||
return nil
|
||||
}
|
||||
return a.DO.Create(values)
|
||||
}
|
||||
|
||||
func (a appConversationTemplateDraftDo) CreateInBatches(values []*model.AppConversationTemplateDraft, batchSize int) error {
|
||||
return a.DO.CreateInBatches(values, batchSize)
|
||||
}
|
||||
|
||||
// Save : !!! underlying implementation is different with GORM
|
||||
// The method is equivalent to executing the statement: db.Clauses(clause.OnConflict{UpdateAll: true}).Create(values)
|
||||
func (a appConversationTemplateDraftDo) Save(values ...*model.AppConversationTemplateDraft) error {
|
||||
if len(values) == 0 {
|
||||
return nil
|
||||
}
|
||||
return a.DO.Save(values)
|
||||
}
|
||||
|
||||
func (a appConversationTemplateDraftDo) First() (*model.AppConversationTemplateDraft, error) {
|
||||
if result, err := a.DO.First(); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return result.(*model.AppConversationTemplateDraft), nil
|
||||
}
|
||||
}
|
||||
|
||||
func (a appConversationTemplateDraftDo) Take() (*model.AppConversationTemplateDraft, error) {
|
||||
if result, err := a.DO.Take(); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return result.(*model.AppConversationTemplateDraft), nil
|
||||
}
|
||||
}
|
||||
|
||||
func (a appConversationTemplateDraftDo) Last() (*model.AppConversationTemplateDraft, error) {
|
||||
if result, err := a.DO.Last(); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return result.(*model.AppConversationTemplateDraft), nil
|
||||
}
|
||||
}
|
||||
|
||||
func (a appConversationTemplateDraftDo) Find() ([]*model.AppConversationTemplateDraft, error) {
|
||||
result, err := a.DO.Find()
|
||||
return result.([]*model.AppConversationTemplateDraft), err
|
||||
}
|
||||
|
||||
func (a appConversationTemplateDraftDo) FindInBatch(batchSize int, fc func(tx gen.Dao, batch int) error) (results []*model.AppConversationTemplateDraft, err error) {
|
||||
buf := make([]*model.AppConversationTemplateDraft, 0, batchSize)
|
||||
err = a.DO.FindInBatches(&buf, batchSize, func(tx gen.Dao, batch int) error {
|
||||
defer func() { results = append(results, buf...) }()
|
||||
return fc(tx, batch)
|
||||
})
|
||||
return results, err
|
||||
}
|
||||
|
||||
func (a appConversationTemplateDraftDo) FindInBatches(result *[]*model.AppConversationTemplateDraft, batchSize int, fc func(tx gen.Dao, batch int) error) error {
|
||||
return a.DO.FindInBatches(result, batchSize, fc)
|
||||
}
|
||||
|
||||
func (a appConversationTemplateDraftDo) Attrs(attrs ...field.AssignExpr) IAppConversationTemplateDraftDo {
|
||||
return a.withDO(a.DO.Attrs(attrs...))
|
||||
}
|
||||
|
||||
func (a appConversationTemplateDraftDo) Assign(attrs ...field.AssignExpr) IAppConversationTemplateDraftDo {
|
||||
return a.withDO(a.DO.Assign(attrs...))
|
||||
}
|
||||
|
||||
func (a appConversationTemplateDraftDo) Joins(fields ...field.RelationField) IAppConversationTemplateDraftDo {
|
||||
for _, _f := range fields {
|
||||
a = *a.withDO(a.DO.Joins(_f))
|
||||
}
|
||||
return &a
|
||||
}
|
||||
|
||||
func (a appConversationTemplateDraftDo) Preload(fields ...field.RelationField) IAppConversationTemplateDraftDo {
|
||||
for _, _f := range fields {
|
||||
a = *a.withDO(a.DO.Preload(_f))
|
||||
}
|
||||
return &a
|
||||
}
|
||||
|
||||
func (a appConversationTemplateDraftDo) FirstOrInit() (*model.AppConversationTemplateDraft, error) {
|
||||
if result, err := a.DO.FirstOrInit(); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return result.(*model.AppConversationTemplateDraft), nil
|
||||
}
|
||||
}
|
||||
|
||||
func (a appConversationTemplateDraftDo) FirstOrCreate() (*model.AppConversationTemplateDraft, error) {
|
||||
if result, err := a.DO.FirstOrCreate(); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return result.(*model.AppConversationTemplateDraft), nil
|
||||
}
|
||||
}
|
||||
|
||||
func (a appConversationTemplateDraftDo) FindByPage(offset int, limit int) (result []*model.AppConversationTemplateDraft, count int64, err error) {
|
||||
result, err = a.Offset(offset).Limit(limit).Find()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if size := len(result); 0 < limit && 0 < size && size < limit {
|
||||
count = int64(size + offset)
|
||||
return
|
||||
}
|
||||
|
||||
count, err = a.Offset(-1).Limit(-1).Count()
|
||||
return
|
||||
}
|
||||
|
||||
func (a appConversationTemplateDraftDo) ScanByPage(result interface{}, offset int, limit int) (count int64, err error) {
|
||||
count, err = a.Count()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
err = a.Offset(offset).Limit(limit).Scan(result)
|
||||
return
|
||||
}
|
||||
|
||||
func (a appConversationTemplateDraftDo) Scan(result interface{}) (err error) {
|
||||
return a.DO.Scan(result)
|
||||
}
|
||||
|
||||
func (a appConversationTemplateDraftDo) Delete(models ...*model.AppConversationTemplateDraft) (result gen.ResultInfo, err error) {
|
||||
return a.DO.Delete(models)
|
||||
}
|
||||
|
||||
func (a *appConversationTemplateDraftDo) withDO(do gen.Dao) *appConversationTemplateDraftDo {
|
||||
a.DO = *do.(*gen.DO)
|
||||
return a
|
||||
}
|
||||
@@ -0,0 +1,408 @@
|
||||
// Code generated by gorm.io/gen. DO NOT EDIT.
|
||||
// Code generated by gorm.io/gen. DO NOT EDIT.
|
||||
// Code generated by gorm.io/gen. DO NOT EDIT.
|
||||
|
||||
package query
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"gorm.io/gorm"
|
||||
"gorm.io/gorm/clause"
|
||||
"gorm.io/gorm/schema"
|
||||
|
||||
"gorm.io/gen"
|
||||
"gorm.io/gen/field"
|
||||
|
||||
"gorm.io/plugin/dbresolver"
|
||||
|
||||
"github.com/coze-dev/coze-studio/backend/domain/workflow/internal/repo/dal/model"
|
||||
)
|
||||
|
||||
func newAppConversationTemplateOnline(db *gorm.DB, opts ...gen.DOOption) appConversationTemplateOnline {
|
||||
_appConversationTemplateOnline := appConversationTemplateOnline{}
|
||||
|
||||
_appConversationTemplateOnline.appConversationTemplateOnlineDo.UseDB(db, opts...)
|
||||
_appConversationTemplateOnline.appConversationTemplateOnlineDo.UseModel(&model.AppConversationTemplateOnline{})
|
||||
|
||||
tableName := _appConversationTemplateOnline.appConversationTemplateOnlineDo.TableName()
|
||||
_appConversationTemplateOnline.ALL = field.NewAsterisk(tableName)
|
||||
_appConversationTemplateOnline.ID = field.NewInt64(tableName, "id")
|
||||
_appConversationTemplateOnline.AppID = field.NewInt64(tableName, "app_id")
|
||||
_appConversationTemplateOnline.SpaceID = field.NewInt64(tableName, "space_id")
|
||||
_appConversationTemplateOnline.Name = field.NewString(tableName, "name")
|
||||
_appConversationTemplateOnline.TemplateID = field.NewInt64(tableName, "template_id")
|
||||
_appConversationTemplateOnline.Version = field.NewString(tableName, "version")
|
||||
_appConversationTemplateOnline.CreatorID = field.NewInt64(tableName, "creator_id")
|
||||
_appConversationTemplateOnline.CreatedAt = field.NewInt64(tableName, "created_at")
|
||||
|
||||
_appConversationTemplateOnline.fillFieldMap()
|
||||
|
||||
return _appConversationTemplateOnline
|
||||
}
|
||||
|
||||
type appConversationTemplateOnline struct {
|
||||
appConversationTemplateOnlineDo
|
||||
|
||||
ALL field.Asterisk
|
||||
ID field.Int64 // id
|
||||
AppID field.Int64 // app id
|
||||
SpaceID field.Int64 // space id
|
||||
Name field.String // conversion name
|
||||
TemplateID field.Int64 // template id
|
||||
Version field.String // version name
|
||||
CreatorID field.Int64 // creator id
|
||||
CreatedAt field.Int64 // create time in millisecond
|
||||
|
||||
fieldMap map[string]field.Expr
|
||||
}
|
||||
|
||||
func (a appConversationTemplateOnline) Table(newTableName string) *appConversationTemplateOnline {
|
||||
a.appConversationTemplateOnlineDo.UseTable(newTableName)
|
||||
return a.updateTableName(newTableName)
|
||||
}
|
||||
|
||||
func (a appConversationTemplateOnline) As(alias string) *appConversationTemplateOnline {
|
||||
a.appConversationTemplateOnlineDo.DO = *(a.appConversationTemplateOnlineDo.As(alias).(*gen.DO))
|
||||
return a.updateTableName(alias)
|
||||
}
|
||||
|
||||
func (a *appConversationTemplateOnline) updateTableName(table string) *appConversationTemplateOnline {
|
||||
a.ALL = field.NewAsterisk(table)
|
||||
a.ID = field.NewInt64(table, "id")
|
||||
a.AppID = field.NewInt64(table, "app_id")
|
||||
a.SpaceID = field.NewInt64(table, "space_id")
|
||||
a.Name = field.NewString(table, "name")
|
||||
a.TemplateID = field.NewInt64(table, "template_id")
|
||||
a.Version = field.NewString(table, "version")
|
||||
a.CreatorID = field.NewInt64(table, "creator_id")
|
||||
a.CreatedAt = field.NewInt64(table, "created_at")
|
||||
|
||||
a.fillFieldMap()
|
||||
|
||||
return a
|
||||
}
|
||||
|
||||
func (a *appConversationTemplateOnline) GetFieldByName(fieldName string) (field.OrderExpr, bool) {
|
||||
_f, ok := a.fieldMap[fieldName]
|
||||
if !ok || _f == nil {
|
||||
return nil, false
|
||||
}
|
||||
_oe, ok := _f.(field.OrderExpr)
|
||||
return _oe, ok
|
||||
}
|
||||
|
||||
func (a *appConversationTemplateOnline) fillFieldMap() {
|
||||
a.fieldMap = make(map[string]field.Expr, 8)
|
||||
a.fieldMap["id"] = a.ID
|
||||
a.fieldMap["app_id"] = a.AppID
|
||||
a.fieldMap["space_id"] = a.SpaceID
|
||||
a.fieldMap["name"] = a.Name
|
||||
a.fieldMap["template_id"] = a.TemplateID
|
||||
a.fieldMap["version"] = a.Version
|
||||
a.fieldMap["creator_id"] = a.CreatorID
|
||||
a.fieldMap["created_at"] = a.CreatedAt
|
||||
}
|
||||
|
||||
func (a appConversationTemplateOnline) clone(db *gorm.DB) appConversationTemplateOnline {
|
||||
a.appConversationTemplateOnlineDo.ReplaceConnPool(db.Statement.ConnPool)
|
||||
return a
|
||||
}
|
||||
|
||||
func (a appConversationTemplateOnline) replaceDB(db *gorm.DB) appConversationTemplateOnline {
|
||||
a.appConversationTemplateOnlineDo.ReplaceDB(db)
|
||||
return a
|
||||
}
|
||||
|
||||
type appConversationTemplateOnlineDo struct{ gen.DO }
|
||||
|
||||
type IAppConversationTemplateOnlineDo interface {
|
||||
gen.SubQuery
|
||||
Debug() IAppConversationTemplateOnlineDo
|
||||
WithContext(ctx context.Context) IAppConversationTemplateOnlineDo
|
||||
WithResult(fc func(tx gen.Dao)) gen.ResultInfo
|
||||
ReplaceDB(db *gorm.DB)
|
||||
ReadDB() IAppConversationTemplateOnlineDo
|
||||
WriteDB() IAppConversationTemplateOnlineDo
|
||||
As(alias string) gen.Dao
|
||||
Session(config *gorm.Session) IAppConversationTemplateOnlineDo
|
||||
Columns(cols ...field.Expr) gen.Columns
|
||||
Clauses(conds ...clause.Expression) IAppConversationTemplateOnlineDo
|
||||
Not(conds ...gen.Condition) IAppConversationTemplateOnlineDo
|
||||
Or(conds ...gen.Condition) IAppConversationTemplateOnlineDo
|
||||
Select(conds ...field.Expr) IAppConversationTemplateOnlineDo
|
||||
Where(conds ...gen.Condition) IAppConversationTemplateOnlineDo
|
||||
Order(conds ...field.Expr) IAppConversationTemplateOnlineDo
|
||||
Distinct(cols ...field.Expr) IAppConversationTemplateOnlineDo
|
||||
Omit(cols ...field.Expr) IAppConversationTemplateOnlineDo
|
||||
Join(table schema.Tabler, on ...field.Expr) IAppConversationTemplateOnlineDo
|
||||
LeftJoin(table schema.Tabler, on ...field.Expr) IAppConversationTemplateOnlineDo
|
||||
RightJoin(table schema.Tabler, on ...field.Expr) IAppConversationTemplateOnlineDo
|
||||
Group(cols ...field.Expr) IAppConversationTemplateOnlineDo
|
||||
Having(conds ...gen.Condition) IAppConversationTemplateOnlineDo
|
||||
Limit(limit int) IAppConversationTemplateOnlineDo
|
||||
Offset(offset int) IAppConversationTemplateOnlineDo
|
||||
Count() (count int64, err error)
|
||||
Scopes(funcs ...func(gen.Dao) gen.Dao) IAppConversationTemplateOnlineDo
|
||||
Unscoped() IAppConversationTemplateOnlineDo
|
||||
Create(values ...*model.AppConversationTemplateOnline) error
|
||||
CreateInBatches(values []*model.AppConversationTemplateOnline, batchSize int) error
|
||||
Save(values ...*model.AppConversationTemplateOnline) error
|
||||
First() (*model.AppConversationTemplateOnline, error)
|
||||
Take() (*model.AppConversationTemplateOnline, error)
|
||||
Last() (*model.AppConversationTemplateOnline, error)
|
||||
Find() ([]*model.AppConversationTemplateOnline, error)
|
||||
FindInBatch(batchSize int, fc func(tx gen.Dao, batch int) error) (results []*model.AppConversationTemplateOnline, err error)
|
||||
FindInBatches(result *[]*model.AppConversationTemplateOnline, batchSize int, fc func(tx gen.Dao, batch int) error) error
|
||||
Pluck(column field.Expr, dest interface{}) error
|
||||
Delete(...*model.AppConversationTemplateOnline) (info gen.ResultInfo, err error)
|
||||
Update(column field.Expr, value interface{}) (info gen.ResultInfo, err error)
|
||||
UpdateSimple(columns ...field.AssignExpr) (info gen.ResultInfo, err error)
|
||||
Updates(value interface{}) (info gen.ResultInfo, err error)
|
||||
UpdateColumn(column field.Expr, value interface{}) (info gen.ResultInfo, err error)
|
||||
UpdateColumnSimple(columns ...field.AssignExpr) (info gen.ResultInfo, err error)
|
||||
UpdateColumns(value interface{}) (info gen.ResultInfo, err error)
|
||||
UpdateFrom(q gen.SubQuery) gen.Dao
|
||||
Attrs(attrs ...field.AssignExpr) IAppConversationTemplateOnlineDo
|
||||
Assign(attrs ...field.AssignExpr) IAppConversationTemplateOnlineDo
|
||||
Joins(fields ...field.RelationField) IAppConversationTemplateOnlineDo
|
||||
Preload(fields ...field.RelationField) IAppConversationTemplateOnlineDo
|
||||
FirstOrInit() (*model.AppConversationTemplateOnline, error)
|
||||
FirstOrCreate() (*model.AppConversationTemplateOnline, error)
|
||||
FindByPage(offset int, limit int) (result []*model.AppConversationTemplateOnline, count int64, err error)
|
||||
ScanByPage(result interface{}, offset int, limit int) (count int64, err error)
|
||||
Scan(result interface{}) (err error)
|
||||
Returning(value interface{}, columns ...string) IAppConversationTemplateOnlineDo
|
||||
UnderlyingDB() *gorm.DB
|
||||
schema.Tabler
|
||||
}
|
||||
|
||||
func (a appConversationTemplateOnlineDo) Debug() IAppConversationTemplateOnlineDo {
|
||||
return a.withDO(a.DO.Debug())
|
||||
}
|
||||
|
||||
func (a appConversationTemplateOnlineDo) WithContext(ctx context.Context) IAppConversationTemplateOnlineDo {
|
||||
return a.withDO(a.DO.WithContext(ctx))
|
||||
}
|
||||
|
||||
func (a appConversationTemplateOnlineDo) ReadDB() IAppConversationTemplateOnlineDo {
|
||||
return a.Clauses(dbresolver.Read)
|
||||
}
|
||||
|
||||
func (a appConversationTemplateOnlineDo) WriteDB() IAppConversationTemplateOnlineDo {
|
||||
return a.Clauses(dbresolver.Write)
|
||||
}
|
||||
|
||||
func (a appConversationTemplateOnlineDo) Session(config *gorm.Session) IAppConversationTemplateOnlineDo {
|
||||
return a.withDO(a.DO.Session(config))
|
||||
}
|
||||
|
||||
func (a appConversationTemplateOnlineDo) Clauses(conds ...clause.Expression) IAppConversationTemplateOnlineDo {
|
||||
return a.withDO(a.DO.Clauses(conds...))
|
||||
}
|
||||
|
||||
func (a appConversationTemplateOnlineDo) Returning(value interface{}, columns ...string) IAppConversationTemplateOnlineDo {
|
||||
return a.withDO(a.DO.Returning(value, columns...))
|
||||
}
|
||||
|
||||
func (a appConversationTemplateOnlineDo) Not(conds ...gen.Condition) IAppConversationTemplateOnlineDo {
|
||||
return a.withDO(a.DO.Not(conds...))
|
||||
}
|
||||
|
||||
func (a appConversationTemplateOnlineDo) Or(conds ...gen.Condition) IAppConversationTemplateOnlineDo {
|
||||
return a.withDO(a.DO.Or(conds...))
|
||||
}
|
||||
|
||||
func (a appConversationTemplateOnlineDo) Select(conds ...field.Expr) IAppConversationTemplateOnlineDo {
|
||||
return a.withDO(a.DO.Select(conds...))
|
||||
}
|
||||
|
||||
func (a appConversationTemplateOnlineDo) Where(conds ...gen.Condition) IAppConversationTemplateOnlineDo {
|
||||
return a.withDO(a.DO.Where(conds...))
|
||||
}
|
||||
|
||||
func (a appConversationTemplateOnlineDo) Order(conds ...field.Expr) IAppConversationTemplateOnlineDo {
|
||||
return a.withDO(a.DO.Order(conds...))
|
||||
}
|
||||
|
||||
func (a appConversationTemplateOnlineDo) Distinct(cols ...field.Expr) IAppConversationTemplateOnlineDo {
|
||||
return a.withDO(a.DO.Distinct(cols...))
|
||||
}
|
||||
|
||||
func (a appConversationTemplateOnlineDo) Omit(cols ...field.Expr) IAppConversationTemplateOnlineDo {
|
||||
return a.withDO(a.DO.Omit(cols...))
|
||||
}
|
||||
|
||||
func (a appConversationTemplateOnlineDo) Join(table schema.Tabler, on ...field.Expr) IAppConversationTemplateOnlineDo {
|
||||
return a.withDO(a.DO.Join(table, on...))
|
||||
}
|
||||
|
||||
func (a appConversationTemplateOnlineDo) LeftJoin(table schema.Tabler, on ...field.Expr) IAppConversationTemplateOnlineDo {
|
||||
return a.withDO(a.DO.LeftJoin(table, on...))
|
||||
}
|
||||
|
||||
func (a appConversationTemplateOnlineDo) RightJoin(table schema.Tabler, on ...field.Expr) IAppConversationTemplateOnlineDo {
|
||||
return a.withDO(a.DO.RightJoin(table, on...))
|
||||
}
|
||||
|
||||
func (a appConversationTemplateOnlineDo) Group(cols ...field.Expr) IAppConversationTemplateOnlineDo {
|
||||
return a.withDO(a.DO.Group(cols...))
|
||||
}
|
||||
|
||||
func (a appConversationTemplateOnlineDo) Having(conds ...gen.Condition) IAppConversationTemplateOnlineDo {
|
||||
return a.withDO(a.DO.Having(conds...))
|
||||
}
|
||||
|
||||
func (a appConversationTemplateOnlineDo) Limit(limit int) IAppConversationTemplateOnlineDo {
|
||||
return a.withDO(a.DO.Limit(limit))
|
||||
}
|
||||
|
||||
func (a appConversationTemplateOnlineDo) Offset(offset int) IAppConversationTemplateOnlineDo {
|
||||
return a.withDO(a.DO.Offset(offset))
|
||||
}
|
||||
|
||||
func (a appConversationTemplateOnlineDo) Scopes(funcs ...func(gen.Dao) gen.Dao) IAppConversationTemplateOnlineDo {
|
||||
return a.withDO(a.DO.Scopes(funcs...))
|
||||
}
|
||||
|
||||
func (a appConversationTemplateOnlineDo) Unscoped() IAppConversationTemplateOnlineDo {
|
||||
return a.withDO(a.DO.Unscoped())
|
||||
}
|
||||
|
||||
func (a appConversationTemplateOnlineDo) Create(values ...*model.AppConversationTemplateOnline) error {
|
||||
if len(values) == 0 {
|
||||
return nil
|
||||
}
|
||||
return a.DO.Create(values)
|
||||
}
|
||||
|
||||
func (a appConversationTemplateOnlineDo) CreateInBatches(values []*model.AppConversationTemplateOnline, batchSize int) error {
|
||||
return a.DO.CreateInBatches(values, batchSize)
|
||||
}
|
||||
|
||||
// Save : !!! underlying implementation is different with GORM
|
||||
// The method is equivalent to executing the statement: db.Clauses(clause.OnConflict{UpdateAll: true}).Create(values)
|
||||
func (a appConversationTemplateOnlineDo) Save(values ...*model.AppConversationTemplateOnline) error {
|
||||
if len(values) == 0 {
|
||||
return nil
|
||||
}
|
||||
return a.DO.Save(values)
|
||||
}
|
||||
|
||||
func (a appConversationTemplateOnlineDo) First() (*model.AppConversationTemplateOnline, error) {
|
||||
if result, err := a.DO.First(); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return result.(*model.AppConversationTemplateOnline), nil
|
||||
}
|
||||
}
|
||||
|
||||
func (a appConversationTemplateOnlineDo) Take() (*model.AppConversationTemplateOnline, error) {
|
||||
if result, err := a.DO.Take(); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return result.(*model.AppConversationTemplateOnline), nil
|
||||
}
|
||||
}
|
||||
|
||||
func (a appConversationTemplateOnlineDo) Last() (*model.AppConversationTemplateOnline, error) {
|
||||
if result, err := a.DO.Last(); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return result.(*model.AppConversationTemplateOnline), nil
|
||||
}
|
||||
}
|
||||
|
||||
func (a appConversationTemplateOnlineDo) Find() ([]*model.AppConversationTemplateOnline, error) {
|
||||
result, err := a.DO.Find()
|
||||
return result.([]*model.AppConversationTemplateOnline), err
|
||||
}
|
||||
|
||||
func (a appConversationTemplateOnlineDo) FindInBatch(batchSize int, fc func(tx gen.Dao, batch int) error) (results []*model.AppConversationTemplateOnline, err error) {
|
||||
buf := make([]*model.AppConversationTemplateOnline, 0, batchSize)
|
||||
err = a.DO.FindInBatches(&buf, batchSize, func(tx gen.Dao, batch int) error {
|
||||
defer func() { results = append(results, buf...) }()
|
||||
return fc(tx, batch)
|
||||
})
|
||||
return results, err
|
||||
}
|
||||
|
||||
func (a appConversationTemplateOnlineDo) FindInBatches(result *[]*model.AppConversationTemplateOnline, batchSize int, fc func(tx gen.Dao, batch int) error) error {
|
||||
return a.DO.FindInBatches(result, batchSize, fc)
|
||||
}
|
||||
|
||||
func (a appConversationTemplateOnlineDo) Attrs(attrs ...field.AssignExpr) IAppConversationTemplateOnlineDo {
|
||||
return a.withDO(a.DO.Attrs(attrs...))
|
||||
}
|
||||
|
||||
func (a appConversationTemplateOnlineDo) Assign(attrs ...field.AssignExpr) IAppConversationTemplateOnlineDo {
|
||||
return a.withDO(a.DO.Assign(attrs...))
|
||||
}
|
||||
|
||||
func (a appConversationTemplateOnlineDo) Joins(fields ...field.RelationField) IAppConversationTemplateOnlineDo {
|
||||
for _, _f := range fields {
|
||||
a = *a.withDO(a.DO.Joins(_f))
|
||||
}
|
||||
return &a
|
||||
}
|
||||
|
||||
func (a appConversationTemplateOnlineDo) Preload(fields ...field.RelationField) IAppConversationTemplateOnlineDo {
|
||||
for _, _f := range fields {
|
||||
a = *a.withDO(a.DO.Preload(_f))
|
||||
}
|
||||
return &a
|
||||
}
|
||||
|
||||
func (a appConversationTemplateOnlineDo) FirstOrInit() (*model.AppConversationTemplateOnline, error) {
|
||||
if result, err := a.DO.FirstOrInit(); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return result.(*model.AppConversationTemplateOnline), nil
|
||||
}
|
||||
}
|
||||
|
||||
func (a appConversationTemplateOnlineDo) FirstOrCreate() (*model.AppConversationTemplateOnline, error) {
|
||||
if result, err := a.DO.FirstOrCreate(); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return result.(*model.AppConversationTemplateOnline), nil
|
||||
}
|
||||
}
|
||||
|
||||
func (a appConversationTemplateOnlineDo) FindByPage(offset int, limit int) (result []*model.AppConversationTemplateOnline, count int64, err error) {
|
||||
result, err = a.Offset(offset).Limit(limit).Find()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if size := len(result); 0 < limit && 0 < size && size < limit {
|
||||
count = int64(size + offset)
|
||||
return
|
||||
}
|
||||
|
||||
count, err = a.Offset(-1).Limit(-1).Count()
|
||||
return
|
||||
}
|
||||
|
||||
func (a appConversationTemplateOnlineDo) ScanByPage(result interface{}, offset int, limit int) (count int64, err error) {
|
||||
count, err = a.Count()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
err = a.Offset(offset).Limit(limit).Scan(result)
|
||||
return
|
||||
}
|
||||
|
||||
func (a appConversationTemplateOnlineDo) Scan(result interface{}) (err error) {
|
||||
return a.DO.Scan(result)
|
||||
}
|
||||
|
||||
func (a appConversationTemplateOnlineDo) Delete(models ...*model.AppConversationTemplateOnline) (result gen.ResultInfo, err error) {
|
||||
return a.DO.Delete(models)
|
||||
}
|
||||
|
||||
func (a *appConversationTemplateOnlineDo) withDO(do gen.Dao) *appConversationTemplateOnlineDo {
|
||||
a.DO = *do.(*gen.DO)
|
||||
return a
|
||||
}
|
||||
@@ -0,0 +1,408 @@
|
||||
// Code generated by gorm.io/gen. DO NOT EDIT.
|
||||
// Code generated by gorm.io/gen. DO NOT EDIT.
|
||||
// Code generated by gorm.io/gen. DO NOT EDIT.
|
||||
|
||||
package query
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"gorm.io/gorm"
|
||||
"gorm.io/gorm/clause"
|
||||
"gorm.io/gorm/schema"
|
||||
|
||||
"gorm.io/gen"
|
||||
"gorm.io/gen/field"
|
||||
|
||||
"gorm.io/plugin/dbresolver"
|
||||
|
||||
"github.com/coze-dev/coze-studio/backend/domain/workflow/internal/repo/dal/model"
|
||||
)
|
||||
|
||||
func newAppDynamicConversationDraft(db *gorm.DB, opts ...gen.DOOption) appDynamicConversationDraft {
|
||||
_appDynamicConversationDraft := appDynamicConversationDraft{}
|
||||
|
||||
_appDynamicConversationDraft.appDynamicConversationDraftDo.UseDB(db, opts...)
|
||||
_appDynamicConversationDraft.appDynamicConversationDraftDo.UseModel(&model.AppDynamicConversationDraft{})
|
||||
|
||||
tableName := _appDynamicConversationDraft.appDynamicConversationDraftDo.TableName()
|
||||
_appDynamicConversationDraft.ALL = field.NewAsterisk(tableName)
|
||||
_appDynamicConversationDraft.ID = field.NewInt64(tableName, "id")
|
||||
_appDynamicConversationDraft.AppID = field.NewInt64(tableName, "app_id")
|
||||
_appDynamicConversationDraft.Name = field.NewString(tableName, "name")
|
||||
_appDynamicConversationDraft.UserID = field.NewInt64(tableName, "user_id")
|
||||
_appDynamicConversationDraft.ConnectorID = field.NewInt64(tableName, "connector_id")
|
||||
_appDynamicConversationDraft.ConversationID = field.NewInt64(tableName, "conversation_id")
|
||||
_appDynamicConversationDraft.CreatedAt = field.NewInt64(tableName, "created_at")
|
||||
_appDynamicConversationDraft.DeletedAt = field.NewField(tableName, "deleted_at")
|
||||
|
||||
_appDynamicConversationDraft.fillFieldMap()
|
||||
|
||||
return _appDynamicConversationDraft
|
||||
}
|
||||
|
||||
type appDynamicConversationDraft struct {
|
||||
appDynamicConversationDraftDo
|
||||
|
||||
ALL field.Asterisk
|
||||
ID field.Int64 // id
|
||||
AppID field.Int64 // app id
|
||||
Name field.String // conversion name
|
||||
UserID field.Int64 // user id
|
||||
ConnectorID field.Int64 // connector id
|
||||
ConversationID field.Int64 // conversation id
|
||||
CreatedAt field.Int64 // create time in millisecond
|
||||
DeletedAt field.Field // delete time in millisecond
|
||||
|
||||
fieldMap map[string]field.Expr
|
||||
}
|
||||
|
||||
func (a appDynamicConversationDraft) Table(newTableName string) *appDynamicConversationDraft {
|
||||
a.appDynamicConversationDraftDo.UseTable(newTableName)
|
||||
return a.updateTableName(newTableName)
|
||||
}
|
||||
|
||||
func (a appDynamicConversationDraft) As(alias string) *appDynamicConversationDraft {
|
||||
a.appDynamicConversationDraftDo.DO = *(a.appDynamicConversationDraftDo.As(alias).(*gen.DO))
|
||||
return a.updateTableName(alias)
|
||||
}
|
||||
|
||||
func (a *appDynamicConversationDraft) updateTableName(table string) *appDynamicConversationDraft {
|
||||
a.ALL = field.NewAsterisk(table)
|
||||
a.ID = field.NewInt64(table, "id")
|
||||
a.AppID = field.NewInt64(table, "app_id")
|
||||
a.Name = field.NewString(table, "name")
|
||||
a.UserID = field.NewInt64(table, "user_id")
|
||||
a.ConnectorID = field.NewInt64(table, "connector_id")
|
||||
a.ConversationID = field.NewInt64(table, "conversation_id")
|
||||
a.CreatedAt = field.NewInt64(table, "created_at")
|
||||
a.DeletedAt = field.NewField(table, "deleted_at")
|
||||
|
||||
a.fillFieldMap()
|
||||
|
||||
return a
|
||||
}
|
||||
|
||||
func (a *appDynamicConversationDraft) GetFieldByName(fieldName string) (field.OrderExpr, bool) {
|
||||
_f, ok := a.fieldMap[fieldName]
|
||||
if !ok || _f == nil {
|
||||
return nil, false
|
||||
}
|
||||
_oe, ok := _f.(field.OrderExpr)
|
||||
return _oe, ok
|
||||
}
|
||||
|
||||
func (a *appDynamicConversationDraft) fillFieldMap() {
|
||||
a.fieldMap = make(map[string]field.Expr, 8)
|
||||
a.fieldMap["id"] = a.ID
|
||||
a.fieldMap["app_id"] = a.AppID
|
||||
a.fieldMap["name"] = a.Name
|
||||
a.fieldMap["user_id"] = a.UserID
|
||||
a.fieldMap["connector_id"] = a.ConnectorID
|
||||
a.fieldMap["conversation_id"] = a.ConversationID
|
||||
a.fieldMap["created_at"] = a.CreatedAt
|
||||
a.fieldMap["deleted_at"] = a.DeletedAt
|
||||
}
|
||||
|
||||
func (a appDynamicConversationDraft) clone(db *gorm.DB) appDynamicConversationDraft {
|
||||
a.appDynamicConversationDraftDo.ReplaceConnPool(db.Statement.ConnPool)
|
||||
return a
|
||||
}
|
||||
|
||||
func (a appDynamicConversationDraft) replaceDB(db *gorm.DB) appDynamicConversationDraft {
|
||||
a.appDynamicConversationDraftDo.ReplaceDB(db)
|
||||
return a
|
||||
}
|
||||
|
||||
type appDynamicConversationDraftDo struct{ gen.DO }
|
||||
|
||||
type IAppDynamicConversationDraftDo interface {
|
||||
gen.SubQuery
|
||||
Debug() IAppDynamicConversationDraftDo
|
||||
WithContext(ctx context.Context) IAppDynamicConversationDraftDo
|
||||
WithResult(fc func(tx gen.Dao)) gen.ResultInfo
|
||||
ReplaceDB(db *gorm.DB)
|
||||
ReadDB() IAppDynamicConversationDraftDo
|
||||
WriteDB() IAppDynamicConversationDraftDo
|
||||
As(alias string) gen.Dao
|
||||
Session(config *gorm.Session) IAppDynamicConversationDraftDo
|
||||
Columns(cols ...field.Expr) gen.Columns
|
||||
Clauses(conds ...clause.Expression) IAppDynamicConversationDraftDo
|
||||
Not(conds ...gen.Condition) IAppDynamicConversationDraftDo
|
||||
Or(conds ...gen.Condition) IAppDynamicConversationDraftDo
|
||||
Select(conds ...field.Expr) IAppDynamicConversationDraftDo
|
||||
Where(conds ...gen.Condition) IAppDynamicConversationDraftDo
|
||||
Order(conds ...field.Expr) IAppDynamicConversationDraftDo
|
||||
Distinct(cols ...field.Expr) IAppDynamicConversationDraftDo
|
||||
Omit(cols ...field.Expr) IAppDynamicConversationDraftDo
|
||||
Join(table schema.Tabler, on ...field.Expr) IAppDynamicConversationDraftDo
|
||||
LeftJoin(table schema.Tabler, on ...field.Expr) IAppDynamicConversationDraftDo
|
||||
RightJoin(table schema.Tabler, on ...field.Expr) IAppDynamicConversationDraftDo
|
||||
Group(cols ...field.Expr) IAppDynamicConversationDraftDo
|
||||
Having(conds ...gen.Condition) IAppDynamicConversationDraftDo
|
||||
Limit(limit int) IAppDynamicConversationDraftDo
|
||||
Offset(offset int) IAppDynamicConversationDraftDo
|
||||
Count() (count int64, err error)
|
||||
Scopes(funcs ...func(gen.Dao) gen.Dao) IAppDynamicConversationDraftDo
|
||||
Unscoped() IAppDynamicConversationDraftDo
|
||||
Create(values ...*model.AppDynamicConversationDraft) error
|
||||
CreateInBatches(values []*model.AppDynamicConversationDraft, batchSize int) error
|
||||
Save(values ...*model.AppDynamicConversationDraft) error
|
||||
First() (*model.AppDynamicConversationDraft, error)
|
||||
Take() (*model.AppDynamicConversationDraft, error)
|
||||
Last() (*model.AppDynamicConversationDraft, error)
|
||||
Find() ([]*model.AppDynamicConversationDraft, error)
|
||||
FindInBatch(batchSize int, fc func(tx gen.Dao, batch int) error) (results []*model.AppDynamicConversationDraft, err error)
|
||||
FindInBatches(result *[]*model.AppDynamicConversationDraft, batchSize int, fc func(tx gen.Dao, batch int) error) error
|
||||
Pluck(column field.Expr, dest interface{}) error
|
||||
Delete(...*model.AppDynamicConversationDraft) (info gen.ResultInfo, err error)
|
||||
Update(column field.Expr, value interface{}) (info gen.ResultInfo, err error)
|
||||
UpdateSimple(columns ...field.AssignExpr) (info gen.ResultInfo, err error)
|
||||
Updates(value interface{}) (info gen.ResultInfo, err error)
|
||||
UpdateColumn(column field.Expr, value interface{}) (info gen.ResultInfo, err error)
|
||||
UpdateColumnSimple(columns ...field.AssignExpr) (info gen.ResultInfo, err error)
|
||||
UpdateColumns(value interface{}) (info gen.ResultInfo, err error)
|
||||
UpdateFrom(q gen.SubQuery) gen.Dao
|
||||
Attrs(attrs ...field.AssignExpr) IAppDynamicConversationDraftDo
|
||||
Assign(attrs ...field.AssignExpr) IAppDynamicConversationDraftDo
|
||||
Joins(fields ...field.RelationField) IAppDynamicConversationDraftDo
|
||||
Preload(fields ...field.RelationField) IAppDynamicConversationDraftDo
|
||||
FirstOrInit() (*model.AppDynamicConversationDraft, error)
|
||||
FirstOrCreate() (*model.AppDynamicConversationDraft, error)
|
||||
FindByPage(offset int, limit int) (result []*model.AppDynamicConversationDraft, count int64, err error)
|
||||
ScanByPage(result interface{}, offset int, limit int) (count int64, err error)
|
||||
Scan(result interface{}) (err error)
|
||||
Returning(value interface{}, columns ...string) IAppDynamicConversationDraftDo
|
||||
UnderlyingDB() *gorm.DB
|
||||
schema.Tabler
|
||||
}
|
||||
|
||||
func (a appDynamicConversationDraftDo) Debug() IAppDynamicConversationDraftDo {
|
||||
return a.withDO(a.DO.Debug())
|
||||
}
|
||||
|
||||
func (a appDynamicConversationDraftDo) WithContext(ctx context.Context) IAppDynamicConversationDraftDo {
|
||||
return a.withDO(a.DO.WithContext(ctx))
|
||||
}
|
||||
|
||||
func (a appDynamicConversationDraftDo) ReadDB() IAppDynamicConversationDraftDo {
|
||||
return a.Clauses(dbresolver.Read)
|
||||
}
|
||||
|
||||
func (a appDynamicConversationDraftDo) WriteDB() IAppDynamicConversationDraftDo {
|
||||
return a.Clauses(dbresolver.Write)
|
||||
}
|
||||
|
||||
func (a appDynamicConversationDraftDo) Session(config *gorm.Session) IAppDynamicConversationDraftDo {
|
||||
return a.withDO(a.DO.Session(config))
|
||||
}
|
||||
|
||||
func (a appDynamicConversationDraftDo) Clauses(conds ...clause.Expression) IAppDynamicConversationDraftDo {
|
||||
return a.withDO(a.DO.Clauses(conds...))
|
||||
}
|
||||
|
||||
func (a appDynamicConversationDraftDo) Returning(value interface{}, columns ...string) IAppDynamicConversationDraftDo {
|
||||
return a.withDO(a.DO.Returning(value, columns...))
|
||||
}
|
||||
|
||||
func (a appDynamicConversationDraftDo) Not(conds ...gen.Condition) IAppDynamicConversationDraftDo {
|
||||
return a.withDO(a.DO.Not(conds...))
|
||||
}
|
||||
|
||||
func (a appDynamicConversationDraftDo) Or(conds ...gen.Condition) IAppDynamicConversationDraftDo {
|
||||
return a.withDO(a.DO.Or(conds...))
|
||||
}
|
||||
|
||||
func (a appDynamicConversationDraftDo) Select(conds ...field.Expr) IAppDynamicConversationDraftDo {
|
||||
return a.withDO(a.DO.Select(conds...))
|
||||
}
|
||||
|
||||
func (a appDynamicConversationDraftDo) Where(conds ...gen.Condition) IAppDynamicConversationDraftDo {
|
||||
return a.withDO(a.DO.Where(conds...))
|
||||
}
|
||||
|
||||
func (a appDynamicConversationDraftDo) Order(conds ...field.Expr) IAppDynamicConversationDraftDo {
|
||||
return a.withDO(a.DO.Order(conds...))
|
||||
}
|
||||
|
||||
func (a appDynamicConversationDraftDo) Distinct(cols ...field.Expr) IAppDynamicConversationDraftDo {
|
||||
return a.withDO(a.DO.Distinct(cols...))
|
||||
}
|
||||
|
||||
func (a appDynamicConversationDraftDo) Omit(cols ...field.Expr) IAppDynamicConversationDraftDo {
|
||||
return a.withDO(a.DO.Omit(cols...))
|
||||
}
|
||||
|
||||
func (a appDynamicConversationDraftDo) Join(table schema.Tabler, on ...field.Expr) IAppDynamicConversationDraftDo {
|
||||
return a.withDO(a.DO.Join(table, on...))
|
||||
}
|
||||
|
||||
func (a appDynamicConversationDraftDo) LeftJoin(table schema.Tabler, on ...field.Expr) IAppDynamicConversationDraftDo {
|
||||
return a.withDO(a.DO.LeftJoin(table, on...))
|
||||
}
|
||||
|
||||
func (a appDynamicConversationDraftDo) RightJoin(table schema.Tabler, on ...field.Expr) IAppDynamicConversationDraftDo {
|
||||
return a.withDO(a.DO.RightJoin(table, on...))
|
||||
}
|
||||
|
||||
func (a appDynamicConversationDraftDo) Group(cols ...field.Expr) IAppDynamicConversationDraftDo {
|
||||
return a.withDO(a.DO.Group(cols...))
|
||||
}
|
||||
|
||||
func (a appDynamicConversationDraftDo) Having(conds ...gen.Condition) IAppDynamicConversationDraftDo {
|
||||
return a.withDO(a.DO.Having(conds...))
|
||||
}
|
||||
|
||||
func (a appDynamicConversationDraftDo) Limit(limit int) IAppDynamicConversationDraftDo {
|
||||
return a.withDO(a.DO.Limit(limit))
|
||||
}
|
||||
|
||||
func (a appDynamicConversationDraftDo) Offset(offset int) IAppDynamicConversationDraftDo {
|
||||
return a.withDO(a.DO.Offset(offset))
|
||||
}
|
||||
|
||||
func (a appDynamicConversationDraftDo) Scopes(funcs ...func(gen.Dao) gen.Dao) IAppDynamicConversationDraftDo {
|
||||
return a.withDO(a.DO.Scopes(funcs...))
|
||||
}
|
||||
|
||||
func (a appDynamicConversationDraftDo) Unscoped() IAppDynamicConversationDraftDo {
|
||||
return a.withDO(a.DO.Unscoped())
|
||||
}
|
||||
|
||||
func (a appDynamicConversationDraftDo) Create(values ...*model.AppDynamicConversationDraft) error {
|
||||
if len(values) == 0 {
|
||||
return nil
|
||||
}
|
||||
return a.DO.Create(values)
|
||||
}
|
||||
|
||||
func (a appDynamicConversationDraftDo) CreateInBatches(values []*model.AppDynamicConversationDraft, batchSize int) error {
|
||||
return a.DO.CreateInBatches(values, batchSize)
|
||||
}
|
||||
|
||||
// Save : !!! underlying implementation is different with GORM
|
||||
// The method is equivalent to executing the statement: db.Clauses(clause.OnConflict{UpdateAll: true}).Create(values)
|
||||
func (a appDynamicConversationDraftDo) Save(values ...*model.AppDynamicConversationDraft) error {
|
||||
if len(values) == 0 {
|
||||
return nil
|
||||
}
|
||||
return a.DO.Save(values)
|
||||
}
|
||||
|
||||
func (a appDynamicConversationDraftDo) First() (*model.AppDynamicConversationDraft, error) {
|
||||
if result, err := a.DO.First(); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return result.(*model.AppDynamicConversationDraft), nil
|
||||
}
|
||||
}
|
||||
|
||||
func (a appDynamicConversationDraftDo) Take() (*model.AppDynamicConversationDraft, error) {
|
||||
if result, err := a.DO.Take(); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return result.(*model.AppDynamicConversationDraft), nil
|
||||
}
|
||||
}
|
||||
|
||||
func (a appDynamicConversationDraftDo) Last() (*model.AppDynamicConversationDraft, error) {
|
||||
if result, err := a.DO.Last(); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return result.(*model.AppDynamicConversationDraft), nil
|
||||
}
|
||||
}
|
||||
|
||||
func (a appDynamicConversationDraftDo) Find() ([]*model.AppDynamicConversationDraft, error) {
|
||||
result, err := a.DO.Find()
|
||||
return result.([]*model.AppDynamicConversationDraft), err
|
||||
}
|
||||
|
||||
func (a appDynamicConversationDraftDo) FindInBatch(batchSize int, fc func(tx gen.Dao, batch int) error) (results []*model.AppDynamicConversationDraft, err error) {
|
||||
buf := make([]*model.AppDynamicConversationDraft, 0, batchSize)
|
||||
err = a.DO.FindInBatches(&buf, batchSize, func(tx gen.Dao, batch int) error {
|
||||
defer func() { results = append(results, buf...) }()
|
||||
return fc(tx, batch)
|
||||
})
|
||||
return results, err
|
||||
}
|
||||
|
||||
func (a appDynamicConversationDraftDo) FindInBatches(result *[]*model.AppDynamicConversationDraft, batchSize int, fc func(tx gen.Dao, batch int) error) error {
|
||||
return a.DO.FindInBatches(result, batchSize, fc)
|
||||
}
|
||||
|
||||
func (a appDynamicConversationDraftDo) Attrs(attrs ...field.AssignExpr) IAppDynamicConversationDraftDo {
|
||||
return a.withDO(a.DO.Attrs(attrs...))
|
||||
}
|
||||
|
||||
func (a appDynamicConversationDraftDo) Assign(attrs ...field.AssignExpr) IAppDynamicConversationDraftDo {
|
||||
return a.withDO(a.DO.Assign(attrs...))
|
||||
}
|
||||
|
||||
func (a appDynamicConversationDraftDo) Joins(fields ...field.RelationField) IAppDynamicConversationDraftDo {
|
||||
for _, _f := range fields {
|
||||
a = *a.withDO(a.DO.Joins(_f))
|
||||
}
|
||||
return &a
|
||||
}
|
||||
|
||||
func (a appDynamicConversationDraftDo) Preload(fields ...field.RelationField) IAppDynamicConversationDraftDo {
|
||||
for _, _f := range fields {
|
||||
a = *a.withDO(a.DO.Preload(_f))
|
||||
}
|
||||
return &a
|
||||
}
|
||||
|
||||
func (a appDynamicConversationDraftDo) FirstOrInit() (*model.AppDynamicConversationDraft, error) {
|
||||
if result, err := a.DO.FirstOrInit(); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return result.(*model.AppDynamicConversationDraft), nil
|
||||
}
|
||||
}
|
||||
|
||||
func (a appDynamicConversationDraftDo) FirstOrCreate() (*model.AppDynamicConversationDraft, error) {
|
||||
if result, err := a.DO.FirstOrCreate(); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return result.(*model.AppDynamicConversationDraft), nil
|
||||
}
|
||||
}
|
||||
|
||||
func (a appDynamicConversationDraftDo) FindByPage(offset int, limit int) (result []*model.AppDynamicConversationDraft, count int64, err error) {
|
||||
result, err = a.Offset(offset).Limit(limit).Find()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if size := len(result); 0 < limit && 0 < size && size < limit {
|
||||
count = int64(size + offset)
|
||||
return
|
||||
}
|
||||
|
||||
count, err = a.Offset(-1).Limit(-1).Count()
|
||||
return
|
||||
}
|
||||
|
||||
func (a appDynamicConversationDraftDo) ScanByPage(result interface{}, offset int, limit int) (count int64, err error) {
|
||||
count, err = a.Count()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
err = a.Offset(offset).Limit(limit).Scan(result)
|
||||
return
|
||||
}
|
||||
|
||||
func (a appDynamicConversationDraftDo) Scan(result interface{}) (err error) {
|
||||
return a.DO.Scan(result)
|
||||
}
|
||||
|
||||
func (a appDynamicConversationDraftDo) Delete(models ...*model.AppDynamicConversationDraft) (result gen.ResultInfo, err error) {
|
||||
return a.DO.Delete(models)
|
||||
}
|
||||
|
||||
func (a *appDynamicConversationDraftDo) withDO(do gen.Dao) *appDynamicConversationDraftDo {
|
||||
a.DO = *do.(*gen.DO)
|
||||
return a
|
||||
}
|
||||
@@ -0,0 +1,408 @@
|
||||
// Code generated by gorm.io/gen. DO NOT EDIT.
|
||||
// Code generated by gorm.io/gen. DO NOT EDIT.
|
||||
// Code generated by gorm.io/gen. DO NOT EDIT.
|
||||
|
||||
package query
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"gorm.io/gorm"
|
||||
"gorm.io/gorm/clause"
|
||||
"gorm.io/gorm/schema"
|
||||
|
||||
"gorm.io/gen"
|
||||
"gorm.io/gen/field"
|
||||
|
||||
"gorm.io/plugin/dbresolver"
|
||||
|
||||
"github.com/coze-dev/coze-studio/backend/domain/workflow/internal/repo/dal/model"
|
||||
)
|
||||
|
||||
func newAppDynamicConversationOnline(db *gorm.DB, opts ...gen.DOOption) appDynamicConversationOnline {
|
||||
_appDynamicConversationOnline := appDynamicConversationOnline{}
|
||||
|
||||
_appDynamicConversationOnline.appDynamicConversationOnlineDo.UseDB(db, opts...)
|
||||
_appDynamicConversationOnline.appDynamicConversationOnlineDo.UseModel(&model.AppDynamicConversationOnline{})
|
||||
|
||||
tableName := _appDynamicConversationOnline.appDynamicConversationOnlineDo.TableName()
|
||||
_appDynamicConversationOnline.ALL = field.NewAsterisk(tableName)
|
||||
_appDynamicConversationOnline.ID = field.NewInt64(tableName, "id")
|
||||
_appDynamicConversationOnline.AppID = field.NewInt64(tableName, "app_id")
|
||||
_appDynamicConversationOnline.Name = field.NewString(tableName, "name")
|
||||
_appDynamicConversationOnline.UserID = field.NewInt64(tableName, "user_id")
|
||||
_appDynamicConversationOnline.ConnectorID = field.NewInt64(tableName, "connector_id")
|
||||
_appDynamicConversationOnline.ConversationID = field.NewInt64(tableName, "conversation_id")
|
||||
_appDynamicConversationOnline.CreatedAt = field.NewInt64(tableName, "created_at")
|
||||
_appDynamicConversationOnline.DeletedAt = field.NewField(tableName, "deleted_at")
|
||||
|
||||
_appDynamicConversationOnline.fillFieldMap()
|
||||
|
||||
return _appDynamicConversationOnline
|
||||
}
|
||||
|
||||
type appDynamicConversationOnline struct {
|
||||
appDynamicConversationOnlineDo
|
||||
|
||||
ALL field.Asterisk
|
||||
ID field.Int64 // id
|
||||
AppID field.Int64 // app id
|
||||
Name field.String // conversion name
|
||||
UserID field.Int64 // user id
|
||||
ConnectorID field.Int64 // connector id
|
||||
ConversationID field.Int64 // conversation id
|
||||
CreatedAt field.Int64 // create time in millisecond
|
||||
DeletedAt field.Field // delete time in millisecond
|
||||
|
||||
fieldMap map[string]field.Expr
|
||||
}
|
||||
|
||||
func (a appDynamicConversationOnline) Table(newTableName string) *appDynamicConversationOnline {
|
||||
a.appDynamicConversationOnlineDo.UseTable(newTableName)
|
||||
return a.updateTableName(newTableName)
|
||||
}
|
||||
|
||||
func (a appDynamicConversationOnline) As(alias string) *appDynamicConversationOnline {
|
||||
a.appDynamicConversationOnlineDo.DO = *(a.appDynamicConversationOnlineDo.As(alias).(*gen.DO))
|
||||
return a.updateTableName(alias)
|
||||
}
|
||||
|
||||
func (a *appDynamicConversationOnline) updateTableName(table string) *appDynamicConversationOnline {
|
||||
a.ALL = field.NewAsterisk(table)
|
||||
a.ID = field.NewInt64(table, "id")
|
||||
a.AppID = field.NewInt64(table, "app_id")
|
||||
a.Name = field.NewString(table, "name")
|
||||
a.UserID = field.NewInt64(table, "user_id")
|
||||
a.ConnectorID = field.NewInt64(table, "connector_id")
|
||||
a.ConversationID = field.NewInt64(table, "conversation_id")
|
||||
a.CreatedAt = field.NewInt64(table, "created_at")
|
||||
a.DeletedAt = field.NewField(table, "deleted_at")
|
||||
|
||||
a.fillFieldMap()
|
||||
|
||||
return a
|
||||
}
|
||||
|
||||
func (a *appDynamicConversationOnline) GetFieldByName(fieldName string) (field.OrderExpr, bool) {
|
||||
_f, ok := a.fieldMap[fieldName]
|
||||
if !ok || _f == nil {
|
||||
return nil, false
|
||||
}
|
||||
_oe, ok := _f.(field.OrderExpr)
|
||||
return _oe, ok
|
||||
}
|
||||
|
||||
func (a *appDynamicConversationOnline) fillFieldMap() {
|
||||
a.fieldMap = make(map[string]field.Expr, 8)
|
||||
a.fieldMap["id"] = a.ID
|
||||
a.fieldMap["app_id"] = a.AppID
|
||||
a.fieldMap["name"] = a.Name
|
||||
a.fieldMap["user_id"] = a.UserID
|
||||
a.fieldMap["connector_id"] = a.ConnectorID
|
||||
a.fieldMap["conversation_id"] = a.ConversationID
|
||||
a.fieldMap["created_at"] = a.CreatedAt
|
||||
a.fieldMap["deleted_at"] = a.DeletedAt
|
||||
}
|
||||
|
||||
func (a appDynamicConversationOnline) clone(db *gorm.DB) appDynamicConversationOnline {
|
||||
a.appDynamicConversationOnlineDo.ReplaceConnPool(db.Statement.ConnPool)
|
||||
return a
|
||||
}
|
||||
|
||||
func (a appDynamicConversationOnline) replaceDB(db *gorm.DB) appDynamicConversationOnline {
|
||||
a.appDynamicConversationOnlineDo.ReplaceDB(db)
|
||||
return a
|
||||
}
|
||||
|
||||
type appDynamicConversationOnlineDo struct{ gen.DO }
|
||||
|
||||
type IAppDynamicConversationOnlineDo interface {
|
||||
gen.SubQuery
|
||||
Debug() IAppDynamicConversationOnlineDo
|
||||
WithContext(ctx context.Context) IAppDynamicConversationOnlineDo
|
||||
WithResult(fc func(tx gen.Dao)) gen.ResultInfo
|
||||
ReplaceDB(db *gorm.DB)
|
||||
ReadDB() IAppDynamicConversationOnlineDo
|
||||
WriteDB() IAppDynamicConversationOnlineDo
|
||||
As(alias string) gen.Dao
|
||||
Session(config *gorm.Session) IAppDynamicConversationOnlineDo
|
||||
Columns(cols ...field.Expr) gen.Columns
|
||||
Clauses(conds ...clause.Expression) IAppDynamicConversationOnlineDo
|
||||
Not(conds ...gen.Condition) IAppDynamicConversationOnlineDo
|
||||
Or(conds ...gen.Condition) IAppDynamicConversationOnlineDo
|
||||
Select(conds ...field.Expr) IAppDynamicConversationOnlineDo
|
||||
Where(conds ...gen.Condition) IAppDynamicConversationOnlineDo
|
||||
Order(conds ...field.Expr) IAppDynamicConversationOnlineDo
|
||||
Distinct(cols ...field.Expr) IAppDynamicConversationOnlineDo
|
||||
Omit(cols ...field.Expr) IAppDynamicConversationOnlineDo
|
||||
Join(table schema.Tabler, on ...field.Expr) IAppDynamicConversationOnlineDo
|
||||
LeftJoin(table schema.Tabler, on ...field.Expr) IAppDynamicConversationOnlineDo
|
||||
RightJoin(table schema.Tabler, on ...field.Expr) IAppDynamicConversationOnlineDo
|
||||
Group(cols ...field.Expr) IAppDynamicConversationOnlineDo
|
||||
Having(conds ...gen.Condition) IAppDynamicConversationOnlineDo
|
||||
Limit(limit int) IAppDynamicConversationOnlineDo
|
||||
Offset(offset int) IAppDynamicConversationOnlineDo
|
||||
Count() (count int64, err error)
|
||||
Scopes(funcs ...func(gen.Dao) gen.Dao) IAppDynamicConversationOnlineDo
|
||||
Unscoped() IAppDynamicConversationOnlineDo
|
||||
Create(values ...*model.AppDynamicConversationOnline) error
|
||||
CreateInBatches(values []*model.AppDynamicConversationOnline, batchSize int) error
|
||||
Save(values ...*model.AppDynamicConversationOnline) error
|
||||
First() (*model.AppDynamicConversationOnline, error)
|
||||
Take() (*model.AppDynamicConversationOnline, error)
|
||||
Last() (*model.AppDynamicConversationOnline, error)
|
||||
Find() ([]*model.AppDynamicConversationOnline, error)
|
||||
FindInBatch(batchSize int, fc func(tx gen.Dao, batch int) error) (results []*model.AppDynamicConversationOnline, err error)
|
||||
FindInBatches(result *[]*model.AppDynamicConversationOnline, batchSize int, fc func(tx gen.Dao, batch int) error) error
|
||||
Pluck(column field.Expr, dest interface{}) error
|
||||
Delete(...*model.AppDynamicConversationOnline) (info gen.ResultInfo, err error)
|
||||
Update(column field.Expr, value interface{}) (info gen.ResultInfo, err error)
|
||||
UpdateSimple(columns ...field.AssignExpr) (info gen.ResultInfo, err error)
|
||||
Updates(value interface{}) (info gen.ResultInfo, err error)
|
||||
UpdateColumn(column field.Expr, value interface{}) (info gen.ResultInfo, err error)
|
||||
UpdateColumnSimple(columns ...field.AssignExpr) (info gen.ResultInfo, err error)
|
||||
UpdateColumns(value interface{}) (info gen.ResultInfo, err error)
|
||||
UpdateFrom(q gen.SubQuery) gen.Dao
|
||||
Attrs(attrs ...field.AssignExpr) IAppDynamicConversationOnlineDo
|
||||
Assign(attrs ...field.AssignExpr) IAppDynamicConversationOnlineDo
|
||||
Joins(fields ...field.RelationField) IAppDynamicConversationOnlineDo
|
||||
Preload(fields ...field.RelationField) IAppDynamicConversationOnlineDo
|
||||
FirstOrInit() (*model.AppDynamicConversationOnline, error)
|
||||
FirstOrCreate() (*model.AppDynamicConversationOnline, error)
|
||||
FindByPage(offset int, limit int) (result []*model.AppDynamicConversationOnline, count int64, err error)
|
||||
ScanByPage(result interface{}, offset int, limit int) (count int64, err error)
|
||||
Scan(result interface{}) (err error)
|
||||
Returning(value interface{}, columns ...string) IAppDynamicConversationOnlineDo
|
||||
UnderlyingDB() *gorm.DB
|
||||
schema.Tabler
|
||||
}
|
||||
|
||||
func (a appDynamicConversationOnlineDo) Debug() IAppDynamicConversationOnlineDo {
|
||||
return a.withDO(a.DO.Debug())
|
||||
}
|
||||
|
||||
func (a appDynamicConversationOnlineDo) WithContext(ctx context.Context) IAppDynamicConversationOnlineDo {
|
||||
return a.withDO(a.DO.WithContext(ctx))
|
||||
}
|
||||
|
||||
func (a appDynamicConversationOnlineDo) ReadDB() IAppDynamicConversationOnlineDo {
|
||||
return a.Clauses(dbresolver.Read)
|
||||
}
|
||||
|
||||
func (a appDynamicConversationOnlineDo) WriteDB() IAppDynamicConversationOnlineDo {
|
||||
return a.Clauses(dbresolver.Write)
|
||||
}
|
||||
|
||||
func (a appDynamicConversationOnlineDo) Session(config *gorm.Session) IAppDynamicConversationOnlineDo {
|
||||
return a.withDO(a.DO.Session(config))
|
||||
}
|
||||
|
||||
func (a appDynamicConversationOnlineDo) Clauses(conds ...clause.Expression) IAppDynamicConversationOnlineDo {
|
||||
return a.withDO(a.DO.Clauses(conds...))
|
||||
}
|
||||
|
||||
func (a appDynamicConversationOnlineDo) Returning(value interface{}, columns ...string) IAppDynamicConversationOnlineDo {
|
||||
return a.withDO(a.DO.Returning(value, columns...))
|
||||
}
|
||||
|
||||
func (a appDynamicConversationOnlineDo) Not(conds ...gen.Condition) IAppDynamicConversationOnlineDo {
|
||||
return a.withDO(a.DO.Not(conds...))
|
||||
}
|
||||
|
||||
func (a appDynamicConversationOnlineDo) Or(conds ...gen.Condition) IAppDynamicConversationOnlineDo {
|
||||
return a.withDO(a.DO.Or(conds...))
|
||||
}
|
||||
|
||||
func (a appDynamicConversationOnlineDo) Select(conds ...field.Expr) IAppDynamicConversationOnlineDo {
|
||||
return a.withDO(a.DO.Select(conds...))
|
||||
}
|
||||
|
||||
func (a appDynamicConversationOnlineDo) Where(conds ...gen.Condition) IAppDynamicConversationOnlineDo {
|
||||
return a.withDO(a.DO.Where(conds...))
|
||||
}
|
||||
|
||||
func (a appDynamicConversationOnlineDo) Order(conds ...field.Expr) IAppDynamicConversationOnlineDo {
|
||||
return a.withDO(a.DO.Order(conds...))
|
||||
}
|
||||
|
||||
func (a appDynamicConversationOnlineDo) Distinct(cols ...field.Expr) IAppDynamicConversationOnlineDo {
|
||||
return a.withDO(a.DO.Distinct(cols...))
|
||||
}
|
||||
|
||||
func (a appDynamicConversationOnlineDo) Omit(cols ...field.Expr) IAppDynamicConversationOnlineDo {
|
||||
return a.withDO(a.DO.Omit(cols...))
|
||||
}
|
||||
|
||||
func (a appDynamicConversationOnlineDo) Join(table schema.Tabler, on ...field.Expr) IAppDynamicConversationOnlineDo {
|
||||
return a.withDO(a.DO.Join(table, on...))
|
||||
}
|
||||
|
||||
func (a appDynamicConversationOnlineDo) LeftJoin(table schema.Tabler, on ...field.Expr) IAppDynamicConversationOnlineDo {
|
||||
return a.withDO(a.DO.LeftJoin(table, on...))
|
||||
}
|
||||
|
||||
func (a appDynamicConversationOnlineDo) RightJoin(table schema.Tabler, on ...field.Expr) IAppDynamicConversationOnlineDo {
|
||||
return a.withDO(a.DO.RightJoin(table, on...))
|
||||
}
|
||||
|
||||
func (a appDynamicConversationOnlineDo) Group(cols ...field.Expr) IAppDynamicConversationOnlineDo {
|
||||
return a.withDO(a.DO.Group(cols...))
|
||||
}
|
||||
|
||||
func (a appDynamicConversationOnlineDo) Having(conds ...gen.Condition) IAppDynamicConversationOnlineDo {
|
||||
return a.withDO(a.DO.Having(conds...))
|
||||
}
|
||||
|
||||
func (a appDynamicConversationOnlineDo) Limit(limit int) IAppDynamicConversationOnlineDo {
|
||||
return a.withDO(a.DO.Limit(limit))
|
||||
}
|
||||
|
||||
func (a appDynamicConversationOnlineDo) Offset(offset int) IAppDynamicConversationOnlineDo {
|
||||
return a.withDO(a.DO.Offset(offset))
|
||||
}
|
||||
|
||||
func (a appDynamicConversationOnlineDo) Scopes(funcs ...func(gen.Dao) gen.Dao) IAppDynamicConversationOnlineDo {
|
||||
return a.withDO(a.DO.Scopes(funcs...))
|
||||
}
|
||||
|
||||
func (a appDynamicConversationOnlineDo) Unscoped() IAppDynamicConversationOnlineDo {
|
||||
return a.withDO(a.DO.Unscoped())
|
||||
}
|
||||
|
||||
func (a appDynamicConversationOnlineDo) Create(values ...*model.AppDynamicConversationOnline) error {
|
||||
if len(values) == 0 {
|
||||
return nil
|
||||
}
|
||||
return a.DO.Create(values)
|
||||
}
|
||||
|
||||
func (a appDynamicConversationOnlineDo) CreateInBatches(values []*model.AppDynamicConversationOnline, batchSize int) error {
|
||||
return a.DO.CreateInBatches(values, batchSize)
|
||||
}
|
||||
|
||||
// Save : !!! underlying implementation is different with GORM
|
||||
// The method is equivalent to executing the statement: db.Clauses(clause.OnConflict{UpdateAll: true}).Create(values)
|
||||
func (a appDynamicConversationOnlineDo) Save(values ...*model.AppDynamicConversationOnline) error {
|
||||
if len(values) == 0 {
|
||||
return nil
|
||||
}
|
||||
return a.DO.Save(values)
|
||||
}
|
||||
|
||||
func (a appDynamicConversationOnlineDo) First() (*model.AppDynamicConversationOnline, error) {
|
||||
if result, err := a.DO.First(); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return result.(*model.AppDynamicConversationOnline), nil
|
||||
}
|
||||
}
|
||||
|
||||
func (a appDynamicConversationOnlineDo) Take() (*model.AppDynamicConversationOnline, error) {
|
||||
if result, err := a.DO.Take(); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return result.(*model.AppDynamicConversationOnline), nil
|
||||
}
|
||||
}
|
||||
|
||||
func (a appDynamicConversationOnlineDo) Last() (*model.AppDynamicConversationOnline, error) {
|
||||
if result, err := a.DO.Last(); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return result.(*model.AppDynamicConversationOnline), nil
|
||||
}
|
||||
}
|
||||
|
||||
func (a appDynamicConversationOnlineDo) Find() ([]*model.AppDynamicConversationOnline, error) {
|
||||
result, err := a.DO.Find()
|
||||
return result.([]*model.AppDynamicConversationOnline), err
|
||||
}
|
||||
|
||||
func (a appDynamicConversationOnlineDo) FindInBatch(batchSize int, fc func(tx gen.Dao, batch int) error) (results []*model.AppDynamicConversationOnline, err error) {
|
||||
buf := make([]*model.AppDynamicConversationOnline, 0, batchSize)
|
||||
err = a.DO.FindInBatches(&buf, batchSize, func(tx gen.Dao, batch int) error {
|
||||
defer func() { results = append(results, buf...) }()
|
||||
return fc(tx, batch)
|
||||
})
|
||||
return results, err
|
||||
}
|
||||
|
||||
func (a appDynamicConversationOnlineDo) FindInBatches(result *[]*model.AppDynamicConversationOnline, batchSize int, fc func(tx gen.Dao, batch int) error) error {
|
||||
return a.DO.FindInBatches(result, batchSize, fc)
|
||||
}
|
||||
|
||||
func (a appDynamicConversationOnlineDo) Attrs(attrs ...field.AssignExpr) IAppDynamicConversationOnlineDo {
|
||||
return a.withDO(a.DO.Attrs(attrs...))
|
||||
}
|
||||
|
||||
func (a appDynamicConversationOnlineDo) Assign(attrs ...field.AssignExpr) IAppDynamicConversationOnlineDo {
|
||||
return a.withDO(a.DO.Assign(attrs...))
|
||||
}
|
||||
|
||||
func (a appDynamicConversationOnlineDo) Joins(fields ...field.RelationField) IAppDynamicConversationOnlineDo {
|
||||
for _, _f := range fields {
|
||||
a = *a.withDO(a.DO.Joins(_f))
|
||||
}
|
||||
return &a
|
||||
}
|
||||
|
||||
func (a appDynamicConversationOnlineDo) Preload(fields ...field.RelationField) IAppDynamicConversationOnlineDo {
|
||||
for _, _f := range fields {
|
||||
a = *a.withDO(a.DO.Preload(_f))
|
||||
}
|
||||
return &a
|
||||
}
|
||||
|
||||
func (a appDynamicConversationOnlineDo) FirstOrInit() (*model.AppDynamicConversationOnline, error) {
|
||||
if result, err := a.DO.FirstOrInit(); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return result.(*model.AppDynamicConversationOnline), nil
|
||||
}
|
||||
}
|
||||
|
||||
func (a appDynamicConversationOnlineDo) FirstOrCreate() (*model.AppDynamicConversationOnline, error) {
|
||||
if result, err := a.DO.FirstOrCreate(); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return result.(*model.AppDynamicConversationOnline), nil
|
||||
}
|
||||
}
|
||||
|
||||
func (a appDynamicConversationOnlineDo) FindByPage(offset int, limit int) (result []*model.AppDynamicConversationOnline, count int64, err error) {
|
||||
result, err = a.Offset(offset).Limit(limit).Find()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if size := len(result); 0 < limit && 0 < size && size < limit {
|
||||
count = int64(size + offset)
|
||||
return
|
||||
}
|
||||
|
||||
count, err = a.Offset(-1).Limit(-1).Count()
|
||||
return
|
||||
}
|
||||
|
||||
func (a appDynamicConversationOnlineDo) ScanByPage(result interface{}, offset int, limit int) (count int64, err error) {
|
||||
count, err = a.Count()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
err = a.Offset(offset).Limit(limit).Scan(result)
|
||||
return
|
||||
}
|
||||
|
||||
func (a appDynamicConversationOnlineDo) Scan(result interface{}) (err error) {
|
||||
return a.DO.Scan(result)
|
||||
}
|
||||
|
||||
func (a appDynamicConversationOnlineDo) Delete(models ...*model.AppDynamicConversationOnline) (result gen.ResultInfo, err error) {
|
||||
return a.DO.Delete(models)
|
||||
}
|
||||
|
||||
func (a *appDynamicConversationOnlineDo) withDO(do gen.Dao) *appDynamicConversationOnlineDo {
|
||||
a.DO = *do.(*gen.DO)
|
||||
return a
|
||||
}
|
||||
@@ -0,0 +1,404 @@
|
||||
// Code generated by gorm.io/gen. DO NOT EDIT.
|
||||
// Code generated by gorm.io/gen. DO NOT EDIT.
|
||||
// Code generated by gorm.io/gen. DO NOT EDIT.
|
||||
|
||||
package query
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"gorm.io/gorm"
|
||||
"gorm.io/gorm/clause"
|
||||
"gorm.io/gorm/schema"
|
||||
|
||||
"gorm.io/gen"
|
||||
"gorm.io/gen/field"
|
||||
|
||||
"gorm.io/plugin/dbresolver"
|
||||
|
||||
"github.com/coze-dev/coze-studio/backend/domain/workflow/internal/repo/dal/model"
|
||||
)
|
||||
|
||||
func newAppStaticConversationDraft(db *gorm.DB, opts ...gen.DOOption) appStaticConversationDraft {
|
||||
_appStaticConversationDraft := appStaticConversationDraft{}
|
||||
|
||||
_appStaticConversationDraft.appStaticConversationDraftDo.UseDB(db, opts...)
|
||||
_appStaticConversationDraft.appStaticConversationDraftDo.UseModel(&model.AppStaticConversationDraft{})
|
||||
|
||||
tableName := _appStaticConversationDraft.appStaticConversationDraftDo.TableName()
|
||||
_appStaticConversationDraft.ALL = field.NewAsterisk(tableName)
|
||||
_appStaticConversationDraft.ID = field.NewInt64(tableName, "id")
|
||||
_appStaticConversationDraft.TemplateID = field.NewInt64(tableName, "template_id")
|
||||
_appStaticConversationDraft.UserID = field.NewInt64(tableName, "user_id")
|
||||
_appStaticConversationDraft.ConnectorID = field.NewInt64(tableName, "connector_id")
|
||||
_appStaticConversationDraft.ConversationID = field.NewInt64(tableName, "conversation_id")
|
||||
_appStaticConversationDraft.CreatedAt = field.NewInt64(tableName, "created_at")
|
||||
_appStaticConversationDraft.DeletedAt = field.NewField(tableName, "deleted_at")
|
||||
|
||||
_appStaticConversationDraft.fillFieldMap()
|
||||
|
||||
return _appStaticConversationDraft
|
||||
}
|
||||
|
||||
type appStaticConversationDraft struct {
|
||||
appStaticConversationDraftDo
|
||||
|
||||
ALL field.Asterisk
|
||||
ID field.Int64 // id
|
||||
TemplateID field.Int64 // template id
|
||||
UserID field.Int64 // user id
|
||||
ConnectorID field.Int64 // connector id
|
||||
ConversationID field.Int64 // conversation id
|
||||
CreatedAt field.Int64 // create time in millisecond
|
||||
DeletedAt field.Field // delete time in millisecond
|
||||
|
||||
fieldMap map[string]field.Expr
|
||||
}
|
||||
|
||||
func (a appStaticConversationDraft) Table(newTableName string) *appStaticConversationDraft {
|
||||
a.appStaticConversationDraftDo.UseTable(newTableName)
|
||||
return a.updateTableName(newTableName)
|
||||
}
|
||||
|
||||
func (a appStaticConversationDraft) As(alias string) *appStaticConversationDraft {
|
||||
a.appStaticConversationDraftDo.DO = *(a.appStaticConversationDraftDo.As(alias).(*gen.DO))
|
||||
return a.updateTableName(alias)
|
||||
}
|
||||
|
||||
func (a *appStaticConversationDraft) updateTableName(table string) *appStaticConversationDraft {
|
||||
a.ALL = field.NewAsterisk(table)
|
||||
a.ID = field.NewInt64(table, "id")
|
||||
a.TemplateID = field.NewInt64(table, "template_id")
|
||||
a.UserID = field.NewInt64(table, "user_id")
|
||||
a.ConnectorID = field.NewInt64(table, "connector_id")
|
||||
a.ConversationID = field.NewInt64(table, "conversation_id")
|
||||
a.CreatedAt = field.NewInt64(table, "created_at")
|
||||
a.DeletedAt = field.NewField(table, "deleted_at")
|
||||
|
||||
a.fillFieldMap()
|
||||
|
||||
return a
|
||||
}
|
||||
|
||||
func (a *appStaticConversationDraft) GetFieldByName(fieldName string) (field.OrderExpr, bool) {
|
||||
_f, ok := a.fieldMap[fieldName]
|
||||
if !ok || _f == nil {
|
||||
return nil, false
|
||||
}
|
||||
_oe, ok := _f.(field.OrderExpr)
|
||||
return _oe, ok
|
||||
}
|
||||
|
||||
func (a *appStaticConversationDraft) fillFieldMap() {
|
||||
a.fieldMap = make(map[string]field.Expr, 7)
|
||||
a.fieldMap["id"] = a.ID
|
||||
a.fieldMap["template_id"] = a.TemplateID
|
||||
a.fieldMap["user_id"] = a.UserID
|
||||
a.fieldMap["connector_id"] = a.ConnectorID
|
||||
a.fieldMap["conversation_id"] = a.ConversationID
|
||||
a.fieldMap["created_at"] = a.CreatedAt
|
||||
a.fieldMap["deleted_at"] = a.DeletedAt
|
||||
}
|
||||
|
||||
func (a appStaticConversationDraft) clone(db *gorm.DB) appStaticConversationDraft {
|
||||
a.appStaticConversationDraftDo.ReplaceConnPool(db.Statement.ConnPool)
|
||||
return a
|
||||
}
|
||||
|
||||
func (a appStaticConversationDraft) replaceDB(db *gorm.DB) appStaticConversationDraft {
|
||||
a.appStaticConversationDraftDo.ReplaceDB(db)
|
||||
return a
|
||||
}
|
||||
|
||||
type appStaticConversationDraftDo struct{ gen.DO }
|
||||
|
||||
type IAppStaticConversationDraftDo interface {
|
||||
gen.SubQuery
|
||||
Debug() IAppStaticConversationDraftDo
|
||||
WithContext(ctx context.Context) IAppStaticConversationDraftDo
|
||||
WithResult(fc func(tx gen.Dao)) gen.ResultInfo
|
||||
ReplaceDB(db *gorm.DB)
|
||||
ReadDB() IAppStaticConversationDraftDo
|
||||
WriteDB() IAppStaticConversationDraftDo
|
||||
As(alias string) gen.Dao
|
||||
Session(config *gorm.Session) IAppStaticConversationDraftDo
|
||||
Columns(cols ...field.Expr) gen.Columns
|
||||
Clauses(conds ...clause.Expression) IAppStaticConversationDraftDo
|
||||
Not(conds ...gen.Condition) IAppStaticConversationDraftDo
|
||||
Or(conds ...gen.Condition) IAppStaticConversationDraftDo
|
||||
Select(conds ...field.Expr) IAppStaticConversationDraftDo
|
||||
Where(conds ...gen.Condition) IAppStaticConversationDraftDo
|
||||
Order(conds ...field.Expr) IAppStaticConversationDraftDo
|
||||
Distinct(cols ...field.Expr) IAppStaticConversationDraftDo
|
||||
Omit(cols ...field.Expr) IAppStaticConversationDraftDo
|
||||
Join(table schema.Tabler, on ...field.Expr) IAppStaticConversationDraftDo
|
||||
LeftJoin(table schema.Tabler, on ...field.Expr) IAppStaticConversationDraftDo
|
||||
RightJoin(table schema.Tabler, on ...field.Expr) IAppStaticConversationDraftDo
|
||||
Group(cols ...field.Expr) IAppStaticConversationDraftDo
|
||||
Having(conds ...gen.Condition) IAppStaticConversationDraftDo
|
||||
Limit(limit int) IAppStaticConversationDraftDo
|
||||
Offset(offset int) IAppStaticConversationDraftDo
|
||||
Count() (count int64, err error)
|
||||
Scopes(funcs ...func(gen.Dao) gen.Dao) IAppStaticConversationDraftDo
|
||||
Unscoped() IAppStaticConversationDraftDo
|
||||
Create(values ...*model.AppStaticConversationDraft) error
|
||||
CreateInBatches(values []*model.AppStaticConversationDraft, batchSize int) error
|
||||
Save(values ...*model.AppStaticConversationDraft) error
|
||||
First() (*model.AppStaticConversationDraft, error)
|
||||
Take() (*model.AppStaticConversationDraft, error)
|
||||
Last() (*model.AppStaticConversationDraft, error)
|
||||
Find() ([]*model.AppStaticConversationDraft, error)
|
||||
FindInBatch(batchSize int, fc func(tx gen.Dao, batch int) error) (results []*model.AppStaticConversationDraft, err error)
|
||||
FindInBatches(result *[]*model.AppStaticConversationDraft, batchSize int, fc func(tx gen.Dao, batch int) error) error
|
||||
Pluck(column field.Expr, dest interface{}) error
|
||||
Delete(...*model.AppStaticConversationDraft) (info gen.ResultInfo, err error)
|
||||
Update(column field.Expr, value interface{}) (info gen.ResultInfo, err error)
|
||||
UpdateSimple(columns ...field.AssignExpr) (info gen.ResultInfo, err error)
|
||||
Updates(value interface{}) (info gen.ResultInfo, err error)
|
||||
UpdateColumn(column field.Expr, value interface{}) (info gen.ResultInfo, err error)
|
||||
UpdateColumnSimple(columns ...field.AssignExpr) (info gen.ResultInfo, err error)
|
||||
UpdateColumns(value interface{}) (info gen.ResultInfo, err error)
|
||||
UpdateFrom(q gen.SubQuery) gen.Dao
|
||||
Attrs(attrs ...field.AssignExpr) IAppStaticConversationDraftDo
|
||||
Assign(attrs ...field.AssignExpr) IAppStaticConversationDraftDo
|
||||
Joins(fields ...field.RelationField) IAppStaticConversationDraftDo
|
||||
Preload(fields ...field.RelationField) IAppStaticConversationDraftDo
|
||||
FirstOrInit() (*model.AppStaticConversationDraft, error)
|
||||
FirstOrCreate() (*model.AppStaticConversationDraft, error)
|
||||
FindByPage(offset int, limit int) (result []*model.AppStaticConversationDraft, count int64, err error)
|
||||
ScanByPage(result interface{}, offset int, limit int) (count int64, err error)
|
||||
Scan(result interface{}) (err error)
|
||||
Returning(value interface{}, columns ...string) IAppStaticConversationDraftDo
|
||||
UnderlyingDB() *gorm.DB
|
||||
schema.Tabler
|
||||
}
|
||||
|
||||
func (a appStaticConversationDraftDo) Debug() IAppStaticConversationDraftDo {
|
||||
return a.withDO(a.DO.Debug())
|
||||
}
|
||||
|
||||
func (a appStaticConversationDraftDo) WithContext(ctx context.Context) IAppStaticConversationDraftDo {
|
||||
return a.withDO(a.DO.WithContext(ctx))
|
||||
}
|
||||
|
||||
func (a appStaticConversationDraftDo) ReadDB() IAppStaticConversationDraftDo {
|
||||
return a.Clauses(dbresolver.Read)
|
||||
}
|
||||
|
||||
func (a appStaticConversationDraftDo) WriteDB() IAppStaticConversationDraftDo {
|
||||
return a.Clauses(dbresolver.Write)
|
||||
}
|
||||
|
||||
func (a appStaticConversationDraftDo) Session(config *gorm.Session) IAppStaticConversationDraftDo {
|
||||
return a.withDO(a.DO.Session(config))
|
||||
}
|
||||
|
||||
func (a appStaticConversationDraftDo) Clauses(conds ...clause.Expression) IAppStaticConversationDraftDo {
|
||||
return a.withDO(a.DO.Clauses(conds...))
|
||||
}
|
||||
|
||||
func (a appStaticConversationDraftDo) Returning(value interface{}, columns ...string) IAppStaticConversationDraftDo {
|
||||
return a.withDO(a.DO.Returning(value, columns...))
|
||||
}
|
||||
|
||||
func (a appStaticConversationDraftDo) Not(conds ...gen.Condition) IAppStaticConversationDraftDo {
|
||||
return a.withDO(a.DO.Not(conds...))
|
||||
}
|
||||
|
||||
func (a appStaticConversationDraftDo) Or(conds ...gen.Condition) IAppStaticConversationDraftDo {
|
||||
return a.withDO(a.DO.Or(conds...))
|
||||
}
|
||||
|
||||
func (a appStaticConversationDraftDo) Select(conds ...field.Expr) IAppStaticConversationDraftDo {
|
||||
return a.withDO(a.DO.Select(conds...))
|
||||
}
|
||||
|
||||
func (a appStaticConversationDraftDo) Where(conds ...gen.Condition) IAppStaticConversationDraftDo {
|
||||
return a.withDO(a.DO.Where(conds...))
|
||||
}
|
||||
|
||||
func (a appStaticConversationDraftDo) Order(conds ...field.Expr) IAppStaticConversationDraftDo {
|
||||
return a.withDO(a.DO.Order(conds...))
|
||||
}
|
||||
|
||||
func (a appStaticConversationDraftDo) Distinct(cols ...field.Expr) IAppStaticConversationDraftDo {
|
||||
return a.withDO(a.DO.Distinct(cols...))
|
||||
}
|
||||
|
||||
func (a appStaticConversationDraftDo) Omit(cols ...field.Expr) IAppStaticConversationDraftDo {
|
||||
return a.withDO(a.DO.Omit(cols...))
|
||||
}
|
||||
|
||||
func (a appStaticConversationDraftDo) Join(table schema.Tabler, on ...field.Expr) IAppStaticConversationDraftDo {
|
||||
return a.withDO(a.DO.Join(table, on...))
|
||||
}
|
||||
|
||||
func (a appStaticConversationDraftDo) LeftJoin(table schema.Tabler, on ...field.Expr) IAppStaticConversationDraftDo {
|
||||
return a.withDO(a.DO.LeftJoin(table, on...))
|
||||
}
|
||||
|
||||
func (a appStaticConversationDraftDo) RightJoin(table schema.Tabler, on ...field.Expr) IAppStaticConversationDraftDo {
|
||||
return a.withDO(a.DO.RightJoin(table, on...))
|
||||
}
|
||||
|
||||
func (a appStaticConversationDraftDo) Group(cols ...field.Expr) IAppStaticConversationDraftDo {
|
||||
return a.withDO(a.DO.Group(cols...))
|
||||
}
|
||||
|
||||
func (a appStaticConversationDraftDo) Having(conds ...gen.Condition) IAppStaticConversationDraftDo {
|
||||
return a.withDO(a.DO.Having(conds...))
|
||||
}
|
||||
|
||||
func (a appStaticConversationDraftDo) Limit(limit int) IAppStaticConversationDraftDo {
|
||||
return a.withDO(a.DO.Limit(limit))
|
||||
}
|
||||
|
||||
func (a appStaticConversationDraftDo) Offset(offset int) IAppStaticConversationDraftDo {
|
||||
return a.withDO(a.DO.Offset(offset))
|
||||
}
|
||||
|
||||
func (a appStaticConversationDraftDo) Scopes(funcs ...func(gen.Dao) gen.Dao) IAppStaticConversationDraftDo {
|
||||
return a.withDO(a.DO.Scopes(funcs...))
|
||||
}
|
||||
|
||||
func (a appStaticConversationDraftDo) Unscoped() IAppStaticConversationDraftDo {
|
||||
return a.withDO(a.DO.Unscoped())
|
||||
}
|
||||
|
||||
func (a appStaticConversationDraftDo) Create(values ...*model.AppStaticConversationDraft) error {
|
||||
if len(values) == 0 {
|
||||
return nil
|
||||
}
|
||||
return a.DO.Create(values)
|
||||
}
|
||||
|
||||
func (a appStaticConversationDraftDo) CreateInBatches(values []*model.AppStaticConversationDraft, batchSize int) error {
|
||||
return a.DO.CreateInBatches(values, batchSize)
|
||||
}
|
||||
|
||||
// Save : !!! underlying implementation is different with GORM
|
||||
// The method is equivalent to executing the statement: db.Clauses(clause.OnConflict{UpdateAll: true}).Create(values)
|
||||
func (a appStaticConversationDraftDo) Save(values ...*model.AppStaticConversationDraft) error {
|
||||
if len(values) == 0 {
|
||||
return nil
|
||||
}
|
||||
return a.DO.Save(values)
|
||||
}
|
||||
|
||||
func (a appStaticConversationDraftDo) First() (*model.AppStaticConversationDraft, error) {
|
||||
if result, err := a.DO.First(); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return result.(*model.AppStaticConversationDraft), nil
|
||||
}
|
||||
}
|
||||
|
||||
func (a appStaticConversationDraftDo) Take() (*model.AppStaticConversationDraft, error) {
|
||||
if result, err := a.DO.Take(); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return result.(*model.AppStaticConversationDraft), nil
|
||||
}
|
||||
}
|
||||
|
||||
func (a appStaticConversationDraftDo) Last() (*model.AppStaticConversationDraft, error) {
|
||||
if result, err := a.DO.Last(); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return result.(*model.AppStaticConversationDraft), nil
|
||||
}
|
||||
}
|
||||
|
||||
func (a appStaticConversationDraftDo) Find() ([]*model.AppStaticConversationDraft, error) {
|
||||
result, err := a.DO.Find()
|
||||
return result.([]*model.AppStaticConversationDraft), err
|
||||
}
|
||||
|
||||
func (a appStaticConversationDraftDo) FindInBatch(batchSize int, fc func(tx gen.Dao, batch int) error) (results []*model.AppStaticConversationDraft, err error) {
|
||||
buf := make([]*model.AppStaticConversationDraft, 0, batchSize)
|
||||
err = a.DO.FindInBatches(&buf, batchSize, func(tx gen.Dao, batch int) error {
|
||||
defer func() { results = append(results, buf...) }()
|
||||
return fc(tx, batch)
|
||||
})
|
||||
return results, err
|
||||
}
|
||||
|
||||
func (a appStaticConversationDraftDo) FindInBatches(result *[]*model.AppStaticConversationDraft, batchSize int, fc func(tx gen.Dao, batch int) error) error {
|
||||
return a.DO.FindInBatches(result, batchSize, fc)
|
||||
}
|
||||
|
||||
func (a appStaticConversationDraftDo) Attrs(attrs ...field.AssignExpr) IAppStaticConversationDraftDo {
|
||||
return a.withDO(a.DO.Attrs(attrs...))
|
||||
}
|
||||
|
||||
func (a appStaticConversationDraftDo) Assign(attrs ...field.AssignExpr) IAppStaticConversationDraftDo {
|
||||
return a.withDO(a.DO.Assign(attrs...))
|
||||
}
|
||||
|
||||
func (a appStaticConversationDraftDo) Joins(fields ...field.RelationField) IAppStaticConversationDraftDo {
|
||||
for _, _f := range fields {
|
||||
a = *a.withDO(a.DO.Joins(_f))
|
||||
}
|
||||
return &a
|
||||
}
|
||||
|
||||
func (a appStaticConversationDraftDo) Preload(fields ...field.RelationField) IAppStaticConversationDraftDo {
|
||||
for _, _f := range fields {
|
||||
a = *a.withDO(a.DO.Preload(_f))
|
||||
}
|
||||
return &a
|
||||
}
|
||||
|
||||
func (a appStaticConversationDraftDo) FirstOrInit() (*model.AppStaticConversationDraft, error) {
|
||||
if result, err := a.DO.FirstOrInit(); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return result.(*model.AppStaticConversationDraft), nil
|
||||
}
|
||||
}
|
||||
|
||||
func (a appStaticConversationDraftDo) FirstOrCreate() (*model.AppStaticConversationDraft, error) {
|
||||
if result, err := a.DO.FirstOrCreate(); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return result.(*model.AppStaticConversationDraft), nil
|
||||
}
|
||||
}
|
||||
|
||||
func (a appStaticConversationDraftDo) FindByPage(offset int, limit int) (result []*model.AppStaticConversationDraft, count int64, err error) {
|
||||
result, err = a.Offset(offset).Limit(limit).Find()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if size := len(result); 0 < limit && 0 < size && size < limit {
|
||||
count = int64(size + offset)
|
||||
return
|
||||
}
|
||||
|
||||
count, err = a.Offset(-1).Limit(-1).Count()
|
||||
return
|
||||
}
|
||||
|
||||
func (a appStaticConversationDraftDo) ScanByPage(result interface{}, offset int, limit int) (count int64, err error) {
|
||||
count, err = a.Count()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
err = a.Offset(offset).Limit(limit).Scan(result)
|
||||
return
|
||||
}
|
||||
|
||||
func (a appStaticConversationDraftDo) Scan(result interface{}) (err error) {
|
||||
return a.DO.Scan(result)
|
||||
}
|
||||
|
||||
func (a appStaticConversationDraftDo) Delete(models ...*model.AppStaticConversationDraft) (result gen.ResultInfo, err error) {
|
||||
return a.DO.Delete(models)
|
||||
}
|
||||
|
||||
func (a *appStaticConversationDraftDo) withDO(do gen.Dao) *appStaticConversationDraftDo {
|
||||
a.DO = *do.(*gen.DO)
|
||||
return a
|
||||
}
|
||||
@@ -0,0 +1,400 @@
|
||||
// Code generated by gorm.io/gen. DO NOT EDIT.
|
||||
// Code generated by gorm.io/gen. DO NOT EDIT.
|
||||
// Code generated by gorm.io/gen. DO NOT EDIT.
|
||||
|
||||
package query
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"gorm.io/gorm"
|
||||
"gorm.io/gorm/clause"
|
||||
"gorm.io/gorm/schema"
|
||||
|
||||
"gorm.io/gen"
|
||||
"gorm.io/gen/field"
|
||||
|
||||
"gorm.io/plugin/dbresolver"
|
||||
|
||||
"github.com/coze-dev/coze-studio/backend/domain/workflow/internal/repo/dal/model"
|
||||
)
|
||||
|
||||
func newAppStaticConversationOnline(db *gorm.DB, opts ...gen.DOOption) appStaticConversationOnline {
|
||||
_appStaticConversationOnline := appStaticConversationOnline{}
|
||||
|
||||
_appStaticConversationOnline.appStaticConversationOnlineDo.UseDB(db, opts...)
|
||||
_appStaticConversationOnline.appStaticConversationOnlineDo.UseModel(&model.AppStaticConversationOnline{})
|
||||
|
||||
tableName := _appStaticConversationOnline.appStaticConversationOnlineDo.TableName()
|
||||
_appStaticConversationOnline.ALL = field.NewAsterisk(tableName)
|
||||
_appStaticConversationOnline.ID = field.NewInt64(tableName, "id")
|
||||
_appStaticConversationOnline.TemplateID = field.NewInt64(tableName, "template_id")
|
||||
_appStaticConversationOnline.UserID = field.NewInt64(tableName, "user_id")
|
||||
_appStaticConversationOnline.ConnectorID = field.NewInt64(tableName, "connector_id")
|
||||
_appStaticConversationOnline.ConversationID = field.NewInt64(tableName, "conversation_id")
|
||||
_appStaticConversationOnline.CreatedAt = field.NewInt64(tableName, "created_at")
|
||||
|
||||
_appStaticConversationOnline.fillFieldMap()
|
||||
|
||||
return _appStaticConversationOnline
|
||||
}
|
||||
|
||||
type appStaticConversationOnline struct {
|
||||
appStaticConversationOnlineDo
|
||||
|
||||
ALL field.Asterisk
|
||||
ID field.Int64 // id
|
||||
TemplateID field.Int64 // template id
|
||||
UserID field.Int64 // user id
|
||||
ConnectorID field.Int64 // connector id
|
||||
ConversationID field.Int64 // conversation id
|
||||
CreatedAt field.Int64 // create time in millisecond
|
||||
|
||||
fieldMap map[string]field.Expr
|
||||
}
|
||||
|
||||
func (a appStaticConversationOnline) Table(newTableName string) *appStaticConversationOnline {
|
||||
a.appStaticConversationOnlineDo.UseTable(newTableName)
|
||||
return a.updateTableName(newTableName)
|
||||
}
|
||||
|
||||
func (a appStaticConversationOnline) As(alias string) *appStaticConversationOnline {
|
||||
a.appStaticConversationOnlineDo.DO = *(a.appStaticConversationOnlineDo.As(alias).(*gen.DO))
|
||||
return a.updateTableName(alias)
|
||||
}
|
||||
|
||||
func (a *appStaticConversationOnline) updateTableName(table string) *appStaticConversationOnline {
|
||||
a.ALL = field.NewAsterisk(table)
|
||||
a.ID = field.NewInt64(table, "id")
|
||||
a.TemplateID = field.NewInt64(table, "template_id")
|
||||
a.UserID = field.NewInt64(table, "user_id")
|
||||
a.ConnectorID = field.NewInt64(table, "connector_id")
|
||||
a.ConversationID = field.NewInt64(table, "conversation_id")
|
||||
a.CreatedAt = field.NewInt64(table, "created_at")
|
||||
|
||||
a.fillFieldMap()
|
||||
|
||||
return a
|
||||
}
|
||||
|
||||
func (a *appStaticConversationOnline) GetFieldByName(fieldName string) (field.OrderExpr, bool) {
|
||||
_f, ok := a.fieldMap[fieldName]
|
||||
if !ok || _f == nil {
|
||||
return nil, false
|
||||
}
|
||||
_oe, ok := _f.(field.OrderExpr)
|
||||
return _oe, ok
|
||||
}
|
||||
|
||||
func (a *appStaticConversationOnline) fillFieldMap() {
|
||||
a.fieldMap = make(map[string]field.Expr, 6)
|
||||
a.fieldMap["id"] = a.ID
|
||||
a.fieldMap["template_id"] = a.TemplateID
|
||||
a.fieldMap["user_id"] = a.UserID
|
||||
a.fieldMap["connector_id"] = a.ConnectorID
|
||||
a.fieldMap["conversation_id"] = a.ConversationID
|
||||
a.fieldMap["created_at"] = a.CreatedAt
|
||||
}
|
||||
|
||||
func (a appStaticConversationOnline) clone(db *gorm.DB) appStaticConversationOnline {
|
||||
a.appStaticConversationOnlineDo.ReplaceConnPool(db.Statement.ConnPool)
|
||||
return a
|
||||
}
|
||||
|
||||
func (a appStaticConversationOnline) replaceDB(db *gorm.DB) appStaticConversationOnline {
|
||||
a.appStaticConversationOnlineDo.ReplaceDB(db)
|
||||
return a
|
||||
}
|
||||
|
||||
type appStaticConversationOnlineDo struct{ gen.DO }
|
||||
|
||||
type IAppStaticConversationOnlineDo interface {
|
||||
gen.SubQuery
|
||||
Debug() IAppStaticConversationOnlineDo
|
||||
WithContext(ctx context.Context) IAppStaticConversationOnlineDo
|
||||
WithResult(fc func(tx gen.Dao)) gen.ResultInfo
|
||||
ReplaceDB(db *gorm.DB)
|
||||
ReadDB() IAppStaticConversationOnlineDo
|
||||
WriteDB() IAppStaticConversationOnlineDo
|
||||
As(alias string) gen.Dao
|
||||
Session(config *gorm.Session) IAppStaticConversationOnlineDo
|
||||
Columns(cols ...field.Expr) gen.Columns
|
||||
Clauses(conds ...clause.Expression) IAppStaticConversationOnlineDo
|
||||
Not(conds ...gen.Condition) IAppStaticConversationOnlineDo
|
||||
Or(conds ...gen.Condition) IAppStaticConversationOnlineDo
|
||||
Select(conds ...field.Expr) IAppStaticConversationOnlineDo
|
||||
Where(conds ...gen.Condition) IAppStaticConversationOnlineDo
|
||||
Order(conds ...field.Expr) IAppStaticConversationOnlineDo
|
||||
Distinct(cols ...field.Expr) IAppStaticConversationOnlineDo
|
||||
Omit(cols ...field.Expr) IAppStaticConversationOnlineDo
|
||||
Join(table schema.Tabler, on ...field.Expr) IAppStaticConversationOnlineDo
|
||||
LeftJoin(table schema.Tabler, on ...field.Expr) IAppStaticConversationOnlineDo
|
||||
RightJoin(table schema.Tabler, on ...field.Expr) IAppStaticConversationOnlineDo
|
||||
Group(cols ...field.Expr) IAppStaticConversationOnlineDo
|
||||
Having(conds ...gen.Condition) IAppStaticConversationOnlineDo
|
||||
Limit(limit int) IAppStaticConversationOnlineDo
|
||||
Offset(offset int) IAppStaticConversationOnlineDo
|
||||
Count() (count int64, err error)
|
||||
Scopes(funcs ...func(gen.Dao) gen.Dao) IAppStaticConversationOnlineDo
|
||||
Unscoped() IAppStaticConversationOnlineDo
|
||||
Create(values ...*model.AppStaticConversationOnline) error
|
||||
CreateInBatches(values []*model.AppStaticConversationOnline, batchSize int) error
|
||||
Save(values ...*model.AppStaticConversationOnline) error
|
||||
First() (*model.AppStaticConversationOnline, error)
|
||||
Take() (*model.AppStaticConversationOnline, error)
|
||||
Last() (*model.AppStaticConversationOnline, error)
|
||||
Find() ([]*model.AppStaticConversationOnline, error)
|
||||
FindInBatch(batchSize int, fc func(tx gen.Dao, batch int) error) (results []*model.AppStaticConversationOnline, err error)
|
||||
FindInBatches(result *[]*model.AppStaticConversationOnline, batchSize int, fc func(tx gen.Dao, batch int) error) error
|
||||
Pluck(column field.Expr, dest interface{}) error
|
||||
Delete(...*model.AppStaticConversationOnline) (info gen.ResultInfo, err error)
|
||||
Update(column field.Expr, value interface{}) (info gen.ResultInfo, err error)
|
||||
UpdateSimple(columns ...field.AssignExpr) (info gen.ResultInfo, err error)
|
||||
Updates(value interface{}) (info gen.ResultInfo, err error)
|
||||
UpdateColumn(column field.Expr, value interface{}) (info gen.ResultInfo, err error)
|
||||
UpdateColumnSimple(columns ...field.AssignExpr) (info gen.ResultInfo, err error)
|
||||
UpdateColumns(value interface{}) (info gen.ResultInfo, err error)
|
||||
UpdateFrom(q gen.SubQuery) gen.Dao
|
||||
Attrs(attrs ...field.AssignExpr) IAppStaticConversationOnlineDo
|
||||
Assign(attrs ...field.AssignExpr) IAppStaticConversationOnlineDo
|
||||
Joins(fields ...field.RelationField) IAppStaticConversationOnlineDo
|
||||
Preload(fields ...field.RelationField) IAppStaticConversationOnlineDo
|
||||
FirstOrInit() (*model.AppStaticConversationOnline, error)
|
||||
FirstOrCreate() (*model.AppStaticConversationOnline, error)
|
||||
FindByPage(offset int, limit int) (result []*model.AppStaticConversationOnline, count int64, err error)
|
||||
ScanByPage(result interface{}, offset int, limit int) (count int64, err error)
|
||||
Scan(result interface{}) (err error)
|
||||
Returning(value interface{}, columns ...string) IAppStaticConversationOnlineDo
|
||||
UnderlyingDB() *gorm.DB
|
||||
schema.Tabler
|
||||
}
|
||||
|
||||
func (a appStaticConversationOnlineDo) Debug() IAppStaticConversationOnlineDo {
|
||||
return a.withDO(a.DO.Debug())
|
||||
}
|
||||
|
||||
func (a appStaticConversationOnlineDo) WithContext(ctx context.Context) IAppStaticConversationOnlineDo {
|
||||
return a.withDO(a.DO.WithContext(ctx))
|
||||
}
|
||||
|
||||
func (a appStaticConversationOnlineDo) ReadDB() IAppStaticConversationOnlineDo {
|
||||
return a.Clauses(dbresolver.Read)
|
||||
}
|
||||
|
||||
func (a appStaticConversationOnlineDo) WriteDB() IAppStaticConversationOnlineDo {
|
||||
return a.Clauses(dbresolver.Write)
|
||||
}
|
||||
|
||||
func (a appStaticConversationOnlineDo) Session(config *gorm.Session) IAppStaticConversationOnlineDo {
|
||||
return a.withDO(a.DO.Session(config))
|
||||
}
|
||||
|
||||
func (a appStaticConversationOnlineDo) Clauses(conds ...clause.Expression) IAppStaticConversationOnlineDo {
|
||||
return a.withDO(a.DO.Clauses(conds...))
|
||||
}
|
||||
|
||||
func (a appStaticConversationOnlineDo) Returning(value interface{}, columns ...string) IAppStaticConversationOnlineDo {
|
||||
return a.withDO(a.DO.Returning(value, columns...))
|
||||
}
|
||||
|
||||
func (a appStaticConversationOnlineDo) Not(conds ...gen.Condition) IAppStaticConversationOnlineDo {
|
||||
return a.withDO(a.DO.Not(conds...))
|
||||
}
|
||||
|
||||
func (a appStaticConversationOnlineDo) Or(conds ...gen.Condition) IAppStaticConversationOnlineDo {
|
||||
return a.withDO(a.DO.Or(conds...))
|
||||
}
|
||||
|
||||
func (a appStaticConversationOnlineDo) Select(conds ...field.Expr) IAppStaticConversationOnlineDo {
|
||||
return a.withDO(a.DO.Select(conds...))
|
||||
}
|
||||
|
||||
func (a appStaticConversationOnlineDo) Where(conds ...gen.Condition) IAppStaticConversationOnlineDo {
|
||||
return a.withDO(a.DO.Where(conds...))
|
||||
}
|
||||
|
||||
func (a appStaticConversationOnlineDo) Order(conds ...field.Expr) IAppStaticConversationOnlineDo {
|
||||
return a.withDO(a.DO.Order(conds...))
|
||||
}
|
||||
|
||||
func (a appStaticConversationOnlineDo) Distinct(cols ...field.Expr) IAppStaticConversationOnlineDo {
|
||||
return a.withDO(a.DO.Distinct(cols...))
|
||||
}
|
||||
|
||||
func (a appStaticConversationOnlineDo) Omit(cols ...field.Expr) IAppStaticConversationOnlineDo {
|
||||
return a.withDO(a.DO.Omit(cols...))
|
||||
}
|
||||
|
||||
func (a appStaticConversationOnlineDo) Join(table schema.Tabler, on ...field.Expr) IAppStaticConversationOnlineDo {
|
||||
return a.withDO(a.DO.Join(table, on...))
|
||||
}
|
||||
|
||||
func (a appStaticConversationOnlineDo) LeftJoin(table schema.Tabler, on ...field.Expr) IAppStaticConversationOnlineDo {
|
||||
return a.withDO(a.DO.LeftJoin(table, on...))
|
||||
}
|
||||
|
||||
func (a appStaticConversationOnlineDo) RightJoin(table schema.Tabler, on ...field.Expr) IAppStaticConversationOnlineDo {
|
||||
return a.withDO(a.DO.RightJoin(table, on...))
|
||||
}
|
||||
|
||||
func (a appStaticConversationOnlineDo) Group(cols ...field.Expr) IAppStaticConversationOnlineDo {
|
||||
return a.withDO(a.DO.Group(cols...))
|
||||
}
|
||||
|
||||
func (a appStaticConversationOnlineDo) Having(conds ...gen.Condition) IAppStaticConversationOnlineDo {
|
||||
return a.withDO(a.DO.Having(conds...))
|
||||
}
|
||||
|
||||
func (a appStaticConversationOnlineDo) Limit(limit int) IAppStaticConversationOnlineDo {
|
||||
return a.withDO(a.DO.Limit(limit))
|
||||
}
|
||||
|
||||
func (a appStaticConversationOnlineDo) Offset(offset int) IAppStaticConversationOnlineDo {
|
||||
return a.withDO(a.DO.Offset(offset))
|
||||
}
|
||||
|
||||
func (a appStaticConversationOnlineDo) Scopes(funcs ...func(gen.Dao) gen.Dao) IAppStaticConversationOnlineDo {
|
||||
return a.withDO(a.DO.Scopes(funcs...))
|
||||
}
|
||||
|
||||
func (a appStaticConversationOnlineDo) Unscoped() IAppStaticConversationOnlineDo {
|
||||
return a.withDO(a.DO.Unscoped())
|
||||
}
|
||||
|
||||
func (a appStaticConversationOnlineDo) Create(values ...*model.AppStaticConversationOnline) error {
|
||||
if len(values) == 0 {
|
||||
return nil
|
||||
}
|
||||
return a.DO.Create(values)
|
||||
}
|
||||
|
||||
func (a appStaticConversationOnlineDo) CreateInBatches(values []*model.AppStaticConversationOnline, batchSize int) error {
|
||||
return a.DO.CreateInBatches(values, batchSize)
|
||||
}
|
||||
|
||||
// Save : !!! underlying implementation is different with GORM
|
||||
// The method is equivalent to executing the statement: db.Clauses(clause.OnConflict{UpdateAll: true}).Create(values)
|
||||
func (a appStaticConversationOnlineDo) Save(values ...*model.AppStaticConversationOnline) error {
|
||||
if len(values) == 0 {
|
||||
return nil
|
||||
}
|
||||
return a.DO.Save(values)
|
||||
}
|
||||
|
||||
func (a appStaticConversationOnlineDo) First() (*model.AppStaticConversationOnline, error) {
|
||||
if result, err := a.DO.First(); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return result.(*model.AppStaticConversationOnline), nil
|
||||
}
|
||||
}
|
||||
|
||||
func (a appStaticConversationOnlineDo) Take() (*model.AppStaticConversationOnline, error) {
|
||||
if result, err := a.DO.Take(); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return result.(*model.AppStaticConversationOnline), nil
|
||||
}
|
||||
}
|
||||
|
||||
func (a appStaticConversationOnlineDo) Last() (*model.AppStaticConversationOnline, error) {
|
||||
if result, err := a.DO.Last(); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return result.(*model.AppStaticConversationOnline), nil
|
||||
}
|
||||
}
|
||||
|
||||
func (a appStaticConversationOnlineDo) Find() ([]*model.AppStaticConversationOnline, error) {
|
||||
result, err := a.DO.Find()
|
||||
return result.([]*model.AppStaticConversationOnline), err
|
||||
}
|
||||
|
||||
func (a appStaticConversationOnlineDo) FindInBatch(batchSize int, fc func(tx gen.Dao, batch int) error) (results []*model.AppStaticConversationOnline, err error) {
|
||||
buf := make([]*model.AppStaticConversationOnline, 0, batchSize)
|
||||
err = a.DO.FindInBatches(&buf, batchSize, func(tx gen.Dao, batch int) error {
|
||||
defer func() { results = append(results, buf...) }()
|
||||
return fc(tx, batch)
|
||||
})
|
||||
return results, err
|
||||
}
|
||||
|
||||
func (a appStaticConversationOnlineDo) FindInBatches(result *[]*model.AppStaticConversationOnline, batchSize int, fc func(tx gen.Dao, batch int) error) error {
|
||||
return a.DO.FindInBatches(result, batchSize, fc)
|
||||
}
|
||||
|
||||
func (a appStaticConversationOnlineDo) Attrs(attrs ...field.AssignExpr) IAppStaticConversationOnlineDo {
|
||||
return a.withDO(a.DO.Attrs(attrs...))
|
||||
}
|
||||
|
||||
func (a appStaticConversationOnlineDo) Assign(attrs ...field.AssignExpr) IAppStaticConversationOnlineDo {
|
||||
return a.withDO(a.DO.Assign(attrs...))
|
||||
}
|
||||
|
||||
func (a appStaticConversationOnlineDo) Joins(fields ...field.RelationField) IAppStaticConversationOnlineDo {
|
||||
for _, _f := range fields {
|
||||
a = *a.withDO(a.DO.Joins(_f))
|
||||
}
|
||||
return &a
|
||||
}
|
||||
|
||||
func (a appStaticConversationOnlineDo) Preload(fields ...field.RelationField) IAppStaticConversationOnlineDo {
|
||||
for _, _f := range fields {
|
||||
a = *a.withDO(a.DO.Preload(_f))
|
||||
}
|
||||
return &a
|
||||
}
|
||||
|
||||
func (a appStaticConversationOnlineDo) FirstOrInit() (*model.AppStaticConversationOnline, error) {
|
||||
if result, err := a.DO.FirstOrInit(); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return result.(*model.AppStaticConversationOnline), nil
|
||||
}
|
||||
}
|
||||
|
||||
func (a appStaticConversationOnlineDo) FirstOrCreate() (*model.AppStaticConversationOnline, error) {
|
||||
if result, err := a.DO.FirstOrCreate(); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return result.(*model.AppStaticConversationOnline), nil
|
||||
}
|
||||
}
|
||||
|
||||
func (a appStaticConversationOnlineDo) FindByPage(offset int, limit int) (result []*model.AppStaticConversationOnline, count int64, err error) {
|
||||
result, err = a.Offset(offset).Limit(limit).Find()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if size := len(result); 0 < limit && 0 < size && size < limit {
|
||||
count = int64(size + offset)
|
||||
return
|
||||
}
|
||||
|
||||
count, err = a.Offset(-1).Limit(-1).Count()
|
||||
return
|
||||
}
|
||||
|
||||
func (a appStaticConversationOnlineDo) ScanByPage(result interface{}, offset int, limit int) (count int64, err error) {
|
||||
count, err = a.Count()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
err = a.Offset(offset).Limit(limit).Scan(result)
|
||||
return
|
||||
}
|
||||
|
||||
func (a appStaticConversationOnlineDo) Scan(result interface{}) (err error) {
|
||||
return a.DO.Scan(result)
|
||||
}
|
||||
|
||||
func (a appStaticConversationOnlineDo) Delete(models ...*model.AppStaticConversationOnline) (result gen.ResultInfo, err error) {
|
||||
return a.DO.Delete(models)
|
||||
}
|
||||
|
||||
func (a *appStaticConversationOnlineDo) withDO(do gen.Dao) *appStaticConversationOnlineDo {
|
||||
a.DO = *do.(*gen.DO)
|
||||
return a
|
||||
}
|
||||
@@ -0,0 +1,440 @@
|
||||
// Code generated by gorm.io/gen. DO NOT EDIT.
|
||||
// Code generated by gorm.io/gen. DO NOT EDIT.
|
||||
// Code generated by gorm.io/gen. DO NOT EDIT.
|
||||
|
||||
package query
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"gorm.io/gorm"
|
||||
"gorm.io/gorm/clause"
|
||||
"gorm.io/gorm/schema"
|
||||
|
||||
"gorm.io/gen"
|
||||
"gorm.io/gen/field"
|
||||
|
||||
"gorm.io/plugin/dbresolver"
|
||||
|
||||
"github.com/coze-dev/coze-studio/backend/domain/workflow/internal/repo/dal/model"
|
||||
)
|
||||
|
||||
func newChatFlowRoleConfig(db *gorm.DB, opts ...gen.DOOption) chatFlowRoleConfig {
|
||||
_chatFlowRoleConfig := chatFlowRoleConfig{}
|
||||
|
||||
_chatFlowRoleConfig.chatFlowRoleConfigDo.UseDB(db, opts...)
|
||||
_chatFlowRoleConfig.chatFlowRoleConfigDo.UseModel(&model.ChatFlowRoleConfig{})
|
||||
|
||||
tableName := _chatFlowRoleConfig.chatFlowRoleConfigDo.TableName()
|
||||
_chatFlowRoleConfig.ALL = field.NewAsterisk(tableName)
|
||||
_chatFlowRoleConfig.ID = field.NewInt64(tableName, "id")
|
||||
_chatFlowRoleConfig.WorkflowID = field.NewInt64(tableName, "workflow_id")
|
||||
_chatFlowRoleConfig.Name = field.NewString(tableName, "name")
|
||||
_chatFlowRoleConfig.Description = field.NewString(tableName, "description")
|
||||
_chatFlowRoleConfig.Version = field.NewString(tableName, "version")
|
||||
_chatFlowRoleConfig.Avatar = field.NewString(tableName, "avatar")
|
||||
_chatFlowRoleConfig.BackgroundImageInfo = field.NewString(tableName, "background_image_info")
|
||||
_chatFlowRoleConfig.OnboardingInfo = field.NewString(tableName, "onboarding_info")
|
||||
_chatFlowRoleConfig.SuggestReplyInfo = field.NewString(tableName, "suggest_reply_info")
|
||||
_chatFlowRoleConfig.AudioConfig = field.NewString(tableName, "audio_config")
|
||||
_chatFlowRoleConfig.UserInputConfig = field.NewString(tableName, "user_input_config")
|
||||
_chatFlowRoleConfig.CreatorID = field.NewInt64(tableName, "creator_id")
|
||||
_chatFlowRoleConfig.CreatedAt = field.NewInt64(tableName, "created_at")
|
||||
_chatFlowRoleConfig.UpdatedAt = field.NewInt64(tableName, "updated_at")
|
||||
_chatFlowRoleConfig.DeletedAt = field.NewField(tableName, "deleted_at")
|
||||
_chatFlowRoleConfig.ConnectorID = field.NewInt64(tableName, "connector_id")
|
||||
|
||||
_chatFlowRoleConfig.fillFieldMap()
|
||||
|
||||
return _chatFlowRoleConfig
|
||||
}
|
||||
|
||||
type chatFlowRoleConfig struct {
|
||||
chatFlowRoleConfigDo
|
||||
|
||||
ALL field.Asterisk
|
||||
ID field.Int64 // id
|
||||
WorkflowID field.Int64 // workflow id
|
||||
Name field.String // role name
|
||||
Description field.String // role description
|
||||
Version field.String // version
|
||||
Avatar field.String // avatar uri
|
||||
BackgroundImageInfo field.String // background image information, object structure
|
||||
OnboardingInfo field.String // intro information, object structure
|
||||
SuggestReplyInfo field.String // user suggestions, object structure
|
||||
AudioConfig field.String // agent audio config, object structure
|
||||
UserInputConfig field.String // user input config, object structure
|
||||
CreatorID field.Int64 // creator id
|
||||
CreatedAt field.Int64 // create time in millisecond
|
||||
UpdatedAt field.Int64 // update time in millisecond
|
||||
DeletedAt field.Field // delete time in millisecond
|
||||
ConnectorID field.Int64 // connector id
|
||||
|
||||
fieldMap map[string]field.Expr
|
||||
}
|
||||
|
||||
func (c chatFlowRoleConfig) Table(newTableName string) *chatFlowRoleConfig {
|
||||
c.chatFlowRoleConfigDo.UseTable(newTableName)
|
||||
return c.updateTableName(newTableName)
|
||||
}
|
||||
|
||||
func (c chatFlowRoleConfig) As(alias string) *chatFlowRoleConfig {
|
||||
c.chatFlowRoleConfigDo.DO = *(c.chatFlowRoleConfigDo.As(alias).(*gen.DO))
|
||||
return c.updateTableName(alias)
|
||||
}
|
||||
|
||||
func (c *chatFlowRoleConfig) updateTableName(table string) *chatFlowRoleConfig {
|
||||
c.ALL = field.NewAsterisk(table)
|
||||
c.ID = field.NewInt64(table, "id")
|
||||
c.WorkflowID = field.NewInt64(table, "workflow_id")
|
||||
c.Name = field.NewString(table, "name")
|
||||
c.Description = field.NewString(table, "description")
|
||||
c.Version = field.NewString(table, "version")
|
||||
c.Avatar = field.NewString(table, "avatar")
|
||||
c.BackgroundImageInfo = field.NewString(table, "background_image_info")
|
||||
c.OnboardingInfo = field.NewString(table, "onboarding_info")
|
||||
c.SuggestReplyInfo = field.NewString(table, "suggest_reply_info")
|
||||
c.AudioConfig = field.NewString(table, "audio_config")
|
||||
c.UserInputConfig = field.NewString(table, "user_input_config")
|
||||
c.CreatorID = field.NewInt64(table, "creator_id")
|
||||
c.CreatedAt = field.NewInt64(table, "created_at")
|
||||
c.UpdatedAt = field.NewInt64(table, "updated_at")
|
||||
c.DeletedAt = field.NewField(table, "deleted_at")
|
||||
c.ConnectorID = field.NewInt64(table, "connector_id")
|
||||
|
||||
c.fillFieldMap()
|
||||
|
||||
return c
|
||||
}
|
||||
|
||||
func (c *chatFlowRoleConfig) GetFieldByName(fieldName string) (field.OrderExpr, bool) {
|
||||
_f, ok := c.fieldMap[fieldName]
|
||||
if !ok || _f == nil {
|
||||
return nil, false
|
||||
}
|
||||
_oe, ok := _f.(field.OrderExpr)
|
||||
return _oe, ok
|
||||
}
|
||||
|
||||
func (c *chatFlowRoleConfig) fillFieldMap() {
|
||||
c.fieldMap = make(map[string]field.Expr, 16)
|
||||
c.fieldMap["id"] = c.ID
|
||||
c.fieldMap["workflow_id"] = c.WorkflowID
|
||||
c.fieldMap["name"] = c.Name
|
||||
c.fieldMap["description"] = c.Description
|
||||
c.fieldMap["version"] = c.Version
|
||||
c.fieldMap["avatar"] = c.Avatar
|
||||
c.fieldMap["background_image_info"] = c.BackgroundImageInfo
|
||||
c.fieldMap["onboarding_info"] = c.OnboardingInfo
|
||||
c.fieldMap["suggest_reply_info"] = c.SuggestReplyInfo
|
||||
c.fieldMap["audio_config"] = c.AudioConfig
|
||||
c.fieldMap["user_input_config"] = c.UserInputConfig
|
||||
c.fieldMap["creator_id"] = c.CreatorID
|
||||
c.fieldMap["created_at"] = c.CreatedAt
|
||||
c.fieldMap["updated_at"] = c.UpdatedAt
|
||||
c.fieldMap["deleted_at"] = c.DeletedAt
|
||||
c.fieldMap["connector_id"] = c.ConnectorID
|
||||
}
|
||||
|
||||
func (c chatFlowRoleConfig) clone(db *gorm.DB) chatFlowRoleConfig {
|
||||
c.chatFlowRoleConfigDo.ReplaceConnPool(db.Statement.ConnPool)
|
||||
return c
|
||||
}
|
||||
|
||||
func (c chatFlowRoleConfig) replaceDB(db *gorm.DB) chatFlowRoleConfig {
|
||||
c.chatFlowRoleConfigDo.ReplaceDB(db)
|
||||
return c
|
||||
}
|
||||
|
||||
type chatFlowRoleConfigDo struct{ gen.DO }
|
||||
|
||||
type IChatFlowRoleConfigDo interface {
|
||||
gen.SubQuery
|
||||
Debug() IChatFlowRoleConfigDo
|
||||
WithContext(ctx context.Context) IChatFlowRoleConfigDo
|
||||
WithResult(fc func(tx gen.Dao)) gen.ResultInfo
|
||||
ReplaceDB(db *gorm.DB)
|
||||
ReadDB() IChatFlowRoleConfigDo
|
||||
WriteDB() IChatFlowRoleConfigDo
|
||||
As(alias string) gen.Dao
|
||||
Session(config *gorm.Session) IChatFlowRoleConfigDo
|
||||
Columns(cols ...field.Expr) gen.Columns
|
||||
Clauses(conds ...clause.Expression) IChatFlowRoleConfigDo
|
||||
Not(conds ...gen.Condition) IChatFlowRoleConfigDo
|
||||
Or(conds ...gen.Condition) IChatFlowRoleConfigDo
|
||||
Select(conds ...field.Expr) IChatFlowRoleConfigDo
|
||||
Where(conds ...gen.Condition) IChatFlowRoleConfigDo
|
||||
Order(conds ...field.Expr) IChatFlowRoleConfigDo
|
||||
Distinct(cols ...field.Expr) IChatFlowRoleConfigDo
|
||||
Omit(cols ...field.Expr) IChatFlowRoleConfigDo
|
||||
Join(table schema.Tabler, on ...field.Expr) IChatFlowRoleConfigDo
|
||||
LeftJoin(table schema.Tabler, on ...field.Expr) IChatFlowRoleConfigDo
|
||||
RightJoin(table schema.Tabler, on ...field.Expr) IChatFlowRoleConfigDo
|
||||
Group(cols ...field.Expr) IChatFlowRoleConfigDo
|
||||
Having(conds ...gen.Condition) IChatFlowRoleConfigDo
|
||||
Limit(limit int) IChatFlowRoleConfigDo
|
||||
Offset(offset int) IChatFlowRoleConfigDo
|
||||
Count() (count int64, err error)
|
||||
Scopes(funcs ...func(gen.Dao) gen.Dao) IChatFlowRoleConfigDo
|
||||
Unscoped() IChatFlowRoleConfigDo
|
||||
Create(values ...*model.ChatFlowRoleConfig) error
|
||||
CreateInBatches(values []*model.ChatFlowRoleConfig, batchSize int) error
|
||||
Save(values ...*model.ChatFlowRoleConfig) error
|
||||
First() (*model.ChatFlowRoleConfig, error)
|
||||
Take() (*model.ChatFlowRoleConfig, error)
|
||||
Last() (*model.ChatFlowRoleConfig, error)
|
||||
Find() ([]*model.ChatFlowRoleConfig, error)
|
||||
FindInBatch(batchSize int, fc func(tx gen.Dao, batch int) error) (results []*model.ChatFlowRoleConfig, err error)
|
||||
FindInBatches(result *[]*model.ChatFlowRoleConfig, batchSize int, fc func(tx gen.Dao, batch int) error) error
|
||||
Pluck(column field.Expr, dest interface{}) error
|
||||
Delete(...*model.ChatFlowRoleConfig) (info gen.ResultInfo, err error)
|
||||
Update(column field.Expr, value interface{}) (info gen.ResultInfo, err error)
|
||||
UpdateSimple(columns ...field.AssignExpr) (info gen.ResultInfo, err error)
|
||||
Updates(value interface{}) (info gen.ResultInfo, err error)
|
||||
UpdateColumn(column field.Expr, value interface{}) (info gen.ResultInfo, err error)
|
||||
UpdateColumnSimple(columns ...field.AssignExpr) (info gen.ResultInfo, err error)
|
||||
UpdateColumns(value interface{}) (info gen.ResultInfo, err error)
|
||||
UpdateFrom(q gen.SubQuery) gen.Dao
|
||||
Attrs(attrs ...field.AssignExpr) IChatFlowRoleConfigDo
|
||||
Assign(attrs ...field.AssignExpr) IChatFlowRoleConfigDo
|
||||
Joins(fields ...field.RelationField) IChatFlowRoleConfigDo
|
||||
Preload(fields ...field.RelationField) IChatFlowRoleConfigDo
|
||||
FirstOrInit() (*model.ChatFlowRoleConfig, error)
|
||||
FirstOrCreate() (*model.ChatFlowRoleConfig, error)
|
||||
FindByPage(offset int, limit int) (result []*model.ChatFlowRoleConfig, count int64, err error)
|
||||
ScanByPage(result interface{}, offset int, limit int) (count int64, err error)
|
||||
Scan(result interface{}) (err error)
|
||||
Returning(value interface{}, columns ...string) IChatFlowRoleConfigDo
|
||||
UnderlyingDB() *gorm.DB
|
||||
schema.Tabler
|
||||
}
|
||||
|
||||
func (c chatFlowRoleConfigDo) Debug() IChatFlowRoleConfigDo {
|
||||
return c.withDO(c.DO.Debug())
|
||||
}
|
||||
|
||||
func (c chatFlowRoleConfigDo) WithContext(ctx context.Context) IChatFlowRoleConfigDo {
|
||||
return c.withDO(c.DO.WithContext(ctx))
|
||||
}
|
||||
|
||||
func (c chatFlowRoleConfigDo) ReadDB() IChatFlowRoleConfigDo {
|
||||
return c.Clauses(dbresolver.Read)
|
||||
}
|
||||
|
||||
func (c chatFlowRoleConfigDo) WriteDB() IChatFlowRoleConfigDo {
|
||||
return c.Clauses(dbresolver.Write)
|
||||
}
|
||||
|
||||
func (c chatFlowRoleConfigDo) Session(config *gorm.Session) IChatFlowRoleConfigDo {
|
||||
return c.withDO(c.DO.Session(config))
|
||||
}
|
||||
|
||||
func (c chatFlowRoleConfigDo) Clauses(conds ...clause.Expression) IChatFlowRoleConfigDo {
|
||||
return c.withDO(c.DO.Clauses(conds...))
|
||||
}
|
||||
|
||||
func (c chatFlowRoleConfigDo) Returning(value interface{}, columns ...string) IChatFlowRoleConfigDo {
|
||||
return c.withDO(c.DO.Returning(value, columns...))
|
||||
}
|
||||
|
||||
func (c chatFlowRoleConfigDo) Not(conds ...gen.Condition) IChatFlowRoleConfigDo {
|
||||
return c.withDO(c.DO.Not(conds...))
|
||||
}
|
||||
|
||||
func (c chatFlowRoleConfigDo) Or(conds ...gen.Condition) IChatFlowRoleConfigDo {
|
||||
return c.withDO(c.DO.Or(conds...))
|
||||
}
|
||||
|
||||
func (c chatFlowRoleConfigDo) Select(conds ...field.Expr) IChatFlowRoleConfigDo {
|
||||
return c.withDO(c.DO.Select(conds...))
|
||||
}
|
||||
|
||||
func (c chatFlowRoleConfigDo) Where(conds ...gen.Condition) IChatFlowRoleConfigDo {
|
||||
return c.withDO(c.DO.Where(conds...))
|
||||
}
|
||||
|
||||
func (c chatFlowRoleConfigDo) Order(conds ...field.Expr) IChatFlowRoleConfigDo {
|
||||
return c.withDO(c.DO.Order(conds...))
|
||||
}
|
||||
|
||||
func (c chatFlowRoleConfigDo) Distinct(cols ...field.Expr) IChatFlowRoleConfigDo {
|
||||
return c.withDO(c.DO.Distinct(cols...))
|
||||
}
|
||||
|
||||
func (c chatFlowRoleConfigDo) Omit(cols ...field.Expr) IChatFlowRoleConfigDo {
|
||||
return c.withDO(c.DO.Omit(cols...))
|
||||
}
|
||||
|
||||
func (c chatFlowRoleConfigDo) Join(table schema.Tabler, on ...field.Expr) IChatFlowRoleConfigDo {
|
||||
return c.withDO(c.DO.Join(table, on...))
|
||||
}
|
||||
|
||||
func (c chatFlowRoleConfigDo) LeftJoin(table schema.Tabler, on ...field.Expr) IChatFlowRoleConfigDo {
|
||||
return c.withDO(c.DO.LeftJoin(table, on...))
|
||||
}
|
||||
|
||||
func (c chatFlowRoleConfigDo) RightJoin(table schema.Tabler, on ...field.Expr) IChatFlowRoleConfigDo {
|
||||
return c.withDO(c.DO.RightJoin(table, on...))
|
||||
}
|
||||
|
||||
func (c chatFlowRoleConfigDo) Group(cols ...field.Expr) IChatFlowRoleConfigDo {
|
||||
return c.withDO(c.DO.Group(cols...))
|
||||
}
|
||||
|
||||
func (c chatFlowRoleConfigDo) Having(conds ...gen.Condition) IChatFlowRoleConfigDo {
|
||||
return c.withDO(c.DO.Having(conds...))
|
||||
}
|
||||
|
||||
func (c chatFlowRoleConfigDo) Limit(limit int) IChatFlowRoleConfigDo {
|
||||
return c.withDO(c.DO.Limit(limit))
|
||||
}
|
||||
|
||||
func (c chatFlowRoleConfigDo) Offset(offset int) IChatFlowRoleConfigDo {
|
||||
return c.withDO(c.DO.Offset(offset))
|
||||
}
|
||||
|
||||
func (c chatFlowRoleConfigDo) Scopes(funcs ...func(gen.Dao) gen.Dao) IChatFlowRoleConfigDo {
|
||||
return c.withDO(c.DO.Scopes(funcs...))
|
||||
}
|
||||
|
||||
func (c chatFlowRoleConfigDo) Unscoped() IChatFlowRoleConfigDo {
|
||||
return c.withDO(c.DO.Unscoped())
|
||||
}
|
||||
|
||||
func (c chatFlowRoleConfigDo) Create(values ...*model.ChatFlowRoleConfig) error {
|
||||
if len(values) == 0 {
|
||||
return nil
|
||||
}
|
||||
return c.DO.Create(values)
|
||||
}
|
||||
|
||||
func (c chatFlowRoleConfigDo) CreateInBatches(values []*model.ChatFlowRoleConfig, batchSize int) error {
|
||||
return c.DO.CreateInBatches(values, batchSize)
|
||||
}
|
||||
|
||||
// Save : !!! underlying implementation is different with GORM
|
||||
// The method is equivalent to executing the statement: db.Clauses(clause.OnConflict{UpdateAll: true}).Create(values)
|
||||
func (c chatFlowRoleConfigDo) Save(values ...*model.ChatFlowRoleConfig) error {
|
||||
if len(values) == 0 {
|
||||
return nil
|
||||
}
|
||||
return c.DO.Save(values)
|
||||
}
|
||||
|
||||
func (c chatFlowRoleConfigDo) First() (*model.ChatFlowRoleConfig, error) {
|
||||
if result, err := c.DO.First(); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return result.(*model.ChatFlowRoleConfig), nil
|
||||
}
|
||||
}
|
||||
|
||||
func (c chatFlowRoleConfigDo) Take() (*model.ChatFlowRoleConfig, error) {
|
||||
if result, err := c.DO.Take(); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return result.(*model.ChatFlowRoleConfig), nil
|
||||
}
|
||||
}
|
||||
|
||||
func (c chatFlowRoleConfigDo) Last() (*model.ChatFlowRoleConfig, error) {
|
||||
if result, err := c.DO.Last(); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return result.(*model.ChatFlowRoleConfig), nil
|
||||
}
|
||||
}
|
||||
|
||||
func (c chatFlowRoleConfigDo) Find() ([]*model.ChatFlowRoleConfig, error) {
|
||||
result, err := c.DO.Find()
|
||||
return result.([]*model.ChatFlowRoleConfig), err
|
||||
}
|
||||
|
||||
func (c chatFlowRoleConfigDo) FindInBatch(batchSize int, fc func(tx gen.Dao, batch int) error) (results []*model.ChatFlowRoleConfig, err error) {
|
||||
buf := make([]*model.ChatFlowRoleConfig, 0, batchSize)
|
||||
err = c.DO.FindInBatches(&buf, batchSize, func(tx gen.Dao, batch int) error {
|
||||
defer func() { results = append(results, buf...) }()
|
||||
return fc(tx, batch)
|
||||
})
|
||||
return results, err
|
||||
}
|
||||
|
||||
func (c chatFlowRoleConfigDo) FindInBatches(result *[]*model.ChatFlowRoleConfig, batchSize int, fc func(tx gen.Dao, batch int) error) error {
|
||||
return c.DO.FindInBatches(result, batchSize, fc)
|
||||
}
|
||||
|
||||
func (c chatFlowRoleConfigDo) Attrs(attrs ...field.AssignExpr) IChatFlowRoleConfigDo {
|
||||
return c.withDO(c.DO.Attrs(attrs...))
|
||||
}
|
||||
|
||||
func (c chatFlowRoleConfigDo) Assign(attrs ...field.AssignExpr) IChatFlowRoleConfigDo {
|
||||
return c.withDO(c.DO.Assign(attrs...))
|
||||
}
|
||||
|
||||
func (c chatFlowRoleConfigDo) Joins(fields ...field.RelationField) IChatFlowRoleConfigDo {
|
||||
for _, _f := range fields {
|
||||
c = *c.withDO(c.DO.Joins(_f))
|
||||
}
|
||||
return &c
|
||||
}
|
||||
|
||||
func (c chatFlowRoleConfigDo) Preload(fields ...field.RelationField) IChatFlowRoleConfigDo {
|
||||
for _, _f := range fields {
|
||||
c = *c.withDO(c.DO.Preload(_f))
|
||||
}
|
||||
return &c
|
||||
}
|
||||
|
||||
func (c chatFlowRoleConfigDo) FirstOrInit() (*model.ChatFlowRoleConfig, error) {
|
||||
if result, err := c.DO.FirstOrInit(); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return result.(*model.ChatFlowRoleConfig), nil
|
||||
}
|
||||
}
|
||||
|
||||
func (c chatFlowRoleConfigDo) FirstOrCreate() (*model.ChatFlowRoleConfig, error) {
|
||||
if result, err := c.DO.FirstOrCreate(); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return result.(*model.ChatFlowRoleConfig), nil
|
||||
}
|
||||
}
|
||||
|
||||
func (c chatFlowRoleConfigDo) FindByPage(offset int, limit int) (result []*model.ChatFlowRoleConfig, count int64, err error) {
|
||||
result, err = c.Offset(offset).Limit(limit).Find()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if size := len(result); 0 < limit && 0 < size && size < limit {
|
||||
count = int64(size + offset)
|
||||
return
|
||||
}
|
||||
|
||||
count, err = c.Offset(-1).Limit(-1).Count()
|
||||
return
|
||||
}
|
||||
|
||||
func (c chatFlowRoleConfigDo) ScanByPage(result interface{}, offset int, limit int) (count int64, err error) {
|
||||
count, err = c.Count()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
err = c.Offset(offset).Limit(limit).Scan(result)
|
||||
return
|
||||
}
|
||||
|
||||
func (c chatFlowRoleConfigDo) Scan(result interface{}) (err error) {
|
||||
return c.DO.Scan(result)
|
||||
}
|
||||
|
||||
func (c chatFlowRoleConfigDo) Delete(models ...*model.ChatFlowRoleConfig) (result gen.ResultInfo, err error) {
|
||||
return c.DO.Delete(models)
|
||||
}
|
||||
|
||||
func (c *chatFlowRoleConfigDo) withDO(do gen.Dao) *chatFlowRoleConfigDo {
|
||||
c.DO = *do.(*gen.DO)
|
||||
return c
|
||||
}
|
||||
@@ -16,20 +16,34 @@ import (
|
||||
)
|
||||
|
||||
var (
|
||||
Q = new(Query)
|
||||
ConnectorWorkflowVersion *connectorWorkflowVersion
|
||||
NodeExecution *nodeExecution
|
||||
WorkflowDraft *workflowDraft
|
||||
WorkflowExecution *workflowExecution
|
||||
WorkflowMeta *workflowMeta
|
||||
WorkflowReference *workflowReference
|
||||
WorkflowSnapshot *workflowSnapshot
|
||||
WorkflowVersion *workflowVersion
|
||||
Q = new(Query)
|
||||
ConnectorWorkflowVersion *connectorWorkflowVersion
|
||||
AppConversationTemplateDraft *appConversationTemplateDraft
|
||||
AppConversationTemplateOnline *appConversationTemplateOnline
|
||||
AppDynamicConversationDraft *appDynamicConversationDraft
|
||||
AppDynamicConversationOnline *appDynamicConversationOnline
|
||||
AppStaticConversationDraft *appStaticConversationDraft
|
||||
AppStaticConversationOnline *appStaticConversationOnline
|
||||
ChatFlowRoleConfig *chatFlowRoleConfig
|
||||
NodeExecution *nodeExecution
|
||||
WorkflowDraft *workflowDraft
|
||||
WorkflowExecution *workflowExecution
|
||||
WorkflowMeta *workflowMeta
|
||||
WorkflowReference *workflowReference
|
||||
WorkflowSnapshot *workflowSnapshot
|
||||
WorkflowVersion *workflowVersion
|
||||
)
|
||||
|
||||
func SetDefault(db *gorm.DB, opts ...gen.DOOption) {
|
||||
*Q = *Use(db, opts...)
|
||||
ConnectorWorkflowVersion = &Q.ConnectorWorkflowVersion
|
||||
AppConversationTemplateDraft = &Q.AppConversationTemplateDraft
|
||||
AppConversationTemplateOnline = &Q.AppConversationTemplateOnline
|
||||
AppDynamicConversationDraft = &Q.AppDynamicConversationDraft
|
||||
AppDynamicConversationOnline = &Q.AppDynamicConversationOnline
|
||||
AppStaticConversationDraft = &Q.AppStaticConversationDraft
|
||||
AppStaticConversationOnline = &Q.AppStaticConversationOnline
|
||||
ChatFlowRoleConfig = &Q.ChatFlowRoleConfig
|
||||
NodeExecution = &Q.NodeExecution
|
||||
WorkflowDraft = &Q.WorkflowDraft
|
||||
WorkflowExecution = &Q.WorkflowExecution
|
||||
@@ -41,44 +55,65 @@ func SetDefault(db *gorm.DB, opts ...gen.DOOption) {
|
||||
|
||||
func Use(db *gorm.DB, opts ...gen.DOOption) *Query {
|
||||
return &Query{
|
||||
db: db,
|
||||
ConnectorWorkflowVersion: newConnectorWorkflowVersion(db, opts...),
|
||||
NodeExecution: newNodeExecution(db, opts...),
|
||||
WorkflowDraft: newWorkflowDraft(db, opts...),
|
||||
WorkflowExecution: newWorkflowExecution(db, opts...),
|
||||
WorkflowMeta: newWorkflowMeta(db, opts...),
|
||||
WorkflowReference: newWorkflowReference(db, opts...),
|
||||
WorkflowSnapshot: newWorkflowSnapshot(db, opts...),
|
||||
WorkflowVersion: newWorkflowVersion(db, opts...),
|
||||
db: db,
|
||||
ConnectorWorkflowVersion: newConnectorWorkflowVersion(db, opts...),
|
||||
AppConversationTemplateDraft: newAppConversationTemplateDraft(db, opts...),
|
||||
AppConversationTemplateOnline: newAppConversationTemplateOnline(db, opts...),
|
||||
AppDynamicConversationDraft: newAppDynamicConversationDraft(db, opts...),
|
||||
AppDynamicConversationOnline: newAppDynamicConversationOnline(db, opts...),
|
||||
AppStaticConversationDraft: newAppStaticConversationDraft(db, opts...),
|
||||
AppStaticConversationOnline: newAppStaticConversationOnline(db, opts...),
|
||||
ChatFlowRoleConfig: newChatFlowRoleConfig(db, opts...),
|
||||
NodeExecution: newNodeExecution(db, opts...),
|
||||
WorkflowDraft: newWorkflowDraft(db, opts...),
|
||||
WorkflowExecution: newWorkflowExecution(db, opts...),
|
||||
WorkflowMeta: newWorkflowMeta(db, opts...),
|
||||
WorkflowReference: newWorkflowReference(db, opts...),
|
||||
WorkflowSnapshot: newWorkflowSnapshot(db, opts...),
|
||||
WorkflowVersion: newWorkflowVersion(db, opts...),
|
||||
}
|
||||
}
|
||||
|
||||
type Query struct {
|
||||
db *gorm.DB
|
||||
|
||||
ConnectorWorkflowVersion connectorWorkflowVersion
|
||||
NodeExecution nodeExecution
|
||||
WorkflowDraft workflowDraft
|
||||
WorkflowExecution workflowExecution
|
||||
WorkflowMeta workflowMeta
|
||||
WorkflowReference workflowReference
|
||||
WorkflowSnapshot workflowSnapshot
|
||||
WorkflowVersion workflowVersion
|
||||
ConnectorWorkflowVersion connectorWorkflowVersion
|
||||
AppConversationTemplateDraft appConversationTemplateDraft
|
||||
AppConversationTemplateOnline appConversationTemplateOnline
|
||||
AppDynamicConversationDraft appDynamicConversationDraft
|
||||
AppDynamicConversationOnline appDynamicConversationOnline
|
||||
AppStaticConversationDraft appStaticConversationDraft
|
||||
AppStaticConversationOnline appStaticConversationOnline
|
||||
ChatFlowRoleConfig chatFlowRoleConfig
|
||||
NodeExecution nodeExecution
|
||||
WorkflowDraft workflowDraft
|
||||
WorkflowExecution workflowExecution
|
||||
WorkflowMeta workflowMeta
|
||||
WorkflowReference workflowReference
|
||||
WorkflowSnapshot workflowSnapshot
|
||||
WorkflowVersion workflowVersion
|
||||
}
|
||||
|
||||
func (q *Query) Available() bool { return q.db != nil }
|
||||
|
||||
func (q *Query) clone(db *gorm.DB) *Query {
|
||||
return &Query{
|
||||
db: db,
|
||||
ConnectorWorkflowVersion: q.ConnectorWorkflowVersion.clone(db),
|
||||
NodeExecution: q.NodeExecution.clone(db),
|
||||
WorkflowDraft: q.WorkflowDraft.clone(db),
|
||||
WorkflowExecution: q.WorkflowExecution.clone(db),
|
||||
WorkflowMeta: q.WorkflowMeta.clone(db),
|
||||
WorkflowReference: q.WorkflowReference.clone(db),
|
||||
WorkflowSnapshot: q.WorkflowSnapshot.clone(db),
|
||||
WorkflowVersion: q.WorkflowVersion.clone(db),
|
||||
db: db,
|
||||
ConnectorWorkflowVersion: q.ConnectorWorkflowVersion.clone(db),
|
||||
AppConversationTemplateDraft: q.AppConversationTemplateDraft.clone(db),
|
||||
AppConversationTemplateOnline: q.AppConversationTemplateOnline.clone(db),
|
||||
AppDynamicConversationDraft: q.AppDynamicConversationDraft.clone(db),
|
||||
AppDynamicConversationOnline: q.AppDynamicConversationOnline.clone(db),
|
||||
AppStaticConversationDraft: q.AppStaticConversationDraft.clone(db),
|
||||
AppStaticConversationOnline: q.AppStaticConversationOnline.clone(db),
|
||||
ChatFlowRoleConfig: q.ChatFlowRoleConfig.clone(db),
|
||||
NodeExecution: q.NodeExecution.clone(db),
|
||||
WorkflowDraft: q.WorkflowDraft.clone(db),
|
||||
WorkflowExecution: q.WorkflowExecution.clone(db),
|
||||
WorkflowMeta: q.WorkflowMeta.clone(db),
|
||||
WorkflowReference: q.WorkflowReference.clone(db),
|
||||
WorkflowSnapshot: q.WorkflowSnapshot.clone(db),
|
||||
WorkflowVersion: q.WorkflowVersion.clone(db),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -92,39 +127,60 @@ func (q *Query) WriteDB() *Query {
|
||||
|
||||
func (q *Query) ReplaceDB(db *gorm.DB) *Query {
|
||||
return &Query{
|
||||
db: db,
|
||||
ConnectorWorkflowVersion: q.ConnectorWorkflowVersion.replaceDB(db),
|
||||
NodeExecution: q.NodeExecution.replaceDB(db),
|
||||
WorkflowDraft: q.WorkflowDraft.replaceDB(db),
|
||||
WorkflowExecution: q.WorkflowExecution.replaceDB(db),
|
||||
WorkflowMeta: q.WorkflowMeta.replaceDB(db),
|
||||
WorkflowReference: q.WorkflowReference.replaceDB(db),
|
||||
WorkflowSnapshot: q.WorkflowSnapshot.replaceDB(db),
|
||||
WorkflowVersion: q.WorkflowVersion.replaceDB(db),
|
||||
db: db,
|
||||
ConnectorWorkflowVersion: q.ConnectorWorkflowVersion.replaceDB(db),
|
||||
AppConversationTemplateDraft: q.AppConversationTemplateDraft.replaceDB(db),
|
||||
AppConversationTemplateOnline: q.AppConversationTemplateOnline.replaceDB(db),
|
||||
AppDynamicConversationDraft: q.AppDynamicConversationDraft.replaceDB(db),
|
||||
AppDynamicConversationOnline: q.AppDynamicConversationOnline.replaceDB(db),
|
||||
AppStaticConversationDraft: q.AppStaticConversationDraft.replaceDB(db),
|
||||
AppStaticConversationOnline: q.AppStaticConversationOnline.replaceDB(db),
|
||||
ChatFlowRoleConfig: q.ChatFlowRoleConfig.replaceDB(db),
|
||||
NodeExecution: q.NodeExecution.replaceDB(db),
|
||||
WorkflowDraft: q.WorkflowDraft.replaceDB(db),
|
||||
WorkflowExecution: q.WorkflowExecution.replaceDB(db),
|
||||
WorkflowMeta: q.WorkflowMeta.replaceDB(db),
|
||||
WorkflowReference: q.WorkflowReference.replaceDB(db),
|
||||
WorkflowSnapshot: q.WorkflowSnapshot.replaceDB(db),
|
||||
WorkflowVersion: q.WorkflowVersion.replaceDB(db),
|
||||
}
|
||||
}
|
||||
|
||||
type queryCtx struct {
|
||||
ConnectorWorkflowVersion IConnectorWorkflowVersionDo
|
||||
NodeExecution INodeExecutionDo
|
||||
WorkflowDraft IWorkflowDraftDo
|
||||
WorkflowExecution IWorkflowExecutionDo
|
||||
WorkflowMeta IWorkflowMetaDo
|
||||
WorkflowReference IWorkflowReferenceDo
|
||||
WorkflowSnapshot IWorkflowSnapshotDo
|
||||
WorkflowVersion IWorkflowVersionDo
|
||||
ConnectorWorkflowVersion IConnectorWorkflowVersionDo
|
||||
AppConversationTemplateDraft IAppConversationTemplateDraftDo
|
||||
AppConversationTemplateOnline IAppConversationTemplateOnlineDo
|
||||
AppDynamicConversationDraft IAppDynamicConversationDraftDo
|
||||
AppDynamicConversationOnline IAppDynamicConversationOnlineDo
|
||||
AppStaticConversationDraft IAppStaticConversationDraftDo
|
||||
AppStaticConversationOnline IAppStaticConversationOnlineDo
|
||||
ChatFlowRoleConfig IChatFlowRoleConfigDo
|
||||
NodeExecution INodeExecutionDo
|
||||
WorkflowDraft IWorkflowDraftDo
|
||||
WorkflowExecution IWorkflowExecutionDo
|
||||
WorkflowMeta IWorkflowMetaDo
|
||||
WorkflowReference IWorkflowReferenceDo
|
||||
WorkflowSnapshot IWorkflowSnapshotDo
|
||||
WorkflowVersion IWorkflowVersionDo
|
||||
}
|
||||
|
||||
func (q *Query) WithContext(ctx context.Context) *queryCtx {
|
||||
return &queryCtx{
|
||||
ConnectorWorkflowVersion: q.ConnectorWorkflowVersion.WithContext(ctx),
|
||||
NodeExecution: q.NodeExecution.WithContext(ctx),
|
||||
WorkflowDraft: q.WorkflowDraft.WithContext(ctx),
|
||||
WorkflowExecution: q.WorkflowExecution.WithContext(ctx),
|
||||
WorkflowMeta: q.WorkflowMeta.WithContext(ctx),
|
||||
WorkflowReference: q.WorkflowReference.WithContext(ctx),
|
||||
WorkflowSnapshot: q.WorkflowSnapshot.WithContext(ctx),
|
||||
WorkflowVersion: q.WorkflowVersion.WithContext(ctx),
|
||||
ConnectorWorkflowVersion: q.ConnectorWorkflowVersion.WithContext(ctx),
|
||||
AppConversationTemplateDraft: q.AppConversationTemplateDraft.WithContext(ctx),
|
||||
AppConversationTemplateOnline: q.AppConversationTemplateOnline.WithContext(ctx),
|
||||
AppDynamicConversationDraft: q.AppDynamicConversationDraft.WithContext(ctx),
|
||||
AppDynamicConversationOnline: q.AppDynamicConversationOnline.WithContext(ctx),
|
||||
AppStaticConversationDraft: q.AppStaticConversationDraft.WithContext(ctx),
|
||||
AppStaticConversationOnline: q.AppStaticConversationOnline.WithContext(ctx),
|
||||
ChatFlowRoleConfig: q.ChatFlowRoleConfig.WithContext(ctx),
|
||||
NodeExecution: q.NodeExecution.WithContext(ctx),
|
||||
WorkflowDraft: q.WorkflowDraft.WithContext(ctx),
|
||||
WorkflowExecution: q.WorkflowExecution.WithContext(ctx),
|
||||
WorkflowMeta: q.WorkflowMeta.WithContext(ctx),
|
||||
WorkflowReference: q.WorkflowReference.WithContext(ctx),
|
||||
WorkflowSnapshot: q.WorkflowSnapshot.WithContext(ctx),
|
||||
WorkflowVersion: q.WorkflowVersion.WithContext(ctx),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -22,6 +22,8 @@ import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/redis/go-redis/v9"
|
||||
|
||||
"github.com/coze-dev/coze-studio/backend/domain/workflow/entity"
|
||||
"github.com/coze-dev/coze-studio/backend/domain/workflow/entity/vo"
|
||||
"github.com/coze-dev/coze-studio/backend/infra/contract/cache"
|
||||
@@ -38,6 +40,7 @@ const (
|
||||
interruptEventListKeyPattern = "interrupt_event_list:%d"
|
||||
interruptEventTTL = 24 * time.Hour // Example: expire after 24 hours
|
||||
previousResumedEventKeyPattern = "previous_resumed_event:%d"
|
||||
ConvToEventExecFormat = "conv_relate_info:%d"
|
||||
)
|
||||
|
||||
// SaveInterruptEvents saves multiple interrupt events to the end of a Redis list.
|
||||
@@ -246,3 +249,33 @@ func (i *interruptEventStoreImpl) ListInterruptEvents(ctx context.Context, wfExe
|
||||
|
||||
return events, nil
|
||||
}
|
||||
|
||||
func (i *interruptEventStoreImpl) BindConvRelatedInfo(ctx context.Context, convID int64, info entity.ConvRelatedInfo) error {
|
||||
data, err := sonic.Marshal(info)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
result := i.redis.Set(ctx, fmt.Sprintf(ConvToEventExecFormat, convID), data, interruptEventTTL)
|
||||
if result.Err() != nil {
|
||||
return result.Err()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (i *interruptEventStoreImpl) GetConvRelatedInfo(ctx context.Context, convID int64) (*entity.ConvRelatedInfo, bool, func() error, error) {
|
||||
data, err := i.redis.Get(ctx, fmt.Sprintf(ConvToEventExecFormat, convID)).Bytes()
|
||||
if err != nil {
|
||||
if errors.Is(err, redis.Nil) {
|
||||
return nil, false, nil, nil
|
||||
}
|
||||
return nil, false, nil, err
|
||||
}
|
||||
rInfo := &entity.ConvRelatedInfo{}
|
||||
err = sonic.UnmarshalString(string(data), rInfo)
|
||||
if err != nil {
|
||||
return nil, false, nil, err
|
||||
}
|
||||
return rInfo, true, func() error {
|
||||
return i.redis.Del(ctx, fmt.Sprintf(ConvToEventExecFormat, convID)).Err()
|
||||
}, nil
|
||||
}
|
||||
|
||||
@@ -70,10 +70,15 @@ type RepositoryImpl struct {
|
||||
workflow.ExecuteHistoryStore
|
||||
builtinModel cm.BaseChatModel
|
||||
workflow.WorkflowConfig
|
||||
workflow.Suggester
|
||||
}
|
||||
|
||||
func NewRepository(idgen idgen.IDGenerator, db *gorm.DB, redis cache.Cmdable, tos storage.Storage,
|
||||
cpStore einoCompose.CheckPointStore, chatModel cm.BaseChatModel, workflowConfig workflow.WorkflowConfig) workflow.Repository {
|
||||
cpStore einoCompose.CheckPointStore, chatModel cm.BaseChatModel, workflowConfig workflow.WorkflowConfig) (workflow.Repository, error) {
|
||||
sg, err := NewSuggester(chatModel)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &RepositoryImpl{
|
||||
IDGenerator: idgen,
|
||||
query: query.Use(db),
|
||||
@@ -90,9 +95,12 @@ func NewRepository(idgen idgen.IDGenerator, db *gorm.DB, redis cache.Cmdable, to
|
||||
query: query.Use(db),
|
||||
redis: redis,
|
||||
},
|
||||
|
||||
builtinModel: chatModel,
|
||||
Suggester: sg,
|
||||
WorkflowConfig: workflowConfig,
|
||||
}
|
||||
}, nil
|
||||
|
||||
}
|
||||
|
||||
func (r *RepositoryImpl) CreateMeta(ctx context.Context, meta *vo.Meta) (int64, error) {
|
||||
@@ -320,13 +328,16 @@ func (r *RepositoryImpl) CreateVersion(ctx context.Context, id int64, info *vo.V
|
||||
|
||||
func (r *RepositoryImpl) CreateOrUpdateDraft(ctx context.Context, id int64, draft *vo.DraftInfo) error {
|
||||
d := &model.WorkflowDraft{
|
||||
ID: id,
|
||||
Canvas: draft.Canvas,
|
||||
InputParams: draft.InputParamsStr,
|
||||
OutputParams: draft.OutputParamsStr,
|
||||
Modified: draft.Modified,
|
||||
TestRunSuccess: draft.TestRunSuccess,
|
||||
CommitID: draft.CommitID,
|
||||
ID: id,
|
||||
Canvas: draft.Canvas,
|
||||
InputParams: draft.InputParamsStr,
|
||||
OutputParams: draft.OutputParamsStr,
|
||||
CommitID: draft.CommitID,
|
||||
}
|
||||
|
||||
if draft.DraftMeta != nil {
|
||||
d.Modified = draft.DraftMeta.Modified
|
||||
d.TestRunSuccess = draft.DraftMeta.TestRunSuccess
|
||||
}
|
||||
|
||||
if err := r.query.WorkflowDraft.WithContext(ctx).Save(d); err != nil {
|
||||
@@ -500,6 +511,10 @@ func (r *RepositoryImpl) UpdateMeta(ctx context.Context, id int64, metaUpdate *v
|
||||
expressions = append(expressions, r.query.WorkflowMeta.LatestVersion.Value(*metaUpdate.LatestPublishedVersion))
|
||||
}
|
||||
|
||||
if metaUpdate.WorkflowMode != nil {
|
||||
expressions = append(expressions, r.query.WorkflowMeta.Mode.Value(int32(*metaUpdate.WorkflowMode)))
|
||||
}
|
||||
|
||||
if len(expressions) == 0 {
|
||||
return nil
|
||||
}
|
||||
@@ -551,10 +566,13 @@ func (r *RepositoryImpl) GetEntity(ctx context.Context, policy *vo.GetPolicy) (_
|
||||
draftMeta = draft.DraftMeta
|
||||
commitID = draft.CommitID
|
||||
case workflowModel.FromSpecificVersion:
|
||||
v, err := r.GetVersion(ctx, policy.ID, policy.Version)
|
||||
v, existed, err := r.GetVersion(ctx, policy.ID, policy.Version)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if !existed {
|
||||
return nil, vo.WrapError(errno.ErrWorkflowNotFound, fmt.Errorf("workflow version %s not found for ID %d: %w", policy.Version, policy.ID, err), errorx.KV("id", strconv.FormatInt(policy.ID, 10)))
|
||||
}
|
||||
canvas = v.Canvas
|
||||
inputParams = v.InputParamsStr
|
||||
outputParams = v.OutputParamsStr
|
||||
@@ -604,7 +622,117 @@ func (r *RepositoryImpl) GetEntity(ctx context.Context, policy *vo.GetPolicy) (_
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (r *RepositoryImpl) GetVersion(ctx context.Context, id int64, version string) (_ *vo.VersionInfo, err error) {
|
||||
func (r *RepositoryImpl) CreateChatFlowRoleConfig(ctx context.Context, chatFlowRole *entity.ChatFlowRole) (int64, error) {
|
||||
id, err := r.GenID(ctx)
|
||||
if err != nil {
|
||||
return 0, vo.WrapError(errno.ErrIDGenError, err)
|
||||
}
|
||||
chatFlowRoleConfig := &model.ChatFlowRoleConfig{
|
||||
ID: id,
|
||||
WorkflowID: chatFlowRole.WorkflowID,
|
||||
Name: chatFlowRole.Name,
|
||||
Description: chatFlowRole.Description,
|
||||
Avatar: chatFlowRole.AvatarUri,
|
||||
AudioConfig: chatFlowRole.AudioConfig,
|
||||
BackgroundImageInfo: chatFlowRole.BackgroundImageInfo,
|
||||
OnboardingInfo: chatFlowRole.OnboardingInfo,
|
||||
SuggestReplyInfo: chatFlowRole.SuggestReplyInfo,
|
||||
UserInputConfig: chatFlowRole.UserInputConfig,
|
||||
CreatorID: chatFlowRole.CreatorID,
|
||||
Version: chatFlowRole.Version,
|
||||
}
|
||||
|
||||
if err := r.query.ChatFlowRoleConfig.WithContext(ctx).Create(chatFlowRoleConfig); err != nil {
|
||||
return 0, vo.WrapError(errno.ErrDatabaseError, fmt.Errorf("create chat flow role: %w", err))
|
||||
}
|
||||
|
||||
return id, nil
|
||||
}
|
||||
|
||||
func (r *RepositoryImpl) UpdateChatFlowRoleConfig(ctx context.Context, workflowID int64, chatFlowRole *vo.ChatFlowRoleUpdate) error {
|
||||
var expressions []field.AssignExpr
|
||||
if chatFlowRole.Name != nil {
|
||||
expressions = append(expressions, r.query.ChatFlowRoleConfig.Name.Value(*chatFlowRole.Name))
|
||||
}
|
||||
if chatFlowRole.Description != nil {
|
||||
expressions = append(expressions, r.query.ChatFlowRoleConfig.Description.Value(*chatFlowRole.Description))
|
||||
}
|
||||
if chatFlowRole.AvatarUri != nil {
|
||||
expressions = append(expressions, r.query.ChatFlowRoleConfig.Avatar.Value(*chatFlowRole.AvatarUri))
|
||||
}
|
||||
if chatFlowRole.AudioConfig != nil {
|
||||
expressions = append(expressions, r.query.ChatFlowRoleConfig.AudioConfig.Value(*chatFlowRole.AudioConfig))
|
||||
}
|
||||
if chatFlowRole.BackgroundImageInfo != nil {
|
||||
expressions = append(expressions, r.query.ChatFlowRoleConfig.BackgroundImageInfo.Value(*chatFlowRole.BackgroundImageInfo))
|
||||
}
|
||||
if chatFlowRole.OnboardingInfo != nil {
|
||||
expressions = append(expressions, r.query.ChatFlowRoleConfig.OnboardingInfo.Value(*chatFlowRole.OnboardingInfo))
|
||||
}
|
||||
if chatFlowRole.SuggestReplyInfo != nil {
|
||||
expressions = append(expressions, r.query.ChatFlowRoleConfig.SuggestReplyInfo.Value(*chatFlowRole.SuggestReplyInfo))
|
||||
}
|
||||
if chatFlowRole.UserInputConfig != nil {
|
||||
expressions = append(expressions, r.query.ChatFlowRoleConfig.UserInputConfig.Value(*chatFlowRole.UserInputConfig))
|
||||
}
|
||||
|
||||
if len(expressions) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
_, err := r.query.ChatFlowRoleConfig.WithContext(ctx).Where(r.query.ChatFlowRoleConfig.WorkflowID.Eq(workflowID)).
|
||||
UpdateColumnSimple(expressions...)
|
||||
if err != nil {
|
||||
return vo.WrapError(errno.ErrDatabaseError, fmt.Errorf("update chat flow role: %w", err))
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *RepositoryImpl) GetChatFlowRoleConfig(ctx context.Context, workflowID int64, version string) (_ *entity.ChatFlowRole, err error, isExist bool) {
|
||||
defer func() {
|
||||
if err != nil {
|
||||
err = vo.WrapIfNeeded(errno.ErrDatabaseError, err)
|
||||
}
|
||||
}()
|
||||
role := &model.ChatFlowRoleConfig{}
|
||||
if version != "" {
|
||||
role, err = r.query.ChatFlowRoleConfig.WithContext(ctx).Where(r.query.ChatFlowRoleConfig.WorkflowID.Eq(workflowID), r.query.ChatFlowRoleConfig.Version.Eq(version)).First()
|
||||
} else {
|
||||
role, err = r.query.ChatFlowRoleConfig.WithContext(ctx).Where(r.query.ChatFlowRoleConfig.WorkflowID.Eq(workflowID)).First()
|
||||
}
|
||||
if err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return nil, err, false
|
||||
}
|
||||
return nil, fmt.Errorf("failed to get chat flow role for chatflowID %d: %w", workflowID, err), true
|
||||
}
|
||||
res := &entity.ChatFlowRole{
|
||||
ID: role.ID,
|
||||
WorkflowID: role.WorkflowID,
|
||||
Name: role.Name,
|
||||
Description: role.Description,
|
||||
AvatarUri: role.Avatar,
|
||||
AudioConfig: role.AudioConfig,
|
||||
BackgroundImageInfo: role.BackgroundImageInfo,
|
||||
OnboardingInfo: role.OnboardingInfo,
|
||||
SuggestReplyInfo: role.SuggestReplyInfo,
|
||||
UserInputConfig: role.UserInputConfig,
|
||||
CreatorID: role.CreatorID,
|
||||
CreatedAt: time.UnixMilli(role.CreatedAt),
|
||||
}
|
||||
if role.UpdatedAt > 0 {
|
||||
res.UpdatedAt = time.UnixMilli(role.UpdatedAt)
|
||||
}
|
||||
return res, err, true
|
||||
}
|
||||
|
||||
func (r *RepositoryImpl) DeleteChatFlowRoleConfig(ctx context.Context, id int64, workflowID int64) error {
|
||||
_, err := r.query.ChatFlowRoleConfig.WithContext(ctx).Where(r.query.ChatFlowRoleConfig.ID.Eq(id), r.query.ChatFlowRoleConfig.WorkflowID.Eq(workflowID)).Delete()
|
||||
return err
|
||||
}
|
||||
|
||||
func (r *RepositoryImpl) GetVersion(ctx context.Context, id int64, version string) (_ *vo.VersionInfo, existed bool, err error) {
|
||||
defer func() {
|
||||
if err != nil {
|
||||
err = vo.WrapIfNeeded(errno.ErrDatabaseError, err)
|
||||
@@ -616,9 +744,9 @@ func (r *RepositoryImpl) GetVersion(ctx context.Context, id int64, version strin
|
||||
First()
|
||||
if err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return nil, vo.WrapError(errno.ErrWorkflowNotFound, fmt.Errorf("workflow version %s not found for ID %d: %w", version, id, err), errorx.KV("id", strconv.FormatInt(id, 10)))
|
||||
return nil, false, nil
|
||||
}
|
||||
return nil, fmt.Errorf("failed to get workflow version %s for ID %d: %w", version, id, err)
|
||||
return nil, false, fmt.Errorf("failed to get workflow version %s for ID %d: %w", version, id, err)
|
||||
}
|
||||
|
||||
return &vo.VersionInfo{
|
||||
@@ -634,7 +762,29 @@ func (r *RepositoryImpl) GetVersion(ctx context.Context, id int64, version strin
|
||||
OutputParamsStr: wfVersion.OutputParams,
|
||||
},
|
||||
CommitID: wfVersion.CommitID,
|
||||
}, nil
|
||||
}, true, nil
|
||||
}
|
||||
|
||||
func (r *RepositoryImpl) GetVersionListByConnectorAndWorkflowID(ctx context.Context, connectorID, workflowID int64, limit int) (_ []string, err error) {
|
||||
if limit <= 0 {
|
||||
return nil, vo.WrapError(errno.ErrInvalidParameter, errors.New("limit must be greater than 0"))
|
||||
}
|
||||
|
||||
connectorWorkflowVersion := r.query.ConnectorWorkflowVersion
|
||||
vl, err := connectorWorkflowVersion.WithContext(ctx).
|
||||
Where(connectorWorkflowVersion.ConnectorID.Eq(connectorID),
|
||||
connectorWorkflowVersion.WorkflowID.Eq(workflowID)).
|
||||
Order(connectorWorkflowVersion.CreatedAt.Desc()).
|
||||
Limit(limit).
|
||||
Find()
|
||||
if err != nil {
|
||||
return nil, vo.WrapError(errno.ErrDatabaseError, err)
|
||||
}
|
||||
var versionList []string
|
||||
for _, v := range vl {
|
||||
versionList = append(versionList, v.Version)
|
||||
}
|
||||
return versionList, nil
|
||||
}
|
||||
|
||||
func (r *RepositoryImpl) IsApplicationConnectorWorkflowVersion(ctx context.Context, connectorID, workflowID int64, version string) (b bool, err error) {
|
||||
@@ -767,6 +917,10 @@ func (r *RepositoryImpl) MGetDrafts(ctx context.Context, policy *vo.MGetPolicy)
|
||||
conditions = append(conditions, r.query.WorkflowMeta.AppID.Eq(0))
|
||||
}
|
||||
|
||||
if q.Mode != nil {
|
||||
conditions = append(conditions, r.query.WorkflowMeta.Mode.Eq(int32(*q.Mode)))
|
||||
}
|
||||
|
||||
type combinedDraft struct {
|
||||
model.WorkflowDraft
|
||||
Name string `gorm:"column:name"`
|
||||
@@ -933,6 +1087,10 @@ func (r *RepositoryImpl) MGetLatestVersion(ctx context.Context, policy *vo.MGetP
|
||||
conditions = append(conditions, r.query.WorkflowMeta.AppID.Eq(0))
|
||||
}
|
||||
|
||||
if q.Mode != nil {
|
||||
conditions = append(conditions, r.query.WorkflowMeta.Mode.Eq(int32(*q.Mode)))
|
||||
}
|
||||
|
||||
type combinedVersion struct {
|
||||
model.WorkflowMeta
|
||||
Version string `gorm:"column:version"` // release version
|
||||
@@ -1157,6 +1315,10 @@ func (r *RepositoryImpl) MGetMetas(ctx context.Context, query *vo.MetaQuery) (
|
||||
conditions = append(conditions, r.query.WorkflowMeta.AppID.Eq(0))
|
||||
}
|
||||
|
||||
if query.Mode != nil {
|
||||
conditions = append(conditions, r.query.WorkflowMeta.Mode.Eq(int32(*query.Mode)))
|
||||
}
|
||||
|
||||
var result []*model.WorkflowMeta
|
||||
|
||||
workflowMetaDo := r.query.WorkflowMeta.WithContext(ctx).Debug().Where(conditions...)
|
||||
@@ -1520,6 +1682,7 @@ func (r *RepositoryImpl) CopyWorkflow(ctx context.Context, workflowID int64, pol
|
||||
IconURI: wfMeta.IconURI,
|
||||
Desc: wfMeta.Description,
|
||||
AppID: ternary.IFElse(wfMeta.AppID == 0, (*int64)(nil), ptr.Of(wfMeta.AppID)),
|
||||
Mode: workflowModel.WorkflowMode(wfMeta.Mode),
|
||||
},
|
||||
CanvasInfo: &vo.CanvasInfo{
|
||||
Canvas: wfDraft.Canvas,
|
||||
@@ -1594,6 +1757,10 @@ func (r *RepositoryImpl) GetKnowledgeRecallChatModel() cm.BaseChatModel {
|
||||
return r.builtinModel
|
||||
}
|
||||
|
||||
func (r *RepositoryImpl) GetObjectUrl(ctx context.Context, objectKey string, opts ...storage.GetOptFn) (string, error) {
|
||||
return r.tos.GetObjectUrl(ctx, objectKey, opts...)
|
||||
}
|
||||
|
||||
func filterDisabledAPIParameters(parametersCfg []*workflow3.APIParameter, m map[string]any) map[string]any {
|
||||
result := make(map[string]any, len(m))
|
||||
responseParameterMap := slices.ToMap(parametersCfg, func(p *workflow3.APIParameter) (string, *workflow3.APIParameter) {
|
||||
|
||||
104
backend/domain/workflow/internal/repo/suggest.go
Normal file
104
backend/domain/workflow/internal/repo/suggest.go
Normal file
@@ -0,0 +1,104 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* 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 repo
|
||||
|
||||
import (
|
||||
"context"
|
||||
"regexp"
|
||||
|
||||
"github.com/cloudwego/eino/components/model"
|
||||
"github.com/cloudwego/eino/components/prompt"
|
||||
"github.com/cloudwego/eino/compose"
|
||||
einoCompose "github.com/cloudwego/eino/compose"
|
||||
"github.com/cloudwego/eino/schema"
|
||||
"github.com/coze-dev/coze-studio/backend/domain/workflow"
|
||||
"github.com/coze-dev/coze-studio/backend/domain/workflow/entity/vo"
|
||||
"github.com/coze-dev/coze-studio/backend/pkg/logs"
|
||||
"github.com/coze-dev/coze-studio/backend/pkg/sonic"
|
||||
)
|
||||
|
||||
const SUGGESTION_PROMPT = `
|
||||
# Role
|
||||
You are an AI assistant that quickly generates 3 relevant follow-up questions.
|
||||
|
||||
# Task
|
||||
Analyze the user's question and the assistant's answer to suggest 3 unique, concise follow-up questions.
|
||||
|
||||
**IMPORTANT**: The assistant's answer can be very long. To be fast, focus only on the main ideas and topics in the answer. Do not analyze the full text in detail.
|
||||
|
||||
### Persona
|
||||
{{ suggest_persona }}
|
||||
|
||||
## Output Format
|
||||
- Return **only** a single JSON string array.
|
||||
- Example: ["What is the history?", "How does it work?", "What are the benefits?"]
|
||||
- The questions must be in the same language as the user's input.
|
||||
`
|
||||
|
||||
type suggesterV3 struct {
|
||||
r einoCompose.Runnable[*vo.SuggestInfo, []string]
|
||||
}
|
||||
type state struct {
|
||||
userMessage *schema.Message
|
||||
answer *schema.Message
|
||||
}
|
||||
|
||||
var suggestRegexp = regexp.MustCompile(`\[(.*?)\]`)
|
||||
|
||||
func NewSuggester(chatModel model.BaseChatModel) (workflow.Suggester, error) {
|
||||
chain := einoCompose.NewChain[*vo.SuggestInfo, []string](einoCompose.WithGenLocalState(func(ctx context.Context) (s *state) {
|
||||
return &state{}
|
||||
}))
|
||||
r, err := chain.AppendLambda(einoCompose.InvokableLambda(func(ctx context.Context, input *vo.SuggestInfo) (output map[string]any, err error) {
|
||||
_ = compose.ProcessState(ctx, func(ctx context.Context, s *state) error {
|
||||
s.userMessage = input.UserInput
|
||||
s.answer = input.AnswerInput
|
||||
return nil
|
||||
})
|
||||
output = map[string]any{}
|
||||
if input.PersonaInput != nil {
|
||||
output["persona_input"] = *input.PersonaInput
|
||||
}
|
||||
return
|
||||
})).AppendChatTemplate(prompt.FromMessages(schema.Jinja2, schema.SystemMessage(SUGGESTION_PROMPT))).AppendChatModel(chatModel,
|
||||
compose.WithStatePreHandler(func(ctx context.Context, in []*schema.Message, state *state) ([]*schema.Message, error) {
|
||||
return append(in, []*schema.Message{state.userMessage, state.answer}...), nil
|
||||
})).AppendLambda(einoCompose.InvokableLambda(func(ctx context.Context, input *schema.Message) (output []string, err error) {
|
||||
content := suggestRegexp.FindString(input.Content)
|
||||
if len(content) == 0 {
|
||||
return
|
||||
}
|
||||
suggests := make([]string, 0)
|
||||
err = sonic.UnmarshalString(content, &suggests)
|
||||
if err != nil {
|
||||
logs.CtxErrorf(ctx, "Failed unmarshalling suggestions: %s", input.Content)
|
||||
|
||||
}
|
||||
return suggests, nil
|
||||
})).Compile(context.Background())
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &suggesterV3{r: r}, nil
|
||||
|
||||
}
|
||||
|
||||
func (s *suggesterV3) Suggest(ctx context.Context, info *vo.SuggestInfo) ([]string, error) {
|
||||
return s.r.Invoke(ctx, info)
|
||||
}
|
||||
490
backend/domain/workflow/service/conversation_impl.go
Normal file
490
backend/domain/workflow/service/conversation_impl.go
Normal file
@@ -0,0 +1,490 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* 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 service
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"github.com/coze-dev/coze-studio/backend/api/model/conversation/common"
|
||||
conventity "github.com/coze-dev/coze-studio/backend/domain/conversation/conversation/entity"
|
||||
|
||||
workflowModel "github.com/coze-dev/coze-studio/backend/api/model/crossdomain/workflow"
|
||||
"github.com/coze-dev/coze-studio/backend/pkg/taskgroup"
|
||||
|
||||
workflow2 "github.com/coze-dev/coze-studio/backend/api/model/workflow"
|
||||
crossconversation "github.com/coze-dev/coze-studio/backend/crossdomain/contract/conversation"
|
||||
"github.com/coze-dev/coze-studio/backend/domain/workflow"
|
||||
"github.com/coze-dev/coze-studio/backend/domain/workflow/entity"
|
||||
"github.com/coze-dev/coze-studio/backend/domain/workflow/entity/vo"
|
||||
"github.com/coze-dev/coze-studio/backend/pkg/errorx"
|
||||
"github.com/coze-dev/coze-studio/backend/pkg/lang/ptr"
|
||||
"github.com/coze-dev/coze-studio/backend/pkg/lang/slices"
|
||||
"github.com/coze-dev/coze-studio/backend/pkg/sonic"
|
||||
"github.com/coze-dev/coze-studio/backend/types/consts"
|
||||
"github.com/coze-dev/coze-studio/backend/types/errno"
|
||||
)
|
||||
|
||||
type conversationImpl struct {
|
||||
repo workflow.Repository
|
||||
}
|
||||
|
||||
func (c *conversationImpl) CreateDraftConversationTemplate(ctx context.Context, template *vo.CreateConversationTemplateMeta) (int64, error) {
|
||||
var (
|
||||
spaceID = template.SpaceID
|
||||
appID = template.AppID
|
||||
name = template.Name
|
||||
userID = template.UserID
|
||||
)
|
||||
|
||||
existed, err := c.IsDraftConversationNameExist(ctx, appID, userID, template.Name)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
if existed {
|
||||
return 0, vo.WrapError(errno.ErrConversationNameIsDuplicated, fmt.Errorf("conversation name %s exists", name), errorx.KV("name", name))
|
||||
}
|
||||
|
||||
return c.repo.CreateDraftConversationTemplate(ctx, &vo.CreateConversationTemplateMeta{
|
||||
SpaceID: spaceID,
|
||||
AppID: appID,
|
||||
Name: name,
|
||||
UserID: userID,
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
func (c *conversationImpl) IsDraftConversationNameExist(ctx context.Context, appID int64, userID int64, name string) (bool, error) {
|
||||
_, existed, err := c.repo.GetDynamicConversationByName(ctx, vo.Draft, appID, consts.CozeConnectorID, userID, name)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
if existed {
|
||||
return true, nil
|
||||
}
|
||||
|
||||
_, existed, err = c.repo.GetConversationTemplate(ctx, vo.Draft, vo.GetConversationTemplatePolicy{AppID: ptr.Of(appID), Name: ptr.Of(name)})
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
if existed {
|
||||
return true, nil
|
||||
}
|
||||
|
||||
return false, nil
|
||||
|
||||
}
|
||||
|
||||
func (c *conversationImpl) UpdateDraftConversationTemplateName(ctx context.Context, appID int64, userID int64, templateID int64, modifiedName string) error {
|
||||
template, existed, err := c.repo.GetConversationTemplate(ctx, vo.Draft, vo.GetConversationTemplatePolicy{TemplateID: ptr.Of(templateID)})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if existed && template.Name == modifiedName {
|
||||
return nil
|
||||
}
|
||||
|
||||
existed, err = c.IsDraftConversationNameExist(ctx, appID, userID, modifiedName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if existed {
|
||||
return vo.WrapError(errno.ErrConversationNameIsDuplicated, fmt.Errorf("conversation name %s exists", modifiedName), errorx.KV("name", modifiedName))
|
||||
}
|
||||
|
||||
wfs, err := c.findReplaceWorkflowByConversationName(ctx, appID, template.Name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = c.replaceWorkflowsConversationName(ctx, wfs, slices.ToMap(wfs, func(e *entity.Workflow) (int64, string) {
|
||||
return e.ID, modifiedName
|
||||
}))
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return c.repo.UpdateDraftConversationTemplateName(ctx, templateID, modifiedName)
|
||||
|
||||
}
|
||||
|
||||
func (c *conversationImpl) CheckWorkflowsToReplace(ctx context.Context, appID int64, templateID int64) ([]*entity.Workflow, error) {
|
||||
template, existed, err := c.repo.GetConversationTemplate(ctx, vo.Draft, vo.GetConversationTemplatePolicy{TemplateID: ptr.Of(templateID)})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if existed {
|
||||
return c.findReplaceWorkflowByConversationName(ctx, appID, template.Name)
|
||||
}
|
||||
|
||||
return []*entity.Workflow{}, nil
|
||||
}
|
||||
|
||||
func (c *conversationImpl) DeleteDraftConversationTemplate(ctx context.Context, templateID int64, wfID2ConversationName map[int64]string) (int64, error) {
|
||||
|
||||
if len(wfID2ConversationName) == 0 {
|
||||
return c.repo.DeleteDraftConversationTemplate(ctx, templateID)
|
||||
}
|
||||
workflowIDs := make([]int64, 0)
|
||||
for id := range wfID2ConversationName {
|
||||
workflowIDs = append(workflowIDs, id)
|
||||
}
|
||||
|
||||
wfs, _, err := c.repo.MGetDrafts(ctx, &vo.MGetPolicy{
|
||||
MetaQuery: vo.MetaQuery{
|
||||
IDs: workflowIDs,
|
||||
},
|
||||
QType: workflowModel.FromDraft,
|
||||
})
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
err = c.replaceWorkflowsConversationName(ctx, wfs, wfID2ConversationName)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return c.repo.DeleteDraftConversationTemplate(ctx, templateID)
|
||||
}
|
||||
|
||||
func (c *conversationImpl) ListConversationTemplate(ctx context.Context, env vo.Env, policy *vo.ListConversationTemplatePolicy) ([]*entity.ConversationTemplate, error) {
|
||||
var (
|
||||
err error
|
||||
templates []*entity.ConversationTemplate
|
||||
appID = policy.AppID
|
||||
)
|
||||
templates, err = c.repo.ListConversationTemplate(ctx, env, &vo.ListConversationTemplatePolicy{
|
||||
AppID: appID,
|
||||
Page: policy.Page,
|
||||
NameLike: policy.NameLike,
|
||||
Version: policy.Version,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return templates, nil
|
||||
|
||||
}
|
||||
|
||||
func (c *conversationImpl) MGetStaticConversation(ctx context.Context, env vo.Env, userID, connectorID int64, templateIDs []int64) ([]*entity.StaticConversation, error) {
|
||||
return c.repo.MGetStaticConversation(ctx, env, userID, connectorID, templateIDs)
|
||||
}
|
||||
|
||||
func (c *conversationImpl) ListDynamicConversation(ctx context.Context, env vo.Env, policy *vo.ListConversationPolicy) ([]*entity.DynamicConversation, error) {
|
||||
return c.repo.ListDynamicConversation(ctx, env, policy)
|
||||
}
|
||||
|
||||
func (c *conversationImpl) ReleaseConversationTemplate(ctx context.Context, appID int64, version string) error {
|
||||
templates, err := c.repo.ListConversationTemplate(ctx, vo.Draft, &vo.ListConversationTemplatePolicy{
|
||||
AppID: appID,
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if len(templates) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
return c.repo.BatchCreateOnlineConversationTemplate(ctx, templates, version)
|
||||
}
|
||||
|
||||
func (c *conversationImpl) InitApplicationDefaultConversationTemplate(ctx context.Context, spaceID, appID int64, userID int64) error {
|
||||
_, err := c.repo.CreateDraftConversationTemplate(ctx, &vo.CreateConversationTemplateMeta{
|
||||
AppID: appID,
|
||||
SpaceID: spaceID,
|
||||
UserID: userID,
|
||||
Name: "Default",
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *conversationImpl) findReplaceWorkflowByConversationName(ctx context.Context, appID int64, name string) ([]*entity.Workflow, error) {
|
||||
|
||||
wfs, _, err := c.repo.MGetDrafts(ctx, &vo.MGetPolicy{
|
||||
QType: workflowModel.FromDraft,
|
||||
MetaQuery: vo.MetaQuery{
|
||||
AppID: ptr.Of(appID),
|
||||
Mode: ptr.Of(workflow2.WorkflowMode_ChatFlow),
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
shouldReplacedWorkflow := func(nodes []*vo.Node) (bool, error) {
|
||||
var startNode *vo.Node
|
||||
for _, node := range nodes {
|
||||
if node.Type == entity.NodeTypeEntry.IDStr() {
|
||||
startNode = node
|
||||
}
|
||||
}
|
||||
if startNode == nil {
|
||||
return false, fmt.Errorf("start node not found for block type")
|
||||
}
|
||||
for _, vAny := range startNode.Data.Outputs {
|
||||
v, err := vo.ParseVariable(vAny)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
if v.Name == "CONVERSATION_NAME" && v.DefaultValue == name {
|
||||
return true, nil
|
||||
}
|
||||
}
|
||||
return false, nil
|
||||
|
||||
}
|
||||
|
||||
shouldReplacedWorkflows := make([]*entity.Workflow, 0)
|
||||
for idx := range wfs {
|
||||
wf := wfs[idx]
|
||||
canvas := &vo.Canvas{}
|
||||
err = sonic.UnmarshalString(wf.Canvas, canvas)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ok, err := shouldReplacedWorkflow(canvas.Nodes)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if ok {
|
||||
shouldReplacedWorkflows = append(shouldReplacedWorkflows, wf)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return shouldReplacedWorkflows, nil
|
||||
|
||||
}
|
||||
|
||||
func (c *conversationImpl) replaceWorkflowsConversationName(ctx context.Context, wfs []*entity.Workflow, workflowID2ConversionName map[int64]string) error {
|
||||
|
||||
replaceConversionName := func(nodes []*vo.Node, conversionName string) error {
|
||||
var startNode *vo.Node
|
||||
for _, node := range nodes {
|
||||
if node.Type == entity.NodeTypeEntry.IDStr() {
|
||||
startNode = node
|
||||
}
|
||||
}
|
||||
if startNode == nil {
|
||||
return fmt.Errorf("start node not found for block type")
|
||||
}
|
||||
for idx, vAny := range startNode.Data.Outputs {
|
||||
v, err := vo.ParseVariable(vAny)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if v.Name == "CONVERSATION_NAME" {
|
||||
v.DefaultValue = conversionName
|
||||
}
|
||||
startNode.Data.Outputs[idx] = v
|
||||
|
||||
}
|
||||
return nil
|
||||
}
|
||||
tg := taskgroup.NewTaskGroup(ctx, len(wfs))
|
||||
for _, wf := range wfs {
|
||||
wfEntity := wf
|
||||
tg.Go(func() error {
|
||||
canvas := &vo.Canvas{}
|
||||
err := sonic.UnmarshalString(wfEntity.Canvas, canvas)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
conversationName := workflowID2ConversionName[wfEntity.ID]
|
||||
err = replaceConversionName(canvas.Nodes, conversationName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
replaceCanvas, err := sonic.MarshalString(canvas)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = c.repo.CreateOrUpdateDraft(ctx, wfEntity.ID, &vo.DraftInfo{
|
||||
DraftMeta: &vo.DraftMeta{
|
||||
TestRunSuccess: false,
|
||||
Modified: true,
|
||||
},
|
||||
Canvas: replaceCanvas,
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
|
||||
})
|
||||
}
|
||||
err := tg.Wait()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *conversationImpl) DeleteDynamicConversation(ctx context.Context, env vo.Env, templateID int64) (int64, error) {
|
||||
return c.repo.DeleteDynamicConversation(ctx, env, templateID)
|
||||
}
|
||||
|
||||
func (c *conversationImpl) GetOrCreateConversation(ctx context.Context, env vo.Env, appID, connectorID, userID int64, conversationName string) (int64, int64, error) {
|
||||
t, existed, err := c.repo.GetConversationTemplate(ctx, env, vo.GetConversationTemplatePolicy{
|
||||
AppID: ptr.Of(appID),
|
||||
Name: ptr.Of(conversationName),
|
||||
})
|
||||
if err != nil {
|
||||
return 0, 0, err
|
||||
}
|
||||
|
||||
conversationIDGenerator := workflow.ConversationIDGenerator(func(ctx context.Context, appID int64, userID, connectorID int64) (*conventity.Conversation, error) {
|
||||
return crossconversation.DefaultSVC().CreateConversation(ctx, &conventity.CreateMeta{
|
||||
AgentID: appID,
|
||||
UserID: userID,
|
||||
ConnectorID: connectorID,
|
||||
Scene: common.Scene_SceneWorkflow,
|
||||
})
|
||||
})
|
||||
|
||||
if existed {
|
||||
conversationID, sectionID, _, err := c.repo.GetOrCreateStaticConversation(ctx, env, conversationIDGenerator, &vo.CreateStaticConversation{
|
||||
AppID: appID,
|
||||
ConnectorID: connectorID,
|
||||
UserID: userID,
|
||||
TemplateID: t.TemplateID,
|
||||
})
|
||||
if err != nil {
|
||||
return 0, 0, err
|
||||
}
|
||||
return conversationID, sectionID, nil
|
||||
}
|
||||
|
||||
conversationID, sectionID, _, err := c.repo.GetOrCreateDynamicConversation(ctx, env, conversationIDGenerator, &vo.CreateDynamicConversation{
|
||||
AppID: appID,
|
||||
ConnectorID: connectorID,
|
||||
UserID: userID,
|
||||
Name: conversationName,
|
||||
})
|
||||
if err != nil {
|
||||
return 0, 0, err
|
||||
}
|
||||
return conversationID, sectionID, nil
|
||||
|
||||
}
|
||||
|
||||
func (c *conversationImpl) UpdateConversation(ctx context.Context, env vo.Env, appID, connectorID, userID int64, conversationName string) (int64, error) {
|
||||
t, existed, err := c.repo.GetConversationTemplate(ctx, env, vo.GetConversationTemplatePolicy{
|
||||
AppID: ptr.Of(appID),
|
||||
Name: ptr.Of(conversationName),
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
if existed {
|
||||
conv, err := crossconversation.DefaultSVC().CreateConversation(ctx, &conventity.CreateMeta{
|
||||
AgentID: appID,
|
||||
UserID: userID,
|
||||
ConnectorID: connectorID,
|
||||
Scene: common.Scene_SceneWorkflow,
|
||||
})
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
if conv == nil {
|
||||
return 0, fmt.Errorf("create conversation failed")
|
||||
}
|
||||
err = c.repo.UpdateStaticConversation(ctx, env, t.TemplateID, connectorID, userID, conv.ID)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return conv.ID, nil
|
||||
}
|
||||
|
||||
dy, existed, err := c.repo.GetDynamicConversationByName(ctx, env, appID, connectorID, userID, conversationName)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
if !existed {
|
||||
return 0, fmt.Errorf("conversation name %v not found", conversationName)
|
||||
}
|
||||
|
||||
conv, err := crossconversation.DefaultSVC().CreateConversation(ctx, &conventity.CreateMeta{
|
||||
AgentID: appID,
|
||||
UserID: userID,
|
||||
ConnectorID: connectorID,
|
||||
Scene: common.Scene_SceneWorkflow,
|
||||
})
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
if conv == nil {
|
||||
return 0, fmt.Errorf("create conversation failed")
|
||||
}
|
||||
err = c.repo.UpdateDynamicConversation(ctx, env, dy.ConversationID, conv.ID)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return conv.ID, nil
|
||||
|
||||
}
|
||||
|
||||
func (c *conversationImpl) GetTemplateByName(ctx context.Context, env vo.Env, appID int64, templateName string) (*entity.ConversationTemplate, bool, error) {
|
||||
return c.repo.GetConversationTemplate(ctx, env, vo.GetConversationTemplatePolicy{
|
||||
AppID: ptr.Of(appID),
|
||||
Name: ptr.Of(templateName),
|
||||
})
|
||||
}
|
||||
|
||||
func (c *conversationImpl) GetDynamicConversationByName(ctx context.Context, env vo.Env, appID, connectorID, userID int64, name string) (*entity.DynamicConversation, bool, error) {
|
||||
return c.repo.GetDynamicConversationByName(ctx, env, appID, connectorID, userID, name)
|
||||
}
|
||||
|
||||
func (c *conversationImpl) GetConversationNameByID(ctx context.Context, env vo.Env, appID, connectorID, conversationID int64) (string, bool, error) {
|
||||
sc, existed, err := c.repo.GetStaticConversationByID(ctx, env, appID, connectorID, conversationID)
|
||||
if err != nil {
|
||||
return "", false, err
|
||||
}
|
||||
if existed {
|
||||
return sc, true, nil
|
||||
}
|
||||
|
||||
dc, existed, err := c.repo.GetDynamicConversationByID(ctx, env, appID, connectorID, conversationID)
|
||||
if err != nil {
|
||||
return "", false, err
|
||||
}
|
||||
|
||||
if existed {
|
||||
return dc.Name, true, nil
|
||||
}
|
||||
|
||||
return "", false, nil
|
||||
}
|
||||
|
||||
func (c *conversationImpl) Suggest(ctx context.Context, input *vo.SuggestInfo) ([]string, error) {
|
||||
return c.repo.Suggest(ctx, input)
|
||||
}
|
||||
@@ -26,6 +26,8 @@ import (
|
||||
"github.com/cloudwego/eino/schema"
|
||||
|
||||
workflowModel "github.com/coze-dev/coze-studio/backend/api/model/crossdomain/workflow"
|
||||
workflowapimodel "github.com/coze-dev/coze-studio/backend/api/model/workflow"
|
||||
crossmessage "github.com/coze-dev/coze-studio/backend/crossdomain/contract/message"
|
||||
"github.com/coze-dev/coze-studio/backend/domain/workflow"
|
||||
"github.com/coze-dev/coze-studio/backend/domain/workflow/entity"
|
||||
"github.com/coze-dev/coze-studio/backend/domain/workflow/entity/vo"
|
||||
@@ -62,6 +64,8 @@ func (i *impl) SyncExecute(ctx context.Context, config workflowModel.ExecuteConf
|
||||
return nil, "", err
|
||||
}
|
||||
|
||||
config.WorkflowMode = wfEntity.Mode
|
||||
|
||||
isApplicationWorkflow := wfEntity.AppID != nil
|
||||
if isApplicationWorkflow && config.Mode == workflowModel.ExecuteModeRelease {
|
||||
err = i.checkApplicationWorkflowReleaseVersion(ctx, *wfEntity.AppID, config.ConnectorID, config.ID, config.Version)
|
||||
@@ -207,6 +211,8 @@ func (i *impl) AsyncExecute(ctx context.Context, config workflowModel.ExecuteCon
|
||||
return 0, err
|
||||
}
|
||||
|
||||
config.WorkflowMode = wfEntity.Mode
|
||||
|
||||
isApplicationWorkflow := wfEntity.AppID != nil
|
||||
if isApplicationWorkflow && config.Mode == workflowModel.ExecuteModeRelease {
|
||||
err = i.checkApplicationWorkflowReleaseVersion(ctx, *wfEntity.AppID, config.ConnectorID, config.ID, config.Version)
|
||||
@@ -292,6 +298,8 @@ func (i *impl) AsyncExecuteNode(ctx context.Context, nodeID string, config workf
|
||||
return 0, err
|
||||
}
|
||||
|
||||
config.WorkflowMode = wfEntity.Mode
|
||||
|
||||
isApplicationWorkflow := wfEntity.AppID != nil
|
||||
if isApplicationWorkflow && config.Mode == workflowModel.ExecuteModeRelease {
|
||||
err = i.checkApplicationWorkflowReleaseVersion(ctx, *wfEntity.AppID, config.ConnectorID, config.ID, config.Version)
|
||||
@@ -300,6 +308,30 @@ func (i *impl) AsyncExecuteNode(ctx context.Context, nodeID string, config workf
|
||||
}
|
||||
}
|
||||
|
||||
historyRounds := int64(0)
|
||||
if config.WorkflowMode == workflowapimodel.WorkflowMode_ChatFlow {
|
||||
|
||||
historyRounds, err = getHistoryRoundsFromNode(ctx, wfEntity, nodeID, i.repo)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
}
|
||||
|
||||
if historyRounds > 0 {
|
||||
messages, scMessages, err := i.prefetchChatHistory(ctx, config, historyRounds)
|
||||
if err != nil {
|
||||
logs.CtxErrorf(ctx, "failed to prefetch chat history: %v", err)
|
||||
}
|
||||
|
||||
if len(messages) > 0 {
|
||||
config.ConversationHistory = messages
|
||||
}
|
||||
|
||||
if len(scMessages) > 0 {
|
||||
config.ConversationHistorySchemaMessages = scMessages
|
||||
}
|
||||
|
||||
}
|
||||
c := &vo.Canvas{}
|
||||
if err = sonic.UnmarshalString(wfEntity.Canvas, c); err != nil {
|
||||
return 0, fmt.Errorf("failed to unmarshal canvas: %w", err)
|
||||
@@ -375,6 +407,8 @@ func (i *impl) StreamExecute(ctx context.Context, config workflowModel.ExecuteCo
|
||||
return nil, err
|
||||
}
|
||||
|
||||
config.WorkflowMode = wfEntity.Mode
|
||||
|
||||
isApplicationWorkflow := wfEntity.AppID != nil
|
||||
if isApplicationWorkflow && config.Mode == workflowModel.ExecuteModeRelease {
|
||||
err = i.checkApplicationWorkflowReleaseVersion(ctx, *wfEntity.AppID, config.ConnectorID, config.ID, config.Version)
|
||||
@@ -383,6 +417,29 @@ func (i *impl) StreamExecute(ctx context.Context, config workflowModel.ExecuteCo
|
||||
}
|
||||
}
|
||||
|
||||
historyRounds := int64(0)
|
||||
if config.WorkflowMode == workflowapimodel.WorkflowMode_ChatFlow {
|
||||
historyRounds, err = i.calculateMaxChatHistoryRounds(ctx, wfEntity, i.repo)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
if historyRounds > 0 {
|
||||
messages, scMessages, err := i.prefetchChatHistory(ctx, config, historyRounds)
|
||||
if err != nil {
|
||||
logs.CtxErrorf(ctx, "failed to prefetch chat history: %v", err)
|
||||
}
|
||||
|
||||
if len(messages) > 0 {
|
||||
config.ConversationHistory = messages
|
||||
}
|
||||
|
||||
if len(scMessages) > 0 {
|
||||
config.ConversationHistorySchemaMessages = scMessages
|
||||
}
|
||||
|
||||
}
|
||||
c := &vo.Canvas{}
|
||||
if err = sonic.UnmarshalString(wfEntity.Canvas, c); err != nil {
|
||||
return nil, fmt.Errorf("failed to unmarshal canvas: %w", err)
|
||||
@@ -718,6 +775,7 @@ func (i *impl) AsyncResume(ctx context.Context, req *entity.ResumeRequest, confi
|
||||
config.AppID = wfExe.AppID
|
||||
config.AgentID = wfExe.AgentID
|
||||
config.CommitID = wfExe.CommitID
|
||||
config.WorkflowMode = wfEntity.Mode
|
||||
|
||||
if config.ConnectorID == 0 {
|
||||
config.ConnectorID = wfExe.ConnectorID
|
||||
@@ -859,6 +917,7 @@ func (i *impl) StreamResume(ctx context.Context, req *entity.ResumeRequest, conf
|
||||
config.AppID = wfExe.AppID
|
||||
config.AgentID = wfExe.AgentID
|
||||
config.CommitID = wfExe.CommitID
|
||||
config.WorkflowMode = wfEntity.Mode
|
||||
|
||||
if config.ConnectorID == 0 {
|
||||
config.ConnectorID = wfExe.ConnectorID
|
||||
@@ -937,3 +996,73 @@ func (i *impl) checkApplicationWorkflowReleaseVersion(ctx context.Context, appID
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
const maxHistoryRounds int64 = 30
|
||||
|
||||
func (i *impl) calculateMaxChatHistoryRounds(ctx context.Context, wfEntity *entity.Workflow, repo workflow.Repository) (int64, error) {
|
||||
if wfEntity == nil {
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
maxRounds, err := getMaxHistoryRoundsRecursively(ctx, wfEntity, repo)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return min(maxRounds, maxHistoryRounds), nil
|
||||
}
|
||||
|
||||
func (i *impl) prefetchChatHistory(ctx context.Context, config workflowModel.ExecuteConfig, historyRounds int64) ([]*crossmessage.WfMessage, []*schema.Message, error) {
|
||||
convID := config.ConversationID
|
||||
agentID := config.AgentID
|
||||
appID := config.AppID
|
||||
userID := config.Operator
|
||||
sectionID := config.SectionID
|
||||
if sectionID == nil {
|
||||
logs.CtxWarnf(ctx, "SectionID is nil, skipping chat history")
|
||||
return nil, nil, nil
|
||||
}
|
||||
|
||||
if convID == nil || *convID == 0 {
|
||||
logs.CtxWarnf(ctx, "ConversationID is 0 or nil, skipping chat history")
|
||||
return nil, nil, nil
|
||||
}
|
||||
|
||||
var resolvedAppID int64
|
||||
if appID != nil {
|
||||
resolvedAppID = *appID
|
||||
} else if agentID != nil {
|
||||
resolvedAppID = *agentID
|
||||
} else {
|
||||
logs.CtxWarnf(ctx, "AppID and AgentID are both nil, skipping chat history")
|
||||
return nil, nil, nil
|
||||
}
|
||||
|
||||
runIdsReq := &crossmessage.GetLatestRunIDsRequest{
|
||||
ConversationID: *convID,
|
||||
AppID: resolvedAppID,
|
||||
UserID: userID,
|
||||
Rounds: historyRounds + 1,
|
||||
SectionID: *sectionID,
|
||||
}
|
||||
|
||||
runIds, err := crossmessage.DefaultSVC().GetLatestRunIDs(ctx, runIdsReq)
|
||||
if err != nil {
|
||||
logs.CtxErrorf(ctx, "failed to get latest run ids: %v", err)
|
||||
return nil, nil, nil
|
||||
}
|
||||
if len(runIds) <= 1 {
|
||||
return []*crossmessage.WfMessage{}, []*schema.Message{}, nil
|
||||
}
|
||||
runIds = runIds[1:]
|
||||
|
||||
response, err := crossmessage.DefaultSVC().GetMessagesByRunIDs(ctx, &crossmessage.GetMessagesByRunIDsRequest{
|
||||
ConversationID: *convID,
|
||||
RunIDs: runIds,
|
||||
})
|
||||
if err != nil {
|
||||
logs.CtxErrorf(ctx, "failed to get messages by run ids: %v", err)
|
||||
return nil, nil, nil
|
||||
}
|
||||
|
||||
return response.Messages, response.SchemaMessages, nil
|
||||
}
|
||||
|
||||
@@ -20,13 +20,14 @@ import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"strconv"
|
||||
|
||||
"github.com/spf13/cast"
|
||||
"golang.org/x/exp/maps"
|
||||
"golang.org/x/sync/errgroup"
|
||||
"gorm.io/gorm"
|
||||
|
||||
"strconv"
|
||||
|
||||
einoCompose "github.com/cloudwego/eino/compose"
|
||||
"github.com/coze-dev/coze-studio/backend/api/model/crossdomain/plugin"
|
||||
workflowModel "github.com/coze-dev/coze-studio/backend/api/model/crossdomain/workflow"
|
||||
@@ -38,6 +39,7 @@ import (
|
||||
"github.com/coze-dev/coze-studio/backend/domain/workflow/internal/canvas/adaptor"
|
||||
"github.com/coze-dev/coze-studio/backend/domain/workflow/internal/canvas/convert"
|
||||
"github.com/coze-dev/coze-studio/backend/domain/workflow/internal/nodes/intentdetector"
|
||||
"github.com/coze-dev/coze-studio/backend/domain/workflow/internal/nodes/knowledge"
|
||||
"github.com/coze-dev/coze-studio/backend/domain/workflow/internal/nodes/llm"
|
||||
"github.com/coze-dev/coze-studio/backend/domain/workflow/internal/repo"
|
||||
"github.com/coze-dev/coze-studio/backend/domain/workflow/internal/schema"
|
||||
@@ -45,6 +47,7 @@ import (
|
||||
"github.com/coze-dev/coze-studio/backend/infra/contract/chatmodel"
|
||||
"github.com/coze-dev/coze-studio/backend/infra/contract/idgen"
|
||||
"github.com/coze-dev/coze-studio/backend/infra/contract/storage"
|
||||
"github.com/coze-dev/coze-studio/backend/pkg/errorx"
|
||||
"github.com/coze-dev/coze-studio/backend/pkg/lang/ptr"
|
||||
"github.com/coze-dev/coze-studio/backend/pkg/lang/slices"
|
||||
"github.com/coze-dev/coze-studio/backend/pkg/logs"
|
||||
@@ -56,6 +59,7 @@ type impl struct {
|
||||
repo workflow.Repository
|
||||
*asToolImpl
|
||||
*executableImpl
|
||||
*conversationImpl
|
||||
}
|
||||
|
||||
func NewWorkflowService(repo workflow.Repository) workflow.Service {
|
||||
@@ -67,12 +71,14 @@ func NewWorkflowService(repo workflow.Repository) workflow.Service {
|
||||
executableImpl: &executableImpl{
|
||||
repo: repo,
|
||||
},
|
||||
conversationImpl: &conversationImpl{repo: repo},
|
||||
}
|
||||
}
|
||||
|
||||
func NewWorkflowRepository(idgen idgen.IDGenerator, db *gorm.DB, redis cache.Cmdable, tos storage.Storage,
|
||||
cpStore einoCompose.CheckPointStore, chatModel chatmodel.BaseChatModel, workflowConfig workflow.WorkflowConfig) workflow.Repository {
|
||||
return repo.NewRepository(idgen, db, redis, tos, cpStore, chatModel, workflowConfig)
|
||||
cpStore einoCompose.CheckPointStore, chatModel chatmodel.BaseChatModel, cfg workflow.WorkflowConfig) (workflow.Repository, error) {
|
||||
return repo.NewRepository(idgen, db, redis, tos, cpStore, chatModel, cfg)
|
||||
|
||||
}
|
||||
|
||||
func (i *impl) ListNodeMeta(_ context.Context, nodeTypes map[entity.NodeType]bool) (map[string][]*entity.NodeTypeMeta, []entity.Category, error) {
|
||||
@@ -440,10 +446,13 @@ func (i *impl) collectNodePropertyMap(ctx context.Context, canvas *vo.Canvas) (m
|
||||
|
||||
var canvasSchema string
|
||||
if n.Data.Inputs.WorkflowVersion != "" {
|
||||
versionInfo, err := i.repo.GetVersion(ctx, wid, n.Data.Inputs.WorkflowVersion)
|
||||
versionInfo, existed, err := i.repo.GetVersion(ctx, wid, n.Data.Inputs.WorkflowVersion)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if !existed {
|
||||
return nil, vo.WrapError(errno.ErrWorkflowNotFound, fmt.Errorf("workflow version %s not found for ID %d: %w", n.Data.Inputs.WorkflowVersion, wid, err), errorx.KV("id", strconv.FormatInt(wid, 10)))
|
||||
}
|
||||
canvasSchema = versionInfo.Canvas
|
||||
} else {
|
||||
draftInfo, err := i.repo.DraftV2(ctx, wid, "")
|
||||
@@ -522,6 +531,9 @@ func isEnableChatHistory(s *schema.NodeSchema) bool {
|
||||
case entity.NodeTypeIntentDetector:
|
||||
llmParam := s.Configs.(*intentdetector.Config).LLMParams
|
||||
return llmParam.EnableChatHistory
|
||||
case entity.NodeTypeKnowledgeRetriever:
|
||||
chatParam := s.Configs.(*knowledge.RetrieveConfig).ChatHistorySetting
|
||||
return chatParam != nil && chatParam.EnableChatHistory
|
||||
default:
|
||||
return false
|
||||
}
|
||||
@@ -541,6 +553,103 @@ func isRefGlobalVariable(s *schema.NodeSchema) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (i *impl) CreateChatFlowRole(ctx context.Context, role *vo.ChatFlowRoleCreate) (int64, error) {
|
||||
id, err := i.repo.CreateChatFlowRoleConfig(ctx, &entity.ChatFlowRole{
|
||||
Name: role.Name,
|
||||
Description: role.Description,
|
||||
WorkflowID: role.WorkflowID,
|
||||
CreatorID: role.CreatorID,
|
||||
AudioConfig: role.AudioConfig,
|
||||
UserInputConfig: role.UserInputConfig,
|
||||
AvatarUri: role.AvatarUri,
|
||||
BackgroundImageInfo: role.BackgroundImageInfo,
|
||||
OnboardingInfo: role.OnboardingInfo,
|
||||
SuggestReplyInfo: role.SuggestReplyInfo,
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
return id, nil
|
||||
}
|
||||
|
||||
func (i *impl) UpdateChatFlowRole(ctx context.Context, workflowID int64, role *vo.ChatFlowRoleUpdate) error {
|
||||
err := i.repo.UpdateChatFlowRoleConfig(ctx, workflowID, role)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (i *impl) GetChatFlowRole(ctx context.Context, workflowID int64, version string) (*entity.ChatFlowRole, error) {
|
||||
role, err, isExist := i.repo.GetChatFlowRoleConfig(ctx, workflowID, version)
|
||||
if !isExist {
|
||||
logs.CtxWarnf(ctx, "chat flow role not exist, workflow id %v, version %v", workflowID, version)
|
||||
// Return (nil, nil) on 'NotExist' to align with the production behavior,
|
||||
// where the GET API may be called before the CREATE API during chatflow creation.
|
||||
return nil, nil
|
||||
}
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return role, nil
|
||||
}
|
||||
|
||||
func (i *impl) GetWorkflowVersionsByConnector(ctx context.Context, connectorID, workflowID int64, limit int) ([]string, error) {
|
||||
return i.repo.GetVersionListByConnectorAndWorkflowID(ctx, connectorID, workflowID, limit)
|
||||
}
|
||||
|
||||
func (i *impl) DeleteChatFlowRole(ctx context.Context, id int64, workflowID int64) error {
|
||||
return i.repo.DeleteChatFlowRoleConfig(ctx, id, workflowID)
|
||||
}
|
||||
|
||||
func (i *impl) PublishChatFlowRole(ctx context.Context, policy *vo.PublishRolePolicy) error {
|
||||
if policy.WorkflowID == 0 || policy.CreatorID == 0 || policy.Version == "" {
|
||||
logs.CtxErrorf(ctx, "invalid publish role policy, workflow id %v, creator id %v should not be zero, version %v should not be empty", policy.WorkflowID, policy.CreatorID, policy.Version)
|
||||
return vo.WrapError(errno.ErrInvalidParameter, fmt.Errorf("invalid publish role policy, workflow id %v, creator id %v should not be zero, version %v should not be empty", policy.WorkflowID, policy.CreatorID, policy.Version))
|
||||
}
|
||||
wf, err := i.repo.GetEntity(ctx, &vo.GetPolicy{
|
||||
ID: policy.WorkflowID,
|
||||
MetaOnly: true,
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if wf.Mode != cloudworkflow.WorkflowMode_ChatFlow {
|
||||
return vo.WrapError(errno.ErrChatFlowRoleOperationFail, fmt.Errorf("workflow id %v, mode %v is not a chatflow", policy.WorkflowID, wf.Mode))
|
||||
}
|
||||
role, err, isExist := i.repo.GetChatFlowRoleConfig(ctx, policy.WorkflowID, "")
|
||||
if !isExist {
|
||||
logs.CtxErrorf(ctx, "get draft chat flow role nil, workflow id %v", policy.WorkflowID)
|
||||
return vo.WrapError(errno.ErrChatFlowRoleOperationFail, fmt.Errorf("get draft chat flow role nil, workflow id %v", policy.WorkflowID))
|
||||
}
|
||||
if err != nil {
|
||||
return vo.WrapIfNeeded(errno.ErrChatFlowRoleOperationFail, err)
|
||||
}
|
||||
|
||||
_, err = i.repo.CreateChatFlowRoleConfig(ctx, &entity.ChatFlowRole{
|
||||
Name: role.Name,
|
||||
Description: role.Description,
|
||||
WorkflowID: policy.WorkflowID,
|
||||
CreatorID: policy.CreatorID,
|
||||
AudioConfig: role.AudioConfig,
|
||||
UserInputConfig: role.UserInputConfig,
|
||||
AvatarUri: role.AvatarUri,
|
||||
BackgroundImageInfo: role.BackgroundImageInfo,
|
||||
OnboardingInfo: role.OnboardingInfo,
|
||||
SuggestReplyInfo: role.SuggestReplyInfo,
|
||||
Version: policy.Version,
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func canvasToRefs(referringID int64, canvasStr string) (map[entity.WorkflowReferenceKey]struct{}, error) {
|
||||
var canvas vo.Canvas
|
||||
if err := sonic.UnmarshalString(canvasStr, &canvas); err != nil {
|
||||
@@ -659,6 +768,13 @@ func (i *impl) UpdateMeta(ctx context.Context, id int64, metaUpdate *vo.MetaUpda
|
||||
return err
|
||||
}
|
||||
|
||||
if metaUpdate.WorkflowMode != nil && *metaUpdate.WorkflowMode == cloudworkflow.WorkflowMode_ChatFlow {
|
||||
err = i.adaptToChatFlow(ctx, id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -667,6 +783,35 @@ func (i *impl) CopyWorkflow(ctx context.Context, workflowID int64, policy vo.Cop
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// chat flow should copy role config
|
||||
if wf.Mode == cloudworkflow.WorkflowMode_ChatFlow {
|
||||
role, err, isExist := i.repo.GetChatFlowRoleConfig(ctx, workflowID, "")
|
||||
if !isExist {
|
||||
logs.CtxErrorf(ctx, "get draft chat flow role nil, workflow id %v", workflowID)
|
||||
return nil, vo.WrapError(errno.ErrChatFlowRoleOperationFail, fmt.Errorf("get draft chat flow role nil, workflow id %v", workflowID))
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return nil, vo.WrapIfNeeded(errno.ErrChatFlowRoleOperationFail, err)
|
||||
}
|
||||
_, err = i.repo.CreateChatFlowRoleConfig(ctx, &entity.ChatFlowRole{
|
||||
Name: role.Name,
|
||||
Description: role.Description,
|
||||
WorkflowID: wf.ID,
|
||||
CreatorID: wf.CreatorID,
|
||||
AudioConfig: role.AudioConfig,
|
||||
UserInputConfig: role.UserInputConfig,
|
||||
AvatarUri: role.AvatarUri,
|
||||
BackgroundImageInfo: role.BackgroundImageInfo,
|
||||
OnboardingInfo: role.OnboardingInfo,
|
||||
SuggestReplyInfo: role.SuggestReplyInfo,
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return wf, nil
|
||||
|
||||
@@ -677,7 +822,7 @@ func (i *impl) ReleaseApplicationWorkflows(ctx context.Context, appID int64, con
|
||||
return nil, fmt.Errorf("connector ids is required")
|
||||
}
|
||||
|
||||
wfs, _, err := i.MGet(ctx, &vo.MGetPolicy{
|
||||
allWorkflowsInApp, _, err := i.MGet(ctx, &vo.MGetPolicy{
|
||||
MetaQuery: vo.MetaQuery{
|
||||
AppID: &appID,
|
||||
},
|
||||
@@ -688,14 +833,15 @@ func (i *impl) ReleaseApplicationWorkflows(ctx context.Context, appID int64, con
|
||||
}
|
||||
|
||||
relatedPlugins := make(map[int64]*plugin.PluginEntity, len(config.PluginIDs))
|
||||
relatedWorkflow := make(map[int64]entity.IDVersionPair, len(wfs))
|
||||
relatedWorkflow := make(map[int64]entity.IDVersionPair, len(allWorkflowsInApp))
|
||||
|
||||
for _, wf := range wfs {
|
||||
for _, wf := range allWorkflowsInApp {
|
||||
relatedWorkflow[wf.ID] = entity.IDVersionPair{
|
||||
ID: wf.ID,
|
||||
Version: config.Version,
|
||||
}
|
||||
}
|
||||
|
||||
for _, id := range config.PluginIDs {
|
||||
relatedPlugins[id] = &plugin.PluginEntity{
|
||||
PluginID: id,
|
||||
@@ -704,7 +850,22 @@ func (i *impl) ReleaseApplicationWorkflows(ctx context.Context, appID int64, con
|
||||
}
|
||||
|
||||
vIssues := make([]*vo.ValidateIssue, 0)
|
||||
for _, wf := range wfs {
|
||||
|
||||
willPublishWorkflows := make([]*entity.Workflow, 0)
|
||||
|
||||
if len(config.WorkflowIDs) == 0 {
|
||||
willPublishWorkflows = allWorkflowsInApp
|
||||
} else {
|
||||
willPublishWorkflows, _, err = i.MGet(ctx, &vo.MGetPolicy{
|
||||
MetaQuery: vo.MetaQuery{
|
||||
AppID: &appID,
|
||||
IDs: config.WorkflowIDs,
|
||||
},
|
||||
QType: workflowModel.FromDraft,
|
||||
})
|
||||
}
|
||||
|
||||
for _, wf := range willPublishWorkflows {
|
||||
issues, err := validateWorkflowTree(ctx, vo.ValidateTreeConfig{
|
||||
CanvasSchema: wf.Canvas,
|
||||
AppID: ptr.Of(appID),
|
||||
@@ -723,7 +884,7 @@ func (i *impl) ReleaseApplicationWorkflows(ctx context.Context, appID int64, con
|
||||
return vIssues, nil
|
||||
}
|
||||
|
||||
for _, wf := range wfs {
|
||||
for _, wf := range willPublishWorkflows {
|
||||
c := &vo.Canvas{}
|
||||
err := sonic.UnmarshalString(wf.Canvas, c)
|
||||
if err != nil {
|
||||
@@ -747,9 +908,8 @@ func (i *impl) ReleaseApplicationWorkflows(ctx context.Context, appID int64, con
|
||||
}
|
||||
|
||||
userID := ctxutil.MustGetUIDFromCtx(ctx)
|
||||
|
||||
workflowsToPublish := make(map[int64]*vo.VersionInfo)
|
||||
for _, wf := range wfs {
|
||||
for _, wf := range willPublishWorkflows {
|
||||
inputStr, err := sonic.MarshalString(wf.InputParams)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -774,8 +934,16 @@ func (i *impl) ReleaseApplicationWorkflows(ctx context.Context, appID int64, con
|
||||
}
|
||||
}
|
||||
|
||||
workflowIDs := make([]int64, 0, len(wfs))
|
||||
workflowIDs := make([]int64, 0, len(willPublishWorkflows))
|
||||
for id, vInfo := range workflowsToPublish {
|
||||
// if version existed skip
|
||||
_, existed, err := i.repo.GetVersion(ctx, id, config.Version)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if existed {
|
||||
continue
|
||||
}
|
||||
wfRefs, err := canvasToRefs(id, vInfo.Canvas)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -787,6 +955,24 @@ func (i *impl) ReleaseApplicationWorkflows(ctx context.Context, appID int64, con
|
||||
}
|
||||
}
|
||||
|
||||
err = i.ReleaseConversationTemplate(ctx, appID, config.Version)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, wf := range willPublishWorkflows {
|
||||
if wf.Mode == cloudworkflow.WorkflowMode_ChatFlow {
|
||||
err = i.PublishChatFlowRole(ctx, &vo.PublishRolePolicy{
|
||||
WorkflowID: wf.ID,
|
||||
CreatorID: wf.CreatorID,
|
||||
Version: config.Version,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for _, connectorID := range config.ConnectorIDs {
|
||||
err = i.repo.BatchCreateConnectorWorkflowVersion(ctx, appID, connectorID, workflowIDs, config.Version)
|
||||
if err != nil {
|
||||
@@ -889,7 +1075,7 @@ func (i *impl) CopyWorkflowFromAppToLibrary(ctx context.Context, workflowID int6
|
||||
}
|
||||
|
||||
if node.Type == entity.NodeTypeLLM.IDStr() {
|
||||
if node.Data.Inputs.FCParam != nil && node.Data.Inputs.FCParam.WorkflowFCParam != nil {
|
||||
if node.Data.Inputs.LLM != nil && node.Data.Inputs.FCParam != nil && node.Data.Inputs.FCParam.WorkflowFCParam != nil {
|
||||
for _, w := range node.Data.Inputs.FCParam.WorkflowFCParam.WorkflowList {
|
||||
var (
|
||||
v *vo.DraftInfo
|
||||
@@ -1012,7 +1198,7 @@ func (i *impl) CopyWorkflowFromAppToLibrary(ctx context.Context, workflowID int6
|
||||
return err
|
||||
}
|
||||
|
||||
cwf, err := i.repo.CopyWorkflow(ctx, wf.id, vo.CopyWorkflowPolicy{
|
||||
cwf, err := i.CopyWorkflow(ctx, wf.id, vo.CopyWorkflowPolicy{
|
||||
TargetAppID: ptr.Of(int64(0)),
|
||||
ModifiedCanvasSchema: ptr.Of(modifiedCanvasString),
|
||||
})
|
||||
@@ -1120,7 +1306,7 @@ func (i *impl) DuplicateWorkflowsByAppID(ctx context.Context, sourceAppID, targe
|
||||
|
||||
}
|
||||
if node.Type == entity.NodeTypeLLM.IDStr() {
|
||||
if node.Data.Inputs.FCParam != nil && node.Data.Inputs.FCParam.WorkflowFCParam != nil {
|
||||
if node.Data.Inputs.LLM != nil && node.Data.Inputs.FCParam != nil && node.Data.Inputs.FCParam.WorkflowFCParam != nil {
|
||||
for _, w := range node.Data.Inputs.FCParam.WorkflowFCParam.WorkflowList {
|
||||
var (
|
||||
v *vo.DraftInfo
|
||||
@@ -1246,6 +1432,11 @@ func (i *impl) DuplicateWorkflowsByAppID(ctx context.Context, sourceAppID, targe
|
||||
}
|
||||
}
|
||||
|
||||
err = i.repo.CopyTemplateConversationByAppID(ctx, sourceAppID, targetAppID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return copiedWorkflowArray, nil
|
||||
|
||||
}
|
||||
@@ -1368,7 +1559,7 @@ func (i *impl) GetWorkflowDependenceResource(ctx context.Context, workflowID int
|
||||
ds.DatabaseIDs = append(ds.DatabaseIDs, dsID)
|
||||
}
|
||||
case entity.NodeTypeLLM:
|
||||
if node.Data.Inputs.FCParam != nil && node.Data.Inputs.FCParam.PluginFCParam != nil {
|
||||
if node.Data.Inputs.LLM != nil && node.Data.Inputs.FCParam != nil && node.Data.Inputs.FCParam.PluginFCParam != nil {
|
||||
for idx := range node.Data.Inputs.FCParam.PluginFCParam.PluginList {
|
||||
if node.Data.Inputs.FCParam.PluginFCParam.PluginList[idx].IsDraft {
|
||||
pl := node.Data.Inputs.FCParam.PluginFCParam.PluginList[idx]
|
||||
@@ -1382,7 +1573,7 @@ func (i *impl) GetWorkflowDependenceResource(ctx context.Context, workflowID int
|
||||
|
||||
}
|
||||
}
|
||||
if node.Data.Inputs.FCParam != nil && node.Data.Inputs.FCParam.KnowledgeFCParam != nil {
|
||||
if node.Data.Inputs.LLM != nil && node.Data.Inputs.FCParam != nil && node.Data.Inputs.FCParam.KnowledgeFCParam != nil {
|
||||
for idx := range node.Data.Inputs.FCParam.KnowledgeFCParam.KnowledgeList {
|
||||
kn := node.Data.Inputs.FCParam.KnowledgeFCParam.KnowledgeList[idx]
|
||||
kid, err := strconv.ParseInt(kn.ID, 10, 64)
|
||||
@@ -1394,7 +1585,7 @@ func (i *impl) GetWorkflowDependenceResource(ctx context.Context, workflowID int
|
||||
}
|
||||
}
|
||||
|
||||
if node.Data.Inputs.FCParam != nil && node.Data.Inputs.FCParam.WorkflowFCParam != nil {
|
||||
if node.Data.Inputs.LLM != nil && node.Data.Inputs.FCParam != nil && node.Data.Inputs.FCParam.WorkflowFCParam != nil {
|
||||
for idx := range node.Data.Inputs.FCParam.WorkflowFCParam.WorkflowList {
|
||||
if node.Data.Inputs.FCParam.WorkflowFCParam.WorkflowList[idx].IsDraft {
|
||||
wID, err := strconv.ParseInt(node.Data.Inputs.FCParam.WorkflowFCParam.WorkflowList[idx].WorkflowID, 10, 64)
|
||||
@@ -1467,6 +1658,165 @@ func (i *impl) GetWorkflowDependenceResource(ctx context.Context, workflowID int
|
||||
|
||||
}
|
||||
|
||||
func (i *impl) checkBotAgentNode(node *vo.Node) error {
|
||||
if node.Type == entity.NodeTypeCreateConversation.IDStr() || node.Type == entity.NodeTypeConversationDelete.IDStr() || node.Type == entity.NodeTypeConversationUpdate.IDStr() || node.Type == entity.NodeTypeConversationList.IDStr() {
|
||||
return errors.New("conversation-related nodes are not supported in chatflow")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (i *impl) validateNodesRecursively(ctx context.Context, nodes []*vo.Node, checkType cloudworkflow.CheckType, visited map[string]struct{}, repo workflow.Repository) error {
|
||||
queue := make([]*vo.Node, 0, len(nodes))
|
||||
queue = append(queue, nodes...)
|
||||
|
||||
for len(queue) > 0 {
|
||||
node := queue[0]
|
||||
queue = queue[1:]
|
||||
|
||||
if node == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
var checkErr error
|
||||
switch checkType {
|
||||
case cloudworkflow.CheckType_BotAgent:
|
||||
checkErr = i.checkBotAgentNode(node)
|
||||
default:
|
||||
// For now, we only handle BotAgent check, so we can do nothing here.
|
||||
// In the future, if there are other check types that need to be validated on every node, this logic will need to be adjusted.
|
||||
}
|
||||
if checkErr != nil {
|
||||
return checkErr
|
||||
}
|
||||
|
||||
// Enqueue nested nodes for BFS traversal. This handles Loop, Batch, and other nodes with nested blocks.
|
||||
if len(node.Blocks) > 0 {
|
||||
queue = append(queue, node.Blocks...)
|
||||
}
|
||||
|
||||
if node.Type == entity.NodeTypeSubWorkflow.IDStr() && node.Data != nil && node.Data.Inputs != nil {
|
||||
workflowIDStr := node.Data.Inputs.WorkflowID
|
||||
if workflowIDStr == "" {
|
||||
continue
|
||||
}
|
||||
|
||||
workflowID, err := strconv.ParseInt(workflowIDStr, 10, 64)
|
||||
if err != nil {
|
||||
return fmt.Errorf("invalid workflow ID in sub-workflow node %s: %w", node.ID, err)
|
||||
}
|
||||
|
||||
version := node.Data.Inputs.WorkflowVersion
|
||||
qType := workflowModel.FromDraft
|
||||
if version != "" {
|
||||
qType = workflowModel.FromSpecificVersion
|
||||
}
|
||||
|
||||
visitedKey := fmt.Sprintf("%d:%s", workflowID, version)
|
||||
if _, ok := visited[visitedKey]; ok {
|
||||
continue
|
||||
}
|
||||
visited[visitedKey] = struct{}{}
|
||||
|
||||
subWfEntity, err := repo.GetEntity(ctx, &vo.GetPolicy{
|
||||
ID: workflowID,
|
||||
QType: qType,
|
||||
Version: version,
|
||||
})
|
||||
if err != nil {
|
||||
delete(visited, visitedKey)
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
continue
|
||||
}
|
||||
return fmt.Errorf("failed to get sub-workflow entity %d: %w", workflowID, err)
|
||||
}
|
||||
|
||||
var canvas vo.Canvas
|
||||
if err := sonic.UnmarshalString(subWfEntity.Canvas, &canvas); err != nil {
|
||||
return fmt.Errorf("failed to unmarshal canvas for workflow %d: %w", subWfEntity.ID, err)
|
||||
}
|
||||
|
||||
queue = append(queue, canvas.Nodes...)
|
||||
}
|
||||
|
||||
if node.Type == entity.NodeTypeLLM.IDStr() && node.Data != nil && node.Data.Inputs != nil && node.Data.Inputs.LLM != nil && node.Data.Inputs.FCParam != nil && node.Data.Inputs.FCParam.WorkflowFCParam != nil {
|
||||
for _, subWfInfo := range node.Data.Inputs.FCParam.WorkflowFCParam.WorkflowList {
|
||||
if subWfInfo.WorkflowID == "" {
|
||||
continue
|
||||
}
|
||||
workflowID, err := strconv.ParseInt(subWfInfo.WorkflowID, 10, 64)
|
||||
if err != nil {
|
||||
return fmt.Errorf("invalid workflow ID in large model node %s: %w", node.ID, err)
|
||||
}
|
||||
|
||||
version := subWfInfo.WorkflowVersion
|
||||
qType := workflowModel.FromDraft
|
||||
if version != "" {
|
||||
qType = workflowModel.FromSpecificVersion
|
||||
}
|
||||
|
||||
visitedKey := fmt.Sprintf("%d:%s", workflowID, version)
|
||||
if _, ok := visited[visitedKey]; ok {
|
||||
continue
|
||||
}
|
||||
visited[visitedKey] = struct{}{}
|
||||
|
||||
subWfEntity, err := repo.GetEntity(ctx, &vo.GetPolicy{
|
||||
ID: workflowID,
|
||||
QType: qType,
|
||||
Version: version,
|
||||
})
|
||||
if err != nil {
|
||||
delete(visited, visitedKey)
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
continue
|
||||
}
|
||||
return fmt.Errorf("failed to get sub-workflow entity %d from large model node: %w", workflowID, err)
|
||||
}
|
||||
|
||||
var canvas vo.Canvas
|
||||
if err := sonic.UnmarshalString(subWfEntity.Canvas, &canvas); err != nil {
|
||||
return fmt.Errorf("failed to unmarshal canvas for workflow %d from large model node: %w", subWfEntity.ID, err)
|
||||
}
|
||||
|
||||
queue = append(queue, canvas.Nodes...)
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (i *impl) WorkflowSchemaCheck(ctx context.Context, wf *entity.Workflow, checks []cloudworkflow.CheckType) ([]*cloudworkflow.CheckResult, error) {
|
||||
checkResults := make([]*cloudworkflow.CheckResult, 0, len(checks))
|
||||
|
||||
var canvas vo.Canvas
|
||||
if err := sonic.UnmarshalString(wf.Canvas, &canvas); err != nil {
|
||||
return nil, fmt.Errorf("failed to unmarshal canvas for workflow %d: %w", wf.ID, err)
|
||||
}
|
||||
|
||||
for _, checkType := range checks {
|
||||
visited := make(map[string]struct{})
|
||||
visitedKey := fmt.Sprintf("%d:%s", wf.ID, wf.GetVersion())
|
||||
visited[visitedKey] = struct{}{}
|
||||
|
||||
err := i.validateNodesRecursively(ctx, canvas.Nodes, checkType, visited, i.repo)
|
||||
|
||||
if err != nil {
|
||||
checkResults = append(checkResults, &cloudworkflow.CheckResult{
|
||||
IsPass: false,
|
||||
Reason: err.Error(),
|
||||
Type: checkType,
|
||||
})
|
||||
} else {
|
||||
checkResults = append(checkResults, &cloudworkflow.CheckResult{
|
||||
IsPass: true,
|
||||
Type: checkType,
|
||||
Reason: "",
|
||||
})
|
||||
}
|
||||
}
|
||||
return checkResults, nil
|
||||
}
|
||||
|
||||
func (i *impl) MGet(ctx context.Context, policy *vo.MGetPolicy) ([]*entity.Workflow, int64, error) {
|
||||
if policy.MetaOnly {
|
||||
metas, total, err := i.repo.MGetMetas(ctx, &policy.MetaQuery)
|
||||
@@ -1527,11 +1877,13 @@ func (i *impl) MGet(ctx context.Context, policy *vo.MGetPolicy) ([]*entity.Workf
|
||||
index := 0
|
||||
|
||||
for id, version := range policy.Versions {
|
||||
v, err := i.repo.GetVersion(ctx, id, version)
|
||||
v, existed, err := i.repo.GetVersion(ctx, id, version)
|
||||
if err != nil {
|
||||
return nil, total, err
|
||||
}
|
||||
|
||||
if !existed {
|
||||
return nil, total, vo.WrapError(errno.ErrWorkflowNotFound, fmt.Errorf("workflow version %s not found for ID %d: %w", version, id, err), errorx.KV("id", strconv.FormatInt(id, 10)))
|
||||
}
|
||||
inputs, outputs, err := ioF(v.InputParamsStr, v.OutputParamsStr)
|
||||
if err != nil {
|
||||
return nil, total, err
|
||||
@@ -1562,6 +1914,14 @@ func (i *impl) MGet(ctx context.Context, policy *vo.MGetPolicy) ([]*entity.Workf
|
||||
}
|
||||
}
|
||||
|
||||
func (i *impl) BindConvRelatedInfo(ctx context.Context, convID int64, info entity.ConvRelatedInfo) error {
|
||||
return i.repo.BindConvRelatedInfo(ctx, convID, info)
|
||||
}
|
||||
|
||||
func (i *impl) GetConvRelatedInfo(ctx context.Context, convID int64) (*entity.ConvRelatedInfo, bool, func() error, error) {
|
||||
return i.repo.GetConvRelatedInfo(ctx, convID)
|
||||
}
|
||||
|
||||
func (i *impl) calculateTestRunSuccess(ctx context.Context, c *vo.Canvas, wid int64) (bool, error) {
|
||||
sc, err := adaptor.CanvasToWorkflowSchema(ctx, c)
|
||||
if err != nil { // not even legal, test run can't possibly be successful
|
||||
@@ -1766,3 +2126,58 @@ func replaceRelatedWorkflowOrExternalResourceInWorkflowNodes(nodes []*vo.Node, r
|
||||
func RegisterAllNodeAdaptors() {
|
||||
adaptor.RegisterAllNodeAdaptors()
|
||||
}
|
||||
func (i *impl) adaptToChatFlow(ctx context.Context, wID int64) error {
|
||||
wfEntity, err := i.repo.GetEntity(ctx, &vo.GetPolicy{
|
||||
ID: wID,
|
||||
QType: workflowModel.FromDraft,
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
canvas := &vo.Canvas{}
|
||||
err = sonic.UnmarshalString(wfEntity.Canvas, canvas)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var startNode *vo.Node
|
||||
for _, node := range canvas.Nodes {
|
||||
if node.Type == entity.NodeTypeEntry.IDStr() {
|
||||
startNode = node
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if startNode == nil {
|
||||
return fmt.Errorf("can not find start node")
|
||||
}
|
||||
|
||||
vMap := make(map[string]bool)
|
||||
for _, o := range startNode.Data.Outputs {
|
||||
v, err := vo.ParseVariable(o)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
vMap[v.Name] = true
|
||||
}
|
||||
|
||||
if _, ok := vMap["USER_INPUT"]; !ok {
|
||||
startNode.Data.Outputs = append(startNode.Data.Outputs, &vo.Variable{
|
||||
Name: "USER_INPUT",
|
||||
Type: vo.VariableTypeString,
|
||||
})
|
||||
}
|
||||
if _, ok := vMap["CONVERSATION_NAME"]; !ok {
|
||||
startNode.Data.Outputs = append(startNode.Data.Outputs, &vo.Variable{
|
||||
Name: "CONVERSATION_NAME",
|
||||
Type: vo.VariableTypeString,
|
||||
DefaultValue: "Default",
|
||||
})
|
||||
}
|
||||
canvasStr, err := sonic.MarshalString(canvas)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return i.Save(ctx, wID, canvasStr)
|
||||
}
|
||||
|
||||
@@ -22,11 +22,15 @@ import (
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
cloudworkflow "github.com/coze-dev/coze-studio/backend/api/model/workflow"
|
||||
workflowModel "github.com/coze-dev/coze-studio/backend/api/model/crossdomain/workflow"
|
||||
"github.com/coze-dev/coze-studio/backend/api/model/workflow"
|
||||
wf "github.com/coze-dev/coze-studio/backend/domain/workflow"
|
||||
"github.com/coze-dev/coze-studio/backend/domain/workflow/entity"
|
||||
"github.com/coze-dev/coze-studio/backend/domain/workflow/entity/vo"
|
||||
"github.com/coze-dev/coze-studio/backend/domain/workflow/internal/canvas/adaptor"
|
||||
"github.com/coze-dev/coze-studio/backend/domain/workflow/internal/canvas/validate"
|
||||
"github.com/coze-dev/coze-studio/backend/domain/workflow/variable"
|
||||
"github.com/coze-dev/coze-studio/backend/pkg/lang/ternary"
|
||||
"github.com/coze-dev/coze-studio/backend/pkg/sonic"
|
||||
"github.com/coze-dev/coze-studio/backend/types/errno"
|
||||
)
|
||||
@@ -102,17 +106,17 @@ func validateWorkflowTree(ctx context.Context, config vo.ValidateTreeConfig) ([]
|
||||
return issues, nil
|
||||
}
|
||||
|
||||
func convertToValidationError(issue *validate.Issue) *cloudworkflow.ValidateErrorData {
|
||||
e := &cloudworkflow.ValidateErrorData{}
|
||||
func convertToValidationError(issue *validate.Issue) *workflow.ValidateErrorData {
|
||||
e := &workflow.ValidateErrorData{}
|
||||
e.Message = issue.Message
|
||||
if issue.NodeErr != nil {
|
||||
e.Type = cloudworkflow.ValidateErrorType_BotValidateNodeErr
|
||||
e.NodeError = &cloudworkflow.NodeError{
|
||||
e.Type = workflow.ValidateErrorType_BotValidateNodeErr
|
||||
e.NodeError = &workflow.NodeError{
|
||||
NodeID: issue.NodeErr.NodeID,
|
||||
}
|
||||
} else if issue.PathErr != nil {
|
||||
e.Type = cloudworkflow.ValidateErrorType_BotValidatePathErr
|
||||
e.PathError = &cloudworkflow.PathError{
|
||||
e.Type = workflow.ValidateErrorType_BotValidatePathErr
|
||||
e.PathError = &workflow.PathError{
|
||||
Start: issue.PathErr.StartNode,
|
||||
End: issue.PathErr.EndNode,
|
||||
}
|
||||
@@ -121,8 +125,8 @@ func convertToValidationError(issue *validate.Issue) *cloudworkflow.ValidateErro
|
||||
return e
|
||||
}
|
||||
|
||||
func toValidateErrorData(issues []*validate.Issue) []*cloudworkflow.ValidateErrorData {
|
||||
validateErrors := make([]*cloudworkflow.ValidateErrorData, 0, len(issues))
|
||||
func toValidateErrorData(issues []*validate.Issue) []*workflow.ValidateErrorData {
|
||||
validateErrors := make([]*workflow.ValidateErrorData, 0, len(issues))
|
||||
for _, issue := range issues {
|
||||
validateErrors = append(validateErrors, convertToValidationError(issue))
|
||||
}
|
||||
@@ -197,3 +201,214 @@ func isIncremental(prev version, next version) bool {
|
||||
|
||||
return next.Patch > prev.Patch
|
||||
}
|
||||
|
||||
func getMaxHistoryRoundsRecursively(ctx context.Context, wfEntity *entity.Workflow, repo wf.Repository) (int64, error) {
|
||||
visited := make(map[string]struct{})
|
||||
maxRounds := int64(0)
|
||||
err := getMaxHistoryRoundsRecursiveHelper(ctx, wfEntity, repo, visited, &maxRounds)
|
||||
return maxRounds, err
|
||||
}
|
||||
|
||||
func getMaxHistoryRoundsRecursiveHelper(ctx context.Context, wfEntity *entity.Workflow, repo wf.Repository, visited map[string]struct{}, maxRounds *int64) error {
|
||||
visitedKey := fmt.Sprintf("%d:%s", wfEntity.ID, wfEntity.GetVersion())
|
||||
if _, ok := visited[visitedKey]; ok {
|
||||
return nil
|
||||
}
|
||||
visited[visitedKey] = struct{}{}
|
||||
|
||||
var canvas vo.Canvas
|
||||
if err := sonic.UnmarshalString(wfEntity.Canvas, &canvas); err != nil {
|
||||
return fmt.Errorf("failed to unmarshal canvas for workflow %d: %w", wfEntity.ID, err)
|
||||
}
|
||||
|
||||
return collectMaxHistoryRounds(ctx, canvas.Nodes, repo, visited, maxRounds)
|
||||
}
|
||||
|
||||
func collectMaxHistoryRounds(ctx context.Context, nodes []*vo.Node, repo wf.Repository, visited map[string]struct{}, maxRounds *int64) error {
|
||||
for _, node := range nodes {
|
||||
if node == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
if node.Data != nil && node.Data.Inputs != nil && node.Data.Inputs.ChatHistorySetting != nil && node.Data.Inputs.ChatHistorySetting.EnableChatHistory {
|
||||
if node.Data.Inputs.ChatHistorySetting.ChatHistoryRound > *maxRounds {
|
||||
*maxRounds = node.Data.Inputs.ChatHistorySetting.ChatHistoryRound
|
||||
}
|
||||
} else if node.Type == entity.NodeTypeLLM.IDStr() && node.Data != nil && node.Data.Inputs != nil && node.Data.Inputs.LLMParam != nil {
|
||||
param := node.Data.Inputs.LLMParam
|
||||
bs, _ := sonic.Marshal(param)
|
||||
llmParam := make(vo.LLMParam, 0)
|
||||
if err := sonic.Unmarshal(bs, &llmParam); err != nil {
|
||||
return err
|
||||
}
|
||||
var chatHistoryEnabled bool
|
||||
var chatHistoryRound int64
|
||||
for _, param := range llmParam {
|
||||
switch param.Name {
|
||||
case "enableChatHistory":
|
||||
if val, ok := param.Input.Value.Content.(bool); ok {
|
||||
b := val
|
||||
chatHistoryEnabled = b
|
||||
}
|
||||
case "chatHistoryRound":
|
||||
if strVal, ok := param.Input.Value.Content.(string); ok {
|
||||
int64Val, err := strconv.ParseInt(strVal, 10, 64)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
chatHistoryRound = int64Val
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if chatHistoryEnabled {
|
||||
if chatHistoryRound > *maxRounds {
|
||||
*maxRounds = chatHistoryRound
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
isSubWorkflow := node.Type == entity.NodeTypeSubWorkflow.IDStr() && node.Data != nil && node.Data.Inputs != nil
|
||||
if isSubWorkflow {
|
||||
workflowIDStr := node.Data.Inputs.WorkflowID
|
||||
if workflowIDStr == "" {
|
||||
continue
|
||||
}
|
||||
|
||||
workflowID, err := strconv.ParseInt(workflowIDStr, 10, 64)
|
||||
if err != nil {
|
||||
return fmt.Errorf("invalid workflow ID in sub-workflow node %s: %w", node.ID, err)
|
||||
}
|
||||
|
||||
subWfEntity, err := repo.GetEntity(ctx, &vo.GetPolicy{
|
||||
ID: workflowID,
|
||||
QType: ternary.IFElse(len(node.Data.Inputs.WorkflowVersion) == 0, workflowModel.FromDraft, workflowModel.FromSpecificVersion),
|
||||
Version: node.Data.Inputs.WorkflowVersion,
|
||||
})
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get sub-workflow entity %d: %w", workflowID, err)
|
||||
}
|
||||
|
||||
if err := getMaxHistoryRoundsRecursiveHelper(ctx, subWfEntity, repo, visited, maxRounds); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if len(node.Blocks) > 0 {
|
||||
if err := collectMaxHistoryRounds(ctx, node.Blocks, repo, visited, maxRounds); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func getHistoryRoundsFromNode(ctx context.Context, wfEntity *entity.Workflow, nodeID string, repo wf.Repository) (int64, error) {
|
||||
if wfEntity == nil {
|
||||
return 0, nil
|
||||
}
|
||||
visited := make(map[string]struct{})
|
||||
visitedKey := fmt.Sprintf("%d:%s", wfEntity.ID, wfEntity.GetVersion())
|
||||
if _, ok := visited[visitedKey]; ok {
|
||||
return 0, nil
|
||||
}
|
||||
visited[visitedKey] = struct{}{}
|
||||
maxRounds := int64(0)
|
||||
c := &vo.Canvas{}
|
||||
if err := sonic.UnmarshalString(wfEntity.Canvas, c); err != nil {
|
||||
return 0, fmt.Errorf("failed to unmarshal canvas: %w", err)
|
||||
}
|
||||
var (
|
||||
n *vo.Node
|
||||
nodeFinder func(nodes []*vo.Node) *vo.Node
|
||||
)
|
||||
nodeFinder = func(nodes []*vo.Node) *vo.Node {
|
||||
for i := range nodes {
|
||||
if nodes[i].ID == nodeID {
|
||||
return nodes[i]
|
||||
}
|
||||
if len(nodes[i].Blocks) > 0 {
|
||||
if n := nodeFinder(nodes[i].Blocks); n != nil {
|
||||
return n
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
n = nodeFinder(c.Nodes)
|
||||
if n.Type == entity.NodeTypeLLM.IDStr() {
|
||||
if n.Data == nil || n.Data.Inputs == nil {
|
||||
return 0, nil
|
||||
}
|
||||
param := n.Data.Inputs.LLMParam
|
||||
bs, _ := sonic.Marshal(param)
|
||||
llmParam := make(vo.LLMParam, 0)
|
||||
if err := sonic.Unmarshal(bs, &llmParam); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
var chatHistoryEnabled bool
|
||||
var chatHistoryRound int64
|
||||
for _, param := range llmParam {
|
||||
switch param.Name {
|
||||
case "enableChatHistory":
|
||||
if val, ok := param.Input.Value.Content.(bool); ok {
|
||||
b := val
|
||||
chatHistoryEnabled = b
|
||||
}
|
||||
case "chatHistoryRound":
|
||||
if strVal, ok := param.Input.Value.Content.(string); ok {
|
||||
int64Val, err := strconv.ParseInt(strVal, 10, 64)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
chatHistoryRound = int64Val
|
||||
}
|
||||
}
|
||||
}
|
||||
if chatHistoryEnabled {
|
||||
return chatHistoryRound, nil
|
||||
}
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
if n.Type == entity.NodeTypeIntentDetector.IDStr() || n.Type == entity.NodeTypeKnowledgeRetriever.IDStr() {
|
||||
if n.Data != nil && n.Data.Inputs != nil && n.Data.Inputs.ChatHistorySetting != nil && n.Data.Inputs.ChatHistorySetting.EnableChatHistory {
|
||||
return n.Data.Inputs.ChatHistorySetting.ChatHistoryRound, nil
|
||||
}
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
if n.Type == entity.NodeTypeSubWorkflow.IDStr() {
|
||||
if n.Data != nil && n.Data.Inputs != nil {
|
||||
workflowIDStr := n.Data.Inputs.WorkflowID
|
||||
if workflowIDStr == "" {
|
||||
return 0, nil
|
||||
}
|
||||
workflowID, err := strconv.ParseInt(workflowIDStr, 10, 64)
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("invalid workflow ID in sub-workflow node %s: %w", n.ID, err)
|
||||
}
|
||||
subWfEntity, err := repo.GetEntity(ctx, &vo.GetPolicy{
|
||||
ID: workflowID,
|
||||
QType: ternary.IFElse(len(n.Data.Inputs.WorkflowVersion) == 0, workflowModel.FromDraft, workflowModel.FromSpecificVersion),
|
||||
Version: n.Data.Inputs.WorkflowVersion,
|
||||
})
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("failed to get sub-workflow entity %d: %w", workflowID, err)
|
||||
}
|
||||
if err := getMaxHistoryRoundsRecursiveHelper(ctx, subWfEntity, repo, visited, &maxRounds); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return maxRounds, nil
|
||||
}
|
||||
}
|
||||
|
||||
if len(n.Blocks) > 0 {
|
||||
if err := collectMaxHistoryRounds(ctx, n.Blocks, repo, visited, &maxRounds); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
}
|
||||
return maxRounds, nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user