diff --git a/backend/api/handler/coze/workflow_service_test.go b/backend/api/handler/coze/workflow_service_test.go index ddc4708f..1d1868cd 100644 --- a/backend/api/handler/coze/workflow_service_test.go +++ b/backend/api/handler/coze/workflow_service_test.go @@ -67,17 +67,17 @@ import ( "github.com/coze-dev/coze-studio/backend/crossdomain/contract/knowledge/knowledgemock" crossmodelmgr "github.com/coze-dev/coze-studio/backend/crossdomain/contract/modelmgr" mockmodel "github.com/coze-dev/coze-studio/backend/crossdomain/contract/modelmgr/modelmock" + crossplugin "github.com/coze-dev/coze-studio/backend/crossdomain/contract/plugin" + "github.com/coze-dev/coze-studio/backend/crossdomain/contract/plugin/pluginmock" crossuser "github.com/coze-dev/coze-studio/backend/crossdomain/contract/user" "github.com/coze-dev/coze-studio/backend/crossdomain/impl/code" - plugin3 "github.com/coze-dev/coze-studio/backend/crossdomain/workflow/plugin" + pluginImpl "github.com/coze-dev/coze-studio/backend/crossdomain/impl/plugin" entity4 "github.com/coze-dev/coze-studio/backend/domain/memory/database/entity" entity2 "github.com/coze-dev/coze-studio/backend/domain/openauth/openapiauth/entity" entity3 "github.com/coze-dev/coze-studio/backend/domain/plugin/entity" entity5 "github.com/coze-dev/coze-studio/backend/domain/plugin/entity" userentity "github.com/coze-dev/coze-studio/backend/domain/user/entity" workflow2 "github.com/coze-dev/coze-studio/backend/domain/workflow" - "github.com/coze-dev/coze-studio/backend/domain/workflow/crossdomain/plugin" - "github.com/coze-dev/coze-studio/backend/domain/workflow/crossdomain/plugin/pluginmock" crosssearch "github.com/coze-dev/coze-studio/backend/domain/workflow/crossdomain/search" "github.com/coze-dev/coze-studio/backend/domain/workflow/crossdomain/search/searchmock" "github.com/coze-dev/coze-studio/backend/domain/workflow/crossdomain/variable" @@ -125,7 +125,7 @@ type wfTestRunner struct { tos *storageMock.MockStorage knowledge *knowledgemock.MockKnowledge database *databasemock.MockDatabase - pluginSrv *pluginmock.MockService + pluginSrv *pluginmock.MockPluginService internalModel *testutil.UTChatModel ctx context.Context closeFn func() @@ -296,8 +296,8 @@ func newWfTestRunner(t *testing.T) *wfTestRunner { mockDatabaseOperator := databasemock.NewMockDatabase(ctrl) crossdatabase.SetDefaultSVC(mockDatabaseOperator) - mockPluginSrv := pluginmock.NewMockService(ctrl) - plugin.SetPluginService(mockPluginSrv) + mockPluginSrv := pluginmock.NewMockPluginService(ctrl) + crossplugin.SetDefaultSVC(mockPluginSrv) mockey.Mock((*user.UserApplicationService).MGetUserBasicInfo).Return(&playground.MGetUserBasicInfoResponse{ UserBasicInfoMap: make(map[string]*playground.UserBasicInfo), @@ -2876,9 +2876,8 @@ func TestLLMWithSkills(t *testing.T) { {ID: int64(7509353598782816256), Operation: operation}, }, nil).AnyTimes() - pluginSrv := plugin3.NewPluginService(r.plugin, r.tos) - - plugin.SetPluginService(pluginSrv) + pluginSrv := pluginImpl.InitDomainService(r.plugin, r.tos) + crossplugin.SetDefaultSVC(pluginSrv) t.Run("llm with plugin tool", func(t *testing.T) { id := r.load("llm_node_with_skills/llm_node_with_plugin_tool.json") @@ -3414,8 +3413,8 @@ func TestGetLLMNodeFCSettingsDetailAndMerged(t *testing.T) { {ID: 123, Operation: operation}, }, nil).AnyTimes() - pluginSrv := plugin3.NewPluginService(r.plugin, r.tos) - plugin.SetPluginService(pluginSrv) + pluginSrv := pluginImpl.InitDomainService(r.plugin, r.tos) + crossplugin.SetDefaultSVC(pluginSrv) t.Run("plugin tool info ", func(t *testing.T) { fcSettingDetailReq := &workflow.GetLLMNodeFCSettingDetailRequest{ @@ -3531,8 +3530,8 @@ func TestGetLLMNodeFCSettingsDetailAndMerged(t *testing.T) { {ID: 123, Operation: operation}, }, nil).AnyTimes() - pluginSrv := plugin3.NewPluginService(r.plugin, r.tos) - plugin.SetPluginService(pluginSrv) + pluginSrv := pluginImpl.InitDomainService(r.plugin, r.tos) + crossplugin.SetDefaultSVC(pluginSrv) t.Run("plugin merge", func(t *testing.T) { fcSettingMergedReq := &workflow.GetLLMNodeFCSettingsMergedRequest{ @@ -3698,7 +3697,7 @@ func TestCopyWorkflow(t *testing.T) { _, err := appworkflow.GetWorkflowDomainSVC().Get(context.Background(), &vo.GetPolicy{ ID: wid, - QType: vo.FromDraft, + QType: plugin2.FromDraft, CommitID: "", }) assert.NotNil(t, err) @@ -3760,7 +3759,7 @@ func TestReleaseApplicationWorkflows(t *testing.T) { wf, err = appworkflow.GetWorkflowDomainSVC().Get(context.Background(), &vo.GetPolicy{ ID: 100100100100, - QType: vo.FromSpecificVersion, + QType: plugin2.FromSpecificVersion, Version: version, }) assert.NoError(t, err) @@ -4054,7 +4053,7 @@ func TestCopyWorkflowAppToLibrary(t *testing.T) { } wf, err := appworkflow.GetWorkflowDomainSVC().Get(ctx, &vo.GetPolicy{ ID: event.WorkflowID, - QType: vo.FromLatestVersion, + QType: plugin2.FromLatestVersion, }) copiedIDs = append(copiedIDs, event.WorkflowID) assert.NoError(t, err) @@ -4096,7 +4095,7 @@ func TestCopyWorkflowAppToLibrary(t *testing.T) { subWf, err := appworkflow.GetWorkflowDomainSVC().Get(ctx, &vo.GetPolicy{ ID: wfId, - QType: vo.FromLatestVersion, + QType: plugin2.FromLatestVersion, }) assert.NoError(t, err) subworkflowCanvas := &vo.Canvas{} @@ -4199,7 +4198,7 @@ func TestCopyWorkflowAppToLibrary(t *testing.T) { } wf, err := appworkflow.GetWorkflowDomainSVC().Get(ctx, &vo.GetPolicy{ ID: event.WorkflowID, - QType: vo.FromLatestVersion, + QType: plugin2.FromLatestVersion, }) copiedIDs = append(copiedIDs, event.WorkflowID) diff --git a/backend/api/model/crossdomain/plugin/workflow.go b/backend/api/model/crossdomain/plugin/workflow.go new file mode 100644 index 00000000..e232a840 --- /dev/null +++ b/backend/api/model/crossdomain/plugin/workflow.go @@ -0,0 +1,154 @@ +/* + * 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 plugin + +import ( + "github.com/coze-dev/coze-studio/backend/api/model/workflow" +) + +type ToolsInfoRequest struct { + PluginEntity PluginEntity + ToolIDs []int64 + IsDraft bool +} + +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 +} + +type ToolsInfoResponse struct { + PluginID int64 + SpaceID int64 + Version string + PluginName string + Description string + IconURL string + PluginType int64 + ToolInfoList map[int64]ToolInfoW + LatestVersion *string + IsOfficial bool + AppID int64 +} + +type ToolInfoW struct { + ToolName string + ToolID int64 + Description string + DebugExample *DebugExample + + Inputs []*workflow.APIParameter + Outputs []*workflow.APIParameter +} + +type DebugExample struct { + ReqExample string + RespExample string +} + +type ToolsInvokableRequest struct { + PluginEntity PluginEntity + ToolsInvokableInfo map[int64]*ToolsInvokableInfo + IsDraft bool +} + +type WorkflowAPIParameters = []*workflow.APIParameter + +type ToolsInvokableInfo struct { + ToolID int64 + RequestAPIParametersConfig WorkflowAPIParameters + ResponseAPIParametersConfig WorkflowAPIParameters +} + +type Locator uint8 + +const ( + FromDraft Locator = iota + FromSpecificVersion + FromLatestVersion +) + +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" +) diff --git a/backend/application/application.go b/backend/application/application.go index d841f6ec..cc806af2 100644 --- a/backend/application/application.go +++ b/backend/application/application.go @@ -131,7 +131,7 @@ func Init(ctx context.Context) (err error) { crossconnector.SetDefaultSVC(connectorImpl.InitDomainService(basicServices.connectorSVC.DomainSVC)) crossdatabase.SetDefaultSVC(databaseImpl.InitDomainService(primaryServices.memorySVC.DatabaseDomainSVC)) crossknowledge.SetDefaultSVC(knowledgeImpl.InitDomainService(primaryServices.knowledgeSVC.DomainSVC)) - crossplugin.SetDefaultSVC(pluginImpl.InitDomainService(primaryServices.pluginSVC.DomainSVC)) + crossplugin.SetDefaultSVC(pluginImpl.InitDomainService(primaryServices.pluginSVC.DomainSVC, infra.TOSClient)) crossvariables.SetDefaultSVC(variablesImpl.InitDomainService(primaryServices.memorySVC.VariablesDomainSVC)) crossworkflow.SetDefaultSVC(workflowImpl.InitDomainService(primaryServices.workflowSVC.DomainSVC)) crossconversation.SetDefaultSVC(conversationImpl.InitDomainService(complexServices.conversationSVC.ConversationDomainSVC)) @@ -142,6 +142,7 @@ func Init(ctx context.Context) (err error) { crossdatacopy.SetDefaultSVC(dataCopyImpl.InitDomainService(basicServices.infra)) crosssearch.SetDefaultSVC(searchImpl.InitDomainService(complexServices.searchSVC.DomainSVC)) crossmodelmgr.SetDefaultSVC(modelmgrImpl.InitDomainService(infra.ModelMgr, nil)) + return nil } diff --git a/backend/application/singleagent/get.go b/backend/application/singleagent/get.go index 41ca6b1f..0a722dc7 100644 --- a/backend/application/singleagent/get.go +++ b/backend/application/singleagent/get.go @@ -240,7 +240,7 @@ func (s *SingleAgentApplicationService) fetchWorkflowDetails(ctx context.Context return a.GetWorkflowId() }), }, - QType: vo.FromLatestVersion, + QType: plugin.FromLatestVersion, } ret, _, err := s.appContext.WorkflowDomainSVC.MGet(ctx, policy) if err != nil { diff --git a/backend/application/workflow/init.go b/backend/application/workflow/init.go index 78a84834..4de6bf14 100644 --- a/backend/application/workflow/init.go +++ b/backend/application/workflow/init.go @@ -25,7 +25,6 @@ import ( "github.com/coze-dev/coze-studio/backend/application/internal" "github.com/coze-dev/coze-studio/backend/crossdomain/impl/code" - wfplugin "github.com/coze-dev/coze-studio/backend/crossdomain/workflow/plugin" wfsearch "github.com/coze-dev/coze-studio/backend/crossdomain/workflow/search" "github.com/coze-dev/coze-studio/backend/crossdomain/workflow/variable" knowledge "github.com/coze-dev/coze-studio/backend/domain/knowledge/service" @@ -35,7 +34,6 @@ import ( search "github.com/coze-dev/coze-studio/backend/domain/search/service" "github.com/coze-dev/coze-studio/backend/domain/workflow" - crossplugin "github.com/coze-dev/coze-studio/backend/domain/workflow/crossdomain/plugin" crosssearch "github.com/coze-dev/coze-studio/backend/domain/workflow/crossdomain/search" crossvariable "github.com/coze-dev/coze-studio/backend/domain/workflow/crossdomain/variable" "github.com/coze-dev/coze-studio/backend/domain/workflow/service" @@ -81,7 +79,6 @@ func InitService(ctx context.Context, components *ServiceComponents) (*Applicati workflowDomainSVC := service.NewWorkflowService(workflowRepo) crossvariable.SetVariableHandler(variable.NewVariableHandler(components.VariablesDomainSVC)) crossvariable.SetVariablesMetaGetter(variable.NewVariablesMetaGetter(components.VariablesDomainSVC)) - crossplugin.SetPluginService(wfplugin.NewPluginService(components.PluginDomainSVC, components.Tos)) code.SetCodeRunner(components.CodeRunner) crosssearch.SetNotifier(wfsearch.NewNotify(components.DomainNotifier)) callbacks.AppendGlobalHandlers(workflowservice.GetTokenCallbackHandler()) diff --git a/backend/application/workflow/workflow.go b/backend/application/workflow/workflow.go index 98f3a2c8..abf7ddc7 100644 --- a/backend/application/workflow/workflow.go +++ b/backend/application/workflow/workflow.go @@ -30,6 +30,7 @@ import ( "github.com/coze-dev/coze-studio/backend/api/model/app/bot_common" model "github.com/coze-dev/coze-studio/backend/api/model/crossdomain/knowledge" + "github.com/coze-dev/coze-studio/backend/api/model/crossdomain/plugin" pluginmodel "github.com/coze-dev/coze-studio/backend/api/model/crossdomain/plugin" "github.com/coze-dev/coze-studio/backend/api/model/data/database/table" "github.com/coze-dev/coze-studio/backend/api/model/playground" @@ -42,10 +43,11 @@ import ( appplugin "github.com/coze-dev/coze-studio/backend/application/plugin" "github.com/coze-dev/coze-studio/backend/application/user" crossknowledge "github.com/coze-dev/coze-studio/backend/crossdomain/contract/knowledge" + crossplugin "github.com/coze-dev/coze-studio/backend/crossdomain/contract/plugin" + crossuser "github.com/coze-dev/coze-studio/backend/crossdomain/contract/user" domainWorkflow "github.com/coze-dev/coze-studio/backend/domain/workflow" workflowDomain "github.com/coze-dev/coze-studio/backend/domain/workflow" - crossplugin "github.com/coze-dev/coze-studio/backend/domain/workflow/crossdomain/plugin" "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" @@ -334,7 +336,7 @@ func (w *ApplicationService) GetCanvasInfo(ctx context.Context, req *workflow.Ge wf, err := GetWorkflowDomainSVC().Get(ctx, &vo.GetPolicy{ ID: mustParseInt64(req.GetWorkflowID()), - QType: vo.FromDraft, + QType: plugin.FromDraft, }) if err != nil { return nil, err @@ -430,19 +432,19 @@ func (w *ApplicationService) TestRun(ctx context.Context, req *workflow.WorkFlow agentID = ptr.Of(mustParseInt64(req.GetBotID())) } - exeCfg := vo.ExecuteConfig{ + exeCfg := plugin.ExecuteConfig{ ID: mustParseInt64(req.GetWorkflowID()), - From: vo.FromDraft, + From: plugin.FromDraft, CommitID: req.GetCommitID(), Operator: uID, - Mode: vo.ExecuteModeDebug, + Mode: plugin.ExecuteModeDebug, AppID: appID, AgentID: agentID, ConnectorID: consts.CozeConnectorID, ConnectorUID: strconv.FormatInt(uID, 10), - TaskType: vo.TaskTypeForeground, - SyncPattern: vo.SyncPatternAsync, - BizType: vo.BizTypeWorkflow, + TaskType: plugin.TaskTypeForeground, + SyncPattern: plugin.SyncPatternAsync, + BizType: plugin.BizTypeWorkflow, Cancellable: true, } @@ -502,18 +504,18 @@ func (w *ApplicationService) NodeDebug(ctx context.Context, req *workflow.Workfl agentID = ptr.Of(mustParseInt64(req.GetBotID())) } - exeCfg := vo.ExecuteConfig{ + exeCfg := plugin.ExecuteConfig{ ID: mustParseInt64(req.GetWorkflowID()), - From: vo.FromDraft, + From: plugin.FromDraft, Operator: uID, - Mode: vo.ExecuteModeNodeDebug, + Mode: plugin.ExecuteModeNodeDebug, AppID: appID, AgentID: agentID, ConnectorID: consts.CozeConnectorID, ConnectorUID: strconv.FormatInt(uID, 10), - TaskType: vo.TaskTypeForeground, - SyncPattern: vo.SyncPatternAsync, - BizType: vo.BizTypeWorkflow, + TaskType: plugin.TaskTypeForeground, + SyncPattern: plugin.SyncPatternAsync, + BizType: plugin.BizTypeWorkflow, Cancellable: true, } @@ -865,7 +867,7 @@ func (w *ApplicationService) CheckWorkflowsExistByAppID(ctx context.Context, app Page: 0, }, }, - QType: vo.FromDraft, + QType: plugin.FromDraft, MetaOnly: true, }) @@ -890,7 +892,7 @@ func (w *ApplicationService) CopyWorkflowFromAppToLibrary(ctx context.Context, w return 0, nil, err } - pluginMap := make(map[int64]*vo.PluginEntity) + pluginMap := make(map[int64]*plugin.PluginEntity) pluginToolMap := make(map[int64]int64) if len(ds.PluginIDs) > 0 { @@ -905,7 +907,7 @@ func (w *ApplicationService) CopyWorkflowFromAppToLibrary(ctx context.Context, w return 0, nil, err } pInfo := response.Plugin - pluginMap[id] = &vo.PluginEntity{ + pluginMap[id] = &plugin.PluginEntity{ PluginID: pInfo.ID, PluginVersion: pInfo.Version, } @@ -957,7 +959,7 @@ func (w *ApplicationService) CopyWorkflowFromAppToLibrary(ctx context.Context, w } - relatedWorkflows, vIssues, err := GetWorkflowDomainSVC().CopyWorkflowFromAppToLibrary(ctx, workflowID, appID, vo.ExternalResourceRelated{ + relatedWorkflows, vIssues, err := GetWorkflowDomainSVC().CopyWorkflowFromAppToLibrary(ctx, workflowID, appID, plugin.ExternalResourceRelated{ PluginMap: pluginMap, PluginToolMap: pluginToolMap, KnowledgeMap: relatedKnowledgeMap, @@ -997,13 +999,13 @@ func (w *ApplicationService) DuplicateWorkflowsByAppID(ctx context.Context, sour } }() - pluginMap := make(map[int64]*vo.PluginEntity) + pluginMap := make(map[int64]*plugin.PluginEntity) for o, n := range externalResource.PluginMap { - pluginMap[o] = &vo.PluginEntity{ + pluginMap[o] = &plugin.PluginEntity{ PluginID: n, } } - externalResourceRelated := vo.ExternalResourceRelated{ + externalResourceRelated := plugin.ExternalResourceRelated{ PluginMap: pluginMap, PluginToolMap: externalResource.PluginToolMap, KnowledgeMap: externalResource.KnowledgeMap, @@ -1026,7 +1028,7 @@ func (w *ApplicationService) CopyWorkflowFromLibraryToApp(ctx context.Context, w } }() - wf, err := GetWorkflowDomainSVC().CopyWorkflow(ctx, workflowID, vo.CopyWorkflowPolicy{ + wf, err := GetWorkflowDomainSVC().CopyWorkflow(ctx, workflowID, plugin.CopyWorkflowPolicy{ TargetAppID: &appID, }) if err != nil { @@ -1053,7 +1055,7 @@ func (w *ApplicationService) MoveWorkflowFromAppToLibrary(ctx context.Context, w return 0, nil, err } - pluginMap := make(map[int64]*vo.PluginEntity) + pluginMap := make(map[int64]*plugin.PluginEntity) if len(ds.PluginIDs) > 0 { for idx := range ds.PluginIDs { id := ds.PluginIDs[idx] @@ -1061,7 +1063,7 @@ func (w *ApplicationService) MoveWorkflowFromAppToLibrary(ctx context.Context, w if err != nil { return 0, nil, err } - pluginMap[id] = &vo.PluginEntity{ + pluginMap[id] = &plugin.PluginEntity{ PluginID: pInfo.ID, PluginVersion: pInfo.Version, } @@ -1090,7 +1092,7 @@ func (w *ApplicationService) MoveWorkflowFromAppToLibrary(ctx context.Context, w } } - relatedWorkflows, vIssues, err := GetWorkflowDomainSVC().CopyWorkflowFromAppToLibrary(ctx, workflowID, appID, vo.ExternalResourceRelated{ + relatedWorkflows, vIssues, err := GetWorkflowDomainSVC().CopyWorkflowFromAppToLibrary(ctx, workflowID, appID, plugin.ExternalResourceRelated{ PluginMap: pluginMap, }) if err != nil { @@ -1100,7 +1102,7 @@ func (w *ApplicationService) MoveWorkflowFromAppToLibrary(ctx context.Context, w return 0, vIssues, nil } - err = GetWorkflowDomainSVC().SyncRelatedWorkflowResources(ctx, appID, relatedWorkflows, vo.ExternalResourceRelated{ + err = GetWorkflowDomainSVC().SyncRelatedWorkflowResources(ctx, appID, relatedWorkflows, plugin.ExternalResourceRelated{ PluginMap: pluginMap, }) if err != nil { @@ -1249,7 +1251,7 @@ func convertStreamRunEvent(workflowID int64) func(msg *entity.Message) (res *wor return &workflow.OpenAPIStreamRunFlowResponse{ ID: strconv.Itoa(messageID), Event: string(DoneEvent), - DebugUrl: ptr.Of(fmt.Sprintf(vo.DebugURLTpl, executeID, spaceID, workflowID)), + DebugUrl: ptr.Of(fmt.Sprintf(plugin.DebugURLTpl, executeID, spaceID, workflowID)), }, nil case entity.WorkflowFailed, entity.WorkflowCancel: var wfe vo.WorkflowError @@ -1259,7 +1261,7 @@ func convertStreamRunEvent(workflowID int64) func(msg *entity.Message) (res *wor return &workflow.OpenAPIStreamRunFlowResponse{ ID: strconv.Itoa(messageID), Event: string(ErrEvent), - DebugUrl: ptr.Of(fmt.Sprintf(vo.DebugURLTpl, executeID, spaceID, workflowID)), + DebugUrl: ptr.Of(fmt.Sprintf(plugin.DebugURLTpl, executeID, spaceID, workflowID)), ErrorCode: ptr.Of(int64(wfe.Code())), ErrorMessage: ptr.Of(wfe.Msg()), }, nil @@ -1268,7 +1270,7 @@ func convertStreamRunEvent(workflowID int64) func(msg *entity.Message) (res *wor return &workflow.OpenAPIStreamRunFlowResponse{ ID: strconv.Itoa(messageID), Event: string(InterruptEvent), - DebugUrl: ptr.Of(fmt.Sprintf(vo.DebugURLTpl, executeID, spaceID, workflowID)), + DebugUrl: ptr.Of(fmt.Sprintf(plugin.DebugURLTpl, executeID, spaceID, workflowID)), InterruptData: &workflow.Interrupt{ EventID: fmt.Sprintf("%d/%d", executeID, msg.InterruptEvent.ID), Type: workflow.InterruptType(msg.InterruptEvent.EventType), @@ -1280,7 +1282,7 @@ func convertStreamRunEvent(workflowID int64) func(msg *entity.Message) (res *wor return &workflow.OpenAPIStreamRunFlowResponse{ ID: strconv.Itoa(messageID), Event: string(InterruptEvent), - DebugUrl: ptr.Of(fmt.Sprintf(vo.DebugURLTpl, executeID, spaceID, workflowID)), + DebugUrl: ptr.Of(fmt.Sprintf(plugin.DebugURLTpl, executeID, spaceID, workflowID)), InterruptData: &workflow.Interrupt{ EventID: fmt.Sprintf("%d/%d", executeID, msg.InterruptEvent.ID), Type: workflow.InterruptType(msg.InterruptEvent.ToolInterruptEvent.EventType), @@ -1396,20 +1398,20 @@ func (w *ApplicationService) OpenAPIStreamRun(ctx context.Context, req *workflow connectorID = apiKeyInfo.ConnectorID } - exeCfg := vo.ExecuteConfig{ + exeCfg := plugin.ExecuteConfig{ ID: meta.ID, - From: vo.FromSpecificVersion, + From: plugin.FromSpecificVersion, Version: *meta.LatestPublishedVersion, Operator: userID, - Mode: vo.ExecuteModeRelease, + Mode: plugin.ExecuteModeRelease, AppID: appID, AgentID: agentID, ConnectorID: connectorID, ConnectorUID: strconv.FormatInt(userID, 10), - TaskType: vo.TaskTypeForeground, - SyncPattern: vo.SyncPatternStream, + TaskType: plugin.TaskTypeForeground, + SyncPattern: plugin.SyncPatternStream, InputFailFast: true, - BizType: vo.BizTypeWorkflow, + BizType: plugin.BizTypeWorkflow, } if exeCfg.AppID != nil && exeCfg.AgentID != nil { @@ -1470,12 +1472,12 @@ func (w *ApplicationService) OpenAPIStreamResume(ctx context.Context, req *workf connectorID = mustParseInt64(req.GetConnectorID()) } - sr, err := GetWorkflowDomainSVC().StreamResume(ctx, resumeReq, vo.ExecuteConfig{ + sr, err := GetWorkflowDomainSVC().StreamResume(ctx, resumeReq, plugin.ExecuteConfig{ Operator: userID, - Mode: vo.ExecuteModeRelease, + Mode: plugin.ExecuteModeRelease, ConnectorID: connectorID, ConnectorUID: strconv.FormatInt(userID, 10), - BizType: vo.BizTypeWorkflow, + BizType: plugin.BizTypeWorkflow, }) if err != nil { return nil, err @@ -1545,18 +1547,18 @@ func (w *ApplicationService) OpenAPIRun(ctx context.Context, req *workflow.OpenA connectorID = apiKeyInfo.ConnectorID } - exeCfg := vo.ExecuteConfig{ + exeCfg := plugin.ExecuteConfig{ ID: meta.ID, - From: vo.FromSpecificVersion, + From: plugin.FromSpecificVersion, Version: *meta.LatestPublishedVersion, Operator: userID, - Mode: vo.ExecuteModeRelease, + Mode: plugin.ExecuteModeRelease, AppID: appID, AgentID: agentID, ConnectorID: connectorID, ConnectorUID: strconv.FormatInt(userID, 10), InputFailFast: true, - BizType: vo.BizTypeWorkflow, + BizType: plugin.BizTypeWorkflow, } if exeCfg.AppID != nil && exeCfg.AgentID != nil { @@ -1564,8 +1566,8 @@ func (w *ApplicationService) OpenAPIRun(ctx context.Context, req *workflow.OpenA } if req.GetIsAsync() { - exeCfg.SyncPattern = vo.SyncPatternAsync - exeCfg.TaskType = vo.TaskTypeBackground + exeCfg.SyncPattern = plugin.SyncPatternAsync + exeCfg.TaskType = plugin.TaskTypeBackground exeID, err := GetWorkflowDomainSVC().AsyncExecute(ctx, exeCfg, parameters) if err != nil { return nil, err @@ -1573,12 +1575,12 @@ func (w *ApplicationService) OpenAPIRun(ctx context.Context, req *workflow.OpenA return &workflow.OpenAPIRunFlowResponse{ ExecuteID: ptr.Of(strconv.FormatInt(exeID, 10)), - DebugUrl: ptr.Of(fmt.Sprintf(vo.DebugURLTpl, exeID, meta.SpaceID, meta.ID)), + DebugUrl: ptr.Of(fmt.Sprintf(plugin.DebugURLTpl, exeID, meta.SpaceID, meta.ID)), }, nil } - exeCfg.SyncPattern = vo.SyncPatternSync - exeCfg.TaskType = vo.TaskTypeForeground + exeCfg.SyncPattern = plugin.SyncPatternSync + exeCfg.TaskType = plugin.TaskTypeForeground wfExe, tPlan, err := GetWorkflowDomainSVC().SyncExecute(ctx, exeCfg, parameters) if err != nil { return nil, err @@ -1609,7 +1611,7 @@ func (w *ApplicationService) OpenAPIRun(ctx context.Context, req *workflow.OpenA return &workflow.OpenAPIRunFlowResponse{ Data: data, ExecuteID: ptr.Of(strconv.FormatInt(wfExe.ID, 10)), - DebugUrl: ptr.Of(fmt.Sprintf(vo.DebugURLTpl, wfExe.ID, wfExe.SpaceID, meta.ID)), + DebugUrl: ptr.Of(fmt.Sprintf(plugin.DebugURLTpl, wfExe.ID, wfExe.SpaceID, meta.ID)), Token: ptr.Of(wfExe.TokenInfo.InputTokens + wfExe.TokenInfo.OutputTokens), Cost: ptr.Of("0.00000"), }, nil @@ -1649,11 +1651,11 @@ func (w *ApplicationService) OpenAPIGetWorkflowRunHistory(ctx context.Context, r var runMode *workflow.WorkflowRunMode switch exe.SyncPattern { - case vo.SyncPatternSync: + case plugin.SyncPatternSync: runMode = ptr.Of(workflow.WorkflowRunMode_Sync) - case vo.SyncPatternAsync: + case plugin.SyncPatternAsync: runMode = ptr.Of(workflow.WorkflowRunMode_Async) - case vo.SyncPatternStream: + case plugin.SyncPatternStream: runMode = ptr.Of(workflow.WorkflowRunMode_Stream) default: } @@ -1670,7 +1672,7 @@ func (w *ApplicationService) OpenAPIGetWorkflowRunHistory(ctx context.Context, r LogID: ptr.Of(exe.LogID), CreateTime: ptr.Of(exe.CreatedAt.Unix()), UpdateTime: updateTime, - DebugUrl: ptr.Of(fmt.Sprintf(vo.DebugURLTpl, exe.ID, exe.SpaceID, exe.WorkflowID)), + DebugUrl: ptr.Of(fmt.Sprintf(plugin.DebugURLTpl, exe.ID, exe.SpaceID, exe.WorkflowID)), Input: exe.Input, Output: exe.Output, Token: ptr.Of(exe.TokenInfo.InputTokens + exe.TokenInfo.OutputTokens), @@ -1804,10 +1806,10 @@ func (w *ApplicationService) TestResume(ctx context.Context, req *workflow.Workf EventID: mustParseInt64(req.GetEventID()), ResumeData: req.GetData(), } - err = GetWorkflowDomainSVC().AsyncResume(ctx, resumeReq, vo.ExecuteConfig{ + err = GetWorkflowDomainSVC().AsyncResume(ctx, resumeReq, plugin.ExecuteConfig{ Operator: ptr.FromOrDefault(ctxutil.GetUIDFromCtx(ctx), 0), - Mode: vo.ExecuteModeDebug, // at this stage it could be debug or node debug, we will decide it within AsyncResume - BizType: vo.BizTypeWorkflow, + Mode: plugin.ExecuteModeDebug, // at this stage it could be debug or node debug, we will decide it within AsyncResume + BizType: plugin.BizTypeWorkflow, Cancellable: true, }) if err != nil { @@ -2002,13 +2004,13 @@ func (w *ApplicationService) ListWorkflow(ctx context.Context, req *workflow.Get } status := req.GetStatus() - var qType vo.Locator + var qType plugin.Locator if status == workflow.WorkFlowListStatus_UnPublished { option.PublishStatus = ptr.Of(vo.UnPublished) - qType = vo.FromDraft + qType = plugin.FromDraft } else if status == workflow.WorkFlowListStatus_HadPublished { option.PublishStatus = ptr.Of(vo.HasPublished) - qType = vo.FromLatestVersion + qType = plugin.FromLatestVersion } if len(req.GetName()) > 0 { @@ -2076,9 +2078,9 @@ func (w *ApplicationService) ListWorkflow(ctx context.Context, req *workflow.Get }, } - if qType == vo.FromDraft { + if qType == plugin.FromDraft { ww.UpdateTime = w.DraftMeta.Timestamp.Unix() - } else if qType == vo.FromLatestVersion || qType == vo.FromSpecificVersion { + } else if qType == plugin.FromLatestVersion || qType == plugin.FromSpecificVersion { ww.UpdateTime = w.VersionMeta.VersionCreatedAt.Unix() } else if w.UpdatedAt != nil { ww.UpdateTime = w.UpdatedAt.Unix() @@ -2163,7 +2165,7 @@ func (w *ApplicationService) GetWorkflowDetail(ctx context.Context, req *workflo MetaQuery: vo.MetaQuery{ IDs: ids, }, - QType: vo.FromDraft, + QType: plugin.FromDraft, MetaOnly: false, }) if err != nil { @@ -2269,7 +2271,7 @@ func (w *ApplicationService) GetWorkflowDetailInfo(ctx context.Context, req *wor MetaQuery: vo.MetaQuery{ IDs: draftIDs, }, - QType: vo.FromDraft, + QType: plugin.FromDraft, MetaOnly: false, }) if err != nil { @@ -2282,7 +2284,7 @@ func (w *ApplicationService) GetWorkflowDetailInfo(ctx context.Context, req *wor MetaQuery: vo.MetaQuery{ IDs: versionIDs, }, - QType: vo.FromSpecificVersion, + QType: plugin.FromSpecificVersion, MetaOnly: false, Versions: id2Version, }) @@ -2483,8 +2485,8 @@ func (w *ApplicationService) GetApiDetail(ctx context.Context, req *workflow.Get return nil, err } - toolInfoResponse, err := crossplugin.GetPluginService().GetPluginToolsInfo(ctx, &crossplugin.ToolsInfoRequest{ - PluginEntity: crossplugin.Entity{ + toolInfoResponse, err := crossplugin.DefaultSVC().GetPluginToolsInfo(ctx, &plugin.ToolsInfoRequest{ + PluginEntity: plugin.PluginEntity{ PluginID: pluginID, PluginVersion: req.PluginVersion, }, @@ -2550,8 +2552,8 @@ func (w *ApplicationService) GetLLMNodeFCSettingDetail(ctx context.Context, req } var ( - pluginSvc = crossplugin.GetPluginService() - pluginToolsInfoReqs = make(map[int64]*crossplugin.ToolsInfoRequest) + pluginSvc = crossplugin.DefaultSVC() + pluginToolsInfoReqs = make(map[int64]*plugin.ToolsInfoRequest) pluginDetailMap = make(map[string]*workflow.PluginDetail) toolsDetailInfo = make(map[string]*workflow.APIDetail) workflowDetailMap = make(map[string]*workflow.WorkflowDetail) @@ -2573,8 +2575,8 @@ func (w *ApplicationService) GetLLMNodeFCSettingDetail(ctx context.Context, req if r, ok := pluginToolsInfoReqs[pluginID]; ok { r.ToolIDs = append(r.ToolIDs, toolID) } else { - pluginToolsInfoReqs[pluginID] = &crossplugin.ToolsInfoRequest{ - PluginEntity: crossplugin.Entity{ + pluginToolsInfoReqs[pluginID] = &plugin.ToolsInfoRequest{ + PluginEntity: plugin.PluginEntity{ PluginID: pluginID, PluginVersion: pl.PluginVersion, }, @@ -2655,7 +2657,7 @@ func (w *ApplicationService) GetLLMNodeFCSettingDetail(ctx context.Context, req MetaQuery: vo.MetaQuery{ IDs: draftIDs, }, - QType: vo.FromDraft, + QType: plugin.FromDraft, MetaOnly: false, }) if err != nil { @@ -2668,7 +2670,7 @@ func (w *ApplicationService) GetLLMNodeFCSettingDetail(ctx context.Context, req MetaQuery: vo.MetaQuery{ IDs: versionIDs, }, - QType: vo.FromSpecificVersion, + QType: plugin.FromSpecificVersion, MetaOnly: false, Versions: id2Version, }) @@ -2758,7 +2760,7 @@ func (w *ApplicationService) GetLLMNodeFCSettingsMerged(ctx context.Context, req var fcPluginSetting *workflow.FCPluginSetting if req.GetPluginFcSetting() != nil { var ( - pluginSvc = crossplugin.GetPluginService() + pluginSvc = crossplugin.DefaultSVC() pluginFcSetting = req.GetPluginFcSetting() isDraft = pluginFcSetting.GetIsDraft() ) @@ -2773,8 +2775,8 @@ func (w *ApplicationService) GetLLMNodeFCSettingsMerged(ctx context.Context, req return nil, err } - pluginReq := &crossplugin.ToolsInfoRequest{ - PluginEntity: vo.PluginEntity{ + pluginReq := &plugin.ToolsInfoRequest{ + PluginEntity: plugin.PluginEntity{ PluginID: pluginID, }, ToolIDs: []int64{toolID}, @@ -2815,7 +2817,7 @@ func (w *ApplicationService) GetLLMNodeFCSettingsMerged(ctx context.Context, req policy := &vo.GetPolicy{ ID: wID, - QType: ternary.IFElse(len(setting.WorkflowVersion) == 0, vo.FromDraft, vo.FromSpecificVersion), + QType: ternary.IFElse(len(setting.WorkflowVersion) == 0, plugin.FromDraft, plugin.FromSpecificVersion), Version: setting.WorkflowVersion, } @@ -2890,7 +2892,7 @@ func (w *ApplicationService) GetPlaygroundPluginList(ctx context.Context, req *p SpaceID: ptr.Of(req.GetSpaceID()), PublishStatus: ptr.Of(vo.HasPublished), }, - QType: vo.FromLatestVersion, + QType: plugin.FromLatestVersion, }) } else if req.GetPage() > 0 && req.GetSize() > 0 { wfs, _, err = GetWorkflowDomainSVC().MGet(ctx, &vo.MGetPolicy{ @@ -2902,7 +2904,7 @@ func (w *ApplicationService) GetPlaygroundPluginList(ctx context.Context, req *p SpaceID: ptr.Of(req.GetSpaceID()), PublishStatus: ptr.Of(vo.HasPublished), }, - QType: vo.FromLatestVersion, + QType: plugin.FromLatestVersion, }) } @@ -2976,7 +2978,7 @@ func (w *ApplicationService) CopyWorkflow(ctx context.Context, req *workflow.Cop return nil, err } - wf, err := GetWorkflowDomainSVC().CopyWorkflow(ctx, workflowID, vo.CopyWorkflowPolicy{ + wf, err := GetWorkflowDomainSVC().CopyWorkflow(ctx, workflowID, plugin.CopyWorkflowPolicy{ ShouldModifyWorkflowName: true, }) if err != nil { @@ -3042,7 +3044,7 @@ func (w *ApplicationService) GetHistorySchema(ctx context.Context, req *workflow // get the workflow entity for that workflowID and commitID policy := &vo.GetPolicy{ ID: workflowID, - QType: ternary.IFElse(len(exe.Version) > 0, vo.FromSpecificVersion, vo.FromDraft), + QType: ternary.IFElse(len(exe.Version) > 0, plugin.FromSpecificVersion, plugin.FromDraft), Version: exe.Version, CommitID: exe.CommitID, } @@ -3100,7 +3102,7 @@ func (w *ApplicationService) GetExampleWorkFlowList(ctx context.Context, req *wo wfs, _, err := GetWorkflowDomainSVC().MGet(ctx, &vo.MGetPolicy{ MetaQuery: option, - QType: vo.FromDraft, + QType: plugin.FromDraft, MetaOnly: false, }) if err != nil { @@ -3179,7 +3181,7 @@ func (w *ApplicationService) CopyWkTemplateApi(ctx context.Context, req *workflo if err != nil { return nil, err } - wf, err := GetWorkflowDomainSVC().CopyWorkflow(ctx, wid, vo.CopyWorkflowPolicy{ + wf, err := GetWorkflowDomainSVC().CopyWorkflow(ctx, wid, plugin.CopyWorkflowPolicy{ ShouldModifyWorkflowName: true, TargetSpaceID: ptr.Of(req.GetTargetSpaceID()), TargetAppID: ptr.Of(int64(0)), diff --git a/backend/crossdomain/contract/modelmgr/modelmgr.go b/backend/crossdomain/contract/modelmgr/modelmgr.go index b5bf16d3..84eb8293 100644 --- a/backend/crossdomain/contract/modelmgr/modelmgr.go +++ b/backend/crossdomain/contract/modelmgr/modelmgr.go @@ -20,6 +20,7 @@ import ( "context" eino "github.com/cloudwego/eino/components/model" + model "github.com/coze-dev/coze-studio/backend/api/model/crossdomain/modelmgr" "github.com/coze-dev/coze-studio/backend/infra/contract/modelmgr" ) diff --git a/backend/crossdomain/contract/plugin/plugin.go b/backend/crossdomain/contract/plugin/plugin.go index 499a254d..cf4f3919 100644 --- a/backend/crossdomain/contract/plugin/plugin.go +++ b/backend/crossdomain/contract/plugin/plugin.go @@ -19,6 +19,8 @@ package plugin import ( "context" + "github.com/cloudwego/eino/schema" + model "github.com/coze-dev/coze-studio/backend/api/model/crossdomain/plugin" ) @@ -35,6 +37,14 @@ type PluginService interface { PublishAPPPlugins(ctx context.Context, req *model.PublishAPPPluginsRequest) (resp *model.PublishAPPPluginsResponse, err error) GetAPPAllPlugins(ctx context.Context, appID int64) (plugins []*model.PluginInfo, err error) MGetVersionTools(ctx context.Context, versionTools []model.VersionTool) (tools []*model.ToolInfo, err error) + GetPluginToolsInfo(ctx context.Context, req *model.ToolsInfoRequest) (*model.ToolsInfoResponse, error) + GetPluginInvokableTools(ctx context.Context, req *model.ToolsInvokableRequest) (map[int64]InvokableTool, error) + ExecutePlugin(ctx context.Context, input map[string]any, pe *model.PluginEntity, toolID int64, cfg model.ExecuteConfig) (map[string]any, error) +} + +type InvokableTool interface { + Info(ctx context.Context) (*schema.ToolInfo, error) + PluginInvoke(ctx context.Context, argumentsInJSON string, cfg model.ExecuteConfig) (string, error) } var defaultSVC PluginService diff --git a/backend/crossdomain/contract/plugin/pluginmock/plugin_mock.go b/backend/crossdomain/contract/plugin/pluginmock/plugin_mock.go new file mode 100644 index 00000000..dd17501d --- /dev/null +++ b/backend/crossdomain/contract/plugin/pluginmock/plugin_mock.go @@ -0,0 +1,323 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: plugin.go +// +// Generated by this command: +// +// mockgen -destination pluginmock/plugin_mock.go --package pluginmock -source plugin.go +// + +// Package pluginmock is a generated GoMock package. +package pluginmock + +import ( + context "context" + reflect "reflect" + + schema "github.com/cloudwego/eino/schema" + plugin "github.com/coze-dev/coze-studio/backend/api/model/crossdomain/plugin" + plugin0 "github.com/coze-dev/coze-studio/backend/crossdomain/contract/plugin" + gomock "go.uber.org/mock/gomock" +) + +// MockPluginService is a mock of PluginService interface. +type MockPluginService struct { + ctrl *gomock.Controller + recorder *MockPluginServiceMockRecorder + isgomock struct{} +} + +// MockPluginServiceMockRecorder is the mock recorder for MockPluginService. +type MockPluginServiceMockRecorder struct { + mock *MockPluginService +} + +// NewMockPluginService creates a new mock instance. +func NewMockPluginService(ctrl *gomock.Controller) *MockPluginService { + mock := &MockPluginService{ctrl: ctrl} + mock.recorder = &MockPluginServiceMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockPluginService) EXPECT() *MockPluginServiceMockRecorder { + return m.recorder +} + +// BindAgentTools mocks base method. +func (m *MockPluginService) BindAgentTools(ctx context.Context, agentID int64, toolIDs []int64) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "BindAgentTools", ctx, agentID, toolIDs) + ret0, _ := ret[0].(error) + return ret0 +} + +// BindAgentTools indicates an expected call of BindAgentTools. +func (mr *MockPluginServiceMockRecorder) BindAgentTools(ctx, agentID, toolIDs any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "BindAgentTools", reflect.TypeOf((*MockPluginService)(nil).BindAgentTools), ctx, agentID, toolIDs) +} + +// DeleteDraftPlugin mocks base method. +func (m *MockPluginService) DeleteDraftPlugin(ctx context.Context, PluginID int64) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "DeleteDraftPlugin", ctx, PluginID) + ret0, _ := ret[0].(error) + return ret0 +} + +// DeleteDraftPlugin indicates an expected call of DeleteDraftPlugin. +func (mr *MockPluginServiceMockRecorder) DeleteDraftPlugin(ctx, PluginID any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteDraftPlugin", reflect.TypeOf((*MockPluginService)(nil).DeleteDraftPlugin), ctx, PluginID) +} + +// DuplicateDraftAgentTools mocks base method. +func (m *MockPluginService) DuplicateDraftAgentTools(ctx context.Context, fromAgentID, toAgentID int64) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "DuplicateDraftAgentTools", ctx, fromAgentID, toAgentID) + ret0, _ := ret[0].(error) + return ret0 +} + +// DuplicateDraftAgentTools indicates an expected call of DuplicateDraftAgentTools. +func (mr *MockPluginServiceMockRecorder) DuplicateDraftAgentTools(ctx, fromAgentID, toAgentID any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DuplicateDraftAgentTools", reflect.TypeOf((*MockPluginService)(nil).DuplicateDraftAgentTools), ctx, fromAgentID, toAgentID) +} + +// ExecutePlugin mocks base method. +func (m *MockPluginService) ExecutePlugin(ctx context.Context, input map[string]any, pe *plugin.PluginEntity, toolID int64, cfg plugin.ExecuteConfig) (map[string]any, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ExecutePlugin", ctx, input, pe, toolID, cfg) + ret0, _ := ret[0].(map[string]any) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ExecutePlugin indicates an expected call of ExecutePlugin. +func (mr *MockPluginServiceMockRecorder) ExecutePlugin(ctx, input, pe, toolID, cfg any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ExecutePlugin", reflect.TypeOf((*MockPluginService)(nil).ExecutePlugin), ctx, input, pe, toolID, cfg) +} + +// ExecuteTool mocks base method. +func (m *MockPluginService) ExecuteTool(ctx context.Context, req *plugin.ExecuteToolRequest, opts ...plugin.ExecuteToolOpt) (*plugin.ExecuteToolResponse, error) { + m.ctrl.T.Helper() + varargs := []any{ctx, req} + for _, a := range opts { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "ExecuteTool", varargs...) + ret0, _ := ret[0].(*plugin.ExecuteToolResponse) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ExecuteTool indicates an expected call of ExecuteTool. +func (mr *MockPluginServiceMockRecorder) ExecuteTool(ctx, req any, opts ...any) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]any{ctx, req}, opts...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ExecuteTool", reflect.TypeOf((*MockPluginService)(nil).ExecuteTool), varargs...) +} + +// GetAPPAllPlugins mocks base method. +func (m *MockPluginService) GetAPPAllPlugins(ctx context.Context, appID int64) ([]*plugin.PluginInfo, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetAPPAllPlugins", ctx, appID) + ret0, _ := ret[0].([]*plugin.PluginInfo) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetAPPAllPlugins indicates an expected call of GetAPPAllPlugins. +func (mr *MockPluginServiceMockRecorder) GetAPPAllPlugins(ctx, appID any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAPPAllPlugins", reflect.TypeOf((*MockPluginService)(nil).GetAPPAllPlugins), ctx, appID) +} + +// GetPluginInvokableTools mocks base method. +func (m *MockPluginService) GetPluginInvokableTools(ctx context.Context, req *plugin.ToolsInvokableRequest) (map[int64]plugin0.InvokableTool, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetPluginInvokableTools", ctx, req) + ret0, _ := ret[0].(map[int64]plugin0.InvokableTool) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetPluginInvokableTools indicates an expected call of GetPluginInvokableTools. +func (mr *MockPluginServiceMockRecorder) GetPluginInvokableTools(ctx, req any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetPluginInvokableTools", reflect.TypeOf((*MockPluginService)(nil).GetPluginInvokableTools), ctx, req) +} + +// GetPluginToolsInfo mocks base method. +func (m *MockPluginService) GetPluginToolsInfo(ctx context.Context, req *plugin.ToolsInfoRequest) (*plugin.ToolsInfoResponse, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetPluginToolsInfo", ctx, req) + ret0, _ := ret[0].(*plugin.ToolsInfoResponse) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetPluginToolsInfo indicates an expected call of GetPluginToolsInfo. +func (mr *MockPluginServiceMockRecorder) GetPluginToolsInfo(ctx, req any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetPluginToolsInfo", reflect.TypeOf((*MockPluginService)(nil).GetPluginToolsInfo), ctx, req) +} + +// MGetAgentTools mocks base method. +func (m *MockPluginService) MGetAgentTools(ctx context.Context, req *plugin.MGetAgentToolsRequest) ([]*plugin.ToolInfo, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "MGetAgentTools", ctx, req) + ret0, _ := ret[0].([]*plugin.ToolInfo) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// MGetAgentTools indicates an expected call of MGetAgentTools. +func (mr *MockPluginServiceMockRecorder) MGetAgentTools(ctx, req any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MGetAgentTools", reflect.TypeOf((*MockPluginService)(nil).MGetAgentTools), ctx, req) +} + +// MGetPluginLatestVersion mocks base method. +func (m *MockPluginService) MGetPluginLatestVersion(ctx context.Context, pluginIDs []int64) (*plugin.MGetPluginLatestVersionResponse, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "MGetPluginLatestVersion", ctx, pluginIDs) + ret0, _ := ret[0].(*plugin.MGetPluginLatestVersionResponse) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// MGetPluginLatestVersion indicates an expected call of MGetPluginLatestVersion. +func (mr *MockPluginServiceMockRecorder) MGetPluginLatestVersion(ctx, pluginIDs any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MGetPluginLatestVersion", reflect.TypeOf((*MockPluginService)(nil).MGetPluginLatestVersion), ctx, pluginIDs) +} + +// MGetVersionPlugins mocks base method. +func (m *MockPluginService) MGetVersionPlugins(ctx context.Context, versionPlugins []plugin.VersionPlugin) ([]*plugin.PluginInfo, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "MGetVersionPlugins", ctx, versionPlugins) + ret0, _ := ret[0].([]*plugin.PluginInfo) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// MGetVersionPlugins indicates an expected call of MGetVersionPlugins. +func (mr *MockPluginServiceMockRecorder) MGetVersionPlugins(ctx, versionPlugins any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MGetVersionPlugins", reflect.TypeOf((*MockPluginService)(nil).MGetVersionPlugins), ctx, versionPlugins) +} + +// MGetVersionTools mocks base method. +func (m *MockPluginService) MGetVersionTools(ctx context.Context, versionTools []plugin.VersionTool) ([]*plugin.ToolInfo, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "MGetVersionTools", ctx, versionTools) + ret0, _ := ret[0].([]*plugin.ToolInfo) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// MGetVersionTools indicates an expected call of MGetVersionTools. +func (mr *MockPluginServiceMockRecorder) MGetVersionTools(ctx, versionTools any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MGetVersionTools", reflect.TypeOf((*MockPluginService)(nil).MGetVersionTools), ctx, versionTools) +} + +// PublishAPPPlugins mocks base method. +func (m *MockPluginService) PublishAPPPlugins(ctx context.Context, req *plugin.PublishAPPPluginsRequest) (*plugin.PublishAPPPluginsResponse, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "PublishAPPPlugins", ctx, req) + ret0, _ := ret[0].(*plugin.PublishAPPPluginsResponse) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// PublishAPPPlugins indicates an expected call of PublishAPPPlugins. +func (mr *MockPluginServiceMockRecorder) PublishAPPPlugins(ctx, req any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PublishAPPPlugins", reflect.TypeOf((*MockPluginService)(nil).PublishAPPPlugins), ctx, req) +} + +// PublishAgentTools mocks base method. +func (m *MockPluginService) PublishAgentTools(ctx context.Context, agentID int64, agentVersion string) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "PublishAgentTools", ctx, agentID, agentVersion) + ret0, _ := ret[0].(error) + return ret0 +} + +// PublishAgentTools indicates an expected call of PublishAgentTools. +func (mr *MockPluginServiceMockRecorder) PublishAgentTools(ctx, agentID, agentVersion any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PublishAgentTools", reflect.TypeOf((*MockPluginService)(nil).PublishAgentTools), ctx, agentID, agentVersion) +} + +// PublishPlugin mocks base method. +func (m *MockPluginService) PublishPlugin(ctx context.Context, req *plugin.PublishPluginRequest) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "PublishPlugin", ctx, req) + ret0, _ := ret[0].(error) + return ret0 +} + +// PublishPlugin indicates an expected call of PublishPlugin. +func (mr *MockPluginServiceMockRecorder) PublishPlugin(ctx, req any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PublishPlugin", reflect.TypeOf((*MockPluginService)(nil).PublishPlugin), ctx, req) +} + +// MockInvokableTool is a mock of InvokableTool interface. +type MockInvokableTool struct { + ctrl *gomock.Controller + recorder *MockInvokableToolMockRecorder + isgomock struct{} +} + +// MockInvokableToolMockRecorder is the mock recorder for MockInvokableTool. +type MockInvokableToolMockRecorder struct { + mock *MockInvokableTool +} + +// NewMockInvokableTool creates a new mock instance. +func NewMockInvokableTool(ctrl *gomock.Controller) *MockInvokableTool { + mock := &MockInvokableTool{ctrl: ctrl} + mock.recorder = &MockInvokableToolMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockInvokableTool) EXPECT() *MockInvokableToolMockRecorder { + return m.recorder +} + +// Info mocks base method. +func (m *MockInvokableTool) Info(ctx context.Context) (*schema.ToolInfo, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Info", ctx) + ret0, _ := ret[0].(*schema.ToolInfo) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// Info indicates an expected call of Info. +func (mr *MockInvokableToolMockRecorder) Info(ctx any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Info", reflect.TypeOf((*MockInvokableTool)(nil).Info), ctx) +} + +// PluginInvoke mocks base method. +func (m *MockInvokableTool) PluginInvoke(ctx context.Context, argumentsInJSON string, cfg plugin.ExecuteConfig) (string, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "PluginInvoke", ctx, argumentsInJSON, cfg) + ret0, _ := ret[0].(string) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// PluginInvoke indicates an expected call of PluginInvoke. +func (mr *MockInvokableToolMockRecorder) PluginInvoke(ctx, argumentsInJSON, cfg any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PluginInvoke", reflect.TypeOf((*MockInvokableTool)(nil).PluginInvoke), ctx, argumentsInJSON, cfg) +} diff --git a/backend/crossdomain/contract/workflow/workflow.go b/backend/crossdomain/contract/workflow/workflow.go index bbc06b01..cfbeb4d2 100644 --- a/backend/crossdomain/contract/workflow/workflow.go +++ b/backend/crossdomain/contract/workflow/workflow.go @@ -23,6 +23,7 @@ import ( einoCompose "github.com/cloudwego/eino/compose" "github.com/cloudwego/eino/schema" + model "github.com/coze-dev/coze-studio/backend/api/model/crossdomain/plugin" "github.com/coze-dev/coze-studio/backend/domain/workflow" "github.com/coze-dev/coze-studio/backend/domain/workflow/entity" workflowEntity "github.com/coze-dev/coze-studio/backend/domain/workflow/entity" @@ -38,13 +39,13 @@ type Workflow interface { allInterruptEvents map[string]*workflowEntity.ToolInterruptEvent) einoCompose.Option ReleaseApplicationWorkflows(ctx context.Context, appID int64, config *ReleaseWorkflowConfig) ([]*vo.ValidateIssue, error) GetWorkflowIDsByAppID(ctx context.Context, appID int64) ([]int64, error) - SyncExecuteWorkflow(ctx context.Context, config vo.ExecuteConfig, input map[string]any) (*workflowEntity.WorkflowExecution, vo.TerminatePlan, error) - WithExecuteConfig(cfg vo.ExecuteConfig) einoCompose.Option + SyncExecuteWorkflow(ctx context.Context, config model.ExecuteConfig, input map[string]any) (*workflowEntity.WorkflowExecution, vo.TerminatePlan, error) + WithExecuteConfig(cfg model.ExecuteConfig) einoCompose.Option WithMessagePipe() (compose.Option, *schema.StreamReader[*entity.Message]) } -type ExecuteConfig = vo.ExecuteConfig -type ExecuteMode = vo.ExecuteMode +type ExecuteConfig = model.ExecuteConfig +type ExecuteMode = model.ExecuteMode type NodeType = entity.NodeType type WorkflowMessage = entity.Message @@ -59,14 +60,14 @@ const ( ExecuteModeNodeDebug ExecuteMode = "node_debug" ) -type TaskType = vo.TaskType +type TaskType = model.TaskType const ( TaskTypeForeground TaskType = "foreground" TaskTypeBackground TaskType = "background" ) -type BizType = vo.BizType +type BizType = model.BizType const ( BizTypeAgent BizType = "agent" diff --git a/backend/crossdomain/impl/modelmgr/modelmgr.go b/backend/crossdomain/impl/modelmgr/modelmgr.go index 05d61741..94741c47 100644 --- a/backend/crossdomain/impl/modelmgr/modelmgr.go +++ b/backend/crossdomain/impl/modelmgr/modelmgr.go @@ -21,6 +21,7 @@ import ( "fmt" eino "github.com/cloudwego/eino/components/model" + model "github.com/coze-dev/coze-studio/backend/api/model/crossdomain/modelmgr" crossmodelmgr "github.com/coze-dev/coze-studio/backend/crossdomain/contract/modelmgr" "github.com/coze-dev/coze-studio/backend/infra/contract/chatmodel" diff --git a/backend/crossdomain/impl/plugin/plugin.go b/backend/crossdomain/impl/plugin/plugin.go index 2ba35f8e..f109b878 100644 --- a/backend/crossdomain/impl/plugin/plugin.go +++ b/backend/crossdomain/impl/plugin/plugin.go @@ -18,23 +18,45 @@ package plugin import ( "context" + "fmt" + "strconv" + + "github.com/cloudwego/eino/compose" + "github.com/cloudwego/eino/schema" + "github.com/getkin/kin-openapi/openapi3" + "golang.org/x/exp/maps" model "github.com/coze-dev/coze-studio/backend/api/model/crossdomain/plugin" + "github.com/coze-dev/coze-studio/backend/api/model/plugin_develop/common" + workflow3 "github.com/coze-dev/coze-studio/backend/api/model/workflow" + "github.com/coze-dev/coze-studio/backend/application/base/pluginutil" crossplugin "github.com/coze-dev/coze-studio/backend/crossdomain/contract/plugin" "github.com/coze-dev/coze-studio/backend/domain/plugin/entity" + "github.com/coze-dev/coze-studio/backend/domain/plugin/service" plugin "github.com/coze-dev/coze-studio/backend/domain/plugin/service" + "github.com/coze-dev/coze-studio/backend/domain/workflow" + entity2 "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/storage" + "github.com/coze-dev/coze-studio/backend/pkg/errorx" + "github.com/coze-dev/coze-studio/backend/pkg/lang/conv" + "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/errno" ) var defaultSVC crossplugin.PluginService type impl struct { DomainSVC plugin.PluginService + tos storage.Storage } -func InitDomainService(c plugin.PluginService) crossplugin.PluginService { +func InitDomainService(c plugin.PluginService, tos storage.Storage) crossplugin.PluginService { defaultSVC = &impl{ DomainSVC: c, + tos: tos, } return defaultSVC @@ -105,3 +127,479 @@ func (s *impl) GetAPPAllPlugins(ctx context.Context, appID int64) (plugins []*mo return plugins, nil } + +type pluginInfo struct { + *entity.PluginInfo + LatestVersion *string +} + +func (s *impl) getPluginsWithTools(ctx context.Context, pluginEntity *model.PluginEntity, toolIDs []int64, isDraft bool) ( + _ *pluginInfo, toolsInfo []*entity.ToolInfo, err error) { + defer func() { + if err != nil { + err = vo.WrapIfNeeded(errno.ErrPluginAPIErr, err) + } + }() + + var pluginsInfo []*entity.PluginInfo + var latestPluginInfo *entity.PluginInfo + pluginID := pluginEntity.PluginID + if isDraft { + plugins, err := s.DomainSVC.MGetDraftPlugins(ctx, []int64{pluginID}) + if err != nil { + return nil, nil, err + } + pluginsInfo = plugins + } else if pluginEntity.PluginVersion == nil || (pluginEntity.PluginVersion != nil && *pluginEntity.PluginVersion == "") { + plugins, err := s.DomainSVC.MGetOnlinePlugins(ctx, []int64{pluginID}) + if err != nil { + return nil, nil, err + } + pluginsInfo = plugins + + } else { + plugins, err := s.DomainSVC.MGetVersionPlugins(ctx, []entity.VersionPlugin{ + {PluginID: pluginID, Version: *pluginEntity.PluginVersion}, + }) + if err != nil { + return nil, nil, err + } + pluginsInfo = plugins + + onlinePlugins, err := s.DomainSVC.MGetOnlinePlugins(ctx, []int64{pluginID}) + if err != nil { + return nil, nil, err + } + for _, pi := range onlinePlugins { + if pi.ID == pluginID { + latestPluginInfo = pi + break + } + } + } + + var pInfo *entity.PluginInfo + for _, p := range pluginsInfo { + if p.ID == pluginID { + pInfo = p + break + } + } + if pInfo == nil { + return nil, nil, vo.NewError(errno.ErrPluginIDNotFound, errorx.KV("id", strconv.FormatInt(pluginID, 10))) + } + + if isDraft { + tools, err := s.DomainSVC.MGetDraftTools(ctx, toolIDs) + if err != nil { + return nil, nil, err + } + toolsInfo = tools + } else if pluginEntity.PluginVersion == nil || (pluginEntity.PluginVersion != nil && *pluginEntity.PluginVersion == "") { + tools, err := s.DomainSVC.MGetOnlineTools(ctx, toolIDs) + if err != nil { + return nil, nil, err + } + toolsInfo = tools + } else { + eVersionTools := slices.Transform(toolIDs, func(tid int64) entity.VersionTool { + return entity.VersionTool{ + ToolID: tid, + Version: *pluginEntity.PluginVersion, + } + }) + tools, err := s.DomainSVC.MGetVersionTools(ctx, eVersionTools) + if err != nil { + return nil, nil, err + } + toolsInfo = tools + } + + if latestPluginInfo != nil { + return &pluginInfo{PluginInfo: pInfo, LatestVersion: latestPluginInfo.Version}, toolsInfo, nil + } + + return &pluginInfo{PluginInfo: pInfo}, toolsInfo, nil +} + +func (s *impl) GetPluginToolsInfo(ctx context.Context, req *model.ToolsInfoRequest) ( + _ *model.ToolsInfoResponse, err error) { + defer func() { + if err != nil { + err = vo.WrapIfNeeded(errno.ErrPluginAPIErr, err) + } + }() + + var toolsInfo []*entity.ToolInfo + isDraft := req.IsDraft || (req.PluginEntity.PluginVersion != nil && *req.PluginEntity.PluginVersion == "0") + pInfo, toolsInfo, err := s.getPluginsWithTools(ctx, &model.PluginEntity{PluginID: req.PluginEntity.PluginID, PluginVersion: req.PluginEntity.PluginVersion}, req.ToolIDs, isDraft) + if err != nil { + return nil, err + } + + url, err := s.tos.GetObjectUrl(ctx, pInfo.GetIconURI()) + if err != nil { + return nil, vo.WrapIfNeeded(errno.ErrTOSError, err) + } + + response := &model.ToolsInfoResponse{ + PluginID: pInfo.ID, + SpaceID: pInfo.SpaceID, + Version: pInfo.GetVersion(), + PluginName: pInfo.GetName(), + Description: pInfo.GetDesc(), + IconURL: url, + PluginType: int64(pInfo.PluginType), + ToolInfoList: make(map[int64]model.ToolInfoW), + LatestVersion: pInfo.LatestVersion, + IsOfficial: pInfo.IsOfficial(), + AppID: pInfo.GetAPPID(), + } + + for _, tf := range toolsInfo { + inputs, err := tf.ToReqAPIParameter() + if err != nil { + return nil, err + } + outputs, err := tf.ToRespAPIParameter() + if err != nil { + return nil, err + } + toolExample := pInfo.GetToolExample(ctx, tf.GetName()) + + var ( + requestExample string + responseExample string + ) + if toolExample != nil { + requestExample = toolExample.RequestExample + responseExample = toolExample.ResponseExample + } + + response.ToolInfoList[tf.ID] = model.ToolInfoW{ + ToolID: tf.ID, + ToolName: tf.GetName(), + Inputs: slices.Transform(inputs, toWorkflowAPIParameter), + Outputs: slices.Transform(outputs, toWorkflowAPIParameter), + Description: tf.GetDesc(), + DebugExample: &model.DebugExample{ + ReqExample: requestExample, + RespExample: responseExample, + }, + } + + } + return response, nil +} + +func (s *impl) GetPluginInvokableTools(ctx context.Context, req *model.ToolsInvokableRequest) ( + _ map[int64]crossplugin.InvokableTool, err error) { + defer func() { + if err != nil { + err = vo.WrapIfNeeded(errno.ErrPluginAPIErr, err) + } + }() + + var toolsInfo []*entity.ToolInfo + isDraft := req.IsDraft || (req.PluginEntity.PluginVersion != nil && *req.PluginEntity.PluginVersion == "0") + pInfo, toolsInfo, err := s.getPluginsWithTools(ctx, &model.PluginEntity{ + PluginID: req.PluginEntity.PluginID, + PluginVersion: req.PluginEntity.PluginVersion, + }, maps.Keys(req.ToolsInvokableInfo), isDraft) + if err != nil { + return nil, err + } + + result := map[int64]crossplugin.InvokableTool{} + for _, tf := range toolsInfo { + tl := &pluginInvokeTool{ + pluginEntity: model.PluginEntity{ + PluginID: pInfo.ID, + PluginVersion: pInfo.Version, + }, + client: s.DomainSVC, + toolInfo: tf, + IsDraft: isDraft, + } + + if r, ok := req.ToolsInvokableInfo[tf.ID]; ok && (r.RequestAPIParametersConfig != nil && r.ResponseAPIParametersConfig != nil) { + reqPluginCommonAPIParameters := slices.Transform(r.RequestAPIParametersConfig, toPluginCommonAPIParameter) + respPluginCommonAPIParameters := slices.Transform(r.ResponseAPIParametersConfig, toPluginCommonAPIParameter) + + tl.toolOperation, err = pluginutil.APIParamsToOpenapiOperation(reqPluginCommonAPIParameters, respPluginCommonAPIParameters) + if err != nil { + return nil, err + } + + tl.toolOperation.OperationID = tf.Operation.OperationID + tl.toolOperation.Summary = tf.Operation.Summary + } + + result[tf.ID] = tl + } + return result, nil +} + +func (s *impl) ExecutePlugin(ctx context.Context, input map[string]any, pe *model.PluginEntity, + toolID int64, cfg model.ExecuteConfig) (map[string]any, error) { + args, err := sonic.MarshalString(input) + if err != nil { + return nil, vo.WrapError(errno.ErrSerializationDeserializationFail, err) + } + + var uID string + if cfg.AgentID != nil { + uID = cfg.ConnectorUID + } else { + uID = conv.Int64ToStr(cfg.Operator) + } + + req := &service.ExecuteToolRequest{ + UserID: uID, + PluginID: pe.PluginID, + ToolID: toolID, + ExecScene: model.ExecSceneOfWorkflow, + ArgumentsInJson: args, + ExecDraftTool: pe.PluginVersion == nil || *pe.PluginVersion == "0", + } + execOpts := []entity.ExecuteToolOpt{ + model.WithInvalidRespProcessStrategy(model.InvalidResponseProcessStrategyOfReturnDefault), + } + + if pe.PluginVersion != nil { + execOpts = append(execOpts, model.WithToolVersion(*pe.PluginVersion)) + } + + r, err := s.DomainSVC.ExecuteTool(ctx, req, execOpts...) + if err != nil { + if extra, ok := compose.IsInterruptRerunError(err); ok { + pluginTIE, ok := extra.(*model.ToolInterruptEvent) + if !ok { + return nil, vo.WrapError(errno.ErrPluginAPIErr, fmt.Errorf("expects ToolInterruptEvent, got %T", extra)) + } + + var eventType workflow3.EventType + switch pluginTIE.Event { + case model.InterruptEventTypeOfToolNeedOAuth: + eventType = workflow3.EventType_WorkflowOauthPlugin + default: + return nil, vo.WrapError(errno.ErrPluginAPIErr, + fmt.Errorf("unsupported interrupt event type: %s", pluginTIE.Event)) + } + + id, err := workflow.GetRepository().GenID(ctx) + if err != nil { + return nil, vo.WrapError(errno.ErrIDGenError, err) + } + + ie := &entity2.InterruptEvent{ + ID: id, + InterruptData: pluginTIE.ToolNeedOAuth.Message, + EventType: eventType, + } + + // temporarily replace interrupt with real error, until frontend can handle plugin oauth interrupt + interruptData := ie.InterruptData + return nil, vo.NewError(errno.ErrAuthorizationRequired, errorx.KV("extra", interruptData)) + } + return nil, err + } + + var output map[string]any + err = sonic.UnmarshalString(r.TrimmedResp, &output) + if err != nil { + return nil, vo.WrapError(errno.ErrSerializationDeserializationFail, err) + } + + return output, nil +} + +type pluginInvokeTool struct { + pluginEntity model.PluginEntity + client service.PluginService + toolInfo *entity.ToolInfo + toolOperation *openapi3.Operation + IsDraft bool +} + +func (p *pluginInvokeTool) Info(ctx context.Context) (_ *schema.ToolInfo, err error) { + defer func() { + if err != nil { + err = vo.WrapIfNeeded(errno.ErrPluginAPIErr, err) + } + }() + + var parameterInfo map[string]*schema.ParameterInfo + if p.toolOperation != nil { + parameterInfo, err = model.NewOpenapi3Operation(p.toolOperation).ToEinoSchemaParameterInfo(ctx) + } else { + parameterInfo, err = p.toolInfo.Operation.ToEinoSchemaParameterInfo(ctx) + } + + if err != nil { + return nil, err + } + + return &schema.ToolInfo{ + Name: p.toolInfo.GetName(), + Desc: p.toolInfo.GetDesc(), + ParamsOneOf: schema.NewParamsOneOfByParams(parameterInfo), + }, nil +} + +func (p *pluginInvokeTool) PluginInvoke(ctx context.Context, argumentsInJSON string, cfg model.ExecuteConfig) (string, error) { + req := &service.ExecuteToolRequest{ + UserID: conv.Int64ToStr(cfg.Operator), + PluginID: p.pluginEntity.PluginID, + ToolID: p.toolInfo.ID, + ExecScene: model.ExecSceneOfWorkflow, + ArgumentsInJson: argumentsInJSON, + ExecDraftTool: p.IsDraft, + } + execOpts := []entity.ExecuteToolOpt{ + model.WithInvalidRespProcessStrategy(model.InvalidResponseProcessStrategyOfReturnDefault), + } + + if p.pluginEntity.PluginVersion != nil { + execOpts = append(execOpts, model.WithToolVersion(*p.pluginEntity.PluginVersion)) + } + + if p.toolOperation != nil { + execOpts = append(execOpts, model.WithOpenapiOperation(model.NewOpenapi3Operation(p.toolOperation))) + } + + r, err := p.client.ExecuteTool(ctx, req, execOpts...) + if err != nil { + if extra, ok := compose.IsInterruptRerunError(err); ok { + pluginTIE, ok := extra.(*model.ToolInterruptEvent) + if !ok { + return "", vo.WrapError(errno.ErrPluginAPIErr, fmt.Errorf("expects ToolInterruptEvent, got %T", extra)) + } + + var eventType workflow3.EventType + switch pluginTIE.Event { + case model.InterruptEventTypeOfToolNeedOAuth: + eventType = workflow3.EventType_WorkflowOauthPlugin + default: + return "", vo.WrapError(errno.ErrPluginAPIErr, + fmt.Errorf("unsupported interrupt event type: %s", pluginTIE.Event)) + } + + id, err := workflow.GetRepository().GenID(ctx) + if err != nil { + return "", vo.WrapError(errno.ErrIDGenError, err) + } + + ie := &entity2.InterruptEvent{ + ID: id, + InterruptData: pluginTIE.ToolNeedOAuth.Message, + EventType: eventType, + } + + tie := &entity2.ToolInterruptEvent{ + ToolCallID: compose.GetToolCallID(ctx), + ToolName: p.toolInfo.GetName(), + InterruptEvent: ie, + } + + // temporarily replace interrupt with real error, until frontend can handle plugin oauth interrupt + _ = tie + interruptData := ie.InterruptData + return "", vo.NewError(errno.ErrAuthorizationRequired, errorx.KV("extra", interruptData)) + } + return "", err + } + return r.TrimmedResp, nil +} + +func toPluginCommonAPIParameter(parameter *workflow3.APIParameter) *common.APIParameter { + if parameter == nil { + return nil + } + p := &common.APIParameter{ + ID: parameter.ID, + Name: parameter.Name, + Desc: parameter.Desc, + Type: common.ParameterType(parameter.Type), + Location: common.ParameterLocation(parameter.Location), + IsRequired: parameter.IsRequired, + GlobalDefault: parameter.GlobalDefault, + GlobalDisable: parameter.GlobalDisable, + LocalDefault: parameter.LocalDefault, + LocalDisable: parameter.LocalDisable, + VariableRef: parameter.VariableRef, + } + if parameter.SubType != nil { + p.SubType = ptr.Of(common.ParameterType(*parameter.SubType)) + } + + if parameter.DefaultParamSource != nil { + p.DefaultParamSource = ptr.Of(common.DefaultParamSource(*parameter.DefaultParamSource)) + } + if parameter.AssistType != nil { + p.AssistType = ptr.Of(common.AssistParameterType(*parameter.AssistType)) + } + + if len(parameter.SubParameters) > 0 { + p.SubParameters = make([]*common.APIParameter, 0, len(parameter.SubParameters)) + for _, subParam := range parameter.SubParameters { + p.SubParameters = append(p.SubParameters, toPluginCommonAPIParameter(subParam)) + } + } + + return p +} + +func toWorkflowAPIParameter(parameter *common.APIParameter) *workflow3.APIParameter { + if parameter == nil { + return nil + } + p := &workflow3.APIParameter{ + ID: parameter.ID, + Name: parameter.Name, + Desc: parameter.Desc, + Type: workflow3.ParameterType(parameter.Type), + Location: workflow3.ParameterLocation(parameter.Location), + IsRequired: parameter.IsRequired, + GlobalDefault: parameter.GlobalDefault, + GlobalDisable: parameter.GlobalDisable, + LocalDefault: parameter.LocalDefault, + LocalDisable: parameter.LocalDisable, + VariableRef: parameter.VariableRef, + } + if parameter.SubType != nil { + p.SubType = ptr.Of(workflow3.ParameterType(*parameter.SubType)) + } + + if parameter.DefaultParamSource != nil { + p.DefaultParamSource = ptr.Of(workflow3.DefaultParamSource(*parameter.DefaultParamSource)) + } + if parameter.AssistType != nil { + p.AssistType = ptr.Of(workflow3.AssistParameterType(*parameter.AssistType)) + } + + // Check if it's an array that needs unwrapping. + if parameter.Type == common.ParameterType_Array && len(parameter.SubParameters) == 1 && parameter.SubParameters[0].Name == "[Array Item]" { + arrayItem := parameter.SubParameters[0] + p.SubType = ptr.Of(workflow3.ParameterType(arrayItem.Type)) + // If the "[Array Item]" is an object, its sub-parameters become the array's sub-parameters. + if arrayItem.Type == common.ParameterType_Object { + p.SubParameters = make([]*workflow3.APIParameter, 0, len(arrayItem.SubParameters)) + for _, subParam := range arrayItem.SubParameters { + p.SubParameters = append(p.SubParameters, toWorkflowAPIParameter(subParam)) + } + } else { + // The array's SubType is the Type of the "[Array Item]". + p.SubParameters = make([]*workflow3.APIParameter, 0, 1) + p.SubParameters = append(p.SubParameters, toWorkflowAPIParameter(arrayItem)) + p.SubParameters[0].Name = "" // Remove the "[Array Item]" name. + } + } else if len(parameter.SubParameters) > 0 { // A simple object or a non-wrapped array. + p.SubParameters = make([]*workflow3.APIParameter, 0, len(parameter.SubParameters)) + for _, subParam := range parameter.SubParameters { + p.SubParameters = append(p.SubParameters, toWorkflowAPIParameter(subParam)) + } + } + + return p +} diff --git a/backend/crossdomain/impl/workflow/workflow.go b/backend/crossdomain/impl/workflow/workflow.go index c4becba5..c2af255f 100644 --- a/backend/crossdomain/impl/workflow/workflow.go +++ b/backend/crossdomain/impl/workflow/workflow.go @@ -23,6 +23,7 @@ import ( einoCompose "github.com/cloudwego/eino/compose" "github.com/cloudwego/eino/schema" + model "github.com/coze-dev/coze-studio/backend/api/model/crossdomain/plugin" crossworkflow "github.com/coze-dev/coze-studio/backend/crossdomain/contract/workflow" "github.com/coze-dev/coze-studio/backend/domain/workflow" "github.com/coze-dev/coze-studio/backend/domain/workflow/entity" @@ -67,11 +68,11 @@ func (i *impl) ReleaseApplicationWorkflows(ctx context.Context, appID int64, con func (i *impl) WithResumeToolWorkflow(resumingEvent *workflowEntity.ToolInterruptEvent, resumeData string, allInterruptEvents map[string]*workflowEntity.ToolInterruptEvent) einoCompose.Option { return i.DomainSVC.WithResumeToolWorkflow(resumingEvent, resumeData, allInterruptEvents) } -func (i *impl) SyncExecuteWorkflow(ctx context.Context, config vo.ExecuteConfig, input map[string]any) (*workflowEntity.WorkflowExecution, vo.TerminatePlan, error) { +func (i *impl) SyncExecuteWorkflow(ctx context.Context, config model.ExecuteConfig, input map[string]any) (*workflowEntity.WorkflowExecution, vo.TerminatePlan, error) { return i.DomainSVC.SyncExecute(ctx, config, input) } -func (i *impl) WithExecuteConfig(cfg vo.ExecuteConfig) einoCompose.Option { +func (i *impl) WithExecuteConfig(cfg model.ExecuteConfig) einoCompose.Option { return i.DomainSVC.WithExecuteConfig(cfg) } diff --git a/backend/crossdomain/workflow/plugin/plugin.go b/backend/crossdomain/workflow/plugin/plugin.go deleted file mode 100644 index 74415afa..00000000 --- a/backend/crossdomain/workflow/plugin/plugin.go +++ /dev/null @@ -1,533 +0,0 @@ -/* - * 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 plugin - -import ( - "context" - "fmt" - "strconv" - - "github.com/getkin/kin-openapi/openapi3" - "golang.org/x/exp/maps" - - "github.com/cloudwego/eino/compose" - - "github.com/cloudwego/eino/schema" - - "github.com/coze-dev/coze-studio/backend/api/model/crossdomain/plugin" - common "github.com/coze-dev/coze-studio/backend/api/model/plugin_develop/common" - workflow3 "github.com/coze-dev/coze-studio/backend/api/model/workflow" - "github.com/coze-dev/coze-studio/backend/application/base/pluginutil" - "github.com/coze-dev/coze-studio/backend/domain/plugin/entity" - "github.com/coze-dev/coze-studio/backend/domain/plugin/service" - "github.com/coze-dev/coze-studio/backend/domain/workflow" - crossplugin "github.com/coze-dev/coze-studio/backend/domain/workflow/crossdomain/plugin" - entity2 "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/storage" - "github.com/coze-dev/coze-studio/backend/pkg/errorx" - "github.com/coze-dev/coze-studio/backend/pkg/lang/conv" - "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/errno" -) - -type pluginService struct { - client service.PluginService - tos storage.Storage -} - -func NewPluginService(client service.PluginService, tos storage.Storage) crossplugin.Service { - return &pluginService{client: client, tos: tos} -} - -type pluginInfo struct { - *entity.PluginInfo - LatestVersion *string -} - -func (t *pluginService) getPluginsWithTools(ctx context.Context, pluginEntity *crossplugin.Entity, toolIDs []int64, isDraft bool) ( - _ *pluginInfo, toolsInfo []*entity.ToolInfo, err error) { - defer func() { - if err != nil { - err = vo.WrapIfNeeded(errno.ErrPluginAPIErr, err) - } - }() - - var pluginsInfo []*entity.PluginInfo - var latestPluginInfo *entity.PluginInfo - pluginID := pluginEntity.PluginID - if isDraft { - plugins, err := t.client.MGetDraftPlugins(ctx, []int64{pluginID}) - if err != nil { - return nil, nil, err - } - pluginsInfo = plugins - } else if pluginEntity.PluginVersion == nil || (pluginEntity.PluginVersion != nil && *pluginEntity.PluginVersion == "") { - plugins, err := t.client.MGetOnlinePlugins(ctx, []int64{pluginID}) - if err != nil { - return nil, nil, err - } - pluginsInfo = plugins - - } else { - plugins, err := t.client.MGetVersionPlugins(ctx, []entity.VersionPlugin{ - {PluginID: pluginID, Version: *pluginEntity.PluginVersion}, - }) - if err != nil { - return nil, nil, err - } - pluginsInfo = plugins - - onlinePlugins, err := t.client.MGetOnlinePlugins(ctx, []int64{pluginID}) - if err != nil { - return nil, nil, err - } - for _, pi := range onlinePlugins { - if pi.ID == pluginID { - latestPluginInfo = pi - break - } - } - } - - var pInfo *entity.PluginInfo - for _, p := range pluginsInfo { - if p.ID == pluginID { - pInfo = p - break - } - } - if pInfo == nil { - return nil, nil, vo.NewError(errno.ErrPluginIDNotFound, errorx.KV("id", strconv.FormatInt(pluginID, 10))) - } - - if isDraft { - tools, err := t.client.MGetDraftTools(ctx, toolIDs) - if err != nil { - return nil, nil, err - } - toolsInfo = tools - } else if pluginEntity.PluginVersion == nil || (pluginEntity.PluginVersion != nil && *pluginEntity.PluginVersion == "") { - tools, err := t.client.MGetOnlineTools(ctx, toolIDs) - if err != nil { - return nil, nil, err - } - toolsInfo = tools - } else { - eVersionTools := slices.Transform(toolIDs, func(tid int64) entity.VersionTool { - return entity.VersionTool{ - ToolID: tid, - Version: *pluginEntity.PluginVersion, - } - }) - tools, err := t.client.MGetVersionTools(ctx, eVersionTools) - if err != nil { - return nil, nil, err - } - toolsInfo = tools - } - - if latestPluginInfo != nil { - return &pluginInfo{PluginInfo: pInfo, LatestVersion: latestPluginInfo.Version}, toolsInfo, nil - } - - return &pluginInfo{PluginInfo: pInfo}, toolsInfo, nil -} - -func (t *pluginService) GetPluginToolsInfo(ctx context.Context, req *crossplugin.ToolsInfoRequest) ( - _ *crossplugin.ToolsInfoResponse, err error) { - defer func() { - if err != nil { - err = vo.WrapIfNeeded(errno.ErrPluginAPIErr, err) - } - }() - - var toolsInfo []*entity.ToolInfo - isDraft := req.IsDraft || (req.PluginEntity.PluginVersion != nil && *req.PluginEntity.PluginVersion == "0") - pInfo, toolsInfo, err := t.getPluginsWithTools(ctx, &crossplugin.Entity{PluginID: req.PluginEntity.PluginID, PluginVersion: req.PluginEntity.PluginVersion}, req.ToolIDs, isDraft) - if err != nil { - return nil, err - } - - url, err := t.tos.GetObjectUrl(ctx, pInfo.GetIconURI()) - if err != nil { - return nil, vo.WrapIfNeeded(errno.ErrTOSError, err) - } - - response := &crossplugin.ToolsInfoResponse{ - PluginID: pInfo.ID, - SpaceID: pInfo.SpaceID, - Version: pInfo.GetVersion(), - PluginName: pInfo.GetName(), - Description: pInfo.GetDesc(), - IconURL: url, - PluginType: int64(pInfo.PluginType), - ToolInfoList: make(map[int64]crossplugin.ToolInfo), - LatestVersion: pInfo.LatestVersion, - IsOfficial: pInfo.IsOfficial(), - AppID: pInfo.GetAPPID(), - } - - for _, tf := range toolsInfo { - inputs, err := tf.ToReqAPIParameter() - if err != nil { - return nil, err - } - outputs, err := tf.ToRespAPIParameter() - if err != nil { - return nil, err - } - toolExample := pInfo.GetToolExample(ctx, tf.GetName()) - - var ( - requestExample string - responseExample string - ) - if toolExample != nil { - requestExample = toolExample.RequestExample - responseExample = toolExample.ResponseExample - } - - response.ToolInfoList[tf.ID] = crossplugin.ToolInfo{ - ToolID: tf.ID, - ToolName: tf.GetName(), - Inputs: slices.Transform(inputs, toWorkflowAPIParameter), - Outputs: slices.Transform(outputs, toWorkflowAPIParameter), - Description: tf.GetDesc(), - DebugExample: &crossplugin.DebugExample{ - ReqExample: requestExample, - RespExample: responseExample, - }, - } - - } - return response, nil -} - -func (t *pluginService) GetPluginInvokableTools(ctx context.Context, req *crossplugin.ToolsInvokableRequest) ( - _ map[int64]crossplugin.InvokableTool, err error) { - defer func() { - if err != nil { - err = vo.WrapIfNeeded(errno.ErrPluginAPIErr, err) - } - }() - - var toolsInfo []*entity.ToolInfo - isDraft := req.IsDraft || (req.PluginEntity.PluginVersion != nil && *req.PluginEntity.PluginVersion == "0") - pInfo, toolsInfo, err := t.getPluginsWithTools(ctx, &crossplugin.Entity{ - PluginID: req.PluginEntity.PluginID, - PluginVersion: req.PluginEntity.PluginVersion, - }, maps.Keys(req.ToolsInvokableInfo), isDraft) - if err != nil { - return nil, err - } - - result := map[int64]crossplugin.InvokableTool{} - for _, tf := range toolsInfo { - tl := &pluginInvokeTool{ - pluginEntity: crossplugin.Entity{ - PluginID: pInfo.ID, - PluginVersion: pInfo.Version, - }, - client: t.client, - toolInfo: tf, - IsDraft: isDraft, - } - - if r, ok := req.ToolsInvokableInfo[tf.ID]; ok && (r.RequestAPIParametersConfig != nil && r.ResponseAPIParametersConfig != nil) { - reqPluginCommonAPIParameters := slices.Transform(r.RequestAPIParametersConfig, toPluginCommonAPIParameter) - respPluginCommonAPIParameters := slices.Transform(r.ResponseAPIParametersConfig, toPluginCommonAPIParameter) - - tl.toolOperation, err = pluginutil.APIParamsToOpenapiOperation(reqPluginCommonAPIParameters, respPluginCommonAPIParameters) - if err != nil { - return nil, err - } - - tl.toolOperation.OperationID = tf.Operation.OperationID - tl.toolOperation.Summary = tf.Operation.Summary - } - - result[tf.ID] = tl - } - return result, nil -} - -func (t *pluginService) ExecutePlugin(ctx context.Context, input map[string]any, pe *crossplugin.Entity, - toolID int64, cfg crossplugin.ExecConfig) (map[string]any, error) { - args, err := sonic.MarshalString(input) - if err != nil { - return nil, vo.WrapError(errno.ErrSerializationDeserializationFail, err) - } - - var uID string - if cfg.AgentID != nil { - uID = cfg.ConnectorUID - } else { - uID = conv.Int64ToStr(cfg.Operator) - } - - req := &service.ExecuteToolRequest{ - UserID: uID, - PluginID: pe.PluginID, - ToolID: toolID, - ExecScene: plugin.ExecSceneOfWorkflow, - ArgumentsInJson: args, - ExecDraftTool: pe.PluginVersion == nil || *pe.PluginVersion == "0", - } - execOpts := []entity.ExecuteToolOpt{ - plugin.WithInvalidRespProcessStrategy(plugin.InvalidResponseProcessStrategyOfReturnDefault), - } - - if pe.PluginVersion != nil { - execOpts = append(execOpts, plugin.WithToolVersion(*pe.PluginVersion)) - } - - r, err := t.client.ExecuteTool(ctx, req, execOpts...) - if err != nil { - if extra, ok := compose.IsInterruptRerunError(err); ok { - pluginTIE, ok := extra.(*plugin.ToolInterruptEvent) - if !ok { - return nil, vo.WrapError(errno.ErrPluginAPIErr, fmt.Errorf("expects ToolInterruptEvent, got %T", extra)) - } - - var eventType workflow3.EventType - switch pluginTIE.Event { - case plugin.InterruptEventTypeOfToolNeedOAuth: - eventType = workflow3.EventType_WorkflowOauthPlugin - default: - return nil, vo.WrapError(errno.ErrPluginAPIErr, - fmt.Errorf("unsupported interrupt event type: %s", pluginTIE.Event)) - } - - id, err := workflow.GetRepository().GenID(ctx) - if err != nil { - return nil, vo.WrapError(errno.ErrIDGenError, err) - } - - ie := &entity2.InterruptEvent{ - ID: id, - InterruptData: pluginTIE.ToolNeedOAuth.Message, - EventType: eventType, - } - - // temporarily replace interrupt with real error, until frontend can handle plugin oauth interrupt - interruptData := ie.InterruptData - return nil, vo.NewError(errno.ErrAuthorizationRequired, errorx.KV("extra", interruptData)) - } - return nil, err - } - - var output map[string]any - err = sonic.UnmarshalString(r.TrimmedResp, &output) - if err != nil { - return nil, vo.WrapError(errno.ErrSerializationDeserializationFail, err) - } - - return output, nil -} - -type pluginInvokeTool struct { - pluginEntity crossplugin.Entity - client service.PluginService - toolInfo *entity.ToolInfo - toolOperation *openapi3.Operation - IsDraft bool -} - -func (p *pluginInvokeTool) Info(ctx context.Context) (_ *schema.ToolInfo, err error) { - defer func() { - if err != nil { - err = vo.WrapIfNeeded(errno.ErrPluginAPIErr, err) - } - }() - - var parameterInfo map[string]*schema.ParameterInfo - if p.toolOperation != nil { - parameterInfo, err = plugin.NewOpenapi3Operation(p.toolOperation).ToEinoSchemaParameterInfo(ctx) - } else { - parameterInfo, err = p.toolInfo.Operation.ToEinoSchemaParameterInfo(ctx) - } - - if err != nil { - return nil, err - } - - return &schema.ToolInfo{ - Name: p.toolInfo.GetName(), - Desc: p.toolInfo.GetDesc(), - ParamsOneOf: schema.NewParamsOneOfByParams(parameterInfo), - }, nil -} - -func (p *pluginInvokeTool) PluginInvoke(ctx context.Context, argumentsInJSON string, cfg crossplugin.ExecConfig) (string, error) { - req := &service.ExecuteToolRequest{ - UserID: conv.Int64ToStr(cfg.Operator), - PluginID: p.pluginEntity.PluginID, - ToolID: p.toolInfo.ID, - ExecScene: plugin.ExecSceneOfWorkflow, - ArgumentsInJson: argumentsInJSON, - ExecDraftTool: p.IsDraft, - } - execOpts := []entity.ExecuteToolOpt{ - plugin.WithInvalidRespProcessStrategy(plugin.InvalidResponseProcessStrategyOfReturnDefault), - } - - if p.pluginEntity.PluginVersion != nil { - execOpts = append(execOpts, plugin.WithToolVersion(*p.pluginEntity.PluginVersion)) - } - - if p.toolOperation != nil { - execOpts = append(execOpts, plugin.WithOpenapiOperation(plugin.NewOpenapi3Operation(p.toolOperation))) - } - - r, err := p.client.ExecuteTool(ctx, req, execOpts...) - if err != nil { - if extra, ok := compose.IsInterruptRerunError(err); ok { - pluginTIE, ok := extra.(*plugin.ToolInterruptEvent) - if !ok { - return "", vo.WrapError(errno.ErrPluginAPIErr, fmt.Errorf("expects ToolInterruptEvent, got %T", extra)) - } - - var eventType workflow3.EventType - switch pluginTIE.Event { - case plugin.InterruptEventTypeOfToolNeedOAuth: - eventType = workflow3.EventType_WorkflowOauthPlugin - default: - return "", vo.WrapError(errno.ErrPluginAPIErr, - fmt.Errorf("unsupported interrupt event type: %s", pluginTIE.Event)) - } - - id, err := workflow.GetRepository().GenID(ctx) - if err != nil { - return "", vo.WrapError(errno.ErrIDGenError, err) - } - - ie := &entity2.InterruptEvent{ - ID: id, - InterruptData: pluginTIE.ToolNeedOAuth.Message, - EventType: eventType, - } - - tie := &entity2.ToolInterruptEvent{ - ToolCallID: compose.GetToolCallID(ctx), - ToolName: p.toolInfo.GetName(), - InterruptEvent: ie, - } - - // temporarily replace interrupt with real error, until frontend can handle plugin oauth interrupt - _ = tie - interruptData := ie.InterruptData - return "", vo.NewError(errno.ErrAuthorizationRequired, errorx.KV("extra", interruptData)) - } - return "", err - } - return r.TrimmedResp, nil -} - -func toPluginCommonAPIParameter(parameter *workflow3.APIParameter) *common.APIParameter { - if parameter == nil { - return nil - } - p := &common.APIParameter{ - ID: parameter.ID, - Name: parameter.Name, - Desc: parameter.Desc, - Type: common.ParameterType(parameter.Type), - Location: common.ParameterLocation(parameter.Location), - IsRequired: parameter.IsRequired, - GlobalDefault: parameter.GlobalDefault, - GlobalDisable: parameter.GlobalDisable, - LocalDefault: parameter.LocalDefault, - LocalDisable: parameter.LocalDisable, - VariableRef: parameter.VariableRef, - } - if parameter.SubType != nil { - p.SubType = ptr.Of(common.ParameterType(*parameter.SubType)) - } - - if parameter.DefaultParamSource != nil { - p.DefaultParamSource = ptr.Of(common.DefaultParamSource(*parameter.DefaultParamSource)) - } - if parameter.AssistType != nil { - p.AssistType = ptr.Of(common.AssistParameterType(*parameter.AssistType)) - } - - if len(parameter.SubParameters) > 0 { - p.SubParameters = make([]*common.APIParameter, 0, len(parameter.SubParameters)) - for _, subParam := range parameter.SubParameters { - p.SubParameters = append(p.SubParameters, toPluginCommonAPIParameter(subParam)) - } - } - - return p -} - -func toWorkflowAPIParameter(parameter *common.APIParameter) *workflow3.APIParameter { - if parameter == nil { - return nil - } - p := &workflow3.APIParameter{ - ID: parameter.ID, - Name: parameter.Name, - Desc: parameter.Desc, - Type: workflow3.ParameterType(parameter.Type), - Location: workflow3.ParameterLocation(parameter.Location), - IsRequired: parameter.IsRequired, - GlobalDefault: parameter.GlobalDefault, - GlobalDisable: parameter.GlobalDisable, - LocalDefault: parameter.LocalDefault, - LocalDisable: parameter.LocalDisable, - VariableRef: parameter.VariableRef, - } - if parameter.SubType != nil { - p.SubType = ptr.Of(workflow3.ParameterType(*parameter.SubType)) - } - - if parameter.DefaultParamSource != nil { - p.DefaultParamSource = ptr.Of(workflow3.DefaultParamSource(*parameter.DefaultParamSource)) - } - if parameter.AssistType != nil { - p.AssistType = ptr.Of(workflow3.AssistParameterType(*parameter.AssistType)) - } - - // Check if it's an array that needs unwrapping. - if parameter.Type == common.ParameterType_Array && len(parameter.SubParameters) == 1 && parameter.SubParameters[0].Name == "[Array Item]" { - arrayItem := parameter.SubParameters[0] - p.SubType = ptr.Of(workflow3.ParameterType(arrayItem.Type)) - // If the "[Array Item]" is an object, its sub-parameters become the array's sub-parameters. - if arrayItem.Type == common.ParameterType_Object { - p.SubParameters = make([]*workflow3.APIParameter, 0, len(arrayItem.SubParameters)) - for _, subParam := range arrayItem.SubParameters { - p.SubParameters = append(p.SubParameters, toWorkflowAPIParameter(subParam)) - } - } else { - // The array's SubType is the Type of the "[Array Item]". - p.SubParameters = make([]*workflow3.APIParameter, 0, 1) - p.SubParameters = append(p.SubParameters, toWorkflowAPIParameter(arrayItem)) - p.SubParameters[0].Name = "" // Remove the "[Array Item]" name. - } - } else if len(parameter.SubParameters) > 0 { // A simple object or a non-wrapped array. - p.SubParameters = make([]*workflow3.APIParameter, 0, len(parameter.SubParameters)) - for _, subParam := range parameter.SubParameters { - p.SubParameters = append(p.SubParameters, toWorkflowAPIParameter(subParam)) - } - } - - return p -} diff --git a/backend/crossdomain/workflow/plugin/plugin_test.go b/backend/crossdomain/workflow/plugin/plugin_test.go deleted file mode 100644 index bb0f55a3..00000000 --- a/backend/crossdomain/workflow/plugin/plugin_test.go +++ /dev/null @@ -1,189 +0,0 @@ -/* - * 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 plugin - -import ( - "testing" - - "github.com/stretchr/testify/assert" - - common "github.com/coze-dev/coze-studio/backend/api/model/plugin_develop/common" - workflow3 "github.com/coze-dev/coze-studio/backend/api/model/workflow" - "github.com/coze-dev/coze-studio/backend/pkg/lang/ptr" -) - -func TestToWorkflowAPIParameter(t *testing.T) { - cases := []struct { - name string - param *common.APIParameter - expected *workflow3.APIParameter - }{ - { - name: "nil parameter", - param: nil, - expected: nil, - }, - { - name: "simple string parameter", - param: &common.APIParameter{ - Name: "prompt", - Type: common.ParameterType_String, - Desc: "User's prompt", - }, - expected: &workflow3.APIParameter{ - Name: "prompt", - Type: workflow3.ParameterType_String, - Desc: "User's prompt", - }, - }, - { - name: "simple object parameter", - param: &common.APIParameter{ - Name: "user_info", - Type: common.ParameterType_Object, - SubParameters: []*common.APIParameter{ - { - Name: "name", - Type: common.ParameterType_String, - }, - { - Name: "age", - Type: common.ParameterType_Number, - }, - }, - }, - expected: &workflow3.APIParameter{ - Name: "user_info", - Type: workflow3.ParameterType_Object, - SubParameters: []*workflow3.APIParameter{ - { - Name: "name", - Type: workflow3.ParameterType_String, - }, - { - Name: "age", - Type: workflow3.ParameterType_Number, - }, - }, - }, - }, - { - name: "array of strings", - param: &common.APIParameter{ - Name: "tags", - Type: common.ParameterType_Array, - SubParameters: []*common.APIParameter{ - { - Name: "[Array Item]", - Type: common.ParameterType_String, - }, - }, - }, - expected: &workflow3.APIParameter{ - Name: "tags", - Type: workflow3.ParameterType_Array, - SubType: ptr.Of(workflow3.ParameterType_String), - SubParameters: []*workflow3.APIParameter{ - { - Type: workflow3.ParameterType_String, - }, - }, - }, - }, - { - name: "array of objects", - param: &common.APIParameter{ - Name: "users", - Type: common.ParameterType_Array, - SubParameters: []*common.APIParameter{ - { - Name: "[Array Item]", - Type: common.ParameterType_Object, - SubParameters: []*common.APIParameter{ - { - Name: "name", - Type: common.ParameterType_String, - }, - { - Name: "id", - Type: common.ParameterType_Number, - }, - }, - }, - }, - }, - expected: &workflow3.APIParameter{ - Name: "users", - Type: workflow3.ParameterType_Array, - SubType: ptr.Of(workflow3.ParameterType_Object), - SubParameters: []*workflow3.APIParameter{ - { - Name: "name", - Type: workflow3.ParameterType_String, - }, - { - Name: "id", - Type: workflow3.ParameterType_Number, - }, - }, - }, - }, - { - name: "array of array of strings", - param: &common.APIParameter{ - Name: "matrix", - Type: common.ParameterType_Array, - SubParameters: []*common.APIParameter{ - { - Name: "[Array Item]", - Type: common.ParameterType_Array, - SubParameters: []*common.APIParameter{ - { - Name: "[Array Item]", - Type: common.ParameterType_String, - }, - }, - }, - }, - }, - expected: &workflow3.APIParameter{ - Name: "matrix", - Type: workflow3.ParameterType_Array, - SubType: ptr.Of(workflow3.ParameterType_Array), - SubParameters: []*workflow3.APIParameter{ - { - Name: "", // Name is cleared - Type: workflow3.ParameterType_Array, - SubType: ptr.Of(workflow3.ParameterType_String), - SubParameters: []*workflow3.APIParameter{ - { - Type: workflow3.ParameterType_String, - }, - }, - }, - }, - }, - }, - } - - for _, tc := range cases { - t.Run(tc.name, func(t *testing.T) { - actual := toWorkflowAPIParameter(tc.param) - assert.Equal(t, tc.expected, actual) - }) - } -} diff --git a/backend/domain/agent/singleagent/internal/agentflow/node_tool_pre_retriever.go b/backend/domain/agent/singleagent/internal/agentflow/node_tool_pre_retriever.go index 57d8dbf4..dce4bdfe 100644 --- a/backend/domain/agent/singleagent/internal/agentflow/node_tool_pre_retriever.go +++ b/backend/domain/agent/singleagent/internal/agentflow/node_tool_pre_retriever.go @@ -30,7 +30,6 @@ import ( crossworkflow "github.com/coze-dev/coze-studio/backend/crossdomain/contract/workflow" pluginEntity "github.com/coze-dev/coze-studio/backend/domain/plugin/entity" "github.com/coze-dev/coze-studio/backend/domain/plugin/service" - "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" ) @@ -89,7 +88,7 @@ func (pr *toolPreCallConf) toolPreRetrieve(ctx context.Context, ar *AgentRequest logs.CtxErrorf(ctx, "Failed to unmarshal json arguments: %s", item.Arguments) return nil, err } - execResp, _, err := crossworkflow.DefaultSVC().SyncExecuteWorkflow(ctx, vo.ExecuteConfig{ + execResp, _, err := crossworkflow.DefaultSVC().SyncExecuteWorkflow(ctx, plugin.ExecuteConfig{ ID: item.PluginID, ConnectorID: ar.Identity.ConnectorID, ConnectorUID: ar.UserID, diff --git a/backend/domain/agent/singleagent/internal/agentflow/node_tool_workflow.go b/backend/domain/agent/singleagent/internal/agentflow/node_tool_workflow.go index 72d42200..3afecca9 100644 --- a/backend/domain/agent/singleagent/internal/agentflow/node_tool_workflow.go +++ b/backend/domain/agent/singleagent/internal/agentflow/node_tool_workflow.go @@ -20,6 +20,7 @@ import ( "context" "github.com/coze-dev/coze-studio/backend/api/model/app/bot_common" + "github.com/coze-dev/coze-studio/backend/api/model/crossdomain/plugin" crossworkflow "github.com/coze-dev/coze-studio/backend/crossdomain/contract/workflow" "github.com/coze-dev/coze-studio/backend/domain/workflow" "github.com/coze-dev/coze-studio/backend/domain/workflow/entity/vo" @@ -36,7 +37,7 @@ func newWorkflowTools(ctx context.Context, conf *workflowConfig) ([]workflow.Too id := info.GetWorkflowId() policies = append(policies, &vo.GetPolicy{ ID: id, - QType: vo.FromLatestVersion, + QType: plugin.FromLatestVersion, }) } diff --git a/backend/domain/workflow/component_interface.go b/backend/domain/workflow/component_interface.go index 6d11d4e7..5ba50e76 100644 --- a/backend/domain/workflow/component_interface.go +++ b/backend/domain/workflow/component_interface.go @@ -23,17 +23,18 @@ import ( "github.com/cloudwego/eino/compose" "github.com/cloudwego/eino/schema" + "github.com/coze-dev/coze-studio/backend/api/model/crossdomain/plugin" "github.com/coze-dev/coze-studio/backend/domain/workflow/entity" "github.com/coze-dev/coze-studio/backend/domain/workflow/entity/vo" ) type Executable interface { - SyncExecute(ctx context.Context, config vo.ExecuteConfig, input map[string]any) (*entity.WorkflowExecution, vo.TerminatePlan, error) - AsyncExecute(ctx context.Context, config vo.ExecuteConfig, input map[string]any) (int64, error) - AsyncExecuteNode(ctx context.Context, nodeID string, config vo.ExecuteConfig, input map[string]any) (int64, error) - AsyncResume(ctx context.Context, req *entity.ResumeRequest, config vo.ExecuteConfig) error - StreamExecute(ctx context.Context, config vo.ExecuteConfig, input map[string]any) (*schema.StreamReader[*entity.Message], error) - StreamResume(ctx context.Context, req *entity.ResumeRequest, config vo.ExecuteConfig) ( + SyncExecute(ctx context.Context, config plugin.ExecuteConfig, input map[string]any) (*entity.WorkflowExecution, vo.TerminatePlan, error) + AsyncExecute(ctx context.Context, config plugin.ExecuteConfig, input map[string]any) (int64, error) + AsyncExecuteNode(ctx context.Context, nodeID string, config plugin.ExecuteConfig, input map[string]any) (int64, error) + AsyncResume(ctx context.Context, req *entity.ResumeRequest, config plugin.ExecuteConfig) error + StreamExecute(ctx context.Context, config plugin.ExecuteConfig, input map[string]any) (*schema.StreamReader[*entity.Message], error) + StreamResume(ctx context.Context, req *entity.ResumeRequest, config plugin.ExecuteConfig) ( *schema.StreamReader[*entity.Message], error) GetExecution(ctx context.Context, wfExe *entity.WorkflowExecution, includeNodes bool) (*entity.WorkflowExecution, error) @@ -48,7 +49,7 @@ type Executable interface { type AsTool interface { WorkflowAsModelTool(ctx context.Context, policies []*vo.GetPolicy) ([]ToolFromWorkflow, error) WithMessagePipe() (compose.Option, *schema.StreamReader[*entity.Message]) - WithExecuteConfig(cfg vo.ExecuteConfig) compose.Option + WithExecuteConfig(cfg plugin.ExecuteConfig) compose.Option WithResumeToolWorkflow(resumingEvent *entity.ToolInterruptEvent, resumeData string, allInterruptEvents map[string]*entity.ToolInterruptEvent) compose.Option } diff --git a/backend/domain/workflow/crossdomain/plugin/plugin.go b/backend/domain/workflow/crossdomain/plugin/plugin.go deleted file mode 100644 index b57183aa..00000000 --- a/backend/domain/workflow/crossdomain/plugin/plugin.go +++ /dev/null @@ -1,121 +0,0 @@ -/* - * 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 plugin - -import ( - "context" - - "github.com/cloudwego/eino/components/tool" - "github.com/cloudwego/eino/schema" - - workflow3 "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" -) - -//go:generate mockgen -destination pluginmock/plugin_mock.go --package pluginmock -source plugin.go -type Service interface { - GetPluginToolsInfo(ctx context.Context, req *ToolsInfoRequest) (*ToolsInfoResponse, error) - GetPluginInvokableTools(ctx context.Context, req *ToolsInvokableRequest) (map[int64]InvokableTool, error) - ExecutePlugin(ctx context.Context, input map[string]any, pe *Entity, - toolID int64, cfg ExecConfig) (map[string]any, error) -} - -func GetPluginService() Service { - return pluginSrvImpl -} - -func SetPluginService(ts Service) { - pluginSrvImpl = ts -} - -var pluginSrvImpl Service - -type Entity = vo.PluginEntity - -type WorkflowAPIParameters = []*workflow3.APIParameter -type ToolsInfoRequest struct { - PluginEntity Entity - ToolIDs []int64 - IsDraft bool -} -type ToolsInvokableInfo struct { - ToolID int64 - RequestAPIParametersConfig WorkflowAPIParameters - ResponseAPIParametersConfig WorkflowAPIParameters -} - -type ToolsInvokableRequest struct { - PluginEntity Entity - ToolsInvokableInfo map[int64]*ToolsInvokableInfo - IsDraft bool -} - -type DebugExample struct { - ReqExample string - RespExample string -} - -type ToolInfo struct { - ToolName string - ToolID int64 - Description string - DebugExample *DebugExample - - Inputs []*workflow3.APIParameter - Outputs []*workflow3.APIParameter -} - -type ToolsInfoResponse struct { - PluginID int64 - SpaceID int64 - Version string - PluginName string - Description string - IconURL string - PluginType int64 - ToolInfoList map[int64]ToolInfo - LatestVersion *string - IsOfficial bool - AppID int64 -} - -type ExecConfig = vo.ExecuteConfig - -type InvokableTool interface { - Info(ctx context.Context) (*schema.ToolInfo, error) - PluginInvoke(ctx context.Context, argumentsInJSON string, cfg ExecConfig) (string, error) -} - -type pluginInvokableTool struct { - pluginInvokableTool InvokableTool -} - -func NewInvokableTool(pl InvokableTool) tool.InvokableTool { - return &pluginInvokableTool{ - pluginInvokableTool: pl, - } -} - -func (p pluginInvokableTool) Info(ctx context.Context) (*schema.ToolInfo, error) { - return p.pluginInvokableTool.Info(ctx) -} - -func (p pluginInvokableTool) InvokableRun(ctx context.Context, argumentsInJSON string, opts ...tool.Option) (string, error) { - execCfg := execute.GetExecuteConfig(opts...) - return p.pluginInvokableTool.PluginInvoke(ctx, argumentsInJSON, execCfg) -} diff --git a/backend/domain/workflow/crossdomain/plugin/pluginmock/plugin_mock.go b/backend/domain/workflow/crossdomain/plugin/pluginmock/plugin_mock.go deleted file mode 100644 index fb2f53ff..00000000 --- a/backend/domain/workflow/crossdomain/plugin/pluginmock/plugin_mock.go +++ /dev/null @@ -1,159 +0,0 @@ -/* - * 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. - */ - -// Code generated by MockGen. DO NOT EDIT. -// Source: plugin.go -// -// Generated by this command: -// -// mockgen -destination pluginmock/plugin_mock.go --package pluginmock -source plugin.go -// - -// Package pluginmock is a generated GoMock package. -package pluginmock - -import ( - context "context" - reflect "reflect" - - schema "github.com/cloudwego/eino/schema" - plugin "github.com/coze-dev/coze-studio/backend/domain/workflow/crossdomain/plugin" - gomock "go.uber.org/mock/gomock" -) - -// MockService is a mock of Service interface. -type MockService struct { - ctrl *gomock.Controller - recorder *MockServiceMockRecorder - isgomock struct{} -} - -// MockServiceMockRecorder is the mock recorder for MockService. -type MockServiceMockRecorder struct { - mock *MockService -} - -// NewMockService creates a new mock instance. -func NewMockService(ctrl *gomock.Controller) *MockService { - mock := &MockService{ctrl: ctrl} - mock.recorder = &MockServiceMockRecorder{mock} - return mock -} - -// EXPECT returns an object that allows the caller to indicate expected use. -func (m *MockService) EXPECT() *MockServiceMockRecorder { - return m.recorder -} - -// ExecutePlugin mocks base method. -func (m *MockService) ExecutePlugin(ctx context.Context, input map[string]any, pe *plugin.Entity, toolID int64, cfg plugin.ExecConfig) (map[string]any, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "ExecutePlugin", ctx, input, pe, toolID, cfg) - ret0, _ := ret[0].(map[string]any) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// ExecutePlugin indicates an expected call of ExecutePlugin. -func (mr *MockServiceMockRecorder) ExecutePlugin(ctx, input, pe, toolID, cfg any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ExecutePlugin", reflect.TypeOf((*MockService)(nil).ExecutePlugin), ctx, input, pe, toolID, cfg) -} - -// GetPluginInvokableTools mocks base method. -func (m *MockService) GetPluginInvokableTools(ctx context.Context, req *plugin.ToolsInvokableRequest) (map[int64]plugin.InvokableTool, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetPluginInvokableTools", ctx, req) - ret0, _ := ret[0].(map[int64]plugin.InvokableTool) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetPluginInvokableTools indicates an expected call of GetPluginInvokableTools. -func (mr *MockServiceMockRecorder) GetPluginInvokableTools(ctx, req any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetPluginInvokableTools", reflect.TypeOf((*MockService)(nil).GetPluginInvokableTools), ctx, req) -} - -// GetPluginToolsInfo mocks base method. -func (m *MockService) GetPluginToolsInfo(ctx context.Context, req *plugin.ToolsInfoRequest) (*plugin.ToolsInfoResponse, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetPluginToolsInfo", ctx, req) - ret0, _ := ret[0].(*plugin.ToolsInfoResponse) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetPluginToolsInfo indicates an expected call of GetPluginToolsInfo. -func (mr *MockServiceMockRecorder) GetPluginToolsInfo(ctx, req any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetPluginToolsInfo", reflect.TypeOf((*MockService)(nil).GetPluginToolsInfo), ctx, req) -} - - -// MockInvokableTool is a mock of InvokableTool interface. -type MockInvokableTool struct { - ctrl *gomock.Controller - recorder *MockInvokableToolMockRecorder - isgomock struct{} -} - -// MockInvokableToolMockRecorder is the mock recorder for MockInvokableTool. -type MockInvokableToolMockRecorder struct { - mock *MockInvokableTool -} - -// NewMockInvokableTool creates a new mock instance. -func NewMockInvokableTool(ctrl *gomock.Controller) *MockInvokableTool { - mock := &MockInvokableTool{ctrl: ctrl} - mock.recorder = &MockInvokableToolMockRecorder{mock} - return mock -} - -// EXPECT returns an object that allows the caller to indicate expected use. -func (m *MockInvokableTool) EXPECT() *MockInvokableToolMockRecorder { - return m.recorder -} - -// Info mocks base method. -func (m *MockInvokableTool) Info(ctx context.Context) (*schema.ToolInfo, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Info", ctx) - ret0, _ := ret[0].(*schema.ToolInfo) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// Info indicates an expected call of Info. -func (mr *MockInvokableToolMockRecorder) Info(ctx any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Info", reflect.TypeOf((*MockInvokableTool)(nil).Info), ctx) -} - -// PluginInvoke mocks base method. -func (m *MockInvokableTool) PluginInvoke(ctx context.Context, argumentsInJSON string, cfg plugin.ExecConfig) (string, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "PluginInvoke", ctx, argumentsInJSON, cfg) - ret0, _ := ret[0].(string) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// PluginInvoke indicates an expected call of PluginInvoke. -func (mr *MockInvokableToolMockRecorder) PluginInvoke(ctx, argumentsInJSON, cfg any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PluginInvoke", reflect.TypeOf((*MockInvokableTool)(nil).PluginInvoke), ctx, argumentsInJSON, cfg) -} diff --git a/backend/domain/workflow/entity/vo/curd.go b/backend/domain/workflow/entity/vo/curd.go index d3f493eb..c5a45b80 100644 --- a/backend/domain/workflow/entity/vo/curd.go +++ b/backend/domain/workflow/entity/vo/curd.go @@ -16,6 +16,10 @@ package vo +import ( + model "github.com/coze-dev/coze-studio/backend/api/model/crossdomain/plugin" +) + type Page struct { Size int32 `json:"size"` Page int32 `json:"page"` @@ -51,17 +55,9 @@ type QueryToolInfoOption struct { IDs []int64 } -type Locator uint8 - -const ( - FromDraft Locator = iota - FromSpecificVersion - FromLatestVersion -) - type GetPolicy struct { ID int64 - QType Locator + QType model.Locator MetaOnly bool Version string CommitID string @@ -76,7 +72,7 @@ type DeletePolicy struct { type MGetPolicy struct { MetaQuery - QType Locator + QType model.Locator MetaOnly bool Versions map[int64]string } diff --git a/backend/domain/workflow/entity/vo/execution.go b/backend/domain/workflow/entity/vo/execution.go deleted file mode 100644 index f9ca3478..00000000 --- a/backend/domain/workflow/entity/vo/execution.go +++ /dev/null @@ -1,67 +0,0 @@ -/* - * 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" -) diff --git a/backend/domain/workflow/entity/vo/node.go b/backend/domain/workflow/entity/vo/node.go index 45eaa914..d6b27618 100644 --- a/backend/domain/workflow/entity/vo/node.go +++ b/backend/domain/workflow/entity/vo/node.go @@ -23,6 +23,7 @@ import ( "github.com/cloudwego/eino/compose" "github.com/cloudwego/eino/schema" + "github.com/coze-dev/coze-studio/backend/api/model/crossdomain/plugin" "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" @@ -92,7 +93,7 @@ type wfErr struct { func (w *wfErr) DebugURL() string { if w.StatusError.Extra() == nil { - return fmt.Sprintf(DebugURLTpl, w.exeID, w.spaceID, w.workflowID) + return fmt.Sprintf(plugin.DebugURLTpl, w.exeID, w.spaceID, w.workflowID) } debugURL, ok := w.StatusError.Extra()["debug_url"] @@ -100,7 +101,7 @@ func (w *wfErr) DebugURL() string { return debugURL } - return fmt.Sprintf(DebugURLTpl, w.exeID, w.spaceID, w.workflowID) + return fmt.Sprintf(plugin.DebugURLTpl, w.exeID, w.spaceID, w.workflowID) } func (w *wfErr) Level() ErrorLevel { @@ -169,7 +170,7 @@ func WrapError(code int, err error, opts ...errorx.Option) WorkflowError { } func WrapWithDebug(code int, err error, exeID, spaceID, workflowID int64, opts ...errorx.Option) WorkflowError { - debugURL := fmt.Sprintf(DebugURLTpl, exeID, spaceID, workflowID) + debugURL := fmt.Sprintf(plugin.DebugURLTpl, exeID, spaceID, workflowID) opts = append(opts, errorx.Extra("debug_url", debugURL)) return WrapError(code, err, opts...) } diff --git a/backend/domain/workflow/entity/vo/workflow_copy.go b/backend/domain/workflow/entity/vo/workflow_copy.go deleted file mode 100644 index c75b692a..00000000 --- a/backend/domain/workflow/entity/vo/workflow_copy.go +++ /dev/null @@ -1,43 +0,0 @@ -/* - * 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 -} diff --git a/backend/domain/workflow/entity/workflow_execution.go b/backend/domain/workflow/entity/workflow_execution.go index 447aa82b..bfc43b63 100644 --- a/backend/domain/workflow/entity/workflow_execution.go +++ b/backend/domain/workflow/entity/workflow_execution.go @@ -19,8 +19,8 @@ package entity import ( "time" + model "github.com/coze-dev/coze-studio/backend/api/model/crossdomain/plugin" "github.com/coze-dev/coze-studio/backend/api/model/workflow" - "github.com/coze-dev/coze-studio/backend/domain/workflow/entity/vo" ) type WorkflowExecuteStatus workflow.WorkflowExeStatus @@ -31,7 +31,7 @@ type WorkflowExecution struct { WorkflowID int64 Version string SpaceID int64 - vo.ExecuteConfig + model.ExecuteConfig CreatedAt time.Time LogID string NodeCount int32 diff --git a/backend/domain/workflow/interface.go b/backend/domain/workflow/interface.go index c76ccb39..3aa5829d 100644 --- a/backend/domain/workflow/interface.go +++ b/backend/domain/workflow/interface.go @@ -22,6 +22,7 @@ import ( "github.com/cloudwego/eino/components/model" "github.com/cloudwego/eino/compose" + "github.com/coze-dev/coze-studio/backend/api/model/crossdomain/plugin" "github.com/coze-dev/coze-studio/backend/api/model/workflow" "github.com/coze-dev/coze-studio/backend/domain/workflow/entity" "github.com/coze-dev/coze-studio/backend/domain/workflow/entity/vo" @@ -38,7 +39,7 @@ type Service interface { Delete(ctx context.Context, policy *vo.DeletePolicy) (err error) 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) + CopyWorkflow(ctx context.Context, workflowID int64, policy plugin.CopyWorkflowPolicy) (*entity.Workflow, 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) @@ -49,10 +50,10 @@ type Service interface { AsTool ReleaseApplicationWorkflows(ctx context.Context, appID int64, config *vo.ReleaseWorkflowConfig) ([]*vo.ValidateIssue, error) - CopyWorkflowFromAppToLibrary(ctx context.Context, workflowID int64, appID int64, related vo.ExternalResourceRelated) (map[int64]entity.IDVersionPair, []*vo.ValidateIssue, error) - DuplicateWorkflowsByAppID(ctx context.Context, sourceAPPID, targetAppID int64, related vo.ExternalResourceRelated) 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 + CopyWorkflowFromAppToLibrary(ctx context.Context, workflowID int64, appID int64, related plugin.ExternalResourceRelated) (map[int64]entity.IDVersionPair, []*vo.ValidateIssue, error) + DuplicateWorkflowsByAppID(ctx context.Context, sourceAPPID, targetAppID int64, related plugin.ExternalResourceRelated) error + GetWorkflowDependenceResource(ctx context.Context, workflowID int64) (*plugin.DependenceResource, error) + SyncRelatedWorkflowResources(ctx context.Context, appID int64, relatedWorkflows map[int64]entity.IDVersionPair, related plugin.ExternalResourceRelated) error } type Repository interface { @@ -87,7 +88,7 @@ type Repository interface { WorkflowAsTool(ctx context.Context, policy vo.GetPolicy, wfToolConfig vo.WorkflowToolConfig) (ToolFromWorkflow, error) - CopyWorkflow(ctx context.Context, workflowID int64, policy vo.CopyWorkflowPolicy) (*entity.Workflow, error) + CopyWorkflow(ctx context.Context, workflowID int64, policy plugin.CopyWorkflowPolicy) (*entity.Workflow, error) GetDraftWorkflowsByAppID(ctx context.Context, AppID int64) (map[int64]*vo.DraftInfo, map[int64]string, error) diff --git a/backend/domain/workflow/internal/canvas/adaptor/canvas_test.go b/backend/domain/workflow/internal/canvas/adaptor/canvas_test.go index fc458fef..81a5eced 100644 --- a/backend/domain/workflow/internal/canvas/adaptor/canvas_test.go +++ b/backend/domain/workflow/internal/canvas/adaptor/canvas_test.go @@ -34,17 +34,18 @@ import ( crossmodel "github.com/coze-dev/coze-studio/backend/api/model/crossdomain/database" "github.com/coze-dev/coze-studio/backend/api/model/crossdomain/knowledge" + "github.com/coze-dev/coze-studio/backend/api/model/crossdomain/plugin" crossdatabase "github.com/coze-dev/coze-studio/backend/crossdomain/contract/database" "github.com/coze-dev/coze-studio/backend/crossdomain/contract/database/databasemock" crossknowledge "github.com/coze-dev/coze-studio/backend/crossdomain/contract/knowledge" "github.com/coze-dev/coze-studio/backend/crossdomain/contract/knowledge/knowledgemock" crossmodelmgr "github.com/coze-dev/coze-studio/backend/crossdomain/contract/modelmgr" mockmodel "github.com/coze-dev/coze-studio/backend/crossdomain/contract/modelmgr/modelmock" + crossplugin "github.com/coze-dev/coze-studio/backend/crossdomain/contract/plugin" + "github.com/coze-dev/coze-studio/backend/crossdomain/contract/plugin/pluginmock" "github.com/coze-dev/coze-studio/backend/crossdomain/impl/code" userentity "github.com/coze-dev/coze-studio/backend/domain/user/entity" "github.com/coze-dev/coze-studio/backend/domain/workflow" - "github.com/coze-dev/coze-studio/backend/domain/workflow/crossdomain/plugin" - "github.com/coze-dev/coze-studio/backend/domain/workflow/crossdomain/plugin/pluginmock" "github.com/coze-dev/coze-studio/backend/domain/workflow/entity/vo" "github.com/coze-dev/coze-studio/backend/domain/workflow/internal/compose" "github.com/coze-dev/coze-studio/backend/domain/workflow/internal/execute" @@ -76,10 +77,10 @@ func TestIntentDetectorAndDatabase(t *testing.T) { mockey.Mock(execute.GetExeCtx).Return(&execute.Context{ RootCtx: execute.RootCtx{ - ExeCfg: vo.ExecuteConfig{ - Mode: vo.ExecuteModeDebug, + ExeCfg: plugin.ExecuteConfig{ + Mode: plugin.ExecuteModeDebug, Operator: 123, - BizType: vo.BizTypeWorkflow, + BizType: plugin.BizTypeWorkflow, }, }, }).Build() @@ -236,10 +237,10 @@ func TestDatabaseCURD(t *testing.T) { mockey.Mock(execute.GetExeCtx).Return(&execute.Context{ RootCtx: execute.RootCtx{ - ExeCfg: vo.ExecuteConfig{ - Mode: vo.ExecuteModeDebug, + ExeCfg: plugin.ExecuteConfig{ + Mode: plugin.ExecuteModeDebug, Operator: 123, - BizType: vo.BizTypeWorkflow, + BizType: plugin.BizTypeWorkflow, }, }, }).Build() @@ -759,8 +760,8 @@ func TestCodeAndPluginNodes(t *testing.T) { }, }, nil) - mockToolService := pluginmock.NewMockService(ctrl) - mockey.Mock(plugin.GetPluginService).Return(mockToolService).Build() + mockToolService := pluginmock.NewMockPluginService(ctrl) + mockey.Mock(crossplugin.DefaultSVC).Return(mockToolService).Build() mockToolService.EXPECT().ExecutePlugin(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(map[string]any{ "log_id": "20240617191637796DF3F4453E16AF3615", diff --git a/backend/domain/workflow/internal/canvas/adaptor/to_schema.go b/backend/domain/workflow/internal/canvas/adaptor/to_schema.go index 59ba16e1..b2e327d0 100644 --- a/backend/domain/workflow/internal/canvas/adaptor/to_schema.go +++ b/backend/domain/workflow/internal/canvas/adaptor/to_schema.go @@ -26,6 +26,7 @@ import ( einoCompose "github.com/cloudwego/eino/compose" + model "github.com/coze-dev/coze-studio/backend/api/model/crossdomain/plugin" "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" @@ -337,7 +338,7 @@ func toSubWorkflowNodeSchema(ctx context.Context, n *vo.Node) (*schema.NodeSchem subWF, err := workflow.GetRepository().GetEntity(ctx, &vo.GetPolicy{ ID: id, - QType: ternary.IFElse(len(version) == 0, vo.FromDraft, vo.FromSpecificVersion), + QType: ternary.IFElse(len(version) == 0, model.FromDraft, model.FromSpecificVersion), Version: version, }) if err != nil { diff --git a/backend/domain/workflow/internal/compose/designate_option.go b/backend/domain/workflow/internal/compose/designate_option.go index b53a011f..7aad436e 100644 --- a/backend/domain/workflow/internal/compose/designate_option.go +++ b/backend/domain/workflow/internal/compose/designate_option.go @@ -25,8 +25,9 @@ import ( einoCompose "github.com/cloudwego/eino/compose" "github.com/cloudwego/eino/schema" + model "github.com/coze-dev/coze-studio/backend/api/model/crossdomain/plugin" + crossplugin "github.com/coze-dev/coze-studio/backend/crossdomain/contract/plugin" workflow2 "github.com/coze-dev/coze-studio/backend/domain/workflow" - "github.com/coze-dev/coze-studio/backend/domain/workflow/crossdomain/plugin" "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" @@ -242,9 +243,9 @@ func llmToolCallbackOptions(ctx context.Context, ns *schema2.NodeSchema, eventCh if err != nil { return nil, fmt.Errorf("invalid workflow id: %s", wfIDStr) } - locator := vo.FromDraft + locator := model.FromDraft if wf.WorkflowVersion != "" { - locator = vo.FromSpecificVersion + locator = model.FromSpecificVersion } wfTool, err := workflow2.GetRepository().WorkflowAsTool(ctx, vo.GetPolicy{ @@ -290,8 +291,8 @@ func llmToolCallbackOptions(ctx context.Context, ns *schema2.NodeSchema, eventCh return nil, err } - toolInfoResponse, err := plugin.GetPluginService().GetPluginToolsInfo(ctx, &plugin.ToolsInfoRequest{ - PluginEntity: plugin.Entity{ + toolInfoResponse, err := crossplugin.DefaultSVC().GetPluginToolsInfo(ctx, &model.ToolsInfoRequest{ + PluginEntity: model.PluginEntity{ PluginID: pluginID, PluginVersion: ptr.Of(p.PluginVersion), }, diff --git a/backend/domain/workflow/internal/compose/state.go b/backend/domain/workflow/internal/compose/state.go index f79c56de..e93dea1a 100644 --- a/backend/domain/workflow/internal/compose/state.go +++ b/backend/domain/workflow/internal/compose/state.go @@ -26,6 +26,7 @@ import ( "github.com/cloudwego/eino/compose" "github.com/cloudwego/eino/schema" + "github.com/coze-dev/coze-studio/backend/api/model/crossdomain/plugin" workflow2 "github.com/coze-dev/coze-studio/backend/api/model/workflow" "github.com/coze-dev/coze-studio/backend/domain/workflow/crossdomain/variable" "github.com/coze-dev/coze-studio/backend/domain/workflow/entity" @@ -79,12 +80,12 @@ func init() { _ = compose.RegisterSerializableType[*entity.WorkflowBasic]("workflow_basic") _ = compose.RegisterSerializableType[vo.TerminatePlan]("terminate_plan") _ = compose.RegisterSerializableType[*entity.ToolInterruptEvent]("tool_interrupt_event") - _ = compose.RegisterSerializableType[vo.ExecuteConfig]("execute_config") - _ = compose.RegisterSerializableType[vo.ExecuteMode]("execute_mode") - _ = compose.RegisterSerializableType[vo.TaskType]("task_type") - _ = compose.RegisterSerializableType[vo.SyncPattern]("sync_pattern") - _ = compose.RegisterSerializableType[vo.Locator]("wf_locator") - _ = compose.RegisterSerializableType[vo.BizType]("biz_type") + _ = compose.RegisterSerializableType[plugin.ExecuteConfig]("execute_config") + _ = compose.RegisterSerializableType[plugin.ExecuteMode]("execute_mode") + _ = compose.RegisterSerializableType[plugin.TaskType]("task_type") + _ = compose.RegisterSerializableType[plugin.SyncPattern]("sync_pattern") + _ = compose.RegisterSerializableType[plugin.Locator]("wf_locator") + _ = compose.RegisterSerializableType[plugin.BizType]("biz_type") _ = compose.RegisterSerializableType[*execute.AppVariables]("app_variables") } @@ -905,12 +906,12 @@ func streamStatePostHandlerForVars(s *schema2.NodeSchema) compose.StreamStatePos func GenStateModifierByEventType(e entity.InterruptEventType, nodeKey vo.NodeKey, resumeData string, - exeCfg vo.ExecuteConfig) (stateModifier compose.StateModifier) { + exeCfg plugin.ExecuteConfig) (stateModifier compose.StateModifier) { // TODO: can we unify them all to a map[NodeKey]resumeData? switch e { case entity.InterruptEventInput: stateModifier = func(ctx context.Context, path compose.NodePath, state any) (err error) { - if exeCfg.BizType == vo.BizTypeAgent { + if exeCfg.BizType == plugin.BizTypeAgent { m := make(map[string]any) sList := strings.Split(resumeData, "\n") for _, s := range sList { diff --git a/backend/domain/workflow/internal/compose/workflow_run.go b/backend/domain/workflow/internal/compose/workflow_run.go index eaa62e49..2a665434 100644 --- a/backend/domain/workflow/internal/compose/workflow_run.go +++ b/backend/domain/workflow/internal/compose/workflow_run.go @@ -26,6 +26,7 @@ import ( einoCompose "github.com/cloudwego/eino/compose" "github.com/cloudwego/eino/schema" + model "github.com/coze-dev/coze-studio/backend/api/model/crossdomain/plugin" 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" @@ -45,7 +46,7 @@ type WorkflowRunner struct { resumeReq *entity.ResumeRequest schema *schema2.WorkflowSchema streamWriter *schema.StreamWriter[*entity.Message] - config vo.ExecuteConfig + config model.ExecuteConfig executeID int64 eventChan chan *execute.Event @@ -77,7 +78,7 @@ func WithStreamWriter(sw *schema.StreamWriter[*entity.Message]) WorkflowRunnerOp } } -func NewWorkflowRunner(b *entity.WorkflowBasic, sc *schema2.WorkflowSchema, config vo.ExecuteConfig, opts ...WorkflowRunnerOption) *WorkflowRunner { +func NewWorkflowRunner(b *entity.WorkflowBasic, sc *schema2.WorkflowSchema, config model.ExecuteConfig, opts ...WorkflowRunnerOption) *WorkflowRunner { options := &workflowRunOptions{} for _, opt := range opts { opt(options) @@ -262,7 +263,7 @@ func (r *WorkflowRunner) Prepare(ctx context.Context) ( cancelCtx, cancelFn := context.WithCancel(ctx) var timeoutFn context.CancelFunc if s := execute.GetStaticConfig(); s != nil { - timeout := ternary.IFElse(config.TaskType == vo.TaskTypeBackground, s.BackgroundRunTimeout, s.ForegroundRunTimeout) + timeout := ternary.IFElse(config.TaskType == model.TaskTypeBackground, s.BackgroundRunTimeout, s.ForegroundRunTimeout) if timeout > 0 { cancelCtx, timeoutFn = context.WithTimeout(cancelCtx, timeout) } diff --git a/backend/domain/workflow/internal/execute/callback.go b/backend/domain/workflow/internal/execute/callback.go index dc7e949e..a913bc86 100644 --- a/backend/domain/workflow/internal/execute/callback.go +++ b/backend/domain/workflow/internal/execute/callback.go @@ -35,6 +35,7 @@ import ( "github.com/cloudwego/eino/schema" callbacks2 "github.com/cloudwego/eino/utils/callbacks" + "github.com/coze-dev/coze-studio/backend/api/model/crossdomain/plugin" workflow2 "github.com/coze-dev/coze-studio/backend/api/model/workflow" "github.com/coze-dev/coze-studio/backend/domain/workflow" "github.com/coze-dev/coze-studio/backend/domain/workflow/entity" @@ -64,7 +65,7 @@ type WorkflowHandler struct { nodeCount int32 requireCheckpoint bool resumeEvent *entity.InterruptEvent - exeCfg vo.ExecuteConfig + exeCfg plugin.ExecuteConfig rootTokenCollector *TokenCollector } @@ -74,7 +75,7 @@ type ToolHandler struct { } func NewRootWorkflowHandler(wb *entity.WorkflowBasic, executeID int64, requireCheckpoint bool, - ch chan<- *Event, resumedEvent *entity.InterruptEvent, exeCfg vo.ExecuteConfig, nodeCount int32, + ch chan<- *Event, resumedEvent *entity.InterruptEvent, exeCfg plugin.ExecuteConfig, nodeCount int32, ) callbacks.Handler { return &WorkflowHandler{ ch: ch, diff --git a/backend/domain/workflow/internal/execute/context.go b/backend/domain/workflow/internal/execute/context.go index b9fa3c49..29bbdf13 100644 --- a/backend/domain/workflow/internal/execute/context.go +++ b/backend/domain/workflow/internal/execute/context.go @@ -28,6 +28,7 @@ import ( "github.com/cloudwego/eino/compose" + "github.com/coze-dev/coze-studio/backend/api/model/crossdomain/plugin" "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" @@ -58,7 +59,7 @@ type RootCtx struct { RootWorkflowBasic *entity.WorkflowBasic RootExecuteID int64 ResumeEvent *entity.InterruptEvent - ExeCfg vo.ExecuteConfig + ExeCfg plugin.ExecuteConfig } type SubWorkflowCtx struct { diff --git a/backend/domain/workflow/internal/execute/event_handle.go b/backend/domain/workflow/internal/execute/event_handle.go index a13a2266..a025a211 100644 --- a/backend/domain/workflow/internal/execute/event_handle.go +++ b/backend/domain/workflow/internal/execute/event_handle.go @@ -27,6 +27,7 @@ import ( "github.com/bytedance/sonic" "github.com/cloudwego/eino/schema" + "github.com/coze-dev/coze-studio/backend/api/model/crossdomain/plugin" "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" @@ -63,7 +64,7 @@ func setRootWorkflowSuccess(ctx context.Context, event *Event, repo workflow.Rep rootWkID := event.RootWorkflowBasic.ID exeCfg := event.ExeCfg - if exeCfg.Mode == vo.ExecuteModeDebug { + if exeCfg.Mode == plugin.ExecuteModeDebug { if err := repo.UpdateWorkflowDraftTestRunSuccess(ctx, rootWkID); err != nil { return fmt.Errorf("failed to save workflow draft test run success: %v", err) } @@ -725,7 +726,7 @@ func HandleExecuteEvent(ctx context.Context, timeoutFn context.CancelFunc, repo workflow.Repository, sw *schema.StreamWriter[*entity.Message], - exeCfg vo.ExecuteConfig, + exeCfg plugin.ExecuteConfig, ) (event *Event) { var ( wfSuccessEvent *Event @@ -760,7 +761,7 @@ func HandleExecuteEvent(ctx context.Context, return event case workflowSuccess: // workflow success, wait for exit node to be done wfSuccessEvent = event - if lastNodeIsDone || exeCfg.Mode == vo.ExecuteModeNodeDebug { + if lastNodeIsDone || exeCfg.Mode == plugin.ExecuteModeNodeDebug { if err = setRootWorkflowSuccess(ctx, wfSuccessEvent, repo, sw); err != nil { logs.CtxErrorf(ctx, "failed to set root workflow success for workflow %d: %v", wfSuccessEvent.RootWorkflowBasic.ID, err) diff --git a/backend/domain/workflow/internal/execute/tool_option.go b/backend/domain/workflow/internal/execute/tool_option.go index e1b5c682..dc8e9bfb 100644 --- a/backend/domain/workflow/internal/execute/tool_option.go +++ b/backend/domain/workflow/internal/execute/tool_option.go @@ -21,14 +21,14 @@ import ( "github.com/cloudwego/eino/compose" "github.com/cloudwego/eino/schema" + "github.com/coze-dev/coze-studio/backend/api/model/crossdomain/plugin" "github.com/coze-dev/coze-studio/backend/domain/workflow/entity" - "github.com/coze-dev/coze-studio/backend/domain/workflow/entity/vo" ) type workflowToolOption struct { resumeReq *entity.ResumeRequest sw *schema.StreamWriter[*entity.Message] - exeCfg vo.ExecuteConfig + exeCfg plugin.ExecuteConfig allInterruptEvents map[string]*entity.ToolInterruptEvent parentTokenCollector *TokenCollector } @@ -46,7 +46,7 @@ func WithIntermediateStreamWriter(sw *schema.StreamWriter[*entity.Message]) tool }) } -func WithExecuteConfig(cfg vo.ExecuteConfig) tool.Option { +func WithExecuteConfig(cfg plugin.ExecuteConfig) tool.Option { return tool.WrapImplSpecificOptFn(func(opts *workflowToolOption) { opts.exeCfg = cfg }) @@ -62,7 +62,7 @@ func GetIntermediateStreamWriter(opts ...tool.Option) *schema.StreamWriter[*enti return opt.sw } -func GetExecuteConfig(opts ...tool.Option) vo.ExecuteConfig { +func GetExecuteConfig(opts ...tool.Option) plugin.ExecuteConfig { opt := tool.GetImplSpecificOptions(&workflowToolOption{}, opts...) return opt.exeCfg } diff --git a/backend/domain/workflow/internal/nodes/database/common.go b/backend/domain/workflow/internal/nodes/database/common.go index 2d1f185e..25ea6b2c 100644 --- a/backend/domain/workflow/internal/nodes/database/common.go +++ b/backend/domain/workflow/internal/nodes/database/common.go @@ -26,6 +26,7 @@ import ( "github.com/cloudwego/eino/compose" "github.com/coze-dev/coze-studio/backend/api/model/crossdomain/database" + "github.com/coze-dev/coze-studio/backend/api/model/crossdomain/plugin" "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" @@ -412,7 +413,7 @@ func isDebugExecute(ctx context.Context) bool { if execCtx == nil { panic(fmt.Errorf("unable to get exe context")) } - return execCtx.RootCtx.ExeCfg.Mode == vo.ExecuteModeDebug || execCtx.RootCtx.ExeCfg.Mode == vo.ExecuteModeNodeDebug + return execCtx.RootCtx.ExeCfg.Mode == plugin.ExecuteModeDebug || execCtx.RootCtx.ExeCfg.Mode == plugin.ExecuteModeNodeDebug } func getExecUserID(ctx context.Context) string { diff --git a/backend/domain/workflow/internal/nodes/database/customsql_test.go b/backend/domain/workflow/internal/nodes/database/customsql_test.go index 5fca27ce..fc295b38 100644 --- a/backend/domain/workflow/internal/nodes/database/customsql_test.go +++ b/backend/domain/workflow/internal/nodes/database/customsql_test.go @@ -25,6 +25,7 @@ import ( "go.uber.org/mock/gomock" "github.com/coze-dev/coze-studio/backend/api/model/crossdomain/database" + "github.com/coze-dev/coze-studio/backend/api/model/crossdomain/plugin" crossdatabase "github.com/coze-dev/coze-studio/backend/crossdomain/contract/database" "github.com/coze-dev/coze-studio/backend/crossdomain/contract/database/databasemock" "github.com/coze-dev/coze-studio/backend/domain/workflow/entity/vo" @@ -71,10 +72,10 @@ func TestCustomSQL_Execute(t *testing.T) { defer mockey.Mock(execute.GetExeCtx).Return(&execute.Context{ RootCtx: execute.RootCtx{ - ExeCfg: vo.ExecuteConfig{ - Mode: vo.ExecuteModeDebug, + ExeCfg: plugin.ExecuteConfig{ + Mode: plugin.ExecuteModeDebug, Operator: 123, - BizType: vo.BizTypeWorkflow, + BizType: plugin.BizTypeWorkflow, }, }, }).Build().UnPatch() diff --git a/backend/domain/workflow/internal/nodes/database/query_test.go b/backend/domain/workflow/internal/nodes/database/query_test.go index c1bb3243..76c04afb 100644 --- a/backend/domain/workflow/internal/nodes/database/query_test.go +++ b/backend/domain/workflow/internal/nodes/database/query_test.go @@ -27,6 +27,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/coze-dev/coze-studio/backend/api/model/crossdomain/database" + "github.com/coze-dev/coze-studio/backend/api/model/crossdomain/plugin" crossdatabase "github.com/coze-dev/coze-studio/backend/crossdomain/contract/database" "github.com/coze-dev/coze-studio/backend/crossdomain/contract/database/databasemock" "github.com/coze-dev/coze-studio/backend/domain/workflow/entity/vo" @@ -56,10 +57,10 @@ func (m *mockDsSelect) Query() func(ctx context.Context, request *database.Query func TestDataset_Query(t *testing.T) { defer mockey.Mock(execute.GetExeCtx).Return(&execute.Context{ RootCtx: execute.RootCtx{ - ExeCfg: vo.ExecuteConfig{ - Mode: vo.ExecuteModeDebug, + ExeCfg: plugin.ExecuteConfig{ + Mode: plugin.ExecuteModeDebug, Operator: 123, - BizType: vo.BizTypeWorkflow, + BizType: plugin.BizTypeWorkflow, }, }, }).Build().UnPatch() diff --git a/backend/domain/workflow/internal/nodes/llm/llm.go b/backend/domain/workflow/internal/nodes/llm/llm.go index 78af91ec..e7df0d24 100644 --- a/backend/domain/workflow/internal/nodes/llm/llm.go +++ b/backend/domain/workflow/internal/nodes/llm/llm.go @@ -36,11 +36,12 @@ import ( "github.com/coze-dev/coze-studio/backend/api/model/crossdomain/knowledge" crossmodel "github.com/coze-dev/coze-studio/backend/api/model/crossdomain/modelmgr" + "github.com/coze-dev/coze-studio/backend/api/model/crossdomain/plugin" workflow3 "github.com/coze-dev/coze-studio/backend/api/model/workflow" crossknowledge "github.com/coze-dev/coze-studio/backend/crossdomain/contract/knowledge" 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" - "github.com/coze-dev/coze-studio/backend/domain/workflow/crossdomain/plugin" "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" @@ -399,9 +400,9 @@ func (c *Config) Build(ctx context.Context, ns *schema2.NodeSchema, _ ...schema2 workflowToolConfig.OutputParametersConfig = wf.FCSetting.ResponseParameters } - locator := vo.FromDraft + locator := plugin.FromDraft if wf.WorkflowVersion != "" { - locator = vo.FromSpecificVersion + locator = plugin.FromSpecificVersion } wfTool, err := workflow.GetRepository().WorkflowAsTool(ctx, vo.GetPolicy{ @@ -455,7 +456,7 @@ func (c *Config) Build(ctx context.Context, ns *schema2.NodeSchema, _ ...schema2 } } else { pluginToolsInfoRequest := &plugin.ToolsInvokableRequest{ - PluginEntity: plugin.Entity{ + PluginEntity: plugin.PluginEntity{ PluginID: pid, PluginVersion: ptr.Of(p.PluginVersion), }, @@ -473,12 +474,12 @@ func (c *Config) Build(ctx context.Context, ns *schema2.NodeSchema, _ ...schema2 } inInvokableTools := make([]tool.BaseTool, 0, len(fcParams.PluginFCParam.PluginList)) for _, req := range pluginToolsInvokableReq { - toolMap, err := plugin.GetPluginService().GetPluginInvokableTools(ctx, req) + toolMap, err := crossplugin.DefaultSVC().GetPluginInvokableTools(ctx, req) if err != nil { return nil, err } for _, t := range toolMap { - inInvokableTools = append(inInvokableTools, plugin.NewInvokableTool(t)) + inInvokableTools = append(inInvokableTools, newInvokableTool(t)) } } if len(inInvokableTools) > 0 { diff --git a/backend/domain/workflow/internal/nodes/llm/plugin.go b/backend/domain/workflow/internal/nodes/llm/plugin.go new file mode 100644 index 00000000..f6a5b66e --- /dev/null +++ b/backend/domain/workflow/internal/nodes/llm/plugin.go @@ -0,0 +1,45 @@ +/* + * 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 llm + +import ( + "context" + + "github.com/cloudwego/eino/components/tool" + "github.com/cloudwego/eino/schema" + + crossplugin "github.com/coze-dev/coze-studio/backend/crossdomain/contract/plugin" + "github.com/coze-dev/coze-studio/backend/domain/workflow/internal/execute" +) + +type pluginInvokableTool struct { + pluginInvokableTool crossplugin.InvokableTool +} + +func newInvokableTool(pl crossplugin.InvokableTool) tool.InvokableTool { + return &pluginInvokableTool{ + pluginInvokableTool: pl, + } +} + +func (p pluginInvokableTool) Info(ctx context.Context) (*schema.ToolInfo, error) { + return p.pluginInvokableTool.Info(ctx) +} + +func (p pluginInvokableTool) InvokableRun(ctx context.Context, argumentsInJSON string, opts ...tool.Option) (string, error) { + execCfg := execute.GetExecuteConfig(opts...) + return p.pluginInvokableTool.PluginInvoke(ctx, argumentsInJSON, execCfg) +} diff --git a/backend/domain/workflow/internal/nodes/plugin/plugin.go b/backend/domain/workflow/internal/nodes/plugin/plugin.go index e59e8f6b..a5479b8a 100644 --- a/backend/domain/workflow/internal/nodes/plugin/plugin.go +++ b/backend/domain/workflow/internal/nodes/plugin/plugin.go @@ -23,7 +23,8 @@ import ( "github.com/cloudwego/eino/compose" - "github.com/coze-dev/coze-studio/backend/domain/workflow/crossdomain/plugin" + model "github.com/coze-dev/coze-studio/backend/api/model/crossdomain/plugin" + crossplugin "github.com/coze-dev/coze-studio/backend/crossdomain/contract/plugin" "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" @@ -100,7 +101,6 @@ func (c *Config) Build(_ context.Context, _ *schema.NodeSchema, _ ...schema.Buil pluginID: c.PluginID, toolID: c.ToolID, pluginVersion: c.PluginVersion, - pluginService: plugin.GetPluginService(), }, nil } @@ -108,16 +108,14 @@ type Plugin struct { pluginID int64 toolID int64 pluginVersion string - - pluginService plugin.Service } func (p *Plugin) Invoke(ctx context.Context, parameters map[string]any) (ret map[string]any, err error) { - var exeCfg vo.ExecuteConfig + var exeCfg model.ExecuteConfig if ctxExeCfg := execute.GetExeCtx(ctx); ctxExeCfg != nil { exeCfg = ctxExeCfg.ExeCfg } - result, err := p.pluginService.ExecutePlugin(ctx, parameters, &vo.PluginEntity{ + result, err := crossplugin.DefaultSVC().ExecutePlugin(ctx, parameters, &model.PluginEntity{ PluginID: p.pluginID, PluginVersion: ptr.Of(p.pluginVersion), }, p.toolID, exeCfg) diff --git a/backend/domain/workflow/internal/repo/execute_history_store.go b/backend/domain/workflow/internal/repo/execute_history_store.go index d4214461..85a3f71e 100644 --- a/backend/domain/workflow/internal/repo/execute_history_store.go +++ b/backend/domain/workflow/internal/repo/execute_history_store.go @@ -25,6 +25,7 @@ import ( "gorm.io/gorm" + "github.com/coze-dev/coze-studio/backend/api/model/crossdomain/plugin" "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" @@ -51,21 +52,21 @@ func (e *executeHistoryStoreImpl) CreateWorkflowExecution(ctx context.Context, e }() var mode int32 - if execution.Mode == vo.ExecuteModeDebug { + if execution.Mode == plugin.ExecuteModeDebug { mode = 1 - } else if execution.Mode == vo.ExecuteModeRelease { + } else if execution.Mode == plugin.ExecuteModeRelease { mode = 2 - } else if execution.Mode == vo.ExecuteModeNodeDebug { + } else if execution.Mode == plugin.ExecuteModeNodeDebug { mode = 3 } var syncPattern int32 switch execution.SyncPattern { - case vo.SyncPatternSync: + case plugin.SyncPatternSync: syncPattern = 1 - case vo.SyncPatternAsync: + case plugin.SyncPatternAsync: syncPattern = 2 - case vo.SyncPatternStream: + case plugin.SyncPatternStream: syncPattern = 3 default: } @@ -211,23 +212,23 @@ func (e *executeHistoryStoreImpl) GetWorkflowExecution(ctx context.Context, id i } rootExe := rootExes[0] - var exeMode vo.ExecuteMode + var exeMode plugin.ExecuteMode if rootExe.Mode == 1 { - exeMode = vo.ExecuteModeDebug + exeMode = plugin.ExecuteModeDebug } else if rootExe.Mode == 2 { - exeMode = vo.ExecuteModeRelease + exeMode = plugin.ExecuteModeRelease } else { - exeMode = vo.ExecuteModeNodeDebug + exeMode = plugin.ExecuteModeNodeDebug } - var syncPattern vo.SyncPattern + var syncPattern plugin.SyncPattern switch rootExe.SyncPattern { case 1: - syncPattern = vo.SyncPatternSync + syncPattern = plugin.SyncPatternSync case 2: - syncPattern = vo.SyncPatternAsync + syncPattern = plugin.SyncPatternAsync case 3: - syncPattern = vo.SyncPatternStream + syncPattern = plugin.SyncPatternStream default: } @@ -236,7 +237,7 @@ func (e *executeHistoryStoreImpl) GetWorkflowExecution(ctx context.Context, id i WorkflowID: rootExe.WorkflowID, Version: rootExe.Version, SpaceID: rootExe.SpaceID, - ExecuteConfig: vo.ExecuteConfig{ + ExecuteConfig: plugin.ExecuteConfig{ Operator: rootExe.OperatorID, Mode: exeMode, AppID: ternary.IFElse(rootExe.AppID > 0, ptr.Of(rootExe.AppID), nil), diff --git a/backend/domain/workflow/internal/repo/repository.go b/backend/domain/workflow/internal/repo/repository.go index 6cb7ca7a..8544774b 100644 --- a/backend/domain/workflow/internal/repo/repository.go +++ b/backend/domain/workflow/internal/repo/repository.go @@ -30,6 +30,7 @@ import ( "gorm.io/gen/field" "gorm.io/gorm" + "github.com/coze-dev/coze-studio/backend/api/model/crossdomain/plugin" workflow3 "github.com/coze-dev/coze-studio/backend/api/model/workflow" "github.com/coze-dev/coze-studio/backend/application/base/ctxutil" "github.com/coze-dev/coze-studio/backend/domain/workflow" @@ -536,7 +537,7 @@ func (r *RepositoryImpl) GetEntity(ctx context.Context, policy *vo.GetPolicy) (_ commitID string ) switch policy.QType { - case vo.FromDraft: + case plugin.FromDraft: draft, err := r.DraftV2(ctx, policy.ID, policy.CommitID) if err != nil { return nil, err @@ -547,7 +548,7 @@ func (r *RepositoryImpl) GetEntity(ctx context.Context, policy *vo.GetPolicy) (_ outputParams = draft.OutputParamsStr draftMeta = draft.DraftMeta commitID = draft.CommitID - case vo.FromSpecificVersion: + case plugin.FromSpecificVersion: v, err := r.GetVersion(ctx, policy.ID, policy.Version) if err != nil { return nil, err @@ -557,7 +558,7 @@ func (r *RepositoryImpl) GetEntity(ctx context.Context, policy *vo.GetPolicy) (_ outputParams = v.OutputParamsStr versionMeta = v.VersionMeta commitID = v.CommitID - case vo.FromLatestVersion: + case plugin.FromLatestVersion: v, err := r.GetLatestVersion(ctx, policy.ID) if err != nil { return nil, err @@ -1410,7 +1411,7 @@ func (r *RepositoryImpl) WorkflowAsTool(ctx context.Context, policy vo.GetPolicy ), nil } -func (r *RepositoryImpl) CopyWorkflow(ctx context.Context, workflowID int64, policy vo.CopyWorkflowPolicy) ( +func (r *RepositoryImpl) CopyWorkflow(ctx context.Context, workflowID int64, policy plugin.CopyWorkflowPolicy) ( _ *entity.Workflow, err error) { const ( copyWorkflowRedisKeyPrefix = "copy_workflow_redis_key_prefix" diff --git a/backend/domain/workflow/service/as_tool_impl.go b/backend/domain/workflow/service/as_tool_impl.go index e07ebf9d..cfcbb552 100644 --- a/backend/domain/workflow/service/as_tool_impl.go +++ b/backend/domain/workflow/service/as_tool_impl.go @@ -22,6 +22,7 @@ import ( einoCompose "github.com/cloudwego/eino/compose" "github.com/cloudwego/eino/schema" + "github.com/coze-dev/coze-studio/backend/api/model/crossdomain/plugin" "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" @@ -36,7 +37,7 @@ func (a *asToolImpl) WithMessagePipe() (einoCompose.Option, *schema.StreamReader return execute.WithMessagePipe() } -func (a *asToolImpl) WithExecuteConfig(cfg vo.ExecuteConfig) einoCompose.Option { +func (a *asToolImpl) WithExecuteConfig(cfg plugin.ExecuteConfig) einoCompose.Option { return einoCompose.WithToolsNodeOption(einoCompose.WithToolOption(execute.WithExecuteConfig(cfg))) } diff --git a/backend/domain/workflow/service/executable_impl.go b/backend/domain/workflow/service/executable_impl.go index 4df59eb6..9e29128c 100644 --- a/backend/domain/workflow/service/executable_impl.go +++ b/backend/domain/workflow/service/executable_impl.go @@ -25,6 +25,8 @@ import ( einoCompose "github.com/cloudwego/eino/compose" "github.com/cloudwego/eino/schema" + "github.com/coze-dev/coze-studio/backend/api/model/crossdomain/plugin" + model "github.com/coze-dev/coze-studio/backend/api/model/crossdomain/plugin" "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" @@ -44,7 +46,7 @@ type executableImpl struct { repo workflow.Repository } -func (i *impl) SyncExecute(ctx context.Context, config vo.ExecuteConfig, input map[string]any) (*entity.WorkflowExecution, vo.TerminatePlan, error) { +func (i *impl) SyncExecute(ctx context.Context, config model.ExecuteConfig, input map[string]any) (*entity.WorkflowExecution, vo.TerminatePlan, error) { var ( err error wfEntity *entity.Workflow @@ -62,7 +64,7 @@ func (i *impl) SyncExecute(ctx context.Context, config vo.ExecuteConfig, input m } isApplicationWorkflow := wfEntity.AppID != nil - if isApplicationWorkflow && config.Mode == vo.ExecuteModeRelease { + if isApplicationWorkflow && config.Mode == model.ExecuteModeRelease { err = i.checkApplicationWorkflowReleaseVersion(ctx, *wfEntity.AppID, config.ConnectorID, config.ID, config.Version) if err != nil { return nil, "", err @@ -189,7 +191,7 @@ func (i *impl) SyncExecute(ctx context.Context, config vo.ExecuteConfig, input m // AsyncExecute executes the specified workflow asynchronously, returning the execution ID. // Intermediate results are not emitted on the fly. // The caller is expected to poll the execution status using the GetExecution method and the returned execution ID. -func (i *impl) AsyncExecute(ctx context.Context, config vo.ExecuteConfig, input map[string]any) (int64, error) { +func (i *impl) AsyncExecute(ctx context.Context, config plugin.ExecuteConfig, input map[string]any) (int64, error) { var ( err error wfEntity *entity.Workflow @@ -207,7 +209,7 @@ func (i *impl) AsyncExecute(ctx context.Context, config vo.ExecuteConfig, input } isApplicationWorkflow := wfEntity.AppID != nil - if isApplicationWorkflow && config.Mode == vo.ExecuteModeRelease { + if isApplicationWorkflow && config.Mode == plugin.ExecuteModeRelease { err = i.checkApplicationWorkflowReleaseVersion(ctx, *wfEntity.AppID, config.ConnectorID, config.ID, config.Version) if err != nil { return 0, err @@ -264,7 +266,7 @@ func (i *impl) AsyncExecute(ctx context.Context, config vo.ExecuteConfig, input return 0, err } - if config.Mode == vo.ExecuteModeDebug { + if config.Mode == plugin.ExecuteModeDebug { if err = i.repo.SetTestRunLatestExeID(ctx, wfEntity.ID, config.Operator, executeID); err != nil { logs.CtxErrorf(ctx, "failed to set test run latest exe id: %v", err) } @@ -275,7 +277,7 @@ func (i *impl) AsyncExecute(ctx context.Context, config vo.ExecuteConfig, input return executeID, nil } -func (i *impl) AsyncExecuteNode(ctx context.Context, nodeID string, config vo.ExecuteConfig, input map[string]any) (int64, error) { +func (i *impl) AsyncExecuteNode(ctx context.Context, nodeID string, config plugin.ExecuteConfig, input map[string]any) (int64, error) { var ( err error wfEntity *entity.Workflow @@ -292,7 +294,7 @@ func (i *impl) AsyncExecuteNode(ctx context.Context, nodeID string, config vo.Ex } isApplicationWorkflow := wfEntity.AppID != nil - if isApplicationWorkflow && config.Mode == vo.ExecuteModeRelease { + if isApplicationWorkflow && config.Mode == plugin.ExecuteModeRelease { err = i.checkApplicationWorkflowReleaseVersion(ctx, *wfEntity.AppID, config.ConnectorID, config.ID, config.Version) if err != nil { return 0, err @@ -343,7 +345,7 @@ func (i *impl) AsyncExecuteNode(ctx context.Context, nodeID string, config vo.Ex return 0, err } - if config.Mode == vo.ExecuteModeNodeDebug { + if config.Mode == plugin.ExecuteModeNodeDebug { if err = i.repo.SetNodeDebugLatestExeID(ctx, wfEntity.ID, nodeID, config.Operator, executeID); err != nil { logs.CtxErrorf(ctx, "failed to set node debug latest exe id: %v", err) } @@ -356,7 +358,7 @@ func (i *impl) AsyncExecuteNode(ctx context.Context, nodeID string, config vo.Ex // StreamExecute executes the specified workflow, returning a stream of execution events. // The caller is expected to receive from the returned stream immediately. -func (i *impl) StreamExecute(ctx context.Context, config vo.ExecuteConfig, input map[string]any) (*schema.StreamReader[*entity.Message], error) { +func (i *impl) StreamExecute(ctx context.Context, config plugin.ExecuteConfig, input map[string]any) (*schema.StreamReader[*entity.Message], error) { var ( err error wfEntity *entity.Workflow @@ -375,7 +377,7 @@ func (i *impl) StreamExecute(ctx context.Context, config vo.ExecuteConfig, input } isApplicationWorkflow := wfEntity.AppID != nil - if isApplicationWorkflow && config.Mode == vo.ExecuteModeRelease { + if isApplicationWorkflow && config.Mode == plugin.ExecuteModeRelease { err = i.checkApplicationWorkflowReleaseVersion(ctx, *wfEntity.AppID, config.ConnectorID, config.ID, config.Version) if err != nil { return nil, err @@ -545,7 +547,7 @@ func (i *impl) GetNodeExecution(ctx context.Context, exeID int64, nodeID string) return nil, nil, fmt.Errorf("try getting workflow exe for exeID : %d, but not found", exeID) } - if wfExe.Mode != vo.ExecuteModeNodeDebug { + if wfExe.Mode != plugin.ExecuteModeNodeDebug { return nodeExe, nil, nil } @@ -671,7 +673,7 @@ func mergeCompositeInnerNodes(nodeExes map[int]*entity.NodeExecution, maxIndex i // AsyncResume resumes a workflow execution asynchronously, using the passed in executionID and eventID. // Intermediate results during the resuming run are not emitted on the fly. // Caller is expected to poll the execution status using the GetExecution method. -func (i *impl) AsyncResume(ctx context.Context, req *entity.ResumeRequest, config vo.ExecuteConfig) error { +func (i *impl) AsyncResume(ctx context.Context, req *entity.ResumeRequest, config plugin.ExecuteConfig) error { wfExe, found, err := i.repo.GetWorkflowExecution(ctx, req.ExecuteID) if err != nil { return err @@ -689,11 +691,11 @@ func (i *impl) AsyncResume(ctx context.Context, req *entity.ResumeRequest, confi return fmt.Errorf("workflow execution %d is not interrupted, status is %v, cannot resume", req.ExecuteID, wfExe.Status) } - var from vo.Locator + var from plugin.Locator if wfExe.Version == "" { - from = vo.FromDraft + from = plugin.FromDraft } else { - from = vo.FromSpecificVersion + from = plugin.FromSpecificVersion } wfEntity, err := i.Get(ctx, &vo.GetPolicy{ @@ -722,7 +724,7 @@ func (i *impl) AsyncResume(ctx context.Context, req *entity.ResumeRequest, confi config.ConnectorID = wfExe.ConnectorID } - if wfExe.Mode == vo.ExecuteModeNodeDebug { + if wfExe.Mode == plugin.ExecuteModeNodeDebug { nodeExes, err := i.repo.GetNodeExecutionsByWfExeID(ctx, wfExe.ID) if err != nil { return err @@ -751,7 +753,7 @@ func (i *impl) AsyncResume(ctx context.Context, req *entity.ResumeRequest, confi return fmt.Errorf("failed to create workflow: %w", err) } - config.Mode = vo.ExecuteModeNodeDebug + config.Mode = plugin.ExecuteModeNodeDebug cancelCtx, _, opts, _, err := compose.NewWorkflowRunner( wfEntity.GetBasic(), workflowSC, config, compose.WithResumeReq(req)).Prepare(ctx) @@ -793,7 +795,7 @@ func (i *impl) AsyncResume(ctx context.Context, req *entity.ResumeRequest, confi // StreamResume resumes a workflow execution, using the passed in executionID and eventID. // Intermediate results during the resuming run are emitted using the returned StreamReader. // Caller is expected to poll the execution status using the GetExecution method. -func (i *impl) StreamResume(ctx context.Context, req *entity.ResumeRequest, config vo.ExecuteConfig) ( +func (i *impl) StreamResume(ctx context.Context, req *entity.ResumeRequest, config plugin.ExecuteConfig) ( *schema.StreamReader[*entity.Message], error) { // must get the interrupt event // generate the state modifier @@ -814,11 +816,11 @@ func (i *impl) StreamResume(ctx context.Context, req *entity.ResumeRequest, conf return nil, fmt.Errorf("workflow execution %d is not interrupted, status is %v, cannot resume", req.ExecuteID, wfExe.Status) } - var from vo.Locator + var from plugin.Locator if wfExe.Version == "" { - from = vo.FromDraft + from = plugin.FromDraft } else { - from = vo.FromSpecificVersion + from = plugin.FromSpecificVersion } wfEntity, err := i.Get(ctx, &vo.GetPolicy{ diff --git a/backend/domain/workflow/service/service_impl.go b/backend/domain/workflow/service/service_impl.go index 58820be1..3856c7ef 100644 --- a/backend/domain/workflow/service/service_impl.go +++ b/backend/domain/workflow/service/service_impl.go @@ -30,6 +30,7 @@ import ( "golang.org/x/sync/errgroup" "gorm.io/gorm" + "github.com/coze-dev/coze-studio/backend/api/model/crossdomain/plugin" cloudworkflow "github.com/coze-dev/coze-studio/backend/api/model/workflow" "github.com/coze-dev/coze-studio/backend/application/base/ctxutil" "github.com/coze-dev/coze-studio/backend/domain/workflow" @@ -386,7 +387,7 @@ func (i *impl) ValidateTree(ctx context.Context, id int64, validateConfig vo.Val MetaQuery: vo.MetaQuery{ IDs: ids, }, - QType: vo.FromDraft, + QType: plugin.FromDraft, }) if err != nil { return nil, err @@ -719,7 +720,7 @@ func (i *impl) UpdateMeta(ctx context.Context, id int64, metaUpdate *vo.MetaUpda return nil } -func (i *impl) CopyWorkflow(ctx context.Context, workflowID int64, policy vo.CopyWorkflowPolicy) (*entity.Workflow, error) { +func (i *impl) CopyWorkflow(ctx context.Context, workflowID int64, policy plugin.CopyWorkflowPolicy) (*entity.Workflow, error) { wf, err := i.repo.CopyWorkflow(ctx, workflowID, policy) if err != nil { return nil, err @@ -754,13 +755,13 @@ func (i *impl) ReleaseApplicationWorkflows(ctx context.Context, appID int64, con MetaQuery: vo.MetaQuery{ AppID: &appID, }, - QType: vo.FromDraft, + QType: plugin.FromDraft, }) if err != nil { return nil, err } - relatedPlugins := make(map[int64]*vo.PluginEntity, len(config.PluginIDs)) + relatedPlugins := make(map[int64]*plugin.PluginEntity, len(config.PluginIDs)) relatedWorkflow := make(map[int64]entity.IDVersionPair, len(wfs)) for _, wf := range wfs { @@ -770,7 +771,7 @@ func (i *impl) ReleaseApplicationWorkflows(ctx context.Context, appID int64, con } } for _, id := range config.PluginIDs { - relatedPlugins[id] = &vo.PluginEntity{ + relatedPlugins[id] = &plugin.PluginEntity{ PluginID: id, PluginVersion: &config.Version, } @@ -803,7 +804,7 @@ func (i *impl) ReleaseApplicationWorkflows(ctx context.Context, appID int64, con return nil, err } - err = replaceRelatedWorkflowOrExternalResourceInWorkflowNodes(c.Nodes, relatedWorkflow, vo.ExternalResourceRelated{ + err = replaceRelatedWorkflowOrExternalResourceInWorkflowNodes(c.Nodes, relatedWorkflow, plugin.ExternalResourceRelated{ PluginMap: relatedPlugins, }) @@ -870,7 +871,7 @@ func (i *impl) ReleaseApplicationWorkflows(ctx context.Context, appID int64, con return nil, nil } -func (i *impl) CopyWorkflowFromAppToLibrary(ctx context.Context, workflowID int64, appID int64, related vo.ExternalResourceRelated) (map[int64]entity.IDVersionPair, []*vo.ValidateIssue, error) { +func (i *impl) CopyWorkflowFromAppToLibrary(ctx context.Context, workflowID int64, appID int64, related plugin.ExternalResourceRelated) (map[int64]entity.IDVersionPair, []*vo.ValidateIssue, error) { type copiedWorkflow struct { id int64 @@ -1084,7 +1085,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.repo.CopyWorkflow(ctx, wf.id, plugin.CopyWorkflowPolicy{ TargetAppID: ptr.Of(int64(0)), ModifiedCanvasSchema: ptr.Of(modifiedCanvasString), }) @@ -1144,7 +1145,7 @@ func (i *impl) CopyWorkflowFromAppToLibrary(ctx context.Context, workflowID int6 } -func (i *impl) DuplicateWorkflowsByAppID(ctx context.Context, sourceAppID, targetAppID int64, related vo.ExternalResourceRelated) error { +func (i *impl) DuplicateWorkflowsByAppID(ctx context.Context, sourceAppID, targetAppID int64, related plugin.ExternalResourceRelated) error { type copiedWorkflow struct { id int64 @@ -1276,7 +1277,7 @@ func (i *impl) DuplicateWorkflowsByAppID(ctx context.Context, sourceAppID, targe return err } - cwf, err := i.CopyWorkflow(ctx, wf.id, vo.CopyWorkflowPolicy{ + cwf, err := i.CopyWorkflow(ctx, wf.id, plugin.CopyWorkflowPolicy{ TargetAppID: ptr.Of(targetAppID), ModifiedCanvasSchema: ptr.Of(modifiedCanvasString), }) @@ -1331,7 +1332,7 @@ func (i *impl) DuplicateWorkflowsByAppID(ctx context.Context, sourceAppID, targe } -func (i *impl) SyncRelatedWorkflowResources(ctx context.Context, appID int64, relatedWorkflows map[int64]entity.IDVersionPair, related vo.ExternalResourceRelated) error { +func (i *impl) SyncRelatedWorkflowResources(ctx context.Context, appID int64, relatedWorkflows map[int64]entity.IDVersionPair, related plugin.ExternalResourceRelated) error { draftVersions, _, err := i.repo.GetDraftWorkflowsByAppID(ctx, appID) if err != nil { return err @@ -1380,10 +1381,10 @@ func (i *impl) SyncRelatedWorkflowResources(ctx context.Context, appID int64, re } -func (i *impl) GetWorkflowDependenceResource(ctx context.Context, workflowID int64) (*vo.DependenceResource, error) { +func (i *impl) GetWorkflowDependenceResource(ctx context.Context, workflowID int64) (*plugin.DependenceResource, error) { wf, err := i.Get(ctx, &vo.GetPolicy{ ID: workflowID, - QType: vo.FromDraft, + QType: plugin.FromDraft, }) if err != nil { return nil, err @@ -1394,7 +1395,7 @@ func (i *impl) GetWorkflowDependenceResource(ctx context.Context, workflowID int return nil, err } - ds := &vo.DependenceResource{ + ds := &plugin.DependenceResource{ PluginIDs: make([]int64, 0), KnowledgeIDs: make([]int64, 0), DatabaseIDs: make([]int64, 0), @@ -1483,7 +1484,7 @@ func (i *impl) GetWorkflowDependenceResource(ctx context.Context, workflowID int subWorkflow, err := i.repo.GetEntity(ctx, &vo.GetPolicy{ ID: wfID, - QType: vo.FromDraft, + QType: plugin.FromDraft, }) if err != nil { return err @@ -1558,9 +1559,9 @@ func (i *impl) MGet(ctx context.Context, policy *vo.MGetPolicy) ([]*entity.Workf } switch policy.QType { - case vo.FromDraft: + case plugin.FromDraft: return i.repo.MGetDrafts(ctx, policy) - case vo.FromSpecificVersion: + case plugin.FromSpecificVersion: if len(policy.IDs) == 0 || len(policy.Versions) != len(policy.IDs) { return nil, 0, fmt.Errorf("ids and versions are required when MGet from specific versions") } @@ -1602,7 +1603,7 @@ func (i *impl) MGet(ctx context.Context, policy *vo.MGetPolicy) ([]*entity.Workf } return result, total, nil - case vo.FromLatestVersion: + case plugin.FromLatestVersion: return i.repo.MGetLatestVersion(ctx, policy) default: panic("not implemented") @@ -1637,7 +1638,7 @@ func (i *impl) calculateTestRunSuccess(ctx context.Context, c *vo.Canvas, wid in return existedDraft.TestRunSuccess, nil // inherit previous draft snapshot's test run success flag } -func replaceRelatedWorkflowOrExternalResourceInWorkflowNodes(nodes []*vo.Node, relatedWorkflows map[int64]entity.IDVersionPair, related vo.ExternalResourceRelated) error { +func replaceRelatedWorkflowOrExternalResourceInWorkflowNodes(nodes []*vo.Node, relatedWorkflows map[int64]entity.IDVersionPair, related plugin.ExternalResourceRelated) error { var ( hasWorkflowRelated = len(relatedWorkflows) > 0 hasPluginRelated = len(related.PluginMap) > 0 diff --git a/backend/internal/mock/domain/workflow/interface.go b/backend/internal/mock/domain/workflow/interface.go index bc93e326..62391632 100644 --- a/backend/internal/mock/domain/workflow/interface.go +++ b/backend/internal/mock/domain/workflow/interface.go @@ -1,19 +1,3 @@ -/* - * 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. - */ - // Code generated by MockGen. DO NOT EDIT. // Source: interface.go // @@ -32,6 +16,7 @@ import ( model "github.com/cloudwego/eino/components/model" compose "github.com/cloudwego/eino/compose" schema "github.com/cloudwego/eino/schema" + plugin "github.com/coze-dev/coze-studio/backend/api/model/crossdomain/plugin" workflow "github.com/coze-dev/coze-studio/backend/api/model/workflow" workflow0 "github.com/coze-dev/coze-studio/backend/domain/workflow" entity "github.com/coze-dev/coze-studio/backend/domain/workflow/entity" @@ -43,6 +28,7 @@ import ( type MockService struct { ctrl *gomock.Controller recorder *MockServiceMockRecorder + isgomock struct{} } // MockServiceMockRecorder is the mock recorder for MockService. @@ -63,7 +49,7 @@ func (m *MockService) EXPECT() *MockServiceMockRecorder { } // AsyncExecute mocks base method. -func (m *MockService) AsyncExecute(ctx context.Context, config vo.ExecuteConfig, input map[string]any) (int64, error) { +func (m *MockService) AsyncExecute(ctx context.Context, config plugin.ExecuteConfig, input map[string]any) (int64, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "AsyncExecute", ctx, config, input) ret0, _ := ret[0].(int64) @@ -78,7 +64,7 @@ func (mr *MockServiceMockRecorder) AsyncExecute(ctx, config, input any) *gomock. } // AsyncExecuteNode mocks base method. -func (m *MockService) AsyncExecuteNode(ctx context.Context, nodeID string, config vo.ExecuteConfig, input map[string]any) (int64, error) { +func (m *MockService) AsyncExecuteNode(ctx context.Context, nodeID string, config plugin.ExecuteConfig, input map[string]any) (int64, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "AsyncExecuteNode", ctx, nodeID, config, input) ret0, _ := ret[0].(int64) @@ -93,7 +79,7 @@ func (mr *MockServiceMockRecorder) AsyncExecuteNode(ctx, nodeID, config, input a } // AsyncResume mocks base method. -func (m *MockService) AsyncResume(ctx context.Context, req *entity.ResumeRequest, config vo.ExecuteConfig) error { +func (m *MockService) AsyncResume(ctx context.Context, req *entity.ResumeRequest, config plugin.ExecuteConfig) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "AsyncResume", ctx, req, config) ret0, _ := ret[0].(error) @@ -121,7 +107,7 @@ func (mr *MockServiceMockRecorder) Cancel(ctx, wfExeID, wfID, spaceID any) *gomo } // CopyWorkflow mocks base method. -func (m *MockService) CopyWorkflow(ctx context.Context, workflowID int64, policy vo.CopyWorkflowPolicy) (*entity.Workflow, error) { +func (m *MockService) CopyWorkflow(ctx context.Context, workflowID int64, policy plugin.CopyWorkflowPolicy) (*entity.Workflow, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "CopyWorkflow", ctx, workflowID, policy) ret0, _ := ret[0].(*entity.Workflow) @@ -136,7 +122,7 @@ func (mr *MockServiceMockRecorder) CopyWorkflow(ctx, workflowID, policy any) *go } // CopyWorkflowFromAppToLibrary mocks base method. -func (m *MockService) CopyWorkflowFromAppToLibrary(ctx context.Context, workflowID, appID int64, related vo.ExternalResourceRelated) (map[int64]entity.IDVersionPair, []*vo.ValidateIssue, error) { +func (m *MockService) CopyWorkflowFromAppToLibrary(ctx context.Context, workflowID, appID int64, related plugin.ExternalResourceRelated) (map[int64]entity.IDVersionPair, []*vo.ValidateIssue, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "CopyWorkflowFromAppToLibrary", ctx, workflowID, appID, related) ret0, _ := ret[0].(map[int64]entity.IDVersionPair) @@ -181,7 +167,7 @@ func (mr *MockServiceMockRecorder) Delete(ctx, policy any) *gomock.Call { } // DuplicateWorkflowsByAppID mocks base method. -func (m *MockService) DuplicateWorkflowsByAppID(ctx context.Context, sourceAPPID, targetAppID int64, related vo.ExternalResourceRelated) error { +func (m *MockService) DuplicateWorkflowsByAppID(ctx context.Context, sourceAPPID, targetAppID int64, related plugin.ExternalResourceRelated) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "DuplicateWorkflowsByAppID", ctx, sourceAPPID, targetAppID, related) ret0, _ := ret[0].(error) @@ -274,10 +260,10 @@ func (mr *MockServiceMockRecorder) GetNodeExecution(ctx, exeID, nodeID any) *gom } // GetWorkflowDependenceResource mocks base method. -func (m *MockService) GetWorkflowDependenceResource(ctx context.Context, workflowID int64) (*vo.DependenceResource, error) { +func (m *MockService) GetWorkflowDependenceResource(ctx context.Context, workflowID int64) (*plugin.DependenceResource, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetWorkflowDependenceResource", ctx, workflowID) - ret0, _ := ret[0].(*vo.DependenceResource) + ret0, _ := ret[0].(*plugin.DependenceResource) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -380,21 +366,21 @@ func (mr *MockServiceMockRecorder) ReleaseApplicationWorkflows(ctx, appID, confi } // Save mocks base method. -func (m *MockService) Save(ctx context.Context, id int64, schema string) error { +func (m *MockService) Save(ctx context.Context, id int64, arg2 string) error { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Save", ctx, id, schema) + ret := m.ctrl.Call(m, "Save", ctx, id, arg2) ret0, _ := ret[0].(error) return ret0 } // Save indicates an expected call of Save. -func (mr *MockServiceMockRecorder) Save(ctx, id, schema any) *gomock.Call { +func (mr *MockServiceMockRecorder) Save(ctx, id, arg2 any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Save", reflect.TypeOf((*MockService)(nil).Save), ctx, id, schema) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Save", reflect.TypeOf((*MockService)(nil).Save), ctx, id, arg2) } // StreamExecute mocks base method. -func (m *MockService) StreamExecute(ctx context.Context, config vo.ExecuteConfig, input map[string]any) (*schema.StreamReader[*entity.Message], error) { +func (m *MockService) StreamExecute(ctx context.Context, config plugin.ExecuteConfig, input map[string]any) (*schema.StreamReader[*entity.Message], error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "StreamExecute", ctx, config, input) ret0, _ := ret[0].(*schema.StreamReader[*entity.Message]) @@ -409,7 +395,7 @@ func (mr *MockServiceMockRecorder) StreamExecute(ctx, config, input any) *gomock } // StreamResume mocks base method. -func (m *MockService) StreamResume(ctx context.Context, req *entity.ResumeRequest, config vo.ExecuteConfig) (*schema.StreamReader[*entity.Message], error) { +func (m *MockService) StreamResume(ctx context.Context, req *entity.ResumeRequest, config plugin.ExecuteConfig) (*schema.StreamReader[*entity.Message], error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "StreamResume", ctx, req, config) ret0, _ := ret[0].(*schema.StreamReader[*entity.Message]) @@ -424,7 +410,7 @@ func (mr *MockServiceMockRecorder) StreamResume(ctx, req, config any) *gomock.Ca } // SyncExecute mocks base method. -func (m *MockService) SyncExecute(ctx context.Context, config vo.ExecuteConfig, input map[string]any) (*entity.WorkflowExecution, vo.TerminatePlan, error) { +func (m *MockService) SyncExecute(ctx context.Context, config plugin.ExecuteConfig, input map[string]any) (*entity.WorkflowExecution, vo.TerminatePlan, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "SyncExecute", ctx, config, input) ret0, _ := ret[0].(*entity.WorkflowExecution) @@ -440,7 +426,7 @@ func (mr *MockServiceMockRecorder) SyncExecute(ctx, config, input any) *gomock.C } // SyncRelatedWorkflowResources mocks base method. -func (m *MockService) SyncRelatedWorkflowResources(ctx context.Context, appID int64, relatedWorkflows map[int64]entity.IDVersionPair, related vo.ExternalResourceRelated) error { +func (m *MockService) SyncRelatedWorkflowResources(ctx context.Context, appID int64, relatedWorkflows map[int64]entity.IDVersionPair, related plugin.ExternalResourceRelated) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "SyncRelatedWorkflowResources", ctx, appID, relatedWorkflows, related) ret0, _ := ret[0].(error) @@ -483,7 +469,7 @@ func (mr *MockServiceMockRecorder) ValidateTree(ctx, id, validateConfig any) *go } // WithExecuteConfig mocks base method. -func (m *MockService) WithExecuteConfig(cfg vo.ExecuteConfig) compose.Option { +func (m *MockService) WithExecuteConfig(cfg plugin.ExecuteConfig) compose.Option { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "WithExecuteConfig", cfg) ret0, _ := ret[0].(compose.Option) @@ -544,6 +530,7 @@ func (mr *MockServiceMockRecorder) WorkflowAsModelTool(ctx, policies any) *gomoc type MockRepository struct { ctrl *gomock.Controller recorder *MockRepositoryMockRecorder + isgomock struct{} } // MockRepositoryMockRecorder is the mock recorder for MockRepository. @@ -592,7 +579,7 @@ func (mr *MockRepositoryMockRecorder) CancelAllRunningNodes(ctx, wfExeID any) *g } // CopyWorkflow mocks base method. -func (m *MockRepository) CopyWorkflow(ctx context.Context, workflowID int64, policy vo.CopyWorkflowPolicy) (*entity.Workflow, error) { +func (m *MockRepository) CopyWorkflow(ctx context.Context, workflowID int64, policy plugin.CopyWorkflowPolicy) (*entity.Workflow, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "CopyWorkflow", ctx, workflowID, policy) ret0, _ := ret[0].(*entity.Workflow)