Merge pull request #1148 from ParisNeo/main

Added  anthropic binding and few localization to other languages
This commit is contained in:
Daniel.y
2025-03-22 00:40:49 +08:00
committed by GitHub
3 changed files with 749 additions and 0 deletions

271
lightrag/llm/anthropic.py Normal file
View 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"},
}

View 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": "جارٍ تحميل وثائق واجهة برمجة التطبيقات..."
}
}

View 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..."
}
}