From 1ab1a241494bef8bdc25c76df4388725bc7ba758 Mon Sep 17 00:00:00 2001 From: Jason Adams Date: Thu, 17 Jul 2025 15:56:22 -0600 Subject: [PATCH 01/19] chore: adds CLAUDE file --- CLAUDE.md | 65 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 CLAUDE.md diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..493adac --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,65 @@ +# CLAUDE.md + +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. + +## Common Development Commands + +### Linting and Code Quality +- **Run all linting checks**: `composer lint` (runs both PHPCS and PHPStan) +- **Run PHP CodeSniffer**: `composer phpcs` +- **Fix code style issues**: `composer phpcbf` +- **Run PHPStan static analysis**: `composer phpstan` + +### Testing +- **Run PHPUnit tests**: `composer phpunit` + +### Dependencies +- **Install dependencies**: `composer install` +- **Update dependencies**: `composer update` + +## High-level Architecture + +This project is a PHP AI Client SDK designed to provide a provider-agnostic API for interacting with various generative AI models. The architecture has several key design principles: + +### API Layers + +1. **Implementer API**: For developers using the SDK to add AI features to their applications + - Fluent API: Chain methods for readable, declarative code (e.g., `AiClient::prompt('...')->generateText()`) + - Traditional API: Method-based approach with arrays of arguments + +2. **Extender API**: For developers adding new providers, models, or extending functionality + - Provider Registry system for managing available AI providers + - Model discovery based on capabilities and requirements + +### Core Concepts + +- **Provider Agnostic**: Abstracts away provider-specific details, allowing code to work with any AI provider (Google, OpenAI, Anthropic, etc.) +- **Capability-Based Model Selection**: Models can be discovered and selected based on their supported capabilities (text generation, image generation, etc.) and options (input modalities, output formats, etc.) +- **Uniform Data Structures**: Consistent message formats, file representations, and results across all providers +- **Modality Support**: Designed to support arbitrary combinations of input/output modalities (text, image, audio, video) + +### Namespace Structure + +The codebase follows a structured namespace hierarchy under `WordPress\AiClient`: +- `Builders`: Fluent API builders (PromptBuilder, MessageBuilder) +- `Embeddings`: Embedding-related data structures +- `Files`: File handling contracts and implementations +- `Messages`: Message DTOs and enums +- `Operations`: Long-running operation support +- `Providers`: Provider system with contracts, models, and registry +- `Results`: Result data structures and transformations +- `Tools`: Function calling and tool support +- `Util`: Utility classes for common operations + +### Key Design Patterns + +- **Interface Segregation**: Separate interfaces for different model capabilities (TextGenerationModelInterface, ImageGenerationModelInterface, etc.) +- **Composition over Inheritance**: Models compose capabilities through interfaces rather than inheritance +- **DTO Pattern**: Data Transfer Objects for messages, results, and configurations with JSON schema support +- **Builder Pattern**: Fluent builders for constructing prompts and messages + +### PHP Compatibility + +- Minimum PHP version: 7.4 +- Follows PER Coding Style +- Uses type hints wherever possible within PHP 7.4 constraints From c016d71e41ce8517d439d060bc56b6ae2e6cce0a Mon Sep 17 00:00:00 2001 From: Jason Adams Date: Thu, 17 Jul 2025 15:57:10 -0600 Subject: [PATCH 02/19] feat: adds composer.lock file --- composer.lock | 2012 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 2012 insertions(+) create mode 100644 composer.lock diff --git a/composer.lock b/composer.lock new file mode 100644 index 0000000..30aa667 --- /dev/null +++ b/composer.lock @@ -0,0 +1,2012 @@ +{ + "_readme": [ + "This file locks the dependencies of your project to a known state", + "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", + "This file is @generated automatically" + ], + "content-hash": "7f83e82443ddd46d217a8ec1099aaacc", + "packages": [], + "packages-dev": [ + { + "name": "dealerdirect/phpcodesniffer-composer-installer", + "version": "v1.1.2", + "source": { + "type": "git", + "url": "https://github.com/PHPCSStandards/composer-installer.git", + "reference": "e9cf5e4bbf7eeaf9ef5db34938942602838fc2b1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/PHPCSStandards/composer-installer/zipball/e9cf5e4bbf7eeaf9ef5db34938942602838fc2b1", + "reference": "e9cf5e4bbf7eeaf9ef5db34938942602838fc2b1", + "shasum": "" + }, + "require": { + "composer-plugin-api": "^2.2", + "php": ">=5.4", + "squizlabs/php_codesniffer": "^2.0 || ^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", + "yoast/phpunit-polyfills": "^1.0" + }, + "type": "composer-plugin", + "extra": { + "class": "PHPCSStandards\\Composer\\Plugin\\Installers\\PHPCodeSniffer\\Plugin" + }, + "autoload": { + "psr-4": { + "PHPCSStandards\\Composer\\Plugin\\Installers\\PHPCodeSniffer\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Franck Nijhof", + "email": "opensource@frenck.dev", + "homepage": "https://frenck.dev", + "role": "Open source developer" + }, + { + "name": "Contributors", + "homepage": "https://github.com/PHPCSStandards/composer-installer/graphs/contributors" + } + ], + "description": "PHP_CodeSniffer Standards Composer Installer Plugin", + "keywords": [ + "PHPCodeSniffer", + "PHP_CodeSniffer", + "code quality", + "codesniffer", + "composer", + "installer", + "phpcbf", + "phpcs", + "plugin", + "qa", + "quality", + "standard", + "standards", + "style guide", + "stylecheck", + "tests" + ], + "support": { + "issues": "https://github.com/PHPCSStandards/composer-installer/issues", + "security": "https://github.com/PHPCSStandards/composer-installer/security/policy", + "source": "https://github.com/PHPCSStandards/composer-installer" + }, + "funding": [ + { + "url": "https://github.com/PHPCSStandards", + "type": "github" + }, + { + "url": "https://github.com/jrfnl", + "type": "github" + }, + { + "url": "https://opencollective.com/php_codesniffer", + "type": "open_collective" + }, + { + "url": "https://thanks.dev/u/gh/phpcsstandards", + "type": "thanks_dev" + } + ], + "time": "2025-07-17T20:45:56+00:00" + }, + { + "name": "doctrine/instantiator", + "version": "1.5.0", + "source": { + "type": "git", + "url": "https://github.com/doctrine/instantiator.git", + "reference": "0a0fa9780f5d4e507415a065172d26a98d02047b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/instantiator/zipball/0a0fa9780f5d4e507415a065172d26a98d02047b", + "reference": "0a0fa9780f5d4e507415a065172d26a98d02047b", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0" + }, + "require-dev": { + "doctrine/coding-standard": "^9 || ^11", + "ext-pdo": "*", + "ext-phar": "*", + "phpbench/phpbench": "^0.16 || ^1", + "phpstan/phpstan": "^1.4", + "phpstan/phpstan-phpunit": "^1", + "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5", + "vimeo/psalm": "^4.30 || ^5.4" + }, + "type": "library", + "autoload": { + "psr-4": { + "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Marco Pivetta", + "email": "ocramius@gmail.com", + "homepage": "https://ocramius.github.io/" + } + ], + "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors", + "homepage": "https://www.doctrine-project.org/projects/instantiator.html", + "keywords": [ + "constructor", + "instantiate" + ], + "support": { + "issues": "https://github.com/doctrine/instantiator/issues", + "source": "https://github.com/doctrine/instantiator/tree/1.5.0" + }, + "funding": [ + { + "url": "https://www.doctrine-project.org/sponsorship.html", + "type": "custom" + }, + { + "url": "https://www.patreon.com/phpdoctrine", + "type": "patreon" + }, + { + "url": "https://tidelift.com/funding/github/packagist/doctrine%2Finstantiator", + "type": "tidelift" + } + ], + "time": "2022-12-30T00:15:36+00:00" + }, + { + "name": "myclabs/deep-copy", + "version": "1.13.3", + "source": { + "type": "git", + "url": "https://github.com/myclabs/DeepCopy.git", + "reference": "faed855a7b5f4d4637717c2b3863e277116beb36" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/faed855a7b5f4d4637717c2b3863e277116beb36", + "reference": "faed855a7b5f4d4637717c2b3863e277116beb36", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0" + }, + "conflict": { + "doctrine/collections": "<1.6.8", + "doctrine/common": "<2.13.3 || >=3 <3.2.2" + }, + "require-dev": { + "doctrine/collections": "^1.6.8", + "doctrine/common": "^2.13.3 || ^3.2.2", + "phpspec/prophecy": "^1.10", + "phpunit/phpunit": "^7.5.20 || ^8.5.23 || ^9.5.13" + }, + "type": "library", + "autoload": { + "files": [ + "src/DeepCopy/deep_copy.php" + ], + "psr-4": { + "DeepCopy\\": "src/DeepCopy/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Create deep copies (clones) of your objects", + "keywords": [ + "clone", + "copy", + "duplicate", + "object", + "object graph" + ], + "support": { + "issues": "https://github.com/myclabs/DeepCopy/issues", + "source": "https://github.com/myclabs/DeepCopy/tree/1.13.3" + }, + "funding": [ + { + "url": "https://tidelift.com/funding/github/packagist/myclabs/deep-copy", + "type": "tidelift" + } + ], + "time": "2025-07-05T12:25:42+00:00" + }, + { + "name": "nikic/php-parser", + "version": "v5.5.0", + "source": { + "type": "git", + "url": "https://github.com/nikic/PHP-Parser.git", + "reference": "ae59794362fe85e051a58ad36b289443f57be7a9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/ae59794362fe85e051a58ad36b289443f57be7a9", + "reference": "ae59794362fe85e051a58ad36b289443f57be7a9", + "shasum": "" + }, + "require": { + "ext-ctype": "*", + "ext-json": "*", + "ext-tokenizer": "*", + "php": ">=7.4" + }, + "require-dev": { + "ircmaxell/php-yacc": "^0.0.7", + "phpunit/phpunit": "^9.0" + }, + "bin": [ + "bin/php-parse" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.0-dev" + } + }, + "autoload": { + "psr-4": { + "PhpParser\\": "lib/PhpParser" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Nikita Popov" + } + ], + "description": "A PHP parser written in PHP", + "keywords": [ + "parser", + "php" + ], + "support": { + "issues": "https://github.com/nikic/PHP-Parser/issues", + "source": "https://github.com/nikic/PHP-Parser/tree/v5.5.0" + }, + "time": "2025-05-31T08:24:38+00:00" + }, + { + "name": "phar-io/manifest", + "version": "2.0.4", + "source": { + "type": "git", + "url": "https://github.com/phar-io/manifest.git", + "reference": "54750ef60c58e43759730615a392c31c80e23176" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phar-io/manifest/zipball/54750ef60c58e43759730615a392c31c80e23176", + "reference": "54750ef60c58e43759730615a392c31c80e23176", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-libxml": "*", + "ext-phar": "*", + "ext-xmlwriter": "*", + "phar-io/version": "^3.0.1", + "php": "^7.2 || ^8.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + }, + { + "name": "Sebastian Heuer", + "email": "sebastian@phpeople.de", + "role": "Developer" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "Developer" + } + ], + "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)", + "support": { + "issues": "https://github.com/phar-io/manifest/issues", + "source": "https://github.com/phar-io/manifest/tree/2.0.4" + }, + "funding": [ + { + "url": "https://github.com/theseer", + "type": "github" + } + ], + "time": "2024-03-03T12:33:53+00:00" + }, + { + "name": "phar-io/version", + "version": "3.2.1", + "source": { + "type": "git", + "url": "https://github.com/phar-io/version.git", + "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phar-io/version/zipball/4f7fd7836c6f332bb2933569e566a0d6c4cbed74", + "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + }, + { + "name": "Sebastian Heuer", + "email": "sebastian@phpeople.de", + "role": "Developer" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "Developer" + } + ], + "description": "Library for handling version information and constraints", + "support": { + "issues": "https://github.com/phar-io/version/issues", + "source": "https://github.com/phar-io/version/tree/3.2.1" + }, + "time": "2022-02-21T01:04:05+00:00" + }, + { + "name": "phpstan/phpstan", + "version": "2.1.18", + "source": { + "type": "git", + "url": "https://github.com/phpstan/phpstan.git", + "reference": "ee1f390b7a70cdf74a2b737e554f68afea885db7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/ee1f390b7a70cdf74a2b737e554f68afea885db7", + "reference": "ee1f390b7a70cdf74a2b737e554f68afea885db7", + "shasum": "" + }, + "require": { + "php": "^7.4|^8.0" + }, + "conflict": { + "phpstan/phpstan-shim": "*" + }, + "bin": [ + "phpstan", + "phpstan.phar" + ], + "type": "library", + "autoload": { + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "PHPStan - PHP Static Analysis Tool", + "keywords": [ + "dev", + "static analysis" + ], + "support": { + "docs": "https://phpstan.org/user-guide/getting-started", + "forum": "https://github.com/phpstan/phpstan/discussions", + "issues": "https://github.com/phpstan/phpstan/issues", + "security": "https://github.com/phpstan/phpstan/security/policy", + "source": "https://github.com/phpstan/phpstan-src" + }, + "funding": [ + { + "url": "https://github.com/ondrejmirtes", + "type": "github" + }, + { + "url": "https://github.com/phpstan", + "type": "github" + } + ], + "time": "2025-07-17T17:22:31+00:00" + }, + { + "name": "phpunit/php-code-coverage", + "version": "9.2.32", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-code-coverage.git", + "reference": "85402a822d1ecf1db1096959413d35e1c37cf1a5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/85402a822d1ecf1db1096959413d35e1c37cf1a5", + "reference": "85402a822d1ecf1db1096959413d35e1c37cf1a5", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-libxml": "*", + "ext-xmlwriter": "*", + "nikic/php-parser": "^4.19.1 || ^5.1.0", + "php": ">=7.3", + "phpunit/php-file-iterator": "^3.0.6", + "phpunit/php-text-template": "^2.0.4", + "sebastian/code-unit-reverse-lookup": "^2.0.3", + "sebastian/complexity": "^2.0.3", + "sebastian/environment": "^5.1.5", + "sebastian/lines-of-code": "^1.0.4", + "sebastian/version": "^3.0.2", + "theseer/tokenizer": "^1.2.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.6" + }, + "suggest": { + "ext-pcov": "PHP extension that provides line coverage", + "ext-xdebug": "PHP extension that provides line coverage as well as branch and path coverage" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "9.2.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.", + "homepage": "https://github.com/sebastianbergmann/php-code-coverage", + "keywords": [ + "coverage", + "testing", + "xunit" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", + "security": "https://github.com/sebastianbergmann/php-code-coverage/security/policy", + "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.32" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-08-22T04:23:01+00:00" + }, + { + "name": "phpunit/php-file-iterator", + "version": "3.0.6", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-file-iterator.git", + "reference": "cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf", + "reference": "cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "FilterIterator implementation that filters files based on a list of suffixes.", + "homepage": "https://github.com/sebastianbergmann/php-file-iterator/", + "keywords": [ + "filesystem", + "iterator" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-file-iterator/issues", + "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/3.0.6" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2021-12-02T12:48:52+00:00" + }, + { + "name": "phpunit/php-invoker", + "version": "3.1.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-invoker.git", + "reference": "5a10147d0aaf65b58940a0b72f71c9ac0423cc67" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-invoker/zipball/5a10147d0aaf65b58940a0b72f71c9ac0423cc67", + "reference": "5a10147d0aaf65b58940a0b72f71c9ac0423cc67", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "ext-pcntl": "*", + "phpunit/phpunit": "^9.3" + }, + "suggest": { + "ext-pcntl": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.1-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Invoke callables with a timeout", + "homepage": "https://github.com/sebastianbergmann/php-invoker/", + "keywords": [ + "process" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-invoker/issues", + "source": "https://github.com/sebastianbergmann/php-invoker/tree/3.1.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-09-28T05:58:55+00:00" + }, + { + "name": "phpunit/php-text-template", + "version": "2.0.4", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-text-template.git", + "reference": "5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28", + "reference": "5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Simple template engine.", + "homepage": "https://github.com/sebastianbergmann/php-text-template/", + "keywords": [ + "template" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-text-template/issues", + "source": "https://github.com/sebastianbergmann/php-text-template/tree/2.0.4" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-10-26T05:33:50+00:00" + }, + { + "name": "phpunit/php-timer", + "version": "5.0.3", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-timer.git", + "reference": "5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2", + "reference": "5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Utility class for timing", + "homepage": "https://github.com/sebastianbergmann/php-timer/", + "keywords": [ + "timer" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-timer/issues", + "source": "https://github.com/sebastianbergmann/php-timer/tree/5.0.3" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-10-26T13:16:10+00:00" + }, + { + "name": "phpunit/phpunit", + "version": "9.6.23", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/phpunit.git", + "reference": "43d2cb18d0675c38bd44982a5d1d88f6d53d8d95" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/43d2cb18d0675c38bd44982a5d1d88f6d53d8d95", + "reference": "43d2cb18d0675c38bd44982a5d1d88f6d53d8d95", + "shasum": "" + }, + "require": { + "doctrine/instantiator": "^1.5.0 || ^2", + "ext-dom": "*", + "ext-json": "*", + "ext-libxml": "*", + "ext-mbstring": "*", + "ext-xml": "*", + "ext-xmlwriter": "*", + "myclabs/deep-copy": "^1.13.1", + "phar-io/manifest": "^2.0.4", + "phar-io/version": "^3.2.1", + "php": ">=7.3", + "phpunit/php-code-coverage": "^9.2.32", + "phpunit/php-file-iterator": "^3.0.6", + "phpunit/php-invoker": "^3.1.1", + "phpunit/php-text-template": "^2.0.4", + "phpunit/php-timer": "^5.0.3", + "sebastian/cli-parser": "^1.0.2", + "sebastian/code-unit": "^1.0.8", + "sebastian/comparator": "^4.0.8", + "sebastian/diff": "^4.0.6", + "sebastian/environment": "^5.1.5", + "sebastian/exporter": "^4.0.6", + "sebastian/global-state": "^5.0.7", + "sebastian/object-enumerator": "^4.0.4", + "sebastian/resource-operations": "^3.0.4", + "sebastian/type": "^3.2.1", + "sebastian/version": "^3.0.2" + }, + "suggest": { + "ext-soap": "To be able to generate mocks based on WSDL files", + "ext-xdebug": "PHP extension that provides line coverage as well as branch and path coverage" + }, + "bin": [ + "phpunit" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "9.6-dev" + } + }, + "autoload": { + "files": [ + "src/Framework/Assert/Functions.php" + ], + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "The PHP Unit Testing framework.", + "homepage": "https://phpunit.de/", + "keywords": [ + "phpunit", + "testing", + "xunit" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/phpunit/issues", + "security": "https://github.com/sebastianbergmann/phpunit/security/policy", + "source": "https://github.com/sebastianbergmann/phpunit/tree/9.6.23" + }, + "funding": [ + { + "url": "https://phpunit.de/sponsors.html", + "type": "custom" + }, + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + }, + { + "url": "https://liberapay.com/sebastianbergmann", + "type": "liberapay" + }, + { + "url": "https://thanks.dev/u/gh/sebastianbergmann", + "type": "thanks_dev" + }, + { + "url": "https://tidelift.com/funding/github/packagist/phpunit/phpunit", + "type": "tidelift" + } + ], + "time": "2025-05-02T06:40:34+00:00" + }, + { + "name": "sebastian/cli-parser", + "version": "1.0.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/cli-parser.git", + "reference": "2b56bea83a09de3ac06bb18b92f068e60cc6f50b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/2b56bea83a09de3ac06bb18b92f068e60cc6f50b", + "reference": "2b56bea83a09de3ac06bb18b92f068e60cc6f50b", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library for parsing CLI options", + "homepage": "https://github.com/sebastianbergmann/cli-parser", + "support": { + "issues": "https://github.com/sebastianbergmann/cli-parser/issues", + "source": "https://github.com/sebastianbergmann/cli-parser/tree/1.0.2" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-03-02T06:27:43+00:00" + }, + { + "name": "sebastian/code-unit", + "version": "1.0.8", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/code-unit.git", + "reference": "1fc9f64c0927627ef78ba436c9b17d967e68e120" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit/zipball/1fc9f64c0927627ef78ba436c9b17d967e68e120", + "reference": "1fc9f64c0927627ef78ba436c9b17d967e68e120", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Collection of value objects that represent the PHP code units", + "homepage": "https://github.com/sebastianbergmann/code-unit", + "support": { + "issues": "https://github.com/sebastianbergmann/code-unit/issues", + "source": "https://github.com/sebastianbergmann/code-unit/tree/1.0.8" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-10-26T13:08:54+00:00" + }, + { + "name": "sebastian/code-unit-reverse-lookup", + "version": "2.0.3", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", + "reference": "ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5", + "reference": "ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Looks up which function or method a line of code belongs to", + "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/", + "support": { + "issues": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/issues", + "source": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/tree/2.0.3" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-09-28T05:30:19+00:00" + }, + { + "name": "sebastian/comparator", + "version": "4.0.8", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/comparator.git", + "reference": "fa0f136dd2334583309d32b62544682ee972b51a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/fa0f136dd2334583309d32b62544682ee972b51a", + "reference": "fa0f136dd2334583309d32b62544682ee972b51a", + "shasum": "" + }, + "require": { + "php": ">=7.3", + "sebastian/diff": "^4.0", + "sebastian/exporter": "^4.0" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Volker Dusch", + "email": "github@wallbash.com" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@2bepublished.at" + } + ], + "description": "Provides the functionality to compare PHP values for equality", + "homepage": "https://github.com/sebastianbergmann/comparator", + "keywords": [ + "comparator", + "compare", + "equality" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/comparator/issues", + "source": "https://github.com/sebastianbergmann/comparator/tree/4.0.8" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2022-09-14T12:41:17+00:00" + }, + { + "name": "sebastian/complexity", + "version": "2.0.3", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/complexity.git", + "reference": "25f207c40d62b8b7aa32f5ab026c53561964053a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/25f207c40d62b8b7aa32f5ab026c53561964053a", + "reference": "25f207c40d62b8b7aa32f5ab026c53561964053a", + "shasum": "" + }, + "require": { + "nikic/php-parser": "^4.18 || ^5.0", + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library for calculating the complexity of PHP code units", + "homepage": "https://github.com/sebastianbergmann/complexity", + "support": { + "issues": "https://github.com/sebastianbergmann/complexity/issues", + "source": "https://github.com/sebastianbergmann/complexity/tree/2.0.3" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-12-22T06:19:30+00:00" + }, + { + "name": "sebastian/diff", + "version": "4.0.6", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/diff.git", + "reference": "ba01945089c3a293b01ba9badc29ad55b106b0bc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/ba01945089c3a293b01ba9badc29ad55b106b0bc", + "reference": "ba01945089c3a293b01ba9badc29ad55b106b0bc", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3", + "symfony/process": "^4.2 || ^5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Kore Nordmann", + "email": "mail@kore-nordmann.de" + } + ], + "description": "Diff implementation", + "homepage": "https://github.com/sebastianbergmann/diff", + "keywords": [ + "diff", + "udiff", + "unidiff", + "unified diff" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/diff/issues", + "source": "https://github.com/sebastianbergmann/diff/tree/4.0.6" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-03-02T06:30:58+00:00" + }, + { + "name": "sebastian/environment", + "version": "5.1.5", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/environment.git", + "reference": "830c43a844f1f8d5b7a1f6d6076b784454d8b7ed" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/830c43a844f1f8d5b7a1f6d6076b784454d8b7ed", + "reference": "830c43a844f1f8d5b7a1f6d6076b784454d8b7ed", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "suggest": { + "ext-posix": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.1-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Provides functionality to handle HHVM/PHP environments", + "homepage": "http://www.github.com/sebastianbergmann/environment", + "keywords": [ + "Xdebug", + "environment", + "hhvm" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/environment/issues", + "source": "https://github.com/sebastianbergmann/environment/tree/5.1.5" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-02-03T06:03:51+00:00" + }, + { + "name": "sebastian/exporter", + "version": "4.0.6", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/exporter.git", + "reference": "78c00df8f170e02473b682df15bfcdacc3d32d72" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/78c00df8f170e02473b682df15bfcdacc3d32d72", + "reference": "78c00df8f170e02473b682df15bfcdacc3d32d72", + "shasum": "" + }, + "require": { + "php": ">=7.3", + "sebastian/recursion-context": "^4.0" + }, + "require-dev": { + "ext-mbstring": "*", + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Volker Dusch", + "email": "github@wallbash.com" + }, + { + "name": "Adam Harvey", + "email": "aharvey@php.net" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@gmail.com" + } + ], + "description": "Provides the functionality to export PHP variables for visualization", + "homepage": "https://www.github.com/sebastianbergmann/exporter", + "keywords": [ + "export", + "exporter" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/exporter/issues", + "source": "https://github.com/sebastianbergmann/exporter/tree/4.0.6" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-03-02T06:33:00+00:00" + }, + { + "name": "sebastian/global-state", + "version": "5.0.7", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/global-state.git", + "reference": "bca7df1f32ee6fe93b4d4a9abbf69e13a4ada2c9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/bca7df1f32ee6fe93b4d4a9abbf69e13a4ada2c9", + "reference": "bca7df1f32ee6fe93b4d4a9abbf69e13a4ada2c9", + "shasum": "" + }, + "require": { + "php": ">=7.3", + "sebastian/object-reflector": "^2.0", + "sebastian/recursion-context": "^4.0" + }, + "require-dev": { + "ext-dom": "*", + "phpunit/phpunit": "^9.3" + }, + "suggest": { + "ext-uopz": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Snapshotting of global state", + "homepage": "http://www.github.com/sebastianbergmann/global-state", + "keywords": [ + "global state" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/global-state/issues", + "source": "https://github.com/sebastianbergmann/global-state/tree/5.0.7" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-03-02T06:35:11+00:00" + }, + { + "name": "sebastian/lines-of-code", + "version": "1.0.4", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/lines-of-code.git", + "reference": "e1e4a170560925c26d424b6a03aed157e7dcc5c5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/e1e4a170560925c26d424b6a03aed157e7dcc5c5", + "reference": "e1e4a170560925c26d424b6a03aed157e7dcc5c5", + "shasum": "" + }, + "require": { + "nikic/php-parser": "^4.18 || ^5.0", + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library for counting the lines of code in PHP source code", + "homepage": "https://github.com/sebastianbergmann/lines-of-code", + "support": { + "issues": "https://github.com/sebastianbergmann/lines-of-code/issues", + "source": "https://github.com/sebastianbergmann/lines-of-code/tree/1.0.4" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-12-22T06:20:34+00:00" + }, + { + "name": "sebastian/object-enumerator", + "version": "4.0.4", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/object-enumerator.git", + "reference": "5c9eeac41b290a3712d88851518825ad78f45c71" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/5c9eeac41b290a3712d88851518825ad78f45c71", + "reference": "5c9eeac41b290a3712d88851518825ad78f45c71", + "shasum": "" + }, + "require": { + "php": ">=7.3", + "sebastian/object-reflector": "^2.0", + "sebastian/recursion-context": "^4.0" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Traverses array structures and object graphs to enumerate all referenced objects", + "homepage": "https://github.com/sebastianbergmann/object-enumerator/", + "support": { + "issues": "https://github.com/sebastianbergmann/object-enumerator/issues", + "source": "https://github.com/sebastianbergmann/object-enumerator/tree/4.0.4" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-10-26T13:12:34+00:00" + }, + { + "name": "sebastian/object-reflector", + "version": "2.0.4", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/object-reflector.git", + "reference": "b4f479ebdbf63ac605d183ece17d8d7fe49c15c7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/b4f479ebdbf63ac605d183ece17d8d7fe49c15c7", + "reference": "b4f479ebdbf63ac605d183ece17d8d7fe49c15c7", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Allows reflection of object attributes, including inherited and non-public ones", + "homepage": "https://github.com/sebastianbergmann/object-reflector/", + "support": { + "issues": "https://github.com/sebastianbergmann/object-reflector/issues", + "source": "https://github.com/sebastianbergmann/object-reflector/tree/2.0.4" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-10-26T13:14:26+00:00" + }, + { + "name": "sebastian/recursion-context", + "version": "4.0.5", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/recursion-context.git", + "reference": "e75bd0f07204fec2a0af9b0f3cfe97d05f92efc1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/e75bd0f07204fec2a0af9b0f3cfe97d05f92efc1", + "reference": "e75bd0f07204fec2a0af9b0f3cfe97d05f92efc1", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Adam Harvey", + "email": "aharvey@php.net" + } + ], + "description": "Provides functionality to recursively process PHP variables", + "homepage": "https://github.com/sebastianbergmann/recursion-context", + "support": { + "issues": "https://github.com/sebastianbergmann/recursion-context/issues", + "source": "https://github.com/sebastianbergmann/recursion-context/tree/4.0.5" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-02-03T06:07:39+00:00" + }, + { + "name": "sebastian/resource-operations", + "version": "3.0.4", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/resource-operations.git", + "reference": "05d5692a7993ecccd56a03e40cd7e5b09b1d404e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/05d5692a7993ecccd56a03e40cd7e5b09b1d404e", + "reference": "05d5692a7993ecccd56a03e40cd7e5b09b1d404e", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Provides a list of PHP built-in functions that operate on resources", + "homepage": "https://www.github.com/sebastianbergmann/resource-operations", + "support": { + "source": "https://github.com/sebastianbergmann/resource-operations/tree/3.0.4" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-03-14T16:00:52+00:00" + }, + { + "name": "sebastian/type", + "version": "3.2.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/type.git", + "reference": "75e2c2a32f5e0b3aef905b9ed0b179b953b3d7c7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/75e2c2a32f5e0b3aef905b9ed0b179b953b3d7c7", + "reference": "75e2c2a32f5e0b3aef905b9ed0b179b953b3d7c7", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.2-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Collection of value objects that represent the types of the PHP type system", + "homepage": "https://github.com/sebastianbergmann/type", + "support": { + "issues": "https://github.com/sebastianbergmann/type/issues", + "source": "https://github.com/sebastianbergmann/type/tree/3.2.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-02-03T06:13:03+00:00" + }, + { + "name": "sebastian/version", + "version": "3.0.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/version.git", + "reference": "c6c1022351a901512170118436c764e473f6de8c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/c6c1022351a901512170118436c764e473f6de8c", + "reference": "c6c1022351a901512170118436c764e473f6de8c", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library that helps with managing the version number of Git-hosted PHP projects", + "homepage": "https://github.com/sebastianbergmann/version", + "support": { + "issues": "https://github.com/sebastianbergmann/version/issues", + "source": "https://github.com/sebastianbergmann/version/tree/3.0.2" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-09-28T06:39:44+00:00" + }, + { + "name": "squizlabs/php_codesniffer", + "version": "3.13.2", + "source": { + "type": "git", + "url": "https://github.com/PHPCSStandards/PHP_CodeSniffer.git", + "reference": "5b5e3821314f947dd040c70f7992a64eac89025c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/PHPCSStandards/PHP_CodeSniffer/zipball/5b5e3821314f947dd040c70f7992a64eac89025c", + "reference": "5b5e3821314f947dd040c70f7992a64eac89025c", + "shasum": "" + }, + "require": { + "ext-simplexml": "*", + "ext-tokenizer": "*", + "ext-xmlwriter": "*", + "php": ">=5.4.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.0 || ^5.0 || ^6.0 || ^7.0 || ^8.0 || ^9.3.4" + }, + "bin": [ + "bin/phpcbf", + "bin/phpcs" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.x-dev" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Greg Sherwood", + "role": "Former lead" + }, + { + "name": "Juliette Reinders Folmer", + "role": "Current lead" + }, + { + "name": "Contributors", + "homepage": "https://github.com/PHPCSStandards/PHP_CodeSniffer/graphs/contributors" + } + ], + "description": "PHP_CodeSniffer tokenizes PHP, JavaScript and CSS files and detects violations of a defined set of coding standards.", + "homepage": "https://github.com/PHPCSStandards/PHP_CodeSniffer", + "keywords": [ + "phpcs", + "standards", + "static analysis" + ], + "support": { + "issues": "https://github.com/PHPCSStandards/PHP_CodeSniffer/issues", + "security": "https://github.com/PHPCSStandards/PHP_CodeSniffer/security/policy", + "source": "https://github.com/PHPCSStandards/PHP_CodeSniffer", + "wiki": "https://github.com/PHPCSStandards/PHP_CodeSniffer/wiki" + }, + "funding": [ + { + "url": "https://github.com/PHPCSStandards", + "type": "github" + }, + { + "url": "https://github.com/jrfnl", + "type": "github" + }, + { + "url": "https://opencollective.com/php_codesniffer", + "type": "open_collective" + }, + { + "url": "https://thanks.dev/u/gh/phpcsstandards", + "type": "thanks_dev" + } + ], + "time": "2025-06-17T22:17:01+00:00" + }, + { + "name": "theseer/tokenizer", + "version": "1.2.3", + "source": { + "type": "git", + "url": "https://github.com/theseer/tokenizer.git", + "reference": "737eda637ed5e28c3413cb1ebe8bb52cbf1ca7a2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/theseer/tokenizer/zipball/737eda637ed5e28c3413cb1ebe8bb52cbf1ca7a2", + "reference": "737eda637ed5e28c3413cb1ebe8bb52cbf1ca7a2", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-tokenizer": "*", + "ext-xmlwriter": "*", + "php": "^7.2 || ^8.0" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + } + ], + "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" + }, + "funding": [ + { + "url": "https://github.com/theseer", + "type": "github" + } + ], + "time": "2024-03-03T12:36:25+00:00" + } + ], + "aliases": [], + "minimum-stability": "dev", + "stability-flags": {}, + "prefer-stable": true, + "prefer-lowest": false, + "platform": { + "php": ">=7.4", + "ext-json": "*" + }, + "platform-dev": {}, + "platform-overrides": { + "php": "7.4" + }, + "plugin-api-version": "2.6.0" +} From 56d0dfe0c668fa08dc6cc0d1d087683b7c65ec89 Mon Sep 17 00:00:00 2001 From: Jason Adams Date: Thu, 17 Jul 2025 15:57:20 -0600 Subject: [PATCH 03/19] chore: ignores .claude folder --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index c1e8802..3a97163 100644 --- a/.gitignore +++ b/.gitignore @@ -12,3 +12,4 @@ vendor/ [Dd]esktop.ini *.DS_store .DS_store? +.claude/ From 612294c218590442f823d42a1a6780dea5243c08 Mon Sep 17 00:00:00 2001 From: Jason Adams Date: Thu, 17 Jul 2025 15:57:45 -0600 Subject: [PATCH 04/19] refactor: removes dummy file --- src/DummyForAnalysis.php | 25 ------------------------- 1 file changed, 25 deletions(-) delete mode 100644 src/DummyForAnalysis.php diff --git a/src/DummyForAnalysis.php b/src/DummyForAnalysis.php deleted file mode 100644 index 7264349..0000000 --- a/src/DummyForAnalysis.php +++ /dev/null @@ -1,25 +0,0 @@ - Date: Thu, 17 Jul 2025 15:57:57 -0600 Subject: [PATCH 05/19] feat: adds all enums --- src/Common/AbstractEnum.php | 229 ++++++++++++++++++ src/Messages/Enums/MessagePartTypeEnum.php | 49 ++++ src/Messages/Enums/MessageRoleEnum.php | 35 +++ src/Messages/Enums/ModalityEnum.php | 49 ++++ src/Operations/Enums/OperationStateEnum.php | 49 ++++ src/Providers/Enums/ProviderTypeEnum.php | 35 +++ src/Providers/Enums/ToolTypeEnum.php | 28 +++ src/Providers/Models/Enums/CapabilityEnum.php | 70 ++++++ src/Providers/Models/Enums/OptionEnum.php | 84 +++++++ src/Results/Enums/FinishReasonEnum.php | 49 ++++ 10 files changed, 677 insertions(+) create mode 100644 src/Common/AbstractEnum.php create mode 100644 src/Messages/Enums/MessagePartTypeEnum.php create mode 100644 src/Messages/Enums/MessageRoleEnum.php create mode 100644 src/Messages/Enums/ModalityEnum.php create mode 100644 src/Operations/Enums/OperationStateEnum.php create mode 100644 src/Providers/Enums/ProviderTypeEnum.php create mode 100644 src/Providers/Enums/ToolTypeEnum.php create mode 100644 src/Providers/Models/Enums/CapabilityEnum.php create mode 100644 src/Providers/Models/Enums/OptionEnum.php create mode 100644 src/Results/Enums/FinishReasonEnum.php diff --git a/src/Common/AbstractEnum.php b/src/Common/AbstractEnum.php new file mode 100644 index 0000000..fc2b83b --- /dev/null +++ b/src/Common/AbstractEnum.php @@ -0,0 +1,229 @@ +isFirstName(); // Returns true + * $enum->equals('first'); // Returns true + * $enum->is(PersonEnum::firstName()); // Returns true + */ +abstract class AbstractEnum +{ + /** + * @var string|int|float The value of the enum instance + */ + private $value; + + /** + * @var array> Cache for reflection data + */ + private static $cache = []; + + /** + * Constructor is private to ensure instances are created through static methods + * + * @param string|int|float $value The enum value + */ + private function __construct($value) + { + $this->value = $value; + } + + /** + * Get the value of the enum instance + * + * @return string|int|float + */ + public function getValue() + { + return $this->value; + } + + /** + * Check if this enum has the same value as the given value + * + * @param string|int|float|self $other The value or enum to compare + * @return bool + */ + public function equals($other): bool + { + if ($other instanceof self) { + return $this->is($other); + } + + return $this->value === $other; + } + + /** + * Check if this enum is the same instance type and value as another enum + * + * @param self $other The other enum to compare + * @return bool + */ + public function is(self $other): bool + { + return get_class($this) === get_class($other) && $this->value === $other->getValue(); + } + + /** + * Get all valid values for this enum + * + * @return array + */ + public static function getValues(): array + { + return self::getConstants(); + } + + /** + * Check if a value is valid for this enum + * + * @param string|int|float $value The value to check + * @return bool + */ + public static function isValidValue($value): bool + { + return in_array($value, self::getValues(), true); + } + + /** + * Create an enum instance from a value + * + * @param string|int|float $value The enum value + * @return static + * @throws InvalidArgumentException If the value is not valid + */ + public static function fromValue($value): self + { + if (!self::isValidValue($value)) { + throw new InvalidArgumentException( + sprintf('Invalid value "%s" for enum %s', (string) $value, static::class) + ); + } + + $className = static::class; + return new $className($value); + } + + /** + * Get all constants for this enum class + * + * @return array + */ + protected static function getConstants(): array + { + $className = static::class; + + if (!isset(self::$cache[$className])) { + $reflection = new ReflectionClass($className); + $constants = $reflection->getConstants(); + + // Filter to only include uppercase snake_case constants + $enumConstants = []; + foreach ($constants as $name => $value) { + if ( + preg_match('/^[A-Z][A-Z0-9_]*$/', $name) + && (is_string($value) || is_int($value) || is_float($value)) + ) { + $enumConstants[$name] = $value; + } + } + + self::$cache[$className] = $enumConstants; + } + + return self::$cache[$className]; + } + + /** + * Handle dynamic method calls for enum creation and checking + * + * @param string $name The method name + * @param array $arguments The method arguments + * @return bool + * @throws BadMethodCallException If the method doesn't exist + */ + public function __call(string $name, array $arguments) + { + // Handle is* methods + if (strpos($name, 'is') === 0) { + $constantName = self::camelCaseToConstant(substr($name, 2)); + $constants = self::getConstants(); + + if (isset($constants[$constantName])) { + return $this->value === $constants[$constantName]; + } + } + + throw new BadMethodCallException( + sprintf('Method %s::%s does not exist', static::class, $name) + ); + } + + /** + * Handle static method calls for enum creation + * + * @param string $name The method name + * @param array $arguments The method arguments + * @return static + * @throws BadMethodCallException If the method doesn't exist + */ + public static function __callStatic(string $name, array $arguments) + { + $constantName = self::camelCaseToConstant($name); + $constants = self::getConstants(); + + if (isset($constants[$constantName])) { + $className = static::class; + return new $className($constants[$constantName]); + } + + throw new BadMethodCallException( + sprintf('Method %s::%s does not exist', static::class, $name) + ); + } + + /** + * Convert camelCase to CONSTANT_CASE + * + * @param string $camelCase The camelCase string + * @return string The CONSTANT_CASE version + */ + private static function camelCaseToConstant(string $camelCase): string + { + $snakeCase = preg_replace('/([a-z])([A-Z])/', '$1_$2', $camelCase); + if ($snakeCase === null) { + return strtoupper($camelCase); + } + return strtoupper($snakeCase); + } + + /** + * String representation of the enum + * + * @return string + */ + public function __toString(): string + { + return (string) $this->value; + } +} diff --git a/src/Messages/Enums/MessagePartTypeEnum.php b/src/Messages/Enums/MessagePartTypeEnum.php new file mode 100644 index 0000000..2bb9014 --- /dev/null +++ b/src/Messages/Enums/MessagePartTypeEnum.php @@ -0,0 +1,49 @@ + Date: Thu, 17 Jul 2025 16:11:31 -0600 Subject: [PATCH 06/19] refactor: makes AbstractEnum act more like Enum --- src/Common/AbstractEnum.php | 157 ++++++++++++++++++++++++++++++------ 1 file changed, 132 insertions(+), 25 deletions(-) diff --git a/src/Common/AbstractEnum.php b/src/Common/AbstractEnum.php index fc2b83b..983ddf4 100644 --- a/src/Common/AbstractEnum.php +++ b/src/Common/AbstractEnum.php @@ -21,47 +21,135 @@ * } * * // Usage: + * $enum = PersonEnum::from('first'); // Creates instance with value 'first' + * $enum = PersonEnum::tryFrom('invalid'); // Returns null * $enum = PersonEnum::firstName(); // Creates instance with value 'first' - * $enum->isFirstName(); // Returns true + * $enum->name; // 'FIRST_NAME' + * $enum->value; // 'first' * $enum->equals('first'); // Returns true * $enum->is(PersonEnum::firstName()); // Returns true + * PersonEnum::cases(); // Returns array of all enum instances */ abstract class AbstractEnum { /** - * @var string|int|float The value of the enum instance + * @var string|int The value of the enum instance */ private $value; /** - * @var array> Cache for reflection data + * @var string The name of the enum constant + */ + private $name; + + /** + * @var array> Cache for reflection data */ private static $cache = []; + /** + * @var array> Cache for enum instances + */ + private static $instances = []; + /** * Constructor is private to ensure instances are created through static methods * - * @param string|int|float $value The enum value + * @param string|int $value The enum value + * @param string $name The constant name */ - private function __construct($value) + private function __construct($value, string $name) { $this->value = $value; + $this->name = $name; + } + + /** + * Magic getter to provide read-only access to properties + * + * @param string $property The property name + * @return mixed + * @throws BadMethodCallException If property doesn't exist + */ + public function __get(string $property) + { + if ($property === 'value' || $property === 'name') { + return $this->$property; + } + + throw new BadMethodCallException( + sprintf('Property %s::%s does not exist', static::class, $property) + ); + } + + /** + * Magic setter to prevent property modification + * + * @param string $property The property name + * @param mixed $value The value to set + * @throws BadMethodCallException Always, as enum properties are read-only + */ + public function __set(string $property, $value): void + { + throw new BadMethodCallException( + sprintf('Cannot modify property %s::%s - enum properties are read-only', static::class, $property) + ); + } + + /** + * Create an enum instance from a value, throws exception if invalid + * + * @param string|int $value The enum value + * @return static + * @throws InvalidArgumentException If the value is not valid + */ + public static function from($value): self + { + $instance = self::tryFrom($value); + if ($instance === null) { + throw new InvalidArgumentException( + sprintf('%s is not a valid backing value for enum %s', (string) $value, static::class) + ); + } + return $instance; } /** - * Get the value of the enum instance + * Try to create an enum instance from a value, returns null if invalid * - * @return string|int|float + * @param string|int $value The enum value + * @return static|null */ - public function getValue() + public static function tryFrom($value): ?self { - return $this->value; + $constants = self::getConstants(); + foreach ($constants as $name => $constantValue) { + if ($constantValue === $value) { + return self::getInstance($constantValue, $name); + } + } + return null; + } + + /** + * Get all enum cases + * + * @return static[] + */ + public static function cases(): array + { + $cases = []; + $constants = self::getConstants(); + foreach ($constants as $name => $value) { + $cases[] = self::getInstance($value, $name); + } + return $cases; } /** * Check if this enum has the same value as the given value * - * @param string|int|float|self $other The value or enum to compare + * @param string|int|self $other The value or enum to compare * @return bool */ public function equals($other): bool @@ -81,13 +169,13 @@ public function equals($other): bool */ public function is(self $other): bool { - return get_class($this) === get_class($other) && $this->value === $other->getValue(); + return $this === $other; // Since we're using singletons, we can use identity comparison } /** * Get all valid values for this enum * - * @return array + * @return array */ public static function getValues(): array { @@ -97,7 +185,7 @@ public static function getValues(): array /** * Check if a value is valid for this enum * - * @param string|int|float $value The value to check + * @param string|int $value The value to check * @return bool */ public static function isValidValue($value): bool @@ -106,28 +194,48 @@ public static function isValidValue($value): bool } /** - * Create an enum instance from a value + * Create an enum instance from a value (deprecated, use from() instead) * - * @param string|int|float $value The enum value + * @param string|int $value The enum value * @return static * @throws InvalidArgumentException If the value is not valid + * @deprecated Use from() method instead */ public static function fromValue($value): self { - if (!self::isValidValue($value)) { - throw new InvalidArgumentException( - sprintf('Invalid value "%s" for enum %s', (string) $value, static::class) - ); - } + return self::from($value); + } + /** + * Get or create a singleton instance for the given value and name + * + * @param string|int $value The enum value + * @param string $name The constant name + * @return static + * @phpstan-return static + */ + private static function getInstance($value, string $name): self + { $className = static::class; - return new $className($value); + $key = $name; + + if (!isset(self::$instances[$className])) { + self::$instances[$className] = []; + } + + if (!isset(self::$instances[$className][$key])) { + $instance = new $className($value, $name); + self::$instances[$className][$key] = $instance; + } + + /** @var static */ + return self::$instances[$className][$key]; } /** * Get all constants for this enum class * - * @return array + * @return array */ protected static function getConstants(): array { @@ -142,7 +250,7 @@ protected static function getConstants(): array foreach ($constants as $name => $value) { if ( preg_match('/^[A-Z][A-Z0-9_]*$/', $name) - && (is_string($value) || is_int($value) || is_float($value)) + && (is_string($value) || is_int($value)) ) { $enumConstants[$name] = $value; } @@ -193,8 +301,7 @@ public static function __callStatic(string $name, array $arguments) $constants = self::getConstants(); if (isset($constants[$constantName])) { - $className = static::class; - return new $className($constants[$constantName]); + return self::getInstance($constants[$constantName], $constantName); } throw new BadMethodCallException( From 58eaec400040bfeb90d2afaeede7f1e8e1a37a77 Mon Sep 17 00:00:00 2001 From: Jason Adams Date: Thu, 17 Jul 2025 16:42:56 -0600 Subject: [PATCH 07/19] Add validation for enum constants - throw RuntimeException for invalid names - Constants must follow UPPER_SNAKE_CASE pattern - Only string and int values are allowed - Ensures enum integrity at runtime --- src/Common/AbstractEnum.php | 32 ++++++++++++++++++++++++++------ 1 file changed, 26 insertions(+), 6 deletions(-) diff --git a/src/Common/AbstractEnum.php b/src/Common/AbstractEnum.php index 983ddf4..9015b12 100644 --- a/src/Common/AbstractEnum.php +++ b/src/Common/AbstractEnum.php @@ -236,6 +236,7 @@ private static function getInstance($value, string $name): self * Get all constants for this enum class * * @return array + * @throws \RuntimeException If invalid constant found */ protected static function getConstants(): array { @@ -245,15 +246,34 @@ protected static function getConstants(): array $reflection = new ReflectionClass($className); $constants = $reflection->getConstants(); - // Filter to only include uppercase snake_case constants + // Validate all constants $enumConstants = []; foreach ($constants as $name => $value) { - if ( - preg_match('/^[A-Z][A-Z0-9_]*$/', $name) - && (is_string($value) || is_int($value)) - ) { - $enumConstants[$name] = $value; + // Check if constant name follows uppercase snake_case pattern + if (!preg_match('/^[A-Z][A-Z0-9_]*$/', $name)) { + throw new \RuntimeException( + sprintf( + 'Invalid enum constant name "%s" in %s. Constants must be UPPER_SNAKE_CASE.', + $name, + $className + ) + ); } + + // Check if value is valid type + if (!is_string($value) && !is_int($value)) { + throw new \RuntimeException( + sprintf( + 'Invalid enum value type for constant %s::%s. ' . + 'Only string and int values are allowed, %s given.', + $className, + $name, + gettype($value) + ) + ); + } + + $enumConstants[$name] = $value; } self::$cache[$className] = $enumConstants; From ebe9d2ad6db04170dd2db108ab5e2700ee102f70 Mon Sep 17 00:00:00 2001 From: Jason Adams Date: Mon, 21 Jul 2025 10:56:22 -0600 Subject: [PATCH 08/19] refactor: removes unnecessary variable --- src/Common/AbstractEnum.php | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/Common/AbstractEnum.php b/src/Common/AbstractEnum.php index 9015b12..3926775 100644 --- a/src/Common/AbstractEnum.php +++ b/src/Common/AbstractEnum.php @@ -217,19 +217,18 @@ public static function fromValue($value): self private static function getInstance($value, string $name): self { $className = static::class; - $key = $name; if (!isset(self::$instances[$className])) { self::$instances[$className] = []; } - if (!isset(self::$instances[$className][$key])) { + if (!isset(self::$instances[$className][$name])) { $instance = new $className($value, $name); - self::$instances[$className][$key] = $instance; + self::$instances[$className][$name] = $instance; } /** @var static */ - return self::$instances[$className][$key]; + return self::$instances[$className][$name]; } /** From 970d794d6a29675ef53b990429ecc1719e282d57 Mon Sep 17 00:00:00 2001 From: Jason Adams Date: Mon, 21 Jul 2025 11:01:08 -0600 Subject: [PATCH 09/19] chore: corrects method description --- src/Common/AbstractEnum.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Common/AbstractEnum.php b/src/Common/AbstractEnum.php index 3926775..da0e2ad 100644 --- a/src/Common/AbstractEnum.php +++ b/src/Common/AbstractEnum.php @@ -282,7 +282,7 @@ protected static function getConstants(): array } /** - * Handle dynamic method calls for enum creation and checking + * Handle dynamic method calls for enum checking * * @param string $name The method name * @param array $arguments The method arguments From 189c478ecad664d0bbd0545507f0890e008e3b07 Mon Sep 17 00:00:00 2001 From: Jason Adams Date: Mon, 21 Jul 2025 12:09:35 -0600 Subject: [PATCH 10/19] refactor: adds property types --- src/Common/AbstractEnum.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Common/AbstractEnum.php b/src/Common/AbstractEnum.php index da0e2ad..4c60fc0 100644 --- a/src/Common/AbstractEnum.php +++ b/src/Common/AbstractEnum.php @@ -40,17 +40,17 @@ abstract class AbstractEnum /** * @var string The name of the enum constant */ - private $name; + private string $name; /** * @var array> Cache for reflection data */ - private static $cache = []; + private static array $cache = []; /** * @var array> Cache for enum instances */ - private static $instances = []; + private static array $instances = []; /** * Constructor is private to ensure instances are created through static methods From 71529cb92f4e776651e7956639596b6e30d2e4e9 Mon Sep 17 00:00:00 2001 From: Jason Adams Date: Mon, 21 Jul 2025 12:09:58 -0600 Subject: [PATCH 11/19] refactor: adds final to methods --- src/Common/AbstractEnum.php | 42 +++++++++++++------------------------ 1 file changed, 14 insertions(+), 28 deletions(-) diff --git a/src/Common/AbstractEnum.php b/src/Common/AbstractEnum.php index 4c60fc0..7754820 100644 --- a/src/Common/AbstractEnum.php +++ b/src/Common/AbstractEnum.php @@ -58,7 +58,7 @@ abstract class AbstractEnum * @param string|int $value The enum value * @param string $name The constant name */ - private function __construct($value, string $name) + final private function __construct($value, string $name) { $this->value = $value; $this->name = $name; @@ -71,7 +71,7 @@ private function __construct($value, string $name) * @return mixed * @throws BadMethodCallException If property doesn't exist */ - public function __get(string $property) + final public function __get(string $property) { if ($property === 'value' || $property === 'name') { return $this->$property; @@ -89,7 +89,7 @@ public function __get(string $property) * @param mixed $value The value to set * @throws BadMethodCallException Always, as enum properties are read-only */ - public function __set(string $property, $value): void + final public function __set(string $property, $value): void { throw new BadMethodCallException( sprintf('Cannot modify property %s::%s - enum properties are read-only', static::class, $property) @@ -103,7 +103,7 @@ public function __set(string $property, $value): void * @return static * @throws InvalidArgumentException If the value is not valid */ - public static function from($value): self + final public static function from($value): self { $instance = self::tryFrom($value); if ($instance === null) { @@ -120,7 +120,7 @@ public static function from($value): self * @param string|int $value The enum value * @return static|null */ - public static function tryFrom($value): ?self + final public static function tryFrom($value): ?self { $constants = self::getConstants(); foreach ($constants as $name => $constantValue) { @@ -136,7 +136,7 @@ public static function tryFrom($value): ?self * * @return static[] */ - public static function cases(): array + final public static function cases(): array { $cases = []; $constants = self::getConstants(); @@ -152,7 +152,7 @@ public static function cases(): array * @param string|int|self $other The value or enum to compare * @return bool */ - public function equals($other): bool + final public function equals($other): bool { if ($other instanceof self) { return $this->is($other); @@ -167,7 +167,7 @@ public function equals($other): bool * @param self $other The other enum to compare * @return bool */ - public function is(self $other): bool + final public function is(self $other): bool { return $this === $other; // Since we're using singletons, we can use identity comparison } @@ -177,7 +177,7 @@ public function is(self $other): bool * * @return array */ - public static function getValues(): array + final public static function getValues(): array { return self::getConstants(); } @@ -188,31 +188,17 @@ public static function getValues(): array * @param string|int $value The value to check * @return bool */ - public static function isValidValue($value): bool + final public static function isValidValue($value): bool { return in_array($value, self::getValues(), true); } - /** - * Create an enum instance from a value (deprecated, use from() instead) - * - * @param string|int $value The enum value - * @return static - * @throws InvalidArgumentException If the value is not valid - * @deprecated Use from() method instead - */ - public static function fromValue($value): self - { - return self::from($value); - } - /** * Get or create a singleton instance for the given value and name * * @param string|int $value The enum value * @param string $name The constant name * @return static - * @phpstan-return static */ private static function getInstance($value, string $name): self { @@ -237,7 +223,7 @@ private static function getInstance($value, string $name): self * @return array * @throws \RuntimeException If invalid constant found */ - protected static function getConstants(): array + final protected static function getConstants(): array { $className = static::class; @@ -289,7 +275,7 @@ protected static function getConstants(): array * @return bool * @throws BadMethodCallException If the method doesn't exist */ - public function __call(string $name, array $arguments) + final public function __call(string $name, array $arguments): bool { // Handle is* methods if (strpos($name, 'is') === 0) { @@ -314,7 +300,7 @@ public function __call(string $name, array $arguments) * @return static * @throws BadMethodCallException If the method doesn't exist */ - public static function __callStatic(string $name, array $arguments) + final public static function __callStatic(string $name, array $arguments): self { $constantName = self::camelCaseToConstant($name); $constants = self::getConstants(); @@ -348,7 +334,7 @@ private static function camelCaseToConstant(string $camelCase): string * * @return string */ - public function __toString(): string + final public function __toString(): string { return (string) $this->value; } From 006baa13860ba431e5ac83f9ce8e72f9554686ac Mon Sep 17 00:00:00 2001 From: Jason Adams Date: Mon, 21 Jul 2025 12:12:09 -0600 Subject: [PATCH 12/19] chore: removes AI-specific tool files --- .gitignore | 6 +++++ CLAUDE.md | 65 ------------------------------------------------------ 2 files changed, 6 insertions(+), 65 deletions(-) delete mode 100644 CLAUDE.md diff --git a/.gitignore b/.gitignore index 3a97163..25a49f2 100644 --- a/.gitignore +++ b/.gitignore @@ -12,4 +12,10 @@ vendor/ [Dd]esktop.ini *.DS_store .DS_store? + +############ +## AI Tools +############ + .claude/ +CLAUDE.md diff --git a/CLAUDE.md b/CLAUDE.md deleted file mode 100644 index 493adac..0000000 --- a/CLAUDE.md +++ /dev/null @@ -1,65 +0,0 @@ -# CLAUDE.md - -This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. - -## Common Development Commands - -### Linting and Code Quality -- **Run all linting checks**: `composer lint` (runs both PHPCS and PHPStan) -- **Run PHP CodeSniffer**: `composer phpcs` -- **Fix code style issues**: `composer phpcbf` -- **Run PHPStan static analysis**: `composer phpstan` - -### Testing -- **Run PHPUnit tests**: `composer phpunit` - -### Dependencies -- **Install dependencies**: `composer install` -- **Update dependencies**: `composer update` - -## High-level Architecture - -This project is a PHP AI Client SDK designed to provide a provider-agnostic API for interacting with various generative AI models. The architecture has several key design principles: - -### API Layers - -1. **Implementer API**: For developers using the SDK to add AI features to their applications - - Fluent API: Chain methods for readable, declarative code (e.g., `AiClient::prompt('...')->generateText()`) - - Traditional API: Method-based approach with arrays of arguments - -2. **Extender API**: For developers adding new providers, models, or extending functionality - - Provider Registry system for managing available AI providers - - Model discovery based on capabilities and requirements - -### Core Concepts - -- **Provider Agnostic**: Abstracts away provider-specific details, allowing code to work with any AI provider (Google, OpenAI, Anthropic, etc.) -- **Capability-Based Model Selection**: Models can be discovered and selected based on their supported capabilities (text generation, image generation, etc.) and options (input modalities, output formats, etc.) -- **Uniform Data Structures**: Consistent message formats, file representations, and results across all providers -- **Modality Support**: Designed to support arbitrary combinations of input/output modalities (text, image, audio, video) - -### Namespace Structure - -The codebase follows a structured namespace hierarchy under `WordPress\AiClient`: -- `Builders`: Fluent API builders (PromptBuilder, MessageBuilder) -- `Embeddings`: Embedding-related data structures -- `Files`: File handling contracts and implementations -- `Messages`: Message DTOs and enums -- `Operations`: Long-running operation support -- `Providers`: Provider system with contracts, models, and registry -- `Results`: Result data structures and transformations -- `Tools`: Function calling and tool support -- `Util`: Utility classes for common operations - -### Key Design Patterns - -- **Interface Segregation**: Separate interfaces for different model capabilities (TextGenerationModelInterface, ImageGenerationModelInterface, etc.) -- **Composition over Inheritance**: Models compose capabilities through interfaces rather than inheritance -- **DTO Pattern**: Data Transfer Objects for messages, results, and configurations with JSON schema support -- **Builder Pattern**: Fluent builders for constructing prompts and messages - -### PHP Compatibility - -- Minimum PHP version: 7.4 -- Follows PER Coding Style -- Uses type hints wherever possible within PHP 7.4 constraints From 742152a82e9cd8a64b1b56978d6b79ca5d0a7ddd Mon Sep 17 00:00:00 2001 From: Jason Adams Date: Tue, 22 Jul 2025 08:23:38 -0600 Subject: [PATCH 13/19] chore: adds since tags --- src/Common/AbstractEnum.php | 18 ++++++++++++++++++ src/Messages/Enums/MessagePartTypeEnum.php | 1 + src/Messages/Enums/MessageRoleEnum.php | 1 + src/Messages/Enums/ModalityEnum.php | 1 + src/Operations/Enums/OperationStateEnum.php | 1 + src/Providers/Enums/ProviderTypeEnum.php | 1 + src/Providers/Enums/ToolTypeEnum.php | 1 + src/Providers/Models/Enums/CapabilityEnum.php | 2 ++ src/Providers/Models/Enums/OptionEnum.php | 2 ++ src/Results/Enums/FinishReasonEnum.php | 1 + 10 files changed, 29 insertions(+) diff --git a/src/Common/AbstractEnum.php b/src/Common/AbstractEnum.php index 7754820..3d30646 100644 --- a/src/Common/AbstractEnum.php +++ b/src/Common/AbstractEnum.php @@ -29,6 +29,8 @@ * $enum->equals('first'); // Returns true * $enum->is(PersonEnum::firstName()); // Returns true * PersonEnum::cases(); // Returns array of all enum instances + * + * @since n.e.x.t */ abstract class AbstractEnum { @@ -55,6 +57,7 @@ abstract class AbstractEnum /** * Constructor is private to ensure instances are created through static methods * + * @since n.e.x.t * @param string|int $value The enum value * @param string $name The constant name */ @@ -67,6 +70,7 @@ final private function __construct($value, string $name) /** * Magic getter to provide read-only access to properties * + * @since n.e.x.t * @param string $property The property name * @return mixed * @throws BadMethodCallException If property doesn't exist @@ -85,6 +89,7 @@ final public function __get(string $property) /** * Magic setter to prevent property modification * + * @since n.e.x.t * @param string $property The property name * @param mixed $value The value to set * @throws BadMethodCallException Always, as enum properties are read-only @@ -99,6 +104,7 @@ final public function __set(string $property, $value): void /** * Create an enum instance from a value, throws exception if invalid * + * @since n.e.x.t * @param string|int $value The enum value * @return static * @throws InvalidArgumentException If the value is not valid @@ -117,6 +123,7 @@ final public static function from($value): self /** * Try to create an enum instance from a value, returns null if invalid * + * @since n.e.x.t * @param string|int $value The enum value * @return static|null */ @@ -134,6 +141,7 @@ final public static function tryFrom($value): ?self /** * Get all enum cases * + * @since n.e.x.t * @return static[] */ final public static function cases(): array @@ -149,6 +157,7 @@ final public static function cases(): array /** * Check if this enum has the same value as the given value * + * @since n.e.x.t * @param string|int|self $other The value or enum to compare * @return bool */ @@ -164,6 +173,7 @@ final public function equals($other): bool /** * Check if this enum is the same instance type and value as another enum * + * @since n.e.x.t * @param self $other The other enum to compare * @return bool */ @@ -175,6 +185,7 @@ final public function is(self $other): bool /** * Get all valid values for this enum * + * @since n.e.x.t * @return array */ final public static function getValues(): array @@ -185,6 +196,7 @@ final public static function getValues(): array /** * Check if a value is valid for this enum * + * @since n.e.x.t * @param string|int $value The value to check * @return bool */ @@ -196,6 +208,7 @@ final public static function isValidValue($value): bool /** * Get or create a singleton instance for the given value and name * + * @since n.e.x.t * @param string|int $value The enum value * @param string $name The constant name * @return static @@ -220,6 +233,7 @@ private static function getInstance($value, string $name): self /** * Get all constants for this enum class * + * @since n.e.x.t * @return array * @throws \RuntimeException If invalid constant found */ @@ -270,6 +284,7 @@ final protected static function getConstants(): array /** * Handle dynamic method calls for enum checking * + * @since n.e.x.t * @param string $name The method name * @param array $arguments The method arguments * @return bool @@ -295,6 +310,7 @@ final public function __call(string $name, array $arguments): bool /** * Handle static method calls for enum creation * + * @since n.e.x.t * @param string $name The method name * @param array $arguments The method arguments * @return static @@ -317,6 +333,7 @@ final public static function __callStatic(string $name, array $arguments): self /** * Convert camelCase to CONSTANT_CASE * + * @since n.e.x.t * @param string $camelCase The camelCase string * @return string The CONSTANT_CASE version */ @@ -332,6 +349,7 @@ private static function camelCaseToConstant(string $camelCase): string /** * String representation of the enum * + * @since n.e.x.t * @return string */ final public function __toString(): string diff --git a/src/Messages/Enums/MessagePartTypeEnum.php b/src/Messages/Enums/MessagePartTypeEnum.php index 2bb9014..a215178 100644 --- a/src/Messages/Enums/MessagePartTypeEnum.php +++ b/src/Messages/Enums/MessagePartTypeEnum.php @@ -9,6 +9,7 @@ /** * Enum for message part types * + * @since n.e.x.t * @method static self text() Create an instance for TEXT type * @method static self inlineFile() Create an instance for INLINE_FILE type * @method static self remoteFile() Create an instance for REMOTE_FILE type diff --git a/src/Messages/Enums/MessageRoleEnum.php b/src/Messages/Enums/MessageRoleEnum.php index 7b2f08d..dc0613c 100644 --- a/src/Messages/Enums/MessageRoleEnum.php +++ b/src/Messages/Enums/MessageRoleEnum.php @@ -9,6 +9,7 @@ /** * Enum for message roles in AI conversations * + * @since n.e.x.t * @method static self user() Create an instance for USER role * @method static self model() Create an instance for MODEL role * @method static self system() Create an instance for SYSTEM role diff --git a/src/Messages/Enums/ModalityEnum.php b/src/Messages/Enums/ModalityEnum.php index c2e8217..803af9b 100644 --- a/src/Messages/Enums/ModalityEnum.php +++ b/src/Messages/Enums/ModalityEnum.php @@ -9,6 +9,7 @@ /** * Enum for input/output modalities * + * @since n.e.x.t * @method static self text() Create an instance for TEXT modality * @method static self document() Create an instance for DOCUMENT modality * @method static self image() Create an instance for IMAGE modality diff --git a/src/Operations/Enums/OperationStateEnum.php b/src/Operations/Enums/OperationStateEnum.php index 7c68dbd..fb58b58 100644 --- a/src/Operations/Enums/OperationStateEnum.php +++ b/src/Operations/Enums/OperationStateEnum.php @@ -9,6 +9,7 @@ /** * Enum for operation states * + * @since n.e.x.t * @method static self starting() Create an instance for STARTING state * @method static self processing() Create an instance for PROCESSING state * @method static self succeeded() Create an instance for SUCCEEDED state diff --git a/src/Providers/Enums/ProviderTypeEnum.php b/src/Providers/Enums/ProviderTypeEnum.php index 90865bb..b29edf1 100644 --- a/src/Providers/Enums/ProviderTypeEnum.php +++ b/src/Providers/Enums/ProviderTypeEnum.php @@ -9,6 +9,7 @@ /** * Enum for provider types * + * @since n.e.x.t * @method static self cloud() Create an instance for CLOUD type * @method static self server() Create an instance for SERVER type * @method static self client() Create an instance for CLIENT type diff --git a/src/Providers/Enums/ToolTypeEnum.php b/src/Providers/Enums/ToolTypeEnum.php index b03bbc4..048835c 100644 --- a/src/Providers/Enums/ToolTypeEnum.php +++ b/src/Providers/Enums/ToolTypeEnum.php @@ -9,6 +9,7 @@ /** * Enum for tool types * + * @since n.e.x.t * @method static self functionDeclarations() Create an instance for FUNCTION_DECLARATIONS type * @method static self webSearch() Create an instance for WEB_SEARCH type * @method bool isFunctionDeclarations() Check if the type is FUNCTION_DECLARATIONS diff --git a/src/Providers/Models/Enums/CapabilityEnum.php b/src/Providers/Models/Enums/CapabilityEnum.php index bc3fb8b..cc2238c 100644 --- a/src/Providers/Models/Enums/CapabilityEnum.php +++ b/src/Providers/Models/Enums/CapabilityEnum.php @@ -9,6 +9,8 @@ /** * Enum for model capabilities * + * @since n.e.x.t + * * @method static self textGeneration() Create an instance for TEXT_GENERATION capability * @method static self imageGeneration() Create an instance for IMAGE_GENERATION capability * @method static self textToSpeechConversion() Create an instance for TEXT_TO_SPEECH_CONVERSION capability diff --git a/src/Providers/Models/Enums/OptionEnum.php b/src/Providers/Models/Enums/OptionEnum.php index cdb9322..ed3a49a 100644 --- a/src/Providers/Models/Enums/OptionEnum.php +++ b/src/Providers/Models/Enums/OptionEnum.php @@ -9,6 +9,8 @@ /** * Enum for model options * + * @since n.e.x.t + * * @method static self inputModalities() Create an instance for INPUT_MODALITIES option * @method static self outputModalities() Create an instance for OUTPUT_MODALITIES option * @method static self systemInstruction() Create an instance for SYSTEM_INSTRUCTION option diff --git a/src/Results/Enums/FinishReasonEnum.php b/src/Results/Enums/FinishReasonEnum.php index eac91b0..c832538 100644 --- a/src/Results/Enums/FinishReasonEnum.php +++ b/src/Results/Enums/FinishReasonEnum.php @@ -9,6 +9,7 @@ /** * Enum for finish reasons of AI generation * + * @since n.e.x.t * @method static self stop() Create an instance for STOP reason * @method static self length() Create an instance for LENGTH reason * @method static self contentFilter() Create an instance for CONTENT_FILTER reason From c78973e9f618291d1c614a7abec25fbd3f5187e2 Mon Sep 17 00:00:00 2001 From: Jason Adams Date: Tue, 22 Jul 2025 11:39:07 -0600 Subject: [PATCH 14/19] refactor: restricts enum values to strings --- src/Common/AbstractEnum.php | 40 ++++++++++++++++++------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/src/Common/AbstractEnum.php b/src/Common/AbstractEnum.php index 3d30646..23857cd 100644 --- a/src/Common/AbstractEnum.php +++ b/src/Common/AbstractEnum.php @@ -35,9 +35,9 @@ abstract class AbstractEnum { /** - * @var string|int The value of the enum instance + * @var string The value of the enum instance */ - private $value; + private string $value; /** * @var string The name of the enum constant @@ -45,7 +45,7 @@ abstract class AbstractEnum private string $name; /** - * @var array> Cache for reflection data + * @var array> Cache for reflection data */ private static array $cache = []; @@ -58,10 +58,10 @@ abstract class AbstractEnum * Constructor is private to ensure instances are created through static methods * * @since n.e.x.t - * @param string|int $value The enum value + * @param string $value The enum value * @param string $name The constant name */ - final private function __construct($value, string $name) + final private function __construct(string $value, string $name) { $this->value = $value; $this->name = $name; @@ -105,16 +105,16 @@ final public function __set(string $property, $value): void * Create an enum instance from a value, throws exception if invalid * * @since n.e.x.t - * @param string|int $value The enum value + * @param string $value The enum value * @return static * @throws InvalidArgumentException If the value is not valid */ - final public static function from($value): self + final public static function from(string $value): self { $instance = self::tryFrom($value); if ($instance === null) { throw new InvalidArgumentException( - sprintf('%s is not a valid backing value for enum %s', (string) $value, static::class) + sprintf('%s is not a valid backing value for enum %s', $value, static::class) ); } return $instance; @@ -124,10 +124,10 @@ final public static function from($value): self * Try to create an enum instance from a value, returns null if invalid * * @since n.e.x.t - * @param string|int $value The enum value + * @param string $value The enum value * @return static|null */ - final public static function tryFrom($value): ?self + final public static function tryFrom(string $value): ?self { $constants = self::getConstants(); foreach ($constants as $name => $constantValue) { @@ -158,7 +158,7 @@ final public static function cases(): array * Check if this enum has the same value as the given value * * @since n.e.x.t - * @param string|int|self $other The value or enum to compare + * @param string|self $other The value or enum to compare * @return bool */ final public function equals($other): bool @@ -186,7 +186,7 @@ final public function is(self $other): bool * Get all valid values for this enum * * @since n.e.x.t - * @return array + * @return array */ final public static function getValues(): array { @@ -197,10 +197,10 @@ final public static function getValues(): array * Check if a value is valid for this enum * * @since n.e.x.t - * @param string|int $value The value to check + * @param string $value The value to check * @return bool */ - final public static function isValidValue($value): bool + final public static function isValidValue(string $value): bool { return in_array($value, self::getValues(), true); } @@ -209,11 +209,11 @@ final public static function isValidValue($value): bool * Get or create a singleton instance for the given value and name * * @since n.e.x.t - * @param string|int $value The enum value + * @param string $value The enum value * @param string $name The constant name * @return static */ - private static function getInstance($value, string $name): self + private static function getInstance(string $value, string $name): self { $className = static::class; @@ -234,7 +234,7 @@ private static function getInstance($value, string $name): self * Get all constants for this enum class * * @since n.e.x.t - * @return array + * @return array * @throws \RuntimeException If invalid constant found */ final protected static function getConstants(): array @@ -260,11 +260,11 @@ final protected static function getConstants(): array } // Check if value is valid type - if (!is_string($value) && !is_int($value)) { + if (!is_string($value)) { throw new \RuntimeException( sprintf( 'Invalid enum value type for constant %s::%s. ' . - 'Only string and int values are allowed, %s given.', + 'Only string values are allowed, %s given.', $className, $name, gettype($value) @@ -354,6 +354,6 @@ private static function camelCaseToConstant(string $camelCase): string */ final public function __toString(): string { - return (string) $this->value; + return $this->value; } } From 863a07cb20486891c1884411eabbbb45d18dfb79 Mon Sep 17 00:00:00 2001 From: Jason Adams Date: Tue, 22 Jul 2025 11:56:27 -0600 Subject: [PATCH 15/19] refactor: updates docblock with new standards --- src/Common/AbstractEnum.php | 106 +++++++++--------- src/Messages/Enums/MessagePartTypeEnum.php | 32 +++--- src/Messages/Enums/MessageRoleEnum.php | 20 ++-- src/Messages/Enums/ModalityEnum.php | 32 +++--- src/Operations/Enums/OperationStateEnum.php | 32 +++--- src/Providers/Enums/ProviderTypeEnum.php | 20 ++-- src/Providers/Enums/ToolTypeEnum.php | 14 +-- src/Providers/Models/Enums/CapabilityEnum.php | 50 ++++----- src/Providers/Models/Enums/OptionEnum.php | 62 +++++----- src/Results/Enums/FinishReasonEnum.php | 32 +++--- 10 files changed, 200 insertions(+), 200 deletions(-) diff --git a/src/Common/AbstractEnum.php b/src/Common/AbstractEnum.php index 23857cd..bfbe6d2 100644 --- a/src/Common/AbstractEnum.php +++ b/src/Common/AbstractEnum.php @@ -55,11 +55,11 @@ abstract class AbstractEnum private static array $instances = []; /** - * Constructor is private to ensure instances are created through static methods + * Constructor is private to ensure instances are created through static methods. * * @since n.e.x.t - * @param string $value The enum value - * @param string $name The constant name + * @param string $value The enum value. + * @param string $name The constant name. */ final private function __construct(string $value, string $name) { @@ -68,12 +68,12 @@ final private function __construct(string $value, string $name) } /** - * Magic getter to provide read-only access to properties + * Provides read-only access to properties. * * @since n.e.x.t - * @param string $property The property name - * @return mixed - * @throws BadMethodCallException If property doesn't exist + * @param string $property The property name. + * @return mixed The property value. + * @throws BadMethodCallException If property doesn't exist. */ final public function __get(string $property) { @@ -87,12 +87,12 @@ final public function __get(string $property) } /** - * Magic setter to prevent property modification + * Prevents property modification. * * @since n.e.x.t - * @param string $property The property name - * @param mixed $value The value to set - * @throws BadMethodCallException Always, as enum properties are read-only + * @param string $property The property name. + * @param mixed $value The value to set. + * @throws BadMethodCallException Always, as enum properties are read-only. */ final public function __set(string $property, $value): void { @@ -102,12 +102,12 @@ final public function __set(string $property, $value): void } /** - * Create an enum instance from a value, throws exception if invalid + * Creates an enum instance from a value, throws exception if invalid. * * @since n.e.x.t - * @param string $value The enum value - * @return static - * @throws InvalidArgumentException If the value is not valid + * @param string $value The enum value. + * @return static The enum instance. + * @throws InvalidArgumentException If the value is not valid. */ final public static function from(string $value): self { @@ -121,11 +121,11 @@ final public static function from(string $value): self } /** - * Try to create an enum instance from a value, returns null if invalid + * Tries to create an enum instance from a value, returns null if invalid. * * @since n.e.x.t - * @param string $value The enum value - * @return static|null + * @param string $value The enum value. + * @return static|null The enum instance or null. */ final public static function tryFrom(string $value): ?self { @@ -139,10 +139,10 @@ final public static function tryFrom(string $value): ?self } /** - * Get all enum cases + * Gets all enum cases. * * @since n.e.x.t - * @return static[] + * @return static[] Array of all enum instances. */ final public static function cases(): array { @@ -155,11 +155,11 @@ final public static function cases(): array } /** - * Check if this enum has the same value as the given value + * Checks if this enum has the same value as the given value. * * @since n.e.x.t - * @param string|self $other The value or enum to compare - * @return bool + * @param string|self $other The value or enum to compare. + * @return bool True if values are equal. */ final public function equals($other): bool { @@ -171,11 +171,11 @@ final public function equals($other): bool } /** - * Check if this enum is the same instance type and value as another enum + * Checks if this enum is the same instance type and value as another enum. * * @since n.e.x.t - * @param self $other The other enum to compare - * @return bool + * @param self $other The other enum to compare. + * @return bool True if enums are identical. */ final public function is(self $other): bool { @@ -183,10 +183,10 @@ final public function is(self $other): bool } /** - * Get all valid values for this enum + * Gets all valid values for this enum. * * @since n.e.x.t - * @return array + * @return array Map of constant names to values. */ final public static function getValues(): array { @@ -194,11 +194,11 @@ final public static function getValues(): array } /** - * Check if a value is valid for this enum + * Checks if a value is valid for this enum. * * @since n.e.x.t - * @param string $value The value to check - * @return bool + * @param string $value The value to check. + * @return bool True if value is valid. */ final public static function isValidValue(string $value): bool { @@ -206,12 +206,12 @@ final public static function isValidValue(string $value): bool } /** - * Get or create a singleton instance for the given value and name + * Gets or creates a singleton instance for the given value and name. * * @since n.e.x.t - * @param string $value The enum value - * @param string $name The constant name - * @return static + * @param string $value The enum value. + * @param string $name The constant name. + * @return static The enum instance. */ private static function getInstance(string $value, string $name): self { @@ -231,11 +231,11 @@ private static function getInstance(string $value, string $name): self } /** - * Get all constants for this enum class + * Gets all constants for this enum class. * * @since n.e.x.t - * @return array - * @throws \RuntimeException If invalid constant found + * @return array Map of constant names to values. + * @throws \RuntimeException If invalid constant found. */ final protected static function getConstants(): array { @@ -282,13 +282,13 @@ final protected static function getConstants(): array } /** - * Handle dynamic method calls for enum checking + * Handles dynamic method calls for enum checking. * * @since n.e.x.t - * @param string $name The method name - * @param array $arguments The method arguments - * @return bool - * @throws BadMethodCallException If the method doesn't exist + * @param string $name The method name. + * @param array $arguments The method arguments. + * @return bool True if the enum value matches. + * @throws BadMethodCallException If the method doesn't exist. */ final public function __call(string $name, array $arguments): bool { @@ -308,13 +308,13 @@ final public function __call(string $name, array $arguments): bool } /** - * Handle static method calls for enum creation + * Handles static method calls for enum creation. * * @since n.e.x.t - * @param string $name The method name - * @param array $arguments The method arguments - * @return static - * @throws BadMethodCallException If the method doesn't exist + * @param string $name The method name. + * @param array $arguments The method arguments. + * @return static The enum instance. + * @throws BadMethodCallException If the method doesn't exist. */ final public static function __callStatic(string $name, array $arguments): self { @@ -331,11 +331,11 @@ final public static function __callStatic(string $name, array $arguments): self } /** - * Convert camelCase to CONSTANT_CASE + * Converts camelCase to CONSTANT_CASE. * * @since n.e.x.t - * @param string $camelCase The camelCase string - * @return string The CONSTANT_CASE version + * @param string $camelCase The camelCase string. + * @return string The CONSTANT_CASE version. */ private static function camelCaseToConstant(string $camelCase): string { @@ -347,10 +347,10 @@ private static function camelCaseToConstant(string $camelCase): string } /** - * String representation of the enum + * Returns string representation of the enum. * * @since n.e.x.t - * @return string + * @return string The enum value. */ final public function __toString(): string { diff --git a/src/Messages/Enums/MessagePartTypeEnum.php b/src/Messages/Enums/MessagePartTypeEnum.php index a215178..139eb13 100644 --- a/src/Messages/Enums/MessagePartTypeEnum.php +++ b/src/Messages/Enums/MessagePartTypeEnum.php @@ -7,44 +7,44 @@ use WordPress\AiClient\Common\AbstractEnum; /** - * Enum for message part types + * Enum for message part types. * * @since n.e.x.t - * @method static self text() Create an instance for TEXT type - * @method static self inlineFile() Create an instance for INLINE_FILE type - * @method static self remoteFile() Create an instance for REMOTE_FILE type - * @method static self functionCall() Create an instance for FUNCTION_CALL type - * @method static self functionResponse() Create an instance for FUNCTION_RESPONSE type - * @method bool isText() Check if the type is TEXT - * @method bool isInlineFile() Check if the type is INLINE_FILE - * @method bool isRemoteFile() Check if the type is REMOTE_FILE - * @method bool isFunctionCall() Check if the type is FUNCTION_CALL - * @method bool isFunctionResponse() Check if the type is FUNCTION_RESPONSE + * @method static self text() Creates an instance for TEXT type. + * @method static self inlineFile() Creates an instance for INLINE_FILE type. + * @method static self remoteFile() Creates an instance for REMOTE_FILE type. + * @method static self functionCall() Creates an instance for FUNCTION_CALL type. + * @method static self functionResponse() Creates an instance for FUNCTION_RESPONSE type. + * @method bool isText() Checks if the type is TEXT. + * @method bool isInlineFile() Checks if the type is INLINE_FILE. + * @method bool isRemoteFile() Checks if the type is REMOTE_FILE. + * @method bool isFunctionCall() Checks if the type is FUNCTION_CALL. + * @method bool isFunctionResponse() Checks if the type is FUNCTION_RESPONSE. */ class MessagePartTypeEnum extends AbstractEnum { /** - * Text content + * Text content. */ public const TEXT = 'text'; /** - * Inline file content (base64 encoded) + * Inline file content (base64 encoded). */ public const INLINE_FILE = 'inline_file'; /** - * Remote file reference (URL) + * Remote file reference (URL). */ public const REMOTE_FILE = 'remote_file'; /** - * Function call request + * Function call request. */ public const FUNCTION_CALL = 'function_call'; /** - * Function response + * Function response. */ public const FUNCTION_RESPONSE = 'function_response'; } diff --git a/src/Messages/Enums/MessageRoleEnum.php b/src/Messages/Enums/MessageRoleEnum.php index dc0613c..b350228 100644 --- a/src/Messages/Enums/MessageRoleEnum.php +++ b/src/Messages/Enums/MessageRoleEnum.php @@ -7,30 +7,30 @@ use WordPress\AiClient\Common\AbstractEnum; /** - * Enum for message roles in AI conversations + * Enum for message roles in AI conversations. * * @since n.e.x.t - * @method static self user() Create an instance for USER role - * @method static self model() Create an instance for MODEL role - * @method static self system() Create an instance for SYSTEM role - * @method bool isUser() Check if the role is USER - * @method bool isModel() Check if the role is MODEL - * @method bool isSystem() Check if the role is SYSTEM + * @method static self user() Creates an instance for USER role. + * @method static self model() Creates an instance for MODEL role. + * @method static self system() Creates an instance for SYSTEM role. + * @method bool isUser() Checks if the role is USER. + * @method bool isModel() Checks if the role is MODEL. + * @method bool isSystem() Checks if the role is SYSTEM. */ class MessageRoleEnum extends AbstractEnum { /** - * User role - messages from the user + * User role - messages from the user. */ public const USER = 'user'; /** - * Model role - messages from the AI model + * Model role - messages from the AI model. */ public const MODEL = 'model'; /** - * System role - system instructions + * System role - system instructions. */ public const SYSTEM = 'system'; } diff --git a/src/Messages/Enums/ModalityEnum.php b/src/Messages/Enums/ModalityEnum.php index 803af9b..102e79f 100644 --- a/src/Messages/Enums/ModalityEnum.php +++ b/src/Messages/Enums/ModalityEnum.php @@ -7,44 +7,44 @@ use WordPress\AiClient\Common\AbstractEnum; /** - * Enum for input/output modalities + * Enum for input/output modalities. * * @since n.e.x.t - * @method static self text() Create an instance for TEXT modality - * @method static self document() Create an instance for DOCUMENT modality - * @method static self image() Create an instance for IMAGE modality - * @method static self audio() Create an instance for AUDIO modality - * @method static self video() Create an instance for VIDEO modality - * @method bool isText() Check if the modality is TEXT - * @method bool isDocument() Check if the modality is DOCUMENT - * @method bool isImage() Check if the modality is IMAGE - * @method bool isAudio() Check if the modality is AUDIO - * @method bool isVideo() Check if the modality is VIDEO + * @method static self text() Creates an instance for TEXT modality. + * @method static self document() Creates an instance for DOCUMENT modality. + * @method static self image() Creates an instance for IMAGE modality. + * @method static self audio() Creates an instance for AUDIO modality. + * @method static self video() Creates an instance for VIDEO modality. + * @method bool isText() Checks if the modality is TEXT. + * @method bool isDocument() Checks if the modality is DOCUMENT. + * @method bool isImage() Checks if the modality is IMAGE. + * @method bool isAudio() Checks if the modality is AUDIO. + * @method bool isVideo() Checks if the modality is VIDEO. */ class ModalityEnum extends AbstractEnum { /** - * Text modality + * Text modality. */ public const TEXT = 'text'; /** - * Document modality (PDFs, Word docs, etc.) + * Document modality (PDFs, Word docs, etc.). */ public const DOCUMENT = 'document'; /** - * Image modality + * Image modality. */ public const IMAGE = 'image'; /** - * Audio modality + * Audio modality. */ public const AUDIO = 'audio'; /** - * Video modality + * Video modality. */ public const VIDEO = 'video'; } diff --git a/src/Operations/Enums/OperationStateEnum.php b/src/Operations/Enums/OperationStateEnum.php index fb58b58..36fa633 100644 --- a/src/Operations/Enums/OperationStateEnum.php +++ b/src/Operations/Enums/OperationStateEnum.php @@ -7,44 +7,44 @@ use WordPress\AiClient\Common\AbstractEnum; /** - * Enum for operation states + * Enum for operation states. * * @since n.e.x.t - * @method static self starting() Create an instance for STARTING state - * @method static self processing() Create an instance for PROCESSING state - * @method static self succeeded() Create an instance for SUCCEEDED state - * @method static self failed() Create an instance for FAILED state - * @method static self canceled() Create an instance for CANCELED state - * @method bool isStarting() Check if the state is STARTING - * @method bool isProcessing() Check if the state is PROCESSING - * @method bool isSucceeded() Check if the state is SUCCEEDED - * @method bool isFailed() Check if the state is FAILED - * @method bool isCanceled() Check if the state is CANCELED + * @method static self starting() Creates an instance for STARTING state. + * @method static self processing() Creates an instance for PROCESSING state. + * @method static self succeeded() Creates an instance for SUCCEEDED state. + * @method static self failed() Creates an instance for FAILED state. + * @method static self canceled() Creates an instance for CANCELED state. + * @method bool isStarting() Checks if the state is STARTING. + * @method bool isProcessing() Checks if the state is PROCESSING. + * @method bool isSucceeded() Checks if the state is SUCCEEDED. + * @method bool isFailed() Checks if the state is FAILED. + * @method bool isCanceled() Checks if the state is CANCELED. */ class OperationStateEnum extends AbstractEnum { /** - * Operation is starting + * Operation is starting. */ public const STARTING = 'starting'; /** - * Operation is processing + * Operation is processing. */ public const PROCESSING = 'processing'; /** - * Operation succeeded + * Operation succeeded. */ public const SUCCEEDED = 'succeeded'; /** - * Operation failed + * Operation failed. */ public const FAILED = 'failed'; /** - * Operation was canceled + * Operation was canceled. */ public const CANCELED = 'canceled'; } diff --git a/src/Providers/Enums/ProviderTypeEnum.php b/src/Providers/Enums/ProviderTypeEnum.php index b29edf1..6086f39 100644 --- a/src/Providers/Enums/ProviderTypeEnum.php +++ b/src/Providers/Enums/ProviderTypeEnum.php @@ -7,30 +7,30 @@ use WordPress\AiClient\Common\AbstractEnum; /** - * Enum for provider types + * Enum for provider types. * * @since n.e.x.t - * @method static self cloud() Create an instance for CLOUD type - * @method static self server() Create an instance for SERVER type - * @method static self client() Create an instance for CLIENT type - * @method bool isCloud() Check if the type is CLOUD - * @method bool isServer() Check if the type is SERVER - * @method bool isClient() Check if the type is CLIENT + * @method static self cloud() Creates an instance for CLOUD type. + * @method static self server() Creates an instance for SERVER type. + * @method static self client() Creates an instance for CLIENT type. + * @method bool isCloud() Checks if the type is CLOUD. + * @method bool isServer() Checks if the type is SERVER. + * @method bool isClient() Checks if the type is CLIENT. */ class ProviderTypeEnum extends AbstractEnum { /** - * Cloud-based AI provider (e.g., OpenAI, Google, Anthropic) + * Cloud-based AI provider (e.g., OpenAI, Google, Anthropic). */ public const CLOUD = 'cloud'; /** - * Server-side AI provider (e.g., self-hosted models) + * Server-side AI provider (e.g., self-hosted models). */ public const SERVER = 'server'; /** - * Client-side AI provider (e.g., browser-based models) + * Client-side AI provider (e.g., browser-based models). */ public const CLIENT = 'client'; } diff --git a/src/Providers/Enums/ToolTypeEnum.php b/src/Providers/Enums/ToolTypeEnum.php index 048835c..d92d472 100644 --- a/src/Providers/Enums/ToolTypeEnum.php +++ b/src/Providers/Enums/ToolTypeEnum.php @@ -7,23 +7,23 @@ use WordPress\AiClient\Common\AbstractEnum; /** - * Enum for tool types + * Enum for tool types. * * @since n.e.x.t - * @method static self functionDeclarations() Create an instance for FUNCTION_DECLARATIONS type - * @method static self webSearch() Create an instance for WEB_SEARCH type - * @method bool isFunctionDeclarations() Check if the type is FUNCTION_DECLARATIONS - * @method bool isWebSearch() Check if the type is WEB_SEARCH + * @method static self functionDeclarations() Creates an instance for FUNCTION_DECLARATIONS type. + * @method static self webSearch() Creates an instance for WEB_SEARCH type. + * @method bool isFunctionDeclarations() Checks if the type is FUNCTION_DECLARATIONS. + * @method bool isWebSearch() Checks if the type is WEB_SEARCH. */ class ToolTypeEnum extends AbstractEnum { /** - * Function declarations tool type + * Function declarations tool type. */ public const FUNCTION_DECLARATIONS = 'function_declarations'; /** - * Web search tool type + * Web search tool type. */ public const WEB_SEARCH = 'web_search'; } diff --git a/src/Providers/Models/Enums/CapabilityEnum.php b/src/Providers/Models/Enums/CapabilityEnum.php index cc2238c..68a8c86 100644 --- a/src/Providers/Models/Enums/CapabilityEnum.php +++ b/src/Providers/Models/Enums/CapabilityEnum.php @@ -7,66 +7,66 @@ use WordPress\AiClient\Common\AbstractEnum; /** - * Enum for model capabilities + * Enum for model capabilities. * * @since n.e.x.t * - * @method static self textGeneration() Create an instance for TEXT_GENERATION capability - * @method static self imageGeneration() Create an instance for IMAGE_GENERATION capability - * @method static self textToSpeechConversion() Create an instance for TEXT_TO_SPEECH_CONVERSION capability - * @method static self speechGeneration() Create an instance for SPEECH_GENERATION capability - * @method static self musicGeneration() Create an instance for MUSIC_GENERATION capability - * @method static self videoGeneration() Create an instance for VIDEO_GENERATION capability - * @method static self embeddingGeneration() Create an instance for EMBEDDING_GENERATION capability - * @method static self chatHistory() Create an instance for CHAT_HISTORY capability - * @method bool isTextGeneration() Check if the capability is TEXT_GENERATION - * @method bool isImageGeneration() Check if the capability is IMAGE_GENERATION - * @method bool isTextToSpeechConversion() Check if the capability is TEXT_TO_SPEECH_CONVERSION - * @method bool isSpeechGeneration() Check if the capability is SPEECH_GENERATION - * @method bool isMusicGeneration() Check if the capability is MUSIC_GENERATION - * @method bool isVideoGeneration() Check if the capability is VIDEO_GENERATION - * @method bool isEmbeddingGeneration() Check if the capability is EMBEDDING_GENERATION - * @method bool isChatHistory() Check if the capability is CHAT_HISTORY + * @method static self textGeneration() Creates an instance for TEXT_GENERATION capability. + * @method static self imageGeneration() Creates an instance for IMAGE_GENERATION capability. + * @method static self textToSpeechConversion() Creates an instance for TEXT_TO_SPEECH_CONVERSION capability. + * @method static self speechGeneration() Creates an instance for SPEECH_GENERATION capability. + * @method static self musicGeneration() Creates an instance for MUSIC_GENERATION capability. + * @method static self videoGeneration() Creates an instance for VIDEO_GENERATION capability. + * @method static self embeddingGeneration() Creates an instance for EMBEDDING_GENERATION capability. + * @method static self chatHistory() Creates an instance for CHAT_HISTORY capability. + * @method bool isTextGeneration() Checks if the capability is TEXT_GENERATION. + * @method bool isImageGeneration() Checks if the capability is IMAGE_GENERATION. + * @method bool isTextToSpeechConversion() Checks if the capability is TEXT_TO_SPEECH_CONVERSION. + * @method bool isSpeechGeneration() Checks if the capability is SPEECH_GENERATION. + * @method bool isMusicGeneration() Checks if the capability is MUSIC_GENERATION. + * @method bool isVideoGeneration() Checks if the capability is VIDEO_GENERATION. + * @method bool isEmbeddingGeneration() Checks if the capability is EMBEDDING_GENERATION. + * @method bool isChatHistory() Checks if the capability is CHAT_HISTORY. */ class CapabilityEnum extends AbstractEnum { /** - * Text generation capability + * Text generation capability. */ public const TEXT_GENERATION = 'text_generation'; /** - * Image generation capability + * Image generation capability. */ public const IMAGE_GENERATION = 'image_generation'; /** - * Text to speech conversion capability + * Text to speech conversion capability. */ public const TEXT_TO_SPEECH_CONVERSION = 'text_to_speech_conversion'; /** - * Speech generation capability + * Speech generation capability. */ public const SPEECH_GENERATION = 'speech_generation'; /** - * Music generation capability + * Music generation capability. */ public const MUSIC_GENERATION = 'music_generation'; /** - * Video generation capability + * Video generation capability. */ public const VIDEO_GENERATION = 'video_generation'; /** - * Embedding generation capability + * Embedding generation capability. */ public const EMBEDDING_GENERATION = 'embedding_generation'; /** - * Chat history support capability + * Chat history support capability. */ public const CHAT_HISTORY = 'chat_history'; } diff --git a/src/Providers/Models/Enums/OptionEnum.php b/src/Providers/Models/Enums/OptionEnum.php index ed3a49a..96fd37a 100644 --- a/src/Providers/Models/Enums/OptionEnum.php +++ b/src/Providers/Models/Enums/OptionEnum.php @@ -7,80 +7,80 @@ use WordPress\AiClient\Common\AbstractEnum; /** - * Enum for model options + * Enum for model options. * * @since n.e.x.t * - * @method static self inputModalities() Create an instance for INPUT_MODALITIES option - * @method static self outputModalities() Create an instance for OUTPUT_MODALITIES option - * @method static self systemInstruction() Create an instance for SYSTEM_INSTRUCTION option - * @method static self candidateCount() Create an instance for CANDIDATE_COUNT option - * @method static self maxTokens() Create an instance for MAX_TOKENS option - * @method static self temperature() Create an instance for TEMPERATURE option - * @method static self topK() Create an instance for TOP_K option - * @method static self topP() Create an instance for TOP_P option - * @method static self outputMimeType() Create an instance for OUTPUT_MIME_TYPE option - * @method static self outputSchema() Create an instance for OUTPUT_SCHEMA option - * @method bool isInputModalities() Check if the option is INPUT_MODALITIES - * @method bool isOutputModalities() Check if the option is OUTPUT_MODALITIES - * @method bool isSystemInstruction() Check if the option is SYSTEM_INSTRUCTION - * @method bool isCandidateCount() Check if the option is CANDIDATE_COUNT - * @method bool isMaxTokens() Check if the option is MAX_TOKENS - * @method bool isTemperature() Check if the option is TEMPERATURE - * @method bool isTopK() Check if the option is TOP_K - * @method bool isTopP() Check if the option is TOP_P - * @method bool isOutputMimeType() Check if the option is OUTPUT_MIME_TYPE - * @method bool isOutputSchema() Check if the option is OUTPUT_SCHEMA + * @method static self inputModalities() Creates an instance for INPUT_MODALITIES option. + * @method static self outputModalities() Creates an instance for OUTPUT_MODALITIES option. + * @method static self systemInstruction() Creates an instance for SYSTEM_INSTRUCTION option. + * @method static self candidateCount() Creates an instance for CANDIDATE_COUNT option. + * @method static self maxTokens() Creates an instance for MAX_TOKENS option. + * @method static self temperature() Creates an instance for TEMPERATURE option. + * @method static self topK() Creates an instance for TOP_K option. + * @method static self topP() Creates an instance for TOP_P option. + * @method static self outputMimeType() Creates an instance for OUTPUT_MIME_TYPE option. + * @method static self outputSchema() Creates an instance for OUTPUT_SCHEMA option. + * @method bool isInputModalities() Checks if the option is INPUT_MODALITIES. + * @method bool isOutputModalities() Checks if the option is OUTPUT_MODALITIES. + * @method bool isSystemInstruction() Checks if the option is SYSTEM_INSTRUCTION. + * @method bool isCandidateCount() Checks if the option is CANDIDATE_COUNT. + * @method bool isMaxTokens() Checks if the option is MAX_TOKENS. + * @method bool isTemperature() Checks if the option is TEMPERATURE. + * @method bool isTopK() Checks if the option is TOP_K. + * @method bool isTopP() Checks if the option is TOP_P. + * @method bool isOutputMimeType() Checks if the option is OUTPUT_MIME_TYPE. + * @method bool isOutputSchema() Checks if the option is OUTPUT_SCHEMA. */ class OptionEnum extends AbstractEnum { /** - * Input modalities option + * Input modalities option. */ public const INPUT_MODALITIES = 'input_modalities'; /** - * Output modalities option + * Output modalities option. */ public const OUTPUT_MODALITIES = 'output_modalities'; /** - * System instruction option + * System instruction option. */ public const SYSTEM_INSTRUCTION = 'system_instruction'; /** - * Candidate count option + * Candidate count option. */ public const CANDIDATE_COUNT = 'candidate_count'; /** - * Maximum tokens option + * Maximum tokens option. */ public const MAX_TOKENS = 'max_tokens'; /** - * Temperature option + * Temperature option. */ public const TEMPERATURE = 'temperature'; /** - * Top K option + * Top K option. */ public const TOP_K = 'top_k'; /** - * Top P option + * Top P option. */ public const TOP_P = 'top_p'; /** - * Output MIME type option + * Output MIME type option. */ public const OUTPUT_MIME_TYPE = 'output_mime_type'; /** - * Output schema option + * Output schema option. */ public const OUTPUT_SCHEMA = 'output_schema'; } diff --git a/src/Results/Enums/FinishReasonEnum.php b/src/Results/Enums/FinishReasonEnum.php index c832538..773dc02 100644 --- a/src/Results/Enums/FinishReasonEnum.php +++ b/src/Results/Enums/FinishReasonEnum.php @@ -7,44 +7,44 @@ use WordPress\AiClient\Common\AbstractEnum; /** - * Enum for finish reasons of AI generation + * Enum for finish reasons of AI generation. * * @since n.e.x.t - * @method static self stop() Create an instance for STOP reason - * @method static self length() Create an instance for LENGTH reason - * @method static self contentFilter() Create an instance for CONTENT_FILTER reason - * @method static self toolCalls() Create an instance for TOOL_CALLS reason - * @method static self error() Create an instance for ERROR reason - * @method bool isStop() Check if the reason is STOP - * @method bool isLength() Check if the reason is LENGTH - * @method bool isContentFilter() Check if the reason is CONTENT_FILTER - * @method bool isToolCalls() Check if the reason is TOOL_CALLS - * @method bool isError() Check if the reason is ERROR + * @method static self stop() Creates an instance for STOP reason. + * @method static self length() Creates an instance for LENGTH reason. + * @method static self contentFilter() Creates an instance for CONTENT_FILTER reason. + * @method static self toolCalls() Creates an instance for TOOL_CALLS reason. + * @method static self error() Creates an instance for ERROR reason. + * @method bool isStop() Checks if the reason is STOP. + * @method bool isLength() Checks if the reason is LENGTH. + * @method bool isContentFilter() Checks if the reason is CONTENT_FILTER. + * @method bool isToolCalls() Checks if the reason is TOOL_CALLS. + * @method bool isError() Checks if the reason is ERROR. */ class FinishReasonEnum extends AbstractEnum { /** - * Generation stopped naturally + * Generation stopped naturally. */ public const STOP = 'stop'; /** - * Generation stopped due to max length + * Generation stopped due to max length. */ public const LENGTH = 'length'; /** - * Generation stopped due to content filter + * Generation stopped due to content filter. */ public const CONTENT_FILTER = 'content_filter'; /** - * Generation stopped to make tool calls + * Generation stopped to make tool calls. */ public const TOOL_CALLS = 'tool_calls'; /** - * Generation stopped due to error + * Generation stopped due to error. */ public const ERROR = 'error'; } From 5cc061f0b33b9a9ab8f65db753547a2823ccb43d Mon Sep 17 00:00:00 2001 From: Jason Adams Date: Tue, 22 Jul 2025 13:18:09 -0600 Subject: [PATCH 16/19] chore: adds spacing to since tags --- src/Common/AbstractEnum.php | 16 ++++++++++++++++ src/Messages/Enums/MessagePartTypeEnum.php | 1 + src/Messages/Enums/MessageRoleEnum.php | 1 + src/Messages/Enums/ModalityEnum.php | 1 + src/Operations/Enums/OperationStateEnum.php | 1 + src/Providers/Enums/ProviderTypeEnum.php | 1 + src/Providers/Enums/ToolTypeEnum.php | 1 + src/Results/Enums/FinishReasonEnum.php | 1 + 8 files changed, 23 insertions(+) diff --git a/src/Common/AbstractEnum.php b/src/Common/AbstractEnum.php index bfbe6d2..5456b4e 100644 --- a/src/Common/AbstractEnum.php +++ b/src/Common/AbstractEnum.php @@ -58,6 +58,7 @@ abstract class AbstractEnum * Constructor is private to ensure instances are created through static methods. * * @since n.e.x.t + * * @param string $value The enum value. * @param string $name The constant name. */ @@ -71,6 +72,7 @@ final private function __construct(string $value, string $name) * Provides read-only access to properties. * * @since n.e.x.t + * * @param string $property The property name. * @return mixed The property value. * @throws BadMethodCallException If property doesn't exist. @@ -90,6 +92,7 @@ final public function __get(string $property) * Prevents property modification. * * @since n.e.x.t + * * @param string $property The property name. * @param mixed $value The value to set. * @throws BadMethodCallException Always, as enum properties are read-only. @@ -105,6 +108,7 @@ final public function __set(string $property, $value): void * Creates an enum instance from a value, throws exception if invalid. * * @since n.e.x.t + * * @param string $value The enum value. * @return static The enum instance. * @throws InvalidArgumentException If the value is not valid. @@ -124,6 +128,7 @@ final public static function from(string $value): self * Tries to create an enum instance from a value, returns null if invalid. * * @since n.e.x.t + * * @param string $value The enum value. * @return static|null The enum instance or null. */ @@ -142,6 +147,7 @@ final public static function tryFrom(string $value): ?self * Gets all enum cases. * * @since n.e.x.t + * * @return static[] Array of all enum instances. */ final public static function cases(): array @@ -158,6 +164,7 @@ final public static function cases(): array * Checks if this enum has the same value as the given value. * * @since n.e.x.t + * * @param string|self $other The value or enum to compare. * @return bool True if values are equal. */ @@ -174,6 +181,7 @@ final public function equals($other): bool * Checks if this enum is the same instance type and value as another enum. * * @since n.e.x.t + * * @param self $other The other enum to compare. * @return bool True if enums are identical. */ @@ -186,6 +194,7 @@ final public function is(self $other): bool * Gets all valid values for this enum. * * @since n.e.x.t + * * @return array Map of constant names to values. */ final public static function getValues(): array @@ -197,6 +206,7 @@ final public static function getValues(): array * Checks if a value is valid for this enum. * * @since n.e.x.t + * * @param string $value The value to check. * @return bool True if value is valid. */ @@ -209,6 +219,7 @@ final public static function isValidValue(string $value): bool * Gets or creates a singleton instance for the given value and name. * * @since n.e.x.t + * * @param string $value The enum value. * @param string $name The constant name. * @return static The enum instance. @@ -234,6 +245,7 @@ private static function getInstance(string $value, string $name): self * Gets all constants for this enum class. * * @since n.e.x.t + * * @return array Map of constant names to values. * @throws \RuntimeException If invalid constant found. */ @@ -285,6 +297,7 @@ final protected static function getConstants(): array * Handles dynamic method calls for enum checking. * * @since n.e.x.t + * * @param string $name The method name. * @param array $arguments The method arguments. * @return bool True if the enum value matches. @@ -311,6 +324,7 @@ final public function __call(string $name, array $arguments): bool * Handles static method calls for enum creation. * * @since n.e.x.t + * * @param string $name The method name. * @param array $arguments The method arguments. * @return static The enum instance. @@ -334,6 +348,7 @@ final public static function __callStatic(string $name, array $arguments): self * Converts camelCase to CONSTANT_CASE. * * @since n.e.x.t + * * @param string $camelCase The camelCase string. * @return string The CONSTANT_CASE version. */ @@ -350,6 +365,7 @@ private static function camelCaseToConstant(string $camelCase): string * Returns string representation of the enum. * * @since n.e.x.t + * * @return string The enum value. */ final public function __toString(): string diff --git a/src/Messages/Enums/MessagePartTypeEnum.php b/src/Messages/Enums/MessagePartTypeEnum.php index 139eb13..b7abeb6 100644 --- a/src/Messages/Enums/MessagePartTypeEnum.php +++ b/src/Messages/Enums/MessagePartTypeEnum.php @@ -10,6 +10,7 @@ * Enum for message part types. * * @since n.e.x.t + * * @method static self text() Creates an instance for TEXT type. * @method static self inlineFile() Creates an instance for INLINE_FILE type. * @method static self remoteFile() Creates an instance for REMOTE_FILE type. diff --git a/src/Messages/Enums/MessageRoleEnum.php b/src/Messages/Enums/MessageRoleEnum.php index b350228..f7a0b62 100644 --- a/src/Messages/Enums/MessageRoleEnum.php +++ b/src/Messages/Enums/MessageRoleEnum.php @@ -10,6 +10,7 @@ * Enum for message roles in AI conversations. * * @since n.e.x.t + * * @method static self user() Creates an instance for USER role. * @method static self model() Creates an instance for MODEL role. * @method static self system() Creates an instance for SYSTEM role. diff --git a/src/Messages/Enums/ModalityEnum.php b/src/Messages/Enums/ModalityEnum.php index 102e79f..3732cc3 100644 --- a/src/Messages/Enums/ModalityEnum.php +++ b/src/Messages/Enums/ModalityEnum.php @@ -10,6 +10,7 @@ * Enum for input/output modalities. * * @since n.e.x.t + * * @method static self text() Creates an instance for TEXT modality. * @method static self document() Creates an instance for DOCUMENT modality. * @method static self image() Creates an instance for IMAGE modality. diff --git a/src/Operations/Enums/OperationStateEnum.php b/src/Operations/Enums/OperationStateEnum.php index 36fa633..32d8770 100644 --- a/src/Operations/Enums/OperationStateEnum.php +++ b/src/Operations/Enums/OperationStateEnum.php @@ -10,6 +10,7 @@ * Enum for operation states. * * @since n.e.x.t + * * @method static self starting() Creates an instance for STARTING state. * @method static self processing() Creates an instance for PROCESSING state. * @method static self succeeded() Creates an instance for SUCCEEDED state. diff --git a/src/Providers/Enums/ProviderTypeEnum.php b/src/Providers/Enums/ProviderTypeEnum.php index 6086f39..4fa4a48 100644 --- a/src/Providers/Enums/ProviderTypeEnum.php +++ b/src/Providers/Enums/ProviderTypeEnum.php @@ -10,6 +10,7 @@ * Enum for provider types. * * @since n.e.x.t + * * @method static self cloud() Creates an instance for CLOUD type. * @method static self server() Creates an instance for SERVER type. * @method static self client() Creates an instance for CLIENT type. diff --git a/src/Providers/Enums/ToolTypeEnum.php b/src/Providers/Enums/ToolTypeEnum.php index d92d472..c0c999a 100644 --- a/src/Providers/Enums/ToolTypeEnum.php +++ b/src/Providers/Enums/ToolTypeEnum.php @@ -10,6 +10,7 @@ * Enum for tool types. * * @since n.e.x.t + * * @method static self functionDeclarations() Creates an instance for FUNCTION_DECLARATIONS type. * @method static self webSearch() Creates an instance for WEB_SEARCH type. * @method bool isFunctionDeclarations() Checks if the type is FUNCTION_DECLARATIONS. diff --git a/src/Results/Enums/FinishReasonEnum.php b/src/Results/Enums/FinishReasonEnum.php index 773dc02..bacf403 100644 --- a/src/Results/Enums/FinishReasonEnum.php +++ b/src/Results/Enums/FinishReasonEnum.php @@ -10,6 +10,7 @@ * Enum for finish reasons of AI generation. * * @since n.e.x.t + * * @method static self stop() Creates an instance for STOP reason. * @method static self length() Creates an instance for LENGTH reason. * @method static self contentFilter() Creates an instance for CONTENT_FILTER reason. From 50b0b538cb5866fbe5e5883182b07a859ab8b8fc Mon Sep 17 00:00:00 2001 From: Jason Adams Date: Tue, 22 Jul 2025 17:03:40 -0600 Subject: [PATCH 17/19] chore: improves comment neutrality Co-authored-by: Felix Arntz --- src/Providers/Enums/ProviderTypeEnum.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Providers/Enums/ProviderTypeEnum.php b/src/Providers/Enums/ProviderTypeEnum.php index 4fa4a48..b1dd7c4 100644 --- a/src/Providers/Enums/ProviderTypeEnum.php +++ b/src/Providers/Enums/ProviderTypeEnum.php @@ -21,17 +21,17 @@ class ProviderTypeEnum extends AbstractEnum { /** - * Cloud-based AI provider (e.g., OpenAI, Google, Anthropic). + * Cloud-based AI provider (e.g. models available via external REST APIs). */ public const CLOUD = 'cloud'; /** - * Server-side AI provider (e.g., self-hosted models). + * Server-side AI provider (e.g. self-hosted models). */ public const SERVER = 'server'; /** - * Client-side AI provider (e.g., browser-based models). + * Client-side AI provider (e.g. browser-based models). */ public const CLIENT = 'client'; } From 2cf2ea9fce869332f438c82b34a19056c66cbedf Mon Sep 17 00:00:00 2001 From: Jason Adams Date: Tue, 22 Jul 2025 17:05:17 -0600 Subject: [PATCH 18/19] chore: ignores more AI files --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index 25a49f2..dfcbf4f 100644 --- a/.gitignore +++ b/.gitignore @@ -19,3 +19,5 @@ vendor/ .claude/ CLAUDE.md +.cursor/ +GEMINI.md From 60b6fa10e303ad59c533e39c032529458ef5e86e Mon Sep 17 00:00:00 2001 From: Jason Adams Date: Tue, 22 Jul 2025 17:07:41 -0600 Subject: [PATCH 19/19] chore: adds missing full-stops Co-authored-by: Felix Arntz --- src/Common/AbstractEnum.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Common/AbstractEnum.php b/src/Common/AbstractEnum.php index 5456b4e..11f1013 100644 --- a/src/Common/AbstractEnum.php +++ b/src/Common/AbstractEnum.php @@ -9,7 +9,7 @@ use ReflectionClass; /** - * Abstract base class for enum-like behavior in PHP 7.4 + * Abstract base class for enum-like behavior in PHP 7.4. * * This class provides enum-like functionality for PHP versions that don't support native enums. * Child classes should define uppercase snake_case constants for enum values. @@ -35,22 +35,22 @@ abstract class AbstractEnum { /** - * @var string The value of the enum instance + * @var string The value of the enum instance. */ private string $value; /** - * @var string The name of the enum constant + * @var string The name of the enum constant. */ private string $name; /** - * @var array> Cache for reflection data + * @var array> Cache for reflection data. */ private static array $cache = []; /** - * @var array> Cache for enum instances + * @var array> Cache for enum instances. */ private static array $instances = [];