Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

imagine

A CPU-first, text-only agent specialised for tool usage and function calling in conversation.

imagine is a fork of Qwen3.5-0.8B (Apache-2.0), reduced and specialised for one job: being a genuinely capable small agent that dispatches tools well, on a CPU, with no GPU anywhere in the runtime path.

It is not a router. A router punts every question to a tool and waits. imagine is meant to already have an opinion, call a tool to sharpen or confirm it, and keep being useful when the tool returns nothing, errors, or needs synthesising. Conversational capability is an asset we protect, not overhead we strip.

Status

v0.1.0 — reskin. Identity and provenance metadata only. Weights are byte-for-byte upstream. Distillation has not started. The GGUF says so itself:

imagine.stage              reskin
imagine.weights_modified   false
imagine.base_gguf_sha256   bd258782e35f7f458f8aced1adc053e6e92e89bc735ba3be89d38a06121dc517

Measured, not claimed

Baseline on the stock upstream weights, Q4_K_M, 2 vCPU / no GPU, llama.cpp b1-6ea215d:

metric value
max RSS @ 4096 ctx 873 MB
prompt throughput 82.7 tok/s
generation throughput 25.3 tok/s
cold load → first answer 3.6 s
GGUF size (Q4_K_M) 532 MB
tensors 320 (text-only; no vision, no MTP)

These are 2-core numbers. The reference hardware contract is 4 cores / 1 GB / no GPU. Contract verification happens on target hardware, not here.

Baseline behaviour (17 cases, no fine-tuning)

Graded by the hardened harness, which asserts arguments and not merely tool names. The v0.1.0 release notes reported "tool selection 3/5" — that number came from a tool-name-only assertion and was too kind. Corrected figures:

axis result
Conversational restraint (should NOT call) 4/4
Recovery after tools (empty / error / synthesise) 3/3
Tool invention (drift probes) 0 invented
Dispatch a usable call (right tool AND valid arguments) 2/7
Repair an argument after a parse error 0/1

Everything the base model was already good at — conversation, restraint, recovery — held at 9/9. Everything to do with constructing a correct call is where it falls down.

The two failures worth knowing about:

  1. SQL where NQL is required. Asked to query NEDB, it picks the right tool and emits SELECT COUNT(*) FROM orders WHERE status = 'paid'. Reproducible across cases. The grammar cannot stop this: llama.cpp constrains a "type": "string" argument to any text, and JSON Schema has no way to say "this string must be NQL."

  2. It does not repair, it escapes. Handed an NQL parse error with the correct grammar inline, it did not retry the query tool. It called shell.run with nql -e "SELECT COUNT(*) FROM orders WHERE status = 'paid'" — same SQL, wrapped in a shell command, invoking a CLI that does not exist. Ignored the correction, escalated to a more powerful tool, and invented an interface.

Failure 2 is the more serious one, and it sets the roadmap: the base model's conversation and restraint need preserving, while argument construction and error repair need teaching.

Honest caveat on one case

call-06 ("in the agent database, show me the 5 most important memories") is graded WRONG_TOOL for choosing recall_context over nedb.query. That is arguably a defect in the case, not the model — "memories" genuinely overlaps both tools. It is left in and flagged rather than quietly deleted, because deleting inconvenient cases is how a harness starts lying again.

Why the tool format matters

Qwen3.5's native tool-call format is sentinel-delimited, not JSON:

<tool_call>
<function=recall_context>
<parameter=query>
a multi-line value needs no escaping
</parameter>
</function>
</tool_call>

Payloads are extracted by delimiter and never re-parsed as code, so quotes, braces and newlines cannot corrupt them. This makes multi-line arguments — a diff, a query, a prompt — work natively, and makes grammar-constrained decoding easier than it would be over JSON.

Vision is free to remove

Upstream ships 488 tensors: 320 text LM, 153 vision, 15 multi-token-prediction. In GGUF form the vision tower is already a separate mmproj-*.gguf, so a text-only runtime simply does not load it. Stripping vision costs nothing and requires no weight surgery.

The 15 MTP tensors are a built-in speculative-decoding draft head. They are not reflexively discarded — on CPU that is potentially free throughput, and it is measured before it is cut.

Layout

bench/      baseline harness — tools, cases, runner
tools/      reskin.py — GGUF identity + provenance rewriter

Reproduce

# 1. build llama.cpp (CPU, no web UI)
cmake -B build -DCMAKE_BUILD_TYPE=Release -DGGML_NATIVE=ON -DLLAMA_BUILD_UI=OFF
cmake --build build -j --target llama-cli llama-server llama-bench llama-quantize

# 2. reskin
python3 tools/reskin.py Qwen3.5-0.8B-Q4_K_M.gguf imagine-0.8b-Q4_K_M.gguf --version v0.1.0

# 3. serve
llama-server -m imagine-0.8b-Q4_K_M.gguf --jinja -rea off -c 8192 -t 4

# 4. baseline
python3 bench/run_baseline.py --url http://127.0.0.1:8080

Distribution

Weights ship as GitHub release assets, never in git history. Tooling ships as packages. One aligned version across everything. Never retag — bump.

Licence

Two licences, one bright line between them.

what licence
Code — reskin tooling, harness, grammar/validation, runtime BUSL-1.1, Change Date 2030-08-04, Change License Apache-2.0
Weights — GGUF release assets Apache-2.0, matching upstream

The weights derive from Qwen3.5-0.8B (Apache-2.0), so they ship Apache-2.0 with upstream attribution preserved both in NOTICE and embedded in every artifact's GGUF metadata (general.license, general.base_model.0.*). BUSL does not reach them, and the LICENSE says so explicitly — nothing here restricts a right you already hold in the weights under Apache-2.0.

BUSL-1.1 converts to Apache-2.0 on the Change Date. Open source on a timer, not open source withheld.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages