Framework-agnostic, provider-agnostic context-window packer for LLM chat history.
Project description
convopack
Framework-agnostic, provider-agnostic context-window packer for LLM chat history.
Why
LLM apps accumulate messages until they overflow the model's context window. Existing fixes are framework-locked (LangChain, LangGraph), provider-specific (Anthropic context-management beta), or designed for long-term semantic memory rather than turn-by-turn packing (mem0).
convopack is a small, focused library that takes a conversation history and a token budget and returns the largest tail that fits, while:
- preserving
tool_use/tool_resultpairs atomically, - normalising message shapes across OpenAI, Anthropic, and Gemini,
- letting you plug in any tokenizer or summariser,
- staying async-friendly and zero-dependency at the core.
Install
pip install convopack # core only
pip install "convopack[tiktoken]" # + OpenAI tokenizer
pip install "convopack[anthropic]" # + Anthropic tokenizer
pip install "convopack[all]" # everything
# or with uv
uv add convopack # core
uv add "convopack[all]" # everything
The library ships a py.typed marker; mypy --strict and pyright both
recognise its public types without further configuration.
Quickstart
from convopack import Packer, Recency
packer = Packer(
budget=8000,
tokenizer="tiktoken:gpt-4o",
strategy=Recency(),
pin=["system", "first_user"],
)
packed = packer.pack(messages) # list[dict] in, list[dict] out
Strategies
| Strategy | When to use |
|---|---|
Recency |
Keep the tail that fits. Cheapest, no LLM call. |
FirstFit |
Keep the oldest chunks that fit. Good when system + few-shots dominate. |
SummaryEvict |
Summarise evicted turns into a single system message. |
Importance |
Score each turn yourself; drop the lowest until it fits. |
SemanticDedup |
Remove near-duplicate turns by embedding cosine, then fall back. |
Comparison
| Feature | convopack | LangChain trim_messages |
mem0 | Anthropic native |
|---|---|---|---|---|
| Framework-free | yes | no | no | yes |
| Multi-provider message shapes | yes | partial | n/a | no |
| Tool-call pair safety | yes | no | n/a | yes (one type) |
| Pluggable strategy | yes | no | n/a | no |
| Async summariser | yes | no | n/a | n/a |
| Scope | per-turn | per-turn | cross-session | per-turn |
Example notebooks
Self-contained Jupyter notebooks. Every one runs end-to-end without an API
key (they use the zero-dependency approx tokenizer and deterministic
fakes). All four are executed in CI to stay in sync with the library.
| Notebook | What it covers |
|---|---|
01_quickstart.ipynb |
Build a Packer, pack a history, round-trip through OpenAI shape, scan budgets. |
02_tool_pair_atomicity.ipynb |
The killer feature: tool_use / tool_result pairs stay together for every strategy. Includes a 200-iteration property check. |
03_strategies.ipynb |
Same history through all five strategies side-by-side. |
04_prompt_caching.ipynb |
Anthropic cache_control markers, OpenAI prefix-stability signature, cost back-of-envelope. |
Rendered with outputs at https://mrrobi.github.io/convopack/notebooks/01_quickstart/.
License
MIT
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file convopack-0.3.2.tar.gz.
File metadata
- Download URL: convopack-0.3.2.tar.gz
- Upload date:
- Size: 43.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c0ec5ce10e1b8e4cc0df82e1dc1813ffcd8d552c8cb16a153857b303bbebf22f
|
|
| MD5 |
635a0da86d6191821b534e071edd0e21
|
|
| BLAKE2b-256 |
e371a3625d2caae7c686ab30c2666868a4aa9887cc4089bb8de40512f7579f7f
|
Provenance
The following attestation bundles were made for convopack-0.3.2.tar.gz:
Publisher:
release.yml on Mrrobi/convopack
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
convopack-0.3.2.tar.gz -
Subject digest:
c0ec5ce10e1b8e4cc0df82e1dc1813ffcd8d552c8cb16a153857b303bbebf22f - Sigstore transparency entry: 1626806631
- Sigstore integration time:
-
Permalink:
Mrrobi/convopack@0a87eba957f2a8a2f1e5864866c3849de08a3e3f -
Branch / Tag:
refs/tags/v0.3.2 - Owner: https://github.com/Mrrobi
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@0a87eba957f2a8a2f1e5864866c3849de08a3e3f -
Trigger Event:
push
-
Statement type:
File details
Details for the file convopack-0.3.2-py3-none-any.whl.
File metadata
- Download URL: convopack-0.3.2-py3-none-any.whl
- Upload date:
- Size: 42.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
fd1659205097fd25786d26e94c4a937a236678e5feaaee1227423b1dab6f2b1d
|
|
| MD5 |
597b5e17ab8c3b301a282a9d7e50a102
|
|
| BLAKE2b-256 |
c6aef9cae158edd80e5d3c4798c12541e65a22367d70a9c5e18ad5f90c2dcfa4
|
Provenance
The following attestation bundles were made for convopack-0.3.2-py3-none-any.whl:
Publisher:
release.yml on Mrrobi/convopack
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
convopack-0.3.2-py3-none-any.whl -
Subject digest:
fd1659205097fd25786d26e94c4a937a236678e5feaaee1227423b1dab6f2b1d - Sigstore transparency entry: 1626806650
- Sigstore integration time:
-
Permalink:
Mrrobi/convopack@0a87eba957f2a8a2f1e5864866c3849de08a3e3f -
Branch / Tag:
refs/tags/v0.3.2 - Owner: https://github.com/Mrrobi
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@0a87eba957f2a8a2f1e5864866c3849de08a3e3f -
Trigger Event:
push
-
Statement type: