Skip to content
Merged
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
101 changes: 101 additions & 0 deletions .runpod/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
![Mastra AI Agent Server](https://mastra.ai/favicon.ico)

Deploy AI agents powered by [Mastra](https://mastra.ai) with OpenAI-compatible endpoints

---

[![Runpod](https://api.runpod.io/badge/runpod-workers/worker-mastra)](https://www.runpod.io/console/hub/runpod-workers/worker-mastra)

---

## Endpoint Configuration

All behaviour is controlled through environment variables:

| Environment Variable | Description | Default | Required |
| -------------------- | ------------------------------------ | ------- | -------- |
| `RUNPOD_API_KEY` | Runpod API key for AI model access | | Yes |
| `DB_HOST` | PostgreSQL database host | | No |
| `DB_USERNAME` | PostgreSQL database username | | No |
| `DB_NAME` | PostgreSQL database name | | No |
| `DB_PASSWORD` | PostgreSQL database password | | No |
| `DB_PORT` | PostgreSQL database port | 6543 | No |
| `PORT` | Server port | 80 | No |
| `MASTRA_PORT` | Internal Mastra server port | 4111 | No |

## Database Setup (Optional)

Database is optional. Without database credentials, the worker uses in-memory storage (no persistent memory between requests).

For persistent agent memory, configure a PostgreSQL database with the `pgvector` extension. We recommend **Supabase** for easy setup:

1. Create a new project at [Supabase Dashboard](https://supabase.com/dashboard)
2. Go to **Settings** > **Database** > **Connection string**
3. Select **Transaction pooler** mode (recommended for serverless)
4. Use the connection details for your environment variables

## API Usage

### Health Check

```bash
curl https://YOUR_ENDPOINT_ID.api.runpod.ai/ping
```

Response:
```json
{"status": "healthy"}
```

### List Available Agents

```bash
curl https://YOUR_ENDPOINT_ID.api.runpod.ai/api/agents
```

### List Available Tools

```bash
curl https://YOUR_ENDPOINT_ID.api.runpod.ai/api/tools
```

### Execute Weather Tool

```bash
curl -X POST https://YOUR_ENDPOINT_ID.api.runpod.ai/api/tools/get-weather/execute \
-H "Content-Type: application/json" \
-d '{"data": {"location": "Berlin"}}'
```

### Chat with Weather Agent

```bash
curl -X POST https://YOUR_ENDPOINT_ID.api.runpod.ai/api/agents/weatherAgent/chat \
-H "Content-Type: application/json" \
-d '{
"messages": [
{"role": "user", "content": "What is the weather in San Francisco?"}
]
}'
```

## Features

- Mastra AI framework with multi-agent support
- Runpod AI SDK provider with OpenAI GPT-OSS-120B
- PostgreSQL storage with PgVector for agent memory
- `/ping` health check for load balancer monitoring
- OpenAI-compatible chat API

## Architecture

- **Runtime:** CPU (serverless)
- **Endpoint Type:** Load Balancer (LB)
- **Framework:** Mastra + Hono server
- **Storage:** PostgreSQL with pgvector extension

## Documentation

- [Mastra Documentation](https://mastra.ai/docs)
- [Runpod Serverless Documentation](https://docs.runpod.io/serverless)

93 changes: 93 additions & 0 deletions .runpod/hub.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
{
"title": "Mastra AI Agent Server",
"description": "Deploy AI agents powered by Mastra with OpenAI-compatible endpoints and PostgreSQL-backed memory",
"type": "serverless",
"category": "language",
"iconUrl": "https://mastra.ai/favicon.ico",
"config": {
"runsOn": "CPU",
"cpuFlavor": "cpu3g-4-16",
"endpointType": "LB",
"containerDiskInGb": 20,
"env": [
{
"key": "RUNPOD_API_KEY",
"input": {
"name": "Runpod API Key",
"type": "string",
"description": "Your Runpod API key for AI model access",
"required": true,
"sensitive": true
}
},
{
"key": "DB_HOST",
"input": {
"name": "Database Host",
"type": "string",
"description": "PostgreSQL database host address (e.g., db.xxx.supabase.co). Optional - uses in-memory storage if not provided.",
"advanced": true
}
},
{
"key": "DB_USERNAME",
"input": {
"name": "Database Username",
"type": "string",
"description": "PostgreSQL database username",
"advanced": true
}
},
{
"key": "DB_NAME",
"input": {
"name": "Database Name",
"type": "string",
"description": "PostgreSQL database name",
"advanced": true
}
},
{
"key": "DB_PASSWORD",
"input": {
"name": "Database Password",
"type": "string",
"description": "PostgreSQL database password",
"sensitive": true,
"advanced": true
}
},
{
"key": "DB_PORT",
"input": {
"name": "Database Port",
"type": "number",
"description": "PostgreSQL database port (6543 for transaction pooler, 5432 for direct)",
"default": 6543,
"advanced": true
}
},
{
"key": "PORT",
"input": {
"name": "Server Port",
"type": "number",
"description": "Port the server listens on",
"default": 80,
"advanced": true
}
},
{
"key": "MASTRA_PORT",
"input": {
"name": "Internal Mastra Port",
"type": "number",
"description": "Internal port for Mastra server",
"default": 4111,
"advanced": true
}
}
]
}
}

40 changes: 40 additions & 0 deletions .runpod/tests.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
{
"tests": [
{
"name": "health_check_test",
"method": "GET",
"path": "/ping",
"expectedStatus": 200,
"timeout": 10000
},
{
"name": "list_agents_test",
"method": "GET",
"path": "/api/agents",
"expectedStatus": 200,
"timeout": 10000
},
{
"name": "list_tools_test",
"method": "GET",
"path": "/api/tools",
"expectedStatus": 200,
"timeout": 10000
},
{
"name": "weather_tool_test",
"method": "POST",
"path": "/api/tools/get-weather/execute",
"input": {
"data": {
"location": "Berlin"
}
},
"expectedStatus": 200,
"timeout": 30000
}
],
"config": {
"cpuFlavor": "cpu3g-4-16"
}
}
Loading
Loading