Skip to content

Commit 61e8331

Browse files
authored
feat(singleagent): openapi v3/chat additional message support assista… (#2067)
1 parent ffec252 commit 61e8331

File tree

16 files changed

+299
-69
lines changed

16 files changed

+299
-69
lines changed

backend/application/conversation/openapi_agent_run.go

Lines changed: 76 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import (
2121
"encoding/json"
2222
"errors"
2323
"io"
24+
"slices"
2425
"strconv"
2526

2627
"github.com/cloudwego/eino/schema"
@@ -102,15 +103,15 @@ func (a *OpenapiAgentRunApplication) checkConversation(ctx context.Context, ar *
102103
return nil, err
103104
}
104105
if conData == nil {
105-
return nil, errors.New("conversation data is nil")
106+
return nil, errorx.New(errno.ErrConversationNotFound)
106107
}
107108
conversationData = conData
108109

109110
ar.ConversationID = ptr.Of(conversationData.ID)
110111
}
111112

112113
if conversationData.CreatorID != userID {
113-
return nil, errors.New("conversation data not match")
114+
return nil, errorx.New(errno.ErrConversationPermissionCode, errorx.KV("msg","user not match"))
114115
}
115116

116117
return conversationData, nil
@@ -138,26 +139,31 @@ func (a *OpenapiAgentRunApplication) buildAgentRunRequest(ctx context.Context, a
138139
if err != nil {
139140
return nil, err
140141
}
141-
multiContent, contentType, err := a.buildMultiContent(ctx, ar)
142+
multiAdditionalMessages, err := a.parseAdditionalMessages(ctx, ar)
143+
if err != nil {
144+
return nil, err
145+
}
146+
filterMultiAdditionalMessages, multiContent, contentType, err := a.parseQueryContent(ctx, multiAdditionalMessages)
142147
if err != nil {
143148
return nil, err
144149
}
145150
displayContent := a.buildDisplayContent(ctx, ar)
146151
arm := &entity.AgentRunMeta{
147-
ConversationID: ptr.From(ar.ConversationID),
148-
AgentID: ar.BotID,
149-
Content: multiContent,
150-
DisplayContent: displayContent,
151-
SpaceID: spaceID,
152-
UserID: ar.User,
153-
SectionID: conversationData.SectionID,
154-
PreRetrieveTools: shortcutCMDData,
155-
IsDraft: false,
156-
ConnectorID: connectorID,
157-
ContentType: contentType,
158-
Ext: ar.ExtraParams,
159-
CustomVariables: ar.CustomVariables,
160-
CozeUID: conversationData.CreatorID,
152+
ConversationID: ptr.From(ar.ConversationID),
153+
AgentID: ar.BotID,
154+
Content: multiContent,
155+
DisplayContent: displayContent,
156+
SpaceID: spaceID,
157+
UserID: ar.User,
158+
SectionID: conversationData.SectionID,
159+
PreRetrieveTools: shortcutCMDData,
160+
IsDraft: false,
161+
ConnectorID: connectorID,
162+
ContentType: contentType,
163+
Ext: ar.ExtraParams,
164+
CustomVariables: ar.CustomVariables,
165+
CozeUID: conversationData.CreatorID,
166+
AdditionalMessages: filterMultiAdditionalMessages,
161167
}
162168
return arm, nil
163169
}
@@ -200,29 +206,68 @@ func (a *OpenapiAgentRunApplication) buildDisplayContent(_ context.Context, ar *
200206
return ""
201207
}
202208

203-
func (a *OpenapiAgentRunApplication) buildMultiContent(ctx context.Context, ar *run.ChatV3Request) ([]*message.InputMetaData, message.ContentType, error) {
204-
var multiContents []*message.InputMetaData
205-
contentType := message.ContentTypeText
209+
func (a *OpenapiAgentRunApplication) parseQueryContent(ctx context.Context, multiAdditionalMessages []*entity.AdditionalMessage) ([]*entity.AdditionalMessage, []*message.InputMetaData, message.ContentType, error) {
210+
211+
var multiContent []*message.InputMetaData
212+
var contentType message.ContentType
213+
var filterMultiAdditionalMessages []*entity.AdditionalMessage
214+
filterMultiAdditionalMessages = multiAdditionalMessages
215+
216+
if len(multiAdditionalMessages) > 0 {
217+
lastMessage := multiAdditionalMessages[len(multiAdditionalMessages)-1]
218+
if lastMessage != nil && lastMessage.Role == schema.User {
219+
multiContent = lastMessage.Content
220+
contentType = lastMessage.ContentType
221+
filterMultiAdditionalMessages = multiAdditionalMessages[:len(multiAdditionalMessages)-1]
222+
}
223+
}
224+
225+
return filterMultiAdditionalMessages, multiContent, contentType, nil
226+
}
227+
228+
func (a *OpenapiAgentRunApplication) parseAdditionalMessages(ctx context.Context, ar *run.ChatV3Request) ([]*entity.AdditionalMessage, error) {
229+
230+
additionalMessages := make([]*entity.AdditionalMessage, 0, len(ar.AdditionalMessages))
206231

207232
for _, item := range ar.AdditionalMessages {
208233
if item == nil {
209234
continue
210235
}
211-
if item.Role != string(schema.User) {
212-
return nil, contentType, errors.New("role not match")
236+
if item.Role != string(schema.User) && item.Role != string(schema.Assistant) {
237+
return nil, errors.New("additional message role only support user and assistant")
238+
}
239+
if item.Type != nil && !slices.Contains([]message.MessageType{message.MessageTypeQuestion, message.MessageTypeAnswer}, message.MessageType(*item.Type)) {
240+
return nil, errors.New("additional message type only support question and answer now")
213241
}
242+
243+
addOne := entity.AdditionalMessage{
244+
Role: schema.RoleType(item.Role),
245+
}
246+
if item.Type != nil {
247+
addOne.Type = message.MessageType(*item.Type)
248+
} else {
249+
addOne.Type = message.MessageTypeQuestion
250+
}
251+
214252
if item.ContentType == run.ContentTypeText {
215253
if item.Content == "" {
216254
continue
217255
}
218-
multiContents = append(multiContents, &message.InputMetaData{
256+
257+
addOne.ContentType = message.ContentTypeText
258+
addOne.Content = []*message.InputMetaData{{
219259
Type: message.InputTypeText,
220260
Text: item.Content,
221-
})
261+
}}
222262
}
223263

224264
if item.ContentType == run.ContentTypeMixApi {
225-
contentType = message.ContentTypeMix
265+
266+
if ptr.From(item.Type) == string(message.MessageTypeAnswer) {
267+
return nil, errors.New(" answer messages only support text content")
268+
}
269+
270+
addOne.ContentType = message.ContentTypeMix
226271
var inputs []*run.AdditionalContent
227272
err := json.Unmarshal([]byte(item.Content), &inputs)
228273

@@ -236,7 +281,8 @@ func (a *OpenapiAgentRunApplication) buildMultiContent(ctx context.Context, ar *
236281
}
237282
switch message.InputType(one.Type) {
238283
case message.InputTypeText:
239-
multiContents = append(multiContents, &message.InputMetaData{
284+
285+
addOne.Content = append(addOne.Content, &message.InputMetaData{
240286
Type: message.InputTypeText,
241287
Text: ptr.From(one.Text),
242288
})
@@ -250,12 +296,12 @@ func (a *OpenapiAgentRunApplication) buildMultiContent(ctx context.Context, ar *
250296
ID: one.GetFileID(),
251297
})
252298
if err != nil {
253-
return nil, contentType, err
299+
return nil, err
254300
}
255301
fileUrl = fileInfo.File.Url
256302
fileURI = fileInfo.File.TosURI
257303
}
258-
multiContents = append(multiContents, &message.InputMetaData{
304+
addOne.Content = append(addOne.Content, &message.InputMetaData{
259305
Type: message.InputType(one.Type),
260306
FileData: []*message.FileData{
261307
{
@@ -269,10 +315,10 @@ func (a *OpenapiAgentRunApplication) buildMultiContent(ctx context.Context, ar *
269315
}
270316
}
271317
}
272-
318+
additionalMessages = append(additionalMessages, &addOne)
273319
}
274320

275-
return multiContents, contentType, nil
321+
return additionalMessages, nil
276322
}
277323

278324
func (a *OpenapiAgentRunApplication) pullStream(ctx context.Context, sseSender *sseImpl.SSenderImpl, streamer *schema.StreamReader[*entity.AgentRunResponse]) {

backend/crossdomain/contract/message/message.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ type Message interface {
3030
GetByRunIDs(ctx context.Context, conversationID int64, runIDs []int64) ([]*message.Message, error)
3131
PreCreate(ctx context.Context, msg *message.Message) (*message.Message, error)
3232
Create(ctx context.Context, msg *message.Message) (*message.Message, error)
33+
BatchCreate(ctx context.Context, msg []*message.Message) ([]*message.Message, error)
3334
List(ctx context.Context, meta *entity.ListMeta) (*entity.ListResult, error)
3435
ListWithoutPair(ctx context.Context, req *entity.ListMeta) (*entity.ListResult, error)
3536
Edit(ctx context.Context, msg *message.Message) (*message.Message, error)

backend/crossdomain/contract/message/messagemock/message_mock.go

Lines changed: 15 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

backend/crossdomain/impl/message/message.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,9 @@ func (c *impl) GetMessageByID(ctx context.Context, id int64) (*entity.Message, e
170170
func (c *impl) ListWithoutPair(ctx context.Context, req *entity.ListMeta) (*entity.ListResult, error) {
171171
return c.DomainSVC.ListWithoutPair(ctx, req)
172172
}
173+
func (c *impl) BatchCreate(ctx context.Context, msgs []*entity.Message) ([]*entity.Message, error) {
174+
return c.DomainSVC.BatchCreate(ctx, msgs)
175+
}
173176

174177
func convertToConvAndSchemaMessage(ctx context.Context, msgs []*entity.Message) ([]*crossmessage.WfMessage, []*schema.Message, error) {
175178
messages := make([]*schema.Message, 0)

backend/domain/conversation/agentrun/entity/run_record.go

Lines changed: 28 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -106,24 +106,34 @@ type MetaInfo struct {
106106
}
107107

108108
type AgentRunMeta struct {
109-
ConversationID int64 `json:"conversation_id"`
110-
ConnectorID int64 `json:"connector_id"`
111-
SpaceID int64 `json:"space_id"`
112-
Scene common.Scene `json:"scene"`
113-
SectionID int64 `json:"section_id"`
114-
Name string `json:"name"`
115-
UserID string `json:"user_id"`
116-
CozeUID int64 `json:"coze_uid"`
117-
AgentID int64 `json:"agent_id"`
118-
ContentType message.ContentType `json:"content_type"`
119-
Content []*message.InputMetaData `json:"content"`
120-
PreRetrieveTools []*Tool `json:"tools"`
121-
IsDraft bool `json:"is_draft"`
122-
CustomerConfig *CustomerConfig `json:"customer_config"`
123-
DisplayContent string `json:"display_content"`
124-
CustomVariables map[string]string `json:"custom_variables"`
125-
Version string `json:"version"`
126-
Ext map[string]string `json:"ext"`
109+
ConversationID int64 `json:"conversation_id"`
110+
ConnectorID int64 `json:"connector_id"`
111+
SpaceID int64 `json:"space_id"`
112+
Scene common.Scene `json:"scene"`
113+
SectionID int64 `json:"section_id"`
114+
Name string `json:"name"`
115+
UserID string `json:"user_id"`
116+
CozeUID int64 `json:"coze_uid"`
117+
AgentID int64 `json:"agent_id"`
118+
ContentType message.ContentType `json:"content_type"`
119+
Content []*message.InputMetaData `json:"content"`
120+
PreRetrieveTools []*Tool `json:"tools"`
121+
IsDraft bool `json:"is_draft"`
122+
CustomerConfig *CustomerConfig `json:"customer_config"`
123+
DisplayContent string `json:"display_content"`
124+
CustomVariables map[string]string `json:"custom_variables"`
125+
Version string `json:"version"`
126+
Ext map[string]string `json:"ext"`
127+
AdditionalMessages []*AdditionalMessage `json:"additional_messages"`
128+
}
129+
130+
type AdditionalMessage struct {
131+
Role schema.RoleType `json:"role"`
132+
Type message.MessageType `json:"type"`
133+
Content []*message.InputMetaData `json:"content"`
134+
ContentType message.ContentType `json:"content_type"`
135+
Name *string `json:"name"`
136+
Meta map[string]string `json:"meta"`
127137
}
128138

129139
type UpdateMeta struct {

backend/domain/conversation/agentrun/internal/chatflow_run.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ import (
4141

4242
func (art *AgentRuntime) ChatflowRun(ctx context.Context, imagex imagex.ImageX) (err error) {
4343

44-
mh := &MesssageEventHanlder{
44+
mh := &MessageEventHandler{
4545
sw: art.SW,
4646
messageEvent: art.MessageEvent,
4747
}
@@ -110,7 +110,7 @@ func concatWfInput(rtDependence *AgentRuntime) string {
110110
return strings.Trim(input, ",")
111111
}
112112

113-
func (art *AgentRuntime) pullWfStream(ctx context.Context, events *schema.StreamReader[*crossworkflow.WorkflowMessage], mh *MesssageEventHanlder) {
113+
func (art *AgentRuntime) pullWfStream(ctx context.Context, events *schema.StreamReader[*crossworkflow.WorkflowMessage], mh *MessageEventHandler) {
114114

115115
fullAnswerContent := bytes.NewBuffer([]byte{})
116116
var usage *msgEntity.UsageExt

backend/domain/conversation/agentrun/internal/message_builder.go

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,51 @@ func preCreateAnswer(ctx context.Context, rtDependence *AgentRuntime) (*msgEntit
221221
return crossmessage.DefaultSVC().PreCreate(ctx, msgMeta)
222222
}
223223

224+
func buildAdditionalMessage2Create(ctx context.Context, runRecord *entity.RunRecordMeta, additionalMessage *entity.AdditionalMessage, userID string) *message.Message {
225+
226+
msg := &msgEntity.Message{
227+
ConversationID: runRecord.ConversationID,
228+
RunID: runRecord.ID,
229+
AgentID: runRecord.AgentID,
230+
SectionID: runRecord.SectionID,
231+
UserID: userID,
232+
MessageType: additionalMessage.Type,
233+
}
234+
235+
switch additionalMessage.Type {
236+
case message.MessageTypeQuestion:
237+
msg.Role = schema.User
238+
msg.ContentType = additionalMessage.ContentType
239+
for _, content := range additionalMessage.Content {
240+
if content.Type == message.InputTypeText {
241+
msg.Content = content.Text
242+
break
243+
}
244+
}
245+
msg.MultiContent = additionalMessage.Content
246+
247+
case message.MessageTypeAnswer:
248+
msg.Role = schema.Assistant
249+
msg.ContentType = message.ContentTypeText
250+
for _, content := range additionalMessage.Content {
251+
if content.Type == message.InputTypeText {
252+
msg.Content = content.Text
253+
break
254+
}
255+
}
256+
modelContent := &schema.Message{
257+
Role: schema.Assistant,
258+
Content: msg.Content,
259+
}
260+
261+
jsonContent, err := json.Marshal(modelContent)
262+
if err == nil {
263+
msg.ModelContent = string(jsonContent)
264+
}
265+
}
266+
return msg
267+
}
268+
224269
func buildAgentMessage2Create(ctx context.Context, chunk *entity.AgentRespEvent, messageType message.MessageType, rtDependence *AgentRuntime) *message.Message {
225270
arm := rtDependence.GetRunMeta()
226271
msg := &msgEntity.Message{

0 commit comments

Comments
 (0)