-
Notifications
You must be signed in to change notification settings - Fork 2
GeminiClient
Pair\Services\GeminiClient is a lightweight HTTP client for the Gemini API.
It focuses on the integration paths Pair applications need most often:
- native
generateContentcalls for text, chat-style, tool-capable, and multimodal model responses - stateless chat helpers that accept
user,assistant, andsystemmessage roles - single-content embeddings for semantic search and document indexing
The Pair core does not require a Gemini SDK. The client uses cURL and keeps the provider dependency optional.
GEMINI_API_KEY=
GEMINI_API_BASE_URL="https://generativelanguage.googleapis.com/v1beta"
GEMINI_GENERATION_MODEL=gemini-2.5-flash
GEMINI_EMBEDDINGS_MODEL=gemini-embedding-2
GEMINI_TIMEOUT=30
GEMINI_CONNECT_TIMEOUT=5Keys:
-
GEMINI_API_KEYis required before outbound API calls. -
GEMINI_API_BASE_URLdefaults to the Gemini REST API base URL. -
GEMINI_GENERATION_MODELis the default model forgenerateContent. -
GEMINI_EMBEDDINGS_MODELis the default model forembedContent.
Pair v4 integrations should be registered explicitly. An application can expose Gemini as the AI adapter:
use Pair\Core\AdapterKeys;
use Pair\Core\Application;
use Pair\Services\GeminiClient;
$app = Application::getInstance();
$app->setAdapter(AdapterKeys::AI, new GeminiClient());
$ai = $app->adapter(AdapterKeys::AI, GeminiClient::class);This keeps Gemini optional and avoids automatic package discovery.
__construct(?string $apiKey = null, ?string $apiBaseUrl = null, ?string $generationModel = null, ?string $embeddingsModel = null, ?int $timeout = null, ?int $connectTimeout = null)
Creates the client with explicit values or Env defaults.
apiKeySet(): boolgenerateContent(string|array $contents, array $options = []): arraygenerateText(string|array $contents, array $options = []): stringchat(array $messages, array $options = []): arraychatText(array $messages, array $options = []): stringcreateEmbeddingResponse(string|array $content, array $options = []): arrayembedText(string $input, array $options = []): arrayextractText(array $response): stringextractEmbeddingVector(array $response): array
Use generateContent() when the caller needs the full Gemini response.
use Pair\Http\JsonResponse;
use Pair\Services\GeminiClient;
$client = new GeminiClient();
$response = $client->generateContent('Summarize this support ticket.', [
'system_instruction' => 'Return concise Italian text.',
'max_output_tokens' => 300,
]);
return new JsonResponse([
'text' => GeminiClient::extractText($response),
]);Use generateText() for the common text-only case:
use Pair\Services\GeminiClient;
$client = new GeminiClient();
$summary = $client->generateText('Summarize this CRM note.', [
'system_instruction' => 'Return one sentence.',
]);Gemini chat is stateless at the HTTP layer. Store conversation state in the Pair application and send the relevant history on each turn.
use Pair\Services\GeminiClient;
$client = new GeminiClient();
$answer = $client->chatText([
['role' => 'system', 'content' => 'You answer in Italian.'],
['role' => 'user', 'content' => 'Ciao, chi sei?'],
]);assistant roles are mapped to Gemini's model role. system messages are lifted into systemInstruction.
Use embedText() for one document chunk:
use Pair\Services\GeminiClient;
$client = new GeminiClient();
$vector = $client->embedText('Document chunk to index.', [
'output_dimensionality' => 768,
]);For batch indexing, call embedText() per project-owned chunk or use a project-level background job. GeminiClient does not persist embeddings.
Do not log raw prompts, uploaded files, model outputs, tool outputs, embeddings, or chat transcripts by default.
Prefer logging operational metadata only:
- endpoint or feature name
- selected model
- request duration
- token usage from the API response
- project-side entity IDs such as
ticket_idordocument_id - error code and sanitized error message
- Keep
GEMINI_API_KEYin.env, never in Git. - Keep provider-specific domain mapping in project services, not controllers.
- Store chatbot history in project-owned tables when the application needs memory.
- For semantic search, store vectors in project-owned tables or a search adapter.
See also: API, Integrations, AdapterRegistry, JsonResponse, OpenAIClient, ClaudeClient.