kao0312 commited on
Commit
3dad4b0
·
1 Parent(s): 12aa997

fix: support multimodal image upload

Browse files
Files changed (2) hide show
  1. internal/chat.go +31 -30
  2. internal/models.go +33 -5
internal/chat.go CHANGED
@@ -65,10 +65,35 @@ func makeUpstreamRequest(token string, messages []Message, model string) (*http.
65
  autoWebSearch = false
66
  }
67
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
68
  // 转换消息为上游格式
69
- var upstreamMessages []map[string]string
70
  for _, msg := range messages {
71
- upstreamMessages = append(upstreamMessages, msg.ToUpstreamMessage())
72
  }
73
 
74
  body := map[string]interface{}{
@@ -88,34 +113,10 @@ func makeUpstreamRequest(token string, messages []Message, model string) (*http.
88
  "id": uuid.New().String(),
89
  }
90
 
91
- // 处理图片上传
92
- if len(imageURLs) > 0 {
93
- files, err := UploadImages(token, imageURLs)
94
- if err != nil {
95
- LogError("Failed to upload images: %v", err)
96
- }
97
- if len(files) > 0 {
98
- // 设置 ref_user_msg_id
99
- var filesData []map[string]interface{}
100
- for _, f := range files {
101
- fileMap := map[string]interface{}{
102
- "type": f.Type,
103
- "file": f.File,
104
- "id": f.ID,
105
- "url": f.URL,
106
- "name": f.Name,
107
- "status": f.Status,
108
- "size": f.Size,
109
- "error": f.Error,
110
- "itemId": f.ItemID,
111
- "media": f.Media,
112
- "ref_user_msg_id": userMsgID,
113
- }
114
- filesData = append(filesData, fileMap)
115
- }
116
- body["files"] = filesData
117
- body["current_user_message_id"] = userMsgID
118
- }
119
  }
120
 
121
  bodyBytes, _ := json.Marshal(body)
 
65
  autoWebSearch = false
66
  }
67
 
68
+ // 上传图片并建立URL→FileID映射
69
+ urlToFileID := make(map[string]string)
70
+ var filesData []map[string]interface{}
71
+ if len(imageURLs) > 0 {
72
+ files, _ := UploadImages(token, imageURLs)
73
+ for i, f := range files {
74
+ if i < len(imageURLs) {
75
+ urlToFileID[imageURLs[i]] = f.ID
76
+ }
77
+ filesData = append(filesData, map[string]interface{}{
78
+ "type": f.Type,
79
+ "file": f.File,
80
+ "id": f.ID,
81
+ "url": f.URL,
82
+ "name": f.Name,
83
+ "status": f.Status,
84
+ "size": f.Size,
85
+ "error": f.Error,
86
+ "itemId": f.ItemID,
87
+ "media": f.Media,
88
+ "ref_user_msg_id": userMsgID,
89
+ })
90
+ }
91
+ }
92
+
93
  // 转换消息为上游格式
94
+ var upstreamMessages []map[string]interface{}
95
  for _, msg := range messages {
96
+ upstreamMessages = append(upstreamMessages, msg.ToUpstreamMessage(urlToFileID))
97
  }
98
 
99
  body := map[string]interface{}{
 
113
  "id": uuid.New().String(),
114
  }
115
 
116
+ // 添加files字段
117
+ if len(filesData) > 0 {
118
+ body["files"] = filesData
119
+ body["current_user_message_id"] = userMsgID
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
120
  }
121
 
122
  bodyBytes, _ := json.Marshal(body)
internal/models.go CHANGED
@@ -111,12 +111,40 @@ func (m *Message) ParseContent() (text string, imageURLs []string) {
111
  return text, imageURLs
112
  }
113
 
114
- // 转换为上游消息格式(纯文本)
115
- func (m *Message) ToUpstreamMessage() map[string]string {
116
- text, _ := m.ParseContent()
117
- return map[string]string{
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
118
  "role": m.Role,
119
- "content": text,
120
  }
121
  }
122
 
 
111
  return text, imageURLs
112
  }
113
 
114
+ // 转换为上游消息格式,支持多模态
115
+ func (m *Message) ToUpstreamMessage(urlToFileID map[string]string) map[string]interface{} {
116
+ text, imageURLs := m.ParseContent()
117
+
118
+ // 无图片,返回纯文本
119
+ if len(imageURLs) == 0 {
120
+ return map[string]interface{}{
121
+ "role": m.Role,
122
+ "content": text,
123
+ }
124
+ }
125
+
126
+ // 有图片,构建多模态内容
127
+ var content []interface{}
128
+ if text != "" {
129
+ content = append(content, map[string]interface{}{
130
+ "type": "text",
131
+ "text": text,
132
+ })
133
+ }
134
+ for _, imgURL := range imageURLs {
135
+ if fileID, ok := urlToFileID[imgURL]; ok {
136
+ content = append(content, map[string]interface{}{
137
+ "type": "image_url",
138
+ "image_url": map[string]interface{}{
139
+ "url": fileID,
140
+ },
141
+ })
142
+ }
143
+ }
144
+
145
+ return map[string]interface{}{
146
  "role": m.Role,
147
+ "content": content,
148
  }
149
  }
150