fix(usage): drop redundant GatewayProvider.embed_batch override (round 3)

Round-3 claude-review finding:

- 🟡 Double _ensure_bearer() on gateway.embed_batch(). Round 1 made
  OpenAIProvider.embed_batch() delegate to embed_batch_with_usage(); because
  GatewayProvider overrode both embed_batch() and embed_batch_with_usage() (each
  calling _ensure_bearer), gateway.embed_batch() refreshed the bearer twice
  (the second a cache-hit no-op). Remove the now-redundant embed_batch()
  override: OpenAI's embed_batch() routes through embed_batch_with_usage(),
  which the gateway still overrides, so the bearer refreshes exactly once on
  every path. The remaining two overrides (embed + embed_batch_with_usage) cover
  all four entrypoints; documented the topology.

- 🟢 Added test_gateway_embed_batch_ensures_bearer_once locking in the single
  refresh.

Cohere token-fallback (🟢 nit) is already covered by
test_bedrock_with_usage_estimates_when_token_count_absent.

Deck #67.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Chris Coutinho
2026-06-08 01:29:36 +02:00
co-authored by Claude Opus 4.8
parent d15ce627ab
commit 9ac9e1ab09
2 changed files with 40 additions and 10 deletions
@@ -217,22 +217,21 @@ class GatewayProvider(OpenAIProvider):
exc,
)
# Bearer-refresh override topology. OpenAIProvider routes embed_batch(),
# embed_with_usage() and embed_batch_with_usage() all through
# embed_batch_with_usage(); only embed() (single) is self-contained. So we
# override exactly two methods to refresh the bearer exactly once on every
# path: embed() (its own entrypoint) and embed_batch_with_usage() (the
# shared funnel for the other three). Overriding embed_batch() as well would
# double-call _ensure_bearer() (override → super().embed_batch() →
# self.embed_batch_with_usage() → override again).
async def embed(self, text: str) -> list[float]:
await self._ensure_bearer()
return await super().embed(text)
async def embed_batch(self, texts: list[str]) -> list[list[float]]:
await self._ensure_bearer()
return await super().embed_batch(texts)
async def embed_batch_with_usage(
self, texts: list[str]
) -> tuple[list[list[float]], int]:
# Only the batch usage-variant is overridden: OpenAIProvider's
# embed_with_usage() routes through embed_batch_with_usage(), so a
# single embed_with_usage() call already lands here and refreshes the
# bearer exactly once (overriding both would double-ensure). This
# differs from embed()/embed_batch() above, where the single embed() is
# self-contained and therefore needs its own override.
await self._ensure_bearer()
return await super().embed_batch_with_usage(texts)