Skip to content

hemlang/hembot

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

22 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Hembot

test

An interactive coding agent for the Hemlock programming language. Written in Hemlock, of course.

Hembot talks to a local llama-server running a Hemlock-tuned model (default: Hemlock-Apothecary-7B), extracts Hemlock code from its responses, runs it in a sandbox, and can optionally feed errors back so the model fixes its own bugs.

Use it in your terminal, over an HTTP API, or in a cute little web chat:

hembot web UI

Setup

  1. Install Hemlock 2.0+ and make sure hemlock is on your PATH.
  2. Install llama-server from llama.cpp.
  3. Grab a GGUF of a Hemlock-tuned model, e.g. Hemlock-Apothecary-7B quantized to Q8_0.
  4. Launch the server in another terminal:
    llama-server -m Hemlock-Apothecary-7B-Q8_0.gguf --port 8199 --ctx-size 8192 -ngl -1
  5. Run Hembot (interpreted):
    hemlock src/hembot.hml
    Or build a self-contained binary and run that:
    make build
    ./hembot

Usage

╔══════════════════════════════════════╗
║  Hembot — Hemlock Coding Agent       ║
╚══════════════════════════════════════╝

you> write a program that prints the first 10 fibonacci numbers
Hembot: ```hemlock
fn main() {
    let a = 0; let b = 1;
    for (let i = 0; i < 10; i++) {
        print(a);
        let t = a + b; a = b; b = t;
    }
}
main();

── sandbox: ✓ ran cleanly 0 1 1 2 3 5 8 13 21 34 ──


## Flags

| Flag | Default | Description |
|------|---------|-------------|
| `--url <url>` | `http://127.0.0.1:8199/v1/chat/completions` | OpenAI-compatible endpoint |
| `--model <name>` | `local` | Model name sent to the server |
| `--system <path>` | `system_prompt.txt` | System prompt file |
| `--no-exec` | off | Don't execute code blocks, just show them |
| `--retry` | off | Auto-retry up to 3 times when extracted code fails (hybrid strategy: feedback first, then cold resamples) |
| `--no-stream` | off | Disable token streaming; wait for the full response before printing |
| `--no-spinner` | off | Silence the "thinking" spinner and the timing line (clean scripted output) |
| `--serve` | off | Run an HTTP API instead of the interactive REPL (see below) |
| `--port <n>` | `8080` | Port to bind when serving |
| `--host <addr>` | `127.0.0.1` | Address to bind when serving |

## HTTP API

Run hembot as a local HTTP service instead of the REPL — handy for editors,
scripts, or other tools:

```bash
hemlock src/hembot.hml --serve --port 8080
# or the compiled binary:  ./hembot --serve --port 8080

It points at the same --url llama-server as the REPL. Each request is stateless (a fresh [system, user] conversation).

Open http://localhost:8080/ in a browser for a little 🌿 kawaii chat UI (served from web/index.html; pass --no-ui to disable, or --ui <path> to point elsewhere).

GET /health{"status":"ok","model":"local"}

POST /chat — generate, extract code, and (optionally) run it:

curl -s -X POST http://127.0.0.1:8080/chat \
  -d '{"prompt": "write a hemlock program that prints 7"}'
{
  "response": "```hemlock\nprint(7);\n```",
  "code": "print(7);",
  "sandbox": { "exit_code": 0, "output": "7\n" }
}
  • execute (optional, default true) — set to false to skip the sandbox; sandbox is then null.
  • code is null when the response contains no fenced Hemlock.
  • Bad/empty prompt400; an upstream model failure → 502.

Project mode (multi-file)

Point hembot at a whole repo and give it tasks that span files:

hemlock src/hembot.hml --project path/to/repo
# task> add a heartbeat ping to the server

The agent sees a repo map (every file's path · exports · imports) and pulls file bodies in on demand. It drives the repo through a small tool protocol — @read, @grep, @write, @edit (search/replace), @delete, @run, @done — and edits land on the git working tree, so every change is a reviewable, revertible diff.

Flags: --whole-file edits by rewriting entire files instead of search/replace (slower / more tokens, but more reliable for weaker models); --max-steps <n> bounds the agent loop (default 12). Overwriting an existing file requires the agent to @read it first.

Slash commands

At the you> prompt:

  • /reset — clear conversation (keeps system prompt)
  • /save <file> — save conversation as JSON
  • /load <file> — resume a saved conversation
  • /help — list the above

Project layout

.
├── src/
│   ├── hembot.hml        # Agent entry point (main loop, I/O, chat)
│   ├── extract.hml       # Pure helpers for parsing LLM responses
│   └── config.hml        # CLI argument parsing and defaults
├── tests/
│   ├── test_extract.hml  # 11 unit tests for extraction
│   └── test_config.hml   # 7 unit tests for config
├── .github/workflows/
│   └── test.yml          # CI: build Hemlock, run the unit tests
├── system_prompt.txt     # The winning hembench prompt
├── package.json          # hpm metadata
└── README.md

Building and testing

make build       # compile hembot binary via hemlockc
make test        # run unit tests under the interpreter (no LLM needed)
make run         # run the agent interpreted
make install     # install to /usr/local/bin (honours PREFIX + DESTDIR)
make clean       # remove build artifacts

# Also wired up as hpm scripts, but note there's an upstream hpm bug
# that throws at exit — the command still runs:
hpm run build
hpm test

CI builds Hemlock from source on each push/PR and runs the full test suite. Tagged pushes (v*) trigger a release workflow that compiles hembot with hemlockc and attaches a Linux x86_64 tarball to the GitHub release.

Why was this system prompt chosen?

The system_prompt.txt shipped here won a prompt sweep on Hemlock-Apothecary-7B (Q8_0) using hembench. It beat the benchmark's baseline prompt by ~13 points overall and pushed L4 (systems programming) from 57% to 86% pass rate.

Key ingredients:

  • Hembot persona (aligns with how the base model was fine-tuned)
  • Mention of interpreter availability so the model "mentally traces" before writing code
  • Seven common-pitfall reminders (semicolons, print() single-arg, / float, ptr_deref_*, etc.)

License

MIT

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Packages

 
 
 

Contributors