Implementation Summary: Features #3, #5, and #6

Note: Dashboard code now lives under routes/dashboard/; routes/dashboard-server.ts is a barrel re-export. For current layout see ARCHITECTURE-CENTER.md.

This document summarizes the implementation of three strategic enhancements for OpenClaw Hybrid Memory.

✅ #3: Visual Memory Graph Explorer

What Was Implemented

  1. Route Integration (routes/dashboard/server.ts; barrel routes/dashboard-server.ts)
    • Added /graph route serving the interactive visualization
    • Added /graphql POST endpoint for GraphQL API
    • Integrated with existing dashboard server
  2. GraphQL Data Layer (routes/graphql-*.ts)
    • Complete GraphQL schema with facts, episodes, links
    • Full resolvers for queries, mutations, subscriptions
    • Real-time updates via GraphQL subscriptions
  3. Interactive Visualization (routes/graph-explorer.ts)
    • D3.js-based force-directed graph
    • Node/edge rendering with category colors
    • Interactive filters (category, decay class, importance, search)
    • Zoom, pan, drag interactions
    • Tooltip with fact details
    • Real-time data fetching from GraphQL

How to Use

  1. Access the Graph Explorer:
    http://localhost:7777/graph
    
  2. Features Available:
    • View all facts as nodes in a graph
    • Filter by category (preference, decision, entity, fact, other)
    • Filter by decay class (permanent, stable, episodic, volatile)
    • Adjust minimum importance/confidence sliders
    • Search facts by text
    • Click nodes to select and see details
    • Drag nodes to rearrange
    • Zoom and pan the graph
  3. GraphQL API:
    POST http://localhost:7777/graphql
    

    Example query:

    query GetGraph {
      graph {
        nodes {
          id
          label
          category
          importance
          confidence
        }
        edges {
          source
          target
          linkType
        }
      }
    }
    

Integration Points

  • Dashboard: Add link to graph explorer in Mission Control
  • Auto-refresh: Graph data updates on each load
  • Performance: Efficient for up to 1000+ nodes

✅ #5: Multi-User Collaboration

What Was Implemented

  1. Data Models (services/collaboration.ts)
    • Organization - Team/company entity
    • MemorySpace - Shared memory contexts (projects, customers)
    • Member - Users belonging to organizations
    • SpacePermission - Fine-grained access control
    • FactSuggestion - Proposed changes awaiting review
    • FactComment - Discussions on facts
    • Activity - Audit trail of all actions
  2. CollaborationService (600+ lines)
    • Complete SQLite schema with indexes
    • CRUD operations for all entities
    • Permission checking system
    • Activity logging
    • Suggestion workflow
    • Comment management
  3. Permission System
    • Roles: owner, admin, editor, viewer
    • Permissions: read, write, delete, manage
    • Inheritance: Org-level roles can override space permissions
    • Validation: Every operation checks permissions

Database Schema

-- 7 tables created:
- organizations
- memory_spaces
- members
- space_permissions
- fact_suggestions
- fact_comments
- activities

-- 10 indexes for performance

How to Use

import { CollaborationService } from './services/collaboration.js';

const collab = new CollaborationService('/path/to/collab.db');

// Create organization
collab.createOrganization({
  id: 'org-123',
  name: 'Acme Corp',
  createdAt: Date.now(),
  plan: 'team'
});

// Add member
collab.addMember({
  userId: 'user-456',
  orgId: 'org-123',
  role: 'editor',
  joinedAt: Date.now()
});

// Create shared space
collab.createSpace({
  id: 'space-789',
  orgId: 'org-123',
  name: 'Customer Support KB',
  visibility: 'org',
  createdBy: 'user-456',
  createdAt: Date.now()
});

// Check permissions
if (collab.hasPermission('user-456', 'space-789', 'write')) {
  // User can write to this space
}

// Create suggestion
collab.createSuggestion({
  id: 'sugg-101',
  spaceId: 'space-789',
  suggestedBy: 'user-456',
  suggestionType: 'edit',
  factId: 'fact-202',
  newText: 'Updated fact text',
  reason: 'Correcting outdated information',
  status: 'pending',
  createdAt: Date.now()
});

// Get pending suggestions
const pending = collab.getPendingSuggestions('space-789');

// Add comment
collab.addComment({
  id: 'comment-303',
  factId: 'fact-202',
  authorId: 'user-456',
  text: 'This needs verification',
  createdAt: Date.now(),
  resolved: false
});

// View activity
const activities = collab.getRecentActivities('org-123', 50);

Next Steps for Full Integration

  1. API Endpoints: Create REST/GraphQL endpoints for collaboration
  2. UI Components: Build team management interface
  3. Notifications: Alert users of pending suggestions
  4. Webhooks: Notify external systems of activities

✅ #6: Plugin/Extension API

What Was Implemented

  1. Plugin System Core (api/plugin-system.ts)
    • MemoryPlugin interface
    • PluginManager class
    • PluginHooks for lifecycle events
    • PluginCapabilities declaration
    • Event system for plugin communication
  2. Plugin Loader (services/plugin-loader.ts)
    • Discovers plugins in plugins directory
    • Loads plugins dynamically
    • Manages plugin lifecycle
    • Integration hooks for memory operations
  3. CLI Commands (cli/plugin-commands.ts)
    • listPlugins() - Show installed plugins
    • installPlugin() - Install from npm or local
    • removePlugin() - Uninstall plugin
    • enablePlugin() / disablePlugin() - Toggle plugins
  4. Documentation (docs/PLUGIN-DEVELOPMENT.md)
    • Complete developer guide
    • Example plugin templates
    • Security best practices
    • Publishing guidelines

Plugin Hooks Available

interface PluginHooks {
  beforeFactStore?: (fact) => Promise<fact>;    // Modify before storage
  afterFactStore?: (fact) => Promise<void>;     // React to storage
  beforeFactDelete?: (factId) => Promise<bool>; // Veto deletion
  afterFactDelete?: (factId) => Promise<void>;  // Cleanup
  beforeSearch?: (query) => Promise<query>;     // Modify query
  afterSearch?: (results) => Promise<results>;  // Filter results
  onMaintenance?: () => Promise<void>;          // Run during maintenance
  onShutdown?: () => Promise<void>;             // Cleanup on exit
}

Example Plugin

// plugins/my-plugin/index.ts
import type { MemoryPlugin } from '@openclaw/hybrid-memory';

export default {
  metadata: {
    id: 'my-plugin',
    name: 'My Plugin',
    version: '1.0.0',
    description: 'Example plugin',
    author: 'Your Name'
  },

  capabilities: {
    canModifyFacts: false,
    canInterceptSearch: false
  },

  hooks: {
    afterFactStore: async (fact) => {
      console.log('Fact stored:', fact.text);
      // Send notification, log to analytics, etc.
    }
  },

  async init(context) {
    context.logger.info('Plugin initialized');

    // Register custom endpoint
    context.registerEndpoint('/my-api', async (req) => {
      return new Response(JSON.stringify({ status: 'ok' }));
    });

    // Register CLI command
    context.registerCommand('my-command', async (args) => {
      console.log('Running my-command with', args);
      return 0;
    });
  }
} as MemoryPlugin;

Plugin Context API

Plugins receive a context with:

interface PluginExtensionContext {
  factsDb: FactsDB;              // Direct database access
  vectorDb?: VectorDB;           // Vector database (if enabled)
  config: HybridMemoryConfig;    // Plugin configuration
  logger: {                      // Logging functions
    info: (msg, ...args) => void;
    warn: (msg, ...args) => void;
    error: (msg, ...args) => void;
    debug: (msg, ...args) => void;
  };
  emit: (event, data) => Promise<void>;              // Emit events
  registerEndpoint: (path, handler) => void;         // Add HTTP endpoint
  registerCommand: (name, handler) => void;          // Add CLI command
}

Plugin Discovery

import { PluginLoader } from './services/plugin-loader.js';

const loader = new PluginLoader(
  factsDb,
  vectorDb,
  pluginContext,
  '/path/to/plugins'
);

// Discover and load all plugins
await loader.discoverAndLoadPlugins();

// Get plugin manager
const pluginManager = loader.getPluginManager();

// Use integration hooks
const integration = new PluginIntegration(pluginManager);

// Before storing a fact
const modifiedFact = await integration.beforeFactStore(fact);

// After storing
await integration.afterFactStore(modifiedFact);

CLI Usage (Coming Soon)

# List installed plugins
hybrid-mem plugin list

# Install from npm
hybrid-mem plugin install @openclaw/plugin-slack-notifications --npm

# Install from local directory
hybrid-mem plugin install ./my-plugin --local

# Remove plugin
hybrid-mem plugin remove my-plugin

# Disable/enable plugin
hybrid-mem plugin disable my-plugin
hybrid-mem plugin enable my-plugin

# Get plugin info
hybrid-mem plugin info my-plugin

Example Plugin Ideas

  1. Slack Notifications - Send alerts for important facts
  2. Fact Analytics - Track usage patterns and growth
  3. Auto-Tagger - Suggest tags based on content
  4. Backup Reminder - Remind users to backup
  5. Export to Notion - Sync facts to Notion database
  6. GitHub Issues - Create issues from decision facts
  7. Email Digests - Send daily/weekly summaries
  8. Sentiment Analysis - Tag facts with sentiment
  9. Language Detection - Auto-detect fact language
  10. Duplicate Detector - Find and merge duplicates

Integration Checklist

For #3 Graph Explorer

  • Route /graph added to dashboard server
  • GraphQL endpoint /graphql implemented
  • D3.js visualization working
  • Add link from Mission Control dashboard
  • Add “Open in Graph Explorer” button to fact details
  • Document in user guide

For #5 Collaboration

  • CollaborationService implemented
  • Database schema created
  • Permission system working
  • Add REST API endpoints
  • Add GraphQL mutations for team operations
  • Build team management UI
  • Add notification system
  • Document team workflows

For #6 Plugin System

  • PluginManager implemented
  • PluginLoader implemented
  • CLI commands created
  • Developer documentation written
  • Integrate into main plugin lifecycle
  • Add CLI command registration to main CLI
  • Create example plugin repository
  • Launch plugin marketplace

Testing

Graph Explorer

# Start dashboard
hybrid-mem dashboard

# Visit in browser
open http://localhost:7777/graph

# Test GraphQL API
curl -X POST http://localhost:7777/graphql \
  -H "Content-Type: application/json" \
  -d '{"query":"{ stats { totalFacts } }"}'

Collaboration

// Test in Node.js REPL
import { CollaborationService } from './services/collaboration.js';

const collab = new CollaborationService('/tmp/test-collab.db');

// Create test org
collab.createOrganization({
  id: 'test-org',
  name: 'Test Org',
  createdAt: Date.now(),
  plan: 'free'
});

// Verify
const org = collab.getOrganization('test-org');
console.log(org); // Should show organization

Plugin System

// Test plugin loading
import { PluginLoader } from './services/plugin-loader.js';

const loader = new PluginLoader(factsDb, vectorDb, context, './plugins');
await loader.discoverAndLoadPlugins();

// Check loaded plugins
const manager = loader.getPluginManager();
const plugins = manager.getAllPlugins();
console.log(`Loaded ${plugins.length} plugins`);

Performance Considerations

Graph Explorer

  • Efficiently handles up to 1000 nodes
  • For larger graphs, consider pagination or clustering
  • D3.js force simulation can be CPU-intensive

Collaboration

  • Indexed queries for fast lookups
  • Activity log can grow large - consider archiving old entries
  • Permission checks are O(1) with proper indexing

Plugin System

  • Plugins load synchronously at startup
  • Consider lazy loading for better startup time
  • Plugin hooks add small overhead to operations

Security Notes

Graph Explorer

  • Read-only visualization (no mutations via UI)
  • GraphQL introspection enabled for development
  • Consider disabling introspection in production

Collaboration

  • All operations check permissions
  • Activity logging provides audit trail
  • Sensitive data in spaces should be encrypted

Plugin System

  • Plugins have full system access
  • Only install trusted plugins
  • Review plugin code before installation
  • Sandbox plugins in future versions

Next Development Steps

  1. Graph Explorer Enhancements
    • Add time-based filtering
    • Show fact relationships (supersession chains)
    • Export graph as PNG/SVG
    • Add graph analytics (centrality, clusters)
  2. Collaboration Features
    • Real-time collaboration with WebSockets
    • Conflict resolution for concurrent edits
    • Team analytics dashboard
    • Integration with identity providers (OAuth)
  3. Plugin Ecosystem
    • Plugin marketplace website
    • Plugin discovery and ratings
    • Automated plugin testing
    • Plugin sandboxing for security

Conclusion

The first enterprise-growth foundations for features (#3, #5, #6) are implemented, with some advanced APIs intentionally conservative until their backing services mature:

  • #3 Graph Explorer: Accessible at /graph, with GraphQL coverage for facts, search, stats, graph data, and link CRUD.
  • #5 Collaboration: Service scaffold and persistence layer are present; external API integration remains incremental.
  • #6 Plugin System: Loader, CLI, and documentation are present, with dynamic plugin discovery supported for direct and npm-installed plugins.

The implementations follow existing code patterns, are TypeScript-strict compliant, and integrate cleanly with the current architecture. Remaining advanced GraphQL and compression capabilities should be described as roadmap work rather than complete production features.


Back to top

OpenClaw Hybrid Memory — durable agent memory

This site uses Just the Docs, a documentation theme for Jekyll.