mirror of
https://github.com/hoshikawa2/compass_backoffice.git
synced 2026-07-10 06:14:19 +00:00
bugfixes
This commit is contained in:
58
app/main.py
58
app/main.py
@@ -16,8 +16,10 @@ from agent_framework.config.settings import settings
|
||||
from agent_framework.analytics.factory import create_analytics_publisher
|
||||
from agent_framework.observability.observer import AgentObserver
|
||||
from src.compat.framework_observer import configure as configure_global_observer
|
||||
from src.compat.framework_services import configure as configure_framework_services
|
||||
from agent_framework.llm.providers import create_llm
|
||||
from agent_framework.memory.message_history import create_memory
|
||||
from agent_framework.memory.summary_memory import create_conversation_summary_memory
|
||||
from agent_framework.mcp.tool_router import create_mcp_tool_router
|
||||
from agent_framework.models.identity import AgentIdentity
|
||||
from agent_framework.identity import IdentityResolver, BusinessContext
|
||||
@@ -49,10 +51,11 @@ telemetry = Telemetry(settings)
|
||||
usage_repository = create_usage_repository(settings)
|
||||
llm = create_llm(settings, telemetry=telemetry, usage_repository=usage_repository)
|
||||
memory = create_memory(settings)
|
||||
summary_memory = create_conversation_summary_memory(settings, message_history=memory, llm=llm, telemetry=telemetry)
|
||||
sessions = create_session_repository(settings)
|
||||
checkpoints = create_checkpoint_repository(settings)
|
||||
cache = create_cache(settings, telemetry=telemetry)
|
||||
gateway = ChannelGateway()
|
||||
gateway = ChannelGateway(input_mode=settings.FRAMEWORK_CHANNEL_INPUT_MODE)
|
||||
analytics = create_analytics_publisher(settings)
|
||||
observer = AgentObserver(analytics=analytics)
|
||||
configure_global_observer({
|
||||
@@ -61,10 +64,11 @@ configure_global_observer({
|
||||
"topic_path": getattr(settings, "GCP_PUBSUB_TOPIC_PATH", None) or getattr(settings, "AGENT_PUBSUB_TOPIC", None),
|
||||
})
|
||||
tool_router = create_mcp_tool_router(settings, telemetry=telemetry)
|
||||
configure_framework_services(tool_router=tool_router)
|
||||
identity_resolver = IdentityResolver.from_yaml(settings.IDENTITY_CONFIG_PATH)
|
||||
agent_profiles = AgentProfileRegistry(settings)
|
||||
sse_hub = SSEHub(settings, telemetry=telemetry)
|
||||
workflow = AgentWorkflow(llm, memory, telemetry, analytics, settings, observer=observer, tool_router=tool_router)
|
||||
workflow = AgentWorkflow(llm, memory, telemetry, analytics, settings, observer=observer, tool_router=tool_router, summary_memory=summary_memory)
|
||||
backoffice_runtime = BackofficeNativeRuntime(settings=settings, telemetry=telemetry, analytics=analytics, observer=observer)
|
||||
|
||||
logger.info("LLM provider carregado: %s", llm.__class__.__name__)
|
||||
@@ -501,6 +505,9 @@ async def shutdown():
|
||||
# Elas chamam o BackofficeNativeRuntime, que compila os workflows com o motor
|
||||
# do framework e aplica guardrails, judges, supervisor, checkpoint e telemetry.
|
||||
|
||||
from src.api.schemas.anatel_schemas import TicketRequestEvent
|
||||
from src.api.schemas.anatel_response_emulator_schemas import EmulatorGenerateRequest, EmulatorFinalizeRequest
|
||||
|
||||
import asyncio
|
||||
from fastapi.exceptions import RequestValidationError
|
||||
from fastapi.responses import JSONResponse
|
||||
@@ -531,13 +538,15 @@ async def startup_backoffice_native_domain():
|
||||
if getattr(original_settings, "ENABLE_OCI_STREAMING", False):
|
||||
from src.infrastructure.streaming.producer import OciProducer
|
||||
app.state.oci_producer = OciProducer(original_settings.OCI_RESPONSE_STREAM_OCID)
|
||||
logger.info("OCI producer de domínio inicializado; consumer legado não é iniciado")
|
||||
configure_framework_services(progress_producer=app.state.oci_producer)
|
||||
logger.info("OCI producer de domínio inicializado via framework services; consumer legado não é iniciado")
|
||||
else:
|
||||
try:
|
||||
from src.infrastructure.streaming.debug_producer import LocalDebugProducer
|
||||
if getattr(original_settings, "DEBUG", False):
|
||||
app.state.oci_producer = LocalDebugProducer()
|
||||
logger.info("LocalDebugProducer de domínio ativo")
|
||||
configure_framework_services(progress_producer=app.state.oci_producer)
|
||||
logger.info("LocalDebugProducer de domínio ativo via framework services")
|
||||
except Exception:
|
||||
pass
|
||||
except Exception:
|
||||
@@ -621,37 +630,34 @@ async def _run_native_checklist(event, request: Request):
|
||||
|
||||
|
||||
@app.post("/agent/process-ticket", status_code=status.HTTP_200_OK)
|
||||
async def native_process_ticket(request: Request, event: "TicketRequestEvent"):
|
||||
async def native_process_ticket(request: Request, event: TicketRequestEvent):
|
||||
return await _run_native_checklist(event, request)
|
||||
|
||||
|
||||
@app.post("/agent/execute", status_code=status.HTTP_200_OK)
|
||||
async def native_agent_execute(request: Request, event: "TicketRequestEvent"):
|
||||
async def native_agent_execute(request: Request, event: TicketRequestEvent):
|
||||
return await _run_native_checklist(event, request)
|
||||
|
||||
|
||||
@app.post("/agent/process-and-stream", status_code=status.HTTP_200_OK)
|
||||
async def native_process_and_stream(request: Request, event: "TicketRequestEvent"):
|
||||
async def native_process_and_stream(request: Request, event: TicketRequestEvent):
|
||||
return await _run_native_checklist(event, request)
|
||||
|
||||
|
||||
@app.post("/agent/search-tais-kb", status_code=status.HTTP_200_OK)
|
||||
async def native_search_tais_kb(body: dict):
|
||||
"""Adapter REST para TAIS KB usando o service/cliente de domínio, não grafo legado."""
|
||||
try:
|
||||
from src.components.clients.tais_kb_client import TaisKbClient
|
||||
query = body.get("query") or body.get("text") or body.get("complaint_description") or ""
|
||||
client = TaisKbClient()
|
||||
if hasattr(client, "search"):
|
||||
result = await client.search(query=query, **{k: v for k, v in body.items() if k not in {"query", "text", "complaint_description"}})
|
||||
elif hasattr(client, "query"):
|
||||
result = await client.query(query)
|
||||
else:
|
||||
raise AttributeError("TAIS KB client has no search/query method")
|
||||
return {"framework_native": True, "result": result}
|
||||
except Exception as exc:
|
||||
await telemetry.event("backoffice.tais_kb.failed", {"error": str(exc)}, kind="tool")
|
||||
return {"framework_native": True, "result": [], "error": str(exc)}
|
||||
"""Adapter REST framework-native para TAIS KB via MCP Router."""
|
||||
from src.compat.framework_services import call_mcp_tool
|
||||
query = body.get("query") or body.get("text") or body.get("complaint_description") or ""
|
||||
result = await call_mcp_tool(
|
||||
"consultar_tais_kb",
|
||||
{"query": query, "protocol_id": body.get("protocol_id") or body.get("complaintProtocol"), "customer_key": body.get("customer_key") or body.get("cpfCnpj")},
|
||||
business_context={"customer_key": body.get("customer_key") or body.get("cpfCnpj"), "interaction_key": body.get("protocol_id") or body.get("complaintProtocol")},
|
||||
original_context=body,
|
||||
)
|
||||
if not result.get("ok"):
|
||||
await telemetry.event("backoffice.tais_kb.failed", {"error": result.get("error")}, kind="tool")
|
||||
return {"framework_native": True, "result": result}
|
||||
|
||||
|
||||
async def _run_native_emulator(request: Request, event):
|
||||
@@ -687,7 +693,7 @@ async def _run_native_emulator(request: Request, event):
|
||||
|
||||
|
||||
@app.post("/case/{transaction_id}/response-emulator/generate", status_code=status.HTTP_200_OK)
|
||||
async def native_response_emulator_generate(transaction_id: str, request: Request, body: "EmulatorGenerateRequest"):
|
||||
async def native_response_emulator_generate(transaction_id: str, request: Request, body: EmulatorGenerateRequest):
|
||||
from src.api.schemas.anatel_response_emulator_schemas import ResponseEmulatorRequestEvent, OperatorFeedback
|
||||
if body.transactionId != transaction_id:
|
||||
raise HTTPException(status_code=400, detail="transactionId path/body mismatch")
|
||||
@@ -711,7 +717,7 @@ async def native_response_emulator_generate(transaction_id: str, request: Reques
|
||||
|
||||
|
||||
@app.post("/case/{transaction_id}/response-emulator/finalize", status_code=status.HTTP_200_OK)
|
||||
async def native_response_emulator_finalize(transaction_id: str, request: Request, body: "EmulatorFinalizeRequest"):
|
||||
async def native_response_emulator_finalize(transaction_id: str, request: Request, body: EmulatorFinalizeRequest):
|
||||
from src.api.schemas.anatel_response_emulator_schemas import ResponseEmulatorRequestEvent
|
||||
if body.transactionId != transaction_id:
|
||||
raise HTTPException(status_code=400, detail="transactionId path/body mismatch")
|
||||
@@ -820,7 +826,3 @@ async def debug_backoffice_parity():
|
||||
},
|
||||
}
|
||||
|
||||
# Late imports only for FastAPI annotation resolution. They are schemas, not
|
||||
# workflow motors.
|
||||
from src.api.schemas.anatel_schemas import TicketRequestEvent
|
||||
from src.api.schemas.anatel_response_emulator_schemas import EmulatorGenerateRequest, EmulatorFinalizeRequest
|
||||
|
||||
@@ -20,6 +20,7 @@ from app.agents.support_agent import SupportAgent
|
||||
from app.agents.backoffice_agent import BackofficeAgent
|
||||
from app.state import AgentState
|
||||
from agent_framework.rag.rag_service import RagService
|
||||
from agent_framework.rag.embedding_provider import create_embedding_provider
|
||||
from agent_framework.cache.cache import create_cache
|
||||
|
||||
|
||||
@@ -85,7 +86,7 @@ class AgentWorkflow:
|
||||
Em ambos os modos, memória/checkpoint/session usam tenant_id:agent_id:session_id.
|
||||
"""
|
||||
|
||||
def __init__(self, llm, memory, telemetry, analytics, settings, observer: AgentObserver | None = None, tool_router=None):
|
||||
def __init__(self, llm, memory, telemetry, analytics, settings, observer: AgentObserver | None = None, tool_router=None, summary_memory=None):
|
||||
self.llm = llm
|
||||
self.memory = memory
|
||||
self.telemetry = telemetry
|
||||
@@ -93,7 +94,7 @@ class AgentWorkflow:
|
||||
self.observer = observer or AgentObserver(analytics=analytics)
|
||||
self.settings = settings
|
||||
self.tool_router = tool_router
|
||||
self.tool_router = tool_router
|
||||
self.summary_memory = summary_memory
|
||||
self.guardrails = GuardrailPipeline(
|
||||
observer=self.observer,
|
||||
enable_parallel=bool(getattr(settings, "ENABLE_PARALLEL_GUARDRAILS", True)),
|
||||
@@ -113,6 +114,7 @@ class AgentWorkflow:
|
||||
self.judge_telemetry = JudgeTelemetry(telemetry)
|
||||
self.langgraph_telemetry = LangGraphDeepTelemetry(telemetry)
|
||||
self.cache = create_cache(settings)
|
||||
self.embedding_provider = create_embedding_provider(settings)
|
||||
self.rag_service = RagService(settings, telemetry=telemetry)
|
||||
self.router = EnterpriseRouter(settings, llm=llm, telemetry=telemetry)
|
||||
agent_kwargs = {"telemetry": telemetry, "tool_router": getattr(self, "tool_router", None), "rag_service": self.rag_service, "cache": self.cache, "settings": settings, "observer": self.observer}
|
||||
|
||||
@@ -382,8 +382,9 @@ class BackofficeNativeRuntime:
|
||||
return state
|
||||
|
||||
@staticmethod
|
||||
def _after_input_guardrails(state: AgentState) -> str:
|
||||
return "blocked" if state.get("error", {}).get("type") == "InputGuardrailBlocked" else "continue"
|
||||
def _after_input_guardrails(state):
|
||||
error = state.get("error") or {}
|
||||
return "blocked" if error.get("type") == "InputGuardrailBlocked" else "continue"
|
||||
|
||||
async def _framework_output_supervisor(self, state: AgentState) -> AgentState:
|
||||
await self._safe_emit_grl(
|
||||
@@ -544,7 +545,8 @@ class BackofficeNativeRuntime:
|
||||
"guardrails_config_path": self.guardrails_config.get("_config_path"),
|
||||
"active_input_rails": [r.get("code") for r in self.guardrails_config.get("input", []) if r.get("enabled", True)],
|
||||
"active_output_rails": [r.get("code") for r in self.guardrails_config.get("output", []) if r.get("enabled", True)],
|
||||
"_oci_producer": getattr(app_state, "oci_producer", None) if app_state is not None else None,
|
||||
# Progress producer is kept in src.compat.framework_services, not in state,
|
||||
# so checkpoints remain JSON-stable and integrity hashes do not change.
|
||||
"_framework_ics_bridge_index": 0,
|
||||
})
|
||||
try:
|
||||
|
||||
Reference in New Issue
Block a user