SOLWYN
Reference

SolwynConfig

The complete SDK configuration reference — constructor arguments, every SolwynConfig field, the full environment-variable table, precedence, and validation.

import os
from anthropic import Anthropic
from openai import OpenAI
from solwyn import Solwyn

client = Solwyn(
    OpenAI(),
    model="gpt-4o",
    api_key=os.environ["SOLWYN_API_KEY"],
    budget_mode="hard_deny",
    fail_open=False,
    fallback=[(Anthropic(), "claude-sonnet-4-5", {"max_tokens": 1024})],
    circuit_breaker_failure_threshold=5,
)

Configuration is passed as keyword arguments to Solwyn() or AsyncSolwyn(). A handful of arguments shape the failover chain and are handled by the client wrapper; the rest map directly onto SolwynConfig fields, many of which also read a SOLWYN_-prefixed environment variable.

SolwynConfig is a Pydantic BaseModel that validates all SDK configuration. You never construct it directly — the wrapper assembles the failover chain (providers, default_params) from the client, model=, fallback=, and default_params= arguments, then constructs and validates the config.

This page is the single source for every configuration option and every environment variable.

Constructor arguments

These keyword-only arguments are handled by the client wrapper itself — they are not raw SolwynConfig fields, and none has an environment variable:

ArgumentTypeDefaultDescription
clientprovider clientrequired (positional)The LLM client to wrap. Provider is auto-detected (client type, base_url host, Azure client class, or conventional local port).
api_keystr | Nonefrom envSolwyn project API key. Falls back to SOLWYN_API_KEY.
modelstr | NoneNoneModel for the primary entry. Optional for single-provider use (the per-call model wins); set it when configuring a fallback chain.
providerstr | NoneNoneExplicit provider identity for the primary entry. SDK v0.6.0+: a pin bypasses type and base_url auto-detection and selects the named adapter — for endpoints detection cannot name (provider="vllm" on a non-default port), or to keep native OpenAI metering behind a gateway base_url. It never translates dialects or rewrites the endpoint. An unknown name raises ConfigurationError(field="provider"); a client-family or sync/async mismatch raises ConfigurationError(field="client"). Constructor-only, no env var.
fallbacklist[tuple][]Failover chain entries: (client, model), (client, model, default_params), or (client, model, default_params, provider). See Provider Failover.
default_paramsdict{}Global fill-absent request params applied to every entry (per-entry default_params wins).
selection_policySelectionPolicy | NoneHealthBasedPolicyCandidate ordering policy: HealthBasedPolicy (default), LatencyPolicy, or CostPolicy; since 0.6.0 CostPolicy is driven by per-call server price hints. Never governed by the plan directive.
control_plane_transportControlPlaneTransport | NoneNoneSDK v0.6.0+. A caller-owned transport for every Solwyn Cloud request — normal operation, fork recovery, interpreter-exit delivery, and lease surrender. The SDK never closes it. Solwyn needs handle_request; AsyncSolwyn needs handle_async_request too. The seam behind solwyn.testing.FakeControlPlane.
**config_kwargsAny SolwynConfig field below.

Precedence

Constructor keyword arguments take precedence over environment variables, which take precedence over defaults:

Constructor kwargs  >  SOLWYN_* env vars  >  Defaults

If a field is provided in both the constructor and an environment variable, the constructor value wins.

One runtime exception, new in 0.3.0 and widened in 0.4.0: on plans without the failover-tuning entitlement, a plan-scoped Cloud directive can advisorily override the eight failover and circuit-breaker tuning fields — failover_total_timeout, failover_hop_read_timeout, failover_idempotency, same_provider_retries, circuit_breaker_recovery_timeout_jitter, circuit_breaker_failure_threshold, circuit_breaker_recovery_timeout, and circuit_breaker_success_threshold — replacing them with SDK defaults at runtime. The override is reversible and applies to no other field; constructor-over-env precedence is unchanged everywhere else. See Plan-scoped tuning entitlement.

Field reference

Required fields

This field must be supplied either as a constructor keyword argument or via the corresponding environment variable. The kwarg defaults to None, and the env-var loader runs before validation, so passing nothing is fine as long as the environment is populated.

FieldTypeEnv varValidation
api_keystrSOLWYN_API_KEYMust match sk_proj_<64 lowercase hex chars>. ASCII-only, no path traversal.

Invalid formats raise ConfigurationError immediately at construction time, with the field attribute set to the failing field name.

Core settings

