feat: manually mirror opencoze's code from bytedance

Change-Id: I09a73aadda978ad9511264a756b2ce51f5761adf
This commit is contained in:
fanlv
2025-07-20 17:36:12 +08:00
commit 890153324f
14811 changed files with 1923430 additions and 0 deletions

View 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 entity
import (
"fmt"
"github.com/bytedance/sonic"
"github.com/cloudwego/eino/compose"
"github.com/coze-dev/coze-studio/backend/api/model/ocean/cloud/workflow"
"github.com/coze-dev/coze-studio/backend/domain/workflow/entity/vo"
)
type InterruptEvent struct {
ID int64 `json:"id"`
NodeKey vo.NodeKey `json:"node_key"`
InterruptData string `json:"interrupt_data,omitempty"`
NodeType NodeType `json:"node_type"`
NodeTitle string `json:"node_title,omitempty"`
NodeIcon string `json:"node_icon,omitempty"`
EventType InterruptEventType `json:"event_type"`
NodePath []string `json:"node_path,omitempty"`
// index within composite node -> interrupt info for that index
// TODO: separate the following fields with InterruptEvent
NestedInterruptInfo map[int]*compose.InterruptInfo `json:"nested_interrupt_info,omitempty"`
SubWorkflowInterruptInfo *compose.InterruptInfo `json:"sub_workflow_interrupt_info,omitempty"`
ToolInterruptEvent *ToolInterruptEvent `json:"tool_interrupt_event,omitempty"`
}
type InterruptEventType = workflow.EventType
const (
InterruptEventQuestion = workflow.EventType_Question
InterruptEventInput = workflow.EventType_InputNode
InterruptEventLLM = 100 // interrupt events emitted by LLM node, which are emitted by nodes within workflow tools
)
func (i *InterruptEvent) String() string {
s, _ := sonic.MarshalIndent(i, "", " ")
return string(s)
}
type ResumeRequest struct {
ExecuteID int64
EventID int64
ResumeData string
}
func (r *ResumeRequest) GetResumeID() string {
return fmt.Sprintf("%d_%d", r.ExecuteID, r.EventID)
}
type ToolInterruptEvent struct {
ToolCallID string
ToolName string
ExecuteID int64
*InterruptEvent
}

View File

@@ -0,0 +1,95 @@
/*
* 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 (
"github.com/cloudwego/eino/schema"
"github.com/coze-dev/coze-studio/backend/api/model/ocean/cloud/workflow"
"github.com/coze-dev/coze-studio/backend/domain/workflow/entity/vo"
)
type Message struct {
*StateMessage
*DataMessage
}
// StateMessage represents a status change for the workflow execution.
type StateMessage struct {
ExecuteID int64
EventID int64 // the resuming event ID for current execution
SpaceID int64
Status WorkflowExecuteStatus
Usage *TokenUsage
LastError vo.WorkflowError
InterruptEvent *InterruptEvent
}
// DataMessage represents a full or chunked message during a run that should go into message history.
type DataMessage struct {
ExecuteID int64 // the root execute ID for current execution
Role schema.RoleType
Type MessageType
Content string
NodeID string
NodeTitle string
NodeType NodeType
Last bool
Usage *TokenUsage
FunctionCall *FunctionCallInfo
ToolResponse *ToolResponseInfo
}
type MessageType string
const (
Answer MessageType = "answer"
FunctionCall MessageType = "function_call"
ToolResponse MessageType = "tool_response"
)
type FunctionInfo struct {
Name string `json:"name"`
Type ToolType `json:"plugin_type"`
PluginID int64 `json:"plugin_id,omitempty"`
PluginName string `json:"plugin_name,omitempty"`
APIID int64 `json:"api_id,omitempty"`
APIName string `json:"api_name,omitempty"`
WorkflowName string `json:"workflow_name,omitempty"`
WorkflowTerminatePlan vo.TerminatePlan `json:"terminate_plan,omitempty"`
}
type FunctionCallInfo struct {
FunctionInfo
CallID string `json:"-"`
Arguments string `json:"arguments"`
}
type ToolResponseInfo struct {
FunctionInfo
CallID string
Response string
}
type ToolType = workflow.PluginType
const (
PluginTool = workflow.PluginType_PLUGIN
WorkflowTool = workflow.PluginType_WORKFLOW
)

View File

@@ -0,0 +1,133 @@
/*
* 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 NodeType string
type NodeTypeMeta struct {
ID int64 `json:"id"`
Name string `json:"name"`
Type NodeType `json:"type"`
Category string `json:"category"`
Color string `json:"color"`
Desc string `json:"desc"`
IconURL string `json:"icon_url"`
SupportBatch bool `json:"support_batch"`
Disabled bool `json:"disabled,omitempty"`
EnUSName string `json:"en_us_name,omitempty"`
EnUSDescription string `json:"en_us_description,omitempty"`
ExecutableMeta
}
type Category struct {
Key string `json:"key"`
Name string `json:"name"`
EnUSName string `json:"en_us_name"`
}
type StreamingParadigm string
const (
Invoke StreamingParadigm = "invoke"
Stream StreamingParadigm = "stream"
Collect StreamingParadigm = "collect"
Transform StreamingParadigm = "transform"
)
type ExecutableMeta struct {
IsComposite bool `json:"is_composite,omitempty"`
DefaultTimeoutMS int64 `json:"default_timeout_ms,omitempty"` // default timeout in milliseconds, 0 means no timeout
PreFillZero bool `json:"pre_fill_zero,omitempty"`
PostFillNil bool `json:"post_fill_nil,omitempty"`
CallbackEnabled bool `json:"callback_enabled,omitempty"` // is false, Eino framework will inject callbacks for this node
MayUseChatModel bool `json:"may_use_chat_model,omitempty"`
InputSourceAware bool `json:"input_source_aware,omitempty"` // whether this node needs to know the runtime status of its input sources
StreamingParadigms map[StreamingParadigm]bool `json:"streaming_paradigms,omitempty"`
StreamSourceEOFAware bool `json:"needs_stream_source_eof,omitempty"` // whether this node needs to be aware stream sources' SourceEOF error
/*
IncrementalOutput indicates that the node's output is intended for progressive, user-facing streaming.
This distinguishes nodes that actually stream text to the user (e.g., 'Exit', 'Output')
from those that are merely capable of streaming internally (defined by StreamingParadigms),
whose output is consumed by other nodes.
In essence, nodes with IncrementalOutput are a subset of those defined in StreamingParadigms.
When set to true, stream chunks from the node are persisted in real-time and can be fetched by get_process.
*/
IncrementalOutput bool `json:"incremental_output,omitempty"`
}
type PluginNodeMeta struct {
PluginID int64 `json:"plugin_id"`
NodeType NodeType `json:"node_type"`
Category string `json:"category"`
ApiID int64 `json:"api_id"`
ApiName string `json:"api_name"`
Name string `json:"name"`
Desc string `json:"desc"`
IconURL string `json:"icon_url"`
}
type PluginCategoryMeta struct {
PluginCategoryMeta int64 `json:"plugin_category_meta"`
NodeType NodeType `json:"node_type"`
Category string `json:"category"`
Name string `json:"name"`
OnlyOfficial bool `json:"only_official"`
IconURL string `json:"icon_url"`
}
const (
NodeTypeVariableAggregator NodeType = "VariableAggregator"
NodeTypeIntentDetector NodeType = "IntentDetector"
NodeTypeTextProcessor NodeType = "TextProcessor"
NodeTypeHTTPRequester NodeType = "HTTPRequester"
NodeTypeLoop NodeType = "Loop"
NodeTypeContinue NodeType = "Continue"
NodeTypeBreak NodeType = "Break"
NodeTypeVariableAssigner NodeType = "VariableAssigner"
NodeTypeVariableAssignerWithinLoop NodeType = "VariableAssignerWithinLoop"
NodeTypeQuestionAnswer NodeType = "QuestionAnswer"
NodeTypeInputReceiver NodeType = "InputReceiver"
NodeTypeOutputEmitter NodeType = "OutputEmitter"
NodeTypeDatabaseCustomSQL NodeType = "DatabaseCustomSQL"
NodeTypeDatabaseQuery NodeType = "DatabaseQuery"
NodeTypeDatabaseInsert NodeType = "DatabaseInsert"
NodeTypeDatabaseDelete NodeType = "DatabaseDelete"
NodeTypeDatabaseUpdate NodeType = "DatabaseUpdate"
NodeTypeKnowledgeIndexer NodeType = "KnowledgeIndexer"
NodeTypeKnowledgeRetriever NodeType = "KnowledgeRetriever"
NodeTypeKnowledgeDeleter NodeType = "KnowledgeDeleter"
NodeTypeEntry NodeType = "Entry"
NodeTypeExit NodeType = "Exit"
NodeTypeCodeRunner NodeType = "CodeRunner"
NodeTypePlugin NodeType = "Plugin"
NodeTypeCreateConversation NodeType = "CreateConversation"
NodeTypeMessageList NodeType = "MessageList"
NodeTypeClearMessage NodeType = "ClearMessage"
NodeTypeLambda NodeType = "Lambda"
NodeTypeLLM NodeType = "LLM"
NodeTypeSelector NodeType = "Selector"
NodeTypeBatch NodeType = "Batch"
NodeTypeSubWorkflow NodeType = "SubWorkflow"
NodeTypeJsonSerialization NodeType = "JsonSerialization"
NodeTypeJsonDeserialization NodeType = "JsonDeserialization"
)
const (
EntryNodeKey = "100001"
ExitNodeKey = "900001"
)

View File

@@ -0,0 +1,867 @@
/*
* 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 (
"github.com/coze-dev/coze-studio/backend/pkg/i18n"
"github.com/coze-dev/coze-studio/backend/pkg/lang/ternary"
)
var Categories = []Category{
{
Key: "", // this is the default category. some of the most important nodes belong here, such as LLM, plugin, sub-workflow
Name: "",
EnUSName: "",
},
{
Key: "logic",
Name: "业务逻辑",
EnUSName: "Logic",
},
{
Key: "input&output",
Name: "输入&输出",
EnUSName: "Input&Output",
},
{
Key: "database",
Name: "数据库",
EnUSName: "Database",
},
{
Key: "data",
Name: "知识库&数据",
EnUSName: "Data",
},
{
Key: "image",
Name: "图像处理",
EnUSName: "Image",
},
{
Key: "audio&video",
Name: "音视频处理",
EnUSName: "Audio&Video",
},
{
Key: "utilities",
Name: "组件",
EnUSName: "Utilities",
},
{
Key: "conversation_management",
Name: "会话管理",
EnUSName: "Conversation management",
},
{
Key: "conversation_history",
Name: "会话历史",
EnUSName: "Conversation history",
},
{
Key: "message",
Name: "消息",
EnUSName: "Message",
},
}
// NodeTypeMetas holds the metadata for all available node types.
// It is initialized with built-in types and potentially extended by loading from external sources.
var NodeTypeMetas = []*NodeTypeMeta{
{
ID: 1,
Name: "开始",
Type: NodeTypeEntry,
Category: "input&output", // Mapped from cate_list
Desc: "工作流的起始节点,用于设定启动工作流需要的信息",
Color: "#5C62FF",
IconURL: "https://lf3-static.bytednsdoc.com/obj/eden-cn/dvsmryvd_avi_dvsm/ljhwZthlaukjlkulzlp/icon/icon-Start-v2.jpg",
SupportBatch: false, // supportBatch: 1
ExecutableMeta: ExecutableMeta{
PostFillNil: true,
StreamingParadigms: map[StreamingParadigm]bool{Invoke: true},
},
EnUSName: "Start",
EnUSDescription: "The starting node of the workflow, used to set the information needed to initiate the workflow.",
},
{
ID: 2,
Name: "结束",
Type: NodeTypeExit,
Category: "input&output", // Mapped from cate_list
Desc: "工作流的最终节点,用于返回工作流运行后的结果信息",
Color: "#5C62FF",
IconURL: "https://lf3-static.bytednsdoc.com/obj/eden-cn/dvsmryvd_avi_dvsm/ljhwZthlaukjlkulzlp/icon/icon-End-v2.jpg",
SupportBatch: false, // supportBatch: 1
ExecutableMeta: ExecutableMeta{
PreFillZero: true,
CallbackEnabled: true,
InputSourceAware: true,
StreamingParadigms: map[StreamingParadigm]bool{Invoke: true, Transform: true},
StreamSourceEOFAware: true,
IncrementalOutput: true,
},
EnUSName: "End",
EnUSDescription: "The final node of the workflow, used to return the result information after the workflow runs.",
},
{
ID: 3,
Name: "大模型",
Type: NodeTypeLLM,
Category: "", // Mapped from cate_list
Desc: "调用大语言模型,使用变量和提示词生成回复",
Color: "#5C62FF",
IconURL: "https://lf3-static.bytednsdoc.com/obj/eden-cn/dvsmryvd_avi_dvsm/ljhwZthlaukjlkulzlp/icon/icon-LLM-v2.jpg",
SupportBatch: true, // supportBatch: 2
ExecutableMeta: ExecutableMeta{
DefaultTimeoutMS: 3 * 60 * 1000, // 3 minutes
PreFillZero: true,
PostFillNil: true,
CallbackEnabled: true,
InputSourceAware: true,
MayUseChatModel: true,
StreamingParadigms: map[StreamingParadigm]bool{Invoke: true, Stream: true},
},
EnUSName: "LLM",
EnUSDescription: "Invoke the large language model, generate responses using variables and prompt words.",
},
{
ID: 4,
Name: "插件",
Type: NodeTypePlugin,
Category: "", // Mapped from cate_list
Desc: "通过添加工具访问实时数据和执行外部操作",
Color: "#CA61FF",
IconURL: "https://lf3-static.bytednsdoc.com/obj/eden-cn/dvsmryvd_avi_dvsm/ljhwZthlaukjlkulzlp/icon/icon-Plugin-v2.jpg",
SupportBatch: true, // supportBatch: 2
ExecutableMeta: ExecutableMeta{
DefaultTimeoutMS: 3 * 60 * 1000, // 3 minutes
PreFillZero: true,
PostFillNil: true,
StreamingParadigms: map[StreamingParadigm]bool{Invoke: true},
},
EnUSName: "Plugin",
EnUSDescription: "Used to access external real-time data and perform operations",
},
{
ID: 5,
Name: "代码",
Type: NodeTypeCodeRunner,
Category: "logic", // Mapped from cate_list
Desc: "编写代码,处理输入变量来生成返回值",
Color: "#00B2B2",
IconURL: "https://lf3-static.bytednsdoc.com/obj/eden-cn/dvsmryvd_avi_dvsm/ljhwZthlaukjlkulzlp/icon/icon-Code-v2.jpg",
SupportBatch: false, // supportBatch: 1
ExecutableMeta: ExecutableMeta{
DefaultTimeoutMS: 60 * 1000, // 1 minute
PreFillZero: true,
PostFillNil: true,
CallbackEnabled: true,
StreamingParadigms: map[StreamingParadigm]bool{Invoke: true},
},
EnUSName: "Code",
EnUSDescription: "Write code to process input variables to generate return values.",
},
{
ID: 6,
Name: "知识库检索",
Type: NodeTypeKnowledgeRetriever,
Category: "data", // Mapped from cate_list
Desc: "在选定的知识中,根据输入变量召回最匹配的信息,并以列表形式返回",
Color: "#FF811A",
IconURL: "https://lf3-static.bytednsdoc.com/obj/eden-cn/dvsmryvd_avi_dvsm/ljhwZthlaukjlkulzlp/icon/icon-KnowledgeQuery-v2.jpg",
SupportBatch: false, // supportBatch: 1
ExecutableMeta: ExecutableMeta{
DefaultTimeoutMS: 60 * 1000, // 1 minute
PreFillZero: true,
PostFillNil: true,
StreamingParadigms: map[StreamingParadigm]bool{Invoke: 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.",
},
{
ID: 8,
Name: "选择器",
Type: NodeTypeSelector,
Category: "logic", // Mapped from cate_list
Desc: "连接多个下游分支,若设定的条件成立则仅运行对应的分支,若均不成立则只运行“否则”分支",
Color: "#00B2B2",
IconURL: "https://lf3-static.bytednsdoc.com/obj/eden-cn/dvsmryvd_avi_dvsm/ljhwZthlaukjlkulzlp/icon/icon-Condition-v2.jpg",
SupportBatch: false, // supportBatch: 1
ExecutableMeta: ExecutableMeta{
CallbackEnabled: true,
StreamingParadigms: map[StreamingParadigm]bool{Invoke: true},
},
EnUSName: "Condition",
EnUSDescription: "Connect multiple downstream branches. Only the corresponding branch will be executed if the set conditions are met. If none are met, only the 'else' branch will be executed.",
},
{
ID: 9,
Name: "工作流",
Type: NodeTypeSubWorkflow,
Category: "", // Mapped from cate_list
Desc: "集成已发布工作流,可以执行嵌套子任务",
Color: "#00B83E",
IconURL: "https://lf3-static.bytednsdoc.com/obj/eden-cn/dvsmryvd_avi_dvsm/ljhwZthlaukjlkulzlp/icon/icon-Workflow-v2.jpg",
SupportBatch: true, // supportBatch: 2
ExecutableMeta: ExecutableMeta{
CallbackEnabled: true,
StreamingParadigms: map[StreamingParadigm]bool{Invoke: true},
},
EnUSName: "Workflow",
EnUSDescription: "Add published workflows to execute subtasks",
},
{
ID: 12,
Name: "SQL自定义",
Type: NodeTypeDatabaseCustomSQL,
Category: "database", // Mapped from cate_list
Desc: "基于用户自定义的 SQL 完成对数据库的增删改查操作",
Color: "#FF811A",
IconURL: "https://lf3-static.bytednsdoc.com/obj/eden-cn/dvsmryvd_avi_dvsm/ljhwZthlaukjlkulzlp/icon/icon-Database-v2.jpg",
SupportBatch: false, // supportBatch: 2
ExecutableMeta: ExecutableMeta{
DefaultTimeoutMS: 60 * 1000, // 1 minute
PreFillZero: true,
PostFillNil: true,
StreamingParadigms: map[StreamingParadigm]bool{Invoke: true},
},
EnUSName: "SQL Customization",
EnUSDescription: "Complete the operations of adding, deleting, modifying and querying the database based on user-defined SQL",
},
{
ID: 13,
Name: "输出",
Type: NodeTypeOutputEmitter,
Category: "input&output", // Mapped from cate_list
Desc: "节点从“消息”更名为“输出”,支持中间过程的消息输出,支持流式和非流式两种方式",
Color: "#5C62FF",
IconURL: "https://lf3-static.bytednsdoc.com/obj/eden-cn/dvsmryvd_avi_dvsm/ljhwZthlaukjlkulzlp/icon/icon-Output-v2.jpg",
SupportBatch: false,
ExecutableMeta: ExecutableMeta{
PreFillZero: true,
CallbackEnabled: true,
InputSourceAware: true,
StreamingParadigms: map[StreamingParadigm]bool{Invoke: true, Stream: true},
StreamSourceEOFAware: true,
IncrementalOutput: true,
},
EnUSName: "Output",
EnUSDescription: "The node is renamed from \"message\" to \"output\", Supports message output in the intermediate process and streaming and non-streaming methods",
},
{
ID: 15,
Name: "文本处理",
Type: NodeTypeTextProcessor,
Category: "utilities", // Mapped from cate_list
Desc: "用于处理多个字符串类型变量的格式",
Color: "#3071F2",
IconURL: "https://lf3-static.bytednsdoc.com/obj/eden-cn/dvsmryvd_avi_dvsm/ljhwZthlaukjlkulzlp/icon/icon-StrConcat-v2.jpg",
SupportBatch: false, // supportBatch: 2
ExecutableMeta: ExecutableMeta{
PreFillZero: true,
CallbackEnabled: true,
InputSourceAware: true,
StreamingParadigms: map[StreamingParadigm]bool{Invoke: true},
},
EnUSName: "Text Processing",
EnUSDescription: "The format used for handling multiple string-type variables.",
},
{
ID: 18,
Name: "问答",
Type: NodeTypeQuestionAnswer,
Category: "utilities", // Mapped from cate_list
Desc: "支持中间向用户提问问题,支持预置选项提问和开放式问题提问两种方式",
Color: "#3071F2",
IconURL: "https://lf3-static.bytednsdoc.com/obj/eden-cn/dvsmryvd_avi_dvsm/ljhwZthlaukjlkulzlp/icon/icon-Direct-Question-v2.jpg",
SupportBatch: false, // supportBatch: 1
ExecutableMeta: ExecutableMeta{
DefaultTimeoutMS: 60 * 1000, // 1 minute
PreFillZero: true,
PostFillNil: true,
CallbackEnabled: true,
MayUseChatModel: true,
StreamingParadigms: map[StreamingParadigm]bool{Invoke: true},
},
EnUSName: "Question",
EnUSDescription: "Support asking questions to the user in the middle of the conversation, with both preset options and open-ended questions",
},
{
ID: 19,
Name: "终止循环",
Type: NodeTypeBreak,
Category: "logic", // Mapped from cate_list
Desc: "用于立即终止当前所在的循环,跳出循环体",
Color: "#00B2B2",
IconURL: "https://lf3-static.bytednsdoc.com/obj/eden-cn/dvsmryvd_avi_dvsm/ljhwZthlaukjlkulzlp/icon/icon-Break-v2.jpg",
SupportBatch: false, // supportBatch: 1
ExecutableMeta: ExecutableMeta{
StreamingParadigms: map[StreamingParadigm]bool{Invoke: true},
},
EnUSName: "Break",
EnUSDescription: "Used to immediately terminate the current loop and jump out of the loop",
},
{
ID: 20,
Name: "设置变量",
Type: NodeTypeVariableAssignerWithinLoop,
Category: "logic", // Mapped from cate_list
Desc: "用于重置循环变量的值,使其下次循环使用重置后的值",
Color: "#00B2B2",
IconURL: "https://lf3-static.bytednsdoc.com/obj/eden-cn/dvsmryvd_avi_dvsm/ljhwZthlaukjlkulzlp/icon/icon-LoopSetVariable-v2.jpg",
SupportBatch: false, // supportBatch: 1
ExecutableMeta: ExecutableMeta{
StreamingParadigms: map[StreamingParadigm]bool{Invoke: true},
},
EnUSName: "Set Variable",
EnUSDescription: "Used to reset the value of the loop variable so that it uses the reset value in the next iteration",
},
{
ID: 21,
Name: "循环",
Type: NodeTypeLoop,
Category: "logic", // Mapped from cate_list
Desc: "用于通过设定循环次数和逻辑,重复执行一系列任务",
Color: "#00B2B2",
IconURL: "https://lf3-static.bytednsdoc.com/obj/eden-cn/dvsmryvd_avi_dvsm/ljhwZthlaukjlkulzlp/icon/icon-Loop-v2.jpg",
SupportBatch: false,
ExecutableMeta: ExecutableMeta{
IsComposite: true,
DefaultTimeoutMS: 60 * 1000, // 1 minute
PreFillZero: true,
PostFillNil: true,
CallbackEnabled: true,
StreamingParadigms: map[StreamingParadigm]bool{Invoke: true},
},
EnUSName: "Loop",
EnUSDescription: "Used to repeatedly execute a series of tasks by setting the number of iterations and logic",
},
{
ID: 22,
Name: "意图识别",
Type: NodeTypeIntentDetector,
Category: "logic", // Mapped from cate_list
Desc: "用于用户输入的意图识别,并将其与预设意图选项进行匹配。",
Color: "#00B2B2",
IconURL: "https://lf3-static.bytednsdoc.com/obj/eden-cn/dvsmryvd_avi_dvsm/ljhwZthlaukjlkulzlp/icon/icon-Intent-v2.jpg",
SupportBatch: false, // supportBatch: 1
ExecutableMeta: ExecutableMeta{
DefaultTimeoutMS: 60 * 1000, // 1 minute
PreFillZero: true,
PostFillNil: true,
CallbackEnabled: true,
MayUseChatModel: true,
StreamingParadigms: map[StreamingParadigm]bool{Invoke: true},
},
EnUSName: "Intent recognition",
EnUSDescription: "Used for recognizing the intent in user input and matching it with preset intent options.",
},
{
ID: 27,
Name: "知识库写入",
Type: NodeTypeKnowledgeIndexer,
Category: "data", // Mapped from cate_list
Desc: "写入节点可以添加 文本类型 的知识库,仅可以添加一个知识库",
Color: "#FF811A",
IconURL: "https://lf3-static.bytednsdoc.com/obj/eden-cn/dvsmryvd_avi_dvsm/ljhwZthlaukjlkulzlp/icon/icon-KnowledgeWriting-v2.jpg",
SupportBatch: false, // supportBatch: 1
ExecutableMeta: ExecutableMeta{
DefaultTimeoutMS: 60 * 1000, // 1 minute
PreFillZero: true,
PostFillNil: true,
StreamingParadigms: map[StreamingParadigm]bool{Invoke: true},
},
EnUSName: "Knowledge writing",
EnUSDescription: "The write node can add a knowledge base of type text. Only one knowledge base can be added.",
},
{
ID: 28,
Name: "批处理",
Type: NodeTypeBatch,
Category: "logic", // Mapped from cate_list
Desc: "通过设定批量运行次数和逻辑,运行批处理体内的任务",
Color: "#00B2B2",
IconURL: "https://lf3-static.bytednsdoc.com/obj/eden-cn/dvsmryvd_avi_dvsm/ljhwZthlaukjlkulzlp/icon/icon-Batch-v2.jpg",
SupportBatch: false, // supportBatch: 1 (Corrected from previous assumption)
ExecutableMeta: ExecutableMeta{
IsComposite: true,
DefaultTimeoutMS: 60 * 1000, // 1 minute
PreFillZero: true,
PostFillNil: true,
CallbackEnabled: true,
StreamingParadigms: map[StreamingParadigm]bool{Invoke: true},
},
EnUSName: "Batch",
EnUSDescription: "By setting the number of batch runs and logic, run the tasks in the batch body.",
},
{
ID: 29,
Name: "继续循环",
Type: NodeTypeContinue,
Category: "logic", // Mapped from cate_list
Desc: "用于终止当前循环,执行下次循环",
Color: "#00B2B2",
IconURL: "https://lf3-static.bytednsdoc.com/obj/eden-cn/dvsmryvd_avi_dvsm/ljhwZthlaukjlkulzlp/icon/icon-Continue-v2.jpg",
SupportBatch: false, // supportBatch: 1
ExecutableMeta: ExecutableMeta{
StreamingParadigms: map[StreamingParadigm]bool{Invoke: true},
},
EnUSName: "Continue",
EnUSDescription: "Used to immediately terminate the current loop and execute next loop",
},
{
ID: 30,
Name: "输入",
Type: NodeTypeInputReceiver,
Category: "input&output", // Mapped from cate_list
Desc: "支持中间过程的信息输入",
Color: "#5C62FF",
IconURL: "https://lf3-static.bytednsdoc.com/obj/eden-cn/dvsmryvd_avi_dvsm/ljhwZthlaukjlkulzlp/icon/icon-Input-v2.jpg",
SupportBatch: false, // supportBatch: 1
ExecutableMeta: ExecutableMeta{
PostFillNil: true,
CallbackEnabled: true,
StreamingParadigms: map[StreamingParadigm]bool{Invoke: true},
},
EnUSName: "Input",
EnUSDescription: "Support intermediate information input",
},
{
ID: 31,
Name: "注释",
Type: "",
Category: "", // Not found in cate_list
Desc: "comment_desc", // Placeholder from JSON
Color: "",
IconURL: "comment_icon", // Placeholder from JSON
SupportBatch: false, // supportBatch: 1
EnUSName: "Comment",
},
{
ID: 32,
Name: "变量聚合",
Type: NodeTypeVariableAggregator,
Category: "logic", // Mapped from cate_list
Desc: "对多个分支的输出进行聚合处理",
Color: "#00B2B2",
IconURL: "https://lf3-static.bytednsdoc.com/obj/eden-cn/dvsmryvd_avi_dvsm/ljhwZthlaukjlkulzlp/icon/VariableMerge-icon.jpg",
SupportBatch: false, // supportBatch: 1
ExecutableMeta: ExecutableMeta{
PostFillNil: true,
CallbackEnabled: true,
InputSourceAware: true,
StreamingParadigms: map[StreamingParadigm]bool{Invoke: true, Transform: true},
},
EnUSName: "Variable Merge",
EnUSDescription: "Aggregate the outputs of multiple branches.",
},
{
ID: 37,
Name: "查询消息列表",
Type: NodeTypeMessageList,
Category: "message", // Mapped from cate_list
Desc: "用于查询消息列表",
Color: "#F2B600",
IconURL: "https://lf3-static.bytednsdoc.com/obj/eden-cn/dvsmryvd_avi_dvsm/ljhwZthlaukjlkulzlp/icon/icon-Conversation-List.jpeg",
SupportBatch: false, // supportBatch: 1
Disabled: true,
ExecutableMeta: ExecutableMeta{
PreFillZero: true,
PostFillNil: true,
StreamingParadigms: map[StreamingParadigm]bool{Invoke: true},
},
EnUSName: "Query message list",
EnUSDescription: "Used to query the message list",
},
{
ID: 38,
Name: "清除上下文",
Type: NodeTypeClearMessage,
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, // supportBatch: 1
Disabled: true,
ExecutableMeta: ExecutableMeta{
PreFillZero: true,
PostFillNil: true,
StreamingParadigms: map[StreamingParadigm]bool{Invoke: true},
},
EnUSName: "Clear conversation history",
EnUSDescription: "Used to clear conversation history. After clearing, the conversation history visible to the LLM node will be empty.",
},
{
ID: 39,
Name: "创建会话",
Type: NodeTypeCreateConversation,
Category: "conversation_management", // Mapped from cate_list
Desc: "用于创建会话",
Color: "#F2B600",
IconURL: "https://lf3-static.bytednsdoc.com/obj/eden-cn/dvsmryvd_avi_dvsm/ljhwZthlaukjlkulzlp/icon/icon-Conversation-Create.jpeg",
SupportBatch: false, // supportBatch: 1
Disabled: true,
ExecutableMeta: ExecutableMeta{
PreFillZero: true,
PostFillNil: true,
StreamingParadigms: map[StreamingParadigm]bool{Invoke: true},
},
EnUSName: "Create conversation",
EnUSDescription: "This node is used to create a conversation.",
},
{
ID: 40,
Name: "变量赋值",
Type: NodeTypeVariableAssigner,
Category: "data", // Mapped from cate_list
Desc: "用于给支持写入的变量赋值,包括应用变量、用户变量",
Color: "#FF811A",
IconURL: "https://lf3-static.bytednsdoc.com/obj/eden-cn/dvsmryvd_avi_dvsm/ljhwZthlaukjlkulzlp/icon/Variable.jpg",
SupportBatch: false, // supportBatch: 1
ExecutableMeta: ExecutableMeta{
StreamingParadigms: map[StreamingParadigm]bool{Invoke: true},
},
EnUSName: "Variable assign",
EnUSDescription: "Assigns values to variables that support the write operation, including app and user variables.",
},
{
ID: 42,
Name: "更新数据",
Type: NodeTypeDatabaseUpdate,
Category: "database", // Mapped from cate_list
Desc: "修改表中已存在的数据记录,用户指定更新条件和内容来更新数据",
Color: "#F2B600",
IconURL: "https://lf3-static.bytednsdoc.com/obj/eden-cn/dvsmryvd_avi_dvsm/ljhwZthlaukjlkulzlp/icon/icon-database-update.jpg", // Corrected Icon URL from JSON
SupportBatch: false, // supportBatch: 1
ExecutableMeta: ExecutableMeta{
DefaultTimeoutMS: 60 * 1000, // 1 minute
PreFillZero: true,
CallbackEnabled: true,
StreamingParadigms: map[StreamingParadigm]bool{Invoke: true},
},
EnUSName: "Update Data",
EnUSDescription: "Modify the existing data records in the table, and the user specifies the update conditions and contents to update the data",
},
{
ID: 43,
Name: "查询数据", // Corrected Name from JSON (was "插入数据")
Type: NodeTypeDatabaseQuery,
Category: "database", // Mapped from cate_list
Desc: "从表获取数据,用户可定义查询条件、选择列等,输出符合条件的数据", // Corrected Desc from JSON
Color: "#F2B600",
IconURL: "https://lf3-static.bytednsdoc.com/obj/eden-cn/dvsmryvd_avi_dvsm/ljhwZthlaukjlkulzlp/icon/icaon-database-select.jpg", // Corrected Icon URL from JSON
SupportBatch: false, // supportBatch: 1
ExecutableMeta: ExecutableMeta{
DefaultTimeoutMS: 60 * 1000, // 1 minute
PreFillZero: true,
CallbackEnabled: true,
StreamingParadigms: map[StreamingParadigm]bool{Invoke: true},
},
EnUSName: "Query Data",
EnUSDescription: "Query data from the table, and the user can define query conditions, select columns, etc., and output the data that meets the conditions",
},
{
ID: 44,
Name: "删除数据",
Type: NodeTypeDatabaseDelete,
Category: "database", // Mapped from cate_list
Desc: "从表中删除数据记录,用户指定删除条件来删除符合条件的记录", // Corrected Desc from JSON
Color: "#F2B600",
IconURL: "https://lf3-static.bytednsdoc.com/obj/eden-cn/dvsmryvd_avi_dvsm/ljhwZthlaukjlkulzlp/icon/icon-database-delete.jpg", // Corrected Icon URL from JSON
SupportBatch: false, // supportBatch: 1
ExecutableMeta: ExecutableMeta{
DefaultTimeoutMS: 60 * 1000, // 1 minute
PreFillZero: true,
CallbackEnabled: true,
StreamingParadigms: map[StreamingParadigm]bool{Invoke: true},
},
EnUSName: "Delete Data",
EnUSDescription: "Delete data records from the table, and the user specifies the deletion conditions to delete the records that meet the conditions",
},
{
ID: 45,
Name: "HTTP 请求",
Type: NodeTypeHTTPRequester,
Category: "utilities", // Mapped from cate_list
Desc: "用于发送API请求从接口返回数据", // Corrected Desc from JSON
Color: "#3071F2",
IconURL: "https://lf3-static.bytednsdoc.com/obj/eden-cn/dvsmryvd_avi_dvsm/ljhwZthlaukjlkulzlp/icon/icon-HTTP.png", // Corrected Icon URL from JSON
SupportBatch: false, // supportBatch: 1
ExecutableMeta: ExecutableMeta{
DefaultTimeoutMS: 60 * 1000, // 1 minute
PreFillZero: true,
PostFillNil: true,
CallbackEnabled: true,
StreamingParadigms: map[StreamingParadigm]bool{Invoke: true},
},
EnUSName: "HTTP request",
EnUSDescription: "It is used to send API requests and return data from the interface.",
},
{
ID: 46,
Name: "新增数据", // Corrected Name from JSON (was "查询数据")
Type: NodeTypeDatabaseInsert,
Category: "database", // Mapped from cate_list
Desc: "向表添加新数据记录,用户输入数据内容后插入数据库", // Corrected Desc from JSON
Color: "#F2B600",
IconURL: "https://lf3-static.bytednsdoc.com/obj/eden-cn/dvsmryvd_avi_dvsm/ljhwZthlaukjlkulzlp/icon/icon-database-insert.jpg", // Corrected Icon URL from JSON
SupportBatch: false, // supportBatch: 1
ExecutableMeta: ExecutableMeta{
DefaultTimeoutMS: 60 * 1000, // 1 minute
PreFillZero: true,
CallbackEnabled: true,
StreamingParadigms: map[StreamingParadigm]bool{Invoke: true},
},
EnUSName: "Add Data",
EnUSDescription: "Add new data records to the table, and insert them into the database after the user enters the data content",
},
{
ID: 58,
Name: "JSON 序列化",
Type: NodeTypeJsonSerialization,
Category: "utilities",
Desc: "用于把变量转化为JSON字符串",
Color: "F2B600",
IconURL: "https://lf3-static.bytednsdoc.com/obj/eden-cn/dvsmryvd_avi_dvsm/ljhwZthlaukjlkulzlp/icon/icon-to_json.png",
SupportBatch: false,
ExecutableMeta: ExecutableMeta{
DefaultTimeoutMS: 60 * 1000, // 1 minute
PreFillZero: true,
CallbackEnabled: true,
StreamingParadigms: map[StreamingParadigm]bool{Invoke: true},
},
EnUSName: "JSON serialization",
EnUSDescription: "Convert variable to JSON string",
},
{
ID: 59,
Name: "JSON 反序列化",
Type: NodeTypeJsonDeserialization,
Category: "utilities",
Desc: "用于将JSON字符串解析为变量",
Color: "F2B600",
IconURL: "https://lf3-static.bytednsdoc.com/obj/eden-cn/dvsmryvd_avi_dvsm/ljhwZthlaukjlkulzlp/icon/icon-from_json.png",
SupportBatch: false,
ExecutableMeta: ExecutableMeta{
DefaultTimeoutMS: 60 * 1000, // 1 minute
PreFillZero: true,
PostFillNil: true,
CallbackEnabled: true,
StreamingParadigms: map[StreamingParadigm]bool{Invoke: true},
},
EnUSName: "JSON deserialization",
EnUSDescription: "Parse JSON string to variable",
},
{
ID: 60,
Name: "知识库删除",
Type: NodeTypeKnowledgeDeleter,
Category: "data", // Mapped from cate_list
Desc: "用于删除知识库中的文档",
Color: "#FF811A",
IconURL: "https://lf3-static.bytednsdoc.com/obj/eden-cn/dvsmryvd_avi_dvsm/ljhwZthlaukjlkulzlp/icon/icons-dataset-delete.png",
SupportBatch: false, // supportBatch: 1
ExecutableMeta: ExecutableMeta{
DefaultTimeoutMS: 60 * 1000, // 1 minute
PreFillZero: true,
PostFillNil: true,
StreamingParadigms: map[StreamingParadigm]bool{Invoke: true},
},
EnUSName: "Knowledge delete",
EnUSDescription: "The delete node can delete a document in knowledge base.",
},
// --- End of nodes parsed from template_list ---
}
// PluginNodeMetas holds metadata for specific plugin API entity.
var PluginNodeMetas []*PluginNodeMeta
// PluginCategoryMetas holds metadata for plugin category entity.
var PluginCategoryMetas []*PluginCategoryMeta
func NodeMetaByNodeType(t NodeType) *NodeTypeMeta {
for _, meta := range NodeTypeMetas {
if meta.Type == t {
return meta
}
}
return nil
}
const defaultZhCNInitCanvasJsonSchema = `{
"nodes": [
{
"id": "100001",
"type": "1",
"meta": {
"position": {
"x": 0,
"y": 0
}
},
"data": {
"nodeMeta": {
"description": "工作流的起始节点,用于设定启动工作流需要的信息",
"icon": "https://lf3-static.bytednsdoc.com/obj/eden-cn/dvsmryvd_avi_dvsm/ljhwZthlaukjlkulzlp/icon/icon-Start.png",
"subTitle": "",
"title": "开始"
},
"outputs": [
{
"type": "string",
"name": "input",
"required": false
}
],
"trigger_parameters": [
{
"type": "string",
"name": "input",
"required": false
}
]
}
},
{
"id": "900001",
"type": "2",
"meta": {
"position": {
"x": 1000,
"y": 0
}
},
"data": {
"nodeMeta": {
"description": "工作流的最终节点,用于返回工作流运行后的结果信息",
"icon": "https://lf3-static.bytednsdoc.com/obj/eden-cn/dvsmryvd_avi_dvsm/ljhwZthlaukjlkulzlp/icon/icon-End.png",
"subTitle": "",
"title": "结束"
},
"inputs": {
"terminatePlan": "returnVariables",
"inputParameters": [
{
"name": "output",
"input": {
"type": "string",
"value": {
"type": "ref",
"content": {
"source": "block-output",
"blockID": "",
"name": ""
}
}
}
}
]
}
}
}
],
"edges": [],
"versions": {
"loop": "v2"
}
}`
const defaultEnUSInitCanvasJsonSchema = `{
"nodes": [
{
"id": "100001",
"type": "1",
"meta": {
"position": {
"x": 0,
"y": 0
}
},
"data": {
"nodeMeta": {
"description": "The starting node of the workflow, used to set the information needed to initiate the workflow.",
"icon": "https://lf3-static.bytednsdoc.com/obj/eden-cn/dvsmryvd_avi_dvsm/ljhwZthlaukjlkulzlp/icon/icon-Start.png",
"subTitle": "",
"title": "Start"
},
"outputs": [
{
"type": "string",
"name": "input",
"required": false
}
],
"trigger_parameters": [
{
"type": "string",
"name": "input",
"required": false
}
]
}
},
{
"id": "900001",
"type": "2",
"meta": {
"position": {
"x": 1000,
"y": 0
}
},
"data": {
"nodeMeta": {
"description": "The final node of the workflow, used to return the result information after the workflow runs.",
"icon": "https://lf3-static.bytednsdoc.com/obj/eden-cn/dvsmryvd_avi_dvsm/ljhwZthlaukjlkulzlp/icon/icon-End.png",
"subTitle": "",
"title": "End"
},
"inputs": {
"terminatePlan": "returnVariables",
"inputParameters": [
{
"name": "output",
"input": {
"type": "string",
"value": {
"type": "ref",
"content": {
"source": "block-output",
"blockID": "",
"name": ""
}
}
}
}
]
}
}
}
],
"edges": [],
"versions": {
"loop": "v2"
}
}`
func GetDefaultInitCanvasJsonSchema(locale i18n.Locale) string {
return ternary.IFElse(locale == i18n.LocaleEN, defaultEnUSInitCanvasJsonSchema, defaultZhCNInitCanvasJsonSchema)
}

View File

@@ -0,0 +1,634 @@
/*
* 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/coze-dev/coze-studio/backend/api/model/ocean/cloud/workflow"
"github.com/coze-dev/coze-studio/backend/domain/workflow/crossdomain/model"
)
type Canvas struct {
Nodes []*Node `json:"nodes"`
Edges []*Edge `json:"edges"`
Versions any `json:"versions"`
}
type Node struct {
ID string `json:"id"`
Type BlockType `json:"type"`
Meta any `json:"meta"`
Data *Data `json:"data"`
Blocks []*Node `json:"blocks,omitempty"`
Edges []*Edge `json:"edges,omitempty"`
Version string `json:"version,omitempty"`
parent *Node
}
func (n *Node) SetParent(parent *Node) {
n.parent = parent
}
func (n *Node) Parent() *Node {
return n.parent
}
type NodeMeta struct {
Title string `json:"title,omitempty"`
Description string `json:"description,omitempty"`
Icon string `json:"icon,omitempty"`
SubTitle string `json:"subTitle,omitempty"`
MainColor string `json:"mainColor,omitempty"`
}
type Edge struct {
SourceNodeID string `json:"sourceNodeID"`
TargetNodeID string `json:"targetNodeID"`
SourcePortID string `json:"sourcePortID,omitempty"`
TargetPortID string `json:"targetPortID,omitempty"`
}
type Data struct {
Meta *NodeMeta `json:"nodeMeta,omitempty"`
Outputs []any `json:"outputs,omitempty"` // either []*Variable or []*Param
Inputs *Inputs `json:"inputs,omitempty"`
Size any `json:"size,omitempty"`
}
type Inputs struct {
InputParameters []*Param `json:"inputParameters"`
Content *BlockInput `json:"content"`
TerminatePlan *TerminatePlan `json:"terminatePlan,omitempty"`
StreamingOutput bool `json:"streamingOutput,omitempty"`
CallTransferVoice bool `json:"callTransferVoice,omitempty"`
ChatHistoryWriting string `json:"chatHistoryWriting,omitempty"`
LLMParam any `json:"llmParam,omitempty"` // The LLMParam type may be one of the LLMParam or IntentDetectorLLMParam type or QALLMParam type
FCParam *FCParam `json:"fcParam,omitempty"`
SettingOnError *SettingOnError `json:"settingOnError,omitempty"`
LoopType LoopType `json:"loopType,omitempty"`
LoopCount *BlockInput `json:"loopCount,omitempty"`
VariableParameters []*Param `json:"variableParameters,omitempty"`
Branches []*struct {
Condition struct {
Logic LogicType `json:"logic"`
Conditions []*Condition `json:"conditions"`
} `json:"condition"`
} `json:"branches,omitempty"`
NodeBatchInfo *NodeBatch `json:"batch,omitempty"` // node in batch mode
*TextProcessor
*SubWorkflow
*IntentDetector
*DatabaseNode
*HttpRequestNode
*KnowledgeIndexer
*CodeRunner
*PluginAPIParam
*VariableAggregator
*VariableAssigner
*QA
*Batch
*Comment
OutputSchema string `json:"outputSchema,omitempty"`
}
type Comment struct {
SchemaType string `json:"schemaType,omitempty"`
Note any `json:"note,omitempty"`
}
type TextProcessor struct {
Method TextProcessingMethod `json:"method,omitempty"`
ConcatParams []*Param `json:"concatParams,omitempty"`
SplitParams []*Param `json:"splitParams,omitempty"`
}
type VariableAssigner struct {
VariableTypeMap map[string]any `json:"variableTypeMap,omitempty"`
}
type LLMParam = []*Param
type IntentDetectorLLMParam = map[string]any
type QALLMParam struct {
GenerationDiversity string `json:"generationDiversity"`
MaxTokens int `json:"maxTokens"`
ModelName string `json:"modelName"`
ModelType int64 `json:"modelType"`
ResponseFormat model.ResponseFormat `json:"responseFormat"`
SystemPrompt string `json:"systemPrompt"`
Temperature float64 `json:"temperature"`
TopP float64 `json:"topP"`
}
type QA struct {
AnswerType QAAnswerType `json:"answer_type"`
Limit int `json:"limit,omitempty"`
ExtractOutput bool `json:"extra_output,omitempty"`
OptionType QAOptionType `json:"option_type,omitempty"`
Options []struct {
Name string `json:"name"`
} `json:"options,omitempty"`
Question string `json:"question,omitempty"`
DynamicOption *BlockInput `json:"dynamic_option,omitempty"`
}
type QAAnswerType string
const (
QAAnswerTypeOption QAAnswerType = "option"
QAAnswerTypeText QAAnswerType = "text"
)
type QAOptionType string
const (
QAOptionTypeStatic QAOptionType = "static"
QAOptionTypeDynamic QAOptionType = "dynamic"
)
type RequestParameter struct {
Name string
}
type FCParam struct {
WorkflowFCParam *struct {
WorkflowList []struct {
WorkflowID string `json:"workflow_id"`
WorkflowVersion string `json:"workflow_version"`
PluginID string `json:"plugin_id"`
PluginVersion string `json:"plugin_version"`
IsDraft bool `json:"is_draft"`
FCSetting *struct {
RequestParameters []*workflow.APIParameter `json:"request_params"`
ResponseParameters []*workflow.APIParameter `json:"response_params"`
} `json:"fc_setting,omitempty"`
} `json:"workflowList,omitempty"`
} `json:"workflowFCParam,omitempty"`
PluginFCParam *struct {
PluginList []struct {
PluginID string `json:"plugin_id"`
ApiId string `json:"api_id"`
ApiName string `json:"api_name"`
PluginVersion string `json:"plugin_version"`
IsDraft bool `json:"is_draft"`
FCSetting *struct {
RequestParameters []*workflow.APIParameter `json:"request_params"`
ResponseParameters []*workflow.APIParameter `json:"response_params"`
} `json:"fc_setting,omitempty"`
}
} `json:"pluginFCParam,omitempty"`
KnowledgeFCParam *struct {
GlobalSetting *struct {
SearchMode int64 `json:"search_mode"`
TopK int64 `json:"top_k"`
MinScore float64 `json:"min_score"`
UseNL2SQL bool `json:"use_nl2_sql"`
UseRewrite bool `json:"use_rewrite"`
UseRerank bool `json:"use_rerank"`
NoRecallReplyCustomizePrompt string `json:"no_recall_reply_customize_prompt"`
NoRecallReplyMode int64 `json:"no_recall_reply_mode"`
} `json:"global_setting,omitempty"`
KnowledgeList []*struct {
ID string `json:"id"`
} `json:"knowledgeList,omitempty"`
} `json:"knowledgeFCParam,omitempty"`
}
type Batch struct {
BatchSize *BlockInput `json:"batchSize,omitempty"`
ConcurrentSize *BlockInput `json:"concurrentSize,omitempty"`
}
type NodeBatch struct {
BatchEnable bool `json:"batchEnable"`
BatchSize int64 `json:"batchSize"`
ConcurrentSize int64 `json:"concurrentSize"`
InputLists []*Param `json:"inputLists,omitempty"`
}
type IntentDetectorLLMConfig struct {
ModelName string `json:"modelName"`
ModelType int `json:"modelType"`
Temperature *float64 `json:"temperature"`
TopP *float64 `json:"topP"`
MaxTokens int `json:"maxTokens"`
ResponseFormat int64 `json:"responseFormat"`
SystemPrompt BlockInput `json:"systemPrompt"`
}
type VariableAggregator struct {
MergeGroups []*Param `json:"mergeGroups,omitempty"`
}
type PluginAPIParam struct {
APIParams []*Param `json:"apiParam"`
}
type CodeRunner struct {
Code string `json:"code"`
Language int64 `json:"language"`
}
type KnowledgeIndexer struct {
DatasetParam []*Param `json:"datasetParam,omitempty"`
StrategyParam StrategyParam `json:"strategyParam,omitempty"`
}
type StrategyParam struct {
ParsingStrategy struct {
ParsingType string `json:"parsingType,omitempty"`
ImageExtraction bool `json:"imageExtraction"`
TableExtraction bool `json:"tableExtraction"`
ImageOcr bool `json:"imageOcr"`
} `json:"parsingStrategy,omitempty"`
ChunkStrategy struct {
ChunkType string `json:"chunkType,omitempty"`
SeparatorType string `json:"separatorType,omitempty"`
Separator string `json:"separator,omitempty"`
MaxToken int64 `json:"maxToken,omitempty"`
Overlap float64 `json:"overlap,omitempty"`
} `json:"chunkStrategy,omitempty"`
IndexStrategy any `json:"indexStrategy"`
}
type HttpRequestNode struct {
APIInfo APIInfo `json:"apiInfo,omitempty"`
Body Body `json:"body,omitempty"`
Headers []*Param `json:"headers"`
Params []*Param `json:"params"`
Auth *Auth `json:"auth"`
Setting *HttpRequestSetting `json:"setting"`
}
type APIInfo struct {
Method string `json:"method"`
URL string `json:"url"`
}
type Body struct {
BodyType string `json:"bodyType"`
BodyData *BodyData `json:"bodyData"`
}
type BodyData struct {
Json string `json:"json,omitempty"`
FormData *struct {
Data []*Param `json:"data"`
} `json:"formData,omitempty"`
FormURLEncoded []*Param `json:"formURLEncoded,omitempty"`
RawText string `json:"rawText,omitempty"`
Binary struct {
FileURL *BlockInput `json:"fileURL"`
} `json:"binary"`
}
type Auth struct {
AuthType string `json:"authType"`
AuthData struct {
CustomData struct {
AddTo string `json:"addTo"`
Data []*Param `json:"data,omitempty"`
} `json:"customData"`
BearerTokenData []*Param `json:"bearerTokenData,omitempty"`
} `json:"authData"`
AuthOpen bool `json:"authOpen"`
}
type HttpRequestSetting struct {
Timeout int64 `json:"timeout"`
RetryTimes int64 `json:"retryTimes"`
}
type DatabaseNode struct {
DatabaseInfoList []*DatabaseInfo `json:"databaseInfoList,omitempty"`
SQL string `json:"sql,omitempty"`
SelectParam *SelectParam `json:"selectParam,omitempty"`
InsertParam *InsertParam `json:"insertParam,omitempty"`
DeleteParam *DeleteParam `json:"deleteParam,omitempty"`
UpdateParam *UpdateParam `json:"updateParam,omitempty"`
}
type DatabaseLogicType string
const (
DatabaseLogicAnd DatabaseLogicType = "AND"
DatabaseLogicOr DatabaseLogicType = "OR"
)
type DBCondition struct {
ConditionList [][]*Param `json:"conditionList,omitempty"`
Logic DatabaseLogicType `json:"logic"`
}
type UpdateParam struct {
Condition DBCondition `json:"condition"`
FieldInfo [][]*Param `json:"fieldInfo"`
}
type DeleteParam struct {
Condition DBCondition `json:"condition"`
}
type InsertParam struct {
FieldInfo [][]*Param `json:"fieldInfo"`
}
type SelectParam struct {
Condition *DBCondition `json:"condition,omitempty"` // may be nil
OrderByList []struct {
FieldID int64 `json:"fieldID"`
IsAsc bool `json:"isAsc"`
} `json:"orderByList,omitempty"`
Limit int64 `json:"limit"`
FieldList []struct {
FieldID int64 `json:"fieldID"`
IsDistinct bool `json:"isDistinct"`
} `json:"fieldList,omitempty"`
}
type DatabaseInfo struct {
DatabaseInfoID string `json:"databaseInfoID"`
}
type IntentDetector struct {
ChatHistorySetting *ChatHistorySetting `json:"chatHistorySetting,omitempty"`
Intents []*Intent `json:"intents,omitempty"`
Mode string `json:"mode,omitempty"`
}
type ChatHistorySetting struct {
EnableChatHistory bool `json:"enableChatHistory,omitempty"`
ChatHistoryRound int64 `json:"chatHistoryRound,omitempty"`
}
type Intent struct {
Name string `json:"name"`
}
type Param struct {
Name string `json:"name,omitempty"`
Input *BlockInput `json:"input,omitempty"`
Left *BlockInput `json:"left,omitempty"`
Right *BlockInput `json:"right,omitempty"`
Variables []*BlockInput `json:"variables,omitempty"`
}
type Variable struct {
Name string `json:"name"`
Type VariableType `json:"type"`
Required bool `json:"required,omitempty"`
AssistType AssistType `json:"assistType,omitempty"`
Schema any `json:"schema,omitempty"` // either []*Variable (for object) or *Variable (for list)
Description string `json:"description,omitempty"`
ReadOnly bool `json:"readOnly,omitempty"`
DefaultValue any `json:"defaultValue,omitempty"`
}
type BlockInput struct {
Type VariableType `json:"type,omitempty" yaml:"Type,omitempty"`
AssistType AssistType `json:"assistType,omitempty" yaml:"AssistType,omitempty"`
Schema any `json:"schema,omitempty" yaml:"Schema,omitempty"` // either *BlockInput(or *Variable) for list or []*Variable (for object)
Value *BlockInputValue `json:"value,omitempty" yaml:"Value,omitempty"`
}
type BlockInputValue struct {
Type BlockInputValueType `json:"type"`
Content any `json:"content,omitempty"` // either string for text such as template, or BlockInputReference
RawMeta any `json:"rawMeta,omitempty"`
}
type BlockInputReference struct {
BlockID string `json:"blockID"`
Name string `json:"name,omitempty"`
Path []string `json:"path,omitempty"`
Source RefSourceType `json:"source"`
}
type Condition struct {
Operator OperatorType `json:"operator"`
Left *Param `json:"left"`
Right *Param `json:"right,omitempty"`
}
type SubWorkflow struct {
WorkflowID string `json:"workflowId,omitempty"`
WorkflowVersion string `json:"workflowVersion,omitempty"`
TerminationType int `json:"type,omitempty"`
SpaceID string `json:"spaceId,omitempty"`
}
// BlockType is the enumeration of node types for front-end canvas schema.
// To add a new BlockType, start from a really big number such as 1000, to avoid conflict with future extensions.
type BlockType string
func (b BlockType) String() string {
return string(b)
}
const (
BlockTypeBotStart BlockType = "1"
BlockTypeBotEnd BlockType = "2"
BlockTypeBotLLM BlockType = "3"
BlockTypeBotAPI BlockType = "4"
BlockTypeBotCode BlockType = "5"
BlockTypeBotDataset BlockType = "6"
BlockTypeCondition BlockType = "8"
BlockTypeBotSubWorkflow BlockType = "9"
BlockTypeDatabase BlockType = "12"
BlockTypeBotMessage BlockType = "13"
BlockTypeBotText BlockType = "15"
BlockTypeQuestion BlockType = "18"
BlockTypeBotBreak BlockType = "19"
BlockTypeBotLoopSetVariable BlockType = "20"
BlockTypeBotLoop BlockType = "21"
BlockTypeBotIntent BlockType = "22"
BlockTypeBotDatasetWrite BlockType = "27"
BlockTypeBotInput BlockType = "30"
BlockTypeBotBatch BlockType = "28"
BlockTypeBotContinue BlockType = "29"
BlockTypeBotComment BlockType = "31"
BlockTypeBotVariableMerge BlockType = "32"
BlockTypeBotAssignVariable BlockType = "40"
BlockTypeDatabaseUpdate BlockType = "42"
BlockTypeDatabaseSelect BlockType = "43"
BlockTypeDatabaseDelete BlockType = "44"
BlockTypeBotHttp BlockType = "45"
BlockTypeDatabaseInsert BlockType = "46"
BlockTypeJsonSerialization BlockType = "58"
BlockTypeJsonDeserialization BlockType = "59"
BlockTypeBotDatasetDelete BlockType = "60"
)
type VariableType string
const (
VariableTypeString VariableType = "string"
VariableTypeInteger VariableType = "integer"
VariableTypeFloat VariableType = "float"
VariableTypeBoolean VariableType = "boolean"
VariableTypeObject VariableType = "object"
VariableTypeList VariableType = "list"
)
type AssistType = int64
const (
AssistTypeNotSet AssistType = 0
AssistTypeDefault AssistType = 1
AssistTypeImage AssistType = 2
AssistTypeDoc AssistType = 3
AssistTypeCode AssistType = 4
AssistTypePPT AssistType = 5
AssistTypeTXT AssistType = 6
AssistTypeExcel AssistType = 7
AssistTypeAudio AssistType = 8
AssistTypeZip AssistType = 9
AssistTypeVideo AssistType = 10
AssistTypeSvg AssistType = 11
AssistTypeVoice AssistType = 12
AssistTypeTime AssistType = 10000
)
type BlockInputValueType string
const (
BlockInputValueTypeLiteral BlockInputValueType = "literal"
BlockInputValueTypeRef BlockInputValueType = "ref"
BlockInputValueTypeObjectRef BlockInputValueType = "object_ref"
)
type RefSourceType string
const (
RefSourceTypeBlockOutput RefSourceType = "block-output" // 代表引用了某个 Block 的输出隐式声明的变量
RefSourceTypeGlobalApp RefSourceType = "global_variable_app"
RefSourceTypeGlobalSystem RefSourceType = "global_variable_system"
RefSourceTypeGlobalUser RefSourceType = "global_variable_user"
)
type TerminatePlan string
const (
ReturnVariables TerminatePlan = "returnVariables"
UseAnswerContent TerminatePlan = "useAnswerContent"
)
type ErrorProcessType int
const (
ErrorProcessTypeThrow ErrorProcessType = 1
ErrorProcessTypeDefault ErrorProcessType = 2
ErrorProcessTypeExceptionBranch ErrorProcessType = 3
)
type SettingOnError struct {
DataOnErr string `json:"dataOnErr,omitempty"`
Switch bool `json:"switch,omitempty"`
ProcessType *ErrorProcessType `json:"processType,omitempty"`
RetryTimes int64 `json:"retryTimes,omitempty"`
TimeoutMs int64 `json:"timeoutMs,omitempty"`
Ext *struct {
BackupLLMParam string `json:"backupLLMParam,omitempty"` // only for LLM Node, marshaled from QALLMParam
} `json:"ext,omitempty"`
}
type LogicType int
const (
_ LogicType = iota
OR
AND
)
type OperatorType int
const (
_ OperatorType = iota
Equal
NotEqual
LengthGreaterThan
LengthGreaterThanEqual
LengthLessThan
LengthLessThanEqual
Contain
NotContain
Empty
NotEmpty
True
False
GreaterThan
GreaterThanEqual
LessThan
LessThanEqual
)
type TextProcessingMethod string
const (
Concat TextProcessingMethod = "concat"
Split TextProcessingMethod = "split"
)
type LoopType string
const (
LoopTypeArray LoopType = "array"
LoopTypeCount LoopType = "count"
LoopTypeInfinite LoopType = "infinite"
)
type WorkflowIdentity struct {
ID string `json:"id"`
Version string `json:"version"`
}
func (c *Canvas) GetAllSubWorkflowIdentities() []*WorkflowIdentity {
workflowEntities := make([]*WorkflowIdentity, 0)
var collectSubWorkFlowEntities func(nodes []*Node)
collectSubWorkFlowEntities = func(nodes []*Node) {
for _, n := range nodes {
if n.Type == BlockTypeBotSubWorkflow {
workflowEntities = append(workflowEntities, &WorkflowIdentity{
ID: n.Data.Inputs.WorkflowID,
Version: n.Data.Inputs.WorkflowVersion,
})
}
if len(n.Blocks) > 0 {
collectSubWorkFlowEntities(n.Blocks)
}
}
}
collectSubWorkFlowEntities(c.Nodes)
return workflowEntities
}
func GenerateNodeIDForBatchMode(key string) string {
return key + "_inner"
}
func IsGeneratedNodeForBatchMode(key string, parentKey string) bool {
return key == GenerateNodeIDForBatchMode(parentKey)
}

View File

@@ -0,0 +1,103 @@
/*
* 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 Page struct {
Size int32 `json:"size"`
Page int32 `json:"page"`
}
func (p *Page) Offset() int {
if p.Page == 0 {
return 0
}
return int((p.Page - 1) * p.Size)
}
func (p *Page) Limit() int {
return int(p.Size)
}
type PublishStatus string
const (
UnPublished PublishStatus = "UnPublished"
HasPublished PublishStatus = "HasPublished"
)
type WorkFlowType string
const (
User WorkFlowType = "user"
Official WorkFlowType = "official"
)
type QueryToolInfoOption struct {
Page *Page
IDs []int64
}
type Locator uint8
const (
FromDraft Locator = iota
FromSpecificVersion
FromLatestVersion
)
type GetPolicy struct {
ID int64
QType Locator
MetaOnly bool
Version string
CommitID string
}
type DeletePolicy struct {
ID *int64
IDs []int64
AppID *int64
}
type MGetPolicy struct {
MetaQuery
QType Locator
MetaOnly bool
Versions map[int64]string
}
type MGetReferencePolicy struct {
ReferredIDs []int64
ReferringIDs []int64
ReferringBizType []ReferringBizType
ReferType []ReferType
}
type ReferType uint8
const (
ReferTypeSubWorkflow ReferType = 1
ReferTypeTool ReferType = 2
)
type ReferringBizType uint8
const (
ReferringBizTypeWorkflow ReferringBizType = 1
ReferringBizTypeAgent ReferringBizType = 2
)

View File

@@ -0,0 +1,70 @@
/*
* 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 (
"time"
"github.com/coze-dev/coze-studio/backend/pkg/sonic"
)
type DraftInfo struct {
*DraftMeta
Canvas string
InputParamsStr string
OutputParamsStr string
CommitID string
}
type CanvasInfo struct {
Canvas string
InputParams []*NamedTypeInfo
OutputParams []*NamedTypeInfo
InputParamsStr string
OutputParamsStr string
}
func (c *CanvasInfo) Unmarshal() error {
if c.InputParamsStr != "" && len(c.InputParams) == 0 {
var input []*NamedTypeInfo
err := sonic.UnmarshalString(c.InputParamsStr, &input)
if err != nil {
return err
}
c.InputParams = input
}
if c.OutputParamsStr != "" && len(c.OutputParams) == 0 {
var output []*NamedTypeInfo
err := sonic.UnmarshalString(c.OutputParamsStr, &output)
if err != nil {
return err
}
c.OutputParams = output
}
return nil
}
type DraftMeta struct {
TestRunSuccess bool
Modified bool
Timestamp time.Time
IsSnapshot bool // if true, this is a snapshot of a previous draft content, not the latest draft
}

View File

@@ -0,0 +1,67 @@
/*
* 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 ExecuteConfig struct {
ID int64
From Locator
Version string
CommitID string
Operator int64
Mode ExecuteMode
AppID *int64
AgentID *int64
ConnectorID int64
ConnectorUID string
TaskType TaskType
SyncPattern SyncPattern
InputFailFast bool // whether to fail fast if input conversion has warnings
BizType BizType
Cancellable bool
}
type ExecuteMode string
const (
ExecuteModeDebug ExecuteMode = "debug"
ExecuteModeRelease ExecuteMode = "release"
ExecuteModeNodeDebug ExecuteMode = "node_debug"
)
type TaskType string
const (
TaskTypeForeground TaskType = "foreground"
TaskTypeBackground TaskType = "background"
)
type SyncPattern string
const (
SyncPatternSync SyncPattern = "sync"
SyncPatternAsync SyncPattern = "async"
SyncPatternStream SyncPattern = "stream"
)
var DebugURLTpl = "http://127.0.0.1:3000/work_flow?execute_id=%d&space_id=%d&workflow_id=%d&execute_mode=2"
type BizType string
const (
BizTypeAgent BizType = "agent"
BizTypeWorkflow BizType = "workflow"
)

View File

@@ -0,0 +1,83 @@
/*
* 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 (
"time"
"github.com/coze-dev/coze-studio/backend/api/model/ocean/cloud/workflow"
)
type ContentType = workflow.WorkFlowType
type Tag = workflow.Tag
type Mode = workflow.WorkflowMode
type Meta struct {
// the following fields are immutable
SpaceID int64
CreatorID int64
CreatedAt time.Time
ContentType ContentType
Tag *Tag
AppID *int64
SourceID *int64
AuthorID int64
// the following fields are mutable
Name string
Desc string
IconURI string
IconURL string
Mode Mode
UpdatedAt *time.Time
UpdaterID *int64
DeletedAt *time.Time
HasPublished bool
LatestPublishedVersion *string
}
type MetaCreate struct {
Name string
Desc string
IconURI string
SpaceID int64
CreatorID int64
ContentType ContentType
AppID *int64
Mode Mode
InitCanvasSchema string
}
type MetaUpdate struct {
Name *string
Desc *string
IconURI *string
HasPublished *bool
LatestPublishedVersion *string
}
type MetaQuery struct {
IDs []int64
SpaceID *int64
Page *Page
Name *string
PublishStatus *PublishStatus
AppID *int64
LibOnly bool
NeedTotalNumber bool
DescByUpdate bool
}

View File

@@ -0,0 +1,602 @@
/*
* 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 (
"errors"
"fmt"
"github.com/cloudwego/eino/compose"
"github.com/cloudwego/eino/schema"
"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"
)
type NodeKey string
type FieldInfo struct {
Path compose.FieldPath `json:"path"`
Source FieldSource `json:"source"`
}
type Reference struct {
FromNodeKey NodeKey `json:"from_node_key,omitempty"`
FromPath compose.FieldPath `json:"from_path"`
VariableType *GlobalVarType `json:"variable_type,omitempty"`
}
type FieldSource struct {
Ref *Reference `json:"ref,omitempty"`
Val any `json:"val,omitempty"`
}
type ImplicitNodeDependency struct {
NodeID string
FieldPath compose.FieldPath
TypeInfo *TypeInfo
}
type TypeInfo struct {
Type DataType `json:"type"`
ElemTypeInfo *TypeInfo `json:"elem_type_info,omitempty"`
FileType *FileSubType `json:"file_type,omitempty"`
Required bool `json:"required,omitempty"`
Desc string `json:"desc,omitempty"`
Properties map[string]*TypeInfo `json:"properties,omitempty"`
}
type NamedTypeInfo struct {
Name string `json:"name"`
Type DataType `json:"type"`
ElemTypeInfo *NamedTypeInfo `json:"elem_type_info,omitempty"`
FileType *FileSubType `json:"file_type,omitempty"`
Required bool `json:"required,omitempty"`
Desc string `json:"desc,omitempty"`
Properties []*NamedTypeInfo `json:"properties,omitempty"`
}
type ErrorLevel string
const (
LevelWarn ErrorLevel = "Warn"
LevelError ErrorLevel = "Error"
LevelCancel ErrorLevel = "pending" // forget about why it's called 'pending', somebody named it and it's now part of the protocol
)
type WorkflowError interface {
errorx.StatusError
DebugURL() string
Level() ErrorLevel
OpenAPICode() int
AppendDebug(exeID, spaceID, workflowID int64) WorkflowError
ChangeErrLevel(newLevel ErrorLevel) WorkflowError
}
type wfErr struct {
errorx.StatusError
exeID int64
spaceID int64
workflowID int64
cause error
}
func (w *wfErr) DebugURL() string {
if w.StatusError.Extra() == nil {
return fmt.Sprintf(DebugURLTpl, w.exeID, w.spaceID, w.workflowID)
}
debugURL, ok := w.StatusError.Extra()["debug_url"]
if ok {
return debugURL
}
return fmt.Sprintf(DebugURLTpl, w.exeID, w.spaceID, w.workflowID)
}
func (w *wfErr) Level() ErrorLevel {
if w.StatusError.Extra() == nil {
return LevelError
}
level, ok := w.StatusError.Extra()["level"]
if ok {
return ErrorLevel(level)
}
return LevelError
}
func (w *wfErr) Error() string {
if w.cause == nil {
return w.StatusError.Error()
}
return fmt.Sprintf("%s, cause: %s", w.StatusError.Error(), w.cause.Error())
}
func (w *wfErr) OpenAPICode() int {
return errno.CodeForOpenAPI(w)
}
func (w *wfErr) AppendDebug(exeID, spaceID, workflowID int64) WorkflowError {
w.exeID = exeID
w.spaceID = spaceID
w.workflowID = workflowID
return w
}
func (w *wfErr) Unwrap() error {
return w.cause
}
func (w *wfErr) ChangeErrLevel(newLevel ErrorLevel) WorkflowError {
w.StatusError.Extra()["level"] = string(newLevel)
return w
}
func NewError(code int, opts ...errorx.Option) WorkflowError {
opts = append(opts, errorx.Extra("level", string(LevelError)))
e := errorx.New(int32(code), opts...)
var sErr errorx.StatusError
_ = errors.As(e, &sErr)
wfe := &wfErr{
StatusError: sErr,
}
return wfe
}
func WrapError(code int, err error, opts ...errorx.Option) WorkflowError {
opts = append(opts, errorx.Extra("level", string(LevelError)))
e := errorx.WrapByCode(err, int32(code), opts...)
var sErr errorx.StatusError
_ = errors.As(e, &sErr)
wfe := &wfErr{
StatusError: sErr,
cause: err,
}
return wfe
}
func WrapWithDebug(code int, err error, exeID, spaceID, workflowID int64, opts ...errorx.Option) WorkflowError {
debugURL := fmt.Sprintf(DebugURLTpl, exeID, spaceID, workflowID)
opts = append(opts, errorx.Extra("debug_url", debugURL))
return WrapError(code, err, opts...)
}
func NewWarn(code int, opts ...errorx.Option) WorkflowError {
opts = append(opts, errorx.Extra("level", string(LevelWarn)))
e := errorx.New(int32(code), opts...)
var sErr errorx.StatusError
_ = errors.As(e, &sErr)
wfe := &wfErr{
StatusError: sErr,
}
return wfe
}
func WrapWarn(code int, err error, opts ...errorx.Option) WorkflowError {
opts = append(opts, errorx.Extra("level", string(LevelWarn)))
e := errorx.WrapByCode(err, int32(code), opts...)
var sErr errorx.StatusError
_ = errors.As(e, &sErr)
wfe := &wfErr{
StatusError: sErr,
cause: err,
}
return wfe
}
func WrapIfNeeded(code int, err error, opts ...errorx.Option) WorkflowError {
var wfe WorkflowError
if errors.As(err, &wfe) {
return wfe
}
return WrapError(code, err, opts...)
}
var CancelErr = newCancel()
func newCancel() WorkflowError {
e := errorx.New(errno.ErrWorkflowCanceledByUser, errorx.Extra("level", string(LevelCancel)))
var sErr errorx.StatusError
_ = errors.As(e, &sErr)
wfe := &wfErr{
StatusError: sErr,
}
return wfe
}
var NodeTimeoutErr = newNodeTimeout()
func newNodeTimeout() WorkflowError {
e := errorx.New(errno.ErrNodeTimeout, errorx.Extra("level", string(LevelError)))
var sErr errorx.StatusError
_ = errors.As(e, &sErr)
wfe := &wfErr{
StatusError: sErr,
}
return wfe
}
var WorkflowTimeoutErr = newWorkflowTimeout()
func newWorkflowTimeout() WorkflowError {
e := errorx.New(errno.ErrWorkflowTimeout, errorx.Extra("level", string(LevelError)))
var sErr errorx.StatusError
_ = errors.As(e, &sErr)
wfe := &wfErr{
StatusError: sErr,
}
return wfe
}
func UnwrapRootErr(err error) error {
var (
rootE = err
currentE error
)
for {
currentE = errors.Unwrap(rootE)
if currentE == nil {
break
}
rootE = currentE
}
return rootE
}
type DataType string
const (
DataTypeString DataType = "string" // string
DataTypeInteger DataType = "integer" // int64
DataTypeNumber DataType = "number" // float64
DataTypeBoolean DataType = "boolean" // bool
DataTypeTime DataType = "time" // time.Time
DataTypeObject DataType = "object" // map[string]any
DataTypeArray DataType = "list" // []any
DataTypeFile DataType = "file" // string (url)
)
// Zero creates a zero value
func (t *TypeInfo) Zero() any {
switch t.Type {
case DataTypeString:
return ""
case DataTypeInteger:
return int64(0)
case DataTypeNumber:
return float64(0)
case DataTypeBoolean:
return false
case DataTypeTime:
return ""
case DataTypeObject:
var m map[string]any
return m
case DataTypeArray:
var a []any
return a
case DataTypeFile:
return ""
default:
panic("impossible")
}
}
func (n *NamedTypeInfo) ToParameterInfo() (*schema.ParameterInfo, error) {
param := &schema.ParameterInfo{
Type: convertDataType(n.Type),
Desc: n.Desc,
Required: n.Required,
}
if n.Type == DataTypeObject {
param.SubParams = make(map[string]*schema.ParameterInfo, len(n.Properties))
for _, subT := range n.Properties {
subParam, err := subT.ToParameterInfo()
if err != nil {
return nil, err
}
param.SubParams[subT.Name] = subParam
}
} else if n.Type == DataTypeArray {
elemParam, err := n.ElemTypeInfo.ToParameterInfo()
if err != nil {
return nil, err
}
param.ElemInfo = elemParam
}
return param, nil
}
func (n *NamedTypeInfo) ToVariable() (*Variable, error) {
variableType, err := convertVariableType(n.Type)
if err != nil {
return nil, err
}
v := &Variable{
Name: n.Name,
Type: variableType,
Required: n.Required,
}
if n.Type == DataTypeFile && n.FileType != nil {
v.AssistType = toAssistType(*n.FileType)
}
if n.Type == DataTypeArray && n.ElemTypeInfo != nil {
ele, err := n.ElemTypeInfo.ToVariable()
if err != nil {
return nil, err
}
v.Schema = ele
}
if n.Type == DataTypeObject && len(n.Properties) > 0 {
varList := make([]*Variable, 0, len(n.Properties))
for _, p := range n.Properties {
v, err := p.ToVariable()
if err != nil {
return nil, err
}
varList = append(varList, v)
}
v.Schema = varList
}
return v, nil
}
func toAssistType(f FileSubType) AssistType {
switch f {
case FileTypeDefault:
return AssistTypeDefault
case FileTypeImage:
return AssistTypeImage
case FileTypeSVG:
return AssistTypeSvg
case FileTypeAudio:
return AssistTypeAudio
case FileTypeVideo:
return AssistTypeVideo
case FileTypeDocument:
return AssistTypeDoc
case FileTypePPT:
return AssistTypePPT
case FileTypeExcel:
return AssistTypeExcel
case FileTypeTxt:
return AssistTypeTXT
case FileTypeCode:
return AssistTypeCode
case FileTypeZip:
return AssistTypeZip
default:
return AssistTypeNotSet
}
}
func convertVariableType(d DataType) (VariableType, error) {
switch d {
case DataTypeString, DataTypeTime, DataTypeFile:
return VariableTypeString, nil
case DataTypeNumber:
return VariableTypeFloat, nil
case DataTypeInteger:
return VariableTypeInteger, nil
case DataTypeBoolean:
return VariableTypeBoolean, nil
case DataTypeObject:
return VariableTypeObject, nil
case DataTypeArray:
return VariableTypeList, nil
default:
return "", fmt.Errorf("unknown variable type: %v", d)
}
}
func convertDataType(d DataType) schema.DataType {
switch d {
case DataTypeString, DataTypeTime, DataTypeFile:
return schema.String
case DataTypeNumber:
return schema.Number
case DataTypeInteger:
return schema.Integer
case DataTypeBoolean:
return schema.Boolean
case DataTypeObject:
return schema.Object
case DataTypeArray:
return schema.Array
default:
panic("unknown data type")
}
}
func TypeInfoToJSONSchema(tis map[string]*TypeInfo, structName *string) (string, error) {
schema_ := map[string]any{
"type": "object",
"properties": make(map[string]any),
"required": []string{},
}
if structName != nil {
schema_["title"] = *structName
}
properties := schema_["properties"].(map[string]any)
for key, typeInfo := range tis {
if typeInfo == nil {
continue
}
sc, err := typeInfoToJSONSchema(typeInfo)
if err != nil {
return "", err
}
properties[key] = sc
if typeInfo.Required {
schema_["required"] = append(schema_["required"].([]string), key)
}
}
jsonBytes, err := sonic.Marshal(schema_)
if err != nil {
return "", err
}
return string(jsonBytes), nil
}
func typeInfoToJSONSchema(info *TypeInfo) (map[string]interface{}, error) {
sc := make(map[string]interface{})
switch info.Type {
case DataTypeString:
sc["type"] = "string"
case DataTypeInteger:
sc["type"] = "integer"
case DataTypeNumber:
sc["type"] = "number"
case DataTypeBoolean:
sc["type"] = "boolean"
case DataTypeTime:
sc["type"] = "string"
sc["format"] = "date-time"
case DataTypeObject:
sc["type"] = "object"
case DataTypeArray:
sc["type"] = "array"
case DataTypeFile:
sc["type"] = "string"
if info.FileType != nil {
sc["contentMediaType"] = string(*info.FileType)
}
default:
return nil, fmt.Errorf("impossible")
}
if info.Desc != "" {
sc["description"] = info.Desc
}
if info.Type == DataTypeArray && info.ElemTypeInfo != nil {
itemsSchema, err := typeInfoToJSONSchema(info.ElemTypeInfo)
if err != nil {
return nil, fmt.Errorf("failed to convert array element type: %v", err)
}
sc["items"] = itemsSchema
}
if info.Type == DataTypeObject && info.Properties != nil {
properties := make(map[string]interface{})
required := make([]string, 0)
for name, propInfo := range info.Properties {
propSchema, err := typeInfoToJSONSchema(propInfo)
if err != nil {
return nil, fmt.Errorf("failed to convert property %s: %v", name, err)
}
properties[name] = propSchema
if propInfo.Required {
required = append(required, name)
}
}
sc["properties"] = properties
if len(required) > 0 {
sc["required"] = required
}
}
return sc, nil
}
type FileSubType string
const (
FileTypeDefault FileSubType = "default"
FileTypeImage FileSubType = "image"
FileTypeSVG FileSubType = "svg"
FileTypeAudio FileSubType = "audio"
FileTypeVideo FileSubType = "video"
FileTypeVoice FileSubType = "voice"
FileTypeDocument FileSubType = "doc"
FileTypePPT FileSubType = "ppt"
FileTypeExcel FileSubType = "excel"
FileTypeTxt FileSubType = "txt"
FileTypeCode FileSubType = "code"
FileTypeZip FileSubType = "zip"
)
type NodeProperty struct {
Type string
IsEnableChatHistory bool
IsEnableUserQuery bool
IsRefGlobalVariable bool
SubWorkflow map[string]*NodeProperty
}
func (f *FieldInfo) IsRefGlobalVariable() bool {
if f.Source.Ref != nil && f.Source.Ref.VariableType != nil {
return *f.Source.Ref.VariableType == GlobalUser || *f.Source.Ref.VariableType == GlobalSystem || *f.Source.Ref.VariableType == GlobalAPP
}
return false
}
func ParseVariable(v any) (*Variable, error) {
if va, ok := v.(*Variable); ok {
return va, nil
}
m, ok := v.(map[string]any)
if !ok {
return nil, fmt.Errorf("invalid content type: %T when parse Variable", v)
}
marshaled, err := sonic.Marshal(m)
if err != nil {
return nil, err
}
p := &Variable{}
if err := sonic.Unmarshal(marshaled, p); err != nil {
return nil, err
}
return p, nil
}
type GlobalVarType string
const (
ParentIntermediate GlobalVarType = "parent_intermediate"
GlobalUser GlobalVarType = "global_user"
GlobalSystem GlobalVarType = "global_system"
GlobalAPP GlobalVarType = "global_app"
)

View File

@@ -0,0 +1,147 @@
/*
* 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 (
"encoding/json"
"testing"
"github.com/stretchr/testify/assert"
)
func TestTypeInfoToJSONSchema(t *testing.T) {
tests := []struct {
name string
typeInfo map[string]*TypeInfo
validate func(t *testing.T, schema string)
}{
{
name: "Basic Data Types",
typeInfo: map[string]*TypeInfo{
"stringField": {Type: DataTypeString},
"intField": {Type: DataTypeInteger},
"numField": {Type: DataTypeNumber},
"boolField": {Type: DataTypeBoolean},
"timeField": {Type: DataTypeTime},
},
validate: func(t *testing.T, schema string) {
var schemaObj map[string]any
err := json.Unmarshal([]byte(schema), &schemaObj)
assert.NoError(t, err)
props := schemaObj["properties"].(map[string]any)
// 验证字符串字段
stringProp := props["stringField"].(map[string]any)
assert.Equal(t, "string", stringProp["type"])
// 验证整数字段
intProp := props["intField"].(map[string]any)
assert.Equal(t, "integer", intProp["type"])
// 验证数字字段
numProp := props["numField"].(map[string]any)
assert.Equal(t, "number", numProp["type"])
// 验证布尔字段
boolProp := props["boolField"].(map[string]any)
assert.Equal(t, "boolean", boolProp["type"])
// 验证时间字段
timeProp := props["timeField"].(map[string]any)
assert.Equal(t, "string", timeProp["type"])
assert.Equal(t, "date-time", timeProp["format"])
},
},
{
name: "Complex Data Types",
typeInfo: map[string]*TypeInfo{
"objectField": {Type: DataTypeObject},
"arrayField": {
Type: DataTypeArray,
ElemTypeInfo: &TypeInfo{Type: DataTypeString},
},
"fileField": {
Type: DataTypeFile,
FileType: fileSubTypePtr(FileTypeImage),
},
},
validate: func(t *testing.T, schema string) {
var schemaObj map[string]any
err := json.Unmarshal([]byte(schema), &schemaObj)
assert.NoError(t, err)
props := schemaObj["properties"].(map[string]any)
// 验证对象字段
objProp := props["objectField"].(map[string]any)
assert.Equal(t, "object", objProp["type"])
// 验证数组字段
arrProp := props["arrayField"].(map[string]any)
assert.Equal(t, "array", arrProp["type"])
items := arrProp["items"].(map[string]any)
assert.Equal(t, "string", items["type"])
// 验证文件字段
fileProp := props["fileField"].(map[string]any)
assert.Equal(t, "string", fileProp["type"])
assert.Equal(t, "image", fileProp["contentMediaType"])
},
},
{
name: "Nested Array",
typeInfo: map[string]*TypeInfo{
"nestedArray": {
Type: DataTypeArray,
ElemTypeInfo: &TypeInfo{Type: DataTypeObject},
},
},
validate: func(t *testing.T, schema string) {
var schemaObj map[string]any
err := json.Unmarshal([]byte(schema), &schemaObj)
assert.NoError(t, err)
props := schemaObj["properties"].(map[string]any)
// 验证嵌套数组字段
arrProp := props["nestedArray"].(map[string]any)
assert.Equal(t, "array", arrProp["type"])
items := arrProp["items"].(map[string]any)
assert.Equal(t, "object", items["type"])
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
schema, err := TypeInfoToJSONSchema(tt.typeInfo, nil)
assert.NoError(t, err)
tt.validate(t, schema)
})
}
}
// 辅助函数,用于创建 DataType 指针
func stringPtr(dt DataType) *DataType {
return &dt
}
// 辅助函数,用于创建 FileSubType 指针
func fileSubTypePtr(fst FileSubType) *FileSubType {
return &fst
}

View File

@@ -0,0 +1,50 @@
/*
* 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/coze-dev/coze-studio/backend/api/model/ocean/cloud/workflow"
"github.com/coze-dev/coze-studio/backend/pkg/sonic"
)
type WorkFlowAsToolInfo struct {
ID int64
Name string
Desc string
IconURL string
PublishStatus PublishStatus
VersionName string
CreatorID int64
InputParams []*NamedTypeInfo
CreatedAt int64
UpdatedAt *int64
}
type ToolDetailInfo struct {
ApiDetailData *workflow.ApiDetailData
ToolInputs any
ToolOutputs any
}
func (t *ToolDetailInfo) MarshalJSON() ([]byte, error) {
bs, _ := sonic.Marshal(t.ApiDetailData)
result := make(map[string]any)
_ = sonic.Unmarshal(bs, &result)
result["inputs"] = t.ToolInputs
result["outputs"] = t.ToolOutputs
return sonic.Marshal(result)
}

View File

@@ -0,0 +1,29 @@
/*
* 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 ValidateTreeConfig struct {
CanvasSchema string
AppID *int64
AgentID *int64
}
type ValidateIssue struct {
WorkflowName string
WorkflowID int64
IssueMessages []string
}

View File

@@ -0,0 +1,43 @@
/*
* 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 "time"
type VersionInfo struct {
*VersionMeta
CanvasInfo
CommitID string
}
type PublishPolicy struct {
ID int64
Version string
VersionDescription string
CreatorID int64
CommitID string
Force bool
}
type VersionMeta struct {
Version string
VersionDescription string
VersionCreatedAt time.Time
VersionCreatorID int64
}

View File

@@ -0,0 +1,43 @@
/*
* 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 PluginEntity struct {
PluginID int64
PluginVersion *string // nil or "0" means draft, "" means latest/online version, otherwise is specific version
}
type DependenceResource struct {
PluginIDs []int64
KnowledgeIDs []int64
DatabaseIDs []int64
}
type ExternalResourceRelated struct {
PluginMap map[int64]*PluginEntity
PluginToolMap map[int64]int64
KnowledgeMap map[int64]int64
DatabaseMap map[int64]int64
}
type CopyWorkflowPolicy struct {
TargetSpaceID *int64
TargetAppID *int64
ModifiedCanvasSchema *string
ShouldModifyWorkflowName bool
}

View File

@@ -0,0 +1,98 @@
/*
* 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/coze-dev/coze-studio/backend/api/model/ocean/cloud/workflow"
"github.com/coze-dev/coze-studio/backend/pkg/sonic"
)
type ReleasedWorkflowData struct {
WorkflowList []*workflow.ReleasedWorkflow
Inputs map[string]any
Outputs map[string]any
}
func (r *ReleasedWorkflowData) MarshalJSON() ([]byte, error) {
inputs := r.Inputs
outputs := r.Outputs
bs, _ := sonic.Marshal(r.WorkflowList)
workflowsListMap := make([]map[string]any, 0, len(r.WorkflowList))
_ = sonic.Unmarshal(bs, &workflowsListMap)
for _, m := range workflowsListMap {
if wId, ok := m["workflow_id"]; ok {
m["inputs"] = inputs[wId.(string)]
m["outputs"] = outputs[wId.(string)]
}
}
result := map[string]interface{}{
"workflow_list": workflowsListMap,
"total": len(r.WorkflowList),
}
return sonic.Marshal(result)
}
type WorkflowDetailDataList struct {
List []*workflow.WorkflowDetailData
Inputs map[string]any
Outputs map[string]any
}
func (r *WorkflowDetailDataList) MarshalJSON() ([]byte, error) {
inputs := r.Inputs
outputs := r.Outputs
bs, _ := sonic.Marshal(r.List)
wfList := make([]map[string]any, 0, len(r.List))
_ = sonic.Unmarshal(bs, &wfList)
for _, m := range wfList {
if wId, ok := m["workflow_id"]; ok {
m["inputs"] = inputs[wId.(string)]
m["outputs"] = outputs[wId.(string)]
}
}
return sonic.Marshal(wfList)
}
type WorkflowDetailInfoDataList struct {
List []*workflow.WorkflowDetailInfoData
Inputs map[string]any
Outputs map[string]any
}
func (r *WorkflowDetailInfoDataList) MarshalJSON() ([]byte, error) {
inputs := r.Inputs
outputs := r.Outputs
bs, _ := sonic.Marshal(r.List)
wfList := make([]map[string]any, 0, len(r.List))
_ = sonic.Unmarshal(bs, &wfList)
for _, m := range wfList {
if wId, ok := m["workflow_id"]; ok {
m["inputs"] = inputs[wId.(string)]
m["outputs"] = outputs[wId.(string)]
}
}
return sonic.Marshal(wfList)
}

View File

@@ -0,0 +1,24 @@
/*
* 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 ReleaseWorkflowConfig struct {
Version string
PluginIDs []int64
ConnectorIDs []int64
}

View File

@@ -0,0 +1,24 @@
/*
* 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/coze-dev/coze-studio/backend/api/model/ocean/cloud/workflow"
type WorkflowToolConfig struct {
InputParametersConfig []*workflow.APIParameter
OutputParametersConfig []*workflow.APIParameter
}

View File

@@ -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 entity
import (
"github.com/coze-dev/coze-studio/backend/api/model/ocean/cloud/workflow"
"github.com/coze-dev/coze-studio/backend/domain/workflow/entity/vo"
)
type ContentType = workflow.WorkFlowType
type Tag = workflow.Tag
type Mode = workflow.WorkflowMode
type Workflow struct {
ID int64
CommitID string
*vo.Meta
*vo.CanvasInfo
*vo.DraftMeta
*vo.VersionMeta
}
func (w *Workflow) GetBasic() *WorkflowBasic {
var version string
if w.VersionMeta != nil {
version = w.VersionMeta.Version
}
return &WorkflowBasic{
ID: w.ID,
Version: version,
SpaceID: w.SpaceID,
AppID: w.AppID,
CommitID: w.CommitID,
}
}
func (w *Workflow) GetLatestVersion() string {
if w.LatestPublishedVersion == nil {
return ""
}
return *w.LatestPublishedVersion
}
func (w *Workflow) GetVersion() string {
if w.VersionMeta == nil {
return ""
}
return w.VersionMeta.Version
}
type IDVersionPair struct {
ID int64
Version string
}
type Stage uint8
const (
StageDraft Stage = 1
StagePublished Stage = 2
)
type WorkflowBasic struct {
ID int64
Version string
SpaceID int64
AppID *int64
CommitID string
}

View File

@@ -0,0 +1,118 @@
/*
* 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"
"github.com/coze-dev/coze-studio/backend/api/model/ocean/cloud/workflow"
"github.com/coze-dev/coze-studio/backend/domain/workflow/entity/vo"
)
type WorkflowExecuteStatus workflow.WorkflowExeStatus
type NodeExecuteStatus workflow.NodeExeStatus
type WorkflowExecution struct {
ID int64
WorkflowID int64
Version string
SpaceID int64
vo.ExecuteConfig
CreatedAt time.Time
LogID string
NodeCount int32
CommitID string
Status WorkflowExecuteStatus
Duration time.Duration
Input *string
Output *string
ErrorCode *string
FailReason *string
TokenInfo *TokenUsage
UpdatedAt *time.Time
ParentNodeID *string
ParentNodeExecuteID *int64
NodeExecutions []*NodeExecution
RootExecutionID int64
CurrentResumingEventID *int64
InterruptEvents []*InterruptEvent
}
const (
WorkflowRunning = WorkflowExecuteStatus(workflow.WorkflowExeStatus_Running)
WorkflowSuccess = WorkflowExecuteStatus(workflow.WorkflowExeStatus_Success)
WorkflowFailed = WorkflowExecuteStatus(workflow.WorkflowExeStatus_Fail)
WorkflowCancel = WorkflowExecuteStatus(workflow.WorkflowExeStatus_Cancel)
WorkflowInterrupted = WorkflowExecuteStatus(5)
)
const (
NodeRunning = NodeExecuteStatus(workflow.NodeExeStatus_Running)
NodeSuccess = NodeExecuteStatus(workflow.NodeExeStatus_Success)
NodeFailed = NodeExecuteStatus(workflow.NodeExeStatus_Fail)
)
type TokenUsage struct {
InputTokens int64
OutputTokens int64
}
type NodeExecution struct {
ID int64
ExecuteID int64
NodeID string
NodeName string
NodeType NodeType
CreatedAt time.Time
Status NodeExecuteStatus
Duration time.Duration
Input *string
Output *string
RawOutput *string
ErrorInfo *string
ErrorLevel *string
TokenInfo *TokenUsage
UpdatedAt *time.Time
Index int
Items *string
ParentNodeID *string
SubWorkflowExecution *WorkflowExecution
IndexedExecutions []*NodeExecution
Extra *NodeExtra
}
type NodeExtra struct {
CurrentSubExecuteID int64 `json:"current_sub_execute_id,omitempty"`
ResponseExtra map[string]any `json:"response_extra,omitempty"`
SubExecuteID int64 `json:"subExecuteID,omitempty"` // for subworkflow node, the execute id of the sub workflow
}
type FCCalled struct {
Input string `json:"input,omitempty"`
Output string `json:"output,omitempty"`
}
type FCCalledDetail struct {
FCCalledList []*FCCalled `json:"fc_called_list,omitempty"`
}

View 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"
"github.com/coze-dev/coze-studio/backend/domain/workflow/entity/vo"
)
type WorkflowReference struct {
ID int64
WorkflowReferenceKey
CreatedAt time.Time
Enabled bool
}
type WorkflowReferenceKey struct {
ReferredID int64
ReferringID int64
vo.ReferType
vo.ReferringBizType
}