Spaces:
Sleeping
Sleeping
import json | |
import time | |
from pydantic import BaseModel, Field, ValidationError | |
from typing import List | |
from langchain.output_parsers import PydanticOutputParser | |
from langchain.prompts import ChatPromptTemplate | |
from google_apis import create_service | |
from langchain_google_genai import ( | |
ChatGoogleGenerativeAI, | |
HarmBlockThreshold, | |
HarmCategory, | |
) | |
client_secret = 'client_secret.json' | |
class Evento(BaseModel): | |
calendar_id: str = Field(default="primary", description="Identificador do calendário do Google Agenda onde o evento será criado. Por padrão, utiliza o calendário principal do usuário ('primary'). Para usar um calendário diferente, forneça o ID do calendário específico.") | |
summary: str = Field(description="Título ou resumo conciso do evento, que será exibido no Google Agenda.") | |
location: str = Field(description="Localização do evento. Pode ser um endereço físico ou um nome de local.") | |
description: str = Field(description="Descrição detalhada do evento, incluindo informações adicionais, agenda, objetivos.") | |
start: str = Field(description="Data e hora de início do evento no formato ISO 8601 (Exemplo: '2023-10-27T10:00:00').") | |
end: str = Field(description="Data e hora de término do evento no formato ISO 8601 (Exemplo: '2023-10-27T11:00:00').") | |
timezone: str = Field(default="America/Fortaleza", description="Fuso horário do evento, utilizando a nomenclatura da IANA Time Zone Database (e.g., 'America/Sao_Paulo', 'Europe/London'). O padrão é 'America/Fortaleza'.") | |
def construct_google_calendar_client(client_secret): | |
""" | |
Constrói um cliente para a API Google Calendar. | |
Parâmetros: | |
- client_secret (str): O caminho para o arquivo client secret JSON. | |
Retorna: | |
- service: A instância de serviço com o API do Google Calendar. | |
""" | |
API_NAME = 'calendar' | |
API_VERSION = 'v3' | |
SCOPES = ['https://www.googleapis.com/auth/calendar'] | |
service = create_service(client_secret, API_NAME, API_VERSION, SCOPES) | |
return service | |
calendar_service = construct_google_calendar_client(client_secret) | |
def create_calendar(calendar_name): | |
""" | |
Criar uma nova lista de calendários. | |
Parâmetros: | |
- calendar_name (str): O nome da nova lista de calendário. | |
Retorno: | |
- dict: Um dicionário contendo o ID da nova lista de calendário. | |
""" | |
calendar_name = calendar_name.replace("'", "").replace('"', "") | |
calendar_list = { | |
'summary': calendar_name | |
} | |
created_calendar_list = calendar_service.calendars().insert(body=calendar_list).execute() | |
return created_calendar_list | |
def list_calendar_list(max_capacity=200): | |
""" | |
Lista todas as listas de calendários disponíveis, com limite de capacidade. | |
Parâmetros: | |
- max_capacity (int, opcional): O número máximo de calendários a serem retornados. | |
Padrão: 200. | |
Retorna: | |
- list: Uma lista de dicionários, onde cada dicionário contém os detalhes | |
de um calendário (ID, nome e descrição). | |
""" | |
if isinstance(max_capacity, str): | |
max_capacity = int(max_capacity) | |
all_calendars = [] | |
all_calendars_cleaned = [] | |
next_page_token = None | |
capacity_tracker = 0 | |
while True: | |
calendar_list = calendar_service.calendarList().list( | |
maxResults = min(200, max_capacity - capacity_tracker), | |
pageToken = next_page_token | |
).execute() | |
calendars = calendar_list.get('items', []) | |
all_calendars.extend(calendars) | |
capacity_tracker += len(calendars) | |
if capacity_tracker >= max_capacity: | |
break | |
next_page_token = calendar_list.get('nextPageToken') | |
if not next_page_token: | |
break | |
for calendar in all_calendars: | |
all_calendars_cleaned.append( | |
{ | |
'id': calendar['id'], | |
'name': calendar['summary'], | |
'description': calendar.get('description', '') | |
}) | |
return all_calendars_cleaned | |
def list_calendar_events(calendar_id, max_capacity=20): | |
""" | |
Lista os eventos de um calendário específico. | |
Parâmetros: | |
- calendar_id (str): O ID do calendário para listar os eventos. | |
- max_capacity (int, opcional): O número máximo de eventos a serem retornados. | |
Padrão: 20. | |
Retorna: | |
- list: Uma lista de dicionários contendo os detalhes dos eventos. | |
""" | |
if isinstance(max_capacity, str): | |
max_capacity = int(max_capacity) | |
all_events = [] | |
next_page_token = None | |
capacity_tracker = 0 | |
while True: | |
events_list = calendar_service.events().list( | |
calendarId=calendar_id, | |
maxResults=min(250, max_capacity - capacity_tracker), | |
pageToken=next_page_token | |
).execute() | |
events = events_list.get('items', []) | |
all_events.extend(events) | |
capacity_tracker += len(events) | |
if capacity_tracker >= max_capacity: | |
break | |
if not next_page_token: | |
break | |
return all_events | |
def extract_event_parameters(query): | |
""" | |
Extrai parâmetros de um evento a partir de uma descrição em linguagem natural. | |
Esta função utiliza um modelo de linguagem grande para interpretar a descrição do evento | |
fornecida e extrair informações como resumo, local, descrição, horário de início e fim, | |
e fuso horário. A resposta é formatada como um JSON de acordo com o esquema definido pela | |
classe `Evento`. | |
Args: | |
query (str): A descrição do evento em linguagem natural. | |
Exemplo: "Marcar reunião com o time de marketing amanhã às 10h na sala de conferência." | |
Returns: | |
str: Uma string JSON contendo os parâmetros extraídos do evento, ou None se a extração falhar. | |
O JSON terá a seguinte estrutura: | |
{ | |
"calendar_id": "ID do calendário Google (padrão: 'primary')", | |
"summary": "Resumo do evento", | |
"location": "Local do evento", | |
"description": "Descrição do evento", | |
"start": "Hora de início do evento", | |
"end": "Hora de término do evento", | |
"timezone": "Fuso horário do evento (padrão: 'America/Fortaleza')" | |
} | |
""" | |
llm = ChatGoogleGenerativeAI( | |
model="gemini-1.5-flash", | |
convert_system_message_to_human=True, | |
handle_parsing_errors=True, | |
temperature=0.6, | |
max_tokens= 1000, | |
safety_settings = { | |
HarmCategory.HARM_CATEGORY_HARASSMENT: HarmBlockThreshold.BLOCK_ONLY_HIGH, | |
HarmCategory.HARM_CATEGORY_HATE_SPEECH: HarmBlockThreshold.BLOCK_ONLY_HIGH, | |
HarmCategory.HARM_CATEGORY_SEXUALLY_EXPLICIT: HarmBlockThreshold.BLOCK_ONLY_HIGH, | |
HarmCategory.HARM_CATEGORY_DANGEROUS_CONTENT: HarmBlockThreshold.BLOCK_ONLY_HIGH, | |
}, | |
) | |
parser = PydanticOutputParser(pydantic_object=Evento) | |
prompt = ChatPromptTemplate.from_messages([ | |
("system", "Você é um assistente especialista em extrair informações de eventos de textos. Extraia os parâmetros necessários para criar um evento, incluindo data e hora de início e fim. Retorne a resposta formatada em JSON de acordo com o esquema fornecido.\n\n{format_instructions}\n"), | |
("human", "{user_query}") | |
]) | |
chain = prompt | llm | parser | |
resposta = chain.invoke({ | |
"language": "Portuguese", | |
"user_query": query, | |
"format_instructions": parser.get_format_instructions(), | |
}) | |
resposta_dict = { | |
'summary': resposta.summary, | |
'location': resposta.location, | |
'description': resposta.description, | |
'start': { | |
"dateTime": resposta.start, | |
"timeZone": resposta.timezone | |
}, | |
'end': { | |
"dateTime": resposta.end, | |
"timeZone": resposta.timezone | |
}, | |
'attendees': [] | |
} | |
resposta_json = json.dumps(resposta_dict, ensure_ascii=False) | |
return resposta.calendar_id, resposta_json | |
def insert_calendar_event(event): | |
""" | |
Insere um evento em um calendário Google. | |
Parâmetros: | |
- event (str): Uma descrição em linguagem natural do evento a ser criado. | |
A função `extract_event_parameters` será utilizada para extrair os detalhes | |
do evento a partir desta descrição e convertê-los em um objeto `Evento`. | |
Exemplos: | |
- "Agendar almoço com a Maria na sexta-feira ao meio-dia no restaurante X." | |
- "Criar um lembrete para pagar as contas no dia 10 às 9h da manhã." | |
- "Bloquear minha agenda para foco no projeto Y na próxima segunda das 14h às 17h." | |
Retorna: | |
- dict: Detalhes do evento criado no Google Agenda ou mensagem de erro. | |
Em caso de sucesso, o dicionário conterá informações sobre o evento criado, | |
incluindo o ID do evento. Em caso de erro, retornará uma mensagem descrevendo | |
o problema encontrado durante o processamento ou inserção do evento. | |
""" | |
extracted_data = extract_event_parameters(event) | |
if not extracted_data: | |
return "Erro: Não foi possível extrair os detalhes do evento da descrição fornecida." | |
calendar_id, event_details = extracted_data | |
request_body = json.loads(event_details) | |
time.sleep(1) ## Evitar limites de requisições do plano gratuito | |
event = calendar_service.events().insert( | |
calendarId = calendar_id, | |
body = request_body | |
).execute() | |
return event |