This commit is contained in:
2026-06-13 15:40:44 -03:00
parent 0714b503d1
commit 1f1188dd4e
181 changed files with 1345 additions and 849 deletions

View File

@@ -32,7 +32,9 @@ from agent_framework.cache.cache import create_cache
from agent_framework.billing.usage_repository import create_usage_repository
from agent_framework.sse.events import SSEHub
from app.workflows.agent_graph import AgentWorkflow
from app.workflows.backoffice_native_runtime import BackofficeNativeRuntime
from app.workflows.backoffice_workflow_executor import BackofficeWorkflowExecutor
from app.channels.backoffice_rest_adapter import BackofficeRestChannelAdapter
from app.workflows.backoffice_workflow_dispatcher import BackofficeWorkflowDispatcher
from app.identity_extraction import enrich_payload_with_text_identity, extract_identity_from_text
logging.basicConfig(level=settings.LOG_LEVEL)
@@ -69,7 +71,9 @@ 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, summary_memory=summary_memory)
backoffice_runtime = BackofficeNativeRuntime(settings=settings, telemetry=telemetry, analytics=analytics, observer=observer)
backoffice_executor = BackofficeWorkflowExecutor(settings=settings, telemetry=telemetry, analytics=analytics, observer=observer)
backoffice_rest_adapter = BackofficeRestChannelAdapter()
backoffice_dispatcher = BackofficeWorkflowDispatcher(channel_gateway=gateway, executor=backoffice_executor, telemetry=telemetry, adapter=backoffice_rest_adapter)
logger.info("LLM provider carregado: %s", llm.__class__.__name__)
logger.info("Langfuse habilitado: %s host=%s", telemetry.is_enabled(), settings.LANGFUSE_HOST)
@@ -498,12 +502,12 @@ async def shutdown():
# ---------------------------------------------------------------------------
# Backoffice TIM/ANATEL develop — execução 100% framework-native
# Backoffice TIM/ANATEL develop — REST como canal do framework
# ---------------------------------------------------------------------------
# As rotas antigas permanecem como adapters REST, mas não registram routers
# legados e não executam legacy graph package nem legacy executor package.
# Elas chamam o BackofficeNativeRuntime, que compila os workflows com o motor
# do framework e aplica guardrails, judges, supervisor, checkpoint e telemetry.
# As rotas antigas permanecem como contratos HTTP de compatibilidade, mas agora
# atuam apenas como REST adapters. Elas traduzem o payload legado para um
# BackofficeChannelEnvelope, passam pelo ChannelGateway e só então o dispatcher
# aciona o workflow LangGraph registrado para o domínio.
from src.api.schemas.anatel_schemas import TicketRequestEvent
from src.api.schemas.anatel_response_emulator_schemas import EmulatorGenerateRequest, EmulatorFinalizeRequest
@@ -599,29 +603,23 @@ async def native_validation_exception_handler(request: Request, exc: RequestVali
return JSONResponse(status_code=422, content={"detail": exc.errors()})
async def _run_native_checklist(event, request: Request):
async def _run_native_checklist(event, request: Request, *, legacy_contract: str = "agent.process-ticket"):
from src.api.utils import agent_helpers
transaction_id = event.transactionId or f"man-{uuid4().hex[:8]}"
payload = event.model_dump(mode="json", by_alias=True)
final_state = await backoffice_runtime.execute_workflow(
"backoffice_checklist",
payload=payload,
transaction_id=transaction_id,
app_state=request.app.state,
metadata={
"tenant_id": "default",
"agent_id": "backoffice_anatel",
"channel": "rest",
"legacy_contract": "agent.process-ticket",
},
)
envelope = backoffice_rest_adapter.from_ticket_event(event, legacy_contract=legacy_contract)
final_state = await backoffice_dispatcher.execute(envelope, app_state=request.app.state)
try:
response_event = agent_helpers.build_cms_response_event(final_state, transaction_id)
return response_event.model_dump(mode="json", by_alias=True)
response_event = agent_helpers.build_cms_response_event(final_state, envelope.transaction_id)
response = response_event.model_dump(mode="json", by_alias=True)
response.setdefault("metadata", {})
response["metadata"]["framework_entrypoint"] = "channel_gateway"
response["metadata"]["source_channel"] = envelope.channel
return response
except Exception:
return {
"transactionId": transaction_id,
"transactionId": envelope.transaction_id,
"framework_native": True,
"framework_entrypoint": "channel_gateway",
"source_channel": envelope.channel,
"current_step": str(final_state.get("current_step")),
"final_response": final_state.get("final_response"),
"error": final_state.get("error"),
@@ -631,17 +629,17 @@ 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):
return await _run_native_checklist(event, request)
return await _run_native_checklist(event, request, legacy_contract="agent.process-ticket")
@app.post("/agent/execute", status_code=status.HTTP_200_OK)
async def native_agent_execute(request: Request, event: TicketRequestEvent):
return await _run_native_checklist(event, request)
return await _run_native_checklist(event, request, legacy_contract="agent.execute")
@app.post("/agent/process-and-stream", status_code=status.HTTP_200_OK)
async def native_process_and_stream(request: Request, event: TicketRequestEvent):
return await _run_native_checklist(event, request)
return await _run_native_checklist(event, request, legacy_contract="agent.process-and-stream")
@app.post("/agent/search-tais-kb", status_code=status.HTTP_200_OK)
@@ -660,31 +658,23 @@ async def native_search_tais_kb(body: dict):
return {"framework_native": True, "result": result}
async def _run_native_emulator(request: Request, event):
transaction_id = event.transactionId
payload = event.model_dump(mode="json", by_alias=True)
final_state = await backoffice_runtime.execute_workflow(
"backoffice_response_emulator",
payload=payload,
transaction_id=transaction_id,
app_state=request.app.state,
metadata={
"tenant_id": "default",
"agent_id": "backoffice_anatel",
"channel": "rest",
"flow_mode": event.flow_mode,
"selected_actions": [a.model_dump(mode="json") for a in event.selected_actions],
"legacy_contract": "case.response-emulator",
},
)
async def _run_native_emulator(request: Request, event, *, legacy_contract: str = "case.response-emulator"):
envelope = backoffice_rest_adapter.from_emulator_event(event, legacy_contract=legacy_contract)
final_state = await backoffice_dispatcher.execute(envelope, app_state=request.app.state)
try:
from src.api.utils.emulator_response_builder import build_emulator_response_event
response_event = build_emulator_response_event(final_state, transaction_id)
return response_event.model_dump(mode="json", by_alias=True)
response_event = build_emulator_response_event(final_state, envelope.transaction_id)
response = response_event.model_dump(mode="json", by_alias=True)
response.setdefault("metadata", {})
response["metadata"]["framework_entrypoint"] = "channel_gateway"
response["metadata"]["source_channel"] = envelope.channel
return response
except Exception:
return {
"transactionId": transaction_id,
"transactionId": envelope.transaction_id,
"framework_native": True,
"framework_entrypoint": "channel_gateway",
"source_channel": envelope.channel,
"current_step": str(final_state.get("current_step")),
"final_response": final_state.get("final_response"),
"error": final_state.get("error"),
@@ -782,6 +772,8 @@ async def native_health_ready():
"workflows": list(backoffice_runtime._graphs.keys()),
"framework_layers": {
"gateway": True,
"channel_gateway_entrypoint": True,
"backoffice_rest_adapter": True,
"identity": True,
"session_repository": settings.SESSION_REPOSITORY_PROVIDER,
"memory_repository": settings.MEMORY_REPOSITORY_PROVIDER,
@@ -802,7 +794,9 @@ async def debug_backoffice_parity():
"legacy_graph_execution": False,
"legacy_router_registration": False,
"forbidden_active_imports": ["legacy_reference_disabled/original_develop/src_agent_graphs", "legacy_reference_disabled/original_develop/src_api_executors"],
"runtime": "app.workflows.backoffice_native_runtime.BackofficeNativeRuntime",
"entrypoint": "app.channels.backoffice_rest_adapter.BackofficeRestChannelAdapter",
"dispatcher": "app.workflows.backoffice_workflow_dispatcher.BackofficeWorkflowDispatcher",
"runtime": "app.workflows.backoffice_workflow_executor.BackofficeWorkflowExecutor",
"domain_package": "src.agent.nodes + src.components.clients + src.agent.local_prompts",
"workflows": {
"backoffice_checklist": [
@@ -814,6 +808,8 @@ async def debug_backoffice_parity():
},
"framework_layers": {
"gateway": True,
"channel_gateway_entrypoint": True,
"backoffice_rest_adapter": True,
"identity": True,
"session_repository": settings.SESSION_REPOSITORY_PROVIDER,
"memory_repository": settings.MEMORY_REPOSITORY_PROVIDER,