Magneteco
Concepts

Event System

Feed structured events into Magneteco memory

Event System

Magneteco's event system allows your applications to feed structured events into the memory system, not just conversations. This is crucial because:

  • Important things happen outside conversations (user actions, system events)
  • Structured events have higher signal-to-noise than raw text
  • Events from external systems (webhooks) can enrich memory

Event Flow

┌─────────────────────────────────────────────────────────────────┐
│                        EVENT SOURCES                             │
├──────────────┬──────────────┬──────────────┬────────────────────┤
│  Your App    │  Webhooks    │  Cron Jobs   │  Other Services    │
└──────┬───────┴──────┬───────┴──────┬───────┴────────┬───────────┘
       │              │              │                │
       ▼              ▼              ▼                ▼
┌─────────────────────────────────────────────────────────────────┐
│                     MAGNETECO EVENT API                          │
│   POST /events           POST /webhooks/:source                  │
└─────────────────────────────────┬───────────────────────────────┘


┌─────────────────────────────────────────────────────────────────┐
│                     EVENT PROCESSOR                              │
│   1. Validate event structure                                    │
│   2. Load event template for eventType                           │
│   3. Transform to natural language                               │
│   4. Queue for extraction (same pipeline as conversations)       │
└─────────────────────────────────────────────────────────────────┘


                        [Normal Memory Pipeline]

Event Schema

interface MemoryEvent {
  // Required
  appId: string;          // Your app identifier
  userId: string;         // User this event relates to
  eventType: string;      // Event type (app-specific)
  source: string;         // Where event originated
  timestamp: string;      // ISO 8601 timestamp
  data: Record<string, unknown>;  // Event-specific payload

  // Optional hints
  suggestedCategory?: string;
  suggestedEntities?: Array<{
    name: string;
    type: string;
  }>;
  importance?: 'low' | 'medium' | 'high' | 'critical';
}

Event Templates

Event templates transform structured events into natural language for the extraction pipeline.

Defining Templates

export const eventTemplates = {
  tanda: {
    sow_approved: (data) =>
      `SOW "${data.sowTitle}" for project "${data.projectName}" was approved by ` +
      `${data.approverName}. The project can now proceed to execution. ` +
      `Client: ${data.clientName}.`,

    deadline_missed: (data) =>
      `IMPORTANT: Deadline missed for ${data.itemType} "${data.itemName}" on project ` +
      `"${data.projectName}". Was due ${data.dueDate}, now ${data.daysOverdue} days overdue. ` +
      `Client: ${data.clientName}. Escalation may be required.`,

    client_feedback: (data) =>
      `Client feedback received from ${data.contactName} at ${data.clientName}: ` +
      `"${data.feedback}". Sentiment: ${data.sentiment}.`,
  },

  glapi: {
    journal_posted: (data) =>
      `Journal entry ${data.entryId} was posted: "${data.memo}". ` +
      `Total amount: ${data.currency}${data.amount}. ` +
      `Accounts affected: ${data.accounts.join(', ')}.`,

    budget_exceeded: (data) =>
      `Budget exceeded for ${data.accountName} (${data.accountCode}): ` +
      `Spent ${data.currency}${data.actualAmount} vs budget ${data.currency}${data.budgetAmount} ` +
      `(${data.percentOver}% over). Period: ${data.period}.`,
  },
};

Using Events

Basic Event Tracking

import { MagnetoClient } from '@magneteco/client';

const memory = new MagnetoClient({
  appId: 'tanda',
  baseUrl: process.env.MAGNETECO_URL,
});

// Track a simple event
await memory.trackEvent({
  userId: 'user-123',
  eventType: 'sow_approved',
  data: {
    sowTitle: 'Phase 1 Implementation',
    projectName: 'NetSuite Migration',
    clientName: 'Acme Corp',
    approverName: 'Jane Smith',
  },
  importance: 'high',
});

With Entity Hints

await memory.trackEvent({
  userId: 'user-123',
  eventType: 'client_feedback',
  data: {
    contactName: 'Bob Johnson',
    clientName: 'Acme Corp',
    feedback: 'Very happy with the testing coverage',
    sentiment: 'positive',
  },
  suggestedEntities: [
    { name: 'Bob Johnson', type: 'Contact' },
    { name: 'Acme Corp', type: 'Client' },
  ],
});

Importance Levels

LevelDescriptionProcessing
lowInformationalNormal processing, lower retrieval priority
mediumStandard eventsNormal processing
highImportant eventsHigher confidence score, flagged in summaries
criticalMust not be forgottenHighest confidence, never pruned
// Importance affects confidence multiplier
const confidenceMultiplier = {
  low: 0.8,
  medium: 1.0,
  high: 1.2,
  critical: 1.5,
};

// Critical events are protected from pruning
function shouldPrune(item: MemoryItem): boolean {
  if (item.metadata?.importance === 'critical') return false;
  // ... normal pruning logic
}

Webhook Integration

Supported Sources

Magneteco can receive webhooks from external services:

  • stripe - Payment events
  • github - Repository events
  • netsuite - ERP events
  • salesforce - CRM events
  • slack - Messaging events
  • custom - Generic handler

Webhook Mappers

Each source has a mapper that validates and transforms webhooks:

interface WebhookMapper {
  // Validate webhook authenticity
  validateSignature?: (payload: any, headers: Record<string, string>) => boolean;

  // Determine if this webhook should create a memory
  shouldProcess: (payload: any) => boolean;

  // Extract user ID from webhook
  extractUserId: (payload: any) => string | null;

  // Map to MemoryEvent
  mapToEvent: (payload: any) => MemoryEvent | null;
}

Example: Stripe Mapper

const stripeMapper: WebhookMapper = {
  validateSignature: (payload, headers) => {
    const signature = headers['stripe-signature'];
    return verifyStripeSignature(payload, signature);
  },

  shouldProcess: (payload) => {
    const relevantEvents = [
      'invoice.paid',
      'invoice.payment_failed',
      'customer.subscription.created',
    ];
    return relevantEvents.includes(payload.type);
  },

  extractUserId: (payload) => {
    return payload.data.object.customer_metadata?.magneteco_user_id;
  },

  mapToEvent: (payload) => ({
    appId: 'my-app',
    userId: payload.data.object.customer_metadata?.magneteco_user_id,
    eventType: payload.type.replace('.', '_'),
    source: 'stripe',
    timestamp: new Date(payload.created * 1000).toISOString(),
    data: {
      customerId: payload.data.object.customer,
      amount: payload.data.object.amount_paid,
      currency: payload.data.object.currency,
    },
    importance: payload.type === 'invoice.payment_failed' ? 'high' : 'medium',
  }),
};

Best Practices

Event Design

  1. Be specific with event types: sow_approved not sow_updated
  2. Include context: Who, what, when, why
  3. Use consistent naming: snake_case for event types
  4. Set appropriate importance: Don't overuse critical

Template Design

  1. Write naturally: Templates should read like descriptions
  2. Include relationships: "Jane approved Bob's SOW"
  3. Add implications: "This means the project can proceed"
  4. Keep it concise: 2-3 sentences is ideal

Webhook Integration

  1. Validate signatures: Always verify authenticity
  2. Filter noise: Not every webhook needs memory
  3. Extract user context: Ensure proper routing
  4. Handle failures gracefully: Don't lose events

On this page