Configuration
Polyglot has a configuration type for each operation family: LLMConfig,
EmbeddingsConfig, and DecisionConfig. All can be loaded from YAML presets,
constructed from arrays, or parsed from DSN strings.
LLMConfig¶
LLMConfig holds connection, model selection, and request-default settings. Model facts live in
ModelCatalog, not in connection configuration.
Namespace: Cognesy\Polyglot\Inference\Config\LLMConfig
Fields¶
| Field | Type | Default | Description |
|---|---|---|---|
apiUrl |
string |
'' |
Base URL for the provider API |
apiKey |
string |
'' |
Authentication key (marked as #[SensitiveParameter]) |
endpoint |
string |
'' |
API endpoint path (e.g. /chat/completions) |
queryParams |
array |
[] |
Query parameters appended to the URL |
metadata |
array |
[] |
Provider-specific metadata (e.g. organization, project for OpenAI) |
model |
string |
'' |
Model identifier |
maxTokens |
int |
1024 |
Default max tokens for responses |
allowLossyFallback |
bool |
false |
Permit known, observable semantic fallback |
driver |
string |
'openai-compatible' |
Driver name (e.g. openai, anthropic, gemini) |
options |
array |
[] |
Additional provider-specific options |
Creating a Config¶
There are three ways to create an LLMConfig:
use Cognesy\Polyglot\Inference\Config\LLMConfig;
// From a named preset (loads from YAML files)
$config = LLMConfig::fromPreset('openai');
// From an associative array
$config = LLMConfig::fromArray([
'driver' => 'openai',
'apiUrl' => 'https://api.openai.com/v1',
'apiKey' => getenv('OPENAI_API_KEY'),
'endpoint' => '/chat/completions',
'model' => 'gpt-4.1-nano',
'maxTokens' => 2048,
]);
// From a DSN string
$config = LLMConfig::fromDsn('openai://model=gpt-4.1-nano&maxTokens=2048');
// @doctest id="dab3"
Presets¶
Presets are YAML files that live in well-known directories. Polyglot searches these paths in order:
config/llm/presets/(project root)packages/polyglot/resources/config/llm/presets/(monorepo)vendor/cognesy/instructor-php/packages/polyglot/resources/config/llm/presets/vendor/cognesy/instructor-polyglot/resources/config/llm/presets/
You may also pass a custom base path:
Overriding Values¶
Use withOverrides() to create a modified copy of an existing config:
$base = LLMConfig::fromPreset('openai');
$custom = $base->withOverrides(['model' => 'gpt-4.1', 'maxTokens' => 4096]);
// @doctest id="670c"
allowLossyFallback is deliberately separate from provider options. It authorizes only a
fallback Polyglot explicitly knows how to describe, such as JSON Schema to JSON Object or a lossy
reasoning effort mapping. It defaults to false, and accepted changes are recorded on the
effective request. Laravel and Symfony connection files use the snake-case field
allow_lossy_fallback; direct PHP construction, arrays, presets, and DSNs use
allowLossyFallback.
Model catalog¶
Catalog use is optional. Look up limits, modalities, and capabilities by exact driver and wire model only when an application needs those facts. An absent offering returns an explicit unknown profile:
use Cognesy\Polyglot\Inference\Models\ModelCatalog;
$profile = ModelCatalog::discover()->find('openai', 'gpt-5.6');
$profile->limits->contextWindow;
$profile->capabilities->jsonSchema;
// @doctest id="cb47"
discover() resolves application config/llm/models and packaged model directories through
the same locations used for presets. Exact lookup loads one <driver>/<model>.yaml record;
identity path components are percent-encoded. Use overlay(ModelCatalog::fromPaths($directory))
for another whole-record layer. Construction reads no records; repeated lookup reuses the hydrated
profile. Enumeration is explicit, and runtime never performs network discovery. See
Model Catalog for the versioned record format and scope lifetime.
Type Coercion¶
LLMConfig and EmbeddingsConfig automatically coerce numeric strings to
integers for integer fields. For LLMConfig, the coerced field is maxTokens.
EmbeddingsConfig¶
EmbeddingsConfig holds the settings for connecting to an embeddings provider.
Namespace: Cognesy\Polyglot\Embeddings\Config\EmbeddingsConfig
Fields¶
| Field | Type | Default | Description |
|---|---|---|---|
apiUrl |
string |
'' |
Base URL for the provider API |
apiKey |
string |
'' |
Authentication key |
endpoint |
string |
'' |
API endpoint path |
model |
string |
'' |
Model identifier |
dimensions |
int |
0 |
Embedding dimensions (0 = provider default) |
maxInputs |
int |
0 |
Maximum number of inputs per request |
metadata |
array |
[] |
Provider-specific metadata |
driver |
string |
'openai' |
Driver name |
Creating a Config¶
use Cognesy\Polyglot\Embeddings\Config\EmbeddingsConfig;
// From a named preset
$config = EmbeddingsConfig::fromPreset('openai');
// From an array
$config = EmbeddingsConfig::fromArray([
'driver' => 'openai',
'apiUrl' => 'https://api.openai.com/v1',
'apiKey' => getenv('OPENAI_API_KEY'),
'endpoint' => '/embeddings',
'model' => 'text-embedding-3-small',
'dimensions' => 1536,
]);
// From a DSN string
$config = EmbeddingsConfig::fromDsn('openai://model=text-embedding-3-small');
// @doctest id="abfe"
Presets for embeddings are resolved from similar paths, under the embed config group:
config/embed/presets/packages/polyglot/resources/config/embed/presets/vendor/cognesy/instructor-php/packages/polyglot/resources/config/embed/presets/vendor/cognesy/instructor-polyglot/resources/config/embed/presets/
Overriding Values¶
$modified = $config->withOverrides([
'model' => 'text-embedding-3-large',
'dimensions' => 1024,
]);
// @doctest id="3346"
For EmbeddingsConfig, type coercion applies to the dimensions and maxInputs fields.
Note: The legacy field name
defaultDimensionsis automatically normalized todimensionsduring config loading.
DecisionConfig¶
DecisionConfig holds the connection and model settings for structured
decision providers.
Namespace: Cognesy\Polyglot\Decision\Config\DecisionConfig
| Field | Type | Description |
|---|---|---|
driver |
string |
Decision driver name; currently typesafe is bundled |
apiUrl |
string |
Provider base URL |
apiKey |
string |
Authentication key |
endpoint |
string |
Endpoint path beginning with / |
model |
string |
Default structured decision model |
Decision presets use the sdm config group:
use Cognesy\Polyglot\Decision\Config\DecisionConfig;
$config = DecisionConfig::fromPreset('typesafe');
$modified = $config->withOverrides(['model' => 'jev-latest']);
// @doctest id="c017"
Use DecisionConfig::fromDefaults() to read config/sdm/default.yaml and
presetNames() to enumerate resolvable presets. See
Decision configuration and runtime for YAML examples,
search paths, redacted inspection, and runtime wiring.
Retry Policies¶
Retry behavior is configured separately from the provider config, via dedicated policy objects. Retry policies must not be placed inside the options array -- Polyglot will throw an InvalidArgumentException if you attempt this.
InferenceRetryPolicy¶
The InferenceRetryPolicy provides fine-grained control over retry behavior for inference requests:
use Cognesy\Polyglot\Inference\Config\InferenceRetryPolicy;
$policy = new InferenceRetryPolicy(
maxAttempts: 3, // Total attempts (including the first)
baseDelayMs: 250, // Base delay between retries
maxDelayMs: 8000, // Maximum delay cap
jitter: 'full', // Jitter strategy: 'none', 'full', or 'equal'
retryOnStatus: [408, 429, 500, 502, 503, 504],
lengthRecovery: 'continue', // 'none', 'continue', or 'increase_max_tokens'
lengthMaxAttempts: 1, // Max recovery attempts for length issues
lengthContinuePrompt: 'Continue.',
maxTokensIncrement: 512, // Increment when using 'increase_max_tokens'
);
$inference->withRetryPolicy($policy);
// @doctest id="1da8"
The retry delay uses exponential backoff: baseDelayMs * 2^(attempt-1), capped at maxDelayMs. The jitter strategy adds randomness to avoid thundering herd problems:
'none'-- exact exponential backoff'full'-- random value between 0 and the calculated delay'equal'-- half the delay plus a random amount up to half the delay
Length recovery allows automatic continuation when a response is cut short by the provider's token limit. Two strategies are available: 'continue' appends the partial response and sends a continuation prompt, while 'increase_max_tokens' retries with a higher max_tokens value.
The policy also retries on specific exceptions by default: TimeoutException and NetworkException. Provider-specific errors classified as retriable (rate limits, quota exceeded, transient errors) are also retried automatically.
EmbeddingsRetryPolicy¶
For embeddings, use EmbeddingsRetryPolicy:
use Cognesy\Polyglot\Embeddings\Config\EmbeddingsRetryPolicy;
$embeddings->withRetryPolicy(new EmbeddingsRetryPolicy(
maxAttempts: 3,
));
// @doctest id="5e88"
DecisionRetryPolicy¶
Decision defaults to one attempt. DecisionRetryPolicy enables bounded retries
for configured statuses and transport failures:
use Cognesy\Polyglot\Decision\Config\DecisionRetryPolicy;
$decision->withRetryPolicy(new DecisionRetryPolicy(
maxAttempts: 3,
baseDelayMs: 250,
maxDelayMs: 4000,
));
// @doctest id="59fe"
The policy defaults to 408, 429, selected 5xx statuses, 529, timeout,
and network failures. It honors bounded Retry-After by default. See
Decision configuration and runtime for the
single-owner retry rule.