|
|
""" |
|
|
Definições do estado do agente e funções de coordenação geral |
|
|
""" |
|
|
from typing import Dict, Any, Optional, TypedDict |
|
|
|
|
|
|
|
|
class AgentState(TypedDict): |
|
|
"""Estado do agente LangGraph - apenas dados serializáveis""" |
|
|
user_input: str |
|
|
selected_model: str |
|
|
response: str |
|
|
advanced_mode: bool |
|
|
execution_time: float |
|
|
error: Optional[str] |
|
|
intermediate_steps: list |
|
|
|
|
|
|
|
|
db_sample_dict: dict |
|
|
|
|
|
|
|
|
agent_id: str |
|
|
engine_id: str |
|
|
cache_id: str |
|
|
|
|
|
|
|
|
query_type: str |
|
|
sql_query_extracted: Optional[str] |
|
|
graph_type: Optional[str] |
|
|
graph_data: Optional[dict] |
|
|
graph_image_id: Optional[str] |
|
|
graph_generated: bool |
|
|
graph_error: Optional[str] |
|
|
|
|
|
|
|
|
cache_hit: bool |
|
|
|
|
|
|
|
|
processing_enabled: bool |
|
|
processing_model: str |
|
|
processing_agent_id: Optional[str] |
|
|
suggested_query: Optional[str] |
|
|
query_observations: Optional[str] |
|
|
processing_result: Optional[dict] |
|
|
processing_success: bool |
|
|
processing_error: Optional[str] |
|
|
|
|
|
|
|
|
refined: bool |
|
|
refinement_error: Optional[str] |
|
|
refinement_quality: Optional[str] |
|
|
quality_metrics: Optional[dict] |
|
|
|
|
|
|
|
|
sql_context: Optional[str] |
|
|
sql_result: Optional[dict] |
|
|
|
|
|
|
|
|
connection_type: str |
|
|
postgresql_config: Optional[dict] |
|
|
selected_table: Optional[str] |
|
|
single_table_mode: bool |
|
|
connection_success: bool |
|
|
connection_error: Optional[str] |
|
|
connection_info: Optional[dict] |
|
|
|
|
|
|
|
|
def should_refine_response(state: Dict[str, Any]) -> str: |
|
|
""" |
|
|
Determina se deve refinar a resposta |
|
|
|
|
|
Args: |
|
|
state: Estado atual |
|
|
|
|
|
Returns: |
|
|
Nome do próximo nó |
|
|
""" |
|
|
if state.get("advanced_mode", False) and not state.get("error"): |
|
|
return "refine_response" |
|
|
else: |
|
|
return "cache_response" |
|
|
|
|
|
|
|
|
def should_generate_graph(state: Dict[str, Any]) -> str: |
|
|
""" |
|
|
Determina se deve gerar gráfico |
|
|
|
|
|
Args: |
|
|
state: Estado atual |
|
|
|
|
|
Returns: |
|
|
Nome do próximo nó |
|
|
""" |
|
|
query_type = state.get("query_type", "") |
|
|
|
|
|
if query_type == "sql_query_graphic" and not state.get("error"): |
|
|
return "graph_selection" |
|
|
elif state.get("advanced_mode", False) and not state.get("error"): |
|
|
return "refine_response" |
|
|
else: |
|
|
return "cache_response" |
|
|
|
|
|
|
|
|
def should_use_processing_agent(state: Dict[str, Any]) -> str: |
|
|
""" |
|
|
Determina se deve usar o Processing Agent |
|
|
|
|
|
Args: |
|
|
state: Estado atual |
|
|
|
|
|
Returns: |
|
|
Nome do próximo nó |
|
|
""" |
|
|
if state.get("processing_enabled", False): |
|
|
return "validate_processing" |
|
|
else: |
|
|
return "prepare_context" |
|
|
|
|
|
|
|
|
def route_after_cache_check(state: Dict[str, Any]) -> str: |
|
|
""" |
|
|
Roteamento após verificação de cache |
|
|
|
|
|
CACHE TEMPORARIAMENTE DESATIVADO - Sempre ignora cache hit |
|
|
|
|
|
Args: |
|
|
state: Estado atual |
|
|
|
|
|
Returns: |
|
|
Nome do próximo nó |
|
|
""" |
|
|
import logging |
|
|
|
|
|
cache_hit = state.get("cache_hit", False) |
|
|
processing_enabled = state.get("processing_enabled", False) |
|
|
|
|
|
|
|
|
|
|
|
cache_hit = False |
|
|
|
|
|
logging.info(f"[ROUTING] Cache hit: {cache_hit} (CACHE DESATIVADO TEMPORARIAMENTE)") |
|
|
logging.info(f"[ROUTING] Processing enabled: {processing_enabled}") |
|
|
|
|
|
if cache_hit: |
|
|
logging.info("[ROUTING] Direcionando para update_history (cache hit)") |
|
|
return "update_history" |
|
|
elif processing_enabled: |
|
|
logging.info("[ROUTING] Direcionando para validate_processing (processing habilitado)") |
|
|
return "validate_processing" |
|
|
else: |
|
|
logging.info("[ROUTING] Direcionando para connection_selection (fluxo direto)") |
|
|
return "connection_selection" |
|
|
|