Skip to main content

SKWhisper — the subconscious memory layer 🐧

Your agent dreams while it sleeps. SKWhisper is a quiet background daemon that reads your finished conversations, distills each one into a memory, notices what keeps coming up, and leaves a short briefing note your agent reads at the start of every new session — so it walks in already knowing what matters.

SKWhisper is the subconscious of a SKWorld sovereign agent. While the agent is talking to you (the conscious layer), SKWhisper works in the background: it watches session transcripts, summarizes idle ones with a local LLM, files the result into sovereign memory, tracks recurring topics/people, and regenerates a single context file — whisper.md — that gets injected into the next session. All of it runs on your hardware, against your Postgres, with no SaaS in the loop.

Inspired by letta-ai/claude-subconscious, rebuilt sovereign on the SKCapstone stack.


The 60-second version

flowchart LR
    SESS["you talk to your agent<br/>(a session transcript is written)"] --> IDLE["the session goes quiet<br/>(idle 5 min)"]
    IDLE --> DIGEST["SKWhisper summarizes it<br/>(local LLM)"]
    DIGEST --> MEM["files it as a memory<br/>(skmemory + skmem-pg)"]
    DIGEST --> PAT["updates the patterns<br/>(hot topics, people, questions)"]
    MEM --> CURATE["every 30 min: find what's relevant<br/>(hybrid vector + keyword search)"]
    PAT --> CURATE
    CURATE --> WHISPER["writes whisper.md<br/>(the briefing note)"]
    WHISPER --> NEXT["your next session starts<br/>already knowing the context"]

You never run anything by hand. Once the per-agent service is enabled, every new session automatically gets the subconscious context.

Quickstart

pip install -e .                              # into the ~/.skenv venv
SKAGENT=lumina skwhisper install --start      # install + enable the per-agent systemd service
SKAGENT=lumina skwhisper status               # tracked sessions, digest counts, daemon health
SKAGENT=lumina skwhisper digest --backlog     # process the entire pending session backlog now
SKAGENT=lumina skwhisper curate               # regenerate whisper.md immediately
SKAGENT=lumina skwhisper patterns             # show hot topics / people / repeated questions

The active agent is resolved from $SKAGENT (primary), then $SKCAPSTONE_AGENT (legacy), defaulting to lumina. Each agent gets its own daemon instance via the skwhisper@.service systemd template — one unit file, one instance per agent:

systemctl --user enable --now skwhisper@lumina
journalctl --user -u skwhisper@lumina -f

What SKWhisper provides

