feat(buffer): refine step retrieval for resume functionality
- Updated the GetStepsForResume method to return only steps with valid resume statuses (failed or interrupted), improving recovery context handling. - Enhanced error handling in message processing across various integrations, including friendly error messages for users in different locales. - Modified file handling in message integrations (Dingtalk, Discord, Feishu, Telegram, Weixin) to differentiate between image and file types, ensuring appropriate content delivery.
This commit is contained in:
parent
4376ac9dad
commit
421d946971
7 changed files with 110 additions and 33 deletions
|
|
@ -382,9 +382,14 @@ func (b *ChatBuffer) GetStepsForResume(finalStatus string) []*BufferedStep {
|
||||||
b.currentStep.Status = finalStatus
|
b.currentStep.Status = finalStatus
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return all steps (they will all have the context for recovery)
|
// Only return steps with valid resume status (failed or interrupted)
|
||||||
result := make([]*BufferedStep, len(b.steps))
|
result := make([]*BufferedStep, 0, len(b.steps))
|
||||||
copy(result, b.steps)
|
for _, step := range b.steps {
|
||||||
|
if step.Status != ResumeStatusFailed && step.Status != ResumeStatusInterrupted {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
result = append(result, step)
|
||||||
|
}
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -91,13 +91,24 @@ func buildContentParts(cm *dtapi.ConvertedMessage) []interface{} {
|
||||||
if url == "" {
|
if url == "" {
|
||||||
url = mi.URL
|
url = mi.URL
|
||||||
}
|
}
|
||||||
|
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{}{
|
parts = append(parts, map[string]interface{}{
|
||||||
"type": "file",
|
"type": "file",
|
||||||
"file_url": url,
|
"file": map[string]interface{}{
|
||||||
"mime_type": mi.MimeType,
|
"url": url,
|
||||||
"file_name": mi.FileName,
|
"filename": mi.FileName,
|
||||||
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return parts
|
return parts
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -96,13 +96,24 @@ func buildContentParts(cm *dcapi.ConvertedMessage) []interface{} {
|
||||||
if url == "" {
|
if url == "" {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
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{}{
|
parts = append(parts, map[string]interface{}{
|
||||||
"type": "file",
|
"type": "file",
|
||||||
"file_url": url,
|
"file": map[string]interface{}{
|
||||||
"mime_type": mi.ContentType,
|
"url": url,
|
||||||
"file_name": mi.FileName,
|
"filename": mi.FileName,
|
||||||
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return parts
|
return parts
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -85,13 +85,24 @@ func buildContentParts(cm *fsapi.ConvertedMessage) []interface{} {
|
||||||
if mi.Wrapper == "" {
|
if mi.Wrapper == "" {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
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{}{
|
parts = append(parts, map[string]interface{}{
|
||||||
"type": "file",
|
"type": "file",
|
||||||
"file_url": mi.Wrapper,
|
"file": map[string]interface{}{
|
||||||
"mime_type": mi.MimeType,
|
"url": mi.Wrapper,
|
||||||
"file_name": mi.FileName,
|
"filename": mi.FileName,
|
||||||
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return parts
|
return parts
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -93,13 +93,24 @@ func buildContentParts(cm *tgapi.ConvertedMessage) []interface{} {
|
||||||
if mi.Wrapper == "" {
|
if mi.Wrapper == "" {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
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{}{
|
parts = append(parts, map[string]interface{}{
|
||||||
"type": "file",
|
"type": "file",
|
||||||
"file_url": mi.Wrapper,
|
"file": map[string]interface{}{
|
||||||
"mime_type": mi.MimeType,
|
"url": mi.Wrapper,
|
||||||
"file_name": mi.FileName,
|
"filename": mi.FileName,
|
||||||
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return parts
|
return parts
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ package weixin
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
agentcontext "github.com/yaoapp/yao/agent/context"
|
agentcontext "github.com/yaoapp/yao/agent/context"
|
||||||
|
|
@ -113,13 +114,24 @@ func (a *Adapter) handleMessage(ctx context.Context, entry *botEntry, msg *weixi
|
||||||
parts = append(parts, map[string]interface{}{"type": "text", "text": content})
|
parts = append(parts, map[string]interface{}{"type": "text", "text": content})
|
||||||
}
|
}
|
||||||
for _, m := range mediaItems {
|
for _, m := range mediaItems {
|
||||||
|
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{}{
|
parts = append(parts, map[string]interface{}{
|
||||||
"type": "file",
|
"type": "file",
|
||||||
"file_url": m.Wrapper,
|
"file": map[string]interface{}{
|
||||||
"mime_type": m.MimeType,
|
"url": m.Wrapper,
|
||||||
"file_name": m.FileName,
|
"filename": m.FileName,
|
||||||
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
}
|
||||||
msgContent = parts
|
msgContent = parts
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -33,6 +33,15 @@ func (h *robotHandler) handleMessage(ctx context.Context, ev *eventtypes.Event,
|
||||||
result, err := callHostAgent(ctx, &payload)
|
result, err := callHostAgent(ctx, &payload)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("message handler: host agent call failed robot=%s: %v", payload.RobotID, err)
|
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 {
|
if ev.IsCall {
|
||||||
resp <- eventtypes.Result{Err: err}
|
resp <- eventtypes.Result{Err: err}
|
||||||
}
|
}
|
||||||
|
|
@ -233,6 +242,13 @@ func resolveHostAssistantID(ctx context.Context, memberID string) (string, *robo
|
||||||
return hostID, record, nil
|
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 {
|
func taskDeployedMessage(execID string, locale string) string {
|
||||||
if strings.HasPrefix(locale, "zh") {
|
if strings.HasPrefix(locale, "zh") {
|
||||||
return fmt.Sprintf("任务已部署(执行编号: %s),完成后会将结果发送给你。", execID)
|
return fmt.Sprintf("任务已部署(执行编号: %s),完成后会将结果发送给你。", execID)
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue