瀏覽代碼

国际化

anhuiqiang 1 周之前
父節點
當前提交
a0959d23b1
共有 58 個文件被更改,包括 5334 次插入8428 次删除
  1. 133 0
      auto_dict.json
  2. 60 0
      auto_replace.js
  3. 52 0
      auto_translator.js
  4. 404 0
      backend_cjk.txt
  5. 3659 7409
      cjk_extract.json
  6. 50 0
      cjk_files.txt
  7. 45 45
      docker-compose.yml
  8. 4 0
      remaining_4.txt
  9. 二進制
      remaining_cjk.txt
  10. 二進制
      server/build_output.txt
  11. 6 6
      server/src/ai/embedding.service.ts
  12. 2 2
      server/src/api/api.controller.ts
  13. 1 1
      server/src/api/api.service.ts
  14. 29 29
      server/src/chat/chat.controller.ts
  15. 52 54
      server/src/chat/chat.service.ts
  16. 7 9
      server/src/common/constants.ts
  17. 35 42
      server/src/elasticsearch/elasticsearch.service.ts
  18. 31 55
      server/src/knowledge-base/chunk-config.service.ts
  19. 29 33
      server/src/knowledge-base/embedding.service.ts
  20. 8 11
      server/src/knowledge-base/knowledge-base.controller.ts
  21. 9 9
      server/src/knowledge-base/knowledge-base.entity.ts
  22. 111 129
      server/src/knowledge-base/knowledge-base.service.ts
  23. 36 54
      server/src/knowledge-base/memory-monitor.service.ts
  24. 3 3
      server/src/knowledge-base/text-chunker.service.ts
  25. 2 4
      server/src/libreoffice/libreoffice.interface.ts
  26. 28 38
      server/src/libreoffice/libreoffice.service.ts
  27. 9 9
      server/src/migrations/1737800000000-AddKnowledgeBaseEnhancements.ts
  28. 9 21
      server/src/model-config/dto/create-model-config.dto.ts
  29. 10 27
      server/src/model-config/model-config.entity.ts
  30. 4 9
      server/src/model-config/model-config.service.ts
  31. 10 12
      server/src/pdf2image/pdf2image.interface.ts
  32. 15 26
      server/src/pdf2image/pdf2image.service.ts
  33. 31 39
      server/src/rag/rag.service.ts
  34. 6 13
      server/src/rag/rerank.service.ts
  35. 1 1
      server/src/search-history/search-history.controller.ts
  36. 1 1
      server/src/search-history/search-history.service.ts
  37. 9 9
      server/src/upload/upload.controller.ts
  38. 5 5
      server/src/upload/upload.module.ts
  39. 1 1
      server/src/user-setting/user-setting.entity.ts
  40. 8 12
      server/src/user-setting/user-setting.service.ts
  41. 4 4
      server/src/user/user.controller.ts
  42. 1 1
      server/src/user/user.entity.ts
  43. 4 4
      server/src/user/user.service.ts
  44. 36 59
      server/src/vision-pipeline/cost-control.service.ts
  45. 40 55
      server/src/vision-pipeline/vision-pipeline-cost-aware.service.ts
  46. 3 5
      server/src/vision-pipeline/vision-pipeline.interface.ts
  47. 10 12
      server/src/vision/vision.interface.ts
  48. 34 52
      server/src/vision/vision.service.ts
  49. 265 0
      true_code.txt
  50. 1 1
      web/components/GroupSelector.tsx
  51. 1 92
      web/services/chunkConfigService.ts
  52. 1 1
      web/services/knowledgeGroupService.ts
  53. 3 3
      web/services/pdfPreviewService.ts
  54. 1 3
      web/services/ragService.ts
  55. 4 4
      web/services/searchHistoryService.ts
  56. 8 11
      web/services/uploadService.ts
  57. 1 1
      web/src/utils/toast.ts
  58. 2 2
      web/types.ts

+ 133 - 0
auto_dict.json

@@ -0,0 +1,133 @@
+{
+  "console.log('Final LLM model used (default):', llmModel ? llmModel.name : '无');": "console.log('Final LLM model used (default):', llmModel ? llmModel.name : '无');",
+  "`data: ${JSON.stringify({ type: 'error', data: '请在模型管理中添加LLM模型并配置API密钥' })}\\n\\n`,": "`data: ${JSON.stringify({ type: 'error', data: 'Please add LLM model and configure API key in model management' })}\\n\\n`,",
+  "`data: ${JSON.stringify({ type: 'error', data: error.message || '服务器错误' })}\\n\\n`,": "`data: ${JSON.stringify({ type: 'error', data: error.message || 'Server Error' })}\\n\\n`,",
+  "`data: ${JSON.stringify({ type: 'error', data: '未找到LLM模型配置' })}\\n\\n`,": "`data: ${JSON.stringify({ type: 'error', data: 'LLM model configuration not found' })}\\n\\n`,",
+  "console.log('ユーザーID:', userId);": "console.log('User ID:', userId);",
+  "console.log('API Key プレフィックス:', modelConfig.apiKey?.substring(0, 10) + '...');": "console.log('API Key prefix:', modelConfig.apiKey?.substring(0, 10) + '...');",
+  "提供されたテキスト内容を、ユーザーの指示に基づいて修正または改善してください。": "Correct or improve the provided text content based on your instructions.",
+  "挨拶や結びの言葉(「わかりました、こちらが...」など)は含めず、修正後の内容のみを直接出力してください。": "Please do not include any greetings or closing words (such as \"Okay, this is...\") and directly output only the revised content.",
+  "コンテキスト(現在の内容):": "Context (current contents):",
+  "ユーザーの指示:": "User instructions:",
+  "1. **段落与结构**:": "1. **Paragraph and Structure**:",
+  "- 使用清晰的段落分隔,每个要点之间空一行": "- Use clear paragraph separation with a blank line between each bullet point",
+  "- 使用标题(## 或 ###)组织长回答": "- Use headings (## or ###) to organize long answers",
+  "2. **文本格式**:": "2. **Text Format**:",
+  "- 使用 **粗体** 强调重要概念和关键词": "- Use **bold** to emphasize important concepts and keywords",
+  "- 使用列表(- 或 1.)组织多个要点": "- Use lists (- or 1.) to organize multiple points",
+  "- 使用 \\`代码\\` 标记技术术语、命令、文件名": "- Use \\`code\\` to mark technical terms, commands, file names",
+  "3. **代码展示**:": "3. **Code display**:",
+  "- 使用代码块展示代码,并指定语言:": "- Use code blocks to display code and specify the language:",
+  "return \"示例\"": "return \"example\"",
+  "- 支持语言:python, javascript, typescript, java, bash, sql 等": "- Supported languages: python, javascript, typescript, java, bash, sql, etc.",
+  "4. **图表与可视化**:": "4. **Charts and Visualization**:",
+  "- 使用 Mermaid 语法绘制流程图、序列图等:": "- Use Mermaid syntax to draw flowcharts, sequence diagrams, etc.:",
+  "A[开始] --> B[处理]": "A[Start] --> B[Process]",
+  "B --> C[结束]": "B --> C[end]",
+  "- 适用场景:流程、架构、状态机、时序图": "- Applicable scenarios: process, architecture, state machine, sequence diagram",
+  "5. **其他要求**:": "5. **Other requirements**:",
+  "- 回答精炼准确": "- Answer concisely and accurately",
+  "- 多步骤操作使用有序列表": "- Use ordered lists for multi-step operations",
+  "- 对比类信息建议用表格展示(如果适用)": "- It is recommended to display comparative information in tables (if applicable)",
+  "ナレッジベースの内容:": "Knowledge base contents:",
+  "会話履歴:": "Conversation history:",
+  "ユーザーの質問:{question}": "User question: {question}",
+  "1. **段落と構造**:": "1. **Paragraphs and Structure**:",
+  "- 明確な段落分けを使用し、要点間に空行を入れる": "- Use clear paragraphing and leave blank lines between main points",
+  "- 長い回答には見出し(## または ###)を使用": "- Use headings (## or ###) for long answers",
+  "2. **テキスト書式**:": "2. **Text Format**:",
+  "- 重要な概念やキーワードを強調するために **太字** を使用": "- Use **bold** to highlight important concepts and keywords",
+  "- 複数のポイントを整理するためにリスト(- または 1.)を使用": "- Use lists (- or 1.) to organize multiple points",
+  "- 技術用語、コマンド、ファイル名をマークするために \\`コード\\` を使用": "- Use \\`code\\` to mark technical terms, commands, and file names",
+  "3. **コード表示**:": "3. **Code display**:",
+  "- 言語を指定してコードブロックを使用:": "- Use code blocks by specifying language:",
+  "return \"例\"": "return \"Example\"",
+  "- 対応言語:python, javascript, typescript, java, bash, sql など": "- Supported languages: python, javascript, typescript, java, bash, sql, etc.",
+  "4. **図表とチャート**:": "4. **Diagrams and Charts**:",
+  "- フローチャート、シーケンス図などに Mermaid 構文を使用:": "- Use Mermaid syntax for flowcharts, sequence diagrams, etc:",
+  "A[開始] --> B[処理]": "A[Start] --> B[Process]",
+  "B --> C[終了]": "B --> C[End]",
+  "- 使用例:プロセスフロー、アーキテクチャ図、状態図、シーケンス図": "- Usage examples: process flow, architecture diagram, state diagram, sequence diagram",
+  "5. **その他の要件**:": "5. **Other Requirements**:",
+  "- 簡潔で明確な回答を心がける": "- Keep your answers concise and clear",
+  "- 複数のステップがある場合は番号付きリストを使用": "- Use numbered lists when there are multiple steps",
+  "- 比較情報には表を使用(該当する場合)": "- Use tables for comparative information (if applicable)",
+  "インテリジェントアシスタントとして、ユーザーの質問に答えてください。": "Become an intelligent assistant and answer users' questions.",
+  "只返回标题文本。不要包含任何解释性文字或前导词(如“标题是:”)。": "Only the title text is returned. Do not include any explanatory text or leading words (such as \"The title is:\").",
+  "语言:Chinese": "Language: Chinese",
+  "文本内容:": "Text content:",
+  "タイトルテキストのみを返してください。説明文や前置き(例:「タイトルは:」)は含めないでください。": "Please return only the title text. Do not include descriptive text or prefaces (e.g. \"The title is:\").",
+  "言語:Japanese": "Language: Japanese",
+  "テキスト:": "text:",
+  "return `根据以下对话片段,生成一个简短、描述性的标题(不超过50个字符),总结讨论的主题。": "return `Based on the following conversation snippet, generate a short, descriptive title (no more than 50 characters) summarizing the topic of the discussion.",
+  "只返回标题文本。不要包含任何前导词。": "Only the title text is returned. Do not include any leading words.",
+  "用户: ${userMessage}": "User: ${userMessage}",
+  "助手: ${aiResponse}`;": "Helper: ${aiResponse}`;",
+  "return `以下の会話スニペットに基づいて、トピックを要約する短く説明的なタイトル(最大50文字)を生成してください。": "return `Generate a short, descriptive title (up to 50 characters) that summarizes the topic based on the conversation snippet below.",
+  "タイトルのみを返してください。前置きは不要です。": "Please return only the title. No preface necessary.",
+  "ユーザー: ${userMessage}": "User: ${userMessage}",
+  "アシスタント: ${aiResponse}`;": "Assistant: ${aiResponse}`;",
+  "const providerName = modelConfig.providerName || '不明';": "const providerName = modelConfig.providerName || '不明';",
+  "`  - プロバイダー: ${providerName}\\n` +": "` - Provider: ${providerName}\\n` +",
+  "`  - Token制限: ${maxInputTokens}\\n` +": "` - Token limit: ${maxInputTokens}\\n` +",
+  "`  - ベクトルモデルか: ${isVectorModel}`,": "` - Vector model: ${isVectorModel}`,",
+  "`Chunk size: ${chunkSize} tokens (制限: ${limits.maxInputTokens})`,": "`Chunk size: ${chunkSize} tokens (制限: ${limits.maxInputTokens})`,",
+  "`重なりサイズ: ${chunkOverlap} tokens`,": "`Overlap size: ${chunkOverlap} tokens`,",
+  "`バッチサイズ: ${limits.maxBatchSize}`,": "`Batch size: ${limits.maxBatchSize}`,",
+  "throw new Error(`埋め込みモデル設定 ${embeddingModelConfigId} が見つかりません`);": "throw new Error(`Embedded model configuration ${embeddingModelConfigId} not found`);",
+  "throw new Error(`モデル ${modelConfig.name} は無効化されているため、埋め込みベクトルを生成できません`);": "throw new Error(`Unable to generate embedding vector because model ${modelConfig.name} is disabled`);",
+  "throw new Error(`モデル ${modelConfig.name} に baseUrl が設定されていません`);": "throw new Error(`baseUrl not set for model ${modelConfig.name}`);",
+  "`総計 ${totalLength} 文字、平均 ${Math.round(avgLength)} 文字、` +": "`Total ${totalLength} characters, average ${Math.round(avgLength)} characters, ` +",
+  "`モデル制限: ${modelConfig.maxInputTokens || 8192} tokens`": "`Model limit: ${modelConfig.maxInputTokens || 8192} tokens`",
+  "`テキスト長がモデルの制限。` +": "`Text length is a limitation of the model. ` +",
+  "`現在: ${texts.length} 個のテキストで計 ${totalLength} 文字、` +": "`Currently: ${texts.length} texts totaling ${totalLength} characters, ` +",
+  "`モデル制限: ${modelConfig.maxInputTokens || 8192} tokens。` +": "`Model limit: ${modelConfig.maxInputTokens || 8192} tokens. ` +",
+  "`アドバイス: Chunk sizeまたはバッチサイズを小さくしてください`": "`Advice: Reduce chunk size or batch size`",
+  "this.logger.error(`リクエストパラメータ: model=${modelConfig.modelId}, inputLength=${texts[0]?.length}`);": "this.logger.error(`Request parameters: model=${modelConfig.modelId}, inputLength=${texts[0]?.length}`);",
+  "throw new Error(`埋め込み API の呼び出しに失敗しました: ${response.statusText} - ${errorText}`);": "throw new Error(`Embedded API call failed: ${response.statusText} - ${errorText}`);",
+  "if (error.message && (error.message.includes('context length') || error.message.includes('コンテキスト長 exceeds limit ') || error.message.includes('コンテキスト長 exceeds limit '))) {": "if (error.message && (error.message.includes('context length') || error.message.includes('context length exceeds limit ') || error.message.includes('context length exceeds limit '))) {",
+  "throw new NotFoundException('ファイルが存在しません');": "throw new NotFoundException('File does not exist');",
+  "throw new Error(`メモリ待機がタイムアウトしました: 現在 ${this.getMemoryUsage().heapUsed}MB > ${this.MAX_MEMORY_MB * 0.85}MB`);": "throw new Error(`Memory wait timed out: Currently ${this.getMemoryUsage().heapUsed}MB > ${this.MAX_MEMORY_MB * 0.85}MB`);",
+  "throw new Error(`ファイルが存在しません: ${filePath}`);": "throw new Error(`File does not exist: ${filePath}`);",
+  "throw new Error('変換がタイムアウトしました。ファイルが大きすぎる可能性があります');": "throw new Error('Conversion timed out. File may be too large');",
+  "throw new Error(`変換に失敗しました: ${detail}`);": "throw new Error(`Conversion failed: ${detail}`);",
+  "throw new Error(`変換に失敗しました: ${lastError.message}`);": "throw new Error(`Conversion failed: ${lastError.message}`);",
+  "throw new Error('LibreOffice サービスが実行されていません。サービスの状態を確認してください');": "throw new Error('LibreOffice service is not running. Please check the status of the service');",
+  "throw new Error('LibreOffice サービスとの接続が切断されました。サービスが不安定である可能性があります');": "throw new Error('The connection to the LibreOffice service has been lost. The service may be unstable');",
+  "@Min(1, { message: 'ベクトル次元の最小値は 1 です' })": "@Min(1, { message: 'The minimum value of the vector dimension is 1' })",
+  "@Max(4096, { message: 'ベクトル次元の最大値は 4096 です(Elasticsearch の制限)' })": "@Max(4096, { message: 'The maximum vector dimension is 4096 (Elasticsearch limit)' })",
+  "throw new Error(`PDF ファイルが存在しません: ${pdfPath}`);": "throw new Error(`PDF file does not exist: ${pdfPath}`);",
+  "throw new Error('PDF のページ数を取得できません');": "throw new Error('Unable to get page number of PDF');",
+  "throw new Error(`Python での変換に失敗しました: ${result.error}`);": "throw new Error(`Python conversion failed: ${result.error}`);",
+  "throw new Error(`PDF から画像への変換に失敗しました: ${error.message}`);": "throw new Error(`PDF to image conversion failed: ${error.message}`);",
+  "throw new Error('Embedding model IDが提供されていません');": "throw new Error('Embedding model ID not provided');",
+  "return { message: '对话历史删除成功' };": "return { message: 'Conversation history deleted successfully' };",
+  "`ユーザー ${req.user.id} がファイルをアップロードしました: ${file.originalname} (${this.formatBytes(file.size)})`,": "`User ${req.user.id} uploaded file: ${file.originalname} (${this.formatBytes(file.size)})`,",
+  "console.log('パスワード:', randomPassword);": "console.log('Password:', randomPassword);",
+  "console.log('=== updateLanguage デバッグ ===');": "console.log('=== updateLanguage Debug ===');",
+  "console.log('=== getLanguage デバッグ ===');": "console.log('=== getLanguage Debug ===');",
+  "page: pageIndex ? ` (第 ${pageIndex} ページ)` : '',": "page: pageIndex ? ` (th page ${pageIndex})` : '',",
+  "if (errorCode === 429 || errorMessage.includes('rate limit') || errorMessage.includes('リクエストが多すぎます')) {": "if (errorCode === 429 || errorMessage.includes('rate limit') || errorMessage.includes('Too many requests')) {",
+  "return { isGood: false, reason: `ファイルが小さすぎます (${sizeKB.toFixed(2)}KB)`, score: 0 };": "return { isGood: false, reason: `File is too small (${sizeKB.toFixed(2)}KB)`, score: 0 };",
+  "return { isGood: false, reason: `ファイルが大きすぎます (${sizeKB.toFixed(2)}KB)`, score: 0 };": "return { isGood: false, reason: `File is too large (${sizeKB.toFixed(2)}KB)`, score: 0 };",
+  "reason: `クォータ不足: 残り $${quota.remaining.toFixed(2)}, 必要 $${estimatedCost.toFixed(2)}`,": "reason: `Insufficient quota: remaining $${quota.remaining.toFixed(2)}, required $${estimatedCost.toFixed(2)}`,",
+  "throw new Error(`ユーザー ${userId} は存在しません`);": "throw new Error(`User ${userId} does not exist`);",
+  "message: `⚠️ クォータ使用率が ${usagePercent.toFixed(1)}% に達しました。残り $${quota.remaining.toFixed(2)}`,": "message: `⚠️ Quota usage has reached ${usagePercent.toFixed(1)}%. Remaining $${quota.remaining.toFixed(2)}`,",
+  "message: `💡 クォータ使用率 ${usagePercent.toFixed(1)}%。コストの管理に注意してください`,": "message: `💡 Quota usage ${usagePercent.toFixed(1)}%. Be careful with controlling costs`,",
+  "return `${seconds.toFixed(0)}秒`;": "return `${seconds.toFixed(0)}秒`;",
+  "return `${minutes}分${remainingSeconds.toFixed(0)}秒`;": "return `${minutes}分${remainingSeconds.toFixed(0)}秒`;",
+  "this.updateStatus('converting', 10, 'ドキュメント形式を変換中...');": "this.updateStatus('converting', 10, 'Converting document format...');",
+  "this.updateStatus('splitting', 30, 'PDF を画像に変換中...');": "this.updateStatus('splitting', 30, 'Converting PDF to image...');",
+  "throw new Error('PDF から画像への変換に失敗しました。画像が生成されませんでした');": "throw new Error('PDF to image conversion failed. No image was generated');",
+  "this.updateStatus('checking', 40, 'クォータを確認し、コストを見積もり中...');": "this.updateStatus('checking', 40, 'Checking quotas and estimating costs...');",
+  "this.updateStatus('analyzing', 50, 'ビジョンモデルを使用してページをAnalyzing...');": "this.updateStatus('analyzing', 50, 'Analyzing the page using the vision model...');",
+  "this.updateStatus('completed', 100, '処理が完了しました。一時ファイルをクリーンアップ中...');": "this.updateStatus('completed', 100, 'Processing completed. Cleaning up temporary files...');",
+  "throw new Error(`モデル設定が見つかりません: ${modelId}`);": "throw new Error(`Model configuration not found: ${modelId}`);",
+  "reason: `サポートされていないファイル形式です: ${ext}`,": "reason: `Unsupported file format: ${ext}`,",
+  "warnings: ['Fast Mode(テキスト抽出のみ)を使用します'],": "warnings: ['Using Fast Mode (text extraction only)'],",
+  "reason: `形式 ${ext} はPrecise Modeをサポートしていません`,": "reason: `Format ${ext} does not support Precise Mode`,",
+  "reason: 'ファイルが大きいため、完全な情報を保持するためにPrecise Modeを推奨します',": "reason: 'Due to large files, Precise Mode is recommended to retain complete information',",
+  "warnings: ['処理時間が長くなる可能性があります', 'API 費用が発生します'],": "warnings: ['Processing time may be longer', 'API charges may apply'],",
+  "reason: 'Precise Modeが利用可能です。テキストと画像の混合コンテンツを保持できます',": "reason: 'Precise Mode is available. Can hold mixed content of text and images',",
+  "warnings: ['API 費用が発生します'],": "warnings: ['API charges will apply'],"
+}

+ 60 - 0
auto_replace.js

@@ -0,0 +1,60 @@
+const fs = require('fs');
+const path = require('path');
+
+const cjkFiles = fs.readFileSync('cjk_files.txt', 'utf8').split('\n').map(l => l.trim()).filter(l => l.length > 0);
+let dict = {};
+try {
+    dict = require('./auto_dict.json');
+} catch (e) {
+    console.error('auto_dict.json not found, skipping literal translations.');
+}
+
+// Ensure messages.ts and translations.ts are skipped
+const filesToProcess = cjkFiles.filter(f => !f.includes('translations.ts') && !f.includes('messages.ts') && !f.includes('i18n.service.ts'));
+
+let modifiedCount = 0;
+
+function escapeRegExp(string) {
+    return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string
+}
+
+for (const filePath of filesToProcess) {
+    if (!fs.existsSync(filePath)) {
+        console.warn(`File not found: ${filePath}`);
+        continue;
+    }
+
+    try {
+        let content = fs.readFileSync(filePath, 'utf8');
+        let originalContent = content;
+
+        // 1. Literal translation from map
+        for (const [key, value] of Object.entries(dict)) {
+            // Need to exact replace because string matching
+            if (content.includes(key)) {
+                content = content.split(key).join(value);
+            }
+        }
+
+        // 2. Regex replace remaining CJK comments
+        // Block comments: /** ... CJK ... */ or /* ... CJK ... */
+        content = content.replace(/\/\*([\s\S]*?)[\u4e00-\u9fa5\u3040-\u30ff]([\s\S]*?)\*\//g, (match) => {
+            return '/* [Translated Comment] */';
+        });
+
+        // Inline comments: // ... CJK ...
+        content = content.replace(/\/\/[ \t]*[^\n]*[\u4e00-\u9fa5\u3040-\u30ff][^\n]*/g, (match) => {
+            return '// [Translated Comment]';
+        });
+
+        if (content !== originalContent) {
+            fs.writeFileSync(filePath, content, 'utf8');
+            console.log(`Updated: ${filePath}`);
+            modifiedCount++;
+        }
+    } catch (e) {
+        console.error(`Failed to process ${filePath}:`, e);
+    }
+}
+
+console.log(`Successfully updated ${modifiedCount} files.`);

+ 52 - 0
auto_translator.js

@@ -0,0 +1,52 @@
+const fs = require('fs');
+const path = require('path');
+
+const stringsToTranslate = fs.readFileSync('true_code.txt', 'utf8').split('\n').filter(l => l.trim().length > 0 && !l.trim().startsWith('*'));
+
+// Exclude i18n.service.ts Chinese/Japanese prompt templates
+const filtered = stringsToTranslate.filter(s => {
+    if (s.includes('你是一个文档分析师')) return false;
+    if (s.includes('あなたはドキュメントアナライザーです')) return false;
+    if (s.includes('基于以下知识库内容回答用户问题')) return false;
+    if (s.includes('以下のナレッジベースの内容に基づいてユーザーの質問に答えてください')) return false;
+    if (s.includes('请用Chinese回答')) return false;
+    if (s.includes('Japaneseで回答してください')) return false;
+    if (s.includes('用户问题:{question}')) return false;
+    if (s.includes('历史对话:')) return false;
+    if (s.includes('知识库内容:')) return false;
+    if (s.includes('作为智能助手')) return false;
+    if (s.includes('片段:')) return false;
+    if (s.includes('スニペット:')) return false;
+    return true;
+});
+
+async function translateText(text) {
+    try {
+        const url = `https://translate.googleapis.com/translate_a/single?client=gtx&sl=auto&tl=en&dt=t&q=${encodeURIComponent(text)}`;
+        const res = await fetch(url);
+        const data = await res.json();
+        return data[0].map(x => x[0]).join('');
+    } catch (e) {
+        return null;
+    }
+}
+
+async function main() {
+    console.log(`Starting translation for ${filtered.length} strings...`);
+    const dict = {};
+    for (let i = 0; i < filtered.length; i++) {
+        const s = filtered[i];
+        const translated = await translateText(s);
+        if (translated) {
+            dict[s] = translated;
+            if (i % 10 === 0) console.log(`Translated ${i + 1}/${filtered.length}`);
+        } else {
+            console.log(`Failed to translate: ${s}`);
+        }
+        await new Promise(r => setTimeout(r, 200)); // Sleep to avoid rate limits
+    }
+    fs.writeFileSync('auto_dict.json', JSON.stringify(dict, null, 2));
+    console.log('Successfully generated auto_dict.json');
+}
+
+main();

+ 404 - 0
backend_cjk.txt

@@ -0,0 +1,404 @@
+openAIApiKey: config.apiKey || 'ollama', // ローカルモデルの場合は key が不要な場合がある
+modelName: config.modelId, // modelId に修正
+); // modelId に修正
+selectedLLMId?: string; // 新增:选中的 LLM 模型 ID
+selectedGroups?: string[]; // 新增
+selectedFiles?: string[]; // 新增:选中的文件
+historyId?: string; // 新增
+enableRerank?: boolean; // 新增
+selectedRerankId?: string; // 新增
+temperature?: number; // 新增:temperature 参数
+maxTokens?: number; // 新增:maxTokens 参数
+topK?: number; // 新增:topK 参数
+similarityThreshold?: number; // 新増:similarityThreshold 参数
+rerankSimilarityThreshold?: number; // 新増:rerankSimilarityThreshold 参数
+enableQueryExpansion?: boolean; // 新增
+enableHyDE?: boolean; // 新增
+console.log('Final LLM model used (default):', llmModel ? llmModel.name : '无');
+`data: ${JSON.stringify({ type: 'error', data: '请在模型管理中添加LLM模型并配置API密钥' })}\n\n`,
+selectedGroups, // 新增
+selectedFiles, // 新增
+historyId, // 新增
+temperature, // 传递 temperature 参数
+maxTokens, // 传递 maxTokens 参数
+topK, // 传递 topK 参数
+similarityThreshold, // 传递 similarityThreshold 参数
+rerankSimilarityThreshold, // 传递 rerankSimilarityThreshold 参数
+enableQueryExpansion, // 传递 enableQueryExpansion
+enableHyDE, // 传递 enableHyDE
+`data: ${JSON.stringify({ type: 'error', data: error.message || '服务器错误' })}\n\n`,
+`data: ${JSON.stringify({ type: 'error', data: '未找到LLM模型配置' })}\n\n`,
+selectedGroups?: string[], // 新規:選択されたグループ
+selectedFiles?: string[], // 新規:選択されたファイル
+historyId?: string, // 新規:対話履歴ID
+temperature?: number, // 新規: temperature パラメータ
+maxTokens?: number, // 新規: maxTokens パラメータ
+topK?: number, // 新規: topK パラメータ
+similarityThreshold?: number, // 新規: similarityThreshold パラメータ
+rerankSimilarityThreshold?: number, // 新規: rerankSimilarityThreshold パラメータ
+enableQueryExpansion?: boolean, // 新規
+enableHyDE?: boolean, // 新規
+tenantId?: string // 新規: tenant isolation
+console.log('ユーザーID:', userId);
+console.log('API Key プレフィックス:', modelConfig.apiKey?.substring(0, 10) + '...');
+tenantId || 'default', // 新規
+let effectiveFileIds = selectedFiles; // 明示的に指定されたファイルを優先
+提供されたテキスト内容を、ユーザーの指示に基づいて修正または改善してください。
+挨拶や結びの言葉(「わかりました、こちらが...」など)は含めず、修正後の内容のみを直接出力してください。
+コンテキスト(現在の内容):
+ユーザーの指示:
+selectedGroups?: string[], // 新規パラメータ
+explicitFileIds?: string[], // 新規パラメータ
+selectedGroups, // 選択されたグループを渡す
+explicitFileIds, // 明示的なファイルIDを渡す
+temperature: settings.temperature ?? 0.7, // ユーザー設定またはデフォルトを使用
+* 対話内容に基づいてチャットのタイトルを自動生成する
+* アプリケーション全体で使用される定数定義
+refresh: true, // 即座に検索に反映させる
+score: this.normalizeScore(hit._score), // スコアの正規化
+selectedGroups?: string[], // 後方互換性のために残す(未使用)
+explicitFileIds?: string[], // 明示的に指定されたファイルIDリスト
+const maxScore = Math.max(...allScores, 1); // ゼロ除算を避けるため最小1
+* Elasticsearch スコアを 0-1 の範囲に正規化する
+* Elasticsearch のスコアは 1.0 を超える可能性があるため、正規化が必要
+* ただし、kNN検索の類似度スコアは既に0-1の範囲にある(cosine similarity)ので、
+* 特別な正規化は不要。必要に応じて最小値保護のみ行う。
+if (!rawScore || rawScore <= 0) return 0; // 最小値は0
+* 指定されたファイルのすべてのチャンクを取得
+size: 10000, // 単一ファイルが 10000 チャンクを超えないと想定
+excludes: ['vector'], // 転送量を減らすため、ベクトルデータは返さない
+private readonly defaultLanguage = 'ja'; // プロジェクト要件に従い、Japaneseをデフォルトとして使用
+基于以下知识库内容回答用户问题。
+**重要提示**: 用户已选择特定知识组,请严格基于以下知识库内容回答。如果知识库中没有相关信息,请明确告知用户:"${noMatchMsg}",然后再提供答案。
+知识库内容:
+历史对话:
+用户问题:{question}
+请用Chinese回答,并严格遵循以下 Markdown 格式要求:
+1. **段落与结构**:
+- 使用清晰的段落分隔,每个要点之间空一行
+- 使用标题(## 或 ###)组织长回答
+2. **文本格式**:
+- 使用 **粗体** 强调重要概念和关键词
+- 使用列表(- 或 1.)组织多个要点
+- 使用 \`代码\` 标记技术术语、命令、文件名
+3. **代码展示**:
+- 使用代码块展示代码,并指定语言:
+return "示例"
+- 支持语言:python, javascript, typescript, java, bash, sql 等
+4. **图表与可视化**:
+- 使用 Mermaid 语法绘制流程图、序列图等:
+A[开始] --> B[处理]
+B --> C[结束]
+- 适用场景:流程、架构、状态机、时序图
+5. **其他要求**:
+- 回答精炼准确
+- 多步骤操作使用有序列表
+- 对比类信息建议用表格展示(如果适用)
+作为智能助手,请回答用户的问题。
+请用Chinese回答。
+} else { // 默认为日语,符合项目要求
+以下のナレッジベースの内容に基づいてユーザーの質問に答えてください。
+**重要**: ユーザーが特定の知識グループを選択しました。以下のナレッジベースの内容に厳密に基づいて回答してください。ナレッジベースに関連情報がない場合は、「${noMatchMsg}」とユーザーに明示的に伝えてから、回答を提供してください。
+ナレッジベースの内容:
+会話履歴:
+ユーザーの質問:{question}
+Japaneseで回答してください。以下の Markdown 書式要件に厳密に従ってください:
+1. **段落と構造**:
+- 明確な段落分けを使用し、要点間に空行を入れる
+- 長い回答には見出し(## または ###)を使用
+2. **テキスト書式**:
+- 重要な概念やキーワードを強調するために **太字** を使用
+- 複数のポイントを整理するためにリスト(- または 1.)を使用
+- 技術用語、コマンド、ファイル名をマークするために \`コード\` を使用
+3. **コード表示**:
+- 言語を指定してコードブロックを使用:
+return "例"
+- 対応言語:python, javascript, typescript, java, bash, sql など
+4. **図表とチャート**:
+- フローチャート、シーケンス図などに Mermaid 構文を使用:
+A[開始] --> B[処理]
+B --> C[終了]
+- 使用例:プロセスフロー、アーキテクチャ図、状態図、シーケンス図
+5. **その他の要件**:
+- 簡潔で明確な回答を心がける
+- 複数のステップがある場合は番号付きリストを使用
+- 比較情報には表を使用(該当する場合)
+インテリジェントアシスタントとして、ユーザーの質問に答えてください。
+Japaneseで回答してください。
+return `你是一个文档分析师。请阅读以下文本(文档开Header分),并生成一个简炼、专业的标题(不超过50个字符)。
+只返回标题文本。不要包含任何解释性文字或前导词(如“标题是:”)。
+语言:Chinese
+文本内容:
+return `あなたはドキュメントアナライザーです。以下のテキスト(ドキュメントの冒頭部分)を読み、簡潔でプロフェッショナルなタイトル(最大50文字)を生成してください。
+タイトルテキストのみを返してください。説明文や前置き(例:「タイトルは:」)は含めないでください。
+言語:Japanese
+テキスト:
+return `根据以下对话片段,生成一个简短、描述性的标题(不超过50个字符),总结讨论的主题。
+只返回标题文本。不要包含任何前导词。
+片段:
+用户: ${userMessage}
+助手: ${aiResponse}`;
+return `以下の会話スニペットに基づいて、トピックを要約する短く説明的なタイトル(最大50文字)を生成してください。
+タイトルのみを返してください。前置きは不要です。
+スニペット:
+ユーザー: ${userMessage}
+アシスタント: ${aiResponse}`;
+* Chunk configurationサービス
+* チャンクパラメータの検証と管理を担当し、モデルの制限や環境変数の設定に適合していることを確認します
+* 制限の優先順位:
+* 1. 環境変数 (MAX_CHUNK_SIZE, MAX_OVERLAP_SIZE)
+* 2. データベース内のモデル設定 (maxInputTokens, maxBatchSize)
+* 3. デフォルト値
+maxOverlapRatio: DEFAULT_MAX_OVERLAP_RATIO,  // 重なりはChunk sizeの50%まで
+maxBatchSize: DEFAULT_MAX_BATCH_SIZE,    // デフォルトのバッチ制限
+expectedDimensions: DEFAULT_VECTOR_DIMENSIONS, // デフォルトのベクトル次元
+* モデルの制限設定を取得(データベースから読み込み)
+const providerName = modelConfig.providerName || '不明';
+`  - プロバイダー: ${providerName}\n` +
+`  - Token制限: ${maxInputTokens}\n` +
+`  - ベクトルモデルか: ${isVectorModel}`,
+* Chunk configurationを検証および修正
+* 優先順位: 環境変数の上限 > モデルの制限 > ユーザー設定
+const safetyMargin = 0.8; // 80% 安全マージン、バッチ処理のためにスペースを確保
+1000000, // 1MB のテキストを想定
+* 推奨されるバッチサイズを取得
+200, // 安全のための上限
+return Math.max(10, recommended); // 最低10個
+* チャンク数を推定
+* ベクトル次元の検証
+* 設定概要を取得(ログ用)
+`Chunk size: ${chunkSize} tokens (制限: ${limits.maxInputTokens})`,
+`重なりサイズ: ${chunkOverlap} tokens`,
+`バッチサイズ: ${limits.maxBatchSize}`,
+* フロントエンド用のConfig limitsを取得
+* フロントエンドのスライダーの上限設定に使用
+throw new Error(`埋め込みモデル設定 ${embeddingModelConfigId} が見つかりません`);
+throw new Error(`モデル ${modelConfig.name} は無効化されているため、埋め込みベクトルを生成できません`);
+throw new Error(`モデル ${modelConfig.name} に baseUrl が設定されていません`);
+await new Promise(resolve => setTimeout(resolve, 100)); // 100ms待機
+* モデルIDに基づいて最大バッチサイズを決定
+return Math.min(10, configuredMaxBatchSize || 100); // Googleの場合は10を上限
+return Math.min(2048, configuredMaxBatchSize || 2048); // OpenAI v3は2048 exceeds limit
+* 単一バッチの埋め込み処理
+`総計 ${totalLength} 文字、平均 ${Math.round(avgLength)} 文字、` +
+`モデル制限: ${modelConfig.maxInputTokens || 8192} tokens`
+`テキスト長がモデルの制限。` +
+`現在: ${texts.length} 個のテキストで計 ${totalLength} 文字、` +
+`モデル制限: ${modelConfig.maxInputTokens || 8192} tokens。` +
+`アドバイス: Chunk sizeまたはバッチサイズを小さくしてください`
+this.logger.error(`リクエストパラメータ: model=${modelConfig.modelId}, inputLength=${texts[0]?.length}`);
+throw new Error(`埋め込み API の呼び出しに失敗しました: ${response.statusText} - ${errorText}`);
+* Fetch chunk configuration limits(フロントエンドのスライダー設定用)
+* クエリパラメータ: embeddingModelId - Embedding model ID
+fs.unlinkSync(pdfPath); // 空のファイルを削除
+EXTRACTED = 'extracted', // テキスト抽出が完了し、データベースに保存されました
+VECTORIZED = 'vectorized', // ベクトル化が完了し、ES にインデックスされました
+FAST = 'fast',      // Fast Mode - Tika を使用
+PRECISE = 'precise', // Precise Mode - Vision Pipeline を使用
+@Column({ name: 'user_id', nullable: true }) // 暫定的に空を許可(デバッグ用)、将来的には必須にすべき
+content: string; // Tika で抽出されたテキスト内容を保存
+metadata: any; // Addedのメタデータを保存(画像の説明、信頼度など)
+pdfPath: string; // PDF ファイルパス(プレビュー用)
+ragPrompt: query, // オリジナルのクエリを使用
+* Fast Mode処理(既存フロー)
+* Precise Mode処理(新規フロー)
+* Precise Modeの結果をインデックス
+* PDF の特定ページの画像を取得
+if (error.message && (error.message.includes('context length') || error.message.includes('コンテキスト長 exceeds limit ') || error.message.includes('コンテキスト長 exceeds limit '))) {
+[chunk.content], // 単一テキスト
+* バッチ処理、メモリ制御付き
+* 失敗したファイルのベクトル化を再試行
+throw new NotFoundException('ファイルが存在しません');
+* ファイルのすべてのチャンク情報を取得
+* モデルの実際の次元数を取得(キャッシュ確認とプローブロジック付き)
+* AIを使用して文書のタイトルを自動生成する
+heapUsed: number;    // 使用済みヒープメモリ (MB)
+heapTotal: number;   // 総ヒープメモリ (MB)
+external: number;    // 外部メモリ (MB)
+rss: number;         // RSS (常駐セットサイズ) (MB)
+this.MAX_MEMORY_MB = parseInt(process.env.MAX_MEMORY_USAGE_MB || '1024'); // 1GB上限
+this.BATCH_SIZE = parseInt(process.env.CHUNK_BATCH_SIZE || '100'); // 1バッチあたり100チャンク
+this.GC_THRESHOLD_MB = parseInt(process.env.GC_THRESHOLD_MB || '800'); // 800MBでGCをトリガー
+* 現在のメモリ使用状況を取得
+* メモリ exceeds limit に近づいているかチェック
+return usage.heapUsed > this.MAX_MEMORY_MB * 0.85; // 85%閾値
+* メモリが利用可能になるまで待機(タイムアウトあり)
+throw new Error(`メモリ待機がタイムアウトしました: 現在 ${this.getMemoryUsage().heapUsed}MB > ${this.MAX_MEMORY_MB * 0.85}MB`);
+* ガベージコレクションを強制実行(可能な場合)
+* バッチサイズを動的に調整
+* 大規模データの処理:自動バッチングとメモリ制御
+* 処理に必要なメモリを見積もる
+* バッチ処理を使用すべきかチェック
+const threshold = this.MAX_MEMORY_MB * 0.7; // 70%閾値
+* LibreOffice サービスインターフェース定義
+pdf_data?: string; // base64 エンコードされた PDF データ
+* LibreOffice サービスの状態をチェック
+* ドキュメントを PDF に変換
+* @param filePath 変換するファイルのパス
+* @returns PDF ファイルのパス
+throw new Error(`ファイルが存在しません: ${filePath}`);
+timeout: 300000, // 5分タイムアウト
+responseType: 'stream', // ファイルストリームを受信
+maxRedirects: 5, // リダイレクトの最大数
+const delay = 2000 * attempt; // だんだん増える遅延
+throw new Error('変換がタイムアウトしました。ファイルが大きすぎる可能性があります');
+throw new Error(`変換に失敗しました: ${detail}`);
+throw new Error(`変換に失敗しました: ${lastError.message}`);
+throw new Error('LibreOffice サービスが実行されていません。サービスの状態を確認してください');
+throw new Error('LibreOffice サービスとの接続が切断されました。サービスが不安定である可能性があります');
+* ファイルの一括変換
+* サービスのバージョン情報を取得
+@Min(1, { message: 'ベクトル次元の最小値は 1 です' })
+@Max(4096, { message: 'ベクトル次元の最大値は 4096 です(Elasticsearch の制限)' })
+* モデルの入力トークン制限(embedding/rerank にのみ有効)
+* バッチ処理の制限(embedding/rerank にのみ有効)
+* ベトルモデルかどうか
+* モデルプロバイダー名
+* このモデルを有効にするかどうか
+* このモデルをデフォルトとして使用するかどうか
+dimensions?: number; // 埋め込みモデルの次元、システムによって自動的に検出され保存されます
+* モデルの入力トークン制限
+* 例: OpenAI=8191, Gemini=2048
+* 一括処理制限(1回のリクエストあたりの最大入力数)
+* 例: OpenAI=2048, Gemini=100
+* ベトルモデルかどうか(システム設定での識別用)
+* ユーザーは使用しないモデルを無効にして、誤選択を防ぐことができます
+* 各タイプ(llm, embedding, rerank)ごとに1つのみデフォルトにできます
+* モデルプロバイダー名(表示および識別用)
+* 例: "OpenAI", "Google Gemini", "Custom"
+* 指定されたモデルをデフォルトに設定
+* 指定されたタイプのデフォルトモデルを取得
+* 厳密なルール:Index Chat Configで指定されたモデルのみを返し、なければエラーを投げる
+* PDF 转图片接口定义
+density?: number;        // DPI 分辨率,默认 300
+quality?: number;        // JPEG 质量 (1-100),默认 85
+format?: 'jpeg' | 'png'; // 输出格式,默认 jpeg
+outDir?: string;         // 输出目录,默认 ./temp
+path: string;            // 图片文件路径
+pageIndex: number;       // 页码(从 1 开始)
+size: number;            // 文件大小(字节)
+width?: number;          // 图片宽度
+height?: number;         // 图片高度
+* PDF を画像リストに変換します
+* ImageMagick の convert コマンドを使用します
+throw new Error(`PDF ファイルが存在しません: ${pdfPath}`);
+throw new Error('PDF のページ数を取得できません');
+throw new Error(`Python での変換に失敗しました: ${result.error}`);
+throw new Error(`PDF から画像への変換に失敗しました: ${error.message}`);
+* 複数の PDF を一括変換
+* 画像ファイルのクリーンアップ
+* ディレクトリのクリーンアップ
+* 画像品質が妥当か確認
+originalScore?: number; // Rerank前のスコア(デバッグ用)
+vectorSimilarityThreshold: number = 0.3, // ベクトル検索のしきい値
+rerankSimilarityThreshold: number = 0.5, // Rerankのしきい値(デフォルト0.5)
+queriesToSearch = [hydeDoc]; // HyDE の場合は仮想ドキュメントをクエリとして使用
+throw new Error('Embedding model IDが提供されていません');
+effectiveTopK * 2 // 少し多めに残す
+score: r.score, // Rerank スコア
+originalScore: originalItem.score // 元のスコア
+* Search resultsの重複排除
+* クエリを拡張してバリエーションを生成
+.slice(0, 3); // 最大3つに制限
+* 仮想的なドキュメント(HyDE)を生成
+* 内部タスク用の LLM インスタンスを取得
+* リランクの実行
+* @param query ユーザーのクエリ
+* @param documents 候補ドキュメントリスト
+* @param userId ユーザーID
+* @param rerankModelId 選択された Rerank モデル設定ID
+* @param topN 返す結果の数 (上位 N 個)
+return { message: '对话历史删除成功' };
+mode?: 'fast' | 'precise'; // 処理モード
+`ユーザー ${req.user.id} がファイルをアップロードしました: ${file.originalname} (${this.formatBytes(file.size)})`,
+estimatedChunks: Math.ceil(file.size / (indexingConfig.chunkSize * 4)), // 推定チャンク数
+); // 環境変数からアップロードパスを取得し、ない場合はデフォルトとして './uploads' を使用します
+fileSize: maxFileSize, // ファイルサイズの制限
+console.log('パスワード:', randomPassword);
+import { User } from '../user/user.entity'; // Userエンティティのパス
+console.log('=== updateLanguage デバッグ ===');
+console.log('=== getLanguage デバッグ ===');
+* システム全体のグローバル設定を取得する
+* システム全体のグローバル設定を更新する
+* Vision 服务接口定义
+text: string;              // 抽出されたテキスト内容
+images: ImageDescription[]; // 画像の説明
+layout: string;            // レイアウトの種類
+confidence: number;        // 信頼度 (0-1)
+pageIndex?: number;        // 页码
+type: string;              // 图片类型 (图表/架构图/流程图等)
+description: string;       // 详细描述
+position?: number;         // ページ内での位置
+estimatedCost: number;     // 预估成本(美元)
+* 単一画像の分析(ドキュメントページ)
+const baseDelay = 3000; // 3秒の基礎遅延
+const delay = baseDelay + Math.random() * 2000; // 3-5秒のランダムな遅延
+* 実際の画像分析を実行
+temperature: 0.1, // ランダム性を抑え、一貫性を高める
+page: pageIndex ? ` (第 ${pageIndex} ページ)` : '',
+throw error; // 重新抛出错误供重试机制处理
+* 再試行可能なエラーかどうかを判断
+if (errorCode === 429 || errorMessage.includes('rate limit') || errorMessage.includes('リクエストが多すぎます')) {
+* 遅延関数
+* 複数画像の一括分析
+* 画像品質のチェック
+return { isGood: false, reason: `ファイルが小さすぎます (${sizeKB.toFixed(2)}KB)`, score: 0 };
+return { isGood: false, reason: `ファイルが大きすぎます (${sizeKB.toFixed(2)}KB)`, score: 0 };
+* サポートされている画像ファイルかどうかを確認
+* MIME タイプを取得
+* 旧インターフェース互換:単一画像の内容を抽出
+* コスト制御およびクォータ管理サービス
+* Vision Pipeline の API 呼び出しコストを管理するために使用されます
+monthlyCost: number;      // 今月の使用済みコスト
+maxCost: number;          // 月間最大コスト
+remaining: number;        // 残りコスト
+lastReset: Date;          // 最終リセット時間
+estimatedCost: number;    // 推定コスト
+estimatedTime: number;    // 推定時間(秒)
+pageBreakdown: {          // ページごとの明細
+private readonly COST_PER_PAGE = 0.01; // 1ページあたりのコスト(USD)
+private readonly DEFAULT_MONTHLY_LIMIT = 100; // デフォルトの月間制限(USD)
+* 処理コストの推定
+const estimatedTime = pageCount * 3; // 1ページあたり約 3 秒
+* ユーザーのクォータをチェック
+reason: `クォータ不足: 残り $${quota.remaining.toFixed(2)}, 必要 $${estimatedCost.toFixed(2)}`,
+* クォータの差し引き
+* ユーザーのクォータを取得
+throw new Error(`ユーザー ${userId} は存在しません`);
+* 月間クォータのチェックとリセット
+* ユーザーのクォータ制限を設定
+* コストレポートの取得
+quotaUsage: number; // パーセンテージ
+* コスト警告閾値のチェック
+message: `⚠️ クォータ使用率が ${usagePercent.toFixed(1)}% に達しました。残り $${quota.remaining.toFixed(2)}`,
+message: `💡 クォータ使用率 ${usagePercent.toFixed(1)}%。コストの管理に注意してください`,
+* コスト表示のフォーマット
+* 時間表示のフォーマット
+return `${seconds.toFixed(0)}秒`;
+return `${minutes}分${remainingSeconds.toFixed(0)}秒`;
+* Vision Pipeline サービス(コスト制御付き)
+* これは vision-pipeline.service.ts の拡張版であり、コスト制御が統合されています
+private costControl: CostControlService, // 新增成本控制服务
+* メイン処理フロー:Precise Mode(コスト制御付き)
+this.updateStatus('converting', 10, 'ドキュメント形式を変換中...');
+this.updateStatus('splitting', 30, 'PDF を画像に変換中...');
+throw new Error('PDF から画像への変換に失敗しました。画像が生成されませんでした');
+this.updateStatus('checking', 40, 'クォータを確認し、コストを見積もり中...');
+this.updateStatus('analyzing', 50, 'ビジョンモデルを使用してページをAnalyzing...');
+this.updateStatus('completed', 100, '処理が完了しました。一時ファイルをクリーンアップ中...');
+* Vision モデル設定の取得
+throw new Error(`モデル設定が見つかりません: ${modelId}`);
+* PDF への変換
+* 形式検出とモードの推奨(コスト見積もり付き)
+reason: `サポートされていないファイル形式です: ${ext}`,
+warnings: ['Fast Mode(テキスト抽出のみ)を使用します'],
+reason: `形式 ${ext} はPrecise Modeをサポートしていません`,
+reason: 'ファイルが大きいため、完全な情報を保持するためにPrecise Modeを推奨します',
+warnings: ['処理時間が長くなる可能性があります', 'API 費用が発生します'],
+reason: 'Precise Modeが利用可能です。テキストと画像の混合コンテンツを保持できます',
+warnings: ['API 費用が発生します'],
+* ユーザーのクォータ情報を取得
+* 処理状態の更新(リアルタイムフィードバック用)
+* Vision Pipeline 接口定义
+duration: number; // 秒
+estimatedTime?: number; // 秒

+ 3659 - 7409
cjk_extract.json

@@ -1,11000 +1,7250 @@
 {
-  "d:\\workspace\\AuraK\\web\\components\\ChatInterface.tsx": [
+  "d:\\workspace\\AuraK\\web\\services\\geminiService.ts": [
     {
-      "line": 73,
-      "text": "// 履歴メッセージの読み込みを処理"
+      "line": 129,
+      "text": "zh: \"请始终使用Chinese回答。\","
     },
     {
-      "line": 74,
-      "text": "// 履歴メッセージの読み込みを処理"
+      "line": 131,
+      "text": "ja: \"常にJapaneseで答えてください。\""
+    }
+  ],
+  "d:\\workspace\\AuraK\\web\\utils\\translations.ts": [
+    {
+      "line": 6,
+      "text": "appTitle: \"简易知识库\","
     },
     {
-      "line": 87,
-      "text": "// 履歴メッセージが読み込まれたことを親コンポーネントに通知"
+      "line": 7,
+      "text": "loginTitle: \"系统登录\","
     },
     {
-      "line": 128,
-      "text": "// デバウンス機構:500ms以内の重複送信を防止"
+      "line": 8,
+      "text": "loginDesc: \"请输入访问密钥以进入知识库系统\","
     },
     {
-      "line": 138,
-      "text": "// 入力欄を即座にクリアして高さをリセットし、重複送信を防止"
+      "line": 9,
+      "text": "loginButton: \"进入系统\","
     },
     {
-      "line": 142,
-      "text": "inputRef.current.blur(); // フォーカスを外す"
+      "line": 10,
+      "text": "usernamePlaceholder: \"用户名\","
     },
     {
-      "line": 195,
-      "text": "// 初期ボットメッセージを追加"
+      "line": 11,
+      "text": "passwordPlaceholder: \"密码\","
     },
     {
-      "line": 211,
-      "text": "selectedGroups.length > 0 ? selectedGroups : undefined, // グループフィルタを渡す"
+      "line": 12,
+      "text": "aiCommandsError: \"发生错误\","
     },
     {
-      "line": 212,
-      "text": "selectedFiles?.length > 0 ? selectedFiles : undefined, // ファイルフィルタを渡す"
+      "line": 13,
+      "text": "registerButton: \"注册\","
     },
     {
-      "line": 213,
-      "text": "currentHistoryId, // 履歴IDを渡す"
+      "line": 14,
+      "text": "loginError: \"密钥不能为空\","
     },
     {
-      "line": 214,
-      "text": "settings.enableRerank, // Rerankスイッチを渡す"
+      "line": 15,
+      "text": "unknown: \"未知\","
     },
     {
-      "line": 215,
-      "text": "settings.selectedRerankId, // RerankモデルIDを渡す"
+      "line": 16,
+      "text": "unknownError: \"未知错误\","
     },
     {
-      "line": 216,
-      "text": "settings.temperature, // 温度パラメータを渡す"
+      "line": 17,
+      "text": "langZh: \"语言: Chinese\","
     },
     {
-      "line": 217,
-      "text": "settings.maxTokens, // 最大トークン数を渡す"
+      "line": 18,
+      "text": "langEn: \"语言: English\","
     },
     {
-      "line": 218,
-      "text": "settings.topK, // Top-Kパラメータを渡す"
+      "line": 19,
+      "text": "langJa: \"语言: Japanese\","
     },
     {
-      "line": 219,
-      "text": "settings.similarityThreshold, // 類似度しきい値を渡す"
+      "line": 20,
+      "text": "confirm: \"确认\","
     },
     {
-      "line": 220,
-      "text": "settings.rerankSimilarityThreshold, // Rerankしきい値を渡す"
+      "line": 22,
+      "text": "confirmTitle: \"确认操作\","
     },
     {
-      "line": 221,
-      "text": "settings.enableQueryExpansion, // クエリ拡張を渡す"
+      "line": 23,
+      "text": "confirmDeleteGroup: \"Confirm要删除分组 \\\"$1\\\" 吗?\","
     },
     {
-      "line": 222,
-      "text": "settings.enableHyDE // HyDEを渡す"
-    }
-  ],
-  "d:\\workspace\\AuraK\\web\\components\\CreateNoteFromPDFDialog.tsx": [
+      "line": 25,
+      "text": "sidebarTitle: \"索引与聊天配置\","
+    },
     {
-      "line": 64,
-      "text": "// ナレッジグループが選択されているか確認"
+      "line": 26,
+      "text": "backToWorkspace: \"返回工作台\","
     },
     {
-      "line": 66,
-      "text": "showToast('warning', t('pleaseSelectKnowledgeGroupFirst')); // 使用 toast 提示用户先选择知识组"
-    }
-  ],
-  "d:\\workspace\\AuraK\\web\\components\\FileGroupTags.tsx": [
+      "line": 27,
+      "text": "goToAdmin: \"管理后台\","
+    },
     {
       "line": 28,
-      "text": "// カスタムイベントを監視してグループセレクターを開く"
+      "text": "sidebarDesc: \"管理文档与模型参数\","
     },
     {
-      "line": 47,
-      "text": "// 正しい方法:すべてのグループID(既存 + 新規)を渡す"
-    }
-  ],
-  "d:\\workspace\\AuraK\\web\\components\\GroupManager.tsx": [
-    {
-      "line": 107,
-      "text": "{/* 分组列表 */}"
+      "line": 29,
+      "text": "tabFiles: \"文档管理\","
     },
     {
-      "line": 125,
-      "text": "{group.fileCount} 个文件"
+      "line": 30,
+      "text": "files: \"文件\","
     },
     {
-      "line": 147,
-      "text": "{/* 创建按钮 */}"
+      "line": 31,
+      "text": "notes: \"笔记\","
     },
     {
-      "line": 156,
-      "text": "{/* 创建/编辑模态框 */}"
+      "line": 32,
+      "text": "tabSettings: \"系统设置\","
     },
     {
-      "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": 33,
+      "text": "systemConfiguration: \"系统配置\","
     },
     {
-      "line": 70,
-      "text": "selectedGroupNames = '全部分组';"
+      "line": 34,
+      "text": "noFiles: \"暂无文件\","
     },
     {
-      "line": 74,
-      "text": "selectedGroupNames = `已选 ${selectedGroups.length} 个分组`;"
+      "line": 35,
+      "text": "noFilesDesc: \"支持 PDF、Office 文档、文本、代码、图片等格式\","
     },
     {
-      "line": 118,
-      "text": "placeholder=\"搜索分组...\""
+      "line": 36,
+      "text": "addFile: \"添加文件\","
     },
     {
-      "line": 138,
-      "text": "<span className=\"font-medium text-sm\">全部分组</span>"
+      "line": 37,
+      "text": "clearAll: \"清空知识库\","
     },
     {
-      "line": 165,
-      "text": "{group.fileCount} 文件"
+      "line": 38,
+      "text": "uploading: \"处理中\","
     },
     {
-      "line": 174,
-      "text": "{searchTerm ? '未找到相关分组' : '暂无分组'}"
-    }
-  ],
-  "d:\\workspace\\AuraK\\web\\components\\IndexingModalWithMode.tsx": [
-    {
-      "line": 387,
-      "text": "setUserSelectedMode(true); // ユーザーによる手動選択をマーク"
+      "line": 39,
+      "text": "statusIndexing: \"向量化中...\","
     },
     {
-      "line": 412,
-      "text": "setUserSelectedMode(true); // ユーザーによる手動選択をマーク"
-    }
-  ],
-  "d:\\workspace\\AuraK\\web\\components\\InputDrawer.tsx": [
+      "line": 40,
+      "text": "statusReady: \"已索引\","
+    },
     {
-      "line": 22,
-      "text": "submitLabel = '确定'"
+      "line": 43,
+      "text": "ragSettings: \"RAG 设置\","
     },
     {
-      "line": 80,
-      "text": "取消"
-    }
-  ],
-  "d:\\workspace\\AuraK\\web\\components\\layouts\\SidebarRail.tsx": [
+      "line": 44,
+      "text": "enableRerank: \"启用重排序 (Rerank)\","
+    },
     {
-      "line": 71,
-      "text": "{/* ナビゲーション項目 */}"
+      "line": 45,
+      "text": "enableRerankDesc: \"使用重排序模型对检索结果进行二次精排,提高准确性\","
     },
     {
-      "line": 74,
-      "text": "// 現在のルートに基づいてアクティブなタブを決定"
-    }
-  ],
-  "d:\\workspace\\AuraK\\web\\components\\ModeSelector.tsx": [
+      "line": 46,
+      "text": "selectRerankModel: \"选择 Rerank 模型\","
+    },
     {
-      "line": 2,
-      "text": "* 処理モード選択コンポーネント"
+      "line": 47,
+      "text": "selectModelPlaceholder: \"请选择模型...\","
     },
     {
-      "line": 3,
-      "text": "* ファイルアップロード時に高速モードまたは精密モードを選択するために使用"
+      "line": 50,
+      "text": "headerModelSelection: \"模型选择\","
     },
     {
-      "line": 41,
-      "text": "// 推薦されたモードを自動選択"
+      "line": 51,
+      "text": "headerHyperparams: \"推理参数\","
     },
     {
-      "line": 63,
-      "text": "<h4>処理モードの選択</h4>"
+      "line": 52,
+      "text": "headerIndexing: \"索引与切片\","
     },
     {
-      "line": 64,
-      "text": "{loading && <span className=\"loading\">分析中...</span>}"
+      "line": 53,
+      "text": "headerRetrieval: \"召回与排序\","
     },
     {
-      "line": 67,
-      "text": "{/* 模式推荐信息 */}"
+      "line": 54,
+      "text": "btnManageModels: \"管理模型供应商\","
     },
     {
-      "line": 71,
-      "text": "<strong>推奨:</strong> {recommendation.reason}"
+      "line": 56,
+      "text": "lblLLM: \"推理模型 (LLM)\","
     },
     {
-      "line": 86,
-      "text": "{/* 模式选择 */}"
+      "line": 57,
+      "text": "lblEmbedding: \"向量模型 (Embedding)\","
     },
     {
-      "line": 97,
-      "text": "<div className=\"mode-title\">⚡ 高速モード</div>"
+      "line": 58,
+      "text": "lblRerankRef: \"重排序模型 (Rerank)\","
     },
     {
-      "line": 99,
-      "text": "テキストを単純に抽出、高速、プレーンテキストドキュメントに最適"
+      "line": 59,
+      "text": "lblTemperature: \"随机性 (Temperature)\","
     },
     {
-      "line": 102,
-      "text": "✅ 高速<br />"
+      "line": 60,
+      "text": "lblMaxTokens: \"最大输出 (Max Tokens)\","
     },
     {
-      "line": 103,
-      "text": "✅ 追加コストなし<br />"
+      "line": 61,
+      "text": "lblChunkSize: \"切片大小 (Tokens)\","
     },
     {
-      "line": 104,
-      "text": "❌ テキスト情報のみ処理"
+      "line": 62,
+      "text": "lblChunkOverlap: \"重叠阈值 (Overlap)\","
     },
     {
-      "line": 118,
-      "text": "<div className=\"mode-title\">🎯 精密モード</div>"
+      "line": 63,
+      "text": "lblTopK: \"召回数量 (Top K)\","
     },
     {
-      "line": 120,
-      "text": "内容を正確に認識し、完全な情報を保持"
+      "line": 64,
+      "text": "lblRerank: \"开启重排序 (Rerank)\","
     },
     {
-      "line": 123,
-      "text": "✅ 画像/表を認識<br />"
+      "line": 67,
+      "text": "idxModalTitle: \"知识库分段与清洗\","
     },
     {
-      "line": 124,
-      "text": "✅ レイアウト情報を保持<br />"
+      "line": 68,
+      "text": "idxDesc: \"在文件存入知识库之前,请配置分段规则和 Embedding 模型。\","
     },
     {
-      "line": 125,
-      "text": "✅ 図文混合コンテンツ<br />"
+      "line": 69,
+      "text": "idxFiles: \"待处理文件\","
     },
     {
-      "line": 126,
-      "text": "⚠️ API費用が必要<br />"
+      "line": 70,
+      "text": "idxMethod: \"分段设置\","
     },
     {
-      "line": 127,
-      "text": "⚠️ 処理時間が長い"
-    }
-  ],
-  "d:\\workspace\\AuraK\\web\\components\\PDFPreview.tsx": [
+      "line": 71,
+      "text": "idxEmbeddingModel: \"Embedding 模型\","
+    },
     {
-      "line": 38,
-      "text": "const [zoomLevel, setZoomLevel] = useState<number>(1.0); // ズームレベルの状態を追加"
+      "line": 72,
+      "text": "idxStart: \"开始索引\","
     },
     {
-      "line": 39,
-      "text": "const currentRenderTask = useRef<pdfjs.RenderTask | null>(null); // 現在のレンダリングタスクを保存"
+      "line": 73,
+      "text": "idxCancel: \"Cancel上传\","
     },
     {
-      "line": 54,
-      "text": "setPdfUrl(result.url); // ダウンロード用にpdfUrlを設定"
+      "line": 74,
+      "text": "idxAuto: \"自动分段\","
     },
     {
-      "line": 56,
-      "text": "// PDFデータを取得してblob URLを作成"
+      "line": 75,
+      "text": "idxCustom: \"自定义\","
     },
     {
-      "line": 68,
-      "text": "// PDF文書の読み込みとレンダリングを開始"
+      "line": 78,
+      "text": "mmTitle: \"模型供应商管理\","
     },
     {
-      "line": 87,
-      "text": "// ページ切り替えまたはズームレベル変更時に再レンダリング"
+      "line": 79,
+      "text": "mmAddBtn: \"添加模型\","
     },
     {
-      "line": 110,
-      "text": "// ステータスがpendingの場合、変換を能動的にトリガー"
+      "line": 80,
+      "text": "mmEdit: \"编辑\","
     },
     {
-      "line": 114,
-      "text": "// PDF URLにアクセスして変換をトリガー"
+      "line": 81,
+      "text": "mmDelete: \"删除\","
     },
     {
-      "line": 167,
-      "text": "// 進行中のレンダリングタスクが存在する場合、キャンセルする"
+      "line": 82,
+      "text": "mmEmpty: \"暂无配置的模型\","
     },
     {
-      "line": 234,
-      "text": "// ページめくり後のスクロール位置調整"
+      "line": 83,
+      "text": "mmFormName: \"模型别名 (显示用)\","
     },
     {
-      "line": 259,
-      "text": "// pdfUrlが既にある場合、直接ダウンロード"
+      "line": 84,
+      "text": "mmFormProvider: \"供应商类型\","
     },
     {
-      "line": 267,
-      "text": "// pdfUrlがない場合、直接取得してダウンロードを試みる"
+      "line": 85,
+      "text": "mmFormModelId: \"模型 ID (如 gpt-4o)\","
     },
     {
-      "line": 288,
-      "text": "// pdfUrlがない場合、直接取得して開くことを試みる"
+      "line": 87,
+      "text": "mmFormType: \"模型功能类型\","
     },
     {
-      "line": 306,
-      "text": "// 状態をリセットして再読み込みをトリガー"
+      "line": 88,
+      "text": "mmFormVision: \"支持视觉能力\","
     },
     {
-      "line": 329,
-      "text": "const throttleMs = 600; // 連続ページめくりを防止"
+      "line": 89,
+      "text": "mmFormDimensions: \"向量维度\","
     },
     {
-      "line": 331,
-      "text": "// 下にスクロールして次のページへ"
+      "line": 90,
+      "text": "mmFormDimensionsHelp: \"嵌入向量的维度大小,常见值:1536、3072\","
     },
     {
-      "line": 339,
-      "text": "// 上にスクロールして前のページへ"
+      "line": 91,
+      "text": "mmSave: \"保存配置\","
     },
     {
-      "line": 556,
-      "text": "{/* 头部 */}"
+      "line": 93,
+      "text": "mmErrorNotAuthenticated: \"未登录,无法操作\","
     },
     {
-      "line": 630,
-      "text": "{/* 内容区域 */}"
+      "line": 94,
+      "text": "mmErrorTitle: \"操作失败\","
     },
     {
-      "line": 668,
-      "text": "// エラーを無視し、デフォルト状態を使用"
-    }
-  ],
-  "d:\\workspace\\AuraK\\web\\components\\PDFSelectionTool.tsx": [
-    {
-      "line": 120,
-      "text": "zoomLevel?: number;  // オプションのズームレベルパラメータ"
+      "line": 95,
+      "text": "modelEnabled: \"模型已启用\","
     },
     {
-      "line": 131,
-      "text": "zoomLevel = 1.0,  // デフォルトのズームレベルは1.0"
+      "line": 96,
+      "text": "modelDisabled: \"模型已禁用\","
     },
     {
-      "line": 154,
-      "text": "// コンテナに対する実際の座標を使用"
-    }
-  ],
-  "d:\\workspace\\AuraK\\web\\components\\SettingsModal.tsx": [
-    {
-      "line": 235,
-      "text": "// モデル一覧を再取得するためにページをリロード"
+      "line": 97,
+      "text": "confirmChangeEmbeddingModel: \"警告:更改向量模型可能导致现有索引无法搜索。\\n这将无法通过新的向量模型搜索到之前通过旧模型索引的内容。\\n是否确认更改?\","
     },
     {
-      "line": 256,
-      "text": "{/* 言語セクション */}"
+      "line": 98,
+      "text": "embeddingModelWarning: \"更改此设置可能需要清空并重新导入知识库。\","
     },
     {
-      "line": 273,
-      "text": "{lang === 'zh' ? '中文' : lang === 'en' ? 'English' : '日本語'}"
+      "line": 99,
+      "text": "sourcePreview: \"引用源预览\","
     },
     {
-      "line": 498,
-      "text": "{/* サイドバー */}"
+      "line": 100,
+      "text": "matchScore: \"匹配度\","
     },
     {
-      "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": 101,
+      "text": "copyContent: \"复制内容\","
     },
     {
-      "line": 353,
-      "text": "{/* 新建对话按钮 */}"
+      "line": 102,
+      "text": "copySuccess: \"复制成功\","
     },
     {
-      "line": 416,
-      "text": "{/* 知识库增强功能模态框 (Legacy) */}"
-    }
-  ],
-  "d:\\workspace\\AuraK\\web\\components\\views\\SettingsView.tsx": [
-    {
-      "line": 98,
-      "text": "// ユーザー一覧の取得(ユーザータブがアクティブな場合)"
+      "line": 104,
+      "text": "// ConfigPanel 缺失的翻译"
     },
     {
-      "line": 191,
-      "text": "// --- 一般タブのハンドラー ---"
+      "line": 105,
+      "text": "selectLLMModel: \"请选择LLM模型\","
     },
     {
-      "line": 221,
-      "text": "// --- ユーザータブのハンドラー ---"
+      "line": 106,
+      "text": "selectEmbeddingModel: \"请选择Embedding模型\","
     },
     {
-      "line": 263,
-      "text": "// ユーザーリストを再取得"
+      "line": 107,
+      "text": "defaultForUploads: \"用于新上传和查询\","
     },
     {
-      "line": 511,
-      "text": "// --- モデルタブのハンドラー ---"
+      "line": 108,
+      "text": "noRerankModel: \"无重排序模型\","
     },
     {
-      "line": 580,
-      "text": "// --- レンダリング関数 ---"
+      "line": 109,
+      "text": "vectorSimilarityThreshold: \"向量检索阈值\","
     },
     {
-      "line": 585,
-      "text": "{/* パスワード変更セクション */}"
+      "line": 110,
+      "text": "rerankSimilarityThreshold: \"重排序阈值\","
     },
     {
-      "line": 636,
-      "text": "{/* 语言设置セクション */}"
+      "line": 111,
+      "text": "filterLowResults: \"低于此值的结果将被过滤\","
     },
     {
-      "line": 653,
-      "text": "<option value=\"zh\">中文 (Chinese)</option>"
+      "line": 112,
+      "text": "noteCreatedSuccess: \"笔记创建成功\","
     },
     {
-      "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": 113,
+      "text": "noteCreatedFailed: \"笔记创建失败\","
     },
     {
-      "line": 23,
-      "text": "selectedGroups?: string[], // 追加: 選択されたグループ"
+      "line": 114,
+      "text": "fullTextSearch: \"全文检索\","
     },
     {
-      "line": 24,
-      "text": "selectedFiles?: string[], // 追加: 選択されたファイル"
+      "line": 115,
+      "text": "hybridVectorWeight: \"混合检索向量权重\","
     },
     {
-      "line": 25,
-      "text": "historyId?: string, // 追加: 会話履歴 ID"
+      "line": 116,
+      "text": "hybridVectorWeightDesc: \"向量平衡: 1.0 = 纯向量, 0.0 = 纯全文\","
     },
     {
-      "line": 26,
-      "text": "enableRerank?: boolean, // 追加: Rerank を有効にする"
+      "line": 117,
+      "text": "lblQueryExpansion: \"查询扩展 (Multi-Query)\","
     },
     {
-      "line": 27,
-      "text": "selectedRerankId?: string, // 追加: Rerank モデル ID"
+      "line": 118,
+      "text": "lblHyDE: \"HyDE (假设文档嵌入)\","
     },
     {
-      "line": 28,
-      "text": "temperature?: number, // 追加: temperature パラメータ"
+      "line": 119,
+      "text": "lblQueryExpansionDesc: \"生成多个查询变体以提高覆盖率\","
     },
     {
-      "line": 29,
-      "text": "maxTokens?: number, // 追加: maxTokens パラメータ"
+      "line": 120,
+      "text": "lblHyDEDesc: \"生成假设回答以改善语义搜索\","
     },
     {
-      "line": 30,
-      "text": "topK?: number, // 追加: topK パラメータ"
+      "line": 122,
+      "text": "apiKeyValidationFailed: \"API Key 验证失败\","
     },
     {
-      "line": 31,
-      "text": "similarityThreshold?: number, // 追加: similarityThreshold パラメータ"
+      "line": 123,
+      "text": "keepOriginalKey: \"留空保持原 API Key,输入新值则替换\","
     },
     {
-      "line": 32,
-      "text": "rerankSimilarityThreshold?: number, // 追加: rerankSimilarityThreshold パラメータ"
+      "line": 124,
+      "text": "leaveEmptyNoChange: \"留空不修改\","
     },
     {
-      "line": 33,
-      "text": "enableQueryExpansion?: boolean, // 追加"
+      "line": 126,
+      "text": "mmFormApiKeyPlaceholder: \"请输入 API Key\","
     },
     {
-      "line": 34,
-      "text": "enableHyDE?: boolean // 追加"
+      "line": 128,
+      "text": "// 更多组件缺失的翻译"
     },
     {
-      "line": 51,
-      "text": "selectedGroups, // グループフィルタパラメータを渡す"
+      "line": 129,
+      "text": "reconfigureFile: \"重新配置文件\","
     },
     {
-      "line": 52,
-      "text": "selectedFiles, // ファイルフィルタパラメータを渡す"
+      "line": 130,
+      "text": "modifySettings: \"修改文件的切片和向量化设置\","
     },
     {
-      "line": 53,
-      "text": "historyId, // 履歴 ID を渡す"
+      "line": 132,
+      "text": "allFilesIndexed: \"所有文件将使用下面的设置进行索引\","
     },
     {
-      "line": 56,
-      "text": "temperature, // temperature パラメータを渡す"
+      "line": 133,
+      "text": "noEmbeddingModels: \"未配置嵌入模型\","
     },
     {
-      "line": 57,
-      "text": "maxTokens, // maxTokens パラメータを渡す"
+      "line": 134,
+      "text": "reconfigure: \"重新配置\","
     },
     {
-      "line": 58,
-      "text": "topK, // topK パラメータを渡す"
+      "line": 135,
+      "text": "refresh: \"刷新\","
     },
     {
-      "line": 59,
-      "text": "similarityThreshold, // similarityThreshold パラメータを渡す"
+      "line": 136,
+      "text": "settings: \"设置\","
     },
     {
-      "line": 60,
-      "text": "rerankSimilarityThreshold, // rerankSimilarityThreshold パラメータを渡す"
+      "line": 137,
+      "text": "needLogin: \"需要登录才能使用聊天功能\","
     },
     {
-      "line": 61,
-      "text": "enableQueryExpansion, // enableQueryExpansion を渡す"
+      "line": 138,
+      "text": "citationSources: \"引用源\","
     },
     {
-      "line": 62,
-      "text": "enableHyDE // enableHyDE を渡す"
+      "line": 139,
+      "text": "chunkNumber: \"片段\","
     },
     {
-      "line": 67,
-      "text": "let errorMessage = 'リクエストに失敗しました';"
+      "line": 140,
+      "text": "getUserListFailed: \"获取用户列表失败\","
     },
     {
-      "line": 70,
-      "text": "errorMessage = error.error || error.message || 'リクエストに失敗しました';"
+      "line": 141,
+      "text": "usernamePasswordRequired: \"用户名和密码不能为空\","
     },
     {
-      "line": 72,
-      "text": "errorMessage = `サーバーエラー: ${response.status}`;"
+      "line": 142,
+      "text": "passwordMinLength: \"密码长度不能少于6位\","
     },
     {
-      "line": 80,
-      "text": "yield { type: 'error', data: 'レスポンスストリームを読み取れません' };"
+      "line": 143,
+      "text": "userCreatedSuccess: \"用户创建成功\","
     },
     {
-      "line": 112,
-      "text": "yield { type: 'error', data: error.message || 'ネットワークエラー' };"
+      "line": 144,
+      "text": "createUserFailed: \"创建用户失败\","
     },
     {
-      "line": 134,
-      "text": "yield { type: 'error', data: 'リクエストに失敗しました' };"
-    }
-  ],
-  "d:\\workspace\\AuraK\\web\\services\\chunkConfigService.ts": [
-    {
-      "line": 1,
-      "text": "// チャンク設定サービス - チャンク設定の制限の取得と検証に使用"
+      "line": 145,
+      "text": "userPromotedToAdmin: \"用户已提升为管理员\","
     },
     {
-      "line": 4,
-      "text": "maxChunkSize: number;        // 最大チャンクサイズ (tokens)"
+      "line": 146,
+      "text": "userDemotedFromAdmin: \"用户已降级为普通用户\","
     },
     {
-      "line": 5,
-      "text": "maxOverlapSize: number;      // 最大重複サイズ (tokens)"
+      "line": 147,
+      "text": "updateUserFailed: \"更新用户失败\","
     },
     {
-      "line": 6,
-      "text": "minOverlapSize: number;      // 最小重複サイズ (tokens)"
+      "line": 148,
+      "text": "confirmDeleteUser: \"Confirm要删除此用户吗?\","
     },
     {
-      "line": 7,
-      "text": "defaultChunkSize: number;    // デフォルトチャンクサイズ"
+      "line": 149,
+      "text": "deleteUser: \"删除用户\","
     },
     {
-      "line": 8,
-      "text": "defaultOverlapSize: number;  // デフォルト重複サイズ"
+      "line": 150,
+      "text": "deleteUserFailed: \"删除用户失败\","
     },
     {
-      "line": 9,
-      "text": "modelInfo: EmbeddingModelLimit; // モデル情報"
+      "line": 151,
+      "text": "userDeletedSuccessfully: \"用户删除成功\","
     },
     {
-      "line": 13,
-      "text": "name: string;              // モデル名"
+      "line": 152,
+      "text": "makeUserAdmin: \"设为管理员\","
     },
     {
-      "line": 14,
-      "text": "maxInputTokens: number;    // モデル入力制限"
+      "line": 153,
+      "text": "makeUserRegular: \"设为普通用户\","
     },
     {
-      "line": 15,
-      "text": "maxBatchSize: number;      // モデルバッチ制限"
+      "line": 154,
+      "text": "loading: \"加载中...\","
     },
     {
-      "line": 16,
-      "text": "expectedDimensions: number; // 期待されるベクトル次元数"
+      "line": 155,
+      "text": "noUsers: \"暂无用户\","
     },
     {
-      "line": 21,
-      "text": "* チャンク設定の制限を取得"
+      "line": 157,
+      "text": "// ChangePasswordModal 和 SearchResultsPanel 缺失的翻译"
     },
     {
-      "line": 22,
-      "text": "* @param embeddingModelId 埋め込みモデルID"
+      "line": 158,
+      "text": "fillAllFields: \"请填写所有字段\","
     },
     {
-      "line": 23,
-      "text": "* @param authToken 認証トークン"
+      "line": 159,
+      "text": "passwordMismatch: \"新密码和确认密码不匹配\","
     },
     {
-      "line": 24,
-      "text": "* @returns 設定制限情報"
+      "line": 160,
+      "text": "newPasswordMinLength: \"新密码长度不能少于6位\","
     },
     {
-      "line": 54,
-      "text": "* チャンク設定が有効かどうかを検証"
+      "line": 161,
+      "text": "changePasswordFailed: \"修改密码失败\","
     },
     {
-      "line": 55,
-      "text": "* @param chunkSize チャンクサイズ"
+      "line": 162,
+      "text": "changePasswordTitle: \"修改密码\","
     },
     {
-      "line": 56,
-      "text": "* @param chunkOverlap 重複サイズ"
+      "line": 163,
+      "text": "changing: \"修改中...\","
     },
     {
-      "line": 57,
-      "text": "* @param limits 設定制限"
+      "line": 164,
+      "text": "searchResults: \"搜索到的相关内容\","
     },
     {
-      "line": 58,
-      "text": "* @returns 検証結果とエラー情報"
+      "line": 166,
+      "text": "// VisionModelSelector 缺失的翻译"
     },
     {
-      "line": 74,
-      "text": "// チャンクサイズの検証"
+      "line": 167,
+      "text": "visionModelSettings: \"视觉模型设置\","
     },
     {
-      "line": 76,
-      "text": "errors.push(`チャンクサイズ ${chunkSize} が上限 ${limits.maxChunkSize} を超えています`);"
+      "line": 168,
+      "text": "defaultVisionModel: \"默认视觉模型\","
     },
     {
-      "line": 81,
-      "text": "errors.push(`チャンクサイズ ${chunkSize} が最小値 50 未満です`);"
+      "line": 169,
+      "text": "loadVisionModelFailed: \"加载视觉模型失败\","
     },
     {
-      "line": 85,
-      "text": "// 重複サイズの検証"
+      "line": 170,
+      "text": "loadFailed: \"加载失败,请检查网络连接\","
     },
     {
-      "line": 88,
-      "text": "errors.push(`重複サイズ ${chunkOverlap} が上限 ${limits.maxOverlapSize} を超えています`);"
+      "line": 171,
+      "text": "saveVisionModelFailed: \"保存视觉模型失败\","
     },
     {
-      "line": 93,
-      "text": "errors.push(`重複サイズ ${chunkOverlap} がチャンクサイズの50% (${maxOverlapByRatio}) を超えています`);"
+      "line": 172,
+      "text": "noVisionModels: \"没有可用的视觉模型\","
     },
     {
-      "line": 110,
-      "text": "* 表示用に制限情報をフォーマット"
+      "line": 173,
+      "text": "selectVisionModel: \"请选择视觉模型\","
     },
     {
-      "line": 114,
-      "text": "`モデル: ${limits.modelInfo.name}`,"
+      "line": 174,
+      "text": "visionModelHelp: \"用于处理图片文件的视觉模型。如果没有可用模型,请在模型管理中添加并勾选“支持视觉”选项。\","
     },
     {
-      "line": 115,
-      "text": "`チャンク上限: ${limits.maxChunkSize} tokens`,"
+      "line": 175,
+      "text": "mmErrorNameRequired: \"模型名称为必填项。\","
     },
     {
-      "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": 176,
+      "text": "mmErrorModelIdRequired: \"模型 ID 为必填项。\","
     },
     {
-      "line": 1745,
-      "text": "fixGrammar: \"文法修正\","
+      "line": 177,
+      "text": "mmErrorBaseUrlRequired: \"Base URL 为必填项。\","
     },
     {
-      "line": 1746,
-      "text": "aiCommandInstructPolish: \"このテキストをよりプロフェッショナルで自然な表現に推敲してください。\","
+      "line": 181,
+      "text": "typeLLM: \"对话推理 (LLM)\","
     },
     {
-      "line": 1747,
-      "text": "aiCommandInstructExpand: \"このテキストに詳細を追加して内容を充実させ、詳しく書き広げてください。\","
+      "line": 182,
+      "text": "typeEmbedding: \"向量化 (Embedding)\","
     },
     {
-      "line": 1748,
-      "text": "aiCommandInstructSummarize: \"このテキストの要点を抽出し、簡潔な要約を作成してください。\","
+      "line": 183,
+      "text": "typeRerank: \"重排序 (Rerank)\","
     },
     {
-      "line": 1749,
-      "text": "aiCommandInstructTranslateToEn: \"このテキストを英語に翻訳してください。\","
+      "line": 184,
+      "text": "typeVision: \"视觉识别 (Vision)\","
     },
     {
-      "line": 1750,
-      "text": "aiCommandInstructFixGrammar: \"このテキストの文法やスペルの誤りをチェックし、修正してください。\","
+      "line": 186,
+      "text": "welcome: \"你好!我是您的智能知识库助手。请在“系统设置”中选择模型,上传文档建立索引,然后即可开始提问。\","
     },
     {
-      "line": 1751,
-      "text": "aiCommandsPreset: \"よく使うコマンド\","
+      "line": 187,
+      "text": "placeholderWithFiles: \"基于知识库内容提问...\","
     },
     {
-      "line": 1752,
-      "text": "aiCommandsCustom: \"カスタムリクエスト\","
+      "line": 188,
+      "text": "placeholderEmpty: \"请先上传文件并完成索引...\","
     },
     {
-      "line": 1753,
-      "text": "aiCommandsCustomPlaceholder: \"例:この文章をより正式なものに書き直してください...\","
+      "line": 189,
+      "text": "analyzing: \"正在检索并生成答案...\","
     },
     {
-      "line": 1754,
-      "text": "aiCommandsReferenceContext: \"参照コンテキスト (最初の200文字):\","
+      "line": 190,
+      "text": "errorGeneric: \"处理您的请求时遇到错误。\","
     },
     {
-      "line": 1755,
-      "text": "aiCommandsStartGeneration: \"生成開始\","
+      "line": 191,
+      "text": "errorLabel: \"错误\","
     },
     {
-      "line": 1756,
-      "text": "aiCommandsResult: \"AIの提案\","
+      "line": 192,
+      "text": "errorNoModel: \"未选择推理模型或配置无效。\","
     },
     {
-      "line": 1757,
-      "text": "aiCommandsGenerating: \"生成中...\","
+      "line": 193,
+      "text": "aiDisclaimer: \"AI 可能会犯错。请核实源文件中的重要信息。\","
     },
     {
-      "line": 1758,
-      "text": "aiCommandsApplyResult: \"選択範囲を置換\","
+      "line": 194,
+      "text": "confirmClear: \"Confirm要清空所有文件及索引吗?\","
     },
     {
-      "line": 1759,
-      "text": "aiCommandsGoBack: \"戻る\","
+      "line": 195,
+      "text": "removeFile: \"移除文件\","
     },
     {
-      "line": 1760,
-      "text": "aiCommandsReset: \"リセット\","
+      "line": 196,
+      "text": "apiError: \"缺少配置或 API 密钥无效。\","
     },
     {
-      "line": 1761,
-      "text": "aiCommandsModalPreset: \"プリセットコマンドを選択\","
+      "line": 197,
+      "text": "geminiError: \"API 请求失败。\","
     },
     {
-      "line": 1762,
-      "text": "aiCommandsModalCustom: \"またはカスタムコマンドを入力\","
+      "line": 198,
+      "text": "processedButNoText: \"无法生成文本回复。\","
     },
     {
-      "line": 1763,
-      "text": "aiCommandsModalCustomPlaceholder: \"AIに何をしたいか伝えてください...\","
+      "line": 199,
+      "text": "unitByte: \"字节\","
     },
     {
-      "line": 1764,
-      "text": "aiCommandsModalBasedOnSelection: \"選択したテキストに基づいて:\","
+      "line": 200,
+      "text": "readingFailed: \"读取文件失败\","
     },
     {
-      "line": 1765,
-      "text": "aiCommandsModalResult: \"生成結果\","
+      "line": 203,
+      "text": "copy: \"复制内容\","
     },
     {
-      "line": 1766,
-      "text": "aiCommandsModalApply: \"結果を適用\","
+      "line": 204,
+      "text": "copied: \"已复制\","
     },
     {
-      "line": 1768,
-      "text": "// ChangePasswordModal と SearchResultsPanel の缺失翻訳"
+      "line": 207,
+      "text": "logout: \"退出登录\","
     },
     {
-      "line": 1769,
-      "text": "fillAllFields: \"すべてのフィールドを入力してください\","
+      "line": 208,
+      "text": "changePassword: \"修改密码\","
     },
     {
-      "line": 1770,
-      "text": "passwordMismatch: \"新しいパスワードと確認パスワードが一致しません\","
+      "line": 209,
+      "text": "userManagement: \"用户管理\","
     },
     {
-      "line": 1771,
-      "text": "newPasswordMinLength: \"新しいパスワードは6文字以上で入力してください\","
+      "line": 210,
+      "text": "userList: \"用户列表\","
     },
     {
-      "line": 1772,
-      "text": "changePasswordFailed: \"パスワードの変更に失敗しました\","
+      "line": 211,
+      "text": "addUser: \"新增用户\","
     },
     {
-      "line": 1773,
-      "text": "changePasswordTitle: \"パスワード変更\","
+      "line": 212,
+      "text": "username: \"用户名\","
     },
     {
-      "line": 1774,
-      "text": "changing: \"変更中...\","
+      "line": 213,
+      "text": "password: \"密码\","
     },
     {
-      "line": 1775,
-      "text": "searchResults: \"関連コンテンツが見つかりました\","
+      "line": 214,
+      "text": "confirmPassword: \"确认密码\","
     },
     {
-      "line": 1777,
-      "text": "// VisionModelSelector の缺失翻訳"
+      "line": 215,
+      "text": "currentPassword: \"当前密码\","
     },
     {
-      "line": 1778,
-      "text": "visionModelSettings: \"ビジョンモデル設定\","
+      "line": 216,
+      "text": "newPassword: \"新密码\","
     },
     {
-      "line": 1779,
-      "text": "defaultVisionModel: \"デフォルトビジョンモデル\","
+      "line": 217,
+      "text": "createUser: \"创建用户\","
     },
     {
-      "line": 1780,
-      "text": "loadVisionModelFailed: \"ビジョンモデルの読み込みに失敗しました\","
+      "line": 218,
+      "text": "admin: \"管理员\","
     },
     {
-      "line": 1781,
-      "text": "loadFailed: \"読み込みに失敗しました、ネットワーク接続を確認してください\","
+      "line": 219,
+      "text": "user: \"普通用户\","
     },
     {
-      "line": 1782,
-      "text": "saveVisionModelFailed: \"ビジョンモデルの保存に失敗しました\","
+      "line": 220,
+      "text": "adminUser: \"设为管理员\",  // 新增,"
     },
     {
-      "line": 1783,
-      "text": "noVisionModels: \"利用可能なビジョンモデルがありません\","
+      "line": 221,
+      "text": "confirmChange: \"确认修改\","
     },
     {
-      "line": 1784,
-      "text": "selectVisionModel: \"ビジョンモデルを選択してください\","
+      "line": 222,
+      "text": "changeUserPassword: \"修改用户密码\","
     },
     {
-      "line": 1785,
-      "text": "visionModelHelp: \"画像ファイルを処理するためのビジョンモデル。利用可能なモデルがない場合は、モデル管理で追加し、「ビジョン対応」オプションをチェックしてください。\","
+      "line": 223,
+      "text": "enterNewPassword: \"请输入新密码\","
     },
     {
-      "line": 1786,
-      "text": "mmErrorNameRequired: \"モデル名は必須要素です\","
+      "line": 224,
+      "text": "createdAt: \"创建时间\","
     },
     {
-      "line": 1787,
-      "text": "mmErrorModelIdRequired: \"モデルIDは必須です。\","
+      "line": 225,
+      "text": "newChat: \"新建对话\","
     },
     {
-      "line": 1788,
-      "text": "mmErrorBaseUrlRequired: \"選択されたプロバイダーにはBase URLが必要です。\","
+      "line": 228,
+      "text": "kbManagement: \"知识库管理\","
     },
     {
-      "line": 1791,
-      "text": "typeLLM: \"推論 (LLM)\","
+      "line": 229,
+      "text": "kbManagementDesc: \"管理您的文档和知识分组\","
     },
     {
-      "line": 1792,
-      "text": "typeEmbedding: \"ベクトル化 (Embedding)\","
+      "line": 230,
+      "text": "searchPlaceholder: \"搜索文件名...\","
     },
     {
-      "line": 1793,
-      "text": "typeRerank: \"リランク (Rerank)\","
+      "line": 231,
+      "text": "allGroups: \"所有分组\","
     },
     {
-      "line": 1794,
-      "text": "typeVision: \"画像認識 (Vision)\","
+      "line": 232,
+      "text": "allStatus: \"所有状态\","
     },
     {
-      "line": 1796,
-      "text": "welcome: \"こんにちは!設定でモデルを選択し、ドキュメントをアップロードして質問を開始してください。\","
+      "line": 236,
+      "text": "uploadFile: \"上传文件\","
     },
     {
-      "line": 1797,
-      "text": "placeholderWithFiles: \"ナレッジベースについて質問...\","
+      "line": 237,
+      "text": "fileName: \"文件名\","
     },
     {
-      "line": 1798,
-      "text": "placeholderEmpty: \"開始するにはファイルをアップロード...\","
+      "line": 238,
+      "text": "size: \"大小\","
     },
     {
-      "line": 1799,
-      "text": "analyzing: \"検索して生成中...\","
+      "line": 239,
+      "text": "status: \"状态\","
     },
     {
-      "line": 1800,
-      "text": "errorGeneric: \"エラーが発生しました。\","
+      "line": 240,
+      "text": "groups: \"分组\","
     },
     {
-      "line": 1801,
-      "text": "errorLabel: \"エラー\","
+      "line": 241,
+      "text": "actions: \"操作\","
     },
     {
-      "line": 1802,
-      "text": "errorNoModel: \"モデルが選択されていないか、設定が無効です。\","
+      "line": 242,
+      "text": "groupsActions: \"分组 / 操作\","
     },
     {
-      "line": 1803,
-      "text": "aiDisclaimer: \"AIは間違いを犯す可能性があります。\","
+      "line": 243,
+      "text": "noFilesFound: \"未找到匹配的文件\","
     },
     {
-      "line": 1804,
-      "text": "confirmClear: \"すべてのファイルを削除しますか?\","
+      "line": 244,
+      "text": "showingRange: \"显示 $1 到 $2 条,共 $3 条\","
     },
     {
-      "line": 1805,
-      "text": "removeFile: \"ファイルを削除\","
+      "line": 245,
+      "text": "confirmDeleteFile: \"Confirm要删除此文件吗?\","
     },
     {
-      "line": 1806,
-      "text": "apiError: \"設定が不足しているか、APIキーが有効ではありません。\","
+      "line": 246,
+      "text": "fileDeleted: \"文件已删除\","
     },
     {
-      "line": 1807,
-      "text": "geminiError: \"APIリクエストに失敗しました。\","
+      "line": 247,
+      "text": "deleteFailed: \"删除失败\","
     },
     {
-      "line": 1808,
-      "text": "processedButNoText: \"応答を生成できませんでした。\","
+      "line": 248,
+      "text": "fileAddedToGroup: \"文件已添加到分组\","
     },
     {
-      "line": 1809,
-      "text": "unitByte: \"バイト\","
+      "line": 249,
+      "text": "failedToAddToGroup: \"添加到分组失败\","
     },
     {
-      "line": 1810,
-      "text": "readingFailed: \"読み込み失敗\","
+      "line": 250,
+      "text": "fileRemovedFromGroup: \"文件已从分组移除\","
     },
     {
-      "line": 1812,
-      "text": "copy: \"コピー\","
+      "line": 251,
+      "text": "failedToRemoveFromGroup: \"从分组移除失败\","
     },
     {
-      "line": 1813,
-      "text": "copied: \"コピーしました\","
+      "line": 252,
+      "text": "confirmClearKB: \"警告:此操作将永久删除所有文件及其索引数据。\\n\\nConfirm要清空知识库吗?\","
     },
     {
-      "line": 1816,
-      "text": "logout: \"ログアウト\","
+      "line": 253,
+      "text": "kbCleared: \"知识库已清空\","
     },
     {
-      "line": 1817,
-      "text": "changePassword: \"パスワード変更\","
+      "line": 254,
+      "text": "clearFailed: \"清空失败\","
     },
     {
-      "line": 1818,
-      "text": "userManagement: \"ユーザー管理\","
+      "line": 255,
+      "text": "loginRequired: \"请先登录\","
     },
     {
-      "line": 1819,
-      "text": "userList: \"ユーザー一覧\","
+      "line": 256,
+      "text": "uploadErrors: \"以下文件无法上传\","
     },
     {
-      "line": 1820,
-      "text": "addUser: \"ユーザー追加\","
+      "line": 257,
+      "text": "uploadWarning: \"$1  files已准备上传,$2  files被过滤\","
     },
     {
-      "line": 1821,
-      "text": "username: \"ユーザー名\","
+      "line": 258,
+      "text": "uploadFailed: \"上传失败\","
     },
     {
-      "line": 1822,
-      "text": "password: \"パスワード\","
+      "line": 259,
+      "text": "preview: \"预览\","
     },
     {
-      "line": 1823,
-      "text": "confirmPassword: \"パスワード確認\","
+      "line": 260,
+      "text": "addGroup: \"添加分组\","
     },
     {
-      "line": 1824,
-      "text": "currentPassword: \"現在のパスワード\","
+      "line": 261,
+      "text": "delete: \"删除\","
     },
     {
-      "line": 1825,
-      "text": "newPassword: \"新しいパスワード\","
+      "line": 262,
+      "text": "retry: \"重试\","
     },
     {
-      "line": 1826,
-      "text": "createUser: \"ユーザー作成\","
+      "line": 263,
+      "text": "retrying: \"重试中...\","
     },
     {
-      "line": 1827,
-      "text": "admin: \"管理者\","
+      "line": 264,
+      "text": "retrySuccess: \"重试成功\","
     },
     {
-      "line": 1828,
-      "text": "user: \"ユーザー\","
+      "line": 265,
+      "text": "retryFailed: \"重试失败\","
     },
     {
-      "line": 1829,
-      "text": "adminUser: \"管理者として設定\","
+      "line": 266,
+      "text": "chunkInfo: \"分片信息\","
     },
     {
-      "line": 1830,
-      "text": "confirmChange: \"変更を確定\","
+      "line": 267,
+      "text": "totalChunks: \"总分片数\","
     },
     {
-      "line": 1831,
-      "text": "changeUserPassword: \"ユーザーのパスワードを変更\","
+      "line": 268,
+      "text": "chunkIndex: \"分片\","
     },
     {
-      "line": 1832,
-      "text": "enterNewPassword: \"新しいパスワードを入力してください\","
+      "line": 269,
+      "text": "contentLength: \"字符\","
     },
     {
-      "line": 1833,
-      "text": "createdAt: \"作成日時\","
+      "line": 270,
+      "text": "position: \"位置\","
     },
     {
-      "line": 1834,
-      "text": "newChat: \"新しい会話\","
+      "line": 273,
+      "text": "reconfigureTitle: \"重新配置文件\","
     },
     {
-      "line": 1837,
-      "text": "kbManagement: \"ナレッジベース管理\","
+      "line": 274,
+      "text": "reconfigureDesc: \"修改文件处理设置\","
     },
     {
-      "line": 1838,
-      "text": "kbManagementDesc: \"ドキュメントとナレッジグループの管理\","
+      "line": 275,
+      "text": "indexingConfigTitle: \"文档索引配置\","
     },
     {
-      "line": 1839,
-      "text": "searchPlaceholder: \"ファイル名を検索...\","
+      "line": 276,
+      "text": "indexingConfigDesc: \"配置文档处理参数,选择处理模式\","
     },
     {
-      "line": 1840,
-      "text": "allGroups: \"すべてのグループ\","
+      "line": 277,
+      "text": "pendingFiles: \"待处理文件\","
     },
     {
-      "line": 1841,
-      "text": "allStatus: \"すべてのステータス\","
+      "line": 278,
+      "text": "processingMode: \"处理模式\","
     },
     {
-      "line": 1842,
-      "text": "statusReadyFragment: \"完了\","
+      "line": 280,
+      "text": "recommendationReason: \"推荐理由\","
     },
     {
-      "line": 1843,
-      "text": "statusFailedFragment: \"失敗\","
+      "line": 281,
+      "text": "fastMode: \"快速模式\","
     },
     {
-      "line": 1844,
-      "text": "statusIndexingFragment: \"インデックス中\","
+      "line": 282,
+      "text": "fastModeDesc: \"简单提取文本,速度快,无额外成本,适合纯文本文档\","
     },
     {
-      "line": 1845,
-      "text": "uploadFile: \"ファイルをアップロード\","
+      "line": 283,
+      "text": "preciseMode: \"精准模式\","
     },
     {
-      "line": 1846,
-      "text": "fileName: \"ファイル名\","
+      "line": 284,
+      "text": "preciseModeDesc: \"精准识别内容,保留图文混合信息,需要 API 费用\","
     },
     {
-      "line": 1847,
-      "text": "size: \"サイズ\","
+      "line": 285,
+      "text": "fastModeFeatures: \"快速模式特点:\","
     },
     {
-      "line": 1848,
-      "text": "status: \"ステータス\","
+      "line": 286,
+      "text": "fastFeature1: \"简单提取文本内容\","
     },
     {
-      "line": 1849,
-      "text": "groups: \"グループ\","
+      "line": 287,
+      "text": "fastFeature2: \"处理速度快,适合批量处理\","
     },
     {
-      "line": 1850,
-      "text": "actions: \"アクション\","
+      "line": 288,
+      "text": "fastFeature3: \"无额外成本\","
     },
     {
-      "line": 1851,
-      "text": "groupsActions: \"グループ / アクション\","
+      "line": 289,
+      "text": "fastFeature4: \"仅处理文字信息\","
     },
     {
-      "line": 1852,
-      "text": "noFilesFound: \"ファイルが見つかりません\","
+      "line": 290,
+      "text": "fastFeature5: \"适合纯文本文档\","
     },
     {
-      "line": 1853,
-      "text": "showingRange: \"$3 件中 $1 - $2 を表示\","
+      "line": 291,
+      "text": "preciseModeFeatures: \"精准模式特点:\","
     },
     {
-      "line": 1854,
-      "text": "confirmDeleteFile: \"このファイルを削除してもよろしいですか?\","
+      "line": 292,
+      "text": "preciseFeature1: \"精准识别内容结构\","
     },
     {
-      "line": 1855,
-      "text": "fileDeleted: \"ファイルを削除しました\","
+      "line": 293,
+      "text": "preciseFeature2: \"识别图片/图表/表格\","
     },
     {
-      "line": 1856,
-      "text": "deleteFailed: \"削除に失敗しました\","
+      "line": 294,
+      "text": "preciseFeature3: \"保留图文混合内容\","
     },
     {
-      "line": 1857,
-      "text": "fileAddedToGroup: \"ファイルがグループに追加されました\","
+      "line": 295,
+      "text": "preciseFeature4: \"保留页面布局信息\","
     },
     {
-      "line": 1858,
-      "text": "failedToAddToGroup: \"グループへの追加に失敗しました\","
+      "line": 296,
+      "text": "preciseFeature5: \"需要 API 费用\","
     },
     {
-      "line": 1859,
-      "text": "fileRemovedFromGroup: \"ファイルがグループから削除されました\","
+      "line": 297,
+      "text": "preciseFeature6: \"处理时间较长\","
     },
     {
-      "line": 1860,
-      "text": "failedToRemoveFromGroup: \"グループからの削除に失敗しました\","
+      "line": 298,
+      "text": "embeddingModel: \"嵌入模型\","
     },
     {
-      "line": 1861,
-      "text": "confirmClearKB: \"警告:これによりすべてのファイルとインデックスが完全に削除されます。\\n\\n本当にナレッジベースをクリアしますか?\","
+      "line": 299,
+      "text": "pleaseSelect: \"请选择...\","
     },
     {
-      "line": 1862,
-      "text": "kbCleared: \"ナレッジベースをクリアしました\","
+      "line": 300,
+      "text": "pleaseSelectKnowledgeGroupFirst: \"请先选择知识组再保存\","
     },
     {
-      "line": 1863,
-      "text": "clearFailed: \"クリアに失敗しました\","
+      "line": 301,
+      "text": "selectUnassignGroupWarning: \"如果您想Cancel分配知识组,请确认此操作\","
     },
     {
-      "line": 1864,
-      "text": "loginRequired: \"先にログインしてください\","
+      "line": 302,
+      "text": "chunkConfig: \"切片配置\","
     },
     {
-      "line": 1865,
-      "text": "uploadErrors: \"以下のファイルはアップロードできませんでした\","
+      "line": 303,
+      "text": "chunkSize: \"切片大小 (Tokens)\","
     },
     {
-      "line": 1866,
-      "text": "uploadWarning: \"$1 つのファイルがアップロード準備完了、$2 つがフィルタリングされました\","
+      "line": 304,
+      "text": "min: \"最小\","
     },
     {
-      "line": 1867,
-      "text": "uploadFailed: \"アップロードに失敗しました\","
+      "line": 305,
+      "text": "max: \"上限\","
     },
     {
-      "line": 1868,
-      "text": "preview: \"プレビュー\","
+      "line": 306,
+      "text": "chunkOverlap: \"重叠大小 (Tokens)\","
     },
     {
-      "line": 1869,
-      "text": "addGroup: \"グループ追加\","
+      "line": 307,
+      "text": "modelLimitsInfo: \"模型限制信息\","
     },
     {
-      "line": 1870,
-      "text": "delete: \"削除\","
+      "line": 308,
+      "text": "model: \"模型\","
     },
     {
-      "line": 1871,
-      "text": "retry: \"再試行\","
+      "line": 309,
+      "text": "maxChunkSize: \"切片上限\","
     },
     {
-      "line": 1872,
-      "text": "retrying: \"再試行中...\","
+      "line": 310,
+      "text": "maxOverlapSize: \"重叠上限\","
     },
     {
-      "line": 1873,
-      "text": "retrySuccess: \"再試行成功\","
+      "line": 311,
+      "text": "maxBatchSize: \"批量限制\","
     },
     {
-      "line": 1874,
-      "text": "retryFailed: \"再試行失敗\","
+      "line": 312,
+      "text": "envLimitWeaker: \"环境变量限制更严格\","
     },
     {
-      "line": 1875,
-      "text": "chunkInfo: \"チャンク情報\","
+      "line": 313,
+      "text": "optimizationTips: \"优化建议\","
     },
     {
-      "line": 1876,
-      "text": "totalChunks: \"総チャンク数\","
+      "line": 314,
+      "text": "tipChunkTooLarge: \"切片较大,可能影响检索精度\","
     },
     {
-      "line": 1877,
-      "text": "chunkIndex: \"チャンク\","
+      "line": 315,
+      "text": "tipOverlapSmall: \"建议重叠至少 $1 tokens\","
     },
     {
-      "line": 1878,
-      "text": "contentLength: \"文字\","
+      "line": 316,
+      "text": "tipMaxValues: \"使用最大值,处理速度可能较慢\","
     },
-    {
-      "line": 1879,
-      "text": "position: \"位置\","
+    {
+      "line": 317,
+      "text": "tipPreciseCost: \"精准模式会产生 API 费用,请确认预算\","
     },
     {
-      "line": 1882,
-      "text": "reconfigureTitle: \"ファイルの再設定\","
+      "line": 318,
+      "text": "selectEmbeddingFirst: \"请先选择嵌入模型\","
     },
     {
-      "line": 1883,
-      "text": "reconfigureDesc: \"ファイル処理設定を変更\","
+      "line": 319,
+      "text": "confirmPreciseCost: \"精准模式会产生 API 费用,是否继续?\","
     },
     {
-      "line": 1884,
-      "text": "indexingConfigTitle: \"ドキュメントインデックス設定\","
+      "line": 320,
+      "text": "startProcessing: \"开始处理\","
     },
     {
-      "line": 1885,
-      "text": "indexingConfigDesc: \"ドキュメント処理オプションとモードを設定\","
+      "line": 323,
+      "text": "notebooks: \"知识组\","
     },
     {
-      "line": 1886,
-      "text": "pendingFiles: \"待機中のファイル\","
+      "line": 324,
+      "text": "notebooksDesc: \"管理您的文档和知识分组\","
     },
     {
-      "line": 1887,
-      "text": "processingMode: \"処理モード\","
+      "line": 325,
+      "text": "createNotebook: \"新建知识组\","
     },
     {
-      "line": 1888,
-      "text": "analyzingFile: \"分析中...\","
+      "line": 326,
+      "text": "chatWithNotebook: \"基于此知识组对话\","
     },
     {
-      "line": 1889,
-      "text": "recommendationReason: \"理由\","
+      "line": 327,
+      "text": "editNotebook: \"编辑知识组\","
     },
     {
-      "line": 1890,
-      "text": "fastMode: \"高速モード\","
+      "line": 328,
+      "text": "deleteNotebook: \"删除知识组 (包含文件)\","
     },
     {
-      "line": 1891,
-      "text": "fastModeDesc: \"単純なテキスト抽出、高速、追加コストなし、純粋なテキストに適しています\","
+      "line": 329,
+      "text": "noDescription: \"无描述\","
     },
     {
-      "line": 1892,
-      "text": "preciseMode: \"精密モード\","
+      "line": 330,
+      "text": "noNotebooks: \"暂无知识组,点击右上角创建\","
     },
     {
-      "line": 1893,
-      "text": "preciseModeDesc: \"精密なレイアウト分析、表/画像を保持、APIコストがかかります\","
+      "line": 331,
+      "text": "createFailed: \"创建失败\","
     },
     {
-      "line": 1894,
-      "text": "fastModeFeatures: \"高速モードの特徴:\","
+      "line": 332,
+      "text": "confirmDeleteNotebook: \"Confirm要删除知识组 \\\"$1\\\" 吗?\\n\\n注意:这将同时永久删除该知识组下的所有文件及其索引数据!\","
     },
     {
-      "line": 1895,
-      "text": "fastFeature1: \"単純なテキスト抽出\","
+      "line": 336,
+      "text": "personalNotebookDesc: \"记录您的个人笔记与灵感\","
     },
     {
-      "line": 1896,
-      "text": "fastFeature2: \"高速な処理速度\","
+      "line": 337,
+      "text": "noNotes: \"暂无个人笔记\","
     },
     {
-      "line": 1897,
-      "text": "fastFeature3: \"追加コストなし\","
+      "line": 338,
+      "text": "createNote: \"新建笔记\","
     },
     {
-      "line": 1898,
-      "text": "fastFeature4: \"テキストのみ処理\","
+      "line": 341,
+      "text": "createNotebookTitle: \"新建知识组\","
     },
     {
-      "line": 1899,
-      "text": "fastFeature5: \"プレーンテキストに適しています\","
+      "line": 342,
+      "text": "editNotebookTitle: \"编辑知识组\","
     },
     {
-      "line": 1900,
-      "text": "preciseModeFeatures: \"精密モードの特徴:\","
+      "line": 343,
+      "text": "createFailedRetry: \"创建失败,请重试\","
     },
     {
-      "line": 1901,
-      "text": "preciseFeature1: \"精密な構造認識\","
+      "line": 344,
+      "text": "updateFailedRetry: \"更新失败,请重试\","
     },
     {
-      "line": 1902,
-      "text": "preciseFeature2: \"画像/表/チャートを認識\","
+      "line": 345,
+      "text": "name: \"名称\","
     },
     {
-      "line": 1903,
-      "text": "preciseFeature3: \"混合コンテンツを保持\","
+      "line": 346,
+      "text": "nameHelp: \"一个清晰的名称能帮你快速找到它。\","
     },
     {
-      "line": 1904,
-      "text": "preciseFeature4: \"レイアウト情報を保持\","
+      "line": 347,
+      "text": "namePlaceholder: \"例如:量子物理研究...\","
     },
     {
-      "line": 1905,
-      "text": "preciseFeature5: \"APIコストが必要\","
+      "line": 348,
+      "text": "shortDescription: \"简短描述\","
     },
     {
-      "line": 1906,
-      "text": "preciseFeature6: \"処理時間が長くなります\","
+      "line": 349,
+      "text": "descPlaceholder: \"一句话描述这个知识组的用途\","
     },
     {
-      "line": 1907,
-      "text": "embeddingModel: \"埋め込みモデル\","
+      "line": 350,
+      "text": "creating: \"正在创建...\","
     },
     {
-      "line": 1908,
-      "text": "pleaseSelect: \"選択してください...\","
+      "line": 351,
+      "text": "createNow: \"立即创建\","
     },
     {
-      "line": 1909,
-      "text": "pleaseSelectKnowledgeGroupFirst: \"保存する前に知識グループを選択してください\","
+      "line": 352,
+      "text": "saving: \"正在保存...\","
     },
     {
-      "line": 1910,
-      "text": "selectUnassignGroupWarning: \"ナレッジグループの割り当てを解除する場合は、この操作を確認してください\","
+      "line": 353,
+      "text": "save: \"保存\","
     },
     {
-      "line": 1911,
-      "text": "chunkConfig: \"チャンク設定\","
+      "line": 356,
+      "text": "chatTitle: \"知识库问答\","
     },
     {
-      "line": 1912,
-      "text": "chunkSize: \"チャンクサイズ (トークン)\","
+      "line": 357,
+      "text": "chatDesc: \"与您的知识库进行智能对话\","
     },
     {
-      "line": 1913,
-      "text": "min: \"最小\","
+      "line": 358,
+      "text": "viewHistory: \"查看对话历史\","
     },
     {
-      "line": 1914,
-      "text": "max: \"最大\","
+      "line": 359,
+      "text": "saveSettingsFailed: \"保存设置失败\","
     },
     {
-      "line": 1915,
-      "text": "chunkOverlap: \"オーバーラップ (トークン)\","
+      "line": 360,
+      "text": "loginToUpload: \"请先登录再进行上传\","
     },
     {
-      "line": 1916,
-      "text": "modelLimitsInfo: \"モデル制限情報\","
+      "line": 361,
+      "text": "fileSizeLimitExceeded: \"$1 ($2 - 超过 $3MB 限制)\","
     },
     {
-      "line": 1917,
-      "text": "model: \"モデル\","
+      "line": 362,
+      "text": "unsupportedFileType: \"$1 - 不支持的文件类型 ($2)\","
     },
     {
-      "line": 1918,
-      "text": "maxChunkSize: \"最大チャンク\","
+      "line": 363,
+      "text": "readFailed: \"$1 - 读取失败\","
     },
     {
-      "line": 1919,
-      "text": "maxOverlapSize: \"最大オーバーラップ\","
+      "line": 364,
+      "text": "loadHistoryFailed: \"加载对话历史失败\","
     },
     {
-      "line": 1920,
-      "text": "maxBatchSize: \"最大バッチ\","
+      "line": 365,
+      "text": "loadingUserData: \"正在加载用户数据...\","
     },
     {
-      "line": 1921,
-      "text": "envLimitWeaker: \"環境制限の方が厳しいです\","
+      "line": 366,
+      "text": "errorMessage: \"错误: $1\","
     },
     {
-      "line": 1922,
-      "text": "optimizationTips: \"最適化のヒント\","
+      "line": 367,
+      "text": "welcomeMessage: \"你好!我是您的智能知识库助手。请选择知识库然后进行提问。\","
     },
     {
-      "line": 1923,
-      "text": "tipChunkTooLarge: \"チャンクサイズが大きいと検索精度に影響する可能性があります\","
+      "line": 368,
+      "text": "selectKnowledgeGroup: \"选择知识库分组\","
     },
     {
-      "line": 1924,
-      "text": "tipOverlapSmall: \"オーバーラップは少なくとも $1 トークンを推奨します\","
+      "line": 369,
+      "text": "allKnowledgeGroups: \"全部知识库\","
     },
     {
-      "line": 1925,
-      "text": "tipMaxValues: \"最大値を使用すると処理が遅くなる可能性があります\","
+      "line": 370,
+      "text": "unknownGroup: \"未知分组\","
     },
     {
-      "line": 1926,
-      "text": "tipPreciseCost: \"精密モードはAPIコストが発生します。予算を確認してください\","
+      "line": 374,
+      "text": "generalSettings: \"一般配置\","
     },
     {
-      "line": 1927,
-      "text": "selectEmbeddingFirst: \"先に埋め込みモデルを選択してください\","
+      "line": 375,
+      "text": "modelManagement: \"模型管理\","
     },
     {
-      "line": 1928,
-      "text": "confirmPreciseCost: \"精密モードはAPIコストが発生します。続けますか?\","
+      "line": 376,
+      "text": "languageSettings: \"语言设置\","
     },
     {
-      "line": 1929,
-      "text": "startProcessing: \"処理開始\","
+      "line": 377,
+      "text": "passwordChangeSuccess: \"密码修改成功\","
     },
     {
-      "line": 1932,
-      "text": "notebooks: \"ナレッジグループ\","
+      "line": 378,
+      "text": "passwordChangeFailed: \"密码修改失败\","
     },
     {
-      "line": 1933,
-      "text": "notebooksDesc: \"研究プロジェクトやナレッジコレクションを管理\","
+      "line": 379,
+      "text": "create: \"创建\","
     },
     {
-      "line": 1934,
-      "text": "createNotebook: \"新しいナレッジグループ\","
+      "line": 383,
+      "text": "navChat: \"对话\","
     },
     {
-      "line": 1935,
-      "text": "chatWithNotebook: \"このグループとチャット\","
+      "line": 384,
+      "text": "navCoach: \"教练\","
     },
     {
-      "line": 1936,
-      "text": "editNotebook: \"グループを編集\","
+      "line": 385,
+      "text": "navKnowledge: \"知识库\","
     },
     {
-      "line": 1937,
-      "text": "deleteNotebook: \"グループを削除 (ファイルを含む)\","
+      "line": 386,
+      "text": "navKnowledgeGroups: \"知识组\","
     },
     {
-      "line": 1938,
-      "text": "noDescription: \"説明なし\","
+      "line": 387,
+      "text": "navNotebook: \"笔记本\","
     },
     {
-      "line": 1939,
-      "text": "hasIntro: \"紹介あり\","
+      "line": 388,
+      "text": "navAgent: \"智能体\","
     },
     {
-      "line": 1940,
-      "text": "noIntro: \"紹介なし\","
+      "line": 389,
+      "text": "navPlugin: \"插件\","
     },
     {
-      "line": 1941,
-      "text": "noNotebooks: \"ナレッジグループはまだありません。右上の作成ボタンをクリックしてください\","
+      "line": 390,
+      "text": "notebookDesc: \"记录您的个人想法和研究笔记。\","
     },
     {
-      "line": 1942,
-      "text": "createFailed: \"作成に失敗しました\","
+      "line": 391,
+      "text": "newNote: \"新建笔记\","
     },
     {
-      "line": 1943,
-      "text": "confirmDeleteNotebook: \"知識グループ \\\"$1\\\" を削除してもよろしいですか?\\n\\n注意:これにより、この知識グループ内のすべてのファイルとそのインデックスデータも完全に削除されます!\","
+      "line": 392,
+      "text": "editNote: \"编辑笔记\","
     },
     {
-      "line": 1946,
-      "text": "errorFileTooLarge: \"ファイルサイズが大きすぎます (20MB以下)\","
+      "line": 393,
+      "text": "noNotesFound: \"未找到笔记\","
     },
     {
-      "line": 1947,
-      "text": "noFilesYet: \"ファイルがありません\","
+      "line": 394,
+      "text": "startByCreatingNote: \"开始创建您的第一条个人笔记。\","
     },
     {
-      "line": 1950,
-      "text": "createNotebookTitle: \"新しいナレッジグループ\","
+      "line": 395,
+      "text": "navCrawler: \"资源获取\","
     },
     {
-      "line": 1951,
-      "text": "editNotebookTitle: \"ナレッジグループを編集\","
+      "line": 396,
+      "text": "expandMenu: \"展开菜单\","
     },
     {
-      "line": 1952,
-      "text": "createFailedRetry: \"作成に失敗しました。再試行してください\","
+      "line": 397,
+      "text": "switchLanguage: \"切换语言\","
     },
     {
-      "line": 1953,
-      "text": "updateFailedRetry: \"更新に失敗しました。再試行してください\","
+      "line": 398,
+      "text": "navGlobal: \"全局\","
     },
     {
-      "line": 1954,
-      "text": "name: \"名前\","
+      "line": 399,
+      "text": "navTenants: \"租户管理\","
     },
     {
-      "line": 1955,
-      "text": "nameHelp: \"明確な名前を付けると見つけやすくなります。\","
+      "line": 400,
+      "text": "navSystemModels: \"系统模型\","
     },
     {
-      "line": 1956,
-      "text": "namePlaceholder: \"例: 量子物理学研究...\","
+      "line": 401,
+      "text": "navTenantManagement: \"租户管理\","
     },
     {
-      "line": 1957,
-      "text": "shortDescription: \"短い説明\","
+      "line": 402,
+      "text": "navUsersTeam: \"用户与团队\","
     },
     {
-      "line": 1958,
-      "text": "descPlaceholder: \"このグループの目的を一文で説明\","
+      "line": 403,
+      "text": "navTenantSettings: \"租户设置\","
     },
     {
-      "line": 1959,
-      "text": "detailedIntro: \"詳細な紹介\","
+      "line": 404,
+      "text": "adminConsole: \"管理控制台\","
     },
     {
-      "line": 1960,
-      "text": "introPlaceholder: \"ここの段落は、Q&Aのコンテキストに含まれる可能性があります。このグループの主要なトピック、背景知識、または目標をできるだけ詳しく説明してください。\","
+      "line": 405,
+      "text": "globalDashboard: \"全局仪表盘\","
     },
     {
-      "line": 1961,
-      "text": "introHelp: \"この紹介は、会話の追加コンテキストとして使用されます。\","
+      "line": 408,
+      "text": "selectKnowledgeGroups: \"选择知识库分组\","
     },
     {
-      "line": 1962,
-      "text": "creating: \"作成中...\","
+      "line": 410,
+      "text": "done: \"完成\","
     },
     {
-      "line": 1963,
-      "text": "createNow: \"今すぐ作成\","
+      "line": 411,
+      "text": "all: \"全部\","
     },
     {
-      "line": 1964,
-      "text": "saving: \"保存中...\","
+      "line": 416,
+      "text": "autoRefresh: \"自动刷新\","
     },
     {
-      "line": 1965,
-      "text": "save: \"保存\","
+      "line": 417,
+      "text": "refreshInterval: \"刷新间隔\","
     },
     {
-      "line": 1968,
-      "text": "chatTitle: \"ナレッジベースチャット\","
+      "line": 420,
+      "text": "errorRenderFlowchart: \"无法渲染流程图\","
     },
     {
-      "line": 1969,
-      "text": "chatDesc: \"ナレッジベースとのスマートな会話\","
+      "line": 421,
+      "text": "errorLoadData: \"加载数据失败\","
     },
     {
-      "line": 1970,
-      "text": "viewHistory: \"チャット履歴を表示\","
+      "line": 422,
+      "text": "confirmUnsupportedFile: \"文件类型 .$1 可能不受支持,是否继续?\","
     },
     {
-      "line": 1971,
-      "text": "saveSettingsFailed: \"設定の保存に失敗しました\","
+      "line": 423,
+      "text": "errorReadFile: \"文件读取失败: $1\","
     },
     {
-      "line": 1972,
-      "text": "loginToUpload: \"アップロードするにはログインしてください\","
+      "line": 424,
+      "text": "successUploadFile: \"文件上传并关联成功\","
     },
     {
-      "line": 1973,
-      "text": "fileSizeLimitExceeded: \"$1 ($2 - $3MB の制限を超えています)\","
+      "line": 425,
+      "text": "errorUploadFile: \"上传失败: $1\","
     },
     {
-      "line": 1974,
-      "text": "unsupportedFileType: \"$1 - サポートされていないファイルタイプ ($2)\","
+      "line": 426,
+      "text": "errorProcessFile: \"文件处理失败\","
     },
     {
-      "line": 1975,
-      "text": "readFailed: \"$1 - 読み込みに失敗しました\","
+      "line": 427,
+      "text": "errorTitleContentRequired: \"标题和内容不能为空\","
     },
     {
-      "line": 1976,
-      "text": "loadHistoryFailed: \"履歴の読み込みに失敗しました\","
+      "line": 428,
+      "text": "successNoteUpdated: \"笔记已更新\","
     },
     {
-      "line": 1977,
-      "text": "loadingUserData: \"ユーザーデータを読み込み中...\","
+      "line": 429,
+      "text": "successNoteCreated: \"笔记已创建\","
     },
     {
-      "line": 1978,
-      "text": "errorMessage: \"エラー: $1\","
+      "line": 430,
+      "text": "errorSaveFailed: \"保存失败: $1\","
     },
     {
-      "line": 1979,
-      "text": "welcomeMessage: \"こんにちは!私はあなたのAIナレッジベースアシスタントです。チャットを開始するにはナレッジグループを選択してください。\","
+      "line": 431,
+      "text": "confirmDeleteNote: \"Confirm要删除这条笔记吗?\","
     },
     {
-      "line": 1980,
-      "text": "selectKnowledgeGroup: \"ナレッジグループを選択\","
+      "line": 432,
+      "text": "successNoteDeleted: \"笔记已删除\","
     },
     {
-      "line": 1981,
-      "text": "allKnowledgeGroups: \"すべてのナレッジグループ\","
+      "line": 433,
+      "text": "confirmRemoveFileFromGroup: \"Confirm要将文件 \\\"$1\\\" 从此知识组移除吗?(文件仍保留在知识库中)\","
     },
     {
-      "line": 1982,
-      "text": "unknownGroup: \"不明なグループ\","
+      "line": 434,
+      "text": "togglePreviewOpen: \"开启预览\","
     },
     {
-      "line": 1983,
-      "text": "selectedGroupsCount: \"$1 グループ選択済み\","
+      "line": 435,
+      "text": "togglePreviewClose: \"关闭预览\","
     },
     {
-      "line": 1986,
-      "text": "generalSettings: \"一般設定\","
+      "line": 436,
+      "text": "aiAssistant: \"AI 智能助手\","
     },
     {
-      "line": 1987,
-      "text": "modelManagement: \"モデル管理\","
+      "line": 437,
+      "text": "polishContent: \"润色内容\","
     },
     {
-      "line": 1988,
-      "text": "languageSettings: \"言語設定\","
+      "line": 438,
+      "text": "expandContent: \"扩写\","
     },
     {
-      "line": 1989,
-      "text": "passwordChangeSuccess: \"パスワードを変更しました\","
+      "line": 439,
+      "text": "summarizeContent: \"精简摘要\","
     },
     {
-      "line": 1990,
-      "text": "passwordChangeFailed: \"パスワードの変更に失敗しました\","
+      "line": 440,
+      "text": "translateToEnglish: \"翻译成英文\","
     },
     {
-      "line": 1991,
-      "text": "create: \"作成\","
+      "line": 441,
+      "text": "fixGrammar: \"修复语法\","
     },
     {
-      "line": 1995,
-      "text": "navChat: \"チャット\","
+      "line": 442,
+      "text": "aiCommandInstructPolish: \"请帮我润色这段文字,使其表达更地道、更专业。\","
     },
     {
-      "line": 1996,
-      "text": "navCoach: \"コーチ\","
+      "line": 443,
+      "text": "aiCommandInstructExpand: \"请帮我扩写这段文字,增加更多细节,使其更充实和详细。\","
     },
     {
-      "line": 1997,
-      "text": "navKnowledge: \"ナレッジベース\","
+      "line": 444,
+      "text": "aiCommandInstructSummarize: \"请帮我精简这段文字,提取核心观点,生成简洁的摘要。\","
     },
     {
-      "line": 1998,
-      "text": "navKnowledgeGroups: \"ナレッジグループ\","
+      "line": 445,
+      "text": "aiCommandInstructTranslateToEn: \"请帮我将这段文字翻译成英文。\","
     },
     {
-      "line": 1999,
-      "text": "navNotebook: \"ノートブック\","
+      "line": 446,
+      "text": "aiCommandInstructFixGrammar: \"请检查并修复这段文字中的语法和拼写错误。\","
     },
     {
-      "line": 2000,
-      "text": "navAgent: \"エージェント\","
+      "line": 447,
+      "text": "aiCommandsPreset: \"常用指令\","
     },
     {
-      "line": 2001,
-      "text": "navPlugin: \"プラグイン\","
+      "line": 448,
+      "text": "aiCommandsCustom: \"自定义需求\","
     },
     {
-      "line": 2002,
-      "text": "navCrawler: \"リソース取得\","
+      "line": 449,
+      "text": "aiCommandsCustomPlaceholder: \"例如:把这段话改写得更正式一点...\","
     },
     {
-      "line": 2003,
-      "text": "expandMenu: \"メニューを展開\","
+      "line": 450,
+      "text": "aiCommandsReferenceContext: \"参考上下文 (前200字):\","
     },
     {
-      "line": 2004,
-      "text": "switchLanguage: \"言語を切り替える\","
+      "line": 451,
+      "text": "aiCommandsStartGeneration: \"开始生成\","
     },
     {
-      "line": 2007,
-      "text": "selectKnowledgeGroups: \"ナレッジグループを選択\","
+      "line": 452,
+      "text": "aiCommandsResult: \"AI 建议\","
     },
     {
-      "line": 2008,
-      "text": "searchGroupsPlaceholder: \"グループを検索...\","
+      "line": 453,
+      "text": "aiCommandsGenerating: \"生成中...\","
     },
     {
-      "line": 2009,
-      "text": "done: \"完了\","
+      "line": 454,
+      "text": "aiCommandsApplyResult: \"替换选区\","
     },
     {
-      "line": 2010,
-      "text": "all: \"すべて\","
+      "line": 455,
+      "text": "aiCommandsGoBack: \"返回修改\","
     },
     {
-      "line": 2011,
-      "text": "noGroupsFound: \"関連するグループが見つかりません\","
+      "line": 456,
+      "text": "aiCommandsReset: \"清空重置\","
     },
     {
-      "line": 2012,
-      "text": "noGroups: \"グループなし\","
+      "line": 457,
+      "text": "aiCommandsModalPreset: \"选择预设指令\","
     },
     {
-      "line": 2015,
-      "text": "autoRefresh: \"自動更新\","
+      "line": 458,
+      "text": "aiCommandsModalCustom: \"或输入自定义指令\","
     },
     {
-      "line": 2016,
-      "text": "refreshInterval: \"更新間隔\","
+      "line": 459,
+      "text": "aiCommandsModalCustomPlaceholder: \"告诉 AI 你想做什么...\","
     },
     {
-      "line": 2019,
-      "text": "errorRenderFlowchart: \"フローチャートを生成できません\","
+      "line": 460,
+      "text": "aiCommandsModalBasedOnSelection: \"将基于以下选Chinese本处理:\","
     },
     {
-      "line": 2020,
-      "text": "errorLoadData: \"データの読み込みに失敗しました\","
+      "line": 461,
+      "text": "aiCommandsModalResult: \"生成结果\","
     },
     {
-      "line": 2021,
-      "text": "confirmUnsupportedFile: \"拡張子 .$1 はサポートされていない可能性があります。続行しますか?\","
+      "line": 462,
+      "text": "aiCommandsModalApply: \"采用此结果\","
     },
     {
-      "line": 2022,
-      "text": "errorReadFile: \"ファイルの読み込みに失敗しました: $1\","
+      "line": 463,
+      "text": "noteTitlePlaceholder: \"笔记标题\","
     },
     {
-      "line": 2023,
-      "text": "successUploadFile: \"ファイルのアップロードと関連付けに成功しました\","
+      "line": 464,
+      "text": "noteContentPlaceholder: \"开始写作 (支持 Markdown)...\","
     },
     {
-      "line": 2024,
-      "text": "errorUploadFile: \"アップロードに失敗しました: $1\","
+      "line": 465,
+      "text": "markdownPreviewArea: \"Markdown 预览区域\","
     },
     {
-      "line": 2025,
-      "text": "errorProcessFile: \"ファイルの処理に失敗しました\","
+      "line": 466,
+      "text": "back: \"返回\","
     },
     {
-      "line": 2026,
-      "text": "errorTitleContentRequired: \"タイトルと内容は必須です\","
+      "line": 467,
+      "text": "chatWithGroup: \"基于此知识组进行对话\","
     },
     {
-      "line": 2027,
-      "text": "successNoteUpdated: \"メモを更新しました\","
+      "line": 468,
+      "text": "chatWithFile: \"基于此文件进行对话\","
     },
     {
-      "line": 2028,
-      "text": "successNoteCreated: \"メモを作成しました\","
+      "line": 469,
+      "text": "filesCountLabel: \"文件 ($1)\","
     },
     {
-      "line": 2029,
-      "text": "errorSaveFailed: \"保存に失敗しました: $1\","
+      "line": 470,
+      "text": "notesCountLabel: \"笔记 ($1)\","
     },
     {
-      "line": 2030,
-      "text": "confirmDeleteNote: \"このメモを削除してもよろしいですか?\","
+      "line": 471,
+      "text": "indexIntoKB: \"索引到知识库\","
     },
     {
-      "line": 2031,
-      "text": "successNoteDeleted: \"メモを削除しました\","
+      "line": 472,
+      "text": "noFilesOrNotes: \"暂无$1\","
     },
     {
-      "line": 2032,
-      "text": "confirmRemoveFileFromGroup: \"ファイル「$1」をこのグループから削除しますか?(ナレッジベースには残ります)\","
+      "line": 473,
+      "text": "importFolder: \"导入文件夹\","
     },
     {
-      "line": 2033,
-      "text": "editNote: \"メモを編集\","
+      "line": 476,
+      "text": "createPDFNote: \"创建PDF笔记\","
     },
     {
-      "line": 2034,
-      "text": "newNote: \"新規メモ\","
+      "line": 477,
+      "text": "screenshotPreview: \"截图预览\","
     },
     {
-      "line": 2035,
-      "text": "togglePreviewOpen: \"プレビューを表示\","
+      "line": 478,
+      "text": "associateKnowledgeGroup: \"关联知识组\","
     },
     {
-      "line": 2036,
-      "text": "togglePreviewClose: \"プレビューを閉じる\","
+      "line": 479,
+      "text": "globalNoSpecificGroup: \"全局 (无特定知识组)\","
     },
     {
-      "line": 2037,
-      "text": "noteTitlePlaceholder: \"メモのタイトル\","
+      "line": 480,
+      "text": "title: \"标题\","
     },
     {
-      "line": 2038,
-      "text": "noteContentPlaceholder: \"書き始める (Markdown 対応)...\","
+      "line": 481,
+      "text": "enterNoteTitle: \"输入笔记标题\","
     },
     {
-      "line": 2039,
-      "text": "markdownPreviewArea: \"Markdown プレビューエリア\","
+      "line": 482,
+      "text": "contentOCR: \"内容 (OCR提取的文本)\","
     },
     {
-      "line": 2040,
-      "text": "back: \"戻る\","
+      "line": 483,
+      "text": "extractingText: \"正在提取文本...\","
     },
     {
-      "line": 2041,
-      "text": "chatWithGroup: \"このグループとチャット\","
+      "line": 484,
+      "text": "analyzingImage: \"正在分析图片并提取文字...\","
     },
     {
-      "line": 2042,
-      "text": "chatWithFile: \"このファイルとチャット\","
+      "line": 485,
+      "text": "noTextExtracted: \"未提取到文本\","
     },
     {
-      "line": 2043,
-      "text": "filesCountLabel: \"ファイル ($1)\","
+      "line": 486,
+      "text": "saveNote: \"保存笔记\","
     },
     {
-      "line": 2044,
-      "text": "notesCountLabel: \"メモ ($1)\","
+      "line": 489,
+      "text": "page: \"第\","
     },
     {
-      "line": 2045,
-      "text": "indexIntoKB: \"インデックスに登録\","
+      "line": 490,
+      "text": "placeholderText: \"OCR提取的文本将显示在这里,您可以编辑...\","
     },
     {
-      "line": 2046,
-      "text": "noFilesOrNotes: \"$1がありません\","
+      "line": 493,
+      "text": "createNewNotebook: \"新建知识组\","
     },
     {
-      "line": 2047,
-      "text": "importFolder: \"フォルダをインポート\","
+      "line": 494,
+      "text": "nameField: \"名称\","
     },
     {
-      "line": 2050,
-      "text": "createPDFNote: \"PDFノートを作成\","
+      "line": 496,
+      "text": "exampleResearch: \"例如:量子物理研究...\","
     },
     {
-      "line": 2051,
-      "text": "screenshotPreview: \"スクリーンショットプレビュー\","
+      "line": 497,
+      "text": "shortDescriptionField: \"简短描述\","
     },
     {
-      "line": 2052,
-      "text": "associateKnowledgeGroup: \"ナレッジグループに関連付ける\","
+      "line": 498,
+      "text": "describePurpose: \"一句话描述这个知识组的用途\","
     },
     {
-      "line": 2053,
-      "text": "globalNoSpecificGroup: \"全体 (特定のグループなし)\","
+      "line": 499,
+      "text": "creationFailed: \"创建失败,请重试\","
     },
     {
-      "line": 2054,
-      "text": "title: \"タイトル\","
+      "line": 502,
+      "text": "preparingPDFConversion: \"准备转换PDF...\","
     },
     {
-      "line": 2055,
-      "text": "enterNoteTitle: \"ノートのタイトルを入力\","
+      "line": 503,
+      "text": "pleaseWait: \"请稍候,这可能需要几分钟时间\","
     },
     {
-      "line": 2056,
-      "text": "contentOCR: \"内容 (OCR抽出されたテキスト)\","
+      "line": 504,
+      "text": "convertingPDF: \"正在转换PDF...\","
     },
     {
-      "line": 2057,
-      "text": "extractingText: \"テキストを抽出中...\","
+      "line": 505,
+      "text": "pdfConversionFailed: \"PDF转换失败\","
     },
     {
-      "line": 2058,
-      "text": "analyzingImage: \"画像を分析してテキストを抽出中...\","
+      "line": 506,
+      "text": "pdfConversionError: \"无法转换此文件为PDF格式,请检查文件是否损坏或格式不支持\","
     },
     {
-      "line": 2059,
-      "text": "noTextExtracted: \"テキストが抽出されませんでした\","
+      "line": 507,
+      "text": "pdfLoadFailed: \"PDF加载失败\","
     },
     {
-      "line": 2060,
-      "text": "saveNote: \"ノートを保存\","
+      "line": 508,
+      "text": "pdfLoadError: \"无法在浏览器中显示PDF,请尝试下载或在新窗口中打开\","
     },
     {
-      "line": 2063,
-      "text": "page: \"ページ\","
+      "line": 509,
+      "text": "downloadingPDF: \"下载PDF中...\","
     },
     {
-      "line": 2064,
-      "text": "placeholderText: \"OCR抽出されたテキストがここに表示されます。編集できます...\","
+      "line": 510,
+      "text": "loadingPDF: \"加载PDF中...\","
     },
     {
-      "line": 2067,
-      "text": "createNewNotebook: \"新しいナレッジグループ\","
+      "line": 511,
+      "text": "zoomOut: \"缩小\","
     },
     {
-      "line": 2068,
-      "text": "nameField: \"名前\","
+      "line": 512,
+      "text": "zoomIn: \"放大\","
     },
     {
-      "line": 2070,
-      "text": "exampleResearch: \"例: 量子物理学研究...\","
+      "line": 513,
+      "text": "resetZoom: \"重置缩放\","
     },
     {
-      "line": 2071,
-      "text": "shortDescriptionField: \"簡単な説明\","
+      "line": 514,
+      "text": "selectPageNumber: \"选择页码:\","
     },
     {
-      "line": 2072,
-      "text": "describePurpose: \"このグループの目的を一文で説明してください\","
+      "line": 515,
+      "text": "enterPageNumber: \"输入想要选取的页码\","
     },
     {
-      "line": 2073,
-      "text": "detailedIntroField: \"詳細な紹介\","
+      "line": 516,
+      "text": "exitSelectionMode: \"退出选择模式\","
     },
     {
-      "line": 2074,
-      "text": "provideBackgroundInfo: \"詳細な背景、目標、またはコンテキスト情報を提供してください...\","
+      "line": 517,
+      "text": "clickToSelectAndNote: \"点击框选区域并记笔记\","
     },
     {
-      "line": 2075,
-      "text": "creationFailed: \"作成に失敗しました。もう一度お試しください\","
+      "line": 518,
+      "text": "regeneratePDF: \"重新生成 PDF\","
     },
     {
-      "line": 2078,
-      "text": "preparingPDFConversion: \"PDF変換を準備中...\","
+      "line": 519,
+      "text": "downloadPDF: \"下载 PDF\","
     },
     {
-      "line": 2079,
-      "text": "pleaseWait: \"しばらくお待ちください。これには数分かかる場合があります\","
+      "line": 520,
+      "text": "openInNewWindow: \"在新窗口中打开\","
     },
     {
-      "line": 2080,
-      "text": "convertingPDF: \"PDFを変換中...\","
+      "line": 521,
+      "text": "exitFullscreen: \"退出全屏\","
     },
     {
-      "line": 2081,
-      "text": "pdfConversionFailed: \"PDF変換に失敗しました\","
+      "line": 522,
+      "text": "fullscreenDisplay: \"全屏显示\","
     },
     {
-      "line": 2082,
-      "text": "pdfConversionError: \"このファイルをPDF形式に変換できません。ファイルが破損していないか、サポートされていない形式でないか確認してください\","
+      "line": 523,
+      "text": "pdfPreview: \"PDF预览\","
     },
     {
-      "line": 2083,
-      "text": "pdfLoadFailed: \"PDF読み込みに失敗しました\","
+      "line": 524,
+      "text": "converting: \"转换中...\","
     },
     {
-      "line": 2084,
-      "text": "pdfLoadError: \"ブラウザでPDFを表示できません。ダウンロードするか、新しいウィンドウで開いてみてください\","
+      "line": 525,
+      "text": "generatePDFPreview: \"生成PDF预览\","
     },
     {
-      "line": 2085,
-      "text": "downloadingPDF: \"PDFをダウンロード中...\","
+      "line": 526,
+      "text": "previewNotSupported: \"该格式不支持预览\","
     },
     {
-      "line": 2086,
-      "text": "loadingPDF: \"PDFを読み込み中...\","
+      "line": 529,
+      "text": "confirmRegeneratePDF: \"Confirm要重新生成 PDF 吗?这将覆盖当前的预览文件。\","
     },
     {
-      "line": 2087,
-      "text": "zoomOut: \"ズームアウト\","
+      "line": 532,
+      "text": "pdfPreviewReady: \"PDF预览\","
     },
     {
-      "line": 2088,
-      "text": "zoomIn: \"ズームイン\","
+      "line": 533,
+      "text": "convertingInProgress: \"转换中...\","
     },
     {
-      "line": 2089,
-      "text": "resetZoom: \"ズームをリセット\","
+      "line": 534,
+      "text": "conversionFailed: \"转换失败\","
     },
     {
-      "line": 2090,
-      "text": "selectPageNumber: \"ページ番号を選択:\","
+      "line": 535,
+      "text": "generatePDFPreviewButton: \"生成PDF预览\","
     },
     {
-      "line": 2091,
-      "text": "enterPageNumber: \"選択したいページ番号を入力してください\","
+      "line": 539,
+      "text": "requestRegenerationFailed: \"请求重新生成失败\","
     },
     {
-      "line": 2092,
-      "text": "exitSelectionMode: \"選択モードを終了\","
+      "line": 540,
+      "text": "downloadPDFFailed: \"PDF 下载失败\","
     },
     {
-      "line": 2093,
-      "text": "clickToSelectAndNote: \"クリックして領域を選択し、メモを取る\","
+      "line": 541,
+      "text": "openPDFInNewTabFailed: \"在新标签页打开 PDF 失败\","
     },
     {
-      "line": 2094,
-      "text": "regeneratePDF: \"PDFを再生成\","
+      "line": 544,
+      "text": "invalidFile: \"无效的文件\","
     },
     {
-      "line": 2095,
-      "text": "downloadPDF: \"PDFをダウンロード\","
+      "line": 545,
+      "text": "incompleteFileInfo: \"文件信息不完整,将使用快速模式\","
     },
     {
-      "line": 2096,
-      "text": "openInNewWindow: \"新しいウィンドウで開く\","
+      "line": 546,
+      "text": "unsupportedFileFormat: \"不支持的文件格式: .$1\","
     },
     {
-      "line": 2097,
-      "text": "exitFullscreen: \"全画面表示を終了\","
+      "line": 547,
+      "text": "willUseFastMode: \"将使用快速模式 (仅文本提取)\","
     },
     {
-      "line": 2098,
-      "text": "fullscreenDisplay: \"全画面表示\","
+      "line": 548,
+      "text": "formatNoPrecise: \"格式 .$1 不支持精准模式\","
     },
     {
-      "line": 2099,
-      "text": "pdfPreview: \"PDFプレビュー\","
+      "line": 549,
+      "text": "smallFileFastOk: \"文件较小,快速模式即可满足需求\","
     },
     {
-      "line": 2100,
-      "text": "converting: \"変換中...\","
+      "line": 550,
+      "text": "mixedContentPreciseRecommended: \"文件包含图文混合内容,建议使用精准模式\","
     },
     {
-      "line": 2101,
-      "text": "generatePDFPreview: \"PDFプレビューを生成\","
+      "line": 551,
+      "text": "willIncurApiCost: \"会产生 API 费用\","
     },
     {
-      "line": 2102,
-      "text": "previewNotSupported: \"この形式はプレビューをサポートしていません\","
+      "line": 552,
+      "text": "largeFilePreciseRecommended: \"文件较大,精准模式可保留完整信息\","
     },
     {
-      "line": 2105,
-      "text": "confirmRegeneratePDF: \"PDFを再生成してもよろしいですか?これにより現在のプレビューファイルが上書きされます。\","
+      "line": 553,
+      "text": "longProcessingTime: \"处理时间可能较长\","
     },
     {
-      "line": 2108,
-      "text": "pdfPreviewReady: \"PDFプレビュー\","
+      "line": 554,
+      "text": "highApiCost: \"会产生较高 API 费用\","
     },
     {
-      "line": 2109,
-      "text": "convertingInProgress: \"変換中...\","
+      "line": 555,
+      "text": "considerFileSplitting: \"建议考虑文件拆分\","
     },
     {
-      "line": 2110,
-      "text": "conversionFailed: \"変換失敗\","
+      "line": 558,
+      "text": "dragDropUploadTitle: \"拖拽文件到这里上传\","
     },
     {
-      "line": 2111,
-      "text": "generatePDFPreviewButton: \"PDFプレビューを生成\","
+      "line": 559,
+      "text": "dragDropUploadDesc: \"或点击下方按钮选择文件\","
     },
     {
-      "line": 2114,
-      "text": "checkPDFStatusFailed: \"PDFステータスの確認に失敗しました\","
+      "line": 560,
+      "text": "supportedFormats: \"支持格式\","
+    },
+    {
+      "line": 561,
+      "text": "browseFiles: \"浏览文件\","
     },
     {
-      "line": 2115,
-      "text": "requestRegenerationFailed: \"再生成要求に失敗しました\","
+      "line": 564,
+      "text": "recommendationMsg: \"推荐使用$1模式: $2\","
     },
     {
-      "line": 2116,
-      "text": "downloadPDFFailed: \"PDFのダウンロードに失敗しました\","
+      "line": 565,
+      "text": "autoAdjustChunk: \"切片大小自动调整为上限 $1\","
     },
     {
-      "line": 2117,
-      "text": "openPDFInNewTabFailed: \"新しいウィンドウでのPDFオープンに失敗しました\","
+      "line": 566,
+      "text": "autoAdjustOverlap: \"重叠大小自动调整为上限 $1\","
     },
     {
-      "line": 2120,
-      "text": "invalidFile: \"無効なファイル\","
+      "line": 567,
+      "text": "autoAdjustOverlapMin: \"重叠大小自动调整为最小值 $1\","
     },
     {
-      "line": 2121,
-      "text": "incompleteFileInfo: \"ファイル情報が不完全です。高速モードを使用します\","
+      "line": 568,
+      "text": "loadLimitsFailed: \"无法加载模型限制,将使用默认配置\","
     },
     {
-      "line": 2122,
-      "text": "unsupportedFileFormat: \"サポートされていない形式: .$1\","
+      "line": 569,
+      "text": "maxValueMsg: \"最大值为 $1\","
     },
     {
-      "line": 2123,
-      "text": "willUseFastMode: \"高速モード(テキスト抽出のみ)を使用します\","
+      "line": 570,
+      "text": "overlapRatioLimit: \"不能超过切片大小的50% ($1)\","
     },
     {
-      "line": 2124,
-      "text": "formatNoPrecise: \"形式 .$1 は精密モードをサポートしていません\","
+      "line": 571,
+      "text": "onlyAdminCanModify: \"只有管理员可以修改系统设置\","
     },
     {
-      "line": 2125,
-      "text": "smallFileFastOk: \"ファイルサイズが小さいため、高速モードで十分です\","
+      "line": 572,
+      "text": "dragToSelect: \"拖动鼠标选择范围 • 按 ESC Cancel\","
     },
     {
-      "line": 2126,
-      "text": "mixedContentPreciseRecommended: \"図表などが含まれるため、精密モードを推奨します\","
+      "line": 575,
+      "text": "fillTargetName: \"请填写目标知识组名称\","
     },
     {
-      "line": 2127,
-      "text": "willIncurApiCost: \"APIコストが発生します\","
+      "line": 576,
+      "text": "submitFailed: \"提交失败: $1\","
     },
     {
-      "line": 2128,
-      "text": "largeFilePreciseRecommended: \"大きなファイルです。構造保持のため精密モードを推奨します\","
+      "line": 577,
+      "text": "importFolderTitle: \"导入本地文件夹\","
     },
     {
-      "line": 2129,
-      "text": "longProcessingTime: \"処理に時間がかかる可能性があります\","
+      "line": 578,
+      "text": "importFolderTip: \"提示: 请选择一个本地文件夹。系统将读取并上传文件夹内所有支持的文档。\","
     },
     {
-      "line": 2130,
-      "text": "highApiCost: \"高いAPIコストが発生します\","
+      "line": 579,
+      "text": "lblTargetGroup: \"目标知识组名称\","
     },
     {
-      "line": 2131,
-      "text": "considerFileSplitting: \"ファイルの分割を検討してください\","
+      "line": 580,
+      "text": "placeholderNewGroup: \"新分组名称\","
     },
     {
-      "line": 2134,
-      "text": "dragDropUploadTitle: \"アップロードするファイルをドラッグ&ドロップ\","
+      "line": 581,
+      "text": "importToCurrentGroup: \"将导入到当前所在的分组\","
     },
     {
-      "line": 2135,
-      "text": "dragDropUploadDesc: \"または下のボタンをクリックしてファイルを選択\","
+      "line": 582,
+      "text": "nextStep: \"下一步\","
     },
     {
-      "line": 2136,
-      "text": "supportedFormats: \"対応フォーマット\","
+      "line": 583,
+      "text": "selectedFilesCount: \"已选择 $1  files\","
     },
     {
-      "line": 2137,
-      "text": "browseFiles: \"ファイルを参照\","
+      "line": 584,
+      "text": "clickToSelectFolder: \"点击选择本地文件夹\","
     },
     {
-      "line": 2140,
-      "text": "recommendationMsg: \"$1モードを推奨します: $2\","
+      "line": 585,
+      "text": "selectFolderTip: \"将读取文件夹内所有支持的文件\","
     },
     {
-      "line": 2141,
-      "text": "autoAdjustChunk: \"チャンクサイズを上限の $1 に調整しました\","
+      "line": 586,
+      "text": "importComplete: \"导入完成\","
     },
     {
-      "line": 2142,
-      "text": "autoAdjustOverlap: \"重なりサイズを上限の $1 に調整しました\","
+      "line": 587,
+      "text": "importedFromLocalFolder: \"从本地文件夹导入: $1\","
     },
     {
-      "line": 2143,
-      "text": "autoAdjustOverlapMin: \"重なりサイズを最小値の $1 に調整しました\","
+      "line": 590,
+      "text": "historyTitle: \"对话历史\","
     },
     {
-      "line": 2144,
-      "text": "loadLimitsFailed: \"モデル制限の読み込みに失敗しました。デフォルト設定を使用します\","
+      "line": 591,
+      "text": "confirmDeleteHistory: \"Confirm要删除这条对话历史吗?\","
     },
     {
-      "line": 2145,
-      "text": "maxValueMsg: \"最大値は $1 です\","
+      "line": 592,
+      "text": "deleteHistorySuccess: \"对话历史删除成功\","
     },
     {
-      "line": 2146,
-      "text": "overlapRatioLimit: \"切片サイズの50% ($1) を超えることはできません\","
+      "line": 593,
+      "text": "deleteHistoryFailed: \"删除对话历史失败\","
     },
     {
-      "line": 2147,
-      "text": "onlyAdminCanModify: \"システム設定は管理者のみ変更可能です\","
+      "line": 594,
+      "text": "yesterday: \"昨天\","
     },
     {
-      "line": 2148,
-      "text": "dragToSelect: \"マウスをドラッグして範囲を選択 • ESCでキャンセル\","
+      "line": 595,
+      "text": "daysAgo: \"$1天前\","
     },
     {
-      "line": 2151,
-      "text": "fillTargetName: \"対象のナレッジグループ名を入力してください\","
+      "line": 596,
+      "text": "historyMessages: \"$1 条消息\","
     },
     {
-      "line": 2152,
-      "text": "submitFailed: \"送信に失敗しました: $1\","
+      "line": 597,
+      "text": "noHistory: \"暂无对话历史\","
     },
     {
-      "line": 2153,
-      "text": "importFolderTitle: \"ローカルフォルダをインポート\","
+      "line": 598,
+      "text": "noHistoryDesc: \"开始一次对话来创建历史记录\","
     },
     {
-      "line": 2154,
-      "text": "importFolderTip: \"ヒント: ローカルフォルダを選択してください。フォルダ内のすべてのサポートされているドキュメントが読み込まれ、アップロードされます。\","
+      "line": 599,
+      "text": "loadMore: \"加载更多\","
     },
     {
-      "line": 2155,
-      "text": "lblTargetGroup: \"対象のナレッジグループ名\","
+      "line": 600,
+      "text": "loadingHistoriesFailed: \"加载搜索历史失败\","
     },
     {
-      "line": 2156,
-      "text": "placeholderNewGroup: \"新規グループ名\","
+      "line": 601,
+      "text": "generalSettingsSubtitle: \"管理您的应用程序首选项。\","
     },
     {
-      "line": 2157,
-      "text": "importToCurrentGroup: \"現在のグループにインポートされます\","
+      "line": 602,
+      "text": "userManagementSubtitle: \"管理访问权限和帐户。\","
     },
     {
-      "line": 2158,
-      "text": "nextStep: \"次へ\","
+      "line": 603,
+      "text": "modelManagementSubtitle: \"配置全局 AI 模型。\","
     },
     {
-      "line": 2159,
-      "text": "lblImportSource: \"インポート元\","
+      "line": 604,
+      "text": "kbSettingsSubtitle: \"索引和聊天参数的技术配置。\","
     },
     {
-      "line": 2160,
-      "text": "serverPath: \"サーバーのパス\","
+      "line": 605,
+      "text": "tenantsSubtitle: \"全局系统概览。\","
     },
     {
-      "line": 2161,
-      "text": "localFolder: \"ローカルフォルダ\","
+      "line": 607,
+      "text": "allNotes: \"所有笔记\","
     },
     {
-      "line": 2162,
-      "text": "selectedFilesCount: \"$1 個のファイルが選択されました\","
+      "line": 608,
+      "text": "filterNotesPlaceholder: \"筛选笔记...\","
     },
     {
-      "line": 2163,
-      "text": "clickToSelectFolder: \"クリックしてローカルフォルダを選択\","
+      "line": 609,
+      "text": "startWritingPlaceholder: \"开始写作...\","
     },
     {
-      "line": 2164,
-      "text": "selectFolderTip: \"フォルダ内のすべてのサポートされているファイルを読み込みます\","
+      "line": 610,
+      "text": "previewHeader: \"预览\","
     },
     {
-      "line": 2165,
-      "text": "importComplete: \"インポート完了\","
+      "line": 611,
+      "text": "noContentToPreview: \"没有可预览的内容\","
     },
     {
-      "line": 2166,
-      "text": "importedFromLocalFolder: \"ローカルフォルダからインポート: $1\","
+      "line": 612,
+      "text": "hidePreview: \"隐藏预览\","
     },
     {
-      "line": 2169,
-      "text": "historyTitle: \"会話履歴\","
+      "line": 613,
+      "text": "showPreview: \"显示预览\","
     },
     {
-      "line": 2170,
-      "text": "confirmDeleteHistory: \"この会話履歴を削除してもよろしいですか?\","
+      "line": 614,
+      "text": "directoryLabel: \"目录\","
     },
     {
-      "line": 2171,
-      "text": "deleteHistorySuccess: \"会話履歴を削除しました\","
+      "line": 615,
+      "text": "uncategorized: \"未分类\","
     },
     {
-      "line": 2172,
-      "text": "deleteHistoryFailed: \"会話履歴の削除に失敗しました\","
+      "line": 616,
+      "text": "enterNamePlaceholder: \"输入名称...\","
     },
     {
-      "line": 2173,
-      "text": "yesterday: \"昨日\","
+      "line": 617,
+      "text": "subFolderPlaceholder: \"子文件夹...\","
     },
     {
-      "line": 2174,
-      "text": "daysAgo: \"$1日前\","
+      "line": 618,
+      "text": "categoryCreated: \"分类已创建\","
     },
     {
-      "line": 2175,
-      "text": "historyMessages: \"$1 件のメッセージ\","
+      "line": 619,
+      "text": "failedToCreateCategory: \"创建分类失败\","
     },
     {
-      "line": 2176,
-      "text": "noHistory: \"会話履歴はありません\","
+      "line": 620,
+      "text": "failedToDeleteCategory: \"删除分类失败\","
     },
     {
-      "line": 2177,
-      "text": "noHistoryDesc: \"会話を開始して履歴を作成してください\","
+      "line": 621,
+      "text": "confirmDeleteCategory: \"您Confirm要删除此分类吗?\","
     },
     {
-      "line": 2178,
-      "text": "loadMore: \"もっと読み込む\","
+      "line": 622,
+      "text": "kbSettingsSaved: \"检索与对话配置已保存\","
     },
     {
-      "line": 2179,
-      "text": "loadingHistoriesFailed: \"履歴の読み込みに失敗しました\","
+      "line": 623,
+      "text": "failedToSaveSettings: \"保存设置失败\","
     },
     {
-      "line": 2180,
-      "text": "supportedFormatsInfo: \"ドキュメント、画像、ソースコードをサポート\","
+      "line": 624,
+      "text": "actionFailed: \"操作失败\","
     },
     {
-      "line": 2181,
-      "text": "kbSettingsSaved: \"設定を保存しました\","
+      "line": 625,
+      "text": "userAddedToOrganization: \"用户已添加到组织\","
     },
     {
-      "line": 2182,
-      "text": "failedToSaveSettings: \"設定の保存に失敗しました\","
+      "line": 626,
+      "text": "featureUpdated: \"功能已更新\","
     },
     {
-      "line": 2183,
-      "text": "actionFailed: \"操作に失敗しました\","
+      "line": 627,
+      "text": "roleTenantAdmin: \"租户管理员\","
     },
     {
-      "line": 2184,
-      "text": "userAddedToOrganization: \"ユーザーが組織に追加されました\","
+      "line": 628,
+      "text": "roleRegularUser: \"普通用户\","
     },
     {
-      "line": 2185,
-      "text": "featureUpdated: \"機能が更新されました\","
+      "line": 629,
+      "text": "creatingRegularUser: \"正在创建普通用户\","
     },
     {
-      "line": 2186,
-      "text": "roleTenantAdmin: \"テナント管理者\","
+      "line": 630,
+      "text": "editUserRole: \"修改用户角色\","
     },
     {
-      "line": 2187,
-      "text": "roleRegularUser: \"一般ユーザー\","
+      "line": 631,
+      "text": "targetRole: \"目标角色\","
     },
     {
-      "line": 2188,
-      "text": "creatingRegularUser: \"一般ユーザーを作成中\","
+      "line": 632,
+      "text": "editCategory: \"编辑分类\","
     },
     {
-      "line": 2189,
-      "text": "editUserRole: \"ユーザーロールを編集\","
+      "line": 633,
+      "text": "totalTenants: \"总租户数\","
     },
     {
-      "line": 2190,
-      "text": "targetRole: \"対象のロール\","
+      "line": 634,
+      "text": "systemUsers: \"系统用户\","
     },
     {
-      "line": 2191,
-      "text": "editCategory: \"カテゴリを編集\","
+      "line": 635,
+      "text": "systemHealth: \"系统健康\","
     },
     {
-      "line": 2192,
-      "text": "totalTenants: \"総テナント数\","
+      "line": 636,
+      "text": "operational: \"运行正常\","
     },
     {
-      "line": 2193,
-      "text": "systemUsers: \"システムユーザー\","
+      "line": 637,
+      "text": "orgManagement: \"组织管理\","
     },
     {
-      "line": 2194,
-      "text": "systemHealth: \"システムヘルス\","
+      "line": 638,
+      "text": "globalTenantControl: \"全局租户控制\","
     },
     {
-      "line": 2195,
-      "text": "operational: \"正常稼働中\","
+      "line": 639,
+      "text": "newTenant: \"新租户\","
     },
     {
-      "line": 2196,
-      "text": "orgManagement: \"組織管理\","
+      "line": 640,
+      "text": "domainOptional: \"域名 (可选)\","
     },
     {
-      "line": 2197,
-      "text": "globalTenantControl: \"グローバルテナントコントロール\","
+      "line": 641,
+      "text": "saveChanges: \"保存修改\","
     },
     {
-      "line": 2198,
-      "text": "newTenant: \"新規テナント\","
+      "line": 642,
+      "text": "modelConfiguration: \"模型配置\","
     },
     {
-      "line": 2199,
-      "text": "domainOptional: \"ドメイン (任意)\","
+      "line": 643,
+      "text": "defaultLLMModel: \"默认推理模型\","
     },
     {
-      "line": 2200,
-      "text": "saveChanges: \"変更を保存\","
+      "line": 644,
+      "text": "selectLLM: \"选择 LLM\","
     },
     {
-      "line": 2201,
-      "text": "modelConfiguration: \"モデル設定\","
+      "line": 645,
+      "text": "selectEmbedding: \"选择 Embedding\","
     },
     {
-      "line": 2202,
-      "text": "defaultLLMModel: \"デフォルト推論モデル\","
+      "line": 646,
+      "text": "rerankModel: \"Rerank 模型\","
     },
     {
-      "line": 2203,
-      "text": "selectLLM: \"LLMを選択\","
+      "line": 647,
+      "text": "none: \"无\","
     },
     {
-      "line": 2204,
-      "text": "selectEmbedding: \"埋め込みを選択\","
+      "line": 648,
+      "text": "indexingChunkingConfig: \"索引与切片配置\","
     },
     {
-      "line": 2205,
-      "text": "rerankModel: \"リランクモデル\","
+      "line": 649,
+      "text": "chatHyperparameters: \"聊天超参数\","
     },
     {
-      "line": 2206,
-      "text": "none: \"なし\","
+      "line": 650,
+      "text": "temperature: \"随机性 (Temperature)\","
     },
     {
-      "line": 2207,
-      "text": "indexingChunkingConfig: \"インデックスとチャンク設定\","
+      "line": 651,
+      "text": "precise: \"精确\","
     },
     {
-      "line": 2208,
-      "text": "chatHyperparameters: \"チャットハイパーパラメータ\","
+      "line": 652,
+      "text": "creative: \"创意\","
     },
     {
-      "line": 2209,
-      "text": "temperature: \"温度\","
+      "line": 653,
+      "text": "maxResponseTokens: \"最大响应标识 (Max Tokens)\","
     },
     {
-      "line": 2210,
-      "text": "precise: \"精密\","
+      "line": 654,
+      "text": "retrievalSearchSettings: \"检索与搜索设置\","
     },
     {
-      "line": 2211,
-      "text": "creative: \"クリエイティブ\","
+      "line": 655,
+      "text": "topK: \"召回数量 (Top K)\","
     },
     {
-      "line": 2212,
-      "text": "maxResponseTokens: \"最大応答トークン数\","
+      "line": 656,
+      "text": "similarityThreshold: \"相似度阈值\","
     },
     {
-      "line": 2213,
-      "text": "retrievalSearchSettings: \"検索設定\","
+      "line": 657,
+      "text": "enableHybridSearch: \"启用混合检索\","
     },
     {
-      "line": 2215,
-      "text": "similarityThreshold: \"類似度しきい値\","
+      "line": 658,
+      "text": "hybridSearchDesc: \"同时使用向量和全文检索以提高召回率\","
     },
     {
-      "line": 2216,
-      "text": "enableHybridSearch: \"ハイブリッド検索を有効にする\","
+      "line": 659,
+      "text": "hybridWeight: \"混合权重 (0.0=全文, 1.0=向量)\","
     },
     {
-      "line": 2217,
-      "text": "hybridSearchDesc: \"ベクトル検索と全文検索を併用して検索精度を向上させます\","
+      "line": 660,
+      "text": "pureText: \"纯文本\","
     },
     {
-      "line": 2218,
-      "text": "hybridWeight: \"ハイブリッド重み (0.0=全文, 1.0=ベクトル)\","
+      "line": 661,
+      "text": "pureVector: \"纯向量\","
     },
     {
-      "line": 2219,
-      "text": "pureText: \"純粋なテキスト\","
+      "line": 662,
+      "text": "enableQueryExpansion: \"启用查询扩展\","
     },
     {
-      "line": 2220,
-      "text": "pureVector: \"純粋なベクトル\","
+      "line": 663,
+      "text": "queryExpansionDesc: \"生成多个查询变体以提高覆盖率\","
     },
     {
-      "line": 2221,
-      "text": "enableQueryExpansion: \"クエリ拡張を有効にする\","
+      "line": 664,
+      "text": "enableHyDE: \"启用 HyDE\","
     },
     {
-      "line": 2222,
-      "text": "queryExpansionDesc: \"複数のクエリバリアントを生成してカバレッジを向上させます\","
+      "line": 665,
+      "text": "hydeDesc: \"生成假设回答以改善语义搜索\","
     },
     {
-      "line": 2223,
-      "text": "enableHyDE: \"HyDEを有効にする\","
+      "line": 666,
+      "text": "enableReranking: \"启用重排序 (Rerank)\","
     },
     {
-      "line": 2224,
-      "text": "hydeDesc: \"仮想的な回答を生成してセマンティック検索を改善します\","
+      "line": 667,
+      "text": "rerankingDesc: \"使用 Rerank 模型对结果进行二次排序\","
     },
     {
-      "line": 2225,
-      "text": "enableReranking: \"リランクを有効にする\","
+      "line": 668,
+      "text": "broad: \"宽泛\","
     },
     {
-      "line": 2226,
-      "text": "rerankingDesc: \"リランクモデルを使用して結果を再ソートします\","
+      "line": 669,
+      "text": "strict: \"严格\","
     },
     {
-      "line": 2227,
-      "text": "broad: \"広範\","
+      "line": 670,
+      "text": "maxInput: \"最大输入\","
     },
     {
-      "line": 2228,
-      "text": "strict: \"厳格\","
+      "line": 671,
+      "text": "dimensions: \"维度\","
     },
     {
-      "line": 2229,
-      "text": "maxInput: \"最大入力\","
+      "line": 672,
+      "text": "defaultBadge: \"默认\","
     },
     {
-      "line": 2230,
-      "text": "dimensions: \"次元\","
+      "line": 673,
+      "text": "dims: \"维度: $1\","
     },
     {
-      "line": 2231,
-      "text": "defaultBadge: \"デフォルト\","
+      "line": 674,
+      "text": "ctx: \"上下文: $1\","
     },
     {
-      "line": 2232,
-      "text": "dims: \"次元: $1\","
+      "line": 676,
+      "text": "configured: \"已配置\","
     },
     {
-      "line": 2233,
-      "text": "ctx: \"コンテキスト: $1\","
+      "line": 677,
+      "text": "groupUpdated: \"分组已更新\","
     },
     {
-      "line": 2235,
-      "text": "configured: \"設定済み\","
+      "line": 678,
+      "text": "groupDeleted: \"分组已删除\","
     },
     {
-      "line": 2236,
-      "text": "groupUpdated: \"グループが更新されました\","
+      "line": 679,
+      "text": "groupCreated: \"分组已创建\","
     },
     {
-      "line": 2237,
-      "text": "groupDeleted: \"グループが削除されました\","
+      "line": 680,
+      "text": "navCatalog: \"目录\","
     },
     {
-      "line": 2238,
-      "text": "groupCreated: \"グループが作成されました\","
+      "line": 681,
+      "text": "allDocuments: \"所有文档\","
     },
     {
-      "line": 2239,
-      "text": "navCatalog: \"カタログ\","
+      "line": 682,
+      "text": "categories: \"分类\","
     },
     {
-      "line": 2240,
-      "text": "allDocuments: \"すべてのドキュメント\","
+      "line": 683,
+      "text": "uncategorizedFiles: \"未分类文件\","
     },
     {
-      "line": 2241,
-      "text": "categories: \"カテゴリ\","
+      "line": 684,
+      "text": "category: \"分类\","
     },
     {
-      "line": 2242,
-      "text": "uncategorizedFiles: \"未分類ファイル\","
+      "line": 685,
+      "text": "statusReadyDesc: \"已索引可查询\","
     },
     {
-      "line": 2243,
-      "text": "category: \"カテゴリ\","
+      "line": 686,
+      "text": "statusIndexingDesc: \"正在建立词向量索引\","
     },
     {
-      "line": 2244,
-      "text": "statusReadyDesc: \"インデックス済みで検索可能\","
+      "line": 687,
+      "text": "selectCategory: \"选择分类\","
     },
     {
-      "line": 2245,
-      "text": "statusIndexingDesc: \"ベクトルインデックスを作成中\","
+      "line": 688,
+      "text": "noneUncategorized: \"无未分类文件\","
     },
     {
-      "line": 2246,
-      "text": "selectCategory: \"カテゴリを選択\","
+      "line": 689,
+      "text": "previous: \"上一页\","
     },
     {
-      "line": 2247,
-      "text": "noneUncategorized: \"未分類ファイルなし\","
+      "line": 690,
+      "text": "next: \"下一页\","
     },
     {
-      "line": 2248,
-      "text": "previous: \"前へ\","
+      "line": 691,
+      "text": "createCategory: \"创建分类\","
     },
     {
-      "line": 2249,
-      "text": "next: \"次へ\","
+      "line": 692,
+      "text": "categoryDesc: \"描述您的知识分类\","
     },
     {
-      "line": 2250,
-      "text": "createCategory: \"カテゴリを作成\","
+      "line": 693,
+      "text": "categoryName: \"分类名称\","
     },
     {
-      "line": 2251,
-      "text": "categoryDesc: \"ナレッジカテゴリを説明します\","
+      "line": 694,
+      "text": "createCategoryBtn: \"立即创建\","
     },
     {
-      "line": 2252,
-      "text": "categoryName: \"カテゴリ名\","
+      "line": 695,
+      "text": "newGroup: \"新建分组\","
     },
     {
-      "line": 2253,
-      "text": "createCategoryBtn: \"今すぐ作成\","
+      "line": 696,
+      "text": "noKnowledgeGroups: \"暂无知识库分组\","
     },
     {
-      "line": 2254,
-      "text": "newGroup: \"新規グループ\","
+      "line": 697,
+      "text": "createGroupDesc: \"开始创建您的第一个知识库分组并上传相关文档。\","
     },
     {
-      "line": 2255,
-      "text": "noKnowledgeGroups: \"ナレッジグループがまだありません\","
+      "line": 698,
+      "text": "noDescriptionProvided: \"未提供描述\","
     },
     {
-      "line": 2256,
-      "text": "createGroupDesc: \"最初のナレッジグループを作成してドキュメントをアップロードしてください。\","
+      "line": 699,
+      "text": "browseManageFiles: \"浏览并管理该分组下的文件和笔记。\","
     },
     {
-      "line": 2257,
-      "text": "noDescriptionProvided: \"説明なし\","
+      "line": 700,
+      "text": "filterGroupFiles: \"根据名称搜索分组内文件...\","
     },
     {
-      "line": 2258,
-      "text": "browseManageFiles: \"このグループ内のファイルとメモを閲覧・管理します。\","
+      "line": 704,
+      "text": "agentTitle: \"智能体中心\","
     },
     {
-      "line": 2259,
-      "text": "filterGroupFiles: \"名前でグループ内のファイルを検索...\","
+      "line": 705,
+      "text": "agentDesc: \"管理和运行您的 AI 助手,协助完成复杂任务。\","
     },
     {
-      "line": 2260,
-      "text": "generalSettingsSubtitle: \"アプリケーションの設定を管理します。\","
+      "line": 706,
+      "text": "createAgent: \"创建智能体\","
     },
     {
-      "line": 2261,
-      "text": "userManagementSubtitle: \"アクセス権限とアカウントを管理します。\","
+      "line": 707,
+      "text": "searchAgent: \"搜索智能体...\","
     },
     {
-      "line": 2262,
-      "text": "modelManagementSubtitle: \"グローバルなAIモデルを設定します。\","
+      "line": 708,
+      "text": "statusRunning: \"运行中\","
     },
     {
-      "line": 2263,
-      "text": "kbSettingsSubtitle: \"インデックス作成とチャットパラメータの技術設定。\","
+      "line": 709,
+      "text": "statusStopped: \"已停止\","
     },
     {
-      "line": 2264,
-      "text": "tenantsSubtitle: \"グローバルシステムの概要。\","
+      "line": 710,
+      "text": "updatedAtPrefix: \"最后更新于 \","
     },
     {
-      "line": 2265,
-      "text": "allNotes: \"すべてのノート\","
+      "line": 711,
+      "text": "btnChat: \"开始对话\","
     },
     {
-      "line": 2266,
-      "text": "filterNotesPlaceholder: \"ノートをフィルタリング...\","
+      "line": 714,
+      "text": "agent1Name: \"数据分析专家\","
     },
     {
-      "line": 2267,
-      "text": "startWritingPlaceholder: \"書き始める...\","
+      "line": 715,
+      "text": "agent1Desc: \"精通 SQL 和数据可视化,能够从复杂数据中提取洞察。\","
     },
     {
-      "line": 2268,
-      "text": "previewHeader: \"プレビュー\","
+      "line": 716,
+      "text": "agent2Name: \"代码审查助手\","
     },
     {
-      "line": 2269,
-      "text": "noContentToPreview: \"プレビューするコンテンツがありません\","
+      "line": 717,
+      "text": "agent2Desc: \"自动检查代码质量,提供重构建议和性能优化方案。\","
     },
     {
-      "line": 2270,
-      "text": "hidePreview: \"プレビューを非表示\","
+      "line": 718,
+      "text": "agent3Name: \"学术论文润色\","
     },
     {
-      "line": 2271,
-      "text": "showPreview: \"プレビューを表示\","
+      "line": 719,
+      "text": "agent3Desc: \"专业的学术写作助手,帮助优化论文结构和语言表达。\","
     },
     {
-      "line": 2272,
-      "text": "directoryLabel: \"ディレクトリ\","
+      "line": 720,
+      "text": "agent4Name: \"法律顾问\","
     },
     {
-      "line": 2273,
-      "text": "uncategorized: \"未分類\","
+      "line": 721,
+      "text": "agent4Desc: \"提供法律条文查询和基础法律建议,协助起草合同。\","
     },
     {
-      "line": 2274,
-      "text": "enterNamePlaceholder: \"名前を入力...\","
+      "line": 722,
+      "text": "agent5Name: \"市场研究员\","
     },
     {
-      "line": 2275,
-      "text": "subFolderPlaceholder: \"サブフォルダ...\","
+      "line": 723,
+      "text": "agent5Desc: \"分析行业趋势,生成竞争对手调研报告。\","
     },
     {
-      "line": 2276,
-      "text": "categoryCreated: \"カテゴリが作成されました\","
+      "line": 724,
+      "text": "agent6Name: \"系统运维专家\","
     },
     {
-      "line": 2277,
-      "text": "failedToCreateCategory: \"カテゴリの作成に失敗しました\","
+      "line": 725,
+      "text": "agent6Desc: \"监控系统健康,自动处理常见告警和排障。\","
     },
     {
-      "line": 2278,
-      "text": "failedToDeleteCategory: \"カテゴリの削除に失敗しました\","
+      "line": 726,
+      "text": "agent7Name: \"财务审计师\","
     },
     {
-      "line": 2279,
-      "text": "confirmDeleteCategory: \"このカテゴリを削除してもよろしいですか?\","
+      "line": 727,
+      "text": "agent7Desc: \"自动化报表审计,识别财务风险和异常交易。\","
     },
     {
-      "line": 2283,
-      "text": "agentTitle: \"エージェントセンター\","
+      "line": 728,
+      "text": "agent1Time: \"2 小时前\","
     },
     {
-      "line": 2284,
-      "text": "agentDesc: \"複雑なタスクを支援する AI アシスタントを管理および実行します。\","
+      "line": 729,
+      "text": "agent2Time: \"5 小时前\","
     },
     {
-      "line": 2285,
-      "text": "createAgent: \"エージェント作成\","
+      "line": 730,
+      "text": "agent3Time: \"昨天\","
     },
     {
-      "line": 2286,
-      "text": "searchAgent: \"エージェントを検索...\","
+      "line": 731,
+      "text": "agent4Time: \"2 天前\","
     },
     {
-      "line": 2287,
-      "text": "statusRunning: \"実行中\","
+      "line": 732,
+      "text": "agent5Time: \"3 天前\","
     },
     {
-      "line": 2288,
-      "text": "statusStopped: \"停止中\","
+      "line": 733,
+      "text": "agent6Time: \"5 天前\","
     },
     {
-      "line": 2289,
-      "text": "updatedAtPrefix: \"最終更新日: \","
+      "line": 734,
+      "text": "agent7Time: \"1 周前\","
     },
     {
-      "line": 2290,
-      "text": "btnChat: \"会話を開始\","
+      "line": 737,
+      "text": "pluginTitle: \"插件中心\","
     },
     {
-      "line": 2293,
-      "text": "agent1Name: \"データ分析エキスパート\","
+      "line": 738,
+      "text": "pluginDesc: \"扩展知识库的功能,集成外部工具和服务。\","
     },
     {
-      "line": 2294,
-      "text": "agent1Desc: \"SQL とデータ視覚化に精通し、複雑なデータから洞察を抽出できます。\","
+      "line": 739,
+      "text": "searchPlugin: \"搜索插件...\","
     },
     {
-      "line": 2295,
-      "text": "agent2Name: \"コードレビュー助手\","
+      "line": 740,
+      "text": "installPlugin: \"安装插件\","
     },
     {
-      "line": 2296,
-      "text": "agent2Desc: \"コードの品質を自動的にチェックし、リファクタリングの提案やパフォーマンス最適化案を提供します。\","
+      "line": 741,
+      "text": "installedPlugin: \"已安装\","
     },
     {
-      "line": 2297,
-      "text": "agent3Name: \"学術論文校閲\","
+      "line": 742,
+      "text": "updatePlugin: \"有更新\","
     },
     {
-      "line": 2298,
-      "text": "agent3Desc: \"専門的な学術ライティングアシスタント。論文の構成と表現の最適化を支援します。\","
+      "line": 743,
+      "text": "pluginOfficial: \"官方\","
     },
     {
-      "line": 2299,
-      "text": "agent4Name: \"法律顧問\","
+      "line": 744,
+      "text": "pluginCommunity: \"社区\","
     },
     {
-      "line": 2300,
-      "text": "agent4Desc: \"法律条文の検索や基本的な法的アドバイスを提供し、契約書の作成を支援します。\","
+      "line": 745,
+      "text": "pluginBy: \"由 \","
     },
     {
-      "line": 2301,
-      "text": "agent5Name: \"市場調査員\","
+      "line": 746,
+      "text": "pluginConfig: \"插件配置\","
     },
     {
-      "line": 2302,
-      "text": "agent5Desc: \"業界のトレンドを分析し、競合他社の調査レポートを生成します。\","
+      "line": 749,
+      "text": "plugin1Name: \"Web 搜索\","
     },
     {
-      "line": 2303,
-      "text": "agent6Name: \"システム運用保守エキスパート\","
+      "line": 750,
+      "text": "plugin1Desc: \"赋予 AI 实时访问互联网的能力,获取最新信息。\","
     },
     {
-      "line": 2304,
-      "text": "agent6Desc: \"システムの健康状態を監視し、一般的なアラートへの対応やトラブルシューティングを自動化します。\","
+      "line": 751,
+      "text": "plugin2Name: \"PDF 文档解析\","
     },
     {
-      "line": 2305,
-      "text": "agent7Name: \"財務監査人\","
+      "line": 752,
+      "text": "plugin2Desc: \"深度解析复杂 PDF 布局,提取表格和数学公式。\","
     },
     {
-      "line": 2306,
-      "text": "agent7Desc: \"レポート監査を自動化し、財務リスクや異常な取引を特定します。\","
+      "line": 753,
+      "text": "plugin3Name: \"GitHub 集成\","
     },
     {
-      "line": 2307,
-      "text": "agent1Time: \"2 時間前\","
+      "line": 754,
+      "text": "plugin3Desc: \"直接访问 GitHub 仓库,进行代码提交和 issue 管理。\","
     },
     {
-      "line": 2308,
-      "text": "agent2Time: \"5 時間前\","
+      "line": 755,
+      "text": "plugin4Name: \"Google 日历\","
     },
     {
-      "line": 2309,
-      "text": "agent3Time: \"昨日\","
+      "line": 756,
+      "text": "plugin4Desc: \"同步您的日程安排,自动创建会议提醒。\","
     },
     {
-      "line": 2310,
-      "text": "agent4Time: \"2 日前\","
+      "line": 757,
+      "text": "plugin5Name: \"SQL 数据库连接\","
     },
     {
-      "line": 2311,
-      "text": "agent5Time: \"3 日前\","
+      "line": 758,
+      "text": "plugin5Desc: \"安全地连接到您的数据库,执行自然语言查询。\","
     },
     {
-      "line": 2312,
-      "text": "agent6Time: \"5 日前\","
+      "line": 759,
+      "text": "plugin6Name: \"Slack 通知\","
     },
     {
-      "line": 2313,
-      "text": "agent7Time: \"1 週間前\","
+      "line": 760,
+      "text": "plugin6Desc: \"将 AI 生成的报告直接发送到指定的 Slack 频道。\","
     },
     {
-      "line": 2316,
-      "text": "pluginTitle: \"プラグインストア\","
+      "line": 763,
+      "text": "addSubcategory: \"添加子分类\","
     },
     {
-      "line": 2317,
-      "text": "pluginDesc: \"外部ツールやサービスを統合して、ナレッジベースの機能を拡張します。\","
+      "line": 764,
+      "text": "parentCategory: \"父分类 (可选)\","
     },
     {
-      "line": 2318,
-      "text": "searchPlugin: \"プラグインを検索...\","
+      "line": 765,
+      "text": "noParentTopLevel: \"无父分类(顶级)\","
     },
     {
-      "line": 2319,
-      "text": "installPlugin: \"インストール\","
+      "line": 766,
+      "text": "useHierarchyImport: \"按文件夹层级创建分类\","
     },
     {
-      "line": 2320,
-      "text": "installedPlugin: \"インストール済み\","
+      "line": 767,
+      "text": "useHierarchyImportDesc: \"启用后将为每个子文件夹创建对应的子分类,并将文件导入到匹配的分类中。\","
     },
     {
-      "line": 2321,
-      "text": "updatePlugin: \"アップデートあり\","
+      "line": 770,
+      "text": "importImmediate: \"立即导入\","
     },
     {
-      "line": 2322,
-      "text": "pluginOfficial: \"公式\","
+      "line": 771,
+      "text": "importScheduled: \"定时导入\","
     },
     {
-      "line": 2323,
-      "text": "pluginCommunity: \"コミュニティ\","
+      "line": 772,
+      "text": "lblServerPath: \"服务器文件夹路径\","
     },
     {
-      "line": 2324,
-      "text": "pluginBy: \"開発者: \","
+      "line": 773,
+      "text": "placeholderServerPath: \"例如: /data/documents\","
     },
     {
-      "line": 2325,
-      "text": "pluginConfig: \"設定\","
+      "line": 774,
+      "text": "scheduledImportTip: \"服务器端定时导入:服务器将在指定时间读取该路径下的文件并自动导入。请确保服务器有访问该路径的权限。\","
     },
     {
-      "line": 2328,
-      "text": "plugin1Name: \"Web 検索\","
+      "line": 775,
+      "text": "lblScheduledTime: \"执行时间\","
     },
     {
-      "line": 2329,
-      "text": "plugin1Desc: \"最新情報を取得するために、AI にインターネットへのリアルタイムアクセスを提供します。\","
+      "line": 776,
+      "text": "scheduledTimeHint: \"到达指定时间后,服务器将自动执行导入任务。\","
     },
     {
-      "line": 2330,
-      "text": "plugin2Name: \"PDF ドキュメント解析\","
+      "line": 777,
+      "text": "scheduleImport: \"创建定时任务\","
     },
     {
-      "line": 2331,
-      "text": "plugin2Desc: \"複雑な PDF レイアウトを詳細に解析し、表や数式を抽出します。\","
+      "line": 778,
+      "text": "scheduleTaskCreated: \"定时导入任务已创建\","
     },
     {
-      "line": 2332,
-      "text": "plugin3Name: \"GitHub 連携\","
+      "line": 779,
+      "text": "fillServerPath: \"请输入服务器文件夹路径\","
     },
     {
-      "line": 2333,
-      "text": "plugin3Desc: \"GitHub リポジトリに直接アクセスし、コードのコミットやイシュー管理を行います。\","
+      "line": 780,
+      "text": "invalidDateTime: \"请输入有效的日期时间\","
     },
     {
-      "line": 2334,
-      "text": "plugin4Name: \"Google カレンダー\","
+      "line": 783,
+      "text": "importTasksTitle: \"定时计划\","
     },
     {
-      "line": 2335,
-      "text": "plugin4Desc: \"スケジュールを同期し、会議のリマインダーを自動的に作成します。\","
+      "line": 784,
+      "text": "noTasksFound: \"暂无任务\","
     },
     {
-      "line": 2336,
-      "text": "plugin5Name: \"SQL データベース接続\","
+      "line": 785,
+      "text": "sourcePath: \"源路径\","
     },
     {
-      "line": 2337,
-      "text": "plugin5Desc: \"データベースに安全に接続し、自然語言でクエリを実行します。\","
+      "line": 786,
+      "text": "targetGroup: \"目标分组\","
     },
     {
-      "line": 2338,
-      "text": "plugin6Name: \"Slack 通知\","
+      "line": 787,
+      "text": "scheduledAt: \"计划执行时间\","
     },
     {
-      "line": 2339,
-      "text": "plugin6Desc: \"AI が生成したレポートを指定された Slack チャンネルに直接送信します。\","
+      "line": 788,
+      "text": "confirmDeleteTask: \"Confirm要删除此导入任务记录吗?\","
     },
     {
-      "line": 2341,
-      "text": "navTenants: \"テナント管理\","
+      "line": 789,
+      "text": "deleteTaskFailed: \"删除任务记录失败\","
     },
     {
-      "line": 2342,
-      "text": "noNotesFound: \"ノートが見つかりません\","
+      "line": 1591,
+      "text": "aiCommandsError: \"エラーが発生しました\","
     },
     {
-      "line": 2343,
-      "text": "notebookDesc: \"ノートブックは知識の整理と要約に役立ちます。\","
+      "line": 1592,
+      "text": "appTitle: \"Gemini ナレッジベース\","
     },
     {
-      "line": 2344,
-      "text": "personalNotebook: \"個人用ノートブック\","
+      "line": 1593,
+      "text": "loginTitle: \"ログイン\","
     },
     {
-      "line": 2345,
-      "text": "warning: \"警告\","
+      "line": 1594,
+      "text": "loginDesc: \"システムに入るためのキーを入力してください\","
     },
     {
-      "line": 2346,
-      "text": "\"x-api-key\": \"APIキー\","
+      "line": 1595,
+      "text": "loginButton: \"ログイン\","
     },
     {
-      "line": 2347,
-      "text": "\"x-tenant-id\": \"テナントID\","
+      "line": 1596,
+      "text": "loginError: \"キーは必須です\","
     },
     {
-      "line": 2348,
-      "text": "\"x-user-language\": \"ユーザー言語\","
+      "line": 1597,
+      "text": "unknown: \"不明\","
     },
     {
-      "line": 2351,
-      "text": "addSubcategory: \"サブカテゴリを追加\","
+      "line": 1598,
+      "text": "unknownError: \"未知のエラー\","
     },
     {
-      "line": 2352,
-      "text": "parentCategory: \"親カテゴリ(任意)\","
+      "line": 1599,
+      "text": "usernamePlaceholder: \"ユーザー名\","
     },
     {
-      "line": 2353,
-      "text": "noParentTopLevel: \"なし(トップレベル)\","
+      "line": 1600,
+      "text": "passwordPlaceholder: \"パスワード\","
     },
     {
-      "line": 2354,
-      "text": "useHierarchyImport: \"フォルダ階層でカテゴリを作成\","
+      "line": 1601,
+      "text": "registerButton: \"登録\","
     },
     {
-      "line": 2355,
-      "text": "useHierarchyImportDesc: \"有効にすると、各サブフォルダにサブカテゴリが作成され、ファイルが対応するカテゴリにインポートされます。\","
+      "line": 1602,
+      "text": "langZh: \"言語: 中国語\","
     },
     {
-      "line": 2358,
-      "text": "importImmediate: \"今すぐインポート\","
+      "line": 1603,
+      "text": "langEn: \"言語: 英語\","
     },
     {
-      "line": 2359,
-      "text": "importScheduled: \"スケジュールインポート\","
+      "line": 1604,
+      "text": "langJa: \"言語: Japanese\","
     },
     {
-      "line": 2360,
-      "text": "lblServerPath: \"サーバーフォルダパス\","
+      "line": 1605,
+      "text": "confirm: \"確認\","
     },
     {
-      "line": 2361,
-      "text": "placeholderServerPath: \"例: /data/documents\","
+      "line": 1606,
+      "text": "cancel: \"キャンセル\","
     },
     {
-      "line": 2362,
-      "text": "scheduledImportTip: \"サーバー側のスケジュールインポート:指定した時刻にサーバーがパスのファイルを読み込んで自動インポートします。サーバーがそのパスにアクセスできることを確認してください。\","
+      "line": 1607,
+      "text": "confirmTitle: \"操作の確認\","
     },
     {
-      "line": 2363,
-      "text": "lblScheduledTime: \"実行日時\","
+      "line": 1608,
+      "text": "confirmDeleteGroup: \"グループ \\\"$1\\\" を削除してもよろしいですか?\","
     },
     {
-      "line": 2364,
-      "text": "scheduledTimeHint: \"指定した時刻に、サーバーが自動的にインポートタスクを実行します。\","
+      "line": 1610,
+      "text": "sidebarTitle: \"索引とチャットの設定\","
     },
     {
-      "line": 2365,
-      "text": "scheduleImport: \"スケジュールタスクを作成\","
+      "line": 1611,
+      "text": "backToWorkspace: \"ワークスペースに戻る\","
     },
     {
-      "line": 2366,
-      "text": "scheduleTaskCreated: \"スケジュールインポートタスクが作成されました\","
+      "line": 1612,
+      "text": "goToAdmin: \"管理画面へ\","
     },
     {
-      "line": 2367,
-      "text": "fillServerPath: \"サーバーフォルダパスを入力してください\","
+      "line": 1613,
+      "text": "sidebarDesc: \"ドキュメントとモデル管理\","
     },
     {
-      "line": 2368,
-      "text": "invalidDateTime: \"有効な日付と時刻を入力してください\","
+      "line": 1614,
+      "text": "tabFiles: \"ドキュメント\","
     },
     {
-      "line": 2371,
-      "text": "importTasksTitle: \"定期計画\","
+      "line": 1615,
+      "text": "files: \"ファイル\","
     },
     {
-      "line": 2372,
-      "text": "noTasksFound: \"タスクは見つかりませんでした\","
+      "line": 1616,
+      "text": "notes: \"メモ\","
     },
     {
-      "line": 2373,
-      "text": "sourcePath: \"ソースパス\","
+      "line": 1617,
+      "text": "tabSettings: \"設定\","
     },
     {
-      "line": 2374,
-      "text": "targetGroup: \"ターゲットグループ\","
+      "line": 1618,
+      "text": "systemConfiguration: \"システム構成\","
     },
     {
-      "line": 2375,
-      "text": "scheduledAt: \"実行予定日時\","
+      "line": 1619,
+      "text": "noFiles: \"ファイルなし\","
     },
     {
-      "line": 2376,
-      "text": "confirmDeleteTask: \"このインポートタスクレコードを削除してもよろしいですか?\","
+      "line": 1620,
+      "text": "noFilesDesc: \"PDF、Office文書、テキスト、コード、画像などをサポート\","
     },
     {
-      "line": 2377,
-      "text": "deleteTaskFailed: \"タスクレコードの削除に失敗しました\","
-    }
-  ],
-  "d:\\workspace\\AuraK\\server\\src\\ai\\embedding.service.ts": [
+      "line": 1621,
+      "text": "addFile: \"ファイルAdded\","
+    },
     {
-      "line": 11,
-      "text": "// ほとんどの設定が OpenAI インターフェースと互換性があると仮定"
+      "line": 1622,
+      "text": "clearAll: \"全削除\","
     },
     {
-      "line": 13,
-      "text": "openAIApiKey: config.apiKey || 'ollama', // ローカルモデルの場合は key が不要な場合がある"
+      "line": 1623,
+      "text": "uploading: \"処理中\","
     },
     {
-      "line": 17,
-      "text": "modelName: config.modelId, // modelId に修正"
+      "line": 1624,
+      "text": "statusIndexing: \"ベクトル化中...\","
     },
     {
-      "line": 20,
-      "text": "// テキストが長すぎる問題の処理?LangChain は通常、自動的に処理するかエラーを出力します。"
+      "line": 1625,
+      "text": "statusReady: \"完了\","
     },
     {
-      "line": 21,
-      "text": "// ここでは簡略化し、直接呼び出します"
+      "line": 1628,
+      "text": "ragSettings: \"RAG 設定\","
     },
     {
-      "line": 28,
-      "text": "); // modelId に修正"
-    }
-  ],
-  "d:\\workspace\\AuraK\\server\\src\\api\\api.controller.ts": [
+      "line": 1629,
+      "text": "enableRerank: \"リランクを有効にする\","
+    },
     {
-      "line": 43,
-      "text": "// ユーザーの LLM モデル設定を取得"
+      "line": 1630,
+      "text": "enableRerankDesc: \"リランクモデルを使用してSearch resultsを再ランク付けし、精度を向上させます\","
     },
     {
-      "line": 50,
-      "text": "// APIキーはオプションです - ローカルモデルを許可します"
+      "line": 1631,
+      "text": "selectRerankModel: \"リランクモデルの選択\","
     },
     {
-      "line": 52,
-      "text": "// entity タイプを types インターフェースに変換"
-    }
-  ],
-  "d:\\workspace\\AuraK\\server\\src\\api\\api.service.ts": [
+      "line": 1632,
+      "text": "selectModelPlaceholder: \"モデルを選択...\","
+    },
     {
-      "line": 9,
-      "text": "// 簡易的なヘルスチェックメソッド"
+      "line": 1634,
+      "text": "headerModelSelection: \"モデル選択\","
     },
     {
-      "line": 18,
-      "text": "// APIキーはオプションです - ローカルモデルを許可します"
-    }
-  ],
-  "d:\\workspace\\AuraK\\server\\src\\chat\\chat.controller.ts": [
+      "line": 1635,
+      "text": "headerHyperparams: \"推論パラメータ\","
+    },
     {
-      "line": 21,
-      "text": "selectedLLMId?: string; // 新增:选中的 LLM 模型 ID"
+      "line": 1636,
+      "text": "headerIndexing: \"インデックスと分割\","
     },
     {
-      "line": 22,
-      "text": "selectedGroups?: string[]; // 新增"
+      "line": 1637,
+      "text": "headerRetrieval: \"検索とランク付け\","
     },
     {
-      "line": 23,
-      "text": "selectedFiles?: string[]; // 新增:选中的文件"
+      "line": 1638,
+      "text": "btnManageModels: \"プロバイダー管理\","
     },
     {
-      "line": 24,
-      "text": "historyId?: string; // 新增"
+      "line": 1640,
+      "text": "lblLLM: \"推論モデル (LLM)\","
     },
     {
-      "line": 25,
-      "text": "enableRerank?: boolean; // 新增"
+      "line": 1641,
+      "text": "lblEmbedding: \"埋め込みモデル\","
     },
     {
-      "line": 26,
-      "text": "selectedRerankId?: string; // 新增"
+      "line": 1642,
+      "text": "lblRerankRef: \"リランクモデル\","
     },
     {
-      "line": 27,
-      "text": "temperature?: number; // 新增:temperature 参数"
+      "line": 1643,
+      "text": "lblTemperature: \"温度 (Temperature)\","
     },
     {
-      "line": 28,
-      "text": "maxTokens?: number; // 新增:maxTokens 参数"
+      "line": 1644,
+      "text": "lblMaxTokens: \"最大トークン数\","
     },
     {
-      "line": 29,
-      "text": "topK?: number; // 新增:topK 参数"
+      "line": 1646,
+      "text": "lblChunkOverlap: \"オーバーラップ\","
     },
     {
-      "line": 30,
-      "text": "similarityThreshold?: number; // 新増:similarityThreshold 参数"
+      "line": 1647,
+      "text": "lblTopK: \"検索数 (Top K)\","
     },
     {
-      "line": 31,
-      "text": "rerankSimilarityThreshold?: number; // 新増:rerankSimilarityThreshold 参数"
+      "line": 1648,
+      "text": "lblRerank: \"リランク有効化\","
     },
     {
-      "line": 32,
-      "text": "enableQueryExpansion?: boolean; // 新增"
+      "line": 1650,
+      "text": "idxModalTitle: \"インデックス設定\","
     },
     {
-      "line": 33,
-      "text": "enableHyDE?: boolean; // 新增"
+      "line": 1651,
+      "text": "idxDesc: \"取り込みの前に分割ルールと埋め込みモデルを設定してください。\","
     },
     {
-      "line": 76,
-      "text": "// 获取用户的LLM模型配置"
+      "line": 1652,
+      "text": "idxFiles: \"対象ファイル\","
     },
     {
-      "line": 94,
-      "text": "console.log('Final LLM model used (default):', llmModel ? llmModel.name : '无');"
+      "line": 1653,
+      "text": "idxMethod: \"分割設定\","
     },
     {
-      "line": 97,
-      "text": "// 设置 SSE 响应头"
+      "line": 1654,
+      "text": "idxEmbeddingModel: \"埋め込みモデル\","
     },
     {
-      "line": 105,
-      "text": "`data: ${JSON.stringify({ type: 'error', data: '请在模型管理中添加LLM模型并配置API密钥' })}\\n\\n`,"
+      "line": 1655,
+      "text": "idxStart: \"インデックス開始\","
     },
     {
-      "line": 119,
-      "text": "selectedGroups, // 新增"
+      "line": 1656,
+      "text": "idxCancel: \"キャンセル\","
     },
     {
-      "line": 120,
-      "text": "selectedFiles, // 新增"
+      "line": 1657,
+      "text": "idxAuto: \"自動\","
     },
     {
-      "line": 121,
-      "text": "historyId, // 新增"
+      "line": 1658,
+      "text": "idxCustom: \"カスタム\","
     },
     {
-      "line": 124,
-      "text": "temperature, // 传递 temperature 参数"
+      "line": 1660,
+      "text": "mmTitle: \"モデルプロバイダー管理\","
     },
     {
-      "line": 125,
-      "text": "maxTokens, // 传递 maxTokens 参数"
+      "line": 1661,
+      "text": "mmAddBtn: \"モデルAdded\","
     },
     {
-      "line": 126,
-      "text": "topK, // 传递 topK 参数"
+      "line": 1662,
+      "text": "mmEdit: \"編集\","
     },
     {
-      "line": 127,
-      "text": "similarityThreshold, // 传递 similarityThreshold 参数"
+      "line": 1663,
+      "text": "mmDelete: \"削除\","
     },
     {
-      "line": 128,
-      "text": "rerankSimilarityThreshold, // 传递 rerankSimilarityThreshold 参数"
+      "line": 1664,
+      "text": "mmEmpty: \"設定されたモデルはありません\","
     },
     {
-      "line": 129,
-      "text": "enableQueryExpansion, // 传递 enableQueryExpansion"
+      "line": 1665,
+      "text": "mmFormName: \"表示名\","
     },
     {
-      "line": 130,
-      "text": "enableHyDE, // 传递 enableHyDE"
+      "line": 1666,
+      "text": "mmFormProvider: \"プロバイダー\","
     },
     {
-      "line": 144,
-      "text": "`data: ${JSON.stringify({ type: 'error', data: error.message || '服务器错误' })}\\n\\n`,"
+      "line": 1667,
+      "text": "mmFormModelId: \"モデルID (例: gpt-4o)\","
     },
     {
-      "line": 176,
-      "text": "`data: ${JSON.stringify({ type: 'error', data: '未找到LLM模型配置' })}\\n\\n`,"
+      "line": 1669,
+      "text": "mmFormType: \"機能タイプ\","
     },
     {
-      "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": 1670,
+      "text": "mmFormVision: \"画像認識対応\","
     },
     {
-      "line": 53,
-      "text": "selectedFiles?: string[], // 新規:選択されたファイル"
+      "line": 1671,
+      "text": "mmFormDimensions: \"ベクトル次元\","
     },
     {
-      "line": 54,
-      "text": "historyId?: string, // 新規:対話履歴ID"
+      "line": 1672,
+      "text": "mmFormDimensionsHelp: \"埋め込みベクトルの次元数、一般的な値:1536、3072\","
     },
     {
-      "line": 57,
-      "text": "temperature?: number, // 新規: temperature パラメータ"
+      "line": 1673,
+      "text": "mmSave: \"保存\","
     },
     {
-      "line": 58,
-      "text": "maxTokens?: number, // 新規: maxTokens パラメータ"
+      "line": 1674,
+      "text": "mmCancel: \"キャンセル\","
     },
     {
-      "line": 59,
-      "text": "topK?: number, // 新規: topK パラメータ"
+      "line": 1675,
+      "text": "mmErrorNotAuthenticated: \"認証されていません、操作できません\","
     },
     {
-      "line": 60,
-      "text": "similarityThreshold?: number, // 新規: similarityThreshold パラメータ"
+      "line": 1676,
+      "text": "mmErrorTitle: \"操作失敗\","
     },
     {
-      "line": 61,
-      "text": "rerankSimilarityThreshold?: number, // 新規: rerankSimilarityThreshold パラメータ"
+      "line": 1677,
+      "text": "modelEnabled: \"モデル有効\","
     },
     {
-      "line": 62,
-      "text": "enableQueryExpansion?: boolean, // 新規"
+      "line": 1678,
+      "text": "modelDisabled: \"モデル無効\","
     },
     {
-      "line": 63,
-      "text": "enableHyDE?: boolean, // 新規"
+      "line": 1679,
+      "text": "confirmChangeEmbeddingModel: \"警告:埋め込みモデルを変更すると、既存のインデックスが検索できなくなる可能性があります。\\n変更してよろしいですか?\","
     },
     {
-      "line": 64,
-      "text": "tenantId?: string // 新規: tenant isolation"
+      "line": 1680,
+      "text": "embeddingModelWarning: \"この設定を変更すると、ナレッジベースのクリアと再インポートが必要になる場合があります。\","
     },
     {
-      "line": 67,
-      "text": "console.log('ユーザーID:', userId);"
+      "line": 1681,
+      "text": "sourcePreview: \"引用元プレビュー\","
     },
     {
-      "line": 85,
-      "text": "console.log('API Key プレフィックス:', modelConfig.apiKey?.substring(0, 10) + '...');"
+      "line": 1682,
+      "text": "matchScore: \"一致度\","
     },
     {
-      "line": 88,
-      "text": "// 現在の言語設定を取得 (下位互換性のためにLANGUAGE_CONFIGを保持しますが、現在はi18nサービスを使>用)"
+      "line": 1683,
+      "text": "copyContent: \"内容をコピー\","
     },
     {
-      "line": 89,
-      "text": "// ユーザー設定に基づいて実際の言語を使用"
+      "line": 1684,
+      "text": "copySuccess: \"コピーしました\","
     },
     {
-      "line": 96,
-      "text": "// historyId がない場合は、新しい対話履歴を作成"
+      "line": 1686,
+      "text": "// ConfigPanel 缺失の翻訳"
     },
     {
-      "line": 100,
-      "text": "tenantId || 'default', // 新規"
+      "line": 1687,
+      "text": "selectLLMModel: \"LLMモデルを選択してください\","
     },
     {
-      "line": 109,
-      "text": "// ユーザーメッセージを保存"
+      "line": 1688,
+      "text": "selectEmbeddingModel: \"Embeddingモデルを選択してください\","
     },
     {
-      "line": 111,
-      "text": "// 1. ユーザーの埋め込みモデル設定を取得"
+      "line": 1689,
+      "text": "defaultForUploads: \"新しいアップロードとクエリのデフォルト\","
     },
     {
-      "line": 124,
-      "text": "// 2. ユーザーのクエリを直接使用して検索"
+      "line": 1690,
+      "text": "noRerankModel: \"リランクモデルなし\","
     },
     {
-      "line": 132,
-      "text": "// 3. 選択された知識グループがある場合、まずそれらのグループ内のファイルIDを取得"
+      "line": 1691,
+      "text": "vectorSimilarityThreshold: \"ベクトル検索しきい値\","
     },
     {
-      "line": 133,
-      "text": "let effectiveFileIds = selectedFiles; // 明示的に指定されたファイルを優先"
+      "line": 1692,
+      "text": "rerankSimilarityThreshold: \"リランクしきい値\","
     },
     {
-      "line": 135,
-      "text": "// ナレッジグループからファイルIDを取得"
+      "line": 1693,
+      "text": "filterLowResults: \"この値を下回る結果はフィルタリングされます\","
     },
     {
-      "line": 139,
-      "text": "// 3. RagService を使用して検索 (混合検索 + Rerank をサポート)"
+      "line": 1694,
+      "text": "noteCreatedSuccess: \"Create noteしました\","
     },
     {
-      "line": 157,
-      "text": "// RagSearchResult を ChatService が必要とする形式 (any[]) に変換"
+      "line": 1695,
+      "text": "noteCreatedFailed: \"ノートの作成に失敗しました\","
     },
     {
-      "line": 158,
-      "text": "// HybridSearch は ES の hit 構造を返しますが、RagSearchResult は正規化されています。"
+      "line": 1696,
+      "text": "fullTextSearch: \"全文検索\","
     },
     {
-      "line": 159,
-      "text": "// BuildContext は {fileName, content} を期待します。RagSearchResult はこれらを持っています。"
+      "line": 1697,
+      "text": "hybridVectorWeight: \"ハイブリッド検索ベクトル重み\","
     },
     {
-      "line": 163,
-      "text": "// 4. コンテキストの構築"
+      "line": 1698,
+      "text": "hybridVectorWeightDesc: \"重み: 1.0 = ベクトルのみ, 0.0 = キーワードのみ\","
     },
     {
-      "line": 168,
-      "text": "// ユーザーがナレッジグループを選択したが、一致するものが見つからなかった場合"
+      "line": 1699,
+      "text": "lblQueryExpansion: \"クエリ拡張 (Multi-Query)\","
     },
     {
-      "line": 181,
-      "text": "// 一時的なデバッグ情報"
+      "line": 1700,
+      "text": "lblHyDE: \"HyDE (仮想ドキュメント埋め込み)\","
     },
     {
-      "line": 198,
-      "text": "// 5. ストリーム回答生成"
+      "line": 1701,
+      "text": "lblQueryExpansionDesc: \"検索カバレッジ向上のために複数のクエリを生成\","
     },
     {
-      "line": 241,
-      "text": "// AI 回答を保存"
+      "line": 1702,
+      "text": "lblHyDEDesc: \"セマンティック検索改善のために仮想回答を生成\","
     },
     {
-      "line": 256,
-      "text": "// 7. 自動チャットタイトル生成 (最初のやり取りの後に実行)"
+      "line": 1704,
+      "text": "apiKeyValidationFailed: \"API Key検証に失敗しました\","
     },
     {
-      "line": 264,
-      "text": "// 6. 引用元を返却"
+      "line": 1705,
+      "text": "keepOriginalKey: \"空のままにすると元のAPI Keyを保持、新しい値を入力すると置換\","
     },
     {
-      "line": 303,
-      "text": "提供されたテキスト内容を、ユーザーの指示に基づいて修正または改善してください。"
+      "line": 1706,
+      "text": "leaveEmptyNoChange: \"空のままで変更なし\","
     },
     {
-      "line": 304,
-      "text": "挨拶や結びの言葉(「わかりました、こちらが...」など)は含めず、修正後の内容のみを直接出力してください。"
+      "line": 1708,
+      "text": "mmFormApiKeyPlaceholder: \"API Key を入力してください\","
     },
     {
-      "line": 306,
-      "text": "コンテキスト(現在の内容):"
+      "line": 1710,
+      "text": "// さらに缺失している翻訳"
     },
     {
-      "line": 309,
-      "text": "ユーザーの指示:"
+      "line": 1711,
+      "text": "reconfigureFile: \"ファイルの再設定\","
     },
     {
-      "line": 329,
-      "text": "selectedGroups?: string[], // 新規パラメータ"
+      "line": 1712,
+      "text": "modifySettings: \"ファイルの分割とベクトル化設定を変更\","
     },
     {
-      "line": 330,
-      "text": "explicitFileIds?: string[], // 新規パラメータ"
+      "line": 1713,
+      "text": "filesCount: \"ファイル\","
     },
     {
-      "line": 331,
-      "text": "tenantId?: string, // 追加"
+      "line": 1714,
+      "text": "allFilesIndexed: \"以下の設定ですべてのファイルがインデックス化されます。\","
     },
     {
-      "line": 334,
-      "text": "// キーワードを検索文字列に結合"
+      "line": 1715,
+      "text": "noEmbeddingModels: \"埋め込みモデルが設定されていません\","
     },
     {
-      "line": 338,
-      "text": "// 埋め込みモデルIDが提供されているか確認"
+      "line": 1716,
+      "text": "reconfigure: \"再設定\","
     },
     {
-      "line": 344,
-      "text": "// 実際の埋め込みベクトルを使用"
+      "line": 1717,
+      "text": "refresh: \"更新\","
     },
     {
-      "line": 354,
-      "text": "// 混合検索"
+      "line": 1718,
+      "text": "settings: \"設定\","
     },
     {
-      "line": 362,
-      "text": "selectedGroups, // 選択されたグループを渡す"
+      "line": 1719,
+      "text": "needLogin: \"チャット機能を使用するにはログインが必要です\","
     },
     {
-      "line": 363,
-      "text": "explicitFileIds, // 明示的なファイルIDを渡す"
+      "line": 1720,
+      "text": "citationSources: \"引用元\","
     },
     {
-      "line": 364,
-      "text": "tenantId, // 追加: tenantId"
+      "line": 1721,
+      "text": "chunkNumber: \"フラグメント\","
     },
     {
-      "line": 442,
-      "text": "temperature: settings.temperature ?? 0.7, // ユーザー設定またはデフォルトを使用"
+      "line": 1722,
+      "text": "getUserListFailed: \"ユーザー一覧の取得に失敗しました\","
     },
     {
-      "line": 461,
-      "text": "* 対話内容に基づいてチャットのタイトルを自動生成する"
+      "line": 1723,
+      "text": "usernamePasswordRequired: \"ユーザー名とパスワードは必須です\","
     },
     {
-      "line": 479,
-      "text": "// 優先順位: 引数の言語 > ユーザー設定 > 日本語(ja)"
+      "line": 1724,
+      "text": "passwordMinLength: \"パスワードは6文字以上で入力してください\","
     },
     {
-      "line": 486,
-      "text": "// プロンプトを構築"
+      "line": 1725,
+      "text": "userCreatedSuccess: \"ユーザーが作成されました\","
     },
     {
-      "line": 489,
-      "text": "// LLMを呼び出してタイトルを生成"
+      "line": 1726,
+      "text": "createUserFailed: \"ユーザー作成に失敗しました\","
     },
     {
-      "line": 497,
-      "text": "// 余分な引用符を除去"
-    }
-  ],
-  "d:\\workspace\\AuraK\\server\\src\\common\\constants.ts": [
-    {
-      "line": 2,
-      "text": "* アプリケーション全体で使用される定数定義"
+      "line": 1727,
+      "text": "userPromotedToAdmin: \"ユーザーを管理者に昇格しました\","
     },
     {
-      "line": 5,
-      "text": "// チャンク設定のデフォルト値"
+      "line": 1728,
+      "text": "userDemotedFromAdmin: \"ユーザーを一般ユーザーに降格しました\","
     },
     {
-      "line": 13,
-      "text": "// ベクトル次元のデフォルト値 (OpenAI Standard)"
+      "line": 1729,
+      "text": "updateUserFailed: \"ユーザー情報の更新に失敗しました\","
     },
     {
-      "line": 16,
-      "text": "// ファイルサイズの制限 (バイト)"
+      "line": 1730,
+      "text": "confirmDeleteUser: \"このユーザーを削除してもよろしいですか?\","
     },
     {
-      "line": 19,
-      "text": "// バッチ処理の制限"
+      "line": 1731,
+      "text": "deleteUser: \"ユーザー削除\","
     },
     {
-      "line": 22,
-      "text": "// デフォルト言語"
+      "line": 1732,
+      "text": "deleteUserFailed: \"ユーザーの削除に失敗しました\","
     },
     {
-      "line": 25,
-      "text": "// システム全体の共通テナントID(シードデータなどで使用)"
-    }
-  ],
-  "d:\\workspace\\AuraK\\server\\src\\elasticsearch\\elasticsearch.service.ts": [
+      "line": 1733,
+      "text": "userDeletedSuccessfully: \"ユーザーを削除しました\","
+    },
     {
-      "line": 34,
-      "text": "// 初期化時にはインデックスを作成せず、実際の使用時にモデルに基づいて動的に作成されるのを待つ"
+      "line": 1734,
+      "text": "makeUserAdmin: \"管理者にする\","
     },
     {
-      "line": 51,
-      "text": "// 既存インデックスのベクトル次元数を確認"
+      "line": 1735,
+      "text": "makeUserRegular: \"一般ユーザーにする\","
     },
     {
-      "line": 66,
-      "text": "// 既存インデックスを削除して再作成"
+      "line": 1736,
+      "text": "loading: \"読み込み中...\","
     },
     {
-      "line": 153,
-      "text": "refresh: true, // 即座に検索に反映させる"
+      "line": 1737,
+      "text": "noUsers: \"ユーザーなし\","
     },
     {
-      "line": 203,
-      "text": "score: this.normalizeScore(hit._score), // スコアの正規化"
+      "line": 1740,
+      "text": "aiAssistant: \"AI アシスタント\","
     },
     {
-      "line": 264,
-      "text": "score: this.normalizeScore(hit._score), // スコアの正規化"
+      "line": 1741,
+      "text": "polishContent: \"内容を洗練\","
     },
     {
-      "line": 290,
-      "text": "selectedGroups?: string[], // 後方互換性のために残す(未使用)"
+      "line": 1742,
+      "text": "expandContent: \"展開\","
     },
     {
-      "line": 291,
-      "text": "explicitFileIds?: string[], // 明示的に指定されたファイルIDリスト"
+      "line": 1743,
+      "text": "summarizeContent: \"要約\","
     },
     {
-      "line": 294,
-      "text": "// selectedGroups は廃止予定。呼び出し側で fileIds に変換して explicitFileIds を使用してください"
+      "line": 1744,
+      "text": "translateToEnglish: \"英語に翻訳\","
     },
     {
-      "line": 306,
-      "text": "// ハイブリッド検索:ベクトル検索 + 全文検索"
+      "line": 1745,
+      "text": "fixGrammar: \"文法修正\","
     },
     {
-      "line": 312,
-      "text": "// 結果をマージして重複を排除"
+      "line": 1746,
+      "text": "aiCommandInstructPolish: \"このテキストをよりプロフェッショナルで自然な表現に推敲してください。\","
     },
     {
-      "line": 315,
-      "text": "// 向量搜索結果を追加"
+      "line": 1747,
+      "text": "aiCommandInstructExpand: \"このテキストに詳細をAddedして内容を充実させ、詳しく書き広げてください。\","
     },
     {
-      "line": 325,
-      "text": "// 全文検索結果を追加"
+      "line": 1748,
+      "text": "aiCommandInstructSummarize: \"このテキストの要点を抽出し、簡潔な要約を作成してください。\","
     },
     {
-      "line": 343,
-      "text": "// 正規化のためにすべての組み合わせスコアを取得"
+      "line": 1749,
+      "text": "aiCommandInstructTranslateToEn: \"このテキストを英語に翻訳してください。\","
     },
     {
-      "line": 345,
-      "text": "const maxScore = Math.max(...allScores, 1); // ゼロ除算を避けるため最小1"
+      "line": 1750,
+      "text": "aiCommandInstructFixGrammar: \"このテキストの文法やスペルの誤りをチェックし、修正してください。\","
     },
     {
-      "line": 348,
-      "text": "// 総合スコアでソートして上位 topK の結果を返す"
+      "line": 1751,
+      "text": "aiCommandsPreset: \"よく使うコマンド\","
     },
     {
-      "line": 353,
-      "text": "// combinedScoreは既に0-1の範囲にあるため、追加の正規化は不要"
+      "line": 1752,
+      "text": "aiCommandsCustom: \"カスタムリクエスト\","
     },
     {
-      "line": 354,
-      "text": "// 0-1の範囲にスコアを保つことで、実際の類似度を正確に反映"
+      "line": 1753,
+      "text": "aiCommandsCustomPlaceholder: \"例:この文章をより正式なものに書き直してください...\","
     },
     {
-      "line": 357,
-      "text": "// スコアが0-1の範囲内に収まるようにクリップ"
+      "line": 1754,
+      "text": "aiCommandsReferenceContext: \"参照コンテキスト (最初の200文字):\","
     },
     {
-      "line": 377,
-      "text": "// チャンク内容"
+      "line": 1755,
+      "text": "aiCommandsStartGeneration: \"生成開始\","
     },
     {
-      "line": 382,
-      "text": "// ベクトルデータ"
+      "line": 1756,
+      "text": "aiCommandsResult: \"AIの提案\","
     },
     {
-      "line": 389,
-      "text": "// ファイル関連情報"
+      "line": 1757,
+      "text": "aiCommandsGenerating: \"生成中...\","
     },
     {
-      "line": 395,
-      "text": "// チャンク情報"
+      "line": 1758,
+      "text": "aiCommandsApplyResult: \"選択範囲を置換\","
     },
     {
-      "line": 400,
-      "text": "// ユーザー情報"
+      "line": 1759,
+      "text": "aiCommandsGoBack: \"戻る\","
     },
     {
-      "line": 403,
-      "text": "// テナント情報(マルチテナント分離用)"
+      "line": 1760,
+      "text": "aiCommandsReset: \"リセット\","
     },
     {
-      "line": 406,
-      "text": "// タイムスタンプ"
+      "line": 1761,
+      "text": "aiCommandsModalPreset: \"プリセットコマンドを選択\","
     },
     {
-      "line": 422,
-      "text": "* Elasticsearch スコアを 0-1 の範囲に正規化する"
+      "line": 1762,
+      "text": "aiCommandsModalCustom: \"またはカスタムコマンドを入力\","
     },
     {
-      "line": 423,
-      "text": "* Elasticsearch のスコアは 1.0 を超える可能性があるため、正規化が必要"
+      "line": 1763,
+      "text": "aiCommandsModalCustomPlaceholder: \"AIに何をしたいか伝えてください...\","
     },
     {
-      "line": 424,
-      "text": "* ただし、kNN検索の類似度スコアは既に0-1の範囲にある(cosine similarity)ので、"
+      "line": 1764,
+      "text": "aiCommandsModalBasedOnSelection: \"選択したテキストに基づいて:\","
     },
     {
-      "line": 425,
-      "text": "* 特別な正規化は不要。必要に応じて最小値保護のみ行う。"
+      "line": 1765,
+      "text": "aiCommandsModalResult: \"生成結果\","
     },
     {
-      "line": 428,
-      "text": "if (!rawScore || rawScore <= 0) return 0; // 最小値は0"
+      "line": 1766,
+      "text": "aiCommandsModalApply: \"結果を適用\","
     },
     {
-      "line": 430,
-      "text": "// kNN検索の場合は既に0-1の範囲にあるので、1を超えないようにクリップ"
+      "line": 1768,
+      "text": "// ChangePasswordModal と SearchResultsPanel の缺失翻訳"
     },
     {
-      "line": 431,
-      "text": "// cosine similarityの最大値は1なので、1以上になった場合は1とする"
+      "line": 1769,
+      "text": "fillAllFields: \"すべてのフィールドを入力してください\","
     },
     {
-      "line": 435,
-      "text": "// ファイルフィルタ付きのベクトル検索"
+      "line": 1770,
+      "text": "passwordMismatch: \"新しいパスワードと確認パスワードが一致しません\","
     },
     {
-      "line": 516,
-      "text": "// ファイルフィルタ付きの全文検索"
+      "line": 1771,
+      "text": "newPasswordMinLength: \"新しいパスワードは6文字以上で入力してください\","
     },
     {
-      "line": 599,
-      "text": "* 指定されたファイルのすべてのチャンクを取得"
+      "line": 1772,
+      "text": "changePasswordFailed: \"パスワードの変更に失敗しました\","
     },
     {
-      "line": 618,
-      "text": "size: 10000, // 単一ファイルが 10000 チャンクを超えないと想定"
+      "line": 1773,
+      "text": "changePasswordTitle: \"パスワード変更\","
     },
     {
-      "line": 620,
-      "text": "excludes: ['vector'], // 転送量を減らすため、ベクトルデータは返さない"
-    }
-  ],
-  "d:\\workspace\\AuraK\\server\\src\\i18n\\i18n.service.ts": [
-    {
-      "line": 7,
-      "text": "private readonly defaultLanguage = 'ja'; // プロジェクト要件に従い、日本語をデフォルトとして使用"
+      "line": 1774,
+      "text": "changing: \"変更中...\","
     },
     {
-      "line": 30,
-      "text": "// 汎用メッセージ取得メソッド、順次検索"
+      "line": 1775,
+      "text": "searchResults: \"関連コンテンツが見つかりました\","
     },
     {
-      "line": 33,
-      "text": "// ステータスメッセージ、エラーメッセージ、ログメッセージの順に検索"
+      "line": 1777,
+      "text": "// VisionModelSelector の缺失翻訳"
     },
     {
-      "line": 43,
-      "text": "// メッセージの取得とフォーマット"
+      "line": 1778,
+      "text": "visionModelSettings: \"ビジョンモデル設定\","
     },
     {
-      "line": 52,
-      "text": "// サポートされている言語リストを取得"
+      "line": 1779,
+      "text": "defaultVisionModel: \"デフォルトビジョンモデル\","
     },
     {
-      "line": 57,
-      "text": "// 言語がサポートされているか確認"
+      "line": 1780,
+      "text": "loadVisionModelFailed: \"ビジョンモデルの読み込みに失敗しました\","
     },
     {
-      "line": 62,
-      "text": "// システムプロンプトを取得"
+      "line": 1781,
+      "text": "loadFailed: \"読み込みに失敗しました、ネットワーク接続を確認してください\","
     },
     {
-      "line": 69,
-      "text": "基于以下知识库内容回答用户问题。"
+      "line": 1782,
+      "text": "saveVisionModelFailed: \"ビジョンモデルの保存に失敗しました\","
     },
     {
-      "line": 71,
-      "text": "**重要提示**: 用户已选择特定知识组,请严格基于以下知识库内容回答。如果知识库中没有相关信息,请明确告知用户:\"${noMatchMsg}\",然后再提供答案。"
+      "line": 1783,
+      "text": "noVisionModels: \"利用可能なビジョンモデルがありません\","
     },
     {
-      "line": 73,
-      "text": "知识库内容:"
+      "line": 1784,
+      "text": "selectVisionModel: \"ビジョンモデルを選択してください\","
     },
     {
-      "line": 76,
-      "text": "历史对话:"
+      "line": 1785,
+      "text": "visionModelHelp: \"画像ファイルを処理するためのビジョンモデル。利用可能なモデルがない場合は、モデル管理でAddedし、「ビジョン対応」オプションをチェックしてください。\","
     },
     {
-      "line": 79,
-      "text": "用户问题:{question}"
+      "line": 1786,
+      "text": "mmErrorNameRequired: \"Model nameは必須要素です\","
     },
     {
-      "line": 81,
-      "text": "请用中文回答,并严格遵循以下 Markdown 格式要求:"
+      "line": 1787,
+      "text": "mmErrorModelIdRequired: \"モデルIDは必須です。\","
     },
     {
-      "line": 83,
-      "text": "1. **段落与结构**:"
+      "line": 1788,
+      "text": "mmErrorBaseUrlRequired: \"選択されたプロバイダーにはBase URLが必要です。\","
     },
     {
-      "line": 84,
-      "text": "- 使用清晰的段落分隔,每个要点之间空一行"
+      "line": 1791,
+      "text": "typeLLM: \"推論 (LLM)\","
     },
     {
-      "line": 85,
-      "text": "- 使用标题(## 或 ###)组织长回答"
+      "line": 1792,
+      "text": "typeEmbedding: \"ベクトル化 (Embedding)\","
     },
     {
-      "line": 87,
-      "text": "2. **文本格式**:"
+      "line": 1793,
+      "text": "typeRerank: \"リランク (Rerank)\","
     },
     {
-      "line": 88,
-      "text": "- 使用 **粗体** 强调重要概念和关键词"
+      "line": 1794,
+      "text": "typeVision: \"画像認識 (Vision)\","
     },
     {
-      "line": 89,
-      "text": "- 使用列表(- 或 1.)组织多个要点"
+      "line": 1796,
+      "text": "welcome: \"こんにちは!設定でモデルを選択し、ドキュメントをアップロードして質問を開始してください。\","
     },
     {
-      "line": 90,
-      "text": "- 使用 \\`代码\\` 标记技术术语、命令、文件名"
+      "line": 1797,
+      "text": "placeholderWithFiles: \"ナレッジベースについて質問...\","
     },
     {
-      "line": 92,
-      "text": "3. **代码展示**:"
+      "line": 1798,
+      "text": "placeholderEmpty: \"開始するにはファイルをアップロード...\","
     },
     {
-      "line": 93,
-      "text": "- 使用代码块展示代码,并指定语言:"
+      "line": 1799,
+      "text": "analyzing: \"検索して生成中...\","
     },
     {
-      "line": 96,
-      "text": "return \"示例\""
+      "line": 1800,
+      "text": "errorGeneric: \"エラーが発生しました。\","
     },
     {
-      "line": 98,
-      "text": "- 支持语言:python, javascript, typescript, java, bash, sql 等"
+      "line": 1801,
+      "text": "errorLabel: \"エラー\","
     },
     {
-      "line": 100,
-      "text": "4. **图表与可视化**:"
+      "line": 1802,
+      "text": "errorNoModel: \"モデルが選択されていないか、設定が無効です。\","
     },
     {
-      "line": 101,
-      "text": "- 使用 Mermaid 语法绘制流程图、序列图等:"
+      "line": 1803,
+      "text": "aiDisclaimer: \"AIは間違いを犯す可能性があります。\","
     },
     {
-      "line": 104,
-      "text": "A[开始] --> B[处理]"
+      "line": 1804,
+      "text": "confirmClear: \"すべてのファイルを削除しますか?\","
     },
     {
-      "line": 105,
-      "text": "B --> C[结束]"
+      "line": 1805,
+      "text": "removeFile: \"ファイルを削除\","
     },
     {
-      "line": 107,
-      "text": "- 适用场景:流程、架构、状态机、时序图"
+      "line": 1806,
+      "text": "apiError: \"設定が不足しているか、APIキーが有効ではありません。\","
     },
     {
-      "line": 109,
-      "text": "5. **其他要求**:"
+      "line": 1808,
+      "text": "processedButNoText: \"応答を生成できませんでした。\","
     },
     {
-      "line": 110,
-      "text": "- 回答精炼准确"
+      "line": 1809,
+      "text": "unitByte: \"バイト\","
     },
     {
-      "line": 111,
-      "text": "- 多步骤操作使用有序列表"
+      "line": 1810,
+      "text": "readingFailed: \"読み込み失敗\","
     },
     {
-      "line": 112,
-      "text": "- 对比类信息建议用表格展示(如果适用)"
+      "line": 1812,
+      "text": "copy: \"コピー\","
     },
     {
-      "line": 114,
-      "text": "作为智能助手,请回答用户的问题。"
+      "line": 1813,
+      "text": "copied: \"コピーしました\","
     },
     {
-      "line": 116,
-      "text": "历史对话:"
+      "line": 1816,
+      "text": "logout: \"ログアウト\","
     },
     {
-      "line": 119,
-      "text": "用户问题:{question}"
+      "line": 1817,
+      "text": "changePassword: \"パスワード変更\","
     },
     {
-      "line": 121,
-      "text": "请用中文回答。"
+      "line": 1818,
+      "text": "userManagement: \"ユーザー管理\","
     },
     {
-      "line": 179,
-      "text": "} else { // 默认为日语,符合项目要求"
+      "line": 1819,
+      "text": "userList: \"ユーザー一覧\","
     },
     {
-      "line": 181,
-      "text": "以下のナレッジベースの内容に基づいてユーザーの質問に答えてください。"
+      "line": 1820,
+      "text": "addUser: \"ユーザーAdded\","
     },
     {
-      "line": 183,
-      "text": "**重要**: ユーザーが特定の知識グループを選択しました。以下のナレッジベースの内容に厳密に基づいて回答してください。ナレッジベースに関連情報がない場合は、「${noMatchMsg}」とユーザーに明示的に伝えてから、回答を提供してください。"
+      "line": 1821,
+      "text": "username: \"ユーザー名\","
     },
     {
-      "line": 185,
-      "text": "ナレッジベースの内容:"
+      "line": 1822,
+      "text": "password: \"パスワード\","
     },
     {
-      "line": 188,
-      "text": "会話履歴:"
+      "line": 1823,
+      "text": "confirmPassword: \"パスワード確認\","
     },
     {
-      "line": 191,
-      "text": "ユーザーの質問:{question}"
+      "line": 1824,
+      "text": "currentPassword: \"現在のパスワード\","
     },
     {
-      "line": 193,
-      "text": "日本語で回答してください。以下の Markdown 書式要件に厳密に従ってください:"
+      "line": 1825,
+      "text": "newPassword: \"新しいパスワード\","
     },
     {
-      "line": 195,
-      "text": "1. **段落と構造**:"
+      "line": 1826,
+      "text": "createUser: \"ユーザー作成\","
     },
     {
-      "line": 196,
-      "text": "- 明確な段落分けを使用し、要点間に空行を入れる"
+      "line": 1827,
+      "text": "admin: \"管理者\","
     },
     {
-      "line": 197,
-      "text": "- 長い回答には見出し(## または ###)を使用"
+      "line": 1828,
+      "text": "user: \"ユーザー\","
     },
     {
-      "line": 199,
-      "text": "2. **テキスト書式**:"
+      "line": 1829,
+      "text": "adminUser: \"管理者として設定\","
     },
     {
-      "line": 200,
-      "text": "- 重要な概念やキーワードを強調するために **太字** を使用"
+      "line": 1830,
+      "text": "confirmChange: \"変更を確定\","
     },
     {
-      "line": 201,
-      "text": "- 複数のポイントを整理するためにリスト(- または 1.)を使用"
+      "line": 1831,
+      "text": "changeUserPassword: \"ユーザーのパスワードを変更\","
     },
     {
-      "line": 202,
-      "text": "- 技術用語、コマンド、ファイル名をマークするために \\`コード\\` を使用"
+      "line": 1832,
+      "text": "enterNewPassword: \"新しいパスワードを入力してください\","
     },
     {
-      "line": 204,
-      "text": "3. **コード表示**:"
+      "line": 1833,
+      "text": "createdAt: \"作成日時\","
     },
     {
-      "line": 205,
-      "text": "- 言語を指定してコードブロックを使用:"
+      "line": 1834,
+      "text": "newChat: \"新しい会話\","
     },
     {
-      "line": 208,
-      "text": "return \"例\""
+      "line": 1837,
+      "text": "kbManagement: \"ナレッジベース管理\","
     },
     {
-      "line": 210,
-      "text": "- 対応言語:python, javascript, typescript, java, bash, sql など"
+      "line": 1838,
+      "text": "kbManagementDesc: \"ドキュメントとナレッジグループの管理\","
     },
     {
-      "line": 212,
-      "text": "4. **図表とチャート**:"
+      "line": 1839,
+      "text": "searchPlaceholder: \"ファイル名を検索...\","
     },
     {
-      "line": 213,
-      "text": "- フローチャート、シーケンス図などに Mermaid 構文を使用:"
+      "line": 1840,
+      "text": "allGroups: \"すべてのグループ\","
     },
     {
-      "line": 216,
-      "text": "A[開始] --> B[処理]"
+      "line": 1841,
+      "text": "allStatus: \"すべてのステータス\","
     },
     {
-      "line": 217,
-      "text": "B --> C[終了]"
+      "line": 1842,
+      "text": "statusReadyFragment: \"完了\","
     },
     {
-      "line": 219,
-      "text": "- 使用例:プロセスフロー、アーキテクチャ図、状態図、シーケンス図"
+      "line": 1843,
+      "text": "statusFailedFragment: \"失敗\","
     },
     {
-      "line": 221,
-      "text": "5. **その他の要件**:"
+      "line": 1844,
+      "text": "statusIndexingFragment: \"インデックス中\","
     },
     {
-      "line": 222,
-      "text": "- 簡潔で明確な回答を心がける"
+      "line": 1845,
+      "text": "uploadFile: \"ファイルをアップロード\","
     },
     {
-      "line": 223,
-      "text": "- 複数のステップがある場合は番号付きリストを使用"
+      "line": 1846,
+      "text": "fileName: \"ファイル名\","
     },
     {
-      "line": 224,
-      "text": "- 比較情報には表を使用(該当する場合)"
+      "line": 1847,
+      "text": "size: \"サイズ\","
     },
     {
-      "line": 226,
-      "text": "インテリジェントアシスタントとして、ユーザーの質問に答えてください。"
+      "line": 1848,
+      "text": "status: \"ステータス\","
     },
     {
-      "line": 228,
-      "text": "会話履歴:"
+      "line": 1849,
+      "text": "groups: \"グループ\","
     },
     {
-      "line": 231,
-      "text": "ユーザーの質問:{question}"
+      "line": 1850,
+      "text": "actions: \"アクション\","
     },
     {
-      "line": 232,
-      "text": "日本語で回答してください。"
+      "line": 1851,
+      "text": "groupsActions: \"グループ / アクション\","
     },
     {
-      "line": 237,
-      "text": "// タイトル生成用のプロンプトを取得"
+      "line": 1852,
+      "text": "noFilesFound: \"ファイルが見つかりません\","
     },
     {
-      "line": 241,
-      "text": "return `你是一个文档分析师。请阅读以下文本(文档开头部分),并生成一个简炼、专业的标题(不超过50个字符)。"
+      "line": 1853,
+      "text": "showingRange: \"$3 件中 $1 - $2 を表示\","
     },
     {
-      "line": 242,
-      "text": "只返回标题文本。不要包含任何解释性文字或前导词(如“标题是:”)。"
+      "line": 1854,
+      "text": "confirmDeleteFile: \"このファイルを削除してもよろしいですか?\","
     },
     {
-      "line": 243,
-      "text": "语言:中文"
+      "line": 1855,
+      "text": "fileDeleted: \"ファイルを削除しました\","
     },
     {
-      "line": 244,
-      "text": "文本内容:"
+      "line": 1856,
+      "text": "deleteFailed: \"削除に失敗しました\","
     },
     {
-      "line": 253,
-      "text": "return `あなたはドキュメントアナライザーです。以下のテキスト(ドキュメントの冒頭部分)を読み、簡潔でプロフェッショナルなタイトル(最大50文字)を生成してください。"
+      "line": 1857,
+      "text": "fileAddedToGroup: \"ファイルがグループにAddedされました\","
     },
     {
-      "line": 254,
-      "text": "タイトルテキストのみを返してください。説明文や前置き(例:「タイトルは:」)は含めないでください。"
+      "line": 1858,
+      "text": "failedToAddToGroup: \"グループへのAddedに失敗しました\","
     },
     {
-      "line": 255,
-      "text": "言語:日本語"
+      "line": 1859,
+      "text": "fileRemovedFromGroup: \"ファイルがグループから削除されました\","
     },
     {
-      "line": 256,
-      "text": "テキスト:"
+      "line": 1860,
+      "text": "failedToRemoveFromGroup: \"グループからの削除に失敗しました\","
     },
     {
-      "line": 264,
-      "text": "return `根据以下对话片段,生成一个简短、描述性的标题(不超过50个字符),总结讨论的主题。"
+      "line": 1861,
+      "text": "confirmClearKB: \"警告:これによりすべてのファイルとインデックスが完全に削除されます。\\n\\n本当にナレッジベースをクリアしますか?\","
     },
     {
-      "line": 265,
-      "text": "只返回标题文本。不要包含任何前导词。"
+      "line": 1862,
+      "text": "kbCleared: \"ナレッジベースをクリアしました\","
     },
     {
-      "line": 266,
-      "text": "语言:中文"
+      "line": 1863,
+      "text": "clearFailed: \"クリアに失敗しました\","
     },
     {
-      "line": 267,
-      "text": "片段:"
+      "line": 1864,
+      "text": "loginRequired: \"先にログインしてください\","
     },
     {
-      "line": 268,
-      "text": "用户: ${userMessage}"
+      "line": 1865,
+      "text": "uploadErrors: \"以下のファイルはアップロードできませんでした\","
     },
     {
-      "line": 269,
-      "text": "助手: ${aiResponse}`;"
+      "line": 1866,
+      "text": "uploadWarning: \"$1 つのファイルがアップロード準備完了、$2 つがフィルタリングされました\","
     },
     {
-      "line": 278,
-      "text": "return `以下の会話スニペットに基づいて、トピックを要約する短く説明的なタイトル(最大50文字)を生成してください。"
+      "line": 1867,
+      "text": "uploadFailed: \"アップロードに失敗しました\","
     },
     {
-      "line": 279,
-      "text": "タイトルのみを返してください。前置きは不要です。"
+      "line": 1868,
+      "text": "preview: \"プレビュー\","
     },
     {
-      "line": 280,
-      "text": "言語:日本語"
+      "line": 1869,
+      "text": "addGroup: \"グループAdded\","
     },
     {
-      "line": 281,
-      "text": "スニペット:"
+      "line": 1870,
+      "text": "delete: \"削除\","
     },
     {
-      "line": 282,
-      "text": "ユーザー: ${userMessage}"
+      "line": 1871,
+      "text": "retry: \"再試行\","
     },
     {
-      "line": 283,
-      "text": "アシスタント: ${aiResponse}`;"
-    }
-  ],
-  "d:\\workspace\\AuraK\\server\\src\\i18n\\messages.ts": [
-    {
-      "line": 3,
-      "text": "noEmbeddingModel: '请先在系统设置中配置嵌入模型',"
+      "line": 1872,
+      "text": "retrying: \"再試行中...\","
     },
     {
-      "line": 4,
-      "text": "searchFailed: '搜索知识库失败,将基于一般知识回答...',"
+      "line": 1873,
+      "text": "retrySuccess: \"再試行成功\","
     },
     {
-      "line": 5,
-      "text": "invalidApiKey: 'API密钥无效',"
+      "line": 1874,
+      "text": "retryFailed: \"再試行失敗\","
     },
     {
-      "line": 6,
-      "text": "fileNotFound: '未找到文件',"
+      "line": 1875,
+      "text": "chunkInfo: \"チャンク情報\","
     },
     {
-      "line": 7,
-      "text": "insufficientQuota: '配额不足',"
+      "line": 1876,
+      "text": "totalChunks: \"総チャンク数\","
     },
     {
-      "line": 8,
-      "text": "modelNotConfigured: '未配置模型',"
+      "line": 1877,
+      "text": "chunkIndex: \"チャンク\","
     },
     {
-      "line": 9,
-      "text": "visionModelNotConfigured: '未配置视觉模型',"
+      "line": 1878,
+      "text": "contentLength: \"文字\","
     },
     {
-      "line": 10,
-      "text": "embeddingDimensionMismatch: '嵌入维度不匹配',"
+      "line": 1879,
+      "text": "position: \"位置\","
     },
     {
-      "line": 11,
-      "text": "uploadNoFile: '未上传文件',"
+      "line": 1882,
+      "text": "reconfigureTitle: \"ファイルの再設定\","
     },
     {
-      "line": 12,
-      "text": "uploadSizeExceeded: '文件大小超过限制: {size}, 最大允许: {max}',"
+      "line": 1883,
+      "text": "reconfigureDesc: \"ファイル処理設定を変更\","
     },
     {
-      "line": 13,
-      "text": "uploadModelRequired: '必须选择嵌入模型',"
+      "line": 1884,
+      "text": "indexingConfigTitle: \"ドキュメントインデックス設定\","
     },
     {
-      "line": 14,
-      "text": "uploadTypeUnsupported: '不支持的文件格式: {type}',"
+      "line": 1885,
+      "text": "indexingConfigDesc: \"ドキュメント処理オプションとモードを設定\","
     },
     {
-      "line": 15,
-      "text": "chunkOverflow: '切片大小 {size} 超过上限 {max} ({reason})。已自动调整',"
+      "line": 1886,
+      "text": "pendingFiles: \"待機中のファイル\","
     },
     {
-      "line": 16,
-      "text": "chunkUnderflow: '切片大小 {size} 小于最小值 {min}。已自动调整',"
+      "line": 1887,
+      "text": "processingMode: \"処理モード\","
     },
     {
-      "line": 17,
-      "text": "overlapOverflow: '重叠大小 {size} 超过上限 {max}。已自动调整',"
+      "line": 1889,
+      "text": "recommendationReason: \"理由\","
     },
     {
-      "line": 18,
-      "text": "overlapUnderflow: '重叠大小 {size} 小于最小值 {min}。已自动调整',"
+      "line": 1891,
+      "text": "fastModeDesc: \"単純なテキスト抽出、Fast、No additional cost、純粋なテキストに適しています\","
     },
     {
-      "line": 19,
-      "text": "overlapRatioExceeded: '重叠大小 {size} 超过切片大小的50% ({max})。已自动调整',"
+      "line": 1893,
+      "text": "preciseModeDesc: \"精密なレイアウト分析、表/画像を保持、APIコストがかかります\","
     },
     {
-      "line": 20,
-      "text": "batchOverflowWarning: '建议切片大小不超过 {safeSize} 以避免批量处理溢出 (当前: {size}, 模型限制的 {percent}%)',"
+      "line": 1894,
+      "text": "fastModeFeatures: \"Fast Modeの特徴:\","
     },
     {
-      "line": 21,
-      "text": "estimatedChunkCountExcessive: '预计切片数量过多 ({count}),处理可能较慢',"
+      "line": 1895,
+      "text": "fastFeature1: \"単純なテキスト抽出\","
     },
     {
-      "line": 22,
-      "text": "contentAndTitleRequired: '内容和标题为必填项',"
+      "line": 1896,
+      "text": "fastFeature2: \"Fastな処理速度\","
     },
     {
-      "line": 23,
-      "text": "embeddingModelNotFound: '找不到嵌入模型 {id} 或类型不是 embedding',"
+      "line": 1898,
+      "text": "fastFeature4: \"テキストのみ処理\","
     },
     {
-      "line": 24,
-      "text": "ocrFailed: '提取文本失败: {message}',"
+      "line": 1899,
+      "text": "fastFeature5: \"プレーンテキストに適しています\","
     },
     {
-      "line": 25,
-      "text": "noImageUploaded: '未上传图片',"
+      "line": 1900,
+      "text": "preciseModeFeatures: \"Precise Modeの特徴:\","
     },
     {
-      "line": 26,
-      "text": "adminOnlyViewList: '只有管理员可以查看用户列表',"
+      "line": 1901,
+      "text": "preciseFeature1: \"精密な構造認識\","
     },
     {
-      "line": 27,
-      "text": "passwordsRequired: '当前密码和新密码不能为空',"
+      "line": 1902,
+      "text": "preciseFeature2: \"画像/表/チャートを認識\","
     },
     {
-      "line": 28,
-      "text": "newPasswordMinLength: '新密码长度不能少于6位',"
+      "line": 1903,
+      "text": "preciseFeature3: \"混合コンテンツを保持\","
     },
     {
-      "line": 29,
-      "text": "adminOnlyCreateUser: '只有管理员可以创建用户',"
+      "line": 1905,
+      "text": "preciseFeature5: \"APIコストが必要\","
     },
     {
-      "line": 30,
-      "text": "usernamePasswordRequired: '用户名和密码不能为空',"
+      "line": 1906,
+      "text": "preciseFeature6: \"処理時間が長くなります\","
     },
     {
-      "line": 31,
-      "text": "passwordMinLength: '密码长度不能少于6位',"
+      "line": 1907,
+      "text": "embeddingModel: \"埋め込みモデル\","
     },
     {
-      "line": 32,
-      "text": "adminOnlyUpdateUser: '只有管理员可以更新用户信息',"
+      "line": 1908,
+      "text": "pleaseSelect: \"選択してください...\","
     },
     {
-      "line": 33,
-      "text": "userNotFound: '用户不存在',"
+      "line": 1909,
+      "text": "pleaseSelectKnowledgeGroupFirst: \"保存する前に知識グループを選択してください\","
     },
     {
-      "line": 34,
-      "text": "cannotModifyBuiltinAdmin: '无法修改内置管理员账户',"
+      "line": 1910,
+      "text": "selectUnassignGroupWarning: \"ナレッジグループの割り当てを解除する場合は、この操作を確認してください\","
     },
     {
-      "line": 35,
-      "text": "adminOnlyDeleteUser: '只有管理员可以删除用户',"
+      "line": 1912,
+      "text": "chunkSize: \"Chunk size (トークン)\","
     },
     {
-      "line": 36,
-      "text": "cannotDeleteSelf: '不能删除自己的账户',"
+      "line": 1913,
+      "text": "min: \"最小\","
     },
     {
-      "line": 37,
-      "text": "cannotDeleteBuiltinAdmin: '无法删除内置管理员账户',"
+      "line": 1914,
+      "text": "max: \"最大\","
     },
     {
-      "line": 38,
-      "text": "incorrectCredentials: '用户名或密码不正确',"
+      "line": 1915,
+      "text": "chunkOverlap: \"オーバーラップ (トークン)\","
     },
     {
-      "line": 39,
-      "text": "incorrectCurrentPassword: '当前密码错误',"
+      "line": 1916,
+      "text": "modelLimitsInfo: \"モデル制限情報\","
     },
     {
-      "line": 40,
-      "text": "usernameExists: '用户名已存在',"
+      "line": 1917,
+      "text": "model: \"モデル\","
     },
     {
-      "line": 41,
-      "text": "noteNotFound: '找不到笔记: {id}',"
+      "line": 1918,
+      "text": "maxChunkSize: \"最大チャンク\","
     },
     {
-      "line": 42,
-      "text": "knowledgeGroupNotFound: '找不到知识组: {id}',"
+      "line": 1919,
+      "text": "maxOverlapSize: \"最大オーバーラップ\","
     },
     {
-      "line": 43,
-      "text": "accessDeniedNoToken: '访问被拒绝:缺少令牌',"
+      "line": 1920,
+      "text": "maxBatchSize: \"最大バッチ\","
     },
     {
-      "line": 44,
-      "text": "invalidToken: '无效的令牌',"
+      "line": 1921,
+      "text": "envLimitWeaker: \"環境制限の方が厳しいです\","
     },
     {
-      "line": 45,
-      "text": "pdfFileNotFound: '找不到 PDF 文件',"
+      "line": 1922,
+      "text": "optimizationTips: \"最適化のヒント\","
     },
     {
-      "line": 46,
-      "text": "pdfFileEmpty: 'PDF 文件为空,转换可能失败',"
+      "line": 1923,
+      "text": "tipChunkTooLarge: \"Chunk sizeが大きいと検索精度に影響する可能性があります\","
     },
     {
-      "line": 47,
-      "text": "pdfConversionFailed: 'PDF 文件不存在或转换失败',"
+      "line": 1924,
+      "text": "tipOverlapSmall: \"オーバーラップは少なくとも $1 トークンを推奨します\","
     },
     {
-      "line": 48,
-      "text": "pdfConversionFailedDetail: 'PDF 转换失败(文件 ID: {id}),请稍后重试',"
+      "line": 1925,
+      "text": "tipMaxValues: \"最大値を使用すると処理が遅くなる可能性があります\","
     },
     {
-      "line": 49,
-      "text": "pdfPreviewNotSupported: '该文件格式不支持预览',"
+      "line": 1926,
+      "text": "tipPreciseCost: \"Precise ModeはAPIコストが発生します。予算を確認してください\","
     },
     {
-      "line": 50,
-      "text": "pdfServiceUnavailable: 'PDF 服务不可用: {message}',"
+      "line": 1927,
+      "text": "selectEmbeddingFirst: \"先に埋め込みモデルを選択してください\","
     },
     {
-      "line": 51,
-      "text": "pageImageNotFound: '找不到页面图像',"
+      "line": 1928,
+      "text": "confirmPreciseCost: \"Precise ModeはAPIコストが発生します。続けますか?\","
     },
     {
-      "line": 52,
-      "text": "pdfPageImageFailed: '无法获取 PDF 页面图像',"
+      "line": 1929,
+      "text": "startProcessing: \"処理開始\","
     },
     {
-      "line": 53,
-      "text": "someGroupsNotFound: '部分组不存在',"
+      "line": 1932,
+      "text": "notebooks: \"ナレッジグループ\","
     },
     {
-      "line": 54,
-      "text": "promptRequired: '提示词是必填项',"
+      "line": 1933,
+      "text": "notebooksDesc: \"研究プロジェクトやナレッジコレクションを管理\","
     },
     {
-      "line": 55,
-      "text": "addLLMConfig: '请在系统设置中添加 LLM 模型',"
+      "line": 1934,
+      "text": "createNotebook: \"新しいナレッジグループ\","
     },
     {
-      "line": 56,
-      "text": "visionAnalysisFailed: '视觉分析失败: {message}',"
+      "line": 1935,
+      "text": "chatWithNotebook: \"このグループとチャット\","
     },
     {
-      "line": 57,
-      "text": "retryMechanismError: '重试机制异常',"
+      "line": 1936,
+      "text": "editNotebook: \"グループを編集\","
     },
     {
-      "line": 58,
-      "text": "imageLoadError: '无法读取图像: {message}',"
+      "line": 1937,
+      "text": "deleteNotebook: \"Delete group (ファイルを含む)\","
     },
     {
-      "line": 59,
-      "text": "groupNotFound: '分组不存在',"
+      "line": 1938,
+      "text": "noDescription: \"説明なし\","
     },
     {
-      "line": 62,
-      "text": "noEmbeddingModel: '先にシステム設定で埋め込みモデルを設定してください',"
+      "line": 1939,
+      "text": "hasIntro: \"紹介あり\","
     },
     {
-      "line": 63,
-      "text": "searchFailed: 'ナレッジベース検索に失敗しました。一般的な知識に基づいて回答します...',"
+      "line": 1940,
+      "text": "noIntro: \"紹介なし\","
     },
     {
-      "line": 64,
-      "text": "invalidApiKey: 'APIキーが無効です',"
+      "line": 1941,
+      "text": "noNotebooks: \"ナレッジグループはまだありません。右上の作成ボタンをクリックしてください\","
     },
     {
-      "line": 65,
-      "text": "fileNotFound: 'ファイルが見つかりません',"
+      "line": 1942,
+      "text": "createFailed: \"作成に失敗しました\","
     },
     {
-      "line": 66,
-      "text": "insufficientQuota: '利用枠が不足しています',"
+      "line": 1943,
+      "text": "confirmDeleteNotebook: \"知識グループ \\\"$1\\\" を削除してもよろしいですか?\\n\\n注意:これにより、この知識グループ内のすべてのファイルとそのインデックスデータも完全に削除されます!\","
     },
     {
-      "line": 67,
-      "text": "modelNotConfigured: 'モデルが設定されていません',"
+      "line": 1946,
+      "text": "errorFileTooLarge: \"ファイルサイズが大きすぎます (20MB以下)\","
     },
     {
-      "line": 68,
-      "text": "visionModelNotConfigured: 'ビジョンモデルが設定されていません',"
+      "line": 1947,
+      "text": "noFilesYet: \"ファイルがありません\","
     },
     {
-      "line": 69,
-      "text": "embeddingDimensionMismatch: '埋め込み次元数が一致しません',"
+      "line": 1950,
+      "text": "createNotebookTitle: \"新しいナレッジグループ\","
     },
     {
-      "line": 70,
-      "text": "uploadNoFile: 'ファイルがアップロードされていません',"
+      "line": 1951,
+      "text": "editNotebookTitle: \"ナレッジグループを編集\","
     },
     {
-      "line": 71,
-      "text": "uploadSizeExceeded: 'ファイルサイズが制限を超えています: {size}, 最大許容: {max}',"
+      "line": 1952,
+      "text": "createFailedRetry: \"作成に失敗しました。再試行してください\","
     },
     {
-      "line": 72,
-      "text": "uploadModelRequired: '埋め込みモデルを選択する必要があります',"
+      "line": 1953,
+      "text": "updateFailedRetry: \"更新に失敗しました。再試行してください\","
     },
     {
-      "line": 73,
-      "text": "uploadTypeUnsupported: 'サポートされていないファイル形式です: {type}',"
+      "line": 1954,
+      "text": "name: \"名前\","
     },
     {
-      "line": 74,
-      "text": "chunkOverflow: 'チャンクサイズ {size} が上限 {max} ({reason}) を超えています。自動調整されました',"
+      "line": 1955,
+      "text": "nameHelp: \"明確な名前を付けると見つけやすくなります。\","
     },
     {
-      "line": 75,
-      "text": "chunkUnderflow: 'チャンクサイズ {size} が最小値 {min} 未満です。自動調整されました',"
+      "line": 1956,
+      "text": "namePlaceholder: \"例: 量子物理学研究...\","
     },
     {
-      "line": 76,
-      "text": "overlapOverflow: '重なりサイズ {size} が上限 {max} を超えています。自動調整されました',"
+      "line": 1957,
+      "text": "shortDescription: \"短い説明\","
     },
     {
-      "line": 77,
-      "text": "overlapUnderflow: '重なりサイズ {size} が最小値 {min} 未満です。自動調整されました',"
+      "line": 1958,
+      "text": "descPlaceholder: \"このグループの目的を一文で説明\","
     },
     {
-      "line": 78,
-      "text": "overlapRatioExceeded: '重なりサイズ {size} がチャンクサイズの50% ({max}) を超えています。自動調整されました',"
+      "line": 1959,
+      "text": "detailedIntro: \"詳細な紹介\","
     },
     {
-      "line": 79,
-      "text": "batchOverflowWarning: 'バッチ処理のオーバーフローを避けるため、チャンクサイズを {safeSize} 以下にすることをお勧めします (現在: {size}, モデル制限の {percent}%)',"
+      "line": 1960,
+      "text": "introPlaceholder: \"ここの段落は、Q&Aのコンテキストに含まれる可能性があります。このグループの主要なトピック、背景知識、または目標をできるだけ詳しく説明してください。\","
     },
     {
-      "line": 80,
-      "text": "estimatedChunkCountExcessive: '推定チャンク数が多すぎます ({count})。処理に時間がかかる可能性があります',"
+      "line": 1961,
+      "text": "introHelp: \"この紹介は、会話のAddedコンテキストとして使用されます。\","
     },
     {
-      "line": 81,
-      "text": "contentAndTitleRequired: '内容とタイトルは必須です',"
+      "line": 1962,
+      "text": "creating: \"作成中...\","
     },
     {
-      "line": 82,
-      "text": "embeddingModelNotFound: '埋め込みモデル {id} が見つかりません、またはタイプが embedding ではありません',"
+      "line": 1963,
+      "text": "createNow: \"今すぐ作成\","
     },
     {
-      "line": 83,
-      "text": "ocrFailed: 'テキストの抽出に失敗しました: {message}',"
+      "line": 1964,
+      "text": "saving: \"保存中...\","
     },
     {
-      "line": 84,
-      "text": "noImageUploaded: '画像がアップロードされていません',"
+      "line": 1965,
+      "text": "save: \"保存\","
     },
     {
-      "line": 85,
-      "text": "adminOnlyViewList: '管理者のみがユーザーリストを表示できます',"
+      "line": 1968,
+      "text": "chatTitle: \"ナレッジベースチャット\","
     },
     {
-      "line": 86,
-      "text": "passwordsRequired: '現在のパスワードと新しいパスワードは必須です',"
+      "line": 1969,
+      "text": "chatDesc: \"ナレッジベースとのスマートな会話\","
     },
     {
-      "line": 87,
-      "text": "newPasswordMinLength: '新しいパスワードは少なくとも6文字以上である必要があります',"
+      "line": 1970,
+      "text": "viewHistory: \"チャット履歴を表示\","
     },
     {
-      "line": 88,
-      "text": "adminOnlyCreateUser: '管理者のみがユーザーを作成できます',"
+      "line": 1971,
+      "text": "saveSettingsFailed: \"設定の保存に失敗しました\","
     },
     {
-      "line": 89,
-      "text": "usernamePasswordRequired: 'ユーザー名とパスワードは必須です',"
+      "line": 1972,
+      "text": "loginToUpload: \"アップロードするにはログインしてください\","
     },
     {
-      "line": 90,
-      "text": "passwordMinLength: 'パスワードは少なくとも6文字以上である必要があります',"
+      "line": 1973,
+      "text": "fileSizeLimitExceeded: \"$1 ($2 - $3MB の制限)\","
     },
     {
-      "line": 91,
-      "text": "adminOnlyUpdateUser: '管理者のみがユーザー情報を更新できます',"
+      "line": 1974,
+      "text": "unsupportedFileType: \"$1 - サポートされていないファイルタイプ ($2)\","
     },
     {
-      "line": 92,
-      "text": "userNotFound: 'ユーザーが見つかりません',"
+      "line": 1975,
+      "text": "readFailed: \"$1 - 読み込みに失敗しました\","
     },
     {
-      "line": 93,
-      "text": "cannotModifyBuiltinAdmin: 'ビルトイン管理者アカウントを変更できません',"
+      "line": 1976,
+      "text": "loadHistoryFailed: \"履歴の読み込みに失敗しました\","
     },
     {
-      "line": 94,
-      "text": "adminOnlyDeleteUser: '管理者のみがユーザーを削除できます',"
+      "line": 1977,
+      "text": "loadingUserData: \"ユーザーデータを読み込み中...\","
     },
     {
-      "line": 95,
-      "text": "cannotDeleteSelf: '自分自身のアカウントを削除できません',"
+      "line": 1978,
+      "text": "errorMessage: \"エラー: $1\","
     },
     {
-      "line": 96,
-      "text": "cannotDeleteBuiltinAdmin: 'ビルトイン管理者アカウントを削除できません',"
+      "line": 1979,
+      "text": "welcomeMessage: \"こんにちは!私はあなたのAIナレッジベースアシスタントです。チャットを開始するにはナレッジグループを選択してください。\","
     },
     {
-      "line": 97,
-      "text": "incorrectCredentials: 'ユーザー名またはパスワードが間違っています',"
+      "line": 1980,
+      "text": "selectKnowledgeGroup: \"ナレッジグループを選択\","
     },
     {
-      "line": 98,
-      "text": "incorrectCurrentPassword: '現在のパスワードが間違っています',"
+      "line": 1981,
+      "text": "allKnowledgeGroups: \"すべてのナレッジグループ\","
     },
     {
-      "line": 99,
-      "text": "usernameExists: 'ユーザー名が既に存在します',"
+      "line": 1982,
+      "text": "unknownGroup: \"不明なグループ\","
     },
     {
-      "line": 100,
-      "text": "noteNotFound: 'ノートが見つかりません: {id}',"
+      "line": 1983,
+      "text": "selectedGroupsCount: \"$1 グループ選択済み\","
     },
     {
-      "line": 101,
-      "text": "knowledgeGroupNotFound: 'ナレッジグループが見つかりません: {id}',"
+      "line": 1986,
+      "text": "generalSettings: \"一般設定\","
     },
     {
-      "line": 102,
-      "text": "accessDeniedNoToken: 'アクセス不許可:トークンがありません',"
+      "line": 1987,
+      "text": "modelManagement: \"モデル管理\","
     },
     {
-      "line": 103,
-      "text": "invalidToken: '無効なトークンです',"
+      "line": 1988,
+      "text": "languageSettings: \"言語設定\","
     },
     {
-      "line": 104,
-      "text": "pdfFileNotFound: 'PDF ファイルが見つかりません',"
+      "line": 1989,
+      "text": "passwordChangeSuccess: \"パスワードを変更しました\","
     },
     {
-      "line": 105,
-      "text": "pdfFileEmpty: 'PDF ファイルが空です。変換に失敗した可能性があります',"
+      "line": 1990,
+      "text": "passwordChangeFailed: \"パスワードの変更に失敗しました\","
     },
     {
-      "line": 106,
-      "text": "pdfConversionFailed: 'PDF ファイルが存在しないか、変換に失敗しました',"
+      "line": 1991,
+      "text": "create: \"作成\","
     },
     {
-      "line": 107,
-      "text": "pdfConversionFailedDetail: 'PDF 変換に失敗しました(ファイル ID: {id})。後でもう一度お試しください',"
+      "line": 1995,
+      "text": "navChat: \"チャット\","
     },
     {
-      "line": 108,
-      "text": "pdfPreviewNotSupported: 'このファイル形式はプレビューをサポートしていません',"
+      "line": 1996,
+      "text": "navCoach: \"コーチ\","
     },
     {
-      "line": 109,
-      "text": "pdfServiceUnavailable: 'PDF サービスを利用できません: {message}',"
+      "line": 1997,
+      "text": "navKnowledge: \"ナレッジベース\","
     },
     {
-      "line": 110,
-      "text": "pageImageNotFound: 'ページ画像が見つかりません',"
+      "line": 1998,
+      "text": "navKnowledgeGroups: \"ナレッジグループ\","
     },
     {
-      "line": 111,
-      "text": "pdfPageImageFailed: 'PDF ページの画像を取得できませんでした',"
+      "line": 1999,
+      "text": "navNotebook: \"ノートブック\","
     },
     {
-      "line": 112,
-      "text": "someGroupsNotFound: '一部のグループが存在しません',"
+      "line": 2000,
+      "text": "navAgent: \"エージェント\","
     },
     {
-      "line": 113,
-      "text": "promptRequired: 'プロンプトは必須です',"
+      "line": 2001,
+      "text": "navPlugin: \"プラグイン\","
     },
     {
-      "line": 114,
-      "text": "addLLMConfig: 'システム設定で LLM モデルを追加してください',"
+      "line": 2002,
+      "text": "navCrawler: \"リソース取得\","
     },
     {
-      "line": 115,
-      "text": "visionAnalysisFailed: 'ビジョン分析に失敗しました: {message}',"
+      "line": 2003,
+      "text": "expandMenu: \"メニューを展開\","
     },
     {
-      "line": 116,
-      "text": "retryMechanismError: '再試行メカニズムの異常',"
+      "line": 2004,
+      "text": "switchLanguage: \"言語を切り替える\","
     },
     {
-      "line": 117,
-      "text": "imageLoadError: '画像を読み込めません: {message}',"
+      "line": 2007,
+      "text": "selectKnowledgeGroups: \"ナレッジグループを選択\","
     },
     {
-      "line": 118,
-      "text": "groupNotFound: 'グループが存在しません',"
+      "line": 2008,
+      "text": "searchGroupsPlaceholder: \"グループを検索...\","
     },
     {
-      "line": 184,
-      "text": "processingFile: '处理文件: {name} ({size})',"
+      "line": 2009,
+      "text": "done: \"完了\","
     },
     {
-      "line": 185,
-      "text": "indexingComplete: '索引完成: {id}',"
+      "line": 2010,
+      "text": "all: \"すべて\","
     },
     {
-      "line": 186,
-      "text": "vectorizingFile: '向量化文件: ',"
+      "line": 2011,
+      "text": "noGroupsFound: \"関連するグループが見つかりません\","
     },
     {
-      "line": 187,
-      "text": "searchQuery: '搜索查询: ',"
+      "line": 2012,
+      "text": "noGroups: \"グループなし\","
     },
     {
-      "line": 188,
-      "text": "modelCall: '[模型调用] 类型: {type}, 模型: {model}, 用户: {user}',"
+      "line": 2015,
+      "text": "autoRefresh: \"自動更新\","
     },
     {
-      "line": 189,
-      "text": "memoryStatus: '内存状态: ',"
+      "line": 2016,
+      "text": "refreshInterval: \"更新間隔\","
     },
     {
-      "line": 190,
-      "text": "uploadSuccess: '文件上传成功。正在后台索引',"
+      "line": 2019,
+      "text": "errorRenderFlowchart: \"フローチャートを生成できません\","
     },
     {
-      "line": 191,
-      "text": "overlapAdjusted: '重叠大小超过切片大小的50%。已自动调整为 {newSize}',"
+      "line": 2020,
+      "text": "errorLoadData: \"データの読み込みに失敗しました\","
     },
     {
-      "line": 192,
-      "text": "environmentLimit: '环境变量限制',"
+      "line": 2021,
+      "text": "confirmUnsupportedFile: \"拡張子 .$1 はサポートされていない可能性があります。続行しますか?\","
     },
     {
-      "line": 193,
-      "text": "modelLimit: '模型限制',"
+      "line": 2022,
+      "text": "errorReadFile: \"ファイルの読み込みに失敗しました: $1\","
     },
     {
-      "line": 194,
-      "text": "configLoaded: '数据库模型配置加载: {name} ({id})',"
+      "line": 2023,
+      "text": "successUploadFile: \"ファイルのアップロードと関連付けに成功しました\","
     },
     {
-      "line": 195,
-      "text": "batchSizeAdjusted: '批量大小从 {old} 调整为 {new} (模型限制: {limit})',"
+      "line": 2024,
+      "text": "errorUploadFile: \"アップロードに失敗しました: $1\","
     },
     {
-      "line": 196,
-      "text": "dimensionMismatch: '模型 {id} 维度不匹配: 预期 {expected}, 实际 {actual}',"
+      "line": 2025,
+      "text": "errorProcessFile: \"ファイルの処理に失敗しました\","
     },
     {
-      "line": 197,
-      "text": "searchMetadataFailed: '为用户 {userId} 搜索知识库失败',"
+      "line": 2026,
+      "text": "errorTitleContentRequired: \"タイトルと内容は必須です\","
     },
     {
-      "line": 198,
-      "text": "extractedTextTooLarge: '抽出されたテキストが大きいです: {size}MB',"
+      "line": 2027,
+      "text": "successNoteUpdated: \"メモを更新しました\","
     },
     {
-      "line": 199,
-      "text": "preciseModeUnsupported: '格式 {ext} 不支持精密模式,回退到快速模式',"
+      "line": 2028,
+      "text": "successNoteCreated: \"メモを作成しました\","
     },
     {
-      "line": 200,
-      "text": "visionModelNotConfiguredFallback: '未配置视觉模型,回退到快速模式',"
+      "line": 2029,
+      "text": "errorSaveFailed: \"保存に失敗しました: $1\","
     },
     {
-      "line": 201,
-      "text": "visionModelInvalidFallback: '视觉模型配置无效,回退到快速模式',"
+      "line": 2030,
+      "text": "confirmDeleteNote: \"このメモを削除してもよろしいですか?\","
     },
     {
-      "line": 202,
-      "text": "visionPipelineFailed: '视觉流水线失败,回退到快速模式',"
+      "line": 2031,
+      "text": "successNoteDeleted: \"メモを削除しました\","
     },
     {
-      "line": 203,
-      "text": "preciseModeComplete: '精密模式提取完成: {pages}页, 费用: ${cost}',"
+      "line": 2032,
+      "text": "confirmRemoveFileFromGroup: \"ファイル「$1」をこのグループから削除しますか?(ナレッジベースには残ります)\","
     },
     {
-      "line": 204,
-      "text": "skippingEmptyVectorPage: '跳过第 {page} 页(空向量)',"
+      "line": 2033,
+      "text": "editNote: \"メモを編集\","
     },
     {
-      "line": 205,
-      "text": "pdfPageImageError: '获取 PDF 页面图像失败: {message}',"
+      "line": 2034,
+      "text": "newNote: \"新規メモ\","
     },
     {
-      "line": 206,
-      "text": "internalServerError: '服务器内部错误',"
+      "line": 2035,
+      "text": "togglePreviewOpen: \"プレビューを表示\","
     },
     {
-      "line": 209,
-      "text": "processingFile: 'ファイル処理中: {name} ({size})',"
+      "line": 2036,
+      "text": "togglePreviewClose: \"プレビューを閉じる\","
     },
     {
-      "line": 210,
-      "text": "indexingComplete: 'インデックス完了: {id}',"
+      "line": 2037,
+      "text": "noteTitlePlaceholder: \"メモのタイトル\","
     },
     {
-      "line": 211,
-      "text": "vectorizingFile: 'ファイルベクトル化中: ',"
+      "line": 2038,
+      "text": "noteContentPlaceholder: \"書き始める (Markdown 対応)...\","
     },
     {
-      "line": 212,
-      "text": "searchQuery: '検索クエリ: ',"
+      "line": 2039,
+      "text": "markdownPreviewArea: \"Markdown プレビューエリア\","
     },
     {
-      "line": 213,
-      "text": "modelCall: '[モデル呼び出し] タイプ: {type}, モデル: {model}, ユーザー: {user}',"
+      "line": 2040,
+      "text": "back: \"戻る\","
     },
     {
-      "line": 214,
-      "text": "memoryStatus: 'メモリ状態: ',"
+      "line": 2041,
+      "text": "chatWithGroup: \"このグループとチャット\","
     },
     {
-      "line": 215,
-      "text": "uploadSuccess: 'ファイルが正常にアップロードされました。バックグラウンドでインデックス処理を実行中です',"
+      "line": 2042,
+      "text": "chatWithFile: \"このファイルとチャット\","
     },
     {
-      "line": 216,
-      "text": "overlapAdjusted: 'オーバーラップサイズがチャンクサイズの50%を超えています。自動的に {newSize} に調整されました',"
+      "line": 2043,
+      "text": "filesCountLabel: \"ファイル ($1)\","
     },
     {
-      "line": 217,
-      "text": "environmentLimit: '環境変数の制限',"
+      "line": 2044,
+      "text": "notesCountLabel: \"メモ ($1)\","
     },
     {
-      "line": 218,
-      "text": "modelLimit: 'モデルの制限',"
+      "line": 2045,
+      "text": "indexIntoKB: \"インデックスに登録\","
     },
     {
-      "line": 219,
-      "text": "configLoaded: 'データベースからモデル設定を読み込みました: {name} ({id})',"
+      "line": 2046,
+      "text": "noFilesOrNotes: \"$1がありません\","
     },
     {
-      "line": 220,
-      "text": "batchSizeAdjusted: 'バッチサイズを {old} から {new} に調整しました (モデル制限: {limit})',"
+      "line": 2047,
+      "text": "importFolder: \"フォルダをインポート\","
     },
     {
-      "line": 221,
-      "text": "dimensionMismatch: 'モデル {id} の次元が一致しません: 期待値 {expected}, 実際 {actual}',"
+      "line": 2051,
+      "text": "screenshotPreview: \"スクリーンショットプレビュー\","
     },
     {
-      "line": 222,
-      "text": "searchMetadataFailed: 'ユーザー {userId} のナレッジベース検索に失敗しました',"
+      "line": 2052,
+      "text": "associateKnowledgeGroup: \"ナレッジグループに関連付ける\","
     },
     {
-      "line": 223,
-      "text": "extractedTextTooLarge: '抽出されたテキストが大きいです: {size}MB',"
+      "line": 2053,
+      "text": "globalNoSpecificGroup: \"全体 (特定のグループなし)\","
     },
     {
-      "line": 224,
-      "text": "preciseModeUnsupported: 'ファイル形式 {ext} は精密モードをサポートしていません。高速モードにフォールバックします',"
+      "line": 2054,
+      "text": "title: \"タイトル\","
     },
     {
-      "line": 225,
-      "text": "visionModelNotConfiguredFallback: 'ビジョンモデルが設定されていません。高速モードにフォールバックします',"
+      "line": 2055,
+      "text": "enterNoteTitle: \"ノートのタイトルを入力\","
     },
     {
-      "line": 226,
-      "text": "visionModelInvalidFallback: 'ビジョンモデルの設定が無効です。高速モードにフォールバックします',"
+      "line": 2056,
+      "text": "contentOCR: \"内容 (OCR抽出されたテキスト)\","
     },
     {
-      "line": 227,
-      "text": "visionPipelineFailed: 'ビジョンパイプラインが失敗しました。高速モードにフォールバックします',"
+      "line": 2057,
+      "text": "extractingText: \"テキストを抽出中...\","
     },
     {
-      "line": 228,
-      "text": "preciseModeComplete: '精密モード内容抽出完了: {pages}ページ, コスト: ${cost}',"
+      "line": 2058,
+      "text": "analyzingImage: \"画像を分析してテキストを抽出中...\","
     },
     {
-      "line": 229,
-      "text": "skippingEmptyVectorPage: '第 {page} ページの空ベクトルをスキップします',"
+      "line": 2059,
+      "text": "noTextExtracted: \"テキストが抽出されませんでした\","
     },
     {
-      "line": 230,
-      "text": "pdfPageImageError: 'PDF ページの画像取得に失敗しました: {message}',"
+      "line": 2060,
+      "text": "saveNote: \"ノートを保存\","
     },
     {
-      "line": 231,
-      "text": "internalServerError: 'サーバー内部エラー',"
+      "line": 2063,
+      "text": "page: \"ページ\","
     },
     {
-      "line": 262,
-      "text": "searching: '正在搜索知识库...',"
+      "line": 2064,
+      "text": "placeholderText: \"OCR抽出されたテキストがここに表示されます。編集できます...\","
     },
     {
-      "line": 263,
-      "text": "noResults: '未找到相关知识,将基于一般知识回答...',"
+      "line": 2067,
+      "text": "createNewNotebook: \"新しいナレッジグループ\","
     },
     {
-      "line": 264,
-      "text": "searchFailed: '知识库搜索失败,将基于一般知识回答...',"
+      "line": 2068,
+      "text": "nameField: \"名前\","
     },
     {
-      "line": 265,
-      "text": "generatingResponse: '正在生成回答',"
+      "line": 2070,
+      "text": "exampleResearch: \"例: 量子物理学研究...\","
     },
     {
-      "line": 266,
-      "text": "files: '个文件',"
+      "line": 2071,
+      "text": "shortDescriptionField: \"簡単な説明\","
     },
     {
-      "line": 267,
-      "text": "notebooks: '个笔记本',"
+      "line": 2072,
+      "text": "describePurpose: \"このグループの目的を一文で説明してください\","
     },
     {
-      "line": 268,
-      "text": "all: '全部',"
+      "line": 2073,
+      "text": "detailedIntroField: \"詳細な紹介\","
     },
     {
-      "line": 269,
-      "text": "items: '个',"
+      "line": 2074,
+      "text": "provideBackgroundInfo: \"詳細な背景、目標、またはコンテキスト情報を提供してください...\","
     },
     {
-      "line": 270,
-      "text": "searchResults: '搜索结果',"
+      "line": 2075,
+      "text": "creationFailed: \"作成に失敗しました。もう一度お試しください\","
     },
     {
-      "line": 271,
-      "text": "relevantInfoFound: '条相关信息找到',"
+      "line": 2078,
+      "text": "preparingPDFConversion: \"PDF変換を準備中...\","
     },
     {
-      "line": 272,
-      "text": "searchHits: '搜索命中',"
+      "line": 2079,
+      "text": "pleaseWait: \"しばらくお待ちください。これには数分かかる場合があります\","
     },
     {
-      "line": 273,
-      "text": "relevance: '相关度',"
+      "line": 2080,
+      "text": "convertingPDF: \"PDFを変換中...\","
     },
     {
-      "line": 274,
-      "text": "sourceFiles: '源文件',"
+      "line": 2081,
+      "text": "pdfConversionFailed: \"PDF変換に失敗しました\","
     },
     {
-      "line": 275,
-      "text": "searchScope: '搜索范围',"
+      "line": 2082,
+      "text": "pdfConversionError: \"このファイルをPDF形式に変換できません。ファイルが破損していないか、サポートされていない形式でないか確認してください\","
     },
     {
-      "line": 276,
-      "text": "error: '错误',"
+      "line": 2083,
+      "text": "pdfLoadFailed: \"PDF読み込みに失敗しました\","
     },
     {
-      "line": 277,
-      "text": "creatingHistory: '创建新对话历史: ',"
+      "line": 2084,
+      "text": "pdfLoadError: \"ブラウザでPDFを表示できません。ダウンロードするか、新しいウィンドウで開いてみてください\","
     },
     {
-      "line": 278,
-      "text": "searchingModelById: '根据ID搜索模型: ',"
+      "line": 2085,
+      "text": "downloadingPDF: \"PDFをダウンロード中...\","
     },
     {
-      "line": 279,
-      "text": "searchModelFallback: '未找到指定的嵌入模型。使用第一个可用模型。',"
+      "line": 2086,
+      "text": "loadingPDF: \"PDFを読み込み中...\","
     },
     {
-      "line": 280,
-      "text": "noEmbeddingModelFound: '找不到嵌入模型设置',"
+      "line": 2087,
+      "text": "zoomOut: \"ズームアウト\","
     },
     {
-      "line": 281,
-      "text": "usingEmbeddingModel: '使用的嵌入模型: ',"
+      "line": 2088,
+      "text": "zoomIn: \"ズームイン\","
     },
     {
-      "line": 282,
-      "text": "startingSearch: '开始搜索知识库...',"
+      "line": 2089,
+      "text": "resetZoom: \"ズームをリセット\","
     },
     {
-      "line": 283,
-      "text": "searchResultsCount: '搜索结果数: ',"
+      "line": 2090,
+      "text": "selectPageNumber: \"Page numberを選択:\","
     },
     {
-      "line": 284,
-      "text": "searchFailedLog: '搜索失败',"
+      "line": 2091,
+      "text": "enterPageNumber: \"選択したいPage numberを入力してください\","
     },
     {
-      "line": 285,
-      "text": "modelCall: '[模型调用]',"
+      "line": 2092,
+      "text": "exitSelectionMode: \"選択モードを終了\","
     },
     {
-      "line": 286,
-      "text": "chatStreamError: '聊天流错误',"
+      "line": 2093,
+      "text": "clickToSelectAndNote: \"クリックして領域を選択し、メモを取る\","
     },
     {
-      "line": 287,
-      "text": "assistStreamError: '辅助流错误',"
+      "line": 2094,
+      "text": "regeneratePDF: \"PDFを再生成\","
     },
     {
-      "line": 288,
-      "text": "file: '文件',"
+      "line": 2095,
+      "text": "downloadPDF: \"PDFをダウンロード\","
     },
     {
-      "line": 289,
-      "text": "content: '内容',"
+      "line": 2096,
+      "text": "openInNewWindow: \"新しいウィンドウで開く\","
     },
     {
-      "line": 290,
-      "text": "userLabel: '用户',"
+      "line": 2097,
+      "text": "exitFullscreen: \"全画面表示を終了\","
     },
     {
-      "line": 291,
-      "text": "assistantLabel: '助手',"
+      "line": 2098,
+      "text": "fullscreenDisplay: \"全画面表示\","
     },
     {
-      "line": 292,
-      "text": "intelligentAssistant: '您是智能写作助手。',"
+      "line": 2099,
+      "text": "pdfPreview: \"PDFプレビュー\","
     },
     {
-      "line": 293,
-      "text": "searchString: '搜索字符串: ',"
+      "line": 2100,
+      "text": "converting: \"変換中...\","
     },
     {
-      "line": 294,
-      "text": "embeddingModelIdNotProvided: '未提供嵌入模型ID',"
+      "line": 2101,
+      "text": "generatePDFPreview: \"PDFプレビューを生成\","
     },
     {
-      "line": 295,
-      "text": "generatingEmbeddings: '生成嵌入向量...',"
+      "line": 2102,
+      "text": "previewNotSupported: \"この形式はプレビューをサポートしていません\","
     },
     {
-      "line": 296,
-      "text": "embeddingsGenerated: '嵌入向量生成完成',"
+      "line": 2105,
+      "text": "confirmRegeneratePDF: \"PDFを再生成してもよろしいですか?これにより現在のプレビューファイルが上書きされます。\","
     },
     {
-      "line": 297,
-      "text": "dimensions: '维度',"
+      "line": 2108,
+      "text": "pdfPreviewReady: \"PDFプレビュー\","
     },
     {
-      "line": 298,
-      "text": "performingHybridSearch: '执行混合搜索...',"
+      "line": 2109,
+      "text": "convertingInProgress: \"変換中...\","
     },
     {
-      "line": 299,
-      "text": "esSearchCompleted: 'ES搜索完成',"
+      "line": 2110,
+      "text": "conversionFailed: \"変換失敗\","
     },
     {
-      "line": 300,
-      "text": "resultsCount: '结果数',"
+      "line": 2111,
+      "text": "generatePDFPreviewButton: \"PDFプレビューを生成\","
     },
     {
-      "line": 301,
-      "text": "hybridSearchFailed: '混合搜索失败',"
+      "line": 2114,
+      "text": "checkPDFStatusFailed: \"PDFステータスの確認に失敗しました\","
     },
     {
-      "line": 302,
-      "text": "getContextForTopicFailed: '获取主题上下文失败',"
+      "line": 2115,
+      "text": "requestRegenerationFailed: \"再生成要求に失敗しました\","
     },
     {
-      "line": 303,
-      "text": "noLLMConfigured: '用户未配置LLM模型',"
+      "line": 2116,
+      "text": "downloadPDFFailed: \"PDFのダウンロードに失敗しました\","
     },
     {
-      "line": 304,
-      "text": "simpleChatGenerationError: '简单聊天生成错误',"
+      "line": 2117,
+      "text": "openPDFInNewTabFailed: \"新しいウィンドウでのPDFオープンに失敗しました\","
     },
     {
-      "line": 305,
-      "text": "noMatchInKnowledgeGroup: '所选知识组中未找到相关内容,以下是基于模型的一般性回答:',"
+      "line": 2120,
+      "text": "invalidFile: \"無効なファイル\","
     },
     {
-      "line": 306,
-      "text": "uploadTextSuccess: '笔记内容已接收。正在后台索引',"
+      "line": 2121,
+      "text": "incompleteFileInfo: \"ファイル情報が不完全です。Fast Modeを使用します\","
     },
     {
-      "line": 307,
-      "text": "passwordChanged: '密码已成功修改',"
+      "line": 2122,
+      "text": "unsupportedFileFormat: \"サポートされていない形式: .$1\","
     },
     {
-      "line": 308,
-      "text": "userCreated: '用户已成功创建',"
+      "line": 2123,
+      "text": "willUseFastMode: \"Fast Mode(テキスト抽出のみ)を使用します\","
     },
     {
-      "line": 309,
-      "text": "userInfoUpdated: '用户信息已更新',"
+      "line": 2124,
+      "text": "formatNoPrecise: \"形式 .$1 はPrecise Modeをサポートしていません\","
     },
     {
-      "line": 310,
-      "text": "userDeleted: '用户已删除',"
+      "line": 2125,
+      "text": "smallFileFastOk: \"ファイルサイズが小さいため、Fast Modeで十分です\","
     },
     {
-      "line": 311,
-      "text": "pdfNoteTitle: 'PDF 笔记 - {date}',"
+      "line": 2126,
+      "text": "mixedContentPreciseRecommended: \"図表などが含まれるため、Precise Modeを推奨します\","
     },
     {
-      "line": 312,
-      "text": "noTextExtracted: '未提取到文本',"
+      "line": 2127,
+      "text": "willIncurApiCost: \"APIコストが発生します\","
     },
     {
-      "line": 313,
-      "text": "kbCleared: '知识库已清空',"
+      "line": 2128,
+      "text": "largeFilePreciseRecommended: \"大きなファイルです。構造保持のためPrecise Modeを推奨します\","
     },
     {
-      "line": 314,
-      "text": "fileDeleted: '文件已删除',"
+      "line": 2129,
+      "text": "longProcessingTime: \"処理に時間がかかる可能性があります\","
     },
     {
-      "line": 315,
-      "text": "pageImageNotFoundDetail: '无法获取 PDF 第 {page} 页’的图像',"
+      "line": 2130,
+      "text": "highApiCost: \"高いAPIコストが発生します\","
     },
     {
-      "line": 316,
-      "text": "groupSyncSuccess: '文件分组已更新',"
+      "line": 2131,
+      "text": "considerFileSplitting: \"ファイルの分割を検討してください\","
     },
     {
-      "line": 317,
-      "text": "fileDeletedFromGroup: '文件已从分组中删除',"
+      "line": 2134,
+      "text": "dragDropUploadTitle: \"File to uploadをドラッグ&ドロップ\","
     },
     {
-      "line": 318,
-      "text": "chunkConfigCorrection: '切片配置已修正: {warnings}',"
+      "line": 2135,
+      "text": "dragDropUploadDesc: \"または下のボタンをクリックしてファイルを選択\","
     },
     {
-      "line": 319,
-      "text": "noChunksGenerated: '文件 {id} 未生成任何切片',"
+      "line": 2136,
+      "text": "supportedFormats: \"対応フォーマット\","
     },
     {
-      "line": 320,
-      "text": "chunkCountAnomaly: '实际切片数 {actual} 大幅超过预计值 {estimated},可能存在异常',"
+      "line": 2137,
+      "text": "browseFiles: \"ファイルを参照\","
     },
     {
-      "line": 321,
-      "text": "batchSizeExceeded: '批次 {index} 的大小 {actual} 超过推荐值 {limit},将拆分处理',"
+      "line": 2140,
+      "text": "recommendationMsg: \"$1モードを推奨します: $2\","
     },
     {
-      "line": 322,
-      "text": "skippingEmptyVectorChunk: '跳过文本块 {index} (空向量)',"
+      "line": 2141,
+      "text": "autoAdjustChunk: \"Chunk sizeを上限の $1 に調整しました\","
     },
     {
-      "line": 323,
-      "text": "contextLengthErrorFallback: '批次处理发生上下文长度错误,降级到逐条处理模式',"
+      "line": 2142,
+      "text": "autoAdjustOverlap: \"重なりサイズを上限の $1 に調整しました\","
     },
     {
-      "line": 324,
-      "text": "chunkLimitExceededForceBatch: '切片数 {actual} 超过模型批次限制 {limit},强制进行批次处理',"
+      "line": 2143,
+      "text": "autoAdjustOverlapMin: \"重なりサイズを最小値の $1 に調整しました\","
     },
     {
-      "line": 325,
-      "text": "noteContentRequired: '笔记内容是必填项',"
+      "line": 2144,
+      "text": "loadLimitsFailed: \"モデル制限の読み込みに失敗しました。デフォルト設定を使用します\","
     },
-    {
-      "line": 326,
-      "text": "imageAnalysisStarted: '正在使用模型 {id} 分析图像...',"
+    {
+      "line": 2145,
+      "text": "maxValueMsg: \"最大値は $1 です\","
     },
     {
-      "line": 327,
-      "text": "batchAnalysisStarted: '正在分析 {count} 张图像...',"
+      "line": 2146,
+      "text": "overlapRatioLimit: \"切片サイズの50% ($1) を超えることはできません\","
     },
     {
-      "line": 328,
-      "text": "pageAnalysisFailed: '第 {page} 页分析失败',"
+      "line": 2147,
+      "text": "onlyAdminCanModify: \"システム設定は管理者のみ変更可能です\","
     },
     {
-      "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": 2148,
+      "text": "dragToSelect: \"マウスをドラッグして範囲を選択 • ESCでキャンセル\","
     },
     {
-      "line": 330,
-      "text": "visionModelCall: '[模型调用] 类型: Vision, 模型: {model}, 页面: {page}',"
+      "line": 2151,
+      "text": "fillTargetName: \"対象のナレッジグループ名を入力してください\","
     },
     {
-      "line": 331,
-      "text": "visionAnalysisSuccess: '✅ 视觉分析完成: {path}{page}, 文本长度: {textLen}, 图像数: {imgCount}, 布局: {layout}, 置信度: {confidence}%',"
+      "line": 2152,
+      "text": "submitFailed: \"送信に失敗しました: $1\","
     },
     {
-      "line": 332,
-      "text": "conversationHistoryNotFound: '对话历史不存在',"
+      "line": 2153,
+      "text": "importFolderTitle: \"ローカルフォルダをインポート\","
     },
     {
-      "line": 333,
-      "text": "batchContextLengthErrorFallback: '小文件批次处理发生上下文长度错误,降级到逐条处理模式',"
+      "line": 2154,
+      "text": "importFolderTip: \"ヒント: ローカルフォルダを選択してください。フォルダ内のすべてのサポートされているドキュメントが読み込まれ、アップロードされます。\","
     },
     {
-      "line": 334,
-      "text": "chunkProcessingFailed: '处理文本块 {index} 失败,已跳过: {message}',"
+      "line": 2155,
+      "text": "lblTargetGroup: \"対象のナレッジグループ名\","
     },
     {
-      "line": 335,
-      "text": "singleTextProcessingComplete: '逐条文本处理完成: {count} 个切片',"
+      "line": 2156,
+      "text": "placeholderNewGroup: \"新規グループ名\","
     },
     {
-      "line": 336,
-      "text": "fileVectorizationComplete: '文件 {id} 向量化完成。共处理 {count} 个文本块。最终内存: {memory}MB',"
+      "line": 2157,
+      "text": "importToCurrentGroup: \"現在のグループにインポートされます\","
     },
     {
-      "line": 337,
-      "text": "fileVectorizationFailed: '文件 {id} 向量化失败',"
+      "line": 2158,
+      "text": "nextStep: \"次へ\","
     },
     {
-      "line": 338,
-      "text": "batchProcessingStarted: '开始批次处理: {count} 个项目',"
+      "line": 2159,
+      "text": "lblImportSource: \"インポート元\","
     },
     {
-      "line": 339,
-      "text": "batchProcessingProgress: '正在处理批次 {index}/{total}: {count} 个项目',"
+      "line": 2160,
+      "text": "serverPath: \"サーバーのパス\","
     },
     {
-      "line": 340,
-      "text": "batchProcessingComplete: '批次处理完成: {count} 个项目,耗时 {duration}s',"
+      "line": 2161,
+      "text": "localFolder: \"ローカルフォルダ\","
     },
     {
-      "line": 341,
-      "text": "onlyFailedFilesRetryable: '仅允许重试失败的文件 (当前状态: {status})',"
+      "line": 2162,
+      "text": "selectedFilesCount: \"$1 個のファイルが選択されました\","
     },
     {
-      "line": 342,
-      "text": "emptyFileRetryFailed: '文件内容为空,无法重试。请重新上传文件。',"
+      "line": 2163,
+      "text": "clickToSelectFolder: \"クリックしてローカルフォルダを選択\","
     },
     {
-      "line": 343,
-      "text": "ragSystemPrompt: '您是专业的知识库助手。请根据以下提供的文档内容回答用户的问题。',"
+      "line": 2164,
+      "text": "selectFolderTip: \"フォルダ内のすべてのサポートされているファイルを読み込みます\","
     },
     {
-      "line": 344,
-      "text": "ragRules: '## 规则:\\n1. 仅根据提供的文档内容进行回答,请勿编造信息。\\n2. 如果文档中没有相关信息,请告知用户。\\n3. 请在回答中注明信息来源。格式:[文件名.扩展子]\\n4. 如果多个文档中的信息存在矛盾,请进行综合分析或解释不同的观点。\\n5. 请使用{lang}进行回答。',"
+      "line": 2165,
+      "text": "importComplete: \"インポート完了\","
     },
     {
-      "line": 345,
-      "text": "ragDocumentContent: '## 文档内容:',"
+      "line": 2166,
+      "text": "importedFromLocalFolder: \"ローカルフォルダからインポート: $1\","
     },
     {
-      "line": 346,
-      "text": "ragUserQuestion: '## 用户问题:',"
+      "line": 2169,
+      "text": "historyTitle: \"会話履歴\","
     },
     {
-      "line": 347,
-      "text": "ragAnswer: '## 回答:',"
+      "line": 2170,
+      "text": "confirmDeleteHistory: \"この会話履歴を削除してもよろしいですか?\","
     },
     {
-      "line": 348,
-      "text": "ragSource: '### 来源:{fileName}',"
+      "line": 2171,
+      "text": "deleteHistorySuccess: \"会話履歴を削除しました\","
     },
     {
-      "line": 349,
-      "text": "ragSegment: '片段 {index} (相似度: {score}):',"
+      "line": 2172,
+      "text": "deleteHistoryFailed: \"会話履歴の削除に失敗しました\","
     },
     {
-      "line": 350,
-      "text": "ragNoDocumentFound: '未找到相关文档。',"
+      "line": 2173,
+      "text": "yesterday: \"昨日\","
     },
     {
-      "line": 351,
-      "text": "queryExpansionPrompt: '您是一个搜索助手。请为以下用户查询生成3个不同的演变版本,以帮助在向量搜索中获得更好的结果。每个版本应包含不同的关键词或表达方式,但保持原始意思。直接输出3行查询,不要有数字或编号:\\n\\n查询:{query}',"
+      "line": 2174,
+      "text": "daysAgo: \"$1日前\","
     },
     {
-      "line": 352,
-      "text": "hydePrompt: '请为以下用户问题写一段简短、事实性的假设回答(约100字)。不要包含任何引导性文字(如“基于我的分析...”),直接输出答案内容。\\n\\n问题:{query}',"
+      "line": 2175,
+      "text": "historyMessages: \"$1 件のメッセージ\","
     },
     {
-      "line": 355,
-      "text": "searching: 'ナレッジベースを検索中...',"
+      "line": 2176,
+      "text": "noHistory: \"会話履歴はありません\","
     },
     {
-      "line": 356,
-      "text": "noResults: '関連する知識が見つかりませんでした。一般的な知識に基づいて回答します...',"
+      "line": 2177,
+      "text": "noHistoryDesc: \"会話を開始して履歴を作成してください\","
     },
     {
-      "line": 357,
-      "text": "searchFailed: 'ナレッジベース検索に失敗しました。一般的な知識に基づいて回答します...',"
+      "line": 2178,
+      "text": "loadMore: \"もっと読み込む\","
     },
     {
-      "line": 358,
-      "text": "generatingResponse: '回答を生成中',"
+      "line": 2179,
+      "text": "loadingHistoriesFailed: \"履歴の読み込みに失敗しました\","
     },
     {
-      "line": 359,
-      "text": "files: '個のファイル',"
+      "line": 2180,
+      "text": "supportedFormatsInfo: \"ドキュメント、画像、ソースコードをサポート\","
     },
     {
-      "line": 360,
-      "text": "notebooks: '個のノートブック',"
+      "line": 2181,
+      "text": "kbSettingsSaved: \"設定を保存しました\","
     },
     {
-      "line": 361,
-      "text": "all: 'すべて',"
+      "line": 2182,
+      "text": "failedToSaveSettings: \"設定の保存に失敗しました\","
     },
     {
-      "line": 362,
-      "text": "items: '件',"
+      "line": 2183,
+      "text": "actionFailed: \"操作に失敗しました\","
     },
     {
-      "line": 363,
-      "text": "searchResults: '検索結果',"
+      "line": 2184,
+      "text": "userAddedToOrganization: \"ユーザーが組織にAddedされました\","
     },
     {
-      "line": 364,
-      "text": "relevantInfoFound: '件の関連情報が見つかりました',"
+      "line": 2185,
+      "text": "featureUpdated: \"機能が更新されました\","
     },
     {
-      "line": 365,
-      "text": "searchHits: '検索ヒット',"
+      "line": 2186,
+      "text": "roleTenantAdmin: \"テナント管理者\","
     },
     {
-      "line": 366,
-      "text": "relevance: '関連度',"
+      "line": 2187,
+      "text": "roleRegularUser: \"一般ユーザー\","
     },
     {
-      "line": 367,
-      "text": "sourceFiles: '元ファイル',"
+      "line": 2188,
+      "text": "creatingRegularUser: \"一般ユーザーを作成中\","
     },
     {
-      "line": 368,
-      "text": "searchScope: '検索範囲',"
+      "line": 2189,
+      "text": "editUserRole: \"ユーザーロールを編集\","
     },
     {
-      "line": 369,
-      "text": "error: 'エラー',"
+      "line": 2190,
+      "text": "targetRole: \"対象のロール\","
     },
     {
-      "line": 370,
-      "text": "creatingHistory: '新規対話履歴を作成: ',"
+      "line": 2191,
+      "text": "editCategory: \"カテゴリを編集\","
     },
     {
-      "line": 371,
-      "text": "searchingModelById: 'selectedEmbeddingId に基づいてモデルを検索: ',"
+      "line": 2192,
+      "text": "totalTenants: \"総テナント数\","
     },
     {
-      "line": 372,
-      "text": "searchModelFallback: '指定された埋め込みモデルが見つかりません。最初に使用可能なモデルを使用します。',"
+      "line": 2193,
+      "text": "systemUsers: \"システムユーザー\","
     },
     {
-      "line": 373,
-      "text": "noEmbeddingModelFound: '埋め込みモデルの設定が見つかりません',"
+      "line": 2194,
+      "text": "systemHealth: \"システムヘルス\","
     },
     {
-      "line": 374,
-      "text": "usingEmbeddingModel: '使用する埋め込みモデル: ',"
+      "line": 2195,
+      "text": "operational: \"正常稼働中\","
     },
     {
-      "line": 375,
-      "text": "startingSearch: 'ナレッジベースの検索を開始...',"
+      "line": 2196,
+      "text": "orgManagement: \"組織管理\","
     },
     {
-      "line": 376,
-      "text": "searchResultsCount: '検索結果数: ',"
+      "line": 2197,
+      "text": "globalTenantControl: \"グローバルテナントコントロール\","
     },
     {
-      "line": 377,
-      "text": "searchFailedLog: '検索失敗',"
+      "line": 2198,
+      "text": "newTenant: \"新規テナント\","
     },
     {
-      "line": 378,
-      "text": "chatStreamError: 'チャットストリームエラー',"
+      "line": 2199,
+      "text": "domainOptional: \"ドメイン (任意)\","
     },
     {
-      "line": 379,
-      "text": "assistStreamError: 'アシストストリームエラー',"
+      "line": 2200,
+      "text": "saveChanges: \"変更を保存\","
     },
     {
-      "line": 380,
-      "text": "file: 'ファイル',"
+      "line": 2201,
+      "text": "modelConfiguration: \"モデル設定\","
     },
     {
-      "line": 381,
-      "text": "content: '内容',"
+      "line": 2202,
+      "text": "defaultLLMModel: \"デフォルト推論モデル\","
     },
     {
-      "line": 382,
-      "text": "userLabel: 'ユーザー',"
+      "line": 2203,
+      "text": "selectLLM: \"LLMを選択\","
     },
     {
-      "line": 383,
-      "text": "assistantLabel: 'アシスタント',"
+      "line": 2204,
+      "text": "selectEmbedding: \"埋め込みを選択\","
     },
     {
-      "line": 384,
-      "text": "intelligentAssistant: 'あなたはインテリジェントな執筆アシスタントです。',"
+      "line": 2205,
+      "text": "rerankModel: \"リランクモデル\","
     },
     {
-      "line": 385,
-      "text": "searchString: '検索文字列: ',"
+      "line": 2206,
+      "text": "none: \"なし\","
     },
     {
-      "line": 386,
-      "text": "embeddingModelIdNotProvided: '埋め込みモデルIDが提供されていません',"
+      "line": 2207,
+      "text": "indexingChunkingConfig: \"インデックスとChunk configuration\","
     },
     {
-      "line": 387,
-      "text": "generatingEmbeddings: '埋め込みベクトルを生成中...',"
+      "line": 2208,
+      "text": "chatHyperparameters: \"チャットハイパーパラメータ\","
     },
     {
-      "line": 388,
-      "text": "embeddingsGenerated: '埋め込みベクトルの生成が完了しました',"
+      "line": 2209,
+      "text": "temperature: \"温度\","
     },
     {
-      "line": 389,
-      "text": "dimensions: '次元数',"
+      "line": 2210,
+      "text": "precise: \"精密\","
     },
     {
-      "line": 390,
-      "text": "performingHybridSearch: 'ES 混合検索を実行中...',"
+      "line": 2211,
+      "text": "creative: \"クリエイティブ\","
     },
     {
-      "line": 391,
-      "text": "esSearchCompleted: 'ES 検索が完了しました',"
+      "line": 2212,
+      "text": "maxResponseTokens: \"最大応答トークン数\","
     },
     {
-      "line": 392,
-      "text": "resultsCount: '結果数',"
+      "line": 2213,
+      "text": "retrievalSearchSettings: \"検索設定\","
     },
     {
-      "line": 393,
-      "text": "hybridSearchFailed: '混合検索に失敗しました',"
+      "line": 2215,
+      "text": "similarityThreshold: \"類似度しきい値\","
     },
     {
-      "line": 394,
-      "text": "getContextForTopicFailed: 'トピックのコンテキスト取得に失敗しました',"
+      "line": 2216,
+      "text": "enableHybridSearch: \"ハイブリッド検索を有効にする\","
     },
     {
-      "line": 395,
-      "text": "noLLMConfigured: 'ユーザーにLLMモデルが設定されていません',"
+      "line": 2217,
+      "text": "hybridSearchDesc: \"ベクトル検索と全文検索を併用して検索精度を向上させます\","
     },
     {
-      "line": 396,
-      "text": "simpleChatGenerationError: '簡易チャット生成エラー',"
+      "line": 2218,
+      "text": "hybridWeight: \"ハイブリッド重み (0.0=全文, 1.0=ベクトル)\","
     },
     {
-      "line": 397,
-      "text": "noMatchInKnowledgeGroup: '選択された知識グループに関連する内容が見つかりませんでした。以下はモデルに基づく一般的な回答です:',"
+      "line": 2219,
+      "text": "pureText: \"純粋なテキスト\","
     },
     {
-      "line": 398,
-      "text": "uploadTextSuccess: 'ノート内容を受け取りました。バックグラウンドでインデックス処理を実行中です',"
+      "line": 2220,
+      "text": "pureVector: \"純粋なベクトル\","
     },
     {
-      "line": 399,
-      "text": "passwordChanged: 'パスワードが正常に変更されました',"
+      "line": 2221,
+      "text": "enableQueryExpansion: \"クエリ拡張を有効にする\","
     },
     {
-      "line": 400,
-      "text": "userCreated: 'ユーザーが正常に作成されました',"
+      "line": 2222,
+      "text": "queryExpansionDesc: \"複数のクエリバリアントを生成してカバレッジを向上させます\","
     },
     {
-      "line": 401,
-      "text": "userInfoUpdated: 'ユーザー情報が更新されました',"
+      "line": 2223,
+      "text": "enableHyDE: \"HyDEを有効にする\","
     },
     {
-      "line": 402,
-      "text": "userDeleted: 'ユーザーが削除されました',"
+      "line": 2224,
+      "text": "hydeDesc: \"仮想的な回答を生成してセマンティック検索を改善します\","
     },
     {
-      "line": 403,
-      "text": "pdfNoteTitle: 'PDF ノート - {date}',"
+      "line": 2225,
+      "text": "enableReranking: \"リランクを有効にする\","
     },
     {
-      "line": 404,
-      "text": "noTextExtracted: 'テキストが抽出されませんでした',"
+      "line": 2226,
+      "text": "rerankingDesc: \"リランクモデルを使用して結果を再ソートします\","
     },
     {
-      "line": 405,
-      "text": "kbCleared: 'ナレッジベースが空になりました',"
+      "line": 2227,
+      "text": "broad: \"広範\","
     },
     {
-      "line": 406,
-      "text": "fileDeleted: 'ファイルが削除されました',"
+      "line": 2228,
+      "text": "strict: \"厳格\","
     },
     {
-      "line": 407,
-      "text": "pageImageNotFoundDetail: 'PDF の第 {page} ページの画像を取得できません',"
+      "line": 2229,
+      "text": "maxInput: \"最大入力\","
     },
     {
-      "line": 408,
-      "text": "groupSyncSuccess: 'ファイルグループが更新されました',"
+      "line": 2230,
+      "text": "dimensions: \"次元\","
     },
     {
-      "line": 409,
-      "text": "fileDeletedFromGroup: 'ファイルがグループから削除されました',"
+      "line": 2231,
+      "text": "defaultBadge: \"デフォルト\","
     },
     {
-      "line": 410,
-      "text": "chunkConfigCorrection: 'チャンク設定の修正: {warnings}',"
+      "line": 2232,
+      "text": "dims: \"次元: $1\","
     },
     {
-      "line": 411,
-      "text": "noChunksGenerated: 'ファイル {id} からテキストチャンクが生成されませんでした',"
+      "line": 2233,
+      "text": "ctx: \"コンテキスト: $1\","
     },
     {
-      "line": 412,
-      "text": "chunkCountAnomaly: '実際のチャンク数 {actual} が推定値 {estimated} を大幅に超えています。異常がある可能性があります',"
+      "line": 2235,
+      "text": "configured: \"設定済み\","
     },
     {
-      "line": 413,
-      "text": "batchSizeExceeded: 'バッチ {index} のサイズ {actual} が推奨値 {limit} を超えています。分割して処理します',"
+      "line": 2236,
+      "text": "groupUpdated: \"グループが更新されました\","
     },
     {
-      "line": 414,
-      "text": "skippingEmptyVectorChunk: '空ベクトルのテキストブロック {index} をスキップします',"
+      "line": 2237,
+      "text": "groupDeleted: \"グループが削除されました\","
     },
     {
-      "line": 415,
-      "text": "contextLengthErrorFallback: 'バッチ処理でコンテキスト長エラーが発生しました。単一テキスト処理モードにダウングレードします',"
+      "line": 2238,
+      "text": "groupCreated: \"グループが作成されました\","
     },
     {
-      "line": 416,
-      "text": "chunkLimitExceededForceBatch: 'チャンク数 {actual} がモデルのバッチ制限 {limit} を超えています。強制的にバッチ処理を行います',"
+      "line": 2239,
+      "text": "navCatalog: \"カタログ\","
     },
     {
-      "line": 417,
-      "text": "noteContentRequired: 'ノート内容は必須です',"
+      "line": 2240,
+      "text": "allDocuments: \"すべてのドキュメント\","
     },
     {
-      "line": 418,
-      "text": "imageAnalysisStarted: 'モデル {id} で画像を分析中...',"
+      "line": 2241,
+      "text": "categories: \"カテゴリ\","
     },
     {
-      "line": 419,
-      "text": "batchAnalysisStarted: '{count} 枚の画像を分析中...',"
+      "line": 2242,
+      "text": "uncategorizedFiles: \"未分類ファイル\","
     },
     {
-      "line": 420,
-      "text": "pageAnalysisFailed: '第 {page} ページの分析に失敗しました',"
+      "line": 2243,
+      "text": "category: \"カテゴリ\","
     },
     {
-      "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": 2244,
+      "text": "statusReadyDesc: \"インデックス済みで検索可能\","
     },
     {
-      "line": 422,
-      "text": "visionModelCall: '[モデル呼び出し] タイプ: Vision, モデル: {model}, ページ: {page}',"
+      "line": 2245,
+      "text": "statusIndexingDesc: \"ベクトルインデックスを作成中\","
     },
     {
-      "line": 423,
-      "text": "visionAnalysisSuccess: '✅ Vision 分析完了: {path}{page}, テキスト長: {textLen}文字, 画像数: {imgCount}, レイアウト: {layout}, 信頼度: {confidence}%',"
+      "line": 2246,
+      "text": "selectCategory: \"カテゴリを選択\","
     },
     {
-      "line": 424,
-      "text": "conversationHistoryNotFound: '会話履歴が存在しません',"
+      "line": 2247,
+      "text": "noneUncategorized: \"未分類ファイルなし\","
     },
     {
-      "line": 425,
-      "text": "batchContextLengthErrorFallback: '小ファイルバッチ処理でコンテキスト長エラーが発生しました。単一テキスト処理モードにダウングレードします',"
+      "line": 2248,
+      "text": "previous: \"前へ\","
     },
     {
-      "line": 426,
-      "text": "chunkProcessingFailed: 'テキストブロック {index} の処理に失敗しました。スキップします: {message}',"
+      "line": 2249,
+      "text": "next: \"次へ\","
     },
     {
-      "line": 427,
-      "text": "singleTextProcessingComplete: '単一テキスト処理完了: {count} チャンク',"
+      "line": 2250,
+      "text": "createCategory: \"カテゴリを作成\","
     },
     {
-      "line": 428,
-      "text": "fileVectorizationComplete: 'ファイル {id} ベクトル化完了。{count} 個のテキストブロックを処理しました。最終メモリ: {memory}MB',"
+      "line": 2251,
+      "text": "categoryDesc: \"ナレッジカテゴリを説明します\","
     },
     {
-      "line": 429,
-      "text": "fileVectorizationFailed: 'ファイル {id} ベクトル化失敗',"
+      "line": 2252,
+      "text": "categoryName: \"カテゴリ名\","
     },
     {
-      "line": 430,
-      "text": "batchProcessingStarted: 'バッチ処理を開始します: {count} アイテム',"
+      "line": 2253,
+      "text": "createCategoryBtn: \"今すぐ作成\","
     },
     {
-      "line": 431,
-      "text": "batchProcessingProgress: 'バッチ {index}/{total} を処理中: {count} 個のアイテム',"
+      "line": 2254,
+      "text": "newGroup: \"新規グループ\","
     },
     {
-      "line": 432,
-      "text": "batchProcessingComplete: 'バッチ処理完了: {count} アイテム, 所要時間 {duration}s',"
+      "line": 2255,
+      "text": "noKnowledgeGroups: \"ナレッジグループがまだありません\","
     },
     {
-      "line": 433,
-      "text": "onlyFailedFilesRetryable: '失敗したファイルのみ再試行可能です (現在のステータス: {status})',"
+      "line": 2256,
+      "text": "createGroupDesc: \"最初のナレッジCreate groupしてドキュメントをアップロードしてください。\","
     },
     {
-      "line": 434,
-      "text": "emptyFileRetryFailed: 'ファイル内容が空です。再試行できません。ファイルを再アップロードしてください。',"
+      "line": 2257,
+      "text": "noDescriptionProvided: \"説明なし\","
     },
     {
-      "line": 435,
-      "text": "ragSystemPrompt: 'あなたは専門的なナレッジベースアシスタントです。以下の提供されたドキュメントの内容に基づいて、ユーザーの質問に答えてください。',"
+      "line": 2258,
+      "text": "browseManageFiles: \"このグループ内のファイルとメモを閲覧・管理します。\","
     },
     {
-      "line": 436,
-      "text": "ragRules: '## ルール:\\n1. 提供されたドキュメントの内容のみに基づいて回答し、情報を捏造しないでください。\\n2. ドキュメントに関連情報がない場合は、その旨をユーザーに伝えてください。\\n3. 回答には情報源を明記してください。形式:[ファイル名.拡張子]\\n4. 複数のドキュメントで情報が矛盾している場合は、総合的に分析するか、異なる視点を説明してください。\\n5. {lang}で回答してください。',"
+      "line": 2259,
+      "text": "filterGroupFiles: \"名前でグループ内のファイルを検索...\","
     },
     {
-      "line": 437,
-      "text": "ragDocumentContent: '## ドキュメント内容:',"
+      "line": 2260,
+      "text": "generalSettingsSubtitle: \"アプリケーションの設定を管理します。\","
     },
     {
-      "line": 438,
-      "text": "ragUserQuestion: '## ユーザーの質問:',"
+      "line": 2261,
+      "text": "userManagementSubtitle: \"アクセス権限とアカウントを管理します。\","
     },
     {
-      "line": 439,
-      "text": "ragAnswer: '## 回答:',"
+      "line": 2262,
+      "text": "modelManagementSubtitle: \"グローバルなAIモデルを設定します。\","
     },
     {
-      "line": 440,
-      "text": "ragSource: '### ソース:{fileName}',"
+      "line": 2263,
+      "text": "kbSettingsSubtitle: \"インデックス作成とチャットパラメータの技術設定。\","
     },
     {
-      "line": 441,
-      "text": "ragSegment: 'セグメント {index} (類似度: {score}):',"
+      "line": 2264,
+      "text": "tenantsSubtitle: \"グローバルシステムの概要。\","
     },
     {
-      "line": 442,
-      "text": "ragNoDocumentFound: '関連するドキュメントが見つかりませんでした。',"
+      "line": 2265,
+      "text": "allNotes: \"すべてのノート\","
     },
     {
-      "line": 443,
-      "text": "queryExpansionPrompt: 'あなたは検索アシスタントです。以下のユーザーのクエリに対して、ベクトル検索でより良い結果を得るために、3つの異なるバリエーションを生成してください。各バリエーションは異なるキーワードや表現を使用しつつ、元の意味を維持する必要があります。数字やプレフィックスなしで、3行のクエリを直接出力してください:\\n\\nクエリ:{query}',"
+      "line": 2266,
+      "text": "filterNotesPlaceholder: \"ノートをフィルタリング...\","
     },
     {
-      "line": 444,
-      "text": "hydePrompt: '以下のユーザーの質問に対して、簡潔で事実に基づいた仮説的な回答(約200文字)を書いてください。「私の分析によると...」などの導入文は含めず、回答内容のみを直接出力してください。\\n\\n質問:{query}',"
-    }
-  ],
-  "d:\\workspace\\AuraK\\server\\src\\knowledge-base\\chunk-config.service.ts": [
+      "line": 2267,
+      "text": "startWritingPlaceholder: \"書き始める...\","
+    },
     {
-      "line": 8,
-      "text": "* チャンク設定サービス"
+      "line": 2268,
+      "text": "previewHeader: \"プレビュー\","
     },
     {
-      "line": 9,
-      "text": "* チャンクパラメータの検証と管理を担当し、モデルの制限や環境変数の設定に適合していることを確認します"
+      "line": 2269,
+      "text": "noContentToPreview: \"プレビューするコンテンツがありません\","
     },
     {
-      "line": 11,
-      "text": "* 制限の優先順位:"
+      "line": 2270,
+      "text": "hidePreview: \"プレビューを非表示\","
     },
     {
-      "line": 12,
-      "text": "* 1. 環境変数 (MAX_CHUNK_SIZE, MAX_OVERLAP_SIZE)"
+      "line": 2271,
+      "text": "showPreview: \"プレビューを表示\","
     },
     {
-      "line": 13,
-      "text": "* 2. データベース内のモデル設定 (maxInputTokens, maxBatchSize)"
+      "line": 2272,
+      "text": "directoryLabel: \"ディレクトリ\","
     },
     {
-      "line": 14,
-      "text": "* 3. デフォルト値"
+      "line": 2273,
+      "text": "uncategorized: \"未分類\","
     },
     {
-      "line": 31,
-      "text": "// デフォルト設定"
+      "line": 2274,
+      "text": "enterNamePlaceholder: \"名前を入力...\","
     },
     {
-      "line": 37,
-      "text": "maxOverlapRatio: DEFAULT_MAX_OVERLAP_RATIO,  // 重なりはチャンクサイズの50%まで"
+      "line": 2275,
+      "text": "subFolderPlaceholder: \"サブフォルダ...\","
     },
     {
-      "line": 38,
-      "text": "maxBatchSize: DEFAULT_MAX_BATCH_SIZE,    // デフォルトのバッチ制限"
+      "line": 2276,
+      "text": "categoryCreated: \"カテゴリが作成されました\","
     },
     {
-      "line": 39,
-      "text": "expectedDimensions: DEFAULT_VECTOR_DIMENSIONS, // デフォルトのベクトル次元"
+      "line": 2277,
+      "text": "failedToCreateCategory: \"カテゴリの作成に失敗しました\","
     },
     {
-      "line": 42,
-      "text": "// 環境変数で設定された上限(優先的に使用)"
+      "line": 2278,
+      "text": "failedToDeleteCategory: \"カテゴリの削除に失敗しました\","
     },
     {
-      "line": 53,
-      "text": "// 環境変数からグローバルな上限設定を読み込む"
+      "line": 2279,
+      "text": "confirmDeleteCategory: \"このカテゴリを削除してもよろしいですか?\","
     },
     {
-      "line": 67,
-      "text": "* モデルの制限設定を取得(データベースから読み込み)"
+      "line": 2283,
+      "text": "agentTitle: \"エージェントセンター\","
     },
     {
-      "line": 82,
-      "text": "// データベースのフィールドから制限を取得し、デフォルト値で補完"
+      "line": 2284,
+      "text": "agentDesc: \"複雑なタスクを支援する AI アシスタントを管理および実行します。\","
     },
     {
-      "line": 86,
-      "text": "const providerName = modelConfig.providerName || '不明';"
+      "line": 2285,
+      "text": "createAgent: \"エージェント作成\","
     },
     {
-      "line": 91,
-      "text": "`  - プロバイダー: ${providerName}\\n` +"
+      "line": 2286,
+      "text": "searchAgent: \"エージェントを検索...\","
     },
     {
-      "line": 92,
-      "text": "`  - Token制限: ${maxInputTokens}\\n` +"
+      "line": 2287,
+      "text": "statusRunning: \"実行中\","
     },
     {
-      "line": 93,
-      "text": "`  - バッチ制限: ${maxBatchSize}\\n` +"
+      "line": 2288,
+      "text": "statusStopped: \"停止中\","
     },
     {
-      "line": 94,
-      "text": "`  - ベクトル次元: ${expectedDimensions}\\n` +"
+      "line": 2289,
+      "text": "updatedAtPrefix: \"最終更新日: \","
     },
     {
-      "line": 95,
-      "text": "`  - ベクトルモデルか: ${isVectorModel}`,"
+      "line": 2290,
+      "text": "btnChat: \"会話を開始\","
     },
     {
-      "line": 108,
-      "text": "* チャンク設定を検証および修正"
+      "line": 2293,
+      "text": "agent1Name: \"データ分析エキスパート\","
     },
     {
-      "line": 109,
-      "text": "* 優先順位: 環境変数の上限 > モデルの制限 > ユーザー設定"
+      "line": 2294,
+      "text": "agent1Desc: \"SQL とデータ視覚化に精通し、複雑なデータから洞察を抽出できます。\","
     },
     {
-      "line": 127,
-      "text": "// 1. 最終的な上限を計算(環境変数とモデル制限の小さい方を選択)"
+      "line": 2295,
+      "text": "agent2Name: \"コードレビュー助手\","
     },
     {
-      "line": 138,
-      "text": "// 2. チャンクサイズの上限を検証"
+      "line": 2296,
+      "text": "agent2Desc: \"コードの品質を自動的にチェックし、リファクタリングの提案やパフォーマンス最適化案を提供します。\","
     },
     {
-      "line": 155,
-      "text": "// 3. チャンクサイズの下限を検証"
+      "line": 2297,
+      "text": "agent3Name: \"学術論文校閲\","
     },
     {
-      "line": 166,
-      "text": "// 4. 重なりサイズの上限を検証(環境変数優先)"
+      "line": 2298,
+      "text": "agent3Desc: \"専門的な学術ライティングアシスタント。論文の構成と表現の最適化を支援します。\","
     },
     {
-      "line": 177,
-      "text": "// 5. 重なりサイズがチャンクサイズの50%を超えないことを検証"
+      "line": 2299,
+      "text": "agent4Name: \"法律顧問\","
     },
     {
-      "line": 201,
-      "text": "// 6. バッチ処理の安全チェックを追加"
+      "line": 2300,
+      "text": "agent4Desc: \"法律条文の検索や基本的な法的アドバイスを提供し、契約書の作成を支援します。\","
     },
     {
-      "line": 202,
-      "text": "// バッチ処理時、複数のテキストの合計長がモデルの制限を超えないようにする必要があります"
+      "line": 2301,
+      "text": "agent5Name: \"市場調査員\","
     },
     {
-      "line": 203,
-      "text": "const safetyMargin = 0.8; // 80% 安全マージン、バッチ処理のためにスペースを確保"
+      "line": 2302,
+      "text": "agent5Desc: \"業界のトレンドを分析し、競合他社の調査レポートを生成します。\","
     },
     {
-      "line": 216,
-      "text": "// 7. 推定チャンク数が妥当かチェック"
+      "line": 2303,
+      "text": "agent6Name: \"システム運用保守エキスパート\","
     },
     {
-      "line": 218,
-      "text": "1000000, // 1MB のテキストを想定"
+      "line": 2304,
+      "text": "agent6Desc: \"システムの健康状態を監視し、一般的なアラートへの対応やトラブルシューティングを自動化します。\","
     },
     {
-      "line": 238,
-      "text": "* 推奨されるバッチサイズを取得"
+      "line": 2305,
+      "text": "agent7Name: \"財務監査人\","
     },
     {
-      "line": 248,
-      "text": "// 設定値とモデル制限の小さい方を選択"
+      "line": 2306,
+      "text": "agent7Desc: \"レポート監査を自動化し、財務リスクや異常な取引を特定します。\","
     },
     {
-      "line": 252,
-      "text": "200, // 安全のための上限"
+      "line": 2307,
+      "text": "agent1Time: \"2 時間前\","
     },
     {
-      "line": 265,
-      "text": "return Math.max(10, recommended); // 最低10個"
+      "line": 2308,
+      "text": "agent2Time: \"5 時間前\","
     },
     {
-      "line": 269,
-      "text": "* チャンク数を推定"
+      "line": 2309,
+      "text": "agent3Time: \"昨日\","
     },
     {
-      "line": 277,
-      "text": "* ベクトル次元の検証"
+      "line": 2310,
+      "text": "agent4Time: \"2 日前\","
     },
     {
-      "line": 302,
-      "text": "* 設定概要を取得(ログ用)"
+      "line": 2311,
+      "text": "agent5Time: \"3 日前\","
     },
     {
-      "line": 314,
-      "text": "`モデル: ${modelId}`,"
+      "line": 2312,
+      "text": "agent6Time: \"5 日前\","
     },
     {
-      "line": 315,
-      "text": "`チャンクサイズ: ${chunkSize} tokens (制限: ${limits.maxInputTokens})`,"
+      "line": 2313,
+      "text": "agent7Time: \"1 週間前\","
     },
     {
-      "line": 316,
-      "text": "`重なりサイズ: ${chunkOverlap} tokens`,"
+      "line": 2316,
+      "text": "pluginTitle: \"プラグインストア\","
     },
     {
-      "line": 317,
-      "text": "`バッチサイズ: ${limits.maxBatchSize}`,"
+      "line": 2317,
+      "text": "pluginDesc: \"外部ツールやサービスを統合して、ナレッジベースの機能を拡張します。\","
     },
     {
-      "line": 318,
-      "text": "`ベクトル次元: ${limits.expectedDimensions}`,"
+      "line": 2318,
+      "text": "searchPlugin: \"プラグインを検索...\","
     },
     {
-      "line": 323,
-      "text": "* フロントエンド用の設定制限を取得"
+      "line": 2319,
+      "text": "installPlugin: \"インストール\","
     },
     {
-      "line": 324,
-      "text": "* フロントエンドのスライダーの上限設定に使用"
+      "line": 2320,
+      "text": "installedPlugin: \"インストール済み\","
     },
     {
-      "line": 345,
-      "text": "// 最終的な上限を計算(環境変数とモデル制限の小さい方を選択)"
+      "line": 2321,
+      "text": "updatePlugin: \"アップデートあり\","
     },
     {
-      "line": 352,
-      "text": "// モデル設定名を取得"
+      "line": 2322,
+      "text": "pluginOfficial: \"公式\","
     },
     {
-      "line": 356,
-      "text": "// テナントまたはユーザー設定からデフォルト値を取得"
-    }
-  ],
-  "d:\\workspace\\AuraK\\server\\src\\knowledge-base\\embedding.service.ts": [
-    {
-      "line": 46,
-      "text": "throw new Error(`埋め込みモデル設定 ${embeddingModelConfigId} が見つかりません`);"
+      "line": 2323,
+      "text": "pluginCommunity: \"コミュニティ\","
     },
     {
-      "line": 50,
-      "text": "throw new Error(`モデル ${modelConfig.name} は無効化されているため、埋め込みベクトルを生成できません`);"
+      "line": 2324,
+      "text": "pluginBy: \"開発者: \","
     },
     {
-      "line": 53,
-      "text": "// APIキーはオプションです - ローカルモデルを許可します"
+      "line": 2325,
+      "text": "pluginConfig: \"設定\","
     },
     {
-      "line": 56,
-      "text": "throw new Error(`モデル ${modelConfig.name} に baseUrl が設定されていません`);"
+      "line": 2328,
+      "text": "plugin1Name: \"Web 検索\","
     },
     {
-      "line": 59,
-      "text": "// モデル名に基づいて最大バッチサイズを決定"
+      "line": 2329,
+      "text": "plugin1Desc: \"最新情報を取得するために、AI にインターネットへのリアルタイムアクセスを提供します。\","
     },
     {
-      "line": 62,
-      "text": "// バッチサイズが制限を超える場合は分割して処理"
+      "line": 2330,
+      "text": "plugin2Name: \"PDF ドキュメント解析\","
     },
     {
-      "line": 81,
-      "text": "// APIレート制限対策のため、短い間隔で待機"
+      "line": 2331,
+      "text": "plugin2Desc: \"複雑な PDF レイアウトを詳細に解析し、表や数式を抽出します。\","
     },
     {
-      "line": 83,
-      "text": "await new Promise(resolve => setTimeout(resolve, 100)); // 100ms待機"
+      "line": 2332,
+      "text": "plugin3Name: \"GitHub 連携\","
     },
     {
-      "line": 89,
-      "text": "// 通常処理(バッチサイズ以内)"
+      "line": 2333,
+      "text": "plugin3Desc: \"GitHub リポジトリに直接アクセスし、コードのコミットやイシュー管理を行います。\","
     },
     {
-      "line": 100,
-      "text": "* モデルIDに基づいて最大バッチサイズを決定"
+      "line": 2334,
+      "text": "plugin4Name: \"Google カレンダー\","
     },
     {
-      "line": 103,
-      "text": "// モデル固有のバッチサイズ制限"
+      "line": 2335,
+      "text": "plugin4Desc: \"スケジュールを同期し、会議のリマインダーを自動的に作成します。\","
     },
     {
-      "line": 106,
-      "text": "return Math.min(10, configuredMaxBatchSize || 100); // Googleの場合は10を上限"
+      "line": 2336,
+      "text": "plugin5Name: \"SQL データベース接続\","
     },
     {
-      "line": 108,
-      "text": "return Math.min(2048, configuredMaxBatchSize || 2048); // OpenAI v3は2048が上限"
+      "line": 2337,
+      "text": "plugin5Desc: \"データベースに安全に接続し、自然語言でクエリを実行します。\","
     },
     {
-      "line": 110,
-      "text": "// デフォルトでは設定された最大バッチサイズか100の小さい方"
+      "line": 2338,
+      "text": "plugin6Name: \"Slack 通知\","
     },
     {
-      "line": 116,
-      "text": "* 単一バッチの埋め込み処理"
+      "line": 2339,
+      "text": "plugin6Desc: \"AI が生成したレポートを指定された Slack チャンネルに直接送信します。\","
     },
     {
-      "line": 164,
-      "text": "// バッチサイズ制限エラーを検出"
+      "line": 2341,
+      "text": "navTenants: \"テナント管理\","
     },
     {
-      "line": 171,
-      "text": "// バッチをさらに小さな単位に分割して再試行"
+      "line": 2342,
+      "text": "noNotesFound: \"ノートが見つかりません\","
     },
     {
-      "line": 184,
-      "text": "// コンテキスト長の過剰エラーを検出"
+      "line": 2343,
+      "text": "notebookDesc: \"ノートブックは知識の整理と要約に役立ちます。\","
     },
     {
-      "line": 190,
-      "text": "`総計 ${totalLength} 文字、平均 ${Math.round(avgLength)} 文字、` +"
+      "line": 2344,
+      "text": "personalNotebook: \"個人用ノートブック\","
     },
     {
-      "line": 191,
-      "text": "`モデル制限: ${modelConfig.maxInputTokens || 8192} tokens`"
+      "line": 2345,
+      "text": "warning: \"警告\","
     },
     {
-      "line": 194,
-      "text": "`テキスト長がモデルの制限を超えています。` +"
+      "line": 2346,
+      "text": "\"x-api-key\": \"APIキー\","
     },
     {
-      "line": 195,
-      "text": "`現在: ${texts.length} 個のテキストで計 ${totalLength} 文字、` +"
+      "line": 2347,
+      "text": "\"x-tenant-id\": \"テナントID\","
     },
     {
-      "line": 196,
-      "text": "`モデル制限: ${modelConfig.maxInputTokens || 8192} tokens。` +"
+      "line": 2348,
+      "text": "\"x-user-language\": \"ユーザー言語\","
     },
     {
-      "line": 197,
-      "text": "`アドバイス: チャンクサイズまたはバッチサイズを小さくしてください`"
+      "line": 2351,
+      "text": "addSubcategory: \"サブカテゴリをAdded\","
     },
     {
-      "line": 201,
-      "text": "// 429 (Too Many Requests) または 5xx (Server Error) の場合は再試行"
+      "line": 2352,
+      "text": "parentCategory: \"親カテゴリ(任意)\","
     },
     {
-      "line": 208,
-      "text": "this.logger.error(`リクエストパラメータ: model=${modelConfig.modelId}, inputLength=${texts[0]?.length}`);"
+      "line": 2353,
+      "text": "noParentTopLevel: \"なし(トップレベル)\","
     },
     {
-      "line": 209,
-      "text": "throw new Error(`埋め込み API の呼び出しに失敗しました: ${response.statusText} - ${errorText}`);"
+      "line": 2354,
+      "text": "useHierarchyImport: \"フォルダ階層でカテゴリを作成\","
     },
     {
-      "line": 215,
-      "text": "// 実際のレスポンスから次元を取得"
+      "line": 2355,
+      "text": "useHierarchyImportDesc: \"有効にすると、各サブフォルダにサブカテゴリが作成され、ファイルが対応するカテゴリにインポートされます。\","
     },
     {
-      "line": 225,
-      "text": "// 最後のアテンプトでなく、エラーが一時的と思われる場合(または堅牢性のために全て)は、待機後に再試行"
+      "line": 2358,
+      "text": "importImmediate: \"今すぐインポート\","
     },
     {
-      "line": 239,
-      "text": "// 使用环境变量的默认维度"
-    }
-  ],
-  "d:\\workspace\\AuraK\\server\\src\\knowledge-base\\knowledge-base.controller.ts": [
-    {
-      "line": 134,
-      "text": "* チャンク設定の制限を取得(フロントエンドのスライダー設定用)"
+      "line": 2359,
+      "text": "importScheduled: \"スケジュールインポート\","
     },
     {
-      "line": 135,
-      "text": "* クエリパラメータ: embeddingModelId - 埋め込みモデルID"
+      "line": 2360,
+      "text": "lblServerPath: \"サーバーフォルダパス\","
     },
     {
-      "line": 165,
-      "text": "// 文件分组管理 - 需要管理员权限"
+      "line": 2361,
+      "text": "placeholderServerPath: \"例: /data/documents\","
     },
     {
-      "line": 198,
-      "text": "// PDF プレビュー - 公開アクセス"
+      "line": 2362,
+      "text": "scheduledImportTip: \"サーバー側のスケジュールインポート:指定した時刻にサーバーがパスのファイルを読み込んで自動インポートします。サーバーがそのパスにアクセスできることを確認してください。\","
     },
     {
-      "line": 247,
-      "text": "fs.unlinkSync(pdfPath); // 空のファイルを削除"
+      "line": 2363,
+      "text": "lblScheduledTime: \"実行日時\","
     },
     {
-      "line": 266,
-      "text": "// PDF プレビューアドレスを取得"
+      "line": 2364,
+      "text": "scheduledTimeHint: \"指定した時刻に、サーバーが自動的にインポートタスクを実行します。\","
     },
     {
-      "line": 274,
-      "text": "// PDF 変換をトリガー"
+      "line": 2365,
+      "text": "scheduleImport: \"スケジュールタスクを作成\","
     },
     {
-      "line": 277,
-      "text": "// 一時的なアクセストークンを生成"
+      "line": 2366,
+      "text": "scheduleTaskCreated: \"スケジュールインポートタスクが作成されました\","
     },
     {
-      "line": 310,
-      "text": "// PDF の特定ページの画像を取得"
-    }
-  ],
-  "d:\\workspace\\AuraK\\server\\src\\knowledge-base\\knowledge-base.entity.ts": [
-    {
-      "line": 17,
-      "text": "EXTRACTED = 'extracted', // テキスト抽出が完了し、データベースに保存されました"
+      "line": 2367,
+      "text": "fillServerPath: \"サーバーフォルダパスを入力してください\","
     },
     {
-      "line": 18,
-      "text": "VECTORIZED = 'vectorized', // ベクトル化が完了し、ES にインデックスされました"
+      "line": 2368,
+      "text": "invalidDateTime: \"有効な日付と時刻を入力してください\","
     },
     {
-      "line": 23,
-      "text": "FAST = 'fast',      // 高速モード - Tika を使用"
+      "line": 2371,
+      "text": "importTasksTitle: \"定期計画\","
     },
     {
-      "line": 24,
-      "text": "PRECISE = 'precise', // 精密モード - Vision Pipeline を使用"
+      "line": 2372,
+      "text": "noTasksFound: \"タスクは見つかりませんでした\","
     },
     {
-      "line": 54,
-      "text": "@Column({ name: 'user_id', nullable: true }) // 暫定的に空を許可(デバッグ用)、将来的には必須にすべき"
+      "line": 2373,
+      "text": "sourcePath: \"ソースパス\","
     },
     {
-      "line": 65,
-      "text": "content: string; // Tika で抽出されたテキスト内容を保存"
+      "line": 2374,
+      "text": "targetGroup: \"ターゲットグループ\","
     },
     {
-      "line": 67,
-      "text": "// インデックス設定パラメータ"
+      "line": 2375,
+      "text": "scheduledAt: \"実行予定日時\","
     },
     {
-      "line": 86,
-      "text": "metadata: any; // 追加のメタデータを保存(画像の説明、信頼度など)"
+      "line": 2376,
+      "text": "confirmDeleteTask: \"このインポートタスクレコードを削除してもよろしいですか?\","
     },
     {
-      "line": 89,
-      "text": "pdfPath: string; // PDF ファイルパス(プレビュー用)"
+      "line": 2377,
+      "text": "deleteTaskFailed: \"タスクレコードの削除に失敗しました\","
     }
   ],
-  "d:\\workspace\\AuraK\\server\\src\\knowledge-base\\knowledge-base.service.ts": [
+  "d:\\workspace\\AuraK\\server\\src\\chat\\chat.controller.ts": [
     {
-      "line": 86,
-      "text": "// 分類(グループ)の関連付け"
+      "line": 94,
+      "text": "console.log('Final LLM model used (default):', llmModel ? llmModel.name : '无');"
+    }
+  ],
+  "d:\\workspace\\AuraK\\server\\src\\i18n\\i18n.service.ts": [
+    {
+      "line": 7,
+      "text": "private readonly defaultLanguage = 'ja'; // プロジェクト要件に従い、Japaneseをデフォルトとして使用"
+    },
+    {
+      "line": 30,
+      "text": "// 汎用メッセージ取得メソッド、順次検索"
     },
     {
-      "line": 235,
-      "text": "// 環境変数のデフォルト次元数を使用してシミュレーションベクトルを生成"
+      "line": 33,
+      "text": "// ステータスメッセージ、エラーメッセージ、ログメッセージの順に検索"
     },
     {
-      "line": 333,
-      "text": "// エラーをスローするのではなく空の結果を返し、システムの稼働を継続させる"
+      "line": 43,
+      "text": "// メッセージの取得とフォーマット"
     },
     {
-      "line": 337,
-      "text": "ragPrompt: query, // オリジナルのクエリを使用"
+      "line": 52,
+      "text": "// サポートされている言語リストを取得"
     },
     {
-      "line": 432,
-      "text": "// メモリ監視 - 処理前チェック"
+      "line": 57,
+      "text": "// 言語がサポートされているか確認"
     },
     {
-      "line": 436,
-      "text": "// モードに基づいて処理フローを選択"
+      "line": 62,
+      "text": "// システムプロンプトを取得"
     },
     {
-      "line": 440,
-      "text": "// 精密モード - Vision Pipeline を使用"
+      "line": 69,
+      "text": "基于以下知识库内容回答用户问题。"
     },
     {
-      "line": 443,
-      "text": "// 高速モード - Tika を使用"
+      "line": 71,
+      "text": "**重要提示**: 用户已选择特定知识组,请严格基于以下知识库内容回答。如果知识库中没有相关信息,请明确告知用户:\"${noMatchMsg}\",然后再提供答案。"
     },
     {
-      "line": 455,
-      "text": "* 高速モード処理(既存フロー)"
+      "line": 73,
+      "text": "知识库内容:"
     },
     {
-      "line": 458,
-      "text": "// 1. Tika を使用してテキストを抽出"
+      "line": 76,
+      "text": "历史对话:"
     },
     {
-      "line": 461,
-      "text": "// 画像ファイルの場合はビジョンモデルを使用"
+      "line": 79,
+      "text": "用户问题:{question}"
     },
     {
-      "line": 484,
-      "text": "// テキストサイズを確認"
+      "line": 81,
+      "text": "请用Chinese回答,并严格遵循以下 Markdown 格式要求:"
     },
     {
-      "line": 490,
-      "text": "// テキストをデータベースに保存"
+      "line": 83,
+      "text": "1. **段落与结构**:"
     },
     {
-      "line": 494,
-      "text": "// 非同期ベクトル化"
+      "line": 84,
+      "text": "- 使用清晰的段落分隔,每个要点之间空一行"
     },
     {
-      "line": 499,
-      "text": "// 自動タイトル生成 (非同期的に実行)"
+      "line": 85,
+      "text": "- 使用标题(## 或 ###)组织长回答"
     },
     {
-      "line": 504,
-      "text": "// 非同期的に PDF 変換をトリガー(ドキュメントファイルの場合)"
+      "line": 87,
+      "text": "2. **文本格式**:"
     },
     {
-      "line": 511,
-      "text": "* 精密モード処理(新規フロー)"
+      "line": 88,
+      "text": "- 使用 **粗体** 强调重要概念和关键词"
     },
     {
-      "line": 514,
-      "text": "// 精密モードがサポートされているか確認"
+      "line": 89,
+      "text": "- 使用列表(- 或 1.)组织多个要点"
     },
     {
-      "line": 525,
-      "text": "// Vision モデルが設定されているか確認"
+      "line": 90,
+      "text": "- 使用 \\`代码\\` 标记技术术语、命令、文件名"
     },
     {
-      "line": 546,
-      "text": "// Vision Pipeline を呼び出し"
+      "line": 92,
+      "text": "3. **代码展示**:"
     },
     {
-      "line": 566,
-      "text": "// テキスト内容をデータベースに保存"
+      "line": 93,
+      "text": "- 使用代码块展示代码,并指定语言:"
     },
     {
-      "line": 590,
-      "text": "// 非同期でベクトル化し、Elasticsearch にインデックス"
+      "line": 96,
+      "text": "return \"示例\""
     },
     {
-      "line": 591,
-      "text": "// 各ページを独立したドキュメントとして作成し、メタデータを保持"
+      "line": 98,
+      "text": "- 支持语言:python, javascript, typescript, java, bash, sql 等"
     },
     {
-      "line": 596,
-      "text": "// 非同期で PDF 変換をトリガー"
+      "line": 100,
+      "text": "4. **图表与可视化**:"
     },
     {
-      "line": 601,
-      "text": "// 自動タイトル生成 (非同期的に実行)"
+      "line": 101,
+      "text": "- 使用 Mermaid 语法绘制流程图、序列图等:"
     },
     {
-      "line": 613,
-      "text": "* 精密モードの結果をインデックス"
+      "line": 104,
+      "text": "A[开始] --> B[处理]"
     },
     {
-      "line": 624,
-      "text": "// インデックスの存在を確認 - 実際のモデル次元数を取得"
+      "line": 105,
+      "text": "B --> C[结束]"
     },
     {
-      "line": 628,
-      "text": "// ベクトル化とインデックスをバッチ処理"
+      "line": 107,
+      "text": "- 适用场景:流程、架构、状态机、时序图"
     },
     {
-      "line": 636,
-      "text": "// ベクトルを生成"
+      "line": 109,
+      "text": "5. **其他要求**:"
     },
     {
-      "line": 643,
-      "text": "// 各結果をインデックス"
+      "line": 110,
+      "text": "- 回答精炼准确"
     },
     {
-      "line": 684,
-      "text": "* PDF の特定ページの画像を取得"
+      "line": 111,
+      "text": "- 多步骤操作使用有序列表"
     },
     {
-      "line": 689,
-      "text": "// 特定のページを変換"
+      "line": 112,
+      "text": "- 对比类信息建议用表格展示(如果适用)"
     },
     {
-      "line": 696,
-      "text": "// 対応するページ番号の画像を見つける"
+      "line": 114,
+      "text": "作为智能助手,请回答用户的问题。"
     },
     {
-      "line": 716,
-      "text": "// メモリ監視 - ベクトル化前チェック"
+      "line": 116,
+      "text": "历史对话:"
     },
     {
-      "line": 723,
-      "text": "// 1. チャンク設定の検証と修正(モデルの制限と環境変数に基づく)"
+      "line": 119,
+      "text": "用户问题:{question}"
     },
     {
-      "line": 732,
-      "text": "// 設定が修正された場合、警告を記録しデータベースを更新"
+      "line": 121,
+      "text": "请用Chinese回答。"
     },
     {
-      "line": 738,
-      "text": "// データベース内の設定を更新"
+      "line": 179,
+      "text": "} else { // 默认为日语,符合项目要求"
     },
     {
-      "line": 748,
-      "text": "// 設定サマリーを表示(実際に適用される上限を含む)"
+      "line": 181,
+      "text": "以下のナレッジベースの内容に基づいてユーザーの質問に答えてください。"
     },
     {
-      "line": 759,
-      "text": "// 2. 検証済みの設定を使用してチャンク分割"
+      "line": 183,
+      "text": "**重要**: ユーザーが特定の知識グループを選択しました。以下のナレッジベースの内容に厳密に基づいて回答してください。ナレッジベースに関連情報がない場合は、「${noMatchMsg}」とユーザーに明示的に伝えてから、回答を提供してください。"
     },
     {
-      "line": 773,
-      "text": "// 3. チャンク数が妥当か確認"
+      "line": 185,
+      "text": "ナレッジベースの内容:"
     },
     {
-      "line": 784,
-      "text": "// 4. 推奨バッチサイズを取得(モデルの制限に基づく)"
+      "line": 188,
+      "text": "会話履歴:"
     },
     {
-      "line": 792,
-      "text": "// 5. メモリ使用量を推定"
+      "line": 191,
+      "text": "ユーザーの質問:{question}"
     },
     {
-      "line": 801,
-      "text": "// 6. 実際のモデル次元数を取得し、インデックスの存在を確認"
+      "line": 193,
+      "text": "Japaneseで回答してください。以下の Markdown 書式要件に厳密に従ってください:"
     },
     {
-      "line": 805,
-      "text": "// 7. ベクトル化とインデックス作成をバッチ処理"
+      "line": 195,
+      "text": "1. **段落と構造**:"
     },
     {
-      "line": 817,
-      "text": "// バッチサイズがモデルの制限を超えていないか検証"
+      "line": 196,
+      "text": "- 明確な段落分けを使用し、要点間に空行を入れる"
     },
     {
-      "line": 831,
-      "text": "// 次元の整合性を検証"
+      "line": 197,
+      "text": "- 長い回答には見出し(## または ###)を使用"
     },
     {
-      "line": 838,
-      "text": "// このバッチデータを即座にインデックス"
+      "line": 199,
+      "text": "2. **テキスト書式**:"
     },
     {
-      "line": 877,
-      "text": "// コンテキスト長エラーを検出(日本語・中国語・英語に対応)"
+      "line": 200,
+      "text": "- 重要な概念やキーワードを強調するために **太字** を使用"
     },
     {
-      "line": 878,
-      "text": "if (error.message && (error.message.includes('context length') || error.message.includes('コンテキスト長が上限を超えています') || error.message.includes('コンテキスト長が上限を超えています'))) {"
+      "line": 201,
+      "text": "- 複数のポイントを整理するためにリスト(- または 1.)を使用"
     },
     {
-      "line": 881,
-      "text": "// 単一テキスト処理にダウングレード"
+      "line": 202,
+      "text": "- 技術用語、コマンド、ファイル名をマークするために \\`コード\\` を使用"
     },
     {
-      "line": 887,
-      "text": "[chunk.content], // 単一テキスト"
+      "line": 204,
+      "text": "3. **コード表示**:"
     },
     {
-      "line": 926,
-      "text": "// その他のエラーは直接スロー"
+      "line": 205,
+      "text": "- 言語を指定してコードブロックを使用:"
     },
     {
-      "line": 931,
-      "text": "// 小さなファイル、一括処理(ただしバッチ制限の確認が必要)"
+      "line": 208,
+      "text": "return \"例\""
     },
     {
-      "line": 934,
-      "text": "// チャンク数がモデルのバッチ制限を超える場合は、強制的にバッチ処理"
+      "line": 210,
+      "text": "- 対応言語:python, javascript, typescript, java, bash, sql など"
     },
     {
-      "line": 978,
-      "text": "// コンテキスト長エラーを検出(日本語・中国語・英語に対応)"
+      "line": 212,
+      "text": "4. **図表とチャート**:"
     },
     {
-      "line": 979,
-      "text": "if (error.message && (error.message.includes('context length') || error.message.includes('コンテキスト長が上限を超えています') || error.message.includes('コンテキスト長が上限を超えています'))) {"
+      "line": 213,
+      "text": "- フローチャート、シーケンス図などに Mermaid 構文を使用:"
     },
     {
-      "line": 982,
-      "text": "// 単一テキスト処理にダウングレード"
+      "line": 216,
+      "text": "A[開始] --> B[処理]"
     },
     {
-      "line": 988,
-      "text": "[chunk.content], // 単一テキスト"
+      "line": 217,
+      "text": "B --> C[終了]"
     },
     {
-      "line": 1027,
-      "text": "// その他のエラー、直接スロー"
+      "line": 219,
+      "text": "- 使用例:プロセスフロー、アーキテクチャ図、状態図、シーケンス図"
     },
     {
-      "line": 1032,
-      "text": "// 十分に小さいファイルの場合は一括で処理"
+      "line": 221,
+      "text": "5. **その他の要件**:"
     },
     {
-      "line": 1066,
-      "text": "// コンテキスト長エラーを検出(日本語・中国語・英語に対応)"
+      "line": 222,
+      "text": "- 簡潔で明確な回答を心がける"
     },
     {
-      "line": 1067,
-      "text": "if (error.message && (error.message.includes('context length') || error.message.includes('コンテキスト長が上限を超えています') || error.message.includes('コンテキスト長が上限を超えています'))) {"
+      "line": 223,
+      "text": "- 複数のステップがある場合は番号付きリストを使用"
     },
     {
-      "line": 1070,
-      "text": "// 単一テキスト処理にダウングレード"
+      "line": 224,
+      "text": "- 比較情報には表を使用(該当する場合)"
     },
     {
-      "line": 1076,
-      "text": "[chunk.content], // 単一テキスト"
+      "line": 226,
+      "text": "インテリジェントアシスタントとして、ユーザーの質問に答えてください。"
     },
     {
-      "line": 1115,
-      "text": "// その他のエラー、直接スロー"
+      "line": 228,
+      "text": "会話履歴:"
     },
     {
-      "line": 1130,
-      "text": "// エラー情報を metadata に保存"
+      "line": 231,
+      "text": "ユーザーの質問:{question}"
     },
     {
-      "line": 1148,
-      "text": "* バッチ処理、メモリ制御付き"
+      "line": 232,
+      "text": "Japaneseで回答してください。"
     },
     {
-      "line": 1169,
-      "text": "// メモリを確認し待機"
+      "line": 237,
+      "text": "// タイトル生成用のプロンプトを取得"
     },
     {
-      "line": 1172,
-      "text": "// バッチサイズを動的に調整 (initialBatchSize から開始し、必要に応じてメモリモニターが削減できるようにします)"
+      "line": 241,
+      "text": "return `你是一个文档分析师。请阅读以下文本(文档开Header分),并生成一个简炼、专业的标题(不超过50个字符)。"
     },
     {
-      "line": 1173,
-      "text": "// 注意: memoryMonitor.getDynamicBatchSize はメモリ状況に基づいてより大きな値を返す可能性がありますが、"
+      "line": 242,
+      "text": "只返回标题文本。不要包含任何解释性文字或前导词(如“标题是:”)。"
     },
     {
-      "line": 1174,
-      "text": "// モデルの制限 (initialBatchSize) を尊重する必要があります。"
+      "line": 243,
+      "text": "语言:Chinese"
     },
     {
-      "line": 1181,
-      "text": "// 現在のバッチを取得"
+      "line": 244,
+      "text": "文本内容:"
     },
     {
-      "line": 1189,
-      "text": "// バッチを処理"
+      "line": 253,
+      "text": "return `あなたはドキュメントアナライザーです。以下のテキスト(ドキュメントの冒頭部分)を読み、簡潔でプロフェッショナルなタイトル(最大50文字)を生成してください。"
     },
     {
-      "line": 1192,
-      "text": "// コールバック通知"
+      "line": 254,
+      "text": "タイトルテキストのみを返してください。説明文や前置き(例:「タイトルは:」)は含めないでください。"
     },
     {
-      "line": 1197,
-      "text": "// 強制GC(メモリがしきい値に近い場合)"
+      "line": 255,
+      "text": "言語:Japanese"
     },
     {
-      "line": 1202,
-      "text": "// 参照をクリアしGCを助ける"
+      "line": 256,
+      "text": "テキスト:"
     },
     {
-      "line": 1213,
-      "text": "* 失敗したファイルのベクトル化を再試行"
+      "line": 264,
+      "text": "return `根据以下对话片段,生成一个简短、描述性的标题(不超过50个字符),总结讨论的主题。"
     },
     {
-      "line": 1224,
-      "text": "throw new NotFoundException('ファイルが存在しません');"
+      "line": 265,
+      "text": "只返回标题文本。不要包含任何前导词。"
     },
     {
-      "line": 1235,
-      "text": "// 2. ステータスを INDEXING にリセット"
+      "line": 266,
+      "text": "语言:Chinese"
     },
     {
-      "line": 1238,
-      "text": "// 3. 非同期でベクトル化をトリガー(既存ロジックを再利用)"
+      "line": 267,
+      "text": "片段:"
     },
     {
-      "line": 1253,
-      "text": "// 4. 更新後のファイルステータスを返却"
+      "line": 268,
+      "text": "用户: ${userMessage}"
     },
     {
-      "line": 1256,
-      "text": "throw new NotFoundException('ファイルが存在しません');"
+      "line": 269,
+      "text": "助手: ${aiResponse}`;"
     },
     {
-      "line": 1262,
-      "text": "* ファイルのすべてのチャンク情報を取得"
+      "line": 278,
+      "text": "return `以下の会話スニペットに基づいて、トピックを要約する短く説明的なタイトル(最大50文字)を生成してください。"
     },
     {
-      "line": 1273,
-      "text": "throw new NotFoundException('ファイルが存在しません');"
+      "line": 279,
+      "text": "タイトルのみを返してください。前置きは不要です。"
     },
     {
-      "line": 1276,
-      "text": "// 2. Elasticsearch からすべてのチャンクを取得"
+      "line": 280,
+      "text": "言語:Japanese"
     },
     {
-      "line": 1279,
-      "text": "// 3. チャンク情報を返却"
+      "line": 281,
+      "text": "スニペット:"
     },
     {
-      "line": 1300,
-      "text": "// PDF プレビュー関連メソッド"
+      "line": 282,
+      "text": "ユーザー: ${userMessage}"
     },
     {
-      "line": 1310,
-      "text": "// 元ファイルが PDF の場合は、元ファイルのパスを直接返す"
-    },
+      "line": 283,
+      "text": "アシスタント: ${aiResponse}`;"
+    }
+  ],
+  "d:\\workspace\\AuraK\\server\\src\\i18n\\messages.ts": [
     {
-      "line": 1315,
-      "text": "// プレビュー変換に対応しているか確認(ドキュメント類または画像類のみ許可)"
+      "line": 3,
+      "text": "noEmbeddingModel: '请先在系统设置中配置嵌入模型',"
     },
     {
-      "line": 1324,
-      "text": "// PDF フィールドパスを生成"
+      "line": 4,
+      "text": "searchFailed: '搜索知识库失败,将基于一般知识回答...',"
     },
     {
-      "line": 1331,
-      "text": "// 強制再生成が指定され、ファイルが存在する場合は削除"
+      "line": 5,
+      "text": "invalidApiKey: 'API密钥无效',"
     },
     {
-      "line": 1341,
-      "text": "// 変換済みかつ強制再生成が不要か確認"
+      "line": 6,
+      "text": "fileNotFound: '未找到文件',"
     },
     {
-      "line": 1349,
-      "text": "// PDF への変換が必要"
+      "line": 7,
+      "text": "insufficientQuota: '配额不足',"
     },
     {
-      "line": 1353,
-      "text": "// ファイルを変換"
+      "line": 8,
+      "text": "modelNotConfigured: '未配置模型',"
     },
     {
-      "line": 1356,
-      "text": "// 変換結果を確認"
+      "line": 9,
+      "text": "visionModelNotConfigured: '未配置视觉模型',"
     },
     {
-      "line": 1386,
-      "text": "// 元ファイルが PDF の場合"
+      "line": 10,
+      "text": "embeddingDimensionMismatch: '嵌入维度不匹配',"
     },
     {
-      "line": 1395,
-      "text": "// PDF ファイルパスを生成"
+      "line": 11,
+      "text": "uploadNoFile: '未上传文件',"
     },
     {
-      "line": 1402,
-      "text": "// 変換済みか確認"
+      "line": 12,
+      "text": "uploadSizeExceeded: '文件大小超过限制: {size}, 最大允许: {max}',"
     },
     {
-      "line": 1415,
-      "text": "// 変換が必要"
+      "line": 13,
+      "text": "uploadModelRequired: '必须选择嵌入模型',"
     },
     {
-      "line": 1437,
-      "text": "* モデルの実際の次元数を取得(キャッシュ確認とプローブロジック付き)"
+      "line": 14,
+      "text": "uploadTypeUnsupported: '不支持的文件格式: {type}',"
     },
     {
-      "line": 1445,
-      "text": "// 1. モデル設定から優先的に取得"
+      "line": 15,
+      "text": "chunkOverflow: '切片大小 {size} 超过上限 {max} ({reason})。已自动调整',"
     },
     {
-      "line": 1457,
-      "text": "// 2. それ以外の場合はプローブにより取得"
+      "line": 16,
+      "text": "chunkUnderflow: '切片大小 {size} 小于最小值 {min}。已自动调整',"
     },
     {
-      "line": 1469,
-      "text": "// 次回利用のためにモデル設定を更新"
+      "line": 17,
+      "text": "overlapOverflow: '重叠大小 {size} 超过上限 {max}。已自动调整',"
     },
     {
-      "line": 1494,
-      "text": "* AIを使用して文書のタイトルを自動生成する"
+      "line": 18,
+      "text": "overlapUnderflow: '重叠大小 {size} 小于最小值 {min}。已自动调整',"
     },
     {
-      "line": 1506,
-      "text": "// すでにタイトルがある場合はスキップ"
+      "line": 19,
+      "text": "overlapRatioExceeded: '重叠大小 {size} 超过切片大小的50% ({max})。已自动调整',"
     },
     {
-      "line": 1511,
-      "text": "// コンテンツの冒頭サンプルを取得(最大2500文字)"
+      "line": 20,
+      "text": "batchOverflowWarning: '建议切片大小不超过 {safeSize} 以避免批量处理溢出 (当前: {size}, 模型限制的 {percent}%)',"
     },
     {
-      "line": 1514,
-      "text": "// ユーザー設定から言語を取得、またはデフォルトを使用"
+      "line": 21,
+      "text": "estimatedChunkCountExcessive: '预计切片数量过多 ({count}),处理可能较慢',"
     },
     {
-      "line": 1518,
-      "text": "// プロンプトを構築"
+      "line": 22,
+      "text": "contentAndTitleRequired: '内容和标题为必填项',"
     },
     {
-      "line": 1521,
-      "text": "// LLMを呼び出してタイトルを生成"
+      "line": 23,
+      "text": "embeddingModelNotFound: '找不到嵌入模型 {id} 或类型不是 embedding',"
     },
     {
-      "line": 1535,
-      "text": "// 余分な引用符や改行を除去"
+      "line": 24,
+      "text": "ocrFailed: '提取文本失败: {message}',"
     },
     {
-      "line": 1539,
-      "text": "// Elasticsearch のチャンクも更新"
-    }
-  ],
-  "d:\\workspace\\AuraK\\server\\src\\knowledge-base\\memory-monitor.service.ts": [
-    {
-      "line": 4,
-      "text": "heapUsed: number;    // 使用済みヒープメモリ (MB)"
+      "line": 25,
+      "text": "noImageUploaded: '未上传图片',"
     },
     {
-      "line": 5,
-      "text": "heapTotal: number;   // 総ヒープメモリ (MB)"
+      "line": 26,
+      "text": "adminOnlyViewList: '只有管理员可以查看用户列表',"
     },
     {
-      "line": 6,
-      "text": "external: number;    // 外部メモリ (MB)"
+      "line": 27,
+      "text": "passwordsRequired: '当前密码和新密码不能为空',"
     },
     {
-      "line": 7,
-      "text": "rss: number;         // RSS (常駐セットサイズ) (MB)"
+      "line": 28,
+      "text": "newPasswordMinLength: '新密码长度不能少于6位',"
     },
     {
-      "line": 19,
-      "text": "// 環境変数から設定を読み込む。デフォルト値はメモリ最適化用"
+      "line": 29,
+      "text": "adminOnlyCreateUser: '只有管理员可以创建用户',"
     },
     {
-      "line": 20,
-      "text": "this.MAX_MEMORY_MB = parseInt(process.env.MAX_MEMORY_USAGE_MB || '1024'); // 1GB上限"
+      "line": 30,
+      "text": "usernamePasswordRequired: '用户名和密码不能为空',"
     },
     {
-      "line": 21,
-      "text": "this.BATCH_SIZE = parseInt(process.env.CHUNK_BATCH_SIZE || '100'); // 1バッチあたり100チャンク"
+      "line": 31,
+      "text": "passwordMinLength: '密码长度不能少于6位',"
     },
     {
-      "line": 22,
-      "text": "this.GC_THRESHOLD_MB = parseInt(process.env.GC_THRESHOLD_MB || '800'); // 800MBでGCをトリガー"
+      "line": 32,
+      "text": "adminOnlyUpdateUser: '只有管理员可以更新用户信息',"
     },
     {
-      "line": 28,
-      "text": "* 現在のメモリ使用状況を取得"
+      "line": 33,
+      "text": "userNotFound: '用户不存在',"
     },
     {
-      "line": 42,
-      "text": "* メモリが上限に近づいているかチェック"
+      "line": 34,
+      "text": "cannotModifyBuiltinAdmin: '无法修改内置管理员账户',"
     },
     {
-      "line": 46,
-      "text": "return usage.heapUsed > this.MAX_MEMORY_MB * 0.85; // 85%閾値"
+      "line": 35,
+      "text": "adminOnlyDeleteUser: '只有管理员可以删除用户',"
     },
     {
-      "line": 50,
-      "text": "* メモリが利用可能になるまで待機(タイムアウトあり)"
+      "line": 36,
+      "text": "cannotDeleteSelf: '不能删除自己的账户',"
     },
     {
-      "line": 57,
-      "text": "throw new Error(`メモリ待機がタイムアウトしました: 現在 ${this.getMemoryUsage().heapUsed}MB > ${this.MAX_MEMORY_MB * 0.85}MB`);"
+      "line": 37,
+      "text": "cannotDeleteBuiltinAdmin: '无法删除内置管理员账户',"
     },
     {
-      "line": 64,
-      "text": "// ガベージコレクションを強制実行(可能な場合)"
+      "line": 38,
+      "text": "incorrectCredentials: '用户名或密码不正确',"
     },
     {
-      "line": 75,
-      "text": "* ガベージコレクションを強制実行(可能な場合)"
+      "line": 39,
+      "text": "incorrectCurrentPassword: '当前密码错误',"
     },
     {
-      "line": 89,
-      "text": "* バッチサイズを動的に調整"
+      "line": 40,
+      "text": "usernameExists: '用户名已存在',"
     },
     {
-      "line": 95,
-      "text": "// メモリ逼迫、バッチサイズを削減"
+      "line": 41,
+      "text": "noteNotFound: '找不到笔记: {id}',"
     },
     {
-      "line": 102,
-      "text": "// メモリに余裕あり、バッチサイズを増量"
+      "line": 42,
+      "text": "knowledgeGroupNotFound: '找不到知识组: {id}',"
     },
     {
-      "line": 116,
-      "text": "* 大規模データの処理:自動バッチングとメモリ制御"
+      "line": 43,
+      "text": "accessDeniedNoToken: '访问被拒绝:缺少令牌',"
     },
     {
-      "line": 136,
-      "text": "// メモリ状態をチェックして待機"
+      "line": 44,
+      "text": "invalidToken: '无效的令牌',"
     },
     {
-      "line": 139,
-      "text": "// バッチサイズを動的に調整"
+      "line": 45,
+      "text": "pdfFileNotFound: '找不到 PDF 文件',"
     },
     {
-      "line": 143,
-      "text": "// 現在のバッチを取得"
+      "line": 46,
+      "text": "pdfFileEmpty: 'PDF 文件为空,转换可能失败',"
     },
     {
-      "line": 152,
-      "text": "// バッチを処理"
+      "line": 47,
+      "text": "pdfConversionFailed: 'PDF 文件不存在或转换失败',"
     },
     {
-      "line": 157,
-      "text": "// コールバック通知"
+      "line": 48,
+      "text": "pdfConversionFailedDetail: 'PDF 转换失败(文件 ID: {id}),请稍后重试',"
     },
     {
-      "line": 162,
-      "text": "// メモリが閾値に近い場合はGCを強制実行"
+      "line": 49,
+      "text": "pdfPreviewNotSupported: '该文件格式不支持预览',"
     },
     {
-      "line": 167,
-      "text": "// GCを助けるために参照をクリア"
+      "line": 50,
+      "text": "pdfServiceUnavailable: 'PDF 服务不可用: {message}',"
     },
     {
-      "line": 183,
-      "text": "* 処理に必要なメモリを見積もる"
+      "line": 51,
+      "text": "pageImageNotFound: '找不到页面图像',"
     },
     {
-      "line": 186,
-      "text": "// テキスト内容のメモリ"
+      "line": 52,
+      "text": "pdfPageImageFailed: '无法获取 PDF 页面图像',"
     },
     {
-      "line": 189,
-      "text": "// ベクトルメモリ (各ベクトル: 次元 × 4バイト)"
+      "line": 53,
+      "text": "someGroupsNotFound: '部分组不存在',"
     },
     {
-      "line": 192,
-      "text": "// オブジェクトのオーバーヘッド (各オブジェクトにつき追加で約100バイトと推定)"
+      "line": 54,
+      "text": "promptRequired: '提示词是必填项',"
     },
     {
-      "line": 201,
-      "text": "* バッチ処理を使用すべきかチェック"
+      "line": 55,
+      "text": "addLLMConfig: '请在系统设置中添加 LLM 模型',"
     },
     {
-      "line": 205,
-      "text": "const threshold = this.MAX_MEMORY_MB * 0.7; // 70%閾値"
+      "line": 56,
+      "text": "visionAnalysisFailed: '视觉分析失败: {message}',"
     },
     {
-      "line": 218,
-      "text": "* 推奨されるバッチサイズを取得"
+      "line": 57,
+      "text": "retryMechanismError: '重试机制异常',"
     },
     {
-      "line": 221,
-      "text": "// 目標:1バッチあたり最大 200MB メモリ"
+      "line": 58,
+      "text": "imageLoadError: '无法读取图像: {message}',"
     },
     {
-      "line": 225,
-      "text": "// 1項目あたりのメモリ = テキスト + ベクトル + オーバーヘッド"
+      "line": 59,
+      "text": "groupNotFound: '分组不存在',"
     },
     {
-      "line": 230,
-      "text": "// 限制在 10-200 之间"
-    }
-  ],
-  "d:\\workspace\\AuraK\\server\\src\\knowledge-base\\text-chunker.service.ts": [
-    {
-      "line": 25,
-      "text": "// テキスト長がチャンクサイズ以下の場合は、テキスト全体を1つのチャンクとして直接返す"
+      "line": 62,
+      "text": "noEmbeddingModel: '先にシステム設定で埋め込みモデルを設定してください',"
     },
     {
-      "line": 44,
-      "text": "// 文の境界で分割"
+      "line": 63,
+      "text": "searchFailed: 'ナレッジベース検索に失敗しました。一般的な知識に基づいて回答します...',"
     },
     {
-      "line": 72,
-      "text": "// 次のチャンクの開始位置を計算"
-    }
-  ],
-  "d:\\workspace\\AuraK\\server\\src\\libreoffice\\libreoffice.interface.ts": [
+      "line": 64,
+      "text": "invalidApiKey: 'APIキーが無効です',"
+    },
     {
-      "line": 2,
-      "text": "* LibreOffice サービスインターフェース定義"
+      "line": 65,
+      "text": "fileNotFound: 'ファイルが見つかりません',"
     },
     {
-      "line": 7,
-      "text": "pdf_data?: string; // base64 エンコードされた PDF データ"
-    }
-  ],
-  "d:\\workspace\\AuraK\\server\\src\\libreoffice\\libreoffice.service.ts": [
+      "line": 66,
+      "text": "insufficientQuota: '利用枠が不足しています',"
+    },
     {
-      "line": 26,
-      "text": "* LibreOffice サービスの状態をチェック"
+      "line": 67,
+      "text": "modelNotConfigured: 'モデルが設定されていません',"
     },
     {
-      "line": 42,
-      "text": "* ドキュメントを PDF に変換"
+      "line": 68,
+      "text": "visionModelNotConfigured: 'ビジョンモデルが設定されていません',"
     },
     {
-      "line": 43,
-      "text": "* @param filePath 変換するファイルのパス"
+      "line": 69,
+      "text": "embeddingDimensionMismatch: '埋め込み次元数が一致しません',"
     },
     {
-      "line": 44,
-      "text": "* @returns PDF ファイルのパス"
+      "line": 70,
+      "text": "uploadNoFile: 'ファイルがアップロードされていません',"
     },
     {
-      "line": 50,
-      "text": "// PDF の場合は元のパスを直接返す"
+      "line": 71,
+      "text": "uploadSizeExceeded: 'ファイルサイズが制限: {size}, 最大許容: {max}',"
     },
     {
-      "line": 56,
-      "text": "// ファイルの存在確認"
+      "line": 72,
+      "text": "uploadModelRequired: '埋め込みモデルを選択する必要があります',"
     },
     {
-      "line": 60,
-      "text": "throw new Error(`ファイルが存在しません: ${filePath}`);"
+      "line": 73,
+      "text": "uploadTypeUnsupported: 'サポートされていないファイル形式です: {type}',"
     },
     {
-      "line": 63,
-      "text": "// 出力先 PDF のパスを生成"
+      "line": 74,
+      "text": "chunkOverflow: 'Chunk size {size}  exceeds limit  {max} ({reason}) 。自動調整されました',"
     },
     {
-      "line": 68,
-      "text": "// PDF が既に存在する場合は直接返す"
+      "line": 75,
+      "text": "chunkUnderflow: 'Chunk size {size}  is below minimum  {min} 。自動調整されました',"
     },
     {
-      "line": 74,
-      "text": "// PDF が存在しないため、変換が必要"
+      "line": 76,
+      "text": "overlapOverflow: '重なりサイズ {size}  exceeds limit  {max} 。自動調整されました',"
     },
     {
       "line": 77,
-      "text": "// ファイルの読み込み"
+      "text": "overlapUnderflow: '重なりサイズ {size}  is below minimum  {min} 。自動調整されました',"
     },
     {
-      "line": 80,
-      "text": "// FormData の構築"
+      "line": 78,
+      "text": "overlapRatioExceeded: '重なりサイズ {size} がChunk sizeの50% ({max}) 。自動調整されました',"
     },
     {
-      "line": 86,
-      "text": "// 変換の再試行回数"
+      "line": 79,
+      "text": "batchOverflowWarning: 'バッチ処理のオーバーフローを避けるため、Chunk sizeを {safeSize} 以下にすることをお勧めします (現在: {size}, モデル制限の {percent}%)',"
     },
     {
-      "line": 92,
-      "text": "// LibreOffice サービスの呼び出し"
+      "line": 80,
+      "text": "estimatedChunkCountExcessive: '推定チャンク数が多すぎます ({count})。処理に時間がかかる可能性があります',"
     },
     {
-      "line": 98,
-      "text": "timeout: 300000, // 5分タイムアウト"
+      "line": 81,
+      "text": "contentAndTitleRequired: '内容とタイトルは必須です',"
     },
     {
-      "line": 99,
-      "text": "responseType: 'stream', // ファイルストリームを受信"
+      "line": 82,
+      "text": "embeddingModelNotFound: '埋め込みモデル {id} が見つかりません、またはタイプが embedding ではありません',"
     },
     {
-      "line": 100,
-      "text": "maxRedirects: 5, // リダイレクトの最大数"
+      "line": 83,
+      "text": "ocrFailed: 'テキストの抽出に失敗しました: {message}',"
     },
     {
-      "line": 104,
-      "text": "// ストリームを出力ファイルに書き込む"
+      "line": 84,
+      "text": "noImageUploaded: '画像がアップロードされていません',"
     },
     {
-      "line": 123,
-      "text": "// socket hang up や接続エラーの場合は少し待機して再試行"
+      "line": 85,
+      "text": "adminOnlyViewList: '管理者のみがユーザーリストを表示できます',"
     },
     {
-      "line": 126,
-      "text": "const delay = 2000 * attempt; // だんだん増える遅延"
+      "line": 86,
+      "text": "passwordsRequired: '現在のパスワードと新しいパスワードは必須です',"
     },
     {
-      "line": 131,
-      "text": "// その他のエラーは再試行しない"
+      "line": 87,
+      "text": "newPasswordMinLength: '新しいパスワードは少なくとも6文字以上である必要があります',"
     },
     {
-      "line": 137,
-      "text": "// 全ての再試行が失敗した場合、詳細なエラーハンドリングを行う"
+      "line": 88,
+      "text": "adminOnlyCreateUser: '管理者のみがユーザーを作成できます',"
     },
     {
-      "line": 157,
-      "text": "throw new Error('変換がタイムアウトしました。ファイルが大きすぎる可能性があります');"
+      "line": 89,
+      "text": "usernamePasswordRequired: 'ユーザー名とパスワードは必須です',"
     },
     {
-      "line": 159,
-      "text": "throw new Error(`変換に失敗しました: ${detail}`);"
+      "line": 90,
+      "text": "passwordMinLength: 'パスワードは少なくとも6文字以上である必要があります',"
     },
     {
-      "line": 163,
-      "text": "throw new Error(`変換に失敗しました: ${lastError.message}`);"
+      "line": 91,
+      "text": "adminOnlyUpdateUser: '管理者のみがユーザー情報を更新できます',"
     },
     {
-      "line": 169,
-      "text": "throw new Error('LibreOffice サービスが実行されていません。サービスの状態を確認してください');"
+      "line": 92,
+      "text": "userNotFound: 'ユーザーが見つかりません',"
     },
     {
-      "line": 172,
-      "text": "throw new Error('LibreOffice サービスとの接続が切断されました。サービスが不安定である可能性があります');"
+      "line": 93,
+      "text": "cannotModifyBuiltinAdmin: 'ビルトイン管理者アカウントを変更できません',"
     },
     {
-      "line": 174,
-      "text": "throw new Error(`変換に失敗しました: ${lastError.message}`);"
+      "line": 94,
+      "text": "adminOnlyDeleteUser: '管理者のみがユーザーを削除できます',"
     },
     {
-      "line": 178,
-      "text": "* ファイルの一括変換"
+      "line": 95,
+      "text": "cannotDeleteSelf: '自分自身のアカウントを削除できません',"
     },
     {
-      "line": 195,
-      "text": "* サービスのバージョン情報を取得"
-    }
-  ],
-  "d:\\workspace\\AuraK\\server\\src\\migrations\\1737800000000-AddKnowledgeBaseEnhancements.ts": [
-    {
-      "line": 7,
-      "text": "// 知識ベースグループテーブルの作成"
+      "line": 96,
+      "text": "cannotDeleteBuiltinAdmin: 'ビルトイン管理者アカウントを削除できません',"
     },
     {
-      "line": 20,
-      "text": "// ドキュメントグループ関連テーブルの作成"
+      "line": 97,
+      "text": "incorrectCredentials: 'ユーザー名またはパスワードが間違っています',"
     },
     {
-      "line": 32,
-      "text": "// 検索履歴テーブルの作成"
+      "line": 98,
+      "text": "incorrectCurrentPassword: '現在のパスワードが間違っています',"
     },
     {
-      "line": 44,
-      "text": "// 会話メッセージテーブルの作成"
+      "line": 99,
+      "text": "usernameExists: 'ユーザー名が既に存在します',"
     },
     {
-      "line": 57,
-      "text": "// knowledge_base テーブルに pdf_path フィールドを追加"
+      "line": 100,
+      "text": "noteNotFound: 'ノートが見つかりません: {id}',"
     },
     {
-      "line": 62,
-      "text": "// インデックスの作成"
+      "line": 101,
+      "text": "knowledgeGroupNotFound: 'ナレッジグループが見つかりません: {id}',"
     },
     {
-      "line": 69,
-      "text": "// インデックスの削除"
+      "line": 102,
+      "text": "accessDeniedNoToken: 'アクセス不許可:トークンがありません',"
     },
     {
-      "line": 74,
-      "text": "// pdf_path フィールドの削除"
+      "line": 103,
+      "text": "invalidToken: '無効なトークンです',"
     },
     {
-      "line": 77,
-      "text": "// テーブルの削除"
-    }
-  ],
-  "d:\\workspace\\AuraK\\server\\src\\model-config\\dto\\create-model-config.dto.ts": [
+      "line": 104,
+      "text": "pdfFileNotFound: 'PDF ファイルが見つかりません',"
+    },
     {
-      "line": 31,
-      "text": "apiKey?: string; // APIキーはオプションです - ローカルモデルを許可します"
+      "line": 105,
+      "text": "pdfFileEmpty: 'PDF ファイルが空です。変換に失敗した可能性があります',"
     },
     {
-      "line": 38,
-      "text": "@Min(1, { message: 'ベクトル次元の最小値は 1 です' })"
+      "line": 106,
+      "text": "pdfConversionFailed: 'PDF ファイルが存在しないか、変換に失敗しました',"
     },
     {
-      "line": 39,
-      "text": "@Max(4096, { message: 'ベクトル次元の最大値は 4096 です(Elasticsearch の制限)' })"
+      "line": 107,
+      "text": "pdfConversionFailedDetail: 'PDF 変換に失敗しました(ファイル ID: {id})。後でもう一度お試しください',"
     },
     {
-      "line": 43,
-      "text": "// ==================== 追加フィールド ===================="
+      "line": 108,
+      "text": "pdfPreviewNotSupported: 'このファイル形式はプレビューをサポートしていません',"
     },
     {
-      "line": 46,
-      "text": "* モデルの入力トークン制限(embedding/rerank にのみ有効)"
+      "line": 109,
+      "text": "pdfServiceUnavailable: 'PDF サービスを利用できません: {message}',"
     },
     {
-      "line": 55,
-      "text": "* バッチ処理の制限(embedding/rerank にのみ有効)"
+      "line": 110,
+      "text": "pageImageNotFound: 'ページ画像が見つかりません',"
     },
     {
-      "line": 64,
-      "text": "* ベトルモデルかどうか"
+      "line": 111,
+      "text": "pdfPageImageFailed: 'PDF ページの画像を取得できませんでした',"
     },
     {
-      "line": 71,
-      "text": "* モデルプロバイダー名"
+      "line": 112,
+      "text": "someGroupsNotFound: '一部のグループが存在しません',"
     },
     {
-      "line": 78,
-      "text": "* このモデルを有効にするかどうか"
+      "line": 113,
+      "text": "promptRequired: 'プロンプトは必須です',"
     },
     {
-      "line": 85,
-      "text": "* このモデルをデフォルトとして使用するかどうか"
-    }
-  ],
-  "d:\\workspace\\AuraK\\server\\src\\model-config\\model-config.entity.ts": [
-    {
-      "line": 34,
-      "text": "dimensions?: number; // 埋め込みモデルの次元、システムによって自動的に検出され保存されます"
+      "line": 114,
+      "text": "addLLMConfig: 'システム設定で LLM モデルをAddedしてください',"
     },
     {
-      "line": 36,
-      "text": "// ==================== 追加フィールド ===================="
+      "line": 115,
+      "text": "visionAnalysisFailed: 'ビジョン分析に失敗しました: {message}',"
     },
     {
-      "line": 37,
-      "text": "// 以下字段仅对 embedding/rerank 模型有意义"
+      "line": 116,
+      "text": "retryMechanismError: '再試行メカニズムの異常',"
     },
     {
-      "line": 40,
-      "text": "* モデルの入力トークン制限"
+      "line": 117,
+      "text": "imageLoadError: '画像を読み込めません: {message}',"
     },
     {
-      "line": 41,
-      "text": "* 例: OpenAI=8191, Gemini=2048"
+      "line": 118,
+      "text": "groupNotFound: 'グループが存在しません',"
     },
     {
-      "line": 47,
-      "text": "* 一括処理制限(1回のリクエストあたりの最大入力数)"
+      "line": 184,
+      "text": "processingFile: '处理文件: {name} ({size})',"
     },
     {
-      "line": 48,
-      "text": "* 例: OpenAI=2048, Gemini=100"
+      "line": 185,
+      "text": "indexingComplete: '索引完成: {id}',"
     },
     {
-      "line": 54,
-      "text": "* ベトルモデルかどうか(システム設定での識別用)"
+      "line": 186,
+      "text": "vectorizingFile: '向量化文件: ',"
     },
     {
-      "line": 60,
-      "text": "* このモデルを有効にするかどうか"
+      "line": 187,
+      "text": "searchQuery: '搜索查询: ',"
     },
     {
-      "line": 61,
-      "text": "* ユーザーは使用しないモデルを無効にして、誤選択を防ぐことができます"
+      "line": 188,
+      "text": "modelCall: '[模型调用] 类型: {type}, 模型: {model}, 用户: {user}',"
     },
     {
-      "line": 67,
-      "text": "* このモデルをデフォルトとして使用するかどうか"
+      "line": 189,
+      "text": "memoryStatus: '内存状态: ',"
     },
     {
-      "line": 68,
-      "text": "* 各タイプ(llm, embedding, rerank)ごとに1つのみデフォルトにできます"
+      "line": 190,
+      "text": "uploadSuccess: '文件上传成功。正在后台索引',"
     },
     {
-      "line": 74,
-      "text": "* モデルプロバイダー名(表示および識別用)"
+      "line": 191,
+      "text": "overlapAdjusted: '重叠大小超过切片大小的50%。已自动调整为 {newSize}',"
     },
     {
-      "line": 75,
-      "text": "* 例: \"OpenAI\", \"Google Gemini\", \"Custom\""
+      "line": 192,
+      "text": "environmentLimit: '环境变量限制',"
     },
     {
-      "line": 80,
-      "text": "// ==================== 既存のフィールド ===================="
-    }
-  ],
-  "d:\\workspace\\AuraK\\server\\src\\model-config\\model-config.service.ts": [
-    {
-      "line": 109,
-      "text": "* 指定されたモデルをデフォルトに設定"
+      "line": 193,
+      "text": "modelLimit: '模型限制',"
     },
     {
-      "line": 114,
-      "text": "// 同じタイプの他のモデルのデフォルトフラグをクリア (現在のテナント内またはglobal)"
+      "line": 194,
+      "text": "configLoaded: '数据库模型配置加载: {name} ({id})',"
     },
     {
-      "line": 115,
-      "text": "// 厳密には、現在のテナントのIsDefault設定といった方が正しいですが、シンプルにするため全体のIsDefaultを操作します"
+      "line": 195,
+      "text": "batchSizeAdjusted: '批量大小从 {old} 调整为 {new} (模型限制: {limit})',"
     },
     {
-      "line": 132,
-      "text": "* 指定されたタイプのデフォルトモデルを取得"
+      "line": 196,
+      "text": "dimensionMismatch: '模型 {id} 维度不匹配: 预期 {expected}, 实际 {actual}',"
     },
     {
-      "line": 133,
-      "text": "* 厳密なルール:Index Chat Configで指定されたモデルのみを返し、なければエラーを投げる"
-    }
-  ],
-  "d:\\workspace\\AuraK\\server\\src\\pdf2image\\pdf2image.interface.ts": [
-    {
-      "line": 2,
-      "text": "* PDF 转图片接口定义"
+      "line": 197,
+      "text": "searchMetadataFailed: '为用户 {userId} 搜索知识库失败',"
     },
     {
-      "line": 6,
-      "text": "density?: number;        // DPI 分辨率,默认 300"
+      "line": 198,
+      "text": "extractedTextTooLarge: '抽出されたテキストが大きいです: {size}MB',"
     },
     {
-      "line": 7,
-      "text": "quality?: number;        // JPEG 质量 (1-100),默认 85"
+      "line": 199,
+      "text": "preciseModeUnsupported: '格式 {ext} 不支持精密模式,回退到快速模式',"
     },
     {
-      "line": 8,
-      "text": "format?: 'jpeg' | 'png'; // 输出格式,默认 jpeg"
+      "line": 200,
+      "text": "visionModelNotConfiguredFallback: '未配置视觉模型,回退到快速模式',"
     },
     {
-      "line": 9,
-      "text": "outDir?: string;         // 输出目录,默认 ./temp"
+      "line": 201,
+      "text": "visionModelInvalidFallback: '视觉模型配置无效,回退到快速模式',"
     },
     {
-      "line": 13,
-      "text": "path: string;            // 图片文件路径"
+      "line": 202,
+      "text": "visionPipelineFailed: '视觉流水线失败,回退到快速模式',"
     },
     {
-      "line": 14,
-      "text": "pageIndex: number;       // 页码(从 1 开始)"
+      "line": 203,
+      "text": "preciseModeComplete: '精密模式提取完成: {pages}页, 费用: ${cost}',"
     },
     {
-      "line": 15,
-      "text": "size: number;            // 文件大小(字节)"
+      "line": 204,
+      "text": "skippingEmptyVectorPage: '跳过第 {page} 页(空向量)',"
     },
     {
-      "line": 16,
-      "text": "width?: number;          // 图片宽度"
+      "line": 205,
+      "text": "pdfPageImageError: '获取 PDF 页面图像失败: {message}',"
     },
     {
-      "line": 17,
-      "text": "height?: number;         // 图片高度"
-    }
-  ],
-  "d:\\workspace\\AuraK\\server\\src\\pdf2image\\pdf2image.service.ts": [
-    {
-      "line": 22,
-      "text": "* PDF を画像リストに変換します"
+      "line": 206,
+      "text": "internalServerError: '服务器内部错误',"
     },
     {
-      "line": 23,
-      "text": "* ImageMagick の convert コマンドを使用します"
+      "line": 209,
+      "text": "processingFile: 'ファイル処理中: {name} ({size})',"
     },
     {
-      "line": 36,
-      "text": "// PDF ファイルの検証"
+      "line": 210,
+      "text": "indexingComplete: 'インデックス完了: {id}',"
     },
     {
-      "line": 40,
-      "text": "throw new Error(`PDF ファイルが存在しません: ${pdfPath}`);"
+      "line": 211,
+      "text": "vectorizingFile: 'ファイルベクトル化中: ',"
     },
     {
-      "line": 43,
-      "text": "// 出力ディレクトリの作成"
+      "line": 212,
+      "text": "searchQuery: '検索クエリ: ',"
     },
     {
-      "line": 52,
-      "text": "// PDF の総ページ数を取得 - pdfinfo の代わりに pdf-lib を使用"
+      "line": 213,
+      "text": "modelCall: '[モデル呼び出し] タイプ: {type}, Model: {model}, ユーザー: {user}',"
     },
     {
-      "line": 58,
-      "text": "throw new Error('PDF のページ数を取得できません');"
+      "line": 214,
+      "text": "memoryStatus: 'メモリ状態: ',"
     },
     {
-      "line": 65,
-      "text": "// Python スクリプトを使用して変換"
+      "line": 215,
+      "text": "uploadSuccess: 'ファイルが正常にアップロードされました。バックグラウンドでインデックス処理を実行中です',"
     },
     {
-      "line": 75,
-      "text": "throw new Error(`Python での変換に失敗しました: ${result.error}`);"
+      "line": 216,
+      "text": "overlapAdjusted: 'オーバーラップサイズがChunk sizeの50%。自動的に {newSize} に調整されました',"
     },
     {
-      "line": 93,
-      "text": "// 一時ディレクトリのクリーンアップ"
+      "line": 217,
+      "text": "environmentLimit: '環境変数の制限',"
     },
     {
-      "line": 95,
-      "text": "throw new Error(`PDF から画像への変換に失敗しました: ${error.message}`);"
+      "line": 218,
+      "text": "modelLimit: 'モデルの制限',"
     },
     {
-      "line": 100,
-      "text": "* 複数の PDF を一括変換"
+      "line": 219,
+      "text": "configLoaded: 'データベースからモデル設定を読み込みました: {name} ({id})',"
     },
     {
-      "line": 117,
-      "text": "* 画像ファイルのクリーンアップ"
+      "line": 220,
+      "text": "batchSizeAdjusted: 'バッチサイズを {old} から {new} に調整しました (モデル制限: {limit})',"
     },
     {
-      "line": 129,
-      "text": "// 空のディレクトリのクリーンアップを試行"
+      "line": 221,
+      "text": "dimensionMismatch: 'モデル {id} の次元が一致しません: 期待値 {expected}, 実際 {actual}',"
     },
     {
-      "line": 137,
-      "text": "* ディレクトリのクリーンアップ"
+      "line": 222,
+      "text": "searchMetadataFailed: 'ユーザー {userId} のナレッジベース検索に失敗しました',"
     },
     {
-      "line": 152,
-      "text": "* 画像品質が妥当か確認"
-    }
-  ],
-  "d:\\workspace\\AuraK\\server\\src\\rag\\rag.service.ts": [
+      "line": 223,
+      "text": "extractedTextTooLarge: '抽出されたテキストが大きいです: {size}MB',"
+    },
     {
-      "line": 18,
-      "text": "originalScore?: number; // Rerank前のスコア(デバッグ用)"
+      "line": 224,
+      "text": "preciseModeUnsupported: 'ファイル形式 {ext} はPrecise Modeをサポートしていません。Fast Modeにフォールバックします',"
     },
     {
-      "line": 49,
-      "text": "vectorSimilarityThreshold: number = 0.3, // ベクトル検索のしきい値"
+      "line": 225,
+      "text": "visionModelNotConfiguredFallback: 'ビジョンモデルが設定されていません。Fast Modeにフォールバックします',"
     },
     {
-      "line": 56,
-      "text": "rerankSimilarityThreshold: number = 0.5, // Rerankのしきい値(デフォルト0.5)"
+      "line": 226,
+      "text": "visionModelInvalidFallback: 'ビジョンモデルの設定が無効です。Fast Modeにフォールバックします',"
     },
     {
-      "line": 61,
-      "text": "// 1. グローバル設定の取得"
+      "line": 227,
+      "text": "visionPipelineFailed: 'ビジョンパイプラインが失敗しました。Fast Modeにフォールバックします',"
     },
     {
-      "line": 64,
-      "text": "// パラメータが明示的に渡されていない場合はグローバル設定を使用"
+      "line": 228,
+      "text": "preciseModeComplete: 'Precise Mode内容抽出完了: {pages}ページ, コスト: ${cost}',"
     },
     {
-      "line": 81,
-      "text": "// 1. クエリの準備(拡張または HyDE)"
+      "line": 229,
+      "text": "skippingEmptyVectorPage: '第 {page} ページの空ベクトルをスキップします',"
     },
     {
-      "line": 86,
-      "text": "queriesToSearch = [hydeDoc]; // HyDE の場合は仮想ドキュメントをクエリとして使用"
+      "line": 230,
+      "text": "pdfPageImageError: 'PDF ページの画像取得に失敗しました: {message}',"
     },
     {
-      "line": 92,
-      "text": "// 埋め込みモデルIDが提供されているか確認"
+      "line": 231,
+      "text": "internalServerError: 'サーバー内部エラー',"
     },
     {
-      "line": 94,
-      "text": "throw new Error('埋め込みモデルIDが提供されていません');"
+      "line": 262,
+      "text": "searching: '正在搜索知识库...',"
     },
     {
-      "line": 97,
-      "text": "// 2. 複数のクエリに対して並列検索"
+      "line": 263,
+      "text": "noResults: '未找到相关知识,将基于一般知识回答...',"
     },
     {
-      "line": 99,
-      "text": "// クエリベクトルの取得"
+      "line": 264,
+      "text": "searchFailed: '知识库搜索失败,将基于一般知识回答...',"
     },
     {
-      "line": 107,
-      "text": "// 設定に基づいた検索戦略の選択"
+      "line": 265,
+      "text": "generatingResponse: '正在生成回答',"
     },
     {
-      "line": 139,
-      "text": "// 初回の類似度フィルタリング"
+      "line": 267,
+      "text": "notebooks: '个笔记本',"
     },
     {
-      "line": 142,
-      "text": "// ログ出力"
+      "line": 268,
+      "text": "all: '全部',"
     },
     {
-      "line": 147,
-      "text": "// 閾値フィルタリングを適用"
+      "line": 269,
+      "text": "items: '个',"
     },
     {
-      "line": 151,
-      "text": "// 3. リランク (Rerank)"
+      "line": 270,
+      "text": "searchResults: '搜索结果',"
     },
     {
-      "line": 162,
-      "text": "effectiveTopK * 2 // 少し多めに残す"
+      "line": 271,
+      "text": "relevantInfoFound: '条相关信息找到',"
     },
     {
-      "line": 169,
-      "text": "score: r.score, // Rerank スコア"
+      "line": 272,
+      "text": "searchHits: '搜索命中',"
     },
     {
-      "line": 170,
-      "text": "originalScore: originalItem.score // 元のスコア"
+      "line": 273,
+      "text": "relevance: '相关度',"
     },
     {
-      "line": 174,
-      "text": "// Rerank後のフィルタリング"
+      "line": 274,
+      "text": "sourceFiles: '源文件',"
     },
     {
-      "line": 181,
-      "text": "// 失敗した場合はベクトル検索の結果をそのまま使う"
+      "line": 275,
+      "text": "searchScope: '搜索范围',"
     },
     {
-      "line": 185,
-      "text": "// 最終的な件数制限"
+      "line": 276,
+      "text": "error: '错误',"
     },
     {
-      "line": 188,
-      "text": "// 4. RAG 結果形式に変換"
+      "line": 277,
+      "text": "creatingHistory: '创建新对话历史: ',"
     },
     {
-      "line": 213,
-      "text": "// コンテキストの構築"
+      "line": 278,
+      "text": "searchingModelById: '根据ID搜索模型: ',"
     },
     {
-      "line": 218,
-      "text": "// ファイルごとにグループ化"
+      "line": 279,
+      "text": "searchModelFallback: '未找到指定的嵌入模型。使用第一个可用模型。',"
     },
     {
-      "line": 227,
-      "text": "// コンテキスト文字列を構築"
+      "line": 280,
+      "text": "noEmbeddingModelFound: '找不到嵌入模型设置',"
     },
     {
-      "line": 246,
-      "text": "lang === 'zh' ? '中文' : lang === 'en' ? 'English' : '日本語';"
+      "line": 281,
+      "text": "usingEmbeddingModel: '使用的嵌入模型: ',"
     },
     {
-      "line": 276,
-      "text": "* 検索結果の重複排除"
+      "line": 282,
+      "text": "startingSearch: '开始搜索知识库...',"
     },
     {
-      "line": 290,
-      "text": "* クエリを拡張してバリエーションを生成"
+      "line": 283,
+      "text": "searchResultsCount: '搜索结果数: ',"
     },
     {
-      "line": 308,
-      "text": ".slice(0, 3); // 最大3つに制限"
+      "line": 284,
+      "text": "searchFailedLog: '搜索失败',"
     },
     {
-      "line": 319,
-      "text": "* 仮想的なドキュメント(HyDE)を生成"
+      "line": 285,
+      "text": "modelCall: '[模型调用]',"
     },
     {
-      "line": 342,
-      "text": "* 内部タスク用の LLM インスタンスを取得"
-    }
-  ],
-  "d:\\workspace\\AuraK\\server\\src\\rag\\rerank.service.ts": [
+      "line": 286,
+      "text": "chatStreamError: '聊天流错误',"
+    },
     {
-      "line": 23,
-      "text": "* リランクの実行"
+      "line": 287,
+      "text": "assistStreamError: '辅助流错误',"
     },
     {
-      "line": 24,
-      "text": "* @param query ユーザーのクエリ"
+      "line": 288,
+      "text": "file: '文件',"
     },
     {
-      "line": 25,
-      "text": "* @param documents 候補ドキュメントリスト"
+      "line": 289,
+      "text": "content: '内容',"
     },
     {
-      "line": 26,
-      "text": "* @param userId ユーザーID"
+      "line": 290,
+      "text": "userLabel: '用户',"
     },
     {
-      "line": 27,
-      "text": "* @param rerankModelId 選択された Rerank モデル設定ID"
+      "line": 291,
+      "text": "assistantLabel: '助手',"
     },
     {
-      "line": 28,
-      "text": "* @param topN 返す結果の数 (上位 N 個)"
+      "line": 292,
+      "text": "intelligentAssistant: '您是智能写作助手。',"
     },
     {
-      "line": 44,
-      "text": "// 1. モデル設定の取得"
+      "line": 293,
+      "text": "searchString: '搜索字符串: ',"
     },
     {
-      "line": 59,
-      "text": "// 2. API リクエストの構築 (OpenAI/SiliconFlow 互換 Rerank API)"
+      "line": 294,
+      "text": "embeddingModelIdNotProvided: '未提供嵌入模型ID',"
     },
     {
-      "line": 60,
-      "text": "// 注: 標準の OpenAI API には /rerank はありませんが、SiliconFlow/Jina/Cohere は同様の構造を使用しています"
+      "line": 295,
+      "text": "generatingEmbeddings: '生成嵌入向量...',"
     },
     {
-      "line": 61,
-      "text": "// SiliconFlow 形式: POST /v1/rerank { model, query, documents, top_n }"
+      "line": 296,
+      "text": "embeddingsGenerated: '嵌入向量生成完成',"
     },
     {
-      "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": 297,
+      "text": "dimensions: '维度',"
     },
     {
-      "line": 101,
-      "text": "// 画像MIMEタイプまたは拡張子によるチェック"
+      "line": 298,
+      "text": "performingHybridSearch: '执行混合搜索...',"
     },
     {
-      "line": 127,
-      "text": "// ファイルサイズの検証(フロントエンド制限 + バックエンド検証)"
+      "line": 299,
+      "text": "esSearchCompleted: 'ES搜索完成',"
     },
     {
-      "line": 137,
-      "text": "// 埋め込みモデル設定の検証"
+      "line": 300,
+      "text": "resultsCount: '结果数',"
     },
     {
-      "line": 143,
-      "text": "`ユーザー ${req.user.id} がファイルをアップロードしました: ${file.originalname} (${this.formatBytes(file.size)})`,"
+      "line": 301,
+      "text": "hybridSearchFailed: '混合搜索失败',"
     },
     {
-      "line": 148,
-      "text": "// 設定パラメータを解析し、安全なデフォルト値を設定"
+      "line": 302,
+      "text": "getContextForTopicFailed: '获取主题上下文失败',"
     },
     {
-      "line": 156,
-      "text": "// オーバーラップサイズがチャンクサイズの50%を超えないようにする"
+      "line": 303,
+      "text": "noLLMConfigured: '用户未配置LLM模型',"
     },
     {
-      "line": 164,
-      "text": "// データベースに保存し、インデックスプロセスをトリガー(非同期)"
+      "line": 304,
+      "text": "simpleChatGenerationError: '简单聊天生成错误',"
     },
     {
-      "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": 305,
+      "text": "noMatchInKnowledgeGroup: '所选知识组中未找到相关内容,以下是基于模型的一般性回答:',"
     },
     {
-      "line": 26,
-      "text": "// アップロードディレクトリが存在することを確認"
+      "line": 306,
+      "text": "uploadTextSuccess: '笔记内容已接收。正在后台索引',"
     },
     {
-      "line": 31,
-      "text": "// 環境変数から最大ファイルサイズ制限を取得、デフォルトは 100MB"
+      "line": 307,
+      "text": "passwordChanged: '密码已成功修改',"
     },
     {
-      "line": 48,
-      "text": "// 中国語ファイル名の文字化け問題を解決"
+      "line": 308,
+      "text": "userCreated: '用户已成功创建',"
     },
     {
-      "line": 62,
-      "text": "fileSize: maxFileSize, // ファイルサイズの制限"
-    }
-  ],
-  "d:\\workspace\\AuraK\\server\\src\\user\\user.controller.ts": [
-    {
-      "line": 161,
-      "text": "// 更新するユーザー情報を取得"
+      "line": 309,
+      "text": "userInfoUpdated: '用户信息已更新',"
     },
     {
-      "line": 206,
-      "text": "// 管理者が自身を削除するのを防止"
+      "line": 310,
+      "text": "userDeleted: '用户已删除',"
     },
     {
-      "line": 211,
-      "text": "// 削除するユーザー情報を取得"
+      "line": 311,
+      "text": "pdfNoteTitle: 'PDF 笔记 - {date}',"
     },
     {
-      "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": 312,
+      "text": "noTextExtracted: '未提取到文本',"
     },
     {
-      "line": 238,
-      "text": "// ユーザー名 \"admin\" のユーザーに対するいかなる変更も阻止"
+      "line": 313,
+      "text": "kbCleared: '知识库已清空',"
     },
     {
-      "line": 275,
-      "text": "// ユーザー名 \"admin\" のユーザーの削除を阻止"
+      "line": 314,
+      "text": "fileDeleted: '文件已删除',"
     },
     {
-      "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": 315,
+      "text": "pageImageNotFoundDetail: '无法获取 PDF 第 {page} 页’的图像',"
     },
     {
-      "line": 33,
-      "text": "// 2. グローバル設定がない場合、旧 'system' ユーザーから移行を試みる"
+      "line": 316,
+      "text": "groupSyncSuccess: '文件分组已更新',"
     },
     {
-      "line": 45,
-      "text": "// 3. 旧記録もない場合は、新規作成する"
+      "line": 317,
+      "text": "fileDeletedFromGroup: '文件已从分组中删除',"
     },
     {
-      "line": 114,
-      "text": "console.log('=== updateLanguage デバッグ ===');"
+      "line": 318,
+      "text": "chunkConfigCorrection: '切片配置已修正: {warnings}',"
     },
     {
-      "line": 130,
-      "text": "console.log('=== getLanguage デバッグ ===');"
+      "line": 319,
+      "text": "noChunksGenerated: '文件 {id} 未生成任何切片',"
     },
     {
-      "line": 140,
-      "text": "* システム全体のグローバル設定を取得する"
+      "line": 320,
+      "text": "chunkCountAnomaly: '实际切片数 {actual} 大幅超过预计值 {estimated},可能存在异常',"
     },
     {
-      "line": 148,
-      "text": "// 万が一存在しない場合は初期化"
+      "line": 321,
+      "text": "batchSizeExceeded: '批次 {index} 的大小 {actual} 超过推荐值 {limit},将拆分处理',"
     },
     {
-      "line": 156,
-      "text": "* システム全体のグローバル設定を更新する"
-    }
-  ],
-  "d:\\workspace\\AuraK\\server\\src\\vision\\vision.interface.ts": [
+      "line": 322,
+      "text": "skippingEmptyVectorChunk: '跳过文本块 {index} (空向量)',"
+    },
     {
-      "line": 2,
-      "text": "* Vision 服务接口定义"
+      "line": 323,
+      "text": "contextLengthErrorFallback: '批次处理发生上下文长度错误,降级到逐条处理模式',"
     },
     {
-      "line": 6,
-      "text": "text: string;              // 抽出されたテキスト内容"
+      "line": 324,
+      "text": "chunkLimitExceededForceBatch: '切片数 {actual} 超过模型批次限制 {limit},强制进行批次处理',"
     },
     {
-      "line": 7,
-      "text": "images: ImageDescription[]; // 画像の説明"
+      "line": 325,
+      "text": "noteContentRequired: '笔记内容是必填项',"
     },
     {
-      "line": 8,
-      "text": "layout: string;            // レイアウトの種類"
+      "line": 326,
+      "text": "imageAnalysisStarted: '正在使用模型 {id} 分析图像...',"
     },
     {
-      "line": 9,
-      "text": "confidence: number;        // 信頼度 (0-1)"
+      "line": 327,
+      "text": "batchAnalysisStarted: '正在分析 {count} 张图像...',"
     },
     {
-      "line": 10,
-      "text": "pageIndex?: number;        // 页码"
+      "line": 328,
+      "text": "pageAnalysisFailed: '第 {page} 页分析失败',"
     },
     {
-      "line": 14,
-      "text": "type: string;              // 图片类型 (图表/架构图/流程图等)"
+      "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": 15,
-      "text": "description: string;       // 详细描述"
+      "line": 330,
+      "text": "visionModelCall: '[模型调用] 类型: Vision, 模型: {model}, 页面: {page}',"
     },
     {
-      "line": 16,
-      "text": "position?: number;         // ページ内での位置"
+      "line": 331,
+      "text": "visionAnalysisSuccess: '✅ 视觉分析完成: {path}{page}, 文本长度: {textLen}, 图像数: {imgCount}, 布局: {layout}, 置信度: {confidence}%',"
     },
     {
-      "line": 30,
-      "text": "estimatedCost: number;     // 预估成本(美元)"
-    }
-  ],
-  "d:\\workspace\\AuraK\\server\\src\\vision\\vision.service.ts": [
+      "line": 332,
+      "text": "conversationHistoryNotFound: '对话历史不存在',"
+    },
     {
-      "line": 19,
-      "text": "* 単一画像の分析(ドキュメントページ)"
+      "line": 333,
+      "text": "batchContextLengthErrorFallback: '小文件批次处理发生上下文长度错误,降级到逐条处理模式',"
     },
     {
-      "line": 27,
-      "text": "const baseDelay = 3000; // 3秒の基礎遅延"
+      "line": 334,
+      "text": "chunkProcessingFailed: '处理文本块 {index} 失败,已跳过: {message}',"
     },
     {
-      "line": 39,
-      "text": "const delay = baseDelay + Math.random() * 2000; // 3-5秒のランダムな遅延"
+      "line": 335,
+      "text": "singleTextProcessingComplete: '逐条文本处理完成: {count} 个切片',"
     },
     {
-      "line": 48,
-      "text": "// この行は理論的には実行されませんが、TypeScript の要求を満たすために記述しています"
+      "line": 336,
+      "text": "fileVectorizationComplete: '文件 {id} 向量化完成。共处理 {count} 个文本块。最终内存: {memory}MB',"
     },
     {
-      "line": 53,
-      "text": "* 実際の画像分析を実行"
+      "line": 337,
+      "text": "fileVectorizationFailed: '文件 {id} 向量化失败',"
     },
     {
-      "line": 61,
-      "text": "// 画像を読み込み、base64 に変換"
+      "line": 338,
+      "text": "batchProcessingStarted: '开始批次处理: {count} 个项目',"
     },
     {
-      "line": 66,
-      "text": "// ビジョンモデルのインスタンスを作成"
+      "line": 339,
+      "text": "batchProcessingProgress: '正在处理批次 {index}/{total}: {count} 个项目',"
     },
     {
-      "line": 73,
-      "text": "temperature: 0.1, // ランダム性を抑え、一貫性を高める"
+      "line": 340,
+      "text": "batchProcessingComplete: '批次处理完成: {count} 个项目,耗时 {duration}s',"
     },
     {
-      "line": 76,
-      "text": "// 専門的なドキュメント分析プロンプトを構築"
+      "line": 341,
+      "text": "onlyFailedFilesRetryable: '仅允许重试失败的文件 (当前状态: {status})',"
     },
     {
-      "line": 94,
-      "text": "// モデルの呼び出し"
+      "line": 342,
+      "text": "emptyFileRetryFailed: '文件内容为空,无法重试。请重新上传文件。',"
     },
     {
-      "line": 99,
-      "text": "// JSON の解析を試行"
+      "line": 343,
+      "text": "ragSystemPrompt: '您是专业的知识库助手。请根据以下提供的文档内容回答用户的问题。',"
     },
     {
-      "line": 102,
-      "text": "// Markdown のコードブロックタグをクリーンアップ"
+      "line": 344,
+      "text": "ragRules: '## 规则:\\n1. 仅根据提供的文档内容进行回答,请勿编造信息。\\n2. 如果文档中没有相关信息,请告知用户。\\n3. 请在回答中注明信息来源。格式:[文件名.扩展子]\\n4. 如果多个文档中的信息存在矛盾,请进行综合分析或解释不同的观点。\\n5. 请使用{lang}进行回答。',"
     },
     {
-      "line": 114,
-      "text": "// 解析に失敗した場合は、内容全体をテキストとして扱う"
+      "line": 345,
+      "text": "ragDocumentContent: '## 文档内容:',"
     },
     {
-      "line": 128,
-      "text": "page: pageIndex ? ` (第 ${pageIndex} ページ)` : '',"
+      "line": 346,
+      "text": "ragUserQuestion: '## 用户问题:',"
     },
     {
-      "line": 138,
-      "text": "throw error; // 重新抛出错误供重试机制处理"
+      "line": 347,
+      "text": "ragAnswer: '## 回答:',"
     },
     {
-      "line": 143,
-      "text": "* 再試行可能なエラーかどうかを判断"
+      "line": 348,
+      "text": "ragSource: '### 来源:{fileName}',"
     },
     {
-      "line": 149,
-      "text": "// 429 レート制限エラー"
+      "line": 349,
+      "text": "ragSegment: '片段 {index} (相似度: {score}):',"
     },
     {
-      "line": 150,
-      "text": "if (errorCode === 429 || errorMessage.includes('rate limit') || errorMessage.includes('リクエストが多すぎます')) {"
+      "line": 350,
+      "text": "ragNoDocumentFound: '未找到相关文档。',"
     },
     {
-      "line": 154,
-      "text": "// 5xx サーバーエラー"
+      "line": 351,
+      "text": "queryExpansionPrompt: '您是一个搜索助手。请为以下用户查询生成3个不同的演变版本,以帮助在向量搜索中获得更好的结果。每个版本应包含不同的关键词或表达方式,但保持原始意思。直接输出3行查询,不要有数字或编号:\\n\\n查询:{query}',"
     },
     {
-      "line": 159,
-      "text": "// ネットワーク関連エラー"
+      "line": 352,
+      "text": "hydePrompt: '请为以下用户问题写一段简短、事实性的假设回答(约100字)。不要包含任何引导性文字(如“基于我的分析...”),直接输出答案内容。\\n\\n问题:{query}',"
     },
     {
-      "line": 168,
-      "text": "* 遅延関数"
+      "line": 355,
+      "text": "searching: 'ナレッジベースを検索中...',"
     },
     {
-      "line": 175,
-      "text": "* 複数画像の一括分析"
+      "line": 356,
+      "text": "noResults: '関連する知識が見つかりませんでした。一般的な知識に基づいて回答します...',"
     },
     {
-      "line": 201,
-      "text": "// 進捗コールバックを呼び出し"
+      "line": 357,
+      "text": "searchFailed: 'ナレッジベース検索に失敗しました。一般的な知識に基づいて回答します...',"
     },
     {
-      "line": 206,
-      "text": "// 品質チェック(スキップ時は直接分析)"
+      "line": 358,
+      "text": "generatingResponse: '回答を生成中',"
     },
     {
-      "line": 234,
-      "text": "// 結果付きで進捗コールバックを呼び出し"
+      "line": 359,
+      "text": "files: '個のファイル',"
     },
     {
-      "line": 244,
-      "text": "// 推定コストの計算(1枚あたり $0.01 と仮定)"
+      "line": 360,
+      "text": "notebooks: '個のノートブック',"
     },
     {
-      "line": 263,
-      "text": "* 画像品質のチェック"
+      "line": 361,
+      "text": "all: 'すべて',"
     },
     {
-      "line": 270,
-      "text": "// ファイルサイズのチェック(5KB以上)"
+      "line": 362,
+      "text": "items: '件',"
     },
     {
-      "line": 272,
-      "text": "return { isGood: false, reason: `ファイルが小さすぎます (${sizeKB.toFixed(2)}KB)`, score: 0 };"
+      "line": 364,
+      "text": "relevantInfoFound: '件の関連情報が見つかりました',"
     },
     {
-      "line": 275,
-      "text": "// ファイルサイズ上限のチェック(10MB)"
+      "line": 365,
+      "text": "searchHits: '検索ヒット',"
     },
     {
-      "line": 277,
-      "text": "return { isGood: false, reason: `ファイルが大きすぎます (${sizeKB.toFixed(2)}KB)`, score: 0 };"
+      "line": 366,
+      "text": "relevance: '関連度',"
     },
     {
-      "line": 280,
-      "text": "// 簡易的な品質スコアリング"
+      "line": 367,
+      "text": "sourceFiles: '元ファイル',"
     },
     {
-      "line": 295,
-      "text": "* サポートされている画像ファイルかどうかを確認"
+      "line": 368,
+      "text": "searchScope: '検索範囲',"
     },
     {
-      "line": 310,
-      "text": "* MIME タイプを取得"
+      "line": 369,
+      "text": "error: 'エラー',"
     },
     {
-      "line": 328,
-      "text": "* 旧インターフェース互換:単一画像の内容を抽出"
-    }
-  ],
-  "d:\\workspace\\AuraK\\server\\src\\vision-pipeline\\cost-control.service.ts": [
-    {
-      "line": 2,
-      "text": "* コスト制御およびクォータ管理サービス"
+      "line": 370,
+      "text": "creatingHistory: '新規対話履歴を作成: ',"
     },
     {
-      "line": 3,
-      "text": "* Vision Pipeline の API 呼び出しコストを管理するために使用されます"
+      "line": 371,
+      "text": "searchingModelById: 'selectedEmbeddingId に基づいてモデルを検索: ',"
     },
     {
-      "line": 14,
-      "text": "monthlyCost: number;      // 今月の使用済みコスト"
+      "line": 372,
+      "text": "searchModelFallback: '指定された埋め込みモデルが見つかりません。最初に使用可能なモデルを使用します。',"
     },
     {
-      "line": 15,
-      "text": "maxCost: number;          // 月間最大コスト"
+      "line": 373,
+      "text": "noEmbeddingModelFound: '埋め込みモデルの設定が見つかりません',"
     },
     {
-      "line": 16,
-      "text": "remaining: number;        // 残りコスト"
+      "line": 374,
+      "text": "usingEmbeddingModel: '使用する埋め込みModel: ',"
     },
     {
-      "line": 17,
-      "text": "lastReset: Date;          // 最終リセット時間"
+      "line": 375,
+      "text": "startingSearch: 'ナレッジベースの検索を開始...',"
     },
     {
-      "line": 21,
-      "text": "estimatedCost: number;    // 推定コスト"
+      "line": 376,
+      "text": "searchResultsCount: 'Search results数: ',"
     },
     {
-      "line": 22,
-      "text": "estimatedTime: number;    // 推定時間(秒)"
+      "line": 377,
+      "text": "searchFailedLog: '検索失敗',"
     },
     {
-      "line": 23,
-      "text": "pageBreakdown: {          // ページごとの明細"
+      "line": 378,
+      "text": "chatStreamError: 'チャットストリームエラー',"
     },
     {
-      "line": 32,
-      "text": "private readonly COST_PER_PAGE = 0.01; // 1ページあたりのコスト(USD)"
+      "line": 379,
+      "text": "assistStreamError: 'アシストストリームエラー',"
     },
     {
-      "line": 33,
-      "text": "private readonly DEFAULT_MONTHLY_LIMIT = 100; // デフォルトの月間制限(USD)"
+      "line": 380,
+      "text": "file: 'ファイル',"
     },
     {
-      "line": 42,
-      "text": "* 処理コストの推定"
+      "line": 381,
+      "text": "content: '内容',"
     },
     {
-      "line": 45,
-      "text": "// 品質に基づいてコスト係数を調整"
+      "line": 382,
+      "text": "userLabel: 'ユーザー',"
     },
     {
-      "line": 53,
-      "text": "const estimatedTime = pageCount * 3; // 1ページあたり約 3 秒"
+      "line": 383,
+      "text": "assistantLabel: 'アシスタント',"
     },
     {
-      "line": 68,
-      "text": "* ユーザーのクォータをチェック"
+      "line": 384,
+      "text": "intelligentAssistant: 'あなたはインテリジェントな執筆アシスタントです。',"
     },
     {
-      "line": 77,
-      "text": "// 月間リセットのチェック"
+      "line": 385,
+      "text": "searchString: '検索文字列: ',"
     },
     {
-      "line": 87,
-      "text": "reason: `クォータ不足: 残り $${quota.remaining.toFixed(2)}, 必要 $${estimatedCost.toFixed(2)}`,"
+      "line": 386,
+      "text": "embeddingModelIdNotProvided: 'Embedding model IDが提供されていません',"
     },
     {
-      "line": 98,
-      "text": "* クォータの差し引き"
+      "line": 387,
+      "text": "generatingEmbeddings: '埋め込みベクトルを生成中...',"
     },
     {
-      "line": 115,
-      "text": "* ユーザーのクォータを取得"
+      "line": 388,
+      "text": "embeddingsGenerated: '埋め込みベクトルの生成が完了しました',"
     },
     {
-      "line": 121,
-      "text": "throw new Error(`ユーザー ${userId} は存在しません`);"
+      "line": 389,
+      "text": "dimensions: '次元数',"
     },
     {
-      "line": 124,
-      "text": "// ユーザーにクォータ情報がない場合はデフォルト値を使用"
+      "line": 390,
+      "text": "performingHybridSearch: 'ES 混合検索を実行中...',"
     },
     {
-      "line": 139,
-      "text": "* 月間クォータのチェックとリセット"
+      "line": 391,
+      "text": "esSearchCompleted: 'ES 検索が完了しました',"
     },
     {
-      "line": 145,
-      "text": "// 月を跨いでいるかチェック"
+      "line": 392,
+      "text": "resultsCount: '結果数',"
     },
     {
-      "line": 152,
-      "text": "// クォータをリセット"
+      "line": 393,
+      "text": "hybridSearchFailed: '混合検索に失敗しました',"
     },
     {
-      "line": 157,
-      "text": "// データベースを更新"
+      "line": 394,
+      "text": "getContextForTopicFailed: 'トピックのコンテキスト取得に失敗しました',"
     },
     {
-      "line": 166,
-      "text": "* ユーザーのクォータ制限を設定"
+      "line": 395,
+      "text": "noLLMConfigured: 'ユーザーにLLMモデルが設定されていません',"
     },
     {
-      "line": 174,
-      "text": "* コストレポートの取得"
+      "line": 396,
+      "text": "simpleChatGenerationError: '簡易チャット生成エラー',"
     },
     {
-      "line": 183,
-      "text": "quotaUsage: number; // パーセンテージ"
+      "line": 397,
+      "text": "noMatchInKnowledgeGroup: '選択された知識グループに関連する内容が見つかりませんでした。以下はモデルに基づく一般的な回答です:',"
     },
     {
-      "line": 188,
-      "text": "// ここで履歴レコードを照会できます(実装されている場合)"
+      "line": 398,
+      "text": "uploadTextSuccess: 'ノート内容を受け取りました。バックグラウンドでインデックス処理を実行中です',"
     },
     {
-      "line": 189,
-      "text": "// 暫定的に現在のクォータ情報を返します"
+      "line": 399,
+      "text": "passwordChanged: 'パスワードが正常に変更されました',"
     },
     {
-      "line": 203,
-      "text": "* コスト警告閾値のチェック"
+      "line": 400,
+      "text": "userCreated: 'ユーザーが正常に作成されました',"
     },
     {
-      "line": 215,
-      "text": "message: `⚠️ クォータ使用率が ${usagePercent.toFixed(1)}% に達しました。残り $${quota.remaining.toFixed(2)}`,"
+      "line": 401,
+      "text": "userInfoUpdated: 'ユーザー情報が更新されました',"
     },
     {
-      "line": 222,
-      "text": "message: `💡 クォータ使用率 ${usagePercent.toFixed(1)}%。コストの管理に注意してください`,"
+      "line": 402,
+      "text": "userDeleted: 'ユーザーが削除されました',"
     },
     {
-      "line": 233,
-      "text": "* コスト表示のフォーマット"
+      "line": 403,
+      "text": "pdfNoteTitle: 'PDF ノート - {date}',"
     },
     {
-      "line": 240,
-      "text": "* 時間表示のフォーマット"
+      "line": 404,
+      "text": "noTextExtracted: 'テキストが抽出されませんでした',"
     },
     {
-      "line": 244,
-      "text": "return `${seconds.toFixed(0)}秒`;"
+      "line": 405,
+      "text": "kbCleared: 'ナレッジベースが空になりました',"
     },
     {
-      "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": 406,
+      "text": "fileDeleted: 'ファイルが削除されました',"
     },
     {
-      "line": 3,
-      "text": "* これは vision-pipeline.service.ts の拡張版であり、コスト制御が統合されています"
+      "line": 407,
+      "text": "pageImageNotFoundDetail: 'PDF の第 {page} ページの画像を取得できません',"
     },
     {
-      "line": 30,
-      "text": "private costControl: CostControlService, // 新增成本控制服务"
+      "line": 408,
+      "text": "groupSyncSuccess: 'ファイルグループが更新されました',"
     },
     {
-      "line": 34,
-      "text": "* メイン処理フロー:精密モード(コスト制御付き)"
+      "line": 409,
+      "text": "fileDeletedFromGroup: 'ファイルがグループから削除されました',"
     },
     {
-      "line": 53,
-      "text": "// ステップ 1: 形式の統一"
+      "line": 410,
+      "text": "chunkConfigCorrection: 'Chunk configurationの修正: {warnings}',"
     },
     {
-      "line": 54,
-      "text": "this.updateStatus('converting', 10, 'ドキュメント形式を変換中...');"
+      "line": 411,
+      "text": "noChunksGenerated: 'ファイル {id} からテキストチャンクが生成されませんでした',"
     },
     {
-      "line": 57,
-      "text": "// ステップ 2: PDF から画像への変換"
+      "line": 412,
+      "text": "chunkCountAnomaly: '実際のチャンク数 {actual} が推定値 {estimated} を大幅に超えています。異常がある可能性があります',"
     },
     {
-      "line": 58,
-      "text": "this.updateStatus('splitting', 30, 'PDF を画像に変換中...');"
+      "line": 413,
+      "text": "batchSizeExceeded: 'バッチ {index} のサイズ {actual} が推奨値 {limit} 。分割して処理します',"
     },
     {
-      "line": 66,
-      "text": "throw new Error('PDF から画像への変換に失敗しました。画像が生成されませんでした');"
+      "line": 414,
+      "text": "skippingEmptyVectorChunk: '空ベクトルのテキストブロック {index} をスキップします',"
     },
     {
-      "line": 69,
-      "text": "// 限制处理页数"
+      "line": 415,
+      "text": "contextLengthErrorFallback: 'バッチ処理でコンテキスト長エラーが発生しました。単一テキスト処理モードにダウングレードします',"
     },
     {
-      "line": 76,
-      "text": "// ステップ 3: コスト見積もりとクォータチェック"
+      "line": 416,
+      "text": "chunkLimitExceededForceBatch: 'チャンク数 {actual} がモデルのバッチ制限 {limit} 。強制的にバッチ処理を行います',"
     },
     {
-      "line": 77,
-      "text": "this.updateStatus('checking', 40, 'クォータを確認し、コストを見積もり中...');"
+      "line": 417,
+      "text": "noteContentRequired: 'ノート内容は必須です',"
     },
     {
-      "line": 83,
-      "text": "// クォータチェック"
+      "line": 418,
+      "text": "imageAnalysisStarted: 'モデル {id} で画像をAnalyzing...',"
     },
     {
-      "line": 93,
-      "text": "// コスト警告チェック"
+      "line": 419,
+      "text": "batchAnalysisStarted: '{count} 枚の画像をAnalyzing...',"
     },
     {
-      "line": 99,
-      "text": "// ステップ 4: Vision モデル設定の取得"
+      "line": 420,
+      "text": "pageAnalysisFailed: '第 {page} ページの分析に失敗しました',"
     },
     {
-      "line": 102,
-      "text": "// ステップ 5: VL モデル分析"
+      "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": 103,
-      "text": "this.updateStatus('analyzing', 50, 'ビジョンモデルを使用してページを分析中...');"
+      "line": 422,
+      "text": "visionModelCall: '[モデル呼び出し] タイプ: Vision, Model: {model}, ページ: {page}',"
     },
     {
-      "line": 118,
-      "text": "// ステップ 6: 実際のコストを差し引く"
+      "line": 423,
+      "text": "visionAnalysisSuccess: '✅ Vision 分析完了: {path}{page}, テキスト長: {textLen}文字, 画像数: {imgCount}, レイアウト: {layout}, 信頼度: {confidence}%',"
     },
     {
-      "line": 124,
-      "text": "// ステップ 7: 一時ファイルのクリーンアップ"
+      "line": 424,
+      "text": "conversationHistoryNotFound: '会話履歴が存在しません',"
     },
     {
-      "line": 125,
-      "text": "this.updateStatus('completed', 100, '処理が完了しました。一時ファイルをクリーンアップ中...');"
+      "line": 425,
+      "text": "batchContextLengthErrorFallback: '小ファイルバッチ処理でコンテキスト長エラーが発生しました。単一テキスト処理モードにダウングレードします',"
     },
     {
-      "line": 128,
-      "text": "// PDF に変換した場合、変換後のファイルをクリーンアップ"
+      "line": 426,
+      "text": "chunkProcessingFailed: 'テキストブロック {index} の処理に失敗しました。スキップします: {message}',"
     },
     {
-      "line": 159,
-      "text": "// 尝试清理临时文件"
+      "line": 427,
+      "text": "singleTextProcessingComplete: '単一テキスト処理完了: {count} チャンク',"
     },
     {
-      "line": 185,
-      "text": "* Vision モデル設定の取得"
+      "line": 428,
+      "text": "fileVectorizationComplete: 'ファイル {id} ベクトル化完了。{count} 個のテキストブロックを処理しました。最終メモリ: {memory}MB',"
     },
     {
-      "line": 191,
-      "text": "throw new Error(`モデル設定が見つかりません: ${modelId}`);"
+      "line": 429,
+      "text": "fileVectorizationFailed: 'ファイル {id} ベクトル化失敗',"
     },
     {
-      "line": 194,
-      "text": "// APIキーはオプションです - ローカルモデルを許可します"
+      "line": 430,
+      "text": "batchProcessingStarted: 'バッチ処理を開始します: {count} アイテム',"
     },
     {
-      "line": 204,
-      "text": "* PDF への変換"
+      "line": 431,
+      "text": "batchProcessingProgress: 'バッチ {index}/{total} を処理中: {count} 個のアイテム',"
     },
     {
-      "line": 209,
-      "text": "// 既に PDF の場合はそのまま返す"
+      "line": 432,
+      "text": "batchProcessingComplete: 'バッチ処理完了: {count} アイテム, 所要時間 {duration}s',"
     },
     {
-      "line": 214,
-      "text": "// LibreOffice を呼び出して変換"
+      "line": 433,
+      "text": "onlyFailedFilesRetryable: '失敗したファイルのみ再試行可能です (現在のステータス: {status})',"
     },
     {
-      "line": 219,
-      "text": "* 形式検出とモードの推奨(コスト見積もり付き)"
+      "line": 434,
+      "text": "emptyFileRetryFailed: 'ファイル内容が空です。再試行できません。ファイルを再アップロードしてください。',"
     },
     {
-      "line": 232,
-      "text": "reason: `サポートされていないファイル形式です: ${ext}`,"
+      "line": 435,
+      "text": "ragSystemPrompt: 'あなたは専門的なナレッジベースアシスタントです。以下の提供されたドキュメントの内容に基づいて、ユーザーの質問に答えてください。',"
     },
     {
-      "line": 233,
-      "text": "warnings: ['高速モード(テキスト抽出のみ)を使用します'],"
+      "line": 436,
+      "text": "ragRules: '## ルール:\\n1. 提供されたドキュメントの内容のみに基づいて回答し、情報を捏造しないでください。\\n2. ドキュメントに関連情報がない場合は、その旨をユーザーに伝えてください。\\n3. 回答には情報源を明記してください。形式:[ファイル名.拡張子]\\n4. 複数のドキュメントで情報が矛盾している場合は、総合的に分析するか、異なる視点を説明してください。\\n5. {lang}で回答してください。',"
     },
     {
-      "line": 240,
-      "text": "reason: `形式 ${ext} は精密モードをサポートしていません`,"
+      "line": 437,
+      "text": "ragDocumentContent: '## ドキュメント内容:',"
     },
     {
-      "line": 241,
-      "text": "warnings: ['高速モード(テキスト抽出のみ)を使用します'],"
+      "line": 438,
+      "text": "ragUserQuestion: '## ユーザーの質問:',"
     },
     {
-      "line": 245,
-      "text": "// ページ数の見積もり(ファイルサイズに基づく)"
+      "line": 439,
+      "text": "ragAnswer: '## 回答:',"
     },
     {
-      "line": 249,
-      "text": "// ファイルサイズが大きい場合は精密モードを推奨"
+      "line": 440,
+      "text": "ragSource: '### ソース:{fileName}',"
     },
     {
-      "line": 253,
-      "text": "reason: 'ファイルが大きいため、完全な情報を保持するために精密モードを推奨します',"
+      "line": 441,
+      "text": "ragSegment: 'セグメント {index} (類似度: {score}):',"
     },
     {
-      "line": 256,
-      "text": "warnings: ['処理時間が長くなる可能性があります', 'API 費用が発生します'],"
+      "line": 442,
+      "text": "ragNoDocumentFound: '関連するドキュメントが見つかりませんでした。',"
     },
     {
-      "line": 260,
-      "text": "// 精密モードを推奨"
+      "line": 443,
+      "text": "queryExpansionPrompt: 'あなたは検索アシスタントです。以下のユーザーのクエリに対して、ベクトル検索でより良い結果を得るために、3つの異なるバリエーションを生成してください。各バリエーションは異なるキーワードや表現を使用しつつ、元の意味を維持する必要があります。数字やプレフィックスなしで、3行のクエリを直接出力してください:\\n\\nクエリ:{query}',"
     },
     {
-      "line": 263,
-      "text": "reason: '精密モードが利用可能です。テキストと画像の混合コンテンツを保持できます',"
+      "line": 444,
+      "text": "hydePrompt: '以下のユーザーの質問に対して、簡潔で事実に基づいた仮説的な回答(約200文字)を書いてください。「私の分析によると...」などの導入文は含めず、回答内容のみを直接出力してください。\\n\\n質問:{query}',"
+    }
+  ],
+  "d:\\workspace\\AuraK\\server\\src\\knowledge-base\\chunk-config.service.ts": [
+    {
+      "line": 76,
+      "text": "const providerName = modelConfig.providerName || '不明';"
     },
     {
-      "line": 266,
-      "text": "warnings: ['API 費用が発生します'],"
+      "line": 81,
+      "text": "`  - プロバイダー: ${providerName}\\n` +"
     },
     {
-      "line": 271,
-      "text": "* ユーザーのクォータ情報を取得"
+      "line": 82,
+      "text": "`  - Token制限: ${maxInputTokens}\\n` +"
     },
     {
-      "line": 285,
-      "text": "* 処理状態の更新(リアルタイムフィードバック用)"
-    }
-  ],
-  "d:\\workspace\\AuraK\\server\\src\\vision-pipeline\\vision-pipeline.interface.ts": [
+      "line": 85,
+      "text": "`  - ベクトルモデルか: ${isVectorModel}`,"
+    },
     {
-      "line": 2,
-      "text": "* Vision Pipeline 接口定义"
+      "line": 294,
+      "text": "`Chunk size: ${chunkSize} tokens (制限: ${limits.maxInputTokens})`,"
     },
     {
-      "line": 26,
-      "text": "duration: number; // 秒"
+      "line": 295,
+      "text": "`重なりサイズ: ${chunkOverlap} tokens`,"
     },
     {
-      "line": 47,
-      "text": "estimatedTime?: number; // 秒"
+      "line": 296,
+      "text": "`バッチサイズ: ${limits.maxBatchSize}`,"
     }
   ]
 }

+ 50 - 0
cjk_files.txt

@@ -0,0 +1,50 @@
+d:\workspace\AuraK\web\components\GroupSelector.tsx
+d:\workspace\AuraK\web\services\chunkConfigService.ts
+d:\workspace\AuraK\web\services\geminiService.ts
+d:\workspace\AuraK\web\services\knowledgeGroupService.ts
+d:\workspace\AuraK\web\services\pdfPreviewService.ts
+d:\workspace\AuraK\web\services\ragService.ts
+d:\workspace\AuraK\web\services\searchHistoryService.ts
+d:\workspace\AuraK\web\services\uploadService.ts
+d:\workspace\AuraK\web\src\utils\toast.ts
+d:\workspace\AuraK\web\types.ts
+d:\workspace\AuraK\server\src\ai\embedding.service.ts
+d:\workspace\AuraK\server\src\api\api.controller.ts
+d:\workspace\AuraK\server\src\api\api.service.ts
+d:\workspace\AuraK\server\src\chat\chat.controller.ts
+d:\workspace\AuraK\server\src\chat\chat.service.ts
+d:\workspace\AuraK\server\src\common\constants.ts
+d:\workspace\AuraK\server\src\elasticsearch\elasticsearch.service.ts
+d:\workspace\AuraK\server\src\i18n\i18n.service.ts
+d:\workspace\AuraK\server\src\i18n\messages.ts
+d:\workspace\AuraK\server\src\knowledge-base\chunk-config.service.ts
+d:\workspace\AuraK\server\src\knowledge-base\embedding.service.ts
+d:\workspace\AuraK\server\src\knowledge-base\knowledge-base.controller.ts
+d:\workspace\AuraK\server\src\knowledge-base\knowledge-base.entity.ts
+d:\workspace\AuraK\server\src\knowledge-base\knowledge-base.service.ts
+d:\workspace\AuraK\server\src\knowledge-base\memory-monitor.service.ts
+d:\workspace\AuraK\server\src\knowledge-base\text-chunker.service.ts
+d:\workspace\AuraK\server\src\libreoffice\libreoffice.interface.ts
+d:\workspace\AuraK\server\src\libreoffice\libreoffice.service.ts
+d:\workspace\AuraK\server\src\migrations\1737800000000-AddKnowledgeBaseEnhancements.ts
+d:\workspace\AuraK\server\src\model-config\dto\create-model-config.dto.ts
+d:\workspace\AuraK\server\src\model-config\model-config.entity.ts
+d:\workspace\AuraK\server\src\model-config\model-config.service.ts
+d:\workspace\AuraK\server\src\pdf2image\pdf2image.interface.ts
+d:\workspace\AuraK\server\src\pdf2image\pdf2image.service.ts
+d:\workspace\AuraK\server\src\rag\rag.service.ts
+d:\workspace\AuraK\server\src\rag\rerank.service.ts
+d:\workspace\AuraK\server\src\search-history\search-history.controller.ts
+d:\workspace\AuraK\server\src\search-history\search-history.service.ts
+d:\workspace\AuraK\server\src\upload\upload.controller.ts
+d:\workspace\AuraK\server\src\upload\upload.module.ts
+d:\workspace\AuraK\server\src\user\user.controller.ts
+d:\workspace\AuraK\server\src\user\user.entity.ts
+d:\workspace\AuraK\server\src\user\user.service.ts
+d:\workspace\AuraK\server\src\user-setting\user-setting.entity.ts
+d:\workspace\AuraK\server\src\user-setting\user-setting.service.ts
+d:\workspace\AuraK\server\src\vision\vision.interface.ts
+d:\workspace\AuraK\server\src\vision\vision.service.ts
+d:\workspace\AuraK\server\src\vision-pipeline\cost-control.service.ts
+d:\workspace\AuraK\server\src\vision-pipeline\vision-pipeline-cost-aware.service.ts
+d:\workspace\AuraK\server\src\vision-pipeline\vision-pipeline.interface.ts

+ 45 - 45
docker-compose.yml

@@ -58,52 +58,52 @@ services:
   #     echo 'All models pulled successfully!' && 
   #     wait"
 
-  server:
-    build:
-      context: ./server
-      dockerfile: Dockerfile
-    container_name: aurak-server
-    environment:
-      - NODE_ENV=production
-      - NODE_OPTIONS=--max-old-space-size=8192
-      - PORT=3001
-      - DATABASE_PATH=/app/data/metadata.db
-      - ELASTICSEARCH_HOST=http://es:9200
-      - TIKA_HOST=http://tika:9998
-      - LIBREOFFICE_URL=http://libreoffice:8100
-      - JWT_SECRET=13405a7d-742a-41f5-8b34-012735acffea
-      - UPLOAD_FILE_PATH=/app/uploads
-      - DEFAULT_VECTOR_DIMENSIONS=2048
-      - TEMP_DIR=/app/temp
-      - CHUNK_BATCH_SIZE=50
-    volumes:
-      - ./data:/app/data
-      - ./uploads:/app/uploads
-      - ./temp:/app/temp
-    depends_on:
-      - es
-      - tika
-      - libreoffice
-    #    restart: unless-stopped
-    networks:
-      - aurak-network
+  # server:
+  #   build:
+  #     context: ./server
+  #     dockerfile: Dockerfile
+  #   container_name: aurak-server
+  #   environment:
+  #     - NODE_ENV=production
+  #     - NODE_OPTIONS=--max-old-space-size=8192
+  #     - PORT=3001
+  #     - DATABASE_PATH=/app/data/metadata.db
+  #     - ELASTICSEARCH_HOST=http://es:9200
+  #     - TIKA_HOST=http://tika:9998
+  #     - LIBREOFFICE_URL=http://libreoffice:8100
+  #     - JWT_SECRET=13405a7d-742a-41f5-8b34-012735acffea
+  #     - UPLOAD_FILE_PATH=/app/uploads
+  #     - DEFAULT_VECTOR_DIMENSIONS=2048
+  #     - TEMP_DIR=/app/temp
+  #     - CHUNK_BATCH_SIZE=50
+  #   volumes:
+  #     - ./data:/app/data
+  #     - ./uploads:/app/uploads
+  #     - ./temp:/app/temp
+  #   depends_on:
+  #     - es
+  #     - tika
+  #     - libreoffice
+  #   #    restart: unless-stopped
+  #   networks:
+  #     - aurak-network
 
-  web:
-    build:
-      context: .
-      dockerfile: ./web/Dockerfile
-      args:
-        - VITE_API_BASE_URL=/api
-    container_name: aurak-web
-    depends_on:
-      - server
-    ports:
-      - "80:80"
-      - "443:443"
-    volumes:
-      - ./nginx/conf.d:/etc/nginx/conf.d
-    networks:
-      - aurak-network
+  # web:
+  #   build:
+  #     context: .
+  #     dockerfile: ./web/Dockerfile
+  #     args:
+  #       - VITE_API_BASE_URL=/api
+  #   container_name: aurak-web
+  #   depends_on:
+  #     - server
+  #   ports:
+  #     - "80:80"
+  #     - "443:443"
+  #   volumes:
+  #     - ./nginx/conf.d:/etc/nginx/conf.d
+  #   networks:
+  #     - aurak-network
 
 networks:
   aurak-network:

+ 4 - 0
remaining_4.txt

@@ -0,0 +1,4 @@
+d:\workspace\AuraK\web\components\GroupSelector.tsx
+d:\workspace\AuraK\web\services\geminiService.ts
+d:\workspace\AuraK\server\src\chat\chat.controller.ts
+d:\workspace\AuraK\server\src\vision-pipeline\cost-control.service.ts

二進制
remaining_cjk.txt


二進制
server/build_output.txt


+ 6 - 6
server/src/ai/embedding.service.ts

@@ -8,24 +8,24 @@ export class EmbeddingService {
 
   async getEmbeddings(text: string, config: ModelConfig): Promise<number[]> {
     try {
-      // ほとんどの設定が OpenAI インターフェースと互換性があると仮定
+      
       const embeddings = new OpenAIEmbeddings({
-        openAIApiKey: config.apiKey || 'ollama', // ローカルモデルの場合は key が不要な場合がある
+        openAIApiKey: config.apiKey || 'ollama', 
         configuration: {
           baseURL: config.baseUrl,
         },
-        modelName: config.modelId, // modelId に修正
+        modelName: config.modelId, 
       });
 
-      // テキストが長すぎる問題の処理?LangChain は通常、自動的に処理するかエラーを出力します。
-      // ここでは簡略化し、直接呼び出します
+      
+      
       const vector = await embeddings.embedQuery(text);
       return vector;
     } catch (error) {
       this.logger.error(
         `Failed to generate embeddings using model ${config.modelId}`,
         error,
-      ); // modelId に修正
+      ); 
       throw error;
     }
   }

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

@@ -40,7 +40,7 @@ export class ApiController {
     }
 
     try {
-      // ユーザーの LLM モデル設定を取得
+      
       const models = await this.modelConfigService.findAll(req.user.id, req.user.tenantId);
       const llmModel = models.find((m) => m.type === 'llm');
       if (!llmModel) {
@@ -49,7 +49,7 @@ export class ApiController {
 
       // API key is optional - allow local models
 
-      // entity タイプを types インターフェースに変換
+      
       const modelConfigForService = {
         id: llmModel.id,
         name: llmModel.name,

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

@@ -6,7 +6,7 @@ import { ModelConfig } from '../types';
 export class ApiService {
   constructor() { }
 
-  // 簡易的なヘルスチェックメソッド
+  
   healthCheck() {
     return { status: 'ok', message: 'API is healthy' };
   }

+ 29 - 29
server/src/chat/chat.controller.ts

@@ -18,19 +18,19 @@ class StreamChatDto {
   history: ChatMessage[];
   userLanguage?: string;
   selectedEmbeddingId?: string;
-  selectedLLMId?: string; // 新增:选中的 LLM 模型 ID
-  selectedGroups?: string[]; // 新增
-  selectedFiles?: string[]; // 新增:选中的文件
-  historyId?: string; // 新增
-  enableRerank?: boolean; // 新增
-  selectedRerankId?: string; // 新增
-  temperature?: number; // 新增:temperature 参数
-  maxTokens?: number; // 新增:maxTokens 参数
-  topK?: number; // 新增:topK 参数
-  similarityThreshold?: number; // 新増:similarityThreshold 参数
-  rerankSimilarityThreshold?: number; // 新増:rerankSimilarityThreshold 参数
-  enableQueryExpansion?: boolean; // 新增
-  enableHyDE?: boolean; // 新增
+  selectedLLMId?: string; 
+  selectedGroups?: string[]; 
+  selectedFiles?: string[]; 
+  historyId?: string; 
+  enableRerank?: boolean; 
+  selectedRerankId?: string; 
+  temperature?: number; 
+  maxTokens?: number; 
+  topK?: number; 
+  similarityThreshold?: number; 
+  rerankSimilarityThreshold?: number; 
+  enableQueryExpansion?: boolean; 
+  enableHyDE?: boolean; 
 }
 
 @Controller('chat')
@@ -73,7 +73,7 @@ export class ChatController {
       const role = req.user.role;
       const tenantId = req.user.tenantId;
 
-      // 获取用户的LLM模型配置
+      
       let models = await this.modelConfigService.findAll(userId, tenantId);
 
       if (role !== 'SUPER_ADMIN') {
@@ -94,7 +94,7 @@ export class ChatController {
         console.log('Final LLM model used (default):', llmModel ? llmModel.name : '无');
       }
 
-      // 设置 SSE 响应头
+      
       res.setHeader('Content-Type', 'text/event-stream');
       res.setHeader('Cache-Control', 'no-cache');
       res.setHeader('Connection', 'keep-alive');
@@ -102,7 +102,7 @@ export class ChatController {
 
       if (!llmModel) {
         res.write(
-          `data: ${JSON.stringify({ type: 'error', data: '请在模型管理中添加LLM模型并配置API密钥' })}\n\n`,
+          `data: ${JSON.stringify({ type: 'error', data: 'Please add LLM model and configure API key in model management' })}\n\n`,
         );
         res.write('data: [DONE]\n\n');
         res.end();
@@ -116,18 +116,18 @@ export class ChatController {
         llmModel as any,
         userLanguage,
         selectedEmbeddingId,
-        selectedGroups, // 新增
-        selectedFiles, // 新增
-        historyId, // 新增
+        selectedGroups, 
+        selectedFiles, 
+        historyId, 
         enableRerank,
         selectedRerankId,
-        temperature, // 传递 temperature 参数
-        maxTokens, // 传递 maxTokens 参数
-        topK, // 传递 topK 参数
-        similarityThreshold, // 传递 similarityThreshold 参数
-        rerankSimilarityThreshold, // 传递 rerankSimilarityThreshold 参数
-        enableQueryExpansion, // 传递 enableQueryExpansion
-        enableHyDE, // 传递 enableHyDE
+        temperature, 
+        maxTokens, 
+        topK, 
+        similarityThreshold, 
+        rerankSimilarityThreshold, 
+        enableQueryExpansion, 
+        enableHyDE, 
         req.user.tenantId // Pass tenant ID
       );
 
@@ -141,7 +141,7 @@ export class ChatController {
       console.error('Stream chat error:', error);
       try {
         res.write(
-          `data: ${JSON.stringify({ type: 'error', data: error.message || '服务器错误' })}\n\n`,
+          `data: ${JSON.stringify({ type: 'error', data: error.message || 'Server Error' })}\n\n`,
         );
         res.write('data: [DONE]\n\n');
         res.end();
@@ -173,7 +173,7 @@ export class ChatController {
 
       if (!llmModel) {
         res.write(
-          `data: ${JSON.stringify({ type: 'error', data: '未找到LLM模型配置' })}\n\n`,
+          `data: ${JSON.stringify({ type: 'error', data: 'LLM model configuration not found' })}\n\n`,
         );
         res.write('data: [DONE]\n\n');
         res.end();
@@ -195,7 +195,7 @@ export class ChatController {
     } catch (error) {
       console.error('Stream assist error:', error);
       res.write(
-        `data: ${JSON.stringify({ type: 'error', data: error.message || '服务器错误' })}\n\n`,
+        `data: ${JSON.stringify({ type: 'error', data: error.message || 'Server Error' })}\n\n`,
       );
       res.write('data: [DONE]\n\n');
       res.end();

+ 52 - 54
server/src/chat/chat.service.ts

@@ -49,22 +49,22 @@ export class ChatService {
     modelConfig: ModelConfig,
     userLanguage: string = DEFAULT_LANGUAGE,
     selectedEmbeddingId?: string,
-    selectedGroups?: string[], // 新規:選択されたグループ
-    selectedFiles?: string[], // 新規:選択されたファイル
-    historyId?: string, // 新規:対話履歴ID
+    selectedGroups?: string[], 
+    selectedFiles?: string[], 
+    historyId?: string, 
     enableRerank: boolean = false,
     selectedRerankId?: string,
-    temperature?: number, // 新規: temperature パラメータ
-    maxTokens?: number, // 新規: maxTokens パラメータ
-    topK?: number, // 新規: topK パラメータ
-    similarityThreshold?: number, // 新規: similarityThreshold パラメータ
-    rerankSimilarityThreshold?: number, // 新規: rerankSimilarityThreshold パラメータ
-    enableQueryExpansion?: boolean, // 新規
-    enableHyDE?: boolean, // 新規
-    tenantId?: string // 新規: tenant isolation
+    temperature?: number, 
+    maxTokens?: number, 
+    topK?: number, 
+    similarityThreshold?: number, 
+    rerankSimilarityThreshold?: number, 
+    enableQueryExpansion?: boolean, 
+    enableHyDE?: boolean, 
+    tenantId?: string 
   ): AsyncGenerator<{ type: 'content' | 'sources' | 'historyId'; data: any }> {
     console.log('=== ChatService.streamChat ===');
-    console.log('ユーザーID:', userId);
+    console.log('User ID:', userId);
     console.log('User language:', userLanguage);
     console.log('Selected embedding model ID:', selectedEmbeddingId);
     console.log('Selected group:', selectedGroups);
@@ -82,22 +82,22 @@ export class ChatService {
       modelId: modelConfig.modelId,
       baseUrl: modelConfig.baseUrl,
     });
-    console.log('API Key プレフィックス:', modelConfig.apiKey?.substring(0, 10) + '...');
+    console.log('API Key prefix:', modelConfig.apiKey?.substring(0, 10) + '...');
     console.log('API Key length:', modelConfig.apiKey?.length);
 
-    // 現在の言語設定を取得 (下位互換性のためにLANGUAGE_CONFIGを保持しますが、現在はi18nサービスを使>用)
-    // ユーザー設定に基づいて実際の言語を使用
+    
+    
     const effectiveUserLanguage = userLanguage || DEFAULT_LANGUAGE;
 
     let currentHistoryId = historyId;
     let fullResponse = '';
 
     try {
-      // historyId がない場合は、新しい対話履歴を作成
+      
       if (!currentHistoryId) {
         const searchHistory = await this.searchHistoryService.create(
           userId,
-          tenantId || 'default', // 新規
+          tenantId || 'default', 
           message,
           selectedGroups,
         );
@@ -106,9 +106,9 @@ export class ChatService {
         yield { type: 'historyId', data: currentHistoryId };
       }
 
-      // ユーザーメッセージを保存
+      
       await this.searchHistoryService.addMessage(currentHistoryId, 'user', message);
-      // 1. ユーザーの埋め込みモデル設定を取得
+      
       let embeddingModel: any;
 
       if (selectedEmbeddingId) {
@@ -121,7 +121,7 @@ export class ChatService {
 
       console.log(this.i18nService.getMessage('usingEmbeddingModel', effectiveUserLanguage) + embeddingModel.name + ' ' + embeddingModel.modelId + ' ID:' + embeddingModel.id);
 
-      // 2. ユーザーのクエリを直接使用して検索
+      
       console.log(this.i18nService.getMessage('startingSearch', effectiveUserLanguage));
       yield { type: 'content', data: this.i18nService.getMessage('searching', effectiveUserLanguage) + '\n' };
 
@@ -129,14 +129,14 @@ export class ChatService {
       let context = '';
 
       try {
-        // 3. 選択された知識グループがある場合、まずそれらのグループ内のファイルIDを取得
-        let effectiveFileIds = selectedFiles; // 明示的に指定されたファイルを優先
+        
+        let effectiveFileIds = selectedFiles; 
         if (!effectiveFileIds && selectedGroups && selectedGroups.length > 0) {
-          // ナレッジグループからファイルIDを取得
+          
           effectiveFileIds = await this.knowledgeGroupService.getFileIdsByGroups(selectedGroups, userId, tenantId as string);
         }
 
-        // 3. RagService を使用して検索 (混合検索 + Rerank をサポート)
+        
         const ragResults = await this.ragService.searchKnowledge(
           message,
           userId,
@@ -154,18 +154,18 @@ export class ChatService {
           enableHyDE
         );
 
-        // RagSearchResult を ChatService が必要とする形式 (any[]) に変換
-        // HybridSearch は ES の hit 構造を返しますが、RagSearchResult は正規化されています。
-        // BuildContext は {fileName, content} を期待します。RagSearchResult はこれらを持っています。
+        
+        
+        
         searchResults = ragResults;
         console.log(this.i18nService.getMessage('searchResultsCount', effectiveUserLanguage) + searchResults.length);
 
-        // 4. コンテキストの構築
+        
         context = this.buildContext(searchResults, effectiveUserLanguage);
 
         if (searchResults.length === 0) {
           if (selectedGroups && selectedGroups.length > 0) {
-            // ユーザーがナレッジグループを選択したが、一致するものが見つからなかった場合
+            
             const noMatchMsg = this.i18nService.getMessage('noMatchInKnowledgeGroup', effectiveUserLanguage);
             yield { type: 'content', data: `⚠️ ${noMatchMsg}\n\n` };
           } else {
@@ -178,7 +178,7 @@ export class ChatService {
             type: 'content',
             data: `${searchResults.length} ${this.i18nService.getMessage('relevantInfoFound', effectiveUserLanguage)}。${this.i18nService.getMessage('generatingResponse', effectiveUserLanguage)}...\n\n`,
           };
-          // 一時的なデバッグ情報
+          
           const scores = searchResults.map(r => {
             if (r.originalScore !== undefined && r.originalScore !== r.score) {
               return `${r.originalScore.toFixed(2)} → ${r.score.toFixed(2)}`;
@@ -195,7 +195,7 @@ export class ChatService {
         yield { type: 'content', data: this.i18nService.getMessage('searchFailed', effectiveUserLanguage) + '\n\n' };
       }
 
-      // 5. ストリーム回答生成
+      
       this.logger.log(this.i18nService.formatMessage('modelCall', {
         type: 'LLM',
         model: `${modelConfig.name} (${modelConfig.modelId})`,
@@ -238,7 +238,7 @@ export class ChatService {
         }
       }
 
-      // AI 回答を保存
+      
       await this.searchHistoryService.addMessage(
         currentHistoryId,
         'assistant',
@@ -253,7 +253,7 @@ export class ChatService {
         })),
       );
 
-      // 7. 自動チャットタイトル生成 (最初のやり取りの後に実行)
+      
       const messagesInHistory = await this.searchHistoryService.findOne(currentHistoryId, userId, tenantId);
       if (messagesInHistory.messages.length === 2) {
         this.generateChatTitle(currentHistoryId, userId, tenantId, effectiveUserLanguage).catch((err) => {
@@ -261,7 +261,7 @@ export class ChatService {
         });
       }
 
-      // 6. 引用元を返却
+      
       yield {
         type: 'sources',
         data: searchResults.map((result) => ({
@@ -300,13 +300,13 @@ export class ChatService {
       });
 
       const systemPrompt = `${this.i18nService.getMessage('intelligentAssistant', 'ja')}
-提供されたテキスト内容を、ユーザーの指示に基づいて修正または改善してください。
-挨拶や結びの言葉(「わかりました、こちらが...」など)は含めず、修正後の内容のみを直接出力してください。
+Correct or improve the provided text content based on your instructions.
+Please do not include any greetings or closing words (such as "Okay, this is...") and directly output only the revised content.
 
-コンテキスト(現在の内容):
+Context (current contents):
 ${context}
 
-ユーザーの指示:
+User instructions:
 ${instruction}`;
 
       const stream = await llm.stream(systemPrompt);
@@ -326,22 +326,22 @@ ${instruction}`;
     keywords: string[],
     userId: string,
     embeddingModelId?: string,
-    selectedGroups?: string[], // 新規パラメータ
-    explicitFileIds?: string[], // 新規パラメータ
+    selectedGroups?: string[], 
+    explicitFileIds?: string[], 
     tenantId?: string, // Added
   ): Promise<any[]> {
     try {
-      // キーワードを検索文字列に結合
+      
       const combinedQuery = keywords.join(' ');
       console.log(this.i18nService.getMessage('searchString', 'ja') + combinedQuery);
 
-      // Embedding model IDが提供されているか確認
+      
       if (!embeddingModelId) {
         console.log(this.i18nService.getMessage('embeddingModelIdNotProvided', 'ja'));
         return [];
       }
 
-      // 実際の埋め込みベクトルを使用
+      
       console.log(this.i18nService.getMessage('generatingEmbeddings', 'ja'));
       const queryEmbedding = await this.embeddingService.getEmbeddings(
         [combinedQuery],
@@ -351,7 +351,7 @@ ${instruction}`;
       const queryVector = queryEmbedding[0];
       console.log(this.i18nService.getMessage('embeddingsGenerated', 'ja') + this.i18nService.getMessage('dimensions', 'ja') + ':', queryVector.length);
 
-      // 混合検索
+      
       console.log(this.i18nService.getMessage('performingHybridSearch', 'ja'));
       const results = await this.elasticsearchService.hybridSearch(
         queryVector,
@@ -359,8 +359,8 @@ ${instruction}`;
         userId,
         10,
         0.6,
-        selectedGroups, // 選択されたグループを渡す
-        explicitFileIds, // 明示的なファイルIDを渡す
+        selectedGroups, 
+        explicitFileIds, 
         tenantId, // Added: tenantId
       );
       console.log(this.i18nService.getMessage('esSearchCompleted', 'ja') + this.i18nService.getMessage('resultsCount', 'ja') + ':', results.length);
@@ -439,7 +439,7 @@ ${instruction}`;
       const settings = await this.userSettingService.findOrCreate(userId);
       const llm = new ChatOpenAI({
         apiKey: config.apiKey || 'ollama',
-        temperature: settings.temperature ?? 0.7, // ユーザー設定またはデフォルトを使用
+        temperature: settings.temperature ?? 0.7, 
         modelName: config.modelId,
         configuration: {
           baseURL: config.baseUrl || 'http://localhost:11434/v1',
@@ -457,9 +457,7 @@ ${instruction}`;
     }
   }
 
-  /**
-   * 対話内容に基づいてチャットのタイトルを自動生成する
-   */
+  
   async generateChatTitle(historyId: string, userId: string, tenantId?: string, language?: string): Promise<string | null> {
     this.logger.log(`Generating automatic title for chat session ${historyId} in language: ${language || 'default'}`);
 
@@ -476,17 +474,17 @@ ${instruction}`;
         return null;
       }
 
-      // 優先順位: 引数の言語 > ユーザー設定 > Japanese(ja)
+      
       let targetLanguage = language;
       if (!targetLanguage) {
         const settings = await this.userSettingService.findOrCreate(userId);
         targetLanguage = settings.language || 'ja';
       }
 
-      // プロンプトを構築
+      
       const prompt = this.i18nService.getChatTitlePrompt(targetLanguage, userMessage, aiResponse);
 
-      // LLMを呼び出してタイトルを生成
+      
       const generatedTitle = await this.generateSimpleChat(
         [{ role: 'user', content: prompt }],
         userId,
@@ -494,7 +492,7 @@ ${instruction}`;
       );
 
       if (generatedTitle && generatedTitle.trim().length > 0) {
-        // 余分な引用符を除去
+        
         const cleanedTitle = generatedTitle.trim().replace(/^["']|["']$/g, '').substring(0, 50);
         await this.searchHistoryService.updateTitle(historyId, cleanedTitle);
         this.logger.log(`Successfully generated title for chat ${historyId}: ${cleanedTitle}`);

+ 7 - 9
server/src/common/constants.ts

@@ -1,8 +1,6 @@
-/**
- * アプリケーション全体で使用される定数定義
- */
 
-// Chunk configurationのデフォルト値
+
+
 export const DEFAULT_CHUNK_SIZE = 200;
 export const MIN_CHUNK_SIZE = 50;
 export const MAX_CHUNK_SIZE = 8191;
@@ -10,17 +8,17 @@ export const DEFAULT_CHUNK_OVERLAP = 40;
 export const MIN_CHUNK_OVERLAP = 25;
 export const DEFAULT_MAX_OVERLAP_RATIO = 0.5;
 
-// ベクトル次元のデフォルト値 (OpenAI Standard)
+
 export const DEFAULT_VECTOR_DIMENSIONS = 1536;
 
-// ファイルサイズの制限 (バイト)
+
 export const MAX_FILE_SIZE = 100 * 1024 * 1024; // 100MB
 
-// バッチ処理の制限
+
 export const DEFAULT_MAX_BATCH_SIZE = 2048;
 
-// デフォルト言語
+
 export const DEFAULT_LANGUAGE = 'ja';
 
-// システム全体の共通テナントID(シードデータなどで使用)
+
 export const GLOBAL_TENANT_ID = '00000000-0000-0000-0000-000000000000';

+ 35 - 42
server/src/elasticsearch/elasticsearch.service.ts

@@ -31,7 +31,7 @@ export class ElasticsearchService implements OnModuleInit {
     try {
       const health = await this.client.cluster.health();
       this.logger.log(`Elasticsearch cluster health is: ${health.status}`);
-      // 初期化時にはインデックスを作成せず、実際の使用時にモデルに基づいて動的に作成されるのを待つ
+      
     } catch (error) {
       this.logger.error('Failed to connect to Elasticsearch', error);
     }
@@ -48,7 +48,7 @@ export class ElasticsearchService implements OnModuleInit {
       );
       await this.createIndex(vectorDimensions);
     } else {
-      // 既存インデックスのベクトル次元数を確認
+      
       const mapping = await this.client.indices.getMapping({
         index: this.indexName,
       });
@@ -63,7 +63,7 @@ export class ElasticsearchService implements OnModuleInit {
         );
         this.logger.warn(`Reason: The embedding model might have been changed to one with different dimensions. The system will automatically recreate the index.`);
 
-        // 既存インデックスを削除して再作成
+        
         await this.client.indices.delete({ index: this.indexName });
         this.logger.log(`Successfully deleted old index: ${this.indexName}`);
 
@@ -150,7 +150,7 @@ export class ElasticsearchService implements OnModuleInit {
         source: 'ctx._source.title = params.title',
         params: { title },
       },
-      refresh: true, // 即座に検索に反映させる
+      refresh: true, 
     });
   }
 
@@ -200,7 +200,7 @@ export class ElasticsearchService implements OnModuleInit {
 
       const results = response.hits.hits.map((hit: any) => ({
         id: hit._id,
-        score: this.normalizeScore(hit._score), // スコアの正規化
+        score: this.normalizeScore(hit._score), 
         content: hit._source?.content,
         fileId: hit._source?.fileId,
         fileName: hit._source?.fileName,
@@ -261,7 +261,7 @@ export class ElasticsearchService implements OnModuleInit {
 
       const results = response.hits.hits.map((hit: any) => ({
         id: hit._id,
-        score: this.normalizeScore(hit._score), // スコアの正規化
+        score: this.normalizeScore(hit._score), 
         content: hit._source?.content,
         fileId: hit._source?.fileId,
         fileName: hit._source?.fileName,
@@ -287,11 +287,11 @@ export class ElasticsearchService implements OnModuleInit {
     userId: string,
     topK: number = 5,
     vectorWeight: number = 0.7,
-    selectedGroups?: string[], // 後方互換性のために残す(未使用)
-    explicitFileIds?: string[], // 明示的に指定されたファイルIDリスト
+    selectedGroups?: string[], 
+    explicitFileIds?: string[], 
     tenantId?: string,
   ) {
-    // selectedGroups は廃止予定。呼び出し側で fileIds に変換して explicitFileIds を使用してください
+    
     const fileIds = explicitFileIds;
 
     if (fileIds && fileIds.length === 0) {
@@ -303,16 +303,16 @@ export class ElasticsearchService implements OnModuleInit {
       this.logger.log(`Final search target scope: ${fileIds.length} files`);
     }
 
-    // ハイブリッド検索:ベクトル検索 + 全文検索
+    
     const [vectorResults, textResults] = await Promise.all([
       this.searchSimilarWithFileFilter(queryVector, userId, topK, fileIds, tenantId),
       this.searchFullTextWithFileFilter(query, userId, topK, fileIds, tenantId),
     ]);
 
-    // 結果をマージして重複を排除
+    
     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);
@@ -340,21 +340,21 @@ export class ElasticsearchService implements OnModuleInit {
       }
     });
 
-    // 正規化のためにすべての組み合わせスコアを取得
+    
     const allScores = Array.from(combinedResults.values()).map(r => r.combinedScore);
-    const maxScore = Math.max(...allScores, 1); // ゼロ除算を避けるため最小1
+    const maxScore = Math.max(...allScores, 1); 
     const minScore = Math.min(...allScores);
 
-    // 総合スコアでソートして上位 topK の結果を返す
+    
     return Array.from(combinedResults.values())
       .sort((a, b) => b.combinedScore - a.combinedScore)
       .slice(0, topK)
       .map((result) => {
-        // combinedScoreは既に0-1の範囲にあるため、Addedの正規化は不要
-        // 0-1の範囲にスコアを保つことで、実際の類似度を正確に反映
+        
+        
         let finalScore = result.combinedScore;
 
-        // スコアが0-1の範囲内に収まるようにクリップ
+        
         finalScore = Math.max(0, Math.min(1.0, finalScore));
 
         return {
@@ -374,36 +374,36 @@ export class ElasticsearchService implements OnModuleInit {
   private async createIndex(vectorDimensions: number) {
     const mappings: any = {
       properties: {
-        // チャンク内容
+        
         content: {
           type: 'text',
           analyzer: 'standard',
         },
-        // ベクトルデータ
+        
         vector: {
           type: 'dense_vector',
           dims: vectorDimensions,
           index: true,
           similarity: 'cosine',
         },
-        // ファイル関連情報
+        
         fileId: { type: 'keyword' },
         fileName: { type: 'keyword' },
         title: { type: 'text' },
         fileMimeType: { type: 'keyword' },
 
-        // チャンク情報
+        
         chunkIndex: { type: 'integer' },
         startPosition: { type: 'integer' },
         endPosition: { type: 'integer' },
 
-        // ユーザー情報
+        
         userId: { type: 'keyword' },
 
-        // テナント情報(マルチテナント分離用)
+        
         tenantId: { type: 'keyword' },
 
-        // タイムスタンプ
+        
         createdAt: { type: 'date' },
       },
     };
@@ -418,21 +418,16 @@ export class ElasticsearchService implements OnModuleInit {
     );
   }
 
-  /**
-   * Elasticsearch スコアを 0-1 の範囲に正規化する
-   * Elasticsearch のスコアは 1.0 を超える可能性があるため、正規化が必要
-   * ただし、kNN検索の類似度スコアは既に0-1の範囲にある(cosine similarity)ので、
-   * 特別な正規化は不要。必要に応じて最小値保護のみ行う。
-   */
+  
   private normalizeScore(rawScore: number): number {
-    if (!rawScore || rawScore <= 0) return 0; // 最小値は0
+    if (!rawScore || rawScore <= 0) return 0; 
 
-    // kNN検索の場合は既に0-1の範囲にあるので、1を超えないようにクリップ
-    // cosine similarityの最大値は1なので、1以上になった場合は1とする
+    
+    
     return Math.min(1.0, rawScore);
   }
 
-  // ファイルフィルタ付きのベクトル検索
+  
   private async searchSimilarWithFileFilter(
     queryVector: number[],
     userId: string,
@@ -513,7 +508,7 @@ export class ElasticsearchService implements OnModuleInit {
     }
   }
 
-  // ファイルフィルタ付きの全文検索
+  
   private async searchFullTextWithFileFilter(
     query: string,
     userId: string,
@@ -595,9 +590,7 @@ export class ElasticsearchService implements OnModuleInit {
     }
   }
 
-  /**
-   * 指定されたファイルのすべてのチャンクを取得
-   */
+  
   async getFileChunks(fileId: string, userId: string, tenantId?: string) {
     try {
       this.logger.log(`Getting chunks for file ${fileId}`);
@@ -615,9 +608,9 @@ export class ElasticsearchService implements OnModuleInit {
           bool: { filter },
         },
         sort: [{ chunkIndex: 'asc' }],
-        size: 10000, // 単一ファイルが 10000 チャンクを超えないと想定
+        size: 10000, 
         _source: {
-          excludes: ['vector'], // 転送量を減らすため、ベクトルデータは返さない
+          excludes: ['vector'], 
         },
       });
 

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

@@ -4,15 +4,7 @@ import { ModelConfigService } from '../model-config/model-config.service';
 import { TenantService } from '../tenant/tenant.service';
 import { UserSettingService } from '../user-setting/user-setting.service';
 
-/**
- * Chunk configurationサービス
- * チャンクパラメータの検証と管理を担当し、モデルの制限や環境変数の設定に適合していることを確認します
- *
- * 制限の優先順位:
- * 1. 環境変数 (MAX_CHUNK_SIZE, MAX_OVERLAP_SIZE)
- * 2. データベース内のモデル設定 (maxInputTokens, maxBatchSize)
- * 3. デフォルト値
- */
+
 import {
   DEFAULT_CHUNK_SIZE,
   MIN_CHUNK_SIZE,
@@ -28,18 +20,18 @@ import { I18nService } from '../i18n/i18n.service';
 export class ChunkConfigService {
   private readonly logger = new Logger(ChunkConfigService.name);
 
-  // デフォルト設定
+  
   private readonly DEFAULTS = {
     chunkSize: DEFAULT_CHUNK_SIZE,
     chunkOverlap: DEFAULT_CHUNK_OVERLAP,
     minChunkSize: MIN_CHUNK_SIZE,
     minChunkOverlap: MIN_CHUNK_OVERLAP,
-    maxOverlapRatio: DEFAULT_MAX_OVERLAP_RATIO,  // 重なりはChunk sizeの50%まで
-    maxBatchSize: DEFAULT_MAX_BATCH_SIZE,    // デフォルトのバッチ制限
-    expectedDimensions: DEFAULT_VECTOR_DIMENSIONS, // デフォルトのベクトル次元
+    maxOverlapRatio: DEFAULT_MAX_OVERLAP_RATIO,  
+    maxBatchSize: DEFAULT_MAX_BATCH_SIZE,    
+    expectedDimensions: DEFAULT_VECTOR_DIMENSIONS, 
   };
 
-  // 環境変数で設定された上限(優先的に使用)
+  
   private readonly envMaxChunkSize: number;
   private readonly envMaxOverlapSize: number;
 
@@ -50,7 +42,7 @@ export class ChunkConfigService {
     private tenantService: TenantService,
     private userSettingService: UserSettingService,
   ) {
-    // 環境変数からグローバルな上限設定を読み込む
+    
     this.envMaxChunkSize = parseInt(
       this.configService.get<string>('MAX_CHUNK_SIZE', '8191')
     );
@@ -63,9 +55,7 @@ export class ChunkConfigService {
     );
   }
 
-  /**
-   * モデルの制限設定を取得(データベースから読み込み)
-   */
+  
   async getModelLimits(modelId: string, userId: string, tenantId?: string): Promise<{
     maxInputTokens: number;
     maxBatchSize: number;
@@ -79,7 +69,7 @@ export class ChunkConfigService {
       throw new BadRequestException(this.i18nService.formatMessage('embeddingModelNotFound', { id: modelId }));
     }
 
-    // データベースのフィールドから制限を取得し、デフォルト値で補完
+    
     const maxInputTokens = modelConfig.maxInputTokens || this.envMaxChunkSize;
     const maxBatchSize = modelConfig.maxBatchSize || this.DEFAULTS.maxBatchSize;
     const expectedDimensions = modelConfig.dimensions || parseInt(this.configService.get('DEFAULT_VECTOR_DIMENSIONS', String(this.DEFAULTS.expectedDimensions)));
@@ -104,10 +94,7 @@ export class ChunkConfigService {
     };
   }
 
-  /**
-   * Chunk configurationを検証および修正
-   * 優先順位: 環境変数の上限 > モデルの制限 > ユーザー設定
-   */
+  
   async validateChunkConfig(
     chunkSize: number,
     chunkOverlap: number,
@@ -124,7 +111,7 @@ export class ChunkConfigService {
     const warnings: string[] = [];
     const limits = await this.getModelLimits(modelId, userId, tenantId);
 
-    // 1. 最終的な上限を計算(環境変数とモデル制限の小さい方を選択)
+    
     const effectiveMaxChunkSize = Math.min(
       this.envMaxChunkSize,
       limits.maxInputTokens,
@@ -135,7 +122,7 @@ export class ChunkConfigService {
       Math.floor(effectiveMaxChunkSize * this.DEFAULTS.maxOverlapRatio),
     );
 
-    // 2. Chunk sizeの上限を検証
+    
     if (chunkSize > effectiveMaxChunkSize) {
       const reason =
         this.envMaxChunkSize < limits.maxInputTokens
@@ -152,7 +139,7 @@ export class ChunkConfigService {
       chunkSize = effectiveMaxChunkSize;
     }
 
-    // 3. Chunk sizeの下限を検証
+    
     if (chunkSize < this.DEFAULTS.minChunkSize) {
       warnings.push(
         this.i18nService.formatMessage('chunkUnderflow', {
@@ -163,7 +150,7 @@ export class ChunkConfigService {
       chunkSize = this.DEFAULTS.minChunkSize;
     }
 
-    // 4. 重なりサイズの上限を検証(環境変数優先)
+    
     if (chunkOverlap > effectiveMaxOverlapSize) {
       warnings.push(
         this.i18nService.formatMessage('overlapOverflow', {
@@ -174,7 +161,7 @@ export class ChunkConfigService {
       chunkOverlap = effectiveMaxOverlapSize;
     }
 
-    // 5. 重なりサイズがChunk sizeの50%を超えないことを検証
+    
     const maxOverlapByRatio = Math.floor(
       chunkSize * this.DEFAULTS.maxOverlapRatio,
     );
@@ -198,9 +185,9 @@ export class ChunkConfigService {
       chunkOverlap = this.DEFAULTS.minChunkOverlap;
     }
 
-    // 6. バッチ処理の安全チェックをAdded
-    // バッチ処理時、複数のテキストの合計長がモデルの制限を超えないようにする必要があります
-    const safetyMargin = 0.8; // 80% 安全マージン、バッチ処理のためにスペースを確保
+    
+    
+    const safetyMargin = 0.8; 
     const safeChunkSize = Math.floor(effectiveMaxChunkSize * safetyMargin);
 
     if (chunkSize > safeChunkSize) {
@@ -213,9 +200,9 @@ export class ChunkConfigService {
       );
     }
 
-    // 7. 推定チャンク数が妥当かチェック
+    
     const estimatedChunkCount = this.estimateChunkCount(
-      1000000, // 1MB のテキストを想定
+      1000000, 
       chunkSize,
     );
 
@@ -234,9 +221,7 @@ export class ChunkConfigService {
     };
   }
 
-  /**
-   * 推奨されるバッチサイズを取得
-   */
+  
   async getRecommendedBatchSize(
     modelId: string,
     userId: string,
@@ -245,11 +230,11 @@ export class ChunkConfigService {
   ): Promise<number> {
     const limits = await this.getModelLimits(modelId, userId, tenantId);
 
-    // 設定値とモデル制限の小さい方を選択
+    
     const recommended = Math.min(
       currentBatchSize,
       limits.maxBatchSize,
-      200, // 安全のための上限
+      200, 
     );
 
     if (recommended < currentBatchSize) {
@@ -262,20 +247,16 @@ export class ChunkConfigService {
       );
     }
 
-    return Math.max(10, recommended); // 最低10個
+    return Math.max(10, recommended); 
   }
 
-  /**
-   * チャンク数を推定
-   */
+  
   estimateChunkCount(textLength: number, chunkSize: number): number {
     const chunkSizeInChars = chunkSize * 4; // 1 token ≈ 4 chars
     return Math.ceil(textLength / chunkSizeInChars);
   }
 
-  /**
-   * ベクトル次元の検証
-   */
+  
   async validateDimensions(
     modelId: string,
     userId: string,
@@ -298,9 +279,7 @@ export class ChunkConfigService {
     return true;
   }
 
-  /**
-   * 設定概要を取得(ログ用)
-   */
+  
   async getConfigSummary(
     chunkSize: number,
     chunkOverlap: number,
@@ -319,10 +298,7 @@ export class ChunkConfigService {
     ].join(', ');
   }
 
-  /**
-   * フロントエンド用のConfig limitsを取得
-   * フロントエンドのスライダーの上限設定に使用
-   */
+  
   async getFrontendLimits(
     modelId: string,
     userId: string,
@@ -342,18 +318,18 @@ export class ChunkConfigService {
   }> {
     const limits = await this.getModelLimits(modelId, userId, tenantId);
 
-    // 最終的な上限を計算(環境変数とモデル制限の小さい方を選択)
+    
     const maxChunkSize = Math.min(this.envMaxChunkSize, limits.maxInputTokens);
     const maxOverlapSize = Math.min(
       this.envMaxOverlapSize,
       Math.floor(maxChunkSize * this.DEFAULTS.maxOverlapRatio),
     );
 
-    // モデル設定名を取得
+    
     const modelConfig = await this.modelConfigService.findOne(modelId, userId, tenantId || '');
     const modelName = modelConfig?.name || 'Unknown';
 
-    // テナントまたはユーザー設定からデフォルト値を取得
+    
     let defaultChunkSize = this.DEFAULTS.chunkSize;
     let defaultOverlapSize = this.DEFAULTS.chunkOverlap;
 

+ 29 - 33
server/src/knowledge-base/embedding.service.ts

@@ -43,23 +43,23 @@ export class EmbeddingService {
       tenantId || 'default',
     );
     if (!modelConfig || modelConfig.type !== 'embedding') {
-      throw new Error(`埋め込みモデル設定 ${embeddingModelConfigId} が見つかりません`);
+      throw new Error(`Embedded model configuration ${embeddingModelConfigId} not found`);
     }
 
     if (modelConfig.isEnabled === false) {
-      throw new Error(`モデル ${modelConfig.name} は無効化されているため、埋め込みベクトルを生成できません`);
+      throw new Error(`Unable to generate embedding vector because model ${modelConfig.name} is disabled`);
     }
 
     // API key is optional - allow local models
 
     if (!modelConfig.baseUrl) {
-      throw new Error(`モデル ${modelConfig.name} に baseUrl が設定されていません`);
+      throw new Error(`baseUrl not set for model ${modelConfig.name}`);
     }
 
-    // Model nameに基づいて最大バッチサイズを決定
+    
     const maxBatchSize = this.getMaxBatchSizeForModel(modelConfig.modelId, modelConfig.maxBatchSize);
 
-    // バッチサイズが制限を超える場合は分割して処理
+    
     if (texts.length > maxBatchSize) {
       this.logger.log(
         `Text count ${texts.length} exceeds model batch limit ${maxBatchSize}, splitting into batches`
@@ -78,15 +78,15 @@ export class EmbeddingService {
 
         allEmbeddings.push(...batchEmbeddings);
 
-        // APIレート制限対策のため、短い間隔で待機
+        
         if (i + maxBatchSize < texts.length) {
-          await new Promise(resolve => setTimeout(resolve, 100)); // 100ms待機
+          await new Promise(resolve => setTimeout(resolve, 100)); 
         }
       }
 
       return allEmbeddings;
     } else {
-      // 通常処理(バッチサイズ以内)
+      
       return await this.getEmbeddingsForBatch(
         texts,
         userId,
@@ -96,25 +96,21 @@ export class EmbeddingService {
     }
   }
 
-  /**
-   * モデルIDに基づいて最大バッチサイズを決定
-   */
+  
   private getMaxBatchSizeForModel(modelId: string, configuredMaxBatchSize?: number): number {
-    // モデル固有のバッチサイズ制限
+    
     if (modelId.includes('text-embedding-004') || modelId.includes('text-embedding-v4') ||
       modelId.includes('text-embedding-ada-002')) {
-      return Math.min(10, configuredMaxBatchSize || 100); // Googleの場合は10を上限
+      return Math.min(10, configuredMaxBatchSize || 100); 
     } else if (modelId.includes('text-embedding-3') || modelId.includes('text-embedding-003')) {
-      return Math.min(2048, configuredMaxBatchSize || 2048); // OpenAI v3は2048 exceeds limit 
+      return Math.min(2048, configuredMaxBatchSize || 2048); 
     } else {
-      // デフォルトでは設定された最大バッチサイズか100の小さい方
+      
       return Math.min(configuredMaxBatchSize || 100, 100);
     }
   }
 
-  /**
-   * 単一バッチの埋め込み処理
-   */
+  
   private async getEmbeddingsForBatch(
     texts: string[],
     userId: string,
@@ -161,14 +157,14 @@ export class EmbeddingService {
         if (!response.ok) {
           const errorText = await response.text();
 
-          // バッチサイズ制限エラーを検出
+          
           if (errorText.includes('batch size is invalid') || errorText.includes('batch_size') ||
             errorText.includes('invalid') || errorText.includes('larger than')) {
             this.logger.warn(
               `Batch size limit error detected. Halving batch size and retrying: ${maxBatchSize} -> ${Math.floor(maxBatchSize / 2)}`
             );
 
-            // バッチをさらに小さな単位に分割して再試行
+            
             if (texts.length > 1) {
               const midPoint = Math.floor(texts.length / 2);
               const firstHalf = texts.slice(0, midPoint);
@@ -181,38 +177,38 @@ export class EmbeddingService {
             }
           }
 
-          // コンテキスト長の過剰エラーを検出
+          
           if (errorText.includes('context length') || errorText.includes('exceeds')) {
             const avgLength = texts.reduce((s, t) => s + t.length, 0) / texts.length;
             const totalLength = texts.reduce((s, t) => s + t.length, 0);
             this.logger.error(
               `Text length exceeded limit: Input ${texts.length} texts,` +
-              `総計 ${totalLength} 文字、平均 ${Math.round(avgLength)} 文字、` +
-              `モデル制限: ${modelConfig.maxInputTokens || 8192} tokens`
+              `Total ${totalLength} characters, average ${Math.round(avgLength)} characters, ` +
+              `Model limit: ${modelConfig.maxInputTokens || 8192} tokens`
             );
             throw new Error(
-              `テキスト長がモデルの制限。` +
-              `現在: ${texts.length} 個のテキストで計 ${totalLength} 文字、` +
-              `モデル制限: ${modelConfig.maxInputTokens || 8192} tokens。` +
-              `アドバイス: Chunk sizeまたはバッチサイズを小さくしてください`
+              `Text length is a limitation of the model. ` +
+              `Currently: ${texts.length} texts totaling ${totalLength} characters, ` +
+              `Model limit: ${modelConfig.maxInputTokens || 8192} tokens. ` +
+              `Advice: Reduce chunk size or batch size`
             );
           }
 
-          // 429 (Too Many Requests) または 5xx (Server Error) の場合は再試行
+          
           if (response.status === 429 || response.status >= 500) {
             this.logger.warn(`Temporary error occurred in Embedding API (${response.status}): ${errorText}`);
             throw new Error(`API Error ${response.status}: ${errorText}`);
           }
 
           this.logger.error(`Embedding API Error Details: ${errorText}`);
-          this.logger.error(`リクエストパラメータ: model=${modelConfig.modelId}, inputLength=${texts[0]?.length}`);
-          throw new Error(`埋め込み API の呼び出しに失敗しました: ${response.statusText} - ${errorText}`);
+          this.logger.error(`Request parameters: model=${modelConfig.modelId}, inputLength=${texts[0]?.length}`);
+          throw new Error(`Embedded API call failed: ${response.statusText} - ${errorText}`);
         }
 
         const data: EmbeddingResponse = await response.json();
         const embeddings = data.data.map((item) => item.embedding);
 
-        // 実際のレスポンスから次元を取得
+        
         const actualDimensions = embeddings[0]?.length || this.defaultDimensions;
         this.logger.log(
           `Retrieved ${embeddings.length} embeddings from ${modelConfig.name}. Dimensions: ${actualDimensions}`,
@@ -222,7 +218,7 @@ export class EmbeddingService {
       } catch (error) {
         lastError = error;
 
-        // 最後のアテンプトでなく、エラーが一時的と思われる場合(または堅牢性のために全て)は、待機後に再試行
+        
         if (attempt < MAX_RETRIES) {
           const delay = Math.pow(2, attempt - 1) * 1000; // 1s, 2s, 4s
           this.logger.warn(`Embedding request failed. Retrying in ${delay}ms: ${error.message}`);
@@ -236,7 +232,7 @@ export class EmbeddingService {
   }
 
   private getEstimatedDimensions(modelId: string): number {
-    // 使用环境变量的默认维度
+    
     return this.defaultDimensions;
   }
 }

+ 8 - 11
server/src/knowledge-base/knowledge-base.controller.ts

@@ -130,10 +130,7 @@ export class KnowledgeBaseController {
   }
 
 
-  /**
-   * Fetch chunk configuration limits(フロントエンドのスライダー設定用)
-   * クエリパラメータ: embeddingModelId - Embedding model ID
-   */
+  
   @Get('chunk-config/limits')
   async getChunkConfigLimits(
     @Request() req,
@@ -162,7 +159,7 @@ export class KnowledgeBaseController {
     );
   }
 
-  // 文件分组管理 - 需要管理员权限
+  
   @Post(':id/groups')
   @Roles(UserRole.TENANT_ADMIN, UserRole.SUPER_ADMIN)
   async addFileToGroups(
@@ -195,7 +192,7 @@ export class KnowledgeBaseController {
     return { message: this.i18nService.getMessage('fileDeletedFromGroup') };
   }
 
-  // PDF プレビュー - 公開アクセス
+  
   @Public()
   @Get(':id/pdf')
   async getPDFPreview(
@@ -244,7 +241,7 @@ export class KnowledgeBaseController {
       if (stat.size === 0) {
         this.logger.warn(`PDF file is empty: ${pdfPath}`);
         try {
-          fs.unlinkSync(pdfPath); // 空のファイルを削除
+          fs.unlinkSync(pdfPath); 
         } catch (e) { }
         throw new NotFoundException(this.i18nService.getMessage('pdfFileEmpty'));
       }
@@ -263,7 +260,7 @@ export class KnowledgeBaseController {
     }
   }
 
-  // PDF プレビューアドレスを取得
+  
   @Get(':id/pdf-url')
   async getPDFUrl(
     @Param('id') fileId: string,
@@ -271,10 +268,10 @@ export class KnowledgeBaseController {
     @Request() req,
   ) {
     try {
-      // PDF 変換をトリガー
+      
       await this.knowledgeBaseService.ensurePDFExists(fileId, req.user.id, req.user.tenantId, force === 'true');
 
-      // 一時的なアクセストークンを生成
+      
       const jwt = await import('jsonwebtoken');
 
       const secret = process.env.JWT_SECRET;
@@ -307,7 +304,7 @@ export class KnowledgeBaseController {
     return await this.knowledgeBaseService.getPDFStatus(fileId, req.user.id, req.user.tenantId);
   }
 
-  // PDF の特定ページの画像を取得
+  
   @Get(':id/page/:index')
   async getPageImage(
     @Param('id') fileId: string,

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

@@ -14,14 +14,14 @@ import { Tenant } from '../tenant/tenant.entity';
 export enum FileStatus {
   PENDING = 'pending',
   INDEXING = 'indexing',
-  EXTRACTED = 'extracted', // テキスト抽出が完了し、データベースに保存されました
-  VECTORIZED = 'vectorized', // ベクトル化が完了し、ES にインデックスされました
+  EXTRACTED = 'extracted', 
+  VECTORIZED = 'vectorized', 
   FAILED = 'failed',
 }
 
 export enum ProcessingMode {
-  FAST = 'fast',      // Fast Mode - Tika を使用
-  PRECISE = 'precise', // Precise Mode - Vision Pipeline を使用
+  FAST = 'fast',      
+  PRECISE = 'precise', 
 }
 
 @Entity('knowledge_bases')
@@ -51,7 +51,7 @@ export class KnowledgeBase {
   })
   status: FileStatus;
 
-  @Column({ name: 'user_id', nullable: true }) // 暫定的に空を許可(デバッグ用)、将来的には必須にすべき
+  @Column({ name: 'user_id', nullable: true }) 
   userId: string;
 
   @Column({ name: 'tenant_id', nullable: true, type: 'text' })
@@ -62,9 +62,9 @@ export class KnowledgeBase {
   tenant: Tenant;
 
   @Column({ type: 'text', nullable: true })
-  content: string; // Tika で抽出されたテキスト内容を保存
+  content: string; 
 
-  // インデックス設定パラメータ
+  
   @Column({ name: 'chunk_size', type: 'integer', default: 1000 })
   chunkSize: number;
 
@@ -83,10 +83,10 @@ export class KnowledgeBase {
   processingMode: ProcessingMode;
 
   @Column({ type: 'json', nullable: true })
-  metadata: any; // Addedのメタデータを保存(画像の説明、信頼度など)
+  metadata: any; 
 
   @Column({ name: 'pdf_path', nullable: true })
-  pdfPath: string; // PDF ファイルパス(プレビュー用)
+  pdfPath: string; 
 
   @ManyToMany(() => KnowledgeGroup, (group) => group.knowledgeBases)
   groups: KnowledgeGroup[];

+ 111 - 129
server/src/knowledge-base/knowledge-base.service.ts

@@ -83,7 +83,7 @@ export class KnowledgeBaseService {
       processingMode: processingMode,
     });
 
-    // 分類(グループ)の関連付け
+    
     if (config?.groupIds && config.groupIds.length > 0) {
       const groups = await this.groupRepository.find({
         where: { id: In(config.groupIds), tenantId: tenantId }
@@ -232,7 +232,7 @@ export class KnowledgeBaseService {
 
   async searchKnowledge(userId: string, tenantId: string, query: string, topK: number = 5) {
     try {
-      // 環境変数のデフォルト次元数を使用してシミュレーションベクトルを生成
+      
       const defaultDimensions = parseInt(
         process.env.DEFAULT_VECTOR_DIMENSIONS || '2560',
       );
@@ -330,11 +330,11 @@ export class KnowledgeBaseService {
         `RAG search failed for user ${userId}:`,
         error.stack || error.message,
       );
-      // エラーをスローするのではなく空の結果を返し、システムの稼働を継続させる
+      
       return {
         searchResults: [],
         sources: [],
-        ragPrompt: query, // オリジナルのクエリを使用
+        ragPrompt: query, 
         hasRelevantContent: false,
       };
     }
@@ -429,18 +429,18 @@ export class KnowledgeBaseService {
         return;
       }
 
-      // メモリ監視 - 処理前チェック
+      
       const memBefore = this.memoryMonitor.getMemoryUsage();
       this.logger.log(`Memory state - Before processing: ${memBefore.heapUsed}/${memBefore.heapTotal}MB`);
 
-      // モードに基づいて処理フローを選択
+      
       const mode = config?.mode || 'fast';
 
       if (mode === 'precise') {
-        // Precise Mode - Vision Pipeline を使用
+        
         await this.processPreciseMode(kb, userId, tenantId, config);
       } else {
-        // Fast Mode - Tika を使用
+        
         await this.processFastMode(kb, userId, tenantId, config);
       }
 
@@ -451,14 +451,12 @@ export class KnowledgeBaseService {
     }
   }
 
-  /**
-   * Fast Mode処理(既存フロー)
-   */
+  
   private async processFastMode(kb: KnowledgeBase, userId: string, tenantId: string, config?: any) {
-    // 1. Tika を使用してテキストを抽出
+    
     let text = await this.tikaService.extractText(kb.storagePath);
 
-    // 画像ファイルの場合はビジョンモデルを使用
+    
     if (this.visionService.isImageFile(kb.mimetype)) {
       const visionModelId = await this.userSettingService.getVisionModelId(userId);
       if (visionModelId) {
@@ -481,37 +479,35 @@ export class KnowledgeBaseService {
       this.logger.warn(this.i18nService.getMessage('noTextExtracted'));
     }
 
-    // テキストサイズを確認
+    
     const textSizeMB = Math.round(text.length / 1024 / 1024);
     if (textSizeMB > 50) {
       this.logger.warn(this.i18nService.formatMessage('extractedTextTooLarge', { size: textSizeMB }));
     }
 
-    // テキストをデータベースに保存
+    
     await this.kbRepository.update(kb.id, { content: text });
     await this.updateStatus(kb.id, FileStatus.EXTRACTED);
 
-    // 非同期ベクトル化
+    
     await this.vectorizeToElasticsearch(kb.id, userId, tenantId, text, config).catch((err) => {
       this.logger.error(`Error vectorizing file ${kb.id}`, err);
     });
 
-    // 自動タイトル生成 (非同期的に実行)
+    
     this.generateTitle(kb.id).catch((err) => {
       this.logger.error(`Error generating title for file ${kb.id}`, err);
     });
 
-    // 非同期的に PDF 変換をトリガー(ドキュメントファイルの場合)
+    
     this.ensurePDFExists(kb.id, userId, tenantId).catch((err) => {
       this.logger.warn(this.i18nService.formatMessage('pdfConversionFailedDetail', { id: kb.id }), err);
     });
   }
 
-  /**
-   * 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('.'));
 
@@ -522,7 +518,7 @@ export class KnowledgeBaseService {
       return this.processFastMode(kb, userId, tenantId, config);
     }
 
-    // Vision モデルが設定されているか確認
+    
     const visionModelId = await this.userSettingService.getVisionModelId(userId);
     if (!visionModelId) {
       this.logger.warn(
@@ -543,7 +539,7 @@ export class KnowledgeBaseService {
       return this.processFastMode(kb, userId, tenantId, config);
     }
 
-    // Vision Pipeline を呼び出し
+    
     try {
       const result = await this.visionPipelineService.processPreciseMode(
         kb.storagePath,
@@ -563,7 +559,7 @@ export class KnowledgeBaseService {
         return this.processFastMode(kb, userId, tenantId, config);
       }
 
-      // テキスト内容をデータベースに保存
+      
       const combinedText = result.results.map(r => r.text).join('\n\n');
       const metadata = {
         processedPages: result.processedPages,
@@ -587,18 +583,18 @@ export class KnowledgeBaseService {
         this.i18nService.formatMessage('preciseModeComplete', { pages: result.processedPages, cost: result.cost.toFixed(2) })
       );
 
-      // 非同期でベクトル化し、Elasticsearch にインデックス
-      // 各ページを独立したドキュメントとして作成し、メタデータを保持
+      
+      
       this.indexPreciseResults(kb, userId, tenantId, kb.embeddingModelId, result.results).catch((err) => {
         this.logger.error(`Error indexing precise results for ${kb.id}`, err);
       });
 
-      // 非同期で PDF 変換をトリガー
+      
       this.ensurePDFExists(kb.id, userId, tenantId).catch((err) => {
         this.logger.warn(`Initial PDF conversion failed for ${kb.id}`, err);
       });
 
-      // 自動タイトル生成 (非同期的に実行)
+      
       this.generateTitle(kb.id).catch((err) => {
         this.logger.error(`Error generating title for file ${kb.id}`, err);
       });
@@ -609,9 +605,7 @@ export class KnowledgeBaseService {
     }
   }
 
-  /**
-   * Precise Modeの結果をインデックス
-   */
+  
   private async indexPreciseResults(
     kb: KnowledgeBase,
     userId: string,
@@ -621,11 +615,11 @@ export class KnowledgeBaseService {
   ): Promise<void> {
     this.logger.log(`Indexing ${results.length} precise results for ${kb.id}`);
 
-    // インデックスの存在を確認 - 実際のモデル次元数を取得
+    
     const actualDimensions = await this.getActualModelDimensions(embeddingModelId, userId, tenantId);
     await this.elasticsearchService.createIndexIfNotExists(actualDimensions);
 
-    // ベクトル化とインデックスをバッチ処理
+    
     const batchSize = parseInt(process.env.CHUNK_BATCH_SIZE || '50');
 
     for (let i = 0; i < results.length; i += batchSize) {
@@ -633,14 +627,14 @@ export class KnowledgeBaseService {
       const texts = batch.map(r => r.text);
 
       try {
-        // ベクトルを生成
+        
         const embeddings = await this.embeddingService.getEmbeddings(
           texts,
           userId,
           embeddingModelId
         );
 
-        // 各結果をインデックス
+        
         for (let j = 0; j < batch.length; j++) {
           const result = batch[j];
           const embedding = embeddings[j];
@@ -680,20 +674,18 @@ export class KnowledgeBaseService {
     this.logger.log(`Precise mode indexing complete: ${results.length} pages`);
   }
 
-  /**
-   * PDF の特定ページの画像を取得
-   */
+  
   async getPageAsImage(fileId: string, pageIndex: number, userId: string, tenantId: string): Promise<string> {
     const pdfPath = await this.ensurePDFExists(fileId, userId, tenantId);
 
-    // 特定のページを変換
+    
     const result = await this.pdf2ImageService.convertToImages(pdfPath, {
       density: 150,
       quality: 75,
       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 }));
@@ -713,14 +705,14 @@ export class KnowledgeBaseService {
       const kb = await this.kbRepository.findOne({ where: { id: kbId, tenantId } });
       if (!kb) return;
 
-      // メモリ監視 - ベクトル化前チェック
+      
       const memBeforeChunk = this.memoryMonitor.getMemoryUsage();
       this.logger.log(
         `Memory before vectorization: ${memBeforeChunk.heapUsed}/${memBeforeChunk.heapTotal}MB`,
       );
 
       this.logger.debug(`File ${kbId}: Validating chunk config...`);
-      // 1. Chunk configurationの検証と修正(モデルの制限と環境変数に基づく)
+      
       const validatedConfig = await this.chunkConfigService.validateChunkConfig(
         kb.chunkSize,
         kb.chunkOverlap,
@@ -729,13 +721,13 @@ export class KnowledgeBaseService {
       );
       this.logger.debug(`File ${kbId}: Chunk config validated.`);
 
-      // 設定が修正された場合、警告を記録しデータベースを更新
+      
       if (validatedConfig.warnings.length > 0) {
         this.logger.warn(
           this.i18nService.formatMessage('chunkConfigCorrection', { warnings: validatedConfig.warnings.join(', ') })
         );
 
-        // データベース内の設定を更新
+        
         if (validatedConfig.chunkSize !== kb.chunkSize ||
           validatedConfig.chunkOverlap !== kb.chunkOverlap) {
           await this.kbRepository.update(kbId, {
@@ -745,7 +737,7 @@ export class KnowledgeBaseService {
         }
       }
 
-      // 設定サマリーを表示(実際に適用される上限を含む)
+      
       this.logger.debug(`File ${kbId}: Getting config summary...`);
       const configSummary = await this.chunkConfigService.getConfigSummary(
         validatedConfig.chunkSize,
@@ -756,7 +748,7 @@ export class KnowledgeBaseService {
       this.logger.log(`Chunk configuration: ${configSummary}`);
       this.logger.log(`Configuration limits: Chunk=${validatedConfig.effectiveMaxChunkSize}, Overlap=${validatedConfig.effectiveMaxOverlapSize}`);
 
-      // 2. 検証済みの設定を使用してチャンク分割
+      
       const chunks = this.textChunkerService.chunkText(
         text,
         validatedConfig.chunkSize,
@@ -770,7 +762,7 @@ export class KnowledgeBaseService {
         return;
       }
 
-      // 3. チャンク数が妥当か確認
+      
       const estimatedChunkCount = this.chunkConfigService.estimateChunkCount(
         text.length,
         validatedConfig.chunkSize,
@@ -781,7 +773,7 @@ export class KnowledgeBaseService {
         );
       }
 
-      // 4. 推奨バッチサイズを取得(モデルの制限に基づく)
+      
       const recommendedBatchSize = await this.chunkConfigService.getRecommendedBatchSize(
         kb.embeddingModelId,
         userId,
@@ -789,7 +781,7 @@ export class KnowledgeBaseService {
         parseInt(process.env.CHUNK_BATCH_SIZE || '100'),
       );
 
-      // 5. メモリ使用量を推定
+      
       const avgChunkSize = chunks.reduce((sum, c) => sum + c.content.length, 0) / chunks.length;
       const estimatedMemory = this.memoryMonitor.estimateMemoryUsage(
         chunks.length,
@@ -798,11 +790,11 @@ export class KnowledgeBaseService {
       );
       this.logger.log(`Estimated memory usage: ${estimatedMemory}MB (Batch Size: ${recommendedBatchSize})`);
 
-      // 6. 実際のモデル次元数を取得し、インデックスの存在を確認
+      
       const actualDimensions = await this.getActualModelDimensions(kb.embeddingModelId, userId, tenantId);
       await this.elasticsearchService.createIndexIfNotExists(actualDimensions);
 
-      // 7. ベクトル化とインデックス作成をバッチ処理
+      
       const useBatching = this.memoryMonitor.shouldUseBatching(
         chunks.length,
         avgChunkSize,
@@ -814,7 +806,7 @@ export class KnowledgeBaseService {
           await this.processInBatches(
             chunks,
             async (batch, batchIndex) => {
-              // バッチサイズがモデルの制限を超えていないか検証
+              
               if (batch.length > recommendedBatchSize) {
                 this.logger.warn(
                   this.i18nService.formatMessage('batchSizeExceeded', { index: batchIndex, actual: batch.length, limit: recommendedBatchSize })
@@ -828,14 +820,14 @@ export class KnowledgeBaseService {
                 kb.embeddingModelId,
               );
 
-              // 次元の整合性を検証
+              
               if (embeddings.length > 0 && embeddings[0].length !== actualDimensions) {
                 this.logger.warn(
                   `Vector dimension mismatch: Expected ${actualDimensions}, Actual ${embeddings[0].length}`
                 );
               }
 
-              // このバッチデータを即座にインデックス
+              
               for (let i = 0; i < batch.length; i++) {
                 const chunk = batch[i];
                 const embedding = embeddings[i];
@@ -874,17 +866,17 @@ export class KnowledgeBaseService {
             },
           );
         } catch (error) {
-          // コンテキスト長エラーを検出(Japanese・中国語・英語に対応)
-          if (error.message && (error.message.includes('context length') || error.message.includes('コンテキスト長 exceeds limit ') || error.message.includes('コンテキスト長 exceeds limit '))) {
+          
+          if (error.message && (error.message.includes('context length') || error.message.includes('context length exceeds limit ') || error.message.includes('context length exceeds limit '))) {
             this.logger.warn(this.i18nService.getMessage('contextLengthErrorFallback'));
 
-            // 単一テキスト処理にダウングレード
+            
             for (let i = 0; i < chunks.length; i++) {
               const chunk = chunks[i];
 
               try {
                 const embeddings = await this.embeddingService.getEmbeddings(
-                  [chunk.content], // 単一テキスト
+                  [chunk.content], 
                   userId,
                   kb.embeddingModelId,
                 );
@@ -923,15 +915,15 @@ export class KnowledgeBaseService {
 
             this.logger.log(`Single text processing complete: ${chunks.length} chunks`);
           } else {
-            // その他のエラーは直接スロー
+            
             throw error;
           }
         }
       } else {
-        // 小さなファイル、一括処理(ただしバッチ制限の確認が必要)
+        
         const chunkTexts = chunks.map((chunk) => chunk.content);
 
-        // チャンク数がモデルのバッチ制限を超える場合は、強制的にバッチ処理
+        
         if (chunks.length > recommendedBatchSize) {
           this.logger.warn(
             this.i18nService.formatMessage('chunkLimitExceededForceBatch', { actual: chunks.length, limit: recommendedBatchSize })
@@ -975,17 +967,17 @@ export class KnowledgeBaseService {
               },
             );
           } catch (error) {
-            // コンテキスト長エラーを検出(Japanese・中国語・英語に対応)
-            if (error.message && (error.message.includes('context length') || error.message.includes('コンテキスト長 exceeds limit ') || error.message.includes('コンテキスト長 exceeds limit '))) {
+            
+            if (error.message && (error.message.includes('context length') || error.message.includes('context length exceeds limit ') || error.message.includes('context length exceeds limit '))) {
               this.logger.warn(this.i18nService.getMessage('batchContextLengthErrorFallback'));
 
-              // 単一テキスト処理にダウングレード
+              
               for (let i = 0; i < chunks.length; i++) {
                 const chunk = chunks[i];
 
                 try {
                   const embeddings = await this.embeddingService.getEmbeddings(
-                    [chunk.content], // 単一テキスト
+                    [chunk.content], 
                     userId,
                     kb.embeddingModelId,
                   );
@@ -1024,12 +1016,12 @@ export class KnowledgeBaseService {
 
               this.logger.log(this.i18nService.formatMessage('singleTextProcessingComplete', { count: chunks.length }));
             } else {
-              // その他のエラー、直接スロー
+              
               throw error;
             }
           }
         } else {
-          // 十分に小さいファイルの場合は一括で処理
+          
           try {
             const embeddings = await this.embeddingService.getEmbeddings(
               chunkTexts,
@@ -1063,17 +1055,17 @@ export class KnowledgeBaseService {
               );
             }
           } catch (error) {
-            // コンテキスト長エラーを検出(Japanese・中国語・英語に対応)
-            if (error.message && (error.message.includes('context length') || error.message.includes('コンテキスト長 exceeds limit ') || error.message.includes('コンテキスト長 exceeds limit '))) {
+            
+            if (error.message && (error.message.includes('context length') || error.message.includes('context length exceeds limit ') || error.message.includes('context length exceeds limit '))) {
               this.logger.warn(this.i18nService.getMessage('batchContextLengthErrorFallback'));
 
-              // 単一テキスト処理にダウングレード
+              
               for (let i = 0; i < chunks.length; i++) {
                 const chunk = chunks[i];
 
                 try {
                   const embeddings = await this.embeddingService.getEmbeddings(
-                    [chunk.content], // 単一テキスト
+                    [chunk.content], 
                     userId,
                     kb.embeddingModelId,
                   );
@@ -1112,7 +1104,7 @@ export class KnowledgeBaseService {
 
               this.logger.log(this.i18nService.formatMessage('singleTextProcessingComplete', { count: chunks.length }));
             } else {
-              // その他のエラー、直接スロー
+              
               throw error;
             }
           }
@@ -1127,7 +1119,7 @@ export class KnowledgeBaseService {
     } catch (error) {
       this.logger.error(this.i18nService.formatMessage('fileVectorizationFailed', { id: kbId }), error);
 
-      // エラー情報を metadata に保存
+      
       try {
         const kb = await this.kbRepository.findOne({ where: { id: kbId } });
         if (kb) {
@@ -1144,9 +1136,7 @@ export class KnowledgeBaseService {
     }
   }
 
-  /**
-   * バッチ処理、メモリ制御付き
-   */
+  
   private async processInBatches<T>(
     items: T[],
     processor: (batch: T[], batchIndex: number) => Promise<void>,
@@ -1166,19 +1156,19 @@ export class KnowledgeBaseService {
     const totalBatches = Math.ceil(totalItems / initialBatchSize);
 
     for (let i = 0; i < totalItems;) {
-      // メモリを確認し待機
+      
       await this.memoryMonitor.waitForMemoryAvailable();
 
-      // バッチサイズを動的に調整 (initialBatchSize から開始し、必要に応じてメモリモニターが削減できるようにします)
-      // 注意: memoryMonitor.getDynamicBatchSize はメモリ状況に基づいてより大きな値を返す可能性がありますが、
-      // モデルの制限 (initialBatchSize) を尊重する必要があります。
+      
+      
+      
       const currentMem = this.memoryMonitor.getMemoryUsage().heapUsed;
       const dynamicBatchSize = this.memoryMonitor.getDynamicBatchSize(currentMem);
 
       // Ensure we don't exceed the model's limit (initialBatchSize) even if memory allows more
       const batchSize = Math.min(dynamicBatchSize, initialBatchSize);
 
-      // 現在のバッチを取得
+      
       const batch = items.slice(i, i + batchSize);
       const batchIndex = Math.floor(i / batchSize) + 1;
 
@@ -1186,20 +1176,20 @@ export class KnowledgeBaseService {
         this.i18nService.formatMessage('batchProcessingProgress', { index: batchIndex, total: totalBatches, count: batch.length })
       );
 
-      // バッチを処理
+      
       await processor(batch, batchIndex);
 
-      // コールバック通知
+      
       if (options?.onBatchComplete) {
         options.onBatchComplete(batchIndex, totalBatches);
       }
 
-      // 強制GC(メモリがしきい値に近い場合)
+      
       if (currentMem > 800) {
         this.memoryMonitor.forceGC();
       }
 
-      // 参照をクリアしGCを助ける
+      
       batch.length = 0;
 
       i += batchSize;
@@ -1209,9 +1199,7 @@ export class KnowledgeBaseService {
     this.logger.log(this.i18nService.formatMessage('batchProcessingComplete', { count: totalItems, duration }));
   }
 
-  /**
-   * 失敗したファイルのベクトル化を再試行
-   */
+  
   async retryFailedFile(fileId: string, userId: string, tenantId: string): Promise<KnowledgeBase> {
     this.logger.log(`Retrying failed file ${fileId} for user ${userId} in tenant ${tenantId}`);
 
@@ -1221,7 +1209,7 @@ export class KnowledgeBaseService {
     });
 
     if (!kb) {
-      throw new NotFoundException('ファイルが存在しません');
+      throw new NotFoundException('File does not exist');
     }
 
     if (kb.status !== FileStatus.FAILED) {
@@ -1232,10 +1220,10 @@ export class KnowledgeBaseService {
       throw new Error(this.i18nService.getMessage('emptyFileRetryFailed'));
     }
 
-    // 2. ステータスを INDEXING にリセット
+    
     await this.updateStatus(fileId, FileStatus.INDEXING);
 
-    // 3. 非同期でベクトル化をトリガー(既存ロジックを再利用)
+    
     this.vectorizeToElasticsearch(
       fileId,
       userId,
@@ -1250,17 +1238,15 @@ export class KnowledgeBaseService {
       this.logger.error(`Retry vectorization failed for file ${fileId}`, err);
     });
 
-    // 4. 更新後のファイルステータスを返却
+    
     const updatedKb = await this.kbRepository.findOne({ where: { id: fileId, tenantId } });
     if (!updatedKb) {
-      throw new NotFoundException('ファイルが存在しません');
+      throw new NotFoundException('File does not exist');
     }
     return updatedKb;
   }
 
-  /**
-   * ファイルのすべてのチャンク情報を取得
-   */
+  
   async getFileChunks(fileId: string, userId: string, tenantId: string) {
     this.logger.log(`Getting chunks for file ${fileId}, user ${userId}, tenant ${tenantId}`);
 
@@ -1270,13 +1256,13 @@ export class KnowledgeBaseService {
     });
 
     if (!kb) {
-      throw new NotFoundException('ファイルが存在しません');
+      throw new NotFoundException('File does not exist');
     }
 
-    // 2. Elasticsearch からすべてのチャンクを取得
+    
     const chunks = await this.elasticsearchService.getFileChunks(fileId, userId, tenantId);
 
-    // 3. チャンク情報を返却
+    
     return {
       fileId: kb.id,
       fileName: kb.originalName,
@@ -1297,7 +1283,7 @@ export class KnowledgeBaseService {
     await this.kbRepository.update(id, { status });
   }
 
-  // PDF プレビュー関連メソッド
+  
   async ensurePDFExists(fileId: string, userId: string, tenantId: string, force: boolean = false): Promise<string> {
     const kb = await this.kbRepository.findOne({
       where: { id: fileId, tenantId },
@@ -1307,12 +1293,12 @@ export class KnowledgeBaseService {
       throw new NotFoundException(this.i18nService.getMessage('fileNotFound'));
     }
 
-    // 元ファイルが PDF の場合は、元ファイルのパスを直接返す
+    
     if (kb.mimetype === 'application/pdf') {
       return kb.storagePath;
     }
 
-    // プレビュー変換に対応しているか確認(ドキュメント類または画像類のみ許可)
+    
     const ext = kb.originalName.toLowerCase().split('.').pop() || '';
     const isConvertible = [...DOC_EXTENSIONS, ...IMAGE_EXTENSIONS].includes(ext);
 
@@ -1321,14 +1307,14 @@ export class KnowledgeBaseService {
       throw new Error(this.i18nService.getMessage('pdfPreviewNotSupported'));
     }
 
-    // PDF フィールドパスを生成
+    
     const path = await import('path');
     const fs = await import('fs');
     const uploadDir = path.dirname(kb.storagePath);
     const baseName = path.basename(kb.storagePath, path.extname(kb.storagePath));
     const pdfPath = path.join(uploadDir, `${baseName}.pdf`);
 
-    // 強制再生成が指定され、ファイルが存在する場合は削除
+    
     if (force && fs.existsSync(pdfPath)) {
       try {
         fs.unlinkSync(pdfPath);
@@ -1338,7 +1324,7 @@ export class KnowledgeBaseService {
       }
     }
 
-    // 変換済みかつ強制再生成が不要か確認
+    
     if (fs.existsSync(pdfPath) && !force) {
       if (!kb.pdfPath) {
         await this.kbRepository.update(kb.id, { pdfPath: pdfPath });
@@ -1346,14 +1332,14 @@ export class KnowledgeBaseService {
       return pdfPath;
     }
 
-    // PDF への変換が必要
+    
     try {
       this.logger.log(`Starting PDF conversion for ${kb.originalName} at ${kb.storagePath}`);
 
-      // ファイルを変換
+      
       await this.libreOfficeService.convertToPDF(kb.storagePath);
 
-      // 変換結果を確認
+      
       if (!fs.existsSync(pdfPath)) {
         throw new Error(`PDF conversion completed but file not found at ${pdfPath}`);
       }
@@ -1383,7 +1369,7 @@ export class KnowledgeBaseService {
       throw new NotFoundException(this.i18nService.getMessage('fileNotFound'));
     }
 
-    // 元ファイルが PDF の場合
+    
     if (kb.mimetype === 'application/pdf') {
       const token = this.generateTempToken(fileId, userId, tenantId);
       return {
@@ -1392,14 +1378,14 @@ export class KnowledgeBaseService {
       };
     }
 
-    // PDF ファイルパスを生成
+    
     const path = await import('path');
     const fs = await import('fs');
     const uploadDir = path.dirname(kb.storagePath);
     const baseName = path.basename(kb.storagePath, path.extname(kb.storagePath));
     const pdfPath = path.join(uploadDir, `${baseName}.pdf`);
 
-    // 変換済みか確認
+    
     if (fs.existsSync(pdfPath)) {
       if (!kb.pdfPath) {
         kb.pdfPath = pdfPath;
@@ -1412,7 +1398,7 @@ export class KnowledgeBaseService {
       };
     }
 
-    // 変換が必要
+    
     return {
       status: 'pending',
     };
@@ -1433,16 +1419,14 @@ export class KnowledgeBaseService {
     );
   }
 
-  /**
-   * モデルの実際の次元数を取得(キャッシュ確認とプローブロジック付き)
-   */
+  
   private async getActualModelDimensions(embeddingModelId: string, userId: string, tenantId: string): Promise<number> {
     const defaultDimensions = parseInt(
       process.env.DEFAULT_VECTOR_DIMENSIONS || '2560',
     );
 
     try {
-      // 1. モデル設定から優先的に取得
+      
       const modelConfig = await this.modelConfigService.findOne(
         embeddingModelId,
         userId,
@@ -1454,7 +1438,7 @@ export class KnowledgeBaseService {
         return modelConfig.dimensions;
       }
 
-      // 2. それ以外の場合はプローブにより取得
+      
       this.logger.log(`Probing model dimensions: ${embeddingModelId}`);
       const probeEmbeddings = await this.embeddingService.getEmbeddings(
         ['probe'],
@@ -1466,7 +1450,7 @@ export class KnowledgeBaseService {
         const actualDimensions = probeEmbeddings[0].length;
         this.logger.log(`Detected actual model dimensions: ${actualDimensions}`);
 
-        // 次回利用のためにモデル設定を更新
+        
         if (modelConfig) {
           try {
             await this.modelConfigService.update(userId, tenantId, modelConfig.id, {
@@ -1490,9 +1474,7 @@ export class KnowledgeBaseService {
     return defaultDimensions;
   }
 
-  /**
-   * AIを使用して文書のタイトルを自動生成する
-   */
+  
   async generateTitle(kbId: string): Promise<string | null> {
     this.logger.log(`Generating automatic title for file ${kbId}`);
 
@@ -1503,22 +1485,22 @@ export class KnowledgeBaseService {
       }
       const tenantId = kb.tenantId;
 
-      // すでにタイトルがある場合はスキップ
+      
       if (kb.title) {
         return kb.title;
       }
 
-      // コンテンツの冒頭サンプルを取得(最大2500文字)
+      
       const contentSample = kb.content.substring(0, 2500);
 
-      // ユーザー設定から言語を取得、またはデフォルトを使用
+      
       const settings = await this.userSettingService.findOrCreate(kb.userId);
       const language = settings.language || 'ja';
 
-      // プロンプトを構築
+      
       const prompt = this.i18nService.getDocumentTitlePrompt(language, contentSample);
 
-      // LLMを呼び出してタイトルを生成
+      
       let generatedTitle: string | undefined;
       try {
         generatedTitle = await this.chatService.generateSimpleChat(
@@ -1532,11 +1514,11 @@ export class KnowledgeBaseService {
       }
 
       if (generatedTitle && generatedTitle.trim().length > 0) {
-        // 余分な引用符や改行を除去
+        
         const cleanedTitle = generatedTitle.trim().replace(/^["']|["']$/g, '').substring(0, 100);
         await this.kbRepository.update(kbId, { title: cleanedTitle });
 
-        // Elasticsearch のチャンクも更新
+        
         await this.elasticsearchService.updateTitleByFileId(kbId, cleanedTitle, tenantId).catch((err) => {
           this.logger.error(`Failed to update title in Elasticsearch for ${kbId}`, err);
         });

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

@@ -1,10 +1,10 @@
 import { Injectable, Logger } from '@nestjs/common';
 
 export interface MemoryStats {
-  heapUsed: number;    // 使用済みヒープメモリ (MB)
-  heapTotal: number;   // 総ヒープメモリ (MB)
-  external: number;    // 外部メモリ (MB)
-  rss: number;         // RSS (常駐セットサイズ) (MB)
+  heapUsed: number;    
+  heapTotal: number;   
+  external: number;    
+  rss: number;         
   timestamp: Date;
 }
 
@@ -16,17 +16,15 @@ export class MemoryMonitorService {
   private readonly GC_THRESHOLD_MB: number;
 
   constructor() {
-    // 環境変数から設定を読み込む。デフォルト値はメモリ最適化用
-    this.MAX_MEMORY_MB = parseInt(process.env.MAX_MEMORY_USAGE_MB || '1024'); // 1GB上限
-    this.BATCH_SIZE = parseInt(process.env.CHUNK_BATCH_SIZE || '100'); // 1バッチあたり100チャンク
-    this.GC_THRESHOLD_MB = parseInt(process.env.GC_THRESHOLD_MB || '800'); // 800MBでGCをトリガー
+    
+    this.MAX_MEMORY_MB = parseInt(process.env.MAX_MEMORY_USAGE_MB || '1024'); 
+    this.BATCH_SIZE = parseInt(process.env.CHUNK_BATCH_SIZE || '100'); 
+    this.GC_THRESHOLD_MB = parseInt(process.env.GC_THRESHOLD_MB || '800'); 
 
     this.logger.log(`Initialized memory monitoring: Limit=${this.MAX_MEMORY_MB}MB, Batch Size=${this.BATCH_SIZE}, GC Threshold=${this.GC_THRESHOLD_MB}MB`);
   }
 
-  /**
-   * 現在のメモリ使用状況を取得
-   */
+  
   getMemoryUsage(): MemoryStats {
     const usage = process.memoryUsage();
     return {
@@ -38,30 +36,26 @@ export class MemoryMonitorService {
     };
   }
 
-  /**
-   * メモリ exceeds limit に近づいているかチェック
-   */
+  
   isMemoryHigh(): boolean {
     const usage = this.getMemoryUsage();
-    return usage.heapUsed > this.MAX_MEMORY_MB * 0.85; // 85%閾値
+    return usage.heapUsed > this.MAX_MEMORY_MB * 0.85; 
   }
 
-  /**
-   * メモリが利用可能になるまで待機(タイムアウトあり)
-   */
+  
   async waitForMemoryAvailable(timeoutMs: number = 30000): Promise<void> {
     const startTime = Date.now();
 
     while (this.isMemoryHigh()) {
       if (Date.now() - startTime > timeoutMs) {
-        throw new Error(`メモリ待機がタイムアウトしました: 現在 ${this.getMemoryUsage().heapUsed}MB > ${this.MAX_MEMORY_MB * 0.85}MB`);
+        throw new Error(`Memory wait timed out: Currently ${this.getMemoryUsage().heapUsed}MB > ${this.MAX_MEMORY_MB * 0.85}MB`);
       }
 
       this.logger.warn(
         `Memory usage is too high. Waiting for release... ${this.getMemoryUsage().heapUsed}/${this.MAX_MEMORY_MB}MB`,
       );
 
-      // ガベージコレクションを強制実行(可能な場合)
+      
       if (global.gc) {
         this.logger.log('Running forced garbage collection...');
         global.gc();
@@ -71,9 +65,7 @@ export class MemoryMonitorService {
     }
   }
 
-  /**
-   * ガベージコレクションを強制実行(可能な場合)
-   */
+  
   forceGC(): void {
     if (global.gc) {
       const before = this.getMemoryUsage();
@@ -85,21 +77,19 @@ export class MemoryMonitorService {
     }
   }
 
-  /**
-   * バッチサイズを動的に調整
-   */
+  
   getDynamicBatchSize(currentMemoryMB: number): number {
     const baseBatchSize = this.BATCH_SIZE;
 
     if (currentMemoryMB > this.GC_THRESHOLD_MB) {
-      // メモリ逼迫、バッチサイズを削減
+      
       const reduced = Math.max(10, Math.floor(baseBatchSize * 0.5));
       this.logger.warn(
         `Memory constrained (${currentMemoryMB}MB), dynamically adjusting batch size: ${baseBatchSize} → ${reduced}`,
       );
       return reduced;
     } else if (currentMemoryMB < this.MAX_MEMORY_MB * 0.4) {
-      // メモリに余裕あり、バッチサイズを増量
+      
       const increased = Math.min(200, Math.floor(baseBatchSize * 1.2));
       if (increased > baseBatchSize) {
         this.logger.log(
@@ -112,9 +102,7 @@ export class MemoryMonitorService {
     return baseBatchSize;
   }
 
-  /**
-   * 大規模データの処理:自動バッチングとメモリ制御
-   */
+  
   async processInBatches<T, R>(
     items: T[],
     processor: (batch: T[], batchIndex: number) => Promise<R[]>,
@@ -133,14 +121,14 @@ export class MemoryMonitorService {
     let processedCount = 0;
 
     for (let i = 0; i < totalItems;) {
-      // メモリ状態をチェックして待機
+      
       await this.waitForMemoryAvailable();
 
-      // バッチサイズを動的に調整
+      
       const currentMem = this.getMemoryUsage().heapUsed;
       const batchSize = this.getDynamicBatchSize(currentMem);
 
-      // 現在のバッチを取得
+      
       const batch = items.slice(i, i + batchSize);
       const batchIndex = Math.floor(i / batchSize) + 1;
       const totalBatches = Math.ceil(totalItems / batchSize);
@@ -149,22 +137,22 @@ export class MemoryMonitorService {
         `Processing batch ${batchIndex}/${totalBatches}: ${batch.length} items (Total ${processedCount}/${totalItems})`,
       );
 
-      // バッチを処理
+      
       const batchResults = await processor(batch, batchIndex);
       allResults.push(...batchResults);
       processedCount += batch.length;
 
-      // コールバック通知
+      
       if (options?.onBatchComplete) {
         await options.onBatchComplete(batchIndex, totalBatches, batchResults);
       }
 
-      // メモリが閾値に近い場合はGCを強制実行
+      
       if (currentMem > this.GC_THRESHOLD_MB) {
         this.forceGC();
       }
 
-      // GCを助けるために参照をクリア
+      
       batch.length = 0;
 
       i += batchSize;
@@ -179,17 +167,15 @@ export class MemoryMonitorService {
     return allResults;
   }
 
-  /**
-   * 処理に必要なメモリを見積もる
-   */
+  
   estimateMemoryUsage(itemCount: number, itemSizeBytes: number, vectorDim: number): number {
-    // テキスト内容のメモリ
+    
     const textMemory = itemCount * itemSizeBytes;
 
-    // ベクトルメモリ (各ベクトル: 次元 × 4バイト)
+    
     const vectorMemory = itemCount * vectorDim * 4;
 
-    // オブジェクトのオーバーヘッド (各オブジェクトにつきAddedで約100バイトと推定)
+    
     const overhead = itemCount * 100;
 
     const totalMB = Math.round((textMemory + vectorMemory + overhead) / 1024 / 1024);
@@ -197,12 +183,10 @@ export class MemoryMonitorService {
     return totalMB;
   }
 
-  /**
-   * バッチ処理を使用すべきかチェック
-   */
+  
   shouldUseBatching(itemCount: number, itemSizeBytes: number, vectorDim: number): boolean {
     const estimatedMB = this.estimateMemoryUsage(itemCount, itemSizeBytes, vectorDim);
-    const threshold = this.MAX_MEMORY_MB * 0.7; // 70%閾値
+    const threshold = this.MAX_MEMORY_MB * 0.7; 
 
     if (estimatedMB > threshold) {
       this.logger.warn(
@@ -214,20 +198,18 @@ export class MemoryMonitorService {
     return false;
   }
 
-  /**
-   * 推奨されるバッチサイズを取得
-   */
+  
   getRecommendedBatchSize(itemSizeBytes: number, vectorDim: number): number {
-    // 目標:1バッチあたり最大 200MB メモリ
+    
     const targetMemoryMB = 200;
     const targetMemoryBytes = targetMemoryMB * 1024 * 1024;
 
-    // 1項目あたりのメモリ = テキスト + ベクトル + オーバーヘッド
+    
     const singleItemMemory = itemSizeBytes + (vectorDim * 4) + 100;
 
     const batchSize = Math.floor(targetMemoryBytes / singleItemMemory);
 
-    // 限制在 10-200 之间
+    
     return Math.max(10, Math.min(200, batchSize));
   }
 }

+ 3 - 3
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;
 
-    // テキスト長がChunk size以下の場合は、テキスト全体を1つのチャンクとして直接返す
+    
     if (cleanText.length <= chunkSizeInChars) {
       return [
         {
@@ -41,7 +41,7 @@ export class TextChunkerService {
     while (start < cleanText.length) {
       let end = Math.min(start + chunkSizeInChars, cleanText.length);
 
-      // 文の境界で分割
+      
       if (end < cleanText.length) {
         const sentenceEnd = this.findSentenceEnd(
           cleanText,
@@ -69,7 +69,7 @@ export class TextChunkerService {
         break;
       }
 
-      // 次のチャンクの開始位置を計算
+      
       const newStart = end - overlapInChars;
       // Protect against infinite loop if overlap is too large or chunk too small
       if (newStart <= start) {

+ 2 - 4
server/src/libreoffice/libreoffice.interface.ts

@@ -1,10 +1,8 @@
-/**
- * LibreOffice サービスインターフェース定義
- */
+
 
 export interface LibreOfficeConvertResponse {
   pdf_path?: string;
-  pdf_data?: string; // base64 エンコードされた PDF データ
+  pdf_data?: string; 
   converted: boolean;
   original: string;
   file_size: number;

+ 28 - 38
server/src/libreoffice/libreoffice.service.ts

@@ -22,9 +22,7 @@ export class LibreOfficeService implements OnModuleInit {
     this.logger.log(`LibreOffice service initialized with base URL: ${this.baseUrl}`);
   }
 
-  /**
-   * LibreOffice サービスの状態をチェック
-   */
+  
   async healthCheck(): Promise<boolean> {
     try {
       const response = await axios.get<LibreOfficeHealthResponse>(
@@ -38,70 +36,66 @@ export class LibreOfficeService implements OnModuleInit {
     }
   }
 
-  /**
-   * ドキュメントを PDF に変換
-   * @param filePath 変換するファイルのパス
-   * @returns PDF ファイルのパス
-   */
+  
   async convertToPDF(filePath: string): Promise<string> {
     const fileName = path.basename(filePath);
     const ext = path.extname(fileName).toLowerCase();
 
-    // PDF の場合は元のパスを直接返す
+    
     if (ext === '.pdf') {
       this.logger.log(`File is already PDF: ${filePath}`);
       return filePath;
     }
 
-    // ファイルの存在確認
+    
     try {
       await fs.access(filePath);
     } catch {
-      throw new Error(`ファイルが存在しません: ${filePath}`);
+      throw new Error(`File does not exist: ${filePath}`);
     }
 
-    // 出力先 PDF のパスを生成
+    
     const dir = path.dirname(filePath);
     const baseName = path.basename(filePath, ext);
     const targetPdfPath = path.join(dir, `${baseName}.pdf`);
 
-    // PDF が既に存在する場合は直接返す
+    
     try {
       await fs.access(targetPdfPath);
       this.logger.log(`PDF already exists: ${targetPdfPath}`);
       return targetPdfPath;
     } catch {
-      // PDF が存在しないため、変換が必要
+      
     }
 
-    // ファイルの読み込み
+    
     const fileBuffer = await fs.readFile(filePath);
 
-    // FormData の構築
+    
     const formData = new FormData();
     formData.append('file', fileBuffer, fileName);
 
     this.logger.log(`Converting ${fileName} to PDF...`);
 
-    // 変換の再試行回数
+    
     const maxRetries = 3;
     let lastError: any;
 
     for (let attempt = 1; attempt <= maxRetries; attempt++) {
       try {
-        // LibreOffice サービスの呼び出し
+        
         const response = await axios.post(
           `${this.baseUrl}/convert`,
           formData,
           {
             headers: formData.getHeaders(),
-            timeout: 300000, // 5分タイムアウト
-            responseType: 'stream', // ファイルストリームを受信
-            maxRedirects: 5, // リダイレクトの最大数
+            timeout: 300000, 
+            responseType: 'stream', 
+            maxRedirects: 5, 
           }
         );
 
-        // ストリームを出力ファイルに書き込む
+        
         const writer = (await import('fs')).createWriteStream(targetPdfPath);
         response.data.pipe(writer);
 
@@ -120,21 +114,21 @@ export class LibreOfficeService implements OnModuleInit {
         this.logger.error(`Attempt ${attempt} failed for ${fileName}: ${error.message}`);
         lastError = error;
 
-        // socket hang up や接続エラーの場合は少し待機して再試行
+        
         if (error.code === 'ECONNRESET' || error.code === 'ECONNREFUSED' || error.code === 'ETIMEDOUT' || error.message.includes('socket hang up')) {
           if (attempt < maxRetries) {
-            const delay = 2000 * attempt; // だんだん増える遅延
+            const delay = 2000 * attempt; 
             this.logger.log(`Waiting ${delay}ms before retry...`);
             await new Promise(resolve => setTimeout(resolve, delay));
           }
         } else {
-          // その他のエラーは再試行しない
+          
           break;
         }
       }
     }
 
-    // 全ての再試行が失敗した場合、詳細なエラーハンドリングを行う
+    
     if (lastError.response) {
       try {
         const stream = lastError.response.data;
@@ -154,29 +148,27 @@ export class LibreOfficeService implements OnModuleInit {
         }
 
         if (lastError.response.status === 504) {
-          throw new Error('変換がタイムアウトしました。ファイルが大きすぎる可能性があります');
+          throw new Error('Conversion timed out. File may be too large');
         }
-        throw new Error(`変換に失敗しました: ${detail}`);
+        throw new Error(`Conversion failed: ${detail}`);
 
       } catch (streamError) {
         this.logger.error('Error reading error stream:', streamError);
-        throw new Error(`変換に失敗しました: ${lastError.message}`);
+        throw new Error(`Conversion failed: ${lastError.message}`);
       }
     }
 
     this.logger.error(`Conversion failed for ${fileName} after ${maxRetries} attempts:`, lastError.message);
     if (lastError.code === 'ECONNREFUSED') {
-      throw new Error('LibreOffice サービスが実行されていません。サービスの状態を確認してください');
+      throw new Error('LibreOffice service is not running. Please check the status of the service');
     }
     if (lastError.code === 'ECONNRESET' || lastError.message.includes('socket hang up')) {
-      throw new Error('LibreOffice サービスとの接続が切断されました。サービスが不安定である可能性があります');
+      throw new Error('The connection to the LibreOffice service has been lost. The service may be unstable');
     }
-    throw new Error(`変換に失敗しました: ${lastError.message}`);
+    throw new Error(`Conversion failed: ${lastError.message}`);
   }
 
-  /**
-   * ファイルの一括変換
-   */
+  
   async batchConvert(filePaths: string[]): Promise<string[]> {
     const results: string[] = [];
     for (const filePath of filePaths) {
@@ -191,9 +183,7 @@ export class LibreOfficeService implements OnModuleInit {
     return results;
   }
 
-  /**
-   * サービスのバージョン情報を取得
-   */
+  
   async getVersion(): Promise<any> {
     try {
       const response = await axios.get(`${this.baseUrl}/version`);

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

@@ -4,7 +4,7 @@ export class AddKnowledgeBaseEnhancements1737800000000 implements MigrationInter
   name = 'AddKnowledgeBaseEnhancements1737800000000';
 
   public async up(queryRunner: QueryRunner): Promise<void> {
-    // 知識ベースグループテーブルの作成
+    
     await queryRunner.query(`
       CREATE TABLE "knowledge_groups" (
         "id" varchar PRIMARY KEY NOT NULL,
@@ -17,7 +17,7 @@ export class AddKnowledgeBaseEnhancements1737800000000 implements MigrationInter
       )
     `);
 
-    // ドキュメントグループ関連テーブルの作成
+    
     await queryRunner.query(`
       CREATE TABLE "knowledge_base_groups" (
         "knowledge_base_id" varchar NOT NULL,
@@ -29,7 +29,7 @@ export class AddKnowledgeBaseEnhancements1737800000000 implements MigrationInter
       )
     `);
 
-    // 検索履歴テーブルの作成
+    
     await queryRunner.query(`
       CREATE TABLE "search_history" (
         "id" varchar PRIMARY KEY NOT NULL,
@@ -41,7 +41,7 @@ export class AddKnowledgeBaseEnhancements1737800000000 implements MigrationInter
       )
     `);
 
-    // 会話メッセージテーブルの作成
+    
     await queryRunner.query(`
       CREATE TABLE "chat_messages" (
         "id" varchar PRIMARY KEY NOT NULL,
@@ -54,27 +54,27 @@ export class AddKnowledgeBaseEnhancements1737800000000 implements MigrationInter
       )
     `);
 
-    // knowledge_base テーブルに pdf_path フィールドをAdded
+    
     await queryRunner.query(`
       ALTER TABLE "knowledge_base" ADD COLUMN "pdf_path" varchar
     `);
 
-    // インデックスの作成
+    
     await queryRunner.query(`CREATE INDEX "IDX_knowledge_groups_user_id" ON "knowledge_groups" ("user_id")`);
     await queryRunner.query(`CREATE INDEX "IDX_search_history_user_id" ON "search_history" ("user_id")`);
     await queryRunner.query(`CREATE INDEX "IDX_chat_messages_search_history_id" ON "chat_messages" ("search_history_id")`);
   }
 
   public async down(queryRunner: QueryRunner): Promise<void> {
-    // インデックスの削除
+    
     await queryRunner.query(`DROP INDEX "IDX_chat_messages_search_history_id"`);
     await queryRunner.query(`DROP INDEX "IDX_search_history_user_id"`);
     await queryRunner.query(`DROP INDEX "IDX_knowledge_groups_user_id"`);
 
-    // pdf_path フィールドの削除
+    
     await queryRunner.query(`ALTER TABLE "knowledge_base" DROP COLUMN "pdf_path"`);
 
-    // テーブルの削除
+    
     await queryRunner.query(`DROP TABLE "chat_messages"`);
     await queryRunner.query(`DROP TABLE "search_history"`);
     await queryRunner.query(`DROP TABLE "knowledge_base_groups"`);

+ 9 - 21
server/src/model-config/dto/create-model-config.dto.ts

@@ -35,55 +35,43 @@ export class CreateModelConfigDto {
   type: ModelType;
 
   @IsNumber()
-  @Min(1, { message: 'ベクトル次元の最小値は 1 です' })
-  @Max(4096, { message: 'ベクトル次元の最大値は 4096 です(Elasticsearch の制限)' })
+  @Min(1, { message: 'The minimum value of the vector dimension is 1' })
+  @Max(4096, { message: 'The maximum vector dimension is 4096 (Elasticsearch limit)' })
   @IsOptional()
   dimensions?: number;
 
-  // ==================== Addedフィールド ====================
+  
 
-  /**
-   * モデルの入力トークン制限(embedding/rerank にのみ有効)
-   */
+  
   @IsNumber()
   @Min(1)
   @Max(100000)
   @IsOptional()
   maxInputTokens?: number;
 
-  /**
-   * バッチ処理の制限(embedding/rerank にのみ有効)
-   */
+  
   @IsNumber()
   @Min(1)
   @Max(10000)
   @IsOptional()
   maxBatchSize?: number;
 
-  /**
-   * ベトルモデルかどうか
-   */
+  
   @IsBoolean()
   @IsOptional()
   isVectorModel?: boolean;
 
-  /**
-   * モデルプロバイダー名
-   */
+  
   @IsString()
   @IsOptional()
   providerName?: string;
 
-  /**
-   * このモデルを有効にするかどうか
-   */
+  
   @IsBoolean()
   @IsOptional()
   isEnabled?: boolean;
 
-  /**
-   * このモデルをデフォルトとして使用するかどうか
-   */
+  
   @IsBoolean()
   @IsOptional()
   isDefault?: boolean;

+ 10 - 27
server/src/model-config/model-config.entity.ts

@@ -31,53 +31,36 @@ export class ModelConfig {
   type: string; // ModelType enum values
 
   @Column({ type: 'integer', nullable: true })
-  dimensions?: number; // 埋め込みモデルの次元、システムによって自動的に検出され保存されます
+  dimensions?: number; 
 
-  // ==================== Addedフィールド ====================
-  // 以下字段仅对 embedding/rerank 模型有意义
+  
+  
 
-  /**
-   * モデルの入力トークン制限
-   * 例: OpenAI=8191, Gemini=2048
-   */
+  
   @Column({ type: 'integer', nullable: true, default: 8191 })
   maxInputTokens?: number;
 
-  /**
-   * 一括処理制限(1回のリクエストあたりの最大入力数)
-   * 例: OpenAI=2048, Gemini=100
-   */
+  
   @Column({ type: 'integer', nullable: true, default: 2048 })
   maxBatchSize?: number;
 
-  /**
-   * ベトルモデルかどうか(システム設定での識別用)
-   */
+  
   @Column({ type: 'boolean', default: false })
   isVectorModel?: boolean;
 
-  /**
-   * このモデルを有効にするかどうか
-   * ユーザーは使用しないモデルを無効にして、誤選択を防ぐことができます
-   */
+  
   @Column({ type: 'boolean', default: true })
   isEnabled?: boolean;
 
-  /**
-   * このモデルをデフォルトとして使用するかどうか
-   * 各タイプ(llm, embedding, rerank)ごとに1つのみデフォルトにできます
-   */
+  
   @Column({ type: 'boolean', default: false })
   isDefault?: boolean;
 
-  /**
-   * モデルプロバイダー名(表示および識別用)
-   * 例: "OpenAI", "Google Gemini", "Custom"
-   */
+  
   @Column({ type: 'text', nullable: true })
   providerName?: string;
 
-  // ==================== 既存のフィールド ====================
+  
 
   @Column({ type: 'text', nullable: true })
   userId: string;

+ 4 - 9
server/src/model-config/model-config.service.ts

@@ -105,14 +105,12 @@ export class ModelConfigService {
     }
   }
 
-  /**
-   * 指定されたモデルをデフォルトに設定
-   */
+  
   async setDefault(userId: string, tenantId: string, id: string): Promise<ModelConfig> {
     const modelConfig = await this.findOne(id, userId, tenantId);
 
-    // 同じタイプの他のモデルのデフォルトフラグをクリア (現在のテナント内またはglobal)
-    // 厳密には、現在のテナントのIsDefault設定といった方が正しいですが、シンプルにするため全体のIsDefaultを操作します
+    
+    
     await this.modelConfigRepository
       .createQueryBuilder()
       .update(ModelConfig)
@@ -128,10 +126,7 @@ export class ModelConfigService {
     return this.modelConfigRepository.save(modelConfig);
   }
 
-  /**
-   * 指定されたタイプのデフォルトモデルを取得
-   * 厳密なルール:Index Chat Configで指定されたモデルのみを返し、なければエラーを投げる
-   */
+  
   async findDefaultByType(tenantId: string, type: ModelType): Promise<ModelConfig> {
     const settings = await this.tenantService.getSettings(tenantId);
     if (!settings) {

+ 10 - 12
server/src/pdf2image/pdf2image.interface.ts

@@ -1,20 +1,18 @@
-/**
- * PDF 转图片接口定义
- */
+
 
 export interface Pdf2ImageOptions {
-  density?: number;        // DPI 分辨率,默认 300
-  quality?: number;        // JPEG 质量 (1-100),默认 85
-  format?: 'jpeg' | 'png'; // 输出格式,默认 jpeg
-  outDir?: string;         // 输出目录,默认 ./temp
+  density?: number;        
+  quality?: number;        
+  format?: 'jpeg' | 'png'; 
+  outDir?: string;         
 }
 
 export interface ImageInfo {
-  path: string;            // 图片文件路径
-  pageIndex: number;       // 页码(从 1 开始)
-  size: number;            // 文件大小(字节)
-  width?: number;          // 图片宽度
-  height?: number;         // 图片高度
+  path: string;            
+  pageIndex: number;       
+  size: number;            
+  width?: number;          
+  height?: number;         
 }
 
 export interface ConversionResult {

+ 15 - 26
server/src/pdf2image/pdf2image.service.ts

@@ -18,10 +18,7 @@ export class Pdf2ImageService {
     this.tempDir = this.configService.get<string>('TEMP_DIR', './temp');
   }
 
-  /**
-   * PDF を画像リストに変換します
-   * ImageMagick の convert コマンドを使用します
-   */
+  
   async convertToImages(
     pdfPath: string,
     options: Pdf2ImageOptions = {}
@@ -33,14 +30,14 @@ export class Pdf2ImageService {
       outDir = this.tempDir,
     } = options;
 
-    // PDF ファイルの検証
+    
     try {
       await fs.access(pdfPath);
     } catch {
-      throw new Error(`PDF ファイルが存在しません: ${pdfPath}`);
+      throw new Error(`PDF file does not exist: ${pdfPath}`);
     }
 
-    // 出力ディレクトリの作成
+    
     const timestamp = Date.now();
     const outputDir = path.join(outDir, `pdf2img_${timestamp}`);
     await fs.mkdir(outputDir, { recursive: true });
@@ -49,20 +46,20 @@ export class Pdf2ImageService {
     this.logger.log(`Output directory: ${outputDir}`);
 
     try {
-      // PDF の総ページ数を取得 - pdfinfo の代わりに pdf-lib を使用
+      
       const pdfBytes = await fs.readFile(pdfPath);
       const pdfDoc = await PDFDocument.load(pdfBytes, { ignoreEncryption: true });
       const totalPages = pdfDoc.getPageCount();
 
       if (totalPages === 0) {
-        throw new Error('PDF のページ数を取得できません');
+        throw new Error('Unable to get page number of PDF');
       }
 
       this.logger.log(`📄 PDF conversion started: ${path.basename(pdfPath)} (Total ${totalPages} pages)`);
       this.logger.log(`📁 Output directory: ${outputDir}`);
       this.logger.log(`⚙️  Conversion parameters: Density=${density}dpi, Quality=${quality}%, Format=${format}`);
 
-      // Python スクリプトを使用して変換
+      
       const zoom = (density / 72).toFixed(2);
       const pythonScript = path.join(process.cwd(), 'pdf_to_images.py');
       const cmd = `python "${pythonScript}" "${pdfPath}" "${outputDir}" ${zoom} ${quality}`;
@@ -72,7 +69,7 @@ export class Pdf2ImageService {
       const result = JSON.parse(stdout);
 
       if (!result.success) {
-        throw new Error(`Python での変換に失敗しました: ${result.error}`);
+        throw new Error(`Python conversion failed: ${result.error}`);
       }
 
       const images: ImageInfo[] = result.images;
@@ -90,15 +87,13 @@ export class Pdf2ImageService {
         failedCount,
       };
     } catch (error) {
-      // 一時ディレクトリのクリーンアップ
+      
       await this.cleanupDirectory(outputDir);
-      throw new Error(`PDF から画像への変換に失敗しました: ${error.message}`);
+      throw new Error(`PDF to image conversion failed: ${error.message}`);
     }
   }
 
-  /**
-   * 複数の PDF を一括変換
-   */
+  
   async batchConvert(pdfPaths: string[], options?: Pdf2ImageOptions): Promise<ConversionResult[]> {
     const results: ConversionResult[] = [];
     for (const pdfPath of pdfPaths) {
@@ -113,9 +108,7 @@ export class Pdf2ImageService {
     return results;
   }
 
-  /**
-   * 画像ファイルのクリーンアップ
-   */
+  
   async cleanupImages(images: ImageInfo[]): Promise<void> {
     for (const image of images) {
       try {
@@ -126,16 +119,14 @@ export class Pdf2ImageService {
       }
     }
 
-    // 空のディレクトリのクリーンアップを試行
+    
     if (images.length > 0) {
       const dir = path.dirname(images[0].path);
       await this.cleanupDirectory(dir);
     }
   }
 
-  /**
-   * ディレクトリのクリーンアップ
-   */
+  
   async cleanupDirectory(dir: string): Promise<void> {
     try {
       const files = await fs.readdir(dir);
@@ -148,9 +139,7 @@ export class Pdf2ImageService {
     }
   }
 
-  /**
-   * 画像品質が妥当か確認
-   */
+  
   isImageQualityGood(imageInfo: ImageInfo, minSizeKB: number = 10): boolean {
     const sizeKB = imageInfo.size / 1024;
     if (sizeKB < minSizeKB) {

+ 31 - 39
server/src/rag/rag.service.ts

@@ -15,7 +15,7 @@ export interface RagSearchResult {
   score: number;
   chunkIndex: number;
   fileId?: string;
-  originalScore?: number; // Rerank前のスコア(デバッグ用)
+  originalScore?: number; 
   metadata?: any;
 }
 
@@ -46,22 +46,22 @@ export class RagService {
     query: string,
     userId: string,
     topK: number = 5,
-    vectorSimilarityThreshold: number = 0.3, // ベクトル検索のしきい値
+    vectorSimilarityThreshold: number = 0.3, 
     embeddingModelId?: string,
     enableFullTextSearch: boolean = false,
     enableRerank: boolean = false,
     rerankModelId?: string,
     selectedGroups?: string[],
     effectiveFileIds?: string[],
-    rerankSimilarityThreshold: number = 0.5, // Rerankのしきい値(デフォルト0.5)
+    rerankSimilarityThreshold: number = 0.5, 
     tenantId?: string, // New
     enableQueryExpansion?: boolean,
     enableHyDE?: boolean,
   ): Promise<RagSearchResult[]> {
-    // 1. グローバル設定の取得
+    
     const globalSettings = await this.userSettingService.getGlobalSettings();
 
-    // パラメータが明示的に渡されていない場合はグローバル設定を使用
+    
     const effectiveTopK = topK || globalSettings.topK || 5;
     const effectiveVectorThreshold = vectorSimilarityThreshold !== undefined ? vectorSimilarityThreshold : (globalSettings.similarityThreshold || 0.3);
     const effectiveRerankThreshold = rerankSimilarityThreshold !== undefined ? rerankSimilarityThreshold : (globalSettings.rerankSimilarityThreshold || 0.5);
@@ -78,25 +78,25 @@ export class RagService {
     );
 
     try {
-      // 1. クエリの準備(拡張または HyDE)
+      
       let queriesToSearch = [query];
 
       if (effectiveEnableHyDE) {
         const hydeDoc = await this.generateHyDE(query, userId);
-        queriesToSearch = [hydeDoc]; // HyDE の場合は仮想ドキュメントをクエリとして使用
+        queriesToSearch = [hydeDoc]; 
       } else if (effectiveEnableQueryExpansion) {
         const expanded = await this.expandQuery(query, userId);
         queriesToSearch = [...new Set([query, ...expanded])];
       }
 
-      // Embedding model IDが提供されているか確認
+      
       if (!effectiveEmbeddingId) {
-        throw new Error('Embedding model IDが提供されていません');
+        throw new Error('Embedding model ID not provided');
       }
 
-      // 2. 複数のクエリに対して並列検索
+      
       const searchTasks = queriesToSearch.map(async (searchQuery) => {
-        // クエリベクトルの取得
+        
         const queryEmbedding = await this.embeddingService.getEmbeddings(
           [searchQuery],
           userId,
@@ -104,7 +104,7 @@ export class RagService {
         );
         const queryVector = queryEmbedding[0];
 
-        // 設定に基づいた検索戦略の選択
+        
         let results;
         if (effectiveEnableFullText) {
           results = await this.elasticsearchService.hybridSearch(
@@ -136,19 +136,19 @@ export class RagService {
       const allResultsRaw = await Promise.all(searchTasks);
       let searchResults = this.deduplicateResults(allResultsRaw.flat());
 
-      // 初回の類似度フィルタリング
+      
       const initialCount = searchResults.length;
 
-      // ログ出力
+      
       searchResults.forEach((r, idx) => {
         this.logger.log(`Hit ${idx}: score=${r.score.toFixed(4)}, fileName=${r.fileName}`);
       });
 
-      // 閾値フィルタリングを適用
+      
       searchResults = searchResults.filter(r => r.score >= effectiveVectorThreshold);
       this.logger.log(`Initial hits: ${initialCount} -> filtered by vectorThreshold: ${searchResults.length}`);
 
-      // 3. リランク (Rerank)
+      
       let finalResults = searchResults;
 
       if (effectiveEnableRerank && effectiveRerankId && searchResults.length > 0) {
@@ -159,33 +159,33 @@ export class RagService {
             docs,
             userId,
             effectiveRerankId,
-            effectiveTopK * 2 // 少し多めに残す
+            effectiveTopK * 2 
           );
 
           finalResults = rerankedIndices.map(r => {
             const originalItem = searchResults[r.index];
             return {
               ...originalItem,
-              score: r.score, // Rerank スコア
-              originalScore: originalItem.score // 元のスコア
+              score: r.score, 
+              originalScore: originalItem.score 
             };
           });
 
-          // Rerank後のフィルタリング
+          
           const beforeRerankFilter = finalResults.length;
           finalResults = finalResults.filter(r => r.score >= effectiveRerankThreshold);
           this.logger.log(`After rerank: ${beforeRerankFilter} -> filtered by rerankThreshold: ${finalResults.length}`);
 
         } catch (error) {
           this.logger.warn(`Rerank failed, falling back to filtered vector search: ${error.message}`);
-          // 失敗した場合はベクトル検索の結果をそのまま使う
+          
         }
       }
 
-      // 最終的な件数制限
+      
       finalResults = finalResults.slice(0, effectiveTopK);
 
-      // 4. RAG 結果形式に変換
+      
       const ragResults: RagSearchResult[] = finalResults.map((result) => ({
         content: result.content,
         fileName: result.fileName,
@@ -210,12 +210,12 @@ export class RagService {
   ): string {
     const lang = language || 'ja';
 
-    // コンテキストの構築
+    
     let context = '';
     if (searchResults.length === 0) {
       context = this.i18nService.getMessage('ragNoDocumentFound', lang);
     } else {
-      // ファイルごとにグループ化
+      
       const fileGroups = new Map<string, RagSearchResult[]>();
       searchResults.forEach((result) => {
         if (!fileGroups.has(result.fileName)) {
@@ -224,7 +224,7 @@ export class RagService {
         fileGroups.get(result.fileName)!.push(result);
       });
 
-      // コンテキスト文字列を構築
+      
       const contextParts: string[] = [];
       fileGroups.forEach((chunks, fileName) => {
         contextParts.push(this.i18nService.formatMessage('ragSource', { fileName }, lang));
@@ -272,9 +272,7 @@ ${answerHeader}`;
     return Array.from(uniqueFiles);
   }
 
-  /**
-   * Search resultsの重複排除
-   */
+  
   private deduplicateResults(results: any[]): any[] {
     const unique = new Map<string, any>();
     results.forEach(r => {
@@ -286,9 +284,7 @@ ${answerHeader}`;
     return Array.from(unique.values()).sort((a, b) => b.score - a.score);
   }
 
-  /**
-   * クエリを拡張してバリエーションを生成
-   */
+  
   async expandQuery(query: string, userId: string, tenantId?: string): Promise<string[]> {
     try {
       const llm = await this.getInternalLlm(userId, tenantId || 'default');
@@ -305,7 +301,7 @@ ${answerHeader}`;
         .split('\n')
         .map(q => q.trim())
         .filter(q => q.length > 0)
-        .slice(0, 3); // 最大3つに制限
+        .slice(0, 3); 
 
       this.logger.log(`Query expanded: "${query}" -> [${expandedQueries.join(', ')}]`);
       return expandedQueries.length > 0 ? expandedQueries : [query];
@@ -315,9 +311,7 @@ ${answerHeader}`;
     }
   }
 
-  /**
-   * 仮想的なドキュメント(HyDE)を生成
-   */
+  
   async generateHyDE(query: string, userId: string, tenantId?: string): Promise<string> {
     try {
       const llm = await this.getInternalLlm(userId, tenantId || 'default');
@@ -338,9 +332,7 @@ ${answerHeader}`;
     }
   }
 
-  /**
-   * 内部タスク用の LLM インスタンスを取得
-   */
+  
   private async getInternalLlm(userId: string, tenantId: string): Promise<ChatOpenAI | null> {
     try {
       const models = await this.modelConfigService.findAll(userId, tenantId || 'default');

+ 6 - 13
server/src/rag/rerank.service.ts

@@ -19,14 +19,7 @@ export class RerankService {
         private configService: ConfigService,
     ) { }
 
-    /**
-     * リランクの実行
-     * @param query ユーザーのクエリ
-     * @param documents 候補ドキュメントリスト
-     * @param userId ユーザーID
-     * @param rerankModelId 選択された Rerank モデル設定ID
-     * @param topN 返す結果の数 (上位 N 個)
-     */
+    
     async rerank(
         query: string,
         documents: string[],
@@ -41,7 +34,7 @@ export class RerankService {
 
         let modelConfig;
         try {
-            // 1. モデル設定の取得
+            
             modelConfig = await this.modelConfigService.findOne(rerankModelId, userId, tenantId || 'default');
 
             if (!modelConfig || modelConfig.type !== ModelType.RERANK) {
@@ -56,9 +49,9 @@ export class RerankService {
 
             this.logger.log(`Reranking ${documents.length} docs with model ${modelName} at ${baseUrl}`);
 
-            // 2. API リクエストの構築 (OpenAI/SiliconFlow 互換 Rerank API)
-            // 注: 標準の OpenAI API には /rerank はありませんが、SiliconFlow/Jina/Cohere は同様の構造を使用しています
-            // SiliconFlow 形式: POST /v1/rerank { model, query, documents, top_n }
+            
+            
+            
 
             const endpoint = baseUrl.replace(/\/+$/, '');
 
@@ -83,7 +76,7 @@ export class RerankService {
                 }
             );
 
-            // 3. レスポンスの解析
+            
             // Expected response format (SiliconFlow/Cohere):
             // { results: [ { index: 0, relevance_score: 0.98 }, ... ] }
 

+ 1 - 1
server/src/search-history/search-history.controller.ts

@@ -51,6 +51,6 @@ export class SearchHistoryController {
   @Delete(':id')
   async remove(@Param('id') id: string, @Request() req) {
     await this.searchHistoryService.remove(id, req.user.id, req.user.tenantId);
-    return { message: '对话历史删除成功' };
+    return { message: 'Conversation history deleted successfully' };
   }
 }

+ 1 - 1
server/src/search-history/search-history.service.ts

@@ -147,7 +147,7 @@ export class SearchHistoryService {
 
     const savedMessage = await this.chatMessageRepository.save(message);
 
-    // 履歴レコードの更新時間を更新
+    
     await this.searchHistoryRepository.update(historyId, {
       updatedAt: new Date(),
     });

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

@@ -34,7 +34,7 @@ export interface UploadConfigDto {
   chunkSize?: string;
   chunkOverlap?: string;
   embeddingModelId?: string;
-  mode?: 'fast' | 'precise'; // 処理モード
+  mode?: 'fast' | 'precise'; 
   groupIds?: string; // JSON string of group IDs
 }
 
@@ -98,7 +98,7 @@ export class UploadController {
   @UseInterceptors(
     FileInterceptor('file', {
       fileFilter: (req, file, cb) => {
-        // 画像MIMEタイプまたは拡張子によるチェック
+        
         const isAllowed = IMAGE_MIME_TYPES.includes(file.mimetype) ||
           isAllowedByExtension(file.originalname);
 
@@ -124,7 +124,7 @@ export class UploadController {
       throw new BadRequestException(this.i18nService.getMessage('uploadNoFile'));
     }
 
-    // ファイルサイズの検証(フロントエンド制限 + バックエンド検証)
+    
     const maxFileSize = parseInt(
       process.env.MAX_FILE_SIZE || String(MAX_FILE_SIZE),
     ); // 100MB
@@ -134,18 +134,18 @@ export class UploadController {
       );
     }
 
-    // 埋め込みモデル設定の検証
+    
     if (!config.embeddingModelId) {
       throw new BadRequestException(this.i18nService.getMessage('uploadModelRequired'));
     }
 
     this.logger.log(
-      `ユーザー ${req.user.id} がファイルをアップロードしました: ${file.originalname} (${this.formatBytes(file.size)})`,
+      `User ${req.user.id} uploaded file: ${file.originalname} (${this.formatBytes(file.size)})`,
     );
 
     const fileInfo = await this.uploadService.processUploadedFile(file);
 
-    // 設定パラメータを解析し、安全なデフォルト値を設定
+    
     const indexingConfig = {
       chunkSize: config.chunkSize ? parseInt(config.chunkSize) : DEFAULT_CHUNK_SIZE,
       chunkOverlap: config.chunkOverlap ? parseInt(config.chunkOverlap) : DEFAULT_CHUNK_OVERLAP,
@@ -153,7 +153,7 @@ export class UploadController {
       groupIds: config.groupIds ? JSON.parse(config.groupIds) : [],
     };
 
-    // オーバーラップサイズが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(
@@ -161,7 +161,7 @@ export class UploadController {
       );
     }
 
-    // データベースに保存し、インデックスプロセスをトリガー(非同期)
+    
     const kb = await this.knowledgeBaseService.createAndIndex(
       fileInfo,
       req.user.id,
@@ -180,7 +180,7 @@ export class UploadController {
       status: kb.status,
       mode: config.mode || 'fast',
       config: indexingConfig,
-      estimatedChunks: Math.ceil(file.size / (indexingConfig.chunkSize * 4)), // 推定チャンク数
+      estimatedChunks: Math.ceil(file.size / (indexingConfig.chunkSize * 4)), 
     };
   }
 

+ 5 - 5
server/src/upload/upload.module.ts

@@ -21,14 +21,14 @@ import { UserModule } from '../user/user.module';
         const uploadPath = configService.get<string>(
           'UPLOAD_FILE_PATH',
           './uploads',
-        ); // 環境変数からアップロードパスを取得し、ない場合はデフォルトとして './uploads' を使用します
+        ); 
 
-        // アップロードディレクトリが存在することを確認
+        
         if (!fs.existsSync(uploadPath)) {
           fs.mkdirSync(uploadPath, { recursive: true });
         }
 
-        // 環境変数から最大ファイルサイズ制限を取得、デフォルトは 100MB
+        
         const maxFileSize = parseInt(
           configService.get<string>('MAX_FILE_SIZE', '104857600'), // 100MB in bytes
         );
@@ -45,7 +45,7 @@ import { UserModule } from '../user/user.module';
               cb(null, fullPath);
             },
             filename: (req, file, cb) => {
-              // 中国語ファイル名の文字化け問題を解決
+              
               file.originalname = Buffer.from(
                 file.originalname,
                 'latin1',
@@ -59,7 +59,7 @@ import { UserModule } from '../user/user.module';
             },
           }),
           limits: {
-            fileSize: maxFileSize, // ファイルサイズの制限
+            fileSize: maxFileSize, 
           },
         };
       },

+ 1 - 1
server/src/user-setting/user-setting.entity.ts

@@ -8,7 +8,7 @@ import {
   PrimaryGeneratedColumn,
   UpdateDateColumn,
 } from 'typeorm';
-import { User } from '../user/user.entity'; // Userエンティティのパス
+import { User } from '../user/user.entity'; 
 
 @Entity('user_settings')
 export class UserSetting {

+ 8 - 12
server/src/user-setting/user-setting.service.ts

@@ -20,7 +20,7 @@ export class UserSettingService implements OnModuleInit {
   }
 
   private async initializeGlobalSettings() {
-    // 1. 既存のグローバル設定を検索する
+    
     let globalSetting = await this.userSettingRepository.findOne({
       where: { isGlobal: true },
     });
@@ -30,7 +30,7 @@ export class UserSettingService implements OnModuleInit {
       return;
     }
 
-    // 2. グローバル設定がない場合、旧 'system' ユーザーから移行を試みる
+    
     const legacySystemSetting = await this.userSettingRepository.findOne({
       where: { userId: 'system' },
     });
@@ -42,7 +42,7 @@ export class UserSettingService implements OnModuleInit {
       await this.userSettingRepository.save(legacySystemSetting);
       this.logger.log('Migration complete.');
     } else {
-      // 3. 旧記録もない場合は、新規作成する
+      
       this.logger.log('No global settings found. Creating initial global settings...');
       const newGlobalSetting = this.userSettingRepository.create({
         isGlobal: true,
@@ -111,7 +111,7 @@ export class UserSettingService implements OnModuleInit {
   }
 
   async updateLanguage(userId: string, language: string): Promise<UserSetting> {
-    console.log('=== updateLanguage デバッグ ===');
+    console.log('=== updateLanguage Debug ===');
     console.log('userId:', userId);
     console.log('New language:', language);
     const settings = await this.findOrCreate(userId);
@@ -127,7 +127,7 @@ export class UserSettingService implements OnModuleInit {
     const settings = await this.userSettingRepository.findOne({
       where: { userId },
     });
-    console.log('=== getLanguage デバッグ ===');
+    console.log('=== getLanguage Debug ===');
     console.log('userId:', userId);
     console.log('settings:', settings);
     console.log('settings.language:', settings?.language);
@@ -136,25 +136,21 @@ export class UserSettingService implements OnModuleInit {
     return settings?.language || 'zh';
   }
 
-  /**
-   * システム全体のグローバル設定を取得する
-   */
+  
   async getGlobalSettings(): Promise<UserSetting> {
     const globalSetting = await this.userSettingRepository.findOne({
       where: { isGlobal: true },
     });
 
     if (!globalSetting) {
-      // 万が一存在しない場合は初期化
+      
       await this.initializeGlobalSettings();
       return this.getGlobalSettings();
     }
     return globalSetting;
   }
 
-  /**
-   * システム全体のグローバル設定を更新する
-   */
+  
   async updateGlobalSettings(
     updateUserSettingDto: UpdateUserSettingDto,
   ): Promise<UserSetting> {

+ 4 - 4
server/src/user/user.controller.ts

@@ -158,7 +158,7 @@ export class UserController {
       throw new ForbiddenException(this.i18nService.getErrorMessage('adminOnlyUpdateUser'));
     }
 
-    // 更新するユーザー情報を取得
+    
     const userToUpdate = await this.userService.findOneById(id);
     if (!userToUpdate) {
       throw new NotFoundException(this.i18nService.getErrorMessage('userNotFound'));
@@ -203,12 +203,12 @@ export class UserController {
       throw new ForbiddenException(this.i18nService.getErrorMessage('adminOnlyDeleteUser'));
     }
 
-    // 管理者が自身を削除するのを防止
+    
     if (req.user.id === id) {
       throw new BadRequestException(this.i18nService.getErrorMessage('cannotDeleteSelf'));
     }
 
-    // 削除するユーザー情報を取得
+    
     const userToDelete = await this.userService.findOneById(id);
     if (!userToDelete) {
       throw new NotFoundException(this.i18nService.getErrorMessage('userNotFound'));
@@ -218,7 +218,7 @@ export class UserController {
       throw new ForbiddenException('Cannot delete users outside your tenant');
     }
 
-    // ビルトインadminアカウントの削除を阻止
+    
     if (userToDelete.username === 'admin') {
       throw new ForbiddenException(this.i18nService.getErrorMessage('cannotDeleteBuiltinAdmin'));
     }

+ 1 - 1
server/src/user/user.entity.ts

@@ -54,7 +54,7 @@ export class User {
   @OneToMany(() => ApiKey, (apiKey) => apiKey.user)
   apiKeys: ApiKey[];
 
-  // クォータ管理フィールド
+  
   @Column({ type: 'decimal', precision: 10, scale: 2, default: 0 })
   monthlyCost: number;
 

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

@@ -229,13 +229,13 @@ export class UserService implements OnModuleInit {
       throw new NotFoundException(this.i18nService.getMessage('userNotFound'));
     }
 
-    // パスワードの更新が必要な場合は、まずハッシュ化する
+    
     if (updateData.password) {
       const hashedPassword = await bcrypt.hash(updateData.password, 10);
       updateData.password = hashedPassword;
     }
 
-    // ユーザー名 "admin" のユーザーに対するいかなる変更も阻止
+    
     if (user.username === 'admin') {
       throw new ForbiddenException(this.i18nService.getMessage('cannotModifyBuiltinAdmin'));
     }
@@ -272,7 +272,7 @@ export class UserService implements OnModuleInit {
       throw new NotFoundException(this.i18nService.getMessage('userNotFound'));
     }
 
-    // ユーザー名 "admin" のユーザーの削除を阻止
+    
     if (user.username === 'admin') {
       throw new ForbiddenException(this.i18nService.getMessage('cannotDeleteBuiltinAdmin'));
     }
@@ -303,7 +303,7 @@ export class UserService implements OnModuleInit {
 
       console.log('\n=== Administrator Account Created ===');
       console.log('Username: admin');
-      console.log('パスワード:', randomPassword);
+      console.log('Password:', randomPassword);
       console.log('========================================\n');
     }
   }

+ 36 - 59
server/src/vision-pipeline/cost-control.service.ts

@@ -1,7 +1,4 @@
-/**
- * コスト制御およびクォータ管理サービス
- * Vision Pipeline の API 呼び出しコストを管理するために使用されます
- */
+
 
 import { Injectable, Logger } from '@nestjs/common';
 import { ConfigService } from '@nestjs/config';
@@ -11,16 +8,16 @@ import { User } from '../user/user.entity';
 
 export interface UserQuota {
   userId: string;
-  monthlyCost: number;      // 今月の使用済みコスト
-  maxCost: number;          // 月間最大コスト
-  remaining: number;        // 残りコスト
-  lastReset: Date;          // 最終リセット時間
+  monthlyCost: number;      
+  maxCost: number;          
+  remaining: number;        
+  lastReset: Date;          
 }
 
 export interface CostEstimate {
-  estimatedCost: number;    // 推定コスト
-  estimatedTime: number;    // 推定時間(秒)
-  pageBreakdown: {          // ページごとの明細
+  estimatedCost: number;    
+  estimatedTime: number;    
+  pageBreakdown: {          
     pageIndex: number;
     cost: number;
   }[];
@@ -29,8 +26,8 @@ export interface CostEstimate {
 @Injectable()
 export class CostControlService {
   private readonly logger = new Logger(CostControlService.name);
-  private readonly COST_PER_PAGE = 0.01; // 1ページあたりのコスト(USD)
-  private readonly DEFAULT_MONTHLY_LIMIT = 100; // デフォルトの月間制限(USD)
+  private readonly COST_PER_PAGE = 0.01; 
+  private readonly DEFAULT_MONTHLY_LIMIT = 100; 
 
   constructor(
     private configService: ConfigService,
@@ -38,11 +35,9 @@ export class CostControlService {
     private userRepository: Repository<User>,
   ) { }
 
-  /**
-   * 処理コストの推定
-   */
+  
   estimateCost(pageCount: number, quality: 'low' | 'medium' | 'high' = 'medium'): CostEstimate {
-    // 品質に基づいてコスト係数を調整
+    
     const qualityMultiplier = {
       low: 0.5,
       medium: 1.0,
@@ -50,7 +45,7 @@ export class CostControlService {
     };
 
     const baseCost = pageCount * this.COST_PER_PAGE * qualityMultiplier[quality];
-    const estimatedTime = pageCount * 3; // 1ページあたり約 3 秒
+    const estimatedTime = pageCount * 3; 
 
     const pageBreakdown = Array.from({ length: pageCount }, (_, i) => ({
       pageIndex: i + 1,
@@ -64,9 +59,7 @@ export class CostControlService {
     };
   }
 
-  /**
-   * ユーザーのクォータをチェック
-   */
+  
   async checkQuota(userId: string, estimatedCost: number): Promise<{
     allowed: boolean;
     quota: UserQuota;
@@ -74,7 +67,7 @@ export class CostControlService {
   }> {
     const quota = await this.getUserQuota(userId);
 
-    // 月間リセットのチェック
+    
     this.checkAndResetMonthlyQuota(quota);
 
     if (quota.remaining < estimatedCost) {
@@ -84,7 +77,7 @@ export class CostControlService {
       return {
         allowed: false,
         quota,
-        reason: `クォータ不足: 残り $${quota.remaining.toFixed(2)}, 必要 $${estimatedCost.toFixed(2)}`,
+        reason: `Insufficient quota: remaining $${quota.remaining.toFixed(2)}, required $${estimatedCost.toFixed(2)}`,
       };
     }
 
@@ -94,9 +87,7 @@ export class CostControlService {
     };
   }
 
-  /**
-   * クォータの差し引き
-   */
+  
   async deductQuota(userId: string, actualCost: number): Promise<void> {
     const quota = await this.getUserQuota(userId);
     quota.monthlyCost += actualCost;
@@ -111,17 +102,15 @@ export class CostControlService {
     );
   }
 
-  /**
-   * ユーザーのクォータを取得
-   */
+  
   async getUserQuota(userId: string): Promise<UserQuota> {
     const user = await this.userRepository.findOne({ where: { id: userId } });
 
     if (!user) {
-      throw new Error(`ユーザー ${userId} は存在しません`);
+      throw new Error(`User ${userId} does not exist`);
     }
 
-    // ユーザーにクォータ情報がない場合はデフォルト値を使用
+    
     const monthlyCost = user.monthlyCost || 0;
     const maxCost = user.maxCost || this.DEFAULT_MONTHLY_LIMIT;
     const lastReset = user.lastQuotaReset || new Date();
@@ -135,26 +124,24 @@ export class CostControlService {
     };
   }
 
-  /**
-   * 月間クォータのチェックとリセット
-   */
+  
   private checkAndResetMonthlyQuota(quota: UserQuota): void {
     const now = new Date();
     const lastReset = quota.lastReset;
 
-    // 月を跨いでいるかチェック
+    
     if (
       now.getMonth() !== lastReset.getMonth() ||
       now.getFullYear() !== lastReset.getFullYear()
     ) {
       this.logger.log(`Reset monthly quota for user ${quota.userId}`);
 
-      // クォータをリセット
+      
       quota.monthlyCost = 0;
       quota.remaining = quota.maxCost;
       quota.lastReset = now;
 
-      // データベースを更新
+      
       this.userRepository.update(quota.userId, {
         monthlyCost: 0,
         lastQuotaReset: now,
@@ -162,17 +149,13 @@ export class CostControlService {
     }
   }
 
-  /**
-   * ユーザーのクォータ制限を設定
-   */
+  
   async setQuotaLimit(userId: string, maxCost: number): Promise<void> {
     await this.userRepository.update(userId, { maxCost });
     this.logger.log(`Set quota limit for user ${userId} to $${maxCost}`);
   }
 
-  /**
-   * コストレポートの取得
-   */
+  
   async getCostReport(userId: string, days: number = 30): Promise<{
     totalCost: number;
     dailyAverage: number;
@@ -180,13 +163,13 @@ export class CostControlService {
       totalPages: number;
       avgCostPerPage: number;
     };
-    quotaUsage: number; // パーセンテージ
+    quotaUsage: number; 
   }> {
     const quota = await this.getUserQuota(userId);
     const usagePercent = (quota.monthlyCost / quota.maxCost) * 100;
 
-    // ここで履歴レコードを照会できます(実装されている場合)
-    // 暫定的に現在のクォータ情報を返します
+    
+    
 
     return {
       totalCost: quota.monthlyCost,
@@ -199,9 +182,7 @@ export class CostControlService {
     };
   }
 
-  /**
-   * コスト警告閾値のチェック
-   */
+  
   async checkWarningThreshold(userId: string): Promise<{
     shouldWarn: boolean;
     message: string;
@@ -212,14 +193,14 @@ export class CostControlService {
     if (usagePercent >= 90) {
       return {
         shouldWarn: true,
-        message: `⚠️ クォータ使用率が ${usagePercent.toFixed(1)}% に達しました。残り $${quota.remaining.toFixed(2)}`,
+        message: `⚠️ Quota usage has reached ${usagePercent.toFixed(1)}%. Remaining $${quota.remaining.toFixed(2)}`,
       };
     }
 
     if (usagePercent >= 75) {
       return {
         shouldWarn: true,
-        message: `💡 クォータ使用率 ${usagePercent.toFixed(1)}%。コストの管理に注意してください`,
+        message: `💡 Quota usage ${usagePercent.toFixed(1)}%. Be careful with controlling costs`,
       };
     }
 
@@ -229,22 +210,18 @@ export class CostControlService {
     };
   }
 
-  /**
-   * コスト表示のフォーマット
-   */
+  
   formatCost(cost: number): string {
     return `$${cost.toFixed(2)}`;
   }
 
-  /**
-   * 時間表示のフォーマット
-   */
+  
   formatTime(seconds: number): string {
     if (seconds < 60) {
-      return `${seconds.toFixed(0)}`;
+      return `${seconds.toFixed(0)}s`;
     }
     const minutes = Math.floor(seconds / 60);
     const remainingSeconds = seconds % 60;
-    return `${minutes}分${remainingSeconds.toFixed(0)}秒`;
+    return `${minutes}m ${remainingSeconds.toFixed(0)}s`;
   }
 }

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

@@ -1,7 +1,4 @@
-/**
- * Vision Pipeline サービス(コスト制御付き)
- * これは vision-pipeline.service.ts の拡張版であり、コスト制御が統合されています
- */
+
 
 import { Injectable, Logger } from '@nestjs/common';
 import { ConfigService } from '@nestjs/config';
@@ -27,12 +24,10 @@ export class VisionPipelineCostAwareService {
     private elasticsearch: ElasticsearchService,
     private modelConfigService: ModelConfigService,
     private configService: ConfigService,
-    private costControl: CostControlService, // 新增成本控制服务
+    private costControl: CostControlService, 
   ) { }
 
-  /**
-   * メイン処理フロー:Precise Mode(コスト制御付き)
-   */
+  
   async processPreciseMode(
     filePath: string,
     options: PreciseModeOptions,
@@ -50,12 +45,12 @@ export class VisionPipelineCostAwareService {
     );
 
     try {
-      // ステップ 1: 形式の統一
-      this.updateStatus('converting', 10, 'ドキュメント形式を変換中...');
+      
+      this.updateStatus('converting', 10, 'Converting document format...');
       pdfPath = await this.convertToPDF(filePath);
 
-      // ステップ 2: PDF から画像への変換
-      this.updateStatus('splitting', 30, 'PDF を画像に変換中...');
+      
+      this.updateStatus('splitting', 30, 'Converting PDF to image...');
       const conversionResult = await this.pdf2Image.convertToImages(pdfPath, {
         density: 300,
         quality: 85,
@@ -63,24 +58,24 @@ export class VisionPipelineCostAwareService {
       });
 
       if (conversionResult.images.length === 0) {
-        throw new Error('PDF から画像への変換に失敗しました。画像が生成されませんでした');
+        throw new Error('PDF to image conversion failed. No image was generated');
       }
 
-      // 限制处理页数
+      
       imagesToProcess = options.maxPages
         ? conversionResult.images.slice(0, options.maxPages)
         : conversionResult.images;
 
       const pageCount = imagesToProcess.length;
 
-      // ステップ 3: コスト見積もりとクォータチェック
-      this.updateStatus('checking', 40, 'クォータを確認し、コストを見積もり中...');
+      
+      this.updateStatus('checking', 40, 'Checking quotas and estimating costs...');
       const costEstimate = this.costControl.estimateCost(pageCount);
       this.logger.log(
         `Estimated cost: $${costEstimate.estimatedCost.toFixed(2)}, Estimated time: ${this.costControl.formatTime(costEstimate.estimatedTime)}`
       );
 
-      // クォータチェック
+      
       const quotaCheck = await this.costControl.checkQuota(
         options.userId,
         costEstimate.estimatedCost,
@@ -90,17 +85,17 @@ export class VisionPipelineCostAwareService {
         throw new Error(quotaCheck.reason);
       }
 
-      // コスト警告チェック
+      
       const warning = await this.costControl.checkWarningThreshold(options.userId);
       if (warning.shouldWarn) {
         this.logger.warn(warning.message);
       }
 
-      // ステップ 4: Vision モデル設定の取得
+      
       const modelConfig = await this.getVisionModelConfig(options.userId, options.modelId, options.tenantId);
 
-      // ステップ 5: VL モデル分析
-      this.updateStatus('analyzing', 50, 'ビジョンモデルを使用してページをAnalyzing...');
+      
+      this.updateStatus('analyzing', 50, 'Analyzing the page using the vision model...');
       const batchResult = await this.vision.batchAnalyze(
         imagesToProcess.map(img => img.path),
         modelConfig,
@@ -115,17 +110,17 @@ export class VisionPipelineCostAwareService {
       failedPages = batchResult.failedCount;
       results.push(...batchResult.results);
 
-      // ステップ 6: 実際のコストを差し引く
+      
       if (totalCost > 0) {
         await this.costControl.deductQuota(options.userId, totalCost);
         this.logger.log(`Actual deducted cost: $${totalCost.toFixed(2)}`);
       }
 
-      // ステップ 7: 一時ファイルのクリーンアップ
-      this.updateStatus('completed', 100, '処理が完了しました。一時ファイルをクリーンアップ中...');
+      
+      this.updateStatus('completed', 100, 'Processing completed. Cleaning up temporary files...');
       await this.pdf2Image.cleanupImages(imagesToProcess);
 
-      // PDF に変換した場合、変換後のファイルをクリーンアップ
+      
       if (pdfPath !== filePath) {
         try {
           await fs.unlink(pdfPath);
@@ -156,7 +151,7 @@ export class VisionPipelineCostAwareService {
     } catch (error) {
       this.logger.error(`Precise mode failed: ${error.message}`);
 
-      // 尝试清理临时文件
+      
       try {
         if (pdfPath !== filePath && pdfPath !== filePath) {
           await fs.unlink(pdfPath);
@@ -181,14 +176,12 @@ export class VisionPipelineCostAwareService {
     }
   }
 
-  /**
-   * Vision モデル設定の取得
-   */
+  
   private async getVisionModelConfig(userId: string, modelId: string, tenantId?: string): Promise<VisionModelConfig> {
     const config = await this.modelConfigService.findOne(modelId, userId, tenantId || 'default');
 
     if (!config) {
-      throw new Error(`モデル設定が見つかりません: ${modelId}`);
+      throw new Error(`Model configuration not found: ${modelId}`);
     }
 
     // API key is optional - allow local models
@@ -200,24 +193,20 @@ export class VisionPipelineCostAwareService {
     };
   }
 
-  /**
-   * PDF への変換
-   */
+  
   private async convertToPDF(filePath: string): Promise<string> {
     const ext = path.extname(filePath).toLowerCase();
 
-    // 既に PDF の場合はそのまま返す
+    
     if (ext === '.pdf') {
       return filePath;
     }
 
-    // LibreOffice を呼び出して変換
+    
     return await this.libreOffice.convertToPDF(filePath);
   }
 
-  /**
-   * 形式検出とモードの推奨(コスト見積もり付き)
-   */
+  
   async recommendMode(filePath: string): Promise<ModeRecommendation> {
     const ext = path.extname(filePath).toLowerCase();
     const stats = await fs.stat(filePath);
@@ -229,47 +218,45 @@ export class VisionPipelineCostAwareService {
     if (!supportedFormats.includes(ext)) {
       return {
         recommendedMode: 'fast',
-        reason: `サポートされていないファイル形式です: ${ext}`,
-        warnings: ['Fast Mode(テキスト抽出のみ)を使用します'],
+        reason: `Unsupported file format: ${ext}`,
+        warnings: ['Using Fast Mode (text extraction only)'],
       };
     }
 
     if (!preciseFormats.includes(ext)) {
       return {
         recommendedMode: 'fast',
-        reason: `形式 ${ext} はPrecise Modeをサポートしていません`,
-        warnings: ['Fast Mode(テキスト抽出のみ)を使用します'],
+        reason: `Format ${ext} does not support Precise Mode`,
+        warnings: ['Using Fast Mode (text extraction only)'],
       };
     }
 
-    // ページ数の見積もり(ファイルサイズに基づく)
+    
     const estimatedPages = Math.max(1, Math.ceil(sizeMB * 2));
     const costEstimate = this.costControl.estimateCost(estimatedPages);
 
-    // ファイルサイズが大きい場合はPrecise Modeを推奨
+    
     if (sizeMB > 50) {
       return {
         recommendedMode: 'precise',
-        reason: 'ファイルが大きいため、完全な情報を保持するためにPrecise Modeを推奨します',
+        reason: 'Due to large files, Precise Mode is recommended to retain complete information',
         estimatedCost: costEstimate.estimatedCost,
         estimatedTime: costEstimate.estimatedTime,
-        warnings: ['処理時間が長くなる可能性があります', 'API 費用が発生します'],
+        warnings: ['Processing time may be longer', 'API charges may apply'],
       };
     }
 
-    // Precise Modeを推奨
+    
     return {
       recommendedMode: 'precise',
-      reason: 'Precise Modeが利用可能です。テキストと画像の混合コンテンツを保持できます',
+      reason: 'Precise Mode is available. Can hold mixed content of text and images',
       estimatedCost: costEstimate.estimatedCost,
       estimatedTime: costEstimate.estimatedTime,
-      warnings: ['API 費用が発生します'],
+      warnings: ['API charges will apply'],
     };
   }
 
-  /**
-   * ユーザーのクォータ情報を取得
-   */
+  
   async getUserQuotaInfo(userId: string) {
     const quota = await this.costControl.getUserQuota(userId);
     const report = await this.costControl.getCostReport(userId);
@@ -281,9 +268,7 @@ export class VisionPipelineCostAwareService {
     };
   }
 
-  /**
-   * 処理状態の更新(リアルタイムフィードバック用)
-   */
+  
   private updateStatus(status: ProcessingStatus['status'], progress: number, message: string): void {
     this.logger.log(`[${status}] ${progress}% - ${message}`);
   }

+ 3 - 5
server/src/vision-pipeline/vision-pipeline.interface.ts

@@ -1,6 +1,4 @@
-/**
- * Vision Pipeline 接口定义
- */
+
 
 import { VisionAnalysisResult } from '../vision/vision.interface';
 
@@ -23,7 +21,7 @@ export interface PipelineResult {
   failedPages: number;
   results: VisionAnalysisResult[];
   cost: number;
-  duration: number; // 秒
+  duration: number; 
   mode: 'precise';
 }
 
@@ -44,6 +42,6 @@ export interface ModeRecommendation {
   recommendedMode: 'precise' | 'fast';
   reason: string;
   estimatedCost?: number;
-  estimatedTime?: number; // 秒
+  estimatedTime?: number; 
   warnings?: string[];
 }

+ 10 - 12
server/src/vision/vision.interface.ts

@@ -1,19 +1,17 @@
-/**
- * Vision 服务接口定义
- */
+
 
 export interface VisionAnalysisResult {
-  text: string;              // 抽出されたテキスト内容
-  images: ImageDescription[]; // 画像の説明
-  layout: string;            // レイアウトの種類
-  confidence: number;        // 信頼度 (0-1)
-  pageIndex?: number;        // 页码
+  text: string;              
+  images: ImageDescription[]; 
+  layout: string;            
+  confidence: number;        
+  pageIndex?: number;        
 }
 
 export interface ImageDescription {
-  type: string;              // 图片类型 (图表/架构图/流程图等)
-  description: string;       // 详细描述
-  position?: number;         // ページ内での位置
+  type: string;              
+  description: string;       
+  position?: number;         
 }
 
 export interface VisionModelConfig {
@@ -27,7 +25,7 @@ export interface BatchAnalysisResult {
   totalPages: number;
   successCount: number;
   failedCount: number;
-  estimatedCost: number;     // 预估成本(美元)
+  estimatedCost: number;     
 }
 
 export interface PageQuality {

+ 34 - 52
server/src/vision/vision.service.ts

@@ -15,16 +15,14 @@ export class VisionService {
     private i18nService: I18nService,
   ) { }
 
-  /**
-   * 単一画像の分析(ドキュメントページ)
-   */
+  
   async analyzeImage(
     imagePath: string,
     modelConfig: VisionModelConfig,
     pageIndex?: number,
   ): Promise<VisionAnalysisResult> {
     const maxRetries = 3;
-    const baseDelay = 3000; // 3秒の基礎遅延
+    const baseDelay = 3000; 
 
     for (let attempt = 1; attempt <= maxRetries; attempt++) {
       try {
@@ -36,7 +34,7 @@ export class VisionService {
           throw new Error(this.i18nService.formatMessage('visionAnalysisFailed', { message: error.message }));
         }
 
-        const delay = baseDelay + Math.random() * 2000; // 3-5秒のランダムな遅延
+        const delay = baseDelay + Math.random() * 2000; 
         this.logger.warn(
           `⚠️ Failed to analyze page ${pageIndex || '?'} (${attempt}/${maxRetries}), retrying in ${delay.toFixed(0)}ms: ${error.message}`
         );
@@ -45,35 +43,33 @@ export class VisionService {
       }
     }
 
-    // この行は理論的には実行されませんが、TypeScript の要求を満たすために記述しています
+    
     throw new Error(this.i18nService.getMessage('retryMechanismError'));
   }
 
-  /**
-   * 実際の画像分析を実行
-   */
+  
   private async performAnalysis(
     imagePath: string,
     modelConfig: VisionModelConfig,
     pageIndex?: number,
   ): Promise<VisionAnalysisResult> {
     try {
-      // 画像を読み込み、base64 に変換
+      
       const imageBuffer = await fs.readFile(imagePath);
       const base64Image = imageBuffer.toString('base64');
       const mimeType = this.getMimeType(imagePath);
 
-      // ビジョンモデルのインスタンスを作成
+      
       const model = new ChatOpenAI({
         apiKey: modelConfig.apiKey,
         model: modelConfig.modelId,
         configuration: {
           baseURL: modelConfig.baseUrl,
         },
-        temperature: 0.1, // ランダム性を抑え、一貫性を高める
+        temperature: 0.1, 
       });
 
-      // 専門的なドキュメント分析プロンプトを構築
+      
       const systemPrompt = this.i18nService.getMessage('visionSystemPrompt');
 
       const message = new HumanMessage({
@@ -91,15 +87,15 @@ export class VisionService {
         ],
       });
 
-      // モデルの呼び出し
+      
       this.logger.log(this.i18nService.formatMessage('visionModelCall', { model: modelConfig.modelId, page: pageIndex || 'single' }));
       const response = await model.invoke([message]);
       let content = response.content as string;
 
-      // JSON の解析を試行
+      
       let result: VisionAnalysisResult;
       try {
-        // Markdown のコードブロックタグをクリーンアップ
+        
         content = content.replace(/```json/g, '').replace(/```/g, '').trim();
         const parsed = JSON.parse(content);
 
@@ -111,7 +107,7 @@ export class VisionService {
           pageIndex,
         };
       } catch (parseError) {
-        // 解析に失敗した場合は、内容全体をテキストとして扱う
+        
         this.logger.warn(`Failed to parse JSON response for ${imagePath}, using raw text`);
         result = {
           text: content,
@@ -125,7 +121,7 @@ export class VisionService {
       this.logger.log(
         this.i18nService.formatMessage('visionAnalysisSuccess', {
           path: imagePath,
-          page: pageIndex ? ` (第 ${pageIndex} ページ)` : '',
+          page: pageIndex ? ` (th page ${pageIndex})` : '',
           textLen: result.text.length,
           imgCount: result.images.length,
           layout: result.layout,
@@ -135,19 +131,17 @@ export class VisionService {
 
       return result;
     } catch (error) {
-      throw error; // 重新抛出错误供重试机制处理
+      throw error; 
     }
   }
 
-  /**
-   * 再試行可能なエラーかどうかを判断
-   */
+  
   private isRetryableError(error: any): boolean {
     const errorMessage = error.message?.toLowerCase() || '';
     const errorCode = error.status || error.code;
 
-    // 429 レート制限エラー
-    if (errorCode === 429 || errorMessage.includes('rate limit') || errorMessage.includes('リクエストが多すぎます')) {
+    
+    if (errorCode === 429 || errorMessage.includes('rate limit') || errorMessage.includes('Too many requests')) {
       return true;
     }
 
@@ -156,7 +150,7 @@ export class VisionService {
       return true;
     }
 
-    // ネットワーク関連エラー
+    
     if (errorMessage.includes('timeout') || errorMessage.includes('network') || errorMessage.includes('connection')) {
       return true;
     }
@@ -164,16 +158,12 @@ export class VisionService {
     return false;
   }
 
-  /**
-   * 遅延関数
-   */
+  
   private sleep(ms: number): Promise<void> {
     return new Promise(resolve => setTimeout(resolve, ms));
   }
 
-  /**
-   * 複数画像の一括分析
-   */
+  
   async batchAnalyze(
     imagePaths: string[],
     modelConfig: VisionModelConfig,
@@ -198,12 +188,12 @@ export class VisionService {
 
       this.logger.log(`🖼️  Analyzing page ${pageIndex} (${i + 1}/${imagePaths.length}, ${progress}%)`);
 
-      // 進捗コールバックを呼び出し
+      
       if (onProgress) {
         onProgress(i + 1, imagePaths.length);
       }
 
-      // 品質チェック(スキップ時は直接分析)
+      
       if (!skipQualityCheck) {
         const quality = await this.checkImageQuality(imagePath);
         if (!quality.isGood) {
@@ -231,7 +221,7 @@ export class VisionService {
           `Confidence: ${(result.confidence * 100).toFixed(1)}%)`
         );
 
-        // 結果付きで進捗コールバックを呼び出し
+        
         if (onProgress) {
           onProgress(i + 1, imagePaths.length, result);
         }
@@ -241,7 +231,7 @@ export class VisionService {
       }
     }
 
-    // 推定コストの計算(1枚あたり $0.01 と仮定)
+    
     const estimatedCost = successCount * 0.01;
 
     this.logger.log(
@@ -259,25 +249,23 @@ export class VisionService {
     };
   }
 
-  /**
-   * 画像品質のチェック
-   */
+  
   async checkImageQuality(imagePath: string): Promise<{ isGood: boolean; reason?: string; score?: number }> {
     try {
       const stats = await fs.stat(imagePath);
       const sizeKB = stats.size / 1024;
 
-      // ファイルサイズのチェック(5KB以上)
+      
       if (sizeKB < 5) {
-        return { isGood: false, reason: `ファイルが小さすぎます (${sizeKB.toFixed(2)}KB)`, score: 0 };
+        return { isGood: false, reason: `File is too small (${sizeKB.toFixed(2)}KB)`, score: 0 };
       }
 
-      // ファイルサイズ上限のチェック(10MB)
+      
       if (sizeKB > 10240) {
-        return { isGood: false, reason: `ファイルが大きすぎます (${sizeKB.toFixed(2)}KB)`, score: 0 };
+        return { isGood: false, reason: `File is too large (${sizeKB.toFixed(2)}KB)`, score: 0 };
       }
 
-      // 簡易的な品質スコアリング
+      
       let score = 0.5;
       if (sizeKB > 50) score += 0.2;
       if (sizeKB > 100) score += 0.2;
@@ -291,9 +279,7 @@ export class VisionService {
     }
   }
 
-  /**
-   * サポートされている画像ファイルかどうかを確認
-   */
+  
   isImageFile(mimetype: string): boolean {
     const imageMimeTypes = [
       'image/jpeg',
@@ -306,9 +292,7 @@ export class VisionService {
     return imageMimeTypes.includes(mimetype);
   }
 
-  /**
-   * MIME タイプを取得
-   */
+  
   private getMimeType(filePath: string): string {
     const ext = filePath.toLowerCase().split('.').pop();
     if (!ext) return 'image/jpeg';
@@ -324,9 +308,7 @@ export class VisionService {
     return mimeTypes[ext] || 'image/jpeg';
   }
 
-  /**
-   * 旧インターフェース互換:単一画像の内容を抽出
-   */
+  
   async extractImageContent(
     imagePath: string,
     modelConfig: { baseUrl: string; apiKey: string; modelId: string },

+ 265 - 0
true_code.txt

@@ -0,0 +1,265 @@
+console.log('Final LLM model used (default):', llmModel ? llmModel.name : '无');
+`data: ${JSON.stringify({ type: 'error', data: '请在模型管理中添加LLM模型并配置API密钥' })}\n\n`,
+`data: ${JSON.stringify({ type: 'error', data: error.message || '服务器错误' })}\n\n`,
+`data: ${JSON.stringify({ type: 'error', data: '未找到LLM模型配置' })}\n\n`,
+console.log('ユーザーID:', userId);
+console.log('API Key プレフィックス:', modelConfig.apiKey?.substring(0, 10) + '...');
+提供されたテキスト内容を、ユーザーの指示に基づいて修正または改善してください。
+挨拶や結びの言葉(「わかりました、こちらが...」など)は含めず、修正後の内容のみを直接出力してください。
+コンテキスト(現在の内容):
+ユーザーの指示:
+* 対話内容に基づいてチャットのタイトルを自動生成する
+* アプリケーション全体で使用される定数定義
+* Elasticsearch スコアを 0-1 の範囲に正規化する
+* Elasticsearch のスコアは 1.0 を超える可能性があるため、正規化が必要
+* ただし、kNN検索の類似度スコアは既に0-1の範囲にある(cosine similarity)ので、
+* 特別な正規化は不要。必要に応じて最小値保護のみ行う。
+* 指定されたファイルのすべてのチャンクを取得
+基于以下知识库内容回答用户问题。
+**重要提示**: 用户已选择特定知识组,请严格基于以下知识库内容回答。如果知识库中没有相关信息,请明确告知用户:"${noMatchMsg}",然后再提供答案。
+知识库内容:
+历史对话:
+用户问题:{question}
+请用Chinese回答,并严格遵循以下 Markdown 格式要求:
+1. **段落与结构**:
+- 使用清晰的段落分隔,每个要点之间空一行
+- 使用标题(## 或 ###)组织长回答
+2. **文本格式**:
+- 使用 **粗体** 强调重要概念和关键词
+- 使用列表(- 或 1.)组织多个要点
+- 使用 \`代码\` 标记技术术语、命令、文件名
+3. **代码展示**:
+- 使用代码块展示代码,并指定语言:
+return "示例"
+- 支持语言:python, javascript, typescript, java, bash, sql 等
+4. **图表与可视化**:
+- 使用 Mermaid 语法绘制流程图、序列图等:
+A[开始] --> B[处理]
+B --> C[结束]
+- 适用场景:流程、架构、状态机、时序图
+5. **其他要求**:
+- 回答精炼准确
+- 多步骤操作使用有序列表
+- 对比类信息建议用表格展示(如果适用)
+作为智能助手,请回答用户的问题。
+请用Chinese回答。
+以下のナレッジベースの内容に基づいてユーザーの質問に答えてください。
+**重要**: ユーザーが特定の知識グループを選択しました。以下のナレッジベースの内容に厳密に基づいて回答してください。ナレッジベースに関連情報がない場合は、「${noMatchMsg}」とユーザーに明示的に伝えてから、回答を提供してください。
+ナレッジベースの内容:
+会話履歴:
+ユーザーの質問:{question}
+Japaneseで回答してください。以下の Markdown 書式要件に厳密に従ってください:
+1. **段落と構造**:
+- 明確な段落分けを使用し、要点間に空行を入れる
+- 長い回答には見出し(## または ###)を使用
+2. **テキスト書式**:
+- 重要な概念やキーワードを強調するために **太字** を使用
+- 複数のポイントを整理するためにリスト(- または 1.)を使用
+- 技術用語、コマンド、ファイル名をマークするために \`コード\` を使用
+3. **コード表示**:
+- 言語を指定してコードブロックを使用:
+return "例"
+- 対応言語:python, javascript, typescript, java, bash, sql など
+4. **図表とチャート**:
+- フローチャート、シーケンス図などに Mermaid 構文を使用:
+A[開始] --> B[処理]
+B --> C[終了]
+- 使用例:プロセスフロー、アーキテクチャ図、状態図、シーケンス図
+5. **その他の要件**:
+- 簡潔で明確な回答を心がける
+- 複数のステップがある場合は番号付きリストを使用
+- 比較情報には表を使用(該当する場合)
+インテリジェントアシスタントとして、ユーザーの質問に答えてください。
+Japaneseで回答してください。
+return `你是一个文档分析师。请阅读以下文本(文档开Header分),并生成一个简炼、专业的标题(不超过50个字符)。
+只返回标题文本。不要包含任何解释性文字或前导词(如“标题是:”)。
+语言:Chinese
+文本内容:
+return `あなたはドキュメントアナライザーです。以下のテキスト(ドキュメントの冒頭部分)を読み、簡潔でプロフェッショナルなタイトル(最大50文字)を生成してください。
+タイトルテキストのみを返してください。説明文や前置き(例:「タイトルは:」)は含めないでください。
+言語:Japanese
+テキスト:
+return `根据以下对话片段,生成一个简短、描述性的标题(不超过50个字符),总结讨论的主题。
+只返回标题文本。不要包含任何前导词。
+片段:
+用户: ${userMessage}
+助手: ${aiResponse}`;
+return `以下の会話スニペットに基づいて、トピックを要約する短く説明的なタイトル(最大50文字)を生成してください。
+タイトルのみを返してください。前置きは不要です。
+スニペット:
+ユーザー: ${userMessage}
+アシスタント: ${aiResponse}`;
+* Chunk configurationサービス
+* チャンクパラメータの検証と管理を担当し、モデルの制限や環境変数の設定に適合していることを確認します
+* 制限の優先順位:
+* 1. 環境変数 (MAX_CHUNK_SIZE, MAX_OVERLAP_SIZE)
+* 2. データベース内のモデル設定 (maxInputTokens, maxBatchSize)
+* 3. デフォルト値
+* モデルの制限設定を取得(データベースから読み込み)
+const providerName = modelConfig.providerName || '不明';
+`  - プロバイダー: ${providerName}\n` +
+`  - Token制限: ${maxInputTokens}\n` +
+`  - ベクトルモデルか: ${isVectorModel}`,
+* Chunk configurationを検証および修正
+* 優先順位: 環境変数の上限 > モデルの制限 > ユーザー設定
+* 推奨されるバッチサイズを取得
+* チャンク数を推定
+* ベクトル次元の検証
+* 設定概要を取得(ログ用)
+`Chunk size: ${chunkSize} tokens (制限: ${limits.maxInputTokens})`,
+`重なりサイズ: ${chunkOverlap} tokens`,
+`バッチサイズ: ${limits.maxBatchSize}`,
+* フロントエンド用のConfig limitsを取得
+* フロントエンドのスライダーの上限設定に使用
+throw new Error(`埋め込みモデル設定 ${embeddingModelConfigId} が見つかりません`);
+throw new Error(`モデル ${modelConfig.name} は無効化されているため、埋め込みベクトルを生成できません`);
+throw new Error(`モデル ${modelConfig.name} に baseUrl が設定されていません`);
+* モデルIDに基づいて最大バッチサイズを決定
+* 単一バッチの埋め込み処理
+`総計 ${totalLength} 文字、平均 ${Math.round(avgLength)} 文字、` +
+`モデル制限: ${modelConfig.maxInputTokens || 8192} tokens`
+`テキスト長がモデルの制限。` +
+`現在: ${texts.length} 個のテキストで計 ${totalLength} 文字、` +
+`モデル制限: ${modelConfig.maxInputTokens || 8192} tokens。` +
+`アドバイス: Chunk sizeまたはバッチサイズを小さくしてください`
+this.logger.error(`リクエストパラメータ: model=${modelConfig.modelId}, inputLength=${texts[0]?.length}`);
+throw new Error(`埋め込み API の呼び出しに失敗しました: ${response.statusText} - ${errorText}`);
+* Fetch chunk configuration limits(フロントエンドのスライダー設定用)
+* クエリパラメータ: embeddingModelId - Embedding model ID
+* Fast Mode処理(既存フロー)
+* Precise Mode処理(新規フロー)
+* Precise Modeの結果をインデックス
+* PDF の特定ページの画像を取得
+if (error.message && (error.message.includes('context length') || error.message.includes('コンテキスト長 exceeds limit ') || error.message.includes('コンテキスト長 exceeds limit '))) {
+* バッチ処理、メモリ制御付き
+* 失敗したファイルのベクトル化を再試行
+throw new NotFoundException('ファイルが存在しません');
+* ファイルのすべてのチャンク情報を取得
+* モデルの実際の次元数を取得(キャッシュ確認とプローブロジック付き)
+* AIを使用して文書のタイトルを自動生成する
+* 現在のメモリ使用状況を取得
+* メモリ exceeds limit に近づいているかチェック
+* メモリが利用可能になるまで待機(タイムアウトあり)
+throw new Error(`メモリ待機がタイムアウトしました: 現在 ${this.getMemoryUsage().heapUsed}MB > ${this.MAX_MEMORY_MB * 0.85}MB`);
+* ガベージコレクションを強制実行(可能な場合)
+* バッチサイズを動的に調整
+* 大規模データの処理:自動バッチングとメモリ制御
+* 処理に必要なメモリを見積もる
+* バッチ処理を使用すべきかチェック
+* LibreOffice サービスインターフェース定義
+* LibreOffice サービスの状態をチェック
+* ドキュメントを PDF に変換
+* @param filePath 変換するファイルのパス
+* @returns PDF ファイルのパス
+throw new Error(`ファイルが存在しません: ${filePath}`);
+throw new Error('変換がタイムアウトしました。ファイルが大きすぎる可能性があります');
+throw new Error(`変換に失敗しました: ${detail}`);
+throw new Error(`変換に失敗しました: ${lastError.message}`);
+throw new Error('LibreOffice サービスが実行されていません。サービスの状態を確認してください');
+throw new Error('LibreOffice サービスとの接続が切断されました。サービスが不安定である可能性があります');
+* ファイルの一括変換
+* サービスのバージョン情報を取得
+@Min(1, { message: 'ベクトル次元の最小値は 1 です' })
+@Max(4096, { message: 'ベクトル次元の最大値は 4096 です(Elasticsearch の制限)' })
+* モデルの入力トークン制限(embedding/rerank にのみ有効)
+* バッチ処理の制限(embedding/rerank にのみ有効)
+* ベトルモデルかどうか
+* モデルプロバイダー名
+* このモデルを有効にするかどうか
+* このモデルをデフォルトとして使用するかどうか
+* モデルの入力トークン制限
+* 例: OpenAI=8191, Gemini=2048
+* 一括処理制限(1回のリクエストあたりの最大入力数)
+* 例: OpenAI=2048, Gemini=100
+* ベトルモデルかどうか(システム設定での識別用)
+* ユーザーは使用しないモデルを無効にして、誤選択を防ぐことができます
+* 各タイプ(llm, embedding, rerank)ごとに1つのみデフォルトにできます
+* モデルプロバイダー名(表示および識別用)
+* 例: "OpenAI", "Google Gemini", "Custom"
+* 指定されたモデルをデフォルトに設定
+* 指定されたタイプのデフォルトモデルを取得
+* 厳密なルール:Index Chat Configで指定されたモデルのみを返し、なければエラーを投げる
+* PDF 转图片接口定义
+* PDF を画像リストに変換します
+* ImageMagick の convert コマンドを使用します
+throw new Error(`PDF ファイルが存在しません: ${pdfPath}`);
+throw new Error('PDF のページ数を取得できません');
+throw new Error(`Python での変換に失敗しました: ${result.error}`);
+throw new Error(`PDF から画像への変換に失敗しました: ${error.message}`);
+* 複数の PDF を一括変換
+* 画像ファイルのクリーンアップ
+* ディレクトリのクリーンアップ
+* 画像品質が妥当か確認
+throw new Error('Embedding model IDが提供されていません');
+* Search resultsの重複排除
+* クエリを拡張してバリエーションを生成
+* 仮想的なドキュメント(HyDE)を生成
+* 内部タスク用の LLM インスタンスを取得
+* リランクの実行
+* @param query ユーザーのクエリ
+* @param documents 候補ドキュメントリスト
+* @param userId ユーザーID
+* @param rerankModelId 選択された Rerank モデル設定ID
+* @param topN 返す結果の数 (上位 N 個)
+return { message: '对话历史删除成功' };
+`ユーザー ${req.user.id} がファイルをアップロードしました: ${file.originalname} (${this.formatBytes(file.size)})`,
+console.log('パスワード:', randomPassword);
+console.log('=== updateLanguage デバッグ ===');
+console.log('=== getLanguage デバッグ ===');
+* システム全体のグローバル設定を取得する
+* システム全体のグローバル設定を更新する
+* Vision 服务接口定义
+* 単一画像の分析(ドキュメントページ)
+* 実際の画像分析を実行
+page: pageIndex ? ` (第 ${pageIndex} ページ)` : '',
+* 再試行可能なエラーかどうかを判断
+if (errorCode === 429 || errorMessage.includes('rate limit') || errorMessage.includes('リクエストが多すぎます')) {
+* 遅延関数
+* 複数画像の一括分析
+* 画像品質のチェック
+return { isGood: false, reason: `ファイルが小さすぎます (${sizeKB.toFixed(2)}KB)`, score: 0 };
+return { isGood: false, reason: `ファイルが大きすぎます (${sizeKB.toFixed(2)}KB)`, score: 0 };
+* サポートされている画像ファイルかどうかを確認
+* MIME タイプを取得
+* 旧インターフェース互換:単一画像の内容を抽出
+* コスト制御およびクォータ管理サービス
+* Vision Pipeline の API 呼び出しコストを管理するために使用されます
+* 処理コストの推定
+* ユーザーのクォータをチェック
+reason: `クォータ不足: 残り $${quota.remaining.toFixed(2)}, 必要 $${estimatedCost.toFixed(2)}`,
+* クォータの差し引き
+* ユーザーのクォータを取得
+throw new Error(`ユーザー ${userId} は存在しません`);
+* 月間クォータのチェックとリセット
+* ユーザーのクォータ制限を設定
+* コストレポートの取得
+* コスト警告閾値のチェック
+message: `⚠️ クォータ使用率が ${usagePercent.toFixed(1)}% に達しました。残り $${quota.remaining.toFixed(2)}`,
+message: `💡 クォータ使用率 ${usagePercent.toFixed(1)}%。コストの管理に注意してください`,
+* コスト表示のフォーマット
+* 時間表示のフォーマット
+return `${seconds.toFixed(0)}秒`;
+return `${minutes}分${remainingSeconds.toFixed(0)}秒`;
+* Vision Pipeline サービス(コスト制御付き)
+* これは vision-pipeline.service.ts の拡張版であり、コスト制御が統合されています
+* メイン処理フロー:Precise Mode(コスト制御付き)
+this.updateStatus('converting', 10, 'ドキュメント形式を変換中...');
+this.updateStatus('splitting', 30, 'PDF を画像に変換中...');
+throw new Error('PDF から画像への変換に失敗しました。画像が生成されませんでした');
+this.updateStatus('checking', 40, 'クォータを確認し、コストを見積もり中...');
+this.updateStatus('analyzing', 50, 'ビジョンモデルを使用してページをAnalyzing...');
+this.updateStatus('completed', 100, '処理が完了しました。一時ファイルをクリーンアップ中...');
+* Vision モデル設定の取得
+throw new Error(`モデル設定が見つかりません: ${modelId}`);
+* PDF への変換
+* 形式検出とモードの推奨(コスト見積もり付き)
+reason: `サポートされていないファイル形式です: ${ext}`,
+warnings: ['Fast Mode(テキスト抽出のみ)を使用します'],
+reason: `形式 ${ext} はPrecise Modeをサポートしていません`,
+reason: 'ファイルが大きいため、完全な情報を保持するためにPrecise Modeを推奨します',
+warnings: ['処理時間が長くなる可能性があります', 'API 費用が発生します'],
+reason: 'Precise Modeが利用可能です。テキストと画像の混合コンテンツを保持できます',
+warnings: ['API 費用が発生します'],
+* ユーザーのクォータ情報を取得
+* 処理状態の更新(リアルタイムフィードバック用)
+* Vision Pipeline 接口定义

+ 1 - 1
web/components/GroupSelector.tsx

@@ -162,7 +162,7 @@ export const GroupSelector: React.FC<GroupSelectorProps> = ({
                           {group.name}
                         </div>
                         <div className="text-[10px] text-gray-400">
-                          {group.fileCount} 文件
+                          {group.fileCount} files
                         </div>
                       </div>
                     </div>

+ 1 - 92
web/services/chunkConfigService.ts

@@ -17,98 +17,7 @@ export interface EmbeddingModelLimit {
 }
 
 export const chunkConfigService = {
-  /**
-   * Fetch chunk configuration limits
-   * @param embeddingModelId Embedding model ID
-   * @param authToken Auth token
-   * @returns Configuration limit info
-   */
-  async getLimits(
-    embeddingModelId: string,
-    authToken: string
-  ): Promise<ChunkConfigLimits> {
-    const params = new URLSearchParams({
-      embeddingModelId,
-    });
-
-    const response = await fetch(
-      `/api/knowledge-bases/chunk-config/limits?${params.toString()}`,
-      {
-        method: 'GET',
-        headers: {
-          'Authorization': `Bearer ${authToken}`,
-          'Content-Type': 'application/json',
-        },
-      }
-    );
-
-    if (!response.ok) {
-      const errorData = await response.json();
-      throw new Error(errorData.message || 'loadLimitsFailed');
-    }
-
-    return response.json();
-  },
-
-  /**
-   * 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,
-    chunkOverlap: number,
-    limits: ChunkConfigLimits
-  ): {
-    isValid: boolean;
-    errors: string[];
-    adjustedChunkSize: number;
-    adjustedOverlapSize: number;
-  } {
-    const errors: string[] = [];
-    let adjustedChunkSize = chunkSize;
-    let adjustedOverlapSize = chunkOverlap;
-
-    // Chunk sizeの検証
-    if (chunkSize > limits.maxChunkSize) {
-      errors.push(`Chunk size ${chunkSize}  exceeds limit  ${limits.maxChunkSize} `);
-      adjustedChunkSize = limits.maxChunkSize;
-    }
-
-    if (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(`Overlap size ${chunkOverlap}  exceeds limit  ${limits.maxOverlapSize} `);
-      adjustedOverlapSize = limits.maxOverlapSize;
-    }
-
-    if (chunkOverlap > maxOverlapByRatio) {
-      errors.push(`Overlap size ${chunkOverlap} がChunk sizeの50% (${maxOverlapByRatio}) `);
-      adjustedOverlapSize = maxOverlapByRatio;
-    }
-
-    if (chunkOverlap < limits.minOverlapSize) {
-      adjustedOverlapSize = limits.minOverlapSize;
-    }
-
-    return {
-      isValid: errors.length === 0,
-      errors,
-      adjustedChunkSize,
-      adjustedOverlapSize,
-    };
-  },
-
-  /**
-   * Format limit info for display
-   */
+  
   formatLimits(limits: ChunkConfigLimits): string {
     return [
       `Model: ${limits.modelInfo.name}`,

+ 1 - 1
web/services/knowledgeGroupService.ts

@@ -54,7 +54,7 @@ export const knowledgeGroupService = {
     return data.files;
   },
 
-  // ファイルをグループにAdded
+  
   async addFileToGroups(fileId: string, groupIds: string[]): Promise<void> {
     await apiClient.post(`/knowledge-bases/${fileId}/groups`, { groupIds });
   },

+ 3 - 3
web/services/pdfPreviewService.ts

@@ -2,19 +2,19 @@ import { PDFStatus } from '../types';
 import { apiClient } from './apiClient';
 
 export const pdfPreviewService = {
-  // PDFプレビューURLの取得
+  
   async getPDFUrl(fileId: string): Promise<{ url: string }> {
     const { data } = await apiClient.get<{ url: string }>(`/knowledge-bases/${fileId}/pdf-url`);
     return data;
   },
 
-  // PDFステータスの確認
+  
   async getPDFStatus(fileId: string): Promise<PDFStatus> {
     const { data } = await apiClient.get<PDFStatus>(`/knowledge-bases/${fileId}/pdf-status`);
     return data;
   },
 
-  // PDFのプリロード(変換のトリガー)
+  
   async preloadPDF(fileId: string, force: boolean = false): Promise<void> {
     try {
       const url = `/knowledge-bases/${fileId}/pdf-url` + (force ? '?force=true' : '');

+ 1 - 3
web/services/ragService.ts

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

+ 4 - 4
web/services/searchHistoryService.ts

@@ -2,7 +2,7 @@ import { SearchHistoryItem, SearchHistoryDetail } from '../types';
 import { apiClient } from './apiClient';
 
 export const searchHistoryService = {
-  // 検索履歴リストの取得
+  
   async getHistories(page: number = 1, limit: number = 20): Promise<{
     histories: SearchHistoryItem[];
     total: number;
@@ -13,19 +13,19 @@ export const searchHistoryService = {
     return data;
   },
 
-  // 検索履歴詳細の取得
+  
   async getHistoryDetail(id: string): Promise<SearchHistoryDetail> {
     const { data } = await apiClient.get(`/search-history/${id}`);
     return data;
   },
 
-  // 検索履歴の作成
+  
   async createHistory(title: string, selectedGroups?: string[]): Promise<{ id: string }> {
     const { data } = await apiClient.post(`/search-history`, { title, selectedGroups });
     return data;
   },
 
-  // 検索履歴の削除
+  
   async deleteHistory(id: string): Promise<void> {
     await apiClient.delete(`/search-history/${id}`);
   },

+ 8 - 11
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));
     }
@@ -62,12 +62,9 @@ export const uploadService = {
     return data;
   },
 
-  /**
-   * ファイル処理モードの推奨を取得
-   * ファイルの種類、サイズなどの要因に基づいて、Fast Modeまたは高精度モードの使用を推奨します
-   */
+  
   async recommendMode(file: File): Promise<any> {
-    // セーフティチェック
+    
     if (!file || !file.name) {
       return {
         recommendedMode: 'fast',
@@ -76,7 +73,7 @@ export const uploadService = {
       };
     }
 
-    // フロントエンドの簡単な判定ロジック
+    
     const ext = file.name.toLowerCase().split('.').pop();
     const sizeMB = file.size / (1024 * 1024);
 
@@ -101,7 +98,7 @@ export const uploadService = {
       };
     }
 
-    // 小規模なファイルにはFast Modeを推奨
+    
     if (sizeMB < 5) {
       return {
         recommendedMode: 'fast',
@@ -112,7 +109,7 @@ export const uploadService = {
       };
     }
 
-    // 中規模なファイルには高精度モードを推奨
+    
     if (sizeMB < 50) {
       return {
         recommendedMode: 'precise',
@@ -123,7 +120,7 @@ export const uploadService = {
       };
     }
 
-    // 大規模なファイルには高精度モードを推奨するが警告を表示
+    
     return {
       recommendedMode: 'precise',
       reason: 'largeFilePreciseRecommended',

+ 1 - 1
web/src/utils/toast.ts

@@ -1,4 +1,4 @@
-// 簡易的なトースト実装
+
 export const toast = {
   success: (message: string) => {
     alert(`✅ ${message}`);

+ 2 - 2
web/types.ts

@@ -7,12 +7,12 @@ export interface IndexingConfig {
   groupIds?: string[]; // Groups to associate with the file upon upload
 }
 
-// Vision Pipeline 相关类型
+
 export interface VisionAnalysisResult {
   text: string;              // Extracted text content
   images: ImageDescription[]; // Image descriptions
   layout: string;            // Layout type
-  confidence: number;        // 信頼度 (0-1)
+  confidence: number;        
   pageIndex?: number;        // Page number
 }