Skip to content

feat: add per-tool circuit breakers - #35

Merged
Deathcharge merged 2 commits into
mainfrom
codex/per-tool-circuit-breakers
Aug 11, 2026
Merged

feat: add per-tool circuit breakers#35
Deathcharge merged 2 commits into
mainfrom
codex/per-tool-circuit-breakers

Conversation

@Deathcharge

Copy link
Copy Markdown
Owner

Summary

  • add opt-in process-local consecutive-failure circuit breakers per exact tool registration
  • fail fast before concurrency/rate admission, invalidate queued permits, and allow one half-open recovery probe
  • expose safe direct/MCP/task results, content-free metrics/lifecycle status, state inspection, and manual reset
  • document scope, retry boundaries, operations, and a runnable recovery example

Failure boundary

Counts tool exceptions, output validation failures, and caller-visible timeouts. Does not count invalid input, policy outcomes, runtime/rate admission rejection, progress-handler failure, or caller cancellation. Core performs no automatic retry.

Verification

  • Black check: 23 files unchanged
  • Ruff: passed
  • strict mypy: 19 source/example files passed
  • pytest: 173 passed, 94.60% branch-aware coverage
  • Bandit: passed
  • real example: failed -> circuit_open -> success
  • strict build/Twine: passed
  • clean no-deps wheel: pip check passed; canonical and legacy imports resolved from site-packages; failed -> circuit_open -> recovered

Candidate artifacts (local, not a release):

  • wheel SHA-256: 2a93ebb8fb8d283c4e878b2a0046ac44f5d656a586195f0e951279b9571ea56d
  • sdist SHA-256: 0bf48553d4c94f928e5b5ab807586c6529bd9d08fd7dd5459babcdc231935c05

@coderabbitai

coderabbitai Bot commented Aug 11, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@Deathcharge, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 51 minutes

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 725fb7e1-c3f2-4a96-87eb-6f6bd6c06a5f

📥 Commits

Reviewing files that changed from the base of the PR and between 733a89b and 5612ced.

📒 Files selected for processing (8)
  • .github/workflows/ci.yml
  • .github/workflows/release.yml
  • MANIFEST.in
  • README.md
  • pyproject.toml
  • scripts/smoke_check.py
  • src/samsarix_core/runtime.py
  • tests/test_runtime.py

Summary by CodeRabbit

  • New Features

    • Added opt-in, per-tool circuit breakers to prevent repeated failures from triggering unnecessary calls.
    • Supports closed, open, and half-open recovery states with retry guidance.
    • Added circuit inspection and manual reset capabilities.
    • Circuit-open results work consistently across direct, batch, MCP, and task-based calls.
    • Added circuit status and trip metrics for monitoring.
    • Circuit-breaker configuration and state types are now publicly available.
  • Documentation

    • Added setup guidance, API reference updates, observability recommendations, and a complete working example.
    • Added release notes and roadmap coverage for the feature.

Walkthrough

Added opt-in, process-local, per-tool circuit breakers. The runtime supports failure thresholds, open and half-open states, permit invalidation, recovery probes, inspection, reset operations, metrics, MCP/task results, documentation, examples, and compatibility exports.

Changes

Per-tool circuit-breaker support

