Skip to content

pbdeuchler/agentcontainers-proxy

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

AgentContainers Proxy

A flexible proxy service that bridges Slack conversations with pluggable agentic systems, providing a seamless interface for users to interact with AI agents through Slack.

Overview

This service acts as a middleware layer between Slack and various AI agent backends (AWS Lambda, Docker containers). It receives Slack webhooks, fetches user configuration from a bootstrap server, forwards messages to the appropriate agent backend, and maintains session continuity across Slack threads.

Features

  • Multi-Backend Support: Run agents via AWS Lambda or Docker containers
  • Session Persistence: Maintains conversation context across Slack threads
  • Dual Deployment Modes: Deploy as HTTP server or AWS Lambda function
  • Async Processing: Non-blocking message handling for responsive Slack interactions
  • User Configuration: Dynamic user config fetching from bootstrap server
  • Error Handling: Graceful error reporting back to Slack users

Architecture

Components

  • Slack Handler: Processes incoming Slack webhooks and events
  • Bootstrap Client: Fetches user-specific agent configurations
  • Agent Clients: Interfaces with different agent backends (Lambda/Docker)
  • Session Manager: PostgreSQL-based thread-to-session mapping
  • Service Layer: Orchestrates the flow between components

Deployment Modes

  1. HTTP Server Mode: Standalone server receiving Slack webhooks
  2. Lambda Function Mode: Serverless deployment with API Gateway integration
  3. Docker Agent Mode: Local Docker container execution for development

Installation

Prerequisites

  • Go 1.24.3 or higher
  • PostgreSQL database
  • Slack App with Events API configured
  • AWS credentials (for Lambda mode)
  • Docker (for Docker agent mode)

Setup

  1. Clone the repository:
git clone https://github.com/pbdeuchler/agentcontainers-proxy
cd agentcontainers-proxy
  1. Install dependencies:
go mod download
  1. Set up the database:
# Run migrations using goose
goose -dir migrations postgres "$DATABASE_URL" up
  1. Configure environment variables (see Configuration section)

Configuration

Environment Variables

Variable Description Required Default
DATABASE_URL PostgreSQL connection string Yes -
BOOTSTRAP_SERVER_URL Bootstrap server endpoint for user configs Yes -
AGENT_LAMBDA_ARN ARN of the Claude Code Lambda function Conditional* -
DOCKER_IMAGE_NAME Docker image for agent execution Conditional* -
SLACK_BOT_TOKEN Slack Bot OAuth token Yes -
SLACK_BOT_USER_ID Slack bot's user ID (to ignore self-messages) No -
SLACK_SIGNING_SECRET Slack app signing secret No -
PORT HTTP server port No 2010
ANTHROPIC_API_KEY API key for Claude (Docker mode) Conditional** -

*Either AGENT_LAMBDA_ARN or DOCKER_IMAGE_NAME must be set **Required when using Docker agent mode

Example Configuration

Copy .env.example to .env and update with your values:

cp .env.example .env
# Edit .env with your configuration

Usage

Running the HTTP Server

# Using go run
go run main.go

# Or build and run
go build -o agentcontainers-proxy
./agentcontainers-proxy

Lambda Deployment

The service automatically detects Lambda environment:

  1. Build for Lambda:
GOOS=linux GOARCH=amd64 go build -o bootstrap main.go
zip function.zip bootstrap
  1. Deploy to AWS Lambda with appropriate environment variables

Docker Agent Mode

To use Docker containers as the agent backend:

export DOCKER_IMAGE_NAME="your-agent-image:tag"
export ANTHROPIC_API_KEY="your-api-key"
go run main.go

API Flow

sequenceDiagram
    participant Slack
    participant Proxy
    participant Bootstrap
    participant Database
    participant Agent

    Slack->>Proxy: POST /slack/webhook
    Proxy->>Bootstrap: GET ?slack_id={user_id}
    Bootstrap-->>Proxy: User config
    Proxy->>Database: Check thread_id mapping
    Database-->>Proxy: session_id (if exists)
    Proxy->>Agent: Invoke with prompt + session
    Agent-->>Proxy: Response + session_id
    Proxy->>Database: Store session mapping
    Proxy->>Slack: Post reply to thread
    Proxy-->>Slack: 200 OK
Loading

Project Structure

agentcontainers-proxy/
├── agentclients/         # Agent backend interfaces
│   ├── docker/          # Docker container client
│   ├── lambda/          # AWS Lambda client
│   └── types.go         # Shared types
├── bootstrap/           # Bootstrap server client
├── cmd/                 # Application entry points
│   ├── common.go       # Shared initialization
│   ├── config.go       # Configuration management
│   ├── lambda.go       # Lambda handler
│   └── server.go       # HTTP server
├── dao/                 # Database access layer
├── migrations/          # Database migrations
├── service/            # Business logic layer
├── slack/              # Slack integration
│   ├── client.go       # Slack API client
│   └── handler.go      # Webhook handler
└── main.go             # Main entry point

Database Schema

The service uses PostgreSQL to maintain session continuity:

CREATE TABLE session_mappings (
    id SERIAL PRIMARY KEY,
    thread_id VARCHAR(255) UNIQUE NOT NULL,
    session_id VARCHAR(255) NOT NULL,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

CREATE INDEX idx_thread_id ON session_mappings(thread_id);

Slack App Configuration

  1. Create a new Slack App at https://api.slack.com/apps
  2. Enable Event Subscriptions
  3. Add Bot Token Scopes:
    • chat:write
    • app_mentions:read
    • messages.channels
    • messages.groups
    • messages.im
    • messages.mpim
  4. Subscribe to bot events:
    • message.channels
    • message.groups
    • message.im
    • message.mpim
  5. Set Request URL to your proxy endpoint:
    • HTTP Server: https://your-domain.com/slack/webhook
    • Lambda: Your API Gateway URL

Bootstrap Server Protocol

The bootstrap server must implement the following endpoint:

GET /bootstrap?slack_id={slack_user_id}

Response format:

{
    "user": {...},
    "prompt": "Initial system prompt",
    "append_system_prompt": "Additional context",
    "allowed_tools": ["tool1", "tool2"],
    "disallowed_tools": ["tool3"],
    "env": {...}
}

Agent Request/Response Format

Request (AgentRequest)

{
    "user": {...},
    "prompt": "User message with context",
    "append_system_prompt": "Additional instructions",
    "allowed_tools": ["Read", "Write"],
    "disallowed_tools": ["Delete"],
    "env": {...},
    "resume_session_id": "previous-session-id"
}

Response (AgentResponse)

{
  "type": "result",
  "subtype": "success",
  "is_error": false,
  "result": "Agent response text",
  "session_id": "new-or-continued-session-id"
}

Development

Running Tests

go test ./...

Building

# Local build
go build -o agentcontainers-proxy

# Linux build for Lambda
GOOS=linux GOARCH=amd64 go build -o bootstrap

Debugging

Enable verbose logging by setting:

export DEBUG=true

Monitoring

The service logs important events including:

  • Incoming Slack messages
  • Bootstrap server calls
  • Agent invocations
  • Database operations
  • Error conditions

Security Considerations

  • Store sensitive environment variables securely
  • Use HTTPS for all external communications
  • Validate Slack requests using signing secret
  • Implement rate limiting for production deployments
  • Regularly rotate API keys and tokens
  • Use least-privilege IAM roles for Lambda execution

Troubleshooting

Common Issues

  1. Database Connection Errors: Verify DATABASE_URL format and network access
  2. Slack Not Responding: Check bot token permissions and webhook URL
  3. Agent Timeout: Increase Lambda timeout or check Docker resource limits
  4. Bootstrap Server Errors: Verify server URL and authentication
  5. Session Continuity Loss: Check database connectivity and migrations

Debug Commands

# Test database connection
psql "$DATABASE_URL" -c "SELECT 1"

# Verify Slack token
curl -H "Authorization: Bearer $SLACK_BOT_TOKEN" https://slack.com/api/auth.test

# Check Lambda function
aws lambda get-function --function-name $AGENT_LAMBDA_ARN

Contributing

  1. Fork the repository
  2. Create a feature branch
  3. Commit your changes
  4. Push to the branch
  5. Create a Pull Request

License

This project is licensed under the GNU GPLv3 License with the Commons Clause License Condition v1.0.

Support

For issues and questions, please open an issue on GitHub.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages