diff --git a/dashboard/src/i18n/composables.ts b/dashboard/src/i18n/composables.ts index c67d749034..0a7c5186ee 100644 --- a/dashboard/src/i18n/composables.ts +++ b/dashboard/src/i18n/composables.ts @@ -103,7 +103,7 @@ export function useI18n() { const locale = computed(() => currentLocale.value); // 获取可用语言列表 - const availableLocales: Locale[] = ['zh-CN', 'en-US', 'ru-RU']; + const availableLocales: Locale[] = ['zh-CN', 'en-US', 'ru-RU', 'ko-KR']; // 检查是否已加载 const isLoaded = computed(() => Object.keys(translations.value).length > 0); @@ -159,7 +159,8 @@ export function useLanguageSwitcher() { const languageOptions = computed(() => [ { value: 'zh-CN', label: '简体中文', flag: '🇨🇳' }, { value: 'en-US', label: 'English', flag: '🇺🇸' }, - { value: 'ru-RU', label: 'Русский', flag: '🇷🇺' } + { value: 'ru-RU', label: 'Русский', flag: '🇷🇺' }, + { value: 'ko-KR', label: '한국어', flag: '🇰🇷' } ]); const currentLanguage = computed(() => { diff --git a/dashboard/src/i18n/locales/ko-KR/core/actions.json b/dashboard/src/i18n/locales/ko-KR/core/actions.json new file mode 100644 index 0000000000..28986f4cd7 --- /dev/null +++ b/dashboard/src/i18n/locales/ko-KR/core/actions.json @@ -0,0 +1,24 @@ +{ + "create": "생성", + "read": "조회", + "update": "수정", + "delete": "삭제", + "search": "검색", + "filter": "필터", + "sort": "정렬", + "export": "내보내기", + "import": "가져오기", + "backup": "백업", + "restore": "복원", + "copy": "복사", + "paste": "붙여넣기", + "cut": "잘라내기", + "undo": "실행 취소", + "redo": "다시 실행", + "refresh": "새로고침", + "submit": "제출", + "reset": "초기화", + "clear": "지우기", + "save": "저장", + "close": "닫기" +} diff --git a/dashboard/src/i18n/locales/ko-KR/core/common.json b/dashboard/src/i18n/locales/ko-KR/core/common.json new file mode 100644 index 0000000000..75bda89aeb --- /dev/null +++ b/dashboard/src/i18n/locales/ko-KR/core/common.json @@ -0,0 +1,143 @@ +{ + "save": "저장", + "cancel": "취소", + "close": "닫기", + "copy": "복사", + "copied": "복사됨", + "copyFailed": "복사 실패", + "delete": "삭제", + "edit": "편집", + "add": "추가", + "confirm": "확인", + "loading": "로딩 중...", + "success": "성공", + "error": "오류", + "warning": "경고", + "info": "정보", + "name": "이름", + "description": "설명", + "author": "작성자", + "status": "상태", + "actions": "작업", + "enable": "활성화", + "disable": "비활성화", + "enabled": "활성화됨", + "disabled": "비활성화됨", + "reload": "다시 불러오기", + "configure": "구성", + "install": "설치", + "uninstall": "제거", + "update": "업데이트", + "language": "언어", + "settings": "설정", + "locale": "ko-KR", + "type": "유형", + "press": "누르기", + "longPress": "길게 누르기", + "yes": "예", + "no": "아니요", + "imagePreview": "이미지 미리보기", + "autoDetect": "자동 감지", + "dialog": { + "confirmTitle": "작업 확인", + "confirmMessage": "이 작업을 실행하시겠습니까?", + "confirmButton": "확인", + "cancelButton": "취소" + }, + "restart": { + "waiting": "AstrBot이 재시작되기를 기다리는 중...", + "maxRetriesReached": "최대 재시도 횟수에 도달했습니다. 수동으로 확인해주세요." + }, + "upgradeRecovery": { + "title": "업그레이드 후 재시작 필요", + "description": "WebUI는 {dashboardVersion}(으)로 업데이트되었지만, AstrBot Core는 아직 {coreVersion}입니다. 이는 대개 업그레이드 도중 페이지를 새로고침하여 재시작 과정이 중단되었을 때 발생합니다. 재시작해도 문제가 해결되지 않으면 AstrBot 실행 디렉터리의 data/dist 폴더를 삭제한 후 AstrBot을 다시 시작해보세요.", + "hint": "백엔드를 재시작하면 업그레이드가 완료됩니다. AstrBot이 복구되면 이 페이지는 자동으로 새로고침됩니다.", + "restartButton": "백엔드 재시작", + "laterButton": "나중에", + "restarting": "백엔드 재시작을 요청하는 중...", + "waiting": "재시작이 요청되었습니다. 백엔드가 복구되기를 기다리는 중...", + "failed": "재시작 요청에 실패했습니다. AstrBot을 수동으로 재시작해주세요." + }, + "readme": { + "title": "플러그인 문서", + "buttons": { + "viewOnGithub": "GitHub에서 저장소 보기", + "refresh": "문서 새로고침" + }, + "loading": "README 문서를 불러오는 중...", + "errors": { + "fetchFailed": "README를 가져오지 못했습니다", + "fetchError": "README를 가져오는 중 오류가 발생했습니다" + }, + "empty": { + "title": "이 플러그인은 문서 링크나 GitHub 저장소 주소를 제공하지 않습니다.", + "subtitle": "플러그인 마켓을 확인하거나 플러그인 작성자에게 문의해주세요." + } + }, + "changelog": { + "title": "변경 이력", + "loading": "변경 이력을 불러오는 중...", + "empty": { + "title": "이 플러그인에는 변경 이력이 없습니다", + "subtitle": "개발자는 플러그인 디렉터리에 CHANGELOG.md 파일을 추가해 변경 이력을 제공할 수 있습니다" + } + }, + "editor": { + "fullscreen": "전체 화면으로 편집", + "editingTitle": "내용 편집 중" + }, + "templateList": { + "addEntry": "항목 추가", + "empty": "아직 항목이 없습니다. 템플릿을 선택해 추가해주세요", + "missingTemplate": "템플릿을 찾을 수 없습니다. 제거 후 다시 추가해주세요.", + "unknownTemplate": "템플릿이 지정되지 않음" + }, + "list": { + "addItemPlaceholder": "새 항목 추가, Enter 키로 확인", + "addButton": "추가", + "addMore": "더 추가", + "batchImport": "일괄 가져오기", + "batchImportTitle": "일괄 가져오기", + "batchImportLabel": "한 줄에 항목 하나씩", + "batchImportPlaceholder": "예시:\n항목 1\n항목 2\n항목 3\n항목 4", + "batchImportHint": "각 줄은 별도의 항목으로 처리되며, 빈 줄은 무시됩니다", + "batchImportButton": "{count}개 항목 가져오기", + "noItems": "항목 없음", + "noItemsHint": "아직 항목이 없습니다. 위 입력란에 입력한 후 Enter 키를 눌러 추가하세요", + "inputPlaceholder": "입력 후 Enter 키를 눌러 추가", + "editTitle": "목록 항목 편집", + "modifyButton": "수정" + }, + "itemCard": { + "enabled": "활성화됨", + "disabled": "비활성화됨", + "delete": "삭제", + "edit": "편집", + "copy": "복사", + "noData": "사용 가능한 데이터 없음" + }, + "objectEditor": { + "dialogTitle": "키-값 쌍 편집", + "noItems": "항목 없음", + "noParams": "매개변수 없음", + "presets": "프리셋", + "newKeyLabel": "새 키", + "valueTypeLabel": "값 유형", + "keyExists": "이미 존재하는 키입니다", + "invalidJson": "잘못된 JSON 형식입니다", + "placeholders": { + "keyName": "키", + "stringValue": "문자열 값", + "numberValue": "숫자 값", + "jsonValue": "JSON" + } + }, + "firstNotice": { + "title": "최초 공지", + "loading": "최초 공지를 불러오는 중...", + "empty": { + "title": "표시할 최초 공지 내용이 없습니다", + "subtitle": "FIRST_NOTICE.md 파일을 찾을 수 없거나 비어 있습니다." + } + } +} diff --git a/dashboard/src/i18n/locales/ko-KR/core/header.json b/dashboard/src/i18n/locales/ko-KR/core/header.json new file mode 100644 index 0000000000..12caf87268 --- /dev/null +++ b/dashboard/src/i18n/locales/ko-KR/core/header.json @@ -0,0 +1,134 @@ +{ + "logoTitle": "AstrBot 대시보드", + "version": { + "hasNewVersion": "AstrBot의 새 버전이 있습니다!", + "dashboardHasNewVersion": "WebUI의 새 버전이 있습니다!" + }, + "buttons": { + "update": "업데이트", + "account": "계정", + "theme": { + "title": "테마", + "light": "라이트 모드", + "dark": "다크 모드", + "system": "시스템 설정 따르기" + } + }, + "updateDialog": { + "title": "AstrBot 업데이트", + "currentVersion": "현재 버전", + "status": { + "checking": "업데이트를 확인하는 중...", + "switching": "버전을 전환하는 중...", + "updating": "업데이트하는 중..." + }, + "tabs": { + "release": "😊 릴리스" + }, + "advancedSettings": "고급 설정", + "releases": "릴리스", + "updateToLatest": "최신 버전으로 업데이트", + "showPreReleases": "사전 릴리스 버전 표시", + "preRelease": "사전 릴리스", + "preReleaseWarning": { + "title": "사전 릴리스 버전 안내", + "description": "사전 릴리스로 표시된 버전에는 알려지지 않은 문제나 버그가 있을 수 있으므로 프로덕션 환경에서 사용하지 않는 것을 권장합니다. 문제가 발생하면 ", + "issueLink": "GitHub Issues" + }, + "tip": "💡 팁:", + "tipContinue": "버전을 전환할 때는 기본적으로 해당 버전의 WebUI 파일이 다운로드됩니다. WebUI 코드는 프로젝트의 dashboard 디렉터리에 있으며, npm을 사용해 직접 빌드할 수도 있습니다.", + "dockerTip": "버전을 전환하면 봇 본체와 대시보드를 함께 업데이트하려고 시도합니다. Docker로 배포한 경우 이미지를 다시 받거나", + "dockerTipLink": "watchtower", + "dockerTipContinue": "를 사용해 자동으로 감시하고 받아올 수도 있습니다.", + "table": { + "tag": "태그", + "publishDate": "게시일", + "content": "내용", + "sourceUrl": "소스 URL", + "actions": "작업", + "view": "보기", + "switch": "전환" + }, + "releaseNotes": { + "title": "릴리스 노트", + "latestLabel": "최신 버전" + }, + "progress": { + "target": "대상 버전: ", + "preparing": "업데이트 준비 중...", + "dashboard": "WebUI 다운로드 중", + "core": "프로젝트 코드 다운로드 중", + "dependencies": "의존성을 업데이트하는 중...", + "restart": "재시작 준비 중...", + "restarting": "AstrBot 재시작 중", + "completed": "업데이트 완료", + "successReady": "업데이트 성공", + "autoReloadIn": "{seconds}초 후 자동으로 새로고침됩니다", + "reloadNow": "지금 새로고침", + "failed": "업데이트 실패" + }, + "redirectConfirm": { + "title": "AstrBot에서 나가기", + "message": "GitHub Releases 페이지를 여시겠습니까?", + "latestLabel": "최신", + "targetVersion": "대상 버전: ", + "currentVersion": "현재 버전: ", + "guideTitle": "이동 후 권장 사항:", + "guideStep1": "사용 중인 OS 및 아키텍처에 맞는 설치 파일을 다운로드하세요.", + "guideStep2": "설치 후 AstrBot을 재시작하세요.", + "guideStep3": "Docker를 사용 중이라면 이미지 업데이트 방식을 우선적으로 사용하세요." + }, + "desktopApp": { + "title": "데스크톱 앱 업데이트", + "message": "AstrBot 데스크톱 애플리케이션을 확인하고 업그레이드합니다.", + "currentVersion": "현재 버전: ", + "latestVersion": "최신 버전: ", + "checking": "데스크톱 앱 업데이트를 확인하는 중...", + "hasNewVersion": "새 버전을 사용할 수 있습니다. 확인을 클릭해 업그레이드하세요.", + "isLatest": "이미 최신 버전입니다", + "installing": "업데이트를 다운로드하고 설치하는 중입니다. 앱이 자동으로 재시작됩니다...", + "checkFailed": "업데이트 확인에 실패했습니다. 나중에 다시 시도해주세요.", + "installFailed": "업그레이드에 실패했습니다. 나중에 다시 시도해주세요." + }, + "dashboardUpdate": { + "title": "대시보드만 최신 버전으로 업데이트", + "currentVersion": "현재 버전", + "hasNewVersion": "새 버전을 사용할 수 있습니다!", + "isLatest": "이미 최신 버전입니다.", + "fallback": "전체 업데이트가 실패할 경우 이 기능으로 WebUI를 다시 다운로드하세요.", + "downloadAndUpdate": "다운로드 및 업데이트" + } + }, + "accountDialog": { + "title": "계정 수정", + "securityWarning": "보안 안내: 계정 보호를 위해 비밀번호를 변경해주세요", + "securityWarningMd5": "새 AstrBot 버전에서 보안이 강화되었습니다. 비밀번호를 변경해주세요.", + "securityWarningUpgrade": "MD5 방식의 비밀번호 저장이 감지되었습니다. 보안 업그레이드를 완료하려면 비밀번호를 변경해주세요.", + "form": { + "currentPassword": "현재 비밀번호", + "newPassword": "새 비밀번호", + "confirmPassword": "새 비밀번호 확인", + "newUsername": "새 사용자 이름 (선택)", + "passwordHint": "8자 이상, 대문자, 소문자, 숫자를 포함해야 합니다", + "confirmPasswordHint": "새 비밀번호를 다시 입력해 확인해주세요", + "usernameHint": "비워두면 현재 사용자 이름이 유지됩니다", + "defaultCredentials": "기본 사용자 이름은 astrbot입니다. 초기 비밀번호는 최초 시작 시 생성되어 콘솔에 표시됩니다." + }, + "validation": { + "passwordRequired": "비밀번호를 입력해주세요", + "passwordMinLength": "비밀번호는 8자 이상이어야 합니다", + "passwordUppercase": "비밀번호에는 대문자가 하나 이상 포함되어야 합니다", + "passwordLowercase": "비밀번호에는 소문자가 하나 이상 포함되어야 합니다", + "passwordDigit": "비밀번호에는 숫자가 하나 이상 포함되어야 합니다", + "passwordMatch": "비밀번호가 일치하지 않습니다", + "usernameMinLength": "사용자 이름은 3자 이상이어야 합니다" + }, + "actions": { + "save": "변경 사항 저장", + "cancel": "취소" + }, + "messages": { + "updateFailed": "업데이트에 실패했습니다. 다시 시도해주세요" + } + } +} diff --git a/dashboard/src/i18n/locales/ko-KR/core/navigation.json b/dashboard/src/i18n/locales/ko-KR/core/navigation.json new file mode 100644 index 0000000000..df27575843 --- /dev/null +++ b/dashboard/src/i18n/locales/ko-KR/core/navigation.json @@ -0,0 +1,50 @@ +{ + "welcome": "환영", + "dashboard": "대시보드", + "platforms": "플랫폼", + "providers": "공급자", + "commands": "명령어", + "persona": "페르소나", + "subagent": "서브 에이전트", + "toolUse": "MCP 도구", + "config": "구성", + "chat": "채팅", + "cron": "예약 작업", + "extension": "플러그인", + "extensionTabs": { + "installed": "AstrBot 플러그인", + "market": "플러그인 마켓", + "mcp": "MCP 서버", + "skills": "스킬", + "components": "핸들러" + }, + "conversation": "대화", + "sessionManagement": "커스텀 규칙", + "console": "콘솔", + "trace": "트레이스", + "alkaid": "Alkaid 연구소", + "knowledgeBase": "지식 베이스", + "about": "정보", + "settings": "설정", + "changelog": "변경 이력", + "documentation": "문서", + "faq": "자주 묻는 질문", + "github": "GitHub", + "drag": "드래그", + "groups": { + "more": "추가 기능" + }, + "changelogDialog": { + "title": "변경 이력", + "loading": "로딩 중...", + "error": "불러오기 실패", + "notFound": "이 버전의 변경 이력을 찾을 수 없습니다", + "selectVersion": "버전 선택", + "current": "현재" + }, + "configTabs": { + "normal": "일반 구성", + "system": "시스템 구성" + }, + "pluginWebui": "플러그인 페이지" +} diff --git a/dashboard/src/i18n/locales/ko-KR/core/shared.json b/dashboard/src/i18n/locales/ko-KR/core/shared.json new file mode 100644 index 0000000000..06d0940f21 --- /dev/null +++ b/dashboard/src/i18n/locales/ko-KR/core/shared.json @@ -0,0 +1,111 @@ +{ + "knowledgeBaseSelector": { + "notSelected": "선택되지 않음", + "buttonText": "지식 베이스 선택...", + "dialogTitle": "지식 베이스 선택", + "loading": "로딩 중...", + "noKnowledgeBases": "사용 가능한 지식 베이스가 없습니다", + "createKnowledgeBase": "지식 베이스 생성", + "selectedCount": "지식 베이스 {count}개 선택됨", + "confirmSelection": "선택 확인", + "cancelSelection": "취소", + "noDescription": "설명 없음", + "documentCount": "문서 {count}개", + "chunkCount": "청크 {count}개" + }, + "pluginSetSelector": { + "notSelected": "활성화된 플러그인 없음", + "allPlugins": "모든 플러그인 활성화 (*)", + "selectedCount": "플러그인 {count}개 선택됨", + "buttonText": "플러그인 세트 선택...", + "dialogTitle": "플러그인 세트 선택", + "loading": "로딩 중...", + "enableAll": "모든 플러그인 활성화", + "enableNone": "모든 플러그인 비활성화", + "customSelect": "직접 선택", + "noPlugins": "사용 가능한 플러그인이 없습니다", + "confirmSelection": "선택 확인", + "cancelSelection": "취소", + "noDescription": "설명 없음", + "notActivated": "활성화되지 않음", + "note": "*시스템 플러그인과 비활성화된 플러그인은 표시되지 않습니다.", + "selectedPluginsLabel": "선택된 플러그인:", + "allPluginsLabel": "모든 플러그인" + }, + "providerSelector": { + "notSelected": "선택되지 않음", + "buttonText": "공급자 선택...", + "dialogTitle": "공급자 선택", + "loading": "로딩 중...", + "noProviders": "사용 가능한 공급자가 없습니다", + "confirmSelection": "선택 확인", + "cancelSelection": "취소", + "clearSelection": "없음", + "clearSelectionSubtitle": "현재 선택 해제", + "unknownType": "알 수 없는 유형", + "createProvider": "공급자 생성", + "manageProviders": "공급자 관리", + "selectProviderPool": "공급자 풀 선택...", + "selectedCount": "공급자 {count}개 선택됨" + }, + "personaSelector": { + "notSelected": "선택되지 않음", + "defaultPersona": "기본 페르소나", + "buttonText": "페르소나 선택...", + "dialogTitle": "페르소나 선택", + "noDescription": "설명 없음", + "noPersonas": "사용 가능한 페르소나가 없습니다", + "createPersona": "새 페르소나 생성", + "cancelSelection": "취소", + "confirmSelection": "선택 확인", + "selectPersonaPool": "페르소나 풀 선택...", + "rootFolder": "모든 페르소나", + "emptyFolder": "이 폴더는 비어 있습니다" + }, + "personaQuickPreview": { + "title": "페르소나 미리보기", + "loading": "로딩 중...", + "noPersonaSelected": "선택된 페르소나가 없습니다", + "personaNotFound": "페르소나 정보를 찾을 수 없습니다", + "systemPromptLabel": "시스템 프롬프트", + "toolsLabel": "도구", + "skillsLabel": "스킬", + "originLabel": "출처", + "originNameLabel": "출처 이름", + "toolInactive": "비활성화됨", + "toolInactiveTooltip": "이 도구는 비활성화되어 있습니다. 확장 -> 핸들러 -> 함수 도구에서 다시 활성화하세요.", + "allTools": "모든 도구 사용 가능", + "allToolsWithCount": "모든 도구 사용 가능 ({count}개)", + "noTools": "구성된 도구가 없습니다", + "allSkills": "모든 스킬 사용 가능", + "allSkillsWithCount": "모든 스킬 사용 가능 ({count}개)", + "noSkills": "구성된 스킬이 없습니다" + }, + "t2iTemplateEditor": { + "buttonText": "T2I 템플릿 커스터마이즈", + "dialogTitle": "텍스트-이미지 HTML 템플릿 커스터마이즈", + "newTemplateNameLabel": "새 템플릿 이름 입력", + "nameRequired": "이름은 필수입니다", + "selectTemplateLabel": "템플릿 선택", + "applied": "적용됨", + "apply": "적용", + "templateEditor": "템플릿 편집기", + "new": "새로 만들기", + "resetBase": "기본값으로 재설정", + "delete": "삭제", + "save": "저장", + "livePreview": "실시간 미리보기 (실제와 다를 수 있음)", + "refreshPreview": "미리보기 새로고침", + "previewText": "이것은 템플릿 출력을 미리 보기 위한 예시 텍스트입니다.\n\n여러 줄과 다양한 서식을 포함할 수 있습니다.", + "syntaxHint": "jinja2 문법을 지원합니다. 사용 가능한 변수: text | safe (렌더링할 텍스트), version (AstrBot 버전). 미리보기 테스트 내용이 로드되지 않거나 잘못 표시되면 '기본값으로 재설정'을 클릭해 기본 템플릿으로 복원하세요.", + "saveAndApply": "현재 템플릿 저장 및 적용", + "confirmReset": "재설정 확인", + "confirmResetMessage": "'base' 템플릿을 기본 내용으로 재설정하시겠습니까? 편집기에 저장하지 않은 변경 사항은 모두 사라집니다. 이 작업은 되돌릴 수 없습니다.", + "confirmResetButton": "재설정 확인", + "confirmDelete": "삭제 확인", + "confirmDeleteMessage": "'{name}' 템플릿을 삭제하시겠습니까? 이 작업은 되돌릴 수 없습니다.", + "confirmDeleteButton": "삭제 확인", + "confirmAction": "작업 확인", + "confirmApplyMessage": "'{name}'에 대한 변경 사항을 저장하고 활성 템플릿으로 설정하시겠습니까?" + } +} diff --git a/dashboard/src/i18n/locales/ko-KR/core/status.json b/dashboard/src/i18n/locales/ko-KR/core/status.json new file mode 100644 index 0000000000..b853296d41 --- /dev/null +++ b/dashboard/src/i18n/locales/ko-KR/core/status.json @@ -0,0 +1,22 @@ +{ + "loading": "로딩 중", + "success": "성공", + "error": "오류", + "warning": "경고", + "info": "정보", + "pending": "대기 중", + "processing": "처리 중", + "completed": "완료", + "failed": "실패", + "cancelled": "취소됨", + "timeout": "시간 초과", + "connecting": "연결 중", + "connected": "연결됨", + "disconnected": "연결 끊김", + "online": "온라인", + "offline": "오프라인", + "active": "활성", + "inactive": "비활성", + "ready": "준비됨", + "busy": "사용 중" +} diff --git a/dashboard/src/i18n/locales/ko-KR/features/about.json b/dashboard/src/i18n/locales/ko-KR/features/about.json new file mode 100644 index 0000000000..a8b811c90c --- /dev/null +++ b/dashboard/src/i18n/locales/ko-KR/features/about.json @@ -0,0 +1,17 @@ +{ + "hero": { + "title": "AstrBot", + "subtitle": "관심과 애정으로 만든 프로젝트 ❤️", + "starButton": "이 프로젝트에 별을 눌러주세요! 🌟", + "issueButton": "이슈 제출" + }, + "contributors": { + "title": "기여자", + "description": "이 프로젝트는 많은 오픈소스 커뮤니티 구성원들이 함께 관리하고 있습니다. 모든 기여자분들의 헌신에 감사드립니다!", + "viewLink": "AstrBot 기여자 보기" + }, + "stats": { + "title": "전 세계 배포 현황", + "license": "AstrBot은 AGPL v3 라이선스로 공개된 오픈소스 프로젝트입니다" + } +} diff --git a/dashboard/src/i18n/locales/ko-KR/features/alkaid/index.json b/dashboard/src/i18n/locales/ko-KR/features/alkaid/index.json new file mode 100644 index 0000000000..25cde77959 --- /dev/null +++ b/dashboard/src/i18n/locales/ko-KR/features/alkaid/index.json @@ -0,0 +1,44 @@ +{ + "title": "Alkaid 연구소", + "subtitle": "최첨단 AI 기능을 살펴보세요", + "comingSoon": "앞으로 펼쳐질 세계, 나중에 함께 탐험해봐요!", + "page": { + "title": "The Alkaid Project.", + "subtitle": "AstrBot Alpha 프로젝트", + "navigation": { + "knowledgeBase": "지식 베이스 (플러그인)", + "longTermMemory": "장기 기억", + "other": "..." + } + }, + "features": { + "knowledgeBase": "지식 베이스", + "longTermMemory": "장기 기억", + "advancedChat": "고급 채팅", + "multiModal": "멀티모달 상호작용" + }, + "status": { + "experimental": "실험적", + "beta": "베타", + "stable": "안정", + "deprecated": "지원 종료" + }, + "sigma": { + "subtitle": "AstrBot 실험적 프로젝트", + "visualization": "시각화", + "filterUserId": "사용자 ID 필터", + "filter": "필터", + "resetFilter": "필터 초기화", + "refreshGraph": "그래프 새로고침", + "nodeDetails": "노드 상세 정보", + "id": "ID", + "type": "유형", + "name": "이름", + "userId": "사용자 ID", + "timestamp": "타임스탬프", + "graphStats": "그래프 통계", + "nodeCount": "노드 수", + "edgeCount": "엣지 수", + "inDevelopment": "개발 중" + } +} diff --git a/dashboard/src/i18n/locales/ko-KR/features/alkaid/knowledge-base.json b/dashboard/src/i18n/locales/ko-KR/features/alkaid/knowledge-base.json new file mode 100644 index 0000000000..891850eda3 --- /dev/null +++ b/dashboard/src/i18n/locales/ko-KR/features/alkaid/knowledge-base.json @@ -0,0 +1,155 @@ +{ + "title": "지식 베이스", + "subtitle": "지식 베이스 콘텐츠를 관리하고 조회합니다", + "documents": { + "title": "문서 목록", + "name": "문서 이름", + "size": "크기", + "uploadTime": "업로드 시간", + "status": "상태", + "actions": "작업" + }, + "management": { + "delete": "삭제", + "preview": "미리보기", + "download": "다운로드", + "reindex": "다시 인덱싱" + }, + "notInstalled": { + "title": "지식 베이스 플러그인이 아직 설치되지 않았습니다", + "install": "지금 설치" + }, + "empty": { + "title": "아직 지식 베이스가 없습니다. 지금 만들어보세요! 🙂", + "create": "지식 베이스 생성" + }, + "list": { + "title": "지식 베이스 목록", + "create": "지식 베이스 생성", + "config": "구성", + "checkUpdate": "플러그인 업데이트 확인", + "updatePlugin": "플러그인을 {version}(으)로 업데이트", + "knowledgeCount": "개 지식 항목", + "tips": "팁: 채팅 페이지에서 /kb 명령어로 사용법을 알아보세요!" + }, + "createDialog": { + "title": "새 지식 베이스 생성", + "nameLabel": "지식 베이스 이름", + "descriptionLabel": "설명", + "descriptionPlaceholder": "지식 베이스에 대한 간단한 설명...", + "embeddingModelLabel": "임베딩 모델", + "rerankModelLabel": "재정렬 모델", + "providerInfo": "공급자 ID: {id} | 임베딩 모델 차원: {dimensions}", + "rerankProviderInfo": "공급자 ID: {id}", + "tips": "팁: 지식 베이스에 임베딩 모델을 한 번 선택한 후에는 공급자의 모델이나 벡터 차원 정보를 변경하지 마세요. 변경하면 지식 베이스의 검색 정확도가 크게 저하되거나 오류가 발생할 수 있습니다.", + "cancel": "취소", + "create": "생성" + }, + "emojiPicker": { + "title": "이모지 선택", + "close": "닫기", + "categories": { + "emotions": "스마일리 및 감정", + "animals": "동물 및 자연", + "food": "음식 및 음료", + "activities": "활동 및 사물", + "travel": "여행 및 장소", + "symbols": "기호 및 깃발" + } + }, + "contentDialog": { + "title": "지식 베이스 관리", + "embeddingModel": "임베딩 모델", + "vectorDimension": "벡터 차원", + "usage": "사용법: 채팅 페이지에서 \"/kb use {name}\"을 입력하세요", + "tabs": { + "upload": "파일 업로드", + "search": "콘텐츠 검색", + "fromURL": "URL에서 가져오기" + } + }, + "upload": { + "title": "지식 베이스에 파일 업로드", + "subtitle": "txt, pdf, epub, word, excel 등 다양한 형식을 지원합니다", + "dropzone": "파일을 이곳에 끌어다 놓거나 클릭하여 업로드하세요", + "chunkSettings": { + "title": "청크 설정", + "tooltip": "청크 크기는 각 텍스트 블록의 크기를 결정하고, 오버랩 길이는 인접한 텍스트 블록 간의 겹침 정도를 결정합니다.\n청크가 작을수록 더 정밀하지만 개수가 늘어나며, 적절한 오버랩은 검색 정확도를 높일 수 있습니다.", + "chunkSizeLabel": "청크 크기", + "chunkSizeHint": "각 텍스트 블록의 크기를 지정합니다. 비워두면 기본값이 사용됩니다", + "overlapLabel": "오버랩 길이", + "overlapHint": "인접한 텍스트 블록 간의 오버랩을 지정합니다. 비워두면 기본값이 사용됩니다" + }, + "upload": "파일 업로드", + "uploading": "업로드하는 중..." + }, + "search": { + "queryLabel": "지식 베이스 콘텐츠 검색", + "queryPlaceholder": "지식 베이스 콘텐츠를 검색할 키워드를 입력하세요...", + "resultCountLabel": "결과 개수", + "searching": "검색하는 중...", + "resultsTitle": "검색 결과", + "relevance": "관련도", + "noResults": "일치하는 콘텐츠를 찾을 수 없습니다" + }, + "deleteDialog": { + "title": "삭제 확인", + "confirmText": "지식 베이스 {name}을(를) 삭제하시겠습니까?", + "warning": "이 작업은 되돌릴 수 없으며, 지식 베이스의 모든 콘텐츠가 영구적으로 삭제됩니다.", + "cancel": "취소", + "delete": "삭제" + }, + "messages": { + "pluginNotAvailable": "플러그인이 설치되지 않았거나 사용할 수 없습니다", + "pluginNotActivated": "astrbot_plugin_knowledge_base 플러그인이 활성화되지 않았습니다. 플러그인 관리 페이지에서 활성화한 후 AstrBot을 재시작해주세요", + "checkPluginFailed": "플러그인 확인에 실패했습니다", + "installFailed": "설치에 실패했습니다", + "installPluginFailed": "플러그인 설치에 실패했습니다", + "getKnowledgeBaseListFailed": "지식 베이스 목록을 가져오지 못했습니다", + "knowledgeBaseCreated": "지식 베이스가 생성되었습니다", + "createFailed": "생성에 실패했습니다", + "createKnowledgeBaseFailed": "지식 베이스 생성에 실패했습니다", + "pleaseEnterKnowledgeBaseName": "지식 베이스 이름을 입력해주세요", + "pleaseSelectFile": "먼저 파일을 선택해주세요", + "operationSuccess": "작업 성공: {message}", + "uploadFailed": "업로드에 실패했습니다", + "fileUploadFailed": "파일 업로드에 실패했습니다", + "pleaseEnterSearchContent": "검색할 내용을 입력해주세요", + "noMatchingContent": "일치하는 콘텐츠를 찾을 수 없습니다", + "searchFailed": "검색에 실패했습니다", + "searchKnowledgeBaseFailed": "지식 베이스 검색에 실패했습니다", + "deleteTargetNotExists": "삭제 대상이 존재하지 않습니다", + "knowledgeBaseDeleted": "지식 베이스가 삭제되었습니다", + "deleteFailed": "삭제에 실패했습니다", + "deleteKnowledgeBaseFailed": "지식 베이스 삭제에 실패했습니다", + "getEmbeddingModelListFailed": "임베딩 모델 목록을 가져오지 못했습니다", + "updateAvailable": "새 버전을 사용할 수 있습니다: {current} -> {latest}", + "pluginUpToDate": "플러그인이 최신 상태입니다", + "pluginNotFoundInMarket": "마켓에서 플러그인을 찾을 수 없습니다", + "checkUpdateFailed": "업데이트 확인에 실패했습니다", + "updateSuccess": "플러그인이 업데이트되었습니다", + "updateFailed": "업데이트에 실패했습니다", + "updatePluginFailed": "플러그인 업데이트에 실패했습니다" + }, + "importFromUrl": { + "title": "URL에서 가져오기", + "urlLabel": "웹페이지 URL", + "urlPlaceholder": "지식을 추출할 웹페이지의 URL을 입력하세요", + "optionsTitle": "가져오기 옵션", + "tooltip": "이 옵션들은 URL 콘텐츠에서 텍스트를 추출하고 처리하는 방식을 제어합니다.\n비워두면 플러그인의 기본 설정이 사용됩니다.\nLLM 텍스트 보정과 요약을 활성화하면 시간이 오래 걸릴 수 있습니다.", + "useLlmRepairLabel": "LLM 텍스트 보정 활성화", + "useClusteringSummaryLabel": "클러스터링 요약 활성화", + "repairLlmProviderIdLabel": "텍스트 보정 모델", + "summarizeLlmProviderIdLabel": "요약 모델", + "embeddingProviderIdLabel": "임베딩 모델", + "chunkSizeLabel": "청크 크기", + "chunkOverlapLabel": "청크 오버랩", + "startImport": "가져오기 시작", + "importing": "가져오는 중...", + "importSuccess": "가져오기 성공", + "importFailed": "가져오기 실패", + "uploadingChunks": "콘텐츠 추출에 성공했습니다. 청크를 업로드하는 중...", + "preRequisite": "안내: 이 기능을 사용하기 전에 플러그인 마켓에서 astrbot_plugin_url_2_knowledge_base를 설치하고, 플러그인 문서의 안내에 따라 playwright 설치를 완료해주세요.", + "allChunksUploaded": "모든 청크가 업로드되었습니다" + } +} diff --git a/dashboard/src/i18n/locales/ko-KR/features/alkaid/memory.json b/dashboard/src/i18n/locales/ko-KR/features/alkaid/memory.json new file mode 100644 index 0000000000..e40727d4a6 --- /dev/null +++ b/dashboard/src/i18n/locales/ko-KR/features/alkaid/memory.json @@ -0,0 +1,97 @@ +{ + "title": "장기 기억", + "subtitle": "AI 어시스턴트의 장기 기억 관리", + "memories": { + "title": "기억 목록", + "content": "기억 내용", + "importance": "중요도", + "createTime": "생성 시간", + "lastAccess": "마지막 접근", + "category": "카테고리" + }, + "categories": { + "personal": "개인 정보", + "preferences": "선호 설정", + "conversations": "대화 기록", + "facts": "사실 정보", + "skills": "스킬 지식" + }, + "importance": { + "high": "높음", + "medium": "보통", + "low": "낮음" + }, + "actions": { + "view": "상세 보기", + "edit": "편집", + "delete": "삭제", + "pin": "고정", + "unpin": "고정 해제" + }, + "filters": { + "all": "전체", + "category": "카테고리별", + "importance": "중요도별", + "dateRange": "날짜 범위별", + "title": "필터", + "userIdLabel": "사용자 ID로 필터링", + "filterButton": "필터", + "resetButton": "필터 초기화", + "refreshButton": "그래프 새로고침" + }, + "search": { + "title": "기억 검색", + "userIdLabel": "사용자 ID", + "queryLabel": "키워드 입력", + "searchButton": "검색", + "resultsTitle": "검색 결과", + "noResults": "관련된 기억 내용을 찾을 수 없습니다", + "similarity": "관련도", + "noTextContent": "텍스트 내용 없음" + }, + "addMemory": { + "title": "기억 데이터 추가", + "textLabel": "텍스트 내용 입력", + "userIdLabel": "사용자 ID", + "summarizeLabel": "요약 필요", + "addButton": "데이터 추가" + }, + "nodeDetails": { + "title": "노드 상세 정보", + "id": "ID", + "type": "유형", + "name": "이름", + "userId": "사용자 ID", + "timestamp": "타임스탬프" + }, + "graphStats": { + "title": "그래프 통계", + "nodeCount": "노드 수", + "edgeCount": "엣지 수" + }, + "factDialog": { + "title": "기억 사실", + "id": "ID", + "docId": "문서 ID", + "createdAt": "생성일", + "updatedAt": "수정일", + "metadata": "메타데이터", + "metadataKey": "키", + "metadataValue": "값", + "loading": "로딩 중...", + "close": "닫기", + "noValue": "없음", + "unknown": "알 수 없음" + }, + "messages": { + "searchQueryRequired": "검색할 키워드를 입력해주세요", + "searchSuccess": "관련된 기억 {count}개를 찾았습니다", + "searchNoResults": "관련된 기억 내용을 찾을 수 없습니다", + "searchError": "검색에 실패했습니다", + "addSuccess": "기억 데이터가 추가되었습니다!", + "addError": "기억 데이터 추가에 실패했습니다", + "factDetailsError": "기억 상세 정보를 가져오지 못했습니다", + "metadataParseError": "메타데이터를 파싱할 수 없습니다", + "relationNoMemoryData": "이 관계에는 연결된 기억 데이터가 없습니다" + } +} diff --git a/dashboard/src/i18n/locales/ko-KR/features/auth.json b/dashboard/src/i18n/locales/ko-KR/features/auth.json new file mode 100644 index 0000000000..e16e482eae --- /dev/null +++ b/dashboard/src/i18n/locales/ko-KR/features/auth.json @@ -0,0 +1,80 @@ +{ + "login": "로그인", + "username": "사용자 이름", + "password": "비밀번호", + "defaultHint": "처음 로그인하는 경우, 로그에서 기본 비밀번호를 확인하세요.", + "totp": { + "code": "인증 코드", + "verify": "확인", + "trustDevice": "이 기기를 30일간 신뢰" + }, + "recovery": { + "title": "복구 코드로 로그인", + "subtitle": "인증 앱에 접근할 수 없나요? 복구 코드로 로그인하세요.", + "code": "복구 코드", + "submit": "복구 코드로 로그인", + "useRecoveryCode": "TOTP를 사용할 수 없나요?", + "backToLogin": "로그인으로 돌아가기", + "savedWarning": "복구 코드를 잃어버리면 일반적인 방법으로는 계정에 다시 접근할 수 없습니다.", + "continue": "계속", + "acknowledge": "복구 코드를 저장했습니다", + "totpDisableWarning": "복구 코드를 사용하면 2단계 인증이 비활성화됩니다." + }, + "setup": { + "title": "계정 설정", + "subtitle": "AstrBot 관리에 사용할 계정을 생성합니다", + "username": "새 사용자 이름", + "password": "새 비밀번호", + "confirmPassword": "새 비밀번호 확인", + "passwordHint": "대문자, 소문자, 숫자를 포함해 8자 이상 입력하세요.", + "submit": "설정 완료", + "totp": { + "code": "인증 코드", + "qrAlt": "TOTP QR 코드", + "title": "TOTP 설정 완료", + "subtitle": "인증 앱으로 QR 코드를 스캔해 2단계 인증을 활성화하세요.", + "step2Hint": "인증 앱(예: Google Authenticator, Authy)으로 이 QR 코드를 스캔한 후 아래에 코드를 입력하세요.", + "verify": "확인 및 완료", + "verifyError": "코드를 확인할 수 없습니다. 인증 앱의 최신 코드를 입력하세요.", + "disableError": "TOTP를 비활성화할 수 없습니다. 다시 시도해주세요.", + "back": "뒤로" + }, + "validation": { + "usernameRequired": "사용자 이름을 입력하세요", + "usernameMinLength": "사용자 이름은 3자 이상이어야 합니다", + "passwordRequired": "비밀번호를 입력하세요", + "passwordMinLength": "비밀번호는 8자 이상이어야 합니다", + "passwordUppercase": "비밀번호에는 대문자가 하나 이상 포함되어야 합니다", + "passwordLowercase": "비밀번호에는 소문자가 하나 이상 포함되어야 합니다", + "passwordDigit": "비밀번호에는 숫자가 하나 이상 포함되어야 합니다", + "confirmPasswordRequired": "비밀번호 확인을 입력하세요", + "passwordMatch": "비밀번호가 일치하지 않습니다" + } + }, + "logo": { + "title": "AstrBot 대시보드", + "totpTitle": "2단계 인증", + "subtitle": "환영합니다" + }, + "versions": { + "webui": "WebUI", + "astrbotRuntime": "AstrBot", + "astrbotCode": "AstrBot(코드)", + "mismatchTooltip": "버전 불일치", + "dialogTitle": "확인이 필요한 버전 상태", + "webuiMismatchTitle": "WebUI가 현재 AstrBot 버전과 일치하지 않습니다", + "webuiMismatchMessage": "이 WebUI는 현재 실행 중인 AstrBot 버전에 맞게 빌드되지 않았을 수 있어 일부 페이지나 API가 예상과 다르게 동작할 수 있습니다. 먼저 AstrBot을 수동으로 재시작해보세요. 그래도 불일치가 계속되면 실행 디렉터리의 data/dist를 삭제한 후 다시 시작해 AstrBot이 알맞은 WebUI를 내려받도록 하세요.", + "runtimeMismatchTitle": "실행 중인 AstrBot이 코드 버전과 일치하지 않습니다", + "runtimeMismatchMessage": "코드는 업데이트되었지만 현재 실행 중인 프로세스는 여전히 이전 버전입니다. AstrBot을 수동으로 재시작해 새 코드를 불러오세요.", + "faq": "FAQ 보기", + "close": "닫기" + }, + "theme": { + "light": "라이트 모드", + "dark": "다크 모드", + "system": "시스템 설정 따르기", + "switchToDark": "다크 테마로 전환", + "switchToLight": "라이트 테마로 전환", + "title": "테마" + } +} diff --git a/dashboard/src/i18n/locales/ko-KR/features/chart.json b/dashboard/src/i18n/locales/ko-KR/features/chart.json new file mode 100644 index 0000000000..dfa16fb7ae --- /dev/null +++ b/dashboard/src/i18n/locales/ko-KR/features/chart.json @@ -0,0 +1,4 @@ +{ + "messageCount": "메시지 수", + "time": "시간" +} diff --git a/dashboard/src/i18n/locales/ko-KR/features/chat.json b/dashboard/src/i18n/locales/ko-KR/features/chat.json new file mode 100644 index 0000000000..c605b8743f --- /dev/null +++ b/dashboard/src/i18n/locales/ko-KR/features/chat.json @@ -0,0 +1,200 @@ +{ + "title": "채팅해요!", + "subtitle": "AI 어시스턴트와 대화하기", + "input": { + "placeholder": "무엇이든 물어보세요...", + "send": "전송", + "clear": "지우기", + "upload": "파일 업로드", + "voice": "음성 입력", + "recordingPrompt": "녹음 중입니다. 말씀해 주세요...", + "chatPrompt": "채팅해요!", + "dropToUpload": "파일을 놓아 업로드", + "stopGenerating": "생성 중지" + }, + "message": { + "user": "사용자", + "assistant": "어시스턴트", + "system": "시스템", + "error": "오류 메시지", + "loading": "생각 중..." + }, + "voice": { + "start": "녹음 시작", + "stop": "녹음 중지", + "recording": "새 녹음", + "processing": "처리 중...", + "error": "녹음 실패", + "listening": "듣는 중...", + "speaking": "말하는 중", + "startRecording": "음성 입력 시작", + "liveMode": "실시간 모드" + }, + "welcome": { + "title": "오늘은 무슨 생각을 하고 계신가요?", + "subtitle": "당신의 지능형 채팅 어시스턴트", + "quickActions": "빠른 작업", + "examples": "예시 질문" + }, + "actions": { + "copy": "복사", + "regenerate": "재생성", + "retry": "다시 시도", + "retryWithModel": "다른 모델 사용", + "noAvailableModels": "사용 가능한 모델 없음", + "like": "좋아요", + "dislike": "싫어요", + "share": "공유", + "newChat": "새 채팅", + "deleteChat": "이 대화 삭제", + "editTitle": "제목 편집", + "fullscreen": "전체 화면 모드", + "exitFullscreen": "전체 화면 종료", + "reply": "답장", + "providerConfig": "모델 구성", + "toolsUsed": "사용된 도구", + "toolCallUsed": "{name} 도구 사용됨", + "pythonCodeAnalysis": "Python 코드 분석 사용됨" + }, + "ipython": { + "output": "출력" + }, + "toolStatus": { + "done": "완료", + "running": "실행 중" + }, + "thread": { + "title": "스레드", + "askInThread": "스레드에서 질문", + "count": "스레드 {count}개", + "createFailed": "스레드 생성 실패", + "delete": "스레드 삭제", + "confirmDelete": "이 스레드를 삭제하시겠습니까? 이 작업은 되돌릴 수 없습니다.", + "placeholder": "이 발췌 내용에 대해 질문하세요..." + }, + "conversation": { + "title": "대화", + "newConversation": "새 대화", + "noHistory": "대화 기록 없음", + "systemStatus": "시스템 상태", + "llmService": "LLM 서비스", + "speechToText": "음성 인식", + "editDisplayName": "세션 이름 편집", + "displayName": "세션 이름", + "displayNameUpdated": "세션 이름이 업데이트되었습니다", + "displayNameUpdateFailed": "세션 이름 업데이트 실패", + "confirmDelete": "\"{name}\"을(를) 삭제하시겠습니까? 이 작업은 되돌릴 수 없습니다." + }, + "modes": { + "darkMode": "다크 모드로 전환", + "lightMode": "라이트 모드로 전환" + }, + "shortcuts": { + "help": "도움말 보기", + "voiceRecord": "음성 녹음", + "pasteImage": "이미지 붙여넣기", + "sendKey": { + "title": "전송 단축키", + "enterToSend": "Enter로 전송", + "shiftEnterToSend": "Shift+Enter로 전송" + } + }, + "streaming": { + "enabled": "스트리밍 사용", + "disabled": "스트리밍 사용 안 함", + "on": "스트림", + "off": "일반" + }, + "transport": { + "title": "전송 모드", + "sse": "SSE", + "websocket": "WebSocket" + }, + "config": { + "title": "구성" + }, + "reasoning": { + "thinking": "사고 과정", + "summarySeparator": ", ", + "thinkSummary": "{count}회 사고함", + "toolSummary": "도구 {count}개 사용", + "think": "생각 중", + "toolUsed": "도구 사용 중" + }, + "reply": { + "replyTo": "답장 대상", + "notFound": "메시지를 찾을 수 없습니다" + }, + "project": { + "title": "프로젝트", + "create": "프로젝트 생성", + "edit": "프로젝트 편집", + "name": "프로젝트 이름", + "emoji": "아이콘 (이모지)", + "description": "설명 (선택 사항)", + "workspace": { + "type": "작업 공간", + "session": "세션별 작업 공간", + "project": "공유 프로젝트 작업 공간", + "custom": "사용자 지정 경로", + "path": "작업 공간 경로" + }, + "loadingSessions": "대화 불러오는 중...", + "noSessions": "이 프로젝트에 대화가 없습니다", + "noProjects": "프로젝트 없음", + "confirmDelete": "\"{title}\" 프로젝트를 삭제하시겠습니까? 이 프로젝트의 대화는 삭제되지 않습니다." + }, + "time": { + "today": "오늘", + "yesterday": "어제" + }, + "stats": { + "tokens": "토큰", + "inputTokens": "입력 (기타)", + "outputTokens": "출력 토큰", + "cachedTokens": "입력 (캐시됨)", + "duration": "소요 시간", + "ttft": "첫 토큰까지 걸린 시간" + }, + "tokenUsage": { + "tooltip": "{used} / {limit} 토큰 ({percent}%)" + }, + "refs": { + "title": "참고 자료", + "sources": "출처" + }, + "connection": { + "title": "연결 상태 알림", + "message": "시스템이 채팅 연결을 다시 설정해야 함을 감지했습니다.", + "reasons": "다음과 같은 이유일 수 있습니다:", + "reasonWindowResize": "채팅 창 크기 전환 (정상 동작)", + "reasonMultipleTabs": "다른 탭에서 채팅 페이지 열기", + "reasonNetworkIssue": "일시적인 네트워크 중단", + "notice": "참고: 메시지가 정상적으로 전달되도록 시스템은 한 번에 하나의 활성 채팅 연결만 허용합니다. 여러 탭에서 채팅을 사용 중이라면 하나의 페이지만 열어 두세요.", + "understand": "확인했습니다", + "status": { + "reconnecting": "재연결 중...", + "reconnected": "채팅 연결이 다시 설정되었습니다", + "failed": "연결 실패, 페이지를 새로고침해 주세요" + } + }, + "commandSuggestion": { + "navigate": "이동", + "select": "선택", + "close": "닫기" + }, + "errors": { + "sendMessageFailed": "메시지 전송 실패, 다시 시도해 주세요", + "createSessionFailed": "세션 생성 실패, 페이지를 새로고침해 주세요" + }, + "batch": { + "selected": "{count}개 선택됨", + "confirmDelete": "대화 {count}개를 삭제하시겠습니까? 이 작업은 되돌릴 수 없습니다.", + "selectAll": "전체 선택", + "deselectAll": "전체 선택 해제", + "delete": "삭제", + "exit": "나가기", + "partialFailure": "대화 {total}개 중 {failed}개 삭제 실패", + "requestFailed": "대화 삭제 실패. 다시 시도해 주세요." + } +} diff --git a/dashboard/src/i18n/locales/ko-KR/features/command.json b/dashboard/src/i18n/locales/ko-KR/features/command.json new file mode 100644 index 0000000000..fe047c6757 --- /dev/null +++ b/dashboard/src/i18n/locales/ko-KR/features/command.json @@ -0,0 +1,95 @@ +{ + "title": "명령어 관리", + "summary": { + "total": "표시된 명령어", + "disabled": "비활성화됨", + "conflicts": "충돌" + }, + "conflictAlert": { + "title": "명령어 충돌 감지됨", + "description": "충돌하는 명령어가 {count}개 있습니다. 충돌하는 명령어는 여러 플러그인을 동시에 실행시켜 예상치 못한 동작을 일으킬 수 있습니다.", + "hint": "\"이름 변경\" 버튼을 클릭해 충돌하는 명령어의 이름을 변경하고 충돌을 해결하세요." + }, + "table": { + "headers": { + "command": "명령어", + "type": "유형", + "plugin": "플러그인", + "description": "설명", + "permission": "권한", + "status": "상태", + "actions": "작업" + } + }, + "type": { + "command": "명령어", + "group": "그룹", + "subCommand": "하위 명령어" + }, + "status": { + "enabled": "활성화됨", + "disabled": "비활성화됨", + "conflict": "충돌" + }, + "permission": { + "everyone": "모든 사용자", + "admin": "관리자" + }, + "tooltips": { + "enable": "명령어 활성화", + "disable": "명령어 비활성화", + "rename": "명령어 이름 변경", + "viewDetails": "세부 정보 보기" + }, + "dialogs": { + "rename": { + "title": "명령어 이름 변경", + "newName": "새 명령어 이름", + "aliases": "별칭 관리", + "addAlias": "별칭 추가", + "cancel": "취소", + "confirm": "확인" + }, + "details": { + "title": "명령어 세부 정보", + "type": "명령어 유형", + "handler": "핸들러", + "module": "모듈 경로", + "originalCommand": "원본 명령어", + "effectiveCommand": "적용된 명령어", + "parentGroup": "상위 그룹", + "subCommands": "하위 명령어", + "aliases": "별칭", + "permission": "권한", + "conflictStatus": "충돌 상태" + } + }, + "messages": { + "toggleSuccess": "명령어 상태가 업데이트되었습니다", + "toggleFailed": "명령어 상태 업데이트 실패", + "renameSuccess": "명령어 이름이 변경되었습니다", + "renameFailed": "이름 변경 실패", + "loadFailed": "명령어 불러오기 실패", + "updateSuccess": "업데이트 성공", + "updateFailed": "업데이트 실패" + }, + "search": { + "placeholder": "명령어 검색..." + }, + "empty": { + "noCommands": "명령어 없음", + "noCommandsDesc": "명령어를 찾을 수 없습니다" + }, + "filters": { + "all": "전체", + "enabled": "활성화됨", + "disabled": "비활성화됨", + "conflict": "충돌", + "byPlugin": "플러그인별 필터", + "byType": "유형별 필터", + "byPermission": "권한별 필터", + "byStatus": "상태별 필터", + "showSystemPlugins": "시스템 플러그인 명령어 표시", + "systemPluginConflictHint": "시스템 플러그인 충돌이 감지되었습니다. 충돌을 해결하면 숨겨집니다." + } +} diff --git a/dashboard/src/i18n/locales/ko-KR/features/config-metadata.json b/dashboard/src/i18n/locales/ko-KR/features/config-metadata.json new file mode 100644 index 0000000000..f307e4ec0d --- /dev/null +++ b/dashboard/src/i18n/locales/ko-KR/features/config-metadata.json @@ -0,0 +1,1768 @@ +{ + "ai_group": { + "name": "AI", + "agent_runner": { + "description": "Agent 실행기", + "hint": "AI 대화에 사용할 실행기를 선택하세요. 기본값은 지식 베이스, 페르소나, 도구 호출 기능을 지원하는 AstrBot 내장 Agent 실행기입니다. Dify, Coze, DeerFlow 같은 서드파티 Agent 실행기를 연동할 계획이 아니라면 이 항목을 수정할 필요가 없습니다.", + "provider_settings": { + "enable": { + "description": "활성화", + "hint": "AI 대화의 메인 스위치" + }, + "agent_runner_type": { + "description": "실행기", + "labels": [ + "내장 Agent", + "Dify", + "Coze", + "Alibaba Cloud Bailian 애플리케이션", + "DeerFlow" + ] + }, + "coze_agent_runner_provider_id": { + "description": "Coze Agent 실행기 공급자 ID" + }, + "dify_agent_runner_provider_id": { + "description": "Dify Agent 실행기 공급자 ID" + }, + "dashscope_agent_runner_provider_id": { + "description": "Alibaba Cloud Bailian 애플리케이션 Agent 실행기 공급자 ID" + }, + "deerflow_agent_runner_provider_id": { + "description": "DeerFlow Agent 실행기 공급자 ID" + } + } + }, + "ai": { + "description": "모델", + "hint": "내장이 아닌 Agent 실행기를 사용할 경우 기본 채팅 모델과 기본 이미지 캡션 모델이 적용되지 않을 수 있지만, 일부 플러그인은 AI 기능 호출을 위해 이 설정에 의존합니다.", + "provider_settings": { + "default_provider_id": { + "description": "기본 채팅 모델", + "hint": "비워두면 첫 번째 모델을 사용합니다" + }, + "fallback_chat_models": { + "description": "대체 채팅 모델 ID", + "hint": "기본 채팅 모델 요청이 실패하면 이 채팅 모델들을 순서대로 대체 사용합니다." + }, + "request_max_retries": { + "description": "최대 재시도 횟수", + "hint": "재시도 가능한 오류가 발생했을 때 단일 모델 요청에 대한 최대 시도 횟수입니다." + }, + "default_image_caption_provider_id": { + "description": "기본 이미지 캡션 모델", + "hint": "비활성화하려면 비워두세요. 멀티모달을 지원하지 않는 모델에 유용합니다" + }, + "image_caption_prompt": { + "description": "이미지 캡션 프롬프트" + } + }, + "provider_stt_settings": { + "enable": { + "description": "음성 인식(STT) 활성화", + "hint": "STT의 메인 스위치" + }, + "provider_id": { + "description": "기본 음성 인식(STT) 모델", + "hint": "사용자는 /provider 명령어로 세션별 STT 모델을 선택할 수도 있습니다." + } + }, + "provider_tts_settings": { + "enable": { + "description": "음성 합성(TTS) 활성화", + "hint": "TTS의 메인 스위치" + }, + "provider_id": { + "description": "기본 음성 합성(TTS) 모델" + }, + "trigger_probability": { + "description": "TTS 트리거 확률" + } + } + }, + "persona": { + "description": "페르소나", + "hint": "AI 대화에 사용할 기본 페르소나를 설정합니다. 페르소나는 페르소나 탭에서 관리할 수 있습니다.", + "provider_settings": { + "default_personality": { + "description": "기본 페르소나" + } + } + }, + "knowledgebase": { + "description": "지식 베이스", + "kb_names": { + "description": "지식 베이스 목록", + "hint": "다중 선택을 지원합니다" + }, + "kb_fusion_top_k": { + "description": "융합 검색 결과 수", + "hint": "여러 지식 베이스의 검색 결과를 융합한 후 반환되는 결과 수입니다" + }, + "kb_final_top_k": { + "description": "최종 결과 수", + "hint": "지식 베이스에서 조회하는 결과 수입니다. 값을 높이면 더 관련성 높은 정보를 얻을 수 있지만 노이즈도 늘어날 수 있습니다. 실제 필요에 맞게 조정하세요" + }, + "kb_agentic_mode": { + "description": "Agentic 지식 베이스 검색", + "hint": "활성화하면 지식 베이스 검색이 LLM 도구가 되어, 모델이 언제 지식 베이스를 조회할지 스스로 판단할 수 있습니다. 모델이 함수 호출(function calling)을 지원해야 합니다." + } + }, + "websearch": { + "description": "웹 검색", + "provider_settings": { + "web_search": { + "description": "웹 검색 활성화" + }, + "websearch_provider": { + "description": "웹 검색 공급자" + }, + "websearch_tavily_key": { + "description": "Tavily API 키", + "hint": "여러 개의 키를 추가하여 순환 사용할 수 있습니다." + }, + "websearch_bocha_key": { + "description": "BoCha API 키", + "hint": "여러 개의 키를 추가하여 순환 사용할 수 있습니다." + }, + "websearch_brave_key": { + "description": "Brave Search API 키", + "hint": "여러 개의 키를 추가하여 순환 사용할 수 있습니다." + }, + "websearch_firecrawl_key": { + "description": "Firecrawl API 키", + "hint": "여러 개의 키를 추가하여 순환 사용할 수 있습니다." + }, + "websearch_baidu_app_builder_key": { + "description": "Baidu Qianfan Smart Cloud APP Builder API 키", + "hint": "참고: [https://console.bce.baidu.com/iam/#/iam/apikey/list](https://console.bce.baidu.com/iam/#/iam/apikey/list)" + }, + "web_search_link": { + "description": "출처 인용 표시" + }, + "websearch_exa_key": { + "description": "Exa API 키", + "hint": "여러 개의 키를 추가하여 순환 사용할 수 있습니다. https://dashboard.exa.ai 에서 키를 발급받으세요" + } + } + }, + "file_extract": { + "description": "파일 추출", + "provider_settings": { + "file_extract": { + "enable": { + "description": "파일 추출 활성화" + }, + "provider": { + "description": "파일 추출 공급자" + }, + "moonshotai_api_key": { + "description": "Moonshot AI API 키" + } + } + } + }, + "agent_computer_use": { + "description": "Agent 컴퓨터 사용", + "hint": "AstrBot이 더 복잡한 작업을 수행할 수 있도록 사용자의 컴퓨터나 샌드박스 환경에 접근하여 사용할 수 있게 합니다. 참고: [Computer Use](https://docs.astrbot.app/use/computer.html).", + "provider_settings": { + "computer_use_runtime": { + "description": "컴퓨터 사용 런타임", + "hint": "Agent 사용을 허용할 환경입니다. `local`은 로컬 머신 환경, `sandbox`는 샌드박스 환경, `none`은 어떤 환경도 허용하지 않음을 의미합니다." + }, + "computer_use_require_admin": { + "description": "AstrBot 관리자 권한 필요", + "hint": "활성화하면 컴퓨터 기능을 사용하는 데 AstrBot 관리자 권한이 필요합니다. 관리자는 플랫폼 구성에서 추가할 수 있습니다. /sid 명령어로 관리자 ID를 확인하세요." + }, + "sandbox": { + "booter": { + "description": "샌드박스 환경 드라이버" + }, + "shipyard_neo_endpoint": { + "description": "Shipyard Neo API 엔드포인트", + "hint": "Bay API 주소, 기본값 http://127.0.0.1:8114." + }, + "shipyard_neo_access_token": { + "description": "Shipyard Neo 액세스 토큰", + "hint": "Bay API 키(sk-bay-...)입니다. 비워두면 credentials.json에서 자동으로 검색합니다." + }, + "shipyard_neo_profile": { + "description": "Shipyard Neo 프로필", + "hint": "Shipyard Neo용 샌드박스 프로필입니다(예: python-default). 비워두면 가장 성능이 좋은 프로필을 자동 선택합니다." + }, + "shipyard_neo_ttl": { + "description": "Shipyard Neo 샌드박스 TTL", + "hint": "샌드박스의 생존 시간(초)입니다." + }, + "cua_image": { + "description": "CUA 이미지", + "hint": "CUA 샌드박스 이미지 또는 OS 유형입니다. 기본값은 linux입니다. 지원되는 값은 설치된 CUA SDK에 따라 다릅니다." + }, + "cua_os_type": { + "description": "CUA OS 유형", + "hint": "CUA 샌드박스 운영체제 유형입니다. 기본값은 linux입니다." + }, + "cua_idle_timeout": { + "description": "CUA 유휴 제한 시간", + "hint": "CUA 샌드박스 세션의 유휴 제한 시간(초)입니다. 0보다 크면 AstrBot이 해당 시간만큼 비활성 상태가 지속된 유휴 CUA 샌드박스를 자동으로 종료합니다. 0은 비활성화를 의미합니다." + }, + "cua_telemetry_enabled": { + "description": "CUA 원격 측정", + "hint": "CUA SDK가 원격 측정 데이터를 전송하도록 허용합니다. 기본값은 비활성화입니다." + }, + "cua_local": { + "description": "CUA 로컬 샌드박스", + "hint": "로컬 CUA 샌드박스를 우선 사용합니다. 클라우드 샌드박스에 CUA_API_KEY가 필요하지 않도록 기본값은 활성화입니다. CUA 클라우드 샌드박스를 사용하려면 비활성화하세요." + }, + "cua_api_key": { + "description": "CUA API 키", + "hint": "CUA 클라우드 샌드박스 API 키입니다. 로컬 샌드박스가 비활성화된 경우에만 필요합니다. CUA_API_KEY 환경 변수로도 제공할 수 있습니다." + }, + "shipyard_endpoint": { + "description": "Shipyard API 엔드포인트", + "hint": "Shipyard 서비스에 접근하기 위한 API 주소입니다." + }, + "shipyard_access_token": { + "description": "Shipyard 액세스 토큰", + "hint": "Shipyard 서비스에 접근하기 위한 액세스 토큰입니다." + }, + "shipyard_ttl": { + "description": "Shipyard 세션 TTL", + "hint": "세션의 생존 시간(초)입니다." + }, + "shipyard_max_sessions": { + "description": "Shipyard 최대 세션 수", + "hint": "인스턴스 하나가 처리할 수 있는 최대 Shipyard 세션 수입니다." + } + } + } + }, + "proactive_capability": { + "description": "능동형 Agent", + "hint": "AstrBot이 스스로 깨어나 작업을 실행하고 결과를 전달합니다. 참고: [Proactive Agent](https://docs.astrbot.app/en/use/proactive-agent.html)", + "provider_settings": { + "proactive_capability": { + "add_cron_tools": { + "description": "활성화", + "hint": "활성화하면 관련 도구가 Agent에 전달되어 능동형 Agent 기능을 구현합니다. 미래의 특정 시점에 무엇을 할지 AstrBot에게 알려주면 예약된 시간에 트리거되어 작업을 실행하고 결과를 사용자에게 보고합니다." + } + } + } + }, + "truncate_and_compress": { + "hint": "[컨텍스트 관리](https://docs.astrbot.app/en/use/context-compress.html)", + "description": "컨텍스트 관리 전략", + "provider_settings": { + "max_context_length": { + "description": "압축 전 최대 대화 턴 수", + "hint": "영구 대화 기록은 이 턴 수를 초과한 뒤에만 아래 전략에 따라 잘리거나 LLM으로 압축됩니다. 요청 시점의 컨텍스트도 전송 전에 이 값의 제약을 받습니다. -1은 턴 수 제한이 없음을 의미합니다." + }, + "dequeue_context_length": { + "description": "한도 초과 시 폐기할 턴 수", + "hint": "기록이 '압축 전 최대 대화 턴 수'를 초과하고 LLM 압축을 사용할 수 없을 때, 가장 오래된 턴을 한 번에 이 개수만큼 폐기합니다. 요청 시점의 잘라내기에도 동일한 값이 재사용됩니다." + }, + "context_limit_reached_strategy": { + "description": "기록 한도 초과 또는 컨텍스트 윈도우 부담 처리 방식", + "labels": [ + "턴 단위로 자르기", + "LLM으로 압축" + ], + "hint": "영구 대화 기록은 '압축 전 최대 대화 턴 수'를 초과한 뒤에만 이 전략을 사용합니다. 각 요청 전에는 토큰이 모델 윈도우에 근접할 때 진행 중인 컨텍스트를 보호하는 데도 동일한 전략이 사용될 수 있습니다." + }, + "llm_compress_instruction": { + "description": "컨텍스트 압축 지시문", + "hint": "비워두면 기본 프롬프트를 사용합니다." + }, + "llm_compress_keep_recent_ratio": { + "description": "유지할 최근 컨텍스트 토큰 비율", + "hint": "현재 컨텍스트 토큰 비율 기준으로 최근 정확한 컨텍스트를 유지합니다(0~0.3). 0.15는 15%를 유지함을 의미하며, 0보다 큰 값은 최소한 가장 최근 라운드를 유지합니다." + }, + "llm_compress_provider_id": { + "description": "컨텍스트 압축용 모델 공급자 ID", + "hint": "비워두면 현재 채팅 모델이 압축에 사용됩니다. 모델을 사용할 수 없거나 압축에 실패하면 AstrBot은 '턴 단위로 자르기' 전략으로 대체합니다." + }, + "fallback_max_context_tokens": { + "description": "대체 컨텍스트 윈도우 크기", + "hint": "max_context_tokens가 0이고 모델이 내장 메타데이터에 없을 때 이 값을 컨텍스트 윈도우 크기로 사용합니다. 기본값: 128000." + } + } + }, + "others": { + "description": "기타 설정", + "provider_settings": { + "display_reasoning_text": { + "description": "추론 내용 표시" + }, + "llm_safety_mode": { + "description": "건전 모드", + "hint": "모델 답변에 안전 가드레일을 추가합니다." + }, + "safety_mode_strategy": { + "description": "건전 모드 전략", + "hint": "건전 모드를 적용하는 방식입니다." + }, + "identifier": { + "description": "사용자 식별", + "hint": "활성화하면 사용자 ID 정보가 프롬프트에 포함됩니다." + }, + "group_name_display": { + "description": "그룹 이름 표시", + "hint": "활성화하면 지원되는 플랫폼(OneBot v11)에서 그룹 이름 정보가 프롬프트에 포함됩니다." + }, + "datetime_system_prompt": { + "description": "실제 시간 인식", + "hint": "활성화하면 현재 시간 정보가 시스템 프롬프트에 추가됩니다." + }, + "show_tool_use_status": { + "description": "함수 호출 상태 출력" + }, + "show_tool_call_result": { + "description": "도구 호출 결과 출력", + "hint": "\"함수 호출 상태 출력\"이 활성화된 경우에만 적용되며, 최대 70자까지 표시됩니다." + }, + "buffer_intermediate_messages": { + "description": "Agent 중간 메시지 병합", + "hint": "활성화하면 비스트리밍 모드에서 다단계 도구 호출 중 생성된 중간 텍스트가 버퍼링되어 Agent 완료 후 하나의 병합된 답변으로 전송됩니다." + }, + "sanitize_context_by_modalities": { + "description": "모달리티 기준 기록 정제", + "hint": "활성화하면 각 LLM 요청 전에 현재 공급자의 모달리티가 지원하지 않는 이미지 블록과 도구 호출 구조를 제거하여 컨텍스트를 정제합니다(모델이 보는 내용이 달라집니다)." + }, + "max_quoted_fallback_images": { + "description": "전달 메시지 이미지 조회 한도", + "hint": "전달된 메시지 파싱에서 주입되는 최대 이미지 수입니다. 초과분은 잘립니다." + }, + "quoted_message_parser": { + "max_component_chain_depth": { + "description": "전달 리치 텍스트 파싱 깊이", + "hint": "전달된 메시지 내부의 리치 텍스트 컴포넌트 체인을 파싱할 때의 최대 재귀 깊이입니다." + }, + "max_forward_node_depth": { + "description": "전달 중첩 파싱 깊이", + "hint": "중첩된 전달 노드를 파싱할 때의 최대 재귀 깊이입니다." + }, + "max_forward_fetch": { + "description": "전달 재귀 조회 한도", + "hint": "get_forward_msg 재귀 조회 작업의 최대 횟수입니다." + }, + "warn_on_action_failure": { + "description": "전달 파싱 실패 시 경고", + "hint": "활성화하면 모든 get_msg/get_forward_msg 시도가 실패했을 때 경고 로그를 남깁니다." + } + }, + "max_agent_step": { + "description": "최대 도구 호출 라운드 수" + }, + "tool_call_timeout": { + "description": "도구 호출 제한 시간(초)" + }, + "tool_schema_mode": { + "description": "도구 스키마 모드", + "hint": "Skills 방식은 먼저 이름/설명만 전송하고 파라미터는 재조회하며, Full 방식은 전체 스키마를 한 번에 전송합니다.", + "labels": [ + "Skills 방식(2단계)", + "전체 스키마" + ] + }, + "streaming_response": { + "description": "스트리밍 출력" + }, + "unsupported_streaming_strategy": { + "description": "스트리밍을 지원하지 않는 플랫폼", + "hint": "스트리밍 응답을 지원하지 않는 플랫폼에 대한 처리 방식을 선택하세요. 실시간 분할 답변은 스트리밍 수신 중 마침표 등 구분점을 감지하면 즉시 내용을 전송합니다", + "labels": [ + "실시간 분할 답변", + "스트리밍 응답 비활성화" + ] + }, + "wake_prefix": { + "description": "추가 LLM 채팅 웨이크 프리픽스", + "hint": "웨이크 프리픽스가 /이고 추가 채팅 웨이크 프리픽스가 chat이면, LLM 요청을 트리거하려면 /chat이 필요합니다" + }, + "prompt_prefix": { + "description": "사용자 프롬프트", + "hint": "사용자 입력의 자리 표시자로 {{prompt}}를 사용할 수 있습니다. 자리 표시자가 없으면 사용자 입력 앞에 추가됩니다." + }, + "image_compress_enabled": { + "description": "이미지 압축 활성화", + "hint": "활성화하면 멀티모달 모델에 전송하기 전 용량이 큰 로컬 이미지를 압축합니다." + }, + "image_compress_options": { + "description": "이미지 압축 설정", + "hint": "이미지 크기 조정 한도, JPEG 품질, 압축 적용 최소 크기 임계값을 제어합니다.", + "max_size": { + "description": "최대 가장자리 길이", + "hint": "압축된 이미지의 가장 긴 변의 길이(픽셀)입니다. 이보다 큰 이미지는 비율에 맞게 축소됩니다." + }, + "quality": { + "description": "JPEG 품질", + "hint": "JPEG 출력 품질(1~100)입니다. 값이 높을수록 디테일이 잘 보존되지만 파일 크기가 커집니다." + } + }, + "reachability_check": { + "description": "공급자 연결 확인", + "hint": "/provider 명령어 실행 시 공급자 연결 상태를 병렬로 테스트합니다. 실제로 모델에 핑을 보내므로 추가 토큰이 소모될 수 있습니다." + } + }, + "provider_tts_settings": { + "dual_output": { + "description": "TTS 활성화 시 음성과 텍스트 동시 출력" + } + } + } + }, + "platform_group": { + "name": "플랫폼", + "platform": { + "description": "메시지 플랫폼 어댑터", + "active_send_mode": { + "description": "능동 전송 API 사용" + }, + "appid": { + "description": "App ID", + "hint": "필수 항목입니다. 현재 메시징 플랫폼의 App ID입니다. 발급 방법은 플랫폼 연동 문서를 참고하세요." + }, + "callback_server_host": { + "description": "콜백 서버 호스트", + "hint": "콜백 서버 호스트입니다. 비워두면 콜백 서버가 비활성화됩니다." + }, + "card_template_id": { + "description": "카드 템플릿 ID", + "hint": "선택 항목입니다. DingTalk 인터랙티브 카드 템플릿 ID입니다. 활성화하면 스트리밍 답변에 인터랙티브 카드가 사용됩니다." + }, + "discord_activity_name": { + "description": "Discord 활동 이름", + "hint": "선택적인 Discord 활동 이름입니다. 비워두면 비활성화됩니다." + }, + "discord_allow_bot_messages": { + "description": "봇 메시지 허용", + "hint": "활성화하면 AstrBot이 다른 Discord 봇의 메시지를 수신합니다. 봇 간 통신 시나리오(예: 메시지 전달)에 유용합니다. 기본값은 비활성화입니다." + }, + "discord_command_register": { + "description": "Discord 슬래시 명령어 등록", + "hint": "활성화하면 AstrBot이 플러그인 명령어를 Discord 슬래시 명령어로 자동 등록합니다" + }, + "discord_proxy": { + "description": "Discord 프록시 URL", + "hint": "선택적 프록시 URL: http://ip:port" + }, + "discord_token": { + "description": "Discord 봇 토큰", + "hint": "여기에 Discord 봇 토큰을 입력하세요." + }, + "enable": { + "description": "활성화", + "hint": "이 어댑터를 활성화할지 여부입니다. 비활성화된 어댑터는 메시지를 수신하지 않습니다." + }, + "enable_group_c2c": { + "description": "메시지 목록 개인 채팅 활성화", + "hint": "활성화하면 봇이 QQ 메시지 목록에서 온 개인 채팅을 수신할 수 있습니다. QQ 봇 플랫폼에서 QR 코드를 스캔해 봇을 친구로 추가해야 할 수 있습니다. 문서를 참고하세요." + }, + "enable_guild_direct_message": { + "description": "길드 다이렉트 메시지 활성화", + "hint": "활성화하면 봇이 길드 다이렉트 메시지를 수신할 수 있습니다." + }, + "id": { + "description": "봇 이름", + "hint": "봇 이름" + }, + "is_sandbox": { + "description": "샌드박스 모드" + }, + "kf_name": { + "description": "WeChat 고객센터 계정 이름", + "hint": "선택 항목입니다. 고객센터 계정 이름(ID 아님)입니다. https://kf.weixin.qq.com/kf/frame#/accounts 에서 확인하세요" + }, + "lark_connection_mode": { + "description": "구독 모드", + "labels": [ + "롱 커넥션 모드", + "웹훅 서버 모드" + ] + }, + "lark_encrypt_key": { + "description": "암호화 키", + "hint": "Lark 콜백 데이터를 복호화하기 위한 암호화 키입니다." + }, + "lark_verification_token": { + "description": "검증 토큰", + "hint": "Lark 콜백 요청을 검증하기 위한 토큰입니다." + }, + "misskey_allow_insecure_downloads": { + "description": "안전하지 않은 다운로드 허용(SSL 검증 비활성화)", + "hint": "원격 서버에 인증서 문제가 있을 경우 대체 수단으로 SSL 검증을 비활성화합니다. 보안 위험이 있으므로 필요한 경우에만 사용하세요." + }, + "misskey_default_visibility": { + "description": "기본 게시물 공개 범위", + "hint": "봇 게시물의 기본 공개 범위입니다. public: 전체 공개, home: 홈 타임라인, followers: 팔로워만." + }, + "misskey_download_chunk_size": { + "description": "스트림 다운로드 청크 크기(바이트)", + "hint": "스트리밍 다운로드 및 MD5 계산 시 청크당 읽는 바이트 수입니다. 너무 작으면 오버헤드가 늘고, 너무 크면 메모리를 더 사용합니다." + }, + "misskey_download_timeout": { + "description": "원격 다운로드 제한 시간(초)", + "hint": "로컬 업로드로 대체할 때 사용되는 원격 파일 다운로드 제한 시간(초)입니다." + }, + "misskey_enable_chat": { + "description": "채팅 메시지 응답 활성화", + "hint": "활성화하면 봇이 개인 채팅 메시지를 수신하고 응답합니다." + }, + "misskey_enable_file_upload": { + "description": "Misskey 파일 업로드 활성화", + "hint": "활성화하면 어댑터가 메시지 체인의 파일을 Misskey에 업로드합니다. URL 파일은 먼저 서버 측 업로드를 시도하며, 비동기 업로드가 실패하면 로컬 다운로드 후 업로드로 대체됩니다." + }, + "misskey_instance_url": { + "description": "Misskey 인스턴스 URL", + "hint": "예: https://misskey.example. 봇 계정이 있는 Misskey 인스턴스입니다." + }, + "misskey_local_only": { + "description": "로컬 전용(연합 비활성화)", + "hint": "활성화하면 봇 게시물이 이 인스턴스에서만 보이고 연합(federation)되지 않습니다." + }, + "misskey_max_download_bytes": { + "description": "최대 다운로드 크기(바이트)", + "hint": "OOM을 방지하기 위해 다운로드 크기 상한을 설정합니다. 비워두거나 null이면 제한이 없습니다." + }, + "misskey_token": { + "description": "Misskey 액세스 토큰", + "hint": "연결 서비스 설정에서 생성된 API 액세스 토큰입니다." + }, + "misskey_upload_concurrency": { + "description": "업로드 동시성 제한", + "hint": "동시에 실행되는 최대 업로드 작업 수(정수, 기본값 3)입니다." + }, + "misskey_upload_folder": { + "description": "대상 드라이브 폴더 ID", + "hint": "선택 항목: Misskey 드라이브 내 대상 폴더의 ID입니다. 비워두면 루트 폴더를 사용합니다." + }, + "port": { + "description": "콜백 서버 포트", + "hint": "콜백 서버 포트입니다. 비워두면 콜백 서버가 비활성화됩니다." + }, + "satori_api_base_url": { + "description": "Satori API 엔드포인트", + "hint": "Satori API의 기본 URL입니다." + }, + "satori_auto_reconnect": { + "description": "자동 재연결 활성화", + "hint": "WebSocket 연결이 끊기면 자동으로 재연결합니다." + }, + "satori_endpoint": { + "description": "Satori WebSocket 엔드포인트", + "hint": "Satori 이벤트용 WebSocket 엔드포인트입니다." + }, + "satori_heartbeat_interval": { + "description": "Satori 하트비트 간격", + "hint": "하트비트 메시지 간의 간격(초)입니다." + }, + "satori_reconnect_delay": { + "description": "Satori 재연결 지연", + "hint": "재연결을 시도하기 전 대기 시간(초)입니다." + }, + "satori_token": { + "description": "Satori 토큰", + "hint": "Satori API 인증용 토큰입니다." + }, + "secret": { + "description": "시크릿", + "hint": "필수 항목입니다." + }, + "slack_connection_mode": { + "description": "Slack 연결 모드", + "hint": "Slack의 연결 모드입니다. `webhook`은 웹훅 서버를 사용하고, `socket`은 Slack의 Socket Mode를 사용합니다." + }, + "slack_webhook_host": { + "description": "Slack 웹훅 호스트", + "hint": "Slack 연결 모드가 `webhook`일 때만 유효합니다." + }, + "slack_webhook_path": { + "description": "Slack 웹훅 경로", + "hint": "Slack 연결 모드가 `webhook`일 때만 유효합니다." + }, + "slack_webhook_port": { + "description": "Slack 웹훅 포트", + "hint": "Slack 연결 모드가 `webhook`일 때만 유효합니다." + }, + "telegram_command_auto_refresh": { + "description": "Telegram 명령어 자동 새로고침", + "hint": "활성화하면 AstrBot이 실행 중 Telegram 명령어를 자동으로 새로고침합니다. (이 설정만으로는 효과가 없습니다)" + }, + "telegram_command_register": { + "description": "Telegram 명령어 등록", + "hint": "활성화하면 AstrBot이 Telegram 명령어를 자동으로 등록합니다." + }, + "telegram_command_register_interval": { + "description": "Telegram 명령어 자동 새로고침 간격", + "hint": "Telegram 명령어 자동 새로고침 간격(초)입니다." + }, + "telegram_polling_restart_delay": { + "description": "Telegram 폴링 재시작 지연", + "hint": "폴링 루프가 예기치 않게 종료되어 재시작이 필요할 때의 대기 시간(초)입니다. 기본값은 5초입니다." + }, + "telegram_token": { + "description": "봇 토큰", + "hint": "중국 본토에 있다면 프록시를 설정하거나 기타 설정에서 api_base를 변경하세요." + }, + "mattermost_url": { + "description": "Mattermost URL", + "hint": "Mattermost 서비스 URL입니다(예: https://chat.example.com)." + }, + "mattermost_bot_token": { + "description": "Mattermost 봇 토큰", + "hint": "Mattermost에서 봇 계정을 생성한 뒤 발급되는 액세스 토큰입니다." + }, + "mattermost_reconnect_delay": { + "description": "Mattermost 재연결 지연", + "hint": "WebSocket 연결이 끊긴 뒤 재연결까지 대기하는 시간(초)입니다. 기본값은 5초입니다." + }, + "type": { + "description": "어댑터 유형" + }, + "unified_webhook_mode": { + "description": "통합 웹훅 모드", + "hint": "활성화하면 별도의 포트를 열지 않고 AstrBot 통합 웹훅 엔트리를 사용합니다. 콜백 URL은 /api/v1/webhooks/platforms/{webhook_uuid}입니다." + }, + "webhook_uuid": { + "description": "웹훅 UUID", + "hint": "통합 웹훅 모드의 고유 식별자로, 플랫폼 생성 시 자동 생성됩니다." + }, + "wecom_ai_bot_name": { + "description": "WeCom AI 봇 이름", + "hint": "정확해야 합니다. 그렇지 않으면 일부 명령어가 동작하지 않습니다." + }, + "wecom_ai_bot_connection_mode": { + "description": "WeCom AI 봇 연결 모드", + "hint": "웹훅 모드는 Token/EncodingAESKey가 필요하며, long_connection 모드는 BotID/Secret이 필요합니다." + }, + "wecomaibot_friend_message_welcome_text": { + "description": "WeCom AI 봇 DM 환영 메시지", + "hint": "사용자가 당일 DM 세션에 진입하면 환영 메시지로 응답합니다. 비워두면 비활성화됩니다." + }, + "wecomaibot_init_respond_text": { + "description": "WeCom AI 봇 초기 응답 텍스트", + "hint": "봇이 메시지를 수신했을 때 최초 답변입니다. 비워두면 비활성화됩니다." + }, + "wecomaibot_token": { + "description": "WeCom AI 봇 토큰", + "hint": "웹훅 콜백 모드에서 인증에 사용됩니다." + }, + "wecomaibot_encoding_aes_key": { + "description": "WeCom AI 봇 EncodingAESKey", + "hint": "웹훅 콜백 모드에서 메시지 암복호화에 사용됩니다." + }, + "wecomaibot_ws_bot_id": { + "description": "롱 커넥션 BotID", + "hint": "WeCom AI 봇 롱 커넥션 모드용 BotID 자격 증명입니다." + }, + "wecomaibot_ws_secret": { + "description": "롱 커넥션 Secret", + "hint": "WeCom AI 봇 롱 커넥션 모드용 Secret 자격 증명입니다." + }, + "wecomaibot_ws_url": { + "description": "롱 커넥션 WebSocket URL", + "hint": "기본값은 wss://openws.work.weixin.qq.com이며 대개 변경할 필요가 없습니다." + }, + "wecomaibot_heartbeat_interval": { + "description": "롱 커넥션 하트비트 간격", + "hint": "롱 커넥션 모드에서의 하트비트 간격(초)입니다. 30초를 권장합니다." + }, + "wpp_active_message_poll": { + "description": "능동 메시지 폴링 활성화", + "hint": "WeChat 메시지가 AstrBot에 제때 동기화되지 않을 때만 활성화하세요. 기본값은 비활성화입니다." + }, + "wpp_active_message_poll_interval": { + "description": "능동 메시지 폴링 간격", + "hint": "간격(초)이며 기본값은 3입니다. 60을 넘기면 오래된 메시지로 간주될 수 있습니다." + }, + "ws_reverse_host": { + "description": "역방향 WebSocket 호스트", + "hint": "AstrBot이 서버 역할을 합니다." + }, + "ws_reverse_port": { + "description": "역방향 WebSocket 포트" + }, + "ws_reverse_token": { + "description": "역방향 WebSocket 토큰", + "hint": "역방향 WebSocket 토큰입니다. 설정하지 않으면 토큰 검증이 비활성화됩니다." + }, + "msg_push_webhook_url": { + "description": "WeCom 메시지 푸시 웹훅 URL", + "hint": "능동 메시지 푸시에 사용됩니다. 더 나은 메시지 전송 경험을 위해 이 값을 설정하는 것을 강력히 권장합니다." + }, + "only_use_webhook_url_to_send": { + "description": "웹훅으로만 답변 전송", + "hint": "활성화하면 모든 WeCom AI 봇 답변이 msg_push_webhook_url을 통해 전송됩니다. 메시지 푸시 웹훅은 이미지, 파일 등 더 많은 메시지 유형을 지원합니다. 타이핑 효과가 필요 없다면 이 옵션을 사용하는 것을 강력히 권장합니다. " + }, + "weixin_oc_base_url": { + "description": "API 기본 URL", + "hint": "기본값: https://ilinkai.weixin.qq.com" + }, + "weixin_oc_bot_type": { + "description": "bot_type(QR 로그인 파라미터)", + "hint": "기본값: 3" + }, + "weixin_oc_qr_poll_interval": { + "description": "QR 상태 폴링 간격(초)", + "hint": "QR 코드 상태를 폴링하는 간격(초)입니다." + }, + "weixin_oc_long_poll_timeout_ms": { + "description": "getUpdates 롱 폴 제한 시간(ms)", + "hint": "메시지 폴링용 제한 시간 파라미터입니다." + }, + "weixin_oc_api_timeout_ms": { + "description": "HTTP 제한 시간(ms)", + "hint": "일반 API 요청 제한 시간입니다." + }, + "weixin_oc_token": { + "description": "로그인 후 토큰(선택)", + "hint": "QR 로그인 후 자동으로 기록되며, 고급 시나리오에서는 수동으로 입력할 수 있습니다." + }, + "kook_bot_token": { + "description": "봇 토큰", + "type": "string", + "hint": "필수 항목입니다. KOOK 개발자 플랫폼에서 발급받은 봇 토큰입니다." + }, + "kook_reconnect_delay": { + "description": "재연결 지연", + "type": "int", + "hint": "재연결 대기 시간(초)이며, 지수 백오프 전략을 사용합니다." + }, + "kook_max_reconnect_delay": { + "description": "최대 재연결 지연", + "type": "int", + "hint": "재연결 지연의 최대값(초)입니다." + }, + "kook_max_retry_delay": { + "description": "최대 재시도 지연", + "type": "int", + "hint": "재시도 최대 지연 시간(초)입니다." + }, + "kook_heartbeat_interval": { + "description": "하트비트 간격", + "type": "int", + "hint": "하트비트 감지 간격(초)입니다." + }, + "kook_heartbeat_timeout": { + "description": "하트비트 제한 시간", + "type": "int", + "hint": "하트비트 감지 제한 시간(초)입니다." + }, + "kook_max_heartbeat_failures": { + "description": "최대 하트비트 실패 횟수", + "type": "int", + "hint": "허용되는 최대 하트비트 실패 횟수이며, 초과 시 연결이 종료됩니다." + }, + "kook_max_consecutive_failures": { + "description": "최대 연속 실패 횟수", + "type": "int", + "hint": "허용되는 최대 연속 실패 횟수이며, 초과 시 재시도가 중단됩니다." + } + }, + "general": { + "description": "일반", + "admins_id": { + "description": "관리자 ID" + }, + "platform_settings": { + "unique_session": { + "description": "세션 격리", + "hint": "활성화하면 그룹 구성원이 독립된 컨텍스트를 가집니다." + }, + "friend_message_needs_wake_prefix": { + "description": "개인 메시지에 웨이크 워드 필요" + }, + "reply_prefix": { + "description": "답변 텍스트 접두사" + }, + "reply_with_mention": { + "description": "답변 시 발신자 멘션" + }, + "reply_with_quote": { + "description": "답변 시 발신자 메시지 인용" + }, + "forward_threshold": { + "description": "전달 메시지 글자 수 임계값" + }, + "empty_mention_waiting": { + "description": "멘션만 있는 메시지에 대기 트리거" + } + }, + "wake_prefix": { + "description": "웨이크 워드" + }, + "disable_builtin_commands": { + "description": "내장 명령어 비활성화", + "hint": "help, sid, new 등 AstrBot의 모든 내장 명령어를 비활성화합니다." + } + }, + "whitelist": { + "description": "화이트리스트", + "platform_settings": { + "enable_id_white_list": { + "description": "화이트리스트 활성화", + "hint": "활성화하면 화이트리스트에 있는 세션에만 응답합니다. 화이트리스트가 비어 있으면 화이트리스트가 비활성화되어 모든 ID가 허용됩니다." + }, + "id_whitelist": { + "description": "화이트리스트 ID 목록", + "hint": "/sid 명령어로 ID를 확인하세요. 목록이 비어 있으면 화이트리스트가 비활성화됨을 의미합니다(모든 ID가 화이트리스트에 포함됨)." + }, + "id_whitelist_log": { + "description": "로그 출력", + "hint": "활성화하면 메시지가 화이트리스트를 통과하지 못했을 때 INFO 레벨 로그를 출력합니다." + }, + "wl_ignore_admin_on_group": { + "description": "관리자 그룹 메시지는 ID 화이트리스트를 우회" + }, + "wl_ignore_admin_on_friend": { + "description": "관리자 개인 메시지는 ID 화이트리스트를 우회" + } + } + }, + "rate_limit": { + "description": "속도 제한", + "platform_settings": { + "rate_limit": { + "time": { + "description": "메시지 속도 제한 시간(초)" + }, + "count": { + "description": "메시지 속도 제한 횟수" + }, + "strategy": { + "description": "속도 제한 전략" + } + } + } + }, + "content_safety": { + "description": "콘텐츠 안전", + "content_safety": { + "also_use_in_response": { + "description": "모델 응답 콘텐츠도 검사" + }, + "baidu_aip": { + "enable": { + "description": "Baidu 콘텐츠 안전 검열 사용", + "hint": "baidu-aip 라이브러리를 수동으로 설치해야 합니다." + }, + "app_id": { + "description": "App ID" + }, + "api_key": { + "description": "API 키" + }, + "secret_key": { + "description": "Secret Key" + } + }, + "internal_keywords": { + "enable": { + "description": "키워드 검사" + }, + "extra_keywords": { + "description": "추가 키워드", + "hint": "추가 키워드 차단 목록이며, 정규식을 지원합니다." + } + } + } + }, + "t2i": { + "description": "텍스트-이미지 변환", + "t2i": { + "description": "텍스트-이미지 변환 출력" + }, + "t2i_word_threshold": { + "description": "텍스트-이미지 변환 글자 수 임계값" + } + }, + "others": { + "description": "기타 설정", + "platform_settings": { + "ignore_bot_self_message": { + "description": "봇 자신의 메시지 무시" + }, + "ignore_at_all": { + "description": "전체 멘션(@All) 이벤트 무시" + }, + "no_permission_reply": { + "description": "권한이 부족한 사용자에게 응답" + } + }, + "platform_specific": { + "lark": { + "pre_ack_emoji": { + "enable": { + "description": "[Lark] 사전 확인 이모지 활성화" + }, + "emojis": { + "description": "이모지 목록(Lark 이모지 열거형 이름)", + "hint": "이모지 열거형 이름 참고: [https://open.feishu.cn/document/server-docs/im-v1/message-reaction/emojis-introduce](https://open.feishu.cn/document/server-docs/im-v1/message-reaction/emojis-introduce)" + } + } + }, + "telegram": { + "pre_ack_emoji": { + "enable": { + "description": "[Telegram] 사전 확인 이모지 활성화" + }, + "emojis": { + "description": "이모지 목록(유니코드)", + "hint": "Telegram은 고정된 반응 세트만 지원합니다. 참고: [https://gist.github.com/Soulter/3f22c8e5f9c7e152e967e8bc28c97fc9](https://gist.github.com/Soulter/3f22c8e5f9c7e152e967e8bc28c97fc9)" + } + } + }, + "discord": { + "pre_ack_emoji": { + "enable": { + "description": "[Discord] 사전 확인 이모지 활성화" + }, + "emojis": { + "description": "이모지 목록(유니코드 또는 커스텀 이모지 이름)", + "hint": "유니코드 이모지 기호를 입력하세요(예: 👍, 🤔, ⏳)" + } + } + } + } + } + }, + "plugin_group": { + "name": "플러그인", + "plugin": { + "description": "플러그인", + "plugin_set": { + "description": "사용 가능한 플러그인", + "hint": "비활성화되지 않은 모든 플러그인은 기본적으로 활성화됩니다. 플러그인 페이지에서 비활성화된 플러그인은 여기서 선택해도 적용되지 않습니다." + } + } + }, + "ext_group": { + "name": "확장", + "segmented_reply": { + "description": "분할 답변", + "platform_settings": { + "segmented_reply": { + "enable": { + "description": "분할 답변 활성화" + }, + "only_llm_result": { + "description": "LLM 결과만 분할" + }, + "interval_method": { + "description": "간격 방식", + "hint": "random은 무작위 지연을 사용합니다. log는 메시지 길이에 따라 지연을 계산합니다: $y=log_{log\\_base}(x)$, 여기서 x는 단어 수, y는 초 단위입니다." + }, + "interval": { + "description": "무작위 간격 시간", + "hint": "형식: 최소값,최대값(예: 1.5,3.5)" + }, + "log_base": { + "description": "로그 밑", + "hint": "로그 간격의 밑이며, 기본값은 2.6입니다. 값 범위: 1.0~10.0." + }, + "words_count_threshold": { + "description": "분할 답변 글자 수 임계값", + "hint": "분할 답변 글자 수 임계값입니다. 이 글자 수보다 적은 메시지만 분할되며, 이보다 많은 메시지는 분할 없이 바로 전송됩니다." + }, + "split_mode": { + "description": "분할 방식", + "hint": "메시지를 분할하는 데 사용됩니다. 기본적으로 마침표, 물음표 등 구두점으로 구분됩니다. 예를 들어 `[。?!]`을 입력하면 모든 마침표, 물음표, 느낌표를 제거합니다. re.findall(r'', text)", + "labels": [ + "정규식", + "단어 목록" + ] + }, + "regex": { + "description": "분할 정규 표현식", + "hint": "분할 지점을 식별하는 정규 표현식입니다. 구분자와 일치하는 패턴을 우선 사용하세요." + }, + "split_words": { + "description": "분할 단어 목록", + "hint": "목록에 있는 단어가 감지되면 분할합니다" + }, + "content_cleanup_rule": { + "description": "콘텐츠 필터링 정규 표현식", + "hint": "분할된 콘텐츠에서 지정된 내용을 제거합니다. 예를 들어 `[。?!]`은 모든 마침표, 물음표, 느낌표를 제거합니다." + } + } + } + }, + "ltm": { + "description": "그룹 채팅 컨텍스트 인식(구 채팅 메모리 강화)", + "provider_ltm_settings": { + "group_icl_enable": { + "description": "그룹 채팅 컨텍스트 인식 활성화" + }, + "group_message_max_cnt": { + "description": "최대 메시지 수" + }, + "image_caption": { + "description": "이미지 자동 이해", + "hint": "그룹 채팅 이미지 캡션 모델 설정이 필요합니다." + }, + "image_caption_provider_id": { + "description": "그룹 채팅 이미지 캡션 모델", + "hint": "그룹 채팅 컨텍스트 인식의 이미지 이해에 사용되며, 기본 이미지 캡션 모델과 별도로 구성됩니다." + }, + "active_reply": { + "enable": { + "description": "능동 답변" + }, + "method": { + "description": "능동 답변 방식" + }, + "possibility_reply": { + "description": "답변 확률", + "hint": "0.0~1.0 사이의 값" + }, + "whitelist": { + "description": "능동 답변 화이트리스트", + "hint": "비어 있으면 화이트리스트 필터링이 비활성화됩니다. /sid 명령어로 ID를 확인하세요." + } + } + } + } + }, + "system_group": { + "name": "시스템", + "system": { + "description": "시스템 설정", + "t2i_strategy": { + "description": "텍스트-이미지 변환 전략", + "hint": "텍스트-이미지 변환 전략입니다. `remote`는 원격 HTML 기반 렌더링 서비스를 사용하고, `local`은 PIL을 사용해 로컬에서 렌더링합니다. local을 사용할 경우, 폰트를 커스터마이즈하려면 data/ 디렉터리에 'font.ttf'라는 이름의 TTF 폰트를 넣으세요." + }, + "t2i_endpoint": { + "description": "텍스트-이미지 변환 서비스 API 엔드포인트", + "hint": "비워두면 AstrBot API 서비스를 사용합니다" + }, + "t2i_template": { + "description": "텍스트-이미지 변환 커스텀 템플릿", + "hint": "활성화하면 텍스트-이미지 변환 렌더링용 HTML 템플릿을 커스터마이즈할 수 있습니다." + }, + "t2i_active_template": { + "description": "현재 적용 중인 텍스트-이미지 변환 렌더링 템플릿", + "hint": "이 값은 텍스트-이미지 변환 템플릿 관리 페이지에서 관리됩니다." + }, + "log_level": { + "description": "콘솔 로그 레벨", + "hint": "콘솔 출력용 로그 레벨입니다." + }, + "log_file_enable": { + "description": "파일 로깅 활성화", + "hint": "콘솔 외에 파일에도 로그를 기록합니다." + }, + "log_file_path": { + "description": "로그 파일 경로", + "hint": "상대 경로는 데이터 디렉터리 기준으로 해석됩니다(예: logs/astrbot.log). 절대 경로도 지원합니다." + }, + "log_file_max_mb": { + "description": "로그 파일 최대 크기(MB)", + "hint": "이 크기를 초과하면 순환(rotate)됩니다. 기본값은 20MB입니다." + }, + "temp_dir_max_size": { + "description": "임시 디렉터리 크기 제한(MB)", + "hint": "data/temp의 전체 크기를 MB 단위로 제한합니다. 시스템은 10분마다 확인하며, 초과 시 가장 오래된 파일부터 삭제하여 현재 크기의 약 30%를 확보합니다." + }, + "trace_log_enable": { + "description": "트레이스 파일 로깅 활성화", + "hint": "트레이스 이벤트를 별도 파일에 기록합니다(콘솔 출력은 변경되지 않습니다)." + }, + "trace_log_path": { + "description": "트레이스 로그 파일 경로", + "hint": "상대 경로는 데이터 디렉터리 기준으로 해석됩니다(예: logs/astrbot.trace.log). 절대 경로도 지원합니다." + }, + "trace_log_max_mb": { + "description": "트레이스 로그 최대 크기(MB)", + "hint": "이 크기를 초과하면 순환(rotate)됩니다. 기본값은 20MB입니다." + }, + "pip_install_arg": { + "description": "추가 pip 설치 인자", + "hint": "플러그인 의존성 설치 시 Python의 pip 도구가 사용됩니다. 여기에 `--break-system-package`와 같은 추가 인자를 제공할 수 있습니다." + }, + "pypi_index_url": { + "description": "PyPI 저장소 URL", + "hint": "Python 의존성 설치에 사용되는 PyPI 저장소 URL입니다. 기본값은 [https://mirrors.aliyun.com/pypi/simple/](https://mirrors.aliyun.com/pypi/simple/)" + }, + "callback_api_base": { + "description": "외부에서 접근 가능한 콜백 API 주소", + "hint": "외부 서비스는 AstrBot이 생성한 콜백 링크(예: 파일 다운로드 링크)를 통해 AstrBot 백엔드에 접근할 수 있습니다. AstrBot은 배포 환경에서 외부에서 접근 가능한 호스트 주소를 자동으로 판단할 수 없으므로, 외부 서비스가 AstrBot 주소에 접근하는 방법을 명시적으로 지정하려면 이 구성 항목이 필요합니다. 예: [http://localhost:6185](http://localhost:6185), [https://example.com](https://example.com) 등." + }, + "disable_metrics": { + "description": "익명 사용 통계 비활성화", + "hint": "비활성화하면 AstrBot이 익명 사용 통계를 업로드하지 않습니다." + }, + "dashboard": { + "trust_proxy_headers": { + "description": "클라이언트 IP에 대해 프록시 헤더 신뢰", + "hint": "비활성화하면 X-Forwarded-For/X-Real-IP를 무시하고 연결 주소만 사용합니다." + }, + "auth_rate_limit": { + "enable": { + "description": "로그인 속도 제한 활성화", + "hint": "비활성화하면 인증 엔드포인트(로그인, TOTP 등)에 속도 제한이 적용되지 않습니다." + }, + "average_interval": { + "description": "엔드포인트 속도 제한 평균 간격(초)", + "hint": "인증 요청 간 최소 평균 간격입니다. 예를 들어 1.0은 초당 최대 1회 요청을 의미합니다." + }, + "max_burst": { + "description": "엔드포인트 속도 제한 최대 버스트", + "hint": "연속으로 허용되는 최대 버스트 요청 수입니다. 예를 들어 3이면 짧은 시간에 최대 3회 요청을 허용합니다." + } + }, + "ssl": { + "enable": { + "description": "WebUI HTTPS 활성화", + "hint": "활성화하면 WebUI가 HTTPS로 직접 서비스됩니다." + }, + "cert_file": { + "description": "SSL 인증서 파일 경로", + "hint": "인증서 파일 경로(PEM)입니다. 절대 경로와 상대 경로(현재 작업 디렉터리 기준)를 모두 지원합니다." + }, + "key_file": { + "description": "SSL 개인 키 파일 경로", + "hint": "개인 키 파일 경로(PEM)입니다. 절대 경로와 상대 경로(현재 작업 디렉터리 기준)를 모두 지원합니다." + }, + "ca_certs": { + "description": "SSL CA 인증서 파일 경로", + "hint": "선택 항목입니다. CA 인증서 파일 경로입니다." + } + }, + "totp": { + "enable": { + "description": "WebUI TOTP 활성화", + "hint": "활성화하면 대시보드 로그인 시 TOTP 코드가 필요합니다." + }, + "manage": "관리", + "configuration": "TOTP", + "statusPending": "설정 필요", + "statusEnabled": "활성화됨", + "setupRequiredHint": "TOTP가 활성화되어 있지만 아직 설정되지 않았습니다. 관리를 클릭하여 설정을 완료하세요.", + "setupTitle": "TOTP 설정", + "setupSubtitle": "인증 앱에서 이 QR 코드를 스캔한 후 인증 코드를 입력하세요.", + "setupConfirm": "확인하고 계속", + "activeSubtitle": "이 QR 코드 또는 시크릿을 사용해 다른 인증 기기를 추가하세요.", + "rotateTitle": "TOTP 시크릿 교체", + "rotateSubtitle": "새 시크릿을 생성한 후, 인증 앱에서 코드를 입력하여 교체를 확인하세요.", + "rotate": "교체", + "rotateRecovery": "복구 코드 교체", + "rotateConfirm": "교체 확인", + "rotateCancel": "취소", + "rotateCode": "인증 코드", + "rotateCodeHint": "인증 앱의 코드를 입력하여 새 키를 확인하세요.", + "rotateError": "잘못된 코드입니다. 다시 시도하세요.", + "recoveryTitle": "복구 코드", + "recoverySubtitle": "이 복구 코드는 한 번만 표시됩니다. 계속하기 전에 저장하세요.", + "recoveryWarning": "분실 시 일반적인 방법으로는 계정 접근을 복구할 수 없습니다.", + "recoveryAcknowledge": "복구 코드를 저장했습니다", + "recoveryClose": "완료", + "disableTitle": "TOTP 비활성화", + "disableSubtitle": "2단계 인증을 비활성화하려면 인증 코드를 입력하세요.", + "disableRecoverySubtitle": "2단계 인증을 비활성화하려면 복구 코드를 입력하세요.", + "disableCode": "인증 코드", + "disableRecoveryCode": "복구 코드", + "disableConfirm": "비활성화", + "disableCancel": "취소", + "disableError": "인증에 실패했습니다. 다시 시도하세요.", + "disableUseRecovery": "TOTP를 사용할 수 없나요?", + "disableUseCode": "인증 코드 사용", + "configSaveTitle": "2단계 인증", + "configSaveSubtitle": "보호된 구성을 변경하려면 인증 코드를 입력하세요.", + "configSaveRotationHint": "TOTP 키를 교체할 때는 기존 코드와 새 코드 모두 인증에 사용할 수 있습니다(교체 작업당 한 번 허용).", + "configSaveCode": "인증 코드", + "configSaveConfirm": "계속", + "configSaveCancel": "취소", + "configSaveError": "인증에 실패했습니다. 다시 시도하세요." + } + }, + "timezone": { + "description": "표준시간대", + "hint": "표준시간대 설정입니다. Asia/Shanghai와 같은 IANA 표준시간대 이름을 입력하세요. 비워두면 시스템 기본 표준시간대를 사용합니다. 전체 표준시간대 목록: [https://data.iana.org/time-zones/tzdb-2021a/zone1970.tab](https://data.iana.org/time-zones/tzdb-2021a/zone1970.tab)" + }, + "http_proxy": { + "description": "HTTP 프록시", + "hint": "활성화하면 환경 변수를 추가하여 프록시가 설정됩니다. 형식: `http://ip:port`" + }, + "no_proxy": { + "description": "직접 연결 주소 목록" + } + } + }, + "provider_group": { + "provider": { + "genie_onnx_model_dir": { + "description": "ONNX 모델 디렉터리", + "hint": "ONNX 모델 파일이 있는 디렉터리 경로입니다" + }, + "genie_language": { + "description": "언어" + }, + "xai_native_search": { + "description": "네이티브 검색 활성화", + "hint": "활성화하면 웹 조회에 xAI Chat Completions의 네이티브 Live Search를 사용합니다(사용량에 따라 과금). xAI 공급자에만 적용됩니다." + }, + "rerank_api_base": { + "description": "재순위 모델 API 기본 URL", + "hint": "전체 요청 URL은 기본 URL과 경로 접미사(기본값 /v1/rerank)를 결합하여 구성됩니다." + }, + "rerank_api_suffix": { + "description": "API URL 경로 접미사", + "hint": "base_url 뒤에 붙는 경로입니다(예: /v1/rerank). 비워두면 자동 추가가 비활성화됩니다." + }, + "rerank_api_key": { + "description": "API 키", + "hint": "API 키가 필요 없으면 비워두세요." + }, + "rerank_model": { + "description": "재순위 모델 이름" + }, + "return_documents": { + "description": "재순위 결과에 원본 문서 반환", + "hint": "네트워크 오버헤드를 줄이기 위해 기본값은 false입니다." + }, + "instruct": { + "description": "커스텀 재순위 작업 설명", + "hint": "qwen3-rerank 모델에서만 적용됩니다. 영어로 작성하는 것을 권장합니다." + }, + "nvidia_rerank_api_base": { + "description": "API 기본 URL" + }, + "nvidia_rerank_api_key": { + "description": "API 키" + }, + "nvidia_rerank_model": { + "description": "재순위 모델 이름", + "hint": "모델 이름은 NVIDIA 문서를 참고하세요." + }, + "nvidia_rerank_model_endpoint": { + "description": "커스텀 모델 엔드포인트", + "hint": "커스텀 URL 접미사 엔드포인트이며, 기본값은 /reranking입니다." + }, + "nvidia_rerank_truncate": { + "description": "텍스트 자르기 전략", + "hint": "입력 텍스트가 너무 길 때 모델의 최대 컨텍스트 길이에 맞게 자를지 여부입니다." + }, + "launch_model_if_not_running": { + "description": "실행 중이 아니면 모델 자동 시작", + "hint": "Xinference에서 모델이 실행 중이 아니면 자동으로 시작을 시도합니다. 프로덕션 환경에서는 비활성화를 권장합니다." + }, + "modalities": { + "description": "모델 기능", + "hint": "모델이 지원하는 모달리티입니다. 모델이 이미지를 지원하지 않으면 이미지 선택을 해제하세요.", + "labels": [ + "텍스트", + "이미지", + "오디오", + "도구 사용" + ] + }, + "custom_headers": { + "description": "커스텀 요청 헤더", + "hint": "여기에 추가한 키/값 쌍은 OpenAI SDK의 default_headers에 병합되어 커스텀 HTTP 헤더로 사용됩니다. 값은 반드시 문자열이어야 합니다." + }, + "ollama_disable_thinking": { + "description": "사고 모드 비활성화", + "hint": "Ollama의 사고(thinking) 모드를 끕니다." + }, + "custom_extra_body": { + "description": "커스텀 요청 바디 파라미터", + "hint": "temperature, top_p, max_tokens 등 요청에 추가 파라미터를 더합니다.", + "template_schema": { + "temperature": { + "description": "온도", + "hint": "무작위성을 제어하며 보통 0~2 사이입니다. 값이 높을수록 더 무작위적입니다.", + "name": "온도" + }, + "top_p": { + "description": "Top-p 샘플링", + "hint": "뉴클리어스 샘플링 파라미터로 보통 0~1 사이입니다. 고려할 확률 질량을 제어합니다.", + "name": "Top-p" + }, + "max_tokens": { + "description": "최대 토큰 수", + "hint": "생성할 최대 토큰 수입니다.", + "name": "최대 토큰 수" + } + } + }, + "gpt_weights_path": { + "description": "GPT 모델 파일 경로", + "hint": ".ckpt 파일입니다. 따옴표 없이 절대 경로를 사용하세요. 비워두면 GPT_SoVITS 내장 SoVITS 모델을 사용합니다(GPT_SoVITS에서 기본값을 변경하는 것을 권장합니다)." + }, + "sovits_weights_path": { + "description": "SoVITS 모델 파일 경로", + "hint": ".pth 파일입니다. 따옴표 없이 절대 경로를 사용하세요. 비워두면 GPT_SoVITS 내장 SoVITS 모델을 사용합니다(GPT_SoVITS에서 기본값을 변경하는 것을 권장합니다)." + }, + "gsv_default_parms": { + "description": "GPT_SoVITS 기본 파라미터", + "hint": "참조 오디오 파일 경로와 텍스트는 필수이며, 나머지 파라미터는 선택 사항입니다.", + "gsv_ref_audio_path": { + "description": "참조 오디오 파일 경로", + "hint": "필수 항목입니다! 따옴표 없이 절대 경로를 사용하세요." + }, + "gsv_prompt_text": { + "description": "참조 오디오 텍스트", + "hint": "필수 항목입니다! 참조 오디오의 대사를 입력하세요." + }, + "gsv_prompt_lang": { + "description": "참조 오디오 텍스트 언어", + "hint": "참조 오디오 텍스트의 언어이며, 기본값은 중국어입니다." + }, + "gsv_aux_ref_audio_paths": { + "description": "보조 참조 오디오 파일 경로", + "hint": "보조 참조 오디오 파일이며 선택 사항입니다." + }, + "gsv_text_lang": { + "description": "텍스트 언어", + "hint": "기본값은 중국어입니다." + }, + "gsv_top_k": { + "description": "음성 다양성", + "hint": "" + }, + "gsv_top_p": { + "description": "뉴클리어스 샘플링 임계값", + "hint": "" + }, + "gsv_temperature": { + "description": "음성 무작위성", + "hint": "" + }, + "gsv_text_split_method": { + "description": "텍스트 분할 방식", + "hint": "옵션: `cut0` 분할 없음, `cut1` 4문장마다 분할, `cut2` 50자마다 분할, `cut3` 중국어 마침표로 분할, `cut4` 영어 마침표로 분할, `cut5` 구두점으로 분할." + }, + "gsv_batch_size": { + "description": "배치 크기", + "hint": "" + }, + "gsv_batch_threshold": { + "description": "배치 임계값", + "hint": "" + }, + "gsv_split_bucket": { + "description": "병렬 처리를 위해 텍스트를 버킷으로 분할", + "hint": "" + }, + "gsv_speed_factor": { + "description": "음성 재생 속도", + "hint": "1이 원래 속도입니다." + }, + "gsv_fragment_interval": { + "description": "음성 조각 간 간격", + "hint": "" + }, + "gsv_streaming_mode": { + "description": "스트리밍 모드 활성화", + "hint": "" + }, + "gsv_seed": { + "description": "무작위 시드", + "hint": "재현 가능한 결과를 위한 값입니다." + }, + "gsv_parallel_infer": { + "description": "병렬 추론 실행", + "hint": "" + }, + "gsv_repetition_penalty": { + "description": "반복 패널티", + "hint": "" + }, + "gsv_media_type": { + "description": "출력 미디어 유형", + "hint": "권장: wav" + } + }, + "embedding_dimensions": { + "description": "임베딩 차원", + "hint": "임베딩 벡터의 차원 수입니다. 모델별로 조정이 필요할 수 있으니 모델 문서를 참고하세요. 값이 정확하지 않으면 벡터 데이터베이스가 동작하지 않습니다." + }, + "embedding_model": { + "description": "임베딩 모델", + "hint": "임베딩 모델 이름입니다." + }, + "embedding_api_key": { + "description": "API 키" + }, + "embedding_api_base": { + "description": "API 기본 URL" + }, + "openai_embedding": { + "hint": "테스트가 실패하면 일부 OpenAI API 버전에서는 끝에 /v1을 추가해 보세요." + }, + "gemini_embedding": { + "hint": "Gemini Embedding은 /v1beta를 수동으로 추가할 필요가 없습니다." + }, + "volcengine_cluster": { + "description": "Volcengine 클러스터", + "hint": "음성 복제 모델의 경우 volcano_icl 또는 volcano_icl_concurr를 선택하세요. 기본값은 volcano_tts입니다." + }, + "volcengine_voice_type": { + "description": "Volcengine 음성", + "hint": "음성 ID(Voice_type)를 입력하세요." + }, + "volcengine_speed_ratio": { + "description": "말하기 속도", + "hint": "말하기 속도이며 범위는 0.2~3.0, 기본값은 1.0입니다." + }, + "volcengine_volume_ratio": { + "description": "음량", + "hint": "음량이며 범위는 0.0~2.0, 기본값은 1.0입니다." + }, + "azure_tts_voice": { + "description": "음성 스타일", + "hint": "API 음성 이름" + }, + "azure_tts_style": { + "description": "스타일", + "hint": "음성별 말하기 스타일입니다. 기쁨, 공감, 차분함 등의 감정을 표현할 수 있습니다." + }, + "azure_tts_role": { + "description": "역할(선택)", + "hint": "말하기 역할극입니다. 음성 이름을 바꾸지 않고도 다양한 나이와 성별을 흉내 낼 수 있습니다. 예를 들어 남성 음성이 음높이를 올려 여성 음성을 흉내 낼 수 있지만 음성 이름 자체는 바뀌지 않습니다. 역할이 없거나 지원되지 않으면 이 속성은 무시됩니다." + }, + "azure_tts_rate": { + "description": "말하기 속도", + "hint": "말하기 속도를 제어합니다. 단어 또는 문장 단위로 적용할 수 있습니다. 속도는 원본 오디오의 0.5배~2배 사이여야 합니다." + }, + "azure_tts_volume": { + "description": "말하기 음량", + "hint": "음량 수준을 제어합니다. 문장 단위로 변경을 적용할 수 있습니다. 0.0~100.0(조용함~큼, 예: 75)을 사용하세요. 기본값은 100.0입니다." + }, + "azure_tts_region": { + "description": "API 지역", + "hint": "Azure TTS가 데이터를 처리하는 지역입니다. https://learn.microsoft.com/zh-cn/azure/ai-services/speech-service/regions 참고" + }, + "azure_tts_subscription_key": { + "description": "서비스 구독 키", + "hint": "Azure TTS 구독 키입니다(토큰 아님)." + }, + "dashscope_tts_voice": { + "description": "음성" + }, + "gm_resp_image_modal": { + "description": "이미지 모달리티 활성화", + "hint": "활성화하면 응답에 이미지가 포함될 수 있습니다. 모델 지원이 필요하며, 그렇지 않으면 오류가 발생합니다. 지원 모델은 Google Gemini 웹사이트를 참고하세요. 팁: 이미지 생성이 필요하다면 더 나은 결과를 위해 `멤버 인식 사용` 설정을 비활성화하세요." + }, + "gm_native_search": { + "description": "네이티브 검색 활성화", + "hint": "활성화하면 모든 함수 도구가 비활성화됩니다. 무료 할당량 제한은 공식 문서를 확인하세요." + }, + "gm_native_coderunner": { + "description": "네이티브 코드 실행기 활성화", + "hint": "활성화하면 모든 함수 도구가 비활성화됩니다." + }, + "gm_url_context": { + "description": "URL 컨텍스트 활성화", + "hint": "활성화하면 모든 함수 도구가 비활성화됩니다." + }, + "gm_safety_settings": { + "description": "안전 필터", + "hint": "모델 입력에 대한 안전 필터링 수준을 설정합니다. 수준: NONE(차단 안 함), HIGH(고위험 차단), MEDIUM_AND_ABOVE(중위험 이상 차단), LOW_AND_ABOVE(저위험 이상 차단). Gemini API 문서를 참고하세요.", + "harassment": { + "description": "괴롭힘", + "hint": "부정적이거나 유해한 댓글" + }, + "hate_speech": { + "description": "혐오 발언", + "hint": "무례하거나, 무시하거나, 비속한 콘텐츠" + }, + "sexually_explicit": { + "description": "노골적인 성적 콘텐츠", + "hint": "성행위나 기타 외설적인 콘텐츠에 대한 언급" + }, + "dangerous_content": { + "description": "위험한 콘텐츠", + "hint": "유해한 행동을 조장, 장려, 또는 조력하는 콘텐츠" + } + }, + "gm_thinking_config": { + "description": "사고 구성", + "budget": { + "description": "사고 예산", + "hint": "추론에 사용할 사고 토큰 수를 모델에게 안내합니다. 참고: https://ai.google.dev/gemini-api/docs/thinking#set-budget" + }, + "level": { + "description": "사고 수준", + "hint": "Gemini 3 이후 모델에 권장되며, 추론 동작을 제어할 수 있습니다. 참고: https://ai.google.dev/gemini-api/docs/thinking#thinking-levels" + } + }, + "anth_thinking_config": { + "description": "사고 구성", + "type": { + "description": "사고 유형", + "hint": "Opus 4.6+ / Sonnet 4.6+에는 'adaptive'로 설정하세요(권장). 비워두면 수동 예산 모드를 사용합니다. 참고: https://platform.claude.com/docs/en/build-with-claude/adaptive-thinking" + }, + "budget": { + "description": "사고 예산", + "hint": "Anthropic thinking.budget_tokens 파라미터입니다. 1024 이상이어야 합니다. type이 비어 있을 때만 사용됩니다. Opus 4.6 / Sonnet 4.6에서는 더 이상 사용되지 않습니다. 참고: https://platform.claude.com/docs/en/build-with-claude/extended-thinking" + }, + "effort": { + "description": "노력 수준", + "hint": "type이 'adaptive'일 때 사고 깊이를 제어합니다. 기본값은 'high'입니다. 'max'는 Opus 4.6 전용입니다. 참고: https://platform.claude.com/docs/en/build-with-claude/effort" + } + }, + "minimax-group-id": { + "description": "사용자 그룹", + "hint": "계정 관리 -> 기본 정보에서 확인할 수 있습니다." + }, + "minimax-langboost": { + "description": "대상 언어/방언", + "hint": "지정한 언어/방언의 인식률을 높이고 해당 시나리오에서 음성 성능을 개선합니다." + }, + "minimax-voice-speed": { + "description": "말하기 속도", + "hint": "합성 속도이며 범위는 [0.5, 2], 기본값은 1.0입니다. 값이 높을수록 빠릅니다." + }, + "minimax-voice-vol": { + "description": "음량", + "hint": "합성 음량이며 범위는 (0, 10], 기본값은 1.0입니다. 값이 높을수록 큽니다." + }, + "minimax-voice-pitch": { + "description": "음높이", + "hint": "합성 음높이이며 범위는 [-12, 12], 기본값은 0입니다." + }, + "minimax-is-timber-weight": { + "description": "혼합 음성 활성화", + "hint": "최대 4개의 음성을 커스텀 가중치로 혼합할 수 있습니다. 활성화하면 단일 음성 설정은 무시됩니다." + }, + "minimax-timber-weight": { + "description": "혼합 음성", + "hint": "혼합할 음성과 가중치입니다. 최대 4개의 음성, 가중치는 [1, 100] 범위의 정수입니다. 공식 API TTS 디버그 콘솔에서 프리셋과 템플릿을 확인하세요. JSON 문자열이어야 하며, 파싱 여부는 콘솔에서 확인하세요. 구조는 기본값과 공식 코드 미리보기를 참고하세요." + }, + "minimax-voice-id": { + "description": "단일 음성", + "hint": "단일 음성 ID입니다. 공식 문서를 참고하세요." + }, + "minimax-voice-emotion": { + "description": "감정", + "hint": "합성 음성의 감정을 제어합니다. auto로 설정하면 텍스트에 따라 감정을 자동 선택합니다." + }, + "minimax-voice-latex": { + "description": "LaTeX 수식 읽기", + "hint": "LaTeX 수식을 읽습니다. 단, 입력 텍스트는 공식 요구사항에 맞게 포맷되어야 합니다." + }, + "minimax-voice-english-normalization": { + "description": "영어 텍스트 정규화", + "hint": "숫자 읽기 성능이 향상되지만 지연 시간이 약간 늘어납니다." + }, + "rag_options": { + "description": "RAG 옵션", + "hint": "지식 베이스 검색 설정이며 선택 사항입니다. Agent 앱 유형(RAG 앱을 포함한 Agent 앱)에서만 지원됩니다. Bailian 앱의 경우 이를 활성화하면 다중 턴 대화가 비활성화됩니다.", + "pipeline_ids": { + "description": "지식 베이스 ID 목록", + "hint": "지정한 지식 베이스의 모든 문서를 검색합니다. https://bailian.console.aliyun.com/ 의 데이터 앱 -> 지식 색인에서 생성 및 ID 확인이 가능합니다." + }, + "file_ids": { + "description": "비정형 문서 ID", + "hint": "지정한 비정형 문서를 검색합니다. https://bailian.console.aliyun.com/ 의 데이터 관리에서 생성 및 ID 확인이 가능합니다." + }, + "output_reference": { + "description": "지식 베이스/문서 참조 출력", + "hint": "각 답변 끝에 참조 출처를 추가합니다. 기본값은 False입니다." + } + }, + "sensevoice_hint": { + "description": "SenseVoice 배포", + "hint": "활성화하기 전에 funasr, funasr_onnx, torchaudio, torch, modelscope, jieba를 설치하고(기본은 CPU, 약 1GB 다운로드) ffmpeg도 설치하세요. 그렇지 않으면 STT가 동작하지 않습니다." + }, + "is_emotion": { + "description": "감정 인식", + "hint": "감정 인식을 활성화합니다. happy?sad?angry?neutral?fearful?disgusted?surprised?unknown" + }, + "stt_model": { + "description": "모델 이름", + "hint": "modelscope의 모델 이름입니다. 기본값: iic/SenseVoiceSmall." + }, + "variables": { + "description": "워크플로 고정 입력 변수", + "hint": "선택 항목입니다. 고정된 워크플로 입력 변수는 워크플로 입력으로 사용됩니다. 채팅 중 /set 명령어로 변수를 동적으로 설정할 수도 있습니다. 이름이 충돌하면 동적 설정이 우선합니다." + }, + "dashscope_app_type": { + "description": "앱 유형", + "hint": "Bailian 앱 유형입니다." + }, + "timeout": { + "description": "제한 시간", + "hint": "제한 시간(초)입니다." + }, + "openai-tts-voice": { + "description": "음성", + "hint": "OpenAI TTS 음성입니다. OpenAI 기본값: 'alloy', 'echo', 'fable', 'onyx', 'nova', 'shimmer'." + }, + "elevenlabs-tts-voice-id": { + "description": "음성 ID", + "hint": "ElevenLabs 음성 ID입니다. https://elevenlabs.io/app/voice-library 에서 음성 ID를 찾아 복사하세요. 기본값 'JBFqnCBsd6RMkjVDRZzb'(George)." + }, + "elevenlabs-tts-output-format": { + "description": "출력 형식", + "hint": "오디오 출력 형식입니다(예: 'mp3_44100_128', 'mp3_22050_32', 'wav_44100', 'opus_48000_128'). Raw PCM/u-law/a-law 형식은 지원되지 않습니다. 기본값 'mp3_44100_128'." + }, + "elevenlabs-tts-stability": { + "description": "안정성", + "hint": "음성 안정성이며 범위는 [0, 1]입니다. 값이 높을수록 일관되고, 낮을수록 표현력이 풍부합니다. 비워두면 서버 기본값을 사용합니다." + }, + "elevenlabs-tts-similarity-boost": { + "description": "유사도 향상", + "hint": "출력이 원본 음성과 얼마나 비슷한지를 나타내며 범위는 [0, 1]입니다. 비워두면 서버 기본값을 사용합니다." + }, + "elevenlabs-tts-style": { + "description": "스타일 과장", + "hint": "음성의 스타일 과장 정도이며 범위는 [0, 1]입니다. 값이 높을수록 지연 시간이 늘어납니다. 비워두면 서버 기본값을 사용합니다." + }, + "elevenlabs-tts-use-speaker-boost": { + "description": "화자 부스트", + "hint": "원본 화자와의 유사도를 강화합니다. 지연 시간이 약간 늘어날 수 있습니다." + }, + "mimo-tts-voice": { + "description": "음성", + "hint": "MiMo TTS 음성 이름입니다. 지원 값에는 'mimo_default', 'default_en', 'default_zh'가 포함됩니다." + }, + "mimo-tts-format": { + "description": "출력 형식", + "hint": "MiMo TTS가 생성하는 오디오 형식입니다. 지원 값: 'wav', 'mp3', 'pcm'." + }, + "mimo-tts-style-prompt": { + "description": "스타일 프롬프트", + "hint": "합성 대상 텍스트 앞에 태그로 추가되어 속도, 감정, 캐릭터, 스타일(예: 기쁨, 빠르게, 손오공, 속삭임)을 제어합니다. 선택 항목입니다." + }, + "mimo-tts-dialect": { + "description": "방언", + "hint": "선행 태그 내부에서 스타일 프롬프트와 결합됩니다(예: 동북 관화, 사천 방언, 허난 방언, 광둥어). 선택 항목입니다." + }, + "mimo-tts-seed-text": { + "description": "시드 텍스트", + "hint": "톤과 말하기 스타일을 유도하기 위한 선택적 사용자 메시지로 전송됩니다. 합성 대상 텍스트에는 추가되지 않습니다." + }, + "fishaudio-tts-character": { + "description": "캐릭터", + "hint": "Fishaudio TTS 캐릭터입니다. 기본값은 Klee입니다. 더 많은 캐릭터: https://fish.audio/zh-CN/discovery" + }, + "fishaudio-tts-reference-id": { + "description": "reference_id", + "hint": "Fishaudio TTS 참조 모델 ID입니다(선택). 설정하면 역할 이름으로 조회하는 대신 이 모델 ID를 직접 사용합니다. 예: 626bb6d3f3364c9cbc3aa6a67300a664. 더 많은 모델: https://fish.audio/zh-CN/discovery 에서 모델 상세 페이지를 열어 모델 ID를 복사하세요." + }, + "whisper_hint": { + "description": "로컬 Whisper 배포 안내", + "hint": "활성화하기 전에 openai-whisper 라이브러리를 설치하세요(NVIDIA 사용자는 torch와 cuda 포함 약 2GB, CPU 사용자는 약 1GB 다운로드), ffmpeg도 설치하세요. 그렇지 않으면 STT가 동작하지 않습니다." + }, + "whisper_device": { + "description": "추론 장치", + "hint": "Whisper 추론 장치입니다. Apple Silicon은 mps를 사용할 수 있으며, 다른 환경에서는 cpu를 사용해야 합니다. mps를 선택했지만 사용할 수 없으면 AstrBot은 cpu로 대체합니다." + }, + "id": { + "description": "ID" + }, + "type": { + "description": "공급자 분류" + }, + "provider_type": { + "description": "공급자 기능 유형" + }, + "enable": { + "description": "활성화" + }, + "key": { + "description": "API 키" + }, + "api_base": { + "description": "API 기본 URL" + }, + "proxy": { + "description": "프록시 주소", + "hint": "HTTP/HTTPS 프록시 URL입니다(예: http://127.0.0.1:7890). 이 공급자의 API 요청에만 적용되며 Docker 내부 네트워킹에는 영향을 주지 않습니다." + }, + "model": { + "description": "모델 ID", + "hint": "모델 이름입니다(예: gpt-4o-mini, deepseek-chat)." + }, + "max_context_tokens": { + "description": "모델 컨텍스트 윈도우 크기", + "hint": "최대 컨텍스트 토큰 수입니다. 0이면 모델 메타데이터에서 자동으로 채워지며(가능한 경우), 수동으로 수정할 수도 있습니다." + }, + "dify_api_key": { + "description": "API 키", + "hint": "Dify API 키입니다. 이 항목은 필수입니다." + }, + "dify_api_base": { + "description": "API 기본 URL", + "hint": "Dify API 기본 URL입니다. 기본값: https://api.dify.ai/v1" + }, + "dify_api_type": { + "description": "Dify 앱 유형", + "hint": "Dify API 유형입니다. Dify 문서에 따르면 chat, chatflow, agent, workflow 유형이 지원됩니다." + }, + "dify_workflow_output_key": { + "description": "Dify 워크플로 출력 변수 이름", + "hint": "Dify 워크플로 출력 변수 이름입니다. 앱 유형이 workflow일 때만 사용됩니다. 기본값: astrbot_wf_output." + }, + "dify_query_input_key": { + "description": "프롬프트 입력 변수 이름", + "hint": "메시지 텍스트용 입력 변수 이름입니다. 기본값: astrbot_text_query." + }, + "coze_api_key": { + "description": "Coze API 키", + "hint": "Coze 서비스 접근용 Coze API 키입니다." + }, + "bot_id": { + "description": "봇 ID", + "hint": "Coze 플랫폼에서 봇을 생성한 뒤 발급되는 Coze 봇 ID입니다." + }, + "coze_api_base": { + "description": "API 기본 URL", + "hint": "Coze API의 기본 URL입니다. 기본값: https://api.coze.cn" + }, + "deerflow_api_base": { + "description": "API 기본 URL", + "hint": "DeerFlow API 게이트웨이 URL입니다. 기본값: http://127.0.0.1:2026" + }, + "deerflow_api_key": { + "description": "DeerFlow API 키", + "hint": "선택 항목입니다. DeerFlow 게이트웨이가 Bearer 인증으로 보호되는 경우 입력하세요." + }, + "deerflow_auth_header": { + "description": "Authorization 헤더", + "hint": "선택 항목입니다. 커스텀 Authorization 헤더 값이며, DeerFlow API 키보다 우선 적용됩니다." + }, + "deerflow_assistant_id": { + "description": "Assistant ID", + "hint": "LangGraph assistant_id이며, 기본값은 lead_agent입니다." + }, + "deerflow_model_name": { + "description": "모델 이름 재정의", + "hint": "선택 항목입니다. DeerFlow 기본 모델을 재정의합니다(런타임 컨텍스트의 model_name에 매핑됨)." + }, + "deerflow_thinking_enabled": { + "description": "사고 모드 활성화" + }, + "deerflow_plan_mode": { + "description": "계획 모드 활성화", + "hint": "DeerFlow is_plan_mode에 매핑됩니다." + }, + "deerflow_subagent_enabled": { + "description": "서브 에이전트 활성화", + "hint": "DeerFlow subagent_enabled에 매핑됩니다." + }, + "deerflow_max_concurrent_subagents": { + "description": "최대 동시 서브 에이전트 수", + "hint": "DeerFlow max_concurrent_subagents에 매핑됩니다. 서브 에이전트가 활성화된 경우에만 적용됩니다. 기본값: 3." + }, + "deerflow_recursion_limit": { + "description": "재귀 한도", + "hint": "LangGraph recursion_limit에 매핑됩니다." + }, + "auto_save_history": { + "description": "Coze가 관리하는 대화 기록", + "hint": "활성화하면 Coze가 대화 기록을 관리합니다. AstrBot이 로컬에 저장한 컨텍스트는 적용되지 않으며(읽기 전용), AstrBot 컨텍스트에 대한 작업도 반영되지 않습니다. 비활성화하면 AstrBot이 컨텍스트를 관리합니다." + } + } + }, + "help": { + "documentation": "공식 문서", + "support": "지원 그룹 참여", + "helpText": "구성이 이해되지 않나요? {documentation} 또는 {support}를 참고하세요.", + "helpPrefix": "구성이 이해되지 않나요? 참고:", + "helpMiddle": "또는", + "helpSuffix": "." + } +} diff --git a/dashboard/src/i18n/locales/ko-KR/features/config.json b/dashboard/src/i18n/locales/ko-KR/features/config.json new file mode 100644 index 0000000000..74d2c075e1 --- /dev/null +++ b/dashboard/src/i18n/locales/ko-KR/features/config.json @@ -0,0 +1,133 @@ +{ + "title": "구성", + "subtitle": "시스템 구성 및 설정 관리", + "editor": { + "visual": "비주얼 편집기", + "code": "코드 편집기", + "revertCode": "이전 코드로 되돌리기", + "applyConfig": "이 구성 적용", + "applyTip": "\"이 구성 적용\"을 클릭하면 구성이 비주얼 편집기에 반영되어 대기 상태가 됩니다. 저장하려면 우측 하단의 저장 버튼을 클릭해야 합니다." + }, + "actions": { + "save": "구성 저장", + "delete": "이 항목 삭제", + "add": "추가", + "reset": "기본값으로 재설정", + "export": "구성 내보내기", + "import": "구성 가져오기", + "validate": "구성 검증" + }, + "help": { + "documentation": "공식 문서", + "support": "도움말 그룹 참여", + "helpText": "구성이 이해되지 않으시나요? {documentation} 또는 {support}를 확인해 주세요.", + "helpPrefix": "구성이 이해되지 않으시나요? 다음을 확인해 주세요", + "helpMiddle": "또는", + "helpSuffix": "." + }, + "messages": { + "configApplied": "구성이 성공적으로 적용되었습니다. 저장하려면 우측 하단의 저장 버튼을 클릭해야 합니다.", + "configApplyError": "구성이 적용되지 않았습니다. JSON 형식 오류입니다.", + "unsavedChangesNotice": "저장되지 않은 구성 변경 사항이 있습니다. 우측 하단의 저장 버튼을 클릭해 적용하세요.", + "saveSuccess": "구성이 저장되었습니다", + "saveError": "구성 저장 실패", + "loadError": "구성 불러오기 실패", + "deleteSuccess": "삭제되었습니다", + "deleteError": "삭제 실패", + "updateSuccess": "업데이트 성공", + "updateError": "업데이트 실패" + }, + "sections": { + "general": "일반 설정", + "advanced": "고급 설정", + "security": "보안 설정", + "appearance": "화면 설정", + "notification": "알림 설정", + "moreConfig": "추가 설정" + }, + "general": { + "botName": "봇 이름", + "language": "인터페이스 언어", + "timezone": "시간대", + "autoSave": "자동 저장", + "debugMode": "디버그 모드" + }, + "advanced": { + "logLevel": "로그 수준", + "maxConnections": "최대 연결 수", + "timeout": "제한 시간", + "retryAttempts": "재시도 횟수", + "cacheSize": "캐시 크기" + }, + "security": { + "apiKey": "API 키", + "allowedHosts": "허용된 호스트", + "rateLimit": "속도 제한", + "encryption": "암호화 설정" + }, + "configSelection": { + "selectConfig": "구성 선택", + "normalConfig": "기본", + "systemConfig": "시스템" + }, + "search": { + "placeholder": "구성 항목 검색 (키/설명/힌트)", + "noResult": "일치하는 구성 항목이 없습니다" + }, + "configManagement": { + "title": "구성 관리", + "description": "AstrBot은 봇마다 별도의 구성 파일을 지원합니다. 기본적으로 `default` 구성이 사용됩니다.", + "newConfig": "새 구성", + "copyConfig": "구성 복사", + "editConfig": "구성 편집", + "manageConfigs": "구성 관리...", + "configName": "이름", + "fillConfigName": "구성 이름을 입력하세요", + "confirmDelete": "\"{name}\" 구성을 삭제하시겠습니까? 이 작업은 되돌릴 수 없습니다.", + "pleaseEnterName": "구성 이름을 입력해 주세요", + "nameExists": "이미 존재하는 구성 이름입니다. 다른 이름을 사용해 주세요.", + "createFailed": "새 구성 생성 실패", + "copyFailed": "구성 복사 실패", + "deleteFailed": "구성 삭제 실패", + "updateFailed": "구성 업데이트 실패" + }, + "buttons": { + "cancel": "취소", + "create": "생성", + "update": "업데이트" + }, + "codeEditor": { + "title": "구성 파일 편집" + }, + "fileUpload": { + "button": "파일 관리", + "dialogTitle": "업로드된 파일", + "dropzone": "새 파일 업로드", + "allowedTypes": "허용된 형식: {types}", + "empty": "업로드된 파일 없음", + "statusMissing": "파일 누락", + "statusUnconfigured": "구성에 없음", + "uploadSuccess": "파일 {count}개 업로드됨", + "uploadFailed": "업로드 실패", + "loadFailed": "파일 목록 불러오기 실패", + "fileTooLarge": "파일이 너무 큽니다 (최대 {max}MB): {name}", + "deleteSuccess": "파일이 삭제되었습니다", + "deleteFailed": "삭제 실패", + "addToConfig": "구성에 추가됨", + "fileCount": "파일: {count}개", + "done": "완료" + }, + "unsavedChangesWarning": { + "dialogTitle": "저장되지 않은 변경 사항", + "leavePage": "저장되지 않은 변경 사항이 있습니다. 나가기 전에 저장하시겠습니까?", + "switchConfig": "구성을 전환하면 저장되지 않은 변경 사항이 사라집니다. 먼저 저장하시겠습니까?", + "options": { + "save": "저장", + "saveAndSwitch": "저장 후 전환", + "discardAndSwitch": "변경 사항 취소 후 전환", + "closeCard": "팝업 창 닫기", + "confirm": "확인", + "cancel": "취소" + } + } +} diff --git a/dashboard/src/i18n/locales/ko-KR/features/console.json b/dashboard/src/i18n/locales/ko-KR/features/console.json new file mode 100644 index 0000000000..b749ecc9ea --- /dev/null +++ b/dashboard/src/i18n/locales/ko-KR/features/console.json @@ -0,0 +1,21 @@ +{ + "title": "콘솔", + "autoScroll": { + "enabled": "자동 스크롤 켜짐", + "disabled": "자동 스크롤 꺼짐" + }, + "pipInstall": { + "button": "pip 패키지 설치", + "dialogTitle": "Pip 패키지 설치", + "packageLabel": "*패키지 이름, 예: llmtuner", + "mirrorLabel": "PyPI 저장소 URL 강제 지정 (선택)", + "mirrorHint": "PyPI 저장소 URL 강제 지정 > 구성 항목 `PyPI 저장소 주소`", + "installButton": "설치", + "installSuccess": "설치에 성공했습니다.", + "installFailed": "설치에 실패했습니다.", + "requestFailed": "요청에 실패했습니다." + }, + "debugHint": { + "text": "디버그 로그는 \"구성 파일 → 시스템 → 콘솔 로그 레벨\"에서 활성화할 수 있습니다" + } +} diff --git a/dashboard/src/i18n/locales/ko-KR/features/conversation.json b/dashboard/src/i18n/locales/ko-KR/features/conversation.json new file mode 100644 index 0000000000..c0f81d7191 --- /dev/null +++ b/dashboard/src/i18n/locales/ko-KR/features/conversation.json @@ -0,0 +1,108 @@ +{ + "title": "대화 관리", + "subtitle": "사용자 대화 기록 관리 및 조회", + "filters": { + "title": "필터 조건", + "platform": "플랫폼", + "type": "유형", + "search": "검색어", + "reset": "초기화" + }, + "history": { + "title": "대화 기록", + "refresh": "새로고침" + }, + "batch": { + "deleteSelected": "선택 항목 삭제 ({count})", + "exportSelected": "선택 항목 내보내기 ({count})" + }, + "pagination": { + "itemsPerPage": "페이지당 항목 수", + "showingItems": "전체 {total}개 중 {start}-{end} 표시" + }, + "table": { + "headers": { + "title": "대화 제목", + "platform": "플랫폼", + "type": "유형", + "cid": "대화 ID", + "umo": "통합 메시지 출처", + "sessionId": "세션 ID", + "createdAt": "생성 시간", + "updatedAt": "수정 시간", + "actions": "작업" + }, + "umoDisplay": { + "parsed": "해석됨", + "raw": "UMO" + } + }, + "actions": { + "view": "보기", + "edit": "편집", + "delete": "삭제" + }, + "messageTypes": { + "group": "그룹 채팅", + "friend": "개인 채팅", + "unknown": "알 수 없음" + }, + "status": { + "noTitle": "제목 없는 대화", + "unknown": "알 수 없음", + "noData": "대화 기록이 없습니다", + "emptyContent": "대화 내용이 비어 있습니다", + "audioNotSupported": "브라우저가 오디오 재생을 지원하지 않습니다." + }, + "dialogs": { + "view": { + "title": "대화 세부 정보", + "editMode": "대화 편집", + "previewMode": "미리보기 모드", + "saveChanges": "변경 사항 저장", + "close": "닫기", + "confirmClose": "저장되지 않은 변경 사항이 있습니다. 정말 닫으시겠습니까?" + }, + "edit": { + "title": "대화 정보 편집", + "titleLabel": "대화 제목", + "titlePlaceholder": "대화 제목을 입력하세요", + "cancel": "취소", + "save": "저장" + }, + "delete": { + "title": "삭제 확인", + "message": "\"{title}\" 대화를 삭제하시겠습니까? 이 작업은 되돌릴 수 없습니다.", + "cancel": "취소", + "confirm": "삭제" + }, + "batchDelete": { + "title": "일괄 삭제 확인", + "message": "선택한 대화 {count}개를 삭제하시겠습니까? 이 작업은 되돌릴 수 없으니 신중하게 진행해 주세요!", + "andMore": "외 {count}개", + "cancel": "취소", + "confirm": "일괄 삭제", + "warning": "경고: 이 작업은 되돌릴 수 없습니다!" + } + }, + "messages": { + "fetchError": "대화 목록 조회 실패", + "saveSuccess": "저장되었습니다", + "saveError": "저장 실패", + "deleteSuccess": "삭제되었습니다", + "deleteError": "삭제 실패", + "historyError": "대화 기록 조회 실패", + "historySaveSuccess": "대화 기록이 저장되었습니다", + "historySaveError": "대화 기록 저장 실패", + "invalidJson": "잘못된 JSON 형식입니다", + "noItemSelected": "먼저 삭제할 대화를 선택해 주세요", + "batchDeleteSuccess": "대화 {count}개가 삭제되었습니다", + "batchDeleteError": "일괄 삭제 실패", + "batchDeletePartial": "삭제 완료: 성공 {deleted}개, 실패 {failed}개", + "exportSuccess": "내보내기 성공", + "exportError": "내보내기 실패", + "noItemSelectedForExport": "먼저 내보낼 대화를 선택해 주세요", + "copySuccess": "복사되었습니다", + "copyError": "복사 실패" + } +} diff --git a/dashboard/src/i18n/locales/ko-KR/features/cron.json b/dashboard/src/i18n/locales/ko-KR/features/cron.json new file mode 100644 index 0000000000..31015961aa --- /dev/null +++ b/dashboard/src/i18n/locales/ko-KR/features/cron.json @@ -0,0 +1,173 @@ +{ + "header": { + "eyebrow": "자동화", + "live": "실시간 동기화" + }, + "page": { + "title": "예약 작업 관리", + "beta": "실험적 기능", + "subtitle": "AstrBot이 예약된 시간에 깨어나 작업을 완료하고 결과를 대상 대화로 전송합니다.", + "proactive": { + "link": "지원되는 플랫폼", + "supported": "능동 전송은 아래에 구성된 플랫폼에서만 사용할 수 있습니다", + "unsupported": "활성화된 능동 메시지 플랫폼이 없습니다. 플랫폼 설정에서 켜주세요." + } + }, + "actions": { + "create": "새 작업", + "edit": "편집", + "refresh": "새로고침", + "delete": "삭제", + "cancel": "취소", + "close": "닫기", + "more": "추가 작업", + "runNow": "지금 실행", + "save": "저장", + "submit": "생성" + }, + "platformDialog": { + "title": "지원되는 플랫폼", + "description": "다음 플랫폼만 능동 메시지 전송을 지원합니다. AstrBot은 이러한 플랫폼의 대상 대화로만 예약 작업 결과를 전송할 수 있습니다." + }, + "card": { + "onceAt": "일회성 · {time}", + "runAt": "실행 시각: {time}", + "nextRun": "다음 실행: {time}", + "dailyAt": "매일 {time}", + "weeklyAt": "매주 {day} {time}", + "monthlyAt": "매월 {day}일 {time}", + "everyMinutes": "{count}분마다", + "everyHours": "{count}시간마다", + "everyDays": "{count}일마다", + "customCron": "사용자 지정 · {cron}", + "noDeliveryTarget": "전송 대상 없음" + }, + "filters": { + "search": "제목 및 내용 검색", + "umo": "전송 대상별 필터", + "noUmos": "UMO 없음", + "noDeliveryTarget": "전송 대상 없음", + "noMatches": "일치하는 예약 작업이 없습니다." + }, + "overview": { + "totalTasks": "전체 작업", + "totalTasksNote": "등록된 예약 작업", + "enabledTasks": "활성화된 작업", + "enabledTasksNote": "실행 준비된 작업", + "oneOffTasks": "일회성 작업", + "recurringTasksNote": "반복 작업 {count}개", + "proactivePlatforms": "능동 전송 플랫폼", + "proactivePlatformsNote": "결과를 능동적으로 전송할 수 있는 플랫폼" + }, + "section": { + "registered": { + "title": "작업 목록", + "subtitle": "등록된 작업, 실행 시점, 현재 상태를 확인하세요" + }, + "delivery": { + "title": "전송 상태", + "subtitle": "작업 실행 후 결과는 지원되는 플랫폼을 통해 능동적으로 전송됩니다", + "support": "능동 전송", + "available": "사용 가능", + "unavailable": "사용 불가", + "enabledPlatforms": "활성화된 플랫폼" + }, + "quickCreate": { + "title": "빠른 생성", + "runMode": "작업 모드", + "target": "대상 지정" + }, + "platforms": { + "title": "지원되는 플랫폼" + } + }, + "table": { + "title": "등록된 작업", + "subtitle": "cron 설정, 세션 대상, 마지막 실행 기록, 활성화 상태를 확인하세요", + "empty": "아직 작업이 없습니다.", + "headers": { + "name": "이름", + "type": "유형", + "cron": "Cron", + "session": "세션 ID", + "nextRun": "다음 실행", + "lastRun": "마지막 실행", + "note": "메모", + "actions": "작업" + }, + "type": { + "once": "일회성", + "recurring": "반복", + "activeAgent": "능동 에이전트", + "workflow": "워크플로", + "unknown": "{type}" + }, + "timezoneLocal": "로컬", + "notAvailable": "—" + }, + "form": { + "title": "새 작업", + "editTitle": "작업 편집", + "chatHint": "여기서 추가하지 않고, 채팅에서 AstrBot에게 예약 작업 생성을 요청할 수도 있습니다.", + "runOnce": "일회성 작업", + "name": "작업 이름 *", + "note": "작업 요구 사항 *", + "scheduleMode": "실행 시간 *", + "scheduleModes": { + "once": "일회성", + "interval": "간격", + "daily": "매일", + "weekly": "매주", + "monthly": "매월", + "cron": "사용자 지정 Cron" + }, + "intervalEvery": "간격 *", + "intervalUnit": "단위 *", + "intervalUnits": { + "minutes": "분", + "hours": "시간", + "days": "일" + }, + "dailyTime": "시간 *", + "weeklyDay": "요일 *", + "weeklyTime": "시간 *", + "monthlyDay": "일 *", + "monthlyTime": "시간 *", + "weekdays": { + "sunday": "일요일", + "monday": "월요일", + "tuesday": "화요일", + "wednesday": "수요일", + "thursday": "목요일", + "friday": "금요일", + "saturday": "토요일" + }, + "cron": "Cron 표현식 *", + "cronPlaceholder": "0 9 * * *", + "runAt": "실행 시각 *", + "session": "전송 대상", + "noUmos": "사용 가능한 세션 없음", + "timezone": "시간대 (선택 사항, 예: Asia/Seoul)", + "enabled": "활성화" + }, + "messages": { + "loadFailed": "작업 불러오기 실패", + "updateSuccess": "업데이트 성공", + "updateFailed": "업데이트 실패", + "deleteSuccess": "삭제되었습니다", + "deleteFailed": "삭제 실패", + "nameRequired": "작업 이름은 필수입니다", + "sessionRequired": "전송 대상은 필수입니다", + "noteRequired": "작업 요구 사항은 필수입니다", + "cronRequired": "Cron 표현식은 필수입니다", + "runAtRequired": "실행 시각을 선택해 주세요", + "intervalRequired": "유효한 간격을 입력해 주세요", + "dailyTimeRequired": "매일 실행 시간을 선택해 주세요", + "weeklyTimeRequired": "매주 요일과 시간을 선택해 주세요", + "monthlyTimeRequired": "매월 일자와 시간을 선택해 주세요", + "createSuccess": "생성되었습니다", + "createFailed": "생성 실패", + "runStarted": "시작되었습니다", + "runFailed": "실행 실패" + } +} diff --git a/dashboard/src/i18n/locales/ko-KR/features/dashboard.json b/dashboard/src/i18n/locales/ko-KR/features/dashboard.json new file mode 100644 index 0000000000..1f9e8331ae --- /dev/null +++ b/dashboard/src/i18n/locales/ko-KR/features/dashboard.json @@ -0,0 +1,65 @@ +{ + "title": "대시보드", + "subtitle": "실시간 모니터링 및 통계", + "lastUpdate": "마지막 업데이트", + "status": { + "loading": "로딩 중...", + "dataError": "데이터를 가져오지 못했습니다", + "noticeError": "공지사항을 가져오지 못했습니다", + "online": "온라인", + "uptime": "가동 시간", + "memoryUsage": "메모리 사용량" + }, + "stats": { + "totalMessage": { + "title": "총 메시지 수", + "subtitle": "모든 플랫폼에서 전송된 총 메시지 수" + }, + "onlinePlatform": { + "title": "플랫폼", + "subtitle": "연결된 플랫폼 수" + }, + "runningTime": { + "title": "가동 시간", + "subtitle": "시스템 가동 시간", + "format": "{hours}시간 {minutes}분 {seconds}초" + }, + "memoryUsage": { + "title": "메모리 사용량", + "subtitle": "시스템 메모리 사용 현황", + "cpuLoad": "CPU 부하", + "status": { + "good": "양호", + "normal": "보통", + "high": "높음" + } + } + }, + "charts": { + "messageTrend": { + "title": "메시지 추이 분석", + "subtitle": "시간에 따른 메시지 수 변화를 추적합니다", + "totalMessages": "총 메시지 수", + "dailyAverage": "일평균", + "growthRate": "증가율", + "timeLabel": "시간", + "messageCount": "메시지 수", + "timeRanges": { + "1day": "최근 1일", + "3days": "최근 3일", + "1week": "최근 1주", + "1month": "최근 1개월" + } + }, + "platformStat": { + "title": "플랫폼별 메시지 통계", + "subtitle": "플랫폼별 메시지 수 분포", + "total": "합계", + "noData": "사용 가능한 플랫폼 데이터가 없습니다", + "messageUnit": "건", + "platformCount": "플랫폼 수", + "mostActive": "가장 활발함", + "totalPercentage": "전체 비율" + } + } +} diff --git a/dashboard/src/i18n/locales/ko-KR/features/extension.json b/dashboard/src/i18n/locales/ko-KR/features/extension.json new file mode 100644 index 0000000000..5f1311156e --- /dev/null +++ b/dashboard/src/i18n/locales/ko-KR/features/extension.json @@ -0,0 +1,456 @@ +{ + "title": "플러그인 관리", + "subtitle": "시스템 확장 기능을 관리하고 설정합니다", + "tabs": { + "installedPlugins": "AstrBot 플러그인", + "installedMcpServers": "MCP", + "skills": "Skills", + "handlersOperation": "핸들러 관리", + "market": "AstrBot 플러그인 마켓" + }, + "titles": { + "installedAstrBotPlugins": "설치된 AstrBot 플러그인" + }, + "failedPlugins": { + "title": "플러그인 로드 실패 ({count})", + "hint": "이 플러그인들은 로드에 실패했습니다. 다시 로드하거나 바로 제거할 수 있습니다.", + "columns": { + "plugin": "플러그인", + "error": "오류" + } + }, + "search": { + "placeholder": "플러그인 검색...", + "marketPlaceholder": "마켓 플러그인 검색..." + }, + "filters": { + "all": "전체" + }, + "views": { + "card": "카드 보기", + "list": "목록 보기" + }, + "buttons": { + "showSystemPlugins": "시스템 플러그인 표시", + "hideSystemPlugins": "시스템 플러그인 숨기기", + "install": "설치", + "uninstall": "제거", + "update": "업데이트", + "reload": "다시 로드", + "enable": "사용", + "disable": "사용 안 함", + "configure": "설정", + "viewInfo": "핸들러", + "viewDocs": "문서", + "viewRepo": "저장소", + "openPages": "페이지", + "openPage": "열기", + "openWebui": "플러그인 UI 열기", + "close": "닫기", + "save": "저장", + "saveAndClose": "저장 후 닫기", + "cancel": "취소", + "next": "다음", + "actions": "작업", + "back": "뒤로", + "selectFile": "파일 선택", + "refresh": "새로고침", + "updateAll": "전체 업데이트", + "pin": "고정", + "unpin": "고정 해제", + "deleteSource": "소스 삭제", + "reshuffle": "다시 섞기" + }, + "status": { + "enabled": "사용 중", + "disabled": "사용 안 함", + "system": "시스템", + "loading": "로딩 중...", + "installed": "설치됨", + "unknown": "알 수 없음", + "unsupported": "지원 안 함" + }, + "tooltips": { + "enable": "클릭하여 사용", + "disable": "클릭하여 사용 안 함", + "reload": "다시 로드", + "configure": "설정", + "viewInfo": "핸들러", + "viewDocs": "문서", + "update": "업데이트", + "uninstall": "제거" + }, + "table": { + "headers": { + "name": "이름", + "description": "설명", + "version": "버전", + "author": "작성자", + "status": "상태", + "actions": "작업", + "stars": "스타", + "lastUpdate": "마지막 업데이트", + "tags": "태그", + "eventType": "이벤트 유형", + "specificType": "세부 유형", + "trigger": "트리거" + } + }, + "empty": { + "noPlugins": "플러그인 없음", + "noPluginsDesc": "플러그인을 설치하거나 검색어를 조정해 보세요" + }, + "detail": { + "contents": "플러그인 핸들러", + "noContents": "핸들러 없음", + "notFound": "플러그인을 찾을 수 없습니다", + "docsTitle": "문서", + "docsEmpty": "문서 없음", + "changelogTitle": "변경 이력", + "changelogEmpty": "변경 이력 없음", + "subCommandsCount": "하위 명령 {count}개", + "handlerGroups": { + "page": "페이지", + "skill": "Skills", + "command": "명령어 / 명령어 그룹", + "llm_tool": "LLM 도구", + "listener": "이벤트 리스너", + "hook": "훅", + "commands": "명령어 / 명령어 그룹", + "hooks": "훅", + "functionTools": "함수 도구", + "eventListeners": "이벤트 리스너" + }, + "info": { + "title": "정보", + "version": "버전", + "author": "작성자", + "category": "카테고리", + "stars": "스타", + "tags": "태그", + "astrbotVersion": "AstrBot 버전 요구 사항", + "supportPlatforms": "지원 플랫폼", + "authorWebsite": "작성자 웹사이트", + "repository": "저장소" + } + }, + "market": { + "recommended": "🥳 추천", + "allPlugins": "📦 전체 플러그인", + "category": "카테고리", + "categories": { + "all": "전체", + "ai_tools": "AI 도구", + "entertainment": "엔터테인먼트", + "productivity": "생산성", + "integrations": "연동", + "utilities": "유틸리티", + "other": "기타" + }, + "showFullName": "전체 이름", + "devDocs": "플러그인 개발 문서", + "submitRepo": "플러그인 저장소 제출", + "customSource": "사용자 지정 플러그인 소스", + "source": "소스", + "availableSources": "사용 가능한 소스", + "sourceManagement": "소스 관리", + "addSource": "소스 추가", + "sourceName": "소스 이름", + "sourceUrl": "소스 URL", + "defaultSource": "기본 소스", + "removeSource": "소스 제거", + "confirmRemoveSource": "이 소스를 제거하시겠습니까?", + "sourceAdded": "소스가 추가되었습니다", + "sourceRemoved": "소스가 제거되었습니다", + "sourceError": "작업에 실패했습니다", + "selectSource": "소스 선택", + "currentSource": "현재 소스", + "editSource": "소스 편집", + "sourceUpdated": "소스가 업데이트되었습니다", + "defaultOfficialSource": "기본 공식 소스", + "sourceExists": "이미 존재하는 소스입니다", + "sourceResolved": "소스가 확인되었습니다", + "installPlugin": "플러그인 설치", + "randomPlugins": "🎲 랜덤 플러그인", + "sourceSafetyWarning": "기본 소스를 사용하더라도 플러그인의 안정성과 보안을 완전히 보장할 수는 없습니다. 사용 전에 반드시 확인하세요." + }, + "sort": { + "by": "정렬 기준", + "default": "기본값", + "installTime": "최근 수정", + "name": "이름", + "stars": "스타", + "author": "작성자", + "updated": "최근 업데이트", + "updateStatus": "업데이트 상태", + "ascending": "오름차순", + "descending": "내림차순" + }, + "tags": { + "danger": "위험" + }, + "dialogs": { + "error": { + "title": "오류 정보", + "checkConsole": "자세한 내용은 콘솔을 확인하세요" + }, + "config": { + "title": "플러그인 설정", + "noConfig": "이 플러그인에는 설정 항목이 없습니다" + }, + "loading": { + "title": "로딩 중...", + "logs": "로그" + }, + "uninstall": { + "title": "삭제 확인", + "message": "이 플러그인을 삭제하시겠습니까?", + "deleteConfig": "플러그인 설정 파일도 함께 삭제", + "deleteData": "플러그인 영구 데이터도 함께 삭제", + "configHint": "설정 파일은 data/config 디렉터리에 있습니다", + "dataHint": "data/plugin_data 및 data/plugins_data의 데이터와 데이터베이스 내 KV 환경설정 데이터를 삭제합니다" + }, + "install": { + "title": "플러그인 설치", + "fromFile": "파일에서 설치", + "fromUrl": "URL에서 설치", + "supportPlatformsCount": "{count}개 플랫폼 지원", + "sectionTitle": "설치", + "downloadSource": "플러그인 패키지가 다음 위치에서 설치됩니다:", + "githubSecurityWarning": "AstrBot은 GitHub에서 다운로드한 플러그인의 안전성을 보장할 수 없습니다. 신뢰할 수 있는 플러그인 소스인 경우에만 설치하세요." + }, + "update": { + "title": "플러그인 업데이트", + "sectionTitle": "업데이트", + "downloadSource": "업데이트 패키지가 다음 위치에서 설치됩니다:", + "confirm": "업데이트 확인" + }, + "danger_warning": { + "title": "위험한 플러그인 경고", + "message": "이 플러그인은 안전하지 않은 코드나 시스템 오작동, 데이터 손실을 유발할 수 있는 기능을 포함한 보안 위험이 있는 것으로 표시되었습니다. 계속 설치하시겠습니까?", + "confirm": "계속", + "cancel": "취소" + }, + "versionSupport": { + "title": "버전 지원 경고", + "message": "이 플러그인이 명시한 AstrBot 버전 범위가 현재 버전과 일치하지 않습니다. 경고를 무시하고 설치를 계속할 수 있지만 정상적으로 동작하지 않을 수 있습니다.", + "confirm": "경고 무시하고 설치", + "cancel": "설치 취소" + }, + "forceUpdate": { + "title": "새 버전이 감지되지 않음", + "message": "이 플러그인의 새 버전이 감지되지 않았습니다. 강제로 다시 설치하시겠습니까? 원격 저장소에서 최신 코드를 가져옵니다.", + "confirm": "강제 업데이트" + }, + "updateAllConfirm": { + "title": "전체 플러그인 업데이트 확인", + "message": "{count}개의 플러그인을 모두 업데이트하시겠습니까? 이 작업은 시간이 걸릴 수 있습니다.", + "confirm": "업데이트 확인" + }, + "sourceBinding": { + "title": "플러그인 소스 변경", + "selectTitle": "플러그인 설치 소스 선택", + "noCandidates": "일치하는 레코드를 포함한 설정된 플러그인 소스가 없고, 이 플러그인은 사용 가능한 저장소 URL도 없습니다.", + "repoOption": "저장소 URL 직접 사용", + "repoOptionId": "저장소를 통해 다시 설치", + "installDestination": "설치 대상", + "confirm": "이 소스 사용", + "confirmAndContinue": "사용하고 계속" + } + }, + "messages": { + "uninstalling": "제거 중", + "refreshing": "플러그인 목록을 새로고침하는 중...", + "refreshSuccess": "플러그인 목록을 새로고침했습니다!", + "refreshFailed": "플러그인 목록 새로고침 중 오류가 발생했습니다", + "operationFailed": "작업에 실패했습니다", + "reloadSuccess": "다시 로드에 성공했습니다", + "reloadFailed": "다시 로드에 실패했습니다", + "updateSuccess": "업데이트에 성공했습니다!", + "addSuccess": "추가에 성공했습니다!", + "saveSuccess": "저장에 성공했습니다!", + "deleteSuccess": "삭제에 성공했습니다!", + "installing": "파일에서 플러그인을 설치하는 중", + "installingFromUrl": "URL에서 플러그인을 설치하는 중...", + "installFailed": "플러그인 설치에 실패했습니다:", + "getMarketDataFailed": "플러그인 마켓 데이터를 가져오지 못했습니다:", + "hasUpdate": "새 버전이 있습니다:", + "confirmDelete": "이 플러그인을 삭제하시겠습니까?", + "fillUrlOrFile": "플러그인 URL을 입력하거나 플러그인 파일을 업로드하세요", + "dontFillBoth": "플러그인 URL과 파일을 동시에 입력하지 마세요", + "supportedFormats": ".zip 플러그인 파일을 지원합니다", + "updateAllSuccess": "업데이트 가능한 모든 플러그인이 업데이트되었습니다!", + "updateAllFailed": "{total}개 중 {failed}개의 플러그인 업데이트에 실패했습니다:", + "noUpdatesAvailable": "업데이트 가능한 플러그인이 없습니다", + "updateDisabled": "이 플러그인은 사용 가능한 설치 소스나 저장소 URL이 없어 업데이트하거나 다시 설치할 수 없습니다", + "changeSourceDisabled": "이 플러그인은 사용 가능한 저장소 URL이 없어 소스를 변경할 수 없습니다", + "fillSourceUrl": "소스 URL을 입력하세요", + "fillSourceName": "소스 이름을 입력하세요", + "resolveSourceFirst": "먼저 소스 URL을 확인하고 검증하세요", + "sourceResolveFailed": "소스 확인에 실패했습니다", + "invalidUrl": "올바른 URL을 입력하세요", + "invalidGithubRepo": "올바른 GitHub 저장소 URL을 입력하세요", + "enterJsonUrl": "플러그인 목록 JSON 데이터를 반환하는 URL을 입력하세요", + "pluginNotFound": "플러그인을 찾을 수 없습니다", + "pluginDisabled": "이 플러그인은 사용 안 함 상태입니다. 페이지를 열기 전에 사용으로 전환하세요.", + "pluginPageNotFound": "플러그인 페이지를 찾을 수 없습니다", + "pluginPageLoadFailed": "플러그인 페이지를 불러오지 못했습니다", + "missingMarketPluginId": "이 소스 레코드에 유효한 플러그인 식별자가 없어 마켓에서 설치할 수 없습니다", + "sourceBindSuccess": "플러그인 소스가 업데이트되었습니다", + "validatingPlugin": "플러그인을 검증하는 중...", + "pluginValidateSuccess": "플러그인 검증을 통과했습니다", + "pluginValidateFailed": "플러그인 검증에 실패했습니다" + }, + "upload": { + "fromFile": "파일에서 설치", + "fromUrl": "URL에서 설치", + "selectFile": "파일 선택", + "enterUrl": "플러그인 저장소 URL 입력" + }, + "skills": { + "modeLocal": "로컬 Skills", + "modeNeo": "Neo Skills", + "actions": "작업", + "upload": "Skills 업로드", + "refresh": "새로고침", + "empty": "Skills가 없습니다", + "emptyHint": "Skills zip 파일을 업로드해 시작하세요", + "uploadDialogTitle": "Skills 업로드", + "uploadHint": "여러 개의 zip Skill 패키지를 업로드하거나 끌어다 놓으세요. 시스템이 구조를 자동으로 검증하고 파일별 결과를 표시합니다.", + "structureRequirement": "아카이브는 여러 개의 skills 폴더를 지원합니다.", + "abilityMultiple": "여러 zip 파일을 한 번에 업로드", + "abilityValidate": "`SKILL.md`를 자동으로 검증", + "abilitySkip": "중복 파일은 자동으로 건너뜁니다.", + "selectFile": "파일 선택", + "selectFiles": "파일 선택(다중 선택 가능)", + "dropzoneTitle": "여러 zip 파일을 여기로 끌어다 놓으세요", + "dropzoneAction": "또는 클릭하여 폴더에서 여러 파일 선택", + "dropzoneHint": "일괄 업로드를 지원하며 구조는 자동으로 검증됩니다", + "fileListTitle": "대기열의 파일", + "fileListEmpty": "선택한 파일이 여기에 검증 결과 및 업로드 상태와 함께 표시됩니다", + "uploading": "업로드 중...", + "batchResultTitle": "일괄 업로드 결과", + "batchResultSummary": "{total}개 중 {success}개 파일 업로드 성공", + "batchSuccessList": "업로드 성공", + "batchFailedList": "업로드 실패", + "confirm": "확인", + "confirmUpload": "업로드 시작", + "cancel": "취소", + "statusWaiting": "대기 중", + "statusUploading": "업로드 중", + "statusSuccess": "업로드됨", + "statusError": "실패", + "statusSkipped": "건너뜀", + "summaryTotal": "{count}개 파일", + "summaryReady": "대기 {count}개", + "summarySuccess": "성공 {count}개", + "summaryFailed": "실패 {count}개", + "summarySkipped": "건너뜀 {count}개", + "validationReady": "업로드할 준비가 되었습니다. 업로드 중 아카이브 구조를 검사합니다.", + "validationZipOnly": "zip Skill 패키지만 지원됩니다", + "validationDuplicate": "같은 이름의 파일이 이미 대기열에 있어 건너뛰었습니다", + "validationUploading": "검증 및 업로드 중...", + "validationUploadFailed": "업로드에 실패했습니다. 다시 시도하세요.", + "validationUploadedAs": "{name}(으)로 설치됨", + "validationNoResult": "검증 결과가 반환되지 않았습니다. 플랫폼 로그를 확인하세요.", + "noDescription": "설명 없음", + "path": "경로", + "uploadSuccess": "업로드 성공", + "uploadFailed": "업로드 실패", + "download": "다운로드", + "downloadSuccess": "다운로드 성공", + "downloadFailed": "다운로드 실패", + "loadFailed": "Skills를 불러오지 못했습니다", + "updateSuccess": "업데이트 성공", + "updateFailed": "업데이트 실패", + "deleteTitle": "삭제 확인", + "deleteMessage": "이 Skill을 삭제하시겠습니까?", + "deleteSuccess": "삭제 성공", + "deleteFailed": "삭제 실패", + "neoSkillKey": "skill_key로 필터링", + "neoStatus": "후보 상태", + "neoStage": "릴리스 단계", + "neoFilterHint": "후보 및 릴리스 기록 필터링", + "neoAll": "전체", + "neoCandidates": "Neo 후보", + "neoReleases": "Neo 릴리스", + "neoLoadFailed": "Neo Skills 데이터를 불러오지 못했습니다", + "neoPass": "통과", + "neoReject": "거부", + "neoEvaluateSuccess": "평가가 업데이트되었습니다", + "neoEvaluateFailed": "평가 업데이트에 실패했습니다", + "neoPromoteSuccess": "승격 성공", + "neoPromoteFailed": "승격 실패", + "neoRollback": "롤백", + "neoRollbackSuccess": "롤백 성공", + "neoRollbackFailed": "롤백 실패", + "neoDeactivate": "비활성화", + "neoDeactivateSuccess": "비활성화 성공", + "neoDeactivateFailed": "비활성화 실패", + "neoSync": "동기화", + "neoSyncSuccess": "동기화 성공", + "neoSyncFailed": "동기화 실패", + "neoDelete": "삭제", + "neoDeleteSuccess": "삭제 성공", + "neoDeleteFailed": "삭제 실패", + "neoPayloadTitle": "Neo Payload", + "neoPayloadFailed": "Payload를 불러오지 못했습니다", + "runtimeNoneWarning": "Computer Use 런타임이 None으로 설정되어 있습니다. 활성화된 런타임이 없어 Skills가 정상적으로 실행되지 않을 수 있습니다.", + "runtimeHint": "AstrBot이 Skills를 사용할 수 있도록 설정에서 Computer Use 런타임을 Local 또는 Sandbox로 지정하세요. Workspace Skills는 아직 이 페이지에 표시되지 않습니다.", + "neoRuntimeRequired": "Neo Skills는 런타임이 sandbox이고 sandbox booter가 shipyard_neo인 경우에만 사용할 수 있습니다.", + "sourceLocalOnly": "로컬 Skill", + "sourceSandboxOnly": "Sandbox 프리셋 Skill", + "sourceBoth": "로컬 + Sandbox", + "sourcePlugin": "플러그인: {plugin}", + "sandboxDiscoveryPending": "Sandbox 프리셋 Skills가 아직 검색되지 않았습니다. 목록을 채우려면 최소 하나의 sandbox 세션을 시작하세요.", + "sandboxPresetReadonly": "Sandbox 프리셋 Skills는 여기서 읽기 전용입니다. 로컬 Skills에서 삭제하거나 사용 여부를 전환할 수 없습니다.", + "pluginReadonly": "플러그인이 제공하는 Skills는 해당 플러그인이 관리합니다. 로컬 Skills에서 삭제하거나 다운로드할 수 없습니다.", + "openEditor": "보기/편집", + "editorTitle": "Skill 편집", + "editorLoadFailed": "Skill 파일을 불러오지 못했습니다", + "editorSaveFailed": "Skill 파일을 저장하지 못했습니다", + "editorSaveSuccess": "저장 성공", + "saveFile": "파일 저장", + "readonly": "읽기 전용", + "unsaved": "저장 안 됨", + "noFileSelected": "선택된 파일 없음", + "discardChanges": "이 파일에 저장하지 않은 변경 사항이 있습니다. 변경 사항을 취소하시겠습니까?" + }, + "card": { + "actions": { + "pluginConfig": "플러그인 설정", + "uninstallPlugin": "플러그인 제거", + "reloadPlugin": "플러그인 다시 로드", + "togglePlugin": "플러그인", + "viewHandlers": "핸들러 보기", + "updateTo": "다음 버전으로 업데이트", + "reinstall": "재설치", + "changeSource": "플러그인 소스 변경" + }, + "status": { + "hasUpdate": "새 버전 있음", + "disabled": "이 플러그인은 사용 안 함 상태입니다", + "handlersCount": " 개 핸들러", + "supportPlatform": "지원 플랫폼", + "supportPlatformsCount": "{count}개 플랫폼 지원", + "astrbotVersion": "AstrBot 버전 요구 사항" + }, + "alt": { + "logo": "로고", + "extensionIcon": "플러그인 아이콘" + }, + "errors": { + "confirmNotRegistered": "$confirm이(가) 올바르게 등록되지 않았습니다" + } + }, + "conflicts": { + "title": "명령어 충돌 감지됨", + "message": "일부 명령어가 비정상적으로 동작할 수 있습니다. [명령어 관리] 패널에서 처리하는 것을 권장합니다.", + "pairs": "개 명령어 충돌", + "goToManage": "관리하러 가기", + "later": "나중에" + }, + "pluginChangelog": { + "menuTitle": "변경 이력 보기" + } +} diff --git a/dashboard/src/i18n/locales/ko-KR/features/knowledge-base/detail.json b/dashboard/src/i18n/locales/ko-KR/features/knowledge-base/detail.json new file mode 100644 index 0000000000..73099ef8f8 --- /dev/null +++ b/dashboard/src/i18n/locales/ko-KR/features/knowledge-base/detail.json @@ -0,0 +1,121 @@ +{ + "title": "지식 베이스 상세", + "backToList": "목록으로 돌아가기", + "breadcrumb": { + "list": "지식 베이스" + }, + "tabs": { + "overview": "개요", + "documents": "문서", + "retrieval": "검색", + "sessions": "세션", + "settings": "설정" + }, + "overview": { + "title": "기본 정보", + "name": "이름", + "description": "설명", + "emoji": "아이콘", + "createdAt": "생성 시간", + "updatedAt": "수정 시간", + "stats": "통계", + "docCount": "문서", + "chunkCount": "청크", + "embeddingModel": "임베딩 모델", + "rerankModel": "재순위 모델", + "notSet": "설정되지 않음" + }, + "documents": { + "title": "문서", + "upload": "문서 업로드", + "empty": "문서 없음", + "name": "이름", + "type": "유형", + "size": "크기", + "chunks": "청크", + "createdAt": "업로드 시간", + "actions": "작업", + "view": "보기", + "delete": "삭제", + "deleteConfirm": "'{name}' 문서를 삭제하시겠습니까?", + "deleteWarning": "문서와 모든 청크가 삭제됩니다. 이 작업은 되돌릴 수 없습니다.", + "uploading": "업로드 중...", + "uploadSuccess": "문서가 업로드되었습니다", + "uploadFailed": "문서 업로드 실패", + "deleteSuccess": "문서가 삭제되었습니다", + "deleteFailed": "문서 삭제 실패" + }, + "upload": { + "title": "문서 업로드", + "selectFile": "파일 선택", + "dropzone": "여기에 파일을 놓거나 클릭하여 선택하세요", + "supportedFormats": "지원 형식: .txt, .md, .markdown, .rst, .adoc, .pdf, .docx, .epub, .xls, .xlsx", + "maxSize": "최대 파일 크기: 128MB", + "chunkSettings": "청크 설정", + "batchSettings": "배치 설정", + "cleaningSettings": "정제 설정", + "enableCleaning": "콘텐츠 정제 사용", + "cleaningProvider": "정제 서비스 공급자", + "cleaningProviderHint": "추출된 웹 페이지 콘텐츠를 정제하고 요약할 LLM 공급자를 선택하세요", + "chunkSize": "청크 크기", + "chunkSizeHint": "청크당 문자 수 (기본값: 512)", + "chunkOverlap": "청크 겹침", + "chunkOverlapHint": "청크 간 겹치는 문자 수 (기본값: 50)", + "batchSize": "배치 크기", + "batchSizeHint": "배치당 처리할 청크 수 (기본값: 32)", + "tasksLimit": "동시 작업 제한", + "tasksLimitHint": "동시에 실행 가능한 업로드 작업의 최대 수 (기본값: 3)", + "maxRetries": "최대 재시도 횟수", + "maxRetriesHint": "업로드 작업 실패 시 재시도 횟수 (기본값: 3)", + "cancel": "취소", + "submit": "업로드", + "fileRequired": "업로드할 파일을 선택해 주세요", + "fileUpload": "파일 업로드", + "fromUrl": "URL에서 가져오기", + "urlPlaceholder": "콘텐츠를 추출할 웹 페이지의 URL을 입력하세요", + "urlRequired": "URL을 입력해 주세요", + "urlHint": "대상 URL에서 주요 콘텐츠가 자동으로 추출되어 문서로 등록됩니다. 현재 {supported} 페이지를 지원합니다. 사용 전 대상 웹 페이지가 크롤러 접근을 허용하는지 확인해 주세요.", + "beta": "베타" + }, + "retrieval": { + "title": "검색", + "subtitle": "밀집 및 희소 검색 방식으로 지식 베이스를 테스트하세요", + "query": "질의", + "queryPlaceholder": "질의를 입력하세요...", + "search": "검색", + "searching": "검색 중...", + "results": "결과", + "noResults": "결과가 없습니다", + "tryDifferentQuery": "다른 질의를 시도해 보세요", + "settings": "검색 설정", + "topK": "결과 수", + "topKHint": "반환할 최대 결과 수", + "enableRerank": "재순위 사용", + "enableRerankHint": "재순위 모델을 사용해 검색 품질을 향상시킵니다", + "score": "관련도 점수", + "document": "문서", + "chunk": "청크 #{index}", + "content": "내용", + "charCount": "{count}자", + "searchSuccess": "검색 완료, {count}개 결과를 찾았습니다", + "searchFailed": "검색 실패", + "queryRequired": "질의를 입력해 주세요" + }, + "settings": { + "title": "지식 베이스 설정", + "basic": "기본 설정", + "retrieval": "검색 설정", + "chunkSize": "청크 크기", + "chunkOverlap": "청크 겹침", + "topKDense": "밀집 검색 결과 수", + "topKSparse": "희소 검색 결과 수", + "topMFinal": "최종 결과 수", + "enableRerank": "재순위 사용", + "embeddingProvider": "임베딩 공급자", + "rerankProvider": "재순위 공급자", + "save": "설정 저장", + "saveSuccess": "설정이 저장되었습니다", + "saveFailed": "설정 저장 실패", + "tips": "팁: 검색 설정을 변경하면 이후 지식 베이스 조회에 영향을 줍니다." + } +} diff --git a/dashboard/src/i18n/locales/ko-KR/features/knowledge-base/document.json b/dashboard/src/i18n/locales/ko-KR/features/knowledge-base/document.json new file mode 100644 index 0000000000..4a9ed13684 --- /dev/null +++ b/dashboard/src/i18n/locales/ko-KR/features/knowledge-base/document.json @@ -0,0 +1,55 @@ +{ + "title": "문서 상세", + "backToKB": "지식 베이스로 돌아가기", + "info": { + "title": "문서 정보", + "name": "문서 이름", + "type": "파일 유형", + "size": "파일 크기", + "chunkCount": "청크 수", + "createdAt": "업로드 시간" + }, + "chunks": { + "title": "청크", + "empty": "청크 없음", + "index": "번호", + "content": "내용", + "charCount": "문자 수", + "actions": "작업", + "view": "보기", + "edit": "편집", + "delete": "삭제", + "preview": "미리보기", + "search": "청크 검색", + "searchPlaceholder": "청크를 검색할 키워드를 입력하세요...", + "showing": "표시 중", + "deleteConfirm": "이 청크를 삭제하시겠습니까?", + "deleteSuccess": "청크가 삭제되었습니다", + "deleteFailed": "청크 삭제 실패" + }, + "edit": { + "title": "청크 편집", + "content": "청크 내용", + "cancel": "취소", + "save": "저장", + "saveSuccess": "청크가 저장되었습니다", + "saveFailed": "청크 저장 실패" + }, + "delete": { + "title": "청크 삭제", + "confirmText": "이 청크를 삭제하시겠습니까?", + "warning": "이 작업은 되돌릴 수 없으며 지식 베이스 검색 성능에 영향을 줄 수 있습니다.", + "cancel": "취소", + "confirm": "삭제", + "deleteSuccess": "청크가 삭제되었습니다", + "deleteFailed": "청크 삭제 실패" + }, + "view": { + "title": "청크 세부 정보", + "index": "번호", + "content": "내용", + "charCount": "문자 수", + "vecDocId": "벡터 ID", + "close": "닫기" + } +} diff --git a/dashboard/src/i18n/locales/ko-KR/features/knowledge-base/index.json b/dashboard/src/i18n/locales/ko-KR/features/knowledge-base/index.json new file mode 100644 index 0000000000..a4de1ccf88 --- /dev/null +++ b/dashboard/src/i18n/locales/ko-KR/features/knowledge-base/index.json @@ -0,0 +1,68 @@ +{ + "title": "지식 베이스 관리", + "subtitle": "지식 베이스 콘텐츠 관리 및 조회", + "list": { + "title": "지식 베이스", + "subtitle": "모든 지식 베이스 컬렉션을 관리하세요", + "create": "지식 베이스 생성", + "refresh": "목록 새로고침", + "empty": "지식 베이스 없음", + "loading": "불러오는 중...", + "documents": "문서", + "chunks": "청크", + "sessionConfig": "세션 구성", + "initError": "초기화 실패" + }, + "card": { + "edit": "편집", + "delete": "삭제", + "open": "열기", + "docCount": "문서 {count}개", + "chunkCount": "청크 {count}개" + }, + "create": { + "title": "지식 베이스 생성", + "nameLabel": "이름", + "namePlaceholder": "지식 베이스 이름을 입력하세요", + "descriptionLabel": "설명", + "descriptionPlaceholder": "이 지식 베이스의 용도를 설명하세요...", + "emojiLabel": "아이콘", + "embeddingModelLabel": "임베딩 모델", + "rerankModelLabel": "재순위 모델 (선택 사항)", + "providerInfo": "공급자: {id} | 차원: {dimensions}", + "rerankProviderInfo": "공급자: {id}", + "cancel": "취소", + "submit": "생성", + "nameRequired": "지식 베이스 이름을 입력해 주세요" + }, + "edit": { + "title": "지식 베이스 편집", + "submit": "저장" + }, + "delete": { + "title": "지식 베이스 삭제", + "confirmText": "'{name}' 지식 베이스를 삭제하시겠습니까?", + "warning": "이 작업은 되돌릴 수 없습니다. 모든 문서, 청크, 관련 구성이 영구적으로 삭제됩니다.", + "cancel": "취소", + "confirm": "삭제" + }, + "emoji": { + "title": "아이콘 선택", + "close": "닫기", + "categories": { + "books": "책 및 문서", + "emotions": "감정 및 표정", + "objects": "사물 및 도구", + "symbols": "기호 및 표시" + } + }, + "messages": { + "createSuccess": "지식 베이스가 생성되었습니다", + "createFailed": "생성 실패", + "updateSuccess": "지식 베이스가 업데이트되었습니다", + "updateFailed": "업데이트 실패", + "deleteSuccess": "지식 베이스가 삭제되었습니다", + "deleteFailed": "삭제 실패", + "loadError": "지식 베이스 목록 불러오기 실패" + } +} diff --git a/dashboard/src/i18n/locales/ko-KR/features/persona.json b/dashboard/src/i18n/locales/ko-KR/features/persona.json new file mode 100644 index 0000000000..f78188eaf6 --- /dev/null +++ b/dashboard/src/i18n/locales/ko-KR/features/persona.json @@ -0,0 +1,147 @@ +{ + "page": { + "description": "챗봇의 페르소나 설정을 관리하고 구성합니다" + }, + "buttons": { + "create": "페르소나 생성", + "createFirst": "첫 페르소나 생성", + "edit": "편집", + "delete": "삭제", + "cancel": "취소", + "save": "저장", + "move": "이동", + "addDialogPair": "대화 쌍 추가" + }, + "labels": { + "presetDialogs": "프리셋 대화 ({count}쌍)", + "createdAt": "생성일", + "updatedAt": "수정일" + }, + "form": { + "personaId": "페르소나 ID", + "systemPrompt": "시스템 프롬프트", + "customErrorMessage": "사용자 지정 오류 응답 메시지 (선택)", + "customErrorMessageHelp": "이 페르소나의 LLM 요청이 실패하면(예: 연결 실패) 이 오류 응답이 먼저 전송됩니다. 비워두면 기본 오류 메시지가 사용됩니다.", + "presetDialogs": "프리셋 대화", + "presetDialogsHelp": "봇이 역할 설정을 더 잘 이해하도록 프리셋 대화를 추가하세요. 대화 개수는 짝수여야 합니다(사용자와 어시스턴트가 번갈아 발화).", + "userMessage": "사용자 메시지", + "assistantMessage": "어시스턴트 메시지", + "tools": "도구 선택", + "toolsHelp": "이 페르소나가 사용할 수 있는 도구를 선택하세요. 도구를 사용하면 봇이 검색, 계산, 정보 조회 등 특정 기능을 수행할 수 있습니다.", + "toolsSelection": "도구 선택 작업", + "selectAllTools": "모든 도구 선택", + "clearAllTools": "선택 해제", + "allSelected": "모두 선택됨", + "mcpServersQuickSelect": "MCP 서버 빠른 선택", + "searchTools": "도구 검색", + "selectedTools": "선택한 도구", + "builtinToolDisabledHint": "빌트인 도구는 아직 여기서 사용 여부를 전환할 수 없습니다. 설정 파일에서 해당 설정 항목을 사용/사용 안 함으로 변경하세요.", + "noToolsAvailable": "사용 가능한 도구 없음", + "noToolsFound": "일치하는 도구 없음", + "loadingTools": "도구를 불러오는 중...", + "allToolsAvailable": "사용 가능한 모든 도구 사용", + "noToolsSelected": "선택한 도구 없음", + "skills": "Skills 선택", + "skillsHelp": "이 페르소나가 사용할 수 있는 Skills를 선택하세요. Skills는 재사용 가능한 워크플로와 가이드를 제공합니다.", + "skillsAllAvailable": "사용 가능한 모든 Skills 사용", + "skillsSelectSpecific": "특정 Skills 선택", + "searchSkills": "Skills 검색", + "selectedSkills": "선택한 Skills", + "noSkillsAvailable": "사용 가능한 Skills 없음", + "noSkillsFound": "일치하는 Skills 없음", + "loadingSkills": "Skills를 불러오는 중...", + "allSkillsAvailable": "사용 가능한 모든 Skills 사용", + "noSkillsSelected": "선택한 Skills 없음", + "skillsRuntimeNoneWarning": "Computer Use 런타임이 None으로 설정되어 있습니다. 활성화된 런타임이 없어 Skills가 정상적으로 실행되지 않을 수 있습니다.", + "createInFolder": "\"{folder}\"에 생성됩니다", + "rootFolder": "전체 페르소나" + }, + "dialog": { + "create": { + "title": "새 페르소나 생성" + }, + "edit": { + "title": "페르소나 편집" + } + }, + "empty": { + "title": "구성된 페르소나 없음", + "description": "첫 페르소나를 생성하여 맞춤형 챗봇 사용을 시작하세요", + "folderEmpty": "이 폴더는 비어 있습니다", + "folderEmptyDescription": "새 페르소나 또는 폴더를 생성하여 시작하세요" + }, + "validation": { + "required": "이 필드는 필수입니다", + "minLength": "최소 {min}자 이상 입력해야 합니다", + "alphanumeric": "영문자, 숫자, 밑줄, 하이픈만 사용할 수 있습니다", + "dialogRequired": "{type}은(는) 비워둘 수 없습니다", + "personaIdExists": "이미 존재하는 페르소나 이름입니다" + }, + "messages": { + "loadError": "페르소나 목록을 불러오지 못했습니다", + "saveSuccess": "저장 성공", + "saveError": "저장 실패", + "deleteConfirm": "페르소나 \"{id}\"을(를) 삭제하시겠습니까? 이 작업은 되돌릴 수 없습니다.", + "deleteSuccess": "삭제 성공", + "deleteError": "삭제 실패" + }, + "persona": { + "personasTitle": "페르소나", + "toolsCount": "개 도구", + "skillsCount": "개 Skills", + "contextMenu": { + "moveTo": "이동..." + }, + "messages": { + "moveSuccess": "페르소나를 이동했습니다", + "moveError": "페르소나 이동에 실패했습니다" + } + }, + "folder": { + "sidebarTitle": "폴더", + "rootFolder": "루트", + "foldersTitle": "폴더", + "noFolders": "아직 폴더가 없습니다", + "createButton": "새 폴더", + "searchPlaceholder": "폴더 검색...", + "form": { + "name": "폴더 이름", + "description": "설명 (선택)" + }, + "validation": { + "nameRequired": "폴더 이름은 필수입니다" + }, + "contextMenu": { + "open": "열기", + "rename": "이름 변경", + "moveTo": "이동...", + "delete": "삭제" + }, + "createDialog": { + "title": "새 폴더 생성", + "createButton": "생성" + }, + "renameDialog": { + "title": "폴더 이름 변경" + }, + "deleteDialog": { + "title": "폴더 삭제", + "message": "폴더 \"{name}\"을(를) 삭제하시겠습니까?", + "warning": "폴더 안의 모든 페르소나는 루트 폴더로 이동됩니다." + }, + "messages": { + "createSuccess": "폴더를 생성했습니다", + "createError": "폴더 생성에 실패했습니다", + "renameSuccess": "폴더 이름을 변경했습니다", + "renameError": "폴더 이름 변경에 실패했습니다", + "deleteSuccess": "폴더를 삭제했습니다", + "deleteError": "폴더 삭제에 실패했습니다" + } + }, + "moveDialog": { + "title": "폴더로 이동", + "description": "\"{name}\"의 대상 폴더를 선택하세요", + "success": "이동 성공", + "error": "이동 실패" + } +} diff --git a/dashboard/src/i18n/locales/ko-KR/features/platform.json b/dashboard/src/i18n/locales/ko-KR/features/platform.json new file mode 100644 index 0000000000..e77992c3c2 --- /dev/null +++ b/dashboard/src/i18n/locales/ko-KR/features/platform.json @@ -0,0 +1,214 @@ +{ + "title": "플랫폼 어댑터 관리", + "subtitle": "다양한 채팅 플랫폼에 연결할 봇 플랫폼 어댑터를 관리합니다", + "adapters": "플랫폼 어댑터", + "addAdapter": "어댑터 추가", + "emptyText": "아직 플랫폼 어댑터가 없습니다. 어댑터 추가를 클릭해 생성하세요", + "viewWebhook": "Webhook URL 보기", + "webhookCopied": "Webhook URL이 클립보드에 복사되었습니다", + "webhookCopyFailed": "복사에 실패했습니다. 직접 복사해 주세요", + "webhookDialog": { + "title": "Webhook 콜백 URL", + "description": "콜백 주소는 다음과 같습니다. 네트워크 환경에서 접근 가능한지 확인하세요. 로그에서도 콜백 주소 정보를 확인할 수 있습니다.", + "close": "닫기" + }, + "details": { + "adapterType": "어댑터 유형", + "token": "토큰", + "description": "설명" + }, + "logs": { + "title": "플랫폼 로그", + "expand": "펼치기", + "collapse": "접기" + }, + "dialog": { + "add": "추가", + "edit": "편집", + "adapter": "플랫폼 어댑터", + "refresh": "새로고침", + "cancel": "취소", + "save": "저장", + "addPlatform": "플랫폼 어댑터 추가", + "connectTitle": "{name} 연결", + "viewTutorial": "튜토리얼 보기", + "noTemplates": "사용 가능한 플랫폼 템플릿이 없습니다", + "idConflict": { + "title": "ID 충돌 경고", + "message": "중복된 ID \"{id}\"가 감지되었습니다. 새 ID를 사용하세요.", + "confirm": "확인" + }, + "securityWarning": { + "title": "보안 경고", + "aiocqhttpTokenMissing": "연결 보안을 강화하려면 ws_reverse_token을 설정하는 것을 강력히 권장합니다. 토큰을 설정하지 않으면 보안 위험이 발생할 수 있습니다.", + "learnMore": "자세히 알아보기" + }, + "invalidPlatformId": "플랫폼 ID에는 ':' 또는 '!'를 포함할 수 없습니다." + }, + "createDialog": { + "step1Title": "플랫폼 카테고리 선택", + "step1Hint": "봇을 어디에 연결하시겠습니까? 예: QQ, WeCom, Feishu, Discord, Telegram.", + "platformTypeLabel": "플랫폼 카테고리", + "configFileTitle": "설정 파일", + "optional": "선택", + "configHint": "봇을 어떻게 설정하시겠습니까? 설정 파일에는 모델, 페르소나, 지식 베이스, 플러그인 등이 포함됩니다.", + "configDefaultHint": "기본적으로 \"default\" 설정 파일을 사용합니다. 나중에 설정할 수 있습니다.", + "useExistingConfig": "기존 설정 파일 사용", + "selectConfigLabel": "설정 파일 선택", + "createNewConfig": "새 설정 파일 생성", + "newConfigNameLabel": "새 설정 이름", + "newConfigTitle": "새 설정 파일 사용", + "newConfigLoadFailed": "기본 설정 템플릿을 불러오지 못했습니다", + "addRouteRule": "라우팅 규칙 추가", + "viewMode": "보기", + "editMode": "편집", + "noRouteRules": "이 플랫폼에는 라우팅 규칙이 없습니다. 기본 설정 파일이 사용됩니다.", + "sessionIdPlaceholder": "세션 ID 또는 *", + "routeSource": { + "selectPlaceholder": "세션 소스 선택", + "noData": "이 봇에 대한 통합 메시지 소스가 아직 없습니다. 해당 봇이 메시징 플랫폼으로부터 최소 한 건의 메시지를 수신하면 여기에 표시됩니다.", + "switchToKnown": "기존 소스 선택으로 전환", + "switchToManual": "수동 입력으로 전환" + }, + "allSessions": "모든 세션", + "configMissing": "설정 파일을 찾을 수 없습니다", + "routeHint": "메시지를 전달할 때 세션 소스를 기준으로 위에서부터 처음 일치하는 설정 파일이 사용됩니다. *는 모두 일치시킵니다. /sid로 세션 ID를 확인할 수 있습니다. 일치하는 항목이 없으면 기본 설정 파일이 사용됩니다.", + "warningContinue": "경고 무시하고 계속", + "warningEditAgain": "다시 편집", + "configDrawerTitle": "설정 파일 관리", + "configDrawerIdLabel": "ID", + "configTableHeaders": { + "configId": "이 인스턴스에 연결된 설정 ID", + "scope": "이 인스턴스에서의 범위" + }, + "routeTableHeaders": { + "source": "메시지 소스 (유형: 세션 ID)", + "config": "설정 파일", + "actions": "작업" + }, + "messageTypeOptions": { + "all": "모든 메시지", + "group": "그룹 메시지 (GroupMessage)", + "friend": "다이렉트 메시지 (FriendMessage)" + }, + "messageTypeLabels": { + "all": "모든 메시지", + "group": "그룹 메시지", + "friend": "다이렉트 메시지" + } + }, + "messages": { + "updateSuccess": "업데이트에 성공했습니다!", + "addSuccess": "추가에 성공했습니다!", + "deleteSuccess": "삭제에 성공했습니다!", + "statusUpdateSuccess": "상태 업데이트에 성공했습니다!", + "deleteConfirm": "플랫폼 어댑터를 삭제하시겠습니까", + "configNotFoundOpenConfig": "대상 설정 파일을 찾을 수 없습니다. 확인을 위해 설정 페이지를 열었습니다.", + "updateMissingPlatformId": "업데이트 실패: 플랫폼 ID가 없습니다.", + "platformUpdateFailed": "플랫폼 업데이트에 실패했습니다.", + "addSuccessWithConfig": "플랫폼이 추가되었습니다. 설정 파일이 업데이트되었습니다.", + "configIdMissing": "설정 파일 ID를 가져올 수 없습니다.", + "routingUpdateFailed": "라우팅 테이블 업데이트에 실패했습니다: {message}", + "createConfigFailed": "설정 파일 생성에 실패했습니다: {message}", + "platformIdMissing": "플랫폼 ID를 가져올 수 없습니다.", + "routingSaveFailed": "라우팅 테이블 저장에 실패했습니다: {message}" + }, + "status": { + "enabled": "사용 중", + "disabled": "사용 안 함", + "connecting": "연결 중", + "connected": "연결됨", + "disconnected": "연결 끊김", + "error": "오류" + }, + "runtimeStatus": { + "running": "실행 중", + "error": "오류", + "pending": "대기 중", + "stopped": "중지됨", + "unknown": "알 수 없음", + "errors": "개 오류" + }, + "platformQr": { + "title": "QR 로그인", + "show": "QR 보기", + "status": "QR 상태", + "waiting": "QR 대기 중", + "close": "닫기" + }, + "registrationAction": { + "lark": { + "title": "원클릭 QR 설정", + "show": "원클릭 QR 설정", + "scanTitle": "휴대폰의 Feishu로 스캔하세요", + "feishu": "Feishu 중국", + "lark": "Lark 글로벌" + }, + "weixinOc": { + "title": "개인 WeChat QR 로그인", + "scanTitle": "휴대폰의 WeChat으로 스캔하세요", + "created": "로그인 완료", + "status": { + "idle": "시작 전", + "starting": "QR 코드 가져오는 중", + "pending": "스캔 대기 중", + "created": "로그인 완료 - 저장 버튼을 클릭하는 것을 잊지 마세요!", + "denied": "취소됨", + "expired": "만료됨", + "error": "로그인 실패" + } + }, + "dingtalk": { + "title": "DingTalk QR 설정", + "scanTitle": "휴대폰의 DingTalk으로 스캔하세요", + "created": "설정 완료" + }, + "qqOfficial": { + "title": "QQ 공식 봇 QR 바인딩", + "scanTitle": "휴대폰의 QQ로 스캔하세요", + "created": "바인딩 완료", + "status": { + "idle": "시작 전", + "starting": "QR 코드 가져오는 중", + "pending": "스캔 대기 중", + "created": "바인딩 완료 - 저장 버튼을 클릭하는 것을 잊지 마세요!", + "denied": "취소됨", + "expired": "만료됨", + "error": "바인딩 실패" + } + }, + "start": "설정 시작", + "created": "설정 완료", + "startFailed": "QR 설정 시작에 실패했습니다", + "pollFailed": "QR 설정 상태 폴링에 실패했습니다", + "platformIdLabel": "봇 ID", + "platformIdRequired": "봇 ID는 필수입니다", + "platformIdInvalid": "봇 ID에는 공백, ':' 또는 '!'를 포함할 수 없습니다", + "mode": { + "title": "설정 방법 선택", + "scan": "원클릭 QR 설정", + "manual": "수동 설정", + "larkManual": "수동 설정 (자체 호스팅 Feishu 지원)" + }, + "scanTitle": "휴대폰의 Feishu로 스캔하세요", + "status": { + "idle": "시작 전", + "starting": "시작 중", + "pending": "스캔 대기 중", + "slow_down": "폴링 지연됨", + "created": "설정 완료 - 저장 버튼을 클릭하는 것을 잊지 마세요!", + "denied": "취소됨", + "expired": "만료됨", + "error": "설정 실패" + } + }, + "errorDialog": { + "title": "오류 상세", + "platformId": "플랫폼 ID", + "errorCount": "오류 횟수", + "lastError": "마지막 오류", + "occurredAt": "발생 시각", + "traceback": "Traceback", + "close": "닫기" + } +} diff --git a/dashboard/src/i18n/locales/ko-KR/features/provider.json b/dashboard/src/i18n/locales/ko-KR/features/provider.json new file mode 100644 index 0000000000..0df4e95e4d --- /dev/null +++ b/dashboard/src/i18n/locales/ko-KR/features/provider.json @@ -0,0 +1,165 @@ +{ + "title": "공급자", + "subtitle": "\"채팅 완성(Chat Completion)\"에서 채팅 모델을 구성할 수 있습니다. 또한 \"에이전트 러너(Agent Runner)\"에는 Dify, Coze, Alibaba Bailian(DashScope) 등 서드파티 서비스와의 연동이 포함됩니다.", + "providers": { + "title": "서비스 공급자", + "settings": "설정", + "addProvider": "공급자 추가", + "providerType": "공급자 유형", + "tabs": { + "all": "전체", + "chatCompletion": "채팅 완성", + "agentRunner": "에이전트 러너", + "speechToText": "음성 인식", + "textToSpeech": "음성 합성", + "embedding": "임베딩", + "rerank": "재순위화" + }, + "empty": { + "all": "사용 가능한 서비스 공급자가 없습니다. 공급자 추가를 클릭해 추가하세요", + "typed": "사용 가능한 {type} 유형의 서비스 공급자가 없습니다. 공급자 추가를 클릭해 추가하세요" + }, + "description": { + "openai": "모든 OpenAI API 호환 공급자를 지원합니다.", + "kimi_code": "사용자 지정 Anthropic API 어댑터를 사용하는 전용 Kimi CodingPlan / Kimi Code 연동입니다.", + "default": "" + } + }, + "availability": { + "title": "공급자 가용성", + "subtitle": "모델 대화 가용성을 테스트하여 판단하며, API 비용이 발생할 수 있습니다", + "refresh": "상태 새로고침", + "noData": "\"상태 새로고침\" 버튼을 클릭해 서비스 공급자 가용성을 확인하세요", + "available": "사용 가능", + "unavailable": "사용 불가", + "pending": "확인 중...", + "errorMessage": "오류 메시지", + "test": "테스트" + }, + "logs": { + "title": "서비스 로그", + "expand": "펼치기", + "collapse": "접기" + }, + "dialogs": { + "addProvider": { + "title": "서비스 공급자", + "tabs": { + "basic": "기본", + "agentRunner": "에이전트 러너", + "speechToText": "음성 인식", + "textToSpeech": "음성 합성", + "embedding": "임베딩", + "rerank": "재순위화" + }, + "noTemplates": "이 유형의 공급자 템플릿이 없습니다" + }, + "config": { + "addTitle": "추가", + "editTitle": "편집", + "provider": "서비스 공급자", + "cancel": "취소", + "save": "저장" + }, + "settings": { + "title": "서비스 공급자 설정", + "sessionSeparation": { + "title": "공급자 세션 분리 사용", + "description": "세션마다 텍스트 생성, TTS, STT 등의 서비스 공급자를 독립적으로 선택할 수 있습니다." + }, + "close": "닫기" + } + }, + "messages": { + "success": { + "update": "업데이트되었습니다!", + "add": "추가되었습니다!", + "delete": "삭제되었습니다!", + "statusUpdate": "상태가 업데이트되었습니다!", + "sessionSeparation": "세션 분리 설정이 업데이트되었습니다" + }, + "error": { + "sessionSeparation": "세션 분리 설정을 가져오지 못했습니다", + "fetchStatus": "서비스 공급자 상태를 가져오지 못했습니다", + "testError": "{id} 테스트에 실패했습니다: {error}" + }, + "confirm": { + "delete": "서비스 공급자 {id}을(를) 삭제하시겠습니까?" + } + }, + "providerTypes": { + "title": "공급자 유형" + }, + "providerSources": { + "title": "공급자 소스", + "add": "추가", + "delete": "공급자 소스 삭제", + "empty": "공급자 소스가 없습니다", + "selectHint": "공급자 소스를 선택하세요", + "selectCreated": "생성된 공급자 소스 선택", + "save": "설정 저장", + "saveAndFetchModels": "저장 및 모델 가져오기", + "fetchModels": "모델 목록 가져오기", + "saveSuccess": "공급자 소스를 저장했습니다", + "saveError": "공급자 소스 저장에 실패했습니다", + "deleteConfirm": "공급자 소스 {id}을(를) 삭제하시겠습니까? 연결된 모든 모델 구성도 함께 삭제됩니다.", + "deleteSuccess": "공급자 소스를 삭제했습니다", + "deleteError": "공급자 소스 삭제에 실패했습니다", + "enabled": "사용 중", + "disabled": "사용 안 함", + "advancedConfig": "고급 설정...", + "fields": { + "name": "이름", + "apiKey": "API 키", + "baseUrl": "기본 URL" + }, + "hints": { + "id": "공급자 소스 ID(공급자 ID 아님)", + "key": "인증용 API 키", + "apiBase": "사용자 지정 API 엔드포인트 URL", + "proxy": "HTTP/HTTPS 프록시 주소(예: http://127.0.0.1:7890). 이 공급자의 API 요청에만 영향을 주며 Docker 내부 네트워킹에는 영향을 주지 않습니다." + }, + "labels": { + "proxy": "프록시" + } + }, + "models": { + "title": "모델", + "available": "사용 가능한 모델", + "configured": "구성된 모델", + "empty": "아직 구성된 모델이 없습니다. 위의 \"모델 가져오기\"를 클릭해 추가하세요.", + "noModelsFound": "사용 가능한 모델을 찾을 수 없습니다", + "fetchError": "모델을 가져오지 못했습니다", + "addSuccess": "모델 {model}을(를) 추가했습니다", + "deleteConfirm": "모델 {id}을(를) 삭제하시겠습니까?", + "deleteSuccess": "모델을 삭제했습니다", + "deleteError": "모델 삭제에 실패했습니다", + "testSuccess": "모델 {id} 테스트를 통과했습니다", + "testSuccessWithLatency": "모델 {id} 테스트를 통과했습니다. 지연 시간 {latency}ms", + "testError": "모델 테스트에 실패했습니다", + "searchPlaceholder": "모델 또는 ID 검색", + "manualAddButton": "사용자 지정 모델", + "manualDialogTitle": "사용자 지정 모델 추가", + "manualDialogModelLabel": "모델 ID (예: gpt-4.1-mini)", + "manualDialogPreviewLabel": "표시 ID (자동 생성)", + "manualDialogPreviewHint": "sourceId/modelId 형태로 생성됩니다", + "manualModelRequired": "모델 ID를 입력하세요", + "manualModelExists": "이미 존재하는 모델입니다", + "configure": "설정", + "testButton": "모델 테스트", + "metadata": { + "image": "이미지 입력", + "audio": "오디오 입력", + "toolUse": "도구 사용", + "reasoning": "추론", + "context": "{tokens} 컨텍스트 윈도우", + "available": "모델 메타데이터가 {capability}을(를) 지원합니다", + "enabled": "{capability} 사용 중", + "supportedDisabled": "모델 메타데이터가 {capability}을(를) 지원하지만, 이 공급자의 모달리티에서는 사용하지 않음으로 설정되어 있습니다." + }, + "tooltips": { + "providerId": "공급자 ID", + "modelId": "모델 ID" + } + } +} diff --git a/dashboard/src/i18n/locales/ko-KR/features/session-management.json b/dashboard/src/i18n/locales/ko-KR/features/session-management.json new file mode 100644 index 0000000000..cb96c8bd2a --- /dev/null +++ b/dashboard/src/i18n/locales/ko-KR/features/session-management.json @@ -0,0 +1,158 @@ +{ + "title": "사용자 지정 규칙", + "subtitle": "특정 세션에 대한 사용자 지정 규칙을 설정하며, 전역 설정보다 우선 적용됩니다", + "buttons": { + "refresh": "새로고침", + "edit": "편집", + "editRule": "규칙 편집", + "deleteAllRules": "모든 규칙 삭제", + "addRule": "규칙 추가", + "save": "저장", + "cancel": "취소", + "delete": "삭제", + "clear": "지우기", + "next": "다음", + "editCustomName": "메모 편집", + "batchDelete": "일괄 삭제" + }, + "customRules": { + "title": "사용자 지정 규칙", + "rulesCount": "규칙", + "hasRules": "구성됨", + "noRules": "사용자 지정 규칙 없음", + "noRulesDesc": "'규칙 추가'를 클릭해 특정 세션에 대한 사용자 지정 규칙을 구성하세요", + "serviceConfig": "서비스 구성", + "pluginConfig": "플러그인 구성", + "kbConfig": "지식 베이스", + "providerConfig": "공급자 구성", + "configured": "구성됨", + "noCustomName": "설정된 메모 없음" + }, + "quickEditName": { + "title": "메모 편집" + }, + "search": { + "placeholder": "세션 검색..." + }, + "table": { + "headers": { + "umoInfo": "통합 메시지 출처", + "rulesOverview": "규칙 개요", + "actions": "작업" + } + }, + "persona": { + "none": "구성 따르기" + }, + "provider": { + "followConfig": "구성 따르기" + }, + "addRule": { + "title": "사용자 지정 규칙 추가", + "description": "규칙을 구성할 세션(UMO)을 선택하세요. 사용자 지정 규칙은 전역 설정보다 우선 적용됩니다.", + "selectUmo": "세션 선택", + "noUmos": "사용 가능한 세션 없음" + }, + "ruleEditor": { + "title": "사용자 지정 규칙 편집", + "description": "이 세션에 대한 사용자 지정 규칙을 구성하세요. 이 규칙은 전역 설정보다 우선 적용됩니다.", + "serviceConfig": { + "title": "서비스 구성", + "sessionEnabled": "세션 활성화", + "llmEnabled": "LLM 활성화", + "ttsEnabled": "TTS 활성화", + "customName": "사용자 지정 이름" + }, + "providerConfig": { + "title": "공급자 구성", + "chatProvider": "채팅 공급자", + "sttProvider": "STT 공급자", + "ttsProvider": "TTS 공급자" + }, + "personaConfig": { + "title": "페르소나 구성", + "selectPersona": "페르소나 선택", + "hint": "페르소나 설정은 LLM의 대화 스타일과 동작 방식에 영향을 줍니다" + }, + "pluginConfig": { + "title": "플러그인 구성", + "disabledPlugins": "비활성화된 플러그인", + "hint": "이 세션에서 비활성화할 플러그인을 선택하세요. 선택하지 않은 플러그인은 계속 활성화된 상태로 유지됩니다." + }, + "kbConfig": { + "title": "지식 베이스 구성", + "selectKbs": "지식 베이스 선택", + "topK": "Top K 결과 수", + "enableRerank": "재순위 사용" + } + }, + "deleteConfirm": { + "title": "삭제 확인", + "message": "이 세션의 모든 사용자 지정 규칙을 삭제하시겠습니까? 삭제 후에는 전역 설정이 적용됩니다." + }, + "batchDeleteConfirm": { + "title": "일괄 삭제 확인", + "message": "선택한 규칙 {count}개를 삭제하시겠습니까? 삭제 후에는 전역 설정이 적용됩니다." + }, + "batchOperations": { + "title": "일괄 작업", + "hint": "세션 설정을 빠르게 일괄 수정하세요", + "scope": "적용 대상", + "scopeSelected": "선택한 세션", + "scopeAll": "모든 세션", + "scopeGroup": "모든 그룹", + "scopePrivate": "모든 개인 채팅", + "llmStatus": "LLM 상태", + "ttsStatus": "TTS 상태", + "chatProvider": "채팅 모델", + "ttsProvider": "TTS 모델", + "apply": "변경 사항 적용" + }, + "groups": { + "title": "그룹 관리", + "count": "그룹 {count}개", + "addToGroup": "그룹에 추가", + "create": "그룹 생성", + "edit": "그룹 편집", + "name": "그룹 이름", + "sessionsCount": "세션 {count}개", + "empty": "아직 그룹이 없습니다. '그룹 생성'을 클릭해 만들어 보세요.", + "availableSessions": "사용 가능한 세션 ({count})", + "selectedSessions": "선택한 세션 ({count})", + "searchPlaceholder": "검색...", + "noMatch": "일치하는 항목 없음", + "noMembers": "구성원 없음", + "customGroupDivider": "── 사용자 지정 그룹 ──", + "customGroupOption": "📁 {name} ({count})", + "groupOption": "{name} ({count}개 세션)", + "deleteConfirm": "\"{name}\" 그룹을 삭제하시겠습니까?" + }, + "status": { + "enabled": "활성화됨", + "disabled": "비활성화됨" + }, + "messages": { + "refreshSuccess": "데이터가 새로고침되었습니다", + "loadError": "데이터 불러오기 실패", + "saveSuccess": "저장되었습니다", + "saveError": "저장 실패", + "clearSuccess": "지워졌습니다", + "clearError": "지우기 실패", + "deleteSuccess": "삭제되었습니다", + "deleteError": "삭제 실패", + "noChanges": "저장할 변경 사항 없음", + "batchDeleteSuccess": "일괄 삭제 성공", + "batchDeleteError": "일괄 삭제 실패", + "selectSessionsFirst": "먼저 세션을 선택해 주세요", + "selectAtLeastOneConfig": "수정할 설정을 하나 이상 선택해 주세요", + "batchUpdateSuccess": "일괄 업데이트 성공", + "partialUpdateFailed": "일부 업데이트 실패", + "batchUpdateError": "일괄 업데이트 실패", + "groupNameRequired": "그룹 이름은 비워둘 수 없습니다", + "saveGroupError": "그룹 저장 실패", + "deleteGroupError": "그룹 삭제 실패", + "selectSessionsToAddFirst": "먼저 추가할 세션을 선택해 주세요", + "addToGroupSuccess": "세션 {count}개를 그룹에 추가했습니다", + "addToGroupError": "그룹에 추가 실패" + } +} diff --git a/dashboard/src/i18n/locales/ko-KR/features/settings.json b/dashboard/src/i18n/locales/ko-KR/features/settings.json new file mode 100644 index 0000000000..ba2d26d021 --- /dev/null +++ b/dashboard/src/i18n/locales/ko-KR/features/settings.json @@ -0,0 +1,268 @@ +{ + "page": { + "title": "설정" + }, + "sections": { + "general": { + "title": "일반" + }, + "appearance": { + "title": "화면" + }, + "network": { + "title": "네트워크" + }, + "security": { + "title": "보안" + }, + "maintenance": { + "title": "유지 관리" + }, + "openapi": { + "title": "OpenAPI" + } + }, + "systemConfig": { + "restartRequired": "시스템 설정이 저장되었습니다. 일부 변경 사항은 AstrBot을 재시작해야 적용됩니다.", + "groups": { + "runtime": { + "title": "런타임 기본 설정", + "subtitle": "시간대와 외부에서 접근 가능한 콜백 URL입니다." + }, + "network": { + "title": "프록시 및 의존성 소스", + "subtitle": "런타임 프록시, Python 의존성 설치 옵션, PyPI 소스입니다." + }, + "webuiSecurity": { + "title": "WebUI 보안", + "subtitle": "HTTPS, 신뢰할 수 있는 프록시 헤더, 로그인 속도 제한, TOTP입니다." + }, + "logs": { + "title": "로그", + "subtitle": "콘솔 로그, 파일 로그, Trace 파일 로깅입니다." + }, + "tempStorage": { + "title": "캐시", + "subtitle": "임시 디렉터리의 자동 정리 임계값입니다." + }, + "t2iRendering": { + "title": "텍스트-이미지 변환", + "subtitle": "텍스트-이미지 변환의 렌더링 전략, 엔드포인트, 사용자 지정 템플릿입니다." + } + }, + "messages": { + "loadFailed": "시스템 설정을 불러오지 못했습니다", + "saveSuccess": "시스템 설정을 저장했습니다", + "saveFailed": "시스템 설정 저장에 실패했습니다" + } + }, + "network": { + "title": "네트워크", + "githubProxy": { + "title": "GitHub 프록시 주소", + "subtitle": "플러그인을 다운로드하거나 AstrBot을 업데이트할 때 사용할 GitHub 프록시 주소를 설정합니다. 중국 본토 네트워크 환경에서 효과적입니다. 사용자 지정이 가능하며 입력이 실시간으로 적용됩니다. 모든 주소의 안정성은 보장되지 않습니다. 플러그인/프로젝트 업데이트 시 오류가 발생하면 먼저 프록시 주소가 정상 작동하는지 확인하세요.", + "label": "GitHub 프록시 주소 선택" + }, + "proxySelector": { + "title": "GitHub 프록시", + "noProxy": "GitHub 프록시 사용 안 함", + "useProxy": "GitHub 프록시 사용", + "testConnection": "연결 테스트", + "available": "사용 가능", + "unavailable": "사용 불가", + "custom": "사용자 지정" + } + }, + "theme": { + "title": "테마", + "subtitle": "테마의 주 색상과 보조 색상을 사용자 지정합니다. 변경 사항은 즉시 적용되며 브라우저에 로컬로 저장됩니다.", + "customize": { + "title": "테마 색상", + "primary": "주 색상", + "secondary": "보조 색상", + "reset": "기본값으로 재설정" + } + }, + "system": { + "title": "시스템", + "restart": { + "title": "재시작", + "subtitle": "AstrBot 재시작", + "confirm": "지금 AstrBot을 재시작하시겠습니까? 재시작하는 동안 WebUI를 일시적으로 사용할 수 없습니다.", + "button": "재시작" + }, + "backup": { + "title": "백업 및 복원", + "subtitle": "새 서버로 손쉽게 마이그레이션할 수 있도록 모든 AstrBot 데이터를 내보내거나 가져옵니다", + "button": "백업 관리자" + }, + "cleanup": { + "title": "로그 및 캐시 정리", + "subtitle": "로그와 캐시의 디스크 사용량을 확인하고, 셸 명령 없이 UI에서 바로 정리하세요.", + "refresh": "사용량 새로고침", + "clean": "정리", + "cleanAll": "전체 정리", + "panel": { + "title": "정리 상세", + "subtitle": "현재 사용량: {size}" + }, + "fileCount": "{count}개 파일", + "confirm": "지금 {target}을(를) 정리하시겠습니까?", + "targetNames": { + "cache": "캐시", + "logs": "로그", + "all": "로그 및 캐시" + }, + "targets": { + "cache": { + "title": "캐시", + "subtitle": "임시 파일, 플러그인 마켓 캐시, Skill 캐시를 제거합니다.", + "button": "캐시 정리" + }, + "logs": { + "title": "로그", + "subtitle": "순환된 로그를 제거하고 현재 활성 로그 파일을 잘라냅니다.", + "button": "로그 정리" + } + }, + "messages": { + "statusFailed": "저장소 사용량을 불러오지 못했습니다", + "cleanupSuccess": "{count}개 파일을 정리하여 {size}를 확보했습니다", + "cleanupFailed": "정리에 실패했습니다" + } + } + }, + "sidebar": { + "title": "사이드바", + "customize": { + "title": "사이드바 사용자 지정", + "subtitle": "모듈을 끌어서 순서를 바꾸거나 \"추가 기능\" 그룹 안팎으로 이동하세요. 설정은 브라우저에 로컬로 저장됩니다.", + "reset": "기본값으로 재설정", + "mainItems": "주요 모듈", + "moreItems": "추가 기능" + } + }, + "backup": { + "dialog": { + "title": "백업 관리자" + }, + "tabs": { + "export": "백업 내보내기", + "import": "백업 가져오기", + "list": "백업 목록" + }, + "export": { + "title": "백업 생성", + "description": "데이터베이스, 지식 베이스, 설정, 첨부 파일, Skills를 포함한 모든 데이터를 ZIP 백업 파일로 내보냅니다.", + "includes": "백업 포함 항목: 메인 데이터베이스, 지식 베이스(메타데이터 + 벡터 인덱스 + 문서), 설정 파일, 첨부 파일, Skills", + "button": "내보내기 시작", + "processing": "내보내는 중...", + "wait": "데이터를 패키징하는 중입니다. 잠시 기다려 주세요...", + "completed": "내보내기 완료!", + "download": "백업 다운로드", + "another": "새 백업 생성", + "failed": "내보내기 실패", + "retry": "재시도" + }, + "import": { + "title": "백업 가져오기", + "warning": "⚠️ 가져오기를 진행하면 기존 데이터가 삭제되고 덮어써집니다! 현재 데이터를 반드시 백업해 두세요.", + "selectFile": "백업 파일 선택 (.zip)", + "uploadAndCheck": "업로드 및 확인", + "uploading": "업로드 중...", + "uploadWait": "백업 파일을 업로드하는 중입니다. 잠시 기다려 주세요...", + "uploadInit": "업로드를 초기화하는 중...", + "uploadingChunks": "청크를 업로드하는 중...", + "uploadComplete": "업로드 완료, 파일을 병합하는 중...", + "checking": "백업 파일을 확인하는 중...", + "invalidBackup": "유효하지 않은 백업 파일입니다", + "backupContents": "백업 내용", + "tables": "개 테이블", + "knowledgeBases": "지식 베이스", + "configFiles": "설정 파일", + "confirmImport": "가져오기 확인", + "button": "가져오기 시작", + "processing": "가져오는 중...", + "wait": "데이터를 복원하는 중입니다. 잠시 기다려 주세요...", + "completed": "가져오기 완료!", + "restartRequired": "데이터를 성공적으로 가져왔습니다. 모든 변경 사항을 적용하려면 지금 바로 AstrBot을 재시작하는 것을 권장합니다.", + "restartNow": "지금 재시작", + "failed": "가져오기 실패", + "retry": "재시도", + "version": { + "backupVersion": "백업 버전", + "currentVersion": "현재 버전", + "backupTime": "백업 시각", + "matchTitle": "✅ 버전 일치", + "matchMessage": "가져오기를 진행하면 다음을 포함한 기존 데이터가 모두 삭제되고 덮어써집니다:\n• 메인 데이터베이스(대화, 설정 등)\n• 지식 베이스\n• 플러그인 및 플러그인 데이터\n• 설정 파일\n• Skills\n\n이 작업은 되돌릴 수 없습니다! 계속하시겠습니까?", + "minorDiffTitle": "⚠️ 버전 차이 경고", + "minorDiffMessage": "마이너 버전 차이는 일반적으로 가져올 수 있지만, 일부 데이터 구조가 변경될 수 있습니다.\n가져오기를 진행하면 기존 데이터가 모두 삭제되고 덮어써집니다!\n\n계속하시겠습니까?", + "majorDiffTitle": "⛔ 가져올 수 없음", + "majorDiffMessage": "메이저 버전 번호가 다릅니다. 메이저 버전이 다른 상태로 가져오면 데이터가 손상될 수 있습니다.\n동일한 메이저 버전의 AstrBot을 사용해 가져오세요." + } + }, + "list": { + "empty": "백업 파일이 없습니다", + "refresh": "목록 새로고침", + "confirmDelete": "이 백업 파일을 삭제하시겠습니까? 이 작업은 되돌릴 수 없습니다.", + "uploaded": "업로드됨", + "restore": "이 백업 복원", + "rename": "이름 변경", + "renameTitle": "백업 파일 이름 변경", + "newName": "새 파일 이름", + "renameHint": "파일 이름에는 영문자, 숫자, 밑줄, 하이픈, 마침표만 사용할 수 있습니다", + "renameRequired": "파일 이름을 입력하세요", + "renameInvalidChars": "파일 이름에 유효하지 않은 문자가 포함되어 있습니다", + "renameFailed": "이름 변경에 실패했습니다", + "ftpHint": "대용량 백업 파일은 FTP/SFTP를 통해 data/backups 디렉터리에 직접 업로드할 수도 있습니다" + } + }, + "apiKey": { + "title": "API 키", + "manageTitle": "개발자 액세스 키", + "subtitle": "외부 개발자가 공개 HTTP API를 호출할 수 있도록 API 키를 생성합니다.", + "name": "키 이름", + "expiresInDays": "만료 기한", + "expiryOptions": { + "day1": "1일", + "day7": "7일", + "day30": "30일", + "day90": "90일", + "permanent": "무제한" + }, + "permanentWarning": "영구 API 키는 위험도가 높습니다. 안전하게 보관하고 꼭 필요한 경우에만 사용하세요.", + "scopes": "권한 범위", + "create": "API 키 생성", + "revoke": "폐기", + "delete": "삭제", + "copy": "복사", + "docsLink": "문서 열기", + "plaintextHint": "지금 이 키를 저장해 두세요. 평문 키는 다시 표시되지 않습니다.", + "empty": "API 키가 없습니다", + "status": { + "active": "활성", + "inactive": "비활성" + }, + "table": { + "name": "이름", + "prefix": "접두사", + "scopes": "권한 범위", + "status": "상태", + "lastUsed": "마지막 사용", + "createdAt": "생성일", + "actions": "작업" + }, + "messages": { + "loadFailed": "API 키를 불러오지 못했습니다", + "scopeRequired": "권한 범위를 하나 이상 선택하세요", + "createSuccess": "API 키가 생성되었습니다", + "createFailed": "API 키 생성에 실패했습니다", + "revokeSuccess": "API 키가 폐기되었습니다", + "revokeFailed": "API 키 폐기에 실패했습니다", + "deleteSuccess": "API 키가 삭제되었습니다", + "deleteFailed": "API 키 삭제에 실패했습니다", + "copySuccess": "API 키가 복사되었습니다", + "copyFailed": "API 키 복사에 실패했습니다" + } + } +} diff --git a/dashboard/src/i18n/locales/ko-KR/features/stats.json b/dashboard/src/i18n/locales/ko-KR/features/stats.json new file mode 100644 index 0000000000..f3a338c9d9 --- /dev/null +++ b/dashboard/src/i18n/locales/ko-KR/features/stats.json @@ -0,0 +1,104 @@ +{ + "header": { + "eyebrow": "대시보드", + "title": "시스템 통계", + "subtitle": "플랫폼, 메시지, 모델 호출을 한눈에 확인합니다.", + "notUpdated": "아직 업데이트되지 않음" + }, + "ranges": { + "oneDay": "1일", + "threeDays": "3일", + "oneWeek": "1주" + }, + "rangeLabels": { + "oneDay": "최근 1일", + "threeDays": "최근 3일", + "oneWeek": "최근 1주" + }, + "overviewCards": { + "platformCount": { + "label": "플랫폼 인스턴스", + "note": "구성되어 있고 현재 실행 중인 플랫폼 인스턴스" + }, + "messageCount": { + "label": "메시지", + "note": "누적 메시지 총량" + }, + "todayModelCalls": { + "label": "오늘의 모델 호출", + "note": "토큰" + }, + "cpu": { + "label": "CPU", + "note": "AstrBot CPU 사용률" + }, + "memory": { + "label": "프로세스 메모리", + "note": "시스템 메모리 {systemMemory}" + }, + "uptime": { + "label": "가동 시간", + "note": "{startTime}에 시작됨" + } + }, + "messageOverview": { + "title": "메시지 개요", + "subtitle": "봇 메시지 통계" + }, + "messageTrend": { + "title": "메시지 추이", + "subtitle": "{range}, 시간별 집계", + "totalMessages": "총 메시지" + }, + "platformRanking": { + "title": "플랫폼 메시지 순위", + "subtitle": "{range}, 집계된 메시지 수 기준 정렬" + }, + "modelCalls": { + "title": "모델 호출", + "subtitle": "모델 호출 통계" + }, + "modelTrend": { + "title": "모델 호출 추이", + "subtitle": "모델 호출의 토큰 추이" + }, + "modelTotal": { + "title": "{range} 총 모델 호출", + "callCount": "{count}회 호출", + "avgTtft": "평균 TTFT", + "avgDuration": "평균 응답 시간", + "avgTpm": "평균 출력 TPM", + "successRate": "성공률" + }, + "modelRanking": { + "title": "{range} 모델 호출 순위", + "subtitle": "모델 호출 토큰 기준 정렬" + }, + "sessionRanking": { + "title": "{range} 세션 토큰 사용량 상위 10개", + "subtitle": "토큰 사용량 기준으로 정렬된 세션" + }, + "empty": { + "platformStats": "사용 가능한 플랫폼 메시지 통계가 없습니다.", + "modelCalls": "{range} 동안의 모델 호출 데이터가 없습니다.", + "sessionCalls": "{range} 동안의 세션 호출 데이터가 없습니다." + }, + "chart": { + "messages": "메시지", + "others": "기타" + }, + "units": { + "tokens": "토큰", + "tpm": "TPM", + "gb": "GB", + "mb": "MB", + "ms": "ms", + "hoursShort": "시간", + "minutesShort": "분", + "secondsShort": "초" + }, + "errors": { + "loadFailed": "통계를 불러오지 못했습니다. 잠시 후 다시 시도하세요.", + "rangeFailed": "통계 범위를 전환하지 못했습니다. 잠시 후 다시 시도하세요." + } +} diff --git a/dashboard/src/i18n/locales/ko-KR/features/subagent.json b/dashboard/src/i18n/locales/ko-KR/features/subagent.json new file mode 100644 index 0000000000..30b73096ee --- /dev/null +++ b/dashboard/src/i18n/locales/ko-KR/features/subagent.json @@ -0,0 +1,86 @@ +{ + "header": { + "eyebrow": "오케스트레이션" + }, + "page": { + "title": "서브 에이전트 오케스트레이션", + "beta": "실험적 기능", + "subtitle": "메인 LLM은 자체 도구를 직접 사용하거나 핸드오프를 통해 서브 에이전트에 작업을 위임할 수 있습니다." + }, + "actions": { + "refresh": "새로고침", + "save": "저장", + "add": "서브 에이전트 추가", + "expand": "펼치기", + "collapse": "접기", + "delete": "삭제", + "close": "닫기" + }, + "overview": { + "totalAgents": "전체 서브 에이전트", + "totalAgentsNote": "구성된 위임 에이전트", + "enabledAgents": "사용 중인 에이전트", + "enabledAgentsNote": "핸드오프 가능한 에이전트", + "mainOrchestration": "메인 오케스트레이션", + "boundPersonas": "연결된 페르소나", + "boundPersonasNote": "페르소나가 연결된 에이전트" + }, + "switches": { + "enable": "서브 에이전트 오케스트레이션 사용", + "enableHint": "서브 에이전트 기능을 사용합니다", + "dedupe": "메인 LLM 도구 중복 제거 (서브 에이전트와 중복되는 도구 숨기기)", + "dedupeHint": "메인 에이전트에서 중복 도구를 제거합니다" + }, + "description": { + "disabled": "사용 안 함: 서브 에이전트가 비활성화되며, 메인 LLM은 페르소나 규칙에 따라 도구를 마운트하여(기본값은 전체) 직접 호출합니다.", + "enabled": "사용 중: 메인 LLM은 자체 도구를 유지하면서 transfer_to_* 위임 도구를 마운트합니다. 중복 제거를 사용하면 서브 에이전트와 겹치는 도구가 메인 도구 세트에서 제거됩니다." + }, + "section": { + "title": "서브 에이전트", + "subtitle": "메인 LLM을 위한 위임 에이전트, 페르소나, 설명을 구성합니다", + "globalSettings": "전역 설정", + "agentSetup": "에이전트 설정" + }, + "cards": { + "statusEnabled": "사용 중", + "statusDisabled": "사용 안 함", + "unnamed": "이름 없는 서브 에이전트", + "transferPrefix": "transfer_to_{name}", + "switchLabel": "사용", + "previewTitle": "미리보기: 메인 LLM에 표시되는 핸드오프 도구", + "personaChip": "페르소나: {id}", + "personaPreview": "페르소나 미리보기", + "noDescription": "아직 설명이 없습니다", + "previewHint": "현재 선택된 페르소나를 검토하여 핸드오프 대상을 확인하세요." + }, + "form": { + "nameLabel": "에이전트 이름 (transfer_to_{name}에 사용됨)", + "nameHint": "소문자와 밑줄만 사용하며, 전역적으로 고유해야 합니다.", + "providerLabel": "채팅 공급자 (선택)", + "providerHint": "비워두면 전역 기본 공급자를 따릅니다.", + "personaLabel": "페르소나 선택", + "personaHint": "서브 에이전트는 선택한 페르소나의 시스템 설정과 도구를 상속받습니다.", + "descriptionLabel": "메인 LLM을 위한 설명 (핸드오프 결정에 사용됨)", + "descriptionHint": "메인 LLM에게 transfer_to_* 도구 설명으로 표시됩니다. 짧고 명확하게 작성하세요." + }, + "messages": { + "loadConfigFailed": "설정을 불러오지 못했습니다", + "loadPersonaFailed": "페르소나 목록을 불러오지 못했습니다", + "unsavedChangesNotice": "이 페이지에 저장하지 않은 변경 사항이 있습니다. 나가기 전에 저장하세요.", + "unsavedChangesLeaveConfirm": "저장하지 않은 변경 사항이 있습니다. 나가면 삭제됩니다. 계속하시겠습니까?", + "unsavedChangesReloadConfirm": "저장하지 않은 변경 사항이 있습니다. 새로고침하면 삭제됩니다. 계속하시겠습니까?", + "nameMissing": "이름이 없는 서브 에이전트가 있습니다", + "nameInvalid": "잘못된 서브 에이전트 이름: 소문자, 숫자, 밑줄만 사용할 수 있으며 문자로 시작해야 합니다", + "nameDuplicate": "중복된 서브 에이전트 이름: {name}", + "personaMissing": "서브 에이전트 {name}에 선택된 페르소나가 없습니다", + "saveSuccess": "저장 성공", + "saveFailed": "저장 실패", + "nameRequired": "이름은 필수입니다", + "namePattern": "소문자, 숫자, 밑줄만 사용할 수 있습니다" + }, + "empty": { + "title": "구성된 에이전트 없음", + "subtitle": "새 서브 에이전트를 추가하여 시작하세요", + "action": "첫 에이전트 생성" + } +} diff --git a/dashboard/src/i18n/locales/ko-KR/features/tool-use.json b/dashboard/src/i18n/locales/ko-KR/features/tool-use.json new file mode 100644 index 0000000000..817ca96fa8 --- /dev/null +++ b/dashboard/src/i18n/locales/ko-KR/features/tool-use.json @@ -0,0 +1,188 @@ +{ + "title": "함수 도구 관리", + "subtitle": "MCP 서버를 관리하고 사용 가능한 함수 도구를 확인합니다", + "tooltip": { + "info": "Function Calling과 MCP란?", + "marketplace": "커뮤니티에서 MCP 서버를 찾아보고 설치하세요", + "serverConfig": "MCP 서버(stdio) 설정은 다음 필드를 지원합니다:\ncommand: 명령어 이름(예: python 또는 uv)\nargs: 명령어 인자 배열(예: [\"run\", \"server.py\"])\nenv: 환경 변수 객체(예: {\"api_key\": \"abc\"})\ncwd: 작업 디렉터리 경로(예: /path/to/server)\nencoding: 출력 인코딩(기본값 utf-8)\nencoding_error_handler: 텍스트 인코딩 오류 처리기입니다. 기본값은 strict입니다.\n그 밖의 필드는 MCP 문서를 참조하세요\n⚠️ Docker로 AstrBot을 배포하는 경우, AstrBot이 마운트한 data 디렉터리에 MCP 서버를 설치했는지 확인하세요" + }, + "tabs": { + "local": "로컬 서버", + "marketplace": "MCP 마켓플레이스" + }, + "mcpServers": { + "title": "MCP 서버", + "description": "MCP 서버를 관리합니다", + "buttons": { + "refresh": "새로고침", + "add": "서버 추가", + "useTemplateStdio": "Stdio 템플릿", + "useTemplateStreamableHttp": "Streamable HTTP 템플릿", + "useTemplateSse": "SSE 템플릿", + "sync": "MCP 서버 동기화" + }, + "empty": "사용 가능한 MCP 서버가 없습니다. 서버 추가를 클릭해 추가하세요", + "status": { + "noTools": "사용 가능한 도구 없음", + "availableTools": "사용 가능한 도구", + "configSummary": "설정: {keys}", + "noConfig": "설정된 항목 없음" + } + }, + "functionTools": { + "title": "함수 도구", + "buttons": { + "view": "도구 보기" + }, + "search": "함수 도구 검색", + "empty": "사용 가능한 함수 도구가 없습니다", + "description": "함수 설명", + "parameters": "매개변수 목록", + "noParameters": "이 도구에는 매개변수가 없습니다", + "filter": { + "showBuiltin": "빌트인 도구 표시" + }, + "table": { + "paramName": "매개변수 이름", + "type": "유형", + "description": "설명", + "required": "필수", + "origin": "출처", + "originName": "출처 이름", + "readonly": "읽기 전용", + "permission": "권한", + "permissionAdmin": "관리자", + "permissionMember": "모든 사용자", + "permissionEveryone": "모든 사용자", + "permissionBuiltin": "시스템 빌트인", + "actions": "작업" + }, + "configTags": { + "tooltipTitle": "이 도구는 다음 이유로 설정 파일 {config}에서 사용 중입니다:", + "conditions": { + "truthy": "{key}이(가) 사용 중임", + "equals": "{key} = {expected}", + "in": "{key}이(가) {expected}와(과) 일치함", + "fallback": "{key}이(가) 현재 {actual}임" + } + }, + "summary": { + "total": "전체", + "active": "사용 중", + "inactive": "사용 안 함" + } + }, + "marketplace": { + "title": "MCP 서버 마켓플레이스", + "search": "서버 검색", + "buttons": { + "refresh": "새로고침", + "detail": "상세 정보", + "import": "가져오기" + }, + "loading": "MCP 서버 마켓플레이스를 불러오는 중...", + "empty": "사용 가능한 MCP 서버가 없습니다", + "status": { + "availableTools": "사용 가능한 도구 ({count})", + "noToolsInfo": "사용 가능한 도구 정보가 없습니다" + } + }, + "dialogs": { + "addServer": { + "title": "MCP 서버 추가", + "editTitle": "MCP 서버 편집", + "fields": { + "name": "서버 이름", + "nameRequired": "이름은 필수입니다", + "enable": "서버 사용", + "config": "서버 설정" + }, + "errors": { + "configEmpty": "설정은 비워둘 수 없습니다", + "jsonFormat": "JSON 형식 오류: {error}", + "jsonParse": "JSON 파싱 오류: {error}" + }, + "buttons": { + "cancel": "취소", + "save": "저장", + "testConnection": "연결 테스트", + "sync": "동기화" + }, + "tips": { + "timeoutConfig": "도구 호출 제한 시간은 설정 페이지에서 별도로 구성하세요", + "transportRecommendation": "Streamable HTTP 또는 SSE 모드를 우선 사용하세요. Stdio 모드는 AstrBot 호스트에서 로컬 프로세스를 시작하므로 신뢰할 수 있는 MCP 서버에만 사용해야 합니다." + } + }, + "serverDetail": { + "title": "서버 상세 정보", + "installConfig": "설치 설정", + "availableTools": "사용 가능한 도구", + "buttons": { + "close": "닫기", + "importConfig": "설정 가져오기" + } + }, + "confirmDelete": "서버 {name}을(를) 삭제하시겠습니까?" + }, + "syncProvider": { + "title": "MCP 서버 동기화", + "subtitle": "공급자로부터 MCP 서버 설정을 로컬로 동기화합니다", + "steps": { + "selectProvider": "1단계: 공급자 선택", + "configureAuth": "2단계: 인증 설정", + "syncServers": "3단계: 서버 동기화" + }, + "providers": { + "modelscope": "ModelScope", + "description": "ModelScope는 다양한 머신러닝 및 AI 서비스를 위한 MCP 서버를 제공하는 오픈 모델 커뮤니티입니다" + }, + "fields": { + "provider": "공급자 선택", + "accessToken": "액세스 토큰", + "tokenRequired": "액세스 토큰은 필수입니다", + "tokenHint": "ModelScope 액세스 토큰을 입력하세요" + }, + "buttons": { + "cancel": "취소", + "previous": "이전", + "next": "다음", + "sync": "동기화 시작", + "getToken": "토큰 발급받기" + }, + "status": { + "selectProvider": "MCP 서버 공급자를 선택하세요", + "enterToken": "계속하려면 액세스 토큰을 입력하세요", + "readyToSync": "서버 설정을 동기화할 준비가 되었습니다" + }, + "messages": { + "syncSuccess": "MCP 서버 동기화에 성공했습니다!", + "syncError": "동기화 실패: {error}", + "tokenHelp": "ModelScope 액세스 토큰은 어떻게 발급받나요? 오른쪽 버튼을 클릭해 안내를 확인하세요" + } + }, + "messages": { + "getServersError": "MCP 서버 목록을 가져오지 못했습니다: {error}", + "getToolsError": "함수 도구 목록을 가져오지 못했습니다: {error}", + "saveSuccess": "저장 성공!", + "saveError": "저장 실패: {error}", + "deleteSuccess": "삭제 성공!", + "deleteError": "삭제 실패: {error}", + "updateSuccess": "업데이트 성공!", + "updateError": "업데이트 실패: {error}", + "getMarketError": "MCP 마켓플레이스 서버 목록을 가져오지 못했습니다: {error}", + "importError": { + "noConfig": "이 서버에는 사용 가능한 설정이 없습니다", + "invalidFormat": "서버 설정 형식이 올바르지 않습니다", + "failed": "설정 가져오기에 실패했습니다: {error}" + }, + "configParseError": "설정 파싱 오류: {error}", + "noAvailableConfig": "사용 가능한 설정이 없습니다", + "toggleToolSuccess": "도구 상태를 전환했습니다!", + "toggleToolReadonly": "빌트인 도구는 읽기 전용이며 사용 여부를 전환할 수 없습니다.", + "toggleToolError": "도구 상태 전환에 실패했습니다: {error}", + "updateToolPermissionSuccess": "{name}의 권한이 업데이트되었습니다", + "updateToolPermissionFailed": "도구 권한 업데이트에 실패했습니다", + "updateToolPermissionBuiltin": "빌트인 도구는 도구별 권한 설정을 지원하지 않습니다.", + "testError": "연결 테스트 실패: {error}" + } +} diff --git a/dashboard/src/i18n/locales/ko-KR/features/trace.json b/dashboard/src/i18n/locales/ko-KR/features/trace.json new file mode 100644 index 0000000000..bcf2304c9d --- /dev/null +++ b/dashboard/src/i18n/locales/ko-KR/features/trace.json @@ -0,0 +1,10 @@ +{ + "title": "트레이스", + "autoScroll": { + "enabled": "자동 스크롤: 켜짐", + "disabled": "자동 스크롤: 꺼짐" + }, + "hint": "현재는 AstrBot 메인 에이전트의 일부 모델 호출 경로만 기록합니다. 이후 더 넓은 범위가 추가될 예정입니다.", + "recording": "기록 중", + "paused": "일시 정지됨" +} diff --git a/dashboard/src/i18n/locales/ko-KR/features/welcome.json b/dashboard/src/i18n/locales/ko-KR/features/welcome.json new file mode 100644 index 0000000000..4ef3637835 --- /dev/null +++ b/dashboard/src/i18n/locales/ko-KR/features/welcome.json @@ -0,0 +1,51 @@ +{ + "greeting": { + "morning": "좋은 아침입니다, AstrBot에 오신 것을 환영합니다", + "afternoon": "좋은 오후입니다, AstrBot에 오신 것을 환영합니다", + "evening": "좋은 저녁입니다, AstrBot에 오신 것을 환영합니다", + "newYear": "새해 복 많이 받으세요!" + }, + "subtitle": "먼저 기본적인 온보딩을 완료할 수 있습니다. 플랫폼과 채팅 공급자 설정은 모두 건너뛸 수 있습니다.", + "announcement": { + "title": "공지사항" + }, + "onboard": { + "title": "빠른 온보딩", + "subtitle": "환영 페이지에서 바로 초기 설정을 완료하세요.", + "step1Title": "AI 모델 설정", + "step1Desc": "AstrBot에서 사용할 AI 모델을 설정합니다.", + "step2Title": "플랫폼 봇 설정", + "step2Desc": "AstrBot을 QQ, Lark, Slack, Telegram 등 메신저 플랫폼에 연결합니다.", + "step3Title": "에이전트의 컴퓨터 사용 허용", + "step3Desc": "에이전트가 이 컴퓨터에 접근하고 사용할 수 있는지 설정합니다.", + "step3HelpTitle": "접근 권한 상세", + "step3HelpItem1": "에이전트는 사용자별로 격리된 워크스페이스 디렉터리에 접근하고 사용할 수 있으며, 더 복잡한 작업을 처리하기 위해 Skills도 사용할 수 있습니다.", + "step3HelpItem2": "AstrBot 관리자의 경우, 에이전트가 셸 명령 실행, Python 코드 실행, 이 컴퓨터의 모든 로컬 디렉터리 접근까지 추가로 허용됩니다.", + "step3HelpClose": "닫기", + "step3SelectLabel": "컴퓨터 접근", + "step3Allow": "허용", + "step3Deny": "허용 안 함", + "configure": "설정", + "save": "저장", + "skip": "건너뛰기", + "pending": "대기 중", + "completed": "완료됨", + "skipped": "건너뜀", + "platformLoadFailed": "플랫폼 설정을 불러오지 못했습니다", + "providerLoadFailed": "공급자 설정을 불러오지 못했습니다", + "providerUpdateFailed": "설정 파일 \"default\"의 기본 채팅 공급자 업데이트에 실패했습니다", + "providerDefaultUpdated": "설정 파일 \"default\"의 기본 채팅 공급자가 {id}(으)로 설정되었습니다", + "computerAccessUpdateFailed": "에이전트의 컴퓨터 접근 권한 업데이트에 실패했습니다", + "computerAccessAllowed": "이제 에이전트가 이 컴퓨터에 접근하고 사용할 수 있습니다", + "computerAccessDenied": "이제 에이전트가 이 컴퓨터에 접근하고 사용할 수 없습니다", + "step3HelpItem3": "더 세밀한 제어가 필요하면 설정 -> 일반 -> 컴퓨터 접근에서 컴퓨터 접근 옵션을 구성하세요." + }, + "resources": { + "title": "리소스", + "githubDesc": "우리에게 별을 눌러주세요!", + "docsTitle": "문서", + "docsDesc": "AstrBot 공식 문서를 읽어보세요.", + "afdianTitle": "Afdian", + "afdianDesc": "Afdian에서 AstrBot 팀을 후원하세요." + } +} diff --git a/dashboard/src/i18n/locales/ko-KR/messages/errors.json b/dashboard/src/i18n/locales/ko-KR/messages/errors.json new file mode 100644 index 0000000000..881cb04f97 --- /dev/null +++ b/dashboard/src/i18n/locales/ko-KR/messages/errors.json @@ -0,0 +1,39 @@ +{ + "network": { + "timeout": "네트워크 요청 시간이 초과되었습니다. 잠시 후 다시 시도해주세요", + "connection": "네트워크 연결에 실패했습니다. 네트워크 상태를 확인해주세요", + "server": "서버 오류가 발생했습니다. 기술 지원팀에 문의해주세요", + "unavailable": "서비스를 일시적으로 사용할 수 없습니다", + "forbidden": "접근이 거부되었습니다" + }, + "validation": { + "required": "필수 입력 항목입니다", + "invalid": "입력 형식이 올바르지 않습니다", + "tooLong": "입력값이 너무 깁니다", + "tooShort": "입력값이 너무 짧습니다", + "email": "올바른 이메일 주소를 입력해주세요", + "url": "올바른 URL을 입력해주세요", + "number": "올바른 숫자를 입력해주세요" + }, + "auth": { + "unauthorized": "인증되지 않은 접근입니다. 다시 로그인해주세요", + "forbidden": "이 작업을 수행할 권한이 없습니다", + "tokenExpired": "로그인이 만료되었습니다. 다시 로그인해주세요", + "invalidCredentials": "사용자 이름 또는 비밀번호가 올바르지 않습니다" + }, + "file": { + "uploadFailed": "파일 업로드에 실패했습니다", + "invalidFormat": "지원하지 않는 파일 형식입니다", + "tooLarge": "파일 크기가 제한을 초과했습니다", + "notFound": "파일을 찾을 수 없습니다" + }, + "operation": { + "failed": "작업에 실패했습니다", + "cancelled": "작업이 취소되었습니다", + "notSupported": "지원하지 않는 작업입니다", + "conflict": "작업이 충돌했습니다. 잠시 후 다시 시도해주세요" + }, + "browser": { + "audioNotSupported": "브라우저가 오디오 재생을 지원하지 않습니다." + } +} diff --git a/dashboard/src/i18n/locales/ko-KR/messages/success.json b/dashboard/src/i18n/locales/ko-KR/messages/success.json new file mode 100644 index 0000000000..1c59a21753 --- /dev/null +++ b/dashboard/src/i18n/locales/ko-KR/messages/success.json @@ -0,0 +1,23 @@ +{ + "operation": { + "saved": "저장되었습니다", + "created": "생성되었습니다", + "updated": "수정되었습니다", + "deleted": "삭제되었습니다", + "uploaded": "업로드되었습니다", + "downloaded": "다운로드되었습니다", + "imported": "가져오기가 완료되었습니다", + "exported": "내보내기가 완료되었습니다", + "copied": "복사되었습니다", + "sent": "전송되었습니다" + }, + "connection": { + "connected": "연결되었습니다", + "authenticated": "로그인되었습니다", + "synchronized": "동기화되었습니다" + }, + "validation": { + "valid": "검증을 통과했습니다", + "completed": "작업이 완료되었습니다" + } +} diff --git a/dashboard/src/i18n/locales/ko-KR/messages/validation.json b/dashboard/src/i18n/locales/ko-KR/messages/validation.json new file mode 100644 index 0000000000..648871ec32 --- /dev/null +++ b/dashboard/src/i18n/locales/ko-KR/messages/validation.json @@ -0,0 +1,25 @@ +{ + "required": "필수 입력 항목입니다", + "email": "올바른 이메일 주소를 입력해주세요", + "url": "올바른 URL을 입력해주세요", + "number": "올바른 숫자를 입력해주세요", + "min": "최소값은 {min}입니다", + "max": "최대값은 {max}입니다", + "minLength": "최소 길이는 {length}자입니다", + "maxLength": "최대 길이는 {length}자입니다", + "pattern": "형식이 올바르지 않습니다", + "unique": "이미 존재하는 값입니다", + "confirm": "두 항목이 일치하지 않습니다", + "fileSize": "파일 크기는 {size}MB를 초과할 수 없습니다", + "fileType": "지원하지 않는 파일 형식입니다", + "required_field": "필수 항목을 입력해주세요", + "invalid_format": "형식이 올바르지 않습니다", + "password_too_short": "비밀번호는 8자 이상이어야 합니다", + "password_too_weak": "비밀번호가 너무 취약합니다", + "invalid_phone": "올바른 전화번호를 입력해주세요", + "invalid_date": "올바른 날짜를 입력해주세요", + "date_range": "날짜 범위가 올바르지 않습니다", + "upload_failed": "파일 업로드에 실패했습니다", + "network_error": "네트워크 연결 오류가 발생했습니다. 다시 시도해주세요", + "operation_cannot_be_undone": "⚠️ 이 작업은 되돌릴 수 없으니 신중하게 선택해주세요!" +} diff --git a/dashboard/src/i18n/translations.ts b/dashboard/src/i18n/translations.ts index e2a12c2df4..e484c8963d 100644 --- a/dashboard/src/i18n/translations.ts +++ b/dashboard/src/i18n/translations.ts @@ -124,6 +124,47 @@ import ruRUErrors from './locales/ru-RU/messages/errors.json'; import ruRUSuccess from './locales/ru-RU/messages/success.json'; import ruRUValidation from './locales/ru-RU/messages/validation.json'; +// Korean translation +import koKRCommon from './locales/ko-KR/core/common.json'; +import koKRActions from './locales/ko-KR/core/actions.json'; +import koKRStatus from './locales/ko-KR/core/status.json'; +import koKRNavigation from './locales/ko-KR/core/navigation.json'; +import koKRHeader from './locales/ko-KR/core/header.json'; +import koKRShared from './locales/ko-KR/core/shared.json'; + +import koKRChat from './locales/ko-KR/features/chat.json'; +import koKRExtension from './locales/ko-KR/features/extension.json'; +import koKRConversation from './locales/ko-KR/features/conversation.json'; +import koKRSessionManagement from './locales/ko-KR/features/session-management.json'; +import koKRToolUse from './locales/ko-KR/features/tool-use.json'; +import koKRProvider from './locales/ko-KR/features/provider.json'; +import koKRPlatform from './locales/ko-KR/features/platform.json'; +import koKRConfig from './locales/ko-KR/features/config.json'; +import koKRConfigMetadata from './locales/ko-KR/features/config-metadata.json'; +import koKRConsole from './locales/ko-KR/features/console.json'; +import koKRTrace from './locales/ko-KR/features/trace.json'; +import koKRAbout from './locales/ko-KR/features/about.json'; +import koKRSettings from './locales/ko-KR/features/settings.json'; +import koKRAuth from './locales/ko-KR/features/auth.json'; +import koKRChart from './locales/ko-KR/features/chart.json'; +import koKRDashboard from './locales/ko-KR/features/dashboard.json'; +import koKRCron from './locales/ko-KR/features/cron.json'; +import koKRStats from './locales/ko-KR/features/stats.json'; +import koKRAlkaidIndex from './locales/ko-KR/features/alkaid/index.json'; +import koKRAlkaidKnowledgeBase from './locales/ko-KR/features/alkaid/knowledge-base.json'; +import koKRAlkaidMemory from './locales/ko-KR/features/alkaid/memory.json'; +import koKRKnowledgeBaseIndex from './locales/ko-KR/features/knowledge-base/index.json'; +import koKRKnowledgeBaseDetail from './locales/ko-KR/features/knowledge-base/detail.json'; +import koKRKnowledgeBaseDocument from './locales/ko-KR/features/knowledge-base/document.json'; +import koKRPersona from './locales/ko-KR/features/persona.json'; +import koKRCommand from './locales/ko-KR/features/command.json'; +import koKRSubagent from './locales/ko-KR/features/subagent.json'; +import koKRWelcome from './locales/ko-KR/features/welcome.json'; + +import koKRErrors from './locales/ko-KR/messages/errors.json'; +import koKRSuccess from './locales/ko-KR/messages/success.json'; +import koKRValidation from './locales/ko-KR/messages/validation.json'; + // 组装翻译对象 export const translations = { 'zh-CN': { @@ -272,7 +313,56 @@ export const translations = { success: ruRUSuccess, validation: ruRUValidation } + }, + 'ko-KR': { + core: { + common: koKRCommon, + actions: koKRActions, + status: koKRStatus, + navigation: koKRNavigation, + header: koKRHeader, + shared: koKRShared + }, + features: { + chat: koKRChat, + extension: koKRExtension, + conversation: koKRConversation, + 'session-management': koKRSessionManagement, + tooluse: koKRToolUse, + provider: koKRProvider, + platform: koKRPlatform, + config: koKRConfig, + 'config-metadata': koKRConfigMetadata, + console: koKRConsole, + trace: koKRTrace, + about: koKRAbout, + settings: koKRSettings, + auth: koKRAuth, + chart: koKRChart, + dashboard: koKRDashboard, + cron: koKRCron, + stats: koKRStats, + alkaid: { + index: koKRAlkaidIndex, + 'knowledge-base': koKRAlkaidKnowledgeBase, + memory: koKRAlkaidMemory + }, + 'knowledge-base': { + index: koKRKnowledgeBaseIndex, + detail: koKRKnowledgeBaseDetail, + document: koKRKnowledgeBaseDocument + }, + persona: koKRPersona, + command: koKRCommand, + subagent: koKRSubagent, + welcome: koKRWelcome + }, + messages: { + errors: koKRErrors, + success: koKRSuccess, + validation: koKRValidation + } } }; -export type TranslationData = typeof translations; +export type TranslationData = typeof translations;