Compare commits

...

9 Commits

127 changed files with 18014 additions and 538 deletions

View File

@ -22,6 +22,7 @@ import (
"context"
"fmt"
openapiauthApp "github.com/coze-dev/coze-studio/backend/application/openauth"
"github.com/coze-dev/coze-studio/backend/application/plugin"
"github.com/coze-dev/coze-studio/backend/application/singleagent"
"github.com/coze-dev/coze-studio/backend/application/upload"
@ -83,6 +84,7 @@ func UploadFileOpen(ctx context.Context, c *app.RequestContext) {
internalServerErrorResponse(ctx, c, err)
return
}
c.JSON(consts.StatusOK, resp)
}
@ -105,3 +107,24 @@ func GetBotOnlineInfo(ctx context.Context, c *app.RequestContext) {
}
c.JSON(consts.StatusOK, resp)
}
// ImpersonateCozeUser .
// @router /api/permission_api/coze_web_app/impersonate_coze_user [POST]
func ImpersonateCozeUser(ctx context.Context, c *app.RequestContext) {
var err error
var req bot_open_api.ImpersonateCozeUserRequest
err = c.BindAndValidate(&req)
if err != nil {
invalidParamRequestResponse(c, err.Error())
return
}
resp, err := openapiauthApp.OpenAuthApplication.ImpersonateCozeUserAccessToken(ctx, &req)
if err != nil {
internalServerErrorResponse(ctx, c, err)
return
}
c.JSON(consts.StatusOK, resp)
}

View File

@ -23,6 +23,7 @@ import (
"errors"
"fmt"
"io"
"strconv"
"github.com/cloudwego/eino/schema"
"github.com/cloudwego/hertz/pkg/app"
@ -555,7 +556,11 @@ func CreateProjectConversationDef(ctx context.Context, c *app.RequestContext) {
return
}
resp := new(workflow.CreateProjectConversationDefResponse)
resp, err := appworkflow.SVC.CreateApplicationConversationDef(ctx, &req)
if err != nil {
internalServerErrorResponse(ctx, c, err)
return
}
c.JSON(consts.StatusOK, resp)
}
@ -570,8 +575,11 @@ func UpdateProjectConversationDef(ctx context.Context, c *app.RequestContext) {
invalidParamRequestResponse(c, err.Error())
return
}
resp := new(workflow.UpdateProjectConversationDefResponse)
resp, err := appworkflow.SVC.UpdateApplicationConversationDef(ctx, &req)
if err != nil {
internalServerErrorResponse(ctx, c, err)
return
}
c.JSON(consts.StatusOK, resp)
}
@ -587,7 +595,11 @@ func DeleteProjectConversationDef(ctx context.Context, c *app.RequestContext) {
return
}
resp := new(workflow.DeleteProjectConversationDefResponse)
resp, err := appworkflow.SVC.DeleteApplicationConversationDef(ctx, &req)
if err != nil {
internalServerErrorResponse(ctx, c, err)
return
}
c.JSON(consts.StatusOK, resp)
}
@ -603,7 +615,11 @@ func ListProjectConversationDef(ctx context.Context, c *app.RequestContext) {
return
}
resp := new(workflow.ListProjectConversationResponse)
resp, err := appworkflow.SVC.ListApplicationConversationDef(ctx, &req)
if err != nil {
internalServerErrorResponse(ctx, c, err)
return
}
c.JSON(consts.StatusOK, resp)
}
@ -723,7 +739,11 @@ func GetChatFlowRole(ctx context.Context, c *app.RequestContext) {
return
}
resp := new(workflow.GetChatFlowRoleResponse)
resp, err := appworkflow.SVC.GetChatFlowRole(ctx, &req)
if err != nil {
internalServerErrorResponse(ctx, c, err)
return
}
c.JSON(consts.StatusOK, resp)
}
@ -738,8 +758,11 @@ func CreateChatFlowRole(ctx context.Context, c *app.RequestContext) {
invalidParamRequestResponse(c, err.Error())
return
}
resp := new(workflow.CreateChatFlowRoleResponse)
resp, err := appworkflow.SVC.CreateChatFlowRole(ctx, &req)
if err != nil {
internalServerErrorResponse(ctx, c, err)
return
}
c.JSON(consts.StatusOK, resp)
}
@ -755,7 +778,11 @@ func DeleteChatFlowRole(ctx context.Context, c *app.RequestContext) {
return
}
resp := new(workflow.DeleteChatFlowRoleResponse)
resp, err := appworkflow.SVC.DeleteChatFlowRole(ctx, &req)
if err != nil {
internalServerErrorResponse(ctx, c, err)
return
}
c.JSON(consts.StatusOK, resp)
}
@ -1068,9 +1095,62 @@ func OpenAPIChatFlowRun(ctx context.Context, c *app.RequestContext) {
return
}
resp := new(workflow.ChatFlowRunResponse)
w := sse.NewWriter(c)
c.SetContentType("text/event-stream; charset=utf-8")
c.Response.Header.Set("Cache-Control", "no-cache")
c.Response.Header.Set("Connection", "keep-alive")
c.Response.Header.Set("Access-Control-Allow-Origin", "*")
c.JSON(consts.StatusOK, resp)
sr, err := appworkflow.SVC.OpenAPIChatFlowRun(ctx, &req)
if err != nil {
internalServerErrorResponse(ctx, c, err)
return
}
sendChatFlowStreamRunSSE(ctx, w, sr)
}
func sendChatFlowStreamRunSSE(ctx context.Context, w *sse.Writer, sr *schema.StreamReader[[]*workflow.ChatFlowRunResponse]) {
defer func() {
_ = w.Close()
sr.Close()
}()
seq := int64(1)
for {
respList, err := sr.Recv()
if err != nil {
if errors.Is(err, io.EOF) {
// finish
break
}
event := &sse.Event{
Type: "error",
Data: []byte(err.Error()),
}
if err = w.Write(event); err != nil {
logs.CtxErrorf(ctx, "publish stream event failed, err:%v", err)
}
return
}
for _, resp := range respList {
event := &sse.Event{
ID: strconv.FormatInt(seq, 10),
Type: resp.Event,
Data: []byte(resp.Data),
}
if err = w.Write(event); err != nil {
logs.CtxErrorf(ctx, "publish stream event failed, err:%v", err)
return
}
seq++
}
}
}
// OpenAPIGetWorkflowInfo .
@ -1084,7 +1164,11 @@ func OpenAPIGetWorkflowInfo(ctx context.Context, c *app.RequestContext) {
return
}
resp := new(workflow.OpenAPIGetWorkflowInfoResponse)
resp, err := appworkflow.SVC.OpenAPIGetWorkflowInfo(ctx, &req)
if err != nil {
internalServerErrorResponse(ctx, c, err)
return
}
c.JSON(consts.StatusOK, resp)
}
@ -1128,3 +1212,22 @@ func GetExampleWorkFlowList(ctx context.Context, c *app.RequestContext) {
c.JSON(consts.StatusOK, resp)
}
// OpenAPICreateConversation .
// @router /v1/workflow/conversation/create [POST]
func OpenAPICreateConversation(ctx context.Context, c *app.RequestContext) {
var err error
var req workflow.CreateConversationRequest
err = c.BindAndValidate(&req)
if err != nil {
c.String(consts.StatusBadRequest, err.Error())
return
}
resp, err := appworkflow.SVC.OpenAPICreateConversation(ctx, &req)
if err != nil {
internalServerErrorResponse(ctx, c, err)
return
}
c.JSON(consts.StatusOK, resp)
}

View File

@ -38,16 +38,18 @@ import (
const HeaderAuthorizationKey = "Authorization"
var needAuthPath = map[string]bool{
"/v3/chat": true,
"/v1/conversations": true,
"/v1/conversation/create": true,
"/v1/conversation/message/list": true,
"/v1/files/upload": true,
"/v1/workflow/run": true,
"/v1/workflow/stream_run": true,
"/v1/workflow/stream_resume": true,
"/v1/workflow/get_run_history": true,
"/v1/bot/get_online_info": true,
"/v3/chat": true,
"/v1/conversations": true,
"/v1/conversation/create": true,
"/v1/conversation/message/list": true,
"/v1/files/upload": true,
"/v1/workflow/run": true,
"/v1/workflow/stream_run": true,
"/v1/workflow/stream_resume": true,
"/v1/workflow/get_run_history": true,
"/v1/bot/get_online_info": true,
"/v1/workflows/chat": true,
"/v1/workflow/conversation/create": true,
}
var needAuthFunc = map[string]bool{

File diff suppressed because it is too large Load Diff

View File

@ -1,3 +1,19 @@
/*
* 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 thriftgo (0.4.1). DO NOT EDIT.
package common
@ -26,6 +42,8 @@ const (
Scene_GenerateAgentInfo Scene = 8
//openapi
Scene_SceneOpenApi Scene = 9
// 工作流
Scene_SceneWorkflow Scene = 50
)
func (p Scene) String() string {
@ -50,6 +68,8 @@ func (p Scene) String() string {
return "GenerateAgentInfo"
case Scene_SceneOpenApi:
return "SceneOpenApi"
case Scene_SceneWorkflow:
return "SceneWorkflow"
}
return "<UNSET>"
}
@ -76,6 +96,8 @@ func SceneFromString(s string) (Scene, error) {
return Scene_GenerateAgentInfo, nil
case "SceneOpenApi":
return Scene_SceneOpenApi, nil
case "SceneWorkflow":
return Scene_SceneWorkflow, nil
}
return Scene(0), fmt.Errorf("not a valid Scene string")
}

View File

@ -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 thriftgo (0.4.1). DO NOT EDIT.
package coze

View File

@ -13,6 +13,7 @@ type LLMParams struct {
EnableChatHistory bool `json:"enableChatHistory"`
SystemPrompt string `json:"systemPrompt"`
ResponseFormat ResponseFormat `json:"responseFormat"`
ChatHistoryRound int64 `json:"chatHistoryRound"`
}
type ResponseFormat int64

View File

@ -26,14 +26,6 @@ import (
crossworkflow "github.com/coze-dev/coze-studio/backend/crossdomain/contract/workflow"
)
type AgentRuntime struct {
AgentVersion string
IsDraft bool
SpaceID int64
ConnectorID int64
PreRetrieveTools []*agentrun.Tool
}
type EventType string
const (
@ -84,6 +76,8 @@ type SingleAgent struct {
JumpConfig *bot_common.JumpConfig
BackgroundImageInfoList []*bot_common.BackgroundImageInfo
Database []*bot_common.Database
BotMode bot_common.BotMode
LayoutInfo *bot_common.LayoutInfo
ShortcutCommand []string
}

File diff suppressed because it is too large Load Diff

View File

@ -1,3 +1,19 @@
/*
* 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 thriftgo (0.4.1). DO NOT EDIT.
package workflow
@ -106,6 +122,8 @@ type WorkflowService interface {
OpenAPIChatFlowRun(ctx context.Context, request *ChatFlowRunRequest) (r *ChatFlowRunResponse, err error)
OpenAPIGetWorkflowInfo(ctx context.Context, request *OpenAPIGetWorkflowInfoRequest) (r *OpenAPIGetWorkflowInfoResponse, err error)
OpenAPICreateConversation(ctx context.Context, request *CreateConversationRequest) (r *CreateConversationRequest, err error)
}
type WorkflowServiceClient struct {
@ -566,6 +584,15 @@ func (p *WorkflowServiceClient) OpenAPIGetWorkflowInfo(ctx context.Context, requ
}
return _result.GetSuccess(), nil
}
func (p *WorkflowServiceClient) OpenAPICreateConversation(ctx context.Context, request *CreateConversationRequest) (r *CreateConversationRequest, err error) {
var _args WorkflowServiceOpenAPICreateConversationArgs
_args.Request = request
var _result WorkflowServiceOpenAPICreateConversationResult
if err = p.Client_().Call(ctx, "OpenAPICreateConversation", &_args, &_result); err != nil {
return
}
return _result.GetSuccess(), nil
}
type WorkflowServiceProcessor struct {
processorMap map[string]thrift.TProcessorFunction
@ -635,6 +662,7 @@ func NewWorkflowServiceProcessor(handler WorkflowService) *WorkflowServiceProces
self.AddToProcessorMap("OpenAPIGetWorkflowRunHistory", &workflowServiceProcessorOpenAPIGetWorkflowRunHistory{handler: handler})
self.AddToProcessorMap("OpenAPIChatFlowRun", &workflowServiceProcessorOpenAPIChatFlowRun{handler: handler})
self.AddToProcessorMap("OpenAPIGetWorkflowInfo", &workflowServiceProcessorOpenAPIGetWorkflowInfo{handler: handler})
self.AddToProcessorMap("OpenAPICreateConversation", &workflowServiceProcessorOpenAPICreateConversation{handler: handler})
return self
}
func (p *WorkflowServiceProcessor) Process(ctx context.Context, iprot, oprot thrift.TProtocol) (success bool, err thrift.TException) {
@ -2959,6 +2987,54 @@ func (p *workflowServiceProcessorOpenAPIGetWorkflowInfo) Process(ctx context.Con
return true, err
}
type workflowServiceProcessorOpenAPICreateConversation struct {
handler WorkflowService
}
func (p *workflowServiceProcessorOpenAPICreateConversation) Process(ctx context.Context, seqId int32, iprot, oprot thrift.TProtocol) (success bool, err thrift.TException) {
args := WorkflowServiceOpenAPICreateConversationArgs{}
if err = args.Read(iprot); err != nil {
iprot.ReadMessageEnd()
x := thrift.NewTApplicationException(thrift.PROTOCOL_ERROR, err.Error())
oprot.WriteMessageBegin("OpenAPICreateConversation", thrift.EXCEPTION, seqId)
x.Write(oprot)
oprot.WriteMessageEnd()
oprot.Flush(ctx)
return false, err
}
iprot.ReadMessageEnd()
var err2 error
result := WorkflowServiceOpenAPICreateConversationResult{}
var retval *CreateConversationRequest
if retval, err2 = p.handler.OpenAPICreateConversation(ctx, args.Request); err2 != nil {
x := thrift.NewTApplicationException(thrift.INTERNAL_ERROR, "Internal error processing OpenAPICreateConversation: "+err2.Error())
oprot.WriteMessageBegin("OpenAPICreateConversation", thrift.EXCEPTION, seqId)
x.Write(oprot)
oprot.WriteMessageEnd()
oprot.Flush(ctx)
return true, err2
} else {
result.Success = retval
}
if err2 = oprot.WriteMessageBegin("OpenAPICreateConversation", thrift.REPLY, seqId); err2 != nil {
err = err2
}
if err2 = result.Write(oprot); err == nil && err2 != nil {
err = err2
}
if err2 = oprot.WriteMessageEnd(); err == nil && err2 != nil {
err = err2
}
if err2 = oprot.Flush(ctx); err == nil && err2 != nil {
err = err2
}
if err != nil {
return
}
return true, err
}
type WorkflowServiceCreateWorkflowArgs struct {
Request *CreateWorkflowRequest `thrift:"request,1"`
}
@ -16974,3 +17050,295 @@ func (p *WorkflowServiceOpenAPIGetWorkflowInfoResult) String() string {
return fmt.Sprintf("WorkflowServiceOpenAPIGetWorkflowInfoResult(%+v)", *p)
}
type WorkflowServiceOpenAPICreateConversationArgs struct {
Request *CreateConversationRequest `thrift:"request,1"`
}
func NewWorkflowServiceOpenAPICreateConversationArgs() *WorkflowServiceOpenAPICreateConversationArgs {
return &WorkflowServiceOpenAPICreateConversationArgs{}
}
func (p *WorkflowServiceOpenAPICreateConversationArgs) InitDefault() {
}
var WorkflowServiceOpenAPICreateConversationArgs_Request_DEFAULT *CreateConversationRequest
func (p *WorkflowServiceOpenAPICreateConversationArgs) GetRequest() (v *CreateConversationRequest) {
if !p.IsSetRequest() {
return WorkflowServiceOpenAPICreateConversationArgs_Request_DEFAULT
}
return p.Request
}
var fieldIDToName_WorkflowServiceOpenAPICreateConversationArgs = map[int16]string{
1: "request",
}
func (p *WorkflowServiceOpenAPICreateConversationArgs) IsSetRequest() bool {
return p.Request != nil
}
func (p *WorkflowServiceOpenAPICreateConversationArgs) Read(iprot thrift.TProtocol) (err error) {
var fieldTypeId thrift.TType
var fieldId int16
if _, err = iprot.ReadStructBegin(); err != nil {
goto ReadStructBeginError
}
for {
_, fieldTypeId, fieldId, err = iprot.ReadFieldBegin()
if err != nil {
goto ReadFieldBeginError
}
if fieldTypeId == thrift.STOP {
break
}
switch fieldId {
case 1:
if fieldTypeId == thrift.STRUCT {
if err = p.ReadField1(iprot); err != nil {
goto ReadFieldError
}
} else if err = iprot.Skip(fieldTypeId); err != nil {
goto SkipFieldError
}
default:
if err = iprot.Skip(fieldTypeId); err != nil {
goto SkipFieldError
}
}
if err = iprot.ReadFieldEnd(); err != nil {
goto ReadFieldEndError
}
}
if err = iprot.ReadStructEnd(); err != nil {
goto ReadStructEndError
}
return nil
ReadStructBeginError:
return thrift.PrependError(fmt.Sprintf("%T read struct begin error: ", p), err)
ReadFieldBeginError:
return thrift.PrependError(fmt.Sprintf("%T read field %d begin error: ", p, fieldId), err)
ReadFieldError:
return thrift.PrependError(fmt.Sprintf("%T read field %d '%s' error: ", p, fieldId, fieldIDToName_WorkflowServiceOpenAPICreateConversationArgs[fieldId]), err)
SkipFieldError:
return thrift.PrependError(fmt.Sprintf("%T field %d skip type %d error: ", p, fieldId, fieldTypeId), err)
ReadFieldEndError:
return thrift.PrependError(fmt.Sprintf("%T read field end error", p), err)
ReadStructEndError:
return thrift.PrependError(fmt.Sprintf("%T read struct end error: ", p), err)
}
func (p *WorkflowServiceOpenAPICreateConversationArgs) ReadField1(iprot thrift.TProtocol) error {
_field := NewCreateConversationRequest()
if err := _field.Read(iprot); err != nil {
return err
}
p.Request = _field
return nil
}
func (p *WorkflowServiceOpenAPICreateConversationArgs) Write(oprot thrift.TProtocol) (err error) {
var fieldId int16
if err = oprot.WriteStructBegin("OpenAPICreateConversation_args"); err != nil {
goto WriteStructBeginError
}
if p != nil {
if err = p.writeField1(oprot); err != nil {
fieldId = 1
goto WriteFieldError
}
}
if err = oprot.WriteFieldStop(); err != nil {
goto WriteFieldStopError
}
if err = oprot.WriteStructEnd(); err != nil {
goto WriteStructEndError
}
return nil
WriteStructBeginError:
return thrift.PrependError(fmt.Sprintf("%T write struct begin error: ", p), err)
WriteFieldError:
return thrift.PrependError(fmt.Sprintf("%T write field %d error: ", p, fieldId), err)
WriteFieldStopError:
return thrift.PrependError(fmt.Sprintf("%T write field stop error: ", p), err)
WriteStructEndError:
return thrift.PrependError(fmt.Sprintf("%T write struct end error: ", p), err)
}
func (p *WorkflowServiceOpenAPICreateConversationArgs) writeField1(oprot thrift.TProtocol) (err error) {
if err = oprot.WriteFieldBegin("request", thrift.STRUCT, 1); err != nil {
goto WriteFieldBeginError
}
if err := p.Request.Write(oprot); err != nil {
return err
}
if err = oprot.WriteFieldEnd(); err != nil {
goto WriteFieldEndError
}
return nil
WriteFieldBeginError:
return thrift.PrependError(fmt.Sprintf("%T write field 1 begin error: ", p), err)
WriteFieldEndError:
return thrift.PrependError(fmt.Sprintf("%T write field 1 end error: ", p), err)
}
func (p *WorkflowServiceOpenAPICreateConversationArgs) String() string {
if p == nil {
return "<nil>"
}
return fmt.Sprintf("WorkflowServiceOpenAPICreateConversationArgs(%+v)", *p)
}
type WorkflowServiceOpenAPICreateConversationResult struct {
Success *CreateConversationRequest `thrift:"success,0,optional"`
}
func NewWorkflowServiceOpenAPICreateConversationResult() *WorkflowServiceOpenAPICreateConversationResult {
return &WorkflowServiceOpenAPICreateConversationResult{}
}
func (p *WorkflowServiceOpenAPICreateConversationResult) InitDefault() {
}
var WorkflowServiceOpenAPICreateConversationResult_Success_DEFAULT *CreateConversationRequest
func (p *WorkflowServiceOpenAPICreateConversationResult) GetSuccess() (v *CreateConversationRequest) {
if !p.IsSetSuccess() {
return WorkflowServiceOpenAPICreateConversationResult_Success_DEFAULT
}
return p.Success
}
var fieldIDToName_WorkflowServiceOpenAPICreateConversationResult = map[int16]string{
0: "success",
}
func (p *WorkflowServiceOpenAPICreateConversationResult) IsSetSuccess() bool {
return p.Success != nil
}
func (p *WorkflowServiceOpenAPICreateConversationResult) Read(iprot thrift.TProtocol) (err error) {
var fieldTypeId thrift.TType
var fieldId int16
if _, err = iprot.ReadStructBegin(); err != nil {
goto ReadStructBeginError
}
for {
_, fieldTypeId, fieldId, err = iprot.ReadFieldBegin()
if err != nil {
goto ReadFieldBeginError
}
if fieldTypeId == thrift.STOP {
break
}
switch fieldId {
case 0:
if fieldTypeId == thrift.STRUCT {
if err = p.ReadField0(iprot); err != nil {
goto ReadFieldError
}
} else if err = iprot.Skip(fieldTypeId); err != nil {
goto SkipFieldError
}
default:
if err = iprot.Skip(fieldTypeId); err != nil {
goto SkipFieldError
}
}
if err = iprot.ReadFieldEnd(); err != nil {
goto ReadFieldEndError
}
}
if err = iprot.ReadStructEnd(); err != nil {
goto ReadStructEndError
}
return nil
ReadStructBeginError:
return thrift.PrependError(fmt.Sprintf("%T read struct begin error: ", p), err)
ReadFieldBeginError:
return thrift.PrependError(fmt.Sprintf("%T read field %d begin error: ", p, fieldId), err)
ReadFieldError:
return thrift.PrependError(fmt.Sprintf("%T read field %d '%s' error: ", p, fieldId, fieldIDToName_WorkflowServiceOpenAPICreateConversationResult[fieldId]), err)
SkipFieldError:
return thrift.PrependError(fmt.Sprintf("%T field %d skip type %d error: ", p, fieldId, fieldTypeId), err)
ReadFieldEndError:
return thrift.PrependError(fmt.Sprintf("%T read field end error", p), err)
ReadStructEndError:
return thrift.PrependError(fmt.Sprintf("%T read struct end error: ", p), err)
}
func (p *WorkflowServiceOpenAPICreateConversationResult) ReadField0(iprot thrift.TProtocol) error {
_field := NewCreateConversationRequest()
if err := _field.Read(iprot); err != nil {
return err
}
p.Success = _field
return nil
}
func (p *WorkflowServiceOpenAPICreateConversationResult) Write(oprot thrift.TProtocol) (err error) {
var fieldId int16
if err = oprot.WriteStructBegin("OpenAPICreateConversation_result"); err != nil {
goto WriteStructBeginError
}
if p != nil {
if err = p.writeField0(oprot); err != nil {
fieldId = 0
goto WriteFieldError
}
}
if err = oprot.WriteFieldStop(); err != nil {
goto WriteFieldStopError
}
if err = oprot.WriteStructEnd(); err != nil {
goto WriteStructEndError
}
return nil
WriteStructBeginError:
return thrift.PrependError(fmt.Sprintf("%T write struct begin error: ", p), err)
WriteFieldError:
return thrift.PrependError(fmt.Sprintf("%T write field %d error: ", p, fieldId), err)
WriteFieldStopError:
return thrift.PrependError(fmt.Sprintf("%T write field stop error: ", p), err)
WriteStructEndError:
return thrift.PrependError(fmt.Sprintf("%T write struct end error: ", p), err)
}
func (p *WorkflowServiceOpenAPICreateConversationResult) writeField0(oprot thrift.TProtocol) (err error) {
if p.IsSetSuccess() {
if err = oprot.WriteFieldBegin("success", thrift.STRUCT, 0); err != nil {
goto WriteFieldBeginError
}
if err := p.Success.Write(oprot); err != nil {
return err
}
if err = oprot.WriteFieldEnd(); err != nil {
goto WriteFieldEndError
}
}
return nil
WriteFieldBeginError:
return thrift.PrependError(fmt.Sprintf("%T write field 0 begin error: ", p), err)
WriteFieldEndError:
return thrift.PrependError(fmt.Sprintf("%T write field 0 end error: ", p), err)
}
func (p *WorkflowServiceOpenAPICreateConversationResult) String() string {
if p == nil {
return "<nil>"
}
return fmt.Sprintf("WorkflowServiceOpenAPICreateConversationResult(%+v)", *p)
}

View File

@ -1,3 +1,19 @@
/*
* 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 hertz generator. DO NOT EDIT.
package coze
@ -250,6 +266,10 @@ func Register(r *server.Hertz) {
}
{
_permission_api := _api.Group("/permission_api", _permission_apiMw()...)
{
_coze_web_app := _permission_api.Group("/coze_web_app", _coze_web_appMw()...)
_coze_web_app.POST("/impersonate_coze_user", append(_impersonatecozeuserMw(), coze.ImpersonateCozeUser)...)
}
{
_pat := _permission_api.Group("/pat", _patMw()...)
_pat.POST("/create_personal_access_token_and_permission", append(_createpersonalaccesstokenandpermissionMw(), coze.CreatePersonalAccessTokenAndPermission)...)
@ -438,6 +458,10 @@ func Register(r *server.Hertz) {
_workflow.POST("/run", append(_openapirunflowMw(), coze.OpenAPIRunFlow)...)
_workflow.POST("/stream_resume", append(_openapistreamresumeflowMw(), coze.OpenAPIStreamResumeFlow)...)
_workflow.POST("/stream_run", append(_openapistreamrunflowMw(), coze.OpenAPIStreamRunFlow)...)
{
_conversation1 := _workflow.Group("/conversation", _conversation1Mw()...)
_conversation1.POST("/create", append(_openapicreateconversationMw(), coze.OpenAPICreateConversation)...)
}
}
{
_workflows := _v1.Group("/workflows", _workflowsMw()...)

View File

@ -1505,3 +1505,23 @@ func _upload1Mw() []app.HandlerFunc {
// your code...
return nil
}
func _conversation1Mw() []app.HandlerFunc {
// your code...
return nil
}
func _openapicreateconversationMw() []app.HandlerFunc {
// your code...
return nil
}
func _coze_web_appMw() []app.HandlerFunc {
// your code...
return nil
}
func _impersonatecozeuserMw() []app.HandlerFunc {
// your code...
return nil
}

View File

@ -137,7 +137,7 @@ func Init(ctx context.Context) (err error) {
crossconversation.SetDefaultSVC(conversationImpl.InitDomainService(complexServices.conversationSVC.ConversationDomainSVC))
crossmessage.SetDefaultSVC(messageImpl.InitDomainService(complexServices.conversationSVC.MessageDomainSVC))
crossagentrun.SetDefaultSVC(agentrunImpl.InitDomainService(complexServices.conversationSVC.AgentRunDomainSVC))
crossagent.SetDefaultSVC(singleagentImpl.InitDomainService(complexServices.singleAgentSVC.DomainSVC, infra.ImageXClient))
crossagent.SetDefaultSVC(singleagentImpl.InitDomainService(complexServices.singleAgentSVC.DomainSVC))
crossuser.SetDefaultSVC(crossuserImpl.InitDomainService(basicServices.userSVC.DomainSVC))
crossdatacopy.SetDefaultSVC(dataCopyImpl.InitDomainService(basicServices.infra))
crosssearch.SetDefaultSVC(searchImpl.InitDomainService(complexServices.searchSVC.DomainSVC))

View File

@ -56,6 +56,7 @@ func InitService(s *ServiceComponents) *ConversationApplicationService {
arDomainComponents := &agentrun.Components{
RunRecordRepo: repository.NewRunRecordRepo(s.DB, s.IDGen),
ImagexSVC: s.ImageX,
}
agentRunDomainSVC := agentrun.NewService(arDomainComponents)

View File

@ -23,6 +23,7 @@ import (
"github.com/pkg/errors"
"github.com/coze-dev/coze-studio/backend/api/model/app/bot_open_api"
openapimodel "github.com/coze-dev/coze-studio/backend/api/model/permission/openapiauth"
"github.com/coze-dev/coze-studio/backend/application/base/ctxutil"
openapi "github.com/coze-dev/coze-studio/backend/domain/openauth/openapiauth"
@ -111,6 +112,28 @@ func (s *OpenAuthApplicationService) CreatePersonalAccessToken(ctx context.Conte
return resp, nil
}
func (s *OpenAuthApplicationService) ImpersonateCozeUserAccessToken(ctx context.Context, req *bot_open_api.ImpersonateCozeUserRequest) (*bot_open_api.ImpersonateCozeUserResponse, error) {
resp := new(bot_open_api.ImpersonateCozeUserResponse)
userID := ctxutil.GetUIDFromCtx(ctx)
expiredSecond := time.Second * 60 * 15
appReq := &entity.CreateApiKey{
UserID: *userID,
}
apiKeyResp, err := openapiAuthDomainSVC.Create(ctx, appReq)
if err != nil {
logs.CtxErrorf(ctx, "OpenAuthApplicationService.CreatePersonalAccessToken failed, err=%v", err)
return resp, errors.New("CreatePersonalAccessToken failed")
}
resp.Data = &bot_open_api.ImpersonateCozeUserResponseData{
AccessToken: apiKeyResp.ApiKey,
ExpiresIn: time.Now().Add(time.Duration(expiredSecond)).Unix(),
TokenType: "Bearer",
}
return resp, nil
}
func (s *OpenAuthApplicationService) ListPersonalAccessTokens(ctx context.Context, req *openapimodel.ListPersonalAccessTokensRequest) (*openapimodel.ListPersonalAccessTokensResponse, error) {
resp := new(openapimodel.ListPersonalAccessTokensResponse)

View File

@ -23,10 +23,12 @@ import (
"github.com/coze-dev/coze-studio/backend/api/model/crossdomain/database"
"github.com/coze-dev/coze-studio/backend/api/model/data/database/table"
"github.com/coze-dev/coze-studio/backend/api/model/resource/common"
"github.com/coze-dev/coze-studio/backend/api/model/workflow"
"github.com/coze-dev/coze-studio/backend/domain/knowledge/service"
dbservice "github.com/coze-dev/coze-studio/backend/domain/memory/database/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/lang/ternary"
"github.com/coze-dev/coze-studio/backend/pkg/logs"
)
@ -158,7 +160,7 @@ func (w *workflowPacker) GetDataInfo(ctx context.Context) (*dataInfo, error) {
}
func (w *workflowPacker) GetProjectDefaultActions(ctx context.Context) []*common.ProjectResourceAction {
return []*common.ProjectResourceAction{
actions := []*common.ProjectResourceAction{
{
Key: common.ProjectResourceActionKey_Rename,
Enable: true,
@ -184,6 +186,21 @@ func (w *workflowPacker) GetProjectDefaultActions(ctx context.Context) []*common
Enable: true,
},
}
meta, err := w.appContext.WorkflowDomainSVC.Get(ctx, &vo.GetPolicy{
ID: w.resID,
MetaOnly: true,
})
if err != nil {
logs.CtxWarnf(ctx, "get policy failed with '%s', err=%v", w.resID, err)
return actions
}
key := ternary.IFElse(meta.Mode == workflow.WorkflowMode_Workflow, common.ProjectResourceActionKey_SwitchToChatflow, common.ProjectResourceActionKey_SwitchToFuncflow)
action := &common.ProjectResourceAction{
Enable: true,
Key: key,
}
return append(actions, action)
}
type knowledgePacker struct {

View File

@ -370,6 +370,12 @@ func (s *SingleAgentApplicationService) applyAgentUpdates(target *entity.SingleA
}
target.Database = patch.DatabaseList
}
if patch.BotMode != nil {
target.BotMode = ptr.From(patch.BotMode)
}
if patch.LayoutInfo != nil {
target.LayoutInfo = patch.LayoutInfo
}
return target, nil
}
@ -419,11 +425,12 @@ func (s *SingleAgentApplicationService) singleAgentDraftDo2Vo(ctx context.Contex
TaskInfo: &bot_common.TaskInfo{},
CreateTime: do.CreatedAt / 1000,
UpdateTime: do.UpdatedAt / 1000,
BotMode: bot_common.BotMode_SingleMode,
BotMode: do.BotMode,
BackgroundImageInfoList: do.BackgroundImageInfoList,
Status: bot_common.BotStatus_Using,
DatabaseList: do.Database,
ShortcutSort: do.ShortcutCommand,
LayoutInfo: do.LayoutInfo,
}
if do.VariablesMetaID != nil {

File diff suppressed because it is too large Load Diff

View File

@ -25,6 +25,7 @@ import (
"github.com/coze-dev/coze-studio/backend/application/internal"
"github.com/coze-dev/coze-studio/backend/crossdomain/impl/code"
wfconversation "github.com/coze-dev/coze-studio/backend/crossdomain/workflow/conversation"
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"
@ -34,7 +35,6 @@ import (
plugin "github.com/coze-dev/coze-studio/backend/domain/plugin/service"
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"
@ -46,6 +46,8 @@ import (
"github.com/coze-dev/coze-studio/backend/infra/contract/imagex"
"github.com/coze-dev/coze-studio/backend/infra/contract/storage"
"github.com/coze-dev/coze-studio/backend/pkg/logs"
crossconversation "github.com/coze-dev/coze-studio/backend/domain/workflow/crossdomain/conversation"
)
type ServiceComponents struct {
@ -85,6 +87,7 @@ func InitService(ctx context.Context, components *ServiceComponents) (*Applicati
code.SetCodeRunner(components.CodeRunner)
crosssearch.SetNotifier(wfsearch.NewNotify(components.DomainNotifier))
callbacks.AppendGlobalHandlers(workflowservice.GetTokenCallbackHandler())
crossconversation.SetConversationManager(wfconversation.NewConversationRepository())
SVC.DomainSVC = workflowDomainSVC
SVC.ImageX = components.ImageX

View File

@ -164,6 +164,21 @@ func (w *ApplicationService) CreateWorkflow(ctx context.Context, req *workflow.C
if err := checkUserSpace(ctx, uID, spaceID); err != nil {
return nil, err
}
var createConversation bool
if req.ProjectID != nil && req.IsSetFlowMode() && req.GetFlowMode() == workflow.WorkflowMode_ChatFlow && req.IsSetCreateConversation() && req.GetCreateConversation() {
createConversation = true
_, err := GetWorkflowDomainSVC().CreateDraftConversationTemplate(ctx, &vo.CreateConversationTemplateMeta{
AppID: mustParseInt64(req.GetProjectID()),
UserID: uID,
SpaceID: spaceID,
Name: req.Name,
})
if err != nil {
return nil, err
}
}
wf := &vo.MetaCreate{
CreatorID: uID,
SpaceID: spaceID,
@ -175,6 +190,14 @@ func (w *ApplicationService) CreateWorkflow(ctx context.Context, req *workflow.C
Mode: ternary.IFElse(req.IsSetFlowMode(), req.GetFlowMode(), workflow.WorkflowMode_Workflow),
InitCanvasSchema: vo.GetDefaultInitCanvasJsonSchema(i18n.GetLocale(ctx)),
}
if req.IsSetFlowMode() && req.GetFlowMode() == workflow.WorkflowMode_ChatFlow {
conversationName := req.Name
if !req.IsSetProjectID() || mustParseInt64(req.GetProjectID()) == 0 || !createConversation {
conversationName = "Default"
}
wf.InitCanvasSchema = vo.GetDefaultInitCanvasJsonSchemaChat(i18n.GetLocale(ctx), conversationName)
}
id, err := GetWorkflowDomainSVC().Create(ctx, wf)
if err != nil {
@ -232,9 +255,10 @@ func (w *ApplicationService) UpdateWorkflowMeta(ctx context.Context, req *workfl
}
err = GetWorkflowDomainSVC().UpdateMeta(ctx, mustParseInt64(req.GetWorkflowID()), &vo.MetaUpdate{
Name: req.Name,
Desc: req.Desc,
IconURI: req.IconURI,
Name: req.Name,
Desc: req.Desc,
IconURI: req.IconURI,
WorkflowMode: req.FlowMode,
})
if err != nil {
return nil, err
@ -1029,6 +1053,18 @@ func (w *ApplicationService) CopyWorkflowFromLibraryToApp(ctx context.Context, w
wf, err := GetWorkflowDomainSVC().CopyWorkflow(ctx, workflowID, vo.CopyWorkflowPolicy{
TargetAppID: &appID,
})
if wf.Mode == workflow.WorkflowMode_ChatFlow {
err = GetWorkflowDomainSVC().CopyChatFlowRole(ctx, &vo.CopyRolePolicy{
SourceID: workflowID,
TargetID: wf.ID,
CreatorID: wf.CreatorID,
})
if err != nil {
return 0, err
}
}
if err != nil {
return 0, err
}
@ -2076,6 +2112,13 @@ func (w *ApplicationService) ListWorkflow(ctx context.Context, req *workflow.Get
},
}
if len(req.Checker) > 0 && status == workflow.WorkFlowListStatus_HadPublished {
ww.CheckResult, err = GetWorkflowDomainSVC().WorkflowSchemaCheck(ctx, w, req.Checker)
if err != nil {
return nil, err
}
}
if qType == vo.FromDraft {
ww.UpdateTime = w.DraftMeta.Timestamp.Unix()
} else if qType == vo.FromLatestVersion || qType == vo.FromSpecificVersion {
@ -3635,3 +3678,419 @@ func checkUserSpace(ctx context.Context, uid int64, spaceID int64) error {
return nil
}
func (w *ApplicationService) populateChatFlowRoleFields(role *workflow.ChatFlowRole, targetRole interface{}) error {
var avatarUri, audioStr, bgStr, obStr, srStr, uiStr string
var err error
if role.Avatar != nil {
avatarUri = role.Avatar.ImageUri
}
if role.AudioConfig != nil {
audioStr, err = sonic.MarshalString(*role.AudioConfig)
if err != nil {
return vo.WrapError(errno.ErrSerializationDeserializationFail, err)
}
}
if role.BackgroundImageInfo != nil {
bgStr, err = sonic.MarshalString(*role.BackgroundImageInfo)
if err != nil {
return vo.WrapError(errno.ErrSerializationDeserializationFail, err)
}
}
if role.OnboardingInfo != nil {
obStr, err = sonic.MarshalString(*role.OnboardingInfo)
if err != nil {
return vo.WrapError(errno.ErrSerializationDeserializationFail, err)
}
}
if role.SuggestReplyInfo != nil {
srStr, err = sonic.MarshalString(*role.SuggestReplyInfo)
if err != nil {
return vo.WrapError(errno.ErrSerializationDeserializationFail, err)
}
}
if role.UserInputConfig != nil {
uiStr, err = sonic.MarshalString(*role.UserInputConfig)
if err != nil {
return vo.WrapError(errno.ErrSerializationDeserializationFail, err)
}
}
switch r := targetRole.(type) {
case *vo.ChatFlowRoleCreate:
if role.Name != nil {
r.Name = *role.Name
}
if role.Description != nil {
r.Description = *role.Description
}
if avatarUri != "" {
r.AvatarUri = avatarUri
}
if audioStr != "" {
r.AudioConfig = audioStr
}
if bgStr != "" {
r.BackgroundImageInfo = bgStr
}
if obStr != "" {
r.OnboardingInfo = obStr
}
if srStr != "" {
r.SuggestReplyInfo = srStr
}
if uiStr != "" {
r.UserInputConfig = uiStr
}
case *vo.ChatFlowRoleUpdate:
r.Name = role.Name
r.Description = role.Description
if avatarUri != "" {
r.AvatarUri = ptr.Of(avatarUri)
}
if audioStr != "" {
r.AudioConfig = ptr.Of(audioStr)
}
if bgStr != "" {
r.BackgroundImageInfo = ptr.Of(bgStr)
}
if obStr != "" {
r.OnboardingInfo = ptr.Of(obStr)
}
if srStr != "" {
r.SuggestReplyInfo = ptr.Of(srStr)
}
if uiStr != "" {
r.UserInputConfig = ptr.Of(uiStr)
}
default:
return vo.WrapError(errno.ErrInvalidParameter, fmt.Errorf("invalid type for targetRole: %T", targetRole))
}
return nil
}
func IsChatFlow(wf *entity.Workflow) bool {
if wf == nil || wf.ID == 0 {
return false
}
return wf.Meta.Mode == workflow.WorkflowMode_ChatFlow
}
func (w *ApplicationService) CreateChatFlowRole(ctx context.Context, req *workflow.CreateChatFlowRoleRequest) (
_ *workflow.CreateChatFlowRoleResponse, err error) {
defer func() {
if panicErr := recover(); panicErr != nil {
err = safego.NewPanicErr(panicErr, debug.Stack())
}
if err != nil {
err = vo.WrapIfNeeded(errno.ErrChatFlowRoleOperationFail, err, errorx.KV("cause", vo.UnwrapRootErr(err).Error()))
}
}()
uID := ctxutil.MustGetUIDFromCtx(ctx)
wf, err := GetWorkflowDomainSVC().Get(ctx, &vo.GetPolicy{
ID: mustParseInt64(req.GetChatFlowRole().GetWorkflowID()),
MetaOnly: true,
})
if err != nil {
return nil, err
}
if err = checkUserSpace(ctx, uID, wf.Meta.SpaceID); err != nil {
return nil, err
}
role := req.GetChatFlowRole()
if !IsChatFlow(wf) {
logs.CtxWarnf(ctx, "CreateChatFlowRole not chat flow, workflowID: %d", wf.ID)
return nil, vo.WrapError(errno.ErrChatFlowRoleOperationFail, fmt.Errorf("workflow %d is not a chat flow", wf.ID))
}
oldRole, err := GetWorkflowDomainSVC().GetChatFlowRole(ctx, mustParseInt64(role.WorkflowID), "")
if err != nil {
return nil, err
}
var roleID int64
if oldRole != nil {
role.ID = strconv.FormatInt(oldRole.ID, 10)
roleID = oldRole.ID
}
if role.GetID() == "" || role.GetID() == "0" {
chatFlowRole := &vo.ChatFlowRoleCreate{
WorkflowID: mustParseInt64(role.WorkflowID),
CreatorID: uID,
}
if err = w.populateChatFlowRoleFields(role, chatFlowRole); err != nil {
return nil, err
}
roleID, err = GetWorkflowDomainSVC().CreateChatFlowRole(ctx, chatFlowRole)
if err != nil {
return nil, err
}
} else {
chatFlowRole := &vo.ChatFlowRoleUpdate{
WorkflowID: mustParseInt64(role.WorkflowID),
}
if err = w.populateChatFlowRoleFields(role, chatFlowRole); err != nil {
return nil, err
}
err = GetWorkflowDomainSVC().UpdateChatFlowRole(ctx, chatFlowRole.WorkflowID, chatFlowRole)
if err != nil {
return nil, err
}
}
return &workflow.CreateChatFlowRoleResponse{
ID: strconv.FormatInt(roleID, 10),
}, nil
}
func (w *ApplicationService) DeleteChatFlowRole(ctx context.Context, req *workflow.DeleteChatFlowRoleRequest) (
_ *workflow.DeleteChatFlowRoleResponse, err error) {
defer func() {
if panicErr := recover(); panicErr != nil {
err = safego.NewPanicErr(panicErr, debug.Stack())
}
if err != nil {
err = vo.WrapIfNeeded(errno.ErrChatFlowRoleOperationFail, err, errorx.KV("cause", vo.UnwrapRootErr(err).Error()))
}
}()
uID := ctxutil.MustGetUIDFromCtx(ctx)
wf, err := GetWorkflowDomainSVC().Get(ctx, &vo.GetPolicy{
ID: mustParseInt64(req.GetWorkflowID()),
MetaOnly: true,
})
if err != nil {
return nil, err
}
if err = checkUserSpace(ctx, uID, wf.Meta.SpaceID); err != nil {
return nil, err
}
err = GetWorkflowDomainSVC().DeleteChatFlowRole(ctx, mustParseInt64(req.ID), mustParseInt64(req.WorkflowID))
if err != nil {
return nil, err
}
return &workflow.DeleteChatFlowRoleResponse{}, nil
}
func (w *ApplicationService) GetChatFlowRole(ctx context.Context, req *workflow.GetChatFlowRoleRequest) (
_ *workflow.GetChatFlowRoleResponse, err error) {
defer func() {
if panicErr := recover(); panicErr != nil {
err = safego.NewPanicErr(panicErr, debug.Stack())
}
if err != nil {
err = vo.WrapIfNeeded(errno.ErrChatFlowRoleOperationFail, err, errorx.KV("cause", vo.UnwrapRootErr(err).Error()))
}
}()
uID := ctxutil.MustGetUIDFromCtx(ctx)
wf, err := GetWorkflowDomainSVC().Get(ctx, &vo.GetPolicy{
ID: mustParseInt64(req.GetWorkflowID()),
MetaOnly: true,
})
if err != nil {
return nil, err
}
if err = checkUserSpace(ctx, uID, wf.Meta.SpaceID); err != nil {
return nil, err
}
if !IsChatFlow(wf) {
logs.CtxWarnf(ctx, "GetChatFlowRole not chat flow, workflowID: %d", wf.ID)
return nil, vo.WrapError(errno.ErrChatFlowRoleOperationFail, fmt.Errorf("workflow %d is not a chat flow", wf.ID))
}
var version string
if wf.Meta.AppID != nil {
if vl, err := GetWorkflowDomainSVC().GetWorkflowVersionsByConnector(ctx, mustParseInt64(req.GetConnectorID()), wf.ID, 1); err != nil {
return nil, err
} else if len(vl) > 0 {
version = vl[0]
}
}
role, err := GetWorkflowDomainSVC().GetChatFlowRole(ctx, mustParseInt64(req.WorkflowID), version)
if err != nil {
return nil, err
}
if role == nil {
logs.CtxWarnf(ctx, "GetChatFlowRole role nil, workflowID: %d", wf.ID)
// Return nil for the error to align with the production behavior,
// where the GET API may be called before the CREATE API during chatflow creation.
return &workflow.GetChatFlowRoleResponse{}, nil
}
wfRole, err := w.convertChatFlowRole(ctx, role)
if err != nil {
return nil, fmt.Errorf("failed to get chat flow role config, internal data processing error: %+v", err)
}
return &workflow.GetChatFlowRoleResponse{
Role: wfRole,
}, nil
}
func (w *ApplicationService) convertChatFlowRole(ctx context.Context, role *entity.ChatFlowRole) (*workflow.ChatFlowRole, error) {
var err error
res := &workflow.ChatFlowRole{
ID: strconv.FormatInt(role.ID, 10),
WorkflowID: strconv.FormatInt(role.WorkflowID, 10),
Name: ptr.Of(role.Name),
Description: ptr.Of(role.Description),
}
if role.AvatarUri != "" {
url, err := w.ImageX.GetResourceURL(ctx, role.AvatarUri)
if err != nil {
return nil, err
}
res.Avatar = &workflow.AvatarConfig{
ImageUri: role.AvatarUri,
ImageUrl: url.URL,
}
}
if role.AudioConfig != "" {
err = sonic.UnmarshalString(role.AudioConfig, &res.AudioConfig)
if err != nil {
logs.CtxErrorf(ctx, "GetChatFlowRole AudioConfig UnmarshalString err: %+v", err)
return nil, vo.WrapError(errno.ErrSerializationDeserializationFail, err)
}
}
if role.OnboardingInfo != "" {
err = sonic.UnmarshalString(role.OnboardingInfo, &res.OnboardingInfo)
if err != nil {
logs.CtxErrorf(ctx, "GetChatFlowRole OnboardingInfo UnmarshalString err: %+v", err)
return nil, vo.WrapError(errno.ErrSerializationDeserializationFail, err)
}
}
if role.SuggestReplyInfo != "" {
err = sonic.UnmarshalString(role.SuggestReplyInfo, &res.SuggestReplyInfo)
if err != nil {
logs.CtxErrorf(ctx, "GetChatFlowRole SuggestReplyInfo UnmarshalString err: %+v", err)
return nil, vo.WrapError(errno.ErrSerializationDeserializationFail, err)
}
}
if role.UserInputConfig != "" {
err = sonic.UnmarshalString(role.UserInputConfig, &res.UserInputConfig)
if err != nil {
logs.CtxErrorf(ctx, "GetChatFlowRole UserInputConfig UnmarshalString err: %+v", err)
return nil, vo.WrapError(errno.ErrSerializationDeserializationFail, err)
}
}
if role.BackgroundImageInfo != "" {
res.BackgroundImageInfo = &workflow.BackgroundImageInfo{}
err = sonic.UnmarshalString(role.BackgroundImageInfo, res.BackgroundImageInfo)
if err != nil {
logs.CtxErrorf(ctx, "GetChatFlowRole BackgroundImageInfo UnmarshalString err: %+v", err)
return nil, vo.WrapError(errno.ErrSerializationDeserializationFail, err)
}
if res.BackgroundImageInfo != nil {
if res.BackgroundImageInfo.WebBackgroundImage != nil && res.BackgroundImageInfo.WebBackgroundImage.OriginImageUri != nil {
url, err := w.ImageX.GetResourceURL(ctx, res.BackgroundImageInfo.WebBackgroundImage.GetOriginImageUri())
if err != nil {
logs.CtxErrorf(ctx, "get url by uri err, err:%s", err.Error())
return nil, err
}
res.BackgroundImageInfo.WebBackgroundImage.ImageUrl = &url.URL
}
if res.BackgroundImageInfo.MobileBackgroundImage != nil && res.BackgroundImageInfo.MobileBackgroundImage.OriginImageUri != nil {
url, err := w.ImageX.GetResourceURL(ctx, res.BackgroundImageInfo.MobileBackgroundImage.GetOriginImageUri())
if err != nil {
logs.CtxErrorf(ctx, "get url by uri err, err:%s", err.Error())
return nil, err
}
res.BackgroundImageInfo.MobileBackgroundImage.ImageUrl = &url.URL
}
}
}
return res, nil
}
func (w *ApplicationService) OpenAPIGetWorkflowInfo(ctx context.Context, req *workflow.OpenAPIGetWorkflowInfoRequest) (
_ *workflow.OpenAPIGetWorkflowInfoResponse, err error) {
defer func() {
if panicErr := recover(); panicErr != nil {
err = safego.NewPanicErr(panicErr, debug.Stack())
}
if err != nil {
err = vo.WrapIfNeeded(errno.ErrChatFlowRoleOperationFail, err, errorx.KV("cause", vo.UnwrapRootErr(err).Error()))
}
}()
uID := ctxutil.MustGetUIDFromCtx(ctx)
wf, err := GetWorkflowDomainSVC().Get(ctx, &vo.GetPolicy{
ID: mustParseInt64(req.GetWorkflowID()),
MetaOnly: true,
})
if err != nil {
return nil, err
}
if err = checkUserSpace(ctx, uID, wf.Meta.SpaceID); err != nil {
return nil, err
}
if !IsChatFlow(wf) {
logs.CtxWarnf(ctx, "GetChatFlowRole not chat flow, workflowID: %d", wf.ID)
return nil, vo.WrapError(errno.ErrChatFlowRoleOperationFail, fmt.Errorf("workflow %d is not a chat flow", wf.ID))
}
var version string
if wf.Meta.AppID != nil {
if vl, err := GetWorkflowDomainSVC().GetWorkflowVersionsByConnector(ctx, mustParseInt64(req.GetConnectorID()), wf.ID, 1); err != nil {
return nil, err
} else if len(vl) > 0 {
version = vl[0]
}
}
role, err := GetWorkflowDomainSVC().GetChatFlowRole(ctx, mustParseInt64(req.WorkflowID), version)
if err != nil {
return nil, err
}
if role == nil {
logs.CtxWarnf(ctx, "GetChatFlowRole role nil, workflowID: %d", wf.ID)
// Return nil for the error to align with the production behavior,
// where the GET API may be called before the CREATE API during chatflow creation.
return &workflow.OpenAPIGetWorkflowInfoResponse{}, nil
}
wfRole, err := w.convertChatFlowRole(ctx, role)
if err != nil {
return nil, fmt.Errorf("failed to get chat flow role config, internal data processing error: %+v", err)
}
return &workflow.OpenAPIGetWorkflowInfoResponse{
WorkflowInfo: &workflow.WorkflowInfo{
Role: wfRole,
},
}, nil
}

View File

@ -21,17 +21,31 @@ import (
"github.com/cloudwego/eino/schema"
"github.com/coze-dev/coze-studio/backend/api/model/crossdomain/message"
"github.com/coze-dev/coze-studio/backend/api/model/crossdomain/agentrun"
"github.com/coze-dev/coze-studio/backend/api/model/crossdomain/singleagent"
)
// Requests and responses must not reference domain entities and can only use models under api/model/crossdomain.
type SingleAgent interface {
StreamExecute(ctx context.Context, historyMsg []*message.Message, query *message.Message,
agentRuntime *singleagent.AgentRuntime) (*schema.StreamReader[*singleagent.AgentEvent], error)
StreamExecute(ctx context.Context,
agentRuntime *AgentRuntime) (*schema.StreamReader[*singleagent.AgentEvent], error)
ObtainAgentByIdentity(ctx context.Context, identity *singleagent.AgentIdentity) (*singleagent.SingleAgent, error)
}
type AgentRuntime struct {
AgentVersion string
UserID string
AgentID int64
IsDraft bool
SpaceID int64
ConnectorID int64
PreRetrieveTools []*agentrun.Tool
HistoryMsg []*schema.Message
Input *schema.Message
ResumeInfo *ResumeInfo
}
type ResumeInfo = singleagent.InterruptInfo
type AgentEvent = singleagent.AgentEvent

View File

@ -20,10 +20,14 @@ import (
"context"
"github.com/coze-dev/coze-studio/backend/api/model/crossdomain/conversation"
"github.com/coze-dev/coze-studio/backend/domain/conversation/conversation/entity"
)
type Conversation interface {
GetCurrentConversation(ctx context.Context, req *conversation.GetCurrent) (*conversation.Conversation, error)
Create(ctx context.Context, req *entity.CreateMeta) (*entity.Conversation, error)
NewConversationCtx(ctx context.Context, req *entity.NewConversationCtxRequest) (*entity.NewConversationCtxResponse, error)
GetByID(ctx context.Context, id int64) (*entity.Conversation, error)
}
var defaultSVC Conversation

View File

@ -20,13 +20,16 @@ import (
"context"
"github.com/coze-dev/coze-studio/backend/api/model/crossdomain/message"
"github.com/coze-dev/coze-studio/backend/domain/conversation/message/entity"
)
type Message interface {
GetByRunIDs(ctx context.Context, conversationID int64, runIDs []int64) ([]*message.Message, error)
PreCreate(ctx context.Context, msg *message.Message) (*message.Message, error)
Create(ctx context.Context, msg *message.Message) (*message.Message, error)
List(ctx context.Context, meta *entity.ListMeta) (*entity.ListResult, error)
Edit(ctx context.Context, msg *message.Message) (*message.Message, error)
Delete(ctx context.Context, req *entity.DeleteMeta) error
}
var defaultSVC Message

View File

@ -39,18 +39,30 @@ type Workflow interface {
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)
StreamExecute(ctx context.Context, config vo.ExecuteConfig, input map[string]any) (*schema.StreamReader[*workflowEntity.Message], error)
WithExecuteConfig(cfg vo.ExecuteConfig) einoCompose.Option
WithMessagePipe() (compose.Option, *schema.StreamReader[*entity.Message])
InitApplicationDefaultConversationTemplate(ctx context.Context, spaceID int64, appID int64, userID int64) error
}
type ExecuteConfig = vo.ExecuteConfig
type WorkflowMessage = workflowEntity.Message
type ExecuteMode = vo.ExecuteMode
type NodeType = entity.NodeType
type MessageType = entity.MessageType
type InterruptEvent = workflowEntity.InterruptEvent
type EventType = workflowEntity.InterruptEventType
type WorkflowMessage = entity.Message
const (
Answer MessageType = "answer"
FunctionCall MessageType = "function_call"
ToolResponse MessageType = "tool_response"
)
const (
NodeTypeOutputEmitter NodeType = "OutputEmitter"
NodeTypeInputReceiver NodeType = "InputReceiver"
NodeTypeQuestion NodeType = "Question"
)
const (
@ -59,6 +71,14 @@ const (
ExecuteModeNodeDebug ExecuteMode = "node_debug"
)
type SyncPattern = vo.SyncPattern
const (
SyncPatternSync SyncPattern = "sync"
SyncPatternAsync SyncPattern = "async"
SyncPatternStream SyncPattern = "stream"
)
type TaskType = vo.TaskType
const (

View File

@ -21,6 +21,7 @@ import (
model "github.com/coze-dev/coze-studio/backend/api/model/crossdomain/conversation"
crossconversation "github.com/coze-dev/coze-studio/backend/crossdomain/contract/conversation"
"github.com/coze-dev/coze-studio/backend/domain/conversation/conversation/entity"
conversation "github.com/coze-dev/coze-studio/backend/domain/conversation/conversation/service"
)
@ -40,3 +41,15 @@ func InitDomainService(c conversation.Conversation) crossconversation.Conversati
func (s *impl) GetCurrentConversation(ctx context.Context, req *model.GetCurrent) (*model.Conversation, error) {
return s.DomainSVC.GetCurrentConversation(ctx, req)
}
func (s *impl) Create(ctx context.Context, req *entity.CreateMeta) (*entity.Conversation, error) {
return s.DomainSVC.Create(ctx, req)
}
func (s *impl) NewConversationCtx(ctx context.Context, req *entity.NewConversationCtxRequest) (*entity.NewConversationCtxResponse, error) {
return s.DomainSVC.NewConversationCtx(ctx, req)
}
func (s *impl) GetByID(ctx context.Context, id int64) (*entity.Conversation, error) {
return s.DomainSVC.GetByID(ctx, id)
}

View File

@ -21,6 +21,8 @@ import (
model "github.com/coze-dev/coze-studio/backend/api/model/crossdomain/message"
crossmessage "github.com/coze-dev/coze-studio/backend/crossdomain/contract/message"
"github.com/coze-dev/coze-studio/backend/domain/conversation/message/entity"
message "github.com/coze-dev/coze-studio/backend/domain/conversation/message/service"
)
@ -53,3 +55,11 @@ func (c *impl) Edit(ctx context.Context, msg *model.Message) (*model.Message, er
func (c *impl) PreCreate(ctx context.Context, msg *model.Message) (*model.Message, error) {
return c.DomainSVC.PreCreate(ctx, msg)
}
func (c *impl) List(ctx context.Context, lm *entity.ListMeta) (*entity.ListResult, error) {
return c.DomainSVC.List(ctx, lm)
}
func (c *impl) Delete(ctx context.Context, req *entity.DeleteMeta) error {
return c.DomainSVC.Delete(ctx, req)
}

View File

@ -18,17 +18,13 @@ package agent
import (
"context"
"encoding/json"
"github.com/cloudwego/eino/schema"
"github.com/coze-dev/coze-studio/backend/api/model/crossdomain/agentrun"
"github.com/coze-dev/coze-studio/backend/api/model/crossdomain/message"
model "github.com/coze-dev/coze-studio/backend/api/model/crossdomain/singleagent"
crossagent "github.com/coze-dev/coze-studio/backend/crossdomain/contract/agent"
singleagent "github.com/coze-dev/coze-studio/backend/domain/agent/singleagent/service"
"github.com/coze-dev/coze-studio/backend/domain/conversation/message/entity"
"github.com/coze-dev/coze-studio/backend/infra/contract/imagex"
"github.com/coze-dev/coze-studio/backend/pkg/lang/conv"
"github.com/coze-dev/coze-studio/backend/pkg/lang/slices"
"github.com/coze-dev/coze-studio/backend/pkg/logs"
@ -38,49 +34,34 @@ var defaultSVC crossagent.SingleAgent
type impl struct {
DomainSVC singleagent.SingleAgent
ImagexSVC imagex.ImageX
}
func InitDomainService(c singleagent.SingleAgent, imagexClient imagex.ImageX) crossagent.SingleAgent {
func InitDomainService(c singleagent.SingleAgent) crossagent.SingleAgent {
defaultSVC = &impl{
DomainSVC: c,
ImagexSVC: imagexClient,
}
return defaultSVC
}
func (c *impl) StreamExecute(ctx context.Context, historyMsg []*message.Message,
query *message.Message, agentRuntime *model.AgentRuntime,
func (c *impl) StreamExecute(ctx context.Context, agentRuntime *crossagent.AgentRuntime,
) (*schema.StreamReader[*model.AgentEvent], error) {
historyMsg = c.historyPairs(historyMsg)
singleAgentStreamExecReq := c.buildSingleAgentStreamExecuteReq(ctx, historyMsg, query, agentRuntime)
singleAgentStreamExecReq := c.buildSingleAgentStreamExecuteReq(ctx, agentRuntime)
streamEvent, err := c.DomainSVC.StreamExecute(ctx, singleAgentStreamExecReq)
logs.CtxInfof(ctx, "agent StreamExecute req:%v, streamEvent:%v, err:%v", conv.DebugJsonToStr(singleAgentStreamExecReq), streamEvent, err)
return streamEvent, err
}
func (c *impl) buildSingleAgentStreamExecuteReq(ctx context.Context, historyMsg []*message.Message,
input *message.Message, agentRuntime *model.AgentRuntime,
func (c *impl) buildSingleAgentStreamExecuteReq(ctx context.Context, agentRuntime *crossagent.AgentRuntime,
) *model.ExecuteRequest {
identity := c.buildIdentity(input, agentRuntime)
inputBuild := c.buildSchemaMessage(ctx, []*message.Message{input})
var inputSM *schema.Message
if len(inputBuild) > 0 {
inputSM = inputBuild[0]
}
history := c.buildSchemaMessage(ctx, historyMsg)
resumeInfo := c.checkResumeInfo(ctx, historyMsg)
return &model.ExecuteRequest{
Identity: identity,
Input: inputSM,
History: history,
UserID: input.UserID,
Identity: c.buildIdentity(agentRuntime),
Input: agentRuntime.Input,
History: agentRuntime.HistoryMsg,
UserID: agentRuntime.UserID,
PreCallTools: slices.Transform(agentRuntime.PreRetrieveTools, func(tool *agentrun.Tool) *agentrun.ToolsRetriever {
return &agentrun.ToolsRetriever{
PluginID: tool.PluginID,
@ -98,141 +79,19 @@ func (c *impl) buildSingleAgentStreamExecuteReq(ctx context.Context, historyMsg
}(tool.Type),
}
}),
ResumeInfo: resumeInfo,
ResumeInfo: agentRuntime.ResumeInfo,
}
}
func (c *impl) historyPairs(historyMsg []*message.Message) []*message.Message {
fcMsgPairs := make(map[int64][]*message.Message)
for _, one := range historyMsg {
if one.MessageType != message.MessageTypeFunctionCall && one.MessageType != message.MessageTypeToolResponse {
continue
}
if _, ok := fcMsgPairs[one.RunID]; !ok {
fcMsgPairs[one.RunID] = []*message.Message{one}
} else {
fcMsgPairs[one.RunID] = append(fcMsgPairs[one.RunID], one)
}
}
var historyAfterPairs []*message.Message
for _, value := range historyMsg {
if value.MessageType == message.MessageTypeFunctionCall {
if len(fcMsgPairs[value.RunID])%2 == 0 {
historyAfterPairs = append(historyAfterPairs, value)
}
} else {
historyAfterPairs = append(historyAfterPairs, value)
}
}
return historyAfterPairs
}
func (c *impl) checkResumeInfo(_ context.Context, historyMsg []*message.Message) *crossagent.ResumeInfo {
var resumeInfo *crossagent.ResumeInfo
for i := len(historyMsg) - 1; i >= 0; i-- {
if historyMsg[i].MessageType == message.MessageTypeQuestion {
break
}
if historyMsg[i].MessageType == message.MessageTypeVerbose {
if historyMsg[i].Ext[string(entity.ExtKeyResumeInfo)] != "" {
err := json.Unmarshal([]byte(historyMsg[i].Ext[string(entity.ExtKeyResumeInfo)]), &resumeInfo)
if err != nil {
return nil
}
}
}
}
return resumeInfo
}
func (c *impl) buildSchemaMessage(ctx context.Context, msgs []*message.Message) []*schema.Message {
schemaMessage := make([]*schema.Message, 0, len(msgs))
for _, msgOne := range msgs {
if msgOne.ModelContent == "" {
continue
}
if msgOne.MessageType == message.MessageTypeVerbose || msgOne.MessageType == message.MessageTypeFlowUp {
continue
}
var sm *schema.Message
err := json.Unmarshal([]byte(msgOne.ModelContent), &sm)
if err != nil {
continue
}
if len(sm.ReasoningContent) > 0 {
sm.ReasoningContent = ""
}
schemaMessage = append(schemaMessage, c.parseMessageURI(ctx, sm))
}
return schemaMessage
}
func (c *impl) parseMessageURI(ctx context.Context, mcMsg *schema.Message) *schema.Message {
if mcMsg.MultiContent == nil {
return mcMsg
}
for k, one := range mcMsg.MultiContent {
switch one.Type {
case schema.ChatMessagePartTypeImageURL:
if one.ImageURL.URI != "" {
url, err := c.ImagexSVC.GetResourceURL(ctx, one.ImageURL.URI)
if err == nil {
mcMsg.MultiContent[k].ImageURL.URL = url.URL
}
}
case schema.ChatMessagePartTypeFileURL:
if one.FileURL.URI != "" {
url, err := c.ImagexSVC.GetResourceURL(ctx, one.FileURL.URI)
if err == nil {
mcMsg.MultiContent[k].FileURL.URL = url.URL
}
}
case schema.ChatMessagePartTypeAudioURL:
if one.AudioURL.URI != "" {
url, err := c.ImagexSVC.GetResourceURL(ctx, one.AudioURL.URI)
if err == nil {
mcMsg.MultiContent[k].AudioURL.URL = url.URL
}
}
case schema.ChatMessagePartTypeVideoURL:
if one.VideoURL.URI != "" {
url, err := c.ImagexSVC.GetResourceURL(ctx, one.VideoURL.URI)
if err == nil {
mcMsg.MultiContent[k].VideoURL.URL = url.URL
}
}
}
}
return mcMsg
}
func (c *impl) buildIdentity(input *message.Message, agentRuntime *model.AgentRuntime) *model.AgentIdentity {
func (c *impl) buildIdentity(agentRuntime *crossagent.AgentRuntime) *model.AgentIdentity {
return &model.AgentIdentity{
AgentID: input.AgentID,
AgentID: agentRuntime.AgentID,
Version: agentRuntime.AgentVersion,
IsDraft: agentRuntime.IsDraft,
ConnectorID: agentRuntime.ConnectorID,
}
}
func (c *impl) GetSingleAgent(ctx context.Context, agentID int64, version string) (agent *model.SingleAgent, err error) {
agentInfo, err := c.DomainSVC.GetSingleAgent(ctx, agentID, version)
if err != nil {
return nil, err
}
return agentInfo.SingleAgent, nil
}
func (c *impl) ObtainAgentByIdentity(ctx context.Context, identity *model.AgentIdentity) (*model.SingleAgent, error) {
agentInfo, err := c.DomainSVC.ObtainAgentByIdentity(ctx, identity)
if err != nil {

View File

@ -70,11 +70,17 @@ func (i *impl) WithResumeToolWorkflow(resumingEvent *workflowEntity.ToolInterrup
func (i *impl) SyncExecuteWorkflow(ctx context.Context, config vo.ExecuteConfig, input map[string]any) (*workflowEntity.WorkflowExecution, vo.TerminatePlan, error) {
return i.DomainSVC.SyncExecute(ctx, config, input)
}
func (i *impl) StreamExecute(ctx context.Context, config vo.ExecuteConfig, input map[string]any) (*schema.StreamReader[*workflowEntity.Message], error) {
return i.DomainSVC.StreamExecute(ctx, config, input)
}
func (i *impl) WithExecuteConfig(cfg vo.ExecuteConfig) einoCompose.Option {
return i.DomainSVC.WithExecuteConfig(cfg)
}
func (i *impl) InitApplicationDefaultConversationTemplate(ctx context.Context, spaceID int64, appID int64, userID int64) error {
return i.DomainSVC.InitApplicationDefaultConversationTemplate(ctx, spaceID, appID, userID)
}
func (i *impl) WithMessagePipe() (compose.Option, *schema.StreamReader[*entity.Message]) {
return i.DomainSVC.WithMessagePipe()
}

View File

@ -0,0 +1,206 @@
/*
* Copyright 2025 coze-dev Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package conversation
import (
"context"
"strconv"
"github.com/cloudwego/eino/schema"
"github.com/coze-dev/coze-studio/backend/api/model/conversation/common"
"github.com/coze-dev/coze-studio/backend/api/model/crossdomain/message"
crossconversation "github.com/coze-dev/coze-studio/backend/crossdomain/contract/conversation"
crossmessage "github.com/coze-dev/coze-studio/backend/crossdomain/contract/message"
"github.com/coze-dev/coze-studio/backend/domain/conversation/conversation/entity"
msgentity "github.com/coze-dev/coze-studio/backend/domain/conversation/message/entity"
"github.com/coze-dev/coze-studio/backend/domain/workflow/crossdomain/conversation"
"github.com/coze-dev/coze-studio/backend/pkg/lang/ptr"
)
type ConversationRepository struct {
}
func NewConversationRepository() *ConversationRepository {
return &ConversationRepository{}
}
func (c *ConversationRepository) CreateConversation(ctx context.Context, req *conversation.CreateConversationRequest) (int64, int64, error) {
ret, err := crossconversation.DefaultSVC().Create(ctx, &entity.CreateMeta{
AgentID: req.AppID,
UserID: req.UserID,
ConnectorID: req.ConnectorID,
Scene: common.Scene_SceneWorkflow,
})
if err != nil {
return 0, 0, err
}
return ret.ID, ret.SectionID, nil
}
func (c *ConversationRepository) GetByID(ctx context.Context, id int64) (*entity.Conversation, error) {
return crossconversation.DefaultSVC().GetByID(ctx, id)
}
func (c *ConversationRepository) CreateMessage(ctx context.Context, req *conversation.CreateMessageRequest) (int64, error) {
msg := &message.Message{
ConversationID: req.ConversationID,
Role: schema.RoleType(req.Role),
Content: req.Content,
ContentType: message.ContentType(req.ContentType),
UserID: strconv.FormatInt(req.UserID, 10),
AgentID: req.AppID,
RunID: req.RunID,
SectionID: req.SectionID,
}
if msg.Role == schema.User {
msg.MessageType = message.MessageTypeQuestion
} else {
msg.MessageType = message.MessageTypeAnswer
}
ret, err := crossmessage.DefaultSVC().Create(ctx, msg)
if err != nil {
return 0, err
}
return ret.ID, nil
}
func (c *ConversationRepository) MessageList(ctx context.Context, req *conversation.MessageListRequest) (*conversation.MessageListResponse, error) {
lm := &msgentity.ListMeta{
ConversationID: req.ConversationID,
Limit: int(req.Limit), // Since the value of limit is checked inside the node, the type cast here is safe
UserID: strconv.FormatInt(req.UserID, 10),
AgentID: req.AppID,
OrderBy: req.OrderBy,
}
if req.BeforeID != nil {
lm.Cursor, _ = strconv.ParseInt(*req.BeforeID, 10, 64)
lm.Direction = msgentity.ScrollPageDirectionNext
}
if req.AfterID != nil {
lm.Cursor, _ = strconv.ParseInt(*req.AfterID, 10, 64)
lm.Direction = msgentity.ScrollPageDirectionPrev
}
lr, err := crossmessage.DefaultSVC().List(ctx, lm)
if err != nil {
return nil, err
}
response := &conversation.MessageListResponse{}
if lr.PrevCursor > 0 {
response.FirstID = strconv.FormatInt(lr.PrevCursor, 10)
}
if lr.NextCursor > 0 {
response.LastID = strconv.FormatInt(lr.NextCursor, 10)
}
if len(lr.Messages) == 0 {
return response, nil
}
messages, err := convertMessage(lr.Messages)
if err != nil {
return nil, err
}
response.Messages = messages
return response, nil
}
func (c *ConversationRepository) ClearConversationHistory(ctx context.Context, req *conversation.ClearConversationHistoryReq) (int64, error) {
resp, err := crossconversation.DefaultSVC().NewConversationCtx(ctx, &entity.NewConversationCtxRequest{
ID: req.ConversationID,
})
if err != nil {
return 0, err
}
return resp.SectionID, nil
}
func (c *ConversationRepository) DeleteMessage(ctx context.Context, req *conversation.DeleteMessageRequest) error {
return crossmessage.DefaultSVC().Delete(ctx, &msgentity.DeleteMeta{
MessageIDs: []int64{req.MessageID},
})
}
func (c *ConversationRepository) EditMessage(ctx context.Context, req *conversation.EditMessageRequest) error {
_, err := crossmessage.DefaultSVC().Edit(ctx, &msgentity.Message{
ID: req.MessageID,
ConversationID: req.ConversationID,
Content: req.Content,
})
if err != nil {
return err
}
return nil
}
func (c *ConversationRepository) GetLatestRunIDs(ctx context.Context, req *conversation.GetLatestRunIDsRequest) ([]int64, error) {
return []int64{0}, nil
}
func (c *ConversationRepository) GetMessagesByRunIDs(ctx context.Context, req *conversation.GetMessagesByRunIDsRequest) (*conversation.GetMessagesByRunIDsResponse, error) {
messages, err := crossmessage.DefaultSVC().GetByRunIDs(ctx, req.ConversationID, req.RunIDs)
if err != nil {
return nil, err
}
msgs, err := convertMessage(messages)
if err != nil {
return nil, err
}
return &conversation.GetMessagesByRunIDsResponse{
Messages: msgs,
}, nil
}
func convertMessage(msgs []*msgentity.Message) ([]*conversation.Message, error) {
messages := make([]*conversation.Message, 0, len(msgs))
for _, m := range msgs {
msg := &conversation.Message{
ID: m.ID,
Role: m.Role,
ContentType: string(m.ContentType)}
if m.MultiContent != nil {
var mcs []*conversation.Content
for _, c := range m.MultiContent {
if c.FileData != nil {
for _, fd := range c.FileData {
mcs = append(mcs, &conversation.Content{
Type: c.Type,
Uri: ptr.Of(fd.URI),
})
}
} else {
mcs = append(mcs, &conversation.Content{
Type: c.Type,
Text: ptr.Of(c.Text),
})
}
}
msg.MultiContent = mcs
} else {
msg.Text = ptr.Of(m.Content)
}
messages = append(messages, msg)
}
return messages, nil
}

View File

@ -0,0 +1,396 @@
/*
* Copyright 2025 coze-dev Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package conversation
import (
"testing"
"github.com/cloudwego/eino/schema"
apimessage "github.com/coze-dev/coze-studio/backend/api/model/crossdomain/message"
"github.com/coze-dev/coze-studio/backend/domain/conversation/message/entity"
"github.com/coze-dev/coze-studio/backend/domain/workflow/crossdomain/conversation"
"github.com/coze-dev/coze-studio/backend/pkg/lang/ptr"
"github.com/stretchr/testify/assert"
)
func Test_convertMessage(t *testing.T) {
type args struct {
lr *entity.ListResult
}
tests := []struct {
name string
args args
want *conversation.MessageListResponse
wantErr bool
}{
{
name: "pure text",
args: args{
lr: &entity.ListResult{
Messages: []*entity.Message{
{
ID: 1,
Role: schema.User,
ContentType: "text",
MultiContent: []*apimessage.InputMetaData{
{
Type: "text",
Text: "hello",
},
},
},
},
},
},
want: &conversation.MessageListResponse{
Messages: []*conversation.Message{
{
ID: 1,
Role: schema.User,
ContentType: "text",
MultiContent: []*conversation.Content{
{Type: "text", Text: ptr.Of("hello")},
},
},
},
},
},
{
name: "pure file",
args: args{
lr: &entity.ListResult{
Messages: []*entity.Message{
{
ID: 2,
Role: schema.User,
ContentType: "file",
MultiContent: []*apimessage.InputMetaData{
{
Type: "file",
FileData: []*apimessage.FileData{
{
URI: "f_uri_1",
},
},
},
{
Type: "text",
Text: "",
},
},
},
},
},
},
want: &conversation.MessageListResponse{
Messages: []*conversation.Message{
{
ID: 2,
Role: schema.User,
ContentType: "file",
MultiContent: []*conversation.Content{
{Type: "file", Uri: ptr.Of("f_uri_1")},
{Type: "text", Text: ptr.Of("")},
},
},
},
},
},
{
name: "text and file",
args: args{
lr: &entity.ListResult{
Messages: []*entity.Message{
{
ID: 3,
Role: schema.User,
ContentType: "text_file",
MultiContent: []*apimessage.InputMetaData{
{
Type: "text",
Text: "hello",
},
{
Type: "file",
FileData: []*apimessage.FileData{
{
URI: "f_uri_2",
},
},
},
},
},
},
},
},
want: &conversation.MessageListResponse{
Messages: []*conversation.Message{
{
ID: 3,
Role: schema.User,
ContentType: "text_file",
MultiContent: []*conversation.Content{
{Type: "text", Text: ptr.Of("hello")},
{Type: "file", Uri: ptr.Of("f_uri_2")},
},
},
},
},
},
{
name: "multiple files",
args: args{
lr: &entity.ListResult{
Messages: []*entity.Message{
{
ID: 4,
Role: schema.User,
ContentType: "file",
MultiContent: []*apimessage.InputMetaData{
{
Type: "file",
FileData: []*apimessage.FileData{
{
URI: "f_uri_3",
},
{
URI: "f_uri_4",
},
},
},
{
Type: "text",
Text: "",
},
},
},
},
},
},
want: &conversation.MessageListResponse{
Messages: []*conversation.Message{
{
ID: 4,
Role: schema.User,
ContentType: "file",
MultiContent: []*conversation.Content{
{Type: "file", Uri: ptr.Of("f_uri_3")},
{Type: "file", Uri: ptr.Of("f_uri_4")},
{Type: "text", Text: ptr.Of("")},
},
},
},
},
},
{
name: "empty text",
args: args{
lr: &entity.ListResult{
Messages: []*entity.Message{
{
ID: 5,
Role: schema.User,
ContentType: "text",
MultiContent: []*apimessage.InputMetaData{
{
Type: "text",
Text: "",
},
},
},
},
},
},
want: &conversation.MessageListResponse{
Messages: []*conversation.Message{
{
ID: 5,
Role: schema.User,
ContentType: "text",
MultiContent: []*conversation.Content{
{Type: "text", Text: ptr.Of("")},
},
},
},
},
},
{
name: "pure image",
args: args{
lr: &entity.ListResult{
Messages: []*entity.Message{
{
ID: 6,
Role: schema.User,
ContentType: "image",
MultiContent: []*apimessage.InputMetaData{
{
Type: "image",
FileData: []*apimessage.FileData{
{
URI: "image_uri_5",
},
},
},
{
Type: "text",
Text: "",
},
},
},
},
},
},
want: &conversation.MessageListResponse{
Messages: []*conversation.Message{
{
ID: 6,
Role: schema.User,
ContentType: "image",
MultiContent: []*conversation.Content{
{Type: "image", Uri: ptr.Of("image_uri_5")},
{Type: "text", Text: ptr.Of("")},
},
},
},
},
},
{
name: "multiple images",
args: args{
lr: &entity.ListResult{
Messages: []*entity.Message{
{
ID: 7,
Role: schema.User,
ContentType: "image",
MultiContent: []*apimessage.InputMetaData{
{
Type: "image",
FileData: []*apimessage.FileData{
{
URI: "file_id_6",
},
{
URI: "file_id_7",
},
},
},
{
Type: "text",
Text: "",
},
},
},
},
},
},
want: &conversation.MessageListResponse{
Messages: []*conversation.Message{
{
ID: 7,
Role: schema.User,
ContentType: "image",
MultiContent: []*conversation.Content{
{Type: "image", Uri: ptr.Of("file_id_6")},
{Type: "image", Uri: ptr.Of("file_id_7")},
{Type: "text", Text: ptr.Of("")},
},
},
},
},
},
{
name: "mixed content",
args: args{
lr: &entity.ListResult{
Messages: []*entity.Message{
{
ID: 8,
Role: schema.User,
ContentType: "mix",
MultiContent: []*apimessage.InputMetaData{
{
Type: "text",
Text: "hello",
},
{
Type: "image",
FileData: []*apimessage.FileData{
{
URI: "file_id_8",
},
},
},
{
Type: "file",
FileData: []*apimessage.FileData{
{
URI: "file_id_9",
},
},
},
},
},
},
},
},
want: &conversation.MessageListResponse{
Messages: []*conversation.Message{
{
ID: 8,
Role: schema.User,
ContentType: "mix",
MultiContent: []*conversation.Content{
{Type: "text", Text: ptr.Of("hello")},
{Type: "image", Uri: ptr.Of("file_id_8")},
{Type: "file", Uri: ptr.Of("file_id_9")},
},
},
},
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
msgs, err := convertMessage(tt.args.lr.Messages)
if (err != nil) != tt.wantErr {
t.Errorf("convertMessage() error = %v, wantErr %v", err, tt.wantErr)
return
}
for i, msg := range msgs {
assert.Equal(t, msg.MultiContent, tt.want.Messages[i].MultiContent)
}
})
}
}

View File

@ -50,7 +50,9 @@ type SingleAgentDraft struct {
JumpConfig *bot_common.JumpConfig `gorm:"column:jump_config;comment:Jump Configuration;serializer:json" json:"jump_config"` // Jump Configuration
BackgroundImageInfoList []*bot_common.BackgroundImageInfo `gorm:"column:background_image_info_list;comment:Background image;serializer:json" json:"background_image_info_list"` // Background image
DatabaseConfig []*bot_common.Database `gorm:"column:database_config;comment:Agent Database Base Configuration;serializer:json" json:"database_config"` // Agent Database Base Configuration
BotMode int32 `gorm:"column:bot_mode;not null;comment:mod,0:single mode 2:chatflow mode" json:"bot_mode"` // mod,0:single mode 2:chatflow mode
ShortcutCommand []string `gorm:"column:shortcut_command;comment:shortcut command;serializer:json" json:"shortcut_command"` // shortcut command
LayoutInfo *bot_common.LayoutInfo `gorm:"column:layout_info;comment:chatflow layout info;serializer:json" json:"layout_info"` // chatflow layout info
}
// TableName SingleAgentDraft's table name

View File

@ -52,7 +52,9 @@ type SingleAgentVersion struct {
Version string `gorm:"column:version;not null;comment:Agent Version" json:"version"` // Agent Version
BackgroundImageInfoList []*bot_common.BackgroundImageInfo `gorm:"column:background_image_info_list;comment:Background image;serializer:json" json:"background_image_info_list"` // Background image
DatabaseConfig []*bot_common.Database `gorm:"column:database_config;comment:Agent Database Base Configuration;serializer:json" json:"database_config"` // Agent Database Base Configuration
BotMode int32 `gorm:"column:bot_mode;not null;comment:mod,0:single mode 2:chatflow mode" json:"bot_mode"` // mod,0:single mode 2:chatflow mode
ShortcutCommand []string `gorm:"column:shortcut_command;comment:shortcut command;serializer:json" json:"shortcut_command"` // shortcut command
LayoutInfo *bot_common.LayoutInfo `gorm:"column:layout_info;comment:chatflow layout info;serializer:json" json:"layout_info"` // chatflow layout info
}
// TableName SingleAgentVersion's table name

View File

@ -1,3 +1,19 @@
/*
* 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 gorm.io/gen. DO NOT EDIT.
// Code generated by gorm.io/gen. DO NOT EDIT.
// Code generated by gorm.io/gen. DO NOT EDIT.
@ -48,7 +64,9 @@ func newSingleAgentDraft(db *gorm.DB, opts ...gen.DOOption) singleAgentDraft {
_singleAgentDraft.JumpConfig = field.NewField(tableName, "jump_config")
_singleAgentDraft.BackgroundImageInfoList = field.NewField(tableName, "background_image_info_list")
_singleAgentDraft.DatabaseConfig = field.NewField(tableName, "database_config")
_singleAgentDraft.BotMode = field.NewInt32(tableName, "bot_mode")
_singleAgentDraft.ShortcutCommand = field.NewField(tableName, "shortcut_command")
_singleAgentDraft.LayoutInfo = field.NewField(tableName, "layout_info")
_singleAgentDraft.fillFieldMap()
@ -81,7 +99,9 @@ type singleAgentDraft struct {
JumpConfig field.Field // Jump Configuration
BackgroundImageInfoList field.Field // Background image
DatabaseConfig field.Field // Agent Database Base Configuration
BotMode field.Int32 // mod,0:single mode 2:chatflow mode
ShortcutCommand field.Field // shortcut command
LayoutInfo field.Field // chatflow layout info
fieldMap map[string]field.Expr
}
@ -119,7 +139,9 @@ func (s *singleAgentDraft) updateTableName(table string) *singleAgentDraft {
s.JumpConfig = field.NewField(table, "jump_config")
s.BackgroundImageInfoList = field.NewField(table, "background_image_info_list")
s.DatabaseConfig = field.NewField(table, "database_config")
s.BotMode = field.NewInt32(table, "bot_mode")
s.ShortcutCommand = field.NewField(table, "shortcut_command")
s.LayoutInfo = field.NewField(table, "layout_info")
s.fillFieldMap()
@ -136,7 +158,7 @@ func (s *singleAgentDraft) GetFieldByName(fieldName string) (field.OrderExpr, bo
}
func (s *singleAgentDraft) fillFieldMap() {
s.fieldMap = make(map[string]field.Expr, 22)
s.fieldMap = make(map[string]field.Expr, 24)
s.fieldMap["id"] = s.ID
s.fieldMap["agent_id"] = s.AgentID
s.fieldMap["creator_id"] = s.CreatorID
@ -158,7 +180,9 @@ func (s *singleAgentDraft) fillFieldMap() {
s.fieldMap["jump_config"] = s.JumpConfig
s.fieldMap["background_image_info_list"] = s.BackgroundImageInfoList
s.fieldMap["database_config"] = s.DatabaseConfig
s.fieldMap["bot_mode"] = s.BotMode
s.fieldMap["shortcut_command"] = s.ShortcutCommand
s.fieldMap["layout_info"] = s.LayoutInfo
}
func (s singleAgentDraft) clone(db *gorm.DB) singleAgentDraft {

View File

@ -1,3 +1,19 @@
/*
* 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 gorm.io/gen. DO NOT EDIT.
// Code generated by gorm.io/gen. DO NOT EDIT.
// Code generated by gorm.io/gen. DO NOT EDIT.
@ -50,7 +66,9 @@ func newSingleAgentVersion(db *gorm.DB, opts ...gen.DOOption) singleAgentVersion
_singleAgentVersion.Version = field.NewString(tableName, "version")
_singleAgentVersion.BackgroundImageInfoList = field.NewField(tableName, "background_image_info_list")
_singleAgentVersion.DatabaseConfig = field.NewField(tableName, "database_config")
_singleAgentVersion.BotMode = field.NewInt32(tableName, "bot_mode")
_singleAgentVersion.ShortcutCommand = field.NewField(tableName, "shortcut_command")
_singleAgentVersion.LayoutInfo = field.NewField(tableName, "layout_info")
_singleAgentVersion.fillFieldMap()
@ -85,7 +103,9 @@ type singleAgentVersion struct {
Version field.String // Agent Version
BackgroundImageInfoList field.Field // Background image
DatabaseConfig field.Field // Agent Database Base Configuration
BotMode field.Int32 // mod,0:single mode 2:chatflow mode
ShortcutCommand field.Field // shortcut command
LayoutInfo field.Field // chatflow layout info
fieldMap map[string]field.Expr
}
@ -125,7 +145,9 @@ func (s *singleAgentVersion) updateTableName(table string) *singleAgentVersion {
s.Version = field.NewString(table, "version")
s.BackgroundImageInfoList = field.NewField(table, "background_image_info_list")
s.DatabaseConfig = field.NewField(table, "database_config")
s.BotMode = field.NewInt32(table, "bot_mode")
s.ShortcutCommand = field.NewField(table, "shortcut_command")
s.LayoutInfo = field.NewField(table, "layout_info")
s.fillFieldMap()
@ -142,7 +164,7 @@ func (s *singleAgentVersion) GetFieldByName(fieldName string) (field.OrderExpr,
}
func (s *singleAgentVersion) fillFieldMap() {
s.fieldMap = make(map[string]field.Expr, 24)
s.fieldMap = make(map[string]field.Expr, 26)
s.fieldMap["id"] = s.ID
s.fieldMap["agent_id"] = s.AgentID
s.fieldMap["creator_id"] = s.CreatorID
@ -166,7 +188,9 @@ func (s *singleAgentVersion) fillFieldMap() {
s.fieldMap["version"] = s.Version
s.fieldMap["background_image_info_list"] = s.BackgroundImageInfoList
s.fieldMap["database_config"] = s.DatabaseConfig
s.fieldMap["bot_mode"] = s.BotMode
s.fieldMap["shortcut_command"] = s.ShortcutCommand
s.fieldMap["layout_info"] = s.LayoutInfo
}
func (s singleAgentVersion) clone(db *gorm.DB) singleAgentVersion {

View File

@ -22,7 +22,9 @@ import (
"gorm.io/gorm"
"github.com/coze-dev/coze-studio/backend/api/model/app/bot_common"
"github.com/coze-dev/coze-studio/backend/api/model/crossdomain/singleagent"
"github.com/coze-dev/coze-studio/backend/domain/agent/singleagent/entity"
"github.com/coze-dev/coze-studio/backend/domain/agent/singleagent/internal/dal/model"
"github.com/coze-dev/coze-studio/backend/domain/agent/singleagent/internal/dal/query"
@ -144,6 +146,8 @@ func (sa *SingleAgentDraftDAO) singleAgentDraftPo2Do(po *model.SingleAgentDraft)
BackgroundImageInfoList: po.BackgroundImageInfoList,
Database: po.DatabaseConfig,
ShortcutCommand: po.ShortcutCommand,
BotMode: bot_common.BotMode(po.BotMode),
LayoutInfo: po.LayoutInfo,
},
}
}
@ -171,5 +175,7 @@ func (sa *SingleAgentDraftDAO) singleAgentDraftDo2Po(do *entity.SingleAgent) *mo
BackgroundImageInfoList: do.BackgroundImageInfoList,
DatabaseConfig: do.Database,
ShortcutCommand: do.ShortcutCommand,
BotMode: int32(do.BotMode),
LayoutInfo: do.LayoutInfo,
}
}

View File

@ -25,10 +25,13 @@ import (
connectorModel "github.com/coze-dev/coze-studio/backend/api/model/crossdomain/connector"
databaseModel "github.com/coze-dev/coze-studio/backend/api/model/crossdomain/database"
knowledgeModel "github.com/coze-dev/coze-studio/backend/api/model/crossdomain/knowledge"
crossconnector "github.com/coze-dev/coze-studio/backend/crossdomain/contract/connector"
crossdatabase "github.com/coze-dev/coze-studio/backend/crossdomain/contract/database"
crossknowledge "github.com/coze-dev/coze-studio/backend/crossdomain/contract/knowledge"
crossplugin "github.com/coze-dev/coze-studio/backend/crossdomain/contract/plugin"
crossworkflow "github.com/coze-dev/coze-studio/backend/crossdomain/contract/workflow"
"github.com/coze-dev/coze-studio/backend/domain/app/entity"
"github.com/coze-dev/coze-studio/backend/domain/app/repository"
"github.com/coze-dev/coze-studio/backend/infra/contract/idgen"
@ -67,6 +70,11 @@ func (a *appServiceImpl) CreateDraftAPP(ctx context.Context, req *CreateDraftAPP
return 0, errorx.Wrapf(err, "CreateDraftAPP failed, spaceID=%d", req.SpaceID)
}
err = crossworkflow.DefaultSVC().InitApplicationDefaultConversationTemplate(ctx, req.SpaceID, appID, req.OwnerID)
if err != nil {
return 0, err
}
return appID, nil
}

View File

@ -158,3 +158,13 @@ type ModelAnswerEvent struct {
Message *schema.Message
Err error
}
type ListRunRecordMeta struct {
ConversationID int64 `json:"conversation_id"`
AgentID int64 `json:"agent_id"`
SectionID int64 `json:"section_id"`
Limit int32 `json:"limit"`
OrderBy string `json:"order_by"` //desc asc
BeforeID int64 `json:"before_id"`
AfterID int64 `json:"after_id"`
}

View File

@ -0,0 +1,140 @@
/*
* 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 internal
import (
"context"
"encoding/json"
"github.com/cloudwego/eino/schema"
"github.com/coze-dev/coze-studio/backend/api/model/crossdomain/message"
crossagent "github.com/coze-dev/coze-studio/backend/crossdomain/contract/agent"
"github.com/coze-dev/coze-studio/backend/domain/conversation/message/entity"
"github.com/coze-dev/coze-studio/backend/infra/contract/imagex"
)
func HistoryPairs(historyMsg []*message.Message) []*message.Message {
fcMsgPairs := make(map[int64][]*message.Message)
for _, one := range historyMsg {
if one.MessageType != message.MessageTypeFunctionCall && one.MessageType != message.MessageTypeToolResponse {
continue
}
if _, ok := fcMsgPairs[one.RunID]; !ok {
fcMsgPairs[one.RunID] = []*message.Message{one}
} else {
fcMsgPairs[one.RunID] = append(fcMsgPairs[one.RunID], one)
}
}
var historyAfterPairs []*message.Message
for _, value := range historyMsg {
if value.MessageType == message.MessageTypeFunctionCall {
if len(fcMsgPairs[value.RunID])%2 == 0 {
historyAfterPairs = append(historyAfterPairs, value)
}
} else {
historyAfterPairs = append(historyAfterPairs, value)
}
}
return historyAfterPairs
}
func TransMessageToSchemaMessage(ctx context.Context, msgs []*message.Message, imagexClient imagex.ImageX) []*schema.Message {
schemaMessage := make([]*schema.Message, 0, len(msgs))
for _, msgOne := range msgs {
if msgOne.ModelContent == "" {
continue
}
if msgOne.MessageType == message.MessageTypeVerbose || msgOne.MessageType == message.MessageTypeFlowUp {
continue
}
var sm *schema.Message
err := json.Unmarshal([]byte(msgOne.ModelContent), &sm)
if err != nil {
continue
}
if len(sm.ReasoningContent) > 0 {
sm.ReasoningContent = ""
}
schemaMessage = append(schemaMessage, parseMessageURI(ctx, sm, imagexClient))
}
return schemaMessage
}
func parseMessageURI(ctx context.Context, mcMsg *schema.Message, imagexClient imagex.ImageX) *schema.Message {
if mcMsg.MultiContent == nil {
return mcMsg
}
for k, one := range mcMsg.MultiContent {
switch one.Type {
case schema.ChatMessagePartTypeImageURL:
if one.ImageURL.URI != "" {
url, err := imagexClient.GetResourceURL(ctx, one.ImageURL.URI)
if err == nil {
mcMsg.MultiContent[k].ImageURL.URL = url.URL
}
}
case schema.ChatMessagePartTypeFileURL:
if one.FileURL.URI != "" {
url, err := imagexClient.GetResourceURL(ctx, one.FileURL.URI)
if err == nil {
mcMsg.MultiContent[k].FileURL.URL = url.URL
}
}
case schema.ChatMessagePartTypeAudioURL:
if one.AudioURL.URI != "" {
url, err := imagexClient.GetResourceURL(ctx, one.AudioURL.URI)
if err == nil {
mcMsg.MultiContent[k].AudioURL.URL = url.URL
}
}
case schema.ChatMessagePartTypeVideoURL:
if one.VideoURL.URI != "" {
url, err := imagexClient.GetResourceURL(ctx, one.VideoURL.URI)
if err == nil {
mcMsg.MultiContent[k].VideoURL.URL = url.URL
}
}
}
}
return mcMsg
}
func ParseResumeInfo(_ context.Context, historyMsg []*message.Message) *crossagent.ResumeInfo {
var resumeInfo *crossagent.ResumeInfo
for i := len(historyMsg) - 1; i >= 0; i-- {
if historyMsg[i].MessageType == message.MessageTypeQuestion {
break
}
if historyMsg[i].MessageType == message.MessageTypeVerbose {
if historyMsg[i].Ext[string(entity.ExtKeyResumeInfo)] != "" {
err := json.Unmarshal([]byte(historyMsg[i].Ext[string(entity.ExtKeyResumeInfo)]), &resumeInfo)
if err != nil {
return nil
}
}
}
}
return resumeInfo
}

View File

@ -19,6 +19,7 @@ package dal
import (
"context"
"encoding/json"
"strings"
"time"
"gorm.io/gorm"
@ -27,6 +28,7 @@ import (
"github.com/coze-dev/coze-studio/backend/domain/conversation/agentrun/internal/dal/model"
"github.com/coze-dev/coze-studio/backend/domain/conversation/agentrun/internal/dal/query"
"github.com/coze-dev/coze-studio/backend/infra/contract/idgen"
"github.com/coze-dev/coze-studio/backend/pkg/lang/slices"
"github.com/coze-dev/coze-studio/backend/pkg/logs"
)
@ -106,20 +108,40 @@ func (dao *RunRecordDAO) Delete(ctx context.Context, id []int64) error {
return err
}
func (dao *RunRecordDAO) List(ctx context.Context, conversationID int64, sectionID int64, limit int32) ([]*model.RunRecord, error) {
logs.CtxInfof(ctx, "list run record req:%v, sectionID:%v, limit:%v", conversationID, sectionID, limit)
func (dao *RunRecordDAO) List(ctx context.Context, meta *entity.ListRunRecordMeta) ([]*entity.RunRecordMeta, error) {
logs.CtxInfof(ctx, "list run record req:%v, sectionID:%v, limit:%v", meta.ConversationID, meta.SectionID, meta.Limit)
m := dao.query.RunRecord
do := m.WithContext(ctx).Where(m.ConversationID.Eq(conversationID)).Debug().Where(m.Status.NotIn(string(entity.RunStatusDeleted)))
if sectionID > 0 {
do = do.Where(m.SectionID.Eq(sectionID))
do := m.WithContext(ctx).Where(m.ConversationID.Eq(meta.ConversationID)).Debug().Where(m.Status.NotIn(string(entity.RunStatusDeleted)))
if meta.BeforeID > 0 {
runRecord, err := m.Where(m.ID.Eq(meta.BeforeID)).First()
if err != nil {
return nil, err
}
do = do.Where(m.CreatedAt.Lt(runRecord.CreatedAt))
}
if limit > 0 {
do = do.Limit(int(limit))
if meta.AfterID > 0 {
runRecord, err := m.Where(m.ID.Eq(meta.AfterID)).First()
if err != nil {
return nil, err
}
do = do.Where(m.CreatedAt.Gt(runRecord.CreatedAt))
}
if meta.SectionID > 0 {
do = do.Where(m.SectionID.Eq(meta.SectionID))
}
if meta.Limit > 0 {
do = do.Limit(int(meta.Limit))
}
if strings.ToLower(meta.OrderBy) == "asc" {
do = do.Order(m.CreatedAt.Asc())
} else {
do = do.Order(m.CreatedAt.Desc())
}
runRecords, err := do.Order(m.CreatedAt.Desc()).Find()
return runRecords, err
runRecords, err := do.Find()
return slices.Transform(runRecords, func(item *model.RunRecord) *entity.RunRecordMeta {
return dao.buildPo2Do(item)
}), err
}
func (dao *RunRecordDAO) buildCreatePO(ctx context.Context, runMeta *entity.AgentRunMeta) (*model.RunRecord, error) {

View File

@ -23,7 +23,6 @@ import (
"github.com/coze-dev/coze-studio/backend/domain/conversation/agentrun/entity"
"github.com/coze-dev/coze-studio/backend/domain/conversation/agentrun/internal/dal"
"github.com/coze-dev/coze-studio/backend/domain/conversation/agentrun/internal/dal/model"
"github.com/coze-dev/coze-studio/backend/infra/contract/idgen"
)
@ -37,5 +36,5 @@ type RunRecordRepo interface {
GetByID(ctx context.Context, id int64) (*entity.RunRecord, error)
Delete(ctx context.Context, id []int64) error
UpdateByID(ctx context.Context, id int64, update *entity.UpdateMeta) error
List(ctx context.Context, conversationID int64, sectionID int64, limit int32) ([]*model.RunRecord, error)
List(ctx context.Context, meta *entity.ListRunRecordMeta) ([]*entity.RunRecordMeta, error)
}

View File

@ -33,17 +33,20 @@ import (
"github.com/cloudwego/eino/schema"
"github.com/mohae/deepcopy"
"github.com/coze-dev/coze-studio/backend/api/model/app/bot_common"
messageModel "github.com/coze-dev/coze-studio/backend/api/model/conversation/message"
"github.com/coze-dev/coze-studio/backend/api/model/crossdomain/agentrun"
"github.com/coze-dev/coze-studio/backend/api/model/crossdomain/message"
"github.com/coze-dev/coze-studio/backend/api/model/crossdomain/singleagent"
crossagent "github.com/coze-dev/coze-studio/backend/crossdomain/contract/agent"
crossmessage "github.com/coze-dev/coze-studio/backend/crossdomain/contract/message"
crossworkflow "github.com/coze-dev/coze-studio/backend/crossdomain/contract/workflow"
"github.com/coze-dev/coze-studio/backend/domain/conversation/agentrun/entity"
"github.com/coze-dev/coze-studio/backend/domain/conversation/agentrun/internal"
"github.com/coze-dev/coze-studio/backend/domain/conversation/agentrun/internal/dal/model"
"github.com/coze-dev/coze-studio/backend/domain/conversation/agentrun/repository"
msgEntity "github.com/coze-dev/coze-studio/backend/domain/conversation/message/entity"
"github.com/coze-dev/coze-studio/backend/infra/contract/imagex"
"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"
@ -72,6 +75,7 @@ type runtimeDependence struct {
type Components struct {
RunRecordRepo repository.RunRecordRepo
ImagexSVC imagex.ImageX
}
func NewService(c *Components) Run {
@ -145,7 +149,11 @@ func (c *runImpl) run(ctx context.Context, sw *schema.StreamWriter[*entity.Agent
rtDependence.questionMsgID = input.ID
err = c.handlerStreamExecute(ctx, sw, history, input, rtDependence)
if rtDependence.agentInfo.BotMode == bot_common.BotMode_WorkflowMode {
err = c.handlerWfAsAgentStreamExecute(ctx, sw, rtDependence)
} else {
err = c.handlerAgentStreamExecute(ctx, sw, history, input, rtDependence)
}
return
}
@ -161,18 +169,59 @@ func (c *runImpl) handlerAgent(ctx context.Context, rtDependence *runtimeDepende
return agentInfo, nil
}
func (c *runImpl) handlerStreamExecute(ctx context.Context, sw *schema.StreamWriter[*entity.AgentRunResponse], historyMsg []*msgEntity.Message, input *msgEntity.Message, rtDependence *runtimeDependence) (err error) {
func (c *runImpl) handlerWfAsAgentStreamExecute(ctx context.Context, sw *schema.StreamWriter[*entity.AgentRunResponse], rtDependence *runtimeDependence) (err error) {
wfID, _ := strconv.ParseInt(rtDependence.agentInfo.LayoutInfo.WorkflowId, 10, 64)
wfStreamer, err := crossworkflow.DefaultSVC().StreamExecute(ctx, crossworkflow.ExecuteConfig{
ID: wfID,
ConnectorID: rtDependence.runMeta.ConnectorID,
ConnectorUID: rtDependence.runMeta.UserID,
AgentID: ptr.Of(rtDependence.runMeta.AgentID),
Mode: crossworkflow.ExecuteModeRelease,
BizType: crossworkflow.BizTypeAgent,
SyncPattern: crossworkflow.SyncPatternStream,
}, map[string]any{
"input": concatWfInput(rtDependence),
})
var wg sync.WaitGroup
wg.Add(1)
safego.Go(ctx, func() {
defer wg.Done()
c.pullWfStream(ctx, wfStreamer, rtDependence, sw)
})
wg.Wait()
return err
}
func concatWfInput(rtDependence *runtimeDependence) string {
var input string
for _, content := range rtDependence.runMeta.Content {
if content.Type == message.InputTypeText {
input = content.Text + "," + input
} else {
for _, file := range content.FileData {
input += file.Url + ","
}
}
}
return input
}
func (c *runImpl) handlerAgentStreamExecute(ctx context.Context, sw *schema.StreamWriter[*entity.AgentRunResponse], historyMsg []*msgEntity.Message, input *msgEntity.Message, rtDependence *runtimeDependence) (err error) {
mainChan := make(chan *entity.AgentRespEvent, 100)
ar := &singleagent.AgentRuntime{
ar := &crossagent.AgentRuntime{
AgentVersion: rtDependence.runMeta.Version,
SpaceID: rtDependence.runMeta.SpaceID,
AgentID: rtDependence.runMeta.AgentID,
IsDraft: rtDependence.runMeta.IsDraft,
ConnectorID: rtDependence.runMeta.ConnectorID,
PreRetrieveTools: rtDependence.runMeta.PreRetrieveTools,
Input: internal.TransMessageToSchemaMessage(ctx, []*msgEntity.Message{input}, c.ImagexSVC)[0],
HistoryMsg: internal.TransMessageToSchemaMessage(ctx, internal.HistoryPairs(historyMsg), c.ImagexSVC),
ResumeInfo: internal.ParseResumeInfo(ctx, historyMsg),
}
streamer, err := crossagent.DefaultSVC().StreamExecute(ctx, historyMsg, input, ar)
streamer, err := crossagent.DefaultSVC().StreamExecute(ctx, ar)
if err != nil {
return errors.New(errorx.ErrorWithoutStack(err))
}
@ -369,7 +418,11 @@ func (c *runImpl) handlerHistory(ctx context.Context, rtDependence *runtimeDepen
conversationTurns = ptr.From(rtDependence.agentInfo.ModelInfo.ShortMemoryPolicy.HistoryRound)
}
runRecordList, err := c.RunRecordRepo.List(ctx, rtDependence.runMeta.ConversationID, rtDependence.runMeta.SectionID, conversationTurns)
runRecordList, err := c.RunRecordRepo.List(ctx, &entity.ListRunRecordMeta{
ConversationID: rtDependence.runMeta.ConversationID,
SectionID: rtDependence.runMeta.SectionID,
Limit: conversationTurns,
})
if err != nil {
return nil, err
}
@ -388,7 +441,7 @@ func (c *runImpl) handlerHistory(ctx context.Context, rtDependence *runtimeDepen
return history, nil
}
func (c *runImpl) getRunID(rr []*model.RunRecord) []int64 {
func (c *runImpl) getRunID(rr []*entity.RunRecordMeta) []int64 {
ids := make([]int64, 0, len(rr))
for _, c := range rr {
ids = append(ids, c.ID)
@ -431,6 +484,189 @@ func (c *runImpl) handlerInput(ctx context.Context, sw *schema.StreamWriter[*ent
}
return cm, nil
}
func (c *runImpl) pullWfStream(ctx context.Context, events *schema.StreamReader[*crossworkflow.WorkflowMessage], rtDependence *runtimeDependence, sw *schema.StreamWriter[*entity.AgentRunResponse]) {
fullAnswerContent := bytes.NewBuffer([]byte{})
var usage *msgEntity.UsageExt
preAnswerMsg, cErr := c.PreCreateAnswer(ctx, rtDependence)
if cErr != nil {
return
}
var preMsgIsFinish = false
for {
st, re := events.Recv()
logs.CtxInfof(ctx, "pullWfStream Recv:%v,err:%v", conv.DebugJsonToStr(st), re)
if re != nil {
if errors.Is(re, io.EOF) {
return
}
logs.CtxErrorf(ctx, "pullWfStream Recv error: %v", re)
c.handlerErr(ctx, re, sw)
return
}
if st == nil {
continue
}
if st.StateMessage != nil && st.StateMessage.InterruptEvent != nil { // interrupt
c.handlerWfInterruptMsg(ctx, sw, st.StateMessage.InterruptEvent, rtDependence)
continue
}
if st.DataMessage == nil {
continue
}
switch st.DataMessage.Type {
case crossworkflow.Answer:
// input node & question node skip
if st.DataMessage != nil && (st.DataMessage.NodeType == crossworkflow.NodeTypeInputReceiver || st.DataMessage.NodeType == crossworkflow.NodeTypeQuestion) {
break
}
if preMsgIsFinish {
preAnswerMsg, cErr = c.PreCreateAnswer(ctx, rtDependence)
if cErr != nil {
return
}
preMsgIsFinish = false
}
if st.DataMessage.Usage != nil {
usage = &msgEntity.UsageExt{
InputTokens: st.DataMessage.Usage.InputTokens,
OutputTokens: st.DataMessage.Usage.OutputTokens,
TotalCount: st.DataMessage.Usage.InputTokens + st.DataMessage.Usage.OutputTokens,
}
}
if st.DataMessage.Last {
preMsgIsFinish = true
sendAnswerMsg := c.buildSendMsg(ctx, preAnswerMsg, false, rtDependence)
sendAnswerMsg.Content = fullAnswerContent.String()
fullAnswerContent.Reset()
hfErr := c.handlerAnswer(ctx, sendAnswerMsg, sw, usage, rtDependence, preAnswerMsg)
if hfErr != nil {
return
}
}
sendAnswerMsg := c.buildSendMsg(ctx, preAnswerMsg, false, rtDependence)
sendAnswerMsg.Content = st.DataMessage.Content
fullAnswerContent.WriteString(st.DataMessage.Content)
c.runEvent.SendMsgEvent(entity.RunEventMessageDelta, sendAnswerMsg, sw)
}
}
}
func (c *runImpl) handlerWfInterruptMsg(ctx context.Context, sw *schema.StreamWriter[*entity.AgentRunResponse], interruptEventData *crossworkflow.InterruptEvent, rtDependence *runtimeDependence) {
interruptData, cType, err := c.handlerWfInterruptEvent(ctx, interruptEventData)
if err != nil {
return
}
preMsg, err := c.PreCreateAnswer(ctx, rtDependence)
if err != nil {
return
}
deltaAnswer := &entity.ChunkMessageItem{
ID: preMsg.ID,
ConversationID: preMsg.ConversationID,
SectionID: preMsg.SectionID,
RunID: preMsg.RunID,
AgentID: preMsg.AgentID,
Role: entity.RoleType(preMsg.Role),
Content: interruptData,
MessageType: preMsg.MessageType,
ContentType: cType,
ReplyID: preMsg.RunID,
Ext: preMsg.Ext,
IsFinish: false,
}
c.runEvent.SendMsgEvent(entity.RunEventMessageDelta, deltaAnswer, sw)
finalAnswer := deepcopy.Copy(deltaAnswer).(*entity.ChunkMessageItem)
err = c.handlerAnswer(ctx, finalAnswer, sw, nil, rtDependence, preMsg)
if err != nil {
return
}
// err = c.handlerInterruptVerbose(ctx, chunk, sw, rtDependence)
// if err != nil {
// return
// }
}
func (c *runImpl) handlerWfInterruptEvent(_ context.Context, interruptEventData *crossworkflow.InterruptEvent) (string, message.ContentType, error) {
type msg struct {
Type string `json:"type,omitempty"`
ContentType string `json:"content_type"`
Content any `json:"content"` // either optionContent or string
ID string `json:"id,omitempty"`
}
defaultContentType := message.ContentTypeText
switch singleagent.InterruptEventType(interruptEventData.EventType) {
case singleagent.InterruptEventType_OauthPlugin:
case singleagent.InterruptEventType_Question:
var iData map[string][]*msg
err := json.Unmarshal([]byte(interruptEventData.InterruptData), &iData)
if err != nil {
return "", defaultContentType, err
}
if len(iData["messages"]) == 0 {
return "", defaultContentType, errorx.New(errno.ErrInterruptDataEmpty)
}
interruptMsg := iData["messages"][0]
if interruptMsg.ContentType == "text" {
return interruptMsg.Content.(string), defaultContentType, nil
} else if interruptMsg.ContentType == "option" || interruptMsg.ContentType == "form_schema" {
iMarshalData, err := json.Marshal(interruptMsg)
if err != nil {
return "", defaultContentType, err
}
return string(iMarshalData), message.ContentTypeCard, nil
}
case singleagent.InterruptEventType_InputNode:
data := interruptEventData.InterruptData
return data, message.ContentTypeCard, nil
case singleagent.InterruptEventType_WorkflowLLM:
data := interruptEventData.ToolInterruptEvent.InterruptData
if singleagent.InterruptEventType(interruptEventData.EventType) == singleagent.InterruptEventType_InputNode {
return data, message.ContentTypeCard, nil
}
if singleagent.InterruptEventType(interruptEventData.EventType) == singleagent.InterruptEventType_Question {
var iData map[string][]*msg
err := json.Unmarshal([]byte(data), &iData)
if err != nil {
return "", defaultContentType, err
}
if len(iData["messages"]) == 0 {
return "", defaultContentType, errorx.New(errno.ErrInterruptDataEmpty)
}
interruptMsg := iData["messages"][0]
if interruptMsg.ContentType == "text" {
return interruptMsg.Content.(string), defaultContentType, nil
} else if interruptMsg.ContentType == "option" || interruptMsg.ContentType == "form_schema" {
iMarshalData, err := json.Marshal(interruptMsg)
if err != nil {
return "", defaultContentType, err
}
return string(iMarshalData), message.ContentTypeCard, nil
}
}
return "", defaultContentType, errorx.New(errno.ErrUnknowInterruptType)
}
return "", defaultContentType, errorx.New(errno.ErrUnknowInterruptType)
}
func (c *runImpl) pull(_ context.Context, mainChan chan *entity.AgentRespEvent, events *schema.StreamReader[*crossagent.AgentEvent]) {
defer func() {
@ -766,7 +1002,7 @@ func (c *runImpl) saveReasoningContent(ctx context.Context, firstAnswerMsg *msgE
}
}
func (c *runImpl) handlerInterrupt(ctx context.Context, chunk *entity.AgentRespEvent, sw *schema.StreamWriter[*entity.AgentRunResponse], rtDependence *runtimeDependence, firstAnswerMsg *msgEntity.Message, reasoningCOntent string) error {
func (c *runImpl) handlerInterrupt(ctx context.Context, chunk *entity.AgentRespEvent, sw *schema.StreamWriter[*entity.AgentRunResponse], rtDependence *runtimeDependence, firstAnswerMsg *msgEntity.Message, reasoningContent string) error {
interruptData, cType, err := c.parseInterruptData(ctx, chunk.Interrupt)
if err != nil {
return err
@ -792,8 +1028,8 @@ func (c *runImpl) handlerInterrupt(ctx context.Context, chunk *entity.AgentRespE
c.runEvent.SendMsgEvent(entity.RunEventMessageDelta, deltaAnswer, sw)
finalAnswer := deepcopy.Copy(deltaAnswer).(*entity.ChunkMessageItem)
if len(reasoningCOntent) > 0 && firstAnswerMsg == nil {
finalAnswer.ReasoningContent = ptr.Of(reasoningCOntent)
if len(reasoningContent) > 0 && firstAnswerMsg == nil {
finalAnswer.ReasoningContent = ptr.Of(reasoningContent)
}
err = c.handlerAnswer(ctx, finalAnswer, sw, nil, rtDependence, preMsg)
if err != nil {

View File

@ -84,14 +84,21 @@ func (dao *MessageDAO) List(ctx context.Context, conversationID int64, limit int
}
if cursor > 0 {
if direction == entity.ScrollPageDirectionPrev {
do = do.Where(m.CreatedAt.Lt(cursor))
} else {
do = do.Where(m.CreatedAt.Gt(cursor))
msg, err := m.Where(m.ID.Eq(cursor)).First()
if err != nil {
return nil, false, err
}
if direction == entity.ScrollPageDirectionPrev {
do = do.Where(m.CreatedAt.Lt(msg.CreatedAt))
do = do.Order(m.CreatedAt.Desc())
} else {
do = do.Where(m.CreatedAt.Gt(msg.CreatedAt))
do = do.Order(m.CreatedAt.Asc())
}
} else {
do = do.Order(m.CreatedAt.Desc())
}
do = do.Order(m.CreatedAt.Desc())
messageList, err := do.Find()
var hasMore bool

View File

@ -18,6 +18,7 @@ package message
import (
"context"
"sort"
"github.com/coze-dev/coze-studio/backend/api/model/crossdomain/message"
"github.com/coze-dev/coze-studio/backend/domain/conversation/message/entity"
@ -62,8 +63,11 @@ func (m *messageImpl) List(ctx context.Context, req *entity.ListMeta) (*entity.L
resp.HasMore = hasMore
if len(messageList) > 0 {
resp.PrevCursor = messageList[len(messageList)-1].CreatedAt
resp.NextCursor = messageList[0].CreatedAt
sort.Slice(messageList, func(i, j int) bool {
return messageList[i].CreatedAt > messageList[j].CreatedAt
})
resp.PrevCursor = messageList[len(messageList)-1].ID
resp.NextCursor = messageList[0].ID
var runIDs []int64
for _, m := range messageList {

View File

@ -32,7 +32,9 @@ type Executable interface {
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) (
*schema.StreamReader[*entity.Message], error)
@ -53,12 +55,31 @@ type AsTool interface {
allInterruptEvents map[string]*entity.ToolInterruptEvent) compose.Option
}
type ConversationService interface {
CreateDraftConversationTemplate(ctx context.Context, template *vo.CreateConversationTemplateMeta) (int64, error)
UpdateDraftConversationTemplateName(ctx context.Context, appID int64, userID int64, templateID int64, name string) error
DeleteDraftConversationTemplate(ctx context.Context, templateID int64, wfID2ConversationName map[int64]string) (int64, error)
CheckWorkflowsToReplace(ctx context.Context, appID int64, templateID int64) ([]*entity.Workflow, error)
DeleteDynamicConversation(ctx context.Context, env vo.Env, templateID int64) (int64, error)
ListConversationTemplate(ctx context.Context, env vo.Env, policy *vo.ListConversationTemplatePolicy) ([]*entity.ConversationTemplate, error)
MGetStaticConversation(ctx context.Context, env vo.Env, userID, connectorID int64, templateIDs []int64) ([]*entity.StaticConversation, error)
ListDynamicConversation(ctx context.Context, env vo.Env, policy *vo.ListConversationPolicy) ([]*entity.DynamicConversation, error)
ReleaseConversationTemplate(ctx context.Context, appID int64, version string) error
InitApplicationDefaultConversationTemplate(ctx context.Context, spaceID int64, appID int64, userID int64) error
GetOrCreateConversation(ctx context.Context, env vo.Env, appID, connectorID, userID int64, conversationName string) (int64, int64, error)
UpdateConversation(ctx context.Context, env vo.Env, appID, connectorID, userID int64, conversationName string) (int64, error)
}
type InterruptEventStore interface {
SaveInterruptEvents(ctx context.Context, wfExeID int64, events []*entity.InterruptEvent) error
GetFirstInterruptEvent(ctx context.Context, wfExeID int64) (*entity.InterruptEvent, bool, error)
UpdateFirstInterruptEvent(ctx context.Context, wfExeID int64, event *entity.InterruptEvent) error
PopFirstInterruptEvent(ctx context.Context, wfExeID int64) (*entity.InterruptEvent, bool, error)
ListInterruptEvents(ctx context.Context, wfExeID int64) ([]*entity.InterruptEvent, error)
BindConvRelatedInfo(ctx context.Context, convID int64, info entity.ConvRelatedInfo) error
GetConvRelatedInfo(ctx context.Context, convID int64) (*entity.ConvRelatedInfo, bool, func() error, error)
}
type CancelSignalStore interface {
@ -90,3 +111,24 @@ type ToolFromWorkflow interface {
TerminatePlan() vo.TerminatePlan
GetWorkflow() *entity.Workflow
}
type ConversationIDGenerator func(ctx context.Context, appID int64, userID, connectorID int64) (int64, int64, error)
type ConversationRepository interface {
CreateDraftConversationTemplate(ctx context.Context, template *vo.CreateConversationTemplateMeta) (int64, error)
UpdateDraftConversationTemplateName(ctx context.Context, templateID int64, name string) error
DeleteDraftConversationTemplate(ctx context.Context, templateID int64) (int64, error)
GetConversationTemplate(ctx context.Context, env vo.Env, policy vo.GetConversationTemplatePolicy) (*entity.ConversationTemplate, bool, error)
DeleteDynamicConversation(ctx context.Context, env vo.Env, id int64) (int64, error)
ListConversationTemplate(ctx context.Context, env vo.Env, policy *vo.ListConversationTemplatePolicy) ([]*entity.ConversationTemplate, error)
MGetStaticConversation(ctx context.Context, env vo.Env, userID, connectorID int64, templateIDs []int64) ([]*entity.StaticConversation, error)
GetOrCreateStaticConversation(ctx context.Context, env vo.Env, idGen ConversationIDGenerator, meta *vo.CreateStaticConversation) (int64, int64, bool, error)
GetOrCreateDynamicConversation(ctx context.Context, env vo.Env, idGen ConversationIDGenerator, meta *vo.CreateDynamicConversation) (int64, int64, bool, error)
GetDynamicConversationByName(ctx context.Context, env vo.Env, appID, connectorID, userID int64, name string) (*entity.DynamicConversation, bool, error)
GetStaticConversationByTemplateID(ctx context.Context, env vo.Env, userID, connectorID, templateID int64) (*entity.StaticConversation, bool, error)
ListDynamicConversation(ctx context.Context, env vo.Env, policy *vo.ListConversationPolicy) ([]*entity.DynamicConversation, error)
BatchCreateOnlineConversationTemplate(ctx context.Context, templates []*entity.ConversationTemplate, version string) error
UpdateDynamicConversationNameByID(ctx context.Context, env vo.Env, templateID int64, name string) error
UpdateStaticConversation(ctx context.Context, env vo.Env, templateID int64, connectorID int64, userID int64, newConversationID int64) error
UpdateDynamicConversation(ctx context.Context, env vo.Env, conversationID, newConversationID int64) error
}

View File

@ -0,0 +1,137 @@
/*
* Copyright 2025 coze-dev Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package conversation
import (
"context"
"github.com/cloudwego/eino/schema"
"github.com/coze-dev/coze-studio/backend/api/model/crossdomain/message"
"github.com/coze-dev/coze-studio/backend/domain/conversation/conversation/entity"
)
type CreateConversationRequest struct {
AppID int64
UserID int64
ConnectorID int64
}
type CreateMessageRequest struct {
ConversationID int64
Role string
Content string
ContentType string
UserID int64
AppID int64
RunID int64
SectionID int64
}
type MessageListRequest struct {
ConversationID int64
Limit int64
BeforeID *string
AfterID *string
UserID int64
AppID int64
OrderBy *string
}
type MessageListResponse struct {
Messages []*Message
FirstID string
LastID string
HasMore bool
}
var conversationManagerImpl ConversationManager
func GetConversationManager() ConversationManager {
return conversationManagerImpl
}
func SetConversationManager(c ConversationManager) {
conversationManagerImpl = c
}
type ConversationHistoryRequest struct {
ConversationID int64
AppID int64
UserID int64
Rounds int64
}
type Content struct {
Type message.InputType `json:"type"`
Text *string `json:"text,omitempty"`
Uri *string `json:"uri,omitempty"`
}
type Message struct {
ID int64
Role schema.RoleType `json:"role"` // user or assistant
MultiContent []*Content `json:"multi_content"`
Text *string `json:"text,omitempty"`
ContentType string `json:"content_type"`
}
type ConversationHistoryResponse struct {
Messages []*Message
}
type GetLatestRunIDsRequest struct {
ConversationID int64
UserID int64
AppID int64
Rounds int64
}
type ClearConversationHistoryReq struct {
ConversationID int64
}
type DeleteMessageRequest struct {
ConversationID int64
MessageID int64
}
type EditMessageRequest struct {
ConversationID int64
MessageID int64
Content string
}
type GetMessagesByRunIDsRequest struct {
ConversationID int64
RunIDs []int64
}
type GetMessagesByRunIDsResponse struct {
Messages []*Message
}
//go:generate mockgen -destination conversationmock/conversation_mock.go --package conversationmock -source conversation.go
type ConversationManager interface {
CreateConversation(ctx context.Context, req *CreateConversationRequest) (int64, int64, error)
CreateMessage(ctx context.Context, req *CreateMessageRequest) (int64, error)
MessageList(ctx context.Context, req *MessageListRequest) (*MessageListResponse, error)
GetLatestRunIDs(ctx context.Context, req *GetLatestRunIDsRequest) ([]int64, error)
GetMessagesByRunIDs(ctx context.Context, req *GetMessagesByRunIDsRequest) (*GetMessagesByRunIDsResponse, error)
ClearConversationHistory(ctx context.Context, req *ClearConversationHistoryReq) (int64, error)
DeleteMessage(ctx context.Context, req *DeleteMessageRequest) error
EditMessage(ctx context.Context, req *EditMessageRequest) error
GetByID(ctx context.Context, id int64) (*entity.Conversation, error)
}

View File

@ -0,0 +1,159 @@
// Code generated by MockGen. DO NOT EDIT.
// Source: conversation.go
//
// Generated by this command:
//
// mockgen -destination conversationmock/conversation_mock.go --package conversationmock -source conversation.go
//
// Package conversationmock is a generated GoMock package.
package conversationmock
import (
context "context"
reflect "reflect"
conversation "github.com/coze-dev/coze-studio/backend/domain/workflow/crossdomain/conversation"
gomock "go.uber.org/mock/gomock"
)
// MockConversationManager is a mock of ConversationManager interface.
type MockConversationManager struct {
ctrl *gomock.Controller
recorder *MockConversationManagerMockRecorder
isgomock struct{}
}
// MockConversationManagerMockRecorder is the mock recorder for MockConversationManager.
type MockConversationManagerMockRecorder struct {
mock *MockConversationManager
}
// NewMockConversationManager creates a new mock instance.
func NewMockConversationManager(ctrl *gomock.Controller) *MockConversationManager {
mock := &MockConversationManager{ctrl: ctrl}
mock.recorder = &MockConversationManagerMockRecorder{mock}
return mock
}
// EXPECT returns an object that allows the caller to indicate expected use.
func (m *MockConversationManager) EXPECT() *MockConversationManagerMockRecorder {
return m.recorder
}
// ClearConversationHistory mocks base method.
func (m *MockConversationManager) ClearConversationHistory(ctx context.Context, req *conversation.ClearConversationHistoryReq) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "ClearConversationHistory", ctx, req)
ret0, _ := ret[0].(error)
return ret0
}
// ClearConversationHistory indicates an expected call of ClearConversationHistory.
func (mr *MockConversationManagerMockRecorder) ClearConversationHistory(ctx, req any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ClearConversationHistory", reflect.TypeOf((*MockConversationManager)(nil).ClearConversationHistory), ctx, req)
}
// CreateConversation mocks base method.
func (m *MockConversationManager) CreateConversation(ctx context.Context, req *conversation.CreateConversationRequest) (int64, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "CreateConversation", ctx, req)
ret0, _ := ret[0].(int64)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// CreateConversation indicates an expected call of CreateConversation.
func (mr *MockConversationManagerMockRecorder) CreateConversation(ctx, req any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateConversation", reflect.TypeOf((*MockConversationManager)(nil).CreateConversation), ctx, req)
}
// CreateMessage mocks base method.
func (m *MockConversationManager) CreateMessage(ctx context.Context, req *conversation.CreateMessageRequest) (int64, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "CreateMessage", ctx, req)
ret0, _ := ret[0].(int64)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// CreateMessage indicates an expected call of CreateMessage.
func (mr *MockConversationManagerMockRecorder) CreateMessage(ctx, req any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateMessage", reflect.TypeOf((*MockConversationManager)(nil).CreateMessage), ctx, req)
}
// DeleteMessage mocks base method.
func (m *MockConversationManager) DeleteMessage(ctx context.Context, req *conversation.DeleteMessageRequest) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "DeleteMessage", ctx, req)
ret0, _ := ret[0].(error)
return ret0
}
// DeleteMessage indicates an expected call of DeleteMessage.
func (mr *MockConversationManagerMockRecorder) DeleteMessage(ctx, req any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteMessage", reflect.TypeOf((*MockConversationManager)(nil).DeleteMessage), ctx, req)
}
// EditMessage mocks base method.
func (m *MockConversationManager) EditMessage(ctx context.Context, req *conversation.EditMessageRequest) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "EditMessage", ctx, req)
ret0, _ := ret[0].(error)
return ret0
}
// EditMessage indicates an expected call of EditMessage.
func (mr *MockConversationManagerMockRecorder) EditMessage(ctx, req any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EditMessage", reflect.TypeOf((*MockConversationManager)(nil).EditMessage), ctx, req)
}
// GetLatestRunIDs mocks base method.
func (m *MockConversationManager) GetLatestRunIDs(ctx context.Context, req *conversation.GetLatestRunIDsRequest) ([]int64, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "GetLatestRunIDs", ctx, req)
ret0, _ := ret[0].([]int64)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// GetLatestRunIDs indicates an expected call of GetLatestRunIDs.
func (mr *MockConversationManagerMockRecorder) GetLatestRunIDs(ctx, req any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetLatestRunIDs", reflect.TypeOf((*MockConversationManager)(nil).GetLatestRunIDs), ctx, req)
}
// GetMessagesByRunIDs mocks base method.
func (m *MockConversationManager) GetMessagesByRunIDs(ctx context.Context, req *conversation.GetMessagesByRunIDsRequest) (*conversation.GetMessagesByRunIDsResponse, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "GetMessagesByRunIDs", ctx, req)
ret0, _ := ret[0].(*conversation.GetMessagesByRunIDsResponse)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// GetMessagesByRunIDs indicates an expected call of GetMessagesByRunIDs.
func (mr *MockConversationManagerMockRecorder) GetMessagesByRunIDs(ctx, req any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetMessagesByRunIDs", reflect.TypeOf((*MockConversationManager)(nil).GetMessagesByRunIDs), ctx, req)
}
// MessageList mocks base method.
func (m *MockConversationManager) MessageList(ctx context.Context, req *conversation.MessageListRequest) (*conversation.MessageListResponse, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "MessageList", ctx, req)
ret0, _ := ret[0].(*conversation.MessageListResponse)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// MessageList indicates an expected call of MessageList.
func (mr *MockConversationManagerMockRecorder) MessageList(ctx, req any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MessageList", reflect.TypeOf((*MockConversationManager)(nil).MessageList), ctx, req)
}

View File

@ -0,0 +1,37 @@
/*
* Copyright 2025 coze-dev Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package entity
import "time"
type ChatFlowRole struct {
ID int64
WorkflowID int64
ConnectorID int64
Name string
Description string
Version string
AvatarUri string
BackgroundImageInfo string
OnboardingInfo string
SuggestReplyInfo string
AudioConfig string
UserInputConfig string
CreatorID int64
CreatedAt time.Time
UpdatedAt time.Time
}

View File

@ -0,0 +1,39 @@
/*
* Copyright 2025 coze-dev Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package entity
type ConversationTemplate struct {
SpaceID int64
AppID int64
Name string
TemplateID int64
}
type StaticConversation struct {
UserID int64
ConnectorID int64
TemplateID int64
ConversationID int64
}
type DynamicConversation struct {
ID int64
UserID int64
ConnectorID int64
ConversationID int64
Name string
}

View File

@ -72,3 +72,9 @@ type ToolInterruptEvent struct {
ExecuteID int64
*InterruptEvent
}
type ConvRelatedInfo struct {
EventID int64
ExecID int64
NodeType NodeType
}

View File

@ -144,8 +144,11 @@ const (
NodeTypeCodeRunner NodeType = "CodeRunner"
NodeTypePlugin NodeType = "Plugin"
NodeTypeCreateConversation NodeType = "CreateConversation"
NodeTypeConversationList NodeType = "ConversationList"
NodeTypeMessageList NodeType = "MessageList"
NodeTypeClearMessage NodeType = "ClearMessage"
NodeTypeCreateMessage NodeType = "CreateMessage"
NodeTypeEditMessage NodeType = "EditMessage"
NodeTypeDeleteMessage NodeType = "DeleteMessage"
NodeTypeLambda NodeType = "Lambda"
NodeTypeLLM NodeType = "LLM"
NodeTypeSelector NodeType = "Selector"
@ -153,6 +156,10 @@ const (
NodeTypeSubWorkflow NodeType = "SubWorkflow"
NodeTypeJsonSerialization NodeType = "JsonSerialization"
NodeTypeJsonDeserialization NodeType = "JsonDeserialization"
NodeTypeConversationUpdate NodeType = "ConversationUpdate"
NodeTypeConversationDelete NodeType = "ConversationDelete"
NodeTypeClearConversationHistory NodeType = "ClearConversationHistory"
NodeTypeConversationHistory NodeType = "ConversationHistory"
NodeTypeComment NodeType = "Comment"
)
@ -272,6 +279,7 @@ var NodeTypeMetas = map[NodeType]*NodeTypeMeta{
PostFillNil: true,
InputSourceAware: true,
MayUseChatModel: true,
UseCtxCache: true,
},
EnUSName: "LLM",
EnUSDescription: "Invoke the large language model, generate responses using variables and prompt words.",
@ -324,6 +332,7 @@ var NodeTypeMetas = map[NodeType]*NodeTypeMeta{
ExecutableMeta: ExecutableMeta{
PreFillZero: true,
PostFillNil: true,
UseCtxCache: true,
},
EnUSName: "Knowledge retrieval",
EnUSDescription: "In the selected knowledge, the best matching information is recalled based on the input variable and returned as an Array.",
@ -487,6 +496,7 @@ var NodeTypeMetas = map[NodeType]*NodeTypeMeta{
PreFillZero: true,
PostFillNil: true,
MayUseChatModel: true,
UseCtxCache: true,
},
EnUSName: "Intent recognition",
EnUSDescription: "Used for recognizing the intent in user input and matching it with preset intent options.",
@ -593,7 +603,6 @@ var NodeTypeMetas = map[NodeType]*NodeTypeMeta{
Color: "#F2B600",
IconURL: "https://lf3-static.bytednsdoc.com/obj/eden-cn/dvsmryvd_avi_dvsm/ljhwZthlaukjlkulzlp/icon/icon-Conversation-List.jpeg",
SupportBatch: false,
Disabled: true,
ExecutableMeta: ExecutableMeta{
PreFillZero: true,
PostFillNil: true,
@ -601,16 +610,15 @@ var NodeTypeMetas = map[NodeType]*NodeTypeMeta{
EnUSName: "Query message list",
EnUSDescription: "Used to query the message list",
},
NodeTypeClearMessage: {
NodeTypeClearConversationHistory: {
ID: 38,
Key: NodeTypeClearMessage,
Name: "清除上下文",
Category: "conversation_history",
Key: NodeTypeClearConversationHistory,
Name: "清空会话历史",
Category: "conversation_history", // Mapped from cate_list
Desc: "用于清空会话历史清空后LLM看到的会话历史为空",
Color: "#F2B600",
IconURL: "https://lf3-static.bytednsdoc.com/obj/eden-cn/dvsmryvd_avi_dvsm/ljhwZthlaukjlkulzlp/icon/icon-Conversation-Delete.jpeg",
SupportBatch: false,
Disabled: true,
SupportBatch: false, // supportBatch: 1
ExecutableMeta: ExecutableMeta{
PreFillZero: true,
PostFillNil: true,
@ -627,7 +635,6 @@ var NodeTypeMetas = map[NodeType]*NodeTypeMeta{
Color: "#F2B600",
IconURL: "https://lf3-static.bytednsdoc.com/obj/eden-cn/dvsmryvd_avi_dvsm/ljhwZthlaukjlkulzlp/icon/icon-Conversation-Create.jpeg",
SupportBatch: false,
Disabled: true,
ExecutableMeta: ExecutableMeta{
PreFillZero: true,
PostFillNil: true,
@ -730,6 +737,118 @@ var NodeTypeMetas = map[NodeType]*NodeTypeMeta{
EnUSName: "Add Data",
EnUSDescription: "Add new data records to the table, and insert them into the database after the user enters the data content",
},
NodeTypeConversationUpdate: {
ID: 51,
Name: "修改会话",
Key: NodeTypeConversationUpdate,
Category: "conversation_management",
Desc: "用于修改会话的名字",
Color: "#F2B600",
IconURL: "https://lf3-static.bytednsdoc.com/obj/eden-cn/dvsmryvd_avi_dvsm/ljhwZthlaukjlkulzlp/icon/icon-编辑会话.jpg",
SupportBatch: false,
ExecutableMeta: ExecutableMeta{
PreFillZero: true,
PostFillNil: true,
},
EnUSName: "Edit Conversation",
EnUSDescription: "Used to modify the name of a conversation.",
},
NodeTypeConversationDelete: {
ID: 52,
Name: "删除会话",
Key: NodeTypeConversationDelete,
Category: "conversation_management",
Desc: "用于删除会话",
Color: "#F2B600",
IconURL: "https://lf3-static.bytednsdoc.com/obj/eden-cn/dvsmryvd_avi_dvsm/ljhwZthlaukjlkulzlp/icon/icon-删除会话.jpg",
SupportBatch: false,
ExecutableMeta: ExecutableMeta{
PreFillZero: true,
PostFillNil: true,
},
EnUSName: "Delete Conversation",
EnUSDescription: "Used to delete a conversation.",
},
NodeTypeConversationList: {
ID: 53,
Name: "查询会话列表",
Key: NodeTypeConversationList,
Category: "conversation_management",
Desc: "用于查询所有会话,包含静态会话、动态会话",
Color: "#F2B600",
IconURL: "https://lf3-static.bytednsdoc.com/obj/eden-cn/dvsmryvd_avi_dvsm/ljhwZthlaukjlkulzlp/icon/icon-查询会话.jpg",
SupportBatch: false,
ExecutableMeta: ExecutableMeta{
PostFillNil: true,
},
EnUSName: "Query Conversation List",
EnUSDescription: "Used to query all conversations, including static conversations and dynamic conversations",
},
NodeTypeConversationHistory: {
ID: 54,
Name: "查询会话历史",
Key: NodeTypeConversationHistory,
Category: "conversation_history", // Mapped from cate_list
Desc: "用于查询会话历史返回LLM可见的会话消息",
Color: "#F2B600",
IconURL: "https://lf3-static.bytednsdoc.com/obj/eden-cn/dvsmryvd_avi_dvsm/ljhwZthlaukjlkulzlp/icon/icon-查询会话历史.jpg",
SupportBatch: false,
ExecutableMeta: ExecutableMeta{
PreFillZero: true,
PostFillNil: true,
},
EnUSName: "Query Conversation History",
EnUSDescription: "Used to query conversation history, returns conversation messages visible to the LLM",
},
NodeTypeCreateMessage: {
ID: 55,
Name: "创建消息",
Key: NodeTypeCreateMessage,
Category: "message",
Desc: "用于创建消息",
Color: "#F2B600",
IconURL: "https://lf3-static.bytednsdoc.com/obj/eden-cn/dvsmryvd_avi_dvsm/ljhwZthlaukjlkulzlp/icon/icon-创建消息.jpg",
SupportBatch: false, // supportBatch: 1
ExecutableMeta: ExecutableMeta{
PreFillZero: true,
PostFillNil: true,
},
EnUSName: "Create message",
EnUSDescription: "Used to create messages",
},
NodeTypeEditMessage: {
ID: 56,
Name: "修改消息",
Key: NodeTypeEditMessage,
Category: "message",
Desc: "用于修改消息",
Color: "#F2B600",
IconURL: "https://lf3-static.bytednsdoc.com/obj/eden-cn/dvsmryvd_avi_dvsm/ljhwZthlaukjlkulzlp/icon/icon-修改消息.jpg",
SupportBatch: false, // supportBatch: 1
ExecutableMeta: ExecutableMeta{
PreFillZero: true,
PostFillNil: true,
},
EnUSName: "Edit message",
EnUSDescription: "Used to edit messages",
},
NodeTypeDeleteMessage: {
ID: 57,
Name: "删除消息",
Key: NodeTypeDeleteMessage,
Category: "message",
Desc: "用于删除消息",
Color: "#F2B600",
IconURL: "https://lf3-static.bytednsdoc.com/obj/eden-cn/dvsmryvd_avi_dvsm/ljhwZthlaukjlkulzlp/icon/icon-删除消息.jpg",
SupportBatch: false, // supportBatch: 1
ExecutableMeta: ExecutableMeta{
PreFillZero: true,
PostFillNil: true,
},
EnUSName: "Delete message",
EnUSDescription: "Used to delete messages",
},
NodeTypeJsonSerialization: {
// ID is the unique identifier of this node type. Used in various front-end APIs.
ID: 58,

View File

@ -17,6 +17,8 @@
package vo
import (
"fmt"
model "github.com/coze-dev/coze-studio/backend/api/model/crossdomain/modelmgr"
"github.com/coze-dev/coze-studio/backend/api/model/workflow"
"github.com/coze-dev/coze-studio/backend/pkg/i18n"
@ -108,7 +110,8 @@ type Data struct {
type Inputs struct {
// InputParameters are the fields defined by user for this particular node.
InputParameters []*Param `json:"inputParameters"`
// ChatHistorySetting configures the chat history setting for this node in chatflow mode.
ChatHistorySetting *ChatHistorySetting `json:"chatHistorySetting,omitempty"`
// SettingOnError configures common error handling strategy for nodes.
// NOTE: enable in frontend node's form first.
SettingOnError *SettingOnError `json:"settingOnError,omitempty"`
@ -432,9 +435,8 @@ type DatabaseInfo struct {
}
type IntentDetector struct {
ChatHistorySetting *ChatHistorySetting `json:"chatHistorySetting,omitempty"`
Intents []*Intent `json:"intents,omitempty"`
Mode string `json:"mode,omitempty"`
Intents []*Intent `json:"intents,omitempty"`
Mode string `json:"mode,omitempty"`
}
type ChatHistorySetting struct {
EnableChatHistory bool `json:"enableChatHistory,omitempty"`
@ -826,6 +828,133 @@ const defaultEnUSInitCanvasJsonSchema = `{
}
}`
const defaultZhCNInitCanvasJsonSchemaChat = `{
"nodes": [{
"id": "100001",
"type": "1",
"meta": {
"position": {
"x": 0,
"y": 0
}
},
"data": {
"outputs": [{
"type": "string",
"name": "USER_INPUT",
"required": true
}, {
"type": "string",
"name": "CONVERSATION_NAME",
"required": false,
"description": "本次请求绑定的会话,会自动写入消息、会从该会话读对话历史。",
"defaultValue": "%s"
}],
"nodeMeta": {
"title": "开始",
"icon": "https://lf3-static.bytednsdoc.com/obj/eden-cn/dvsmryvd_avi_dvsm/ljhwZthlaukjlkulzlp/icon/icon-Start.png",
"description": "工作流的起始节点,用于设定启动工作流需要的信息",
"subTitle": ""
}
}
}, {
"id": "900001",
"type": "2",
"meta": {
"position": {
"x": 1000,
"y": 0
}
},
"data": {
"nodeMeta": {
"title": "结束",
"icon": "https://lf3-static.bytednsdoc.com/obj/eden-cn/dvsmryvd_avi_dvsm/ljhwZthlaukjlkulzlp/icon/icon-End.png",
"description": "工作流的最终节点,用于返回工作流运行后的结果信息",
"subTitle": ""
},
"inputs": {
"terminatePlan": "useAnswerContent",
"streamingOutput": true,
"inputParameters": [{
"name": "output",
"input": {
"type": "string",
"value": {
"type": "ref"
}
}
}]
}
}
}]
}`
const defaultEnUSInitCanvasJsonSchemaChat = `{
"nodes": [{
"id": "100001",
"type": "1",
"meta": {
"position": {
"x": 0,
"y": 0
}
},
"data": {
"outputs": [{
"type": "string",
"name": "USER_INPUT",
"required": true
}, {
"type": "string",
"name": "CONVERSATION_NAME",
"required": false,
"description": "The conversation bound to this request will automatically write messages and read conversation history from that conversation.",
"defaultValue": "%s"
}],
"nodeMeta": {
"title": "Start",
"icon": "https://lf3-static.bytednsdoc.com/obj/eden-cn/dvsmryvd_avi_dvsm/ljhwZthlaukjlkulzlp/icon/icon-Start.png",
"description": "The starting node of the workflow, used to set the information needed to initiate the workflow.",
"subTitle": ""
}
}
}, {
"id": "900001",
"type": "2",
"meta": {
"position": {
"x": 1000,
"y": 0
}
},
"data": {
"nodeMeta": {
"title": "End",
"icon": "https://lf3-static.bytednsdoc.com/obj/eden-cn/dvsmryvd_avi_dvsm/ljhwZthlaukjlkulzlp/icon/icon-End.png",
"description": "The final node of the workflow, used to return the result information after the workflow runs.",
"subTitle": ""
},
"inputs": {
"terminatePlan": "useAnswerContent",
"streamingOutput": true,
"inputParameters": [{
"name": "output",
"input": {
"type": "string",
"value": {
"type": "ref"
}
}
}]
}
}
}]
}`
func GetDefaultInitCanvasJsonSchema(locale i18n.Locale) string {
return ternary.IFElse(locale == i18n.LocaleEN, defaultEnUSInitCanvasJsonSchema, defaultZhCNInitCanvasJsonSchema)
}
func GetDefaultInitCanvasJsonSchemaChat(locale i18n.Locale, name string) string {
return ternary.IFElse(locale == i18n.LocaleEN, fmt.Sprintf(defaultEnUSInitCanvasJsonSchemaChat, name), fmt.Sprintf(defaultZhCNInitCanvasJsonSchemaChat, name))
}

View File

@ -0,0 +1,54 @@
/*
* Copyright 2025 coze-dev Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package vo
type ChatFlowRoleCreate struct {
WorkflowID int64
CreatorID int64
Name string
Description string
AvatarUri string
BackgroundImageInfo string
OnboardingInfo string
SuggestReplyInfo string
AudioConfig string
UserInputConfig string
}
type ChatFlowRoleUpdate struct {
WorkflowID int64
Name *string
Description *string
AvatarUri *string
BackgroundImageInfo *string
OnboardingInfo *string
SuggestReplyInfo *string
AudioConfig *string
UserInputConfig *string
}
type PublishRolePolicy struct {
WorkflowID int64
CreatorID int64
Version string
}
type CopyRolePolicy struct {
SourceID int64
TargetID int64
CreatorID int64
}

View File

@ -0,0 +1,74 @@
/*
* Copyright 2025 coze-dev Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package vo
type ChatFlowEvent string
const (
ChatFlowCreated ChatFlowEvent = "conversation.chat.created"
ChatFlowInProgress ChatFlowEvent = "conversation.chat.in_progress"
ChatFlowCompleted ChatFlowEvent = "conversation.chat.completed"
ChatFlowFailed ChatFlowEvent = "conversation.chat.failed"
ChatFlowRequiresAction ChatFlowEvent = "conversation.chat.requires_action"
ChatFlowError ChatFlowEvent = "error"
ChatFlowDone ChatFlowEvent = "done"
ChatFlowMessageDelta ChatFlowEvent = "conversation.message.delta"
ChatFlowMessageCompleted ChatFlowEvent = "conversation.message.completed"
)
type Usage struct {
TokenCount *int32 `form:"token_count" json:"token_count,omitempty"`
OutputTokens *int32 `form:"output_count" json:"output_count,omitempty"`
InputTokens *int32 `form:"input_count" json:"input_count,omitempty"`
}
type Status string
const (
Created Status = "created"
InProgress Status = "in_progress"
Completed Status = "completed"
Failed Status = "failed"
RequiresAction Status = "requires_action"
Canceled Status = "canceled"
)
type ChatFlowDetail struct {
ID string `json:"id,omitempty"`
ConversationID string `json:"conversation_id,omitempty"`
BotID string `json:"bot_id,omitempty"`
Status Status `json:"status,omitempty"`
Usage *Usage `json:"usage,omitempty"`
ExecuteID string `json:"execute_id,omitempty"`
}
type MessageDetail struct {
ID string `json:"id"`
ChatID string `json:"chat_id"`
ConversationID string `json:"conversation_id"`
BotID string `json:"bot_id"`
Role string `json:"role"`
Type string `json:"type"`
Content string `json:"content"`
ContentType string `json:"content_type"`
}
type ErrorDetail struct {
Code string `form:"code,required" json:"code,required"`
Msg string `form:"msg,required" json:"msg,required"`
DebugUrl string `form:"debug_url" json:"debug_url,omitempty"`
}

View File

@ -0,0 +1,74 @@
/*
* Copyright 2025 coze-dev Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package vo
type Env string
const (
Draft Env = "draft"
Online Env = "online"
)
type CreateConversationTemplateMeta struct {
UserID int64
AppID int64
SpaceID int64
Name string
}
type GetConversationTemplatePolicy struct {
AppID *int64
Name *string
Version *string
TemplateID *int64
}
type ListConversationTemplatePolicy struct {
AppID int64
Page *Page
NameLike *string
Version *string
}
type ListConversationMeta struct {
APPID int64
UserID int64
ConnectorID int64
}
type ListConversationPolicy struct {
ListConversationMeta
Page *Page
NameLike *string
Version *string
}
type CreateStaticConversation struct {
AppID int64
UserID int64
ConnectorID int64
TemplateID int64
}
type CreateDynamicConversation struct {
AppID int64
UserID int64
ConnectorID int64
Name string
}

View File

@ -16,22 +16,34 @@
package vo
import (
"github.com/cloudwego/eino/schema"
"github.com/coze-dev/coze-studio/backend/api/model/workflow"
"github.com/coze-dev/coze-studio/backend/domain/workflow/crossdomain/conversation"
)
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
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
WorkflowMode WorkflowMode
RoundID *int64 // if workflow is chat flow, conversation round id is required
ConversationID *int64 // if workflow is chat flow, conversation id is required
UserMessage *schema.Message
ConversationHistory []*conversation.Message
SectionID *int64
}
type ExecuteMode string
@ -42,6 +54,8 @@ const (
ExecuteModeNodeDebug ExecuteMode = "node_debug"
)
type WorkflowMode = workflow.WorkflowMode
type TaskType string
const (

View File

@ -68,6 +68,7 @@ type MetaUpdate struct {
IconURI *string
HasPublished *bool
LatestPublishedVersion *string
WorkflowMode *Mode
}
type MetaQuery struct {
@ -80,4 +81,5 @@ type MetaQuery struct {
LibOnly bool
NeedTotalNumber bool
DescByUpdate bool
Mode *workflow.WorkflowMode
}

View File

@ -26,6 +26,7 @@ import (
"github.com/coze-dev/coze-studio/backend/domain/workflow/entity"
"github.com/coze-dev/coze-studio/backend/domain/workflow/entity/vo"
"github.com/coze-dev/coze-studio/backend/infra/contract/idgen"
"github.com/coze-dev/coze-studio/backend/infra/contract/storage"
)
//go:generate mockgen -destination ../../internal/mock/domain/workflow/interface.go --package mockWorkflow -source interface.go
@ -39,12 +40,21 @@ type Service interface {
Publish(ctx context.Context, policy *vo.PublishPolicy) (err error)
UpdateMeta(ctx context.Context, id int64, metaUpdate *vo.MetaUpdate) (err error)
CopyWorkflow(ctx context.Context, workflowID int64, policy vo.CopyWorkflowPolicy) (*entity.Workflow, error)
WorkflowSchemaCheck(ctx context.Context, wf *entity.Workflow, checks []workflow.CheckType) ([]*workflow.CheckResult, error)
QueryNodeProperties(ctx context.Context, id int64) (map[string]*vo.NodeProperty, error) // only draft
ValidateTree(ctx context.Context, id int64, validateConfig vo.ValidateTreeConfig) ([]*workflow.ValidateTreeInfo, error)
GetWorkflowReference(ctx context.Context, id int64) (map[int64]*vo.Meta, error)
CreateChatFlowRole(ctx context.Context, role *vo.ChatFlowRoleCreate) (int64, error)
UpdateChatFlowRole(ctx context.Context, workflowID int64, role *vo.ChatFlowRoleUpdate) error
GetChatFlowRole(ctx context.Context, workflowID int64, version string) (*entity.ChatFlowRole, error)
DeleteChatFlowRole(ctx context.Context, id int64, workflowID int64) error
PublishChatFlowRole(ctx context.Context, policy *vo.PublishRolePolicy) error
CopyChatFlowRole(ctx context.Context, policy *vo.CopyRolePolicy) error
GetWorkflowVersionsByConnector(ctx context.Context, connectorID, workflowID int64, limit int) ([]string, error)
Executable
AsTool
@ -53,17 +63,27 @@ type Service interface {
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
ConversationService
BindConvRelatedInfo(ctx context.Context, convID int64, info entity.ConvRelatedInfo) error
GetConvRelatedInfo(ctx context.Context, convID int64) (*entity.ConvRelatedInfo, bool, func() error, error)
}
type Repository interface {
CreateMeta(ctx context.Context, meta *vo.Meta) (int64, error)
CreateVersion(ctx context.Context, id int64, info *vo.VersionInfo, newRefs map[entity.WorkflowReferenceKey]struct{}) (err error)
CreateOrUpdateDraft(ctx context.Context, id int64, draft *vo.DraftInfo) error
CreateChatFlowRoleConfig(ctx context.Context, chatFlowRole *entity.ChatFlowRole) (int64, error)
UpdateChatFlowRoleConfig(ctx context.Context, workflowID int64, chatFlowRole *vo.ChatFlowRoleUpdate) error
GetChatFlowRoleConfig(ctx context.Context, workflowID int64, version string) (*entity.ChatFlowRole, error, bool)
DeleteChatFlowRoleConfig(ctx context.Context, id int64, workflowID int64) error
Delete(ctx context.Context, id int64) error
MDelete(ctx context.Context, ids []int64) error
GetMeta(ctx context.Context, id int64) (*vo.Meta, error)
UpdateMeta(ctx context.Context, id int64, metaUpdate *vo.MetaUpdate) error
GetVersion(ctx context.Context, id int64, version string) (*vo.VersionInfo, error)
GetVersionListByConnectorAndWorkflowID(ctx context.Context, connectorID, workflowID int64, limit int) ([]string, error)
GetEntity(ctx context.Context, policy *vo.GetPolicy) (*entity.Workflow, error)
@ -95,10 +115,13 @@ type Repository interface {
IsApplicationConnectorWorkflowVersion(ctx context.Context, connectorID, workflowID int64, version string) (b bool, err error)
GetObjectUrl(ctx context.Context, objectKey string, opts ...storage.GetOptFn) (string, error)
compose.CheckPointStore
idgen.IDGenerator
GetKnowledgeRecallChatModel() model.BaseChatModel
ConversationRepository
}
var repositorySingleton Repository

View File

@ -33,6 +33,7 @@ import (
"github.com/coze-dev/coze-studio/backend/domain/workflow/internal/nodes"
"github.com/coze-dev/coze-studio/backend/domain/workflow/internal/nodes/batch"
"github.com/coze-dev/coze-studio/backend/domain/workflow/internal/nodes/code"
"github.com/coze-dev/coze-studio/backend/domain/workflow/internal/nodes/conversation"
"github.com/coze-dev/coze-studio/backend/domain/workflow/internal/nodes/database"
"github.com/coze-dev/coze-studio/backend/domain/workflow/internal/nodes/emitter"
"github.com/coze-dev/coze-studio/backend/domain/workflow/internal/nodes/entry"
@ -673,6 +674,36 @@ func RegisterAllNodeAdaptors() {
nodes.RegisterNodeAdaptor(entity.NodeTypeLLM, func() nodes.NodeAdaptor {
return &llm.Config{}
})
nodes.RegisterNodeAdaptor(entity.NodeTypeCreateConversation, func() nodes.NodeAdaptor {
return &conversation.CreateConversationConfig{}
})
nodes.RegisterNodeAdaptor(entity.NodeTypeConversationUpdate, func() nodes.NodeAdaptor {
return &conversation.UpdateConversationConfig{}
})
nodes.RegisterNodeAdaptor(entity.NodeTypeConversationDelete, func() nodes.NodeAdaptor {
return &conversation.DeleteConversationConfig{}
})
nodes.RegisterNodeAdaptor(entity.NodeTypeConversationList, func() nodes.NodeAdaptor {
return &conversation.ConversationListConfig{}
})
nodes.RegisterNodeAdaptor(entity.NodeTypeConversationHistory, func() nodes.NodeAdaptor {
return &conversation.ConversationHistoryConfig{}
})
nodes.RegisterNodeAdaptor(entity.NodeTypeClearConversationHistory, func() nodes.NodeAdaptor {
return &conversation.ClearConversationHistoryConfig{}
})
nodes.RegisterNodeAdaptor(entity.NodeTypeMessageList, func() nodes.NodeAdaptor {
return &conversation.MessageListConfig{}
})
nodes.RegisterNodeAdaptor(entity.NodeTypeCreateMessage, func() nodes.NodeAdaptor {
return &conversation.CreateMessageConfig{}
})
nodes.RegisterNodeAdaptor(entity.NodeTypeEditMessage, func() nodes.NodeAdaptor {
return &conversation.EditMessageConfig{}
})
nodes.RegisterNodeAdaptor(entity.NodeTypeDeleteMessage, func() nodes.NodeAdaptor {
return &conversation.DeleteMessageConfig{}
})
// register branch adaptors
nodes.RegisterBranchAdaptor(entity.NodeTypeSelector, func() nodes.BranchAdaptor {

View File

@ -0,0 +1,93 @@
{
"nodes": [
{
"id": "100001",
"type": "1",
"meta": {
"position": {
"x": 13.818572856225469,
"y": -37.20384999753011
}
},
"data": {
"nodeMeta": {
"title": "开始",
"description": "工作流的起始节点,用于设定启动工作流需要的信息",
"icon": "https://lf3-static.bytednsdoc.com/obj/eden-cn/dvsmryvd_avi_dvsm/ljhwZthlaukjlkulzlp/icon/icon-Start-v2.jpg",
"subTitle": ""
},
"settings": null,
"version": "",
"outputs": [
{
"type": "string",
"name": "USER_INPUT",
"required": false
},
{
"type": "string",
"name": "CONVERSATION_NAME",
"required": false,
"description": "本次请求绑定的会话,会自动写入消息、会从该会话读对话历史。",
"defaultValue": "Default"
},
{
"type": "string",
"name": "input",
"required": false
}
],
"trigger_parameters": []
}
},
{
"id": "900001",
"type": "2",
"meta": {
"position": {
"x": 642.9671427865745,
"y": -37.20384999753011
}
},
"data": {
"nodeMeta": {
"description": "工作流的最终节点,用于返回工作流运行后的结果信息",
"icon": "https://lf3-static.bytednsdoc.com/obj/eden-cn/dvsmryvd_avi_dvsm/ljhwZthlaukjlkulzlp/icon/icon-End-v2.jpg",
"subTitle": "",
"title": "结束"
},
"inputs": {
"terminatePlan": "returnVariables",
"inputParameters": [
{
"name": "output",
"input": {
"type": "string",
"value": {
"type": "ref",
"content": {
"source": "block-output",
"blockID": "100001",
"name": "input"
},
"rawMeta": {
"type": 1
}
}
}
}
]
}
}
}
],
"edges": [
{
"sourceNodeID": "100001",
"targetNodeID": "900001"
}
],
"versions": {
"loop": "v2"
}
}

View File

@ -0,0 +1,89 @@
{
"nodes": [{
"blocks": [],
"data": {
"nodeMeta": {
"description": "工作流的起始节点,用于设定启动工作流需要的信息",
"icon": "https://lf3-static.bytednsdoc.com/obj/eden-cn/dvsmryvd_avi_dvsm/ljhwZthlaukjlkulzlp/icon/icon-Start-v2.jpg",
"subTitle": "",
"title": "开始"
},
"outputs": [{
"name": "USER_INPUT",
"required": false,
"type": "string"
}, {
"defaultValue": "Default",
"description": "本次请求绑定的会话,会自动写入消息、会从该会话读对话历史。",
"name": "CONVERSATION_NAME",
"required": false,
"type": "string"
}],
"trigger_parameters": []
},
"edges": null,
"id": "100001",
"meta": {
"position": {
"x": 0,
"y": 0
}
},
"type": "1"
}, {
"blocks": [],
"data": {
"inputs": {
"content": {
"type": "string",
"value": {
"content": "{{output}}",
"type": "literal"
}
},
"inputParameters": [{
"input": {
"type": "string",
"value": {
"content": {
"blockID": "100001",
"name": "USER_INPUT",
"source": "block-output"
},
"rawMeta": {
"type": 1
},
"type": "ref"
}
},
"name": "output"
}],
"streamingOutput": true,
"terminatePlan": "useAnswerContent"
},
"nodeMeta": {
"description": "工作流的最终节点,用于返回工作流运行后的结果信息",
"icon": "https://lf3-static.bytednsdoc.com/obj/eden-cn/dvsmryvd_avi_dvsm/ljhwZthlaukjlkulzlp/icon/icon-End-v2.jpg",
"subTitle": "",
"title": "结束"
}
},
"edges": null,
"id": "900001",
"meta": {
"position": {
"x": 1000,
"y": 0
}
},
"type": "2"
}],
"edges": [{
"sourceNodeID": "100001",
"targetNodeID": "900001",
"sourcePortID": ""
}],
"versions": {
"loop": "v2"
}
}

View File

@ -0,0 +1,193 @@
{
"nodes": [{
"blocks": [],
"data": {
"nodeMeta": {
"description": "工作流的起始节点,用于设定启动工作流需要的信息",
"icon": "https://lf3-static.bytednsdoc.com/obj/eden-cn/dvsmryvd_avi_dvsm/ljhwZthlaukjlkulzlp/icon/icon-Start-v2.jpg",
"subTitle": "",
"title": "开始"
},
"outputs": [{
"name": "USER_INPUT",
"required": false,
"type": "string"
}, {
"defaultValue": "Default",
"description": "本次请求绑定的会话,会自动写入消息、会从该会话读对话历史。",
"name": "CONVERSATION_NAME",
"required": false,
"type": "string"
}],
"trigger_parameters": []
},
"edges": null,
"id": "100001",
"meta": {
"position": {
"x": 0,
"y": 0
}
},
"type": "1"
}, {
"blocks": [],
"data": {
"inputs": {
"content": {
"type": "string",
"value": {
"content": "{{output}}",
"type": "literal"
}
},
"inputParameters": [{
"input": {
"schema": {
"schema": [{
"name": "conversationName",
"type": "string"
}, {
"name": "conversationId",
"type": "string"
}],
"type": "object"
},
"type": "list",
"value": {
"content": {
"blockID": "107363",
"name": "conversationList",
"source": "block-output"
},
"rawMeta": {
"type": 103
},
"type": "ref"
}
},
"name": "output"
}],
"streamingOutput": true,
"terminatePlan": "useAnswerContent"
},
"nodeMeta": {
"description": "工作流的最终节点,用于返回工作流运行后的结果信息",
"icon": "https://lf3-static.bytednsdoc.com/obj/eden-cn/dvsmryvd_avi_dvsm/ljhwZthlaukjlkulzlp/icon/icon-End-v2.jpg",
"subTitle": "",
"title": "结束"
}
},
"edges": null,
"id": "900001",
"meta": {
"position": {
"x": 1058,
"y": -13
}
},
"type": "2"
}, {
"blocks": [],
"data": {
"inputs": {
"inputParameters": []
},
"nodeMeta": {
"description": "用于查询所有会话,包含静态会话、动态会话",
"icon": "https://lf3-static.bytednsdoc.com/obj/eden-cn/dvsmryvd_avi_dvsm/ljhwZthlaukjlkulzlp/icon/icon-查询会话.jpg",
"mainColor": "#F2B600",
"subTitle": "查询会话列表",
"title": "查询会话列表"
},
"outputs": [{
"name": "conversationList",
"schema": {
"schema": [{
"name": "conversationName",
"type": "string"
}, {
"name": "conversationId",
"type": "string"
}],
"type": "object"
},
"type": "list"
}]
},
"edges": null,
"id": "107363",
"meta": {
"position": {
"x": 561,
"y": 186
}
},
"type": "53"
}, {
"blocks": [],
"data": {
"inputs": {
"inputParameters": [{
"input": {
"type": "string",
"value": {
"content": {
"blockID": "100001",
"name": "CONVERSATION_NAME",
"source": "block-output"
},
"rawMeta": {
"type": 1
},
"type": "ref"
}
},
"name": "conversationName"
}]
},
"nodeMeta": {
"description": "用于创建会话",
"icon": "https://lf3-static.bytednsdoc.com/obj/eden-cn/dvsmryvd_avi_dvsm/ljhwZthlaukjlkulzlp/icon/icon-Conversation-Create.jpeg",
"mainColor": "#F2B600",
"subTitle": "创建会话",
"title": "创建会话"
},
"outputs": [{
"name": "isSuccess",
"type": "boolean"
}, {
"name": "isExisted",
"type": "boolean"
}, {
"name": "conversationId",
"type": "string"
}]
},
"edges": null,
"id": "110245",
"meta": {
"position": {
"x": 487,
"y": -196
}
},
"type": "39"
}],
"edges": [{
"sourceNodeID": "100001",
"targetNodeID": "110245",
"sourcePortID": ""
}, {
"sourceNodeID": "107363",
"targetNodeID": "900001",
"sourcePortID": ""
}, {
"sourceNodeID": "110245",
"targetNodeID": "107363",
"sourcePortID": ""
}],
"versions": {
"loop": "v2"
}
}

View File

@ -0,0 +1,137 @@
{
"nodes": [
{
"id": "100001",
"type": "1",
"meta": {
"position": {
"x": 180,
"y": 13.700000000000003
}
},
"data": {
"nodeMeta": {
"description": "工作流的起始节点,用于设定启动工作流需要的信息",
"icon": "https://lf3-static.bytednsdoc.com/obj/eden-cn/dvsmryvd_avi_dvsm/ljhwZthlaukjlkulzlp/icon/icon-Start-v2.jpg",
"subTitle": "",
"title": "开始"
},
"outputs": [
{
"type": "string",
"name": "input",
"required": false
}
],
"trigger_parameters": []
}
},
{
"id": "900001",
"type": "2",
"meta": {
"position": {
"x": 1100,
"y": 0.7000000000000028
}
},
"data": {
"nodeMeta": {
"description": "工作流的最终节点,用于返回工作流运行后的结果信息",
"icon": "https://lf3-static.bytednsdoc.com/obj/eden-cn/dvsmryvd_avi_dvsm/ljhwZthlaukjlkulzlp/icon/icon-End-v2.jpg",
"subTitle": "",
"title": "结束"
},
"inputs": {
"terminatePlan": "returnVariables",
"inputParameters": [
{
"name": "output",
"input": {
"type": "string",
"value": {
"type": "ref",
"content": {
"source": "block-output",
"blockID": "163698",
"name": "conversationId"
},
"rawMeta": {
"type": 1
}
}
}
}
]
}
}
},
{
"id": "163698",
"type": "39",
"meta": {
"position": {
"x": 640,
"y": 0
}
},
"data": {
"outputs": [
{
"type": "boolean",
"name": "isSuccess"
},
{
"type": "boolean",
"name": "isExisted"
},
{
"type": "string",
"name": "conversationId"
}
],
"nodeMeta": {
"title": "创建会话",
"icon": "https://lf3-static.bytednsdoc.com/obj/eden-cn/dvsmryvd_avi_dvsm/ljhwZthlaukjlkulzlp/icon/icon-Conversation-Create.jpeg",
"description": "用于创建会话",
"mainColor": "#F2B600",
"subTitle": "创建会话"
},
"inputs": {
"inputParameters": [
{
"name": "conversationName",
"input": {
"type": "string",
"value": {
"type": "ref",
"content": {
"source": "block-output",
"blockID": "100001",
"name": "input"
},
"rawMeta": {
"type": 1
}
}
}
}
]
}
}
}
],
"edges": [
{
"sourceNodeID": "100001",
"targetNodeID": "163698"
},
{
"sourceNodeID": "163698",
"targetNodeID": "900001"
}
],
"versions": {
"loop": "v2"
}
}

View File

@ -0,0 +1,129 @@
{
"nodes": [
{
"id": "100001",
"type": "1",
"meta": {
"position": {
"x": -13.523809523809522,
"y": -25.294372294372295
}
},
"data": {
"nodeMeta": {
"description": "工作流的起始节点,用于设定启动工作流需要的信息",
"icon": "https://lf3-static.bytednsdoc.com/obj/eden-cn/dvsmryvd_avi_dvsm/ljhwZthlaukjlkulzlp/icon/icon-Start-v2.jpg",
"subTitle": "",
"title": "开始"
},
"outputs": [
{
"type": "string",
"name": "input",
"required": false
}
],
"trigger_parameters": []
}
},
{
"id": "900001",
"type": "2",
"meta": {
"position": {
"x": 890.3549783549786,
"y": -71.48917748917748
}
},
"data": {
"nodeMeta": {
"description": "工作流的最终节点,用于返回工作流运行后的结果信息",
"icon": "https://lf3-static.bytednsdoc.com/obj/eden-cn/dvsmryvd_avi_dvsm/ljhwZthlaukjlkulzlp/icon/icon-End-v2.jpg",
"subTitle": "",
"title": "结束"
},
"inputs": {
"terminatePlan": "returnVariables",
"inputParameters": [
{
"name": "output",
"input": {
"type": "boolean",
"value": {
"type": "ref",
"content": {
"source": "block-output",
"blockID": "118024",
"name": "isSuccess"
},
"rawMeta": {
"type": 3
}
}
}
}
]
}
}
},
{
"id": "118024",
"type": "52",
"meta": {
"position": {
"x": 423.6623376623378,
"y": -126.39999999999999
}
},
"data": {
"outputs": [
{
"type": "boolean",
"name": "isSuccess"
}
],
"nodeMeta": {
"title": "删除会话",
"icon": "https://lf3-static.bytednsdoc.com/obj/eden-cn/dvsmryvd_avi_dvsm/ljhwZthlaukjlkulzlp/icon/icon-删除会话.jpg",
"description": "用于删除会话",
"mainColor": "#F2B600",
"subTitle": "删除会话"
},
"inputs": {
"inputParameters": [
{
"name": "conversationName",
"input": {
"type": "string",
"value": {
"type": "ref",
"content": {
"source": "block-output",
"blockID": "100001",
"name": "input"
},
"rawMeta": {
"type": 1
}
}
}
}
]
}
}
}
],
"edges": [
{
"sourceNodeID": "100001",
"targetNodeID": "118024"
},
{
"sourceNodeID": "118024",
"targetNodeID": "900001"
}
],
"versions": {
"loop": "v2"
}
}

View File

@ -0,0 +1,191 @@
{
"nodes": [
{
"id": "100001",
"type": "1",
"meta": {
"position": {
"x": -243.67931247880136,
"y": -233.598184501318
}
},
"data": {
"nodeMeta": {
"description": "工作流的起始节点,用于设定启动工作流需要的信息",
"icon": "https://lf3-static.bytednsdoc.com/obj/eden-cn/dvsmryvd_avi_dvsm/ljhwZthlaukjlkulzlp/icon/icon-Start-v2.jpg",
"subTitle": "",
"title": "开始"
},
"outputs": [
{
"type": "string",
"name": "input",
"required": false
}
],
"trigger_parameters": []
}
},
{
"id": "900001",
"type": "2",
"meta": {
"position": {
"x": 911.2952705396514,
"y": -331.2250749763467
}
},
"data": {
"nodeMeta": {
"description": "工作流的最终节点,用于返回工作流运行后的结果信息",
"icon": "https://lf3-static.bytednsdoc.com/obj/eden-cn/dvsmryvd_avi_dvsm/ljhwZthlaukjlkulzlp/icon/icon-End-v2.jpg",
"subTitle": "",
"title": "结束"
},
"inputs": {
"terminatePlan": "returnVariables",
"inputParameters": [
{
"name": "output",
"input": {
"value": {
"type": "object_ref"
},
"type": "object",
"schema": [
{
"name": "isSuccess",
"input": {
"type": "boolean",
"value": {
"type": "ref",
"content": {
"source": "block-output",
"blockID": "122336",
"name": "isSuccess"
},
"rawMeta": {
"type": 3
}
}
}
},
{
"name": "isExisted",
"input": {
"type": "boolean",
"value": {
"type": "ref",
"content": {
"source": "block-output",
"blockID": "122336",
"name": "isExisted"
},
"rawMeta": {
"type": 3
}
}
}
},
{
"name": "conversationId",
"input": {
"type": "string",
"value": {
"type": "ref",
"content": {
"source": "block-output",
"blockID": "122336",
"name": "conversationId"
},
"rawMeta": {
"type": 1
}
}
}
}
]
}
}
]
}
}
},
{
"id": "122336",
"type": "51",
"meta": {
"position": {
"x": 343.08704991877585,
"y": -462.38794621339696
}
},
"data": {
"outputs": [
{
"type": "boolean",
"name": "isSuccess"
},
{
"type": "boolean",
"name": "isExisted"
},
{
"type": "string",
"name": "conversationId"
}
],
"nodeMeta": {
"title": "修改会话",
"icon": "https://lf3-static.bytednsdoc.com/obj/eden-cn/dvsmryvd_avi_dvsm/ljhwZthlaukjlkulzlp/icon/icon-编辑会话.jpg",
"description": "用于修改会话的名字",
"mainColor": "#F2B600",
"subTitle": "修改会话"
},
"inputs": {
"inputParameters": [
{
"name": "conversationName",
"input": {
"type": "string",
"value": {
"type": "literal",
"content": "template_v1",
"rawMeta": {
"type": 1
}
}
}
},
{
"name": "newConversationName",
"input": {
"type": "string",
"value": {
"type": "literal",
"content": "new",
"rawMeta": {
"type": 1
}
}
}
}
]
}
}
}
],
"edges": [
{
"sourceNodeID": "100001",
"targetNodeID": "122336"
},
{
"sourceNodeID": "122336",
"targetNodeID": "900001"
}
],
"versions": {
"loop": "v2"
}
}

View File

@ -0,0 +1,262 @@
{
"nodes": [
{
"id": "100001",
"type": "1",
"meta": {
"position": {
"x": 180,
"y": 13.700000000000003
}
},
"data": {
"nodeMeta": {
"description": "工作流的起始节点,用于设定启动工作流需要的信息",
"icon": "https://lf3-static.bytednsdoc.com/obj/eden-cn/dvsmryvd_avi_dvsm/ljhwZthlaukjlkulzlp/icon/icon-Start-v2.jpg",
"subTitle": "",
"title": "开始"
},
"outputs": [
{
"type": "string",
"name": "input",
"required": true
},
{
"type": "string",
"name": "new_name",
"required": true
}
],
"trigger_parameters": []
}
},
{
"id": "900001",
"type": "2",
"meta": {
"position": {
"x": 1560,
"y": 0.7000000000000028
}
},
"data": {
"nodeMeta": {
"description": "工作流的最终节点,用于返回工作流运行后的结果信息",
"icon": "https://lf3-static.bytednsdoc.com/obj/eden-cn/dvsmryvd_avi_dvsm/ljhwZthlaukjlkulzlp/icon/icon-End-v2.jpg",
"subTitle": "",
"title": "结束"
},
"inputs": {
"terminatePlan": "returnVariables",
"inputParameters": [
{
"name": "obj",
"input": {
"value": {
"type": "object_ref"
},
"type": "object",
"schema": [
{
"name": "isSuccess",
"input": {
"type": "boolean",
"value": {
"type": "ref",
"content": {
"source": "block-output",
"blockID": "193175",
"name": "isSuccess"
},
"rawMeta": {
"type": 3
}
}
}
},
{
"name": "isExisted",
"input": {
"type": "boolean",
"value": {
"type": "ref",
"content": {
"source": "block-output",
"blockID": "193175",
"name": "isExisted"
},
"rawMeta": {
"type": 3
}
}
}
},
{
"name": "conversationId",
"input": {
"type": "string",
"value": {
"type": "ref",
"content": {
"source": "block-output",
"blockID": "193175",
"name": "conversationId"
},
"rawMeta": {
"type": 1
}
}
}
}
]
}
}
]
}
}
},
{
"id": "139551",
"type": "39",
"meta": {
"position": {
"x": 627.929589270746,
"y": -36.21123218776195
}
},
"data": {
"outputs": [
{
"type": "boolean",
"name": "isSuccess"
},
{
"type": "boolean",
"name": "isExisted"
},
{
"type": "string",
"name": "conversationId"
}
],
"nodeMeta": {
"title": "创建会话",
"icon": "https://lf3-static.bytednsdoc.com/obj/eden-cn/dvsmryvd_avi_dvsm/ljhwZthlaukjlkulzlp/icon/icon-Conversation-Create.jpeg",
"description": "用于创建会话",
"mainColor": "#F2B600",
"subTitle": "创建会话"
},
"inputs": {
"inputParameters": [
{
"name": "conversationName",
"input": {
"type": "string",
"value": {
"type": "ref",
"content": {
"source": "block-output",
"blockID": "100001",
"name": "input"
},
"rawMeta": {
"type": 1
}
}
}
}
]
}
}
},
{
"id": "193175",
"type": "51",
"meta": {
"position": {
"x": 1100,
"y": 0
}
},
"data": {
"outputs": [
{
"type": "boolean",
"name": "isSuccess"
},
{
"type": "boolean",
"name": "isExisted"
},
{
"type": "string",
"name": "conversationId"
}
],
"nodeMeta": {
"title": "修改会话",
"icon": "https://lf3-static.bytednsdoc.com/obj/eden-cn/dvsmryvd_avi_dvsm/ljhwZthlaukjlkulzlp/icon/icon-编辑会话.jpg",
"description": "用于修改会话的名字",
"mainColor": "#F2B600",
"subTitle": "修改会话"
},
"inputs": {
"inputParameters": [
{
"name": "conversationName",
"input": {
"type": "string",
"value": {
"type": "ref",
"content": {
"source": "block-output",
"blockID": "100001",
"name": "input"
},
"rawMeta": {
"type": 1
}
}
}
},
{
"name": "newConversationName",
"input": {
"type": "string",
"value": {
"type": "ref",
"content": {
"source": "block-output",
"blockID": "100001",
"name": "new_name"
},
"rawMeta": {
"type": 1
}
}
}
}
]
}
}
}
],
"edges": [
{
"sourceNodeID": "100001",
"targetNodeID": "139551"
},
{
"sourceNodeID": "193175",
"targetNodeID": "900001"
},
{
"sourceNodeID": "139551",
"targetNodeID": "193175"
}
],
"versions": {
"loop": "v2"
}
}

View File

@ -0,0 +1,234 @@
{
"nodes": [{
"blocks": [],
"data": {
"nodeMeta": {
"description": "工作流的起始节点,用于设定启动工作流需要的信息",
"icon": "https://lf3-static.bytednsdoc.com/obj/eden-cn/dvsmryvd_avi_dvsm/ljhwZthlaukjlkulzlp/icon/icon-Start-v2.jpg",
"subTitle": "",
"title": "开始"
},
"outputs": [{
"name": "USER_INPUT",
"required": false,
"type": "string"
}, {
"defaultValue": "Default",
"description": "本次请求绑定的会话,会自动写入消息、会从该会话读对话历史。",
"name": "CONVERSATION_NAME",
"required": false,
"type": "string"
}],
"trigger_parameters": []
},
"edges": null,
"id": "100001",
"meta": {
"position": {
"x": 0,
"y": 0
}
},
"type": "1"
}, {
"blocks": [],
"data": {
"inputs": {
"inputParameters": [{
"input": {
"type": "boolean",
"value": {
"content": {
"blockID": "195185",
"name": "isSuccess",
"source": "block-output"
},
"rawMeta": {
"type": 3
},
"type": "ref"
}
},
"name": "output"
}, {
"input": {
"type": "string",
"value": {
"content": {
"blockID": "195185",
"name": "message.messageId",
"source": "block-output"
},
"rawMeta": {
"type": 1
},
"type": "ref"
}
},
"name": "mID"
}],
"terminatePlan": "returnVariables"
},
"nodeMeta": {
"description": "工作流的最终节点,用于返回工作流运行后的结果信息",
"icon": "https://lf3-static.bytednsdoc.com/obj/eden-cn/dvsmryvd_avi_dvsm/ljhwZthlaukjlkulzlp/icon/icon-End-v2.jpg",
"subTitle": "",
"title": "结束"
}
},
"edges": null,
"id": "900001",
"meta": {
"position": {
"x": 1000,
"y": 0
}
},
"type": "2"
}, {
"blocks": [],
"data": {
"inputs": {
"inputParameters": [{
"input": {
"type": "string",
"value": {
"content": {
"blockID": "100001",
"name": "CONVERSATION_NAME",
"source": "block-output"
},
"rawMeta": {
"type": 1
},
"type": "ref"
}
},
"name": "conversationName"
}, {
"input": {
"type": "string",
"value": {
"content": "user",
"type": "literal"
}
},
"name": "role"
}, {
"input": {
"type": "string",
"value": {
"content": "1",
"rawMeta": {
"type": 1
},
"type": "literal"
}
},
"name": "content"
}]
},
"nodeMeta": {
"description": "用于创建消息",
"icon": "https://lf3-static.bytednsdoc.com/obj/eden-cn/dvsmryvd_avi_dvsm/ljhwZthlaukjlkulzlp/icon/icon-创建消息.jpg",
"mainColor": "#F2B600",
"subTitle": "创建消息",
"title": "创建消息"
},
"outputs": [{
"name": "isSuccess",
"type": "boolean"
}, {
"name": "message",
"schema": [{
"name": "messageId",
"type": "string"
}, {
"name": "role",
"type": "string"
}, {
"name": "contentType",
"type": "string"
}, {
"name": "content",
"type": "string"
}],
"type": "object"
}]
},
"edges": null,
"id": "195185",
"meta": {
"position": {
"x": 482,
"y": -13
}
},
"type": "55"
}, {
"blocks": [],
"data": {
"inputs": {
"inputParameters": [{
"input": {
"type": "string",
"value": {
"content": {
"blockID": "100001",
"name": "CONVERSATION_NAME",
"source": "block-output"
},
"rawMeta": {
"type": 1
},
"type": "ref"
}
},
"name": "conversationName"
}]
},
"nodeMeta": {
"description": "用于创建会话",
"icon": "https://lf3-static.bytednsdoc.com/obj/eden-cn/dvsmryvd_avi_dvsm/ljhwZthlaukjlkulzlp/icon/icon-Conversation-Create.jpeg",
"mainColor": "#F2B600",
"subTitle": "创建会话",
"title": "创建会话"
},
"outputs": [{
"name": "isSuccess",
"type": "boolean"
}, {
"name": "isExisted",
"type": "boolean"
}, {
"name": "conversationId",
"type": "string"
}]
},
"edges": null,
"id": "121849",
"meta": {
"position": {
"x": 302,
"y": -236
}
},
"type": "39"
}],
"edges": [{
"sourceNodeID": "100001",
"targetNodeID": "121849",
"sourcePortID": ""
}, {
"sourceNodeID": "195185",
"targetNodeID": "900001",
"sourcePortID": ""
}, {
"sourceNodeID": "121849",
"targetNodeID": "195185",
"sourcePortID": ""
}],
"versions": {
"loop": "v2"
}
}

View File

@ -0,0 +1,310 @@
{
"nodes": [{
"blocks": [],
"data": {
"nodeMeta": {
"description": "工作流的起始节点,用于设定启动工作流需要的信息",
"icon": "https://lf3-static.bytednsdoc.com/obj/eden-cn/dvsmryvd_avi_dvsm/ljhwZthlaukjlkulzlp/icon/icon-Start-v2.jpg",
"subTitle": "",
"title": "开始"
},
"outputs": [{
"name": "USER_INPUT",
"required": false,
"type": "string"
}, {
"defaultValue": "Default",
"description": "本次请求绑定的会话,会自动写入消息、会从该会话读对话历史。",
"name": "CONVERSATION_NAME",
"required": false,
"type": "string"
}],
"trigger_parameters": []
},
"edges": null,
"id": "100001",
"meta": {
"position": {
"x": 0,
"y": 0
}
},
"type": "1"
}, {
"blocks": [],
"data": {
"inputs": {
"inputParameters": [{
"input": {
"schema": {
"schema": [{
"name": "messageId",
"type": "string"
}, {
"name": "role",
"type": "string"
}, {
"name": "contentType",
"type": "string"
}, {
"name": "content",
"type": "string"
}],
"type": "object"
},
"type": "list",
"value": {
"content": {
"blockID": "132703",
"name": "messageList",
"source": "block-output"
},
"rawMeta": {
"type": 103
},
"type": "ref"
}
},
"name": "output"
}],
"terminatePlan": "returnVariables"
},
"nodeMeta": {
"description": "工作流的最终节点,用于返回工作流运行后的结果信息",
"icon": "https://lf3-static.bytednsdoc.com/obj/eden-cn/dvsmryvd_avi_dvsm/ljhwZthlaukjlkulzlp/icon/icon-End-v2.jpg",
"subTitle": "",
"title": "结束"
}
},
"edges": null,
"id": "900001",
"meta": {
"position": {
"x": 1000,
"y": 0
}
},
"type": "2"
}, {
"blocks": [],
"data": {
"inputs": {
"inputParameters": [{
"input": {
"type": "string",
"value": {
"content": {
"blockID": "100001",
"name": "CONVERSATION_NAME",
"source": "block-output"
},
"rawMeta": {
"type": 1
},
"type": "ref"
}
},
"name": "conversationName"
}]
},
"nodeMeta": {
"description": "用于查询消息列表",
"icon": "https://lf3-static.bytednsdoc.com/obj/eden-cn/dvsmryvd_avi_dvsm/ljhwZthlaukjlkulzlp/icon/icon-Conversation-List.jpeg",
"mainColor": "#F2B600",
"subTitle": "查询消息列表",
"title": "查询消息列表"
},
"outputs": [{
"name": "messageList",
"schema": {
"schema": [{
"name": "messageId",
"type": "string"
}, {
"name": "role",
"type": "string"
}, {
"name": "contentType",
"type": "string"
}, {
"name": "content",
"type": "string"
}],
"type": "object"
},
"type": "list"
}, {
"name": "firstId",
"type": "string"
}, {
"name": "lastId",
"type": "string"
}, {
"name": "hasMore",
"type": "boolean"
}]
},
"edges": null,
"id": "132703",
"meta": {
"position": {
"x": 514,
"y": 96
}
},
"type": "37"
}, {
"blocks": [],
"data": {
"inputs": {
"inputParameters": [{
"input": {
"type": "string",
"value": {
"content": {
"blockID": "100001",
"name": "CONVERSATION_NAME",
"source": "block-output"
},
"rawMeta": {
"type": 1
},
"type": "ref"
}
},
"name": "conversationName"
}]
},
"nodeMeta": {
"description": "用于创建会话",
"icon": "https://lf3-static.bytednsdoc.com/obj/eden-cn/dvsmryvd_avi_dvsm/ljhwZthlaukjlkulzlp/icon/icon-Conversation-Create.jpeg",
"mainColor": "#F2B600",
"subTitle": "创建会话",
"title": "创建会话"
},
"outputs": [{
"name": "isSuccess",
"type": "boolean"
}, {
"name": "isExisted",
"type": "boolean"
}, {
"name": "conversationId",
"type": "string"
}]
},
"edges": null,
"id": "166724",
"meta": {
"position": {
"x": 323,
"y": -332
}
},
"type": "39"
}, {
"blocks": [],
"data": {
"inputs": {
"inputParameters": [{
"input": {
"type": "string",
"value": {
"content": {
"blockID": "100001",
"name": "CONVERSATION_NAME",
"source": "block-output"
},
"rawMeta": {
"type": 1
},
"type": "ref"
}
},
"name": "conversationName"
}, {
"input": {
"type": "string",
"value": {
"content": "user",
"type": "literal"
}
},
"name": "role"
}, {
"input": {
"type": "string",
"value": {
"content": {
"blockID": "100001",
"name": "USER_INPUT",
"source": "block-output"
},
"rawMeta": {
"type": 1
},
"type": "ref"
}
},
"name": "content"
}]
},
"nodeMeta": {
"description": "用于创建消息",
"icon": "https://lf3-static.bytednsdoc.com/obj/eden-cn/dvsmryvd_avi_dvsm/ljhwZthlaukjlkulzlp/icon/icon-创建消息.jpg",
"mainColor": "#F2B600",
"subTitle": "创建消息",
"title": "创建消息"
},
"outputs": [{
"name": "isSuccess",
"type": "boolean"
}, {
"name": "message",
"schema": [{
"name": "messageId",
"type": "string"
}, {
"name": "role",
"type": "string"
}, {
"name": "contentType",
"type": "string"
}, {
"name": "content",
"type": "string"
}],
"type": "object"
}]
},
"edges": null,
"id": "157061",
"meta": {
"position": {
"x": 479,
"y": -127
}
},
"type": "55"
}],
"edges": [{
"sourceNodeID": "100001",
"targetNodeID": "166724",
"sourcePortID": ""
}, {
"sourceNodeID": "132703",
"targetNodeID": "900001",
"sourcePortID": ""
}, {
"sourceNodeID": "157061",
"targetNodeID": "132703",
"sourcePortID": ""
}, {
"sourceNodeID": "166724",
"targetNodeID": "157061",
"sourcePortID": ""
}],
"versions": {
"loop": "v2"
}
}

View File

@ -86,6 +86,9 @@ func init() {
_ = compose.RegisterSerializableType[vo.Locator]("wf_locator")
_ = compose.RegisterSerializableType[vo.BizType]("biz_type")
_ = compose.RegisterSerializableType[*execute.AppVariables]("app_variables")
_ = compose.RegisterSerializableType[workflow2.WorkflowMode]("workflow_mode")
_ = compose.RegisterSerializableType[*schema.Message]("schema_message")
}
func (s *State) AddQuestion(nodeKey vo.NodeKey, question *qa.Question) {

View File

@ -0,0 +1,137 @@
/*
* Copyright 2025 coze-dev Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package conversation
import (
"context"
"errors"
"fmt"
wf "github.com/coze-dev/coze-studio/backend/domain/workflow"
"github.com/coze-dev/coze-studio/backend/domain/workflow/crossdomain/conversation"
"github.com/coze-dev/coze-studio/backend/domain/workflow/entity"
"github.com/coze-dev/coze-studio/backend/domain/workflow/entity/vo"
"github.com/coze-dev/coze-studio/backend/domain/workflow/internal/canvas/convert"
"github.com/coze-dev/coze-studio/backend/domain/workflow/internal/execute"
"github.com/coze-dev/coze-studio/backend/domain/workflow/internal/nodes"
"github.com/coze-dev/coze-studio/backend/domain/workflow/internal/schema"
"github.com/coze-dev/coze-studio/backend/pkg/lang/ptr"
"github.com/coze-dev/coze-studio/backend/pkg/lang/ternary"
"github.com/coze-dev/coze-studio/backend/types/errno"
)
type ClearConversationHistoryConfig struct{}
type ClearConversationHistory struct {
Manager conversation.ConversationManager
}
func (c *ClearConversationHistoryConfig) Adapt(_ context.Context, n *vo.Node, _ ...nodes.AdaptOption) (*schema.NodeSchema, error) {
ns := &schema.NodeSchema{
Key: vo.NodeKey(n.ID),
Type: entity.NodeTypeClearConversationHistory,
Name: n.Data.Meta.Title,
Configs: c,
}
if err := convert.SetInputsForNodeSchema(n, ns); err != nil {
return nil, err
}
if err := convert.SetOutputTypesForNodeSchema(n, ns); err != nil {
return nil, err
}
return ns, nil
}
func (c *ClearConversationHistoryConfig) Build(_ context.Context, ns *schema.NodeSchema, _ ...schema.BuildOption) (any, error) {
return &ClearConversationHistory{
Manager: conversation.GetConversationManager(),
}, nil
}
func (c *ClearConversationHistory) Invoke(ctx context.Context, in map[string]any) (map[string]any, error) {
var (
execCtx = execute.GetExeCtx(ctx)
env = ternary.IFElse(execCtx.ExeCfg.Mode == vo.ExecuteModeRelease, vo.Online, vo.Draft)
appID = execCtx.ExeCfg.AppID
agentID = execCtx.ExeCfg.AgentID
connectorID = execCtx.ExeCfg.ConnectorID
userID = execCtx.ExeCfg.Operator
version = execCtx.ExeCfg.Version
)
if agentID != nil {
return nil, vo.WrapError(errno.ErrConversationNodesNotAvailable, fmt.Errorf("in the agent scenario, query conversation list is not available"))
}
if appID == nil {
return nil, vo.WrapError(errno.ErrConversationNodesNotAvailable, fmt.Errorf("query conversation list node, app id is required"))
}
conversationName, ok := in["conversationName"].(string)
if !ok {
return nil, vo.WrapError(errno.ErrInvalidParameter, errors.New("conversation name is required"))
}
t, existed, err := wf.GetRepository().GetConversationTemplate(ctx, env, vo.GetConversationTemplatePolicy{
AppID: appID,
Name: ptr.Of(conversationName),
Version: ptr.Of(version),
})
if err != nil {
return nil, vo.WrapError(errno.ErrConversationNodesNotAvailable, err)
}
var conversationID int64
if existed {
ret, existed, err := wf.GetRepository().GetStaticConversationByTemplateID(ctx, env, userID, connectorID, t.TemplateID)
if err != nil {
return nil, vo.WrapError(errno.ErrConversationNodesNotAvailable, err)
}
if existed {
conversationID = ret.ConversationID
}
} else {
ret, existed, err := wf.GetRepository().GetDynamicConversationByName(ctx, env, *appID, connectorID, userID, conversationName)
if err != nil {
return nil, vo.WrapError(errno.ErrConversationNodesNotAvailable, err)
}
if existed {
conversationID = ret.ConversationID
}
}
if !existed {
return map[string]any{
"isSuccess": false,
}, nil
}
sectionID, err := c.Manager.ClearConversationHistory(ctx, &conversation.ClearConversationHistoryReq{
ConversationID: conversationID,
})
if err != nil {
return nil, vo.WrapError(errno.ErrConversationNodesNotAvailable, err)
}
execCtx.ExeCfg.SectionID = ptr.Of(sectionID)
return map[string]any{
"isSuccess": true,
}, nil
}

View File

@ -0,0 +1,151 @@
/*
* Copyright 2025 coze-dev Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package conversation
import (
"context"
"errors"
"fmt"
"strings"
"github.com/cloudwego/eino/schema"
"github.com/coze-dev/coze-studio/backend/api/model/crossdomain/message"
"github.com/coze-dev/coze-studio/backend/domain/workflow"
"github.com/coze-dev/coze-studio/backend/domain/workflow/crossdomain/conversation"
"github.com/coze-dev/coze-studio/backend/domain/workflow/entity/vo"
"github.com/coze-dev/coze-studio/backend/pkg/lang/ptr"
"github.com/coze-dev/coze-studio/backend/pkg/logs"
"github.com/coze-dev/coze-studio/backend/types/errno"
)
func ConvertMessageToString(ctx context.Context, msg *conversation.Message) (string, error) {
if msg.MultiContent != nil {
var textContents []string
var otherContents []string
for _, m := range msg.MultiContent {
if m.Text != nil {
textContents = append(textContents, ptr.From(m.Text))
} else if m.Uri != nil {
url, err := workflow.GetRepository().GetObjectUrl(ctx, ptr.From(m.Uri))
if err != nil {
return "", err
}
otherContents = append(otherContents, url)
}
}
var allParts []string
if len(textContents) > 0 {
allParts = append(allParts, textContents...)
}
if len(otherContents) > 0 {
allParts = append(allParts, otherContents...)
}
return strings.Join(allParts, ","), nil
} else if msg.Text != nil {
return ptr.From(msg.Text), nil
} else {
return "", vo.WrapError(errno.ErrInvalidParameter, errors.New("message is invalid"))
}
}
func ConvertMessageToSchema(ctx context.Context, msg *conversation.Message) (*schema.Message, error) {
schemaMsg := &schema.Message{}
switch msg.Role {
case schema.User:
schemaMsg.Role = schema.User
case schema.Assistant:
schemaMsg.Role = schema.Assistant
default:
return nil, fmt.Errorf("unknown role: %s", string(msg.Role))
}
if msg.Text != nil {
schemaMsg.Content = *msg.Text
return schemaMsg, nil
}
if len(msg.MultiContent) > 0 {
multiContent := make([]schema.ChatMessagePart, 0, len(msg.MultiContent))
for _, part := range msg.MultiContent {
schemaPart, err := convertContentPart(ctx, part)
if err != nil {
logs.CtxErrorf(ctx, "failed to convert content part, err: %v", err)
continue
}
multiContent = append(multiContent, schemaPart)
}
schemaMsg.MultiContent = multiContent
return schemaMsg, nil
}
return nil, fmt.Errorf("message has no content")
}
func convertContentPart(ctx context.Context, part *conversation.Content) (schema.ChatMessagePart, error) {
schemaPart := schema.ChatMessagePart{}
uri := ""
if part.Uri != nil {
uri = *part.Uri
}
switch part.Type {
case message.InputTypeText:
schemaPart.Type = schema.ChatMessagePartTypeText
if part.Text == nil || *part.Text == "" {
return schema.ChatMessagePart{}, fmt.Errorf("text is empty for text content part type")
}
schemaPart.Text = *part.Text
case message.InputTypeImage:
schemaPart.Type = schema.ChatMessagePartTypeImageURL
url, err := workflow.GetRepository().GetObjectUrl(ctx, uri)
if err != nil {
return schema.ChatMessagePart{}, fmt.Errorf("failed to get object url: %w", err)
}
schemaPart.ImageURL = &schema.ChatMessageImageURL{URL: url}
case message.InputTypeAudio:
schemaPart.Type = schema.ChatMessagePartTypeAudioURL
url, err := workflow.GetRepository().GetObjectUrl(ctx, uri)
if err != nil {
return schema.ChatMessagePart{}, fmt.Errorf("failed to get object url: %w", err)
}
schemaPart.AudioURL = &schema.ChatMessageAudioURL{URL: url}
case message.InputTypeVideo:
schemaPart.Type = schema.ChatMessagePartTypeVideoURL
url, err := workflow.GetRepository().GetObjectUrl(ctx, uri)
if err != nil {
return schema.ChatMessagePart{}, fmt.Errorf("failed to get object url: %w", err)
}
schemaPart.VideoURL = &schema.ChatMessageVideoURL{URL: url}
case message.InputTypeFile:
schemaPart.Type = schema.ChatMessagePartTypeFileURL
url, err := workflow.GetRepository().GetObjectUrl(ctx, uri)
if err != nil {
return schema.ChatMessagePart{}, fmt.Errorf("failed to get object url: %w", err)
}
schemaPart.FileURL = &schema.ChatMessageFileURL{URL: url}
default:
return schema.ChatMessagePart{}, fmt.Errorf("unknown content part type: %s", part.Type)
}
if schemaPart.Type != schema.ChatMessagePartTypeText && uri == "" {
return schema.ChatMessagePart{}, fmt.Errorf("uri is empty for non-text content part type %s", part.Type)
}
return schemaPart, nil
}

View File

@ -0,0 +1,151 @@
/*
* Copyright 2025 coze-dev Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package conversation
import (
"context"
"fmt"
"strconv"
"github.com/coze-dev/coze-studio/backend/domain/workflow"
"github.com/coze-dev/coze-studio/backend/domain/workflow/entity"
"github.com/coze-dev/coze-studio/backend/domain/workflow/entity/vo"
"github.com/coze-dev/coze-studio/backend/domain/workflow/internal/canvas/convert"
"github.com/coze-dev/coze-studio/backend/domain/workflow/internal/execute"
"github.com/coze-dev/coze-studio/backend/domain/workflow/internal/nodes"
"github.com/coze-dev/coze-studio/backend/domain/workflow/internal/schema"
"github.com/coze-dev/coze-studio/backend/pkg/lang/ptr"
"github.com/coze-dev/coze-studio/backend/pkg/lang/slices"
"github.com/coze-dev/coze-studio/backend/pkg/lang/ternary"
"github.com/coze-dev/coze-studio/backend/types/errno"
)
type ConversationList struct{}
type ConversationListConfig struct{}
func (c *ConversationListConfig) Adapt(_ context.Context, n *vo.Node, _ ...nodes.AdaptOption) (*schema.NodeSchema, error) {
ns := &schema.NodeSchema{
Key: vo.NodeKey(n.ID),
Type: entity.NodeTypeConversationList,
Name: n.Data.Meta.Title,
Configs: c,
}
if err := convert.SetInputsForNodeSchema(n, ns); err != nil {
return nil, err
}
if err := convert.SetOutputTypesForNodeSchema(n, ns); err != nil {
return nil, err
}
return ns, nil
}
func (c *ConversationListConfig) Build(_ context.Context, ns *schema.NodeSchema, _ ...schema.BuildOption) (any, error) {
return &ConversationList{}, nil
}
type conversationInfo struct {
conversationName string
conversationId string
}
func (c *ConversationList) Invoke(ctx context.Context, _ map[string]any) (map[string]any, error) {
var (
execCtx = execute.GetExeCtx(ctx)
env = ternary.IFElse(execCtx.ExeCfg.Mode == vo.ExecuteModeRelease, vo.Online, vo.Draft)
appID = execCtx.ExeCfg.AppID
agentID = execCtx.ExeCfg.AgentID
connectorID = execCtx.ExeCfg.ConnectorID
userID = execCtx.ExeCfg.Operator
version = execCtx.ExeCfg.Version
)
if agentID != nil {
return nil, vo.WrapError(errno.ErrConversationNodesNotAvailable, fmt.Errorf("in the agent scenario, query conversation list is not available"))
}
if appID == nil {
return nil, vo.WrapError(errno.ErrConversationNodesNotAvailable, fmt.Errorf("query conversation list node, app id is required"))
}
templates, err := workflow.GetRepository().ListConversationTemplate(ctx, env, &vo.ListConversationTemplatePolicy{
AppID: *appID,
Version: ptr.Of(version),
})
if err != nil {
return nil, err
}
templateIds := make([]int64, 0, len(templates))
for _, template := range templates {
templateIds = append(templateIds, template.TemplateID)
}
staticConversations, err := workflow.GetRepository().MGetStaticConversation(ctx, env, userID, connectorID, templateIds)
if err != nil {
return nil, err
}
templateIDToConvID := slices.ToMap(staticConversations, func(conv *entity.StaticConversation) (int64, int64) {
return conv.TemplateID, conv.ConversationID
})
var conversationList []conversationInfo
for _, template := range templates {
convID, ok := templateIDToConvID[template.TemplateID]
if !ok {
convID = 0
}
conversationList = append(conversationList, conversationInfo{
conversationName: template.Name,
conversationId: strconv.FormatInt(convID, 10),
})
}
dynamicConversations, err := workflow.GetRepository().ListDynamicConversation(ctx, env, &vo.ListConversationPolicy{
ListConversationMeta: vo.ListConversationMeta{
APPID: *appID,
UserID: userID,
ConnectorID: connectorID,
},
})
if err != nil {
return nil, err
}
for _, conv := range dynamicConversations {
conversationList = append(conversationList, conversationInfo{
conversationName: conv.Name,
conversationId: strconv.FormatInt(conv.ConversationID, 10),
})
}
resultList := make([]any, len(conversationList))
for i, v := range conversationList {
resultList[i] = map[string]any{
"conversationName": v.conversationName,
"conversationId": v.conversationId,
}
}
return map[string]any{
"conversationList": resultList,
}, nil
}

View File

@ -0,0 +1,184 @@
/*
* Copyright 2025 coze-dev Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package conversation
import (
"context"
"errors"
"fmt"
"github.com/coze-dev/coze-studio/backend/api/model/workflow"
wf "github.com/coze-dev/coze-studio/backend/domain/workflow"
"github.com/coze-dev/coze-studio/backend/domain/workflow/crossdomain/conversation"
"github.com/coze-dev/coze-studio/backend/domain/workflow/entity"
"github.com/coze-dev/coze-studio/backend/domain/workflow/entity/vo"
"github.com/coze-dev/coze-studio/backend/domain/workflow/internal/canvas/convert"
"github.com/coze-dev/coze-studio/backend/domain/workflow/internal/execute"
"github.com/coze-dev/coze-studio/backend/domain/workflow/internal/nodes"
"github.com/coze-dev/coze-studio/backend/domain/workflow/internal/schema"
"github.com/coze-dev/coze-studio/backend/pkg/lang/ptr"
"github.com/coze-dev/coze-studio/backend/pkg/lang/ternary"
"github.com/coze-dev/coze-studio/backend/types/errno"
)
type ConversationHistoryConfig struct{}
type ConversationHistory struct {
Manager conversation.ConversationManager
}
func (ch *ConversationHistoryConfig) Adapt(_ context.Context, n *vo.Node, _ ...nodes.AdaptOption) (*schema.NodeSchema, error) {
ns := &schema.NodeSchema{
Key: vo.NodeKey(n.ID),
Type: entity.NodeTypeConversationHistory,
Name: n.Data.Meta.Title,
Configs: ch,
}
if err := convert.SetInputsForNodeSchema(n, ns); err != nil {
return nil, err
}
if err := convert.SetOutputTypesForNodeSchema(n, ns); err != nil {
return nil, err
}
return ns, nil
}
func (ch *ConversationHistoryConfig) Build(_ context.Context, ns *schema.NodeSchema, _ ...schema.BuildOption) (any, error) {
return &ConversationHistory{
Manager: conversation.GetConversationManager(),
}, nil
}
func (ch *ConversationHistory) Invoke(ctx context.Context, input map[string]any) (map[string]any, error) {
var (
execCtx = execute.GetExeCtx(ctx)
env = ternary.IFElse(execCtx.ExeCfg.Mode == vo.ExecuteModeRelease, vo.Online, vo.Draft)
appID = execCtx.ExeCfg.AppID
agentID = execCtx.ExeCfg.AgentID
connectorID = execCtx.ExeCfg.ConnectorID
userID = execCtx.ExeCfg.Operator
version = execCtx.ExeCfg.Version
)
if agentID != nil {
return nil, vo.WrapError(errno.ErrConversationNodesNotAvailable, fmt.Errorf("in the agent scenario, query conversation list is not available"))
}
if appID == nil {
return nil, vo.WrapError(errno.ErrConversationNodesNotAvailable, fmt.Errorf("query conversation list node, app id is required"))
}
conversationName, ok := input["conversationName"].(string)
if !ok {
return nil, vo.WrapError(errno.ErrInvalidParameter, errors.New("conversation name is required"))
}
rounds, ok := input["rounds"].(int64)
if !ok {
return nil, vo.WrapError(errno.ErrInvalidParameter, errors.New("rounds is required"))
}
template, existed, err := wf.GetRepository().GetConversationTemplate(ctx, env, vo.GetConversationTemplatePolicy{
AppID: appID,
Name: ptr.Of(conversationName),
Version: ptr.Of(version),
})
if err != nil {
return nil, vo.WrapError(errno.ErrConversationNodesNotAvailable, err)
}
var conversationID int64
if existed {
sts, existed, err := wf.GetRepository().GetStaticConversationByTemplateID(ctx, env, userID, connectorID, template.TemplateID)
if err != nil {
return nil, vo.WrapError(errno.ErrConversationNodesNotAvailable, err)
}
if existed {
conversationID = sts.ConversationID
}
} else {
dyConversation, existed, err := wf.GetRepository().GetDynamicConversationByName(ctx, env, *appID, connectorID, userID, conversationName)
if err != nil {
return nil, vo.WrapError(errno.ErrConversationNodesNotAvailable, err)
}
if existed {
conversationID = dyConversation.ConversationID
}
}
if !existed {
return nil, vo.WrapError(errno.ErrConversationOfAppNotFound, fmt.Errorf("the conversation name does not exist: '%v'", conversationName))
}
isChatFlow := execCtx.ExeCfg.WorkflowMode == workflow.WorkflowMode_ChatFlow
if isChatFlow {
rounds += 1
}
runIDs, err := ch.Manager.GetLatestRunIDs(ctx, &conversation.GetLatestRunIDsRequest{
ConversationID: conversationID,
UserID: userID,
AppID: *appID,
Rounds: rounds,
})
if err != nil {
return nil, vo.WrapError(errno.ErrConversationNodesNotAvailable, err)
}
var messageList []any
if len(runIDs) == 0 {
return map[string]any{
"messageList": messageList,
}, nil
}
if isChatFlow {
if len(runIDs) == 1 {
return map[string]any{
"messageList": messageList,
}, nil
}
runIDs = runIDs[1:] // chatflow needs to filter out this session
}
response, err := ch.Manager.GetMessagesByRunIDs(ctx, &conversation.GetMessagesByRunIDsRequest{
ConversationID: conversationID,
RunIDs: runIDs,
})
if err != nil {
return nil, vo.WrapError(errno.ErrConversationNodesNotAvailable, err)
}
for _, msg := range response.Messages {
content, err := ConvertMessageToString(ctx, msg)
if err != nil {
return nil, vo.WrapError(errno.ErrConversationNodesNotAvailable, err)
}
messageList = append(messageList, map[string]any{
"role": string(msg.Role),
"content": content,
})
}
return map[string]any{
"messageList": messageList,
}, nil
}

View File

@ -0,0 +1,141 @@
/*
* Copyright 2025 coze-dev Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package conversation
import (
"context"
"errors"
"fmt"
"github.com/coze-dev/coze-studio/backend/domain/workflow"
"github.com/coze-dev/coze-studio/backend/domain/workflow/crossdomain/conversation"
"github.com/coze-dev/coze-studio/backend/domain/workflow/entity"
"github.com/coze-dev/coze-studio/backend/domain/workflow/entity/vo"
"github.com/coze-dev/coze-studio/backend/domain/workflow/internal/canvas/convert"
"github.com/coze-dev/coze-studio/backend/domain/workflow/internal/execute"
"github.com/coze-dev/coze-studio/backend/domain/workflow/internal/nodes"
"github.com/coze-dev/coze-studio/backend/domain/workflow/internal/schema"
"github.com/coze-dev/coze-studio/backend/pkg/lang/ptr"
"github.com/coze-dev/coze-studio/backend/pkg/lang/ternary"
"github.com/coze-dev/coze-studio/backend/types/errno"
)
type CreateConversationConfig struct{}
type CreateConversation struct {
Manager conversation.ConversationManager
}
func (c *CreateConversationConfig) Adapt(_ context.Context, n *vo.Node, _ ...nodes.AdaptOption) (*schema.NodeSchema, error) {
ns := &schema.NodeSchema{
Key: vo.NodeKey(n.ID),
Type: entity.NodeTypeCreateConversation,
Name: n.Data.Meta.Title,
Configs: c,
}
if err := convert.SetInputsForNodeSchema(n, ns); err != nil {
return nil, err
}
if err := convert.SetOutputTypesForNodeSchema(n, ns); err != nil {
return nil, err
}
return ns, nil
}
func (c *CreateConversationConfig) Build(_ context.Context, ns *schema.NodeSchema, _ ...schema.BuildOption) (any, error) {
return &CreateConversation{
Manager: conversation.GetConversationManager(),
}, nil
}
func (c *CreateConversation) Invoke(ctx context.Context, input map[string]any) (map[string]any, error) {
var (
execCtx = execute.GetExeCtx(ctx)
env = ternary.IFElse(execCtx.ExeCfg.Mode == vo.ExecuteModeRelease, vo.Online, vo.Draft)
appID = execCtx.ExeCfg.AppID
agentID = execCtx.ExeCfg.AgentID
version = execCtx.ExeCfg.Version
connectorID = execCtx.ExeCfg.ConnectorID
userID = execCtx.ExeCfg.Operator
conversationIDGenerator = workflow.ConversationIDGenerator(func(ctx context.Context, appID int64, userID, connectorID int64) (int64, int64, error) {
return c.Manager.CreateConversation(ctx, &conversation.CreateConversationRequest{
AppID: appID,
UserID: userID,
ConnectorID: connectorID,
})
})
)
if agentID != nil {
return nil, vo.WrapError(errno.ErrConversationNodesNotAvailable, fmt.Errorf("in the agent scenario, create conversation is not available"))
}
if appID == nil {
return nil, vo.WrapError(errno.ErrConversationNodesNotAvailable, errors.New("create conversation node, app id is required"))
}
conversationName, ok := input["conversationName"].(string)
if !ok {
return nil, vo.WrapError(errno.ErrInvalidParameter, errors.New("conversation name is required"))
}
template, existed, err := workflow.GetRepository().GetConversationTemplate(ctx, env, vo.GetConversationTemplatePolicy{
AppID: appID,
Name: ptr.Of(conversationName),
Version: ptr.Of(version),
})
if err != nil {
return nil, err
}
if existed {
cID, _, existed, err := workflow.GetRepository().GetOrCreateStaticConversation(ctx, env, conversationIDGenerator, &vo.CreateStaticConversation{
AppID: ptr.From(appID),
TemplateID: template.TemplateID,
UserID: userID,
ConnectorID: connectorID,
})
if err != nil {
return nil, err
}
return map[string]any{
"isSuccess": true,
"conversationId": cID,
"isExisted": existed,
}, nil
}
cID, _, existed, err := workflow.GetRepository().GetOrCreateDynamicConversation(ctx, env, conversationIDGenerator, &vo.CreateDynamicConversation{
AppID: ptr.From(appID),
UserID: userID,
ConnectorID: connectorID,
Name: conversationName,
})
if err != nil {
return nil, err
}
return map[string]any{
"isSuccess": true,
"conversationId": cID,
"isExisted": existed,
}, nil
}

View File

@ -0,0 +1,272 @@
/*
* Copyright 2025 coze-dev Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package conversation
import (
"context"
"errors"
"fmt"
"sync/atomic"
"github.com/coze-dev/coze-studio/backend/domain/workflow"
"github.com/coze-dev/coze-studio/backend/domain/workflow/crossdomain/conversation"
"github.com/coze-dev/coze-studio/backend/domain/workflow/entity"
"github.com/coze-dev/coze-studio/backend/domain/workflow/entity/vo"
"github.com/coze-dev/coze-studio/backend/domain/workflow/internal/canvas/convert"
"github.com/coze-dev/coze-studio/backend/domain/workflow/internal/execute"
"github.com/coze-dev/coze-studio/backend/domain/workflow/internal/nodes"
"github.com/coze-dev/coze-studio/backend/domain/workflow/internal/schema"
"github.com/coze-dev/coze-studio/backend/pkg/lang/ptr"
"github.com/coze-dev/coze-studio/backend/pkg/lang/ternary"
"github.com/coze-dev/coze-studio/backend/types/errno"
)
type CreateMessageConfig struct{}
type CreateMessage struct {
Creator conversation.ConversationManager
}
func (c *CreateMessageConfig) Adapt(_ context.Context, n *vo.Node, _ ...nodes.AdaptOption) (*schema.NodeSchema, error) {
ns := &schema.NodeSchema{
Key: vo.NodeKey(n.ID),
Type: entity.NodeTypeCreateMessage,
Name: n.Data.Meta.Title,
Configs: c,
}
if err := convert.SetInputsForNodeSchema(n, ns); err != nil {
return nil, err
}
if err := convert.SetOutputTypesForNodeSchema(n, ns); err != nil {
return nil, err
}
return ns, nil
}
func (c *CreateMessageConfig) Build(_ context.Context, ns *schema.NodeSchema, _ ...schema.BuildOption) (any, error) {
return &CreateMessage{
Creator: conversation.GetConversationManager(),
}, nil
}
func (c *CreateMessage) getConversationIDByName(ctx context.Context, env vo.Env, appID *int64, version, conversationName string, userID, connectorID int64) (int64, error) {
template, isExist, err := workflow.GetRepository().GetConversationTemplate(ctx, env, vo.GetConversationTemplatePolicy{
AppID: appID,
Name: ptr.Of(conversationName),
Version: ptr.Of(version),
})
if err != nil {
return 0, vo.WrapError(errno.ErrConversationNodeInvalidOperation, err)
}
conversationIDGenerator := workflow.ConversationIDGenerator(func(ctx context.Context, appID int64, userID, connectorID int64) (int64, int64, error) {
return c.Creator.CreateConversation(ctx, &conversation.CreateConversationRequest{
AppID: appID,
UserID: userID,
ConnectorID: connectorID,
})
})
var conversationID int64
if isExist {
cID, _, _, err := workflow.GetRepository().GetOrCreateStaticConversation(ctx, env, conversationIDGenerator, &vo.CreateStaticConversation{
AppID: ptr.From(appID),
TemplateID: template.TemplateID,
UserID: userID,
ConnectorID: connectorID,
})
if err != nil {
return 0, err
}
conversationID = cID
} else {
dc, _, err := workflow.GetRepository().GetDynamicConversationByName(ctx, env, *appID, connectorID, userID, conversationName)
if err != nil {
return 0, err
}
if dc != nil {
conversationID = dc.ConversationID
}
}
return conversationID, nil
}
func (c *CreateMessage) Invoke(ctx context.Context, input map[string]any) (map[string]any, error) {
var (
execCtx = execute.GetExeCtx(ctx)
env = ternary.IFElse(execCtx.ExeCfg.Mode == vo.ExecuteModeRelease, vo.Online, vo.Draft)
appID = execCtx.ExeCfg.AppID
agentID = execCtx.ExeCfg.AgentID
version = execCtx.ExeCfg.Version
connectorID = execCtx.ExeCfg.ConnectorID
userID = execCtx.ExeCfg.Operator
)
conversationName, ok := input["conversationName"].(string)
if !ok {
return nil, vo.WrapError(errno.ErrInvalidParameter, errors.New("conversationName is required"))
}
role, ok := input["role"].(string)
if !ok {
return nil, vo.WrapError(errno.ErrInvalidParameter, errors.New("role is required"))
}
if role != "user" && role != "assistant" {
return nil, vo.WrapError(errno.ErrInvalidParameter, fmt.Errorf("role must be user or assistant"))
}
content, ok := input["content"].(string)
if !ok {
return nil, vo.WrapError(errno.ErrConversationNodeInvalidOperation, errors.New("content is required"))
}
var conversationID int64
var err error
var resolvedAppID int64
if appID == nil {
if conversationName != "Default" {
return nil, vo.WrapError(errno.ErrOnlyDefaultConversationAllowInAgentScenario, errors.New("conversation node only allow in application"))
}
if agentID == nil || execCtx.ExeCfg.ConversationID == nil {
return map[string]any{
"isSuccess": false,
"message": map[string]any{
"messageId": "0",
"role": role,
"contentType": "text",
"content": content,
},
}, nil
}
conversationID = *execCtx.ExeCfg.ConversationID
resolvedAppID = *agentID
} else {
conversationID, err = c.getConversationIDByName(ctx, env, appID, version, conversationName, userID, connectorID)
if err != nil {
return nil, err
}
resolvedAppID = *appID
}
if conversationID == 0 {
return map[string]any{
"isSuccess": false,
"message": map[string]any{
"messageId": "0",
"role": role,
"contentType": "text",
"content": content,
},
}, nil
}
currentConversationID := execCtx.ExeCfg.ConversationID
isCurrentConversation := currentConversationID != nil && *currentConversationID == conversationID
var runID int64
if role == "user" {
// For user messages, always create a new run and store the ID in the context.
newRunID, err := workflow.GetRepository().GenID(ctx)
if err != nil {
return nil, err
}
if execCtx.ExeCfg.RoundID != nil {
atomic.StoreInt64(execCtx.ExeCfg.RoundID, newRunID)
}
runID = newRunID
} else if isCurrentConversation {
// For assistant messages in the same conversation, reuse the runID from the context.
if execCtx.ExeCfg.RoundID == nil {
// This indicates an inconsistent state, as a user message should have set this.
return map[string]any{
"isSuccess": false,
"message": map[string]any{
"messageId": "0",
"role": role,
"contentType": "text",
"content": content,
},
}, nil
}
runID = *execCtx.ExeCfg.RoundID
} else {
// For assistant messages in a different conversation or a new workflow run,
// find the latest runID or create a new one as a fallback.
runIDs, err := c.Creator.GetLatestRunIDs(ctx, &conversation.GetLatestRunIDsRequest{
ConversationID: conversationID,
UserID: userID,
AppID: resolvedAppID,
Rounds: 1,
})
if err != nil {
return nil, err
}
if len(runIDs) > 0 && runIDs[0] != 0 {
runID = runIDs[0]
} else {
newRunID, err := workflow.GetRepository().GenID(ctx)
if err != nil {
return nil, err
}
runID = newRunID
}
}
var sectionID int64
if isCurrentConversation {
if execCtx.ExeCfg.SectionID != nil {
sectionID = *execCtx.ExeCfg.SectionID
} else {
return nil, vo.WrapError(errno.ErrInvalidParameter, errors.New("section id is required"))
}
} else {
cInfo, err := c.Creator.GetByID(ctx, conversationID)
if err != nil {
return nil, err
}
sectionID = cInfo.SectionID
}
mID, err := c.Creator.CreateMessage(ctx, &conversation.CreateMessageRequest{
ConversationID: conversationID,
Role: role,
Content: content,
ContentType: "text",
UserID: userID,
AppID: resolvedAppID,
RunID: runID,
SectionID: sectionID,
})
if err != nil {
return nil, fmt.Errorf("failed to create message: %w", err)
}
messageOutput := map[string]any{
"messageId": mID,
"role": role,
"contentType": "text",
"content": content,
}
return map[string]any{
"isSuccess": true,
"message": messageOutput,
}, nil
}

View File

@ -0,0 +1,120 @@
/*
* Copyright 2025 coze-dev Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package conversation
import (
"context"
"errors"
"fmt"
"github.com/coze-dev/coze-studio/backend/domain/workflow"
"github.com/coze-dev/coze-studio/backend/domain/workflow/entity"
"github.com/coze-dev/coze-studio/backend/domain/workflow/entity/vo"
"github.com/coze-dev/coze-studio/backend/domain/workflow/internal/canvas/convert"
"github.com/coze-dev/coze-studio/backend/domain/workflow/internal/execute"
"github.com/coze-dev/coze-studio/backend/domain/workflow/internal/nodes"
"github.com/coze-dev/coze-studio/backend/domain/workflow/internal/schema"
"github.com/coze-dev/coze-studio/backend/pkg/lang/ptr"
"github.com/coze-dev/coze-studio/backend/pkg/lang/ternary"
"github.com/coze-dev/coze-studio/backend/types/errno"
)
type DeleteConversationConfig struct{}
type DeleteConversation struct{}
func (d *DeleteConversationConfig) Adapt(_ context.Context, n *vo.Node, _ ...nodes.AdaptOption) (*schema.NodeSchema, error) {
ns := &schema.NodeSchema{
Key: vo.NodeKey(n.ID),
Type: entity.NodeTypeConversationDelete,
Name: n.Data.Meta.Title,
Configs: d,
}
if err := convert.SetInputsForNodeSchema(n, ns); err != nil {
return nil, err
}
if err := convert.SetOutputTypesForNodeSchema(n, ns); err != nil {
return nil, err
}
return ns, nil
}
func (d *DeleteConversationConfig) Build(_ context.Context, ns *schema.NodeSchema, _ ...schema.BuildOption) (any, error) {
return &DeleteConversation{}, nil
}
func (d *DeleteConversation) Invoke(ctx context.Context, in map[string]any) (map[string]any, error) {
var (
execCtx = execute.GetExeCtx(ctx)
env = ternary.IFElse(execCtx.ExeCfg.Mode == vo.ExecuteModeRelease, vo.Online, vo.Draft)
appID = execCtx.ExeCfg.AppID
agentID = execCtx.ExeCfg.AgentID
version = execCtx.ExeCfg.Version
connectorID = execCtx.ExeCfg.ConnectorID
userID = execCtx.ExeCfg.Operator
)
if agentID != nil {
return nil, vo.WrapError(errno.ErrConversationNodesNotAvailable, fmt.Errorf("in the agent scenario, delete conversation is not available"))
}
if appID == nil {
return nil, vo.WrapError(errno.ErrConversationNodesNotAvailable, errors.New("delete conversation node, app id is required"))
}
cName, ok := in["conversationName"]
if !ok {
return nil, vo.WrapError(errno.ErrInvalidParameter, errors.New("conversation name is required"))
}
conversationName := cName.(string)
_, existed, err := workflow.GetRepository().GetConversationTemplate(ctx, env, vo.GetConversationTemplatePolicy{
AppID: appID,
Name: ptr.Of(conversationName),
Version: ptr.Of(version),
})
if err != nil {
return nil, err
}
if existed {
return nil, vo.WrapError(errno.ErrConversationNodeInvalidOperation, fmt.Errorf("only conversation created through nodes are allowed to be modified or deleted"))
}
dyConversation, existed, err := workflow.GetRepository().GetDynamicConversationByName(ctx, env, *appID, connectorID, userID, conversationName)
if err != nil {
return nil, err
}
if !existed {
return nil, vo.WrapError(errno.ErrConversationOfAppNotFound, fmt.Errorf("the conversation name does not exist: '%v'", conversationName))
}
_, err = workflow.GetRepository().DeleteDynamicConversation(ctx, env, dyConversation.ID)
if err != nil {
return nil, err
}
return map[string]any{
"isSuccess": true,
}, nil
}

View File

@ -0,0 +1,162 @@
/*
* Copyright 2025 coze-dev Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package conversation
import (
"context"
"errors"
"fmt"
"strconv"
wf "github.com/coze-dev/coze-studio/backend/domain/workflow"
"github.com/coze-dev/coze-studio/backend/domain/workflow/crossdomain/conversation"
"github.com/coze-dev/coze-studio/backend/domain/workflow/entity"
"github.com/coze-dev/coze-studio/backend/domain/workflow/entity/vo"
"github.com/coze-dev/coze-studio/backend/domain/workflow/internal/canvas/convert"
"github.com/coze-dev/coze-studio/backend/domain/workflow/internal/execute"
"github.com/coze-dev/coze-studio/backend/domain/workflow/internal/nodes"
"github.com/coze-dev/coze-studio/backend/domain/workflow/internal/schema"
"github.com/coze-dev/coze-studio/backend/pkg/lang/ptr"
"github.com/coze-dev/coze-studio/backend/pkg/lang/ternary"
"github.com/coze-dev/coze-studio/backend/types/errno"
)
type DeleteMessageConfig struct{}
type DeleteMessage struct {
Manager conversation.ConversationManager
}
func (d *DeleteMessageConfig) Adapt(_ context.Context, n *vo.Node, _ ...nodes.AdaptOption) (*schema.NodeSchema, error) {
ns := &schema.NodeSchema{
Key: vo.NodeKey(n.ID),
Type: entity.NodeTypeDeleteMessage,
Name: n.Data.Meta.Title,
Configs: d,
}
if err := convert.SetInputsForNodeSchema(n, ns); err != nil {
return nil, err
}
if err := convert.SetOutputTypesForNodeSchema(n, ns); err != nil {
return nil, err
}
return ns, nil
}
func (d *DeleteMessageConfig) Build(_ context.Context, ns *schema.NodeSchema, _ ...schema.BuildOption) (any, error) {
return &DeleteMessage{
Manager: conversation.GetConversationManager(),
}, nil
}
func (d *DeleteMessage) Invoke(ctx context.Context, input map[string]any) (map[string]any, error) {
var (
execCtx = execute.GetExeCtx(ctx)
env = ternary.IFElse(execCtx.ExeCfg.Mode == vo.ExecuteModeRelease, vo.Online, vo.Draft)
appID = execCtx.ExeCfg.AppID
agentID = execCtx.ExeCfg.AgentID
version = execCtx.ExeCfg.Version
connectorID = execCtx.ExeCfg.ConnectorID
userID = execCtx.ExeCfg.Operator
successMap = map[string]any{
"isSuccess": true,
}
failedMap = map[string]any{
"isSuccess": false,
}
)
conversationName, ok := input["conversationName"].(string)
if !ok {
return nil, vo.WrapError(errno.ErrInvalidParameter, errors.New("conversationName is required"))
}
messageStr, ok := input["messageId"].(string)
if !ok {
return nil, vo.WrapError(errno.ErrInvalidParameter, errors.New("messageId is required"))
}
messageID, err := strconv.ParseInt(messageStr, 10, 64)
if err != nil {
return nil, vo.WrapError(errno.ErrInvalidParameter, err)
}
if appID == nil {
if conversationName != "Default" {
return nil, vo.WrapError(errno.ErrOnlyDefaultConversationAllowInAgentScenario, fmt.Errorf("only default conversation allow in agent scenario"))
}
if agentID == nil || execCtx.ExeCfg.ConversationID == nil {
return failedMap, nil
}
err = d.Manager.DeleteMessage(ctx, &conversation.DeleteMessageRequest{ConversationID: *execCtx.ExeCfg.ConversationID, MessageID: messageID})
if err != nil {
return nil, vo.WrapError(errno.ErrConversationNodesNotAvailable, err)
}
return successMap, nil
}
t, existed, err := wf.GetRepository().GetConversationTemplate(ctx, env, vo.GetConversationTemplatePolicy{
AppID: appID,
Name: ptr.Of(conversationName),
Version: ptr.Of(version),
})
if err != nil {
return nil, vo.WrapError(errno.ErrConversationNodesNotAvailable, err)
}
if existed {
sts, existed, err := wf.GetRepository().GetStaticConversationByTemplateID(ctx, env, userID, connectorID, t.TemplateID)
if err != nil {
return nil, vo.WrapError(errno.ErrConversationNodesNotAvailable, err)
}
if !existed {
return failedMap, nil
}
err = d.Manager.DeleteMessage(ctx, &conversation.DeleteMessageRequest{ConversationID: sts.ConversationID, MessageID: messageID})
if err != nil {
return nil, vo.WrapError(errno.ErrConversationNodesNotAvailable, err)
}
return successMap, nil
} else {
dyConversation, existed, err := wf.GetRepository().GetDynamicConversationByName(ctx, env, *appID, connectorID, userID, conversationName)
if err != nil {
return nil, vo.WrapError(errno.ErrConversationNodesNotAvailable, err)
}
if !existed {
return failedMap, nil
}
err = d.Manager.DeleteMessage(ctx, &conversation.DeleteMessageRequest{ConversationID: dyConversation.ConversationID, MessageID: messageID})
if err != nil {
return nil, vo.WrapError(errno.ErrConversationNodesNotAvailable, err)
}
return successMap, nil
}
}

View File

@ -0,0 +1,168 @@
/*
* Copyright 2025 coze-dev Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package conversation
import (
"context"
"errors"
"fmt"
"strconv"
"github.com/coze-dev/coze-studio/backend/domain/workflow"
"github.com/coze-dev/coze-studio/backend/domain/workflow/crossdomain/conversation"
"github.com/coze-dev/coze-studio/backend/domain/workflow/entity"
"github.com/coze-dev/coze-studio/backend/domain/workflow/entity/vo"
"github.com/coze-dev/coze-studio/backend/domain/workflow/internal/canvas/convert"
"github.com/coze-dev/coze-studio/backend/domain/workflow/internal/execute"
"github.com/coze-dev/coze-studio/backend/domain/workflow/internal/nodes"
"github.com/coze-dev/coze-studio/backend/domain/workflow/internal/schema"
"github.com/coze-dev/coze-studio/backend/pkg/lang/ptr"
"github.com/coze-dev/coze-studio/backend/pkg/lang/ternary"
"github.com/coze-dev/coze-studio/backend/types/errno"
)
type EditMessageConfig struct{}
type EditMessage struct {
Manager conversation.ConversationManager
}
func (e *EditMessageConfig) Adapt(_ context.Context, n *vo.Node, _ ...nodes.AdaptOption) (*schema.NodeSchema, error) {
ns := &schema.NodeSchema{
Key: vo.NodeKey(n.ID),
Type: entity.NodeTypeEditMessage,
Name: n.Data.Meta.Title,
Configs: e,
}
if err := convert.SetInputsForNodeSchema(n, ns); err != nil {
return nil, err
}
if err := convert.SetOutputTypesForNodeSchema(n, ns); err != nil {
return nil, err
}
return ns, nil
}
func (e *EditMessageConfig) Build(_ context.Context, ns *schema.NodeSchema, _ ...schema.BuildOption) (any, error) {
return &EditMessage{
Manager: conversation.GetConversationManager(),
}, nil
}
func (e *EditMessage) Invoke(ctx context.Context, input map[string]any) (map[string]any, error) {
var (
execCtx = execute.GetExeCtx(ctx)
env = ternary.IFElse(execCtx.ExeCfg.Mode == vo.ExecuteModeRelease, vo.Online, vo.Draft)
appID = execCtx.ExeCfg.AppID
agentID = execCtx.ExeCfg.AgentID
version = execCtx.ExeCfg.Version
connectorID = execCtx.ExeCfg.ConnectorID
userID = execCtx.ExeCfg.Operator
successMap = map[string]any{
"isSuccess": true,
}
failedMap = map[string]any{
"isSuccess": false,
}
)
conversationName, ok := input["conversationName"].(string)
if !ok {
return nil, vo.WrapError(errno.ErrInvalidParameter, errors.New("conversationName is required"))
}
messageStr, ok := input["messageId"].(string)
if !ok {
return nil, vo.WrapError(errno.ErrInvalidParameter, errors.New("messageId is required"))
}
messageID, err := strconv.ParseInt(messageStr, 10, 64)
if err != nil {
return nil, vo.WrapError(errno.ErrConversationNodesNotAvailable, err)
}
newContent, ok := input["newContent"].(string)
if !ok {
return nil, vo.WrapError(errno.ErrInvalidParameter, errors.New("newContent is required"))
}
if appID == nil {
if conversationName != "Default" {
return nil, vo.WrapError(errno.ErrOnlyDefaultConversationAllowInAgentScenario, fmt.Errorf("only default conversation allow in agent scenario"))
}
if agentID == nil || execCtx.ExeCfg.ConversationID == nil {
return failedMap, nil
}
err = e.Manager.EditMessage(ctx, &conversation.EditMessageRequest{ConversationID: *execCtx.ExeCfg.ConversationID, MessageID: messageID, Content: newContent})
if err != nil {
return nil, vo.WrapError(errno.ErrConversationNodesNotAvailable, err)
}
return successMap, err
}
t, existed, err := workflow.GetRepository().GetConversationTemplate(ctx, env, vo.GetConversationTemplatePolicy{
AppID: appID,
Name: ptr.Of(conversationName),
Version: ptr.Of(version),
})
if err != nil {
return nil, vo.WrapError(errno.ErrConversationNodesNotAvailable, err)
}
if existed {
sts, existed, err := workflow.GetRepository().GetStaticConversationByTemplateID(ctx, env, userID, connectorID, t.TemplateID)
if err != nil {
return nil, vo.WrapError(errno.ErrConversationNodesNotAvailable, err)
}
if !existed {
return failedMap, nil
}
err = e.Manager.EditMessage(ctx, &conversation.EditMessageRequest{ConversationID: sts.ConversationID, MessageID: messageID, Content: newContent})
if err != nil {
return nil, vo.WrapError(errno.ErrConversationNodesNotAvailable, err)
}
return successMap, nil
} else {
dyConversation, existed, err := workflow.GetRepository().GetDynamicConversationByName(ctx, env, *appID, connectorID, userID, conversationName)
if err != nil {
return nil, vo.WrapError(errno.ErrConversationNodesNotAvailable, err)
}
if !existed {
return failedMap, nil
}
err = e.Manager.EditMessage(ctx, &conversation.EditMessageRequest{ConversationID: dyConversation.ConversationID, MessageID: messageID, Content: newContent})
if err != nil {
return nil, vo.WrapError(errno.ErrConversationNodesNotAvailable, err)
}
return successMap, nil
}
}

View File

@ -0,0 +1,220 @@
/*
* Copyright 2025 coze-dev Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package conversation
import (
"context"
"errors"
"fmt"
"strconv"
"github.com/coze-dev/coze-studio/backend/domain/workflow"
"github.com/coze-dev/coze-studio/backend/domain/workflow/crossdomain/conversation"
"github.com/coze-dev/coze-studio/backend/domain/workflow/entity"
"github.com/coze-dev/coze-studio/backend/domain/workflow/entity/vo"
"github.com/coze-dev/coze-studio/backend/domain/workflow/internal/canvas/convert"
"github.com/coze-dev/coze-studio/backend/domain/workflow/internal/execute"
"github.com/coze-dev/coze-studio/backend/domain/workflow/internal/nodes"
"github.com/coze-dev/coze-studio/backend/domain/workflow/internal/schema"
"github.com/coze-dev/coze-studio/backend/pkg/lang/ptr"
"github.com/coze-dev/coze-studio/backend/pkg/lang/ternary"
"github.com/coze-dev/coze-studio/backend/types/errno"
)
type MessageListConfig struct{}
type MessageList struct {
Lister conversation.ConversationManager
}
func (m *MessageListConfig) Adapt(_ context.Context, n *vo.Node, _ ...nodes.AdaptOption) (*schema.NodeSchema, error) {
ns := &schema.NodeSchema{
Key: vo.NodeKey(n.ID),
Type: entity.NodeTypeMessageList,
Name: n.Data.Meta.Title,
Configs: m,
}
if err := convert.SetInputsForNodeSchema(n, ns); err != nil {
return nil, err
}
if err := convert.SetOutputTypesForNodeSchema(n, ns); err != nil {
return nil, err
}
return ns, nil
}
func (m *MessageListConfig) Build(_ context.Context, ns *schema.NodeSchema, _ ...schema.BuildOption) (any, error) {
return &MessageList{
Lister: conversation.GetConversationManager(),
}, nil
}
func (m *MessageList) getConversationIDByName(ctx context.Context, env vo.Env, appID *int64, version, conversationName string, userID, connectorID int64) (int64, error) {
template, isExist, err := workflow.GetRepository().GetConversationTemplate(ctx, env, vo.GetConversationTemplatePolicy{
AppID: appID,
Name: ptr.Of(conversationName),
Version: ptr.Of(version),
})
if err != nil {
return 0, vo.WrapError(errno.ErrConversationNodeInvalidOperation, err)
}
var conversationID int64
if isExist {
sc, _, err := workflow.GetRepository().GetStaticConversationByTemplateID(ctx, env, userID, connectorID, template.TemplateID)
if err != nil {
return 0, vo.WrapError(errno.ErrConversationNodeInvalidOperation, err)
}
if sc != nil {
conversationID = sc.ConversationID
}
} else {
dc, _, err := workflow.GetRepository().GetDynamicConversationByName(ctx, env, *appID, connectorID, userID, conversationName)
if err != nil {
return 0, vo.WrapError(errno.ErrConversationNodeInvalidOperation, err)
}
if dc != nil {
conversationID = dc.ConversationID
}
}
return conversationID, nil
}
func (m *MessageList) Invoke(ctx context.Context, input map[string]any) (map[string]any, error) {
var (
execCtx = execute.GetExeCtx(ctx)
env = ternary.IFElse(execCtx.ExeCfg.Mode == vo.ExecuteModeRelease, vo.Online, vo.Draft)
appID = execCtx.ExeCfg.AppID
agentID = execCtx.ExeCfg.AgentID
version = execCtx.ExeCfg.Version
connectorID = execCtx.ExeCfg.ConnectorID
userID = execCtx.ExeCfg.Operator
)
conversationName, ok := input["conversationName"].(string)
if !ok {
return nil, vo.WrapError(errno.ErrConversationNodeInvalidOperation, errors.New("ConversationName is required"))
}
var conversationID int64
var err error
var resolvedAppID int64
if appID == nil {
if conversationName != "Default" {
return nil, vo.WrapError(errno.ErrOnlyDefaultConversationAllowInAgentScenario, errors.New("conversation node only allow in application"))
}
if agentID == nil || execCtx.ExeCfg.ConversationID == nil {
return map[string]any{
"messageList": []any{},
"firstId": "0",
"lastId": "0",
"hasMore": false,
}, nil
}
conversationID = *execCtx.ExeCfg.ConversationID
resolvedAppID = *agentID
} else {
conversationID, err = m.getConversationIDByName(ctx, env, appID, version, conversationName, userID, connectorID)
if err != nil {
return nil, err
}
resolvedAppID = *appID
}
req := &conversation.MessageListRequest{
UserID: userID,
AppID: resolvedAppID,
ConversationID: conversationID,
}
if req.ConversationID == 0 {
return map[string]any{
"messageList": []any{},
"firstId": "0",
"lastId": "0",
"hasMore": false,
}, nil
}
limit, ok := input["limit"].(int64)
if ok {
if limit > 0 && limit <= 50 {
req.Limit = limit
} else {
req.Limit = 50
}
} else {
req.Limit = 50
}
beforeID, ok := input["beforeId"].(string)
if ok {
req.BeforeID = &beforeID
}
afterID, ok := input["afterId"].(string)
if ok {
req.AfterID = &afterID
}
if beforeID != "" && afterID != "" {
return nil, vo.WrapError(errno.ErrInvalidParameter, fmt.Errorf("BeforeID and AfterID cannot be set at the same time"))
}
ml, err := m.Lister.MessageList(ctx, req)
if err != nil {
return nil, err
}
var messageList []any
for _, msg := range ml.Messages {
content, err := ConvertMessageToString(ctx, msg)
if err != nil {
return nil, err
}
messageList = append(messageList, map[string]any{
"messageId": strconv.FormatInt(msg.ID, 10),
"role": string(msg.Role),
"contentType": msg.ContentType,
"content": content,
})
}
// TODO: After the List interface is updated, the firstId and lastId from the response can be returned directly without extra processing
var firstId, lastId any = "0", "0"
if len(messageList) > 0 {
if firstMsg, ok := messageList[0].(map[string]any); ok {
firstId = firstMsg["messageId"]
}
if lastMsg, ok := messageList[len(messageList)-1].(map[string]any); ok {
lastId = lastMsg["messageId"]
}
}
return map[string]any{
"messageList": messageList,
"firstId": firstId,
"lastId": lastId,
"hasMore": ml.HasMore,
}, nil
}

View File

@ -0,0 +1,147 @@
/*
* Copyright 2025 coze-dev Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package conversation
import (
"context"
"errors"
"fmt"
"strconv"
wf "github.com/coze-dev/coze-studio/backend/domain/workflow"
"github.com/coze-dev/coze-studio/backend/domain/workflow/entity"
"github.com/coze-dev/coze-studio/backend/domain/workflow/entity/vo"
"github.com/coze-dev/coze-studio/backend/domain/workflow/internal/canvas/convert"
"github.com/coze-dev/coze-studio/backend/domain/workflow/internal/execute"
"github.com/coze-dev/coze-studio/backend/domain/workflow/internal/nodes"
"github.com/coze-dev/coze-studio/backend/domain/workflow/internal/schema"
"github.com/coze-dev/coze-studio/backend/pkg/lang/ptr"
"github.com/coze-dev/coze-studio/backend/pkg/lang/ternary"
"github.com/coze-dev/coze-studio/backend/types/errno"
)
type UpdateConversationConfig struct{}
type UpdateConversation struct{}
func (c *UpdateConversationConfig) Adapt(_ context.Context, n *vo.Node, _ ...nodes.AdaptOption) (*schema.NodeSchema, error) {
ns := &schema.NodeSchema{
Key: vo.NodeKey(n.ID),
Type: entity.NodeTypeConversationUpdate,
Name: n.Data.Meta.Title,
Configs: c,
}
if err := convert.SetInputsForNodeSchema(n, ns); err != nil {
return nil, err
}
if err := convert.SetOutputTypesForNodeSchema(n, ns); err != nil {
return nil, err
}
return ns, nil
}
func (c *UpdateConversationConfig) Build(_ context.Context, ns *schema.NodeSchema, _ ...schema.BuildOption) (any, error) {
return &UpdateConversation{}, nil
}
func (c *UpdateConversation) Invoke(ctx context.Context, in map[string]any) (map[string]any, error) {
var (
execCtx = execute.GetExeCtx(ctx)
env = ternary.IFElse(execCtx.ExeCfg.Mode == vo.ExecuteModeRelease, vo.Online, vo.Draft)
appID = execCtx.ExeCfg.AppID
agentID = execCtx.ExeCfg.AgentID
version = execCtx.ExeCfg.Version
connectorID = execCtx.ExeCfg.ConnectorID
userID = execCtx.ExeCfg.Operator
)
cName, ok := in["conversationName"]
if !ok {
return nil, vo.WrapError(errno.ErrInvalidParameter, errors.New("conversation name is required"))
}
conversationName := cName.(string)
ncName, ok := in["newConversationName"]
if !ok {
return nil, vo.WrapError(errno.ErrInvalidParameter, errors.New("new conversationName name is required"))
}
newConversationName := ncName.(string)
if agentID != nil {
return nil, vo.WrapError(errno.ErrConversationNodesNotAvailable, fmt.Errorf("in the agent scenario, update conversation is not available"))
}
if appID == nil {
return nil, vo.WrapError(errno.ErrConversationNodesNotAvailable, errors.New("conversation update node, app id is required"))
}
_, existed, err := wf.GetRepository().GetConversationTemplate(ctx, env, vo.GetConversationTemplatePolicy{
AppID: appID,
Name: ptr.Of(conversationName),
Version: ptr.Of(version),
})
if err != nil {
return nil, err
}
if existed {
return nil, vo.WrapError(errno.ErrConversationNodeInvalidOperation, fmt.Errorf("only conversation created through nodes are allowed to be modified or deleted"))
}
conversation, existed, err := wf.GetRepository().GetDynamicConversationByName(ctx, env, *appID, connectorID, userID, conversationName)
if err != nil {
return nil, err
}
if !existed {
return map[string]any{
"conversationId": "0",
"isSuccess": false,
"isExisted": false,
}, nil
}
ncConversation, existed, err := wf.GetRepository().GetDynamicConversationByName(ctx, env, *appID, connectorID, userID, newConversationName)
if err != nil {
return nil, err
}
if existed {
return map[string]any{
"conversationId": strconv.FormatInt(ncConversation.ConversationID, 10),
"isSuccess": false,
"isExisted": true,
}, nil
}
err = wf.GetRepository().UpdateDynamicConversationNameByID(ctx, env, conversation.ID, newConversationName)
if err != nil {
return nil, err
}
return map[string]any{
"conversationId": strconv.FormatInt(conversation.ConversationID, 10),
"isSuccess": true,
"isExisted": false,
}, nil
}

View File

@ -26,24 +26,29 @@ import (
"github.com/cloudwego/eino/components/prompt"
"github.com/cloudwego/eino/compose"
"github.com/cloudwego/eino/schema"
"github.com/spf13/cast"
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/domain/workflow/crossdomain/conversation"
"github.com/coze-dev/coze-studio/backend/domain/workflow/entity"
"github.com/coze-dev/coze-studio/backend/domain/workflow/entity/vo"
"github.com/coze-dev/coze-studio/backend/domain/workflow/internal/canvas/convert"
"github.com/coze-dev/coze-studio/backend/domain/workflow/internal/execute"
"github.com/coze-dev/coze-studio/backend/domain/workflow/internal/nodes"
nodesconversation "github.com/coze-dev/coze-studio/backend/domain/workflow/internal/nodes/conversation"
schema2 "github.com/coze-dev/coze-studio/backend/domain/workflow/internal/schema"
"github.com/coze-dev/coze-studio/backend/pkg/ctxcache"
"github.com/coze-dev/coze-studio/backend/pkg/lang/ternary"
"github.com/coze-dev/coze-studio/backend/pkg/logs"
"github.com/coze-dev/coze-studio/backend/pkg/sonic"
"github.com/spf13/cast"
)
type Config struct {
Intents []string
SystemPrompt string
IsFastMode bool
LLMParams *model.LLMParams
Intents []string
SystemPrompt string
IsFastMode bool
LLMParams *model.LLMParams
ChatHistorySetting *vo.ChatHistorySetting
}
func (c *Config) Adapt(_ context.Context, n *vo.Node, _ ...nodes.AdaptOption) (*schema2.NodeSchema, error) {
@ -59,6 +64,10 @@ func (c *Config) Adapt(_ context.Context, n *vo.Node, _ ...nodes.AdaptOption) (*
return nil, fmt.Errorf("intent detector node's llmParam is nil")
}
if n.Data.Inputs.ChatHistorySetting != nil {
c.ChatHistorySetting = n.Data.Inputs.ChatHistorySetting
}
llmParam, ok := param.(vo.IntentDetectorLLMParam)
if !ok {
return nil, fmt.Errorf("llm node's llmParam must be LLMParam, got %v", llmParam)
@ -141,14 +150,16 @@ func (c *Config) Build(ctx context.Context, _ *schema2.NodeSchema, _ ...schema2.
&schema.Message{Content: sptTemplate, Role: schema.System},
&schema.Message{Content: "{{query}}", Role: schema.User})
r, err := chain.AppendChatTemplate(prompts).AppendChatModel(m).Compile(ctx)
r, err := chain.AppendChatTemplate(newHistoryChatTemplate(prompts, c.ChatHistorySetting)).AppendChatModel(m).Compile(ctx)
if err != nil {
return nil, err
}
return &IntentDetector{
isFastMode: c.IsFastMode,
systemPrompt: c.SystemPrompt,
runner: r,
isFastMode: c.IsFastMode,
systemPrompt: c.SystemPrompt,
runner: r,
ChatHistorySetting: c.ChatHistorySetting,
}, nil
}
@ -182,6 +193,10 @@ func (c *Config) ExpectPorts(ctx context.Context, n *vo.Node) []string {
return expects
}
type contextKey string
const chatHistoryKey contextKey = "chatHistory"
const SystemIntentPrompt = `
# Role
You are an intention classification expert, good at being able to judge which classification the user's input belongs to.
@ -240,9 +255,10 @@ Note:
const classificationID = "classificationId"
type IntentDetector struct {
isFastMode bool
systemPrompt string
runner compose.Runnable[map[string]any, *schema.Message]
isFastMode bool
systemPrompt string
runner compose.Runnable[map[string]any, *schema.Message]
ChatHistorySetting *vo.ChatHistorySetting
}
func (id *IntentDetector) parseToNodeOut(content string) (map[string]any, error) {
@ -320,3 +336,48 @@ func toIntentString(its []string) (string, error) {
return sonic.MarshalString(vs)
}
func (id *IntentDetector) ToCallbackInput(ctx context.Context, in map[string]any) (map[string]any, error) {
if id.ChatHistorySetting == nil || !id.ChatHistorySetting.EnableChatHistory {
return in, nil
}
var messages []*conversation.Message
execCtx := execute.GetExeCtx(ctx)
if execCtx != nil {
messages = execCtx.ExeCfg.ConversationHistory
}
if len(messages) == 0 {
return in, nil
}
count := 0
endIdx := 0
var historyMessages []any
for _, msg := range messages {
if count > int(id.ChatHistorySetting.ChatHistoryRound) {
break
}
if msg.Role == schema.User {
count++
}
endIdx++
content, err := nodesconversation.ConvertMessageToString(ctx, msg)
if err != nil {
logs.CtxWarnf(ctx, "failed to convert message to string: %v", err)
continue
}
historyMessages = append(historyMessages, map[string]any{
"role": string(msg.Role),
"content": content,
})
}
ctxcache.Store(ctx, chatHistoryKey, messages[:endIdx])
ret := map[string]any{
"chatHistory": historyMessages,
"query": in["query"],
}
return ret, nil
}

View File

@ -0,0 +1,102 @@
/*
* Copyright 2025 coze-dev Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package intentdetector
import (
"context"
"fmt"
"github.com/cloudwego/eino/components/prompt"
"github.com/cloudwego/eino/schema"
"github.com/coze-dev/coze-studio/backend/api/model/workflow"
"github.com/coze-dev/coze-studio/backend/domain/workflow/crossdomain/conversation"
"github.com/coze-dev/coze-studio/backend/domain/workflow/entity/vo"
"github.com/coze-dev/coze-studio/backend/domain/workflow/internal/execute"
nodesconversation "github.com/coze-dev/coze-studio/backend/domain/workflow/internal/nodes/conversation"
"github.com/coze-dev/coze-studio/backend/pkg/ctxcache"
"github.com/coze-dev/coze-studio/backend/pkg/logs"
)
type historyChatTemplate struct {
basePrompt prompt.ChatTemplate
chatHistorySetting *vo.ChatHistorySetting
}
func newHistoryChatTemplate(basePrompt prompt.ChatTemplate, chatHistorySetting *vo.ChatHistorySetting) prompt.ChatTemplate {
return &historyChatTemplate{
basePrompt: basePrompt,
chatHistorySetting: chatHistorySetting,
}
}
func (t *historyChatTemplate) Format(ctx context.Context, vs map[string]any, opts ...prompt.Option) ([]*schema.Message, error) {
baseMessages, err := t.basePrompt.Format(ctx, vs, opts...)
if err != nil {
return nil, fmt.Errorf("failed to format base prompt: %w", err)
}
if len(baseMessages) == 0 {
return nil, fmt.Errorf("base prompt returned no messages")
}
if t.chatHistorySetting == nil || !t.chatHistorySetting.EnableChatHistory {
return baseMessages, nil
}
exeCtx := execute.GetExeCtx(ctx)
if exeCtx == nil {
logs.CtxWarnf(ctx, "execute context is nil, skipping chat history")
return baseMessages, nil
}
if exeCtx.ExeCfg.WorkflowMode != workflow.WorkflowMode_ChatFlow {
return baseMessages, nil
}
historyFromCtx, ok := ctxcache.Get[[]*conversation.Message](ctx, chatHistoryKey)
var messages []*conversation.Message
if ok {
messages = historyFromCtx
}
if len(messages) == 0 {
logs.CtxWarnf(ctx, "conversation history is empty")
return baseMessages, nil
}
historyMessages := make([]*schema.Message, 0, len(messages))
for _, msg := range messages {
schemaMsg, err := nodesconversation.ConvertMessageToSchema(ctx, msg)
if err != nil {
logs.CtxWarnf(ctx, "failed to convert history message, skipping: %v", err)
continue
}
historyMessages = append(historyMessages, schemaMsg)
}
if len(historyMessages) == 0 {
return baseMessages, nil
}
finalMessages := make([]*schema.Message, 0, len(baseMessages)+len(historyMessages))
finalMessages = append(finalMessages, baseMessages[0]) // System prompt
finalMessages = append(finalMessages, historyMessages...)
if len(baseMessages) > 1 {
finalMessages = append(finalMessages, baseMessages[1:]...) // User prompt and any others
}
return finalMessages, nil
}

View File

@ -22,21 +22,33 @@ import (
"github.com/spf13/cast"
einoSchema "github.com/cloudwego/eino/schema"
"github.com/coze-dev/coze-studio/backend/api/model/crossdomain/knowledge"
"github.com/coze-dev/coze-studio/backend/api/model/workflow"
crossknowledge "github.com/coze-dev/coze-studio/backend/crossdomain/contract/knowledge"
"github.com/coze-dev/coze-studio/backend/domain/workflow/crossdomain/conversation"
"github.com/coze-dev/coze-studio/backend/domain/workflow/entity"
"github.com/coze-dev/coze-studio/backend/domain/workflow/entity/vo"
"github.com/coze-dev/coze-studio/backend/domain/workflow/internal/canvas/convert"
"github.com/coze-dev/coze-studio/backend/domain/workflow/internal/execute"
"github.com/coze-dev/coze-studio/backend/domain/workflow/internal/nodes"
nodesconversation "github.com/coze-dev/coze-studio/backend/domain/workflow/internal/nodes/conversation"
"github.com/coze-dev/coze-studio/backend/domain/workflow/internal/schema"
"github.com/coze-dev/coze-studio/backend/pkg/ctxcache"
"github.com/coze-dev/coze-studio/backend/pkg/lang/slices"
"github.com/coze-dev/coze-studio/backend/pkg/logs"
)
const outputList = "outputList"
type contextKey string
const chatHistoryKey contextKey = "chatHistory"
type RetrieveConfig struct {
KnowledgeIDs []int64
RetrievalStrategy *knowledge.RetrievalStrategy
KnowledgeIDs []int64
RetrievalStrategy *knowledge.RetrievalStrategy
ChatHistorySetting *vo.ChatHistorySetting
}
func (r *RetrieveConfig) Adapt(_ context.Context, n *vo.Node, _ ...nodes.AdaptOption) (*schema.NodeSchema, error) {
@ -60,6 +72,10 @@ func (r *RetrieveConfig) Adapt(_ context.Context, n *vo.Node, _ ...nodes.AdaptOp
}
r.KnowledgeIDs = knowledgeIDs
if inputs.ChatHistorySetting != nil {
r.ChatHistorySetting = inputs.ChatHistorySetting
}
retrievalStrategy := &knowledge.RetrievalStrategy{}
var getDesignatedParamContent = func(name string) (any, bool) {
@ -154,14 +170,16 @@ func (r *RetrieveConfig) Build(_ context.Context, _ *schema.NodeSchema, _ ...sch
}
return &Retrieve{
knowledgeIDs: r.KnowledgeIDs,
retrievalStrategy: r.RetrievalStrategy,
knowledgeIDs: r.KnowledgeIDs,
retrievalStrategy: r.RetrievalStrategy,
ChatHistorySetting: r.ChatHistorySetting,
}, nil
}
type Retrieve struct {
knowledgeIDs []int64
retrievalStrategy *knowledge.RetrievalStrategy
knowledgeIDs []int64
retrievalStrategy *knowledge.RetrievalStrategy
ChatHistorySetting *vo.ChatHistorySetting
}
func (kr *Retrieve) Invoke(ctx context.Context, input map[string]any) (map[string]any, error) {
@ -173,6 +191,7 @@ func (kr *Retrieve) Invoke(ctx context.Context, input map[string]any) (map[strin
req := &knowledge.RetrieveRequest{
Query: query,
KnowledgeIDs: kr.knowledgeIDs,
ChatHistory: kr.GetChatHistoryOrNil(ctx, kr.ChatHistorySetting),
Strategy: kr.retrievalStrategy,
}
@ -190,3 +209,84 @@ func (kr *Retrieve) Invoke(ctx context.Context, input map[string]any) (map[strin
return result, nil
}
func (kr *Retrieve) GetChatHistoryOrNil(ctx context.Context, ChatHistorySetting *vo.ChatHistorySetting) []*einoSchema.Message {
if ChatHistorySetting == nil || !ChatHistorySetting.EnableChatHistory {
return nil
}
exeCtx := execute.GetExeCtx(ctx)
if exeCtx == nil {
logs.CtxWarnf(ctx, "execute context is nil, skipping chat history")
return nil
}
if exeCtx.ExeCfg.WorkflowMode != workflow.WorkflowMode_ChatFlow {
return nil
}
historyFromCtx, ok := ctxcache.Get[[]*conversation.Message](ctx, chatHistoryKey)
var messages []*conversation.Message
if ok {
messages = historyFromCtx
}
if len(messages) == 0 {
logs.CtxWarnf(ctx, "conversation history is empty")
return nil
}
historyMessages := make([]*einoSchema.Message, 0, len(messages))
for _, msg := range messages {
schemaMsg, err := nodesconversation.ConvertMessageToSchema(ctx, msg)
if err != nil {
logs.CtxWarnf(ctx, "failed to convert history message, skipping: %v", err)
continue
}
historyMessages = append(historyMessages, schemaMsg)
}
return historyMessages
}
func (kr *Retrieve) ToCallbackInput(ctx context.Context, in map[string]any) (map[string]any, error) {
if kr.ChatHistorySetting == nil || !kr.ChatHistorySetting.EnableChatHistory {
return in, nil
}
var messages []*conversation.Message
execCtx := execute.GetExeCtx(ctx)
if execCtx != nil {
messages = execCtx.ExeCfg.ConversationHistory
}
if len(messages) == 0 {
return in, nil
}
count := 0
endIdx := 0
var historyMessages []any
for _, msg := range messages {
if count > int(kr.ChatHistorySetting.ChatHistoryRound) {
break
}
if msg.Role == einoSchema.User {
count++
}
endIdx++
content, err := nodesconversation.ConvertMessageToString(ctx, msg)
if err != nil {
logs.CtxWarnf(ctx, "failed to convert message to string: %v", err)
continue
}
historyMessages = append(historyMessages, map[string]any{
"role": string(msg.Role),
"content": content,
})
}
ctxcache.Store(ctx, chatHistoryKey, messages[:endIdx])
ret := map[string]any{
"chatHistory": historyMessages,
"Query": in["Query"],
}
return ret, nil
}

View File

@ -40,12 +40,14 @@ import (
crossknowledge "github.com/coze-dev/coze-studio/backend/crossdomain/contract/knowledge"
crossmodelmgr "github.com/coze-dev/coze-studio/backend/crossdomain/contract/modelmgr"
"github.com/coze-dev/coze-studio/backend/domain/workflow"
"github.com/coze-dev/coze-studio/backend/domain/workflow/crossdomain/conversation"
"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"
"github.com/coze-dev/coze-studio/backend/domain/workflow/internal/execute"
"github.com/coze-dev/coze-studio/backend/domain/workflow/internal/nodes"
nodesconversation "github.com/coze-dev/coze-studio/backend/domain/workflow/internal/nodes/conversation"
schema2 "github.com/coze-dev/coze-studio/backend/domain/workflow/internal/schema"
"github.com/coze-dev/coze-studio/backend/infra/contract/modelmgr"
"github.com/coze-dev/coze-studio/backend/pkg/ctxcache"
@ -57,6 +59,10 @@ import (
"github.com/coze-dev/coze-studio/backend/types/errno"
)
type contextKey string
const chatHistoryKey contextKey = "chatHistory"
type Format int
const (
@ -164,12 +170,14 @@ type KnowledgeRecallConfig struct {
}
type Config struct {
SystemPrompt string
UserPrompt string
OutputFormat Format
LLMParams *crossmodel.LLMParams
FCParam *vo.FCParam
BackupLLMParams *crossmodel.LLMParams
SystemPrompt string
UserPrompt string
OutputFormat Format
LLMParams *crossmodel.LLMParams
FCParam *vo.FCParam
BackupLLMParams *crossmodel.LLMParams
ChatHistorySetting *vo.ChatHistorySetting
AssociateStartNodeUserInputFields map[string]struct{}
}
func (c *Config) Adapt(_ context.Context, n *vo.Node, _ ...nodes.AdaptOption) (*schema2.NodeSchema, error) {
@ -199,6 +207,13 @@ func (c *Config) Adapt(_ context.Context, n *vo.Node, _ ...nodes.AdaptOption) (*
c.SystemPrompt = convertedLLMParam.SystemPrompt
c.UserPrompt = convertedLLMParam.Prompt
if convertedLLMParam.EnableChatHistory {
c.ChatHistorySetting = &vo.ChatHistorySetting{
EnableChatHistory: true,
ChatHistoryRound: convertedLLMParam.ChatHistoryRound,
}
}
var resFormat Format
switch convertedLLMParam.ResponseFormat {
case crossmodel.ResponseFormatText:
@ -270,6 +285,15 @@ func (c *Config) Adapt(_ context.Context, n *vo.Node, _ ...nodes.AdaptOption) (*
}
}
c.AssociateStartNodeUserInputFields = make(map[string]struct{})
for _, info := range ns.InputSources {
if len(info.Path) == 1 && info.Source.Ref != nil && info.Source.Ref.FromNodeKey == entity.EntryNodeKey {
if compose.FromFieldPath(info.Source.Ref.FromPath).Equals(compose.FromField("USER_INPUT")) {
c.AssociateStartNodeUserInputFields[info.Path[0]] = struct{}{}
}
}
}
return ns, nil
}
@ -317,7 +341,14 @@ func llmParamsToLLMParam(params vo.LLMParam) (*crossmodel.LLMParams, error) {
case "systemPrompt":
strVal := param.Input.Value.Content.(string)
p.SystemPrompt = strVal
case "chatHistoryRound", "generationDiversity", "frequencyPenalty", "presencePenalty":
case "chatHistoryRound":
strVal := param.Input.Value.Content.(string)
int64Val, err := strconv.ParseInt(strVal, 10, 64)
if err != nil {
return nil, err
}
p.ChatHistoryRound = int64Val
case "generationDiversity", "frequencyPenalty", "presencePenalty":
// do nothing
case "topP":
strVal := param.Input.Value.Content.(string)
@ -586,11 +617,12 @@ func (c *Config) Build(ctx context.Context, ns *schema2.NodeSchema, _ ...schema2
inputs[knowledgeUserPromptTemplateKey] = &vo.TypeInfo{
Type: vo.DataTypeString,
}
sp := newPromptTpl(schema.System, c.SystemPrompt, inputs, nil)
up := newPromptTpl(schema.User, userPrompt, inputs, []string{knowledgeUserPromptTemplateKey})
sp := newPromptTpl(schema.System, c.SystemPrompt, inputs)
up := newPromptTpl(schema.User, userPrompt, inputs, withReservedKeys([]string{knowledgeUserPromptTemplateKey}), withAssociateUserInputFields(c.AssociateStartNodeUserInputFields))
template := newPrompts(sp, up, modelWithInfo)
templateWithChatHistory := newPromptsWithChatHistory(template, c.ChatHistorySetting)
_ = g.AddChatTemplateNode(templateNodeKey, template,
_ = g.AddChatTemplateNode(templateNodeKey, templateWithChatHistory,
compose.WithStatePreHandler(func(ctx context.Context, in map[string]any, state llmState) (map[string]any, error) {
for k, v := range state {
in[k] = v
@ -600,10 +632,12 @@ func (c *Config) Build(ctx context.Context, ns *schema2.NodeSchema, _ ...schema2
_ = g.AddEdge(knowledgeLambdaKey, templateNodeKey)
} else {
sp := newPromptTpl(schema.System, c.SystemPrompt, ns.InputTypes, nil)
up := newPromptTpl(schema.User, userPrompt, ns.InputTypes, nil)
sp := newPromptTpl(schema.System, c.SystemPrompt, ns.InputTypes)
up := newPromptTpl(schema.User, userPrompt, ns.InputTypes, withAssociateUserInputFields(c.AssociateStartNodeUserInputFields))
template := newPrompts(sp, up, modelWithInfo)
_ = g.AddChatTemplateNode(templateNodeKey, template)
templateWithChatHistory := newPromptsWithChatHistory(template, c.ChatHistorySetting)
_ = g.AddChatTemplateNode(templateNodeKey, templateWithChatHistory)
_ = g.AddEdge(compose.START, templateNodeKey)
}
@ -745,10 +779,11 @@ func (c *Config) Build(ctx context.Context, ns *schema2.NodeSchema, _ ...schema2
}
llm := &LLM{
r: r,
outputFormat: format,
requireCheckpoint: requireCheckpoint,
fullSources: ns.FullSources,
r: r,
outputFormat: format,
requireCheckpoint: requireCheckpoint,
fullSources: ns.FullSources,
chatHistorySetting: c.ChatHistorySetting,
}
return llm, nil
@ -815,10 +850,11 @@ func toRetrievalSearchType(s int64) (knowledge.SearchType, error) {
}
type LLM struct {
r compose.Runnable[map[string]any, map[string]any]
outputFormat Format
requireCheckpoint bool
fullSources map[string]*schema2.SourceInfo
r compose.Runnable[map[string]any, map[string]any]
outputFormat Format
requireCheckpoint bool
fullSources map[string]*schema2.SourceInfo
chatHistorySetting *vo.ChatHistorySetting
}
const (
@ -1197,6 +1233,52 @@ type ToolInterruptEventStore interface {
ResumeToolInterruptEvent(llmNodeKey vo.NodeKey, toolCallID string) (string, error)
}
func (l *LLM) ToCallbackInput(ctx context.Context, input map[string]any) (map[string]any, error) {
if l.chatHistorySetting == nil || !l.chatHistorySetting.EnableChatHistory {
return input, nil
}
var messages []*conversation.Message
execCtx := execute.GetExeCtx(ctx)
if execCtx != nil {
messages = execCtx.ExeCfg.ConversationHistory
}
if len(messages) == 0 {
return input, nil
}
count := 0
endIdx := 0
var historyMessages []any
for _, msg := range messages {
if count > int(l.chatHistorySetting.ChatHistoryRound) {
break
}
if msg.Role == schema.User {
count++
}
endIdx++
content, err := nodesconversation.ConvertMessageToString(ctx, msg)
if err != nil {
logs.CtxWarnf(ctx, "failed to convert message to string: %v", err)
continue
}
historyMessages = append(historyMessages, map[string]any{
"role": string(msg.Role),
"content": content,
})
}
ctxcache.Store(ctx, chatHistoryKey, messages[:endIdx])
ret := map[string]any{
"chatHistory": historyMessages,
}
for k, v := range input {
ret[k] = v
}
return ret, nil
}
func (l *LLM) ToCallbackOutput(ctx context.Context, output map[string]any) (*nodes.StructuredCallbackOutput, error) {
c := execute.GetExeCtx(ctx)
if c == nil {

View File

@ -23,12 +23,16 @@ import (
"github.com/cloudwego/eino/components/prompt"
"github.com/cloudwego/eino/schema"
"github.com/coze-dev/coze-studio/backend/api/model/workflow"
"github.com/coze-dev/coze-studio/backend/domain/workflow/crossdomain/conversation"
"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"
nodesconversation "github.com/coze-dev/coze-studio/backend/domain/workflow/internal/nodes/conversation"
schema2 "github.com/coze-dev/coze-studio/backend/domain/workflow/internal/schema"
"github.com/coze-dev/coze-studio/backend/infra/contract/modelmgr"
"github.com/coze-dev/coze-studio/backend/pkg/ctxcache"
"github.com/coze-dev/coze-studio/backend/pkg/logs"
"github.com/coze-dev/coze-studio/backend/pkg/sonic"
)
@ -38,12 +42,30 @@ type prompts struct {
mwi ModelWithInfo
}
type promptsWithChatHistory struct {
prompts *prompts
cfg *vo.ChatHistorySetting
}
func withReservedKeys(keys []string) func(tpl *promptTpl) {
return func(tpl *promptTpl) {
tpl.reservedKeys = keys
}
}
func withAssociateUserInputFields(fs map[string]struct{}) func(tpl *promptTpl) {
return func(tpl *promptTpl) {
tpl.associateUserInputFields = fs
}
}
type promptTpl struct {
role schema.RoleType
tpl string
parts []promptPart
hasMultiModal bool
reservedKeys []string
role schema.RoleType
tpl string
parts []promptPart
hasMultiModal bool
reservedKeys []string
associateUserInputFields map[string]struct{}
}
type promptPart struct {
@ -54,12 +76,20 @@ type promptPart struct {
func newPromptTpl(role schema.RoleType,
tpl string,
inputTypes map[string]*vo.TypeInfo,
reservedKeys []string,
opts ...func(*promptTpl),
) *promptTpl {
if len(tpl) == 0 {
return nil
}
pTpl := &promptTpl{
role: role,
tpl: tpl,
}
for _, opt := range opts {
opt(pTpl)
}
parts := nodes.ParseTemplate(tpl)
promptParts := make([]promptPart, 0, len(parts))
hasMultiModal := false
@ -87,14 +117,10 @@ func newPromptTpl(role schema.RoleType,
hasMultiModal = true
}
pTpl.parts = promptParts
pTpl.hasMultiModal = hasMultiModal
return &promptTpl{
role: role,
tpl: tpl,
parts: promptParts,
hasMultiModal: hasMultiModal,
reservedKeys: reservedKeys,
}
return pTpl
}
const sourceKey = "sources_%s"
@ -107,23 +133,53 @@ func newPrompts(sp, up *promptTpl, model ModelWithInfo) *prompts {
}
}
func newPromptsWithChatHistory(prompts *prompts, cfg *vo.ChatHistorySetting) *promptsWithChatHistory {
return &promptsWithChatHistory{
prompts: prompts,
cfg: cfg,
}
}
func (pl *promptTpl) render(ctx context.Context, vs map[string]any,
sources map[string]*schema2.SourceInfo,
supportedModals map[modelmgr.Modal]bool,
) (*schema.Message, error) {
if !pl.hasMultiModal || len(supportedModals) == 0 {
var opts []nodes.RenderOption
if len(pl.reservedKeys) > 0 {
opts = append(opts, nodes.WithReservedKey(pl.reservedKeys...))
isChatFlow := execute.GetExeCtx(ctx).ExeCfg.WorkflowMode == workflow.WorkflowMode_ChatFlow
userMessage := execute.GetExeCtx(ctx).ExeCfg.UserMessage
if !isChatFlow {
if !pl.hasMultiModal || len(supportedModals) == 0 {
var opts []nodes.RenderOption
if len(pl.reservedKeys) > 0 {
opts = append(opts, nodes.WithReservedKey(pl.reservedKeys...))
}
r, err := nodes.Render(ctx, pl.tpl, vs, sources, opts...)
if err != nil {
return nil, err
}
return &schema.Message{
Role: pl.role,
Content: r,
}, nil
}
r, err := nodes.Render(ctx, pl.tpl, vs, sources, opts...)
if err != nil {
return nil, err
} else {
if (!pl.hasMultiModal || len(supportedModals) == 0) &&
(len(pl.associateUserInputFields) == 0 ||
(len(pl.associateUserInputFields) > 0 && userMessage.MultiContent == nil)) {
var opts []nodes.RenderOption
if len(pl.reservedKeys) > 0 {
opts = append(opts, nodes.WithReservedKey(pl.reservedKeys...))
}
r, err := nodes.Render(ctx, pl.tpl, vs, sources, opts...)
if err != nil {
return nil, err
}
return &schema.Message{
Role: pl.role,
Content: r,
}, nil
}
return &schema.Message{
Role: pl.role,
Content: r,
}, nil
}
multiParts := make([]schema.ChatMessagePart, 0, len(pl.parts))
@ -141,6 +197,13 @@ func (pl *promptTpl) render(ctx context.Context, vs map[string]any,
continue
}
if _, ok := pl.associateUserInputFields[part.part.Value]; ok && userMessage != nil && isChatFlow {
for _, p := range userMessage.MultiContent {
multiParts = append(multiParts, p)
}
continue
}
skipped, invalid := part.part.Skipped(sources)
if invalid {
var reserved bool
@ -288,3 +351,59 @@ func (p *prompts) Format(ctx context.Context, vs map[string]any, _ ...prompt.Opt
return []*schema.Message{systemMsg, userMsg}, nil
}
func (p *promptsWithChatHistory) Format(ctx context.Context, vs map[string]any, _ ...prompt.Option) (
[]*schema.Message, error) {
baseMessages, err := p.prompts.Format(ctx, vs)
if err != nil {
return nil, err
}
if p.cfg == nil || !p.cfg.EnableChatHistory {
return baseMessages, nil
}
exeCtx := execute.GetExeCtx(ctx)
if exeCtx == nil {
logs.CtxWarnf(ctx, "execute context is nil, skipping chat history")
return baseMessages, nil
}
if exeCtx.ExeCfg.WorkflowMode != workflow.WorkflowMode_ChatFlow {
return baseMessages, nil
}
historyFromCtx, ok := ctxcache.Get[[]*conversation.Message](ctx, chatHistoryKey)
var messages []*conversation.Message
if ok {
messages = historyFromCtx
}
if len(messages) == 0 {
logs.CtxWarnf(ctx, "conversation history is empty")
return baseMessages, nil
}
historyMessages := make([]*schema.Message, 0, len(messages))
for _, msg := range messages {
schemaMsg, err := nodesconversation.ConvertMessageToSchema(ctx, msg)
if err != nil {
logs.CtxWarnf(ctx, "failed to convert history message, skipping: %v", err)
continue
}
historyMessages = append(historyMessages, schemaMsg)
}
if len(historyMessages) == 0 {
return baseMessages, nil
}
finalMessages := make([]*schema.Message, 0, len(baseMessages)+len(historyMessages))
if len(baseMessages) > 0 && baseMessages[0].Role == schema.System {
finalMessages = append(finalMessages, baseMessages[0])
baseMessages = baseMessages[1:]
}
finalMessages = append(finalMessages, historyMessages...)
finalMessages = append(finalMessages, baseMessages...)
return finalMessages, nil
}

View File

@ -0,0 +1,800 @@
/*
* Copyright 2025 coze-dev Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package repo
import (
"context"
"errors"
"fmt"
"gorm.io/gen"
"gorm.io/gorm"
crossconversation "github.com/coze-dev/coze-studio/backend/crossdomain/contract/conversation"
"github.com/coze-dev/coze-studio/backend/domain/workflow"
"github.com/coze-dev/coze-studio/backend/domain/workflow/entity"
"github.com/coze-dev/coze-studio/backend/domain/workflow/entity/vo"
"github.com/coze-dev/coze-studio/backend/domain/workflow/internal/repo/dal/model"
"github.com/coze-dev/coze-studio/backend/pkg/lang/slices"
"github.com/coze-dev/coze-studio/backend/types/errno"
)
const batchSize = 10
func (r *RepositoryImpl) CreateDraftConversationTemplate(ctx context.Context, template *vo.CreateConversationTemplateMeta) (int64, error) {
id, err := r.GenID(ctx)
if err != nil {
return 0, vo.WrapError(errno.ErrIDGenError, err)
}
m := &model.AppConversationTemplateDraft{
ID: id,
AppID: template.AppID,
SpaceID: template.SpaceID,
Name: template.Name,
CreatorID: template.UserID,
TemplateID: id,
}
err = r.query.AppConversationTemplateDraft.WithContext(ctx).Create(m)
if err != nil {
return 0, vo.WrapError(errno.ErrDatabaseError, err)
}
return id, nil
}
func (r *RepositoryImpl) GetConversationTemplate(ctx context.Context, env vo.Env, policy vo.GetConversationTemplatePolicy) (*entity.ConversationTemplate, bool, error) {
var (
appID = policy.AppID
name = policy.Name
version = policy.Version
templateID = policy.TemplateID
)
conditions := make([]gen.Condition, 0)
if env == vo.Draft {
if appID != nil {
conditions = append(conditions, r.query.AppConversationTemplateDraft.AppID.Eq(*appID))
}
if name != nil {
conditions = append(conditions, r.query.AppConversationTemplateDraft.Name.Eq(*name))
}
if templateID != nil {
conditions = append(conditions, r.query.AppConversationTemplateDraft.TemplateID.Eq(*templateID))
}
template, err := r.query.AppConversationTemplateDraft.WithContext(ctx).Where(conditions...).First()
if err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return nil, false, nil
}
return nil, false, vo.WrapError(errno.ErrDatabaseError, err)
}
return &entity.ConversationTemplate{
AppID: template.AppID,
Name: template.Name,
TemplateID: template.TemplateID,
}, true, nil
} else if env == vo.Online {
if policy.Version == nil {
return nil, false, fmt.Errorf("need to set the version to query the online environment template")
}
conditions = append(conditions, r.query.AppConversationTemplateOnline.Version.Eq(*version))
if appID != nil {
conditions = append(conditions, r.query.AppConversationTemplateOnline.AppID.Eq(*appID))
}
if name != nil {
conditions = append(conditions, r.query.AppConversationTemplateOnline.Name.Eq(*name))
}
if templateID != nil {
conditions = append(conditions, r.query.AppConversationTemplateOnline.TemplateID.Eq(*templateID))
}
template, err := r.query.AppConversationTemplateOnline.WithContext(ctx).Where(conditions...).First()
if err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return nil, false, nil
}
return nil, false, err
}
return &entity.ConversationTemplate{
AppID: template.AppID,
Name: template.Name,
TemplateID: template.TemplateID,
}, true, nil
}
return nil, false, fmt.Errorf("unknown env %v", env)
}
func (r *RepositoryImpl) UpdateDraftConversationTemplateName(ctx context.Context, templateID int64, name string) error {
_, err := r.query.AppConversationTemplateDraft.WithContext(ctx).Where(
r.query.AppConversationTemplateDraft.TemplateID.Eq(templateID),
).UpdateColumnSimple(r.query.AppConversationTemplateDraft.Name.Value(name))
if err != nil {
return vo.WrapError(errno.ErrDatabaseError, err)
}
return nil
}
func (r *RepositoryImpl) DeleteDraftConversationTemplate(ctx context.Context, templateID int64) (int64, error) {
resultInfo, err := r.query.AppConversationTemplateDraft.WithContext(ctx).Where(
r.query.AppConversationTemplateDraft.TemplateID.Eq(templateID),
).Delete()
if err != nil {
return 0, vo.WrapError(errno.ErrDatabaseError, err)
}
return resultInfo.RowsAffected, nil
}
func (r *RepositoryImpl) DeleteDynamicConversation(ctx context.Context, env vo.Env, id int64) (int64, error) {
if env == vo.Draft {
info, err := r.query.AppDynamicConversationDraft.WithContext(ctx).Where(r.query.AppDynamicConversationDraft.ID.Eq(id)).Delete()
if err != nil {
return 0, vo.WrapError(errno.ErrDatabaseError, err)
}
return info.RowsAffected, nil
} else if env == vo.Online {
info, err := r.query.AppDynamicConversationOnline.WithContext(ctx).Where(r.query.AppDynamicConversationOnline.ID.Eq(id)).Delete()
if err != nil {
return 0, vo.WrapError(errno.ErrDatabaseError, err)
}
return info.RowsAffected, nil
} else {
return 0, fmt.Errorf("unknown env %v", env)
}
}
func (r *RepositoryImpl) ListConversationTemplate(ctx context.Context, env vo.Env, policy *vo.ListConversationTemplatePolicy) ([]*entity.ConversationTemplate, error) {
if env == vo.Draft {
return r.listDraftConversationTemplate(ctx, policy)
} else if env == vo.Online {
return r.listOnlineConversationTemplate(ctx, policy)
} else {
return nil, fmt.Errorf("unknown env %v", env)
}
}
func (r *RepositoryImpl) listDraftConversationTemplate(ctx context.Context, policy *vo.ListConversationTemplatePolicy) ([]*entity.ConversationTemplate, error) {
conditions := make([]gen.Condition, 0)
conditions = append(conditions, r.query.AppConversationTemplateDraft.AppID.Eq(policy.AppID))
if policy.NameLike != nil {
conditions = append(conditions, r.query.AppConversationTemplateDraft.Name.Like("%%"+*policy.NameLike+"%%"))
}
appConversationTemplateDraftDao := r.query.AppConversationTemplateDraft.WithContext(ctx)
var (
templates []*model.AppConversationTemplateDraft
err error
)
if policy.Page != nil {
templates, err = appConversationTemplateDraftDao.Where(conditions...).Offset(policy.Page.Offset()).Limit(policy.Page.Limit()).Find()
} else {
templates, err = appConversationTemplateDraftDao.Where(conditions...).Find()
}
if err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return []*entity.ConversationTemplate{}, nil
}
return nil, vo.WrapError(errno.ErrDatabaseError, err)
}
return slices.Transform(templates, func(a *model.AppConversationTemplateDraft) *entity.ConversationTemplate {
return &entity.ConversationTemplate{
SpaceID: a.SpaceID,
AppID: a.AppID,
Name: a.Name,
TemplateID: a.TemplateID,
}
}), nil
}
func (r *RepositoryImpl) listOnlineConversationTemplate(ctx context.Context, policy *vo.ListConversationTemplatePolicy) ([]*entity.ConversationTemplate, error) {
conditions := make([]gen.Condition, 0)
conditions = append(conditions, r.query.AppConversationTemplateOnline.AppID.Eq(policy.AppID))
if policy.Version == nil {
return nil, fmt.Errorf("list online template fail, version is required")
}
conditions = append(conditions, r.query.AppConversationTemplateOnline.Version.Eq(*policy.Version))
if policy.NameLike != nil {
conditions = append(conditions, r.query.AppConversationTemplateOnline.Name.Like("%%"+*policy.NameLike+"%%"))
}
appConversationTemplateOnlineDao := r.query.AppConversationTemplateOnline.WithContext(ctx)
var (
templates []*model.AppConversationTemplateOnline
err error
)
if policy.Page != nil {
templates, err = appConversationTemplateOnlineDao.Where(conditions...).Offset(policy.Page.Offset()).Limit(policy.Page.Limit()).Find()
} else {
templates, err = appConversationTemplateOnlineDao.Where(conditions...).Find()
}
if err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return []*entity.ConversationTemplate{}, nil
}
return nil, vo.WrapError(errno.ErrDatabaseError, err)
}
return slices.Transform(templates, func(a *model.AppConversationTemplateOnline) *entity.ConversationTemplate {
return &entity.ConversationTemplate{
SpaceID: a.SpaceID,
AppID: a.AppID,
Name: a.Name,
TemplateID: a.TemplateID,
}
}), nil
}
func (r *RepositoryImpl) MGetStaticConversation(ctx context.Context, env vo.Env, userID, connectorID int64, templateIDs []int64) ([]*entity.StaticConversation, error) {
if env == vo.Draft {
return r.mGetDraftStaticConversation(ctx, userID, connectorID, templateIDs)
} else if env == vo.Online {
return r.mGetOnlineStaticConversation(ctx, userID, connectorID, templateIDs)
} else {
return nil, fmt.Errorf("unknown env %v", env)
}
}
func (r *RepositoryImpl) mGetDraftStaticConversation(ctx context.Context, userID, connectorID int64, templateIDs []int64) ([]*entity.StaticConversation, error) {
conditions := make([]gen.Condition, 0, 3)
conditions = append(conditions, r.query.AppStaticConversationDraft.UserID.Eq(userID))
conditions = append(conditions, r.query.AppStaticConversationDraft.ConnectorID.Eq(connectorID))
if len(templateIDs) == 1 {
conditions = append(conditions, r.query.AppStaticConversationDraft.TemplateID.Eq(templateIDs[0]))
} else {
conditions = append(conditions, r.query.AppStaticConversationDraft.TemplateID.In(templateIDs...))
}
cs, err := r.query.AppStaticConversationDraft.WithContext(ctx).Where(conditions...).Find()
if err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return []*entity.StaticConversation{}, nil
}
return nil, vo.WrapError(errno.ErrDatabaseError, err)
}
return slices.Transform(cs, func(a *model.AppStaticConversationDraft) *entity.StaticConversation {
return &entity.StaticConversation{
TemplateID: a.TemplateID,
ConversationID: a.ConversationID,
UserID: a.UserID,
ConnectorID: a.ConnectorID,
}
}), nil
}
func (r *RepositoryImpl) mGetOnlineStaticConversation(ctx context.Context, userID, connectorID int64, templateIDs []int64) ([]*entity.StaticConversation, error) {
conditions := make([]gen.Condition, 0, 3)
conditions = append(conditions, r.query.AppStaticConversationOnline.UserID.Eq(userID))
conditions = append(conditions, r.query.AppStaticConversationOnline.ConnectorID.Eq(connectorID))
if len(templateIDs) == 1 {
conditions = append(conditions, r.query.AppStaticConversationOnline.TemplateID.Eq(templateIDs[0]))
} else {
conditions = append(conditions, r.query.AppStaticConversationOnline.TemplateID.In(templateIDs...))
}
cs, err := r.query.AppStaticConversationOnline.WithContext(ctx).Where(conditions...).Find()
if err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return []*entity.StaticConversation{}, nil
}
return nil, vo.WrapError(errno.ErrDatabaseError, err)
}
return slices.Transform(cs, func(a *model.AppStaticConversationOnline) *entity.StaticConversation {
return &entity.StaticConversation{
TemplateID: a.TemplateID,
ConversationID: a.ConversationID,
}
}), nil
}
func (r *RepositoryImpl) ListDynamicConversation(ctx context.Context, env vo.Env, policy *vo.ListConversationPolicy) ([]*entity.DynamicConversation, error) {
if env == vo.Draft {
return r.listDraftDynamicConversation(ctx, policy)
} else if env == vo.Online {
return r.listOnlineDynamicConversation(ctx, policy)
} else {
return nil, fmt.Errorf("unknown env %v", env)
}
}
func (r *RepositoryImpl) listDraftDynamicConversation(ctx context.Context, policy *vo.ListConversationPolicy) ([]*entity.DynamicConversation, error) {
var (
appID = policy.APPID
userID = policy.UserID
connectorID = policy.ConnectorID
)
conditions := make([]gen.Condition, 0)
conditions = append(conditions, r.query.AppDynamicConversationDraft.AppID.Eq(appID))
conditions = append(conditions, r.query.AppDynamicConversationDraft.UserID.Eq(userID))
conditions = append(conditions, r.query.AppDynamicConversationDraft.ConnectorID.Eq(connectorID))
if policy.NameLike != nil {
conditions = append(conditions, r.query.AppDynamicConversationDraft.Name.Like("%%"+*policy.NameLike+"%%"))
}
appDynamicConversationDraftDao := r.query.AppDynamicConversationDraft.WithContext(ctx).Where(conditions...)
var (
dynamicConversations = make([]*model.AppDynamicConversationDraft, 0)
err error
)
if policy.Page != nil {
dynamicConversations, err = appDynamicConversationDraftDao.Offset(policy.Page.Offset()).Limit(policy.Page.Limit()).Find()
} else {
dynamicConversations, err = appDynamicConversationDraftDao.Where(conditions...).Find()
}
if err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return []*entity.DynamicConversation{}, nil
}
return nil, vo.WrapError(errno.ErrDatabaseError, err)
}
return slices.Transform(dynamicConversations, func(a *model.AppDynamicConversationDraft) *entity.DynamicConversation {
return &entity.DynamicConversation{
ID: a.ID,
Name: a.Name,
UserID: a.UserID,
ConnectorID: a.ConnectorID,
ConversationID: a.ConversationID,
}
}), nil
}
func (r *RepositoryImpl) listOnlineDynamicConversation(ctx context.Context, policy *vo.ListConversationPolicy) ([]*entity.DynamicConversation, error) {
var (
appID = policy.APPID
userID = policy.UserID
connectorID = policy.ConnectorID
)
conditions := make([]gen.Condition, 0)
conditions = append(conditions, r.query.AppDynamicConversationOnline.AppID.Eq(appID))
conditions = append(conditions, r.query.AppDynamicConversationOnline.UserID.Eq(userID))
conditions = append(conditions, r.query.AppDynamicConversationOnline.AppID.Eq(appID))
conditions = append(conditions, r.query.AppDynamicConversationOnline.ConnectorID.Eq(connectorID))
if policy.NameLike != nil {
conditions = append(conditions, r.query.AppDynamicConversationOnline.Name.Like("%%"+*policy.NameLike+"%%"))
}
appDynamicConversationOnlineDao := r.query.AppDynamicConversationOnline.WithContext(ctx).Where(conditions...)
var (
dynamicConversations = make([]*model.AppDynamicConversationOnline, 0)
err error
)
if policy.Page != nil {
dynamicConversations, err = appDynamicConversationOnlineDao.Offset(policy.Page.Offset()).Limit(policy.Page.Limit()).Find()
} else {
dynamicConversations, err = appDynamicConversationOnlineDao.Where(conditions...).Find()
}
if err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return []*entity.DynamicConversation{}, nil
}
return nil, vo.WrapError(errno.ErrDatabaseError, err)
}
return slices.Transform(dynamicConversations, func(a *model.AppDynamicConversationOnline) *entity.DynamicConversation {
return &entity.DynamicConversation{
ID: a.ID,
Name: a.Name,
UserID: a.UserID,
ConnectorID: a.ConnectorID,
ConversationID: a.ConversationID,
}
}), nil
}
func (r *RepositoryImpl) GetOrCreateStaticConversation(ctx context.Context, env vo.Env, idGen workflow.ConversationIDGenerator, meta *vo.CreateStaticConversation) (int64, int64, bool, error) {
if env == vo.Draft {
return r.getOrCreateDraftStaticConversation(ctx, idGen, meta)
} else if env == vo.Online {
return r.getOrCreateOnlineStaticConversation(ctx, idGen, meta)
} else {
return 0, 0, false, fmt.Errorf("unknown env %v", env)
}
}
func (r *RepositoryImpl) GetOrCreateDynamicConversation(ctx context.Context, env vo.Env, idGen workflow.ConversationIDGenerator, meta *vo.CreateDynamicConversation) (int64, int64, bool, error) {
if env == vo.Draft {
appDynamicConversationDraft := r.query.AppDynamicConversationDraft
ret, err := appDynamicConversationDraft.WithContext(ctx).Where(
appDynamicConversationDraft.AppID.Eq(meta.AppID),
appDynamicConversationDraft.ConnectorID.Eq(meta.ConnectorID),
appDynamicConversationDraft.UserID.Eq(meta.UserID),
appDynamicConversationDraft.Name.Eq(meta.Name),
).First()
if err == nil {
cInfo, err := crossconversation.DefaultSVC().GetByID(ctx, ret.ConversationID)
if err != nil {
return 0, 0, false, vo.WrapError(errno.ErrDatabaseError, err)
}
return ret.ConversationID, cInfo.SectionID, true, nil
}
if !errors.Is(err, gorm.ErrRecordNotFound) {
return 0, 0, false, vo.WrapError(errno.ErrDatabaseError, err)
}
cID, sID, err := idGen(ctx, meta.AppID, meta.UserID, meta.ConnectorID)
if err != nil {
return 0, 0, false, err
}
id, err := r.GenID(ctx)
if err != nil {
return 0, 0, false, vo.WrapError(errno.ErrIDGenError, err)
}
err = r.query.AppDynamicConversationDraft.WithContext(ctx).Create(&model.AppDynamicConversationDraft{
ID: id,
AppID: meta.AppID,
Name: meta.Name,
UserID: meta.UserID,
ConnectorID: meta.ConnectorID,
ConversationID: cID,
})
if err != nil {
return 0, 0, false, vo.WrapError(errno.ErrDatabaseError, err)
}
return cID, sID, false, nil
} else if env == vo.Online {
appDynamicConversationOnline := r.query.AppDynamicConversationOnline
ret, err := appDynamicConversationOnline.WithContext(ctx).Where(
appDynamicConversationOnline.AppID.Eq(meta.AppID),
appDynamicConversationOnline.ConnectorID.Eq(meta.ConnectorID),
appDynamicConversationOnline.UserID.Eq(meta.UserID),
appDynamicConversationOnline.Name.Eq(meta.Name),
).First()
if err == nil {
cInfo, err := crossconversation.DefaultSVC().GetByID(ctx, ret.ConversationID)
if err != nil {
return 0, 0, false, vo.WrapError(errno.ErrDatabaseError, err)
}
return ret.ConversationID, cInfo.SectionID, true, nil
}
if !errors.Is(err, gorm.ErrRecordNotFound) {
return 0, 0, false, vo.WrapError(errno.ErrDatabaseError, err)
}
cID, sID, err := idGen(ctx, meta.AppID, meta.UserID, meta.ConnectorID)
if err != nil {
return 0, 0, false, err
}
id, err := r.GenID(ctx)
if err != nil {
return 0, 0, false, vo.WrapError(errno.ErrIDGenError, err)
}
err = r.query.AppDynamicConversationOnline.WithContext(ctx).Create(&model.AppDynamicConversationOnline{
ID: id,
AppID: meta.AppID,
Name: meta.Name,
UserID: meta.UserID,
ConnectorID: meta.ConnectorID,
ConversationID: cID,
})
if err != nil {
return 0, 0, false, vo.WrapError(errno.ErrDatabaseError, err)
}
return cID, sID, false, nil
} else {
return 0, 0, false, fmt.Errorf("unknown env %v", env)
}
}
func (r *RepositoryImpl) GetStaticConversationByTemplateID(ctx context.Context, env vo.Env, userID, connectorID, templateID int64) (*entity.StaticConversation, bool, error) {
if env == vo.Draft {
conditions := make([]gen.Condition, 0, 3)
conditions = append(conditions, r.query.AppStaticConversationDraft.UserID.Eq(userID))
conditions = append(conditions, r.query.AppStaticConversationDraft.ConnectorID.Eq(connectorID))
conditions = append(conditions, r.query.AppStaticConversationDraft.TemplateID.Eq(templateID))
cs, err := r.query.AppStaticConversationDraft.WithContext(ctx).Where(conditions...).First()
if err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return nil, false, nil
}
return nil, false, vo.WrapError(errno.ErrDatabaseError, err)
}
return &entity.StaticConversation{
UserID: cs.UserID,
ConnectorID: cs.ConnectorID,
TemplateID: cs.TemplateID,
ConversationID: cs.ConversationID,
}, true, nil
} else if env == vo.Online {
conditions := make([]gen.Condition, 0, 3)
conditions = append(conditions, r.query.AppStaticConversationOnline.UserID.Eq(userID))
conditions = append(conditions, r.query.AppStaticConversationOnline.ConnectorID.Eq(connectorID))
conditions = append(conditions, r.query.AppStaticConversationOnline.TemplateID.Eq(templateID))
cs, err := r.query.AppStaticConversationOnline.WithContext(ctx).Where(conditions...).First()
if err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return nil, false, nil
}
return nil, false, vo.WrapError(errno.ErrDatabaseError, err)
}
return &entity.StaticConversation{
UserID: cs.UserID,
ConnectorID: cs.ConnectorID,
TemplateID: cs.TemplateID,
ConversationID: cs.ConversationID,
}, true, nil
} else {
return nil, false, fmt.Errorf("unknown env %v", env)
}
}
func (r *RepositoryImpl) getOrCreateDraftStaticConversation(ctx context.Context, idGen workflow.ConversationIDGenerator, meta *vo.CreateStaticConversation) (int64, int64, bool, error) {
cs, err := r.mGetDraftStaticConversation(ctx, meta.UserID, meta.ConnectorID, []int64{meta.TemplateID})
if err != nil {
return 0, 0, false, vo.WrapError(errno.ErrDatabaseError, err)
}
if len(cs) > 0 {
cInfo, err := crossconversation.DefaultSVC().GetByID(ctx, cs[0].ConversationID)
if err != nil {
return 0, 0, false, vo.WrapError(errno.ErrDatabaseError, err)
}
return cs[0].ConversationID, cInfo.SectionID, true, nil
}
conversationID, sectionID, err := idGen(ctx, meta.AppID, meta.UserID, meta.ConnectorID)
if err != nil {
return 0, 0, false, err
}
id, err := r.GenID(ctx)
if err != nil {
return 0, 0, false, vo.WrapError(errno.ErrIDGenError, err)
}
object := &model.AppStaticConversationDraft{
ID: id,
UserID: meta.UserID,
ConnectorID: meta.ConnectorID,
TemplateID: meta.TemplateID,
ConversationID: conversationID,
}
err = r.query.AppStaticConversationDraft.WithContext(ctx).Create(object)
if err != nil {
return 0, 0, false, vo.WrapError(errno.ErrDatabaseError, err)
}
return conversationID, sectionID, false, nil
}
func (r *RepositoryImpl) getOrCreateOnlineStaticConversation(ctx context.Context, idGen workflow.ConversationIDGenerator, meta *vo.CreateStaticConversation) (int64, int64, bool, error) {
cs, err := r.mGetOnlineStaticConversation(ctx, meta.UserID, meta.ConnectorID, []int64{meta.TemplateID})
if err != nil {
return 0, 0, false, vo.WrapError(errno.ErrDatabaseError, err)
}
if len(cs) > 0 {
cInfo, err := crossconversation.DefaultSVC().GetByID(ctx, cs[0].ConversationID)
if err != nil {
return 0, 0, false, vo.WrapError(errno.ErrDatabaseError, err)
}
return cs[0].ConversationID, cInfo.SectionID, true, nil
}
conversationID, sectionID, err := idGen(ctx, meta.AppID, meta.UserID, meta.ConnectorID)
if err != nil {
return 0, 0, false, err
}
id, err := r.GenID(ctx)
if err != nil {
return 0, 0, false, vo.WrapError(errno.ErrIDGenError, err)
}
object := &model.AppStaticConversationOnline{
ID: id,
UserID: meta.UserID,
ConnectorID: meta.ConnectorID,
TemplateID: meta.TemplateID,
ConversationID: conversationID,
}
err = r.query.AppStaticConversationOnline.WithContext(ctx).Create(object)
if err != nil {
return 0, 0, false, vo.WrapError(errno.ErrDatabaseError, err)
}
return conversationID, sectionID, false, nil
}
func (r *RepositoryImpl) BatchCreateOnlineConversationTemplate(ctx context.Context, templates []*entity.ConversationTemplate, version string) error {
ids, err := r.GenMultiIDs(ctx, len(templates))
if err != nil {
return vo.WrapError(errno.ErrIDGenError, err)
}
objects := make([]*model.AppConversationTemplateOnline, 0, len(templates))
for idx := range templates {
template := templates[idx]
objects = append(objects, &model.AppConversationTemplateOnline{
ID: ids[idx],
SpaceID: template.SpaceID,
AppID: template.AppID,
TemplateID: template.TemplateID,
Name: template.Name,
Version: version,
})
}
err = r.query.AppConversationTemplateOnline.WithContext(ctx).CreateInBatches(objects, batchSize)
if err != nil {
return vo.WrapError(errno.ErrDatabaseError, err)
}
return nil
}
func (r *RepositoryImpl) GetDynamicConversationByName(ctx context.Context, env vo.Env, appID, connectorID, userID int64, name string) (*entity.DynamicConversation, bool, error) {
if env == vo.Draft {
appDynamicConversationDraft := r.query.AppDynamicConversationDraft
ret, err := appDynamicConversationDraft.WithContext(ctx).Where(
appDynamicConversationDraft.AppID.Eq(appID),
appDynamicConversationDraft.ConnectorID.Eq(connectorID),
appDynamicConversationDraft.UserID.Eq(userID),
appDynamicConversationDraft.Name.Eq(name)).First()
if err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return nil, false, nil
}
return nil, false, err
}
return &entity.DynamicConversation{
ID: ret.ID,
UserID: ret.UserID,
ConnectorID: ret.ConnectorID,
ConversationID: ret.ConversationID,
Name: ret.Name,
}, true, nil
} else if env == vo.Online {
appDynamicConversationOnline := r.query.AppDynamicConversationOnline
ret, err := appDynamicConversationOnline.WithContext(ctx).Where(
appDynamicConversationOnline.AppID.Eq(appID),
appDynamicConversationOnline.ConnectorID.Eq(connectorID),
appDynamicConversationOnline.UserID.Eq(userID),
appDynamicConversationOnline.Name.Eq(name)).First()
if err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return nil, false, nil
}
return nil, false, err
}
return &entity.DynamicConversation{
ID: ret.ID,
UserID: ret.UserID,
ConnectorID: ret.ConnectorID,
ConversationID: ret.ConversationID,
Name: ret.Name,
}, true, nil
} else {
return nil, false, fmt.Errorf("unknown env %v", env)
}
}
func (r *RepositoryImpl) UpdateDynamicConversationNameByID(ctx context.Context, env vo.Env, templateID int64, name string) error {
if env == vo.Draft {
appDynamicConversationDraft := r.query.AppDynamicConversationDraft
_, err := appDynamicConversationDraft.WithContext(ctx).Where(
appDynamicConversationDraft.ID.Eq(templateID),
).UpdateColumnSimple(appDynamicConversationDraft.Name.Value(name))
if err != nil {
return vo.WrapError(errno.ErrDatabaseError, err)
}
return nil
} else if env == vo.Online {
appDynamicConversationOnline := r.query.AppDynamicConversationOnline
_, err := appDynamicConversationOnline.WithContext(ctx).Where(
appDynamicConversationOnline.ID.Eq(templateID),
).UpdateColumnSimple(appDynamicConversationOnline.Name.Value(name))
if err != nil {
return vo.WrapError(errno.ErrDatabaseError, err)
}
return nil
} else {
return fmt.Errorf("unknown env %v", env)
}
}
func (r *RepositoryImpl) UpdateStaticConversation(ctx context.Context, env vo.Env, templateID int64, connectorID int64, userID int64, newConversationID int64) error {
if env == vo.Draft {
appStaticConversationDraft := r.query.AppStaticConversationDraft
_, err := appStaticConversationDraft.WithContext(ctx).Where(
appStaticConversationDraft.TemplateID.Eq(templateID),
appStaticConversationDraft.ConnectorID.Eq(connectorID),
appStaticConversationDraft.UserID.Eq(userID),
).UpdateColumn(appStaticConversationDraft.ConversationID, newConversationID)
if err != nil {
return err
}
return err
} else if env == vo.Online {
appStaticConversationOnline := r.query.AppStaticConversationOnline
_, err := appStaticConversationOnline.WithContext(ctx).Where(
appStaticConversationOnline.TemplateID.Eq(templateID),
appStaticConversationOnline.ConnectorID.Eq(connectorID),
appStaticConversationOnline.UserID.Eq(userID),
).UpdateColumn(appStaticConversationOnline.ConversationID, newConversationID)
if err != nil {
return err
}
return nil
} else {
return fmt.Errorf("unknown env %v", env)
}
}
func (r *RepositoryImpl) UpdateDynamicConversation(ctx context.Context, env vo.Env, conversationID, newConversationID int64) error {
if env == vo.Draft {
appDynamicConversationDraft := r.query.AppDynamicConversationDraft
_, err := appDynamicConversationDraft.WithContext(ctx).Where(appDynamicConversationDraft.ConversationID.Eq(conversationID)).
UpdateColumn(appDynamicConversationDraft.ConversationID, newConversationID)
if err != nil {
return err
}
return nil
} else if env == vo.Online {
appDynamicConversationOnline := r.query.AppDynamicConversationOnline
_, err := appDynamicConversationOnline.WithContext(ctx).Where(appDynamicConversationOnline.ConversationID.Eq(conversationID)).
UpdateColumn(appDynamicConversationOnline.ConversationID, newConversationID)
if err != nil {
return err
}
return nil
} else {
return fmt.Errorf("unknown env %v", env)
}
}

View File

@ -0,0 +1,29 @@
// Code generated by gorm.io/gen. DO NOT EDIT.
// Code generated by gorm.io/gen. DO NOT EDIT.
// Code generated by gorm.io/gen. DO NOT EDIT.
package model
import (
"gorm.io/gorm"
)
const TableNameAppConversationTemplateDraft = "app_conversation_template_draft"
// AppConversationTemplateDraft mapped from table <app_conversation_template_draft>
type AppConversationTemplateDraft struct {
ID int64 `gorm:"column:id;primaryKey;comment:id" json:"id"` // id
AppID int64 `gorm:"column:app_id;not null;comment:app id" json:"app_id"` // app id
SpaceID int64 `gorm:"column:space_id;not null;comment:space id" json:"space_id"` // space id
Name string `gorm:"column:name;not null;comment:conversion name" json:"name"` // conversion name
TemplateID int64 `gorm:"column:template_id;not null;comment:template id" json:"template_id"` // template id
CreatorID int64 `gorm:"column:creator_id;not null;comment:creator id" json:"creator_id"` // creator id
CreatedAt int64 `gorm:"column:created_at;not null;autoCreateTime:milli;comment:create time in millisecond" json:"created_at"` // create time in millisecond
UpdatedAt int64 `gorm:"column:updated_at;autoUpdateTime:milli;comment:update time in millisecond" json:"updated_at"` // update time in millisecond
DeletedAt gorm.DeletedAt `gorm:"column:deleted_at;comment:delete time in millisecond" json:"deleted_at"` // delete time in millisecond
}
// TableName AppConversationTemplateDraft's table name
func (*AppConversationTemplateDraft) TableName() string {
return TableNameAppConversationTemplateDraft
}

View File

@ -0,0 +1,24 @@
// Code generated by gorm.io/gen. DO NOT EDIT.
// Code generated by gorm.io/gen. DO NOT EDIT.
// Code generated by gorm.io/gen. DO NOT EDIT.
package model
const TableNameAppConversationTemplateOnline = "app_conversation_template_online"
// AppConversationTemplateOnline mapped from table <app_conversation_template_online>
type AppConversationTemplateOnline struct {
ID int64 `gorm:"column:id;primaryKey;comment:id" json:"id"` // id
AppID int64 `gorm:"column:app_id;not null;comment:app id" json:"app_id"` // app id
SpaceID int64 `gorm:"column:space_id;not null;comment:space id" json:"space_id"` // space id
Name string `gorm:"column:name;not null;comment:conversion name" json:"name"` // conversion name
TemplateID int64 `gorm:"column:template_id;not null;comment:template id" json:"template_id"` // template id
Version string `gorm:"column:version;not null;comment:version name" json:"version"` // version name
CreatorID int64 `gorm:"column:creator_id;not null;comment:creator id" json:"creator_id"` // creator id
CreatedAt int64 `gorm:"column:created_at;not null;autoCreateTime:milli;comment:create time in millisecond" json:"created_at"` // create time in millisecond
}
// TableName AppConversationTemplateOnline's table name
func (*AppConversationTemplateOnline) TableName() string {
return TableNameAppConversationTemplateOnline
}

View File

@ -0,0 +1,28 @@
// Code generated by gorm.io/gen. DO NOT EDIT.
// Code generated by gorm.io/gen. DO NOT EDIT.
// Code generated by gorm.io/gen. DO NOT EDIT.
package model
import (
"gorm.io/gorm"
)
const TableNameAppDynamicConversationDraft = "app_dynamic_conversation_draft"
// AppDynamicConversationDraft mapped from table <app_dynamic_conversation_draft>
type AppDynamicConversationDraft struct {
ID int64 `gorm:"column:id;primaryKey;comment:id" json:"id"` // id
AppID int64 `gorm:"column:app_id;not null;comment:app id" json:"app_id"` // app id
Name string `gorm:"column:name;not null;comment:conversion name" json:"name"` // conversion name
UserID int64 `gorm:"column:user_id;not null;comment:user id" json:"user_id"` // user id
ConnectorID int64 `gorm:"column:connector_id;not null;comment:connector id" json:"connector_id"` // connector id
ConversationID int64 `gorm:"column:conversation_id;not null;comment:conversation id" json:"conversation_id"` // conversation id
CreatedAt int64 `gorm:"column:created_at;not null;autoCreateTime:milli;comment:create time in millisecond" json:"created_at"` // create time in millisecond
DeletedAt gorm.DeletedAt `gorm:"column:deleted_at;comment:delete time in millisecond" json:"deleted_at"` // delete time in millisecond
}
// TableName AppDynamicConversationDraft's table name
func (*AppDynamicConversationDraft) TableName() string {
return TableNameAppDynamicConversationDraft
}

View File

@ -0,0 +1,28 @@
// Code generated by gorm.io/gen. DO NOT EDIT.
// Code generated by gorm.io/gen. DO NOT EDIT.
// Code generated by gorm.io/gen. DO NOT EDIT.
package model
import (
"gorm.io/gorm"
)
const TableNameAppDynamicConversationOnline = "app_dynamic_conversation_online"
// AppDynamicConversationOnline mapped from table <app_dynamic_conversation_online>
type AppDynamicConversationOnline struct {
ID int64 `gorm:"column:id;primaryKey;comment:id" json:"id"` // id
AppID int64 `gorm:"column:app_id;not null;comment:app id" json:"app_id"` // app id
Name string `gorm:"column:name;not null;comment:conversion name" json:"name"` // conversion name
UserID int64 `gorm:"column:user_id;not null;comment:user id" json:"user_id"` // user id
ConnectorID int64 `gorm:"column:connector_id;not null;comment:connector id" json:"connector_id"` // connector id
ConversationID int64 `gorm:"column:conversation_id;not null;comment:conversation id" json:"conversation_id"` // conversation id
CreatedAt int64 `gorm:"column:created_at;not null;autoCreateTime:milli;comment:create time in millisecond" json:"created_at"` // create time in millisecond
DeletedAt gorm.DeletedAt `gorm:"column:deleted_at;comment:delete time in millisecond" json:"deleted_at"` // delete time in millisecond
}
// TableName AppDynamicConversationOnline's table name
func (*AppDynamicConversationOnline) TableName() string {
return TableNameAppDynamicConversationOnline
}

View File

@ -0,0 +1,27 @@
// Code generated by gorm.io/gen. DO NOT EDIT.
// Code generated by gorm.io/gen. DO NOT EDIT.
// Code generated by gorm.io/gen. DO NOT EDIT.
package model
import (
"gorm.io/gorm"
)
const TableNameAppStaticConversationDraft = "app_static_conversation_draft"
// AppStaticConversationDraft mapped from table <app_static_conversation_draft>
type AppStaticConversationDraft struct {
ID int64 `gorm:"column:id;primaryKey;comment:id" json:"id"` // id
TemplateID int64 `gorm:"column:template_id;not null;comment:template id" json:"template_id"` // template id
UserID int64 `gorm:"column:user_id;not null;comment:user id" json:"user_id"` // user id
ConnectorID int64 `gorm:"column:connector_id;not null;comment:connector id" json:"connector_id"` // connector id
ConversationID int64 `gorm:"column:conversation_id;not null;comment:conversation id" json:"conversation_id"` // conversation id
CreatedAt int64 `gorm:"column:created_at;not null;autoCreateTime:milli;comment:create time in millisecond" json:"created_at"` // create time in millisecond
DeletedAt gorm.DeletedAt `gorm:"column:deleted_at;comment:delete time in millisecond" json:"deleted_at"` // delete time in millisecond
}
// TableName AppStaticConversationDraft's table name
func (*AppStaticConversationDraft) TableName() string {
return TableNameAppStaticConversationDraft
}

View File

@ -0,0 +1,22 @@
// Code generated by gorm.io/gen. DO NOT EDIT.
// Code generated by gorm.io/gen. DO NOT EDIT.
// Code generated by gorm.io/gen. DO NOT EDIT.
package model
const TableNameAppStaticConversationOnline = "app_static_conversation_online"
// AppStaticConversationOnline mapped from table <app_static_conversation_online>
type AppStaticConversationOnline struct {
ID int64 `gorm:"column:id;primaryKey;comment:id" json:"id"` // id
TemplateID int64 `gorm:"column:template_id;not null;comment:template id" json:"template_id"` // template id
UserID int64 `gorm:"column:user_id;not null;comment:user id" json:"user_id"` // user id
ConnectorID int64 `gorm:"column:connector_id;not null;comment:connector id" json:"connector_id"` // connector id
ConversationID int64 `gorm:"column:conversation_id;not null;comment:conversation id" json:"conversation_id"` // conversation id
CreatedAt int64 `gorm:"column:created_at;not null;autoCreateTime:milli;comment:create time in millisecond" json:"created_at"` // create time in millisecond
}
// TableName AppStaticConversationOnline's table name
func (*AppStaticConversationOnline) TableName() string {
return TableNameAppStaticConversationOnline
}

View File

@ -0,0 +1,36 @@
// Code generated by gorm.io/gen. DO NOT EDIT.
// Code generated by gorm.io/gen. DO NOT EDIT.
// Code generated by gorm.io/gen. DO NOT EDIT.
package model
import (
"gorm.io/gorm"
)
const TableNameChatFlowRoleConfig = "chat_flow_role_config"
// ChatFlowRoleConfig mapped from table <chat_flow_role_config>
type ChatFlowRoleConfig struct {
ID int64 `gorm:"column:id;primaryKey;comment:id" json:"id"` // id
WorkflowID int64 `gorm:"column:workflow_id;not null;comment:workflow id" json:"workflow_id"` // workflow id
Name string `gorm:"column:name;not null;comment:role name" json:"name"` // role name
Description string `gorm:"column:description;not null;comment:role description" json:"description"` // role description
Version string `gorm:"column:version;not null;comment:version" json:"version"` // version
Avatar string `gorm:"column:avatar;not null;comment:avatar uri" json:"avatar"` // avatar uri
BackgroundImageInfo string `gorm:"column:background_image_info;not null;comment:background image information, object structure" json:"background_image_info"` // background image information, object structure
OnboardingInfo string `gorm:"column:onboarding_info;not null;comment:intro information, object structure" json:"onboarding_info"` // intro information, object structure
SuggestReplyInfo string `gorm:"column:suggest_reply_info;not null;comment:user suggestions, object structure" json:"suggest_reply_info"` // user suggestions, object structure
AudioConfig string `gorm:"column:audio_config;not null;comment:agent audio config, object structure" json:"audio_config"` // agent audio config, object structure
UserInputConfig string `gorm:"column:user_input_config;not null;comment:user input config, object structure" json:"user_input_config"` // user input config, object structure
CreatorID int64 `gorm:"column:creator_id;not null;comment:creator id" json:"creator_id"` // creator id
CreatedAt int64 `gorm:"column:created_at;not null;autoCreateTime:milli;comment:create time in millisecond" json:"created_at"` // create time in millisecond
UpdatedAt int64 `gorm:"column:updated_at;autoUpdateTime:milli;comment:update time in millisecond" json:"updated_at"` // update time in millisecond
DeletedAt gorm.DeletedAt `gorm:"column:deleted_at;comment:delete time in millisecond" json:"deleted_at"` // delete time in millisecond
ConnectorID int64 `gorm:"column:connector_id;comment:connector id" json:"connector_id"` // connector id
}
// TableName ChatFlowRoleConfig's table name
func (*ChatFlowRoleConfig) TableName() string {
return TableNameChatFlowRoleConfig
}

View File

@ -0,0 +1,412 @@
// Code generated by gorm.io/gen. DO NOT EDIT.
// Code generated by gorm.io/gen. DO NOT EDIT.
// Code generated by gorm.io/gen. DO NOT EDIT.
package query
import (
"context"
"gorm.io/gorm"
"gorm.io/gorm/clause"
"gorm.io/gorm/schema"
"gorm.io/gen"
"gorm.io/gen/field"
"gorm.io/plugin/dbresolver"
"github.com/coze-dev/coze-studio/backend/domain/workflow/internal/repo/dal/model"
)
func newAppConversationTemplateDraft(db *gorm.DB, opts ...gen.DOOption) appConversationTemplateDraft {
_appConversationTemplateDraft := appConversationTemplateDraft{}
_appConversationTemplateDraft.appConversationTemplateDraftDo.UseDB(db, opts...)
_appConversationTemplateDraft.appConversationTemplateDraftDo.UseModel(&model.AppConversationTemplateDraft{})
tableName := _appConversationTemplateDraft.appConversationTemplateDraftDo.TableName()
_appConversationTemplateDraft.ALL = field.NewAsterisk(tableName)
_appConversationTemplateDraft.ID = field.NewInt64(tableName, "id")
_appConversationTemplateDraft.AppID = field.NewInt64(tableName, "app_id")
_appConversationTemplateDraft.SpaceID = field.NewInt64(tableName, "space_id")
_appConversationTemplateDraft.Name = field.NewString(tableName, "name")
_appConversationTemplateDraft.TemplateID = field.NewInt64(tableName, "template_id")
_appConversationTemplateDraft.CreatorID = field.NewInt64(tableName, "creator_id")
_appConversationTemplateDraft.CreatedAt = field.NewInt64(tableName, "created_at")
_appConversationTemplateDraft.UpdatedAt = field.NewInt64(tableName, "updated_at")
_appConversationTemplateDraft.DeletedAt = field.NewField(tableName, "deleted_at")
_appConversationTemplateDraft.fillFieldMap()
return _appConversationTemplateDraft
}
type appConversationTemplateDraft struct {
appConversationTemplateDraftDo
ALL field.Asterisk
ID field.Int64 // id
AppID field.Int64 // app id
SpaceID field.Int64 // space id
Name field.String // conversion name
TemplateID field.Int64 // template id
CreatorID field.Int64 // creator id
CreatedAt field.Int64 // create time in millisecond
UpdatedAt field.Int64 // update time in millisecond
DeletedAt field.Field // delete time in millisecond
fieldMap map[string]field.Expr
}
func (a appConversationTemplateDraft) Table(newTableName string) *appConversationTemplateDraft {
a.appConversationTemplateDraftDo.UseTable(newTableName)
return a.updateTableName(newTableName)
}
func (a appConversationTemplateDraft) As(alias string) *appConversationTemplateDraft {
a.appConversationTemplateDraftDo.DO = *(a.appConversationTemplateDraftDo.As(alias).(*gen.DO))
return a.updateTableName(alias)
}
func (a *appConversationTemplateDraft) updateTableName(table string) *appConversationTemplateDraft {
a.ALL = field.NewAsterisk(table)
a.ID = field.NewInt64(table, "id")
a.AppID = field.NewInt64(table, "app_id")
a.SpaceID = field.NewInt64(table, "space_id")
a.Name = field.NewString(table, "name")
a.TemplateID = field.NewInt64(table, "template_id")
a.CreatorID = field.NewInt64(table, "creator_id")
a.CreatedAt = field.NewInt64(table, "created_at")
a.UpdatedAt = field.NewInt64(table, "updated_at")
a.DeletedAt = field.NewField(table, "deleted_at")
a.fillFieldMap()
return a
}
func (a *appConversationTemplateDraft) GetFieldByName(fieldName string) (field.OrderExpr, bool) {
_f, ok := a.fieldMap[fieldName]
if !ok || _f == nil {
return nil, false
}
_oe, ok := _f.(field.OrderExpr)
return _oe, ok
}
func (a *appConversationTemplateDraft) fillFieldMap() {
a.fieldMap = make(map[string]field.Expr, 9)
a.fieldMap["id"] = a.ID
a.fieldMap["app_id"] = a.AppID
a.fieldMap["space_id"] = a.SpaceID
a.fieldMap["name"] = a.Name
a.fieldMap["template_id"] = a.TemplateID
a.fieldMap["creator_id"] = a.CreatorID
a.fieldMap["created_at"] = a.CreatedAt
a.fieldMap["updated_at"] = a.UpdatedAt
a.fieldMap["deleted_at"] = a.DeletedAt
}
func (a appConversationTemplateDraft) clone(db *gorm.DB) appConversationTemplateDraft {
a.appConversationTemplateDraftDo.ReplaceConnPool(db.Statement.ConnPool)
return a
}
func (a appConversationTemplateDraft) replaceDB(db *gorm.DB) appConversationTemplateDraft {
a.appConversationTemplateDraftDo.ReplaceDB(db)
return a
}
type appConversationTemplateDraftDo struct{ gen.DO }
type IAppConversationTemplateDraftDo interface {
gen.SubQuery
Debug() IAppConversationTemplateDraftDo
WithContext(ctx context.Context) IAppConversationTemplateDraftDo
WithResult(fc func(tx gen.Dao)) gen.ResultInfo
ReplaceDB(db *gorm.DB)
ReadDB() IAppConversationTemplateDraftDo
WriteDB() IAppConversationTemplateDraftDo
As(alias string) gen.Dao
Session(config *gorm.Session) IAppConversationTemplateDraftDo
Columns(cols ...field.Expr) gen.Columns
Clauses(conds ...clause.Expression) IAppConversationTemplateDraftDo
Not(conds ...gen.Condition) IAppConversationTemplateDraftDo
Or(conds ...gen.Condition) IAppConversationTemplateDraftDo
Select(conds ...field.Expr) IAppConversationTemplateDraftDo
Where(conds ...gen.Condition) IAppConversationTemplateDraftDo
Order(conds ...field.Expr) IAppConversationTemplateDraftDo
Distinct(cols ...field.Expr) IAppConversationTemplateDraftDo
Omit(cols ...field.Expr) IAppConversationTemplateDraftDo
Join(table schema.Tabler, on ...field.Expr) IAppConversationTemplateDraftDo
LeftJoin(table schema.Tabler, on ...field.Expr) IAppConversationTemplateDraftDo
RightJoin(table schema.Tabler, on ...field.Expr) IAppConversationTemplateDraftDo
Group(cols ...field.Expr) IAppConversationTemplateDraftDo
Having(conds ...gen.Condition) IAppConversationTemplateDraftDo
Limit(limit int) IAppConversationTemplateDraftDo
Offset(offset int) IAppConversationTemplateDraftDo
Count() (count int64, err error)
Scopes(funcs ...func(gen.Dao) gen.Dao) IAppConversationTemplateDraftDo
Unscoped() IAppConversationTemplateDraftDo
Create(values ...*model.AppConversationTemplateDraft) error
CreateInBatches(values []*model.AppConversationTemplateDraft, batchSize int) error
Save(values ...*model.AppConversationTemplateDraft) error
First() (*model.AppConversationTemplateDraft, error)
Take() (*model.AppConversationTemplateDraft, error)
Last() (*model.AppConversationTemplateDraft, error)
Find() ([]*model.AppConversationTemplateDraft, error)
FindInBatch(batchSize int, fc func(tx gen.Dao, batch int) error) (results []*model.AppConversationTemplateDraft, err error)
FindInBatches(result *[]*model.AppConversationTemplateDraft, batchSize int, fc func(tx gen.Dao, batch int) error) error
Pluck(column field.Expr, dest interface{}) error
Delete(...*model.AppConversationTemplateDraft) (info gen.ResultInfo, err error)
Update(column field.Expr, value interface{}) (info gen.ResultInfo, err error)
UpdateSimple(columns ...field.AssignExpr) (info gen.ResultInfo, err error)
Updates(value interface{}) (info gen.ResultInfo, err error)
UpdateColumn(column field.Expr, value interface{}) (info gen.ResultInfo, err error)
UpdateColumnSimple(columns ...field.AssignExpr) (info gen.ResultInfo, err error)
UpdateColumns(value interface{}) (info gen.ResultInfo, err error)
UpdateFrom(q gen.SubQuery) gen.Dao
Attrs(attrs ...field.AssignExpr) IAppConversationTemplateDraftDo
Assign(attrs ...field.AssignExpr) IAppConversationTemplateDraftDo
Joins(fields ...field.RelationField) IAppConversationTemplateDraftDo
Preload(fields ...field.RelationField) IAppConversationTemplateDraftDo
FirstOrInit() (*model.AppConversationTemplateDraft, error)
FirstOrCreate() (*model.AppConversationTemplateDraft, error)
FindByPage(offset int, limit int) (result []*model.AppConversationTemplateDraft, count int64, err error)
ScanByPage(result interface{}, offset int, limit int) (count int64, err error)
Scan(result interface{}) (err error)
Returning(value interface{}, columns ...string) IAppConversationTemplateDraftDo
UnderlyingDB() *gorm.DB
schema.Tabler
}
func (a appConversationTemplateDraftDo) Debug() IAppConversationTemplateDraftDo {
return a.withDO(a.DO.Debug())
}
func (a appConversationTemplateDraftDo) WithContext(ctx context.Context) IAppConversationTemplateDraftDo {
return a.withDO(a.DO.WithContext(ctx))
}
func (a appConversationTemplateDraftDo) ReadDB() IAppConversationTemplateDraftDo {
return a.Clauses(dbresolver.Read)
}
func (a appConversationTemplateDraftDo) WriteDB() IAppConversationTemplateDraftDo {
return a.Clauses(dbresolver.Write)
}
func (a appConversationTemplateDraftDo) Session(config *gorm.Session) IAppConversationTemplateDraftDo {
return a.withDO(a.DO.Session(config))
}
func (a appConversationTemplateDraftDo) Clauses(conds ...clause.Expression) IAppConversationTemplateDraftDo {
return a.withDO(a.DO.Clauses(conds...))
}
func (a appConversationTemplateDraftDo) Returning(value interface{}, columns ...string) IAppConversationTemplateDraftDo {
return a.withDO(a.DO.Returning(value, columns...))
}
func (a appConversationTemplateDraftDo) Not(conds ...gen.Condition) IAppConversationTemplateDraftDo {
return a.withDO(a.DO.Not(conds...))
}
func (a appConversationTemplateDraftDo) Or(conds ...gen.Condition) IAppConversationTemplateDraftDo {
return a.withDO(a.DO.Or(conds...))
}
func (a appConversationTemplateDraftDo) Select(conds ...field.Expr) IAppConversationTemplateDraftDo {
return a.withDO(a.DO.Select(conds...))
}
func (a appConversationTemplateDraftDo) Where(conds ...gen.Condition) IAppConversationTemplateDraftDo {
return a.withDO(a.DO.Where(conds...))
}
func (a appConversationTemplateDraftDo) Order(conds ...field.Expr) IAppConversationTemplateDraftDo {
return a.withDO(a.DO.Order(conds...))
}
func (a appConversationTemplateDraftDo) Distinct(cols ...field.Expr) IAppConversationTemplateDraftDo {
return a.withDO(a.DO.Distinct(cols...))
}
func (a appConversationTemplateDraftDo) Omit(cols ...field.Expr) IAppConversationTemplateDraftDo {
return a.withDO(a.DO.Omit(cols...))
}
func (a appConversationTemplateDraftDo) Join(table schema.Tabler, on ...field.Expr) IAppConversationTemplateDraftDo {
return a.withDO(a.DO.Join(table, on...))
}
func (a appConversationTemplateDraftDo) LeftJoin(table schema.Tabler, on ...field.Expr) IAppConversationTemplateDraftDo {
return a.withDO(a.DO.LeftJoin(table, on...))
}
func (a appConversationTemplateDraftDo) RightJoin(table schema.Tabler, on ...field.Expr) IAppConversationTemplateDraftDo {
return a.withDO(a.DO.RightJoin(table, on...))
}
func (a appConversationTemplateDraftDo) Group(cols ...field.Expr) IAppConversationTemplateDraftDo {
return a.withDO(a.DO.Group(cols...))
}
func (a appConversationTemplateDraftDo) Having(conds ...gen.Condition) IAppConversationTemplateDraftDo {
return a.withDO(a.DO.Having(conds...))
}
func (a appConversationTemplateDraftDo) Limit(limit int) IAppConversationTemplateDraftDo {
return a.withDO(a.DO.Limit(limit))
}
func (a appConversationTemplateDraftDo) Offset(offset int) IAppConversationTemplateDraftDo {
return a.withDO(a.DO.Offset(offset))
}
func (a appConversationTemplateDraftDo) Scopes(funcs ...func(gen.Dao) gen.Dao) IAppConversationTemplateDraftDo {
return a.withDO(a.DO.Scopes(funcs...))
}
func (a appConversationTemplateDraftDo) Unscoped() IAppConversationTemplateDraftDo {
return a.withDO(a.DO.Unscoped())
}
func (a appConversationTemplateDraftDo) Create(values ...*model.AppConversationTemplateDraft) error {
if len(values) == 0 {
return nil
}
return a.DO.Create(values)
}
func (a appConversationTemplateDraftDo) CreateInBatches(values []*model.AppConversationTemplateDraft, batchSize int) error {
return a.DO.CreateInBatches(values, batchSize)
}
// Save : !!! underlying implementation is different with GORM
// The method is equivalent to executing the statement: db.Clauses(clause.OnConflict{UpdateAll: true}).Create(values)
func (a appConversationTemplateDraftDo) Save(values ...*model.AppConversationTemplateDraft) error {
if len(values) == 0 {
return nil
}
return a.DO.Save(values)
}
func (a appConversationTemplateDraftDo) First() (*model.AppConversationTemplateDraft, error) {
if result, err := a.DO.First(); err != nil {
return nil, err
} else {
return result.(*model.AppConversationTemplateDraft), nil
}
}
func (a appConversationTemplateDraftDo) Take() (*model.AppConversationTemplateDraft, error) {
if result, err := a.DO.Take(); err != nil {
return nil, err
} else {
return result.(*model.AppConversationTemplateDraft), nil
}
}
func (a appConversationTemplateDraftDo) Last() (*model.AppConversationTemplateDraft, error) {
if result, err := a.DO.Last(); err != nil {
return nil, err
} else {
return result.(*model.AppConversationTemplateDraft), nil
}
}
func (a appConversationTemplateDraftDo) Find() ([]*model.AppConversationTemplateDraft, error) {
result, err := a.DO.Find()
return result.([]*model.AppConversationTemplateDraft), err
}
func (a appConversationTemplateDraftDo) FindInBatch(batchSize int, fc func(tx gen.Dao, batch int) error) (results []*model.AppConversationTemplateDraft, err error) {
buf := make([]*model.AppConversationTemplateDraft, 0, batchSize)
err = a.DO.FindInBatches(&buf, batchSize, func(tx gen.Dao, batch int) error {
defer func() { results = append(results, buf...) }()
return fc(tx, batch)
})
return results, err
}
func (a appConversationTemplateDraftDo) FindInBatches(result *[]*model.AppConversationTemplateDraft, batchSize int, fc func(tx gen.Dao, batch int) error) error {
return a.DO.FindInBatches(result, batchSize, fc)
}
func (a appConversationTemplateDraftDo) Attrs(attrs ...field.AssignExpr) IAppConversationTemplateDraftDo {
return a.withDO(a.DO.Attrs(attrs...))
}
func (a appConversationTemplateDraftDo) Assign(attrs ...field.AssignExpr) IAppConversationTemplateDraftDo {
return a.withDO(a.DO.Assign(attrs...))
}
func (a appConversationTemplateDraftDo) Joins(fields ...field.RelationField) IAppConversationTemplateDraftDo {
for _, _f := range fields {
a = *a.withDO(a.DO.Joins(_f))
}
return &a
}
func (a appConversationTemplateDraftDo) Preload(fields ...field.RelationField) IAppConversationTemplateDraftDo {
for _, _f := range fields {
a = *a.withDO(a.DO.Preload(_f))
}
return &a
}
func (a appConversationTemplateDraftDo) FirstOrInit() (*model.AppConversationTemplateDraft, error) {
if result, err := a.DO.FirstOrInit(); err != nil {
return nil, err
} else {
return result.(*model.AppConversationTemplateDraft), nil
}
}
func (a appConversationTemplateDraftDo) FirstOrCreate() (*model.AppConversationTemplateDraft, error) {
if result, err := a.DO.FirstOrCreate(); err != nil {
return nil, err
} else {
return result.(*model.AppConversationTemplateDraft), nil
}
}
func (a appConversationTemplateDraftDo) FindByPage(offset int, limit int) (result []*model.AppConversationTemplateDraft, count int64, err error) {
result, err = a.Offset(offset).Limit(limit).Find()
if err != nil {
return
}
if size := len(result); 0 < limit && 0 < size && size < limit {
count = int64(size + offset)
return
}
count, err = a.Offset(-1).Limit(-1).Count()
return
}
func (a appConversationTemplateDraftDo) ScanByPage(result interface{}, offset int, limit int) (count int64, err error) {
count, err = a.Count()
if err != nil {
return
}
err = a.Offset(offset).Limit(limit).Scan(result)
return
}
func (a appConversationTemplateDraftDo) Scan(result interface{}) (err error) {
return a.DO.Scan(result)
}
func (a appConversationTemplateDraftDo) Delete(models ...*model.AppConversationTemplateDraft) (result gen.ResultInfo, err error) {
return a.DO.Delete(models)
}
func (a *appConversationTemplateDraftDo) withDO(do gen.Dao) *appConversationTemplateDraftDo {
a.DO = *do.(*gen.DO)
return a
}

View File

@ -0,0 +1,408 @@
// Code generated by gorm.io/gen. DO NOT EDIT.
// Code generated by gorm.io/gen. DO NOT EDIT.
// Code generated by gorm.io/gen. DO NOT EDIT.
package query
import (
"context"
"gorm.io/gorm"
"gorm.io/gorm/clause"
"gorm.io/gorm/schema"
"gorm.io/gen"
"gorm.io/gen/field"
"gorm.io/plugin/dbresolver"
"github.com/coze-dev/coze-studio/backend/domain/workflow/internal/repo/dal/model"
)
func newAppConversationTemplateOnline(db *gorm.DB, opts ...gen.DOOption) appConversationTemplateOnline {
_appConversationTemplateOnline := appConversationTemplateOnline{}
_appConversationTemplateOnline.appConversationTemplateOnlineDo.UseDB(db, opts...)
_appConversationTemplateOnline.appConversationTemplateOnlineDo.UseModel(&model.AppConversationTemplateOnline{})
tableName := _appConversationTemplateOnline.appConversationTemplateOnlineDo.TableName()
_appConversationTemplateOnline.ALL = field.NewAsterisk(tableName)
_appConversationTemplateOnline.ID = field.NewInt64(tableName, "id")
_appConversationTemplateOnline.AppID = field.NewInt64(tableName, "app_id")
_appConversationTemplateOnline.SpaceID = field.NewInt64(tableName, "space_id")
_appConversationTemplateOnline.Name = field.NewString(tableName, "name")
_appConversationTemplateOnline.TemplateID = field.NewInt64(tableName, "template_id")
_appConversationTemplateOnline.Version = field.NewString(tableName, "version")
_appConversationTemplateOnline.CreatorID = field.NewInt64(tableName, "creator_id")
_appConversationTemplateOnline.CreatedAt = field.NewInt64(tableName, "created_at")
_appConversationTemplateOnline.fillFieldMap()
return _appConversationTemplateOnline
}
type appConversationTemplateOnline struct {
appConversationTemplateOnlineDo
ALL field.Asterisk
ID field.Int64 // id
AppID field.Int64 // app id
SpaceID field.Int64 // space id
Name field.String // conversion name
TemplateID field.Int64 // template id
Version field.String // version name
CreatorID field.Int64 // creator id
CreatedAt field.Int64 // create time in millisecond
fieldMap map[string]field.Expr
}
func (a appConversationTemplateOnline) Table(newTableName string) *appConversationTemplateOnline {
a.appConversationTemplateOnlineDo.UseTable(newTableName)
return a.updateTableName(newTableName)
}
func (a appConversationTemplateOnline) As(alias string) *appConversationTemplateOnline {
a.appConversationTemplateOnlineDo.DO = *(a.appConversationTemplateOnlineDo.As(alias).(*gen.DO))
return a.updateTableName(alias)
}
func (a *appConversationTemplateOnline) updateTableName(table string) *appConversationTemplateOnline {
a.ALL = field.NewAsterisk(table)
a.ID = field.NewInt64(table, "id")
a.AppID = field.NewInt64(table, "app_id")
a.SpaceID = field.NewInt64(table, "space_id")
a.Name = field.NewString(table, "name")
a.TemplateID = field.NewInt64(table, "template_id")
a.Version = field.NewString(table, "version")
a.CreatorID = field.NewInt64(table, "creator_id")
a.CreatedAt = field.NewInt64(table, "created_at")
a.fillFieldMap()
return a
}
func (a *appConversationTemplateOnline) GetFieldByName(fieldName string) (field.OrderExpr, bool) {
_f, ok := a.fieldMap[fieldName]
if !ok || _f == nil {
return nil, false
}
_oe, ok := _f.(field.OrderExpr)
return _oe, ok
}
func (a *appConversationTemplateOnline) fillFieldMap() {
a.fieldMap = make(map[string]field.Expr, 8)
a.fieldMap["id"] = a.ID
a.fieldMap["app_id"] = a.AppID
a.fieldMap["space_id"] = a.SpaceID
a.fieldMap["name"] = a.Name
a.fieldMap["template_id"] = a.TemplateID
a.fieldMap["version"] = a.Version
a.fieldMap["creator_id"] = a.CreatorID
a.fieldMap["created_at"] = a.CreatedAt
}
func (a appConversationTemplateOnline) clone(db *gorm.DB) appConversationTemplateOnline {
a.appConversationTemplateOnlineDo.ReplaceConnPool(db.Statement.ConnPool)
return a
}
func (a appConversationTemplateOnline) replaceDB(db *gorm.DB) appConversationTemplateOnline {
a.appConversationTemplateOnlineDo.ReplaceDB(db)
return a
}
type appConversationTemplateOnlineDo struct{ gen.DO }
type IAppConversationTemplateOnlineDo interface {
gen.SubQuery
Debug() IAppConversationTemplateOnlineDo
WithContext(ctx context.Context) IAppConversationTemplateOnlineDo
WithResult(fc func(tx gen.Dao)) gen.ResultInfo
ReplaceDB(db *gorm.DB)
ReadDB() IAppConversationTemplateOnlineDo
WriteDB() IAppConversationTemplateOnlineDo
As(alias string) gen.Dao
Session(config *gorm.Session) IAppConversationTemplateOnlineDo
Columns(cols ...field.Expr) gen.Columns
Clauses(conds ...clause.Expression) IAppConversationTemplateOnlineDo
Not(conds ...gen.Condition) IAppConversationTemplateOnlineDo
Or(conds ...gen.Condition) IAppConversationTemplateOnlineDo
Select(conds ...field.Expr) IAppConversationTemplateOnlineDo
Where(conds ...gen.Condition) IAppConversationTemplateOnlineDo
Order(conds ...field.Expr) IAppConversationTemplateOnlineDo
Distinct(cols ...field.Expr) IAppConversationTemplateOnlineDo
Omit(cols ...field.Expr) IAppConversationTemplateOnlineDo
Join(table schema.Tabler, on ...field.Expr) IAppConversationTemplateOnlineDo
LeftJoin(table schema.Tabler, on ...field.Expr) IAppConversationTemplateOnlineDo
RightJoin(table schema.Tabler, on ...field.Expr) IAppConversationTemplateOnlineDo
Group(cols ...field.Expr) IAppConversationTemplateOnlineDo
Having(conds ...gen.Condition) IAppConversationTemplateOnlineDo
Limit(limit int) IAppConversationTemplateOnlineDo
Offset(offset int) IAppConversationTemplateOnlineDo
Count() (count int64, err error)
Scopes(funcs ...func(gen.Dao) gen.Dao) IAppConversationTemplateOnlineDo
Unscoped() IAppConversationTemplateOnlineDo
Create(values ...*model.AppConversationTemplateOnline) error
CreateInBatches(values []*model.AppConversationTemplateOnline, batchSize int) error
Save(values ...*model.AppConversationTemplateOnline) error
First() (*model.AppConversationTemplateOnline, error)
Take() (*model.AppConversationTemplateOnline, error)
Last() (*model.AppConversationTemplateOnline, error)
Find() ([]*model.AppConversationTemplateOnline, error)
FindInBatch(batchSize int, fc func(tx gen.Dao, batch int) error) (results []*model.AppConversationTemplateOnline, err error)
FindInBatches(result *[]*model.AppConversationTemplateOnline, batchSize int, fc func(tx gen.Dao, batch int) error) error
Pluck(column field.Expr, dest interface{}) error
Delete(...*model.AppConversationTemplateOnline) (info gen.ResultInfo, err error)
Update(column field.Expr, value interface{}) (info gen.ResultInfo, err error)
UpdateSimple(columns ...field.AssignExpr) (info gen.ResultInfo, err error)
Updates(value interface{}) (info gen.ResultInfo, err error)
UpdateColumn(column field.Expr, value interface{}) (info gen.ResultInfo, err error)
UpdateColumnSimple(columns ...field.AssignExpr) (info gen.ResultInfo, err error)
UpdateColumns(value interface{}) (info gen.ResultInfo, err error)
UpdateFrom(q gen.SubQuery) gen.Dao
Attrs(attrs ...field.AssignExpr) IAppConversationTemplateOnlineDo
Assign(attrs ...field.AssignExpr) IAppConversationTemplateOnlineDo
Joins(fields ...field.RelationField) IAppConversationTemplateOnlineDo
Preload(fields ...field.RelationField) IAppConversationTemplateOnlineDo
FirstOrInit() (*model.AppConversationTemplateOnline, error)
FirstOrCreate() (*model.AppConversationTemplateOnline, error)
FindByPage(offset int, limit int) (result []*model.AppConversationTemplateOnline, count int64, err error)
ScanByPage(result interface{}, offset int, limit int) (count int64, err error)
Scan(result interface{}) (err error)
Returning(value interface{}, columns ...string) IAppConversationTemplateOnlineDo
UnderlyingDB() *gorm.DB
schema.Tabler
}
func (a appConversationTemplateOnlineDo) Debug() IAppConversationTemplateOnlineDo {
return a.withDO(a.DO.Debug())
}
func (a appConversationTemplateOnlineDo) WithContext(ctx context.Context) IAppConversationTemplateOnlineDo {
return a.withDO(a.DO.WithContext(ctx))
}
func (a appConversationTemplateOnlineDo) ReadDB() IAppConversationTemplateOnlineDo {
return a.Clauses(dbresolver.Read)
}
func (a appConversationTemplateOnlineDo) WriteDB() IAppConversationTemplateOnlineDo {
return a.Clauses(dbresolver.Write)
}
func (a appConversationTemplateOnlineDo) Session(config *gorm.Session) IAppConversationTemplateOnlineDo {
return a.withDO(a.DO.Session(config))
}
func (a appConversationTemplateOnlineDo) Clauses(conds ...clause.Expression) IAppConversationTemplateOnlineDo {
return a.withDO(a.DO.Clauses(conds...))
}
func (a appConversationTemplateOnlineDo) Returning(value interface{}, columns ...string) IAppConversationTemplateOnlineDo {
return a.withDO(a.DO.Returning(value, columns...))
}
func (a appConversationTemplateOnlineDo) Not(conds ...gen.Condition) IAppConversationTemplateOnlineDo {
return a.withDO(a.DO.Not(conds...))
}
func (a appConversationTemplateOnlineDo) Or(conds ...gen.Condition) IAppConversationTemplateOnlineDo {
return a.withDO(a.DO.Or(conds...))
}
func (a appConversationTemplateOnlineDo) Select(conds ...field.Expr) IAppConversationTemplateOnlineDo {
return a.withDO(a.DO.Select(conds...))
}
func (a appConversationTemplateOnlineDo) Where(conds ...gen.Condition) IAppConversationTemplateOnlineDo {
return a.withDO(a.DO.Where(conds...))
}
func (a appConversationTemplateOnlineDo) Order(conds ...field.Expr) IAppConversationTemplateOnlineDo {
return a.withDO(a.DO.Order(conds...))
}
func (a appConversationTemplateOnlineDo) Distinct(cols ...field.Expr) IAppConversationTemplateOnlineDo {
return a.withDO(a.DO.Distinct(cols...))
}
func (a appConversationTemplateOnlineDo) Omit(cols ...field.Expr) IAppConversationTemplateOnlineDo {
return a.withDO(a.DO.Omit(cols...))
}
func (a appConversationTemplateOnlineDo) Join(table schema.Tabler, on ...field.Expr) IAppConversationTemplateOnlineDo {
return a.withDO(a.DO.Join(table, on...))
}
func (a appConversationTemplateOnlineDo) LeftJoin(table schema.Tabler, on ...field.Expr) IAppConversationTemplateOnlineDo {
return a.withDO(a.DO.LeftJoin(table, on...))
}
func (a appConversationTemplateOnlineDo) RightJoin(table schema.Tabler, on ...field.Expr) IAppConversationTemplateOnlineDo {
return a.withDO(a.DO.RightJoin(table, on...))
}
func (a appConversationTemplateOnlineDo) Group(cols ...field.Expr) IAppConversationTemplateOnlineDo {
return a.withDO(a.DO.Group(cols...))
}
func (a appConversationTemplateOnlineDo) Having(conds ...gen.Condition) IAppConversationTemplateOnlineDo {
return a.withDO(a.DO.Having(conds...))
}
func (a appConversationTemplateOnlineDo) Limit(limit int) IAppConversationTemplateOnlineDo {
return a.withDO(a.DO.Limit(limit))
}
func (a appConversationTemplateOnlineDo) Offset(offset int) IAppConversationTemplateOnlineDo {
return a.withDO(a.DO.Offset(offset))
}
func (a appConversationTemplateOnlineDo) Scopes(funcs ...func(gen.Dao) gen.Dao) IAppConversationTemplateOnlineDo {
return a.withDO(a.DO.Scopes(funcs...))
}
func (a appConversationTemplateOnlineDo) Unscoped() IAppConversationTemplateOnlineDo {
return a.withDO(a.DO.Unscoped())
}
func (a appConversationTemplateOnlineDo) Create(values ...*model.AppConversationTemplateOnline) error {
if len(values) == 0 {
return nil
}
return a.DO.Create(values)
}
func (a appConversationTemplateOnlineDo) CreateInBatches(values []*model.AppConversationTemplateOnline, batchSize int) error {
return a.DO.CreateInBatches(values, batchSize)
}
// Save : !!! underlying implementation is different with GORM
// The method is equivalent to executing the statement: db.Clauses(clause.OnConflict{UpdateAll: true}).Create(values)
func (a appConversationTemplateOnlineDo) Save(values ...*model.AppConversationTemplateOnline) error {
if len(values) == 0 {
return nil
}
return a.DO.Save(values)
}
func (a appConversationTemplateOnlineDo) First() (*model.AppConversationTemplateOnline, error) {
if result, err := a.DO.First(); err != nil {
return nil, err
} else {
return result.(*model.AppConversationTemplateOnline), nil
}
}
func (a appConversationTemplateOnlineDo) Take() (*model.AppConversationTemplateOnline, error) {
if result, err := a.DO.Take(); err != nil {
return nil, err
} else {
return result.(*model.AppConversationTemplateOnline), nil
}
}
func (a appConversationTemplateOnlineDo) Last() (*model.AppConversationTemplateOnline, error) {
if result, err := a.DO.Last(); err != nil {
return nil, err
} else {
return result.(*model.AppConversationTemplateOnline), nil
}
}
func (a appConversationTemplateOnlineDo) Find() ([]*model.AppConversationTemplateOnline, error) {
result, err := a.DO.Find()
return result.([]*model.AppConversationTemplateOnline), err
}
func (a appConversationTemplateOnlineDo) FindInBatch(batchSize int, fc func(tx gen.Dao, batch int) error) (results []*model.AppConversationTemplateOnline, err error) {
buf := make([]*model.AppConversationTemplateOnline, 0, batchSize)
err = a.DO.FindInBatches(&buf, batchSize, func(tx gen.Dao, batch int) error {
defer func() { results = append(results, buf...) }()
return fc(tx, batch)
})
return results, err
}
func (a appConversationTemplateOnlineDo) FindInBatches(result *[]*model.AppConversationTemplateOnline, batchSize int, fc func(tx gen.Dao, batch int) error) error {
return a.DO.FindInBatches(result, batchSize, fc)
}
func (a appConversationTemplateOnlineDo) Attrs(attrs ...field.AssignExpr) IAppConversationTemplateOnlineDo {
return a.withDO(a.DO.Attrs(attrs...))
}
func (a appConversationTemplateOnlineDo) Assign(attrs ...field.AssignExpr) IAppConversationTemplateOnlineDo {
return a.withDO(a.DO.Assign(attrs...))
}
func (a appConversationTemplateOnlineDo) Joins(fields ...field.RelationField) IAppConversationTemplateOnlineDo {
for _, _f := range fields {
a = *a.withDO(a.DO.Joins(_f))
}
return &a
}
func (a appConversationTemplateOnlineDo) Preload(fields ...field.RelationField) IAppConversationTemplateOnlineDo {
for _, _f := range fields {
a = *a.withDO(a.DO.Preload(_f))
}
return &a
}
func (a appConversationTemplateOnlineDo) FirstOrInit() (*model.AppConversationTemplateOnline, error) {
if result, err := a.DO.FirstOrInit(); err != nil {
return nil, err
} else {
return result.(*model.AppConversationTemplateOnline), nil
}
}
func (a appConversationTemplateOnlineDo) FirstOrCreate() (*model.AppConversationTemplateOnline, error) {
if result, err := a.DO.FirstOrCreate(); err != nil {
return nil, err
} else {
return result.(*model.AppConversationTemplateOnline), nil
}
}
func (a appConversationTemplateOnlineDo) FindByPage(offset int, limit int) (result []*model.AppConversationTemplateOnline, count int64, err error) {
result, err = a.Offset(offset).Limit(limit).Find()
if err != nil {
return
}
if size := len(result); 0 < limit && 0 < size && size < limit {
count = int64(size + offset)
return
}
count, err = a.Offset(-1).Limit(-1).Count()
return
}
func (a appConversationTemplateOnlineDo) ScanByPage(result interface{}, offset int, limit int) (count int64, err error) {
count, err = a.Count()
if err != nil {
return
}
err = a.Offset(offset).Limit(limit).Scan(result)
return
}
func (a appConversationTemplateOnlineDo) Scan(result interface{}) (err error) {
return a.DO.Scan(result)
}
func (a appConversationTemplateOnlineDo) Delete(models ...*model.AppConversationTemplateOnline) (result gen.ResultInfo, err error) {
return a.DO.Delete(models)
}
func (a *appConversationTemplateOnlineDo) withDO(do gen.Dao) *appConversationTemplateOnlineDo {
a.DO = *do.(*gen.DO)
return a
}

View File

@ -0,0 +1,408 @@
// Code generated by gorm.io/gen. DO NOT EDIT.
// Code generated by gorm.io/gen. DO NOT EDIT.
// Code generated by gorm.io/gen. DO NOT EDIT.
package query
import (
"context"
"gorm.io/gorm"
"gorm.io/gorm/clause"
"gorm.io/gorm/schema"
"gorm.io/gen"
"gorm.io/gen/field"
"gorm.io/plugin/dbresolver"
"github.com/coze-dev/coze-studio/backend/domain/workflow/internal/repo/dal/model"
)
func newAppDynamicConversationDraft(db *gorm.DB, opts ...gen.DOOption) appDynamicConversationDraft {
_appDynamicConversationDraft := appDynamicConversationDraft{}
_appDynamicConversationDraft.appDynamicConversationDraftDo.UseDB(db, opts...)
_appDynamicConversationDraft.appDynamicConversationDraftDo.UseModel(&model.AppDynamicConversationDraft{})
tableName := _appDynamicConversationDraft.appDynamicConversationDraftDo.TableName()
_appDynamicConversationDraft.ALL = field.NewAsterisk(tableName)
_appDynamicConversationDraft.ID = field.NewInt64(tableName, "id")
_appDynamicConversationDraft.AppID = field.NewInt64(tableName, "app_id")
_appDynamicConversationDraft.Name = field.NewString(tableName, "name")
_appDynamicConversationDraft.UserID = field.NewInt64(tableName, "user_id")
_appDynamicConversationDraft.ConnectorID = field.NewInt64(tableName, "connector_id")
_appDynamicConversationDraft.ConversationID = field.NewInt64(tableName, "conversation_id")
_appDynamicConversationDraft.CreatedAt = field.NewInt64(tableName, "created_at")
_appDynamicConversationDraft.DeletedAt = field.NewField(tableName, "deleted_at")
_appDynamicConversationDraft.fillFieldMap()
return _appDynamicConversationDraft
}
type appDynamicConversationDraft struct {
appDynamicConversationDraftDo
ALL field.Asterisk
ID field.Int64 // id
AppID field.Int64 // app id
Name field.String // conversion name
UserID field.Int64 // user id
ConnectorID field.Int64 // connector id
ConversationID field.Int64 // conversation id
CreatedAt field.Int64 // create time in millisecond
DeletedAt field.Field // delete time in millisecond
fieldMap map[string]field.Expr
}
func (a appDynamicConversationDraft) Table(newTableName string) *appDynamicConversationDraft {
a.appDynamicConversationDraftDo.UseTable(newTableName)
return a.updateTableName(newTableName)
}
func (a appDynamicConversationDraft) As(alias string) *appDynamicConversationDraft {
a.appDynamicConversationDraftDo.DO = *(a.appDynamicConversationDraftDo.As(alias).(*gen.DO))
return a.updateTableName(alias)
}
func (a *appDynamicConversationDraft) updateTableName(table string) *appDynamicConversationDraft {
a.ALL = field.NewAsterisk(table)
a.ID = field.NewInt64(table, "id")
a.AppID = field.NewInt64(table, "app_id")
a.Name = field.NewString(table, "name")
a.UserID = field.NewInt64(table, "user_id")
a.ConnectorID = field.NewInt64(table, "connector_id")
a.ConversationID = field.NewInt64(table, "conversation_id")
a.CreatedAt = field.NewInt64(table, "created_at")
a.DeletedAt = field.NewField(table, "deleted_at")
a.fillFieldMap()
return a
}
func (a *appDynamicConversationDraft) GetFieldByName(fieldName string) (field.OrderExpr, bool) {
_f, ok := a.fieldMap[fieldName]
if !ok || _f == nil {
return nil, false
}
_oe, ok := _f.(field.OrderExpr)
return _oe, ok
}
func (a *appDynamicConversationDraft) fillFieldMap() {
a.fieldMap = make(map[string]field.Expr, 8)
a.fieldMap["id"] = a.ID
a.fieldMap["app_id"] = a.AppID
a.fieldMap["name"] = a.Name
a.fieldMap["user_id"] = a.UserID
a.fieldMap["connector_id"] = a.ConnectorID
a.fieldMap["conversation_id"] = a.ConversationID
a.fieldMap["created_at"] = a.CreatedAt
a.fieldMap["deleted_at"] = a.DeletedAt
}
func (a appDynamicConversationDraft) clone(db *gorm.DB) appDynamicConversationDraft {
a.appDynamicConversationDraftDo.ReplaceConnPool(db.Statement.ConnPool)
return a
}
func (a appDynamicConversationDraft) replaceDB(db *gorm.DB) appDynamicConversationDraft {
a.appDynamicConversationDraftDo.ReplaceDB(db)
return a
}
type appDynamicConversationDraftDo struct{ gen.DO }
type IAppDynamicConversationDraftDo interface {
gen.SubQuery
Debug() IAppDynamicConversationDraftDo
WithContext(ctx context.Context) IAppDynamicConversationDraftDo
WithResult(fc func(tx gen.Dao)) gen.ResultInfo
ReplaceDB(db *gorm.DB)
ReadDB() IAppDynamicConversationDraftDo
WriteDB() IAppDynamicConversationDraftDo
As(alias string) gen.Dao
Session(config *gorm.Session) IAppDynamicConversationDraftDo
Columns(cols ...field.Expr) gen.Columns
Clauses(conds ...clause.Expression) IAppDynamicConversationDraftDo
Not(conds ...gen.Condition) IAppDynamicConversationDraftDo
Or(conds ...gen.Condition) IAppDynamicConversationDraftDo
Select(conds ...field.Expr) IAppDynamicConversationDraftDo
Where(conds ...gen.Condition) IAppDynamicConversationDraftDo
Order(conds ...field.Expr) IAppDynamicConversationDraftDo
Distinct(cols ...field.Expr) IAppDynamicConversationDraftDo
Omit(cols ...field.Expr) IAppDynamicConversationDraftDo
Join(table schema.Tabler, on ...field.Expr) IAppDynamicConversationDraftDo
LeftJoin(table schema.Tabler, on ...field.Expr) IAppDynamicConversationDraftDo
RightJoin(table schema.Tabler, on ...field.Expr) IAppDynamicConversationDraftDo
Group(cols ...field.Expr) IAppDynamicConversationDraftDo
Having(conds ...gen.Condition) IAppDynamicConversationDraftDo
Limit(limit int) IAppDynamicConversationDraftDo
Offset(offset int) IAppDynamicConversationDraftDo
Count() (count int64, err error)
Scopes(funcs ...func(gen.Dao) gen.Dao) IAppDynamicConversationDraftDo
Unscoped() IAppDynamicConversationDraftDo
Create(values ...*model.AppDynamicConversationDraft) error
CreateInBatches(values []*model.AppDynamicConversationDraft, batchSize int) error
Save(values ...*model.AppDynamicConversationDraft) error
First() (*model.AppDynamicConversationDraft, error)
Take() (*model.AppDynamicConversationDraft, error)
Last() (*model.AppDynamicConversationDraft, error)
Find() ([]*model.AppDynamicConversationDraft, error)
FindInBatch(batchSize int, fc func(tx gen.Dao, batch int) error) (results []*model.AppDynamicConversationDraft, err error)
FindInBatches(result *[]*model.AppDynamicConversationDraft, batchSize int, fc func(tx gen.Dao, batch int) error) error
Pluck(column field.Expr, dest interface{}) error
Delete(...*model.AppDynamicConversationDraft) (info gen.ResultInfo, err error)
Update(column field.Expr, value interface{}) (info gen.ResultInfo, err error)
UpdateSimple(columns ...field.AssignExpr) (info gen.ResultInfo, err error)
Updates(value interface{}) (info gen.ResultInfo, err error)
UpdateColumn(column field.Expr, value interface{}) (info gen.ResultInfo, err error)
UpdateColumnSimple(columns ...field.AssignExpr) (info gen.ResultInfo, err error)
UpdateColumns(value interface{}) (info gen.ResultInfo, err error)
UpdateFrom(q gen.SubQuery) gen.Dao
Attrs(attrs ...field.AssignExpr) IAppDynamicConversationDraftDo
Assign(attrs ...field.AssignExpr) IAppDynamicConversationDraftDo
Joins(fields ...field.RelationField) IAppDynamicConversationDraftDo
Preload(fields ...field.RelationField) IAppDynamicConversationDraftDo
FirstOrInit() (*model.AppDynamicConversationDraft, error)
FirstOrCreate() (*model.AppDynamicConversationDraft, error)
FindByPage(offset int, limit int) (result []*model.AppDynamicConversationDraft, count int64, err error)
ScanByPage(result interface{}, offset int, limit int) (count int64, err error)
Scan(result interface{}) (err error)
Returning(value interface{}, columns ...string) IAppDynamicConversationDraftDo
UnderlyingDB() *gorm.DB
schema.Tabler
}
func (a appDynamicConversationDraftDo) Debug() IAppDynamicConversationDraftDo {
return a.withDO(a.DO.Debug())
}
func (a appDynamicConversationDraftDo) WithContext(ctx context.Context) IAppDynamicConversationDraftDo {
return a.withDO(a.DO.WithContext(ctx))
}
func (a appDynamicConversationDraftDo) ReadDB() IAppDynamicConversationDraftDo {
return a.Clauses(dbresolver.Read)
}
func (a appDynamicConversationDraftDo) WriteDB() IAppDynamicConversationDraftDo {
return a.Clauses(dbresolver.Write)
}
func (a appDynamicConversationDraftDo) Session(config *gorm.Session) IAppDynamicConversationDraftDo {
return a.withDO(a.DO.Session(config))
}
func (a appDynamicConversationDraftDo) Clauses(conds ...clause.Expression) IAppDynamicConversationDraftDo {
return a.withDO(a.DO.Clauses(conds...))
}
func (a appDynamicConversationDraftDo) Returning(value interface{}, columns ...string) IAppDynamicConversationDraftDo {
return a.withDO(a.DO.Returning(value, columns...))
}
func (a appDynamicConversationDraftDo) Not(conds ...gen.Condition) IAppDynamicConversationDraftDo {
return a.withDO(a.DO.Not(conds...))
}
func (a appDynamicConversationDraftDo) Or(conds ...gen.Condition) IAppDynamicConversationDraftDo {
return a.withDO(a.DO.Or(conds...))
}
func (a appDynamicConversationDraftDo) Select(conds ...field.Expr) IAppDynamicConversationDraftDo {
return a.withDO(a.DO.Select(conds...))
}
func (a appDynamicConversationDraftDo) Where(conds ...gen.Condition) IAppDynamicConversationDraftDo {
return a.withDO(a.DO.Where(conds...))
}
func (a appDynamicConversationDraftDo) Order(conds ...field.Expr) IAppDynamicConversationDraftDo {
return a.withDO(a.DO.Order(conds...))
}
func (a appDynamicConversationDraftDo) Distinct(cols ...field.Expr) IAppDynamicConversationDraftDo {
return a.withDO(a.DO.Distinct(cols...))
}
func (a appDynamicConversationDraftDo) Omit(cols ...field.Expr) IAppDynamicConversationDraftDo {
return a.withDO(a.DO.Omit(cols...))
}
func (a appDynamicConversationDraftDo) Join(table schema.Tabler, on ...field.Expr) IAppDynamicConversationDraftDo {
return a.withDO(a.DO.Join(table, on...))
}
func (a appDynamicConversationDraftDo) LeftJoin(table schema.Tabler, on ...field.Expr) IAppDynamicConversationDraftDo {
return a.withDO(a.DO.LeftJoin(table, on...))
}
func (a appDynamicConversationDraftDo) RightJoin(table schema.Tabler, on ...field.Expr) IAppDynamicConversationDraftDo {
return a.withDO(a.DO.RightJoin(table, on...))
}
func (a appDynamicConversationDraftDo) Group(cols ...field.Expr) IAppDynamicConversationDraftDo {
return a.withDO(a.DO.Group(cols...))
}
func (a appDynamicConversationDraftDo) Having(conds ...gen.Condition) IAppDynamicConversationDraftDo {
return a.withDO(a.DO.Having(conds...))
}
func (a appDynamicConversationDraftDo) Limit(limit int) IAppDynamicConversationDraftDo {
return a.withDO(a.DO.Limit(limit))
}
func (a appDynamicConversationDraftDo) Offset(offset int) IAppDynamicConversationDraftDo {
return a.withDO(a.DO.Offset(offset))
}
func (a appDynamicConversationDraftDo) Scopes(funcs ...func(gen.Dao) gen.Dao) IAppDynamicConversationDraftDo {
return a.withDO(a.DO.Scopes(funcs...))
}
func (a appDynamicConversationDraftDo) Unscoped() IAppDynamicConversationDraftDo {
return a.withDO(a.DO.Unscoped())
}
func (a appDynamicConversationDraftDo) Create(values ...*model.AppDynamicConversationDraft) error {
if len(values) == 0 {
return nil
}
return a.DO.Create(values)
}
func (a appDynamicConversationDraftDo) CreateInBatches(values []*model.AppDynamicConversationDraft, batchSize int) error {
return a.DO.CreateInBatches(values, batchSize)
}
// Save : !!! underlying implementation is different with GORM
// The method is equivalent to executing the statement: db.Clauses(clause.OnConflict{UpdateAll: true}).Create(values)
func (a appDynamicConversationDraftDo) Save(values ...*model.AppDynamicConversationDraft) error {
if len(values) == 0 {
return nil
}
return a.DO.Save(values)
}
func (a appDynamicConversationDraftDo) First() (*model.AppDynamicConversationDraft, error) {
if result, err := a.DO.First(); err != nil {
return nil, err
} else {
return result.(*model.AppDynamicConversationDraft), nil
}
}
func (a appDynamicConversationDraftDo) Take() (*model.AppDynamicConversationDraft, error) {
if result, err := a.DO.Take(); err != nil {
return nil, err
} else {
return result.(*model.AppDynamicConversationDraft), nil
}
}
func (a appDynamicConversationDraftDo) Last() (*model.AppDynamicConversationDraft, error) {
if result, err := a.DO.Last(); err != nil {
return nil, err
} else {
return result.(*model.AppDynamicConversationDraft), nil
}
}
func (a appDynamicConversationDraftDo) Find() ([]*model.AppDynamicConversationDraft, error) {
result, err := a.DO.Find()
return result.([]*model.AppDynamicConversationDraft), err
}
func (a appDynamicConversationDraftDo) FindInBatch(batchSize int, fc func(tx gen.Dao, batch int) error) (results []*model.AppDynamicConversationDraft, err error) {
buf := make([]*model.AppDynamicConversationDraft, 0, batchSize)
err = a.DO.FindInBatches(&buf, batchSize, func(tx gen.Dao, batch int) error {
defer func() { results = append(results, buf...) }()
return fc(tx, batch)
})
return results, err
}
func (a appDynamicConversationDraftDo) FindInBatches(result *[]*model.AppDynamicConversationDraft, batchSize int, fc func(tx gen.Dao, batch int) error) error {
return a.DO.FindInBatches(result, batchSize, fc)
}
func (a appDynamicConversationDraftDo) Attrs(attrs ...field.AssignExpr) IAppDynamicConversationDraftDo {
return a.withDO(a.DO.Attrs(attrs...))
}
func (a appDynamicConversationDraftDo) Assign(attrs ...field.AssignExpr) IAppDynamicConversationDraftDo {
return a.withDO(a.DO.Assign(attrs...))
}
func (a appDynamicConversationDraftDo) Joins(fields ...field.RelationField) IAppDynamicConversationDraftDo {
for _, _f := range fields {
a = *a.withDO(a.DO.Joins(_f))
}
return &a
}
func (a appDynamicConversationDraftDo) Preload(fields ...field.RelationField) IAppDynamicConversationDraftDo {
for _, _f := range fields {
a = *a.withDO(a.DO.Preload(_f))
}
return &a
}
func (a appDynamicConversationDraftDo) FirstOrInit() (*model.AppDynamicConversationDraft, error) {
if result, err := a.DO.FirstOrInit(); err != nil {
return nil, err
} else {
return result.(*model.AppDynamicConversationDraft), nil
}
}
func (a appDynamicConversationDraftDo) FirstOrCreate() (*model.AppDynamicConversationDraft, error) {
if result, err := a.DO.FirstOrCreate(); err != nil {
return nil, err
} else {
return result.(*model.AppDynamicConversationDraft), nil
}
}
func (a appDynamicConversationDraftDo) FindByPage(offset int, limit int) (result []*model.AppDynamicConversationDraft, count int64, err error) {
result, err = a.Offset(offset).Limit(limit).Find()
if err != nil {
return
}
if size := len(result); 0 < limit && 0 < size && size < limit {
count = int64(size + offset)
return
}
count, err = a.Offset(-1).Limit(-1).Count()
return
}
func (a appDynamicConversationDraftDo) ScanByPage(result interface{}, offset int, limit int) (count int64, err error) {
count, err = a.Count()
if err != nil {
return
}
err = a.Offset(offset).Limit(limit).Scan(result)
return
}
func (a appDynamicConversationDraftDo) Scan(result interface{}) (err error) {
return a.DO.Scan(result)
}
func (a appDynamicConversationDraftDo) Delete(models ...*model.AppDynamicConversationDraft) (result gen.ResultInfo, err error) {
return a.DO.Delete(models)
}
func (a *appDynamicConversationDraftDo) withDO(do gen.Dao) *appDynamicConversationDraftDo {
a.DO = *do.(*gen.DO)
return a
}

View File

@ -0,0 +1,408 @@
// Code generated by gorm.io/gen. DO NOT EDIT.
// Code generated by gorm.io/gen. DO NOT EDIT.
// Code generated by gorm.io/gen. DO NOT EDIT.
package query
import (
"context"
"gorm.io/gorm"
"gorm.io/gorm/clause"
"gorm.io/gorm/schema"
"gorm.io/gen"
"gorm.io/gen/field"
"gorm.io/plugin/dbresolver"
"github.com/coze-dev/coze-studio/backend/domain/workflow/internal/repo/dal/model"
)
func newAppDynamicConversationOnline(db *gorm.DB, opts ...gen.DOOption) appDynamicConversationOnline {
_appDynamicConversationOnline := appDynamicConversationOnline{}
_appDynamicConversationOnline.appDynamicConversationOnlineDo.UseDB(db, opts...)
_appDynamicConversationOnline.appDynamicConversationOnlineDo.UseModel(&model.AppDynamicConversationOnline{})
tableName := _appDynamicConversationOnline.appDynamicConversationOnlineDo.TableName()
_appDynamicConversationOnline.ALL = field.NewAsterisk(tableName)
_appDynamicConversationOnline.ID = field.NewInt64(tableName, "id")
_appDynamicConversationOnline.AppID = field.NewInt64(tableName, "app_id")
_appDynamicConversationOnline.Name = field.NewString(tableName, "name")
_appDynamicConversationOnline.UserID = field.NewInt64(tableName, "user_id")
_appDynamicConversationOnline.ConnectorID = field.NewInt64(tableName, "connector_id")
_appDynamicConversationOnline.ConversationID = field.NewInt64(tableName, "conversation_id")
_appDynamicConversationOnline.CreatedAt = field.NewInt64(tableName, "created_at")
_appDynamicConversationOnline.DeletedAt = field.NewField(tableName, "deleted_at")
_appDynamicConversationOnline.fillFieldMap()
return _appDynamicConversationOnline
}
type appDynamicConversationOnline struct {
appDynamicConversationOnlineDo
ALL field.Asterisk
ID field.Int64 // id
AppID field.Int64 // app id
Name field.String // conversion name
UserID field.Int64 // user id
ConnectorID field.Int64 // connector id
ConversationID field.Int64 // conversation id
CreatedAt field.Int64 // create time in millisecond
DeletedAt field.Field // delete time in millisecond
fieldMap map[string]field.Expr
}
func (a appDynamicConversationOnline) Table(newTableName string) *appDynamicConversationOnline {
a.appDynamicConversationOnlineDo.UseTable(newTableName)
return a.updateTableName(newTableName)
}
func (a appDynamicConversationOnline) As(alias string) *appDynamicConversationOnline {
a.appDynamicConversationOnlineDo.DO = *(a.appDynamicConversationOnlineDo.As(alias).(*gen.DO))
return a.updateTableName(alias)
}
func (a *appDynamicConversationOnline) updateTableName(table string) *appDynamicConversationOnline {
a.ALL = field.NewAsterisk(table)
a.ID = field.NewInt64(table, "id")
a.AppID = field.NewInt64(table, "app_id")
a.Name = field.NewString(table, "name")
a.UserID = field.NewInt64(table, "user_id")
a.ConnectorID = field.NewInt64(table, "connector_id")
a.ConversationID = field.NewInt64(table, "conversation_id")
a.CreatedAt = field.NewInt64(table, "created_at")
a.DeletedAt = field.NewField(table, "deleted_at")
a.fillFieldMap()
return a
}
func (a *appDynamicConversationOnline) GetFieldByName(fieldName string) (field.OrderExpr, bool) {
_f, ok := a.fieldMap[fieldName]
if !ok || _f == nil {
return nil, false
}
_oe, ok := _f.(field.OrderExpr)
return _oe, ok
}
func (a *appDynamicConversationOnline) fillFieldMap() {
a.fieldMap = make(map[string]field.Expr, 8)
a.fieldMap["id"] = a.ID
a.fieldMap["app_id"] = a.AppID
a.fieldMap["name"] = a.Name
a.fieldMap["user_id"] = a.UserID
a.fieldMap["connector_id"] = a.ConnectorID
a.fieldMap["conversation_id"] = a.ConversationID
a.fieldMap["created_at"] = a.CreatedAt
a.fieldMap["deleted_at"] = a.DeletedAt
}
func (a appDynamicConversationOnline) clone(db *gorm.DB) appDynamicConversationOnline {
a.appDynamicConversationOnlineDo.ReplaceConnPool(db.Statement.ConnPool)
return a
}
func (a appDynamicConversationOnline) replaceDB(db *gorm.DB) appDynamicConversationOnline {
a.appDynamicConversationOnlineDo.ReplaceDB(db)
return a
}
type appDynamicConversationOnlineDo struct{ gen.DO }
type IAppDynamicConversationOnlineDo interface {
gen.SubQuery
Debug() IAppDynamicConversationOnlineDo
WithContext(ctx context.Context) IAppDynamicConversationOnlineDo
WithResult(fc func(tx gen.Dao)) gen.ResultInfo
ReplaceDB(db *gorm.DB)
ReadDB() IAppDynamicConversationOnlineDo
WriteDB() IAppDynamicConversationOnlineDo
As(alias string) gen.Dao
Session(config *gorm.Session) IAppDynamicConversationOnlineDo
Columns(cols ...field.Expr) gen.Columns
Clauses(conds ...clause.Expression) IAppDynamicConversationOnlineDo
Not(conds ...gen.Condition) IAppDynamicConversationOnlineDo
Or(conds ...gen.Condition) IAppDynamicConversationOnlineDo
Select(conds ...field.Expr) IAppDynamicConversationOnlineDo
Where(conds ...gen.Condition) IAppDynamicConversationOnlineDo
Order(conds ...field.Expr) IAppDynamicConversationOnlineDo
Distinct(cols ...field.Expr) IAppDynamicConversationOnlineDo
Omit(cols ...field.Expr) IAppDynamicConversationOnlineDo
Join(table schema.Tabler, on ...field.Expr) IAppDynamicConversationOnlineDo
LeftJoin(table schema.Tabler, on ...field.Expr) IAppDynamicConversationOnlineDo
RightJoin(table schema.Tabler, on ...field.Expr) IAppDynamicConversationOnlineDo
Group(cols ...field.Expr) IAppDynamicConversationOnlineDo
Having(conds ...gen.Condition) IAppDynamicConversationOnlineDo
Limit(limit int) IAppDynamicConversationOnlineDo
Offset(offset int) IAppDynamicConversationOnlineDo
Count() (count int64, err error)
Scopes(funcs ...func(gen.Dao) gen.Dao) IAppDynamicConversationOnlineDo
Unscoped() IAppDynamicConversationOnlineDo
Create(values ...*model.AppDynamicConversationOnline) error
CreateInBatches(values []*model.AppDynamicConversationOnline, batchSize int) error
Save(values ...*model.AppDynamicConversationOnline) error
First() (*model.AppDynamicConversationOnline, error)
Take() (*model.AppDynamicConversationOnline, error)
Last() (*model.AppDynamicConversationOnline, error)
Find() ([]*model.AppDynamicConversationOnline, error)
FindInBatch(batchSize int, fc func(tx gen.Dao, batch int) error) (results []*model.AppDynamicConversationOnline, err error)
FindInBatches(result *[]*model.AppDynamicConversationOnline, batchSize int, fc func(tx gen.Dao, batch int) error) error
Pluck(column field.Expr, dest interface{}) error
Delete(...*model.AppDynamicConversationOnline) (info gen.ResultInfo, err error)
Update(column field.Expr, value interface{}) (info gen.ResultInfo, err error)
UpdateSimple(columns ...field.AssignExpr) (info gen.ResultInfo, err error)
Updates(value interface{}) (info gen.ResultInfo, err error)
UpdateColumn(column field.Expr, value interface{}) (info gen.ResultInfo, err error)
UpdateColumnSimple(columns ...field.AssignExpr) (info gen.ResultInfo, err error)
UpdateColumns(value interface{}) (info gen.ResultInfo, err error)
UpdateFrom(q gen.SubQuery) gen.Dao
Attrs(attrs ...field.AssignExpr) IAppDynamicConversationOnlineDo
Assign(attrs ...field.AssignExpr) IAppDynamicConversationOnlineDo
Joins(fields ...field.RelationField) IAppDynamicConversationOnlineDo
Preload(fields ...field.RelationField) IAppDynamicConversationOnlineDo
FirstOrInit() (*model.AppDynamicConversationOnline, error)
FirstOrCreate() (*model.AppDynamicConversationOnline, error)
FindByPage(offset int, limit int) (result []*model.AppDynamicConversationOnline, count int64, err error)
ScanByPage(result interface{}, offset int, limit int) (count int64, err error)
Scan(result interface{}) (err error)
Returning(value interface{}, columns ...string) IAppDynamicConversationOnlineDo
UnderlyingDB() *gorm.DB
schema.Tabler
}
func (a appDynamicConversationOnlineDo) Debug() IAppDynamicConversationOnlineDo {
return a.withDO(a.DO.Debug())
}
func (a appDynamicConversationOnlineDo) WithContext(ctx context.Context) IAppDynamicConversationOnlineDo {
return a.withDO(a.DO.WithContext(ctx))
}
func (a appDynamicConversationOnlineDo) ReadDB() IAppDynamicConversationOnlineDo {
return a.Clauses(dbresolver.Read)
}
func (a appDynamicConversationOnlineDo) WriteDB() IAppDynamicConversationOnlineDo {
return a.Clauses(dbresolver.Write)
}
func (a appDynamicConversationOnlineDo) Session(config *gorm.Session) IAppDynamicConversationOnlineDo {
return a.withDO(a.DO.Session(config))
}
func (a appDynamicConversationOnlineDo) Clauses(conds ...clause.Expression) IAppDynamicConversationOnlineDo {
return a.withDO(a.DO.Clauses(conds...))
}
func (a appDynamicConversationOnlineDo) Returning(value interface{}, columns ...string) IAppDynamicConversationOnlineDo {
return a.withDO(a.DO.Returning(value, columns...))
}
func (a appDynamicConversationOnlineDo) Not(conds ...gen.Condition) IAppDynamicConversationOnlineDo {
return a.withDO(a.DO.Not(conds...))
}
func (a appDynamicConversationOnlineDo) Or(conds ...gen.Condition) IAppDynamicConversationOnlineDo {
return a.withDO(a.DO.Or(conds...))
}
func (a appDynamicConversationOnlineDo) Select(conds ...field.Expr) IAppDynamicConversationOnlineDo {
return a.withDO(a.DO.Select(conds...))
}
func (a appDynamicConversationOnlineDo) Where(conds ...gen.Condition) IAppDynamicConversationOnlineDo {
return a.withDO(a.DO.Where(conds...))
}
func (a appDynamicConversationOnlineDo) Order(conds ...field.Expr) IAppDynamicConversationOnlineDo {
return a.withDO(a.DO.Order(conds...))
}
func (a appDynamicConversationOnlineDo) Distinct(cols ...field.Expr) IAppDynamicConversationOnlineDo {
return a.withDO(a.DO.Distinct(cols...))
}
func (a appDynamicConversationOnlineDo) Omit(cols ...field.Expr) IAppDynamicConversationOnlineDo {
return a.withDO(a.DO.Omit(cols...))
}
func (a appDynamicConversationOnlineDo) Join(table schema.Tabler, on ...field.Expr) IAppDynamicConversationOnlineDo {
return a.withDO(a.DO.Join(table, on...))
}
func (a appDynamicConversationOnlineDo) LeftJoin(table schema.Tabler, on ...field.Expr) IAppDynamicConversationOnlineDo {
return a.withDO(a.DO.LeftJoin(table, on...))
}
func (a appDynamicConversationOnlineDo) RightJoin(table schema.Tabler, on ...field.Expr) IAppDynamicConversationOnlineDo {
return a.withDO(a.DO.RightJoin(table, on...))
}
func (a appDynamicConversationOnlineDo) Group(cols ...field.Expr) IAppDynamicConversationOnlineDo {
return a.withDO(a.DO.Group(cols...))
}
func (a appDynamicConversationOnlineDo) Having(conds ...gen.Condition) IAppDynamicConversationOnlineDo {
return a.withDO(a.DO.Having(conds...))
}
func (a appDynamicConversationOnlineDo) Limit(limit int) IAppDynamicConversationOnlineDo {
return a.withDO(a.DO.Limit(limit))
}
func (a appDynamicConversationOnlineDo) Offset(offset int) IAppDynamicConversationOnlineDo {
return a.withDO(a.DO.Offset(offset))
}
func (a appDynamicConversationOnlineDo) Scopes(funcs ...func(gen.Dao) gen.Dao) IAppDynamicConversationOnlineDo {
return a.withDO(a.DO.Scopes(funcs...))
}
func (a appDynamicConversationOnlineDo) Unscoped() IAppDynamicConversationOnlineDo {
return a.withDO(a.DO.Unscoped())
}
func (a appDynamicConversationOnlineDo) Create(values ...*model.AppDynamicConversationOnline) error {
if len(values) == 0 {
return nil
}
return a.DO.Create(values)
}
func (a appDynamicConversationOnlineDo) CreateInBatches(values []*model.AppDynamicConversationOnline, batchSize int) error {
return a.DO.CreateInBatches(values, batchSize)
}
// Save : !!! underlying implementation is different with GORM
// The method is equivalent to executing the statement: db.Clauses(clause.OnConflict{UpdateAll: true}).Create(values)
func (a appDynamicConversationOnlineDo) Save(values ...*model.AppDynamicConversationOnline) error {
if len(values) == 0 {
return nil
}
return a.DO.Save(values)
}
func (a appDynamicConversationOnlineDo) First() (*model.AppDynamicConversationOnline, error) {
if result, err := a.DO.First(); err != nil {
return nil, err
} else {
return result.(*model.AppDynamicConversationOnline), nil
}
}
func (a appDynamicConversationOnlineDo) Take() (*model.AppDynamicConversationOnline, error) {
if result, err := a.DO.Take(); err != nil {
return nil, err
} else {
return result.(*model.AppDynamicConversationOnline), nil
}
}
func (a appDynamicConversationOnlineDo) Last() (*model.AppDynamicConversationOnline, error) {
if result, err := a.DO.Last(); err != nil {
return nil, err
} else {
return result.(*model.AppDynamicConversationOnline), nil
}
}
func (a appDynamicConversationOnlineDo) Find() ([]*model.AppDynamicConversationOnline, error) {
result, err := a.DO.Find()
return result.([]*model.AppDynamicConversationOnline), err
}
func (a appDynamicConversationOnlineDo) FindInBatch(batchSize int, fc func(tx gen.Dao, batch int) error) (results []*model.AppDynamicConversationOnline, err error) {
buf := make([]*model.AppDynamicConversationOnline, 0, batchSize)
err = a.DO.FindInBatches(&buf, batchSize, func(tx gen.Dao, batch int) error {
defer func() { results = append(results, buf...) }()
return fc(tx, batch)
})
return results, err
}
func (a appDynamicConversationOnlineDo) FindInBatches(result *[]*model.AppDynamicConversationOnline, batchSize int, fc func(tx gen.Dao, batch int) error) error {
return a.DO.FindInBatches(result, batchSize, fc)
}
func (a appDynamicConversationOnlineDo) Attrs(attrs ...field.AssignExpr) IAppDynamicConversationOnlineDo {
return a.withDO(a.DO.Attrs(attrs...))
}
func (a appDynamicConversationOnlineDo) Assign(attrs ...field.AssignExpr) IAppDynamicConversationOnlineDo {
return a.withDO(a.DO.Assign(attrs...))
}
func (a appDynamicConversationOnlineDo) Joins(fields ...field.RelationField) IAppDynamicConversationOnlineDo {
for _, _f := range fields {
a = *a.withDO(a.DO.Joins(_f))
}
return &a
}
func (a appDynamicConversationOnlineDo) Preload(fields ...field.RelationField) IAppDynamicConversationOnlineDo {
for _, _f := range fields {
a = *a.withDO(a.DO.Preload(_f))
}
return &a
}
func (a appDynamicConversationOnlineDo) FirstOrInit() (*model.AppDynamicConversationOnline, error) {
if result, err := a.DO.FirstOrInit(); err != nil {
return nil, err
} else {
return result.(*model.AppDynamicConversationOnline), nil
}
}
func (a appDynamicConversationOnlineDo) FirstOrCreate() (*model.AppDynamicConversationOnline, error) {
if result, err := a.DO.FirstOrCreate(); err != nil {
return nil, err
} else {
return result.(*model.AppDynamicConversationOnline), nil
}
}
func (a appDynamicConversationOnlineDo) FindByPage(offset int, limit int) (result []*model.AppDynamicConversationOnline, count int64, err error) {
result, err = a.Offset(offset).Limit(limit).Find()
if err != nil {
return
}
if size := len(result); 0 < limit && 0 < size && size < limit {
count = int64(size + offset)
return
}
count, err = a.Offset(-1).Limit(-1).Count()
return
}
func (a appDynamicConversationOnlineDo) ScanByPage(result interface{}, offset int, limit int) (count int64, err error) {
count, err = a.Count()
if err != nil {
return
}
err = a.Offset(offset).Limit(limit).Scan(result)
return
}
func (a appDynamicConversationOnlineDo) Scan(result interface{}) (err error) {
return a.DO.Scan(result)
}
func (a appDynamicConversationOnlineDo) Delete(models ...*model.AppDynamicConversationOnline) (result gen.ResultInfo, err error) {
return a.DO.Delete(models)
}
func (a *appDynamicConversationOnlineDo) withDO(do gen.Dao) *appDynamicConversationOnlineDo {
a.DO = *do.(*gen.DO)
return a
}

View File

@ -0,0 +1,404 @@
// Code generated by gorm.io/gen. DO NOT EDIT.
// Code generated by gorm.io/gen. DO NOT EDIT.
// Code generated by gorm.io/gen. DO NOT EDIT.
package query
import (
"context"
"gorm.io/gorm"
"gorm.io/gorm/clause"
"gorm.io/gorm/schema"
"gorm.io/gen"
"gorm.io/gen/field"
"gorm.io/plugin/dbresolver"
"github.com/coze-dev/coze-studio/backend/domain/workflow/internal/repo/dal/model"
)
func newAppStaticConversationDraft(db *gorm.DB, opts ...gen.DOOption) appStaticConversationDraft {
_appStaticConversationDraft := appStaticConversationDraft{}
_appStaticConversationDraft.appStaticConversationDraftDo.UseDB(db, opts...)
_appStaticConversationDraft.appStaticConversationDraftDo.UseModel(&model.AppStaticConversationDraft{})
tableName := _appStaticConversationDraft.appStaticConversationDraftDo.TableName()
_appStaticConversationDraft.ALL = field.NewAsterisk(tableName)
_appStaticConversationDraft.ID = field.NewInt64(tableName, "id")
_appStaticConversationDraft.TemplateID = field.NewInt64(tableName, "template_id")
_appStaticConversationDraft.UserID = field.NewInt64(tableName, "user_id")
_appStaticConversationDraft.ConnectorID = field.NewInt64(tableName, "connector_id")
_appStaticConversationDraft.ConversationID = field.NewInt64(tableName, "conversation_id")
_appStaticConversationDraft.CreatedAt = field.NewInt64(tableName, "created_at")
_appStaticConversationDraft.DeletedAt = field.NewField(tableName, "deleted_at")
_appStaticConversationDraft.fillFieldMap()
return _appStaticConversationDraft
}
type appStaticConversationDraft struct {
appStaticConversationDraftDo
ALL field.Asterisk
ID field.Int64 // id
TemplateID field.Int64 // template id
UserID field.Int64 // user id
ConnectorID field.Int64 // connector id
ConversationID field.Int64 // conversation id
CreatedAt field.Int64 // create time in millisecond
DeletedAt field.Field // delete time in millisecond
fieldMap map[string]field.Expr
}
func (a appStaticConversationDraft) Table(newTableName string) *appStaticConversationDraft {
a.appStaticConversationDraftDo.UseTable(newTableName)
return a.updateTableName(newTableName)
}
func (a appStaticConversationDraft) As(alias string) *appStaticConversationDraft {
a.appStaticConversationDraftDo.DO = *(a.appStaticConversationDraftDo.As(alias).(*gen.DO))
return a.updateTableName(alias)
}
func (a *appStaticConversationDraft) updateTableName(table string) *appStaticConversationDraft {
a.ALL = field.NewAsterisk(table)
a.ID = field.NewInt64(table, "id")
a.TemplateID = field.NewInt64(table, "template_id")
a.UserID = field.NewInt64(table, "user_id")
a.ConnectorID = field.NewInt64(table, "connector_id")
a.ConversationID = field.NewInt64(table, "conversation_id")
a.CreatedAt = field.NewInt64(table, "created_at")
a.DeletedAt = field.NewField(table, "deleted_at")
a.fillFieldMap()
return a
}
func (a *appStaticConversationDraft) GetFieldByName(fieldName string) (field.OrderExpr, bool) {
_f, ok := a.fieldMap[fieldName]
if !ok || _f == nil {
return nil, false
}
_oe, ok := _f.(field.OrderExpr)
return _oe, ok
}
func (a *appStaticConversationDraft) fillFieldMap() {
a.fieldMap = make(map[string]field.Expr, 7)
a.fieldMap["id"] = a.ID
a.fieldMap["template_id"] = a.TemplateID
a.fieldMap["user_id"] = a.UserID
a.fieldMap["connector_id"] = a.ConnectorID
a.fieldMap["conversation_id"] = a.ConversationID
a.fieldMap["created_at"] = a.CreatedAt
a.fieldMap["deleted_at"] = a.DeletedAt
}
func (a appStaticConversationDraft) clone(db *gorm.DB) appStaticConversationDraft {
a.appStaticConversationDraftDo.ReplaceConnPool(db.Statement.ConnPool)
return a
}
func (a appStaticConversationDraft) replaceDB(db *gorm.DB) appStaticConversationDraft {
a.appStaticConversationDraftDo.ReplaceDB(db)
return a
}
type appStaticConversationDraftDo struct{ gen.DO }
type IAppStaticConversationDraftDo interface {
gen.SubQuery
Debug() IAppStaticConversationDraftDo
WithContext(ctx context.Context) IAppStaticConversationDraftDo
WithResult(fc func(tx gen.Dao)) gen.ResultInfo
ReplaceDB(db *gorm.DB)
ReadDB() IAppStaticConversationDraftDo
WriteDB() IAppStaticConversationDraftDo
As(alias string) gen.Dao
Session(config *gorm.Session) IAppStaticConversationDraftDo
Columns(cols ...field.Expr) gen.Columns
Clauses(conds ...clause.Expression) IAppStaticConversationDraftDo
Not(conds ...gen.Condition) IAppStaticConversationDraftDo
Or(conds ...gen.Condition) IAppStaticConversationDraftDo
Select(conds ...field.Expr) IAppStaticConversationDraftDo
Where(conds ...gen.Condition) IAppStaticConversationDraftDo
Order(conds ...field.Expr) IAppStaticConversationDraftDo
Distinct(cols ...field.Expr) IAppStaticConversationDraftDo
Omit(cols ...field.Expr) IAppStaticConversationDraftDo
Join(table schema.Tabler, on ...field.Expr) IAppStaticConversationDraftDo
LeftJoin(table schema.Tabler, on ...field.Expr) IAppStaticConversationDraftDo
RightJoin(table schema.Tabler, on ...field.Expr) IAppStaticConversationDraftDo
Group(cols ...field.Expr) IAppStaticConversationDraftDo
Having(conds ...gen.Condition) IAppStaticConversationDraftDo
Limit(limit int) IAppStaticConversationDraftDo
Offset(offset int) IAppStaticConversationDraftDo
Count() (count int64, err error)
Scopes(funcs ...func(gen.Dao) gen.Dao) IAppStaticConversationDraftDo
Unscoped() IAppStaticConversationDraftDo
Create(values ...*model.AppStaticConversationDraft) error
CreateInBatches(values []*model.AppStaticConversationDraft, batchSize int) error
Save(values ...*model.AppStaticConversationDraft) error
First() (*model.AppStaticConversationDraft, error)
Take() (*model.AppStaticConversationDraft, error)
Last() (*model.AppStaticConversationDraft, error)
Find() ([]*model.AppStaticConversationDraft, error)
FindInBatch(batchSize int, fc func(tx gen.Dao, batch int) error) (results []*model.AppStaticConversationDraft, err error)
FindInBatches(result *[]*model.AppStaticConversationDraft, batchSize int, fc func(tx gen.Dao, batch int) error) error
Pluck(column field.Expr, dest interface{}) error
Delete(...*model.AppStaticConversationDraft) (info gen.ResultInfo, err error)
Update(column field.Expr, value interface{}) (info gen.ResultInfo, err error)
UpdateSimple(columns ...field.AssignExpr) (info gen.ResultInfo, err error)
Updates(value interface{}) (info gen.ResultInfo, err error)
UpdateColumn(column field.Expr, value interface{}) (info gen.ResultInfo, err error)
UpdateColumnSimple(columns ...field.AssignExpr) (info gen.ResultInfo, err error)
UpdateColumns(value interface{}) (info gen.ResultInfo, err error)
UpdateFrom(q gen.SubQuery) gen.Dao
Attrs(attrs ...field.AssignExpr) IAppStaticConversationDraftDo
Assign(attrs ...field.AssignExpr) IAppStaticConversationDraftDo
Joins(fields ...field.RelationField) IAppStaticConversationDraftDo
Preload(fields ...field.RelationField) IAppStaticConversationDraftDo
FirstOrInit() (*model.AppStaticConversationDraft, error)
FirstOrCreate() (*model.AppStaticConversationDraft, error)
FindByPage(offset int, limit int) (result []*model.AppStaticConversationDraft, count int64, err error)
ScanByPage(result interface{}, offset int, limit int) (count int64, err error)
Scan(result interface{}) (err error)
Returning(value interface{}, columns ...string) IAppStaticConversationDraftDo
UnderlyingDB() *gorm.DB
schema.Tabler
}
func (a appStaticConversationDraftDo) Debug() IAppStaticConversationDraftDo {
return a.withDO(a.DO.Debug())
}
func (a appStaticConversationDraftDo) WithContext(ctx context.Context) IAppStaticConversationDraftDo {
return a.withDO(a.DO.WithContext(ctx))
}
func (a appStaticConversationDraftDo) ReadDB() IAppStaticConversationDraftDo {
return a.Clauses(dbresolver.Read)
}
func (a appStaticConversationDraftDo) WriteDB() IAppStaticConversationDraftDo {
return a.Clauses(dbresolver.Write)
}
func (a appStaticConversationDraftDo) Session(config *gorm.Session) IAppStaticConversationDraftDo {
return a.withDO(a.DO.Session(config))
}
func (a appStaticConversationDraftDo) Clauses(conds ...clause.Expression) IAppStaticConversationDraftDo {
return a.withDO(a.DO.Clauses(conds...))
}
func (a appStaticConversationDraftDo) Returning(value interface{}, columns ...string) IAppStaticConversationDraftDo {
return a.withDO(a.DO.Returning(value, columns...))
}
func (a appStaticConversationDraftDo) Not(conds ...gen.Condition) IAppStaticConversationDraftDo {
return a.withDO(a.DO.Not(conds...))
}
func (a appStaticConversationDraftDo) Or(conds ...gen.Condition) IAppStaticConversationDraftDo {
return a.withDO(a.DO.Or(conds...))
}
func (a appStaticConversationDraftDo) Select(conds ...field.Expr) IAppStaticConversationDraftDo {
return a.withDO(a.DO.Select(conds...))
}
func (a appStaticConversationDraftDo) Where(conds ...gen.Condition) IAppStaticConversationDraftDo {
return a.withDO(a.DO.Where(conds...))
}
func (a appStaticConversationDraftDo) Order(conds ...field.Expr) IAppStaticConversationDraftDo {
return a.withDO(a.DO.Order(conds...))
}
func (a appStaticConversationDraftDo) Distinct(cols ...field.Expr) IAppStaticConversationDraftDo {
return a.withDO(a.DO.Distinct(cols...))
}
func (a appStaticConversationDraftDo) Omit(cols ...field.Expr) IAppStaticConversationDraftDo {
return a.withDO(a.DO.Omit(cols...))
}
func (a appStaticConversationDraftDo) Join(table schema.Tabler, on ...field.Expr) IAppStaticConversationDraftDo {
return a.withDO(a.DO.Join(table, on...))
}
func (a appStaticConversationDraftDo) LeftJoin(table schema.Tabler, on ...field.Expr) IAppStaticConversationDraftDo {
return a.withDO(a.DO.LeftJoin(table, on...))
}
func (a appStaticConversationDraftDo) RightJoin(table schema.Tabler, on ...field.Expr) IAppStaticConversationDraftDo {
return a.withDO(a.DO.RightJoin(table, on...))
}
func (a appStaticConversationDraftDo) Group(cols ...field.Expr) IAppStaticConversationDraftDo {
return a.withDO(a.DO.Group(cols...))
}
func (a appStaticConversationDraftDo) Having(conds ...gen.Condition) IAppStaticConversationDraftDo {
return a.withDO(a.DO.Having(conds...))
}
func (a appStaticConversationDraftDo) Limit(limit int) IAppStaticConversationDraftDo {
return a.withDO(a.DO.Limit(limit))
}
func (a appStaticConversationDraftDo) Offset(offset int) IAppStaticConversationDraftDo {
return a.withDO(a.DO.Offset(offset))
}
func (a appStaticConversationDraftDo) Scopes(funcs ...func(gen.Dao) gen.Dao) IAppStaticConversationDraftDo {
return a.withDO(a.DO.Scopes(funcs...))
}
func (a appStaticConversationDraftDo) Unscoped() IAppStaticConversationDraftDo {
return a.withDO(a.DO.Unscoped())
}
func (a appStaticConversationDraftDo) Create(values ...*model.AppStaticConversationDraft) error {
if len(values) == 0 {
return nil
}
return a.DO.Create(values)
}
func (a appStaticConversationDraftDo) CreateInBatches(values []*model.AppStaticConversationDraft, batchSize int) error {
return a.DO.CreateInBatches(values, batchSize)
}
// Save : !!! underlying implementation is different with GORM
// The method is equivalent to executing the statement: db.Clauses(clause.OnConflict{UpdateAll: true}).Create(values)
func (a appStaticConversationDraftDo) Save(values ...*model.AppStaticConversationDraft) error {
if len(values) == 0 {
return nil
}
return a.DO.Save(values)
}
func (a appStaticConversationDraftDo) First() (*model.AppStaticConversationDraft, error) {
if result, err := a.DO.First(); err != nil {
return nil, err
} else {
return result.(*model.AppStaticConversationDraft), nil
}
}
func (a appStaticConversationDraftDo) Take() (*model.AppStaticConversationDraft, error) {
if result, err := a.DO.Take(); err != nil {
return nil, err
} else {
return result.(*model.AppStaticConversationDraft), nil
}
}
func (a appStaticConversationDraftDo) Last() (*model.AppStaticConversationDraft, error) {
if result, err := a.DO.Last(); err != nil {
return nil, err
} else {
return result.(*model.AppStaticConversationDraft), nil
}
}
func (a appStaticConversationDraftDo) Find() ([]*model.AppStaticConversationDraft, error) {
result, err := a.DO.Find()
return result.([]*model.AppStaticConversationDraft), err
}
func (a appStaticConversationDraftDo) FindInBatch(batchSize int, fc func(tx gen.Dao, batch int) error) (results []*model.AppStaticConversationDraft, err error) {
buf := make([]*model.AppStaticConversationDraft, 0, batchSize)
err = a.DO.FindInBatches(&buf, batchSize, func(tx gen.Dao, batch int) error {
defer func() { results = append(results, buf...) }()
return fc(tx, batch)
})
return results, err
}
func (a appStaticConversationDraftDo) FindInBatches(result *[]*model.AppStaticConversationDraft, batchSize int, fc func(tx gen.Dao, batch int) error) error {
return a.DO.FindInBatches(result, batchSize, fc)
}
func (a appStaticConversationDraftDo) Attrs(attrs ...field.AssignExpr) IAppStaticConversationDraftDo {
return a.withDO(a.DO.Attrs(attrs...))
}
func (a appStaticConversationDraftDo) Assign(attrs ...field.AssignExpr) IAppStaticConversationDraftDo {
return a.withDO(a.DO.Assign(attrs...))
}
func (a appStaticConversationDraftDo) Joins(fields ...field.RelationField) IAppStaticConversationDraftDo {
for _, _f := range fields {
a = *a.withDO(a.DO.Joins(_f))
}
return &a
}
func (a appStaticConversationDraftDo) Preload(fields ...field.RelationField) IAppStaticConversationDraftDo {
for _, _f := range fields {
a = *a.withDO(a.DO.Preload(_f))
}
return &a
}
func (a appStaticConversationDraftDo) FirstOrInit() (*model.AppStaticConversationDraft, error) {
if result, err := a.DO.FirstOrInit(); err != nil {
return nil, err
} else {
return result.(*model.AppStaticConversationDraft), nil
}
}
func (a appStaticConversationDraftDo) FirstOrCreate() (*model.AppStaticConversationDraft, error) {
if result, err := a.DO.FirstOrCreate(); err != nil {
return nil, err
} else {
return result.(*model.AppStaticConversationDraft), nil
}
}
func (a appStaticConversationDraftDo) FindByPage(offset int, limit int) (result []*model.AppStaticConversationDraft, count int64, err error) {
result, err = a.Offset(offset).Limit(limit).Find()
if err != nil {
return
}
if size := len(result); 0 < limit && 0 < size && size < limit {
count = int64(size + offset)
return
}
count, err = a.Offset(-1).Limit(-1).Count()
return
}
func (a appStaticConversationDraftDo) ScanByPage(result interface{}, offset int, limit int) (count int64, err error) {
count, err = a.Count()
if err != nil {
return
}
err = a.Offset(offset).Limit(limit).Scan(result)
return
}
func (a appStaticConversationDraftDo) Scan(result interface{}) (err error) {
return a.DO.Scan(result)
}
func (a appStaticConversationDraftDo) Delete(models ...*model.AppStaticConversationDraft) (result gen.ResultInfo, err error) {
return a.DO.Delete(models)
}
func (a *appStaticConversationDraftDo) withDO(do gen.Dao) *appStaticConversationDraftDo {
a.DO = *do.(*gen.DO)
return a
}

View File

@ -0,0 +1,400 @@
// Code generated by gorm.io/gen. DO NOT EDIT.
// Code generated by gorm.io/gen. DO NOT EDIT.
// Code generated by gorm.io/gen. DO NOT EDIT.
package query
import (
"context"
"gorm.io/gorm"
"gorm.io/gorm/clause"
"gorm.io/gorm/schema"
"gorm.io/gen"
"gorm.io/gen/field"
"gorm.io/plugin/dbresolver"
"github.com/coze-dev/coze-studio/backend/domain/workflow/internal/repo/dal/model"
)
func newAppStaticConversationOnline(db *gorm.DB, opts ...gen.DOOption) appStaticConversationOnline {
_appStaticConversationOnline := appStaticConversationOnline{}
_appStaticConversationOnline.appStaticConversationOnlineDo.UseDB(db, opts...)
_appStaticConversationOnline.appStaticConversationOnlineDo.UseModel(&model.AppStaticConversationOnline{})
tableName := _appStaticConversationOnline.appStaticConversationOnlineDo.TableName()
_appStaticConversationOnline.ALL = field.NewAsterisk(tableName)
_appStaticConversationOnline.ID = field.NewInt64(tableName, "id")
_appStaticConversationOnline.TemplateID = field.NewInt64(tableName, "template_id")
_appStaticConversationOnline.UserID = field.NewInt64(tableName, "user_id")
_appStaticConversationOnline.ConnectorID = field.NewInt64(tableName, "connector_id")
_appStaticConversationOnline.ConversationID = field.NewInt64(tableName, "conversation_id")
_appStaticConversationOnline.CreatedAt = field.NewInt64(tableName, "created_at")
_appStaticConversationOnline.fillFieldMap()
return _appStaticConversationOnline
}
type appStaticConversationOnline struct {
appStaticConversationOnlineDo
ALL field.Asterisk
ID field.Int64 // id
TemplateID field.Int64 // template id
UserID field.Int64 // user id
ConnectorID field.Int64 // connector id
ConversationID field.Int64 // conversation id
CreatedAt field.Int64 // create time in millisecond
fieldMap map[string]field.Expr
}
func (a appStaticConversationOnline) Table(newTableName string) *appStaticConversationOnline {
a.appStaticConversationOnlineDo.UseTable(newTableName)
return a.updateTableName(newTableName)
}
func (a appStaticConversationOnline) As(alias string) *appStaticConversationOnline {
a.appStaticConversationOnlineDo.DO = *(a.appStaticConversationOnlineDo.As(alias).(*gen.DO))
return a.updateTableName(alias)
}
func (a *appStaticConversationOnline) updateTableName(table string) *appStaticConversationOnline {
a.ALL = field.NewAsterisk(table)
a.ID = field.NewInt64(table, "id")
a.TemplateID = field.NewInt64(table, "template_id")
a.UserID = field.NewInt64(table, "user_id")
a.ConnectorID = field.NewInt64(table, "connector_id")
a.ConversationID = field.NewInt64(table, "conversation_id")
a.CreatedAt = field.NewInt64(table, "created_at")
a.fillFieldMap()
return a
}
func (a *appStaticConversationOnline) GetFieldByName(fieldName string) (field.OrderExpr, bool) {
_f, ok := a.fieldMap[fieldName]
if !ok || _f == nil {
return nil, false
}
_oe, ok := _f.(field.OrderExpr)
return _oe, ok
}
func (a *appStaticConversationOnline) fillFieldMap() {
a.fieldMap = make(map[string]field.Expr, 6)
a.fieldMap["id"] = a.ID
a.fieldMap["template_id"] = a.TemplateID
a.fieldMap["user_id"] = a.UserID
a.fieldMap["connector_id"] = a.ConnectorID
a.fieldMap["conversation_id"] = a.ConversationID
a.fieldMap["created_at"] = a.CreatedAt
}
func (a appStaticConversationOnline) clone(db *gorm.DB) appStaticConversationOnline {
a.appStaticConversationOnlineDo.ReplaceConnPool(db.Statement.ConnPool)
return a
}
func (a appStaticConversationOnline) replaceDB(db *gorm.DB) appStaticConversationOnline {
a.appStaticConversationOnlineDo.ReplaceDB(db)
return a
}
type appStaticConversationOnlineDo struct{ gen.DO }
type IAppStaticConversationOnlineDo interface {
gen.SubQuery
Debug() IAppStaticConversationOnlineDo
WithContext(ctx context.Context) IAppStaticConversationOnlineDo
WithResult(fc func(tx gen.Dao)) gen.ResultInfo
ReplaceDB(db *gorm.DB)
ReadDB() IAppStaticConversationOnlineDo
WriteDB() IAppStaticConversationOnlineDo
As(alias string) gen.Dao
Session(config *gorm.Session) IAppStaticConversationOnlineDo
Columns(cols ...field.Expr) gen.Columns
Clauses(conds ...clause.Expression) IAppStaticConversationOnlineDo
Not(conds ...gen.Condition) IAppStaticConversationOnlineDo
Or(conds ...gen.Condition) IAppStaticConversationOnlineDo
Select(conds ...field.Expr) IAppStaticConversationOnlineDo
Where(conds ...gen.Condition) IAppStaticConversationOnlineDo
Order(conds ...field.Expr) IAppStaticConversationOnlineDo
Distinct(cols ...field.Expr) IAppStaticConversationOnlineDo
Omit(cols ...field.Expr) IAppStaticConversationOnlineDo
Join(table schema.Tabler, on ...field.Expr) IAppStaticConversationOnlineDo
LeftJoin(table schema.Tabler, on ...field.Expr) IAppStaticConversationOnlineDo
RightJoin(table schema.Tabler, on ...field.Expr) IAppStaticConversationOnlineDo
Group(cols ...field.Expr) IAppStaticConversationOnlineDo
Having(conds ...gen.Condition) IAppStaticConversationOnlineDo
Limit(limit int) IAppStaticConversationOnlineDo
Offset(offset int) IAppStaticConversationOnlineDo
Count() (count int64, err error)
Scopes(funcs ...func(gen.Dao) gen.Dao) IAppStaticConversationOnlineDo
Unscoped() IAppStaticConversationOnlineDo
Create(values ...*model.AppStaticConversationOnline) error
CreateInBatches(values []*model.AppStaticConversationOnline, batchSize int) error
Save(values ...*model.AppStaticConversationOnline) error
First() (*model.AppStaticConversationOnline, error)
Take() (*model.AppStaticConversationOnline, error)
Last() (*model.AppStaticConversationOnline, error)
Find() ([]*model.AppStaticConversationOnline, error)
FindInBatch(batchSize int, fc func(tx gen.Dao, batch int) error) (results []*model.AppStaticConversationOnline, err error)
FindInBatches(result *[]*model.AppStaticConversationOnline, batchSize int, fc func(tx gen.Dao, batch int) error) error
Pluck(column field.Expr, dest interface{}) error
Delete(...*model.AppStaticConversationOnline) (info gen.ResultInfo, err error)
Update(column field.Expr, value interface{}) (info gen.ResultInfo, err error)
UpdateSimple(columns ...field.AssignExpr) (info gen.ResultInfo, err error)
Updates(value interface{}) (info gen.ResultInfo, err error)
UpdateColumn(column field.Expr, value interface{}) (info gen.ResultInfo, err error)
UpdateColumnSimple(columns ...field.AssignExpr) (info gen.ResultInfo, err error)
UpdateColumns(value interface{}) (info gen.ResultInfo, err error)
UpdateFrom(q gen.SubQuery) gen.Dao
Attrs(attrs ...field.AssignExpr) IAppStaticConversationOnlineDo
Assign(attrs ...field.AssignExpr) IAppStaticConversationOnlineDo
Joins(fields ...field.RelationField) IAppStaticConversationOnlineDo
Preload(fields ...field.RelationField) IAppStaticConversationOnlineDo
FirstOrInit() (*model.AppStaticConversationOnline, error)
FirstOrCreate() (*model.AppStaticConversationOnline, error)
FindByPage(offset int, limit int) (result []*model.AppStaticConversationOnline, count int64, err error)
ScanByPage(result interface{}, offset int, limit int) (count int64, err error)
Scan(result interface{}) (err error)
Returning(value interface{}, columns ...string) IAppStaticConversationOnlineDo
UnderlyingDB() *gorm.DB
schema.Tabler
}
func (a appStaticConversationOnlineDo) Debug() IAppStaticConversationOnlineDo {
return a.withDO(a.DO.Debug())
}
func (a appStaticConversationOnlineDo) WithContext(ctx context.Context) IAppStaticConversationOnlineDo {
return a.withDO(a.DO.WithContext(ctx))
}
func (a appStaticConversationOnlineDo) ReadDB() IAppStaticConversationOnlineDo {
return a.Clauses(dbresolver.Read)
}
func (a appStaticConversationOnlineDo) WriteDB() IAppStaticConversationOnlineDo {
return a.Clauses(dbresolver.Write)
}
func (a appStaticConversationOnlineDo) Session(config *gorm.Session) IAppStaticConversationOnlineDo {
return a.withDO(a.DO.Session(config))
}
func (a appStaticConversationOnlineDo) Clauses(conds ...clause.Expression) IAppStaticConversationOnlineDo {
return a.withDO(a.DO.Clauses(conds...))
}
func (a appStaticConversationOnlineDo) Returning(value interface{}, columns ...string) IAppStaticConversationOnlineDo {
return a.withDO(a.DO.Returning(value, columns...))
}
func (a appStaticConversationOnlineDo) Not(conds ...gen.Condition) IAppStaticConversationOnlineDo {
return a.withDO(a.DO.Not(conds...))
}
func (a appStaticConversationOnlineDo) Or(conds ...gen.Condition) IAppStaticConversationOnlineDo {
return a.withDO(a.DO.Or(conds...))
}
func (a appStaticConversationOnlineDo) Select(conds ...field.Expr) IAppStaticConversationOnlineDo {
return a.withDO(a.DO.Select(conds...))
}
func (a appStaticConversationOnlineDo) Where(conds ...gen.Condition) IAppStaticConversationOnlineDo {
return a.withDO(a.DO.Where(conds...))
}
func (a appStaticConversationOnlineDo) Order(conds ...field.Expr) IAppStaticConversationOnlineDo {
return a.withDO(a.DO.Order(conds...))
}
func (a appStaticConversationOnlineDo) Distinct(cols ...field.Expr) IAppStaticConversationOnlineDo {
return a.withDO(a.DO.Distinct(cols...))
}
func (a appStaticConversationOnlineDo) Omit(cols ...field.Expr) IAppStaticConversationOnlineDo {
return a.withDO(a.DO.Omit(cols...))
}
func (a appStaticConversationOnlineDo) Join(table schema.Tabler, on ...field.Expr) IAppStaticConversationOnlineDo {
return a.withDO(a.DO.Join(table, on...))
}
func (a appStaticConversationOnlineDo) LeftJoin(table schema.Tabler, on ...field.Expr) IAppStaticConversationOnlineDo {
return a.withDO(a.DO.LeftJoin(table, on...))
}
func (a appStaticConversationOnlineDo) RightJoin(table schema.Tabler, on ...field.Expr) IAppStaticConversationOnlineDo {
return a.withDO(a.DO.RightJoin(table, on...))
}
func (a appStaticConversationOnlineDo) Group(cols ...field.Expr) IAppStaticConversationOnlineDo {
return a.withDO(a.DO.Group(cols...))
}
func (a appStaticConversationOnlineDo) Having(conds ...gen.Condition) IAppStaticConversationOnlineDo {
return a.withDO(a.DO.Having(conds...))
}
func (a appStaticConversationOnlineDo) Limit(limit int) IAppStaticConversationOnlineDo {
return a.withDO(a.DO.Limit(limit))
}
func (a appStaticConversationOnlineDo) Offset(offset int) IAppStaticConversationOnlineDo {
return a.withDO(a.DO.Offset(offset))
}
func (a appStaticConversationOnlineDo) Scopes(funcs ...func(gen.Dao) gen.Dao) IAppStaticConversationOnlineDo {
return a.withDO(a.DO.Scopes(funcs...))
}
func (a appStaticConversationOnlineDo) Unscoped() IAppStaticConversationOnlineDo {
return a.withDO(a.DO.Unscoped())
}
func (a appStaticConversationOnlineDo) Create(values ...*model.AppStaticConversationOnline) error {
if len(values) == 0 {
return nil
}
return a.DO.Create(values)
}
func (a appStaticConversationOnlineDo) CreateInBatches(values []*model.AppStaticConversationOnline, batchSize int) error {
return a.DO.CreateInBatches(values, batchSize)
}
// Save : !!! underlying implementation is different with GORM
// The method is equivalent to executing the statement: db.Clauses(clause.OnConflict{UpdateAll: true}).Create(values)
func (a appStaticConversationOnlineDo) Save(values ...*model.AppStaticConversationOnline) error {
if len(values) == 0 {
return nil
}
return a.DO.Save(values)
}
func (a appStaticConversationOnlineDo) First() (*model.AppStaticConversationOnline, error) {
if result, err := a.DO.First(); err != nil {
return nil, err
} else {
return result.(*model.AppStaticConversationOnline), nil
}
}
func (a appStaticConversationOnlineDo) Take() (*model.AppStaticConversationOnline, error) {
if result, err := a.DO.Take(); err != nil {
return nil, err
} else {
return result.(*model.AppStaticConversationOnline), nil
}
}
func (a appStaticConversationOnlineDo) Last() (*model.AppStaticConversationOnline, error) {
if result, err := a.DO.Last(); err != nil {
return nil, err
} else {
return result.(*model.AppStaticConversationOnline), nil
}
}
func (a appStaticConversationOnlineDo) Find() ([]*model.AppStaticConversationOnline, error) {
result, err := a.DO.Find()
return result.([]*model.AppStaticConversationOnline), err
}
func (a appStaticConversationOnlineDo) FindInBatch(batchSize int, fc func(tx gen.Dao, batch int) error) (results []*model.AppStaticConversationOnline, err error) {
buf := make([]*model.AppStaticConversationOnline, 0, batchSize)
err = a.DO.FindInBatches(&buf, batchSize, func(tx gen.Dao, batch int) error {
defer func() { results = append(results, buf...) }()
return fc(tx, batch)
})
return results, err
}
func (a appStaticConversationOnlineDo) FindInBatches(result *[]*model.AppStaticConversationOnline, batchSize int, fc func(tx gen.Dao, batch int) error) error {
return a.DO.FindInBatches(result, batchSize, fc)
}
func (a appStaticConversationOnlineDo) Attrs(attrs ...field.AssignExpr) IAppStaticConversationOnlineDo {
return a.withDO(a.DO.Attrs(attrs...))
}
func (a appStaticConversationOnlineDo) Assign(attrs ...field.AssignExpr) IAppStaticConversationOnlineDo {
return a.withDO(a.DO.Assign(attrs...))
}
func (a appStaticConversationOnlineDo) Joins(fields ...field.RelationField) IAppStaticConversationOnlineDo {
for _, _f := range fields {
a = *a.withDO(a.DO.Joins(_f))
}
return &a
}
func (a appStaticConversationOnlineDo) Preload(fields ...field.RelationField) IAppStaticConversationOnlineDo {
for _, _f := range fields {
a = *a.withDO(a.DO.Preload(_f))
}
return &a
}
func (a appStaticConversationOnlineDo) FirstOrInit() (*model.AppStaticConversationOnline, error) {
if result, err := a.DO.FirstOrInit(); err != nil {
return nil, err
} else {
return result.(*model.AppStaticConversationOnline), nil
}
}
func (a appStaticConversationOnlineDo) FirstOrCreate() (*model.AppStaticConversationOnline, error) {
if result, err := a.DO.FirstOrCreate(); err != nil {
return nil, err
} else {
return result.(*model.AppStaticConversationOnline), nil
}
}
func (a appStaticConversationOnlineDo) FindByPage(offset int, limit int) (result []*model.AppStaticConversationOnline, count int64, err error) {
result, err = a.Offset(offset).Limit(limit).Find()
if err != nil {
return
}
if size := len(result); 0 < limit && 0 < size && size < limit {
count = int64(size + offset)
return
}
count, err = a.Offset(-1).Limit(-1).Count()
return
}
func (a appStaticConversationOnlineDo) ScanByPage(result interface{}, offset int, limit int) (count int64, err error) {
count, err = a.Count()
if err != nil {
return
}
err = a.Offset(offset).Limit(limit).Scan(result)
return
}
func (a appStaticConversationOnlineDo) Scan(result interface{}) (err error) {
return a.DO.Scan(result)
}
func (a appStaticConversationOnlineDo) Delete(models ...*model.AppStaticConversationOnline) (result gen.ResultInfo, err error) {
return a.DO.Delete(models)
}
func (a *appStaticConversationOnlineDo) withDO(do gen.Dao) *appStaticConversationOnlineDo {
a.DO = *do.(*gen.DO)
return a
}

View File

@ -0,0 +1,440 @@
// Code generated by gorm.io/gen. DO NOT EDIT.
// Code generated by gorm.io/gen. DO NOT EDIT.
// Code generated by gorm.io/gen. DO NOT EDIT.
package query
import (
"context"
"gorm.io/gorm"
"gorm.io/gorm/clause"
"gorm.io/gorm/schema"
"gorm.io/gen"
"gorm.io/gen/field"
"gorm.io/plugin/dbresolver"
"github.com/coze-dev/coze-studio/backend/domain/workflow/internal/repo/dal/model"
)
func newChatFlowRoleConfig(db *gorm.DB, opts ...gen.DOOption) chatFlowRoleConfig {
_chatFlowRoleConfig := chatFlowRoleConfig{}
_chatFlowRoleConfig.chatFlowRoleConfigDo.UseDB(db, opts...)
_chatFlowRoleConfig.chatFlowRoleConfigDo.UseModel(&model.ChatFlowRoleConfig{})
tableName := _chatFlowRoleConfig.chatFlowRoleConfigDo.TableName()
_chatFlowRoleConfig.ALL = field.NewAsterisk(tableName)
_chatFlowRoleConfig.ID = field.NewInt64(tableName, "id")
_chatFlowRoleConfig.WorkflowID = field.NewInt64(tableName, "workflow_id")
_chatFlowRoleConfig.Name = field.NewString(tableName, "name")
_chatFlowRoleConfig.Description = field.NewString(tableName, "description")
_chatFlowRoleConfig.Version = field.NewString(tableName, "version")
_chatFlowRoleConfig.Avatar = field.NewString(tableName, "avatar")
_chatFlowRoleConfig.BackgroundImageInfo = field.NewString(tableName, "background_image_info")
_chatFlowRoleConfig.OnboardingInfo = field.NewString(tableName, "onboarding_info")
_chatFlowRoleConfig.SuggestReplyInfo = field.NewString(tableName, "suggest_reply_info")
_chatFlowRoleConfig.AudioConfig = field.NewString(tableName, "audio_config")
_chatFlowRoleConfig.UserInputConfig = field.NewString(tableName, "user_input_config")
_chatFlowRoleConfig.CreatorID = field.NewInt64(tableName, "creator_id")
_chatFlowRoleConfig.CreatedAt = field.NewInt64(tableName, "created_at")
_chatFlowRoleConfig.UpdatedAt = field.NewInt64(tableName, "updated_at")
_chatFlowRoleConfig.DeletedAt = field.NewField(tableName, "deleted_at")
_chatFlowRoleConfig.ConnectorID = field.NewInt64(tableName, "connector_id")
_chatFlowRoleConfig.fillFieldMap()
return _chatFlowRoleConfig
}
type chatFlowRoleConfig struct {
chatFlowRoleConfigDo
ALL field.Asterisk
ID field.Int64 // id
WorkflowID field.Int64 // workflow id
Name field.String // role name
Description field.String // role description
Version field.String // version
Avatar field.String // avatar uri
BackgroundImageInfo field.String // background image information, object structure
OnboardingInfo field.String // intro information, object structure
SuggestReplyInfo field.String // user suggestions, object structure
AudioConfig field.String // agent audio config, object structure
UserInputConfig field.String // user input config, object structure
CreatorID field.Int64 // creator id
CreatedAt field.Int64 // create time in millisecond
UpdatedAt field.Int64 // update time in millisecond
DeletedAt field.Field // delete time in millisecond
ConnectorID field.Int64 // connector id
fieldMap map[string]field.Expr
}
func (c chatFlowRoleConfig) Table(newTableName string) *chatFlowRoleConfig {
c.chatFlowRoleConfigDo.UseTable(newTableName)
return c.updateTableName(newTableName)
}
func (c chatFlowRoleConfig) As(alias string) *chatFlowRoleConfig {
c.chatFlowRoleConfigDo.DO = *(c.chatFlowRoleConfigDo.As(alias).(*gen.DO))
return c.updateTableName(alias)
}
func (c *chatFlowRoleConfig) updateTableName(table string) *chatFlowRoleConfig {
c.ALL = field.NewAsterisk(table)
c.ID = field.NewInt64(table, "id")
c.WorkflowID = field.NewInt64(table, "workflow_id")
c.Name = field.NewString(table, "name")
c.Description = field.NewString(table, "description")
c.Version = field.NewString(table, "version")
c.Avatar = field.NewString(table, "avatar")
c.BackgroundImageInfo = field.NewString(table, "background_image_info")
c.OnboardingInfo = field.NewString(table, "onboarding_info")
c.SuggestReplyInfo = field.NewString(table, "suggest_reply_info")
c.AudioConfig = field.NewString(table, "audio_config")
c.UserInputConfig = field.NewString(table, "user_input_config")
c.CreatorID = field.NewInt64(table, "creator_id")
c.CreatedAt = field.NewInt64(table, "created_at")
c.UpdatedAt = field.NewInt64(table, "updated_at")
c.DeletedAt = field.NewField(table, "deleted_at")
c.ConnectorID = field.NewInt64(table, "connector_id")
c.fillFieldMap()
return c
}
func (c *chatFlowRoleConfig) GetFieldByName(fieldName string) (field.OrderExpr, bool) {
_f, ok := c.fieldMap[fieldName]
if !ok || _f == nil {
return nil, false
}
_oe, ok := _f.(field.OrderExpr)
return _oe, ok
}
func (c *chatFlowRoleConfig) fillFieldMap() {
c.fieldMap = make(map[string]field.Expr, 16)
c.fieldMap["id"] = c.ID
c.fieldMap["workflow_id"] = c.WorkflowID
c.fieldMap["name"] = c.Name
c.fieldMap["description"] = c.Description
c.fieldMap["version"] = c.Version
c.fieldMap["avatar"] = c.Avatar
c.fieldMap["background_image_info"] = c.BackgroundImageInfo
c.fieldMap["onboarding_info"] = c.OnboardingInfo
c.fieldMap["suggest_reply_info"] = c.SuggestReplyInfo
c.fieldMap["audio_config"] = c.AudioConfig
c.fieldMap["user_input_config"] = c.UserInputConfig
c.fieldMap["creator_id"] = c.CreatorID
c.fieldMap["created_at"] = c.CreatedAt
c.fieldMap["updated_at"] = c.UpdatedAt
c.fieldMap["deleted_at"] = c.DeletedAt
c.fieldMap["connector_id"] = c.ConnectorID
}
func (c chatFlowRoleConfig) clone(db *gorm.DB) chatFlowRoleConfig {
c.chatFlowRoleConfigDo.ReplaceConnPool(db.Statement.ConnPool)
return c
}
func (c chatFlowRoleConfig) replaceDB(db *gorm.DB) chatFlowRoleConfig {
c.chatFlowRoleConfigDo.ReplaceDB(db)
return c
}
type chatFlowRoleConfigDo struct{ gen.DO }
type IChatFlowRoleConfigDo interface {
gen.SubQuery
Debug() IChatFlowRoleConfigDo
WithContext(ctx context.Context) IChatFlowRoleConfigDo
WithResult(fc func(tx gen.Dao)) gen.ResultInfo
ReplaceDB(db *gorm.DB)
ReadDB() IChatFlowRoleConfigDo
WriteDB() IChatFlowRoleConfigDo
As(alias string) gen.Dao
Session(config *gorm.Session) IChatFlowRoleConfigDo
Columns(cols ...field.Expr) gen.Columns
Clauses(conds ...clause.Expression) IChatFlowRoleConfigDo
Not(conds ...gen.Condition) IChatFlowRoleConfigDo
Or(conds ...gen.Condition) IChatFlowRoleConfigDo
Select(conds ...field.Expr) IChatFlowRoleConfigDo
Where(conds ...gen.Condition) IChatFlowRoleConfigDo
Order(conds ...field.Expr) IChatFlowRoleConfigDo
Distinct(cols ...field.Expr) IChatFlowRoleConfigDo
Omit(cols ...field.Expr) IChatFlowRoleConfigDo
Join(table schema.Tabler, on ...field.Expr) IChatFlowRoleConfigDo
LeftJoin(table schema.Tabler, on ...field.Expr) IChatFlowRoleConfigDo
RightJoin(table schema.Tabler, on ...field.Expr) IChatFlowRoleConfigDo
Group(cols ...field.Expr) IChatFlowRoleConfigDo
Having(conds ...gen.Condition) IChatFlowRoleConfigDo
Limit(limit int) IChatFlowRoleConfigDo
Offset(offset int) IChatFlowRoleConfigDo
Count() (count int64, err error)
Scopes(funcs ...func(gen.Dao) gen.Dao) IChatFlowRoleConfigDo
Unscoped() IChatFlowRoleConfigDo
Create(values ...*model.ChatFlowRoleConfig) error
CreateInBatches(values []*model.ChatFlowRoleConfig, batchSize int) error
Save(values ...*model.ChatFlowRoleConfig) error
First() (*model.ChatFlowRoleConfig, error)
Take() (*model.ChatFlowRoleConfig, error)
Last() (*model.ChatFlowRoleConfig, error)
Find() ([]*model.ChatFlowRoleConfig, error)
FindInBatch(batchSize int, fc func(tx gen.Dao, batch int) error) (results []*model.ChatFlowRoleConfig, err error)
FindInBatches(result *[]*model.ChatFlowRoleConfig, batchSize int, fc func(tx gen.Dao, batch int) error) error
Pluck(column field.Expr, dest interface{}) error
Delete(...*model.ChatFlowRoleConfig) (info gen.ResultInfo, err error)
Update(column field.Expr, value interface{}) (info gen.ResultInfo, err error)
UpdateSimple(columns ...field.AssignExpr) (info gen.ResultInfo, err error)
Updates(value interface{}) (info gen.ResultInfo, err error)
UpdateColumn(column field.Expr, value interface{}) (info gen.ResultInfo, err error)
UpdateColumnSimple(columns ...field.AssignExpr) (info gen.ResultInfo, err error)
UpdateColumns(value interface{}) (info gen.ResultInfo, err error)
UpdateFrom(q gen.SubQuery) gen.Dao
Attrs(attrs ...field.AssignExpr) IChatFlowRoleConfigDo
Assign(attrs ...field.AssignExpr) IChatFlowRoleConfigDo
Joins(fields ...field.RelationField) IChatFlowRoleConfigDo
Preload(fields ...field.RelationField) IChatFlowRoleConfigDo
FirstOrInit() (*model.ChatFlowRoleConfig, error)
FirstOrCreate() (*model.ChatFlowRoleConfig, error)
FindByPage(offset int, limit int) (result []*model.ChatFlowRoleConfig, count int64, err error)
ScanByPage(result interface{}, offset int, limit int) (count int64, err error)
Scan(result interface{}) (err error)
Returning(value interface{}, columns ...string) IChatFlowRoleConfigDo
UnderlyingDB() *gorm.DB
schema.Tabler
}
func (c chatFlowRoleConfigDo) Debug() IChatFlowRoleConfigDo {
return c.withDO(c.DO.Debug())
}
func (c chatFlowRoleConfigDo) WithContext(ctx context.Context) IChatFlowRoleConfigDo {
return c.withDO(c.DO.WithContext(ctx))
}
func (c chatFlowRoleConfigDo) ReadDB() IChatFlowRoleConfigDo {
return c.Clauses(dbresolver.Read)
}
func (c chatFlowRoleConfigDo) WriteDB() IChatFlowRoleConfigDo {
return c.Clauses(dbresolver.Write)
}
func (c chatFlowRoleConfigDo) Session(config *gorm.Session) IChatFlowRoleConfigDo {
return c.withDO(c.DO.Session(config))
}
func (c chatFlowRoleConfigDo) Clauses(conds ...clause.Expression) IChatFlowRoleConfigDo {
return c.withDO(c.DO.Clauses(conds...))
}
func (c chatFlowRoleConfigDo) Returning(value interface{}, columns ...string) IChatFlowRoleConfigDo {
return c.withDO(c.DO.Returning(value, columns...))
}
func (c chatFlowRoleConfigDo) Not(conds ...gen.Condition) IChatFlowRoleConfigDo {
return c.withDO(c.DO.Not(conds...))
}
func (c chatFlowRoleConfigDo) Or(conds ...gen.Condition) IChatFlowRoleConfigDo {
return c.withDO(c.DO.Or(conds...))
}
func (c chatFlowRoleConfigDo) Select(conds ...field.Expr) IChatFlowRoleConfigDo {
return c.withDO(c.DO.Select(conds...))
}
func (c chatFlowRoleConfigDo) Where(conds ...gen.Condition) IChatFlowRoleConfigDo {
return c.withDO(c.DO.Where(conds...))
}
func (c chatFlowRoleConfigDo) Order(conds ...field.Expr) IChatFlowRoleConfigDo {
return c.withDO(c.DO.Order(conds...))
}
func (c chatFlowRoleConfigDo) Distinct(cols ...field.Expr) IChatFlowRoleConfigDo {
return c.withDO(c.DO.Distinct(cols...))
}
func (c chatFlowRoleConfigDo) Omit(cols ...field.Expr) IChatFlowRoleConfigDo {
return c.withDO(c.DO.Omit(cols...))
}
func (c chatFlowRoleConfigDo) Join(table schema.Tabler, on ...field.Expr) IChatFlowRoleConfigDo {
return c.withDO(c.DO.Join(table, on...))
}
func (c chatFlowRoleConfigDo) LeftJoin(table schema.Tabler, on ...field.Expr) IChatFlowRoleConfigDo {
return c.withDO(c.DO.LeftJoin(table, on...))
}
func (c chatFlowRoleConfigDo) RightJoin(table schema.Tabler, on ...field.Expr) IChatFlowRoleConfigDo {
return c.withDO(c.DO.RightJoin(table, on...))
}
func (c chatFlowRoleConfigDo) Group(cols ...field.Expr) IChatFlowRoleConfigDo {
return c.withDO(c.DO.Group(cols...))
}
func (c chatFlowRoleConfigDo) Having(conds ...gen.Condition) IChatFlowRoleConfigDo {
return c.withDO(c.DO.Having(conds...))
}
func (c chatFlowRoleConfigDo) Limit(limit int) IChatFlowRoleConfigDo {
return c.withDO(c.DO.Limit(limit))
}
func (c chatFlowRoleConfigDo) Offset(offset int) IChatFlowRoleConfigDo {
return c.withDO(c.DO.Offset(offset))
}
func (c chatFlowRoleConfigDo) Scopes(funcs ...func(gen.Dao) gen.Dao) IChatFlowRoleConfigDo {
return c.withDO(c.DO.Scopes(funcs...))
}
func (c chatFlowRoleConfigDo) Unscoped() IChatFlowRoleConfigDo {
return c.withDO(c.DO.Unscoped())
}
func (c chatFlowRoleConfigDo) Create(values ...*model.ChatFlowRoleConfig) error {
if len(values) == 0 {
return nil
}
return c.DO.Create(values)
}
func (c chatFlowRoleConfigDo) CreateInBatches(values []*model.ChatFlowRoleConfig, batchSize int) error {
return c.DO.CreateInBatches(values, batchSize)
}
// Save : !!! underlying implementation is different with GORM
// The method is equivalent to executing the statement: db.Clauses(clause.OnConflict{UpdateAll: true}).Create(values)
func (c chatFlowRoleConfigDo) Save(values ...*model.ChatFlowRoleConfig) error {
if len(values) == 0 {
return nil
}
return c.DO.Save(values)
}
func (c chatFlowRoleConfigDo) First() (*model.ChatFlowRoleConfig, error) {
if result, err := c.DO.First(); err != nil {
return nil, err
} else {
return result.(*model.ChatFlowRoleConfig), nil
}
}
func (c chatFlowRoleConfigDo) Take() (*model.ChatFlowRoleConfig, error) {
if result, err := c.DO.Take(); err != nil {
return nil, err
} else {
return result.(*model.ChatFlowRoleConfig), nil
}
}
func (c chatFlowRoleConfigDo) Last() (*model.ChatFlowRoleConfig, error) {
if result, err := c.DO.Last(); err != nil {
return nil, err
} else {
return result.(*model.ChatFlowRoleConfig), nil
}
}
func (c chatFlowRoleConfigDo) Find() ([]*model.ChatFlowRoleConfig, error) {
result, err := c.DO.Find()
return result.([]*model.ChatFlowRoleConfig), err
}
func (c chatFlowRoleConfigDo) FindInBatch(batchSize int, fc func(tx gen.Dao, batch int) error) (results []*model.ChatFlowRoleConfig, err error) {
buf := make([]*model.ChatFlowRoleConfig, 0, batchSize)
err = c.DO.FindInBatches(&buf, batchSize, func(tx gen.Dao, batch int) error {
defer func() { results = append(results, buf...) }()
return fc(tx, batch)
})
return results, err
}
func (c chatFlowRoleConfigDo) FindInBatches(result *[]*model.ChatFlowRoleConfig, batchSize int, fc func(tx gen.Dao, batch int) error) error {
return c.DO.FindInBatches(result, batchSize, fc)
}
func (c chatFlowRoleConfigDo) Attrs(attrs ...field.AssignExpr) IChatFlowRoleConfigDo {
return c.withDO(c.DO.Attrs(attrs...))
}
func (c chatFlowRoleConfigDo) Assign(attrs ...field.AssignExpr) IChatFlowRoleConfigDo {
return c.withDO(c.DO.Assign(attrs...))
}
func (c chatFlowRoleConfigDo) Joins(fields ...field.RelationField) IChatFlowRoleConfigDo {
for _, _f := range fields {
c = *c.withDO(c.DO.Joins(_f))
}
return &c
}
func (c chatFlowRoleConfigDo) Preload(fields ...field.RelationField) IChatFlowRoleConfigDo {
for _, _f := range fields {
c = *c.withDO(c.DO.Preload(_f))
}
return &c
}
func (c chatFlowRoleConfigDo) FirstOrInit() (*model.ChatFlowRoleConfig, error) {
if result, err := c.DO.FirstOrInit(); err != nil {
return nil, err
} else {
return result.(*model.ChatFlowRoleConfig), nil
}
}
func (c chatFlowRoleConfigDo) FirstOrCreate() (*model.ChatFlowRoleConfig, error) {
if result, err := c.DO.FirstOrCreate(); err != nil {
return nil, err
} else {
return result.(*model.ChatFlowRoleConfig), nil
}
}
func (c chatFlowRoleConfigDo) FindByPage(offset int, limit int) (result []*model.ChatFlowRoleConfig, count int64, err error) {
result, err = c.Offset(offset).Limit(limit).Find()
if err != nil {
return
}
if size := len(result); 0 < limit && 0 < size && size < limit {
count = int64(size + offset)
return
}
count, err = c.Offset(-1).Limit(-1).Count()
return
}
func (c chatFlowRoleConfigDo) ScanByPage(result interface{}, offset int, limit int) (count int64, err error) {
count, err = c.Count()
if err != nil {
return
}
err = c.Offset(offset).Limit(limit).Scan(result)
return
}
func (c chatFlowRoleConfigDo) Scan(result interface{}) (err error) {
return c.DO.Scan(result)
}
func (c chatFlowRoleConfigDo) Delete(models ...*model.ChatFlowRoleConfig) (result gen.ResultInfo, err error) {
return c.DO.Delete(models)
}
func (c *chatFlowRoleConfigDo) withDO(do gen.Dao) *chatFlowRoleConfigDo {
c.DO = *do.(*gen.DO)
return c
}

View File

@ -16,20 +16,34 @@ import (
)
var (
Q = new(Query)
ConnectorWorkflowVersion *connectorWorkflowVersion
NodeExecution *nodeExecution
WorkflowDraft *workflowDraft
WorkflowExecution *workflowExecution
WorkflowMeta *workflowMeta
WorkflowReference *workflowReference
WorkflowSnapshot *workflowSnapshot
WorkflowVersion *workflowVersion
Q = new(Query)
ConnectorWorkflowVersion *connectorWorkflowVersion
AppConversationTemplateDraft *appConversationTemplateDraft
AppConversationTemplateOnline *appConversationTemplateOnline
AppDynamicConversationDraft *appDynamicConversationDraft
AppDynamicConversationOnline *appDynamicConversationOnline
AppStaticConversationDraft *appStaticConversationDraft
AppStaticConversationOnline *appStaticConversationOnline
ChatFlowRoleConfig *chatFlowRoleConfig
NodeExecution *nodeExecution
WorkflowDraft *workflowDraft
WorkflowExecution *workflowExecution
WorkflowMeta *workflowMeta
WorkflowReference *workflowReference
WorkflowSnapshot *workflowSnapshot
WorkflowVersion *workflowVersion
)
func SetDefault(db *gorm.DB, opts ...gen.DOOption) {
*Q = *Use(db, opts...)
ConnectorWorkflowVersion = &Q.ConnectorWorkflowVersion
AppConversationTemplateDraft = &Q.AppConversationTemplateDraft
AppConversationTemplateOnline = &Q.AppConversationTemplateOnline
AppDynamicConversationDraft = &Q.AppDynamicConversationDraft
AppDynamicConversationOnline = &Q.AppDynamicConversationOnline
AppStaticConversationDraft = &Q.AppStaticConversationDraft
AppStaticConversationOnline = &Q.AppStaticConversationOnline
ChatFlowRoleConfig = &Q.ChatFlowRoleConfig
NodeExecution = &Q.NodeExecution
WorkflowDraft = &Q.WorkflowDraft
WorkflowExecution = &Q.WorkflowExecution
@ -41,44 +55,65 @@ func SetDefault(db *gorm.DB, opts ...gen.DOOption) {
func Use(db *gorm.DB, opts ...gen.DOOption) *Query {
return &Query{
db: db,
ConnectorWorkflowVersion: newConnectorWorkflowVersion(db, opts...),
NodeExecution: newNodeExecution(db, opts...),
WorkflowDraft: newWorkflowDraft(db, opts...),
WorkflowExecution: newWorkflowExecution(db, opts...),
WorkflowMeta: newWorkflowMeta(db, opts...),
WorkflowReference: newWorkflowReference(db, opts...),
WorkflowSnapshot: newWorkflowSnapshot(db, opts...),
WorkflowVersion: newWorkflowVersion(db, opts...),
db: db,
ConnectorWorkflowVersion: newConnectorWorkflowVersion(db, opts...),
AppConversationTemplateDraft: newAppConversationTemplateDraft(db, opts...),
AppConversationTemplateOnline: newAppConversationTemplateOnline(db, opts...),
AppDynamicConversationDraft: newAppDynamicConversationDraft(db, opts...),
AppDynamicConversationOnline: newAppDynamicConversationOnline(db, opts...),
AppStaticConversationDraft: newAppStaticConversationDraft(db, opts...),
AppStaticConversationOnline: newAppStaticConversationOnline(db, opts...),
ChatFlowRoleConfig: newChatFlowRoleConfig(db, opts...),
NodeExecution: newNodeExecution(db, opts...),
WorkflowDraft: newWorkflowDraft(db, opts...),
WorkflowExecution: newWorkflowExecution(db, opts...),
WorkflowMeta: newWorkflowMeta(db, opts...),
WorkflowReference: newWorkflowReference(db, opts...),
WorkflowSnapshot: newWorkflowSnapshot(db, opts...),
WorkflowVersion: newWorkflowVersion(db, opts...),
}
}
type Query struct {
db *gorm.DB
ConnectorWorkflowVersion connectorWorkflowVersion
NodeExecution nodeExecution
WorkflowDraft workflowDraft
WorkflowExecution workflowExecution
WorkflowMeta workflowMeta
WorkflowReference workflowReference
WorkflowSnapshot workflowSnapshot
WorkflowVersion workflowVersion
ConnectorWorkflowVersion connectorWorkflowVersion
AppConversationTemplateDraft appConversationTemplateDraft
AppConversationTemplateOnline appConversationTemplateOnline
AppDynamicConversationDraft appDynamicConversationDraft
AppDynamicConversationOnline appDynamicConversationOnline
AppStaticConversationDraft appStaticConversationDraft
AppStaticConversationOnline appStaticConversationOnline
ChatFlowRoleConfig chatFlowRoleConfig
NodeExecution nodeExecution
WorkflowDraft workflowDraft
WorkflowExecution workflowExecution
WorkflowMeta workflowMeta
WorkflowReference workflowReference
WorkflowSnapshot workflowSnapshot
WorkflowVersion workflowVersion
}
func (q *Query) Available() bool { return q.db != nil }
func (q *Query) clone(db *gorm.DB) *Query {
return &Query{
db: db,
ConnectorWorkflowVersion: q.ConnectorWorkflowVersion.clone(db),
NodeExecution: q.NodeExecution.clone(db),
WorkflowDraft: q.WorkflowDraft.clone(db),
WorkflowExecution: q.WorkflowExecution.clone(db),
WorkflowMeta: q.WorkflowMeta.clone(db),
WorkflowReference: q.WorkflowReference.clone(db),
WorkflowSnapshot: q.WorkflowSnapshot.clone(db),
WorkflowVersion: q.WorkflowVersion.clone(db),
db: db,
ConnectorWorkflowVersion: q.ConnectorWorkflowVersion.clone(db),
AppConversationTemplateDraft: q.AppConversationTemplateDraft.clone(db),
AppConversationTemplateOnline: q.AppConversationTemplateOnline.clone(db),
AppDynamicConversationDraft: q.AppDynamicConversationDraft.clone(db),
AppDynamicConversationOnline: q.AppDynamicConversationOnline.clone(db),
AppStaticConversationDraft: q.AppStaticConversationDraft.clone(db),
AppStaticConversationOnline: q.AppStaticConversationOnline.clone(db),
ChatFlowRoleConfig: q.ChatFlowRoleConfig.clone(db),
NodeExecution: q.NodeExecution.clone(db),
WorkflowDraft: q.WorkflowDraft.clone(db),
WorkflowExecution: q.WorkflowExecution.clone(db),
WorkflowMeta: q.WorkflowMeta.clone(db),
WorkflowReference: q.WorkflowReference.clone(db),
WorkflowSnapshot: q.WorkflowSnapshot.clone(db),
WorkflowVersion: q.WorkflowVersion.clone(db),
}
}
@ -92,39 +127,60 @@ func (q *Query) WriteDB() *Query {
func (q *Query) ReplaceDB(db *gorm.DB) *Query {
return &Query{
db: db,
ConnectorWorkflowVersion: q.ConnectorWorkflowVersion.replaceDB(db),
NodeExecution: q.NodeExecution.replaceDB(db),
WorkflowDraft: q.WorkflowDraft.replaceDB(db),
WorkflowExecution: q.WorkflowExecution.replaceDB(db),
WorkflowMeta: q.WorkflowMeta.replaceDB(db),
WorkflowReference: q.WorkflowReference.replaceDB(db),
WorkflowSnapshot: q.WorkflowSnapshot.replaceDB(db),
WorkflowVersion: q.WorkflowVersion.replaceDB(db),
db: db,
ConnectorWorkflowVersion: q.ConnectorWorkflowVersion.replaceDB(db),
AppConversationTemplateDraft: q.AppConversationTemplateDraft.replaceDB(db),
AppConversationTemplateOnline: q.AppConversationTemplateOnline.replaceDB(db),
AppDynamicConversationDraft: q.AppDynamicConversationDraft.replaceDB(db),
AppDynamicConversationOnline: q.AppDynamicConversationOnline.replaceDB(db),
AppStaticConversationDraft: q.AppStaticConversationDraft.replaceDB(db),
AppStaticConversationOnline: q.AppStaticConversationOnline.replaceDB(db),
ChatFlowRoleConfig: q.ChatFlowRoleConfig.replaceDB(db),
NodeExecution: q.NodeExecution.replaceDB(db),
WorkflowDraft: q.WorkflowDraft.replaceDB(db),
WorkflowExecution: q.WorkflowExecution.replaceDB(db),
WorkflowMeta: q.WorkflowMeta.replaceDB(db),
WorkflowReference: q.WorkflowReference.replaceDB(db),
WorkflowSnapshot: q.WorkflowSnapshot.replaceDB(db),
WorkflowVersion: q.WorkflowVersion.replaceDB(db),
}
}
type queryCtx struct {
ConnectorWorkflowVersion IConnectorWorkflowVersionDo
NodeExecution INodeExecutionDo
WorkflowDraft IWorkflowDraftDo
WorkflowExecution IWorkflowExecutionDo
WorkflowMeta IWorkflowMetaDo
WorkflowReference IWorkflowReferenceDo
WorkflowSnapshot IWorkflowSnapshotDo
WorkflowVersion IWorkflowVersionDo
ConnectorWorkflowVersion IConnectorWorkflowVersionDo
AppConversationTemplateDraft IAppConversationTemplateDraftDo
AppConversationTemplateOnline IAppConversationTemplateOnlineDo
AppDynamicConversationDraft IAppDynamicConversationDraftDo
AppDynamicConversationOnline IAppDynamicConversationOnlineDo
AppStaticConversationDraft IAppStaticConversationDraftDo
AppStaticConversationOnline IAppStaticConversationOnlineDo
ChatFlowRoleConfig IChatFlowRoleConfigDo
NodeExecution INodeExecutionDo
WorkflowDraft IWorkflowDraftDo
WorkflowExecution IWorkflowExecutionDo
WorkflowMeta IWorkflowMetaDo
WorkflowReference IWorkflowReferenceDo
WorkflowSnapshot IWorkflowSnapshotDo
WorkflowVersion IWorkflowVersionDo
}
func (q *Query) WithContext(ctx context.Context) *queryCtx {
return &queryCtx{
ConnectorWorkflowVersion: q.ConnectorWorkflowVersion.WithContext(ctx),
NodeExecution: q.NodeExecution.WithContext(ctx),
WorkflowDraft: q.WorkflowDraft.WithContext(ctx),
WorkflowExecution: q.WorkflowExecution.WithContext(ctx),
WorkflowMeta: q.WorkflowMeta.WithContext(ctx),
WorkflowReference: q.WorkflowReference.WithContext(ctx),
WorkflowSnapshot: q.WorkflowSnapshot.WithContext(ctx),
WorkflowVersion: q.WorkflowVersion.WithContext(ctx),
ConnectorWorkflowVersion: q.ConnectorWorkflowVersion.WithContext(ctx),
AppConversationTemplateDraft: q.AppConversationTemplateDraft.WithContext(ctx),
AppConversationTemplateOnline: q.AppConversationTemplateOnline.WithContext(ctx),
AppDynamicConversationDraft: q.AppDynamicConversationDraft.WithContext(ctx),
AppDynamicConversationOnline: q.AppDynamicConversationOnline.WithContext(ctx),
AppStaticConversationDraft: q.AppStaticConversationDraft.WithContext(ctx),
AppStaticConversationOnline: q.AppStaticConversationOnline.WithContext(ctx),
ChatFlowRoleConfig: q.ChatFlowRoleConfig.WithContext(ctx),
NodeExecution: q.NodeExecution.WithContext(ctx),
WorkflowDraft: q.WorkflowDraft.WithContext(ctx),
WorkflowExecution: q.WorkflowExecution.WithContext(ctx),
WorkflowMeta: q.WorkflowMeta.WithContext(ctx),
WorkflowReference: q.WorkflowReference.WithContext(ctx),
WorkflowSnapshot: q.WorkflowSnapshot.WithContext(ctx),
WorkflowVersion: q.WorkflowVersion.WithContext(ctx),
}
}

Some files were not shown because too many files have changed in this diff Show More