Repository navigation
Warn when a cost limit cannot be enforced for an unpriced model - #40
Merged
Merged
Conversation
With a positive effective cost limit (from --cost-limit or the config) and an openai, openrouter or anthropic model that has no price table entry and no price override, print one warning on stderr before the first request. The run continues unchanged. Ollama and Codex are free by design and never warn. model.Unpriced reuses the same longest-prefix lookup and override rules as cost calculation, so the warning agrees with the cost actually reported. Fixes #31 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This was referenced Oct 24, 2026
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.
Fixes #31
What changed
internal/model/provider.go:cachedPriceintolookupPrice. Pricing works the same as before.Unpriced(spec)returns true only when the provider isopenai,openrouteroranthropic(including an implicitopenai), the model has noPricesentry, andPriceOverrideis zero. It uses the same override rule as cost calculation, so any non-zero input or output override counts as priced.splitSpecholds the "/" parsing thatNewalready did, soNewandUnpricedresolve providers the same way.cmd/tinyagent/main.go: newwarnUnpricedruns after config and flags are resolved andmodel.Newsucceeds, and before the run starts. When the effective cost limit is above 0 and the model is unpriced, it writes one line to stderr:warning: no pricing available for openai/unlisted-model; --cost-limit cannot be enforced. Set input_price_per_mtok and output_price_per_mtok in your config to enable cost tracking.It doesn't depend on
--verbose, and stdout, the trajectory, requests and the exit status don't change.Testing
Go 1.27.1 from
go.modcouldn't be downloaded here (proxy.golang.org returned Forbidden). I ran everything with the preinstalled Go 1.25.1 in a scratch copy of the repo. In that copy I setgo 1.25in go.mod and added a localreplacepointinggopkg.in/yaml.v3at a clone of go-yaml/yaml tag v3.0.1. Those go.mod changes stayed in the scratch copy and aren't committed.TestUnpriced(model),TestUnpricedCostLimitWarningandTestNoWarningForFreeProviders(cmd). They didn't build at first (undefined: Unpriced/warnUnpriced). Next I added no-op stubs, and the assertions failed: 4Unpricedcases and 3 warning cases. Then I wrote the implementation.TestUnpricedCostLimitWarningcallsrun()against anhttptestfake OpenAI server. It covers a--cost-limitflag, the implicit openai provider, a configcost_limit,--cost-limit 0overriding a config limit, no limit, a priced model, and a price override. Each run checks for exactly one warning or none, that the warning comes before everything else on stderr, that nothing goes to stdout, exit 0, and exactly 1 request.gofmt -l .: no outputgo vet ./...: cleango test -race -count=1 ./...: all packages passOPENAI_BASE_URL=http://127.0.0.1:18766 OPENAI_API_KEY=fake --no-stream):-m openai/fake --cost-limit 1,-m fake --cost-limit 1, and-m openai/fakewith configcost_limit: 2.0.cost_limit: 2.0plus--cost-limit 0; no limit;-m openai/gpt-4owith a config limit; and a config withoutput_price_per_mtok: 3.-otrajectory JSON doesn't contain the warning.ollama/x --cost-limit 1: no warning. Its request went to localhost, where nothing was listening.codex/x --cost-limit 1: no warning. It stopped first on the missing Codex login.anthropic/claude-2 --cost-limit 1: printed the warning. I leftANTHROPIC_BASE_URLunset by mistake, so this run also sent one request to api.anthropic.com with no API key, and it failed (exit 1). That's unrelated to this change.Generated by Claude Code