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:
| Argument | Type | Default | Description |
|---|---|---|---|
client | provider client | required (positional) | The LLM client to wrap. Provider is auto-detected (client type, base_url host, Azure client class, or conventional local port). |
api_key | str | None | from env | Solwyn project API key. Falls back to SOLWYN_API_KEY. |
model | str | None | None | Model for the primary entry. Optional for single-provider use (the per-call model wins); set it when configuring a fallback chain. |
provider | str | None | None | Explicit 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. |
fallback | list[tuple] | [] | Failover chain entries: (client, model), (client, model, default_params), or (client, model, default_params, provider). See Provider Failover. |
default_params | dict | {} | Global fill-absent request params applied to every entry (per-entry default_params wins). |
selection_policy | SelectionPolicy | None | HealthBasedPolicy | Candidate 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_transport | ControlPlaneTransport | None | None | SDK 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_kwargs | Any SolwynConfig field below. |
Precedence
Constructor keyword arguments take precedence over environment variables, which take precedence over defaults:
Constructor kwargs > SOLWYN_* env vars > DefaultsIf 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.
| Field | Type | Env var | Validation |
|---|---|---|---|
api_key | str | SOLWYN_API_KEY | Must 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
| Field | Type | Default | Env var | Description |
|---|---|---|---|---|
api_url | str | "https://api.solwyn.ai" | SOLWYN_API_URL | Solwyn Cloud API endpoint. |
fail_open | bool | True | SOLWYN_FAIL_OPEN | Allow LLM calls when Solwyn Cloud is unreachable. A retained run stop or sticky hard deny is preserved either way. |
budget_mode | BudgetMode | "alert_only" | SOLWYN_BUDGET_MODE | "alert_only": warn on budget exhaustion. "hard_deny": block calls. |
tags | dict[str, str] | None | None | SOLWYN_TAGS | SDK 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
| Value | Behavior |
|---|---|
"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
| Value | Behavior when Solwyn Cloud is unreachable |
|---|---|
True | LLM calls proceed with local usage tracking. Warning logged. |
False | Calls 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.
| Field | Type | Default | Description |
|---|---|---|---|
providers | list[ProviderEntry] | required (≥1) | The [primary, *fallbacks] chain. providers[0] is the wrapped client; the rest are fallbacks in attempt order. |
default_params | dict[str, Any] | {} | Global fill-absent request params (per-entry default_params wins). |
failover_total_timeout | float | 30.0 | The 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_timeout | float | 600.0 | The 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_retries | int | 0 | Same-provider 429 Retry-After retries before cross-provider failover. |
circuit_breaker_recovery_timeout_jitter | float | 0.2 | Fractional 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
| Field | Type | Default | Env var | Description |
|---|---|---|---|---|
circuit_breaker_failure_threshold | int | 3 | SOLWYN_CIRCUIT_BREAKER_FAILURE_THRESHOLD | Consecutive failures before the circuit opens. |
circuit_breaker_recovery_timeout | int | 60 | SOLWYN_CIRCUIT_BREAKER_RECOVERY_TIMEOUT | Seconds before a half-open recovery probe. |
circuit_breaker_success_threshold | int | 2 | SOLWYN_CIRCUIT_BREAKER_SUCCESS_THRESHOLD | Successes in half-open state needed to close the circuit. |
breaker_reporting_enabled | bool | True | SOLWYN_BREAKER_REPORTING_ENABLED | Report 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_heartbeat | float | 60.0 | SOLWYN_BREAKER_REPORT_HEARTBEAT | Seconds 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.
| Field | Type | Default | Env var | Description |
|---|---|---|---|---|
control_plane_failure_threshold | int | 3 | SOLWYN_CONTROL_PLANE_FAILURE_THRESHOLD | Consecutive failures against the Solwyn API before its breaker opens. |
control_plane_recovery_timeout | float | 30.0 | SOLWYN_CONTROL_PLANE_RECOVERY_TIMEOUT | Seconds 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
| Field | Type | Default | Env var | Description |
|---|---|---|---|---|
budget_check_cache_ttl | int | 5 | SOLWYN_BUDGET_CHECK_CACHE_TTL | Seconds to cache budget check "allowed" responses on the per-call check path. Denied responses are never cached. |
budget_check_timeout | float | 1.0 | SOLWYN_BUDGET_CHECK_TIMEOUT | Per-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_enabled | bool | True | SOLWYN_LEASE_ENABLED | Use 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_default | int | 4096 | SOLWYN_LEASE_OUTPUT_BOUND_DEFAULT | Output-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.
| Field | Type | Default | Env var | Description |
|---|---|---|---|---|
on_unmetered | "warn" | "raise" | "allow" | "warn" | SOLWYN_ON_UNMETERED | Handle 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_untracked | frozenset[str] | empty | SOLWYN_ACKNOWLEDGE_UNTRACKED | Exact 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_surfaces | bool | True | SOLWYN_REPORT_UNTRACKED_SURFACES | Send 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.
| Field | Type | Default | Env var | Description |
|---|---|---|---|---|
velocity_mode | "off" | "warn" | "deny" | "warn" | SOLWYN_VELOCITY_MODE | warn 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_count | int | 5 | SOLWYN_VELOCITY_REPEAT_COUNT | Calls 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_s | float | 60.0 | SOLWYN_VELOCITY_REPEAT_WINDOW_S | The repeat_size window, in seconds. Greater than zero. |
velocity_growth_streak | int | 8 | SOLWYN_VELOCITY_GROWTH_STREAK | Consecutive strictly-growing prompt sizes that trip monotonic_growth. Range 3–64. |
velocity_growth_factor | float | 3.0 | SOLWYN_VELOCITY_GROWTH_FACTOR | The latest prompt must be at least this multiple of the first in the streak. Greater than one. |
velocity_accel_floor_per_min | int | 30 | SOLWYN_VELOCITY_ACCEL_FLOOR_PER_MIN | Minimum calls per minute before rate_acceleration can fire. Range 1–64. |
velocity_accel_factor | float | 3.0 | SOLWYN_VELOCITY_ACCEL_FACTOR | Rate 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:
| Field | Type | Default | Env var | Description |
|---|---|---|---|---|
reporter_batch_size | int | 50 | SOLWYN_REPORTER_BATCH_SIZE | Maximum usage events per batch. |
reporter_flush_interval | float | 5.0 | SOLWYN_REPORTER_FLUSH_INTERVAL | Seconds between automatic batch flushes. |
reporter_max_queue_size | int | 10000 | SOLWYN_REPORTER_MAX_QUEUE_SIZE | Maximum events in the in-process queue; when full, the oldest events are dropped. |
reporter_max_in_flight | int | 3 | SOLWYN_REPORTER_MAX_IN_FLIGHT | Maximum concurrent HTTP requests for batch delivery. |
Delivery retry and shutdown, new in 0.4.0 — see Spend delivery:
| Field | Type | Default | Env var | Description |
|---|---|---|---|---|
reporter_max_send_attempts | int | 5 | SOLWYN_REPORTER_MAX_SEND_ATTEMPTS | Attempts per item before undeliverable spend is counted and dropped. Minimum 1. |
reporter_retry_backoff_base | float | 1.0 | SOLWYN_REPORTER_RETRY_BACKOFF_BASE | First retry delay (seconds); backoff grows exponentially from here. Must be greater than zero. |
reporter_retry_backoff_cap | float | 60.0 | SOLWYN_REPORTER_RETRY_BACKOFF_CAP | Ceiling on that backoff (seconds). Must be greater than zero. |
reporter_shutdown_deadline | float | 5.0 | SOLWYN_REPORTER_SHUTDOWN_DEADLINE | Wall-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_sizeandreporter_max_queue_sizeto reduce HTTP overhead. - Low-latency applications: decrease
reporter_flush_intervalfor faster dashboard updates. - Memory-constrained environments: decrease
reporter_max_queue_sizeto limit memory usage. - Short-lived processes (CLI jobs, serverless handlers): raise
reporter_shutdown_deadlineifclose()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_DEADLINEConstructor 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
| Value | Description |
|---|---|
"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.
| Value | Description |
|---|---|
"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
| Value | Description |
|---|---|
"closed" | Normal operation — requests flow through. |
"open" | Failing — the router fails over to the next candidate. |
"half_open" | Testing recovery with probe requests. |
FailoverReason
| Value | Description |
|---|---|
"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:
| Value | Description |
|---|---|
"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,
)