Skip to content

chore: replace resilience dep with zero-dependency native impl - #73

Merged
swaldmann merged 15 commits into
mainfrom
agents-zero-deps-resilience
Sep 3, 2026
Merged

chore: replace resilience dep with zero-dependency native impl#73
swaldmann merged 15 commits into
mainfrom
agents-zero-deps-resilience

Conversation

@swaldmann

@swaldmann swaldmann commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

@sap-cloud-sdk/resilience is basically a wrapper around async-retry, last updated 5 years ago.

This PR removes @sap-cloud-sdk/resilience and replaces timeout, retry, and circuitBreaker with a Node-native, zero dependencies implementation.

AbortController is now wired into the request signal so timeouts actually cancel the in-flight HTTP call instead of just ignoring it. Retry uses capped exponential backoff (32 seconds max) with jitter.

Have you...

  • Added relevant entry to the change log?

Removes `@sap-cloud-sdk/resilience` and replaces `timeout`, `retry`, and
`circuitBreaker` with a Node-native implementation in `lib/utils/resilience.js`.

`AbortController` is now wired into the request signal so timeouts actually
cancel the in-flight HTTP call instead of just ignoring it. Retry uses
capped exponential backoff with jitter. `CircuitBreaker` uses private class
fields and a rolling window, matching the same defaults and error-filter
semantics as before.
@swaldmann
swaldmann force-pushed the agents-zero-deps-resilience branch from 885e7a5 to 39b0eaa Compare September 1, 2026 16:47

@schiwekM schiwekM left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Nice, could you add it to the anthropic model as well?

@swaldmann swaldmann changed the title feat: replace resilience dep with zero-dependency native impl chore: replace resilience dep with zero-dependency native impl Sep 2, 2026
Comment thread lib/utils/resilience.js Outdated
Comment thread lib/utils/resilience.js
@swaldmann
swaldmann force-pushed the agents-zero-deps-resilience branch from b4f366f to 39b0eaa Compare September 2, 2026 10:02
- Replace circuitBreakerDefaultOptions export with _cbOptions() reading
  cds.env.agents.circuitBreaker at call time, merging over hardcoded defaults.
  The test profile sets resetTimeout: 3000 so tests can wait it out reliably.
- Key breakers by URI only (not URI + tenantId): the model is shared across
  tenants so a per-tenant breaker provides no benefit.
- Simplify the recover test: trip breaker, wait 3500ms for half-open,
  then verify the probe call succeeds and closes the breaker.
- Raise per-user quota to 10000 in test profile so the trip loops never
  exhaust the limit.
@swaldmann
swaldmann force-pushed the agents-zero-deps-resilience branch 2 times, most recently from 3234e03 to f5a6a26 Compare September 2, 2026 11:39
schiwekM
schiwekM previously approved these changes Sep 2, 2026
Akatuoro
Akatuoro previously approved these changes Sep 2, 2026
Comment thread lib/utils/resilience.js Outdated
Comment thread tests/projects/bookshop/package.json Outdated
@swaldmann
swaldmann dismissed stale reviews from Akatuoro and schiwekM via bf385d9 September 2, 2026 15:49
@swaldmann
swaldmann marked this pull request as ready for review September 3, 2026 16:10
@swaldmann
swaldmann requested review from a team as code owners September 3, 2026 16:10
@hyperspace-pr-bot

Copy link
Copy Markdown

Summary

The following content is AI-generated and provides a summary of the pull request:


Chore: Replace @sap-cloud-sdk/resilience with Zero-Dependency Native Implementation

Have you...

  • Added relevant entry to the change log?

Overview

This PR removes the @sap-cloud-sdk/resilience dependency (a wrapper around async-retry, last updated 5 years ago) and replaces it with a Node-native, zero-dependency implementation of timeout, retry, and circuitBreaker resilience patterns.

Changes

New lib/utils/resilience.js

A self-contained resilience module implementing three middleware functions:

  • timeout(ms) — Wires AbortController into the request signal so timeouts actually cancel the in-flight HTTP call. Uses Promise.race against a timer that aborts the underlying request.
  • retry(retries) — Capped exponential backoff (max 32s) with jitter. Bails immediately on 4xx errors; retries on 5xx and network errors.
  • circuitBreaker() — Per-URI breaker with a rolling time window. Opens after volume threshold calls exceed the error rate; fails fast with EOPENBREAKER while open. 4xx errors never trip the breaker.

Circuit Breaker Configuration

Default settings added to package.json under cds.agents.circuitBreaker:

{
  "errorThresholdPercentage": 50,
  "volumeThreshold": 10,
  "resetTimeout": 30000,
  "rollingCountTimeout": 10000
}

Import Updates

  • lib/agents/middleware/content-filter.js and lib/models/aicore.js now import from ../../utils/resilience.js
  • @sap-cloud-sdk/resilience removed from package.json dependencies

Test Improvements

  • Replaced brittle deep-require hacks to access @sap-cloud-sdk/resilience internals with a proper OData resetBreakers() action exposed on the test service
  • Circuit breaker volumeThreshold lowered to 2 in the test environment for faster test execution
  • Test loop counts updated to match the new lower threshold

  • 🔄 Regenerate and Update Summary
  • ✏️ Insert as PR Description (deletes this comment)
  • 🗑️ Delete comment
PR Bot Information

Version: 1.31.13

  • File Content Strategy: Full file content
  • Event Trigger: pull_request.ready_for_review
  • Output Template: Repository PR Template
  • LLM: anthropic--claude-4.6-sonnet
  • Correlation ID: 0bac6220-a7b2-11f1-9bf1-20d440ae327b
  • Summary Prompt: Default Prompt

@swaldmann
swaldmann enabled auto-merge (squash) September 3, 2026 17:47
@swaldmann
swaldmann merged commit 4b64dec into main Sep 3, 2026
20 of 21 checks passed
@swaldmann
swaldmann deleted the agents-zero-deps-resilience branch September 3, 2026 17:48
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.

3 participants