Fix Gradio UI for report generation with detail levels and custom models
This commit is contained in:
parent
ae130ac49b
commit
0d547d016b
|
@ -576,17 +576,19 @@ reranker = get_jina_reranker()
|
|||
```python
|
||||
from ranking.jina_reranker import JinaReranker
|
||||
|
||||
# Initialize with specific model
|
||||
reranker = JinaReranker()
|
||||
query = "What is quantum computing?"
|
||||
documents = [
|
||||
"Quantum computing is a computation system that uses quantum mechanics.",
|
||||
"Classical computers use bits while quantum computers use qubits.",
|
||||
"Artificial intelligence is transforming various industries."
|
||||
]
|
||||
|
||||
reranked = reranker.rerank(query, documents)
|
||||
for doc in reranked:
|
||||
print(f"Score: {doc['score']}, Document: {doc['document']}")
|
||||
# Rerank documents
|
||||
results = reranker.rerank(
|
||||
query="What is quantum computing?",
|
||||
documents=["Document about quantum physics", "Document about quantum computing", "Document about classical computing"],
|
||||
top_n=2
|
||||
)
|
||||
|
||||
# Process results
|
||||
for result in results:
|
||||
print(f"Score: {result['score']}, Document: {result['document']}")
|
||||
```
|
||||
|
||||
#### Integration with ResultCollector
|
||||
|
@ -785,115 +787,141 @@ results = reranker.rerank(
|
|||
# Process results
|
||||
for result in results:
|
||||
print(f"Score: {result['score']}, Document: {result['document']}")
|
||||
|
||||
## Query Processor Testing
|
||||
|
||||
The query processor module has been tested with the Groq LLM provider to ensure it functions correctly with the newly integrated models.
|
||||
|
||||
### Test Scripts
|
||||
|
||||
Two test scripts have been created to validate the query processor functionality:
|
||||
|
||||
#### Basic Test Script (test_query_processor.py)
|
||||
|
||||
```python
|
||||
# Get the query processor
|
||||
processor = get_query_processor()
|
||||
|
||||
# Process a query
|
||||
result = processor.process_query("What are the latest advancements in quantum computing?")
|
||||
|
||||
# Generate search queries
|
||||
search_result = processor.generate_search_queries(result, ["google", "bing", "scholar"])
|
||||
```
|
||||
|
||||
- **Purpose**: Tests the core functionality of the query processor
|
||||
- **Features**:
|
||||
- Uses monkey patching to ensure the Groq model is used
|
||||
- Provides detailed output of processing results
|
||||
## Report Generation Module
|
||||
|
||||
#### Comprehensive Test Script (test_query_processor_comprehensive.py)
|
||||
### ReportDetailLevelManager Class
|
||||
|
||||
```python
|
||||
# Test query enhancement
|
||||
enhanced_query = test_enhance_query("What is quantum computing?")
|
||||
|
||||
# Test query classification
|
||||
classification = test_classify_query("What is quantum computing?")
|
||||
|
||||
# Test the full processing pipeline
|
||||
structured_query = test_process_query("What is quantum computing?")
|
||||
|
||||
# Test search query generation
|
||||
search_result = test_generate_search_queries(structured_query, ["google", "bing", "scholar"])
|
||||
```
|
||||
|
||||
- **Purpose**: Tests all aspects of the query processor in detail
|
||||
- **Features**:
|
||||
- Tests individual components in isolation
|
||||
- Tests a variety of query types
|
||||
- Saves detailed test results to a JSON file
|
||||
|
||||
## LLM Interface
|
||||
|
||||
### LLMInterface Class
|
||||
|
||||
The `LLMInterface` class provides a unified interface for interacting with various LLM providers through LiteLLM.
|
||||
The `ReportDetailLevelManager` class manages configurations for different report detail levels.
|
||||
|
||||
#### Initialization
|
||||
```python
|
||||
llm = LLMInterface(model_name="gpt-4")
|
||||
detail_level_manager = get_report_detail_level_manager()
|
||||
```
|
||||
- **Description**: Initializes the LLM interface with the specified model
|
||||
- **Parameters**:
|
||||
- `model_name` (Optional[str]): The name of the model to use (defaults to config value)
|
||||
- **Requirements**: Appropriate API key must be set in environment or config
|
||||
- **Description**: Gets a singleton instance of the ReportDetailLevelManager
|
||||
|
||||
#### complete
|
||||
#### get_detail_level_config
|
||||
```python
|
||||
response = llm.complete(prompt, system_prompt=None, temperature=None, max_tokens=None)
|
||||
config = detail_level_manager.get_detail_level_config(detail_level)
|
||||
```
|
||||
- **Description**: Generates a completion for the given prompt
|
||||
- **Description**: Gets configuration parameters for a specific detail level
|
||||
- **Parameters**:
|
||||
- `prompt` (str): The prompt to complete
|
||||
- `system_prompt` (Optional[str]): System prompt for context
|
||||
- `temperature` (Optional[float]): Temperature for generation
|
||||
- `max_tokens` (Optional[int]): Maximum tokens to generate
|
||||
- **Returns**: str - The generated completion
|
||||
- **Raises**: LLMError if the completion fails
|
||||
- `detail_level` (str): Detail level as a string (brief, standard, detailed, comprehensive)
|
||||
- **Returns**: Dict[str, Any] - Configuration parameters for the specified detail level
|
||||
- **Raises**: ValueError if the detail level is not valid
|
||||
|
||||
#### complete_json
|
||||
#### get_template_modifier
|
||||
```python
|
||||
json_response = llm.complete_json(prompt, system_prompt=None, json_schema=None)
|
||||
template = detail_level_manager.get_template_modifier(detail_level, query_type)
|
||||
```
|
||||
- **Description**: Generates a JSON response for the given prompt
|
||||
- **Description**: Gets template modifier for a specific detail level and query type
|
||||
- **Parameters**:
|
||||
- `prompt` (str): The prompt to complete
|
||||
- `system_prompt` (Optional[str]): System prompt for context
|
||||
- `json_schema` (Optional[Dict]): JSON schema for validation
|
||||
- **Returns**: Dict - The generated JSON response
|
||||
- **Raises**: LLMError if the completion fails or JSON is invalid
|
||||
- `detail_level` (str): Detail level as a string (brief, standard, detailed, comprehensive)
|
||||
- `query_type` (str): Query type as a string (factual, exploratory, comparative)
|
||||
- **Returns**: str - Template modifier as a string
|
||||
- **Raises**: ValueError if the detail level or query type is not valid
|
||||
|
||||
#### Supported Providers
|
||||
- OpenAI
|
||||
- Azure OpenAI
|
||||
- Anthropic
|
||||
- Ollama
|
||||
- Groq
|
||||
- OpenRouter
|
||||
|
||||
#### Example Usage
|
||||
#### get_available_detail_levels
|
||||
```python
|
||||
from query.llm_interface import LLMInterface
|
||||
levels = detail_level_manager.get_available_detail_levels()
|
||||
```
|
||||
- **Description**: Gets a list of available detail levels with descriptions
|
||||
- **Returns**: List[Tuple[str, str]] - List of tuples containing detail level and description
|
||||
|
||||
# Initialize with specific model
|
||||
llm = LLMInterface(model_name="llama-3.1-8b-instant")
|
||||
### ReportGenerator Class
|
||||
|
||||
# Generate a completion
|
||||
response = llm.complete(
|
||||
prompt="Explain quantum computing",
|
||||
system_prompt="You are a helpful assistant that explains complex topics simply.",
|
||||
temperature=0.7
|
||||
The `ReportGenerator` class generates reports from search results.
|
||||
|
||||
#### Initialization
|
||||
```python
|
||||
report_generator = get_report_generator()
|
||||
```
|
||||
- **Description**: Gets a singleton instance of the ReportGenerator
|
||||
|
||||
#### initialize
|
||||
```python
|
||||
await report_generator.initialize()
|
||||
```
|
||||
- **Description**: Initializes the report generator by setting up the database
|
||||
- **Returns**: None
|
||||
|
||||
#### set_detail_level
|
||||
```python
|
||||
report_generator.set_detail_level(detail_level)
|
||||
```
|
||||
- **Description**: Sets the detail level for report generation
|
||||
- **Parameters**:
|
||||
- `detail_level` (str): Detail level (brief, standard, detailed, comprehensive)
|
||||
- **Returns**: None
|
||||
- **Raises**: ValueError if the detail level is not valid
|
||||
|
||||
#### get_detail_level_config
|
||||
```python
|
||||
config = report_generator.get_detail_level_config()
|
||||
```
|
||||
- **Description**: Gets the current detail level configuration
|
||||
- **Returns**: Dict[str, Any] - Configuration parameters for the current detail level
|
||||
|
||||
#### get_available_detail_levels
|
||||
```python
|
||||
levels = report_generator.get_available_detail_levels()
|
||||
```
|
||||
- **Description**: Gets a list of available detail levels with descriptions
|
||||
- **Returns**: List[Tuple[str, str]] - List of tuples containing detail level and description
|
||||
|
||||
#### process_search_results
|
||||
```python
|
||||
documents = await report_generator.process_search_results(search_results)
|
||||
```
|
||||
- **Description**: Processes search results by scraping the URLs and storing them in the database
|
||||
- **Parameters**:
|
||||
- `search_results` (List[Dict[str, Any]]): List of search results, each containing at least a 'url' field
|
||||
- **Returns**: List[Dict[str, Any]] - List of processed documents
|
||||
|
||||
#### prepare_documents_for_report
|
||||
```python
|
||||
chunks = await report_generator.prepare_documents_for_report(search_results, token_budget, chunk_size, overlap_size)
|
||||
```
|
||||
- **Description**: Prepares documents for report generation by chunking and selecting relevant content
|
||||
- **Parameters**:
|
||||
- `search_results` (List[Dict[str, Any]]): List of search results
|
||||
- `token_budget` (Optional[int]): Maximum number of tokens to use
|
||||
- `chunk_size` (Optional[int]): Maximum number of tokens per chunk
|
||||
- `overlap_size` (Optional[int]): Number of tokens to overlap between chunks
|
||||
- **Returns**: List[Dict[str, Any]] - List of selected document chunks
|
||||
|
||||
#### generate_report
|
||||
```python
|
||||
report = await report_generator.generate_report(
|
||||
search_results=search_results,
|
||||
query=query,
|
||||
token_budget=token_budget,
|
||||
chunk_size=chunk_size,
|
||||
overlap_size=overlap_size,
|
||||
detail_level=detail_level
|
||||
)
|
||||
```
|
||||
- **Description**: Generates a report from search results
|
||||
- **Parameters**:
|
||||
- `search_results` (List[Dict[str, Any]]): List of search results
|
||||
- `query` (str): Original search query
|
||||
- `token_budget` (Optional[int]): Maximum number of tokens to use
|
||||
- `chunk_size` (Optional[int]): Maximum number of tokens per chunk
|
||||
- `overlap_size` (Optional[int]): Number of tokens to overlap between chunks
|
||||
- `detail_level` (Optional[str]): Level of detail for the report (brief, standard, detailed, comprehensive)
|
||||
- **Returns**: str - Generated report as a string
|
||||
|
||||
print(response)
|
||||
#### initialize_report_generator
|
||||
```python
|
||||
await initialize_report_generator()
|
||||
```
|
||||
- **Description**: Initializes the global report generator instance
|
||||
- **Returns**: None
|
||||
|
||||
#### get_report_generator
|
||||
```python
|
||||
report_generator = get_report_generator()
|
||||
```
|
||||
- **Description**: Gets the global report generator instance
|
||||
- **Returns**: ReportGenerator - Initialized report generator instance
|
||||
|
|
|
@ -8,7 +8,9 @@ import json
|
|||
import gradio as gr
|
||||
import sys
|
||||
import time
|
||||
import asyncio
|
||||
from pathlib import Path
|
||||
from datetime import datetime
|
||||
|
||||
# Add the parent directory to the path to allow importing from other modules
|
||||
sys.path.append(str(Path(__file__).parent.parent))
|
||||
|
@ -16,6 +18,9 @@ sys.path.append(str(Path(__file__).parent.parent))
|
|||
from query.query_processor import QueryProcessor
|
||||
from execution.search_executor import SearchExecutor
|
||||
from execution.result_collector import ResultCollector
|
||||
from report.report_generator import get_report_generator, initialize_report_generator
|
||||
from report.report_detail_levels import get_report_detail_level_manager, DetailLevel
|
||||
from config.config import Config
|
||||
|
||||
|
||||
class GradioInterface:
|
||||
|
@ -28,6 +33,20 @@ class GradioInterface:
|
|||
self.result_collector = ResultCollector()
|
||||
self.results_dir = Path(__file__).parent.parent / "results"
|
||||
self.results_dir.mkdir(exist_ok=True)
|
||||
self.reports_dir = Path(__file__).parent.parent
|
||||
self.reports_dir.mkdir(exist_ok=True)
|
||||
self.detail_level_manager = get_report_detail_level_manager()
|
||||
self.config = Config()
|
||||
|
||||
# The report generator will be initialized in the async init method
|
||||
self.report_generator = None
|
||||
|
||||
async def async_init(self):
|
||||
"""Asynchronously initialize components that require async initialization."""
|
||||
# Initialize the report generator
|
||||
await initialize_report_generator()
|
||||
self.report_generator = get_report_generator()
|
||||
return self
|
||||
|
||||
def process_query(self, query, num_results=10, use_reranker=True):
|
||||
"""
|
||||
|
@ -165,6 +184,146 @@ class GradioInterface:
|
|||
|
||||
return markdown
|
||||
|
||||
async def generate_report(self, query, detail_level, custom_model=None, process_thinking_tags=False, results_file=None):
|
||||
"""
|
||||
Generate a report from a query.
|
||||
|
||||
Args:
|
||||
query (str): The query to process
|
||||
detail_level (str): Detail level for the report
|
||||
custom_model (str): Custom model to use for report generation
|
||||
process_thinking_tags (bool): Whether to process thinking tags in the output
|
||||
results_file (str): Path to results file (optional)
|
||||
|
||||
Returns:
|
||||
tuple: (report_markdown, report_file_path)
|
||||
"""
|
||||
try:
|
||||
# Create a timestamped output file
|
||||
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
|
||||
model_suffix = ""
|
||||
if custom_model:
|
||||
model_name = custom_model.split('/')[-1]
|
||||
model_suffix = f"_{model_name}"
|
||||
|
||||
output_file = self.reports_dir / f"report_{timestamp}{model_suffix}.md"
|
||||
|
||||
# Get detail level configuration
|
||||
config = self.detail_level_manager.get_detail_level_config(detail_level)
|
||||
|
||||
# If custom model is provided, use it
|
||||
if custom_model:
|
||||
config["model"] = custom_model
|
||||
|
||||
print(f"Generating report with detail level: {detail_level}")
|
||||
print(f"Detail level configuration: {config}")
|
||||
print(f"Using model: {config['model']}")
|
||||
print(f"Processing thinking tags: {process_thinking_tags}")
|
||||
|
||||
# If results file is provided, load results from it
|
||||
search_results = []
|
||||
if results_file and os.path.exists(results_file):
|
||||
with open(results_file, 'r') as f:
|
||||
search_results = json.load(f)
|
||||
print(f"Loaded {len(search_results)} results from {results_file}")
|
||||
else:
|
||||
# If no results file is provided, perform a search
|
||||
print(f"No results file provided, performing search for: {query}")
|
||||
|
||||
# Process the query to create a structured query
|
||||
structured_query = self.query_processor.process_query(query)
|
||||
|
||||
# Generate search queries for different engines
|
||||
structured_query = self.query_processor.generate_search_queries(
|
||||
structured_query,
|
||||
self.search_executor.get_available_search_engines()
|
||||
)
|
||||
|
||||
# Execute the search with the structured query
|
||||
search_results_dict = self.search_executor.execute_search(
|
||||
structured_query,
|
||||
num_results=config["num_results"]
|
||||
)
|
||||
|
||||
# Flatten the search results
|
||||
search_results = []
|
||||
for engine_results in search_results_dict.values():
|
||||
search_results.extend(engine_results)
|
||||
|
||||
# Rerank results if we have a reranker
|
||||
if hasattr(self, 'reranker') and self.reranker:
|
||||
search_results = self.reranker.rerank_with_metadata(
|
||||
query,
|
||||
search_results,
|
||||
document_key='snippet',
|
||||
top_n=config["num_results"]
|
||||
)
|
||||
|
||||
# Set the model for report generation if custom model is provided
|
||||
if custom_model:
|
||||
# This will update the report synthesizer to use the custom model
|
||||
self.report_generator.set_detail_level(detail_level)
|
||||
|
||||
# Generate the report
|
||||
report = await self.report_generator.generate_report(
|
||||
search_results=search_results,
|
||||
query=query,
|
||||
token_budget=config["token_budget"],
|
||||
chunk_size=config["chunk_size"],
|
||||
overlap_size=config["overlap_size"],
|
||||
detail_level=detail_level
|
||||
)
|
||||
|
||||
# Process thinking tags if requested
|
||||
if process_thinking_tags:
|
||||
report = self._process_thinking_tags(report)
|
||||
|
||||
# Save report to file
|
||||
with open(output_file, 'w', encoding='utf-8') as f:
|
||||
f.write(report)
|
||||
|
||||
print(f"Report saved to: {output_file}")
|
||||
|
||||
return report, str(output_file)
|
||||
|
||||
except Exception as e:
|
||||
error_message = f"Error generating report: {str(e)}"
|
||||
print(f"ERROR: {error_message}")
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
return f"## Error\n\n{error_message}", None
|
||||
|
||||
def _process_thinking_tags(self, text):
|
||||
"""
|
||||
Process thinking tags in the text.
|
||||
|
||||
Args:
|
||||
text (str): Text to process
|
||||
|
||||
Returns:
|
||||
str: Processed text
|
||||
"""
|
||||
# Remove content between <thinking> and </thinking> tags
|
||||
import re
|
||||
return re.sub(r'<thinking>.*?</thinking>', '', text, flags=re.DOTALL)
|
||||
|
||||
def get_available_models(self):
|
||||
"""
|
||||
Get a list of available models for report generation.
|
||||
|
||||
Returns:
|
||||
list: List of available model names
|
||||
"""
|
||||
# Get models from config
|
||||
models = [
|
||||
"llama-3.1-8b-instant",
|
||||
"llama-3.3-70b-versatile",
|
||||
"groq/deepseek-r1-distill-llama-70b-specdec",
|
||||
"openrouter-mixtral",
|
||||
"openrouter-claude"
|
||||
]
|
||||
return models
|
||||
|
||||
def create_interface(self):
|
||||
"""
|
||||
Create and return the Gradio interface.
|
||||
|
@ -179,62 +338,126 @@ class GradioInterface:
|
|||
This system helps you research topics by searching across multiple sources
|
||||
including Google (via Serper), Google Scholar, and arXiv.
|
||||
|
||||
The system will return ALL results from each search engine, up to the maximum
|
||||
number specified by the "Results Per Engine" slider. Results are ranked by
|
||||
relevance across all sources.
|
||||
You can either search for results or generate a comprehensive report.
|
||||
"""
|
||||
)
|
||||
|
||||
with gr.Row():
|
||||
with gr.Column(scale=4):
|
||||
query_input = gr.Textbox(
|
||||
label="Research Query",
|
||||
placeholder="Enter your research question here...",
|
||||
lines=3
|
||||
with gr.Tabs() as tabs:
|
||||
with gr.TabItem("Search"):
|
||||
with gr.Row():
|
||||
with gr.Column(scale=4):
|
||||
search_query_input = gr.Textbox(
|
||||
label="Research Query",
|
||||
placeholder="Enter your research question here...",
|
||||
lines=3
|
||||
)
|
||||
with gr.Column(scale=1):
|
||||
search_num_results = gr.Slider(
|
||||
minimum=5,
|
||||
maximum=50,
|
||||
value=20,
|
||||
step=5,
|
||||
label="Results Per Engine"
|
||||
)
|
||||
search_use_reranker = gr.Checkbox(
|
||||
label="Use Semantic Reranker",
|
||||
value=True,
|
||||
info="Uses Jina AI's reranker for more relevant results"
|
||||
)
|
||||
search_button = gr.Button("Search", variant="primary")
|
||||
|
||||
gr.Examples(
|
||||
examples=[
|
||||
["What are the latest advancements in quantum computing?"],
|
||||
["Compare transformer and RNN architectures for NLP tasks"],
|
||||
["Explain the environmental impact of electric vehicles"]
|
||||
],
|
||||
inputs=search_query_input
|
||||
)
|
||||
with gr.Column(scale=1):
|
||||
num_results = gr.Slider(
|
||||
minimum=5,
|
||||
maximum=50,
|
||||
value=20,
|
||||
step=5,
|
||||
label="Results Per Engine"
|
||||
)
|
||||
use_reranker = gr.Checkbox(
|
||||
label="Use Semantic Reranker",
|
||||
value=True,
|
||||
info="Uses Jina AI's reranker for more relevant results"
|
||||
)
|
||||
search_button = gr.Button("Search", variant="primary")
|
||||
|
||||
gr.Examples(
|
||||
examples=[
|
||||
["What are the latest advancements in quantum computing?"],
|
||||
["Compare transformer and RNN architectures for NLP tasks"],
|
||||
["Explain the environmental impact of electric vehicles"]
|
||||
],
|
||||
inputs=query_input
|
||||
)
|
||||
|
||||
with gr.Row():
|
||||
with gr.Column():
|
||||
results_output = gr.Markdown(label="Results")
|
||||
|
||||
with gr.Row():
|
||||
with gr.Column():
|
||||
search_results_output = gr.Markdown(label="Results")
|
||||
|
||||
with gr.Row():
|
||||
with gr.Column():
|
||||
search_file_output = gr.Textbox(
|
||||
label="Results saved to file",
|
||||
interactive=False
|
||||
)
|
||||
|
||||
with gr.Row():
|
||||
with gr.Column():
|
||||
file_output = gr.Textbox(
|
||||
label="Results saved to file",
|
||||
interactive=False
|
||||
with gr.TabItem("Generate Report"):
|
||||
with gr.Row():
|
||||
with gr.Column(scale=4):
|
||||
report_query_input = gr.Textbox(
|
||||
label="Research Query",
|
||||
placeholder="Enter your research question here...",
|
||||
lines=3
|
||||
)
|
||||
with gr.Column(scale=1):
|
||||
report_detail_level = gr.Dropdown(
|
||||
choices=["brief", "standard", "detailed", "comprehensive"],
|
||||
value="standard",
|
||||
label="Detail Level",
|
||||
info="Controls the depth and breadth of the report"
|
||||
)
|
||||
report_custom_model = gr.Dropdown(
|
||||
choices=self.get_available_models(),
|
||||
value=None,
|
||||
label="Custom Model (Optional)",
|
||||
info="Select a custom model for report generation"
|
||||
)
|
||||
report_process_thinking = gr.Checkbox(
|
||||
label="Process Thinking Tags",
|
||||
value=False,
|
||||
info="Process <thinking> tags in model output"
|
||||
)
|
||||
report_button = gr.Button("Generate Report", variant="primary")
|
||||
|
||||
gr.Examples(
|
||||
examples=[
|
||||
["What are the latest advancements in quantum computing?"],
|
||||
["Compare transformer and RNN architectures for NLP tasks"],
|
||||
["Explain the environmental impact of electric vehicles"],
|
||||
["Explain the potential relationship between creatine supplementation and muscle loss due to GLP1-ar drugs for weight loss."]
|
||||
],
|
||||
inputs=report_query_input
|
||||
)
|
||||
|
||||
with gr.Row():
|
||||
with gr.Column():
|
||||
report_output = gr.Markdown(label="Generated Report")
|
||||
|
||||
with gr.Row():
|
||||
with gr.Column():
|
||||
report_file_output = gr.Textbox(
|
||||
label="Report saved to file",
|
||||
interactive=False
|
||||
)
|
||||
|
||||
# Add information about detail levels
|
||||
detail_levels_info = ""
|
||||
for level, description in self.detail_level_manager.get_available_detail_levels():
|
||||
detail_levels_info += f"- **{level}**: {description}\n"
|
||||
|
||||
gr.Markdown(f"### Detail Levels\n{detail_levels_info}")
|
||||
|
||||
# Set up event handlers
|
||||
search_button.click(
|
||||
fn=self.process_query,
|
||||
inputs=[query_input, num_results, use_reranker],
|
||||
outputs=[results_output, file_output]
|
||||
inputs=[search_query_input, search_num_results, search_use_reranker],
|
||||
outputs=[search_results_output, search_file_output]
|
||||
)
|
||||
|
||||
report_button.click(
|
||||
fn=lambda q, d, m, p, f: asyncio.run(self.generate_report(q, d, m, p, f)),
|
||||
inputs=[report_query_input, report_detail_level, report_custom_model,
|
||||
report_process_thinking, search_file_output],
|
||||
outputs=[report_output, report_file_output]
|
||||
)
|
||||
|
||||
return interface
|
||||
|
||||
|
||||
def launch(self, **kwargs):
|
||||
"""
|
||||
Launch the Gradio interface.
|
||||
|
@ -248,7 +471,14 @@ class GradioInterface:
|
|||
|
||||
def main():
|
||||
"""Main function to launch the Gradio interface."""
|
||||
# Create interface and initialize async components
|
||||
interface = GradioInterface()
|
||||
|
||||
# Run the async initialization in the event loop
|
||||
loop = asyncio.get_event_loop()
|
||||
loop.run_until_complete(interface.async_init())
|
||||
|
||||
# Launch the interface
|
||||
interface.launch(share=True)
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue