Spaces:
Running
Running
| """backend/tools/gdrive_tool.py — Google Drive Tier 3 Memory Tool. | |
| Consente all'agente di archiviare e recuperare dati da Google Drive. | |
| Ottimizzato per sessioni lunghe e offloading di memoria. | |
| """ | |
| import os, json, logging, httpx | |
| from typing import Any, Optional | |
| from api.auth_managed import _decrypt, _sb_list_tokens | |
| _logger = logging.getLogger("gdrive_tool") | |
| _TIMEOUT = 20.0 | |
| async def gdrive_rw( | |
| action: str, | |
| filename: Optional[str] = None, | |
| content: Optional[str] = None, | |
| file_id: Optional[str] = None, | |
| query: Optional[str] = None, | |
| user_id: str = "default" | |
| ) -> dict[str, Any]: | |
| """ | |
| Gestisce file su Google Drive per memoria a lungo termine. | |
| action: search, read, write, update | |
| """ | |
| try: | |
| # 1. Recupera token Google | |
| tokens = await _sb_list_tokens(user_id) | |
| g_token = next((t for t in tokens if t['provider'] == 'google'), None) | |
| if not g_token: | |
| return {"ok": False, "error": "[CONNECTOR_NEEDED:google] Connetti Google Drive per usare la memoria Tier 3"} | |
| access_token = _decrypt(g_token['access_token']) | |
| headers = {"Authorization": f"Bearer {access_token}", "Accept": "application/json"} | |
| async with httpx.AsyncClient(timeout=_TIMEOUT) as client: | |
| # --- SEARCH --- | |
| if action == "search": | |
| q = f"name contains '{query}'" if query else "mimeType = 'text/plain'" | |
| r = await client.get( | |
| "https://www.googleapis.com/drive/v3/files", | |
| params={"q": q, "fields": "files(id, name, modifiedTime)"}, | |
| headers=headers | |
| ) | |
| if r.status_code != 200: | |
| return {"ok": False, "error": f"Drive Search Error: {r.text[:200]}"} | |
| return {"ok": True, "files": r.json().get("files", [])} | |
| # --- READ --- | |
| elif action == "read": | |
| if not file_id: return {"ok": False, "error": "file_id mancante"} | |
| r = await client.get(f"https://www.googleapis.com/drive/v3/files/{file_id}?alt=media", headers=headers) | |
| if r.status_code != 200: | |
| return {"ok": False, "error": f"Drive Read Error: {r.text[:200]}"} | |
| return {"ok": True, "content": r.text} | |
| # --- WRITE (Create) --- | |
| elif action == "write": | |
| if not filename: return {"ok": False, "error": "filename mancante"} | |
| meta = {"name": filename, "mimeType": "text/plain"} | |
| files = {'data': ('metadata', json.dumps(meta), 'application/json'), | |
| 'file': (filename, content or "", 'text/plain')} | |
| r = await client.post("https://www.googleapis.com/upload/drive/v3/files?uploadType=multipart", | |
| headers={"Authorization": f"Bearer {access_token}"}, files=files) | |
| if r.status_code not in (200, 201): | |
| return {"ok": False, "error": f"Drive Write Error: {r.text[:200]}"} | |
| return {"ok": True, "file_id": r.json().get("id"), "message": f"File {filename} creato su Drive"} | |
| # --- UPDATE --- | |
| elif action == "update": | |
| if not file_id: return {"ok": False, "error": "file_id mancante"} | |
| r = await client.patch(f"https://www.googleapis.com/upload/drive/v3/files/{file_id}?uploadType=media", | |
| headers=headers, content=content or "") | |
| if r.status_code != 200: | |
| return {"ok": False, "error": f"Drive Update Error: {r.text[:200]}"} | |
| return {"ok": True, "message": "File aggiornato su Drive"} | |
| return {"ok": False, "error": f"Azione {action} non supportata"} | |
| except Exception as e: | |
| _logger.error("GDrive Tool Error: %s", e) | |
| return {"ok": False, "error": str(e)} | |
| TOOL_DESCRIPTOR = { | |
| "name": "gdrive_memory", | |
| "description": ( | |
| "Gestisce la memoria a lungo termine su Google Drive (Tier 3). " | |
| "Usa per archiviare contesti pesanti, log o file che superano i limiti di memoria locale. " | |
| "Azioni: write (crea), read (legge), search (cerca), update (aggiorna)." | |
| ), | |
| "parameters": { | |
| "type": "object", | |
| "properties": { | |
| "action": {"type": "string", "enum": ["write", "read", "search", "update"]}, | |
| "filename": {"type": "string", "description": "Nome del file (es. session_memory_2026.txt)"}, | |
| "content": {"type": "string", "description": "Contenuto da archiviare"}, | |
| "file_id": {"type": "string", "description": "ID del file Drive per read/update"}, | |
| "query": {"type": "string", "description": "Termine di ricerca per action=search"} | |
| }, | |
| "required": ["action"] | |
| }, | |
| "fn": gdrive_rw | |
| } | |