Client
Generate AI content from PHP with one method call. The Client resolves your configured provider from johannschopplich.copilot options and dispatches text or structured-output requests – the same path the Panel uses.
use JohannSchopplich\Copilot\AI\Client;
$result = Client::instance()->generateObject(
messages: [
['role' => 'user', 'content' => "What's 2+2?"],
],
schema: ['type' => 'object', 'properties' => ['answer' => ['type' => 'integer']], 'required' => ['answer']],
);
Construction
use JohannSchopplich\Copilot\AI\Client;
$client = Client::instance();
The singleton reads johannschopplich.copilot options once and caches the resolved provider until you call Client::reset().
use JohannSchopplich\Copilot\AI\Client;
use JohannSchopplich\Copilot\AI\Resolver;
$client = new Client(
resolver: Resolver::fromKirbyOptions(),
);
A fresh resolution against changed config – useful when an apiKey closure depends on the current Panel user.
use JohannSchopplich\Copilot\AI\Client;
use JohannSchopplich\Copilot\AI\Providers\OpenAIProvider;
use JohannSchopplich\Copilot\AI\ProviderConfig;
$provider = new OpenAIProvider(new ProviderConfig(
apiKey: 'sk-test-xxx',
model: 'gpt-5.4-mini',
));
$client = new Client(providerOverride: $provider);
Bypass the resolver entirely. Intended for tests and one-off scripts.
Methods
generateObject
public function generateObject(array $messages, array $schema): array
system message is forwarded; the rest become user / assistant turns.Returns the decoded JSON response as an associative array. Throws ProviderException on any failure.
generateText
public function generateText(array $messages): string
system message is forwarded; the rest become user / assistant turns.Returns the response text as a plain string. Throws ProviderException on any failure.
requireApiKey
public function requireApiKey(): void
Asserts that the active provider has an API key configured. Throws Kirby\Exception\AuthException with a message pointing to the missing config path. Useful as a preflight before kicking off a long batch operation.
reset (static)
public static function reset(): void
Clear the cached singleton. Call this in tests that swap config between cases.
Error Handling
use JohannSchopplich\Copilot\AI\Client;
use JohannSchopplich\Copilot\AI\Exception\ProviderException;
use Kirby\Exception\AuthException;
try {
$client = Client::instance();
$client->requireApiKey();
$result = $client->generateObject($messages, $schema);
} catch (AuthException $error) {
// Missing API key
} catch (ProviderException $error) {
// Upstream failure – $error->getDetails() carries provider/model/response context
}
Forcing a Provider for One Call
The resolver always dispatches to the provider set at johannschopplich.copilot.provider. To force a different one for a single call, use providerOverride:
use JohannSchopplich\Copilot\AI\Client;
use JohannSchopplich\Copilot\AI\Providers\AnthropicProvider;
use JohannSchopplich\Copilot\AI\Resolver;
use JohannSchopplich\Copilot\AI\ProviderName;
$config = Resolver::fromKirbyOptions()->forProvider(ProviderName::Anthropic);
$client = new Client(providerOverride: new AnthropicProvider($config));
$result = $client->generateObject($messages, $schema);
Use From a Sister Plugin
The Copilot AI strategy in Content Translator is a working example of consuming Client::generateObject() from another plugin. See the AI Strategy CLI script for a complete page-translation workflow that selects the AI strategy at call time.