Catalog PyPI
PACKAGE EXPLORERView in registry

agentaicommunity-agent-context-compression

PyPI

Context compression middleware for AI agent frameworks — automatically summarizes conversation history when token limits are approached

agentaicompressioncontextllmmiddlewaresummarizationtokens
Versions collected1
Direct dependencies2From release 0.1.0
Last observed20 Oct, 21:27 UTC

README

Version 0.1.0 documentation

🗜️ AzureAICommunity - Agent - Context Compression Middleware

Automatic conversation history compression middleware for AI agent applications built on the Agent Framework.

PyPI Version Python Versions PyPI Downloads License PyPI Status GitHub Follow YouTube Channel YouTube Subscribers LinkedIn

**Keep long multi-turn

Getting Started · Configuration · Usage · Contributing


Overview

agentaicommunity-agent-context-compression is a plug-and-play context management layer for AI agent pipelines built on agent-framework. It counts tokens in the conversation history before each LLM call, and when the count approaches your configured limit it automatically summarises the older messages — keeping the session alive without hitting context-window errors.


✨ Features

Feature
🗜️Automatic compression — fires transparently when the token threshold is hit
⚙️Configurable trigger — set max_tokens and trigger_ratio to match your model's context window
🔒Keep recent messages — keep_last_messages preserves the tail of the conversation verbatim
🔧Tool-call aware — keeps assistant + tool message pairs together during split
🔔Block or allow — on_threshold_reached callback lets you log, alert, or stop the request
📝Structured logging — pass your own logging.Logger; no print() calls
📊Token usage tracking — last_usage on the middleware instance after each call (both modes)
🌊Streaming support — works transparently with stream=True; usage captured via framework hooks
🔌Provider-agnostic — works with any agent-framework LLM client (Ollama, OpenAI, Azure, etc.)

📦 Installation

pip install agentaicommunity-agent-context-compression

Or install from source:

cd ContextCompression
pip install -e .

🚀 Quick Start

Non-streaming

import asyncio
import logging
from agent_framework.ollama import OllamaChatClient
from context_compression import ContextCompressionMiddleware, TokenThresholdReachedError

logging.basicConfig(level=logging.INFO)

summarizer = ContextCompressionMiddleware(
    llm_client=OllamaChatClient(model="gemma3:4b"),  # LLM used to write the summary
    max_tokens=8000,        # compress when history approaches this size
    trigger_ratio=0.80,     # fire at 80% = 6400 tokens
    keep_last_messages=8,   # always keep the 8 most recent messages verbatim
    logger=logging.getLogger("ContextCompression"),
)

agent = OllamaChatClient(model="gemma3:4b").as_agent(
    name="MyAgent",
    instructions="You are a helpful assistant.",
    middleware=[summarizer],
)
session = agent.create_session()

async def main():
    for message in ["Hi, my name is Vinoth.", "I work in Python.", "What is my name?"]:
        response = await agent.run(message, session=session)
        print(response.text)

asyncio.run(main())

Streaming

async def main():
    messages = ["Hi, my name is Vinoth.", "I work in Python.", "What is my name?"]
    for message in messages:
        stream = agent.run(message, session=session, stream=True)
        async for update in stream:
            chunk = getattr(update, "text", None)
            if chunk:
                print(chunk, end="", flush=True)
        print()
        await stream.get_final_response()  # finalizes stream and populates last_usage

asyncio.run(main())

🧑‍💻 Usage

Threshold Callback Payload

Every call to on_threshold_reached receives a dict:

{
    "tokens_used":    87,   # current history token count
    "max_tokens":    100,   # your configured max
    "trigger_tokens": 75,   # the threshold that was crossed
}

Return True → compression proceeds normally.
Return False → request is blocked and TokenThresholdReachedError is raised.

Token Usage After Each Call

last_usage is populated after every call — both streaming and non-streaming:

# Non-streaming
response = await agent.run("Hello", session=session)

# Streaming
stream = agent.run("Hello", session=session, stream=True)
async for update in stream:
    pass
await stream.get_final_response()

# Either way, last_usage is populated:
u = summarizer.last_usage
print(u["input_token_count"])   # tokens sent to LLM
print(u["output_token_count"])  # tokens in the response
print(u["total_token_count"])   # input + output

Handling TokenThresholdReachedError

from context_compression import ContextCompressionMiddleware, TokenThresholdReachedError

try:
    response = await agent.run(message, session=session)
except TokenThresholdReachedError as e:
    print(f"Blocked: {e}")
    # handle gracefully — notify user, end session, etc.

⚙️ Configuration

ContextCompressionMiddleware

ParameterTypeDefaultDescription
llm_clientany LLM clientrequiredClient used to generate the summary (can be a smaller/cheaper model)
max_tokensint8000History size limit (tiktoken count)
trigger_ratiofloat0.80Compression fires at max_tokens × trigger_ratio
keep_last_messagesint8Number of recent messages to keep verbatim after compression
model_encodingstr"cl100k_base"tiktoken encoding for token counting
on_threshold_reachedCallable[[dict], bool]NoneCallback fired at threshold. Return True to compress, False to block
loggerlogging.LoggerNoneYour logger. Falls back to logging.getLogger(__name__)

