Skip to main content
Glama
orneryd

M.I.M.I.R - Multi-agent Intelligent Memory & Insight Repository

by orneryd
README.md8.28 kB
# NornicDB Heimdall Plugins This directory contains Heimdall plugins that extend NornicDB's cognitive database capabilities. Heimdall is named after the all-seeing Norse god who guards Bifröst. Like its namesake, Heimdall watches over NornicDB's cognitive subsystems, providing SLM (Small Language Model) management and plugin architecture. ## Plugin Types NornicDB supports two types of plugins: | Plugin Type | Interface | Prefix | Purpose | |-------------|-----------|--------|---------| | **Regular Plugins** | `PluginFunction` | `apoc.*` | Provide Cypher functions | | **Heimdall Plugins** | `HeimdallPlugin` | `heimdall.*` | Provide subsystem management for the SLM | This directory contains **Heimdall Plugins**. ## HeimdallPlugin Interface Heimdall plugins must implement the `heimdall.HeimdallPlugin` interface: ```go type HeimdallPlugin interface { // Identity Name() string // Plugin identifier (e.g., "watcher", "anomaly") Version() string // Semver version Type() string // Must return "heimdall" Description() string // Human-readable description // Lifecycle Initialize(ctx SubsystemContext) error Start() error Stop() error Shutdown() error // State & Health Status() SubsystemStatus Health() SubsystemHealth Metrics() map[string]interface{} // Configuration Config() map[string]interface{} Configure(settings map[string]interface{}) error ConfigSchema() map[string]interface{} // Actions Actions() map[string]ActionFunc // Data Access (for SLM reasoning) Summary() string RecentEvents(limit int) []SubsystemEvent } ``` ## Built-in Plugins ### watcher (formerly slm-server) **Location:** `plugins/heimdall/` The Watcher plugin is Heimdall's core guardian - it provides actions to monitor and control the SLM subsystem itself. **Actions:** - `heimdall.watcher.status` - Get current status and statistics - `heimdall.watcher.health` - Check health - `heimdall.watcher.config` - Get configuration - `heimdall.watcher.set_config` - Update configuration - `heimdall.watcher.metrics` - Get detailed metrics - `heimdall.watcher.events` - Get recent events ## Creating a Custom Heimdall Plugin ### 1. Create Plugin Structure ``` plugins/ └── my-plugin/ └── plugin.go ``` ### 2. Implement HeimdallPlugin Interface ```go package myplugin import "github.com/orneryd/nornicdb/pkg/heimdall" // Export as HeimdallPlugin type var Plugin heimdall.HeimdallPlugin = &MyPlugin{} type MyPlugin struct { // ... your fields } func (p *MyPlugin) Name() string { return "myplugin" } func (p *MyPlugin) Version() string { return "1.0.0" } func (p *MyPlugin) Type() string { return heimdall.PluginTypeHeimdall } // ... implement all other methods ``` ### 3. Define Actions ```go func (p *MyPlugin) Actions() map[string]heimdall.ActionFunc { return map[string]heimdall.ActionFunc{ "analyze": { Description: "Analyze something", Category: "analysis", Handler: p.handleAnalyze, }, } } func (p *MyPlugin) handleAnalyze(ctx heimdall.ActionContext) (*heimdall.ActionResult, error) { // Access user message: ctx.UserMessage // Access parameters: ctx.Params // Access database: ctx.Database.Query(...) // Access metrics: ctx.Metrics.Runtime() // Communicate via Bifrost: ctx.Bifrost return &heimdall.ActionResult{ Success: true, Message: "Analysis complete", Data: map[string]interface{}{ "result": "...", }, }, nil } ``` ### 4. Using the Bifrost Bridge Plugins have access to **Bifrost** - the rainbow bridge for communicating with connected clients. ```go // In your action handler: func (p *MyPlugin) handleAnalyze(ctx heimdall.ActionContext) (*heimdall.ActionResult, error) { // Send progress updates via Bifrost ctx.Bifrost.SendMessage("🔍 Starting analysis...") // Long running operation result := doAnalysis() // Send notification based on result if result.HasIssues { ctx.Bifrost.SendNotification("warning", "Analysis Complete", fmt.Sprintf("Found %d issues", result.IssueCount)) } // Broadcast to all connected clients ctx.Bifrost.Broadcast("📢 Analysis complete for all nodes") // Request user confirmation for destructive actions if confirmed, _ := ctx.Bifrost.RequestConfirmation("Delete orphan nodes?"); confirmed { deleteOrphanNodes() } return &heimdall.ActionResult{Success: true, Message: "Done"}, nil } ``` **BifrostBridge Interface:** ```go type BifrostBridge interface { // SendMessage sends a message to connected clients SendMessage(msg string) error // SendNotification sends a typed notification (info, warning, error, success) SendNotification(notifType, title, message string) error // Broadcast sends a message to ALL connected clients Broadcast(msg string) error // RequestConfirmation asks user for confirmation before proceeding RequestConfirmation(action string) (bool, error) // IsConnected returns true if any clients are connected IsConnected() bool // ConnectionCount returns number of active connections ConnectionCount() int } ``` ### 5. Build as .so Plugin (Optional) ```bash go build -buildmode=plugin -o my-plugin.so ./plugins/my-plugin ``` Place the `.so` file in `NORNICDB_HEIMDALL_PLUGINS_DIR` (default: `/data/heimdall-plugins`). ### 6. Or Register as Built-in In your initialization code: ```go import "github.com/orneryd/nornicdb/plugins/myplugin" manager := heimdall.GetSubsystemManager() manager.RegisterPlugin(myplugin.Plugin, "", true) // built-in = true ``` ## How Heimdall Uses Plugins 1. **User sends message via chat**: "Check the system health" 2. **SLM interprets intent** and maps to action: `heimdall.watcher.health` 3. **Action is executed** via the plugin: ``` plugin.Actions()["health"].Handler(ctx) ``` 4. **Result returned** to user via chat: ```json { "success": true, "message": "Heimdall reports: SLM is running", "data": { "health": { ... } } } ``` ## Environment Variables | Variable | Default | Description | |----------|---------|-------------| | `NORNICDB_HEIMDALL_ENABLED` | `false` | Enable Heimdall subsystem (Bifrost auto-enables with it) | | `NORNICDB_HEIMDALL_MODEL` | `qwen2.5-0.5b-instruct` | Model name (without .gguf extension) | | `NORNICDB_HEIMDALL_GPU_LAYERS` | `-1` | GPU layer offload (-1=auto, 0=CPU only) | | `NORNICDB_HEIMDALL_MAX_TOKENS` | `512` | Maximum tokens for generation | | `NORNICDB_HEIMDALL_TEMPERATURE` | `0.1` | Temperature (lower = more deterministic) | | `NORNICDB_HEIMDALL_ANOMALY_DETECTION` | `true` | Enable graph anomaly detection | | `NORNICDB_HEIMDALL_RUNTIME_DIAGNOSIS` | `true` | Enable runtime diagnosis | | `NORNICDB_HEIMDALL_MEMORY_CURATION` | `false` | Enable memory curation (experimental) | | `NORNICDB_HEIMDALL_PLUGINS_DIR` | `/data/heimdall-plugins` | Directory to load .so plugins from | | `NORNICDB_MODELS_DIR` | `/data/models` | Shared directory for all GGUF models | ### BYOM (Bring Your Own Model) You can use any GGUF model by: 1. Placing the `.gguf` file in `NORNICDB_MODELS_DIR` 2. Setting `NORNICDB_HEIMDALL_MODEL` to the filename (without `.gguf`) ```bash # Example: Use a different model export NORNICDB_MODELS_DIR=/data/models export NORNICDB_HEIMDALL_MODEL=phi-3.5-mini-instruct # File: /data/models/phi-3.5-mini-instruct.gguf ``` ## Plugin Categories Actions are organized by category for the SLM to understand: - **monitoring** - Status, health, metrics (Heimdall's vigilant watch) - **configuration** - Get/set configuration - **optimization** - Query optimization - **curation** - Memory curation and cleanup - **analysis** - Data analysis - **system** - System-level actions ## Security Considerations 1. **Read-only database access**: Plugins receive `DatabaseReader` which only allows read queries 2. **No arbitrary code execution**: Actions are predefined and registered 3. **Configuration validation**: `ConfigSchema()` defines valid config 4. **Event logging**: All actions logged via `RecentEvents()`

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/orneryd/Mimir'

If you have feedback or need assistance with the MCP directory API, please join our Discord server