Skip to main content
Back to integrations
FrameworkContext provider

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+.

1. Installation and setup

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.

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

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):

config.tomltoml
[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

2. Architecture & execution flow

1

Installing llmslim registers the provider through the gptme.context_providers entry point, so get_context_provider("llmslim") and list_providers() find it.

2

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.

3

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.

4

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.

5

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.

6

Messages are never removed or reordered, and role, timestamp, call_id and the other fields are kept. The result is gptme's CompactionResult.

3. Runnable example and its output

gptme_provider.pypython
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):

outputtext
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.

4. Options

Keyword arguments, shown as name = default.

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.

5. Deployment best practices

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.

6. Key optimization 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.

7. 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].

Frequently asked questions

Troubleshooting

Further reading