Blocking runaway sessions

def my_callback(info: dict) -> bool:
    if info["tokens_used"] > 500_000:
        return False   # block — raises TokenThresholdReachedError
    return True        # allow compression

middleware = ContextCompressionMiddleware(
    ...,
    on_threshold_reached=my_callback,
)

Provider Compatibility:
Works with any LLM client that implements the agent-framework ChatClient interface.


🤝 Contributing

Contributions are welcome! Please open an issue to discuss what you'd like to change before submitting a pull request.

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/my-feature)
  3. Commit your changes (git commit -m 'Add my feature')
  4. Push to the branch (git push origin feature/my-feature)
  5. Open a Pull Request

👤 Author

Built and maintained by Vinoth Rajendran.


📄 License

MIT — see LICENSE for details.

Downloads & popularity

2downloads
1-day window · source-reported counts20 Oct 2026
94.50
2026-07-23: 2 · observed 2026-10-21T11:46:42.5882891Z · period 2026-07-23–2026-07-232026-07-24: 1 · observed 2026-10-21T11:46:42.5882891Z · period 2026-07-24–2026-07-242026-07-27: 3 · observed 2026-10-21T11:46:42.5882891Z · period 2026-07-27–2026-07-272026-07-28: 1 · observed 2026-10-21T11:46:42.5882891Z · period 2026-07-28–2026-07-282026-07-29: 2 · observed 2026-10-21T11:46:42.5882891Z · period 2026-07-29–2026-07-292026-08-01: 1 · observed 2026-10-21T11:46:42.5882891Z · period 2026-08-01–2026-08-012026-08-02: 1 · observed 2026-10-21T11:46:42.5882891Z · period 2026-08-02–2026-08-022026-08-09: 2 · observed 2026-10-21T11:46:42.5882891Z · period 2026-08-09–2026-08-092026-08-14: 6 · observed 2026-10-21T11:46:42.5882891Z · period 2026-08-14–2026-08-142026-08-17: 2 · observed 2026-10-21T11:46:42.5882891Z · period 2026-08-17–2026-08-172026-08-23: 3 · observed 2026-10-21T11:46:42.5882891Z · period 2026-08-23–2026-08-232026-08-24: 9 · observed 2026-10-21T11:46:42.5882891Z · period 2026-08-24–2026-08-242026-08-28: 5 · observed 2026-10-21T11:46:42.5882891Z · period 2026-08-28–2026-08-282026-08-31: 2 · observed 2026-10-21T11:46:42.5882891Z · period 2026-08-31–2026-08-312026-09-06: 1 · observed 2026-10-21T11:46:42.5882891Z · period 2026-09-06–2026-09-062026-09-07: 1 · observed 2026-10-21T11:46:42.5882891Z · period 2026-09-07–2026-09-072026-09-10: 1 · observed 2026-10-21T11:46:42.5882891Z · period 2026-09-10–2026-09-102026-09-12: 1 · observed 2026-10-21T11:46:42.5882891Z · period 2026-09-12–2026-09-122026-09-14: 2 · observed 2026-10-21T11:46:42.5882891Z · period 2026-09-14–2026-09-142026-09-16: 1 · observed 2026-10-21T11:46:42.5882891Z · period 2026-09-16–2026-09-162026-09-20: 4 · observed 2026-10-21T11:46:42.5882891Z · period 2026-09-20–2026-09-202026-09-22: 2 · observed 2026-10-21T11:46:42.5882891Z · period 2026-09-22–2026-09-222026-09-23: 1 · observed 2026-10-21T11:46:42.5882891Z · period 2026-09-23–2026-09-232026-09-26: 1 · observed 2026-10-21T11:46:42.5882891Z · period 2026-09-26–2026-09-262026-09-27: 3 · observed 2026-10-21T11:46:42.5882891Z · period 2026-09-27–2026-09-272026-09-29: 1 · observed 2026-10-21T11:46:42.5882891Z · period 2026-09-29–2026-09-292026-09-30: 1 · observed 2026-10-21T11:46:42.5882891Z · period 2026-09-30–2026-09-302026-10-02: 1 · observed 2026-10-21T11:46:42.5882891Z · period 2026-10-02–2026-10-022026-10-04: 1 · observed 2026-10-21T11:46:42.5882891Z · period 2026-10-04–2026-10-042026-10-06: 1 · observed 2026-10-21T11:46:42.5882891Z · period 2026-10-06–2026-10-062026-10-08: 3 · observed 2026-10-21T11:46:42.5882891Z · period 2026-10-08–2026-10-082026-10-09: 2 · observed 2026-10-21T11:46:42.5882891Z · period 2026-10-09–2026-10-092026-10-10: 2 · observed 2026-10-21T11:46:42.5882891Z · period 2026-10-10–2026-10-102026-10-11: 2 · observed 2026-10-21T11:46:42.5882891Z · period 2026-10-11–2026-10-112026-10-12: 2 · observed 2026-10-21T11:46:42.5882891Z · period 2026-10-12–2026-10-122026-10-13: 1 · observed 2026-10-21T11:46:42.5882891Z · period 2026-10-13–2026-10-132026-10-14: 6 · observed 2026-10-21T11:46:42.5882891Z · period 2026-10-14–2026-10-142026-10-15: 2 · observed 2026-10-21T11:46:42.5882891Z · period 2026-10-15–2026-10-152026-10-16: 2 · observed 2026-10-21T11:46:42.5882891Z · period 2026-10-16–2026-10-162026-10-17: 7 · observed 2026-10-21T11:46:42.5882891Z · period 2026-10-17–2026-10-172026-10-18: 3 · observed 2026-10-21T11:46:42.5882891Z · period 2026-10-18–2026-10-182026-10-20: 2 · observed 2026-10-21T11:46:42.5882891Z · period 2026-10-20–2026-10-20
23 Jul20 Oct

