Skip to content
Merged
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
94 changes: 3 additions & 91 deletions src/Builders/PromptBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@
use WordPress\AiClient\Providers\Models\DTO\ModelRequirements;
use WordPress\AiClient\Providers\Models\DTO\RequiredOption;
use WordPress\AiClient\Providers\Models\Enums\CapabilityEnum;
use WordPress\AiClient\Providers\Models\Enums\OptionEnum;
use WordPress\AiClient\Providers\Models\ImageGeneration\Contracts\ImageGenerationModelInterface;
use WordPress\AiClient\Providers\Models\SpeechGeneration\Contracts\SpeechGenerationModelInterface;
use WordPress\AiClient\Providers\Models\TextGeneration\Contracts\TextGenerationModelInterface;
Expand Down Expand Up @@ -510,79 +509,6 @@ public function asJsonResponse(?array $schema = null): self
return $this;
}

/**
* Gets the inferred model requirements based on prompt features.
*
* @since 0.1.0
*
* @param CapabilityEnum $capability The capability the model must support.
* @return ModelRequirements The inferred requirements.
*/
private function getModelRequirements(CapabilityEnum $capability): ModelRequirements
{
$capabilities = [$capability];
$inputModalities = [];

// Check if we have chat history (multiple messages)
if (count($this->messages) > 1) {
$capabilities[] = CapabilityEnum::chatHistory();
}

// Analyze all messages to determine required input modalities
$hasFunctionMessageParts = false;
foreach ($this->messages as $message) {
foreach ($message->getParts() as $part) {
// Check for text input
if ($part->getType()->isText()) {
$inputModalities[] = ModalityEnum::text();
}

// Check for file inputs
if ($part->getType()->isFile()) {
$file = $part->getFile();

if ($file !== null) {
if ($file->isImage()) {
$inputModalities[] = ModalityEnum::image();
} elseif ($file->isAudio()) {
$inputModalities[] = ModalityEnum::audio();
} elseif ($file->isVideo()) {
$inputModalities[] = ModalityEnum::video();
} elseif ($file->isDocument() || $file->isText()) {
$inputModalities[] = ModalityEnum::document();
}
}
}

// Check for function calls/responses (these might require special capabilities)
if ($part->getType()->isFunctionCall() || $part->getType()->isFunctionResponse()) {
$hasFunctionMessageParts = true;
}
}
}

// Build required options from ModelConfig
$requiredOptions = $this->modelConfig->toRequiredOptions();

if ($hasFunctionMessageParts) {
// Add function declarations option if we have function calls/responses
$requiredOptions = $this->includeInRequiredOptions(
$requiredOptions,
new RequiredOption(OptionEnum::functionDeclarations(), true)
);
}

// Add input modalities if we have any inputs
$requiredOptions = $this->includeInRequiredOptions(
$requiredOptions,
new RequiredOption(OptionEnum::inputModalities(), $inputModalities)
);

return new ModelRequirements(
$capabilities,
$requiredOptions
);
}

