mirror of
https://github.com/All-Hands-AI/OpenHands.git
synced 2026-01-08 22:38:05 -05:00
Fix unlocalized strings in frontend components (#8585)
Co-authored-by: openhands <openhands@all-hands.dev>
This commit is contained in:
@@ -119,6 +119,18 @@ function isExcludedTechnicalString(str) {
|
||||
return EXCLUDED_TECHNICAL_STRINGS.includes(str);
|
||||
}
|
||||
|
||||
function isLikelyCode(str) {
|
||||
// A string with no spaces and at least one underscore or colon is likely a code.
|
||||
// (e.g.: "browser_interactive" or "error:")
|
||||
if (str.includes(" ")) {
|
||||
return false
|
||||
}
|
||||
if (str.includes(":") || str.includes("_")){
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
function isCommonDevelopmentString(str) {
|
||||
// Technical patterns that are definitely not UI strings
|
||||
const technicalPatterns = [
|
||||
@@ -385,6 +397,11 @@ function isLikelyUserFacingText(str) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check if it looks like a code rather than a key
|
||||
if (isLikelyCode(str)) {
|
||||
return false
|
||||
}
|
||||
|
||||
// Check if it's a raw translation key that should be wrapped in t()
|
||||
if (isRawTranslationKey(str)) {
|
||||
return true;
|
||||
|
||||
@@ -11,18 +11,19 @@ import {
|
||||
FinishAction,
|
||||
} from "#/types/core/actions";
|
||||
import { getDefaultEventContent, MAX_CONTENT_LENGTH } from "./shared";
|
||||
import i18n from "#/i18n";
|
||||
|
||||
const getRiskText = (risk: ActionSecurityRisk) => {
|
||||
switch (risk) {
|
||||
case ActionSecurityRisk.LOW:
|
||||
return "Low Risk";
|
||||
return i18n.t("SECURITY$LOW_RISK");
|
||||
case ActionSecurityRisk.MEDIUM:
|
||||
return "Medium Risk";
|
||||
return i18n.t("SECURITY$MEDIUM_RISK");
|
||||
case ActionSecurityRisk.HIGH:
|
||||
return "High Risk";
|
||||
return i18n.t("SECURITY$HIGH_RISK");
|
||||
case ActionSecurityRisk.UNKNOWN:
|
||||
default:
|
||||
return "Unknown Risk";
|
||||
return i18n.t("SECURITY$UNKNOWN_RISK");
|
||||
}
|
||||
};
|
||||
|
||||
@@ -81,15 +82,14 @@ const getFinishActionContent = (event: FinishAction): string => {
|
||||
|
||||
switch (event.args.task_completed) {
|
||||
case "success":
|
||||
content +=
|
||||
"\n\n\nI believe that the task was **completed successfully**.";
|
||||
content += `\n\n\n${i18n.t("FINISH$TASK_COMPLETED_SUCCESSFULLY")}`;
|
||||
break;
|
||||
case "failure":
|
||||
content += "\n\n\nI believe that the task was **not completed**.";
|
||||
content += `\n\n\n${i18n.t("FINISH$TASK_NOT_COMPLETED")}`;
|
||||
break;
|
||||
case "partial":
|
||||
default:
|
||||
content += "\n\n\nI believe that the task was **completed partially**.";
|
||||
content += `\n\n\n${i18n.t("FINISH$TASK_COMPLETED_PARTIALLY")}`;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ import { MonoComponent } from "../mono-component";
|
||||
import { PathComponent } from "../path-component";
|
||||
import { getActionContent } from "./get-action-content";
|
||||
import { getObservationContent } from "./get-observation-content";
|
||||
import i18n from "#/i18n";
|
||||
|
||||
const hasPathProperty = (
|
||||
obj: Record<string, unknown>,
|
||||
@@ -64,7 +65,7 @@ export const getEventContent = (
|
||||
}
|
||||
|
||||
return {
|
||||
title: title ?? "Unknown event",
|
||||
details: details ?? "Unknown event",
|
||||
title: title ?? i18n.t("EVENT$UNKNOWN_EVENT"),
|
||||
details: details ?? i18n.t("EVENT$UNKNOWN_EVENT"),
|
||||
};
|
||||
};
|
||||
|
||||
@@ -9,6 +9,7 @@ import {
|
||||
} from "#/types/core/observations";
|
||||
import { getObservationResult } from "./get-observation-result";
|
||||
import { getDefaultEventContent, MAX_CONTENT_LENGTH } from "./shared";
|
||||
import i18n from "#/i18n";
|
||||
|
||||
const getReadObservationContent = (event: ReadObservation): string =>
|
||||
`\`\`\`\n${event.content}\n\`\`\``;
|
||||
@@ -20,7 +21,7 @@ const getCommandObservationContent = (
|
||||
if (content.length > MAX_CONTENT_LENGTH) {
|
||||
content = `${content.slice(0, MAX_CONTENT_LENGTH)}...`;
|
||||
}
|
||||
return `Output:\n\`\`\`sh\n${content.trim() || "[Command finished execution with no output]"}\n\`\`\``;
|
||||
return `Output:\n\`\`\`sh\n${content.trim() || i18n.t("OBSERVATION$COMMAND_NO_OUTPUT")}\n\`\`\``;
|
||||
};
|
||||
|
||||
const getEditObservationContent = (
|
||||
@@ -50,7 +51,7 @@ const getMcpObservationContent = (event: OpenHandsObservation): string => {
|
||||
if (content.length > MAX_CONTENT_LENGTH) {
|
||||
content = `${content.slice(0, MAX_CONTENT_LENGTH)}...`;
|
||||
}
|
||||
return `**Output:**\n\`\`\`\n${content.trim() || "[MCP Tool finished execution with no output]"}\n\`\`\``;
|
||||
return `**Output:**\n\`\`\`\n${content.trim() || i18n.t("OBSERVATION$MCP_NO_OUTPUT")}\n\`\`\``;
|
||||
};
|
||||
|
||||
const getRecallObservationContent = (event: RecallObservation): string => {
|
||||
|
||||
@@ -40,7 +40,7 @@ export function TaskCard({ task }: TaskCardProps) {
|
||||
|
||||
const handleLaunchConversation = () => {
|
||||
const repo = getRepo(task.repo, task.git_provider);
|
||||
setOptimisticUserMessage("Addressing task...");
|
||||
setOptimisticUserMessage(t("TASK$ADDRESSING_TASK"));
|
||||
|
||||
return createConversation({
|
||||
selectedRepository: repo,
|
||||
|
||||
@@ -1,5 +1,18 @@
|
||||
// this file generate by script, don't modify it manually!!!
|
||||
export enum I18nKey {
|
||||
SECURITY$LOW_RISK = "SECURITY$LOW_RISK",
|
||||
SECURITY$MEDIUM_RISK = "SECURITY$MEDIUM_RISK",
|
||||
SECURITY$HIGH_RISK = "SECURITY$HIGH_RISK",
|
||||
SECURITY$UNKNOWN_RISK = "SECURITY$UNKNOWN_RISK",
|
||||
FINISH$TASK_COMPLETED_SUCCESSFULLY = "FINISH$TASK_COMPLETED_SUCCESSFULLY",
|
||||
FINISH$TASK_NOT_COMPLETED = "FINISH$TASK_NOT_COMPLETED",
|
||||
FINISH$TASK_COMPLETED_PARTIALLY = "FINISH$TASK_COMPLETED_PARTIALLY",
|
||||
EVENT$UNKNOWN_EVENT = "EVENT$UNKNOWN_EVENT",
|
||||
OBSERVATION$COMMAND_NO_OUTPUT = "OBSERVATION$COMMAND_NO_OUTPUT",
|
||||
OBSERVATION$MCP_NO_OUTPUT = "OBSERVATION$MCP_NO_OUTPUT",
|
||||
OBSERVATION$ERROR_PREFIX = "OBSERVATION$ERROR_PREFIX",
|
||||
TASK$ADDRESSING_TASK = "TASK$ADDRESSING_TASK",
|
||||
CHAT_INTERFACE$AGENT_ERROR_MESSAGE = "CHAT_INTERFACE$AGENT_ERROR_MESSAGE",
|
||||
SECRETS$SECRET_VALUE_REQUIRED = "SECRETS$SECRET_VALUE_REQUIRED",
|
||||
SECRETS$ADD_SECRET = "SECRETS$ADD_SECRET",
|
||||
SECRETS$EDIT_SECRET = "SECRETS$EDIT_SECRET",
|
||||
@@ -279,7 +292,6 @@ export enum I18nKey {
|
||||
CHAT_INTERFACE$AGENT_STOPPED_MESSAGE = "CHAT_INTERFACE$AGENT_STOPPED_MESSAGE",
|
||||
CHAT_INTERFACE$AGENT_FINISHED_MESSAGE = "CHAT_INTERFACE$AGENT_FINISHED_MESSAGE",
|
||||
CHAT_INTERFACE$AGENT_REJECTED_MESSAGE = "CHAT_INTERFACE$AGENT_REJECTED_MESSAGE",
|
||||
CHAT_INTERFACE$AGENT_ERROR_MESSAGE = "CHAT_INTERFACE$AGENT_ERROR_MESSAGE",
|
||||
CHAT_INTERFACE$AGENT_AWAITING_USER_CONFIRMATION_MESSAGE = "CHAT_INTERFACE$AGENT_AWAITING_USER_CONFIRMATION_MESSAGE",
|
||||
CHAT_INTERFACE$AGENT_ACTION_USER_CONFIRMED_MESSAGE = "CHAT_INTERFACE$AGENT_ACTION_USER_CONFIRMED_MESSAGE",
|
||||
CHAT_INTERFACE$AGENT_ACTION_USER_REJECTED_MESSAGE = "CHAT_INTERFACE$AGENT_ACTION_USER_REJECTED_MESSAGE",
|
||||
@@ -529,12 +541,4 @@ export enum I18nKey {
|
||||
TIPS$API_USAGE = "TIPS$API_USAGE",
|
||||
TIPS$LEARN_MORE = "TIPS$LEARN_MORE",
|
||||
TIPS$PROTIP = "TIPS$PROTIP",
|
||||
INCREASE_TEST_COVERAGE = "INCREASE_TEST_COVERAGE",
|
||||
AUTO_MERGE_PRS = "AUTO_MERGE_PRS",
|
||||
FIX_README = "FIX_README",
|
||||
CLEAN_DEPENDENCIES = "CLEAN_DEPENDENCIES",
|
||||
BILLING$YOUVE_GOT_50 = "BILLING$YOUVE_GOT_50",
|
||||
BILLING$CLAIM_YOUR_50 = "BILLING$CLAIM_YOUR_50",
|
||||
SETTINGS$RUNTIME_OPTION_1X = "SETTINGS$RUNTIME_OPTION_1X",
|
||||
SETTINGS$RUNTIME_OPTION_2X = "SETTINGS$RUNTIME_OPTION_2X",
|
||||
}
|
||||
|
||||
@@ -1,4 +1,196 @@
|
||||
{
|
||||
"SECURITY$LOW_RISK": {
|
||||
"en": "Low Risk",
|
||||
"ja": "低リスク",
|
||||
"zh-CN": "低风险",
|
||||
"zh-TW": "低風險",
|
||||
"ko-KR": "낮은 위험",
|
||||
"no": "Lav risiko",
|
||||
"it": "Rischio basso",
|
||||
"pt": "Baixo risco",
|
||||
"es": "Riesgo bajo",
|
||||
"ar": "مخاطر منخفضة",
|
||||
"fr": "Risque faible",
|
||||
"tr": "Düşük risk",
|
||||
"de": "Geringes Risiko",
|
||||
"uk": "Низький ризик"
|
||||
},
|
||||
"SECURITY$MEDIUM_RISK": {
|
||||
"en": "Medium Risk",
|
||||
"ja": "中リスク",
|
||||
"zh-CN": "中等风险",
|
||||
"zh-TW": "中等風險",
|
||||
"ko-KR": "중간 위험",
|
||||
"no": "Middels risiko",
|
||||
"it": "Rischio medio",
|
||||
"pt": "Risco médio",
|
||||
"es": "Riesgo medio",
|
||||
"ar": "مخاطر متوسطة",
|
||||
"fr": "Risque moyen",
|
||||
"tr": "Orta risk",
|
||||
"de": "Mittleres Risiko",
|
||||
"uk": "Середній ризик"
|
||||
},
|
||||
"SECURITY$HIGH_RISK": {
|
||||
"en": "High Risk",
|
||||
"ja": "高リスク",
|
||||
"zh-CN": "高风险",
|
||||
"zh-TW": "高風險",
|
||||
"ko-KR": "높은 위험",
|
||||
"no": "Høy risiko",
|
||||
"it": "Rischio alto",
|
||||
"pt": "Alto risco",
|
||||
"es": "Riesgo alto",
|
||||
"ar": "مخاطر عالية",
|
||||
"fr": "Risque élevé",
|
||||
"tr": "Yüksek risk",
|
||||
"de": "Hohes Risiko",
|
||||
"uk": "Високий ризик"
|
||||
},
|
||||
"SECURITY$UNKNOWN_RISK": {
|
||||
"en": "Unknown Risk",
|
||||
"ja": "不明なリスク",
|
||||
"zh-CN": "未知风险",
|
||||
"zh-TW": "未知風險",
|
||||
"ko-KR": "알 수 없는 위험",
|
||||
"no": "Ukjent risiko",
|
||||
"it": "Rischio sconosciuto",
|
||||
"pt": "Risco desconhecido",
|
||||
"es": "Riesgo desconocido",
|
||||
"ar": "مخاطر غير معروفة",
|
||||
"fr": "Risque inconnu",
|
||||
"tr": "Bilinmeyen risk",
|
||||
"de": "Unbekanntes Risiko",
|
||||
"uk": "Невідомий ризик"
|
||||
},
|
||||
"FINISH$TASK_COMPLETED_SUCCESSFULLY": {
|
||||
"en": "I believe that the task was **completed successfully**.",
|
||||
"ja": "タスクは**正常に完了**したと思います。",
|
||||
"zh-CN": "我相信任务已**成功完成**。",
|
||||
"zh-TW": "我相信任務已**成功完成**。",
|
||||
"ko-KR": "작업이 **성공적으로 완료**되었다고 생각합니다.",
|
||||
"no": "Jeg tror at oppgaven ble **fullført vellykket**.",
|
||||
"it": "Ritengo che l'attività sia stata **completata con successo**.",
|
||||
"pt": "Acredito que a tarefa foi **concluída com sucesso**.",
|
||||
"es": "Creo que la tarea se ha **completado con éxito**.",
|
||||
"ar": "أعتقد أن المهمة قد **اكتملت بنجاح**.",
|
||||
"fr": "Je pense que la tâche a été **accomplie avec succès**.",
|
||||
"tr": "Görevin **başarıyla tamamlandığına** inanıyorum.",
|
||||
"de": "Ich glaube, dass die Aufgabe **erfolgreich abgeschlossen** wurde.",
|
||||
"uk": "Я вважаю, що завдання було **успішно виконано**."
|
||||
},
|
||||
"FINISH$TASK_NOT_COMPLETED": {
|
||||
"en": "I believe that the task was **not completed**.",
|
||||
"ja": "タスクは**完了していない**と思います。",
|
||||
"zh-CN": "我相信任务**未完成**。",
|
||||
"zh-TW": "我相信任務**未完成**。",
|
||||
"ko-KR": "작업이 **완료되지 않았다**고 생각합니다.",
|
||||
"no": "Jeg tror at oppgaven **ikke ble fullført**.",
|
||||
"it": "Ritengo che l'attività **non sia stata completata**.",
|
||||
"pt": "Acredito que a tarefa **não foi concluída**.",
|
||||
"es": "Creo que la tarea **no se ha completado**.",
|
||||
"ar": "أعتقد أن المهمة **لم تكتمل**.",
|
||||
"fr": "Je pense que la tâche **n'a pas été accomplie**.",
|
||||
"tr": "Görevin **tamamlanmadığına** inanıyorum.",
|
||||
"de": "Ich glaube, dass die Aufgabe **nicht abgeschlossen** wurde.",
|
||||
"uk": "Я вважаю, що завдання **не було виконано**."
|
||||
},
|
||||
"FINISH$TASK_COMPLETED_PARTIALLY": {
|
||||
"en": "I believe that the task was **completed partially**.",
|
||||
"ja": "タスクは**部分的に完了**したと思います。",
|
||||
"zh-CN": "我相信任务已**部分完成**。",
|
||||
"zh-TW": "我相信任務已**部分完成**。",
|
||||
"ko-KR": "작업이 **부분적으로 완료**되었다고 생각합니다.",
|
||||
"no": "Jeg tror at oppgaven ble **delvis fullført**.",
|
||||
"it": "Ritengo che l'attività sia stata **completata parzialmente**.",
|
||||
"pt": "Acredito que a tarefa foi **concluída parcialmente**.",
|
||||
"es": "Creo que la tarea se ha **completado parcialmente**.",
|
||||
"ar": "أعتقد أن المهمة قد **اكتملت جزئيًا**.",
|
||||
"fr": "Je pense que la tâche a été **partiellement accomplie**.",
|
||||
"tr": "Görevin **kısmen tamamlandığına** inanıyorum.",
|
||||
"de": "Ich glaube, dass die Aufgabe **teilweise abgeschlossen** wurde.",
|
||||
"uk": "Я вважаю, що завдання було **частково виконано**."
|
||||
},
|
||||
"EVENT$UNKNOWN_EVENT": {
|
||||
"en": "Unknown event",
|
||||
"ja": "不明なイベント",
|
||||
"zh-CN": "未知事件",
|
||||
"zh-TW": "未知事件",
|
||||
"ko-KR": "알 수 없는 이벤트",
|
||||
"no": "Ukjent hendelse",
|
||||
"it": "Evento sconosciuto",
|
||||
"pt": "Evento desconhecido",
|
||||
"es": "Evento desconocido",
|
||||
"ar": "حدث غير معروف",
|
||||
"fr": "Événement inconnu",
|
||||
"tr": "Bilinmeyen olay",
|
||||
"de": "Unbekanntes Ereignis",
|
||||
"uk": "Невідома подія"
|
||||
},
|
||||
"OBSERVATION$COMMAND_NO_OUTPUT": {
|
||||
"en": "[Command finished execution with no output]",
|
||||
"ja": "[コマンドは出力なしで実行を終了しました]",
|
||||
"zh-CN": "[命令执行完毕,没有输出]",
|
||||
"zh-TW": "[命令執行完畢,沒有輸出]",
|
||||
"ko-KR": "[명령이 출력 없이 실행을 완료했습니다]",
|
||||
"no": "[Kommandoen ble fullført uten utdata]",
|
||||
"it": "[Il comando ha terminato l'esecuzione senza output]",
|
||||
"pt": "[Comando terminou a execução sem saída]",
|
||||
"es": "[El comando terminó la ejecución sin salida]",
|
||||
"ar": "[انتهى تنفيذ الأمر بدون مخرجات]",
|
||||
"fr": "[La commande s'est terminée sans sortie]",
|
||||
"tr": "[Komut çıktı olmadan yürütmeyi tamamladı]",
|
||||
"de": "[Befehl wurde ohne Ausgabe ausgeführt]",
|
||||
"uk": "[Команда завершила виконання без виводу]"
|
||||
},
|
||||
"OBSERVATION$MCP_NO_OUTPUT": {
|
||||
"en": "[MCP Tool finished execution with no output]",
|
||||
"ja": "[MCPツールは出力なしで実行を終了しました]",
|
||||
"zh-CN": "[MCP工具执行完毕,没有输出]",
|
||||
"zh-TW": "[MCP工具執行完畢,沒有輸出]",
|
||||
"ko-KR": "[MCP 도구가 출력 없이 실행을 완료했습니다]",
|
||||
"no": "[MCP-verktøyet ble fullført uten utdata]",
|
||||
"it": "[Lo strumento MCP ha terminato l'esecuzione senza output]",
|
||||
"pt": "[Ferramenta MCP terminou a execução sem saída]",
|
||||
"es": "[La herramienta MCP terminó la ejecución sin salida]",
|
||||
"ar": "[انتهى تنفيذ أداة MCP بدون مخرجات]",
|
||||
"fr": "[L'outil MCP s'est terminé sans sortie]",
|
||||
"tr": "[MCP Aracı çıktı olmadan yürütmeyi tamamladı]",
|
||||
"de": "[MCP-Tool wurde ohne Ausgabe ausgeführt]",
|
||||
"uk": "[Інструмент MCP завершив виконання без виводу]"
|
||||
},
|
||||
"OBSERVATION$ERROR_PREFIX": {
|
||||
"en": "error:",
|
||||
"ja": "エラー:",
|
||||
"zh-CN": "错误:",
|
||||
"zh-TW": "錯誤:",
|
||||
"ko-KR": "오류:",
|
||||
"no": "feil:",
|
||||
"it": "errore:",
|
||||
"pt": "erro:",
|
||||
"es": "error:",
|
||||
"ar": "خطأ:",
|
||||
"fr": "erreur:",
|
||||
"tr": "hata:",
|
||||
"de": "Fehler:",
|
||||
"uk": "помилка:"
|
||||
},
|
||||
"TASK$ADDRESSING_TASK": {
|
||||
"en": "Addressing task...",
|
||||
"ja": "タスクに対応中...",
|
||||
"zh-CN": "正在处理任务...",
|
||||
"zh-TW": "正在處理任務...",
|
||||
"ko-KR": "작업 처리 중...",
|
||||
"no": "Adresserer oppgave...",
|
||||
"it": "Affrontando l'attività...",
|
||||
"pt": "Abordando tarefa...",
|
||||
"es": "Abordando tarea...",
|
||||
"ar": "معالجة المهمة...",
|
||||
"fr": "Traitement de la tâche...",
|
||||
"tr": "Görev ele alınıyor...",
|
||||
"de": "Aufgabe wird bearbeitet...",
|
||||
"uk": "Вирішення завдання..."
|
||||
},
|
||||
"SECRETS$SECRET_VALUE_REQUIRED": {
|
||||
"en": "Secret value is required",
|
||||
"ja": "シークレット値は必須です",
|
||||
|
||||
Reference in New Issue
Block a user