Skip to content

feat(agent): clear missing-package error, opt-in strict, on_error hook (O1/O2 engine half)#25

Merged
rennf93 merged 2 commits into
masterfrom
feat/agent-error-clarity
Jun 23, 2026
Merged

feat(agent): clear missing-package error, opt-in strict, on_error hook (O1/O2 engine half)#25
rennf93 merged 2 commits into
masterfrom
feat/agent-error-clarity

Conversation

@rennf93

@rennf93 rennf93 commented Jun 23, 2026

Copy link
Copy Markdown
Owner

Engine foundation for the agent-error-clarity design-partner feedback (O1 + O2). The fastapi-guard adapter half and the guard-agent transport half build on this.

What

A design partner couldn't tell when agent telemetry failed: a missing guard-agent package produced a silent warning and a misleading "check agent_api_key" error, and other failures (GeoIP) were swallowed silently.

  • Clear missing-package signal (O1). to_agent_config() now raises AgentPackageNotInstalledError (naming the package + install command) instead of returning an ambiguous None. A missing guard-agent can no longer masquerade as "configuration is invalid / check agent_api_key" in adapters.
  • Opt-in strict (O1/O2). SecurityConfig.agent_strict (default False) — adapters raise at init instead of degrading to agent-off when True. Fail-soft stays the default for availability-sensitive deployments.
  • Single on_error hook (O2). SecurityConfig.on_error (default None) is one best-effort on_error(stage, exc, context) callback (stageagent_init/geoip/transport_send/encryption). utils.invoke_error_hook invokes it and never lets a raising hook propagate into the request path.
  • Stop the silent GeoIP drop (O2). SecurityEventBus._lookup_country now logs at warning and fires on_error(stage="geoip") instead of a bare except Exception: return None.

Decisions (confirmed with maintainer)

Fail-soft default + opt-in strict · fix in guard-core engine (all adapters benefit) · single on_error(stage, exc, context) hook · (fastapi-guard[agent] extra lands in the adapter PR).

Verification

  • New tests/test_agent_error_clarity.py (+ updated to_agent_config import-error test); generated sync mirror runs the same suite (parity).
  • Full async suite 1838 passed, full sync suite green, all pre-commit gates incl. check-sync green.

Follow-ups (same feature, separate repos)

  • guard-agent: AgentConfig.on_error + fire at transport send/flush + encryption-abort swallow points.
  • fastapi-guard: [agent] extra + middleware restructure (catch AgentPackageNotInstalledError → one clear error; honor agent_strict; fire on_error; surface agent-degraded state via get_stats/health_check).

Version bump deferred until the three repos land together.

…k (O1/O2 engine)

Engine foundation for the agent-error-clarity work (fastapi-guard + guard-agent halves to follow).

- to_agent_config() raises AgentPackageNotInstalledError (naming the package and
  install command) instead of returning an ambiguous None, so a missing guard-agent
  can no longer masquerade as an 'invalid config / check agent_api_key' error in
  adapters.
- SecurityConfig.agent_strict (default False): adapters raise at init instead of
  degrading to agent-off when True.
- SecurityConfig.on_error (default None): one best-effort on_error(stage, exc,
  context) hook; utils.invoke_error_hook invokes it and never lets a raising hook
  propagate into the request path.
- Stop the silent GeoIP drop: SecurityEventBus._lookup_country now logs at warning
  and fires on_error(stage='geoip') instead of swallowing the exception.

Async + sync mirror; full suites green; all pre-commit gates incl. check-sync green.
@github-actions github-actions Bot added area: core-subsystems Touches guard_core/core/{responses,routing,validation,bypass,behavioral,events,initialization}/ area: models Touches guard_core/models.py area: sync Touches guard_core/sync/ (sync mirror generated by unasync) area: utils Touches guard_core/utils.py or exceptions.py tests Test suite changes labels Jun 23, 2026
@rennf93 rennf93 self-assigned this Jun 23, 2026
- cover the defensive branches O5/O6 left uncovered: _ip_in_list non-IP entry
  fallback + _check_whitelist empty (utils), restrictive route whitelist block
  (helpers), AWS prefix without a region field (cloud_handler), and the
  CompositeAgentHandler started/degraded/failed_handlers properties.
- replace deprecated redis setex(k, ttl, v) with set(k, v, ex=ttl) (async+sync).
- filter the unavoidable opentelemetry SelectableGroups DeprecationWarning.

Full async+sync suite: 100% lines + branches, 3696 passed, zero warnings.
@github-actions github-actions Bot added area: handlers Touches guard_core/handlers/ dependencies pyproject.toml or uv.lock labels Jun 23, 2026
@rennf93
rennf93 merged commit b0c0ede into master Jun 23, 2026
11 checks passed
@rennf93
rennf93 deleted the feat/agent-error-clarity branch June 23, 2026 06:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: core-subsystems Touches guard_core/core/{responses,routing,validation,bypass,behavioral,events,initialization}/ area: handlers Touches guard_core/handlers/ area: models Touches guard_core/models.py area: sync Touches guard_core/sync/ (sync mirror generated by unasync) area: utils Touches guard_core/utils.py or exceptions.py dependencies pyproject.toml or uv.lock tests Test suite changes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant