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-4.1.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-4.1.0-py3-none-any.whl (18.2 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: slide_space_monkey-4.1.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-4.1.0.tar.gz
Algorithm Hash digest
SHA256 c7fd43bf34f67b5a9e30725024cd34608160e8e5e740ff15657fbac73731b56a
MD5 f6ead2ec0a7c22f35276570d7b33c3ec
BLAKE2b-256 a87eb0fa9c2021807ffbb0d8194888710aeb761ee2317ea6159a87f3a2a34733

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for slide_space_monkey-4.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 b7e5071881863187727690967ca732a736c3a0b27778251996da756e87652fb3
MD5 8022b166b68bf729c76068b4d51948a2
BLAKE2b-256 fbad929a4e683b426d08df1868e507516b8aedab7fd82dee9181219d7aa4441a

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