SOLWYN

TypeScript SDK Changelog

Release notes for the Solwyn TypeScript SDK, from the 0.1.0-rc.1 candidate through the current 0.2.0 release.

All notable public changes to @solwyn/sdk are documented here. The package follows Semantic Versioning. During 0.x, breaking changes are called out here and in the corresponding release notes before users upgrade.

0.2.0 — Current release

Status: published to npm on 2026-10-21 as the latest release.

This minor release adds content-free attribution for LangChain.js / LangGraph.js and OpenAI Agents JS, plus OpenTelemetry trace correlation on metadata events. The new optional peers can cause npm ERESOLVE in applications that already pin out-of-range framework versions, and coverage fingerprints for several providers change; review Changed before upgrading. The new framework entries and trace correlation read no prompt or response content.

Added

  • OpenAI Agents JS attribution. The @solwyn/sdk/openai-agents entry adds content-free workflow and stable per-agent run scopes for the Node.js 22+ Chat Completions and Responses HTTP recipe. Function-tool turns, handoffs, and hand-backs reuse the correct agent identity; the wrapped client alone owns enforcement and settlement. Nested agent-as-tool calls, unexpected models, missing hierarchy, and concurrent attempts fail closed with typed errors. Tool-code and guardrail denials and stops surface the original Solwyn error from run, streamed iteration, and completed when Agents preserves it. Invalid OpenAIProvider options raise ConfigurationError. See TypeScript SDK OpenAI Agents.
  • LangChain.js and LangGraph.js attribution. The @solwyn/sdk/langchain entry supplies a content-free run-scope handler and a guarded Chat Completions leaf for the documented Node.js 22+ OpenAI recipe. Stable graph-node scopes preserve lease reuse, velocity history, and exact-run stops across iterations. Responses and non-streaming JSON-schema parsing are refused. Early stream termination and Node.js 22 abort-and-drain require an invocation-local handler. Invalid namePrefix values are rejected eagerly. See TypeScript SDK LangChain.
  • OpenTelemetry trace correlation. Metadata events from wrapped clients and the AI SDK middleware include the caller's active OpenTelemetry trace_id, span_id, and trace_sampled when the application already has an active span. The values are captured once at call start and carried by every event of the call. Solwyn adds no OpenTelemetry dependency and creates no spans. Disable capture with traceCorrelation: false or SOLWYN_TRACE_CORRELATION=false. See TypeScript SDK Privacy.

Changed

  • Compatibility: the new optional @openai/agents >=0.20.0 <1 and @langchain/core >=1.2.14 <2 peers can cause npm ERESOLVE when an application already installs an out-of-range version, even when it does not use the integration. Upgrade that dependency or stay on 0.1.1. The Agents recipe requires openai >=7.2.0 <8 and zod 4.
  • Background work no longer joins the caller's trace. Reporter flushes, close-time delivery, lease renewals and surrenders, and untracked-surface advisories run without the active span and baggage of the call that started them. Budget checks and lease grants still run in the caller's context.
  • Compatibility: legacy raw-request and client escapes on native OpenAI, Azure OpenAI, Anthropic, and Together clients, OpenAI Realtime session and client-secret creation and call acceptance, and Google GenAI Live and ApiClient transports now report unmetered_spend with explicit scopes instead of unknown. Bedrock coverage lists InvokeModelWithBidirectionalStreamCommand as blocked, matching its existing runtime refusal. The onUnmetered posture is unchanged, and existing acknowledgeUntracked tokens remain valid. Refresh pinned coverage(client).expect(...) fingerprints for OpenAI, Azure, Anthropic, Together, Google GenAI, and Bedrock when upgrading.

Fixed

  • Additional Anthropic streaming cache writes are attributed using the served request's TTL when it agrees with the initial usage split. Mixed-TTL requests mark inferred cache-write growth as estimated.
  • Settlement after per-call streaming errors. Mid-stream provider errors on streams that used a per-call budget check now settle the provider-reported usage observed before the error and include those tokens in the error event, so Cloud spend can increase for such calls. Lease-funded streams still report zero usage and release the local claim. Deferred responses.stream helpers report a zero-token error event with no confirmation.

0.1.1 — Documentation patch

Status: published to npm on 2026-10-17.

Fixed

  • Reorganized the package README so the npm package page shows it in full, with reference material moved to the SDK repository's docs/ directory. There are no package behavior changes.

0.1.0 — First stable public preview

Status: published to npm on 2026-10-17.

Added

  • BudgetEnforcer.checkBudget() returns the effective callId, including one minted when the caller omits it, and accepts a caller signal.

Changed

  • OpenAI 7 support. The optional openai peer range is >=4.41.0 <8. OpenAI 7 requires Node.js 22 or later; the provider-free core still runs on Node.js 20 with a compatible older provider SDK.
  • Reviewed provider surfaces. Coverage rules were refreshed for @anthropic-ai/sdk@0.135.0, openai@7.36.0, together-ai@0.58.0, and @google/genai@2.30.0. Newly reviewed operations, including credential-client and raw-request escapes, are explicitly unmetered and follow onUnmetered. Refresh strict coverage fingerprints when upgrading.
  • Google automatic continuation. With @google/genai@2.30.0, automatic continuation on the metered generate-content methods takes one budget check and settles cumulative usage once, bounded by Solwyn-owned request deadlines.
  • Run leases. Leases widen in the background to model chains a run starts using, recover from a 409 refusal or ineligible renewal within 150 seconds, surrender finished runs through a bounded dispatcher, and report only their own spend.
  • Reporting. reporterMaxInFlight now limits concurrent settlement confirmations while metadata batches stay serial, and retries honor Retry-After with bounded jittered backoff.
  • Run tracking on demand. Importing @solwyn/sdk/node no longer installs a process-wide async hook.
  • Breaking: raw JSON-schema Responses parse formats produce unknown parsed types; narrow the value, use a branded schema helper, or pass explicit type arguments.
  • Breaking: once close() begins, intercepted calls reject with SolwynError("client is closed"), and open streams settle once from usage observed so far. Finish or cancel streams before closing, and create a new client for later calls. The AI SDK middleware handle follows the same rule.
  • Breaking: when a plan suppresses custom failover tuning, the SDK keeps a stricter requested idempotency policy, failover window, and retry count instead of loosening them to defaults.
  • Breaking: the per-call solwynIdempotent field only tightens policy; true no longer escalates to "always".
  • Breaking: numeric configuration is range-checked. Durations must be finite and at most 2,147,483.647 seconds, budgetCheckTimeout must be at least 0.1 seconds, reporterBatchSize is capped at 1000, and breakerReportHeartbeat at 60 seconds. Direct BudgetEnforcer durations are validated the same way.
  • Breaking: loggers must supply all four methods and a selectionPolicy must supply order(); partial objects raise ConfigurationError synchronously.
  • Breaking: createTokenDetails() and TokenDetailsSchema.parse() reject cache buckets that exceed input_tokens.
  • Breaking: velocity history is kept for up to 4096 runs, so configured loop denials can fire for high-concurrency runs. Use velocityMode: "warn" to observe flags first.
  • Breaking: key, membership, and descriptor reflection no longer apply untracked-spend posture; coverage is enforced when a guarded operation is invoked.
  • Breaking: coverage() throws ConfigurationError with field: "client" instead of TypeError for an object that is not a Solwyn wrapper.
  • Breaking: refused, overflowing, or expired lease surrenders are dropped and reported in lease.surrenders_dropped warnings instead of being retried on every call.
  • Breaking: ingest responses require a strict duplicates list, and lease renewals require model and provider together. Update custom control-plane fixtures accordingly.
  • Breaking: FakeControlPlane allows project overruns in alert_only mode, uses hard_deny for scoped and run denials, defaults lease timers to 120 seconds with a 15-second refresh, stores only accepted ingest events, and enforces batch, body, and project limits. stopRun() accepts only the "manual_kill" reason.
  • Breaking: cancelling an established stream settles the usage observed so far instead of refunding the whole reservation; cancellation before connection reports possibly_succeeded: true.
  • Breaking: status-less provider errors after a stream connects count toward the provider breaker unless caused by caller cancellation; non-429 HTTP 4xx errors are health-neutral.
  • Breaking: a lease attempt and its per-call fallback share one preflight deadline. With less than 50 milliseconds remaining, preflight skips network I/O and applies local policy. Caller AbortSignals cancel preflight without counting as a control-plane outage.

Fixed

  • Abandoned drop-in and AI SDK middleware streams settle observed usage once on garbage collection, and clients dropped without close() can be collected.
  • Run stops retain the usage carried by the chunk pulled at the stop boundary, and an iterator throw() settles observed usage like return().
  • Anthropic streaming usage follows cumulative message_delta counters, including server-tool usage and cache TTL splits. Google preflight estimates include content parts and systemInstruction.
  • The AI SDK middleware refuses dispatch after a concurrent run stop, aborts in-flight streams at the next chunk boundary, and adds attribution for Vertex Anthropic, LM Studio, vLLM, generic compatible providers, and Alibaba models.
  • Caller aborts end same-provider Retry-After waits immediately, and already-aborted calls skip velocity detection and budget I/O.
  • failoverHopReadTimeout is documented accurately: for OpenAI, OpenAI-compatible, and Anthropic clients it covers connecting and receiving response headers only, superseding the 0.1.0-rc.1 limitation below that described it as a whole-request bound.

0.1.0-rc.1 — Public preview candidate

Status: published to npm on 2026-09-13 as the first public-preview candidate.

