SOLWYN

TypeScript SDK Configuration

Public Solwyn TypeScript options, environment variables, strict validation, defaults, and qualified runtime boundaries.

The public wrapper accepts camelCase SolwynOptions. Each option is copied once into a strict, validated internal configuration; unknown keys are rejected instead of being ignored. Pass provider request settings to the provider client or request, not to Solwyn.

import { Solwyn } from "@solwyn/sdk";
import OpenAI from "openai";

const solwynApiKey = process.env.SOLWYN_API_KEY;
if (!solwynApiKey) throw new Error("SOLWYN_API_KEY is required");

const client = new Solwyn(new OpenAI(), {
  apiKey: solwynApiKey,
  model: "gpt-4o",
  failOpen: true,
  onUnmetered: "raise",
  leaseEnabled: true,
  reporterShutdownDeadline: 5,
});

try {
  await client.chat.completions.create({
    model: "gpt-4o",
    messages: [{ role: "user", content: "Return one short greeting." }],
  });
} finally {
  await client.close();
}

In this example, the provider-required model is explicit on the request. Per-call request values win over defaultParams and constructor-level model defaults.

Identity, attribution, and coverage

OptionEnvironment variableDefaultMeaning
apiKeySOLWYN_API_KEYRequiredSolwyn project key: sk_proj_ plus 64 lowercase hexadecimal characters.
apiUrlSOLWYN_API_URLhttps://api.solwyn.aiSolwyn Cloud API base URL.
model—NonePrimary model default; a per-call model takes precedence.
provider—Auto-detectPrimary provider identity pin. It bypasses detection, then validates the client family.
fallback—[]Ordered tuples of [client, model], optionally followed by defaultParams and a provider override.
defaultParams—{}Fill-absent provider request values. Per-call values win.
tagsSOLWYN_TAGSNoneDefault content-free attribution tags. Environment form is comma-separated key=value.
onUnmeteredSOLWYN_ON_UNMETERED"warn""warn", "raise", or "allow" for unmetered or newly observed spend surfaces.
acknowledgeUntrackedSOLWYN_ACKNOWLEDGE_UNTRACKED[]Exact reviewed terminal surface tokens. Environment form is comma-separated.
reportUntrackedSurfacesSOLWYN_REPORT_UNTRACKED_SURFACEStrueSend content-free untracked-surface advisories to Solwyn Cloud.
traceCorrelationSOLWYN_TRACE_CORRELATIONtrueAdd the caller's active OpenTelemetry trace ID, span ID, and sampled flag to metadata events when an active span exists. false disables capture.

Set apiUrl only to the trusted HTTPS Solwyn control-plane endpoint you intend to use. The SDK sends the Solwyn project key to that endpoint as a bearer credential.

Valid provider identities are openai, anthropic, google, bedrock, xai, deepseek, mistral, qwen, groq, together, fireworks, perplexity, azure_openai, openrouter, zai, ollama, vllm, lmstudio, and openai_compatible. Provider name controls attribution, budgets, and circuit breakers; provider dialect controls dispatch and translation. See TypeScript SDK providers before adding an explicit pin.

Trace correlation adds no OpenTelemetry dependency and creates no spans. It reads only the active span's trace ID, span ID, and sampled flag through an already-registered OpenTelemetry API, once at call start; see TypeScript SDK privacy.

Tags are never inferred from prompt or response content. A per-call solwyn_tags property is removed only from an intercepted provider request and used as explicit attribution. Tagged calls remain in the per-call budget-check path rather than using a run lease, so tag-scoped policy stays authoritative.

Budgets and leases

OptionEnvironment variableDefaultMeaning
failOpenSOLWYN_FAIL_OPENtrueOutage posture after applicable retained-denial checks.
budgetModeSOLWYN_BUDGET_MODE"alert_only""alert_only" or "hard_deny", attached to SDK-local outage results. It does not override the mode returned by a live Cloud check.
budgetCheckCacheTtlSOLWYN_BUDGET_CHECK_CACHE_TTL5Unscoped allow-cache lifetime in integer seconds; 0 disables it.
budgetCheckTimeoutSOLWYN_BUDGET_CHECK_TIMEOUT1Budget pre-flight timeout in seconds, at least 0.1, capped by the whole-chain deadline.
leaseEnabledSOLWYN_LEASE_ENABLEDtrueEnable local token leases for eligible, untagged, run-scoped text calls.
leaseOutputBoundDefaultSOLWYN_LEASE_OUTPUT_BOUND_DEFAULT4096Output-token reservation when a request has no usable structural cap.

The live mode returned by Solwyn Cloud is authoritative for that call. An applicable retained hard denial is preserved during a later outage even when failOpen is true. Read TypeScript SDK budgets before changing fail-open or lease behavior.

Failover and provider breakers

