Skip to main content

A simple, powerful way to deploy Tyler AI agents as Slack agents

Project description

Space Monkey - Tyler Slack Agent

A simple, powerful way to deploy Tyler AI agents as Slack agents. Space Monkey handles all the complexity of Slack integration while you focus on building your agent's capabilities.

Overview

Space Monkey bridges the gap between Tyler agents and Slack, providing:

  • Seamless integration of Tyler agents into Slack workspaces
  • Intelligent message classification and routing
  • Persistent conversation management using Narrator
  • Built-in file handling and health monitoring
  • Production-ready deployment with Docker support

Features

  • Simple API: Just import SlackApp, Agent, and stores from one package
  • Intelligent Message Routing: Automatically classifies messages and routes appropriately
  • Thread Management: Persistent conversation threads with configurable storage backends
  • File Handling: Built-in support for file attachments and processing
  • Health Monitoring: Optional health check endpoints for production deployments
  • Weave Integration: Built-in tracing and monitoring support

Quick Start

1. Install the Package

# Using uv (recommended)
uv add slide-space-monkey

# Using pip (fallback)
pip install slide-space-monkey

2. Set Up Environment Variables

Copy the example environment file and add your tokens:

cp env.example .env
# Then edit .env with your actual tokens

Required variables:

# Required: Slack Configuration
SLACK_BOT_TOKEN=xoxb-your-bot-token
SLACK_APP_TOKEN=xapp-your-app-token

# Required: LLM Configuration (at least one)
OPENAI_API_KEY=sk-your-openai-api-key      # For GPT models
# ANTHROPIC_API_KEY=sk-ant-your-key         # For Claude models
# GEMINI_API_KEY=your-gemini-api-key        # For Gemini models
# XAI_API_KEY=xai-your-grok-api-key         # For Grok models

# Optional: Weave Monitoring
WANDB_API_KEY=your-wandb-key
WANDB_PROJECT=your-project-name

# Optional: Health Check
HEALTH_CHECK_URL=http://healthcheck:8000/ping-receiver
HEALTH_PING_INTERVAL_SECONDS=120  # How often to ping (defaults to 120)

# Optional: Environment & Logging
ENV=development  # Environment name for Weave tracing
LOG_LEVEL=INFO   # Log level (DEBUG, INFO, WARNING, ERROR)

# Optional: Database (defaults to in-memory)
NARRATOR_DB_TYPE=postgresql
NARRATOR_DB_USER=tyler
NARRATOR_DB_PASSWORD=password
NARRATOR_DB_HOST=localhost
NARRATOR_DB_PORT=5432
NARRATOR_DB_NAME=tyler

# Optional: File Storage (defaults to ~/.tyler/files)
NARRATOR_FILE_STORAGE_PATH=/data/files

3. Create Your Agent

import asyncio
from space_monkey import SlackApp, ThreadStore, FileStore, Agent

async def main():
    # Create stores
    thread_store = await ThreadStore.create()  # In-memory by default
    file_store = await FileStore.create()      # Default file storage
    
    # Create your agent
    agent = Agent(
        name="SlackBot",
        model_name="gpt-4.1", 
        purpose="To be a helpful assistant in Slack",
        tools=["web", "files"],
        temperature=0.7
    )
    
    # Start the Slack app
    app = SlackApp(
        agent=agent,
        thread_store=thread_store,
        file_store=file_store
    )
    
    await app.start()

if __name__ == "__main__":
    asyncio.run(main())

That's it! Your Tyler agent is now running as a Slack agent.

Advanced Configuration

Database Storage

For production deployments, use a persistent database:

from space_monkey import ThreadStore, FileStore

# PostgreSQL
thread_store = await ThreadStore.create(
    "postgresql+asyncpg://user:pass@localhost/db"
)

# SQLite
thread_store = await ThreadStore.create(
    "sqlite+aiosqlite:///path/to/db.sqlite"
)

# Custom file storage
file_store = await FileStore.create(
    base_path="/data/files",
    max_file_size=100 * 1024 * 1024,  # 100MB
    max_storage_size=10 * 1024 * 1024 * 1024  # 10GB
)

Custom Agent Configuration

# Create a custom agent with specific tools and settings
agent = Agent(
    name="CustomBot",
    model_name="gpt-4.1",
    purpose="Your custom agent purpose",
    tools=["notion:notion-search", "web", "files"],
    temperature=0.7,
    version="1.0.0"
)

# Tyler Agent with custom settings
agent = Agent(
    name="CustomBot", 
    model_name="gpt-4.1",
    purpose="Your custom agent purpose",
    tools=["notion:notion-search"],
    temperature=0.5
)

App Configuration

app = SlackApp(
    agent=agent,
    thread_store=thread_store,
    file_store=file_store,
    health_check_url="http://healthcheck:8000/ping-receiver",
    weave_project="my-slack-agent"
)

# Start with custom host/port
await app.start(host="0.0.0.0", port=8080)

Message Classification Configuration

Space Monkey includes intelligent message routing that determines when your agent should respond. You can customize what topics your agent should respond to:

# Default configuration (responds to general questions and requests)
app = SlackApp(
    agent=agent,
    thread_store=thread_store,
    file_store=file_store
)

# Custom topic configuration
app = SlackApp(
    agent=agent,
    thread_store=thread_store,
    file_store=file_store,
    response_topics="technical support, troubleshooting, or product questions"
)

# HR/People team configuration
app = SlackApp(
    agent=agent,
    thread_store=thread_store,
    file_store=file_store,
    response_topics="people topics, HR, company culture, recognition, or employee experience"
)

How It Works

Space Monkey acts as the bridge between Slack and Tyler:

  1. SlackApp - Manages the Slack connection and message handling
  2. Tyler Agent - Provides the AI capabilities and tool usage
  3. Narrator Storage - Persists conversations and files
  4. Message Classifier - Intelligently routes messages based on context

The integration is designed to be invisible to users - they simply interact with a helpful AI agent in their Slack workspace.

Message Routing

Tyler Slack Agent automatically handles intelligent message routing:

  1. Direct Messages: All DM messages are processed by your agent
  2. @Mentions: Messages that mention the agent are always processed
  3. Channel Messages: Automatically classified to determine if they need a response
  4. Thread Replies: Continues conversations in threads appropriately
  5. Reactions: Simple acknowledgments get emoji reactions instead of text responses

This happens automatically - you just define your agent's behavior and Space Monkey handles the rest.

Storage Backends

Thread Storage

  • In-Memory: Fast, ephemeral (default for development)
  • SQLite: Local persistence (good for single-instance deployments)
  • PostgreSQL: Production-ready with full ACID compliance

File Storage

  • Local File System: Sharded directory structure for efficient file organization
  • Configurable Limits: Set maximum file sizes and total storage limits
  • MIME Type Validation: Automatic file type detection and validation

Production Deployment

Docker

Space Monkey includes Docker support for easy deployment. A production-ready Dockerfile and docker-compose.yml are included in the package.

Quick Start with Docker

# Build the image
docker build -t my-slack-agent .

# Run with environment variables
docker run -d \
  --name slack-agent \
  -p 8000:8000 \
  -e SLACK_BOT_TOKEN=$SLACK_BOT_TOKEN \
  -e SLACK_APP_TOKEN=$SLACK_APP_TOKEN \
  -e OPENAI_API_KEY=$OPENAI_API_KEY \
  my-slack-agent

Using Docker Compose

# Copy environment template
cp env.example .env
# Edit .env with your credentials

# Start the agent
docker-compose up -d

# View logs
docker-compose logs -f slack-agent

# Stop
docker-compose down

Production Deployment

The included Dockerfile follows best practices:

  • Non-root user for security
  • Health checks for monitoring
  • Proper signal handling for graceful shutdown
  • Multi-stage build for smaller images
  • Layer caching for faster builds

Environment Configuration

# Production .env
SLACK_BOT_TOKEN=xoxb-prod-token
SLACK_APP_TOKEN=xapp-prod-token

# LLM Configuration (choose one or more)
OPENAI_API_KEY=sk-prod-openai-key
# ANTHROPIC_API_KEY=sk-ant-prod-key
# GEMINI_API_KEY=prod-gemini-api-key
# XAI_API_KEY=xai-prod-grok-key

# Database
NARRATOR_DB_TYPE=postgresql
NARRATOR_DB_USER=tyler_prod
NARRATOR_DB_PASSWORD=secure_password
NARRATOR_DB_HOST=db.example.com
NARRATOR_DB_PORT=5432
NARRATOR_DB_NAME=tyler_prod

# File Storage
NARRATOR_FILE_STORAGE_PATH=/data/files

# Monitoring
WANDB_API_KEY=prod-wandb-key
WANDB_PROJECT=slack-agent-prod
HEALTH_CHECK_URL=http://healthcheck:8000/ping-receiver
HEALTH_PING_INTERVAL_SECONDS=120

# Environment & Logging
ENV=production
LOG_LEVEL=INFO

Health Monitoring

The agent includes built-in health check endpoints and optional external health monitoring:

app = SlackApp(
    agent=agent,
    thread_store=thread_store,
    file_store=file_store,
    health_check_url="http://healthcheck:8000/ping-receiver"
)

API Reference

SlackApp

class SlackApp:
    def __init__(
        self,
        agent: Agent,
        thread_store: ThreadStore,
        file_store: FileStore,
        health_check_url: Optional[str] = None,
        weave_project: Optional[str] = None,
        response_topics: Optional[str] = None
    ):
        """
        Initialize Slack app with agent and stores.
        
        Args:
            agent: The main Tyler agent to handle conversations
            thread_store: ThreadStore instance for conversation persistence  
            file_store: FileStore instance for file handling
            health_check_url: Optional URL for health check pings
            weave_project: Optional Weave project name for tracing
            response_topics: Simple sentence describing what topics the agent should respond to
        """
        
    async def start(
        self,
        host: str = "0.0.0.0",
        port: int = 8000
    ) -> None:
        """Start the Slack agent app."""

Classifier Configuration

def format_classifier_prompt(
    agent_name: str = "Assistant",
    bot_user_id: str = "",
    response_topics: str = "general questions, requests for help, or inquiries directed at the assistant"
) -> str:
    """Format the classifier prompt with custom configuration."""

Agent

class Agent:
    def __init__(
        self,
        name: str,
        model_name: str,
        purpose: str,
        tools: Optional[List[str]] = None,
        temperature: Optional[float] = None,
        version: str = "1.0.0",
        thread_store: Optional[ThreadStore] = None,
        file_store: Optional[FileStore] = None
    ):
        """Create a Tyler agent with full configuration options."""

Stores

# ThreadStore
thread_store = await ThreadStore.create()  # In-memory
thread_store = await ThreadStore.create(database_url)  # Database

# FileStore  
file_store = await FileStore.create()  # Default settings
file_store = await FileStore.create(
    base_path="/path/to/files",
    max_file_size=100 * 1024 * 1024,
    max_storage_size=10 * 1024 * 1024 * 1024
)

Examples

Simple HR Agent

import asyncio
from space_monkey import SlackApp, Agent, ThreadStore, FileStore

async def main():
    # Simple setup for an HR assistant with HR-specific topic classification
    thread_store = await ThreadStore.create()
    file_store = await FileStore.create()
    
    agent = Agent(
        name="HRBot",
        model_name="gpt-4.1",
        purpose="To help with HR and people team questions",
        tools=["notion:notion-search"],
        temperature=0.7
    )
    
    app = SlackApp(
        agent=agent,
        thread_store=thread_store,
        file_store=file_store,
        response_topics="people topics, HR, company culture, recognition, or employee experience"
    )
    
    await app.start()

asyncio.run(main())

Technical Support Agent

import asyncio
from space_monkey import SlackApp, Agent, ThreadStore, FileStore

async def main():
    # Technical support agent with custom topic classification
    thread_store = await ThreadStore.create()
    file_store = await FileStore.create()
    
    agent = Agent(
        name="TechSupport",
        model_name="gpt-4.1",
        purpose="To help users with technical support and troubleshooting",
        tools=["web", "files"],
        temperature=0.3
    )
    
    app = SlackApp(
        agent=agent,
        thread_store=thread_store,
        file_store=file_store,
        response_topics="technical issues, bugs, troubleshooting, or product support"
    )
    
    await app.start()

asyncio.run(main())

Custom Agent with Database

import asyncio
from space_monkey import SlackApp, Agent, ThreadStore, FileStore

async def main():
    # Production setup with PostgreSQL
    thread_store = await ThreadStore.create(
        "postgresql+asyncpg://user:pass@localhost/db"
    )
    file_store = await FileStore.create(base_path="/data/files")
    
    # Custom agent
    agent = Agent(
        name="SupportBot",
        model_name="gpt-4.1",
        purpose="Help users with technical support questions",
        tools=["web", "files"],
        temperature=0.3
    )
    
    app = SlackApp(
        agent=agent,
        thread_store=thread_store,
        file_store=file_store,
        weave_project="support-agent"
    )
    
    await app.start(port=8080)

asyncio.run(main())

Use Cases

  • HR/People Bots: Answer employee questions using Notion as a knowledge base
  • Technical Support: Help users troubleshoot issues with web search and file analysis
  • Team Assistants: Automate routine tasks and answer common questions
  • Custom Workflows: Build any conversational AI use case with Tyler's full capabilities

Contributing

Space Monkey is part of the Slide ecosystem. See the main repository for contribution guidelines.

License

MIT License - see LICENSE file for details.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

slide_space_monkey-5.2.0.tar.gz (19.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

slide_space_monkey-5.2.0-py3-none-any.whl (18.2 kB view details)

Uploaded Python 3

File details

Details for the file slide_space_monkey-5.2.0.tar.gz.

File metadata

  • Download URL: slide_space_monkey-5.2.0.tar.gz
  • Upload date:
  • Size: 19.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: python-httpx/0.28.1

File hashes

Hashes for slide_space_monkey-5.2.0.tar.gz
Algorithm Hash digest
SHA256 9c95f2c48825526b13b43a05bf70dd55e895356779def8e190e21aa18f65721e
MD5 442c5153f6a5eb6689122f9754bd4f8a
BLAKE2b-256 1b37e2bbe934d7975abdad803ca9c392b55d5274e50cd06d3c7c5862cb6ff5cb

See more details on using hashes here.

File details

Details for the file slide_space_monkey-5.2.0-py3-none-any.whl.

File metadata

File hashes

Hashes for slide_space_monkey-5.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 110109c766733dc7b619f7b2fa190e5f41907cd64daf66f73901d3bcad398718
MD5 771b93838336e181f78475402416e1c4
BLAKE2b-256 9595bdddaf66128e28c596c7d263b16d5a1ae104a7153904cb5120773142c016

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page