Configure Kirby Copilot globally in your config.php file. This sets default configuration properties that apply to all plugin instances, including AI provider settings, generation parameters, and default behavior for view buttons and sections.
Kirby Copilot supports multiple AI providers. You must configure at least one provider with valid credentials for the plugin to function.
All provider configurations are nested under the johannschopplich.copilot key:
return [
'johannschopplich.copilot' => [
'provider' => 'google', // Choose your primary provider
'providers' => [
'google' => [
'apiKey' => 'YOUR_API_KEY',
// Model for content generation
'model' => 'gemini-3-pro-preview',
// Model for writer field inline suggestions
'completionModel' => 'gemini-3-flash-preview'
]
]
]
];
Each provider supports two model configurations:
model – Used for content generation (text, blocks, layouts).completionModel – Used for inline suggestions in writer fields (should be fast and lightweight).return [
'johannschopplich.copilot' => [
'provider' => 'openai',
'providers' => [
'openai' => [
'apiKey' => env('OPENAI_API_KEY'),
'model' => 'gpt-5-mini'
]
]
]
];
return [
'johannschopplich.copilot' => [
'provider' => 'google',
'providers' => [
'google' => [
'apiKey' => env('GOOGLE_API_KEY'),
'model' => 'gemini-3-pro-preview'
]
]
]
];
return [
'johannschopplich.copilot' => [
'provider' => 'anthropic',
'providers' => [
'anthropic' => [
'apiKey' => env('ANTHROPIC_API_KEY'),
'model' => 'claude-sonnet-4-5-20250929'
]
]
]
];
return [
'johannschopplich.copilot' => [
'provider' => 'mistral',
'providers' => [
'mistral' => [
'apiKey' => env('MISTRAL_API_KEY'),
'model' => 'mistral-large-latest',
// Optional: custom base URL
'baseUrl' => 'https://api.mistral.ai'
]
]
]
];
If you do not specify a model or completionModel, Kirby Copilot uses sensible defaults for each provider:
| Provider | Generation Model (model) | Completion Model (completionModel) |
|---|---|---|
| OpenAI | gpt-5.2 | gpt-5-nano |
gemini-3-pro-preview | gemini-3-flash-preview | |
| Anthropic | claude-sonnet-4-5-20250929 | claude-haiku-4-5-20251001 |
| Mistral | mistral-large-latest | mistral-small-latest |
completionModel is used for inline suggestions in writer fields. It should be a fast, lightweight model optimized for quick inline suggestions.systemPrompt StringGlobal system prompt that defines how the AI should structure and approach content generation. This can be overridden by view button props or section configuration.
Kirby Copilot ships with a well-crafted default system prompt that handles response formatting for different field types (text, markdown, rich-text) and preserves formatting when working with selected text. In most cases, the default works out of the box and customization is not necessary.
excludedBlocks ArraySpecify block types to exclude from structured data generation in blocks and layout fields. This is useful for custom block types for which AI generation is not desired.
Default: [] (no blocks excluded)
return [
'johannschopplich.copilot' => [
'excludedBlocks' => ['custom-form', 'widget', 'advertisement'],
]
];
reasoningEffort StringControls the depth of reasoning applied during content generation. This property works with all reasoning-capable models across providers (GPT-5, Gemini 3, Claude 4).
Default: low
Options: none, low, medium, high
return [
'johannschopplich.copilot' => [
'reasoningEffort' => 'medium'
]
];
temperature configuration obsolete.completion Array | BooleanControls inline suggestions in writer fields. Inline suggestions are enabled by default for all writer fields.
Default: ['debounce' => 1000]
To disable inline suggestions globally:
return [
'johannschopplich.copilot' => [
'completion' => false
]
];
To customize the debounce timing (minimum 500ms):
return [
'johannschopplich.copilot' => [
'completion' => [
'debounce' => 1500 // Wait 1.5 seconds after typing stops
]
]
];
promptTemplates ArrayDefine prompt templates that appear for all Panel users. Config-defined templates are read-only and displayed alongside user-created templates.
Default: [] (uses built-in defaults)
return [
'johannschopplich.copilot' => [
'promptTemplates' => [
[
'label' => 'Apply House Style',
'prompt' => 'Format the text according to our editorial style: artist names in bold, album titles in italics, use curly quotation marks.'
],
[
'label' => 'Add Spotify Links',
'prompt' => 'Find all album titles in the text and wrap them in Markdown links to their Spotify pages.'
]
]
]
];
return [
'johannschopplich.copilot' => [
'promptTemplates' => [
[
'label' => [
'en' => 'Apply House Style',
'de' => 'Redaktionsstil anwenden'
],
'prompt' => [
'en' => 'Format the text according to our editorial style: artist names in bold, album titles in italics, use curly quotation marks.',
'de' => 'Formatiere den Text nach unserem Redaktionsstil: Künstlernamen fett, Albumtitel kursiv, typografische Anführungszeichen verwenden.'
]
]
]
]
];
baseUrl StringCustom base URL for the AI provider API. This property is configured per provider alongside apiKey and model. Useful when using proxy services, custom API endpoints, or self-hosted AI services like llama.cpp.
Default: Provider-specific default URL
return [
'johannschopplich.copilot' => [
'provider' => 'openai',
'providers' => [
'openai' => [
'apiKey' => env('OPENAI_API_KEY'),
'model' => 'llama-3.2-3b-instruct',
'baseUrl' => 'https://llama.example.com/v1'
]
]
]
];
You can set global defaults that apply to both view buttons and sections. These can be overridden in individual blueprints.
For detailed descriptions of each property, see the View Button & Section Configuration page. The following properties can be set globally:
error, warn, info, debug.return [
'johannschopplich.copilot' => [
'provider' => 'google', // Primary provider
'providers' => [
'google' => [
'apiKey' => env('GOOGLE_API_KEY'),
'model' => 'gemini-3-pro-preview'
]
],
// Global Defaults
'logLevel' => 'info',
'excludedBlocks' => ['custom-form']
]
];
Starting with v3, all AI provider requests are routed through a server-side proxy. Your API keys are no longer exposed in browser network requests, protecting them from Panel users.
We still recommend following these best practices:
return [
'johannschopplich.copilot' => [
'providers' => [
'openai' => [
'apiKey' => env('OPENAI_API_KEY'), // Use environment variables
]
]
]
];
For advanced use cases, you can provide a closure that resolves the API key dynamically at runtime. The closure receives the Kirby instance as its first argument, allowing user-specific or context-dependent API keys.
return [
'johannschopplich.copilot' => [
'providers' => [
'openai' => [
'apiKey' => function (\Kirby\Cms\App $kirby) {
// Example: Return different keys based on user role
$user = $kirby->user();
if ($user?->role()->name() === 'admin') {
return env('OPENAI_API_KEY_ADMIN');
}
return env('OPENAI_API_KEY_USER');
}
]
]
]
];
This is useful for scenarios like:
Global configuration serves as the foundation, with more specific configurations overriding global defaults:
config.php)return [
'johannschopplich.copilot' => [
'logLevel' => 'warn',
'systemPrompt' => 'Global prompt…'
]
];
sections:
copilot:
type: copilot
field: content
logLevel: debug # Overrides global
# systemPrompt inherited from global
buttons:
copilot:
logLevel: debug # Overrides both global
return [
'johannschopplich.copilot' => [
'provider' => 'google', // Primary provider
'providers' => [
'google' => [
'apiKey' => env('GOOGLE_API_KEY'),
'model' => 'gemini-3-pro-preview',
'completionModel' => 'gemini-3-flash-preview'
],
'openai' => [
'apiKey' => env('OPENAI_API_KEY'),
'model' => 'gpt-5-mini',
'completionModel' => 'gpt-5-nano'
]
],
// Generation settings
'reasoningEffort' => 'low',
'completion' => [
'debounce' => 1000
],
// Global defaults
'excludedBlocks' => [
'contact-form',
'newsletter-signup',
'advertisement'
]
]
];