Skip to content

fix(tavus): don't retry 4xx and preserve provider errors - #2635

Merged
davidzhao merged 2 commits into
mainfrom
fix/tavus-api-retries
Oct 4, 2026
Merged

davidzhao merged 2 commits into
mainfrom
fix/tavus-api-retries

Conversation

@rosetta-livekit-bot

@rosetta-livekit-bot rosetta-livekit-bot Bot commented Oct 4, 2026 •

Copy link
Copy Markdown
Contributor

Ports livekit/agents#7494.

Summary

  • return non-retryable Tavus status errors immediately
  • retry 5xx and network failures while preserving the final provider error or network cause
  • avoid duplicate accepted POSTs when Tavus returns malformed JSON
  • add a patch changeset for @livekit/agents-plugin-tavus
Source diff coverage
  • livekit-plugins/livekit-plugins-tavus/livekit/plugins/tavus/api.py: adapted to plugins/tavus/src/api.ts. The Python aiohttp exception branches map to Fetch TypeError and timeout DOMException; Python exception chaining maps to JavaScript Error.cause. Existing target retry timing remains in milliseconds through intervalForRetry.
  • tests/test_plugin_tavus.py: adapted to plugins/tavus/src/api.test.ts, the target plugin's existing co-located Vitest suite. All five source tests are ported: 4xx classification/status preservation, 5xx retry-to-success, persistent 5xx provider error preservation, malformed success JSON without retry, and network retry/cause chaining.
  • Not applicable: none. Every source diff file has a target counterpart and is covered.

Validation

  • pnpm test plugins/tavus (16 tests across the complete Tavus package suite)
  • pnpm --filter @livekit/agents-plugin-tavus build
  • pnpm --filter @livekit/agents-plugin-tavus lint
  • pnpm build (40 workspace packages)
  • pnpm lint reaches an unrelated pre-existing error at plugins/openai/src/ws/llm.ts:127 (@typescript-eslint/no-misused-promises); Tavus package lint passes.

Ported from livekit/agents#7494

Original PR description

TavusAPI._post retries every failure, including 4xx responses that can never succeed. With a wrong API key the avatar takes about 4 seconds to fail, logs three tracebacks, and ends with a retryable APIConnectionError("Failed to call Tavus API after all retries") that has lost the 401 and the response body.

The loop catches Exception, which includes the APIStatusError it raises itself for a non-2xx response, logs each one with logger.exception, and always finishes with a generic, unchained APIConnectionError. It also runs range(max_retry), one attempt fewer than the other avatar plugins.

This is the same change #7314 made for Anam. A non-retryable APIStatusError is re-raised immediately. 5xx and network errors are retried max_retry times after the first attempt with a warning (status code only, no payload), and the final error is the provider's APIStatusError, or an APIConnectionError chained to the network error.

Against a local server with default connect options, on main: a 401 takes 4.00s, three tracebacks, generic APIConnectionError; a persistent 503 is the same. With this change a 401 raises APIStatusError(status_code=401) on the first attempt with no traceback, 503, 503, 200 still succeeds, and a persistent 503 raises APIStatusError(status_code=503) after four attempts (6.01s, one more attempt than before, matching Anam). Five tests added in a new tests/test_plugin_tavus.py; the four retry-classification ones fail on main, and one covers a 2xx with a malformed JSON body, which now fails once with a non-retryable APIConnectionError instead of re-sending a POST Tavus already accepted.

Closes #7493.

@rosetta-livekit-bot
rosetta-livekit-bot Bot requested a review from a team as a code owner October 4, 2026 06:01
@changeset-bot

changeset-bot Bot commented Oct 4, 2026 •

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 58eb1c4

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 39 packages
Name Type
@livekit/agents-plugin-tavus Patch
@livekit/agents Patch
@livekit/agents-plugin-anam Patch
@livekit/agents-plugin-anthropic Patch
@livekit/agents-plugin-assemblyai Patch
@livekit/agents-plugin-azure Patch
@livekit/agents-plugin-baseten Patch
@livekit/agents-plugin-bey Patch
@livekit/agents-plugin-cartesia Patch
@livekit/agents-plugin-cerebras Patch
@livekit/agents-plugin-deepgram Patch
@livekit/agents-plugin-did Patch
@livekit/agents-plugin-elevenlabs Patch
@livekit/agents-plugin-fishaudio Patch
@livekit/agents-plugin-google Patch
@livekit/agents-plugin-hume Patch
@livekit/agents-plugin-inworld Patch
@livekit/agents-plugin-krisp Patch
@livekit/agents-plugin-lemonslice Patch
@livekit/agents-plugin-liveavatar Patch
@livekit/agents-plugin-livekit Patch
@livekit/agents-plugin-meta Patch
@livekit/agents-plugin-minimax Patch
@livekit/agents-plugin-mistral Patch
@livekit/agents-plugin-mistralai Patch
@livekit/agents-plugin-neuphonic Patch
@livekit/agents-plugin-openai Patch
@livekit/agents-plugin-perplexity Patch
@livekit/agents-plugin-phonic Patch
@livekit/agents-plugin-protoface Patch
@livekit/agents-plugin-resemble Patch
@livekit/agents-plugin-rime Patch
@livekit/agents-plugin-runway Patch
@livekit/agents-plugin-sarvam Patch
@livekit/agents-plugin-silero Patch
@livekit/agents-plugin-soniox Patch
@livekit/agents-plugins-test Patch
@livekit/agents-plugin-trugen Patch
@livekit/agents-plugin-xai Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

devin-ai-integration[bot]

This comment was marked as resolved.

@davidzhao
davidzhao merged commit c3a02bd into main Oct 4, 2026
8 of 9 checks passed
@davidzhao
davidzhao deleted the fix/tavus-api-retries branch October 4, 2026 06:56
@github-actions github-actions Bot mentioned this pull request Oct 4, 2026
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