Skip to content

Architecture ​

System Overview ​

App ──▶ LLM Interceptor ──▶ Provider (Anthropic / OpenAI)
              │
        Plugin Pipeline
              │
     ┌────────┴────────┐
     │                 │
  Storage           State
  (SQLite/PG)    (Memory/Redis)

Plugin Lifecycle ​

PhaseOrderDescription
OnRequestOTel → ToolPolicy → RateLimit → Budget → CostTrackerRun in registration order; any plugin can block
ForwardN/ARequest sent to upstream; response captured
OnResponseCostTracker → Budget → RateLimit → ToolPolicy → OTelRun in reverse order

CostTracker must be last in registration order (first in reverse) so it writes cost data before Budget reads it on the next request.

Key Interfaces ​

Plugin ​

go
type Plugin interface {
    Name() string
    OnRequest(ctx *RequestContext) (*HookResult, error)
    OnResponse(ctx *ResponseContext) error
}

Storage.Backend ​

go
type Backend interface {
    SaveRequest(ctx context.Context, req *types.StoredRequest) error
    QueryRequests(ctx context.Context, filter types.RequestFilter) ([]types.StoredRequest, error)
    // ... SaveAPIKey, SaveConfig, SaveAuditEntry, etc.
    Close() error
}

State.Backend ​

go
type Backend interface {
    Increment(ctx context.Context, key string, delta int64) (int64, error)
    Get(ctx context.Context, key string) (int64, error)
    Reset(ctx context.Context, key string) error
    Close() error
}

Design Principles ​

  • Forward path never blocked: OTel export, state updates, and metrics collection are async
  • Metadata map: RequestContext.Metadata is the inter-plugin communication channel
  • Interface-abstracted: Storage and State backends are swappable at config time
  • Dual mode: Passthrough (default) vs Router (managed keys)

Released under the MIT License.