Skip to content

muninn v0.2.2

Latest

Choose a tag to compare

@scottlarkin scottlarkin released this 22 Sep 22:06
· 1 commit to main since this release

What's new

  • An optional classifier for the small decisions — off by default. Alongside
    its real work, muninn asks a language model a stream of narrow questions: is
    this recalled memory relevant to what you just typed, are these two entities
    the same thing, does this new lesson replace an older one, was that short
    message a correction. A new [jev] section points those questions at
    TypeSafe's Jev instead — a model that answers yes/no, pick-one and score
    questions with a typed value and a calibrated probability rather than prose.
    Turn it on with your own API key:

    [jev]
    enabled = true
    api_key = "env:TYPESAFE_API_KEY"
    

    Nothing else is required, and nothing changes until you do it. The questions
    it takes over are: filtering and ranking recalled memories, deciding whether
    two entities or two schema types are the same, choosing a parent type,
    judging which older lessons a new one supersedes, spotting a corrective
    message, and settling confident duplicate merges during background curation.

  • Every classifier path falls back to whatever decided it before. On an
    error, a timeout, or a probability that lands in the undecided band, the
    previous decision runs instead: your language model in most cases, and for
    correction detection the pattern list muninn has always used, which never
    involved a model. A missing key, an expired key or a provider outage degrades
    to the behaviour you had rather than to a wrong answer. An undecided answer is
    never read as a "no" — that distinction is what stops a slow reply from
    quietly minting a duplicate of an entity that already exists.

  • Recall is now ranked before it is trimmed. See Fixed below; it is the
    one change that lands whether or not you enable the classifier.

  • Two operator commands for a whole-graph pass. muninn jev audit sweeps the
    entire graph and writes a report of what the classifier thinks should change:
    duplicate entities found both by name and by vector neighbour, synonym schema
    types, types with no parent, lessons whose meaning depends on a missing
    referent, and lessons that supersede an older one. It writes nothing to the
    graph. muninn jev apply replays that report back through the same guarded
    merge paths the background curator already uses, with a dry run as the default
    and a probability floor you choose. On a graph of 32,500 entities the sweep
    took about four minutes and eleven cents; applying its verdicts merged 101
    duplicate entity pairs.

  • Health and spend are visible. muninn health reports
    jev: up | down | disabled, and the server's health endpoint carries a jev
    key once it is configured. A classifier that is down never flips the overall
    ok, because every path it serves has a working fallback — it is an
    accelerator, not a dependency. Its tokens are metered per tenant alongside
    model calls and keyed by its own model id, so you can see what it costs
    separately.

  • Where your data goes. While the classifier is off, which is the default,
    nothing new leaves the machine. With it on, the text behind each judgement is
    sent to a third-party API: the memories being ranked for a prompt, entity names
    and summaries, schema type names and descriptions, and lesson text. The
    whole-graph sweep is the deliberate exception — one run sends most of your
    entity names and summaries, every schema type and every lesson. If that trade
    is not one you want, leave the classifier off; everything works as it did.

Fixed

  • A highly relevant memory could be dropped from the injected context while a
    weaker one survived.
    Each section of the injected memory has a byte budget,
    and it trimmed from the end of the section — where "the end" was decided by
    retrieval order, not by the relevance grade the recall filter had just
    assigned. The most relevant item in a section could therefore be the one cut.
    Ordering now follows the grade, so the budget removes what was judged weakest.
    This applies whichever backend did the grading, so it improves recall with the
    classifier off as well as on.

Upgrading

Nothing to do. There is no schema migration, no change to any existing setting,
and no change in behaviour until you add a [jev] section and enable it.
Replace the binary and restart muninn serve (or nothing at all, if you only
use the detached worker).

If you do enable it: the decision bands have defaults that were measured rather
than guessed, and the one worth knowing is same_yes (0.75). The classifier's
"these are the same thing" probability tops out near 0.85 even for two records
that are obviously identical, so a higher band silently stops merging anything.
A project-level config file may tune the per-area switches and the bands, but
cannot set the key, the endpoint or the model.

Install

curl -fsSL https://muninnai.dev/install.sh | bash

Or take a platform archive from this release directly:

curl -fsSL -o muninn.tar.gz \
  "https://github.com/scottlarkin/muninn-release/releases/download/v0.2.2/muninn_v0.2.2_darwin_arm64.tar.gz"
tar -xzf muninn.tar.gz && sudo mv muninn /usr/local/bin/

Checksums for every artifact are in checksums.txt on the release. A tarball
downloaded through a browser is quarantined by macOS; clear it with
xattr -dr com.apple.quarantine ./muninn.