From 043941c7ad5502acfb2838c498bbdea2c1fce63d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vitor=20Hugo=20Belorio=20Sim=C3=A3o?= Date: Fri, 20 Feb 2026 16:37:57 -0300 Subject: [PATCH] =?UTF-8?q?:recycle:=20refactor:=20Atualizando=20a=20l?= =?UTF-8?q?=C3=B3gica=20de=20retorno=20das=20tools=20e=20criando=20a=20see?= =?UTF-8?q?d=20para=20popular=20o=20banco=20de=20dados.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/db/tool_seed.py | 123 ++++++++++++++++++++++++++++++++++ app/services/tool_registry.py | 55 +++++++++------ 2 files changed, 157 insertions(+), 21 deletions(-) create mode 100644 app/db/tool_seed.py diff --git a/app/db/tool_seed.py b/app/db/tool_seed.py new file mode 100644 index 0000000..5ea20de --- /dev/null +++ b/app/db/tool_seed.py @@ -0,0 +1,123 @@ +from app.db.database import SessionLocal +from app.repositories.tool_repository import ToolRepository + + +def get_tools_definitions(): + return [ + { + "name": "consultar_estoque", + "description": "Use esta ferramenta para consultar veículos disponíveis no estoque até um preço máximo informado pelo cliente, opcionalmente filtrando por categoria (Hatch, Sedan, SUV, etc.). Ideal quando o cliente quer saber quais carros cabem no orçamento ou comparar opções dentro de uma faixa de preço.", + "parameters": { + "type": "object", + "properties": { + "preco_max": { + "type": "number", + "description": "Preço máximo do veículo em reais (BRL)." + }, + "categoria": { + "type": "string", + "description": "Categoria do veículo, por exemplo: Hatch, Sedan, SUV. Opcional." + }, + }, + "required": ["preco_max"], + }, + }, + { + "name": "validar_cliente_venda", + "description": "Use esta ferramenta quando precisar avaliar se o cliente pode financiar um veículo específico. Ela recebe o CPF e o valor do veículo, consulta um score simulado e retorna se o cliente está aprovado ou reprovado para a compra, juntamente com o score e um limite de crédito estimado.", + "parameters": { + "type": "object", + "properties": { + "cpf": { + "type": "string", + "description": "CPF do cliente, com ou sem formatação (apenas dígitos também é aceito)." + }, + "valor_veiculo": { + "type": "number", + "description": "Valor do veículo em reais (BRL) que o cliente deseja comprar." + }, + }, + "required": ["cpf", "valor_veiculo"], + }, + }, + { + "name": "avaliar_veiculo_troca", + "description": "Use esta ferramenta quando o cliente quiser saber quanto o carro dele vale como entrada em uma negociação. Ela recebe modelo, ano e quilometragem do veículo atual e devolve um valor estimado de avaliação para troca, já considerando depreciação por ano e quilometragem.", + "parameters": { + "type": "object", + "properties": { + "modelo": { + "type": "string", + "description": "Modelo do veículo que o cliente deseja oferecer na troca (por exemplo, 'Toyota Corolla')." + }, + "ano": { + "type": "integer", + "description": "Ano de fabricação do veículo do cliente." + }, + "km": { + "type": "integer", + "description": "Quilometragem atual do veículo do cliente." + }, + }, + "required": ["modelo", "ano", "km"], + }, + }, + { + "name": "agendar_revisao", + "description": "Use esta ferramenta quando o cliente quiser marcar uma revisão ou manutenção para o veículo. Ela recebe a placa e a data/hora desejada, cria um agendamento simulado e retorna um identificador, além do status do agendamento.", + "parameters": { + "type": "object", + "properties": { + "placa": { + "type": "string", + "description": "Placa do veículo que será levado para revisão." + }, + "data_hora": { + "type": "string", + "description": "Data e hora desejada para a revisão, em formato ISO 8601 (por exemplo, '2026-03-10T09:00:00-03:00')." + }, + }, + "required": ["placa", "data_hora"], + }, + }, + { + "name": "cancelar_pedido", + "description": "Use esta ferramenta quando o cliente solicitar o cancelamento de um pedido já registrado. Ela recebe o número do pedido e o motivo do cancelamento, atualiza o status para 'Cancelado' e retorna os detalhes do cancelamento para que você explique o resultado ao cliente.", + "parameters": { + "type": "object", + "properties": { + "numero_pedido": { + "type": "string", + "description": "Número do pedido que o cliente deseja cancelar." + }, + "motivo": { + "type": "string", + "description": "Motivo do cancelamento informado pelo cliente (por exemplo, atraso, mudança de planos, condição de pagamento, etc.)." + }, + }, + "required": ["numero_pedido", "motivo"], + }, + }, + ] + + +def seed_tools(): + db = SessionLocal() + try: + repo = ToolRepository(db) + existing = repo.get_all() + existing_names = {t.name for t in existing} + for tool_def in get_tools_definitions(): + if tool_def["name"] in existing_names: + continue + repo.create( + name=tool_def["name"], + description=tool_def["description"], + parameters=tool_def["parameters"], + ) + finally: + db.close() + + +if __name__ == "__main__": + seed_tools() diff --git a/app/services/tool_registry.py b/app/services/tool_registry.py index ebab905..815ef4b 100644 --- a/app/services/tool_registry.py +++ b/app/services/tool_registry.py @@ -1,30 +1,43 @@ -from typing import List +from typing import List, Dict, Callable + +from sqlalchemy.orm import Session + from app.models.tool_model import ToolDefinition -# from app.integrations.estoque_service import consultar_estoque +from app.repositories.tool_repository import ToolRepository +from app.services.handlers import ( + consultar_estoque, + validar_cliente_venda, + avaliar_veiculo_troca, + agendar_revisao, + cancelar_pedido, +) + + +HANDLERS: Dict[str, Callable] = { + "consultar_estoque": consultar_estoque, + "validar_cliente_venda": validar_cliente_venda, + "avaliar_veiculo_troca": avaliar_veiculo_troca, + "agendar_revisao": agendar_revisao, + "cancelar_pedido": cancelar_pedido, +} class ToolRegistry: - def __init__(self): + def __init__(self, db: Session): self._tools = [] - """ - # Registrando manualmente por enquanto, porém isso poderia vir de um BD. - self.register_tool( - name="consultar_estoque", - description="Consulta veículos disponíveis até determinado preço", # Descrição que ajuda o modelo Gemini a entender quado selecionar essa Tool. - parameters={ - "type": "object", - "properties": { - "preco_max": { - "type": "number", - "description": "Preço máximo do veículo" - } - }, - "required": ["preco_max"] - }, - handler=consultar_estoque - ) - """ + repo = ToolRepository(db) + db_tools = repo.get_all() + for db_tool in db_tools: + handler = HANDLERS.get(db_tool.name) + if not handler: + continue + self.register_tool( + name=db_tool.name, + description=db_tool.description, + parameters=db_tool.parameters, + handler=handler, + ) # O método abaixo serve para adicionar uma nova tool ao sistema (podendo inserir a lógica de adcicionar ao BD futuramente). def register_tool(self, name, description, parameters, handler):