Skip to content

GeminiClient

Viames Marino edited this page Apr 25, 2026 · 1 revision

Pair framework: 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 generateContent calls for text, chat-style, tool-capable, and multimodal model responses
  • stateless chat helpers that accept user, assistant, and system message 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.

Configuration

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=5

Keys:

  • GEMINI_API_KEY is required before outbound API calls.
  • GEMINI_API_BASE_URL defaults to the Gemini REST API base URL.
  • GEMINI_GENERATION_MODEL is the default model for generateContent.
  • GEMINI_EMBEDDINGS_MODEL is the default model for embedContent.

Extension path

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.

Constructor

__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.

Main methods

  • apiKeySet(): bool
  • generateContent(string|array $contents, array $options = []): array
  • generateText(string|array $contents, array $options = []): string
  • chat(array $messages, array $options = []): array
  • chatText(array $messages, array $options = []): string
  • createEmbeddingResponse(string|array $content, array $options = []): array
  • embedText(string $input, array $options = []): array
  • extractText(array $response): string
  • extractEmbeddingVector(array $response): array

Text Generation

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.',
]);

Chat

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.

Embeddings

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.

Safe Logging

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_id or document_id
  • error code and sanitized error message

Operational Notes

  • Keep GEMINI_API_KEY in .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.

Gemini References

See also: API, Integrations, AdapterRegistry, JsonResponse, OpenAIClient, ClaudeClient.

Clone this wiki locally