@use-crux/google
Google GenAI SDK adapter, factory pattern with provider caching plus dense embedding helpers.
Google message content supports native image, audio, video, and documents.
Specialized exports include Imagen/Gemini-native generateImage(), finite
Interactions streamImage(), native Gemini generateSpeech() (including
two-speaker configuration), finite TTS streamSpeech(), and composed
transcribe(). Composed transcription returns text with no word timing or
diarization and rejects those requests before I/O. Endpoint-specific options
stay separated in typed extra records.
All five specialized media operations use the portable media-operation Safety contracts;
canonical audits are returned in result.safety, while
provider-native raw values remain unguarded. See the
content-primitive matrix.
Peer dependency: @google/genai (^2.0.0)
import {
createGoogle,
embedding,
googleProviderRuntime,
googleTranscript,
toMessages,
fromMessages,
} from "@use-crux/google";
import { createGenerateObjectFn, createGenerateTextFn } from "@use-crux/google";For media workflows, start with Media and multimodal,
then use Streaming generated media for
streamImage() and streamSpeech(). For text usage and provider comparison,
see the Execution guide.
Request capacity and counting
The adapter exposes adapter.capacity(model) and the standalone
googleModelCapacity(model) helper. Capacity lookup is synchronous and does
not create or read CachedContent.
import { googleModelCapacity } from "@use-crux/google";
const profile = googleModelCapacity("gemini-2.5-flash");| Known model-id prefix | Context window | Default output reserve |
|---|---|---|
gemini-3 | 1,048,576 | 65,536 |
gemini-2.5 | 1,048,576 | 65,536 |
gemini-2.0 | 1,048,576 | 8,192 |
gemini-1.5-pro | 2,097,152 | 8,192 |
gemini-1.5-flash | 1,048,576 | 8,192 |
Versioned aliases inherit their family profile. Unknown identifiers use a
conservative 32,768-token window with an 8,192-token reserve. Known profiles
report countingConfidence: "estimated"; the fallback reports
"conservative".
The adapter does not call a provider token-count endpoint. Crux estimates the complete request and reports the applied margin in request inspection. Cached input can reduce provider billing, but it does not reduce the model context capacity used for fit.
createGoogle(client, opts?)
Create an adapter bound to a Google GenAI client with optional CachedContent configuration.
createGoogle() is the package's mapped single-turn bundle factory: it resolves the CachedContent option into a single GoogleCachedContentLifecycle, passes it into the provider runtime, and returns the bound adapter. The lifecycle owns prefix detection, cache keying/reuse, SDK cache operations, and fallback policy, and returns a request-ready config patch that both generate() and stream() merge. The package-owned googleTranscript owns Content[] conversion plus assistant text/function-call extraction. The Google package still owns the SDK request shape, function-call normalization, and response metadata normalization; the provider runtime supplies the adapter shell and default tool-round formatting.
Google content support maps image/file data to inlineData and URL-backed image/file parts to fileData when mediaType is present. URL-backed parts without a MIME type fail before the provider call. Assistant inline/file media decodes back into canonical content, and function-response media uses the same part table as messages.
| Field | Type | Description |
|---|---|---|
client | GoogleGenAI | The Google GenAI client instance |
opts.cachedContent | false | GoogleCacheConfig | GoogleCachedContentLifecycle | CachedContent configuration. Omit for defaults, pass false to disable, or pass a fully custom lifecycle. |
GoogleCacheConfig:
| Field | Type | Default | Description |
|---|---|---|---|
enabled | boolean | true | Enable/disable the built-in lifecycle |
defaultTtlSeconds | number | 300 | TTL for server-side cache objects |
maxEntries | number | 50 | Max concurrent cache entries in memory |
onError | 'fallback' | 'throw' | 'fallback' | Whether cache operation failures fall back to an inline systemInstruction or reject |
port | GoogleCachedContentCachePort | SDK-backed | Override the create/delete boundary while keeping built-in keying, TTL, and eviction. |
GoogleCachedContentCachePort:
interface GoogleCachedContentCachePort {
create(input: {
model: string;
systemInstruction: string;
ttlSeconds: number;
}): Promise<GoogleCacheName | undefined>;
delete(input: { name: GoogleCacheName }): Promise<void>;
}Returns:
| Method | Description |
|---|---|
.generate(prompt, options) | Execute a prompt via Google GenAI with Zod validation (structured) or text generation |
.stream(prompt, options) | Stream a prompt execution |
.generateImage(options) | Generate/edit completed Imagen or Gemini-native images |
.transcribe(options) | Run one honest composed audio-to-text generation |
.generateSpeech(options) | Generate completed single- or two-speaker audio |
.streamImage(options) | Stream current finite Interactions image deltas |
.streamSpeech(options) | Stream finite Generate Content raw-PCM speech bytes |
.prepare(prompt, options) | Prepare a sans-I/O call handle with Google params |
.retrievalModel(config) | Bind Google generation to core retrieval recipe steps |
.reranker(config) | Create a judge-backed core Reranker |
import { createGoogle } from "@use-crux/google";
import { GoogleGenAI } from "@google/genai";
const adapter = createGoogle(
new GoogleGenAI({ apiKey: process.env.GOOGLE_API_KEY }),
);
const result = await adapter.generate(sentiment, {
model: "gemini-2.5-flash",
input: { text: "Great product!" },
});
result.text;
result.usage;
result.finalStep;When the leading resolved system blocks have providerCache: true, the
adapter automatically creates and reuses a Google CachedContent object for
that prefix, then sends any uncached remainder as systemInstruction. A
single GoogleCachedContentLifecycle owns prefix detection, cache
keying/reuse, SDK cache operations, and fallback policy, and returns a
request-ready config patch. createGoogle() builds it; generate() and
stream() only merge the patch, so the cache lifecycle never leaks into core.
// Custom CachedContent configuration
const adapter = createGoogle(client, {
cachedContent: { defaultTtlSeconds: 600, maxEntries: 100 },
});
// Surface cache failures instead of silently falling back
const strict = createGoogle(client, { cachedContent: { onError: "throw" } });
// Disable caching entirely
const adapter = createGoogle(client, { cachedContent: false });
// Back caching with a custom cache port, or pass a fully custom lifecycle
const custom = createGoogle(client, { cachedContent: { port: myCachePort } });
// Skip or tune cache lifecycle for one request
await adapter.generate(prompt, {
model: "gemini-2.5-flash",
extra: { cachedContent: { ttlSeconds: 600 } },
});adapter.generate(prompt, options)
| Field | Type | Description |
|---|---|---|
prompt | Prompt | The prompt to execute |
options.model | string | Model name |
options.input | object | Input values |
options.tools | Record<string, unknown>? | Additional Crux tools to merge at call time |
options.toolMiddleware | ToolMiddleware | readonly ToolMiddleware[]? | Tool execution hooks, including Crux resumable approvals through result.messages. |
options.toolApproval | ToolApprovalMap? | Call-site approval policy; exact tool names beat '*'. |
options.toolsContext | Record<string, unknown>? | Required for composed tools that declare contextSchema; values are Zod-validated before the tool loop starts. |
options.runtimeContext | unknown? | Shared per-run context visible to tool execute, middleware, and function-form toolApproval policies. |
options.transport | (params, info) => Promise<GenerateContentResponse> | BYO wire call. Crux still owns tools, approvals, validation retry, routing, and timeouts. |
options.extra.tools | GoogleFunctionDeclaration[]? | Google-native function declarations that bypass Crux tool conversion |
options.temperature | number? | Temperature |
options.maxOutputTokens | number? | Max output tokens |
options.topP | number? | Top-p sampling |
options.topK | number? | Top-k sampling |
options.extra.cachedContent.skip | boolean? | Skip caching for this call |
options.extra.cachedContent.ttlSeconds | number? | TTL in seconds for a newly-created cache on this call |
Returns: normalized Crux generate result with:
result.text: extracted assistant textresult.usage: accumulated usage when every provider-call step reported usageresult.cost: provider-reported cost when availableresult.finalStep: final provider-call text, usage, finish reason, response id, and actual model idresult.raw: raw Google SDK responseresult._meta: retained trace metadata for observability plumbingresult.usage?.inputTokenDetails.cacheReadTokens: tokens served from cache when available
Structured output is validated with Zod after generation. Invalid JSON from the model produces a Zod error, not a Google SDK error.
adapter.stream(prompt, options)
Stream a prompt execution.
| Field | Type | Description |
|---|---|---|
prompt | Prompt | The prompt to execute |
options.model | string | Model name |
options.input | object | Input values |
options.tools | Record<string, unknown>? | Additional Crux tools to merge at call time |
options.toolMiddleware | ToolMiddleware | readonly ToolMiddleware[]? | Tool execution hooks, including Crux resumable approvals through result.messages. |
options.toolApproval | ToolApprovalMap? | Call-site approval policy; exact tool names beat '*'. |
options.toolsContext | Record<string, unknown>? | Required for composed tools that declare contextSchema; values are Zod-validated before the tool loop starts. |
options.runtimeContext | unknown? | Shared per-run context visible to tool execute, middleware, and function-form toolApproval policies. |
options.extra.tools | GoogleFunctionDeclaration[]? | Google-native function declarations that bypass Crux tool conversion |
options.temperature | number? | Temperature |
options.maxOutputTokens | number? | Max output tokens |
options.topP | number? | Top-p sampling |
options.topK | number? | Top-k sampling |
options.extra.cachedContent.skip | boolean? | Skip caching for this call |
options.extra.cachedContent.ttlSeconds | number? | TTL in seconds for a newly-created cache on this call |
Returns: StreamResult<TOutput, TPartial>:
result.textStream: published, Safety-final text deltasresult.fullStream: every published logical event in canonical orderresult.partialOutputStream: canonical partialz.inputfor a structured promptresult.completion: promise resolving to the canonical completion envelope (text, optionalobject, optionalusage, optionalcost,steps,finalStep,messages, and pending approvals)result.cancel(reason?): abort the whole logical operation, including the active provider attempt
There is deliberately no raw on a managed stream: a provider stream resolves
before terminal Safety and describes only one attempt, so exposing it would
bypass guardrail holds, structured occurrence gating, commit gates, and
validation retry.
Media operations
Completed and streaming image, transcription, and speech behavior is documented
separately in Google media operations.
That page owns native endpoints, typed extra namespaces, model gates,
terminal raw types, stream framing, and composed-transcription limits.
toParams(resolved, options) / fromResponse(response)
toParams() converts a ResolvedPrompt plus { model, settings?, extra? }
into Google generateContent params. ResolvedPrompt does not include a
model, so options.model is required. Pass cachedContentLifecycle when codec
calls should use a Google CachedContent planner; otherwise the codec uses the
inline disabled-cache fallback.
fromResponse() normalizes a Google response into Crux AdapterResponse
facts. These codecs are translation-only. Use managed generate()/stream()
when Crux should run tools, approvals, validation retry, memory capture,
safety, and observability.
adapter.prepare(prompt, options)
Prepare a headless Google call. Crux resolves the prompt and returns public
Google params without making the SDK call. Feed a raw GenerateContentResponse
back with finish(response), or use step(response) when tools, validation
retry, or approval suspension may need another provider turn.
generate(prompt, { ...options, transport }) is the BYO-wire mode where Crux
keeps owning the loop and invokes your callback for each Google request.
stream() with transport is intentionally unsupported and rejects with
CruxTransportStreamUnsupportedError.
adapter.retrievalModel(config)
Create a core RetrievalModel from the adapter instance.
const retrievalModel = adapter.retrievalModel({ model: "gemini-2.5-flash" });Use it as a recipe-level model or step-level model.
adapter.reranker(config)
Create a core Reranker for rerank({ engine }).
const engine = adapter.reranker({
model: "gemini-2.5-flash",
topN: 12,
});Google's direct SDK adapter does not expose a native rerank endpoint. adapter.reranker() uses Crux's judgeReranker() over the configured Google model, so each rerank call spends generation tokens.
toMessages(sdkMessages)
Convert Google Content[] to canonical Message[].
| Field | Type | Description |
|---|---|---|
sdkMessages | Content[] | Google GenAI content messages |
Returns: Message[]
fromMessages(messages)
Convert canonical Message[] to Google Content[].
| Field | Type | Description |
|---|---|---|
messages | Message[] | Canonical messages |
Returns: Content[]
Assistant tool calls become functionCall parts and tool results become functionResponse parts. When Google does not provide a tool-call id, the adapter synthesizes stable per-turn ids such as tc_0 for the Crux tool round.
googleTranscript is the lower-level NativeTranscriptCodec used by createGoogle(). The public toMessages() and fromMessages() wrappers delegate to it.
createGenerateObjectFn(client)
Create a provider-native GenerateObjectFn bound only to a client. Every call
must supply a non-empty Google model id.
| Field | Type | Description |
|---|---|---|
client | GoogleGenAI | Google GenAI client instance |
Returns: GenerateObjectFn
const generateObject = createGenerateObjectFn(client);
const { object } = await generateObject({
model: "gemini-2.5-flash",
messages,
schema,
});This helper uses the same native chat profile and media codec as
createGoogle(). It accepts exactly one of prompt or canonical messages,
uses Google GenAI structured JSON output, and returns { object } while
preserving provider errors. It does not run Crux prompt resolution, validation
retry, safety, tools, memory capture, or instrumentation.
createGenerateTextFn(client, model)
Create a GenerateTextFn bound to a client and model.
| Field | Type | Description |
|---|---|---|
client | GoogleGenAI | Google GenAI client instance |
model | string | Model name |
Returns: GenerateTextFn
embedding(client, config)
Create a dense Crux embedding backed by client.models.embedContent().
import { GoogleGenAI } from "@google/genai";
import { embedding } from "@use-crux/google";
const client = new GoogleGenAI({ apiKey: process.env.GOOGLE_API_KEY });
const docsEmbedding = embedding(client, {
model: "gemini-embedding-2",
});
await docsEmbedding.embed("dog", { role: "query" });
await docsEmbedding.embed({ type: "image", source: dogPhoto });Known literal model ids infer verified modality tuples. gemini-embedding-2
defaults to text, image, audio, video, and document inputs, the model id as its
Crux name, 3072 dimensions, and an 8192-token text limit. Unknown or dynamic
model ids conservatively default to text-only and require explicit sizing.
Google's SDK returns token counts per embedded input when available, and the
Crux helper aggregates them into embedding usage metadata automatically.
| Field | Type | Description |
|---|---|---|
client | GoogleGenAI | Google GenAI client instance |
config.name | string? | Stable embedding identifier; Gemini Embedding 2 defaults to the model id. |
config.model | string | Google embedding model |
config.modalities | EmbeddingModality[]? | Explicit native modalities; overrides known-model defaults. |
config.dimensions | number? | Output dimensions; Gemini Embedding 2 defaults to 3072. |
config.maxInputTokens | number? | Text token ceiling; Gemini Embedding 2 defaults to 8192. |
config.batch.maxSize | number? | Top-level Crux batch size. Defaults to 100. |
config.batch.concurrency | number? | Top-level Crux batch concurrency. Defaults to 1. |
config.tasks | { query?: string; document?: string }? | Role-specific task types for models that support them. |
config.title | string? | Document title. Only applies to retrieval-document tasks. |
config.mimeType | string? | Optional input MIME type |
config.autoTruncate | boolean? | Vertex-only truncation behavior |
config.version | string? | Extra vector-semantic revision for cache invalidation |
The helper fingerprint includes model, both role task types, title, MIME type,
and auto-truncation behavior, then appends version when supplied. Operational
batch settings do not change that identity. Gemini Embedding 2 does not accept
taskType; put its text retrieval instruction in the input instead.
Types
import type {
CreateGoogleOptions,
GoogleCacheConfig,
GoogleCacheName,
GoogleCachedContentCachePort,
GoogleCachedContentCallOptions,
GoogleCachedContentErrorMode,
GoogleCachedContentLifecycle,
GoogleCachedContentOption,
GoogleCachedContentPlan,
GoogleCachedContentPrepareArgs,
GoogleEmbeddingConfig,
GoogleExtra,
GoogleFunctionDeclaration,
GoogleRequest,
} from "@use-crux/google";Related
- Guide: Execution
- Guide: Embeddings
- Reference: Prompts
- Reference: @use-crux/ai (Vercel AI SDK)