Documentation
¶
Overview ¶
Package gemini is a bespoke client for Google's Gemini generateContent API. It satisfies inference.Client for both the non-streaming (generateContent) and streaming (streamGenerateContent, SSE) paths. Gemini is not plain OpenAI-over-HTTP: the model id lives in the URL path with a ":generateContent" method suffix, and the credential is an "x-goog-api-key" HEADER (not a Bearer token) — so the generic transport client (which assumes a static /chat/completions path and Bearer auth) cannot serve it. The JSON body + per-event decoding are delegated to the shared geminiapi Codec; only wire routing (URL + header + SSE endpoint) lives here.
Index ¶
- func New(key auth.APIKey) (inference.Client, error)
- func NewCounter(key auth.APIKey) (contextcount.ContextCounter, error)
- type Client
- type Counter
- type CounterEndpointError
- type CounterEndpointReason
- type CounterRequestError
- type CounterRequestReason
- type CounterResponseError
- type CounterResponseField
- type CounterResponseFieldError
- type CounterResponseFieldReason
- type CounterResponseReason
- type CounterStateError
- type CounterStateReason
- type RequestBuildError
- type UnsupportedAPIFormatError
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func New ¶
New constructs a Gemini client authenticated with key. It fails closed with *llm.AuthRequiredError when key is empty — no Client and no network object are created — matching the auto.New credential contract for an AuthAPIKey provider.
func NewCounter ¶
func NewCounter(key auth.APIKey) (contextcount.ContextCounter, error)
NewCounter constructs an exact provider counter authenticated with key.
Types ¶
type Client ¶
type Client struct {
// contains filtered or unexported fields
}
Client is a Gemini generateContent inference client. It owns one Authenticator (the x-goog-api-key header) and one http.Client, and is safe for concurrent use (both are immutable after construction). Binding is by provider: a request whose Model.Provider is not ProviderGoogle is rejected pre-I/O with *failure.ModelMismatchError. The endpoint base is fixed at construction.
func (*Client) Invoke ¶
Invoke sends a non-streaming generateContent request and returns the decoded response. Ordered, all pre-I/O guards first (preflight), then: build the ctx-bound POST to <base>/models/<name>:generateContent, set the x-goog-api-key header, do, map transport/non-2xx failures, and decode the Gemini response.
func (*Client) Stream ¶
func (c *Client) Stream(ctx context.Context, req inference.Request) (*stream.StreamReader[content.Chunk], error)
Stream sends a streamGenerateContent request and, on 2xx, returns a chunk reader that de-frames the SSE body and decodes each event via the shared codec. The body is identical to Invoke's (Gemini streaming is an endpoint + ?alt=sse concern, not a body field). Same ordered pre-I/O guards. A non-2xx status maps to *failure.APIError (body drained + closed first); on 2xx the codec's DecodeStream takes ownership of the response body and closes it via the returned reader's Close. Gemini SSE has no [DONE] sentinel — the sse framer returns io.EOF at body end, which the reader surfaces normally.
type Counter ¶
type Counter struct {
// contains filtered or unexported fields
}
Counter is a separately constructed Gemini countTokens client. It is not embedded in Client so an inference client can never acquire the optional ContextCounter capability accidentally.
func (*Counter) CountContext ¶
func (c *Counter) CountContext(ctx context.Context, req inference.Request) (contextcount.ContextCount, error)
CountContext sends the complete encoded inference request to countTokens.
func (*Counter) CounterCapability ¶
func (c *Counter) CounterCapability() contextcount.CounterCapability
CounterCapability declares countTokens as exact provider counting over the same Google API endpoint, conservatively allowing provider logging.
type CounterEndpointError ¶
type CounterEndpointError struct {
Reason CounterEndpointReason
}
CounterEndpointError rejects unsafe counter routing before any request I/O. The raw endpoint is deliberately omitted because it may contain credentials.
func (*CounterEndpointError) Error ¶
func (e *CounterEndpointError) Error() string
type CounterEndpointReason ¶
type CounterEndpointReason string
CounterEndpointReason classifies an endpoint that cannot safely carry a countTokens request. Values never include the rejected endpoint or credentials.
const ( CounterEndpointMalformed CounterEndpointReason = "malformed endpoint" CounterEndpointMissingHost CounterEndpointReason = "missing endpoint host" CounterEndpointCredentials CounterEndpointReason = "endpoint contains credentials" CounterEndpointUnsupportedScheme CounterEndpointReason = "unsupported endpoint scheme" CounterEndpointInsecureTransport CounterEndpointReason = "plaintext endpoint is not loopback" CounterEndpointNonASCIIHost CounterEndpointReason = "endpoint host is not ASCII" CounterEndpointInvalidHost CounterEndpointReason = "invalid endpoint host" CounterEndpointAmbiguousPath CounterEndpointReason = "ambiguous escaped endpoint path" )
type CounterRequestError ¶
type CounterRequestError struct {
Reason CounterRequestReason
Err error
}
CounterRequestError reports a local countTokens envelope invariant failure. It never carries request bytes or the model name.
func (*CounterRequestError) Error ¶
func (e *CounterRequestError) Error() string
func (*CounterRequestError) Unwrap ¶
func (e *CounterRequestError) Unwrap() error
type CounterRequestReason ¶
type CounterRequestReason string
CounterRequestReason classifies failure to build the countTokens envelope from the already encoded complete GenerateContentRequest.
const ( CounterRequestGenerateBodyInvalid CounterRequestReason = "generateContentRequest body is not one JSON object" CounterRequestModelEncodingFailed CounterRequestReason = "model resource JSON encoding failed" CounterRequestModelCollision CounterRequestReason = "generateContentRequest already contains model" )
type CounterResponseError ¶
type CounterResponseError struct {
Reason CounterResponseReason
Err error
}
CounterResponseError reports an invalid successful countTokens response. Provider payload bytes are deliberately omitted so Error never leaks request or response data; Err carries only a typed/safe parsing cause.
func (*CounterResponseError) Error ¶
func (e *CounterResponseError) Error() string
func (*CounterResponseError) Unwrap ¶
func (e *CounterResponseError) Unwrap() error
type CounterResponseField ¶
type CounterResponseField string
CounterResponseField identifies one field in a countTokens response.
const CounterResponseFieldTotalTokens CounterResponseField = "totalTokens"
type CounterResponseFieldError ¶
type CounterResponseFieldError struct {
Field CounterResponseField
Reason CounterResponseFieldReason
}
CounterResponseFieldError reports a field-level response ambiguity without retaining provider-controlled values.
func (*CounterResponseFieldError) Error ¶
func (e *CounterResponseFieldError) Error() string
type CounterResponseFieldReason ¶
type CounterResponseFieldReason string
CounterResponseFieldReason classifies an ambiguous response field.
const CounterResponseFieldDuplicate CounterResponseFieldReason = "duplicate"
type CounterResponseReason ¶
type CounterResponseReason string
CounterResponseReason classifies a countTokens response that cannot produce a trustworthy normalized input-token count.
const ( CounterResponseMalformed CounterResponseReason = "malformed response" CounterResponseMissingCount CounterResponseReason = "missing totalTokens" CounterResponseInvalidCount CounterResponseReason = "invalid totalTokens" CounterResponseDuplicateField CounterResponseReason = "duplicate response field" CounterResponseBodyTooLarge CounterResponseReason = "response body too large" )
type CounterStateError ¶
type CounterStateError struct {
Reason CounterStateReason
}
CounterStateError rejects an invalid counter before request encoding or I/O.
func (*CounterStateError) Error ¶
func (e *CounterStateError) Error() string
type CounterStateReason ¶
type CounterStateReason string
CounterStateReason classifies an unusable Counter or CountContext boundary.
const ( CounterStateNilReceiver CounterStateReason = "nil counter" CounterStateNilContext CounterStateReason = "nil context" CounterStateMissingEndpoint CounterStateReason = "missing endpoint" CounterStateMissingAuthenticator CounterStateReason = "missing authenticator" CounterStateMissingHTTPDoer CounterStateReason = "missing HTTP doer" CounterStateInvalidTimeout CounterStateReason = "invalid timeout" )
type RequestBuildError ¶
type RequestBuildError struct {
Err error
}
RequestBuildError is a failure to CONSTRUCT the outbound HTTP request (a malformed endpoint/URL), kept distinct from *failure.NetworkError (reserved for transport failures out of hc.Do) so errors.As never misclassifies a config bug as a transport fault. Unwrap exposes the net/http cause.
func (*RequestBuildError) Error ¶
func (e *RequestBuildError) Error() string
func (*RequestBuildError) Unwrap ¶
func (e *RequestBuildError) Unwrap() error
type UnsupportedAPIFormatError ¶
UnsupportedAPIFormatError is a fail-closed rejection, before any I/O, of a request whose Model.APIFormat this client cannot honor. This client encodes only the Gemini generateContent dialect. Provider.supportsAPIFormat currently admits only APIFormatGemini for ProviderGoogle, so a ValidateModel-passing Google Model can never reach this guard — it is defense-in-depth (Open/Closed): should a second Google dialect ever be admitted upstream, this keeps the client from silently Gemini-encoding a request it does not understand. Carries the offending format so callers can branch via errors.As.
func (*UnsupportedAPIFormatError) Error ¶
func (e *UnsupportedAPIFormatError) Error() string