pypistats · 42 observations shown. Missing days are unknown. Source category: overall: without mirrors.

View observed values
Date / source periodValueObserved at
2026-10-20 – 2026-10-2022026-10-21T11:46:42.5882891Z
2026-10-18 – 2026-10-1832026-10-21T11:46:42.5882891Z
2026-10-17 – 2026-10-1772026-10-21T11:46:42.5882891Z
2026-10-16 – 2026-10-1622026-10-21T11:46:42.5882891Z
2026-10-15 – 2026-10-1522026-10-21T11:46:42.5882891Z
2026-10-14 – 2026-10-1462026-10-21T11:46:42.5882891Z
2026-10-13 – 2026-10-1312026-10-21T11:46:42.5882891Z
2026-10-12 – 2026-10-1222026-10-21T11:46:42.5882891Z
2026-10-11 – 2026-10-1122026-10-21T11:46:42.5882891Z
2026-10-10 – 2026-10-1022026-10-21T11:46:42.5882891Z
2026-10-09 – 2026-10-0922026-10-21T11:46:42.5882891Z
2026-10-08 – 2026-10-0832026-10-21T11:46:42.5882891Z
2026-10-06 – 2026-10-0612026-10-21T11:46:42.5882891Z
2026-10-04 – 2026-10-0412026-10-21T11:46:42.5882891Z
2026-10-02 – 2026-10-0212026-10-21T11:46:42.5882891Z
2026-09-30 – 2026-09-3012026-10-21T11:46:42.5882891Z
2026-09-29 – 2026-09-2912026-10-21T11:46:42.5882891Z
2026-09-27 – 2026-09-2732026-10-21T11:46:42.5882891Z
2026-09-26 – 2026-09-2612026-10-21T11:46:42.5882891Z
2026-09-23 – 2026-09-2312026-10-21T11:46:42.5882891Z
2026-09-22 – 2026-09-2222026-10-21T11:46:42.5882891Z
2026-09-20 – 2026-09-2042026-10-21T11:46:42.5882891Z
2026-09-16 – 2026-09-1612026-10-21T11:46:42.5882891Z
2026-09-14 – 2026-09-1422026-10-21T11:46:42.5882891Z
2026-09-12 – 2026-09-1212026-10-21T11:46:42.5882891Z
2026-09-10 – 2026-09-1012026-10-21T11:46:42.5882891Z
2026-09-07 – 2026-09-0712026-10-21T11:46:42.5882891Z
2026-09-06 – 2026-09-0612026-10-21T11:46:42.5882891Z
2026-08-31 – 2026-08-3122026-10-21T11:46:42.5882891Z
2026-08-28 – 2026-08-2852026-10-21T11:46:42.5882891Z
2026-08-24 – 2026-08-2492026-10-21T11:46:42.5882891Z
2026-08-23 – 2026-08-2332026-10-21T11:46:42.5882891Z
2026-08-17 – 2026-08-1722026-10-21T11:46:42.5882891Z
2026-08-14 – 2026-08-1462026-10-21T11:46:42.5882891Z
2026-08-09 – 2026-08-0922026-10-21T11:46:42.5882891Z
2026-08-02 – 2026-08-0212026-10-21T11:46:42.5882891Z
2026-08-01 – 2026-08-0112026-10-21T11:46:42.5882891Z
2026-07-29 – 2026-07-2922026-10-21T11:46:42.5882891Z
2026-07-28 – 2026-07-2812026-10-21T11:46:42.5882891Z
2026-07-27 – 2026-07-2732026-10-21T11:46:42.5882891Z
2026-07-24 – 2026-07-2412026-10-21T11:46:42.5882891Z
2026-07-23 – 2026-07-2322026-10-21T11:46:42.5882891Z

Versions 1

Collected releases
VersionPublishedDirect dependenciesOpen version
0.1.020 Apr 20262

Package advisories

0
No matching advisories collected

This describes our collected data; it is not a security assessment.

Repository

PENDING
agent-ai-community/agent-context-compression

Shared repository data · GitHub

License detected in repository
Not collected

Metadata history

Meaningful changes
Current collected state Current

Observed since 20 Oct, 21:27 UTC

No superseded metadata states collected. Unchanged observations do not create new revisions.

Record identity

package:28f3b9459374635988589acbe0706f61a5b391e6d2894a0d0d17da431645fa98