SDKs
Overview
The Python SDK, the TypeScript SDK, and raw REST — install, initialize, the core compress call, agent client, and errors. Everything else is one link away.
compresr (Python 3.9+) and @compresr/sdk (Node 20+) wrap the REST API with typed methods, auth, retries, and async support. Every snippet is shown in all three flavors — pick a tab once and the choice sticks across the docs.
This page covers what only the SDKs have: installation, the client and its options, the core compress call, the agent client, and the exception types.
Install
The agent client ships in the base install (Python compresr ≥ 2.8.2, TypeScript @compresr/sdk ≥ 1.5); the old compresr[agents] extras still work as no-op aliases.
Initialize
Construct the client once and reuse it — it keeps an internal connection pool. See Authentication for the three ways to supply the key.
Constructor options
The table follows the language toggle — flip any snippet above to TypeScript and it re-renders with the camelCase spellings, types, and defaults.
api_keystr | NoneOptionalNone → COMPRESR_API_KEY env~/.compresr/credentials — see Authentication for all three ways to supply the key.base_urlstr | NoneOptionalNone → COMPRESR_BASE_URL env → https://api.compresr.aiCompresrError("insecure_base_url")) except loopback, unless COMPRESR_ALLOW_INSECURE=1 is set; TypeScript logs a warning and proceeds.timeoutint (seconds)Optional300retry_configRetryConfig | NoneOptionalbuilt-in policyRetryConfig (importable from the package root): retries 429/503 with exponential backoff, respects Retry-After.llmstr | NoneOptional"anthropic" or "anthropic:claude-haiku-4-5" to pin a default model.llm_api_keystr | NoneOptionalANTHROPIC_API_KEY / OPENAI_API_KEY / GOOGLE_API_KEY depending on llm.compressiondict | CompressionPolicy | NoneOptionalenable_prompt_cacheboolOptionalTruecache_control, OpenAI prompt_cache_key; no-op on Gemini).prompt_cache_ttl"5m" | "1h"Optional"5m""1h" maps to prompt_cache_retention: "24h".prompt_cache_min_messagesintOptional2openai_prompt_cache_keystr | NoneOptionalprompt_cache_key; omitted → provider defaults apply.llm_http_client / llm_http_async_clienthttpx.Client / httpx.AsyncClientOptionalhttpx client(s) for the downstream LLM call — corporate proxies, custom CA bundles, mTLS.compress
Single-request compression. Parameters map 1:1 to the API — the canonical parameter table, defaults, and target_compression_ratio semantics live in the Models reference. TypeScript accepts camelCase (targetCompressionRatio); the wire and all response fields stay snake_case.
Response
dataobjectcompressed_contextstringThe compressed text, ready to drop into your prompt.
original_tokensintegerToken count of the input context (tiktoken cl100k).
compressed_tokensintegerToken count of the compressed output.
tokens_savedintegeroriginal_tokens − compressed_tokens.
actual_compression_rationumberFraction of input tokens removed (0–1), regardless of how the target was expressed.
duration_msintegerServer-side wall-clock time for the compression pass.
Async
Python ships compress_async — same parameters as compress, awaitable. Use async with (or call await client.aclose() when done) so the connection pool closes cleanly. TypeScript is async-native throughout; there are no _async variants — fire calls concurrently with Promise.all.
If every row shares one model and ratio, prefer a single compress_batch call over N concurrent singles — one round trip, one rate-limit hit. Streaming is sync-only in Python; compress_batch_async is covered in the batch guide.
Everything else
| Capability | Methods | Where it's documented |
|---|---|---|
| Streaming | compress_stream / compressStream | Streaming guide — wire protocol, error handling, why plain compress usually wins today |
| Batch (≤ 100 contexts) | compress_batch / compressBatch | Batch guide — input shapes, atomicity, aggregates; endpoint: /batch |
| Web search tools | WebSearchTool (Tavily / Brave / AgentCore) | Web search guide |
| Research | client.research.run / .search | Web search guide § Research facade |
| Framework middleware | CompresrToolMiddleware, extractors, postprocessors | LangChain, LangGraph, LiteLLM, LlamaIndex |
| Parameters & models | target_compression_ratio, coarse, dynamic, … | Models reference — the canonical table; coarse mode |
| Wire contract | envelope, status codes, rate limits | API conventions, Error codes, Rate limits |
Agent client
Construct the client with llm= and you get an agent surface: three call shapes that auto-compress every tool output above min_tokens before the LLM sees it (LangChain 1.0 create_agent + CompresrToolMiddleware under the hood). There is no cURL equivalent — the compression the middleware fires is the same /api/compress/question-specific/ endpoint.
Rules that bite:
- Model lives at the call site.
llm="anthropic"sets the provider; every call passesmodel=. Pin a default withllm="anthropic:claude-haiku-4-5"(or/— both separators work). Neither set →CompresrError("model is required …"). - Python
run()/arun()are keyword-only —client.run("question")raisesTypeError. - Any LangChain tool works. A
@tool-decorated function (Python) ortool({...})(TypeScript) gets its string output compressed automatically. - Per-call LLM knobs (
temperature,top_p,max_tokens,stop,seed, …) forward to the chat model; unknown keys are silently dropped. On Gemini the SDK renamesmax_tokens→max_output_tokensfor you. - Async: Python exposes
acreate/arun. Agent-layer streaming is not implemented — Python facades have no.stream(...)(raisesAttributeError); TypeScript throwsCompresrError(code: 'not_implemented').compress_streamis unaffected. - Web search and research:
WebSearchTool(Tavily / Brave / AgentCore) and theclient.researchfacade are covered in the web search guide.
Compression knobs
compression={...} at construction applies to every tool output the middleware compresses:
| Key | Default | Effect |
|---|---|---|
compression_model_name | "latte_v1" | Which model compresses tool outputs. See Models. |
target_compression_ratio | 0.5 | Same semantics as the compress parameter. |
min_tokens | 200 | Tool outputs shorter than this skip compression (middleware-side gate, not sent to the API). |
coarse | server default (true) | Paragraph-level vs token-level. See coarse mode. |
allow_tools / ignore_tools | — | Whitelist / blacklist of tool names to compress. |
on_error | "passthrough" | On a Compresr backend error, forward the original tool output; "raise" to fail loudly. |
The policy doesn't expose the dynamic* knobs; call client.compress(dynamic=True, ...) directly if you need adaptive ratios.
Errors
Every SDK error inherits from CompresrError and carries a stable code plus structured attributes (err.retry_after, err.field, …) — HTTP-level details in Error codes. In Python, import them from compresr.exceptions (they are not re-exported at the package root). In TypeScript, the classes marked ✓ are importable from @compresr/sdk; everything else arrives as CompresrError with the corresponding code.
| Exception | HTTP | code | TS import | Attributes |
|---|---|---|---|---|
AuthenticationError | 401 | authentication_error | ✓ | — |
ScopeError | 403 | scope_error | ✓ | required_scope |
NotFoundError | 404 | not_found | ✓ | resource |
RateLimitError | 429 | rate_limit_exceeded | ✓ | retry_after (int; fractional Retry-After values read as None — guard with err.retry_after or 1) |
ValidationError | 422 | validation_error | ✓ | field |
ServerError | 5xx | server_error | ✓ | — |
ServiceUnavailableError | 503 | service_unavailable | — | service, retry_after |
CompresrConnectionError / ConnectionError | — | connection_error | ✓ | transport failures, including timeouts |
CompresrError | — | (varies) | ✓ | base class — catch as fallback |
Always handle 429
The free tier has tight per-minute limits. A retry loop with exponential backoff that respects retry_after is the single most important piece of production error handling.