Skip to content

About

Native Rust (egui) desktop tool that turns a product and audience description into one core need, one promise and three ad placements, then grades the copy for groundedness. Offline TextRank engine plus Claude engines.

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Latest commit

 

History

10 Commits

Folders and files

Repository files navigation

Compressor

A native desktop tool that collapses the abstraction stack between a product and the customer who needs it.

You paste in a product description and a description of who you think the customer is, pick an engine, and Compressor returns one tight artifact:

  • one plainly stated core need,
  • one honest one sentence promise connecting the product to that need,
  • and that promise expressed for three ad placements: Meta primary text, a Google headline set, and a landing page hero.

One input, one tight output. No variation spam. Every result is then graded for groundedness (how much of its claim bearing vocabulary the product actually supports), checked for readability and hype, and, for the deterministic engine, shown with its full work.

Stack: Rust, egui/eframe (glow renderer), tokio and reqwest with rustls. The model backed engines call the Anthropic Messages API (default model claude-opus-4-8, set in src/engine/llm.rs). Ships as one Windows .exe.


Download

Get the latest build from the Releases page and pick the file for your system from under Assets:

System File
Windows compressor-vX.Y.Z-x86_64-pc-windows-msvc.zip (unzip, then run compressor.exe)
macOS, Apple Silicon (M1 and later) compressor-vX.Y.Z-aarch64-apple-darwin.tar.gz
macOS, Intel compressor-vX.Y.Z-x86_64-apple-darwin.tar.gz
Linux x86_64 compressor-vX.Y.Z-x86_64-unknown-linux-gnu.tar.gz

Each is a single self contained program, no install required. SHA256SUMS.txt lets you check the download.

The binaries are not code signed. On Windows, SmartScreen may warn about an "unknown publisher": click More info, then Run anyway. On macOS, the first time, right-click the program and choose Open.

The Heuristic engine runs with no API key; for the Hybrid and LLM engines, paste an Anthropic API key into the window (see Setting the API key). compressor --help and compressor --version print a short usage note without opening the window.

There is no cargo install compressor: that crate name on crates.io belongs to an unrelated audio project. To build it yourself, see Building and running.


Screenshots

A Hybrid run on the built in load example (Ledger), showing the compression readout, the promise graded at 100% inked, the placements, and the proof sheet.

Compressor: input, compression readout, core need, promise graded for groundedness

Compressor: Google headlines, landing hero, and the proof sheet with ranked promise impressions


Three engines behind one interface

The core architectural move is a CompressionEngine trait with three implementations the UI can pick between at runtime:

Engine What it is Needs a key
Heuristic Deterministic, model free. Extractive core need (TextRank), templated promise slotting with scored candidate selection, pure placement formatters. Fully grounded by construction and explainable. Runs offline. No
Hybrid The model writes the copy; the deterministic layer audits it (groundedness) and attaches the explainability trace. Using AI and keeping it honest. Yes
LLM The Anthropic Messages API writes the copy. The scorer still grades it for honesty. Yes

The groundedness scorer sits outside all three and grades whatever any of them produces. Run it on the model's promise and you can literally show "this promise is 92% grounded; this one drifted to 60%, and here are the unsupported claims."


The three questions

1. What does the tool do?

Marketing tools mostly generate. You ask for ad copy and they hand back a wall of options, then you spend an hour deciding which layer of abstraction to trust. Compressor does the opposite. It takes the two things you actually know (what the product is, and who you think needs it) and removes the layers between them until one need and one promise are left standing, then renders that promise into the three placements you ship most, at the lengths those placements demand.

Crucially, it does this two ways. The deterministic engine never calls a model: it extracts the need, slots input derived terms into a promise, scores the candidates, and shows its work. The model engines write more fluent copy. And the same groundedness math grades all of them, so the AI output is held to the same honesty standard as the deterministic one.

The thesis is compression, not generation. Removing layers, not adding noise.

2. Why build this one?

Because the failure mode of AI marketing copy is volume and drift. Twelve headlines is not a decision, it is twelve more decisions, and a fluent promise that quietly claims a capability the product does not have is worse than no copy at all. Compressor encodes the discipline that actually moves conversion: name the real need in plain language, make a single defensible promise, and measure how far any copy has drifted from what the product literally is.

The groundedness scorer is the part an API wrapper structurally cannot match, and the deterministic engine's explainability ("core need extracted from sentence 3, TextRank 0.81; promise template 2 selected; 94% grounded") is a transparency no model backed tool can offer. The constraint is the product.

3. What would you build next if it were your full time job?

The deterministic engine, the groundedness scorer, the hybrid audit, the A/B candidate scoring, the readability and constraint checks, and the explainability panel are all built. Next, in rough priority order:

  • Batch / CSV mode. Media buyers work at scale. Drop in a CSV of products, get a compression per row, exported back to CSV, parallelized across rows with rayon. This reframes the tool from a toy to something a team runs Monday morning.
  • Schema enforced LLM output. Move the model engines to the Messages API output_config.format with a JSON schema, so malformed output becomes structurally impossible rather than handled after the fact.
  • Streaming. Stream the model response so the core need appears the instant it is ready.
  • Local persistence. Save runs to SQLite (or a flat JSON history) so the tool remembers across sessions, and let the user diff two audiences for the same product side by side.
  • Destination exports. A "copy for Meta Ads Manager" action and a Google RSA shaped export, because knowing the destination matters, not just the copy.
  • A real POS tagger for slot extraction, to sharpen the deterministic promise's grammar beyond the current frequency and lexicon heuristics.

Setting the API key

The Hybrid and LLM engines need an Anthropic API key. The Heuristic engine needs nothing and runs entirely offline.

The simplest way: paste it into the window. Open compressor.exe, paste your key into the masked Anthropic key bar at the top, and use the tool. No files, no environment variables. Tick remember on this device if you want the app to load it automatically next time. (Remembering writes the key in plain text under your user profile at %APPDATA%\Compressor\key.txt; leave it unticked to keep the key in memory for the session only.)

Or set the environment variable, which the app uses as a fallback when the key bar is empty:

$env:ANTHROPIC_API_KEY = "sk-ant-..."   # current session
setx ANTHROPIC_API_KEY "sk-ant-..."     # persist for your user
export ANTHROPIC_API_KEY="sk-ant-..."

If a model engine is selected with no key from either source, the app does not crash; it reports the ANTHROPIC_API_KEY environment variable is not set in the error card. The key is never hardcoded.


Building and running

You need a stable Rust toolchain (built with Rust 1.91). On Linux, install the windowing and OpenGL headers first, for example on Debian or Ubuntu: sudo apt-get install libx11-dev libxcursor-dev libxrandr-dev libxi-dev libxkbcommon-dev libwayland-dev libgl1-mesa-dev.

git clone https://github.com/Mattbusel/compressor
cd compressor
cargo run            # development
cargo run --release  # optimized
cargo test           # run the analysis and engine unit tests

The deterministic engine works with no key, so cargo run then selecting Heuristic is the fastest way to see it work end to end.


Producing the .exe

cargo build --release

The single self contained executable is written to target/release/compressor.exe (roughly 4 MB, no runtime dependencies beyond the system graphics stack). The release profile is tuned for a small binary: size optimization (opt-level = "z"), link time optimization, a single codegen unit, panic = "abort", and symbol stripping. The Windows console is suppressed in release via windows_subsystem = "windows".


Architecture

Each module has one responsibility and its own document in docs/.

Module Responsibility Doc
domain The typed vocabulary. Illegal states unrepresentable. docs/domain.md
text Dependency free text primitives (tokenize, stem, syllables). docs/text.md
analysis The deterministic measurement layer: TextRank, groundedness, readability, constraints. docs/analysis.md
prompt Pure construction of the system and user prompts. docs/prompt.md
engine The CompressionEngine trait and its three engines. docs/engine.md
app The egui UI, the custom theme, the async to UI bridge. docs/app.md

Data flows one direction. The app validates raw text into domain newtypes, dispatches to the selected engine (which may use analysis and text), grades the result with the analysis groundedness scorer, and renders it.

app (UI)  ->  domain (ProductInput, AudienceInput)
              |
              v
        engine::run(kind, ...)  ->  Heuristic | Hybrid | LLM   ->  EngineOutput
              |                          (uses analysis + text + prompt)
              v
     analysis::Grounded grades the output, outside the engine
              |
              v
        app renders the result, the score, and the explainability trace

A note on the code as a teaching artifact

Throughout the source and these docs, the Rust primitives in use are named and briefly explained where they appear: the newtype pattern, enum sum types, Result and thiserror, traits and async fn in traits, boxed futures for runtime dispatch, the mpsc channel, OnceLock, power iteration, lifetimes, and the design token approach to theming.

About

Native Rust (egui) desktop tool that turns a product and audience description into one core need, one promise and three ad placements, then grades the copy for groundedness. Offline TextRank engine plus Claude engines.

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages