Merge pull request #1148 from ParisNeo/main
Added anthropic binding and few localization to other languages
This commit is contained in:
271
lightrag/llm/anthropic.py
Normal file
271
lightrag/llm/anthropic.py
Normal file
@@ -0,0 +1,271 @@
|
|||||||
|
from ..utils import verbose_debug, VERBOSE_DEBUG
|
||||||
|
import sys
|
||||||
|
import os
|
||||||
|
import logging
|
||||||
|
import numpy as np
|
||||||
|
from typing import Any, Union, AsyncIterator
|
||||||
|
import pipmaster as pm # Pipmaster for dynamic library install
|
||||||
|
|
||||||
|
if sys.version_info < (3, 9):
|
||||||
|
from typing import AsyncIterator
|
||||||
|
else:
|
||||||
|
from collections.abc import AsyncIterator
|
||||||
|
|
||||||
|
# Install Anthropic SDK if not present
|
||||||
|
if not pm.is_installed("anthropic"):
|
||||||
|
pm.install("anthropic")
|
||||||
|
|
||||||
|
# Add Voyage AI import
|
||||||
|
if not pm.is_installed("voyageai"):
|
||||||
|
pm.install("voyageai")
|
||||||
|
import voyageai
|
||||||
|
|
||||||
|
from anthropic import (
|
||||||
|
AsyncAnthropic,
|
||||||
|
APIConnectionError,
|
||||||
|
RateLimitError,
|
||||||
|
APITimeoutError,
|
||||||
|
)
|
||||||
|
from tenacity import (
|
||||||
|
retry,
|
||||||
|
stop_after_attempt,
|
||||||
|
wait_exponential,
|
||||||
|
retry_if_exception_type,
|
||||||
|
)
|
||||||
|
from lightrag.utils import (
|
||||||
|
safe_unicode_decode,
|
||||||
|
logger,
|
||||||
|
)
|
||||||
|
from lightrag.api import __api_version__
|
||||||
|
|
||||||
|
# Custom exception for retry mechanism
|
||||||
|
class InvalidResponseError(Exception):
|
||||||
|
"""Custom exception class for triggering retry mechanism"""
|
||||||
|
pass
|
||||||
|
|
||||||
|
# Core Anthropic completion function with retry
|
||||||
|
@retry(
|
||||||
|
stop=stop_after_attempt(3),
|
||||||
|
wait=wait_exponential(multiplier=1, min=4, max=10),
|
||||||
|
retry=retry_if_exception_type(
|
||||||
|
(RateLimitError, APIConnectionError, APITimeoutError, InvalidResponseError)
|
||||||
|
),
|
||||||
|
)
|
||||||
|
async def anthropic_complete_if_cache(
|
||||||
|
model: str,
|
||||||
|
prompt: str,
|
||||||
|
system_prompt: str | None = None,
|
||||||
|
history_messages: list[dict[str, Any]] | None = None,
|
||||||
|
base_url: str | None = None,
|
||||||
|
api_key: str | None = None,
|
||||||
|
**kwargs: Any,
|
||||||
|
) -> Union[str, AsyncIterator[str]]:
|
||||||
|
if history_messages is None:
|
||||||
|
history_messages = []
|
||||||
|
if not api_key:
|
||||||
|
api_key = os.environ.get("ANTHROPIC_API_KEY")
|
||||||
|
|
||||||
|
default_headers = {
|
||||||
|
"User-Agent": f"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_8) LightRAG/{__api_version__}",
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
}
|
||||||
|
|
||||||
|
# Set logger level to INFO when VERBOSE_DEBUG is off
|
||||||
|
if not VERBOSE_DEBUG and logger.level == logging.DEBUG:
|
||||||
|
logging.getLogger("anthropic").setLevel(logging.INFO)
|
||||||
|
|
||||||
|
anthropic_async_client = (
|
||||||
|
AsyncAnthropic(default_headers=default_headers, api_key=api_key)
|
||||||
|
if base_url is None
|
||||||
|
else AsyncAnthropic(
|
||||||
|
base_url=base_url, default_headers=default_headers, api_key=api_key
|
||||||
|
)
|
||||||
|
)
|
||||||
|
kwargs.pop("hashing_kv", None)
|
||||||
|
messages: list[dict[str, Any]] = []
|
||||||
|
if system_prompt:
|
||||||
|
messages.append({"role": "system", "content": system_prompt})
|
||||||
|
messages.extend(history_messages)
|
||||||
|
messages.append({"role": "user", "content": prompt})
|
||||||
|
|
||||||
|
logger.debug("===== Sending Query to Anthropic LLM =====")
|
||||||
|
logger.debug(f"Model: {model} Base URL: {base_url}")
|
||||||
|
logger.debug(f"Additional kwargs: {kwargs}")
|
||||||
|
verbose_debug(f"Query: {prompt}")
|
||||||
|
verbose_debug(f"System prompt: {system_prompt}")
|
||||||
|
|
||||||
|
try:
|
||||||
|
response = await anthropic_async_client.messages.create(
|
||||||
|
model=model,
|
||||||
|
messages=messages,
|
||||||
|
stream=True,
|
||||||
|
**kwargs
|
||||||
|
)
|
||||||
|
except APIConnectionError as e:
|
||||||
|
logger.error(f"Anthropic API Connection Error: {e}")
|
||||||
|
raise
|
||||||
|
except RateLimitError as e:
|
||||||
|
logger.error(f"Anthropic API Rate Limit Error: {e}")
|
||||||
|
raise
|
||||||
|
except APITimeoutError as e:
|
||||||
|
logger.error(f"Anthropic API Timeout Error: {e}")
|
||||||
|
raise
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(
|
||||||
|
f"Anthropic API Call Failed,\nModel: {model},\nParams: {kwargs}, Got: {e}"
|
||||||
|
)
|
||||||
|
raise
|
||||||
|
|
||||||
|
async def stream_response():
|
||||||
|
try:
|
||||||
|
async for event in response:
|
||||||
|
content = event.delta.text if hasattr(event, "delta") and event.delta.text else None
|
||||||
|
if content is None:
|
||||||
|
continue
|
||||||
|
if r"\u" in content:
|
||||||
|
content = safe_unicode_decode(content.encode("utf-8"))
|
||||||
|
yield content
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"Error in stream response: {str(e)}")
|
||||||
|
raise
|
||||||
|
|
||||||
|
return stream_response()
|
||||||
|
|
||||||
|
# Generic Anthropic completion function
|
||||||
|
async def anthropic_complete(
|
||||||
|
prompt: str,
|
||||||
|
system_prompt: str | None = None,
|
||||||
|
history_messages: list[dict[str, Any]] | None = None,
|
||||||
|
**kwargs: Any,
|
||||||
|
) -> Union[str, AsyncIterator[str]]:
|
||||||
|
if history_messages is None:
|
||||||
|
history_messages = []
|
||||||
|
model_name = kwargs["hashing_kv"].global_config["llm_model_name"]
|
||||||
|
return await anthropic_complete_if_cache(
|
||||||
|
model_name,
|
||||||
|
prompt,
|
||||||
|
system_prompt=system_prompt,
|
||||||
|
history_messages=history_messages,
|
||||||
|
**kwargs,
|
||||||
|
)
|
||||||
|
|
||||||
|
# Claude 3 Opus specific completion
|
||||||
|
async def claude_3_opus_complete(
|
||||||
|
prompt: str,
|
||||||
|
system_prompt: str | None = None,
|
||||||
|
history_messages: list[dict[str, Any]] | None = None,
|
||||||
|
**kwargs: Any,
|
||||||
|
) -> Union[str, AsyncIterator[str]]:
|
||||||
|
if history_messages is None:
|
||||||
|
history_messages = []
|
||||||
|
return await anthropic_complete_if_cache(
|
||||||
|
"claude-3-opus-20240229",
|
||||||
|
prompt,
|
||||||
|
system_prompt=system_prompt,
|
||||||
|
history_messages=history_messages,
|
||||||
|
**kwargs,
|
||||||
|
)
|
||||||
|
|
||||||
|
# Claude 3 Sonnet specific completion
|
||||||
|
async def claude_3_sonnet_complete(
|
||||||
|
prompt: str,
|
||||||
|
system_prompt: str | None = None,
|
||||||
|
history_messages: list[dict[str, Any]] | None = None,
|
||||||
|
**kwargs: Any,
|
||||||
|
) -> Union[str, AsyncIterator[str]]:
|
||||||
|
if history_messages is None:
|
||||||
|
history_messages = []
|
||||||
|
return await anthropic_complete_if_cache(
|
||||||
|
"claude-3-sonnet-20240229",
|
||||||
|
prompt,
|
||||||
|
system_prompt=system_prompt,
|
||||||
|
history_messages=history_messages,
|
||||||
|
**kwargs,
|
||||||
|
)
|
||||||
|
|
||||||
|
# Claude 3 Haiku specific completion
|
||||||
|
async def claude_3_haiku_complete(
|
||||||
|
prompt: str,
|
||||||
|
system_prompt: str | None = None,
|
||||||
|
history_messages: list[dict[str, Any]] | None = None,
|
||||||
|
**kwargs: Any,
|
||||||
|
) -> Union[str, AsyncIterator[str]]:
|
||||||
|
if history_messages is None:
|
||||||
|
history_messages = []
|
||||||
|
return await anthropic_complete_if_cache(
|
||||||
|
"claude-3-haiku-20240307",
|
||||||
|
prompt,
|
||||||
|
system_prompt=system_prompt,
|
||||||
|
history_messages=history_messages,
|
||||||
|
**kwargs,
|
||||||
|
)
|
||||||
|
|
||||||
|
# Embedding function (placeholder, as Anthropic does not provide embeddings)
|
||||||
|
@retry(
|
||||||
|
stop=stop_after_attempt(3),
|
||||||
|
wait=wait_exponential(multiplier=1, min=4, max=60),
|
||||||
|
retry=retry_if_exception_type(
|
||||||
|
(RateLimitError, APIConnectionError, APITimeoutError)
|
||||||
|
),
|
||||||
|
)
|
||||||
|
async def anthropic_embed(
|
||||||
|
texts: list[str],
|
||||||
|
model: str = "voyage-3", # Default to voyage-3 as a good general-purpose model
|
||||||
|
base_url: str = None,
|
||||||
|
api_key: str = None,
|
||||||
|
) -> np.ndarray:
|
||||||
|
"""
|
||||||
|
Generate embeddings using Voyage AI since Anthropic doesn't provide native embedding support.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
texts: List of text strings to embed
|
||||||
|
model: Voyage AI model name (e.g., "voyage-3", "voyage-3-large", "voyage-code-3")
|
||||||
|
base_url: Optional custom base URL (not used for Voyage AI)
|
||||||
|
api_key: API key for Voyage AI (defaults to VOYAGE_API_KEY environment variable)
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
numpy array of shape (len(texts), embedding_dimension) containing the embeddings
|
||||||
|
"""
|
||||||
|
if not api_key:
|
||||||
|
api_key = os.environ.get("VOYAGE_API_KEY")
|
||||||
|
if not api_key:
|
||||||
|
logger.error("VOYAGE_API_KEY environment variable not set")
|
||||||
|
raise ValueError("VOYAGE_API_KEY environment variable is required for embeddings")
|
||||||
|
|
||||||
|
try:
|
||||||
|
# Initialize Voyage AI client
|
||||||
|
voyage_client = voyageai.Client(api_key=api_key)
|
||||||
|
|
||||||
|
# Get embeddings
|
||||||
|
result = voyage_client.embed(
|
||||||
|
texts,
|
||||||
|
model=model,
|
||||||
|
input_type="document" # Assuming document context; could be made configurable
|
||||||
|
)
|
||||||
|
|
||||||
|
# Convert list of embeddings to numpy array
|
||||||
|
embeddings = np.array(result.embeddings, dtype=np.float32)
|
||||||
|
|
||||||
|
logger.debug(f"Generated embeddings for {len(texts)} texts using {model}")
|
||||||
|
verbose_debug(f"Embedding shape: {embeddings.shape}")
|
||||||
|
|
||||||
|
return embeddings
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"Voyage AI embedding failed: {str(e)}")
|
||||||
|
raise
|
||||||
|
|
||||||
|
# Optional: a helper function to get available embedding models
|
||||||
|
def get_available_embedding_models() -> dict[str, dict]:
|
||||||
|
"""
|
||||||
|
Returns a dictionary of available Voyage AI embedding models and their properties.
|
||||||
|
"""
|
||||||
|
return {
|
||||||
|
"voyage-3-large": {"context_length": 32000, "dimension": 1024, "description": "Best general-purpose and multilingual"},
|
||||||
|
"voyage-3": {"context_length": 32000, "dimension": 1024, "description": "General-purpose and multilingual"},
|
||||||
|
"voyage-3-lite": {"context_length": 32000, "dimension": 512, "description": "Optimized for latency and cost"},
|
||||||
|
"voyage-code-3": {"context_length": 32000, "dimension": 1024, "description": "Optimized for code"},
|
||||||
|
"voyage-finance-2": {"context_length": 32000, "dimension": 1024, "description": "Optimized for finance"},
|
||||||
|
"voyage-law-2": {"context_length": 16000, "dimension": 1024, "description": "Optimized for legal"},
|
||||||
|
"voyage-multimodal-3": {"context_length": 32000, "dimension": 1024, "description": "Multimodal text and images"},
|
||||||
|
}
|
239
lightrag_webui/src/locales/ar.json
Normal file
239
lightrag_webui/src/locales/ar.json
Normal file
@@ -0,0 +1,239 @@
|
|||||||
|
{
|
||||||
|
"settings": {
|
||||||
|
"language": "اللغة",
|
||||||
|
"theme": "السمة",
|
||||||
|
"light": "فاتح",
|
||||||
|
"dark": "داكن",
|
||||||
|
"system": "النظام"
|
||||||
|
},
|
||||||
|
"header": {
|
||||||
|
"documents": "المستندات",
|
||||||
|
"knowledgeGraph": "شبكة المعرفة",
|
||||||
|
"retrieval": "الاسترجاع",
|
||||||
|
"api": "واجهة برمجة التطبيقات",
|
||||||
|
"projectRepository": "مستودع المشروع",
|
||||||
|
"themeToggle": {
|
||||||
|
"switchToLight": "التحويل إلى السمة الفاتحة",
|
||||||
|
"switchToDark": "التحويل إلى السمة الداكنة"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"documentPanel": {
|
||||||
|
"clearDocuments": {
|
||||||
|
"button": "مسح",
|
||||||
|
"tooltip": "مسح المستندات",
|
||||||
|
"title": "مسح المستندات",
|
||||||
|
"confirm": "هل تريد حقًا مسح جميع المستندات؟",
|
||||||
|
"confirmButton": "نعم",
|
||||||
|
"success": "تم مسح المستندات بنجاح",
|
||||||
|
"failed": "فشل مسح المستندات:\n{{message}}",
|
||||||
|
"error": "فشل مسح المستندات:\n{{error}}"
|
||||||
|
},
|
||||||
|
"uploadDocuments": {
|
||||||
|
"button": "رفع",
|
||||||
|
"tooltip": "رفع المستندات",
|
||||||
|
"title": "رفع المستندات",
|
||||||
|
"description": "اسحب وأفلت مستنداتك هنا أو انقر للتصفح.",
|
||||||
|
"uploading": "جارٍ الرفع {{name}}: {{percent}}%",
|
||||||
|
"success": "نجاح الرفع:\nتم رفع {{name}} بنجاح",
|
||||||
|
"failed": "فشل الرفع:\n{{name}}\n{{message}}",
|
||||||
|
"error": "فشل الرفع:\n{{name}}\n{{error}}",
|
||||||
|
"generalError": "فشل الرفع\n{{error}}",
|
||||||
|
"fileTypes": "الأنواع المدعومة: TXT، MD، DOCX، PDF، PPTX، RTF، ODT، EPUB، HTML، HTM، TEX، JSON، XML، YAML، YML، CSV، LOG، CONF، INI، PROPERTIES، SQL، BAT، SH، C، CPP، PY، JAVA، JS، TS، SWIFT، GO، RB، PHP، CSS، SCSS، LESS"
|
||||||
|
},
|
||||||
|
"documentManager": {
|
||||||
|
"title": "إدارة المستندات",
|
||||||
|
"scanButton": "مسح ضوئي",
|
||||||
|
"scanTooltip": "مسح المستندات ضوئيًا",
|
||||||
|
"uploadedTitle": "المستندات المرفوعة",
|
||||||
|
"uploadedDescription": "قائمة المستندات المرفوعة وحالاتها.",
|
||||||
|
"emptyTitle": "لا توجد مستندات",
|
||||||
|
"emptyDescription": "لا توجد مستندات مرفوعة بعد.",
|
||||||
|
"columns": {
|
||||||
|
"id": "المعرف",
|
||||||
|
"summary": "الملخص",
|
||||||
|
"status": "الحالة",
|
||||||
|
"length": "الطول",
|
||||||
|
"chunks": "الأجزاء",
|
||||||
|
"created": "تم الإنشاء",
|
||||||
|
"updated": "تم التحديث",
|
||||||
|
"metadata": "البيانات الوصفية"
|
||||||
|
},
|
||||||
|
"status": {
|
||||||
|
"completed": "مكتمل",
|
||||||
|
"processing": "قيد المعالجة",
|
||||||
|
"pending": "معلق",
|
||||||
|
"failed": "فشل"
|
||||||
|
},
|
||||||
|
"errors": {
|
||||||
|
"loadFailed": "فشل تحميل المستندات\n{{error}}",
|
||||||
|
"scanFailed": "فشل المسح الضوئي للمستندات\n{{error}}",
|
||||||
|
"scanProgressFailed": "فشل الحصول على تقدم المسح الضوئي\n{{error}}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"graphPanel": {
|
||||||
|
"sideBar": {
|
||||||
|
"settings": {
|
||||||
|
"settings": "الإعدادات",
|
||||||
|
"healthCheck": "فحص الحالة",
|
||||||
|
"showPropertyPanel": "إظهار لوحة الخصائص",
|
||||||
|
"showSearchBar": "إظهار شريط البحث",
|
||||||
|
"showNodeLabel": "إظهار تسمية العقدة",
|
||||||
|
"nodeDraggable": "العقدة قابلة للسحب",
|
||||||
|
"showEdgeLabel": "إظهار تسمية الحافة",
|
||||||
|
"hideUnselectedEdges": "إخفاء الحواف غير المحددة",
|
||||||
|
"edgeEvents": "أحداث الحافة",
|
||||||
|
"maxQueryDepth": "أقصى عمق للاستعلام",
|
||||||
|
"minDegree": "الدرجة الدنيا",
|
||||||
|
"maxLayoutIterations": "أقصى تكرارات التخطيط",
|
||||||
|
"depth": "العمق",
|
||||||
|
"degree": "الدرجة",
|
||||||
|
"apiKey": "مفتاح واجهة برمجة التطبيقات",
|
||||||
|
"enterYourAPIkey": "أدخل مفتاح واجهة برمجة التطبيقات الخاص بك",
|
||||||
|
"save": "حفظ",
|
||||||
|
"refreshLayout": "تحديث التخطيط"
|
||||||
|
},
|
||||||
|
"zoomControl": {
|
||||||
|
"zoomIn": "تكبير",
|
||||||
|
"zoomOut": "تصغير",
|
||||||
|
"resetZoom": "إعادة تعيين التكبير"
|
||||||
|
},
|
||||||
|
"layoutsControl": {
|
||||||
|
"startAnimation": "بدء حركة التخطيط",
|
||||||
|
"stopAnimation": "إيقاف حركة التخطيط",
|
||||||
|
"layoutGraph": "تخطيط الرسم البياني",
|
||||||
|
"layouts": {
|
||||||
|
"Circular": "دائري",
|
||||||
|
"Circlepack": "حزمة دائرية",
|
||||||
|
"Random": "عشوائي",
|
||||||
|
"Noverlaps": "بدون تداخل",
|
||||||
|
"Force Directed": "موجه بالقوة",
|
||||||
|
"Force Atlas": "أطلس القوة"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"fullScreenControl": {
|
||||||
|
"fullScreen": "شاشة كاملة",
|
||||||
|
"windowed": "نوافذ"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"statusIndicator": {
|
||||||
|
"connected": "متصل",
|
||||||
|
"disconnected": "غير متصل"
|
||||||
|
},
|
||||||
|
"statusCard": {
|
||||||
|
"unavailable": "معلومات الحالة غير متوفرة",
|
||||||
|
"storageInfo": "معلومات التخزين",
|
||||||
|
"workingDirectory": "دليل العمل",
|
||||||
|
"inputDirectory": "دليل الإدخال",
|
||||||
|
"llmConfig": "تكوين نموذج اللغة الكبير",
|
||||||
|
"llmBinding": "ربط نموذج اللغة الكبير",
|
||||||
|
"llmBindingHost": "مضيف ربط نموذج اللغة الكبير",
|
||||||
|
"llmModel": "نموذج اللغة الكبير",
|
||||||
|
"maxTokens": "أقصى عدد من الرموز",
|
||||||
|
"embeddingConfig": "تكوين التضمين",
|
||||||
|
"embeddingBinding": "ربط التضمين",
|
||||||
|
"embeddingBindingHost": "مضيف ربط التضمين",
|
||||||
|
"embeddingModel": "نموذج التضمين",
|
||||||
|
"storageConfig": "تكوين التخزين",
|
||||||
|
"kvStorage": "تخزين المفتاح-القيمة",
|
||||||
|
"docStatusStorage": "تخزين حالة المستند",
|
||||||
|
"graphStorage": "تخزين الرسم البياني",
|
||||||
|
"vectorStorage": "تخزين المتجهات"
|
||||||
|
},
|
||||||
|
"propertiesView": {
|
||||||
|
"node": {
|
||||||
|
"title": "عقدة",
|
||||||
|
"id": "المعرف",
|
||||||
|
"labels": "التسميات",
|
||||||
|
"degree": "الدرجة",
|
||||||
|
"properties": "الخصائص",
|
||||||
|
"relationships": "العلاقات",
|
||||||
|
"propertyNames": {
|
||||||
|
"description": "الوصف",
|
||||||
|
"entity_id": "الاسم",
|
||||||
|
"entity_type": "النوع",
|
||||||
|
"source_id": "معرف المصدر",
|
||||||
|
"Neighbour": "الجار"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"edge": {
|
||||||
|
"title": "علاقة",
|
||||||
|
"id": "المعرف",
|
||||||
|
"type": "النوع",
|
||||||
|
"source": "المصدر",
|
||||||
|
"target": "الهدف",
|
||||||
|
"properties": "الخصائص"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"search": {
|
||||||
|
"placeholder": "ابحث في العقد...",
|
||||||
|
"message": "و {{count}} آخرون"
|
||||||
|
},
|
||||||
|
"graphLabels": {
|
||||||
|
"selectTooltip": "حدد تسمية الاستعلام",
|
||||||
|
"noLabels": "لم يتم العثور على تسميات",
|
||||||
|
"label": "التسمية",
|
||||||
|
"placeholder": "ابحث في التسميات...",
|
||||||
|
"andOthers": "و {{count}} آخرون"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"retrievePanel": {
|
||||||
|
"chatMessage": {
|
||||||
|
"copyTooltip": "نسخ إلى الحافظة",
|
||||||
|
"copyError": "فشل نسخ النص إلى الحافظة"
|
||||||
|
},
|
||||||
|
"retrieval": {
|
||||||
|
"startPrompt": "ابدأ الاسترجاع بكتابة استفسارك أدناه",
|
||||||
|
"clear": "مسح",
|
||||||
|
"send": "إرسال",
|
||||||
|
"placeholder": "اكتب استفسارك...",
|
||||||
|
"error": "خطأ: فشل الحصول على الرد"
|
||||||
|
},
|
||||||
|
"querySettings": {
|
||||||
|
"parametersTitle": "المعلمات",
|
||||||
|
"parametersDescription": "تكوين معلمات الاستعلام الخاص بك",
|
||||||
|
"queryMode": "وضع الاستعلام",
|
||||||
|
"queryModeTooltip": "حدد استراتيجية الاسترجاع:\n• ساذج: بحث أساسي بدون تقنيات متقدمة\n• محلي: استرجاع معلومات يعتمد على السياق\n• عالمي: يستخدم قاعدة المعرفة العالمية\n• مختلط: يجمع بين الاسترجاع المحلي والعالمي\n• مزيج: يدمج شبكة المعرفة مع الاسترجاع المتجهي",
|
||||||
|
"queryModeOptions": {
|
||||||
|
"naive": "ساذج",
|
||||||
|
"local": "محلي",
|
||||||
|
"global": "عالمي",
|
||||||
|
"hybrid": "مختلط",
|
||||||
|
"mix": "مزيج"
|
||||||
|
},
|
||||||
|
"responseFormat": "تنسيق الرد",
|
||||||
|
"responseFormatTooltip": "يحدد تنسيق الرد. أمثلة:\n• فقرات متعددة\n• فقرة واحدة\n• نقاط نقطية",
|
||||||
|
"responseFormatOptions": {
|
||||||
|
"multipleParagraphs": "فقرات متعددة",
|
||||||
|
"singleParagraph": "فقرة واحدة",
|
||||||
|
"bulletPoints": "نقاط نقطية"
|
||||||
|
},
|
||||||
|
"topK": "أعلى K نتائج",
|
||||||
|
"topKTooltip": "عدد العناصر العلوية للاسترجاع. يمثل الكيانات في وضع 'محلي' والعلاقات في وضع 'عالمي'",
|
||||||
|
"topKPlaceholder": "عدد النتائج",
|
||||||
|
"maxTokensTextUnit": "أقصى عدد من الرموز لوحدة النص",
|
||||||
|
"maxTokensTextUnitTooltip": "الحد الأقصى لعدد الرموز المسموح به لكل جزء نصي مسترجع",
|
||||||
|
"maxTokensGlobalContext": "أقصى عدد من الرموز للسياق العالمي",
|
||||||
|
"maxTokensGlobalContextTooltip": "الحد الأقصى لعدد الرموز المخصص لأوصاف العلاقات في الاسترجاع العالمي",
|
||||||
|
"maxTokensLocalContext": "أقصى عدد من الرموز للسياق المحلي",
|
||||||
|
"maxTokensLocalContextTooltip": "الحد الأقصى لعدد الرموز المخصص لأوصاف الكيانات في الاسترجاع المحلي",
|
||||||
|
"historyTurns": "دورات التاريخ",
|
||||||
|
"historyTurnsTooltip": "عدد الدورات الكاملة للمحادثة (أزواج المستخدم-المساعد) التي يجب مراعاتها في سياق الرد",
|
||||||
|
"historyTurnsPlaceholder": "عدد دورات التاريخ",
|
||||||
|
"hlKeywords": "الكلمات المفتاحية عالية المستوى",
|
||||||
|
"hlKeywordsTooltip": "قائمة الكلمات المفتاحية عالية المستوى لإعطائها الأولوية في الاسترجاع. افصل بينها بفواصل",
|
||||||
|
"hlkeywordsPlaceHolder": "أدخل الكلمات المفتاحية",
|
||||||
|
"llKeywords": "الكلمات المفتاحية منخفضة المستوى",
|
||||||
|
"llKeywordsTooltip": "قائمة الكلمات المفتاحية منخفضة المستوى لتحسين تركيز الاسترجاع. افصل بينها بفواصل",
|
||||||
|
"onlyNeedContext": "تحتاج فقط إلى السياق",
|
||||||
|
"onlyNeedContextTooltip": "إذا كان صحيحًا، يتم إرجاع السياق المسترجع فقط دون إنشاء رد",
|
||||||
|
"onlyNeedPrompt": "تحتاج فقط إلى المطالبة",
|
||||||
|
"onlyNeedPromptTooltip": "إذا كان صحيحًا، يتم إرجاع المطالبة المولدة فقط دون إنتاج رد",
|
||||||
|
"streamResponse": "تدفق الرد",
|
||||||
|
"streamResponseTooltip": "إذا كان صحيحًا، يتيح إخراج التدفق للردود في الوقت الفعلي"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"apiSite": {
|
||||||
|
"loading": "جارٍ تحميل وثائق واجهة برمجة التطبيقات..."
|
||||||
|
}
|
||||||
|
}
|
239
lightrag_webui/src/locales/fr.json
Normal file
239
lightrag_webui/src/locales/fr.json
Normal file
@@ -0,0 +1,239 @@
|
|||||||
|
{
|
||||||
|
"settings": {
|
||||||
|
"language": "Langue",
|
||||||
|
"theme": "Thème",
|
||||||
|
"light": "Clair",
|
||||||
|
"dark": "Sombre",
|
||||||
|
"system": "Système"
|
||||||
|
},
|
||||||
|
"header": {
|
||||||
|
"documents": "Documents",
|
||||||
|
"knowledgeGraph": "Graphe de connaissances",
|
||||||
|
"retrieval": "Récupération",
|
||||||
|
"api": "API",
|
||||||
|
"projectRepository": "Référentiel du projet",
|
||||||
|
"themeToggle": {
|
||||||
|
"switchToLight": "Passer au thème clair",
|
||||||
|
"switchToDark": "Passer au thème sombre"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"documentPanel": {
|
||||||
|
"clearDocuments": {
|
||||||
|
"button": "Effacer",
|
||||||
|
"tooltip": "Effacer les documents",
|
||||||
|
"title": "Effacer les documents",
|
||||||
|
"confirm": "Voulez-vous vraiment effacer tous les documents ?",
|
||||||
|
"confirmButton": "OUI",
|
||||||
|
"success": "Documents effacés avec succès",
|
||||||
|
"failed": "Échec de l'effacement des documents :\n{{message}}",
|
||||||
|
"error": "Échec de l'effacement des documents :\n{{error}}"
|
||||||
|
},
|
||||||
|
"uploadDocuments": {
|
||||||
|
"button": "Télécharger",
|
||||||
|
"tooltip": "Télécharger des documents",
|
||||||
|
"title": "Télécharger des documents",
|
||||||
|
"description": "Glissez-déposez vos documents ici ou cliquez pour parcourir.",
|
||||||
|
"uploading": "Téléchargement de {{name}} : {{percent}}%",
|
||||||
|
"success": "Succès du téléchargement :\n{{name}} téléchargé avec succès",
|
||||||
|
"failed": "Échec du téléchargement :\n{{name}}\n{{message}}",
|
||||||
|
"error": "Échec du téléchargement :\n{{name}}\n{{error}}",
|
||||||
|
"generalError": "Échec du téléchargement\n{{error}}",
|
||||||
|
"fileTypes": "Types pris en charge : TXT, MD, DOCX, PDF, PPTX, RTF, ODT, EPUB, HTML, HTM, TEX, JSON, XML, YAML, YML, CSV, LOG, CONF, INI, PROPERTIES, SQL, BAT, SH, C, CPP, PY, JAVA, JS, TS, SWIFT, GO, RB, PHP, CSS, SCSS, LESS"
|
||||||
|
},
|
||||||
|
"documentManager": {
|
||||||
|
"title": "Gestion des documents",
|
||||||
|
"scanButton": "Scanner",
|
||||||
|
"scanTooltip": "Scanner les documents",
|
||||||
|
"uploadedTitle": "Documents téléchargés",
|
||||||
|
"uploadedDescription": "Liste des documents téléchargés et leurs statuts.",
|
||||||
|
"emptyTitle": "Aucun document",
|
||||||
|
"emptyDescription": "Il n'y a pas encore de documents téléchargés.",
|
||||||
|
"columns": {
|
||||||
|
"id": "ID",
|
||||||
|
"summary": "Résumé",
|
||||||
|
"status": "Statut",
|
||||||
|
"length": "Longueur",
|
||||||
|
"chunks": "Fragments",
|
||||||
|
"created": "Créé",
|
||||||
|
"updated": "Mis à jour",
|
||||||
|
"metadata": "Métadonnées"
|
||||||
|
},
|
||||||
|
"status": {
|
||||||
|
"completed": "Terminé",
|
||||||
|
"processing": "En traitement",
|
||||||
|
"pending": "En attente",
|
||||||
|
"failed": "Échoué"
|
||||||
|
},
|
||||||
|
"errors": {
|
||||||
|
"loadFailed": "Échec du chargement des documents\n{{error}}",
|
||||||
|
"scanFailed": "Échec de la numérisation des documents\n{{error}}",
|
||||||
|
"scanProgressFailed": "Échec de l'obtention de la progression de la numérisation\n{{error}}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"graphPanel": {
|
||||||
|
"sideBar": {
|
||||||
|
"settings": {
|
||||||
|
"settings": "Paramètres",
|
||||||
|
"healthCheck": "Vérification de l'état",
|
||||||
|
"showPropertyPanel": "Afficher le panneau des propriétés",
|
||||||
|
"showSearchBar": "Afficher la barre de recherche",
|
||||||
|
"showNodeLabel": "Afficher l'étiquette du nœud",
|
||||||
|
"nodeDraggable": "Nœud déplaçable",
|
||||||
|
"showEdgeLabel": "Afficher l'étiquette de l'arête",
|
||||||
|
"hideUnselectedEdges": "Masquer les arêtes non sélectionnées",
|
||||||
|
"edgeEvents": "Événements des arêtes",
|
||||||
|
"maxQueryDepth": "Profondeur maximale de la requête",
|
||||||
|
"minDegree": "Degré minimum",
|
||||||
|
"maxLayoutIterations": "Itérations maximales de mise en page",
|
||||||
|
"depth": "Profondeur",
|
||||||
|
"degree": "Degré",
|
||||||
|
"apiKey": "Clé API",
|
||||||
|
"enterYourAPIkey": "Entrez votre clé API",
|
||||||
|
"save": "Sauvegarder",
|
||||||
|
"refreshLayout": "Actualiser la mise en page"
|
||||||
|
},
|
||||||
|
"zoomControl": {
|
||||||
|
"zoomIn": "Zoom avant",
|
||||||
|
"zoomOut": "Zoom arrière",
|
||||||
|
"resetZoom": "Réinitialiser le zoom"
|
||||||
|
},
|
||||||
|
"layoutsControl": {
|
||||||
|
"startAnimation": "Démarrer l'animation de mise en page",
|
||||||
|
"stopAnimation": "Arrêter l'animation de mise en page",
|
||||||
|
"layoutGraph": "Mettre en page le graphe",
|
||||||
|
"layouts": {
|
||||||
|
"Circular": "Circulaire",
|
||||||
|
"Circlepack": "Paquet circulaire",
|
||||||
|
"Random": "Aléatoire",
|
||||||
|
"Noverlaps": "Sans chevauchement",
|
||||||
|
"Force Directed": "Dirigé par la force",
|
||||||
|
"Force Atlas": "Atlas de force"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"fullScreenControl": {
|
||||||
|
"fullScreen": "Plein écran",
|
||||||
|
"windowed": "Fenêtré"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"statusIndicator": {
|
||||||
|
"connected": "Connecté",
|
||||||
|
"disconnected": "Déconnecté"
|
||||||
|
},
|
||||||
|
"statusCard": {
|
||||||
|
"unavailable": "Informations sur l'état indisponibles",
|
||||||
|
"storageInfo": "Informations de stockage",
|
||||||
|
"workingDirectory": "Répertoire de travail",
|
||||||
|
"inputDirectory": "Répertoire d'entrée",
|
||||||
|
"llmConfig": "Configuration du modèle de langage",
|
||||||
|
"llmBinding": "Liaison du modèle de langage",
|
||||||
|
"llmBindingHost": "Hôte de liaison du modèle de langage",
|
||||||
|
"llmModel": "Modèle de langage",
|
||||||
|
"maxTokens": "Nombre maximum de jetons",
|
||||||
|
"embeddingConfig": "Configuration d'incorporation",
|
||||||
|
"embeddingBinding": "Liaison d'incorporation",
|
||||||
|
"embeddingBindingHost": "Hôte de liaison d'incorporation",
|
||||||
|
"embeddingModel": "Modèle d'incorporation",
|
||||||
|
"storageConfig": "Configuration de stockage",
|
||||||
|
"kvStorage": "Stockage clé-valeur",
|
||||||
|
"docStatusStorage": "Stockage de l'état des documents",
|
||||||
|
"graphStorage": "Stockage du graphe",
|
||||||
|
"vectorStorage": "Stockage vectoriel"
|
||||||
|
},
|
||||||
|
"propertiesView": {
|
||||||
|
"node": {
|
||||||
|
"title": "Nœud",
|
||||||
|
"id": "ID",
|
||||||
|
"labels": "Étiquettes",
|
||||||
|
"degree": "Degré",
|
||||||
|
"properties": "Propriétés",
|
||||||
|
"relationships": "Relations",
|
||||||
|
"propertyNames": {
|
||||||
|
"description": "Description",
|
||||||
|
"entity_id": "Nom",
|
||||||
|
"entity_type": "Type",
|
||||||
|
"source_id": "ID source",
|
||||||
|
"Neighbour": "Voisin"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"edge": {
|
||||||
|
"title": "Relation",
|
||||||
|
"id": "ID",
|
||||||
|
"type": "Type",
|
||||||
|
"source": "Source",
|
||||||
|
"target": "Cible",
|
||||||
|
"properties": "Propriétés"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"search": {
|
||||||
|
"placeholder": "Rechercher des nœuds...",
|
||||||
|
"message": "Et {{count}} autres"
|
||||||
|
},
|
||||||
|
"graphLabels": {
|
||||||
|
"selectTooltip": "Sélectionner l'étiquette de la requête",
|
||||||
|
"noLabels": "Aucune étiquette trouvée",
|
||||||
|
"label": "Étiquette",
|
||||||
|
"placeholder": "Rechercher des étiquettes...",
|
||||||
|
"andOthers": "Et {{count}} autres"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"retrievePanel": {
|
||||||
|
"chatMessage": {
|
||||||
|
"copyTooltip": "Copier dans le presse-papiers",
|
||||||
|
"copyError": "Échec de la copie du texte dans le presse-papiers"
|
||||||
|
},
|
||||||
|
"retrieval": {
|
||||||
|
"startPrompt": "Démarrez une récupération en tapant votre requête ci-dessous",
|
||||||
|
"clear": "Effacer",
|
||||||
|
"send": "Envoyer",
|
||||||
|
"placeholder": "Tapez votre requête...",
|
||||||
|
"error": "Erreur : Échec de l'obtention de la réponse"
|
||||||
|
},
|
||||||
|
"querySettings": {
|
||||||
|
"parametersTitle": "Paramètres",
|
||||||
|
"parametersDescription": "Configurez vos paramètres de requête",
|
||||||
|
"queryMode": "Mode de requête",
|
||||||
|
"queryModeTooltip": "Sélectionnez la stratégie de récupération :\n• Naïf : Recherche de base sans techniques avancées\n• Local : Récupération d'informations dépendante du contexte\n• Global : Utilise une base de connaissances globale\n• Hybride : Combine récupération locale et globale\n• Mixte : Intègre le graphe de connaissances avec la récupération vectorielle",
|
||||||
|
"queryModeOptions": {
|
||||||
|
"naive": "Naïf",
|
||||||
|
"local": "Local",
|
||||||
|
"global": "Global",
|
||||||
|
"hybrid": "Hybride",
|
||||||
|
"mix": "Mixte"
|
||||||
|
},
|
||||||
|
"responseFormat": "Format de réponse",
|
||||||
|
"responseFormatTooltip": "Définit le format de la réponse. Exemples :\n• Plusieurs paragraphes\n• Paragraphe unique\n• Points à puces",
|
||||||
|
"responseFormatOptions": {
|
||||||
|
"multipleParagraphs": "Plusieurs paragraphes",
|
||||||
|
"singleParagraph": "Paragraphe unique",
|
||||||
|
"bulletPoints": "Points à puces"
|
||||||
|
},
|
||||||
|
"topK": "Top K résultats",
|
||||||
|
"topKTooltip": "Nombre d'éléments supérieurs à récupérer. Représente les entités en mode 'local' et les relations en mode 'global'",
|
||||||
|
"topKPlaceholder": "Nombre de résultats",
|
||||||
|
"maxTokensTextUnit": "Nombre maximum de jetons pour l'unité de texte",
|
||||||
|
"maxTokensTextUnitTooltip": "Nombre maximum de jetons autorisés pour chaque fragment de texte récupéré",
|
||||||
|
"maxTokensGlobalContext": "Nombre maximum de jetons pour le contexte global",
|
||||||
|
"maxTokensGlobalContextTooltip": "Nombre maximum de jetons alloués pour les descriptions des relations dans la récupération globale",
|
||||||
|
"maxTokensLocalContext": "Nombre maximum de jetons pour le contexte local",
|
||||||
|
"maxTokensLocalContextTooltip": "Nombre maximum de jetons alloués pour les descriptions des entités dans la récupération locale",
|
||||||
|
"historyTurns": "Tours d'historique",
|
||||||
|
"historyTurnsTooltip": "Nombre de tours complets de conversation (paires utilisateur-assistant) à prendre en compte dans le contexte de la réponse",
|
||||||
|
"historyTurnsPlaceholder": "Nombre de tours d'historique",
|
||||||
|
"hlKeywords": "Mots-clés de haut niveau",
|
||||||
|
"hlKeywordsTooltip": "Liste de mots-clés de haut niveau à prioriser dans la récupération. Séparez par des virgules",
|
||||||
|
"hlkeywordsPlaceHolder": "Entrez les mots-clés",
|
||||||
|
"llKeywords": "Mots-clés de bas niveau",
|
||||||
|
"llKeywordsTooltip": "Liste de mots-clés de bas niveau pour affiner la focalisation de la récupération. Séparez par des virgules",
|
||||||
|
"onlyNeedContext": "Besoin uniquement du contexte",
|
||||||
|
"onlyNeedContextTooltip": "Si vrai, ne renvoie que le contexte récupéré sans générer de réponse",
|
||||||
|
"onlyNeedPrompt": "Besoin uniquement de l'invite",
|
||||||
|
"onlyNeedPromptTooltip": "Si vrai, ne renvoie que l'invite générée sans produire de réponse",
|
||||||
|
"streamResponse": "Réponse en flux",
|
||||||
|
"streamResponseTooltip": "Si vrai, active la sortie en flux pour des réponses en temps réel"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"apiSite": {
|
||||||
|
"loading": "Chargement de la documentation de l'API..."
|
||||||
|
}
|
||||||
|
}
|
Reference in New Issue
Block a user