Spaces:
Sleeping
Sleeping
File size: 9,530 Bytes
b2437ae |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 |
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 |