Availability
| Edition | Deployment Type |
|---|---|
| Community & Enterprise | Self-Managed, Hybrid |
Unified SDK Overview
The Unified SDK (pkg/plugin_sdk) is the modern, recommended approach for all plugin development. It provides:
- Single Import: One SDK works in both AI Studio and Edge Gateway
- Automatic Runtime Detection: SDK detects the execution environment
- Capability-Based Design: Implement only what you need
- Type-Safe: Clean Go types, no manual proto handling
- Service Access: Built-in KV storage, logging, events, and management APIs
- Context-Rich: Access to app, user, LLM metadata in every call
Installation
Basic Plugin Structure
Expandable
Plugin Capabilities
Plugins implement one or more capability interfaces. The SDK supports 15 distinct capabilities:| Capability | Interface | Where It Works | Purpose |
|---|---|---|---|
| Pre-Auth | PreAuthHandler | Studio + Gateway | Process requests before authentication |
| Auth | AuthHandler | Studio + Gateway | Custom authentication with credential lookup |
| Post-Auth | PostAuthHandler | Studio + Gateway | Process requests after authentication (most common) |
| Response | ResponseHandler | Studio + Gateway | Modify response headers and body |
| Data Collection | DataCollector | Studio + Gateway | Collect telemetry (analytics, budgets, proxy logs) |
| Custom Endpoints | CustomEndpointHandler | Gateway | Serve custom HTTP endpoints under /plugins/{slug}/ |
| UI Provider | UIProvider | Studio only | Serve admin web UI assets |
| Portal UI | PortalUIProvider | Studio only | Portal-facing pages and forms with user context |
| Config Provider | ConfigProvider | Studio + Gateway | Provide JSON Schema configuration |
| Manifest Provider | ManifestProvider | Gateway only | Provide plugin manifest (gateway-only plugins) |
| Agent | AgentPlugin | Studio only | Conversational AI agent with streaming |
| Object Hooks | ObjectHookHandler | Studio only | Intercept CRUD operations on objects |
| Scheduler | SchedulerPlugin | Studio only | Execute tasks on cron-based schedules |
| Edge Payload | EdgePayloadReceiver | Studio only | Receive data from edge (gateway) plugins |
| Resource Provider | ResourceProvider | Studio only | Register custom resource types for Apps with privacy scoring |
Multi-Capability Plugins
A single plugin can implement multiple capabilities. For example, a rate limiter might implement:PostAuthHandler- Check limits before requestResponseHandler- Update counters after responseUIProvider- Provide management UI
Expandable
Core Interfaces
1. PreAuthHandler
Process requests before authentication. Useful for IP filtering, request validation, etc.2. AuthHandler
Custom authentication with credential lookup. This interface requires three methods to fully integrate with the access control system.Why App Linking Is Critical
A valid credential alone is not enough. The system requires an associated App object because Apps provide the access control context:- Policy enforcement - Rate limits, usage quotas, and restrictions
- Tool/Datasource permissions - Which tools and datasources the credential can access
- LLM restrictions - Which LLMs the credential is allowed to use
- Budget controls - Cost tracking and spending limits
Authentication Flow
HandleAuth()- Validates the credential and returns an App ID and User IDGetAppByCredential()- System calls this to fetch the full App object for access controlGetUserByCredential()- System calls this to fetch the User object for identity context
Example Implementation
Expandable
Common Pitfalls
| Pitfall | Symptom | Solution |
|---|---|---|
| Not returning App ID | Requests fail with “no app context” | Always return a valid AppId in AuthResponse |
| App doesn’t exist | 500 errors after auth success | Verify App exists in database before returning its ID |
Not implementing GetAppByCredential | Compile error or runtime panic | Implement all three interface methods |
| Using wrong App ID | Permission denied for tools/LLMs | Ensure the App has the required permissions configured |
examples/plugins/studio/custom-auth-ui/ for a complete implementation.
3. PostAuthHandler
Process requests after authentication. Most common capability for request enrichment, policy enforcement, etc.Expandable
4. ResponseHandler
Modify response headers and body. Two methods allow phased processing:Expandable
5. DataCollector
Collect telemetry data (analytics, budgets, proxy logs).Expandable
6. AgentPlugin
Conversational AI agent with streaming support. See Agent Plugins Guide for details.7. ObjectHookHandler
Intercept CRUD operations on AI Studio objects (LLMs, Datasources, Tools, Users). See Object Hooks Guide for complete details.8. UIProvider
Serve web UI assets for AI Studio plugins. See UI Plugins Guide for details.9. ConfigProvider
Provide JSON Schema for plugin configuration.Expandable
10. ManifestProvider
Provide plugin manifest for gateway-only plugins (no UI).11. SchedulerPlugin
Execute tasks on cron-based schedules.12. EdgePayloadReceiver
Receive data from edge (Edge Gateway) plugins. This enables the hub-and-spoke communication pattern where edge plugins can send data back to the control plane. See Edge-to-Control Communication for complete details.Expandable
Context and Services
Every handler receives aContext that provides access to runtime information and services.
Context Fields
Runtime Detection
Plugins can adapt behavior based on runtime:Service Broker
The context provides access to services throughctx.Services:
Universal Services (Both Runtimes)
KV Storage:- Studio: PostgreSQL-backed, shared across hosts, durable
- Gateway: Local database, per-instance, ephemeral
Expandable
- Events enable real-time communication between plugins and across the hub-spoke architecture
- Direction controls routing:
DirLocal(stays local),DirUp(edge→control),DirDown(control→edge) - See Service API Reference for complete documentation
Runtime-Specific Services
Gateway Services (ctx.Services.Gateway()):
Expandable
ctx.Services.Studio()):
Expandable
Initialization Pattern
Plugins should extract the service broker ID during initialization for Service API access:Expandable
BasePlugin Convenience Struct
The SDK providesBasePlugin to reduce boilerplate:
Expandable
BasePlugin provides default implementations for common methods, which you can override as needed.
Error Handling
Blocking Requests
Return a response withBlock: true:
Non-Blocking Errors
Log the error and continue:Agent Errors
Send ERROR chunks for streaming agents:Complete Example: Multi-Capability Plugin
Expandable
Testing Plugins
Unit Testing
Expandable
Integration Testing
See working examples inexamples/plugins/ for integration test patterns.
Best Practices
Configuration
- Validate configuration in
Initialize() - Extract broker ID for Service API access
- Set sensible defaults
- Return errors for invalid config
Service API Usage
- Always check runtime before calling runtime-specific services
- Use context timeouts for external calls
- Cache frequently accessed data in KV storage
- Handle service errors gracefully
- Use Events for cross-plugin and edge-to-control communication
- Unsubscribe from events in
Shutdown()to prevent leaks
Performance
- Minimize Service API calls in request path
- Use KV storage for caching
- Avoid blocking operations in handlers
- Use goroutines for async work (clean up in Shutdown)
Resource Management
- Clean up resources in
Shutdown()method - Close connections and file handles
- Cancel background goroutines
- Clear caches
Security
- Validate all inputs
- Sanitize log output (no secrets)
- Use secure defaults
- Follow least privilege principle
Session-Based Broker Pattern
Plugins running in AI Studio use a session-based broker pattern for Service API access. Understanding this pattern is critical for plugins that need to call host APIs (likeai_studio_sdk.CreateLLM(), ai_studio_sdk.ListApps(), etc.).
How It Works
- Plugin loads: The host creates a long-lived gRPC broker connection
- Session opens: The host calls
OpenSessionon the plugin, providing the broker ID - OnSessionReady callback: For plugins implementing
SessionAware, this signals the broker is ready - Service API available: The plugin can now dial the broker and call host APIs
The SessionAware Interface
Plugins that need early access to Service APIs should implementSessionAware:
Connection Warmup Pattern (Critical!)
Important: The go-plugin broker only accepts ONE connection per broker ID. If your plugin uses both the Event Service and the Management Service API, whichever dials first will succeed, and the connection must be shared. The SDK handles this automatically, but you should warm up the connection early inOnSessionReady to ensure it’s established before any RPC calls come in:
Expandable
Why Warmup Is Important
Without warmup, you may encounter “timeout waiting for connection info” errors when your plugin tries to use the Service API during an RPC call. This happens because:- The broker connection is time-sensitive
- Dialing late (during RPC) may fail if the broker has timed out
- Event subscriptions and Service API calls share the same connection
Complete Example: Plugin with Service API and Events
Expandable
Troubleshooting Connection Issues
Error: “timeout waiting for connection info”- Plugin is trying to dial the broker too late
- Solution: Implement
SessionAwareand warm up the connection inOnSessionReady
- The broker ID wasn’t extracted from config
- Solution: The SDK handles this automatically via
OpenSession, but verify your plugin isn’t overriding the broker setup
ai_studio_sdk.Initialize()wasn’t called or failed- Solution: Check logs for initialization errors during plugin startup