/**
* Infers the capability from configured output modalities.
Expand Down Expand Up @@ -671,11 +597,11 @@ private function isSupported(?CapabilityEnum $intendedCapability = null): bool
}

// Build requirements with the specified capability
$requirements = $this->getModelRequirements($intendedCapability);
$requirements = ModelRequirements::fromPromptData($intendedCapability, $this->messages, $this->modelConfig);

// If the model has been set, check if it meets the requirements
if ($this->model !== null) {
return $this->model->metadata()->meetsRequirements($requirements);
return $requirements->areMetBy($this->model->metadata());
}

try {
Expand Down Expand Up @@ -1112,7 +1038,7 @@ protected function appendPartToMessages(MessagePart $part): void
*/
private function getConfiguredModel(CapabilityEnum $capability): ModelInterface
{
$requirements = $this->getModelRequirements($capability);
$requirements = ModelRequirements::fromPromptData($capability, $this->messages, $this->modelConfig);

// If a model has been explicitly set, return it
if ($this->model !== null) {
Expand Down Expand Up @@ -1333,20 +1259,6 @@ private function isMessagesList($value): bool
* @param RequiredOption $option The option to potentially add.
* @return list<RequiredOption> The updated list of required options.
*/
private function includeInRequiredOptions(array $options, RequiredOption $option): array
{
// Check if an option with the same name already exists
foreach ($options as $existingOption) {
if ($existingOption->getName()->equals($option->getName())) {
// Option already exists, return unchanged list
return $options;
}
}

// Add the new option
$options[] = $option;
return $options;
}

/**
* Includes output modalities if not already present.
Expand Down
133 changes: 0 additions & 133 deletions src/Providers/Models/DTO/ModelConfig.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
use WordPress\AiClient\Files\Enums\FileTypeEnum;
use WordPress\AiClient\Files\Enums\MediaOrientationEnum;
use WordPress\AiClient\Messages\Enums\ModalityEnum;
use WordPress\AiClient\Providers\Models\Enums\OptionEnum;
use WordPress\AiClient\Tools\DTO\FunctionDeclaration;
use WordPress\AiClient\Tools\DTO\WebSearch;

Expand Down Expand Up @@ -962,138 +961,6 @@ static function (FunctionDeclaration $function_declaration): array {
return $data;
}

/**
* Converts the model configuration to required options.
*
* @since 0.1.0
*
* @return list<RequiredOption> The required options.
*/
public function toRequiredOptions(): array
{
$requiredOptions = [];

// Map properties that have corresponding OptionEnum values
if ($this->outputModalities !== null) {
$requiredOptions[] = new RequiredOption(
OptionEnum::outputModalities(),
$this->outputModalities
);
}

if ($this->systemInstruction !== null) {
$requiredOptions[] = new RequiredOption(
OptionEnum::systemInstruction(),
$this->systemInstruction
);
}

if ($this->candidateCount !== null) {
$requiredOptions[] = new RequiredOption(
OptionEnum::candidateCount(),
$this->candidateCount
);
}

if ($this->maxTokens !== null) {
$requiredOptions[] = new RequiredOption(
OptionEnum::maxTokens(),
$this->maxTokens
);
}

if ($this->temperature !== null) {
$requiredOptions[] = new RequiredOption(
OptionEnum::temperature(),
$this->temperature
);
}

if ($this->topP !== null) {
$requiredOptions[] = new RequiredOption(
OptionEnum::topP(),
$this->topP
);
}

if ($this->topK !== null) {
$requiredOptions[] = new RequiredOption(
OptionEnum::topK(),
$this->topK
);
}

if ($this->outputMimeType !== null) {
$requiredOptions[] = new RequiredOption(
OptionEnum::outputMimeType(),
$this->outputMimeType
);
}

if ($this->outputSchema !== null) {
$requiredOptions[] = new RequiredOption(
OptionEnum::outputSchema(),
$this->outputSchema
);
}

// Handle properties without OptionEnum values as custom options
// These would need to be handled specially by providers
if ($this->stopSequences !== null) {
$requiredOptions[] = new RequiredOption(OptionEnum::stopSequences(), $this->stopSequences);
}

if ($this->presencePenalty !== null) {
$requiredOptions[] = new RequiredOption(OptionEnum::presencePenalty(), $this->presencePenalty);
}

if ($this->frequencyPenalty !== null) {
$requiredOptions[] = new RequiredOption(OptionEnum::frequencyPenalty(), $this->frequencyPenalty);
}

if ($this->logprobs !== null) {
$requiredOptions[] = new RequiredOption(OptionEnum::logprobs(), $this->logprobs);
}

if ($this->topLogprobs !== null) {
$requiredOptions[] = new RequiredOption(OptionEnum::topLogprobs(), $this->topLogprobs);
}

if ($this->functionDeclarations !== null) {
$requiredOptions[] = new RequiredOption(OptionEnum::functionDeclarations(), true);
}

if ($this->webSearch !== null) {
$requiredOptions[] = new RequiredOption(OptionEnum::webSearch(), true);
}

if ($this->outputFileType !== null) {
$requiredOptions[] = new RequiredOption(OptionEnum::outputFileType(), $this->outputFileType);
}

if ($this->outputMediaOrientation !== null) {
$requiredOptions[] = new RequiredOption(
OptionEnum::outputMediaOrientation(),
$this->outputMediaOrientation
);
}

if ($this->outputMediaAspectRatio !== null) {
$requiredOptions[] = new RequiredOption(
OptionEnum::outputMediaAspectRatio(),
$this->outputMediaAspectRatio
);
}

// Add custom options as individual RequiredOptions
// Custom options don't have predefined OptionEnum values, so we use the customOptions enum
// with the actual key-value pair as the value
foreach ($this->customOptions as $key => $value) {
$requiredOptions[] = new RequiredOption(OptionEnum::customOptions(), [$key => $value]);
}

return $requiredOptions;
}

/**
* {@inheritDoc}
Expand Down
55 changes: 0 additions & 55 deletions src/Providers/Models/DTO/ModelMetadata.php
Original file line number Diff line number Diff line change
Expand Up @@ -54,15 +54,6 @@ class ModelMetadata extends AbstractDataTransferObject
*/
protected array $supportedOptions;

/**
* @var array<string, true> Map of supported capabilities for O(1) lookups.
*/
private array $capabilitiesMap = [];

/**
* @var array<string, SupportedOption> Map of supported options by name for O(1) lookups.
*/
private array $optionsMap = [];

/**
* Constructor.
Expand Down Expand Up @@ -90,16 +81,6 @@ public function __construct(string $id, string $name, array $supportedCapabiliti
$this->name = $name;
$this->supportedCapabilities = $supportedCapabilities;
$this->supportedOptions = $supportedOptions;

// Build capability map for efficient lookups
foreach ($supportedCapabilities as $capability) {
$this->capabilitiesMap[$capability->value] = true;
}

// Build options map for efficient lookups
foreach ($supportedOptions as $option) {
$this->optionsMap[$option->getName()->value] = $option;
}
}

/**
Expand Down Expand Up @@ -209,42 +190,6 @@ public function toArray(): array
];
}

/**
* Checks whether this model meets the specified requirements.
*
* @since 0.1.0
*
* @param ModelRequirements $requirements The requirements to check against.
* @return bool True if the model meets all requirements, false otherwise.
*/
public function meetsRequirements(ModelRequirements $requirements): bool
{
// Check if all required capabilities are supported using map lookup
foreach ($requirements->getRequiredCapabilities() as $requiredCapability) {
if (!isset($this->capabilitiesMap[$requiredCapability->value])) {
return false;
}
}

// Check if all required options are supported with the specified values
foreach ($requirements->getRequiredOptions() as $requiredOption) {
// Use map lookup instead of linear search
if (!isset($this->optionsMap[$requiredOption->getName()->value])) {
return false;
}

$supportedOption = $this->optionsMap[$requiredOption->getName()->value];

// Check if the required value is supported by this option
if (!$supportedOption->isSupportedValue($requiredOption->getValue())) {
return false;
}
}

return true;
}


/**
* {@inheritDoc}
*
Expand Down
Loading