Client

Generate text or structured JSON from any PHP context with one method call – CLI commands, hooks, custom controllers.

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().

Methods

generateObject

public function generateObject(array $messages, array $schema): array
messages
list<array{role: string, content: string}>
Chat messages. The first system message is forwarded; the rest become user / assistant turns.
schema
array<string, mixed>
JSON Schema for the response. The provider enforces it via the appropriate structured-output mechanism for its API.

Returns the decoded JSON response as an associative array. Throws ProviderException on any failure.

generateText

public function generateText(array $messages): string
messages
list<array{role: string, content: string}>
Chat messages. The first 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
}
See Exceptions for the full ProviderException payload.

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.