FieldTypeDefaultEnv varDescription
api_urlstr"https://api.solwyn.ai"SOLWYN_API_URLSolwyn Cloud API endpoint.
fail_openboolTrueSOLWYN_FAIL_OPENAllow LLM calls when Solwyn Cloud is unreachable. A retained run stop or sticky hard deny is preserved either way.
budget_modeBudgetMode"alert_only"SOLWYN_BUDGET_MODE"alert_only": warn on budget exhaustion. "hard_deny": block calls.
tagsdict[str, str] | NoneNoneSOLWYN_TAGSSDK v0.5.0+. Default spend tags for every intercepted call — the lowest-precedence layer under run-scope and per-call tags. Env form is key=value,key2=value2 (split at the first =; no whitespace stripping; a comma cannot appear in a value). At most 10 keys, key 1–64, value 0–256, no NUL. A tagged call always takes a live budget check. See Tags.

budget_mode values

ValueBehavior
"alert_only"Default. Logs a warning when budget is exhausted but allows the call.
"hard_deny"Raises BudgetExceededError and blocks the call before it reaches the provider.

fail_open values

ValueBehavior when Solwyn Cloud is unreachable
TrueLLM calls proceed with local usage tracking. Warning logged.
FalseCalls are denied when the budget check cannot be completed.

The SOLWYN_FAIL_OPEN environment variable accepts true, 1, yes (case-insensitive) for True, and any other value for False.

Provider failover chain

These fields are assembled by the client wrapper from your client / model= / fallback= / default_params= arguments. They are constructor-only — none is read from the environment.

FieldTypeDefaultDescription
providerslist[ProviderEntry]required (≥1)The [primary, *fallbacks] chain. providers[0] is the wrapped client; the rest are fallbacks in attempt order.
default_paramsdict[str, Any]{}Global fill-absent request params (per-entry default_params wins).
failover_total_timeoutfloat30.0The failover window (seconds): the budget pre-flight, each hop's connect/pool slice, Retry-After sleeps, and advancement between hops. Since 0.4.0 it no longer caps a dispatched hop's read. Must be a finite number (SDK v0.6.0+); 0 is accepted and dispatches nothing.
failover_hop_read_timeoutfloat600.0The per-hop read/write bound (seconds), decoupled from the window (SDK v0.4.0+). Must be a finite number greater than zero. See Failover timeouts.
failover_idempotency"safe" | "never" | "always""safe"Failover aggressiveness after an ambiguous (post-send) failure.
same_provider_retriesint0Same-provider 429 Retry-After retries before cross-provider failover.
circuit_breaker_recovery_timeout_jitterfloat0.2Fractional jitter on the recovery timeout so instances don't probe in lockstep.

ProviderEntry carries provider, model, and default_params only — never an api_key or base_url. Provider credentials live on your client objects.

Breaking in 0.6.0: both timeouts reject booleans, NaN, +inf, and -inf at construction. float("inf") was previously accepted and produced an unbounded failover window or hop read. Through Solwyn(...) the rejection is a ConfigurationError whose field names the timeout; constructing SolwynConfig directly raises pydantic's ValidationError.

See Provider Failover for the full failover model, including the per-call solwyn_idempotent override.

Circuit breaker

FieldTypeDefaultEnv varDescription
circuit_breaker_failure_thresholdint3SOLWYN_CIRCUIT_BREAKER_FAILURE_THRESHOLDConsecutive failures before the circuit opens.
circuit_breaker_recovery_timeoutint60SOLWYN_CIRCUIT_BREAKER_RECOVERY_TIMEOUTSeconds before a half-open recovery probe.
circuit_breaker_success_thresholdint2SOLWYN_CIRCUIT_BREAKER_SUCCESS_THRESHOLDSuccesses in half-open state needed to close the circuit.
breaker_reporting_enabledboolTrueSOLWYN_BREAKER_REPORTING_ENABLEDReport per-provider breaker state to Solwyn Cloud for dashboard visibility (SDK v0.3.0+). Advisory telemetry only — enforcement stays process-local. See Breaker state reporting.
breaker_report_heartbeatfloat60.0SOLWYN_BREAKER_REPORT_HEARTBEATSeconds between full breaker-state refreshes (SDK v0.4.0+). Between heartbeats, a provider reports only when its snapshot changes — state, failure count, or success count. Must be greater than zero.

Lower failure_threshold values react faster to outages but may trigger on transient errors. Lower recovery_timeout values recover faster but may probe before the provider is ready.

Control plane

