gemini

package
v0.10.14 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 7, 2026 License: MIT Imports: 20 Imported by: 0

Documentation

Index

Constants

View Source
const DefaultGeminiQuotaStaleAfter = 15 * time.Minute
View Source
const GeminiAuthFreshnessWindow = 7 * 24 * time.Hour
View Source
const GeminiModelDiscoveryFreshnessWindow = 24 * time.Hour

Variables

This section is empty.

Functions

func DefaultGeminiModelDiscovery

func DefaultGeminiModelDiscovery() harnesses.ModelDiscoverySnapshot

func FindGeminiQuotaWindow

func FindGeminiQuotaWindow(windows []harnesses.QuotaWindow, limitID string) *harnesses.QuotaWindow

FindGeminiQuotaWindow returns the QuotaWindow matching limitID, or nil.

func GeminiQuotaCachePath

func GeminiQuotaCachePath() (string, error)

GeminiQuotaCachePath returns the durable Gemini quota cache path.

func GeminiQuotaSnapshotAge

func GeminiQuotaSnapshotAge(snapshot *GeminiQuotaSnapshot, now time.Time) time.Duration

GeminiQuotaSnapshotAge reports snapshot age relative to now.

func IsGeminiQuotaFresh

func IsGeminiQuotaFresh(snapshot *GeminiQuotaSnapshot, now time.Time, staleAfter time.Duration) bool

IsGeminiQuotaFresh reports whether a snapshot is present and not stale.

func ModelDiscoveryFromText

func ModelDiscoveryFromText(text, source string) harnesses.ModelDiscoverySnapshot

ModelDiscoveryFromText extracts Gemini model IDs from caller-provided CLI output without assuming a current default model list.

func ParseGeminiModelManage

func ParseGeminiModelManage(text string) []harnesses.QuotaWindow

ParseGeminiModelManage parses the raw text captured from `gemini` in /model manage. It returns one QuotaWindow per recognised tier, with the tier label, used percent, reset text, and a derived quota state. Tiers missing in the captured text are simply absent from the returned slice.

func ReadGeminiQuotaFromCassette

func ReadGeminiQuotaFromCassette(dir string) ([]harnesses.QuotaWindow, error)

ReadGeminiQuotaFromCassette replays a previously recorded cassette and re-parses its final frame as Gemini /model manage output.

func ReadGeminiQuotaViaPTY

func ReadGeminiQuotaViaPTY(timeout time.Duration, opts ...QuotaPTYOption) ([]harnesses.QuotaWindow, error)

ReadGeminiQuotaViaPTY launches Gemini, sends /model manage, and returns the parsed tier quota windows. Callers must only treat non-empty, non-error results as authoritative — Gemini CLI renders /model manage as a version- sensitive TUI, so a timeout or empty parse means "quota unknown".

func ResolveGeminiModelAlias

func ResolveGeminiModelAlias(model string, snapshot harnesses.ModelDiscoverySnapshot) string

func TierLimitIDForModel

func TierLimitIDForModel(model string) (string, bool)

TierLimitIDForModel returns the tier limit_id that covers the given concrete Gemini model ID (e.g. "gemini-2.5-pro" -> "gemini-pro"). Unknown models return ("", false).

func WriteGeminiQuota

func WriteGeminiQuota(path string, snapshot GeminiQuotaSnapshot) error

WriteGeminiQuota atomically persists a GeminiQuotaSnapshot to path.

Types

type AuthSnapshot

type AuthSnapshot struct {
	Authenticated bool
	AuthType      string
	Account       *harnesses.AccountInfo
	CapturedAt    time.Time
	Fresh         bool
	Source        string
	Detail        string
}

AuthSnapshot captures non-secret Gemini CLI auth/account evidence. It never stores API keys, OAuth tokens, refresh tokens, or raw credential payloads.

func ReadAuthEvidence

func ReadAuthEvidence(now time.Time) AuthSnapshot

ReadAuthEvidence reads Gemini CLI auth evidence from the user's configured environment and ~/.gemini directory. It is best-effort because Gemini CLI has no stable non-interactive quota command; routing uses this as auth/account freshness evidence and exposes quota as unknown.

func ReadAuthEvidenceFromDir

func ReadAuthEvidenceFromDir(dir string, now time.Time) AuthSnapshot

ReadAuthEvidenceFromDir reads non-secret Gemini CLI auth evidence from a caller-provided .gemini directory. Tests use this for credential-free replay.

type GeminiQuotaRoutingDecision

type GeminiQuotaRoutingDecision struct {
	// PreferGemini is true when the snapshot is fresh and at least one
	// non-exhausted tier is present.
	PreferGemini bool
	// SnapshotPresent is true when a snapshot was found (even if stale).
	SnapshotPresent bool
	// Fresh is true when the snapshot is present and newer than staleAfter.
	Fresh bool
	// Age is the snapshot age (zero when absent).
	Age time.Duration
	// Snapshot is the cached snapshot when present.
	Snapshot *GeminiQuotaSnapshot
	// AvailableTiers lists tier limit_ids (e.g. "gemini-flash") that are
	// fresh and below the exhaustion threshold.
	AvailableTiers []string
	// ExhaustedTiers lists tier limit_ids currently blocked (e.g. "gemini-pro"
	// at 100% used).
	ExhaustedTiers []string
	// Reason describes the diagnostic outcome.
	Reason string
}