Layer / File(s) Summary
Circuit-breaker contracts and exports
src/samsarix_core/models.py, src/samsarix_core/__init__.py, src/helix_core/__init__.py, docs/API_REFERENCE.md
Added circuit states, configuration validation, circuit-open statuses, metrics, serialization, and package exports.
Runtime circuit execution
src/samsarix_core/runtime.py
Added registration configuration, thread-safe permits, state transitions, recovery probing, stale-permit invalidation, outcome tracking, circuit-open results, inspection, and reset operations.
Behavior and integration documentation
README.md, CHANGELOG.md, ROADMAP.md, docs/*, examples/circuit_breaker_api.py
Documented circuit-breaker behavior across direct, MCP, and task execution, and added an executable recovery example.
Cross-interface and lifecycle validation
.github/workflows/*, tests/test_runtime.py, tests/test_mcp.py, tests/test_mcp_tasks.py, tests/test_definitions.py
Added coverage for configuration, failures, recovery, concurrency, rate limits, timeouts, safe results, metrics, compatibility exports, and smoke checks.

Estimated code review effort: 4 (Complex) | ~60 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Caller
  participant ToolRuntime
  participant CircuitBreaker
  participant Tool
  Caller->>ToolRuntime: Invoke registered tool
  ToolRuntime->>CircuitBreaker: Acquire and validate permit
  CircuitBreaker-->>ToolRuntime: Permit or circuit_open rejection
  ToolRuntime->>Tool: Execute after capacity and rate checks
  Tool-->>ToolRuntime: Success or failure
  ToolRuntime->>CircuitBreaker: Record outcome
  CircuitBreaker-->>ToolRuntime: Update circuit state
  ToolRuntime-->>Caller: Return tool result
Loading

Possibly related PRs

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 46.99% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely describes the main change: adding per-tool circuit breakers.
Description check ✅ Passed The description directly explains the circuit-breaker implementation, behavior, scope, documentation, and verification results.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/per-tool-circuit-breakers

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.github/workflows/ci.yml:
- Around line 60-61: Replace the duplicated inline wheel smoke-check commands
with one shared checked-in scripts/smoke_check.py invocation, preserving all
existing export and behavior assertions. Update .github/workflows/ci.yml lines
60-61 to invoke it with .smoke/bin/python, and .github/workflows/release.yml
lines 46-47 to invoke the same script with .release-smoke/bin/python.

In `@README.md`:
- Around line 249-255: Update the ToolRuntime.invoke() runtime status list to
include circuit_open, matching the circuit-breaker behavior documented in the
surrounding README section and keeping the existing statuses unchanged.

In `@src/samsarix_core/runtime.py`:
- Around line 656-657: Replace the inline circuit failure handling at the shown
call site and the corresponding failure paths around the other circuit-breaker
calls with `_record_circuit_failure`, passing the relevant circuit attempt and
current time. Preserve the existing ordering so `fail()` occurs before execution
cancellation, and keep the trip counter update centralized in the helper.

In `@tests/test_runtime.py`:
- Around line 1551-1557: Update the async timeout test around the
slow_async_dependency invocations to wait for started using the same one-second
synchronization pattern as the synchronous counterpart, replacing the immediate
started.is_set() assertion while preserving the existing circuit-breaker
assertions.
- Around line 1687-1698: Add a parametrized test case in the existing
ToolCircuitBreaker validation matrix using recovery_timeout_seconds=1e308 with a
valid failure_threshold and expecting ValueError, so execution reaches the
isfinite(retry_after_ms) guard; optionally include negative and non-numeric
recovery timeout cases if consistent with the surrounding validation coverage.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 47c46609-6bed-4dc4-8ff2-15cea2d79ac0

📥 Commits

Reviewing files that changed from the base of the PR and between 39206fb and 733a89b.

📒 Files selected for processing (22)
  • .github/workflows/ci.yml
  • .github/workflows/release.yml
  • CHANGELOG.md
  • README.md
  • ROADMAP.md
  • docs/API_REFERENCE.md
  • docs/ARCHITECTURE.md
  • docs/BEST_PRACTICES.md
  • docs/CIRCUIT_BREAKERS.md
  • docs/GETTING_STARTED.md
  • docs/MCP.md
  • docs/OBSERVABILITY.md
  • docs/RATE_LIMITS.md
  • examples/circuit_breaker_api.py
  • src/helix_core/__init__.py
  • src/samsarix_core/__init__.py
  • src/samsarix_core/models.py
  • src/samsarix_core/runtime.py
  • tests/test_definitions.py
  • tests/test_mcp.py
  • tests/test_mcp_tasks.py
  • tests/test_runtime.py

Comment thread .github/workflows/ci.yml Outdated
Comment thread README.md
Comment thread src/samsarix_core/runtime.py Outdated
Comment thread tests/test_runtime.py Outdated
Comment thread tests/test_runtime.py
@Deathcharge
Deathcharge merged commit 2744d69 into main Aug 11, 2026
15 checks passed
@Deathcharge
Deathcharge deleted the codex/per-tool-circuit-breakers branch August 11, 2026 04:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant