You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The project implements a provideragnostic PHP AI client SDK to communicate with any generative AI models of various capabilities using a uniform API.
5
+
The PHP AI Client is a provider-agnostic PHP SDK designed to communicate with any generative AI model across various capabilities through a uniform API. It is a WordPress-agnostic PHP package that can be used in any PHP project, providing a flexible and extensible way to integrate AI features.
6
6
7
-
The project is stewarded by [WordPress AI Team](https://make.wordpress.org/ai/) members and contributors. It is however WordPress agnostic, so that any PHP project can use it.
7
+
## Commands & Scripts
8
8
9
-
## High-level architecture
9
+
The following commands are available for development and can be run using Composer:
10
10
11
-
The project architecture has several key design principles:
11
+
*`composer lint`: Runs all linting checks.
12
+
*`composer phpcs`: Runs PHP_CodeSniffer to check for coding standards violations.
13
+
*`composer phpcbf`: Automatically fixes coding standards violations that can be fixed automatically.
14
+
*`composer phpstan`: Runs PHPStan for static analysis.
15
+
*`composer test`: Runs the PHPUnit test suite (this is an alias for `composer phpunit`).
16
+
*`composer phpunit`: Runs the PHPUnit test suite.
12
17
13
-
### API layers
18
+
##Coding Standards & Compatibility Constraints
14
19
15
-
1.**Implementer API**: For developers using the SDK to add AI features to their applications
- Traditional API: Method-based approach with arrays of arguments (e.g. `AiClient::generateText('...')`)
20
+
All code in this project MUST adhere to the coding standards, naming conventions, and documentation standards outlined in the `CONTRIBUTING.md` file. Any agent working on this project MUST read and follow the guidelines in that file before starting any work.
18
21
19
-
2.**Extender API**: For developers adding new providers, models, or extending functionality
20
-
- Provider Registry system for managing available AI providers
21
-
- Model discovery based on capabilities and requirements
22
+
Key constraints include:
22
23
23
-
### Core concepts
24
+
* PHP 7.4 as the minimum required version.
25
+
* PER Coding Style (extending PSR-12).
26
+
* Strict type hinting for all parameters, return values, and properties.
24
27
25
-
-**Provider Agnostic**: Abstracts away provider-specific details, allowing code to work with any AI provider (Google, OpenAI, Anthropic, etc.)
26
-
-**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.)
27
-
-**Uniform Data Structures**: Consistent message formats, file representations, and results across all providers
28
-
-**Modality Support**: Designed to support arbitrary combinations of input/output modalities (text, image, audio, video)
28
+
## Core Principles
29
29
30
-
### Key design patterns
30
+
***Provider Agnostic:** The client is designed to work with any AI provider, avoiding vendor lock-in.
31
+
***Extensibility:** The architecture allows for new providers, models, and capabilities to be added without modifying the core functionality.
32
+
***Flexibility:** The client supports a wide range of AI capabilities, including text generation, image generation, and more, with arbitrary combinations of input and output modalities.
33
+
***Developer Experience:** The client provides two distinct APIs: a simple, fluent API for implementers and a more technical, interface-based API for extenders.
31
34
32
-
-**Interface Segregation**: Separate interfaces for different model capabilities (TextGenerationModelInterface, ImageGenerationModelInterface, etc.)
33
-
-**Composition over Inheritance**: Models compose capabilities through interfaces rather than inheritance
34
-
-**DTO Pattern**: Data Transfer Objects for messages, results, and configurations with JSON schema support
35
-
-**Builder Pattern**: Fluent builders for constructing prompts and messages
35
+
### Dependency Management
36
36
37
-
### Directory structure
37
+
The project aims to have minimal third-party dependencies. Any new dependency requires justification and should be discussed before implementation.
38
38
39
-
-**Production Code**: All production code is found in the `src` directory, in subdirectories that match the namespace structure.
40
-
-**Tests**: PHPUnit tests are found in the `tests/unit` directory, with each test file covering a specific class from `src`.
41
-
- Each test file is named after the tested class, suffixed with `Test`.
42
-
- Each test file is located in a subdirectory equivalent to the tested class's directory within `src`.
43
-
- Test specific mock classes and traits are located in `tests/mocks` and `tests/traits` respectively.
39
+
### Error Handling
44
40
45
-
### Namespace structure
41
+
The project uses custom exceptions for error handling. When appropriate, throw a custom exception class. Custom exception classes should extend the base `Exception` class.
46
42
47
-
The production code in `src` follows a structured namespace hierarchy under the root namespace `WordPress\AiClient`:
43
+
### Testing
48
44
49
-
-`Builders`: Fluent API builders (PromptBuilder, MessageBuilder)
50
-
-`Embeddings`: Embedding-related data structures
51
-
-`Files`: File handling contracts and implementations
52
-
-`Messages`: Message DTOs and enums
53
-
-`Operations`: Long-running operation support
54
-
-`Providers`: Provider system with contracts, models, and registry
55
-
-`Results`: Result data structures and transformations
56
-
-`Tools`: Function calling and tool support
57
-
-`Util`: Utility classes for common operations
45
+
The project uses PHPUnit for unit testing. Test files are located in the `tests/` directory and mirror the structure of the `src/` directory. The test suite is executed by running `composer phpunit`. The `tests/mocks` directory contains mock implementations for testing purposes, and `tests/traits` contains reusable testing traits. All new code requires corresponding unit tests.
58
46
59
-
## Development tooling and commands
47
+
## Project Architecture Overview
60
48
61
-
### Linting and code quality
49
+
The project's architecture is heavily inspired by the Vercel AI SDK and is designed to be modular and extensible. Key components include:
62
50
63
-
-**Run all linting checks**: `composer lint` (runs both PHPCS and PHPStan)
***`AiClient`:** The main entry point for interacting with the SDK, offering both a fluent API (via `AiClient::prompt()`) and a traditional method-based API.
52
+
***Providers:** Implementations for specific AI providers (e.g., OpenAI, Google, Anthropic). Each provider has its own models and metadata.
53
+
***`ProviderRegistry`:** Manages the available AI providers and models, allowing for discovery of models based on their capabilities.
54
+
***Models:** Represent specific AI models and their capabilities. They are responsible for handling the logic for a specific AI task.
55
+
***HTTP Communication:** A custom `HttpTransporter` layer abstracts HTTP communication, decoupling models from specific PSR-18 HTTP client implementations. Models create custom `Request` objects and receive custom `Response` objects, which the transporter translates to and from PSR-7 standards.
67
56
68
-
### Testing
57
+
For a more detailed overview, refer to the `docs/ARCHITECTURE.md` file.
69
58
70
-
-**Run PHPUnit tests**: `composer phpunit`
59
+
## Directory Structure
71
60
72
-
### Dependencies
61
+
*`src/`: Contains the main source code for the client.
62
+
*`src/Builders/`: Home to the fluent API builders (`PromptBuilder`, `MessageBuilder`).
63
+
*`src/Providers/`: Contains the contracts and base classes for AI providers and models.
64
+
*`src/ProviderImplementations/`: Contains the concrete implementations for specific AI providers like Google, OpenAI, and Anthropic.
65
+
*`src/Providers/Http/`: Contains the HTTP communication layer, including the `HttpTransporter`.
66
+
*`tests/`: Contains the test suite for the project.
67
+
*`docs/`: Contains the project's documentation, including architecture, requirements, and a glossary.
73
68
74
-
-**Install dependencies**: `composer install`
75
-
-**Update dependencies**: `composer update`
69
+
## Agent Guidelines
70
+
71
+
### Naming conventions
76
72
77
-
##Coding standards and best practices
73
+
### DO:
78
74
79
-
-**Code style**: All code must be compliant with the [PER Coding Style](https://www.php-fig.org/per/coding-style/), which extends [PSR-12](https://www.php-fig.org/psr/psr-12/).
80
-
-**Minimum required PHP version**: All code must be backward compatible with PHP 7.4. For newer PHP functions, polyfills can be used.
75
+
***Read the Docs:** Before making any changes, thoroughly read `CONTRIBUTING.md` and `docs/ARCHITECTURE.md`.
76
+
***Follow Coding Standards:** Strictly adhere to the coding standards defined in `CONTRIBUTING.md` and enforced by PHP_CodeSniffer.
77
+
***Write Tests:** All new features or bug fixes must be accompanied by corresponding unit tests.
78
+
***Use the Fluent API:** When writing examples or tests for the implementer API, prefer the fluent API for readability.
79
+
***Use `{@inheritDoc}`:** When implementing an interface method, use `{@inheritDoc}` in the PHPDoc block to avoid duplicating documentation, as specified in `CONTRIBUTING.md`.
81
80
82
-
### Type hints
81
+
### DON'T:
83
82
84
-
All parameters, return values, and properties must use explicit type hints, except in cases where providing the correct type hint would be impossible given limitations of backward compatibility with PHP 7.4. In any case, concrete type annotations using PHPStan should be present.
83
+
***Bypass the `HttpTransporter`:** Do not use a PSR-18 HTTP client directly within a model. All HTTP communication must go through the `HttpTransporter`.
84
+
***Add Provider-Specific Logic to Core:** Keep the core client agnostic. Provider-specific logic should be encapsulated within the provider's implementation in `src/ProviderImplementations/`.
85
+
***Introduce Out-of-Scope Features:** Do not add features that are out of scope for this project, such as agents or the Model Context Protocol (MCP), as noted in `docs/REQUIREMENTS.md`.
86
+
***Duplicate Documentation:** Avoid duplicating PHPDoc descriptions for methods that implement an interface.
85
87
86
88
### Exception handling
87
89
@@ -92,16 +94,8 @@ All exceptions must use the project's custom exception classes rather than PHP b
92
94
- All custom exceptions implement `WordPress\AiClient\Exceptions\AiClientExceptionInterface` for unified exception handling
93
95
- Follow usage-driven design: only implement static factory methods that are actually used in the codebase
94
96
95
-
### Naming conventions
96
-
97
-
The following naming conventions must be followed for consistency and autoloading:
98
-
99
-
- Interfaces are suffixed with `Interface`.
100
-
- Traits are suffixed with `Trait`.
101
-
- Enums are suffixed with `Enum`.
102
-
- File names are the same as the class, trait, and interface name for PSR-4 autoloading.
103
-
- Classes, interfaces, and traits, and namespaces are not prefixed with `Ai`, excluding the root namespace.
104
-
105
-
## Further reading
97
+
## Common Pitfalls
106
98
107
-
The `docs` folder in this repository provides additional in-depth information about various aspects of the project, such as its requirements or architecture.
99
+
***Direct HTTP Client Usage:** A common mistake is to instantiate a PSR-18 client directly in a model. This is incorrect. Instead, the model should receive an `HttpTransporter` instance and use it to send requests.
100
+
***Ignoring the Fluent API:** While the traditional API is available, the fluent API is the preferred way for implementers to use the client. Avoid writing complex, nested method calls when the fluent API provides a cleaner alternative.
101
+
***Duplicating Interface Documentation:** Manually writing PHPDoc descriptions for methods that implement an interface is a common pitfall. The `{@inheritDoc}` tag should be used instead to inherit the documentation from the interface.
0 commit comments