Skip to content

How it works

cmx is a local gateway. Your harness talks to it exactly like it talks to the model provider; cmx forwards to the real upstream, transparently managing context along the way.

Terminal window
harness ──▶ cmx gateway (127.0.0.1:17322) ──▶ model provider
└─ TUI: cmx
  1. Stable message IDs

    On every proxied request, older messages get tagged with stable markers:

    <cmx-id-m0001> …original message content… </cmx-id-m0001>

    The most recent messages — the “tail” you configured with keep_recent_tokens — are left byte-identical, which is what keeps your provider’s prompt cache hitting.

  2. The compress tool

    cmx advertises a compress tool to the model (adding it only if your harness hasn’t already defined one). When the model judges that a span of earlier messages is stale — old tool outputs, abandoned approaches, long logs — it calls:

    { "ids": ["m0003-m0009"], "reason": "stale exploration replaced by newer findings" }
  3. Interception + summarization

    The compress call is stripped from the response — your harness never sees it. Instead, cmx asks the same provider (or a cheaper summarizer_model) to distill the span into dense factual bullets: decisions, file paths, commands, errors, outcomes.

  4. Rewrite on the next turn

    Next turn, covered messages are replaced:

    <cmx-id-compressed>
    [Summary cX of m0003-m0009 — earlier content compressed]
    - user wants X; constraints Y
    - tried A (failed: …); working from B
    - next: C
    </cmx-id-compressed>

    Overlapping compressions nest naturally: a later summary that covers an older summary substitutes the older text in place.

  • The recent tail (last keep_recent_tokens of context) — never compressed
  • The final message of every request (the current turn)
  • Messages using protected tools (task, skill, todowrite, todoread, write, edit by default)
  • Exact code and error content the model still needs — the tool description tells the model not to compress anything it still depends on

When context grows past min_context_tokens, cmx appends a small system reminder listing compressible IDs every nudge_frequency requests. The model decides. No summarization happens without an explicit compress call.

OpenAI-style Anthropic-style
Endpoint /v1/chat/completions /v1/messages
Streaming (SSE)
Tool calls
Usage/caching stats

OpenAI Responses requests (/v1/responses), including current Codex traffic, are forwarded transparently. The hosted dashboard is a separate, optional Cloudflare surface; local gateway operation does not depend on it.