Skip to content

chore(release): v1.0.0 - #3

Merged
eraflo merged 26 commits into
mainfrom
dev
Oct 9, 2026
Merged

eraflo merged 26 commits into
mainfrom
dev

Conversation

@eraflo

@eraflo eraflo commented Oct 9, 2026

Copy link
Copy Markdown
Owner

Calcine 1.0.0, the first stable release. Merge with a merge commit (not squash): release.yml then builds and publishes v1.0.0 (Windows installer, Linux .deb, updater manifest, SHA256SUMS, SBOM, provenance).

Release notes: the ## 1.0.0 section of CHANGELOG.md.

Also brings to main (and so to the website and the repository page) the privacy policy and the code signing policy that SignPath reviews.

Tested on 0.2.0-beta.4 (same code minus the version and changelog):

  • Windows and Linux ARM64 packages build and sign in CI; the Linux .deb installs on a clean Ubuntu 24.04 and installs GenieX
  • Workspace tests, clippy, typecheck, Biome and Vitest on Windows; tests and clippy on Linux ARM64
  • Manual checklist on a Snapdragon PC (docs/RELEASING.md)

🤖 Generated with Claude Code

eraflo and others added 26 commits October 8, 2026 23:24
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Chat: Precise / Balanced / Creative presets, top-p, top-k, min-p,
penalties, seed, stop sequences, offloaded layers, and saved system
prompts. Optional settings are only sent when set, so GenieX's defaults
apply otherwise.

Measured on GenieX 0.8: seed and ngl only apply to llama.cpp models, and
stop is ignored over the API, so the chat cuts the reply at the first
stop sequence itself. nctx sent per request is ignored too: the context
window is now a server option.

Server page: Model loading card with the unload delay (--keepalive) and
the llama.cpp context window (--nctx), saved in server.json. Changing
them restarts a running GenieX.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A button in the chat header saves the conversation as a .md file through the system save dialog: one section per message, reasoning folded in <details>, attachments named. The file name is cleaned up for Windows.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Open WebUI must run on this PC, not in Docker, since Calcine only listens on loopback; the snippet says so. Comments are in the UI language.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Auto, CPU or NPU for llama.cpp vision models (vit_compute). GenieX 0.8 rejects the GPU here, so it isn't offered.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The Library's import dialog state moves to the UI store so the palette can open it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A button in the chat header loads the model with the chat's settings (compute unit, offloaded layers) through a one-token request. Measured with Qwen3-4B on the NPU: first token in 0.15 s after preloading, 13.3 s without.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Apps that only speak Ollama can use Calcine's models. /api/version,
tags, show, ps, chat and generate are translated to GenieX's OpenAI API
(images, options, think, format, tools) and answered as JSON lines or
one object, like Ollama. Model management stays in the app (501).

On the main port these routes need a key as usual. Settings › Local API
› Ollama apps also opens 127.0.0.1:11434, where callers need no key but
can only run models. The listener is known from the socket, never from
headers, and Host and Origin checks still apply. Off by default; a port
taken by Ollama itself is reported.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Measures time to first token, prompt reading and generation speed of a
model on each compute unit (NPU, hybrid, GPU, CPU), with one warmup and
repeated runs on a fixed random prompt, using geniex-bench.

- The tool is downloaded on demand at the installed GenieX's version
  from its GitHub release; GitHub's digest and the published .sha256
  must agree. Unpacked with Windows' tar into Calcine's data folder.
- One process per unit: in matrix mode a failure stops the rest. A failed
  unit is recorded with its error; geniex serve is paused meanwhile and
  started again afterwards.
- Results are kept in benchmarks.json: latest session as bars with the
  spread, fastest models, history with CSV export, and real-world speed
  from the request log.
- Jobs report steps ("Measuring 2 of 4"); phase and step changes are no
  longer throttled. The Markdown export becomes save_export (Markdown or
  CSV).

Verified on a Snapdragon X Elite: Qwen3-0.6B on the NPU 51.9 tok/s, first
token 38.7 ms; SmolVLM-256M on NPU, hybrid, GPU and CPU.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…g policy

Prepares Calcine for the SignPath Foundation's code signing program.

- Installers contain Calcine only. GenieX includes Qualcomm's proprietary
  runtimes, which SignPath can't sign, so the welcome screen downloads
  the official installer from Qualcomm and checks it against the SHA-256
  pinned in runtime/geniex.json, built into the app. The error shown when
  GenieX is missing links to it. fetch-geniex.ts becomes check-geniex.ts.
- PRIVACY.md lists every connection Calcine makes. The installer's
  license page shows a summary with the MIT license (kept in sync by a
  test), and Settings › Calcine updates gets "Check for updates
  automatically" to stop the startup checks (GitHub, Qualcomm).
- README and website: privacy and code signing policy sections (roles,
  build, approval), and GenieX wording updated.

BREAKING CHANGE: GenieX is no longer bundled; first launch needs internet
to install it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
llama.cpp models can guess tokens ahead and keep those the model agrees
with: n-gram methods (no extra model) or a draft model from the library
(draft-simple, EAGLE-3, MTP), with optional draft sizes and probability.

- Chat: a Speculative decoding section; each reply shows how many
  guesses were kept, from GenieX's timings (draft_n, draft_n_accepted).
- Benchmark: the same choice, passed to geniex-bench (--spec-type,
  --draft-model), shown in results, kept apart in the fastest models and
  exported in the CSV, so runs with and without can be compared.

Measured on GenieX 0.8: spec_type is one comma-separated string, draft
models resolve by name. On SmolVLM-256M (GPU) n-gram cache kept 3 of 18
guesses in the Chat; the draft-model path couldn't be checked without a
compatible pair of GGUF models.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
GenieX 0.8 ignores response_format and grammars in API requests, on
QAIRT and llama.cpp alike, so the gateway enforces them: it adds an
instruction with a filled-in example built from the schema, extracts
and checks the JSON (a JSON Schema subset), and asks the model to fix
it, twice at most. Clients get the checked JSON in the usual OpenAI
shape, streamed or not, or a 422 explaining what never matched.

- OpenAI API: response_format json_object and json_schema.
- Ollama API: format "json" or a schema, same checks.
- Chat: Output format (Text, JSON, Schema with a schema editor); JSON
  replies show as a formatted block.

Measured on the NPU: Qwen3-4B and Qwen3-0.6B (QAIRT) return valid,
conforming JSON; the example made the 0.6B pass where the bare schema
failed three times.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
GenieX 0.8 handles tools natively (calls, parallel calls, streaming,
tool results) but ignores tool_choice. The gateway now enforces it:
"none" removes the tools; "required" or a named function asks for the
call as JSON, with only that function offered, checks the name and the
arguments against the parameters, retries, and answers tool_calls.

Measured on the NPU: Qwen3-4B skipped tools it thought it didn't need
and Qwen3-0.6B ignored the instruction through the native format, while
both write the JSON call reliably. Examples now use named placeholders
("<city>"), which small models replace instead of copying "...", and a
copied placeholder is sent back for a fix (structured output too).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
AI Hub models have their context window compiled in (4096 tokens for
most) and GenieX refuses longer prompts; its sliding window only exists
in `infer`/`run`. Calcine now:

- counts prompts with each model's tokenizer.json plus the chat
  template's share, matching GenieX's counts within 2 tokens;
- shows how full the conversation is in the Chat;
- forgets the oldest exchanges when asked (`"truncation": "auto"`,
  always for Ollama clients as Ollama does, on by default in the Chat),
  marking what the model no longer sees. The Chat cuts down to 75% of
  the room so the start stays put and GenieX keeps reusing its cache:
  on Qwen3 0.6B the next reply started in 90 ms instead of 1.1 s;
- works around GenieX 0.8 counting its cached conversation against the
  window when a request doesn't continue it (a regenerated reply, another
  client): it empties the cache with a one-token request and retries;
- explains context_length_exceeded errors and how to avoid them.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The context meter pushed the header's buttons over the settings panel
on smaller windows. The header now adapts to the chat column (a
container query): the model picker shrinks, the runtime badge and the
meter's numbers go first, then the meter and the preload and export
buttons when the column is very narrow.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Below 1200 px wide, the conversations, the chat and the settings don't
fit side by side and the chat got squeezed. The panel now starts hidden
there and shown on wider windows; opening or closing it holds for that
size of window.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
When a conversation outgrows the context window, the model now writes a
summary of what it stops seeing (folding in the previous one), kept in
its system prompt: the start of the prompt stays put until the next cut,
so GenieX keeps reusing its cache. The divider shows the summary, the
reply shows "Summarizing the oldest messages…" meanwhile, and "Keep a
summary" can be turned off.

Measured on the NPU: asking for a summary of a quoted transcript, small
models followed instructions inside it ("Reply Got it") and a JSON list
of facts didn't help; sending the forgotten turns as the chat did, then
asking, works, and reuses GenieX's cache (1.7 s on Qwen3 0.6B). A
repetition penalty and dropping repeated sentences stop Qwen3 4B from
looping.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The SoC's energy metering (EMI) shows in Windows' `Energy Meter`
counters: on Snapdragon X, the whole system (SYS), the CPU clusters and
the GPU, but no NPU channel (its work shows in SYS). The meters only
open for administrators, and the counters are translated (PDH can't add
them by their English names on a French Windows), so Calcine finds them
through PerfLib's English names and reads the translated paths.

- Hardware: live power of the whole system, CPU and GPU.
- Benchmark › Energy: a model's speed and energy on each compute unit
  and power mode, through geniex serve: load in the mode, measure idle,
  read the meter around each generation. Energy per token above idle and
  for the whole system, tokens per joule, the most efficient highlighted.

Measured: Qwen3-0.6B on the NPU, about +10 W above idle at 87 tok/s
(~110 mJ/token); SmolVLM-256M (llama.cpp) is most efficient on the CPU
(59 mJ/token vs ~280 on GPU and NPU). Power modes, per request or for
the server, changed neither speed nor energy on mains power.

Also fixes the benchmark form's effect re-running on every render
("Maximum update depth exceeded").

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
An optional, separate port (0.0.0.0:18443 by default) serves the same
API to other devices; the loopback API is unchanged. Off by default.

- HTTPS only, with rustls and ring (no cmake or nasm), HTTP/1.1 and
  HTTP/2. The certificate is self-signed, made on this PC with rcgen for
  its name, name.local and address; its SHA-256 fingerprint is shown to
  pin it, certificate.pem can be imported, and it can be renewed.
- A key is always needed there, it must be allowed for other devices
  (new "From other devices" option), Calcine's own token is refused, and
  keys never reach local files.
- Only allowed addresses connect: private networks by default (Tailscale
  included), or the ranges listed. 10 invalid keys within a minute block
  an address for 5 minutes.
- Turning it off also closes the connections still open.
- Settings › Local network: switch, address, fingerprint, certificate,
  port, allowed addresses.

Tested for real from the LAN address with a client trusting only
certificate.pem: models listed, chat on the NPU, missing or wrong keys
refused, untrusted clients refused.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
`calcine-cli` is a console program built from the app's crate (the app
is a windowed program, so terminals neither wait for it nor show its
output). It runs the same services and gateway as the window
(`setup::build`), with the app's settings, keys and data folder.

- `serve [--port N] [--network] [--network-port N]`: serves until
  Ctrl+C, Ctrl+Break or the console closing, then stops geniex serve;
  prints the addresses, the certificate fingerprint and one line per
  request. If the window already serves the port, it says so.
- `keys list | create <name> [--manage] [--network] [--local-files] |
  revoke <id>`.
- The key store reads api-keys.json again when another program changed
  it, so a key created or revoked from the CLI (or the window) counts at
  once in the other one.
- The installer puts calcine-cli.exe next to calcine.exe (checked in the
  generated NSIS script).

Also fixes the type errors that failed CI on the last two commits:
f64 fields come as `number | null`, serde-defaulted settings as optional.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
`calcine-cli path add|remove|status` changes the user's own PATH
(HKCU\Environment) through the registry API, keeping its REG_EXPAND_SZ
type, and tells Windows so new terminals see it. The installer runs
`path add` after installing and the uninstaller `path remove`: doing it
in NSIS would cut a PATH longer than 1024 characters short.

Tested on a throwaway registry value, never the real PATH; the hooks are
in the generated installer script and makensis builds it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Changing the network settings stopped the old listener without waiting
for it, so binding the same port again could fail ("already used") and
leave the port off. Restarting now waits until the old listener is gone.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- GenieX on Linux: installs the official archive to
  ~/.local/share/geniex-cli (pinned SHA-256, like the Windows installer),
  runs it with its libraries and the parent-death signal, falls back to the
  CPU where the compute DSP isn't exposed, and explains a missing chipset.
- Hardware: NPU (FastRPC), Adreno GPU and SoC from /dev and /sys.
- calcine-cli: geniex install and geniex chipset, for machines without a
  screen; the .deb puts it in /usr/bin.
- Packaging: signed .deb (needs ocl-icd-libopencl1) built on
  ubuntu-24.04-arm for releases and betas, with Linux entries in the
  updater manifest; ARM64 build and tests in CI for main.
- UI: startup, network and Mica wording per system.
- API keys: notice changes made by another program even within one
  timestamp tick (size and inode too).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
SignPath asks for the policy on download pages; the notes also say which
file is for Windows and which for Linux.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Linux ARM64 preview, calcine-cli, the network port, structured output and
tools, long conversations, benchmark and energy across the README, the
website (with the Linux package link), PRIVACY.md, SECURITY.md and
CONTRIBUTING.md.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@eraflo
eraflo merged commit d56e5db into main Oct 9, 2026
18 checks passed
@eraflo
eraflo deleted the dev branch October 9, 2026 23:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant