fix(runtime): dispatch explicit human handoff requests without model
This commit is contained in:
@@ -4,9 +4,11 @@ import (
|
||||
"context"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
"unicode"
|
||||
|
||||
"code.tczkiot.com/wlw/ai-agent/contract"
|
||||
applicationruntime "code.tczkiot.com/wlw/ai-agent/internal/ai/application/runtime"
|
||||
@@ -27,6 +29,26 @@ const aiReplyInvocationToolCode = "runtime/ai_reply"
|
||||
|
||||
const aiReplyInvocationRecoveryGrace = 30 * time.Second
|
||||
|
||||
// Match complete commands, not mentions such as “不要转人工” or “转人工是什么意思”.
|
||||
// These requests must not depend on the model choosing to call a tool.
|
||||
var explicitHumanHandoffCommand = regexp.MustCompile(`^(请|麻烦)?(帮我|给我)?(我要|我想要|我想)?(转接|转|找|联系|接通)?(一下)?人工(客服|服务)?(谢谢|吧)?$`)
|
||||
|
||||
func isExplicitHumanHandoffRequest(message models.Message) bool {
|
||||
if message.SenderType != enums.IMSenderTypeCustomer || message.MessageType != enums.IMMessageTypeText {
|
||||
return false
|
||||
}
|
||||
content := strings.TrimFunc(strings.TrimSpace(message.Content), func(r rune) bool {
|
||||
return unicode.IsSpace(r) || strings.ContainsRune("。!!,,??;;", r)
|
||||
})
|
||||
content = strings.Map(func(r rune) rune {
|
||||
if unicode.IsSpace(r) {
|
||||
return -1
|
||||
}
|
||||
return r
|
||||
}, content)
|
||||
return explicitHumanHandoffCommand.MatchString(content)
|
||||
}
|
||||
|
||||
func (s *aiReplyService) resolveReplyTimeout(aiAgent models.AIAgent) time.Duration {
|
||||
if aiAgent.ReplyTimeoutSeconds <= 0 {
|
||||
return time.Duration(defaultAIReplyAsyncTimeoutSeconds) * time.Second
|
||||
@@ -313,6 +335,12 @@ func (s *aiReplyService) TriggerReply(ctx context.Context, conversation models.C
|
||||
if !IsAIAgentRolloutEligible(conversation, aiAgent, svc.ChannelService.Get(conversation.ChannelID)) {
|
||||
return nil
|
||||
}
|
||||
if isExplicitHumanHandoffRequest(message) {
|
||||
_, err := svc.ConversationHumanDispatchService.HandoffByAIWithRequestID(
|
||||
conversation.ID, aiAgent, strings.TrimSpace(message.Content), message.RequestID,
|
||||
)
|
||||
return err
|
||||
}
|
||||
identityResolution, identityErr := resolveGuestBusinessIdentity(ctx, conversation, message)
|
||||
if identityErr != nil || identityResolution.NeedsPrompt {
|
||||
_, err := s.commit.CommitAIReply(replyCommitInput{
|
||||
|
||||
Reference in New Issue
Block a user