Metadata-Version: 2.4
Name: powerailabs-contextkit
Version: 0.6.0
Summary: Assemble: declare prioritized, pinnable context blocks; pack them to a token budget with an inspectable receipt.
Author: Raghav Mishra
License-Expression: Apache-2.0
License-File: LICENSE
License-File: NOTICE
Requires-Python: >=3.11
Requires-Dist: powerailabs-core<0.2,>=0.1
Provides-Extra: squeeze
Requires-Dist: powerailabs-squeeze<0.2,>=0.1; extra == 'squeeze'
Description-Content-Type: text/markdown

# powerailabs-contextkit

Treat the context window like a packed suitcase, not a string you concatenate. Declare blocks
with priorities and eviction rules; contextkit fits them to a token budget and tells you exactly
what it kept, shrank, and dropped.

**Every assembled prompt comes with a receipt.**

![PyPI](https://img.shields.io/pypi/v/powerailabs-contextkit) ![license](https://img.shields.io/badge/license-Apache_2.0-blue) · `pip install powerailabs-contextkit`

```python
from powerailabs.contextkit import Context, Block

ctx = Context(budget_tokens=8000, model="claude-opus-4-8", reserve_output=1000, order="attention")
ctx.add(Block(system_prompt, priority=10, pin=True, role="system"))
ctx.add(Block(retrieved_docs, priority=5, evict="compress"))        # uses squeeze if installed
ctx.add(Block(messages=chat_history, priority=3, evict="drop_oldest"))  # peels OLDEST turns
ctx.add(Block(user_msg, priority=9, pin=True, role="user"))

messages = ctx.assemble()      # provider-ready, guaranteed within budget — including framing
print(ctx.report())            # the receipt: kept / truncated / dropped + token math
preview = ctx.whatif(budget_tokens=4000)   # same inputs, tighter budget, no commit
```

**Within budget means *within budget*.** `report().used == tokens.count(assemble(), model)`: packing
charges the per-message framing providers add around every turn, so a "full" prompt doesn't quietly
overflow once sent.

**Inbound** — call it *before* the model call. Deterministic packing; per-block eviction
(`drop_oldest`/`truncate`/`summarize`/`compress`, or your own `EvictionStrategy` object).
`Block(messages=[...])` holds a conversation segment and `drop_oldest` peels the *oldest* turns (a
sliding window); `Block(evict="truncate", keep="tail")` keeps the end and leaves a `…[truncated]`
marker. `order="attention"` (lost-in-the-middle) or `order="cache"` (stable prefix). Adapters for
OpenAI, Anthropic (`for_anthropic`), Gemini (`for_gemini`), and Bedrock (`for_bedrock`), multimodal-safe.
`aassemble()` awaits async (LLM) summarizers; `image_tokens` charges multimodal blocks (int or a
resolution-aware callable). The `report()` flows onto core's bus, so `acttrace` records what the model
actually saw. `evict="compress"` goes through core's `Compressor` *protocol* — squeeze is the default
backend, and `use_compressor(...)` swaps in any other (e.g. an ML-based compressor) without touching
call sites.

See [`docs/contextkit.md`](https://github.com/PowerAI-Labs/powerailabs/blob/main/docs/contextkit.md) · [CHANGELOG](https://github.com/PowerAI-Labs/powerailabs/blob/main/packages/powerailabs-contextkit/CHANGELOG.md). *Part of the PowerAI Labs stack — [github.com/PowerAI-Labs/powerailabs](https://github.com/PowerAI-Labs/powerailabs). Apache-2.0; provided "as is", without warranty — use at your own risk (LICENSE §7–8).*
