import os from pathlib import Path from google.genai import types def read_file(filepath: str) -> str: """Read and return file contents.""" try: p = Path(filepath) if not p.exists(): return f"File not found: {filepath}" if p.stat().st_size > 5 * 1024 * 1024: # 5MB limit return "File too large (max 5MB)." return p.read_text(encoding="utf-8", errors="replace") except Exception as e: return f"Error reading file: {e}" def save_upload(filepath_or_obj, upload_dir="/app/data/uploads") -> str: """Save uploaded file and return path. Gradio provides filepath as string.""" os.makedirs(upload_dir, exist_ok=True) # Gradio with type="filepath" passes a string path if isinstance(filepath_or_obj, str) and filepath_or_obj: src = Path(filepath_or_obj) if src.exists(): dest = Path(upload_dir) / src.name import shutil shutil.copy2(str(src), str(dest)) return str(dest) return filepath_or_obj return str(filepath_or_obj) if filepath_or_obj else "" def get_file_info(filepath: str) -> dict: """Get file information.""" p = Path(filepath) if not p.exists(): return {"exists": False} stat = p.stat() return { "exists": True, "name": p.name, "extension": p.suffix.lower(), "size": stat.st_size, "size_human": f"{stat.st_size / 1024:.1f} KB" if stat.st_size < 1024 * 1024 else f"{stat.st_size / (1024*1024):.1f} MB", } # Tool declarations for google-genai function calling file_tool_declarations = [ types.FunctionDeclaration( name="read_uploaded_file", description="Read the contents of a file that the user uploaded. Use to analyze uploaded documents, code, or text files.", parameters=types.Schema( type="OBJECT", properties={ "filepath": types.Schema(type="STRING", description="Path to the uploaded file"), }, required=["filepath"], ), ) ] def handle_file_read(args: dict) -> str: """Handle file read tool call.""" filepath = args.get("filepath", "") return read_file(filepath)