# LLMSlim + gptme

> A gptme context provider for automatic compaction and /compact trim. Older tool output is compressed instead of being replaced by a stub.

LLMSlimContextProvider is a gptme context provider backed by LLMSlim. It keeps the system prompt, the first messages, pinned messages, tool calls and the latest turns exactly as they are, and compresses older tool output and history until the conversation fits gptme's limit. Tool output keeps its failures, tracebacks and line structure. It runs locally, with no model call. Python 3.10+.

Category: Framework

## Install

```bash
pip install "llmslim[gptme]"   # gptme 0.34 or newer, Python 3.10+; needs llmslim 0.9.0 or newer
```

The extra installs gptme 0.34 or newer and needs Python 3.10 or newer. Installing llmslim registers two gptme entry points, so there is nothing to import or register yourself. gptme pins mcp<2, while llmslim[mcp] and llmslim[agents] need mcp>=2, so they cannot share an environment; that is also why llmslim[all] does not include gptme.

To make LLMSlim the provider gptme's own compaction uses, turn it on in ~/.config/gptme/config.toml (or in a project's gptme.toml, which overrides the user file key by key):

```toml
[plugin.llmslim]
compaction = true
# Optional:
keep_recent = 6      # most recent messages kept verbatim (tool output in them is still capped)
min_tokens = 200     # shorter messages are never compressed
```

## How it fits

- Installing llmslim registers the provider through the gptme.context_providers entry point, so get_context_provider("llmslim") and list_providers() find it.
- gptme's automatic compaction and /compact trim always ask for the provider named "default". With [plugin.llmslim] compaction = true, the gptme.plugins entry point makes LLMSlim that provider; without it, gptme's own compaction is unchanged.
- compress(messages, config) keeps exactly as they are: the leading system messages, the first config.keep_head messages, pinned messages, assistant messages that contain a tool call or a code block, and the user and assistant messages among the last keep_recent.
- Tool output longer than config.max_tool_result_tokens (2,000 by default) is compressed to that size. If the conversation is still over config.limit (80% of the model's context when gptme passes no limit), the older messages are compressed by one shared ratio.
- If that is not enough, the oldest are replaced by a one-line placeholder, and as a last resort recent tool output is compressed below its cap.
- Messages are never removed or reordered, and role, timestamp, call_id and the other fields are kept. The result is gptme's CompactionResult.

## Example

```python
from gptme.message import Message
from gptme.tools.autocompact.context_provider import CompressionConfig, get_context_provider

from llmslim import count_tokens

# 300 lines of test output with one failure, as gptme's shell tool would return it.
lines = [f"tests/test_api.py::test_case_{i} PASSED" for i in range(300)]
lines.insert(200, "tests/test_refund.py::test_rounding FAILED - AssertionError: 10.05 != 10.04")
test_output = "Ran command: `pytest -q`\n" + "\n".join(lines)

log = [
    Message("system", "You are gptme, a coding agent.", pinned=True),
    Message("user", "Fix the failing refund test."),
    Message("assistant", "Running the tests.\n```shell\npytest -q\n```"),
    Message("system", test_output),
    Message("assistant", "One test fails: test_rounding. Reading refund.py next."),
    Message("user", "Go ahead."),
]

provider = get_context_provider("llmslim")  # found through llmslim's entry point
result = provider.compress(log, CompressionConfig(limit=1000, keep_head=2))

for before, after in zip(log, result.messages):
    print(f"{before.role:9} {count_tokens(before.content):5} -> {count_tokens(after.content):4} tokens")
print(result.limitations[0])
print()
print(result.messages[3].content)
```

Output (Python 3.12, gptme 0.34.0, token counts from tiktoken):

```text
system       10 ->   10 tokens
user          6 ->    6 tokens
assistant    12 ->   12 tokens
system     3631 ->   91 tokens
assistant    13 ->   13 tokens
user          3 ->    3 tokens
LLMSlim extractive compression: 3,675 -> 135 tokens; budget 1,000; 1 compressed, 0 dropped

Ran command: `pytest -q`
tests/test_api.py::test_case_0 PASSED
... [198 similar lines]
tests/test_api.py::test_case_199 PASSED
tests/test_refund.py::test_rounding FAILED - AssertionError: 10.05 != 10.04
tests/test_api.py::test_case_200 PASSED
... [98 similar lines]
tests/test_api.py::test_case_299 PASSED
```

gptme stores tool output as system messages. The test output is over gptme's 2,000-token limit for a single tool result, so it is compressed even though it is recent: the failure and its neighbours stay, and the runs of passing tests collapse into a count. This output is a favourable case, because near-identical lines compress very well; prose is compressed only as far as the budget requires. The tool call that produced the output is kept as it is, so the model still sees which command ran.

## Options

| Option | Default | Meaning |
|---|---|---|
| `keep_recent` | `6` | Most recent messages kept verbatim (their tool output is still capped). |
| `min_tokens` | `200` | Messages with at most this many tokens are not compressed. |
| `relevance` | `"lexical"` | "lexical", "semantic" (needs llmslim[semantic]) or a callable scorer(query, texts) -> scores. |
| `additional_compress_kwargs` | `None` | Other llmslim.ContextCompressor options, for example mode. |

## Deployment

Install llmslim[gptme] and set compaction = true under [plugin.llmslim] in ~/.config/gptme/config.toml or in a project's gptme.toml. Without it the plugin does nothing and gptme's own compaction is unchanged. /compact summarize is not affected; it still asks the model for a summary. Set options in the same [plugin.llmslim] table, as keyword arguments, or with LLMSlimContextProvider.configured(...), which returns a class for register_provider.

## Tips

- Turn compaction on in a project's gptme.toml when only some projects should use LLMSlim; it overrides the user file key by key.
- Raise keep_recent to keep more of the latest messages verbatim. Tool output in them is still capped at config.max_tool_result_tokens.
- Messages with at most min_tokens tokens are never compressed; raise it to leave more short messages untouched.
- Use LLMSlimContextProvider.configured(...) to build a provider class with your own options for register_provider.

## Limitations

- Needs llmslim 0.9.0 or newer, gptme 0.34 or newer and Python 3.10 or newer. The 0.9.0 release was tested with gptme 0.34.0.
- gptme pins mcp<2, while LLMSlim's MCP catalog support (llmslim[mcp], llmslim[agents]) needs mcp>=2, so the two cannot share an environment. llmslim[all] does not include gptme.
- gptme imports the plugins of all installed packages at startup unless you keep a [plugins] enabled = [...] allowlist, so with llmslim installed gptme also imports llmslim (and NumPy and scikit-learn) when it starts.
- When compression is not enough, the oldest messages are replaced by a one-line placeholder such as [3,631 tokens of earlier tool output omitted by LLMSlim].

## FAQ

### Do I need to import or register anything?

No. Installing llmslim registers two gptme entry points. gptme.context_providers lets get_context_provider("llmslim") and list_providers() find the provider; gptme.plugins makes LLMSlim the provider gptme's own compaction uses when [plugin.llmslim] compaction = true is set.

### Which gptme commands does it change?

gptme's automatic compaction and /compact trim, which always ask for the provider named "default" (gptme's development branch also uses it for context-overflow recovery). /compact summarize is not affected; it still asks the model for a summary.

### Does it call a model?

No. It runs locally, with no model call. Token counts use llmslim.count_tokens (tiktoken when installed).

### Why is gptme not in llmslim[all]?

gptme pins mcp<2, while LLMSlim's MCP catalog support (llmslim[mcp], llmslim[agents]) needs mcp>=2, so the two cannot share an environment.

### Which gptme versions are supported?

gptme 0.34 or newer, on Python 3.10 or newer. The 0.9.0 release was tested with gptme 0.34.0.

## Troubleshooting

- **ImportError: llmslim.integrations.gptme requires gptme 0.34 or newer:** Install the extra in the same environment as gptme, on Python 3.10 or newer: pip install "llmslim[gptme]". The provider needs llmslim 0.9.0 or newer.
- **gptme's compaction does not use LLMSlim:** Set compaction = true under [plugin.llmslim] in ~/.config/gptme/config.toml or the project's gptme.toml. Without it the plugin does nothing. A project's gptme.toml overrides the user file key by key.
- **pip cannot install llmslim[gptme] together with llmslim[mcp] or llmslim[agents]:** gptme pins mcp<2 and LLMSlim's MCP catalog support needs mcp>=2, so they cannot share an environment. Install them in separate environments.

## Further reading

- [gptme guide on GitHub](https://github.com/Thanatos9404/llmslim/blob/main/docs/integrations/GPTME.md)
- [Provider source: llmslim/integrations/gptme.py](https://github.com/Thanatos9404/llmslim/blob/main/llmslim/integrations/gptme.py)
- [gptme context compression docs](https://gptme.org/docs/context-compression.html)
- [Benchmarks](https://www.llmslim.app/benchmarks.md)

Canonical page: https://www.llmslim.app/integrations/gptme
