Polyglot Package Cheatsheet¶
Code-verified API reference for packages/polyglot.
Core Facades¶
use Cognesy\Polyglot\Inference\Inference;
use Cognesy\Polyglot\Embeddings\Embeddings;
use Cognesy\Polyglot\Decision\Decision;
$inference = new Inference();
$embeddings = new Embeddings();
$decision = new Decision();
Inference Quick Start¶
Use a preset for the normal path:
use Cognesy\Polyglot\Inference\Inference;
use Cognesy\Messages\Messages;
$message = Inference::using('openai')
->withModel('gpt-4.1-nano')
->withMessages(Messages::fromString('Say hello in one sentence.'))
->get();
$text = $message->content()->toString();
Get parsed JSON:
use Cognesy\Polyglot\Inference\Data\ResponseFormat;
$data = Inference::using('openai')
->withModel('gpt-4.1-nano')
->withResponseFormat(ResponseFormat::jsonObject())
->withMessages(Messages::fromString('Return JSON with key "ok".'))
->asJsonData();
Inference Constructors¶
use Cognesy\Polyglot\Inference\Config\LLMConfig;
use Cognesy\Polyglot\Inference\Inference;
use Cognesy\Polyglot\Inference\InferenceRuntime;
use Cognesy\Polyglot\Inference\LLMProvider;
$inference = new Inference();
$inference = Inference::using('openai');
$inference = Inference::fromConfig(LLMConfig::fromPreset('openai'));
$inference = Inference::fromProvider(LLMProvider::using('openai'));
$inference = Inference::fromRuntime(
InferenceRuntime::fromConfig(LLMConfig::fromPreset('openai')),
);
$inference = $inference->withRuntime(
InferenceRuntime::fromConfig(LLMConfig::fromPreset('openai')),
);
Inference Request Builder Methods¶
use Cognesy\Messages\Messages;
use Cognesy\Polyglot\Inference\Config\InferenceRetryPolicy;
use Cognesy\Polyglot\Inference\Data\ResponseFormat;
use Cognesy\Polyglot\Inference\Data\ToolChoice;
use Cognesy\Polyglot\Inference\Data\ToolDefinitions;
use Cognesy\Polyglot\Inference\Enums\ResponseCachePolicy;
$inference = Inference::using('openai')
->withMessages($messages) // Messages
->withModel('gpt-4.1-nano')
->withMaxTokens(800)
->withTools($tools) // ToolDefinitions
->withToolChoice(ToolChoice::auto())
->withResponseFormat($responseFormat) // ResponseFormat
->withOptions(['temperature' => 0])
->withStreaming(true)
->withResponseCachePolicy(ResponseCachePolicy::Memory)
->withRetryPolicy(new InferenceRetryPolicy(maxAttempts: 3))
->withCachedContext(
messages: $cachedMessages, // ?Messages
tools: $cachedTools, // ?ToolDefinitions
toolChoice: ToolChoice::auto(),
responseFormat: $cachedResponseFormat, // ?ResponseFormat
);
Single-call variant:
$inference = Inference::using('openai')->with(
messages: $messages, // ?Messages
model: 'gpt-4.1-nano',
tools: $tools, // ?ToolDefinitions
toolChoice: ToolChoice::auto(),
responseFormat: $responseFormat, // ?ResponseFormat
options: ['temperature' => 0],
);
With explicit request:
use Cognesy\Messages\Messages;
use Cognesy\Polyglot\Inference\Data\InferenceRequest;
$request = new InferenceRequest(
messages: Messages::fromString('Hello'),
model: 'gpt-4.1-nano',
);
$pending = Inference::using('openai')
->withRequest($request)
->create();
Inference Execution Surfaces¶
$pending = $inference->create();
$message = $inference->get();
$response = $inference->response();
$json = $inference->asJson();
$data = $inference->asJsonData();
$toolJson = $inference->asToolCallJson();
$toolData = $inference->asToolCallJsonData();
$stream = $inference->stream();
$isStreamed = $pending->isStreamed();
$message = $pending->get();
$response = $pending->response();
$json = $pending->asJson();
$data = $pending->asJsonData();
$toolJson = $pending->asToolCallJson();
$toolData = $pending->asToolCallJsonData();
$stream = $pending->stream();
Reasoning, Model Facts, and Pricing¶
Reasoning is projected from the ordered assistant message:
$reasoning = $response->message()->reasoningContent();
foreach ($stream->deltas() as $delta) {
echo $delta->messageChunks->reasoningDelta();
}
Read model facts using one exact (driver, wire model) key. An absent key
returns unknown facts; the catalog does not infer from the model name:
use Cognesy\Polyglot\Inference\Models\ModelCatalog;
$profile = ModelCatalog::discover()->find('qwen', 'qwen3.8-max');
$profile->limits->contextWindow;
$profile->capabilities->tools;
$profile->capabilities->reasoning;
The catalog is not used by ordinary inference unless it is passed explicitly to
InferenceRuntime. Reuse one discovered catalog at the application composition
root when local capability policy or metadata is needed. Known semantic fallback
is off by default; direct PHP config uses allowLossyFallback: true, while
Laravel and Symfony connection config uses allow_lossy_fallback: true. Every
accepted adjustment is observable on the effective request and
InferenceRequested event.
Pricing is caller-owned and is not stored in model catalog records:
use Cognesy\Polyglot\Inference\Data\InferencePricing;
use Cognesy\Polyglot\Inference\Pricing\FlatRateCostCalculator;
$cost = (new FlatRateCostCalculator())->calculate(
usage: $response->usage(),
// Illustrative USD rates per 1M tokens; supply your current sourced rates.
pricing: new InferencePricing(
inputPerMToken: 0.20,
outputPerMToken: 0.80,
),
);
Streaming (InferenceStream)¶
$stream = $inference
->withStreaming(true)
->create()
->stream();
foreach ($stream->deltas() as $delta) {
// PartialInferenceDelta
}
$mapped = $stream->map(fn($delta) => $delta->messageChunks->textDelta());
$filtered = $stream->filter(fn($delta) => $delta->messageChunks->textDelta() !== '');
$total = $stream->reduce(
fn($carry, $delta) => $carry + strlen($delta->messageChunks->textDelta()),
0,
);
$allDeltas = $stream->all();
$final = $stream->final(); // ?InferenceResponse
$stream->onDelta(function ($delta): void {
// callback for each visible delta
});
$lastDelta = $stream->lastDelta();
$usage = $stream->usage();
$execution = $stream->execution();
Inference Runtime / Provider Setup¶
use Cognesy\Polyglot\Inference\Config\LLMConfig;
use Cognesy\Polyglot\Inference\InferenceRuntime;
use Cognesy\Polyglot\Inference\LLMProvider;
$runtime = InferenceRuntime::fromConfig(LLMConfig::fromPreset('openai'));
$runtime = InferenceRuntime::fromProvider(LLMProvider::using('openai'));
$provider = LLMProvider::using('openai')
->withConfigOverrides(['model' => 'gpt-4.1-nano'])
->withModel('gpt-4.1-mini');
Driver registry helpers:
use Cognesy\Polyglot\Inference\Creation\InferenceDriverRegistry;
$drivers = InferenceDriverRegistry::default()
->withDriver('custom', $driverFactory);
$runtime = InferenceRuntime::fromConfig(
LLMConfig::fromArray([
'driver' => 'custom',
'apiUrl' => 'https://example.test',
'endpoint' => '/v1/chat',
'model' => 'custom-model',
]),
drivers: $drivers,
);
Embeddings Quick Start¶
use Cognesy\Polyglot\Embeddings\Embeddings;
$vectors = Embeddings::using('openai')
->withModel('text-embedding-3-small')
->withInputs(['hello world'])
->vectors();
Embeddings Constructors and Builder Methods¶
use Cognesy\Polyglot\Embeddings\Config\EmbeddingsConfig;
use Cognesy\Polyglot\Embeddings\Config\EmbeddingsRetryPolicy;
use Cognesy\Polyglot\Embeddings\Embeddings;
use Cognesy\Polyglot\Embeddings\EmbeddingsProvider;
use Cognesy\Polyglot\Embeddings\EmbeddingsRuntime;
$embeddings = new Embeddings();
$embeddings = Embeddings::using('openai');
$embeddings = Embeddings::fromConfig(EmbeddingsConfig::fromPreset('openai'));
$embeddings = Embeddings::fromProvider(
EmbeddingsProvider::fromEmbeddingsConfig(EmbeddingsConfig::fromPreset('openai')),
);
$embeddings = Embeddings::fromRuntime(
EmbeddingsRuntime::fromConfig(EmbeddingsConfig::fromPreset('openai')),
);
$embeddings = $embeddings
->withInputs(['a', 'b'])
->withModel('text-embedding-3-small')
->withOptions(['dimensions' => 512])
->withRetryPolicy(new EmbeddingsRetryPolicy(maxAttempts: 3));
Single-call variant:
$embeddings = Embeddings::using('openai')->with(
input: ['hello'],
options: ['dimensions' => 512],
model: 'text-embedding-3-small',
);
With explicit request:
use Cognesy\Polyglot\Embeddings\Data\EmbeddingsRequest;
$request = new EmbeddingsRequest(
input: ['hello'],
model: 'text-embedding-3-small',
);
$pending = Embeddings::using('openai')
->withRequest($request)
->create();
Execution shortcuts:
$response = $embeddings->get();
$vectors = $embeddings->vectors();
$first = $embeddings->first();
$pending = $embeddings->create();
$request = $pending->request();
$response = $pending->get();
Embeddings Runtime / Provider Setup¶
use Cognesy\Polyglot\Embeddings\Config\EmbeddingsConfig;
use Cognesy\Polyglot\Embeddings\Embeddings;
use Cognesy\Polyglot\Embeddings\EmbeddingsProvider;
use Cognesy\Polyglot\Embeddings\EmbeddingsRuntime;
$runtime = EmbeddingsRuntime::fromConfig(EmbeddingsConfig::fromPreset('openai'));
$runtime = EmbeddingsRuntime::fromProvider(
EmbeddingsProvider::fromEmbeddingsConfig(EmbeddingsConfig::fromPreset('openai')),
);
$provider = EmbeddingsProvider::new()
->withConfig(EmbeddingsConfig::fromPreset('openai'))
->withConfigOverrides(['model' => 'text-embedding-3-small']);
Decision Quick Start¶
use Cognesy\Polyglot\Decision\Collections\ChoiceOptions;
use Cognesy\Polyglot\Decision\Collections\Questions;
use Cognesy\Polyglot\Decision\Collections\ScoreLevels;
use Cognesy\Polyglot\Decision\Data\ChoiceOption;
use Cognesy\Polyglot\Decision\Decision;
use Cognesy\Polyglot\Decision\Questions\Choice;
use Cognesy\Polyglot\Decision\Questions\Noul;
use Cognesy\Polyglot\Decision\Questions\Score;
$questions = Questions::of(
new Noul('billing', 'Is this about billing?'),
new Choice(
id: 'tone',
options: ChoiceOptions::of(
new ChoiceOption('calm'),
new ChoiceOption('frustrated'),
),
instructions: 'What is the tone?',
),
new Score(
id: 'urgency',
levels: ScoreLevels::of('low', 'medium', 'high'),
instructions: 'How urgent is this?',
),
);
$answers = Decision::using('typesafe')
->with(input: 'Charged twice; please help today.', questions: $questions)
->get();
$probability = $answers->noul('billing')->probability();
$tone = $answers->choice('tone')->value();
$urgency = $answers->score('urgency')->value();
Decision Runtime and Pending Result¶
use Cognesy\Polyglot\Decision\Config\DecisionConfig;
use Cognesy\Polyglot\Decision\Config\DecisionRetryPolicy;
use Cognesy\Polyglot\Decision\Data\DecisionRequest;
use Cognesy\Polyglot\Decision\DecisionRuntime;
$runtime = DecisionRuntime::fromConfig(DecisionConfig::fromPreset('typesafe'));
$pending = $runtime->create(new DecisionRequest(
input: 'Charged twice; please help today.',
questions: $questions,
retryPolicy: new DecisionRetryPolicy(maxAttempts: 3),
));
$request = $pending->request();
$executionId = $pending->executionId();
$answers = $pending->get();
$response = $pending->response(); // memoized after get()
Decision defaults to one attempt and has no streaming API. Lifecycle telemetry uses
sdm.decision and sdm.decision.attempt. See docs/decision/overview.md for
serialization, structured content, dynamic options, retry ownership, and live testing.
Testing¶
Deterministic test seams:
Tests\Support\FakeInferenceDriver- queue sync
InferenceResponsefixtures or streamingPartialInferenceDeltabatches - best for most inference runtime tests that do not need HTTP or adapter coverage
Tests\Support\FakeEmbeddingsDriver- queue
EmbeddingsResponsefixtures and record handled requests - best for most embeddings runtime and memoization tests
MockHttpDriver- use when transport and provider adapter behavior still matter
- best for golden tests, request assertions, and provider-specific error-path coverage
POLYGLOT_TYPESAFE_LIVE=1- opts into the bounded TypeSafe integration smoke
- ordinary test runs remain offline