fix: XML动作标签 + 意图分析上下文 + 图片file_id引用
- 动作消息改用 <action>...</action> XML 标签(注入器 + 解析器 + 测试) - 括号解析保留为降级方案,确保向后兼容 - 意图分析传入最近对话历史,防止短追问误判为 iot_query - 意图提示词强化:短追问明确归为 question,iot_query 需设备名词 - 图片附件支持 file_id 轻量引用(Gateway FileStore 解析 + 上传端点复用) - API 文档更新:附件新格式 + 图片传递链路 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -28,15 +28,17 @@ type ChatHandler struct {
|
||||
cfg *config.Config
|
||||
hub *ws.Hub
|
||||
sessionStore *store.SessionStore
|
||||
fileStore *store.FileStore
|
||||
upgrader websocket.Upgrader
|
||||
}
|
||||
|
||||
// NewChatHandler 创建聊天处理器
|
||||
func NewChatHandler(cfg *config.Config, hub *ws.Hub, sessionStore *store.SessionStore) *ChatHandler {
|
||||
func NewChatHandler(cfg *config.Config, hub *ws.Hub, sessionStore *store.SessionStore, fileStore *store.FileStore) *ChatHandler {
|
||||
return &ChatHandler{
|
||||
cfg: cfg,
|
||||
hub: hub,
|
||||
sessionStore: sessionStore,
|
||||
fileStore: fileStore,
|
||||
upgrader: websocket.Upgrader{
|
||||
ReadBufferSize: 1024,
|
||||
WriteBufferSize: 1024,
|
||||
@@ -154,13 +156,26 @@ func (h *ChatHandler) handleChatMessage(client *ws.Client, msg ws.ClientMessage)
|
||||
if len(msg.Attachments) > 0 {
|
||||
images := make([]string, 0, len(msg.Attachments))
|
||||
for _, att := range msg.Attachments {
|
||||
if att.Type == "image" && att.URL != "" {
|
||||
imgURL := att.URL
|
||||
// 将相对路径转换为绝对 URL,方便 AI-Core 访问
|
||||
if strings.HasPrefix(imgURL, "/") {
|
||||
imgURL = "http://127.0.0.1:" + h.cfg.Port + imgURL
|
||||
if att.Type == "image" {
|
||||
imgURL := ""
|
||||
// 优先使用 file_id 引用(轻量,支持跨设备同步)
|
||||
if att.FileID != "" && h.fileStore != nil {
|
||||
if f, err := h.fileStore.GetFile(att.FileID); err == nil {
|
||||
imgURL = "http://127.0.0.1:" + h.cfg.Port + "/api/v1/files/" + f.ID + "/download"
|
||||
} else {
|
||||
logger.Printf("[chat] file_id 解析失败: %s, err=%v", att.FileID, err)
|
||||
}
|
||||
}
|
||||
// 回退: 使用 URL(兼容旧客户端 base64 data URI)
|
||||
if imgURL == "" && att.URL != "" {
|
||||
imgURL = att.URL
|
||||
if strings.HasPrefix(imgURL, "/") {
|
||||
imgURL = "http://127.0.0.1:" + h.cfg.Port + imgURL
|
||||
}
|
||||
}
|
||||
if imgURL != "" {
|
||||
images = append(images, imgURL)
|
||||
}
|
||||
images = append(images, imgURL)
|
||||
}
|
||||
}
|
||||
if len(images) > 0 {
|
||||
|
||||
@@ -27,7 +27,7 @@ func Setup(r *gin.Engine, hub *ws.Hub, cfg *config.Config, sessionStore *store.S
|
||||
authHandler := handler.NewAuthHandler(cfg, authDB)
|
||||
sessionHandler := handler.NewSessionHandler(hub, sessionStore)
|
||||
memoryHandler := handler.NewMemoryHandler(cfg.MemoryServiceURL)
|
||||
chatHandler := handler.NewChatHandler(cfg, hub, sessionStore)
|
||||
chatHandler := handler.NewChatHandler(cfg, hub, sessionStore, fileStore)
|
||||
webhookHandler := handler.NewWebhookHandler(cfg, hub)
|
||||
notificationHandler := handler.NewNotificationHandler(cfg, hub)
|
||||
reminderHandler := handler.NewReminderHandler(reminderStore, hub)
|
||||
|
||||
@@ -2,14 +2,15 @@ package ws
|
||||
|
||||
// MessageAttachment 消息附件 (图片等)
|
||||
type MessageAttachment struct {
|
||||
Type string `json:"type"` // image
|
||||
URL string `json:"url"` // 图片 URL 或 data URL
|
||||
ThumbnailURL string `json:"thumbnail_url,omitempty"`
|
||||
Filename string `json:"filename,omitempty"`
|
||||
Width int `json:"width,omitempty"`
|
||||
Height int `json:"height,omitempty"`
|
||||
Size int64 `json:"size,omitempty"` // 文件大小 bytes
|
||||
Description string `json:"description,omitempty"` // AI 对图片的描述
|
||||
Type string `json:"type"` // image
|
||||
URL string `json:"url,omitempty"` // 图片 URL 或 data URL(旧格式,向后兼容)
|
||||
FileID string `json:"file_id,omitempty"` // 文件 ID(新格式,轻量引用)
|
||||
ThumbnailURL string `json:"thumbnail_url,omitempty"` // 缩略图 URL
|
||||
Filename string `json:"filename,omitempty"`
|
||||
Width int `json:"width,omitempty"`
|
||||
Height int `json:"height,omitempty"`
|
||||
Size int64 `json:"size,omitempty"` // 文件大小 bytes
|
||||
Description string `json:"description,omitempty"` // AI 对图片的描述
|
||||
}
|
||||
|
||||
// 客户端 → 服务端消息
|
||||
|
||||
Reference in New Issue
Block a user