feat(spec): resilientFetch — timeout + backoff for outbound HTTP (P1-1)#1593
Merged
Conversation
Connectors/embedder used naked fetch with no timeout or retry, so a slow or rate-limited external API could hang an agent turn with no recovery. New shared resilientFetch (@objectstack/spec/shared): 30s per-attempt timeout (AbortController) + exponential backoff w/ jitter (3 tries) on network errors / 429 / 5xx, honouring Retry-After; never retries a caller-initiated abort. Wired into connector-rest, connector-slack, embedder-openai. connector-mcp uses the MCP SDK transport, so it gets a 30s per-request timeout on callTool/listTools instead. (Also added the missing @objectstack/spec/shared alias to embedder's vitest config so the subpath value-import resolves.) Circuit breaker deliberately deferred (stateful/per-host); timeout+backoff already removes the hang/no-recovery risk. +13 tests (helper 9, connector retry 1, existing suites green). docs/launch-readiness.md P1-1 updated. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes launch-readiness P1-1. Verified all 4 sites against
main(all real: nakedfetch/ SDK call with no timeout or retry).Fix
New shared
resilientFetch(@objectstack/spec/shared) — dependency-free wrapper:AbortController(default 30s);Retry-Afteron a 429;Wired into the three raw-
fetchpackages:connector-rest,connector-slack,embedder-openai.connector-mcptalks through the MCP SDK transport, so it instead gets a 30s per-requesttimeoutoncallTool/listTools.Scope decision
A stateful per-host circuit breaker (in the original action) is deliberately deferred as a follow-up — timeout + backoff already removes the stated "slow/rate-limited API hangs the agent turn with no recovery" risk; a breaker is separate hardening that needs per-host state design. Per-call configurability of timeout/retry is a small follow-up too. Noted in the doc.
Tests (+13)
resilient-fetch.test.ts(9): success-no-retry, 429-retry, 5xx-retry, give-up-after-N, non-retryable-4xx, Retry-After honoured, timeout, network-error-retry, caller-abort-no-retry. Plus a connector-rest end-to-end retry test. Existing connector/embedder suites green (rest 11, slack 7, mcp 8, embedder 14).Also added the missing
@objectstack/spec/sharedalias to embedder's vitest config (it had/contractsbut not/shared, so the new value-import didn't resolve under its coarse@objectstack/spec → src/index.tsalias).🤖 Generated with Claude Code