npm package: @mirra-messenger/sdk
Description: Official TypeScript/JavaScript SDK for the Mirra Messenger API
Author: Mirra
Latest version: 0.20.0

# Mirra SDK for TypeScript/JavaScript

Official TypeScript/JavaScript SDK for the [Mirra API](https://docs.getmirra.app).

Build, deploy, and monetize AI agents, serverless scripts, and API integrations with a simple, type-safe client library.

## Installation

```bash
npm install @mirra-messenger/sdk
```

or with yarn:

```bash
yarn add @mirra-messenger/sdk
```

## Quick Start

```typescript
import { MirraSDK } from '@mirra-messenger/sdk';

// Initialize the SDK with your API key
const mirra = new MirraSDK({
  apiKey: 'your_api_key_here'
});

// Create a memory
const memory = await mirra.memory.create({
  content: 'Important information to remember',
  type: 'note',
  metadata: { category: 'work' }
});

// Chat with AI
const response = await mirra.ai.chat({
  messages: [
    { role: 'user', content: 'Hello, how are you?' }
  ]
});

console.log(response.content);
```

## Authentication

Get your API key from the Mirra mobile app:
1. Open the Mirra app
2. Go to **Settings** → **API Keys**
3. Click **Generate New Key**
4. Copy your API key

⚠️ **Keep your API key secure!** Never commit it to version control or expose it in client-side code.

## Usage Examples

### Memory Operations

Store and retrieve information in Mirra's knowledge graph with semantic search.

```typescript
// Create a memory entity
const memory = await mirra.memory.create({
  type: 'task',
  content: 'Buy groceries: milk, eggs, bread',
  metadata: { priority: 'high', dueDate: '2025-11-20' }
});

console.log(`Created memory with ID: ${memory.id}`);

// Search memories semantically
const results = await mirra.memory.search({
  query: 'grocery shopping',
  limit: 10
});

results.forEach(result => {
  console.log(`[${result.score}] ${result.content}`);
});

// Query memories with filters
const tasks = await mirra.memory.query({
  type: 'task',
  limit: 20,
  offset: 0
});

// Find a specific memory
const found = await mirra.memory.findOne({
  filters: { id: memory.id }
});

// Update a memory
await mirra.memory.update({
  id: memory.id,
  content: 'Updated: Buy groceries and vegetables',
  metadata: { priority: 'medium', completed: false }
});

// Delete a memory
await mirra.memory.delete(memory.id);
```

#### Memory Types

Supported entity types:
- `task` - Tasks and todos
- `topic` - Discussion topics and themes
- `document` - Documents and notes
- `contact` - Contact information
- `event` - Calendar events and meetings
- `idea` - Ideas and brainstorming notes

### AI Operations

Access powerful AI capabilities with multi-provider support (Anthropic Claude, Google Gemini, OpenAI).

#### Chat

Simple conversational AI with support for system prompts and multi-turn conversations.

```typescript
// Basic chat
const response = await mirra.ai.chat({
  messages: [
    { role: 'user', content: 'Explain quantum computing in simple terms' }
  ]
});

console.log(response.content);
console.log(`Tokens used: ${response.usage.inputTokens + response.usage.outputTokens}`);

// Multi-turn conversation with system prompt
const chat = await mirra.ai.chat({
  messages: [
    { role: 'system', content: 'You are a helpful coding assistant.' },
    { role: 'user', content: 'How do I reverse a string in Python?' },
    { role: 'assistant', content: 'You can reverse a string using slicing: text[::-1]' },
    { role: 'user', content: 'Can you show me with a function?' }
  ],
  provider: 'anthropic',
  model: 'claude-3-5-sonnet-20241022',
  temperature: 0.7,
  maxTokens: 1000
});
```

#### Streaming

Stream AI responses in real-time for better user experience.

```typescript
const stream = mirra.ai.chatStream({
  messages: [
    { role: 'user', content: 'Write a short story about a robot learning to paint' }
  ],
  provider: 'anthropic',
  model: 'claude-3-haiku-20240307'
});

// Process chunks as they arrive
for await (const chunk of stream) {
  if (chunk.done) {
    console.log('\n\nStream complete!');
    console.log(`Tokens: ${chunk.usage?.inputTokens} in, ${chunk.usage?.outputTokens} out`);
  } else {
    process.stdout.write(chunk.delta);
  }
}
```

#### Decision Making

Get structured AI decisions from multiple options with reasoning.

```typescript
const decision = await mirra.ai.decide({
  prompt: 'Which programming language should I learn first?',
  options: [
    { id: 'python', label: 'Python', metadata: { difficulty: 'easy', versatile: true } },
    { id: 'javascript', label: 'JavaScript', metadata: { difficulty: 'medium', webFocused: true } },
    { id: 'rust', label: 'Rust', metadata: { difficulty: 'hard', performant: true } }
  ],
  context: 'I want to build web applications and have no prior coding experience',
  provider: 'anthropic',
  model: 'claude-3-haiku-20240307'
});

console.log(`Selected: ${decision.selectedOption}`);
console.log(`Reasoning: ${decision.reasoning}`);
```

#### Batch Processing

Process multiple AI requests efficiently in a single call.

```typescript
const batch = await mirra.ai.batchChat({
  requests: [
    { message: 'What is 2+2?' },
    { message: 'What is the capital of France?' },
    { message: 'Explain photosynthesis briefly' }
  ]
});

batch.forEach((response, index) => {
  console.log(`Response ${index + 1}:`, response.content);
});
```

#### Supported Providers & Models

**Anthropic Claude:**
- `claude-3-haiku-20240307` - Fast, cost-effective
- `claude-3-sonnet-20240229` - Balanced performance
- `claude-3-5-sonnet-20241022` - Advanced reasoning (default)
- `claude-3-opus-20240229` - Highest quality

**Google Gemini:**
- `gemini-2.5-flash` - Fast, efficient
- `gemini-2.5-pro` - Advanced capabilities

**OpenAI GPT:**
- `gpt-4o` - Latest GPT-4 Optimized
- `gpt-4o-mini` - Compact and fast
- Coming soon

#### Token Consumption

All AI operations consume tokens from your account balance. Monitor your usage:
- Input tokens: Your messages and context
- Output tokens: AI's responses

View your balance in the Mirra app under Settings → API & Billing.

### Agent Management

```typescript
// Create an agent
const agent = await mirra.agents.create({
  subdomain: 'my-assistant',
  name: 'My Personal Assistant',
  systemPrompt: 'You are a helpful personal assistant.',
  description: 'An AI assistant for daily tasks',
  enabled: true
});

// List agents
const agents = await mirra.agents.list();

// Update an agent
await mirra.agents.update(agent.id, {
  name: 'Updated Assistant Name',
  enabled: false
});

// Delete an agent
await mirra.agents.delete(agent.id);
```

### Script Operations

```typescript
// Create a script
const script = await mirra.scripts.create({
  name: 'Data Processor',
  description: 'Processes incoming data',
  code: `
    export async function handler(event, context, mirra) {
      // Your script logic here
      const result = await mirra.memory.search({
        query: event.query,
        limit: 5
      });
      
      return { success: true, results: result };
    }
  `,
  runtime: 'nodejs18',
  config: {
    timeout: 30,
    memory: 256,
    allowedResources: []
  }
});

// Deploy a script
await mirra.scripts.deploy(script.id);

// Invoke a script
const result = await mirra.scripts.invoke({
  scriptId: script.id,
  payload: { query: 'test data' }
});

console.log(result);
```

### Resource Operations

```typescript
// List available resources
const resources = await mirra.resources.list();

// Call a resource method
const result = await mirra.resources.call({
  resourceId: 'weather-api',
  method: 'getCurrentWeather',
  params: { city: 'San Francisco' }
});
```

### Document Operations

Upload, manage, and search documents with semantic search and multi-graph sharing.

```typescript
import { readFileSync } from 'fs';

// Upload a document
const fileBuffer = readFileSync('report.pdf');
const uploadResult = await mirra.documents.upload({
  file: fileBuffer.toString('base64'),
  filename: 'report.pdf',
  mimeType: 'application/pdf',
  title: 'Q4 Financial Report',
  productTags: ['finance', 'quarterly']
});

console.log(`Uploaded: ${uploadResult.documentId}`);
console.log(`Chunks: ${uploadResult.chunkCount}`);

// List documents
const docs = await mirra.documents.list({ limit: 20 });
console.log(`Found ${docs.count} documents`);

// Get document details
const doc = await mirra.documents.get(uploadResult.documentId);
console.log(`Title: ${doc.document.title}`);
console.log(`Chunks: ${doc.chunkCount}`);

// Search documents semantically
const searchResults = await mirra.documents.search({
  query: 'quarterly earnings revenue',
  limit: 10,
  threshold: 0.7
});

searchResults.results.forEach(result => {
  console.log(`[${result.score.toFixed(2)}] ${result.content.substring(0, 100)}...`);
});

// Share document to a group
await mirra.documents.share(uploadResult.documentId, {
  targetGraphId: 'group-123',
  shareReason: 'For team review'
});

// List where a document is shared
const graphs = await mirra.documents.listGraphs(uploadResult.documentId);
graphs.graphs.forEach(g => {
  console.log(`Shared in: ${g.graphId} (primary: ${g.isPrimary})`);
});

// Remove sharing from a graph
await mirra.documents.unshare(uploadResult.documentId, 'group-123');

// Delete a document
await mirra.documents.delete(uploadResult.documentId);
```

#### Supported Document Types

- PDF (`.pdf`) - `application/pdf`
- Word (`.docx`) - `application/vnd.openxmlformats-officedocument.wordprocessingml.document`
- Plain Text (`.txt`) - `text/plain`
- Markdown (`.md`) - `text/markdown`

### Template Operations

```typescript
// List templates
const templates = await mirra.templates.list();

// Get template details
const template = await mirra.templates.get('template-id');

// Install a template
await mirra.templates.install('template-id');
```

### Marketplace

```typescript
// Browse marketplace
const items = await mirra.marketplace.browse({
  type: 'agent',
  category: 'productivity',
  limit: 20
});

// Search marketplace
const searchResults = await mirra.marketplace.search('weather assistant');
```

## Configuration

### Custom Base URL

For development or custom deployments:

```typescript
const mirra = new MirraSDK({
  apiKey: 'your_api_key',
  baseUrl: 'http://localhost:3000/api/sdk/v1'
});
```

### Error Handling

All SDK methods throw errors that include:
- `message`: Human-readable error message
- `code`: Error code (e.g., 'VALIDATION_ERROR', 'NOT_FOUND')
- `statusCode`: HTTP status code
- `details`: Additional error details (if available)

```typescript
try {
  await mirra.memory.create({ content: '' }); // Invalid: empty content
} catch (error) {
  console.error('Error code:', error.code);
  console.error('Message:', error.message);
  console.error('Status:', error.statusCode);
  console.error('Details:', error.details);
}
```

## TypeScript Support

This SDK is written in TypeScript and provides full type definitions out of the box. No additional `@types` packages needed!

```typescript
import { MirraSDK, ChatMessage, Agent } from '@mirra-messenger/sdk';

const messages: ChatMessage[] = [
  { role: 'user', content: 'Hello!' }
];

const agent: Agent = await mirra.agents.create({
  subdomain: 'test',
  name: 'Test Agent',
  systemPrompt: 'You are helpful.'
});
```

## Migration Guide

### Flat Responses (v0.15+)

All SDK methods now return **flat response objects** instead of wrapped `{ data, metadata }` envelopes. This applies to every method across all adapters — generated methods, hand-coded helpers, and `resources.call()`.

**Before (v0.14 and earlier):**

```typescript
const result = await mirra.memory.create({ content: 'Hello' });
console.log(result.data.id);       // ← had to unwrap .data
console.log(result.metadata);      // ← metadata envelope field
```

**After (v0.15+):**

```typescript
const result = await mirra.memory.create({ content: 'Hello' });
console.log(result.id);            // ← flat, direct access
```

#### What changed

| Method category | Before | After |
|----------------|--------|-------|
| Generated adapter methods (`mirra.memory.*`, `mirra.twitter.*`, etc.) | `result.data.field` | `result.field` |
| `mirra.resources.call()` | `result.data.field` | `result.field` |
| `mirra.flows.get()` / `mirra.flows.list()` | `result.data.field` | `result.field` |

#### How to migrate

Search your codebase for the old wrapper pattern and remove the `.data` layer:

```bash
# Find all .data. accesses on SDK results
grep -rn '\.data\.' --include='*.ts' --include='*.js' src/
```

Common patterns to update:

```typescript
// Array results
result.data.forEach(...)      →  result.forEach(...)
result.data[0]                →  result[0]
result.data.length            →  result.length

// Object field access
result.data.id                →  result.id
result.data?.status           →  result?.status

// Existence checks
if (result.data) { ... }      →  if (result) { ... }

// Destructuring
const { data } = result;      →  // use result directly
```

#### `callDirect()` is deprecated

`resources.callDirect()` was introduced as the v2 alternative to `resources.call()`. Now that `call()` itself uses the v2 endpoint, `callDirect()` is redundant. It still works (delegates to `call()`) but will be removed in a future release.

```typescript
// Before — had to choose between call() and callDirect()
const wrapped = await mirra.resources.call(params);     // v1 wrapped
const flat = await mirra.resources.callDirect(params);   // v2 flat

// After — just use call()
const result = await mirra.resources.call(params);       // v2 flat
```

## API Reference

For complete API documentation, visit [https://docs.getmirra.app](https://docs.getmirra.app)

## Support

- **Documentation**: [https://docs.getmirra.app](https://docs.getmirra.app)
- **Issues**: [GitHub Issues](https://github.com/Oz-Networks/fxn-monorepo/issues)
- **Email**: support@getmirra.app

## License

MIT