Spaces:
Sleeping
Sleeping
import gradio as gr | |
import os | |
class GradioUI: | |
def __init__(self, agent): | |
self.agent = agent | |
def process_input(self, query: str, pdf_file: gr.File = None): | |
""" | |
Processes user input, which can include a text query and optionally a PDF file. | |
If a PDF is uploaded, it assumes the query is a question about it and calls | |
the Document Q&A tool directly. Otherwise, it sends the query to the agent.run() method. | |
Args: | |
query (str): The text query from the user. | |
pdf_file (gr.File, optional): The uploaded PDF file object provided by Gradio. Defaults to None. | |
Returns: | |
str: The response from the agent or tool. | |
""" | |
# Check if a PDF file is uploaded AND there is a text query (assumed to be the question) | |
if pdf_file is not None and query and query.strip(): | |
print(f"PDF file uploaded: {pdf_file.name}") | |
print(f"Query (assumed question for PDF): {query}") | |
try: | |
# --- Call the Document Q&A tool directly --- | |
# We assume the document_qna_tool is at index 4 as per your app.py initialization | |
# Gradio's gr.File object has a .name attribute which is the file path | |
# The document_qna_tool expects a file path string. | |
print("Detected PDF upload and query. Calling document_qna_tool...") | |
# The tool signature is document_qna_tool(pdf_path: str, question: str) | |
response = self.agent.tools["document_qna_tool"](pdf_file.name, query) | |
print("Document Q&A tool finished.") | |
# Optional: Clean up the uploaded file after processing | |
# import os | |
# try: | |
# if os.path.exists(pdf_file.name): | |
# os.remove(pdf_file.name) | |
# print(f"Cleaned up file: {pdf_file.name}") | |
# except Exception as e: | |
# print(f"Error cleaning up file {pdf_file.name}: {e}") | |
return response | |
except IndexError: | |
return "Error: Document Q&A tool not found at the expected index (4). Check agent tool setup in app.py." | |
except Exception as e: | |
import traceback # Add this import if it's not already at the top of the file | |
print(f"Error during Document Q&A tool execution: {e}") | |
print("Full Traceback:") | |
print(traceback.format_exc()) # <--- ADD THIS LINE | |
return f"An error occurred during Document Q&A: {str(e)}" | |
# If no PDF file, or query is empty when file is present, handle as a general agent query | |
elif query and query.strip(): | |
print(f"No PDF file or query is for general task. Processing with agent.run(): {query}") | |
try: | |
# --- Call the agent's run method for general queries --- | |
response = self.agent.run(query) | |
print("Agent.run finished for general query.") | |
return response | |
except Exception as e: | |
print(f"Error during agent.run: {e}") | |
return f"An error occurred while processing your request: {str(e)}" | |
# Handle cases where only a PDF is uploaded without a question, or no input at all | |
elif pdf_file is not None: | |
# Optional: Clean up the uploaded file if no question was provided | |
# import os | |
# try: | |
# if os.path.exists(pdf_file.name): | |
# os.remove(pdf_file.name) | |
# print(f"Cleaned up file: {pdf_file.name}") | |
# except Exception as e: | |
# print(f"Error cleaning up file {pdf_file.name}: {e}") | |
return "Please enter a question in the textbox to ask about the uploaded PDF." | |
else: | |
return "Please enter a request or upload a document for analysis." | |
def launch(self): | |
""" | |
Launches the Gradio user interface with input components stacked vertically. | |
""" | |
with gr.Blocks() as demo: | |
gr.Markdown("# Multi-Tool AI Agent with Document Upload") | |
gr.Markdown( | |
"Enter your request and optionally upload a PDF document. " | |
"If you upload a PDF, the text box should contain your question about the document. " | |
"Otherwise, use the text box for general requests (weather, search, etc.)." | |
) | |
# Stack components vertically by default within gr.Blocks | |
# Text input for the user's query or question | |
query_input = gr.Textbox( | |
label="Enter your request or question:", | |
placeholder="e.g., What is the weather in London? Search for the latest news about AI. What does this document say about [topic]? Summarize the document.", | |
lines=3, # Gives height to the textbox | |
interactive=True | |
) | |
# File upload component for PDF documents - placed below the textbox | |
pdf_upload = gr.File( | |
label="Upload PDF (Optional - for Document Q&A)", | |
file_types=[".pdf"], # Restrict file types to PDF | |
interactive=True, | |
# The vertical size of this component is somewhat fixed by Gradio | |
) | |
# Button to trigger the processing function - placed below the file upload | |
submit_btn = gr.Button("Submit") | |
# Output field below the button | |
agent_output = gr.Textbox( | |
label="Agent's Response:", | |
interactive=False, | |
lines=10, | |
autoscroll=True | |
) | |
# Link the button click to the process_input function | |
# Pass both query_input (text) and pdf_upload (file) as inputs | |
submit_btn.click( | |
fn=self.process_input, | |
inputs=[query_input, pdf_upload], # This list specifies all inputs | |
outputs=agent_output # This specifies the output where the return value goes | |
) | |
# Optional examples - adjust these based on your tools and whether you have default files | |
# examples = [ | |
# ["What is the time in Berlin?", None], # Example with only text | |
# ["Generate an image of a robot cooking pasta.", None], # Example with only text | |
# # Example for document Q&A - requires a default file path accessible by the tool | |
# # and needs to be in the same directory or accessible path | |
# # ["Summarize the introduction section", "sample_document.pdf"] # Example with text and file | |
# ] | |
# gr.Examples(examples=examples, inputs=[query_input, pdf_upload]) # Examples take same inputs as function | |
# Launch the Gradio interface | |
# Setting share=True creates a public URL (useful for demos, be mindful of security/costs) | |
# Setting inline=False opens the app in a new browser tab | |
demo.launch(share=False, inline=False) |