Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .changeset/fix-openmemory-esbuild.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
"@darkresearch/mallory-server": patch
---

fix: resolve esbuild version conflict in OpenMemory setup to use bun consistently

This fixes the esbuild version mismatch that prevented using bun with OpenMemory backend by pinning esbuild to 0.25.12 and updating the setup script to use bun instead of npm.
31 changes: 27 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ mallory/
## ✨ Features

### Client (Mobile & Web)

- 🔐 **Authentication**: Google OAuth via Supabase
- 💬 **AI Chat**: Streaming conversations with Claude
- 💰 **Embedded Wallet**: Grid-powered smart contract wallets
Expand All @@ -26,6 +27,7 @@ mallory/
- 🏷️ **Version Tracking**: Automatic version display with git commit hash

### Server (Backend API)

- 🤖 **AI Streaming**: Claude integration with Server-Sent Events and extended thinking
- 🔧 **AI Tools**: Web search (Exa), user memory (Supermemory), and 20+ Nansen data APIs
- 💰 **x402 Payments**: Server-side implementation for premium data access
Expand All @@ -34,13 +36,15 @@ mallory/
- 🚀 **Production Ready**: Comprehensive testing infrastructure

### Monorepo Management

- 🔄 **Synchronized Versioning**: Single command updates all packages
- 🏷️ **Automatic Releases**: GitHub releases created on version tags
- 📝 **Generated Changelogs**: Commit history automatically compiled

## 🚀 Quick Start

### Prerequisites

- Node.js 18+ or Bun
- Git
- Expo CLI (optional, included in dependencies)
Expand All @@ -56,6 +60,7 @@ bun install
### 2. Environment Setup

#### Client Environment (`.env` in `apps/client/`)

```bash
# Copy from template
cp apps/client/.env.example apps/client/.env
Expand All @@ -69,6 +74,7 @@ EXPO_PUBLIC_GRID_ENV=sandbox
```

#### Server Environment (`.env` in `apps/server/`)

```bash
# Copy from template
cp apps/server/.env.example apps/server/.env
Expand All @@ -84,18 +90,24 @@ GRID_API_KEY=your-grid-api-key
EXA_API_KEY=your-exa-key

# Infinite Memory (OpenMemory for infinite context):
# Note: Run 'bash services/openmemory-setup.sh' first to set up the backend
# Default API key is 'openmemory_dev_key' (configurable in openmemory/backend/.env)
OPENMEMORY_URL=http://localhost:8080
OPENMEMORY_API_KEY=your-openmemory-key
OPENMEMORY_API_KEY=openmemory_dev_key
# Optional: For free embeddings, set GEMINI_API_KEY (otherwise uses OpenAI)
GEMINI_API_KEY=your-gemini-key
```

### 3. Run Development Servers

#### Option A: Run Both (Client + Server)

```bash
bun run dev
```

#### Option B: Run Separately

```bash
# Terminal 1 - Backend
bun run server
Expand All @@ -105,6 +117,7 @@ bun run client
```

The client will be available at:

- Web: http://localhost:8081
- API: http://localhost:3001

Expand All @@ -113,6 +126,7 @@ The client will be available at:
See [apps/client/README.md](./apps/client/README.md) for detailed client documentation.

**Key Commands:**

```bash
cd apps/client

Expand All @@ -131,11 +145,13 @@ bun run android
See [apps/server/README.md](./apps/server/README.md) for detailed server documentation.

**API Endpoints:**

- `POST /api/chat` - AI chat streaming with tool calling
- `GET /api/wallet/holdings` - Wallet holdings with price data
- `GET /health` - Health check

**AI Tools:**

- `searchWeb` - Web search via Exa (always available)
- `addMemory` - User memory via Supermemory (optional)
- `nansen*` - 20+ Nansen API endpoints for blockchain analytics (requires x402 payments)
Expand All @@ -158,15 +174,19 @@ Grid's architecture means neither the client nor server ever has access to user
The `packages/shared` directory contains TypeScript types and utilities shared between client and server:

```typescript
import type { ChatRequest, HoldingsResponse } from '@darkresearch/mallory-shared';
import { X402PaymentService } from '@darkresearch/mallory-shared';
import type {
ChatRequest,
HoldingsResponse,
} from "@darkresearch/mallory-shared";
import { X402PaymentService } from "@darkresearch/mallory-shared";
```

## 🧪 Testing

Mallory has comprehensive test coverage: unit tests, integration tests, and E2E tests.

**Run tests:**

```bash
cd apps/client

Expand All @@ -183,6 +203,7 @@ bun test __tests__/e2e/long-context.test.ts # ~10-20 min, ~$2-3
```

**CI/CD:**

- Regular tests run on every PR
- AI tests only run when `[run-ai-tests]` is in commit message:
```bash
Expand All @@ -194,13 +215,15 @@ See [apps/client/__tests__/CHAT_STATE_TESTS.md](./apps/client/__tests__/CHAT_STA
## 🚢 Deployment

### Client Deployment

- **Web**: Deploy to Vercel, Netlify, or any static host
- **iOS**: Deploy via Expo EAS or native build
- **Android**: Deploy via Expo EAS or native build

See [apps/client/README.md](./apps/client/README.md#deployment) for details.

### Server Deployment

- **Recommended**: Railway, Render, Fly.io
- **Node.js**: Any Node.js 18+ hosting

Expand Down Expand Up @@ -300,6 +323,7 @@ Apache License 2.0 - see [LICENSE](./LICENSE) for details.
## 🙏 Acknowledgments

Built with:

- [Expo](https://expo.dev) - React Native framework
- [Grid (Squads)](https://developers.squads.so) - Embedded wallets
- [Anthropic](https://anthropic.com) - Claude AI with extended thinking
Expand All @@ -314,4 +338,3 @@ Built with:
---

**Made with ❤️ by [Dark](https://darkresearch.ai)**

24 changes: 20 additions & 4 deletions apps/server/src/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -125,23 +125,39 @@ async function checkOpenMemory() {
}

try {
// Try to ping OpenMemory health endpoint
const response = await fetch(`${openMemoryUrl}/health`, {
// Test with cavira.app OpenMemory - try root endpoint or a simple query
// cavira.app OpenMemory may not have /health, so we test basic connectivity
const testUrl = `${openMemoryUrl}/`;
const response = await fetch(testUrl, {
method: 'GET',
headers: {
'Authorization': `Bearer ${openMemoryApiKey}`,
'Content-Type': 'application/json',
},
signal: AbortSignal.timeout(2000), // 2 second timeout
});

if (response.ok) {
// Only HTTP 200 indicates successful connection
if (response.status === 200) {
console.log(`✅ OpenMemory: Connected (${openMemoryUrl})`);
console.log(` Infinite memory enabled with semantic retrieval`);
} else if (response.status === 401) {
console.log(`❌ OpenMemory: Authentication failed (${openMemoryUrl})`);
console.log(` Invalid API key. Check OPENMEMORY_API_KEY in .env`);
console.log(` Infinite memory will be disabled until this is fixed.`);
} else if (response.status === 404) {
console.log(`⚠️ OpenMemory: Endpoint not found (HTTP 404)`);
console.log(` OpenMemory server is reachable but endpoint may be incorrect`);
console.log(` Check OPENMEMORY_URL in .env`);
} else {
console.log(`⚠️ OpenMemory: Unreachable (HTTP ${response.status})`);
console.log(` Check that OpenMemory is running on ${openMemoryUrl}`);
}
} catch (error) {
console.log(`❌ OpenMemory: Connection failed (${openMemoryUrl})`);
console.log(` Error: ${error instanceof Error ? error.message : 'Unknown error'}`);
console.log(` Run: cd services/openmemory/backend && bun start`);
console.log(` Run: bash services/openmemory-setup.sh`);
console.log(` Then: cd services/openmemory/backend && bun start`);
}
}

Expand Down
70 changes: 57 additions & 13 deletions services/openmemory-setup.sh
Original file line number Diff line number Diff line change
@@ -1,17 +1,41 @@
#!/bin/bash
# OpenMemory setup script for Mallory

set -e
set -o pipefail

echo "🚀 Setting up OpenMemory for Mallory..."

# Check if bun is available
if ! command -v bun &> /dev/null; then
echo "❌ Error: bun is required but not installed"
echo " Please install bun first: https://bun.sh"
exit 1
fi

# Navigate to services directory
cd "$(dirname "$0")"

# Clone OpenMemory repository if it doesn't exist
if [ ! -d "openmemory" ]; then
echo "📥 Cloning OpenMemory repository..."
git clone https://github.com/CaviraOSS/OpenMemory.git openmemory
echo "✅ OpenMemory repository cloned"
else
echo "✅ OpenMemory repository already exists"
fi

# Create .env file if it doesn't exist
if [ ! -f services/openmemory/backend/.env ]; then
if [ ! -f openmemory/backend/.env ]; then
echo "📝 Creating OpenMemory .env file..."
cat > services/openmemory/backend/.env << 'EOF'
mkdir -p openmemory/backend/data
cat > openmemory/backend/.env << EOF
# OpenMemory Configuration for Mallory

# Embedding Provider - Using Gemini (free tier!)
OM_EMBED_PROVIDER=gemini
OM_GEMINI_API_KEY=${GEMINI_API_KEY}
# Embedding Provider - Using Gemini (free tier!) or OpenAI
OM_EMBED_PROVIDER=${OM_EMBED_PROVIDER:-gemini}
OM_GEMINI_API_KEY=${GEMINI_API_KEY:-}
OPENAI_API_KEY=${OPENAI_API_KEY:-}

# Server Configuration
OM_PORT=8080
Expand All @@ -23,30 +47,50 @@ OM_DB_PATH=./data/openmemory.sqlite
# Memory Tier
OM_TIER=smart

# Vector Dimensions (Gemini)
OM_VEC_DIM=768
# Vector Dimensions (Gemini: 768, OpenAI: 1536)
OM_VEC_DIM=${OM_VEC_DIM:-768}

# API Key
# API Key for authentication
OM_API_KEY=${OPENMEMORY_API_KEY:-openmemory_dev_key}
EOF
echo "✅ .env file created"
else
echo "✅ .env file already exists"
fi

# Fix esbuild version conflict for bun compatibility
echo "🔧 Fixing esbuild version for bun compatibility..."
cd openmemory/backend
# Add esbuild 0.25.12 to devDependencies if not already present
if ! grep -q '"esbuild":' package.json; then
# Use bun to add esbuild as devDependency
bun add -d esbuild@0.25.12
echo "✅ Added esbuild 0.25.12 to devDependencies"
else
echo "✅ esbuild already in package.json"
fi

# Install dependencies
echo "📦 Installing OpenMemory dependencies..."
if [ ! -d "node_modules" ]; then
bun install
echo "✅ Dependencies installed"
else
echo "✅ Dependencies already installed"
fi

# Build OpenMemory
echo "🔨 Building OpenMemory..."
cd services/openmemory/backend
bun run build

echo ""
echo "✅ OpenMemory is ready!"
echo "✅ OpenMemory setup complete!"
echo ""
echo "To start OpenMemory:"
echo " cd services/openmemory/backend && bun start"
echo ""
echo "Or add to your .env:"
echo "Or add to your server .env:"
echo " OPENMEMORY_URL=http://localhost:8080"
echo " OPENMEMORY_API_KEY=openmemory_dev_key"
echo " OPENAI_API_KEY=your_openai_key"

echo " GEMINI_API_KEY=your_gemini_key (optional, for free embeddings)"
echo " OPENAI_API_KEY=your_openai_key (if not using Gemini)"
Loading