GeminiQuotaRoutingDecision summarises whether foreground routing may select Gemini without probing the CLI inline. The decision is made per tier: a tier is "available" only when it has a fresh, non-exhausted quota window.

func DecideGeminiQuotaRouting

func DecideGeminiQuotaRouting(snapshot *GeminiQuotaSnapshot, now time.Time, staleAfter time.Duration) GeminiQuotaRoutingDecision

DecideGeminiQuotaRouting turns a durable quota snapshot into a foreground routing decision. Missing, stale, or empty quota evidence keeps Gemini out of automatic routing.

func ReadGeminiQuotaRoutingDecision

func ReadGeminiQuotaRoutingDecision(now time.Time, staleAfter time.Duration) GeminiQuotaRoutingDecision

ReadGeminiQuotaRoutingDecision reads the default cache and produces a routing decision in one call.

func (GeminiQuotaRoutingDecision) IsGeminiTierAvailable

func (d GeminiQuotaRoutingDecision) IsGeminiTierAvailable(model string) bool

IsGeminiTierAvailable reports whether the tier for a concrete Gemini model is currently selectable according to the decision. An unknown model returns false so routing never silently picks a model outside the parsed tier set.

type GeminiQuotaSnapshot

type GeminiQuotaSnapshot struct {
	CapturedAt time.Time               `json:"captured_at"`
	Windows    []harnesses.QuotaWindow `json:"windows"`
	Source     string                  `json:"source"` // e.g. "pty", "cassette"
	Account    *harnesses.AccountInfo  `json:"account,omitempty"`
	Detail     string                  `json:"detail,omitempty"`
}

GeminiQuotaSnapshot captures parsed Gemini CLI /model manage quota evidence in a durable cache so foreground routing consumers do not invoke PTY capture inline.

Auth/account freshness on its own is NOT quota evidence. Only a parsed GeminiQuotaSnapshot with one or more tier windows promotes Gemini beyond the "quota unknown" state.

func ReadGeminiQuota

func ReadGeminiQuota() (*GeminiQuotaSnapshot, bool)

ReadGeminiQuota reads the default Gemini quota cache.

func ReadGeminiQuotaFrom

func ReadGeminiQuotaFrom(path string) (*GeminiQuotaSnapshot, bool)

ReadGeminiQuotaFrom reads a Gemini quota snapshot from a specific path.

func RefreshGeminiQuotaViaPTY

func RefreshGeminiQuotaViaPTY(timeout time.Duration, opts ...QuotaPTYOption) (GeminiQuotaSnapshot, error)

RefreshGeminiQuotaViaPTY launches the probe and returns a ready-to-write durable snapshot. The Account field is filled from ReadAuthEvidence so the snapshot records auth/account context alongside quota evidence (but the quota decision is still gated on parsed windows, not on Account alone).

func (*GeminiQuotaSnapshot) MaxUsedPercent

func (s *GeminiQuotaSnapshot) MaxUsedPercent() float64

MaxUsedPercent returns the largest used-percent across all tier windows in the snapshot. Returns 0 for nil/empty snapshots.

type QuotaPTYOption

type QuotaPTYOption func(*quotaPTYOptions)

QuotaPTYOption configures a Gemini quota PTY probe.

func WithQuotaPTYCassetteDir

func WithQuotaPTYCassetteDir(dir string) QuotaPTYOption

func WithQuotaPTYCommand

func WithQuotaPTYCommand(binary string, args ...string) QuotaPTYOption

func WithQuotaPTYEnv

func WithQuotaPTYEnv(env ...string) QuotaPTYOption

func WithQuotaPTYWorkdir

func WithQuotaPTYWorkdir(workdir string) QuotaPTYOption

type Runner

type Runner struct {
	// Binary is the absolute path to the gemini executable. When empty the
	// runner resolves "gemini" via PATH at Execute time.
	Binary string

	// BaseArgs is prepended to the per-request argument list.
	// Gemini default: ["--output-format", "stream-json"].
	BaseArgs []string

	// PromptMode controls how the prompt is delivered.
	// "arg" (default) sends "-p <prompt>"; "stdin" sends "-p ”" and writes
	// the prompt to stdin. Gemini requires -p/--prompt for headless mode.
	PromptMode string

	// EventBuffer overrides the per-Execute channel buffer size.
	EventBuffer int
}

Runner is the subprocess-backed gemini harness. It launches gemini in headless mode (-p/--prompt), buffers stream-json stdout, and emits text_delta + final events after the process exits.

When the output is valid JSON with a stats.models token block, usage is extracted per the DDx ExtractUsage("gemini", ...) shape.

func (*Runner) Execute

func (r *Runner) Execute(ctx context.Context, req harnesses.ExecuteRequest) (<-chan harnesses.Event, error)

Execute runs one resolved request through the gemini CLI and emits events on the returned channel. Since gemini has no stream-json mode, events are emitted after the process exits (emit-on-EOF pattern).

func (*Runner) HealthCheck

func (r *Runner) HealthCheck(ctx context.Context) error

HealthCheck verifies the gemini binary is present.

func (*Runner) Info

func (r *Runner) Info() harnesses.HarnessInfo

Info returns identity + capability metadata for this harness.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL