my-env / server /policy.py
vinaykumarbharwal
feat: Enhance bug triage task with updated ticket data and triage policy
339abf5
Raw
History Blame Contribute Delete
3.32 kB
"""Shared deterministic triage policy used by the API and offline runner."""
from __future__ import annotations
from models import ActionModel
from server.heuristics import (
COMPONENT_TEAM_MAP,
infer_component,
infer_priority,
infer_severity,
needs_more_info,
suggested_info_type,
)
def recommend_action(observation, action_history: list[str] | None = None) -> tuple[ActionModel, str]:
"""Return the next deterministic action for the current ticket."""
ticket = observation.current_ticket
history = set(action_history or [])
if ticket is None:
return (
ActionModel(action_type="next_ticket", next_ticket={}),
"No active ticket is loaded, so moving to the next ticket is safest.",
)
duplicate_id = (ticket.suspected_duplicate_ids or [None])[0]
component = infer_component(ticket, observation.available_components)
severity = infer_severity(ticket, component)
priority = infer_priority(ticket, severity)
if duplicate_id:
if "mark_duplicate" not in history:
return (
ActionModel(
action_type="mark_duplicate",
mark_duplicate={"canonical_ticket_id": str(duplicate_id)},
),
f"Duplicate hints point to {duplicate_id}, so linking it should happen first.",
)
return (
ActionModel(action_type="next_ticket", next_ticket={}),
"This ticket is already linked as a duplicate, so continuing would only waste steps.",
)
if "classify" not in history:
return (
ActionModel(
action_type="classify",
classify={
"severity": severity,
"priority": priority,
"component": component,
},
),
"Classification is still missing, so severity, priority, and component come first.",
)
if "assign" not in history:
default_team = observation.available_teams[0] if observation.available_teams else "backend-api"
team = COMPONENT_TEAM_MAP.get(component, default_team)
return (
ActionModel(action_type="assign", assign={"team": team}),
f"The inferred component maps best to {team}, so routing is the next step.",
)
if severity in {"sev0", "sev1"} and "escalate_incident" not in history:
return (
ActionModel(
action_type="escalate_incident",
escalate_incident={"justification": "High-impact production risk detected"},
),
"This looks like a critical ticket, so escalation should happen before moving on.",
)
if needs_more_info(ticket) and "request_info" not in history:
info_type = suggested_info_type(ticket)
return (
ActionModel(
action_type="request_info",
request_info={"info_type": info_type},
),
"The report is missing enough evidence that requesting more information is justified.",
)
return (
ActionModel(action_type="next_ticket", next_ticket={}),
"The important triage steps for this ticket are already covered, so moving on is reasonable.",
)