New in 0.4.0. These govern a circuit breaker around Solwyn Cloud itself, so a Solwyn outage is discovered once per client rather than re-paid on every call. It is a separate health domain from the per-provider breakers above, is never included in breaker state reports, and never denies a call on its own — it only decides how fast the SDK stops waiting on an unreachable control plane.

FieldTypeDefaultEnv varDescription
control_plane_failure_thresholdint3SOLWYN_CONTROL_PLANE_FAILURE_THRESHOLDConsecutive failures against the Solwyn API before its breaker opens.
control_plane_recovery_timeoutfloat30.0SOLWYN_CONTROL_PLANE_RECOVERY_TIMEOUTSeconds before a recovery probe once that breaker is open.

A read-only-key refusal means Solwyn responded, so it records a success and never opens this breaker. See Read-only key diagnostics.

Budget

FieldTypeDefaultEnv varDescription
budget_check_cache_ttlint5SOLWYN_BUDGET_CHECK_CACHE_TTLSeconds to cache budget check "allowed" responses on the per-call check path. Denied responses are never cached.
budget_check_timeoutfloat1.0SOLWYN_BUDGET_CHECK_TIMEOUTPer-request timeout (seconds) for the pre-flight check and lease grant (SDK v0.4.0+; was an effective 5s before). This request gates the caller's hot path, so the default is deliberately short — the control-plane breaker above caps repeated discovery of an outage.
lease_enabledboolTrueSOLWYN_LEASE_ENABLEDUse run-scoped token leases for eligible calls inside solwyn.run(...) (SDK v0.4.0+). False is a kill switch that routes every call back to the per-call check path. See Run-scoped leases.
lease_output_bound_defaultint4096SOLWYN_LEASE_OUTPUT_BOUND_DEFAULTOutput-token allowance reserved for a lease-funded call that declares no max_tokens-family cap on any configured hop (SDK v0.4.0+). Must be greater than zero.

budget_check_cache_ttl applies to the per-call check path only — it never authorizes a lease-funded call, and run-scoped and tagged checks bypass it. SDK v0.6.0+: the cache is a bounded 16-entry LRU keyed by provider, model, the fallback chain, and modality; a hit replays that entry's own price hints and never a reservation id. Lower values give more responsive enforcement at the cost of more API round-trips; higher values reduce traffic but may allow brief overspend.

Coverage

SDK v0.6.0+. How the wrapper treats provider capabilities Solwyn does not meter. See Coverage controls.

FieldTypeDefaultEnv varDescription
on_unmetered"warn" | "raise" | "allow""warn"SOLWYN_ON_UNMETEREDHandle untracked or unknown pre-call capabilities: log one warning per surface per process and forward (warn), refuse with UntrackedSpendSurfaceError before provider I/O (raise), or forward silently (allow).
acknowledge_untrackedfrozenset[str]emptySOLWYN_ACKNOWLEDGE_UNTRACKEDExact terminal capability tokens exempt from the posture. Env form is comma-delimited, elements stripped; an empty element is an error. Every token is validated against the wrapped client at construction (ConfigurationError(field="acknowledge_untracked")).
report_untracked_surfacesboolTrueSOLWYN_REPORT_UNTRACKED_SURFACESSend structural advisory reports for unacknowledged warn/allow observations to /api/v1/untracked-surfaces, at most once per surface every fifteen minutes, off the request path. Set false to keep them local; the posture above is unaffected. Requires a writable project key.

Velocity

SDK v0.6.0+. Local runaway-run detection inside a solwyn.run(...) scope. It runs entirely in-process on token counts and timing — never on content — and either warns or stops the run. See Local velocity detection.

FieldTypeDefaultEnv varDescription
velocity_mode"off" | "warn" | "deny""warn"SOLWYN_VELOCITY_MODEwarn logs velocity.flagged and reports the flag on the run; deny stops the run locally so its next call raises RunStoppedError; off disables detection.
velocity_repeat_countint5SOLWYN_VELOCITY_REPEAT_COUNTCalls to the same model with the same-sized prompt (within max(8, 2%) tokens) inside the window that trip repeat_size. Range 2–64.
velocity_repeat_window_sfloat60.0SOLWYN_VELOCITY_REPEAT_WINDOW_SThe repeat_size window, in seconds. Greater than zero.
velocity_growth_streakint8SOLWYN_VELOCITY_GROWTH_STREAKConsecutive strictly-growing prompt sizes that trip monotonic_growth. Range 3–64.
velocity_growth_factorfloat3.0SOLWYN_VELOCITY_GROWTH_FACTORThe latest prompt must be at least this multiple of the first in the streak. Greater than one.
velocity_accel_floor_per_minint30SOLWYN_VELOCITY_ACCEL_FLOOR_PER_MINMinimum calls per minute before rate_acceleration can fire. Range 1–64.
velocity_accel_factorfloat3.0SOLWYN_VELOCITY_ACCEL_FACTORRate multiple over the run's earlier pace that trips rate_acceleration. Greater than one.

