Refactor localization strings to English across various services and UI components

- Updated titles and subtitles in channel_service.go for web channel and WeChat MP channel configurations.
- Changed handoff messages in conversation_human_dispatch_service.go to English.
- Modified notification messages in event handlers for ticket and conversation assignments to English.
- Adjusted ticket creation messages in ticket_service.go to reflect English localization.
- Updated default locale settings in i18n configuration files to English (en-US).
- Changed HTML language attribute in layout.tsx to English.
- Refactored widget locale detection logic in agent-desk-sdk.ts to prioritize English.
This commit is contained in:
mlogclub
2026-05-31 20:06:44 +08:00
parent bcf2ee38c0
commit b128447a7e
36 changed files with 315 additions and 164 deletions
@@ -183,13 +183,13 @@ func recommendNextAction(intent string, signals []string, input AnalyzeConversat
func recommendQuestions(intent string, signals []string, input AnalyzeConversationInput) []string {
questions := make([]string, 0, 3)
if containsSignal(signals, "ticket_expected") && strings.TrimSpace(input.ObservedIssue) == "" {
questions = append(questions, "请进一步确认用户遇到的具体问题现象、报错信息和期望处理结果。")
questions = append(questions, "Please confirm the specific issue, error message, and expected outcome.")
}
if containsSignal(signals, "handoff_requested") {
questions = append(questions, "请确认用户是否明确要求人工客服,以及当前问题为何需要人工继续处理。")
questions = append(questions, "Please confirm whether the user explicitly requested human support and why the issue needs human handling.")
}
if intent == "complaint" {
questions = append(questions, "请确认投诉点、影响范围和用户当前最希望解决的事项。")
questions = append(questions, "Please confirm the complaint, impact, and the user's most important desired outcome.")
}
return questions
}
@@ -89,7 +89,7 @@ func (g *CreateTicketGraph) Run(ctx context.Context, argumentsInJSON string) (st
Handled: true,
Terminal: true,
Action: "ticket_created",
ReplyText: fmt.Sprintf("工单已创建,工单号:%s,标题:%s", strings.TrimSpace(item.TicketNo), strings.TrimSpace(item.Title)),
ReplyText: fmt.Sprintf("Ticket created. Ticket no: %s. Title: %s.", strings.TrimSpace(item.TicketNo), strings.TrimSpace(item.Title)),
ShouldRetry: false,
}), nil
case ConfirmationDecisionCancel:
@@ -134,7 +134,7 @@ func (g *CreateTicketGraph) buildCreateRequest(argumentsInJSON string) (request.
}
func (g *CreateTicketGraph) buildConfirmationPrompt(req request.CreateTicketFromConversationRequest) string {
return fmt.Sprintf("我准备为你创建工单。\n标题:%s\n描述:%s\n请直接回复“确认”或“取消”。",
return fmt.Sprintf("I am ready to create a ticket for you.\nTitle: %s\nDescription: %s\nPlease reply with \"Confirm\" or \"Cancel\".",
strings.TrimSpace(req.Title), strings.TrimSpace(req.Description))
}
+2 -2
View File
@@ -122,7 +122,7 @@ func (g *HandoffGraph) Run(ctx context.Context, argumentsInJSON string) (string,
}
func (g *HandoffGraph) buildReason(argumentsInJSON string) (string, error) {
reason := "用户需要转人工支持"
reason := "The user needs human support."
var args handoffGraphArgs
if strings.TrimSpace(argumentsInJSON) != "" {
if err := json.Unmarshal([]byte(argumentsInJSON), &args); err != nil {
@@ -136,7 +136,7 @@ func (g *HandoffGraph) buildReason(argumentsInJSON string) (string, error) {
}
func (g *HandoffGraph) buildConfirmationPrompt(reason string) string {
return fmt.Sprintf("我准备为你转接人工客服。\n原因:%s\n请直接回复“确认”或“取消”。", strings.TrimSpace(reason))
return fmt.Sprintf("I am ready to connect you to a human support agent.\nReason: %s\nPlease reply with \"Confirm\" or \"Cancel\".", strings.TrimSpace(reason))
}
func parseHandoffDecision(value string) ConfirmationDecision {
+11 -8
View File
@@ -5,11 +5,11 @@ import "strings"
const (
InterruptTypeTicketCreationConfirmation = "ticket_creation_confirmation"
InterruptTypeHandoffConfirmation = "handoff_confirmation"
ConfirmOrCancelPrompt = "请回复“确认”或“取消”。"
NeedExplicitConfirmationPrompt = "我需要你的明确确认,请直接回复“确认”或“取消”。"
ConfirmationExpiredReply = "本次确认已失效,请重新发起。"
CancelCreateTicketReply = "已取消本次工单创建。"
CancelHandoffReply = "已取消本次转人工。"
ConfirmOrCancelPrompt = `Please reply with "Confirm" or "Cancel".`
NeedExplicitConfirmationPrompt = `I need your explicit confirmation. Please reply with "Confirm" or "Cancel".`
ConfirmationExpiredReply = "This confirmation has expired. Please start again."
CancelCreateTicketReply = "Ticket creation has been cancelled."
CancelHandoffReply = "Human handoff has been cancelled."
)
type ConfirmationDecision string
@@ -24,13 +24,13 @@ func ParseConfirmationDecision(value string) ConfirmationDecision {
if value == "" {
return ""
}
confirmWords := []string{"确认", "是", "好的", "可以", "ok", "yes", "继续", "同意"}
confirmWords := []string{"确认", "是", "好的", "可以", "ok", "yes", "continue", "confirm", "继续", "同意"}
for _, item := range confirmWords {
if strings.Contains(value, item) {
return ConfirmationDecisionConfirm
}
}
cancelWords := []string{"取消", "不用", "不需要", "算了", "no"}
cancelWords := []string{"取消", "不用", "不需要", "算了", "no", "cancel"}
for _, item := range cancelWords {
if strings.Contains(value, item) {
return ConfirmationDecisionCancel
@@ -41,5 +41,8 @@ func ParseConfirmationDecision(value string) ConfirmationDecision {
func IsCancellationReply(replyText string) bool {
replyText = strings.TrimSpace(replyText)
return strings.Contains(replyText, CancelCreateTicketReply) || strings.Contains(replyText, CancelHandoffReply)
return strings.Contains(replyText, CancelCreateTicketReply) ||
strings.Contains(replyText, CancelHandoffReply) ||
strings.Contains(replyText, "已取消本次工单创建。") ||
strings.Contains(replyText, "已取消本次转人工。")
}
@@ -78,11 +78,11 @@ func buildPrepareTicketDraftResult(conversation models.Conversation, messages []
result.Description = buildDraftDescription(conversation, messages, input)
if strings.TrimSpace(result.Title) == "" {
result.MissingFields = append(result.MissingFields, "title")
result.FollowUpQuestions = append(result.FollowUpQuestions, "请补充一个简洁的工单标题,明确概括用户遇到的问题。")
result.FollowUpQuestions = append(result.FollowUpQuestions, "Please provide a concise ticket title that clearly summarizes the issue.")
}
if !hasSufficientIssueContext(input, result.Description) {
result.MissingFields = append(result.MissingFields, "issue")
result.FollowUpQuestions = append(result.FollowUpQuestions, "请补充具体问题现象、报错信息或用户诉求,以便整理成工单。")
result.FollowUpQuestions = append(result.FollowUpQuestions, "Please provide the specific issue, error message, or request so I can prepare the ticket.")
}
result.Ready = result.Title != "" && result.Description != "" && len(result.MissingFields) == 0
return result
@@ -107,22 +107,22 @@ func buildDraftDescription(conversation models.Conversation, messages []models.M
}
parts := make([]string, 0, 6)
if input.Issue != "" {
parts = append(parts, "问题现象:"+input.Issue)
parts = append(parts, "Issue: "+input.Issue)
}
if input.Impact != "" {
parts = append(parts, "影响范围:"+input.Impact)
parts = append(parts, "Impact: "+input.Impact)
}
if input.ExpectedOutcome != "" {
parts = append(parts, "用户诉求:"+input.ExpectedOutcome)
parts = append(parts, "Requested outcome: "+input.ExpectedOutcome)
}
if input.CurrentAttempt != "" {
parts = append(parts, "已尝试处理:"+input.CurrentAttempt)
parts = append(parts, "Attempts so far: "+input.CurrentAttempt)
}
if strings.TrimSpace(conversation.LastMessageSummary) != "" {
parts = append(parts, "会话摘要:"+strings.TrimSpace(conversation.LastMessageSummary))
parts = append(parts, "Conversation summary: "+strings.TrimSpace(conversation.LastMessageSummary))
}
if recent := buildRecentMessageDigest(messages); recent != "" {
parts = append(parts, "最近消息:"+recent)
parts = append(parts, "Recent messages: "+recent)
}
return strings.TrimSpace(strings.Join(parts, "\n"))
}
@@ -137,10 +137,10 @@ func hasSufficientIssueContext(input PrepareTicketDraftInput, description string
func buildConversationFacts(conversation models.Conversation, messages []models.Message) []string {
facts := make([]string, 0, 4)
if strings.TrimSpace(conversation.LastMessageSummary) != "" {
facts = append(facts, "最近摘要:"+strings.TrimSpace(conversation.LastMessageSummary))
facts = append(facts, "Recent summary: "+strings.TrimSpace(conversation.LastMessageSummary))
}
if digest := buildRecentMessageDigest(messages); digest != "" {
facts = append(facts, "最近消息:"+digest)
facts = append(facts, "Recent messages: "+digest)
}
return facts
}
@@ -163,13 +163,13 @@ func buildRecentMessageDigest(messages []models.Message) string {
func messageSenderLabel(senderType enums.IMSenderType) string {
switch senderType {
case enums.IMSenderTypeCustomer:
return "用户"
return "Customer"
case enums.IMSenderTypeAgent:
return "客服"
return "Agent"
case enums.IMSenderTypeAI:
return "AI"
default:
return "消息"
return "Message"
}
}