Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
83 changes: 83 additions & 0 deletions src/Providers/ApiBasedImplementation/AbstractApiBasedModel.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

namespace WordPress\AiClient\Providers\ApiBasedImplementation;

use WordPress\AiClient\Messages\Enums\ModalityEnum;
use WordPress\AiClient\Providers\ApiBasedImplementation\Contracts\ApiBasedModelInterface;
use WordPress\AiClient\Providers\DTO\ProviderMetadata;
use WordPress\AiClient\Providers\Http\Contracts\WithHttpTransporterInterface;
Expand All @@ -13,6 +14,7 @@
use WordPress\AiClient\Providers\Http\Traits\WithRequestAuthenticationTrait;
use WordPress\AiClient\Providers\Models\DTO\ModelConfig;
use WordPress\AiClient\Providers\Models\DTO\ModelMetadata;
use WordPress\AiClient\Providers\Models\Enums\OptionEnum;

/**
* Base class for an API-based model for a provider.
Expand Down Expand Up @@ -124,4 +126,85 @@ final public function getRequestOptions(): ?RequestOptions
{
return $this->requestOptions;
}

/**
* {@inheritDoc}
*
* @since n.e.x.t
*/
final public function getCapabilities(): array
{
return [
'input' => $this->extractModalities(OptionEnum::inputModalities()),
'output' => $this->extractModalities(OptionEnum::outputModalities()),
];
}

/**
* {@inheritDoc}
*
* @since n.e.x.t
*/
final public function supportsInput(ModalityEnum $modality): bool
{
foreach ($this->extractModalities(OptionEnum::inputModalities()) as $supported) {
if ($supported->value === $modality->value) {
return true;
}
}
return false;
}

/**
* {@inheritDoc}
*
* @since n.e.x.t
*/
final public function supportsOutput(ModalityEnum $modality): bool
{
foreach ($this->extractModalities(OptionEnum::outputModalities()) as $supported) {
if ($supported->value === $modality->value) {
return true;
}
}
return false;
}

/**
* Extracts a list of ModalityEnum values from the model metadata for a given option key.
*
* Looks up the SupportedOption matching $optionKey in the model's metadata and converts
* each stored value to a ModalityEnum instance. Values that are not valid ModalityEnum
* values are silently skipped.
*
* @since n.e.x.t
*
* @param OptionEnum $optionKey The option key to look up (e.g. inputModalities, outputModalities).
* @return list<ModalityEnum> The list of modalities, or an empty list if none are defined.
*/
private function extractModalities(OptionEnum $optionKey): array
{
foreach ($this->metadata->getSupportedOptions() as $supportedOption) {
if ($supportedOption->getName()->value !== $optionKey->value) {
continue;
}

$values = $supportedOption->getSupportedValues();
if ($values === null) {
return [];
}

$modalities = [];
foreach ($values as $value) {
if ($value instanceof ModalityEnum) {
$modalities[] = $value;
} elseif (is_string($value)) {
$modalities[] = ModalityEnum::from($value);
}
}
return $modalities;
}

return [];
}
}
34 changes: 34 additions & 0 deletions src/Providers/Models/Contracts/ModelInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

namespace WordPress\AiClient\Providers\Models\Contracts;

use WordPress\AiClient\Messages\Enums\ModalityEnum;
use WordPress\AiClient\Providers\DTO\ProviderMetadata;
use WordPress\AiClient\Providers\Models\DTO\ModelConfig;
use WordPress\AiClient\Providers\Models\DTO\ModelMetadata;
Expand Down Expand Up @@ -54,4 +55,37 @@ public function setConfig(ModelConfig $config): void;
* @return ModelConfig Current model configuration.
*/
public function getConfig(): ModelConfig;

/**
* Returns the supported input and output modalities for this model.
*
* The returned array contains two keys: 'input' and 'output', each
* containing a list of supported ModalityEnum values. An empty list
* means no modalities of that kind are explicitly declared.
*
* @since n.e.x.t
*
* @return array{input: list<ModalityEnum>, output: list<ModalityEnum>} Supported modalities.
*/
public function getCapabilities(): array;

/**
* Checks whether the model supports the given input modality.
*
* @since n.e.x.t
*
* @param ModalityEnum $modality The modality to check.
* @return bool True if the input modality is supported, false otherwise.
*/
public function supportsInput(ModalityEnum $modality): bool;

/**
* Checks whether the model supports the given output modality.
*
* @since n.e.x.t
*
* @param ModalityEnum $modality The modality to check.
* @return bool True if the output modality is supported, false otherwise.
*/
public function supportsOutput(ModalityEnum $modality): bool;
}
71 changes: 71 additions & 0 deletions tests/mocks/MockModel.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

namespace WordPress\AiClient\Tests\mocks;

use WordPress\AiClient\Messages\Enums\ModalityEnum;
use WordPress\AiClient\Providers\DTO\ProviderMetadata;
use WordPress\AiClient\Providers\Http\Contracts\WithHttpTransporterInterface;
use WordPress\AiClient\Providers\Http\Contracts\WithRequestAuthenticationInterface;
Expand All @@ -12,6 +13,7 @@
use WordPress\AiClient\Providers\Models\Contracts\ModelInterface;
use WordPress\AiClient\Providers\Models\DTO\ModelConfig;
use WordPress\AiClient\Providers\Models\DTO\ModelMetadata;
use WordPress\AiClient\Providers\Models\Enums\OptionEnum;

/**
* Mock model for testing.
Expand Down Expand Up @@ -75,4 +77,73 @@ public function setConfig(ModelConfig $config): void
{
$this->config = $config;
}

/**
* {@inheritDoc}
*/
public function getCapabilities(): array
{
return [
'input' => $this->extractModalities(OptionEnum::inputModalities()),
'output' => $this->extractModalities(OptionEnum::outputModalities()),
];
}

/**
* {@inheritDoc}
*/
public function supportsInput(ModalityEnum $modality): bool
{
foreach ($this->extractModalities(OptionEnum::inputModalities()) as $supported) {
if ($supported->value === $modality->value) {
return true;
}
}
return false;
}

/**
* {@inheritDoc}
*/
public function supportsOutput(ModalityEnum $modality): bool
{
foreach ($this->extractModalities(OptionEnum::outputModalities()) as $supported) {
if ($supported->value === $modality->value) {
return true;
}
}
return false;
}

/**
* Extracts modality instances from the metadata's supported options.
*
* @param OptionEnum $optionKey The option key to look up.
* @return list<ModalityEnum> The list of modalities.
*/
private function extractModalities(OptionEnum $optionKey): array
{
foreach ($this->metadata->getSupportedOptions() as $supportedOption) {
if ($supportedOption->getName()->value !== $optionKey->value) {
continue;
}

$values = $supportedOption->getSupportedValues();
if ($values === null) {
return [];
}

$modalities = [];
foreach ($values as $value) {
if ($value instanceof ModalityEnum) {
$modalities[] = $value;
} elseif (is_string($value)) {
$modalities[] = ModalityEnum::from($value);
}
}
return $modalities;
}

return [];
}
}
46 changes: 46 additions & 0 deletions tests/traits/MockModelCreationTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

use WordPress\AiClient\Messages\DTO\MessagePart;
use WordPress\AiClient\Messages\DTO\ModelMessage;
use WordPress\AiClient\Messages\Enums\ModalityEnum;
use WordPress\AiClient\Providers\DTO\ProviderMetadata;
use WordPress\AiClient\Providers\Enums\ProviderTypeEnum;
use WordPress\AiClient\Providers\Models\Contracts\ModelInterface;
Expand Down Expand Up @@ -193,6 +194,21 @@ public function getConfig(): ModelConfig
return $this->config;
}

public function getCapabilities(): array
{
return ['input' => [], 'output' => []];
}

public function supportsInput(ModalityEnum $modality): bool
{
return false;
}

public function supportsOutput(ModalityEnum $modality): bool
{
return false;
}

public function generateTextResult(array $prompt): GenerativeAiResult
{
return $this->result;
Expand Down Expand Up @@ -260,6 +276,21 @@ public function getConfig(): ModelConfig
return $this->config;
}

public function getCapabilities(): array
{
return ['input' => [], 'output' => []];
}

public function supportsInput(ModalityEnum $modality): bool
{
return false;
}

public function supportsOutput(ModalityEnum $modality): bool
{
return false;
}

public function generateImageResult(array $prompt): GenerativeAiResult
{
return $this->result;
Expand Down Expand Up @@ -327,6 +358,21 @@ public function getConfig(): ModelConfig
return $this->config;
}

public function getCapabilities(): array
{
return ['input' => [], 'output' => []];
}

public function supportsInput(ModalityEnum $modality): bool
{
return false;
}

public function supportsOutput(ModalityEnum $modality): bool
{
return false;
}

public function generateVideoResult(array $prompt): GenerativeAiResult
{
return $this->result;
Expand Down
Loading
Loading