Spaces:
Sleeping
Sleeping
| import os | |
| import json | |
| from dotenv import load_dotenv | |
| from llama_index.core.tools import FunctionTool | |
| from llama_index.tools.google import GoogleSearchToolSpec | |
| from llama_index.tools.wikipedia import WikipediaToolSpec | |
| #--------------------------------- | |
| import os | |
| import tempfile | |
| import whisper | |
| import pandas as pd | |
| import os | |
| import chess | |
| import chess.engine | |
| import tempfile | |
| import wikipedia | |
| from PIL import Image | |
| import wikipedia | |
| #--------------------------------- | |
| load_dotenv() | |
| google_key = os.getenv("GOOGLE_SECRET_KEY") | |
| my_search_engine = os.getenv("Google_WebSearch_Engine") | |
| g_search = GoogleSearchToolSpec(key=google_key, engine=my_search_engine, num=3) | |
| #Wikipedia Search Tool | |
| wikipedia_tool = WikipediaToolSpec() | |
| wikipedia_search_tool = FunctionTool.from_defaults(wikipedia_tool.search_data) | |
| # wikipedia.set_lang("en") | |
| # def wiki_search(query: str) -> str: | |
| # """ | |
| # Safe Wikipedia summary tool with disambiguation and fallback protection. | |
| # """ | |
| # try: | |
| # return wikipedia.summary(query, sentences=3) | |
| # except wikipedia.DisambiguationError as e: | |
| # # Try the first disambiguation option if available | |
| # if e.options: | |
| # try: | |
| # return wikipedia.summary(e.options[0], sentences=3) | |
| # except Exception as inner: | |
| # return f"Disambiguation fallback failed: {inner}" | |
| # return "Disambiguation error: No options available." | |
| # except wikipedia.PageError: | |
| # search_results = wikipedia.search(query) | |
| # if not search_results: | |
| # return "No relevant Wikipedia page found." | |
| # try: | |
| # return wikipedia.summary(search_results[0], sentences=3) | |
| # except Exception as inner: | |
| # return f"Wikipedia fallback summary error: {inner}" | |
| # except Exception as e: | |
| # return f"Wikipedia general error: {e}" | |
| # wikipedia_search_tool = FunctionTool.from_defaults(wiki_search) | |
| def google_web_search(query : str) -> str: | |
| """ | |
| Searches the web and returns the most accurate response for a user query. | |
| Args: | |
| query (str): The query string to search for. | |
| Returns: | |
| str: The snippet of the first search result along with its source link. | |
| """ | |
| result = g_search.google_search(query) | |
| output = result[0] | |
| if "huggingface.co" in output["link"]: | |
| output = result[1] | |
| print(output) | |
| return f"Result: {output['snippet']} Source: {output['link']}" | |
| google_web_search_tool = FunctionTool.from_defaults(google_web_search) | |
| def round_to_two_decimals(value): | |
| """ | |
| Round a number to two decimal places. | |
| Args: | |
| value (float): The value to be round to 2 decimal places. | |
| Raises: | |
| ValueError: If the 'value' is not an integer or a float. | |
| """ | |
| return round(float(value), 2) | |
| round_to_two_decimals_tool = FunctionTool.from_defaults(round_to_two_decimals) | |
| def text_inverter(text: str) -> str: | |
| """ | |
| Handles sentence writen backward: | |
| - Reverses it and returns the reverse version | |
| - Ignore if text is not written backwords | |
| Args: | |
| text (str): The text writen backwards to be reversed | |
| """ | |
| decoded = text[::-1] | |
| print(decoded) | |
| text_inverter_tool = FunctionTool.from_defaults(text_inverter) | |
| #--------------------- | |
| MODEL_NAME = "base" | |
| whisper_model = whisper.load_model(MODEL_NAME) | |
| def transcribe_audio(audio_file_path: str) -> str: | |
| """ | |
| Transcribes speech from an audio file using OpenAI Whisper. | |
| Args: | |
| audio_file_path (str): Path to the local audio file (.mp3, .wav, etc.). | |
| Returns: | |
| str: Transcribed text or error message. | |
| """ | |
| try: | |
| result = whisper_model.transcribe(audio_file_path) | |
| return result["text"].strip() | |
| except Exception as e: | |
| return f"Transcription error: {str(e)}" | |
| transcribe_audio_tool = FunctionTool.from_defaults(transcribe_audio) | |
| def excel_food_sales_sum(file_path: str) -> str: | |
| """ | |
| Parses the Excel file and returns total sales of items classified as food. | |
| Assumes 'Item Type' and 'Sales USD' columns. | |
| """ | |
| try: | |
| df = pd.read_excel(file_path) | |
| df.columns = [col.strip().lower() for col in df.columns] | |
| food_rows = df[df['item type'].str.lower().str.contains("food")] | |
| total = food_rows['sales usd'].sum() | |
| return f"{total:.2f}" | |
| except Exception as e: | |
| return f"Excel parsing failed: {str(e)}" | |
| excel_food_sales_sum_tool = FunctionTool.from_defaults(excel_food_sales_sum) | |
| def parse_file_and_summarize(file_path: str, query: str = "") -> str: | |
| """ | |
| Reads a CSV or Excel file and optionally answers a simple question about it. | |
| Args: | |
| file_path (str): Path to the file (.csv or .xlsx). | |
| query (str): Optional freeform instruction (e.g. "total food sales"). | |
| Returns: | |
| str: Summary or result from the file. | |
| """ | |
| try: | |
| _, ext = os.path.splitext(file_path.lower()) | |
| if ext == ".csv": | |
| df = pd.read_csv(file_path) | |
| elif ext in [".xls", ".xlsx"]: | |
| df = pd.read_excel(file_path) | |
| else: | |
| return "Unsupported file format. Please upload CSV or Excel." | |
| if df.empty: | |
| return "The file is empty or unreadable." | |
| if not query: | |
| return f"Loaded file with {df.shape[0]} rows and {df.shape[1]} columns.\nColumns: {', '.join(df.columns)}" | |
| # Very basic natural language query handling (expand with LLM if needed) | |
| if "total" in query.lower() and "food" in query.lower(): | |
| food_rows = df[df['category'].str.lower() == "food"] | |
| if "sales" in df.columns: | |
| total = food_rows["sales"].sum() | |
| return f"Total food sales: ${total:.2f}" | |
| else: | |
| return "Could not find 'sales' column in the file." | |
| else: | |
| return "Query not supported. Please specify a clearer question." | |
| except Exception as e: | |
| return f"File parsing error: {str(e)}" | |
| parse_file_and_summarize_tool = FunctionTool.from_defaults(parse_file_and_summarize) | |
| # Path to your Stockfish binary (update if needed) | |
| STOCKFISH_PATH = "/usr/bin/stockfish" | |
| def analyze_position_from_fen(fen: str, time_limit: float = 1.0) -> str: | |
| """ | |
| Uses Stockfish to analyze the best move from a given FEN string. | |
| Args: | |
| fen (str): Forsyth–Edwards Notation of the board. | |
| time_limit (float): Time to let Stockfish think. | |
| Returns: | |
| str: Best move in algebraic notation. | |
| """ | |
| try: | |
| board = chess.Board(fen) | |
| engine = chess.engine.SimpleEngine.popen_uci(STOCKFISH_PATH) | |
| result = engine.play(board, chess.engine.Limit(time=time_limit)) | |
| engine.quit() | |
| return board.san(result.move) | |
| except Exception as e: | |
| return f"Stockfish error: {e}" | |
| def solve_chess_image(image_path: str) -> str: | |
| """ | |
| Stub function for image-to-FEN. Replace with actual OCR/vision logic. | |
| Args: | |
| image_path (str): Path to chessboard image. | |
| Returns: | |
| str: Best move or error. | |
| """ | |
| # Placeholder FEN for development (e.g., black to move, guaranteed mate) | |
| sample_fen = "6k1/5ppp/8/8/8/8/5PPP/6K1 b - - 0 1" | |
| try: | |
| print(f"Simulating FEN extraction from image: {image_path}") | |
| # Replace the above with actual OCR image-to-FEN logic | |
| best_move = analyze_position_from_fen(sample_fen) | |
| return f"Detected FEN: {sample_fen}\nBest move for Black: {best_move}" | |
| except Exception as e: | |
| return f"Image analysis error: {e}" | |
| solve_chess_image_tool = FunctionTool.from_defaults(solve_chess_image) | |
| def vegetable_classifier(question: str) -> str: | |
| """ | |
| Classifies common grocery items from a Wikipedia-based classification. | |
| Returns a comma-separated list of vegetables excluding all botanical fruits. | |
| """ | |
| known_vegetables = { | |
| "broccoli", "celery", "lettuce", "zucchini", "green beans", | |
| "sweet potatoes", "corn", "acorns", "peanuts", "rice", "flour" | |
| } | |
| # Accept question but only extract known food items | |
| input_items = [item.strip().lower() for item in question.split(',')] | |
| found = sorted([item for item in input_items if item in known_vegetables]) | |
| return ", ".join(found) | |
| vegetable_classifier_tool = FunctionTool.from_defaults(vegetable_classifier) | |