๐Ÿ“‹ Plugin Overview

Bifrost plugins provide middleware functionality:
  • Request/response processing and modification
  • Authentication and authorization controls
  • Rate limiting and traffic shaping
  • Monitoring and metrics collection
  • Custom business logic injection

Current Plugin Loading (Command-line)

Go Binary:
bifrost-http -config config.json -plugins "maxim,custom-plugin"
Docker:
docker run -p 8080:8080 \
  -v $(pwd)/config.json:/app/config/config.json \
  -e OPENAI_API_KEY \
  -e APP_PLUGINS=maxim,custom-plugin \
  maximhq/bifrost

๐Ÿ”ง Available Plugins

Maxim Logger Plugin

Official logging and analytics plugin:
# Environment variables required
export MAXIM_API_KEY="your-maxim-api-key"
export MAXIM_LOG_REPO_ID="your-repo-id"

# Start with Maxim plugin
bifrost-http -config config.json -plugins "maxim"
Features:
  • Request/response logging to Maxim platform
  • Performance analytics and insights
  • Error tracking and debugging
  • Usage pattern analysis

Prometheus Metrics Plugin

Built-in metrics collection (always loaded):
# Access metrics
curl http://localhost:8080/metrics
Metrics provided:
  • Request count and latency
  • Provider performance
  • Error rates and types
  • Resource utilization

๐Ÿ› ๏ธ Custom Plugin Development

Plugin Interface

Plugins implement the schemas.Plugin interface:
type Plugin interface {
    Name() string
    ProcessRequest(ctx BifrostContext, req *BifrostRequest) (*BifrostRequest, *BifrostError)
    ProcessResponse(ctx BifrostContext, req *BifrostRequest, resp *BifrostResponse) (*BifrostResponse, *BifrostError)
}

Example Plugin Structure

package myplugin

import (
    "github.com/maximhq/bifrost/core/schemas"
)

type MyPlugin struct {
    config MyPluginConfig
}

func NewMyPlugin(config MyPluginConfig) *MyPlugin {
    return &MyPlugin{config: config}
}

func (p *MyPlugin) Name() string {
    return "my-plugin"
}

func (p *MyPlugin) ProcessRequest(
    ctx schemas.BifrostContext,
    req *schemas.BifrostRequest,
) (*schemas.BifrostRequest, *schemas.BifrostError) {
    // Process incoming request
    // Add headers, validate, modify, etc.
    return req, nil
}

func (p *MyPlugin) ProcessResponse(
    ctx schemas.BifrostContext,
    req *schemas.BifrostRequest,
    resp *schemas.BifrostResponse,
) (*schemas.BifrostResponse, *schemas.BifrostError) {
    // Process outgoing response
    // Log, transform, add metadata, etc.
    return resp, nil
}

๐Ÿ“‹ Plugin Use Cases

Authentication Plugin

func (p *AuthPlugin) ProcessRequest(
    ctx schemas.BifrostContext,
    req *schemas.BifrostRequest,
) (*schemas.BifrostRequest, *schemas.BifrostError) {
    // Extract API key from headers
    apiKey := ctx.GetHeader("X-API-Key")

    // Validate against database/service
    if !p.validateAPIKey(apiKey) {
        return nil, &schemas.BifrostError{
            Message: "Invalid API key",
            StatusCode: &[]int{401}[0],
        }
    }

    return req, nil
}

Rate Limiting Plugin

func (p *RateLimitPlugin) ProcessRequest(
    ctx schemas.BifrostContext,
    req *schemas.BifrostRequest,
) (*schemas.BifrostRequest, *schemas.BifrostError) {
    clientIP := ctx.GetClientIP()

    if !p.limiter.Allow(clientIP) {
        return nil, &schemas.BifrostError{
            Message: "Rate limit exceeded",
            StatusCode: &[]int{429}[0],
        }
    }

    return req, nil
}

Request Transformation Plugin

func (p *TransformPlugin) ProcessRequest(
    ctx schemas.BifrostContext,
    req *schemas.BifrostRequest,
) (*schemas.BifrostRequest, *schemas.BifrostError) {
    // Add organization context to messages
    if req.Input.ChatCompletionInput != nil {
        messages := *req.Input.ChatCompletionInput

        // Add system message with org context
        orgContext := schemas.BifrostMessage{
            Role: "system",
            Content: schemas.MessageContent{
                Text: p.getOrganizationContext(ctx),
            },
        }

        messages = append([]schemas.BifrostMessage{orgContext}, messages...)
        req.Input.ChatCompletionInput = &messages
    }

    return req, nil
}

๐Ÿ”ฎ Future JSON Configuration

Planned configuration format (under development):
{
  "providers": {
    "openai": {
      "keys": [
        {
          "value": "env.OPENAI_API_KEY",
          "models": ["gpt-4o-mini"],
          "weight": 1.0
        }
      ]
    }
  },
  "plugins": [
    {
      "name": "maxim",
      "source": "../../plugins/maxim",
      "type": "local",
      "config": {
        "api_key": "env.MAXIM_API_KEY",
        "log_repo_id": "env.MAXIM_LOG_REPO_ID"
      }
    },
    {
      "name": "mocker",
      "source": "../../plugins/mocker",
      "type": "local",
      "config": {
        "enabled": true,
        "default_behavior": "passthrough",
        "rules": [
          {
            "name": "test-mock",
            "enabled": true,
            "priority": 1,
            "probability": 1,
            "conditions": {
              "providers": ["openai"]
            },
            "responses": [
              {
                "type": "success",
                "weight": 1.0,
                "content": {
                  "message": "This is a mock response for testing"
                }
              }
            ]
          }
        ]
      }
    }
  ]
}

๐Ÿงช Testing Custom Plugins

Unit Testing

func TestMyPlugin(t *testing.T) {
    plugin := NewMyPlugin(MyPluginConfig{})

    ctx := &schemas.BifrostContext{}
    req := &schemas.BifrostRequest{
        Provider: "openai",
        Model: "gpt-4o-mini",
    }

    processedReq, err := plugin.ProcessRequest(ctx, req)

    assert.Nil(t, err)
    assert.NotNil(t, processedReq)
    // Add your assertions
}

Integration Testing

# Build plugin
go build -buildmode=plugin -o myplugin.so ./plugins/myplugin

# Test with HTTP transport
bifrost-http -config config.json -plugins "myplugin"

# Send test request
curl -X POST http://localhost:8080/v1/chat/completions \
  -H "Content-Type: application/json" \
  -H "X-Test-Header: test-value" \
  -d '{
    "provider": "openai",
    "model": "gpt-4o-mini",
    "messages": [{"role": "user", "content": "test"}]
  }'

๐Ÿ”ง Plugin Execution Order

Plugins execute in loading order:
# This order: auth -> rate-limit -> maxim -> request
bifrost-http -plugins "auth,rate-limit,maxim"
Request flow:
  1. auth.ProcessRequest()
  2. rate-limit.ProcessRequest()
  3. maxim.ProcessRequest()
  4. Provider request
  5. maxim.ProcessResponse()
  6. rate-limit.ProcessResponse()
  7. auth.ProcessResponse()
Architecture: For plugin system design and performance details, see Architecture Documentation. Development: Full plugin development guide and examples available in Go Package Plugins.