| [ Index ] |
PHP Cross Reference of WordPress Trunk (Updated Daily) |
[Summary view] [Print] [Text view]
1 <?php 2 3 declare (strict_types=1); 4 namespace WordPress\AiClient; 5 6 use WordPress\AiClientDependencies\Psr\EventDispatcher\EventDispatcherInterface; 7 use WordPress\AiClientDependencies\Psr\SimpleCache\CacheInterface; 8 use WordPress\AiClient\Builders\PromptBuilder; 9 use WordPress\AiClient\Common\Exception\InvalidArgumentException; 10 use WordPress\AiClient\Common\Exception\RuntimeException; 11 use WordPress\AiClient\Providers\Contracts\ProviderAvailabilityInterface; 12 use WordPress\AiClient\Providers\Contracts\ProviderInterface; 13 use WordPress\AiClient\Providers\Models\Contracts\ModelInterface; 14 use WordPress\AiClient\Providers\Models\DTO\ModelConfig; 15 use WordPress\AiClient\Providers\ProviderRegistry; 16 use WordPress\AiClient\Results\DTO\GenerativeAiResult; 17 /** 18 * Main AI Client class providing both fluent and traditional APIs for AI operations. 19 * 20 * This class serves as the primary entry point for AI operations, offering: 21 * - Fluent API for easy-to-read chained method calls 22 * - Traditional API for array-based configuration (WordPress style) 23 * - Integration with provider registry for model discovery 24 * - Support for three model specification approaches 25 * 26 * All model requirements analysis and capability matching is handled 27 * automatically by the PromptBuilder, which provides intelligent model 28 * discovery based on prompt content and configuration. 29 * 30 * ## Model Specification Approaches 31 * 32 * ### 1. Specific Model Instance 33 * Use a specific ModelInterface instance when you know exactly which model to use: 34 * ```php 35 * $model = $registry->getProvider('openai')->getModel('gpt-4'); 36 * $result = AiClient::generateTextResult('What is PHP?', $model); 37 * ``` 38 * 39 * ### 2. ModelConfig for Auto-Discovery 40 * Use ModelConfig to specify requirements and let the system discover the best model: 41 * ```php 42 * $config = new ModelConfig(); 43 * $config->setTemperature(0.7); 44 * $config->setMaxTokens(150); 45 * 46 * $result = AiClient::generateTextResult('What is PHP?', $config); 47 * ``` 48 * 49 * ### 3. Automatic Discovery (Default) 50 * Pass null or omit the parameter for intelligent model discovery based on prompt content: 51 * ```php 52 * // System analyzes prompt and selects appropriate model automatically 53 * $result = AiClient::generateTextResult('What is PHP?'); 54 * $imageResult = AiClient::generateImageResult('A sunset over mountains'); 55 * ``` 56 * 57 * ## Fluent API Examples 58 * ```php 59 * // Fluent API with automatic model discovery 60 * $result = AiClient::prompt('Generate an image of a sunset') 61 * ->usingTemperature(0.7) 62 * ->generateImageResult(); 63 * 64 * // Fluent API with specific model 65 * $result = AiClient::prompt('What is PHP?') 66 * ->usingModel($specificModel) 67 * ->usingTemperature(0.5) 68 * ->generateTextResult(); 69 * 70 * // Fluent API with model configuration 71 * $result = AiClient::prompt('Explain quantum physics') 72 * ->usingModelConfig($config) 73 * ->generateTextResult(); 74 * ``` 75 * 76 * @since 0.1.0 77 * 78 * @phpstan-import-type Prompt from PromptBuilder 79 * 80 * phpcs:ignore Generic.Files.LineLength.TooLong 81 */ 82 class AiClient 83 { 84 /** 85 * @var string The version of the AI Client. 86 */ 87 public const VERSION = '1.3.1'; 88 /** 89 * @var ProviderRegistry|null The default provider registry instance. 90 */ 91 private static ?ProviderRegistry $defaultRegistry = null; 92 /** 93 * @var EventDispatcherInterface|null The event dispatcher for prompt lifecycle events. 94 */ 95 private static ?EventDispatcherInterface $eventDispatcher = null; 96 /** 97 * @var CacheInterface|null The PSR-16 cache for storing and retrieving cached data. 98 */ 99 private static ?CacheInterface $cache = null; 100 /** 101 * Gets the default provider registry instance. 102 * 103 * @since 0.1.0 104 * 105 * @return ProviderRegistry The default provider registry. 106 */ 107 public static function defaultRegistry(): ProviderRegistry 108 { 109 if (self::$defaultRegistry === null) { 110 self::$defaultRegistry = new ProviderRegistry(); 111 } 112 return self::$defaultRegistry; 113 } 114 /** 115 * Sets the event dispatcher for prompt lifecycle events. 116 * 117 * The event dispatcher will be used to dispatch BeforeGenerateResultEvent and 118 * AfterGenerateResultEvent during prompt generation. 119 * 120 * @since 0.4.0 121 * 122 * @param EventDispatcherInterface|null $dispatcher The event dispatcher, or null to disable. 123 * @return void 124 */ 125 public static function setEventDispatcher(?EventDispatcherInterface $dispatcher): void 126 { 127 self::$eventDispatcher = $dispatcher; 128 } 129 /** 130 * Gets the event dispatcher for prompt lifecycle events. 131 * 132 * @since 0.4.0 133 * 134 * @return EventDispatcherInterface|null The event dispatcher, or null if not set. 135 */ 136 public static function getEventDispatcher(): ?EventDispatcherInterface 137 { 138 return self::$eventDispatcher; 139 } 140 /** 141 * Sets the PSR-16 cache for storing and retrieving cached data. 142 * 143 * The cache can be used to store AI responses and other data to avoid 144 * redundant API calls and improve performance. 145 * 146 * @since 0.4.0 147 * 148 * @param CacheInterface|null $cache The PSR-16 cache instance, or null to disable caching. 149 * @return void 150 */ 151 public static function setCache(?CacheInterface $cache): void 152 { 153 self::$cache = $cache; 154 } 155 /** 156 * Gets the PSR-16 cache instance. 157 * 158 * @since 0.4.0 159 * 160 * @return CacheInterface|null The cache instance, or null if not set. 161 */ 162 public static function getCache(): ?CacheInterface 163 { 164 return self::$cache; 165 } 166 /** 167 * Checks if a provider is configured and available for use. 168 * 169 * Supports multiple input formats for developer convenience: 170 * - ProviderAvailabilityInterface: Direct availability check 171 * - string (provider ID): e.g., AiClient::isConfigured('openai') 172 * - string (class name): e.g., AiClient::isConfigured(OpenAiProvider::class) 173 * 174 * When using string input, this method leverages the ProviderRegistry's centralized 175 * dependency management, ensuring HttpTransporter and authentication are properly 176 * injected into availability instances. 177 * 178 * @since 0.1.0 179 * @since 0.2.0 Now supports being passed a provider ID or class name. 180 * 181 * @param ProviderAvailabilityInterface|string|class-string<ProviderInterface> $availabilityOrIdOrClassName 182 * The provider availability instance, provider ID, or provider class name. 183 * @return bool True if the provider is configured and available, false otherwise. 184 */ 185 public static function isConfigured($availabilityOrIdOrClassName): bool 186 { 187 // Handle direct ProviderAvailabilityInterface (backward compatibility) 188 if ($availabilityOrIdOrClassName instanceof ProviderAvailabilityInterface) { 189 return $availabilityOrIdOrClassName->isConfigured(); 190 } 191 // Handle string input (provider ID or class name) via registry 192 if (is_string($availabilityOrIdOrClassName)) { 193 return self::defaultRegistry()->isProviderConfigured($availabilityOrIdOrClassName); 194 } 195 throw new \InvalidArgumentException('Parameter must be a ProviderAvailabilityInterface instance, provider ID string, or provider class name. ' . sprintf('Received: %s', is_object($availabilityOrIdOrClassName) ? get_class($availabilityOrIdOrClassName) : gettype($availabilityOrIdOrClassName))); 196 } 197 /** 198 * Creates a new prompt builder for fluent API usage. 199 * 200 * Returns a PromptBuilder instance configured with the specified or default registry. 201 * The traditional API methods in this class delegate to PromptBuilder 202 * for all generation logic. 203 * 204 * @since 0.1.0 205 * 206 * @param Prompt $prompt Optional initial prompt content. 207 * @param ProviderRegistry|null $registry Optional custom registry. If null, uses default. 208 * @return PromptBuilder The prompt builder instance. 209 */ 210 public static function prompt($prompt = null, ?ProviderRegistry $registry = null): PromptBuilder 211 { 212 return new PromptBuilder($registry ?? self::defaultRegistry(), $prompt, self::$eventDispatcher); 213 } 214 /** 215 * Generates content using a unified API that automatically detects model capabilities. 216 * 217 * When no model is provided, this method delegates to PromptBuilder for intelligent 218 * model discovery based on prompt content and configuration. When a model is provided, 219 * it infers the capability from the model's interfaces and delegates to the capability-based method. 220 * 221 * @since 0.1.0 222 * 223 * @param Prompt $prompt The prompt content. 224 * @param ModelInterface|ModelConfig $modelOrConfig Specific model to use, or model configuration 225 * for auto-discovery. 226 * @param ProviderRegistry|null $registry Optional custom registry. If null, uses default. 227 * @return GenerativeAiResult The generation result. 228 * 229 * @throws \InvalidArgumentException If the provided model doesn't support any known generation type. 230 * @throws \RuntimeException If no suitable model can be found for the prompt. 231 */ 232 public static function generateResult($prompt, $modelOrConfig, ?ProviderRegistry $registry = null): GenerativeAiResult 233 { 234 self::validateModelOrConfigParameter($modelOrConfig); 235 return self::getConfiguredPromptBuilder($prompt, $modelOrConfig, $registry)->generateResult(); 236 } 237 /** 238 * Generates text using the traditional API approach. 239 * 240 * @since 0.1.0 241 * 242 * @param Prompt $prompt The prompt content. 243 * @param ModelInterface|ModelConfig|null $modelOrConfig Optional specific model to use, 244 * or model configuration for auto-discovery, 245 * or null for defaults. 246 * @param ProviderRegistry|null $registry Optional custom registry. If null, uses default. 247 * @return GenerativeAiResult The generation result. 248 * 249 * @throws \InvalidArgumentException If the prompt format is invalid. 250 * @throws \RuntimeException If no suitable model is found. 251 */ 252 public static function generateTextResult($prompt, $modelOrConfig = null, ?ProviderRegistry $registry = null): GenerativeAiResult 253 { 254 self::validateModelOrConfigParameter($modelOrConfig); 255 return self::getConfiguredPromptBuilder($prompt, $modelOrConfig, $registry)->generateTextResult(); 256 } 257 /** 258 * Generates an image using the traditional API approach. 259 * 260 * @since 0.1.0 261 * 262 * @param Prompt $prompt The prompt content. 263 * @param ModelInterface|ModelConfig|null $modelOrConfig Optional specific model to use, 264 * or model configuration for auto-discovery, 265 * or null for defaults. 266 * @param ProviderRegistry|null $registry Optional custom registry. If null, uses default. 267 * @return GenerativeAiResult The generation result. 268 * 269 * @throws \InvalidArgumentException If the prompt format is invalid. 270 * @throws \RuntimeException If no suitable model is found. 271 */ 272 public static function generateImageResult($prompt, $modelOrConfig = null, ?ProviderRegistry $registry = null): GenerativeAiResult 273 { 274 self::validateModelOrConfigParameter($modelOrConfig); 275 return self::getConfiguredPromptBuilder($prompt, $modelOrConfig, $registry)->generateImageResult(); 276 } 277 /** 278 * Converts text to speech using the traditional API approach. 279 * 280 * @since 0.1.0 281 * 282 * @param Prompt $prompt The prompt content. 283 * @param ModelInterface|ModelConfig|null $modelOrConfig Optional specific model to use, 284 * or model configuration for auto-discovery, 285 * or null for defaults. 286 * @param ProviderRegistry|null $registry Optional custom registry. If null, uses default. 287 * @return GenerativeAiResult The generation result. 288 * 289 * @throws \InvalidArgumentException If the prompt format is invalid. 290 * @throws \RuntimeException If no suitable model is found. 291 */ 292 public static function convertTextToSpeechResult($prompt, $modelOrConfig = null, ?ProviderRegistry $registry = null): GenerativeAiResult 293 { 294 self::validateModelOrConfigParameter($modelOrConfig); 295 return self::getConfiguredPromptBuilder($prompt, $modelOrConfig, $registry)->convertTextToSpeechResult(); 296 } 297 /** 298 * Generates speech using the traditional API approach. 299 * 300 * @since 0.1.0 301 * 302 * @param Prompt $prompt The prompt content. 303 * @param ModelInterface|ModelConfig|null $modelOrConfig Optional specific model to use, 304 * or model configuration for auto-discovery, 305 * or null for defaults. 306 * @param ProviderRegistry|null $registry Optional custom registry. If null, uses default. 307 * @return GenerativeAiResult The generation result. 308 * 309 * @throws \InvalidArgumentException If the prompt format is invalid. 310 * @throws \RuntimeException If no suitable model is found. 311 */ 312 public static function generateSpeechResult($prompt, $modelOrConfig = null, ?ProviderRegistry $registry = null): GenerativeAiResult 313 { 314 self::validateModelOrConfigParameter($modelOrConfig); 315 return self::getConfiguredPromptBuilder($prompt, $modelOrConfig, $registry)->generateSpeechResult(); 316 } 317 /** 318 * Generates a video using the traditional API approach. 319 * 320 * @since 1.3.0 321 * 322 * @param Prompt $prompt The prompt content. 323 * @param ModelInterface|ModelConfig|null $modelOrConfig Optional specific model to use, 324 * or model configuration for auto-discovery, 325 * or null for defaults. 326 * @param ProviderRegistry|null $registry Optional custom registry. If null, uses default. 327 * @return GenerativeAiResult The generation result. 328 * 329 * @throws \InvalidArgumentException If the prompt format is invalid. 330 * @throws \RuntimeException If no suitable model is found. 331 */ 332 public static function generateVideoResult($prompt, $modelOrConfig = null, ?ProviderRegistry $registry = null): GenerativeAiResult 333 { 334 self::validateModelOrConfigParameter($modelOrConfig); 335 return self::getConfiguredPromptBuilder($prompt, $modelOrConfig, $registry)->generateVideoResult(); 336 } 337 /** 338 * Creates a new message builder for fluent API usage. 339 * 340 * This method will be implemented once MessageBuilder is available. 341 * MessageBuilder will provide a fluent interface for constructing complex 342 * messages with multiple parts, attachments, and metadata. 343 * 344 * @since 0.1.0 345 * 346 * @param string|null $text Optional initial message text. 347 * @return object MessageBuilder instance (type will be updated when MessageBuilder is available). 348 * 349 * @throws \RuntimeException When MessageBuilder is not yet available. 350 */ 351 public static function message(?string $text = null) 352 { 353 throw new RuntimeException('MessageBuilder is not yet available. This method depends on builder infrastructure. ' . 'Use direct generation methods (generateTextResult, generateImageResult, etc.) for now.'); 354 } 355 /** 356 * Validates that parameter is ModelInterface, ModelConfig, or null. 357 * 358 * @param mixed $modelOrConfig The parameter to validate. 359 * @return void 360 * @throws \InvalidArgumentException If parameter is invalid type. 361 */ 362 private static function validateModelOrConfigParameter($modelOrConfig): void 363 { 364 if ($modelOrConfig !== null && !$modelOrConfig instanceof ModelInterface && !$modelOrConfig instanceof ModelConfig) { 365 throw new InvalidArgumentException('Parameter must be a ModelInterface instance (specific model), ' . 'ModelConfig instance (for auto-discovery), or null (default auto-discovery). ' . sprintf('Received: %s', is_object($modelOrConfig) ? get_class($modelOrConfig) : gettype($modelOrConfig))); 366 } 367 } 368 /** 369 * Configures PromptBuilder based on model/config parameter type. 370 * 371 * @param Prompt $prompt The prompt content. 372 * @param ModelInterface|ModelConfig|null $modelOrConfig The model or config parameter. 373 * @param ProviderRegistry|null $registry Optional custom registry to use. 374 * @return PromptBuilder Configured prompt builder. 375 */ 376 private static function getConfiguredPromptBuilder($prompt, $modelOrConfig, ?ProviderRegistry $registry = null): PromptBuilder 377 { 378 $builder = self::prompt($prompt, $registry); 379 if ($modelOrConfig instanceof ModelInterface) { 380 $builder->usingModel($modelOrConfig); 381 } elseif ($modelOrConfig instanceof ModelConfig) { 382 $builder->usingModelConfig($modelOrConfig); 383 } 384 // null case: use default model discovery 385 return $builder; 386 } 387 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
| Generated : Sat Jun 13 09:38:55 2026 | Cross-referenced by PHPXref |