package hitl import "fmt" // Strings holds every user-facing text of the bot. The language is chosen once at start (HITL_LANG=en|ja). // Identifiers (action ids, labels, run ids, JSON) stay as they are; only the surrounding text changes. type Strings struct { ProposalTitle func(actionID string) string FieldRootCause string FieldTarget string FieldEvidence string FieldRationale string FieldRun string FieldStatus string FieldResult string FieldAlert string RootCauseValue func(label string, conf float64) string ButtonApprove string ButtonReject string StatusWaiting func(unixTS int64) string StatusRejected func(by string) string StatusExecuting func(by string) string StatusExecuted func(by string) string StatusApproveFailed func(err string) string StatusExecFailed func(by, err string) string StatusExpiredBefore string StatusNoDecision string StatusApprovedAPI func(by string, executed bool) string ExpiryMessage func(actionID, target, runID, scenarioID string) string EscalationTitle func(label string) string EscalationStatus string ThreadRunbook string NotAllowed string Footer func(model, prompt, session string) string Empty string } var langs = map[string]Strings{ "en": { ProposalTitle: func(a string) string { return "Layer-2 proposal: " + a }, FieldRootCause: "Root cause", FieldTarget: "Target", FieldEvidence: "Evidence", FieldRationale: "Rationale", FieldRun: "Run / scenario", FieldStatus: "Status", FieldResult: "Result", FieldAlert: "Alert", RootCauseValue: func(l string, c float64) string { return fmt.Sprintf("%s (confidence %.2f)", l, c) }, ButtonApprove: "Approve", ButtonReject: "Reject", StatusWaiting: func(t int64) string { return fmt.Sprintf("waiting for approval until ", t) }, StatusRejected: func(by string) string { return "rejected by " + by }, StatusExecuting: func(by string) string { return "approved by " + by + ", executing..." }, StatusExecuted: func(by string) string { return "approved by " + by + "; executed" }, StatusApproveFailed: func(e string) string { return "approval failed: " + e }, StatusExecFailed: func(by, e string) string { return "approved by " + by + "; execution failed: " + e }, StatusExpiredBefore: "expired before approval", StatusApprovedAPI: func(by string, executed bool) string { if executed { return "approved through the harness API by " + by + "; executed" } return "approved through the harness API by " + by }, StatusNoDecision: "no decision within the window; moved to layer 3", ExpiryMessage: func(a, t, r, s string) string { return fmt.Sprintf("Proposal `%s` for `%s` (run %s, scenario %s) received no decision within the approval window. Layer 3: follow the runbook or call the harness `/actions/execute` with the operator token.", a, t, r, s) }, EscalationTitle: func(l string) string { return "Escalation: " + l }, EscalationStatus: "layer 3: human decision required", ThreadRunbook: "Runbook:\n", NotAllowed: "You are not in the approver role.", Footer: func(m, p, s string) string { return fmt.Sprintf("model %s, prompt %s, session %s", m, p, s) }, Empty: "-", }, "ja": { ProposalTitle: func(a string) string { return "第2層の提案: " + a }, FieldRootCause: "推定原因", FieldTarget: "対象", FieldEvidence: "根拠", FieldRationale: "判断理由", FieldRun: "Run / シナリオ", FieldStatus: "状態", FieldResult: "実行結果", FieldAlert: "アラート", RootCauseValue: func(l string, c float64) string { return fmt.Sprintf("%s(確信度 %.2f)", l, c) }, ButtonApprove: "承認", ButtonReject: "却下", StatusWaiting: func(t int64) string { return fmt.Sprintf("承認待ち(期限 )", t) }, StatusRejected: func(by string) string { return by + " が却下" }, StatusExecuting: func(by string) string { return by + " が承認、実行中..." }, StatusExecuted: func(by string) string { return by + " が承認、実行済み" }, StatusApproveFailed: func(e string) string { return "承認の記録に失敗: " + e }, StatusExecFailed: func(by, e string) string { return by + " が承認したが実行に失敗: " + e }, StatusExpiredBefore: "承認前に期限切れ", StatusApprovedAPI: func(by string, executed bool) string { if executed { return by + " がハーネス API で承認、実行済み" } return by + " がハーネス API で承認" }, StatusNoDecision: "期限内に判断がなかったため第3層へ引き継ぎ", ExpiryMessage: func(a, t, r, s string) string { return fmt.Sprintf("提案 `%s`(対象 `%s`、run %s、シナリオ %s)は承認期限内に判断されませんでした。第3層の対応です。ランブックに従って手動で対処するか、オペレーター用トークンでハーネスの `/actions/execute` を呼び出してください。", a, t, r, s) }, EscalationTitle: func(l string) string { return "エスカレーション: " + l }, EscalationStatus: "第3層: 人の判断が必要", ThreadRunbook: "ランブック:\n", NotAllowed: "承認ロールが付与されていません。", Footer: func(m, p, s string) string { return fmt.Sprintf("モデル %s、プロンプト %s、セッション %s", m, p, s) }, Empty: "-", }, } // Lang returns the string set for a language code; unknown codes fall back to English. func Lang(code string) Strings { if s, ok := langs[code]; ok { return s } return langs["en"] }