Together AI
Use Solwyn with the native Together SDK — sync, async, streaming, cache billing, and tracked surfaces
Wrap the native Together client directly. Solwyn recognizes Together and AsyncTogether by client type, keeps requests going directly to Together, and attributes tracked chat-completion usage as provider=together.
Setup
Together's native client requires Solwyn 0.1.12 or newer and Together SDK 2.0 or newer:
pip install "solwyn[together]>=0.1.12"The together extra installs the supported floor, together>=2.0, as a convenience — the SDK itself never imports together; detection is duck-typed. Together 1.x remains best-effort rather than a supported integration. Set both services' keys in the environment; Together() reads TOGETHER_API_KEY itself.
export TOGETHER_API_KEY=...
export SOLWYN_API_KEY=...Quickstart
Pass Together() to Solwyn() and keep using the native chat-completions surface:
from together import Together
from solwyn import Solwyn
with Solwyn(Together()) as client:
response = client.chat.completions.create(
model="meta-llama/Llama-3.3-70B-Instruct-Turbo",
messages=[{"role": "user", "content": "Explain cache locality in one sentence."}],
)
print(response.choices[0].message.content)The request and response keep Together's native types. Solwyn performs the budget check before dispatch, then reports usage so Solwyn Cloud can compute and display cost without capturing prompt or response content.
Sync and async clients
Pair each Solwyn wrapper with the matching Together client:
| Execution model | Solwyn wrapper | Together client |
|---|---|---|
| Sync | Solwyn | Together |
| Async | AsyncSolwyn | AsyncTogether |
import asyncio
from together import AsyncTogether
from solwyn import AsyncSolwyn
async def main():
async with AsyncSolwyn(AsyncTogether()) as client:
response = await client.chat.completions.create(
model="meta-llama/Llama-3.3-70B-Instruct-Turbo",
messages=[{"role": "user", "content": "Hello from async Together!"}],
)
print(response.choices[0].message.content)
asyncio.run(main())Do not mix the pairs. In particular, Solwyn(AsyncTogether()) is a known mispair: the sync wrapper cannot await the async client's coroutine. Use AsyncSolwyn(AsyncTogether()) instead.
Streaming usage and estimation
Streaming preserves Together's native iterator:
from together import Together
from solwyn import Solwyn
with Solwyn(Together()) as client:
stream = client.chat.completions.create(
model="meta-llama/Llama-3.3-70B-Instruct-Turbo",
messages=[{"role": "user", "content": "Count to three."}],
stream=True,
)
for chunk in stream:
if chunk.choices:
print(chunk.choices[0].delta.content or "", end="")Together's typed v2 create() rejects stream_options. Solwyn therefore never injects stream_options for Together; do not add it to native calls just to request usage.
A live probe on July 10, 2026 saw terminal usage on both sync and async streams, but Solwyn does not assume every future response will include it. If a stream or non-streaming response has no usable token counts, Solwyn falls back to privacy-safe length measurement and marks the reported token details with is_estimated=True. The estimator measures lengths without retaining, logging, or transmitting prompt or response content.
Cached-token billing
Together has returned cached prompt tokens in two response shapes:
- nested:
usage.prompt_tokens_details.cached_tokens - flat:
usage.cached_tokens
Solwyn normalizes either shape to cached_input_tokens. Together's cached tokens are a subset of prompt_tokens (prompt_tokens >= cached_tokens), not an additive token count. Solwyn reports that breakdown and the Cloud API applies Together's cached-input billing server-side; the SDK never computes dollar cost.
Together's serverless prompt cache is automatic and best-effort. Reusing an eligible prefix does not guarantee a hit on a particular request. The Solwyn SDK reports cached input, and Solwyn Cloud applies the cached-input rate, only when Together returns a non-zero cached-token count; cached_tokens=0 is a normal cold response, not evidence that wrapping failed. See Together's cached-input pricing.
Provider attribution
A native Together or AsyncTogether object is attributed by its module and class. That remains true if you give the native client a custom base_url: tracked calls still report provider=together.
If you intentionally use openai.OpenAI(base_url="https://api.together.xyz/v1") instead, Solwyn follows the Together host profile and still reports provider=together. That OpenAI-client route remains supported and is documented under OpenAI-compatible providers.
Unmetered Together surfaces
Solwyn tracks chat.completions.create, embeddings.create, images.generate / images.edit, audio.transcriptions.create, and audio.speech.create — Together is priced for text, embedding, image, and audio; see the provider × modality matrix. Together's image calls are budget-checked before the request and recorded as cost events with modality image; because the endpoint returns no usage, the billing quantity is request-derived (image count × the model's per-image rate). Audio transcriptions and speech are budget-tracked the same way and recorded with modality audio — transcriptions priced by audio duration, speech by the input character count measured inside the privacy firewall so the text never leaves your process. A model with no Together price card is rejected as an unknown model, exactly as on any other tracked surface. These native Together surfaces are billable spend Solwyn does not yet meter, so they pass through to the underlying client untracked:
completionsrerankcode_interpreterevals
The first access to each of these surfaces on a wrapped client logs a warning naming only the provider and surface. The call then proceeds unchanged. There is no budget check and no cost event for an unmetered call; repeated access to the same surface on that wrapped client does not repeat the warning.
Together's batches and fine_tuning surfaces are not billable LLM spend, so they pass through silently — no warning, no budget check, and no cost event — the same posture as files, moderations, and models.list.
Video is not on that list because it is not an untracked pass-through. The wrapped native Together client rides the OpenAI dialect, and the SDK's video interception (videos.create) is wired for OpenAI's Sora only — no video seam exists on the OpenAI-compatible dialect Together speaks. Calling videos.create on a wrapped Together client therefore fails loud with UnsupportedSurfaceError rather than silently passing through. Together's own native video endpoint is not carried on this surface.
Privacy
Together calls go straight from your application to Together. Solwyn never captures, logs, or transmits prompts or responses. It sends only bounded metadata such as provider, model, token counts, cache counts, status, latency, and cost attribution to Solwyn Cloud. See Privacy for the complete wire contract.