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 with just a few lines of code.

Overview

Space Monkey provides a clean, class-based API for creating and deploying Tyler agents as Slack agents. It handles all the complexity of Slack integration, message routing, thread management, and storage while exposing a simple interface for agent configuration.

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

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"
)

Agent Configuration

Space Monkey uses Tyler Agent directly, giving you full access to all Tyler's capabilities:

agent = Agent(
    name="MyBot",             # Agent name
    model_name="gpt-4.1",     # Model to use
    purpose="Your agent's purpose and instructions",
    tools=["web", "files"],   # Available tools
    temperature=0.7,          # Model temperature
    version="1.0.0"           # Agent version
)

You can configure agents for any use case by adjusting the purpose and tools:

  • HR/People assistance with Notion integration
  • Customer support with web search
  • Technical assistance with file processing
  • And any other conversational AI use case

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())

Contributing

Tyler Slack Agent is part of the Tyler ecosystem. See the main Tyler documentation for information about contributing to the project.

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-0.2.0.tar.gz (19.0 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-0.2.0-py3-none-any.whl (18.1 kB view details)

Uploaded Python 3

File details

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

File metadata

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

File hashes

Hashes for slide_space_monkey-0.2.0.tar.gz
Algorithm Hash digest
SHA256 4ba0cb90137d55126e28ec98981bde48961712ababa770d9ab037fac87446894
MD5 13aa1f236ef2d716fb56545061f20def
BLAKE2b-256 35087045f054121f6c222de7d8378b9c2bb1552d1e0d07e3e1ad8b5346ec3613

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for slide_space_monkey-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 5f4c9aa6f5c0a7e647e99862d72ad038bbeed512abe179ab2706c4331f382fcb
MD5 d76a349bb54153840867cde172d5ea04
BLAKE2b-256 bcb18688d34cb2c6db617250fa3708eb6b69496a20aa02693d8386b10309bf35

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