npm package: @mnexium/sdk
Description: Official Mnexium SDK for JavaScript/TypeScript - Add memory to your AI applications
Author: Mnexium, Inc.
Latest version: 0.2.2

# @mnexium/sdk

Official Mnexium SDK for JavaScript/TypeScript. Add persistent memory, conversation history, user profiles, and agent state to your AI apps.

Works with **OpenAI**, **Anthropic**, and **Google Gemini**. Bring your own API key.

## Installation

```bash
npm install @mnexium/sdk
```

## Quick Start

```typescript
import { Mnexium } from '@mnexium/sdk';

const mnx = new Mnexium({
  apiKey: 'mnx_...', // Optional - auto-provisions trial key if omitted
  openai: { apiKey: process.env.OPENAI_API_KEY },
});

// Get a Subject handle (no network call)
const alice = mnx.subject('user_123');
// Or auto-generate an ID:
const anon = mnx.subject();

// Simple one-off message
const response = await alice.process('Hello!');
console.log(response.content);

// Multi-turn chat with history
const chat = alice.createChat({ history: true, learn: true, recall: true });
await chat.process('My favorite color is blue');
await chat.process('What is my favorite color?'); // Remembers!
```

## Core Concepts

### Subject

A **Subject** is a logical identity (user, agent, org, device) that owns memory, profile, and state. Creating a Subject is instant — no network call.

```typescript
const alice = mnx.subject('user_123');

// Subject owns all resources
await alice.memories.search('hobbies');
await alice.memories.list();
await alice.profile.get();
await alice.state.get('preferences');
await alice.claims.get('favorite_color');
await alice.chats.list({ limit: 10 });
```

### Chat

A **Chat** is a conversation thread with a stable `chatId`. Chats belong to a Subject.

```typescript
const chat = alice.createChat({
  model: 'gpt-4o-mini',
  history: true,    // Include previous messages
  learn: true,      // Extract memories from conversation
  recall: true,     // Inject relevant memories into context
  profile: true,    // Include user profile in context
});

await chat.process('Hello!');
await chat.process('What did I just say?'); // Has history
```

### Streaming

Real-time streaming responses with async iterators:

```typescript
const stream = await chat.process({ content: 'Tell me a story', stream: true });

for await (const chunk of stream) {
  process.stdout.write(chunk.content);
}

// Metadata available after stream completes
console.log(stream.totalContent);  // Full accumulated text
console.log(stream.usage);         // Token counts
console.log(stream.chatId);        // Chat ID

// Or collect the full response at once
const stream2 = await chat.process({ content: 'Summarize', stream: true });
const text = await stream2.text();
```

### Multi-Provider Support

The SDK auto-detects the provider from the model name:

```typescript
const mnx = new Mnexium({
  openai: { apiKey: process.env.OPENAI_API_KEY },
  anthropic: { apiKey: process.env.ANTHROPIC_API_KEY },
  google: { apiKey: process.env.GOOGLE_API_KEY },
});

const alice = mnx.subject('user_123');
const chat = alice.createChat({ learn: true, recall: true });

// Switch models freely — memories are shared across providers
await chat.process({ content: 'I love hiking', model: 'gpt-4o-mini' });
await chat.process({ content: 'What do I love?', model: 'claude-sonnet-4-20250514' });
await chat.process({ content: 'Tell me my hobbies', model: 'gemini-2.0-flash' });
```

## API Reference

### Memories

```typescript
// Add a memory
const mem = await alice.memories.add('User prefers dark mode', { source: 'settings' });

// List memories
const memories = await alice.memories.list({ limit: 50 });

// Semantic search
const results = await alice.memories.search('preferences', { limit: 5 });

// Get a specific memory
const memory = await alice.memories.get('mem_abc123');

// Update a memory
await alice.memories.update('mem_abc123', { text: 'Updated text' });

// Delete a memory
await alice.memories.delete('mem_abc123');

// List superseded memories
const old = await alice.memories.superseded();

// Restore a superseded memory
await alice.memories.restore('mem_abc123');

// Query recall events (which memories were used in a chat)
const recalls = await alice.memories.recalls({ chatId: 'chat_xyz' });
```

### Real-time Memory Events

Subscribe to memory changes via SSE:

```typescript
const events = alice.memories.subscribe();

for await (const event of events) {
  switch (event.type) {
    case 'memory.created':
      console.log('New memory:', event.data);
      break;
    case 'memory.superseded':
      console.log('Memory replaced:', event.data);
      break;
    case 'memory.deleted':
      console.log('Memory removed:', event.data);
      break;
  }
}

// Close the connection
events.close();
```

Event types: `connected`, `memory.created`, `memory.updated`, `memory.deleted`, `memory.superseded`, `profile.updated`, `heartbeat`

### Claims (Structured Facts)

```typescript
// Set a claim
await alice.claims.set('favorite_color', 'blue', { confidence: 0.95 });

// Get a specific slot
const color = await alice.claims.get('favorite_color');

// List all claim slots
const slots = await alice.claims.list();

// Get current truth (all active values)
const truth = await alice.claims.truth();

// Get claim history
const history = await alice.claims.history();

// Retract a claim
await alice.claims.retract('clm_abc123');
```

### Profile

```typescript
// Get profile
const profile = await alice.profile.get();

// Update profile fields
await alice.profile.update([
  { field_key: 'display_name', value: 'Alice' },
  { field_key: 'timezone', value: 'America/New_York' },
]);

// Delete a profile field
await alice.profile.deleteField('timezone');
```

### Agent State

Persist key-value state for workflows, wizards, and agent continuity:

```typescript
// Set state (with optional TTL)
await alice.state.set('current_task', { step: 3 }, { ttlSeconds: 3600 });

// Get state
const task = await alice.state.get('current_task');

// Delete state
await alice.state.delete('current_task');
```

### Records (Structured Data)

Define typed schemas and work with structured records:

```typescript
// Define a schema
await mnx.records.defineSchema(
  'deal',
  {
    title: { type: 'string', required: true },
    value: { type: 'number' },
    stage: { type: 'string' },
  },
  { displayName: 'Deal', description: 'Sales opportunities' }
);

// Insert a record
const deal = await mnx.records.insert('deal', {
  title: 'Acme Renewal',
  value: 500000,
  stage: 'negotiation',
});

// Get/update/delete
const found = await mnx.records.get('deal', deal.record_id);
await mnx.records.update('deal', deal.record_id, { stage: 'closed_won' });
await mnx.records.delete('deal', deal.record_id);

// Query/search
const wonDeals = await mnx.records.query('deal', {
  where: { stage: 'closed_won' },
  orderBy: '-value',
  limit: 10,
});
const similar = await mnx.records.search('deal', 'large enterprise renewals');
```

### Integrations

Manage inbound pull and webhook connectors that map external payloads into prompt-ready keys:

```typescript
// Create a pull integration
const integration = await mnx.integrations.create({
  name: 'Weather Forecast',
  mode: 'pull',
  scope: 'project',
  endpointUrl: 'https://api.open-meteo.com/v1/forecast',
  method: 'GET',
  allowLiveFetch: true,
  cacheTtlSeconds: 300,
  queryTemplate: {
    latitude: '40.7128',
    longitude: '-74.0060',
    current: 'temperature_2m,wind_speed_10m',
  },
  outputMap: [
    { key: 'weather_temp', path: 'current.temperature_2m' },
    { key: 'weather_wind', path: 'current.wind_speed_10m' },
  ],
});

// List / inspect / update / disable
const integrations = await mnx.integrations.list();
const sameIntegration = await mnx.integrations.get(integration.integration_id);
await mnx.integrations.update(integration.integration_id, { cacheTtlSeconds: 600 });
await mnx.integrations.delete(integration.integration_id);

// Execute a dry run or refresh cache
const preview = await mnx.integrations.test(integration.integration_id);
const refreshed = await mnx.integrations.sync(integration.integration_id, {
  subjectId: 'user_123',
  chatId: 'chat_456',
});

// Send a signed webhook payload
await mnx.integrations.webhook(integration.integration_id, {
  current: { temperature_2m: 14.1, wind_speed_10m: 13.8 },
}, {
  secret: 'whsec_...',
  eventId: 'evt_123',
});

console.log(preview.values.weather_temp);
console.log(refreshed.cache_written);
```

### Chat History

```typescript
// List recent chats
const chats = await alice.chats.list({ limit: 10 });

// Read messages from a specific chat
const messages = await alice.chats.read('chat_abc123');

// Delete a chat
await alice.chats.delete('chat_abc123');
```

### System Prompts

```typescript
// Create a prompt
const prompt = await mnx.prompts.create({
  name: 'Customer Support',
  promptText: 'You are a helpful customer support agent...',
  isDefault: true,
});

// List all prompts
const prompts = await mnx.prompts.list();

// Update a prompt
await mnx.prompts.update(prompt.id, { promptText: 'Updated instructions...' });

// Preview which prompts will be injected
const resolved = await mnx.prompts.resolve({ subjectId: 'user_123' });

// Use in chat
const chat = alice.createChat({ systemPrompt: prompt.id });

// Delete a prompt
await mnx.prompts.delete(prompt.id);
```

## Configuration

```typescript
const mnx = new Mnexium({
  apiKey: 'mnx_...',           // Optional — auto-provisions trial key
  baseUrl: 'https://mnexium.com/api/v1', // API base URL
  timeout: 30000,              // Request timeout (ms)
  maxRetries: 2,               // Retry count for failed requests
  openai: { apiKey: '...' },   // OpenAI config
  anthropic: { apiKey: '...' }, // Anthropic config
  google: { apiKey: '...' },   // Google config
  defaults: {                  // Default options for all process() calls
    model: 'gpt-4o-mini',
    learn: true,
    recall: false,
    profile: false,
    history: true,
    memoryPolicy: 'mp_sales_v1', // Or false to disable policy for a request
  },
});
```

### Mnx Parameters

Every `process()` and `chat.process()` call supports these options:

| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| `model` | string | `'gpt-4o-mini'` | Model to use |
| `learn` | boolean/`'force'` | `true` | Extract memories from conversation |
| `recall` | boolean | `false` | Inject relevant memories into context |
| `profile` | boolean | `false` | Include user profile in context |
| `history` | boolean | `true` | Prepend previous messages from this chat |
| `log` | boolean | `true` | Save messages to chat history |
| `summarize` | boolean/string | `false` | `'light'`, `'balanced'`, or `'aggressive'` |
| `systemPrompt` | boolean/string | `true` | `true` (auto), `false` (skip), or prompt ID |
| `memoryPolicy` | string/boolean | — | Policy ID string to force a policy, or `false` to disable policy for this request |
| `records` | object | — | Records controls: `learn: 'force' | 'auto' | false`, `tables: string[]`, `sync: boolean`, `recall: boolean` |
| `stream` | boolean | `false` | Enable streaming response |
| `metadata` | object | — | Custom metadata attached to saved logs |

Memory policy fallback header: the SDK also sends `x-mnx-memory-policy` when `memoryPolicy` is set.
- `memoryPolicy: false` -> `x-mnx-memory-policy: false`
- `memoryPolicy: 'mp_abc123'` -> `x-mnx-memory-policy: mp_abc123`

Records extraction controls:

```typescript
const response = await mnx.process({
  content: 'Extract and save order details',
  records: {
    learn: 'force',            // 'force' | 'auto' | false
    tables: ['orders'],        // Optional allowlist
    sync: true,                // Wait for write completion
    recall: true,              // Include prior records in context
  },
});

console.log(response.records); // Sync extraction metadata (when returned by backend)
```

## Trial Keys

If you don't provide an API key, Mnexium auto-provisions a trial key:

```typescript
const mnx = new Mnexium({
  openai: { apiKey: process.env.OPENAI_API_KEY },
});

const alice = mnx.subject('user_123');
await alice.process('Hello!');

// Get the provisioned key to save it
const trial = mnx.getTrialInfo();
console.log('Save this key:', trial?.key);
```

Claim your trial key at [mnexium.com/claim](https://mnexium.com/claim).

## Error Handling

```typescript
import { Mnexium, AuthenticationError, RateLimitError, APIError } from '@mnexium/sdk';

try {
  await alice.process('Hello!');
} catch (error) {
  if (error instanceof AuthenticationError) {
    console.error('Invalid API key');
  } else if (error instanceof RateLimitError) {
    console.error(`Rate limited. Current: ${error.current}, Limit: ${error.limit}`);
  } else if (error instanceof APIError) {
    console.error(`API error ${error.status}: ${error.message}`);
  }
}
```

## Raw Response

Access the full API response for advanced use:

```typescript
const response = await chat.process('Hello!');
console.log(response.raw);    // Full API response object
console.log(response.chatId); // Chat ID
console.log(response.usage);  // { promptTokens, completionTokens, totalTokens }
```

## Examples

See the [examples/](./examples/) directory for runnable demos:

| Example | Description |
|---------|-------------|
| `npm run hello` | Hello world — chat, history, recall |
| `npm run streaming` | Real-time streaming responses |
| `npm run events` | Real-time memory event subscriptions |
| `npm run memories` | Add, list, search, delete memories |
| `npm run claims` | Claims extraction and manual setting |
| `npm run state` | Agent state with TTL |
| `npm run profile` | User profiles |
| `npm run records` | Structured records (schemas, CRUD, query, search) |
| `npm run prompts` | System prompt management |
| `npm run multi` | Multi-provider (OpenAI, Claude, Gemini) |
| `npm run full` | Full API demo |

## TypeScript

Full TypeScript support with exported types:

```typescript
import type {
  MnexiumConfig,
  ChatOptions,
  ProcessOptions,
  ProcessResponse,
  ChatHistoryItem,
  StreamChunk,
  MemoryEvent,
} from '@mnexium/sdk';

import { StreamResponse, EventStream } from '@mnexium/sdk';
```

## Supported Models

- **OpenAI:** gpt-4o, gpt-4o-mini, gpt-4-turbo, gpt-4, gpt-3.5-turbo, o1, o1-mini, o3
- **Anthropic:** claude-3-opus, claude-3-sonnet, claude-3-haiku, claude-3-5-sonnet, claude-sonnet-4
- **Google Gemini:** gemini-2.0-flash-lite, gemini-2.5-flash, gemini-1.5-pro, gemini-1.5-flash

## Links

- [Documentation](https://mnexium.com/docs)
- [Blog](https://mnexium.com/blogs)
- [Sign Up](https://mnexium.com)

## License

MIT