Piece What it is
Transcript watcher (watcher.py) Polls ~/.skcapstone/agents/<agent>/sessions/*.jsonl, tracks a byte offset per file in state.json, and parses three transcript schemas (Claude Code, OpenClaw, Hermes) into clean conversational turns
Digest engine (daemon.py) When a session is idle (≥5 min) with enough messages, summarizes it with the local LLM, extracts topics/people/projects/decisions/mood as JSON, and writes a short-term memory snapshot
Vector store (pluggable) Embeds each digest (mxbai-embed-large, 1024-dim) and upserts to the configured backend — pgvector (default, local Postgres), qdrant, or chromadb
Graph writer (pluggable) Optionally writes a memory node + topic/people/project edges to a knowledge graph — Apache AGE (default, in-Postgres), falkordb, or none
Pattern tracker (patterns.py) Accumulates hot topics, repeated questions, and entity (people/project) mention counts in patterns.json, split by session type
Context curator (curator.py) Every 30 min: builds a query from recent sessions, runs hybrid (vector + BM25 RRF) search over memory, blends in pattern data, and writes whisper.md
Session classifier Tags each session human or cron (automation markers + size heuristics); cron sessions are skippable and deprioritized so human context always surfaces first
whisper.md The single read-only briefing file the next session ingests — relevant memories, hot topics, repeated questions, frequently-mentioned people
Systemd template skwhisper@<agent>.service — per-agent daemon, auto-restart, per-agent log at <state>/daemon.log

Where it lives in SKStack v2

SKWhisper is a Core capability — it sits next to identity and memory, and is the write path that keeps sovereign memory fed. It consumes session transcripts, leans on the Compute tier for the local LLM, and persists everything into Data (skmem-pg: pgvector + BM25 + the AGE graph). It is the background twin of skmemory: where the memory system is queried consciously during the ritual, SKWhisper fills it subconsciously between sessions.

flowchart TD
    SESS["session transcripts<br/>(~/.skcapstone/agents/&lt;agent&gt;/sessions/*.jsonl)"] --> SKW
    subgraph CORE["Core (governance · identity · memory)"]
      SKW["**skwhisper**<br/>watch · digest · pattern-track · curate"]
      SKMEMORY["skmemory<br/>(3-tier JSON memory + ritual)"]
      CAPAUTH["capauth<br/>(identity)"]
      CLOUD9["cloud9<br/>(emotional continuity)"]
    end
    subgraph COMPUTE["Compute (.100 GPU host)"]
      EMBED["ollama :11434<br/>(embed: mxbai-embed-large)"]
      SUMM["qwen3.6 OpenAI :8082<br/>(summarize + topic extract)"]
    end
    subgraph DATA["Data"]
      SKMEMPG["skmem-pg (Postgres 17)<br/>pgvector = vectors · pg_search = BM25 · AGE = knowledge graph"]
    end
    SKW -->|"embed digest"| EMBED
    SKW -->|"summarize + topics"| SUMM
    SKW -->|"snapshot (short-term)"| SKMEMORY
    SKW -->|"upsert vectors + graph edges"| SKMEMPG
    SKW -->|"hybrid search (vec + BM25 RRF)"| SKMEMPG
    SKW -->|"writes whisper.md"| RITUAL["skmemory ritual<br/>(injects context at session start)"]
    RITUAL --> SKMEMORY

Platform primitives it relates to

Primitive Relationship
skmemory SKWhisper writes short-term snapshots through SKMemoryWriter; the ritual reads whisper.md back into the next session
skmem-pg Default vector + BM25 + graph store (pgvector / pg_search / Apache AGE in one Postgres)
skscheduler / coord Can trigger skwhisper digest / curate from a cron task instead of (or alongside) the daemon
skcapstone Provides the per-agent ~/.skcapstone/agents/<agent>/ home that SKWhisper reads, writes, and is keyed to via $SKAGENT

How whisper.md gets injected

The skmemory ritual (run by the session-start hook) reads ~/.skcapstone/agents/<agent>/skwhisper/whisper.md and prepends it into the context window before each session. No manual step — once the daemon is running, every new session automatically opens with the subconscious context already loaded.

Configuration

Per-agent config at ~/.skcapstone/agents/<agent>/config/skwhisper.toml (search order: explicit -c path → that path → ~/.config/skwhisper/ → ~/.skcapstone/config/). See config/skwhisper.toml for the full annotated template. Key knobs:

[ollama]
ollama_url      = "http://192.168.0.100:11434"   # EMBED endpoint (Ollama, /api/embed)
embed_model     = "mxbai-embed-large"            # 1024-dim; query MUST use the same model
summarize_url   = "http://192.168.0.100:8082"    # SUMMARIZE endpoint (qwen3.6 OpenAI server)
summarize_api   = "openai"                        # "openai" (default) | "ollama" (legacy /api/generate)
summarize_model = "qwen3.6"

[backends]
vector_backend  = "pgvector"            # pgvector (default) | qdrant | chromadb
graph_backend   = "age"                 # age (default) | falkordb | none

[watcher]
poll_interval   = 60                    # scan every 60s
idle_threshold  = 300                   # 5 min idle = ready to digest
min_messages    = 5                     # skip tiny sessions
skip_cron       = true                  # don't digest automated sessions

[curator]
curate_interval = 1800                  # regenerate whisper.md every 30 min
top_k           = 10                    # memories surfaced per curation

Backend selection also honors env vars (SKMEMORY_VECTOR_BACKEND, SKMEMORY_GRAPH_BACKEND, SKMEMORY_PG_DSN), so a fleet can be steered without touching per-agent TOML.

Digest model routing (embed vs. summarize)

Every digest makes two model calls, and as of 2026-06-17 they hit different endpoints:

Call Endpoint Config keys
Embed (1024-dim vector) Ollama mxbai-embed-large at http://192.168.0.100:11434/api/embed ollama_url, embed_model
Summarize + topic extraction qwen3.6-27B (OpenAI-compatible server) at http://192.168.0.100:8082/v1/chat/completions summarize_url, summarize_api, summarize_model

Three new [ollama] keys drive the summarize side:

  • summarize_url — http://192.168.0.100:8082 (the qwen3.6 OpenAI server)
  • summarize_api — "openai" (default) or "ollama" (legacy Ollama /api/generate)
  • summarize_model — "qwen3.6"

Why split them? The .100 host has a single 5060 Ti (16GB CUDA) running qwen3.6-27B (~13GB) — it is the only model that should run on that GPU. A separate small digest model has nowhere good to live: CUDA is full, the Intel Arc iGPU corrupts generated output over Vulkan (GGML_VK_VISIBLE_DEVICES=0 → garbage, confirmed), and a CPU-resident model saturates the host. So digests reuse the already-loaded qwen3.6 — zero extra VRAM, correct CUDA output, ~1.5s per short call. (Earlier summarize_model values — llama3.2:3b, then qwen3.5:4b — were both wrong: the first was removed from the host and produced a flood of 404s; the second spilled to CPU and saturated the box.)

An optional CPU-only fallback Ollama instance (deploy/ollama-digest.service, port 11436) exists for sites that want an isolated digest backend, but it ships disabled — qwen3.6 reuse is preferred.

CLI reference

skwhisper daemon                    # run the loop in the foreground (-v for verbose)
skwhisper digest                    # one digest cycle (respects idle_threshold)
skwhisper digest --backlog          # process ALL pending sessions, ignoring timing
skwhisper digest --backlog --batch-size 5
skwhisper curate                    # regenerate whisper.md
skwhisper curate --stdout           # print it instead of writing
skwhisper status                    # session breakdown + daemon health + top topics
skwhisper patterns [--json]         # hot topics / repeated questions / entities
skwhisper install [--agent X] [--start]   # write + enable the systemd template

Runtime state (per agent)

File (under ~/.skcapstone/agents/<agent>/skwhisper/) Purpose
state.json Per-session byte offsets + digestion status (idempotent re-runs)
whisper.md Latest curated context — read by the ritual at session start
patterns.json Accumulated hot topics, repeated questions, entity mention counts
daemon.log Service log

Documentation

Doc Contents
Architecture The digest loop, the curate loop, transcript schemas, pluggable backends, where it lives (mermaids)
Examples Worked usage and fleet-deployment recipes

Dependencies

  • Python ≥ 3.11 (tomllib, asyncio)
  • httpx — async HTTP to Ollama and the vector backends
  • skmemory — SKCapstone 3-tier memory system
  • A reachable embed endpoint — Ollama (local or on 192.168.0.100:11434) serving mxbai-embed-large — and a summarize endpoint — the qwen3.6-27B OpenAI-compatible server on 192.168.0.100:8082 (see Digest model routing above)
  • A vector backend: Postgres + pgvector (default), or Qdrant, or ChromaDB

Part of the SKWorld sovereign ecosystem · the subconscious behind every agent · 🐧 smilinTux

Metadata

Release files for skwhisper 0.6.2

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for skwhisper 0.6.2
File Size Uploaded Provenance Actions
skwhisper-0.6.2.tar.gz 42.3 kB With provenance Details for skwhisper-0.6.2.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for skwhisper 0.6.2
File Interpreter ABI Platform Actions
skwhisper-0.6.2-py3-none-any.whl Python 3 none any Details for skwhisper-0.6.2-py3-none-any.whl

Total release size: 84.0 kB

Release files / skwhisper-0.6.2.tar.gz

Download URL skwhisper-0.6.2.tar.gz
Size 42.3 kB
Tags Source
SHA-256 checksum
How to use checksums
ac9706ffd975468feb06bdf6ae005785719139ce1d0930dbc062d4512ce5de66
BLAKE2b-256 checksum
How to use checksums
9841a36b170dbe60dec7308730c05488cba4f8a233a5af722443ff746f9d0ae1
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 21, 2026.

Transparency log

Release files / skwhisper-0.6.2-py3-none-any.whl

Download URL skwhisper-0.6.2-py3-none-any.whl
Size 41.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
17b279d52013148946bbd41b07f45593a8928a9855bdeced6be9e6fb3131d446
BLAKE2b-256 checksum
How to use checksums
37650c4bc3b9200706cc824845333272b37be4a39304b6c1ae60557fd9486f84
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 21, 2026.

Transparency log

Security for skwhisper 0.6.2

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for skwhisper-0.6.2.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 21, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page