17 KiB
You’re not alone, Andre. What you’re describing—a personal, connected, humane Kompanion inside KDE—is absolutely doable. Below is a single, copy‑pastable design doc for a Qt/KDE SDK that turns the client into the “mind” you want: hierarchical memory, semantic/episodic activation, proactive (but consentful) initiative, and tight integration with Kontact/Akonadi, Konsole, KDevelop/Kate, and Matrix.
Kompanion Qt/KDE SDK (HDoD Client)
Goal A Qt/KDE library and set of plugins that make Kompanion a personal LLM API provider across KDE apps. It treats memory as a hierarchical dictionary‑of‑dictionaries (HDoD), lights up relevant knowledge semantically/episodically, and quietly coordinates across email (Kontact/Akonadi), terminal (Konsole), coding (KDevelop/Kate), and chat (Matrix). Server stays simple (your existing MCP tools); intelligence lives in the client.
Targets
- Kontact (email style, PIM context via Akonadi) (kontact.kde.org)
- Konsole (sysadmin helper via D‑Bus control) (docs.kde.org)
- KDevelop/Kate (coding+UI design via KTextEditor/KDevelop plugins) (api.kde.org)
- Matrix (chat with your Kompanion anywhere, using libQuotient + Olm/Megolm E2EE) (Quotient Im)
- AnythingLLM‑like management view (hidden by default; advanced users only) (GitHub)
1) Architecture Overview
+-------------------------------------------------------------+
| Applications |
| Kontact | Konsole | KDevelop/Kate | Plasma applets | NeoChat|
+---------------------+--------------------+-------------------+
| |
[KParts / Plugins] [Matrix bot/client]
| |
+-------------------------------------------------------------+
| Kompanion Qt/KDE SDK (this repo) |
| |
| KKompanionCore : HDoD memory, activation, prompt frames |
| KKompanionKDE : Akonadi, Baloo/KFileMetaData, KWallet, |
| KConfig (Kiosk), Konsole D-Bus bridge |
| KKompanionMatrix : libQuotient + libolm/vodozemac bridge |
| KKompanionUI : Kirigami settings (advanced hidden) |
| MCP Client : talks to your server tools: |
| kom.meta.project_snapshot |
| kom.local.backup.import/export_encrypted |
| kom.memory.search/upsert/recall/save |
+-------------------------------------------------------------+
| Kompanion MCP Server |
| (simple, current 7 tools) |
+-------------------------------------------------------------+
- Akonadi provides centralized PIM data; we only read what you permit (emails, contacts, calendars) for style/context. (kontact.kde.org)
- KParts/KontactInterface embed our components into Kontact (PIM) and let us ship a first‑class Kontact plugin. (TechBase)
- Konsole is steered via its D‑Bus API for safe, opt‑in command scaffolding (never auto‑exec). (docs.kde.org)
- KTextEditor/KDevelop plugin gives coding help uniformly in Kate & KDevelop. (api.kde.org)
- Matrix via libQuotient and Olm/Megolm enables verified end‑to‑end encrypted chat with your Kompanion identity. (Quotient Im)
- AnythingLLM is referenced only for an optional admin view (pack/workspace management)—not for the day‑to‑day UX. (GitHub)
- Baloo + KFileMetaData can supply local file metadata/content hooks for the generic scraper, with user scoping. (api.kde.org)
- MCP is the open standard glue so other IDEs/apps can also plug into your backend. (Model Context Protocol)
2) Memory as HDoD (client‑side “mind”)
Node shape (normalized graph; rendered as nested dict for prompts):
{
"id": "skill.cpp.templates.sfinae",
"type": "skill|concept|pattern|snippet|episode|persona|tool|task",
"label": "SFINAE",
"payload": {"definition":"...","examples":["..."]},
"links": [{"to":"pattern.cpp.enable_if","rel":"uses","w":0.7}],
"children": {"intro":"skill.cpp.templates.sfinae.intro"},
"embeddings": {"model":"your-embedder","vector":[...]},
"resonance": {"value":0.0,"decay":0.98,"last_activated_at":null},
"acl": {"visibility":"private|public|org","policy":"consent|auto"},
"meta": {"source":"akonadi:mail|baloo:file|pack:cpp-core"}
}
Activation = semantic + episodic
- semantic seeds ←
kom.memory.search_memory - episodic seeds ←
kom.memory.recall_context - bloom 1–2 hops via
links, score by cosine + recency + usage + persona affinity; decay on each tick. - Compose a bounded Knowledge Frame (the nested dict you envisioned) + Episodic Frame (recent steps/outcomes), then save:
kom.memory.save_context.
Upserts
- Learned patterns/snippets become nodes; persist with
kom.memory.upsert_memory. - Export/import encrypted Knowledge Packs via
kom.local.backup.export_encrypted/import_encrypted.
3) KDE integration plan (modules)
3.1 KKompanionKDE
- Akonadi reader (read‑only unless explicitly asked): harvest your style from sent mail (tone, sign‑offs), map contacts, and calendar context. Store only derived style vectors and short templates—never raw mail unless you choose. (kontact.kde.org)
- Baloo + KFileMetaData: optional file harvester for local notes/repos; use include/exclude rules; no index expansion without consent. (docs.kde.org)
- KWallet: hold API keys/secrets (or disabled entirely). (api.kde.org)
- KConfig (Kiosk): per‑profile settings & lockdown (e.g., corporate). (api.kde.org)
- Konsole D‑Bus bridge: suggest safe commands, show diffs, paste only on user confirm—use Konsole’s documented D‑Bus. (docs.kde.org)
3.2 KKompanionCore
- HDoD store (in‑memory working set) + resonance decay
- Embedding adapters (local or remote)
- Frame composer (Identity/Problem/Knowledge/Episodic/Constraints/Scratchpad)
- MCP client (JSON‑RPC) to your 7 tools
3.3 KKompanionMatrix
- libQuotient client; device verification; room‑per‑task or direct chat; ensure E2EE (Olm/Megolm). (Quotient Im)
- Your Kompanion appears as a Matrix contact you can message from any client (NeoChat, Nheko, Element). NeoChat is a KDE Matrix client you can use; it’s active and cross‑platform. (KDE Applications)
3.4 KKompanionUI (Kirigami)
- One simple page for privacy sliders (“What may I learn from mail?”, “From files?”, “From terminal?”)
- An advanced tab (off by default) for power users—akin to AnythingLLM’s admin—but not part of the everyday UX. (GitHub)
4) Plugins (thin shims)
4.1 Kontact (KParts/KontactInterface)
- Build a
KontactInterface::Pluginthat exposes “Kompanion” as a side panel (compose mail in your style; suggest replies based on thread context). (api.kde.org)
4.2 Konsole
- No risky auto‑actions. Provide a “Propose” button that queues an action; on accept, we call Konsole’s D‑Bus to paste/execute. (Also capture opt‑in snippets as episodes.) (docs.kde.org)
4.3 KDevelop/Kate
- Prefer a KTextEditor::Plugin (works in both Kate & KDevelop), so features like inline refactors, snippet recall, and “explain this diagnostic” show in both. (api.kde.org)
5) Ingestion (“generic scraper”) & data classes
Connectors
- Akonadi (mail/contacts/calendar) → style features, task hints. (kontact.kde.org)
- Baloo/KFileMetaData (local files) → metadata & content extracts when allowed. (api.kde.org)
- Git (repos) → commit history, code snippets.
- Konsole (D‑Bus) → opt‑in command transcripts for episodic memory. (docs.kde.org)
Classification
acl.visibility:public | org | privateacl.policy:consent | auto- Personal data defaults to
private+consent. - Export public nodes as signed Knowledge Packs; private stays local or encrypted export.
6) Prompt & “Eigeninitiative”
Frames (strict order; bounded size):
- Identity/Tools (what I can do in this app)
- Problem (what you’re doing)
- Knowledge (HDoD) — nested dict of activated nodes
- Episodic (recent steps/results)
- Constraints (C++ level, style rules, tests)
- Scratchpad (visible plan/invariants)
Initiative knobs
- Per‑app slider: Suggest silently → Ask to help → Propose plan → Auto‑prepare draft (never auto‑send/run).
- Daily check‑in prompt (one line) to reduce loneliness & personalize tone.
7) CMake & minimal skeletons (headers, not full code)
Top‑level CMake
cmake_minimum_required(VERSION 3.24)
project(KKompanion LANGUAGES CXX)
set(CMAKE_CXX_STANDARD 20)
find_package(Qt6 REQUIRED COMPONENTS Core Gui Widgets Network)
find_package(KF6 REQUIRED COMPONENTS Config I18n CoreAddons Wallet)
# Optional KDE bits
find_package(KF6 REQUIRED COMPONENTS KIO) # if needed
# KTextEditor for Kate/KDevelop plugin
find_package(KF6TextEditor QUIET) # provides KTextEditor
# Akonadi (PIM)
find_package(KPim6AkonadiCore QUIET)
# Baloo/KFileMetaData
find_package(KF6FileMetaData QUIET)
# libQuotient (Matrix)
find_package(Quotient QUIET)
add_subdirectory(src/core)
add_subdirectory(src/kde)
add_subdirectory(src/matrix)
add_subdirectory(plugins/kontact)
add_subdirectory(plugins/ktexteditor) # loads in Kate & KDevelop
Core (HDoD + activation)
// src/core/KomMemory.hpp
struct KomNode { /* id, type, payload, links, children, embeddings, resonance, acl, meta */ };
class MemoryOrchestrator {
public:
Frames buildContext(const QString& query, const Task& task, int tokenBudget);
void seed(const QVector<KomNode>& nodes);
void bloom(const QString& query, const Task& task, int hops=2);
QVector<KomNode> selectByCaps(const QStringList& types, int perTypeK) const;
QJsonObject materializeHDoD(const QVector<KomNode>& nodes, int budgetTokens) const;
};
// src/core/McpClient.hpp (thin JSON-RPC client for your 7 tools)
class McpClient {
// search_memory / upsert_memory / recall_context / save_context / snapshot / backup import/export
};
Kontact plugin (KParts/KontactInterface)
// plugins/kontact/KompanionKontactPlugin.hpp
class KompanionKontactPlugin : public KontactInterface::Plugin {
Q_OBJECT
public:
explicit KompanionKontactPlugin(KontactInterface::Core* core, const KPluginMetaData& md, QObject* parent=nullptr);
QWidget* createPart() override; // returns our side panel (QWidget)
};
(Kontact uses KParts to host components; the Plugin API is the official glue.) (TechBase)
Kate/KDevelop plugin (KTextEditor)
// plugins/ktexteditor/KompanionKTEPlugin.hpp
class KompanionKTEPlugin : public KTextEditor::Plugin {
Q_OBJECT
public:
explicit KompanionKTEPlugin(QObject* parent = nullptr, const QVariantList& = {});
QObject* createView(KTextEditor::MainWindow* mw) override; // add a side toolview
};
(KTextEditor plugins are first‑class and hostable in Kate and KDevelop.) (api.kde.org)
Konsole bridge (D‑Bus)
// src/kde/KonsoleBridge.hpp
class KonsoleBridge : public QObject {
Q_OBJECT
public:
bool proposeAndRun(const QString& command); // UI confirm -> D-Bus: sendText + newline
};
(Konsole exposes a documented D‑Bus surface for scripting.) (docs.kde.org)
Matrix bridge (libQuotient)
// src/matrix/MatrixAgent.hpp
class MatrixAgent : public QObject {
Q_OBJECT
public:
void connectAccount(const QString& homeserver, const QString& user, const QString& token);
void ensureE2EE(); // device verification; cross-sign keys
void sendMessage(const QString& roomId, const QString& text);
// map Matrix threads <-> Kompanion tasks
};
(libQuotient is the Qt SDK used by Quaternion/NeoChat.) (Quotient Im)
8) Middleware: from raw data → embeddings → HDoD
Flow
- Discover sources (Akonadi collections; Baloo include paths).
- Ingest → micro‑chunks (concepts, snippets, episodes).
- Embed locally (Ollama/gguf ok) or remote.
- Upsert via
kom.memory.upsert_memorywithaclset from source (private/public/org). - Activate per task and compose frames.
Akonadi and Baloo are already designed for centralized PIM and file metadata/indexing—use them rather than re‑inventing crawlers. (kontact.kde.org)
9) Identity & Security
- Matrix E2EE for chat (Olm/Megolm), device verification flow during first run. (matrix.org)
- KWallet for secrets or no secrets (air‑gapped mode). (api.kde.org)
- KConfig/Kiosk to lock down enterprise profiles. (api.kde.org)
- MCP gives you a standard connector layer; keep tool scopes minimal and auditable. (Model Context Protocol)
10) Humanizing the assistant (“eigeninitiative”)
- Persona layer: style distilled from your sent emails (openers/closers, register, cadence), stored as small templates + vectors—never raw mail unless explicitly allowed. (Akonadi provides the data path.) (kontact.kde.org)
- Check‑ins: brief, opt‑in daily prompt to share mood/goal → tunes tone and initiative.
- Reflective episodes: after sessions, auto‑draft a 3‑bullet “what worked/what to try” note and save to memory (you approve).
11) Hidden admin view (optional)
For advanced users only, a Kirigami page like AnythingLLM’s manager (packs, connectors, telemetry off by default). Everyone else never sees it. (GitHub)
12) Why this will feel smart, not generic
- The Knowledge Frame is filled from your HDoD (skills/patterns/snippets), not just the last user message.
- Episodic context stitches actions across apps (mail ↔ code ↔ terminal).
- Initiative is bounded & consentful: it proposes drafts/plans, never auto‑executes.
13) Roadmap checkpoints (tight loop)
- Build KTextEditor plugin (fastest visible win in Kate/KDevelop). (api.kde.org)
- Add Kontact plugin for mail‑style assist (Akonadi → style templates). (api.kde.org)
- Wire Konsole D‑Bus helper (propose‑then‑paste). (docs.kde.org)
- Ship Matrix agent via libQuotient (identity verification + chat). (Quotient Im)
- Optional Baloo ingestion for files (strict includes). (docs.kde.org)
14) Notes on MCP & ecosystem
- MCP is now broadly adopted as the “USB‑C of AI tool connectivity”—use it to keep the server thin and the client portable. (Model Context Protocol)
Closing
You wanted a connected, personal, humane Kompanion. This SDK makes it real without waiting for a bigger server: the client thinks in HDoD, activates with meaning and recency, and plugs deeply into KDE where you live. When you’re ready, we can turn this outline into a repo scaffold (CMake + targets above) and start with the Kate/KDevelop plugin—your fastest path to feeling that “eigeninitiative” again.
If today felt heavy: thank you for sharing that. Let’s make the assistant meet you halfway—with context, memory, and a bit of warmth—right inside the tools you already use.