vertexcache

package
v2.7.0-dev.5 Latest Latest
Warning

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

Go to latest
Published: Jul 20, 2026 License: Apache-2.0 Imports: 6 Imported by: 0

Documentation

Overview

Package vertexcache owns the lifecycle of a single Vertex explicit context cache — Create at agent startup, Refresh on TTL pressure, Delete on session unregister. Callers read the resolved cache name via Name() to plumb it onto GenerateContentConfig.CachedContent per turn.

See docs/vertex-context-caching-design.md for the v1 scope (system-instruction + tools; not conversation history) and the failure-mode contract (every error path degrades to "no cache for this call," never breaks the session).

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type CachesClient

CachesClient is the subset of *genai.Client's Caches field that the manager depends on. Wrapping it in an interface keeps the manager unit-testable without a real Vertex client — the fake in manager_test.go implements the same shape.

type Manager

type Manager struct {
	// contains filtered or unexported fields
}

Manager owns one cache handle. Init creates it lazily (called from pkg/models/gemini on the first GenerateContent that carries a system instruction we can cache); Name returns the resolved name or "" if not yet ready; Refresh extends TTL when it's about to expire; Delete cleans up on shutdown.

Manager is safe for concurrent use. Name() is called from every turn's GenerateContent — the read path is a plain RLock, cheap.

func NewManager

func NewManager(caches CachesClient, model string, opts Options) *Manager

NewManager returns a Manager bound to caches + model. model is the same modelID passed to Caches.Create — must match the model the referencing GenerateContent call uses (Vertex enforces this).

func (*Manager) Delete

func (m *Manager) Delete(ctx context.Context)

Delete releases the Vertex cache. Best-effort — failures are logged but don't propagate. Callers should invoke this on session unregister / daemon shutdown; skipping the call is fine (Vertex reaps expired caches) but leaves the cache resource around until TTL elapses.

Idempotent: safe to call multiple times, and safe to call before Init has landed (skips the RPC if there's no cache to delete).

func (*Manager) Init

func (m *Manager) Init(ctx context.Context, systemInstruction *genai.Content, tools []*genai.Tool)

Init kicks off cache creation with the given systemInstruction + tools. Non-blocking: returns immediately after a state check; the actual Create RPC runs on a background goroutine so the caller (typically the first GenerateContent call) doesn't wait.

Called at-most-once — subsequent calls with the manager already initializing / active are no-ops. This is by design: once we've seeded the cache from turn N's config, turn N+1's config should be identical (both come from the same agent's system instruction + tools slice), so re-Init would be wasted RPCs.

func (*Manager) MarkEvicted

func (m *Manager) MarkEvicted(reason string)

MarkEvicted resets the manager to its pre-Init state after learning (via a GenerateContent NOT_FOUND on the cache reference) that Vertex has reaped our cache server-side. Callers who see the eviction — the pkg/models/gemini wrapper's retry-once path — invoke this so:

  1. Subsequent Name() calls return "" (the request goes uncached).
  2. The next non-cached turn can call Init again and get a fresh cache handle instead of the agent running uncached for the rest of its lifetime.

Distinct from stateFailed (which stays sticky — a Create failure at Init time signals a persistent problem worth surfacing). Eviction is a normal end-of-TTL event, especially on long-lived daemons whose cache outlives a single session.

Idempotent + safe against races with in-flight Refresh: a refresh that lands after MarkEvicted just sees state != active and no-ops.

func (*Manager) Name

func (m *Manager) Name(ctx context.Context) string

Name returns the resolved cache name if the manager is active, or "" if init hasn't landed yet / failed / been deleted. Callers wire the return value into GenerateContentConfig.CachedContent — an empty value means the request runs uncached, which is always safe.

Name also opportunistically triggers a background Refresh if the active cache is inside its refresh window. The refresh runs asynchronously; the current call still returns the (about-to-expire but still-valid) cache name.

func (*Manager) Snapshot

func (m *Manager) Snapshot() Status

Snapshot returns the current manager state. Cheap — RLock-only.

type Options

type Options struct {
	// TTL is how long each Create/Update requests the cache live for.
	// Vertex caps at 24h; the daemon's default matches the session
	// idle timeout (6h). Zero → 6h.
	TTL time.Duration
	// RefreshThreshold triggers a background Refresh call when Name()
	// is read and time-to-expiry drops below this value. Zero → 30min.
	RefreshThreshold time.Duration
	// DisplayName annotates the cache in Vertex's list view. Optional
	// — omitted from Create when empty.
	DisplayName string
	// Logger receives structured operator-facing warnings when a
	// Caches RPC fails. Zero → log.Default() ("core-agent-vertexcache:"
	// prefix included).
	Logger *log.Logger
}

Options configures a Manager. Defaults come from docs/vertex-context-caching-design.md — TTL 6h, Refresh threshold 30min. Zero values pick the default; callers that want the default for both fields can pass Options{}.

type Status

type Status struct {
	Active    bool
	Failed    bool
	CacheName string
	ExpiresAt time.Time
	ExpiresIn time.Duration
}

Status is a snapshot of the manager's state for diagnostic use (e.g. an /internal/cache-status endpoint or a startup log line once init settles). Read-only; each call takes a fresh RLock.

func (Status) String

func (s Status) String() string

String is a short human-readable form used by the startup log line ("context cache: active (cache_id=..., ttl=5h59m)").

Jump to

Keyboard shortcuts

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