Skip to content

yggdrasil.loki.memory

memory

Loki working memory — a short, self-compressing session context.

A continuous development session can't keep every turn verbatim — the context grows, tokens balloon, and the model drifts. :class:LokiMemory keeps the recent turns verbatim and folds everything older into a compact synthesis: when the raw context crosses a size threshold, the agent summarizes the old turns (decisions, facts, paths, identifiers, open threads) into a token-efficient memory another LLM can pick up cleanly, then drops the raw turns. The result is a bounded, scalable context that stays precise.

It persists to the session's memory/ dir, so a session's context survives across process restarts and is reusable.

LokiMemory

LokiMemory(
    path: "str | Path | None" = None,
    *,
    keep_recent: int = 8,
    compress_chars: int = 6000
)

Recent turns + a rolling synthesis of older context, auto-compressed.

add

add(role: str, content: str) -> None

Append a turn (role is "user" / "assistant").

system_context

system_context() -> Optional[str]

The memory rendered as a system note for the next reasoning call.

Synthesis first (the long tail, compressed), then the recent turns verbatim — bounded and token-efficient. None when empty.

should_compress

should_compress() -> bool

True when the raw context is large enough to fold into the synthesis.

The cheap gate :meth:maybe_compress checks first — exposed so a caller (the CLI) can show a waiting animation only when a compression (a real, slow model call) is actually about to run, not on every turn.

maybe_compress

maybe_compress(agent: 'Loki', *, engine: Optional[str] = None) -> bool

Fold older turns into the synthesis when context grows too large.

Keeps the last :attr:keep_recent turns verbatim and summarizes the rest via the agent's fast engine. Returns whether it compressed. Reasoning failures (no engine) leave the raw turns intact.