Mocker
Quick Start
Section titled “Quick Start”Minimal Configuration
Section titled “Minimal Configuration”The simplest way to use the Mocker plugin is with no configuration - it will create a default catch-all rule:
package main
import ( "context" deepintshield "github.com/maximhq/deepintshield/core" "github.com/maximhq/deepintshield/core/schemas" mocker "github.com/maximhq/deepintshield/plugins/mocker")
func main() { // Create plugin with minimal config plugin, err := mocker.NewMockerPlugin(mocker.MockerConfig{ Enabled: true, // Default rule will be created automatically }) if err != nil { panic(err) }
// Initialize DeepIntShield with the plugin client, initErr := deepintshield.Init(context.Background(), schemas.DeepIntShieldConfig{ Account: &yourAccount, LLMPlugins: []schemas.LLMPlugin{plugin}, }) if err != nil { panic(err) } defer client.Shutdown()
// All chat and responses requests will now return: "This is a mock response from the Mocker plugin"
// Chat completion request chatResponse, _ := client.ChatCompletionRequest(schemas.NewDeepIntShieldContext(context.Background(), schemas.NoDeadline), &schemas.DeepIntShieldChatRequest{ Provider: schemas.OpenAI, Model: "gpt-4", Input: []schemas.ChatMessage{ { Role: schemas.ChatMessageRoleUser, Content: schemas.ChatMessageContent{ ContentStr: deepintshield.Ptr("Hello!"), }, }, }, })
// Responses request responsesResponse, _ := client.ResponsesRequest(schemas.NewDeepIntShieldContext(context.Background(), schemas.NoDeadline), &schemas.DeepIntShieldResponsesRequest{ Provider: schemas.OpenAI, Model: "gpt-4o", Input: []schemas.ResponsesMessage{ { Role: deepintshield.Ptr(schemas.ResponsesInputMessageRoleUser), Content: &schemas.ResponsesMessageContent{ ContentStr: deepintshield.Ptr("Hello!"), }, }, }, })}Custom Response
Section titled “Custom Response”plugin, err := mocker.NewMockerPlugin(mocker.MockerConfig{ Enabled: true, Rules: []mocker.MockRule{ { Name: "openai-mock", Enabled: true, Probability: 1.0, // Always trigger Conditions: mocker.Conditions{ Providers: []string{"openai"}, }, Responses: []mocker.Response{ { Type: mocker.ResponseTypeSuccess, Content: &mocker.SuccessResponse{ Message: "Hello! This is a custom mock response for OpenAI.", Usage: &mocker.Usage{ PromptTokens: 15, CompletionTokens: 25, TotalTokens: 40, }, }, }, }, }, },})Responses Request Example
Section titled “Responses Request Example”The mocker plugin automatically handles both chat completion and responses requests with the same configuration:
// This rule will work for both ChatCompletionRequest and ResponsesRequest{ Name: "universal-mock", Enabled: true, Probability: 1.0, Conditions: mocker.Conditions{ MessageRegex: stringPtr("(?i).*hello.*"), }, Responses: []mocker.Response{ { Type: mocker.ResponseTypeSuccess, Content: &mocker.SuccessResponse{ Message: "Hello! I'm a mock response that works for both request types.", }, }, },}Installation
Section titled “Installation”Add the plugin to your project:
go get github.com/maximhq/deepintshield/plugins/mockerImport in your code:
import mocker "github.com/maximhq/deepintshield/plugins/mocker"Basic Usage
Section titled “Basic Usage”Creating the Plugin
Section titled “Creating the Plugin”config := mocker.MockerConfig{ Enabled: true, DefaultBehavior: mocker.DefaultBehaviorPassthrough, // "passthrough", "success", "error" Rules: []mocker.MockRule{ // Your rules here },}
plugin, err := mocker.NewMockerPlugin(config)if err != nil { log.Fatal(err)}Adding to DeepIntShield
Section titled “Adding to DeepIntShield”client, initErr := deepintshield.Init(context.Background(), schemas.DeepIntShieldConfig{ Account: &yourAccount, LLMPlugins: []schemas.LLMPlugin{plugin}, Logger: deepintshield.NewDefaultLogger(schemas.LogLevelInfo),})Disabling the Plugin
Section titled “Disabling the Plugin”config := mocker.MockerConfig{ Enabled: false, // All requests pass through to real providers}Supported Request Types
Section titled “Supported Request Types”The Mocker plugin supports the following DeepIntShield request types:
- Chat Completion Requests (
ChatCompletionRequest) - Standard chat-based interactions - Responses Requests (
ResponsesRequest) - OpenAI-compatible responses API format - Skip Context Key - Use
"skip-mocker"context key to bypass mocking per request
Skip Mocker for Specific Requests
Section titled “Skip Mocker for Specific Requests”You can skip the mocker plugin for specific requests by adding a context key:
import "github.com/maximhq/deepintshield/core/schemas"
// Create context that skips mockerctx := context.WithValue(context.Background(), schemas.DeepIntShieldContextKey("skip-mocker"), true)
// This request will bypass the mocker and go to the real providerresponse, err := client.ChatCompletionRequest(schemas.NewDeepIntShieldContext(ctx, schemas.NoDeadline), request)Key Features
Section titled “Key Features”Template Variables
Section titled “Template Variables”Create dynamic responses using templates:
Response{ Type: mocker.ResponseTypeSuccess, Content: &mocker.SuccessResponse{ MessageTemplate: stringPtr("Hello from {{provider}} using model {{model}}!"), },}Available Variables:
{{provider}}- Provider name (e.g., “openai”, “anthropic”){{model}}- Model name (e.g., “gpt-4”, “claude-3”){{faker.*}}- Fake data generation (see Configuration Reference)
Weighted Response Selection
Section titled “Weighted Response Selection”Configure multiple responses with different probabilities:
Responses: []mocker.Response{ { Type: mocker.ResponseTypeSuccess, Weight: 0.8, // 80% chance Content: &mocker.SuccessResponse{ Message: "Success response", }, }, { Type: mocker.ResponseTypeError, Weight: 0.2, // 20% chance Error: &mocker.ErrorResponse{ Message: "Rate limit exceeded", Type: stringPtr("rate_limit"), Code: stringPtr("429"), }, },}Latency Simulation
Section titled “Latency Simulation”Add realistic delays to responses:
// Fixed latencyLatency: &mocker.Latency{ Type: mocker.LatencyTypeFixed, Min: 250 * time.Millisecond,}
// Variable latencyLatency: &mocker.Latency{ Type: mocker.LatencyTypeUniform, Min: 100 * time.Millisecond, Max: 500 * time.Millisecond,}Advanced Matching
Section titled “Advanced Matching”Regex Message Matching
Section titled “Regex Message Matching”Conditions: mocker.Conditions{ MessageRegex: stringPtr(`(?i).*support.*|.*help.*`),}Request Size Filtering
Section titled “Request Size Filtering”Conditions: mocker.Conditions{ RequestSize: &mocker.SizeRange{ Min: 100, // bytes Max: 1000, // bytes },}Faker Data Generation
Section titled “Faker Data Generation”Create realistic test data using faker variables:
{ Name: "user-profile-example", Responses: []mocker.Response{ { Type: mocker.ResponseTypeSuccess, Content: &mocker.SuccessResponse{ MessageTemplate: stringPtr(`User Profile:- Name: {{faker.name}}- Email: {{faker.email}}- Company: {{faker.company}}- Address: {{faker.address}}, {{faker.city}}- Phone: {{faker.phone}}- User ID: {{faker.uuid}}- Join Date: {{faker.date}}- Premium Account: {{faker.boolean}}`), }, }, },}Statistics and Monitoring
Section titled “Statistics and Monitoring”Get runtime statistics for monitoring:
stats := plugin.GetStatistics()fmt.Printf("Plugin enabled: %v\n", stats.Enabled)fmt.Printf("Total requests: %d\n", stats.TotalRequests)fmt.Printf("Mocked requests: %d\n", stats.MockedRequests)
// Rule-specific statsfor ruleName, ruleStats := range stats.Rules { fmt.Printf("Rule %s: %d triggers\n", ruleName, ruleStats.Triggers)}Configuration Reference
Section titled “Configuration Reference”MockerConfig
Section titled “MockerConfig”| Field | Type | Default | Description |
|---|---|---|---|
Enabled | bool | false | Enable/disable the entire plugin |
DefaultBehavior | string | "passthrough" | Action when no rules match: "passthrough", "success", "error" |
GlobalLatency | *Latency | nil | Global latency applied to all rules |
Rules | []MockRule | [] | List of mock rules evaluated in priority order |
MockRule
Section titled “MockRule”| Field | Type | Default | Description |
|---|---|---|---|
Name | string | - | Unique rule name for identification |
Enabled | bool | true | Enable/disable this specific rule |
Priority | int | 0 | Higher numbers = higher priority |
Probability | float64 | 1.0 | Activation probability (0.0=never, 1.0=always) |
Conditions | Conditions | {} | Matching conditions (empty = match all) |
Responses | []Response | - | Possible responses (weighted random selection) |
Latency | *Latency | nil | Rule-specific latency override |
Conditions
Section titled “Conditions”| Field | Type | Description |
|---|---|---|
Providers | []string | Match specific providers: ["openai", "anthropic"] |
Models | []string | Match specific models: ["gpt-4", "claude-3"] |
MessageRegex | *string | Regex pattern to match message content |
RequestSize | *SizeRange | Request size constraints in bytes |
Response
Section titled “Response”| Field | Type | Description |
|---|---|---|
Type | string | Response type: "success" or "error" |
Weight | float64 | Weight for random selection (default: 1.0) |
Content | *SuccessResponse | Required if Type="success" |
Error | *ErrorResponse | Required if Type="error" |
AllowFallbacks | *bool | Control fallback behavior (nil=allow, false=block) |
SuccessResponse
Section titled “SuccessResponse”| Field | Type | Description |
|---|---|---|
Message | string | Static response message |
MessageTemplate | *string | Template with variables: {{provider}}, {{model}}, {{faker.*}} |
Model | *string | Override model name in response |
Usage | *Usage | Token usage information |
FinishReason | *string | Completion reason (default: "stop") |
CustomFields | map[string]interface{} | Additional metadata fields |
ErrorResponse
Section titled “ErrorResponse”| Field | Type | Description |
|---|---|---|
Message | string | Error message to return |
Type | *string | Error type (e.g., "rate_limit", "auth_error") |
Code | *string | Error code (e.g., "429", "401") |
StatusCode | *int | HTTP status code |
Latency
Section titled “Latency”| Field | Type | Description |
|---|---|---|
Type | string | Latency type: "fixed" or "uniform" |
Min | time.Duration | Minimum/exact latency (use time.Millisecond) |
Max | time.Duration | Maximum latency (required for "uniform") |
Important: Use Go’s time.Duration constants:
- ✅ Correct:
100 * time.Millisecond - ❌ Wrong:
100(nanoseconds, barely noticeable)
Faker Variables
Section titled “Faker Variables”Personal Information
Section titled “Personal Information”{{faker.name}}- Full name{{faker.first_name}}- First name only{{faker.last_name}}- Last name only{{faker.email}}- Email address{{faker.phone}}- Phone number
Location
Section titled “Location”{{faker.address}}- Street address{{faker.city}}- City name{{faker.state}}- State/province{{faker.zip_code}}- Postal code
Business
Section titled “Business”{{faker.company}}- Company name{{faker.job_title}}- Job title
Text and Data
Section titled “Text and Data”{{faker.lorem_ipsum}}- Lorem ipsum text{{faker.lorem_ipsum:10}}- Lorem ipsum with 10 words{{faker.uuid}}- UUID v4{{faker.hex_color}}- Hex color code
Numbers and Dates
Section titled “Numbers and Dates”{{faker.integer}}- Random integer (1-100){{faker.integer:10,50}}- Random integer between 10-50{{faker.float}}- Random float (0-100, 2 decimals){{faker.float:1,10}}- Random float between 1-10{{faker.boolean}}- Random boolean{{faker.date}}- Date (YYYY-MM-DD format){{faker.datetime}}- Datetime (YYYY-MM-DD HH:MM:SS format)
Best Practices
Section titled “Best Practices”Rule Organization
Section titled “Rule Organization”// Use priority to control rule evaluation orderrules := []mocker.MockRule{ {Name: "specific-error", Priority: 100, Conditions: /* specific */}, {Name: "general-success", Priority: 50, Conditions: /* general */}, {Name: "catch-all", Priority: 0, Conditions: /* empty */},}Development vs Production
Section titled “Development vs Production”// Development: High mock rateconfig := mocker.MockerConfig{ Enabled: true, Rules: []mocker.MockRule{ {Probability: 1.0}, // Always mock },}
// Production: Occasional testingconfig := mocker.MockerConfig{ Enabled: true, Rules: []mocker.MockRule{ {Probability: 0.1}, // 10% mock rate },}Performance Considerations
Section titled “Performance Considerations”- Place specific conditions before general ones (higher priority)
- Use simple string matching over complex regex when possible
- Keep response templates reasonably sized
- Consider disabling debug logging in production
Testing Your Configuration
Section titled “Testing Your Configuration”func validateMockerConfig(config mocker.MockerConfig) error { _, err := mocker.NewMockerPlugin(config) return err}
// Test before deploymentif err := validateMockerConfig(yourConfig); err != nil { log.Fatalf("Invalid mocker configuration: %v", err)}Common Issues
Section titled “Common Issues”Plugin Not Triggering
Section titled “Plugin Not Triggering”- Check if plugin is enabled:
Enabled: true - Verify rule is enabled:
rule.Enabled: true - Check probability:
Probability: 1.0for testing - Verify conditions match your request
Latency Not Working
Section titled “Latency Not Working”Use time.Duration constants, not raw integers:
// ❌ Wrong: 100 nanoseconds (barely noticeable)Min: 100
// ✅ Correct: 100 millisecondsMin: 100 * time.MillisecondRegex Not Matching
Section titled “Regex Not Matching”Test your regex pattern and ensure proper escaping:
// Case-insensitive matchingMessageRegex: stringPtr(`(?i).*help.*`)
// Escape special charactersMessageRegex: stringPtr(`\$\d+\.\d+`) // Match $12.34Controlling Fallbacks
Section titled “Controlling Fallbacks”Response{ Type: mocker.ResponseTypeError, AllowFallbacks: boolPtr(false), // Block fallbacks Error: &mocker.ErrorResponse{ Message: "Authentication failed", },}Skip Mocker Not Working
Section titled “Skip Mocker Not Working”Ensure you’re using the correct context key format:
// ✅ Correctctx := context.WithValue(context.Background(), schemas.DeepIntShieldContextKey("skip-mocker"), true)
// ❌ Wrongctx := context.WithValue(context.Background(), "skip-mocker", true)Responses Request Issues
Section titled “Responses Request Issues”If responses requests aren’t being mocked:
- Verify the plugin supports
ResponsesRequest(version 1.2.13+) - Check that your regex patterns match the message content
- Ensure the request type is
schemas.ResponsesRequest
Debug Mode
Section titled “Debug Mode”Enable debug logging to troubleshoot:
client, initErr := deepintshield.Init(context.Background(), schemas.DeepIntShieldConfig{ Account: &account, LLMPlugins: []schemas.LLMPlugin{plugin}, Logger: deepintshield.NewDefaultLogger(schemas.LogLevelDebug),})