Fix linting
This commit is contained in:
parent
1766cddd6c
commit
e7948df541
1 changed files with 188 additions and 165 deletions
|
|
@ -151,17 +151,16 @@ class QueryDataResponse(BaseModel):
|
||||||
|
|
||||||
class StreamChunkResponse(BaseModel):
|
class StreamChunkResponse(BaseModel):
|
||||||
"""Response model for streaming chunks in NDJSON format"""
|
"""Response model for streaming chunks in NDJSON format"""
|
||||||
|
|
||||||
references: Optional[List[Dict[str, str]]] = Field(
|
references: Optional[List[Dict[str, str]]] = Field(
|
||||||
default=None,
|
default=None,
|
||||||
description="Reference list (only in first chunk when include_references=True)"
|
description="Reference list (only in first chunk when include_references=True)",
|
||||||
)
|
)
|
||||||
response: Optional[str] = Field(
|
response: Optional[str] = Field(
|
||||||
default=None,
|
default=None, description="Response content chunk or complete response"
|
||||||
description="Response content chunk or complete response"
|
|
||||||
)
|
)
|
||||||
error: Optional[str] = Field(
|
error: Optional[str] = Field(
|
||||||
default=None,
|
default=None, description="Error message if processing fails"
|
||||||
description="Error message if processing fails"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -169,8 +168,8 @@ def create_query_routes(rag, api_key: Optional[str] = None, top_k: int = 60):
|
||||||
combined_auth = get_combined_auth_dependency(api_key)
|
combined_auth = get_combined_auth_dependency(api_key)
|
||||||
|
|
||||||
@router.post(
|
@router.post(
|
||||||
"/query",
|
"/query",
|
||||||
response_model=QueryResponse,
|
response_model=QueryResponse,
|
||||||
dependencies=[Depends(combined_auth)],
|
dependencies=[Depends(combined_auth)],
|
||||||
responses={
|
responses={
|
||||||
200: {
|
200: {
|
||||||
|
|
@ -182,7 +181,7 @@ def create_query_routes(rag, api_key: Optional[str] = None, top_k: int = 60):
|
||||||
"properties": {
|
"properties": {
|
||||||
"response": {
|
"response": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"description": "The generated response from the RAG system"
|
"description": "The generated response from the RAG system",
|
||||||
},
|
},
|
||||||
"references": {
|
"references": {
|
||||||
"type": "array",
|
"type": "array",
|
||||||
|
|
@ -190,13 +189,13 @@ def create_query_routes(rag, api_key: Optional[str] = None, top_k: int = 60):
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
"reference_id": {"type": "string"},
|
"reference_id": {"type": "string"},
|
||||||
"file_path": {"type": "string"}
|
"file_path": {"type": "string"},
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
"description": "Reference list (only included when include_references=True)"
|
"description": "Reference list (only included when include_references=True)",
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
"required": ["response"]
|
"required": ["response"],
|
||||||
},
|
},
|
||||||
"examples": {
|
"examples": {
|
||||||
"with_references": {
|
"with_references": {
|
||||||
|
|
@ -205,17 +204,23 @@ def create_query_routes(rag, api_key: Optional[str] = None, top_k: int = 60):
|
||||||
"value": {
|
"value": {
|
||||||
"response": "Artificial Intelligence (AI) is a branch of computer science that aims to create intelligent machines capable of performing tasks that typically require human intelligence, such as learning, reasoning, and problem-solving.",
|
"response": "Artificial Intelligence (AI) is a branch of computer science that aims to create intelligent machines capable of performing tasks that typically require human intelligence, such as learning, reasoning, and problem-solving.",
|
||||||
"references": [
|
"references": [
|
||||||
{"reference_id": "1", "file_path": "/documents/ai_overview.pdf"},
|
{
|
||||||
{"reference_id": "2", "file_path": "/documents/machine_learning.txt"}
|
"reference_id": "1",
|
||||||
]
|
"file_path": "/documents/ai_overview.pdf",
|
||||||
}
|
},
|
||||||
|
{
|
||||||
|
"reference_id": "2",
|
||||||
|
"file_path": "/documents/machine_learning.txt",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
},
|
},
|
||||||
"without_references": {
|
"without_references": {
|
||||||
"summary": "Response without references",
|
"summary": "Response without references",
|
||||||
"description": "Example response when include_references=False",
|
"description": "Example response when include_references=False",
|
||||||
"value": {
|
"value": {
|
||||||
"response": "Artificial Intelligence (AI) is a branch of computer science that aims to create intelligent machines capable of performing tasks that typically require human intelligence, such as learning, reasoning, and problem-solving."
|
"response": "Artificial Intelligence (AI) is a branch of computer science that aims to create intelligent machines capable of performing tasks that typically require human intelligence, such as learning, reasoning, and problem-solving."
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
"different_modes": {
|
"different_modes": {
|
||||||
"summary": "Different query modes",
|
"summary": "Different query modes",
|
||||||
|
|
@ -225,12 +230,12 @@ def create_query_routes(rag, api_key: Optional[str] = None, top_k: int = 60):
|
||||||
"global_mode": "Provides broader context from relationship patterns",
|
"global_mode": "Provides broader context from relationship patterns",
|
||||||
"hybrid_mode": "Combines local and global approaches",
|
"hybrid_mode": "Combines local and global approaches",
|
||||||
"naive_mode": "Simple vector similarity search",
|
"naive_mode": "Simple vector similarity search",
|
||||||
"mix_mode": "Integrates knowledge graph and vector retrieval"
|
"mix_mode": "Integrates knowledge graph and vector retrieval",
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
400: {
|
400: {
|
||||||
"description": "Bad Request - Invalid input parameters",
|
"description": "Bad Request - Invalid input parameters",
|
||||||
|
|
@ -238,15 +243,13 @@ def create_query_routes(rag, api_key: Optional[str] = None, top_k: int = 60):
|
||||||
"application/json": {
|
"application/json": {
|
||||||
"schema": {
|
"schema": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {"detail": {"type": "string"}},
|
||||||
"detail": {"type": "string"}
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
"example": {
|
"example": {
|
||||||
"detail": "Query text must be at least 3 characters long"
|
"detail": "Query text must be at least 3 characters long"
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
500: {
|
500: {
|
||||||
"description": "Internal Server Error - Query processing failed",
|
"description": "Internal Server Error - Query processing failed",
|
||||||
|
|
@ -254,25 +257,23 @@ def create_query_routes(rag, api_key: Optional[str] = None, top_k: int = 60):
|
||||||
"application/json": {
|
"application/json": {
|
||||||
"schema": {
|
"schema": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {"detail": {"type": "string"}},
|
||||||
"detail": {"type": "string"}
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
"example": {
|
"example": {
|
||||||
"detail": "Failed to process query: LLM service unavailable"
|
"detail": "Failed to process query: LLM service unavailable"
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
)
|
)
|
||||||
async def query_text(request: QueryRequest):
|
async def query_text(request: QueryRequest):
|
||||||
"""
|
"""
|
||||||
Comprehensive RAG query endpoint with non-streaming response.
|
Comprehensive RAG query endpoint with non-streaming response.
|
||||||
|
|
||||||
This endpoint performs Retrieval-Augmented Generation (RAG) queries using various modes
|
This endpoint performs Retrieval-Augmented Generation (RAG) queries using various modes
|
||||||
to provide intelligent responses based on your knowledge base.
|
to provide intelligent responses based on your knowledge base.
|
||||||
|
|
||||||
**Query Modes:**
|
**Query Modes:**
|
||||||
- **local**: Focuses on specific entities and their direct relationships
|
- **local**: Focuses on specific entities and their direct relationships
|
||||||
- **global**: Analyzes broader patterns and relationships across the knowledge graph
|
- **global**: Analyzes broader patterns and relationships across the knowledge graph
|
||||||
|
|
@ -280,16 +281,16 @@ def create_query_routes(rag, api_key: Optional[str] = None, top_k: int = 60):
|
||||||
- **naive**: Simple vector similarity search without knowledge graph
|
- **naive**: Simple vector similarity search without knowledge graph
|
||||||
- **mix**: Integrates knowledge graph retrieval with vector search (recommended)
|
- **mix**: Integrates knowledge graph retrieval with vector search (recommended)
|
||||||
- **bypass**: Direct LLM query without knowledge retrieval
|
- **bypass**: Direct LLM query without knowledge retrieval
|
||||||
|
|
||||||
**Key Features:**
|
**Key Features:**
|
||||||
- Non-streaming response for simple integration
|
- Non-streaming response for simple integration
|
||||||
- Optional reference citations for source attribution
|
- Optional reference citations for source attribution
|
||||||
- Flexible token control for response length management
|
- Flexible token control for response length management
|
||||||
- Conversation history support for multi-turn dialogues
|
- Conversation history support for multi-turn dialogues
|
||||||
- Multiple response format options
|
- Multiple response format options
|
||||||
|
|
||||||
**Usage Examples:**
|
**Usage Examples:**
|
||||||
|
|
||||||
Basic query:
|
Basic query:
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
|
|
@ -297,7 +298,7 @@ def create_query_routes(rag, api_key: Optional[str] = None, top_k: int = 60):
|
||||||
"mode": "mix"
|
"mode": "mix"
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Advanced query with references:
|
Advanced query with references:
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
|
|
@ -308,7 +309,7 @@ def create_query_routes(rag, api_key: Optional[str] = None, top_k: int = 60):
|
||||||
"top_k": 10
|
"top_k": 10
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Conversation with history:
|
Conversation with history:
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
|
|
@ -336,7 +337,7 @@ def create_query_routes(rag, api_key: Optional[str] = None, top_k: int = 60):
|
||||||
- **references**: Source citations (if include_references=True)
|
- **references**: Source citations (if include_references=True)
|
||||||
|
|
||||||
Raises:
|
Raises:
|
||||||
HTTPException:
|
HTTPException:
|
||||||
- 400: Invalid input parameters (e.g., query too short)
|
- 400: Invalid input parameters (e.g., query too short)
|
||||||
- 500: Internal processing error (e.g., LLM service unavailable)
|
- 500: Internal processing error (e.g., LLM service unavailable)
|
||||||
"""
|
"""
|
||||||
|
|
@ -369,7 +370,7 @@ def create_query_routes(rag, api_key: Optional[str] = None, top_k: int = 60):
|
||||||
raise HTTPException(status_code=500, detail=str(e))
|
raise HTTPException(status_code=500, detail=str(e))
|
||||||
|
|
||||||
@router.post(
|
@router.post(
|
||||||
"/query/stream",
|
"/query/stream",
|
||||||
dependencies=[Depends(combined_auth)],
|
dependencies=[Depends(combined_auth)],
|
||||||
responses={
|
responses={
|
||||||
200: {
|
200: {
|
||||||
|
|
@ -380,37 +381,37 @@ def create_query_routes(rag, api_key: Optional[str] = None, top_k: int = 60):
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"format": "ndjson",
|
"format": "ndjson",
|
||||||
"description": "Newline-delimited JSON (NDJSON) format used for both streaming and non-streaming responses. For streaming: multiple lines with separate JSON objects. For non-streaming: single line with complete JSON object.",
|
"description": "Newline-delimited JSON (NDJSON) format used for both streaming and non-streaming responses. For streaming: multiple lines with separate JSON objects. For non-streaming: single line with complete JSON object.",
|
||||||
"example": '{"references": [{"reference_id": "1", "file_path": "/documents/ai.pdf"}]}\n{"response": "Artificial Intelligence is"}\n{"response": " a field of computer science"}\n{"response": " that focuses on creating intelligent machines."}'
|
"example": '{"references": [{"reference_id": "1", "file_path": "/documents/ai.pdf"}]}\n{"response": "Artificial Intelligence is"}\n{"response": " a field of computer science"}\n{"response": " that focuses on creating intelligent machines."}',
|
||||||
},
|
},
|
||||||
"examples": {
|
"examples": {
|
||||||
"streaming_with_references": {
|
"streaming_with_references": {
|
||||||
"summary": "Streaming mode with references (stream=true)",
|
"summary": "Streaming mode with references (stream=true)",
|
||||||
"description": "Multiple NDJSON lines when stream=True and include_references=True. First line contains references, subsequent lines contain response chunks.",
|
"description": "Multiple NDJSON lines when stream=True and include_references=True. First line contains references, subsequent lines contain response chunks.",
|
||||||
"value": '{"references": [{"reference_id": "1", "file_path": "/documents/ai_overview.pdf"}, {"reference_id": "2", "file_path": "/documents/ml_basics.txt"}]}\n{"response": "Artificial Intelligence (AI) is a branch of computer science"}\n{"response": " that aims to create intelligent machines capable of performing"}\n{"response": " tasks that typically require human intelligence, such as learning,"}\n{"response": " reasoning, and problem-solving."}'
|
"value": '{"references": [{"reference_id": "1", "file_path": "/documents/ai_overview.pdf"}, {"reference_id": "2", "file_path": "/documents/ml_basics.txt"}]}\n{"response": "Artificial Intelligence (AI) is a branch of computer science"}\n{"response": " that aims to create intelligent machines capable of performing"}\n{"response": " tasks that typically require human intelligence, such as learning,"}\n{"response": " reasoning, and problem-solving."}',
|
||||||
},
|
},
|
||||||
"streaming_without_references": {
|
"streaming_without_references": {
|
||||||
"summary": "Streaming mode without references (stream=true)",
|
"summary": "Streaming mode without references (stream=true)",
|
||||||
"description": "Multiple NDJSON lines when stream=True and include_references=False. Only response chunks are sent.",
|
"description": "Multiple NDJSON lines when stream=True and include_references=False. Only response chunks are sent.",
|
||||||
"value": '{"response": "Machine learning is a subset of artificial intelligence"}\n{"response": " that enables computers to learn and improve from experience"}\n{"response": " without being explicitly programmed for every task."}'
|
"value": '{"response": "Machine learning is a subset of artificial intelligence"}\n{"response": " that enables computers to learn and improve from experience"}\n{"response": " without being explicitly programmed for every task."}',
|
||||||
},
|
},
|
||||||
"non_streaming_with_references": {
|
"non_streaming_with_references": {
|
||||||
"summary": "Non-streaming mode with references (stream=false)",
|
"summary": "Non-streaming mode with references (stream=false)",
|
||||||
"description": "Single NDJSON line when stream=False and include_references=True. Complete response with references in one message.",
|
"description": "Single NDJSON line when stream=False and include_references=True. Complete response with references in one message.",
|
||||||
"value": '{"references": [{"reference_id": "1", "file_path": "/documents/neural_networks.pdf"}], "response": "Neural networks are computational models inspired by biological neural networks that consist of interconnected nodes (neurons) organized in layers. They are fundamental to deep learning and can learn complex patterns from data through training processes."}'
|
"value": '{"references": [{"reference_id": "1", "file_path": "/documents/neural_networks.pdf"}], "response": "Neural networks are computational models inspired by biological neural networks that consist of interconnected nodes (neurons) organized in layers. They are fundamental to deep learning and can learn complex patterns from data through training processes."}',
|
||||||
},
|
},
|
||||||
"non_streaming_without_references": {
|
"non_streaming_without_references": {
|
||||||
"summary": "Non-streaming mode without references (stream=false)",
|
"summary": "Non-streaming mode without references (stream=false)",
|
||||||
"description": "Single NDJSON line when stream=False and include_references=False. Complete response only.",
|
"description": "Single NDJSON line when stream=False and include_references=False. Complete response only.",
|
||||||
"value": '{"response": "Deep learning is a subset of machine learning that uses neural networks with multiple layers (hence deep) to model and understand complex patterns in data. It has revolutionized fields like computer vision, natural language processing, and speech recognition."}'
|
"value": '{"response": "Deep learning is a subset of machine learning that uses neural networks with multiple layers (hence deep) to model and understand complex patterns in data. It has revolutionized fields like computer vision, natural language processing, and speech recognition."}',
|
||||||
},
|
},
|
||||||
"error_response": {
|
"error_response": {
|
||||||
"summary": "Error during streaming",
|
"summary": "Error during streaming",
|
||||||
"description": "Error handling in NDJSON format when an error occurs during processing.",
|
"description": "Error handling in NDJSON format when an error occurs during processing.",
|
||||||
"value": '{"references": [{"reference_id": "1", "file_path": "/documents/ai.pdf"}]}\n{"response": "Artificial Intelligence is"}\n{"error": "LLM service temporarily unavailable"}'
|
"value": '{"references": [{"reference_id": "1", "file_path": "/documents/ai.pdf"}]}\n{"response": "Artificial Intelligence is"}\n{"error": "LLM service temporarily unavailable"}',
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
400: {
|
400: {
|
||||||
"description": "Bad Request - Invalid input parameters",
|
"description": "Bad Request - Invalid input parameters",
|
||||||
|
|
@ -418,15 +419,13 @@ def create_query_routes(rag, api_key: Optional[str] = None, top_k: int = 60):
|
||||||
"application/json": {
|
"application/json": {
|
||||||
"schema": {
|
"schema": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {"detail": {"type": "string"}},
|
||||||
"detail": {"type": "string"}
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
"example": {
|
"example": {
|
||||||
"detail": "Query text must be at least 3 characters long"
|
"detail": "Query text must be at least 3 characters long"
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
500: {
|
500: {
|
||||||
"description": "Internal Server Error - Query processing failed",
|
"description": "Internal Server Error - Query processing failed",
|
||||||
|
|
@ -434,27 +433,25 @@ def create_query_routes(rag, api_key: Optional[str] = None, top_k: int = 60):
|
||||||
"application/json": {
|
"application/json": {
|
||||||
"schema": {
|
"schema": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {"detail": {"type": "string"}},
|
||||||
"detail": {"type": "string"}
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
"example": {
|
"example": {
|
||||||
"detail": "Failed to process streaming query: Knowledge graph unavailable"
|
"detail": "Failed to process streaming query: Knowledge graph unavailable"
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
)
|
)
|
||||||
async def query_text_stream(request: QueryRequest):
|
async def query_text_stream(request: QueryRequest):
|
||||||
"""
|
"""
|
||||||
Advanced RAG query endpoint with flexible streaming and non-streaming response modes.
|
Advanced RAG query endpoint with flexible streaming and non-streaming response modes.
|
||||||
|
|
||||||
This endpoint provides the most flexible querying experience, supporting both real-time streaming
|
This endpoint provides the most flexible querying experience, supporting both real-time streaming
|
||||||
and complete response delivery based on your integration needs.
|
and complete response delivery based on your integration needs.
|
||||||
|
|
||||||
**Response Modes:**
|
**Response Modes:**
|
||||||
|
|
||||||
**Streaming Mode (stream=True, default):**
|
**Streaming Mode (stream=True, default):**
|
||||||
- Real-time response delivery as content is generated
|
- Real-time response delivery as content is generated
|
||||||
- NDJSON format: each line is a separate JSON object
|
- NDJSON format: each line is a separate JSON object
|
||||||
|
|
@ -462,19 +459,19 @@ def create_query_routes(rag, api_key: Optional[str] = None, top_k: int = 60):
|
||||||
- Subsequent lines: `{"response": "content chunk"}`
|
- Subsequent lines: `{"response": "content chunk"}`
|
||||||
- Error handling: `{"error": "error message"}`
|
- Error handling: `{"error": "error message"}`
|
||||||
- Perfect for chat interfaces and real-time applications
|
- Perfect for chat interfaces and real-time applications
|
||||||
|
|
||||||
**Non-Streaming Mode (stream=False):**
|
**Non-Streaming Mode (stream=False):**
|
||||||
- Complete response delivered in a single message
|
- Complete response delivered in a single message
|
||||||
- NDJSON format: single line with complete content
|
- NDJSON format: single line with complete content
|
||||||
- Format: `{"references": [...], "response": "complete content"}`
|
- Format: `{"references": [...], "response": "complete content"}`
|
||||||
- Ideal for batch processing and simple integrations
|
- Ideal for batch processing and simple integrations
|
||||||
|
|
||||||
**Response Format Details:**
|
**Response Format Details:**
|
||||||
- **Content-Type**: `application/x-ndjson` (Newline-Delimited JSON)
|
- **Content-Type**: `application/x-ndjson` (Newline-Delimited JSON)
|
||||||
- **Structure**: Each line is an independent, valid JSON object
|
- **Structure**: Each line is an independent, valid JSON object
|
||||||
- **Parsing**: Process line-by-line, each line is self-contained
|
- **Parsing**: Process line-by-line, each line is self-contained
|
||||||
- **Headers**: Includes cache control and connection management
|
- **Headers**: Includes cache control and connection management
|
||||||
|
|
||||||
**Query Modes (same as /query endpoint):**
|
**Query Modes (same as /query endpoint):**
|
||||||
- **local**: Entity-focused retrieval with direct relationships
|
- **local**: Entity-focused retrieval with direct relationships
|
||||||
- **global**: Pattern analysis across the knowledge graph
|
- **global**: Pattern analysis across the knowledge graph
|
||||||
|
|
@ -482,7 +479,7 @@ def create_query_routes(rag, api_key: Optional[str] = None, top_k: int = 60):
|
||||||
- **naive**: Vector similarity search only
|
- **naive**: Vector similarity search only
|
||||||
- **mix**: Integrated knowledge graph + vector retrieval (recommended)
|
- **mix**: Integrated knowledge graph + vector retrieval (recommended)
|
||||||
- **bypass**: Direct LLM query without knowledge retrieval
|
- **bypass**: Direct LLM query without knowledge retrieval
|
||||||
|
|
||||||
**Key Features:**
|
**Key Features:**
|
||||||
- Dual-mode operation (streaming/non-streaming) in single endpoint
|
- Dual-mode operation (streaming/non-streaming) in single endpoint
|
||||||
- Real-time response delivery for interactive applications
|
- Real-time response delivery for interactive applications
|
||||||
|
|
@ -491,9 +488,9 @@ def create_query_routes(rag, api_key: Optional[str] = None, top_k: int = 60):
|
||||||
- Conversation history support for multi-turn dialogues
|
- Conversation history support for multi-turn dialogues
|
||||||
- Comprehensive error handling with graceful degradation
|
- Comprehensive error handling with graceful degradation
|
||||||
- Token control for response length management
|
- Token control for response length management
|
||||||
|
|
||||||
**Usage Examples:**
|
**Usage Examples:**
|
||||||
|
|
||||||
Real-time streaming query:
|
Real-time streaming query:
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
|
|
@ -503,7 +500,7 @@ def create_query_routes(rag, api_key: Optional[str] = None, top_k: int = 60):
|
||||||
"include_references": true
|
"include_references": true
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Complete response query:
|
Complete response query:
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
|
|
@ -513,7 +510,7 @@ def create_query_routes(rag, api_key: Optional[str] = None, top_k: int = 60):
|
||||||
"response_type": "Multiple Paragraphs"
|
"response_type": "Multiple Paragraphs"
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Conversation with context:
|
Conversation with context:
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
|
|
@ -525,9 +522,9 @@ def create_query_routes(rag, api_key: Optional[str] = None, top_k: int = 60):
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
**Response Processing:**
|
**Response Processing:**
|
||||||
|
|
||||||
For streaming responses, process each line:
|
For streaming responses, process each line:
|
||||||
```python
|
```python
|
||||||
async for line in response.iter_lines():
|
async for line in response.iter_lines():
|
||||||
|
|
@ -542,7 +539,7 @@ def create_query_routes(rag, api_key: Optional[str] = None, top_k: int = 60):
|
||||||
# Handle error
|
# Handle error
|
||||||
error_message = data["error"]
|
error_message = data["error"]
|
||||||
```
|
```
|
||||||
|
|
||||||
For non-streaming responses:
|
For non-streaming responses:
|
||||||
```python
|
```python
|
||||||
line = await response.text()
|
line = await response.text()
|
||||||
|
|
@ -550,7 +547,7 @@ def create_query_routes(rag, api_key: Optional[str] = None, top_k: int = 60):
|
||||||
complete_response = data["response"]
|
complete_response = data["response"]
|
||||||
references = data.get("references", [])
|
references = data.get("references", [])
|
||||||
```
|
```
|
||||||
|
|
||||||
**Error Handling:**
|
**Error Handling:**
|
||||||
- Streaming errors are delivered as `{"error": "message"}` lines
|
- Streaming errors are delivered as `{"error": "message"}` lines
|
||||||
- Non-streaming errors raise HTTP exceptions
|
- Non-streaming errors raise HTTP exceptions
|
||||||
|
|
@ -578,10 +575,10 @@ def create_query_routes(rag, api_key: Optional[str] = None, top_k: int = 60):
|
||||||
- Complete response: `{"references": [...], "response": "complete content"}`
|
- Complete response: `{"references": [...], "response": "complete content"}`
|
||||||
|
|
||||||
Raises:
|
Raises:
|
||||||
HTTPException:
|
HTTPException:
|
||||||
- 400: Invalid input parameters (e.g., query too short, invalid mode)
|
- 400: Invalid input parameters (e.g., query too short, invalid mode)
|
||||||
- 500: Internal processing error (e.g., LLM service unavailable)
|
- 500: Internal processing error (e.g., LLM service unavailable)
|
||||||
|
|
||||||
Note:
|
Note:
|
||||||
This endpoint is ideal for applications requiring flexible response delivery.
|
This endpoint is ideal for applications requiring flexible response delivery.
|
||||||
Use streaming mode for real-time interfaces and non-streaming for batch processing.
|
Use streaming mode for real-time interfaces and non-streaming for batch processing.
|
||||||
|
|
@ -657,11 +654,11 @@ def create_query_routes(rag, api_key: Optional[str] = None, top_k: int = 60):
|
||||||
"status": {
|
"status": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"enum": ["success", "failure"],
|
"enum": ["success", "failure"],
|
||||||
"description": "Query execution status"
|
"description": "Query execution status",
|
||||||
},
|
},
|
||||||
"message": {
|
"message": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"description": "Status message describing the result"
|
"description": "Status message describing the result",
|
||||||
},
|
},
|
||||||
"data": {
|
"data": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
|
|
@ -676,10 +673,10 @@ def create_query_routes(rag, api_key: Optional[str] = None, top_k: int = 60):
|
||||||
"description": {"type": "string"},
|
"description": {"type": "string"},
|
||||||
"source_id": {"type": "string"},
|
"source_id": {"type": "string"},
|
||||||
"file_path": {"type": "string"},
|
"file_path": {"type": "string"},
|
||||||
"reference_id": {"type": "string"}
|
"reference_id": {"type": "string"},
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
"description": "Retrieved entities from knowledge graph"
|
"description": "Retrieved entities from knowledge graph",
|
||||||
},
|
},
|
||||||
"relationships": {
|
"relationships": {
|
||||||
"type": "array",
|
"type": "array",
|
||||||
|
|
@ -693,10 +690,10 @@ def create_query_routes(rag, api_key: Optional[str] = None, top_k: int = 60):
|
||||||
"weight": {"type": "number"},
|
"weight": {"type": "number"},
|
||||||
"source_id": {"type": "string"},
|
"source_id": {"type": "string"},
|
||||||
"file_path": {"type": "string"},
|
"file_path": {"type": "string"},
|
||||||
"reference_id": {"type": "string"}
|
"reference_id": {"type": "string"},
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
"description": "Retrieved relationships from knowledge graph"
|
"description": "Retrieved relationships from knowledge graph",
|
||||||
},
|
},
|
||||||
"chunks": {
|
"chunks": {
|
||||||
"type": "array",
|
"type": "array",
|
||||||
|
|
@ -706,10 +703,10 @@ def create_query_routes(rag, api_key: Optional[str] = None, top_k: int = 60):
|
||||||
"content": {"type": "string"},
|
"content": {"type": "string"},
|
||||||
"file_path": {"type": "string"},
|
"file_path": {"type": "string"},
|
||||||
"chunk_id": {"type": "string"},
|
"chunk_id": {"type": "string"},
|
||||||
"reference_id": {"type": "string"}
|
"reference_id": {"type": "string"},
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
"description": "Retrieved text chunks from vector database"
|
"description": "Retrieved text chunks from vector database",
|
||||||
},
|
},
|
||||||
"references": {
|
"references": {
|
||||||
"type": "array",
|
"type": "array",
|
||||||
|
|
@ -717,13 +714,13 @@ def create_query_routes(rag, api_key: Optional[str] = None, top_k: int = 60):
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
"reference_id": {"type": "string"},
|
"reference_id": {"type": "string"},
|
||||||
"file_path": {"type": "string"}
|
"file_path": {"type": "string"},
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
"description": "Reference list for citation purposes"
|
"description": "Reference list for citation purposes",
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
"description": "Structured retrieval data containing entities, relationships, chunks, and references"
|
"description": "Structured retrieval data containing entities, relationships, chunks, and references",
|
||||||
},
|
},
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
|
|
@ -732,25 +729,41 @@ def create_query_routes(rag, api_key: Optional[str] = None, top_k: int = 60):
|
||||||
"keywords": {
|
"keywords": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
"high_level": {"type": "array", "items": {"type": "string"}},
|
"high_level": {
|
||||||
"low_level": {"type": "array", "items": {"type": "string"}}
|
"type": "array",
|
||||||
}
|
"items": {"type": "string"},
|
||||||
|
},
|
||||||
|
"low_level": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {"type": "string"},
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
"processing_info": {
|
"processing_info": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
"total_entities_found": {"type": "integer"},
|
"total_entities_found": {
|
||||||
"total_relations_found": {"type": "integer"},
|
"type": "integer"
|
||||||
"entities_after_truncation": {"type": "integer"},
|
},
|
||||||
"relations_after_truncation": {"type": "integer"},
|
"total_relations_found": {
|
||||||
"final_chunks_count": {"type": "integer"}
|
"type": "integer"
|
||||||
}
|
},
|
||||||
}
|
"entities_after_truncation": {
|
||||||
|
"type": "integer"
|
||||||
|
},
|
||||||
|
"relations_after_truncation": {
|
||||||
|
"type": "integer"
|
||||||
|
},
|
||||||
|
"final_chunks_count": {
|
||||||
|
"type": "integer"
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
"description": "Query metadata including mode, keywords, and processing information"
|
"description": "Query metadata including mode, keywords, and processing information",
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
"required": ["status", "message", "data", "metadata"]
|
"required": ["status", "message", "data", "metadata"],
|
||||||
},
|
},
|
||||||
"examples": {
|
"examples": {
|
||||||
"successful_local_mode": {
|
"successful_local_mode": {
|
||||||
|
|
@ -767,7 +780,7 @@ def create_query_routes(rag, api_key: Optional[str] = None, top_k: int = 60):
|
||||||
"description": "Computational models inspired by biological neural networks",
|
"description": "Computational models inspired by biological neural networks",
|
||||||
"source_id": "chunk-123",
|
"source_id": "chunk-123",
|
||||||
"file_path": "/documents/ai_basics.pdf",
|
"file_path": "/documents/ai_basics.pdf",
|
||||||
"reference_id": "1"
|
"reference_id": "1",
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"relationships": [
|
"relationships": [
|
||||||
|
|
@ -779,7 +792,7 @@ def create_query_routes(rag, api_key: Optional[str] = None, top_k: int = 60):
|
||||||
"weight": 0.85,
|
"weight": 0.85,
|
||||||
"source_id": "chunk-123",
|
"source_id": "chunk-123",
|
||||||
"file_path": "/documents/ai_basics.pdf",
|
"file_path": "/documents/ai_basics.pdf",
|
||||||
"reference_id": "1"
|
"reference_id": "1",
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"chunks": [
|
"chunks": [
|
||||||
|
|
@ -787,28 +800,35 @@ def create_query_routes(rag, api_key: Optional[str] = None, top_k: int = 60):
|
||||||
"content": "Neural networks are computational models that mimic the way biological neural networks work...",
|
"content": "Neural networks are computational models that mimic the way biological neural networks work...",
|
||||||
"file_path": "/documents/ai_basics.pdf",
|
"file_path": "/documents/ai_basics.pdf",
|
||||||
"chunk_id": "chunk-123",
|
"chunk_id": "chunk-123",
|
||||||
"reference_id": "1"
|
"reference_id": "1",
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"references": [
|
"references": [
|
||||||
{"reference_id": "1", "file_path": "/documents/ai_basics.pdf"}
|
{
|
||||||
]
|
"reference_id": "1",
|
||||||
|
"file_path": "/documents/ai_basics.pdf",
|
||||||
|
}
|
||||||
|
],
|
||||||
},
|
},
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"query_mode": "local",
|
"query_mode": "local",
|
||||||
"keywords": {
|
"keywords": {
|
||||||
"high_level": ["neural", "networks"],
|
"high_level": ["neural", "networks"],
|
||||||
"low_level": ["computation", "model", "algorithm"]
|
"low_level": [
|
||||||
|
"computation",
|
||||||
|
"model",
|
||||||
|
"algorithm",
|
||||||
|
],
|
||||||
},
|
},
|
||||||
"processing_info": {
|
"processing_info": {
|
||||||
"total_entities_found": 5,
|
"total_entities_found": 5,
|
||||||
"total_relations_found": 3,
|
"total_relations_found": 3,
|
||||||
"entities_after_truncation": 1,
|
"entities_after_truncation": 1,
|
||||||
"relations_after_truncation": 1,
|
"relations_after_truncation": 1,
|
||||||
"final_chunks_count": 1
|
"final_chunks_count": 1,
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
"global_mode": {
|
"global_mode": {
|
||||||
"summary": "Global mode data retrieval",
|
"summary": "Global mode data retrieval",
|
||||||
|
|
@ -827,22 +847,29 @@ def create_query_routes(rag, api_key: Optional[str] = None, top_k: int = 60):
|
||||||
"weight": 0.92,
|
"weight": 0.92,
|
||||||
"source_id": "chunk-456",
|
"source_id": "chunk-456",
|
||||||
"file_path": "/documents/ai_overview.pdf",
|
"file_path": "/documents/ai_overview.pdf",
|
||||||
"reference_id": "2"
|
"reference_id": "2",
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"chunks": [],
|
"chunks": [],
|
||||||
"references": [
|
"references": [
|
||||||
{"reference_id": "2", "file_path": "/documents/ai_overview.pdf"}
|
{
|
||||||
]
|
"reference_id": "2",
|
||||||
|
"file_path": "/documents/ai_overview.pdf",
|
||||||
|
}
|
||||||
|
],
|
||||||
},
|
},
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"query_mode": "global",
|
"query_mode": "global",
|
||||||
"keywords": {
|
"keywords": {
|
||||||
"high_level": ["artificial", "intelligence", "overview"],
|
"high_level": [
|
||||||
"low_level": []
|
"artificial",
|
||||||
}
|
"intelligence",
|
||||||
}
|
"overview",
|
||||||
}
|
],
|
||||||
|
"low_level": [],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
"naive_mode": {
|
"naive_mode": {
|
||||||
"summary": "Naive mode data retrieval",
|
"summary": "Naive mode data retrieval",
|
||||||
|
|
@ -858,25 +885,25 @@ def create_query_routes(rag, api_key: Optional[str] = None, top_k: int = 60):
|
||||||
"content": "Deep learning is a subset of machine learning that uses neural networks with multiple layers...",
|
"content": "Deep learning is a subset of machine learning that uses neural networks with multiple layers...",
|
||||||
"file_path": "/documents/deep_learning.pdf",
|
"file_path": "/documents/deep_learning.pdf",
|
||||||
"chunk_id": "chunk-789",
|
"chunk_id": "chunk-789",
|
||||||
"reference_id": "3"
|
"reference_id": "3",
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"references": [
|
"references": [
|
||||||
{"reference_id": "3", "file_path": "/documents/deep_learning.pdf"}
|
{
|
||||||
]
|
"reference_id": "3",
|
||||||
|
"file_path": "/documents/deep_learning.pdf",
|
||||||
|
}
|
||||||
|
],
|
||||||
},
|
},
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"query_mode": "naive",
|
"query_mode": "naive",
|
||||||
"keywords": {
|
"keywords": {"high_level": [], "low_level": []},
|
||||||
"high_level": [],
|
},
|
||||||
"low_level": []
|
},
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
400: {
|
400: {
|
||||||
"description": "Bad Request - Invalid input parameters",
|
"description": "Bad Request - Invalid input parameters",
|
||||||
|
|
@ -884,15 +911,13 @@ def create_query_routes(rag, api_key: Optional[str] = None, top_k: int = 60):
|
||||||
"application/json": {
|
"application/json": {
|
||||||
"schema": {
|
"schema": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {"detail": {"type": "string"}},
|
||||||
"detail": {"type": "string"}
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
"example": {
|
"example": {
|
||||||
"detail": "Query text must be at least 3 characters long"
|
"detail": "Query text must be at least 3 characters long"
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
500: {
|
500: {
|
||||||
"description": "Internal Server Error - Data retrieval failed",
|
"description": "Internal Server Error - Data retrieval failed",
|
||||||
|
|
@ -900,35 +925,33 @@ def create_query_routes(rag, api_key: Optional[str] = None, top_k: int = 60):
|
||||||
"application/json": {
|
"application/json": {
|
||||||
"schema": {
|
"schema": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {"detail": {"type": "string"}},
|
||||||
"detail": {"type": "string"}
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
"example": {
|
"example": {
|
||||||
"detail": "Failed to retrieve data: Knowledge graph unavailable"
|
"detail": "Failed to retrieve data: Knowledge graph unavailable"
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
)
|
)
|
||||||
async def query_data(request: QueryRequest):
|
async def query_data(request: QueryRequest):
|
||||||
"""
|
"""
|
||||||
Advanced data retrieval endpoint for structured RAG analysis.
|
Advanced data retrieval endpoint for structured RAG analysis.
|
||||||
|
|
||||||
This endpoint provides raw retrieval results without LLM generation, perfect for:
|
This endpoint provides raw retrieval results without LLM generation, perfect for:
|
||||||
- **Data Analysis**: Examine what information would be used for RAG
|
- **Data Analysis**: Examine what information would be used for RAG
|
||||||
- **System Integration**: Get structured data for custom processing
|
- **System Integration**: Get structured data for custom processing
|
||||||
- **Debugging**: Understand retrieval behavior and quality
|
- **Debugging**: Understand retrieval behavior and quality
|
||||||
- **Research**: Analyze knowledge graph structure and relationships
|
- **Research**: Analyze knowledge graph structure and relationships
|
||||||
|
|
||||||
**Key Features:**
|
**Key Features:**
|
||||||
- No LLM generation - pure data retrieval
|
- No LLM generation - pure data retrieval
|
||||||
- Complete structured output with entities, relationships, and chunks
|
- Complete structured output with entities, relationships, and chunks
|
||||||
- Always includes references for citation
|
- Always includes references for citation
|
||||||
- Detailed metadata about processing and keywords
|
- Detailed metadata about processing and keywords
|
||||||
- Compatible with all query modes and parameters
|
- Compatible with all query modes and parameters
|
||||||
|
|
||||||
**Query Mode Behaviors:**
|
**Query Mode Behaviors:**
|
||||||
- **local**: Returns entities and their direct relationships + related chunks
|
- **local**: Returns entities and their direct relationships + related chunks
|
||||||
- **global**: Returns relationship patterns across the knowledge graph
|
- **global**: Returns relationship patterns across the knowledge graph
|
||||||
|
|
@ -936,16 +959,16 @@ def create_query_routes(rag, api_key: Optional[str] = None, top_k: int = 60):
|
||||||
- **naive**: Returns only vector-retrieved text chunks (no knowledge graph)
|
- **naive**: Returns only vector-retrieved text chunks (no knowledge graph)
|
||||||
- **mix**: Integrates knowledge graph data with vector-retrieved chunks
|
- **mix**: Integrates knowledge graph data with vector-retrieved chunks
|
||||||
- **bypass**: Returns empty data arrays (used for direct LLM queries)
|
- **bypass**: Returns empty data arrays (used for direct LLM queries)
|
||||||
|
|
||||||
**Data Structure:**
|
**Data Structure:**
|
||||||
- **entities**: Knowledge graph entities with descriptions and metadata
|
- **entities**: Knowledge graph entities with descriptions and metadata
|
||||||
- **relationships**: Connections between entities with weights and descriptions
|
- **relationships**: Connections between entities with weights and descriptions
|
||||||
- **chunks**: Text segments from documents with source information
|
- **chunks**: Text segments from documents with source information
|
||||||
- **references**: Citation information mapping reference IDs to file paths
|
- **references**: Citation information mapping reference IDs to file paths
|
||||||
- **metadata**: Processing information, keywords, and query statistics
|
- **metadata**: Processing information, keywords, and query statistics
|
||||||
|
|
||||||
**Usage Examples:**
|
**Usage Examples:**
|
||||||
|
|
||||||
Analyze entity relationships:
|
Analyze entity relationships:
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
|
|
@ -954,7 +977,7 @@ def create_query_routes(rag, api_key: Optional[str] = None, top_k: int = 60):
|
||||||
"top_k": 10
|
"top_k": 10
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Explore global patterns:
|
Explore global patterns:
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
|
|
@ -963,7 +986,7 @@ def create_query_routes(rag, api_key: Optional[str] = None, top_k: int = 60):
|
||||||
"max_relation_tokens": 2000
|
"max_relation_tokens": 2000
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Vector similarity search:
|
Vector similarity search:
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
|
|
@ -972,13 +995,13 @@ def create_query_routes(rag, api_key: Optional[str] = None, top_k: int = 60):
|
||||||
"chunk_top_k": 5
|
"chunk_top_k": 5
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
**Response Analysis:**
|
**Response Analysis:**
|
||||||
- **Empty arrays**: Normal for certain modes (e.g., naive mode has no entities/relationships)
|
- **Empty arrays**: Normal for certain modes (e.g., naive mode has no entities/relationships)
|
||||||
- **Processing info**: Shows retrieval statistics and token usage
|
- **Processing info**: Shows retrieval statistics and token usage
|
||||||
- **Keywords**: High-level and low-level keywords extracted from query
|
- **Keywords**: High-level and low-level keywords extracted from query
|
||||||
- **Reference mapping**: Links all data back to source documents
|
- **Reference mapping**: Links all data back to source documents
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
request (QueryRequest): The request object containing query parameters:
|
request (QueryRequest): The request object containing query parameters:
|
||||||
- **query**: The search query to analyze (min 3 characters)
|
- **query**: The search query to analyze (min 3 characters)
|
||||||
|
|
@ -997,10 +1020,10 @@ def create_query_routes(rag, api_key: Optional[str] = None, top_k: int = 60):
|
||||||
- **metadata**: Query processing information and statistics
|
- **metadata**: Query processing information and statistics
|
||||||
|
|
||||||
Raises:
|
Raises:
|
||||||
HTTPException:
|
HTTPException:
|
||||||
- 400: Invalid input parameters (e.g., query too short, invalid mode)
|
- 400: Invalid input parameters (e.g., query too short, invalid mode)
|
||||||
- 500: Internal processing error (e.g., knowledge graph unavailable)
|
- 500: Internal processing error (e.g., knowledge graph unavailable)
|
||||||
|
|
||||||
Note:
|
Note:
|
||||||
This endpoint always includes references regardless of the include_references parameter,
|
This endpoint always includes references regardless of the include_references parameter,
|
||||||
as structured data analysis typically requires source attribution.
|
as structured data analysis typically requires source attribution.
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue