Type. The model is already answering. There is no send button.
This is not a duplex socket and it does not stream your keystrokes on one connection. Each pause in typing aborts the last chat completion and starts another with the whole draft. The interesting part is the UX: wait until the last word looks stable, never rewrite a bubble, stack a new reply, kill the previous stream hard.
git clone https://github.com/scalattice/dont-hit-send.git
cd dont-hit-send
export SCALATTICE_API_KEY=slt_...
./run.sh
# → http://127.0.0.1:8766./run.sh creates a venv, installs, and starts the server. Pass-through flags work: ./run.sh --host 0.0.0.0 --port 8766.
Defaults to Scalattice (https://api.scalattice.cloud/v1). Any OpenAI-compatible /v1/chat/completions works. Settings in the UI, or:
export OPENAI_BASE_URL=https://api.example.com/v1
export OPENAI_API_KEY=...
export DHS_MODEL=your-model
./run.shGet a Scalattice key at scalattice.cloud. Live demo: scalattice.com/dont-hit-send.
- Debounce ~350ms, then fire
- Hold if the last token looks like a half-word (
and Nwhile you typeand NASA) - Abort empty in-flight streams; stack a new reply instead of mutating the last one
- Meters: streams started, aborted, time to first token, rough token count
The client is dont_hit_send/static/app.js. The server is a tiny stdlib proxy so the key never sits in the browser. No extra Python packages.
dont-hit-send --host 0.0.0.0 --port 8766Docker:
docker build -t dont-hit-send .
docker run --rm -p 8766:8766 -e SCALATTICE_API_KEY=slt_... dont-hit-sendConfig file, if you save a key in Settings: ~/.dont-hit-send/config.json (override with DHS_DATA_DIR).
MIT