repeat_size and monotonic_growth can stop a run under deny; rate_acceleration is advisory only. A local stop is never lifted by a server allow — only solwyn.clear_run_termination(run_id) clears it.

Reporter

The metadata reporter sends token-usage events to Solwyn Cloud in batches:

FieldTypeDefaultEnv varDescription
reporter_batch_sizeint50SOLWYN_REPORTER_BATCH_SIZEMaximum usage events per batch.
reporter_flush_intervalfloat5.0SOLWYN_REPORTER_FLUSH_INTERVALSeconds between automatic batch flushes.
reporter_max_queue_sizeint10000SOLWYN_REPORTER_MAX_QUEUE_SIZEMaximum events in the in-process queue; when full, the oldest events are dropped.
reporter_max_in_flightint3SOLWYN_REPORTER_MAX_IN_FLIGHTMaximum concurrent HTTP requests for batch delivery.

Delivery retry and shutdown, new in 0.4.0 — see Spend delivery:

FieldTypeDefaultEnv varDescription
reporter_max_send_attemptsint5SOLWYN_REPORTER_MAX_SEND_ATTEMPTSAttempts per item before undeliverable spend is counted and dropped. Minimum 1.
reporter_retry_backoff_basefloat1.0SOLWYN_REPORTER_RETRY_BACKOFF_BASEFirst retry delay (seconds); backoff grows exponentially from here. Must be greater than zero.
reporter_retry_backoff_capfloat60.0SOLWYN_REPORTER_RETRY_BACKOFF_CAPCeiling on that backoff (seconds). Must be greater than zero.
reporter_shutdown_deadlinefloat5.0SOLWYN_REPORTER_SHUTDOWN_DEADLINEWall-clock budget (seconds) shared by everything close() must finish. Work still queued at the deadline is counted and dropped. 0 is permitted.

Tuning guidance:

  • High-throughput applications: increase reporter_batch_size and reporter_max_queue_size to reduce HTTP overhead.
  • Low-latency applications: decrease reporter_flush_interval for faster dashboard updates.
  • Memory-constrained environments: decrease reporter_max_queue_size to limit memory usage.
  • Short-lived processes (CLI jobs, serverless handlers): raise reporter_shutdown_deadline if close() is dropping spend on exit, or lower it if an unreachable Solwyn is holding up teardown.

Environment variables

This is the complete, site-wide list of environment variables the SDK reads. Only the fields below are populated from the environment — the failover chain (fallback, model, provider, default_params, selection_policy, control_plane_transport) and the failover knobs, including failover_hop_read_timeout, are constructor-only. The prefix is always SOLWYN_, and the suffix is the uppercase field name:

api_key                            -> SOLWYN_API_KEY
api_url                            -> SOLWYN_API_URL
fail_open                          -> SOLWYN_FAIL_OPEN
budget_mode                        -> SOLWYN_BUDGET_MODE
tags                               -> SOLWYN_TAGS
on_unmetered                       -> SOLWYN_ON_UNMETERED
acknowledge_untracked              -> SOLWYN_ACKNOWLEDGE_UNTRACKED
report_untracked_surfaces          -> SOLWYN_REPORT_UNTRACKED_SURFACES
velocity_mode                      -> SOLWYN_VELOCITY_MODE
velocity_repeat_count              -> SOLWYN_VELOCITY_REPEAT_COUNT
velocity_repeat_window_s           -> SOLWYN_VELOCITY_REPEAT_WINDOW_S
velocity_growth_streak             -> SOLWYN_VELOCITY_GROWTH_STREAK
velocity_growth_factor             -> SOLWYN_VELOCITY_GROWTH_FACTOR
velocity_accel_floor_per_min       -> SOLWYN_VELOCITY_ACCEL_FLOOR_PER_MIN
velocity_accel_factor              -> SOLWYN_VELOCITY_ACCEL_FACTOR
circuit_breaker_failure_threshold  -> SOLWYN_CIRCUIT_BREAKER_FAILURE_THRESHOLD
circuit_breaker_recovery_timeout   -> SOLWYN_CIRCUIT_BREAKER_RECOVERY_TIMEOUT
circuit_breaker_success_threshold  -> SOLWYN_CIRCUIT_BREAKER_SUCCESS_THRESHOLD
breaker_reporting_enabled          -> SOLWYN_BREAKER_REPORTING_ENABLED
breaker_report_heartbeat           -> SOLWYN_BREAKER_REPORT_HEARTBEAT
budget_check_cache_ttl             -> SOLWYN_BUDGET_CHECK_CACHE_TTL
budget_check_timeout               -> SOLWYN_BUDGET_CHECK_TIMEOUT
lease_enabled                      -> SOLWYN_LEASE_ENABLED
lease_output_bound_default         -> SOLWYN_LEASE_OUTPUT_BOUND_DEFAULT
control_plane_failure_threshold    -> SOLWYN_CONTROL_PLANE_FAILURE_THRESHOLD
control_plane_recovery_timeout     -> SOLWYN_CONTROL_PLANE_RECOVERY_TIMEOUT
reporter_batch_size                -> SOLWYN_REPORTER_BATCH_SIZE
reporter_flush_interval            -> SOLWYN_REPORTER_FLUSH_INTERVAL
reporter_max_queue_size            -> SOLWYN_REPORTER_MAX_QUEUE_SIZE
reporter_max_in_flight             -> SOLWYN_REPORTER_MAX_IN_FLIGHT
reporter_max_send_attempts         -> SOLWYN_REPORTER_MAX_SEND_ATTEMPTS
reporter_retry_backoff_base        -> SOLWYN_REPORTER_RETRY_BACKOFF_BASE
reporter_retry_backoff_cap         -> SOLWYN_REPORTER_RETRY_BACKOFF_CAP
reporter_shutdown_deadline         -> SOLWYN_REPORTER_SHUTDOWN_DEADLINE

Constructor values take precedence over environment variables, which take precedence over defaults.

Boolean coercion

The SOLWYN_FAIL_OPEN, SOLWYN_BREAKER_REPORTING_ENABLED, SOLWYN_LEASE_ENABLED, and SOLWYN_REPORT_UNTRACKED_SURFACES environment variables are coerced to booleans: true, 1, yes (case-insensitive) map to True. All other values map to False — including a typo, so SOLWYN_REPORT_UNTRACKED_SURFACES=TRUE_ silently disables a default-on feature.

Validation

Tags

SOLWYN_TAGS entries must be key=value; an entry without = (which is what a comma inside a value produces) raises ConfigurationError(field="tags"). A set-but-empty SOLWYN_TAGS= raises for the same reason — unset the variable rather than clearing it. The same bounds apply to the constructor mapping: at most 10 keys, keys 1–64 characters, values 0–256, no NUL, all strings.

Timeouts

failover_total_timeout and failover_hop_read_timeout must be finite numbers; the hop read timeout must also be greater than zero. Booleans are rejected explicitly ("timeout bounds must be numbers, not booleans").

Credential format validation

The api_key is validated after construction:

  • API key: must match the regex ^sk_proj_[a-f0-9]{64}$

Security checks applied:

  • Unicode NFC normalization (prevents homograph attacks)
  • ASCII-only enforcement (prevents encoding exploits)
  • Path traversal rejection (.., /, \ are rejected)

Invalid formats raise ConfigurationError with the field attribute set to the failing field name.

Provider chain validation

The config requires at least one entry in providers. An empty chain raises ConfigurationError on the providers field. In normal use the wrapped client always supplies the primary entry, so this is satisfied automatically.

Extra field rejection

SolwynConfig uses Pydantic's extra="forbid" mode. Any unrecognized keyword argument is rejected:

import os
from openai import OpenAI
from solwyn import Solwyn

# Rejected -- "typo_field" is not recognized.
# The removed fallback_model / primary_provider options are also rejected here.
client = Solwyn(
    OpenAI(),
    api_key=os.environ["SOLWYN_API_KEY"],
    typo_field="value",
)

Use fallback=[...] for failover (see Provider Failover); the primary provider is auto-detected from the wrapped client unless you pin it with provider=.

Enum values

BudgetMode

ValueDescription
"alert_only"Log warning on budget exhaustion, allow calls.
"hard_deny"Raise BudgetExceededError, block calls.

ProviderName