OptionEnvironment variableDefaultMeaning
selectionPolicy—HealthBasedPolicyCandidate ordering policy.
failoverIdempotency—"safe""safe", "never", or "always" for cross-provider failover.
sameProviderRetries—0Same-provider retries for HTTP 429 responses with usable Retry-After.
failoverTotalTimeout—30Seconds for pre-flight, retry sleeps, and between-hop admission. It does not cap an in-flight provider read.
failoverHopReadTimeout—600Per-attempt provider timeout in seconds; the phases it covers vary by provider SDK.
circuitBreakerRecoveryTimeoutJitter—0.2Provider-breaker recovery jitter fraction.
circuitBreakerFailureThresholdSOLWYN_CIRCUIT_BREAKER_FAILURE_THRESHOLD3Consecutive failures before a provider breaker opens.
circuitBreakerRecoveryTimeoutSOLWYN_CIRCUIT_BREAKER_RECOVERY_TIMEOUT60Base recovery timeout in integer seconds.
circuitBreakerSuccessThresholdSOLWYN_CIRCUIT_BREAKER_SUCCESS_THRESHOLD2Half-open successes required to close a provider breaker.

Both timeout options reject booleans and non-finite values. failoverHopReadTimeout must be positive. A zero failoverTotalTimeout is valid and prevents new work from starting after call entry. JavaScript provider SDKs expose one per-request timeout carrier, and what it covers differs by SDK. For OpenAI, OpenAI-compatible, and Anthropic clients, failoverHopReadTimeout covers only connecting and receiving response headers: a response body or stream that stalls after its first bytes is not interrupted. For Google, Solwyn keeps the bound armed until the buffered response or stream finishes, so it also limits the total duration of a healthy stream. To bound a stalled stream on the other SDKs, pass an AbortSignal in the request options or apply your own idle timeout while iterating. Bedrock's request timeout is not a universal hard abort for every Converse stream handler; configure a finite socket timeout on the AWS request handler too.

See TypeScript SDK failover for fallback tuple shapes, first-byte stream behavior, and fail-loud translation limits.

Control-plane and reporter behavior

OptionEnvironment variableDefaultMeaning
fetch—globalThis.fetchCaller-owned Solwyn control-plane transport seam.
logger—Console-backed loggerdebug, info, warn, and error logger implementation.
controlPlaneFailureThresholdSOLWYN_CONTROL_PLANE_FAILURE_THRESHOLD3Consecutive budget-check, confirmation, or lease-operation outages before the shared control-plane breaker opens.
controlPlaneRecoveryTimeoutSOLWYN_CONTROL_PLANE_RECOVERY_TIMEOUT30Control-plane breaker recovery timeout in seconds.
breakerReportingEnabledSOLWYN_BREAKER_REPORTING_ENABLEDtrueInclude provider-breaker snapshots in reporter cycles.
reporterBatchSizeSOLWYN_REPORTER_BATCH_SIZE50Events per metadata-ingest batch; 1–1000.
reporterFlushIntervalSOLWYN_REPORTER_FLUSH_INTERVAL5Background flush interval in seconds.
reporterMaxQueueSizeSOLWYN_REPORTER_MAX_QUEUE_SIZE10000Reporter queue cap; overflow drops the oldest event.
reporterMaxInFlightSOLWYN_REPORTER_MAX_IN_FLIGHT3Maximum concurrent settlement-confirmation sends. Metadata-ingest batches remain serial.
reporterMaxSendAttemptsSOLWYN_REPORTER_MAX_SEND_ATTEMPTS5Ordinary retryable send attempts before telemetry is disposed. HTTP 429 responses have a separate cap of 20.
reporterRetryBackoffBaseSOLWYN_REPORTER_RETRY_BACKOFF_BASE1Retry backoff base in seconds.
reporterRetryBackoffCapSOLWYN_REPORTER_RETRY_BACKOFF_CAP60Retry backoff cap in seconds.
reporterShutdownDeadlineSOLWYN_REPORTER_SHUTDOWN_DEADLINE5Shared close() deadline in seconds for in-flight calls, open-stream settlement, reporting, and advisory delivery; 0 is valid.
breakerReportHeartbeatSOLWYN_BREAKER_REPORT_HEARTBEAT60Full provider-breaker refresh interval in seconds; greater than 0 and at most 60.

Reporter batch size, flush interval, queue size, maximum in-flight sends, and retry backoffs must be positive. Send attempts must be at least one. The shutdown deadline may be zero. Timeout, cache, recovery, flush, backoff, and shutdown durations must be finite and no greater than 2147483.647 seconds, so their millisecond delays fit the runtime timer range. A present fetch value must be a function, and an injected logger must provide all four debug, info, warn, and error methods; both are rejected synchronously otherwise.

Local velocity monitoring

OptionEnvironment variableDefaultMeaning
velocityModeSOLWYN_VELOCITY_MODE"warn""off", "warn", or "deny".
velocityRepeatCountSOLWYN_VELOCITY_REPEAT_COUNT5Near-identical calls required inside the repeat window; range 2–64.
velocityRepeatWindowSSOLWYN_VELOCITY_REPEAT_WINDOW_S60Repeat detection window in seconds.
velocityGrowthStreakSOLWYN_VELOCITY_GROWTH_STREAK8Strictly growing call sizes required; range 3–64.
velocityGrowthFactorSOLWYN_VELOCITY_GROWTH_FACTOR3Required latest-to-first estimated-input ratio; greater than one.
velocityAccelFloorPerMinSOLWYN_VELOCITY_ACCEL_FLOOR_PER_MIN30Minimum current-minute call count for acceleration detection; integer 1–64.
velocityAccelFactorSOLWYN_VELOCITY_ACCEL_FACTOR3Required current-to-prior-minute rate ratio; greater than one.

