summaryrefslogtreecommitdiff
path: root/internal/provider/google/pricing.go
blob: 55ea66f4a50266b82a3204199a804b90b4108350 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
package google

import "strings"

// modelPrice is USD cost per million tokens for one model (or model family
// prefix).
type modelPrice struct {
	InputPerMTok  float64
	OutputPerMTok float64
}

// pricingTable maps a model-name *prefix* to its per-million-token pricing.
// Keyed by prefix (rather than exact model string) so dated/versioned model
// IDs (e.g. "gemini-2.5-flash-preview-09-2025") still resolve without
// needing an entry per snapshot. Edit this table as Google's pricing or
// model lineup changes — it intentionally has no other logic attached.
//
// Prices below are cached from training/research as of mid-2026 and are not
// fetched live; verify against https://ai.google.dev/gemini-api/docs/pricing
// before relying on them for real billing decisions. Two caveats specific to
// Gemini pricing that this flat per-model table does NOT model:
//   - Some tiers (notably 1.5 Pro and some 2.5 Pro contexts) charge a higher
//     rate once the prompt exceeds 128K/200K tokens; the price below is the
//     lower/base-context rate.
//   - Some Flash-tier models charge a different (higher) output rate for
//     "thinking"/reasoning tokens vs. plain output tokens; the price below
//     is the standard output rate, not the thinking-token rate.
var pricingTable = map[string]modelPrice{
	// Pro tier (most capable, most expensive).
	"gemini-2.5-pro": {InputPerMTok: 1.25, OutputPerMTok: 10.00},
	"gemini-1.5-pro": {InputPerMTok: 1.25, OutputPerMTok: 5.00},

	// Flash tier (balanced cost/capability; default for most tasks).
	"gemini-2.5-flash-lite": {InputPerMTok: 0.10, OutputPerMTok: 0.40},
	"gemini-2.5-flash":      {InputPerMTok: 0.30, OutputPerMTok: 2.50},
	"gemini-2.0-flash-lite": {InputPerMTok: 0.075, OutputPerMTok: 0.30},
	"gemini-2.0-flash":      {InputPerMTok: 0.10, OutputPerMTok: 0.40},
	"gemini-1.5-flash-8b":   {InputPerMTok: 0.0375, OutputPerMTok: 0.15},
	"gemini-1.5-flash":      {InputPerMTok: 0.075, OutputPerMTok: 0.30},
}

// defaultPricing is used for unrecognized models rather than erroring —
// Flash-tier pricing is a reasonable default since it's the most commonly
// used tier for the harness's escalation ladder.
var defaultPricing = modelPrice{InputPerMTok: 0.30, OutputPerMTok: 2.50}

// pricingFor returns the per-million-token input/output pricing for model,
// matching the longest pricingTable prefix that model starts with. Falls
// back to defaultPricing for unrecognized models.
func pricingFor(model string) (inputPerMTok, outputPerMTok float64) {
	price := defaultPricing
	bestLen := -1
	for prefix, p := range pricingTable {
		if len(prefix) > bestLen && strings.HasPrefix(model, prefix) {
			bestLen = len(prefix)
			price = p
		}
	}
	return price.InputPerMTok, price.OutputPerMTok
}