The first four values are native API dialects (Bedrock's Converse API is its own dialect). The rest are OpenAI-compatible providers: they speak the Chat Completions dialect but are distinct providers for attribution, pricing, budget enforcement, and circuit breaking.

ValueDescription
"openai"OpenAI provider (native dialect).
"anthropic"Anthropic provider (native dialect).
"google"Google Gemini provider (native dialect).
"bedrock"Amazon Bedrock provider — Converse API (native dialect).
"xai"xAI (Grok), via api.x.ai.
"deepseek"DeepSeek, via api.deepseek.com.
"mistral"Mistral, via api.mistral.ai.
"qwen"Qwen (DashScope compatible mode).
"zai"Z.AI, via api.z.ai (the GLM model family).
"groq"Groq, via api.groq.com.
"together"Together AI.
"fireworks"Fireworks, via api.fireworks.ai.
"perplexity"Perplexity (Sonar), via api.perplexity.ai.
"azure_openai"Azure OpenAI (host suffix or AzureOpenAI client class).
"openrouter"OpenRouter, via openrouter.ai.
"ollama"Ollama (conventional local port 11434).
"vllm"vLLM (conventional local port 8000).
"lmstudio"LM Studio (conventional local port 1234).
"openai_compatible"Generic catch-all for any unrecognized OpenAI-compatible endpoint (custom proxies, new vendors).

CircuitState

ValueDescription
"closed"Normal operation — requests flow through.
"open"Failing — the router fails over to the next candidate.
"half_open"Testing recovery with probe requests.

FailoverReason

ValueDescription
"circuit_open"The primary's breaker was open and was skipped (never attempted).
"primary_error"The primary was attempted and raised before a fallback succeeded.
"model_fallback"A same-provider model swap served the call.
"cost_routed"SDK v0.6.0+. A price-aware policy placed a healthy, cheaper cross-provider candidate ahead of the healthy primary, and that candidate served the call. Attribution only — never a failure. See Cost-aware routing.

DenySource

SDK v0.6.0+. The deny_source on a denial receipt:

ValueDescription
"server"Solwyn Cloud answered the check with a denial (budget, per-run cap, scoped rule, or operator stop).
"sticky_replay"The SDK replayed a retained server verdict — a sticky hard deny or a run stop — without asking again, typically during an outage.
"local_enforcement"fail_open=False denied locally while Solwyn Cloud was unreachable.
"lease_exhausted"A run's lease and headroom share were spent while Solwyn Cloud was unreachable, and budget_mode="hard_deny" denied.
"local_velocity"The SDK's velocity detector stopped the run.
"run_terminated"A call was refused because the run was already stopped.
"aggregate_replay"A folded aggregate standing in for receipts that could not be delivered individually.

Example: full configuration

import os
from anthropic import Anthropic
from openai import OpenAI
from solwyn import Solwyn, CostPolicy

client = Solwyn(
    OpenAI(),
    # Primary entry
    model="gpt-4o",
    # Required
    api_key=os.environ["SOLWYN_API_KEY"],
    # Core
    api_url="https://api.solwyn.ai",
    budget_mode="hard_deny",
    fail_open=False,
    tags={"environment": "production", "service_name": "research"},
    # Coverage
    on_unmetered="raise",
    acknowledge_untracked={"models.list"},
    report_untracked_surfaces=True,
    # Velocity
    velocity_mode="deny",
    velocity_repeat_count=8,
    # Failover chain
    fallback=[(Anthropic(), "claude-sonnet-4-5", {"max_tokens": 1024})],
    default_params={"temperature": 0.7},
    selection_policy=CostPolicy(),
    failover_total_timeout=20.0,
    failover_hop_read_timeout=120.0,
    failover_idempotency="safe",
    same_provider_retries=1,
    # Circuit breaker
    circuit_breaker_failure_threshold=5,
    circuit_breaker_recovery_timeout=30,
    circuit_breaker_success_threshold=3,
    breaker_report_heartbeat=60.0,
    # Control plane
    control_plane_failure_threshold=3,
    control_plane_recovery_timeout=30.0,
    # Budget
    budget_check_cache_ttl=10,
    budget_check_timeout=1.0,
    lease_enabled=True,
    lease_output_bound_default=4096,
    # Reporter
    reporter_batch_size=100,
    reporter_flush_interval=2.0,
    reporter_max_queue_size=20000,
    reporter_max_in_flight=5,
    reporter_max_send_attempts=5,
    reporter_retry_backoff_base=1.0,
    reporter_retry_backoff_cap=60.0,
    reporter_shutdown_deadline=5.0,
)

On this page