Standardize agent event payloads and team activity timeline UI

This commit is contained in:
ي
2026-03-02 22:01:12 +05:30
parent cb6a3a8042
commit a7bf355703
5 changed files with 258 additions and 194 deletions

View File

@@ -31,7 +31,7 @@ from utils.logger_utils import get_service_logger
from services.database import get_session_for_user
from services.intelligence.monitoring.semantic_dashboard import RealTimeSemanticMonitor
from services.intelligence.agents.safety_framework import get_safety_framework
from services.agent_activity_service import AgentActivityService
from services.agent_activity_service import AgentActivityService, build_agent_event_payload
from services.intelligence.agents.agent_usage_tracking import track_agent_usage_sync
import time
@@ -426,7 +426,7 @@ class BaseALwrityAgent(ABC):
event_type="plan",
severity="info",
message=(prompt[:2000] if prompt else None),
payload={"kind": "prompt"},
payload=build_agent_event_payload(phase="planning", step="run_started", tool_name="agent_run", progress_percent=0, input_summary=prompt[:250], output_summary="Agent run initialized", decision_reason="Received run prompt", safe_debug=False, metadata={"kind": "prompt"}),
run_id=run_record.id,
agent_type=self.agent_type,
)
@@ -453,7 +453,7 @@ class BaseALwrityAgent(ABC):
event_type="final_summary",
severity="info",
message=(str(result)[:2000] if result is not None else None),
payload={"kind": "result"},
payload=build_agent_event_payload(phase="execution", step="run_completed", tool_name="agent_run", progress_percent=100, output_summary=str(result)[:400] if result is not None else "No output", decision_reason="Run completed", safe_debug=True, metadata={"kind": "result"}),
run_id=run_record.id,
agent_type=self.agent_type,
)
@@ -467,7 +467,7 @@ class BaseALwrityAgent(ABC):
event_type="error",
severity="error",
message=str(e)[:2000],
payload={"kind": "exception"},
payload=build_agent_event_payload(phase="execution", step="run_error", tool_name="agent_runtime", output_summary=str(e)[:400], decision_reason="Unhandled exception during run", safe_debug=False, metadata={"kind": "exception"}),
run_id=run_record.id,
agent_type=self.agent_type,
)
@@ -513,7 +513,7 @@ class BaseALwrityAgent(ABC):
event_type="plan",
severity="info",
message=f"{action.action_type} -> {action.target_resource}",
payload={"action": asdict(action)},
payload=build_agent_event_payload(phase="planning", step="action_received", tool_name=action.action_type, progress_percent=5, input_summary=f"target={action.target_resource}", output_summary="Action accepted for execution", decision_reason="Start run lifecycle", safe_debug=True, metadata={"action": asdict(action)}),
run_id=run_record.id,
agent_type=self.agent_type,
)
@@ -528,7 +528,7 @@ class BaseALwrityAgent(ABC):
event_type="decision",
severity="warning",
message="Action failed safety validation",
payload={"action_id": action.action_id, "action_type": action.action_type},
payload=build_agent_event_payload(phase="validation", step="safety_blocked", tool_name="safety_framework", progress_percent=10, input_summary=action.action_type, output_summary="Action blocked by safety validation", decision_reason="Safety framework rejected action", safe_debug=True, metadata={"action_id": action.action_id, "action_type": action.action_type}),
run_id=run_record.id,
agent_type=self.agent_type,
)
@@ -568,7 +568,7 @@ class BaseALwrityAgent(ABC):
event_type="decision",
severity="info",
message="Action requires approval",
payload={"approval_id": req.id, "action_id": action.action_id},
payload=build_agent_event_payload(phase="approval", step="awaiting_user_decision", tool_name=action.action_type, progress_percent=20, input_summary=action.target_resource, output_summary="Approval request created", decision_reason="Action requires human approval", safe_debug=True, metadata={"approval_id": req.id, "action_id": action.action_id}),
run_id=run_record.id,
agent_type=self.agent_type,
)
@@ -593,7 +593,7 @@ class BaseALwrityAgent(ABC):
event_type="progress",
severity="info",
message="Rollback checkpoint created",
payload={"checkpoint_id": checkpoint_id},
payload=build_agent_event_payload(phase="safety", step="checkpoint_created", tool_name="rollback_manager", progress_percent=35, output_summary="Rollback checkpoint created", decision_reason="Prepare rollback safety net", safe_debug=True, metadata={"checkpoint_id": checkpoint_id}),
run_id=run_record.id,
agent_type=self.agent_type,
)
@@ -604,7 +604,7 @@ class BaseALwrityAgent(ABC):
event_type="warning",
severity="warning",
message=str(e)[:2000],
payload={"checkpoint": "failed"},
payload=build_agent_event_payload(phase="safety", step="checkpoint_failed", tool_name="rollback_manager", progress_percent=30, output_summary="Checkpoint creation failed", decision_reason="Proceeding without checkpoint", safe_debug=False, metadata={"checkpoint": "failed"}),
run_id=run_record.id,
agent_type=self.agent_type,
)
@@ -639,7 +639,7 @@ class BaseALwrityAgent(ABC):
event_type="final_summary",
severity="info",
message=str(result)[:2000] if result is not None else None,
payload={"action_id": action.action_id},
payload=build_agent_event_payload(phase="execution", step="completed", tool_name=action.action_type, progress_percent=100, output_summary=str(result)[:400] if result is not None else "No output", decision_reason="Action execution completed", safe_debug=True, metadata={"action_id": action.action_id}),
run_id=run_record.id,
agent_type=self.agent_type,
)
@@ -690,7 +690,7 @@ class BaseALwrityAgent(ABC):
event_type="error",
severity="error",
message=str(e)[:2000],
payload={"action_id": action.action_id, "checkpoint_id": checkpoint_id},
payload=build_agent_event_payload(phase="execution", step="failed", tool_name=action.action_type, progress_percent=100, output_summary=str(e)[:400], decision_reason="Exception during action execution", safe_debug=False, metadata={"action_id": action.action_id, "checkpoint_id": checkpoint_id}),
run_id=run_record.id,
agent_type=self.agent_type,
)

