Skip to main content

context-pipe

PyPI - Version PyPI - Python Version License: MIT CI/CD

Extensible conversation context management toolkit for LLM applications.

context-pipe manages conversation history within token budgets — storing messages, triggering summarization when the context window fills up, and persisting conversations to pluggable backends. Compaction logic is provider-agnostic: you inject whatever LLM call you want.

Installation

Install the base package:

uv add context-pipe

Or with optional backend support:

# With in-memory backend
uv add context-pipe[memory]

# With Redis backend
uv add context-pipe[redis]

# With SQLAlchemy backend
uv add context-pipe[sqlalchemy]

# With all backends
uv add context-pipe[all]

Quick Start

import asyncio
from context_pipe import (
    Conversation,
    Message,
    Role,
    WindowPolicy,
    CompactionEngine,
    AbstractCompactor,
)
from context_pipe_memory import MemoryBackend


class SimpleCompactor(AbstractCompactor):
    """A simple compactor that summarizes messages."""

    def summarize(self, messages: list[Message]) -> str:
        """Summarize messages by taking the first and last (sync)."""
        if not messages:
            return ""
        return f"Summary of {len(messages)} messages: {messages[0].content} ... {messages[-1].content}"

    async def asummarize(self, messages: list[Message]) -> str:
        """Summarize messages by taking the first and last (async)."""
        if not messages:
            return ""
        return f"Summary of {len(messages)} messages: {messages[0].content} ... {messages[-1].content}"


# Async example
async def async_example():
    # Create a conversation
    conv = Conversation(id="conv-1")

    # Add messages
    conv.append(
        Message(
            role=Role.USER,
            content="What is the capital of France?",
            token_count=10,
        )
    )
    conv.append(
        Message(
            role=Role.ASSISTANT,
            content="The capital of France is Paris.",
            token_count=12,
        )
    )

    # Set up compaction with a token budget
    policy = WindowPolicy(token_budget=100, trigger_at=0.8, keep_n_recent=2)
    compactor = SimpleCompactor()
    engine = CompactionEngine(policy=policy, compactor=compactor)

    # Use the backend to persist (async)
    backend = MemoryBackend()
    await backend.asave(conv)

    # Load and compact
    loaded = await backend.aload("conv-1")
    compacted = await engine.maybe_compact(loaded)
    await backend.asave(compacted)

    print(f"Total tokens: {compacted.total_tokens()}")
    print(f"Active messages: {len(compacted.active_messages())}")
    print(f"Summaries: {len(compacted.summaries)}")


# Sync example
def sync_example():
    # Create a conversation
    conv = Conversation(id="conv-2")

    # Add messages
    conv.append(
        Message(
            role=Role.USER,
            content="What is the capital of Germany?",
            token_count=10,
        )
    )
    conv.append(
        Message(
            role=Role.ASSISTANT,
            content="The capital of Germany is Berlin.",
            token_count=12,
        )
    )

    # Use the backend to persist (sync)
    backend = MemoryBackend()
    backend.save(conv)

    # Load (sync)
    loaded = backend.load("conv-2")
    print(f"Loaded conversation with {len(loaded.messages)} messages")


if __name__ == "__main__":
    # Run async example
    asyncio.run(async_example())
    
    # Run sync example
    sync_example()

Sync and Async APIs

context-pipe provides both synchronous and asynchronous versions of all backend methods and compactors, following Django's async conventions:

  • Async methods use an a prefix: asave(), aload(), adelete(), aexists(), asummarize()
  • Sync methods use regular names: save(), load(), delete(), exists(), summarize()

This allows you to use the same library in both async-first and sync-first applications:

# Async usage
backend = MemoryBackend()
await backend.asave(conversation)
loaded = await backend.aload(conv_id)

# Sync usage (same backend instance)
backend = MemoryBackend()
backend.save(conversation)
loaded = backend.load(conv_id)

Documentation

For detailed documentation, visit the full docs or see Getting Started.

Features

  • Flexible Storage — In-memory, Redis, SQLAlchemy, or custom backends
  • Sync/Async Dual API — Use the same library in sync-first or async-first applications
  • Token Budget Management — Automatic compaction when approaching context limits
  • Provider-Agnostic Compaction — Bring your own LLM or summarization logic
  • Type-Safe — Full type hints and mypy strict mode support
  • Extensible — Simple interfaces for custom backends and compactors

Contributing

We welcome contributions, suggestions, and ideas! context-pipe is designed to be extensible, and we're particularly interested in:

  • New Backend Implementations — Add support for additional storage systems
  • Compaction Algorithms — Propose or implement novel message summarization strategies
  • Token Counting Strategies — Different tokenization approaches for various LLM providers
  • Performance Optimizations — Improve compaction efficiency and backend speed
  • Documentation & Examples — Help us document use cases and best practices
  • Bug Reports & Feature Requests — Let us know how we can improve

How to Contribute

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/my-algorithm)
  3. Make your changes and ensure tests pass (uv run pytest)
  4. Submit a pull request with a clear description

Algorithm Contributions

If you're implementing a new compaction algorithm or backend strategy:

  • Add comprehensive docstrings explaining the approach
  • Include unit tests demonstrating the behavior
  • Update documentation with performance characteristics
  • Consider async/await patterns for consistency

See the Getting Started guide for development setup.

License

MIT

Metadata

Release files for context-pipe 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Built distribution (wheel)

Table of built distributions (wheels) for context-pipe 0.1.0
File Interpreter ABI Platform
context_pipe-0.1.0-py3-none-any.whl Python 3 none any Details

Release files / context_pipe-0.1.0-py3-none-any.whl

Download URL context_pipe-0.1.0-py3-none-any.whl
Size 7.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
b70e5963e01d654060d6817b8c3dc306c1eeaa53f9debffb1865ae05928bccad
BLAKE2b-256 checksum
How to use checksums
1ff33234ddc07bdabb00e61622600c6d8b73973351d2159ed6c25a90bd1dcc0e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Apr 9, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.1.0 This release

1 release file

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page