{"id":30759683,"url":"https://github.com/wordpress/wp-ai-client","last_synced_at":"2026-03-01T22:09:52.078Z","repository":{"id":312462168,"uuid":"1047580098","full_name":"WordPress/wp-ai-client","owner":"WordPress","description":"An AI client and API for WordPress to communicate with any generative AI models of various capabilities using a uniform API.","archived":false,"fork":false,"pushed_at":"2026-02-28T00:59:58.000Z","size":814,"stargazers_count":110,"open_issues_count":13,"forks_count":20,"subscribers_count":6,"default_branch":"trunk","last_synced_at":"2026-02-28T01:43:56.009Z","etag":null,"topics":["ai","wordpress"],"latest_commit_sha":null,"homepage":"","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/WordPress.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":"AGENTS.md","dco":null,"cla":null}},"created_at":"2025-08-30T18:27:14.000Z","updated_at":"2026-02-23T02:25:06.000Z","dependencies_parsed_at":"2025-10-31T00:20:53.609Z","dependency_job_id":"0bdf09e0-e4de-44e5-83a5-4075bc8a1512","html_url":"https://github.com/WordPress/wp-ai-client","commit_stats":null,"previous_names":["wordpress/wp-ai-client"],"tags_count":5,"template":false,"template_full_name":null,"purl":"pkg:github/WordPress/wp-ai-client","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/WordPress%2Fwp-ai-client","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/WordPress%2Fwp-ai-client/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/WordPress%2Fwp-ai-client/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/WordPress%2Fwp-ai-client/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/WordPress","download_url":"https://codeload.github.com/WordPress/wp-ai-client/tar.gz/refs/heads/trunk","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/WordPress%2Fwp-ai-client/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29986242,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-01T21:06:37.093Z","status":"ssl_error","status_checked_at":"2026-03-01T21:05:45.052Z","response_time":124,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ai","wordpress"],"created_at":"2025-09-04T12:02:59.337Z","updated_at":"2026-03-01T22:09:52.073Z","avatar_url":"https://github.com/WordPress.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"# WordPress AI Client\n\n\u003e **Deprecated:** This package is deprecated in favor of the built-in AI client in WordPress 7.0+. On 7.0+, the PHP SDK infrastructure is disabled (core handles it natively), but the REST API endpoints and JavaScript API remain active since they are not yet in core. See [UPGRADE.md](./UPGRADE.md) for migration details.\n\n[_Part of the **AI Building Blocks for WordPress** initiative_](https://make.wordpress.org/ai/2025/07/17/ai-building-blocks)\n\nAn AI client and API for WordPress to communicate with any generative AI models of various capabilities using a uniform API.\n\nBuilt on top of the [PHP AI Client](https://github.com/WordPress/php-ai-client), adapted for the WordPress ecosystem.\n\n## Features\n\n- **WordPress-native Prompt Builder**: Fluent API for building and configuring AI prompts, built directly on top of the PHP AI Client while following WordPress Coding Standards and best practices.\n- **Admin Settings Screen**: Integrated settings screen in WP Admin to provision AI provider API credentials.\n- **Automatic Credential Wiring**: Automatic wiring up of AI provider API credentials based on storage in a WordPress database option.\n- **PSR-compliant HTTP Client**: HTTP client implementation using the WordPress HTTP API, fully compatible with PSR standards.\n- **Client-side JavaScript API**: A JavaScript API with a similar prompt builder, using REST endpoints under the hood to connect to the server-side infrastructure.\n\n**Note:** The client-side JavaScript API and REST endpoints are by default limited to only administrators since they allow arbitrary prompts and configuration. A `prompt_ai` capability is used to control access, and sites are able to customize how that capability is granted to users or specific roles.\n\n## Installation\n\n```bash\ncomposer require wordpress/wp-ai-client\n```\n\n## Configuration\n\n### 1. Initialize the Client\n\nYou must initialize the client on the WordPress `init` hook. This sets up the HTTP client integration and registers the settings screen. If you are using this as a plugin, this is already handled for you in `plugin.php`.\n\n```php\nadd_action( 'init', array( 'WordPress\\AI_Client\\AI_Client', 'init' ) );\n```\n\n### 2. Configure API Credentials\n\nBefore making requests, you need to configure API keys for your desired providers (e.g. Anthropic, Google, OpenAI).\n\n1. Go to **Settings \u003e AI Credentials** in the WordPress Admin.\n2. Enter your API keys for the providers you intend to use.\n3. Save changes.\n\n### 3. Load the JavaScript API (Optional)\n\nTo use the client-side JavaScript API, you need to enqueue the script.\n\n```php\nadd_action(\n\t'admin_enqueue_scripts',\n\tstatic function () {\n\t\twp_enqueue_script( 'wp-ai-client' );\n\t}\n);\n```\n\n## Usage\n\nThe SDK provides a fluent `Prompt_Builder` interface to construct and execute AI requests.\n\n### Text Generation\n\n**PHP:**\n\n```php\n$text = wp_ai_client_prompt( 'Write a haiku about WordPress.' )\n\t-\u003egenerate_text();\n\nif ( is_wp_error( $text ) ) {\n\twp_die( $text-\u003eget_error_message() );\n}\n\necho wp_kses_post( $text );\n```\n\n**JavaScript:**\n\n```javascript\ntext = await wp.aiClient.prompt( 'Write a haiku about WordPress.' )\n\t.generateText();\n\nconsole.log( text );\n```\n\n### Image Generation\n\n**PHP:**\n\n```php\n$image_file = wp_ai_client_prompt( 'A futuristic WordPress logo in neon style' )\n\t-\u003egenerate_image();\n\nif ( is_wp_error( $image_file ) ) {\n\twp_die( $image_file-\u003eget_error_message() );\n}\n\n$data_uri = $image_file-\u003egetDataUri();\n\necho '\u003cimg src=\"' . esc_url( $data_uri ) . '\" alt=\"A futuristic WordPress logo in neon style\"\u003e';\n```\n\n**JavaScript:**\n\n```javascript\nconst imageFile = await wp.aiClient.prompt( 'A futuristic WordPress logo in neon style' )\n\t.generateImage();\n\nconst dataUri = imageFile.getDataUri();\n\nconsole.log( `\u003cimg src=\"${ dataUri }\" alt=\"A futuristic WordPress logo in neon style\"\u003e` );\n```\n\n### Advanced Usage\n\n#### JSON Output and Temperature\n\n**PHP:**\n\n```php\n$schema = array(\n\t'type'       =\u003e 'array',\n\t'items'      =\u003e array(\n\t\t'type'       =\u003e 'object',\n\t\t'properties' =\u003e array(\n\t\t\t'plugin_name' =\u003e array( 'type' =\u003e 'string' ),\n\t\t\t'category'    =\u003e array( 'type' =\u003e 'string' ),\n\t\t),\n\t\t'required'   =\u003e array( 'plugin_name', 'category' ),\n\t),\n);\n\n$json = wp_ai_client_prompt( 'List 5 popular WordPress plugins with their primary category.' )\n\t-\u003eusing_temperature( 0.2 ) // Lower temperature for more deterministic result.\n\t-\u003eas_json_response( $schema )\n\t-\u003egenerate_text();\n\nif ( is_wp_error( $json ) ) {\n\twp_die( $json-\u003eget_error_message() );\n}\n\n// Output will be a JSON string adhering to the schema.\n$data = json_decode( $json, true );\n```\n\n**JavaScript:**\n\n```javascript\nconst schema = {\n\ttype: 'array',\n\titems: {\n\t\ttype: 'object',\n\t\tproperties: {\n\t\t\tplugin_name: { type: 'string' },\n\t\t\tcategory: { type: 'string' },\n\t\t},\n\t\trequired: [ 'plugin_name', 'category' ],\n\t},\n};\n\nconst json = await wp.aiClient.prompt( 'List 5 popular WordPress plugins with their primary category.' )\n\t.usingTemperature( 0.2 ) // Lower temperature for more deterministic result.\n\t.asJsonResponse( schema )\n\t.generateText();\n\n// Output will be a JSON string adhering to the schema.\nconst data = JSON.parse( json );\n```\n\n#### Generating Multiple Image Candidates\n\n**PHP:**\n\n```php\n$images = wp_ai_client_prompt( 'Aerial shot of snowy plains, cinematic.' )\n\t-\u003egenerate_images( 4 );\n\nif ( is_wp_error( $images ) ) {\n\twp_die( $images-\u003eget_error_message() );\n}\n\nforeach ( $images as $image_file ) {\n\techo '\u003cimg src=\"' . esc_url( $image_file-\u003egetDataUri() ) . '\" alt=\"Aerial shot of snowy plains\"\u003e';\n}\n```\n\n**JavaScript:**\n\n```javascript\nconst images = await wp.aiClient.prompt( 'Aerial shot of snowy plains, cinematic.' )\n\t.generateImages( 4 );\n\nfor ( const imageFile of images ) {\n\tconsole.log( `\u003cimg src=\"${ imageFile.getDataUri() }\" alt=\"Aerial shot of snowy plains\"\u003e` );\n}\n```\n\n#### Multimodal Output (Text \u0026 Image)\n\n**PHP:**\n\n```php\nuse WordPress\\AiClient\\Messages\\Enums\\ModalityEnum;\n\n$result = wp_ai_client_prompt( 'Create a recipe for a chocolate cake and include photos for the steps.' )\n\t-\u003eas_output_modalities( ModalityEnum::text(), ModalityEnum::image() )\n\t-\u003egenerate_result();\n\nif ( is_wp_error( $result ) ) {\n\twp_die( $result-\u003eget_error_message() );\n}\n\n// Iterate through the message parts.\nforeach ( $result-\u003etoMessage()-\u003egetParts() as $part ) {\n\tif ( $part-\u003eisText() ) {\n\t\techo wp_kses_post( $part-\u003egetText() );\n\t} elseif ( $part-\u003eisFile() \u0026\u0026 $part-\u003egetFile()-\u003eisImage() ) {\n\t\techo '\u003cimg src=\"' . esc_url( $part-\u003egetFile()-\u003egetDataUri() ) . '\" alt=\"\"\u003e';\n\t}\n}\n```\n\n**JavaScript:**\n\n```javascript\nconst { Modality, MessagePartType } = wp.aiClient.enums;\n\nconst result = await wp.aiClient.prompt( 'Create a recipe for a chocolate cake and include photos for the steps.' )\n\t.asOutputModalities( Modality.TEXT, Modality.IMAGE )\n\t.generateResult();\n\n// Iterate through the message parts.\nfor ( const part of result.toMessage().parts ) {\n\tif ( part.type === MessagePartType.TEXT ) {\n\t\tconsole.log( part.text );\n\t} else if ( part.type === MessagePartType.FILE \u0026\u0026 part.file.isImage() ) {\n\t\tconsole.log( `\u003cimg src=\"${ part.file.getDataUri() }\" alt=\"\"\u003e` );\n\t}\n}\n```\n\n## Best Practices\n\n### Automatic Model Selection\n\nBy default, the SDK automatically chooses a suitable model based on the prompt's requirements (e.g., text vs. image) and the configured providers on the site. This makes your plugin **provider-agnostic**, allowing it to work on any site regardless of which AI provider the admin has configured.\n\n### Using Model Preferences\n\nIf you prefer specific models for better performance or capabilities, use `using_model_preference()`. The SDK will try to use the first available model from your list. If none are available (e.g., provider not configured), it falls back to automatic selection.\n\nPass preferences as either a model ID string, or as an array of `[ provider_id, model_id ]`. For broader compatibility, it is recommended to pass only the model ID string, since there can be different providers offering the same model - e.g. many AI cloud services proxy through calls to models from third party model labs. Only pass the array of provider ID and model ID if you (for whichever reason) _only_ want to allow the model to be served from the specific provider.\n\n**PHP:**\n\n```php\n$summary = wp_ai_client_prompt( 'Summarize the history of the printing press.' )\n\t-\u003eusing_temperature( 0.1 )\n\t-\u003eusing_model_preference(\n\t\t'claude-sonnet-4-5',\n\t\t'gemini-3-pro-preview',\n\t\t'gpt-5.1'\n\t)\n\t-\u003egenerate_text();\n```\n\n**JavaScript:**\n\n```javascript\nconst summary = await wp.aiClient.prompt( 'Summarize the history of the printing press.' )\n\t.usingTemperature( 0.1 )\n\t.usingModelPreference(\n\t\t[ 'anthropic', 'claude-sonnet-4-5' ],\n\t\t[ 'google', 'gemini-3-pro-preview' ],\n\t\t[ 'openai', 'gpt-5.1' ]\n\t)\n\t.generateText();\n```\n\n### Setting max tokens\n\nControl the maximum number of tokens the AI model can generate in its response. Higher values allow for longer, more detailed outputs, while lower values help keep responses concise and reduce API costs.\n\n**PHP:**\n\n```php\nuse WordPress\\AI_Client\\AI_Client;\n\n$text = AI_Client::prompt( 'Explain quantum computing in complicated terms.' )\n\t-\u003eusing_max_tokens( 8000 )\n\t-\u003egenerate_text();\n```\n\n**JavaScript:**\n\n```javascript\nconst text = await wp.aiClient\n\t.prompt(\"Explain quantum computing in complicated terms.\")\n\t.usingMaxTokens(8000)\n\t.generateText();\n```\n\n### Using a Specific Model\n\nEnforcing a single specific model using `using_model()` restricts your feature to sites that have that specific provider configured. For most scenarios, this is unnecessarily opinionated. Only use this approach if you really only want to offer the feature in combination with that model.\n\n**PHP:**\n\n```php\nuse WordPress\\AiClient\\ProviderImplementations\\Anthropic\\AnthropicProvider as Anthropic;\n\n$text = wp_ai_client_prompt( 'Explain quantum computing in simple terms.' )\n\t-\u003eusing_model( Anthropic::model( 'claude-sonnet-4-5' ) )\n\t-\u003egenerate_text();\n```\n\n**JavaScript:**\n\n```javascript\nconst text = await wp.aiClient.prompt( 'Explain quantum computing in simple terms.' )\n\t.usingModel( 'anthropic', 'claude-sonnet-4-5' )\n\t.generateText();\n```\n\n### Feature Detection\n\nBefore actually sending an AI prompt and getting a response, always check if the prompt is supported before execution.\n\nThis is always recommended, but especially crucial if you require the use of a specific model.\n\n**PHP:**\n\n```php\n$prompt = wp_ai_client_prompt( 'Explain quantum computing in simple terms.' )\n\t-\u003eusing_temperature( 0.2 );\n\nif ( $prompt-\u003eis_supported_for_text_generation() ) {\n\t// Safe to generate.\n\t$text = $prompt-\u003egenerate_text();\n} else {\n\t// Fallback: Hide feature or show setup instructions.\n}\n```\n\n**JavaScript:**\n\n```javascript\nconst prompt = wp.aiClient.prompt( 'Explain quantum computing in simple terms.' )\n\t.usingTemperature( 0.2 );\n\nif ( await prompt.isSupportedForTextGeneration() ) {\n\t// Safe to generate.\n\tconst text = await prompt.generateText();\n} else {\n\t// Fallback: Hide feature or show setup instructions.\n}\n```\n\nThe above condition will only evaluate to `true` if the site has one or more providers configured with models that support text generation including a temperature configuration.\n\nGenerally, using `is_supported_for_text_generation()` (or `is_supported_for_image_generation()`, etc.) ensures you only expose AI features that can actually run on the current site configuration.\n\n## Error Handling\n\nThe `wp_ai_client_prompt()` function returns `WP_Error` on failure, following WordPress conventions.\n\n```php\n$text = wp_ai_client_prompt( 'Hello' )\n\t-\u003egenerate_text();\n\nif ( is_wp_error( $text ) ) {\n\twp_die( $text-\u003eget_error_message() );\n}\n\necho wp_kses_post( $text );\n```\n\n### Exception-based (advanced)\n\nIf you prefer exceptions, use `AI_Client::prompt()` directly.\n\n```php\nuse WordPress\\AI_Client\\AI_Client;\n\ntry {\n\t$text = AI_Client::prompt( 'Hello' )-\u003egenerate_text();\n} catch ( \\Exception $e ) {\n\twp_die( $e-\u003egetMessage() );\n}\n\necho wp_kses_post( $text );\n```\n\n## Architecture\n\nThis library is a WordPress-specific wrapper around the [PHP AI Client](https://github.com/WordPress/php-ai-client).\n\n*   **`wp_ai_client_prompt()`**: The recommended entry point function. Returns a `Prompt_Builder_With_WP_Error`.\n*   **`WordPress\\AI_Client\\AI_Client`**: The class-based entry point (for advanced use cases).\n*   **`WordPress\\AI_Client\\Builders\\Prompt_Builder`**: A fluent builder for constructing AI requests. It maps WordPress-style `snake_case` methods to the underlying SDK's `camelCase` methods.\n*   **`WordPress\\AI_Client\\Builders\\Prompt_Builder_With_WP_Error`**: A wrapper around `Prompt_Builder` that catches exceptions and returns `WP_Error` objects.\n\n## Further reading\n\nSee the [`Prompt_Builder` class](https://github.com/WordPress/wp-ai-client/blob/trunk/includes/Builders/Prompt_Builder.php) and its public methods for all the ways you can configure the prompt.\n\nSee the [contributing documentation](./CONTRIBUTING.md) for more information on how to get involved.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwordpress%2Fwp-ai-client","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fwordpress%2Fwp-ai-client","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwordpress%2Fwp-ai-client/lists"}