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
61
62
63
64
65
66
67
68
69
70
package main

// model.go centralises everything about the Gemini Live model in one place:
// the model id, the Live endpoint, audio stream specs, and the paid-tier
// pricing used to compute live cost stats. To switch models or update prices in
// the future, edit only activeModel below.

// ModelConfig bundles all model-specific settings and rates.
type ModelConfig struct {
	// ID is the model name (without the "models/" prefix; dialLive adds it).
	ID string

	// WSHost / WSPath form the Live API BidiGenerateContent endpoint.
	WSHost string
	WSPath string

	// Audio stream specs (raw little-endian PCM16).
	AudioInSampleRate  int // client mic -> server -> Gemini
	AudioOutSampleRate int // Gemini -> server -> client playback
	// AudioTokensPerSecond is Gemini's billing convention for audio
	// (25 tokens per second of audio, per the pricing page).
	AudioTokensPerSecond float64

	// Paid-tier prices in USD per 1,000,000 tokens.
	PriceAudioInPerMTok  float64
	PriceAudioOutPerMTok float64
	PriceImageInPerMTok  float64
	PriceTextInPerMTok   float64
	PriceTextOutPerMTok  float64
}

// activeModel is the single source of truth for the model in use.
//
// Rates below are the paid-tier prices for gemini-3.1-flash-live-preview
// (per 1M tokens): audio in $3.00, audio out $12.00, image/video in $1.00,
// text in $0.75, text out $4.50. Audio bills at 25 tokens/second.
var activeModel = ModelConfig{
	ID:     "gemini-3.1-flash-live-preview",
	WSHost: "generativelanguage.googleapis.com",
	WSPath: "/ws/google.ai.generativelanguage.v1beta.GenerativeService.BidiGenerateContent",

	AudioInSampleRate:    16000,
	AudioOutSampleRate:   24000,
	AudioTokensPerSecond: 25.0,

	PriceAudioInPerMTok:  3.00,
	PriceAudioOutPerMTok: 12.00,
	PriceImageInPerMTok:  1.00,
	PriceTextInPerMTok:   0.75,
	PriceTextOutPerMTok:  4.50,
}

// bytesPerAudioSecond returns the byte count of one second of PCM16 mono at the
// given sample rate (2 bytes/sample).
func bytesPerAudioSecond(sampleRate int) float64 { return float64(sampleRate) * 2.0 }

// audioSecondsFromBytes converts a PCM16-mono byte count to seconds.
func audioSecondsFromBytes(nbytes int, sampleRate int) float64 {
	return float64(nbytes) / bytesPerAudioSecond(sampleRate)
}

// audioTokens converts audio seconds to billed tokens (25 tok/s).
func (m ModelConfig) audioTokens(seconds float64) float64 {
	return seconds * m.AudioTokensPerSecond
}

// costUSD converts a token count and a per-1M-token price to dollars.
func costUSD(tokens, pricePerMTok float64) float64 {
	return tokens / 1_000_000.0 * pricePerMTok
}