feat: support conversation isolation (#2443)

Co-authored-by: yangyu.1 <tomasyu985@gmail.com>
This commit is contained in:
junwen-lee
2025-11-05 21:35:17 +08:00
committed by GitHub
parent 5d1276b2b8
commit acfce615ec
29 changed files with 405 additions and 95 deletions

View File

@ -1,4 +1,20 @@
// Code generated by thriftgo (0.4.2). DO NOT EDIT.
/*
* 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 conversation
@ -1033,6 +1049,7 @@ type ConversationData struct {
LastSectionID *int64 `thrift:"LastSectionID,6,optional" form:"last_section_id" json:"last_section_id,string,omitempty"`
AccountID *int64 `thrift:"AccountID,7,optional" form:"account_id" json:"account_id,omitempty"`
Name *string `thrift:"Name,8,optional" form:"name" json:"name,omitempty"`
UserID *string `thrift:"UserID,9,optional" form:"user_id" json:"user_id,omitempty"`
}
func NewConversationData() *ConversationData {
@ -1099,6 +1116,15 @@ func (p *ConversationData) GetName() (v string) {
return *p.Name
}
var ConversationData_UserID_DEFAULT string
func (p *ConversationData) GetUserID() (v string) {
if !p.IsSetUserID() {
return ConversationData_UserID_DEFAULT
}
return *p.UserID
}
var fieldIDToName_ConversationData = map[int16]string{
1: "Id",
2: "CreatedAt",
@ -1108,6 +1134,7 @@ var fieldIDToName_ConversationData = map[int16]string{
6: "LastSectionID",
7: "AccountID",
8: "Name",
9: "UserID",
}
func (p *ConversationData) IsSetCreatorID() bool {
@ -1130,6 +1157,10 @@ func (p *ConversationData) IsSetName() bool {
return p.Name != nil
}
func (p *ConversationData) IsSetUserID() bool {
return p.UserID != nil
}
func (p *ConversationData) Read(iprot thrift.TProtocol) (err error) {
var fieldTypeId thrift.TType
var fieldId int16
@ -1212,6 +1243,14 @@ func (p *ConversationData) Read(iprot thrift.TProtocol) (err error) {
} else if err = iprot.Skip(fieldTypeId); err != nil {
goto SkipFieldError
}
case 9:
if fieldTypeId == thrift.STRING {
if err = p.ReadField9(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
@ -1347,6 +1386,17 @@ func (p *ConversationData) ReadField8(iprot thrift.TProtocol) error {
p.Name = _field
return nil
}
func (p *ConversationData) ReadField9(iprot thrift.TProtocol) error {
var _field *string
if v, err := iprot.ReadString(); err != nil {
return err
} else {
_field = &v
}
p.UserID = _field
return nil
}
func (p *ConversationData) Write(oprot thrift.TProtocol) (err error) {
var fieldId int16
@ -1386,6 +1436,10 @@ func (p *ConversationData) Write(oprot thrift.TProtocol) (err error) {
fieldId = 8
goto WriteFieldError
}
if err = p.writeField9(oprot); err != nil {
fieldId = 9
goto WriteFieldError
}
}
if err = oprot.WriteFieldStop(); err != nil {
goto WriteFieldStopError
@ -1553,6 +1607,24 @@ WriteFieldBeginError:
WriteFieldEndError:
return thrift.PrependError(fmt.Sprintf("%T write field 8 end error: ", p), err)
}
func (p *ConversationData) writeField9(oprot thrift.TProtocol) (err error) {
if p.IsSetUserID() {
if err = oprot.WriteFieldBegin("UserID", thrift.STRING, 9); err != nil {
goto WriteFieldBeginError
}
if err := oprot.WriteString(*p.UserID); err != nil {
return err
}
if err = oprot.WriteFieldEnd(); err != nil {
goto WriteFieldEndError
}
}
return nil
WriteFieldBeginError:
return thrift.PrependError(fmt.Sprintf("%T write field 9 begin error: ", p), err)
WriteFieldEndError:
return thrift.PrependError(fmt.Sprintf("%T write field 9 end error: ", p), err)
}
func (p *ConversationData) String() string {
if p == nil {
@ -1567,6 +1639,7 @@ type CreateConversationRequest struct {
MetaData map[string]string `thrift:"MetaData,1,optional" form:"meta_data" json:"meta_data,omitempty"`
BotId *int64 `thrift:"BotId,3,optional" form:"bot_id" json:"bot_id,string,omitempty"`
ConnectorId *int64 `thrift:"ConnectorId,4,optional" form:"connector_id" json:"connector_id,string,omitempty"`
UserID *string `thrift:"user_id,50,optional" form:"user_id" json:"user_id,omitempty"`
}
func NewCreateConversationRequest() *CreateConversationRequest {
@ -1603,10 +1676,20 @@ func (p *CreateConversationRequest) GetConnectorId() (v int64) {
return *p.ConnectorId
}
var CreateConversationRequest_UserID_DEFAULT string
func (p *CreateConversationRequest) GetUserID() (v string) {
if !p.IsSetUserID() {
return CreateConversationRequest_UserID_DEFAULT
}
return *p.UserID
}
var fieldIDToName_CreateConversationRequest = map[int16]string{
1: "MetaData",
3: "BotId",
4: "ConnectorId",
1: "MetaData",
3: "BotId",
4: "ConnectorId",
50: "user_id",
}
func (p *CreateConversationRequest) IsSetMetaData() bool {
@ -1621,6 +1704,10 @@ func (p *CreateConversationRequest) IsSetConnectorId() bool {
return p.ConnectorId != nil
}
func (p *CreateConversationRequest) IsSetUserID() bool {
return p.UserID != nil
}
func (p *CreateConversationRequest) Read(iprot thrift.TProtocol) (err error) {
var fieldTypeId thrift.TType
var fieldId int16
@ -1663,6 +1750,14 @@ func (p *CreateConversationRequest) Read(iprot thrift.TProtocol) (err error) {
} else if err = iprot.Skip(fieldTypeId); err != nil {
goto SkipFieldError
}
case 50:
if fieldTypeId == thrift.STRING {
if err = p.ReadField50(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
@ -1743,6 +1838,17 @@ func (p *CreateConversationRequest) ReadField4(iprot thrift.TProtocol) error {
p.ConnectorId = _field
return nil
}
func (p *CreateConversationRequest) ReadField50(iprot thrift.TProtocol) error {
var _field *string
if v, err := iprot.ReadString(); err != nil {
return err
} else {
_field = &v
}
p.UserID = _field
return nil
}
func (p *CreateConversationRequest) Write(oprot thrift.TProtocol) (err error) {
var fieldId int16
@ -1762,6 +1868,10 @@ func (p *CreateConversationRequest) Write(oprot thrift.TProtocol) (err error) {
fieldId = 4
goto WriteFieldError
}
if err = p.writeField50(oprot); err != nil {
fieldId = 50
goto WriteFieldError
}
}
if err = oprot.WriteFieldStop(); err != nil {
goto WriteFieldStopError
@ -1845,6 +1955,24 @@ WriteFieldBeginError:
WriteFieldEndError:
return thrift.PrependError(fmt.Sprintf("%T write field 4 end error: ", p), err)
}
func (p *CreateConversationRequest) writeField50(oprot thrift.TProtocol) (err error) {
if p.IsSetUserID() {
if err = oprot.WriteFieldBegin("user_id", thrift.STRING, 50); err != nil {
goto WriteFieldBeginError
}
if err := oprot.WriteString(*p.UserID); err != nil {
return err
}
if err = oprot.WriteFieldEnd(); err != nil {
goto WriteFieldEndError
}
}
return nil
WriteFieldBeginError:
return thrift.PrependError(fmt.Sprintf("%T write field 50 begin error: ", p), err)
WriteFieldEndError:
return thrift.PrependError(fmt.Sprintf("%T write field 50 end error: ", p), err)
}
func (p *CreateConversationRequest) String() string {
if p == nil {
@ -2771,6 +2899,7 @@ type ListConversationsApiRequest struct {
SortField string `thrift:"sort_field,4" json:"sort_field" query:"sort_field"`
BotID int64 `thrift:"bot_id,5,required" json:"bot_id,string,required" query:"bot_id,required"`
ConnectorID *int64 `thrift:"connector_id,6,optional" json:"connector_id,string,omitempty" query:"connector_id"`
UserID *string `thrift:"user_id,50,optional" json:"user_id,omitempty" query:"user_id"`
Base *base.Base `thrift:"Base,255" form:"Base" json:"Base" query:"Base"`
}
@ -2810,6 +2939,15 @@ func (p *ListConversationsApiRequest) GetConnectorID() (v int64) {
return *p.ConnectorID
}
var ListConversationsApiRequest_UserID_DEFAULT string
func (p *ListConversationsApiRequest) GetUserID() (v string) {
if !p.IsSetUserID() {
return ListConversationsApiRequest_UserID_DEFAULT
}
return *p.UserID
}
var ListConversationsApiRequest_Base_DEFAULT *base.Base
func (p *ListConversationsApiRequest) GetBase() (v *base.Base) {
@ -2826,6 +2964,7 @@ var fieldIDToName_ListConversationsApiRequest = map[int16]string{
4: "sort_field",
5: "bot_id",
6: "connector_id",
50: "user_id",
255: "Base",
}
@ -2833,6 +2972,10 @@ func (p *ListConversationsApiRequest) IsSetConnectorID() bool {
return p.ConnectorID != nil
}
func (p *ListConversationsApiRequest) IsSetUserID() bool {
return p.UserID != nil
}
func (p *ListConversationsApiRequest) IsSetBase() bool {
return p.Base != nil
}
@ -2905,6 +3048,14 @@ func (p *ListConversationsApiRequest) Read(iprot thrift.TProtocol) (err error) {
} else if err = iprot.Skip(fieldTypeId); err != nil {
goto SkipFieldError
}
case 50:
if fieldTypeId == thrift.STRING {
if err = p.ReadField50(iprot); err != nil {
goto ReadFieldError
}
} else if err = iprot.Skip(fieldTypeId); err != nil {
goto SkipFieldError
}
case 255:
if fieldTypeId == thrift.STRUCT {
if err = p.ReadField255(iprot); err != nil {
@ -3014,6 +3165,17 @@ func (p *ListConversationsApiRequest) ReadField6(iprot thrift.TProtocol) error {
p.ConnectorID = _field
return nil
}
func (p *ListConversationsApiRequest) ReadField50(iprot thrift.TProtocol) error {
var _field *string
if v, err := iprot.ReadString(); err != nil {
return err
} else {
_field = &v
}
p.UserID = _field
return nil
}
func (p *ListConversationsApiRequest) ReadField255(iprot thrift.TProtocol) error {
_field := base.NewBase()
if err := _field.Read(iprot); err != nil {
@ -3053,6 +3215,10 @@ func (p *ListConversationsApiRequest) Write(oprot thrift.TProtocol) (err error)
fieldId = 6
goto WriteFieldError
}
if err = p.writeField50(oprot); err != nil {
fieldId = 50
goto WriteFieldError
}
if err = p.writeField255(oprot); err != nil {
fieldId = 255
goto WriteFieldError
@ -3173,6 +3339,24 @@ WriteFieldBeginError:
WriteFieldEndError:
return thrift.PrependError(fmt.Sprintf("%T write field 6 end error: ", p), err)
}
func (p *ListConversationsApiRequest) writeField50(oprot thrift.TProtocol) (err error) {
if p.IsSetUserID() {
if err = oprot.WriteFieldBegin("user_id", thrift.STRING, 50); err != nil {
goto WriteFieldBeginError
}
if err := oprot.WriteString(*p.UserID); err != nil {
return err
}
if err = oprot.WriteFieldEnd(); err != nil {
goto WriteFieldEndError
}
}
return nil
WriteFieldBeginError:
return thrift.PrependError(fmt.Sprintf("%T write field 50 begin error: ", p), err)
WriteFieldEndError:
return thrift.PrependError(fmt.Sprintf("%T write field 50 end error: ", p), err)
}
func (p *ListConversationsApiRequest) writeField255(oprot thrift.TProtocol) (err error) {
if err = oprot.WriteFieldBegin("Base", thrift.STRUCT, 255); err != nil {
goto WriteFieldBeginError

View File

@ -1,4 +1,20 @@
// Code generated by thriftgo (0.4.2). DO NOT EDIT.
/*
* 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 conversation

View File

@ -269,7 +269,7 @@ func (c *ConversationApplicationService) checkConversation(ctx context.Context,
conData, err := c.ConversationDomainSVC.Create(ctx, &convEntity.CreateMeta{
AgentID: ar.BotID,
UserID: userID,
CreatorID: userID,
Scene: ptr.From(ar.Scene),
ConnectorID: consts.CozeConnectorID,
})

View File

@ -83,7 +83,7 @@ func (c *ConversationApplicationService) ClearHistory(ctx context.Context, req *
// create new conversation
convRes, err := c.ConversationDomainSVC.Create(ctx, &entity.CreateMeta{
AgentID: currentRes.AgentID,
UserID: currentRes.CreatorID,
CreatorID: currentRes.CreatorID,
Scene: currentRes.Scene,
ConnectorID: consts.CozeConnectorID,
})
@ -126,7 +126,7 @@ func (c *ConversationApplicationService) CreateSection(ctx context.Context, conv
func (c *ConversationApplicationService) CreateConversation(ctx context.Context, req *conversation.CreateConversationRequest) (*conversation.CreateConversationResponse, error) {
resp := new(conversation.CreateConversationResponse)
apiKeyInfo := ctxutil.GetApiAuthFromCtx(ctx)
userID := apiKeyInfo.UserID
creatorID := apiKeyInfo.UserID
connectorID := req.GetConnectorId()
agentID := req.GetBotId()
if connectorID != consts.WebSDKConnectorID {
@ -135,7 +135,8 @@ func (c *ConversationApplicationService) CreateConversation(ctx context.Context,
conversationData, err := c.ConversationDomainSVC.Create(ctx, &entity.CreateMeta{
AgentID: agentID,
UserID: userID,
UserID: req.UserID,
CreatorID: creatorID,
ConnectorID: connectorID,
Scene: common.Scene_SceneOpenApi,
Ext: parseMetaData(req.MetaData),
@ -149,6 +150,7 @@ func (c *ConversationApplicationService) CreateConversation(ctx context.Context,
ConnectorID: &conversationData.ConnectorID,
CreatedAt: conversationData.CreatedAt / 1000,
MetaData: parseExt(conversationData.Ext),
UserID: conversationData.UserID,
}
return resp, nil
}
@ -191,7 +193,7 @@ func (c *ConversationApplicationService) ListConversation(ctx context.Context, r
}
conversationDOList, hasMore, err := c.ConversationDomainSVC.List(ctx, &entity.ListMeta{
UserID: userID,
CreatorID: userID,
AgentID: req.GetBotID(),
ConnectorID: connectorID,
Scene: common.Scene_SceneOpenApi,
@ -203,6 +205,7 @@ func (c *ConversationApplicationService) ListConversation(ctx context.Context, r
}
return nil
}(),
UserID: req.UserID,
})
if err != nil {
return resp, err
@ -215,6 +218,7 @@ func (c *ConversationApplicationService) ListConversation(ctx context.Context, r
CreatedAt: conv.CreatedAt / 1000,
Name: ptr.Of(conv.Name),
MetaData: parseExt(conv.Ext),
UserID: conv.UserID,
}
})

View File

@ -141,7 +141,7 @@ func (c *ConversationApplicationService) getCurrentConversation(ctx context.Cont
// create conversation
ccNew, err := c.ConversationDomainSVC.Create(ctx, &convEntity.CreateMeta{
AgentID: agentID,
UserID: userID,
CreatorID: userID,
Scene: scene,
ConnectorID: ptr.From(connectorID),
})

View File

@ -91,7 +91,7 @@ func (a *OpenapiAgentRunApplication) OpenapiAgentRun(ctx context.Context, sseSen
return nil
}
func (a *OpenapiAgentRunApplication) checkConversation(ctx context.Context, ar *run.ChatV3Request, userID int64, connectorID int64) (*convEntity.Conversation, error) {
func (a *OpenapiAgentRunApplication) checkConversation(ctx context.Context, ar *run.ChatV3Request, creatorID int64, connectorID int64) (*convEntity.Conversation, error) {
var conversationData *convEntity.Conversation
if ptr.From(ar.ConversationID) > 0 {
conData, err := ConversationSVC.ConversationDomainSVC.GetByID(ctx, ptr.From(ar.ConversationID))
@ -105,9 +105,10 @@ func (a *OpenapiAgentRunApplication) checkConversation(ctx context.Context, ar *
conData, err := ConversationSVC.ConversationDomainSVC.Create(ctx, &convEntity.CreateMeta{
AgentID: ar.BotID,
UserID: userID,
CreatorID: creatorID,
ConnectorID: connectorID,
Scene: common.Scene_SceneOpenApi,
UserID: ptr.Of(ar.User),
})
if err != nil {
return nil, err
@ -120,7 +121,7 @@ func (a *OpenapiAgentRunApplication) checkConversation(ctx context.Context, ar *
ar.ConversationID = ptr.Of(conversationData.ID)
}
if conversationData.CreatorID != userID {
if conversationData.CreatorID != creatorID {
return nil, errorx.New(errno.ErrConversationPermissionCode, errorx.KV("msg", "user not match"))
}

View File

@ -283,10 +283,11 @@ func TestOpenapiAgentRun_CreateNewConversation(t *testing.T) {
ID: 22222,
CreatorID: 12345,
SectionID: 98765,
UserID: ptr.Of("test-user"),
}
mockConversation.EXPECT().Create(ctx, gomock.Any()).DoAndReturn(func(ctx context.Context, meta *convEntity.CreateMeta) (*convEntity.Conversation, error) {
assert.Equal(t, int64(67890), meta.AgentID)
assert.Equal(t, int64(12345), meta.UserID)
assert.Equal(t, "test-user", ptr.From(meta.UserID))
assert.Equal(t, common.Scene_SceneOpenApi, meta.Scene)
return mockConv, nil
})

View File

@ -550,6 +550,12 @@ func (w *ApplicationService) OpenAPIChatFlowRun(ctx context.Context, req *workfl
apiKeyInfo = ctxutil.GetApiAuthFromCtx(ctx)
userID = apiKeyInfo.UserID
connectorID int64
runtimeUserID = func() *string {
if uID, ok := req.Ext["user_id"]; ok {
return ptr.Of(uID)
}
return nil
}()
)
if len(req.GetConnectorID()) == 0 {
connectorID = ternary.IFElse(isDebug, consts.CozeConnectorID, apiKeyInfo.ConnectorID)
@ -676,11 +682,16 @@ func (w *ApplicationService) OpenAPIChatFlowRun(ctx context.Context, req *workfl
ExecuteID: info.ExecID,
ResumeData: lastUserMessage.Content,
}, workflowModel.ExecuteConfig{
Operator: userID,
Mode: ternary.IFElse(isDebug, workflowModel.ExecuteModeDebug, workflowModel.ExecuteModeRelease),
ConnectorID: connectorID,
ConnectorUID: strconv.FormatInt(userID, 10),
BizType: workflowModel.BizTypeWorkflow,
Operator: userID,
Mode: ternary.IFElse(isDebug, workflowModel.ExecuteModeDebug, workflowModel.ExecuteModeRelease),
ConnectorID: connectorID,
ConnectorUID: func() string {
if runtimeUserID != nil {
return *runtimeUserID
}
return strconv.FormatInt(userID, 10)
}(),
BizType: workflowModel.BizTypeWorkflow,
})
if err != nil {
@ -704,15 +715,20 @@ func (w *ApplicationService) OpenAPIChatFlowRun(ctx context.Context, req *workfl
}
exeCfg := workflowModel.ExecuteConfig{
ID: mustParseInt64(req.GetWorkflowID()),
From: locator,
Version: version,
Operator: userID,
Mode: ternary.IFElse(isDebug, workflowModel.ExecuteModeDebug, workflowModel.ExecuteModeRelease),
AppID: appID,
AgentID: agentID,
ConnectorID: connectorID,
ConnectorUID: strconv.FormatInt(userID, 10),
ID: mustParseInt64(req.GetWorkflowID()),
From: locator,
Version: version,
Operator: userID,
Mode: ternary.IFElse(isDebug, workflowModel.ExecuteModeDebug, workflowModel.ExecuteModeRelease),
AppID: appID,
AgentID: agentID,
ConnectorID: connectorID,
ConnectorUID: func() string {
if runtimeUserID != nil {
return *runtimeUserID
}
return strconv.FormatInt(userID, 10)
}(),
TaskType: workflowModel.TaskTypeForeground,
SyncPattern: workflowModel.SyncPatternStream,
InputFailFast: true,

View File

@ -1513,6 +1513,12 @@ func (w *ApplicationService) OpenAPIStreamRun(ctx context.Context, req *workflow
apiKeyInfo := ctxutil.GetApiAuthFromCtx(ctx)
userID := apiKeyInfo.UserID
runtimeUserID := func() *string {
if uID, ok := req.Ext["user_id"]; ok {
return ptr.Of(uID)
}
return nil
}()
parameters := make(map[string]any)
if req.Parameters != nil {
err := sonic.UnmarshalString(*req.Parameters, &parameters)
@ -1557,15 +1563,20 @@ func (w *ApplicationService) OpenAPIStreamRun(ctx context.Context, req *workflow
}
exeCfg := workflowModel.ExecuteConfig{
ID: meta.ID,
From: workflowModel.FromSpecificVersion,
Version: *meta.LatestPublishedVersion,
Operator: userID,
Mode: workflowModel.ExecuteModeRelease,
AppID: appID,
AgentID: agentID,
ConnectorID: connectorID,
ConnectorUID: strconv.FormatInt(userID, 10),
ID: meta.ID,
From: workflowModel.FromSpecificVersion,
Version: *meta.LatestPublishedVersion,
Operator: userID,
Mode: workflowModel.ExecuteModeRelease,
AppID: appID,
AgentID: agentID,
ConnectorID: connectorID,
ConnectorUID: func() string {
if runtimeUserID != nil {
return *runtimeUserID
}
return strconv.FormatInt(userID, 10)
}(),
TaskType: workflowModel.TaskTypeForeground,
SyncPattern: workflowModel.SyncPatternStream,
InputFailFast: true,
@ -1624,6 +1635,12 @@ func (w *ApplicationService) OpenAPIStreamResume(ctx context.Context, req *workf
apiKeyInfo := ctxutil.GetApiAuthFromCtx(ctx)
userID := apiKeyInfo.UserID
runtimeUserID := func() *string {
if uID, ok := req.Ext["user_id"]; ok {
return ptr.Of(uID)
}
return nil
}()
checkResult, err := crosspermission.DefaultSVC().CheckAuthz(ctx, &permission.CheckAuthzData{
OperatorID: userID,
@ -1650,11 +1667,16 @@ func (w *ApplicationService) OpenAPIStreamResume(ctx context.Context, req *workf
}
sr, err := GetWorkflowDomainSVC().StreamResume(ctx, resumeReq, workflowModel.ExecuteConfig{
Operator: userID,
Mode: workflowModel.ExecuteModeRelease,
ConnectorID: connectorID,
ConnectorUID: strconv.FormatInt(userID, 10),
BizType: workflowModel.BizTypeWorkflow,
Operator: userID,
Mode: workflowModel.ExecuteModeRelease,
ConnectorID: connectorID,
ConnectorUID: func() string {
if runtimeUserID != nil {
return *runtimeUserID
}
return strconv.FormatInt(userID, 10)
}(),
BizType: workflowModel.BizTypeWorkflow,
})
if err != nil {
return nil, err
@ -1680,6 +1702,12 @@ func (w *ApplicationService) OpenAPIRun(ctx context.Context, req *workflow.OpenA
apiKeyInfo := ctxutil.GetApiAuthFromCtx(ctx)
userID := apiKeyInfo.UserID
runtimeUserID := func() *string {
if uID, ok := req.Ext["user_id"]; ok {
return ptr.Of(uID)
}
return nil
}()
parameters := make(map[string]any)
if req.Parameters != nil {
@ -1725,15 +1753,20 @@ func (w *ApplicationService) OpenAPIRun(ctx context.Context, req *workflow.OpenA
}
exeCfg := workflowModel.ExecuteConfig{
ID: meta.ID,
From: workflowModel.FromSpecificVersion,
Version: *meta.LatestPublishedVersion,
Operator: userID,
Mode: workflowModel.ExecuteModeRelease,
AppID: appID,
AgentID: agentID,
ConnectorID: connectorID,
ConnectorUID: strconv.FormatInt(userID, 10),
ID: meta.ID,
From: workflowModel.FromSpecificVersion,
Version: *meta.LatestPublishedVersion,
Operator: userID,
Mode: workflowModel.ExecuteModeRelease,
AppID: appID,
AgentID: agentID,
ConnectorID: connectorID,
ConnectorUID: func() string {
if runtimeUserID != nil {
return *runtimeUserID
}
return strconv.FormatInt(userID, 10)
}(),
InputFailFast: true,
BizType: workflowModel.BizTypeWorkflow,
}

View File

@ -47,6 +47,7 @@ type Conversation struct {
AgentID int64 `json:"agent_id"`
ConnectorID int64 `json:"connector_id"`
CreatorID int64 `json:"creator_id"`
UserID *string `json:"user_id"`
Scene common.Scene `json:"scene"`
Status ConversationStatus `json:"status"`
Ext string `json:"ext"`

View File

@ -26,7 +26,8 @@ type Conversation = model.Conversation
type CreateMeta struct {
Name string `json:"name"`
AgentID int64 `json:"agent_id"`
UserID int64 `json:"user_id"`
UserID *string `json:"user_id"`
CreatorID int64 `json:"creator_id"`
ConnectorID int64 `json:"connector_id"`
Scene common.Scene `json:"scene"`
Ext string `json:"ext"`
@ -44,7 +45,8 @@ type NewConversationCtxResponse struct {
type GetCurrent = model.GetCurrent
type ListMeta struct {
UserID int64 `json:"user_id"`
CreatorID int64 `json:"creator_id"`
UserID *string `json:"user_id"`
ConnectorID int64 `json:"connector_id"`
Scene common.Scene `json:"scene"`
AgentID int64 `json:"agent_id"`

View File

@ -145,12 +145,16 @@ func (dao *ConversationDAO) List(ctx context.Context, listMeta *entity.ListMeta)
var hasMore bool
do := dao.query.Conversation.WithContext(ctx).Debug()
do = do.Where(dao.query.Conversation.CreatorID.Eq(listMeta.UserID)).
do = do.Where(dao.query.Conversation.CreatorID.Eq(listMeta.CreatorID)).
Where(dao.query.Conversation.AgentID.Eq(listMeta.AgentID)).
Where(dao.query.Conversation.Scene.Eq(int32(listMeta.Scene))).
Where(dao.query.Conversation.ConnectorID.Eq(listMeta.ConnectorID)).
Where(dao.query.Conversation.Status.Eq(int32(conversation.ConversationStatusNormal)))
if listMeta.UserID != nil {
do = do.Where(dao.query.Conversation.UserID.Eq(ptr.From(listMeta.UserID)))
}
do = do.Offset((listMeta.Page - 1) * listMeta.Limit)
if listMeta.Limit > 0 {
@ -188,6 +192,7 @@ func (dao *ConversationDAO) conversationDO2PO(ctx context.Context, conversation
SectionID: conversation.SectionID,
ConnectorID: conversation.ConnectorID,
AgentID: conversation.AgentID,
UserID: ptr.From(conversation.UserID),
CreatorID: conversation.CreatorID,
Scene: int32(conversation.Scene),
Status: int32(conversation.Status),
@ -211,6 +216,7 @@ func (dao *ConversationDAO) conversationPO2DO(ctx context.Context, c *model.Conv
CreatedAt: c.CreatedAt,
UpdatedAt: c.UpdatedAt,
Name: c.Name,
UserID: ptr.Of(c.UserID),
}
}
@ -228,6 +234,7 @@ func (dao *ConversationDAO) conversationBatchPO2DO(ctx context.Context, conversa
CreatedAt: c.CreatedAt,
UpdatedAt: c.UpdatedAt,
Name: c.Name,
UserID: ptr.Of(c.UserID),
}
})
}

View File

@ -25,7 +25,6 @@ const TableNameConversation = "conversation"
// Conversation conversation info record
type Conversation struct {
ID int64 `gorm:"column:id;primaryKey;autoIncrement:true;comment:id" json:"id"` // id
Name string `gorm:"column:name;not null;comment:conversation name" json:"name"` // conversation name
ConnectorID int64 `gorm:"column:connector_id;not null;comment:Publish Connector ID" json:"connector_id"` // Publish Connector ID
AgentID int64 `gorm:"column:agent_id;not null;comment:agent_id" json:"agent_id"` // agent_id
Scene int32 `gorm:"column:scene;not null;comment:conversation scene" json:"scene"` // conversation scene
@ -35,6 +34,8 @@ type Conversation struct {
Status int32 `gorm:"column:status;not null;default:1;comment:status: 1-normal 2-deleted" json:"status"` // status: 1-normal 2-deleted
CreatedAt int64 `gorm:"column:created_at;not null;autoCreateTime:milli;comment:Create Time in Milliseconds" json:"created_at"` // Create Time in Milliseconds
UpdatedAt int64 `gorm:"column:updated_at;not null;autoUpdateTime:milli;comment:Update Time in Milliseconds" json:"updated_at"` // Update Time in Milliseconds
Name string `gorm:"column:name;not null;comment:conversation name" json:"name"` // conversation name
UserID string `gorm:"column:user_id;not null;comment:user id" json:"user_id"` // user id
}
// TableName Conversation's table name

View File

@ -44,7 +44,6 @@ func newConversation(db *gorm.DB, opts ...gen.DOOption) conversation {
tableName := _conversation.conversationDo.TableName()
_conversation.ALL = field.NewAsterisk(tableName)
_conversation.ID = field.NewInt64(tableName, "id")
_conversation.Name = field.NewString(tableName, "name")
_conversation.ConnectorID = field.NewInt64(tableName, "connector_id")
_conversation.AgentID = field.NewInt64(tableName, "agent_id")
_conversation.Scene = field.NewInt32(tableName, "scene")
@ -54,6 +53,8 @@ func newConversation(db *gorm.DB, opts ...gen.DOOption) conversation {
_conversation.Status = field.NewInt32(tableName, "status")
_conversation.CreatedAt = field.NewInt64(tableName, "created_at")
_conversation.UpdatedAt = field.NewInt64(tableName, "updated_at")
_conversation.Name = field.NewString(tableName, "name")
_conversation.UserID = field.NewString(tableName, "user_id")
_conversation.fillFieldMap()
@ -66,7 +67,6 @@ type conversation struct {
ALL field.Asterisk
ID field.Int64 // id
Name field.String // conversation name
ConnectorID field.Int64 // Publish Connector ID
AgentID field.Int64 // agent_id
Scene field.Int32 // conversation scene
@ -76,6 +76,8 @@ type conversation struct {
Status field.Int32 // status: 1-normal 2-deleted
CreatedAt field.Int64 // Create Time in Milliseconds
UpdatedAt field.Int64 // Update Time in Milliseconds
Name field.String // conversation name
UserID field.String // user id
fieldMap map[string]field.Expr
}
@ -93,7 +95,6 @@ func (c conversation) As(alias string) *conversation {
func (c *conversation) updateTableName(table string) *conversation {
c.ALL = field.NewAsterisk(table)
c.ID = field.NewInt64(table, "id")
c.Name = field.NewString(table, "name")
c.ConnectorID = field.NewInt64(table, "connector_id")
c.AgentID = field.NewInt64(table, "agent_id")
c.Scene = field.NewInt32(table, "scene")
@ -103,6 +104,8 @@ func (c *conversation) updateTableName(table string) *conversation {
c.Status = field.NewInt32(table, "status")
c.CreatedAt = field.NewInt64(table, "created_at")
c.UpdatedAt = field.NewInt64(table, "updated_at")
c.Name = field.NewString(table, "name")
c.UserID = field.NewString(table, "user_id")
c.fillFieldMap()
@ -119,9 +122,8 @@ func (c *conversation) GetFieldByName(fieldName string) (field.OrderExpr, bool)
}
func (c *conversation) fillFieldMap() {
c.fieldMap = make(map[string]field.Expr, 11)
c.fieldMap = make(map[string]field.Expr, 12)
c.fieldMap["id"] = c.ID
c.fieldMap["name"] = c.Name
c.fieldMap["connector_id"] = c.ConnectorID
c.fieldMap["agent_id"] = c.AgentID
c.fieldMap["scene"] = c.Scene
@ -131,6 +133,8 @@ func (c *conversation) fillFieldMap() {
c.fieldMap["status"] = c.Status
c.fieldMap["created_at"] = c.CreatedAt
c.fieldMap["updated_at"] = c.UpdatedAt
c.fieldMap["name"] = c.Name
c.fieldMap["user_id"] = c.UserID
}
func (c conversation) clone(db *gorm.DB) conversation {

View File

@ -40,11 +40,12 @@ func (c *conversationImpl) Create(ctx context.Context, req *entity.CreateMeta) (
var resp *entity.Conversation
doData := &entity.Conversation{
CreatorID: req.UserID,
CreatorID: req.CreatorID,
AgentID: req.AgentID,
Scene: req.Scene,
ConnectorID: req.ConnectorID,
Ext: req.Ext,
UserID: req.UserID,
}
resp, err := c.ConversationRepo.Create(ctx, doData)

View File

@ -57,7 +57,7 @@ func TestCreateConversation(t *testing.T) {
createData, err := NewService(components).Create(ctx, &entity.CreateMeta{
AgentID: 100000,
UserID: 222222,
CreatorID: 222222,
ConnectorID: 100001,
Scene: common.Scene_Playground,
Ext: "debug ext9999",

View File

@ -79,7 +79,7 @@ func (c *CreateConversation) Invoke(ctx context.Context, input map[string]any) (
conversationIDGenerator = workflow.ConversationIDGenerator(func(ctx context.Context, appID int64, userID, connectorID int64) (*conventity.Conversation, error) {
return crossconversation.DefaultSVC().CreateConversation(ctx, &conventity.CreateMeta{
AgentID: appID,
UserID: userID,
CreatorID: userID,
ConnectorID: connectorID,
Scene: common.Scene_SceneWorkflow,
})

View File

@ -89,7 +89,7 @@ func (c *CreateMessage) getConversationIDByName(ctx context.Context, env vo.Env,
conversationIDGenerator := workflow.ConversationIDGenerator(func(ctx context.Context, appID int64, userID, connectorID int64) (*conventity.Conversation, error) {
return crossconversation.DefaultSVC().CreateConversation(ctx, &conventity.CreateMeta{
AgentID: appID,
UserID: userID,
CreatorID: userID,
ConnectorID: connectorID,
Scene: common.Scene_SceneWorkflow,
})

View File

@ -421,9 +421,10 @@ func getExecUserID(ctx context.Context) string {
if execCtx == nil {
panic(fmt.Errorf("unable to get exe context"))
}
if execCtx.RootCtx.ExeCfg.AgentID != nil {
if execCtx.RootCtx.ExeCfg.ConnectorUID != "" {
return execCtx.RootCtx.ExeCfg.ConnectorUID
}
uIDStr := strconv.FormatInt(execCtx.RootCtx.ExeCfg.Operator, 10)
return uIDStr
}

View File

@ -43,7 +43,7 @@ func ExecutePlugin(ctx context.Context, input map[string]any, pe *vo.PluginEntit
}
var uID string
if cfg.AgentID != nil {
if cfg.ConnectorUID != "" {
uID = cfg.ConnectorUID
} else {
uID = conv.Int64ToStr(cfg.Operator)

View File

@ -363,7 +363,7 @@ func (c *conversationImpl) GetOrCreateConversation(ctx context.Context, env vo.E
conversationIDGenerator := workflow.ConversationIDGenerator(func(ctx context.Context, bizID int64, userID, connectorID int64) (*conventity.Conversation, error) {
return crossconversation.DefaultSVC().CreateConversation(ctx, &conventity.CreateMeta{
AgentID: bizID,
UserID: userID,
CreatorID: userID,
ConnectorID: connectorID,
Scene: common.Scene_SceneWorkflow,
})
@ -408,7 +408,7 @@ func (c *conversationImpl) UpdateConversation(ctx context.Context, env vo.Env, a
if existed {
conv, err := crossconversation.DefaultSVC().CreateConversation(ctx, &conventity.CreateMeta{
AgentID: appID,
UserID: userID,
CreatorID: userID,
ConnectorID: connectorID,
Scene: common.Scene_SceneWorkflow,
})
@ -436,7 +436,7 @@ func (c *conversationImpl) UpdateConversation(ctx context.Context, env vo.Env, a
conv, err := crossconversation.DefaultSVC().CreateConversation(ctx, &conventity.CreateMeta{
AgentID: appID,
UserID: userID,
CreatorID: userID,
ConnectorID: connectorID,
Scene: common.Scene_SceneWorkflow,
})