diff --git a/ai-hub/app/core/orchestration/agent_loop.py b/ai-hub/app/core/orchestration/agent_loop.py
index 065128f..ef920a6 100644
--- a/ai-hub/app/core/orchestration/agent_loop.py
+++ b/ai-hub/app/core/orchestration/agent_loop.py
@@ -121,7 +121,10 @@
instance.total_output_tokens = (instance.total_output_tokens or 0) + final_output_tokens
if final_tool_counts:
- current_counts = dict(instance.tool_call_counts or {})
+ # Deep copy the current counts to ensure SQLAlchemy detects change
+ import copy
+ current_counts = copy.deepcopy(instance.tool_call_counts or {})
+
for k, v in final_tool_counts.items():
# Upgrade legacy single-integer counts into rich metric dicts
if k in current_counts and isinstance(current_counts[k], int):
@@ -136,7 +139,11 @@
current_counts[k]["failures"] += v.get("failures", 0)
instance.tool_call_counts = current_counts
+ # Explicitly mark as modified for JSON column persistence
+ from sqlalchemy.orm.attributes import flag_modified
+ flag_modified(instance, "tool_call_counts")
+ print(f"[AgentExecutor] Saved metrics for {agent_id}. Tool calls: {final_tool_counts}")
db.commit()
return final_answer
diff --git a/frontend/src/features/agents/components/AgentDrillDown.js b/frontend/src/features/agents/components/AgentDrillDown.js
index 5ff4c77..496a483 100644
--- a/frontend/src/features/agents/components/AgentDrillDown.js
+++ b/frontend/src/features/agents/components/AgentDrillDown.js
@@ -131,7 +131,7 @@
useEffect(() => {
fetchData();
- const interval = setInterval(fetchData, 3000);
+ const interval = setInterval(fetchData, 1500); // 1.5s for more active feel
return () => clearInterval(interval);
}, [agentId]);
@@ -362,7 +362,9 @@