refactor(agent/tool_guardrails,subscription_view): flatten no-progress block check and payload mapping

This commit is contained in:
Teknium
2026-09-02 19:36:47 -07:00
parent 273c96f789
commit 874d8487cd
2 changed files with 9 additions and 21 deletions

View File

@@ -148,14 +148,10 @@ def subscription_change_preview_from_payload(payload: dict[str, Any]) -> Subscri
)
def subscription_state_from_payload(
payload: dict[str, Any], *, portal_url: Optional[str] = None
) -> SubscriptionState:
def subscription_state_from_payload(payload: dict[str, Any], *, portal_url: Optional[str] = None) -> SubscriptionState:
"""Map a raw ``/api/billing/subscription`` JSON dict into :class:`SubscriptionState`."""
org, can_change_plan_raw = parse_org_fields(payload)
raw_context = payload.get("context")
raw_tiers = payload.get("tiers")
tiers = tuple(filter(None, map(_parse_tier, raw_tiers))) if isinstance(raw_tiers, list) else ()
raw_context, raw_tiers = payload.get("context"), payload.get("tiers")
return SubscriptionState(
logged_in=True,
org_name=org.get("name"),
@@ -164,7 +160,7 @@ def subscription_state_from_payload(
can_change_plan_raw=can_change_plan_raw,
context=raw_context if raw_context in ("personal", "team") else "personal",
current=_parse_current(payload.get("current")),
tiers=tiers,
tiers=tuple(filter(None, map(_parse_tier, raw_tiers))) if isinstance(raw_tiers, list) else (),
portal_url=portal_url,
)
@@ -179,13 +175,10 @@ def build_subscription_state(*, timeout: float = 15.0) -> SubscriptionState:
if fixture is not None:
return fixture
return fetch_portal_state(
"get_subscription_state",
"subscription",
"get_subscription_state", "subscription",
failed=lambda **kw: SubscriptionState(logged_in=False, **kw),
parse=lambda payload, portal_url: subscription_state_from_payload(payload, portal_url=portal_url),
portal_fallback=lambda base: base,
timeout=timeout,
log=logger,
portal_fallback=lambda base: base, timeout=timeout, log=logger,
)

View File

@@ -302,9 +302,7 @@ class ToolCallGuardrailController:
"""Build a warn/block/halt decision; block/halt is also recorded as the turn's halt decision."""
if message is None:
message = _DECISION_MESSAGES[code].format(tool_name=tool_name, count=count, **fmt)
decision = ToolGuardrailDecision(
action=action, code=code, message=message, tool_name=tool_name, count=count, signature=signature,
)
decision = ToolGuardrailDecision(action, code, message, tool_name, count, signature)
if decision.should_halt:
self._halt_decision = decision
return decision
@@ -326,12 +324,9 @@ class ToolCallGuardrailController:
exact_count = 0 if self._progress_since_failure.get(signature) else self._exact_failure_counts.get(signature, 0)
if exact_count >= self.config.exact_failure_block_after:
return self._decide("block", "repeated_exact_failure_block", tool_name, exact_count, signature)
if self._is_idempotent(tool_name):
record = self._no_progress.get(signature)
if record is not None and record[1] >= self.config.no_progress_block_after:
return self._decide("block", "idempotent_no_progress_block", tool_name, record[1], signature)
repeat_count = self._no_progress.get(signature, ("", 0))[1] if self._is_idempotent(tool_name) else 0
if repeat_count >= self.config.no_progress_block_after:
return self._decide("block", "idempotent_no_progress_block", tool_name, repeat_count, signature)
return allow
def after_call(