diff --git a/agent/context/buffer.go b/agent/context/buffer.go index 3659be4f..1c36a0b1 100644 --- a/agent/context/buffer.go +++ b/agent/context/buffer.go @@ -382,9 +382,14 @@ func (b *ChatBuffer) GetStepsForResume(finalStatus string) []*BufferedStep { b.currentStep.Status = finalStatus } - // Return all steps (they will all have the context for recovery) - result := make([]*BufferedStep, len(b.steps)) - copy(result, b.steps) + // Only return steps with valid resume status (failed or interrupted) + result := make([]*BufferedStep, 0, len(b.steps)) + for _, step := range b.steps { + if step.Status != ResumeStatusFailed && step.Status != ResumeStatusInterrupted { + continue + } + result = append(result, step) + } return result } diff --git a/agent/robot/events/integrations/dingtalk/message.go b/agent/robot/events/integrations/dingtalk/message.go index cd510254..9a323f3e 100644 --- a/agent/robot/events/integrations/dingtalk/message.go +++ b/agent/robot/events/integrations/dingtalk/message.go @@ -91,12 +91,23 @@ func buildContentParts(cm *dtapi.ConvertedMessage) []interface{} { if url == "" { url = mi.URL } - parts = append(parts, map[string]interface{}{ - "type": "file", - "file_url": url, - "mime_type": mi.MimeType, - "file_name": mi.FileName, - }) + if strings.HasPrefix(mi.MimeType, "image/") { + parts = append(parts, map[string]interface{}{ + "type": "image_url", + "image_url": map[string]interface{}{ + "url": url, + "detail": "auto", + }, + }) + } else { + parts = append(parts, map[string]interface{}{ + "type": "file", + "file": map[string]interface{}{ + "url": url, + "filename": mi.FileName, + }, + }) + } } return parts diff --git a/agent/robot/events/integrations/discord/message.go b/agent/robot/events/integrations/discord/message.go index 42b69c59..3a8d7397 100644 --- a/agent/robot/events/integrations/discord/message.go +++ b/agent/robot/events/integrations/discord/message.go @@ -96,12 +96,23 @@ func buildContentParts(cm *dcapi.ConvertedMessage) []interface{} { if url == "" { continue } - parts = append(parts, map[string]interface{}{ - "type": "file", - "file_url": url, - "mime_type": mi.ContentType, - "file_name": mi.FileName, - }) + if strings.HasPrefix(mi.ContentType, "image/") { + parts = append(parts, map[string]interface{}{ + "type": "image_url", + "image_url": map[string]interface{}{ + "url": url, + "detail": "auto", + }, + }) + } else { + parts = append(parts, map[string]interface{}{ + "type": "file", + "file": map[string]interface{}{ + "url": url, + "filename": mi.FileName, + }, + }) + } } return parts diff --git a/agent/robot/events/integrations/feishu/message.go b/agent/robot/events/integrations/feishu/message.go index 9cd093c6..ceff60c5 100644 --- a/agent/robot/events/integrations/feishu/message.go +++ b/agent/robot/events/integrations/feishu/message.go @@ -85,12 +85,23 @@ func buildContentParts(cm *fsapi.ConvertedMessage) []interface{} { if mi.Wrapper == "" { continue } - parts = append(parts, map[string]interface{}{ - "type": "file", - "file_url": mi.Wrapper, - "mime_type": mi.MimeType, - "file_name": mi.FileName, - }) + if strings.HasPrefix(mi.MimeType, "image/") { + parts = append(parts, map[string]interface{}{ + "type": "image_url", + "image_url": map[string]interface{}{ + "url": mi.Wrapper, + "detail": "auto", + }, + }) + } else { + parts = append(parts, map[string]interface{}{ + "type": "file", + "file": map[string]interface{}{ + "url": mi.Wrapper, + "filename": mi.FileName, + }, + }) + } } return parts diff --git a/agent/robot/events/integrations/telegram/message.go b/agent/robot/events/integrations/telegram/message.go index 00b83887..21fc70da 100644 --- a/agent/robot/events/integrations/telegram/message.go +++ b/agent/robot/events/integrations/telegram/message.go @@ -93,12 +93,23 @@ func buildContentParts(cm *tgapi.ConvertedMessage) []interface{} { if mi.Wrapper == "" { continue } - parts = append(parts, map[string]interface{}{ - "type": "file", - "file_url": mi.Wrapper, - "mime_type": mi.MimeType, - "file_name": mi.FileName, - }) + if strings.HasPrefix(mi.MimeType, "image/") { + parts = append(parts, map[string]interface{}{ + "type": "image_url", + "image_url": map[string]interface{}{ + "url": mi.Wrapper, + "detail": "auto", + }, + }) + } else { + parts = append(parts, map[string]interface{}{ + "type": "file", + "file": map[string]interface{}{ + "url": mi.Wrapper, + "filename": mi.FileName, + }, + }) + } } return parts diff --git a/agent/robot/events/integrations/weixin/polling.go b/agent/robot/events/integrations/weixin/polling.go index f3eaf0a9..58d867d3 100644 --- a/agent/robot/events/integrations/weixin/polling.go +++ b/agent/robot/events/integrations/weixin/polling.go @@ -3,6 +3,7 @@ package weixin import ( "context" "fmt" + "strings" "time" agentcontext "github.com/yaoapp/yao/agent/context" @@ -113,12 +114,23 @@ func (a *Adapter) handleMessage(ctx context.Context, entry *botEntry, msg *weixi parts = append(parts, map[string]interface{}{"type": "text", "text": content}) } for _, m := range mediaItems { - parts = append(parts, map[string]interface{}{ - "type": "file", - "file_url": m.Wrapper, - "mime_type": m.MimeType, - "file_name": m.FileName, - }) + if strings.HasPrefix(m.MimeType, "image/") { + parts = append(parts, map[string]interface{}{ + "type": "image_url", + "image_url": map[string]interface{}{ + "url": m.Wrapper, + "detail": "auto", + }, + }) + } else { + parts = append(parts, map[string]interface{}{ + "type": "file", + "file": map[string]interface{}{ + "url": m.Wrapper, + "filename": m.FileName, + }, + }) + } } msgContent = parts } diff --git a/agent/robot/events/message.go b/agent/robot/events/message.go index 468fb365..69c880ff 100644 --- a/agent/robot/events/message.go +++ b/agent/robot/events/message.go @@ -33,6 +33,15 @@ func (h *robotHandler) handleMessage(ctx context.Context, ev *eventtypes.Event, result, err := callHostAgent(ctx, &payload) if err != nil { log.Error("message handler: host agent call failed robot=%s: %v", payload.RobotID, err) + + if reply := getReplyFunc(); reply != nil { + errMsg := friendlyErrorMessage(payload.Metadata.Locale) + _ = reply(ctx, &agentcontext.Message{ + Role: agentcontext.RoleAssistant, + Content: errMsg, + }, payload.Metadata) + } + if ev.IsCall { resp <- eventtypes.Result{Err: err} } @@ -233,6 +242,13 @@ func resolveHostAssistantID(ctx context.Context, memberID string) (string, *robo return hostID, record, nil } +func friendlyErrorMessage(locale string) string { + if strings.HasPrefix(locale, "zh") { + return "抱歉,处理您的消息时出现了问题,请稍后重试。" + } + return "Sorry, there was a problem processing your message. Please try again later." +} + func taskDeployedMessage(execID string, locale string) string { if strings.HasPrefix(locale, "zh") { return fmt.Sprintf("任务已部署(执行编号: %s),完成后会将结果发送给你。", execID)