Localize user-facing UI, agent output, and backend messages to Simplified Chinese
ci / go (push) Waiting to run
ci / go-db (agent) (push) Waiting to run
ci / go-db (config) (push) Waiting to run
ci / go-db (db) (push) Waiting to run
ci / go-db (evidence) (push) Waiting to run
ci / go-db (llmrec) (push) Waiting to run
ci / go-db (server) (push) Waiting to run
detections / detections (push) Waiting to run
docs / links (push) Waiting to run
web / web (push) Waiting to run

This commit is contained in:
dela
2026-10-09 14:08:31 +08:00
parent 8af63417c8
commit 97668dab7e
148 changed files with 1671 additions and 1672 deletions
+15 -15
View File
@@ -30,15 +30,15 @@ import (
// (판정 프롬프트 본문)는 번역하지 않으며, [模型] 센티넬(decision_source 분류용 · UI 에서
// 표시 전 제거 · db SQL LIKE·HasPrefix 소비처와 결합)도 원문 그대로 둔다.
const (
msgReviewContextIncomplete = "검토 맥락이 완전하지 않아 사람의 확인이 필요합니다: "
msgModelApprovalFailed = "모델 승인에 실패하여 실패 정책에 따라 처리합니다: "
msgModelOutputUnparsable = "모델 출력을 해석할 수 없어 실패 정책에 따라 처리합니다"
msgToolApprovalRequestFmt = "도구 %s 승인 요청 (#%d)"
reasonWorkCanceled = "작업이 취소되었습니다"
reasonWorkCanceledPreExec = "실행 전에 작업이 취소되었습니다"
reasonApprovalTimeout = "승인 시간이 초과되어 시간 초과 정책에 따라 처리합니다"
reasonManualDeny = "사람이 실행을 거부했습니다"
reasonManualAllow = "사람이 실행을 허용했습니다"
msgReviewContextIncomplete = "审查上下文不完整,需要人工确认:"
msgModelApprovalFailed = "模型审批失败,将按失败策略处理:"
msgModelOutputUnparsable = "无法解析模型输出,将按失败策略处理"
msgToolApprovalRequestFmt = "工具 %s 审批请求 (#%d)"
reasonWorkCanceled = "任务已取消"
reasonWorkCanceledPreExec = "执行前任务已取消"
reasonApprovalTimeout = "审批超时,将按超时策略处理"
reasonManualDeny = "人工拒绝执行"
reasonManualAllow = "人工允许执行"
)
// ctxKey is the unexported context key type to avoid collisions.
@@ -508,11 +508,11 @@ func (i *Interceptor) Judge(ctx context.Context, tool string, arguments json.Raw
func judgeActionLabel(action string) string {
switch action {
case "allow":
return "허용"
return "允许"
case "deny":
return "차단"
return "阻止"
case "ask":
return "확인 요청"
return "请求确认"
default:
return action
}
@@ -566,9 +566,9 @@ func ruleMatches(r compiledRule, toolName string, input []byte) bool {
func defaultMessage(action, name string) string {
switch action {
case "deny":
return "가로채기 규칙 [" + name + "] 에 따라 이 도구를 실행할 수 없습니다"
return "根据拦截规则 [" + name + "],无法执行此工具"
case "ask":
return "가로채기 규칙 [" + name + "] 에 따라 사용자 승인이 필요합니다. 잠시 기다려 주세요"
return "根据拦截规则 [" + name + "],需要用户审批。请稍候"
default:
return ""
}
@@ -681,7 +681,7 @@ func (i *Interceptor) HandleAsk(ctx context.Context, convID int64, dec Decision,
}
}
var ErrAlreadyDecided = errors.New("이미 처리되었거나 존재하지 않는 승인입니다. 기록을 새로 고쳐 주세요")
var ErrAlreadyDecided = errors.New("该审批已处理或不存在,请刷新记录")
// Decide resolves a pending request. Called by the HTTP decide endpoint.
func (i *Interceptor) Decide(pendingID int64, allowed bool) error {
+13 -13
View File
@@ -27,15 +27,15 @@ func hasHan(s string) bool {
return false
}
// assertKorean fails if s lacks Hangul or still carries Han ideographs. Reverting
// any localized message back to Chinese trips hasHan, so the test is not vacuous.
func assertKorean(t *testing.T, label, s string) {
// assertChinese fails if s lacks Han ideographs or still carries Hangul. Reverting
// any localized message back to Korean trips hasHangul, so the test is not vacuous.
func assertChinese(t *testing.T, label, s string) {
t.Helper()
if !hasHangul(s) {
t.Errorf("%s: 한글이 없습니다: %q", label, s)
if !hasHan(s) {
t.Errorf("%s: 缺少汉字: %q", label, s)
}
if hasHan(s) {
t.Errorf("%s: 한자가 남아 있습니다: %q", label, s)
if hasHangul(s) {
t.Errorf("%s: 仍残留韩文: %q", label, s)
}
}
@@ -54,7 +54,7 @@ func TestInterceptMessagesLocalized(t *testing.T) {
{"reasonManualAllow", reasonManualAllow},
{"ErrAlreadyDecided", ErrAlreadyDecided.Error()},
} {
assertKorean(t, c.name, c.s)
assertChinese(t, c.name, c.s)
}
}
@@ -63,7 +63,7 @@ func TestInterceptMessagesLocalized(t *testing.T) {
// passes through untranslated.
func TestJudgeActionLabelLocalized(t *testing.T) {
for _, action := range []string{"allow", "deny", "ask"} {
assertKorean(t, "judgeActionLabel("+action+")", judgeActionLabel(action))
assertChinese(t, "judgeActionLabel("+action+")", judgeActionLabel(action))
}
if got := judgeActionLabel("weird"); got != "weird" {
t.Errorf("judgeActionLabel(weird) = %q, want passthrough", got)
@@ -75,7 +75,7 @@ func TestJudgeActionLabelLocalized(t *testing.T) {
func TestDefaultMessageLocalized(t *testing.T) {
for _, action := range []string{"deny", "ask"} {
msg := defaultMessage(action, "R1")
assertKorean(t, "defaultMessage("+action+")", msg)
assertChinese(t, "defaultMessage("+action+")", msg)
if !strings.Contains(msg, "R1") {
t.Errorf("defaultMessage(%s) dropped rule name: %q", action, msg)
}
@@ -90,11 +90,11 @@ func TestDefaultMessageLocalized(t *testing.T) {
// the tool name via /도구\s+(\S+)\s+승인/.
func TestToolApprovalSummaryLocalized(t *testing.T) {
s := fmt.Sprintf(msgToolApprovalRequestFmt, "Bash", 42)
assertKorean(t, "msgToolApprovalRequestFmt", s)
assertChinese(t, "msgToolApprovalRequestFmt", s)
if !strings.Contains(s, "(#42)") {
t.Errorf("summary lost the (#N) marker (transcript.tsx pending_id regex): %q", s)
}
if !strings.Contains(s, "도구 Bash 승인") {
t.Errorf("summary lost the '도구 X 승인' shape (transcript.tsx toolName regex): %q", s)
if !strings.Contains(s, "工具 Bash 审批") {
t.Errorf("summary lost the '工具 X 审批' shape (transcript.tsx toolName regex): %q", s)
}
}