Spaces:
Sleeping
Sleeping
File size: 11,755 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 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 |
import os
from datetime import datetime
from langchain import hub
from langchain.agents import Tool, AgentExecutor
from langchain.agents.format_scratchpad import format_log_to_str
from langchain.agents.output_parsers import ReActSingleInputOutputParser
from langchain.memory import ChatMessageHistory, ConversationBufferWindowMemory
from langchain.tools.render import render_text_description
from langchain.utilities import DuckDuckGoSearchAPIWrapper
from langchain_google_genai import (
ChatGoogleGenerativeAI,
HarmBlockThreshold,
HarmCategory,
)
import streamlit as st
from planing_tools import weatherapi_forecast_periods, query_rag
from calendar_tools import list_calendar_list, list_calendar_events, insert_calendar_event, create_calendar
from dotenv import load_dotenv
hoje = datetime.today()
data_formatada = hoje.strftime("%Y/%m/%d")
# Pega o dia da semana em inglês
dia_da_semana_ingles = hoje.strftime("%A")
# Dicionário para mapear os dias da semana de inglês para português
dias_da_semana_pt = {
"Monday": "segunda-feira",
"Tuesday": "terça-feira",
"Wednesday": "quarta-feira",
"Thursday": "quinta-feira",
"Friday": "sexta-feira",
"Saturday": "sábado",
"Sunday": "domingo"
}
# Traduz o dia da semana para português
dia_da_semana_pt = dias_da_semana_pt.get(dia_da_semana_ingles, dia_da_semana_ingles)
# Formata a data para utilizar no prompt
data_atual = f"{dia_da_semana_pt}, {data_formatada}"
load_dotenv()
os.environ["GOOGLE_API_KEY"] = os.getenv('GOOGLE_API_KEY')
os.environ["LANGCHAIN_API_KEY"] = os.getenv('LANGCHAIN_API_KEY')
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,
},
)
def transfer_to_calendar_agent(input_str):
return calendar_agent_executor.invoke({"input": input_str})
def transfer_to_travel_agent(input_str):
return travel_agent_executor.invoke({"input": input_str})
ddg_search = DuckDuckGoSearchAPIWrapper()
travel_planing_tools = [
Tool(
name="DuckDuckGo Search",
func=ddg_search.run,
description="""Essa ferramenta DEVE ser utilizada para buscar eventos relevantes no período fornecido pelo usuário.
Ela é útil para obter informações sobre eventos ou atividades especiais que estão acontecendo na cidade de destino nas datas que o usuário informou.
O modelo deve usá-la para complementar as sugestões de atividades."""
),
Tool(
name="Weather Forecast",
func=lambda date_string: weatherapi_forecast_periods(date_string, st.session_state.selected_destino),
description="""Esta ferramenta DEVE ser usada obrigatoriamente *antes* de gerar o roteiro turístico, e somente após coletar todas as informações necessárias do usuário, incluindo o intervalo exato de datas.
A consulta do clima deve ser feita separadamente para cada dia do período informado, garantindo que as atividades planejadas no roteiro sejam compatíveis com as condições climáticas previstas.
**Quando usar:**
- O clima é um fator relevante para a definição de atividades no roteiro.
- O usuário especificou o intervalo de datas para o planejamento.
**Instruções:**
1. Certifique-se de coletar as datas exatas do período solicitado pelo usuário.
2. Consulte a previsão do tempo para cada dia separadamente no intervalo de datas fornecido.
3. Use o resultado da previsão para ajustar o planejamento das atividades de acordo com as condições climáticas.
**Exemplo de uso:**
- Entrada do usuário: "Planeje um roteiro entre os dias 1º de agosto e 4 de março."
- Ações do modelo:
Action input: 2025/08/01
Action input: 2025/08/02
Action input: 2025/08/03
Action input: 2025/08/04
"""
),
Tool(
name="Query RAG",
func=lambda query_text: query_rag(query_text, st.session_state.selected_destino),
description="""Esta ferramenta deve ser usada quando o modelo souber a cidade de destino e os interesses do usuário, com o objetivo de fornecer informações sobre pontos turísticos e atrações que se alinham com esses interesses.
O modelo deve utilizar essa ferramenta para sugerir atividades e lugares específicos a visitar, baseados na cidade e nos interesses fornecidos."""
),
Tool(
name="Calendar Agent",
func=transfer_to_calendar_agent,
description="Esse agente lida com tudo relacionado ao calendário. As mensagens enviadas a ele devem estar em Português."
),
]
from calendar_tools import list_calendar_list, list_calendar_events, insert_calendar_event, create_calendar
google_calendar_tools = [
Tool(
name="Create Calendar List",
func=create_calendar,
description="""
Use a função create_calendar_list para criar um novo calendário.
Forneça o resumo (título) do calendário que você deseja criar.
- Exemplo de uso: 'Meu Calendário de Viagens'
- Essa função vai criar um novo calendário com o resumo fornecido.
"""
),
Tool(
name="List Calendar List",
func=list_calendar_list,
description="""
Use a função list_calendar_list para obter a lista dos seus calendários disponíveis no Google Calendar.
Se você quiser limitar o número de calendários retornados, forneça o número máximo desejado.
- Exemplo de uso: Forneça o número máximo de calendários a serem listados, como 50. Se não quiser um limite, apenas diga para listar 200 o máximo por padrão.
"""
),
Tool(
name="List Calendar Events",
func=list_calendar_events,
description="""
Use a função list_calendar_events para obter a lista de eventos de um calendário específico.
Você precisa fornecer o ID do calendário e, opcionalmente, o número máximo de eventos a serem listados.
- Exemplo de uso para o calendário principal: forneça 'primary' como o ID do calendário.
- Exemplo de uso com limite: forneça o ID do calendário e o número máximo de eventos, como 'primary', 20.
- Para listar eventos de um calendário específico, primeiro liste seus calendários para encontrar o ID correto.
"""
),
Tool(
name="Insert Calendar Event",
func=insert_calendar_event,
description="""
Use a função Insert Calendar Event para adicionar **um único evento** a um calendário Google.
Esta função deve ser chamada **uma vez para cada evento** que precisa ser agendado.
A entrada para esta função deve ser uma descrição clara e completa de **um único evento**
em linguagem natural, contendo todas as informações necessárias para agendá-lo individualmente.
Se o usuário pediu para criar um novo calendário, você DEVE utilizar o calendar_id desse novo calendário para a inserção dos eventos.
**Formato de entrada esperado:**
**Descrição em Linguagem Natural (obrigatório):**
Forneça uma descrição textual detalhada para **um único evento**. Inclua o calendar_id (se fornecido pelo usuário), o que será feito,
quando (data e hora específicas), onde (local exato) e quaisquer detalhes adicionais relevantes
para esse evento em particular.
**Exemplos de descrições de eventos individuais:**
- "Agendar almoço com a Maria na sexta-feira ao meio-dia no restaurante X."
- "Criar um compromisso para pagar as contas no dia 10 de janeiro às 9h da manhã."
- "Bloquear minha agenda para foco no projeto Y na próxima segunda-feira, das 14h às 17h, na minha mesa."
**Como usar esta função corretamente:**
1. **Identifique cada evento individualmente:** Se a intenção é agendar múltiplos eventos,
trate cada um como uma chamada separada para esta função.
2. **Obtenha o ID do calendário (se necessário):** Se o usuário mencionar um nome de
calendário específico, use a função 'list_calendar_list' **primeiro** para obter
o 'calendar_id' correspondente.
3. **Chame esta função com a descrição de um único evento:** Forneça a descrição completa
em linguagem natural para o evento específico que você deseja agendar.
**Informações essenciais para cada descrição de evento:**
- **O que:** Uma descrição concisa do evento (ex: "Reunião de equipe", "Consulta médica").
- **Quando:** A data e hora de início e fim **precisas** do evento.
- **Onde:** O local **específico** do evento.
- **Fuso Horário (opcional):** Se aplicável, mencione o fuso horário se for diferente
de "America/Fortaleza".
**Exemplo de uso**
*Usuário: Agendar visita ao Aquário Natal sábado das 9h às 12h.*
*Agente:* (Chama 'Insert Calendar Event' com a Action Input: "Agendar visita ao Aquário Natal sábado das 9h às 12h.")
**Observação IMPORTANTE:** Esta função **NÃO** deve ser usada para criar múltiplos eventos
com uma única chamada. Cada chamada deve corresponder a **um único evento**.
Ao final da execução desta função, você DEVE fornecer ao usuário a confirmação do agendamento
desse evento específico, incluindo o título, data, hora.
No final forneça o link para o calendário google: [https://www.google.com/calendar]
"""
)
]
travel_planing_prompt = hub.pull("tales/agente_turismo")
google_calendar_prompt = hub.pull("tales/agente_calendario")
llm_with_stop = llm.bind(stop=["\nObservation"])
planing_prompt = travel_planing_prompt.partial(
tools=render_text_description(travel_planing_tools),
tool_names=", ".join([t.name for t in travel_planing_tools]),
)
calendar_prompt = google_calendar_prompt.partial(
tools=render_text_description(google_calendar_tools),
tool_names=", ".join([t.name for t in google_calendar_tools]),
)
history = ChatMessageHistory()
memory = ConversationBufferWindowMemory(
k=20,
chat_memory=history,
memory_key="chat_history",
input_key="input",
other_memory_key=["destino"])
travel_planing_agent = (
{
"input": lambda x: x["input"],
"destino": lambda x: x.get("destino"),
"agent_scratchpad": lambda x: format_log_to_str(x["intermediate_steps"]),
"chat_history": lambda x: x["chat_history"],
"data_atual": lambda x: data_atual,
}
| planing_prompt
| llm_with_stop
| ReActSingleInputOutputParser()
)
travel_agent_executor = AgentExecutor(agent=travel_planing_agent, tools=travel_planing_tools, verbose=True, memory=memory, handle_parsing_errors=True)
google_calendar_agent = (
{
"input": lambda x: x["input"],
"agent_scratchpad": lambda x: format_log_to_str(x["intermediate_steps"]),
"chat_history": lambda x: x["chat_history"],
"data_atual": lambda x: data_atual,
}
| calendar_prompt
| llm_with_stop
| ReActSingleInputOutputParser()
)
calendar_agent_executor = AgentExecutor(agent=google_calendar_agent, tools=google_calendar_tools, verbose=True, memory=memory) |