144 lines
4.5 KiB
Python
144 lines
4.5 KiB
Python
#!/usr/bin/env python3
|
|
"""Pure execution-target policy for Agent Task worker and review stages."""
|
|
|
|
from __future__ import annotations
|
|
|
|
from dataclasses import dataclass
|
|
from datetime import datetime
|
|
|
|
from zoneinfo import ZoneInfo
|
|
|
|
|
|
KST = ZoneInfo("Asia/Seoul")
|
|
|
|
VALID_STAGES = {"worker", "review"}
|
|
VALID_LANES = {"local", "cloud"}
|
|
|
|
|
|
@dataclass(frozen=True)
|
|
class RouteTarget:
|
|
adapter: str
|
|
target: str
|
|
execution_class: str
|
|
selfcheck_required: bool
|
|
|
|
|
|
@dataclass(frozen=True)
|
|
class PolicyDecision:
|
|
rule_id: str
|
|
policy_priority: int
|
|
reason_codes: tuple[str, ...]
|
|
time_window: str
|
|
candidates: tuple[RouteTarget, ...]
|
|
|
|
|
|
PI_ORNITH = RouteTarget("pi", "iop/ornith:35b", "local_model", True)
|
|
AGY_GEMINI_LOW = RouteTarget(
|
|
"agy", "Gemini 3.6 Flash (Low)", "cloud_model", False
|
|
)
|
|
AGY_GEMINI_MEDIUM = RouteTarget(
|
|
"agy", "Gemini 3.6 Flash (Medium)", "cloud_model", False
|
|
)
|
|
AGY_GEMINI_HIGH = RouteTarget(
|
|
"agy", "Gemini 3.6 Flash (High)", "cloud_model", False
|
|
)
|
|
PI_LAGUNA = RouteTarget("pi", "iop/laguna-s:2.1", "local_model", True)
|
|
CLAUDE_OPUS = RouteTarget("claude", "claude-opus-4-8", "cloud_model", False)
|
|
CODEX_SOL_XHIGH = RouteTarget("codex", "gpt-5.6-sol", "cloud_model", False)
|
|
|
|
|
|
def _validate(stage: str, lane: str, grade: int, evaluated_at: datetime) -> None:
|
|
if stage not in VALID_STAGES:
|
|
raise ValueError(f"unsupported stage: {stage}")
|
|
if lane not in VALID_LANES:
|
|
raise ValueError(f"unsupported lane: {lane}")
|
|
if not 1 <= grade <= 10:
|
|
raise ValueError(f"grade must be in G01..G10: {grade}")
|
|
if evaluated_at.tzinfo is None or evaluated_at.utcoffset() is None:
|
|
raise ValueError("evaluated_at must be timezone-aware")
|
|
|
|
|
|
def _kst_time_window(evaluated_at: datetime) -> str:
|
|
kst_time = evaluated_at.astimezone(KST).time()
|
|
if 7 <= kst_time.hour < 23:
|
|
return "kst-day-[07:00,23:00)"
|
|
return "kst-night-[23:00,07:00)"
|
|
|
|
|
|
def select_policy(
|
|
*, stage: str, lane: str, grade: int, evaluated_at: datetime
|
|
) -> PolicyDecision:
|
|
"""Return the ordered target policy for one initial route evaluation."""
|
|
|
|
_validate(stage, lane, grade, evaluated_at)
|
|
|
|
if stage == "review":
|
|
return PolicyDecision(
|
|
rule_id="official-review-codex",
|
|
policy_priority=10,
|
|
reason_codes=("official_review_fixed",),
|
|
time_window="not_applicable",
|
|
candidates=(CODEX_SOL_XHIGH,),
|
|
)
|
|
|
|
if lane == "local":
|
|
if grade <= 6:
|
|
return PolicyDecision(
|
|
rule_id="worker-local-g01-g06",
|
|
policy_priority=30,
|
|
reason_codes=("local_low_grade",),
|
|
time_window="not_applicable",
|
|
candidates=(PI_ORNITH,),
|
|
)
|
|
if grade <= 8:
|
|
time_window = _kst_time_window(evaluated_at)
|
|
if time_window == "kst-day-[07:00,23:00)":
|
|
rule_id = "worker-local-g07-g08-kst-day"
|
|
reason_code = "kst_day_gemini_medium"
|
|
candidates = (AGY_GEMINI_MEDIUM, PI_LAGUNA)
|
|
else:
|
|
rule_id = "worker-local-g07-g08-kst-night"
|
|
reason_code = "kst_night_laguna"
|
|
candidates = (PI_LAGUNA, AGY_GEMINI_MEDIUM)
|
|
return PolicyDecision(
|
|
rule_id=rule_id,
|
|
policy_priority=20,
|
|
reason_codes=(reason_code,),
|
|
time_window=time_window,
|
|
candidates=candidates,
|
|
)
|
|
return PolicyDecision(
|
|
rule_id="worker-local-g09-g10",
|
|
policy_priority=30,
|
|
reason_codes=("local_high_grade_cloud_target",),
|
|
time_window="not_applicable",
|
|
candidates=(CLAUDE_OPUS,),
|
|
)
|
|
|
|
if grade <= 2:
|
|
target = AGY_GEMINI_LOW
|
|
rule_id = "worker-cloud-g01-g02"
|
|
reason_code = "cloud_gemini_low_grade"
|
|
elif grade <= 4:
|
|
target = AGY_GEMINI_MEDIUM
|
|
rule_id = "worker-cloud-g03-g04"
|
|
reason_code = "cloud_gemini_medium_grade"
|
|
elif grade <= 6:
|
|
target = AGY_GEMINI_HIGH
|
|
rule_id = "worker-cloud-g05-g06"
|
|
reason_code = "cloud_gemini_high_grade"
|
|
elif grade <= 8:
|
|
target = CLAUDE_OPUS
|
|
rule_id = "worker-cloud-g07-g08"
|
|
reason_code = "cloud_opus_grade"
|
|
else:
|
|
target = CODEX_SOL_XHIGH
|
|
rule_id = "worker-cloud-g09-g10"
|
|
reason_code = "cloud_codex_grade"
|
|
return PolicyDecision(
|
|
rule_id=rule_id,
|
|
policy_priority=30,
|
|
reason_codes=(reason_code,),
|
|
time_window="not_applicable",
|
|
candidates=(target,),
|
|
)
|