Merge pull request #1782 from HKUDS/rerank
Refactor the token control system
This commit is contained in:
commit
b44c8d46a5
71 changed files with 1235 additions and 756 deletions
28
README-zh.md
28
README-zh.md
|
|
@ -293,26 +293,19 @@ class QueryParam:
|
|||
top_k: int = int(os.getenv("TOP_K", "60"))
|
||||
"""Number of top items to retrieve. Represents entities in 'local' mode and relationships in 'global' mode."""
|
||||
|
||||
chunk_top_k: int = int(os.getenv("CHUNK_TOP_K", "5"))
|
||||
"""Number of text chunks to retrieve initially from vector search.
|
||||
chunk_top_k: int = int(os.getenv("CHUNK_TOP_K", "10"))
|
||||
"""Number of text chunks to retrieve initially from vector search and keep after reranking.
|
||||
If None, defaults to top_k value.
|
||||
"""
|
||||
|
||||
chunk_rerank_top_k: int = int(os.getenv("CHUNK_RERANK_TOP_K", "5"))
|
||||
"""Number of text chunks to keep after reranking.
|
||||
If None, keeps all chunks returned from initial retrieval.
|
||||
"""
|
||||
max_entity_tokens: int = int(os.getenv("MAX_ENTITY_TOKENS", "10000"))
|
||||
"""Maximum number of tokens allocated for entity context in unified token control system."""
|
||||
|
||||
max_token_for_text_unit: int = int(os.getenv("MAX_TOKEN_TEXT_CHUNK", "4000"))
|
||||
"""Maximum number of tokens allowed for each retrieved text chunk."""
|
||||
max_relation_tokens: int = int(os.getenv("MAX_RELATION_TOKENS", "10000"))
|
||||
"""Maximum number of tokens allocated for relationship context in unified token control system."""
|
||||
|
||||
max_token_for_global_context: int = int(
|
||||
os.getenv("MAX_TOKEN_RELATION_DESC", "4000")
|
||||
)
|
||||
"""Maximum number of tokens allocated for relationship descriptions in global retrieval."""
|
||||
|
||||
max_token_for_local_context: int = int(os.getenv("MAX_TOKEN_ENTITY_DESC", "4000"))
|
||||
"""Maximum number of tokens allocated for entity descriptions in local retrieval."""
|
||||
max_total_tokens: int = int(os.getenv("MAX_TOTAL_TOKENS", "32000"))
|
||||
"""Maximum total tokens budget for the entire query context (entities + relations + chunks + system prompt)."""
|
||||
|
||||
hl_keywords: list[str] = field(default_factory=list)
|
||||
"""List of high-level keywords to prioritize in retrieval."""
|
||||
|
|
@ -341,6 +334,11 @@ class QueryParam:
|
|||
"""User-provided prompt for the query.
|
||||
If proivded, this will be use instead of the default vaulue from prompt template.
|
||||
"""
|
||||
|
||||
enable_rerank: bool = True
|
||||
"""Enable reranking for retrieved text chunks. If True but no rerank model is configured, a warning will be issued.
|
||||
Default is True to enable reranking when rerank model is available.
|
||||
"""
|
||||
```
|
||||
|
||||
> top_k的默认值可以通过环境变量TOP_K更改。
|
||||
|
|
|
|||
28
README.md
28
README.md
|
|
@ -300,26 +300,19 @@ class QueryParam:
|
|||
top_k: int = int(os.getenv("TOP_K", "60"))
|
||||
"""Number of top items to retrieve. Represents entities in 'local' mode and relationships in 'global' mode."""
|
||||
|
||||
chunk_top_k: int = int(os.getenv("CHUNK_TOP_K", "5"))
|
||||
"""Number of text chunks to retrieve initially from vector search.
|
||||
chunk_top_k: int = int(os.getenv("CHUNK_TOP_K", "10"))
|
||||
"""Number of text chunks to retrieve initially from vector search and keep after reranking.
|
||||
If None, defaults to top_k value.
|
||||
"""
|
||||
|
||||
chunk_rerank_top_k: int = int(os.getenv("CHUNK_RERANK_TOP_K", "5"))
|
||||
"""Number of text chunks to keep after reranking.
|
||||
If None, keeps all chunks returned from initial retrieval.
|
||||
"""
|
||||
max_entity_tokens: int = int(os.getenv("MAX_ENTITY_TOKENS", "10000"))
|
||||
"""Maximum number of tokens allocated for entity context in unified token control system."""
|
||||
|
||||
max_token_for_text_unit: int = int(os.getenv("MAX_TOKEN_TEXT_CHUNK", "4000"))
|
||||
"""Maximum number of tokens allowed for each retrieved text chunk."""
|
||||
max_relation_tokens: int = int(os.getenv("MAX_RELATION_TOKENS", "10000"))
|
||||
"""Maximum number of tokens allocated for relationship context in unified token control system."""
|
||||
|
||||
max_token_for_global_context: int = int(
|
||||
os.getenv("MAX_TOKEN_RELATION_DESC", "4000")
|
||||
)
|
||||
"""Maximum number of tokens allocated for relationship descriptions in global retrieval."""
|
||||
|
||||
max_token_for_local_context: int = int(os.getenv("MAX_TOKEN_ENTITY_DESC", "4000"))
|
||||
"""Maximum number of tokens allocated for entity descriptions in local retrieval."""
|
||||
max_total_tokens: int = int(os.getenv("MAX_TOTAL_TOKENS", "32000"))
|
||||
"""Maximum total tokens budget for the entire query context (entities + relations + chunks + system prompt)."""
|
||||
|
||||
conversation_history: list[dict[str, str]] = field(default_factory=list)
|
||||
"""Stores past conversation history to maintain context.
|
||||
|
|
@ -342,6 +335,11 @@ class QueryParam:
|
|||
"""User-provided prompt for the query.
|
||||
If proivded, this will be use instead of the default vaulue from prompt template.
|
||||
"""
|
||||
|
||||
enable_rerank: bool = True
|
||||
"""Enable reranking for retrieved text chunks. If True but no rerank model is configured, a warning will be issued.
|
||||
Default is True to enable reranking when rerank model is available.
|
||||
"""
|
||||
```
|
||||
|
||||
> default value of Top_k can be change by environment variables TOP_K.
|
||||
|
|
|
|||
|
|
@ -1,36 +1,24 @@
|
|||
# Rerank Integration in LightRAG
|
||||
# Rerank Integration Guide
|
||||
|
||||
This document explains how to configure and use the rerank functionality in LightRAG to improve retrieval quality.
|
||||
LightRAG supports reranking functionality to improve retrieval quality by re-ordering documents based on their relevance to the query. Reranking is now controlled per query via the `enable_rerank` parameter (default: True).
|
||||
|
||||
## Overview
|
||||
|
||||
Reranking is an optional feature that improves the quality of retrieved documents by re-ordering them based on their relevance to the query. This is particularly useful when you want higher precision in document retrieval across all query modes (naive, local, global, hybrid, mix).
|
||||
|
||||
## Architecture
|
||||
|
||||
The rerank integration follows a simplified design pattern:
|
||||
|
||||
- **Single Function Configuration**: All rerank settings (model, API keys, top_k, etc.) are contained within the rerank function
|
||||
- **Async Processing**: Non-blocking rerank operations
|
||||
- **Error Handling**: Graceful fallback to original results
|
||||
- **Optional Feature**: Can be enabled/disabled via configuration
|
||||
- **Code Reuse**: Single generic implementation for Jina/Cohere compatible APIs
|
||||
|
||||
## Configuration
|
||||
## Quick Start
|
||||
|
||||
### Environment Variables
|
||||
|
||||
Set this variable in your `.env` file or environment:
|
||||
Set these variables in your `.env` file or environment for rerank model configuration:
|
||||
|
||||
```bash
|
||||
# Enable/disable reranking
|
||||
ENABLE_RERANK=True
|
||||
# Rerank model configuration (required when enable_rerank=True in queries)
|
||||
RERANK_MODEL=BAAI/bge-reranker-v2-m3
|
||||
RERANK_BINDING_HOST=https://api.your-provider.com/v1/rerank
|
||||
RERANK_BINDING_API_KEY=your_api_key_here
|
||||
```
|
||||
|
||||
### Programmatic Configuration
|
||||
|
||||
```python
|
||||
from lightrag import LightRAG
|
||||
from lightrag import LightRAG, QueryParam
|
||||
from lightrag.rerank import custom_rerank, RerankModel
|
||||
|
||||
# Method 1: Using a custom rerank function with all settings included
|
||||
|
|
@ -49,8 +37,19 @@ rag = LightRAG(
|
|||
working_dir="./rag_storage",
|
||||
llm_model_func=your_llm_func,
|
||||
embedding_func=your_embedding_func,
|
||||
enable_rerank=True,
|
||||
rerank_model_func=my_rerank_func,
|
||||
rerank_model_func=my_rerank_func, # Configure rerank function
|
||||
)
|
||||
|
||||
# Query with rerank enabled (default)
|
||||
result = await rag.aquery(
|
||||
"your query",
|
||||
param=QueryParam(enable_rerank=True) # Control rerank per query
|
||||
)
|
||||
|
||||
# Query with rerank disabled
|
||||
result = await rag.aquery(
|
||||
"your query",
|
||||
param=QueryParam(enable_rerank=False)
|
||||
)
|
||||
|
||||
# Method 2: Using RerankModel wrapper
|
||||
|
|
@ -67,9 +66,17 @@ rag = LightRAG(
|
|||
working_dir="./rag_storage",
|
||||
llm_model_func=your_llm_func,
|
||||
embedding_func=your_embedding_func,
|
||||
enable_rerank=True,
|
||||
rerank_model_func=rerank_model.rerank,
|
||||
)
|
||||
|
||||
# Control rerank per query
|
||||
result = await rag.aquery(
|
||||
"your query",
|
||||
param=QueryParam(
|
||||
enable_rerank=True, # Enable rerank for this query
|
||||
chunk_top_k=5 # Number of chunks to keep after reranking
|
||||
)
|
||||
)
|
||||
```
|
||||
|
||||
## Supported Providers
|
||||
|
|
@ -164,7 +171,6 @@ async def main():
|
|||
working_dir="./rag_storage",
|
||||
llm_model_func=gpt_4o_mini_complete,
|
||||
embedding_func=openai_embedding,
|
||||
enable_rerank=True,
|
||||
rerank_model_func=my_rerank_func,
|
||||
)
|
||||
|
||||
|
|
@ -180,7 +186,7 @@ async def main():
|
|||
# Query with rerank (automatically applied)
|
||||
result = await rag.aquery(
|
||||
"Your question here",
|
||||
param=QueryParam(mode="hybrid", top_k=5) # This top_k is passed to rerank function
|
||||
param=QueryParam(enable_rerank=True) # This top_k is passed to rerank function
|
||||
)
|
||||
|
||||
print(result)
|
||||
|
|
|
|||
148
env.example
148
env.example
|
|
@ -1,6 +1,8 @@
|
|||
### This is sample file of .env
|
||||
|
||||
###########################
|
||||
### Server Configuration
|
||||
###########################
|
||||
HOST=0.0.0.0
|
||||
PORT=9621
|
||||
WEBUI_TITLE='My Graph KB'
|
||||
|
|
@ -9,29 +11,17 @@ OLLAMA_EMULATING_MODEL_TAG=latest
|
|||
# WORKERS=2
|
||||
# CORS_ORIGINS=http://localhost:3000,http://localhost:8080
|
||||
|
||||
### Login Configuration
|
||||
# AUTH_ACCOUNTS='admin:admin123,user1:pass456'
|
||||
# TOKEN_SECRET=Your-Key-For-LightRAG-API-Server
|
||||
# TOKEN_EXPIRE_HOURS=48
|
||||
# GUEST_TOKEN_EXPIRE_HOURS=24
|
||||
# JWT_ALGORITHM=HS256
|
||||
|
||||
### API-Key to access LightRAG Server API
|
||||
# LIGHTRAG_API_KEY=your-secure-api-key-here
|
||||
# WHITELIST_PATHS=/health,/api/*
|
||||
|
||||
### Optional SSL Configuration
|
||||
# SSL=true
|
||||
# SSL_CERTFILE=/path/to/cert.pem
|
||||
# SSL_KEYFILE=/path/to/key.pem
|
||||
|
||||
### Directory Configuration (defaults to current working directory)
|
||||
### Should not be set if deploy by docker (Set by Dockerfile instead of .env)
|
||||
### Default value is ./inputs and ./rag_storage
|
||||
# INPUT_DIR=<absolute_path_for_doc_input_dir>
|
||||
# WORKING_DIR=<absolute_path_for_working_dir>
|
||||
|
||||
### Max nodes return from grap retrieval
|
||||
### Max nodes return from grap retrieval in webui
|
||||
# MAX_GRAPH_NODES=1000
|
||||
|
||||
### Logging level
|
||||
|
|
@ -42,65 +32,97 @@ OLLAMA_EMULATING_MODEL_TAG=latest
|
|||
### Logfile location (defaults to current working directory)
|
||||
# LOG_DIR=/path/to/log/directory
|
||||
|
||||
### RAG Configuration
|
||||
### Chunk size for document splitting, 500~1500 is recommended
|
||||
# CHUNK_SIZE=1200
|
||||
# CHUNK_OVERLAP_SIZE=100
|
||||
#####################################
|
||||
### Login and API-Key Configuration
|
||||
#####################################
|
||||
# AUTH_ACCOUNTS='admin:admin123,user1:pass456'
|
||||
# TOKEN_SECRET=Your-Key-For-LightRAG-API-Server
|
||||
# TOKEN_EXPIRE_HOURS=48
|
||||
# GUEST_TOKEN_EXPIRE_HOURS=24
|
||||
# JWT_ALGORITHM=HS256
|
||||
|
||||
### RAG Query Configuration
|
||||
### API-Key to access LightRAG Server API
|
||||
# LIGHTRAG_API_KEY=your-secure-api-key-here
|
||||
# WHITELIST_PATHS=/health,/api/*
|
||||
|
||||
########################
|
||||
### Query Configuration
|
||||
########################
|
||||
# LLM responde cache for query (Not valid for streaming response
|
||||
ENABLE_LLM_CACHE=true
|
||||
# HISTORY_TURNS=3
|
||||
# MAX_TOKEN_TEXT_CHUNK=6000
|
||||
# MAX_TOKEN_RELATION_DESC=4000
|
||||
# MAX_TOKEN_ENTITY_DESC=4000
|
||||
# COSINE_THRESHOLD=0.2
|
||||
### Number of entities or relations to retrieve from KG
|
||||
# TOP_K=60
|
||||
### Number of text chunks to retrieve initially from vector search
|
||||
# CHUNK_TOP_K=5
|
||||
### Number of entities or relations retrieved from KG
|
||||
# TOP_K=40
|
||||
### Maxmium number or chunks plan to send to LLM
|
||||
# CHUNK_TOP_K=10
|
||||
### control the actual enties send to LLM
|
||||
# MAX_ENTITY_TOKENS=10000
|
||||
### control the actual relations send to LLM
|
||||
# MAX_RELATION_TOKENS=10000
|
||||
### control the maximum tokens send to LLM (include entities, raltions and chunks)
|
||||
# MAX_TOTAL_TOKENS=32000
|
||||
### maxumium related chunks grab from single entity or relations
|
||||
# RELATED_CHUNK_NUMBER=10
|
||||
|
||||
### Rerank Configuration
|
||||
# ENABLE_RERANK=False
|
||||
### Number of text chunks to keep after reranking (should be <= CHUNK_TOP_K)
|
||||
# CHUNK_RERANK_TOP_K=5
|
||||
### Rerank model configuration (required when ENABLE_RERANK=True)
|
||||
### Reranker configuration (Set ENABLE_RERANK to true in reranking model is configed)
|
||||
ENABLE_RERANK=False
|
||||
# RERANK_MODEL=BAAI/bge-reranker-v2-m3
|
||||
# RERANK_BINDING_HOST=https://api.your-rerank-provider.com/v1/rerank
|
||||
# RERANK_BINDING_API_KEY=your_rerank_api_key_here
|
||||
|
||||
### Entity and relation summarization configuration
|
||||
########################################
|
||||
### Document processing configuration
|
||||
########################################
|
||||
### Language: English, Chinese, French, German ...
|
||||
SUMMARY_LANGUAGE=English
|
||||
ENABLE_LLM_CACHE_FOR_EXTRACT=true
|
||||
### MAX_TOKENS: max tokens send to LLM for entity relation summaries (less than context size of the model)
|
||||
MAX_TOKENS=32000
|
||||
### Chunk size for document splitting, 500~1500 is recommended
|
||||
# CHUNK_SIZE=1200
|
||||
# CHUNK_OVERLAP_SIZE=100
|
||||
### Entity and relation summarization configuration
|
||||
### Number of duplicated entities/edges to trigger LLM re-summary on merge ( at least 3 is recommented)
|
||||
# FORCE_LLM_SUMMARY_ON_MERGE=6
|
||||
# FORCE_LLM_SUMMARY_ON_MERGE=4
|
||||
### Maximum number of entity extraction attempts for ambiguous content
|
||||
# MAX_GLEANING=1
|
||||
|
||||
### Number of parallel processing documents(Less than MAX_ASYNC/2 is recommended)
|
||||
# MAX_PARALLEL_INSERT=2
|
||||
###############################
|
||||
### Concurrency Configuration
|
||||
###############################
|
||||
### Max concurrency requests of LLM (for both query and document processing)
|
||||
MAX_ASYNC=4
|
||||
### Number of parallel processing documents(between 2~10, MAX_ASYNC/4 is recommended)
|
||||
MAX_PARALLEL_INSERT=2
|
||||
### Max concurrency requests for Embedding
|
||||
# EMBEDDING_FUNC_MAX_ASYNC=8
|
||||
### Num of chunks send to Embedding in single request
|
||||
# EMBEDDING_BATCH_NUM=10
|
||||
|
||||
#######################
|
||||
### LLM Configuration
|
||||
ENABLE_LLM_CACHE=true
|
||||
ENABLE_LLM_CACHE_FOR_EXTRACT=true
|
||||
#######################
|
||||
### Time out in seconds for LLM, None for infinite timeout
|
||||
TIMEOUT=240
|
||||
### Some models like o1-mini require temperature to be set to 1
|
||||
TEMPERATURE=0
|
||||
### Max concurrency requests of LLM
|
||||
MAX_ASYNC=4
|
||||
### MAX_TOKENS: max tokens send to LLM for entity relation summaries (less than context size of the model)
|
||||
MAX_TOKENS=32000
|
||||
### LLM Binding type: openai, ollama, lollms, azure_openai
|
||||
LLM_BINDING=openai
|
||||
LLM_MODEL=gpt-4o
|
||||
LLM_BINDING_HOST=https://api.openai.com/v1
|
||||
LLM_BINDING_API_KEY=your_api_key
|
||||
|
||||
### Set as num_ctx option for Ollama LLM
|
||||
# OLLAMA_NUM_CTX=32768
|
||||
|
||||
### Optional for Azure
|
||||
# AZURE_OPENAI_API_VERSION=2024-08-01-preview
|
||||
# AZURE_OPENAI_DEPLOYMENT=gpt-4o
|
||||
### set as num_ctx option for Ollama LLM
|
||||
# OLLAMA_NUM_CTX=32768
|
||||
|
||||
### Embedding Configuration
|
||||
####################################################################################
|
||||
### Embedding Configuration (Should not be changed after the first file processed)
|
||||
####################################################################################
|
||||
### Embedding Binding type: openai, ollama, lollms, azure_openai
|
||||
EMBEDDING_BINDING=ollama
|
||||
EMBEDDING_MODEL=bge-m3:latest
|
||||
|
|
@ -108,51 +130,53 @@ EMBEDDING_DIM=1024
|
|||
EMBEDDING_BINDING_API_KEY=your_api_key
|
||||
# If the embedding service is deployed within the same Docker stack, use host.docker.internal instead of localhost
|
||||
EMBEDDING_BINDING_HOST=http://localhost:11434
|
||||
### Num of chunks send to Embedding in single request
|
||||
# EMBEDDING_BATCH_NUM=10
|
||||
### Max concurrency requests for Embedding
|
||||
# EMBEDDING_FUNC_MAX_ASYNC=8
|
||||
### Maximum tokens sent to Embedding for each chunk (no longer in use?)
|
||||
# MAX_EMBED_TOKENS=8192
|
||||
|
||||
### Optional for Azure
|
||||
# AZURE_EMBEDDING_DEPLOYMENT=text-embedding-3-large
|
||||
# AZURE_EMBEDDING_API_VERSION=2023-05-15
|
||||
# AZURE_EMBEDDING_ENDPOINT=your_endpoint
|
||||
# AZURE_EMBEDDING_API_KEY=your_api_key
|
||||
|
||||
###########################
|
||||
############################
|
||||
### Data storage selection
|
||||
###########################
|
||||
### In-memory database with local file persistence(Recommended for small scale deployment)
|
||||
############################
|
||||
### Default storage (Recommended for small scale deployment)
|
||||
# LIGHTRAG_KV_STORAGE=JsonKVStorage
|
||||
# LIGHTRAG_DOC_STATUS_STORAGE=JsonDocStatusStorage
|
||||
# LIGHTRAG_GRAPH_STORAGE=NetworkXStorage
|
||||
# LIGHTRAG_VECTOR_STORAGE=NanoVectorDBStorage
|
||||
|
||||
### Redis Storage (Recommended for production deployment)
|
||||
# LIGHTRAG_KV_STORAGE=RedisKVStorage
|
||||
# LIGHTRAG_DOC_STATUS_STORAGE=RedisDocStatusStorage
|
||||
|
||||
### Vector Storage (Recommended for production deployment)
|
||||
# LIGHTRAG_VECTOR_STORAGE=MilvusVectorDBStorage
|
||||
# LIGHTRAG_VECTOR_STORAGE=QdrantVectorDBStorage
|
||||
# LIGHTRAG_VECTOR_STORAGE=FaissVectorDBStorage
|
||||
|
||||
### Graph Storage (Recommended for production deployment)
|
||||
# LIGHTRAG_GRAPH_STORAGE=Neo4JStorage
|
||||
# LIGHTRAG_GRAPH_STORAGE=MemgraphStorage
|
||||
|
||||
### PostgreSQL
|
||||
# LIGHTRAG_KV_STORAGE=PGKVStorage
|
||||
# LIGHTRAG_DOC_STATUS_STORAGE=PGDocStatusStorage
|
||||
# LIGHTRAG_GRAPH_STORAGE=PGGraphStorage
|
||||
# LIGHTRAG_VECTOR_STORAGE=PGVectorStorage
|
||||
|
||||
### MongoDB (Vector storage only available on Atlas Cloud)
|
||||
# LIGHTRAG_KV_STORAGE=MongoKVStorage
|
||||
# LIGHTRAG_DOC_STATUS_STORAGE=MongoDocStatusStorage
|
||||
# LIGHTRAG_GRAPH_STORAGE=MongoGraphStorage
|
||||
# LIGHTRAG_VECTOR_STORAGE=MongoVectorDBStorage
|
||||
### Redis Storage (Recommended for production deployment)
|
||||
# LIGHTRAG_KV_STORAGE=RedisKVStorage
|
||||
# LIGHTRAG_DOC_STATUS_STORAGE=RedisDocStatusStorage
|
||||
### Vector Storage (Recommended for production deployment)
|
||||
# LIGHTRAG_VECTOR_STORAGE=MilvusVectorDBStorage
|
||||
# LIGHTRAG_VECTOR_STORAGE=QdrantVectorDBStorage
|
||||
### Graph Storage (Recommended for production deployment)
|
||||
# LIGHTRAG_GRAPH_STORAGE=Neo4JStorage
|
||||
# LIGHTRAG_GRAPH_STORAGE=MemgraphStorage
|
||||
|
||||
####################################################################
|
||||
### Default workspace for all storage types
|
||||
### For the purpose of isolation of data for each LightRAG instance
|
||||
### Valid characters: a-z, A-Z, 0-9, and _
|
||||
### WORKSPACE setting workspace name for all storage types
|
||||
### in the purpose of isolating data from LightRAG instances.
|
||||
### Valid workspace name constraints: a-z, A-Z, 0-9, and _
|
||||
####################################################################
|
||||
# WORKSPACE=space1
|
||||
|
||||
|
|
|
|||
|
|
@ -9,7 +9,11 @@ Configuration Required:
|
|||
2. Set your embedding API key and base URL in embedding_func()
|
||||
3. Set your rerank API key and base URL in the rerank configuration
|
||||
4. Or use environment variables (.env file):
|
||||
- ENABLE_RERANK=True
|
||||
- RERANK_MODEL=your_rerank_model
|
||||
- RERANK_BINDING_HOST=your_rerank_endpoint
|
||||
- RERANK_BINDING_API_KEY=your_rerank_api_key
|
||||
|
||||
Note: Rerank is now controlled per query via the 'enable_rerank' parameter (default: True)
|
||||
"""
|
||||
|
||||
import asyncio
|
||||
|
|
@ -83,8 +87,7 @@ async def create_rag_with_rerank():
|
|||
max_token_size=8192,
|
||||
func=embedding_func,
|
||||
),
|
||||
# Simplified Rerank Configuration
|
||||
enable_rerank=True,
|
||||
# Rerank Configuration - provide the rerank function
|
||||
rerank_model_func=my_rerank_func,
|
||||
)
|
||||
|
||||
|
|
@ -120,7 +123,6 @@ async def create_rag_with_rerank_model():
|
|||
max_token_size=8192,
|
||||
func=embedding_func,
|
||||
),
|
||||
enable_rerank=True,
|
||||
rerank_model_func=rerank_model.rerank,
|
||||
)
|
||||
|
||||
|
|
@ -130,9 +132,9 @@ async def create_rag_with_rerank_model():
|
|||
return rag
|
||||
|
||||
|
||||
async def test_rerank_with_different_topk():
|
||||
async def test_rerank_with_different_settings():
|
||||
"""
|
||||
Test rerank functionality with different top_k settings
|
||||
Test rerank functionality with different enable_rerank settings
|
||||
"""
|
||||
print("🚀 Setting up LightRAG with Rerank functionality...")
|
||||
|
||||
|
|
@ -154,16 +156,41 @@ async def test_rerank_with_different_topk():
|
|||
print(f"\n🔍 Testing query: '{query}'")
|
||||
print("=" * 80)
|
||||
|
||||
# Test different top_k values to show parameter priority
|
||||
top_k_values = [2, 5, 10]
|
||||
# Test with rerank enabled (default)
|
||||
print("\n📊 Testing with enable_rerank=True (default):")
|
||||
result_with_rerank = await rag.aquery(
|
||||
query,
|
||||
param=QueryParam(
|
||||
mode="naive",
|
||||
top_k=10,
|
||||
chunk_top_k=5,
|
||||
enable_rerank=True, # Explicitly enable rerank
|
||||
),
|
||||
)
|
||||
print(f" Result length: {len(result_with_rerank)} characters")
|
||||
print(f" Preview: {result_with_rerank[:100]}...")
|
||||
|
||||
for top_k in top_k_values:
|
||||
print(f"\n📊 Testing with QueryParam(top_k={top_k}):")
|
||||
# Test with rerank disabled
|
||||
print("\n📊 Testing with enable_rerank=False:")
|
||||
result_without_rerank = await rag.aquery(
|
||||
query,
|
||||
param=QueryParam(
|
||||
mode="naive",
|
||||
top_k=10,
|
||||
chunk_top_k=5,
|
||||
enable_rerank=False, # Disable rerank
|
||||
),
|
||||
)
|
||||
print(f" Result length: {len(result_without_rerank)} characters")
|
||||
print(f" Preview: {result_without_rerank[:100]}...")
|
||||
|
||||
# Test naive mode with specific top_k
|
||||
result = await rag.aquery(query, param=QueryParam(mode="naive", top_k=top_k))
|
||||
print(f" Result length: {len(result)} characters")
|
||||
print(f" Preview: {result[:100]}...")
|
||||
# Test with default settings (enable_rerank defaults to True)
|
||||
print("\n📊 Testing with default settings (enable_rerank defaults to True):")
|
||||
result_default = await rag.aquery(
|
||||
query, param=QueryParam(mode="naive", top_k=10, chunk_top_k=5)
|
||||
)
|
||||
print(f" Result length: {len(result_default)} characters")
|
||||
print(f" Preview: {result_default[:100]}...")
|
||||
|
||||
|
||||
async def test_direct_rerank():
|
||||
|
|
@ -209,17 +236,21 @@ async def main():
|
|||
print("=" * 60)
|
||||
|
||||
try:
|
||||
# Test rerank with different top_k values
|
||||
await test_rerank_with_different_topk()
|
||||
# Test rerank with different enable_rerank settings
|
||||
await test_rerank_with_different_settings()
|
||||
|
||||
# Test direct rerank
|
||||
await test_direct_rerank()
|
||||
|
||||
print("\n✅ Example completed successfully!")
|
||||
print("\n💡 Key Points:")
|
||||
print(" ✓ All rerank configurations are contained within rerank_model_func")
|
||||
print(" ✓ Rerank improves document relevance ordering")
|
||||
print(" ✓ Configure API keys within your rerank function")
|
||||
print(" ✓ Rerank is now controlled per query via 'enable_rerank' parameter")
|
||||
print(" ✓ Default value for enable_rerank is True")
|
||||
print(" ✓ Rerank function is configured at LightRAG initialization")
|
||||
print(" ✓ Per-query enable_rerank setting overrides default behavior")
|
||||
print(
|
||||
" ✓ If enable_rerank=True but no rerank model is configured, a warning is issued"
|
||||
)
|
||||
print(" ✓ Monitor API usage and costs when using rerank services")
|
||||
|
||||
except Exception as e:
|
||||
|
|
|
|||
|
|
@ -11,6 +11,14 @@ from lightrag.utils import get_env_value
|
|||
from lightrag.constants import (
|
||||
DEFAULT_WOKERS,
|
||||
DEFAULT_TIMEOUT,
|
||||
DEFAULT_TOP_K,
|
||||
DEFAULT_CHUNK_TOP_K,
|
||||
DEFAULT_HISTORY_TURNS,
|
||||
DEFAULT_MAX_ENTITY_TOKENS,
|
||||
DEFAULT_MAX_RELATION_TOKENS,
|
||||
DEFAULT_MAX_TOTAL_TOKENS,
|
||||
DEFAULT_COSINE_THRESHOLD,
|
||||
DEFAULT_RELATED_CHUNK_NUMBER,
|
||||
)
|
||||
|
||||
# use the .env that is inside the current folder
|
||||
|
|
@ -151,45 +159,6 @@ def parse_args() -> argparse.Namespace:
|
|||
help="Path to SSL private key file (required if --ssl is enabled)",
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
"--history-turns",
|
||||
type=int,
|
||||
default=get_env_value("HISTORY_TURNS", 3, int),
|
||||
help="Number of conversation history turns to include (default: from env or 3)",
|
||||
)
|
||||
|
||||
# Search parameters
|
||||
parser.add_argument(
|
||||
"--top-k",
|
||||
type=int,
|
||||
default=get_env_value("TOP_K", 60, int),
|
||||
help="Number of most similar results to return (default: from env or 60)",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--chunk-top-k",
|
||||
type=int,
|
||||
default=get_env_value("CHUNK_TOP_K", 15, int),
|
||||
help="Number of text chunks to retrieve initially from vector search (default: from env or 15)",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--chunk-rerank-top-k",
|
||||
type=int,
|
||||
default=get_env_value("CHUNK_RERANK_TOP_K", 5, int),
|
||||
help="Number of text chunks to keep after reranking (default: from env or 5)",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--enable-rerank",
|
||||
action="store_true",
|
||||
default=get_env_value("ENABLE_RERANK", False, bool),
|
||||
help="Enable rerank functionality (default: from env or False)",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--cosine-threshold",
|
||||
type=float,
|
||||
default=get_env_value("COSINE_THRESHOLD", 0.2, float),
|
||||
help="Cosine similarity threshold (default: from env or 0.4)",
|
||||
)
|
||||
|
||||
# Ollama model name
|
||||
parser.add_argument(
|
||||
"--simulated-model-name",
|
||||
|
|
@ -321,6 +290,26 @@ def parse_args() -> argparse.Namespace:
|
|||
args.rerank_binding_host = get_env_value("RERANK_BINDING_HOST", None)
|
||||
args.rerank_binding_api_key = get_env_value("RERANK_BINDING_API_KEY", None)
|
||||
|
||||
# Query configuration
|
||||
args.history_turns = get_env_value("HISTORY_TURNS", DEFAULT_HISTORY_TURNS, int)
|
||||
args.top_k = get_env_value("TOP_K", DEFAULT_TOP_K, int)
|
||||
args.chunk_top_k = get_env_value("CHUNK_TOP_K", DEFAULT_CHUNK_TOP_K, int)
|
||||
args.max_entity_tokens = get_env_value(
|
||||
"MAX_ENTITY_TOKENS", DEFAULT_MAX_ENTITY_TOKENS, int
|
||||
)
|
||||
args.max_relation_tokens = get_env_value(
|
||||
"MAX_RELATION_TOKENS", DEFAULT_MAX_RELATION_TOKENS, int
|
||||
)
|
||||
args.max_total_tokens = get_env_value(
|
||||
"MAX_TOTAL_TOKENS", DEFAULT_MAX_TOTAL_TOKENS, int
|
||||
)
|
||||
args.cosine_threshold = get_env_value(
|
||||
"COSINE_THRESHOLD", DEFAULT_COSINE_THRESHOLD, float
|
||||
)
|
||||
args.related_chunk_number = get_env_value(
|
||||
"RELATED_CHUNK_NUMBER", DEFAULT_RELATED_CHUNK_NUMBER, int
|
||||
)
|
||||
|
||||
ollama_server_infos.LIGHTRAG_MODEL = args.simulated_model_name
|
||||
|
||||
return args
|
||||
|
|
|
|||
|
|
@ -292,9 +292,9 @@ def create_app(args):
|
|||
),
|
||||
)
|
||||
|
||||
# Configure rerank function if enabled
|
||||
# Configure rerank function if model and API are configured
|
||||
rerank_model_func = None
|
||||
if args.enable_rerank and args.rerank_binding_api_key and args.rerank_binding_host:
|
||||
if args.rerank_binding_api_key and args.rerank_binding_host:
|
||||
from lightrag.rerank import custom_rerank
|
||||
|
||||
async def server_rerank_func(
|
||||
|
|
@ -312,10 +312,12 @@ def create_app(args):
|
|||
)
|
||||
|
||||
rerank_model_func = server_rerank_func
|
||||
logger.info(f"Rerank enabled with model: {args.rerank_model}")
|
||||
elif args.enable_rerank:
|
||||
logger.warning(
|
||||
"Rerank enabled but RERANK_BINDING_API_KEY or RERANK_BINDING_HOST not configured. Rerank will be disabled."
|
||||
logger.info(
|
||||
f"Rerank model configured: {args.rerank_model} (can be enabled per query)"
|
||||
)
|
||||
else:
|
||||
logger.info(
|
||||
"Rerank model not configured. Set RERANK_BINDING_API_KEY and RERANK_BINDING_HOST to enable reranking."
|
||||
)
|
||||
|
||||
# Initialize RAG
|
||||
|
|
@ -351,7 +353,6 @@ def create_app(args):
|
|||
},
|
||||
enable_llm_cache_for_entity_extract=args.enable_llm_cache_for_extract,
|
||||
enable_llm_cache=args.enable_llm_cache,
|
||||
enable_rerank=args.enable_rerank,
|
||||
rerank_model_func=rerank_model_func,
|
||||
auto_manage_storages_states=False,
|
||||
max_parallel_insert=args.max_parallel_insert,
|
||||
|
|
@ -381,7 +382,6 @@ def create_app(args):
|
|||
},
|
||||
enable_llm_cache_for_entity_extract=args.enable_llm_cache_for_extract,
|
||||
enable_llm_cache=args.enable_llm_cache,
|
||||
enable_rerank=args.enable_rerank,
|
||||
rerank_model_func=rerank_model_func,
|
||||
auto_manage_storages_states=False,
|
||||
max_parallel_insert=args.max_parallel_insert,
|
||||
|
|
@ -512,11 +512,13 @@ def create_app(args):
|
|||
"enable_llm_cache": args.enable_llm_cache,
|
||||
"workspace": args.workspace,
|
||||
"max_graph_nodes": args.max_graph_nodes,
|
||||
# Rerank configuration
|
||||
"enable_rerank": args.enable_rerank,
|
||||
"rerank_model": args.rerank_model if args.enable_rerank else None,
|
||||
# Rerank configuration (based on whether rerank model is configured)
|
||||
"enable_rerank": rerank_model_func is not None,
|
||||
"rerank_model": args.rerank_model
|
||||
if rerank_model_func is not None
|
||||
else None,
|
||||
"rerank_binding_host": args.rerank_binding_host
|
||||
if args.enable_rerank
|
||||
if rerank_model_func is not None
|
||||
else None,
|
||||
},
|
||||
"auth_mode": auth_mode,
|
||||
|
|
|
|||
|
|
@ -52,31 +52,25 @@ class QueryRequest(BaseModel):
|
|||
chunk_top_k: Optional[int] = Field(
|
||||
ge=1,
|
||||
default=None,
|
||||
description="Number of text chunks to retrieve initially from vector search.",
|
||||
description="Number of text chunks to retrieve initially from vector search and keep after reranking.",
|
||||
)
|
||||
|
||||
chunk_rerank_top_k: Optional[int] = Field(
|
||||
max_entity_tokens: Optional[int] = Field(
|
||||
default=None,
|
||||
description="Maximum number of tokens allocated for entity context in unified token control system.",
|
||||
ge=1,
|
||||
default=None,
|
||||
description="Number of text chunks to keep after reranking.",
|
||||
)
|
||||
|
||||
max_token_for_text_unit: Optional[int] = Field(
|
||||
gt=1,
|
||||
max_relation_tokens: Optional[int] = Field(
|
||||
default=None,
|
||||
description="Maximum number of tokens allowed for each retrieved text chunk.",
|
||||
description="Maximum number of tokens allocated for relationship context in unified token control system.",
|
||||
ge=1,
|
||||
)
|
||||
|
||||
max_token_for_global_context: Optional[int] = Field(
|
||||
gt=1,
|
||||
max_total_tokens: Optional[int] = Field(
|
||||
default=None,
|
||||
description="Maximum number of tokens allocated for relationship descriptions in global retrieval.",
|
||||
)
|
||||
|
||||
max_token_for_local_context: Optional[int] = Field(
|
||||
gt=1,
|
||||
default=None,
|
||||
description="Maximum number of tokens allocated for entity descriptions in local retrieval.",
|
||||
description="Maximum total tokens budget for the entire query context (entities + relations + chunks + system prompt).",
|
||||
ge=1,
|
||||
)
|
||||
|
||||
conversation_history: Optional[List[Dict[str, Any]]] = Field(
|
||||
|
|
@ -99,6 +93,11 @@ class QueryRequest(BaseModel):
|
|||
description="User-provided prompt for the query. If provided, this will be used instead of the default value from prompt template.",
|
||||
)
|
||||
|
||||
enable_rerank: Optional[bool] = Field(
|
||||
default=None,
|
||||
description="Enable reranking for retrieved text chunks. If True but no rerank model is configured, a warning will be issued. Default is True.",
|
||||
)
|
||||
|
||||
@field_validator("query", mode="after")
|
||||
@classmethod
|
||||
def query_strip_after(cls, query: str) -> str:
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
import{e as v,c as b,g as m,k as O,h as P,j as p,l as w,m as c,n as x,t as A,o as N}from"./_baseUniq-CtAZZJ8e.js";import{aU as g,aq as _,aV as $,aW as E,aX as F,aY as I,aZ as M,a_ as y,a$ as B,b0 as T}from"./mermaid-vendor-D0f_SE0h.js";var S=/\s/;function q(n){for(var r=n.length;r--&&S.test(n.charAt(r)););return r}var G=/^\s+/;function H(n){return n&&n.slice(0,q(n)+1).replace(G,"")}var o=NaN,L=/^[-+]0x[0-9a-f]+$/i,R=/^0b[01]+$/i,W=/^0o[0-7]+$/i,X=parseInt;function Y(n){if(typeof n=="number")return n;if(v(n))return o;if(g(n)){var r=typeof n.valueOf=="function"?n.valueOf():n;n=g(r)?r+"":r}if(typeof n!="string")return n===0?n:+n;n=H(n);var t=R.test(n);return t||W.test(n)?X(n.slice(2),t?2:8):L.test(n)?o:+n}var z=1/0,C=17976931348623157e292;function K(n){if(!n)return n===0?n:0;if(n=Y(n),n===z||n===-1/0){var r=n<0?-1:1;return r*C}return n===n?n:0}function U(n){var r=K(n),t=r%1;return r===r?t?r-t:r:0}function fn(n){var r=n==null?0:n.length;return r?b(n):[]}var l=Object.prototype,Z=l.hasOwnProperty,dn=_(function(n,r){n=Object(n);var t=-1,e=r.length,a=e>2?r[2]:void 0;for(a&&$(r[0],r[1],a)&&(e=1);++t<e;)for(var f=r[t],i=E(f),s=-1,d=i.length;++s<d;){var u=i[s],h=n[u];(h===void 0||F(h,l[u])&&!Z.call(n,u))&&(n[u]=f[u])}return n});function un(n){var r=n==null?0:n.length;return r?n[r-1]:void 0}function D(n){return function(r,t,e){var a=Object(r);if(!I(r)){var f=m(t);r=O(r),t=function(s){return f(a[s],s,a)}}var i=n(r,t,e);return i>-1?a[f?r[i]:i]:void 0}}var J=Math.max;function Q(n,r,t){var e=n==null?0:n.length;if(!e)return-1;var a=t==null?0:U(t);return a<0&&(a=J(e+a,0)),P(n,m(r),a)}var hn=D(Q);function V(n,r){var t=-1,e=I(n)?Array(n.length):[];return p(n,function(a,f,i){e[++t]=r(a,f,i)}),e}function gn(n,r){var t=M(n)?w:V;return t(n,m(r))}var j=Object.prototype,k=j.hasOwnProperty;function nn(n,r){return n!=null&&k.call(n,r)}function mn(n,r){return n!=null&&c(n,r,nn)}function rn(n,r){return n<r}function tn(n,r,t){for(var e=-1,a=n.length;++e<a;){var f=n[e],i=r(f);if(i!=null&&(s===void 0?i===i&&!v(i):t(i,s)))var s=i,d=f}return d}function on(n){return n&&n.length?tn(n,y,rn):void 0}function an(n,r,t,e){if(!g(n))return n;r=x(r,n);for(var a=-1,f=r.length,i=f-1,s=n;s!=null&&++a<f;){var d=A(r[a]),u=t;if(d==="__proto__"||d==="constructor"||d==="prototype")return n;if(a!=i){var h=s[d];u=void 0,u===void 0&&(u=g(h)?h:B(r[a+1])?[]:{})}T(s,d,u),s=s[d]}return n}function vn(n,r,t){for(var e=-1,a=r.length,f={};++e<a;){var i=r[e],s=N(n,i);t(s,i)&&an(f,x(i,n),s)}return f}export{rn as a,tn as b,V as c,vn as d,on as e,fn as f,hn as g,mn as h,dn as i,U as j,un as l,gn as m,K as t};
|
||||
import{e as v,c as b,g as m,k as O,h as P,j as p,l as w,m as c,n as x,t as A,o as N}from"./_baseUniq-BZ3hvks1.js";import{aU as g,aq as _,aV as $,aW as E,aX as F,aY as I,aZ as M,a_ as y,a$ as B,b0 as T}from"./mermaid-vendor-CR44n-lC.js";var S=/\s/;function q(n){for(var r=n.length;r--&&S.test(n.charAt(r)););return r}var G=/^\s+/;function H(n){return n&&n.slice(0,q(n)+1).replace(G,"")}var o=NaN,L=/^[-+]0x[0-9a-f]+$/i,R=/^0b[01]+$/i,W=/^0o[0-7]+$/i,X=parseInt;function Y(n){if(typeof n=="number")return n;if(v(n))return o;if(g(n)){var r=typeof n.valueOf=="function"?n.valueOf():n;n=g(r)?r+"":r}if(typeof n!="string")return n===0?n:+n;n=H(n);var t=R.test(n);return t||W.test(n)?X(n.slice(2),t?2:8):L.test(n)?o:+n}var z=1/0,C=17976931348623157e292;function K(n){if(!n)return n===0?n:0;if(n=Y(n),n===z||n===-1/0){var r=n<0?-1:1;return r*C}return n===n?n:0}function U(n){var r=K(n),t=r%1;return r===r?t?r-t:r:0}function fn(n){var r=n==null?0:n.length;return r?b(n):[]}var l=Object.prototype,Z=l.hasOwnProperty,dn=_(function(n,r){n=Object(n);var t=-1,e=r.length,a=e>2?r[2]:void 0;for(a&&$(r[0],r[1],a)&&(e=1);++t<e;)for(var f=r[t],i=E(f),s=-1,d=i.length;++s<d;){var u=i[s],h=n[u];(h===void 0||F(h,l[u])&&!Z.call(n,u))&&(n[u]=f[u])}return n});function un(n){var r=n==null?0:n.length;return r?n[r-1]:void 0}function D(n){return function(r,t,e){var a=Object(r);if(!I(r)){var f=m(t);r=O(r),t=function(s){return f(a[s],s,a)}}var i=n(r,t,e);return i>-1?a[f?r[i]:i]:void 0}}var J=Math.max;function Q(n,r,t){var e=n==null?0:n.length;if(!e)return-1;var a=t==null?0:U(t);return a<0&&(a=J(e+a,0)),P(n,m(r),a)}var hn=D(Q);function V(n,r){var t=-1,e=I(n)?Array(n.length):[];return p(n,function(a,f,i){e[++t]=r(a,f,i)}),e}function gn(n,r){var t=M(n)?w:V;return t(n,m(r))}var j=Object.prototype,k=j.hasOwnProperty;function nn(n,r){return n!=null&&k.call(n,r)}function mn(n,r){return n!=null&&c(n,r,nn)}function rn(n,r){return n<r}function tn(n,r,t){for(var e=-1,a=n.length;++e<a;){var f=n[e],i=r(f);if(i!=null&&(s===void 0?i===i&&!v(i):t(i,s)))var s=i,d=f}return d}function on(n){return n&&n.length?tn(n,y,rn):void 0}function an(n,r,t,e){if(!g(n))return n;r=x(r,n);for(var a=-1,f=r.length,i=f-1,s=n;s!=null&&++a<f;){var d=A(r[a]),u=t;if(d==="__proto__"||d==="constructor"||d==="prototype")return n;if(a!=i){var h=s[d];u=void 0,u===void 0&&(u=g(h)?h:B(r[a+1])?[]:{})}T(s,d,u),s=s[d]}return n}function vn(n,r,t){for(var e=-1,a=r.length,f={};++e<a;){var i=r[e],s=N(n,i);t(s,i)&&an(f,x(i,n),s)}return f}export{rn as a,tn as b,V as c,vn as d,on as e,fn as f,hn as g,mn as h,dn as i,U as j,un as l,gn as m,K as t};
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
|
@ -1 +1 @@
|
|||
import{_ as l}from"./mermaid-vendor-D0f_SE0h.js";function m(e,c){var i,t,o;e.accDescr&&((i=c.setAccDescription)==null||i.call(c,e.accDescr)),e.accTitle&&((t=c.setAccTitle)==null||t.call(c,e.accTitle)),e.title&&((o=c.setDiagramTitle)==null||o.call(c,e.title))}l(m,"populateCommonDb");export{m as p};
|
||||
import{_ as l}from"./mermaid-vendor-CR44n-lC.js";function m(e,c){var i,t,o;e.accDescr&&((i=c.setAccDescription)==null||i.call(c,e.accDescr)),e.accTitle&&((t=c.setAccTitle)==null||t.call(c,e.accTitle)),e.title&&((o=c.setDiagramTitle)==null||o.call(c,e.title))}l(m,"populateCommonDb");export{m as p};
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
|
@ -1 +1 @@
|
|||
import{_ as n,a1 as x,j as l}from"./mermaid-vendor-D0f_SE0h.js";var c=n((a,t)=>{const e=a.append("rect");if(e.attr("x",t.x),e.attr("y",t.y),e.attr("fill",t.fill),e.attr("stroke",t.stroke),e.attr("width",t.width),e.attr("height",t.height),t.name&&e.attr("name",t.name),t.rx&&e.attr("rx",t.rx),t.ry&&e.attr("ry",t.ry),t.attrs!==void 0)for(const r in t.attrs)e.attr(r,t.attrs[r]);return t.class&&e.attr("class",t.class),e},"drawRect"),d=n((a,t)=>{const e={x:t.startx,y:t.starty,width:t.stopx-t.startx,height:t.stopy-t.starty,fill:t.fill,stroke:t.stroke,class:"rect"};c(a,e).lower()},"drawBackgroundRect"),g=n((a,t)=>{const e=t.text.replace(x," "),r=a.append("text");r.attr("x",t.x),r.attr("y",t.y),r.attr("class","legend"),r.style("text-anchor",t.anchor),t.class&&r.attr("class",t.class);const s=r.append("tspan");return s.attr("x",t.x+t.textMargin*2),s.text(e),r},"drawText"),h=n((a,t,e,r)=>{const s=a.append("image");s.attr("x",t),s.attr("y",e);const i=l.sanitizeUrl(r);s.attr("xlink:href",i)},"drawImage"),m=n((a,t,e,r)=>{const s=a.append("use");s.attr("x",t),s.attr("y",e);const i=l.sanitizeUrl(r);s.attr("xlink:href",`#${i}`)},"drawEmbeddedImage"),y=n(()=>({x:0,y:0,width:100,height:100,fill:"#EDF2AE",stroke:"#666",anchor:"start",rx:0,ry:0}),"getNoteRect"),p=n(()=>({x:0,y:0,width:100,height:100,"text-anchor":"start",style:"#666",textMargin:0,rx:0,ry:0,tspan:!0}),"getTextObj");export{d as a,p as b,m as c,c as d,h as e,g as f,y as g};
|
||||
import{_ as n,a1 as x,j as l}from"./mermaid-vendor-CR44n-lC.js";var c=n((a,t)=>{const e=a.append("rect");if(e.attr("x",t.x),e.attr("y",t.y),e.attr("fill",t.fill),e.attr("stroke",t.stroke),e.attr("width",t.width),e.attr("height",t.height),t.name&&e.attr("name",t.name),t.rx&&e.attr("rx",t.rx),t.ry&&e.attr("ry",t.ry),t.attrs!==void 0)for(const r in t.attrs)e.attr(r,t.attrs[r]);return t.class&&e.attr("class",t.class),e},"drawRect"),d=n((a,t)=>{const e={x:t.startx,y:t.starty,width:t.stopx-t.startx,height:t.stopy-t.starty,fill:t.fill,stroke:t.stroke,class:"rect"};c(a,e).lower()},"drawBackgroundRect"),g=n((a,t)=>{const e=t.text.replace(x," "),r=a.append("text");r.attr("x",t.x),r.attr("y",t.y),r.attr("class","legend"),r.style("text-anchor",t.anchor),t.class&&r.attr("class",t.class);const s=r.append("tspan");return s.attr("x",t.x+t.textMargin*2),s.text(e),r},"drawText"),h=n((a,t,e,r)=>{const s=a.append("image");s.attr("x",t),s.attr("y",e);const i=l.sanitizeUrl(r);s.attr("xlink:href",i)},"drawImage"),m=n((a,t,e,r)=>{const s=a.append("use");s.attr("x",t),s.attr("y",e);const i=l.sanitizeUrl(r);s.attr("xlink:href",`#${i}`)},"drawEmbeddedImage"),y=n(()=>({x:0,y:0,width:100,height:100,fill:"#EDF2AE",stroke:"#666",anchor:"start",rx:0,ry:0}),"getNoteRect"),p=n(()=>({x:0,y:0,width:100,height:100,"text-anchor":"start",style:"#666",textMargin:0,rx:0,ry:0,tspan:!0}),"getTextObj");export{d as a,p as b,m as c,c as d,h as e,g as f,y as g};
|
||||
|
|
@ -1 +1 @@
|
|||
import{_ as n,d as r,e as d,l as g}from"./mermaid-vendor-D0f_SE0h.js";var u=n((e,t)=>{let o;return t==="sandbox"&&(o=r("#i"+e)),(t==="sandbox"?r(o.nodes()[0].contentDocument.body):r("body")).select(`[id="${e}"]`)},"getDiagramElement"),b=n((e,t,o,i)=>{e.attr("class",o);const{width:a,height:s,x:h,y:x}=l(e,t);d(e,s,a,i);const c=w(h,x,a,s,t);e.attr("viewBox",c),g.debug(`viewBox configured: ${c} with padding: ${t}`)},"setupViewPortForSVG"),l=n((e,t)=>{var i;const o=((i=e.node())==null?void 0:i.getBBox())||{width:0,height:0,x:0,y:0};return{width:o.width+t*2,height:o.height+t*2,x:o.x,y:o.y}},"calculateDimensionsWithPadding"),w=n((e,t,o,i,a)=>`${e-a} ${t-a} ${o} ${i}`,"createViewBox");export{u as g,b as s};
|
||||
import{_ as n,d as r,e as d,l as g}from"./mermaid-vendor-CR44n-lC.js";var u=n((e,t)=>{let o;return t==="sandbox"&&(o=r("#i"+e)),(t==="sandbox"?r(o.nodes()[0].contentDocument.body):r("body")).select(`[id="${e}"]`)},"getDiagramElement"),b=n((e,t,o,i)=>{e.attr("class",o);const{width:a,height:s,x:h,y:x}=l(e,t);d(e,s,a,i);const c=w(h,x,a,s,t);e.attr("viewBox",c),g.debug(`viewBox configured: ${c} with padding: ${t}`)},"setupViewPortForSVG"),l=n((e,t)=>{var i;const o=((i=e.node())==null?void 0:i.getBBox())||{width:0,height:0,x:0,y:0};return{width:o.width+t*2,height:o.height+t*2,x:o.x,y:o.y}},"calculateDimensionsWithPadding"),w=n((e,t,o,i,a)=>`${e-a} ${t-a} ${o} ${i}`,"createViewBox");export{u as g,b as s};
|
||||
|
|
@ -1 +1 @@
|
|||
import{_ as s}from"./mermaid-vendor-D0f_SE0h.js";var t,e=(t=class{constructor(i){this.init=i,this.records=this.init()}reset(){this.records=this.init()}},s(t,"ImperativeState"),t);export{e as I};
|
||||
import{_ as s}from"./mermaid-vendor-CR44n-lC.js";var t,e=(t=class{constructor(i){this.init=i,this.records=this.init()}reset(){this.records=this.init()}},s(t,"ImperativeState"),t);export{e as I};
|
||||
|
|
@ -1 +1 @@
|
|||
import{s as a,c as s,a as e,C as t}from"./chunk-A2AXSNBT-B91iiasA.js";import{_ as i}from"./mermaid-vendor-D0f_SE0h.js";import"./chunk-RZ5BOZE2-B615FLH4.js";import"./feature-graph-NODQb6qW.js";import"./react-vendor-DEwriMA6.js";import"./graph-vendor-B-X5JegA.js";import"./ui-vendor-CeCm8EER.js";import"./utils-vendor-BysuhMZA.js";var f={parser:e,get db(){return new t},renderer:s,styles:a,init:i(r=>{r.class||(r.class={}),r.class.arrowMarkerAbsolute=r.arrowMarkerAbsolute},"init")};export{f as diagram};
|
||||
import{s as a,c as s,a as e,C as t}from"./chunk-A2AXSNBT-CRex3-yW.js";import{_ as i}from"./mermaid-vendor-CR44n-lC.js";import"./chunk-RZ5BOZE2-CdnIs5Fb.js";import"./feature-graph-wF7LCIjH.js";import"./react-vendor-DEwriMA6.js";import"./graph-vendor-B-X5JegA.js";import"./ui-vendor-CeCm8EER.js";import"./utils-vendor-BysuhMZA.js";var f={parser:e,get db(){return new t},renderer:s,styles:a,init:i(r=>{r.class||(r.class={}),r.class.arrowMarkerAbsolute=r.arrowMarkerAbsolute},"init")};export{f as diagram};
|
||||
|
|
@ -1 +1 @@
|
|||
import{s as a,c as s,a as e,C as t}from"./chunk-A2AXSNBT-B91iiasA.js";import{_ as i}from"./mermaid-vendor-D0f_SE0h.js";import"./chunk-RZ5BOZE2-B615FLH4.js";import"./feature-graph-NODQb6qW.js";import"./react-vendor-DEwriMA6.js";import"./graph-vendor-B-X5JegA.js";import"./ui-vendor-CeCm8EER.js";import"./utils-vendor-BysuhMZA.js";var f={parser:e,get db(){return new t},renderer:s,styles:a,init:i(r=>{r.class||(r.class={}),r.class.arrowMarkerAbsolute=r.arrowMarkerAbsolute},"init")};export{f as diagram};
|
||||
import{s as a,c as s,a as e,C as t}from"./chunk-A2AXSNBT-CRex3-yW.js";import{_ as i}from"./mermaid-vendor-CR44n-lC.js";import"./chunk-RZ5BOZE2-CdnIs5Fb.js";import"./feature-graph-wF7LCIjH.js";import"./react-vendor-DEwriMA6.js";import"./graph-vendor-B-X5JegA.js";import"./ui-vendor-CeCm8EER.js";import"./utils-vendor-BysuhMZA.js";var f={parser:e,get db(){return new t},renderer:s,styles:a,init:i(r=>{r.class||(r.class={}),r.class.arrowMarkerAbsolute=r.arrowMarkerAbsolute},"init")};export{f as diagram};
|
||||
1
lightrag/api/webui/assets/clone-Dm5jEAXQ.js
generated
1
lightrag/api/webui/assets/clone-Dm5jEAXQ.js
generated
|
|
@ -1 +0,0 @@
|
|||
import{b as r}from"./_baseUniq-CtAZZJ8e.js";var e=4;function a(o){return r(o,e)}export{a as c};
|
||||
1
lightrag/api/webui/assets/clone-eVzB-9-f.js
generated
Normal file
1
lightrag/api/webui/assets/clone-eVzB-9-f.js
generated
Normal file
|
|
@ -0,0 +1 @@
|
|||
import{b as r}from"./_baseUniq-BZ3hvks1.js";var e=4;function a(o){return r(o,e)}export{a as c};
|
||||
File diff suppressed because one or more lines are too long
|
|
@ -1,4 +1,4 @@
|
|||
import{p as k}from"./chunk-4BMEZGHF-CAhtCpmT.js";import{_ as l,s as R,g as F,t as I,q as _,a as E,b as D,K as G,z,F as y,G as C,H as P,l as H,Q as V}from"./mermaid-vendor-D0f_SE0h.js";import{p as W}from"./radar-MK3ICKWK-DOAXm8cx.js";import"./feature-graph-NODQb6qW.js";import"./react-vendor-DEwriMA6.js";import"./graph-vendor-B-X5JegA.js";import"./ui-vendor-CeCm8EER.js";import"./utils-vendor-BysuhMZA.js";import"./_baseUniq-CtAZZJ8e.js";import"./_basePickBy-D3PHsJjq.js";import"./clone-Dm5jEAXQ.js";var h={showLegend:!0,ticks:5,max:null,min:0,graticule:"circle"},w={axes:[],curves:[],options:h},g=structuredClone(w),B=P.radar,j=l(()=>y({...B,...C().radar}),"getConfig"),b=l(()=>g.axes,"getAxes"),q=l(()=>g.curves,"getCurves"),K=l(()=>g.options,"getOptions"),N=l(a=>{g.axes=a.map(t=>({name:t.name,label:t.label??t.name}))},"setAxes"),Q=l(a=>{g.curves=a.map(t=>({name:t.name,label:t.label??t.name,entries:U(t.entries)}))},"setCurves"),U=l(a=>{if(a[0].axis==null)return a.map(e=>e.value);const t=b();if(t.length===0)throw new Error("Axes must be populated before curves for reference entries");return t.map(e=>{const r=a.find(s=>{var o;return((o=s.axis)==null?void 0:o.$refText)===e.name});if(r===void 0)throw new Error("Missing entry for axis "+e.label);return r.value})},"computeCurveEntries"),X=l(a=>{var e,r,s,o,i;const t=a.reduce((n,c)=>(n[c.name]=c,n),{});g.options={showLegend:((e=t.showLegend)==null?void 0:e.value)??h.showLegend,ticks:((r=t.ticks)==null?void 0:r.value)??h.ticks,max:((s=t.max)==null?void 0:s.value)??h.max,min:((o=t.min)==null?void 0:o.value)??h.min,graticule:((i=t.graticule)==null?void 0:i.value)??h.graticule}},"setOptions"),Y=l(()=>{z(),g=structuredClone(w)},"clear"),$={getAxes:b,getCurves:q,getOptions:K,setAxes:N,setCurves:Q,setOptions:X,getConfig:j,clear:Y,setAccTitle:D,getAccTitle:E,setDiagramTitle:_,getDiagramTitle:I,getAccDescription:F,setAccDescription:R},Z=l(a=>{k(a,$);const{axes:t,curves:e,options:r}=a;$.setAxes(t),$.setCurves(e),$.setOptions(r)},"populate"),J={parse:l(async a=>{const t=await W("radar",a);H.debug(t),Z(t)},"parse")},tt=l((a,t,e,r)=>{const s=r.db,o=s.getAxes(),i=s.getCurves(),n=s.getOptions(),c=s.getConfig(),d=s.getDiagramTitle(),u=G(t),p=et(u,c),m=n.max??Math.max(...i.map(f=>Math.max(...f.entries))),x=n.min,v=Math.min(c.width,c.height)/2;at(p,o,v,n.ticks,n.graticule),rt(p,o,v,c),M(p,o,i,x,m,n.graticule,c),T(p,i,n.showLegend,c),p.append("text").attr("class","radarTitle").text(d).attr("x",0).attr("y",-c.height/2-c.marginTop)},"draw"),et=l((a,t)=>{const e=t.width+t.marginLeft+t.marginRight,r=t.height+t.marginTop+t.marginBottom,s={x:t.marginLeft+t.width/2,y:t.marginTop+t.height/2};return a.attr("viewbox",`0 0 ${e} ${r}`).attr("width",e).attr("height",r),a.append("g").attr("transform",`translate(${s.x}, ${s.y})`)},"drawFrame"),at=l((a,t,e,r,s)=>{if(s==="circle")for(let o=0;o<r;o++){const i=e*(o+1)/r;a.append("circle").attr("r",i).attr("class","radarGraticule")}else if(s==="polygon"){const o=t.length;for(let i=0;i<r;i++){const n=e*(i+1)/r,c=t.map((d,u)=>{const p=2*u*Math.PI/o-Math.PI/2,m=n*Math.cos(p),x=n*Math.sin(p);return`${m},${x}`}).join(" ");a.append("polygon").attr("points",c).attr("class","radarGraticule")}}},"drawGraticule"),rt=l((a,t,e,r)=>{const s=t.length;for(let o=0;o<s;o++){const i=t[o].label,n=2*o*Math.PI/s-Math.PI/2;a.append("line").attr("x1",0).attr("y1",0).attr("x2",e*r.axisScaleFactor*Math.cos(n)).attr("y2",e*r.axisScaleFactor*Math.sin(n)).attr("class","radarAxisLine"),a.append("text").text(i).attr("x",e*r.axisLabelFactor*Math.cos(n)).attr("y",e*r.axisLabelFactor*Math.sin(n)).attr("class","radarAxisLabel")}},"drawAxes");function M(a,t,e,r,s,o,i){const n=t.length,c=Math.min(i.width,i.height)/2;e.forEach((d,u)=>{if(d.entries.length!==n)return;const p=d.entries.map((m,x)=>{const v=2*Math.PI*x/n-Math.PI/2,f=A(m,r,s,c),O=f*Math.cos(v),S=f*Math.sin(v);return{x:O,y:S}});o==="circle"?a.append("path").attr("d",L(p,i.curveTension)).attr("class",`radarCurve-${u}`):o==="polygon"&&a.append("polygon").attr("points",p.map(m=>`${m.x},${m.y}`).join(" ")).attr("class",`radarCurve-${u}`)})}l(M,"drawCurves");function A(a,t,e,r){const s=Math.min(Math.max(a,t),e);return r*(s-t)/(e-t)}l(A,"relativeRadius");function L(a,t){const e=a.length;let r=`M${a[0].x},${a[0].y}`;for(let s=0;s<e;s++){const o=a[(s-1+e)%e],i=a[s],n=a[(s+1)%e],c=a[(s+2)%e],d={x:i.x+(n.x-o.x)*t,y:i.y+(n.y-o.y)*t},u={x:n.x-(c.x-i.x)*t,y:n.y-(c.y-i.y)*t};r+=` C${d.x},${d.y} ${u.x},${u.y} ${n.x},${n.y}`}return`${r} Z`}l(L,"closedRoundCurve");function T(a,t,e,r){if(!e)return;const s=(r.width/2+r.marginRight)*3/4,o=-(r.height/2+r.marginTop)*3/4,i=20;t.forEach((n,c)=>{const d=a.append("g").attr("transform",`translate(${s}, ${o+c*i})`);d.append("rect").attr("width",12).attr("height",12).attr("class",`radarLegendBox-${c}`),d.append("text").attr("x",16).attr("y",0).attr("class","radarLegendText").text(n.label)})}l(T,"drawLegend");var st={draw:tt},nt=l((a,t)=>{let e="";for(let r=0;r<a.THEME_COLOR_LIMIT;r++){const s=a[`cScale${r}`];e+=`
|
||||
import{p as k}from"./chunk-4BMEZGHF-DM9xX3Iw.js";import{_ as l,s as R,g as F,t as I,q as _,a as E,b as D,K as G,z,F as y,G as C,H as P,l as H,Q as V}from"./mermaid-vendor-CR44n-lC.js";import{p as W}from"./radar-MK3ICKWK-B97XRKGx.js";import"./feature-graph-wF7LCIjH.js";import"./react-vendor-DEwriMA6.js";import"./graph-vendor-B-X5JegA.js";import"./ui-vendor-CeCm8EER.js";import"./utils-vendor-BysuhMZA.js";import"./_baseUniq-BZ3hvks1.js";import"./_basePickBy-DV1dBXEu.js";import"./clone-eVzB-9-f.js";var h={showLegend:!0,ticks:5,max:null,min:0,graticule:"circle"},w={axes:[],curves:[],options:h},g=structuredClone(w),B=P.radar,j=l(()=>y({...B,...C().radar}),"getConfig"),b=l(()=>g.axes,"getAxes"),q=l(()=>g.curves,"getCurves"),K=l(()=>g.options,"getOptions"),N=l(a=>{g.axes=a.map(t=>({name:t.name,label:t.label??t.name}))},"setAxes"),Q=l(a=>{g.curves=a.map(t=>({name:t.name,label:t.label??t.name,entries:U(t.entries)}))},"setCurves"),U=l(a=>{if(a[0].axis==null)return a.map(e=>e.value);const t=b();if(t.length===0)throw new Error("Axes must be populated before curves for reference entries");return t.map(e=>{const r=a.find(s=>{var o;return((o=s.axis)==null?void 0:o.$refText)===e.name});if(r===void 0)throw new Error("Missing entry for axis "+e.label);return r.value})},"computeCurveEntries"),X=l(a=>{var e,r,s,o,i;const t=a.reduce((n,c)=>(n[c.name]=c,n),{});g.options={showLegend:((e=t.showLegend)==null?void 0:e.value)??h.showLegend,ticks:((r=t.ticks)==null?void 0:r.value)??h.ticks,max:((s=t.max)==null?void 0:s.value)??h.max,min:((o=t.min)==null?void 0:o.value)??h.min,graticule:((i=t.graticule)==null?void 0:i.value)??h.graticule}},"setOptions"),Y=l(()=>{z(),g=structuredClone(w)},"clear"),$={getAxes:b,getCurves:q,getOptions:K,setAxes:N,setCurves:Q,setOptions:X,getConfig:j,clear:Y,setAccTitle:D,getAccTitle:E,setDiagramTitle:_,getDiagramTitle:I,getAccDescription:F,setAccDescription:R},Z=l(a=>{k(a,$);const{axes:t,curves:e,options:r}=a;$.setAxes(t),$.setCurves(e),$.setOptions(r)},"populate"),J={parse:l(async a=>{const t=await W("radar",a);H.debug(t),Z(t)},"parse")},tt=l((a,t,e,r)=>{const s=r.db,o=s.getAxes(),i=s.getCurves(),n=s.getOptions(),c=s.getConfig(),d=s.getDiagramTitle(),u=G(t),p=et(u,c),m=n.max??Math.max(...i.map(f=>Math.max(...f.entries))),x=n.min,v=Math.min(c.width,c.height)/2;at(p,o,v,n.ticks,n.graticule),rt(p,o,v,c),M(p,o,i,x,m,n.graticule,c),T(p,i,n.showLegend,c),p.append("text").attr("class","radarTitle").text(d).attr("x",0).attr("y",-c.height/2-c.marginTop)},"draw"),et=l((a,t)=>{const e=t.width+t.marginLeft+t.marginRight,r=t.height+t.marginTop+t.marginBottom,s={x:t.marginLeft+t.width/2,y:t.marginTop+t.height/2};return a.attr("viewbox",`0 0 ${e} ${r}`).attr("width",e).attr("height",r),a.append("g").attr("transform",`translate(${s.x}, ${s.y})`)},"drawFrame"),at=l((a,t,e,r,s)=>{if(s==="circle")for(let o=0;o<r;o++){const i=e*(o+1)/r;a.append("circle").attr("r",i).attr("class","radarGraticule")}else if(s==="polygon"){const o=t.length;for(let i=0;i<r;i++){const n=e*(i+1)/r,c=t.map((d,u)=>{const p=2*u*Math.PI/o-Math.PI/2,m=n*Math.cos(p),x=n*Math.sin(p);return`${m},${x}`}).join(" ");a.append("polygon").attr("points",c).attr("class","radarGraticule")}}},"drawGraticule"),rt=l((a,t,e,r)=>{const s=t.length;for(let o=0;o<s;o++){const i=t[o].label,n=2*o*Math.PI/s-Math.PI/2;a.append("line").attr("x1",0).attr("y1",0).attr("x2",e*r.axisScaleFactor*Math.cos(n)).attr("y2",e*r.axisScaleFactor*Math.sin(n)).attr("class","radarAxisLine"),a.append("text").text(i).attr("x",e*r.axisLabelFactor*Math.cos(n)).attr("y",e*r.axisLabelFactor*Math.sin(n)).attr("class","radarAxisLabel")}},"drawAxes");function M(a,t,e,r,s,o,i){const n=t.length,c=Math.min(i.width,i.height)/2;e.forEach((d,u)=>{if(d.entries.length!==n)return;const p=d.entries.map((m,x)=>{const v=2*Math.PI*x/n-Math.PI/2,f=A(m,r,s,c),O=f*Math.cos(v),S=f*Math.sin(v);return{x:O,y:S}});o==="circle"?a.append("path").attr("d",L(p,i.curveTension)).attr("class",`radarCurve-${u}`):o==="polygon"&&a.append("polygon").attr("points",p.map(m=>`${m.x},${m.y}`).join(" ")).attr("class",`radarCurve-${u}`)})}l(M,"drawCurves");function A(a,t,e,r){const s=Math.min(Math.max(a,t),e);return r*(s-t)/(e-t)}l(A,"relativeRadius");function L(a,t){const e=a.length;let r=`M${a[0].x},${a[0].y}`;for(let s=0;s<e;s++){const o=a[(s-1+e)%e],i=a[s],n=a[(s+1)%e],c=a[(s+2)%e],d={x:i.x+(n.x-o.x)*t,y:i.y+(n.y-o.y)*t},u={x:n.x-(c.x-i.x)*t,y:n.y-(c.y-i.y)*t};r+=` C${d.x},${d.y} ${u.x},${u.y} ${n.x},${n.y}`}return`${r} Z`}l(L,"closedRoundCurve");function T(a,t,e,r){if(!e)return;const s=(r.width/2+r.marginRight)*3/4,o=-(r.height/2+r.marginTop)*3/4,i=20;t.forEach((n,c)=>{const d=a.append("g").attr("transform",`translate(${s}, ${o+c*i})`);d.append("rect").attr("width",12).attr("height",12).attr("class",`radarLegendBox-${c}`),d.append("text").attr("x",16).attr("y",0).attr("class","radarLegendText").text(n.label)})}l(T,"drawLegend");var st={draw:tt},nt=l((a,t)=>{let e="";for(let r=0;r<a.THEME_COLOR_LIMIT;r++){const s=a[`cScale${r}`];e+=`
|
||||
.radarCurve-${r} {
|
||||
color: ${s};
|
||||
fill: ${s};
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
import{p as w}from"./chunk-4BMEZGHF-CAhtCpmT.js";import{_ as n,s as B,g as S,t as F,q as z,a as P,b as W,F as x,K as T,e as D,z as _,G as A,H as E,l as v}from"./mermaid-vendor-D0f_SE0h.js";import{p as N}from"./radar-MK3ICKWK-DOAXm8cx.js";import"./feature-graph-NODQb6qW.js";import"./react-vendor-DEwriMA6.js";import"./graph-vendor-B-X5JegA.js";import"./ui-vendor-CeCm8EER.js";import"./utils-vendor-BysuhMZA.js";import"./_baseUniq-CtAZZJ8e.js";import"./_basePickBy-D3PHsJjq.js";import"./clone-Dm5jEAXQ.js";var C={packet:[]},h=structuredClone(C),L=E.packet,Y=n(()=>{const t=x({...L,...A().packet});return t.showBits&&(t.paddingY+=10),t},"getConfig"),G=n(()=>h.packet,"getPacket"),H=n(t=>{t.length>0&&h.packet.push(t)},"pushWord"),I=n(()=>{_(),h=structuredClone(C)},"clear"),m={pushWord:H,getPacket:G,getConfig:Y,clear:I,setAccTitle:W,getAccTitle:P,setDiagramTitle:z,getDiagramTitle:F,getAccDescription:S,setAccDescription:B},K=1e4,M=n(t=>{w(t,m);let e=-1,o=[],s=1;const{bitsPerRow:i}=m.getConfig();for(let{start:a,end:r,label:p}of t.blocks){if(r&&r<a)throw new Error(`Packet block ${a} - ${r} is invalid. End must be greater than start.`);if(a!==e+1)throw new Error(`Packet block ${a} - ${r??a} is not contiguous. It should start from ${e+1}.`);for(e=r??a,v.debug(`Packet block ${a} - ${e} with label ${p}`);o.length<=i+1&&m.getPacket().length<K;){const[b,c]=O({start:a,end:r,label:p},s,i);if(o.push(b),b.end+1===s*i&&(m.pushWord(o),o=[],s++),!c)break;({start:a,end:r,label:p}=c)}}m.pushWord(o)},"populate"),O=n((t,e,o)=>{if(t.end===void 0&&(t.end=t.start),t.start>t.end)throw new Error(`Block start ${t.start} is greater than block end ${t.end}.`);return t.end+1<=e*o?[t,void 0]:[{start:t.start,end:e*o-1,label:t.label},{start:e*o,end:t.end,label:t.label}]},"getNextFittingBlock"),q={parse:n(async t=>{const e=await N("packet",t);v.debug(e),M(e)},"parse")},R=n((t,e,o,s)=>{const i=s.db,a=i.getConfig(),{rowHeight:r,paddingY:p,bitWidth:b,bitsPerRow:c}=a,u=i.getPacket(),l=i.getDiagramTitle(),g=r+p,d=g*(u.length+1)-(l?0:r),k=b*c+2,f=T(e);f.attr("viewbox",`0 0 ${k} ${d}`),D(f,d,k,a.useMaxWidth);for(const[$,y]of u.entries())U(f,y,$,a);f.append("text").text(l).attr("x",k/2).attr("y",d-g/2).attr("dominant-baseline","middle").attr("text-anchor","middle").attr("class","packetTitle")},"draw"),U=n((t,e,o,{rowHeight:s,paddingX:i,paddingY:a,bitWidth:r,bitsPerRow:p,showBits:b})=>{const c=t.append("g"),u=o*(s+a)+a;for(const l of e){const g=l.start%p*r+1,d=(l.end-l.start+1)*r-i;if(c.append("rect").attr("x",g).attr("y",u).attr("width",d).attr("height",s).attr("class","packetBlock"),c.append("text").attr("x",g+d/2).attr("y",u+s/2).attr("class","packetLabel").attr("dominant-baseline","middle").attr("text-anchor","middle").text(l.label),!b)continue;const k=l.end===l.start,f=u-2;c.append("text").attr("x",g+(k?d/2:0)).attr("y",f).attr("class","packetByte start").attr("dominant-baseline","auto").attr("text-anchor",k?"middle":"start").text(l.start),k||c.append("text").attr("x",g+d).attr("y",f).attr("class","packetByte end").attr("dominant-baseline","auto").attr("text-anchor","end").text(l.end)}},"drawWord"),X={draw:R},j={byteFontSize:"10px",startByteColor:"black",endByteColor:"black",labelColor:"black",labelFontSize:"12px",titleColor:"black",titleFontSize:"14px",blockStrokeColor:"black",blockStrokeWidth:"1",blockFillColor:"#efefef"},J=n(({packet:t}={})=>{const e=x(j,t);return`
|
||||
import{p as w}from"./chunk-4BMEZGHF-DM9xX3Iw.js";import{_ as n,s as B,g as S,t as F,q as z,a as P,b as W,F as x,K as T,e as D,z as _,G as A,H as E,l as v}from"./mermaid-vendor-CR44n-lC.js";import{p as N}from"./radar-MK3ICKWK-B97XRKGx.js";import"./feature-graph-wF7LCIjH.js";import"./react-vendor-DEwriMA6.js";import"./graph-vendor-B-X5JegA.js";import"./ui-vendor-CeCm8EER.js";import"./utils-vendor-BysuhMZA.js";import"./_baseUniq-BZ3hvks1.js";import"./_basePickBy-DV1dBXEu.js";import"./clone-eVzB-9-f.js";var C={packet:[]},h=structuredClone(C),L=E.packet,Y=n(()=>{const t=x({...L,...A().packet});return t.showBits&&(t.paddingY+=10),t},"getConfig"),G=n(()=>h.packet,"getPacket"),H=n(t=>{t.length>0&&h.packet.push(t)},"pushWord"),I=n(()=>{_(),h=structuredClone(C)},"clear"),m={pushWord:H,getPacket:G,getConfig:Y,clear:I,setAccTitle:W,getAccTitle:P,setDiagramTitle:z,getDiagramTitle:F,getAccDescription:S,setAccDescription:B},K=1e4,M=n(t=>{w(t,m);let e=-1,o=[],s=1;const{bitsPerRow:i}=m.getConfig();for(let{start:a,end:r,label:p}of t.blocks){if(r&&r<a)throw new Error(`Packet block ${a} - ${r} is invalid. End must be greater than start.`);if(a!==e+1)throw new Error(`Packet block ${a} - ${r??a} is not contiguous. It should start from ${e+1}.`);for(e=r??a,v.debug(`Packet block ${a} - ${e} with label ${p}`);o.length<=i+1&&m.getPacket().length<K;){const[b,c]=O({start:a,end:r,label:p},s,i);if(o.push(b),b.end+1===s*i&&(m.pushWord(o),o=[],s++),!c)break;({start:a,end:r,label:p}=c)}}m.pushWord(o)},"populate"),O=n((t,e,o)=>{if(t.end===void 0&&(t.end=t.start),t.start>t.end)throw new Error(`Block start ${t.start} is greater than block end ${t.end}.`);return t.end+1<=e*o?[t,void 0]:[{start:t.start,end:e*o-1,label:t.label},{start:e*o,end:t.end,label:t.label}]},"getNextFittingBlock"),q={parse:n(async t=>{const e=await N("packet",t);v.debug(e),M(e)},"parse")},R=n((t,e,o,s)=>{const i=s.db,a=i.getConfig(),{rowHeight:r,paddingY:p,bitWidth:b,bitsPerRow:c}=a,u=i.getPacket(),l=i.getDiagramTitle(),g=r+p,d=g*(u.length+1)-(l?0:r),k=b*c+2,f=T(e);f.attr("viewbox",`0 0 ${k} ${d}`),D(f,d,k,a.useMaxWidth);for(const[$,y]of u.entries())U(f,y,$,a);f.append("text").text(l).attr("x",k/2).attr("y",d-g/2).attr("dominant-baseline","middle").attr("text-anchor","middle").attr("class","packetTitle")},"draw"),U=n((t,e,o,{rowHeight:s,paddingX:i,paddingY:a,bitWidth:r,bitsPerRow:p,showBits:b})=>{const c=t.append("g"),u=o*(s+a)+a;for(const l of e){const g=l.start%p*r+1,d=(l.end-l.start+1)*r-i;if(c.append("rect").attr("x",g).attr("y",u).attr("width",d).attr("height",s).attr("class","packetBlock"),c.append("text").attr("x",g+d/2).attr("y",u+s/2).attr("class","packetLabel").attr("dominant-baseline","middle").attr("text-anchor","middle").text(l.label),!b)continue;const k=l.end===l.start,f=u-2;c.append("text").attr("x",g+(k?d/2:0)).attr("y",f).attr("class","packetByte start").attr("dominant-baseline","auto").attr("text-anchor",k?"middle":"start").text(l.start),k||c.append("text").attr("x",g+d).attr("y",f).attr("class","packetByte end").attr("dominant-baseline","auto").attr("text-anchor","end").text(l.end)}},"drawWord"),X={draw:R},j={byteFontSize:"10px",startByteColor:"black",endByteColor:"black",labelColor:"black",labelFontSize:"12px",titleColor:"black",titleFontSize:"14px",blockStrokeColor:"black",blockStrokeWidth:"1",blockFillColor:"#efefef"},J=n(({packet:t}={})=>{const e=x(j,t);return`
|
||||
.packetByte {
|
||||
font-size: ${e.byteFontSize};
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
10
lightrag/api/webui/assets/feature-retrieval-DdCvVec9.js
generated
Normal file
10
lightrag/api/webui/assets/feature-retrieval-DdCvVec9.js
generated
Normal file
File diff suppressed because one or more lines are too long
|
|
@ -1,4 +1,4 @@
|
|||
import{_ as m,o as O1,l as Z,c as Ge,d as Ce,p as H1,r as q1,u as i1,b as X1,s as Q1,q as J1,a as Z1,g as $1,t as et,k as tt,v as st,J as it,x as rt,y as s1,z as nt,A as at,B as ut,C as lt}from"./mermaid-vendor-D0f_SE0h.js";import{g as ot,s as ct}from"./chunk-RZ5BOZE2-B615FLH4.js";import"./feature-graph-NODQb6qW.js";import"./react-vendor-DEwriMA6.js";import"./graph-vendor-B-X5JegA.js";import"./ui-vendor-CeCm8EER.js";import"./utils-vendor-BysuhMZA.js";var ht="flowchart-",Pe,dt=(Pe=class{constructor(){this.vertexCounter=0,this.config=Ge(),this.vertices=new Map,this.edges=[],this.classes=new Map,this.subGraphs=[],this.subGraphLookup=new Map,this.tooltips=new Map,this.subCount=0,this.firstGraphFlag=!0,this.secCount=-1,this.posCrossRef=[],this.funs=[],this.setAccTitle=X1,this.setAccDescription=Q1,this.setDiagramTitle=J1,this.getAccTitle=Z1,this.getAccDescription=$1,this.getDiagramTitle=et,this.funs.push(this.setupToolTips.bind(this)),this.addVertex=this.addVertex.bind(this),this.firstGraph=this.firstGraph.bind(this),this.setDirection=this.setDirection.bind(this),this.addSubGraph=this.addSubGraph.bind(this),this.addLink=this.addLink.bind(this),this.setLink=this.setLink.bind(this),this.updateLink=this.updateLink.bind(this),this.addClass=this.addClass.bind(this),this.setClass=this.setClass.bind(this),this.destructLink=this.destructLink.bind(this),this.setClickEvent=this.setClickEvent.bind(this),this.setTooltip=this.setTooltip.bind(this),this.updateLinkInterpolate=this.updateLinkInterpolate.bind(this),this.setClickFun=this.setClickFun.bind(this),this.bindFunctions=this.bindFunctions.bind(this),this.lex={firstGraph:this.firstGraph.bind(this)},this.clear(),this.setGen("gen-2")}sanitizeText(i){return tt.sanitizeText(i,this.config)}lookUpDomId(i){for(const n of this.vertices.values())if(n.id===i)return n.domId;return i}addVertex(i,n,a,u,l,f,c={},A){var U,T;if(!i||i.trim().length===0)return;let r;if(A!==void 0){let d;A.includes(`
|
||||
import{_ as m,o as O1,l as Z,c as Ge,d as Ce,p as H1,r as q1,u as i1,b as X1,s as Q1,q as J1,a as Z1,g as $1,t as et,k as tt,v as st,J as it,x as rt,y as s1,z as nt,A as at,B as ut,C as lt}from"./mermaid-vendor-CR44n-lC.js";import{g as ot,s as ct}from"./chunk-RZ5BOZE2-CdnIs5Fb.js";import"./feature-graph-wF7LCIjH.js";import"./react-vendor-DEwriMA6.js";import"./graph-vendor-B-X5JegA.js";import"./ui-vendor-CeCm8EER.js";import"./utils-vendor-BysuhMZA.js";var ht="flowchart-",Pe,dt=(Pe=class{constructor(){this.vertexCounter=0,this.config=Ge(),this.vertices=new Map,this.edges=[],this.classes=new Map,this.subGraphs=[],this.subGraphLookup=new Map,this.tooltips=new Map,this.subCount=0,this.firstGraphFlag=!0,this.secCount=-1,this.posCrossRef=[],this.funs=[],this.setAccTitle=X1,this.setAccDescription=Q1,this.setDiagramTitle=J1,this.getAccTitle=Z1,this.getAccDescription=$1,this.getDiagramTitle=et,this.funs.push(this.setupToolTips.bind(this)),this.addVertex=this.addVertex.bind(this),this.firstGraph=this.firstGraph.bind(this),this.setDirection=this.setDirection.bind(this),this.addSubGraph=this.addSubGraph.bind(this),this.addLink=this.addLink.bind(this),this.setLink=this.setLink.bind(this),this.updateLink=this.updateLink.bind(this),this.addClass=this.addClass.bind(this),this.setClass=this.setClass.bind(this),this.destructLink=this.destructLink.bind(this),this.setClickEvent=this.setClickEvent.bind(this),this.setTooltip=this.setTooltip.bind(this),this.updateLinkInterpolate=this.updateLinkInterpolate.bind(this),this.setClickFun=this.setClickFun.bind(this),this.bindFunctions=this.bindFunctions.bind(this),this.lex={firstGraph:this.firstGraph.bind(this)},this.clear(),this.setGen("gen-2")}sanitizeText(i){return tt.sanitizeText(i,this.config)}lookUpDomId(i){for(const n of this.vertices.values())if(n.id===i)return n.domId;return i}addVertex(i,n,a,u,l,f,c={},A){var U,T;if(!i||i.trim().length===0)return;let r;if(A!==void 0){let d;A.includes(`
|
||||
`)?d=A+`
|
||||
`:d=`{
|
||||
`+A+`
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
|
@ -1,2 +1,2 @@
|
|||
import{_ as e,l as o,K as i,e as n,L as p}from"./mermaid-vendor-D0f_SE0h.js";import{p as m}from"./radar-MK3ICKWK-DOAXm8cx.js";import"./feature-graph-NODQb6qW.js";import"./react-vendor-DEwriMA6.js";import"./graph-vendor-B-X5JegA.js";import"./ui-vendor-CeCm8EER.js";import"./utils-vendor-BysuhMZA.js";import"./_baseUniq-CtAZZJ8e.js";import"./_basePickBy-D3PHsJjq.js";import"./clone-Dm5jEAXQ.js";var g={parse:e(async r=>{const a=await m("info",r);o.debug(a)},"parse")},v={version:p.version},d=e(()=>v.version,"getVersion"),c={getVersion:d},l=e((r,a,s)=>{o.debug(`rendering info diagram
|
||||
import{_ as e,l as o,K as i,e as n,L as p}from"./mermaid-vendor-CR44n-lC.js";import{p as m}from"./radar-MK3ICKWK-B97XRKGx.js";import"./feature-graph-wF7LCIjH.js";import"./react-vendor-DEwriMA6.js";import"./graph-vendor-B-X5JegA.js";import"./ui-vendor-CeCm8EER.js";import"./utils-vendor-BysuhMZA.js";import"./_baseUniq-BZ3hvks1.js";import"./_basePickBy-DV1dBXEu.js";import"./clone-eVzB-9-f.js";var g={parse:e(async r=>{const a=await m("info",r);o.debug(a)},"parse")},v={version:p.version},d=e(()=>v.version,"getVersion"),c={getVersion:d},l=e((r,a,s)=>{o.debug(`rendering info diagram
|
||||
`+r);const t=i(a);n(t,100,400,!0),t.append("g").append("text").attr("x",100).attr("y",40).attr("class","version").attr("font-size",32).style("text-anchor","middle").text(`v${s}`)},"draw"),f={draw:l},L={parser:g,db:c,renderer:f};export{L as diagram};
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
import{a as pt,g as at,f as gt,d as mt}from"./chunk-D6G4REZN-CGaqGId9.js";import{_ as s,g as xt,s as kt,a as _t,b as bt,t as vt,q as wt,c as A,d as W,e as Tt,z as St,N as tt}from"./mermaid-vendor-D0f_SE0h.js";import"./feature-graph-NODQb6qW.js";import"./react-vendor-DEwriMA6.js";import"./graph-vendor-B-X5JegA.js";import"./ui-vendor-CeCm8EER.js";import"./utils-vendor-BysuhMZA.js";var H=function(){var t=s(function(g,r,a,l){for(a=a||{},l=g.length;l--;a[g[l]]=r);return a},"o"),e=[6,8,10,11,12,14,16,17,18],i=[1,9],c=[1,10],n=[1,11],u=[1,12],h=[1,13],f=[1,14],d={trace:s(function(){},"trace"),yy:{},symbols_:{error:2,start:3,journey:4,document:5,EOF:6,line:7,SPACE:8,statement:9,NEWLINE:10,title:11,acc_title:12,acc_title_value:13,acc_descr:14,acc_descr_value:15,acc_descr_multiline_value:16,section:17,taskName:18,taskData:19,$accept:0,$end:1},terminals_:{2:"error",4:"journey",6:"EOF",8:"SPACE",10:"NEWLINE",11:"title",12:"acc_title",13:"acc_title_value",14:"acc_descr",15:"acc_descr_value",16:"acc_descr_multiline_value",17:"section",18:"taskName",19:"taskData"},productions_:[0,[3,3],[5,0],[5,2],[7,2],[7,1],[7,1],[7,1],[9,1],[9,2],[9,2],[9,1],[9,1],[9,2]],performAction:s(function(r,a,l,y,p,o,S){var _=o.length-1;switch(p){case 1:return o[_-1];case 2:this.$=[];break;case 3:o[_-1].push(o[_]),this.$=o[_-1];break;case 4:case 5:this.$=o[_];break;case 6:case 7:this.$=[];break;case 8:y.setDiagramTitle(o[_].substr(6)),this.$=o[_].substr(6);break;case 9:this.$=o[_].trim(),y.setAccTitle(this.$);break;case 10:case 11:this.$=o[_].trim(),y.setAccDescription(this.$);break;case 12:y.addSection(o[_].substr(8)),this.$=o[_].substr(8);break;case 13:y.addTask(o[_-1],o[_]),this.$="task";break}},"anonymous"),table:[{3:1,4:[1,2]},{1:[3]},t(e,[2,2],{5:3}),{6:[1,4],7:5,8:[1,6],9:7,10:[1,8],11:i,12:c,14:n,16:u,17:h,18:f},t(e,[2,7],{1:[2,1]}),t(e,[2,3]),{9:15,11:i,12:c,14:n,16:u,17:h,18:f},t(e,[2,5]),t(e,[2,6]),t(e,[2,8]),{13:[1,16]},{15:[1,17]},t(e,[2,11]),t(e,[2,12]),{19:[1,18]},t(e,[2,4]),t(e,[2,9]),t(e,[2,10]),t(e,[2,13])],defaultActions:{},parseError:s(function(r,a){if(a.recoverable)this.trace(r);else{var l=new Error(r);throw l.hash=a,l}},"parseError"),parse:s(function(r){var a=this,l=[0],y=[],p=[null],o=[],S=this.table,_="",B=0,J=0,ut=2,K=1,yt=o.slice.call(arguments,1),k=Object.create(this.lexer),E={yy:{}};for(var O in this.yy)Object.prototype.hasOwnProperty.call(this.yy,O)&&(E.yy[O]=this.yy[O]);k.setInput(r,E.yy),E.yy.lexer=k,E.yy.parser=this,typeof k.yylloc>"u"&&(k.yylloc={});var Y=k.yylloc;o.push(Y);var dt=k.options&&k.options.ranges;typeof E.yy.parseError=="function"?this.parseError=E.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;function ft(v){l.length=l.length-2*v,p.length=p.length-v,o.length=o.length-v}s(ft,"popStack");function Q(){var v;return v=y.pop()||k.lex()||K,typeof v!="number"&&(v instanceof Array&&(y=v,v=y.pop()),v=a.symbols_[v]||v),v}s(Q,"lex");for(var b,P,w,q,C={},N,$,D,j;;){if(P=l[l.length-1],this.defaultActions[P]?w=this.defaultActions[P]:((b===null||typeof b>"u")&&(b=Q()),w=S[P]&&S[P][b]),typeof w>"u"||!w.length||!w[0]){var G="";j=[];for(N in S[P])this.terminals_[N]&&N>ut&&j.push("'"+this.terminals_[N]+"'");k.showPosition?G="Parse error on line "+(B+1)+`:
|
||||
import{a as pt,g as at,f as gt,d as mt}from"./chunk-D6G4REZN-5j_Vlndu.js";import{_ as s,g as xt,s as kt,a as _t,b as bt,t as vt,q as wt,c as A,d as W,e as Tt,z as St,N as tt}from"./mermaid-vendor-CR44n-lC.js";import"./feature-graph-wF7LCIjH.js";import"./react-vendor-DEwriMA6.js";import"./graph-vendor-B-X5JegA.js";import"./ui-vendor-CeCm8EER.js";import"./utils-vendor-BysuhMZA.js";var H=function(){var t=s(function(g,r,a,l){for(a=a||{},l=g.length;l--;a[g[l]]=r);return a},"o"),e=[6,8,10,11,12,14,16,17,18],i=[1,9],c=[1,10],n=[1,11],u=[1,12],h=[1,13],f=[1,14],d={trace:s(function(){},"trace"),yy:{},symbols_:{error:2,start:3,journey:4,document:5,EOF:6,line:7,SPACE:8,statement:9,NEWLINE:10,title:11,acc_title:12,acc_title_value:13,acc_descr:14,acc_descr_value:15,acc_descr_multiline_value:16,section:17,taskName:18,taskData:19,$accept:0,$end:1},terminals_:{2:"error",4:"journey",6:"EOF",8:"SPACE",10:"NEWLINE",11:"title",12:"acc_title",13:"acc_title_value",14:"acc_descr",15:"acc_descr_value",16:"acc_descr_multiline_value",17:"section",18:"taskName",19:"taskData"},productions_:[0,[3,3],[5,0],[5,2],[7,2],[7,1],[7,1],[7,1],[9,1],[9,2],[9,2],[9,1],[9,1],[9,2]],performAction:s(function(r,a,l,y,p,o,S){var _=o.length-1;switch(p){case 1:return o[_-1];case 2:this.$=[];break;case 3:o[_-1].push(o[_]),this.$=o[_-1];break;case 4:case 5:this.$=o[_];break;case 6:case 7:this.$=[];break;case 8:y.setDiagramTitle(o[_].substr(6)),this.$=o[_].substr(6);break;case 9:this.$=o[_].trim(),y.setAccTitle(this.$);break;case 10:case 11:this.$=o[_].trim(),y.setAccDescription(this.$);break;case 12:y.addSection(o[_].substr(8)),this.$=o[_].substr(8);break;case 13:y.addTask(o[_-1],o[_]),this.$="task";break}},"anonymous"),table:[{3:1,4:[1,2]},{1:[3]},t(e,[2,2],{5:3}),{6:[1,4],7:5,8:[1,6],9:7,10:[1,8],11:i,12:c,14:n,16:u,17:h,18:f},t(e,[2,7],{1:[2,1]}),t(e,[2,3]),{9:15,11:i,12:c,14:n,16:u,17:h,18:f},t(e,[2,5]),t(e,[2,6]),t(e,[2,8]),{13:[1,16]},{15:[1,17]},t(e,[2,11]),t(e,[2,12]),{19:[1,18]},t(e,[2,4]),t(e,[2,9]),t(e,[2,10]),t(e,[2,13])],defaultActions:{},parseError:s(function(r,a){if(a.recoverable)this.trace(r);else{var l=new Error(r);throw l.hash=a,l}},"parseError"),parse:s(function(r){var a=this,l=[0],y=[],p=[null],o=[],S=this.table,_="",B=0,J=0,ut=2,K=1,yt=o.slice.call(arguments,1),k=Object.create(this.lexer),E={yy:{}};for(var O in this.yy)Object.prototype.hasOwnProperty.call(this.yy,O)&&(E.yy[O]=this.yy[O]);k.setInput(r,E.yy),E.yy.lexer=k,E.yy.parser=this,typeof k.yylloc>"u"&&(k.yylloc={});var Y=k.yylloc;o.push(Y);var dt=k.options&&k.options.ranges;typeof E.yy.parseError=="function"?this.parseError=E.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;function ft(v){l.length=l.length-2*v,p.length=p.length-v,o.length=o.length-v}s(ft,"popStack");function Q(){var v;return v=y.pop()||k.lex()||K,typeof v!="number"&&(v instanceof Array&&(y=v,v=y.pop()),v=a.symbols_[v]||v),v}s(Q,"lex");for(var b,P,w,q,C={},N,$,D,j;;){if(P=l[l.length-1],this.defaultActions[P]?w=this.defaultActions[P]:((b===null||typeof b>"u")&&(b=Q()),w=S[P]&&S[P][b]),typeof w>"u"||!w.length||!w[0]){var G="";j=[];for(N in S[P])this.terminals_[N]&&N>ut&&j.push("'"+this.terminals_[N]+"'");k.showPosition?G="Parse error on line "+(B+1)+`:
|
||||
`+k.showPosition()+`
|
||||
Expecting `+j.join(", ")+", got '"+(this.terminals_[b]||b)+"'":G="Parse error on line "+(B+1)+": Unexpected "+(b==K?"end of input":"'"+(this.terminals_[b]||b)+"'"),this.parseError(G,{text:k.match,token:this.terminals_[b]||b,line:k.yylineno,loc:Y,expected:j})}if(w[0]instanceof Array&&w.length>1)throw new Error("Parse Error: multiple actions possible at state: "+P+", token: "+b);switch(w[0]){case 1:l.push(b),p.push(k.yytext),o.push(k.yylloc),l.push(w[1]),b=null,J=k.yyleng,_=k.yytext,B=k.yylineno,Y=k.yylloc;break;case 2:if($=this.productions_[w[1]][1],C.$=p[p.length-$],C._$={first_line:o[o.length-($||1)].first_line,last_line:o[o.length-1].last_line,first_column:o[o.length-($||1)].first_column,last_column:o[o.length-1].last_column},dt&&(C._$.range=[o[o.length-($||1)].range[0],o[o.length-1].range[1]]),q=this.performAction.apply(C,[_,J,B,E.yy,w[1],p,o].concat(yt)),typeof q<"u")return q;$&&(l=l.slice(0,-1*$*2),p=p.slice(0,-1*$),o=o.slice(0,-1*$)),l.push(this.productions_[w[1]][0]),p.push(C.$),o.push(C._$),D=S[l[l.length-2]][l[l.length-1]],l.push(D);break;case 3:return!0}}return!0},"parse")},x=function(){var g={EOF:1,parseError:s(function(a,l){if(this.yy.parser)this.yy.parser.parseError(a,l);else throw new Error(a)},"parseError"),setInput:s(function(r,a){return this.yy=a||this.yy||{},this._input=r,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},"setInput"),input:s(function(){var r=this._input[0];this.yytext+=r,this.yyleng++,this.offset++,this.match+=r,this.matched+=r;var a=r.match(/(?:\r\n?|\n).*/g);return a?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),r},"input"),unput:s(function(r){var a=r.length,l=r.split(/(?:\r\n?|\n)/g);this._input=r+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-a),this.offset-=a;var y=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),l.length-1&&(this.yylineno-=l.length-1);var p=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:l?(l.length===y.length?this.yylloc.first_column:0)+y[y.length-l.length].length-l[0].length:this.yylloc.first_column-a},this.options.ranges&&(this.yylloc.range=[p[0],p[0]+this.yyleng-a]),this.yyleng=this.yytext.length,this},"unput"),more:s(function(){return this._more=!0,this},"more"),reject:s(function(){if(this.options.backtrack_lexer)this._backtrack=!0;else return this.parseError("Lexical error on line "+(this.yylineno+1)+`. You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).
|
||||
`+this.showPosition(),{text:"",token:null,line:this.yylineno});return this},"reject"),less:s(function(r){this.unput(this.match.slice(r))},"less"),pastInput:s(function(){var r=this.matched.substr(0,this.matched.length-this.match.length);return(r.length>20?"...":"")+r.substr(-20).replace(/\n/g,"")},"pastInput"),upcomingInput:s(function(){var r=this.match;return r.length<20&&(r+=this._input.substr(0,20-r.length)),(r.substr(0,20)+(r.length>20?"...":"")).replace(/\n/g,"")},"upcomingInput"),showPosition:s(function(){var r=this.pastInput(),a=new Array(r.length+1).join("-");return r+this.upcomingInput()+`
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
import{_ as c,l as te,c as W,K as fe,a7 as ye,a8 as be,a9 as me,a2 as _e,H as Y,i as G,v as Ee,J as ke,a3 as Se,a4 as le,a5 as ce}from"./mermaid-vendor-D0f_SE0h.js";import"./feature-graph-NODQb6qW.js";import"./react-vendor-DEwriMA6.js";import"./graph-vendor-B-X5JegA.js";import"./ui-vendor-CeCm8EER.js";import"./utils-vendor-BysuhMZA.js";var $=function(){var t=c(function(_,i,n,a){for(n=n||{},a=_.length;a--;n[_[a]]=i);return n},"o"),g=[1,4],d=[1,13],r=[1,12],p=[1,15],E=[1,16],f=[1,20],h=[1,19],L=[6,7,8],C=[1,26],w=[1,24],N=[1,25],s=[6,7,11],H=[1,31],x=[6,7,11,24],P=[1,6,13,16,17,20,23],M=[1,35],U=[1,36],A=[1,6,7,11,13,16,17,20,23],j=[1,38],V={trace:c(function(){},"trace"),yy:{},symbols_:{error:2,start:3,mindMap:4,spaceLines:5,SPACELINE:6,NL:7,KANBAN:8,document:9,stop:10,EOF:11,statement:12,SPACELIST:13,node:14,shapeData:15,ICON:16,CLASS:17,nodeWithId:18,nodeWithoutId:19,NODE_DSTART:20,NODE_DESCR:21,NODE_DEND:22,NODE_ID:23,SHAPE_DATA:24,$accept:0,$end:1},terminals_:{2:"error",6:"SPACELINE",7:"NL",8:"KANBAN",11:"EOF",13:"SPACELIST",16:"ICON",17:"CLASS",20:"NODE_DSTART",21:"NODE_DESCR",22:"NODE_DEND",23:"NODE_ID",24:"SHAPE_DATA"},productions_:[0,[3,1],[3,2],[5,1],[5,2],[5,2],[4,2],[4,3],[10,1],[10,1],[10,1],[10,2],[10,2],[9,3],[9,2],[12,3],[12,2],[12,2],[12,2],[12,1],[12,2],[12,1],[12,1],[12,1],[12,1],[14,1],[14,1],[19,3],[18,1],[18,4],[15,2],[15,1]],performAction:c(function(i,n,a,o,u,e,B){var l=e.length-1;switch(u){case 6:case 7:return o;case 8:o.getLogger().trace("Stop NL ");break;case 9:o.getLogger().trace("Stop EOF ");break;case 11:o.getLogger().trace("Stop NL2 ");break;case 12:o.getLogger().trace("Stop EOF2 ");break;case 15:o.getLogger().info("Node: ",e[l-1].id),o.addNode(e[l-2].length,e[l-1].id,e[l-1].descr,e[l-1].type,e[l]);break;case 16:o.getLogger().info("Node: ",e[l].id),o.addNode(e[l-1].length,e[l].id,e[l].descr,e[l].type);break;case 17:o.getLogger().trace("Icon: ",e[l]),o.decorateNode({icon:e[l]});break;case 18:case 23:o.decorateNode({class:e[l]});break;case 19:o.getLogger().trace("SPACELIST");break;case 20:o.getLogger().trace("Node: ",e[l-1].id),o.addNode(0,e[l-1].id,e[l-1].descr,e[l-1].type,e[l]);break;case 21:o.getLogger().trace("Node: ",e[l].id),o.addNode(0,e[l].id,e[l].descr,e[l].type);break;case 22:o.decorateNode({icon:e[l]});break;case 27:o.getLogger().trace("node found ..",e[l-2]),this.$={id:e[l-1],descr:e[l-1],type:o.getType(e[l-2],e[l])};break;case 28:this.$={id:e[l],descr:e[l],type:0};break;case 29:o.getLogger().trace("node found ..",e[l-3]),this.$={id:e[l-3],descr:e[l-1],type:o.getType(e[l-2],e[l])};break;case 30:this.$=e[l-1]+e[l];break;case 31:this.$=e[l];break}},"anonymous"),table:[{3:1,4:2,5:3,6:[1,5],8:g},{1:[3]},{1:[2,1]},{4:6,6:[1,7],7:[1,8],8:g},{6:d,7:[1,10],9:9,12:11,13:r,14:14,16:p,17:E,18:17,19:18,20:f,23:h},t(L,[2,3]),{1:[2,2]},t(L,[2,4]),t(L,[2,5]),{1:[2,6],6:d,12:21,13:r,14:14,16:p,17:E,18:17,19:18,20:f,23:h},{6:d,9:22,12:11,13:r,14:14,16:p,17:E,18:17,19:18,20:f,23:h},{6:C,7:w,10:23,11:N},t(s,[2,24],{18:17,19:18,14:27,16:[1,28],17:[1,29],20:f,23:h}),t(s,[2,19]),t(s,[2,21],{15:30,24:H}),t(s,[2,22]),t(s,[2,23]),t(x,[2,25]),t(x,[2,26]),t(x,[2,28],{20:[1,32]}),{21:[1,33]},{6:C,7:w,10:34,11:N},{1:[2,7],6:d,12:21,13:r,14:14,16:p,17:E,18:17,19:18,20:f,23:h},t(P,[2,14],{7:M,11:U}),t(A,[2,8]),t(A,[2,9]),t(A,[2,10]),t(s,[2,16],{15:37,24:H}),t(s,[2,17]),t(s,[2,18]),t(s,[2,20],{24:j}),t(x,[2,31]),{21:[1,39]},{22:[1,40]},t(P,[2,13],{7:M,11:U}),t(A,[2,11]),t(A,[2,12]),t(s,[2,15],{24:j}),t(x,[2,30]),{22:[1,41]},t(x,[2,27]),t(x,[2,29])],defaultActions:{2:[2,1],6:[2,2]},parseError:c(function(i,n){if(n.recoverable)this.trace(i);else{var a=new Error(i);throw a.hash=n,a}},"parseError"),parse:c(function(i){var n=this,a=[0],o=[],u=[null],e=[],B=this.table,l="",z=0,se=0,ue=2,re=1,ge=e.slice.call(arguments,1),b=Object.create(this.lexer),T={yy:{}};for(var J in this.yy)Object.prototype.hasOwnProperty.call(this.yy,J)&&(T.yy[J]=this.yy[J]);b.setInput(i,T.yy),T.yy.lexer=b,T.yy.parser=this,typeof b.yylloc>"u"&&(b.yylloc={});var q=b.yylloc;e.push(q);var de=b.options&&b.options.ranges;typeof T.yy.parseError=="function"?this.parseError=T.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;function pe(S){a.length=a.length-2*S,u.length=u.length-S,e.length=e.length-S}c(pe,"popStack");function ae(){var S;return S=o.pop()||b.lex()||re,typeof S!="number"&&(S instanceof Array&&(o=S,S=o.pop()),S=n.symbols_[S]||S),S}c(ae,"lex");for(var k,R,v,Q,F={},K,I,oe,X;;){if(R=a[a.length-1],this.defaultActions[R]?v=this.defaultActions[R]:((k===null||typeof k>"u")&&(k=ae()),v=B[R]&&B[R][k]),typeof v>"u"||!v.length||!v[0]){var Z="";X=[];for(K in B[R])this.terminals_[K]&&K>ue&&X.push("'"+this.terminals_[K]+"'");b.showPosition?Z="Parse error on line "+(z+1)+`:
|
||||
import{_ as c,l as te,c as W,K as fe,a7 as ye,a8 as be,a9 as me,a2 as _e,H as Y,i as G,v as Ee,J as ke,a3 as Se,a4 as le,a5 as ce}from"./mermaid-vendor-CR44n-lC.js";import"./feature-graph-wF7LCIjH.js";import"./react-vendor-DEwriMA6.js";import"./graph-vendor-B-X5JegA.js";import"./ui-vendor-CeCm8EER.js";import"./utils-vendor-BysuhMZA.js";var $=function(){var t=c(function(_,i,n,a){for(n=n||{},a=_.length;a--;n[_[a]]=i);return n},"o"),g=[1,4],d=[1,13],r=[1,12],p=[1,15],E=[1,16],f=[1,20],h=[1,19],L=[6,7,8],C=[1,26],w=[1,24],N=[1,25],s=[6,7,11],H=[1,31],x=[6,7,11,24],P=[1,6,13,16,17,20,23],M=[1,35],U=[1,36],A=[1,6,7,11,13,16,17,20,23],j=[1,38],V={trace:c(function(){},"trace"),yy:{},symbols_:{error:2,start:3,mindMap:4,spaceLines:5,SPACELINE:6,NL:7,KANBAN:8,document:9,stop:10,EOF:11,statement:12,SPACELIST:13,node:14,shapeData:15,ICON:16,CLASS:17,nodeWithId:18,nodeWithoutId:19,NODE_DSTART:20,NODE_DESCR:21,NODE_DEND:22,NODE_ID:23,SHAPE_DATA:24,$accept:0,$end:1},terminals_:{2:"error",6:"SPACELINE",7:"NL",8:"KANBAN",11:"EOF",13:"SPACELIST",16:"ICON",17:"CLASS",20:"NODE_DSTART",21:"NODE_DESCR",22:"NODE_DEND",23:"NODE_ID",24:"SHAPE_DATA"},productions_:[0,[3,1],[3,2],[5,1],[5,2],[5,2],[4,2],[4,3],[10,1],[10,1],[10,1],[10,2],[10,2],[9,3],[9,2],[12,3],[12,2],[12,2],[12,2],[12,1],[12,2],[12,1],[12,1],[12,1],[12,1],[14,1],[14,1],[19,3],[18,1],[18,4],[15,2],[15,1]],performAction:c(function(i,n,a,o,u,e,B){var l=e.length-1;switch(u){case 6:case 7:return o;case 8:o.getLogger().trace("Stop NL ");break;case 9:o.getLogger().trace("Stop EOF ");break;case 11:o.getLogger().trace("Stop NL2 ");break;case 12:o.getLogger().trace("Stop EOF2 ");break;case 15:o.getLogger().info("Node: ",e[l-1].id),o.addNode(e[l-2].length,e[l-1].id,e[l-1].descr,e[l-1].type,e[l]);break;case 16:o.getLogger().info("Node: ",e[l].id),o.addNode(e[l-1].length,e[l].id,e[l].descr,e[l].type);break;case 17:o.getLogger().trace("Icon: ",e[l]),o.decorateNode({icon:e[l]});break;case 18:case 23:o.decorateNode({class:e[l]});break;case 19:o.getLogger().trace("SPACELIST");break;case 20:o.getLogger().trace("Node: ",e[l-1].id),o.addNode(0,e[l-1].id,e[l-1].descr,e[l-1].type,e[l]);break;case 21:o.getLogger().trace("Node: ",e[l].id),o.addNode(0,e[l].id,e[l].descr,e[l].type);break;case 22:o.decorateNode({icon:e[l]});break;case 27:o.getLogger().trace("node found ..",e[l-2]),this.$={id:e[l-1],descr:e[l-1],type:o.getType(e[l-2],e[l])};break;case 28:this.$={id:e[l],descr:e[l],type:0};break;case 29:o.getLogger().trace("node found ..",e[l-3]),this.$={id:e[l-3],descr:e[l-1],type:o.getType(e[l-2],e[l])};break;case 30:this.$=e[l-1]+e[l];break;case 31:this.$=e[l];break}},"anonymous"),table:[{3:1,4:2,5:3,6:[1,5],8:g},{1:[3]},{1:[2,1]},{4:6,6:[1,7],7:[1,8],8:g},{6:d,7:[1,10],9:9,12:11,13:r,14:14,16:p,17:E,18:17,19:18,20:f,23:h},t(L,[2,3]),{1:[2,2]},t(L,[2,4]),t(L,[2,5]),{1:[2,6],6:d,12:21,13:r,14:14,16:p,17:E,18:17,19:18,20:f,23:h},{6:d,9:22,12:11,13:r,14:14,16:p,17:E,18:17,19:18,20:f,23:h},{6:C,7:w,10:23,11:N},t(s,[2,24],{18:17,19:18,14:27,16:[1,28],17:[1,29],20:f,23:h}),t(s,[2,19]),t(s,[2,21],{15:30,24:H}),t(s,[2,22]),t(s,[2,23]),t(x,[2,25]),t(x,[2,26]),t(x,[2,28],{20:[1,32]}),{21:[1,33]},{6:C,7:w,10:34,11:N},{1:[2,7],6:d,12:21,13:r,14:14,16:p,17:E,18:17,19:18,20:f,23:h},t(P,[2,14],{7:M,11:U}),t(A,[2,8]),t(A,[2,9]),t(A,[2,10]),t(s,[2,16],{15:37,24:H}),t(s,[2,17]),t(s,[2,18]),t(s,[2,20],{24:j}),t(x,[2,31]),{21:[1,39]},{22:[1,40]},t(P,[2,13],{7:M,11:U}),t(A,[2,11]),t(A,[2,12]),t(s,[2,15],{24:j}),t(x,[2,30]),{22:[1,41]},t(x,[2,27]),t(x,[2,29])],defaultActions:{2:[2,1],6:[2,2]},parseError:c(function(i,n){if(n.recoverable)this.trace(i);else{var a=new Error(i);throw a.hash=n,a}},"parseError"),parse:c(function(i){var n=this,a=[0],o=[],u=[null],e=[],B=this.table,l="",z=0,se=0,ue=2,re=1,ge=e.slice.call(arguments,1),b=Object.create(this.lexer),T={yy:{}};for(var J in this.yy)Object.prototype.hasOwnProperty.call(this.yy,J)&&(T.yy[J]=this.yy[J]);b.setInput(i,T.yy),T.yy.lexer=b,T.yy.parser=this,typeof b.yylloc>"u"&&(b.yylloc={});var q=b.yylloc;e.push(q);var de=b.options&&b.options.ranges;typeof T.yy.parseError=="function"?this.parseError=T.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;function pe(S){a.length=a.length-2*S,u.length=u.length-S,e.length=e.length-S}c(pe,"popStack");function ae(){var S;return S=o.pop()||b.lex()||re,typeof S!="number"&&(S instanceof Array&&(o=S,S=o.pop()),S=n.symbols_[S]||S),S}c(ae,"lex");for(var k,R,v,Q,F={},K,I,oe,X;;){if(R=a[a.length-1],this.defaultActions[R]?v=this.defaultActions[R]:((k===null||typeof k>"u")&&(k=ae()),v=B[R]&&B[R][k]),typeof v>"u"||!v.length||!v[0]){var Z="";X=[];for(K in B[R])this.terminals_[K]&&K>ue&&X.push("'"+this.terminals_[K]+"'");b.showPosition?Z="Parse error on line "+(z+1)+`:
|
||||
`+b.showPosition()+`
|
||||
Expecting `+X.join(", ")+", got '"+(this.terminals_[k]||k)+"'":Z="Parse error on line "+(z+1)+": Unexpected "+(k==re?"end of input":"'"+(this.terminals_[k]||k)+"'"),this.parseError(Z,{text:b.match,token:this.terminals_[k]||k,line:b.yylineno,loc:q,expected:X})}if(v[0]instanceof Array&&v.length>1)throw new Error("Parse Error: multiple actions possible at state: "+R+", token: "+k);switch(v[0]){case 1:a.push(k),u.push(b.yytext),e.push(b.yylloc),a.push(v[1]),k=null,se=b.yyleng,l=b.yytext,z=b.yylineno,q=b.yylloc;break;case 2:if(I=this.productions_[v[1]][1],F.$=u[u.length-I],F._$={first_line:e[e.length-(I||1)].first_line,last_line:e[e.length-1].last_line,first_column:e[e.length-(I||1)].first_column,last_column:e[e.length-1].last_column},de&&(F._$.range=[e[e.length-(I||1)].range[0],e[e.length-1].range[1]]),Q=this.performAction.apply(F,[l,se,z,T.yy,v[1],u,e].concat(ge)),typeof Q<"u")return Q;I&&(a=a.slice(0,-1*I*2),u=u.slice(0,-1*I),e=e.slice(0,-1*I)),a.push(this.productions_[v[1]][0]),u.push(F.$),e.push(F._$),oe=B[a[a.length-2]][a[a.length-1]],a.push(oe);break;case 3:return!0}}return!0},"parse")},m=function(){var _={EOF:1,parseError:c(function(n,a){if(this.yy.parser)this.yy.parser.parseError(n,a);else throw new Error(n)},"parseError"),setInput:c(function(i,n){return this.yy=n||this.yy||{},this._input=i,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},"setInput"),input:c(function(){var i=this._input[0];this.yytext+=i,this.yyleng++,this.offset++,this.match+=i,this.matched+=i;var n=i.match(/(?:\r\n?|\n).*/g);return n?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),i},"input"),unput:c(function(i){var n=i.length,a=i.split(/(?:\r\n?|\n)/g);this._input=i+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-n),this.offset-=n;var o=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),a.length-1&&(this.yylineno-=a.length-1);var u=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:a?(a.length===o.length?this.yylloc.first_column:0)+o[o.length-a.length].length-a[0].length:this.yylloc.first_column-n},this.options.ranges&&(this.yylloc.range=[u[0],u[0]+this.yyleng-n]),this.yyleng=this.yytext.length,this},"unput"),more:c(function(){return this._more=!0,this},"more"),reject:c(function(){if(this.options.backtrack_lexer)this._backtrack=!0;else return this.parseError("Lexical error on line "+(this.yylineno+1)+`. You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).
|
||||
`+this.showPosition(),{text:"",token:null,line:this.yylineno});return this},"reject"),less:c(function(i){this.unput(this.match.slice(i))},"less"),pastInput:c(function(){var i=this.matched.substr(0,this.matched.length-this.match.length);return(i.length>20?"...":"")+i.substr(-20).replace(/\n/g,"")},"pastInput"),upcomingInput:c(function(){var i=this.match;return i.length<20&&(i+=this._input.substr(0,20-i.length)),(i.substr(0,20)+(i.length>20?"...":"")).replace(/\n/g,"")},"upcomingInput"),showPosition:c(function(){var i=this.pastInput(),n=new Array(i.length+1).join("-");return i+this.upcomingInput()+`
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
|
@ -1,4 +1,4 @@
|
|||
import{p as N}from"./chunk-4BMEZGHF-CAhtCpmT.js";import{_ as i,g as B,s as U,a as q,b as H,t as K,q as V,l as C,c as Z,F as j,K as J,M as Q,N as z,O as X,e as Y,z as tt,P as et,H as at}from"./mermaid-vendor-D0f_SE0h.js";import{p as rt}from"./radar-MK3ICKWK-DOAXm8cx.js";import"./feature-graph-NODQb6qW.js";import"./react-vendor-DEwriMA6.js";import"./graph-vendor-B-X5JegA.js";import"./ui-vendor-CeCm8EER.js";import"./utils-vendor-BysuhMZA.js";import"./_baseUniq-CtAZZJ8e.js";import"./_basePickBy-D3PHsJjq.js";import"./clone-Dm5jEAXQ.js";var it=at.pie,D={sections:new Map,showData:!1},f=D.sections,w=D.showData,st=structuredClone(it),ot=i(()=>structuredClone(st),"getConfig"),nt=i(()=>{f=new Map,w=D.showData,tt()},"clear"),lt=i(({label:t,value:a})=>{f.has(t)||(f.set(t,a),C.debug(`added new section: ${t}, with value: ${a}`))},"addSection"),ct=i(()=>f,"getSections"),pt=i(t=>{w=t},"setShowData"),dt=i(()=>w,"getShowData"),F={getConfig:ot,clear:nt,setDiagramTitle:V,getDiagramTitle:K,setAccTitle:H,getAccTitle:q,setAccDescription:U,getAccDescription:B,addSection:lt,getSections:ct,setShowData:pt,getShowData:dt},gt=i((t,a)=>{N(t,a),a.setShowData(t.showData),t.sections.map(a.addSection)},"populateDb"),ut={parse:i(async t=>{const a=await rt("pie",t);C.debug(a),gt(a,F)},"parse")},mt=i(t=>`
|
||||
import{p as N}from"./chunk-4BMEZGHF-DM9xX3Iw.js";import{_ as i,g as B,s as U,a as q,b as H,t as K,q as V,l as C,c as Z,F as j,K as J,M as Q,N as z,O as X,e as Y,z as tt,P as et,H as at}from"./mermaid-vendor-CR44n-lC.js";import{p as rt}from"./radar-MK3ICKWK-B97XRKGx.js";import"./feature-graph-wF7LCIjH.js";import"./react-vendor-DEwriMA6.js";import"./graph-vendor-B-X5JegA.js";import"./ui-vendor-CeCm8EER.js";import"./utils-vendor-BysuhMZA.js";import"./_baseUniq-BZ3hvks1.js";import"./_basePickBy-DV1dBXEu.js";import"./clone-eVzB-9-f.js";var it=at.pie,D={sections:new Map,showData:!1},f=D.sections,w=D.showData,st=structuredClone(it),ot=i(()=>structuredClone(st),"getConfig"),nt=i(()=>{f=new Map,w=D.showData,tt()},"clear"),lt=i(({label:t,value:a})=>{f.has(t)||(f.set(t,a),C.debug(`added new section: ${t}, with value: ${a}`))},"addSection"),ct=i(()=>f,"getSections"),pt=i(t=>{w=t},"setShowData"),dt=i(()=>w,"getShowData"),F={getConfig:ot,clear:nt,setDiagramTitle:V,getDiagramTitle:K,setAccTitle:H,getAccTitle:q,setAccDescription:U,getAccDescription:B,addSection:lt,getSections:ct,setShowData:pt,getShowData:dt},gt=i((t,a)=>{N(t,a),a.setShowData(t.showData),t.sections.map(a.addSection)},"populateDb"),ut={parse:i(async t=>{const a=await rt("pie",t);C.debug(a),gt(a,F)},"parse")},mt=i(t=>`
|
||||
.pieCircle{
|
||||
stroke: ${t.pieStrokeColor};
|
||||
stroke-width : ${t.pieStrokeWidth};
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
|
@ -1 +1 @@
|
|||
import{s as r,b as e,a,S as s}from"./chunk-AEK57VVT-gQ4j2jcG.js";import{_ as i}from"./mermaid-vendor-D0f_SE0h.js";import"./chunk-RZ5BOZE2-B615FLH4.js";import"./feature-graph-NODQb6qW.js";import"./react-vendor-DEwriMA6.js";import"./graph-vendor-B-X5JegA.js";import"./ui-vendor-CeCm8EER.js";import"./utils-vendor-BysuhMZA.js";var b={parser:a,get db(){return new s(2)},renderer:e,styles:r,init:i(t=>{t.state||(t.state={}),t.state.arrowMarkerAbsolute=t.arrowMarkerAbsolute},"init")};export{b as diagram};
|
||||
import{s as r,b as e,a,S as s}from"./chunk-AEK57VVT-DlsJi6tH.js";import{_ as i}from"./mermaid-vendor-CR44n-lC.js";import"./chunk-RZ5BOZE2-CdnIs5Fb.js";import"./feature-graph-wF7LCIjH.js";import"./react-vendor-DEwriMA6.js";import"./graph-vendor-B-X5JegA.js";import"./ui-vendor-CeCm8EER.js";import"./utils-vendor-BysuhMZA.js";var b={parser:a,get db(){return new s(2)},renderer:e,styles:r,init:i(t=>{t.state||(t.state={}),t.state.arrowMarkerAbsolute=t.arrowMarkerAbsolute},"init")};export{b as diagram};
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
import{_ as s,c as xt,l as T,d as q,a2 as kt,a3 as _t,a4 as bt,a5 as vt,N as nt,D as wt,a6 as St,z as Et}from"./mermaid-vendor-D0f_SE0h.js";import"./feature-graph-NODQb6qW.js";import"./react-vendor-DEwriMA6.js";import"./graph-vendor-B-X5JegA.js";import"./ui-vendor-CeCm8EER.js";import"./utils-vendor-BysuhMZA.js";var X=function(){var n=s(function(f,i,a,d){for(a=a||{},d=f.length;d--;a[f[d]]=i);return a},"o"),t=[6,8,10,11,12,14,16,17,20,21],e=[1,9],l=[1,10],r=[1,11],h=[1,12],c=[1,13],g=[1,16],m=[1,17],p={trace:s(function(){},"trace"),yy:{},symbols_:{error:2,start:3,timeline:4,document:5,EOF:6,line:7,SPACE:8,statement:9,NEWLINE:10,title:11,acc_title:12,acc_title_value:13,acc_descr:14,acc_descr_value:15,acc_descr_multiline_value:16,section:17,period_statement:18,event_statement:19,period:20,event:21,$accept:0,$end:1},terminals_:{2:"error",4:"timeline",6:"EOF",8:"SPACE",10:"NEWLINE",11:"title",12:"acc_title",13:"acc_title_value",14:"acc_descr",15:"acc_descr_value",16:"acc_descr_multiline_value",17:"section",20:"period",21:"event"},productions_:[0,[3,3],[5,0],[5,2],[7,2],[7,1],[7,1],[7,1],[9,1],[9,2],[9,2],[9,1],[9,1],[9,1],[9,1],[18,1],[19,1]],performAction:s(function(i,a,d,u,y,o,S){var k=o.length-1;switch(y){case 1:return o[k-1];case 2:this.$=[];break;case 3:o[k-1].push(o[k]),this.$=o[k-1];break;case 4:case 5:this.$=o[k];break;case 6:case 7:this.$=[];break;case 8:u.getCommonDb().setDiagramTitle(o[k].substr(6)),this.$=o[k].substr(6);break;case 9:this.$=o[k].trim(),u.getCommonDb().setAccTitle(this.$);break;case 10:case 11:this.$=o[k].trim(),u.getCommonDb().setAccDescription(this.$);break;case 12:u.addSection(o[k].substr(8)),this.$=o[k].substr(8);break;case 15:u.addTask(o[k],0,""),this.$=o[k];break;case 16:u.addEvent(o[k].substr(2)),this.$=o[k];break}},"anonymous"),table:[{3:1,4:[1,2]},{1:[3]},n(t,[2,2],{5:3}),{6:[1,4],7:5,8:[1,6],9:7,10:[1,8],11:e,12:l,14:r,16:h,17:c,18:14,19:15,20:g,21:m},n(t,[2,7],{1:[2,1]}),n(t,[2,3]),{9:18,11:e,12:l,14:r,16:h,17:c,18:14,19:15,20:g,21:m},n(t,[2,5]),n(t,[2,6]),n(t,[2,8]),{13:[1,19]},{15:[1,20]},n(t,[2,11]),n(t,[2,12]),n(t,[2,13]),n(t,[2,14]),n(t,[2,15]),n(t,[2,16]),n(t,[2,4]),n(t,[2,9]),n(t,[2,10])],defaultActions:{},parseError:s(function(i,a){if(a.recoverable)this.trace(i);else{var d=new Error(i);throw d.hash=a,d}},"parseError"),parse:s(function(i){var a=this,d=[0],u=[],y=[null],o=[],S=this.table,k="",M=0,P=0,B=2,J=1,O=o.slice.call(arguments,1),_=Object.create(this.lexer),E={yy:{}};for(var v in this.yy)Object.prototype.hasOwnProperty.call(this.yy,v)&&(E.yy[v]=this.yy[v]);_.setInput(i,E.yy),E.yy.lexer=_,E.yy.parser=this,typeof _.yylloc>"u"&&(_.yylloc={});var L=_.yylloc;o.push(L);var A=_.options&&_.options.ranges;typeof E.yy.parseError=="function"?this.parseError=E.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;function R(I){d.length=d.length-2*I,y.length=y.length-I,o.length=o.length-I}s(R,"popStack");function z(){var I;return I=u.pop()||_.lex()||J,typeof I!="number"&&(I instanceof Array&&(u=I,I=u.pop()),I=a.symbols_[I]||I),I}s(z,"lex");for(var w,C,N,K,F={},j,$,et,G;;){if(C=d[d.length-1],this.defaultActions[C]?N=this.defaultActions[C]:((w===null||typeof w>"u")&&(w=z()),N=S[C]&&S[C][w]),typeof N>"u"||!N.length||!N[0]){var Q="";G=[];for(j in S[C])this.terminals_[j]&&j>B&&G.push("'"+this.terminals_[j]+"'");_.showPosition?Q="Parse error on line "+(M+1)+`:
|
||||
import{_ as s,c as xt,l as T,d as q,a2 as kt,a3 as _t,a4 as bt,a5 as vt,N as nt,D as wt,a6 as St,z as Et}from"./mermaid-vendor-CR44n-lC.js";import"./feature-graph-wF7LCIjH.js";import"./react-vendor-DEwriMA6.js";import"./graph-vendor-B-X5JegA.js";import"./ui-vendor-CeCm8EER.js";import"./utils-vendor-BysuhMZA.js";var X=function(){var n=s(function(f,i,a,d){for(a=a||{},d=f.length;d--;a[f[d]]=i);return a},"o"),t=[6,8,10,11,12,14,16,17,20,21],e=[1,9],l=[1,10],r=[1,11],h=[1,12],c=[1,13],g=[1,16],m=[1,17],p={trace:s(function(){},"trace"),yy:{},symbols_:{error:2,start:3,timeline:4,document:5,EOF:6,line:7,SPACE:8,statement:9,NEWLINE:10,title:11,acc_title:12,acc_title_value:13,acc_descr:14,acc_descr_value:15,acc_descr_multiline_value:16,section:17,period_statement:18,event_statement:19,period:20,event:21,$accept:0,$end:1},terminals_:{2:"error",4:"timeline",6:"EOF",8:"SPACE",10:"NEWLINE",11:"title",12:"acc_title",13:"acc_title_value",14:"acc_descr",15:"acc_descr_value",16:"acc_descr_multiline_value",17:"section",20:"period",21:"event"},productions_:[0,[3,3],[5,0],[5,2],[7,2],[7,1],[7,1],[7,1],[9,1],[9,2],[9,2],[9,1],[9,1],[9,1],[9,1],[18,1],[19,1]],performAction:s(function(i,a,d,u,y,o,S){var k=o.length-1;switch(y){case 1:return o[k-1];case 2:this.$=[];break;case 3:o[k-1].push(o[k]),this.$=o[k-1];break;case 4:case 5:this.$=o[k];break;case 6:case 7:this.$=[];break;case 8:u.getCommonDb().setDiagramTitle(o[k].substr(6)),this.$=o[k].substr(6);break;case 9:this.$=o[k].trim(),u.getCommonDb().setAccTitle(this.$);break;case 10:case 11:this.$=o[k].trim(),u.getCommonDb().setAccDescription(this.$);break;case 12:u.addSection(o[k].substr(8)),this.$=o[k].substr(8);break;case 15:u.addTask(o[k],0,""),this.$=o[k];break;case 16:u.addEvent(o[k].substr(2)),this.$=o[k];break}},"anonymous"),table:[{3:1,4:[1,2]},{1:[3]},n(t,[2,2],{5:3}),{6:[1,4],7:5,8:[1,6],9:7,10:[1,8],11:e,12:l,14:r,16:h,17:c,18:14,19:15,20:g,21:m},n(t,[2,7],{1:[2,1]}),n(t,[2,3]),{9:18,11:e,12:l,14:r,16:h,17:c,18:14,19:15,20:g,21:m},n(t,[2,5]),n(t,[2,6]),n(t,[2,8]),{13:[1,19]},{15:[1,20]},n(t,[2,11]),n(t,[2,12]),n(t,[2,13]),n(t,[2,14]),n(t,[2,15]),n(t,[2,16]),n(t,[2,4]),n(t,[2,9]),n(t,[2,10])],defaultActions:{},parseError:s(function(i,a){if(a.recoverable)this.trace(i);else{var d=new Error(i);throw d.hash=a,d}},"parseError"),parse:s(function(i){var a=this,d=[0],u=[],y=[null],o=[],S=this.table,k="",M=0,P=0,B=2,J=1,O=o.slice.call(arguments,1),_=Object.create(this.lexer),E={yy:{}};for(var v in this.yy)Object.prototype.hasOwnProperty.call(this.yy,v)&&(E.yy[v]=this.yy[v]);_.setInput(i,E.yy),E.yy.lexer=_,E.yy.parser=this,typeof _.yylloc>"u"&&(_.yylloc={});var L=_.yylloc;o.push(L);var A=_.options&&_.options.ranges;typeof E.yy.parseError=="function"?this.parseError=E.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;function R(I){d.length=d.length-2*I,y.length=y.length-I,o.length=o.length-I}s(R,"popStack");function z(){var I;return I=u.pop()||_.lex()||J,typeof I!="number"&&(I instanceof Array&&(u=I,I=u.pop()),I=a.symbols_[I]||I),I}s(z,"lex");for(var w,C,N,K,F={},j,$,et,G;;){if(C=d[d.length-1],this.defaultActions[C]?N=this.defaultActions[C]:((w===null||typeof w>"u")&&(w=z()),N=S[C]&&S[C][w]),typeof N>"u"||!N.length||!N[0]){var Q="";G=[];for(j in S[C])this.terminals_[j]&&j>B&&G.push("'"+this.terminals_[j]+"'");_.showPosition?Q="Parse error on line "+(M+1)+`:
|
||||
`+_.showPosition()+`
|
||||
Expecting `+G.join(", ")+", got '"+(this.terminals_[w]||w)+"'":Q="Parse error on line "+(M+1)+": Unexpected "+(w==J?"end of input":"'"+(this.terminals_[w]||w)+"'"),this.parseError(Q,{text:_.match,token:this.terminals_[w]||w,line:_.yylineno,loc:L,expected:G})}if(N[0]instanceof Array&&N.length>1)throw new Error("Parse Error: multiple actions possible at state: "+C+", token: "+w);switch(N[0]){case 1:d.push(w),y.push(_.yytext),o.push(_.yylloc),d.push(N[1]),w=null,P=_.yyleng,k=_.yytext,M=_.yylineno,L=_.yylloc;break;case 2:if($=this.productions_[N[1]][1],F.$=y[y.length-$],F._$={first_line:o[o.length-($||1)].first_line,last_line:o[o.length-1].last_line,first_column:o[o.length-($||1)].first_column,last_column:o[o.length-1].last_column},A&&(F._$.range=[o[o.length-($||1)].range[0],o[o.length-1].range[1]]),K=this.performAction.apply(F,[k,P,M,E.yy,N[1],y,o].concat(O)),typeof K<"u")return K;$&&(d=d.slice(0,-1*$*2),y=y.slice(0,-1*$),o=o.slice(0,-1*$)),d.push(this.productions_[N[1]][0]),y.push(F.$),o.push(F._$),et=S[d[d.length-2]][d[d.length-1]],d.push(et);break;case 3:return!0}}return!0},"parse")},x=function(){var f={EOF:1,parseError:s(function(a,d){if(this.yy.parser)this.yy.parser.parseError(a,d);else throw new Error(a)},"parseError"),setInput:s(function(i,a){return this.yy=a||this.yy||{},this._input=i,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},"setInput"),input:s(function(){var i=this._input[0];this.yytext+=i,this.yyleng++,this.offset++,this.match+=i,this.matched+=i;var a=i.match(/(?:\r\n?|\n).*/g);return a?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),i},"input"),unput:s(function(i){var a=i.length,d=i.split(/(?:\r\n?|\n)/g);this._input=i+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-a),this.offset-=a;var u=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),d.length-1&&(this.yylineno-=d.length-1);var y=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:d?(d.length===u.length?this.yylloc.first_column:0)+u[u.length-d.length].length-d[0].length:this.yylloc.first_column-a},this.options.ranges&&(this.yylloc.range=[y[0],y[0]+this.yyleng-a]),this.yyleng=this.yytext.length,this},"unput"),more:s(function(){return this._more=!0,this},"more"),reject:s(function(){if(this.options.backtrack_lexer)this._backtrack=!0;else return this.parseError("Lexical error on line "+(this.yylineno+1)+`. You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).
|
||||
`+this.showPosition(),{text:"",token:null,line:this.yylineno});return this},"reject"),less:s(function(i){this.unput(this.match.slice(i))},"less"),pastInput:s(function(){var i=this.matched.substr(0,this.matched.length-this.match.length);return(i.length>20?"...":"")+i.substr(-20).replace(/\n/g,"")},"pastInput"),upcomingInput:s(function(){var i=this.match;return i.length<20&&(i+=this._input.substr(0,20-i.length)),(i.substr(0,20)+(i.length>20?"...":"")).replace(/\n/g,"")},"upcomingInput"),showPosition:s(function(){var i=this.pastInput(),a=new Array(i.length+1).join("-");return i+this.upcomingInput()+`
|
||||
File diff suppressed because one or more lines are too long
12
lightrag/api/webui/index.html
generated
12
lightrag/api/webui/index.html
generated
|
|
@ -8,16 +8,16 @@
|
|||
<link rel="icon" type="image/png" href="favicon.png" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Lightrag</title>
|
||||
<script type="module" crossorigin src="/webui/assets/index-yRRg2BZk.js"></script>
|
||||
<script type="module" crossorigin src="/webui/assets/index-D3V9EKqf.js"></script>
|
||||
<link rel="modulepreload" crossorigin href="/webui/assets/react-vendor-DEwriMA6.js">
|
||||
<link rel="modulepreload" crossorigin href="/webui/assets/ui-vendor-CeCm8EER.js">
|
||||
<link rel="modulepreload" crossorigin href="/webui/assets/graph-vendor-B-X5JegA.js">
|
||||
<link rel="modulepreload" crossorigin href="/webui/assets/utils-vendor-BysuhMZA.js">
|
||||
<link rel="modulepreload" crossorigin href="/webui/assets/feature-graph-NODQb6qW.js">
|
||||
<link rel="modulepreload" crossorigin href="/webui/assets/mermaid-vendor-D0f_SE0h.js">
|
||||
<link rel="modulepreload" crossorigin href="/webui/assets/markdown-vendor-DmIvJdn7.js">
|
||||
<link rel="modulepreload" crossorigin href="/webui/assets/feature-retrieval-DalFy9WB.js">
|
||||
<link rel="modulepreload" crossorigin href="/webui/assets/feature-documents-oks3sUnM.js">
|
||||
<link rel="modulepreload" crossorigin href="/webui/assets/feature-graph-wF7LCIjH.js">
|
||||
<link rel="modulepreload" crossorigin href="/webui/assets/mermaid-vendor-CR44n-lC.js">
|
||||
<link rel="modulepreload" crossorigin href="/webui/assets/markdown-vendor-ZbbHR4ge.js">
|
||||
<link rel="modulepreload" crossorigin href="/webui/assets/feature-retrieval-DdCvVec9.js">
|
||||
<link rel="modulepreload" crossorigin href="/webui/assets/feature-documents-DZY3tMAq.js">
|
||||
<link rel="stylesheet" crossorigin href="/webui/assets/feature-graph-BipNuM18.css">
|
||||
<link rel="stylesheet" crossorigin href="/webui/assets/index-DwO2XWaU.css">
|
||||
</head>
|
||||
|
|
|
|||
|
|
@ -14,7 +14,16 @@ from typing import (
|
|||
)
|
||||
from .utils import EmbeddingFunc
|
||||
from .types import KnowledgeGraph
|
||||
from .constants import GRAPH_FIELD_SEP
|
||||
from .constants import (
|
||||
GRAPH_FIELD_SEP,
|
||||
DEFAULT_TOP_K,
|
||||
DEFAULT_CHUNK_TOP_K,
|
||||
DEFAULT_MAX_ENTITY_TOKENS,
|
||||
DEFAULT_MAX_RELATION_TOKENS,
|
||||
DEFAULT_MAX_TOTAL_TOKENS,
|
||||
DEFAULT_HISTORY_TURNS,
|
||||
DEFAULT_ENABLE_RERANK,
|
||||
)
|
||||
|
||||
# use the .env that is inside the current folder
|
||||
# allows to use different .env file for each lightrag instance
|
||||
|
|
@ -36,7 +45,7 @@ T = TypeVar("T")
|
|||
class QueryParam:
|
||||
"""Configuration parameters for query execution in LightRAG."""
|
||||
|
||||
mode: Literal["local", "global", "hybrid", "naive", "mix", "bypass"] = "global"
|
||||
mode: Literal["local", "global", "hybrid", "naive", "mix", "bypass"] = "mix"
|
||||
"""Specifies the retrieval mode:
|
||||
- "local": Focuses on context-dependent information.
|
||||
- "global": Utilizes global knowledge.
|
||||
|
|
@ -57,29 +66,28 @@ class QueryParam:
|
|||
stream: bool = False
|
||||
"""If True, enables streaming output for real-time responses."""
|
||||
|
||||
top_k: int = int(os.getenv("TOP_K", "60"))
|
||||
top_k: int = int(os.getenv("TOP_K", str(DEFAULT_TOP_K)))
|
||||
"""Number of top items to retrieve. Represents entities in 'local' mode and relationships in 'global' mode."""
|
||||
|
||||
chunk_top_k: int = int(os.getenv("CHUNK_TOP_K", "5"))
|
||||
"""Number of text chunks to retrieve initially from vector search.
|
||||
chunk_top_k: int = int(os.getenv("CHUNK_TOP_K", str(DEFAULT_CHUNK_TOP_K)))
|
||||
"""Number of text chunks to retrieve initially from vector search and keep after reranking.
|
||||
If None, defaults to top_k value.
|
||||
"""
|
||||
|
||||
chunk_rerank_top_k: int = int(os.getenv("CHUNK_RERANK_TOP_K", "5"))
|
||||
"""Number of text chunks to keep after reranking.
|
||||
If None, keeps all chunks returned from initial retrieval.
|
||||
"""
|
||||
|
||||
max_token_for_text_unit: int = int(os.getenv("MAX_TOKEN_TEXT_CHUNK", "6000"))
|
||||
"""Maximum number of tokens allowed for each retrieved text chunk."""
|
||||
|
||||
max_token_for_global_context: int = int(
|
||||
os.getenv("MAX_TOKEN_RELATION_DESC", "4000")
|
||||
max_entity_tokens: int = int(
|
||||
os.getenv("MAX_ENTITY_TOKENS", str(DEFAULT_MAX_ENTITY_TOKENS))
|
||||
)
|
||||
"""Maximum number of tokens allocated for relationship descriptions in global retrieval."""
|
||||
"""Maximum number of tokens allocated for entity context in unified token control system."""
|
||||
|
||||
max_token_for_local_context: int = int(os.getenv("MAX_TOKEN_ENTITY_DESC", "4000"))
|
||||
"""Maximum number of tokens allocated for entity descriptions in local retrieval."""
|
||||
max_relation_tokens: int = int(
|
||||
os.getenv("MAX_RELATION_TOKENS", str(DEFAULT_MAX_RELATION_TOKENS))
|
||||
)
|
||||
"""Maximum number of tokens allocated for relationship context in unified token control system."""
|
||||
|
||||
max_total_tokens: int = int(
|
||||
os.getenv("MAX_TOTAL_TOKENS", str(DEFAULT_MAX_TOTAL_TOKENS))
|
||||
)
|
||||
"""Maximum total tokens budget for the entire query context (entities + relations + chunks + system prompt)."""
|
||||
|
||||
hl_keywords: list[str] = field(default_factory=list)
|
||||
"""List of high-level keywords to prioritize in retrieval."""
|
||||
|
|
@ -92,7 +100,7 @@ class QueryParam:
|
|||
Format: [{"role": "user/assistant", "content": "message"}].
|
||||
"""
|
||||
|
||||
history_turns: int = 3
|
||||
history_turns: int = int(os.getenv("HISTORY_TURNS", str(DEFAULT_HISTORY_TURNS)))
|
||||
"""Number of complete conversation turns (user-assistant pairs) to consider in the response context."""
|
||||
|
||||
ids: list[str] | None = None
|
||||
|
|
@ -109,6 +117,13 @@ class QueryParam:
|
|||
If proivded, this will be use instead of the default vaulue from prompt template.
|
||||
"""
|
||||
|
||||
enable_rerank: bool = (
|
||||
os.getenv("ENABLE_RERANK", str(DEFAULT_ENABLE_RERANK).lower()).lower() == "true"
|
||||
)
|
||||
"""Enable reranking for retrieved text chunks. If True but no rerank model is configured, a warning will be issued.
|
||||
Default is True to enable reranking when rerank model is available.
|
||||
"""
|
||||
|
||||
|
||||
@dataclass
|
||||
class StorageNameSpace(ABC):
|
||||
|
|
|
|||
|
|
@ -12,6 +12,17 @@ DEFAULT_FORCE_LLM_SUMMARY_ON_MERGE = 4
|
|||
DEFAULT_WOKERS = 2
|
||||
DEFAULT_TIMEOUT = 150
|
||||
|
||||
# Query and retrieval configuration defaults
|
||||
DEFAULT_TOP_K = 40
|
||||
DEFAULT_CHUNK_TOP_K = 10
|
||||
DEFAULT_MAX_ENTITY_TOKENS = 10000
|
||||
DEFAULT_MAX_RELATION_TOKENS = 10000
|
||||
DEFAULT_MAX_TOTAL_TOKENS = 32000
|
||||
DEFAULT_HISTORY_TURNS = 3
|
||||
DEFAULT_ENABLE_RERANK = True
|
||||
DEFAULT_COSINE_THRESHOLD = 0.2
|
||||
DEFAULT_RELATED_CHUNK_NUMBER = 10
|
||||
|
||||
# Separator for graph fields
|
||||
GRAPH_FIELD_SEP = "<SEP>"
|
||||
|
||||
|
|
|
|||
|
|
@ -185,10 +185,6 @@ class FaissVectorDBStorage(BaseVectorStorage):
|
|||
embedding = np.array(embedding, dtype=np.float32)
|
||||
faiss.normalize_L2(embedding) # we do in-place normalization
|
||||
|
||||
logger.info(
|
||||
f"Query: {query}, top_k: {top_k}, threshold: {self.cosine_better_than_threshold}"
|
||||
)
|
||||
|
||||
# Perform the similarity search
|
||||
index = await self._get_index()
|
||||
distances, indices = index.search(embedding, top_k)
|
||||
|
|
|
|||
|
|
@ -20,6 +20,9 @@ def direct_log(message, enable_output: bool = False, level: str = "DEBUG"):
|
|||
level: Log level (default: "DEBUG")
|
||||
enable_output: Whether to actually output the log (default: True)
|
||||
"""
|
||||
if not enable_output:
|
||||
return
|
||||
|
||||
# Get the current logger level from the lightrag logger
|
||||
try:
|
||||
from lightrag.utils import logger
|
||||
|
|
@ -40,7 +43,7 @@ def direct_log(message, enable_output: bool = False, level: str = "DEBUG"):
|
|||
message_level = level_mapping.get(level.upper(), logging.DEBUG)
|
||||
|
||||
# print(f"Diret_log: {level.upper()} {message_level} ? {current_level}", file=sys.stderr, flush=True)
|
||||
if enable_output or (message_level >= current_level):
|
||||
if message_level >= current_level:
|
||||
print(f"{level}: {message}", file=sys.stderr, flush=True)
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -24,6 +24,13 @@ from typing import (
|
|||
from lightrag.constants import (
|
||||
DEFAULT_MAX_GLEANING,
|
||||
DEFAULT_FORCE_LLM_SUMMARY_ON_MERGE,
|
||||
DEFAULT_TOP_K,
|
||||
DEFAULT_CHUNK_TOP_K,
|
||||
DEFAULT_MAX_ENTITY_TOKENS,
|
||||
DEFAULT_MAX_RELATION_TOKENS,
|
||||
DEFAULT_MAX_TOTAL_TOKENS,
|
||||
DEFAULT_COSINE_THRESHOLD,
|
||||
DEFAULT_RELATED_CHUNK_NUMBER,
|
||||
)
|
||||
from lightrag.utils import get_env_value
|
||||
|
||||
|
|
@ -125,6 +132,42 @@ class LightRAG:
|
|||
log_level: int | None = field(default=None)
|
||||
log_file_path: str | None = field(default=None)
|
||||
|
||||
# Query parameters
|
||||
# ---
|
||||
|
||||
top_k: int = field(default=get_env_value("TOP_K", DEFAULT_TOP_K, int))
|
||||
"""Number of entities/relations to retrieve for each query."""
|
||||
|
||||
chunk_top_k: int = field(
|
||||
default=get_env_value("CHUNK_TOP_K", DEFAULT_CHUNK_TOP_K, int)
|
||||
)
|
||||
"""Maximum number of chunks in context."""
|
||||
|
||||
max_entity_tokens: int = field(
|
||||
default=get_env_value("MAX_ENTITY_TOKENS", DEFAULT_MAX_ENTITY_TOKENS, int)
|
||||
)
|
||||
"""Maximum number of tokens for entity in context."""
|
||||
|
||||
max_relation_tokens: int = field(
|
||||
default=get_env_value("MAX_RELATION_TOKENS", DEFAULT_MAX_RELATION_TOKENS, int)
|
||||
)
|
||||
"""Maximum number of tokens for relation in context."""
|
||||
|
||||
max_total_tokens: int = field(
|
||||
default=get_env_value("MAX_TOTAL_TOKENS", DEFAULT_MAX_TOTAL_TOKENS, int)
|
||||
)
|
||||
"""Maximum total tokens in context (including system prompt, entities, relations and chunks)."""
|
||||
|
||||
cosine_threshold: int = field(
|
||||
default=get_env_value("COSINE_THRESHOLD", DEFAULT_COSINE_THRESHOLD, int)
|
||||
)
|
||||
"""Cosine threshold of vector DB retrieval for entities, relations and chunks."""
|
||||
|
||||
related_chunk_number: int = field(
|
||||
default=get_env_value("RELATED_CHUNK_NUMBER", DEFAULT_RELATED_CHUNK_NUMBER, int)
|
||||
)
|
||||
"""Number of related chunks to grab from single entity or relation."""
|
||||
|
||||
# Entity extraction
|
||||
# ---
|
||||
|
||||
|
|
@ -238,11 +281,6 @@ class LightRAG:
|
|||
# Rerank Configuration
|
||||
# ---
|
||||
|
||||
enable_rerank: bool = field(
|
||||
default=bool(os.getenv("ENABLE_RERANK", "False").lower() == "true")
|
||||
)
|
||||
"""Enable reranking for improved retrieval quality. Defaults to False."""
|
||||
|
||||
rerank_model_func: Callable[..., object] | None = field(default=None)
|
||||
"""Function for reranking retrieved documents. All rerank configurations (model name, API keys, top_k, etc.) should be included in this function. Optional."""
|
||||
|
||||
|
|
@ -454,9 +492,9 @@ class LightRAG:
|
|||
)
|
||||
|
||||
# Init Rerank
|
||||
if self.enable_rerank and self.rerank_model_func:
|
||||
if self.rerank_model_func:
|
||||
logger.info("Rerank model initialized for improved retrieval quality")
|
||||
elif self.enable_rerank and not self.rerank_model_func:
|
||||
else:
|
||||
logger.warning(
|
||||
"Rerank is enabled but no rerank_model_func provided. Reranking will be skipped."
|
||||
)
|
||||
|
|
|
|||
|
|
@ -36,7 +36,13 @@ from .base import (
|
|||
QueryParam,
|
||||
)
|
||||
from .prompt import PROMPTS
|
||||
from .constants import GRAPH_FIELD_SEP
|
||||
from .constants import (
|
||||
GRAPH_FIELD_SEP,
|
||||
DEFAULT_MAX_ENTITY_TOKENS,
|
||||
DEFAULT_MAX_RELATION_TOKENS,
|
||||
DEFAULT_MAX_TOTAL_TOKENS,
|
||||
DEFAULT_RELATED_CHUNK_NUMBER,
|
||||
)
|
||||
from .kg.shared_storage import get_storage_keyed_lock
|
||||
import time
|
||||
from dotenv import load_dotenv
|
||||
|
|
@ -1643,7 +1649,9 @@ async def kg_query(
|
|||
|
||||
tokenizer: Tokenizer = global_config["tokenizer"]
|
||||
len_of_prompts = len(tokenizer.encode(query + sys_prompt))
|
||||
logger.debug(f"[kg_query]Prompt Tokens: {len_of_prompts}")
|
||||
logger.debug(
|
||||
f"[kg_query] Sending to LLM: {len_of_prompts:,} tokens (Query: {len(tokenizer.encode(query))}, System: {len(tokenizer.encode(sys_prompt))})"
|
||||
)
|
||||
|
||||
response = await use_model_func(
|
||||
query,
|
||||
|
|
@ -1766,7 +1774,9 @@ async def extract_keywords_only(
|
|||
|
||||
tokenizer: Tokenizer = global_config["tokenizer"]
|
||||
len_of_prompts = len(tokenizer.encode(kw_prompt))
|
||||
logger.debug(f"[kg_query]Prompt Tokens: {len_of_prompts}")
|
||||
logger.debug(
|
||||
f"[extract_keywords] Sending to LLM: {len_of_prompts:,} tokens (Prompt: {len_of_prompts})"
|
||||
)
|
||||
|
||||
# 5. Call the LLM for keyword extraction
|
||||
if param.model_func:
|
||||
|
|
@ -1883,51 +1893,63 @@ async def _build_query_context(
|
|||
entities_context = []
|
||||
relations_context = []
|
||||
|
||||
# Store original data for later text chunk retrieval
|
||||
original_node_datas = []
|
||||
original_edge_datas = []
|
||||
|
||||
# Handle local and global modes
|
||||
if query_param.mode == "local":
|
||||
entities_context, relations_context, entity_chunks = await _get_node_data(
|
||||
(
|
||||
entities_context,
|
||||
relations_context,
|
||||
node_datas,
|
||||
use_relations,
|
||||
) = await _get_node_data(
|
||||
ll_keywords,
|
||||
knowledge_graph_inst,
|
||||
entities_vdb,
|
||||
text_chunks_db,
|
||||
query_param,
|
||||
)
|
||||
all_chunks.extend(entity_chunks)
|
||||
original_node_datas = node_datas
|
||||
original_edge_datas = use_relations
|
||||
|
||||
elif query_param.mode == "global":
|
||||
entities_context, relations_context, relationship_chunks = await _get_edge_data(
|
||||
(
|
||||
entities_context,
|
||||
relations_context,
|
||||
edge_datas,
|
||||
use_entities,
|
||||
) = await _get_edge_data(
|
||||
hl_keywords,
|
||||
knowledge_graph_inst,
|
||||
relationships_vdb,
|
||||
text_chunks_db,
|
||||
query_param,
|
||||
)
|
||||
all_chunks.extend(relationship_chunks)
|
||||
original_edge_datas = edge_datas
|
||||
original_node_datas = use_entities
|
||||
|
||||
else: # hybrid or mix mode
|
||||
ll_data = await _get_node_data(
|
||||
ll_keywords,
|
||||
knowledge_graph_inst,
|
||||
entities_vdb,
|
||||
text_chunks_db,
|
||||
query_param,
|
||||
)
|
||||
hl_data = await _get_edge_data(
|
||||
hl_keywords,
|
||||
knowledge_graph_inst,
|
||||
relationships_vdb,
|
||||
text_chunks_db,
|
||||
query_param,
|
||||
)
|
||||
|
||||
(ll_entities_context, ll_relations_context, ll_chunks) = ll_data
|
||||
(hl_entities_context, hl_relations_context, hl_chunks) = hl_data
|
||||
(ll_entities_context, ll_relations_context, ll_node_datas, ll_edge_datas) = (
|
||||
ll_data
|
||||
)
|
||||
(hl_entities_context, hl_relations_context, hl_edge_datas, hl_node_datas) = (
|
||||
hl_data
|
||||
)
|
||||
|
||||
# Collect chunks from entity and relationship sources
|
||||
all_chunks.extend(ll_chunks)
|
||||
all_chunks.extend(hl_chunks)
|
||||
|
||||
# Get vector chunks if in mix mode
|
||||
# Get vector chunks first if in mix mode
|
||||
if query_param.mode == "mix" and chunks_vdb:
|
||||
vector_chunks = await _get_vector_context(
|
||||
query,
|
||||
|
|
@ -1936,33 +1958,259 @@ async def _build_query_context(
|
|||
)
|
||||
all_chunks.extend(vector_chunks)
|
||||
|
||||
# Store original data from both sources
|
||||
original_node_datas = ll_node_datas + hl_node_datas
|
||||
original_edge_datas = ll_edge_datas + hl_edge_datas
|
||||
|
||||
# Combine entities and relations contexts
|
||||
entities_context = process_combine_contexts(
|
||||
hl_entities_context, ll_entities_context
|
||||
ll_entities_context, hl_entities_context
|
||||
)
|
||||
relations_context = process_combine_contexts(
|
||||
hl_relations_context, ll_relations_context
|
||||
)
|
||||
|
||||
# Process all chunks uniformly: deduplication, reranking, and token truncation
|
||||
processed_chunks = await process_chunks_unified(
|
||||
query=query,
|
||||
chunks=all_chunks,
|
||||
query_param=query_param,
|
||||
global_config=text_chunks_db.global_config,
|
||||
source_type="mixed",
|
||||
logger.info(
|
||||
f"Initial context: {len(entities_context)} entities, {len(relations_context)} relations, {len(all_chunks)} chunks"
|
||||
)
|
||||
|
||||
# Build final text_units_context from processed chunks
|
||||
text_units_context = []
|
||||
for i, chunk in enumerate(processed_chunks):
|
||||
text_units_context.append(
|
||||
{
|
||||
"id": i + 1,
|
||||
"content": chunk["content"],
|
||||
"file_path": chunk.get("file_path", "unknown_source"),
|
||||
}
|
||||
# Unified token control system - Apply precise token limits to entities and relations
|
||||
tokenizer = text_chunks_db.global_config.get("tokenizer")
|
||||
if tokenizer:
|
||||
# Get new token limits from query_param (with fallback to global_config)
|
||||
max_entity_tokens = getattr(
|
||||
query_param,
|
||||
"max_entity_tokens",
|
||||
text_chunks_db.global_config.get(
|
||||
"max_entity_tokens", DEFAULT_MAX_ENTITY_TOKENS
|
||||
),
|
||||
)
|
||||
max_relation_tokens = getattr(
|
||||
query_param,
|
||||
"max_relation_tokens",
|
||||
text_chunks_db.global_config.get(
|
||||
"max_relation_tokens", DEFAULT_MAX_RELATION_TOKENS
|
||||
),
|
||||
)
|
||||
max_total_tokens = getattr(
|
||||
query_param,
|
||||
"max_total_tokens",
|
||||
text_chunks_db.global_config.get(
|
||||
"max_total_tokens", DEFAULT_MAX_TOTAL_TOKENS
|
||||
),
|
||||
)
|
||||
|
||||
# Truncate entities based on complete JSON serialization
|
||||
if entities_context:
|
||||
original_entity_count = len(entities_context)
|
||||
|
||||
# Process entities context to replace GRAPH_FIELD_SEP with : in file_path fields
|
||||
for entity in entities_context:
|
||||
if "file_path" in entity and entity["file_path"]:
|
||||
entity["file_path"] = entity["file_path"].replace(
|
||||
GRAPH_FIELD_SEP, ";"
|
||||
)
|
||||
|
||||
entities_context = truncate_list_by_token_size(
|
||||
entities_context,
|
||||
key=lambda x: json.dumps(x, ensure_ascii=False),
|
||||
max_token_size=max_entity_tokens,
|
||||
tokenizer=tokenizer,
|
||||
)
|
||||
if len(entities_context) < original_entity_count:
|
||||
logger.debug(
|
||||
f"Truncated entities: {original_entity_count} -> {len(entities_context)} (entity max tokens: {max_entity_tokens})"
|
||||
)
|
||||
|
||||
# Truncate relations based on complete JSON serialization
|
||||
if relations_context:
|
||||
original_relation_count = len(relations_context)
|
||||
|
||||
# Process relations context to replace GRAPH_FIELD_SEP with : in file_path fields
|
||||
for relation in relations_context:
|
||||
if "file_path" in relation and relation["file_path"]:
|
||||
relation["file_path"] = relation["file_path"].replace(
|
||||
GRAPH_FIELD_SEP, ";"
|
||||
)
|
||||
|
||||
relations_context = truncate_list_by_token_size(
|
||||
relations_context,
|
||||
key=lambda x: json.dumps(x, ensure_ascii=False),
|
||||
max_token_size=max_relation_tokens,
|
||||
tokenizer=tokenizer,
|
||||
)
|
||||
if len(relations_context) < original_relation_count:
|
||||
logger.debug(
|
||||
f"Truncated relations: {original_relation_count} -> {len(relations_context)} (relation max tokens: {max_relation_tokens})"
|
||||
)
|
||||
|
||||
# After truncation, get text chunks based on final entities and relations
|
||||
logger.info("Getting text chunks based on truncated entities and relations...")
|
||||
|
||||
# Create filtered data based on truncated context
|
||||
final_node_datas = []
|
||||
if entities_context and original_node_datas:
|
||||
final_entity_names = {e["entity"] for e in entities_context}
|
||||
seen_nodes = set()
|
||||
for node in original_node_datas:
|
||||
name = node.get("entity_name")
|
||||
if name in final_entity_names and name not in seen_nodes:
|
||||
final_node_datas.append(node)
|
||||
seen_nodes.add(name)
|
||||
|
||||
final_edge_datas = []
|
||||
if relations_context and original_edge_datas:
|
||||
final_relation_pairs = {(r["entity1"], r["entity2"]) for r in relations_context}
|
||||
seen_edges = set()
|
||||
for edge in original_edge_datas:
|
||||
src, tgt = edge.get("src_id"), edge.get("tgt_id")
|
||||
if src is None or tgt is None:
|
||||
src, tgt = edge.get("src_tgt", (None, None))
|
||||
|
||||
pair = (src, tgt)
|
||||
if pair in final_relation_pairs and pair not in seen_edges:
|
||||
final_edge_datas.append(edge)
|
||||
seen_edges.add(pair)
|
||||
|
||||
# Get text chunks based on final filtered data
|
||||
text_chunk_tasks = []
|
||||
|
||||
if final_node_datas:
|
||||
text_chunk_tasks.append(
|
||||
_find_most_related_text_unit_from_entities(
|
||||
final_node_datas,
|
||||
query_param,
|
||||
text_chunks_db,
|
||||
knowledge_graph_inst,
|
||||
)
|
||||
)
|
||||
|
||||
if final_edge_datas:
|
||||
text_chunk_tasks.append(
|
||||
_find_related_text_unit_from_relationships(
|
||||
final_edge_datas,
|
||||
query_param,
|
||||
text_chunks_db,
|
||||
)
|
||||
)
|
||||
|
||||
# Execute text chunk retrieval in parallel
|
||||
if text_chunk_tasks:
|
||||
text_chunk_results = await asyncio.gather(*text_chunk_tasks)
|
||||
for chunks in text_chunk_results:
|
||||
if chunks:
|
||||
all_chunks.extend(chunks)
|
||||
|
||||
# Apply token processing to chunks if tokenizer is available
|
||||
text_units_context = []
|
||||
if tokenizer and all_chunks:
|
||||
# Calculate dynamic token limit for text chunks
|
||||
entities_str = json.dumps(entities_context, ensure_ascii=False)
|
||||
relations_str = json.dumps(relations_context, ensure_ascii=False)
|
||||
|
||||
# Calculate base context tokens (entities + relations + template)
|
||||
kg_context_template = """-----Entities(KG)-----
|
||||
|
||||
```json
|
||||
{entities_str}
|
||||
```
|
||||
|
||||
-----Relationships(KG)-----
|
||||
|
||||
```json
|
||||
{relations_str}
|
||||
```
|
||||
|
||||
-----Document Chunks(DC)-----
|
||||
|
||||
```json
|
||||
[]
|
||||
```
|
||||
|
||||
"""
|
||||
kg_context = kg_context_template.format(
|
||||
entities_str=entities_str, relations_str=relations_str
|
||||
)
|
||||
kg_context_tokens = len(tokenizer.encode(kg_context))
|
||||
|
||||
# Calculate actual system prompt overhead dynamically
|
||||
# 1. Calculate conversation history tokens
|
||||
history_context = ""
|
||||
if query_param.conversation_history:
|
||||
history_context = get_conversation_turns(
|
||||
query_param.conversation_history, query_param.history_turns
|
||||
)
|
||||
history_tokens = (
|
||||
len(tokenizer.encode(history_context)) if history_context else 0
|
||||
)
|
||||
|
||||
# 2. Calculate system prompt template tokens (excluding context_data)
|
||||
user_prompt = query_param.user_prompt if query_param.user_prompt else ""
|
||||
response_type = (
|
||||
query_param.response_type
|
||||
if query_param.response_type
|
||||
else "Multiple Paragraphs"
|
||||
)
|
||||
|
||||
# Get the system prompt template from PROMPTS
|
||||
sys_prompt_template = text_chunks_db.global_config.get(
|
||||
"system_prompt_template", PROMPTS["rag_response"]
|
||||
)
|
||||
|
||||
# Create a sample system prompt with placeholders filled (excluding context_data)
|
||||
sample_sys_prompt = sys_prompt_template.format(
|
||||
history=history_context,
|
||||
context_data="", # Empty for overhead calculation
|
||||
response_type=response_type,
|
||||
user_prompt=user_prompt,
|
||||
)
|
||||
sys_prompt_template_tokens = len(tokenizer.encode(sample_sys_prompt))
|
||||
|
||||
# Total system prompt overhead = template + query tokens
|
||||
query_tokens = len(tokenizer.encode(query))
|
||||
sys_prompt_overhead = sys_prompt_template_tokens + query_tokens
|
||||
|
||||
buffer_tokens = 100 # Safety buffer as requested
|
||||
|
||||
# Calculate available tokens for text chunks
|
||||
used_tokens = kg_context_tokens + sys_prompt_overhead + buffer_tokens
|
||||
available_chunk_tokens = max_total_tokens - used_tokens
|
||||
|
||||
logger.debug(
|
||||
f"Token allocation - Total: {max_total_tokens}, History: {history_tokens}, SysPrompt: {sys_prompt_overhead}, KG: {kg_context_tokens}, Buffer: {buffer_tokens}, Available for chunks: {available_chunk_tokens}"
|
||||
)
|
||||
|
||||
# Re-process chunks with dynamic token limit
|
||||
if all_chunks:
|
||||
# Create a temporary query_param copy with adjusted chunk token limit
|
||||
temp_chunks = [
|
||||
{"content": chunk["content"], "file_path": chunk["file_path"]}
|
||||
for chunk in all_chunks
|
||||
]
|
||||
|
||||
# Apply token truncation to chunks using the dynamic limit
|
||||
truncated_chunks = await process_chunks_unified(
|
||||
query=query,
|
||||
chunks=temp_chunks,
|
||||
query_param=query_param,
|
||||
global_config=text_chunks_db.global_config,
|
||||
source_type="mixed",
|
||||
chunk_token_limit=available_chunk_tokens, # Pass dynamic limit
|
||||
)
|
||||
|
||||
# Rebuild text_units_context with truncated chunks
|
||||
for i, chunk in enumerate(truncated_chunks):
|
||||
text_units_context.append(
|
||||
{
|
||||
"id": i + 1,
|
||||
"content": chunk["content"],
|
||||
"file_path": chunk.get("file_path", "unknown_source"),
|
||||
}
|
||||
)
|
||||
|
||||
logger.debug(
|
||||
f"Re-truncated chunks for dynamic token limit: {len(temp_chunks)} -> {len(text_units_context)} (chunk available tokens: {available_chunk_tokens})"
|
||||
)
|
||||
|
||||
logger.info(
|
||||
f"Final context: {len(entities_context)} entities, {len(relations_context)} relations, {len(text_units_context)} chunks"
|
||||
|
|
@ -2002,7 +2250,6 @@ async def _get_node_data(
|
|||
query: str,
|
||||
knowledge_graph_inst: BaseGraphStorage,
|
||||
entities_vdb: BaseVectorStorage,
|
||||
text_chunks_db: BaseKVStorage,
|
||||
query_param: QueryParam,
|
||||
):
|
||||
# get similar entities
|
||||
|
|
@ -2015,7 +2262,7 @@ async def _get_node_data(
|
|||
)
|
||||
|
||||
if not len(results):
|
||||
return "", "", ""
|
||||
return "", "", [], []
|
||||
|
||||
# Extract all entity IDs from your results list
|
||||
node_ids = [r["entity_name"] for r in results]
|
||||
|
|
@ -2042,34 +2289,16 @@ async def _get_node_data(
|
|||
}
|
||||
for k, n, d in zip(results, node_datas, node_degrees)
|
||||
if n is not None
|
||||
] # what is this text_chunks_db doing. dont remember it in airvx. check the diagram.
|
||||
# get entitytext chunk
|
||||
use_text_units = await _find_most_related_text_unit_from_entities(
|
||||
node_datas,
|
||||
query_param,
|
||||
text_chunks_db,
|
||||
knowledge_graph_inst,
|
||||
)
|
||||
]
|
||||
|
||||
use_relations = await _find_most_related_edges_from_entities(
|
||||
node_datas,
|
||||
query_param,
|
||||
knowledge_graph_inst,
|
||||
)
|
||||
|
||||
tokenizer: Tokenizer = text_chunks_db.global_config.get("tokenizer")
|
||||
len_node_datas = len(node_datas)
|
||||
node_datas = truncate_list_by_token_size(
|
||||
node_datas,
|
||||
key=lambda x: x["description"] if x["description"] is not None else "",
|
||||
max_token_size=query_param.max_token_for_local_context,
|
||||
tokenizer=tokenizer,
|
||||
)
|
||||
logger.debug(
|
||||
f"Truncate entities from {len_node_datas} to {len(node_datas)} (max tokens:{query_param.max_token_for_local_context})"
|
||||
)
|
||||
|
||||
logger.info(
|
||||
f"Local query: {len(node_datas)} entites, {len(use_relations)} relations, {len(use_text_units)} chunks"
|
||||
f"Local query: {len(node_datas)} entites, {len(use_relations)} relations"
|
||||
)
|
||||
|
||||
# build prompt
|
||||
|
|
@ -2088,7 +2317,6 @@ async def _get_node_data(
|
|||
"entity": n["entity_name"],
|
||||
"type": n.get("entity_type", "UNKNOWN"),
|
||||
"description": n.get("description", "UNKNOWN"),
|
||||
"rank": n["rank"],
|
||||
"created_at": created_at,
|
||||
"file_path": file_path,
|
||||
}
|
||||
|
|
@ -2110,15 +2338,12 @@ async def _get_node_data(
|
|||
"entity1": e["src_tgt"][0],
|
||||
"entity2": e["src_tgt"][1],
|
||||
"description": e["description"],
|
||||
"keywords": e["keywords"],
|
||||
"weight": e["weight"],
|
||||
"rank": e["rank"],
|
||||
"created_at": created_at,
|
||||
"file_path": file_path,
|
||||
}
|
||||
)
|
||||
|
||||
return entities_context, relations_context, use_text_units
|
||||
return entities_context, relations_context, node_datas, use_relations
|
||||
|
||||
|
||||
async def _find_most_related_text_unit_from_entities(
|
||||
|
|
@ -2127,8 +2352,14 @@ async def _find_most_related_text_unit_from_entities(
|
|||
text_chunks_db: BaseKVStorage,
|
||||
knowledge_graph_inst: BaseGraphStorage,
|
||||
):
|
||||
logger.debug(f"Searching text chunks for {len(node_datas)} entities")
|
||||
|
||||
text_units = [
|
||||
split_string_by_multi_markers(dp["source_id"], [GRAPH_FIELD_SEP])
|
||||
split_string_by_multi_markers(dp["source_id"], [GRAPH_FIELD_SEP])[
|
||||
: text_chunks_db.global_config.get(
|
||||
"related_chunk_number", DEFAULT_RELATED_CHUNK_NUMBER
|
||||
)
|
||||
]
|
||||
for dp in node_datas
|
||||
if dp["source_id"] is not None
|
||||
]
|
||||
|
|
@ -2273,20 +2504,9 @@ async def _find_most_related_edges_from_entities(
|
|||
}
|
||||
all_edges_data.append(combined)
|
||||
|
||||
tokenizer: Tokenizer = knowledge_graph_inst.global_config.get("tokenizer")
|
||||
all_edges_data = sorted(
|
||||
all_edges_data, key=lambda x: (x["rank"], x["weight"]), reverse=True
|
||||
)
|
||||
all_edges_data = truncate_list_by_token_size(
|
||||
all_edges_data,
|
||||
key=lambda x: x["description"] if x["description"] is not None else "",
|
||||
max_token_size=query_param.max_token_for_global_context,
|
||||
tokenizer=tokenizer,
|
||||
)
|
||||
|
||||
logger.debug(
|
||||
f"Truncate relations from {len(all_edges)} to {len(all_edges_data)} (max tokens:{query_param.max_token_for_global_context})"
|
||||
)
|
||||
|
||||
return all_edges_data
|
||||
|
||||
|
|
@ -2295,7 +2515,6 @@ async def _get_edge_data(
|
|||
keywords,
|
||||
knowledge_graph_inst: BaseGraphStorage,
|
||||
relationships_vdb: BaseVectorStorage,
|
||||
text_chunks_db: BaseKVStorage,
|
||||
query_param: QueryParam,
|
||||
):
|
||||
logger.info(
|
||||
|
|
@ -2307,7 +2526,7 @@ async def _get_edge_data(
|
|||
)
|
||||
|
||||
if not len(results):
|
||||
return "", "", ""
|
||||
return "", "", [], []
|
||||
|
||||
# Prepare edge pairs in two forms:
|
||||
# For the batch edge properties function, use dicts.
|
||||
|
|
@ -2343,31 +2562,18 @@ async def _get_edge_data(
|
|||
}
|
||||
edge_datas.append(combined)
|
||||
|
||||
tokenizer: Tokenizer = text_chunks_db.global_config.get("tokenizer")
|
||||
edge_datas = sorted(
|
||||
edge_datas, key=lambda x: (x["rank"], x["weight"]), reverse=True
|
||||
)
|
||||
edge_datas = truncate_list_by_token_size(
|
||||
|
||||
use_entities = await _find_most_related_entities_from_relationships(
|
||||
edge_datas,
|
||||
key=lambda x: x["description"] if x["description"] is not None else "",
|
||||
max_token_size=query_param.max_token_for_global_context,
|
||||
tokenizer=tokenizer,
|
||||
)
|
||||
use_entities, use_text_units = await asyncio.gather(
|
||||
_find_most_related_entities_from_relationships(
|
||||
edge_datas,
|
||||
query_param,
|
||||
knowledge_graph_inst,
|
||||
),
|
||||
_find_related_text_unit_from_relationships(
|
||||
edge_datas,
|
||||
query_param,
|
||||
text_chunks_db,
|
||||
knowledge_graph_inst,
|
||||
),
|
||||
query_param,
|
||||
knowledge_graph_inst,
|
||||
)
|
||||
|
||||
logger.info(
|
||||
f"Global query: {len(use_entities)} entites, {len(edge_datas)} relations, {len(use_text_units)} chunks"
|
||||
f"Global query: {len(use_entities)} entites, {len(edge_datas)} relations"
|
||||
)
|
||||
|
||||
relations_context = []
|
||||
|
|
@ -2386,9 +2592,6 @@ async def _get_edge_data(
|
|||
"entity1": e["src_id"],
|
||||
"entity2": e["tgt_id"],
|
||||
"description": e["description"],
|
||||
"keywords": e["keywords"],
|
||||
"weight": e["weight"],
|
||||
"rank": e["rank"],
|
||||
"created_at": created_at,
|
||||
"file_path": file_path,
|
||||
}
|
||||
|
|
@ -2410,22 +2613,13 @@ async def _get_edge_data(
|
|||
"entity": n["entity_name"],
|
||||
"type": n.get("entity_type", "UNKNOWN"),
|
||||
"description": n.get("description", "UNKNOWN"),
|
||||
"rank": n["rank"],
|
||||
"created_at": created_at,
|
||||
"file_path": file_path,
|
||||
}
|
||||
)
|
||||
|
||||
text_units_context = []
|
||||
for i, t in enumerate(use_text_units):
|
||||
text_units_context.append(
|
||||
{
|
||||
"id": i + 1,
|
||||
"content": t["content"],
|
||||
"file_path": t.get("file_path", "unknown"),
|
||||
}
|
||||
)
|
||||
return entities_context, relations_context, text_units_context
|
||||
# Return original data for later text chunk retrieval
|
||||
return entities_context, relations_context, edge_datas, use_entities
|
||||
|
||||
|
||||
async def _find_most_related_entities_from_relationships(
|
||||
|
|
@ -2462,18 +2656,6 @@ async def _find_most_related_entities_from_relationships(
|
|||
combined = {**node, "entity_name": entity_name, "rank": degree}
|
||||
node_datas.append(combined)
|
||||
|
||||
tokenizer: Tokenizer = knowledge_graph_inst.global_config.get("tokenizer")
|
||||
len_node_datas = len(node_datas)
|
||||
node_datas = truncate_list_by_token_size(
|
||||
node_datas,
|
||||
key=lambda x: x["description"] if x["description"] is not None else "",
|
||||
max_token_size=query_param.max_token_for_local_context,
|
||||
tokenizer=tokenizer,
|
||||
)
|
||||
logger.debug(
|
||||
f"Truncate entities from {len_node_datas} to {len(node_datas)} (max tokens:{query_param.max_token_for_local_context})"
|
||||
)
|
||||
|
||||
return node_datas
|
||||
|
||||
|
||||
|
|
@ -2481,10 +2663,15 @@ async def _find_related_text_unit_from_relationships(
|
|||
edge_datas: list[dict],
|
||||
query_param: QueryParam,
|
||||
text_chunks_db: BaseKVStorage,
|
||||
knowledge_graph_inst: BaseGraphStorage,
|
||||
):
|
||||
logger.debug(f"Searching text chunks for {len(edge_datas)} relationships")
|
||||
|
||||
text_units = [
|
||||
split_string_by_multi_markers(dp["source_id"], [GRAPH_FIELD_SEP])
|
||||
split_string_by_multi_markers(dp["source_id"], [GRAPH_FIELD_SEP])[
|
||||
: text_chunks_db.global_config.get(
|
||||
"related_chunk_number", DEFAULT_RELATED_CHUNK_NUMBER
|
||||
)
|
||||
]
|
||||
for dp in edge_datas
|
||||
if dp["source_id"] is not None
|
||||
]
|
||||
|
|
@ -2565,13 +2752,66 @@ async def naive_query(
|
|||
if chunks is None or len(chunks) == 0:
|
||||
return PROMPTS["fail_response"]
|
||||
|
||||
# Process chunks using unified processing
|
||||
# Calculate dynamic token limit for chunks
|
||||
# Get token limits from query_param (with fallback to global_config)
|
||||
max_total_tokens = getattr(
|
||||
query_param,
|
||||
"max_total_tokens",
|
||||
global_config.get("max_total_tokens", DEFAULT_MAX_TOTAL_TOKENS),
|
||||
)
|
||||
|
||||
# Calculate conversation history tokens
|
||||
history_context = ""
|
||||
if query_param.conversation_history:
|
||||
history_context = get_conversation_turns(
|
||||
query_param.conversation_history, query_param.history_turns
|
||||
)
|
||||
history_tokens = len(tokenizer.encode(history_context)) if history_context else 0
|
||||
|
||||
# Calculate system prompt template tokens (excluding content_data)
|
||||
user_prompt = query_param.user_prompt if query_param.user_prompt else ""
|
||||
response_type = (
|
||||
query_param.response_type
|
||||
if query_param.response_type
|
||||
else "Multiple Paragraphs"
|
||||
)
|
||||
|
||||
# Use the provided system prompt or default
|
||||
sys_prompt_template = (
|
||||
system_prompt if system_prompt else PROMPTS["naive_rag_response"]
|
||||
)
|
||||
|
||||
# Create a sample system prompt with empty content_data to calculate overhead
|
||||
sample_sys_prompt = sys_prompt_template.format(
|
||||
content_data="", # Empty for overhead calculation
|
||||
response_type=response_type,
|
||||
history=history_context,
|
||||
user_prompt=user_prompt,
|
||||
)
|
||||
sys_prompt_template_tokens = len(tokenizer.encode(sample_sys_prompt))
|
||||
|
||||
# Total system prompt overhead = template + query tokens
|
||||
query_tokens = len(tokenizer.encode(query))
|
||||
sys_prompt_overhead = sys_prompt_template_tokens + query_tokens
|
||||
|
||||
buffer_tokens = 100 # Safety buffer
|
||||
|
||||
# Calculate available tokens for chunks
|
||||
used_tokens = sys_prompt_overhead + buffer_tokens
|
||||
available_chunk_tokens = max_total_tokens - used_tokens
|
||||
|
||||
logger.debug(
|
||||
f"Naive query token allocation - Total: {max_total_tokens}, History: {history_tokens}, SysPrompt: {sys_prompt_overhead}, Buffer: {buffer_tokens}, Available for chunks: {available_chunk_tokens}"
|
||||
)
|
||||
|
||||
# Process chunks using unified processing with dynamic token limit
|
||||
processed_chunks = await process_chunks_unified(
|
||||
query=query,
|
||||
chunks=chunks,
|
||||
query_param=query_param,
|
||||
global_config=global_config,
|
||||
source_type="vector",
|
||||
chunk_token_limit=available_chunk_tokens, # Pass dynamic limit
|
||||
)
|
||||
|
||||
logger.info(f"Final context: {len(processed_chunks)} chunks")
|
||||
|
|
@ -2622,7 +2862,9 @@ async def naive_query(
|
|||
return sys_prompt
|
||||
|
||||
len_of_prompts = len(tokenizer.encode(query + sys_prompt))
|
||||
logger.debug(f"[naive_query]Prompt Tokens: {len_of_prompts}")
|
||||
logger.debug(
|
||||
f"[naive_query] Sending to LLM: {len_of_prompts:,} tokens (Query: {len(tokenizer.encode(query))}, System: {len(tokenizer.encode(sys_prompt))})"
|
||||
)
|
||||
|
||||
response = await use_model_func(
|
||||
query,
|
||||
|
|
@ -2746,7 +2988,9 @@ async def kg_query_with_keywords(
|
|||
|
||||
tokenizer: Tokenizer = global_config["tokenizer"]
|
||||
len_of_prompts = len(tokenizer.encode(query + sys_prompt))
|
||||
logger.debug(f"[kg_query_with_keywords]Prompt Tokens: {len_of_prompts}")
|
||||
logger.debug(
|
||||
f"[kg_query_with_keywords] Sending to LLM: {len_of_prompts:,} tokens (Query: {len(tokenizer.encode(query))}, System: {len(tokenizer.encode(sys_prompt))})"
|
||||
)
|
||||
|
||||
# 6. Generate response
|
||||
response = await use_model_func(
|
||||
|
|
@ -2866,6 +3110,7 @@ async def apply_rerank_if_enabled(
|
|||
query: str,
|
||||
retrieved_docs: list[dict],
|
||||
global_config: dict,
|
||||
enable_rerank: bool = True,
|
||||
top_k: int = None,
|
||||
) -> list[dict]:
|
||||
"""
|
||||
|
|
@ -2875,18 +3120,19 @@ async def apply_rerank_if_enabled(
|
|||
query: The search query
|
||||
retrieved_docs: List of retrieved documents
|
||||
global_config: Global configuration containing rerank settings
|
||||
enable_rerank: Whether to enable reranking from query parameter
|
||||
top_k: Number of top documents to return after reranking
|
||||
|
||||
Returns:
|
||||
Reranked documents if rerank is enabled, otherwise original documents
|
||||
"""
|
||||
if not global_config.get("enable_rerank", False) or not retrieved_docs:
|
||||
if not enable_rerank or not retrieved_docs:
|
||||
return retrieved_docs
|
||||
|
||||
rerank_func = global_config.get("rerank_model_func")
|
||||
if not rerank_func:
|
||||
logger.debug(
|
||||
"Rerank is enabled but no rerank function provided, skipping rerank"
|
||||
logger.warning(
|
||||
"Rerank is enabled but no rerank model is configured. Please set up a rerank model or set enable_rerank=False in query parameters."
|
||||
)
|
||||
return retrieved_docs
|
||||
|
||||
|
|
@ -2923,6 +3169,7 @@ async def process_chunks_unified(
|
|||
query_param: QueryParam,
|
||||
global_config: dict,
|
||||
source_type: str = "mixed",
|
||||
chunk_token_limit: int = None, # Add parameter for dynamic token limit
|
||||
) -> list[dict]:
|
||||
"""
|
||||
Unified processing for text chunks: deduplication, chunk_top_k limiting, reranking, and token truncation.
|
||||
|
|
@ -2933,6 +3180,7 @@ async def process_chunks_unified(
|
|||
query_param: Query parameters containing configuration
|
||||
global_config: Global configuration dictionary
|
||||
source_type: Source type for logging ("vector", "entity", "relationship", "mixed")
|
||||
chunk_token_limit: Dynamic token limit for chunks (if None, uses default)
|
||||
|
||||
Returns:
|
||||
Processed and filtered list of text chunks
|
||||
|
|
@ -2954,12 +3202,13 @@ async def process_chunks_unified(
|
|||
)
|
||||
|
||||
# 2. Apply reranking if enabled and query is provided
|
||||
if global_config.get("enable_rerank", False) and query and unique_chunks:
|
||||
rerank_top_k = query_param.chunk_rerank_top_k or len(unique_chunks)
|
||||
if query_param.enable_rerank and query and unique_chunks:
|
||||
rerank_top_k = query_param.chunk_top_k or len(unique_chunks)
|
||||
unique_chunks = await apply_rerank_if_enabled(
|
||||
query=query,
|
||||
retrieved_docs=unique_chunks,
|
||||
global_config=global_config,
|
||||
enable_rerank=query_param.enable_rerank,
|
||||
top_k=rerank_top_k,
|
||||
)
|
||||
logger.debug(f"Rerank: {len(unique_chunks)} chunks (source: {source_type})")
|
||||
|
|
@ -2975,16 +3224,25 @@ async def process_chunks_unified(
|
|||
# 4. Token-based final truncation
|
||||
tokenizer = global_config.get("tokenizer")
|
||||
if tokenizer and unique_chunks:
|
||||
# Set default chunk_token_limit if not provided
|
||||
if chunk_token_limit is None:
|
||||
# Get default from query_param or global_config
|
||||
chunk_token_limit = getattr(
|
||||
query_param,
|
||||
"max_total_tokens",
|
||||
global_config.get("MAX_TOTAL_TOKENS", 32000),
|
||||
)
|
||||
|
||||
original_count = len(unique_chunks)
|
||||
unique_chunks = truncate_list_by_token_size(
|
||||
unique_chunks,
|
||||
key=lambda x: x.get("content", ""),
|
||||
max_token_size=query_param.max_token_for_text_unit,
|
||||
max_token_size=chunk_token_limit,
|
||||
tokenizer=tokenizer,
|
||||
)
|
||||
logger.debug(
|
||||
f"Token truncation: {len(unique_chunks)} chunks from {original_count} "
|
||||
f"(max tokens: {query_param.max_token_for_text_unit}, source: {source_type})"
|
||||
f"(chunk available tokens: {chunk_token_limit}, source: {source_type})"
|
||||
)
|
||||
|
||||
return unique_chunks
|
||||
|
|
|
|||
|
|
@ -10,55 +10,58 @@ from .utils import logger
|
|||
|
||||
class RerankModel(BaseModel):
|
||||
"""
|
||||
Pydantic model class for defining a custom rerank model.
|
||||
|
||||
This class provides a convenient wrapper for rerank functions, allowing you to
|
||||
encapsulate all rerank configurations (API keys, model settings, etc.) in one place.
|
||||
|
||||
Attributes:
|
||||
rerank_func (Callable[[Any], List[Dict]]): A callable function that reranks documents.
|
||||
The function should take query and documents as input and return reranked results.
|
||||
kwargs (Dict[str, Any]): A dictionary that contains the arguments to pass to the callable function.
|
||||
This should include all necessary configurations such as model name, API key, base_url, etc.
|
||||
Wrapper for rerank functions that can be used with LightRAG.
|
||||
|
||||
Example usage:
|
||||
Rerank model example with Jina:
|
||||
```python
|
||||
rerank_model = RerankModel(
|
||||
rerank_func=jina_rerank,
|
||||
kwargs={
|
||||
"model": "BAAI/bge-reranker-v2-m3",
|
||||
"api_key": "your_api_key_here",
|
||||
"base_url": "https://api.jina.ai/v1/rerank"
|
||||
}
|
||||
```python
|
||||
from lightrag.rerank import RerankModel, jina_rerank
|
||||
|
||||
# Create rerank model
|
||||
rerank_model = RerankModel(
|
||||
rerank_func=jina_rerank,
|
||||
kwargs={
|
||||
"model": "BAAI/bge-reranker-v2-m3",
|
||||
"api_key": "your_api_key_here",
|
||||
"base_url": "https://api.jina.ai/v1/rerank"
|
||||
}
|
||||
)
|
||||
|
||||
# Use in LightRAG
|
||||
rag = LightRAG(
|
||||
rerank_model_func=rerank_model.rerank,
|
||||
# ... other configurations
|
||||
)
|
||||
|
||||
# Query with rerank enabled (default)
|
||||
result = await rag.aquery(
|
||||
"your query",
|
||||
param=QueryParam(enable_rerank=True)
|
||||
)
|
||||
```
|
||||
|
||||
Or define a custom function directly:
|
||||
```python
|
||||
async def my_rerank_func(query: str, documents: list, top_k: int = None, **kwargs):
|
||||
return await jina_rerank(
|
||||
query=query,
|
||||
documents=documents,
|
||||
model="BAAI/bge-reranker-v2-m3",
|
||||
api_key="your_api_key_here",
|
||||
top_k=top_k or 10,
|
||||
**kwargs
|
||||
)
|
||||
|
||||
# Use in LightRAG
|
||||
rag = LightRAG(
|
||||
enable_rerank=True,
|
||||
rerank_model_func=rerank_model.rerank,
|
||||
# ... other configurations
|
||||
)
|
||||
```
|
||||
rag = LightRAG(
|
||||
rerank_model_func=my_rerank_func,
|
||||
# ... other configurations
|
||||
)
|
||||
|
||||
Or define a custom function directly:
|
||||
```python
|
||||
async def my_rerank_func(query: str, documents: list, top_k: int = None, **kwargs):
|
||||
return await jina_rerank(
|
||||
query=query,
|
||||
documents=documents,
|
||||
model="BAAI/bge-reranker-v2-m3",
|
||||
api_key="your_api_key_here",
|
||||
top_k=top_k or 10,
|
||||
**kwargs
|
||||
)
|
||||
|
||||
rag = LightRAG(
|
||||
enable_rerank=True,
|
||||
rerank_model_func=my_rerank_func,
|
||||
# ... other configurations
|
||||
)
|
||||
```
|
||||
# Control rerank per query
|
||||
result = await rag.aquery(
|
||||
"your query",
|
||||
param=QueryParam(enable_rerank=True) # Enable rerank for this query
|
||||
)
|
||||
```
|
||||
"""
|
||||
|
||||
rerank_func: Callable[[Any], List[Dict]]
|
||||
|
|
|
|||
|
|
@ -795,7 +795,9 @@ def process_combine_contexts(*context_lists):
|
|||
if not context_list: # Skip empty lists
|
||||
continue
|
||||
for item in context_list:
|
||||
content_dict = {k: v for k, v in item.items() if k != "id"}
|
||||
content_dict = {
|
||||
k: v for k, v in item.items() if k != "id" and k != "created_at"
|
||||
}
|
||||
content_key = tuple(sorted(content_dict.items()))
|
||||
if content_key not in seen_content:
|
||||
seen_content[content_key] = item
|
||||
|
|
|
|||
|
|
@ -106,12 +106,14 @@ export type QueryRequest = {
|
|||
stream?: boolean
|
||||
/** Number of top items to retrieve. Represents entities in 'local' mode and relationships in 'global' mode. */
|
||||
top_k?: number
|
||||
/** Maximum number of tokens allowed for each retrieved text chunk. */
|
||||
max_token_for_text_unit?: number
|
||||
/** Maximum number of tokens allocated for relationship descriptions in global retrieval. */
|
||||
max_token_for_global_context?: number
|
||||
/** Maximum number of tokens allocated for entity descriptions in local retrieval. */
|
||||
max_token_for_local_context?: number
|
||||
/** Maximum number of text chunks to retrieve and keep after reranking. */
|
||||
chunk_top_k?: number
|
||||
/** Maximum number of tokens allocated for entity context in unified token control system. */
|
||||
max_entity_tokens?: number
|
||||
/** Maximum number of tokens allocated for relationship context in unified token control system. */
|
||||
max_relation_tokens?: number
|
||||
/** Maximum total tokens budget for the entire query context (entities + relations + chunks + system prompt). */
|
||||
max_total_tokens?: number
|
||||
/**
|
||||
* Stores past conversation history to maintain context.
|
||||
* Format: [{"role": "user/assistant", "content": "message"}].
|
||||
|
|
@ -121,6 +123,8 @@ export type QueryRequest = {
|
|||
history_turns?: number
|
||||
/** User-provided prompt for the query. If provided, this will be used instead of the default value from prompt template. */
|
||||
user_prompt?: string
|
||||
/** Enable reranking for retrieved text chunks. If True but no rerank model is configured, a warning will be issued. Default is True. */
|
||||
enable_rerank?: boolean
|
||||
}
|
||||
|
||||
export type QueryResponse = {
|
||||
|
|
|
|||
|
|
@ -119,7 +119,6 @@ export default function QuerySettings() {
|
|||
</Tooltip>
|
||||
</TooltipProvider>
|
||||
<div>
|
||||
{/* Removed sr-only label */}
|
||||
<Input
|
||||
id="top_k"
|
||||
type="number"
|
||||
|
|
@ -136,120 +135,148 @@ export default function QuerySettings() {
|
|||
}}
|
||||
min={1}
|
||||
placeholder={t('retrievePanel.querySettings.topKPlaceholder')}
|
||||
className="h-9"
|
||||
/>
|
||||
</div>
|
||||
</>
|
||||
|
||||
{/* Max Tokens */}
|
||||
{/* Chunk Top K */}
|
||||
<>
|
||||
<>
|
||||
<TooltipProvider>
|
||||
<Tooltip>
|
||||
<TooltipTrigger asChild>
|
||||
<label htmlFor="max_token_for_text_unit" className="ml-1 cursor-help">
|
||||
{t('retrievePanel.querySettings.maxTokensTextUnit')}
|
||||
</label>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent side="left">
|
||||
<p>{t('retrievePanel.querySettings.maxTokensTextUnitTooltip')}</p>
|
||||
</TooltipContent>
|
||||
</Tooltip>
|
||||
</TooltipProvider>
|
||||
<div>
|
||||
{/* Removed sr-only label */}
|
||||
<Input
|
||||
id="max_token_for_text_unit"
|
||||
type="number"
|
||||
value={querySettings.max_token_for_text_unit ?? ''}
|
||||
onChange={(e) => {
|
||||
const value = e.target.value
|
||||
handleChange('max_token_for_text_unit', value === '' ? '' : parseInt(value) || 0)
|
||||
}}
|
||||
onBlur={(e) => {
|
||||
const value = e.target.value
|
||||
if (value === '' || isNaN(parseInt(value))) {
|
||||
handleChange('max_token_for_text_unit', 10000)
|
||||
}
|
||||
}}
|
||||
min={1}
|
||||
placeholder={t('retrievePanel.querySettings.maxTokensTextUnit')}
|
||||
className="h-9"
|
||||
/>
|
||||
</div>
|
||||
</>
|
||||
<TooltipProvider>
|
||||
<Tooltip>
|
||||
<TooltipTrigger asChild>
|
||||
<label htmlFor="chunk_top_k" className="ml-1 cursor-help">
|
||||
{t('retrievePanel.querySettings.chunkTopK')}
|
||||
</label>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent side="left">
|
||||
<p>{t('retrievePanel.querySettings.chunkTopKTooltip')}</p>
|
||||
</TooltipContent>
|
||||
</Tooltip>
|
||||
</TooltipProvider>
|
||||
<div>
|
||||
<Input
|
||||
id="chunk_top_k"
|
||||
type="number"
|
||||
value={querySettings.chunk_top_k ?? ''}
|
||||
onChange={(e) => {
|
||||
const value = e.target.value
|
||||
handleChange('chunk_top_k', value === '' ? '' : parseInt(value) || 0)
|
||||
}}
|
||||
onBlur={(e) => {
|
||||
const value = e.target.value
|
||||
if (value === '' || isNaN(parseInt(value))) {
|
||||
handleChange('chunk_top_k', 1)
|
||||
}
|
||||
}}
|
||||
min={1}
|
||||
placeholder={t('retrievePanel.querySettings.chunkTopKPlaceholder')}
|
||||
/>
|
||||
</div>
|
||||
</>
|
||||
|
||||
<>
|
||||
<TooltipProvider>
|
||||
<Tooltip>
|
||||
<TooltipTrigger asChild>
|
||||
<label htmlFor="max_token_for_global_context" className="ml-1 cursor-help">
|
||||
{t('retrievePanel.querySettings.maxTokensGlobalContext')}
|
||||
</label>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent side="left">
|
||||
<p>{t('retrievePanel.querySettings.maxTokensGlobalContextTooltip')}</p>
|
||||
</TooltipContent>
|
||||
</Tooltip>
|
||||
</TooltipProvider>
|
||||
<div>
|
||||
{/* Removed sr-only label */}
|
||||
<Input
|
||||
id="max_token_for_global_context"
|
||||
type="number"
|
||||
value={querySettings.max_token_for_global_context ?? ''}
|
||||
onChange={(e) => {
|
||||
const value = e.target.value
|
||||
handleChange('max_token_for_global_context', value === '' ? '' : parseInt(value) || 0)
|
||||
}}
|
||||
onBlur={(e) => {
|
||||
const value = e.target.value
|
||||
if (value === '' || isNaN(parseInt(value))) {
|
||||
handleChange('max_token_for_global_context', 4000)
|
||||
}
|
||||
}}
|
||||
min={1}
|
||||
placeholder={t('retrievePanel.querySettings.maxTokensGlobalContext')}
|
||||
className="h-9"
|
||||
/>
|
||||
</div>
|
||||
</>
|
||||
{/* Max Entity Tokens */}
|
||||
<>
|
||||
<TooltipProvider>
|
||||
<Tooltip>
|
||||
<TooltipTrigger asChild>
|
||||
<label htmlFor="max_entity_tokens" className="ml-1 cursor-help">
|
||||
{t('retrievePanel.querySettings.maxEntityTokens')}
|
||||
</label>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent side="left">
|
||||
<p>{t('retrievePanel.querySettings.maxEntityTokensTooltip')}</p>
|
||||
</TooltipContent>
|
||||
</Tooltip>
|
||||
</TooltipProvider>
|
||||
<div>
|
||||
<Input
|
||||
id="max_entity_tokens"
|
||||
type="number"
|
||||
value={querySettings.max_entity_tokens ?? ''}
|
||||
onChange={(e) => {
|
||||
const value = e.target.value
|
||||
handleChange('max_entity_tokens', value === '' ? '' : parseInt(value) || 0)
|
||||
}}
|
||||
onBlur={(e) => {
|
||||
const value = e.target.value
|
||||
if (value === '' || isNaN(parseInt(value))) {
|
||||
handleChange('max_entity_tokens', 1000)
|
||||
}
|
||||
}}
|
||||
min={1}
|
||||
placeholder={t('retrievePanel.querySettings.maxEntityTokensPlaceholder')}
|
||||
/>
|
||||
</div>
|
||||
</>
|
||||
|
||||
<>
|
||||
<TooltipProvider>
|
||||
<Tooltip>
|
||||
<TooltipTrigger asChild>
|
||||
<label htmlFor="max_token_for_local_context" className="ml-1 cursor-help">
|
||||
{t('retrievePanel.querySettings.maxTokensLocalContext')}
|
||||
</label>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent side="left">
|
||||
<p>{t('retrievePanel.querySettings.maxTokensLocalContextTooltip')}</p>
|
||||
</TooltipContent>
|
||||
</Tooltip>
|
||||
</TooltipProvider>
|
||||
<div>
|
||||
{/* Removed sr-only label */}
|
||||
<Input
|
||||
id="max_token_for_local_context"
|
||||
type="number"
|
||||
value={querySettings.max_token_for_local_context ?? ''}
|
||||
onChange={(e) => {
|
||||
const value = e.target.value
|
||||
handleChange('max_token_for_local_context', value === '' ? '' : parseInt(value) || 0)
|
||||
}}
|
||||
onBlur={(e) => {
|
||||
const value = e.target.value
|
||||
if (value === '' || isNaN(parseInt(value))) {
|
||||
handleChange('max_token_for_local_context', 4000)
|
||||
}
|
||||
}}
|
||||
min={1}
|
||||
placeholder={t('retrievePanel.querySettings.maxTokensLocalContext')}
|
||||
className="h-9"
|
||||
/>
|
||||
</div>
|
||||
</>
|
||||
{/* Max Relation Tokens */}
|
||||
<>
|
||||
<TooltipProvider>
|
||||
<Tooltip>
|
||||
<TooltipTrigger asChild>
|
||||
<label htmlFor="max_relation_tokens" className="ml-1 cursor-help">
|
||||
{t('retrievePanel.querySettings.maxRelationTokens')}
|
||||
</label>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent side="left">
|
||||
<p>{t('retrievePanel.querySettings.maxRelationTokensTooltip')}</p>
|
||||
</TooltipContent>
|
||||
</Tooltip>
|
||||
</TooltipProvider>
|
||||
<div>
|
||||
<Input
|
||||
id="max_relation_tokens"
|
||||
type="number"
|
||||
value={querySettings.max_relation_tokens ?? ''}
|
||||
onChange={(e) => {
|
||||
const value = e.target.value
|
||||
handleChange('max_relation_tokens', value === '' ? '' : parseInt(value) || 0)
|
||||
}}
|
||||
onBlur={(e) => {
|
||||
const value = e.target.value
|
||||
if (value === '' || isNaN(parseInt(value))) {
|
||||
handleChange('max_relation_tokens', 1000)
|
||||
}
|
||||
}}
|
||||
min={1}
|
||||
placeholder={t('retrievePanel.querySettings.maxRelationTokensPlaceholder')}
|
||||
/>
|
||||
</div>
|
||||
</>
|
||||
|
||||
{/* Max Total Tokens */}
|
||||
<>
|
||||
<TooltipProvider>
|
||||
<Tooltip>
|
||||
<TooltipTrigger asChild>
|
||||
<label htmlFor="max_total_tokens" className="ml-1 cursor-help">
|
||||
{t('retrievePanel.querySettings.maxTotalTokens')}
|
||||
</label>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent side="left">
|
||||
<p>{t('retrievePanel.querySettings.maxTotalTokensTooltip')}</p>
|
||||
</TooltipContent>
|
||||
</Tooltip>
|
||||
</TooltipProvider>
|
||||
<div>
|
||||
<Input
|
||||
id="max_total_tokens"
|
||||
type="number"
|
||||
value={querySettings.max_total_tokens ?? ''}
|
||||
onChange={(e) => {
|
||||
const value = e.target.value
|
||||
handleChange('max_total_tokens', value === '' ? '' : parseInt(value) || 0)
|
||||
}}
|
||||
onBlur={(e) => {
|
||||
const value = e.target.value
|
||||
if (value === '' || isNaN(parseInt(value))) {
|
||||
handleChange('max_total_tokens', 1000)
|
||||
}
|
||||
}}
|
||||
min={1}
|
||||
placeholder={t('retrievePanel.querySettings.maxTotalTokensPlaceholder')}
|
||||
/>
|
||||
</div>
|
||||
</>
|
||||
|
||||
{/* History Turns */}
|
||||
|
|
@ -267,7 +294,6 @@ export default function QuerySettings() {
|
|||
</Tooltip>
|
||||
</TooltipProvider>
|
||||
<div>
|
||||
{/* Removed sr-only label */}
|
||||
<Input
|
||||
id="history_turns"
|
||||
type="number"
|
||||
|
|
@ -316,6 +342,27 @@ export default function QuerySettings() {
|
|||
|
||||
{/* Toggle Options */}
|
||||
<>
|
||||
<div className="flex items-center gap-2">
|
||||
<TooltipProvider>
|
||||
<Tooltip>
|
||||
<TooltipTrigger asChild>
|
||||
<label htmlFor="enable_rerank" className="flex-1 ml-1 cursor-help">
|
||||
{t('retrievePanel.querySettings.enableRerank')}
|
||||
</label>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent side="left">
|
||||
<p>{t('retrievePanel.querySettings.enableRerankTooltip')}</p>
|
||||
</TooltipContent>
|
||||
</Tooltip>
|
||||
</TooltipProvider>
|
||||
<Checkbox
|
||||
className="mr-1 cursor-pointer"
|
||||
id="enable_rerank"
|
||||
checked={querySettings.enable_rerank}
|
||||
onCheckedChange={(checked) => handleChange('enable_rerank', checked)}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="flex items-center gap-2">
|
||||
<TooltipProvider>
|
||||
<Tooltip>
|
||||
|
|
@ -379,6 +426,7 @@ export default function QuerySettings() {
|
|||
/>
|
||||
</div>
|
||||
</>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</CardContent>
|
||||
|
|
|
|||
|
|
@ -363,16 +363,22 @@
|
|||
"singleParagraph": "فقرة واحدة",
|
||||
"bulletPoints": "نقاط نقطية"
|
||||
},
|
||||
"topK": "أعلى K نتائج",
|
||||
"topKTooltip": "عدد العناصر العلوية للاسترجاع. يمثل الكيانات في وضع 'محلي' والعلاقات في وضع 'عالمي'",
|
||||
"topKPlaceholder": "عدد النتائج",
|
||||
"maxTokensTextUnit": "أقصى عدد من الرموز لوحدة النص",
|
||||
"maxTokensTextUnitTooltip": "الحد الأقصى لعدد الرموز المسموح به لكل جزء نصي مسترجع",
|
||||
"maxTokensGlobalContext": "أقصى عدد من الرموز للسياق العالمي",
|
||||
"maxTokensGlobalContextTooltip": "الحد الأقصى لعدد الرموز المخصص لأوصاف العلاقات في الاسترجاع العالمي",
|
||||
"maxTokensLocalContext": "أقصى عدد من الرموز للسياق المحلي",
|
||||
"maxTokensLocalContextTooltip": "الحد الأقصى لعدد الرموز المخصص لأوصاف الكيانات في الاسترجاع المحلي",
|
||||
"historyTurns": "دورات التاريخ",
|
||||
"topK": "أعلى K",
|
||||
"topKTooltip": "عدد العناصر العلوية للاسترداد. يمثل الكيانات في الوضع 'المحلي' والعلاقات في الوضع 'العالمي'.",
|
||||
"topKPlaceholder": "أدخل قيمة أعلى k",
|
||||
"chunkTopK": "أعلى K للقطع",
|
||||
"chunkTopKTooltip": "العدد الأقصى لقطع النص المراد استردادها ومعالجتها.",
|
||||
"chunkTopKPlaceholder": "أدخل قيمة أعلى k للقطع",
|
||||
"chunkRerankTopK": "أعلى K لإعادة الترتيب",
|
||||
"chunkRerankTopKTooltip": "عدد قطع النص المراد الاحتفاظ بها بعد إعادة الترتيب.",
|
||||
"chunkRerankTopKPlaceholder": "أدخل قيمة أعلى k لإعادة الترتيب",
|
||||
"maxEntityTokens": "الحد الأقصى لرموز الكيان",
|
||||
"maxEntityTokensTooltip": "الحد الأقصى لعدد الرموز المخصصة لسياق الكيان في نظام التحكم الموحد في الرموز",
|
||||
"maxRelationTokens": "الحد الأقصى لرموز العلاقة",
|
||||
"maxRelationTokensTooltip": "الحد الأقصى لعدد الرموز المخصصة لسياق العلاقة في نظام التحكم الموحد في الرموز",
|
||||
"maxTotalTokens": "إجمالي الحد الأقصى للرموز",
|
||||
"maxTotalTokensTooltip": "الحد الأقصى الإجمالي لميزانية الرموز لسياق الاستعلام بالكامل (الكيانات + العلاقات + الأجزاء + موجه النظام)",
|
||||
"historyTurns": "أدوار التاريخ",
|
||||
"historyTurnsTooltip": "عدد الدورات الكاملة للمحادثة (أزواج المستخدم-المساعد) التي يجب مراعاتها في سياق الرد",
|
||||
"historyTurnsPlaceholder": "عدد دورات التاريخ",
|
||||
"onlyNeedContext": "تحتاج فقط إلى السياق",
|
||||
|
|
@ -383,7 +389,9 @@
|
|||
"streamResponseTooltip": "إذا كان صحيحًا، يتيح إخراج التدفق للردود في الوقت الفعلي",
|
||||
"userPrompt": "مطالبة مخصصة",
|
||||
"userPromptTooltip": "تقديم متطلبات استجابة إضافية إلى نموذج اللغة الكبير (غير متعلقة بمحتوى الاستعلام، فقط لمعالجة المخرجات).",
|
||||
"userPromptPlaceholder": "أدخل مطالبة مخصصة (اختياري)"
|
||||
"userPromptPlaceholder": "أدخل مطالبة مخصصة (اختياري)",
|
||||
"enableRerank": "تمكين إعادة الترتيب",
|
||||
"enableRerankTooltip": "تمكين إعادة ترتيب أجزاء النص المسترجعة. إذا كان True ولكن لم يتم تكوين نموذج إعادة الترتيب، فسيتم إصدار تحذير. افتراضي True."
|
||||
}
|
||||
},
|
||||
"apiSite": {
|
||||
|
|
|
|||
|
|
@ -363,15 +363,21 @@
|
|||
"singleParagraph": "Single Paragraph",
|
||||
"bulletPoints": "Bullet Points"
|
||||
},
|
||||
"topK": "Top K Results",
|
||||
"topKTooltip": "Number of top items to retrieve. Represents entities in 'local' mode and relationships in 'global' mode",
|
||||
"topKPlaceholder": "Number of results",
|
||||
"maxTokensTextUnit": "Max Tokens for Text Unit",
|
||||
"maxTokensTextUnitTooltip": "Maximum number of tokens allowed for each retrieved text chunk",
|
||||
"maxTokensGlobalContext": "Max Tokens for Global Context",
|
||||
"maxTokensGlobalContextTooltip": "Maximum number of tokens allocated for relationship descriptions in global retrieval",
|
||||
"maxTokensLocalContext": "Max Tokens for Local Context",
|
||||
"maxTokensLocalContextTooltip": "Maximum number of tokens allocated for entity descriptions in local retrieval",
|
||||
"topK": "Top K",
|
||||
"topKTooltip": "Number of top items to retrieve. Represents entities in 'local' mode and relationships in 'global' mode.",
|
||||
"topKPlaceholder": "Enter top k value",
|
||||
"chunkTopK": "Chunk Top K",
|
||||
"chunkTopKTooltip": "Maximum number of text chunks to retrieve and process.",
|
||||
"chunkTopKPlaceholder": "Enter chunk top k value",
|
||||
"chunkRerankTopK": "Chunk Rerank Top K",
|
||||
"chunkRerankTopKTooltip": "Number of text chunks to keep after reranking.",
|
||||
"chunkRerankTopKPlaceholder": "Enter rerank top k value",
|
||||
"maxEntityTokens": "Max Entity Tokens",
|
||||
"maxEntityTokensTooltip": "Maximum number of tokens allocated for entity context in unified token control system",
|
||||
"maxRelationTokens": "Max Relation Tokens",
|
||||
"maxRelationTokensTooltip": "Maximum number of tokens allocated for relationship context in unified token control system",
|
||||
"maxTotalTokens": "Max Total Tokens",
|
||||
"maxTotalTokensTooltip": "Maximum total tokens budget for the entire query context (entities + relations + chunks + system prompt)",
|
||||
"historyTurns": "History Turns",
|
||||
"historyTurnsTooltip": "Number of complete conversation turns (user-assistant pairs) to consider in the response context",
|
||||
"historyTurnsPlaceholder": "Number of history turns",
|
||||
|
|
@ -383,7 +389,9 @@
|
|||
"streamResponseTooltip": "If True, enables streaming output for real-time responses",
|
||||
"userPrompt": "User Prompt",
|
||||
"userPromptTooltip": "Provide additional response requirements to the LLM (unrelated to query content, only for output processing).",
|
||||
"userPromptPlaceholder": "Enter custom prompt (optional)"
|
||||
"userPromptPlaceholder": "Enter custom prompt (optional)",
|
||||
"enableRerank": "Enable Rerank",
|
||||
"enableRerankTooltip": "Enable reranking for retrieved text chunks. If True but no rerank model is configured, a warning will be issued. Default is True."
|
||||
}
|
||||
},
|
||||
"apiSite": {
|
||||
|
|
|
|||
|
|
@ -363,15 +363,21 @@
|
|||
"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",
|
||||
"topK": "Top K",
|
||||
"topKTooltip": "Nombre d'éléments principaux à récupérer. Représente les entités en mode 'local' et les relations en mode 'global'.",
|
||||
"topKPlaceholder": "Entrez la valeur top k",
|
||||
"chunkTopK": "Top K des Chunks",
|
||||
"chunkTopKTooltip": "Nombre maximum de chunks de texte à récupérer et traiter.",
|
||||
"chunkTopKPlaceholder": "Entrez la valeur top k des chunks",
|
||||
"chunkRerankTopK": "Top K du Reclassement",
|
||||
"chunkRerankTopKTooltip": "Nombre de chunks de texte à conserver après reclassement.",
|
||||
"chunkRerankTopKPlaceholder": "Entrez la valeur top k du reclassement",
|
||||
"maxEntityTokens": "Limite de jetons d'entité",
|
||||
"maxEntityTokensTooltip": "Nombre maximum de jetons alloués au contexte d'entité dans le système de contrôle de jetons unifié",
|
||||
"maxRelationTokens": "Limite de jetons de relation",
|
||||
"maxRelationTokensTooltip": "Nombre maximum de jetons alloués au contexte de relation dans le système de contrôle de jetons unifié",
|
||||
"maxTotalTokens": "Limite totale de jetons",
|
||||
"maxTotalTokensTooltip": "Budget total maximum de jetons pour l'ensemble du contexte de requête (entités + relations + blocs + prompt système)",
|
||||
"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",
|
||||
|
|
@ -383,7 +389,9 @@
|
|||
"streamResponseTooltip": "Si vrai, active la sortie en flux pour des réponses en temps réel",
|
||||
"userPrompt": "Invite personnalisée",
|
||||
"userPromptTooltip": "Fournir des exigences de réponse supplémentaires au LLM (sans rapport avec le contenu de la requête, uniquement pour le traitement de sortie).",
|
||||
"userPromptPlaceholder": "Entrez une invite personnalisée (facultatif)"
|
||||
"userPromptPlaceholder": "Entrez une invite personnalisée (facultatif)",
|
||||
"enableRerank": "Activer le Reclassement",
|
||||
"enableRerankTooltip": "Active le reclassement pour les fragments de texte récupérés. Si True mais qu'aucun modèle de reclassement n'est configuré, un avertissement sera émis. True par défaut."
|
||||
}
|
||||
},
|
||||
"apiSite": {
|
||||
|
|
|
|||
|
|
@ -363,15 +363,21 @@
|
|||
"singleParagraph": "单段落",
|
||||
"bulletPoints": "要点"
|
||||
},
|
||||
"topK": "Top K结果",
|
||||
"topKTooltip": "检索的顶部项目数。在'local'模式下表示实体,在'global'模式下表示关系",
|
||||
"topKPlaceholder": "结果数量",
|
||||
"maxTokensTextUnit": "文本单元最大令牌数",
|
||||
"maxTokensTextUnitTooltip": "每个检索文本块允许的最大令牌数",
|
||||
"maxTokensGlobalContext": "全局上下文最大令牌数",
|
||||
"maxTokensGlobalContextTooltip": "全局检索中关系描述的最大令牌数",
|
||||
"maxTokensLocalContext": "本地上下文最大令牌数",
|
||||
"maxTokensLocalContextTooltip": "本地检索中实体描述的最大令牌数",
|
||||
"topK": "Top K",
|
||||
"topKTooltip": "检索的顶部条目数量。在'local'模式下表示实体,在'global'模式下表示关系。",
|
||||
"topKPlaceholder": "输入top k值",
|
||||
"chunkTopK": "文本块 Top K",
|
||||
"chunkTopKTooltip": "检索和处理的最大文本块数量。",
|
||||
"chunkTopKPlaceholder": "输入文本块top k值",
|
||||
"chunkRerankTopK": "重排序 Top K",
|
||||
"chunkRerankTopKTooltip": "重排序后保留的文本块数量。",
|
||||
"chunkRerankTopKPlaceholder": "输入重排序top k值",
|
||||
"maxEntityTokens": "实体令牌数上限",
|
||||
"maxEntityTokensTooltip": "统一令牌控制系统中分配给实体上下文的最大令牌数",
|
||||
"maxRelationTokens": "关系令牌数上限",
|
||||
"maxRelationTokensTooltip": "统一令牌控制系统中分配给关系上下文的最大令牌数",
|
||||
"maxTotalTokens": "总令牌数上限",
|
||||
"maxTotalTokensTooltip": "整个查询上下文的最大总令牌预算(实体+关系+文档块+系统提示)",
|
||||
"historyTurns": "历史轮次",
|
||||
"historyTurnsTooltip": "响应上下文中考虑的完整对话轮次(用户-助手对)数量",
|
||||
"historyTurnsPlaceholder": "历史轮次数",
|
||||
|
|
@ -383,7 +389,9 @@
|
|||
"streamResponseTooltip": "如果为True,启用实时流式输出响应",
|
||||
"userPrompt": "用户提示词",
|
||||
"userPromptTooltip": "向LLM提供额外的响应要求(与查询内容无关,仅用于处理输出)。",
|
||||
"userPromptPlaceholder": "输入自定义提示词(可选)"
|
||||
"userPromptPlaceholder": "输入自定义提示词(可选)",
|
||||
"enableRerank": "启用重排",
|
||||
"enableRerankTooltip": "为检索到的文本块启用重排。如果为True但未配置重排模型,将发出警告。默认为True。"
|
||||
}
|
||||
},
|
||||
"apiSite": {
|
||||
|
|
|
|||
|
|
@ -304,7 +304,7 @@
|
|||
"file_path": "來源",
|
||||
"keywords": "Keys",
|
||||
"weight": "權重"
|
||||
}
|
||||
}
|
||||
},
|
||||
"edge": {
|
||||
"title": "關係",
|
||||
|
|
@ -363,15 +363,15 @@
|
|||
"singleParagraph": "單段落",
|
||||
"bulletPoints": "重點"
|
||||
},
|
||||
"topK": "Top K結果",
|
||||
"topKTooltip": "檢索的前幾項結果數。在'local'模式下表示實體,在'global'模式下表示關係",
|
||||
"topKPlaceholder": "結果數量",
|
||||
"maxTokensTextUnit": "文字單元最大權杖數",
|
||||
"maxTokensTextUnitTooltip": "每個檢索文字區塊允許的最大權杖數",
|
||||
"maxTokensGlobalContext": "全域上下文最大權杖數",
|
||||
"maxTokensGlobalContextTooltip": "全域檢索中關係描述的最大權杖數",
|
||||
"maxTokensLocalContext": "本地上下文最大權杖數",
|
||||
"maxTokensLocalContextTooltip": "本地檢索中實體描述的最大權杖數",
|
||||
"topK": "Top K",
|
||||
"topKTooltip": "檢索的頂部條目數量。在'local'模式下表示實體,在'global'模式下表示關係。",
|
||||
"topKPlaceholder": "輸入top k值",
|
||||
"chunkTopK": "文字區塊 Top K",
|
||||
"chunkTopKTooltip": "檢索和處理的最大文字區塊數量。",
|
||||
"chunkTopKPlaceholder": "輸入文字區塊top k值",
|
||||
"chunkRerankTopK": "重新排序 Top K",
|
||||
"chunkRerankTopKTooltip": "重新排序後保留的文字區塊數量。",
|
||||
"chunkRerankTopKPlaceholder": "輸入重新排序top k值",
|
||||
"historyTurns": "歷史輪次",
|
||||
"historyTurnsTooltip": "回應上下文中考慮的完整對話輪次(使用者-助手對)數量",
|
||||
"historyTurnsPlaceholder": "歷史輪次數",
|
||||
|
|
@ -383,7 +383,15 @@
|
|||
"streamResponseTooltip": "如果為True,啟用即時串流輸出回應",
|
||||
"userPrompt": "用戶提示詞",
|
||||
"userPromptTooltip": "向LLM提供額外的響應要求(與查詢內容無關,僅用於處理輸出)。",
|
||||
"userPromptPlaceholder": "輸入自定義提示詞(可選)"
|
||||
"userPromptPlaceholder": "輸入自定義提示詞(可選)",
|
||||
"enableRerank": "啟用重排",
|
||||
"enableRerankTooltip": "為檢索到的文本塊啟用重排。如果為True但未配置重排模型,將發出警告。默認為True。",
|
||||
"maxEntityTokens": "實體令牌數上限",
|
||||
"maxEntityTokensTooltip": "統一令牌控制系統中分配給實體上下文的最大令牌數",
|
||||
"maxRelationTokens": "關係令牌數上限",
|
||||
"maxRelationTokensTooltip": "統一令牌控制系統中分配給關係上下文的最大令牌數",
|
||||
"maxTotalTokens": "總令牌數上限",
|
||||
"maxTotalTokensTooltip": "整個查詢上下文的最大總令牌預算(實體+關係+文檔塊+系統提示)"
|
||||
}
|
||||
},
|
||||
"apiSite": {
|
||||
|
|
|
|||
|
|
@ -110,17 +110,17 @@ const useSettingsStoreBase = create<SettingsState>()(
|
|||
querySettings: {
|
||||
mode: 'global',
|
||||
response_type: 'Multiple Paragraphs',
|
||||
top_k: 10,
|
||||
max_token_for_text_unit: 6000,
|
||||
max_token_for_global_context: 4000,
|
||||
max_token_for_local_context: 4000,
|
||||
top_k: 40,
|
||||
chunk_top_k: 10,
|
||||
max_entity_tokens: 10000,
|
||||
max_relation_tokens: 10000,
|
||||
max_total_tokens: 32000,
|
||||
only_need_context: false,
|
||||
only_need_prompt: false,
|
||||
stream: true,
|
||||
history_turns: 3,
|
||||
hl_keywords: [],
|
||||
ll_keywords: [],
|
||||
user_prompt: ''
|
||||
user_prompt: '',
|
||||
enable_rerank: true
|
||||
},
|
||||
|
||||
setTheme: (theme: Theme) => set({ theme }),
|
||||
|
|
@ -192,7 +192,7 @@ const useSettingsStoreBase = create<SettingsState>()(
|
|||
{
|
||||
name: 'settings-storage',
|
||||
storage: createJSONStorage(() => localStorage),
|
||||
version: 14,
|
||||
version: 15,
|
||||
migrate: (state: any, version: number) => {
|
||||
if (version < 2) {
|
||||
state.showEdgeLabel = false
|
||||
|
|
@ -260,6 +260,20 @@ const useSettingsStoreBase = create<SettingsState>()(
|
|||
// Add backendMaxGraphNodes field for older versions
|
||||
state.backendMaxGraphNodes = null
|
||||
}
|
||||
if (version < 15) {
|
||||
// Add new querySettings
|
||||
state.querySettings = {
|
||||
...state.querySettings,
|
||||
mode: 'mix',
|
||||
response_type: 'Multiple Paragraphs',
|
||||
top_k: 40,
|
||||
chunk_top_k: 10,
|
||||
max_entity_tokens: 10000,
|
||||
max_relation_tokens: 10000,
|
||||
max_total_tokens: 32000,
|
||||
enable_rerank: true
|
||||
}
|
||||
}
|
||||
return state
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue