Skip to content

Cap API provider output tokens and web-search spend per request#491

Merged
jrhizor merged 6 commits into
mainfrom
jrhizor/provider-spend-caps
Jul 24, 2026
Merged

Cap API provider output tokens and web-search spend per request#491
jrhizor merged 6 commits into
mainfrom
jrhizor/provider-spend-caps

Conversation

@jrhizor

@jrhizor jrhizor commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

First of a stack extracted from #483 so the DB-config work can land in small, releasable pieces.

What

Hard per-request spend caps on the four direct-API providers, so no single tracked run can spend unboundedly:

  • Output-token caps on anthropic-api, openai-api, openrouter, mistral-api (centralized in providers/config.ts).
  • Web-search budget caps: Anthropic max_uses = 1, OpenAI maxToolCalls = 2, OpenRouter native-first web plugin with search_context_size + Exa max_results. The onboarding structured-research path keeps its own deeper, named cap.

Why it's low-risk

No schema, no migration, no dependency on the config hierarchy — just provider-layer constants and their use. Supersedes the mechanism half of #452.

Tests: 4 new provider cap suites (10 cases); lib typechecks.

Bound a single tracked run's cost on the four direct-API providers:
- Output-token caps on anthropic-api, openai-api, openrouter, mistral-api.
- Web-search budget caps: Anthropic max_uses=1, OpenAI maxToolCalls=2,
  OpenRouter native-first web plugin with search_context_size + Exa
  max_results. The onboarding research path keeps a deeper, named cap.

Code defaults centralized in providers/config.ts; no schema, no config
dependency. Extracted from the DB-config PR so it can ship on its own.
@vercel

vercel Bot commented Jul 23, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
elmo Ready Ready Preview, Comment Jul 24, 2026 9:12am

Request Review

jrhizor added 2 commits July 23, 2026 20:31
…d-caps

# Conflicts:
#	packages/lib/src/providers/registry/anthropic-api.ts
#	packages/lib/src/providers/registry/openai-api.ts
Revert the OpenRouter plugin switch: ":online" is exactly equivalent to
plugins: [{ id: "web" }] and already routes to native provider search, so
the explicit config changed nothing but the request shape.

Raise the OpenAI and OpenRouter caps to 16k and Mistral to 8k. The caps
bound worst-case spend, and on OpenAI/OpenRouter they also count reasoning
tokens, so the old 8k left little room on reasoning targets.

A capped response still stores as a normal run, so log the finish reason
rather than failing — a truncated answer would otherwise land as a
real-looking result with fewer brand mentions.
Measured against ~30k tracked ChatGPT answers as a proxy for answer length:
p99 is ~3.4k tokens and ~0.4% run past 4k, so the long-standing 4k cap was
clipping roughly 1 run in 240. A clipped answer stores as a normal run with
fewer brand mentions, so those were scoring as quiet false negatives.
Anthropic was already hard-capped at 4000 in production, so keep it there —
this changes nothing for Anthropic. OpenAI, OpenRouter, and Mistral get a
uniform 8000 worst-case bound; on OpenAI/OpenRouter that ceiling also covers
reasoning tokens, and warnIfOutputCapped logs any run that hits it so the
number can be revisited from real traffic.
The /v1/conversations response has no finish_reason field (confirmed against
the client-ts schema), so warnIfOutputCapped only applies to the chat path.
@jrhizor
jrhizor merged commit 72e7091 into main Jul 24, 2026
9 checks passed
@jrhizor
jrhizor deleted the jrhizor/provider-spend-caps branch July 24, 2026 09:13
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