Merge branch 'review/pr-361'

This commit is contained in:
ajaysi
2026-03-02 11:34:04 +05:30
3 changed files with 56 additions and 8 deletions

View File

@@ -1,6 +1,7 @@
from fastapi import APIRouter, Depends, HTTPException from fastapi import APIRouter, Depends, HTTPException
from typing import Any, Dict, Optional from typing import Any, Dict, Optional
from datetime import datetime from datetime import datetime
from loguru import logger
from sqlalchemy.orm import Session from sqlalchemy.orm import Session
@@ -182,7 +183,13 @@ async def set_task_status(
feedback_text=completion_notes feedback_text=completion_notes
) )
except Exception as e: except Exception as e:
pass # Don't block response on memory update failure logger.warning(
"Task memory outcome recording failed for user_id={} task_id={} error_class={} error_message={}",
user_id,
task_id,
type(e).__name__,
str(e),
)
plan_for_date = db.query(DailyWorkflowPlan).filter(DailyWorkflowPlan.id == task.plan_id).first() plan_for_date = db.query(DailyWorkflowPlan).filter(DailyWorkflowPlan.id == task.plan_id).first()
plan_date = plan_for_date.date if plan_for_date and plan_for_date.date else "" plan_date = plan_for_date.date if plan_for_date and plan_for_date.date else ""

View File

@@ -368,9 +368,15 @@ class RealTimeSemanticMonitor:
# Using StrategyArchitect for pillar/gap analysis # Using StrategyArchitect for pillar/gap analysis
if hasattr(self.strategy_agent, 'find_semantic_gaps'): if hasattr(self.strategy_agent, 'find_semantic_gaps'):
# This method requires competitor indices, which is complex to get here without full context. logger.warning(
# Let's use the SIF service directly for lighter weight insights or call the agent's high level method. "Skipping direct semantic gap method invocation for user_id={} due to missing competitor index context",
pass self.user_id,
)
else:
logger.warning(
"Strategy agent missing find_semantic_gaps for user_id={}, using dashboard-context fallback",
self.user_id,
)
# Alternative: Query SIF directly for "content gaps" if they are indexed as such # Alternative: Query SIF directly for "content gaps" if they are indexed as such
# Or generate them now via LLM + SIF Context # Or generate them now via LLM + SIF Context
@@ -422,6 +428,17 @@ class RealTimeSemanticMonitor:
source_agent="Strategy Architect Agent" source_agent="Strategy Architect Agent"
)) ))
if not ai_insights:
logger.warning(
"Dashboard context returned no ai_insights for user_id={}, insight generation is degraded",
self.user_id,
)
else:
logger.warning(
"SEO dashboard context unavailable for user_id={}, using fallback insight only",
self.user_id,
)
except Exception as agent_err: except Exception as agent_err:
logger.warning(f"Agent insight generation failed: {agent_err}") logger.warning(f"Agent insight generation failed: {agent_err}")
@@ -514,8 +531,13 @@ class RealTimeSemanticMonitor:
dedupe_key=dedupe_key, dedupe_key=dedupe_key,
) )
db.close() db.close()
except Exception: except Exception as alert_err:
pass logger.warning(
"Unable to persist semantic alerts for user_id={} error_class={} error_message={}",
self.user_id,
type(alert_err).__name__,
str(alert_err),
)
await self._send_alerts(alerts) await self._send_alerts(alerts)
async def get_cache_stats(self) -> Dict[str, Any]: async def get_cache_stats(self) -> Dict[str, Any]:

View File

@@ -30,6 +30,17 @@ class TaskMemoryService:
self.user_id = user_id self.user_id = user_id
self.db = db self.db = db
self.intelligence = TxtaiIntelligenceService(user_id) self.intelligence = TxtaiIntelligenceService(user_id)
self._metrics_counters: Dict[str, int] = {}
def _increment_metric(self, metric_name: str, increment: int = 1) -> None:
"""Increment lightweight in-memory counters for observability hooks."""
self._metrics_counters[metric_name] = self._metrics_counters.get(metric_name, 0) + increment
logger.debug(
"TaskMemory metric updated user_id={} metric={} value={}",
self.user_id,
metric_name,
self._metrics_counters[metric_name],
)
def _compute_hash(self, title: str, description: str) -> str: def _compute_hash(self, title: str, description: str) -> str:
"""Compute a consistent hash for task deduplication.""" """Compute a consistent hash for task deduplication."""
@@ -154,8 +165,16 @@ class TaskMemoryService:
f"Filtering redundant task (semantic {top_score:.2f}, history status={history_status}): {p.title}" f"Filtering redundant task (semantic {top_score:.2f}, history status={history_status}): {p.title}"
) )
is_semantic_duplicate = True is_semantic_duplicate = True
except Exception: except Exception as semantic_err:
pass self._increment_metric("semantic_filter_failures")
self._increment_metric("semantic_filter_degraded_path_taken")
logger.warning(
"Semantic filter degraded for user_id={} proposal_title={} error_class={} error_message={}",
self.user_id,
getattr(p, "title", ""),
type(semantic_err).__name__,
str(semantic_err),
)
if not is_semantic_duplicate: if not is_semantic_duplicate:
filtered.append(p) filtered.append(p)