From b5159457f15afa2bb65467e9cf607e4483c3e103 Mon Sep 17 00:00:00 2001 From: Felix Arntz Date: Sat, 29 Nov 2025 17:03:12 -0800 Subject: [PATCH 01/14] Set up dependencies for AI Playground. --- composer.json | 2 +- composer.lock | 189 +++++++++++++------------- package-lock.json | 335 ++++++++++++++++++++++++++++++++-------------- package.json | 5 +- webpack.config.js | 27 ++++ 5 files changed, 357 insertions(+), 201 deletions(-) diff --git a/composer.json b/composer.json index 2bb73b10..609dc61d 100644 --- a/composer.json +++ b/composer.json @@ -9,7 +9,7 @@ "php": ">=7.4", "wordpress/abilities-api": "^0.4.0", "wordpress/mcp-adapter": "dev-trunk", - "wordpress/wp-ai-client": "dev-trunk" + "wordpress/wp-ai-client": "dev-add/providers-models-js-api" }, "require-dev": { "automattic/vipwpcs": "^3.0", diff --git a/composer.lock b/composer.lock index 439c1c09..07c3fa57 100644 --- a/composer.lock +++ b/composer.lock @@ -4,20 +4,20 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "f275018de0bc539ae98c534ab9e40c5a", + "content-hash": "ceafab605b1eb4aeb4da26b07dc3179d", "packages": [ { "name": "automattic/jetpack-autoloader", - "version": "v5.0.11", + "version": "v5.0.13", "source": { "type": "git", "url": "https://github.com/Automattic/jetpack-autoloader.git", - "reference": "90bf7b3bc29cb7be74105ac99afab4c21bc47e29" + "reference": "94888d86820a99a0f3aba3498ba10f6b6245c929" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Automattic/jetpack-autoloader/zipball/90bf7b3bc29cb7be74105ac99afab4c21bc47e29", - "reference": "90bf7b3bc29cb7be74105ac99afab4c21bc47e29", + "url": "https://api.github.com/repos/Automattic/jetpack-autoloader/zipball/94888d86820a99a0f3aba3498ba10f6b6245c929", + "reference": "94888d86820a99a0f3aba3498ba10f6b6245c929", "shasum": "" }, "require": { @@ -25,7 +25,7 @@ "php": ">=7.2" }, "require-dev": { - "automattic/jetpack-changelogger": "^6.0.7", + "automattic/jetpack-changelogger": "^6.0.9", "automattic/phpunit-select-config": "^1.0.3", "composer/composer": "^2.2", "yoast/phpunit-polyfills": "^4.0.0" @@ -67,9 +67,9 @@ "wordpress" ], "support": { - "source": "https://github.com/Automattic/jetpack-autoloader/tree/v5.0.11" + "source": "https://github.com/Automattic/jetpack-autoloader/tree/v5.0.13" }, - "time": "2025-10-06T10:32:52+00:00" + "time": "2025-11-12T16:41:11+00:00" }, { "name": "nyholm/psr7", @@ -631,12 +631,12 @@ "source": { "type": "git", "url": "https://github.com/WordPress/mcp-adapter.git", - "reference": "b55221f9d31307ae69943a094394a126579017f6" + "reference": "6d46c961c779bb44037da85bf4b562ead42dee37" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/WordPress/mcp-adapter/zipball/b55221f9d31307ae69943a094394a126579017f6", - "reference": "b55221f9d31307ae69943a094394a126579017f6", + "url": "https://api.github.com/repos/WordPress/mcp-adapter/zipball/6d46c961c779bb44037da85bf4b562ead42dee37", + "reference": "6d46c961c779bb44037da85bf4b562ead42dee37", "shasum": "" }, "require": { @@ -698,20 +698,20 @@ "issues": "https://github.com/wordpress/mcp-adapter/issues", "source": "https://github.com/wordpress/mcp-adapter" }, - "time": "2025-11-03T17:53:17+00:00" + "time": "2025-11-26T22:09:42+00:00" }, { "name": "wordpress/php-ai-client", - "version": "0.2.0", + "version": "0.3.0", "source": { "type": "git", "url": "https://github.com/WordPress/php-ai-client.git", - "reference": "81a104a9bc5f887e3fbecea6e0d9cd8eab3be0b2" + "reference": "70e5e222c74d734f5740802057762135a8a33318" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/WordPress/php-ai-client/zipball/81a104a9bc5f887e3fbecea6e0d9cd8eab3be0b2", - "reference": "81a104a9bc5f887e3fbecea6e0d9cd8eab3be0b2", + "url": "https://api.github.com/repos/WordPress/php-ai-client/zipball/70e5e222c74d734f5740802057762135a8a33318", + "reference": "70e5e222c74d734f5740802057762135a8a33318", "shasum": "" }, "require": { @@ -765,27 +765,27 @@ "issues": "https://github.com/WordPress/php-ai-client/issues", "source": "https://github.com/WordPress/php-ai-client" }, - "time": "2025-10-21T00:05:14+00:00" + "time": "2025-11-27T00:07:29+00:00" }, { "name": "wordpress/wp-ai-client", - "version": "dev-trunk", + "version": "dev-add/providers-models-js-api", "source": { "type": "git", "url": "https://github.com/WordPress/wp-ai-client.git", - "reference": "a41ef6075c1cbb56dfc380fe5c13a347b265d193" + "reference": "28825463f9cda12576273eaeb4f513e4708e898a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/WordPress/wp-ai-client/zipball/a41ef6075c1cbb56dfc380fe5c13a347b265d193", - "reference": "a41ef6075c1cbb56dfc380fe5c13a347b265d193", + "url": "https://api.github.com/repos/WordPress/wp-ai-client/zipball/28825463f9cda12576273eaeb4f513e4708e898a", + "reference": "28825463f9cda12576273eaeb4f513e4708e898a", "shasum": "" }, "require": { "ext-json": "*", "nyholm/psr7": "^1.5", "php": ">=7.4", - "wordpress/php-ai-client": "^0.2" + "wordpress/php-ai-client": "^0.3" }, "require-dev": { "automattic/vipwpcs": "^3.0", @@ -799,7 +799,6 @@ "wp-phpunit/wp-phpunit": "^6.8", "yoast/phpunit-polyfills": "^4.0" }, - "default-branch": true, "type": "library", "autoload": { "psr-4": { @@ -847,7 +846,7 @@ "issues": "https://github.com/WordPress/wp-ai-client/issues", "source": "https://github.com/WordPress/wp-ai-client" }, - "time": "2025-11-13T00:12:21+00:00" + "time": "2025-11-30T00:13:42+00:00" } ], "packages-dev": [ @@ -1053,29 +1052,29 @@ }, { "name": "dealerdirect/phpcodesniffer-composer-installer", - "version": "v1.1.2", + "version": "v1.2.0", "source": { "type": "git", "url": "https://github.com/PHPCSStandards/composer-installer.git", - "reference": "e9cf5e4bbf7eeaf9ef5db34938942602838fc2b1" + "reference": "845eb62303d2ca9b289ef216356568ccc075ffd1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/PHPCSStandards/composer-installer/zipball/e9cf5e4bbf7eeaf9ef5db34938942602838fc2b1", - "reference": "e9cf5e4bbf7eeaf9ef5db34938942602838fc2b1", + "url": "https://api.github.com/repos/PHPCSStandards/composer-installer/zipball/845eb62303d2ca9b289ef216356568ccc075ffd1", + "reference": "845eb62303d2ca9b289ef216356568ccc075ffd1", "shasum": "" }, "require": { "composer-plugin-api": "^2.2", "php": ">=5.4", - "squizlabs/php_codesniffer": "^2.0 || ^3.1.0 || ^4.0" + "squizlabs/php_codesniffer": "^3.1.0 || ^4.0" }, "require-dev": { "composer/composer": "^2.2", "ext-json": "*", "ext-zip": "*", "php-parallel-lint/php-parallel-lint": "^1.4.0", - "phpcompatibility/php-compatibility": "^9.0", + "phpcompatibility/php-compatibility": "^9.0 || ^10.0.0@dev", "yoast/phpunit-polyfills": "^1.0" }, "type": "composer-plugin", @@ -1145,7 +1144,7 @@ "type": "thanks_dev" } ], - "time": "2025-07-17T20:45:56+00:00" + "time": "2025-11-11T04:32:07+00:00" }, { "name": "doctrine/instantiator", @@ -1510,16 +1509,16 @@ "source": { "type": "git", "url": "https://github.com/PHPCompatibility/PHPCompatibility.git", - "reference": "ff4efdd80e094a81fd6329b570c9a632f21d42b4" + "reference": "ed82765a97f1480242bb7bc6558503b3526fd9c4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/PHPCompatibility/PHPCompatibility/zipball/ff4efdd80e094a81fd6329b570c9a632f21d42b4", - "reference": "ff4efdd80e094a81fd6329b570c9a632f21d42b4", + "url": "https://api.github.com/repos/PHPCompatibility/PHPCompatibility/zipball/ed82765a97f1480242bb7bc6558503b3526fd9c4", + "reference": "ed82765a97f1480242bb7bc6558503b3526fd9c4", "shasum": "" }, "require": { - "php": ">=5.4", + "php": ">=7.2", "phpcsstandards/phpcsutils": "^1.1.2", "squizlabs/php_codesniffer": "^3.13.3 || ^4.0" }, @@ -1529,14 +1528,11 @@ "require-dev": { "php-parallel-lint/php-console-highlighter": "^1.0.0", "php-parallel-lint/php-parallel-lint": "^1.4.0", - "phpcsstandards/phpcsdevcs": "^1.1.6", + "phpcsstandards/phpcsdevcs": "^1.2.0", "phpcsstandards/phpcsdevtools": "^1.2.3", - "phpunit/phpunit": "^4.8.36 || ^5.7.21 || ^6.0 || ^7.0 || ^8.0 || ^9.3.4 || ^10.5.32 || ^11.3.3", + "phpunit/phpunit": "^8.0 || ^9.3.4 || ^10.5.32 || ^11.3.3", "yoast/phpunit-polyfills": "^1.1.5 || ^2.0.5 || ^3.1.0" }, - "suggest": { - "roave/security-advisories": "dev-master || Helps prevent installing dependencies with known security issues." - }, "default-branch": true, "type": "phpcodesniffer-standard", "extra": { @@ -1596,7 +1592,7 @@ "type": "thanks_dev" } ], - "time": "2025-10-30T20:24:19+00:00" + "time": "2025-11-29T22:53:33+00:00" }, { "name": "phpcompatibility/phpcompatibility-paragonie", @@ -1751,27 +1747,27 @@ }, { "name": "phpcsstandards/phpcsextra", - "version": "1.4.2", + "version": "1.5.0", "source": { "type": "git", "url": "https://github.com/PHPCSStandards/PHPCSExtra.git", - "reference": "8e89a01c7b8fed84a12a2a7f5a23a44cdbe4f62e" + "reference": "b598aa890815b8df16363271b659d73280129101" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/PHPCSStandards/PHPCSExtra/zipball/8e89a01c7b8fed84a12a2a7f5a23a44cdbe4f62e", - "reference": "8e89a01c7b8fed84a12a2a7f5a23a44cdbe4f62e", + "url": "https://api.github.com/repos/PHPCSStandards/PHPCSExtra/zipball/b598aa890815b8df16363271b659d73280129101", + "reference": "b598aa890815b8df16363271b659d73280129101", "shasum": "" }, "require": { "php": ">=5.4", - "phpcsstandards/phpcsutils": "^1.1.2", - "squizlabs/php_codesniffer": "^3.13.4 || ^4.0" + "phpcsstandards/phpcsutils": "^1.2.0", + "squizlabs/php_codesniffer": "^3.13.5 || ^4.0.1" }, "require-dev": { "php-parallel-lint/php-console-highlighter": "^1.0", "php-parallel-lint/php-parallel-lint": "^1.4.0", - "phpcsstandards/phpcsdevcs": "^1.1.6", + "phpcsstandards/phpcsdevcs": "^1.2.0", "phpcsstandards/phpcsdevtools": "^1.2.1", "phpunit/phpunit": "^4.5 || ^5.0 || ^6.0 || ^7.0 || ^8.0 || ^9.3.4" }, @@ -1829,32 +1825,32 @@ "type": "thanks_dev" } ], - "time": "2025-10-28T17:00:02+00:00" + "time": "2025-11-12T23:06:57+00:00" }, { "name": "phpcsstandards/phpcsutils", - "version": "1.1.3", + "version": "1.2.1", "source": { "type": "git", "url": "https://github.com/PHPCSStandards/PHPCSUtils.git", - "reference": "8b8e17615d04f2fc2cd46fc1d2fd888fa21b3cf9" + "reference": "d71128c702c180ca3b27c761b6773f883394f162" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/PHPCSStandards/PHPCSUtils/zipball/8b8e17615d04f2fc2cd46fc1d2fd888fa21b3cf9", - "reference": "8b8e17615d04f2fc2cd46fc1d2fd888fa21b3cf9", + "url": "https://api.github.com/repos/PHPCSStandards/PHPCSUtils/zipball/d71128c702c180ca3b27c761b6773f883394f162", + "reference": "d71128c702c180ca3b27c761b6773f883394f162", "shasum": "" }, "require": { "dealerdirect/phpcodesniffer-composer-installer": "^0.4.1 || ^0.5 || ^0.6.2 || ^0.7 || ^1.0", "php": ">=5.4", - "squizlabs/php_codesniffer": "^3.13.3 || ^4.0" + "squizlabs/php_codesniffer": "^3.13.5 || ^4.0.1" }, "require-dev": { "ext-filter": "*", "php-parallel-lint/php-console-highlighter": "^1.0", "php-parallel-lint/php-parallel-lint": "^1.4.0", - "phpcsstandards/phpcsdevcs": "^1.1.6", + "phpcsstandards/phpcsdevcs": "^1.2.0", "yoast/phpunit-polyfills": "^1.1.0 || ^2.0.0 || ^3.0.0" }, "type": "phpcodesniffer-standard", @@ -1922,7 +1918,7 @@ "type": "thanks_dev" } ], - "time": "2025-10-16T16:39:32+00:00" + "time": "2025-11-17T12:58:33+00:00" }, { "name": "phpstan/extension-installer", @@ -2021,11 +2017,11 @@ }, { "name": "phpstan/phpstan", - "version": "2.1.31", + "version": "2.1.32", "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan/zipball/ead89849d879fe203ce9292c6ef5e7e76f867b96", - "reference": "ead89849d879fe203ce9292c6ef5e7e76f867b96", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/e126cad1e30a99b137b8ed75a85a676450ebb227", + "reference": "e126cad1e30a99b137b8ed75a85a676450ebb227", "shasum": "" }, "require": { @@ -2070,7 +2066,7 @@ "type": "github" } ], - "time": "2025-10-10T14:14:11+00:00" + "time": "2025-11-11T15:18:17+00:00" }, { "name": "phpstan/phpstan-deprecation-rules", @@ -2121,21 +2117,21 @@ }, { "name": "phpstan/phpstan-phpunit", - "version": "2.0.7", + "version": "2.0.8", "source": { "type": "git", "url": "https://github.com/phpstan/phpstan-phpunit.git", - "reference": "9a9b161baee88a5f5c58d816943cff354ff233dc" + "reference": "2fe9fbeceaf76dd1ebaa7bbbb25e2fb5e59db2fe" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan-phpunit/zipball/9a9b161baee88a5f5c58d816943cff354ff233dc", - "reference": "9a9b161baee88a5f5c58d816943cff354ff233dc", + "url": "https://api.github.com/repos/phpstan/phpstan-phpunit/zipball/2fe9fbeceaf76dd1ebaa7bbbb25e2fb5e59db2fe", + "reference": "2fe9fbeceaf76dd1ebaa7bbbb25e2fb5e59db2fe", "shasum": "" }, "require": { "php": "^7.4 || ^8.0", - "phpstan/phpstan": "^2.1.18" + "phpstan/phpstan": "^2.1.32" }, "conflict": { "phpunit/phpunit": "<7.0" @@ -2168,9 +2164,9 @@ "description": "PHPUnit extensions and rules for PHPStan", "support": { "issues": "https://github.com/phpstan/phpstan-phpunit/issues", - "source": "https://github.com/phpstan/phpstan-phpunit/tree/2.0.7" + "source": "https://github.com/phpstan/phpstan-phpunit/tree/2.0.8" }, - "time": "2025-07-13T11:31:46+00:00" + "time": "2025-11-11T07:55:22+00:00" }, { "name": "phpunit/php-code-coverage", @@ -3736,16 +3732,16 @@ }, { "name": "squizlabs/php_codesniffer", - "version": "3.13.4", + "version": "3.13.5", "source": { "type": "git", "url": "https://github.com/PHPCSStandards/PHP_CodeSniffer.git", - "reference": "ad545ea9c1b7d270ce0fc9cbfb884161cd706119" + "reference": "0ca86845ce43291e8f5692c7356fccf3bcf02bf4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/PHPCSStandards/PHP_CodeSniffer/zipball/ad545ea9c1b7d270ce0fc9cbfb884161cd706119", - "reference": "ad545ea9c1b7d270ce0fc9cbfb884161cd706119", + "url": "https://api.github.com/repos/PHPCSStandards/PHP_CodeSniffer/zipball/0ca86845ce43291e8f5692c7356fccf3bcf02bf4", + "reference": "0ca86845ce43291e8f5692c7356fccf3bcf02bf4", "shasum": "" }, "require": { @@ -3762,11 +3758,6 @@ "bin/phpcs" ], "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.x-dev" - } - }, "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" @@ -3816,7 +3807,7 @@ "type": "thanks_dev" } ], - "time": "2025-09-05T05:47:09+00:00" + "time": "2025-11-04T16:30:35+00:00" }, { "name": "szepeviktor/phpstan-wordpress", @@ -3883,16 +3874,16 @@ }, { "name": "theseer/tokenizer", - "version": "1.2.3", + "version": "1.3.1", "source": { "type": "git", "url": "https://github.com/theseer/tokenizer.git", - "reference": "737eda637ed5e28c3413cb1ebe8bb52cbf1ca7a2" + "reference": "b7489ce515e168639d17feec34b8847c326b0b3c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/theseer/tokenizer/zipball/737eda637ed5e28c3413cb1ebe8bb52cbf1ca7a2", - "reference": "737eda637ed5e28c3413cb1ebe8bb52cbf1ca7a2", + "url": "https://api.github.com/repos/theseer/tokenizer/zipball/b7489ce515e168639d17feec34b8847c326b0b3c", + "reference": "b7489ce515e168639d17feec34b8847c326b0b3c", "shasum": "" }, "require": { @@ -3921,7 +3912,7 @@ "description": "A small library for converting tokenized PHP source code into XML and potentially other formats", "support": { "issues": "https://github.com/theseer/tokenizer/issues", - "source": "https://github.com/theseer/tokenizer/tree/1.2.3" + "source": "https://github.com/theseer/tokenizer/tree/1.3.1" }, "funding": [ { @@ -3929,20 +3920,20 @@ "type": "github" } ], - "time": "2024-03-03T12:36:25+00:00" + "time": "2025-11-17T20:03:58+00:00" }, { "name": "wp-coding-standards/wpcs", - "version": "3.2.0", + "version": "3.3.0", "source": { "type": "git", "url": "https://github.com/WordPress/WordPress-Coding-Standards.git", - "reference": "d2421de7cec3274ae622c22c744de9a62c7925af" + "reference": "7795ec6fa05663d716a549d0b44e47ffc8b0d4a6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/WordPress/WordPress-Coding-Standards/zipball/d2421de7cec3274ae622c22c744de9a62c7925af", - "reference": "d2421de7cec3274ae622c22c744de9a62c7925af", + "url": "https://api.github.com/repos/WordPress/WordPress-Coding-Standards/zipball/7795ec6fa05663d716a549d0b44e47ffc8b0d4a6", + "reference": "7795ec6fa05663d716a549d0b44e47ffc8b0d4a6", "shasum": "" }, "require": { @@ -3950,17 +3941,17 @@ "ext-libxml": "*", "ext-tokenizer": "*", "ext-xmlreader": "*", - "php": ">=5.4", - "phpcsstandards/phpcsextra": "^1.4.0", + "php": ">=7.2", + "phpcsstandards/phpcsextra": "^1.5.0", "phpcsstandards/phpcsutils": "^1.1.0", - "squizlabs/php_codesniffer": "^3.13.0" + "squizlabs/php_codesniffer": "^3.13.4" }, "require-dev": { "php-parallel-lint/php-console-highlighter": "^1.0.0", "php-parallel-lint/php-parallel-lint": "^1.4.0", - "phpcompatibility/php-compatibility": "^9.0", + "phpcompatibility/php-compatibility": "^10.0.0@dev", "phpcsstandards/phpcsdevtools": "^1.2.0", - "phpunit/phpunit": "^4.0 || ^5.0 || ^6.0 || ^7.0 || ^8.0 || ^9.0" + "phpunit/phpunit": "^8.0 || ^9.0" }, "suggest": { "ext-iconv": "For improved results", @@ -3995,7 +3986,7 @@ "type": "custom" } ], - "time": "2025-07-24T20:08:31+00:00" + "time": "2025-11-25T12:08:04+00:00" }, { "name": "wp-phpunit/wp-phpunit", @@ -4047,15 +4038,15 @@ }, { "name": "wpackagist-plugin/plugin-check", - "version": "1.6.0", + "version": "1.7.0", "source": { "type": "svn", "url": "https://plugins.svn.wordpress.org/plugin-check/", - "reference": "tags/1.6.0" + "reference": "tags/1.7.0" }, "dist": { "type": "zip", - "url": "https://downloads.wordpress.org/plugin/plugin-check.1.6.0.zip" + "url": "https://downloads.wordpress.org/plugin/plugin-check.1.7.0.zip" }, "require": { "composer/installers": "^1.0 || ^2.0" @@ -4137,9 +4128,9 @@ ], "minimum-stability": "dev", "stability-flags": { - "phpcompatibility/php-compatibility": 20, "wordpress/mcp-adapter": 20, - "wordpress/wp-ai-client": 20 + "wordpress/wp-ai-client": 20, + "phpcompatibility/php-compatibility": 20 }, "prefer-stable": true, "prefer-lowest": false, @@ -4147,7 +4138,7 @@ "ext-json": "*", "php": ">=7.4" }, - "platform-dev": {}, + "platform-dev": [], "platform-overrides": { "php": "7.4" }, diff --git a/package-lock.json b/package-lock.json index 412c17df..a713de2d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -20,7 +20,9 @@ "@wordpress/icons": "^11.1.0", "@wordpress/notices": "^5.35.0", "@wordpress/plugins": "^7.34.0", - "react": "^18.3.1" + "react": "^18.3.1", + "wp-admin-components": "^1.0.0", + "wp-interface": "^1.0.0" }, "devDependencies": { "@types/react": "^18.2.47", @@ -28,6 +30,7 @@ "@types/wordpress__blocks": "^12.5.18", "@wordpress/env": "^10.34.0", "@wordpress/scripts": "^31.0.0", + "copy-webpack-plugin": "^13.0.1", "typescript": "^5.9.3", "webpack-remove-empty-scripts": "^1.1.1" }, @@ -110,7 +113,6 @@ "version": "7.28.5", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/generator": "^7.28.5", @@ -1865,7 +1867,6 @@ "integrity": "sha512-eohl3hKTiVyD1ilYdw9T0OiB4hnjef89e3dMYKz+mVKDzj+5IteTseASUsOB+EU9Tf6VNTCjDePcP6wkDGmLKQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@keyv/serialize": "^1.1.1" } @@ -1907,7 +1908,6 @@ } ], "license": "MIT", - "peer": true, "engines": { "node": ">=18" }, @@ -1931,7 +1931,6 @@ } ], "license": "MIT", - "peer": true, "engines": { "node": ">=18" } @@ -2105,7 +2104,6 @@ "resolved": "https://registry.npmjs.org/@emotion/react/-/react-11.14.0.tgz", "integrity": "sha512-O000MLDBDdk/EohJPFUqvnp4qnHeYkVP5B0xEG0D/L7cOKP9kefu2DXn8dj74cQfsEzUqh+sr1RzFqiL1o+PpA==", "license": "MIT", - "peer": true, "dependencies": { "@babel/runtime": "^7.18.3", "@emotion/babel-plugin": "^11.13.5", @@ -3457,7 +3455,6 @@ "integrity": "sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg==", "dev": true, "license": "Apache-2.0", - "peer": true, "engines": { "node": ">=8.0.0" } @@ -3481,7 +3478,6 @@ "integrity": "sha512-s5vvxXPVdjqS3kTLKMeBMvop9hbWkwzBpu+mUO2M7sZtlkyDJGwFe33wRKnbaYDo8ExRVBIIdwIGrqpxHuKttA==", "dev": true, "license": "Apache-2.0", - "peer": true, "engines": { "node": ">=14" }, @@ -3495,7 +3491,6 @@ "integrity": "sha512-OOCM2C/QIURhJMuKaekP3TRBxBKxG/TWWA0TL2J6nXUtDnuCtccy49LUJF8xPFXMX+0LMcxFpCo8M9cGY1W6rQ==", "dev": true, "license": "Apache-2.0", - "peer": true, "dependencies": { "@opentelemetry/semantic-conventions": "1.28.0" }, @@ -3978,7 +3973,6 @@ "integrity": "sha512-5UxZqiAgLYGFjS4s9qm5mBVo433u+dSPUFWVWXmLAD4wB65oMCoXaJP1KJa9DIYYMeHu3z4BZcStG3LC593cWA==", "dev": true, "license": "Apache-2.0", - "peer": true, "dependencies": { "@opentelemetry/core": "1.30.1", "@opentelemetry/semantic-conventions": "1.28.0" @@ -4006,7 +4000,6 @@ "integrity": "sha512-jVPgBbH1gCy2Lb7X0AVQ8XAfgg0pJ4nvl8/IiQA6nxOsPvS+0zMJaFSs2ltXe0J6C8dqjcnpyqINDJmU30+uOg==", "dev": true, "license": "Apache-2.0", - "peer": true, "dependencies": { "@opentelemetry/core": "1.30.1", "@opentelemetry/resources": "1.30.1", @@ -4035,7 +4028,6 @@ "integrity": "sha512-kocjix+/sSggfJhwXqClZ3i9Y/MI0fp7b+g7kCRm6psy2dsf8uApTRclwG18h8Avm7C9+fnt+O36PspJ/OzoWg==", "dev": true, "license": "Apache-2.0", - "peer": true, "engines": { "node": ">=14" } @@ -5380,7 +5372,6 @@ "version": "8.1.0", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@babel/core": "^7.21.3", "@svgr/babel-preset": "8.1.0", @@ -5727,7 +5718,6 @@ "version": "9.6.1", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@types/estree": "*", "@types/json-schema": "*" @@ -5953,7 +5943,6 @@ "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.27.tgz", "integrity": "sha512-cisd7gxkzjBKU2GgdYrTdtQx1SORymWyaAFhaxQPK9bYO9ot3Y5OikQRvY0VYQtvwjeQnizCINJAenh/V7MK2w==", "license": "MIT", - "peer": true, "dependencies": { "@types/prop-types": "*", "csstype": "^3.2.2" @@ -5964,7 +5953,6 @@ "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.3.7.tgz", "integrity": "sha512-MEe3UeoENYVFXzoXEWsvcpg6ZvlrFNlOQ7EOsvhI3CfAXwzPfO8Qwuxd40nepsYKqyyVQnTdEfv68q91yLcKrQ==", "license": "MIT", - "peer": true, "peerDependencies": { "@types/react": "^18.0.0" } @@ -6575,7 +6563,6 @@ "integrity": "sha512-LAUYz4lc+Do8/g7aeRa8JkyDErK6ekstQaqWQrNRW//MY1TvCEpMtpTWvlQ+FPbWCx+Xixu/6SHt5N0HR+SB4w==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@babel/runtime": "^7.9.2" } @@ -6680,7 +6667,6 @@ "version": "6.21.0", "dev": true, "license": "BSD-2-Clause", - "peer": true, "dependencies": { "@typescript-eslint/scope-manager": "6.21.0", "@typescript-eslint/types": "6.21.0", @@ -8049,7 +8035,6 @@ "version": "10.34.0", "dev": true, "license": "GPL-2.0-or-later", - "peer": true, "dependencies": { "@inquirer/prompts": "^7.2.0", "chalk": "^4.0.0", @@ -8815,6 +8800,78 @@ "url": "https://opencollective.com/babel" } }, + "node_modules/@wordpress/scripts/node_modules/array-union": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-3.0.1.tgz", + "integrity": "sha512-1OvF9IbWwaeiM9VhzYXVQacMibxpXOMYVNIvMtKRyX9SImBXpKcFr8XvFDeEslCyuH/t6KRt7HEO94AlP8Iatw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@wordpress/scripts/node_modules/copy-webpack-plugin": { + "version": "10.2.4", + "resolved": "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-10.2.4.tgz", + "integrity": "sha512-xFVltahqlsRcyyJqQbDY6EYTtyQZF9rf+JPjwHObLdPFMEISqkFkr7mFoVOC6BfYS/dNThyoQKvziugm+OnwBg==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-glob": "^3.2.7", + "glob-parent": "^6.0.1", + "globby": "^12.0.2", + "normalize-path": "^3.0.0", + "schema-utils": "^4.0.0", + "serialize-javascript": "^6.0.0" + }, + "engines": { + "node": ">= 12.20.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.1.0" + } + }, + "node_modules/@wordpress/scripts/node_modules/globby": { + "version": "12.2.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-12.2.0.tgz", + "integrity": "sha512-wiSuFQLZ+urS9x2gGPl1H5drc5twabmm4m2gTR27XDFyjUHJUNsS8o/2aKyIF6IoBaR630atdher0XJ5g6OMmA==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-union": "^3.0.1", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.7", + "ignore": "^5.1.9", + "merge2": "^1.4.1", + "slash": "^4.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@wordpress/scripts/node_modules/slash": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-4.0.0.tgz", + "integrity": "sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/@wordpress/server-side-render": { "version": "6.11.0", "resolved": "https://registry.npmjs.org/@wordpress/server-side-render/-/server-side-render-6.11.0.tgz", @@ -9060,7 +9117,6 @@ "version": "8.15.0", "dev": true, "license": "MIT", - "peer": true, "bin": { "acorn": "bin/acorn" }, @@ -9140,7 +9196,6 @@ "version": "6.12.6", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -10054,7 +10109,6 @@ } ], "license": "MIT", - "peer": true, "dependencies": { "baseline-browser-mapping": "^2.8.19", "caniuse-lite": "^1.0.30001751", @@ -10903,19 +10957,20 @@ "license": "MIT" }, "node_modules/copy-webpack-plugin": { - "version": "10.2.4", + "version": "13.0.1", + "resolved": "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-13.0.1.tgz", + "integrity": "sha512-J+YV3WfhY6W/Xf9h+J1znYuqTye2xkBUIGyTPWuBAT27qajBa5mR4f8WBmfDY3YjRftT2kqZZiLi1qf0H+UOFw==", "dev": true, "license": "MIT", "dependencies": { - "fast-glob": "^3.2.7", "glob-parent": "^6.0.1", - "globby": "^12.0.2", "normalize-path": "^3.0.0", - "schema-utils": "^4.0.0", - "serialize-javascript": "^6.0.0" + "schema-utils": "^4.2.0", + "serialize-javascript": "^6.0.2", + "tinyglobby": "^0.2.12" }, "engines": { - "node": ">= 12.20.0" + "node": ">= 18.12.0" }, "funding": { "type": "opencollective", @@ -10925,47 +10980,6 @@ "webpack": "^5.1.0" } }, - "node_modules/copy-webpack-plugin/node_modules/array-union": { - "version": "3.0.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/copy-webpack-plugin/node_modules/globby": { - "version": "12.2.0", - "dev": true, - "license": "MIT", - "dependencies": { - "array-union": "^3.0.1", - "dir-glob": "^3.0.1", - "fast-glob": "^3.2.7", - "ignore": "^5.1.9", - "merge2": "^1.4.1", - "slash": "^4.0.0" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/copy-webpack-plugin/node_modules/slash": { - "version": "4.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/core-js": { "version": "3.47.0", "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.47.0.tgz", @@ -11690,8 +11704,7 @@ "node_modules/devtools-protocol": { "version": "0.0.1507524", "dev": true, - "license": "BSD-3-Clause", - "peer": true + "license": "BSD-3-Clause" }, "node_modules/diff": { "version": "4.0.2", @@ -12289,7 +12302,6 @@ "version": "8.57.1", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.6.1", @@ -12344,7 +12356,6 @@ "version": "8.10.2", "dev": true, "license": "MIT", - "peer": true, "bin": { "eslint-config-prettier": "bin/cli.js" }, @@ -12457,7 +12468,6 @@ "version": "2.32.0", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@rtsao/scc": "^1.1.0", "array-includes": "^3.1.9", @@ -15559,7 +15569,6 @@ "version": "29.7.0", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@jest/core": "^29.7.0", "@jest/types": "^29.6.3", @@ -16560,8 +16569,7 @@ "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1521046.tgz", "integrity": "sha512-vhE6eymDQSKWUXwwA37NtTTVEzjtGVfDr3pRbsWEQ5onH/Snp2c+2xZHWJJawG/0hCCJLRGt4xVtEVUVILol4w==", "dev": true, - "license": "BSD-3-Clause", - "peer": true + "license": "BSD-3-Clause" }, "node_modules/lighthouse/node_modules/puppeteer-core/node_modules/ws": { "version": "8.18.3", @@ -17598,7 +17606,6 @@ "integrity": "sha512-cuXAJJB1Rdqz0UO6w524matlBqDBjcNt7Ru+RDIu4y6RI1gVqiWBnylrK8sPRk81gGBA0X8hJbDXolVOoTc+sA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "ajv": "^6.12.6", "ajv-errors": "^1.0.1", @@ -18561,6 +18568,7 @@ "integrity": "sha512-aFi5B0WovBHTEvpM3DzXTUaeN6eN0qWnTkKx4NQaH4Wvcmc153PdaY2UBdSYKaGYw+UyWXSVyxDUg5DoPEttjw==", "dev": true, "license": "Apache-2.0", + "peer": true, "dependencies": { "playwright-core": "1.56.1" }, @@ -18580,6 +18588,7 @@ "integrity": "sha512-hutraynyn31F+Bifme+Ps9Vq59hKuUCz7H1kDOcBs+2oGguKkWTU50bBWrtz34OUWmIwpBTWDxaRPXrIXkgvmQ==", "dev": true, "license": "Apache-2.0", + "peer": true, "bin": { "playwright-core": "cli.js" }, @@ -18598,6 +18607,7 @@ "os": [ "darwin" ], + "peer": true, "engines": { "node": "^8.16.0 || ^10.6.0 || >=11.0.0" } @@ -18643,7 +18653,6 @@ } ], "license": "MIT", - "peer": true, "dependencies": { "nanoid": "^3.3.11", "picocolors": "^1.1.1", @@ -19315,7 +19324,6 @@ "resolved": "https://registry.npmjs.org/preact/-/preact-10.27.2.tgz", "integrity": "sha512-5SYSgFKSyhCbk6SrXyMpqjb5+MQBgfvEKE/OC+PujcY34sOpqtr+0AZQtPYx5IA6VxynQ7rUPCtKzyovpj9Bpg==", "license": "MIT", - "peer": true, "funding": { "type": "opencollective", "url": "https://opencollective.com/preact" @@ -19335,7 +19343,6 @@ "resolved": "https://registry.npmjs.org/wp-prettier/-/wp-prettier-3.0.3.tgz", "integrity": "sha512-X4UlrxDTH8oom9qXlcjnydsjAOD2BmB6yFmvS4Z2zdTzqqpRWb+fbqrH412+l+OUXmbzJlSXjlMFYPgYG12IAA==", "dev": true, - "peer": true, "bin": { "prettier": "bin/prettier.cjs" }, @@ -19680,7 +19687,6 @@ "node_modules/react": { "version": "18.3.1", "license": "MIT", - "peer": true, "dependencies": { "loose-envify": "^1.1.0" }, @@ -19747,7 +19753,6 @@ "node_modules/react-dom": { "version": "18.3.1", "license": "MIT", - "peer": true, "dependencies": { "loose-envify": "^1.1.0", "scheduler": "^0.23.2" @@ -19778,7 +19783,6 @@ "version": "0.14.2", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=0.10.0" } @@ -20001,8 +20005,7 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/redux/-/redux-5.0.1.tgz", "integrity": "sha512-M9/ELqF6fy8FwmkpnF0S3YKOqMyoWJ4+CS5Efg2ct3oY9daQvd/Pc71FpGZsVsbl3Cpb+IIcjBDUnnyBdQbq4w==", - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/reflect.getprototypeof": { "version": "1.0.10", @@ -20041,6 +20044,12 @@ "node": ">=4" } }, + "node_modules/regenerator-runtime": { + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", + "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==", + "license": "MIT" + }, "node_modules/regexp.prototype.flags": { "version": "1.5.4", "dev": true, @@ -20504,7 +20513,6 @@ "version": "1.93.3", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "chokidar": "^4.0.0", "immutable": "^5.0.2", @@ -20599,7 +20607,6 @@ "version": "8.17.1", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "fast-deep-equal": "^3.1.3", "fast-uri": "^3.0.1", @@ -21963,7 +21970,6 @@ } ], "license": "MIT", - "peer": true, "dependencies": { "@csstools/css-parser-algorithms": "^3.0.5", "@csstools/css-tokenizer": "^3.0.4", @@ -22299,7 +22305,6 @@ "integrity": "sha512-8sLjZwK0R+JlxlYcTuVnyT2v+htpdrjDOKuMcOVdYjt52Lh8hWRYpxBPoKx/Zg+bcjc3wx6fmQevMmUztS/ccA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" @@ -22820,7 +22825,6 @@ "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=12" }, @@ -22997,8 +23001,7 @@ }, "node_modules/tslib": { "version": "2.8.1", - "license": "0BSD", - "peer": true + "license": "0BSD" }, "node_modules/tsutils": { "version": "3.21.0", @@ -23042,7 +23045,6 @@ "version": "0.20.2", "dev": true, "license": "(MIT OR CC0-1.0)", - "peer": true, "engines": { "node": ">=10" }, @@ -23148,7 +23150,6 @@ "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", "dev": true, "license": "Apache-2.0", - "peer": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -23251,7 +23252,6 @@ "dev": true, "hasInstallScript": true, "license": "MIT", - "peer": true, "dependencies": { "napi-postinstall": "^0.3.0" }, @@ -23622,7 +23622,6 @@ "version": "5.102.1", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@types/eslint-scope": "^3.7.7", "@types/estree": "^1.0.8", @@ -23723,7 +23722,6 @@ "version": "5.1.4", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@discoveryjs/json-ext": "^0.5.0", "@webpack-cli/configtest": "^2.1.1", @@ -23823,7 +23821,6 @@ "version": "5.2.2", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@types/bonjour": "^3.5.13", "@types/connect-history-api-fallback": "^1.5.4", @@ -24222,6 +24219,145 @@ "node": ">=0.10.0" } }, + "node_modules/wp-admin-components": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/wp-admin-components/-/wp-admin-components-1.0.0.tgz", + "integrity": "sha512-6sFAD/5GfU3vFHdi2BHE2wPLRiswtoXthOYd1ZCUkIG8nLigVQ73GuP3fUwz+CKSmfvEMnvKt/ua6/gaNzBG3w==", + "license": "GPL-2.0-or-later", + "dependencies": { + "@ariakit/react": "^0.4.15", + "@emotion/styled": "^11.6.0", + "@wordpress/a11y": "^4.35.0", + "@wordpress/components": "^30.8.0", + "@wordpress/compose": "^7.35.0", + "@wordpress/element": "^6.35.0", + "@wordpress/i18n": "^6.8.0", + "clsx": "^2.1.1", + "wp-component-utils": "^1.0.0" + }, + "engines": { + "node": ">=20.0.0" + }, + "peerDependencies": { + "react": "^18.0.0", + "react-dom": "^18.0.0" + } + }, + "node_modules/wp-component-utils": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/wp-component-utils/-/wp-component-utils-1.0.0.tgz", + "integrity": "sha512-kD3yYsOAvIyJcto2K8dmUUcoTUcRBAIZlagXPiTsfhYKUUqo0TtCtBsZpVSOGMUShkgMpH4yJIPzm5tREHeVLQ==", + "license": "GPL-2.0-or-later", + "dependencies": { + "@wordpress/components": "^30.8.0" + }, + "engines": { + "node": ">=20.0.0" + }, + "peerDependencies": { + "react": "^18.0.0", + "react-dom": "^18.0.0" + } + }, + "node_modules/wp-interface": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/wp-interface/-/wp-interface-1.0.0.tgz", + "integrity": "sha512-2J4qsA1KiMVr7wgNcrGCsKpsQCp11sMEdR5BT4mkFSX77rKww2tTpV2aIR0n52Aji7ExxZU1YVh/fL4xq1Qyqw==", + "license": "GPL-2.0-or-later", + "dependencies": { + "@wordpress/components": "^30.8.0", + "@wordpress/compose": "^7.35.0", + "@wordpress/data": "^10.35.0", + "@wordpress/element": "^6.35.0", + "@wordpress/icons": "^11.2.0", + "@wordpress/interface": "9.17.0", + "@wordpress/keyboard-shortcuts": "^5.35.0", + "@wordpress/keycodes": "^4.35.0", + "@wordpress/notices": "^5.35.0", + "@wordpress/preferences": "^4.35.0", + "clsx": "^2.1.1", + "wp-store-utils": "^1.0.0" + }, + "engines": { + "node": ">=20.0.0" + }, + "peerDependencies": { + "react": "^18.0.0", + "react-dom": "^18.0.0" + } + }, + "node_modules/wp-interface/node_modules/@babel/runtime": { + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.25.7.tgz", + "integrity": "sha512-FjoyLe754PMiYsFaN5C94ttGiOmBNYTf6pLr4xXHAT5uctHb092PBszndLDR5XA/jghQvn4n7JMHl7dmTgbm9w==", + "license": "MIT", + "dependencies": { + "regenerator-runtime": "^0.14.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/wp-interface/node_modules/@wordpress/interface": { + "version": "9.17.0", + "resolved": "https://registry.npmjs.org/@wordpress/interface/-/interface-9.17.0.tgz", + "integrity": "sha512-Y0jS2iNEAVC+1JlKjRwOyMEnFKmaSPehUZNnm2VsvTJIT4/W4GuQxOAE4GaEWa2+2aG7Jrr+NcH+HZOUXPdCEA==", + "license": "GPL-2.0-or-later", + "dependencies": { + "@babel/runtime": "7.25.7", + "@wordpress/a11y": "^4.32.0", + "@wordpress/components": "^30.5.0", + "@wordpress/compose": "^7.32.0", + "@wordpress/data": "^10.32.0", + "@wordpress/deprecated": "^4.32.0", + "@wordpress/element": "^6.32.0", + "@wordpress/i18n": "^6.5.0", + "@wordpress/icons": "^10.32.0", + "@wordpress/plugins": "^7.32.0", + "@wordpress/preferences": "^4.32.0", + "@wordpress/viewport": "^6.32.0", + "clsx": "^2.1.1" + }, + "engines": { + "node": ">=18.12.0", + "npm": ">=8.19.2" + }, + "peerDependencies": { + "react": "^18.0.0", + "react-dom": "^18.0.0" + } + }, + "node_modules/wp-interface/node_modules/@wordpress/interface/node_modules/@wordpress/icons": { + "version": "10.32.0", + "resolved": "https://registry.npmjs.org/@wordpress/icons/-/icons-10.32.0.tgz", + "integrity": "sha512-1WvJdT361X1LnetYBpBWUjAVXZzl+pBdIwHbYRAp8ej47EI/igPmNxmq81nFd40s8fer/9qtipielcqSI6H2rA==", + "license": "GPL-2.0-or-later", + "dependencies": { + "@babel/runtime": "7.25.7", + "@wordpress/element": "^6.32.0", + "@wordpress/primitives": "^4.32.0" + }, + "engines": { + "node": ">=18.12.0", + "npm": ">=8.19.2" + } + }, + "node_modules/wp-store-utils": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/wp-store-utils/-/wp-store-utils-1.0.0.tgz", + "integrity": "sha512-J2D/IaYn4R1X8zPseUKWnVrI3cghg76TVBY0uHlZrJNWI8anAGIH5ttdXLSlF2s0JrwNt9PxU5jOEuW8mApkLA==", + "license": "GPL-2.0-or-later", + "dependencies": { + "@wordpress/data": "^10.35.0" + }, + "engines": { + "node": ">=20.0.0" + }, + "peerDependencies": { + "react": "^18.0.0", + "react-dom": "^18.0.0" + } + }, "node_modules/wrap-ansi": { "version": "6.2.0", "dev": true, @@ -24484,7 +24620,6 @@ "resolved": "https://registry.npmjs.org/yjs/-/yjs-13.6.27.tgz", "integrity": "sha512-OIDwaflOaq4wC6YlPBy2L6ceKeKuF7DeTxx+jPzv1FHn9tCZ0ZwSRnUBxD05E3yed46fv/FWJbvR+Ud7x0L7zw==", "license": "MIT", - "peer": true, "dependencies": { "lib0": "^0.2.99" }, diff --git a/package.json b/package.json index fb8b80fd..8cf30f59 100644 --- a/package.json +++ b/package.json @@ -34,6 +34,7 @@ "@types/wordpress__blocks": "^12.5.18", "@wordpress/env": "^10.34.0", "@wordpress/scripts": "^31.0.0", + "copy-webpack-plugin": "^13.0.1", "typescript": "^5.9.3", "webpack-remove-empty-scripts": "^1.1.1" }, @@ -49,7 +50,9 @@ "@wordpress/icons": "^11.1.0", "@wordpress/notices": "^5.35.0", "@wordpress/plugins": "^7.34.0", - "react": "^18.3.1" + "react": "^18.3.1", + "wp-admin-components": "^1.0.0", + "wp-interface": "^1.0.0" }, "overrides": { "webpack-dev-server@<=5.2.0": ">=5.2.1" diff --git a/webpack.config.js b/webpack.config.js index 49a296e9..681367b3 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -6,6 +6,7 @@ const defaultConfig = require( '@wordpress/scripts/config/webpack.config' ); /** * External dependencies */ +const CopyWebpackPlugin = require( 'copy-webpack-plugin' ); const RemoveEmptyScriptsPlugin = require( 'webpack-remove-empty-scripts' ); const path = require( 'path' ); @@ -35,6 +36,32 @@ module.exports = { // Include WP's plugin config. ...defaultConfig.plugins, + // Copy build styles from external packages. + new CopyWebpackPlugin( { + patterns: [ + { + from: path.resolve( + __dirname, + 'node_modules/wp-admin-components/build-style' + ), + to: path.resolve( + __dirname, + 'build/external/wp-admin-components' + ), + }, + { + from: path.resolve( + __dirname, + 'node_modules/wp-interface/build-style' + ), + to: path.resolve( + __dirname, + 'build/external/wp-interface' + ), + }, + ], + } ), + // Removes the empty `.js` files generated by webpack but // sets it after WP has generated its `*.asset.php` file. new RemoveEmptyScriptsPlugin( { From dd46ddcd8b5ba8f87cc42a015a417c58ec4f928b Mon Sep 17 00:00:00 2001 From: Felix Arntz Date: Sat, 29 Nov 2025 17:38:19 -0800 Subject: [PATCH 02/14] Fix bugs in Asset_Loader. --- includes/Asset_Loader.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/includes/Asset_Loader.php b/includes/Asset_Loader.php index 535116a7..05c204cf 100644 --- a/includes/Asset_Loader.php +++ b/includes/Asset_Loader.php @@ -38,7 +38,7 @@ class Asset_Loader { public static function enqueue_script( string $handle, string $file_name ): void { $script_path = AI_EXPERIMENTS_DIR . 'build/' . $file_name . '.js'; $script_url = AI_EXPERIMENTS_PLUGIN_URL . 'build/' . $file_name . '.js'; - $script_asset_path = $script_path . '.asset.php'; + $script_asset_path = substr( $script_path, 0, -3 ) . '.asset.php'; if ( file_exists( $script_asset_path ) ) { $asset_data = require $script_asset_path; // phpcs:ignore WordPressVIPMinimum.Files.IncludingFile.UsingVariable @@ -69,7 +69,7 @@ public static function enqueue_script( string $handle, string $file_name ): void public static function enqueue_style( string $handle, string $file_name ): void { $style_path = AI_EXPERIMENTS_DIR . 'build/' . $file_name . '.css'; $style_url = AI_EXPERIMENTS_PLUGIN_URL . 'build/' . $file_name . '.css'; - $style_asset_path = $style_path . '.asset.php'; + $style_asset_path = substr( $style_path, 0, -4 ) . '.asset.php'; if ( file_exists( $style_asset_path ) ) { $asset_data = require $style_asset_path; // phpcs:ignore WordPressVIPMinimum.Files.IncludingFile.UsingVariable From d29b59641034bf4aa0fd8d75fd1e56ea9efbce4a Mon Sep 17 00:00:00 2001 From: Felix Arntz Date: Sat, 29 Nov 2025 17:38:44 -0800 Subject: [PATCH 03/14] Scaffold AI Playground screen. --- includes/Experiment_Loader.php | 1 + .../AI_Playground/AI_Playground.php | 125 ++++++++++++++++++ .../components/PlaygroundApp/index.tsx | 112 ++++++++++++++++ .../components/PlaygroundApp/style.scss | 7 + src/experiments/ai-playground/index.tsx | 33 +++++ webpack.config.js | 5 + 6 files changed, 283 insertions(+) create mode 100644 includes/Experiments/AI_Playground/AI_Playground.php create mode 100644 src/experiments/ai-playground/components/PlaygroundApp/index.tsx create mode 100644 src/experiments/ai-playground/components/PlaygroundApp/style.scss create mode 100644 src/experiments/ai-playground/index.tsx diff --git a/includes/Experiment_Loader.php b/includes/Experiment_Loader.php index 53803b59..cf327c64 100644 --- a/includes/Experiment_Loader.php +++ b/includes/Experiment_Loader.php @@ -106,6 +106,7 @@ private function get_default_experiments(): array { $experiment_classes = array( \WordPress\AI\Experiments\Example_Experiment\Example_Experiment::class, \WordPress\AI\Experiments\Title_Generation\Title_Generation::class, + \WordPress\AI\Experiments\AI_Playground\AI_Playground::class, ); /** diff --git a/includes/Experiments/AI_Playground/AI_Playground.php b/includes/Experiments/AI_Playground/AI_Playground.php new file mode 100644 index 00000000..2d74240f --- /dev/null +++ b/includes/Experiments/AI_Playground/AI_Playground.php @@ -0,0 +1,125 @@ + 'ai-playground', + 'label' => __( 'AI Playground', 'ai' ), + 'description' => __( 'Adds a playground UI to explore prompting AI models directly', 'ai' ), + ); + } + + /** + * {@inheritDoc} + * + * @since n.e.x.t + */ + public function register(): void { + add_action( 'admin_menu', array( $this, 'add_playground_screen' ) ); + } + + /** + * Adds the AI Playground admin screen. + * + * @since n.e.x.t + */ + public function add_playground_screen(): void { + $hook_suffix = add_management_page( + __( 'AI Playground', 'ai' ), + __( 'AI Playground', 'ai' ), + 'manage_options', + 'ai-playground', + array( $this, 'render_playground_screen' ) + ); + + add_action( "load-$hook_suffix", array( $this, 'load_playground_screen' ) ); + } + + /** + * Loads the AI Playground admin screen. + * + * @since n.e.x.t + */ + public function load_playground_screen(): void { + add_filter( + 'admin_body_class', + static function ( $classes ) { + return "$classes remove-screen-spacing"; + } + ); + + add_action( + 'admin_notices', + static function () { + remove_all_actions( 'admin_notices' ); + }, + -9999 + ); + + add_action( + 'admin_enqueue_scripts', + function (): void { + // Enqueue the WordPress AI Client. + wp_enqueue_script( 'wp-ai-client' ); + + // Enqueue foundational stylesheets for the UI. + wp_enqueue_style( + 'ai_wp-interface', + AI_EXPERIMENTS_PLUGIN_URL . 'build/external/wp-interface/style.css', + array( 'wp-components', 'wp-editor' ), + '1.0.0' + ); + wp_style_add_data( 'ai_wp-interface', 'rtl', 'replace' ); + wp_enqueue_style( + 'ai_wp-admin-components', + AI_EXPERIMENTS_PLUGIN_URL . 'build/external/wp-admin-components/style.css', + array( 'wp-components' ), + '1.0.0' + ); + wp_style_add_data( 'ai_wp-admin-components', 'rtl', 'replace' ); + + // Enqueue AI Playground assets. + Asset_Loader::enqueue_script( 'playground', 'experiments/ai-playground' ); + Asset_Loader::enqueue_style( 'playground', 'experiments/style-ai-playground' ); + } + ); + } + + /** + * Renders the AI Playground admin screen. + * + * @since n.e.x.t + */ + public function render_playground_screen(): void { + ?> +
+ +
+ +
+

{ __( 'AI Playground', 'ai' ) }

+ + + + + { () => ( + <> + + + + + + + { __( 'Learn more', 'ai' ) } + + + + ) } + + +
+ +
+

{ __( 'Main content goes here.', 'ai' ) }

+
+ + +

{ __( 'Sidebar content goes here.', 'ai' ) }

+
+ +
+

{ __( 'Version 1.0', 'ai' ) }

+
+ + ); +} diff --git a/src/experiments/ai-playground/components/PlaygroundApp/style.scss b/src/experiments/ai-playground/components/PlaygroundApp/style.scss new file mode 100644 index 00000000..5aeb6dea --- /dev/null +++ b/src/experiments/ai-playground/components/PlaygroundApp/style.scss @@ -0,0 +1,7 @@ +.wp-interface-header__right { + + .components-button:disabled, + .components-button[aria-disabled="true"] { + cursor: not-allowed; + } +} diff --git a/src/experiments/ai-playground/index.tsx b/src/experiments/ai-playground/index.tsx new file mode 100644 index 00000000..ff44cf79 --- /dev/null +++ b/src/experiments/ai-playground/index.tsx @@ -0,0 +1,33 @@ +/** + * WordPress dependencies + */ +import domReady from '@wordpress/dom-ready'; +import { createRoot } from '@wordpress/element'; + +/** + * Internal dependencies + */ +import PlaygroundApp from './components/PlaygroundApp'; + +/** + * Mounts the given component into the DOM. + * + * @since 0.4.0 + * + * @param jsx - The JSX node to be mounted. + * @param renderTarget - The target element to render the JSX into. + */ +function mountApp( jsx: JSX.Element, renderTarget: Element ) { + const root = createRoot( renderTarget ); + root.render( jsx ); +} + +// Initialize the app once the DOM is ready. +domReady( () => { + const renderTarget = document.getElementById( 'ai-playground-root' ); + if ( ! renderTarget ) { + return; + } + + mountApp( , renderTarget ); +} ); diff --git a/webpack.config.js b/webpack.config.js index 681367b3..932dd9a5 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -30,6 +30,11 @@ module.exports = { 'src/experiments/title-generation', 'index.tsx' ), + 'experiments/ai-playground': path.resolve( + process.cwd(), + 'src/experiments/ai-playground', + 'index.tsx' + ), }, plugins: [ From 41a7119557cb2cf226a7e1608da6187ca5cd49e8 Mon Sep 17 00:00:00 2001 From: Felix Arntz Date: Mon, 1 Dec 2025 15:03:08 -0800 Subject: [PATCH 04/14] Port over AI Playground implementation (with a few omissions) from AI Services. --- package-lock.json | 33 +- package.json | 5 +- .../ai-playground/ai-client-enums.ts | 94 ++ .../ai-playground/ai-client-types.ts | 152 +++ .../components/PlaygroundApp/index.tsx | 63 +- .../PlaygroundApp/reset-messages-button.tsx | 70 ++ .../system-instruction-toggle.tsx | 80 ++ .../PlaygroundCapabilitiesPanel/index.tsx | 117 +++ .../components/PlaygroundMain/index.tsx | 24 + .../components/PlaygroundMain/input.tsx | 404 ++++++++ .../components/PlaygroundMain/loader.tsx | 62 ++ .../components/PlaygroundMain/media-modal.tsx | 96 ++ .../PlaygroundMain/message-parts.tsx | 151 +++ .../components/PlaygroundMain/messages.tsx | 224 +++++ .../components/PlaygroundMain/style.scss | 397 ++++++++ .../PlaygroundMain/system-instruction.tsx | 55 ++ .../PlaygroundModelConfigPanel/index.tsx | 232 +++++ .../components/PlaygroundMoreMenu/index.tsx | 100 ++ .../PlaygroundProviderModelPanel/index.tsx | 207 ++++ .../components/PlaygroundStatus/index.tsx | 144 +++ src/experiments/ai-playground/helpers.ts | 136 +++ src/experiments/ai-playground/index.tsx | 2 +- .../ai-playground/store/capabilities.ts | 356 +++++++ src/experiments/ai-playground/store/index.ts | 26 + .../ai-playground/store/messages.ts | 888 ++++++++++++++++++ src/experiments/ai-playground/store/name.ts | 1 + .../ai-playground/store/service-model.ts | 409 ++++++++ src/experiments/ai-playground/types.ts | 64 ++ 28 files changed, 4552 insertions(+), 40 deletions(-) create mode 100644 src/experiments/ai-playground/ai-client-enums.ts create mode 100644 src/experiments/ai-playground/ai-client-types.ts create mode 100644 src/experiments/ai-playground/components/PlaygroundApp/reset-messages-button.tsx create mode 100644 src/experiments/ai-playground/components/PlaygroundApp/system-instruction-toggle.tsx create mode 100644 src/experiments/ai-playground/components/PlaygroundCapabilitiesPanel/index.tsx create mode 100644 src/experiments/ai-playground/components/PlaygroundMain/index.tsx create mode 100644 src/experiments/ai-playground/components/PlaygroundMain/input.tsx create mode 100644 src/experiments/ai-playground/components/PlaygroundMain/loader.tsx create mode 100644 src/experiments/ai-playground/components/PlaygroundMain/media-modal.tsx create mode 100644 src/experiments/ai-playground/components/PlaygroundMain/message-parts.tsx create mode 100644 src/experiments/ai-playground/components/PlaygroundMain/messages.tsx create mode 100644 src/experiments/ai-playground/components/PlaygroundMain/style.scss create mode 100644 src/experiments/ai-playground/components/PlaygroundMain/system-instruction.tsx create mode 100644 src/experiments/ai-playground/components/PlaygroundModelConfigPanel/index.tsx create mode 100644 src/experiments/ai-playground/components/PlaygroundMoreMenu/index.tsx create mode 100644 src/experiments/ai-playground/components/PlaygroundProviderModelPanel/index.tsx create mode 100644 src/experiments/ai-playground/components/PlaygroundStatus/index.tsx create mode 100644 src/experiments/ai-playground/helpers.ts create mode 100644 src/experiments/ai-playground/store/capabilities.ts create mode 100644 src/experiments/ai-playground/store/index.ts create mode 100644 src/experiments/ai-playground/store/messages.ts create mode 100644 src/experiments/ai-playground/store/name.ts create mode 100644 src/experiments/ai-playground/store/service-model.ts create mode 100644 src/experiments/ai-playground/types.ts diff --git a/package-lock.json b/package-lock.json index a713de2d..29a41ed9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -20,9 +20,12 @@ "@wordpress/icons": "^11.1.0", "@wordpress/notices": "^5.35.0", "@wordpress/plugins": "^7.34.0", + "markdown-to-jsx": "^9.3.0", + "memize": "^2.1.1", "react": "^18.3.1", "wp-admin-components": "^1.0.0", - "wp-interface": "^1.0.0" + "wp-interface": "^1.0.0", + "wp-store-utils": "^1.0.0" }, "devDependencies": { "@types/react": "^18.2.47", @@ -16896,6 +16899,34 @@ "url": "https://github.com/fb55/entities?sponsor=1" } }, + "node_modules/markdown-to-jsx": { + "version": "9.3.0", + "resolved": "https://registry.npmjs.org/markdown-to-jsx/-/markdown-to-jsx-9.3.0.tgz", + "integrity": "sha512-IlO9RkgpuCsd41eYLOW03qyh2zhSry7W3IPZNsAstgyd8KtmmW+D98JGyTPcJFQohTu4UVVqtiyg6sjLY4NDOQ==", + "license": "MIT", + "engines": { + "node": ">= 18" + }, + "peerDependencies": { + "react": ">= 16.0.0", + "solid-js": ">=1.0.0", + "vue": ">=3.0.0" + }, + "peerDependenciesMeta": { + "react": { + "optional": true + }, + "react-native": { + "optional": true + }, + "solid-js": { + "optional": true + }, + "vue": { + "optional": true + } + } + }, "node_modules/markdownlint": { "version": "0.25.1", "dev": true, diff --git a/package.json b/package.json index 8cf30f59..627c42c0 100644 --- a/package.json +++ b/package.json @@ -50,9 +50,12 @@ "@wordpress/icons": "^11.1.0", "@wordpress/notices": "^5.35.0", "@wordpress/plugins": "^7.34.0", + "markdown-to-jsx": "^9.3.0", + "memize": "^2.1.1", "react": "^18.3.1", "wp-admin-components": "^1.0.0", - "wp-interface": "^1.0.0" + "wp-interface": "^1.0.0", + "wp-store-utils": "^1.0.0" }, "overrides": { "webpack-dev-server@<=5.2.0": ">=5.2.1" diff --git a/src/experiments/ai-playground/ai-client-enums.ts b/src/experiments/ai-playground/ai-client-enums.ts new file mode 100644 index 00000000..34db7f3c --- /dev/null +++ b/src/experiments/ai-playground/ai-client-enums.ts @@ -0,0 +1,94 @@ +/** + * This is a copy of the `src/enums.ts` file of the WordPress AI Client. + * + * This is TEMPORARY. Eventually it should come from that package directly. + */ + +export const FileType = { + INLINE: 'inline', + REMOTE: 'remote', +} as const; +export type FileType = ( typeof FileType )[ keyof typeof FileType ]; + +export const MediaOrientation = { + SQUARE: 'square', + LANDSCAPE: 'landscape', + PORTRAIT: 'portrait', +} as const; +export type MediaOrientation = + ( typeof MediaOrientation )[ keyof typeof MediaOrientation ]; + +export const FinishReason = { + STOP: 'stop', + LENGTH: 'length', + CONTENT_FILTER: 'content_filter', + TOOL_CALLS: 'tool_calls', + ERROR: 'error', +} as const; +export type FinishReason = ( typeof FinishReason )[ keyof typeof FinishReason ]; + +export const OperationState = { + STARTING: 'starting', + PROCESSING: 'processing', + SUCCEEDED: 'succeeded', + FAILED: 'failed', + CANCELED: 'canceled', +} as const; +export type OperationState = + ( typeof OperationState )[ keyof typeof OperationState ]; + +export const ToolType = { + FUNCTION_DECLARATIONS: 'function_declarations', + WEB_SEARCH: 'web_search', +} as const; +export type ToolType = ( typeof ToolType )[ keyof typeof ToolType ]; + +export const ProviderType = { + CLOUD: 'cloud', + SERVER: 'server', + CLIENT: 'client', +} as const; +export type ProviderType = ( typeof ProviderType )[ keyof typeof ProviderType ]; + +export const MessagePartType = { + TEXT: 'text', + FILE: 'file', + FUNCTION_CALL: 'function_call', + FUNCTION_RESPONSE: 'function_response', +} as const; +export type MessagePartType = + ( typeof MessagePartType )[ keyof typeof MessagePartType ]; + +export const MessagePartChannel = { + CONTENT: 'content', + THOUGHT: 'thought', +} as const; +export type MessagePartChannel = + ( typeof MessagePartChannel )[ keyof typeof MessagePartChannel ]; + +export const Modality = { + TEXT: 'text', + DOCUMENT: 'document', + IMAGE: 'image', + AUDIO: 'audio', + VIDEO: 'video', +} as const; +export type Modality = ( typeof Modality )[ keyof typeof Modality ]; + +export const MessageRole = { + USER: 'user', + MODEL: 'model', +} as const; +export type MessageRole = ( typeof MessageRole )[ keyof typeof MessageRole ]; + +export const Capability = { + TEXT_GENERATION: 'text_generation', + IMAGE_GENERATION: 'image_generation', + TEXT_TO_SPEECH_CONVERSION: 'text_to_speech_conversion', + SPEECH_GENERATION: 'speech_generation', + MUSIC_GENERATION: 'music_generation', + VIDEO_GENERATION: 'video_generation', + EMBEDDING_GENERATION: 'embedding_generation', + CHAT_HISTORY: 'chat_history', +} as const; +export type Capability = ( typeof Capability )[ keyof typeof Capability ]; diff --git a/src/experiments/ai-playground/ai-client-types.ts b/src/experiments/ai-playground/ai-client-types.ts new file mode 100644 index 00000000..77e6cfa5 --- /dev/null +++ b/src/experiments/ai-playground/ai-client-types.ts @@ -0,0 +1,152 @@ +/** + * This is a copy of the `src/types.ts` file of the WordPress AI Client. + * + * This is TEMPORARY. Eventually it should come from that package directly. + */ + +/** + * Internal dependencies + */ +import type { + FileType, + FinishReason, + MessagePartChannel, + MessagePartType, + MessageRole, + OperationState, + ProviderType, + MediaOrientation, + Modality, +} from './ai-client-enums'; + +export type File = { + fileType: FileType; + mimeType: string; + url?: string; + base64Data?: string; +}; + +export type TokenUsage = { + promptTokens: number; + completionTokens: number; + totalTokens: number; +}; + +export type ProviderMetadata = { + id: string; + name: string; + type: ProviderType; + credentialsUrl?: string; +}; + +export type SupportedOption = { + name: string; + supportedValues?: unknown[]; +}; + +export type ModelMetadata = { + id: string; + name: string; + supportedCapabilities: string[]; + supportedOptions: SupportedOption[]; +}; + +export type FunctionCall = { + id?: string; + name?: string; + args?: unknown; +}; + +export type FunctionResponse = { + id: string; + name: string; + response: unknown; +}; + +export type MessagePart = + | { + channel: MessagePartChannel; + type: typeof MessagePartType.TEXT; + text: string; + } + | { + channel: MessagePartChannel; + type: typeof MessagePartType.FILE; + file: File; + } + | { + channel: MessagePartChannel; + type: typeof MessagePartType.FUNCTION_CALL; + functionCall: FunctionCall; + } + | { + channel: MessagePartChannel; + type: typeof MessagePartType.FUNCTION_RESPONSE; + functionResponse: FunctionResponse; + }; + +export type Message = { + role: MessageRole; + parts: MessagePart[]; +}; + +export type Candidate = { + message: Message; + finishReason: FinishReason; +}; + +export type GenerativeAiResult = { + id: string; + candidates: Candidate[]; + tokenUsage: TokenUsage; + providerMetadata: ProviderMetadata; + modelMetadata: ModelMetadata; + additionalData?: Record< string, unknown >; +}; + +export type GenerativeAiOperation = { + id: string; + state: OperationState; + result?: GenerativeAiResult; +}; + +export type FunctionDeclaration = { + name: string; + description: string; + parameters?: Record< string, unknown >; +}; + +export type WebSearch = { + allowedDomains?: string[]; + disallowedDomains?: string[]; +}; + +export type ModelConfig = { + outputModalities?: Modality[]; + systemInstruction?: string; + candidateCount?: number; + maxTokens?: number; + temperature?: number; + topP?: number; + topK?: number; + stopSequences?: string[]; + presencePenalty?: number; + frequencyPenalty?: number; + logprobs?: boolean; + topLogprobs?: number; + functionDeclarations?: FunctionDeclaration[]; + webSearch?: WebSearch; + outputFileType?: FileType; + outputMimeType?: string; + outputSchema?: Record< string, unknown >; + outputMediaOrientation?: MediaOrientation; + outputMediaAspectRatio?: string; + outputSpeechVoice?: string; + customOptions?: Record< string, unknown >; +}; + +export type RequestOptions = { + timeout?: number; + connectTimeout?: number; + maxRedirects?: number; +}; diff --git a/src/experiments/ai-playground/components/PlaygroundApp/index.tsx b/src/experiments/ai-playground/components/PlaygroundApp/index.tsx index aeeba46a..05339a05 100644 --- a/src/experiments/ai-playground/components/PlaygroundApp/index.tsx +++ b/src/experiments/ai-playground/components/PlaygroundApp/index.tsx @@ -5,22 +5,28 @@ import { App, Header, HeaderActions, - PinnedSidebars, - MoreMenu, - Sidebar, Footer, + Sidebar, + PinnedSidebars, } from 'wp-interface'; /** * WordPress dependencies */ -import { Button } from '@wordpress/components'; -import { __, _x, isRTL } from '@wordpress/i18n'; +import { __, isRTL } from '@wordpress/i18n'; import { drawerLeft, drawerRight } from '@wordpress/icons'; /** * Internal dependencies */ +import PlaygroundMoreMenu from '../PlaygroundMoreMenu'; +import PlaygroundStatus from '../PlaygroundStatus'; +import PlaygroundMain from '../PlaygroundMain'; +import PlaygroundCapabilitiesPanel from '../PlaygroundCapabilitiesPanel'; +import PlaygroundProviderModelPanel from '../PlaygroundProviderModelPanel'; +import PlaygroundModelConfigPanel from '../PlaygroundModelConfigPanel'; +import SystemInstructionToggle from './system-instruction-toggle'; +import ResetMessagesButton from './reset-messages-button'; import './style.scss'; /** @@ -65,47 +71,30 @@ export default function PlaygroundApp() {

{ __( 'AI Playground', 'ai' ) }

- + + - - { () => ( - <> - - - - - - - { __( 'Learn more', 'ai' ) } - - - - ) } - +
- -
-

{ __( 'Main content goes here.', 'ai' ) }

-
- + + { __( 'AI Configuration', 'ai' ) } + + } isActiveByDefault > -

{ __( 'Sidebar content goes here.', 'ai' ) }

+ + +
-
-

{ __( 'Version 1.0', 'ai' ) }

+
); diff --git a/src/experiments/ai-playground/components/PlaygroundApp/reset-messages-button.tsx b/src/experiments/ai-playground/components/PlaygroundApp/reset-messages-button.tsx new file mode 100644 index 00000000..12de486d --- /dev/null +++ b/src/experiments/ai-playground/components/PlaygroundApp/reset-messages-button.tsx @@ -0,0 +1,70 @@ +/** + * WordPress dependencies + */ +import { + Button, + // eslint-disable-next-line @wordpress/no-unsafe-wp-apis + __experimentalConfirmDialog as ConfirmDialog, +} from '@wordpress/components'; +import { useSelect, useDispatch } from '@wordpress/data'; +import { useState } from '@wordpress/element'; +import { __ } from '@wordpress/i18n'; + +/** + * Internal dependencies + */ +import { store as playgroundStore } from '../../store'; + +/** + * Renders the reset messages button. + * + * @since n.e.x.t + * + * @return The component to be rendered. + */ +export default function ResetMessagesButton() { + const [ isConfirmDialogVisible, setIsConfirmDialogVisible ] = + useState< boolean >( false ); + + const messages = useSelect( + ( select ) => select( playgroundStore ).getMessages(), + [] + ); + const disabled = messages.length === 0; + + const { resetMessages } = useDispatch( playgroundStore ); + + return ( + <> + + { isConfirmDialogVisible && ( + { + resetMessages(); + setIsConfirmDialogVisible( false ); + } } + onCancel={ () => setIsConfirmDialogVisible( false ) } + confirmButtonText={ __( 'Delete', 'ai' ) } + size="medium" + > + { __( + 'Are you sure you want to reset all messages? You will not be able to recover them.', + 'ai' + ) } + + ) } + + ); +} diff --git a/src/experiments/ai-playground/components/PlaygroundApp/system-instruction-toggle.tsx b/src/experiments/ai-playground/components/PlaygroundApp/system-instruction-toggle.tsx new file mode 100644 index 00000000..1423c3fd --- /dev/null +++ b/src/experiments/ai-playground/components/PlaygroundApp/system-instruction-toggle.tsx @@ -0,0 +1,80 @@ +/** + * WordPress dependencies + */ +import { Button } from '@wordpress/components'; +import { useSelect, useDispatch } from '@wordpress/data'; +import { useEffect } from '@wordpress/element'; +import { __ } from '@wordpress/i18n'; +import { preformatted } from '@wordpress/icons'; +import { + useShortcut, + store as keyboardShortcutsStore, +} from '@wordpress/keyboard-shortcuts'; + +/** + * Internal dependencies + */ +import { store as playgroundStore } from '../../store'; + +/** + * Renders the system instruction toggle button. + * + * @since n.e.x.t + * + * @return The component to be rendered. + */ +export default function SystemInstructionToggle() { + const { registerShortcut } = useDispatch( keyboardShortcutsStore ); + useEffect( () => { + registerShortcut( { + name: 'ai/toggle-system-instruction', + category: 'global', + description: __( 'Show or hide the system instruction.', 'ai' ), + keyCombination: { + modifier: 'primaryShift', + character: '.', + }, + } ); + }, [ registerShortcut ] ); + + const isSystemInstructionVisible = useSelect( + ( select ) => select( playgroundStore ).isSystemInstructionVisible(), + [] + ); + + const { showSystemInstruction, hideSystemInstruction } = + useDispatch( playgroundStore ); + const toggleSystemInstruction = () => { + if ( isSystemInstructionVisible ) { + hideSystemInstruction(); + } else { + showSystemInstruction(); + } + }; + + useShortcut( 'ai/toggle-system-instruction', () => { + toggleSystemInstruction(); + } ); + + const shortcut = useSelect( + ( select ) => + select( keyboardShortcutsStore ).getShortcutRepresentation( + 'ai/toggle-system-instruction', + 'display' + ), + [] + ); + + return ( +