View File

@@ -14,6 +14,7 @@ from datetime import datetime
from loguru import logger
from ..txtai_service import TxtaiIntelligenceService
from services.intelligence.agents.core_agent_framework import BaseALwrityAgent, AgentAction, TaskProposal
from services.agent_activity_service import AgentActivityService, build_agent_event_payload
from services.seo_tools.content_strategy_service import ContentStrategyService
from services.analytics import PlatformAnalyticsService
from services.intelligence.sif_agents import SharedLLMWrapper, LocalLLMWrapper
@@ -62,6 +63,41 @@ class SIFBaseAgent(BaseALwrityAgent):
if kwargs:
logger.debug(f"[{self.__class__.__name__}] Parameters: {kwargs}")
db = None
try:
from services.database import get_session_for_user
db = get_session_for_user(self.user_id)
if not db:
return
activity = AgentActivityService(db, self.user_id)
activity.log_event(
event_type="progress",
severity="info",
message=f"{self.__class__.__name__}: {operation}",
payload=build_agent_event_payload(
phase="specialized_agent",
step=operation.lower().replace(" ", "_"),
tool_name=self.__class__.__name__,
input_summary=str(kwargs)[:300] if kwargs else None,
output_summary="Operation invoked",
decision_reason="Agent method execution trace",
safe_debug=True,
metadata={"params": kwargs} if kwargs else {},
),
run_id=None,
agent_type=self.agent_type,
)
except Exception:
pass
finally:
try:
if db:
db.close()
except Exception:
pass
def _create_txtai_agent(self):
"""
SIF agents use the intelligence service directly, but we can expose