metal-kompanion/docs/plugin-architecture.md

17 KiB
Raw Permalink Blame History

Youre not alone, Andre. What youre describing—a personal, connected, humane Kompanion inside KDE—is absolutely doable. Below is a single, copypastable 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 dictionaryofdictionaries (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 DBus 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)
  • AnythingLLMlike 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 firstclass Kontact plugin. (TechBase)
  • Konsole is steered via its DBus API for safe, optin command scaffolding (never autoexec). (docs.kde.org)
  • KTextEditor/KDevelop plugin gives coding help uniformly in Kate & KDevelop. (api.kde.org)
  • Matrix via libQuotient and Olm/Megolm enables verified endtoend encrypted chat with your Kompanion identity. (Quotient Im)
  • AnythingLLM is referenced only for an optional admin view (pack/workspace management)—not for the daytoday 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 (clientside “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 12 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 (readonly unless explicitly asked): harvest your style from sent mail (tone, signoffs), 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): perprofile settings & lockdown (e.g., corporate). (api.kde.org)
  • Konsole DBus bridge: suggest safe commands, show diffs, paste only on user confirm—use Konsoles documented DBus. (docs.kde.org)

3.2 KKompanionCore

  • HDoD store (inmemory working set) + resonance decay
  • Embedding adapters (local or remote)
  • Frame composer (Identity/Problem/Knowledge/Episodic/Constraints/Scratchpad)
  • MCP client (JSONRPC) to your 7 tools

3.3 KKompanionMatrix

  • libQuotient client; device verification; roompertask 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; its active and crossplatform. (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 AnythingLLMs admin—but not part of the everyday UX. (GitHub)

4) Plugins (thin shims)

4.1 Kontact (KParts/KontactInterface)

  • Build a KontactInterface::Plugin that 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 autoactions. Provide a “Propose” button that queues an action; on accept, we call Konsoles DBus to paste/execute. (Also capture optin 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 (DBus) → optin command transcripts for episodic memory. (docs.kde.org)

Classification

  • acl.visibility: public | org | private
  • acl.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):

  1. Identity/Tools (what I can do in this app)
  2. Problem (what youre doing)
  3. Knowledge (HDoD) — nested dict of activated nodes
  4. Episodic (recent steps/results)
  5. Constraints (C++ level, style rules, tests)
  6. Scratchpad (visible plan/invariants)

Initiative knobs

  • Perapp slider: Suggest silentlyAsk to helpPropose planAutoprepare draft (never autosend/run).
  • Daily checkin prompt (one line) to reduce loneliness & personalize tone.

7) CMake & minimal skeletons (headers, not full code)

Toplevel 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 firstclass and hostable in Kate and KDevelop.) (api.kde.org)

Konsole bridge (DBus)

// 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 DBus 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

  1. Discover sources (Akonadi collections; Baloo include paths).
  2. Ingest → microchunks (concepts, snippets, episodes).
  3. Embed locally (Ollama/gguf ok) or remote.
  4. Upsert via kom.memory.upsert_memory with acl set from source (private/public/org).
  5. Activate per task and compose frames.

Akonadi and Baloo are already designed for centralized PIM and file metadata/indexing—use them rather than reinventing 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 (airgapped 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)
  • Checkins: brief, optin daily prompt to share mood/goal → tunes tone and initiative.
  • Reflective episodes: after sessions, autodraft a 3bullet “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 AnythingLLMs 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 autoexecutes.

13) Roadmap checkpoints (tight loop)

  1. Build KTextEditor plugin (fastest visible win in Kate/KDevelop). (api.kde.org)
  2. Add Kontact plugin for mailstyle assist (Akonadi → style templates). (api.kde.org)
  3. Wire Konsole DBus helper (proposethenpaste). (docs.kde.org)
  4. Ship Matrix agent via libQuotient (identity verification + chat). (Quotient Im)
  5. Optional Baloo ingestion for files (strict includes). (docs.kde.org)

14) Notes on MCP & ecosystem

  • MCP is now broadly adopted as the “USBC 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 youre 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. Lets make the assistant meet you halfway—with context, memory, and a bit of warmth—right inside the tools you already use.