Added

  • A drop-in Solwyn proxy for existing provider clients, preserving their request types, instanceof behavior, reflection, property mutation, and provider shutdown behavior.
  • Duck-typed support for native OpenAI, Azure OpenAI, Anthropic, Google Gemini, Amazon Bedrock, Together AI, named OpenAI-compatible providers, and a generic compatible fallback. The core has no runtime provider-SDK imports.
  • Native OpenAI and Azure OpenAI Responses metering for responses.create, responses.parse, and the deferred responses.stream helper.
  • Buffered and streaming usage settlement across supported provider dialects. A completed compatible text call with missing or incomplete provider usage falls back to a marked, length-based token estimate instead of silent zero usage.
  • Pre-flight budget enforcement, automatic settlement, fail-open and local-enforcement outage behavior, retained hard-deny authority, denial receipts, and bounded aggregate replay.
  • Run-scoped local token leases for eligible untagged text calls, with generation-fenced renewal and surrender during shutdown. See TypeScript SDK Budgets.
  • Ordered provider failover, per-provider circuit breakers, same-provider Retry-After retries, deadlines, idempotency policy, same-dialect passthrough, and fail-loud minimal cross-dialect translation. See TypeScript SDK Failover.
  • Request-scoped Cloud price hints for CostPolicy; the hints do not create mutable client-wide pricing state.
  • Provider-surface controls: onUnmetered, exact acknowledgeUntracked tokens, content-free advisory reporting, local coverage(), and reviewed surface fingerprints.
  • Node-only callback run() and detached createRun() / RunHandle.activate() / finish() APIs, including parent-run attribution and inherited tag layers. See TypeScript SDK Runs.
  • Exact-ID cooperative run control through server directives and bounded local velocity detection. Later dispatches and active drop-in streams stop with RunStoppedError; clearing a termination affects future work only.
  • Primary-only metering for supported embedding, image, audio, and video methods, using observable token or structural media quantities.
  • Vercel AI SDK language-model middleware from @solwyn/sdk/ai-sdk, including AI Gateway vendor attribution. See TypeScript SDK AI SDK Middleware.
  • An edge-safe @solwyn/sdk core, a Node-specific @solwyn/sdk/node entry, and dual ESM/CommonJS builds with declarations.
  • A framework-neutral @solwyn/sdk/testing entry with FakeControlPlane, scripted scenarios, seven reserved magic models, reusable contract probes, and a denial-only provider sentinel. See TypeScript SDK Testing.
  • Typed SolwynError subclasses and strict zod wire schemas.
  • A path-restricted privacy firewall. Only content-free usage and operational metadata, plus explicit caller-provided tags, cross the Solwyn control-plane boundary. See TypeScript SDK Privacy.

Changed before the public preview

  • Live Cloud response mode governs live budget blocking. The constructor's budgetMode describes SDK-local outage results rather than overriding the control plane.
  • Explicit provider pins bypass detection and synchronously validate the pinned client family.
  • Tag precedence is explicit: per-call values override run values, which override client defaults. Tagged calls bypass run leases so tag-scoped rules remain authoritative.
  • Project-period hard denials are retained globally during an outage. Run denials and stops are retained only for the exact run; tag-period denials are not retained for future calls.
  • RunStoppedError derives directly from SolwynError, not BudgetExceededError.
  • Reporter shutdown is bounded, retry backoff is capped, and per-event ingest rejections are surfaced.

Fixed before the public preview

  • Native stream tee() and readable conversion now share metering, translation, run-stop, and settlement state; cancelling an unread native OpenAI or Anthropic stream closes the underlying request.
  • Usage paid before a structural response-translation failure remains accounted for.
  • Provider wrappers preserve overloads and generic inference while mixed ESM/CommonJS imports share run enforcement, error identity, and wrapper identity.
  • AI SDK middleware includes explicit run tags, conservatively accounts for unknown paid usage, and settles each logical buffered or streaming call once.
  • Run stops cover native Responses subscriptions and late event waiters; stream cancellation closes the original iterator once.
  • Admission checks the exact structural request sent to a provider. Unsupported payload overrides fail before provider or control-plane I/O.
  • Distinct metadata events receive deduplication-safe timestamps, while retries retain stable event identity.
  • Translation diagnostics use fixed structural labels rather than caller-controlled content.

Removed before the public preview

  • The public BudgetEnforcer.confirmCost() method. Settlement is owned by the client and reporter.
  • The public updatePriceHints() mutation API and client-wide price-hint store.
  • Exact-tokenizer loading and the tokenizer dependency. Estimation is always heuristic and length-based; provider-reported usage remains settlement truth.

Known limitations

  • Lease-backed calls currently carry no price hints, so CostPolicy uses health-tier ordering and preserves configured order within equal tiers until lease grants include hints.
  • JavaScript provider SDKs expose one per-request timeout carrier. failoverHopReadTimeout bounds the provider request rather than a distinct read phase, and Bedrock request timeouts cannot universally hard-abort every Converse stream handler.
  • Intercepted OpenAI and Anthropic calls return plain promises rather than provider-specific APIPromise values, so .withResponse() and .asResponse() are unavailable on those calls.
  • The AI SDK middleware meters the single model supplied by the AI SDK. It does not perform provider-client failover or cross-dialect translation.

On this page