secondwind GitHub Details, Stars and Alternatives | OpenRepoFinder
orchetron / repository
secondwind
Losslessly compress the tool output your AI agent sends the model, prove every value survived, and report the exact tokens removed. Run it as a proxy, a library, or middleware.
A transparent discovery signal based on current public GitHub metadata.
Recent activity35% weight
100
Community adoption25% weight
14
Maintenance state20% weight
100
License clarity10% weight
100
Project information10% weight
75
This score does not audit code, security, maintainers, documentation quality, or suitability. Verify the repository and its current documentation before adoption.
README preview
Lossless. Provable. Composable.
Cut the tokens your AI agent sends the model, without losing a value, and prove it.
Secondwind sits between your coding agent and the model API. It losslessly compresses the
tool output your agent feeds back to the model, proves every value survived, and reports
exactly how many tokens it removed. Your agent behaves the same. The model just reads
fewer tokens.
Lossless by proof, not by hope. A block is compressed only when it passes a
canonical-hash admission check and a coverage invariant. Anything that would drop a
value is refused and sent through untouched.
Zero change to your agent. A thin proxy rewrites requests and pipes replies
straight back, so streaming never breaks and secondwind never joins the conversation.
Tokens you can prove, not dollars you would guess. Every block reports the exact
tokens it removed, counted once and re-checkable against the original. secondwind never
estimates your bill; the token reduction is the ground truth.
Three ways to run it
Proxy: secondwind serve / run sits between your agent and the model API. Zero code
change, works with any agent (below).
Library (SDK): call Session directly in Python, Node/Bun, or sandboxed WebAssembly. No
proxy, no model download (In-process).
Middleware: drop-in adapters for LangChain, LangGraph, Agno, Strands, Cursor, LiteLLM, the
Vercel AI SDK, and ASGI (Adapters).
Same lossless-and-proven core in all three.
Install
Pick the surface you want: the proxy is a single binary, each library is one package.
# CLI / proxy: a prebuilt, checksum-verified binary (falls back to a source build)
curl -fsSL https://raw.githubusercontent.com/orchetron/secondwind/main/install.sh | sh
pip install secondwind # Python library and adapters
npm install secondwind # Node / Bun library and adapters
ALGORITHMICALLY RELATED
Similar Open-Source Projects
Selected from shared topics, language and repository description—not editorial ratings.
Rather build the CLI from source? cargo install --git https://github.com/orchetron/secondwind secondwind (needs Rust), or clone this repo and cargo install --path crates/cli.
Quickstart
Once the CLI is installed, two commands wire it up; then use your agent exactly as you always do:
secondwind setup # wire Claude Code once (registers the resolve tool)
secondwind run -- claude # run your agent through it, get a token receipt
Use Claude Code exactly as you normally would. When the session ends, you get a receipt:
Every rewrite is gated and verified lossless, and nothing about the agent's behavior
changes.
Then watch it work, and confirm the install:
secondwind proof # a local web dashboard of every block compressed, with lossless proof
secondwind watch # or a live terminal view, for a second pane next to your agent
secondwind check # verify the install: tokenizer, state, agent integration
Other agents and APIs
run is the fast path for any terminal agent. It launches the agent with its base URL
pointed at the proxy for that session, sets both ANTHROPIC_BASE_URL and OPENAI_BASE_URL
so Anthropic and OpenAI CLIs both work, and changes nothing on disk, so there is nothing to
undo and the proxy exits with the agent. With no argument it routes whatever known agent is
on your PATH:
secondwind run # detect an installed agent and route it
secondwind run -- codex # or name one; both base URLs are set for you
For a GUI or a persistent setup, run the shared endpoint and point the agent's own base URL
override at it:
secondwind serve & # hosts the optimizing endpoint on :8787
export ANTHROPIC_BASE_URL=http://127.0.0.1:8787 # an Anthropic-API agent
# or, for an OpenAI-API agent, set its base URL (OPENAI_BASE_URL / SDK base_url) to the same
The proxy detects the request shape per request and compresses the tool outputs in it,
whether the agent speaks the Anthropic Messages, OpenAI Chat Completions, OpenAI
Responses, or AWS Bedrock Converse format. Anything it cannot prove a win on passes
through with every value intact.
See one block compress
Point optimize at any tool-output block to watch it shrink and prove it. Straight from a
clone, with nothing installed, cargo run -p secondwind -- optimize <file> does the same:
secondwind optimize bench/compression/corpus/01-highcard-array.json
cargo run -p secondwind -- optimize examples/services.json # no install needed
That block went from 19,502 to 10,042 tokens, all 991 of its values are still present, and
the certificate lets secondwind verify re-check the compressed output against the
original. (The output above is trimmed to the salient fields; the command also prints the byte
counts and the full compressed wire.) More samples, one per tool-output shape, are in
examples/.
Use it in-process (library and adapters)
No proxy required: call secondwind directly in your own code, same lossless-and-proven core, in your
process. The native library is bundled, so there is no build step and no model download.
Python (pip install secondwind):
import secondwind
session = secondwind.Session()
out = session.rewrite(request) # compress a request's tool outputs, in place
print(out["stats"]) # tokens saved, counted once
secondwind.compress(block) # or compress a single block
Node and Bun (npm install secondwind; native FFI, or secondwind/wasm for a sandboxed build
that runs anywhere WebAssembly does, including the browser):
import { Session } from "secondwind";
const out = new Session().rewrite(request);
Any language can call the same shared library through its C ABI. Full API in the binding READMEs:
Python, Node.
Framework adapters
Drop-in, in-process, lossless. Each is a couple of lines; the binding READMEs carry the snippets.
framework
import
LangChain (LCEL)
from secondwind.langchain import compress_tool_outputs
LangGraph
from secondwind.langchain import compress_pre_model_hook
Agno
from secondwind.agno import SecondwindCompressionManager
Strands
from secondwind.strands import SecondwindHooks
Cursor
python -m secondwind.cursor (postToolUse hook)
LiteLLM
from secondwind.litellm import SecondwindCallback
ASGI (Starlette / FastAPI)
from secondwind.asgi import SecondwindMiddleware
Vercel AI SDK
import { secondwindMiddleware } from "secondwind/vercel"
LangGraph.js
import { compressPreModelHook } from "secondwind/langgraph"
One import and one wrap. Your framework's tool outputs compress losslessly on the way to the
model, and pass through untouched when they will not shrink.
Bring your own codec
The library runs a proof-gated best-of-N codec search, and you can add your own codec to it. It
competes with the built-ins and is proven decode(encode(x)) == x per block, so a wrong or reckless
codec is dropped, never shipped.
session = secondwind.Session(codec=MyCodec()) # or Session(proposers=False) to turn the search off
How it works
Your agent · Claude Code, Cursor, Codex, or any Anthropic, OpenAI, or Bedrock app
│ tool outputs · search results · logs · diffs · files · prose
▼
┌─ secondwind · runs locally, your data never leaves your machine ───────────
│
│ 1 · route each block by shape, run the matching compressor
│ uniform JSON arrays -> columnar codec (dict, affix, adaptive per-column)
│ search / grep / find -> shared path + snippet dictionary, or match-map
│ logs / CLI output -> line template + parameter extraction
│ diffs / patches -> per-file change-surface summary
│ long prose -> extractive coverage summary (or the --prose-classifier endpoint)
│ a repeated block -> byte-exact cross-turn dedup
│
│ 2 · rank which rows stay inline (relevance)
│ BM25 + relevance feedback + character trigram + distilled static
│ embeddings, or your own embedding model via --embed
│
│ 3 · apply only if it clears every gate
│ admission canonical leaf-multiset hash + coverage (lossless)
│ net-cost a real token reduction after overhead (a real win)
│ detectors fabrication · numeric drift · artifact loss (no harm)
│
└─ emit ─────────────────────────────────────────────────────────────────────
inline every value present, no round-trip
offload a short marker; the model calls resolve() for the exact
original, kept in a durable on-disk store
verbatim nothing was a proven win, so the block passes untouched
Responses stream from the model back to your agent byte for byte.
secondwind rewrites requests; it never rewrites a response.
Your agent calls a tool (reads a file, runs a search, lists an API), then feeds the result
back to the model on the next turn. That tool output is where the tokens pile up.
secondwind rewrites it three ways, in order of preference:
Reshape it inline. Uniform arrays, search results, logs, and diffs are re-encoded to
a compact form that still contains every value, so the model reads it directly with no
round-trip.
Offload it, recoverably. Bulk that will not shrink inline is replaced with a short
marker. The model fetches the exact original through the resolve tool (registered by
secondwind setup) whenever it needs it. Nothing is dropped, it is moved one hop away.
Leave it alone. If neither is a proven win, the block passes through byte for byte.
Offload activates only when the agent actually carries the resolve tool, so a marker can
never be stranded. The response path is a pure byte pipe: secondwind reads requests and
never touches responses.
Relevance and prose (optional)
Query-aware relevance keeps the rows a request is about inline and offloads the rest. It
runs on a thin, baked-in embedding table by default. Add --embed <url> --embed-model <name> to rank with your own embeddings model instead.
--prose summarizes long prose into a shorter, recoverable working summary.
--prose-classifier <url> points at your own extractive keep/drop endpoint for
token-level shrink. Both keep the full original one resolve call away.
Architecture
secondwind runs entirely on your machine. Nothing leaves it except the compressed request,
which goes to the same model API your agent already uses.
On your machine remote
───────────────────────────────────────────── ──────────
your agent ──── request ────► secondwind ──── compressed ───► Model
(any API) ◄─── response ────