The repeat window and the growth and acceleration factors also accept positive infinity to disable the corresponding bound. Only repeat size and monotonic growth are deny-eligible. Rate acceleration is advisory. Velocity history is structural and content-blind; see TypeScript SDK runs.

Environment precedence

For mapped fields, resolution is:

  1. a constructor option when it is not undefined;
  2. the matching SOLWYN_* environment variable;
  3. the documented default.

This is a presence check, not a truthiness check. Explicit false, 0, and "" values win over the environment and are then validated. Boolean environment values use true, 1, or yes case-insensitively for true; all other strings resolve to false. This applies to SOLWYN_FAIL_OPEN, SOLWYN_LEASE_ENABLED, SOLWYN_REPORT_UNTRACKED_SURFACES, SOLWYN_TRACE_CORRELATION, and SOLWYN_BREAKER_REPORTING_ENABLED. Numeric environment values are coerced and validated; empty strings and booleans are rejected for numeric options. SOLWYN_TAGS uses comma-separated key=value entries, while SOLWYN_ACKNOWLEDGE_UNTRACKED uses comma-separated exact surface tokens.

Where process.env is unavailable, environment loading is an empty snapshot. Pass apiKey and other required settings explicitly in edge runtimes.

Strict validation

Construction fails synchronously with ConfigurationError for:

  • a missing or malformed Solwyn project key;
  • any unknown or snake_case constructor option;
  • an unknown provider identity or incompatible provider/client pin;
  • a malformed fallback tuple;
  • an invalid enum, tag, acknowledgment token, timeout, reporter limit, or velocity threshold;
  • a present non-function fetch, a logger missing any of its four methods, or a selectionPolicy without order();
  • wrapping a client that is already a Solwyn wrapper.

ConfigurationError.field identifies the rejected field when one is available. Constructor and environment schema errors use the internal snake_case field name, for example budget_check_timeout or failover_hop_read_timeout. Response and request wire schemas are also strict: unexpected control-plane fields are treated as contract drift rather than silently defaulted. Provider errors remain provider errors and pass through unchanged; see TypeScript SDK errors.

Runtime and compiler support

0.2.0 is qualified on these exact full runtime lanes:

RuntimeQualification
Node.js 22.23.2Full ESM/CommonJS, package, consumer, provider, and runtime gates.
Node.js 24.21.0Full ESM/CommonJS, package, consumer, provider, and runtime gates.
Node.js 20.20.2Legacy installed-artifact lane for the provider-free core, @solwyn/sdk/node, and @solwyn/sdk/testing only, while the manifest continues to declare >=20. It is not a source-build, provider-surface, Vercel AI SDK 7, LangChain, or OpenAI Agents lane.

Use Node.js 22 or 24 for new applications. The package publishes dual ESM and CommonJS entries. Its declarations are consumer-checked with exact TypeScript 5.8.3 and 6.0.3, under strict: true, skipLibCheck: false, and a lib set that includes ESNext.Disposable. These two compiler cells are the tested boundary; no claim is made for every compiler version between them.

Provider compatibility is likewise stated as exact tested cells rather than inferred continuous ranges. See the provider qualification table.

Browser and edge qualification

The core @solwyn/sdk entry uses web-standard fetch, AbortController, crypto.randomUUID, timers, and web streams, and it imports no node:* module. Release checks exercise a browser-target bundle, an edge-like VM without Node globals, and a real browser execution path. Those checks establish browser/edge-compatible packaging; they do not certify deployment on every named edge platform, provider transport, or hosting product.

@solwyn/sdk/node is Node-only because callback run(...), createRun(), and RunHandle.activate(...) use AsyncLocalStorage. Do not import that entry into an edge bundle. Without it, calls still budget-check and report, but ambient run IDs and names are absent. The LangChain and OpenAI Agents attribution entries also require @solwyn/sdk/node and throw ConfigurationError without it; on edge runtimes the wrapped client alone still enforces budgets.

Browser-compatible code is not permission to expose secrets. Provider and Solwyn project keys belong in a trusted server or edge secret store. Validate network policy, streaming behavior, provider SDK compatibility, and shutdown semantics on your actual deployment platform.

Shutdown is configuration too

The client owns queued settlement, advisory, budget, lease, and provider-lifecycle work. Always await client.close() in a finally block or use await using. One reporterShutdownDeadline bounds the wait for in-flight calls, open-stream settlement, reporting, and advisory delivery, and the provider's own close() runs last. Calls made after close() begins reject with SolwynError("client is closed"). See the TypeScript SDK overview for both patterns.

On this page