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
|
||||
}
|
||||
|
||||
// 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
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue