feat(llm): approval-gated movement executor + rag-api agent wiring + agent UI

- decide_approval now executes the underlying data movement when an approved
  request carries an executor=movement payload (real human-gated executor).
- rag-api service gets OPENMETADATA_* (via atc.env) + COMMAND_CENTER_URL so it can
  sync the catalog and call platform tools.
- Knowledge Chat gains an Agent-mode toggle (SSE tool-loop with step chips) and a
  'Sync catalog' button.
This commit is contained in:
mo
2026-06-27 03:28:18 +02:00
parent 8263a03190
commit 9fb5b0a780
3 changed files with 152 additions and 5 deletions
+11
View File
@@ -45,6 +45,7 @@ from sql_console import router as sql_router
from agent_ops import router as agent_ops_router, agent_dml_loop, etl_agent_loop
from cdc_consumer import router as cdc_router, cdc_consumer_loop
from movements import router as movements_router
from movements import MOVEMENT_BY_ID, trigger_and_watch
from dataflow import router as dataflow_router
from pii_catalog import router as pii_router
from ssh_terminal import ssh_session
@@ -1084,6 +1085,16 @@ async def decide_approval(approval_id: str, body: ApprovalDecision):
)
if not item:
return {"error": "not found"}
# Approval-gated executor: run the underlying action once a supervisor approves it.
if item.get("status") == "approved":
payload = item.get("payload") or {}
if isinstance(payload, dict) and payload.get("executor") == "movement":
mid = payload.get("movement_id")
if mid in MOVEMENT_BY_ID:
add_feed("etl-guardian", f"Approval {approval_id} granted — executing movement '{mid}'", "info")
asyncio.create_task(trigger_and_watch(mid, payload.get("conf")))
return {"ok": True, "approval": item}