Spaces:
Sleeping
Sleeping
| """ | |
| app/core/priority.py | |
| --------------------- | |
| Shared priority scoring utilities for NotiFlow Autonomous. | |
| Replaces the single-agent string assignment pattern with an | |
| additive scoring model. Any agent can contribute points. | |
| UrgencyAgent is the sole agent that derives the final label. | |
| Score scale: 0 β 100 (int, clamped) | |
| > 70 β "high" | |
| > 40 β "medium" | |
| β€ 40 β "low" | |
| Public API | |
| ---------- | |
| contribute_priority_score(ctx, points, reason) -> None | |
| Add points to context["priority_score"] and log the reason. | |
| derive_priority_label(ctx) -> str | |
| Read context["priority_score"] and return the label string. | |
| Also writes context["priority"] = label and returns it. | |
| reset_priority_score(ctx) -> None | |
| Zero the score (used at replan boundaries). | |
| """ | |
| from __future__ import annotations | |
| import logging | |
| from typing import Any | |
| logger = logging.getLogger(__name__) | |
| _SCORE_KEY = "priority_score" | |
| _REASONS_KEY = "priority_score_reasons" | |
| # Thresholds | |
| _HIGH_THRESHOLD = 70 | |
| _MEDIUM_THRESHOLD = 40 | |
| def contribute_priority_score( | |
| ctx: dict[str, Any], | |
| points: int, | |
| reason: str, | |
| ) -> None: | |
| """ | |
| Add points (0β100 scale) to the running priority score. | |
| Points are clamped so the total never exceeds 100. | |
| The reason is appended to context["priority_score_reasons"] for audit. | |
| Args: | |
| ctx: The live request context dict. | |
| points: Integer contribution (positive only). | |
| reason: Human-readable explanation of why this score was added. | |
| """ | |
| if points <= 0: | |
| return | |
| current = ctx.get(_SCORE_KEY, 0) | |
| new_val = min(100, current + points) | |
| ctx[_SCORE_KEY] = new_val | |
| ctx.setdefault(_REASONS_KEY, []).append( | |
| {"points": points, "reason": reason, "total_after": new_val} | |
| ) | |
| logger.debug( | |
| "[Priority] +%d (%s) β total=%d", points, reason, new_val | |
| ) | |
| def derive_priority_label(ctx: dict[str, Any]) -> str: | |
| """ | |
| Derive the final priority label from the accumulated score. | |
| Writes context["priority"] = label and returns the label. | |
| Args: | |
| ctx: The live request context dict. | |
| Returns: | |
| "high" | "medium" | "low" | |
| """ | |
| score = ctx.get(_SCORE_KEY, 0) | |
| if score > _HIGH_THRESHOLD: | |
| label = "high" | |
| elif score > _MEDIUM_THRESHOLD: | |
| label = "medium" | |
| else: | |
| label = "low" | |
| ctx["priority"] = label | |
| logger.info( | |
| "[Priority] score=%d β label=%s", score, label | |
| ) | |
| return label | |
| def reset_priority_score(ctx: dict[str, Any]) -> None: | |
| """ | |
| Reset the priority score to 0 (used at replan boundaries). | |
| Args: | |
| ctx: The live request context dict. | |
| """ | |
| ctx[_SCORE_KEY] = 0 | |
| ctx[_REASONS_KEY] = [] |