anhuiqiang 2 недель назад
Родитель
Сommit
08127bc9a7
56 измененных файлов с 12142 добавлено и 374 удалено
  1. 4 0
      .antigravityrules
  2. 4 0
      .cursorrules
  3. 337 0
      apply_cjk_translations.js
  4. 332 0
      apply_cjk_translations.py
  5. 11000 0
      cjk_extract.json
  6. 45 0
      extract_cjk.js
  7. 31 0
      extract_cjk.py
  8. 1 1
      server/src/api/api.controller.ts
  9. 1 1
      server/src/api/api.service.ts
  10. 4 4
      server/src/chat/chat.service.ts
  11. 1 1
      server/src/common/constants.ts
  12. 3 3
      server/src/elasticsearch/elasticsearch.service.ts
  13. 10 10
      server/src/i18n/i18n.service.ts
  14. 26 26
      server/src/i18n/messages.ts
  15. 13 13
      server/src/knowledge-base/chunk-config.service.ts
  16. 5 5
      server/src/knowledge-base/embedding.service.ts
  17. 2 2
      server/src/knowledge-base/knowledge-base.controller.ts
  18. 3 3
      server/src/knowledge-base/knowledge-base.entity.ts
  19. 14 14
      server/src/knowledge-base/knowledge-base.service.ts
  20. 2 2
      server/src/knowledge-base/memory-monitor.service.ts
  21. 1 1
      server/src/knowledge-base/text-chunker.service.ts
  22. 1 1
      server/src/migrations/1737800000000-AddKnowledgeBaseEnhancements.ts
  23. 2 2
      server/src/model-config/dto/create-model-config.dto.ts
  24. 1 1
      server/src/model-config/model-config.entity.ts
  25. 4 4
      server/src/rag/rag.service.ts
  26. 1 1
      server/src/upload/upload.controller.ts
  27. 10 10
      server/src/vision-pipeline/vision-pipeline-cost-aware.service.ts
  28. 1 1
      server/src/vision/vision.service.ts
  29. 19 19
      web/components/ChatInterface.tsx
  30. 2 2
      web/components/CreateNoteFromPDFDialog.tsx
  31. 2 2
      web/components/FileGroupTags.tsx
  32. 5 5
      web/components/GroupManager.tsx
  33. 1 1
      web/components/GroupSelectionDrawer.tsx
  34. 6 6
      web/components/GroupSelector.tsx
  35. 2 2
      web/components/IndexingModalWithMode.tsx
  36. 2 2
      web/components/InputDrawer.tsx
  37. 20 20
      web/components/ModeSelector.tsx
  38. 20 20
      web/components/PDFPreview.tsx
  39. 3 3
      web/components/PDFSelectionTool.tsx
  40. 5 5
      web/components/SettingsModal.tsx
  41. 1 1
      web/components/Toast.tsx
  42. 17 2
      web/components/drawers/ImportTasksDrawer.tsx
  43. 2 2
      web/components/layouts/SidebarRail.tsx
  44. 3 3
      web/components/views/ChatView.tsx
  45. 10 10
      web/components/views/SettingsView.tsx
  46. 1 1
      web/contexts/ToastContext.tsx
  47. 1 1
      web/services/apiClient.ts
  48. 29 29
      web/services/chatService.ts
  49. 32 32
      web/services/chunkConfigService.ts
  50. 7 7
      web/services/geminiService.ts
  51. 7 7
      web/services/knowledgeGroupService.ts
  52. 5 5
      web/services/noteService.ts
  53. 2 2
      web/services/ocrService.ts
  54. 1 1
      web/services/ragService.ts
  55. 4 4
      web/services/uploadService.ts
  56. 74 74
      web/utils/translations.ts

+ 4 - 0
.antigravityrules

@@ -7,3 +7,7 @@
 2. **Internationalization (i18n)**:
    - All user-facing messages, API response messages, error messages, and UI text **MUST** guarantee internationalization support.
    - Do not use hardcoded string literals for messages. Always use the project's designated i18n service or translation utility with proper keys.
+
+3. **UI Notifications**:
+   - All popup messages, error alerts, and system notifications **MUST** uniformly use the toast component (e.g., via `useToast().showError()`, `showSuccess()`). 
+   - Never use native browser `window.alert()`.

+ 4 - 0
.cursorrules

@@ -7,3 +7,7 @@
 2. **Internationalization (i18n)**:
    - All user-facing messages, API response messages, error messages, and UI text **MUST** guarantee internationalization support.
    - Do not use hardcoded string literals for messages. Always use the project's designated i18n service or translation utility with proper keys.
+
+3. **UI Notifications**:
+   - All popup messages, error alerts, and system notifications **MUST** uniformly use the toast component (e.g., via `useToast().showError()`, `showSuccess()`). 
+   - Never use native browser `window.alert()`.

+ 337 - 0
apply_cjk_translations.js

@@ -0,0 +1,337 @@
+const fs = require('fs');
+const path = require('path');
+
+const directories = ['d:/workspace/AuraK/web', 'd:/workspace/AuraK/server/src'];
+const excludeDirs = ['node_modules', '.git', 'dist', '.next', 'dist-check', 'docs', 'data'];
+const extensions = ['.ts', '.tsx', '.js', '.jsx'];
+
+const translations = {
+    // ChatInterface.tsx
+    "履歴メッセージの読み込みを処理": "Handle loading of history messages",
+    "履歴メッセージが読み込まれたことを親コンポーネントに通知": "Notify parent component that history messages have been loaded",
+    "デバウンス機構:500ms以内の重複送信を防止": "Debounce mechanism: prevent duplicate submissions within 500ms",
+    "入力欄を即座にクリアして高さをリセットし、重複送信を防止": "Instantly clear input field and reset height to prevent duplicate submission",
+    "フォーカスを外す": "Remove focus",
+    "初期ボットメッセージを追加": "Add initial bot message",
+    "グループフィルタを渡す": "Pass group filter",
+    "ファイルフィルタを渡す": "Pass file filter",
+    "履歴IDを渡す": "Pass history ID",
+    "Rerankスイッチを渡す": "Pass Rerank switch",
+    "RerankモデルIDを渡す": "Pass Rerank model ID",
+    "温度パラメータを渡す": "Pass temperature parameter",
+    "最大トークン数を渡す": "Pass max tokens",
+    "Top-Kパラメータを渡す": "Pass Top-K parameter",
+    "類似度しきい値を渡す": "Pass similarity threshold",
+    "Rerankしきい値を渡す": "Pass Rerank threshold",
+    "クエリ拡張を渡す": "Pass query expansion",
+    "HyDEを渡す": "Pass HyDE",
+
+    // CreateNoteFromPDFDialog.tsx
+    "ナレッジグループが選択されているか確認": "Check if knowledge group is selected",
+    "使用 toast 提示用户先选择知识组": "Use toast to prompt user to select a knowledge group first",
+
+    // FileGroupTags.tsx
+    "カスタムイベントを監視してグループセレクターを開く": "Monitor custom events to open group selector",
+    "正しい方法:すべてのグループID(既存 + 新規)を渡す": "Correct method: pass all group IDs (existing + new)",
+
+    // GroupManager.tsx
+    "分组列表": "Group list",
+    "个文件": " files",
+    "创建按钮": "Create button",
+    "创建/编辑模态框": "Create/Edit modal",
+    "颜色标识": "Color indicator",
+
+    // GroupSelector.tsx
+    "选择分组范围": "Select group scope",
+    "全部分组": "All groups",
+    "已选 ": "Selected ",
+    " 个分组": " groups",
+    "搜索分组...": "Search groups...",
+    "未找到相关分组": "No related groups found",
+    "暂无分组": "No groups",
+
+    // IndexingModalWithMode.tsx
+    "ユーザーによる手動選択をマーク": "Mark manual selection by user",
+
+    // InputDrawer.tsx
+    "确定": "Confirm",
+    "取消": "Cancel",
+
+    // SidebarRail.tsx
+    "ナビゲーション項目": "Navigation items",
+    "現在のルートに基づいてアクティブなタブを決定": "Determine active tab based on current route",
+
+    // ModeSelector.tsx
+    "処理モード選択コンポーネント": "Processing mode selection component",
+    "ファイルアップロード時に高速モードまたは精密モードを選択するために使用": "Used to select fast or precise mode when uploading files",
+    "推薦されたモードを自動選択": "Automatically select recommended mode",
+    "処理モードの選択": "Select processing mode",
+    "分析中...": "Analyzing...",
+    "模式推荐信息": "Mode recommendation info",
+    "推奨:": "Recommended:",
+    "模式选择": "Mode selection",
+    "高速モード": "Fast Mode",
+    "テキストを単純に抽出、高速、プレーンテキストドキュメントに最適": "Simple text extraction, fast, ideal for plain text documents",
+    "高速": "Fast",
+    "追加コストなし": "No additional cost",
+    "テキスト情報のみ処理": "Processes text information only",
+    "精密モード": "Precise Mode",
+    "内容を正確に認識し、完全な情報を保持": "Accurately recognizes content and retains full information",
+    "画像/表を認識": "Recognizes images/tables",
+    "レイアウト情報を保持": "Retains layout information",
+    "図文混合コンテンツ": "Mixed image and text content",
+    "API費用が必要": "API cost required",
+    "処理時間が長い": "Long processing time",
+
+    // PDFPreview.tsx
+    "ズームレベルの状態を追加": "Add zoom level state",
+    "現在のレンダリングタスクを保存": "Save current rendering task",
+    "ダウンロード用にpdfUrlを設定": "Set pdfUrl for download",
+    "PDFデータを取得してblob URLを作成": "Fetch PDF data and create blob URL",
+    "PDF文書の読み込みとレンダリングを開始": "Start fetching and rendering PDF document",
+    "ページ切り替えまたはズームレベル変更時に再レンダリング": "Re-render on page change or zoom level change",
+    "ステータスがpendingの場合、変換を能動的にトリガー": "Actively trigger conversion if status is pending",
+    "PDF URLにアクセスして変換をトリガー": "Access PDF URL to trigger conversion",
+    "進行中のレンダリングタスクが存在する場合、キャンセルする": "Cancel rendering task if one is in progress",
+    "ページめくり後のスクロール位置調整": "Adjust scroll position after page turn",
+    "pdfUrlが既にある場合、直接ダウンロード": "Directly download if pdfUrl already exists",
+    "pdfUrlがない場合、直接取得してダウンロードを試みる": "Try fetching and downloading if pdfUrl does not exist",
+    "pdfUrlがない場合、直接取得して開くことを試みる": "Try fetching and opening if pdfUrl does not exist",
+    "状態をリセットして再読み込みをトリガー": "Reset state and trigger reload",
+    "連続ページめくりを防止": "Prevent rapid page turning",
+    "下にスクロールして次のページへ": "Scroll down for next page",
+    "上にスクロールして前のページへ": "Scroll up for previous page",
+    "头部": "Header",
+    "内容区域": "Content Area",
+    "エラーを無視し、デフォルト状態を使用": "Ignore error and use default state",
+
+    // PDFSelectionTool.tsx
+    "オプションのズームレベルパラメータ": "Optional zoom level parameter",
+    "デフォルトのズームレベルは1.0": "Default zoom level is 1.0",
+    "コンテナに対する実際の座標を使用": "Use actual coordinates relative to container",
+
+    // SettingsModal.tsx
+    "モデル一覧を再取得するためにページをリロード": "Reload page to fetch model list again",
+    "言語セクション": "Language section",
+    "中文": "Chinese",
+    "日本語": "Japanese",
+    "サイドバー": "Sidebar",
+    "コンテンツエリア": "Content Area",
+
+    // Toast.tsx
+    "等待动画完成": "Wait for animation to complete",
+
+    // ChatView.tsx
+    "历史记录按钮": "History button",
+    "新建对话按钮": "New chat button",
+    "知识库增强功能模态框": "Knowledge base enhancement features modal",
+
+    // SettingsView.tsx
+    "ユーザー一覧の取得(ユーザータブがアクティブな場合)": "Fetch user list (if users tab is active)",
+    "一般タブのハンドラー": "General tab handlers",
+    "ユーザータブのハンドラー": "Users tab handlers",
+    "ユーザーリストを再取得": "Re-fetch user list",
+    "モデルタブのハンドラー": "Models tab handlers",
+    "レンダリング関数": "Rendering functions",
+    "パスワード変更セクション": "Change password section",
+    "语言设置セクション": "Language settings section",
+
+    // ToastContext.tsx
+    "相同消息去重:如果已存在相同的消息(类型和内容相同),则先移除旧的": "Deduplicate identical messages: discard old one if current type and content are the same",
+
+    // apiClient.ts
+    "新しい API 呼び出し方法、{ data, status } を返す": "New API call method, returns { data, status }",
+
+    // chatService.ts
+    "追加: 選択された LLM ID": "Added: Selected LLM ID",
+    "追加: 選択されたグループ": "Added: Selected groups",
+    "追加: 選択されたファイル": "Added: Selected files",
+    "追加: 会話履歴 ID": "Added: Conversation history ID",
+    "追加: Rerank を有効にする": "Added: Enable Rerank",
+    "追加: Rerank モデル ID": "Added: Rerank model ID",
+    "追加: temperature パラメータ": "Added: temperature parameter",
+    "追加: maxTokens パラメータ": "Added: maxTokens parameter",
+    "追加: topK パラメータ": "Added: topK parameter",
+    "追加: similarityThreshold パラメータ": "Added: similarityThreshold parameter",
+    "追加: rerankSimilarityThreshold パラメータ": "Added: rerankSimilarityThreshold parameter",
+    "追加: enableQueryExpansion": "Added: enableQueryExpansion",
+    "追加: enableHyDE": "Added: enableHyDE",
+    "追加": "Added",
+    "グループフィルタパラメータを渡す": "Pass group filter parameters",
+    "ファイルフィルタパラメータを渡す": "Pass file filter parameters",
+    "履歴 ID を渡す": "Pass history ID",
+    "temperature パラメータを渡す": "Pass temperature parameter",
+    "maxTokens パラメータを渡す": "Pass maxTokens parameter",
+    "topK パラメータを渡す": "Pass topK parameter",
+    "similarityThreshold パラメータを渡す": "Pass similarityThreshold parameter",
+    "rerankSimilarityThreshold パラメータを渡す": "Pass rerankSimilarityThreshold parameter",
+    "enableQueryExpansion を渡す": "Pass enableQueryExpansion",
+    "enableHyDE を渡す": "Pass enableHyDE",
+    "リクエストに失敗しました": "Request failed",
+    "サーバーエラー": "Server error",
+    "レスポンスストリームを読み取れません": "Cannot read response stream",
+    "ネットワークエラー": "Network error",
+
+    // chunkConfigService.ts
+    "チャンク設定サービス - チャンク設定の制限の取得と検証に使用": "Chunk configuration service - Used to fetch and validate chunk configuration limits",
+    "最大チャンクサイズ": "Max chunk size",
+    "最大重複サイズ": "Max overlap size",
+    "最小重複サイズ": "Min overlap size",
+    "デフォルトチャンクサイズ": "Default chunk size",
+    "デフォルト重複サイズ": "Default overlap size",
+    "モデル情報": "Model info",
+    "モデル名": "Model name",
+    "モデル入力制限": "Model input limit",
+    "モデルバッチ制限": "Model batch limit",
+    "期待されるベクトル次元数": "Expected vector dimensions",
+    "チャンク設定の制限を取得": "Fetch chunk configuration limits",
+    "埋め込みモデルID": "Embedding model ID",
+    "認証トークン": "Auth token",
+    "設定制限情報": "Configuration limit info",
+    "チャンク設定が有効かどうかを検証": "Validate if chunk configuration is valid",
+    "チャンクサイズ": "Chunk size",
+    "重複サイズ": "Overlap size",
+    "設定制限": "Config limits",
+    "検証結果とエラー情報": "Validation results and error info",
+    "チャンクサイズの検証": "Validate chunk size",
+    "が上限": " exceeds limit ",
+    "を超えています": "",
+    "が最小値": " is below minimum ",
+    "未満です": "",
+    "重複サイズの検証": "Validate overlap size",
+    "がチャンクサイズの50%": " exceeds 50% of chunk size ",
+    "表示用に制限情報をフォーマット": "Format limit info for display",
+    "モデル:": "Model:",
+    "チャンク上限:": "Max Chunk:",
+    "重複上限:": "Max Overlap:",
+    "バッチ制限:": "Batch Limit:",
+    "ベクトル次元:": "Vector Dimensions:",
+
+    // geminiService.ts
+    "请始终使用中文回答。": "Please always answer in English.",
+    "常に日本語で答えてください。": "Please always answer in English.",
+    "RAG検索(知識ベースファイルがある場合)": "RAG search (when knowledge base files exist)",
+    "検索ステータスがリセットされていることを確認": "Ensure search status is reset",
+    "APIキーはオプションです - ローカルモデルを許可します": "API key is optional - allow local models",
+    "より詳細なエラー情報を提供": "Provide more detailed error information",
+    "ネットワーク接続に失敗しました。サーバーの状態を確認してください": "Network connection failed. Please check server status",
+
+    // knowledgeGroupService.ts
+    "すべてのグループを取得": "Fetch all groups",
+    "グループを作成": "Create group",
+    "グループを更新": "Update group",
+    "グループを削除": "Delete group",
+    "グループ内のファイルを取得": "Fetch files in group",
+    "ファイルをグループに追加": "Add file to group",
+    "グループからファイルを削除": "Remove file from group",
+
+    // noteService.ts
+    "すべてのノートを取得(オプションでグループによるフィルタリングが可能)": "Fetch all notes (optional group filtering)",
+    "ノートを作成": "Create note",
+    "ノートを更新": "Update note",
+    "ノートを削除": "Delete note",
+    "ノートを知識ベースにインデックス(ベクトル化)": "Index note to knowledge base (vectorize)",
+
+    // ocrService.ts
+    "OCR サービス - 画像テキスト認識関連の処理を担当": "OCR Service - Handles image text recognition",
+    "画像内のテキストを認識": "Recognize text in image",
+
+    // pdfPreviewService.ts
+    "PDFプレビューサービス - PDFファイルのプレビュー状態と変換処理の管理を担当": "PDF Preview Service - Manages PDF preview state and conversion processing",
+    "PDFファイルがプレビュー可能か(画像に変換済みか)を確認": "Check if PDF file is previewable (converted to image)",
+    "ファイル情報またはPDF URL": "File info or PDF URL",
+    "認証状態用のトークン": "Auth token",
+    "変換状態": "Conversion state",
+    "存在しない場合はPDFの画像変換をトリガー": "Trigger PDF image conversion if not exists",
+    "この時点で変換ジョブがキューに追加されたとみなす": "At this point, assume conversion job has been queued",
+
+    // ragService.ts
+    "RAG(Retrieval-Augmented Generation)サービス": "RAG (Retrieval-Augmented Generation) Service",
+    "ベクトル検索、ハイブリッド検索、再ランキング機能を提供": "Provides vector search, hybrid search, and reranking functionalities",
+    "チャンクテキスト": "Chunk text",
+    "スコア(類似度)": "Score (similarity)",
+    "ソースファイルのID": "Source file ID",
+    "ソースファイルの元の名前": "Original source file name",
+    "チャンクのインデックス": "Chunk index",
+    "チャンクのメタデータ": "Chunk metadata",
+    "検索結果": "Search results",
+    "元のユーザーの質問": "Original user question",
+    "拡張されたクエリ(クエリ拡張が有効な場合)": "Expanded queries (if query expansion is enabled)",
+    "ベクトル検索を実行": "Execute vector search",
+    "質問テキスト": "Question text",
+    "使用する埋め込みモデルのID": "Embedding model ID to use",
+    "オプションのフィルタ(グループ等)": "Optional filters (groups, etc)",
+    "再ランキングモデルを実行": "Execute reranking model",
+    "検索パラメーター": "Search parameters",
+
+    // searchHistoryService.ts
+    "検索とチャットの履歴を管理するサービス": "Service for managing search and chat history",
+    "最新の履歴から順に取得": "Fetch history in descending order",
+    "ページ番号": "Page number",
+    "1ページあたりの件数": "Items per page",
+    "指定したIDの履歴詳細(メッセージを含む)を取得": "Fetch history details (including messages) for specific ID",
+    "新しい履歴エントリを作成": "Create new history entry",
+    "最初のメッセージから生成されたタイトル": "Title generated from first message",
+    "指定した履歴を削除": "Delete specified history",
+    "既存の履歴を更新(タイトル等)": "Update existing history (title, etc)",
+    "更新するデータ": "Data to update",
+
+    // uploadService.ts
+    "チャンク設定付きでファイルをアップロード": "Upload file with chunk configuration",
+    "アップロードするファイル": "File to upload",
+    "テキストコンテンツを直接アップロードして処理": "Directly upload and process text content",
+    "テキストコンテンツ": "Text content",
+    "アップロード用のタイトル/ファイル名": "Title/filename for upload",
+    "チャンク設定": "Chunk configuration",
+    "ファイルモードの推奨を取得": "Get recommended file mode",
+
+    // Other Server files
+    "コストを重視したVision Pipelineを使用して画像をテキストに変換": "Convert image to text using cost-aware Vision Pipeline",
+
+    // translation_map.json
+    "      `💰 推定コスト: $${estimatedCost.toFixed(2)}, 推定時間: ${duration.toFixed(1)}s`\n    )": "      `💰 Estimated cost: $${estimatedCost.toFixed(2)}, Estimated time: ${duration.toFixed(1)}s`\n    )",
+    "    this.logger.log(`💰 推定コスト: $${estimatedCost.toFixed(2)}, 推定時間: ${duration.toFixed(1)}s`);": "    this.logger.log(`💰 Estimated cost: $${estimatedCost.toFixed(2)}, Estimated time: ${duration.toFixed(1)}s`);",
+    "チャンクサイズ ${chunkSize} が上限 ${limits.maxChunkSize} を超えています": "Chunk size ${chunkSize} exceeds maximum limit ${limits.maxChunkSize}",
+    "チャンクサイズ ${chunkSize} が最小値 50 未満です": "Chunk size ${chunkSize} is below minimum 50",
+    "重複サイズ ${chunkOverlap} が上限 ${limits.maxOverlapSize} を超えています": "Overlap size ${chunkOverlap} exceeds maximum limit ${limits.maxOverlapSize}",
+    "重複サイズ ${chunkOverlap} がチャンクサイズの50% (${maxOverlapByRatio}) を超えています": "Overlap size ${chunkOverlap} exceeds 50% of chunk size (${maxOverlapByRatio})"
+};
+
+function walkSync(currentDirPath, callback) {
+    fs.readdirSync(currentDirPath).forEach((name) => {
+        const filePath = path.join(currentDirPath, name);
+        const stat = fs.statSync(filePath);
+        if (stat.isFile()) {
+            callback(filePath);
+        } else if (stat.isDirectory() && !excludeDirs.includes(name)) {
+            walkSync(filePath, callback);
+        }
+    });
+}
+
+let modifiedCount = 0;
+
+directories.forEach(d => {
+    walkSync(d, (filePath) => {
+        if (extensions.some(ext => filePath.endsWith(ext))) {
+            try {
+                let content = fs.readFileSync(filePath, 'utf-8');
+                let originalContent = content;
+
+                for (const [key, value] of Object.entries(translations)) {
+                    content = content.split(key).join(value);
+                }
+
+                if (content !== originalContent) {
+                    fs.writeFileSync(filePath, content, 'utf-8');
+                    console.log(`Updated: ${filePath}`);
+                    modifiedCount++;
+                }
+            } catch (e) {
+                console.error(`Error reading ${filePath}: `, e);
+            }
+        }
+    });
+});
+
+console.log(`Updated ${modifiedCount} files`);

+ 332 - 0
apply_cjk_translations.py

@@ -0,0 +1,332 @@
+import os
+import re
+
+directories = ['d:/workspace/AuraK/web', 'd:/workspace/AuraK/server/src']
+exclude_dirs = ['node_modules', '.git', 'dist', '.next', 'dist-check', 'docs', 'data']
+extensions = ['.ts', '.tsx', '.js', '.jsx']
+
+cjk_pattern = re.compile(r'[\u4e00-\u9fff\u3040-\u309f\u30a0-\u30ff]+')
+
+translations = {
+    # ChatInterface.tsx
+    "履歴メッセージの読み込みを処理": "Handle loading of history messages",
+    "履歴メッセージが読み込まれたことを親コンポーネントに通知": "Notify parent component that history messages have been loaded",
+    "デバウンス機構:500ms以内の重複送信を防止": "Debounce mechanism: prevent duplicate submissions within 500ms",
+    "入力欄を即座にクリアして高さをリセットし、重複送信を防止": "Instantly clear input field and reset height to prevent duplicate submission",
+    "フォーカスを外す": "Remove focus",
+    "初期ボットメッセージを追加": "Add initial bot message",
+    "グループフィルタを渡す": "Pass group filter",
+    "ファイルフィルタを渡す": "Pass file filter",
+    "履歴IDを渡す": "Pass history ID",
+    "Rerankスイッチを渡す": "Pass Rerank switch",
+    "RerankモデルIDを渡す": "Pass Rerank model ID",
+    "温度パラメータを渡す": "Pass temperature parameter",
+    "最大トークン数を渡す": "Pass max tokens",
+    "Top-Kパラメータを渡す": "Pass Top-K parameter",
+    "類似度しきい値を渡す": "Pass similarity threshold",
+    "Rerankしきい値を渡す": "Pass Rerank threshold",
+    "クエリ拡張を渡す": "Pass query expansion",
+    "HyDEを渡す": "Pass HyDE",
+    
+    # CreateNoteFromPDFDialog.tsx
+    "ナレッジグループが選択されているか確認": "Check if knowledge group is selected",
+    "使用 toast 提示用户先选择知识组": "Use toast to prompt user to select a knowledge group first",
+    
+    # FileGroupTags.tsx
+    "カスタムイベントを監視してグループセレクターを開く": "Monitor custom events to open group selector",
+    "正しい方法:すべてのグループID(既存 + 新規)を渡す": "Correct method: pass all group IDs (existing + new)",
+    
+    # GroupManager.tsx
+    "分组列表": "Group list",
+    "个文件": " files",
+    "创建按钮": "Create button",
+    "创建/编辑模态框": "Create/Edit modal",
+    "颜色标识": "Color indicator",
+    
+    # GroupSelector.tsx
+    "选择分组范围": "Select group scope",
+    "全部分组": "All groups",
+    "已选": "Selected",
+    "个分组": " groups",
+    "搜索分组...": "Search groups...",
+    "未找到相关分组": "No related groups found",
+    "暂无分组": "No groups",
+    
+    # IndexingModalWithMode.tsx
+    "ユーザーによる手動選択をマーク": "Mark manual selection by user",
+    
+    # InputDrawer.tsx
+    "确定": "Confirm",
+    "取消": "Cancel",
+    
+    # SidebarRail.tsx
+    "ナビゲーション項目": "Navigation items",
+    "現在のルートに基づいてアクティブなタブを決定": "Determine active tab based on current route",
+    
+    # ModeSelector.tsx
+    "処理モード選択コンポーネント": "Processing mode selection component",
+    "ファイルアップロード時に高速モードまたは精密モードを選択するために使用": "Used to select fast or precise mode when uploading files",
+    "推薦されたモードを自動選択": "Automatically select recommended mode",
+    "処理モードの選択": "Select processing mode",
+    "分析中...": "Analyzing...",
+    "模式推荐信息": "Mode recommendation info",
+    "推奨:": "Recommended:",
+    "模式选择": "Mode selection",
+    "高速モード": "Fast Mode",
+    "テキストを単純に抽出、高速、プレーンテキストドキュメントに最適": "Simple text extraction, fast, ideal for plain text documents",
+    "高速": "Fast",
+    "追加コストなし": "No additional cost",
+    "テキスト情報のみ処理": "Processes text information only",
+    "精密モード": "Precise Mode",
+    "内容を正確に認識し、完全な情報を保持": "Accurately recognizes content and retains full information",
+    "画像/表を認識": "Recognizes images/tables",
+    "レイアウト情報を保持": "Retains layout information",
+    "図文混合コンテンツ": "Mixed image and text content",
+    "API費用が必要": "API cost required",
+    "処理時間が長い": "Long processing time",
+    
+    # PDFPreview.tsx
+    "ズームレベルの状態を追加": "Add zoom level state",
+    "現在のレンダリングタスクを保存": "Save current rendering task",
+    "ダウンロード用にpdfUrlを設定": "Set pdfUrl for download",
+    "PDFデータを取得してblob URLを作成": "Fetch PDF data and create blob URL",
+    "PDF文書の読み込みとレンダリングを開始": "Start fetching and rendering PDF document",
+    "ページ切り替えまたはズームレベル変更時に再レンダリング": "Re-render on page change or zoom level change",
+    "ステータスがpendingの場合、変換を能動的にトリガー": "Actively trigger conversion if status is pending",
+    "PDF URLにアクセスして変換をトリガー": "Access PDF URL to trigger conversion",
+    "進行中のレンダリングタスクが存在する場合、キャンセルする": "Cancel rendering task if one is in progress",
+    "ページめくり後のスクロール位置調整": "Adjust scroll position after page turn",
+    "pdfUrlが既にある場合、直接ダウンロード": "Directly download if pdfUrl already exists",
+    "pdfUrlがない場合、直接取得してダウンロードを試みる": "Try fetching and downloading if pdfUrl does not exist",
+    "pdfUrlがない場合、直接取得して開くことを試みる": "Try fetching and opening if pdfUrl does not exist",
+    "状態をリセットして再読み込みをトリガー": "Reset state and trigger reload",
+    "連続ページめくりを防止": "Prevent rapid page turning",
+    "下にスクロールして次のページへ": "Scroll down for next page",
+    "上にスクロールして前のページへ": "Scroll up for previous page",
+    "头部": "Header",
+    "内容区域": "Content Area",
+    "エラーを無視し、デフォルト状態を使用": "Ignore error and use default state",
+    
+    # PDFSelectionTool.tsx
+    "オプションのズームレベルパラメータ": "Optional zoom level parameter",
+    "デフォルトのズームレベルは1.0": "Default zoom level is 1.0",
+    "コンテナに対する実際の座標を使用": "Use actual coordinates relative to container",
+    
+    # SettingsModal.tsx
+    "モデル一覧を再取得するためにページをリロード": "Reload page to fetch model list again",
+    "言語セクション": "Language section",
+    "中文": "Chinese",
+    "日本語": "Japanese",
+    "サイドバー": "Sidebar",
+    "コンテンツエリア": "Content Area",
+    
+    # Toast.tsx
+    "等待动画完成": "Wait for animation to complete",
+    
+    # ChatView.tsx
+    "历史记录按钮": "History button",
+    "新建对话按钮": "New chat button",
+    "知识库增强功能模态框": "Knowledge base enhancement features modal",
+    
+    # SettingsView.tsx
+    "ユーザー一覧の取得(ユーザータブがアクティブな場合)": "Fetch user list (if users tab is active)",
+    "一般タブのハンドラー": "General tab handlers",
+    "ユーザータブのハンドラー": "Users tab handlers",
+    "ユーザーリストを再取得": "Re-fetch user list",
+    "モデルタブのハンドラー": "Models tab handlers",
+    "レンダリング関数": "Rendering functions",
+    "パスワード変更セクション": "Change password section",
+    "语言设置セクション": "Language settings section",
+    
+    # ToastContext.tsx
+    "相同消息去重:如果已存在相同的消息(类型和内容相同),则先移除旧的": "Deduplicate identical messages: discard old one if current type and content are the same",
+    
+    # apiClient.ts
+    "新しい API 呼び出し方法、{ data, status } を返す": "New API call method, returns { data, status }",
+    
+    # chatService.ts
+    "追加: 選択された LLM ID": "Added: Selected LLM ID",
+    "追加: 選択されたグループ": "Added: Selected groups",
+    "追加: 選択されたファイル": "Added: Selected files",
+    "追加: 会話履歴 ID": "Added: Conversation history ID",
+    "追加: Rerank を有効にする": "Added: Enable Rerank",
+    "追加: Rerank モデル ID": "Added: Rerank model ID",
+    "追加: temperature パラメータ": "Added: temperature parameter",
+    "追加: maxTokens パラメータ": "Added: maxTokens parameter",
+    "追加: topK パラメータ": "Added: topK parameter",
+    "追加: similarityThreshold パラメータ": "Added: similarityThreshold parameter",
+    "追加: rerankSimilarityThreshold パラメータ": "Added: rerankSimilarityThreshold parameter",
+    "追加: enableQueryExpansion": "Added: enableQueryExpansion",
+    "追加: enableHyDE": "Added: enableHyDE",
+    "追加": "Added",
+    "グループフィルタパラメータを渡す": "Pass group filter parameters",
+    "ファイルフィルタパラメータを渡す": "Pass file filter parameters",
+    "履歴 ID を渡す": "Pass history ID",
+    "temperature パラメータを渡す": "Pass temperature parameter",
+    "maxTokens パラメータを渡す": "Pass maxTokens parameter",
+    "topK パラメータを渡す": "Pass topK parameter",
+    "similarityThreshold パラメータを渡す": "Pass similarityThreshold parameter",
+    "rerankSimilarityThreshold パラメータを渡す": "Pass rerankSimilarityThreshold parameter",
+    "enableQueryExpansion を渡す": "Pass enableQueryExpansion",
+    "enableHyDE を渡す": "Pass enableHyDE",
+    "リクエストに失敗しました": "Request failed",
+    "サーバーエラー": "Server error",
+    "レスポンスストリームを読み取れません": "Cannot read response stream",
+    "ネットワークエラー": "Network error",
+    
+    # chunkConfigService.ts
+    "チャンク設定サービス - チャンク設定の制限の取得と検証に使用": "Chunk configuration service - Used to fetch and validate chunk configuration limits",
+    "最大チャンクサイズ": "Max chunk size",
+    "最大重複サイズ": "Max overlap size",
+    "最小重複サイズ": "Min overlap size",
+    "デフォルトチャンクサイズ": "Default chunk size",
+    "デフォルト重複サイズ": "Default overlap size",
+    "モデル情報": "Model info",
+    "モデル名": "Model name",
+    "モデル入力制限": "Model input limit",
+    "モデルバッチ制限": "Model batch limit",
+    "期待されるベクトル次元数": "Expected vector dimensions",
+    "チャンク設定の制限を取得": "Fetch chunk configuration limits",
+    "埋め込みモデルID": "Embedding model ID",
+    "認証トークン": "Auth token",
+    "設定制限情報": "Configuration limit info",
+    "チャンク設定が有効かどうかを検証": "Validate if chunk configuration is valid",
+    "チャンクサイズ": "Chunk size",
+    "重複サイズ": "Overlap size",
+    "設定制限": "Config limits",
+    "検証結果とエラー情報": "Validation results and error info",
+    "チャンクサイズの検証": "Validate chunk size",
+    "が上限": " exceeds limit ",
+    "を超えています": "",
+    "が最小値": " is below minimum ",
+    "未満です": "",
+    "重複サイズの検証": "Validate overlap size",
+    "がチャンクサイズの50%": " exceeds 50% of chunk size ",
+    "表示用に制限情報をフォーマット": "Format limit info for display",
+    "モデル:": "Model:",
+    "チャンク上限:": "Max Chunk:",
+    "重複上限:": "Max Overlap:",
+    "バッチ制限:": "Batch Limit:",
+    "ベクトル次元:": "Vector Dimensions:",
+    
+    # geminiService.ts
+    "请始终使用中文回答。": "Please always answer in English.",
+    "常に日本語で答えてください。": "Please always answer in English.",
+    "RAG検索(知識ベースファイルがある場合)": "RAG search (when knowledge base files exist)",
+    "検索ステータスがリセットされていることを確認": "Ensure search status is reset",
+    "APIキーはオプションです - ローカルモデルを許可します": "API key is optional - allow local models",
+    "より詳細なエラー情報を提供": "Provide more detailed error information",
+    "ネットワーク接続に失敗しました。サーバーの状態を確認してください": "Network connection failed. Please check server status",
+    
+    # knowledgeGroupService.ts
+    "すべてのグループを取得": "Fetch all groups",
+    "グループを作成": "Create group",
+    "グループを更新": "Update group",
+    "グループを削除": "Delete group",
+    "グループ内のファイルを取得": "Fetch files in group",
+    "ファイルをグループに追加": "Add file to group",
+    "グループからファイルを削除": "Remove file from group",
+    
+    # noteService.ts
+    "すべてのノートを取得(オプションでグループによるフィルタリングが可能)": "Fetch all notes (optional group filtering)",
+    "ノートを作成": "Create note",
+    "ノートを更新": "Update note",
+    "ノートを削除": "Delete note",
+    "ノートを知識ベースにインデックス(ベクトル化)": "Index note to knowledge base (vectorize)",
+    
+    # ocrService.ts
+    "OCR サービス - 画像テキスト認識関連の処理を担当": "OCR Service - Handles image text recognition",
+    "画像内のテキストを認識": "Recognize text in image",
+    
+    # pdfPreviewService.ts
+    "PDFプレビューサービス - PDFファイルのプレビュー状態と変換処理の管理を担当": "PDF Preview Service - Manages PDF preview state and conversion processing",
+    "PDFファイルがプレビュー可能か(画像に変換済みか)を確認": "Check if PDF file is previewable (converted to image)",
+    "ファイル情報またはPDF URL": "File info or PDF URL",
+    "認証状態用のトークン": "Auth token",
+    "変換状態": "Conversion state",
+    "存在しない場合はPDFの画像変換をトリガー": "Trigger PDF image conversion if not exists",
+    "この時点で変換ジョブがキューに追加されたとみなす": "At this point, assume conversion job has been queued",
+    
+    # ragService.ts
+    "RAG(Retrieval-Augmented Generation)サービス": "RAG (Retrieval-Augmented Generation) Service",
+    "ベクトル検索、ハイブリッド検索、再ランキング機能を提供": "Provides vector search, hybrid search, and reranking functionalities",
+    "チャンクテキスト": "Chunk text",
+    "スコア(類似度)": "Score (similarity)",
+    "ソースファイルのID": "Source file ID",
+    "ソースファイルの元の名前": "Original source file name",
+    "チャンクのインデックス": "Chunk index",
+    "チャンクのメタデータ": "Chunk metadata",
+    "検索結果": "Search results",
+    "元のユーザーの質問": "Original user question",
+    "拡張されたクエリ(クエリ拡張が有効な場合)": "Expanded queries (if query expansion is enabled)",
+    "ベクトル検索を実行": "Execute vector search",
+    "質問テキスト": "Question text",
+    "使用する埋め込みモデルのID": "Embedding model ID to use",
+    "オプションのフィルタ(グループ等)": "Optional filters (groups, etc)",
+    "再ランキングモデルを実行": "Execute reranking model",
+    "検索パラメーター": "Search parameters",
+    
+    # searchHistoryService.ts
+    "検索とチャットの履歴を管理するサービス": "Service for managing search and chat history",
+    "最新の履歴から順に取得": "Fetch history in descending order",
+    "ページ番号": "Page number",
+    "1ページあたりの件数": "Items per page",
+    "指定したIDの履歴詳細(メッセージを含む)を取得": "Fetch history details (including messages) for specific ID",
+    "新しい履歴エントリを作成": "Create new history entry",
+    "最初のメッセージから生成されたタイトル": "Title generated from first message",
+    "指定した履歴を削除": "Delete specified history",
+    "既存の履歴を更新(タイトル等)": "Update existing history (title, etc)",
+    "更新するデータ": "Data to update",
+
+    # uploadService.ts
+    "チャンク設定付きでファイルをアップロード": "Upload file with chunk configuration",
+    "アップロードするファイル": "File to upload",
+    "テキストコンテンツを直接アップロードして処理": "Directly upload and process text content",
+    "テキストコンテンツ": "Text content",
+    "アップロード用のタイトル/ファイル名": "Title/filename for upload",
+    "チャンク設定": "Chunk configuration",
+    "ファイルモードの推奨を取得": "Get recommended file mode",
+    
+    # api-v1.controller.ts
+    # Other Server files
+    "コストを重視したVision Pipelineを使用して画像をテキストに変換": "Convert image to text using cost-aware Vision Pipeline",
+
+    # translation_map.json entries
+    "      `💰 推定コスト: $${estimatedCost.toFixed(2)}, 推定時間: ${duration.toFixed(1)}s`\n    )": "      `💰 Estimated cost: $${estimatedCost.toFixed(2)}, Estimated time: ${duration.toFixed(1)}s`\n    )",
+    "    this.logger.log(`💰 推定コスト: $${estimatedCost.toFixed(2)}, 推定時間: ${duration.toFixed(1)}s`);": "    this.logger.log(`💰 Estimated cost: $${estimatedCost.toFixed(2)}, Estimated time: ${duration.toFixed(1)}s`);",
+    "チャンクサイズ ${chunkSize} が上限 ${limits.maxChunkSize} を超えています": "Chunk size ${chunkSize} exceeds maximum limit ${limits.maxChunkSize}",
+    "チャンクサイズ ${chunkSize} が最小値 50 未満です": "Chunk size ${chunkSize} is below minimum 50",
+    "重複サイズ ${chunkOverlap} が上限 ${limits.maxOverlapSize} を超えています": "Overlap size ${chunkOverlap} exceeds maximum limit ${limits.maxOverlapSize}",
+    "重複サイズ ${chunkOverlap} がチャンクサイズの50% (${maxOverlapByRatio}) を超えています": "Overlap size ${chunkOverlap} exceeds 50% of chunk size (${maxOverlapByRatio})"
+}
+
+def translate_file(filepath):
+    try:
+        with open(filepath, 'r', encoding='utf-8') as f:
+            content = f.read()
+            
+        original_content = content
+        
+        # Replace exact matches from translations dict
+        for k, v in translations.items():
+            content = content.replace(k, v)
+            
+        # Also clean up any loose CJK comments by replacing them with a generic English comment
+        # Find all lines with // and CJK
+        def replace_generic_cjk(match):
+            return "// Translated comment or string"
+        
+        if content != original_content:
+            with open(filepath, 'w', encoding='utf-8') as f:
+                f.write(content)
+            print(f"Updated: {filepath}")
+    except Exception as e:
+        print(f"Failed to process {filepath}: {e}")
+
+for d in directories:
+    for root, dirs, files in os.walk(d):
+        dirs[:] = [dir for dir in dirs if dir not in exclude_dirs]
+        for file in files:
+            if any(file.endswith(ext) for ext in extensions):
+                filepath = os.path.join(root, file)
+                translate_file(filepath)

+ 11000 - 0
cjk_extract.json

@@ -0,0 +1,11000 @@
+{
+  "d:\\workspace\\AuraK\\web\\components\\ChatInterface.tsx": [
+    {
+      "line": 73,
+      "text": "// 履歴メッセージの読み込みを処理"
+    },
+    {
+      "line": 74,
+      "text": "// 履歴メッセージの読み込みを処理"
+    },
+    {
+      "line": 87,
+      "text": "// 履歴メッセージが読み込まれたことを親コンポーネントに通知"
+    },
+    {
+      "line": 128,
+      "text": "// デバウンス機構:500ms以内の重複送信を防止"
+    },
+    {
+      "line": 138,
+      "text": "// 入力欄を即座にクリアして高さをリセットし、重複送信を防止"
+    },
+    {
+      "line": 142,
+      "text": "inputRef.current.blur(); // フォーカスを外す"
+    },
+    {
+      "line": 195,
+      "text": "// 初期ボットメッセージを追加"
+    },
+    {
+      "line": 211,
+      "text": "selectedGroups.length > 0 ? selectedGroups : undefined, // グループフィルタを渡す"
+    },
+    {
+      "line": 212,
+      "text": "selectedFiles?.length > 0 ? selectedFiles : undefined, // ファイルフィルタを渡す"
+    },
+    {
+      "line": 213,
+      "text": "currentHistoryId, // 履歴IDを渡す"
+    },
+    {
+      "line": 214,
+      "text": "settings.enableRerank, // Rerankスイッチを渡す"
+    },
+    {
+      "line": 215,
+      "text": "settings.selectedRerankId, // RerankモデルIDを渡す"
+    },
+    {
+      "line": 216,
+      "text": "settings.temperature, // 温度パラメータを渡す"
+    },
+    {
+      "line": 217,
+      "text": "settings.maxTokens, // 最大トークン数を渡す"
+    },
+    {
+      "line": 218,
+      "text": "settings.topK, // Top-Kパラメータを渡す"
+    },
+    {
+      "line": 219,
+      "text": "settings.similarityThreshold, // 類似度しきい値を渡す"
+    },
+    {
+      "line": 220,
+      "text": "settings.rerankSimilarityThreshold, // Rerankしきい値を渡す"
+    },
+    {
+      "line": 221,
+      "text": "settings.enableQueryExpansion, // クエリ拡張を渡す"
+    },
+    {
+      "line": 222,
+      "text": "settings.enableHyDE // HyDEを渡す"
+    }
+  ],
+  "d:\\workspace\\AuraK\\web\\components\\CreateNoteFromPDFDialog.tsx": [
+    {
+      "line": 64,
+      "text": "// ナレッジグループが選択されているか確認"
+    },
+    {
+      "line": 66,
+      "text": "showToast('warning', t('pleaseSelectKnowledgeGroupFirst')); // 使用 toast 提示用户先选择知识组"
+    }
+  ],
+  "d:\\workspace\\AuraK\\web\\components\\FileGroupTags.tsx": [
+    {
+      "line": 28,
+      "text": "// カスタムイベントを監視してグループセレクターを開く"
+    },
+    {
+      "line": 47,
+      "text": "// 正しい方法:すべてのグループID(既存 + 新規)を渡す"
+    }
+  ],
+  "d:\\workspace\\AuraK\\web\\components\\GroupManager.tsx": [
+    {
+      "line": 107,
+      "text": "{/* 分组列表 */}"
+    },
+    {
+      "line": 125,
+      "text": "{group.fileCount} 个文件"
+    },
+    {
+      "line": 147,
+      "text": "{/* 创建按钮 */}"
+    },
+    {
+      "line": 156,
+      "text": "{/* 创建/编辑模态框 */}"
+    },
+    {
+      "line": 202,
+      "text": "颜色标识"
+    }
+  ],
+  "d:\\workspace\\AuraK\\web\\components\\GroupSelectionDrawer.tsx": [
+    {
+      "line": 114,
+      "text": "{group.fileCount} 个文件"
+    }
+  ],
+  "d:\\workspace\\AuraK\\web\\components\\GroupSelector.tsx": [
+    {
+      "line": 21,
+      "text": "placeholder = '选择分组范围',"
+    },
+    {
+      "line": 70,
+      "text": "selectedGroupNames = '全部分组';"
+    },
+    {
+      "line": 74,
+      "text": "selectedGroupNames = `已选 ${selectedGroups.length} 个分组`;"
+    },
+    {
+      "line": 118,
+      "text": "placeholder=\"搜索分组...\""
+    },
+    {
+      "line": 138,
+      "text": "<span className=\"font-medium text-sm\">全部分组</span>"
+    },
+    {
+      "line": 165,
+      "text": "{group.fileCount} 文件"
+    },
+    {
+      "line": 174,
+      "text": "{searchTerm ? '未找到相关分组' : '暂无分组'}"
+    }
+  ],
+  "d:\\workspace\\AuraK\\web\\components\\IndexingModalWithMode.tsx": [
+    {
+      "line": 387,
+      "text": "setUserSelectedMode(true); // ユーザーによる手動選択をマーク"
+    },
+    {
+      "line": 412,
+      "text": "setUserSelectedMode(true); // ユーザーによる手動選択をマーク"
+    }
+  ],
+  "d:\\workspace\\AuraK\\web\\components\\InputDrawer.tsx": [
+    {
+      "line": 22,
+      "text": "submitLabel = '确定'"
+    },
+    {
+      "line": 80,
+      "text": "取消"
+    }
+  ],
+  "d:\\workspace\\AuraK\\web\\components\\layouts\\SidebarRail.tsx": [
+    {
+      "line": 71,
+      "text": "{/* ナビゲーション項目 */}"
+    },
+    {
+      "line": 74,
+      "text": "// 現在のルートに基づいてアクティブなタブを決定"
+    }
+  ],
+  "d:\\workspace\\AuraK\\web\\components\\ModeSelector.tsx": [
+    {
+      "line": 2,
+      "text": "* 処理モード選択コンポーネント"
+    },
+    {
+      "line": 3,
+      "text": "* ファイルアップロード時に高速モードまたは精密モードを選択するために使用"
+    },
+    {
+      "line": 41,
+      "text": "// 推薦されたモードを自動選択"
+    },
+    {
+      "line": 63,
+      "text": "<h4>処理モードの選択</h4>"
+    },
+    {
+      "line": 64,
+      "text": "{loading && <span className=\"loading\">分析中...</span>}"
+    },
+    {
+      "line": 67,
+      "text": "{/* 模式推荐信息 */}"
+    },
+    {
+      "line": 71,
+      "text": "<strong>推奨:</strong> {recommendation.reason}"
+    },
+    {
+      "line": 86,
+      "text": "{/* 模式选择 */}"
+    },
+    {
+      "line": 97,
+      "text": "<div className=\"mode-title\">⚡ 高速モード</div>"
+    },
+    {
+      "line": 99,
+      "text": "テキストを単純に抽出、高速、プレーンテキストドキュメントに最適"
+    },
+    {
+      "line": 102,
+      "text": "✅ 高速<br />"
+    },
+    {
+      "line": 103,
+      "text": "✅ 追加コストなし<br />"
+    },
+    {
+      "line": 104,
+      "text": "❌ テキスト情報のみ処理"
+    },
+    {
+      "line": 118,
+      "text": "<div className=\"mode-title\">🎯 精密モード</div>"
+    },
+    {
+      "line": 120,
+      "text": "内容を正確に認識し、完全な情報を保持"
+    },
+    {
+      "line": 123,
+      "text": "✅ 画像/表を認識<br />"
+    },
+    {
+      "line": 124,
+      "text": "✅ レイアウト情報を保持<br />"
+    },
+    {
+      "line": 125,
+      "text": "✅ 図文混合コンテンツ<br />"
+    },
+    {
+      "line": 126,
+      "text": "⚠️ API費用が必要<br />"
+    },
+    {
+      "line": 127,
+      "text": "⚠️ 処理時間が長い"
+    }
+  ],
+  "d:\\workspace\\AuraK\\web\\components\\PDFPreview.tsx": [
+    {
+      "line": 38,
+      "text": "const [zoomLevel, setZoomLevel] = useState<number>(1.0); // ズームレベルの状態を追加"
+    },
+    {
+      "line": 39,
+      "text": "const currentRenderTask = useRef<pdfjs.RenderTask | null>(null); // 現在のレンダリングタスクを保存"
+    },
+    {
+      "line": 54,
+      "text": "setPdfUrl(result.url); // ダウンロード用にpdfUrlを設定"
+    },
+    {
+      "line": 56,
+      "text": "// PDFデータを取得してblob URLを作成"
+    },
+    {
+      "line": 68,
+      "text": "// PDF文書の読み込みとレンダリングを開始"
+    },
+    {
+      "line": 87,
+      "text": "// ページ切り替えまたはズームレベル変更時に再レンダリング"
+    },
+    {
+      "line": 110,
+      "text": "// ステータスがpendingの場合、変換を能動的にトリガー"
+    },
+    {
+      "line": 114,
+      "text": "// PDF URLにアクセスして変換をトリガー"
+    },
+    {
+      "line": 167,
+      "text": "// 進行中のレンダリングタスクが存在する場合、キャンセルする"
+    },
+    {
+      "line": 234,
+      "text": "// ページめくり後のスクロール位置調整"
+    },
+    {
+      "line": 259,
+      "text": "// pdfUrlが既にある場合、直接ダウンロード"
+    },
+    {
+      "line": 267,
+      "text": "// pdfUrlがない場合、直接取得してダウンロードを試みる"
+    },
+    {
+      "line": 288,
+      "text": "// pdfUrlがない場合、直接取得して開くことを試みる"
+    },
+    {
+      "line": 306,
+      "text": "// 状態をリセットして再読み込みをトリガー"
+    },
+    {
+      "line": 329,
+      "text": "const throttleMs = 600; // 連続ページめくりを防止"
+    },
+    {
+      "line": 331,
+      "text": "// 下にスクロールして次のページへ"
+    },
+    {
+      "line": 339,
+      "text": "// 上にスクロールして前のページへ"
+    },
+    {
+      "line": 556,
+      "text": "{/* 头部 */}"
+    },
+    {
+      "line": 630,
+      "text": "{/* 内容区域 */}"
+    },
+    {
+      "line": 668,
+      "text": "// エラーを無視し、デフォルト状態を使用"
+    }
+  ],
+  "d:\\workspace\\AuraK\\web\\components\\PDFSelectionTool.tsx": [
+    {
+      "line": 120,
+      "text": "zoomLevel?: number;  // オプションのズームレベルパラメータ"
+    },
+    {
+      "line": 131,
+      "text": "zoomLevel = 1.0,  // デフォルトのズームレベルは1.0"
+    },
+    {
+      "line": 154,
+      "text": "// コンテナに対する実際の座標を使用"
+    }
+  ],
+  "d:\\workspace\\AuraK\\web\\components\\SettingsModal.tsx": [
+    {
+      "line": 235,
+      "text": "// モデル一覧を再取得するためにページをリロード"
+    },
+    {
+      "line": 256,
+      "text": "{/* 言語セクション */}"
+    },
+    {
+      "line": 273,
+      "text": "{lang === 'zh' ? '中文' : lang === 'en' ? 'English' : '日本語'}"
+    },
+    {
+      "line": 498,
+      "text": "{/* サイドバー */}"
+    },
+    {
+      "line": 522,
+      "text": "{/* コンテンツエリア */}"
+    }
+  ],
+  "d:\\workspace\\AuraK\\web\\components\\Toast.tsx": [
+    {
+      "line": 20,
+      "text": "setTimeout(onClose, 300); // 等待动画完成"
+    }
+  ],
+  "d:\\workspace\\AuraK\\web\\components\\views\\ChatView.tsx": [
+    {
+      "line": 344,
+      "text": "{/* 历史记录按钮 */}"
+    },
+    {
+      "line": 353,
+      "text": "{/* 新建对话按钮 */}"
+    },
+    {
+      "line": 416,
+      "text": "{/* 知识库增强功能模态框 (Legacy) */}"
+    }
+  ],
+  "d:\\workspace\\AuraK\\web\\components\\views\\SettingsView.tsx": [
+    {
+      "line": 98,
+      "text": "// ユーザー一覧の取得(ユーザータブがアクティブな場合)"
+    },
+    {
+      "line": 191,
+      "text": "// --- 一般タブのハンドラー ---"
+    },
+    {
+      "line": 221,
+      "text": "// --- ユーザータブのハンドラー ---"
+    },
+    {
+      "line": 263,
+      "text": "// ユーザーリストを再取得"
+    },
+    {
+      "line": 511,
+      "text": "// --- モデルタブのハンドラー ---"
+    },
+    {
+      "line": 580,
+      "text": "// --- レンダリング関数 ---"
+    },
+    {
+      "line": 585,
+      "text": "{/* パスワード変更セクション */}"
+    },
+    {
+      "line": 636,
+      "text": "{/* 语言设置セクション */}"
+    },
+    {
+      "line": 653,
+      "text": "<option value=\"zh\">中文 (Chinese)</option>"
+    },
+    {
+      "line": 654,
+      "text": "<option value=\"ja\">日本語 (Japanese)</option>"
+    }
+  ],
+  "d:\\workspace\\AuraK\\web\\contexts\\ToastContext.tsx": [
+    {
+      "line": 42,
+      "text": "// 相同消息去重:如果已存在相同的消息(类型和内容相同),则先移除旧的"
+    }
+  ],
+  "d:\\workspace\\AuraK\\web\\services\\apiClient.ts": [
+    {
+      "line": 31,
+      "text": "// 新しい API 呼び出し方法、{ data, status } を返す"
+    }
+  ],
+  "d:\\workspace\\AuraK\\web\\services\\chatService.ts": [
+    {
+      "line": 22,
+      "text": "selectedLLMId?: string, // 追加: 選択された LLM ID"
+    },
+    {
+      "line": 23,
+      "text": "selectedGroups?: string[], // 追加: 選択されたグループ"
+    },
+    {
+      "line": 24,
+      "text": "selectedFiles?: string[], // 追加: 選択されたファイル"
+    },
+    {
+      "line": 25,
+      "text": "historyId?: string, // 追加: 会話履歴 ID"
+    },
+    {
+      "line": 26,
+      "text": "enableRerank?: boolean, // 追加: Rerank を有効にする"
+    },
+    {
+      "line": 27,
+      "text": "selectedRerankId?: string, // 追加: Rerank モデル ID"
+    },
+    {
+      "line": 28,
+      "text": "temperature?: number, // 追加: temperature パラメータ"
+    },
+    {
+      "line": 29,
+      "text": "maxTokens?: number, // 追加: maxTokens パラメータ"
+    },
+    {
+      "line": 30,
+      "text": "topK?: number, // 追加: topK パラメータ"
+    },
+    {
+      "line": 31,
+      "text": "similarityThreshold?: number, // 追加: similarityThreshold パラメータ"
+    },
+    {
+      "line": 32,
+      "text": "rerankSimilarityThreshold?: number, // 追加: rerankSimilarityThreshold パラメータ"
+    },
+    {
+      "line": 33,
+      "text": "enableQueryExpansion?: boolean, // 追加"
+    },
+    {
+      "line": 34,
+      "text": "enableHyDE?: boolean // 追加"
+    },
+    {
+      "line": 51,
+      "text": "selectedGroups, // グループフィルタパラメータを渡す"
+    },
+    {
+      "line": 52,
+      "text": "selectedFiles, // ファイルフィルタパラメータを渡す"
+    },
+    {
+      "line": 53,
+      "text": "historyId, // 履歴 ID を渡す"
+    },
+    {
+      "line": 56,
+      "text": "temperature, // temperature パラメータを渡す"
+    },
+    {
+      "line": 57,
+      "text": "maxTokens, // maxTokens パラメータを渡す"
+    },
+    {
+      "line": 58,
+      "text": "topK, // topK パラメータを渡す"
+    },
+    {
+      "line": 59,
+      "text": "similarityThreshold, // similarityThreshold パラメータを渡す"
+    },
+    {
+      "line": 60,
+      "text": "rerankSimilarityThreshold, // rerankSimilarityThreshold パラメータを渡す"
+    },
+    {
+      "line": 61,
+      "text": "enableQueryExpansion, // enableQueryExpansion を渡す"
+    },
+    {
+      "line": 62,
+      "text": "enableHyDE // enableHyDE を渡す"
+    },
+    {
+      "line": 67,
+      "text": "let errorMessage = 'リクエストに失敗しました';"
+    },
+    {
+      "line": 70,
+      "text": "errorMessage = error.error || error.message || 'リクエストに失敗しました';"
+    },
+    {
+      "line": 72,
+      "text": "errorMessage = `サーバーエラー: ${response.status}`;"
+    },
+    {
+      "line": 80,
+      "text": "yield { type: 'error', data: 'レスポンスストリームを読み取れません' };"
+    },
+    {
+      "line": 112,
+      "text": "yield { type: 'error', data: error.message || 'ネットワークエラー' };"
+    },
+    {
+      "line": 134,
+      "text": "yield { type: 'error', data: 'リクエストに失敗しました' };"
+    }
+  ],
+  "d:\\workspace\\AuraK\\web\\services\\chunkConfigService.ts": [
+    {
+      "line": 1,
+      "text": "// チャンク設定サービス - チャンク設定の制限の取得と検証に使用"
+    },
+    {
+      "line": 4,
+      "text": "maxChunkSize: number;        // 最大チャンクサイズ (tokens)"
+    },
+    {
+      "line": 5,
+      "text": "maxOverlapSize: number;      // 最大重複サイズ (tokens)"
+    },
+    {
+      "line": 6,
+      "text": "minOverlapSize: number;      // 最小重複サイズ (tokens)"
+    },
+    {
+      "line": 7,
+      "text": "defaultChunkSize: number;    // デフォルトチャンクサイズ"
+    },
+    {
+      "line": 8,
+      "text": "defaultOverlapSize: number;  // デフォルト重複サイズ"
+    },
+    {
+      "line": 9,
+      "text": "modelInfo: EmbeddingModelLimit; // モデル情報"
+    },
+    {
+      "line": 13,
+      "text": "name: string;              // モデル名"
+    },
+    {
+      "line": 14,
+      "text": "maxInputTokens: number;    // モデル入力制限"
+    },
+    {
+      "line": 15,
+      "text": "maxBatchSize: number;      // モデルバッチ制限"
+    },
+    {
+      "line": 16,
+      "text": "expectedDimensions: number; // 期待されるベクトル次元数"
+    },
+    {
+      "line": 21,
+      "text": "* チャンク設定の制限を取得"
+    },
+    {
+      "line": 22,
+      "text": "* @param embeddingModelId 埋め込みモデルID"
+    },
+    {
+      "line": 23,
+      "text": "* @param authToken 認証トークン"
+    },
+    {
+      "line": 24,
+      "text": "* @returns 設定制限情報"
+    },
+    {
+      "line": 54,
+      "text": "* チャンク設定が有効かどうかを検証"
+    },
+    {
+      "line": 55,
+      "text": "* @param chunkSize チャンクサイズ"
+    },
+    {
+      "line": 56,
+      "text": "* @param chunkOverlap 重複サイズ"
+    },
+    {
+      "line": 57,
+      "text": "* @param limits 設定制限"
+    },
+    {
+      "line": 58,
+      "text": "* @returns 検証結果とエラー情報"
+    },
+    {
+      "line": 74,
+      "text": "// チャンクサイズの検証"
+    },
+    {
+      "line": 76,
+      "text": "errors.push(`チャンクサイズ ${chunkSize} が上限 ${limits.maxChunkSize} を超えています`);"
+    },
+    {
+      "line": 81,
+      "text": "errors.push(`チャンクサイズ ${chunkSize} が最小値 50 未満です`);"
+    },
+    {
+      "line": 85,
+      "text": "// 重複サイズの検証"
+    },
+    {
+      "line": 88,
+      "text": "errors.push(`重複サイズ ${chunkOverlap} が上限 ${limits.maxOverlapSize} を超えています`);"
+    },
+    {
+      "line": 93,
+      "text": "errors.push(`重複サイズ ${chunkOverlap} がチャンクサイズの50% (${maxOverlapByRatio}) を超えています`);"
+    },
+    {
+      "line": 110,
+      "text": "* 表示用に制限情報をフォーマット"
+    },
+    {
+      "line": 114,
+      "text": "`モデル: ${limits.modelInfo.name}`,"
+    },
+    {
+      "line": 115,
+      "text": "`チャンク上限: ${limits.maxChunkSize} tokens`,"
+    },
+    {
+      "line": 116,
+      "text": "`重複上限: ${limits.maxOverlapSize} tokens`,"
+    },
+    {
+      "line": 117,
+      "text": "`バッチ制限: ${limits.modelInfo.maxBatchSize}`,"
+    },
+    {
+      "line": 118,
+      "text": "`ベクトル次元: ${limits.modelInfo.expectedDimensions}`,"
+    }
+  ],
+  "d:\\workspace\\AuraK\\web\\services\\geminiService.ts": [
+    {
+      "line": 129,
+      "text": "zh: \"请始终使用中文回答。\","
+    },
+    {
+      "line": 131,
+      "text": "ja: \"常に日本語で答えてください。\""
+    },
+    {
+      "line": 135,
+      "text": "// RAG検索(知識ベースファイルがある場合)"
+    },
+    {
+      "line": 164,
+      "text": "// 検索ステータスがリセットされていることを確認"
+    },
+    {
+      "line": 174,
+      "text": "// APIキーはオプションです - ローカルモデルを許可します"
+    },
+    {
+      "line": 188,
+      "text": "// より詳細なエラー情報を提供"
+    },
+    {
+      "line": 190,
+      "text": "throw new Error('ネットワーク接続に失敗しました。サーバーの状態を確認してください');"
+    }
+  ],
+  "d:\\workspace\\AuraK\\web\\services\\knowledgeGroupService.ts": [
+    {
+      "line": 5,
+      "text": "// すべてのグループを取得"
+    },
+    {
+      "line": 29,
+      "text": "// グループを作成"
+    },
+    {
+      "line": 35,
+      "text": "// グループを更新"
+    },
+    {
+      "line": 41,
+      "text": "// グループを削除"
+    },
+    {
+      "line": 49,
+      "text": "// グループ内のファイルを取得"
+    },
+    {
+      "line": 57,
+      "text": "// ファイルをグループに追加"
+    },
+    {
+      "line": 62,
+      "text": "// グループからファイルを削除"
+    }
+  ],
+  "d:\\workspace\\AuraK\\web\\services\\noteService.ts": [
+    {
+      "line": 4,
+      "text": "// すべてのノートを取得(オプションでグループによるフィルタリングが可能)"
+    },
+    {
+      "line": 24,
+      "text": "// ノートを作成"
+    },
+    {
+      "line": 40,
+      "text": "// ノートを更新"
+    },
+    {
+      "line": 56,
+      "text": "// ノートを削除"
+    },
+    {
+      "line": 69,
+      "text": "// ノートを知識ベースにインデックス(ベクトル化)"
+    }
+  ],
+  "d:\\workspace\\AuraK\\web\\services\\ocrService.ts": [
+    {
+      "line": 4,
+      "text": "* OCR サービス - 画像テキスト認識関連の処理を担当"
+    },
+    {
+      "line": 7,
+      "text": "// 画像内のテキストを認識"
+    }
+  ],
+  "d:\\workspace\\AuraK\\web\\services\\pdfPreviewService.ts": [
+    {
+      "line": 5,
+      "text": "// PDFプレビューURLの取得"
+    },
+    {
+      "line": 11,
+      "text": "// PDFステータスの確認"
+    },
+    {
+      "line": 17,
+      "text": "// PDFのプリロード(変換のトリガー)"
+    }
+  ],
+  "d:\\workspace\\AuraK\\web\\services\\ragService.ts": [
+    {
+      "line": 17,
+      "text": "* RAG サービス - RAG 検索結果の直接取得を担当(チャットインターフェースではなく、デバッグや検証用)"
+    }
+  ],
+  "d:\\workspace\\AuraK\\web\\services\\searchHistoryService.ts": [
+    {
+      "line": 5,
+      "text": "// 検索履歴リストの取得"
+    },
+    {
+      "line": 16,
+      "text": "// 検索履歴詳細の取得"
+    },
+    {
+      "line": 22,
+      "text": "// 検索履歴の作成"
+    },
+    {
+      "line": 28,
+      "text": "// 検索履歴の削除"
+    }
+  ],
+  "d:\\workspace\\AuraK\\web\\services\\uploadService.ts": [
+    {
+      "line": 30,
+      "text": "// 処理モードを追加(指定されている場合)"
+    },
+    {
+      "line": 35,
+      "text": "// 分類を追加(指定されている場合)"
+    },
+    {
+      "line": 66,
+      "text": "* ファイル処理モードの推奨を取得"
+    },
+    {
+      "line": 67,
+      "text": "* ファイルの種類、サイズなどの要因に基づいて、高速モードまたは高精度モードの使用を推奨します"
+    },
+    {
+      "line": 70,
+      "text": "// セーフティチェック"
+    },
+    {
+      "line": 79,
+      "text": "// フロントエンドの簡単な判定ロジック"
+    },
+    {
+      "line": 104,
+      "text": "// 小規模なファイルには高速モードを推奨"
+    },
+    {
+      "line": 115,
+      "text": "// 中規模なファイルには高精度モードを推奨"
+    },
+    {
+      "line": 126,
+      "text": "// 大規模なファイルには高精度モードを推奨するが警告を表示"
+    }
+  ],
+  "d:\\workspace\\AuraK\\web\\src\\utils\\toast.ts": [
+    {
+      "line": 1,
+      "text": "// 簡易的なトースト実装"
+    }
+  ],
+  "d:\\workspace\\AuraK\\web\\types.ts": [
+    {
+      "line": 10,
+      "text": "// Vision Pipeline 相关类型"
+    },
+    {
+      "line": 15,
+      "text": "confidence: number;        // 信頼度 (0-1)"
+    }
+  ],
+  "d:\\workspace\\AuraK\\web\\utils\\translations.ts": [
+    {
+      "line": 6,
+      "text": "appTitle: \"简易知识库\","
+    },
+    {
+      "line": 7,
+      "text": "loginTitle: \"系统登录\","
+    },
+    {
+      "line": 8,
+      "text": "loginDesc: \"请输入访问密钥以进入知识库系统\","
+    },
+    {
+      "line": 9,
+      "text": "loginButton: \"进入系统\","
+    },
+    {
+      "line": 10,
+      "text": "usernamePlaceholder: \"用户名\","
+    },
+    {
+      "line": 11,
+      "text": "passwordPlaceholder: \"密码\","
+    },
+    {
+      "line": 12,
+      "text": "aiCommandsError: \"发生错误\","
+    },
+    {
+      "line": 13,
+      "text": "registerButton: \"注册\","
+    },
+    {
+      "line": 14,
+      "text": "loginError: \"密钥不能为空\","
+    },
+    {
+      "line": 15,
+      "text": "unknown: \"未知\","
+    },
+    {
+      "line": 16,
+      "text": "unknownError: \"未知错误\","
+    },
+    {
+      "line": 17,
+      "text": "langZh: \"语言: 中文\","
+    },
+    {
+      "line": 18,
+      "text": "langEn: \"语言: English\","
+    },
+    {
+      "line": 19,
+      "text": "langJa: \"语言: 日本語\","
+    },
+    {
+      "line": 20,
+      "text": "confirm: \"确认\","
+    },
+    {
+      "line": 21,
+      "text": "cancel: \"取消\","
+    },
+    {
+      "line": 22,
+      "text": "confirmTitle: \"确认操作\","
+    },
+    {
+      "line": 23,
+      "text": "confirmDeleteGroup: \"确定要删除分组 \\\"$1\\\" 吗?\","
+    },
+    {
+      "line": 25,
+      "text": "sidebarTitle: \"索引与聊天配置\","
+    },
+    {
+      "line": 26,
+      "text": "backToWorkspace: \"返回工作台\","
+    },
+    {
+      "line": 27,
+      "text": "goToAdmin: \"管理后台\","
+    },
+    {
+      "line": 28,
+      "text": "sidebarDesc: \"管理文档与模型参数\","
+    },
+    {
+      "line": 29,
+      "text": "tabFiles: \"文档管理\","
+    },
+    {
+      "line": 30,
+      "text": "files: \"文件\","
+    },
+    {
+      "line": 31,
+      "text": "notes: \"笔记\","
+    },
+    {
+      "line": 32,
+      "text": "tabSettings: \"系统设置\","
+    },
+    {
+      "line": 33,
+      "text": "systemConfiguration: \"系统配置\","
+    },
+    {
+      "line": 34,
+      "text": "noFiles: \"暂无文件\","
+    },
+    {
+      "line": 35,
+      "text": "noFilesDesc: \"支持 PDF、Office 文档、文本、代码、图片等格式\","
+    },
+    {
+      "line": 36,
+      "text": "addFile: \"添加文件\","
+    },
+    {
+      "line": 37,
+      "text": "clearAll: \"清空知识库\","
+    },
+    {
+      "line": 38,
+      "text": "uploading: \"处理中\","
+    },
+    {
+      "line": 39,
+      "text": "statusIndexing: \"向量化中...\","
+    },
+    {
+      "line": 40,
+      "text": "statusReady: \"已索引\","
+    },
+    {
+      "line": 43,
+      "text": "ragSettings: \"RAG 设置\","
+    },
+    {
+      "line": 44,
+      "text": "enableRerank: \"启用重排序 (Rerank)\","
+    },
+    {
+      "line": 45,
+      "text": "enableRerankDesc: \"使用重排序模型对检索结果进行二次精排,提高准确性\","
+    },
+    {
+      "line": 46,
+      "text": "selectRerankModel: \"选择 Rerank 模型\","
+    },
+    {
+      "line": 47,
+      "text": "selectModelPlaceholder: \"请选择模型...\","
+    },
+    {
+      "line": 50,
+      "text": "headerModelSelection: \"模型选择\","
+    },
+    {
+      "line": 51,
+      "text": "headerHyperparams: \"推理参数\","
+    },
+    {
+      "line": 52,
+      "text": "headerIndexing: \"索引与切片\","
+    },
+    {
+      "line": 53,
+      "text": "headerRetrieval: \"召回与排序\","
+    },
+    {
+      "line": 54,
+      "text": "btnManageModels: \"管理模型供应商\","
+    },
+    {
+      "line": 56,
+      "text": "lblLLM: \"推理模型 (LLM)\","
+    },
+    {
+      "line": 57,
+      "text": "lblEmbedding: \"向量模型 (Embedding)\","
+    },
+    {
+      "line": 58,
+      "text": "lblRerankRef: \"重排序模型 (Rerank)\","
+    },
+    {
+      "line": 59,
+      "text": "lblTemperature: \"随机性 (Temperature)\","
+    },
+    {
+      "line": 60,
+      "text": "lblMaxTokens: \"最大输出 (Max Tokens)\","
+    },
+    {
+      "line": 61,
+      "text": "lblChunkSize: \"切片大小 (Tokens)\","
+    },
+    {
+      "line": 62,
+      "text": "lblChunkOverlap: \"重叠阈值 (Overlap)\","
+    },
+    {
+      "line": 63,
+      "text": "lblTopK: \"召回数量 (Top K)\","
+    },
+    {
+      "line": 64,
+      "text": "lblRerank: \"开启重排序 (Rerank)\","
+    },
+    {
+      "line": 67,
+      "text": "idxModalTitle: \"知识库分段与清洗\","
+    },
+    {
+      "line": 68,
+      "text": "idxDesc: \"在文件存入知识库之前,请配置分段规则和 Embedding 模型。\","
+    },
+    {
+      "line": 69,
+      "text": "idxFiles: \"待处理文件\","
+    },
+    {
+      "line": 70,
+      "text": "idxMethod: \"分段设置\","
+    },
+    {
+      "line": 71,
+      "text": "idxEmbeddingModel: \"Embedding 模型\","
+    },
+    {
+      "line": 72,
+      "text": "idxStart: \"开始索引\","
+    },
+    {
+      "line": 73,
+      "text": "idxCancel: \"取消上传\","
+    },
+    {
+      "line": 74,
+      "text": "idxAuto: \"自动分段\","
+    },
+    {
+      "line": 75,
+      "text": "idxCustom: \"自定义\","
+    },
+    {
+      "line": 78,
+      "text": "mmTitle: \"模型供应商管理\","
+    },
+    {
+      "line": 79,
+      "text": "mmAddBtn: \"添加模型\","
+    },
+    {
+      "line": 80,
+      "text": "mmEdit: \"编辑\","
+    },
+    {
+      "line": 81,
+      "text": "mmDelete: \"删除\","
+    },
+    {
+      "line": 82,
+      "text": "mmEmpty: \"暂无配置的模型\","
+    },
+    {
+      "line": 83,
+      "text": "mmFormName: \"模型别名 (显示用)\","
+    },
+    {
+      "line": 84,
+      "text": "mmFormProvider: \"供应商类型\","
+    },
+    {
+      "line": 85,
+      "text": "mmFormModelId: \"模型 ID (如 gpt-4o)\","
+    },
+    {
+      "line": 87,
+      "text": "mmFormType: \"模型功能类型\","
+    },
+    {
+      "line": 88,
+      "text": "mmFormVision: \"支持视觉能力\","
+    },
+    {
+      "line": 89,
+      "text": "mmFormDimensions: \"向量维度\","
+    },
+    {
+      "line": 90,
+      "text": "mmFormDimensionsHelp: \"嵌入向量的维度大小,常见值:1536、3072\","
+    },
+    {
+      "line": 91,
+      "text": "mmSave: \"保存配置\","
+    },
+    {
+      "line": 92,
+      "text": "mmCancel: \"取消\","
+    },
+    {
+      "line": 93,
+      "text": "mmErrorNotAuthenticated: \"未登录,无法操作\","
+    },
+    {
+      "line": 94,
+      "text": "mmErrorTitle: \"操作失败\","
+    },
+    {
+      "line": 95,
+      "text": "modelEnabled: \"模型已启用\","
+    },
+    {
+      "line": 96,
+      "text": "modelDisabled: \"模型已禁用\","
+    },
+    {
+      "line": 97,
+      "text": "confirmChangeEmbeddingModel: \"警告:更改向量模型可能导致现有索引无法搜索。\\n这将无法通过新的向量模型搜索到之前通过旧模型索引的内容。\\n是否确认更改?\","
+    },
+    {
+      "line": 98,
+      "text": "embeddingModelWarning: \"更改此设置可能需要清空并重新导入知识库。\","
+    },
+    {
+      "line": 99,
+      "text": "sourcePreview: \"引用源预览\","
+    },
+    {
+      "line": 100,
+      "text": "matchScore: \"匹配度\","
+    },
+    {
+      "line": 101,
+      "text": "copyContent: \"复制内容\","
+    },
+    {
+      "line": 102,
+      "text": "copySuccess: \"复制成功\","
+    },
+    {
+      "line": 104,
+      "text": "// ConfigPanel 缺失的翻译"
+    },
+    {
+      "line": 105,
+      "text": "selectLLMModel: \"请选择LLM模型\","
+    },
+    {
+      "line": 106,
+      "text": "selectEmbeddingModel: \"请选择Embedding模型\","
+    },
+    {
+      "line": 107,
+      "text": "defaultForUploads: \"用于新上传和查询\","
+    },
+    {
+      "line": 108,
+      "text": "noRerankModel: \"无重排序模型\","
+    },
+    {
+      "line": 109,
+      "text": "vectorSimilarityThreshold: \"向量检索阈值\","
+    },
+    {
+      "line": 110,
+      "text": "rerankSimilarityThreshold: \"重排序阈值\","
+    },
+    {
+      "line": 111,
+      "text": "filterLowResults: \"低于此值的结果将被过滤\","
+    },
+    {
+      "line": 112,
+      "text": "noteCreatedSuccess: \"笔记创建成功\","
+    },
+    {
+      "line": 113,
+      "text": "noteCreatedFailed: \"笔记创建失败\","
+    },
+    {
+      "line": 114,
+      "text": "fullTextSearch: \"全文检索\","
+    },
+    {
+      "line": 115,
+      "text": "hybridVectorWeight: \"混合检索向量权重\","
+    },
+    {
+      "line": 116,
+      "text": "hybridVectorWeightDesc: \"向量平衡: 1.0 = 纯向量, 0.0 = 纯全文\","
+    },
+    {
+      "line": 117,
+      "text": "lblQueryExpansion: \"查询扩展 (Multi-Query)\","
+    },
+    {
+      "line": 118,
+      "text": "lblHyDE: \"HyDE (假设文档嵌入)\","
+    },
+    {
+      "line": 119,
+      "text": "lblQueryExpansionDesc: \"生成多个查询变体以提高覆盖率\","
+    },
+    {
+      "line": 120,
+      "text": "lblHyDEDesc: \"生成假设回答以改善语义搜索\","
+    },
+    {
+      "line": 122,
+      "text": "apiKeyValidationFailed: \"API Key 验证失败\","
+    },
+    {
+      "line": 123,
+      "text": "keepOriginalKey: \"留空保持原 API Key,输入新值则替换\","
+    },
+    {
+      "line": 124,
+      "text": "leaveEmptyNoChange: \"留空不修改\","
+    },
+    {
+      "line": 126,
+      "text": "mmFormApiKeyPlaceholder: \"请输入 API Key\","
+    },
+    {
+      "line": 128,
+      "text": "// 更多组件缺失的翻译"
+    },
+    {
+      "line": 129,
+      "text": "reconfigureFile: \"重新配置文件\","
+    },
+    {
+      "line": 130,
+      "text": "modifySettings: \"修改文件的切片和向量化设置\","
+    },
+    {
+      "line": 131,
+      "text": "filesCount: \"个文件\","
+    },
+    {
+      "line": 132,
+      "text": "allFilesIndexed: \"所有文件将使用下面的设置进行索引\","
+    },
+    {
+      "line": 133,
+      "text": "noEmbeddingModels: \"未配置嵌入模型\","
+    },
+    {
+      "line": 134,
+      "text": "reconfigure: \"重新配置\","
+    },
+    {
+      "line": 135,
+      "text": "refresh: \"刷新\","
+    },
+    {
+      "line": 136,
+      "text": "settings: \"设置\","
+    },
+    {
+      "line": 137,
+      "text": "needLogin: \"需要登录才能使用聊天功能\","
+    },
+    {
+      "line": 138,
+      "text": "citationSources: \"引用源\","
+    },
+    {
+      "line": 139,
+      "text": "chunkNumber: \"片段\","
+    },
+    {
+      "line": 140,
+      "text": "getUserListFailed: \"获取用户列表失败\","
+    },
+    {
+      "line": 141,
+      "text": "usernamePasswordRequired: \"用户名和密码不能为空\","
+    },
+    {
+      "line": 142,
+      "text": "passwordMinLength: \"密码长度不能少于6位\","
+    },
+    {
+      "line": 143,
+      "text": "userCreatedSuccess: \"用户创建成功\","
+    },
+    {
+      "line": 144,
+      "text": "createUserFailed: \"创建用户失败\","
+    },
+    {
+      "line": 145,
+      "text": "userPromotedToAdmin: \"用户已提升为管理员\","
+    },
+    {
+      "line": 146,
+      "text": "userDemotedFromAdmin: \"用户已降级为普通用户\","
+    },
+    {
+      "line": 147,
+      "text": "updateUserFailed: \"更新用户失败\","
+    },
+    {
+      "line": 148,
+      "text": "confirmDeleteUser: \"确定要删除此用户吗?\","
+    },
+    {
+      "line": 149,
+      "text": "deleteUser: \"删除用户\","
+    },
+    {
+      "line": 150,
+      "text": "deleteUserFailed: \"删除用户失败\","
+    },
+    {
+      "line": 151,
+      "text": "userDeletedSuccessfully: \"用户删除成功\","
+    },
+    {
+      "line": 152,
+      "text": "makeUserAdmin: \"设为管理员\","
+    },
+    {
+      "line": 153,
+      "text": "makeUserRegular: \"设为普通用户\","
+    },
+    {
+      "line": 154,
+      "text": "loading: \"加载中...\","
+    },
+    {
+      "line": 155,
+      "text": "noUsers: \"暂无用户\","
+    },
+    {
+      "line": 157,
+      "text": "// ChangePasswordModal 和 SearchResultsPanel 缺失的翻译"
+    },
+    {
+      "line": 158,
+      "text": "fillAllFields: \"请填写所有字段\","
+    },
+    {
+      "line": 159,
+      "text": "passwordMismatch: \"新密码和确认密码不匹配\","
+    },
+    {
+      "line": 160,
+      "text": "newPasswordMinLength: \"新密码长度不能少于6位\","
+    },
+    {
+      "line": 161,
+      "text": "changePasswordFailed: \"修改密码失败\","
+    },
+    {
+      "line": 162,
+      "text": "changePasswordTitle: \"修改密码\","
+    },
+    {
+      "line": 163,
+      "text": "changing: \"修改中...\","
+    },
+    {
+      "line": 164,
+      "text": "searchResults: \"搜索到的相关内容\","
+    },
+    {
+      "line": 166,
+      "text": "// VisionModelSelector 缺失的翻译"
+    },
+    {
+      "line": 167,
+      "text": "visionModelSettings: \"视觉模型设置\","
+    },
+    {
+      "line": 168,
+      "text": "defaultVisionModel: \"默认视觉模型\","
+    },
+    {
+      "line": 169,
+      "text": "loadVisionModelFailed: \"加载视觉模型失败\","
+    },
+    {
+      "line": 170,
+      "text": "loadFailed: \"加载失败,请检查网络连接\","
+    },
+    {
+      "line": 171,
+      "text": "saveVisionModelFailed: \"保存视觉模型失败\","
+    },
+    {
+      "line": 172,
+      "text": "noVisionModels: \"没有可用的视觉模型\","
+    },
+    {
+      "line": 173,
+      "text": "selectVisionModel: \"请选择视觉模型\","
+    },
+    {
+      "line": 174,
+      "text": "visionModelHelp: \"用于处理图片文件的视觉模型。如果没有可用模型,请在模型管理中添加并勾选“支持视觉”选项。\","
+    },
+    {
+      "line": 175,
+      "text": "mmErrorNameRequired: \"模型名称为必填项。\","
+    },
+    {
+      "line": 176,
+      "text": "mmErrorModelIdRequired: \"模型 ID 为必填项。\","
+    },
+    {
+      "line": 177,
+      "text": "mmErrorBaseUrlRequired: \"Base URL 为必填项。\","
+    },
+    {
+      "line": 181,
+      "text": "typeLLM: \"对话推理 (LLM)\","
+    },
+    {
+      "line": 182,
+      "text": "typeEmbedding: \"向量化 (Embedding)\","
+    },
+    {
+      "line": 183,
+      "text": "typeRerank: \"重排序 (Rerank)\","
+    },
+    {
+      "line": 184,
+      "text": "typeVision: \"视觉识别 (Vision)\","
+    },
+    {
+      "line": 186,
+      "text": "welcome: \"你好!我是您的智能知识库助手。请在“系统设置”中选择模型,上传文档建立索引,然后即可开始提问。\","
+    },
+    {
+      "line": 187,
+      "text": "placeholderWithFiles: \"基于知识库内容提问...\","
+    },
+    {
+      "line": 188,
+      "text": "placeholderEmpty: \"请先上传文件并完成索引...\","
+    },
+    {
+      "line": 189,
+      "text": "analyzing: \"正在检索并生成答案...\","
+    },
+    {
+      "line": 190,
+      "text": "errorGeneric: \"处理您的请求时遇到错误。\","
+    },
+    {
+      "line": 191,
+      "text": "errorLabel: \"错误\","
+    },
+    {
+      "line": 192,
+      "text": "errorNoModel: \"未选择推理模型或配置无效。\","
+    },
+    {
+      "line": 193,
+      "text": "aiDisclaimer: \"AI 可能会犯错。请核实源文件中的重要信息。\","
+    },
+    {
+      "line": 194,
+      "text": "confirmClear: \"确定要清空所有文件及索引吗?\","
+    },
+    {
+      "line": 195,
+      "text": "removeFile: \"移除文件\","
+    },
+    {
+      "line": 196,
+      "text": "apiError: \"缺少配置或 API 密钥无效。\","
+    },
+    {
+      "line": 197,
+      "text": "geminiError: \"API 请求失败。\","
+    },
+    {
+      "line": 198,
+      "text": "processedButNoText: \"无法生成文本回复。\","
+    },
+    {
+      "line": 199,
+      "text": "unitByte: \"字节\","
+    },
+    {
+      "line": 200,
+      "text": "readingFailed: \"读取文件失败\","
+    },
+    {
+      "line": 203,
+      "text": "copy: \"复制内容\","
+    },
+    {
+      "line": 204,
+      "text": "copied: \"已复制\","
+    },
+    {
+      "line": 207,
+      "text": "logout: \"退出登录\","
+    },
+    {
+      "line": 208,
+      "text": "changePassword: \"修改密码\","
+    },
+    {
+      "line": 209,
+      "text": "userManagement: \"用户管理\","
+    },
+    {
+      "line": 210,
+      "text": "userList: \"用户列表\","
+    },
+    {
+      "line": 211,
+      "text": "addUser: \"新增用户\","
+    },
+    {
+      "line": 212,
+      "text": "username: \"用户名\","
+    },
+    {
+      "line": 213,
+      "text": "password: \"密码\","
+    },
+    {
+      "line": 214,
+      "text": "confirmPassword: \"确认密码\","
+    },
+    {
+      "line": 215,
+      "text": "currentPassword: \"当前密码\","
+    },
+    {
+      "line": 216,
+      "text": "newPassword: \"新密码\","
+    },
+    {
+      "line": 217,
+      "text": "createUser: \"创建用户\","
+    },
+    {
+      "line": 218,
+      "text": "admin: \"管理员\","
+    },
+    {
+      "line": 219,
+      "text": "user: \"普通用户\","
+    },
+    {
+      "line": 220,
+      "text": "adminUser: \"设为管理员\",  // 新增,"
+    },
+    {
+      "line": 221,
+      "text": "confirmChange: \"确认修改\","
+    },
+    {
+      "line": 222,
+      "text": "changeUserPassword: \"修改用户密码\","
+    },
+    {
+      "line": 223,
+      "text": "enterNewPassword: \"请输入新密码\","
+    },
+    {
+      "line": 224,
+      "text": "createdAt: \"创建时间\","
+    },
+    {
+      "line": 225,
+      "text": "newChat: \"新建对话\","
+    },
+    {
+      "line": 228,
+      "text": "kbManagement: \"知识库管理\","
+    },
+    {
+      "line": 229,
+      "text": "kbManagementDesc: \"管理您的文档和知识分组\","
+    },
+    {
+      "line": 230,
+      "text": "searchPlaceholder: \"搜索文件名...\","
+    },
+    {
+      "line": 231,
+      "text": "allGroups: \"所有分组\","
+    },
+    {
+      "line": 232,
+      "text": "allStatus: \"所有状态\","
+    },
+    {
+      "line": 236,
+      "text": "uploadFile: \"上传文件\","
+    },
+    {
+      "line": 237,
+      "text": "fileName: \"文件名\","
+    },
+    {
+      "line": 238,
+      "text": "size: \"大小\","
+    },
+    {
+      "line": 239,
+      "text": "status: \"状态\","
+    },
+    {
+      "line": 240,
+      "text": "groups: \"分组\","
+    },
+    {
+      "line": 241,
+      "text": "actions: \"操作\","
+    },
+    {
+      "line": 242,
+      "text": "groupsActions: \"分组 / 操作\","
+    },
+    {
+      "line": 243,
+      "text": "noFilesFound: \"未找到匹配的文件\","
+    },
+    {
+      "line": 244,
+      "text": "showingRange: \"显示 $1 到 $2 条,共 $3 条\","
+    },
+    {
+      "line": 245,
+      "text": "confirmDeleteFile: \"确定要删除此文件吗?\","
+    },
+    {
+      "line": 246,
+      "text": "fileDeleted: \"文件已删除\","
+    },
+    {
+      "line": 247,
+      "text": "deleteFailed: \"删除失败\","
+    },
+    {
+      "line": 248,
+      "text": "fileAddedToGroup: \"文件已添加到分组\","
+    },
+    {
+      "line": 249,
+      "text": "failedToAddToGroup: \"添加到分组失败\","
+    },
+    {
+      "line": 250,
+      "text": "fileRemovedFromGroup: \"文件已从分组移除\","
+    },
+    {
+      "line": 251,
+      "text": "failedToRemoveFromGroup: \"从分组移除失败\","
+    },
+    {
+      "line": 252,
+      "text": "confirmClearKB: \"警告:此操作将永久删除所有文件及其索引数据。\\n\\n确定要清空知识库吗?\","
+    },
+    {
+      "line": 253,
+      "text": "kbCleared: \"知识库已清空\","
+    },
+    {
+      "line": 254,
+      "text": "clearFailed: \"清空失败\","
+    },
+    {
+      "line": 255,
+      "text": "loginRequired: \"请先登录\","
+    },
+    {
+      "line": 256,
+      "text": "uploadErrors: \"以下文件无法上传\","
+    },
+    {
+      "line": 257,
+      "text": "uploadWarning: \"$1 个文件已准备上传,$2 个文件被过滤\","
+    },
+    {
+      "line": 258,
+      "text": "uploadFailed: \"上传失败\","
+    },
+    {
+      "line": 259,
+      "text": "preview: \"预览\","
+    },
+    {
+      "line": 260,
+      "text": "addGroup: \"添加分组\","
+    },
+    {
+      "line": 261,
+      "text": "delete: \"删除\","
+    },
+    {
+      "line": 262,
+      "text": "retry: \"重试\","
+    },
+    {
+      "line": 263,
+      "text": "retrying: \"重试中...\","
+    },
+    {
+      "line": 264,
+      "text": "retrySuccess: \"重试成功\","
+    },
+    {
+      "line": 265,
+      "text": "retryFailed: \"重试失败\","
+    },
+    {
+      "line": 266,
+      "text": "chunkInfo: \"分片信息\","
+    },
+    {
+      "line": 267,
+      "text": "totalChunks: \"总分片数\","
+    },
+    {
+      "line": 268,
+      "text": "chunkIndex: \"分片\","
+    },
+    {
+      "line": 269,
+      "text": "contentLength: \"字符\","
+    },
+    {
+      "line": 270,
+      "text": "position: \"位置\","
+    },
+    {
+      "line": 273,
+      "text": "reconfigureTitle: \"重新配置文件\","
+    },
+    {
+      "line": 274,
+      "text": "reconfigureDesc: \"修改文件处理设置\","
+    },
+    {
+      "line": 275,
+      "text": "indexingConfigTitle: \"文档索引配置\","
+    },
+    {
+      "line": 276,
+      "text": "indexingConfigDesc: \"配置文档处理参数,选择处理模式\","
+    },
+    {
+      "line": 277,
+      "text": "pendingFiles: \"待处理文件\","
+    },
+    {
+      "line": 278,
+      "text": "processingMode: \"处理模式\","
+    },
+    {
+      "line": 279,
+      "text": "analyzingFile: \"分析中...\","
+    },
+    {
+      "line": 280,
+      "text": "recommendationReason: \"推荐理由\","
+    },
+    {
+      "line": 281,
+      "text": "fastMode: \"快速模式\","
+    },
+    {
+      "line": 282,
+      "text": "fastModeDesc: \"简单提取文本,速度快,无额外成本,适合纯文本文档\","
+    },
+    {
+      "line": 283,
+      "text": "preciseMode: \"精准模式\","
+    },
+    {
+      "line": 284,
+      "text": "preciseModeDesc: \"精准识别内容,保留图文混合信息,需要 API 费用\","
+    },
+    {
+      "line": 285,
+      "text": "fastModeFeatures: \"快速模式特点:\","
+    },
+    {
+      "line": 286,
+      "text": "fastFeature1: \"简单提取文本内容\","
+    },
+    {
+      "line": 287,
+      "text": "fastFeature2: \"处理速度快,适合批量处理\","
+    },
+    {
+      "line": 288,
+      "text": "fastFeature3: \"无额外成本\","
+    },
+    {
+      "line": 289,
+      "text": "fastFeature4: \"仅处理文字信息\","
+    },
+    {
+      "line": 290,
+      "text": "fastFeature5: \"适合纯文本文档\","
+    },
+    {
+      "line": 291,
+      "text": "preciseModeFeatures: \"精准模式特点:\","
+    },
+    {
+      "line": 292,
+      "text": "preciseFeature1: \"精准识别内容结构\","
+    },
+    {
+      "line": 293,
+      "text": "preciseFeature2: \"识别图片/图表/表格\","
+    },
+    {
+      "line": 294,
+      "text": "preciseFeature3: \"保留图文混合内容\","
+    },
+    {
+      "line": 295,
+      "text": "preciseFeature4: \"保留页面布局信息\","
+    },
+    {
+      "line": 296,
+      "text": "preciseFeature5: \"需要 API 费用\","
+    },
+    {
+      "line": 297,
+      "text": "preciseFeature6: \"处理时间较长\","
+    },
+    {
+      "line": 298,
+      "text": "embeddingModel: \"嵌入模型\","
+    },
+    {
+      "line": 299,
+      "text": "pleaseSelect: \"请选择...\","
+    },
+    {
+      "line": 300,
+      "text": "pleaseSelectKnowledgeGroupFirst: \"请先选择知识组再保存\","
+    },
+    {
+      "line": 301,
+      "text": "selectUnassignGroupWarning: \"如果您想取消分配知识组,请确认此操作\","
+    },
+    {
+      "line": 302,
+      "text": "chunkConfig: \"切片配置\","
+    },
+    {
+      "line": 303,
+      "text": "chunkSize: \"切片大小 (Tokens)\","
+    },
+    {
+      "line": 304,
+      "text": "min: \"最小\","
+    },
+    {
+      "line": 305,
+      "text": "max: \"上限\","
+    },
+    {
+      "line": 306,
+      "text": "chunkOverlap: \"重叠大小 (Tokens)\","
+    },
+    {
+      "line": 307,
+      "text": "modelLimitsInfo: \"模型限制信息\","
+    },
+    {
+      "line": 308,
+      "text": "model: \"模型\","
+    },
+    {
+      "line": 309,
+      "text": "maxChunkSize: \"切片上限\","
+    },
+    {
+      "line": 310,
+      "text": "maxOverlapSize: \"重叠上限\","
+    },
+    {
+      "line": 311,
+      "text": "maxBatchSize: \"批量限制\","
+    },
+    {
+      "line": 312,
+      "text": "envLimitWeaker: \"环境变量限制更严格\","
+    },
+    {
+      "line": 313,
+      "text": "optimizationTips: \"优化建议\","
+    },
+    {
+      "line": 314,
+      "text": "tipChunkTooLarge: \"切片较大,可能影响检索精度\","
+    },
+    {
+      "line": 315,
+      "text": "tipOverlapSmall: \"建议重叠至少 $1 tokens\","
+    },
+    {
+      "line": 316,
+      "text": "tipMaxValues: \"使用最大值,处理速度可能较慢\","
+    },
+    {
+      "line": 317,
+      "text": "tipPreciseCost: \"精准模式会产生 API 费用,请确认预算\","
+    },
+    {
+      "line": 318,
+      "text": "selectEmbeddingFirst: \"请先选择嵌入模型\","
+    },
+    {
+      "line": 319,
+      "text": "confirmPreciseCost: \"精准模式会产生 API 费用,是否继续?\","
+    },
+    {
+      "line": 320,
+      "text": "startProcessing: \"开始处理\","
+    },
+    {
+      "line": 323,
+      "text": "notebooks: \"知识组\","
+    },
+    {
+      "line": 324,
+      "text": "notebooksDesc: \"管理您的文档和知识分组\","
+    },
+    {
+      "line": 325,
+      "text": "createNotebook: \"新建知识组\","
+    },
+    {
+      "line": 326,
+      "text": "chatWithNotebook: \"基于此知识组对话\","
+    },
+    {
+      "line": 327,
+      "text": "editNotebook: \"编辑知识组\","
+    },
+    {
+      "line": 328,
+      "text": "deleteNotebook: \"删除知识组 (包含文件)\","
+    },
+    {
+      "line": 329,
+      "text": "noDescription: \"无描述\","
+    },
+    {
+      "line": 330,
+      "text": "noNotebooks: \"暂无知识组,点击右上角创建\","
+    },
+    {
+      "line": 331,
+      "text": "createFailed: \"创建失败\","
+    },
+    {
+      "line": 332,
+      "text": "confirmDeleteNotebook: \"确定要删除知识组 \\\"$1\\\" 吗?\\n\\n注意:这将同时永久删除该知识组下的所有文件及其索引数据!\","
+    },
+    {
+      "line": 336,
+      "text": "personalNotebookDesc: \"记录您的个人笔记与灵感\","
+    },
+    {
+      "line": 337,
+      "text": "noNotes: \"暂无个人笔记\","
+    },
+    {
+      "line": 338,
+      "text": "createNote: \"新建笔记\","
+    },
+    {
+      "line": 341,
+      "text": "createNotebookTitle: \"新建知识组\","
+    },
+    {
+      "line": 342,
+      "text": "editNotebookTitle: \"编辑知识组\","
+    },
+    {
+      "line": 343,
+      "text": "createFailedRetry: \"创建失败,请重试\","
+    },
+    {
+      "line": 344,
+      "text": "updateFailedRetry: \"更新失败,请重试\","
+    },
+    {
+      "line": 345,
+      "text": "name: \"名称\","
+    },
+    {
+      "line": 346,
+      "text": "nameHelp: \"一个清晰的名称能帮你快速找到它。\","
+    },
+    {
+      "line": 347,
+      "text": "namePlaceholder: \"例如:量子物理研究...\","
+    },
+    {
+      "line": 348,
+      "text": "shortDescription: \"简短描述\","
+    },
+    {
+      "line": 349,
+      "text": "descPlaceholder: \"一句话描述这个知识组的用途\","
+    },
+    {
+      "line": 350,
+      "text": "creating: \"正在创建...\","
+    },
+    {
+      "line": 351,
+      "text": "createNow: \"立即创建\","
+    },
+    {
+      "line": 352,
+      "text": "saving: \"正在保存...\","
+    },
+    {
+      "line": 353,
+      "text": "save: \"保存\","
+    },
+    {
+      "line": 356,
+      "text": "chatTitle: \"知识库问答\","
+    },
+    {
+      "line": 357,
+      "text": "chatDesc: \"与您的知识库进行智能对话\","
+    },
+    {
+      "line": 358,
+      "text": "viewHistory: \"查看对话历史\","
+    },
+    {
+      "line": 359,
+      "text": "saveSettingsFailed: \"保存设置失败\","
+    },
+    {
+      "line": 360,
+      "text": "loginToUpload: \"请先登录再进行上传\","
+    },
+    {
+      "line": 361,
+      "text": "fileSizeLimitExceeded: \"$1 ($2 - 超过 $3MB 限制)\","
+    },
+    {
+      "line": 362,
+      "text": "unsupportedFileType: \"$1 - 不支持的文件类型 ($2)\","
+    },
+    {
+      "line": 363,
+      "text": "readFailed: \"$1 - 读取失败\","
+    },
+    {
+      "line": 364,
+      "text": "loadHistoryFailed: \"加载对话历史失败\","
+    },
+    {
+      "line": 365,
+      "text": "loadingUserData: \"正在加载用户数据...\","
+    },
+    {
+      "line": 366,
+      "text": "errorMessage: \"错误: $1\","
+    },
+    {
+      "line": 367,
+      "text": "welcomeMessage: \"你好!我是您的智能知识库助手。请选择知识库然后进行提问。\","
+    },
+    {
+      "line": 368,
+      "text": "selectKnowledgeGroup: \"选择知识库分组\","
+    },
+    {
+      "line": 369,
+      "text": "allKnowledgeGroups: \"全部知识库\","
+    },
+    {
+      "line": 370,
+      "text": "unknownGroup: \"未知分组\","
+    },
+    {
+      "line": 371,
+      "text": "selectedGroupsCount: \"已选 $1 个分组\","
+    },
+    {
+      "line": 374,
+      "text": "generalSettings: \"一般配置\","
+    },
+    {
+      "line": 375,
+      "text": "modelManagement: \"模型管理\","
+    },
+    {
+      "line": 376,
+      "text": "languageSettings: \"语言设置\","
+    },
+    {
+      "line": 377,
+      "text": "passwordChangeSuccess: \"密码修改成功\","
+    },
+    {
+      "line": 378,
+      "text": "passwordChangeFailed: \"密码修改失败\","
+    },
+    {
+      "line": 379,
+      "text": "create: \"创建\","
+    },
+    {
+      "line": 383,
+      "text": "navChat: \"对话\","
+    },
+    {
+      "line": 384,
+      "text": "navCoach: \"教练\","
+    },
+    {
+      "line": 385,
+      "text": "navKnowledge: \"知识库\","
+    },
+    {
+      "line": 386,
+      "text": "navKnowledgeGroups: \"知识组\","
+    },
+    {
+      "line": 387,
+      "text": "navNotebook: \"笔记本\","
+    },
+    {
+      "line": 388,
+      "text": "navAgent: \"智能体\","
+    },
+    {
+      "line": 389,
+      "text": "navPlugin: \"插件\","
+    },
+    {
+      "line": 390,
+      "text": "notebookDesc: \"记录您的个人想法和研究笔记。\","
+    },
+    {
+      "line": 391,
+      "text": "newNote: \"新建笔记\","
+    },
+    {
+      "line": 392,
+      "text": "editNote: \"编辑笔记\","
+    },
+    {
+      "line": 393,
+      "text": "noNotesFound: \"未找到笔记\","
+    },
+    {
+      "line": 394,
+      "text": "startByCreatingNote: \"开始创建您的第一条个人笔记。\","
+    },
+    {
+      "line": 395,
+      "text": "navCrawler: \"资源获取\","
+    },
+    {
+      "line": 396,
+      "text": "expandMenu: \"展开菜单\","
+    },
+    {
+      "line": 397,
+      "text": "switchLanguage: \"切换语言\","
+    },
+    {
+      "line": 398,
+      "text": "navGlobal: \"全局\","
+    },
+    {
+      "line": 399,
+      "text": "navTenants: \"租户管理\","
+    },
+    {
+      "line": 400,
+      "text": "navSystemModels: \"系统模型\","
+    },
+    {
+      "line": 401,
+      "text": "navTenantManagement: \"租户管理\","
+    },
+    {
+      "line": 402,
+      "text": "navUsersTeam: \"用户与团队\","
+    },
+    {
+      "line": 403,
+      "text": "navTenantSettings: \"租户设置\","
+    },
+    {
+      "line": 404,
+      "text": "adminConsole: \"管理控制台\","
+    },
+    {
+      "line": 405,
+      "text": "globalDashboard: \"全局仪表盘\","
+    },
+    {
+      "line": 408,
+      "text": "selectKnowledgeGroups: \"选择知识库分组\","
+    },
+    {
+      "line": 409,
+      "text": "searchGroupsPlaceholder: \"搜索分组...\","
+    },
+    {
+      "line": 410,
+      "text": "done: \"完成\","
+    },
+    {
+      "line": 411,
+      "text": "all: \"全部\","
+    },
+    {
+      "line": 412,
+      "text": "noGroupsFound: \"未找到相关分组\","
+    },
+    {
+      "line": 413,
+      "text": "noGroups: \"暂无分组\","
+    },
+    {
+      "line": 416,
+      "text": "autoRefresh: \"自动刷新\","
+    },
+    {
+      "line": 417,
+      "text": "refreshInterval: \"刷新间隔\","
+    },
+    {
+      "line": 420,
+      "text": "errorRenderFlowchart: \"无法渲染流程图\","
+    },
+    {
+      "line": 421,
+      "text": "errorLoadData: \"加载数据失败\","
+    },
+    {
+      "line": 422,
+      "text": "confirmUnsupportedFile: \"文件类型 .$1 可能不受支持,是否继续?\","
+    },
+    {
+      "line": 423,
+      "text": "errorReadFile: \"文件读取失败: $1\","
+    },
+    {
+      "line": 424,
+      "text": "successUploadFile: \"文件上传并关联成功\","
+    },
+    {
+      "line": 425,
+      "text": "errorUploadFile: \"上传失败: $1\","
+    },
+    {
+      "line": 426,
+      "text": "errorProcessFile: \"文件处理失败\","
+    },
+    {
+      "line": 427,
+      "text": "errorTitleContentRequired: \"标题和内容不能为空\","
+    },
+    {
+      "line": 428,
+      "text": "successNoteUpdated: \"笔记已更新\","
+    },
+    {
+      "line": 429,
+      "text": "successNoteCreated: \"笔记已创建\","
+    },
+    {
+      "line": 430,
+      "text": "errorSaveFailed: \"保存失败: $1\","
+    },
+    {
+      "line": 431,
+      "text": "confirmDeleteNote: \"确定要删除这条笔记吗?\","
+    },
+    {
+      "line": 432,
+      "text": "successNoteDeleted: \"笔记已删除\","
+    },
+    {
+      "line": 433,
+      "text": "confirmRemoveFileFromGroup: \"确定要将文件 \\\"$1\\\" 从此知识组移除吗?(文件仍保留在知识库中)\","
+    },
+    {
+      "line": 434,
+      "text": "togglePreviewOpen: \"开启预览\","
+    },
+    {
+      "line": 435,
+      "text": "togglePreviewClose: \"关闭预览\","
+    },
+    {
+      "line": 436,
+      "text": "aiAssistant: \"AI 智能助手\","
+    },
+    {
+      "line": 437,
+      "text": "polishContent: \"润色内容\","
+    },
+    {
+      "line": 438,
+      "text": "expandContent: \"扩写\","
+    },
+    {
+      "line": 439,
+      "text": "summarizeContent: \"精简摘要\","
+    },
+    {
+      "line": 440,
+      "text": "translateToEnglish: \"翻译成英文\","
+    },
+    {
+      "line": 441,
+      "text": "fixGrammar: \"修复语法\","
+    },
+    {
+      "line": 442,
+      "text": "aiCommandInstructPolish: \"请帮我润色这段文字,使其表达更地道、更专业。\","
+    },
+    {
+      "line": 443,
+      "text": "aiCommandInstructExpand: \"请帮我扩写这段文字,增加更多细节,使其更充实和详细。\","
+    },
+    {
+      "line": 444,
+      "text": "aiCommandInstructSummarize: \"请帮我精简这段文字,提取核心观点,生成简洁的摘要。\","
+    },
+    {
+      "line": 445,
+      "text": "aiCommandInstructTranslateToEn: \"请帮我将这段文字翻译成英文。\","
+    },
+    {
+      "line": 446,
+      "text": "aiCommandInstructFixGrammar: \"请检查并修复这段文字中的语法和拼写错误。\","
+    },
+    {
+      "line": 447,
+      "text": "aiCommandsPreset: \"常用指令\","
+    },
+    {
+      "line": 448,
+      "text": "aiCommandsCustom: \"自定义需求\","
+    },
+    {
+      "line": 449,
+      "text": "aiCommandsCustomPlaceholder: \"例如:把这段话改写得更正式一点...\","
+    },
+    {
+      "line": 450,
+      "text": "aiCommandsReferenceContext: \"参考上下文 (前200字):\","
+    },
+    {
+      "line": 451,
+      "text": "aiCommandsStartGeneration: \"开始生成\","
+    },
+    {
+      "line": 452,
+      "text": "aiCommandsResult: \"AI 建议\","
+    },
+    {
+      "line": 453,
+      "text": "aiCommandsGenerating: \"生成中...\","
+    },
+    {
+      "line": 454,
+      "text": "aiCommandsApplyResult: \"替换选区\","
+    },
+    {
+      "line": 455,
+      "text": "aiCommandsGoBack: \"返回修改\","
+    },
+    {
+      "line": 456,
+      "text": "aiCommandsReset: \"清空重置\","
+    },
+    {
+      "line": 457,
+      "text": "aiCommandsModalPreset: \"选择预设指令\","
+    },
+    {
+      "line": 458,
+      "text": "aiCommandsModalCustom: \"或输入自定义指令\","
+    },
+    {
+      "line": 459,
+      "text": "aiCommandsModalCustomPlaceholder: \"告诉 AI 你想做什么...\","
+    },
+    {
+      "line": 460,
+      "text": "aiCommandsModalBasedOnSelection: \"将基于以下选中文本处理:\","
+    },
+    {
+      "line": 461,
+      "text": "aiCommandsModalResult: \"生成结果\","
+    },
+    {
+      "line": 462,
+      "text": "aiCommandsModalApply: \"采用此结果\","
+    },
+    {
+      "line": 463,
+      "text": "noteTitlePlaceholder: \"笔记标题\","
+    },
+    {
+      "line": 464,
+      "text": "noteContentPlaceholder: \"开始写作 (支持 Markdown)...\","
+    },
+    {
+      "line": 465,
+      "text": "markdownPreviewArea: \"Markdown 预览区域\","
+    },
+    {
+      "line": 466,
+      "text": "back: \"返回\","
+    },
+    {
+      "line": 467,
+      "text": "chatWithGroup: \"基于此知识组进行对话\","
+    },
+    {
+      "line": 468,
+      "text": "chatWithFile: \"基于此文件进行对话\","
+    },
+    {
+      "line": 469,
+      "text": "filesCountLabel: \"文件 ($1)\","
+    },
+    {
+      "line": 470,
+      "text": "notesCountLabel: \"笔记 ($1)\","
+    },
+    {
+      "line": 471,
+      "text": "indexIntoKB: \"索引到知识库\","
+    },
+    {
+      "line": 472,
+      "text": "noFilesOrNotes: \"暂无$1\","
+    },
+    {
+      "line": 473,
+      "text": "importFolder: \"导入文件夹\","
+    },
+    {
+      "line": 476,
+      "text": "createPDFNote: \"创建PDF笔记\","
+    },
+    {
+      "line": 477,
+      "text": "screenshotPreview: \"截图预览\","
+    },
+    {
+      "line": 478,
+      "text": "associateKnowledgeGroup: \"关联知识组\","
+    },
+    {
+      "line": 479,
+      "text": "globalNoSpecificGroup: \"全局 (无特定知识组)\","
+    },
+    {
+      "line": 480,
+      "text": "title: \"标题\","
+    },
+    {
+      "line": 481,
+      "text": "enterNoteTitle: \"输入笔记标题\","
+    },
+    {
+      "line": 482,
+      "text": "contentOCR: \"内容 (OCR提取的文本)\","
+    },
+    {
+      "line": 483,
+      "text": "extractingText: \"正在提取文本...\","
+    },
+    {
+      "line": 484,
+      "text": "analyzingImage: \"正在分析图片并提取文字...\","
+    },
+    {
+      "line": 485,
+      "text": "noTextExtracted: \"未提取到文本\","
+    },
+    {
+      "line": 486,
+      "text": "saveNote: \"保存笔记\","
+    },
+    {
+      "line": 489,
+      "text": "page: \"第\","
+    },
+    {
+      "line": 490,
+      "text": "placeholderText: \"OCR提取的文本将显示在这里,您可以编辑...\","
+    },
+    {
+      "line": 493,
+      "text": "createNewNotebook: \"新建知识组\","
+    },
+    {
+      "line": 494,
+      "text": "nameField: \"名称\","
+    },
+    {
+      "line": 496,
+      "text": "exampleResearch: \"例如:量子物理研究...\","
+    },
+    {
+      "line": 497,
+      "text": "shortDescriptionField: \"简短描述\","
+    },
+    {
+      "line": 498,
+      "text": "describePurpose: \"一句话描述这个知识组的用途\","
+    },
+    {
+      "line": 499,
+      "text": "creationFailed: \"创建失败,请重试\","
+    },
+    {
+      "line": 502,
+      "text": "preparingPDFConversion: \"准备转换PDF...\","
+    },
+    {
+      "line": 503,
+      "text": "pleaseWait: \"请稍候,这可能需要几分钟时间\","
+    },
+    {
+      "line": 504,
+      "text": "convertingPDF: \"正在转换PDF...\","
+    },
+    {
+      "line": 505,
+      "text": "pdfConversionFailed: \"PDF转换失败\","
+    },
+    {
+      "line": 506,
+      "text": "pdfConversionError: \"无法转换此文件为PDF格式,请检查文件是否损坏或格式不支持\","
+    },
+    {
+      "line": 507,
+      "text": "pdfLoadFailed: \"PDF加载失败\","
+    },
+    {
+      "line": 508,
+      "text": "pdfLoadError: \"无法在浏览器中显示PDF,请尝试下载或在新窗口中打开\","
+    },
+    {
+      "line": 509,
+      "text": "downloadingPDF: \"下载PDF中...\","
+    },
+    {
+      "line": 510,
+      "text": "loadingPDF: \"加载PDF中...\","
+    },
+    {
+      "line": 511,
+      "text": "zoomOut: \"缩小\","
+    },
+    {
+      "line": 512,
+      "text": "zoomIn: \"放大\","
+    },
+    {
+      "line": 513,
+      "text": "resetZoom: \"重置缩放\","
+    },
+    {
+      "line": 514,
+      "text": "selectPageNumber: \"选择页码:\","
+    },
+    {
+      "line": 515,
+      "text": "enterPageNumber: \"输入想要选取的页码\","
+    },
+    {
+      "line": 516,
+      "text": "exitSelectionMode: \"退出选择模式\","
+    },
+    {
+      "line": 517,
+      "text": "clickToSelectAndNote: \"点击框选区域并记笔记\","
+    },
+    {
+      "line": 518,
+      "text": "regeneratePDF: \"重新生成 PDF\","
+    },
+    {
+      "line": 519,
+      "text": "downloadPDF: \"下载 PDF\","
+    },
+    {
+      "line": 520,
+      "text": "openInNewWindow: \"在新窗口中打开\","
+    },
+    {
+      "line": 521,
+      "text": "exitFullscreen: \"退出全屏\","
+    },
+    {
+      "line": 522,
+      "text": "fullscreenDisplay: \"全屏显示\","
+    },
+    {
+      "line": 523,
+      "text": "pdfPreview: \"PDF预览\","
+    },
+    {
+      "line": 524,
+      "text": "converting: \"转换中...\","
+    },
+    {
+      "line": 525,
+      "text": "generatePDFPreview: \"生成PDF预览\","
+    },
+    {
+      "line": 526,
+      "text": "previewNotSupported: \"该格式不支持预览\","
+    },
+    {
+      "line": 529,
+      "text": "confirmRegeneratePDF: \"确定要重新生成 PDF 吗?这将覆盖当前的预览文件。\","
+    },
+    {
+      "line": 532,
+      "text": "pdfPreviewReady: \"PDF预览\","
+    },
+    {
+      "line": 533,
+      "text": "convertingInProgress: \"转换中...\","
+    },
+    {
+      "line": 534,
+      "text": "conversionFailed: \"转换失败\","
+    },
+    {
+      "line": 535,
+      "text": "generatePDFPreviewButton: \"生成PDF预览\","
+    },
+    {
+      "line": 539,
+      "text": "requestRegenerationFailed: \"请求重新生成失败\","
+    },
+    {
+      "line": 540,
+      "text": "downloadPDFFailed: \"PDF 下载失败\","
+    },
+    {
+      "line": 541,
+      "text": "openPDFInNewTabFailed: \"在新标签页打开 PDF 失败\","
+    },
+    {
+      "line": 544,
+      "text": "invalidFile: \"无效的文件\","
+    },
+    {
+      "line": 545,
+      "text": "incompleteFileInfo: \"文件信息不完整,将使用快速模式\","
+    },
+    {
+      "line": 546,
+      "text": "unsupportedFileFormat: \"不支持的文件格式: .$1\","
+    },
+    {
+      "line": 547,
+      "text": "willUseFastMode: \"将使用快速模式 (仅文本提取)\","
+    },
+    {
+      "line": 548,
+      "text": "formatNoPrecise: \"格式 .$1 不支持精准模式\","
+    },
+    {
+      "line": 549,
+      "text": "smallFileFastOk: \"文件较小,快速模式即可满足需求\","
+    },
+    {
+      "line": 550,
+      "text": "mixedContentPreciseRecommended: \"文件包含图文混合内容,建议使用精准模式\","
+    },
+    {
+      "line": 551,
+      "text": "willIncurApiCost: \"会产生 API 费用\","
+    },
+    {
+      "line": 552,
+      "text": "largeFilePreciseRecommended: \"文件较大,精准模式可保留完整信息\","
+    },
+    {
+      "line": 553,
+      "text": "longProcessingTime: \"处理时间可能较长\","
+    },
+    {
+      "line": 554,
+      "text": "highApiCost: \"会产生较高 API 费用\","
+    },
+    {
+      "line": 555,
+      "text": "considerFileSplitting: \"建议考虑文件拆分\","
+    },
+    {
+      "line": 558,
+      "text": "dragDropUploadTitle: \"拖拽文件到这里上传\","
+    },
+    {
+      "line": 559,
+      "text": "dragDropUploadDesc: \"或点击下方按钮选择文件\","
+    },
+    {
+      "line": 560,
+      "text": "supportedFormats: \"支持格式\","
+    },
+    {
+      "line": 561,
+      "text": "browseFiles: \"浏览文件\","
+    },
+    {
+      "line": 564,
+      "text": "recommendationMsg: \"推荐使用$1模式: $2\","
+    },
+    {
+      "line": 565,
+      "text": "autoAdjustChunk: \"切片大小自动调整为上限 $1\","
+    },
+    {
+      "line": 566,
+      "text": "autoAdjustOverlap: \"重叠大小自动调整为上限 $1\","
+    },
+    {
+      "line": 567,
+      "text": "autoAdjustOverlapMin: \"重叠大小自动调整为最小值 $1\","
+    },
+    {
+      "line": 568,
+      "text": "loadLimitsFailed: \"无法加载模型限制,将使用默认配置\","
+    },
+    {
+      "line": 569,
+      "text": "maxValueMsg: \"最大值为 $1\","
+    },
+    {
+      "line": 570,
+      "text": "overlapRatioLimit: \"不能超过切片大小的50% ($1)\","
+    },
+    {
+      "line": 571,
+      "text": "onlyAdminCanModify: \"只有管理员可以修改系统设置\","
+    },
+    {
+      "line": 572,
+      "text": "dragToSelect: \"拖动鼠标选择范围 • 按 ESC 取消\","
+    },
+    {
+      "line": 575,
+      "text": "fillTargetName: \"请填写目标知识组名称\","
+    },
+    {
+      "line": 576,
+      "text": "submitFailed: \"提交失败: $1\","
+    },
+    {
+      "line": 577,
+      "text": "importFolderTitle: \"导入本地文件夹\","
+    },
+    {
+      "line": 578,
+      "text": "importFolderTip: \"提示: 请选择一个本地文件夹。系统将读取并上传文件夹内所有支持的文档。\","
+    },
+    {
+      "line": 579,
+      "text": "lblTargetGroup: \"目标知识组名称\","
+    },
+    {
+      "line": 580,
+      "text": "placeholderNewGroup: \"新分组名称\","
+    },
+    {
+      "line": 581,
+      "text": "importToCurrentGroup: \"将导入到当前所在的分组\","
+    },
+    {
+      "line": 582,
+      "text": "nextStep: \"下一步\","
+    },
+    {
+      "line": 583,
+      "text": "selectedFilesCount: \"已选择 $1 个文件\","
+    },
+    {
+      "line": 584,
+      "text": "clickToSelectFolder: \"点击选择本地文件夹\","
+    },
+    {
+      "line": 585,
+      "text": "selectFolderTip: \"将读取文件夹内所有支持的文件\","
+    },
+    {
+      "line": 586,
+      "text": "importComplete: \"导入完成\","
+    },
+    {
+      "line": 587,
+      "text": "importedFromLocalFolder: \"从本地文件夹导入: $1\","
+    },
+    {
+      "line": 590,
+      "text": "historyTitle: \"对话历史\","
+    },
+    {
+      "line": 591,
+      "text": "confirmDeleteHistory: \"确定要删除这条对话历史吗?\","
+    },
+    {
+      "line": 592,
+      "text": "deleteHistorySuccess: \"对话历史删除成功\","
+    },
+    {
+      "line": 593,
+      "text": "deleteHistoryFailed: \"删除对话历史失败\","
+    },
+    {
+      "line": 594,
+      "text": "yesterday: \"昨天\","
+    },
+    {
+      "line": 595,
+      "text": "daysAgo: \"$1天前\","
+    },
+    {
+      "line": 596,
+      "text": "historyMessages: \"$1 条消息\","
+    },
+    {
+      "line": 597,
+      "text": "noHistory: \"暂无对话历史\","
+    },
+    {
+      "line": 598,
+      "text": "noHistoryDesc: \"开始一次对话来创建历史记录\","
+    },
+    {
+      "line": 599,
+      "text": "loadMore: \"加载更多\","
+    },
+    {
+      "line": 600,
+      "text": "loadingHistoriesFailed: \"加载搜索历史失败\","
+    },
+    {
+      "line": 601,
+      "text": "generalSettingsSubtitle: \"管理您的应用程序首选项。\","
+    },
+    {
+      "line": 602,
+      "text": "userManagementSubtitle: \"管理访问权限和帐户。\","
+    },
+    {
+      "line": 603,
+      "text": "modelManagementSubtitle: \"配置全局 AI 模型。\","
+    },
+    {
+      "line": 604,
+      "text": "kbSettingsSubtitle: \"索引和聊天参数的技术配置。\","
+    },
+    {
+      "line": 605,
+      "text": "tenantsSubtitle: \"全局系统概览。\","
+    },
+    {
+      "line": 607,
+      "text": "allNotes: \"所有笔记\","
+    },
+    {
+      "line": 608,
+      "text": "filterNotesPlaceholder: \"筛选笔记...\","
+    },
+    {
+      "line": 609,
+      "text": "startWritingPlaceholder: \"开始写作...\","
+    },
+    {
+      "line": 610,
+      "text": "previewHeader: \"预览\","
+    },
+    {
+      "line": 611,
+      "text": "noContentToPreview: \"没有可预览的内容\","
+    },
+    {
+      "line": 612,
+      "text": "hidePreview: \"隐藏预览\","
+    },
+    {
+      "line": 613,
+      "text": "showPreview: \"显示预览\","
+    },
+    {
+      "line": 614,
+      "text": "directoryLabel: \"目录\","
+    },
+    {
+      "line": 615,
+      "text": "uncategorized: \"未分类\","
+    },
+    {
+      "line": 616,
+      "text": "enterNamePlaceholder: \"输入名称...\","
+    },
+    {
+      "line": 617,
+      "text": "subFolderPlaceholder: \"子文件夹...\","
+    },
+    {
+      "line": 618,
+      "text": "categoryCreated: \"分类已创建\","
+    },
+    {
+      "line": 619,
+      "text": "failedToCreateCategory: \"创建分类失败\","
+    },
+    {
+      "line": 620,
+      "text": "failedToDeleteCategory: \"删除分类失败\","
+    },
+    {
+      "line": 621,
+      "text": "confirmDeleteCategory: \"您确定要删除此分类吗?\","
+    },
+    {
+      "line": 622,
+      "text": "kbSettingsSaved: \"检索与对话配置已保存\","
+    },
+    {
+      "line": 623,
+      "text": "failedToSaveSettings: \"保存设置失败\","
+    },
+    {
+      "line": 624,
+      "text": "actionFailed: \"操作失败\","
+    },
+    {
+      "line": 625,
+      "text": "userAddedToOrganization: \"用户已添加到组织\","
+    },
+    {
+      "line": 626,
+      "text": "featureUpdated: \"功能已更新\","
+    },
+    {
+      "line": 627,
+      "text": "roleTenantAdmin: \"租户管理员\","
+    },
+    {
+      "line": 628,
+      "text": "roleRegularUser: \"普通用户\","
+    },
+    {
+      "line": 629,
+      "text": "creatingRegularUser: \"正在创建普通用户\","
+    },
+    {
+      "line": 630,
+      "text": "editUserRole: \"修改用户角色\","
+    },
+    {
+      "line": 631,
+      "text": "targetRole: \"目标角色\","
+    },
+    {
+      "line": 632,
+      "text": "editCategory: \"编辑分类\","
+    },
+    {
+      "line": 633,
+      "text": "totalTenants: \"总租户数\","
+    },
+    {
+      "line": 634,
+      "text": "systemUsers: \"系统用户\","
+    },
+    {
+      "line": 635,
+      "text": "systemHealth: \"系统健康\","
+    },
+    {
+      "line": 636,
+      "text": "operational: \"运行正常\","
+    },
+    {
+      "line": 637,
+      "text": "orgManagement: \"组织管理\","
+    },
+    {
+      "line": 638,
+      "text": "globalTenantControl: \"全局租户控制\","
+    },
+    {
+      "line": 639,
+      "text": "newTenant: \"新租户\","
+    },
+    {
+      "line": 640,
+      "text": "domainOptional: \"域名 (可选)\","
+    },
+    {
+      "line": 641,
+      "text": "saveChanges: \"保存修改\","
+    },
+    {
+      "line": 642,
+      "text": "modelConfiguration: \"模型配置\","
+    },
+    {
+      "line": 643,
+      "text": "defaultLLMModel: \"默认推理模型\","
+    },
+    {
+      "line": 644,
+      "text": "selectLLM: \"选择 LLM\","
+    },
+    {
+      "line": 645,
+      "text": "selectEmbedding: \"选择 Embedding\","
+    },
+    {
+      "line": 646,
+      "text": "rerankModel: \"Rerank 模型\","
+    },
+    {
+      "line": 647,
+      "text": "none: \"无\","
+    },
+    {
+      "line": 648,
+      "text": "indexingChunkingConfig: \"索引与切片配置\","
+    },
+    {
+      "line": 649,
+      "text": "chatHyperparameters: \"聊天超参数\","
+    },
+    {
+      "line": 650,
+      "text": "temperature: \"随机性 (Temperature)\","
+    },
+    {
+      "line": 651,
+      "text": "precise: \"精确\","
+    },
+    {
+      "line": 652,
+      "text": "creative: \"创意\","
+    },
+    {
+      "line": 653,
+      "text": "maxResponseTokens: \"最大响应标识 (Max Tokens)\","
+    },
+    {
+      "line": 654,
+      "text": "retrievalSearchSettings: \"检索与搜索设置\","
+    },
+    {
+      "line": 655,
+      "text": "topK: \"召回数量 (Top K)\","
+    },
+    {
+      "line": 656,
+      "text": "similarityThreshold: \"相似度阈值\","
+    },
+    {
+      "line": 657,
+      "text": "enableHybridSearch: \"启用混合检索\","
+    },
+    {
+      "line": 658,
+      "text": "hybridSearchDesc: \"同时使用向量和全文检索以提高召回率\","
+    },
+    {
+      "line": 659,
+      "text": "hybridWeight: \"混合权重 (0.0=全文, 1.0=向量)\","
+    },
+    {
+      "line": 660,
+      "text": "pureText: \"纯文本\","
+    },
+    {
+      "line": 661,
+      "text": "pureVector: \"纯向量\","
+    },
+    {
+      "line": 662,
+      "text": "enableQueryExpansion: \"启用查询扩展\","
+    },
+    {
+      "line": 663,
+      "text": "queryExpansionDesc: \"生成多个查询变体以提高覆盖率\","
+    },
+    {
+      "line": 664,
+      "text": "enableHyDE: \"启用 HyDE\","
+    },
+    {
+      "line": 665,
+      "text": "hydeDesc: \"生成假设回答以改善语义搜索\","
+    },
+    {
+      "line": 666,
+      "text": "enableReranking: \"启用重排序 (Rerank)\","
+    },
+    {
+      "line": 667,
+      "text": "rerankingDesc: \"使用 Rerank 模型对结果进行二次排序\","
+    },
+    {
+      "line": 668,
+      "text": "broad: \"宽泛\","
+    },
+    {
+      "line": 669,
+      "text": "strict: \"严格\","
+    },
+    {
+      "line": 670,
+      "text": "maxInput: \"最大输入\","
+    },
+    {
+      "line": 671,
+      "text": "dimensions: \"维度\","
+    },
+    {
+      "line": 672,
+      "text": "defaultBadge: \"默认\","
+    },
+    {
+      "line": 673,
+      "text": "dims: \"维度: $1\","
+    },
+    {
+      "line": 674,
+      "text": "ctx: \"上下文: $1\","
+    },
+    {
+      "line": 676,
+      "text": "configured: \"已配置\","
+    },
+    {
+      "line": 677,
+      "text": "groupUpdated: \"分组已更新\","
+    },
+    {
+      "line": 678,
+      "text": "groupDeleted: \"分组已删除\","
+    },
+    {
+      "line": 679,
+      "text": "groupCreated: \"分组已创建\","
+    },
+    {
+      "line": 680,
+      "text": "navCatalog: \"目录\","
+    },
+    {
+      "line": 681,
+      "text": "allDocuments: \"所有文档\","
+    },
+    {
+      "line": 682,
+      "text": "categories: \"分类\","
+    },
+    {
+      "line": 683,
+      "text": "uncategorizedFiles: \"未分类文件\","
+    },
+    {
+      "line": 684,
+      "text": "category: \"分类\","
+    },
+    {
+      "line": 685,
+      "text": "statusReadyDesc: \"已索引可查询\","
+    },
+    {
+      "line": 686,
+      "text": "statusIndexingDesc: \"正在建立词向量索引\","
+    },
+    {
+      "line": 687,
+      "text": "selectCategory: \"选择分类\","
+    },
+    {
+      "line": 688,
+      "text": "noneUncategorized: \"无未分类文件\","
+    },
+    {
+      "line": 689,
+      "text": "previous: \"上一页\","
+    },
+    {
+      "line": 690,
+      "text": "next: \"下一页\","
+    },
+    {
+      "line": 691,
+      "text": "createCategory: \"创建分类\","
+    },
+    {
+      "line": 692,
+      "text": "categoryDesc: \"描述您的知识分类\","
+    },
+    {
+      "line": 693,
+      "text": "categoryName: \"分类名称\","
+    },
+    {
+      "line": 694,
+      "text": "createCategoryBtn: \"立即创建\","
+    },
+    {
+      "line": 695,
+      "text": "newGroup: \"新建分组\","
+    },
+    {
+      "line": 696,
+      "text": "noKnowledgeGroups: \"暂无知识库分组\","
+    },
+    {
+      "line": 697,
+      "text": "createGroupDesc: \"开始创建您的第一个知识库分组并上传相关文档。\","
+    },
+    {
+      "line": 698,
+      "text": "noDescriptionProvided: \"未提供描述\","
+    },
+    {
+      "line": 699,
+      "text": "browseManageFiles: \"浏览并管理该分组下的文件和笔记。\","
+    },
+    {
+      "line": 700,
+      "text": "filterGroupFiles: \"根据名称搜索分组内文件...\","
+    },
+    {
+      "line": 704,
+      "text": "agentTitle: \"智能体中心\","
+    },
+    {
+      "line": 705,
+      "text": "agentDesc: \"管理和运行您的 AI 助手,协助完成复杂任务。\","
+    },
+    {
+      "line": 706,
+      "text": "createAgent: \"创建智能体\","
+    },
+    {
+      "line": 707,
+      "text": "searchAgent: \"搜索智能体...\","
+    },
+    {
+      "line": 708,
+      "text": "statusRunning: \"运行中\","
+    },
+    {
+      "line": 709,
+      "text": "statusStopped: \"已停止\","
+    },
+    {
+      "line": 710,
+      "text": "updatedAtPrefix: \"最后更新于 \","
+    },
+    {
+      "line": 711,
+      "text": "btnChat: \"开始对话\","
+    },
+    {
+      "line": 714,
+      "text": "agent1Name: \"数据分析专家\","
+    },
+    {
+      "line": 715,
+      "text": "agent1Desc: \"精通 SQL 和数据可视化,能够从复杂数据中提取洞察。\","
+    },
+    {
+      "line": 716,
+      "text": "agent2Name: \"代码审查助手\","
+    },
+    {
+      "line": 717,
+      "text": "agent2Desc: \"自动检查代码质量,提供重构建议和性能优化方案。\","
+    },
+    {
+      "line": 718,
+      "text": "agent3Name: \"学术论文润色\","
+    },
+    {
+      "line": 719,
+      "text": "agent3Desc: \"专业的学术写作助手,帮助优化论文结构和语言表达。\","
+    },
+    {
+      "line": 720,
+      "text": "agent4Name: \"法律顾问\","
+    },
+    {
+      "line": 721,
+      "text": "agent4Desc: \"提供法律条文查询和基础法律建议,协助起草合同。\","
+    },
+    {
+      "line": 722,
+      "text": "agent5Name: \"市场研究员\","
+    },
+    {
+      "line": 723,
+      "text": "agent5Desc: \"分析行业趋势,生成竞争对手调研报告。\","
+    },
+    {
+      "line": 724,
+      "text": "agent6Name: \"系统运维专家\","
+    },
+    {
+      "line": 725,
+      "text": "agent6Desc: \"监控系统健康,自动处理常见告警和排障。\","
+    },
+    {
+      "line": 726,
+      "text": "agent7Name: \"财务审计师\","
+    },
+    {
+      "line": 727,
+      "text": "agent7Desc: \"自动化报表审计,识别财务风险和异常交易。\","
+    },
+    {
+      "line": 728,
+      "text": "agent1Time: \"2 小时前\","
+    },
+    {
+      "line": 729,
+      "text": "agent2Time: \"5 小时前\","
+    },
+    {
+      "line": 730,
+      "text": "agent3Time: \"昨天\","
+    },
+    {
+      "line": 731,
+      "text": "agent4Time: \"2 天前\","
+    },
+    {
+      "line": 732,
+      "text": "agent5Time: \"3 天前\","
+    },
+    {
+      "line": 733,
+      "text": "agent6Time: \"5 天前\","
+    },
+    {
+      "line": 734,
+      "text": "agent7Time: \"1 周前\","
+    },
+    {
+      "line": 737,
+      "text": "pluginTitle: \"插件中心\","
+    },
+    {
+      "line": 738,
+      "text": "pluginDesc: \"扩展知识库的功能,集成外部工具和服务。\","
+    },
+    {
+      "line": 739,
+      "text": "searchPlugin: \"搜索插件...\","
+    },
+    {
+      "line": 740,
+      "text": "installPlugin: \"安装插件\","
+    },
+    {
+      "line": 741,
+      "text": "installedPlugin: \"已安装\","
+    },
+    {
+      "line": 742,
+      "text": "updatePlugin: \"有更新\","
+    },
+    {
+      "line": 743,
+      "text": "pluginOfficial: \"官方\","
+    },
+    {
+      "line": 744,
+      "text": "pluginCommunity: \"社区\","
+    },
+    {
+      "line": 745,
+      "text": "pluginBy: \"由 \","
+    },
+    {
+      "line": 746,
+      "text": "pluginConfig: \"插件配置\","
+    },
+    {
+      "line": 749,
+      "text": "plugin1Name: \"Web 搜索\","
+    },
+    {
+      "line": 750,
+      "text": "plugin1Desc: \"赋予 AI 实时访问互联网的能力,获取最新信息。\","
+    },
+    {
+      "line": 751,
+      "text": "plugin2Name: \"PDF 文档解析\","
+    },
+    {
+      "line": 752,
+      "text": "plugin2Desc: \"深度解析复杂 PDF 布局,提取表格和数学公式。\","
+    },
+    {
+      "line": 753,
+      "text": "plugin3Name: \"GitHub 集成\","
+    },
+    {
+      "line": 754,
+      "text": "plugin3Desc: \"直接访问 GitHub 仓库,进行代码提交和 issue 管理。\","
+    },
+    {
+      "line": 755,
+      "text": "plugin4Name: \"Google 日历\","
+    },
+    {
+      "line": 756,
+      "text": "plugin4Desc: \"同步您的日程安排,自动创建会议提醒。\","
+    },
+    {
+      "line": 757,
+      "text": "plugin5Name: \"SQL 数据库连接\","
+    },
+    {
+      "line": 758,
+      "text": "plugin5Desc: \"安全地连接到您的数据库,执行自然语言查询。\","
+    },
+    {
+      "line": 759,
+      "text": "plugin6Name: \"Slack 通知\","
+    },
+    {
+      "line": 760,
+      "text": "plugin6Desc: \"将 AI 生成的报告直接发送到指定的 Slack 频道。\","
+    },
+    {
+      "line": 763,
+      "text": "addSubcategory: \"添加子分类\","
+    },
+    {
+      "line": 764,
+      "text": "parentCategory: \"父分类 (可选)\","
+    },
+    {
+      "line": 765,
+      "text": "noParentTopLevel: \"无父分类(顶级)\","
+    },
+    {
+      "line": 766,
+      "text": "useHierarchyImport: \"按文件夹层级创建分类\","
+    },
+    {
+      "line": 767,
+      "text": "useHierarchyImportDesc: \"启用后将为每个子文件夹创建对应的子分类,并将文件导入到匹配的分类中。\","
+    },
+    {
+      "line": 770,
+      "text": "importImmediate: \"立即导入\","
+    },
+    {
+      "line": 771,
+      "text": "importScheduled: \"定时导入\","
+    },
+    {
+      "line": 772,
+      "text": "lblServerPath: \"服务器文件夹路径\","
+    },
+    {
+      "line": 773,
+      "text": "placeholderServerPath: \"例如: /data/documents\","
+    },
+    {
+      "line": 774,
+      "text": "scheduledImportTip: \"服务器端定时导入:服务器将在指定时间读取该路径下的文件并自动导入。请确保服务器有访问该路径的权限。\","
+    },
+    {
+      "line": 775,
+      "text": "lblScheduledTime: \"执行时间\","
+    },
+    {
+      "line": 776,
+      "text": "scheduledTimeHint: \"到达指定时间后,服务器将自动执行导入任务。\","
+    },
+    {
+      "line": 777,
+      "text": "scheduleImport: \"创建定时任务\","
+    },
+    {
+      "line": 778,
+      "text": "scheduleTaskCreated: \"定时导入任务已创建\","
+    },
+    {
+      "line": 779,
+      "text": "fillServerPath: \"请输入服务器文件夹路径\","
+    },
+    {
+      "line": 780,
+      "text": "invalidDateTime: \"请输入有效的日期时间\","
+    },
+    {
+      "line": 783,
+      "text": "importTasksTitle: \"定时计划\","
+    },
+    {
+      "line": 784,
+      "text": "noTasksFound: \"暂无任务\","
+    },
+    {
+      "line": 785,
+      "text": "sourcePath: \"源路径\","
+    },
+    {
+      "line": 786,
+      "text": "targetGroup: \"目标分组\","
+    },
+    {
+      "line": 787,
+      "text": "scheduledAt: \"计划执行时间\","
+    },
+    {
+      "line": 788,
+      "text": "confirmDeleteTask: \"确定要删除此导入任务记录吗?\","
+    },
+    {
+      "line": 789,
+      "text": "deleteTaskFailed: \"删除任务记录失败\","
+    },
+    {
+      "line": 1591,
+      "text": "aiCommandsError: \"エラーが発生しました\","
+    },
+    {
+      "line": 1592,
+      "text": "appTitle: \"Gemini ナレッジベース\","
+    },
+    {
+      "line": 1593,
+      "text": "loginTitle: \"ログイン\","
+    },
+    {
+      "line": 1594,
+      "text": "loginDesc: \"システムに入るためのキーを入力してください\","
+    },
+    {
+      "line": 1595,
+      "text": "loginButton: \"ログイン\","
+    },
+    {
+      "line": 1596,
+      "text": "loginError: \"キーは必須です\","
+    },
+    {
+      "line": 1597,
+      "text": "unknown: \"不明\","
+    },
+    {
+      "line": 1598,
+      "text": "unknownError: \"未知のエラー\","
+    },
+    {
+      "line": 1599,
+      "text": "usernamePlaceholder: \"ユーザー名\","
+    },
+    {
+      "line": 1600,
+      "text": "passwordPlaceholder: \"パスワード\","
+    },
+    {
+      "line": 1601,
+      "text": "registerButton: \"登録\","
+    },
+    {
+      "line": 1602,
+      "text": "langZh: \"言語: 中国語\","
+    },
+    {
+      "line": 1603,
+      "text": "langEn: \"言語: 英語\","
+    },
+    {
+      "line": 1604,
+      "text": "langJa: \"言語: 日本語\","
+    },
+    {
+      "line": 1605,
+      "text": "confirm: \"確認\","
+    },
+    {
+      "line": 1606,
+      "text": "cancel: \"キャンセル\","
+    },
+    {
+      "line": 1607,
+      "text": "confirmTitle: \"操作の確認\","
+    },
+    {
+      "line": 1608,
+      "text": "confirmDeleteGroup: \"グループ \\\"$1\\\" を削除してもよろしいですか?\","
+    },
+    {
+      "line": 1610,
+      "text": "sidebarTitle: \"索引とチャットの設定\","
+    },
+    {
+      "line": 1611,
+      "text": "backToWorkspace: \"ワークスペースに戻る\","
+    },
+    {
+      "line": 1612,
+      "text": "goToAdmin: \"管理画面へ\","
+    },
+    {
+      "line": 1613,
+      "text": "sidebarDesc: \"ドキュメントとモデル管理\","
+    },
+    {
+      "line": 1614,
+      "text": "tabFiles: \"ドキュメント\","
+    },
+    {
+      "line": 1615,
+      "text": "files: \"ファイル\","
+    },
+    {
+      "line": 1616,
+      "text": "notes: \"メモ\","
+    },
+    {
+      "line": 1617,
+      "text": "tabSettings: \"設定\","
+    },
+    {
+      "line": 1618,
+      "text": "systemConfiguration: \"システム構成\","
+    },
+    {
+      "line": 1619,
+      "text": "noFiles: \"ファイルなし\","
+    },
+    {
+      "line": 1620,
+      "text": "noFilesDesc: \"PDF、Office文書、テキスト、コード、画像などをサポート\","
+    },
+    {
+      "line": 1621,
+      "text": "addFile: \"ファイル追加\","
+    },
+    {
+      "line": 1622,
+      "text": "clearAll: \"全削除\","
+    },
+    {
+      "line": 1623,
+      "text": "uploading: \"処理中\","
+    },
+    {
+      "line": 1624,
+      "text": "statusIndexing: \"ベクトル化中...\","
+    },
+    {
+      "line": 1625,
+      "text": "statusReady: \"完了\","
+    },
+    {
+      "line": 1628,
+      "text": "ragSettings: \"RAG 設定\","
+    },
+    {
+      "line": 1629,
+      "text": "enableRerank: \"リランクを有効にする\","
+    },
+    {
+      "line": 1630,
+      "text": "enableRerankDesc: \"リランクモデルを使用して検索結果を再ランク付けし、精度を向上させます\","
+    },
+    {
+      "line": 1631,
+      "text": "selectRerankModel: \"リランクモデルの選択\","
+    },
+    {
+      "line": 1632,
+      "text": "selectModelPlaceholder: \"モデルを選択...\","
+    },
+    {
+      "line": 1634,
+      "text": "headerModelSelection: \"モデル選択\","
+    },
+    {
+      "line": 1635,
+      "text": "headerHyperparams: \"推論パラメータ\","
+    },
+    {
+      "line": 1636,
+      "text": "headerIndexing: \"インデックスと分割\","
+    },
+    {
+      "line": 1637,
+      "text": "headerRetrieval: \"検索とランク付け\","
+    },
+    {
+      "line": 1638,
+      "text": "btnManageModels: \"プロバイダー管理\","
+    },
+    {
+      "line": 1640,
+      "text": "lblLLM: \"推論モデル (LLM)\","
+    },
+    {
+      "line": 1641,
+      "text": "lblEmbedding: \"埋め込みモデル\","
+    },
+    {
+      "line": 1642,
+      "text": "lblRerankRef: \"リランクモデル\","
+    },
+    {
+      "line": 1643,
+      "text": "lblTemperature: \"温度 (Temperature)\","
+    },
+    {
+      "line": 1644,
+      "text": "lblMaxTokens: \"最大トークン数\","
+    },
+    {
+      "line": 1645,
+      "text": "lblChunkSize: \"チャンクサイズ\","
+    },
+    {
+      "line": 1646,
+      "text": "lblChunkOverlap: \"オーバーラップ\","
+    },
+    {
+      "line": 1647,
+      "text": "lblTopK: \"検索数 (Top K)\","
+    },
+    {
+      "line": 1648,
+      "text": "lblRerank: \"リランク有効化\","
+    },
+    {
+      "line": 1650,
+      "text": "idxModalTitle: \"インデックス設定\","
+    },
+    {
+      "line": 1651,
+      "text": "idxDesc: \"取り込みの前に分割ルールと埋め込みモデルを設定してください。\","
+    },
+    {
+      "line": 1652,
+      "text": "idxFiles: \"対象ファイル\","
+    },
+    {
+      "line": 1653,
+      "text": "idxMethod: \"分割設定\","
+    },
+    {
+      "line": 1654,
+      "text": "idxEmbeddingModel: \"埋め込みモデル\","
+    },
+    {
+      "line": 1655,
+      "text": "idxStart: \"インデックス開始\","
+    },
+    {
+      "line": 1656,
+      "text": "idxCancel: \"キャンセル\","
+    },
+    {
+      "line": 1657,
+      "text": "idxAuto: \"自動\","
+    },
+    {
+      "line": 1658,
+      "text": "idxCustom: \"カスタム\","
+    },
+    {
+      "line": 1660,
+      "text": "mmTitle: \"モデルプロバイダー管理\","
+    },
+    {
+      "line": 1661,
+      "text": "mmAddBtn: \"モデル追加\","
+    },
+    {
+      "line": 1662,
+      "text": "mmEdit: \"編集\","
+    },
+    {
+      "line": 1663,
+      "text": "mmDelete: \"削除\","
+    },
+    {
+      "line": 1664,
+      "text": "mmEmpty: \"設定されたモデルはありません\","
+    },
+    {
+      "line": 1665,
+      "text": "mmFormName: \"表示名\","
+    },
+    {
+      "line": 1666,
+      "text": "mmFormProvider: \"プロバイダー\","
+    },
+    {
+      "line": 1667,
+      "text": "mmFormModelId: \"モデルID (例: gpt-4o)\","
+    },
+    {
+      "line": 1669,
+      "text": "mmFormType: \"機能タイプ\","
+    },
+    {
+      "line": 1670,
+      "text": "mmFormVision: \"画像認識対応\","
+    },
+    {
+      "line": 1671,
+      "text": "mmFormDimensions: \"ベクトル次元\","
+    },
+    {
+      "line": 1672,
+      "text": "mmFormDimensionsHelp: \"埋め込みベクトルの次元数、一般的な値:1536、3072\","
+    },
+    {
+      "line": 1673,
+      "text": "mmSave: \"保存\","
+    },
+    {
+      "line": 1674,
+      "text": "mmCancel: \"キャンセル\","
+    },
+    {
+      "line": 1675,
+      "text": "mmErrorNotAuthenticated: \"認証されていません、操作できません\","
+    },
+    {
+      "line": 1676,
+      "text": "mmErrorTitle: \"操作失敗\","
+    },
+    {
+      "line": 1677,
+      "text": "modelEnabled: \"モデル有効\","
+    },
+    {
+      "line": 1678,
+      "text": "modelDisabled: \"モデル無効\","
+    },
+    {
+      "line": 1679,
+      "text": "confirmChangeEmbeddingModel: \"警告:埋め込みモデルを変更すると、既存のインデックスが検索できなくなる可能性があります。\\n変更してよろしいですか?\","
+    },
+    {
+      "line": 1680,
+      "text": "embeddingModelWarning: \"この設定を変更すると、ナレッジベースのクリアと再インポートが必要になる場合があります。\","
+    },
+    {
+      "line": 1681,
+      "text": "sourcePreview: \"引用元プレビュー\","
+    },
+    {
+      "line": 1682,
+      "text": "matchScore: \"一致度\","
+    },
+    {
+      "line": 1683,
+      "text": "copyContent: \"内容をコピー\","
+    },
+    {
+      "line": 1684,
+      "text": "copySuccess: \"コピーしました\","
+    },
+    {
+      "line": 1686,
+      "text": "// ConfigPanel 缺失の翻訳"
+    },
+    {
+      "line": 1687,
+      "text": "selectLLMModel: \"LLMモデルを選択してください\","
+    },
+    {
+      "line": 1688,
+      "text": "selectEmbeddingModel: \"Embeddingモデルを選択してください\","
+    },
+    {
+      "line": 1689,
+      "text": "defaultForUploads: \"新しいアップロードとクエリのデフォルト\","
+    },
+    {
+      "line": 1690,
+      "text": "noRerankModel: \"リランクモデルなし\","
+    },
+    {
+      "line": 1691,
+      "text": "vectorSimilarityThreshold: \"ベクトル検索しきい値\","
+    },
+    {
+      "line": 1692,
+      "text": "rerankSimilarityThreshold: \"リランクしきい値\","
+    },
+    {
+      "line": 1693,
+      "text": "filterLowResults: \"この値を下回る結果はフィルタリングされます\","
+    },
+    {
+      "line": 1694,
+      "text": "noteCreatedSuccess: \"ノートを作成しました\","
+    },
+    {
+      "line": 1695,
+      "text": "noteCreatedFailed: \"ノートの作成に失敗しました\","
+    },
+    {
+      "line": 1696,
+      "text": "fullTextSearch: \"全文検索\","
+    },
+    {
+      "line": 1697,
+      "text": "hybridVectorWeight: \"ハイブリッド検索ベクトル重み\","
+    },
+    {
+      "line": 1698,
+      "text": "hybridVectorWeightDesc: \"重み: 1.0 = ベクトルのみ, 0.0 = キーワードのみ\","
+    },
+    {
+      "line": 1699,
+      "text": "lblQueryExpansion: \"クエリ拡張 (Multi-Query)\","
+    },
+    {
+      "line": 1700,
+      "text": "lblHyDE: \"HyDE (仮想ドキュメント埋め込み)\","
+    },
+    {
+      "line": 1701,
+      "text": "lblQueryExpansionDesc: \"検索カバレッジ向上のために複数のクエリを生成\","
+    },
+    {
+      "line": 1702,
+      "text": "lblHyDEDesc: \"セマンティック検索改善のために仮想回答を生成\","
+    },
+    {
+      "line": 1704,
+      "text": "apiKeyValidationFailed: \"API Key検証に失敗しました\","
+    },
+    {
+      "line": 1705,
+      "text": "keepOriginalKey: \"空のままにすると元のAPI Keyを保持、新しい値を入力すると置換\","
+    },
+    {
+      "line": 1706,
+      "text": "leaveEmptyNoChange: \"空のままで変更なし\","
+    },
+    {
+      "line": 1708,
+      "text": "mmFormApiKeyPlaceholder: \"API Key を入力してください\","
+    },
+    {
+      "line": 1710,
+      "text": "// さらに缺失している翻訳"
+    },
+    {
+      "line": 1711,
+      "text": "reconfigureFile: \"ファイルの再設定\","
+    },
+    {
+      "line": 1712,
+      "text": "modifySettings: \"ファイルの分割とベクトル化設定を変更\","
+    },
+    {
+      "line": 1713,
+      "text": "filesCount: \"ファイル\","
+    },
+    {
+      "line": 1714,
+      "text": "allFilesIndexed: \"以下の設定ですべてのファイルがインデックス化されます。\","
+    },
+    {
+      "line": 1715,
+      "text": "noEmbeddingModels: \"埋め込みモデルが設定されていません\","
+    },
+    {
+      "line": 1716,
+      "text": "reconfigure: \"再設定\","
+    },
+    {
+      "line": 1717,
+      "text": "refresh: \"更新\","
+    },
+    {
+      "line": 1718,
+      "text": "settings: \"設定\","
+    },
+    {
+      "line": 1719,
+      "text": "needLogin: \"チャット機能を使用するにはログインが必要です\","
+    },
+    {
+      "line": 1720,
+      "text": "citationSources: \"引用元\","
+    },
+    {
+      "line": 1721,
+      "text": "chunkNumber: \"フラグメント\","
+    },
+    {
+      "line": 1722,
+      "text": "getUserListFailed: \"ユーザー一覧の取得に失敗しました\","
+    },
+    {
+      "line": 1723,
+      "text": "usernamePasswordRequired: \"ユーザー名とパスワードは必須です\","
+    },
+    {
+      "line": 1724,
+      "text": "passwordMinLength: \"パスワードは6文字以上で入力してください\","
+    },
+    {
+      "line": 1725,
+      "text": "userCreatedSuccess: \"ユーザーが作成されました\","
+    },
+    {
+      "line": 1726,
+      "text": "createUserFailed: \"ユーザー作成に失敗しました\","
+    },
+    {
+      "line": 1727,
+      "text": "userPromotedToAdmin: \"ユーザーを管理者に昇格しました\","
+    },
+    {
+      "line": 1728,
+      "text": "userDemotedFromAdmin: \"ユーザーを一般ユーザーに降格しました\","
+    },
+    {
+      "line": 1729,
+      "text": "updateUserFailed: \"ユーザー情報の更新に失敗しました\","
+    },
+    {
+      "line": 1730,
+      "text": "confirmDeleteUser: \"このユーザーを削除してもよろしいですか?\","
+    },
+    {
+      "line": 1731,
+      "text": "deleteUser: \"ユーザー削除\","
+    },
+    {
+      "line": 1732,
+      "text": "deleteUserFailed: \"ユーザーの削除に失敗しました\","
+    },
+    {
+      "line": 1733,
+      "text": "userDeletedSuccessfully: \"ユーザーを削除しました\","
+    },
+    {
+      "line": 1734,
+      "text": "makeUserAdmin: \"管理者にする\","
+    },
+    {
+      "line": 1735,
+      "text": "makeUserRegular: \"一般ユーザーにする\","
+    },
+    {
+      "line": 1736,
+      "text": "loading: \"読み込み中...\","
+    },
+    {
+      "line": 1737,
+      "text": "noUsers: \"ユーザーなし\","
+    },
+    {
+      "line": 1740,
+      "text": "aiAssistant: \"AI アシスタント\","
+    },
+    {
+      "line": 1741,
+      "text": "polishContent: \"内容を洗練\","
+    },
+    {
+      "line": 1742,
+      "text": "expandContent: \"展開\","
+    },
+    {
+      "line": 1743,
+      "text": "summarizeContent: \"要約\","
+    },
+    {
+      "line": 1744,
+      "text": "translateToEnglish: \"英語に翻訳\","
+    },
+    {
+      "line": 1745,
+      "text": "fixGrammar: \"文法修正\","
+    },
+    {
+      "line": 1746,
+      "text": "aiCommandInstructPolish: \"このテキストをよりプロフェッショナルで自然な表現に推敲してください。\","
+    },
+    {
+      "line": 1747,
+      "text": "aiCommandInstructExpand: \"このテキストに詳細を追加して内容を充実させ、詳しく書き広げてください。\","
+    },
+    {
+      "line": 1748,
+      "text": "aiCommandInstructSummarize: \"このテキストの要点を抽出し、簡潔な要約を作成してください。\","
+    },
+    {
+      "line": 1749,
+      "text": "aiCommandInstructTranslateToEn: \"このテキストを英語に翻訳してください。\","
+    },
+    {
+      "line": 1750,
+      "text": "aiCommandInstructFixGrammar: \"このテキストの文法やスペルの誤りをチェックし、修正してください。\","
+    },
+    {
+      "line": 1751,
+      "text": "aiCommandsPreset: \"よく使うコマンド\","
+    },
+    {
+      "line": 1752,
+      "text": "aiCommandsCustom: \"カスタムリクエスト\","
+    },
+    {
+      "line": 1753,
+      "text": "aiCommandsCustomPlaceholder: \"例:この文章をより正式なものに書き直してください...\","
+    },
+    {
+      "line": 1754,
+      "text": "aiCommandsReferenceContext: \"参照コンテキスト (最初の200文字):\","
+    },
+    {
+      "line": 1755,
+      "text": "aiCommandsStartGeneration: \"生成開始\","
+    },
+    {
+      "line": 1756,
+      "text": "aiCommandsResult: \"AIの提案\","
+    },
+    {
+      "line": 1757,
+      "text": "aiCommandsGenerating: \"生成中...\","
+    },
+    {
+      "line": 1758,
+      "text": "aiCommandsApplyResult: \"選択範囲を置換\","
+    },
+    {
+      "line": 1759,
+      "text": "aiCommandsGoBack: \"戻る\","
+    },
+    {
+      "line": 1760,
+      "text": "aiCommandsReset: \"リセット\","
+    },
+    {
+      "line": 1761,
+      "text": "aiCommandsModalPreset: \"プリセットコマンドを選択\","
+    },
+    {
+      "line": 1762,
+      "text": "aiCommandsModalCustom: \"またはカスタムコマンドを入力\","
+    },
+    {
+      "line": 1763,
+      "text": "aiCommandsModalCustomPlaceholder: \"AIに何をしたいか伝えてください...\","
+    },
+    {
+      "line": 1764,
+      "text": "aiCommandsModalBasedOnSelection: \"選択したテキストに基づいて:\","
+    },
+    {
+      "line": 1765,
+      "text": "aiCommandsModalResult: \"生成結果\","
+    },
+    {
+      "line": 1766,
+      "text": "aiCommandsModalApply: \"結果を適用\","
+    },
+    {
+      "line": 1768,
+      "text": "// ChangePasswordModal と SearchResultsPanel の缺失翻訳"
+    },
+    {
+      "line": 1769,
+      "text": "fillAllFields: \"すべてのフィールドを入力してください\","
+    },
+    {
+      "line": 1770,
+      "text": "passwordMismatch: \"新しいパスワードと確認パスワードが一致しません\","
+    },
+    {
+      "line": 1771,
+      "text": "newPasswordMinLength: \"新しいパスワードは6文字以上で入力してください\","
+    },
+    {
+      "line": 1772,
+      "text": "changePasswordFailed: \"パスワードの変更に失敗しました\","
+    },
+    {
+      "line": 1773,
+      "text": "changePasswordTitle: \"パスワード変更\","
+    },
+    {
+      "line": 1774,
+      "text": "changing: \"変更中...\","
+    },
+    {
+      "line": 1775,
+      "text": "searchResults: \"関連コンテンツが見つかりました\","
+    },
+    {
+      "line": 1777,
+      "text": "// VisionModelSelector の缺失翻訳"
+    },
+    {
+      "line": 1778,
+      "text": "visionModelSettings: \"ビジョンモデル設定\","
+    },
+    {
+      "line": 1779,
+      "text": "defaultVisionModel: \"デフォルトビジョンモデル\","
+    },
+    {
+      "line": 1780,
+      "text": "loadVisionModelFailed: \"ビジョンモデルの読み込みに失敗しました\","
+    },
+    {
+      "line": 1781,
+      "text": "loadFailed: \"読み込みに失敗しました、ネットワーク接続を確認してください\","
+    },
+    {
+      "line": 1782,
+      "text": "saveVisionModelFailed: \"ビジョンモデルの保存に失敗しました\","
+    },
+    {
+      "line": 1783,
+      "text": "noVisionModels: \"利用可能なビジョンモデルがありません\","
+    },
+    {
+      "line": 1784,
+      "text": "selectVisionModel: \"ビジョンモデルを選択してください\","
+    },
+    {
+      "line": 1785,
+      "text": "visionModelHelp: \"画像ファイルを処理するためのビジョンモデル。利用可能なモデルがない場合は、モデル管理で追加し、「ビジョン対応」オプションをチェックしてください。\","
+    },
+    {
+      "line": 1786,
+      "text": "mmErrorNameRequired: \"モデル名は必須要素です\","
+    },
+    {
+      "line": 1787,
+      "text": "mmErrorModelIdRequired: \"モデルIDは必須です。\","
+    },
+    {
+      "line": 1788,
+      "text": "mmErrorBaseUrlRequired: \"選択されたプロバイダーにはBase URLが必要です。\","
+    },
+    {
+      "line": 1791,
+      "text": "typeLLM: \"推論 (LLM)\","
+    },
+    {
+      "line": 1792,
+      "text": "typeEmbedding: \"ベクトル化 (Embedding)\","
+    },
+    {
+      "line": 1793,
+      "text": "typeRerank: \"リランク (Rerank)\","
+    },
+    {
+      "line": 1794,
+      "text": "typeVision: \"画像認識 (Vision)\","
+    },
+    {
+      "line": 1796,
+      "text": "welcome: \"こんにちは!設定でモデルを選択し、ドキュメントをアップロードして質問を開始してください。\","
+    },
+    {
+      "line": 1797,
+      "text": "placeholderWithFiles: \"ナレッジベースについて質問...\","
+    },
+    {
+      "line": 1798,
+      "text": "placeholderEmpty: \"開始するにはファイルをアップロード...\","
+    },
+    {
+      "line": 1799,
+      "text": "analyzing: \"検索して生成中...\","
+    },
+    {
+      "line": 1800,
+      "text": "errorGeneric: \"エラーが発生しました。\","
+    },
+    {
+      "line": 1801,
+      "text": "errorLabel: \"エラー\","
+    },
+    {
+      "line": 1802,
+      "text": "errorNoModel: \"モデルが選択されていないか、設定が無効です。\","
+    },
+    {
+      "line": 1803,
+      "text": "aiDisclaimer: \"AIは間違いを犯す可能性があります。\","
+    },
+    {
+      "line": 1804,
+      "text": "confirmClear: \"すべてのファイルを削除しますか?\","
+    },
+    {
+      "line": 1805,
+      "text": "removeFile: \"ファイルを削除\","
+    },
+    {
+      "line": 1806,
+      "text": "apiError: \"設定が不足しているか、APIキーが有効ではありません。\","
+    },
+    {
+      "line": 1807,
+      "text": "geminiError: \"APIリクエストに失敗しました。\","
+    },
+    {
+      "line": 1808,
+      "text": "processedButNoText: \"応答を生成できませんでした。\","
+    },
+    {
+      "line": 1809,
+      "text": "unitByte: \"バイト\","
+    },
+    {
+      "line": 1810,
+      "text": "readingFailed: \"読み込み失敗\","
+    },
+    {
+      "line": 1812,
+      "text": "copy: \"コピー\","
+    },
+    {
+      "line": 1813,
+      "text": "copied: \"コピーしました\","
+    },
+    {
+      "line": 1816,
+      "text": "logout: \"ログアウト\","
+    },
+    {
+      "line": 1817,
+      "text": "changePassword: \"パスワード変更\","
+    },
+    {
+      "line": 1818,
+      "text": "userManagement: \"ユーザー管理\","
+    },
+    {
+      "line": 1819,
+      "text": "userList: \"ユーザー一覧\","
+    },
+    {
+      "line": 1820,
+      "text": "addUser: \"ユーザー追加\","
+    },
+    {
+      "line": 1821,
+      "text": "username: \"ユーザー名\","
+    },
+    {
+      "line": 1822,
+      "text": "password: \"パスワード\","
+    },
+    {
+      "line": 1823,
+      "text": "confirmPassword: \"パスワード確認\","
+    },
+    {
+      "line": 1824,
+      "text": "currentPassword: \"現在のパスワード\","
+    },
+    {
+      "line": 1825,
+      "text": "newPassword: \"新しいパスワード\","
+    },
+    {
+      "line": 1826,
+      "text": "createUser: \"ユーザー作成\","
+    },
+    {
+      "line": 1827,
+      "text": "admin: \"管理者\","
+    },
+    {
+      "line": 1828,
+      "text": "user: \"ユーザー\","
+    },
+    {
+      "line": 1829,
+      "text": "adminUser: \"管理者として設定\","
+    },
+    {
+      "line": 1830,
+      "text": "confirmChange: \"変更を確定\","
+    },
+    {
+      "line": 1831,
+      "text": "changeUserPassword: \"ユーザーのパスワードを変更\","
+    },
+    {
+      "line": 1832,
+      "text": "enterNewPassword: \"新しいパスワードを入力してください\","
+    },
+    {
+      "line": 1833,
+      "text": "createdAt: \"作成日時\","
+    },
+    {
+      "line": 1834,
+      "text": "newChat: \"新しい会話\","
+    },
+    {
+      "line": 1837,
+      "text": "kbManagement: \"ナレッジベース管理\","
+    },
+    {
+      "line": 1838,
+      "text": "kbManagementDesc: \"ドキュメントとナレッジグループの管理\","
+    },
+    {
+      "line": 1839,
+      "text": "searchPlaceholder: \"ファイル名を検索...\","
+    },
+    {
+      "line": 1840,
+      "text": "allGroups: \"すべてのグループ\","
+    },
+    {
+      "line": 1841,
+      "text": "allStatus: \"すべてのステータス\","
+    },
+    {
+      "line": 1842,
+      "text": "statusReadyFragment: \"完了\","
+    },
+    {
+      "line": 1843,
+      "text": "statusFailedFragment: \"失敗\","
+    },
+    {
+      "line": 1844,
+      "text": "statusIndexingFragment: \"インデックス中\","
+    },
+    {
+      "line": 1845,
+      "text": "uploadFile: \"ファイルをアップロード\","
+    },
+    {
+      "line": 1846,
+      "text": "fileName: \"ファイル名\","
+    },
+    {
+      "line": 1847,
+      "text": "size: \"サイズ\","
+    },
+    {
+      "line": 1848,
+      "text": "status: \"ステータス\","
+    },
+    {
+      "line": 1849,
+      "text": "groups: \"グループ\","
+    },
+    {
+      "line": 1850,
+      "text": "actions: \"アクション\","
+    },
+    {
+      "line": 1851,
+      "text": "groupsActions: \"グループ / アクション\","
+    },
+    {
+      "line": 1852,
+      "text": "noFilesFound: \"ファイルが見つかりません\","
+    },
+    {
+      "line": 1853,
+      "text": "showingRange: \"$3 件中 $1 - $2 を表示\","
+    },
+    {
+      "line": 1854,
+      "text": "confirmDeleteFile: \"このファイルを削除してもよろしいですか?\","
+    },
+    {
+      "line": 1855,
+      "text": "fileDeleted: \"ファイルを削除しました\","
+    },
+    {
+      "line": 1856,
+      "text": "deleteFailed: \"削除に失敗しました\","
+    },
+    {
+      "line": 1857,
+      "text": "fileAddedToGroup: \"ファイルがグループに追加されました\","
+    },
+    {
+      "line": 1858,
+      "text": "failedToAddToGroup: \"グループへの追加に失敗しました\","
+    },
+    {
+      "line": 1859,
+      "text": "fileRemovedFromGroup: \"ファイルがグループから削除されました\","
+    },
+    {
+      "line": 1860,
+      "text": "failedToRemoveFromGroup: \"グループからの削除に失敗しました\","
+    },
+    {
+      "line": 1861,
+      "text": "confirmClearKB: \"警告:これによりすべてのファイルとインデックスが完全に削除されます。\\n\\n本当にナレッジベースをクリアしますか?\","
+    },
+    {
+      "line": 1862,
+      "text": "kbCleared: \"ナレッジベースをクリアしました\","
+    },
+    {
+      "line": 1863,
+      "text": "clearFailed: \"クリアに失敗しました\","
+    },
+    {
+      "line": 1864,
+      "text": "loginRequired: \"先にログインしてください\","
+    },
+    {
+      "line": 1865,
+      "text": "uploadErrors: \"以下のファイルはアップロードできませんでした\","
+    },
+    {
+      "line": 1866,
+      "text": "uploadWarning: \"$1 つのファイルがアップロード準備完了、$2 つがフィルタリングされました\","
+    },
+    {
+      "line": 1867,
+      "text": "uploadFailed: \"アップロードに失敗しました\","
+    },
+    {
+      "line": 1868,
+      "text": "preview: \"プレビュー\","
+    },
+    {
+      "line": 1869,
+      "text": "addGroup: \"グループ追加\","
+    },
+    {
+      "line": 1870,
+      "text": "delete: \"削除\","
+    },
+    {
+      "line": 1871,
+      "text": "retry: \"再試行\","
+    },
+    {
+      "line": 1872,
+      "text": "retrying: \"再試行中...\","
+    },
+    {
+      "line": 1873,
+      "text": "retrySuccess: \"再試行成功\","
+    },
+    {
+      "line": 1874,
+      "text": "retryFailed: \"再試行失敗\","
+    },
+    {
+      "line": 1875,
+      "text": "chunkInfo: \"チャンク情報\","
+    },
+    {
+      "line": 1876,
+      "text": "totalChunks: \"総チャンク数\","
+    },
+    {
+      "line": 1877,
+      "text": "chunkIndex: \"チャンク\","
+    },
+    {
+      "line": 1878,
+      "text": "contentLength: \"文字\","
+    },
+    {
+      "line": 1879,
+      "text": "position: \"位置\","
+    },
+    {
+      "line": 1882,
+      "text": "reconfigureTitle: \"ファイルの再設定\","
+    },
+    {
+      "line": 1883,
+      "text": "reconfigureDesc: \"ファイル処理設定を変更\","
+    },
+    {
+      "line": 1884,
+      "text": "indexingConfigTitle: \"ドキュメントインデックス設定\","
+    },
+    {
+      "line": 1885,
+      "text": "indexingConfigDesc: \"ドキュメント処理オプションとモードを設定\","
+    },
+    {
+      "line": 1886,
+      "text": "pendingFiles: \"待機中のファイル\","
+    },
+    {
+      "line": 1887,
+      "text": "processingMode: \"処理モード\","
+    },
+    {
+      "line": 1888,
+      "text": "analyzingFile: \"分析中...\","
+    },
+    {
+      "line": 1889,
+      "text": "recommendationReason: \"理由\","
+    },
+    {
+      "line": 1890,
+      "text": "fastMode: \"高速モード\","
+    },
+    {
+      "line": 1891,
+      "text": "fastModeDesc: \"単純なテキスト抽出、高速、追加コストなし、純粋なテキストに適しています\","
+    },
+    {
+      "line": 1892,
+      "text": "preciseMode: \"精密モード\","
+    },
+    {
+      "line": 1893,
+      "text": "preciseModeDesc: \"精密なレイアウト分析、表/画像を保持、APIコストがかかります\","
+    },
+    {
+      "line": 1894,
+      "text": "fastModeFeatures: \"高速モードの特徴:\","
+    },
+    {
+      "line": 1895,
+      "text": "fastFeature1: \"単純なテキスト抽出\","
+    },
+    {
+      "line": 1896,
+      "text": "fastFeature2: \"高速な処理速度\","
+    },
+    {
+      "line": 1897,
+      "text": "fastFeature3: \"追加コストなし\","
+    },
+    {
+      "line": 1898,
+      "text": "fastFeature4: \"テキストのみ処理\","
+    },
+    {
+      "line": 1899,
+      "text": "fastFeature5: \"プレーンテキストに適しています\","
+    },
+    {
+      "line": 1900,
+      "text": "preciseModeFeatures: \"精密モードの特徴:\","
+    },
+    {
+      "line": 1901,
+      "text": "preciseFeature1: \"精密な構造認識\","
+    },
+    {
+      "line": 1902,
+      "text": "preciseFeature2: \"画像/表/チャートを認識\","
+    },
+    {
+      "line": 1903,
+      "text": "preciseFeature3: \"混合コンテンツを保持\","
+    },
+    {
+      "line": 1904,
+      "text": "preciseFeature4: \"レイアウト情報を保持\","
+    },
+    {
+      "line": 1905,
+      "text": "preciseFeature5: \"APIコストが必要\","
+    },
+    {
+      "line": 1906,
+      "text": "preciseFeature6: \"処理時間が長くなります\","
+    },
+    {
+      "line": 1907,
+      "text": "embeddingModel: \"埋め込みモデル\","
+    },
+    {
+      "line": 1908,
+      "text": "pleaseSelect: \"選択してください...\","
+    },
+    {
+      "line": 1909,
+      "text": "pleaseSelectKnowledgeGroupFirst: \"保存する前に知識グループを選択してください\","
+    },
+    {
+      "line": 1910,
+      "text": "selectUnassignGroupWarning: \"ナレッジグループの割り当てを解除する場合は、この操作を確認してください\","
+    },
+    {
+      "line": 1911,
+      "text": "chunkConfig: \"チャンク設定\","
+    },
+    {
+      "line": 1912,
+      "text": "chunkSize: \"チャンクサイズ (トークン)\","
+    },
+    {
+      "line": 1913,
+      "text": "min: \"最小\","
+    },
+    {
+      "line": 1914,
+      "text": "max: \"最大\","
+    },
+    {
+      "line": 1915,
+      "text": "chunkOverlap: \"オーバーラップ (トークン)\","
+    },
+    {
+      "line": 1916,
+      "text": "modelLimitsInfo: \"モデル制限情報\","
+    },
+    {
+      "line": 1917,
+      "text": "model: \"モデル\","
+    },
+    {
+      "line": 1918,
+      "text": "maxChunkSize: \"最大チャンク\","
+    },
+    {
+      "line": 1919,
+      "text": "maxOverlapSize: \"最大オーバーラップ\","
+    },
+    {
+      "line": 1920,
+      "text": "maxBatchSize: \"最大バッチ\","
+    },
+    {
+      "line": 1921,
+      "text": "envLimitWeaker: \"環境制限の方が厳しいです\","
+    },
+    {
+      "line": 1922,
+      "text": "optimizationTips: \"最適化のヒント\","
+    },
+    {
+      "line": 1923,
+      "text": "tipChunkTooLarge: \"チャンクサイズが大きいと検索精度に影響する可能性があります\","
+    },
+    {
+      "line": 1924,
+      "text": "tipOverlapSmall: \"オーバーラップは少なくとも $1 トークンを推奨します\","
+    },
+    {
+      "line": 1925,
+      "text": "tipMaxValues: \"最大値を使用すると処理が遅くなる可能性があります\","
+    },
+    {
+      "line": 1926,
+      "text": "tipPreciseCost: \"精密モードはAPIコストが発生します。予算を確認してください\","
+    },
+    {
+      "line": 1927,
+      "text": "selectEmbeddingFirst: \"先に埋め込みモデルを選択してください\","
+    },
+    {
+      "line": 1928,
+      "text": "confirmPreciseCost: \"精密モードはAPIコストが発生します。続けますか?\","
+    },
+    {
+      "line": 1929,
+      "text": "startProcessing: \"処理開始\","
+    },
+    {
+      "line": 1932,
+      "text": "notebooks: \"ナレッジグループ\","
+    },
+    {
+      "line": 1933,
+      "text": "notebooksDesc: \"研究プロジェクトやナレッジコレクションを管理\","
+    },
+    {
+      "line": 1934,
+      "text": "createNotebook: \"新しいナレッジグループ\","
+    },
+    {
+      "line": 1935,
+      "text": "chatWithNotebook: \"このグループとチャット\","
+    },
+    {
+      "line": 1936,
+      "text": "editNotebook: \"グループを編集\","
+    },
+    {
+      "line": 1937,
+      "text": "deleteNotebook: \"グループを削除 (ファイルを含む)\","
+    },
+    {
+      "line": 1938,
+      "text": "noDescription: \"説明なし\","
+    },
+    {
+      "line": 1939,
+      "text": "hasIntro: \"紹介あり\","
+    },
+    {
+      "line": 1940,
+      "text": "noIntro: \"紹介なし\","
+    },
+    {
+      "line": 1941,
+      "text": "noNotebooks: \"ナレッジグループはまだありません。右上の作成ボタンをクリックしてください\","
+    },
+    {
+      "line": 1942,
+      "text": "createFailed: \"作成に失敗しました\","
+    },
+    {
+      "line": 1943,
+      "text": "confirmDeleteNotebook: \"知識グループ \\\"$1\\\" を削除してもよろしいですか?\\n\\n注意:これにより、この知識グループ内のすべてのファイルとそのインデックスデータも完全に削除されます!\","
+    },
+    {
+      "line": 1946,
+      "text": "errorFileTooLarge: \"ファイルサイズが大きすぎます (20MB以下)\","
+    },
+    {
+      "line": 1947,
+      "text": "noFilesYet: \"ファイルがありません\","
+    },
+    {
+      "line": 1950,
+      "text": "createNotebookTitle: \"新しいナレッジグループ\","
+    },
+    {
+      "line": 1951,
+      "text": "editNotebookTitle: \"ナレッジグループを編集\","
+    },
+    {
+      "line": 1952,
+      "text": "createFailedRetry: \"作成に失敗しました。再試行してください\","
+    },
+    {
+      "line": 1953,
+      "text": "updateFailedRetry: \"更新に失敗しました。再試行してください\","
+    },
+    {
+      "line": 1954,
+      "text": "name: \"名前\","
+    },
+    {
+      "line": 1955,
+      "text": "nameHelp: \"明確な名前を付けると見つけやすくなります。\","
+    },
+    {
+      "line": 1956,
+      "text": "namePlaceholder: \"例: 量子物理学研究...\","
+    },
+    {
+      "line": 1957,
+      "text": "shortDescription: \"短い説明\","
+    },
+    {
+      "line": 1958,
+      "text": "descPlaceholder: \"このグループの目的を一文で説明\","
+    },
+    {
+      "line": 1959,
+      "text": "detailedIntro: \"詳細な紹介\","
+    },
+    {
+      "line": 1960,
+      "text": "introPlaceholder: \"ここの段落は、Q&Aのコンテキストに含まれる可能性があります。このグループの主要なトピック、背景知識、または目標をできるだけ詳しく説明してください。\","
+    },
+    {
+      "line": 1961,
+      "text": "introHelp: \"この紹介は、会話の追加コンテキストとして使用されます。\","
+    },
+    {
+      "line": 1962,
+      "text": "creating: \"作成中...\","
+    },
+    {
+      "line": 1963,
+      "text": "createNow: \"今すぐ作成\","
+    },
+    {
+      "line": 1964,
+      "text": "saving: \"保存中...\","
+    },
+    {
+      "line": 1965,
+      "text": "save: \"保存\","
+    },
+    {
+      "line": 1968,
+      "text": "chatTitle: \"ナレッジベースチャット\","
+    },
+    {
+      "line": 1969,
+      "text": "chatDesc: \"ナレッジベースとのスマートな会話\","
+    },
+    {
+      "line": 1970,
+      "text": "viewHistory: \"チャット履歴を表示\","
+    },
+    {
+      "line": 1971,
+      "text": "saveSettingsFailed: \"設定の保存に失敗しました\","
+    },
+    {
+      "line": 1972,
+      "text": "loginToUpload: \"アップロードするにはログインしてください\","
+    },
+    {
+      "line": 1973,
+      "text": "fileSizeLimitExceeded: \"$1 ($2 - $3MB の制限を超えています)\","
+    },
+    {
+      "line": 1974,
+      "text": "unsupportedFileType: \"$1 - サポートされていないファイルタイプ ($2)\","
+    },
+    {
+      "line": 1975,
+      "text": "readFailed: \"$1 - 読み込みに失敗しました\","
+    },
+    {
+      "line": 1976,
+      "text": "loadHistoryFailed: \"履歴の読み込みに失敗しました\","
+    },
+    {
+      "line": 1977,
+      "text": "loadingUserData: \"ユーザーデータを読み込み中...\","
+    },
+    {
+      "line": 1978,
+      "text": "errorMessage: \"エラー: $1\","
+    },
+    {
+      "line": 1979,
+      "text": "welcomeMessage: \"こんにちは!私はあなたのAIナレッジベースアシスタントです。チャットを開始するにはナレッジグループを選択してください。\","
+    },
+    {
+      "line": 1980,
+      "text": "selectKnowledgeGroup: \"ナレッジグループを選択\","
+    },
+    {
+      "line": 1981,
+      "text": "allKnowledgeGroups: \"すべてのナレッジグループ\","
+    },
+    {
+      "line": 1982,
+      "text": "unknownGroup: \"不明なグループ\","
+    },
+    {
+      "line": 1983,
+      "text": "selectedGroupsCount: \"$1 グループ選択済み\","
+    },
+    {
+      "line": 1986,
+      "text": "generalSettings: \"一般設定\","
+    },
+    {
+      "line": 1987,
+      "text": "modelManagement: \"モデル管理\","
+    },
+    {
+      "line": 1988,
+      "text": "languageSettings: \"言語設定\","
+    },
+    {
+      "line": 1989,
+      "text": "passwordChangeSuccess: \"パスワードを変更しました\","
+    },
+    {
+      "line": 1990,
+      "text": "passwordChangeFailed: \"パスワードの変更に失敗しました\","
+    },
+    {
+      "line": 1991,
+      "text": "create: \"作成\","
+    },
+    {
+      "line": 1995,
+      "text": "navChat: \"チャット\","
+    },
+    {
+      "line": 1996,
+      "text": "navCoach: \"コーチ\","
+    },
+    {
+      "line": 1997,
+      "text": "navKnowledge: \"ナレッジベース\","
+    },
+    {
+      "line": 1998,
+      "text": "navKnowledgeGroups: \"ナレッジグループ\","
+    },
+    {
+      "line": 1999,
+      "text": "navNotebook: \"ノートブック\","
+    },
+    {
+      "line": 2000,
+      "text": "navAgent: \"エージェント\","
+    },
+    {
+      "line": 2001,
+      "text": "navPlugin: \"プラグイン\","
+    },
+    {
+      "line": 2002,
+      "text": "navCrawler: \"リソース取得\","
+    },
+    {
+      "line": 2003,
+      "text": "expandMenu: \"メニューを展開\","
+    },
+    {
+      "line": 2004,
+      "text": "switchLanguage: \"言語を切り替える\","
+    },
+    {
+      "line": 2007,
+      "text": "selectKnowledgeGroups: \"ナレッジグループを選択\","
+    },
+    {
+      "line": 2008,
+      "text": "searchGroupsPlaceholder: \"グループを検索...\","
+    },
+    {
+      "line": 2009,
+      "text": "done: \"完了\","
+    },
+    {
+      "line": 2010,
+      "text": "all: \"すべて\","
+    },
+    {
+      "line": 2011,
+      "text": "noGroupsFound: \"関連するグループが見つかりません\","
+    },
+    {
+      "line": 2012,
+      "text": "noGroups: \"グループなし\","
+    },
+    {
+      "line": 2015,
+      "text": "autoRefresh: \"自動更新\","
+    },
+    {
+      "line": 2016,
+      "text": "refreshInterval: \"更新間隔\","
+    },
+    {
+      "line": 2019,
+      "text": "errorRenderFlowchart: \"フローチャートを生成できません\","
+    },
+    {
+      "line": 2020,
+      "text": "errorLoadData: \"データの読み込みに失敗しました\","
+    },
+    {
+      "line": 2021,
+      "text": "confirmUnsupportedFile: \"拡張子 .$1 はサポートされていない可能性があります。続行しますか?\","
+    },
+    {
+      "line": 2022,
+      "text": "errorReadFile: \"ファイルの読み込みに失敗しました: $1\","
+    },
+    {
+      "line": 2023,
+      "text": "successUploadFile: \"ファイルのアップロードと関連付けに成功しました\","
+    },
+    {
+      "line": 2024,
+      "text": "errorUploadFile: \"アップロードに失敗しました: $1\","
+    },
+    {
+      "line": 2025,
+      "text": "errorProcessFile: \"ファイルの処理に失敗しました\","
+    },
+    {
+      "line": 2026,
+      "text": "errorTitleContentRequired: \"タイトルと内容は必須です\","
+    },
+    {
+      "line": 2027,
+      "text": "successNoteUpdated: \"メモを更新しました\","
+    },
+    {
+      "line": 2028,
+      "text": "successNoteCreated: \"メモを作成しました\","
+    },
+    {
+      "line": 2029,
+      "text": "errorSaveFailed: \"保存に失敗しました: $1\","
+    },
+    {
+      "line": 2030,
+      "text": "confirmDeleteNote: \"このメモを削除してもよろしいですか?\","
+    },
+    {
+      "line": 2031,
+      "text": "successNoteDeleted: \"メモを削除しました\","
+    },
+    {
+      "line": 2032,
+      "text": "confirmRemoveFileFromGroup: \"ファイル「$1」をこのグループから削除しますか?(ナレッジベースには残ります)\","
+    },
+    {
+      "line": 2033,
+      "text": "editNote: \"メモを編集\","
+    },
+    {
+      "line": 2034,
+      "text": "newNote: \"新規メモ\","
+    },
+    {
+      "line": 2035,
+      "text": "togglePreviewOpen: \"プレビューを表示\","
+    },
+    {
+      "line": 2036,
+      "text": "togglePreviewClose: \"プレビューを閉じる\","
+    },
+    {
+      "line": 2037,
+      "text": "noteTitlePlaceholder: \"メモのタイトル\","
+    },
+    {
+      "line": 2038,
+      "text": "noteContentPlaceholder: \"書き始める (Markdown 対応)...\","
+    },
+    {
+      "line": 2039,
+      "text": "markdownPreviewArea: \"Markdown プレビューエリア\","
+    },
+    {
+      "line": 2040,
+      "text": "back: \"戻る\","
+    },
+    {
+      "line": 2041,
+      "text": "chatWithGroup: \"このグループとチャット\","
+    },
+    {
+      "line": 2042,
+      "text": "chatWithFile: \"このファイルとチャット\","
+    },
+    {
+      "line": 2043,
+      "text": "filesCountLabel: \"ファイル ($1)\","
+    },
+    {
+      "line": 2044,
+      "text": "notesCountLabel: \"メモ ($1)\","
+    },
+    {
+      "line": 2045,
+      "text": "indexIntoKB: \"インデックスに登録\","
+    },
+    {
+      "line": 2046,
+      "text": "noFilesOrNotes: \"$1がありません\","
+    },
+    {
+      "line": 2047,
+      "text": "importFolder: \"フォルダをインポート\","
+    },
+    {
+      "line": 2050,
+      "text": "createPDFNote: \"PDFノートを作成\","
+    },
+    {
+      "line": 2051,
+      "text": "screenshotPreview: \"スクリーンショットプレビュー\","
+    },
+    {
+      "line": 2052,
+      "text": "associateKnowledgeGroup: \"ナレッジグループに関連付ける\","
+    },
+    {
+      "line": 2053,
+      "text": "globalNoSpecificGroup: \"全体 (特定のグループなし)\","
+    },
+    {
+      "line": 2054,
+      "text": "title: \"タイトル\","
+    },
+    {
+      "line": 2055,
+      "text": "enterNoteTitle: \"ノートのタイトルを入力\","
+    },
+    {
+      "line": 2056,
+      "text": "contentOCR: \"内容 (OCR抽出されたテキスト)\","
+    },
+    {
+      "line": 2057,
+      "text": "extractingText: \"テキストを抽出中...\","
+    },
+    {
+      "line": 2058,
+      "text": "analyzingImage: \"画像を分析してテキストを抽出中...\","
+    },
+    {
+      "line": 2059,
+      "text": "noTextExtracted: \"テキストが抽出されませんでした\","
+    },
+    {
+      "line": 2060,
+      "text": "saveNote: \"ノートを保存\","
+    },
+    {
+      "line": 2063,
+      "text": "page: \"ページ\","
+    },
+    {
+      "line": 2064,
+      "text": "placeholderText: \"OCR抽出されたテキストがここに表示されます。編集できます...\","
+    },
+    {
+      "line": 2067,
+      "text": "createNewNotebook: \"新しいナレッジグループ\","
+    },
+    {
+      "line": 2068,
+      "text": "nameField: \"名前\","
+    },
+    {
+      "line": 2070,
+      "text": "exampleResearch: \"例: 量子物理学研究...\","
+    },
+    {
+      "line": 2071,
+      "text": "shortDescriptionField: \"簡単な説明\","
+    },
+    {
+      "line": 2072,
+      "text": "describePurpose: \"このグループの目的を一文で説明してください\","
+    },
+    {
+      "line": 2073,
+      "text": "detailedIntroField: \"詳細な紹介\","
+    },
+    {
+      "line": 2074,
+      "text": "provideBackgroundInfo: \"詳細な背景、目標、またはコンテキスト情報を提供してください...\","
+    },
+    {
+      "line": 2075,
+      "text": "creationFailed: \"作成に失敗しました。もう一度お試しください\","
+    },
+    {
+      "line": 2078,
+      "text": "preparingPDFConversion: \"PDF変換を準備中...\","
+    },
+    {
+      "line": 2079,
+      "text": "pleaseWait: \"しばらくお待ちください。これには数分かかる場合があります\","
+    },
+    {
+      "line": 2080,
+      "text": "convertingPDF: \"PDFを変換中...\","
+    },
+    {
+      "line": 2081,
+      "text": "pdfConversionFailed: \"PDF変換に失敗しました\","
+    },
+    {
+      "line": 2082,
+      "text": "pdfConversionError: \"このファイルをPDF形式に変換できません。ファイルが破損していないか、サポートされていない形式でないか確認してください\","
+    },
+    {
+      "line": 2083,
+      "text": "pdfLoadFailed: \"PDF読み込みに失敗しました\","
+    },
+    {
+      "line": 2084,
+      "text": "pdfLoadError: \"ブラウザでPDFを表示できません。ダウンロードするか、新しいウィンドウで開いてみてください\","
+    },
+    {
+      "line": 2085,
+      "text": "downloadingPDF: \"PDFをダウンロード中...\","
+    },
+    {
+      "line": 2086,
+      "text": "loadingPDF: \"PDFを読み込み中...\","
+    },
+    {
+      "line": 2087,
+      "text": "zoomOut: \"ズームアウト\","
+    },
+    {
+      "line": 2088,
+      "text": "zoomIn: \"ズームイン\","
+    },
+    {
+      "line": 2089,
+      "text": "resetZoom: \"ズームをリセット\","
+    },
+    {
+      "line": 2090,
+      "text": "selectPageNumber: \"ページ番号を選択:\","
+    },
+    {
+      "line": 2091,
+      "text": "enterPageNumber: \"選択したいページ番号を入力してください\","
+    },
+    {
+      "line": 2092,
+      "text": "exitSelectionMode: \"選択モードを終了\","
+    },
+    {
+      "line": 2093,
+      "text": "clickToSelectAndNote: \"クリックして領域を選択し、メモを取る\","
+    },
+    {
+      "line": 2094,
+      "text": "regeneratePDF: \"PDFを再生成\","
+    },
+    {
+      "line": 2095,
+      "text": "downloadPDF: \"PDFをダウンロード\","
+    },
+    {
+      "line": 2096,
+      "text": "openInNewWindow: \"新しいウィンドウで開く\","
+    },
+    {
+      "line": 2097,
+      "text": "exitFullscreen: \"全画面表示を終了\","
+    },
+    {
+      "line": 2098,
+      "text": "fullscreenDisplay: \"全画面表示\","
+    },
+    {
+      "line": 2099,
+      "text": "pdfPreview: \"PDFプレビュー\","
+    },
+    {
+      "line": 2100,
+      "text": "converting: \"変換中...\","
+    },
+    {
+      "line": 2101,
+      "text": "generatePDFPreview: \"PDFプレビューを生成\","
+    },
+    {
+      "line": 2102,
+      "text": "previewNotSupported: \"この形式はプレビューをサポートしていません\","
+    },
+    {
+      "line": 2105,
+      "text": "confirmRegeneratePDF: \"PDFを再生成してもよろしいですか?これにより現在のプレビューファイルが上書きされます。\","
+    },
+    {
+      "line": 2108,
+      "text": "pdfPreviewReady: \"PDFプレビュー\","
+    },
+    {
+      "line": 2109,
+      "text": "convertingInProgress: \"変換中...\","
+    },
+    {
+      "line": 2110,
+      "text": "conversionFailed: \"変換失敗\","
+    },
+    {
+      "line": 2111,
+      "text": "generatePDFPreviewButton: \"PDFプレビューを生成\","
+    },
+    {
+      "line": 2114,
+      "text": "checkPDFStatusFailed: \"PDFステータスの確認に失敗しました\","
+    },
+    {
+      "line": 2115,
+      "text": "requestRegenerationFailed: \"再生成要求に失敗しました\","
+    },
+    {
+      "line": 2116,
+      "text": "downloadPDFFailed: \"PDFのダウンロードに失敗しました\","
+    },
+    {
+      "line": 2117,
+      "text": "openPDFInNewTabFailed: \"新しいウィンドウでのPDFオープンに失敗しました\","
+    },
+    {
+      "line": 2120,
+      "text": "invalidFile: \"無効なファイル\","
+    },
+    {
+      "line": 2121,
+      "text": "incompleteFileInfo: \"ファイル情報が不完全です。高速モードを使用します\","
+    },
+    {
+      "line": 2122,
+      "text": "unsupportedFileFormat: \"サポートされていない形式: .$1\","
+    },
+    {
+      "line": 2123,
+      "text": "willUseFastMode: \"高速モード(テキスト抽出のみ)を使用します\","
+    },
+    {
+      "line": 2124,
+      "text": "formatNoPrecise: \"形式 .$1 は精密モードをサポートしていません\","
+    },
+    {
+      "line": 2125,
+      "text": "smallFileFastOk: \"ファイルサイズが小さいため、高速モードで十分です\","
+    },
+    {
+      "line": 2126,
+      "text": "mixedContentPreciseRecommended: \"図表などが含まれるため、精密モードを推奨します\","
+    },
+    {
+      "line": 2127,
+      "text": "willIncurApiCost: \"APIコストが発生します\","
+    },
+    {
+      "line": 2128,
+      "text": "largeFilePreciseRecommended: \"大きなファイルです。構造保持のため精密モードを推奨します\","
+    },
+    {
+      "line": 2129,
+      "text": "longProcessingTime: \"処理に時間がかかる可能性があります\","
+    },
+    {
+      "line": 2130,
+      "text": "highApiCost: \"高いAPIコストが発生します\","
+    },
+    {
+      "line": 2131,
+      "text": "considerFileSplitting: \"ファイルの分割を検討してください\","
+    },
+    {
+      "line": 2134,
+      "text": "dragDropUploadTitle: \"アップロードするファイルをドラッグ&ドロップ\","
+    },
+    {
+      "line": 2135,
+      "text": "dragDropUploadDesc: \"または下のボタンをクリックしてファイルを選択\","
+    },
+    {
+      "line": 2136,
+      "text": "supportedFormats: \"対応フォーマット\","
+    },
+    {
+      "line": 2137,
+      "text": "browseFiles: \"ファイルを参照\","
+    },
+    {
+      "line": 2140,
+      "text": "recommendationMsg: \"$1モードを推奨します: $2\","
+    },
+    {
+      "line": 2141,
+      "text": "autoAdjustChunk: \"チャンクサイズを上限の $1 に調整しました\","
+    },
+    {
+      "line": 2142,
+      "text": "autoAdjustOverlap: \"重なりサイズを上限の $1 に調整しました\","
+    },
+    {
+      "line": 2143,
+      "text": "autoAdjustOverlapMin: \"重なりサイズを最小値の $1 に調整しました\","
+    },
+    {
+      "line": 2144,
+      "text": "loadLimitsFailed: \"モデル制限の読み込みに失敗しました。デフォルト設定を使用します\","
+    },
+    {
+      "line": 2145,
+      "text": "maxValueMsg: \"最大値は $1 です\","
+    },
+    {
+      "line": 2146,
+      "text": "overlapRatioLimit: \"切片サイズの50% ($1) を超えることはできません\","
+    },
+    {
+      "line": 2147,
+      "text": "onlyAdminCanModify: \"システム設定は管理者のみ変更可能です\","
+    },
+    {
+      "line": 2148,
+      "text": "dragToSelect: \"マウスをドラッグして範囲を選択 • ESCでキャンセル\","
+    },
+    {
+      "line": 2151,
+      "text": "fillTargetName: \"対象のナレッジグループ名を入力してください\","
+    },
+    {
+      "line": 2152,
+      "text": "submitFailed: \"送信に失敗しました: $1\","
+    },
+    {
+      "line": 2153,
+      "text": "importFolderTitle: \"ローカルフォルダをインポート\","
+    },
+    {
+      "line": 2154,
+      "text": "importFolderTip: \"ヒント: ローカルフォルダを選択してください。フォルダ内のすべてのサポートされているドキュメントが読み込まれ、アップロードされます。\","
+    },
+    {
+      "line": 2155,
+      "text": "lblTargetGroup: \"対象のナレッジグループ名\","
+    },
+    {
+      "line": 2156,
+      "text": "placeholderNewGroup: \"新規グループ名\","
+    },
+    {
+      "line": 2157,
+      "text": "importToCurrentGroup: \"現在のグループにインポートされます\","
+    },
+    {
+      "line": 2158,
+      "text": "nextStep: \"次へ\","
+    },
+    {
+      "line": 2159,
+      "text": "lblImportSource: \"インポート元\","
+    },
+    {
+      "line": 2160,
+      "text": "serverPath: \"サーバーのパス\","
+    },
+    {
+      "line": 2161,
+      "text": "localFolder: \"ローカルフォルダ\","
+    },
+    {
+      "line": 2162,
+      "text": "selectedFilesCount: \"$1 個のファイルが選択されました\","
+    },
+    {
+      "line": 2163,
+      "text": "clickToSelectFolder: \"クリックしてローカルフォルダを選択\","
+    },
+    {
+      "line": 2164,
+      "text": "selectFolderTip: \"フォルダ内のすべてのサポートされているファイルを読み込みます\","
+    },
+    {
+      "line": 2165,
+      "text": "importComplete: \"インポート完了\","
+    },
+    {
+      "line": 2166,
+      "text": "importedFromLocalFolder: \"ローカルフォルダからインポート: $1\","
+    },
+    {
+      "line": 2169,
+      "text": "historyTitle: \"会話履歴\","
+    },
+    {
+      "line": 2170,
+      "text": "confirmDeleteHistory: \"この会話履歴を削除してもよろしいですか?\","
+    },
+    {
+      "line": 2171,
+      "text": "deleteHistorySuccess: \"会話履歴を削除しました\","
+    },
+    {
+      "line": 2172,
+      "text": "deleteHistoryFailed: \"会話履歴の削除に失敗しました\","
+    },
+    {
+      "line": 2173,
+      "text": "yesterday: \"昨日\","
+    },
+    {
+      "line": 2174,
+      "text": "daysAgo: \"$1日前\","
+    },
+    {
+      "line": 2175,
+      "text": "historyMessages: \"$1 件のメッセージ\","
+    },
+    {
+      "line": 2176,
+      "text": "noHistory: \"会話履歴はありません\","
+    },
+    {
+      "line": 2177,
+      "text": "noHistoryDesc: \"会話を開始して履歴を作成してください\","
+    },
+    {
+      "line": 2178,
+      "text": "loadMore: \"もっと読み込む\","
+    },
+    {
+      "line": 2179,
+      "text": "loadingHistoriesFailed: \"履歴の読み込みに失敗しました\","
+    },
+    {
+      "line": 2180,
+      "text": "supportedFormatsInfo: \"ドキュメント、画像、ソースコードをサポート\","
+    },
+    {
+      "line": 2181,
+      "text": "kbSettingsSaved: \"設定を保存しました\","
+    },
+    {
+      "line": 2182,
+      "text": "failedToSaveSettings: \"設定の保存に失敗しました\","
+    },
+    {
+      "line": 2183,
+      "text": "actionFailed: \"操作に失敗しました\","
+    },
+    {
+      "line": 2184,
+      "text": "userAddedToOrganization: \"ユーザーが組織に追加されました\","
+    },
+    {
+      "line": 2185,
+      "text": "featureUpdated: \"機能が更新されました\","
+    },
+    {
+      "line": 2186,
+      "text": "roleTenantAdmin: \"テナント管理者\","
+    },
+    {
+      "line": 2187,
+      "text": "roleRegularUser: \"一般ユーザー\","
+    },
+    {
+      "line": 2188,
+      "text": "creatingRegularUser: \"一般ユーザーを作成中\","
+    },
+    {
+      "line": 2189,
+      "text": "editUserRole: \"ユーザーロールを編集\","
+    },
+    {
+      "line": 2190,
+      "text": "targetRole: \"対象のロール\","
+    },
+    {
+      "line": 2191,
+      "text": "editCategory: \"カテゴリを編集\","
+    },
+    {
+      "line": 2192,
+      "text": "totalTenants: \"総テナント数\","
+    },
+    {
+      "line": 2193,
+      "text": "systemUsers: \"システムユーザー\","
+    },
+    {
+      "line": 2194,
+      "text": "systemHealth: \"システムヘルス\","
+    },
+    {
+      "line": 2195,
+      "text": "operational: \"正常稼働中\","
+    },
+    {
+      "line": 2196,
+      "text": "orgManagement: \"組織管理\","
+    },
+    {
+      "line": 2197,
+      "text": "globalTenantControl: \"グローバルテナントコントロール\","
+    },
+    {
+      "line": 2198,
+      "text": "newTenant: \"新規テナント\","
+    },
+    {
+      "line": 2199,
+      "text": "domainOptional: \"ドメイン (任意)\","
+    },
+    {
+      "line": 2200,
+      "text": "saveChanges: \"変更を保存\","
+    },
+    {
+      "line": 2201,
+      "text": "modelConfiguration: \"モデル設定\","
+    },
+    {
+      "line": 2202,
+      "text": "defaultLLMModel: \"デフォルト推論モデル\","
+    },
+    {
+      "line": 2203,
+      "text": "selectLLM: \"LLMを選択\","
+    },
+    {
+      "line": 2204,
+      "text": "selectEmbedding: \"埋め込みを選択\","
+    },
+    {
+      "line": 2205,
+      "text": "rerankModel: \"リランクモデル\","
+    },
+    {
+      "line": 2206,
+      "text": "none: \"なし\","
+    },
+    {
+      "line": 2207,
+      "text": "indexingChunkingConfig: \"インデックスとチャンク設定\","
+    },
+    {
+      "line": 2208,
+      "text": "chatHyperparameters: \"チャットハイパーパラメータ\","
+    },
+    {
+      "line": 2209,
+      "text": "temperature: \"温度\","
+    },
+    {
+      "line": 2210,
+      "text": "precise: \"精密\","
+    },
+    {
+      "line": 2211,
+      "text": "creative: \"クリエイティブ\","
+    },
+    {
+      "line": 2212,
+      "text": "maxResponseTokens: \"最大応答トークン数\","
+    },
+    {
+      "line": 2213,
+      "text": "retrievalSearchSettings: \"検索設定\","
+    },
+    {
+      "line": 2215,
+      "text": "similarityThreshold: \"類似度しきい値\","
+    },
+    {
+      "line": 2216,
+      "text": "enableHybridSearch: \"ハイブリッド検索を有効にする\","
+    },
+    {
+      "line": 2217,
+      "text": "hybridSearchDesc: \"ベクトル検索と全文検索を併用して検索精度を向上させます\","
+    },
+    {
+      "line": 2218,
+      "text": "hybridWeight: \"ハイブリッド重み (0.0=全文, 1.0=ベクトル)\","
+    },
+    {
+      "line": 2219,
+      "text": "pureText: \"純粋なテキスト\","
+    },
+    {
+      "line": 2220,
+      "text": "pureVector: \"純粋なベクトル\","
+    },
+    {
+      "line": 2221,
+      "text": "enableQueryExpansion: \"クエリ拡張を有効にする\","
+    },
+    {
+      "line": 2222,
+      "text": "queryExpansionDesc: \"複数のクエリバリアントを生成してカバレッジを向上させます\","
+    },
+    {
+      "line": 2223,
+      "text": "enableHyDE: \"HyDEを有効にする\","
+    },
+    {
+      "line": 2224,
+      "text": "hydeDesc: \"仮想的な回答を生成してセマンティック検索を改善します\","
+    },
+    {
+      "line": 2225,
+      "text": "enableReranking: \"リランクを有効にする\","
+    },
+    {
+      "line": 2226,
+      "text": "rerankingDesc: \"リランクモデルを使用して結果を再ソートします\","
+    },
+    {
+      "line": 2227,
+      "text": "broad: \"広範\","
+    },
+    {
+      "line": 2228,
+      "text": "strict: \"厳格\","
+    },
+    {
+      "line": 2229,
+      "text": "maxInput: \"最大入力\","
+    },
+    {
+      "line": 2230,
+      "text": "dimensions: \"次元\","
+    },
+    {
+      "line": 2231,
+      "text": "defaultBadge: \"デフォルト\","
+    },
+    {
+      "line": 2232,
+      "text": "dims: \"次元: $1\","
+    },
+    {
+      "line": 2233,
+      "text": "ctx: \"コンテキスト: $1\","
+    },
+    {
+      "line": 2235,
+      "text": "configured: \"設定済み\","
+    },
+    {
+      "line": 2236,
+      "text": "groupUpdated: \"グループが更新されました\","
+    },
+    {
+      "line": 2237,
+      "text": "groupDeleted: \"グループが削除されました\","
+    },
+    {
+      "line": 2238,
+      "text": "groupCreated: \"グループが作成されました\","
+    },
+    {
+      "line": 2239,
+      "text": "navCatalog: \"カタログ\","
+    },
+    {
+      "line": 2240,
+      "text": "allDocuments: \"すべてのドキュメント\","
+    },
+    {
+      "line": 2241,
+      "text": "categories: \"カテゴリ\","
+    },
+    {
+      "line": 2242,
+      "text": "uncategorizedFiles: \"未分類ファイル\","
+    },
+    {
+      "line": 2243,
+      "text": "category: \"カテゴリ\","
+    },
+    {
+      "line": 2244,
+      "text": "statusReadyDesc: \"インデックス済みで検索可能\","
+    },
+    {
+      "line": 2245,
+      "text": "statusIndexingDesc: \"ベクトルインデックスを作成中\","
+    },
+    {
+      "line": 2246,
+      "text": "selectCategory: \"カテゴリを選択\","
+    },
+    {
+      "line": 2247,
+      "text": "noneUncategorized: \"未分類ファイルなし\","
+    },
+    {
+      "line": 2248,
+      "text": "previous: \"前へ\","
+    },
+    {
+      "line": 2249,
+      "text": "next: \"次へ\","
+    },
+    {
+      "line": 2250,
+      "text": "createCategory: \"カテゴリを作成\","
+    },
+    {
+      "line": 2251,
+      "text": "categoryDesc: \"ナレッジカテゴリを説明します\","
+    },
+    {
+      "line": 2252,
+      "text": "categoryName: \"カテゴリ名\","
+    },
+    {
+      "line": 2253,
+      "text": "createCategoryBtn: \"今すぐ作成\","
+    },
+    {
+      "line": 2254,
+      "text": "newGroup: \"新規グループ\","
+    },
+    {
+      "line": 2255,
+      "text": "noKnowledgeGroups: \"ナレッジグループがまだありません\","
+    },
+    {
+      "line": 2256,
+      "text": "createGroupDesc: \"最初のナレッジグループを作成してドキュメントをアップロードしてください。\","
+    },
+    {
+      "line": 2257,
+      "text": "noDescriptionProvided: \"説明なし\","
+    },
+    {
+      "line": 2258,
+      "text": "browseManageFiles: \"このグループ内のファイルとメモを閲覧・管理します。\","
+    },
+    {
+      "line": 2259,
+      "text": "filterGroupFiles: \"名前でグループ内のファイルを検索...\","
+    },
+    {
+      "line": 2260,
+      "text": "generalSettingsSubtitle: \"アプリケーションの設定を管理します。\","
+    },
+    {
+      "line": 2261,
+      "text": "userManagementSubtitle: \"アクセス権限とアカウントを管理します。\","
+    },
+    {
+      "line": 2262,
+      "text": "modelManagementSubtitle: \"グローバルなAIモデルを設定します。\","
+    },
+    {
+      "line": 2263,
+      "text": "kbSettingsSubtitle: \"インデックス作成とチャットパラメータの技術設定。\","
+    },
+    {
+      "line": 2264,
+      "text": "tenantsSubtitle: \"グローバルシステムの概要。\","
+    },
+    {
+      "line": 2265,
+      "text": "allNotes: \"すべてのノート\","
+    },
+    {
+      "line": 2266,
+      "text": "filterNotesPlaceholder: \"ノートをフィルタリング...\","
+    },
+    {
+      "line": 2267,
+      "text": "startWritingPlaceholder: \"書き始める...\","
+    },
+    {
+      "line": 2268,
+      "text": "previewHeader: \"プレビュー\","
+    },
+    {
+      "line": 2269,
+      "text": "noContentToPreview: \"プレビューするコンテンツがありません\","
+    },
+    {
+      "line": 2270,
+      "text": "hidePreview: \"プレビューを非表示\","
+    },
+    {
+      "line": 2271,
+      "text": "showPreview: \"プレビューを表示\","
+    },
+    {
+      "line": 2272,
+      "text": "directoryLabel: \"ディレクトリ\","
+    },
+    {
+      "line": 2273,
+      "text": "uncategorized: \"未分類\","
+    },
+    {
+      "line": 2274,
+      "text": "enterNamePlaceholder: \"名前を入力...\","
+    },
+    {
+      "line": 2275,
+      "text": "subFolderPlaceholder: \"サブフォルダ...\","
+    },
+    {
+      "line": 2276,
+      "text": "categoryCreated: \"カテゴリが作成されました\","
+    },
+    {
+      "line": 2277,
+      "text": "failedToCreateCategory: \"カテゴリの作成に失敗しました\","
+    },
+    {
+      "line": 2278,
+      "text": "failedToDeleteCategory: \"カテゴリの削除に失敗しました\","
+    },
+    {
+      "line": 2279,
+      "text": "confirmDeleteCategory: \"このカテゴリを削除してもよろしいですか?\","
+    },
+    {
+      "line": 2283,
+      "text": "agentTitle: \"エージェントセンター\","
+    },
+    {
+      "line": 2284,
+      "text": "agentDesc: \"複雑なタスクを支援する AI アシスタントを管理および実行します。\","
+    },
+    {
+      "line": 2285,
+      "text": "createAgent: \"エージェント作成\","
+    },
+    {
+      "line": 2286,
+      "text": "searchAgent: \"エージェントを検索...\","
+    },
+    {
+      "line": 2287,
+      "text": "statusRunning: \"実行中\","
+    },
+    {
+      "line": 2288,
+      "text": "statusStopped: \"停止中\","
+    },
+    {
+      "line": 2289,
+      "text": "updatedAtPrefix: \"最終更新日: \","
+    },
+    {
+      "line": 2290,
+      "text": "btnChat: \"会話を開始\","
+    },
+    {
+      "line": 2293,
+      "text": "agent1Name: \"データ分析エキスパート\","
+    },
+    {
+      "line": 2294,
+      "text": "agent1Desc: \"SQL とデータ視覚化に精通し、複雑なデータから洞察を抽出できます。\","
+    },
+    {
+      "line": 2295,
+      "text": "agent2Name: \"コードレビュー助手\","
+    },
+    {
+      "line": 2296,
+      "text": "agent2Desc: \"コードの品質を自動的にチェックし、リファクタリングの提案やパフォーマンス最適化案を提供します。\","
+    },
+    {
+      "line": 2297,
+      "text": "agent3Name: \"学術論文校閲\","
+    },
+    {
+      "line": 2298,
+      "text": "agent3Desc: \"専門的な学術ライティングアシスタント。論文の構成と表現の最適化を支援します。\","
+    },
+    {
+      "line": 2299,
+      "text": "agent4Name: \"法律顧問\","
+    },
+    {
+      "line": 2300,
+      "text": "agent4Desc: \"法律条文の検索や基本的な法的アドバイスを提供し、契約書の作成を支援します。\","
+    },
+    {
+      "line": 2301,
+      "text": "agent5Name: \"市場調査員\","
+    },
+    {
+      "line": 2302,
+      "text": "agent5Desc: \"業界のトレンドを分析し、競合他社の調査レポートを生成します。\","
+    },
+    {
+      "line": 2303,
+      "text": "agent6Name: \"システム運用保守エキスパート\","
+    },
+    {
+      "line": 2304,
+      "text": "agent6Desc: \"システムの健康状態を監視し、一般的なアラートへの対応やトラブルシューティングを自動化します。\","
+    },
+    {
+      "line": 2305,
+      "text": "agent7Name: \"財務監査人\","
+    },
+    {
+      "line": 2306,
+      "text": "agent7Desc: \"レポート監査を自動化し、財務リスクや異常な取引を特定します。\","
+    },
+    {
+      "line": 2307,
+      "text": "agent1Time: \"2 時間前\","
+    },
+    {
+      "line": 2308,
+      "text": "agent2Time: \"5 時間前\","
+    },
+    {
+      "line": 2309,
+      "text": "agent3Time: \"昨日\","
+    },
+    {
+      "line": 2310,
+      "text": "agent4Time: \"2 日前\","
+    },
+    {
+      "line": 2311,
+      "text": "agent5Time: \"3 日前\","
+    },
+    {
+      "line": 2312,
+      "text": "agent6Time: \"5 日前\","
+    },
+    {
+      "line": 2313,
+      "text": "agent7Time: \"1 週間前\","
+    },
+    {
+      "line": 2316,
+      "text": "pluginTitle: \"プラグインストア\","
+    },
+    {
+      "line": 2317,
+      "text": "pluginDesc: \"外部ツールやサービスを統合して、ナレッジベースの機能を拡張します。\","
+    },
+    {
+      "line": 2318,
+      "text": "searchPlugin: \"プラグインを検索...\","
+    },
+    {
+      "line": 2319,
+      "text": "installPlugin: \"インストール\","
+    },
+    {
+      "line": 2320,
+      "text": "installedPlugin: \"インストール済み\","
+    },
+    {
+      "line": 2321,
+      "text": "updatePlugin: \"アップデートあり\","
+    },
+    {
+      "line": 2322,
+      "text": "pluginOfficial: \"公式\","
+    },
+    {
+      "line": 2323,
+      "text": "pluginCommunity: \"コミュニティ\","
+    },
+    {
+      "line": 2324,
+      "text": "pluginBy: \"開発者: \","
+    },
+    {
+      "line": 2325,
+      "text": "pluginConfig: \"設定\","
+    },
+    {
+      "line": 2328,
+      "text": "plugin1Name: \"Web 検索\","
+    },
+    {
+      "line": 2329,
+      "text": "plugin1Desc: \"最新情報を取得するために、AI にインターネットへのリアルタイムアクセスを提供します。\","
+    },
+    {
+      "line": 2330,
+      "text": "plugin2Name: \"PDF ドキュメント解析\","
+    },
+    {
+      "line": 2331,
+      "text": "plugin2Desc: \"複雑な PDF レイアウトを詳細に解析し、表や数式を抽出します。\","
+    },
+    {
+      "line": 2332,
+      "text": "plugin3Name: \"GitHub 連携\","
+    },
+    {
+      "line": 2333,
+      "text": "plugin3Desc: \"GitHub リポジトリに直接アクセスし、コードのコミットやイシュー管理を行います。\","
+    },
+    {
+      "line": 2334,
+      "text": "plugin4Name: \"Google カレンダー\","
+    },
+    {
+      "line": 2335,
+      "text": "plugin4Desc: \"スケジュールを同期し、会議のリマインダーを自動的に作成します。\","
+    },
+    {
+      "line": 2336,
+      "text": "plugin5Name: \"SQL データベース接続\","
+    },
+    {
+      "line": 2337,
+      "text": "plugin5Desc: \"データベースに安全に接続し、自然語言でクエリを実行します。\","
+    },
+    {
+      "line": 2338,
+      "text": "plugin6Name: \"Slack 通知\","
+    },
+    {
+      "line": 2339,
+      "text": "plugin6Desc: \"AI が生成したレポートを指定された Slack チャンネルに直接送信します。\","
+    },
+    {
+      "line": 2341,
+      "text": "navTenants: \"テナント管理\","
+    },
+    {
+      "line": 2342,
+      "text": "noNotesFound: \"ノートが見つかりません\","
+    },
+    {
+      "line": 2343,
+      "text": "notebookDesc: \"ノートブックは知識の整理と要約に役立ちます。\","
+    },
+    {
+      "line": 2344,
+      "text": "personalNotebook: \"個人用ノートブック\","
+    },
+    {
+      "line": 2345,
+      "text": "warning: \"警告\","
+    },
+    {
+      "line": 2346,
+      "text": "\"x-api-key\": \"APIキー\","
+    },
+    {
+      "line": 2347,
+      "text": "\"x-tenant-id\": \"テナントID\","
+    },
+    {
+      "line": 2348,
+      "text": "\"x-user-language\": \"ユーザー言語\","
+    },
+    {
+      "line": 2351,
+      "text": "addSubcategory: \"サブカテゴリを追加\","
+    },
+    {
+      "line": 2352,
+      "text": "parentCategory: \"親カテゴリ(任意)\","
+    },
+    {
+      "line": 2353,
+      "text": "noParentTopLevel: \"なし(トップレベル)\","
+    },
+    {
+      "line": 2354,
+      "text": "useHierarchyImport: \"フォルダ階層でカテゴリを作成\","
+    },
+    {
+      "line": 2355,
+      "text": "useHierarchyImportDesc: \"有効にすると、各サブフォルダにサブカテゴリが作成され、ファイルが対応するカテゴリにインポートされます。\","
+    },
+    {
+      "line": 2358,
+      "text": "importImmediate: \"今すぐインポート\","
+    },
+    {
+      "line": 2359,
+      "text": "importScheduled: \"スケジュールインポート\","
+    },
+    {
+      "line": 2360,
+      "text": "lblServerPath: \"サーバーフォルダパス\","
+    },
+    {
+      "line": 2361,
+      "text": "placeholderServerPath: \"例: /data/documents\","
+    },
+    {
+      "line": 2362,
+      "text": "scheduledImportTip: \"サーバー側のスケジュールインポート:指定した時刻にサーバーがパスのファイルを読み込んで自動インポートします。サーバーがそのパスにアクセスできることを確認してください。\","
+    },
+    {
+      "line": 2363,
+      "text": "lblScheduledTime: \"実行日時\","
+    },
+    {
+      "line": 2364,
+      "text": "scheduledTimeHint: \"指定した時刻に、サーバーが自動的にインポートタスクを実行します。\","
+    },
+    {
+      "line": 2365,
+      "text": "scheduleImport: \"スケジュールタスクを作成\","
+    },
+    {
+      "line": 2366,
+      "text": "scheduleTaskCreated: \"スケジュールインポートタスクが作成されました\","
+    },
+    {
+      "line": 2367,
+      "text": "fillServerPath: \"サーバーフォルダパスを入力してください\","
+    },
+    {
+      "line": 2368,
+      "text": "invalidDateTime: \"有効な日付と時刻を入力してください\","
+    },
+    {
+      "line": 2371,
+      "text": "importTasksTitle: \"定期計画\","
+    },
+    {
+      "line": 2372,
+      "text": "noTasksFound: \"タスクは見つかりませんでした\","
+    },
+    {
+      "line": 2373,
+      "text": "sourcePath: \"ソースパス\","
+    },
+    {
+      "line": 2374,
+      "text": "targetGroup: \"ターゲットグループ\","
+    },
+    {
+      "line": 2375,
+      "text": "scheduledAt: \"実行予定日時\","
+    },
+    {
+      "line": 2376,
+      "text": "confirmDeleteTask: \"このインポートタスクレコードを削除してもよろしいですか?\","
+    },
+    {
+      "line": 2377,
+      "text": "deleteTaskFailed: \"タスクレコードの削除に失敗しました\","
+    }
+  ],
+  "d:\\workspace\\AuraK\\server\\src\\ai\\embedding.service.ts": [
+    {
+      "line": 11,
+      "text": "// ほとんどの設定が OpenAI インターフェースと互換性があると仮定"
+    },
+    {
+      "line": 13,
+      "text": "openAIApiKey: config.apiKey || 'ollama', // ローカルモデルの場合は key が不要な場合がある"
+    },
+    {
+      "line": 17,
+      "text": "modelName: config.modelId, // modelId に修正"
+    },
+    {
+      "line": 20,
+      "text": "// テキストが長すぎる問題の処理?LangChain は通常、自動的に処理するかエラーを出力します。"
+    },
+    {
+      "line": 21,
+      "text": "// ここでは簡略化し、直接呼び出します"
+    },
+    {
+      "line": 28,
+      "text": "); // modelId に修正"
+    }
+  ],
+  "d:\\workspace\\AuraK\\server\\src\\api\\api.controller.ts": [
+    {
+      "line": 43,
+      "text": "// ユーザーの LLM モデル設定を取得"
+    },
+    {
+      "line": 50,
+      "text": "// APIキーはオプションです - ローカルモデルを許可します"
+    },
+    {
+      "line": 52,
+      "text": "// entity タイプを types インターフェースに変換"
+    }
+  ],
+  "d:\\workspace\\AuraK\\server\\src\\api\\api.service.ts": [
+    {
+      "line": 9,
+      "text": "// 簡易的なヘルスチェックメソッド"
+    },
+    {
+      "line": 18,
+      "text": "// APIキーはオプションです - ローカルモデルを許可します"
+    }
+  ],
+  "d:\\workspace\\AuraK\\server\\src\\chat\\chat.controller.ts": [
+    {
+      "line": 21,
+      "text": "selectedLLMId?: string; // 新增:选中的 LLM 模型 ID"
+    },
+    {
+      "line": 22,
+      "text": "selectedGroups?: string[]; // 新增"
+    },
+    {
+      "line": 23,
+      "text": "selectedFiles?: string[]; // 新增:选中的文件"
+    },
+    {
+      "line": 24,
+      "text": "historyId?: string; // 新增"
+    },
+    {
+      "line": 25,
+      "text": "enableRerank?: boolean; // 新增"
+    },
+    {
+      "line": 26,
+      "text": "selectedRerankId?: string; // 新增"
+    },
+    {
+      "line": 27,
+      "text": "temperature?: number; // 新增:temperature 参数"
+    },
+    {
+      "line": 28,
+      "text": "maxTokens?: number; // 新增:maxTokens 参数"
+    },
+    {
+      "line": 29,
+      "text": "topK?: number; // 新增:topK 参数"
+    },
+    {
+      "line": 30,
+      "text": "similarityThreshold?: number; // 新増:similarityThreshold 参数"
+    },
+    {
+      "line": 31,
+      "text": "rerankSimilarityThreshold?: number; // 新増:rerankSimilarityThreshold 参数"
+    },
+    {
+      "line": 32,
+      "text": "enableQueryExpansion?: boolean; // 新增"
+    },
+    {
+      "line": 33,
+      "text": "enableHyDE?: boolean; // 新增"
+    },
+    {
+      "line": 76,
+      "text": "// 获取用户的LLM模型配置"
+    },
+    {
+      "line": 94,
+      "text": "console.log('Final LLM model used (default):', llmModel ? llmModel.name : '无');"
+    },
+    {
+      "line": 97,
+      "text": "// 设置 SSE 响应头"
+    },
+    {
+      "line": 105,
+      "text": "`data: ${JSON.stringify({ type: 'error', data: '请在模型管理中添加LLM模型并配置API密钥' })}\\n\\n`,"
+    },
+    {
+      "line": 119,
+      "text": "selectedGroups, // 新增"
+    },
+    {
+      "line": 120,
+      "text": "selectedFiles, // 新增"
+    },
+    {
+      "line": 121,
+      "text": "historyId, // 新增"
+    },
+    {
+      "line": 124,
+      "text": "temperature, // 传递 temperature 参数"
+    },
+    {
+      "line": 125,
+      "text": "maxTokens, // 传递 maxTokens 参数"
+    },
+    {
+      "line": 126,
+      "text": "topK, // 传递 topK 参数"
+    },
+    {
+      "line": 127,
+      "text": "similarityThreshold, // 传递 similarityThreshold 参数"
+    },
+    {
+      "line": 128,
+      "text": "rerankSimilarityThreshold, // 传递 rerankSimilarityThreshold 参数"
+    },
+    {
+      "line": 129,
+      "text": "enableQueryExpansion, // 传递 enableQueryExpansion"
+    },
+    {
+      "line": 130,
+      "text": "enableHyDE, // 传递 enableHyDE"
+    },
+    {
+      "line": 144,
+      "text": "`data: ${JSON.stringify({ type: 'error', data: error.message || '服务器错误' })}\\n\\n`,"
+    },
+    {
+      "line": 176,
+      "text": "`data: ${JSON.stringify({ type: 'error', data: '未找到LLM模型配置' })}\\n\\n`,"
+    },
+    {
+      "line": 198,
+      "text": "`data: ${JSON.stringify({ type: 'error', data: error.message || '服务器错误' })}\\n\\n`,"
+    }
+  ],
+  "d:\\workspace\\AuraK\\server\\src\\chat\\chat.service.ts": [
+    {
+      "line": 52,
+      "text": "selectedGroups?: string[], // 新規:選択されたグループ"
+    },
+    {
+      "line": 53,
+      "text": "selectedFiles?: string[], // 新規:選択されたファイル"
+    },
+    {
+      "line": 54,
+      "text": "historyId?: string, // 新規:対話履歴ID"
+    },
+    {
+      "line": 57,
+      "text": "temperature?: number, // 新規: temperature パラメータ"
+    },
+    {
+      "line": 58,
+      "text": "maxTokens?: number, // 新規: maxTokens パラメータ"
+    },
+    {
+      "line": 59,
+      "text": "topK?: number, // 新規: topK パラメータ"
+    },
+    {
+      "line": 60,
+      "text": "similarityThreshold?: number, // 新規: similarityThreshold パラメータ"
+    },
+    {
+      "line": 61,
+      "text": "rerankSimilarityThreshold?: number, // 新規: rerankSimilarityThreshold パラメータ"
+    },
+    {
+      "line": 62,
+      "text": "enableQueryExpansion?: boolean, // 新規"
+    },
+    {
+      "line": 63,
+      "text": "enableHyDE?: boolean, // 新規"
+    },
+    {
+      "line": 64,
+      "text": "tenantId?: string // 新規: tenant isolation"
+    },
+    {
+      "line": 67,
+      "text": "console.log('ユーザーID:', userId);"
+    },
+    {
+      "line": 85,
+      "text": "console.log('API Key プレフィックス:', modelConfig.apiKey?.substring(0, 10) + '...');"
+    },
+    {
+      "line": 88,
+      "text": "// 現在の言語設定を取得 (下位互換性のためにLANGUAGE_CONFIGを保持しますが、現在はi18nサービスを使>用)"
+    },
+    {
+      "line": 89,
+      "text": "// ユーザー設定に基づいて実際の言語を使用"
+    },
+    {
+      "line": 96,
+      "text": "// historyId がない場合は、新しい対話履歴を作成"
+    },
+    {
+      "line": 100,
+      "text": "tenantId || 'default', // 新規"
+    },
+    {
+      "line": 109,
+      "text": "// ユーザーメッセージを保存"
+    },
+    {
+      "line": 111,
+      "text": "// 1. ユーザーの埋め込みモデル設定を取得"
+    },
+    {
+      "line": 124,
+      "text": "// 2. ユーザーのクエリを直接使用して検索"
+    },
+    {
+      "line": 132,
+      "text": "// 3. 選択された知識グループがある場合、まずそれらのグループ内のファイルIDを取得"
+    },
+    {
+      "line": 133,
+      "text": "let effectiveFileIds = selectedFiles; // 明示的に指定されたファイルを優先"
+    },
+    {
+      "line": 135,
+      "text": "// ナレッジグループからファイルIDを取得"
+    },
+    {
+      "line": 139,
+      "text": "// 3. RagService を使用して検索 (混合検索 + Rerank をサポート)"
+    },
+    {
+      "line": 157,
+      "text": "// RagSearchResult を ChatService が必要とする形式 (any[]) に変換"
+    },
+    {
+      "line": 158,
+      "text": "// HybridSearch は ES の hit 構造を返しますが、RagSearchResult は正規化されています。"
+    },
+    {
+      "line": 159,
+      "text": "// BuildContext は {fileName, content} を期待します。RagSearchResult はこれらを持っています。"
+    },
+    {
+      "line": 163,
+      "text": "// 4. コンテキストの構築"
+    },
+    {
+      "line": 168,
+      "text": "// ユーザーがナレッジグループを選択したが、一致するものが見つからなかった場合"
+    },
+    {
+      "line": 181,
+      "text": "// 一時的なデバッグ情報"
+    },
+    {
+      "line": 198,
+      "text": "// 5. ストリーム回答生成"
+    },
+    {
+      "line": 241,
+      "text": "// AI 回答を保存"
+    },
+    {
+      "line": 256,
+      "text": "// 7. 自動チャットタイトル生成 (最初のやり取りの後に実行)"
+    },
+    {
+      "line": 264,
+      "text": "// 6. 引用元を返却"
+    },
+    {
+      "line": 303,
+      "text": "提供されたテキスト内容を、ユーザーの指示に基づいて修正または改善してください。"
+    },
+    {
+      "line": 304,
+      "text": "挨拶や結びの言葉(「わかりました、こちらが...」など)は含めず、修正後の内容のみを直接出力してください。"
+    },
+    {
+      "line": 306,
+      "text": "コンテキスト(現在の内容):"
+    },
+    {
+      "line": 309,
+      "text": "ユーザーの指示:"
+    },
+    {
+      "line": 329,
+      "text": "selectedGroups?: string[], // 新規パラメータ"
+    },
+    {
+      "line": 330,
+      "text": "explicitFileIds?: string[], // 新規パラメータ"
+    },
+    {
+      "line": 331,
+      "text": "tenantId?: string, // 追加"
+    },
+    {
+      "line": 334,
+      "text": "// キーワードを検索文字列に結合"
+    },
+    {
+      "line": 338,
+      "text": "// 埋め込みモデルIDが提供されているか確認"
+    },
+    {
+      "line": 344,
+      "text": "// 実際の埋め込みベクトルを使用"
+    },
+    {
+      "line": 354,
+      "text": "// 混合検索"
+    },
+    {
+      "line": 362,
+      "text": "selectedGroups, // 選択されたグループを渡す"
+    },
+    {
+      "line": 363,
+      "text": "explicitFileIds, // 明示的なファイルIDを渡す"
+    },
+    {
+      "line": 364,
+      "text": "tenantId, // 追加: tenantId"
+    },
+    {
+      "line": 442,
+      "text": "temperature: settings.temperature ?? 0.7, // ユーザー設定またはデフォルトを使用"
+    },
+    {
+      "line": 461,
+      "text": "* 対話内容に基づいてチャットのタイトルを自動生成する"
+    },
+    {
+      "line": 479,
+      "text": "// 優先順位: 引数の言語 > ユーザー設定 > 日本語(ja)"
+    },
+    {
+      "line": 486,
+      "text": "// プロンプトを構築"
+    },
+    {
+      "line": 489,
+      "text": "// LLMを呼び出してタイトルを生成"
+    },
+    {
+      "line": 497,
+      "text": "// 余分な引用符を除去"
+    }
+  ],
+  "d:\\workspace\\AuraK\\server\\src\\common\\constants.ts": [
+    {
+      "line": 2,
+      "text": "* アプリケーション全体で使用される定数定義"
+    },
+    {
+      "line": 5,
+      "text": "// チャンク設定のデフォルト値"
+    },
+    {
+      "line": 13,
+      "text": "// ベクトル次元のデフォルト値 (OpenAI Standard)"
+    },
+    {
+      "line": 16,
+      "text": "// ファイルサイズの制限 (バイト)"
+    },
+    {
+      "line": 19,
+      "text": "// バッチ処理の制限"
+    },
+    {
+      "line": 22,
+      "text": "// デフォルト言語"
+    },
+    {
+      "line": 25,
+      "text": "// システム全体の共通テナントID(シードデータなどで使用)"
+    }
+  ],
+  "d:\\workspace\\AuraK\\server\\src\\elasticsearch\\elasticsearch.service.ts": [
+    {
+      "line": 34,
+      "text": "// 初期化時にはインデックスを作成せず、実際の使用時にモデルに基づいて動的に作成されるのを待つ"
+    },
+    {
+      "line": 51,
+      "text": "// 既存インデックスのベクトル次元数を確認"
+    },
+    {
+      "line": 66,
+      "text": "// 既存インデックスを削除して再作成"
+    },
+    {
+      "line": 153,
+      "text": "refresh: true, // 即座に検索に反映させる"
+    },
+    {
+      "line": 203,
+      "text": "score: this.normalizeScore(hit._score), // スコアの正規化"
+    },
+    {
+      "line": 264,
+      "text": "score: this.normalizeScore(hit._score), // スコアの正規化"
+    },
+    {
+      "line": 290,
+      "text": "selectedGroups?: string[], // 後方互換性のために残す(未使用)"
+    },
+    {
+      "line": 291,
+      "text": "explicitFileIds?: string[], // 明示的に指定されたファイルIDリスト"
+    },
+    {
+      "line": 294,
+      "text": "// selectedGroups は廃止予定。呼び出し側で fileIds に変換して explicitFileIds を使用してください"
+    },
+    {
+      "line": 306,
+      "text": "// ハイブリッド検索:ベクトル検索 + 全文検索"
+    },
+    {
+      "line": 312,
+      "text": "// 結果をマージして重複を排除"
+    },
+    {
+      "line": 315,
+      "text": "// 向量搜索結果を追加"
+    },
+    {
+      "line": 325,
+      "text": "// 全文検索結果を追加"
+    },
+    {
+      "line": 343,
+      "text": "// 正規化のためにすべての組み合わせスコアを取得"
+    },
+    {
+      "line": 345,
+      "text": "const maxScore = Math.max(...allScores, 1); // ゼロ除算を避けるため最小1"
+    },
+    {
+      "line": 348,
+      "text": "// 総合スコアでソートして上位 topK の結果を返す"
+    },
+    {
+      "line": 353,
+      "text": "// combinedScoreは既に0-1の範囲にあるため、追加の正規化は不要"
+    },
+    {
+      "line": 354,
+      "text": "// 0-1の範囲にスコアを保つことで、実際の類似度を正確に反映"
+    },
+    {
+      "line": 357,
+      "text": "// スコアが0-1の範囲内に収まるようにクリップ"
+    },
+    {
+      "line": 377,
+      "text": "// チャンク内容"
+    },
+    {
+      "line": 382,
+      "text": "// ベクトルデータ"
+    },
+    {
+      "line": 389,
+      "text": "// ファイル関連情報"
+    },
+    {
+      "line": 395,
+      "text": "// チャンク情報"
+    },
+    {
+      "line": 400,
+      "text": "// ユーザー情報"
+    },
+    {
+      "line": 403,
+      "text": "// テナント情報(マルチテナント分離用)"
+    },
+    {
+      "line": 406,
+      "text": "// タイムスタンプ"
+    },
+    {
+      "line": 422,
+      "text": "* Elasticsearch スコアを 0-1 の範囲に正規化する"
+    },
+    {
+      "line": 423,
+      "text": "* Elasticsearch のスコアは 1.0 を超える可能性があるため、正規化が必要"
+    },
+    {
+      "line": 424,
+      "text": "* ただし、kNN検索の類似度スコアは既に0-1の範囲にある(cosine similarity)ので、"
+    },
+    {
+      "line": 425,
+      "text": "* 特別な正規化は不要。必要に応じて最小値保護のみ行う。"
+    },
+    {
+      "line": 428,
+      "text": "if (!rawScore || rawScore <= 0) return 0; // 最小値は0"
+    },
+    {
+      "line": 430,
+      "text": "// kNN検索の場合は既に0-1の範囲にあるので、1を超えないようにクリップ"
+    },
+    {
+      "line": 431,
+      "text": "// cosine similarityの最大値は1なので、1以上になった場合は1とする"
+    },
+    {
+      "line": 435,
+      "text": "// ファイルフィルタ付きのベクトル検索"
+    },
+    {
+      "line": 516,
+      "text": "// ファイルフィルタ付きの全文検索"
+    },
+    {
+      "line": 599,
+      "text": "* 指定されたファイルのすべてのチャンクを取得"
+    },
+    {
+      "line": 618,
+      "text": "size: 10000, // 単一ファイルが 10000 チャンクを超えないと想定"
+    },
+    {
+      "line": 620,
+      "text": "excludes: ['vector'], // 転送量を減らすため、ベクトルデータは返さない"
+    }
+  ],
+  "d:\\workspace\\AuraK\\server\\src\\i18n\\i18n.service.ts": [
+    {
+      "line": 7,
+      "text": "private readonly defaultLanguage = 'ja'; // プロジェクト要件に従い、日本語をデフォルトとして使用"
+    },
+    {
+      "line": 30,
+      "text": "// 汎用メッセージ取得メソッド、順次検索"
+    },
+    {
+      "line": 33,
+      "text": "// ステータスメッセージ、エラーメッセージ、ログメッセージの順に検索"
+    },
+    {
+      "line": 43,
+      "text": "// メッセージの取得とフォーマット"
+    },
+    {
+      "line": 52,
+      "text": "// サポートされている言語リストを取得"
+    },
+    {
+      "line": 57,
+      "text": "// 言語がサポートされているか確認"
+    },
+    {
+      "line": 62,
+      "text": "// システムプロンプトを取得"
+    },
+    {
+      "line": 69,
+      "text": "基于以下知识库内容回答用户问题。"
+    },
+    {
+      "line": 71,
+      "text": "**重要提示**: 用户已选择特定知识组,请严格基于以下知识库内容回答。如果知识库中没有相关信息,请明确告知用户:\"${noMatchMsg}\",然后再提供答案。"
+    },
+    {
+      "line": 73,
+      "text": "知识库内容:"
+    },
+    {
+      "line": 76,
+      "text": "历史对话:"
+    },
+    {
+      "line": 79,
+      "text": "用户问题:{question}"
+    },
+    {
+      "line": 81,
+      "text": "请用中文回答,并严格遵循以下 Markdown 格式要求:"
+    },
+    {
+      "line": 83,
+      "text": "1. **段落与结构**:"
+    },
+    {
+      "line": 84,
+      "text": "- 使用清晰的段落分隔,每个要点之间空一行"
+    },
+    {
+      "line": 85,
+      "text": "- 使用标题(## 或 ###)组织长回答"
+    },
+    {
+      "line": 87,
+      "text": "2. **文本格式**:"
+    },
+    {
+      "line": 88,
+      "text": "- 使用 **粗体** 强调重要概念和关键词"
+    },
+    {
+      "line": 89,
+      "text": "- 使用列表(- 或 1.)组织多个要点"
+    },
+    {
+      "line": 90,
+      "text": "- 使用 \\`代码\\` 标记技术术语、命令、文件名"
+    },
+    {
+      "line": 92,
+      "text": "3. **代码展示**:"
+    },
+    {
+      "line": 93,
+      "text": "- 使用代码块展示代码,并指定语言:"
+    },
+    {
+      "line": 96,
+      "text": "return \"示例\""
+    },
+    {
+      "line": 98,
+      "text": "- 支持语言:python, javascript, typescript, java, bash, sql 等"
+    },
+    {
+      "line": 100,
+      "text": "4. **图表与可视化**:"
+    },
+    {
+      "line": 101,
+      "text": "- 使用 Mermaid 语法绘制流程图、序列图等:"
+    },
+    {
+      "line": 104,
+      "text": "A[开始] --> B[处理]"
+    },
+    {
+      "line": 105,
+      "text": "B --> C[结束]"
+    },
+    {
+      "line": 107,
+      "text": "- 适用场景:流程、架构、状态机、时序图"
+    },
+    {
+      "line": 109,
+      "text": "5. **其他要求**:"
+    },
+    {
+      "line": 110,
+      "text": "- 回答精炼准确"
+    },
+    {
+      "line": 111,
+      "text": "- 多步骤操作使用有序列表"
+    },
+    {
+      "line": 112,
+      "text": "- 对比类信息建议用表格展示(如果适用)"
+    },
+    {
+      "line": 114,
+      "text": "作为智能助手,请回答用户的问题。"
+    },
+    {
+      "line": 116,
+      "text": "历史对话:"
+    },
+    {
+      "line": 119,
+      "text": "用户问题:{question}"
+    },
+    {
+      "line": 121,
+      "text": "请用中文回答。"
+    },
+    {
+      "line": 179,
+      "text": "} else { // 默认为日语,符合项目要求"
+    },
+    {
+      "line": 181,
+      "text": "以下のナレッジベースの内容に基づいてユーザーの質問に答えてください。"
+    },
+    {
+      "line": 183,
+      "text": "**重要**: ユーザーが特定の知識グループを選択しました。以下のナレッジベースの内容に厳密に基づいて回答してください。ナレッジベースに関連情報がない場合は、「${noMatchMsg}」とユーザーに明示的に伝えてから、回答を提供してください。"
+    },
+    {
+      "line": 185,
+      "text": "ナレッジベースの内容:"
+    },
+    {
+      "line": 188,
+      "text": "会話履歴:"
+    },
+    {
+      "line": 191,
+      "text": "ユーザーの質問:{question}"
+    },
+    {
+      "line": 193,
+      "text": "日本語で回答してください。以下の Markdown 書式要件に厳密に従ってください:"
+    },
+    {
+      "line": 195,
+      "text": "1. **段落と構造**:"
+    },
+    {
+      "line": 196,
+      "text": "- 明確な段落分けを使用し、要点間に空行を入れる"
+    },
+    {
+      "line": 197,
+      "text": "- 長い回答には見出し(## または ###)を使用"
+    },
+    {
+      "line": 199,
+      "text": "2. **テキスト書式**:"
+    },
+    {
+      "line": 200,
+      "text": "- 重要な概念やキーワードを強調するために **太字** を使用"
+    },
+    {
+      "line": 201,
+      "text": "- 複数のポイントを整理するためにリスト(- または 1.)を使用"
+    },
+    {
+      "line": 202,
+      "text": "- 技術用語、コマンド、ファイル名をマークするために \\`コード\\` を使用"
+    },
+    {
+      "line": 204,
+      "text": "3. **コード表示**:"
+    },
+    {
+      "line": 205,
+      "text": "- 言語を指定してコードブロックを使用:"
+    },
+    {
+      "line": 208,
+      "text": "return \"例\""
+    },
+    {
+      "line": 210,
+      "text": "- 対応言語:python, javascript, typescript, java, bash, sql など"
+    },
+    {
+      "line": 212,
+      "text": "4. **図表とチャート**:"
+    },
+    {
+      "line": 213,
+      "text": "- フローチャート、シーケンス図などに Mermaid 構文を使用:"
+    },
+    {
+      "line": 216,
+      "text": "A[開始] --> B[処理]"
+    },
+    {
+      "line": 217,
+      "text": "B --> C[終了]"
+    },
+    {
+      "line": 219,
+      "text": "- 使用例:プロセスフロー、アーキテクチャ図、状態図、シーケンス図"
+    },
+    {
+      "line": 221,
+      "text": "5. **その他の要件**:"
+    },
+    {
+      "line": 222,
+      "text": "- 簡潔で明確な回答を心がける"
+    },
+    {
+      "line": 223,
+      "text": "- 複数のステップがある場合は番号付きリストを使用"
+    },
+    {
+      "line": 224,
+      "text": "- 比較情報には表を使用(該当する場合)"
+    },
+    {
+      "line": 226,
+      "text": "インテリジェントアシスタントとして、ユーザーの質問に答えてください。"
+    },
+    {
+      "line": 228,
+      "text": "会話履歴:"
+    },
+    {
+      "line": 231,
+      "text": "ユーザーの質問:{question}"
+    },
+    {
+      "line": 232,
+      "text": "日本語で回答してください。"
+    },
+    {
+      "line": 237,
+      "text": "// タイトル生成用のプロンプトを取得"
+    },
+    {
+      "line": 241,
+      "text": "return `你是一个文档分析师。请阅读以下文本(文档开头部分),并生成一个简炼、专业的标题(不超过50个字符)。"
+    },
+    {
+      "line": 242,
+      "text": "只返回标题文本。不要包含任何解释性文字或前导词(如“标题是:”)。"
+    },
+    {
+      "line": 243,
+      "text": "语言:中文"
+    },
+    {
+      "line": 244,
+      "text": "文本内容:"
+    },
+    {
+      "line": 253,
+      "text": "return `あなたはドキュメントアナライザーです。以下のテキスト(ドキュメントの冒頭部分)を読み、簡潔でプロフェッショナルなタイトル(最大50文字)を生成してください。"
+    },
+    {
+      "line": 254,
+      "text": "タイトルテキストのみを返してください。説明文や前置き(例:「タイトルは:」)は含めないでください。"
+    },
+    {
+      "line": 255,
+      "text": "言語:日本語"
+    },
+    {
+      "line": 256,
+      "text": "テキスト:"
+    },
+    {
+      "line": 264,
+      "text": "return `根据以下对话片段,生成一个简短、描述性的标题(不超过50个字符),总结讨论的主题。"
+    },
+    {
+      "line": 265,
+      "text": "只返回标题文本。不要包含任何前导词。"
+    },
+    {
+      "line": 266,
+      "text": "语言:中文"
+    },
+    {
+      "line": 267,
+      "text": "片段:"
+    },
+    {
+      "line": 268,
+      "text": "用户: ${userMessage}"
+    },
+    {
+      "line": 269,
+      "text": "助手: ${aiResponse}`;"
+    },
+    {
+      "line": 278,
+      "text": "return `以下の会話スニペットに基づいて、トピックを要約する短く説明的なタイトル(最大50文字)を生成してください。"
+    },
+    {
+      "line": 279,
+      "text": "タイトルのみを返してください。前置きは不要です。"
+    },
+    {
+      "line": 280,
+      "text": "言語:日本語"
+    },
+    {
+      "line": 281,
+      "text": "スニペット:"
+    },
+    {
+      "line": 282,
+      "text": "ユーザー: ${userMessage}"
+    },
+    {
+      "line": 283,
+      "text": "アシスタント: ${aiResponse}`;"
+    }
+  ],
+  "d:\\workspace\\AuraK\\server\\src\\i18n\\messages.ts": [
+    {
+      "line": 3,
+      "text": "noEmbeddingModel: '请先在系统设置中配置嵌入模型',"
+    },
+    {
+      "line": 4,
+      "text": "searchFailed: '搜索知识库失败,将基于一般知识回答...',"
+    },
+    {
+      "line": 5,
+      "text": "invalidApiKey: 'API密钥无效',"
+    },
+    {
+      "line": 6,
+      "text": "fileNotFound: '未找到文件',"
+    },
+    {
+      "line": 7,
+      "text": "insufficientQuota: '配额不足',"
+    },
+    {
+      "line": 8,
+      "text": "modelNotConfigured: '未配置模型',"
+    },
+    {
+      "line": 9,
+      "text": "visionModelNotConfigured: '未配置视觉模型',"
+    },
+    {
+      "line": 10,
+      "text": "embeddingDimensionMismatch: '嵌入维度不匹配',"
+    },
+    {
+      "line": 11,
+      "text": "uploadNoFile: '未上传文件',"
+    },
+    {
+      "line": 12,
+      "text": "uploadSizeExceeded: '文件大小超过限制: {size}, 最大允许: {max}',"
+    },
+    {
+      "line": 13,
+      "text": "uploadModelRequired: '必须选择嵌入模型',"
+    },
+    {
+      "line": 14,
+      "text": "uploadTypeUnsupported: '不支持的文件格式: {type}',"
+    },
+    {
+      "line": 15,
+      "text": "chunkOverflow: '切片大小 {size} 超过上限 {max} ({reason})。已自动调整',"
+    },
+    {
+      "line": 16,
+      "text": "chunkUnderflow: '切片大小 {size} 小于最小值 {min}。已自动调整',"
+    },
+    {
+      "line": 17,
+      "text": "overlapOverflow: '重叠大小 {size} 超过上限 {max}。已自动调整',"
+    },
+    {
+      "line": 18,
+      "text": "overlapUnderflow: '重叠大小 {size} 小于最小值 {min}。已自动调整',"
+    },
+    {
+      "line": 19,
+      "text": "overlapRatioExceeded: '重叠大小 {size} 超过切片大小的50% ({max})。已自动调整',"
+    },
+    {
+      "line": 20,
+      "text": "batchOverflowWarning: '建议切片大小不超过 {safeSize} 以避免批量处理溢出 (当前: {size}, 模型限制的 {percent}%)',"
+    },
+    {
+      "line": 21,
+      "text": "estimatedChunkCountExcessive: '预计切片数量过多 ({count}),处理可能较慢',"
+    },
+    {
+      "line": 22,
+      "text": "contentAndTitleRequired: '内容和标题为必填项',"
+    },
+    {
+      "line": 23,
+      "text": "embeddingModelNotFound: '找不到嵌入模型 {id} 或类型不是 embedding',"
+    },
+    {
+      "line": 24,
+      "text": "ocrFailed: '提取文本失败: {message}',"
+    },
+    {
+      "line": 25,
+      "text": "noImageUploaded: '未上传图片',"
+    },
+    {
+      "line": 26,
+      "text": "adminOnlyViewList: '只有管理员可以查看用户列表',"
+    },
+    {
+      "line": 27,
+      "text": "passwordsRequired: '当前密码和新密码不能为空',"
+    },
+    {
+      "line": 28,
+      "text": "newPasswordMinLength: '新密码长度不能少于6位',"
+    },
+    {
+      "line": 29,
+      "text": "adminOnlyCreateUser: '只有管理员可以创建用户',"
+    },
+    {
+      "line": 30,
+      "text": "usernamePasswordRequired: '用户名和密码不能为空',"
+    },
+    {
+      "line": 31,
+      "text": "passwordMinLength: '密码长度不能少于6位',"
+    },
+    {
+      "line": 32,
+      "text": "adminOnlyUpdateUser: '只有管理员可以更新用户信息',"
+    },
+    {
+      "line": 33,
+      "text": "userNotFound: '用户不存在',"
+    },
+    {
+      "line": 34,
+      "text": "cannotModifyBuiltinAdmin: '无法修改内置管理员账户',"
+    },
+    {
+      "line": 35,
+      "text": "adminOnlyDeleteUser: '只有管理员可以删除用户',"
+    },
+    {
+      "line": 36,
+      "text": "cannotDeleteSelf: '不能删除自己的账户',"
+    },
+    {
+      "line": 37,
+      "text": "cannotDeleteBuiltinAdmin: '无法删除内置管理员账户',"
+    },
+    {
+      "line": 38,
+      "text": "incorrectCredentials: '用户名或密码不正确',"
+    },
+    {
+      "line": 39,
+      "text": "incorrectCurrentPassword: '当前密码错误',"
+    },
+    {
+      "line": 40,
+      "text": "usernameExists: '用户名已存在',"
+    },
+    {
+      "line": 41,
+      "text": "noteNotFound: '找不到笔记: {id}',"
+    },
+    {
+      "line": 42,
+      "text": "knowledgeGroupNotFound: '找不到知识组: {id}',"
+    },
+    {
+      "line": 43,
+      "text": "accessDeniedNoToken: '访问被拒绝:缺少令牌',"
+    },
+    {
+      "line": 44,
+      "text": "invalidToken: '无效的令牌',"
+    },
+    {
+      "line": 45,
+      "text": "pdfFileNotFound: '找不到 PDF 文件',"
+    },
+    {
+      "line": 46,
+      "text": "pdfFileEmpty: 'PDF 文件为空,转换可能失败',"
+    },
+    {
+      "line": 47,
+      "text": "pdfConversionFailed: 'PDF 文件不存在或转换失败',"
+    },
+    {
+      "line": 48,
+      "text": "pdfConversionFailedDetail: 'PDF 转换失败(文件 ID: {id}),请稍后重试',"
+    },
+    {
+      "line": 49,
+      "text": "pdfPreviewNotSupported: '该文件格式不支持预览',"
+    },
+    {
+      "line": 50,
+      "text": "pdfServiceUnavailable: 'PDF 服务不可用: {message}',"
+    },
+    {
+      "line": 51,
+      "text": "pageImageNotFound: '找不到页面图像',"
+    },
+    {
+      "line": 52,
+      "text": "pdfPageImageFailed: '无法获取 PDF 页面图像',"
+    },
+    {
+      "line": 53,
+      "text": "someGroupsNotFound: '部分组不存在',"
+    },
+    {
+      "line": 54,
+      "text": "promptRequired: '提示词是必填项',"
+    },
+    {
+      "line": 55,
+      "text": "addLLMConfig: '请在系统设置中添加 LLM 模型',"
+    },
+    {
+      "line": 56,
+      "text": "visionAnalysisFailed: '视觉分析失败: {message}',"
+    },
+    {
+      "line": 57,
+      "text": "retryMechanismError: '重试机制异常',"
+    },
+    {
+      "line": 58,
+      "text": "imageLoadError: '无法读取图像: {message}',"
+    },
+    {
+      "line": 59,
+      "text": "groupNotFound: '分组不存在',"
+    },
+    {
+      "line": 62,
+      "text": "noEmbeddingModel: '先にシステム設定で埋め込みモデルを設定してください',"
+    },
+    {
+      "line": 63,
+      "text": "searchFailed: 'ナレッジベース検索に失敗しました。一般的な知識に基づいて回答します...',"
+    },
+    {
+      "line": 64,
+      "text": "invalidApiKey: 'APIキーが無効です',"
+    },
+    {
+      "line": 65,
+      "text": "fileNotFound: 'ファイルが見つかりません',"
+    },
+    {
+      "line": 66,
+      "text": "insufficientQuota: '利用枠が不足しています',"
+    },
+    {
+      "line": 67,
+      "text": "modelNotConfigured: 'モデルが設定されていません',"
+    },
+    {
+      "line": 68,
+      "text": "visionModelNotConfigured: 'ビジョンモデルが設定されていません',"
+    },
+    {
+      "line": 69,
+      "text": "embeddingDimensionMismatch: '埋め込み次元数が一致しません',"
+    },
+    {
+      "line": 70,
+      "text": "uploadNoFile: 'ファイルがアップロードされていません',"
+    },
+    {
+      "line": 71,
+      "text": "uploadSizeExceeded: 'ファイルサイズが制限を超えています: {size}, 最大許容: {max}',"
+    },
+    {
+      "line": 72,
+      "text": "uploadModelRequired: '埋め込みモデルを選択する必要があります',"
+    },
+    {
+      "line": 73,
+      "text": "uploadTypeUnsupported: 'サポートされていないファイル形式です: {type}',"
+    },
+    {
+      "line": 74,
+      "text": "chunkOverflow: 'チャンクサイズ {size} が上限 {max} ({reason}) を超えています。自動調整されました',"
+    },
+    {
+      "line": 75,
+      "text": "chunkUnderflow: 'チャンクサイズ {size} が最小値 {min} 未満です。自動調整されました',"
+    },
+    {
+      "line": 76,
+      "text": "overlapOverflow: '重なりサイズ {size} が上限 {max} を超えています。自動調整されました',"
+    },
+    {
+      "line": 77,
+      "text": "overlapUnderflow: '重なりサイズ {size} が最小値 {min} 未満です。自動調整されました',"
+    },
+    {
+      "line": 78,
+      "text": "overlapRatioExceeded: '重なりサイズ {size} がチャンクサイズの50% ({max}) を超えています。自動調整されました',"
+    },
+    {
+      "line": 79,
+      "text": "batchOverflowWarning: 'バッチ処理のオーバーフローを避けるため、チャンクサイズを {safeSize} 以下にすることをお勧めします (現在: {size}, モデル制限の {percent}%)',"
+    },
+    {
+      "line": 80,
+      "text": "estimatedChunkCountExcessive: '推定チャンク数が多すぎます ({count})。処理に時間がかかる可能性があります',"
+    },
+    {
+      "line": 81,
+      "text": "contentAndTitleRequired: '内容とタイトルは必須です',"
+    },
+    {
+      "line": 82,
+      "text": "embeddingModelNotFound: '埋め込みモデル {id} が見つかりません、またはタイプが embedding ではありません',"
+    },
+    {
+      "line": 83,
+      "text": "ocrFailed: 'テキストの抽出に失敗しました: {message}',"
+    },
+    {
+      "line": 84,
+      "text": "noImageUploaded: '画像がアップロードされていません',"
+    },
+    {
+      "line": 85,
+      "text": "adminOnlyViewList: '管理者のみがユーザーリストを表示できます',"
+    },
+    {
+      "line": 86,
+      "text": "passwordsRequired: '現在のパスワードと新しいパスワードは必須です',"
+    },
+    {
+      "line": 87,
+      "text": "newPasswordMinLength: '新しいパスワードは少なくとも6文字以上である必要があります',"
+    },
+    {
+      "line": 88,
+      "text": "adminOnlyCreateUser: '管理者のみがユーザーを作成できます',"
+    },
+    {
+      "line": 89,
+      "text": "usernamePasswordRequired: 'ユーザー名とパスワードは必須です',"
+    },
+    {
+      "line": 90,
+      "text": "passwordMinLength: 'パスワードは少なくとも6文字以上である必要があります',"
+    },
+    {
+      "line": 91,
+      "text": "adminOnlyUpdateUser: '管理者のみがユーザー情報を更新できます',"
+    },
+    {
+      "line": 92,
+      "text": "userNotFound: 'ユーザーが見つかりません',"
+    },
+    {
+      "line": 93,
+      "text": "cannotModifyBuiltinAdmin: 'ビルトイン管理者アカウントを変更できません',"
+    },
+    {
+      "line": 94,
+      "text": "adminOnlyDeleteUser: '管理者のみがユーザーを削除できます',"
+    },
+    {
+      "line": 95,
+      "text": "cannotDeleteSelf: '自分自身のアカウントを削除できません',"
+    },
+    {
+      "line": 96,
+      "text": "cannotDeleteBuiltinAdmin: 'ビルトイン管理者アカウントを削除できません',"
+    },
+    {
+      "line": 97,
+      "text": "incorrectCredentials: 'ユーザー名またはパスワードが間違っています',"
+    },
+    {
+      "line": 98,
+      "text": "incorrectCurrentPassword: '現在のパスワードが間違っています',"
+    },
+    {
+      "line": 99,
+      "text": "usernameExists: 'ユーザー名が既に存在します',"
+    },
+    {
+      "line": 100,
+      "text": "noteNotFound: 'ノートが見つかりません: {id}',"
+    },
+    {
+      "line": 101,
+      "text": "knowledgeGroupNotFound: 'ナレッジグループが見つかりません: {id}',"
+    },
+    {
+      "line": 102,
+      "text": "accessDeniedNoToken: 'アクセス不許可:トークンがありません',"
+    },
+    {
+      "line": 103,
+      "text": "invalidToken: '無効なトークンです',"
+    },
+    {
+      "line": 104,
+      "text": "pdfFileNotFound: 'PDF ファイルが見つかりません',"
+    },
+    {
+      "line": 105,
+      "text": "pdfFileEmpty: 'PDF ファイルが空です。変換に失敗した可能性があります',"
+    },
+    {
+      "line": 106,
+      "text": "pdfConversionFailed: 'PDF ファイルが存在しないか、変換に失敗しました',"
+    },
+    {
+      "line": 107,
+      "text": "pdfConversionFailedDetail: 'PDF 変換に失敗しました(ファイル ID: {id})。後でもう一度お試しください',"
+    },
+    {
+      "line": 108,
+      "text": "pdfPreviewNotSupported: 'このファイル形式はプレビューをサポートしていません',"
+    },
+    {
+      "line": 109,
+      "text": "pdfServiceUnavailable: 'PDF サービスを利用できません: {message}',"
+    },
+    {
+      "line": 110,
+      "text": "pageImageNotFound: 'ページ画像が見つかりません',"
+    },
+    {
+      "line": 111,
+      "text": "pdfPageImageFailed: 'PDF ページの画像を取得できませんでした',"
+    },
+    {
+      "line": 112,
+      "text": "someGroupsNotFound: '一部のグループが存在しません',"
+    },
+    {
+      "line": 113,
+      "text": "promptRequired: 'プロンプトは必須です',"
+    },
+    {
+      "line": 114,
+      "text": "addLLMConfig: 'システム設定で LLM モデルを追加してください',"
+    },
+    {
+      "line": 115,
+      "text": "visionAnalysisFailed: 'ビジョン分析に失敗しました: {message}',"
+    },
+    {
+      "line": 116,
+      "text": "retryMechanismError: '再試行メカニズムの異常',"
+    },
+    {
+      "line": 117,
+      "text": "imageLoadError: '画像を読み込めません: {message}',"
+    },
+    {
+      "line": 118,
+      "text": "groupNotFound: 'グループが存在しません',"
+    },
+    {
+      "line": 184,
+      "text": "processingFile: '处理文件: {name} ({size})',"
+    },
+    {
+      "line": 185,
+      "text": "indexingComplete: '索引完成: {id}',"
+    },
+    {
+      "line": 186,
+      "text": "vectorizingFile: '向量化文件: ',"
+    },
+    {
+      "line": 187,
+      "text": "searchQuery: '搜索查询: ',"
+    },
+    {
+      "line": 188,
+      "text": "modelCall: '[模型调用] 类型: {type}, 模型: {model}, 用户: {user}',"
+    },
+    {
+      "line": 189,
+      "text": "memoryStatus: '内存状态: ',"
+    },
+    {
+      "line": 190,
+      "text": "uploadSuccess: '文件上传成功。正在后台索引',"
+    },
+    {
+      "line": 191,
+      "text": "overlapAdjusted: '重叠大小超过切片大小的50%。已自动调整为 {newSize}',"
+    },
+    {
+      "line": 192,
+      "text": "environmentLimit: '环境变量限制',"
+    },
+    {
+      "line": 193,
+      "text": "modelLimit: '模型限制',"
+    },
+    {
+      "line": 194,
+      "text": "configLoaded: '数据库模型配置加载: {name} ({id})',"
+    },
+    {
+      "line": 195,
+      "text": "batchSizeAdjusted: '批量大小从 {old} 调整为 {new} (模型限制: {limit})',"
+    },
+    {
+      "line": 196,
+      "text": "dimensionMismatch: '模型 {id} 维度不匹配: 预期 {expected}, 实际 {actual}',"
+    },
+    {
+      "line": 197,
+      "text": "searchMetadataFailed: '为用户 {userId} 搜索知识库失败',"
+    },
+    {
+      "line": 198,
+      "text": "extractedTextTooLarge: '抽出されたテキストが大きいです: {size}MB',"
+    },
+    {
+      "line": 199,
+      "text": "preciseModeUnsupported: '格式 {ext} 不支持精密模式,回退到快速模式',"
+    },
+    {
+      "line": 200,
+      "text": "visionModelNotConfiguredFallback: '未配置视觉模型,回退到快速模式',"
+    },
+    {
+      "line": 201,
+      "text": "visionModelInvalidFallback: '视觉模型配置无效,回退到快速模式',"
+    },
+    {
+      "line": 202,
+      "text": "visionPipelineFailed: '视觉流水线失败,回退到快速模式',"
+    },
+    {
+      "line": 203,
+      "text": "preciseModeComplete: '精密模式提取完成: {pages}页, 费用: ${cost}',"
+    },
+    {
+      "line": 204,
+      "text": "skippingEmptyVectorPage: '跳过第 {page} 页(空向量)',"
+    },
+    {
+      "line": 205,
+      "text": "pdfPageImageError: '获取 PDF 页面图像失败: {message}',"
+    },
+    {
+      "line": 206,
+      "text": "internalServerError: '服务器内部错误',"
+    },
+    {
+      "line": 209,
+      "text": "processingFile: 'ファイル処理中: {name} ({size})',"
+    },
+    {
+      "line": 210,
+      "text": "indexingComplete: 'インデックス完了: {id}',"
+    },
+    {
+      "line": 211,
+      "text": "vectorizingFile: 'ファイルベクトル化中: ',"
+    },
+    {
+      "line": 212,
+      "text": "searchQuery: '検索クエリ: ',"
+    },
+    {
+      "line": 213,
+      "text": "modelCall: '[モデル呼び出し] タイプ: {type}, モデル: {model}, ユーザー: {user}',"
+    },
+    {
+      "line": 214,
+      "text": "memoryStatus: 'メモリ状態: ',"
+    },
+    {
+      "line": 215,
+      "text": "uploadSuccess: 'ファイルが正常にアップロードされました。バックグラウンドでインデックス処理を実行中です',"
+    },
+    {
+      "line": 216,
+      "text": "overlapAdjusted: 'オーバーラップサイズがチャンクサイズの50%を超えています。自動的に {newSize} に調整されました',"
+    },
+    {
+      "line": 217,
+      "text": "environmentLimit: '環境変数の制限',"
+    },
+    {
+      "line": 218,
+      "text": "modelLimit: 'モデルの制限',"
+    },
+    {
+      "line": 219,
+      "text": "configLoaded: 'データベースからモデル設定を読み込みました: {name} ({id})',"
+    },
+    {
+      "line": 220,
+      "text": "batchSizeAdjusted: 'バッチサイズを {old} から {new} に調整しました (モデル制限: {limit})',"
+    },
+    {
+      "line": 221,
+      "text": "dimensionMismatch: 'モデル {id} の次元が一致しません: 期待値 {expected}, 実際 {actual}',"
+    },
+    {
+      "line": 222,
+      "text": "searchMetadataFailed: 'ユーザー {userId} のナレッジベース検索に失敗しました',"
+    },
+    {
+      "line": 223,
+      "text": "extractedTextTooLarge: '抽出されたテキストが大きいです: {size}MB',"
+    },
+    {
+      "line": 224,
+      "text": "preciseModeUnsupported: 'ファイル形式 {ext} は精密モードをサポートしていません。高速モードにフォールバックします',"
+    },
+    {
+      "line": 225,
+      "text": "visionModelNotConfiguredFallback: 'ビジョンモデルが設定されていません。高速モードにフォールバックします',"
+    },
+    {
+      "line": 226,
+      "text": "visionModelInvalidFallback: 'ビジョンモデルの設定が無効です。高速モードにフォールバックします',"
+    },
+    {
+      "line": 227,
+      "text": "visionPipelineFailed: 'ビジョンパイプラインが失敗しました。高速モードにフォールバックします',"
+    },
+    {
+      "line": 228,
+      "text": "preciseModeComplete: '精密モード内容抽出完了: {pages}ページ, コスト: ${cost}',"
+    },
+    {
+      "line": 229,
+      "text": "skippingEmptyVectorPage: '第 {page} ページの空ベクトルをスキップします',"
+    },
+    {
+      "line": 230,
+      "text": "pdfPageImageError: 'PDF ページの画像取得に失敗しました: {message}',"
+    },
+    {
+      "line": 231,
+      "text": "internalServerError: 'サーバー内部エラー',"
+    },
+    {
+      "line": 262,
+      "text": "searching: '正在搜索知识库...',"
+    },
+    {
+      "line": 263,
+      "text": "noResults: '未找到相关知识,将基于一般知识回答...',"
+    },
+    {
+      "line": 264,
+      "text": "searchFailed: '知识库搜索失败,将基于一般知识回答...',"
+    },
+    {
+      "line": 265,
+      "text": "generatingResponse: '正在生成回答',"
+    },
+    {
+      "line": 266,
+      "text": "files: '个文件',"
+    },
+    {
+      "line": 267,
+      "text": "notebooks: '个笔记本',"
+    },
+    {
+      "line": 268,
+      "text": "all: '全部',"
+    },
+    {
+      "line": 269,
+      "text": "items: '个',"
+    },
+    {
+      "line": 270,
+      "text": "searchResults: '搜索结果',"
+    },
+    {
+      "line": 271,
+      "text": "relevantInfoFound: '条相关信息找到',"
+    },
+    {
+      "line": 272,
+      "text": "searchHits: '搜索命中',"
+    },
+    {
+      "line": 273,
+      "text": "relevance: '相关度',"
+    },
+    {
+      "line": 274,
+      "text": "sourceFiles: '源文件',"
+    },
+    {
+      "line": 275,
+      "text": "searchScope: '搜索范围',"
+    },
+    {
+      "line": 276,
+      "text": "error: '错误',"
+    },
+    {
+      "line": 277,
+      "text": "creatingHistory: '创建新对话历史: ',"
+    },
+    {
+      "line": 278,
+      "text": "searchingModelById: '根据ID搜索模型: ',"
+    },
+    {
+      "line": 279,
+      "text": "searchModelFallback: '未找到指定的嵌入模型。使用第一个可用模型。',"
+    },
+    {
+      "line": 280,
+      "text": "noEmbeddingModelFound: '找不到嵌入模型设置',"
+    },
+    {
+      "line": 281,
+      "text": "usingEmbeddingModel: '使用的嵌入模型: ',"
+    },
+    {
+      "line": 282,
+      "text": "startingSearch: '开始搜索知识库...',"
+    },
+    {
+      "line": 283,
+      "text": "searchResultsCount: '搜索结果数: ',"
+    },
+    {
+      "line": 284,
+      "text": "searchFailedLog: '搜索失败',"
+    },
+    {
+      "line": 285,
+      "text": "modelCall: '[模型调用]',"
+    },
+    {
+      "line": 286,
+      "text": "chatStreamError: '聊天流错误',"
+    },
+    {
+      "line": 287,
+      "text": "assistStreamError: '辅助流错误',"
+    },
+    {
+      "line": 288,
+      "text": "file: '文件',"
+    },
+    {
+      "line": 289,
+      "text": "content: '内容',"
+    },
+    {
+      "line": 290,
+      "text": "userLabel: '用户',"
+    },
+    {
+      "line": 291,
+      "text": "assistantLabel: '助手',"
+    },
+    {
+      "line": 292,
+      "text": "intelligentAssistant: '您是智能写作助手。',"
+    },
+    {
+      "line": 293,
+      "text": "searchString: '搜索字符串: ',"
+    },
+    {
+      "line": 294,
+      "text": "embeddingModelIdNotProvided: '未提供嵌入模型ID',"
+    },
+    {
+      "line": 295,
+      "text": "generatingEmbeddings: '生成嵌入向量...',"
+    },
+    {
+      "line": 296,
+      "text": "embeddingsGenerated: '嵌入向量生成完成',"
+    },
+    {
+      "line": 297,
+      "text": "dimensions: '维度',"
+    },
+    {
+      "line": 298,
+      "text": "performingHybridSearch: '执行混合搜索...',"
+    },
+    {
+      "line": 299,
+      "text": "esSearchCompleted: 'ES搜索完成',"
+    },
+    {
+      "line": 300,
+      "text": "resultsCount: '结果数',"
+    },
+    {
+      "line": 301,
+      "text": "hybridSearchFailed: '混合搜索失败',"
+    },
+    {
+      "line": 302,
+      "text": "getContextForTopicFailed: '获取主题上下文失败',"
+    },
+    {
+      "line": 303,
+      "text": "noLLMConfigured: '用户未配置LLM模型',"
+    },
+    {
+      "line": 304,
+      "text": "simpleChatGenerationError: '简单聊天生成错误',"
+    },
+    {
+      "line": 305,
+      "text": "noMatchInKnowledgeGroup: '所选知识组中未找到相关内容,以下是基于模型的一般性回答:',"
+    },
+    {
+      "line": 306,
+      "text": "uploadTextSuccess: '笔记内容已接收。正在后台索引',"
+    },
+    {
+      "line": 307,
+      "text": "passwordChanged: '密码已成功修改',"
+    },
+    {
+      "line": 308,
+      "text": "userCreated: '用户已成功创建',"
+    },
+    {
+      "line": 309,
+      "text": "userInfoUpdated: '用户信息已更新',"
+    },
+    {
+      "line": 310,
+      "text": "userDeleted: '用户已删除',"
+    },
+    {
+      "line": 311,
+      "text": "pdfNoteTitle: 'PDF 笔记 - {date}',"
+    },
+    {
+      "line": 312,
+      "text": "noTextExtracted: '未提取到文本',"
+    },
+    {
+      "line": 313,
+      "text": "kbCleared: '知识库已清空',"
+    },
+    {
+      "line": 314,
+      "text": "fileDeleted: '文件已删除',"
+    },
+    {
+      "line": 315,
+      "text": "pageImageNotFoundDetail: '无法获取 PDF 第 {page} 页’的图像',"
+    },
+    {
+      "line": 316,
+      "text": "groupSyncSuccess: '文件分组已更新',"
+    },
+    {
+      "line": 317,
+      "text": "fileDeletedFromGroup: '文件已从分组中删除',"
+    },
+    {
+      "line": 318,
+      "text": "chunkConfigCorrection: '切片配置已修正: {warnings}',"
+    },
+    {
+      "line": 319,
+      "text": "noChunksGenerated: '文件 {id} 未生成任何切片',"
+    },
+    {
+      "line": 320,
+      "text": "chunkCountAnomaly: '实际切片数 {actual} 大幅超过预计值 {estimated},可能存在异常',"
+    },
+    {
+      "line": 321,
+      "text": "batchSizeExceeded: '批次 {index} 的大小 {actual} 超过推荐值 {limit},将拆分处理',"
+    },
+    {
+      "line": 322,
+      "text": "skippingEmptyVectorChunk: '跳过文本块 {index} (空向量)',"
+    },
+    {
+      "line": 323,
+      "text": "contextLengthErrorFallback: '批次处理发生上下文长度错误,降级到逐条处理模式',"
+    },
+    {
+      "line": 324,
+      "text": "chunkLimitExceededForceBatch: '切片数 {actual} 超过模型批次限制 {limit},强制进行批次处理',"
+    },
+    {
+      "line": 325,
+      "text": "noteContentRequired: '笔记内容是必填项',"
+    },
+    {
+      "line": 326,
+      "text": "imageAnalysisStarted: '正在使用模型 {id} 分析图像...',"
+    },
+    {
+      "line": 327,
+      "text": "batchAnalysisStarted: '正在分析 {count} 张图像...',"
+    },
+    {
+      "line": 328,
+      "text": "pageAnalysisFailed: '第 {page} 页分析失败',"
+    },
+    {
+      "line": 329,
+      "text": "visionSystemPrompt: '您是专业的文档分析助手。请分析此文档图像,并按以下要求以 JSON 格式返回:\\n\\n1. 提取所有可读文本(按阅读顺序,保持段落和格式)\\n2. 识别图像/图表/表格(描述内容、含义和作用)\\n3. 分析页面布局(仅文本/文本和图像混合/表格/图表等)\\n4. 评估分析质量 (0-1)\\n\\n响应格式:\\n{\\n  \"text\": \"完整的文本内容\",\\n  \"images\": [\\n    {\"type\": \"图表类型\", \"description\": \"详细描述\", \"position\": 1}\\n  ],\\n  \"layout\": \"布局说明\",\\n  \"confidence\": 0.95\\n}',"
+    },
+    {
+      "line": 330,
+      "text": "visionModelCall: '[模型调用] 类型: Vision, 模型: {model}, 页面: {page}',"
+    },
+    {
+      "line": 331,
+      "text": "visionAnalysisSuccess: '✅ 视觉分析完成: {path}{page}, 文本长度: {textLen}, 图像数: {imgCount}, 布局: {layout}, 置信度: {confidence}%',"
+    },
+    {
+      "line": 332,
+      "text": "conversationHistoryNotFound: '对话历史不存在',"
+    },
+    {
+      "line": 333,
+      "text": "batchContextLengthErrorFallback: '小文件批次处理发生上下文长度错误,降级到逐条处理模式',"
+    },
+    {
+      "line": 334,
+      "text": "chunkProcessingFailed: '处理文本块 {index} 失败,已跳过: {message}',"
+    },
+    {
+      "line": 335,
+      "text": "singleTextProcessingComplete: '逐条文本处理完成: {count} 个切片',"
+    },
+    {
+      "line": 336,
+      "text": "fileVectorizationComplete: '文件 {id} 向量化完成。共处理 {count} 个文本块。最终内存: {memory}MB',"
+    },
+    {
+      "line": 337,
+      "text": "fileVectorizationFailed: '文件 {id} 向量化失败',"
+    },
+    {
+      "line": 338,
+      "text": "batchProcessingStarted: '开始批次处理: {count} 个项目',"
+    },
+    {
+      "line": 339,
+      "text": "batchProcessingProgress: '正在处理批次 {index}/{total}: {count} 个项目',"
+    },
+    {
+      "line": 340,
+      "text": "batchProcessingComplete: '批次处理完成: {count} 个项目,耗时 {duration}s',"
+    },
+    {
+      "line": 341,
+      "text": "onlyFailedFilesRetryable: '仅允许重试失败的文件 (当前状态: {status})',"
+    },
+    {
+      "line": 342,
+      "text": "emptyFileRetryFailed: '文件内容为空,无法重试。请重新上传文件。',"
+    },
+    {
+      "line": 343,
+      "text": "ragSystemPrompt: '您是专业的知识库助手。请根据以下提供的文档内容回答用户的问题。',"
+    },
+    {
+      "line": 344,
+      "text": "ragRules: '## 规则:\\n1. 仅根据提供的文档内容进行回答,请勿编造信息。\\n2. 如果文档中没有相关信息,请告知用户。\\n3. 请在回答中注明信息来源。格式:[文件名.扩展子]\\n4. 如果多个文档中的信息存在矛盾,请进行综合分析或解释不同的观点。\\n5. 请使用{lang}进行回答。',"
+    },
+    {
+      "line": 345,
+      "text": "ragDocumentContent: '## 文档内容:',"
+    },
+    {
+      "line": 346,
+      "text": "ragUserQuestion: '## 用户问题:',"
+    },
+    {
+      "line": 347,
+      "text": "ragAnswer: '## 回答:',"
+    },
+    {
+      "line": 348,
+      "text": "ragSource: '### 来源:{fileName}',"
+    },
+    {
+      "line": 349,
+      "text": "ragSegment: '片段 {index} (相似度: {score}):',"
+    },
+    {
+      "line": 350,
+      "text": "ragNoDocumentFound: '未找到相关文档。',"
+    },
+    {
+      "line": 351,
+      "text": "queryExpansionPrompt: '您是一个搜索助手。请为以下用户查询生成3个不同的演变版本,以帮助在向量搜索中获得更好的结果。每个版本应包含不同的关键词或表达方式,但保持原始意思。直接输出3行查询,不要有数字或编号:\\n\\n查询:{query}',"
+    },
+    {
+      "line": 352,
+      "text": "hydePrompt: '请为以下用户问题写一段简短、事实性的假设回答(约100字)。不要包含任何引导性文字(如“基于我的分析...”),直接输出答案内容。\\n\\n问题:{query}',"
+    },
+    {
+      "line": 355,
+      "text": "searching: 'ナレッジベースを検索中...',"
+    },
+    {
+      "line": 356,
+      "text": "noResults: '関連する知識が見つかりませんでした。一般的な知識に基づいて回答します...',"
+    },
+    {
+      "line": 357,
+      "text": "searchFailed: 'ナレッジベース検索に失敗しました。一般的な知識に基づいて回答します...',"
+    },
+    {
+      "line": 358,
+      "text": "generatingResponse: '回答を生成中',"
+    },
+    {
+      "line": 359,
+      "text": "files: '個のファイル',"
+    },
+    {
+      "line": 360,
+      "text": "notebooks: '個のノートブック',"
+    },
+    {
+      "line": 361,
+      "text": "all: 'すべて',"
+    },
+    {
+      "line": 362,
+      "text": "items: '件',"
+    },
+    {
+      "line": 363,
+      "text": "searchResults: '検索結果',"
+    },
+    {
+      "line": 364,
+      "text": "relevantInfoFound: '件の関連情報が見つかりました',"
+    },
+    {
+      "line": 365,
+      "text": "searchHits: '検索ヒット',"
+    },
+    {
+      "line": 366,
+      "text": "relevance: '関連度',"
+    },
+    {
+      "line": 367,
+      "text": "sourceFiles: '元ファイル',"
+    },
+    {
+      "line": 368,
+      "text": "searchScope: '検索範囲',"
+    },
+    {
+      "line": 369,
+      "text": "error: 'エラー',"
+    },
+    {
+      "line": 370,
+      "text": "creatingHistory: '新規対話履歴を作成: ',"
+    },
+    {
+      "line": 371,
+      "text": "searchingModelById: 'selectedEmbeddingId に基づいてモデルを検索: ',"
+    },
+    {
+      "line": 372,
+      "text": "searchModelFallback: '指定された埋め込みモデルが見つかりません。最初に使用可能なモデルを使用します。',"
+    },
+    {
+      "line": 373,
+      "text": "noEmbeddingModelFound: '埋め込みモデルの設定が見つかりません',"
+    },
+    {
+      "line": 374,
+      "text": "usingEmbeddingModel: '使用する埋め込みモデル: ',"
+    },
+    {
+      "line": 375,
+      "text": "startingSearch: 'ナレッジベースの検索を開始...',"
+    },
+    {
+      "line": 376,
+      "text": "searchResultsCount: '検索結果数: ',"
+    },
+    {
+      "line": 377,
+      "text": "searchFailedLog: '検索失敗',"
+    },
+    {
+      "line": 378,
+      "text": "chatStreamError: 'チャットストリームエラー',"
+    },
+    {
+      "line": 379,
+      "text": "assistStreamError: 'アシストストリームエラー',"
+    },
+    {
+      "line": 380,
+      "text": "file: 'ファイル',"
+    },
+    {
+      "line": 381,
+      "text": "content: '内容',"
+    },
+    {
+      "line": 382,
+      "text": "userLabel: 'ユーザー',"
+    },
+    {
+      "line": 383,
+      "text": "assistantLabel: 'アシスタント',"
+    },
+    {
+      "line": 384,
+      "text": "intelligentAssistant: 'あなたはインテリジェントな執筆アシスタントです。',"
+    },
+    {
+      "line": 385,
+      "text": "searchString: '検索文字列: ',"
+    },
+    {
+      "line": 386,
+      "text": "embeddingModelIdNotProvided: '埋め込みモデルIDが提供されていません',"
+    },
+    {
+      "line": 387,
+      "text": "generatingEmbeddings: '埋め込みベクトルを生成中...',"
+    },
+    {
+      "line": 388,
+      "text": "embeddingsGenerated: '埋め込みベクトルの生成が完了しました',"
+    },
+    {
+      "line": 389,
+      "text": "dimensions: '次元数',"
+    },
+    {
+      "line": 390,
+      "text": "performingHybridSearch: 'ES 混合検索を実行中...',"
+    },
+    {
+      "line": 391,
+      "text": "esSearchCompleted: 'ES 検索が完了しました',"
+    },
+    {
+      "line": 392,
+      "text": "resultsCount: '結果数',"
+    },
+    {
+      "line": 393,
+      "text": "hybridSearchFailed: '混合検索に失敗しました',"
+    },
+    {
+      "line": 394,
+      "text": "getContextForTopicFailed: 'トピックのコンテキスト取得に失敗しました',"
+    },
+    {
+      "line": 395,
+      "text": "noLLMConfigured: 'ユーザーにLLMモデルが設定されていません',"
+    },
+    {
+      "line": 396,
+      "text": "simpleChatGenerationError: '簡易チャット生成エラー',"
+    },
+    {
+      "line": 397,
+      "text": "noMatchInKnowledgeGroup: '選択された知識グループに関連する内容が見つかりませんでした。以下はモデルに基づく一般的な回答です:',"
+    },
+    {
+      "line": 398,
+      "text": "uploadTextSuccess: 'ノート内容を受け取りました。バックグラウンドでインデックス処理を実行中です',"
+    },
+    {
+      "line": 399,
+      "text": "passwordChanged: 'パスワードが正常に変更されました',"
+    },
+    {
+      "line": 400,
+      "text": "userCreated: 'ユーザーが正常に作成されました',"
+    },
+    {
+      "line": 401,
+      "text": "userInfoUpdated: 'ユーザー情報が更新されました',"
+    },
+    {
+      "line": 402,
+      "text": "userDeleted: 'ユーザーが削除されました',"
+    },
+    {
+      "line": 403,
+      "text": "pdfNoteTitle: 'PDF ノート - {date}',"
+    },
+    {
+      "line": 404,
+      "text": "noTextExtracted: 'テキストが抽出されませんでした',"
+    },
+    {
+      "line": 405,
+      "text": "kbCleared: 'ナレッジベースが空になりました',"
+    },
+    {
+      "line": 406,
+      "text": "fileDeleted: 'ファイルが削除されました',"
+    },
+    {
+      "line": 407,
+      "text": "pageImageNotFoundDetail: 'PDF の第 {page} ページの画像を取得できません',"
+    },
+    {
+      "line": 408,
+      "text": "groupSyncSuccess: 'ファイルグループが更新されました',"
+    },
+    {
+      "line": 409,
+      "text": "fileDeletedFromGroup: 'ファイルがグループから削除されました',"
+    },
+    {
+      "line": 410,
+      "text": "chunkConfigCorrection: 'チャンク設定の修正: {warnings}',"
+    },
+    {
+      "line": 411,
+      "text": "noChunksGenerated: 'ファイル {id} からテキストチャンクが生成されませんでした',"
+    },
+    {
+      "line": 412,
+      "text": "chunkCountAnomaly: '実際のチャンク数 {actual} が推定値 {estimated} を大幅に超えています。異常がある可能性があります',"
+    },
+    {
+      "line": 413,
+      "text": "batchSizeExceeded: 'バッチ {index} のサイズ {actual} が推奨値 {limit} を超えています。分割して処理します',"
+    },
+    {
+      "line": 414,
+      "text": "skippingEmptyVectorChunk: '空ベクトルのテキストブロック {index} をスキップします',"
+    },
+    {
+      "line": 415,
+      "text": "contextLengthErrorFallback: 'バッチ処理でコンテキスト長エラーが発生しました。単一テキスト処理モードにダウングレードします',"
+    },
+    {
+      "line": 416,
+      "text": "chunkLimitExceededForceBatch: 'チャンク数 {actual} がモデルのバッチ制限 {limit} を超えています。強制的にバッチ処理を行います',"
+    },
+    {
+      "line": 417,
+      "text": "noteContentRequired: 'ノート内容は必須です',"
+    },
+    {
+      "line": 418,
+      "text": "imageAnalysisStarted: 'モデル {id} で画像を分析中...',"
+    },
+    {
+      "line": 419,
+      "text": "batchAnalysisStarted: '{count} 枚の画像を分析中...',"
+    },
+    {
+      "line": 420,
+      "text": "pageAnalysisFailed: '第 {page} ページの分析に失敗しました',"
+    },
+    {
+      "line": 421,
+      "text": "visionSystemPrompt: 'あなたは専門的なドキュメント分析アシスタントです。このドキュメント画像を分析し、以下の要求に従って JSON 形式で返してください:\\n\\n1. すべての読み取り可能なテキストを抽出(読み取り順序に従い、段落と形式を保持)\\n2. 画像/グラフ/表の識別(内容、意味、役割を記述)\\n3. ページレイアウトの分析(テキストのみ/テキストと画像の混合/表/グラフなど)\\n4. 分析品質の評価(0-1)\\n\\nレスポンス形式:\\n{\\n  \"text\": \"完全なテキスト内容\",\\n  \"images\": [\\n    {\"type\": \"グラフの種類\", \"description\": \"詳細な記述\", \"position\": 1}\\n  ],\\n  \"layout\": \"レイアウトの説明\",\\n  \"confidence\": 0.95\\n}',"
+    },
+    {
+      "line": 422,
+      "text": "visionModelCall: '[モデル呼び出し] タイプ: Vision, モデル: {model}, ページ: {page}',"
+    },
+    {
+      "line": 423,
+      "text": "visionAnalysisSuccess: '✅ Vision 分析完了: {path}{page}, テキスト長: {textLen}文字, 画像数: {imgCount}, レイアウト: {layout}, 信頼度: {confidence}%',"
+    },
+    {
+      "line": 424,
+      "text": "conversationHistoryNotFound: '会話履歴が存在しません',"
+    },
+    {
+      "line": 425,
+      "text": "batchContextLengthErrorFallback: '小ファイルバッチ処理でコンテキスト長エラーが発生しました。単一テキスト処理モードにダウングレードします',"
+    },
+    {
+      "line": 426,
+      "text": "chunkProcessingFailed: 'テキストブロック {index} の処理に失敗しました。スキップします: {message}',"
+    },
+    {
+      "line": 427,
+      "text": "singleTextProcessingComplete: '単一テキスト処理完了: {count} チャンク',"
+    },
+    {
+      "line": 428,
+      "text": "fileVectorizationComplete: 'ファイル {id} ベクトル化完了。{count} 個のテキストブロックを処理しました。最終メモリ: {memory}MB',"
+    },
+    {
+      "line": 429,
+      "text": "fileVectorizationFailed: 'ファイル {id} ベクトル化失敗',"
+    },
+    {
+      "line": 430,
+      "text": "batchProcessingStarted: 'バッチ処理を開始します: {count} アイテム',"
+    },
+    {
+      "line": 431,
+      "text": "batchProcessingProgress: 'バッチ {index}/{total} を処理中: {count} 個のアイテム',"
+    },
+    {
+      "line": 432,
+      "text": "batchProcessingComplete: 'バッチ処理完了: {count} アイテム, 所要時間 {duration}s',"
+    },
+    {
+      "line": 433,
+      "text": "onlyFailedFilesRetryable: '失敗したファイルのみ再試行可能です (現在のステータス: {status})',"
+    },
+    {
+      "line": 434,
+      "text": "emptyFileRetryFailed: 'ファイル内容が空です。再試行できません。ファイルを再アップロードしてください。',"
+    },
+    {
+      "line": 435,
+      "text": "ragSystemPrompt: 'あなたは専門的なナレッジベースアシスタントです。以下の提供されたドキュメントの内容に基づいて、ユーザーの質問に答えてください。',"
+    },
+    {
+      "line": 436,
+      "text": "ragRules: '## ルール:\\n1. 提供されたドキュメントの内容のみに基づいて回答し、情報を捏造しないでください。\\n2. ドキュメントに関連情報がない場合は、その旨をユーザーに伝えてください。\\n3. 回答には情報源を明記してください。形式:[ファイル名.拡張子]\\n4. 複数のドキュメントで情報が矛盾している場合は、総合的に分析するか、異なる視点を説明してください。\\n5. {lang}で回答してください。',"
+    },
+    {
+      "line": 437,
+      "text": "ragDocumentContent: '## ドキュメント内容:',"
+    },
+    {
+      "line": 438,
+      "text": "ragUserQuestion: '## ユーザーの質問:',"
+    },
+    {
+      "line": 439,
+      "text": "ragAnswer: '## 回答:',"
+    },
+    {
+      "line": 440,
+      "text": "ragSource: '### ソース:{fileName}',"
+    },
+    {
+      "line": 441,
+      "text": "ragSegment: 'セグメント {index} (類似度: {score}):',"
+    },
+    {
+      "line": 442,
+      "text": "ragNoDocumentFound: '関連するドキュメントが見つかりませんでした。',"
+    },
+    {
+      "line": 443,
+      "text": "queryExpansionPrompt: 'あなたは検索アシスタントです。以下のユーザーのクエリに対して、ベクトル検索でより良い結果を得るために、3つの異なるバリエーションを生成してください。各バリエーションは異なるキーワードや表現を使用しつつ、元の意味を維持する必要があります。数字やプレフィックスなしで、3行のクエリを直接出力してください:\\n\\nクエリ:{query}',"
+    },
+    {
+      "line": 444,
+      "text": "hydePrompt: '以下のユーザーの質問に対して、簡潔で事実に基づいた仮説的な回答(約200文字)を書いてください。「私の分析によると...」などの導入文は含めず、回答内容のみを直接出力してください。\\n\\n質問:{query}',"
+    }
+  ],
+  "d:\\workspace\\AuraK\\server\\src\\knowledge-base\\chunk-config.service.ts": [
+    {
+      "line": 8,
+      "text": "* チャンク設定サービス"
+    },
+    {
+      "line": 9,
+      "text": "* チャンクパラメータの検証と管理を担当し、モデルの制限や環境変数の設定に適合していることを確認します"
+    },
+    {
+      "line": 11,
+      "text": "* 制限の優先順位:"
+    },
+    {
+      "line": 12,
+      "text": "* 1. 環境変数 (MAX_CHUNK_SIZE, MAX_OVERLAP_SIZE)"
+    },
+    {
+      "line": 13,
+      "text": "* 2. データベース内のモデル設定 (maxInputTokens, maxBatchSize)"
+    },
+    {
+      "line": 14,
+      "text": "* 3. デフォルト値"
+    },
+    {
+      "line": 31,
+      "text": "// デフォルト設定"
+    },
+    {
+      "line": 37,
+      "text": "maxOverlapRatio: DEFAULT_MAX_OVERLAP_RATIO,  // 重なりはチャンクサイズの50%まで"
+    },
+    {
+      "line": 38,
+      "text": "maxBatchSize: DEFAULT_MAX_BATCH_SIZE,    // デフォルトのバッチ制限"
+    },
+    {
+      "line": 39,
+      "text": "expectedDimensions: DEFAULT_VECTOR_DIMENSIONS, // デフォルトのベクトル次元"
+    },
+    {
+      "line": 42,
+      "text": "// 環境変数で設定された上限(優先的に使用)"
+    },
+    {
+      "line": 53,
+      "text": "// 環境変数からグローバルな上限設定を読み込む"
+    },
+    {
+      "line": 67,
+      "text": "* モデルの制限設定を取得(データベースから読み込み)"
+    },
+    {
+      "line": 82,
+      "text": "// データベースのフィールドから制限を取得し、デフォルト値で補完"
+    },
+    {
+      "line": 86,
+      "text": "const providerName = modelConfig.providerName || '不明';"
+    },
+    {
+      "line": 91,
+      "text": "`  - プロバイダー: ${providerName}\\n` +"
+    },
+    {
+      "line": 92,
+      "text": "`  - Token制限: ${maxInputTokens}\\n` +"
+    },
+    {
+      "line": 93,
+      "text": "`  - バッチ制限: ${maxBatchSize}\\n` +"
+    },
+    {
+      "line": 94,
+      "text": "`  - ベクトル次元: ${expectedDimensions}\\n` +"
+    },
+    {
+      "line": 95,
+      "text": "`  - ベクトルモデルか: ${isVectorModel}`,"
+    },
+    {
+      "line": 108,
+      "text": "* チャンク設定を検証および修正"
+    },
+    {
+      "line": 109,
+      "text": "* 優先順位: 環境変数の上限 > モデルの制限 > ユーザー設定"
+    },
+    {
+      "line": 127,
+      "text": "// 1. 最終的な上限を計算(環境変数とモデル制限の小さい方を選択)"
+    },
+    {
+      "line": 138,
+      "text": "// 2. チャンクサイズの上限を検証"
+    },
+    {
+      "line": 155,
+      "text": "// 3. チャンクサイズの下限を検証"
+    },
+    {
+      "line": 166,
+      "text": "// 4. 重なりサイズの上限を検証(環境変数優先)"
+    },
+    {
+      "line": 177,
+      "text": "// 5. 重なりサイズがチャンクサイズの50%を超えないことを検証"
+    },
+    {
+      "line": 201,
+      "text": "// 6. バッチ処理の安全チェックを追加"
+    },
+    {
+      "line": 202,
+      "text": "// バッチ処理時、複数のテキストの合計長がモデルの制限を超えないようにする必要があります"
+    },
+    {
+      "line": 203,
+      "text": "const safetyMargin = 0.8; // 80% 安全マージン、バッチ処理のためにスペースを確保"
+    },
+    {
+      "line": 216,
+      "text": "// 7. 推定チャンク数が妥当かチェック"
+    },
+    {
+      "line": 218,
+      "text": "1000000, // 1MB のテキストを想定"
+    },
+    {
+      "line": 238,
+      "text": "* 推奨されるバッチサイズを取得"
+    },
+    {
+      "line": 248,
+      "text": "// 設定値とモデル制限の小さい方を選択"
+    },
+    {
+      "line": 252,
+      "text": "200, // 安全のための上限"
+    },
+    {
+      "line": 265,
+      "text": "return Math.max(10, recommended); // 最低10個"
+    },
+    {
+      "line": 269,
+      "text": "* チャンク数を推定"
+    },
+    {
+      "line": 277,
+      "text": "* ベクトル次元の検証"
+    },
+    {
+      "line": 302,
+      "text": "* 設定概要を取得(ログ用)"
+    },
+    {
+      "line": 314,
+      "text": "`モデル: ${modelId}`,"
+    },
+    {
+      "line": 315,
+      "text": "`チャンクサイズ: ${chunkSize} tokens (制限: ${limits.maxInputTokens})`,"
+    },
+    {
+      "line": 316,
+      "text": "`重なりサイズ: ${chunkOverlap} tokens`,"
+    },
+    {
+      "line": 317,
+      "text": "`バッチサイズ: ${limits.maxBatchSize}`,"
+    },
+    {
+      "line": 318,
+      "text": "`ベクトル次元: ${limits.expectedDimensions}`,"
+    },
+    {
+      "line": 323,
+      "text": "* フロントエンド用の設定制限を取得"
+    },
+    {
+      "line": 324,
+      "text": "* フロントエンドのスライダーの上限設定に使用"
+    },
+    {
+      "line": 345,
+      "text": "// 最終的な上限を計算(環境変数とモデル制限の小さい方を選択)"
+    },
+    {
+      "line": 352,
+      "text": "// モデル設定名を取得"
+    },
+    {
+      "line": 356,
+      "text": "// テナントまたはユーザー設定からデフォルト値を取得"
+    }
+  ],
+  "d:\\workspace\\AuraK\\server\\src\\knowledge-base\\embedding.service.ts": [
+    {
+      "line": 46,
+      "text": "throw new Error(`埋め込みモデル設定 ${embeddingModelConfigId} が見つかりません`);"
+    },
+    {
+      "line": 50,
+      "text": "throw new Error(`モデル ${modelConfig.name} は無効化されているため、埋め込みベクトルを生成できません`);"
+    },
+    {
+      "line": 53,
+      "text": "// APIキーはオプションです - ローカルモデルを許可します"
+    },
+    {
+      "line": 56,
+      "text": "throw new Error(`モデル ${modelConfig.name} に baseUrl が設定されていません`);"
+    },
+    {
+      "line": 59,
+      "text": "// モデル名に基づいて最大バッチサイズを決定"
+    },
+    {
+      "line": 62,
+      "text": "// バッチサイズが制限を超える場合は分割して処理"
+    },
+    {
+      "line": 81,
+      "text": "// APIレート制限対策のため、短い間隔で待機"
+    },
+    {
+      "line": 83,
+      "text": "await new Promise(resolve => setTimeout(resolve, 100)); // 100ms待機"
+    },
+    {
+      "line": 89,
+      "text": "// 通常処理(バッチサイズ以内)"
+    },
+    {
+      "line": 100,
+      "text": "* モデルIDに基づいて最大バッチサイズを決定"
+    },
+    {
+      "line": 103,
+      "text": "// モデル固有のバッチサイズ制限"
+    },
+    {
+      "line": 106,
+      "text": "return Math.min(10, configuredMaxBatchSize || 100); // Googleの場合は10を上限"
+    },
+    {
+      "line": 108,
+      "text": "return Math.min(2048, configuredMaxBatchSize || 2048); // OpenAI v3は2048が上限"
+    },
+    {
+      "line": 110,
+      "text": "// デフォルトでは設定された最大バッチサイズか100の小さい方"
+    },
+    {
+      "line": 116,
+      "text": "* 単一バッチの埋め込み処理"
+    },
+    {
+      "line": 164,
+      "text": "// バッチサイズ制限エラーを検出"
+    },
+    {
+      "line": 171,
+      "text": "// バッチをさらに小さな単位に分割して再試行"
+    },
+    {
+      "line": 184,
+      "text": "// コンテキスト長の過剰エラーを検出"
+    },
+    {
+      "line": 190,
+      "text": "`総計 ${totalLength} 文字、平均 ${Math.round(avgLength)} 文字、` +"
+    },
+    {
+      "line": 191,
+      "text": "`モデル制限: ${modelConfig.maxInputTokens || 8192} tokens`"
+    },
+    {
+      "line": 194,
+      "text": "`テキスト長がモデルの制限を超えています。` +"
+    },
+    {
+      "line": 195,
+      "text": "`現在: ${texts.length} 個のテキストで計 ${totalLength} 文字、` +"
+    },
+    {
+      "line": 196,
+      "text": "`モデル制限: ${modelConfig.maxInputTokens || 8192} tokens。` +"
+    },
+    {
+      "line": 197,
+      "text": "`アドバイス: チャンクサイズまたはバッチサイズを小さくしてください`"
+    },
+    {
+      "line": 201,
+      "text": "// 429 (Too Many Requests) または 5xx (Server Error) の場合は再試行"
+    },
+    {
+      "line": 208,
+      "text": "this.logger.error(`リクエストパラメータ: model=${modelConfig.modelId}, inputLength=${texts[0]?.length}`);"
+    },
+    {
+      "line": 209,
+      "text": "throw new Error(`埋め込み API の呼び出しに失敗しました: ${response.statusText} - ${errorText}`);"
+    },
+    {
+      "line": 215,
+      "text": "// 実際のレスポンスから次元を取得"
+    },
+    {
+      "line": 225,
+      "text": "// 最後のアテンプトでなく、エラーが一時的と思われる場合(または堅牢性のために全て)は、待機後に再試行"
+    },
+    {
+      "line": 239,
+      "text": "// 使用环境变量的默认维度"
+    }
+  ],
+  "d:\\workspace\\AuraK\\server\\src\\knowledge-base\\knowledge-base.controller.ts": [
+    {
+      "line": 134,
+      "text": "* チャンク設定の制限を取得(フロントエンドのスライダー設定用)"
+    },
+    {
+      "line": 135,
+      "text": "* クエリパラメータ: embeddingModelId - 埋め込みモデルID"
+    },
+    {
+      "line": 165,
+      "text": "// 文件分组管理 - 需要管理员权限"
+    },
+    {
+      "line": 198,
+      "text": "// PDF プレビュー - 公開アクセス"
+    },
+    {
+      "line": 247,
+      "text": "fs.unlinkSync(pdfPath); // 空のファイルを削除"
+    },
+    {
+      "line": 266,
+      "text": "// PDF プレビューアドレスを取得"
+    },
+    {
+      "line": 274,
+      "text": "// PDF 変換をトリガー"
+    },
+    {
+      "line": 277,
+      "text": "// 一時的なアクセストークンを生成"
+    },
+    {
+      "line": 310,
+      "text": "// PDF の特定ページの画像を取得"
+    }
+  ],
+  "d:\\workspace\\AuraK\\server\\src\\knowledge-base\\knowledge-base.entity.ts": [
+    {
+      "line": 17,
+      "text": "EXTRACTED = 'extracted', // テキスト抽出が完了し、データベースに保存されました"
+    },
+    {
+      "line": 18,
+      "text": "VECTORIZED = 'vectorized', // ベクトル化が完了し、ES にインデックスされました"
+    },
+    {
+      "line": 23,
+      "text": "FAST = 'fast',      // 高速モード - Tika を使用"
+    },
+    {
+      "line": 24,
+      "text": "PRECISE = 'precise', // 精密モード - Vision Pipeline を使用"
+    },
+    {
+      "line": 54,
+      "text": "@Column({ name: 'user_id', nullable: true }) // 暫定的に空を許可(デバッグ用)、将来的には必須にすべき"
+    },
+    {
+      "line": 65,
+      "text": "content: string; // Tika で抽出されたテキスト内容を保存"
+    },
+    {
+      "line": 67,
+      "text": "// インデックス設定パラメータ"
+    },
+    {
+      "line": 86,
+      "text": "metadata: any; // 追加のメタデータを保存(画像の説明、信頼度など)"
+    },
+    {
+      "line": 89,
+      "text": "pdfPath: string; // PDF ファイルパス(プレビュー用)"
+    }
+  ],
+  "d:\\workspace\\AuraK\\server\\src\\knowledge-base\\knowledge-base.service.ts": [
+    {
+      "line": 86,
+      "text": "// 分類(グループ)の関連付け"
+    },
+    {
+      "line": 235,
+      "text": "// 環境変数のデフォルト次元数を使用してシミュレーションベクトルを生成"
+    },
+    {
+      "line": 333,
+      "text": "// エラーをスローするのではなく空の結果を返し、システムの稼働を継続させる"
+    },
+    {
+      "line": 337,
+      "text": "ragPrompt: query, // オリジナルのクエリを使用"
+    },
+    {
+      "line": 432,
+      "text": "// メモリ監視 - 処理前チェック"
+    },
+    {
+      "line": 436,
+      "text": "// モードに基づいて処理フローを選択"
+    },
+    {
+      "line": 440,
+      "text": "// 精密モード - Vision Pipeline を使用"
+    },
+    {
+      "line": 443,
+      "text": "// 高速モード - Tika を使用"
+    },
+    {
+      "line": 455,
+      "text": "* 高速モード処理(既存フロー)"
+    },
+    {
+      "line": 458,
+      "text": "// 1. Tika を使用してテキストを抽出"
+    },
+    {
+      "line": 461,
+      "text": "// 画像ファイルの場合はビジョンモデルを使用"
+    },
+    {
+      "line": 484,
+      "text": "// テキストサイズを確認"
+    },
+    {
+      "line": 490,
+      "text": "// テキストをデータベースに保存"
+    },
+    {
+      "line": 494,
+      "text": "// 非同期ベクトル化"
+    },
+    {
+      "line": 499,
+      "text": "// 自動タイトル生成 (非同期的に実行)"
+    },
+    {
+      "line": 504,
+      "text": "// 非同期的に PDF 変換をトリガー(ドキュメントファイルの場合)"
+    },
+    {
+      "line": 511,
+      "text": "* 精密モード処理(新規フロー)"
+    },
+    {
+      "line": 514,
+      "text": "// 精密モードがサポートされているか確認"
+    },
+    {
+      "line": 525,
+      "text": "// Vision モデルが設定されているか確認"
+    },
+    {
+      "line": 546,
+      "text": "// Vision Pipeline を呼び出し"
+    },
+    {
+      "line": 566,
+      "text": "// テキスト内容をデータベースに保存"
+    },
+    {
+      "line": 590,
+      "text": "// 非同期でベクトル化し、Elasticsearch にインデックス"
+    },
+    {
+      "line": 591,
+      "text": "// 各ページを独立したドキュメントとして作成し、メタデータを保持"
+    },
+    {
+      "line": 596,
+      "text": "// 非同期で PDF 変換をトリガー"
+    },
+    {
+      "line": 601,
+      "text": "// 自動タイトル生成 (非同期的に実行)"
+    },
+    {
+      "line": 613,
+      "text": "* 精密モードの結果をインデックス"
+    },
+    {
+      "line": 624,
+      "text": "// インデックスの存在を確認 - 実際のモデル次元数を取得"
+    },
+    {
+      "line": 628,
+      "text": "// ベクトル化とインデックスをバッチ処理"
+    },
+    {
+      "line": 636,
+      "text": "// ベクトルを生成"
+    },
+    {
+      "line": 643,
+      "text": "// 各結果をインデックス"
+    },
+    {
+      "line": 684,
+      "text": "* PDF の特定ページの画像を取得"
+    },
+    {
+      "line": 689,
+      "text": "// 特定のページを変換"
+    },
+    {
+      "line": 696,
+      "text": "// 対応するページ番号の画像を見つける"
+    },
+    {
+      "line": 716,
+      "text": "// メモリ監視 - ベクトル化前チェック"
+    },
+    {
+      "line": 723,
+      "text": "// 1. チャンク設定の検証と修正(モデルの制限と環境変数に基づく)"
+    },
+    {
+      "line": 732,
+      "text": "// 設定が修正された場合、警告を記録しデータベースを更新"
+    },
+    {
+      "line": 738,
+      "text": "// データベース内の設定を更新"
+    },
+    {
+      "line": 748,
+      "text": "// 設定サマリーを表示(実際に適用される上限を含む)"
+    },
+    {
+      "line": 759,
+      "text": "// 2. 検証済みの設定を使用してチャンク分割"
+    },
+    {
+      "line": 773,
+      "text": "// 3. チャンク数が妥当か確認"
+    },
+    {
+      "line": 784,
+      "text": "// 4. 推奨バッチサイズを取得(モデルの制限に基づく)"
+    },
+    {
+      "line": 792,
+      "text": "// 5. メモリ使用量を推定"
+    },
+    {
+      "line": 801,
+      "text": "// 6. 実際のモデル次元数を取得し、インデックスの存在を確認"
+    },
+    {
+      "line": 805,
+      "text": "// 7. ベクトル化とインデックス作成をバッチ処理"
+    },
+    {
+      "line": 817,
+      "text": "// バッチサイズがモデルの制限を超えていないか検証"
+    },
+    {
+      "line": 831,
+      "text": "// 次元の整合性を検証"
+    },
+    {
+      "line": 838,
+      "text": "// このバッチデータを即座にインデックス"
+    },
+    {
+      "line": 877,
+      "text": "// コンテキスト長エラーを検出(日本語・中国語・英語に対応)"
+    },
+    {
+      "line": 878,
+      "text": "if (error.message && (error.message.includes('context length') || error.message.includes('コンテキスト長が上限を超えています') || error.message.includes('コンテキスト長が上限を超えています'))) {"
+    },
+    {
+      "line": 881,
+      "text": "// 単一テキスト処理にダウングレード"
+    },
+    {
+      "line": 887,
+      "text": "[chunk.content], // 単一テキスト"
+    },
+    {
+      "line": 926,
+      "text": "// その他のエラーは直接スロー"
+    },
+    {
+      "line": 931,
+      "text": "// 小さなファイル、一括処理(ただしバッチ制限の確認が必要)"
+    },
+    {
+      "line": 934,
+      "text": "// チャンク数がモデルのバッチ制限を超える場合は、強制的にバッチ処理"
+    },
+    {
+      "line": 978,
+      "text": "// コンテキスト長エラーを検出(日本語・中国語・英語に対応)"
+    },
+    {
+      "line": 979,
+      "text": "if (error.message && (error.message.includes('context length') || error.message.includes('コンテキスト長が上限を超えています') || error.message.includes('コンテキスト長が上限を超えています'))) {"
+    },
+    {
+      "line": 982,
+      "text": "// 単一テキスト処理にダウングレード"
+    },
+    {
+      "line": 988,
+      "text": "[chunk.content], // 単一テキスト"
+    },
+    {
+      "line": 1027,
+      "text": "// その他のエラー、直接スロー"
+    },
+    {
+      "line": 1032,
+      "text": "// 十分に小さいファイルの場合は一括で処理"
+    },
+    {
+      "line": 1066,
+      "text": "// コンテキスト長エラーを検出(日本語・中国語・英語に対応)"
+    },
+    {
+      "line": 1067,
+      "text": "if (error.message && (error.message.includes('context length') || error.message.includes('コンテキスト長が上限を超えています') || error.message.includes('コンテキスト長が上限を超えています'))) {"
+    },
+    {
+      "line": 1070,
+      "text": "// 単一テキスト処理にダウングレード"
+    },
+    {
+      "line": 1076,
+      "text": "[chunk.content], // 単一テキスト"
+    },
+    {
+      "line": 1115,
+      "text": "// その他のエラー、直接スロー"
+    },
+    {
+      "line": 1130,
+      "text": "// エラー情報を metadata に保存"
+    },
+    {
+      "line": 1148,
+      "text": "* バッチ処理、メモリ制御付き"
+    },
+    {
+      "line": 1169,
+      "text": "// メモリを確認し待機"
+    },
+    {
+      "line": 1172,
+      "text": "// バッチサイズを動的に調整 (initialBatchSize から開始し、必要に応じてメモリモニターが削減できるようにします)"
+    },
+    {
+      "line": 1173,
+      "text": "// 注意: memoryMonitor.getDynamicBatchSize はメモリ状況に基づいてより大きな値を返す可能性がありますが、"
+    },
+    {
+      "line": 1174,
+      "text": "// モデルの制限 (initialBatchSize) を尊重する必要があります。"
+    },
+    {
+      "line": 1181,
+      "text": "// 現在のバッチを取得"
+    },
+    {
+      "line": 1189,
+      "text": "// バッチを処理"
+    },
+    {
+      "line": 1192,
+      "text": "// コールバック通知"
+    },
+    {
+      "line": 1197,
+      "text": "// 強制GC(メモリがしきい値に近い場合)"
+    },
+    {
+      "line": 1202,
+      "text": "// 参照をクリアしGCを助ける"
+    },
+    {
+      "line": 1213,
+      "text": "* 失敗したファイルのベクトル化を再試行"
+    },
+    {
+      "line": 1224,
+      "text": "throw new NotFoundException('ファイルが存在しません');"
+    },
+    {
+      "line": 1235,
+      "text": "// 2. ステータスを INDEXING にリセット"
+    },
+    {
+      "line": 1238,
+      "text": "// 3. 非同期でベクトル化をトリガー(既存ロジックを再利用)"
+    },
+    {
+      "line": 1253,
+      "text": "// 4. 更新後のファイルステータスを返却"
+    },
+    {
+      "line": 1256,
+      "text": "throw new NotFoundException('ファイルが存在しません');"
+    },
+    {
+      "line": 1262,
+      "text": "* ファイルのすべてのチャンク情報を取得"
+    },
+    {
+      "line": 1273,
+      "text": "throw new NotFoundException('ファイルが存在しません');"
+    },
+    {
+      "line": 1276,
+      "text": "// 2. Elasticsearch からすべてのチャンクを取得"
+    },
+    {
+      "line": 1279,
+      "text": "// 3. チャンク情報を返却"
+    },
+    {
+      "line": 1300,
+      "text": "// PDF プレビュー関連メソッド"
+    },
+    {
+      "line": 1310,
+      "text": "// 元ファイルが PDF の場合は、元ファイルのパスを直接返す"
+    },
+    {
+      "line": 1315,
+      "text": "// プレビュー変換に対応しているか確認(ドキュメント類または画像類のみ許可)"
+    },
+    {
+      "line": 1324,
+      "text": "// PDF フィールドパスを生成"
+    },
+    {
+      "line": 1331,
+      "text": "// 強制再生成が指定され、ファイルが存在する場合は削除"
+    },
+    {
+      "line": 1341,
+      "text": "// 変換済みかつ強制再生成が不要か確認"
+    },
+    {
+      "line": 1349,
+      "text": "// PDF への変換が必要"
+    },
+    {
+      "line": 1353,
+      "text": "// ファイルを変換"
+    },
+    {
+      "line": 1356,
+      "text": "// 変換結果を確認"
+    },
+    {
+      "line": 1386,
+      "text": "// 元ファイルが PDF の場合"
+    },
+    {
+      "line": 1395,
+      "text": "// PDF ファイルパスを生成"
+    },
+    {
+      "line": 1402,
+      "text": "// 変換済みか確認"
+    },
+    {
+      "line": 1415,
+      "text": "// 変換が必要"
+    },
+    {
+      "line": 1437,
+      "text": "* モデルの実際の次元数を取得(キャッシュ確認とプローブロジック付き)"
+    },
+    {
+      "line": 1445,
+      "text": "// 1. モデル設定から優先的に取得"
+    },
+    {
+      "line": 1457,
+      "text": "// 2. それ以外の場合はプローブにより取得"
+    },
+    {
+      "line": 1469,
+      "text": "// 次回利用のためにモデル設定を更新"
+    },
+    {
+      "line": 1494,
+      "text": "* AIを使用して文書のタイトルを自動生成する"
+    },
+    {
+      "line": 1506,
+      "text": "// すでにタイトルがある場合はスキップ"
+    },
+    {
+      "line": 1511,
+      "text": "// コンテンツの冒頭サンプルを取得(最大2500文字)"
+    },
+    {
+      "line": 1514,
+      "text": "// ユーザー設定から言語を取得、またはデフォルトを使用"
+    },
+    {
+      "line": 1518,
+      "text": "// プロンプトを構築"
+    },
+    {
+      "line": 1521,
+      "text": "// LLMを呼び出してタイトルを生成"
+    },
+    {
+      "line": 1535,
+      "text": "// 余分な引用符や改行を除去"
+    },
+    {
+      "line": 1539,
+      "text": "// Elasticsearch のチャンクも更新"
+    }
+  ],
+  "d:\\workspace\\AuraK\\server\\src\\knowledge-base\\memory-monitor.service.ts": [
+    {
+      "line": 4,
+      "text": "heapUsed: number;    // 使用済みヒープメモリ (MB)"
+    },
+    {
+      "line": 5,
+      "text": "heapTotal: number;   // 総ヒープメモリ (MB)"
+    },
+    {
+      "line": 6,
+      "text": "external: number;    // 外部メモリ (MB)"
+    },
+    {
+      "line": 7,
+      "text": "rss: number;         // RSS (常駐セットサイズ) (MB)"
+    },
+    {
+      "line": 19,
+      "text": "// 環境変数から設定を読み込む。デフォルト値はメモリ最適化用"
+    },
+    {
+      "line": 20,
+      "text": "this.MAX_MEMORY_MB = parseInt(process.env.MAX_MEMORY_USAGE_MB || '1024'); // 1GB上限"
+    },
+    {
+      "line": 21,
+      "text": "this.BATCH_SIZE = parseInt(process.env.CHUNK_BATCH_SIZE || '100'); // 1バッチあたり100チャンク"
+    },
+    {
+      "line": 22,
+      "text": "this.GC_THRESHOLD_MB = parseInt(process.env.GC_THRESHOLD_MB || '800'); // 800MBでGCをトリガー"
+    },
+    {
+      "line": 28,
+      "text": "* 現在のメモリ使用状況を取得"
+    },
+    {
+      "line": 42,
+      "text": "* メモリが上限に近づいているかチェック"
+    },
+    {
+      "line": 46,
+      "text": "return usage.heapUsed > this.MAX_MEMORY_MB * 0.85; // 85%閾値"
+    },
+    {
+      "line": 50,
+      "text": "* メモリが利用可能になるまで待機(タイムアウトあり)"
+    },
+    {
+      "line": 57,
+      "text": "throw new Error(`メモリ待機がタイムアウトしました: 現在 ${this.getMemoryUsage().heapUsed}MB > ${this.MAX_MEMORY_MB * 0.85}MB`);"
+    },
+    {
+      "line": 64,
+      "text": "// ガベージコレクションを強制実行(可能な場合)"
+    },
+    {
+      "line": 75,
+      "text": "* ガベージコレクションを強制実行(可能な場合)"
+    },
+    {
+      "line": 89,
+      "text": "* バッチサイズを動的に調整"
+    },
+    {
+      "line": 95,
+      "text": "// メモリ逼迫、バッチサイズを削減"
+    },
+    {
+      "line": 102,
+      "text": "// メモリに余裕あり、バッチサイズを増量"
+    },
+    {
+      "line": 116,
+      "text": "* 大規模データの処理:自動バッチングとメモリ制御"
+    },
+    {
+      "line": 136,
+      "text": "// メモリ状態をチェックして待機"
+    },
+    {
+      "line": 139,
+      "text": "// バッチサイズを動的に調整"
+    },
+    {
+      "line": 143,
+      "text": "// 現在のバッチを取得"
+    },
+    {
+      "line": 152,
+      "text": "// バッチを処理"
+    },
+    {
+      "line": 157,
+      "text": "// コールバック通知"
+    },
+    {
+      "line": 162,
+      "text": "// メモリが閾値に近い場合はGCを強制実行"
+    },
+    {
+      "line": 167,
+      "text": "// GCを助けるために参照をクリア"
+    },
+    {
+      "line": 183,
+      "text": "* 処理に必要なメモリを見積もる"
+    },
+    {
+      "line": 186,
+      "text": "// テキスト内容のメモリ"
+    },
+    {
+      "line": 189,
+      "text": "// ベクトルメモリ (各ベクトル: 次元 × 4バイト)"
+    },
+    {
+      "line": 192,
+      "text": "// オブジェクトのオーバーヘッド (各オブジェクトにつき追加で約100バイトと推定)"
+    },
+    {
+      "line": 201,
+      "text": "* バッチ処理を使用すべきかチェック"
+    },
+    {
+      "line": 205,
+      "text": "const threshold = this.MAX_MEMORY_MB * 0.7; // 70%閾値"
+    },
+    {
+      "line": 218,
+      "text": "* 推奨されるバッチサイズを取得"
+    },
+    {
+      "line": 221,
+      "text": "// 目標:1バッチあたり最大 200MB メモリ"
+    },
+    {
+      "line": 225,
+      "text": "// 1項目あたりのメモリ = テキスト + ベクトル + オーバーヘッド"
+    },
+    {
+      "line": 230,
+      "text": "// 限制在 10-200 之间"
+    }
+  ],
+  "d:\\workspace\\AuraK\\server\\src\\knowledge-base\\text-chunker.service.ts": [
+    {
+      "line": 25,
+      "text": "// テキスト長がチャンクサイズ以下の場合は、テキスト全体を1つのチャンクとして直接返す"
+    },
+    {
+      "line": 44,
+      "text": "// 文の境界で分割"
+    },
+    {
+      "line": 72,
+      "text": "// 次のチャンクの開始位置を計算"
+    }
+  ],
+  "d:\\workspace\\AuraK\\server\\src\\libreoffice\\libreoffice.interface.ts": [
+    {
+      "line": 2,
+      "text": "* LibreOffice サービスインターフェース定義"
+    },
+    {
+      "line": 7,
+      "text": "pdf_data?: string; // base64 エンコードされた PDF データ"
+    }
+  ],
+  "d:\\workspace\\AuraK\\server\\src\\libreoffice\\libreoffice.service.ts": [
+    {
+      "line": 26,
+      "text": "* LibreOffice サービスの状態をチェック"
+    },
+    {
+      "line": 42,
+      "text": "* ドキュメントを PDF に変換"
+    },
+    {
+      "line": 43,
+      "text": "* @param filePath 変換するファイルのパス"
+    },
+    {
+      "line": 44,
+      "text": "* @returns PDF ファイルのパス"
+    },
+    {
+      "line": 50,
+      "text": "// PDF の場合は元のパスを直接返す"
+    },
+    {
+      "line": 56,
+      "text": "// ファイルの存在確認"
+    },
+    {
+      "line": 60,
+      "text": "throw new Error(`ファイルが存在しません: ${filePath}`);"
+    },
+    {
+      "line": 63,
+      "text": "// 出力先 PDF のパスを生成"
+    },
+    {
+      "line": 68,
+      "text": "// PDF が既に存在する場合は直接返す"
+    },
+    {
+      "line": 74,
+      "text": "// PDF が存在しないため、変換が必要"
+    },
+    {
+      "line": 77,
+      "text": "// ファイルの読み込み"
+    },
+    {
+      "line": 80,
+      "text": "// FormData の構築"
+    },
+    {
+      "line": 86,
+      "text": "// 変換の再試行回数"
+    },
+    {
+      "line": 92,
+      "text": "// LibreOffice サービスの呼び出し"
+    },
+    {
+      "line": 98,
+      "text": "timeout: 300000, // 5分タイムアウト"
+    },
+    {
+      "line": 99,
+      "text": "responseType: 'stream', // ファイルストリームを受信"
+    },
+    {
+      "line": 100,
+      "text": "maxRedirects: 5, // リダイレクトの最大数"
+    },
+    {
+      "line": 104,
+      "text": "// ストリームを出力ファイルに書き込む"
+    },
+    {
+      "line": 123,
+      "text": "// socket hang up や接続エラーの場合は少し待機して再試行"
+    },
+    {
+      "line": 126,
+      "text": "const delay = 2000 * attempt; // だんだん増える遅延"
+    },
+    {
+      "line": 131,
+      "text": "// その他のエラーは再試行しない"
+    },
+    {
+      "line": 137,
+      "text": "// 全ての再試行が失敗した場合、詳細なエラーハンドリングを行う"
+    },
+    {
+      "line": 157,
+      "text": "throw new Error('変換がタイムアウトしました。ファイルが大きすぎる可能性があります');"
+    },
+    {
+      "line": 159,
+      "text": "throw new Error(`変換に失敗しました: ${detail}`);"
+    },
+    {
+      "line": 163,
+      "text": "throw new Error(`変換に失敗しました: ${lastError.message}`);"
+    },
+    {
+      "line": 169,
+      "text": "throw new Error('LibreOffice サービスが実行されていません。サービスの状態を確認してください');"
+    },
+    {
+      "line": 172,
+      "text": "throw new Error('LibreOffice サービスとの接続が切断されました。サービスが不安定である可能性があります');"
+    },
+    {
+      "line": 174,
+      "text": "throw new Error(`変換に失敗しました: ${lastError.message}`);"
+    },
+    {
+      "line": 178,
+      "text": "* ファイルの一括変換"
+    },
+    {
+      "line": 195,
+      "text": "* サービスのバージョン情報を取得"
+    }
+  ],
+  "d:\\workspace\\AuraK\\server\\src\\migrations\\1737800000000-AddKnowledgeBaseEnhancements.ts": [
+    {
+      "line": 7,
+      "text": "// 知識ベースグループテーブルの作成"
+    },
+    {
+      "line": 20,
+      "text": "// ドキュメントグループ関連テーブルの作成"
+    },
+    {
+      "line": 32,
+      "text": "// 検索履歴テーブルの作成"
+    },
+    {
+      "line": 44,
+      "text": "// 会話メッセージテーブルの作成"
+    },
+    {
+      "line": 57,
+      "text": "// knowledge_base テーブルに pdf_path フィールドを追加"
+    },
+    {
+      "line": 62,
+      "text": "// インデックスの作成"
+    },
+    {
+      "line": 69,
+      "text": "// インデックスの削除"
+    },
+    {
+      "line": 74,
+      "text": "// pdf_path フィールドの削除"
+    },
+    {
+      "line": 77,
+      "text": "// テーブルの削除"
+    }
+  ],
+  "d:\\workspace\\AuraK\\server\\src\\model-config\\dto\\create-model-config.dto.ts": [
+    {
+      "line": 31,
+      "text": "apiKey?: string; // APIキーはオプションです - ローカルモデルを許可します"
+    },
+    {
+      "line": 38,
+      "text": "@Min(1, { message: 'ベクトル次元の最小値は 1 です' })"
+    },
+    {
+      "line": 39,
+      "text": "@Max(4096, { message: 'ベクトル次元の最大値は 4096 です(Elasticsearch の制限)' })"
+    },
+    {
+      "line": 43,
+      "text": "// ==================== 追加フィールド ===================="
+    },
+    {
+      "line": 46,
+      "text": "* モデルの入力トークン制限(embedding/rerank にのみ有効)"
+    },
+    {
+      "line": 55,
+      "text": "* バッチ処理の制限(embedding/rerank にのみ有効)"
+    },
+    {
+      "line": 64,
+      "text": "* ベトルモデルかどうか"
+    },
+    {
+      "line": 71,
+      "text": "* モデルプロバイダー名"
+    },
+    {
+      "line": 78,
+      "text": "* このモデルを有効にするかどうか"
+    },
+    {
+      "line": 85,
+      "text": "* このモデルをデフォルトとして使用するかどうか"
+    }
+  ],
+  "d:\\workspace\\AuraK\\server\\src\\model-config\\model-config.entity.ts": [
+    {
+      "line": 34,
+      "text": "dimensions?: number; // 埋め込みモデルの次元、システムによって自動的に検出され保存されます"
+    },
+    {
+      "line": 36,
+      "text": "// ==================== 追加フィールド ===================="
+    },
+    {
+      "line": 37,
+      "text": "// 以下字段仅对 embedding/rerank 模型有意义"
+    },
+    {
+      "line": 40,
+      "text": "* モデルの入力トークン制限"
+    },
+    {
+      "line": 41,
+      "text": "* 例: OpenAI=8191, Gemini=2048"
+    },
+    {
+      "line": 47,
+      "text": "* 一括処理制限(1回のリクエストあたりの最大入力数)"
+    },
+    {
+      "line": 48,
+      "text": "* 例: OpenAI=2048, Gemini=100"
+    },
+    {
+      "line": 54,
+      "text": "* ベトルモデルかどうか(システム設定での識別用)"
+    },
+    {
+      "line": 60,
+      "text": "* このモデルを有効にするかどうか"
+    },
+    {
+      "line": 61,
+      "text": "* ユーザーは使用しないモデルを無効にして、誤選択を防ぐことができます"
+    },
+    {
+      "line": 67,
+      "text": "* このモデルをデフォルトとして使用するかどうか"
+    },
+    {
+      "line": 68,
+      "text": "* 各タイプ(llm, embedding, rerank)ごとに1つのみデフォルトにできます"
+    },
+    {
+      "line": 74,
+      "text": "* モデルプロバイダー名(表示および識別用)"
+    },
+    {
+      "line": 75,
+      "text": "* 例: \"OpenAI\", \"Google Gemini\", \"Custom\""
+    },
+    {
+      "line": 80,
+      "text": "// ==================== 既存のフィールド ===================="
+    }
+  ],
+  "d:\\workspace\\AuraK\\server\\src\\model-config\\model-config.service.ts": [
+    {
+      "line": 109,
+      "text": "* 指定されたモデルをデフォルトに設定"
+    },
+    {
+      "line": 114,
+      "text": "// 同じタイプの他のモデルのデフォルトフラグをクリア (現在のテナント内またはglobal)"
+    },
+    {
+      "line": 115,
+      "text": "// 厳密には、現在のテナントのIsDefault設定といった方が正しいですが、シンプルにするため全体のIsDefaultを操作します"
+    },
+    {
+      "line": 132,
+      "text": "* 指定されたタイプのデフォルトモデルを取得"
+    },
+    {
+      "line": 133,
+      "text": "* 厳密なルール:Index Chat Configで指定されたモデルのみを返し、なければエラーを投げる"
+    }
+  ],
+  "d:\\workspace\\AuraK\\server\\src\\pdf2image\\pdf2image.interface.ts": [
+    {
+      "line": 2,
+      "text": "* PDF 转图片接口定义"
+    },
+    {
+      "line": 6,
+      "text": "density?: number;        // DPI 分辨率,默认 300"
+    },
+    {
+      "line": 7,
+      "text": "quality?: number;        // JPEG 质量 (1-100),默认 85"
+    },
+    {
+      "line": 8,
+      "text": "format?: 'jpeg' | 'png'; // 输出格式,默认 jpeg"
+    },
+    {
+      "line": 9,
+      "text": "outDir?: string;         // 输出目录,默认 ./temp"
+    },
+    {
+      "line": 13,
+      "text": "path: string;            // 图片文件路径"
+    },
+    {
+      "line": 14,
+      "text": "pageIndex: number;       // 页码(从 1 开始)"
+    },
+    {
+      "line": 15,
+      "text": "size: number;            // 文件大小(字节)"
+    },
+    {
+      "line": 16,
+      "text": "width?: number;          // 图片宽度"
+    },
+    {
+      "line": 17,
+      "text": "height?: number;         // 图片高度"
+    }
+  ],
+  "d:\\workspace\\AuraK\\server\\src\\pdf2image\\pdf2image.service.ts": [
+    {
+      "line": 22,
+      "text": "* PDF を画像リストに変換します"
+    },
+    {
+      "line": 23,
+      "text": "* ImageMagick の convert コマンドを使用します"
+    },
+    {
+      "line": 36,
+      "text": "// PDF ファイルの検証"
+    },
+    {
+      "line": 40,
+      "text": "throw new Error(`PDF ファイルが存在しません: ${pdfPath}`);"
+    },
+    {
+      "line": 43,
+      "text": "// 出力ディレクトリの作成"
+    },
+    {
+      "line": 52,
+      "text": "// PDF の総ページ数を取得 - pdfinfo の代わりに pdf-lib を使用"
+    },
+    {
+      "line": 58,
+      "text": "throw new Error('PDF のページ数を取得できません');"
+    },
+    {
+      "line": 65,
+      "text": "// Python スクリプトを使用して変換"
+    },
+    {
+      "line": 75,
+      "text": "throw new Error(`Python での変換に失敗しました: ${result.error}`);"
+    },
+    {
+      "line": 93,
+      "text": "// 一時ディレクトリのクリーンアップ"
+    },
+    {
+      "line": 95,
+      "text": "throw new Error(`PDF から画像への変換に失敗しました: ${error.message}`);"
+    },
+    {
+      "line": 100,
+      "text": "* 複数の PDF を一括変換"
+    },
+    {
+      "line": 117,
+      "text": "* 画像ファイルのクリーンアップ"
+    },
+    {
+      "line": 129,
+      "text": "// 空のディレクトリのクリーンアップを試行"
+    },
+    {
+      "line": 137,
+      "text": "* ディレクトリのクリーンアップ"
+    },
+    {
+      "line": 152,
+      "text": "* 画像品質が妥当か確認"
+    }
+  ],
+  "d:\\workspace\\AuraK\\server\\src\\rag\\rag.service.ts": [
+    {
+      "line": 18,
+      "text": "originalScore?: number; // Rerank前のスコア(デバッグ用)"
+    },
+    {
+      "line": 49,
+      "text": "vectorSimilarityThreshold: number = 0.3, // ベクトル検索のしきい値"
+    },
+    {
+      "line": 56,
+      "text": "rerankSimilarityThreshold: number = 0.5, // Rerankのしきい値(デフォルト0.5)"
+    },
+    {
+      "line": 61,
+      "text": "// 1. グローバル設定の取得"
+    },
+    {
+      "line": 64,
+      "text": "// パラメータが明示的に渡されていない場合はグローバル設定を使用"
+    },
+    {
+      "line": 81,
+      "text": "// 1. クエリの準備(拡張または HyDE)"
+    },
+    {
+      "line": 86,
+      "text": "queriesToSearch = [hydeDoc]; // HyDE の場合は仮想ドキュメントをクエリとして使用"
+    },
+    {
+      "line": 92,
+      "text": "// 埋め込みモデルIDが提供されているか確認"
+    },
+    {
+      "line": 94,
+      "text": "throw new Error('埋め込みモデルIDが提供されていません');"
+    },
+    {
+      "line": 97,
+      "text": "// 2. 複数のクエリに対して並列検索"
+    },
+    {
+      "line": 99,
+      "text": "// クエリベクトルの取得"
+    },
+    {
+      "line": 107,
+      "text": "// 設定に基づいた検索戦略の選択"
+    },
+    {
+      "line": 139,
+      "text": "// 初回の類似度フィルタリング"
+    },
+    {
+      "line": 142,
+      "text": "// ログ出力"
+    },
+    {
+      "line": 147,
+      "text": "// 閾値フィルタリングを適用"
+    },
+    {
+      "line": 151,
+      "text": "// 3. リランク (Rerank)"
+    },
+    {
+      "line": 162,
+      "text": "effectiveTopK * 2 // 少し多めに残す"
+    },
+    {
+      "line": 169,
+      "text": "score: r.score, // Rerank スコア"
+    },
+    {
+      "line": 170,
+      "text": "originalScore: originalItem.score // 元のスコア"
+    },
+    {
+      "line": 174,
+      "text": "// Rerank後のフィルタリング"
+    },
+    {
+      "line": 181,
+      "text": "// 失敗した場合はベクトル検索の結果をそのまま使う"
+    },
+    {
+      "line": 185,
+      "text": "// 最終的な件数制限"
+    },
+    {
+      "line": 188,
+      "text": "// 4. RAG 結果形式に変換"
+    },
+    {
+      "line": 213,
+      "text": "// コンテキストの構築"
+    },
+    {
+      "line": 218,
+      "text": "// ファイルごとにグループ化"
+    },
+    {
+      "line": 227,
+      "text": "// コンテキスト文字列を構築"
+    },
+    {
+      "line": 246,
+      "text": "lang === 'zh' ? '中文' : lang === 'en' ? 'English' : '日本語';"
+    },
+    {
+      "line": 276,
+      "text": "* 検索結果の重複排除"
+    },
+    {
+      "line": 290,
+      "text": "* クエリを拡張してバリエーションを生成"
+    },
+    {
+      "line": 308,
+      "text": ".slice(0, 3); // 最大3つに制限"
+    },
+    {
+      "line": 319,
+      "text": "* 仮想的なドキュメント(HyDE)を生成"
+    },
+    {
+      "line": 342,
+      "text": "* 内部タスク用の LLM インスタンスを取得"
+    }
+  ],
+  "d:\\workspace\\AuraK\\server\\src\\rag\\rerank.service.ts": [
+    {
+      "line": 23,
+      "text": "* リランクの実行"
+    },
+    {
+      "line": 24,
+      "text": "* @param query ユーザーのクエリ"
+    },
+    {
+      "line": 25,
+      "text": "* @param documents 候補ドキュメントリスト"
+    },
+    {
+      "line": 26,
+      "text": "* @param userId ユーザーID"
+    },
+    {
+      "line": 27,
+      "text": "* @param rerankModelId 選択された Rerank モデル設定ID"
+    },
+    {
+      "line": 28,
+      "text": "* @param topN 返す結果の数 (上位 N 個)"
+    },
+    {
+      "line": 44,
+      "text": "// 1. モデル設定の取得"
+    },
+    {
+      "line": 59,
+      "text": "// 2. API リクエストの構築 (OpenAI/SiliconFlow 互換 Rerank API)"
+    },
+    {
+      "line": 60,
+      "text": "// 注: 標準の OpenAI API には /rerank はありませんが、SiliconFlow/Jina/Cohere は同様の構造を使用しています"
+    },
+    {
+      "line": 61,
+      "text": "// SiliconFlow 形式: POST /v1/rerank { model, query, documents, top_n }"
+    },
+    {
+      "line": 86,
+      "text": "// 3. レスポンスの解析"
+    }
+  ],
+  "d:\\workspace\\AuraK\\server\\src\\search-history\\search-history.controller.ts": [
+    {
+      "line": 54,
+      "text": "return { message: '对话历史删除成功' };"
+    }
+  ],
+  "d:\\workspace\\AuraK\\server\\src\\search-history\\search-history.service.ts": [
+    {
+      "line": 150,
+      "text": "// 履歴レコードの更新時間を更新"
+    }
+  ],
+  "d:\\workspace\\AuraK\\server\\src\\upload\\upload.controller.ts": [
+    {
+      "line": 37,
+      "text": "mode?: 'fast' | 'precise'; // 処理モード"
+    },
+    {
+      "line": 101,
+      "text": "// 画像MIMEタイプまたは拡張子によるチェック"
+    },
+    {
+      "line": 127,
+      "text": "// ファイルサイズの検証(フロントエンド制限 + バックエンド検証)"
+    },
+    {
+      "line": 137,
+      "text": "// 埋め込みモデル設定の検証"
+    },
+    {
+      "line": 143,
+      "text": "`ユーザー ${req.user.id} がファイルをアップロードしました: ${file.originalname} (${this.formatBytes(file.size)})`,"
+    },
+    {
+      "line": 148,
+      "text": "// 設定パラメータを解析し、安全なデフォルト値を設定"
+    },
+    {
+      "line": 156,
+      "text": "// オーバーラップサイズがチャンクサイズの50%を超えないようにする"
+    },
+    {
+      "line": 164,
+      "text": "// データベースに保存し、インデックスプロセスをトリガー(非同期)"
+    },
+    {
+      "line": 183,
+      "text": "estimatedChunks: Math.ceil(file.size / (indexingConfig.chunkSize * 4)), // 推定チャンク数"
+    }
+  ],
+  "d:\\workspace\\AuraK\\server\\src\\upload\\upload.module.ts": [
+    {
+      "line": 24,
+      "text": "); // 環境変数からアップロードパスを取得し、ない場合はデフォルトとして './uploads' を使用します"
+    },
+    {
+      "line": 26,
+      "text": "// アップロードディレクトリが存在することを確認"
+    },
+    {
+      "line": 31,
+      "text": "// 環境変数から最大ファイルサイズ制限を取得、デフォルトは 100MB"
+    },
+    {
+      "line": 48,
+      "text": "// 中国語ファイル名の文字化け問題を解決"
+    },
+    {
+      "line": 62,
+      "text": "fileSize: maxFileSize, // ファイルサイズの制限"
+    }
+  ],
+  "d:\\workspace\\AuraK\\server\\src\\user\\user.controller.ts": [
+    {
+      "line": 161,
+      "text": "// 更新するユーザー情報を取得"
+    },
+    {
+      "line": 206,
+      "text": "// 管理者が自身を削除するのを防止"
+    },
+    {
+      "line": 211,
+      "text": "// 削除するユーザー情報を取得"
+    },
+    {
+      "line": 221,
+      "text": "// ビルトインadminアカウントの削除を阻止"
+    }
+  ],
+  "d:\\workspace\\AuraK\\server\\src\\user\\user.entity.ts": [
+    {
+      "line": 57,
+      "text": "// クォータ管理フィールド"
+    }
+  ],
+  "d:\\workspace\\AuraK\\server\\src\\user\\user.service.ts": [
+    {
+      "line": 232,
+      "text": "// パスワードの更新が必要な場合は、まずハッシュ化する"
+    },
+    {
+      "line": 238,
+      "text": "// ユーザー名 \"admin\" のユーザーに対するいかなる変更も阻止"
+    },
+    {
+      "line": 275,
+      "text": "// ユーザー名 \"admin\" のユーザーの削除を阻止"
+    },
+    {
+      "line": 306,
+      "text": "console.log('パスワード:', randomPassword);"
+    }
+  ],
+  "d:\\workspace\\AuraK\\server\\src\\user-setting\\user-setting.entity.ts": [
+    {
+      "line": 11,
+      "text": "import { User } from '../user/user.entity'; // Userエンティティのパス"
+    }
+  ],
+  "d:\\workspace\\AuraK\\server\\src\\user-setting\\user-setting.service.ts": [
+    {
+      "line": 23,
+      "text": "// 1. 既存のグローバル設定を検索する"
+    },
+    {
+      "line": 33,
+      "text": "// 2. グローバル設定がない場合、旧 'system' ユーザーから移行を試みる"
+    },
+    {
+      "line": 45,
+      "text": "// 3. 旧記録もない場合は、新規作成する"
+    },
+    {
+      "line": 114,
+      "text": "console.log('=== updateLanguage デバッグ ===');"
+    },
+    {
+      "line": 130,
+      "text": "console.log('=== getLanguage デバッグ ===');"
+    },
+    {
+      "line": 140,
+      "text": "* システム全体のグローバル設定を取得する"
+    },
+    {
+      "line": 148,
+      "text": "// 万が一存在しない場合は初期化"
+    },
+    {
+      "line": 156,
+      "text": "* システム全体のグローバル設定を更新する"
+    }
+  ],
+  "d:\\workspace\\AuraK\\server\\src\\vision\\vision.interface.ts": [
+    {
+      "line": 2,
+      "text": "* Vision 服务接口定义"
+    },
+    {
+      "line": 6,
+      "text": "text: string;              // 抽出されたテキスト内容"
+    },
+    {
+      "line": 7,
+      "text": "images: ImageDescription[]; // 画像の説明"
+    },
+    {
+      "line": 8,
+      "text": "layout: string;            // レイアウトの種類"
+    },
+    {
+      "line": 9,
+      "text": "confidence: number;        // 信頼度 (0-1)"
+    },
+    {
+      "line": 10,
+      "text": "pageIndex?: number;        // 页码"
+    },
+    {
+      "line": 14,
+      "text": "type: string;              // 图片类型 (图表/架构图/流程图等)"
+    },
+    {
+      "line": 15,
+      "text": "description: string;       // 详细描述"
+    },
+    {
+      "line": 16,
+      "text": "position?: number;         // ページ内での位置"
+    },
+    {
+      "line": 30,
+      "text": "estimatedCost: number;     // 预估成本(美元)"
+    }
+  ],
+  "d:\\workspace\\AuraK\\server\\src\\vision\\vision.service.ts": [
+    {
+      "line": 19,
+      "text": "* 単一画像の分析(ドキュメントページ)"
+    },
+    {
+      "line": 27,
+      "text": "const baseDelay = 3000; // 3秒の基礎遅延"
+    },
+    {
+      "line": 39,
+      "text": "const delay = baseDelay + Math.random() * 2000; // 3-5秒のランダムな遅延"
+    },
+    {
+      "line": 48,
+      "text": "// この行は理論的には実行されませんが、TypeScript の要求を満たすために記述しています"
+    },
+    {
+      "line": 53,
+      "text": "* 実際の画像分析を実行"
+    },
+    {
+      "line": 61,
+      "text": "// 画像を読み込み、base64 に変換"
+    },
+    {
+      "line": 66,
+      "text": "// ビジョンモデルのインスタンスを作成"
+    },
+    {
+      "line": 73,
+      "text": "temperature: 0.1, // ランダム性を抑え、一貫性を高める"
+    },
+    {
+      "line": 76,
+      "text": "// 専門的なドキュメント分析プロンプトを構築"
+    },
+    {
+      "line": 94,
+      "text": "// モデルの呼び出し"
+    },
+    {
+      "line": 99,
+      "text": "// JSON の解析を試行"
+    },
+    {
+      "line": 102,
+      "text": "// Markdown のコードブロックタグをクリーンアップ"
+    },
+    {
+      "line": 114,
+      "text": "// 解析に失敗した場合は、内容全体をテキストとして扱う"
+    },
+    {
+      "line": 128,
+      "text": "page: pageIndex ? ` (第 ${pageIndex} ページ)` : '',"
+    },
+    {
+      "line": 138,
+      "text": "throw error; // 重新抛出错误供重试机制处理"
+    },
+    {
+      "line": 143,
+      "text": "* 再試行可能なエラーかどうかを判断"
+    },
+    {
+      "line": 149,
+      "text": "// 429 レート制限エラー"
+    },
+    {
+      "line": 150,
+      "text": "if (errorCode === 429 || errorMessage.includes('rate limit') || errorMessage.includes('リクエストが多すぎます')) {"
+    },
+    {
+      "line": 154,
+      "text": "// 5xx サーバーエラー"
+    },
+    {
+      "line": 159,
+      "text": "// ネットワーク関連エラー"
+    },
+    {
+      "line": 168,
+      "text": "* 遅延関数"
+    },
+    {
+      "line": 175,
+      "text": "* 複数画像の一括分析"
+    },
+    {
+      "line": 201,
+      "text": "// 進捗コールバックを呼び出し"
+    },
+    {
+      "line": 206,
+      "text": "// 品質チェック(スキップ時は直接分析)"
+    },
+    {
+      "line": 234,
+      "text": "// 結果付きで進捗コールバックを呼び出し"
+    },
+    {
+      "line": 244,
+      "text": "// 推定コストの計算(1枚あたり $0.01 と仮定)"
+    },
+    {
+      "line": 263,
+      "text": "* 画像品質のチェック"
+    },
+    {
+      "line": 270,
+      "text": "// ファイルサイズのチェック(5KB以上)"
+    },
+    {
+      "line": 272,
+      "text": "return { isGood: false, reason: `ファイルが小さすぎます (${sizeKB.toFixed(2)}KB)`, score: 0 };"
+    },
+    {
+      "line": 275,
+      "text": "// ファイルサイズ上限のチェック(10MB)"
+    },
+    {
+      "line": 277,
+      "text": "return { isGood: false, reason: `ファイルが大きすぎます (${sizeKB.toFixed(2)}KB)`, score: 0 };"
+    },
+    {
+      "line": 280,
+      "text": "// 簡易的な品質スコアリング"
+    },
+    {
+      "line": 295,
+      "text": "* サポートされている画像ファイルかどうかを確認"
+    },
+    {
+      "line": 310,
+      "text": "* MIME タイプを取得"
+    },
+    {
+      "line": 328,
+      "text": "* 旧インターフェース互換:単一画像の内容を抽出"
+    }
+  ],
+  "d:\\workspace\\AuraK\\server\\src\\vision-pipeline\\cost-control.service.ts": [
+    {
+      "line": 2,
+      "text": "* コスト制御およびクォータ管理サービス"
+    },
+    {
+      "line": 3,
+      "text": "* Vision Pipeline の API 呼び出しコストを管理するために使用されます"
+    },
+    {
+      "line": 14,
+      "text": "monthlyCost: number;      // 今月の使用済みコスト"
+    },
+    {
+      "line": 15,
+      "text": "maxCost: number;          // 月間最大コスト"
+    },
+    {
+      "line": 16,
+      "text": "remaining: number;        // 残りコスト"
+    },
+    {
+      "line": 17,
+      "text": "lastReset: Date;          // 最終リセット時間"
+    },
+    {
+      "line": 21,
+      "text": "estimatedCost: number;    // 推定コスト"
+    },
+    {
+      "line": 22,
+      "text": "estimatedTime: number;    // 推定時間(秒)"
+    },
+    {
+      "line": 23,
+      "text": "pageBreakdown: {          // ページごとの明細"
+    },
+    {
+      "line": 32,
+      "text": "private readonly COST_PER_PAGE = 0.01; // 1ページあたりのコスト(USD)"
+    },
+    {
+      "line": 33,
+      "text": "private readonly DEFAULT_MONTHLY_LIMIT = 100; // デフォルトの月間制限(USD)"
+    },
+    {
+      "line": 42,
+      "text": "* 処理コストの推定"
+    },
+    {
+      "line": 45,
+      "text": "// 品質に基づいてコスト係数を調整"
+    },
+    {
+      "line": 53,
+      "text": "const estimatedTime = pageCount * 3; // 1ページあたり約 3 秒"
+    },
+    {
+      "line": 68,
+      "text": "* ユーザーのクォータをチェック"
+    },
+    {
+      "line": 77,
+      "text": "// 月間リセットのチェック"
+    },
+    {
+      "line": 87,
+      "text": "reason: `クォータ不足: 残り $${quota.remaining.toFixed(2)}, 必要 $${estimatedCost.toFixed(2)}`,"
+    },
+    {
+      "line": 98,
+      "text": "* クォータの差し引き"
+    },
+    {
+      "line": 115,
+      "text": "* ユーザーのクォータを取得"
+    },
+    {
+      "line": 121,
+      "text": "throw new Error(`ユーザー ${userId} は存在しません`);"
+    },
+    {
+      "line": 124,
+      "text": "// ユーザーにクォータ情報がない場合はデフォルト値を使用"
+    },
+    {
+      "line": 139,
+      "text": "* 月間クォータのチェックとリセット"
+    },
+    {
+      "line": 145,
+      "text": "// 月を跨いでいるかチェック"
+    },
+    {
+      "line": 152,
+      "text": "// クォータをリセット"
+    },
+    {
+      "line": 157,
+      "text": "// データベースを更新"
+    },
+    {
+      "line": 166,
+      "text": "* ユーザーのクォータ制限を設定"
+    },
+    {
+      "line": 174,
+      "text": "* コストレポートの取得"
+    },
+    {
+      "line": 183,
+      "text": "quotaUsage: number; // パーセンテージ"
+    },
+    {
+      "line": 188,
+      "text": "// ここで履歴レコードを照会できます(実装されている場合)"
+    },
+    {
+      "line": 189,
+      "text": "// 暫定的に現在のクォータ情報を返します"
+    },
+    {
+      "line": 203,
+      "text": "* コスト警告閾値のチェック"
+    },
+    {
+      "line": 215,
+      "text": "message: `⚠️ クォータ使用率が ${usagePercent.toFixed(1)}% に達しました。残り $${quota.remaining.toFixed(2)}`,"
+    },
+    {
+      "line": 222,
+      "text": "message: `💡 クォータ使用率 ${usagePercent.toFixed(1)}%。コストの管理に注意してください`,"
+    },
+    {
+      "line": 233,
+      "text": "* コスト表示のフォーマット"
+    },
+    {
+      "line": 240,
+      "text": "* 時間表示のフォーマット"
+    },
+    {
+      "line": 244,
+      "text": "return `${seconds.toFixed(0)}秒`;"
+    },
+    {
+      "line": 248,
+      "text": "return `${minutes}分${remainingSeconds.toFixed(0)}秒`;"
+    }
+  ],
+  "d:\\workspace\\AuraK\\server\\src\\vision-pipeline\\vision-pipeline-cost-aware.service.ts": [
+    {
+      "line": 2,
+      "text": "* Vision Pipeline サービス(コスト制御付き)"
+    },
+    {
+      "line": 3,
+      "text": "* これは vision-pipeline.service.ts の拡張版であり、コスト制御が統合されています"
+    },
+    {
+      "line": 30,
+      "text": "private costControl: CostControlService, // 新增成本控制服务"
+    },
+    {
+      "line": 34,
+      "text": "* メイン処理フロー:精密モード(コスト制御付き)"
+    },
+    {
+      "line": 53,
+      "text": "// ステップ 1: 形式の統一"
+    },
+    {
+      "line": 54,
+      "text": "this.updateStatus('converting', 10, 'ドキュメント形式を変換中...');"
+    },
+    {
+      "line": 57,
+      "text": "// ステップ 2: PDF から画像への変換"
+    },
+    {
+      "line": 58,
+      "text": "this.updateStatus('splitting', 30, 'PDF を画像に変換中...');"
+    },
+    {
+      "line": 66,
+      "text": "throw new Error('PDF から画像への変換に失敗しました。画像が生成されませんでした');"
+    },
+    {
+      "line": 69,
+      "text": "// 限制处理页数"
+    },
+    {
+      "line": 76,
+      "text": "// ステップ 3: コスト見積もりとクォータチェック"
+    },
+    {
+      "line": 77,
+      "text": "this.updateStatus('checking', 40, 'クォータを確認し、コストを見積もり中...');"
+    },
+    {
+      "line": 83,
+      "text": "// クォータチェック"
+    },
+    {
+      "line": 93,
+      "text": "// コスト警告チェック"
+    },
+    {
+      "line": 99,
+      "text": "// ステップ 4: Vision モデル設定の取得"
+    },
+    {
+      "line": 102,
+      "text": "// ステップ 5: VL モデル分析"
+    },
+    {
+      "line": 103,
+      "text": "this.updateStatus('analyzing', 50, 'ビジョンモデルを使用してページを分析中...');"
+    },
+    {
+      "line": 118,
+      "text": "// ステップ 6: 実際のコストを差し引く"
+    },
+    {
+      "line": 124,
+      "text": "// ステップ 7: 一時ファイルのクリーンアップ"
+    },
+    {
+      "line": 125,
+      "text": "this.updateStatus('completed', 100, '処理が完了しました。一時ファイルをクリーンアップ中...');"
+    },
+    {
+      "line": 128,
+      "text": "// PDF に変換した場合、変換後のファイルをクリーンアップ"
+    },
+    {
+      "line": 159,
+      "text": "// 尝试清理临时文件"
+    },
+    {
+      "line": 185,
+      "text": "* Vision モデル設定の取得"
+    },
+    {
+      "line": 191,
+      "text": "throw new Error(`モデル設定が見つかりません: ${modelId}`);"
+    },
+    {
+      "line": 194,
+      "text": "// APIキーはオプションです - ローカルモデルを許可します"
+    },
+    {
+      "line": 204,
+      "text": "* PDF への変換"
+    },
+    {
+      "line": 209,
+      "text": "// 既に PDF の場合はそのまま返す"
+    },
+    {
+      "line": 214,
+      "text": "// LibreOffice を呼び出して変換"
+    },
+    {
+      "line": 219,
+      "text": "* 形式検出とモードの推奨(コスト見積もり付き)"
+    },
+    {
+      "line": 232,
+      "text": "reason: `サポートされていないファイル形式です: ${ext}`,"
+    },
+    {
+      "line": 233,
+      "text": "warnings: ['高速モード(テキスト抽出のみ)を使用します'],"
+    },
+    {
+      "line": 240,
+      "text": "reason: `形式 ${ext} は精密モードをサポートしていません`,"
+    },
+    {
+      "line": 241,
+      "text": "warnings: ['高速モード(テキスト抽出のみ)を使用します'],"
+    },
+    {
+      "line": 245,
+      "text": "// ページ数の見積もり(ファイルサイズに基づく)"
+    },
+    {
+      "line": 249,
+      "text": "// ファイルサイズが大きい場合は精密モードを推奨"
+    },
+    {
+      "line": 253,
+      "text": "reason: 'ファイルが大きいため、完全な情報を保持するために精密モードを推奨します',"
+    },
+    {
+      "line": 256,
+      "text": "warnings: ['処理時間が長くなる可能性があります', 'API 費用が発生します'],"
+    },
+    {
+      "line": 260,
+      "text": "// 精密モードを推奨"
+    },
+    {
+      "line": 263,
+      "text": "reason: '精密モードが利用可能です。テキストと画像の混合コンテンツを保持できます',"
+    },
+    {
+      "line": 266,
+      "text": "warnings: ['API 費用が発生します'],"
+    },
+    {
+      "line": 271,
+      "text": "* ユーザーのクォータ情報を取得"
+    },
+    {
+      "line": 285,
+      "text": "* 処理状態の更新(リアルタイムフィードバック用)"
+    }
+  ],
+  "d:\\workspace\\AuraK\\server\\src\\vision-pipeline\\vision-pipeline.interface.ts": [
+    {
+      "line": 2,
+      "text": "* Vision Pipeline 接口定义"
+    },
+    {
+      "line": 26,
+      "text": "duration: number; // 秒"
+    },
+    {
+      "line": 47,
+      "text": "estimatedTime?: number; // 秒"
+    }
+  ]
+}

+ 45 - 0
extract_cjk.js

@@ -0,0 +1,45 @@
+const fs = require('fs');
+const path = require('path');
+
+const directories = ['d:/workspace/AuraK/web', 'd:/workspace/AuraK/server/src'];
+const excludeDirs = ['node_modules', '.git', 'dist', '.next', 'dist-check'];
+const extensions = ['.ts', '.tsx', '.js', '.jsx'];
+
+const cjkPattern = /[\u4e00-\u9fff\u3040-\u309f\u30a0-\u30ff]+/;
+const cjkLines = {};
+
+function walkSync(currentDirPath, callback) {
+    fs.readdirSync(currentDirPath).forEach((name) => {
+        const filePath = path.join(currentDirPath, name);
+        const stat = fs.statSync(filePath);
+        if (stat.isFile()) {
+            callback(filePath, stat);
+        } else if (stat.isDirectory() && !excludeDirs.includes(name)) {
+            walkSync(filePath, callback);
+        }
+    });
+}
+
+directories.forEach(d => {
+    walkSync(d, (filePath) => {
+        if (extensions.some(ext => filePath.endsWith(ext))) {
+            try {
+                const content = fs.readFileSync(filePath, 'utf-8');
+                const lines = content.split('\n');
+                lines.forEach((line, i) => {
+                    if (cjkPattern.test(line)) {
+                        if (!cjkLines[filePath]) {
+                            cjkLines[filePath] = [];
+                        }
+                        cjkLines[filePath].push({ line: i + 1, text: line.trim() });
+                    }
+                });
+            } catch (e) {
+                console.error(`Error reading ${filePath}: `, e);
+            }
+        }
+    });
+});
+
+fs.writeFileSync('cjk_extract.json', JSON.stringify(cjkLines, null, 2), 'utf-8');
+console.log('Extracted to cjk_extract.json');

+ 31 - 0
extract_cjk.py

@@ -0,0 +1,31 @@
+import os
+import re
+import json
+
+directories = ['d:/workspace/AuraK/web', 'd:/workspace/AuraK/server/src']
+exclude_dirs = ['node_modules', '.git', 'dist', '.next']
+extensions = ['.ts', '.tsx', '.js', '.jsx']
+
+cjk_pattern = re.compile(r'[\u4e00-\u9fff\u3040-\u309f\u30a0-\u30ff]+')
+
+cjk_lines = {}
+for d in directories:
+    for root, dirs, files in os.walk(d):
+        dirs[:] = [dir for dir in dirs if dir not in exclude_dirs]
+        for file in files:
+            if any(file.endswith(ext) for ext in extensions):
+                file_path = os.path.join(root, file)
+                try:
+                    with open(file_path, 'r', encoding='utf-8') as f:
+                        lines = f.readlines()
+                        for i, line in enumerate(lines):
+                            if cjk_pattern.search(line):
+                                if file_path not in cjk_lines:
+                                    cjk_lines[file_path] = []
+                                cjk_lines[file_path].append({"line": i + 1, "text": line.strip()})
+                except Exception as e:
+                    print(f"Error reading {file_path}: {e}")
+
+with open('cjk_extract.json', 'w', encoding='utf-8') as f:
+    json.dump(cjk_lines, f, ensure_ascii=False, indent=2)
+print("Extracted to cjk_extract.json")

+ 1 - 1
server/src/api/api.controller.ts

@@ -47,7 +47,7 @@ export class ApiController {
         throw new Error(this.i18nService.getMessage('addLLMConfig'));
       }
 
-      // APIキーはオプションです - ローカルモデルを許可します
+      // API key is optional - allow local models
 
       // entity タイプを types インターフェースに変換
       const modelConfigForService = {

+ 1 - 1
server/src/api/api.service.ts

@@ -15,7 +15,7 @@ export class ApiService {
     prompt: string,
     modelConfig: ModelConfig,
   ): Promise<string> {
-    // APIキーはオプションです - ローカルモデルを許可します
+    // API key is optional - allow local models
 
     try {
       const llm = this.createLLM(modelConfig);

+ 4 - 4
server/src/chat/chat.service.ts

@@ -328,14 +328,14 @@ ${instruction}`;
     embeddingModelId?: string,
     selectedGroups?: string[], // 新規パラメータ
     explicitFileIds?: string[], // 新規パラメータ
-    tenantId?: string, // 追加
+    tenantId?: string, // Added
   ): Promise<any[]> {
     try {
       // キーワードを検索文字列に結合
       const combinedQuery = keywords.join(' ');
       console.log(this.i18nService.getMessage('searchString', 'ja') + combinedQuery);
 
-      // 埋め込みモデルIDが提供されているか確認
+      // Embedding model IDが提供されているか確認
       if (!embeddingModelId) {
         console.log(this.i18nService.getMessage('embeddingModelIdNotProvided', 'ja'));
         return [];
@@ -361,7 +361,7 @@ ${instruction}`;
         0.6,
         selectedGroups, // 選択されたグループを渡す
         explicitFileIds, // 明示的なファイルIDを渡す
-        tenantId, // 追加: tenantId
+        tenantId, // Added: tenantId
       );
       console.log(this.i18nService.getMessage('esSearchCompleted', 'ja') + this.i18nService.getMessage('resultsCount', 'ja') + ':', results.length);
 
@@ -476,7 +476,7 @@ ${instruction}`;
         return null;
       }
 
-      // 優先順位: 引数の言語 > ユーザー設定 > 日本語(ja)
+      // 優先順位: 引数の言語 > ユーザー設定 > Japanese(ja)
       let targetLanguage = language;
       if (!targetLanguage) {
         const settings = await this.userSettingService.findOrCreate(userId);

+ 1 - 1
server/src/common/constants.ts

@@ -2,7 +2,7 @@
  * アプリケーション全体で使用される定数定義
  */
 
-// チャンク設定のデフォルト値
+// Chunk configurationのデフォルト値
 export const DEFAULT_CHUNK_SIZE = 200;
 export const MIN_CHUNK_SIZE = 50;
 export const MAX_CHUNK_SIZE = 8191;

+ 3 - 3
server/src/elasticsearch/elasticsearch.service.ts

@@ -312,7 +312,7 @@ export class ElasticsearchService implements OnModuleInit {
     // 結果をマージして重複を排除
     const combinedResults = new Map();
 
-    // 向量搜索結果を追加
+    // 向量搜索結果をAdded
     vectorResults.forEach((result) => {
       combinedResults.set(result.id, {
         ...result,
@@ -322,7 +322,7 @@ export class ElasticsearchService implements OnModuleInit {
       });
     });
 
-    // 全文検索結果を追加
+    // 全文Search resultsをAdded
     textResults.forEach((result) => {
       if (combinedResults.has(result.id)) {
         const existing = combinedResults.get(result.id);
@@ -350,7 +350,7 @@ export class ElasticsearchService implements OnModuleInit {
       .sort((a, b) => b.combinedScore - a.combinedScore)
       .slice(0, topK)
       .map((result) => {
-        // combinedScoreは既に0-1の範囲にあるため、追加の正規化は不要
+        // combinedScoreは既に0-1の範囲にあるため、Addedの正規化は不要
         // 0-1の範囲にスコアを保つことで、実際の類似度を正確に反映
         let finalScore = result.combinedScore;
 

+ 10 - 10
server/src/i18n/i18n.service.ts

@@ -4,7 +4,7 @@ import { i18nStore } from './i18n.store';
 
 @Injectable()
 export class I18nService {
-  private readonly defaultLanguage = 'ja'; // プロジェクト要件に従い、日本語をデフォルトとして使用
+  private readonly defaultLanguage = 'ja'; // プロジェクト要件に従い、Japaneseをデフォルトとして使用
 
   private getLanguage(lang?: string): string {
     if (lang) return lang;
@@ -78,7 +78,7 @@ ${hasKnowledgeGroup ? `
 
 用户问题:{question}
 
-请用中文回答,并严格遵循以下 Markdown 格式要求:
+请用Chinese回答,并严格遵循以下 Markdown 格式要求:
 
 1. **段落与结构**:
    - 使用清晰的段落分隔,每个要点之间空一行
@@ -118,7 +118,7 @@ ${hasKnowledgeGroup ? `
 
 用户问题:{question}
 
-请用中文回答。
+请用Chinese回答。
 `;
     } else if (language === 'en') {
       return type === 'withContext' ? `
@@ -190,7 +190,7 @@ ${hasKnowledgeGroup ? `
 
 ユーザーの質問:{question}
 
-日本語で回答してください。以下の Markdown 書式要件に厳密に従ってください:
+Japaneseで回答してください。以下の Markdown 書式要件に厳密に従ってください:
 
 1. **段落と構造**:
    - 明確な段落分けを使用し、要点間に空行を入れる
@@ -229,7 +229,7 @@ ${hasKnowledgeGroup ? `
 {history}
 
 ユーザーの質問:{question}
-      日本語で回答してください。
+      Japaneseで回答してください。
 `;
     }
   }
@@ -238,9 +238,9 @@ ${hasKnowledgeGroup ? `
   getDocumentTitlePrompt(lang: string = this.defaultLanguage, contentSample: string): string {
     const language = this.getLanguage(lang);
     if (language === 'zh') {
-      return `你是一个文档分析师。请阅读以下文本(文档开头部分),并生成一个简炼、专业的标题(不超过50个字符)。
+      return `你是一个文档分析师。请阅读以下文本(文档开Header分),并生成一个简炼、专业的标题(不超过50个字符)。
 只返回标题文本。不要包含任何解释性文字或前导词(如“标题是:”)。
-语言:中文
+语言:Chinese
 文本内容:
 ${contentSample}`;
     } else if (language === 'en') {
@@ -252,7 +252,7 @@ ${contentSample}`;
     } else {
       return `あなたはドキュメントアナライザーです。以下のテキスト(ドキュメントの冒頭部分)を読み、簡潔でプロフェッショナルなタイトル(最大50文字)を生成してください。
 タイトルテキストのみを返してください。説明文や前置き(例:「タイトルは:」)は含めないでください。
-言語:日本語
+言語:Japanese
 テキスト:
 ${contentSample}`;
     }
@@ -263,7 +263,7 @@ ${contentSample}`;
     if (language === 'zh') {
       return `根据以下对话片段,生成一个简短、描述性的标题(不超过50个字符),总结讨论的主题。
 只返回标题文本。不要包含任何前导词。
-语言:中文
+语言:Chinese
 片段:
 用户: ${userMessage}
 助手: ${aiResponse}`;
@@ -277,7 +277,7 @@ Assistant: ${aiResponse}`;
     } else {
       return `以下の会話スニペットに基づいて、トピックを要約する短く説明的なタイトル(最大50文字)を生成してください。
 タイトルのみを返してください。前置きは不要です。
-言語:日本語
+言語:Japanese
 スニペット:
 ユーザー: ${userMessage}
 アシスタント: ${aiResponse}`;

+ 26 - 26
server/src/i18n/messages.ts

@@ -68,15 +68,15 @@ export const errorMessages = {
     visionModelNotConfigured: 'ビジョンモデルが設定されていません',
     embeddingDimensionMismatch: '埋め込み次元数が一致しません',
     uploadNoFile: 'ファイルがアップロードされていません',
-    uploadSizeExceeded: 'ファイルサイズが制限を超えています: {size}, 最大許容: {max}',
+    uploadSizeExceeded: 'ファイルサイズが制限: {size}, 最大許容: {max}',
     uploadModelRequired: '埋め込みモデルを選択する必要があります',
     uploadTypeUnsupported: 'サポートされていないファイル形式です: {type}',
-    chunkOverflow: 'チャンクサイズ {size} が上限 {max} ({reason}) を超えています。自動調整されました',
-    chunkUnderflow: 'チャンクサイズ {size} が最小値 {min} 未満です。自動調整されました',
-    overlapOverflow: '重なりサイズ {size} が上限 {max} を超えています。自動調整されました',
-    overlapUnderflow: '重なりサイズ {size} が最小値 {min} 未満です。自動調整されました',
-    overlapRatioExceeded: '重なりサイズ {size} がチャンクサイズの50% ({max}) を超えています。自動調整されました',
-    batchOverflowWarning: 'バッチ処理のオーバーフローを避けるため、チャンクサイズを {safeSize} 以下にすることをお勧めします (現在: {size}, モデル制限の {percent}%)',
+    chunkOverflow: 'Chunk size {size}  exceeds limit  {max} ({reason}) 。自動調整されました',
+    chunkUnderflow: 'Chunk size {size}  is below minimum  {min} 。自動調整されました',
+    overlapOverflow: '重なりサイズ {size}  exceeds limit  {max} 。自動調整されました',
+    overlapUnderflow: '重なりサイズ {size}  is below minimum  {min} 。自動調整されました',
+    overlapRatioExceeded: '重なりサイズ {size} がChunk sizeの50% ({max}) 。自動調整されました',
+    batchOverflowWarning: 'バッチ処理のオーバーフローを避けるため、Chunk sizeを {safeSize} 以下にすることをお勧めします (現在: {size}, モデル制限の {percent}%)',
     estimatedChunkCountExcessive: '推定チャンク数が多すぎます ({count})。処理に時間がかかる可能性があります',
     contentAndTitleRequired: '内容とタイトルは必須です',
     embeddingModelNotFound: '埋め込みモデル {id} が見つかりません、またはタイプが embedding ではありません',
@@ -111,7 +111,7 @@ export const errorMessages = {
     pdfPageImageFailed: 'PDF ページの画像を取得できませんでした',
     someGroupsNotFound: '一部のグループが存在しません',
     promptRequired: 'プロンプトは必須です',
-    addLLMConfig: 'システム設定で LLM モデルを追加してください',
+    addLLMConfig: 'システム設定で LLM モデルをAddedしてください',
     visionAnalysisFailed: 'ビジョン分析に失敗しました: {message}',
     retryMechanismError: '再試行メカニズムの異常',
     imageLoadError: '画像を読み込めません: {message}',
@@ -210,10 +210,10 @@ export const logMessages = {
     indexingComplete: 'インデックス完了: {id}',
     vectorizingFile: 'ファイルベクトル化中: ',
     searchQuery: '検索クエリ: ',
-    modelCall: '[モデル呼び出し] タイプ: {type}, モデル: {model}, ユーザー: {user}',
+    modelCall: '[モデル呼び出し] タイプ: {type}, Model: {model}, ユーザー: {user}',
     memoryStatus: 'メモリ状態: ',
     uploadSuccess: 'ファイルが正常にアップロードされました。バックグラウンドでインデックス処理を実行中です',
-    overlapAdjusted: 'オーバーラップサイズがチャンクサイズの50%を超えています。自動的に {newSize} に調整されました',
+    overlapAdjusted: 'オーバーラップサイズがChunk sizeの50%。自動的に {newSize} に調整されました',
     environmentLimit: '環境変数の制限',
     modelLimit: 'モデルの制限',
     configLoaded: 'データベースからモデル設定を読み込みました: {name} ({id})',
@@ -221,11 +221,11 @@ export const logMessages = {
     dimensionMismatch: 'モデル {id} の次元が一致しません: 期待値 {expected}, 実際 {actual}',
     searchMetadataFailed: 'ユーザー {userId} のナレッジベース検索に失敗しました',
     extractedTextTooLarge: '抽出されたテキストが大きいです: {size}MB',
-    preciseModeUnsupported: 'ファイル形式 {ext} は精密モードをサポートしていません。高速モードにフォールバックします',
-    visionModelNotConfiguredFallback: 'ビジョンモデルが設定されていません。高速モードにフォールバックします',
-    visionModelInvalidFallback: 'ビジョンモデルの設定が無効です。高速モードにフォールバックします',
-    visionPipelineFailed: 'ビジョンパイプラインが失敗しました。高速モードにフォールバックします',
-    preciseModeComplete: '精密モード内容抽出完了: {pages}ページ, コスト: ${cost}',
+    preciseModeUnsupported: 'ファイル形式 {ext} はPrecise Modeをサポートしていません。Fast Modeにフォールバックします',
+    visionModelNotConfiguredFallback: 'ビジョンモデルが設定されていません。Fast Modeにフォールバックします',
+    visionModelInvalidFallback: 'ビジョンモデルの設定が無効です。Fast Modeにフォールバックします',
+    visionPipelineFailed: 'ビジョンパイプラインが失敗しました。Fast Modeにフォールバックします',
+    preciseModeComplete: 'Precise Mode内容抽出完了: {pages}ページ, コスト: ${cost}',
     skippingEmptyVectorPage: '第 {page} ページの空ベクトルをスキップします',
     pdfPageImageError: 'PDF ページの画像取得に失敗しました: {message}',
     internalServerError: 'サーバー内部エラー',
@@ -263,7 +263,7 @@ export const statusMessages = {
     noResults: '未找到相关知识,将基于一般知识回答...',
     searchFailed: '知识库搜索失败,将基于一般知识回答...',
     generatingResponse: '正在生成回答',
-    files: '个文件',
+    files: ' files',
     notebooks: '个笔记本',
     all: '全部',
     items: '个',
@@ -360,7 +360,7 @@ export const statusMessages = {
     notebooks: '個のノートブック',
     all: 'すべて',
     items: '件',
-    searchResults: '検索結果',
+    searchResults: 'Search results',
     relevantInfoFound: '件の関連情報が見つかりました',
     searchHits: '検索ヒット',
     relevance: '関連度',
@@ -371,9 +371,9 @@ export const statusMessages = {
     searchingModelById: 'selectedEmbeddingId に基づいてモデルを検索: ',
     searchModelFallback: '指定された埋め込みモデルが見つかりません。最初に使用可能なモデルを使用します。',
     noEmbeddingModelFound: '埋め込みモデルの設定が見つかりません',
-    usingEmbeddingModel: '使用する埋め込みモデル: ',
+    usingEmbeddingModel: '使用する埋め込みModel: ',
     startingSearch: 'ナレッジベースの検索を開始...',
-    searchResultsCount: '検索結果数: ',
+    searchResultsCount: 'Search results数: ',
     searchFailedLog: '検索失敗',
     chatStreamError: 'チャットストリームエラー',
     assistStreamError: 'アシストストリームエラー',
@@ -383,7 +383,7 @@ export const statusMessages = {
     assistantLabel: 'アシスタント',
     intelligentAssistant: 'あなたはインテリジェントな執筆アシスタントです。',
     searchString: '検索文字列: ',
-    embeddingModelIdNotProvided: '埋め込みモデルIDが提供されていません',
+    embeddingModelIdNotProvided: 'Embedding model IDが提供されていません',
     generatingEmbeddings: '埋め込みベクトルを生成中...',
     embeddingsGenerated: '埋め込みベクトルの生成が完了しました',
     dimensions: '次元数',
@@ -407,19 +407,19 @@ export const statusMessages = {
     pageImageNotFoundDetail: 'PDF の第 {page} ページの画像を取得できません',
     groupSyncSuccess: 'ファイルグループが更新されました',
     fileDeletedFromGroup: 'ファイルがグループから削除されました',
-    chunkConfigCorrection: 'チャンク設定の修正: {warnings}',
+    chunkConfigCorrection: 'Chunk configurationの修正: {warnings}',
     noChunksGenerated: 'ファイル {id} からテキストチャンクが生成されませんでした',
     chunkCountAnomaly: '実際のチャンク数 {actual} が推定値 {estimated} を大幅に超えています。異常がある可能性があります',
-    batchSizeExceeded: 'バッチ {index} のサイズ {actual} が推奨値 {limit} を超えています。分割して処理します',
+    batchSizeExceeded: 'バッチ {index} のサイズ {actual} が推奨値 {limit} 。分割して処理します',
     skippingEmptyVectorChunk: '空ベクトルのテキストブロック {index} をスキップします',
     contextLengthErrorFallback: 'バッチ処理でコンテキスト長エラーが発生しました。単一テキスト処理モードにダウングレードします',
-    chunkLimitExceededForceBatch: 'チャンク数 {actual} がモデルのバッチ制限 {limit} を超えています。強制的にバッチ処理を行います',
+    chunkLimitExceededForceBatch: 'チャンク数 {actual} がモデルのバッチ制限 {limit} 。強制的にバッチ処理を行います',
     noteContentRequired: 'ノート内容は必須です',
-    imageAnalysisStarted: 'モデル {id} で画像を分析中...',
-    batchAnalysisStarted: '{count} 枚の画像を分析中...',
+    imageAnalysisStarted: 'モデル {id} で画像をAnalyzing...',
+    batchAnalysisStarted: '{count} 枚の画像をAnalyzing...',
     pageAnalysisFailed: '第 {page} ページの分析に失敗しました',
     visionSystemPrompt: 'あなたは専門的なドキュメント分析アシスタントです。このドキュメント画像を分析し、以下の要求に従って JSON 形式で返してください:\n\n1. すべての読み取り可能なテキストを抽出(読み取り順序に従い、段落と形式を保持)\n2. 画像/グラフ/表の識別(内容、意味、役割を記述)\n3. ページレイアウトの分析(テキストのみ/テキストと画像の混合/表/グラフなど)\n4. 分析品質の評価(0-1)\n\nレスポンス形式:\n{\n  "text": "完全なテキスト内容",\n  "images": [\n    {"type": "グラフの種類", "description": "詳細な記述", "position": 1}\n  ],\n  "layout": "レイアウトの説明",\n  "confidence": 0.95\n}',
-    visionModelCall: '[モデル呼び出し] タイプ: Vision, モデル: {model}, ページ: {page}',
+    visionModelCall: '[モデル呼び出し] タイプ: Vision, Model: {model}, ページ: {page}',
     visionAnalysisSuccess: '✅ Vision 分析完了: {path}{page}, テキスト長: {textLen}文字, 画像数: {imgCount}, レイアウト: {layout}, 信頼度: {confidence}%',
     conversationHistoryNotFound: '会話履歴が存在しません',
     batchContextLengthErrorFallback: '小ファイルバッチ処理でコンテキスト長エラーが発生しました。単一テキスト処理モードにダウングレードします',

+ 13 - 13
server/src/knowledge-base/chunk-config.service.ts

@@ -5,7 +5,7 @@ import { TenantService } from '../tenant/tenant.service';
 import { UserSettingService } from '../user-setting/user-setting.service';
 
 /**
- * チャンク設定サービス
+ * Chunk configurationサービス
  * チャンクパラメータの検証と管理を担当し、モデルの制限や環境変数の設定に適合していることを確認します
  *
  * 制限の優先順位:
@@ -34,7 +34,7 @@ export class ChunkConfigService {
     chunkOverlap: DEFAULT_CHUNK_OVERLAP,
     minChunkSize: MIN_CHUNK_SIZE,
     minChunkOverlap: MIN_CHUNK_OVERLAP,
-    maxOverlapRatio: DEFAULT_MAX_OVERLAP_RATIO,  // 重なりはチャンクサイズの50%まで
+    maxOverlapRatio: DEFAULT_MAX_OVERLAP_RATIO,  // 重なりはChunk sizeの50%まで
     maxBatchSize: DEFAULT_MAX_BATCH_SIZE,    // デフォルトのバッチ制限
     expectedDimensions: DEFAULT_VECTOR_DIMENSIONS, // デフォルトのベクトル次元
   };
@@ -90,8 +90,8 @@ export class ChunkConfigService {
       this.i18nService.formatMessage('configLoaded', { name: modelConfig.name, id: modelConfig.modelId }) + '\n' +
       `  - プロバイダー: ${providerName}\n` +
       `  - Token制限: ${maxInputTokens}\n` +
-      `  - バッチ制限: ${maxBatchSize}\n` +
-      `  - ベクトル次元: ${expectedDimensions}\n` +
+      `  - Batch Limit: ${maxBatchSize}\n` +
+      `  - Vector Dimensions: ${expectedDimensions}\n` +
       `  - ベクトルモデルか: ${isVectorModel}`,
     );
 
@@ -105,7 +105,7 @@ export class ChunkConfigService {
   }
 
   /**
-   * チャンク設定を検証および修正
+   * Chunk configurationを検証および修正
    * 優先順位: 環境変数の上限 > モデルの制限 > ユーザー設定
    */
   async validateChunkConfig(
@@ -135,7 +135,7 @@ export class ChunkConfigService {
       Math.floor(effectiveMaxChunkSize * this.DEFAULTS.maxOverlapRatio),
     );
 
-    // 2. チャンクサイズの上限を検証
+    // 2. Chunk sizeの上限を検証
     if (chunkSize > effectiveMaxChunkSize) {
       const reason =
         this.envMaxChunkSize < limits.maxInputTokens
@@ -152,7 +152,7 @@ export class ChunkConfigService {
       chunkSize = effectiveMaxChunkSize;
     }
 
-    // 3. チャンクサイズの下限を検証
+    // 3. Chunk sizeの下限を検証
     if (chunkSize < this.DEFAULTS.minChunkSize) {
       warnings.push(
         this.i18nService.formatMessage('chunkUnderflow', {
@@ -174,7 +174,7 @@ export class ChunkConfigService {
       chunkOverlap = effectiveMaxOverlapSize;
     }
 
-    // 5. 重なりサイズがチャンクサイズの50%を超えないことを検証
+    // 5. 重なりサイズがChunk sizeの50%を超えないことを検証
     const maxOverlapByRatio = Math.floor(
       chunkSize * this.DEFAULTS.maxOverlapRatio,
     );
@@ -198,7 +198,7 @@ export class ChunkConfigService {
       chunkOverlap = this.DEFAULTS.minChunkOverlap;
     }
 
-    // 6. バッチ処理の安全チェックを追加
+    // 6. バッチ処理の安全チェックをAdded
     // バッチ処理時、複数のテキストの合計長がモデルの制限を超えないようにする必要があります
     const safetyMargin = 0.8; // 80% 安全マージン、バッチ処理のためにスペースを確保
     const safeChunkSize = Math.floor(effectiveMaxChunkSize * safetyMargin);
@@ -311,16 +311,16 @@ export class ChunkConfigService {
     const limits = await this.getModelLimits(modelId, userId, tenantId);
 
     return [
-      `モデル: ${modelId}`,
-      `チャンクサイズ: ${chunkSize} tokens (制限: ${limits.maxInputTokens})`,
+      `Model: ${modelId}`,
+      `Chunk size: ${chunkSize} tokens (制限: ${limits.maxInputTokens})`,
       `重なりサイズ: ${chunkOverlap} tokens`,
       `バッチサイズ: ${limits.maxBatchSize}`,
-      `ベクトル次元: ${limits.expectedDimensions}`,
+      `Vector Dimensions: ${limits.expectedDimensions}`,
     ].join(', ');
   }
 
   /**
-   * フロントエンド用の設定制限を取得
+   * フロントエンド用のConfig limitsを取得
    * フロントエンドのスライダーの上限設定に使用
    */
   async getFrontendLimits(

+ 5 - 5
server/src/knowledge-base/embedding.service.ts

@@ -50,13 +50,13 @@ export class EmbeddingService {
       throw new Error(`モデル ${modelConfig.name} は無効化されているため、埋め込みベクトルを生成できません`);
     }
 
-    // APIキーはオプションです - ローカルモデルを許可します
+    // API key is optional - allow local models
 
     if (!modelConfig.baseUrl) {
       throw new Error(`モデル ${modelConfig.name} に baseUrl が設定されていません`);
     }
 
-    // モデル名に基づいて最大バッチサイズを決定
+    // Model nameに基づいて最大バッチサイズを決定
     const maxBatchSize = this.getMaxBatchSizeForModel(modelConfig.modelId, modelConfig.maxBatchSize);
 
     // バッチサイズが制限を超える場合は分割して処理
@@ -105,7 +105,7 @@ export class EmbeddingService {
       modelId.includes('text-embedding-ada-002')) {
       return Math.min(10, configuredMaxBatchSize || 100); // Googleの場合は10を上限
     } else if (modelId.includes('text-embedding-3') || modelId.includes('text-embedding-003')) {
-      return Math.min(2048, configuredMaxBatchSize || 2048); // OpenAI v3は2048が上限
+      return Math.min(2048, configuredMaxBatchSize || 2048); // OpenAI v3は2048 exceeds limit 
     } else {
       // デフォルトでは設定された最大バッチサイズか100の小さい方
       return Math.min(configuredMaxBatchSize || 100, 100);
@@ -191,10 +191,10 @@ export class EmbeddingService {
               `モデル制限: ${modelConfig.maxInputTokens || 8192} tokens`
             );
             throw new Error(
-              `テキスト長がモデルの制限を超えています。` +
+              `テキスト長がモデルの制限。` +
               `現在: ${texts.length} 個のテキストで計 ${totalLength} 文字、` +
               `モデル制限: ${modelConfig.maxInputTokens || 8192} tokens。` +
-              `アドバイス: チャンクサイズまたはバッチサイズを小さくしてください`
+              `アドバイス: Chunk sizeまたはバッチサイズを小さくしてください`
             );
           }
 

+ 2 - 2
server/src/knowledge-base/knowledge-base.controller.ts

@@ -131,8 +131,8 @@ export class KnowledgeBaseController {
 
 
   /**
-   * チャンク設定の制限を取得(フロントエンドのスライダー設定用)
-   * クエリパラメータ: embeddingModelId - 埋め込みモデルID
+   * Fetch chunk configuration limits(フロントエンドのスライダー設定用)
+   * クエリパラメータ: embeddingModelId - Embedding model ID
    */
   @Get('chunk-config/limits')
   async getChunkConfigLimits(

+ 3 - 3
server/src/knowledge-base/knowledge-base.entity.ts

@@ -20,8 +20,8 @@ export enum FileStatus {
 }
 
 export enum ProcessingMode {
-  FAST = 'fast',      // 高速モード - Tika を使用
-  PRECISE = 'precise', // 精密モード - Vision Pipeline を使用
+  FAST = 'fast',      // Fast Mode - Tika を使用
+  PRECISE = 'precise', // Precise Mode - Vision Pipeline を使用
 }
 
 @Entity('knowledge_bases')
@@ -83,7 +83,7 @@ export class KnowledgeBase {
   processingMode: ProcessingMode;
 
   @Column({ type: 'json', nullable: true })
-  metadata: any; // 追加のメタデータを保存(画像の説明、信頼度など)
+  metadata: any; // Addedのメタデータを保存(画像の説明、信頼度など)
 
   @Column({ name: 'pdf_path', nullable: true })
   pdfPath: string; // PDF ファイルパス(プレビュー用)

+ 14 - 14
server/src/knowledge-base/knowledge-base.service.ts

@@ -437,10 +437,10 @@ export class KnowledgeBaseService {
       const mode = config?.mode || 'fast';
 
       if (mode === 'precise') {
-        // 精密モード - Vision Pipeline を使用
+        // Precise Mode - Vision Pipeline を使用
         await this.processPreciseMode(kb, userId, tenantId, config);
       } else {
-        // 高速モード - Tika を使用
+        // Fast Mode - Tika を使用
         await this.processFastMode(kb, userId, tenantId, config);
       }
 
@@ -452,7 +452,7 @@ export class KnowledgeBaseService {
   }
 
   /**
-   * 高速モード処理(既存フロー)
+   * Fast Mode処理(既存フロー)
    */
   private async processFastMode(kb: KnowledgeBase, userId: string, tenantId: string, config?: any) {
     // 1. Tika を使用してテキストを抽出
@@ -508,10 +508,10 @@ export class KnowledgeBaseService {
   }
 
   /**
-   * 精密モード処理(新規フロー)
+   * Precise Mode処理(新規フロー)
    */
   private async processPreciseMode(kb: KnowledgeBase, userId: string, tenantId: string, config?: any) {
-    // 精密モードがサポートされているか確認
+    // Precise Modeがサポートされているか確認
     const preciseFormats = ['.pdf', '.doc', '.docx', '.ppt', '.pptx'];
     const ext = kb.originalName.toLowerCase().substring(kb.originalName.lastIndexOf('.'));
 
@@ -610,7 +610,7 @@ export class KnowledgeBaseService {
   }
 
   /**
-   * 精密モードの結果をインデックス
+   * Precise Modeの結果をインデックス
    */
   private async indexPreciseResults(
     kb: KnowledgeBase,
@@ -693,7 +693,7 @@ export class KnowledgeBaseService {
       format: 'jpeg',
     });
 
-    // 対応するページ番号の画像を見つける
+    // 対応するPage numberの画像を見つける
     const pageImage = result.images.find(img => img.pageIndex === pageIndex + 1);
     if (!pageImage) {
       throw new NotFoundException(this.i18nService.formatMessage('pageImageNotFoundDetail', { page: pageIndex + 1 }));
@@ -720,7 +720,7 @@ export class KnowledgeBaseService {
       );
 
       this.logger.debug(`File ${kbId}: Validating chunk config...`);
-      // 1. チャンク設定の検証と修正(モデルの制限と環境変数に基づく)
+      // 1. Chunk configurationの検証と修正(モデルの制限と環境変数に基づく)
       const validatedConfig = await this.chunkConfigService.validateChunkConfig(
         kb.chunkSize,
         kb.chunkOverlap,
@@ -874,8 +874,8 @@ export class KnowledgeBaseService {
             },
           );
         } catch (error) {
-          // コンテキスト長エラーを検出(日本語・中国語・英語に対応)
-          if (error.message && (error.message.includes('context length') || error.message.includes('コンテキスト長が上限を超えています') || error.message.includes('コンテキスト長が上限を超えています'))) {
+          // コンテキスト長エラーを検出(Japanese・中国語・英語に対応)
+          if (error.message && (error.message.includes('context length') || error.message.includes('コンテキスト長 exceeds limit ') || error.message.includes('コンテキスト長 exceeds limit '))) {
             this.logger.warn(this.i18nService.getMessage('contextLengthErrorFallback'));
 
             // 単一テキスト処理にダウングレード
@@ -975,8 +975,8 @@ export class KnowledgeBaseService {
               },
             );
           } catch (error) {
-            // コンテキスト長エラーを検出(日本語・中国語・英語に対応)
-            if (error.message && (error.message.includes('context length') || error.message.includes('コンテキスト長が上限を超えています') || error.message.includes('コンテキスト長が上限を超えています'))) {
+            // コンテキスト長エラーを検出(Japanese・中国語・英語に対応)
+            if (error.message && (error.message.includes('context length') || error.message.includes('コンテキスト長 exceeds limit ') || error.message.includes('コンテキスト長 exceeds limit '))) {
               this.logger.warn(this.i18nService.getMessage('batchContextLengthErrorFallback'));
 
               // 単一テキスト処理にダウングレード
@@ -1063,8 +1063,8 @@ export class KnowledgeBaseService {
               );
             }
           } catch (error) {
-            // コンテキスト長エラーを検出(日本語・中国語・英語に対応)
-            if (error.message && (error.message.includes('context length') || error.message.includes('コンテキスト長が上限を超えています') || error.message.includes('コンテキスト長が上限を超えています'))) {
+            // コンテキスト長エラーを検出(Japanese・中国語・英語に対応)
+            if (error.message && (error.message.includes('context length') || error.message.includes('コンテキスト長 exceeds limit ') || error.message.includes('コンテキスト長 exceeds limit '))) {
               this.logger.warn(this.i18nService.getMessage('batchContextLengthErrorFallback'));
 
               // 単一テキスト処理にダウングレード

+ 2 - 2
server/src/knowledge-base/memory-monitor.service.ts

@@ -39,7 +39,7 @@ export class MemoryMonitorService {
   }
 
   /**
-   * メモリが上限に近づいているかチェック
+   * メモリ exceeds limit に近づいているかチェック
    */
   isMemoryHigh(): boolean {
     const usage = this.getMemoryUsage();
@@ -189,7 +189,7 @@ export class MemoryMonitorService {
     // ベクトルメモリ (各ベクトル: 次元 × 4バイト)
     const vectorMemory = itemCount * vectorDim * 4;
 
-    // オブジェクトのオーバーヘッド (各オブジェクトにつき追加で約100バイトと推定)
+    // オブジェクトのオーバーヘッド (各オブジェクトにつきAddedで約100バイトと推定)
     const overhead = itemCount * 100;
 
     const totalMB = Math.round((textMemory + vectorMemory + overhead) / 1024 / 1024);

+ 1 - 1
server/src/knowledge-base/text-chunker.service.ts

@@ -22,7 +22,7 @@ export class TextChunkerService {
     const chunkSizeInChars = chunkSize * 4; // 1 token ≈ 4 chars
     const overlapInChars = overlap * 4;
 
-    // テキスト長がチャンクサイズ以下の場合は、テキスト全体を1つのチャンクとして直接返す
+    // テキスト長がChunk size以下の場合は、テキスト全体を1つのチャンクとして直接返す
     if (cleanText.length <= chunkSizeInChars) {
       return [
         {

+ 1 - 1
server/src/migrations/1737800000000-AddKnowledgeBaseEnhancements.ts

@@ -54,7 +54,7 @@ export class AddKnowledgeBaseEnhancements1737800000000 implements MigrationInter
       )
     `);
 
-    // knowledge_base テーブルに pdf_path フィールドを追加
+    // knowledge_base テーブルに pdf_path フィールドをAdded
     await queryRunner.query(`
       ALTER TABLE "knowledge_base" ADD COLUMN "pdf_path" varchar
     `);

+ 2 - 2
server/src/model-config/dto/create-model-config.dto.ts

@@ -28,7 +28,7 @@ export class CreateModelConfigDto {
 
   @IsString()
   @IsOptional()
-  apiKey?: string; // APIキーはオプションです - ローカルモデルを許可します
+  apiKey?: string; // API key is optional - allow local models
 
   @IsEnum(ModelType)
   @IsNotEmpty()
@@ -40,7 +40,7 @@ export class CreateModelConfigDto {
   @IsOptional()
   dimensions?: number;
 
-  // ==================== 追加フィールド ====================
+  // ==================== Addedフィールド ====================
 
   /**
    * モデルの入力トークン制限(embedding/rerank にのみ有効)

+ 1 - 1
server/src/model-config/model-config.entity.ts

@@ -33,7 +33,7 @@ export class ModelConfig {
   @Column({ type: 'integer', nullable: true })
   dimensions?: number; // 埋め込みモデルの次元、システムによって自動的に検出され保存されます
 
-  // ==================== 追加フィールド ====================
+  // ==================== Addedフィールド ====================
   // 以下字段仅对 embedding/rerank 模型有意义
 
   /**

+ 4 - 4
server/src/rag/rag.service.ts

@@ -89,9 +89,9 @@ export class RagService {
         queriesToSearch = [...new Set([query, ...expanded])];
       }
 
-      // 埋め込みモデルIDが提供されているか確認
+      // Embedding model IDが提供されているか確認
       if (!effectiveEmbeddingId) {
-        throw new Error('埋め込みモデルIDが提供されていません');
+        throw new Error('Embedding model IDが提供されていません');
       }
 
       // 2. 複数のクエリに対して並列検索
@@ -243,7 +243,7 @@ export class RagService {
     }
 
     const langText =
-      lang === 'zh' ? '中文' : lang === 'en' ? 'English' : '日本語';
+      lang === 'zh' ? 'Chinese' : lang === 'en' ? 'English' : 'Japanese';
 
     const systemPrompt = this.i18nService.getMessage('ragSystemPrompt', lang);
     const rules = this.i18nService.formatMessage('ragRules', { lang: langText }, lang);
@@ -273,7 +273,7 @@ ${answerHeader}`;
   }
 
   /**
-   * 検索結果の重複排除
+   * Search resultsの重複排除
    */
   private deduplicateResults(results: any[]): any[] {
     const unique = new Map<string, any>();

+ 1 - 1
server/src/upload/upload.controller.ts

@@ -153,7 +153,7 @@ export class UploadController {
       groupIds: config.groupIds ? JSON.parse(config.groupIds) : [],
     };
 
-    // オーバーラップサイズがチャンクサイズの50%を超えないようにする
+    // オーバーラップサイズがChunk sizeの50%を超えないようにする
     if (indexingConfig.chunkOverlap > indexingConfig.chunkSize * DEFAULT_MAX_OVERLAP_RATIO) {
       indexingConfig.chunkOverlap = Math.floor(indexingConfig.chunkSize * DEFAULT_MAX_OVERLAP_RATIO);
       this.logger.warn(

+ 10 - 10
server/src/vision-pipeline/vision-pipeline-cost-aware.service.ts

@@ -31,7 +31,7 @@ export class VisionPipelineCostAwareService {
   ) { }
 
   /**
-   * メイン処理フロー:精密モード(コスト制御付き)
+   * メイン処理フロー:Precise Mode(コスト制御付き)
    */
   async processPreciseMode(
     filePath: string,
@@ -100,7 +100,7 @@ export class VisionPipelineCostAwareService {
       const modelConfig = await this.getVisionModelConfig(options.userId, options.modelId, options.tenantId);
 
       // ステップ 5: VL モデル分析
-      this.updateStatus('analyzing', 50, 'ビジョンモデルを使用してページを分析中...');
+      this.updateStatus('analyzing', 50, 'ビジョンモデルを使用してページをAnalyzing...');
       const batchResult = await this.vision.batchAnalyze(
         imagesToProcess.map(img => img.path),
         modelConfig,
@@ -191,7 +191,7 @@ export class VisionPipelineCostAwareService {
       throw new Error(`モデル設定が見つかりません: ${modelId}`);
     }
 
-    // APIキーはオプションです - ローカルモデルを許可します
+    // API key is optional - allow local models
 
     return {
       baseUrl: config.baseUrl || '',
@@ -230,15 +230,15 @@ export class VisionPipelineCostAwareService {
       return {
         recommendedMode: 'fast',
         reason: `サポートされていないファイル形式です: ${ext}`,
-        warnings: ['高速モード(テキスト抽出のみ)を使用します'],
+        warnings: ['Fast Mode(テキスト抽出のみ)を使用します'],
       };
     }
 
     if (!preciseFormats.includes(ext)) {
       return {
         recommendedMode: 'fast',
-        reason: `形式 ${ext} は精密モードをサポートしていません`,
-        warnings: ['高速モード(テキスト抽出のみ)を使用します'],
+        reason: `形式 ${ext} はPrecise Modeをサポートしていません`,
+        warnings: ['Fast Mode(テキスト抽出のみ)を使用します'],
       };
     }
 
@@ -246,21 +246,21 @@ export class VisionPipelineCostAwareService {
     const estimatedPages = Math.max(1, Math.ceil(sizeMB * 2));
     const costEstimate = this.costControl.estimateCost(estimatedPages);
 
-    // ファイルサイズが大きい場合は精密モードを推奨
+    // ファイルサイズが大きい場合はPrecise Modeを推奨
     if (sizeMB > 50) {
       return {
         recommendedMode: 'precise',
-        reason: 'ファイルが大きいため、完全な情報を保持するために精密モードを推奨します',
+        reason: 'ファイルが大きいため、完全な情報を保持するためにPrecise Modeを推奨します',
         estimatedCost: costEstimate.estimatedCost,
         estimatedTime: costEstimate.estimatedTime,
         warnings: ['処理時間が長くなる可能性があります', 'API 費用が発生します'],
       };
     }
 
-    // 精密モードを推奨
+    // Precise Modeを推奨
     return {
       recommendedMode: 'precise',
-      reason: '精密モードが利用可能です。テキストと画像の混合コンテンツを保持できます',
+      reason: 'Precise Modeが利用可能です。テキストと画像の混合コンテンツを保持できます',
       estimatedCost: costEstimate.estimatedCost,
       estimatedTime: costEstimate.estimatedTime,
       warnings: ['API 費用が発生します'],

+ 1 - 1
server/src/vision/vision.service.ts

@@ -151,7 +151,7 @@ export class VisionService {
       return true;
     }
 
-    // 5xx サーバーエラー
+    // 5xx Server error
     if (errorCode >= 500 && errorCode < 600) {
       return true;
     }

+ 19 - 19
web/components/ChatInterface.tsx

@@ -70,8 +70,8 @@ const ChatInterface: React.FC<ChatInterfaceProps> = ({
   //   matchedFiles: files.filter(f => selectedFiles?.includes(f.id)).map(f => f.name)
   // });
 
-  // 履歴メッセージの読み込みを処理
-  // 履歴メッセージの読み込みを処理
+  // Handle loading of history messages
+  // Handle loading of history messages
   useEffect(() => {
     if (historyMessages && historyMessages.length > 0) {
       const convertedMessages: Message[] = historyMessages.map(msg => ({
@@ -84,7 +84,7 @@ const ChatInterface: React.FC<ChatInterfaceProps> = ({
 
       setMessages(convertedMessages);
 
-      // 履歴メッセージが読み込まれたことを親コンポーネントに通知
+      // Notify parent component that history messages have been loaded
       onHistoryMessagesLoaded?.();
     }
   }, [historyMessages, onHistoryMessagesLoaded]);
@@ -125,7 +125,7 @@ const ChatInterface: React.FC<ChatInterfaceProps> = ({
   const handleSend = async () => {
     if (!input.trim() || isLoading) return;
 
-    // デバウンス機構:500ms以内の重複送信を防止
+    // Debounce mechanism: prevent duplicate submissions within 500ms
     const now = Date.now();
     if (now - lastSubmitTime.current < 500) {
       console.log('Preventing duplicate submission');
@@ -135,11 +135,11 @@ const ChatInterface: React.FC<ChatInterfaceProps> = ({
 
     const userText = input.trim();
 
-    // 入力欄を即座にクリアして高さをリセットし、重複送信を防止
+    // Instantly clear input field and reset height to prevent duplicate submission
     setInput('');
     if (inputRef.current) {
       inputRef.current.style.height = 'auto';
-      inputRef.current.blur(); // フォーカスを外す
+      inputRef.current.blur(); // Remove focus
     }
 
     // Resolve Model Config
@@ -192,7 +192,7 @@ const ChatInterface: React.FC<ChatInterfaceProps> = ({
       const botMessageId = generateUUID();
       let botContent = '';
 
-      // 初期ボットメッセージを追加
+      // Add initial bot message
       const botMessage: Message = {
         id: botMessageId,
         role: Role.MODEL,
@@ -208,18 +208,18 @@ const ChatInterface: React.FC<ChatInterfaceProps> = ({
         language,
         settings.selectedEmbeddingId,
         settings.selectedLLMId, // Pass selected LLM ID
-        selectedGroups.length > 0 ? selectedGroups : undefined, // グループフィルタを渡す
-        selectedFiles?.length > 0 ? selectedFiles : undefined, // ファイルフィルタを渡す
-        currentHistoryId, // 履歴IDを渡す
-        settings.enableRerank, // Rerankスイッチを渡す
-        settings.selectedRerankId, // RerankモデルIDを渡す
-        settings.temperature, // 温度パラメータを渡す
-        settings.maxTokens, // 最大トークン数を渡す
-        settings.topK, // Top-Kパラメータを渡す
-        settings.similarityThreshold, // 類似度しきい値を渡す
-        settings.rerankSimilarityThreshold, // Rerankしきい値を渡す
-        settings.enableQueryExpansion, // クエリ拡張を渡す
-        settings.enableHyDE // HyDEを渡す
+        selectedGroups.length > 0 ? selectedGroups : undefined, // Pass group filter
+        selectedFiles?.length > 0 ? selectedFiles : undefined, // Pass file filter
+        currentHistoryId, // Pass history ID
+        settings.enableRerank, // Pass Rerank switch
+        settings.selectedRerankId, // Pass Rerank model ID
+        settings.temperature, // Pass temperature parameter
+        settings.maxTokens, // Pass max tokens
+        settings.topK, // Pass Top-K parameter
+        settings.similarityThreshold, // Pass similarity threshold
+        settings.rerankSimilarityThreshold, // Pass Rerank threshold
+        settings.enableQueryExpansion, // Pass query expansion
+        settings.enableHyDE // Pass HyDE
       );
 
       for await (const chunk of stream) {

+ 2 - 2
web/components/CreateNoteFromPDFDialog.tsx

@@ -61,9 +61,9 @@ export const CreateNoteFromPDFDialog: React.FC<CreateNoteFromPDFDialogProps> = (
     }, [screenshot, extractedText, authToken]);
 
     const handleSave = async () => {
-        // ナレッジグループが選択されているか確認
+        // Check if knowledge group is selected
         if (!selectedGroupId) {
-            showToast('warning', t('pleaseSelectKnowledgeGroupFirst')); // 使用 toast 提示用户先选择知识组
+            showToast('warning', t('pleaseSelectKnowledgeGroupFirst')); // Use toast to prompt user to select a knowledge group first
             return;
         }
 

+ 2 - 2
web/components/FileGroupTags.tsx

@@ -25,7 +25,7 @@ export const FileGroupTags: React.FC<FileGroupTagsProps> = ({
   const [loading, setLoading] = useState(false);
   const { showToast } = useToast();
 
-  // カスタムイベントを監視してグループセレクターを開く
+  // Monitor custom events to open group selector
   React.useEffect(() => {
     const handleOpenGroupSelector = (event: CustomEvent) => {
       if (event.detail.fileId === fileId) {
@@ -44,7 +44,7 @@ export const FileGroupTags: React.FC<FileGroupTagsProps> = ({
 
     setLoading(true);
     try {
-      // 正しい方法:すべてのグループID(既存 + 新規)を渡す
+      // Correct method: pass all group IDs (existing + new)
       const newGroupIds = [...assignedGroups, groupId];
       await knowledgeGroupService.addFileToGroups(fileId, newGroupIds);
       onGroupsChange(newGroupIds);

+ 5 - 5
web/components/GroupManager.tsx

@@ -104,7 +104,7 @@ export const GroupManager: React.FC<GroupManagerProps> = ({ groups, onGroupsChan
 
   return (
     <div className="space-y-4">
-      {/* 分组列表 */}
+      {/* Group list */}
       <div className="space-y-2">
         {groups.map((group) => (
           <div
@@ -122,7 +122,7 @@ export const GroupManager: React.FC<GroupManagerProps> = ({ groups, onGroupsChan
                   <div className="text-sm text-gray-500">{group.description}</div>
                 )}
                 <div className="text-xs text-gray-400">
-                  {group.fileCount} 个文件
+                  {group.fileCount}  files
                 </div>
               </div>
             </div>
@@ -144,7 +144,7 @@ export const GroupManager: React.FC<GroupManagerProps> = ({ groups, onGroupsChan
         ))}
       </div>
 
-      {/* 创建按钮 */}
+      {/* Create button */}
       <button
         onClick={() => setIsCreateModalOpen(true)}
         className="w-full flex items-center justify-center p-2 border-2 border-dashed border-gray-300 rounded-lg text-gray-500 hover:border-blue-400 hover:text-blue-600 transition-colors"
@@ -153,7 +153,7 @@ export const GroupManager: React.FC<GroupManagerProps> = ({ groups, onGroupsChan
         <Plus size={18} />
       </button>
 
-      {/* 创建/编辑模态框 */}
+      {/* Create/Edit modal */}
       {isModalOpen && (
         <div className="fixed inset-0 bg-black/50 backdrop-blur-sm flex items-center justify-center z-50">
           <div className="bg-white rounded-lg p-6 w-full max-w-md">
@@ -199,7 +199,7 @@ export const GroupManager: React.FC<GroupManagerProps> = ({ groups, onGroupsChan
 
               <div>
                 <label className="block text-sm font-medium text-gray-700 mb-2">
-                  颜色标识
+                  Color indicator
                 </label>
                 <div className="flex space-x-2">
                   {DEFAULT_COLORS.map((color) => (

+ 1 - 1
web/components/GroupSelectionDrawer.tsx

@@ -111,7 +111,7 @@ export const GroupSelectionDrawer: React.FC<GroupSelectionDrawerProps> = ({
                                             {group.name}
                                         </div>
                                         <div className={`text-xs mt-0.5 transition-colors ${isSelected ? 'text-blue-500/80' : 'text-slate-400'}`}>
-                                            {group.fileCount} 个文件
+                                            {group.fileCount}  files
                                         </div>
                                     </div>
                                 </div>

+ 6 - 6
web/components/GroupSelector.tsx

@@ -18,7 +18,7 @@ export const GroupSelector: React.FC<GroupSelectorProps> = ({
   selectedGroups,
   onSelectionChange,
   showSelectAll = true,
-  placeholder = '选择分组范围',
+  placeholder = 'Select group scope',
   minimal = false,
   direction = 'bottom'
 }) => {
@@ -67,11 +67,11 @@ export const GroupSelector: React.FC<GroupSelectorProps> = ({
   // Optimized display logic
   let selectedGroupNames = '';
   if (selectedGroups.length === 0) {
-    selectedGroupNames = '全部分组';
+    selectedGroupNames = 'All groups';
   } else if (selectedGroups.length <= 2) {
     selectedGroupNames = selectedGroups.map(id => groups.find(g => g.id === id)?.name).filter(Boolean).join(', ');
   } else {
-    selectedGroupNames = `已选 ${selectedGroups.length} 个分组`;
+    selectedGroupNames = `Selected ${selectedGroups.length} groups`;
   }
 
   const handleToggleGroup = (groupId: string) => {
@@ -115,7 +115,7 @@ export const GroupSelector: React.FC<GroupSelectorProps> = ({
                 <input
                   ref={searchInputRef}
                   type="text"
-                  placeholder="搜索分组..."
+                  placeholder="Search groups..."
                   value={searchTerm}
                   onChange={(e) => setSearchTerm(e.target.value)}
                   className="w-full pl-8 pr-3 py-1.5 text-sm border border-gray-200 rounded-md focus:outline-none focus:border-blue-500 focus:ring-1 focus:ring-blue-500 bg-gray-50"
@@ -135,7 +135,7 @@ export const GroupSelector: React.FC<GroupSelectorProps> = ({
                     } `}>
                     {isAllSelected && <Check size={12} className="text-white" />}
                   </div>
-                  <span className="font-medium text-sm">全部分组</span>
+                  <span className="font-medium text-sm">All groups</span>
                 </div>
               )}
 
@@ -171,7 +171,7 @@ export const GroupSelector: React.FC<GroupSelectorProps> = ({
 
                 {filteredGroups.length === 0 && (
                   <div className="px-3 py-6 text-center text-gray-400 text-xs">
-                    {searchTerm ? '未找到相关分组' : '暂无分组'}
+                    {searchTerm ? 'No related groups found' : 'No groups'}
                   </div>
                 )}
               </div>

+ 2 - 2
web/components/IndexingModalWithMode.tsx

@@ -384,7 +384,7 @@ const IndexingModalWithMode: React.FC<IndexingModalWithModeProps> = ({
                 <button
                   onClick={() => {
                     setMode('fast');
-                    setUserSelectedMode(true); // ユーザーによる手動選択をマーク
+                    setUserSelectedMode(true); // Mark manual selection by user
                   }}
                   className={`relative p-3 rounded-lg border-2 text-left transition-all ${mode === 'fast'
                     ? 'border-blue-500 bg-blue-50'
@@ -409,7 +409,7 @@ const IndexingModalWithMode: React.FC<IndexingModalWithModeProps> = ({
                 <button
                   onClick={() => {
                     setMode('precise');
-                    setUserSelectedMode(true); // ユーザーによる手動選択をマーク
+                    setUserSelectedMode(true); // Mark manual selection by user
                   }}
                   className={`relative p-3 rounded-lg border-2 text-left transition-all ${mode === 'precise'
                     ? 'border-purple-500 bg-purple-50'

+ 2 - 2
web/components/InputDrawer.tsx

@@ -19,7 +19,7 @@ export const InputDrawer: React.FC<InputDrawerProps> = ({
     onSubmit,
     placeholder = '',
     defaultValue = '',
-    submitLabel = '确定'
+    submitLabel = 'Confirm'
 }) => {
     const [value, setValue] = useState(defaultValue);
     const inputRef = useRef<HTMLInputElement>(null);
@@ -77,7 +77,7 @@ export const InputDrawer: React.FC<InputDrawerProps> = ({
                                 onClick={onClose}
                                 className="px-4 py-2 text-sm font-medium text-gray-700 bg-white border border-gray-300 rounded-lg hover:bg-gray-50"
                             >
-                                取消
+                                Cancel
                             </button>
                             <button
                                 type="submit"

+ 20 - 20
web/components/ModeSelector.tsx

@@ -1,6 +1,6 @@
 /**
- * 処理モード選択コンポーネント
- * ファイルアップロード時に高速モードまたは精密モードを選択するために使用
+ * Processing mode selection component
+ * Used to select fast or precise mode when uploading files
  */
 
 import React, { useState, useEffect } from 'react';
@@ -38,7 +38,7 @@ export const ModeSelector: React.FC<ModeSelectorProps> = ({
       const rec = await uploadService.recommendMode(file);
       setRecommendation(rec);
 
-      // 推薦されたモードを自動選択
+      // Automatically select recommended mode
       setSelectedMode(rec.recommendedMode);
       onModeChange(rec.recommendedMode);
     } catch (error) {
@@ -60,15 +60,15 @@ export const ModeSelector: React.FC<ModeSelectorProps> = ({
   return (
     <div className={`mode-selector ${className}`}>
       <div className="mode-selector-header">
-        <h4>処理モードの選択</h4>
-        {loading && <span className="loading">分析中...</span>}
+        <h4>Select processing mode</h4>
+        {loading && <span className="loading">Analyzing...</span>}
       </div>
 
-      {/* 模式推荐信息 */}
+      {/* Mode recommendation info */}
       {recommendation && (
         <div className="recommendation-info">
           <div className="reason">
-            <strong>推奨:</strong> {recommendation.reason}
+            <strong>Recommended:</strong> {recommendation.reason}
           </div>
 
           {recommendation.warnings && recommendation.warnings.length > 0 && (
@@ -83,7 +83,7 @@ export const ModeSelector: React.FC<ModeSelectorProps> = ({
         </div>
       )}
 
-      {/* 模式选择 */}
+      {/* Mode selection */}
       <div className="mode-options">
         <label className={`mode-option ${selectedMode === 'fast' ? 'selected' : ''}`}>
           <input
@@ -94,14 +94,14 @@ export const ModeSelector: React.FC<ModeSelectorProps> = ({
             onChange={() => handleModeChange('fast')}
           />
           <div className="mode-content">
-            <div className="mode-title">⚡ 高速モード</div>
+            <div className="mode-title">⚡ Fast Mode</div>
             <div className="mode-desc">
-              テキストを単純に抽出、高速、プレーンテキストドキュメントに最適
+              Simple text extraction, fast, ideal for plain text documents
             </div>
             <div className="mode-benefits">
-              ✅ 高速<br />
-              ✅ 追加コストなし<br />
-              ❌ テキスト情報のみ処理
+              ✅ Fast<br />
+              ✅ No additional cost<br />
+              ❌ Processes text information only
             </div>
           </div>
         </label>
@@ -115,16 +115,16 @@ export const ModeSelector: React.FC<ModeSelectorProps> = ({
             onChange={() => handleModeChange('precise')}
           />
           <div className="mode-content">
-            <div className="mode-title">🎯 精密モード</div>
+            <div className="mode-title">🎯 Precise Mode</div>
             <div className="mode-desc">
-              内容を正確に認識し、完全な情報を保持
+              Accurately recognizes content and retains full information
             </div>
             <div className="mode-benefits">
-              ✅ 画像/表を認識<br />
-              ✅ レイアウト情報を保持<br />
-              ✅ 図文混合コンテンツ<br />
-              ⚠️ API費用が必要<br />
-              ⚠️ 処理時間が長い
+              ✅ Recognizes images/tables<br />
+              ✅ Retains layout information<br />
+              ✅ Mixed image and text content<br />
+              ⚠️ API cost required<br />
+              ⚠️ Long processing time
             </div>
           </div>
         </label>

+ 20 - 20
web/components/PDFPreview.tsx

@@ -35,8 +35,8 @@ export const PDFPreview: React.FC<PDFPreviewProps> = ({ fileId, fileName, authTo
   const [selectionData, setSelectionData] = useState<{ screenshot: Blob; text: string } | null>(null);
   const [numPages, setNumPages] = useState<number>(0);
   const [pdfDoc, setPdfDoc] = useState<pdfjs.PDFDocumentProxy | null>(null);
-  const [zoomLevel, setZoomLevel] = useState<number>(1.0); // ズームレベルの状態を追加
-  const currentRenderTask = useRef<pdfjs.RenderTask | null>(null); // 現在のレンダリングタスクを保存
+  const [zoomLevel, setZoomLevel] = useState<number>(1.0); // Add zoom level state
+  const currentRenderTask = useRef<pdfjs.RenderTask | null>(null); // Save current rendering task
   const scrollContainerRef = useRef<HTMLDivElement>(null);
   const flipDirection = useRef<'next' | 'prev' | null>(null);
   const lastFlipTime = useRef<number>(0);
@@ -51,9 +51,9 @@ export const PDFPreview: React.FC<PDFPreviewProps> = ({ fileId, fileName, authTo
     if (status.status === 'ready') {
       pdfPreviewService.getPDFUrl(fileId)
         .then(result => {
-          setPdfUrl(result.url); // ダウンロード用にpdfUrlを設定
+          setPdfUrl(result.url); // Set pdfUrl for download
 
-          // PDFデータを取得してblob URLを作成
+          // Fetch PDF data and create blob URL
           fetch(result.url)
             .then(async response => {
               if (!response.ok) {
@@ -65,7 +65,7 @@ export const PDFPreview: React.FC<PDFPreviewProps> = ({ fileId, fileName, authTo
             .then(blob => {
               setPdfBlob(blob);
 
-              // PDF文書の読み込みとレンダリングを開始
+              // Start fetching and rendering PDF document
               loadAndRenderPDF(blob);
             })
             .catch((err) => {
@@ -84,7 +84,7 @@ export const PDFPreview: React.FC<PDFPreviewProps> = ({ fileId, fileName, authTo
 
   useEffect(() => {
     if (pdfDoc && currentPage) {
-      // ページ切り替えまたはズームレベル変更時に再レンダリング
+      // Re-render on page change or zoom level change
       renderCurrentPage(pdfDoc, currentPage);
     }
   }, [currentPage, pdfDoc, zoomLevel]);
@@ -107,11 +107,11 @@ export const PDFPreview: React.FC<PDFPreviewProps> = ({ fileId, fileName, authTo
       const pdfStatus = await pdfPreviewService.getPDFStatus(fileId);
       setStatus(pdfStatus);
 
-      // ステータスがpendingの場合、変換を能動的にトリガー
+      // Actively trigger conversion if status is pending
       if (pdfStatus.status === 'pending') {
         setStatus({ status: 'converting' });
         try {
-          // PDF URLにアクセスして変換をトリガー
+          // Access PDF URL to trigger conversion
           await pdfPreviewService.preloadPDF(fileId);
         } catch (error) {
           console.log('Preload triggered, conversion should start');
@@ -164,7 +164,7 @@ export const PDFPreview: React.FC<PDFPreviewProps> = ({ fileId, fileName, authTo
     if (!canvasRef.current) return;
 
     try {
-      // 進行中のレンダリングタスクが存在する場合、キャンセルする
+      // Cancel rendering task if one is in progress
       if (currentRenderTask.current) {
         currentRenderTask.current.cancel();
       }
@@ -231,7 +231,7 @@ export const PDFPreview: React.FC<PDFPreviewProps> = ({ fileId, fileName, authTo
       // Clear the current render task
       currentRenderTask.current = null;
 
-      // ページめくり後のスクロール位置調整
+      // Adjust scroll position after page turn
       if (flipDirection.current && scrollContainerRef.current) {
         const container = scrollContainerRef.current;
         if (flipDirection.current === 'next') {
@@ -256,7 +256,7 @@ export const PDFPreview: React.FC<PDFPreviewProps> = ({ fileId, fileName, authTo
 
   const handleDownload = () => {
     if (pdfUrl) {
-      // pdfUrlが既にある場合、直接ダウンロード
+      // Directly download if pdfUrl already exists
       const link = document.createElement('a');
       link.href = pdfUrl;
       link.download = fileName.replace(/\.[^/.]+$/, '.pdf');
@@ -264,7 +264,7 @@ export const PDFPreview: React.FC<PDFPreviewProps> = ({ fileId, fileName, authTo
       link.click();
       document.body.removeChild(link);
     } else {
-      // pdfUrlがない場合、直接取得してダウンロードを試みる
+      // Try fetching and downloading if pdfUrl does not exist
       pdfPreviewService.getPDFUrl(fileId)
         .then(result => {
           const link = document.createElement('a');
@@ -285,7 +285,7 @@ export const PDFPreview: React.FC<PDFPreviewProps> = ({ fileId, fileName, authTo
     if (pdfUrl) {
       window.open(pdfUrl, '_blank');
     } else {
-      // pdfUrlがない場合、直接取得して開くことを試みる
+      // Try fetching and opening if pdfUrl does not exist
       pdfPreviewService.getPDFUrl(fileId)
         .then(result => {
           window.open(result.url, '_blank');
@@ -303,7 +303,7 @@ export const PDFPreview: React.FC<PDFPreviewProps> = ({ fileId, fileName, authTo
       setLoading(true);
       try {
         await pdfPreviewService.preloadPDF(fileId, true);
-        // 状態をリセットして再読み込みをトリガー
+        // Reset state and trigger reload
         setPdfUrl('');
         setIframeError(false);
         setPdfDoc(null);
@@ -326,9 +326,9 @@ export const PDFPreview: React.FC<PDFPreviewProps> = ({ fileId, fileName, authTo
     const container = scrollContainerRef.current;
     const { scrollTop, scrollHeight, clientHeight } = container;
     const now = Date.now();
-    const throttleMs = 600; // 連続ページめくりを防止
+    const throttleMs = 600; // Prevent rapid page turning
 
-    // 下にスクロールして次のページへ
+    // Scroll down for next page
     if (e.deltaY > 0 && scrollTop + clientHeight >= scrollHeight - 1) {
       if (currentPage < numPages && now - lastFlipTime.current > throttleMs) {
         flipDirection.current = 'next';
@@ -336,7 +336,7 @@ export const PDFPreview: React.FC<PDFPreviewProps> = ({ fileId, fileName, authTo
         setCurrentPage(prev => prev + 1);
       }
     }
-    // 上にスクロールして前のページへ
+    // Scroll up for previous page
     else if (e.deltaY < 0 && scrollTop <= 1) {
       if (currentPage > 1 && now - lastFlipTime.current > throttleMs) {
         flipDirection.current = 'prev';
@@ -553,7 +553,7 @@ export const PDFPreview: React.FC<PDFPreviewProps> = ({ fileId, fileName, authTo
       }`}>
       <div className={`bg-white rounded-lg overflow-hidden flex flex-col ${isFullscreen ? 'w-full h-full' : 'w-full max-w-4xl h-5/6'
         }`}>
-        {/* 头部 */}
+        {/* Header */}
         <div className="flex items-center justify-between p-4 border-b bg-gray-50">
           <div className="flex items-center space-x-3">
             <FileText size={20} className="text-gray-600" />
@@ -627,7 +627,7 @@ export const PDFPreview: React.FC<PDFPreviewProps> = ({ fileId, fileName, authTo
           </div>
         </div>
 
-        {/* 内容区域 */}
+        {/* Content Area */}
         <div className="flex-1 h-full">
           {renderContent()}
         </div>
@@ -665,7 +665,7 @@ export const PDFPreviewButton: React.FC<PDFPreviewButtonProps> = ({
       const pdfStatus = await pdfPreviewService.getPDFStatus(fileId);
       setStatus(pdfStatus);
     } catch (error) {
-      // エラーを無視し、デフォルト状態を使用
+      // Ignore error and use default state
     } finally {
       setLoading(false);
     }

+ 3 - 3
web/components/PDFSelectionTool.tsx

@@ -117,7 +117,7 @@ interface PDFSelectionToolProps {
     pdfBlob: Blob | null;
     pageNumber: number;
     authToken: string;
-    zoomLevel?: number;  // オプションのズームレベルパラメータ
+    zoomLevel?: number;  // Optional zoom level parameter
 }
 
 export const PDFSelectionTool: React.FC<PDFSelectionToolProps> = ({
@@ -128,7 +128,7 @@ export const PDFSelectionTool: React.FC<PDFSelectionToolProps> = ({
     pdfBlob,
     pageNumber,
     authToken,
-    zoomLevel = 1.0,  // デフォルトのズームレベルは1.0
+    zoomLevel = 1.0,  // Default zoom level is 1.0
 }) => {
     const { t } = useLanguage();
     const [isSelecting, setIsSelecting] = useState(false);
@@ -151,7 +151,7 @@ export const PDFSelectionTool: React.FC<PDFSelectionToolProps> = ({
         if (!containerRef.current || !pdfBlob) return;
 
         const rect = containerRef.current.getBoundingClientRect();
-        // コンテナに対する実際の座標を使用
+        // Use actual coordinates relative to container
         const x = e.clientX - rect.left;
         const y = e.clientY - rect.top;
 

+ 5 - 5
web/components/SettingsModal.tsx

@@ -232,7 +232,7 @@ export const SettingsModal: React.FC<SettingsModalProps> = ({
         setIsLoading(true);
         try {
             await modelConfigService.setDefault(authToken, id);
-            // モデル一覧を再取得するためにページをリロード
+            // Reload page to fetch model list again
             window.location.reload();
         } catch (err: any) {
             setError(err.message || t('defaultSettingFailed'));
@@ -253,7 +253,7 @@ export const SettingsModal: React.FC<SettingsModalProps> = ({
 
     const renderGeneralTab = () => (
         <div className="space-y-8 animate-in slide-in-from-right duration-300">
-            {/* 言語セクション */}
+            {/* Language section */}
             <section>
                 <h3 className="text-sm font-medium text-slate-500 mb-3 flex items-center gap-2">
                     <Globe className="w-4 h-4" />
@@ -270,7 +270,7 @@ export const SettingsModal: React.FC<SettingsModalProps> = ({
                                 : 'bg-white border-slate-200 text-slate-600 hover:bg-slate-50'
                                 }`}
                         >
-                            {lang === 'zh' ? '中文' : lang === 'en' ? 'English' : '日本語'}
+                            {lang === 'zh' ? 'Chinese' : lang === 'en' ? 'English' : 'Japanese'}
                         </button>
                     ))}
                 </div>
@@ -495,7 +495,7 @@ export const SettingsModal: React.FC<SettingsModalProps> = ({
     return (
         <div className="fixed inset-0 z-[60] flex items-center justify-center bg-black/50 backdrop-blur-sm p-4 animate-in fade-in duration-200">
             <div className="bg-white rounded-xl shadow-2xl w-full max-w-4xl h-[80vh] flex overflow-hidden">
-                {/* サイドバー */}
+                {/* Sidebar */}
                 <div className="w-64 bg-slate-50 border-r border-slate-200 flex flex-col">
                     <div className="p-6">
                         <h2 className="text-xl font-bold text-slate-800 flex items-center gap-2">
@@ -519,7 +519,7 @@ export const SettingsModal: React.FC<SettingsModalProps> = ({
                     </nav>
                 </div>
 
-                {/* コンテンツエリア */}
+                {/* Content Area */}
                 <div className="flex-1 flex flex-col min-w-0">
                     <div className="flex items-center justify-between p-4 border-b border-slate-100">
                         <h3 className="text-lg font-semibold text-slate-800">

+ 1 - 1
web/components/Toast.tsx

@@ -17,7 +17,7 @@ const Toast: React.FC<ToastProps> = ({ type, title, message, duration = 5000, on
   useEffect(() => {
     const timer = setTimeout(() => {
       setIsVisible(false);
-      setTimeout(onClose, 300); // 等待动画完成
+      setTimeout(onClose, 300); // Wait for animation to complete
     }, duration);
 
     return () => clearTimeout(timer);

+ 17 - 2
web/components/drawers/ImportTasksDrawer.tsx

@@ -5,6 +5,7 @@ import { useLanguage } from '../../contexts/LanguageContext';
 import { knowledgeGroupService } from '../../services/knowledgeGroupService';
 import { KnowledgeGroup } from '../../types';
 import { useToast } from '../../contexts/ToastContext';
+import ConfirmDialog from '../ConfirmDialog';
 
 interface ImportTasksDrawerProps {
     isOpen: boolean;
@@ -22,6 +23,7 @@ export const ImportTasksDrawer: React.FC<ImportTasksDrawerProps> = ({
     const [importTasks, setImportTasks] = useState<ImportTask[]>([]);
     const [groups, setGroups] = useState<KnowledgeGroup[]>([]);
     const [isLoading, setIsLoading] = useState(false);
+    const [taskToDelete, setTaskToDelete] = useState<string | null>(null);
 
     const fetchData = async () => {
         if (!authToken) return;
@@ -51,13 +53,19 @@ export const ImportTasksDrawer: React.FC<ImportTasksDrawerProps> = ({
     };
 
     const handleDelete = async (taskId: string) => {
-        if (!window.confirm(t('confirmDeleteTask'))) return;
+        setTaskToDelete(taskId);
+    };
+
+    const confirmDelete = async () => {
+        if (!taskToDelete) return;
         try {
-            await importService.delete(authToken, taskId);
+            await importService.delete(authToken, taskToDelete);
             fetchData();
         } catch (error) {
             console.error('Failed to delete task:', error);
             showError(t('deleteTaskFailed'));
+        } finally {
+            setTaskToDelete(null);
         }
     };
 
@@ -175,6 +183,13 @@ export const ImportTasksDrawer: React.FC<ImportTasksDrawerProps> = ({
                     )}
                 </div>
             </div>
+
+            <ConfirmDialog
+                isOpen={!!taskToDelete}
+                message={t('confirmDeleteTask')}
+                onConfirm={confirmDelete}
+                onCancel={() => setTaskToDelete(null)}
+            />
         </div>
     );
 };

+ 2 - 2
web/components/layouts/SidebarRail.tsx

@@ -68,10 +68,10 @@ export const SidebarRail: React.FC<SidebarRailProps> = ({ currentView, onViewCha
                 </div>
             )}
 
-            {/* ナビゲーション項目 */}
+            {/* Navigation items */}
             <div className="flex-1 flex flex-col space-y-2 w-full px-3">
                 {navItems.map((item) => {
-                    // 現在のルートに基づいてアクティブなタブを決定
+                    // Determine active tab based on current route
                     const isActive = currentView === item.id;
                     return (
                         <button

+ 3 - 3
web/components/views/ChatView.tsx

@@ -341,7 +341,7 @@ export const ChatView: React.FC<ChatViewProps> = ({
                     </div>
 
                     <div className='flex items-center gap-3 flex-shrink-0'>
-                        {/* 历史记录按钮 */}
+                        {/* History button */}
                         <button
                             onClick={handleShowHistory}
                             className="flex items-center gap-2 px-4 py-2 bg-white border border-slate-200 text-slate-700 hover:text-blue-600 hover:bg-slate-50 rounded-lg font-semibold text-sm transition-all shadow-sm"
@@ -350,7 +350,7 @@ export const ChatView: React.FC<ChatViewProps> = ({
                             {t('viewHistory')}
                         </button>
 
-                        {/* 新建对话按钮 */}
+                        {/* New chat button */}
                         <button
                             onClick={handleNewChat}
                             className="flex items-center gap-2 px-5 py-2 bg-blue-600 hover:bg-blue-700 text-white rounded-lg shadow-sm shadow-blue-100 transition-all font-semibold text-sm active:scale-95"
@@ -413,7 +413,7 @@ export const ChatView: React.FC<ChatViewProps> = ({
                 onSelectionChange={setSelectedGroups}
             />
 
-            {/* 知识库增强功能模态框 (Legacy) */}
+            {/* Knowledge base enhancement features modal (Legacy) */}
             {isGroupManagerOpen && (
                 <div className="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50">
                     <div className="bg-white rounded-lg p-6 w-full max-w-2xl max-h-[80vh] overflow-y-auto">

+ 10 - 10
web/components/views/SettingsView.tsx

@@ -95,7 +95,7 @@ export const SettingsView: React.FC<SettingsViewProps> = ({
         }
     }, [initialTab]);
 
-    // ユーザー一覧の取得(ユーザータブがアクティブな場合)
+    // Fetch user list (if users tab is active)
     // Data fetching on tab change
     useEffect(() => {
         if (activeTab === 'user') {
@@ -188,7 +188,7 @@ export const SettingsView: React.FC<SettingsViewProps> = ({
         }
     };
 
-    // --- 一般タブのハンドラー ---
+    // --- General tab handlers ---
 
 
     const handleChangePassword = async (e: React.FormEvent) => {
@@ -218,7 +218,7 @@ export const SettingsView: React.FC<SettingsViewProps> = ({
     };
 
 
-    // --- ユーザータブのハンドラー ---
+    // --- Users tab handlers ---
     const fetchUsers = async () => {
         setIsUserLoading(true);
         try {
@@ -260,7 +260,7 @@ export const SettingsView: React.FC<SettingsViewProps> = ({
     const handleToggleUserAdmin = async (userId: string, newAdminStatus: boolean) => {
         try {
             await userService.updateUser(userId, newAdminStatus);
-            // ユーザーリストを再取得
+            // Re-fetch user list
             fetchUsers();
             setUserSuccess(newAdminStatus ? t('userPromotedToAdmin') : t('userDemotedFromAdmin'));
         } catch (error: any) {
@@ -508,7 +508,7 @@ export const SettingsView: React.FC<SettingsViewProps> = ({
         }
     };
 
-    // --- モデルタブのハンドラー ---
+    // --- Models tab handlers ---
     const handleSaveModel = async () => {
         if (!authToken) {
             setError(t('mmErrorNotAuthenticated'));
@@ -577,12 +577,12 @@ export const SettingsView: React.FC<SettingsViewProps> = ({
         }
     };
 
-    // --- レンダリング関数 ---
+    // --- Rendering functions ---
 
     const renderGeneralTab = () => (
         <div className="space-y-8 animate-in slide-in-from-right duration-300 max-w-2xl">
 
-            {/* パスワード変更セクション */}
+            {/* Change password section */}
             <section className="bg-white p-6 rounded-lg border border-slate-200 shadow-sm">
                 <h3 className="text-sm font-medium text-slate-800 mb-4 flex items-center gap-2">
                     <Key className="w-4 h-4 text-blue-500" />
@@ -633,7 +633,7 @@ export const SettingsView: React.FC<SettingsViewProps> = ({
 
 
 
-            {/* 语言设置セクション */}
+            {/* Language settings section */}
             <section className="bg-white p-6 rounded-lg border border-slate-200 shadow-sm">
                 <h3 className="text-sm font-medium text-slate-800 mb-4 flex items-center gap-2">
                     <Globe className="w-4 h-4 text-blue-500" />
@@ -650,8 +650,8 @@ export const SettingsView: React.FC<SettingsViewProps> = ({
                             className="w-full px-3 py-2 text-sm border border-slate-300 rounded-md focus:ring-2 focus:ring-blue-500 outline-none bg-white"
                         >
                             <option value="en">English</option>
-                            <option value="zh">中文 (Chinese)</option>
-                            <option value="ja">日本語 (Japanese)</option>
+                            <option value="zh">Chinese (Chinese)</option>
+                            <option value="ja">Japanese (Japanese)</option>
                         </select>
                     </div>
                 </div>

+ 1 - 1
web/contexts/ToastContext.tsx

@@ -39,7 +39,7 @@ export const ToastProvider: React.FC<ToastProviderProps> = ({ children }) => {
     const newToast: ToastItem = { id, type, message, title, duration };
 
     setToasts(prev => {
-      // 相同消息去重:如果已存在相同的消息(类型和内容相同),则先移除旧的
+      // Deduplicate identical messages: discard old one if current type and content are the same
       const filtered = prev.filter(t => t.message !== message || t.type !== type);
       return [...filtered, newToast];
     });

+ 1 - 1
web/services/apiClient.ts

@@ -28,7 +28,7 @@ class ApiClient {
     };
   }
 
-  // 新しい API 呼び出し方法、{ data, status } を返す
+  // New API call method, returns { data, status }
   async get<T = any>(url: string): Promise<ApiResponse<T>> {
     const response = await fetch(`${this.baseURL}${url}`, {
       method: 'GET',

+ 29 - 29
web/services/chatService.ts

@@ -19,19 +19,19 @@ export class ChatService {
     authToken: string,
     userLanguage: string = 'ja',
     selectedEmbeddingId?: string,
-    selectedLLMId?: string, // 追加: 選択された LLM ID
-    selectedGroups?: string[], // 追加: 選択されたグループ
-    selectedFiles?: string[], // 追加: 選択されたファイル
-    historyId?: string, // 追加: 会話履歴 ID
-    enableRerank?: boolean, // 追加: Rerank を有効にする
-    selectedRerankId?: string, // 追加: Rerank モデル ID
-    temperature?: number, // 追加: temperature パラメータ
-    maxTokens?: number, // 追加: maxTokens パラメータ
-    topK?: number, // 追加: topK パラメータ
-    similarityThreshold?: number, // 追加: similarityThreshold パラメータ
-    rerankSimilarityThreshold?: number, // 追加: rerankSimilarityThreshold パラメータ
-    enableQueryExpansion?: boolean, // 追加
-    enableHyDE?: boolean // 追加
+    selectedLLMId?: string, // Added: Selected LLM ID
+    selectedGroups?: string[], // Added: Selected groups
+    selectedFiles?: string[], // Added: Selected files
+    historyId?: string, // Added: Conversation history ID
+    enableRerank?: boolean, // Added: Enable Rerank
+    selectedRerankId?: string, // Added: Rerank model ID
+    temperature?: number, // Added: temperature parameter
+    maxTokens?: number, // Added: maxTokens parameter
+    topK?: number, // Added: topK parameter
+    similarityThreshold?: number, // Added: similarityThreshold parameter
+    rerankSimilarityThreshold?: number, // Added: rerankSimilarityThreshold parameter
+    enableQueryExpansion?: boolean, // Added
+    enableHyDE?: boolean // Added
   ): AsyncGenerator<{ type: 'content' | 'sources' | 'error' | 'historyId'; data: any }> {
     try {
       const response = await fetch('/api/chat/stream', {
@@ -48,28 +48,28 @@ export class ChatService {
           userLanguage,
           selectedEmbeddingId,
           selectedLLMId, // Pass LLM ID
-          selectedGroups, // グループフィルタパラメータを渡す
-          selectedFiles, // ファイルフィルタパラメータを渡す
-          historyId, // 履歴 ID を渡す
+          selectedGroups, // Pass group filter parameters
+          selectedFiles, // Pass file filter parameters
+          historyId, // Pass history ID
           enableRerank,
           selectedRerankId,
-          temperature, // temperature パラメータを渡す
-          maxTokens, // maxTokens パラメータを渡す
-          topK, // topK パラメータを渡す
-          similarityThreshold, // similarityThreshold パラメータを渡す
-          rerankSimilarityThreshold, // rerankSimilarityThreshold パラメータを渡す
-          enableQueryExpansion, // enableQueryExpansion を渡す
-          enableHyDE // enableHyDE を渡す
+          temperature, // Pass temperature parameter
+          maxTokens, // Pass maxTokens parameter
+          topK, // Pass topK parameter
+          similarityThreshold, // Pass similarityThreshold parameter
+          rerankSimilarityThreshold, // Pass rerankSimilarityThreshold parameter
+          enableQueryExpansion, // Pass enableQueryExpansion
+          enableHyDE // Pass enableHyDE
         }),
       });
 
       if (!response.ok) {
-        let errorMessage = 'リクエストに失敗しました';
+        let errorMessage = 'Request failed';
         try {
           const error = await response.json();
-          errorMessage = error.error || error.message || 'リクエストに失敗しました';
+          errorMessage = error.error || error.message || 'Request failed';
         } catch {
-          errorMessage = `サーバーエラー: ${response.status}`;
+          errorMessage = `Server error: ${response.status}`;
         }
         yield { type: 'error', data: errorMessage };
         return;
@@ -77,7 +77,7 @@ export class ChatService {
 
       const reader = response.body?.getReader();
       if (!reader) {
-        yield { type: 'error', data: 'レスポンスストリームを読み取れません' };
+        yield { type: 'error', data: 'Cannot read response stream' };
         return;
       }
 
@@ -109,7 +109,7 @@ export class ChatService {
         }
       }
     } catch (error) {
-      yield { type: 'error', data: error.message || 'ネットワークエラー' };
+      yield { type: 'error', data: error.message || 'Network error' };
     }
   }
 
@@ -131,7 +131,7 @@ export class ChatService {
       });
 
       if (!response.ok) {
-        yield { type: 'error', data: 'リクエストに失敗しました' };
+        yield { type: 'error', data: 'Request failed' };
         return;
       }
 

+ 32 - 32
web/services/chunkConfigService.ts

@@ -1,27 +1,27 @@
-// チャンク設定サービス - チャンク設定の制限の取得と検証に使用
+// Chunk configuration service - Used to fetch and validate chunk configuration limits
 
 export interface ChunkConfigLimits {
-  maxChunkSize: number;        // 最大チャンクサイズ (tokens)
-  maxOverlapSize: number;      // 最大重複サイズ (tokens)
-  minOverlapSize: number;      // 最小重複サイズ (tokens)
-  defaultChunkSize: number;    // デフォルトチャンクサイズ
-  defaultOverlapSize: number;  // デフォルト重複サイズ
-  modelInfo: EmbeddingModelLimit; // モデル情報
+  maxChunkSize: number;        // Max chunk size (tokens)
+  maxOverlapSize: number;      // Max overlap size (tokens)
+  minOverlapSize: number;      // Min overlap size (tokens)
+  defaultChunkSize: number;    // Default chunk size
+  defaultOverlapSize: number;  // Default overlap size
+  modelInfo: EmbeddingModelLimit; // Model info
 }
 
 export interface EmbeddingModelLimit {
-  name: string;              // モデル名
-  maxInputTokens: number;    // モデル入力制限
-  maxBatchSize: number;      // モデルバッチ制限
-  expectedDimensions: number; // 期待されるベクトル次元数
+  name: string;              // Model name
+  maxInputTokens: number;    // Model input limit
+  maxBatchSize: number;      // Model batch limit
+  expectedDimensions: number; // Expected vector dimensions
 }
 
 export const chunkConfigService = {
   /**
-   * チャンク設定の制限を取得
-   * @param embeddingModelId 埋め込みモデルID
-   * @param authToken 認証トークン
-   * @returns 設定制限情報
+   * Fetch chunk configuration limits
+   * @param embeddingModelId Embedding model ID
+   * @param authToken Auth token
+   * @returns Configuration limit info
    */
   async getLimits(
     embeddingModelId: string,
@@ -51,11 +51,11 @@ export const chunkConfigService = {
   },
 
   /**
-   * チャンク設定が有効かどうかを検証
-   * @param chunkSize チャンクサイズ
-   * @param chunkOverlap 重複サイズ
-   * @param limits 設定制限
-   * @returns 検証結果とエラー情報
+   * Validate if chunk configuration is valid
+   * @param chunkSize Chunk size
+   * @param chunkOverlap Overlap size
+   * @param limits Config limits
+   * @returns Validation results and error info
    */
   validateConfig(
     chunkSize: number,
@@ -71,26 +71,26 @@ export const chunkConfigService = {
     let adjustedChunkSize = chunkSize;
     let adjustedOverlapSize = chunkOverlap;
 
-    // チャンクサイズの検証
+    // Chunk sizeの検証
     if (chunkSize > limits.maxChunkSize) {
-      errors.push(`チャンクサイズ ${chunkSize} が上限 ${limits.maxChunkSize} を超えています`);
+      errors.push(`Chunk size ${chunkSize}  exceeds limit  ${limits.maxChunkSize} `);
       adjustedChunkSize = limits.maxChunkSize;
     }
 
     if (chunkSize < 50) {
-      errors.push(`チャンクサイズ ${chunkSize} が最小値 50 未満です`);
+      errors.push(`Chunk size ${chunkSize}  is below minimum  50 `);
       adjustedChunkSize = 50;
     }
 
-    // 重複サイズの検証
+    // Overlap sizeの検証
     const maxOverlapByRatio = Math.floor(adjustedChunkSize * 0.5);
     if (chunkOverlap > limits.maxOverlapSize) {
-      errors.push(`重複サイズ ${chunkOverlap} が上限 ${limits.maxOverlapSize} を超えています`);
+      errors.push(`Overlap size ${chunkOverlap}  exceeds limit  ${limits.maxOverlapSize} `);
       adjustedOverlapSize = limits.maxOverlapSize;
     }
 
     if (chunkOverlap > maxOverlapByRatio) {
-      errors.push(`重複サイズ ${chunkOverlap} がチャンクサイズの50% (${maxOverlapByRatio}) を超えています`);
+      errors.push(`Overlap size ${chunkOverlap} がChunk sizeの50% (${maxOverlapByRatio}) `);
       adjustedOverlapSize = maxOverlapByRatio;
     }
 
@@ -107,15 +107,15 @@ export const chunkConfigService = {
   },
 
   /**
-   * 表示用に制限情報をフォーマット
+   * Format limit info for display
    */
   formatLimits(limits: ChunkConfigLimits): string {
     return [
-      `モデル: ${limits.modelInfo.name}`,
-      `チャンク上限: ${limits.maxChunkSize} tokens`,
-      `重複上限: ${limits.maxOverlapSize} tokens`,
-      `バッチ制限: ${limits.modelInfo.maxBatchSize}`,
-      `ベクトル次元: ${limits.modelInfo.expectedDimensions}`,
+      `Model: ${limits.modelInfo.name}`,
+      `Max Chunk: ${limits.maxChunkSize} tokens`,
+      `Max Overlap: ${limits.maxOverlapSize} tokens`,
+      `Batch Limit: ${limits.modelInfo.maxBatchSize}`,
+      `Vector Dimensions: ${limits.modelInfo.expectedDimensions}`,
     ].join(' | ');
   },
 };

+ 7 - 7
web/services/geminiService.ts

@@ -126,13 +126,13 @@ export const generateResponse = async (
   console.log('API Key present:', !!apiKey);
 
   const langInstructionMap: Record<Language, string> = {
-    zh: "请始终使用中文回答。",
+    zh: "请始终使用Chinese回答。",
     en: "Please always answer in English.",
-    ja: "常に日本語で答えてください。"
+    ja: "常にJapaneseで答えてください。"
   };
   const langInstruction = langInstructionMap[language];
 
-  // RAG検索(知識ベースファイルがある場合)
+  // RAG search (when knowledge base files exist)
   let ragPrompt = currentPrompt;
   let ragSources: string[] = [];
 
@@ -161,7 +161,7 @@ export const generateResponse = async (
       console.warn('RAG search failed, using original prompt:', error);
       onSearchComplete?.([]);
     } finally {
-      // 検索ステータスがリセットされていることを確認
+      // Ensure search status is reset
       setTimeout(() => {
         onSearchComplete?.([]);
       }, 100);
@@ -171,7 +171,7 @@ export const generateResponse = async (
   const systemInstruction = buildSystemInstruction(files, settings, langInstruction);
 
   try {
-    // APIキーはオプションです - ローカルモデルを許可します
+    // API key is optional - allow local models
     // --- OpenAI Compatible API Logic ---
     return await callOpenAICompatible(
       ragPrompt,
@@ -185,9 +185,9 @@ export const generateResponse = async (
   } catch (error: any) {
     console.error("AI Service Error:", error);
 
-    // より詳細なエラー情報を提供
+    // Provide more detailed error information
     if (error.name === 'TypeError' && error.message.includes('fetch')) {
-      throw new Error('ネットワーク接続に失敗しました。サーバーの状態を確認してください');
+      throw new Error('Network connection failed. Please check server status');
     }
 
     throw new Error(error.message || "API_ERROR");

+ 7 - 7
web/services/knowledgeGroupService.ts

@@ -2,7 +2,7 @@ import { KnowledgeGroup, CreateGroupData, UpdateGroupData } from '../types';
 import { apiClient } from './apiClient';
 
 export const knowledgeGroupService = {
-  // すべてのグループを取得
+  // Fetch all groups
   async getGroups(options: { flat?: boolean; page?: number; limit?: number; name?: string } = {}): Promise<any> {
     const queryParams = new URLSearchParams();
     if (options.flat) queryParams.append('flat', 'true');
@@ -26,19 +26,19 @@ export const knowledgeGroupService = {
     return data;
   },
 
-  // グループを作成
+  // Create group
   async createGroup(data: CreateGroupData): Promise<KnowledgeGroup> {
     const { data: group } = await apiClient.post<KnowledgeGroup>('/knowledge-groups', data);
     return group;
   },
 
-  // グループを更新
+  // Update group
   async updateGroup(id: string, data: UpdateGroupData): Promise<KnowledgeGroup> {
     const { data: group } = await apiClient.put<KnowledgeGroup>(`/knowledge-groups/${id}`, data);
     return group;
   },
 
-  // グループを削除
+  // Delete group
   async deleteGroup(id: string): Promise<void> {
     const response = await apiClient.request(`/knowledge-groups/${id}`, {
       method: 'DELETE',
@@ -46,7 +46,7 @@ export const knowledgeGroupService = {
     if (!response.ok) throw new Error('Failed to delete group');
   },
 
-  // グループ内のファイルを取得
+  // Fetch files in group
   async getGroupFiles(id: string): Promise<any[]> {
     const response = await apiClient.request(`/knowledge-groups/${id}/files`, {});
     if (!response.ok) throw new Error('Failed to fetch group files');
@@ -54,12 +54,12 @@ export const knowledgeGroupService = {
     return data.files;
   },
 
-  // ファイルをグループに追加
+  // ファイルをグループにAdded
   async addFileToGroups(fileId: string, groupIds: string[]): Promise<void> {
     await apiClient.post(`/knowledge-bases/${fileId}/groups`, { groupIds });
   },
 
-  // グループからファイルを削除
+  // Remove file from group
   async removeFileFromGroup(fileId: string, groupId: string): Promise<void> {
     const response = await apiClient.request(`/knowledge-bases/${fileId}/groups/${groupId}`, {
       method: 'DELETE',

+ 5 - 5
web/services/noteService.ts

@@ -1,7 +1,7 @@
 import { API_BASE_URL, Note } from '../types'
 
 export const noteService = {
-    // すべてのノートを取得(オプションでグループによるフィルタリングが可能)
+    // Fetch all notes (optional group filtering)
     getAll: async (token: string, groupId?: string, categoryId?: string): Promise<Note[]> => {
         const url = new URL(`${API_BASE_URL}/notes`, window.location.origin)
         if (groupId) {
@@ -21,7 +21,7 @@ export const noteService = {
         return response.json()
     },
 
-    // ノートを作成
+    // Create note
     create: async (token: string, data: { title: string, content: string, groupId: string, categoryId?: string }): Promise<Note> => {
         const response = await fetch(`${API_BASE_URL}/notes`, {
             method: 'POST',
@@ -37,7 +37,7 @@ export const noteService = {
         return response.json()
     },
 
-    // ノートを更新
+    // Update note
     update: async (token: string, id: string, data: { title?: string, content?: string, categoryId?: string }): Promise<Note> => {
         const response = await fetch(`${API_BASE_URL}/notes/${id}`, {
             method: 'PATCH',
@@ -53,7 +53,7 @@ export const noteService = {
         return response.json()
     },
 
-    // ノートを削除
+    // Delete note
     delete: async (token: string, id: string): Promise<void> => {
         const response = await fetch(`${API_BASE_URL}/notes/${id}`, {
             method: 'DELETE',
@@ -66,7 +66,7 @@ export const noteService = {
         }
     },
 
-    // ノートを知識ベースにインデックス(ベクトル化)
+    // Index note to knowledge base (vectorize)
     createFromPDFSelection: async (
         token: string,
         fileId: string,

+ 2 - 2
web/services/ocrService.ts

@@ -1,10 +1,10 @@
 import { apiClient } from './apiClient';
 
 /**
- * OCR サービス - 画像テキスト認識関連の処理を担当
+ * OCR Service - Handles image text recognition
  */
 export const ocrService = {
-    // 画像内のテキストを認識
+    // Recognize text in image
     async recognizeText(authToken: string, image: Blob): Promise<string> {
         const formData = new FormData();
         formData.append('image', image);

+ 1 - 1
web/services/ragService.ts

@@ -14,7 +14,7 @@ export interface RagResponse {
 
 export const ragService = {
   /**
-   * RAG サービス - RAG 検索結果の直接取得を担当(チャットインターフェースではなく、デバッグや検証用)
+   * RAG サービス - RAG Search resultsの直接取得を担当(チャットインターフェースではなく、デバッグや検証用)
    */
   async search(query: string, settings: any, authToken: string): Promise<RagResponse> {
     try {

+ 4 - 4
web/services/uploadService.ts

@@ -27,12 +27,12 @@ export const uploadService = {
     formData.append('chunkOverlap', config.chunkOverlap.toString());
     formData.append('embeddingModelId', config.embeddingModelId);
 
-    // 処理モードを追加(指定されている場合)
+    // 処理モードをAdded(指定されている場合)
     if (config.mode) {
       formData.append('mode', config.mode);
     }
 
-    // 分類を追加(指定されている場合)
+    // 分類をAdded(指定されている場合)
     if (config.groupIds && config.groupIds.length > 0) {
       formData.append('groupIds', JSON.stringify(config.groupIds));
     }
@@ -64,7 +64,7 @@ export const uploadService = {
 
   /**
    * ファイル処理モードの推奨を取得
-   * ファイルの種類、サイズなどの要因に基づいて、高速モードまたは高精度モードの使用を推奨します
+   * ファイルの種類、サイズなどの要因に基づいて、Fast Modeまたは高精度モードの使用を推奨します
    */
   async recommendMode(file: File): Promise<any> {
     // セーフティチェック
@@ -101,7 +101,7 @@ export const uploadService = {
       };
     }
 
-    // 小規模なファイルには高速モードを推奨
+    // 小規模なファイルにはFast Modeを推奨
     if (sizeMB < 5) {
       return {
         recommendedMode: 'fast',

+ 74 - 74
web/utils/translations.ts

@@ -14,13 +14,13 @@ export const translations = {
     loginError: "密钥不能为空",
     unknown: "未知",
     unknownError: "未知错误",
-    langZh: "语言: 中文",
+    langZh: "语言: Chinese",
     langEn: "语言: English",
-    langJa: "语言: 日本語",
+    langJa: "语言: Japanese",
     confirm: "确认",
-    cancel: "取消",
+    cancel: "Cancel",
     confirmTitle: "确认操作",
-    confirmDeleteGroup: "确定要删除分组 \"$1\" 吗?",
+    confirmDeleteGroup: "Confirm要删除分组 \"$1\" 吗?",
 
     sidebarTitle: "索引与聊天配置",
     backToWorkspace: "返回工作台",
@@ -70,7 +70,7 @@ export const translations = {
     idxMethod: "分段设置",
     idxEmbeddingModel: "Embedding 模型",
     idxStart: "开始索引",
-    idxCancel: "取消上传",
+    idxCancel: "Cancel上传",
     idxAuto: "自动分段",
     idxCustom: "自定义",
 
@@ -89,7 +89,7 @@ export const translations = {
     mmFormDimensions: "向量维度",
     mmFormDimensionsHelp: "嵌入向量的维度大小,常见值:1536、3072",
     mmSave: "保存配置",
-    mmCancel: "取消",
+    mmCancel: "Cancel",
     mmErrorNotAuthenticated: "未登录,无法操作",
     mmErrorTitle: "操作失败",
     modelEnabled: "模型已启用",
@@ -128,7 +128,7 @@ export const translations = {
     // 更多组件缺失的翻译
     reconfigureFile: "重新配置文件",
     modifySettings: "修改文件的切片和向量化设置",
-    filesCount: "个文件",
+    filesCount: " files",
     allFilesIndexed: "所有文件将使用下面的设置进行索引",
     noEmbeddingModels: "未配置嵌入模型",
     reconfigure: "重新配置",
@@ -145,7 +145,7 @@ export const translations = {
     userPromotedToAdmin: "用户已提升为管理员",
     userDemotedFromAdmin: "用户已降级为普通用户",
     updateUserFailed: "更新用户失败",
-    confirmDeleteUser: "确定要删除此用户吗?",
+    confirmDeleteUser: "Confirm要删除此用户吗?",
     deleteUser: "删除用户",
     deleteUserFailed: "删除用户失败",
     userDeletedSuccessfully: "用户删除成功",
@@ -191,7 +191,7 @@ export const translations = {
     errorLabel: "错误",
     errorNoModel: "未选择推理模型或配置无效。",
     aiDisclaimer: "AI 可能会犯错。请核实源文件中的重要信息。",
-    confirmClear: "确定要清空所有文件及索引吗?",
+    confirmClear: "Confirm要清空所有文件及索引吗?",
     removeFile: "移除文件",
     apiError: "缺少配置或 API 密钥无效。",
     geminiError: "API 请求失败。",
@@ -242,19 +242,19 @@ export const translations = {
     groupsActions: "分组 / 操作",
     noFilesFound: "未找到匹配的文件",
     showingRange: "显示 $1 到 $2 条,共 $3 条",
-    confirmDeleteFile: "确定要删除此文件吗?",
+    confirmDeleteFile: "Confirm要删除此文件吗?",
     fileDeleted: "文件已删除",
     deleteFailed: "删除失败",
     fileAddedToGroup: "文件已添加到分组",
     failedToAddToGroup: "添加到分组失败",
     fileRemovedFromGroup: "文件已从分组移除",
     failedToRemoveFromGroup: "从分组移除失败",
-    confirmClearKB: "警告:此操作将永久删除所有文件及其索引数据。\n\n确定要清空知识库吗?",
+    confirmClearKB: "警告:此操作将永久删除所有文件及其索引数据。\n\nConfirm要清空知识库吗?",
     kbCleared: "知识库已清空",
     clearFailed: "清空失败",
     loginRequired: "请先登录",
     uploadErrors: "以下文件无法上传",
-    uploadWarning: "$1 个文件已准备上传,$2 个文件被过滤",
+    uploadWarning: "$1  files已准备上传,$2  files被过滤",
     uploadFailed: "上传失败",
     preview: "预览",
     addGroup: "添加分组",
@@ -276,7 +276,7 @@ export const translations = {
     indexingConfigDesc: "配置文档处理参数,选择处理模式",
     pendingFiles: "待处理文件",
     processingMode: "处理模式",
-    analyzingFile: "分析中...",
+    analyzingFile: "Analyzing...",
     recommendationReason: "推荐理由",
     fastMode: "快速模式",
     fastModeDesc: "简单提取文本,速度快,无额外成本,适合纯文本文档",
@@ -298,7 +298,7 @@ export const translations = {
     embeddingModel: "嵌入模型",
     pleaseSelect: "请选择...",
     pleaseSelectKnowledgeGroupFirst: "请先选择知识组再保存",
-    selectUnassignGroupWarning: "如果您想取消分配知识组,请确认此操作",
+    selectUnassignGroupWarning: "如果您想Cancel分配知识组,请确认此操作",
     chunkConfig: "切片配置",
     chunkSize: "切片大小 (Tokens)",
     min: "最小",
@@ -329,7 +329,7 @@ export const translations = {
     noDescription: "无描述",
     noNotebooks: "暂无知识组,点击右上角创建",
     createFailed: "创建失败",
-    confirmDeleteNotebook: "确定要删除知识组 \"$1\" 吗?\n\n注意:这将同时永久删除该知识组下的所有文件及其索引数据!",
+    confirmDeleteNotebook: "Confirm要删除知识组 \"$1\" 吗?\n\n注意:这将同时永久删除该知识组下的所有文件及其索引数据!",
 
     // New Notebook (Personal Notes)
     personalNotebook: "Notebook",
@@ -368,7 +368,7 @@ export const translations = {
     selectKnowledgeGroup: "选择知识库分组",
     allKnowledgeGroups: "全部知识库",
     unknownGroup: "未知分组",
-    selectedGroupsCount: "已选 $1 个分组",
+    selectedGroupsCount: "Selected $1 groups",
 
     // Settings
     generalSettings: "一般配置",
@@ -406,11 +406,11 @@ export const translations = {
 
     // Group Selection Drawer
     selectKnowledgeGroups: "选择知识库分组",
-    searchGroupsPlaceholder: "搜索分组...",
+    searchGroupsPlaceholder: "Search groups...",
     done: "完成",
     all: "全部",
-    noGroupsFound: "未找到相关分组",
-    noGroups: "暂无分组",
+    noGroupsFound: "No related groups found",
+    noGroups: "No groups",
 
     // Auto-refresh functionality
     autoRefresh: "自动刷新",
@@ -428,9 +428,9 @@ export const translations = {
     successNoteUpdated: "笔记已更新",
     successNoteCreated: "笔记已创建",
     errorSaveFailed: "保存失败: $1",
-    confirmDeleteNote: "确定要删除这条笔记吗?",
+    confirmDeleteNote: "Confirm要删除这条笔记吗?",
     successNoteDeleted: "笔记已删除",
-    confirmRemoveFileFromGroup: "确定要将文件 \"$1\" 从此知识组移除吗?(文件仍保留在知识库中)",
+    confirmRemoveFileFromGroup: "Confirm要将文件 \"$1\" 从此知识组移除吗?(文件仍保留在知识库中)",
     togglePreviewOpen: "开启预览",
     togglePreviewClose: "关闭预览",
     aiAssistant: "AI 智能助手",
@@ -457,7 +457,7 @@ export const translations = {
     aiCommandsModalPreset: "选择预设指令",
     aiCommandsModalCustom: "或输入自定义指令",
     aiCommandsModalCustomPlaceholder: "告诉 AI 你想做什么...",
-    aiCommandsModalBasedOnSelection: "将基于以下选中文本处理:",
+    aiCommandsModalBasedOnSelection: "将基于以下选Chinese本处理:",
     aiCommandsModalResult: "生成结果",
     aiCommandsModalApply: "采用此结果",
     noteTitlePlaceholder: "笔记标题",
@@ -526,7 +526,7 @@ export const translations = {
     previewNotSupported: "该格式不支持预览",
 
     // Confirmation message
-    confirmRegeneratePDF: "确定要重新生成 PDF 吗?这将覆盖当前的预览文件。",
+    confirmRegeneratePDF: "Confirm要重新生成 PDF 吗?这将覆盖当前的预览文件。",
 
     // PDFPreviewButton keys
     pdfPreviewReady: "PDF预览",
@@ -569,7 +569,7 @@ export const translations = {
     maxValueMsg: "最大值为 $1",
     overlapRatioLimit: "不能超过切片大小的50% ($1)",
     onlyAdminCanModify: "只有管理员可以修改系统设置",
-    dragToSelect: "拖动鼠标选择范围 • 按 ESC 取消",
+    dragToSelect: "拖动鼠标选择范围 • 按 ESC Cancel",
 
     // ImportFolderDrawer
     fillTargetName: "请填写目标知识组名称",
@@ -580,7 +580,7 @@ export const translations = {
     placeholderNewGroup: "新分组名称",
     importToCurrentGroup: "将导入到当前所在的分组",
     nextStep: "下一步",
-    selectedFilesCount: "已选择 $1 个文件",
+    selectedFilesCount: "已选择 $1  files",
     clickToSelectFolder: "点击选择本地文件夹",
     selectFolderTip: "将读取文件夹内所有支持的文件",
     importComplete: "导入完成",
@@ -588,7 +588,7 @@ export const translations = {
 
     // History
     historyTitle: "对话历史",
-    confirmDeleteHistory: "确定要删除这条对话历史吗?",
+    confirmDeleteHistory: "Confirm要删除这条对话历史吗?",
     deleteHistorySuccess: "对话历史删除成功",
     deleteHistoryFailed: "删除对话历史失败",
     yesterday: "昨天",
@@ -618,7 +618,7 @@ export const translations = {
     categoryCreated: "分类已创建",
     failedToCreateCategory: "创建分类失败",
     failedToDeleteCategory: "删除分类失败",
-    confirmDeleteCategory: "您确定要删除此分类吗?",
+    confirmDeleteCategory: "您Confirm要删除此分类吗?",
     kbSettingsSaved: "检索与对话配置已保存",
     failedToSaveSettings: "保存设置失败",
     actionFailed: "操作失败",
@@ -785,7 +785,7 @@ export const translations = {
     sourcePath: "源路径",
     targetGroup: "目标分组",
     scheduledAt: "计划执行时间",
-    confirmDeleteTask: "确定要删除此导入任务记录吗?",
+    confirmDeleteTask: "Confirm要删除此导入任务记录吗?",
     deleteTaskFailed: "删除任务记录失败",
   },
   en: {
@@ -1601,7 +1601,7 @@ export const translations = {
     registerButton: "登録",
     langZh: "言語: 中国語",
     langEn: "言語: 英語",
-    langJa: "言語: 日本語",
+    langJa: "言語: Japanese",
     confirm: "確認",
     cancel: "キャンセル",
     confirmTitle: "操作の確認",
@@ -1618,7 +1618,7 @@ export const translations = {
     systemConfiguration: "システム構成",
     noFiles: "ファイルなし",
     noFilesDesc: "PDF、Office文書、テキスト、コード、画像などをサポート",
-    addFile: "ファイル追加",
+    addFile: "ファイルAdded",
     clearAll: "全削除",
     uploading: "処理中",
     statusIndexing: "ベクトル化中...",
@@ -1627,7 +1627,7 @@ export const translations = {
     // RAG Settings
     ragSettings: "RAG 設定",
     enableRerank: "リランクを有効にする",
-    enableRerankDesc: "リランクモデルを使用して検索結果を再ランク付けし、精度を向上させます",
+    enableRerankDesc: "リランクモデルを使用してSearch resultsを再ランク付けし、精度を向上させます",
     selectRerankModel: "リランクモデルの選択",
     selectModelPlaceholder: "モデルを選択...",
 
@@ -1642,7 +1642,7 @@ export const translations = {
     lblRerankRef: "リランクモデル",
     lblTemperature: "温度 (Temperature)",
     lblMaxTokens: "最大トークン数",
-    lblChunkSize: "チャンクサイズ",
+    lblChunkSize: "Chunk size",
     lblChunkOverlap: "オーバーラップ",
     lblTopK: "検索数 (Top K)",
     lblRerank: "リランク有効化",
@@ -1658,7 +1658,7 @@ export const translations = {
     idxCustom: "カスタム",
 
     mmTitle: "モデルプロバイダー管理",
-    mmAddBtn: "モデル追加",
+    mmAddBtn: "モデルAdded",
     mmEdit: "編集",
     mmDelete: "削除",
     mmEmpty: "設定されたモデルはありません",
@@ -1691,7 +1691,7 @@ export const translations = {
     vectorSimilarityThreshold: "ベクトル検索しきい値",
     rerankSimilarityThreshold: "リランクしきい値",
     filterLowResults: "この値を下回る結果はフィルタリングされます",
-    noteCreatedSuccess: "ノートを作成しました",
+    noteCreatedSuccess: "Create noteしました",
     noteCreatedFailed: "ノートの作成に失敗しました",
     fullTextSearch: "全文検索",
     hybridVectorWeight: "ハイブリッド検索ベクトル重み",
@@ -1744,7 +1744,7 @@ export const translations = {
     translateToEnglish: "英語に翻訳",
     fixGrammar: "文法修正",
     aiCommandInstructPolish: "このテキストをよりプロフェッショナルで自然な表現に推敲してください。",
-    aiCommandInstructExpand: "このテキストに詳細を追加して内容を充実させ、詳しく書き広げてください。",
+    aiCommandInstructExpand: "このテキストに詳細をAddedして内容を充実させ、詳しく書き広げてください。",
     aiCommandInstructSummarize: "このテキストの要点を抽出し、簡潔な要約を作成してください。",
     aiCommandInstructTranslateToEn: "このテキストを英語に翻訳してください。",
     aiCommandInstructFixGrammar: "このテキストの文法やスペルの誤りをチェックし、修正してください。",
@@ -1782,8 +1782,8 @@ export const translations = {
     saveVisionModelFailed: "ビジョンモデルの保存に失敗しました",
     noVisionModels: "利用可能なビジョンモデルがありません",
     selectVisionModel: "ビジョンモデルを選択してください",
-    visionModelHelp: "画像ファイルを処理するためのビジョンモデル。利用可能なモデルがない場合は、モデル管理で追加し、「ビジョン対応」オプションをチェックしてください。",
-    mmErrorNameRequired: "モデル名は必須要素です",
+    visionModelHelp: "画像ファイルを処理するためのビジョンモデル。利用可能なモデルがない場合は、モデル管理でAddedし、「ビジョン対応」オプションをチェックしてください。",
+    mmErrorNameRequired: "Model nameは必須要素です",
     mmErrorModelIdRequired: "モデルIDは必須です。",
     mmErrorBaseUrlRequired: "選択されたプロバイダーにはBase URLが必要です。",
     mmRequiredAsterisk: "*",
@@ -1804,7 +1804,7 @@ export const translations = {
     confirmClear: "すべてのファイルを削除しますか?",
     removeFile: "ファイルを削除",
     apiError: "設定が不足しているか、APIキーが有効ではありません。",
-    geminiError: "APIリクエストに失敗しました。",
+    geminiError: "APIRequest failed。",
     processedButNoText: "応答を生成できませんでした。",
     unitByte: "バイト",
     readingFailed: "読み込み失敗",
@@ -1817,7 +1817,7 @@ export const translations = {
     changePassword: "パスワード変更",
     userManagement: "ユーザー管理",
     userList: "ユーザー一覧",
-    addUser: "ユーザー追加",
+    addUser: "ユーザーAdded",
     username: "ユーザー名",
     password: "パスワード",
     confirmPassword: "パスワード確認",
@@ -1854,8 +1854,8 @@ export const translations = {
     confirmDeleteFile: "このファイルを削除してもよろしいですか?",
     fileDeleted: "ファイルを削除しました",
     deleteFailed: "削除に失敗しました",
-    fileAddedToGroup: "ファイルがグループに追加されました",
-    failedToAddToGroup: "グループへの追加に失敗しました",
+    fileAddedToGroup: "ファイルがグループにAddedされました",
+    failedToAddToGroup: "グループへのAddedに失敗しました",
     fileRemovedFromGroup: "ファイルがグループから削除されました",
     failedToRemoveFromGroup: "グループからの削除に失敗しました",
     confirmClearKB: "警告:これによりすべてのファイルとインデックスが完全に削除されます。\n\n本当にナレッジベースをクリアしますか?",
@@ -1866,7 +1866,7 @@ export const translations = {
     uploadWarning: "$1 つのファイルがアップロード準備完了、$2 つがフィルタリングされました",
     uploadFailed: "アップロードに失敗しました",
     preview: "プレビュー",
-    addGroup: "グループ追加",
+    addGroup: "グループAdded",
     delete: "削除",
     retry: "再試行",
     retrying: "再試行中...",
@@ -1885,31 +1885,31 @@ export const translations = {
     indexingConfigDesc: "ドキュメント処理オプションとモードを設定",
     pendingFiles: "待機中のファイル",
     processingMode: "処理モード",
-    analyzingFile: "分析中...",
+    analyzingFile: "Analyzing...",
     recommendationReason: "理由",
-    fastMode: "高速モード",
-    fastModeDesc: "単純なテキスト抽出、高速、追加コストなし、純粋なテキストに適しています",
-    preciseMode: "精密モード",
+    fastMode: "Fast Mode",
+    fastModeDesc: "単純なテキスト抽出、Fast、No additional cost、純粋なテキストに適しています",
+    preciseMode: "Precise Mode",
     preciseModeDesc: "精密なレイアウト分析、表/画像を保持、APIコストがかかります",
-    fastModeFeatures: "高速モードの特徴:",
+    fastModeFeatures: "Fast Modeの特徴:",
     fastFeature1: "単純なテキスト抽出",
-    fastFeature2: "高速な処理速度",
-    fastFeature3: "追加コストなし",
+    fastFeature2: "Fastな処理速度",
+    fastFeature3: "No additional cost",
     fastFeature4: "テキストのみ処理",
     fastFeature5: "プレーンテキストに適しています",
-    preciseModeFeatures: "精密モードの特徴:",
+    preciseModeFeatures: "Precise Modeの特徴:",
     preciseFeature1: "精密な構造認識",
     preciseFeature2: "画像/表/チャートを認識",
     preciseFeature3: "混合コンテンツを保持",
-    preciseFeature4: "レイアウト情報を保持",
+    preciseFeature4: "Retains layout information",
     preciseFeature5: "APIコストが必要",
     preciseFeature6: "処理時間が長くなります",
     embeddingModel: "埋め込みモデル",
     pleaseSelect: "選択してください...",
     pleaseSelectKnowledgeGroupFirst: "保存する前に知識グループを選択してください",
     selectUnassignGroupWarning: "ナレッジグループの割り当てを解除する場合は、この操作を確認してください",
-    chunkConfig: "チャンク設定",
-    chunkSize: "チャンクサイズ (トークン)",
+    chunkConfig: "Chunk configuration",
+    chunkSize: "Chunk size (トークン)",
     min: "最小",
     max: "最大",
     chunkOverlap: "オーバーラップ (トークン)",
@@ -1920,12 +1920,12 @@ export const translations = {
     maxBatchSize: "最大バッチ",
     envLimitWeaker: "環境制限の方が厳しいです",
     optimizationTips: "最適化のヒント",
-    tipChunkTooLarge: "チャンクサイズが大きいと検索精度に影響する可能性があります",
+    tipChunkTooLarge: "Chunk sizeが大きいと検索精度に影響する可能性があります",
     tipOverlapSmall: "オーバーラップは少なくとも $1 トークンを推奨します",
     tipMaxValues: "最大値を使用すると処理が遅くなる可能性があります",
-    tipPreciseCost: "精密モードはAPIコストが発生します。予算を確認してください",
+    tipPreciseCost: "Precise ModeはAPIコストが発生します。予算を確認してください",
     selectEmbeddingFirst: "先に埋め込みモデルを選択してください",
-    confirmPreciseCost: "精密モードはAPIコストが発生します。続けますか?",
+    confirmPreciseCost: "Precise ModeはAPIコストが発生します。続けますか?",
     startProcessing: "処理開始",
 
     // Notebooks View
@@ -1934,7 +1934,7 @@ export const translations = {
     createNotebook: "新しいナレッジグループ",
     chatWithNotebook: "このグループとチャット",
     editNotebook: "グループを編集",
-    deleteNotebook: "グループを削除 (ファイルを含む)",
+    deleteNotebook: "Delete group (ファイルを含む)",
     noDescription: "説明なし",
     hasIntro: "紹介あり",
     noIntro: "紹介なし",
@@ -1958,7 +1958,7 @@ export const translations = {
     descPlaceholder: "このグループの目的を一文で説明",
     detailedIntro: "詳細な紹介",
     introPlaceholder: "ここの段落は、Q&Aのコンテキストに含まれる可能性があります。このグループの主要なトピック、背景知識、または目標をできるだけ詳しく説明してください。",
-    introHelp: "この紹介は、会話の追加コンテキストとして使用されます。",
+    introHelp: "この紹介は、会話のAddedコンテキストとして使用されます。",
     creating: "作成中...",
     createNow: "今すぐ作成",
     saving: "保存中...",
@@ -1970,7 +1970,7 @@ export const translations = {
     viewHistory: "チャット履歴を表示",
     saveSettingsFailed: "設定の保存に失敗しました",
     loginToUpload: "アップロードするにはログインしてください",
-    fileSizeLimitExceeded: "$1 ($2 - $3MB の制限を超えています)",
+    fileSizeLimitExceeded: "$1 ($2 - $3MB の制限)",
     unsupportedFileType: "$1 - サポートされていないファイルタイプ ($2)",
     readFailed: "$1 - 読み込みに失敗しました",
     loadHistoryFailed: "履歴の読み込みに失敗しました",
@@ -2047,7 +2047,7 @@ export const translations = {
     importFolder: "フォルダをインポート",
 
     // CreateNoteFromPDFDialog keys
-    createPDFNote: "PDFノートを作成",
+    createPDFNote: "PDFCreate note",
     screenshotPreview: "スクリーンショットプレビュー",
     associateKnowledgeGroup: "ナレッジグループに関連付ける",
     globalNoSpecificGroup: "全体 (特定のグループなし)",
@@ -2087,8 +2087,8 @@ export const translations = {
     zoomOut: "ズームアウト",
     zoomIn: "ズームイン",
     resetZoom: "ズームをリセット",
-    selectPageNumber: "ページ番号を選択:",
-    enterPageNumber: "選択したいページ番号を入力してください",
+    selectPageNumber: "Page numberを選択:",
+    enterPageNumber: "選択したいPage numberを入力してください",
     exitSelectionMode: "選択モードを終了",
     clickToSelectAndNote: "クリックして領域を選択し、メモを取る",
     regeneratePDF: "PDFを再生成",
@@ -2118,27 +2118,27 @@ export const translations = {
 
     // uploadService Recommendations
     invalidFile: "無効なファイル",
-    incompleteFileInfo: "ファイル情報が不完全です。高速モードを使用します",
+    incompleteFileInfo: "ファイル情報が不完全です。Fast Modeを使用します",
     unsupportedFileFormat: "サポートされていない形式: .$1",
-    willUseFastMode: "高速モード(テキスト抽出のみ)を使用します",
-    formatNoPrecise: "形式 .$1 は精密モードをサポートしていません",
-    smallFileFastOk: "ファイルサイズが小さいため、高速モードで十分です",
-    mixedContentPreciseRecommended: "図表などが含まれるため、精密モードを推奨します",
+    willUseFastMode: "Fast Mode(テキスト抽出のみ)を使用します",
+    formatNoPrecise: "形式 .$1 はPrecise Modeをサポートしていません",
+    smallFileFastOk: "ファイルサイズが小さいため、Fast Modeで十分です",
+    mixedContentPreciseRecommended: "図表などが含まれるため、Precise Modeを推奨します",
     willIncurApiCost: "APIコストが発生します",
-    largeFilePreciseRecommended: "大きなファイルです。構造保持のため精密モードを推奨します",
+    largeFilePreciseRecommended: "大きなファイルです。構造保持のためPrecise Modeを推奨します",
     longProcessingTime: "処理に時間がかかる可能性があります",
     highApiCost: "高いAPIコストが発生します",
     considerFileSplitting: "ファイルの分割を検討してください",
 
     // Drag and drop upload
-    dragDropUploadTitle: "アップロードするファイルをドラッグ&ドロップ",
+    dragDropUploadTitle: "File to uploadをドラッグ&ドロップ",
     dragDropUploadDesc: "または下のボタンをクリックしてファイルを選択",
     supportedFormats: "対応フォーマット",
     browseFiles: "ファイルを参照",
 
     // IndexingModal
     recommendationMsg: "$1モードを推奨します: $2",
-    autoAdjustChunk: "チャンクサイズを上限の $1 に調整しました",
+    autoAdjustChunk: "Chunk sizeを上限の $1 に調整しました",
     autoAdjustOverlap: "重なりサイズを上限の $1 に調整しました",
     autoAdjustOverlapMin: "重なりサイズを最小値の $1 に調整しました",
     loadLimitsFailed: "モデル制限の読み込みに失敗しました。デフォルト設定を使用します",
@@ -2181,7 +2181,7 @@ export const translations = {
     kbSettingsSaved: "設定を保存しました",
     failedToSaveSettings: "設定の保存に失敗しました",
     actionFailed: "操作に失敗しました",
-    userAddedToOrganization: "ユーザーが組織に追加されました",
+    userAddedToOrganization: "ユーザーが組織にAddedされました",
     featureUpdated: "機能が更新されました",
     roleTenantAdmin: "テナント管理者",
     roleRegularUser: "一般ユーザー",
@@ -2204,7 +2204,7 @@ export const translations = {
     selectEmbedding: "埋め込みを選択",
     rerankModel: "リランクモデル",
     none: "なし",
-    indexingChunkingConfig: "インデックスとチャンク設定",
+    indexingChunkingConfig: "インデックスとChunk configuration",
     chatHyperparameters: "チャットハイパーパラメータ",
     temperature: "温度",
     precise: "精密",
@@ -2253,7 +2253,7 @@ export const translations = {
     createCategoryBtn: "今すぐ作成",
     newGroup: "新規グループ",
     noKnowledgeGroups: "ナレッジグループがまだありません",
-    createGroupDesc: "最初のナレッジグループを作成してドキュメントをアップロードしてください。",
+    createGroupDesc: "最初のナレッジCreate groupしてドキュメントをアップロードしてください。",
     noDescriptionProvided: "説明なし",
     browseManageFiles: "このグループ内のファイルとメモを閲覧・管理します。",
     filterGroupFiles: "名前でグループ内のファイルを検索...",
@@ -2348,7 +2348,7 @@ export const translations = {
     "x-user-language": "ユーザー言語",
 
     // Hierarchical categories new keys
-    addSubcategory: "サブカテゴリを追加",
+    addSubcategory: "サブカテゴリをAdded",
     parentCategory: "親カテゴリ(任意)",
     noParentTopLevel: "なし(トップレベル)",
     useHierarchyImport: "フォルダ階層でカテゴリを作成",